34 files changed, 1065 insertions, 116 deletions
diff --git a/gammu/emb/common/common.pro b/gammu/emb/common/common.pro index 797199b..af45382 100644 --- a/gammu/emb/common/common.pro +++ b/gammu/emb/common/common.pro @@ -1,188 +1,194 @@ ###################################################################### # Automatically generated by qmake (1.07a) Fri Jul 30 22:13:34 2004 ###################################################################### TEMPLATE = lib DEPENDPATH += device \ misc \ phone \ protocol \ service \ device/bluetoth \ device/irda \ device/serial \ misc/coding \ phone/alcatel \ phone/at \ phone/nokia \ phone/obex \ phone/symbian \ protocol/alcatel \ protocol/at \ protocol/nokia \ protocol/obex \ protocol/symbian \ service/backup \ service/sms \ phone/nokia/dct3 \ phone/nokia/dct4 INCLUDEPATH += . \ misc/coding \ misc \ device \ phone/nokia/dct4 \ phone/nokia/dct3 \ phone/at \ phone/alcatel \ phone/obex \ phone/symbian \ protocol \ protocol/nokia \ protocol/at \ protocol/alcatel \ protocol/obex \ protocol/symbian \ device/serial \ device/irda \ device/bluetoth \ service \ service/sms \ service/backup \ phone/nokia \ phone # Input HEADERS += config.h \ gammu.h \ gsmcomon.h \ gsmstate.h \ device/devfunc.h \ misc/cfg.h \ misc/misc.h \ phone/pfunc.h \ protocol/protocol.h \ service/gsmcal.h \ service/gsmcall.h \ service/gsmdata.h \ service/gsmlogo.h \ service/gsmmisc.h \ service/gsmnet.h \ service/gsmpbk.h \ service/gsmprof.h \ service/gsmring.h \ device/bluetoth/affix.h \ - device/bluetoth/blue_w32.h \ device/bluetoth/bluetoth.h \ device/bluetoth/bluez.h \ device/irda/irda.h \ - device/irda/irda_unx.h \ - device/irda/irda_w32.h \ device/serial/ser_djg.h \ - device/serial/ser_unx.h \ - device/serial/ser_w32.h \ misc/coding/coding.h \ misc/coding/md5.h \ phone/alcatel/alcatel.h \ phone/at/atgen.h \ phone/nokia/ncommon.h \ phone/nokia/nfunc.h \ phone/nokia/nfuncold.h \ phone/obex/obexgen.h \ phone/symbian/mroutgen.h \ protocol/alcatel/alcabus.h \ protocol/at/at.h \ protocol/nokia/fbus2.h \ protocol/nokia/mbus2.h \ protocol/nokia/phonet.h \ protocol/obex/obex.h \ protocol/symbian/mrouter.h \ service/backup/backgen.h \ service/backup/backics.h \ service/backup/backldif.h \ service/backup/backlmb.h \ service/backup/backtext.h \ service/backup/backvcf.h \ service/backup/backvcs.h \ service/backup/gsmback.h \ service/sms/gsmems.h \ service/sms/gsmmulti.h \ service/sms/gsmsms.h \ phone/nokia/dct3/dct3comm.h \ phone/nokia/dct3/dct3func.h \ phone/nokia/dct3/n6110.h \ phone/nokia/dct3/n7110.h \ + phone/nokia/dct3/n0650.h \ phone/nokia/dct3/n9210.h \ phone/nokia/dct4/dct4func.h \ phone/nokia/dct4/n3320.h \ phone/nokia/dct4/n3650.h \ phone/nokia/dct4/n6510.h SOURCES +=gsmcomon.c \ gsmstate.c \ misc/misc.c \ misc/cfg.c \ misc/coding/coding.c \ misc/coding/md5.c \ service/sms/gsmsms.c \ service/sms/gsmems.c \ service/sms/gsmmulti.c \ service/gsmcal.c \ service/gsmdata.c \ service/gsmpbk.c \ service/gsmring.c \ service/gsmlogo.c \ service/gsmmisc.c \ service/gsmnet.c \ service/backup/gsmback.c \ service/backup/backldif.c \ service/backup/backlmb.c \ service/backup/backtext.c \ service/backup/backvcs.c \ service/backup/backvcf.c \ service/backup/backics.c \ device/bluetoth/affix.c \ device/bluetoth/bluez.c \ -device/bluetoth/blue_w32.c \ device/bluetoth/bluetoth.c \ device/serial/ser_djg.c \ device/irda/irda.c \ device/devfunc.c \ protocol/at/at.c \ protocol/alcatel/alcabus.c \ protocol/nokia/mbus2.c \ protocol/nokia/fbus2.c \ protocol/nokia/phonet.c \ protocol/obex/obex.c \ protocol/symbian/mrouter.c \ phone/pfunc.c \ phone/at/atgen.c \ phone/at/siemens.c \ phone/at/samsung.c \ phone/at/sonyeric.c \ phone/alcatel/alcatel.c \ phone/nokia/dct3/n6110.c \ phone/nokia/dct3/n7110.c \ +phone/nokia/dct3/n0650.c \ phone/nokia/dct3/n9210.c \ phone/nokia/dct3/dct3func.c \ phone/nokia/dct4/n3320.c \ phone/nokia/dct4/n3650.c \ phone/nokia/dct4/n6510.c \ phone/nokia/dct4/dct4func.c \ phone/nokia/nauto.c \ phone/nokia/nfunc.c \ phone/nokia/nfuncold.c \ phone/obex/obexgen.c \ phone/symbian/mroutgen.c DEFINES += DESKTOP_VERSION TARGET = microgammu CONFIG = warn_off release console DESTDIR = ../../../bin OBJECTS_DIR = obj/unix MOC_DIR = moc/unix unix: { -SOURCES += device/serial/ser_unx.c +HEADERS += device/serial/ser_unx.h \ + device/irda/irda_unx.h + +SOURCES += device/serial/ser_unx.c \ + } win32:{ -SOURCES += device/serial/ser_w32.c + +HEADERS += device/serial/ser_w32.h \ + device/irda/irda_w32.h \ + device/bluetoth/blue_w32.h + +SOURCES += device/serial/ser_w32.c \ + device/bluetoth/blue_w32.c } diff --git a/gammu/emb/common/commonE.pro b/gammu/emb/common/commonE.pro index f5b559d..1512814 100644 --- a/gammu/emb/common/commonE.pro +++ b/gammu/emb/common/commonE.pro @@ -1,181 +1,187 @@ ###################################################################### # Automatically generated by qmake (1.07a) Fri Jul 30 22:13:34 2004 ###################################################################### TEMPLATE = lib DEPENDPATH += device \ misc \ phone \ protocol \ service \ device/bluetoth \ device/irda \ device/serial \ misc/coding \ phone/alcatel \ phone/at \ phone/nokia \ phone/obex \ phone/symbian \ protocol/alcatel \ protocol/at \ protocol/nokia \ protocol/obex \ protocol/symbian \ service/backup \ service/sms \ phone/nokia/dct3 \ phone/nokia/dct4 INCLUDEPATH += . \ misc/coding \ misc \ device \ phone/nokia/dct4 \ phone/nokia/dct3 \ phone/at \ phone/alcatel \ phone/obex \ phone/symbian \ protocol \ protocol/nokia \ protocol/at \ protocol/alcatel \ protocol/obex \ protocol/symbian \ device/serial \ device/irda \ device/bluetoth \ service \ service/sms \ service/backup \ phone/nokia \ phone # Input HEADERS += config.h \ gammu.h \ gsmcomon.h \ gsmstate.h \ device/devfunc.h \ misc/cfg.h \ misc/misc.h \ phone/pfunc.h \ protocol/protocol.h \ service/gsmcal.h \ service/gsmcall.h \ service/gsmdata.h \ service/gsmlogo.h \ service/gsmmisc.h \ service/gsmnet.h \ service/gsmpbk.h \ service/gsmprof.h \ service/gsmring.h \ device/bluetoth/affix.h \ - device/bluetoth/blue_w32.h \ device/bluetoth/bluetoth.h \ device/bluetoth/bluez.h \ device/irda/irda.h \ device/irda/irda_unx.h \ - device/irda/irda_w32.h \ device/serial/ser_djg.h \ device/serial/ser_unx.h \ - device/serial/ser_w32.h \ misc/coding/coding.h \ misc/coding/md5.h \ phone/alcatel/alcatel.h \ phone/at/atgen.h \ phone/nokia/ncommon.h \ phone/nokia/nfunc.h \ phone/nokia/nfuncold.h \ phone/obex/obexgen.h \ phone/symbian/mroutgen.h \ protocol/alcatel/alcabus.h \ protocol/at/at.h \ protocol/nokia/fbus2.h \ protocol/nokia/mbus2.h \ protocol/nokia/phonet.h \ protocol/obex/obex.h \ protocol/symbian/mrouter.h \ service/backup/backgen.h \ service/backup/backics.h \ service/backup/backldif.h \ service/backup/backlmb.h \ service/backup/backtext.h \ service/backup/backvcf.h \ service/backup/backvcs.h \ service/backup/gsmback.h \ service/sms/gsmems.h \ service/sms/gsmmulti.h \ service/sms/gsmsms.h \ phone/nokia/dct3/dct3comm.h \ phone/nokia/dct3/dct3func.h \ phone/nokia/dct3/n6110.h \ phone/nokia/dct3/n7110.h \ phone/nokia/dct3/n9210.h \ phone/nokia/dct4/dct4func.h \ phone/nokia/dct4/n3320.h \ + phone/nokia/dct3/n0650.h \ phone/nokia/dct4/n3650.h \ phone/nokia/dct4/n6510.h SOURCES +=gsmcomon.c \ gsmstate.c \ misc/misc.c \ misc/cfg.c \ misc/coding/coding.c \ misc/coding/md5.c \ service/sms/gsmsms.c \ service/sms/gsmems.c \ service/sms/gsmmulti.c \ service/gsmcal.c \ service/gsmdata.c \ service/gsmpbk.c \ service/gsmring.c \ service/gsmlogo.c \ service/gsmmisc.c \ service/gsmnet.c \ service/backup/gsmback.c \ service/backup/backldif.c \ service/backup/backlmb.c \ service/backup/backtext.c \ service/backup/backvcs.c \ service/backup/backvcf.c \ service/backup/backics.c \ device/bluetoth/affix.c \ device/bluetoth/bluez.c \ -device/bluetoth/blue_w32.c \ device/bluetoth/bluetoth.c \ device/serial/ser_unx.c \ device/serial/ser_djg.c \ device/irda/irda.c \ device/devfunc.c \ protocol/at/at.c \ protocol/alcatel/alcabus.c \ protocol/nokia/mbus2.c \ protocol/nokia/fbus2.c \ protocol/nokia/phonet.c \ protocol/obex/obex.c \ protocol/symbian/mrouter.c \ phone/pfunc.c \ phone/at/atgen.c \ phone/at/siemens.c \ phone/at/samsung.c \ phone/at/sonyeric.c \ phone/alcatel/alcatel.c \ phone/nokia/dct3/n6110.c \ phone/nokia/dct3/n7110.c \ phone/nokia/dct3/n9210.c \ phone/nokia/dct3/dct3func.c \ phone/nokia/dct4/n3320.c \ phone/nokia/dct4/n3650.c \ phone/nokia/dct4/n6510.c \ +phone/nokia/dct3/n0650.c \ phone/nokia/dct4/dct4func.c \ phone/nokia/nauto.c \ phone/nokia/nfunc.c \ phone/nokia/nfuncold.c \ phone/obex/obexgen.c \ phone/symbian/mroutgen.c TARGET = kammu DESTDIR = $(QPEDIR)/lib OBJECTS_DIR = obj/$(PLATFORM) MOC_DIR = moc/$(PLATFORM) CONFIG = warn_off release console + + + + + # device/bluetoth/blue_w32.h \ + # device/irda/irda_w32.h \ + # device/serial/ser_w32.h \ + # device/bluetoth/blue_w32.c \
\ No newline at end of file diff --git a/gammu/emb/common/device/serial/ser_djg.c b/gammu/emb/common/device/serial/ser_djg.c index 2524187..609deb8 100644 --- a/gammu/emb/common/device/serial/ser_djg.c +++ b/gammu/emb/common/device/serial/ser_djg.c @@ -1,74 +1,443 @@ +/* Some sources from SVAsync (c) 1996, 1997, Samuel Vincent + * 7337 Carioca Ct, Rohnert Park, Ca 94928 + * "you may freely use it in your programs without paying me anything" + */ +/* Some sources from DZCOMM */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_SERIALDEVICE #ifdef DJGPP #include "../../gsmcomon.h" +#include "../../misc/coding/coding.h" #include "ser_djg.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <dos.h> +#include <dpmi.h> +#include <pc.h> +#include <go32.h> +#include <sys/farptr.h> +#include <sys/movedata.h> +#include <conio.h> + +extern unsigned short __djgpp_ds_alias; +extern void SVAsyncProtISR(void); + +static unsigned char SVAsyncStatus=0; + +static void lock_interrupt_memory(void); +static void unlock_interrupt_memory(void); + +#define Ctrl8259_0 0x020 /* 8259 port */ +#define Ctrl8259_1 0x021 /* 8259 port (Masks) */ +#define BufSize 32768 /* Buffer Size */ + +static unsigned char VectorNum; /* Vector Number */ +static unsigned char EnableIRQ; /* Mask to enable 8259 IRQ */ +static unsigned char DisableIRQ; /* Mask to disable 8259 IRQ */ +static _go32_dpmi_seginfo ProtVector; /* Old Protmode Vector */ +static _go32_dpmi_seginfo info; /* New Protmode Vector */ + +/* Register Addresses for the UART */ +static unsigned short Port; /* Port Base Address */ +unsigned short THR; /* Transmitter Holding Register */ +unsigned short RDR; /* Reciever Data Register */ +unsigned short BRDL; /* Baud Rate Divisor, Low byte */ +unsigned short BRDH; /* Baud Rate Divisor, High Byte */ +unsigned short IER; /* Interupt Enable Register */ +unsigned short IIR; /* Interupt Identification Register */ +unsigned short FCR; /* FIFO Control Register */ +unsigned short LCR; /* Line Control Register */ +unsigned short MCR; /* Modem Control Register */ +unsigned short LSR; /* Line Status Register */ +unsigned short MSR; /* Modem Status Register */ +unsigned short SCR; /* SCR Register */ + +/* Data Buffer */ +unsigned volatile char RecBuffer[BufSize] = { 0 }; +unsigned volatile int RecHead, RecTail; + +/* This uninstalls the ISR and resets the serial port. */ +static void SVAsyncStop(void) +{ + if(!SVAsyncStatus) return; + SVAsyncStatus = 0; + + /***** Mask (disable) 8259 IRQ Interrupt */ + outportb(Ctrl8259_1, (inportb(Ctrl8259_1) | DisableIRQ)); + + /***** Disable 8250 interrupt */ + outportb(LCR, (inportb(LCR) & 0x7F)); + outportb(IER, 0); + + /***** Set bit 3 in MCR to 0 */ + outportb(MCR, (inportb(MCR) & 0xF7)); + + /***** Interrupts are disabled. Restore saved interrupt vector. */ + _go32_dpmi_set_protected_mode_interrupt_vector(VectorNum, &ProtVector); +} + +/* This will empty the receive buffer */ +static void SVAsyncClear(void) +{ + disable(); + RecHead = 0; + RecTail = 0; + enable(); +} + + +/* Sets communication parameters + * Baud = 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 28800, 38400, 57600 + * Control = The value to place in the LCR + */ +void SVAsyncSet(unsigned int Baud, unsigned int Control) +{ + int divisor; + unsigned char divlow, divhigh; + + if (!Baud) return; + + divisor = 115200 / Baud; + + disable(); + + outportb(LCR, Control | 0x80); /* Set Port Toggle to BRDL/BRDH registers */ + divlow = divisor & 0x000000ff; + divhigh = (divisor >> 8) & 0x000000ff; + outportb(BRDL, divlow); /* Set Baud Rate */ + outportb(BRDH, divhigh); + + outportb(LCR, Control & 0x007F); /* Set LCR and Port Toggle */ + + enable(); +} + +/* Sets various handshaking lines */ +void SVAsyncHand(unsigned int Hand) +{ + outportb(MCR, Hand | 0x08); /* Keep interrupt enable ON */ +} + +static void lock_interrupt_memory(void) +{ + int errval; + __dpmi_meminfo info; + unsigned long address; + + __dpmi_get_segment_base_address(_my_ds(), &address); + + info.address = (int) address + (int) &RDR; + info.size = sizeof(RDR); + errval = __dpmi_lock_linear_region(&info); + if(errval == -1) printf("Error in locking memory\n!"); + + info.address = (int) address + (int) &LSR; + info.size = sizeof(LSR); + errval = __dpmi_lock_linear_region(&info); + if(errval == -1) printf("Error in locking memory\n!"); + + info.address = (int) address + (int) &RecHead; + info.size = sizeof(RecHead); + errval = __dpmi_lock_linear_region(&info); + if(errval == -1) printf("Error in locking memory\n!"); + + info.address = (int) address + (int) &RecBuffer; + info.size = sizeof(RecBuffer); + errval = __dpmi_lock_linear_region(&info); + if(errval == -1) printf("Error in locking memory\n!"); + + info.address = (int) address + (int) RecBuffer; + info.size = BufSize; + errval = __dpmi_lock_linear_region(&info); + if(errval == -1) printf("Error in locking memory\n!"); + + __dpmi_get_segment_base_address(_my_cs(), &address); + + info.address = (int) address + (int) SVAsyncProtISR; + info.size = 4096; /* 4096 bytes is probably overkill. */ + errval = __dpmi_lock_linear_region(&info); + if(errval == -1) printf("Error in locking memory\n!"); +} + +static void unlock_interrupt_memory(void) +{ + __dpmi_meminfo info; + unsigned long address; + + __dpmi_get_segment_base_address(_my_ds(), &address); + info.address = (int) address + (int) &RDR; + info.size = sizeof(RDR); + __dpmi_unlock_linear_region(&info); + info.address = (int) address + (int) &LSR; + info.size = sizeof(LSR); + __dpmi_unlock_linear_region(&info); + info.address = (int) address + (int) &RecHead; + info.size = sizeof(RecHead); + __dpmi_unlock_linear_region(&info); + info.address = (int) address + (int) &RecBuffer; + info.size = sizeof(RecBuffer); + __dpmi_unlock_linear_region(&info); + info.address = (int) address + (int) RecBuffer; + info.size = BufSize; + __dpmi_unlock_linear_region(&info); + + __dpmi_get_segment_base_address(_my_cs(), &address); + + info.address = (int) address + (int) SVAsyncProtISR; + info.size = 4096; /* probably overkill */ + __dpmi_unlock_linear_region(&info); +} + static GSM_Error serial_close(GSM_StateMachine *s) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; + SVAsyncStop(); - return ERR_NOTIMPLEMENTED; + return ERR_NONE; } static GSM_Error serial_open (GSM_StateMachine *s) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; - - return ERR_NOTIMPLEMENTED; + GSM_Device_SerialData *d = &s->Device.Data.Serial; + unsigned char temp; + int i; + + /**** Set various things according to com port number */ + if (mystrncasecmp(s->CurrentConfig->Device,"com1:",0)) { + Port = 0x03F8; + VectorNum = 0x0C; + EnableIRQ = 0xEF; + DisableIRQ = 0x10; + } else if (mystrncasecmp(s->CurrentConfig->Device,"com2:",0)) { + Port = 0x02F8; + VectorNum = 0x0B; + EnableIRQ = 0xF7; + DisableIRQ = 0x08; + } else if (mystrncasecmp(s->CurrentConfig->Device,"com3:",0)) { + Port = 0x03E8; + VectorNum = 0x0C; + EnableIRQ = 0xEF; + DisableIRQ = 0x10; + } else if (mystrncasecmp(s->CurrentConfig->Device,"com4:",0)) { + Port = 0x02E8; + VectorNum = 0x0B; + EnableIRQ = 0xF7; + DisableIRQ = 0x08; + } else return ERR_NOTSUPPORTED; + + /**** Compute Register locations */ + THR = Port; + RDR = Port; + BRDL = Port; + BRDH = 1 + Port; + IER = 1 + Port; + IIR = 2 + Port; + FCR = 2 + Port; + LCR = 3 + Port; + MCR = 4 + Port; + LSR = 5 + Port; + MSR = 6 + Port; + SCR = 7 + Port; + + /***** Initalize Buffer */ + SVAsyncClear(); + + lock_interrupt_memory(); + atexit(unlock_interrupt_memory); + /***** Set bit 3 in MCR to 0 */ + outportb(MCR, (inportb(MCR) & 0xF7)); + + /*** Save and reassign interrupt vectors */ + + _go32_dpmi_get_protected_mode_interrupt_vector(VectorNum, &ProtVector); + + info.pm_offset = (int) SVAsyncProtISR; + info.pm_selector = _my_cs(); + _go32_dpmi_set_protected_mode_interrupt_vector(VectorNum, &info); + + atexit(SVAsyncStop); + + /***** Enable 8259 interrupt (IRQ) line for this async adapter */ + outportb(Ctrl8259_1, (inportb(Ctrl8259_1) & EnableIRQ)); + + /***** Enable 8250 Interrupt-on-data-ready */ + outportb(LCR, (inportb(LCR) & 0x7F)); + + outportb(IER, 0); + if (inportb(IER)) { + SVAsyncStatus = 0; + return ERR_UNKNOWN; + } + outportb(IER, 0x01); + + /***** Clear 8250 Status and data registers */ + do { + temp=inportb(RDR); + temp=inportb(LSR); + temp=inportb(MSR); + temp=inportb(IIR); + } while(!(temp & 1)); + + /***** Set Bit 3 of MCR -- Enable interupts */ + outportb(MCR, (inportb(MCR) | 0x08)); + + SVAsyncStatus = 1; + /***** Clear Buffer Just in case */ + SVAsyncClear(); + + /* Code based on stuff from SVAsync lib. + * Clear UART Status and data registers + * setting up FIFO if possible + */ + outportb(SCR, 0x55); + if (inportb(SCR) == 0x55) { + /* On the off chance that SCR is actually hardwired to 0x55, + * do the same check with a different value. + */ + outportb(SCR, 0xAA); + if (inportb(SCR) == 0xAA) { + /* The chip is better than an 8250 - it has a scratch pad */ + outportb(SCR, i); /* Set SCR back to what it was before */ + inportb(SCR); /* Give slow motherboards a chance */ + + /* Is there a FIFO ? - go through twice for slow motherboards */ + outportb(FCR, 0x01); + i = inportb(FCR); + outportb(FCR, 0x01); + i = inportb(FCR); + + /* Some old stuff relies on this (no idea why) */ + outportb(FCR, 0x00); + inportb(FCR); /* Give slow motherboards a chance */ + + if ((i&0x80) == 0) { + smprintf(s,"UART 16450 or UART 8250 with scratch pad\n"); + } else if ((i&0x40) == 0) { + smprintf(s,"UART 16550 - broken FIFO\n"); + } else { + /* It's a 16450A series : try and start the FIFO. + * It appears that some chips need a two call protocol, but + * those that don't seem to work even if you do start it + * twice. The first call is simply to start it, the second + * starts it and sets an 8 byte FIFO trigger level. + */ + outportb(FCR, 0x01); + inportb(FCR); /* Give slow motherboards a chance */ + outportb(FCR, 0x87); + inportb(FCR); /* Give slow motherboards a chance */ + + /* Check that the FIFO initialised */ + if ((inportb(IIR) & 0xc0) != 0xc0) { + /* + * It didn't so we assume it isn't there but disable it to + * be on the safe side. + */ + outportb(IIR, 0xfe); + inportb(IIR); /* Give slow motherboards a chance */ + smprintf(s,"UART 16450A - FIFO disabled\n"); + } else { + smprintf(s,"UART 16450A - FIFO enabled\n"); + } + } + } else { + smprintf(s,"UART 8250\n"); + } + } + + d->Control = BITS_8 | STOP_1; + d->Parity = false; + d->Speed = 9600; + SVAsyncSet(d->Speed,d->Control | NO_PARITY); + + return ERR_NONE; } static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - return ERR_NOTIMPLEMENTED; + d->Parity = parity; + + if (parity) { + SVAsyncSet(d->Speed, d->Control | ODD_PARITY); + } else { + SVAsyncSet(d->Speed, d->Control | NO_PARITY); + } + + return ERR_NONE; } static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; + if (dtr && rts) { + SVAsyncHand(DTR | RTS); + } else if (dtr) { + SVAsyncHand(DTR); + } else if (rts) { + SVAsyncHand(RTS); + } else { + SVAsyncHand(0); + } - return ERR_NOTIMPLEMENTED; + return ERR_NONE; } static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - return ERR_NOTIMPLEMENTED; + d->Speed = speed; + + if (d->Parity) { + SVAsyncSet(d->Speed, d->Control | ODD_PARITY); + } else { + SVAsyncSet(d->Speed, d->Control | NO_PARITY); + } + + return ERR_NONE; } -static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) +static int serial_read(GSM_StateMachine *s, char *buf, size_t nbytes) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; + if(RecTail == RecHead) return 0; + + disable(); + buf[0] = RecBuffer[RecTail++]; + if(RecTail >= BufSize) RecTail = 0; + enable(); - return 0; + return 1; } -static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) +static int serial_write(GSM_StateMachine *s, char *buf, size_t nbytes) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; + int i; + + for (i=0;i<nbytes;i++) { + while(~inportb(LSR) & 0x20); + outportb(THR, buf[i]); + } - return 0; + return i; } GSM_Device_Functions SerialDevice = { serial_open, serial_close, serial_setparity, serial_setdtrrts, serial_setspeed, serial_read, serial_write }; #endif #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/device/serial/ser_djg.h b/gammu/emb/common/device/serial/ser_djg.h index b35b282..3bb2a5b 100644 --- a/gammu/emb/common/device/serial/ser_djg.h +++ b/gammu/emb/common/device/serial/ser_djg.h @@ -1,15 +1,50 @@ +/* Some sources from SVAsync (c) 1996, 1997, Samuel Vincent + * 7337 Carioca Ct, Rohnert Park, Ca 94928 + * "you may freely use it in your programs without paying me anything" + */ #ifdef DJGPP #ifndef djgppserial_h #define djgppserial_h typedef struct { - int hPhone; + int hPhone; + int Speed; + unsigned int Control; + bool Parity; } GSM_Device_SerialData; +/* Defines for Com Port Paramaters, the second paramater to SVAsyncSet() */ +#define BITS_8 0x03 +#define BITS_7 0x02 +#define STOP_1 0x00 +#define STOP_2 0x04 +#define EVEN_PARITY 0x18 +#define ODD_PARITY 0x08 +#define NO_PARITY 0x00 + +/* Defines for SVAsyncHand() */ +#define DTR 0x01 +#define RTS 0x02 +#define USER 0x04 +#define LOOPBACK 0x10 + +/* Defines for SVAsyncStat() */ +#define D_CTS 0x0100 +#define D_DSR 0x0200 +#define D_RI 0x0400 +#define D_DCD 0x0800 +#define CTS 0x1000 +#define DSR 0x2000 +#define RI 0x4000 +#define DCD 0x8000 +#define PARITY 0x0004 +#define THREMPTY 0x0020 +#define BREAKDET 0x1000 + #endif #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/device/serial/ser_unx.c b/gammu/emb/common/device/serial/ser_unx.c index 69c7515..18b5f6f 100644 --- a/gammu/emb/common/device/serial/ser_unx.c +++ b/gammu/emb/common/device/serial/ser_unx.c @@ -1,319 +1,328 @@ /* (c) 2002-2004 by Marcin Wiacek */ /* locking device and settings all speeds by Michal Cihar */ /* based on some work from Gnokii (www.gnokii.org) * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot * GNU GPL version 2 or later */ +/* Due to a problem in the source code management, the names of some of + * the authors have unfortunately been lost. We do not mean to belittle + * their efforts and hope they will contact us to see their names + * properly added to the Copyright notice above. + * Having published their contributions under the terms of the GNU + * General Public License (GPL) [version 2], the Copyright of these + * authors will remain respected by adhering to the license they chose + * to publish their code under. + */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_SERIALDEVICE #ifndef WIN32 #ifndef DJGPP #include <sys/file.h> #include <sys/time.h> #include <string.h> #include <termios.h> #include <errno.h> #include "../../gsmcomon.h" #include "ser_unx.h" #ifndef O_NONBLOCK # define O_NONBLOCK 0 #endif #ifdef __NetBSD__ # define FNONBLOCK O_NONBLOCK # define B57600 0010001 # define B115200 0010002 # define B230400 0010003 # define B460800 0010004 # define B500000 0010005 # define B576000 0010006 # define B921600 0010007 # define B1000000 0010010 # define B1152000 0010011 # define B1500000 0010012 # define B2000000 0010013 # define B2500000 0010014 # define B3000000 0010015 # define B3500000 0010016 # define B4000000 0010017 #endif static GSM_Error serial_close(GSM_StateMachine *s) { GSM_Device_SerialData *d = &s->Device.Data.Serial; /* Restores old settings */ tcsetattr(d->hPhone, TCSANOW, &d->old_settings); /* Closes device */ close(d->hPhone); return ERR_NONE; } static GSM_Error serial_open (GSM_StateMachine *s) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - struct termios t; - int i; + struct termios t; + int i; /* O_NONBLOCK MUST is required to avoid waiting for DCD */ d->hPhone = open(s->CurrentConfig->Device, O_RDWR | O_NOCTTY | O_NONBLOCK); if (d->hPhone < 0) { i = errno; GSM_OSErrorInfo(s,"open in serial_open"); if (i == 2) return ERR_DEVICENOTEXIST; //no such file or directory if (i == 13) return ERR_DEVICENOPERMISSION; //permission denied return ERR_DEVICEOPENERROR; } #ifdef TIOCEXCL /* open() calls from other applications shall fail now */ ioctl(d->hPhone, TIOCEXCL, (char *) 0); #endif if (tcgetattr(d->hPhone, &d->old_settings) == -1) { close(d->hPhone); GSM_OSErrorInfo(s,"tcgetattr in serial_open"); return ERR_DEVICEREADERROR; } if (tcflush(d->hPhone, TCIOFLUSH) == -1) { serial_close(s); GSM_OSErrorInfo(s,"tcflush in serial_open"); return ERR_DEVICEOPENERROR; } memcpy(&t, &d->old_settings, sizeof(struct termios)); /* Opening without parity */ t.c_iflag = IGNPAR; t.c_oflag = 0; /* disconnect line, 8 bits, enable receiver, * ignore modem lines,lower modem line after disconnect */ t.c_cflag = B0 | CS8 | CREAD | CLOCAL | HUPCL; /* enable hardware (RTS/CTS) flow control (NON POSIX) */ /* t.c_cflag |= CRTSCTS; */ t.c_lflag = 0; t.c_cc[VMIN] = 1; t.c_cc[VTIME] = 0; if (tcsetattr(d->hPhone, TCSANOW, &t) == -1) { serial_close(s); GSM_OSErrorInfo(s,"tcsetattr in serial_open"); return ERR_DEVICEOPENERROR; } /* Making file descriptor asynchronous. */ if (fcntl(d->hPhone, F_SETFL, FASYNC | FNONBLOCK) == -1) { serial_close(s); GSM_OSErrorInfo(s,"fcntl in serial_open"); return ERR_DEVICEOPENERROR; } return ERR_NONE; } static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - struct termios t; + struct termios t; if (tcgetattr(d->hPhone, &t)) { GSM_OSErrorInfo(s,"tcgetattr in serial_setparity"); return ERR_DEVICEREADERROR; } if (parity) { t.c_cflag |= (PARENB | PARODD); t.c_iflag = 0; } else { t.c_iflag = IGNPAR; } if (tcsetattr(d->hPhone, TCSANOW, &t) == -1){ serial_close(s); GSM_OSErrorInfo(s,"tcsetattr in serial_setparity"); return ERR_DEVICEPARITYERROR; } return ERR_NONE; } static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - struct termios t; - unsigned int flags; + struct termios t; + unsigned int flags; if (tcgetattr(d->hPhone, &t)) { GSM_OSErrorInfo(s,"tcgetattr in serial_setdtrrts"); return ERR_DEVICEREADERROR; } #ifdef CRTSCTS /* Disabling hardware flow control */ t.c_cflag &= ~CRTSCTS; #endif if (tcsetattr(d->hPhone, TCSANOW, &t) == -1) { serial_close(s); GSM_OSErrorInfo(s,"tcsetattr in serial_setdtrrts"); return ERR_DEVICEDTRRTSERROR; } flags = TIOCM_DTR; if (dtr) { ioctl(d->hPhone, TIOCMBIS, &flags); } else { ioctl(d->hPhone, TIOCMBIC, &flags); } flags = TIOCM_RTS; if (rts) { ioctl(d->hPhone, TIOCMBIS, &flags); } else { ioctl(d->hPhone, TIOCMBIC, &flags); } flags = 0; ioctl(d->hPhone, TIOCMGET, &flags); dbgprintf("Serial device:"); dbgprintf(" DTR is %s", flags&TIOCM_DTR?"up":"down"); dbgprintf(", RTS is %s", flags&TIOCM_RTS?"up":"down"); dbgprintf(", CAR is %s", flags&TIOCM_CAR?"up":"down"); dbgprintf(", CTS is %s\n", flags&TIOCM_CTS?"up":"down"); if (((flags&TIOCM_DTR)==TIOCM_DTR) != dtr) return ERR_DEVICEDTRRTSERROR; if (((flags&TIOCM_RTS)==TIOCM_RTS) != rts) return ERR_DEVICEDTRRTSERROR; return ERR_NONE; } static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) { GSM_Device_SerialData *d = &s->Device.Data.Serial; struct termios t; int speed2 = B19200; if (tcgetattr(d->hPhone, &t)) { GSM_OSErrorInfo(s,"tcgetattr in serial_setspeed"); return ERR_DEVICEREADERROR; } smprintf(s, "Setting speed to %d\n", speed); switch (speed) { case 50: speed2 = B50; break; case 75: speed2 = B75; break; case 110: speed2 = B110; break; case 134: speed2 = B134; break; case 150: speed2 = B150; break; case 200: speed2 = B200; break; case 300: speed2 = B300; break; case 600: speed2 = B600; break; case 1200: speed2 = B1200; break; case 1800: speed2 = B1800; break; case 2400: speed2 = B2400; break; case 4800: speed2 = B4800; break; case 9600: speed2 = B9600; break; case 19200: speed2 = B19200; break; case 38400: speed2 = B38400; break; #ifdef B57600 case 57600: speed2 = B57600; break; case 115200: speed2 = B115200; break; case 230400: speed2 = B230400; break; case 460800: speed2 = B460800; break; #ifdef B500000 case 500000: speed2 = B500000; break; case 576000: speed2 = B576000; break; case 921600: speed2 = B921600; break; case 1000000: speed2 = B1000000; break; case 1152000: speed2 = B1152000; break; case 1500000: speed2 = B1500000; break; case 2000000: speed2 = B2000000; break; case 2500000: speed2 = B2500000; break; case 3000000: speed2 = B3000000; break; case 3500000: speed2 = B3500000; break; case 4000000: speed2 = B4000000; break; #endif #endif } /* This should work on all systems because it is done according to POSIX */ cfsetispeed(&t, speed2); cfsetospeed(&t, speed2); if (tcsetattr(d->hPhone, TCSADRAIN, &t) == -1) { serial_close(s); GSM_OSErrorInfo(s,"tcsetattr in serial_setspeed"); return ERR_DEVICECHANGESPEEDERROR; } return ERR_NONE; } static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) { GSM_Device_SerialData *d = &s->Device.Data.Serial; struct timeval timeout2; - fd_set readfds; - int actual = 0; + fd_set readfds; + int actual = 0; FD_ZERO(&readfds); FD_SET(d->hPhone, &readfds); timeout2.tv_sec = 0; timeout2.tv_usec = 1; if (select(d->hPhone+1, &readfds, NULL, NULL, &timeout2)) { actual = read(d->hPhone, buf, nbytes); if (actual == -1) GSM_OSErrorInfo(s,"serial_read"); } return actual; } static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - int ret; - size_t actual = 0; + int ret; + size_t actual = 0; do { ret = write(d->hPhone, (unsigned char *)buf, nbytes - actual); if (ret < 0 && errno == EAGAIN) continue; if (ret < 0) { if (actual != nbytes) GSM_OSErrorInfo(s,"serial_write"); return actual; } actual += ret; buf += ret; if (s->ConnectionType == GCT_FBUS2PL2303) my_sleep(1); } while (actual < nbytes); return actual; } GSM_Device_Functions SerialDevice = { serial_open, serial_close, serial_setparity, serial_setdtrrts, serial_setspeed, serial_read, serial_write }; #endif #endif #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/device/serial/ser_w32.c b/gammu/emb/common/device/serial/ser_w32.c index 7d88fc7..a7919fe 100644 --- a/gammu/emb/common/device/serial/ser_w32.c +++ b/gammu/emb/common/device/serial/ser_w32.c @@ -1,344 +1,353 @@ /* (c) 2002-2004 by Marcin Wiacek */ /* based on some work from MSDN and others */ /* based on some work from Gnokii (www.gnokii.org) * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot * GNU GPL version 2 or later */ +/* Due to a problem in the source code management, the names of some of + * the authors have unfortunately been lost. We do not mean to belittle + * their efforts and hope they will contact us to see their names + * properly added to the Copyright notice above. + * Having published their contributions under the terms of the GNU + * General Public License (GPL) [version 2], the Copyright of these + * authors will remain respected by adhering to the license they chose + * to publish their code under. + */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_SERIALDEVICE #ifdef WIN32 #include <windows.h> #include <string.h> #include <stdio.h> #include <io.h> #include <memory.h> #include "../../gsmcomon.h" #include "ser_w32.h" static GSM_Error serial_close(GSM_StateMachine *s) { GSM_Device_SerialData *d = &s->Device.Data.Serial; /* Disables all monitored events for device */ SetCommMask(d->hPhone, 0); /* Discards all characters from input/output buffer and terminates * pending read/write operations */ PurgeComm(d->hPhone, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); /* Clears the DTR (data-terminal-ready) signal */ EscapeCommFunction(d->hPhone, CLRDTR); /* Restores old settings */ if (SetCommState(d->hPhone, &d->old_settings)==0) { GSM_OSErrorInfo(s, "SetCommState in serial_close"); } /* Closes device */ if (CloseHandle(d->hPhone)==0) { GSM_OSErrorInfo(s, "CloseHandle in serial_close"); } return ERR_NONE; } static GSM_Error serial_open (GSM_StateMachine *s) { GSM_Device_SerialData *d = &s->Device.Data.Serial; DCB dcb; unsigned char DeviceName[80],DeviceName2[80]; int i; #ifdef GSM_ENABLE_FBUS2DKU5 HKEY hKey; DWORD DeviceNameLen, KeyNameLen; unsigned char KeyName[100]; #endif strcpy(DeviceName2,s->CurrentConfig->Device); #ifdef GSM_ENABLE_FBUS2DKU5 if (s->ConnectionType == GCT_FBUS2DKU5) { smprintf(s,"Reading DKU5 device\n"); DeviceName2[0] = 0; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) { smprintf(s,"Error opening key\n"); return ERR_DEVICENOTWORK; } i = 0; while(1) { DeviceNameLen = 80; KeyNameLen = 100; if (RegEnumValue(hKey,i,KeyName,&KeyNameLen,NULL,NULL,DeviceName2,&DeviceNameLen) != ERROR_SUCCESS) { smprintf(s,"Error reading key value\n"); return ERR_DEVICENOTWORK; } // smprintf(s,"Key name is %s, value is %s\n",KeyName,DeviceName2); if (!strncmp(KeyName,"\\Device\\AtmelVirtualPort",24)) break; i++; } RegCloseKey(hKey); if (strlen(DeviceName2) == 0) return ERR_DEVICENOTWORK; smprintf(s,"DKU5 device is \"%s\"\n",DeviceName2); //nodriver } #endif if ((s->ConnectionType == GCT_FBUS2DKU5) || (!strncmp(DeviceName2,"com",3) && strlen(DeviceName2)>3)) { sprintf(DeviceName,"\\\\.\\COM%i",atoi(DeviceName2+3)); } else { strcpy(DeviceName,DeviceName2); } smprintf(s,"Device is %s\n",DeviceName); /* Allows for reading/writing, no device sharing */ d->hPhone = CreateFile(DeviceName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (d->hPhone == INVALID_HANDLE_VALUE) { i = GetLastError(); GSM_OSErrorInfo(s, "CreateFile in serial_open"); if (i == 2) return ERR_DEVICENOTWORK; //can't find specified file if (i == 5) return ERR_DEVICEBUSY; //access denied if (i == 31) return ERR_DEVICENOTWORK; //attached device not working if (i == 123) return ERR_DEVICENOTEXIST; return ERR_DEVICEOPENERROR; } d->old_settings.DCBlength = sizeof(DCB); if (GetCommState(d->hPhone, &d->old_settings)==0) { GSM_OSErrorInfo(s, "ReadDevice in serial_open"); return ERR_DEVICEREADERROR; } /* When char will be received, we will receive notifications */ SetCommMask(d->hPhone, EV_RXCHAR); /* Sets size for input/output buffer */ SetupComm(d->hPhone, 4096, 4096); /* Discards all characters from input/output buffer and terminates * pending read/write operations */ PurgeComm(d->hPhone, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); memcpy(&dcb, &d->old_settings, sizeof(DCB)); dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; /* No Xon/Xof flow control */ // dcb.fOutX = false; // dcb.fInX = false; /* Hardware flow control */ // dcb.fOutxDsrFlow = true; // dcb.fOutxCtsFlow = true; // dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; // dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; /* Initialise the port settings */ if (SetCommState(d->hPhone, &dcb)==0) { GSM_OSErrorInfo(s, "WriteDevice in serial_open"); return ERR_DEVICEOPENERROR; } return ERR_NONE; } static GSM_Error serial_setparity (GSM_StateMachine *s, bool parity) { DCB dcb; GSM_Device_SerialData *d = &s->Device.Data.Serial; dcb.DCBlength = sizeof(DCB); if (GetCommState(d->hPhone, &dcb)==0) { GSM_OSErrorInfo(s, "ReadDevice in serial_setparity"); return ERR_DEVICEREADERROR; } if (parity) { dcb.Parity = ODDPARITY; } else { dcb.Parity = NOPARITY; } if (SetCommState(d->hPhone, &dcb)==0) { GSM_OSErrorInfo(s, "WriteDevice in serial_setparity"); return ERR_DEVICEPARITYERROR; } return ERR_NONE; } static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) { DCB dcb; GSM_Device_SerialData *d = &s->Device.Data.Serial; dcb.DCBlength = sizeof(DCB); if (GetCommState(d->hPhone, &dcb)==0) { GSM_OSErrorInfo(s, "ReadDevice in serial_setdtrrts"); return ERR_DEVICEREADERROR; } dcb.fOutxDsrFlow = 0; dcb.fDtrControl = DTR_CONTROL_DISABLE; if (dtr) dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fOutxCtsFlow = 0; dcb.fRtsControl = RTS_CONTROL_DISABLE; if (rts) dcb.fRtsControl = RTS_CONTROL_ENABLE; /* no software (Xon/Xof) flow control */ dcb.fInX = dcb.fOutX = 0; if (SetCommState(d->hPhone, &dcb)==0) { GSM_OSErrorInfo(s, "WriteDevice in serial_setdtrrts"); return ERR_DEVICEDTRRTSERROR; } /* the rest of function checks, if setting was really done */ dcb.DCBlength = sizeof(DCB); GetCommState(d->hPhone, &dcb); dbgprintf("Serial device:"); dbgprintf(" DTR is "); switch (dcb.fDtrControl) { case DTR_CONTROL_ENABLE : dbgprintf("up"); break; case DTR_CONTROL_DISABLE : dbgprintf("down"); break; case DTR_CONTROL_HANDSHAKE : dbgprintf("handshake"); break; } dbgprintf(", RTS is "); switch (dcb.fRtsControl) { case RTS_CONTROL_ENABLE : dbgprintf("up"); break; case RTS_CONTROL_DISABLE : dbgprintf("down"); break; case RTS_CONTROL_HANDSHAKE : dbgprintf("handshake"); break; case RTS_CONTROL_TOGGLE : dbgprintf("toggle"); break; } dbgprintf("\n"); if ( dtr && dcb.fDtrControl != DTR_CONTROL_ENABLE ) return ERR_DEVICEDTRRTSERROR; if (!dtr && dcb.fDtrControl != DTR_CONTROL_DISABLE) return ERR_DEVICEDTRRTSERROR; if ( rts && dcb.fRtsControl != RTS_CONTROL_ENABLE ) return ERR_DEVICEDTRRTSERROR; if (!rts && dcb.fRtsControl != RTS_CONTROL_DISABLE) return ERR_DEVICEDTRRTSERROR; return ERR_NONE; } static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) { DCB dcb; GSM_Device_SerialData *d = &s->Device.Data.Serial; dcb.DCBlength = sizeof(DCB); if (GetCommState(d->hPhone, &dcb)==0) { GSM_OSErrorInfo(s, "ReadDevice in serial_setspeed"); return ERR_DEVICEREADERROR; } dcb.BaudRate = speed; if (SetCommState(d->hPhone, &dcb)==0) { GSM_OSErrorInfo(s, "WriteDevice in serial_setspeed"); return ERR_DEVICECHANGESPEEDERROR; } return ERR_NONE; } static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) { COMSTAT ComStat; DWORD ErrorFlags, Length; GSM_Device_SerialData *d = &s->Device.Data.Serial; /* Gets information about a communications error and * current status of device */ ClearCommError(d->hPhone, &ErrorFlags, &ComStat); Length = ComStat.cbInQue; /* Nothing to read */ if (Length <= 0) return Length; /* Read without problems */ if (ReadFile(d->hPhone, buf, Length, &Length, &d->osRead)) return Length; if (GetLastError() != ERROR_IO_PENDING) { GSM_OSErrorInfo(s, "serial_read1"); Length = 0; ClearCommError(d->hPhone, &ErrorFlags, &ComStat); return Length; } while(1) { if (GetOverlappedResult(d->hPhone,&d->osRead, &Length, TRUE)) break; if (GetLastError() != ERROR_IO_INCOMPLETE) { GSM_OSErrorInfo(s, "serial_read2"); /* an error occurred, try to recover */ ClearCommError(d->hPhone, &ErrorFlags, &ComStat); break; } } return Length; } static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) { DWORD BytesWritten,ErrorFlags,BytesSent=0; COMSTAT ComStat; GSM_Device_SerialData *d = &s->Device.Data.Serial; if (WriteFile(d->hPhone, buf, nbytes, &BytesSent, &d->osWrite)) return BytesSent; if (GetLastError() != ERROR_IO_PENDING) { GSM_OSErrorInfo(s, "serial_write1"); ClearCommError(d->hPhone, &ErrorFlags, &ComStat); return BytesSent; } while (1) { if (GetOverlappedResult(d->hPhone, &d->osWrite, &BytesWritten, TRUE)) break; if (GetLastError() != ERROR_IO_INCOMPLETE) { GSM_OSErrorInfo(s, "serial_write2"); ClearCommError(d->hPhone, &ErrorFlags, &ComStat); break; } BytesSent += BytesWritten; } BytesSent += BytesWritten; return BytesSent; } GSM_Device_Functions SerialDevice = { serial_open, serial_close, serial_setparity, serial_setdtrrts, serial_setspeed, serial_read, serial_write }; #endif #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/gsmstate.c b/gammu/emb/common/gsmstate.c index 31e365d..c65dc01 100644 --- a/gammu/emb/common/gsmstate.c +++ b/gammu/emb/common/gsmstate.c @@ -1,1278 +1,1279 @@ /* (c) 2002-2004 by Marcin Wiacek */ /* Phones ID (c) partially by Walek */ #include <stdarg.h> #include <string.h> #include <errno.h> #include "gsmcomon.h" #include "gsmstate.h" #include "misc/cfg.h" #include "misc/coding/coding.h" #include "device/devfunc.h" static void GSM_RegisterConnection(GSM_StateMachine *s, unsigned int connection, GSM_Device_Functions *device, GSM_Protocol_Functions *protocol) { if ((unsigned int)s->ConnectionType == connection) { s->Device.Functions = device; s->Protocol.Functions = protocol; } } static GSM_Error GSM_RegisterAllConnections(GSM_StateMachine *s, char *connection) { /* We check here is used connection string type is correct for ANY * OS. If not, we return with error, that string is incorrect at all */ s->ConnectionType = 0; if (mystrncasecmp("mbus" ,connection,0)) s->ConnectionType = GCT_MBUS2; if (mystrncasecmp("fbus" ,connection,0)) s->ConnectionType = GCT_FBUS2; if (mystrncasecmp("fbusdlr3" ,connection,0)) s->ConnectionType = GCT_FBUS2DLR3; if (mystrncasecmp("fbusdku5" ,connection,0)) s->ConnectionType = GCT_FBUS2DKU5; if (mystrncasecmp("fbuspl2303" ,connection,0)) s->ConnectionType = GCT_FBUS2PL2303; if (mystrncasecmp("fbusblue" ,connection,0)) s->ConnectionType = GCT_FBUS2BLUE; if (mystrncasecmp("fbusirda" ,connection,0)) s->ConnectionType = GCT_FBUS2IRDA; if (mystrncasecmp("phonetblue" ,connection,0)) s->ConnectionType = GCT_PHONETBLUE; if (mystrncasecmp("mrouterblue" ,connection,0)) s->ConnectionType = GCT_MROUTERBLUE; if (mystrncasecmp("irdaphonet" ,connection,0)) s->ConnectionType = GCT_IRDAPHONET; if (mystrncasecmp("irdaat" ,connection,0)) s->ConnectionType = GCT_IRDAAT; if (mystrncasecmp("irdaobex" ,connection,0)) s->ConnectionType = GCT_IRDAOBEX; if (mystrncasecmp("blueobex" ,connection,0)) s->ConnectionType = GCT_BLUEOBEX; if (mystrncasecmp("bluefbus" ,connection,0)) s->ConnectionType = GCT_BLUEFBUS2; if (mystrncasecmp("bluephonet" ,connection,0)) s->ConnectionType = GCT_BLUEPHONET; if (mystrncasecmp("blueat" ,connection,0)) s->ConnectionType = GCT_BLUEAT; if (mystrncasecmp("bluerfobex" ,connection,0)) s->ConnectionType = GCT_BLUEOBEX; if (mystrncasecmp("bluerffbus" ,connection,0)) s->ConnectionType = GCT_BLUEFBUS2; if (mystrncasecmp("bluerfphonet",connection,0)) s->ConnectionType = GCT_BLUEPHONET; if (mystrncasecmp("bluerfat" ,connection,0)) s->ConnectionType = GCT_BLUEAT; /* These are for compatibility only */ if (mystrncasecmp("atblue" ,connection,0)) s->ConnectionType = GCT_BLUEAT; if (mystrncasecmp("dlr3blue" ,connection,0)) s->ConnectionType = GCT_BLUEFBUS2; if (mystrncasecmp("irda" ,connection,0)) s->ConnectionType = GCT_IRDAPHONET; if (mystrncasecmp("dlr3" ,connection,0)) s->ConnectionType = GCT_FBUS2DLR3; if (mystrncasecmp("infrared" ,connection,0)) s->ConnectionType = GCT_FBUS2IRDA; if (mystrncasecmp("at" ,connection,2)) { /* Use some resonable default, when no speed defined */ if (strlen(connection) == 2) { s->Speed = 19200; } else { s->Speed = FindSerialSpeed(connection+2); } if (s->Speed != 0) s->ConnectionType = GCT_AT; } if (s->ConnectionType==0) return ERR_UNKNOWNCONNECTIONTYPESTRING; /* We check now if user gave connection type compiled & available * for used OS (if not, we return, that source not available) */ s->Device.Functions = NULL; s->Protocol.Functions = NULL; #ifdef GSM_ENABLE_MBUS2 GSM_RegisterConnection(s, GCT_MBUS2, &SerialDevice, &MBUS2Protocol); #endif #ifdef GSM_ENABLE_FBUS2 GSM_RegisterConnection(s, GCT_FBUS2, &SerialDevice, &FBUS2Protocol); #endif #ifdef GSM_ENABLE_FBUS2DLR3 GSM_RegisterConnection(s, GCT_FBUS2DLR3, &SerialDevice, &FBUS2Protocol); #endif #ifdef GSM_ENABLE_FBUS2DKU5 GSM_RegisterConnection(s, GCT_FBUS2DKU5, &SerialDevice, &FBUS2Protocol); #endif #ifdef GSM_ENABLE_FBUS2PL2303 GSM_RegisterConnection(s, GCT_FBUS2PL2303,&SerialDevice, &FBUS2Protocol); #endif #ifdef GSM_ENABLE_FBUS2BLUE GSM_RegisterConnection(s, GCT_FBUS2BLUE, &SerialDevice, &FBUS2Protocol); #endif #ifdef GSM_ENABLE_FBUS2IRDA GSM_RegisterConnection(s, GCT_FBUS2IRDA, &SerialDevice, &FBUS2Protocol); #endif #ifdef GSM_ENABLE_PHONETBLUE GSM_RegisterConnection(s, GCT_PHONETBLUE,&SerialDevice, &PHONETProtocol); #endif #ifdef GSM_ENABLE_MROUTERBLUE GSM_RegisterConnection(s, GCT_MROUTERBLUE,&SerialDevice, &MROUTERProtocol); #endif #ifdef GSM_ENABLE_IRDAPHONET GSM_RegisterConnection(s, GCT_IRDAPHONET,&IrdaDevice, &PHONETProtocol); #endif #ifdef GSM_ENABLE_BLUEFBUS2 GSM_RegisterConnection(s, GCT_BLUEFBUS2, &BlueToothDevice,&FBUS2Protocol); #endif #ifdef GSM_ENABLE_BLUEPHONET GSM_RegisterConnection(s, GCT_BLUEPHONET,&BlueToothDevice,&PHONETProtocol); #endif #ifdef GSM_ENABLE_BLUEAT GSM_RegisterConnection(s, GCT_BLUEAT, &BlueToothDevice,&ATProtocol); #endif #ifdef GSM_ENABLE_AT GSM_RegisterConnection(s, GCT_AT, &SerialDevice, &ATProtocol); #endif #ifdef GSM_ENABLE_IRDAAT GSM_RegisterConnection(s, GCT_IRDAAT, &IrdaDevice, &ATProtocol); #endif #ifdef GSM_ENABLE_IRDAOBEX GSM_RegisterConnection(s, GCT_IRDAOBEX, &IrdaDevice, &OBEXProtocol); #endif #ifdef GSM_ENABLE_BLUEOBEX GSM_RegisterConnection(s, GCT_BLUEOBEX, &BlueToothDevice,&OBEXProtocol); #endif if (s->Device.Functions==NULL || s->Protocol.Functions==NULL) return ERR_SOURCENOTAVAILABLE; return ERR_NONE; } static void GSM_RegisterModule(GSM_StateMachine *s,GSM_Phone_Functions *phone) { /* Auto model */ if (s->CurrentConfig->Model[0] == 0) { if (strstr(phone->models,GetModelData(NULL,s->Phone.Data.Model,NULL)->model) != NULL) { smprintf(s,"[Module - \"%s\"]\n",phone->models); s->Phone.Functions = phone; } } else { if (strstr(phone->models,s->CurrentConfig->Model) != NULL) { smprintf(s,"[Module - \"%s\"]\n",phone->models); s->Phone.Functions = phone; } } } GSM_Error GSM_RegisterAllPhoneModules(GSM_StateMachine *s) { OnePhoneModel *model; /* Auto model */ if (s->CurrentConfig->Model[0] == 0) { model = GetModelData(NULL,s->Phone.Data.Model,NULL); #ifdef GSM_ENABLE_ALCATEL if (model->model[0] != 0 && IsPhoneFeatureAvailable(model, F_ALCATEL)) { smprintf(s,"[Module - \"%s\"]\n",ALCATELPhone.models); s->Phone.Functions = &ALCATELPhone; return ERR_NONE; } #endif #ifdef GSM_ENABLE_ATGEN /* With ATgen and auto model we can work with unknown models too */ if (s->ConnectionType==GCT_AT || s->ConnectionType==GCT_BLUEAT || s->ConnectionType==GCT_IRDAAT) { smprintf(s,"[Module - \"%s\"]\n",ATGENPhone.models); s->Phone.Functions = &ATGENPhone; return ERR_NONE; } #endif if (model->model[0] == 0) return ERR_UNKNOWNMODELSTRING; } s->Phone.Functions=NULL; #ifdef GSM_ENABLE_ATGEN /* AT module can have the same models ID to "normal" Nokia modules */ if (s->ConnectionType==GCT_AT || s->ConnectionType==GCT_BLUEAT || s->ConnectionType==GCT_IRDAAT) { GSM_RegisterModule(s,&ATGENPhone); if (s->Phone.Functions!=NULL) return ERR_NONE; } #endif #ifdef GSM_ENABLE_OBEXGEN GSM_RegisterModule(s,&OBEXGENPhone); #endif #ifdef GSM_ENABLE_MROUTERGEN GSM_RegisterModule(s,&MROUTERGENPhone); #endif #ifdef GSM_ENABLE_NOKIA3320 GSM_RegisterModule(s,&N3320Phone); #endif #ifdef GSM_ENABLE_NOKIA3650 GSM_RegisterModule(s,&N3650Phone); #endif #ifdef GSM_ENABLE_NOKIA650 GSM_RegisterModule(s,&N650Phone); #endif #ifdef GSM_ENABLE_NOKIA6110 GSM_RegisterModule(s,&N6110Phone); #endif #ifdef GSM_ENABLE_NOKIA6510 GSM_RegisterModule(s,&N6510Phone); #endif #ifdef GSM_ENABLE_NOKIA7110 GSM_RegisterModule(s,&N7110Phone); #endif #ifdef GSM_ENABLE_NOKIA9210 GSM_RegisterModule(s,&N9210Phone); #endif #ifdef GSM_ENABLE_ALCATEL GSM_RegisterModule(s,&ALCATELPhone); #endif if (s->Phone.Functions==NULL) return ERR_UNKNOWNMODELSTRING; return ERR_NONE; } GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum) { GSM_Error error; GSM_DateTime time; int i; for (i=0;i<s->ConfigNum;i++) { s->CurrentConfig = &s->Config[i]; s->Speed = 0; s->ReplyNum = ReplyNum; s->Phone.Data.ModelInfo = GetModelData("unknown",NULL,NULL); s->Phone.Data.Manufacturer[0] = 0; s->Phone.Data.Model[0] = 0; s->Phone.Data.Version[0] = 0; s->Phone.Data.VerDate[0] = 0; s->Phone.Data.VerNum = 0; s->Phone.Data.StartInfoCounter = 0; s->Phone.Data.SentMsg = NULL; s->Phone.Data.HardwareCache[0] = 0; s->Phone.Data.ProductCodeCache[0] = 0; s->Phone.Data.EnableIncomingCall = false; s->Phone.Data.EnableIncomingSMS = false; s->Phone.Data.EnableIncomingCB = false; s->Phone.Data.EnableIncomingUSSD = false; s->User.UserReplyFunctions = NULL; s->User.IncomingCall = NULL; s->User.IncomingSMS = NULL; s->User.IncomingCB = NULL; s->User.IncomingUSSD = NULL; s->User.SendSMSStatus = NULL; s->LockFile = NULL; s->opened = false; s->Phone.Functions = NULL; s->di = di; s->di.use_global = s->CurrentConfig->UseGlobalDebugFile; GSM_SetDebugLevel(s->CurrentConfig->DebugLevel, &s->di); error=GSM_SetDebugFile(s->CurrentConfig->DebugFile, &s->di); if (error != ERR_NONE) return error; if (s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXT || s->di.dl == DL_TEXTERROR || s->di.dl == DL_TEXTALLDATE || s->di.dl == DL_TEXTDATE || s->di.dl == DL_TEXTERRORDATE) { smprintf(s,"[Gammu - %s built %s %s",VERSION,__TIME__,__DATE__); if (strlen(GetCompiler()) != 0) { smprintf(s," in %s",GetCompiler()); } smprintf(s,"]\n[Connection - \"%s\"]\n",s->CurrentConfig->Connection); smprintf(s,"[Model type - \"%s\"]\n",s->CurrentConfig->Model); smprintf(s,"[Device - \"%s\"]\n",s->CurrentConfig->Device); if (strlen(GetOS()) != 0) { smprintf(s,"[Run on - %s]\n",GetOS()); } } if (s->di.dl==DL_BINARY) { smprintf(s,"%c",((unsigned char)strlen(VERSION))); smprintf(s,"%s",VERSION); } error=GSM_RegisterAllConnections(s, s->CurrentConfig->Connection); if (error!=ERR_NONE) return error; /* Model auto */ if (s->CurrentConfig->Model[0]==0) { if (mystrncasecmp(s->CurrentConfig->LockDevice,"yes",0)) { error = lock_device(s->CurrentConfig->Device, &(s->LockFile)); if (error != ERR_NONE) return error; } /* Irda devices can set now model to some specific and * we don't have to make auto detection later */ error=s->Device.Functions->OpenDevice(s); if (i != s->ConfigNum - 1) { if (error == ERR_DEVICEOPENERROR) continue; if (error == ERR_DEVICELOCKED) continue; if (error == ERR_DEVICENOTEXIST) continue; if (error == ERR_DEVICEBUSY) continue; if (error == ERR_DEVICENOPERMISSION) continue; if (error == ERR_DEVICENODRIVER) continue; if (error == ERR_DEVICENOTWORK) continue; } if (error!=ERR_NONE) { if (s->LockFile!=NULL) unlock_device(&(s->LockFile)); return error; } s->opened = true; error=s->Protocol.Functions->Initialise(s); if (error!=ERR_NONE) return error; /* If still auto model, try to get model by asking phone for it */ if (s->Phone.Data.Model[0]==0) { smprintf(s,"[Module - \"auto\"]\n"); switch (s->ConnectionType) { #ifdef GSM_ENABLE_ATGEN case GCT_AT: case GCT_BLUEAT: case GCT_IRDAAT: s->Phone.Functions = &ATGENPhone; break; #endif #ifdef GSM_ENABLE_OBEXGEN case GCT_IRDAOBEX: case GCT_BLUEOBEX: s->Phone.Functions = &OBEXGENPhone; break; #endif #ifdef GSM_ENABLE_MROUTERGEN case GCT_MROUTERBLUE: s->Phone.Functions = &MROUTERGENPhone; break; #endif #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4) case GCT_MBUS2: case GCT_FBUS2: case GCT_FBUS2DLR3: case GCT_FBUS2DKU5: case GCT_FBUS2PL2303: case GCT_FBUS2BLUE: case GCT_FBUS2IRDA: case GCT_PHONETBLUE: case GCT_IRDAPHONET: case GCT_BLUEFBUS2: case GCT_BLUEPHONET: s->Phone.Functions = &NAUTOPhone; break; #endif default: s->Phone.Functions = NULL; } if (s->Phone.Functions == NULL) return ERR_UNKNOWN; /* Please note, that AT module need to send first * command for enabling echo */ error=s->Phone.Functions->Initialise(s); if (error == ERR_TIMEOUT && i != s->ConfigNum - 1) continue; if (error != ERR_NONE) return error; error=s->Phone.Functions->GetModel(s); if (error == ERR_TIMEOUT && i != s->ConfigNum - 1) continue; if (error != ERR_NONE) return error; } } /* Switching to "correct" module */ error=GSM_RegisterAllPhoneModules(s); if (error!=ERR_NONE) return error; /* We didn't open device earlier ? Make it now */ if (!s->opened) { if (mystrncasecmp(s->CurrentConfig->LockDevice,"yes",0)) { error = lock_device(s->CurrentConfig->Device, &(s->LockFile)); if (error != ERR_NONE) return error; } error=s->Device.Functions->OpenDevice(s); if (i != s->ConfigNum - 1) { if (error == ERR_DEVICEOPENERROR) continue; if (error == ERR_DEVICELOCKED) continue; if (error == ERR_DEVICENOTEXIST) continue; if (error == ERR_DEVICEBUSY) continue; if (error == ERR_DEVICENOPERMISSION) continue; if (error == ERR_DEVICENODRIVER) continue; if (error == ERR_DEVICENOTWORK) continue; } if (error!=ERR_NONE) { if (s->LockFile!=NULL) unlock_device(&(s->LockFile)); return error; } s->opened = true; error=s->Protocol.Functions->Initialise(s); if (error!=ERR_NONE) return error; } error=s->Phone.Functions->Initialise(s); if (error == ERR_TIMEOUT && i != s->ConfigNum - 1) continue; if (error != ERR_NONE) return error; if (mystrncasecmp(s->CurrentConfig->StartInfo,"yes",0)) { s->Phone.Functions->ShowStartInfo(s,true); s->Phone.Data.StartInfoCounter = 30; } if (mystrncasecmp(s->CurrentConfig->SyncTime,"yes",0)) { GSM_GetCurrentDateTime (&time); s->Phone.Functions->SetDateTime(s,&time); } /* For debug it's good to have firmware and real model version and manufacturer */ error=s->Phone.Functions->GetManufacturer(s); if (error == ERR_TIMEOUT && i != s->ConfigNum - 1) continue; if (error != ERR_NONE) return error; error=s->Phone.Functions->GetModel(s); if (error != ERR_NONE) return error; error=s->Phone.Functions->GetFirmware(s); if (error != ERR_NONE) return error; return ERR_NONE; } return ERR_UNKNOWN; } int GSM_ReadDevice (GSM_StateMachine *s, bool wait) { unsigned char buff[255]; int res = 0, count; unsigned int i; GSM_DateTime Date; GSM_GetCurrentDateTime (&Date); i=Date.Second; while (i==Date.Second) { res = s->Device.Functions->ReadDevice(s, buff, 255); if (!wait) break; if (res > 0) break; my_sleep(5); GSM_GetCurrentDateTime(&Date); } for (count = 0; count < res; count++) s->Protocol.Functions->StateMachine(s,buff[count]); return res; } GSM_Error GSM_TerminateConnection(GSM_StateMachine *s) { GSM_Error error; if (!s->opened) return ERR_UNKNOWN; smprintf(s,"[Closing]\n"); if (mystrncasecmp(s->CurrentConfig->StartInfo,"yes",0)) { if (s->Phone.Data.StartInfoCounter > 0) s->Phone.Functions->ShowStartInfo(s,false); } if (s->Phone.Functions != NULL) { error=s->Phone.Functions->Terminate(s); if (error!=ERR_NONE) return error; } error=s->Protocol.Functions->Terminate(s); if (error!=ERR_NONE) return error; error = s->Device.Functions->CloseDevice(s); if (error!=ERR_NONE) return error; s->Phone.Data.ModelInfo = NULL; s->Phone.Data.Manufacturer[0] = 0; s->Phone.Data.Model[0] = 0; s->Phone.Data.Version[0] = 0; s->Phone.Data.VerDate[0] = 0; s->Phone.Data.VerNum = 0; if (s->LockFile!=NULL) unlock_device(&(s->LockFile)); if (!s->di.use_global && s->di.dl!=0 && fileno(s->di.df) != 1 && fileno(s->di.df) != 2) fclose(s->di.df); s->opened = false; return ERR_NONE; } GSM_Error GSM_WaitForOnce(GSM_StateMachine *s, unsigned char *buffer, int length, unsigned char type, int time) { GSM_Phone_Data *Phone = &s->Phone.Data; GSM_Protocol_Message sentmsg; int i; i=0; do { if (length != 0) { sentmsg.Length = length; sentmsg.Type = type; sentmsg.Buffer = (unsigned char *)malloc(length); memcpy(sentmsg.Buffer,buffer,length); Phone->SentMsg = &sentmsg; } /* Some data received. Reset timer */ if (GSM_ReadDevice(s,true)!=0) i=0; if (length != 0) { free (sentmsg.Buffer); Phone->SentMsg = NULL; } /* Request completed */ if (Phone->RequestID==ID_None) return Phone->DispatchError; i++; } while (i<time); return ERR_TIMEOUT; } GSM_Error GSM_WaitFor (GSM_StateMachine *s, unsigned char *buffer, int length, unsigned char type, int time, GSM_Phone_RequestID request) { GSM_Phone_Data *Phone = &s->Phone.Data; GSM_Error error; int reply; if (mystrncasecmp(s->CurrentConfig->StartInfo,"yes",0)) { if (Phone->StartInfoCounter > 0) { Phone->StartInfoCounter--; if (Phone->StartInfoCounter == 0) s->Phone.Functions->ShowStartInfo(s,false); } } Phone->RequestID = request; Phone->DispatchError = ERR_TIMEOUT; for (reply=0;reply<s->ReplyNum;reply++) { if (reply!=0) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl == DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl == DL_TEXTERRORDATE) { smprintf(s, "[Retrying %i type 0x%02X]\n", reply, type); } } error = s->Protocol.Functions->WriteMessage(s, buffer, length, type); if (error!=ERR_NONE) return error; error = GSM_WaitForOnce(s, buffer, length, type, time); if (error != ERR_TIMEOUT) return error; } return Phone->DispatchError; } static GSM_Error CheckReplyFunctions(GSM_StateMachine *s, GSM_Reply_Function *Reply, int *reply) { GSM_Phone_Data *Data = &s->Phone.Data; GSM_Protocol_Message *msg = s->Phone.Data.RequestMsg; bool execute; bool available = false; int i = 0; -// int j; +// int j; while (Reply[i].requestID!=ID_None) { execute=false; /* Binary frames like in Nokia */ if (strlen(Reply[i].msgtype) < 2) { if (Reply[i].msgtype[0]==msg->Type) { if (Reply[i].subtypechar!=0) { if (Reply[i].subtypechar<=msg->Length) { if (msg->Buffer[Reply[i].subtypechar]==Reply[i].subtype) execute=true; } } else execute=true; } } else { // printf("msg length %i %i\n",strlen(Reply[i].msgtype),msg->Length); if ((int)strlen(Reply[i].msgtype)<msg->Length) { // printf("Comparing \"%s\" and \"",Reply[i].msgtype); // for (j=0;j<strlen(Reply[i].msgtype);j++) { // if (msg->Buffer[j]!=13 && msg->Buffer[j]!=10) { // printf("%c",msg->Buffer[j]); // } // } // printf("\"\n"); if (strncmp(Reply[i].msgtype,msg->Buffer,strlen(Reply[i].msgtype))==0) { execute=true; } } } if (execute) { *reply=i; if (Reply[i].requestID == ID_IncomingFrame || Reply[i].requestID == Data->RequestID || Data->RequestID == ID_EachFrame) { return ERR_NONE; } available=true; } i++; } if (available) { return ERR_FRAMENOTREQUESTED; } else { return ERR_UNKNOWNFRAME; } } GSM_Error GSM_DispatchMessage(GSM_StateMachine *s) { GSM_Error error = ERR_UNKNOWNFRAME; GSM_Protocol_Message *msg = s->Phone.Data.RequestMsg; GSM_Phone_Data *Phone = &s->Phone.Data; bool disp = false; GSM_Reply_Function *Reply; int reply, i; if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) { smprintf(s, "RECEIVED frame "); smprintf(s, "type 0x%02X/length 0x%02X/%i", msg->Type, msg->Length, msg->Length); DumpMessage(s->di.use_global ? di.df : s->di.df, s->di.dl, msg->Buffer, msg->Length); if (msg->Length == 0) smprintf(s, "\n"); fflush(s->di.df); } if (s->di.dl==DL_BINARY) { smprintf(s,"%c",0x02); /* Receiving */ smprintf(s,"%c",msg->Type); smprintf(s,"%c",msg->Length/256); smprintf(s,"%c",msg->Length%256); for (i=0;i<msg->Length;i++) { smprintf(s,"%c",msg->Buffer[i]); } } Reply=s->User.UserReplyFunctions; if (Reply!=NULL) error=CheckReplyFunctions(s,Reply,&reply); if (error==ERR_UNKNOWNFRAME) { Reply=s->Phone.Functions->ReplyFunctions; error=CheckReplyFunctions(s,Reply,&reply); } if (error==ERR_NONE) { error=Reply[reply].Function(*msg, s); if (Reply[reply].requestID==Phone->RequestID) { if (error == ERR_NEEDANOTHERANSWER) { error = ERR_NONE; } else { Phone->RequestID=ID_None; } } } if (strcmp(s->Phone.Functions->models,"NAUTO")) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { disp = true; switch (error) { case ERR_UNKNOWNRESPONSE: smprintf(s, "\nUNKNOWN response"); break; case ERR_UNKNOWNFRAME: smprintf(s, "\nUNKNOWN frame"); break; case ERR_FRAMENOTREQUESTED: smprintf(s, "\nFrame not request now"); break; default: disp = false; } } if (error == ERR_UNKNOWNFRAME || error == ERR_FRAMENOTREQUESTED) { error = ERR_TIMEOUT; } } if (disp) { smprintf(s,". If you can, PLEASE report it (see readme.txt). THANK YOU\n"); if (Phone->SentMsg != NULL) { smprintf(s,"LAST SENT frame "); smprintf(s, "type 0x%02X/length %i", Phone->SentMsg->Type, Phone->SentMsg->Length); DumpMessage(s->di.use_global ? di.df : s->di.df, s->di.dl, Phone->SentMsg->Buffer, Phone->SentMsg->Length); } smprintf(s, "RECEIVED frame "); smprintf(s, "type 0x%02X/length 0x%02X/%i", msg->Type, msg->Length, msg->Length); DumpMessage(s->di.use_global ? di.df : s->di.df, s->di.dl, msg->Buffer, msg->Length); smprintf(s, "\n"); } return error; } INI_Section *GSM_FindGammuRC(void) { INI_Section *ini_file; char *HomeDrive,*HomePath,*FileName=malloc(1); int FileNameUsed=1; FileName[0] = 0; #if defined(WIN32) || defined(DJGPP) HomeDrive = getenv("HOMEDRIVE"); if (HomeDrive) { FileName = realloc(FileName,FileNameUsed+strlen(HomeDrive)+1); FileName = strcat(FileName, HomeDrive); FileNameUsed += strlen(HomeDrive)+1; } HomePath = getenv("HOMEPATH"); if (HomePath) { FileName = realloc(FileName,FileNameUsed+strlen(HomePath)+1); FileName = strcat(FileName, HomePath); FileNameUsed += strlen(HomePath)+1; } FileName = realloc(FileName,FileNameUsed+8+1); strcat(FileName, "\\gammurc"); #else HomeDrive = NULL; HomePath = getenv("HOME"); if (HomePath) { FileName = realloc(FileName,FileNameUsed+strlen(HomePath)+1); FileName = strcat(FileName, HomePath); FileNameUsed += strlen(HomePath)+1; } FileName = realloc(FileName,FileNameUsed+9+1); strcat(FileName, "/.gammurc"); #endif // dbgprintf("\"%s\"\n",FileName); ini_file = INI_ReadFile(FileName, false); free(FileName); if (ini_file == NULL) { #if defined(WIN32) || defined(DJGPP) ini_file = INI_ReadFile("gammurc", false); if (ini_file == NULL) return NULL; #else ini_file = INI_ReadFile("/etc/gammurc", false); if (ini_file == NULL) return NULL; #endif } return ini_file; } bool GSM_ReadConfig(INI_Section *cfg_info, GSM_Config *cfg, int num) { INI_Section *h; unsigned char section[50]; bool found = false; #if defined(WIN32) || defined(DJGPP) char *DefaultPort = "com2:"; #else char *DefaultPort = "/dev/ttyS1"; #endif char *DefaultModel = ""; char *DefaultConnection = "fbus"; char *DefaultSynchronizeTime = "no"; char *DefaultDebugFile = ""; char *DefaultDebugLevel = ""; char *DefaultLockDevice = "no"; char *DefaultStartInfo = "no"; char *Temp; /* By default all debug output will go to one filedescriptor */ bool DefaultUseGlobalDebugFile = true; cfg->Device = DefaultPort; cfg->Connection = DefaultConnection; cfg->SyncTime = DefaultSynchronizeTime; cfg->DebugFile = DefaultDebugFile; strcpy(cfg->Model,DefaultModel); strcpy(cfg->DebugLevel,DefaultDebugLevel); cfg->LockDevice = DefaultLockDevice; cfg->StartInfo = DefaultStartInfo; cfg->DefaultDevice = true; cfg->DefaultModel = true; cfg->DefaultConnection = true; cfg->DefaultSyncTime = true; cfg->DefaultDebugFile = true; cfg->DefaultDebugLevel = true; cfg->DefaultLockDevice = true; cfg->DefaultStartInfo = true; cfg->UseGlobalDebugFile = DefaultUseGlobalDebugFile; if (cfg_info==NULL) return false; if (num == 0) { sprintf(section,"gammu"); } else { sprintf(section,"gammu%i",num); } for (h = cfg_info; h != NULL; h = h->Next) { if (mystrncasecmp(section, h->SectionName, strlen(section))) { found = true; break; } } if (!found) return false; cfg->Device = INI_GetValue(cfg_info, section, "port", false); if (!cfg->Device) { free(cfg->Device); cfg->Device = strdup(DefaultPort); } else { cfg->DefaultDevice = false; } cfg->Connection = INI_GetValue(cfg_info, section, "connection", false); if (!cfg->Connection) { free(cfg->Connection); cfg->Connection = strdup(DefaultConnection); } else { cfg->DefaultConnection = false; } cfg->SyncTime = INI_GetValue(cfg_info, section, "synchronizetime", false); if (!cfg->SyncTime) { free(cfg->SyncTime); cfg->SyncTime = strdup(DefaultSynchronizeTime); } else { cfg->DefaultSyncTime = false; } cfg->DebugFile = INI_GetValue(cfg_info, section, "logfile", false); if (!cfg->DebugFile) { free(cfg->DebugFile); cfg->DebugFile = strdup(DefaultDebugFile); } else { cfg->DefaultDebugFile = false; } cfg->LockDevice = INI_GetValue(cfg_info, section, "use_locking", false); if (!cfg->LockDevice) { free(cfg->LockDevice); cfg->LockDevice = strdup(DefaultLockDevice); } else { cfg->DefaultLockDevice = false; } Temp = INI_GetValue(cfg_info, section, "model", false); if (!Temp) { strcpy(cfg->Model,DefaultModel); } else { cfg->DefaultModel = false; strcpy(cfg->Model,Temp); } Temp = INI_GetValue(cfg_info, section, "logformat", false); if (!Temp) { strcpy(cfg->DebugLevel,DefaultDebugLevel); } else { cfg->DefaultDebugLevel = false; strcpy(cfg->DebugLevel,Temp); } cfg->StartInfo = INI_GetValue(cfg_info, section, "startinfo", false); if (!cfg->StartInfo) { free(cfg->StartInfo); cfg->StartInfo = strdup(DefaultStartInfo); } else { cfg->DefaultStartInfo = false; } return true; } static OnePhoneModel allmodels[] = { #ifdef GSM_ENABLE_NOKIA650 {"0650" ,"THF-12","", {0}}, #endif #ifdef GSM_ENABLE_NOKIA6510 {"1100" ,"RH-18" ,"", {0}}, {"1100a","RH-38" ,"", {0}}, {"1100b","RH-36" ,"", {0}}, #endif #ifdef GSM_ENABLE_NOKIA6110 {"2100" ,"NAM-2" ,"", {F_NOWAP,F_NOCALLER,F_RING_SM,F_CAL33,F_POWER_BATT,F_PROFILES33,F_NOCALLINFO,F_NODTMF,0}},//quess #endif #ifdef GSM_ENABLE_NOKIA6510 {"3100" ,"RH-19" ,"", {F_PBKTONEGAL,F_PBKSMSLIST,0}},//fixme {"3100b","RH-50" ,"", {F_PBKTONEGAL,F_PBKSMSLIST,0}},//fixme + {"3105" ,"RH-48" ,"Nokia 3105", {F_PBKTONEGAL,F_PBKSMSLIST,F_VOICETAGS,0}},//fixme {"3108", "RH-6", "Nokia 3108", {0}}, //does it have irda ? {"3200", "RH-30" ,"Nokia 3200", {F_PBKTONEGAL,0}},//fixme {"3200a","RH-31" ,"Nokia 3200", {F_PBKTONEGAL,0}},//fixme #endif #ifdef GSM_ENABLE_NOKIA6110 {"3210" ,"NSE-8" ,"", {F_NOWAP,F_NOCALLER,F_NOCALENDAR,F_NOPBKUNICODE,F_POWER_BATT,F_PROFILES51,F_NOPICTUREUNI,F_NOCALLINFO,F_NODTMF,0}}, {"3210" ,"NSE-9" ,"", {F_NOWAP,F_NOCALLER,F_NOCALENDAR,F_NOPBKUNICODE,F_POWER_BATT,F_PROFILES51,F_NOPICTUREUNI,F_NOCALLINFO,F_NODTMF,0}}, #endif #ifdef GSM_ENABLE_NOKIA6510 {"3300" ,"NEM-1" ,"Nokia 3300", {F_PBKTONEGAL,0}},//fixme {"3300" ,"NEM-2" ,"Nokia 3300", {F_PBKTONEGAL,0}},//fixme #endif #ifdef GSM_ENABLE_NOKIA6110 {"3310" ,"NHM-5" ,"", {F_NOWAP,F_NOCALLER,F_RING_SM,F_CAL33,F_POWER_BATT,F_PROFILES33,F_NOCALLINFO,F_NODTMF,0}}, #endif #ifdef GSM_ENABLE_NOKIA3320 {"3320" ,"NPC-1" ,"Nokia 3320", {F_CAL62,F_DAYMONTH,0}},//fixme #endif #ifdef GSM_ENABLE_NOKIA6110 {"3330" ,"NHM-6" ,"", {F_NOCALLER,F_RING_SM,F_CAL33,F_PROFILES33,F_NOPICTUREUNI,F_NOCALLINFO,F_NODTMF,0}}, {"3390" ,"NPB-1" ,"", {F_NOWAP,F_NOCALLER,F_RING_SM,F_CAL33,F_PROFILES33,F_NOPICTUREUNI,F_NOCALLINFO,F_NODTMF,0}}, {"3410" ,"NHM-2" ,"", {F_RING_SM,F_CAL33,F_PROFILES33,F_NOCALLINFO,F_NODTMF,0}}, #endif #ifdef GSM_ENABLE_NOKIA6510 {"3510" ,"NHM-8" ,"", {F_CAL35,F_PBK35,F_NOGPRSPOINT,F_VOICETAGS,0}}, {"3510i","RH-9" ,"", {F_CAL35,F_PBK35,F_NOGPRSPOINT,F_VOICETAGS,0}}, {"3530" ,"RH-9" ,"", {F_CAL35,F_PBK35,F_NOGPRSPOINT,F_VOICETAGS,0}}, {"3589i","RH-44" ,"", {F_VOICETAGS,0}}, {"3590" ,"NPM-8" ,"", {0}},//irda? {"3595" ,"NPM-10" ,"", {0}},//irda? #endif #ifdef GSM_ENABLE_NOKIA6110 {"3610" ,"NAM-1" ,"", {F_NOCALLER,F_RING_SM,F_CAL33,F_POWER_BATT,F_PROFILES33,F_NOCALLINFO,F_NODTMF,0}},//quess #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA3650) {"3650" ,"NHL-8" ,"Nokia 3650", {0}}, {"NGAGE","NEM-4" ,"", {F_RADIO,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) {"5100" ,"NPM-6" ,"Nokia 5100", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, {"5100" ,"NPM-6U","Nokia 5100", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, {"5100" ,"NPM-6X","Nokia 5100", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, {"5140" ,"NPL-4" ,"Nokia 5140", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKUSER,F_WAPMMSPROXY,0}}, {"5140" ,"NPL-5" ,"Nokia 5140", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKUSER,F_WAPMMSPROXY,0}}, #endif #ifdef GSM_ENABLE_NOKIA6110 {"5110" ,"NSE-1" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, {"5110i","NSE-2" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, {"5130" ,"NSK-1" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, {"5190" ,"NSB-1" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6110) {"5210" ,"NSM-5" ,"Nokia 5210", {F_CAL52,F_NOSTARTANI,F_NOPICTUREUNI,F_NODTMF,0}}, #endif #ifdef GSM_ENABLE_NOKIA6110 {"5510" ,"NPM-5" ,"", {F_NOCALLER,F_PROFILES33,F_NOPICTUREUNI,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) {"6100" ,"NPL-2" ,"Nokia 6100", {F_PBKTONEGAL,F_TODO66,0}}, #endif #ifdef GSM_ENABLE_NOKIA6110 {"6110" ,"NSE-3" ,"", {F_NOWAP,F_NOPICTURE,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,0}}, {"6130" ,"NSK-3" ,"", {F_NOWAP,F_NOPICTURE,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,0}}, {"6150" ,"NSM-1" ,"", {F_NOWAP,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,F_NOPICTUREUNI,0}}, {"6190" ,"NSB-3" ,"", {F_NOWAP,F_NOPICTURE,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) {"6200" ,"NPL-3" ,"Nokia 6200", {F_PBKTONEGAL,0}}, {"6220" ,"RH-20" ,"Nokia 6220", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,F_PBKUSER,F_WAPMMSPROXY,F_NOTES,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA7110) {"6210" ,"NPE-3" ,"Nokia 6210", {F_VOICETAGS,F_CAL62,0}}, {"6250" ,"NHM-3" ,"Nokia 6250", {F_VOICETAGS,F_CAL62,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) {"6230" ,"RH-12" ,"Nokia 6230", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,F_PBKUSER,F_WAPMMSPROXY,F_NOTES,0}}, {"6310" ,"NPE-4" ,"Nokia 6310", {F_TODO63,F_CAL65,F_NOMIDI,F_NOMMS,F_VOICETAGS,0}}, {"6310i","NPL-1" ,"Nokia 6310i",{F_TODO63,F_CAL65,F_NOMIDI,F_BLUETOOTH,F_NOMMS,F_VOICETAGS,0}}, {"6385" ,"NHP-2AX","Nokia 6385",{F_TODO63,F_CAL65,F_NOMIDI,F_NOMMS,F_VOICETAGS,0}}, {"6510" ,"NPM-9" ,"Nokia 6510", {F_TODO63,F_CAL65,F_NOMIDI,F_RADIO,F_NOFILESYSTEM,F_NOMMS,F_VOICETAGS,0}}, {"6610" ,"NHL-4U","Nokia 6610", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, {"6610i","RM-37" ,"Nokia 6610i",{F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, {"6800" ,"NSB-9" ,"Nokia 6800", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,0}}, {"6800" ,"NHL-6" ,"Nokia 6800", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,0}}, - {"6810" ,"RM-2" ,"Nokia 6810", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,0}},//quess - {"6820" ,"NHL-9" ,"Nokia 6820", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,0}},//quess + {"6810" ,"RM-2" ,"Nokia 6810", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,F_NOTES,0}},//quess + {"6820" ,"NHL-9" ,"Nokia 6820", {F_PBKTONEGAL,F_TODO66,F_PBKSMSLIST,F_NOTES,0}},//quess #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA7110) {"7110" ,"NSE-5" ,"Nokia 7110", {F_CAL62,0}}, {"7190" ,"NSB-5" ,"Nokia 7190", {F_CAL62,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) {"7200" ,"RH-23" ,"Nokia 7200", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,F_PBKUSER,0}},//quess {"7210" ,"NHL-4" ,"Nokia 7210", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, {"7250" ,"NHL-4J","Nokia 7250", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKIMG,0}}, {"7250i","NHL-4JX","Nokia 7250i",{F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKIMG,0}}, {"7600", "NMM-3", "Nokia 7600", {F_TODO66,0}}, #endif #if defined(GSM_ENABLE_ATGEN) {"7650" ,"NHL-2" ,"Nokia 7650", {0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6110) {"8210" ,"NSM-3" ,"Nokia 8210", {F_NOWAP,F_NOSTARTANI,F_NOPBKUNICODE,F_NOPICTUREUNI,0}}, {"8250" ,"NSM-3D","Nokia 8250", {F_NOWAP,F_NOSTARTANI,F_CAL82,F_NOPICTUREUNI,0}}, {"8290" ,"NSB-7" ,"Nokia 8290", {F_NOWAP,F_NOSTARTANI,F_NOPBKUNICODE,F_NOPICTUREUNI,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) {"8310" ,"NHM-7" ,"Nokia 8310", {F_CAL62,F_NOMIDI,F_RADIO,F_NOFILESYSTEM,F_NOMMS,F_VOICETAGS,0}}, {"8390" ,"NSB-8" ,"Nokia 8390", {F_CAL62,F_NOMIDI,F_RADIO,F_NOFILESYSTEM,F_NOMMS,F_VOICETAGS,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6110) {"8850" ,"NSM-2" ,"Nokia 8850", {0}}, {"8855" ,"NSM-4" ,"Nokia 8855", {0}}, {"8890" ,"NSB-6" ,"Nokia 8890", {0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) {"8910" ,"NHM-4" ,"Nokia 8910", {F_CAL62,F_NOMIDI,F_NOFILESYSTEM,F_NOMMS,0}}, {"8910i","NHM-4" ,"Nokia 8910i",{F_CAL62,F_NOMIDI,F_NOFILESYSTEM,F_NOMMS,0}}, #endif #ifdef GSM_ENABLE_NOKIA9210 {"9210" ,"RAE-3" ,"", {0}}, {"9210i","RAE-5" ,"", {0}}, #endif #ifdef GSM_ENABLE_ATGEN {"at" , "at", "", {0}}, /* Siemens */ {"M20" , "M20", "", {F_M20SMS,F_SLOWWRITE,0}}, {"MC35" , "MC35", "", {0}}, {"TC35" , "TC35", "", {0}}, {"S25", "S25", "SIEMENS S25", {0}}, {"C35i" , "C35i", "", {0}}, {"S35i" , "S35i", "", {0}}, {"M35i" , "M35i", "", {0}}, {"S40" , "Siemens S40", "", {0}}, {"C45" , "C45", "", {0}}, {"S45" , "S45", "", {0}}, {"ME45" , "ME45", "", {0}}, {"SL45" , "SL45", "", {0}}, {"SL45i" , "SL45i", "", {0}}, {"M50" , "M50", "", {0}}, {"S45" , "6618" , "", {0}}, {"ME45" , "3618" , "", {0}}, {"S55" , "S55" , "", {0}}, /* Samsung */ {"S100" , "SGH-S100" , "", {0}}, {"S200" , "SGH-S200" , "", {0}}, {"S300" , "SGH-S300" , "", {0}}, {"S500" , "SGH-S500" , "", {0}}, {"V200" , "SGH-V200" , "", {0}}, {"T100" , "SGH-T100" , "", {0}}, {"E700" , "SGH-E700" , "", {0}}, /* Ericsson/Sony Ericsson */ {"T28s", "1101101-BVT28s","", {0}}, {"R320s" , "1101201-BV R320s","", {0}}, {"R380s", "7100101-BVR380s" ,"", {0}}, {"R520m", "1130101-BVR520m" ,"", {0}}, {"T39m", "1130102-BVT39m" ,"", {0}}, {"T65", "1101901-BVT65" , "", {0}}, {"T68", "1130201-BVT68" , "", {0}}, {"T68i", "1130202-BVT68" , "", {0}}, {"R600", "102001-BVR600" , "", {0}}, {"T200", "1130501-BVT200" ,"", {0}}, {"T300", "1130601-BVT300" ,"T300", {0}}, {"T310", "1130602-BVT310" ,"", {0}}, {"P800", "7130501-BVP800" ,"", {0}}, /* Other */ {"iPAQ" , "iPAQ" , "" , {0}}, {"A2D" , "A2D" , "" , {0}}, {"9210" , "RAE-3", "Nokia Communicator GSM900/1800",{0}}, {"myV-65", "myV-65 GPRS", "", {F_SMSME900,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_ALCATEL) {"BE5", "ONE TOUCH 500","", {F_ALCATEL,F_SMSONLYSENT,F_BROKENCPBS,0}}, {"BH4", "ONE TOUCH 535","ALCATEL OT535", {F_ALCATEL,F_SMSONLYSENT,0}}, {"BF5", "ONE TOUCH 715","ALCATEL OT715", {F_ALCATEL,F_SMSONLYSENT,F_BROKENCPBS,0}}, #endif {"unknown", "" ,"", {0}} }; OnePhoneModel *GetModelData(char *model, char *number, char *irdamodel) { int i = 0; while (strcmp(allmodels[i].number,"") != 0) { if (model !=NULL) { if (strcmp (model, allmodels[i].model) == 0) { return (&allmodels[i]); } } if (number !=NULL) { if (strcmp (number, allmodels[i].number) == 0) { return (&allmodels[i]); } } if (irdamodel !=NULL) { if (strcmp (irdamodel, allmodels[i].irdamodel) == 0) { return (&allmodels[i]); } } i++; } return (&allmodels[i]); } bool IsPhoneFeatureAvailable(OnePhoneModel *model, Feature feature) { int i = 0; bool retval = false; while (model->features[i] != 0) { if (model->features[i] == feature) { retval = true; break; } i++; } return retval; } void GSM_DumpMessageLevel2(GSM_StateMachine *s, unsigned char *message, int messagesize, int type) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) { smprintf(s,"SENDING frame "); smprintf(s,"type 0x%02X/length 0x%02X/%i", type, messagesize, messagesize); DumpMessage(s->di.use_global ? di.df : s->di.df, s->di.dl, message, messagesize); if (messagesize == 0) smprintf(s,"\n"); if (s->di.df) fflush(s->di.df); } } void GSM_DumpMessageLevel3(GSM_StateMachine *s, unsigned char *message, int messagesize, int type) { int i; if (s->di.dl==DL_BINARY) { smprintf(s,"%c",0x01); /* Sending */ smprintf(s,"%c",type); smprintf(s,"%c",messagesize/256); smprintf(s,"%c",messagesize%256); for (i=0;i<messagesize;i++) smprintf(s,"%c",message[i]); } } #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif int smprintf(GSM_StateMachine *s, const char *format, ...) { va_list argp; int result=0; unsigned char buffer[2000]; Debug_Level dl; FILE *df; va_start(argp, format); if (s == NULL) { dl = di.dl; df = di.df; } else { dl = s->di.dl; if (s->di.use_global) { df = di.df; } else { df = s->di.df; } } if (dl != 0) { result = vsprintf(buffer, format, argp); result = smfprintf(df, dl, "%s", buffer); } va_end(argp); return result; } void GSM_OSErrorInfo(GSM_StateMachine *s, char *description) { #ifdef WIN32 int i; unsigned char *lpMsgBuf; /* We don't use errno in win32 - GetLastError gives better info */ if (GetLastError()!=-1) { if (s->di.dl == DL_TEXTERROR || s->di.dl == DL_TEXT || s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXTERRORDATE || s->di.dl == DL_TEXTDATE || s->di.dl == DL_TEXTALLDATE) { FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); for (i=0;i<(int)strlen(lpMsgBuf);i++) { if (lpMsgBuf[i] == 13 || lpMsgBuf[i] == 10) { lpMsgBuf[i] = ' '; } } smprintf(s,"[System error - %s, %i, \"%s\"]\n",description,GetLastError(),(LPCTSTR)lpMsgBuf); LocalFree(lpMsgBuf); } } return; #endif if (errno!=-1) { if (s->di.dl == DL_TEXTERROR || s->di.dl == DL_TEXT || s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXTERRORDATE || s->di.dl == DL_TEXTDATE || s->di.dl == DL_TEXTALLDATE) { smprintf(s,"[System error - %s, %i, \"%s\"]\n",description,errno,strerror(errno)); } } } #ifdef GSM_ENABLE_BACKUP void GSM_GetPhoneFeaturesForBackup(GSM_StateMachine *s, GSM_Backup_Info *info) { GSM_Error error; GSM_MemoryStatus MemStatus; GSM_ToDoStatus ToDoStatus; GSM_CalendarEntry Note; GSM_WAPBookmark Bookmark; GSM_MultiWAPSettings WAPSettings; GSM_FMStation FMStation; GSM_GPRSAccessPoint GPRSPoint; // GSM_Profile Profile; if (info->PhonePhonebook) { MemStatus.MemoryType = MEM_ME; error=s->Phone.Functions->GetMemoryStatus(s, &MemStatus); if (error==ERR_NONE && MemStatus.MemoryUsed != 0) { } else { info->PhonePhonebook = false; } } if (info->SIMPhonebook) { MemStatus.MemoryType = MEM_SM; error=s->Phone.Functions->GetMemoryStatus(s, &MemStatus); if (error==ERR_NONE && MemStatus.MemoryUsed != 0) { } else { info->SIMPhonebook = false; } } if (info->Calendar) { error=s->Phone.Functions->GetNextCalendar(s,&Note,true); if (error!=ERR_NONE) info->Calendar = false; } if (info->ToDo) { error=s->Phone.Functions->GetToDoStatus(s,&ToDoStatus); if (error == ERR_NONE && ToDoStatus.Used != 0) { } else { info->ToDo = false; } } if (info->WAPBookmark) { Bookmark.Location = 1; error=s->Phone.Functions->GetWAPBookmark(s,&Bookmark); if (error == ERR_NONE) { } else { info->WAPBookmark = false; } } if (info->WAPSettings) { WAPSettings.Location = 1; error=s->Phone.Functions->GetWAPSettings(s,&WAPSettings); if (error == ERR_NONE) { } else { info->WAPSettings = false; } } if (info->MMSSettings) { WAPSettings.Location = 1; error=s->Phone.Functions->GetMMSSettings(s,&WAPSettings); if (error == ERR_NONE) { } else { info->WAPSettings = false; } } if (info->FMStation) { FMStation.Location = 1; error = s->Phone.Functions->GetFMStation(s,&FMStation); if (error == ERR_NONE || error == ERR_EMPTY) { } else { info->FMStation = false; } } if (info->GPRSPoint) { GPRSPoint.Location = 1; error = s->Phone.Functions->GetGPRSAccessPoint(s,&GPRSPoint); if (error == ERR_NONE || error == ERR_EMPTY) { } else { info->GPRSPoint = false; } } } #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/gsmstate.h b/gammu/emb/common/gsmstate.h index 2b4806c..6861fbc 100644 --- a/gammu/emb/common/gsmstate.h +++ b/gammu/emb/common/gsmstate.h @@ -1,1579 +1,1605 @@ /* (c) 2002-2004 by Marcin Wiacek & Michal Cihar */ #ifndef __gsm_state_h #define __gsm_state_h #include <time.h> #include "config.h" #include "misc/cfg.h" typedef struct _GSM_StateMachine GSM_StateMachine; typedef struct _GSM_User GSM_User; typedef struct _OnePhoneModel OnePhoneModel; typedef struct _GSM_Reply_Function GSM_Reply_Function; #ifdef GSM_ENABLE_NOKIA3320 # include "phone/nokia/dct4/n3320.h" #endif #ifdef GSM_ENABLE_NOKIA3650 # include "phone/nokia/dct4/n3650.h" #endif #ifdef GSM_ENABLE_NOKIA650 # include "phone/nokia/dct3/n0650.h" #endif #ifdef GSM_ENABLE_NOKIA6110 # include "phone/nokia/dct3/n6110.h" #endif #ifdef GSM_ENABLE_NOKIA6510 # include "phone/nokia/dct4/n6510.h" #endif #ifdef GSM_ENABLE_NOKIA7110 # include "phone/nokia/dct3/n7110.h" #endif #ifdef GSM_ENABLE_NOKIA9210 # include "phone/nokia/dct3/n9210.h" #endif #ifdef GSM_ENABLE_ATGEN # include "phone/at/atgen.h" #endif #ifdef GSM_ENABLE_ALCATEL # include "phone/alcatel/alcatel.h" #endif #ifdef GSM_ENABLE_OBEXGEN # include "phone/obex/obexgen.h" #endif #ifdef GSM_ENABLE_MROUTERGEN # include "phone/symbian/mroutgen.h" #endif #ifndef GSM_USED_MBUS2 # undef GSM_ENABLE_MBUS2 #endif #ifndef GSM_USED_FBUS2 # undef GSM_ENABLE_FBUS2 #endif #ifndef GSM_USED_FBUS2DLR3 # undef GSM_ENABLE_FBUS2DLR3 #endif #ifndef GSM_USED_FBUS2DKU5 # undef GSM_ENABLE_FBUS2DKU5 #endif #ifndef GSM_USED_FBUS2PL2303 # undef GSM_ENABLE_FBUS2PL2303 #endif #ifndef GSM_USED_FBUS2BLUE # undef GSM_ENABLE_FBUS2BLUE #endif #ifndef GSM_USED_FBUS2IRDA # undef GSM_ENABLE_FBUS2IRDA #endif #ifndef GSM_USED_PHONETBLUE # undef GSM_ENABLE_PHONETBLUE #endif #ifndef GSM_USED_AT # undef GSM_ENABLE_AT #endif #ifndef GSM_USED_IRDAOBEX # undef GSM_ENABLE_IRDAOBEX #endif #ifndef GSM_USED_BLUEOBEX # undef GSM_ENABLE_BLUEOBEX #endif #ifndef GSM_USED_ALCABUS # undef GSM_ENABLE_ALCABUS #endif #ifndef GSM_USED_IRDAPHONET # undef GSM_ENABLE_IRDAPHONET #endif #ifndef GSM_USED_BLUEFBUS2 # undef GSM_ENABLE_BLUEFBUS2 #endif #ifndef GSM_USED_BLUEPHONET # undef GSM_ENABLE_BLUEPHONET #endif #ifndef GSM_USED_BLUEAT # undef GSM_ENABLE_BLUEAT #endif #ifndef GSM_USED_IRDAAT # undef GSM_ENABLE_IRDAAT #endif #ifndef GSM_USED_MROUTERBLUE # undef GSM_ENABLE_MROUTERBLUE #endif #if defined(GSM_ENABLE_NOKIA3320) || defined(GSM_ENABLE_NOKIA650) || defined(GSM_ENABLE_NOKIA6110) || defined(GSM_ENABLE_NOKIA7110) || defined(GSM_ENABLE_NOKIA9210) # define GSM_ENABLE_NOKIA_DCT3 #endif #if defined(GSM_ENABLE_NOKIA3650) || defined(GSM_ENABLE_NOKIA6510) # define GSM_ENABLE_NOKIA_DCT4 #endif #include "protocol/protocol.h" #if defined(GSM_ENABLE_FBUS2) || defined(GSM_ENABLE_FBUS2IRDA) || defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2BLUE) || defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2DKU5) || defined(GSM_ENABLE_FBUS2PL2303) # include "protocol/nokia/fbus2.h" #endif #ifdef GSM_ENABLE_MBUS2 # include "protocol/nokia/mbus2.h" #endif #if defined(GSM_ENABLE_PHONETBLUE) || defined(GSM_ENABLE_IRDAPHONET) || defined(GSM_ENABLE_BLUEPHONET) # include "protocol/nokia/phonet.h" #endif #if defined(GSM_ENABLE_AT) || defined(GSM_ENABLE_BLUEAT) || defined(GSM_ENABLE_IRDAAT) # include "protocol/at/at.h" #endif #ifdef GSM_ENABLE_ALCABUS # include "protocol/alcatel/alcabus.h" #endif #if defined(GSM_ENABLE_IRDAOBEX) || defined(GSM_ENABLE_BLUEOBEX) # include "protocol/obex/obex.h" #endif #if defined(GSM_ENABLE_MROUTERBLUE) # include "protocol/symbian/mrouter.h" #endif #define GSM_ENABLE_SERIALDEVICE #ifndef GSM_USED_SERIALDEVICE # undef GSM_ENABLE_SERIALDEVICE #endif #define GSM_ENABLE_IRDADEVICE #ifndef GSM_USED_IRDADEVICE # undef GSM_ENABLE_IRDADEVICE #endif #define GSM_ENABLE_BLUETOOTHDEVICE #ifndef GSM_USED_BLUETOOTHDEVICE # undef GSM_ENABLE_BLUETOOTHDEVICE #endif #ifdef DJGPP # undef GSM_ENABLE_IRDADEVICE # undef GSM_ENABLE_IRDAPHONET # undef GSM_ENABLE_IRDAOBEX # undef GSM_ENABLE_IRDAAT # undef GSM_ENABLE_FBUS2IRDA # undef GSM_ENABLE_BLUETOOTHDEVICE # undef GSM_ENABLE_BLUEPHONET # undef GSM_ENABLE_BLUEOBEX # undef GSM_ENABLE_BLUEAT # undef GSM_ENABLE_BLUEFBUS2 # undef GSM_ENABLE_PHONETBLUE # undef GSM_ENABLE_FBUS2BLUE # undef GSM_ENABLE_MROUTERBLUE #endif #ifndef WIN32 # ifdef ENABLE_LGPL # undef GSM_ENABLE_IRDADEVICE # undef GSM_ENABLE_IRDAPHONET # undef GSM_ENABLE_IRDAOBEX # undef GSM_ENABLE_IRDAAT # undef GSM_ENABLE_FBUS2IRDA # undef GSM_ENABLE_BLUETOOTHDEVICE # undef GSM_ENABLE_BLUEPHONET # undef GSM_ENABLE_BLUEOBEX # undef GSM_ENABLE_BLUEAT # undef GSM_ENABLE_BLUEFBUS2 # undef GSM_ENABLE_PHONETBLUE # undef GSM_ENABLE_FBUS2BLUE # undef GSM_ENABLE_MROUTERBLUE # endif #endif #ifdef GSM_ENABLE_SERIALDEVICE # include "device/serial/ser_w32.h" # include "device/serial/ser_unx.h" # include "device/serial/ser_djg.h" #endif #ifdef GSM_ENABLE_IRDADEVICE # include "device/irda/irda.h" #endif #ifdef GSM_ENABLE_BLUETOOTHDEVICE # include "device/bluetoth/bluetoth.h" #endif #include "service/gsmpbk.h" #include "service/gsmnet.h" #include "service/gsmring.h" #include "service/gsmcal.h" #include "service/gsmdata.h" #include "service/gsmlogo.h" #include "service/gsmmisc.h" #include "service/gsmprof.h" #include "service/gsmcall.h" #include "service/sms/gsmsms.h" #include "service/sms/gsmems.h" #include "service/sms/gsmmulti.h" #include "service/backup/gsmback.h" /* ------------------------- Device layer ---------------------------------- */ /** * Device functions, each device has to provide these. */ typedef struct { /** * Opens device. */ GSM_Error (*OpenDevice) (GSM_StateMachine *s); /** * Closes device. */ GSM_Error (*CloseDevice) (GSM_StateMachine *s); /** * Sets parity for device. */ GSM_Error (*DeviceSetParity) (GSM_StateMachine *s, bool parity); /** * Sets dtr (data to read) and rts (ready to send) flags. */ GSM_Error (*DeviceSetDtrRts) (GSM_StateMachine *s, bool dtr, bool rts); /** * Sets device speed. */ GSM_Error (*DeviceSetSpeed) (GSM_StateMachine *s, int speed); /** * Attempts to read nbytes from device. */ int (*ReadDevice) (GSM_StateMachine *s, void *buf, size_t nbytes); /** * Attempts to read nbytes from device. */ int (*WriteDevice) (GSM_StateMachine *s, void *buf, size_t nbytes); } GSM_Device_Functions; #ifdef GSM_ENABLE_SERIALDEVICE extern GSM_Device_Functions SerialDevice; #endif #ifdef GSM_ENABLE_IRDADEVICE extern GSM_Device_Functions IrdaDevice; #endif #ifdef GSM_ENABLE_BLUETOOTHDEVICE extern GSM_Device_Functions BlueToothDevice; #endif /** * Structure containing device specific data and pointer to device functions - * @ref GSM_Device_Functions. The data are in a union, so you can use only * one device at one time. */ typedef struct { union { char fake; #ifdef GSM_ENABLE_SERIALDEVICE GSM_Device_SerialData Serial; #endif #ifdef GSM_ENABLE_IRDADEVICE GSM_Device_IrdaData Irda; #endif #ifdef GSM_ENABLE_BLUETOOTHDEVICE GSM_Device_BlueToothData BlueTooth; #endif } Data; GSM_Device_Functions *Functions; } GSM_Device; /* ---------------------- Protocol layer ----------------------------------- */ /** * Protocol functions, each protocol has to implement these. */ typedef struct { /** * Writes message to device. */ GSM_Error (*WriteMessage) (GSM_StateMachine *s, unsigned char *buffer, int length, unsigned char type); /** * This one is called when character is received from device. */ GSM_Error (*StateMachine) (GSM_StateMachine *s, unsigned char rx_char); /** * Protocol initialisation. */ GSM_Error (*Initialise) (GSM_StateMachine *s); /** * Protocol termination. */ GSM_Error (*Terminate) (GSM_StateMachine *s); } GSM_Protocol_Functions; #ifdef GSM_ENABLE_MBUS2 extern GSM_Protocol_Functions MBUS2Protocol; #endif #if defined(GSM_ENABLE_FBUS2) || defined(GSM_ENABLE_FBUS2IRDA) || defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2DKU5) || defined(GSM_ENABLE_FBUS2BLUE) || defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2PL2303) extern GSM_Protocol_Functions FBUS2Protocol; #endif #if defined(GSM_ENABLE_PHONETBLUE) || defined(GSM_ENABLE_IRDAPHONET) || defined(GSM_ENABLE_BLUEPHONET) extern GSM_Protocol_Functions PHONETProtocol; #endif #if defined(GSM_ENABLE_AT) || defined(GSM_ENABLE_BLUEAT) || defined(GSM_ENABLE_IRDAAT) extern GSM_Protocol_Functions ATProtocol; #endif #ifdef GSM_ENABLE_ALCABUS extern GSM_Protocol_Functions ALCABUSProtocol; #endif #if defined(GSM_ENABLE_IRDAOBEX) || defined(GSM_ENABLE_BLUEOBEX) extern GSM_Protocol_Functions OBEXProtocol; #endif #if defined(GSM_ENABLE_MROUTERBLUE) extern GSM_Protocol_Functions MROUTERProtocol; #endif /** * Structure containing protocol specific data and pointer to protocol * functions - @ref GSM_Protocol_Functions. The data are in a structure, so * you may use more protocols at once and switch between them. */ typedef struct { struct { char fake; #ifdef GSM_ENABLE_MBUS2 GSM_Protocol_MBUS2Data MBUS2; #endif #if defined(GSM_ENABLE_FBUS2) || defined(GSM_ENABLE_FBUS2IRDA) || defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2DKU5) || defined(GSM_ENABLE_FBUS2PL2303) || defined(GSM_ENABLE_FBUS2BLUE) || defined(GSM_ENABLE_BLUEFBUS2) GSM_Protocol_FBUS2Data FBUS2; #endif #if defined(GSM_ENABLE_PHONETBLUE) || defined(GSM_ENABLE_IRDAPHONET) || defined(GSM_ENABLE_BLUEPHONET) GSM_Protocol_PHONETData PHONET; #endif #if defined(GSM_ENABLE_AT) || defined(GSM_ENABLE_BLUEAT) || defined(GSM_ENABLE_IRDAAT) GSM_Protocol_ATData AT; #endif #ifdef GSM_ENABLE_ALCABUS GSM_Protocol_ALCABUSData ALCABUS; #endif #if defined(GSM_ENABLE_IRDAOBEX) || defined(GSM_ENABLE_BLUEOBEX) GSM_Protocol_OBEXData OBEX; #endif #if defined(GSM_ENABLE_MROUTERBLUE) GSM_Protocol_MROUTERData MROUTER; #endif } Data; GSM_Protocol_Functions *Functions; } GSM_Protocol; /* -------------------------- Phone layer ---------------------------------- */ /** * Phone requests identificators, these are used for internally identifying * which operation is being performed. */ typedef enum { ID_None=1, ID_GetModel, ID_GetFirmware, ID_EnableSecurity, ID_GetIMEI, ID_GetDateTime, ID_GetAlarm, ID_GetMemory, ID_GetMemoryStatus, ID_GetSMSC, ID_GetSMSMessage, ID_EnableEcho, ID_EnableErrorInfo, ID_SetOBEX, ID_SetUSSD, ID_GetNote, + ID_SetNote, ID_GetSignalQuality, ID_GetBatteryCharge, ID_GetSMSFolders, ID_GetSMSFolderStatus, ID_GetSMSStatus, ID_AddSMSFolder, ID_GetNetworkInfo, ID_GetRingtone, ID_DialVoice, ID_GetCalendarNotesInfo, ID_GetCalendarNote, ID_GetSecurityCode, ID_GetWAPBookmark, ID_GetBitmap, ID_SaveSMSMessage, ID_CancelCall, ID_SetDateTime, ID_SetAlarm, ID_DisableConnectFunc, ID_EnableConnectFunc, ID_AnswerCall, ID_SetBitmap, ID_SetRingtone, ID_DeleteSMSMessage, ID_DeleteCalendarNote, ID_SetPath, ID_SetSMSC, ID_SetProfile, ID_SetMemory, ID_DeleteMemory, ID_SetCalendarNote, ID_SetIncomingSMS, ID_SetIncomingCB, ID_GetCalendarNotePos, ID_Initialise, ID_GetConnectSet, ID_SetWAPBookmark, ID_GetLocale, ID_SetLocale, ID_GetCalendarSettings, ID_SetCalendarSettings, ID_GetGPRSPoint, ID_SetGPRSPoint, ID_EnableGPRSPoint, ID_DeleteWAPBookmark, ID_Netmonitor, ID_HoldCall, ID_UnholdCall, ID_ConferenceCall, ID_SplitCall, ID_TransferCall, ID_SwitchCall, ID_GetManufactureMonth, ID_GetProductCode, ID_GetOriginalIMEI, ID_GetHardware, ID_GetPPM, ID_GetSMSMode, ID_GetSMSMemories, ID_GetManufacturer, ID_SetMemoryType, ID_SetMemoryCharset, ID_GetMMSSettings, ID_SetSMSParameters, ID_GetFMStation, ID_SetFMStation, ID_GetLanguage, ID_SetFastSMSSending, ID_Reset, ID_GetToDo, ID_PressKey, ID_DeleteAllToDo, ID_SetLight, ID_Divert, ID_SetToDo, ID_PlayTone, ID_GetChatSettings, ID_GetSyncMLSettings, ID_GetSyncMLName, ID_GetSecurityStatus, ID_EnterSecurityCode, ID_GetProfile, ID_GetRingtonesInfo, ID_MakeAuthentication, ID_GetSpeedDial, ID_ResetPhoneSettings, ID_SendDTMF, ID_GetDisplayStatus, ID_SetAutoNetworkLogin, ID_SetConnectSet, ID_SetMMSSettings, ID_GetSIMIMSI, ID_GetFileInfo, ID_FileSystemStatus, ID_GetFile, ID_AddFile, ID_AddFolder, ID_DeleteFile, #ifdef GSM_ENABLE_ALCATEL /* AT mode */ ID_SetFlowControl, ID_AlcatelConnect, ID_AlcatelProtocol, /* Binary mode */ ID_AlcatelAttach, ID_AlcatelDetach, ID_AlcatelCommit, ID_AlcatelCommit2, ID_AlcatelEnd, ID_AlcatelClose, ID_AlcatelStart, ID_AlcatelSelect1, ID_AlcatelSelect2, ID_AlcatelSelect3, ID_AlcatelBegin1, ID_AlcatelBegin2, ID_AlcatelGetIds1, ID_AlcatelGetIds2, ID_AlcatelGetCategories1, ID_AlcatelGetCategories2, ID_AlcatelGetCategoryText1, ID_AlcatelGetCategoryText2, ID_AlcatelAddCategoryText1, ID_AlcatelAddCategoryText2, ID_AlcatelGetFields1, ID_AlcatelGetFields2, ID_AlcatelGetFieldValue1, ID_AlcatelGetFieldValue2, ID_AlcatelDeleteItem1, ID_AlcatelDeleteItem2, ID_AlcatelDeleteField, ID_AlcatelCreateField, ID_AlcatelUpdateField, #endif ID_IncomingFrame, ID_User1, ID_User2, ID_User3, ID_User4, ID_User5, ID_User6, ID_User7, ID_User8, ID_User9, ID_User10, ID_EachFrame } GSM_Phone_RequestID; /** * Phone related data are stored here. */ typedef struct { /** * Phone IMEI (or serial number). */ char IMEI[MAX_IMEI_LENGTH]; /** * Phone manufacturer as reported by phone. */ char Manufacturer[MAX_MANUFACTURER_LENGTH]; /** * Phone model as reported by phone. */ char Model[MAX_MODEL_LENGTH]; /** * Model information, pointer to static @ref allmodels array. */ OnePhoneModel *ModelInfo; /** * Phone version as reported by phone. It doesn't have to be numerical * at all. */ char Version[MAX_VERSION_LENGTH]; /** * Phone version date, might be empty for some models. */ char VerDate[MAX_VERSION_DATE_LENGTH]; /** * Phone version as number, if applicable. */ double VerNum; /** * Cache for hardware version used by some modules. */ char HardwareCache[50]; /** * Cache for product code version used by some modules. */ char ProductCodeCache[50]; /** * Counter used for disabling startup info on phone, see * @ref GSM_Phone_Functions::ShowStartInfo . After this is 0, the startup info is hidden. */ int StartInfoCounter; /** * Pointer to structure used internally by phone drivers. */ GSM_GPRSAccessPoint *GPRSPoint; /** * Pointer to structure used internally by phone drivers. */ GSM_SpeedDial *SpeedDial; /** * Pointer to structure used internally by phone drivers. */ GSM_DateTime *DateTime; /** * Pointer to structure used internally by phone drivers. */ GSM_Alarm *Alarm; /** * Pointer to structure used internally by phone drivers. */ GSM_MemoryEntry *Memory; /** * Pointer to structure used internally by phone drivers. */ GSM_MemoryStatus *MemoryStatus; /** * Pointer to structure used internally by phone drivers. */ GSM_SMSC *SMSC; /** * Pointer to structure used internally by phone drivers. */ GSM_MultiSMSMessage *GetSMSMessage; /** * Pointer to structure used internally by phone drivers. */ GSM_SMSMessage *SaveSMSMessage; /** * Pointer to structure used internally by phone drivers. */ GSM_SMSMemoryStatus *SMSStatus; /** * Pointer to structure used internally by phone drivers. */ GSM_SMSFolders *SMSFolders; /** * Used internally by phone drivers. */ int *VoiceRecord; /** * Used internally by phone drivers. */ int CallID; /** * Pointer to structure used internally by phone drivers. */ GSM_SignalQuality *SignalQuality; /** * Pointer to structure used internally by phone drivers. */ GSM_BatteryCharge *BatteryCharge; /** * Pointer to structure used internally by phone drivers. */ GSM_NetworkInfo *NetworkInfo; /** * Pointer to structure used internally by phone drivers. */ GSM_Ringtone *Ringtone; /** * Pointer to structure used internally by phone drivers. */ GSM_CalendarEntry *Cal; /** * Used internally by phone drivers. */ unsigned char *SecurityCode; /** * Pointer to structure used internally by phone drivers. */ GSM_WAPBookmark *WAPBookmark; /** * Pointer to structure used internally by phone drivers. */ GSM_MultiWAPSettings *WAPSettings; /** * Pointer to structure used internally by phone drivers. */ GSM_Bitmap *Bitmap; /** * Used internally by phone drivers. */ unsigned char *Netmonitor; /** * Pointer to structure used internally by phone drivers. */ GSM_MultiCallDivert *Divert; /** * Pointer to structure used internally by phone drivers. */ GSM_ToDoEntry *ToDo; GSM_NoteEntry *Note; /** * Used internally by phone drivers. */ bool PressKey; /** * Pointer to structure used internally by phone drivers. */ GSM_SecurityCodeType *SecurityStatus; /** * Pointer to structure used internally by phone drivers. */ GSM_Profile *Profile; /** * Pointer to structure used internally by phone drivers. */ GSM_AllRingtonesInfo *RingtonesInfo; /** * Pointer to structure used internally by phone drivers. */ GSM_DisplayFeatures *DisplayFeatures; /** * Pointer to structure used internally by phone drivers. */ GSM_FMStation *FMStation; /** * Pointer to structure used internally by phone drivers. */ GSM_Locale *Locale; /** * Pointer to structure used internally by phone drivers. */ GSM_CalendarSettings *CalendarSettings; /** * Used internally by phone drivers. */ unsigned char *PhoneString; /** * Used internally by phone drivers. */ int StartPhoneString; /** * Pointer to structure used internally by phone drivers. */ GSM_File *FileInfo; /** * Pointer to structure used internally by phone drivers. */ GSM_File *File; /** * Pointer to structure used internally by phone drivers. */ GSM_FileSystemStatus *FileSystemStatus; GSM_ChatSettings *ChatSettings; GSM_SyncMLSettings *SyncMLSettings; /** * Should phone notify about incoming calls? */ bool EnableIncomingCall; /** * Should phone notify about incoming SMSes? */ bool EnableIncomingSMS; /** * Should phone notify about incoming CBs? */ bool EnableIncomingCB; /** * Should phone notify about incoming USSDs? */ bool EnableIncomingUSSD; /** * Last message received from phone. */ GSM_Protocol_Message *RequestMsg; /** * Last message sent by Gammu. */ GSM_Protocol_Message *SentMsg; /** * What operation is being performed now, see @ref GSM_Phone_RequestID * for possible values. */ GSM_Phone_RequestID RequestID; /** * Error returned by function in phone module. */ GSM_Error DispatchError; /** * Structure with private phone modules data. */ struct { int fake; #ifdef GSM_ENABLE_NOKIA3320 GSM_Phone_N3320Data N3320; #endif #ifdef GSM_ENABLE_NOKIA3650 GSM_Phone_N3650Data N3650; #endif #ifdef GSM_ENABLE_NOKIA650 GSM_Phone_N650Data N650; #endif #ifdef GSM_ENABLE_NOKIA6110 GSM_Phone_N6110Data N6110; #endif #ifdef GSM_ENABLE_NOKIA6510 GSM_Phone_N6510Data N6510; #endif #ifdef GSM_ENABLE_NOKIA7110 GSM_Phone_N7110Data N7110; #endif #ifdef GSM_ENABLE_ATGEN GSM_Phone_ATGENData ATGEN; #endif #ifdef GSM_ENABLE_ALCATEL GSM_Phone_ALCATELData ALCATEL; #endif #ifdef GSM_ENABLE_OBEXGEN GSM_Phone_OBEXGENData OBEXGEN; #endif #ifdef GSM_ENABLE_MROUTERGEN GSM_Phone_MROUTERGENData MROUTERGEN; #endif } Priv; } GSM_Phone_Data; /** * Structure for defining reply functions. * * Function is called when requestID matches current operation or is * ID_IncomingFrame and msgtype matches start message and (if msgtype is just * one character) subtypechar is zero or subtypechar-th character of message * matches subtype. * * Should be used in array with last element containing ID_None as requestID. */ struct _GSM_Reply_Function { /** * Pointer to function that should be executed. */ GSM_Error (*Function) (GSM_Protocol_Message msg, GSM_StateMachine *s); /** * Message type, if it is longer than 1 character, it disables subtype * checking. */ unsigned char *msgtype; /** * Which character of message should be checked as subtype. Zero to * disable subtype checking. */ int subtypechar; /** * Subtype to be checked. */ unsigned char subtype; /** * Phone request when this can be called, use ID_IncomingFrame when * you want to use this in any state. */ GSM_Phone_RequestID requestID; }; /** * Structure defining phone functions. */ typedef struct { /** * Names of supported models separated by |. Must contain at least one * name. */ char *models; /** * Array of reply functions for the phone, see * @ref GSM_Reply_Function for details about it. */ GSM_Reply_Function *ReplyFunctions; /** * Initializes phone. */ GSM_Error (*Initialise) (GSM_StateMachine *s); /** * Terminates phone communication. */ GSM_Error (*Terminate) (GSM_StateMachine *s); /** * Dispatches messages from phone, at the end it should call * @ref GSM_DispatchMessage. */ GSM_Error (*DispatchMessage) (GSM_StateMachine *s); /** * Enables showing information on phone display. */ GSM_Error (*ShowStartInfo) (GSM_StateMachine *s, bool enable); /** * Reads manufacturer from phone. */ GSM_Error (*GetManufacturer) (GSM_StateMachine *s); /** * Reads model from phone. */ GSM_Error (*GetModel) (GSM_StateMachine *s); /** * Reads firmware information from phone. */ GSM_Error (*GetFirmware) (GSM_StateMachine *s); /** * Reads IMEI/serial number from phone. */ GSM_Error (*GetIMEI) (GSM_StateMachine *s); /** * Gets date and time from phone. */ GSM_Error (*GetOriginalIMEI) (GSM_StateMachine *s, char *value); /** * Gets month when device was manufactured. */ GSM_Error (*GetManufactureMonth)(GSM_StateMachine *s, char *value); /** * Gets product code of device. */ GSM_Error (*GetProductCode) (GSM_StateMachine *s, char *value); /** * Gets hardware information about device. */ GSM_Error (*GetHardware) (GSM_StateMachine *s, char *value); /** * Gets PPM (Post Programmable Memory) info from phone * (in other words for Nokia get, which language pack is in phone) */ GSM_Error (*GetPPM) (GSM_StateMachine *s, char *value); /** * Gets SIM IMSI from phone. */ GSM_Error (*GetSIMIMSI) (GSM_StateMachine *s, char *IMSI); /** * Reads date and time from phone. */ GSM_Error (*GetDateTime) (GSM_StateMachine *s, GSM_DateTime *date_time); /** * Sets date and time in phone. */ GSM_Error (*SetDateTime) (GSM_StateMachine *s, GSM_DateTime *date_time); /** * Reads alarm set in phone. */ GSM_Error (*GetAlarm) (GSM_StateMachine *s, GSM_Alarm *alarm); /** * Sets alarm in phone. */ GSM_Error (*SetAlarm) (GSM_StateMachine *s, GSM_Alarm *alarm); /** * Gets locale from phone. */ GSM_Error (*GetLocale) (GSM_StateMachine *s, GSM_Locale *locale); /** * Sets locale of phone. */ GSM_Error (*SetLocale) (GSM_StateMachine *s, GSM_Locale *locale); /** * Emulates key press or key release. */ GSM_Error (*PressKey) (GSM_StateMachine *s, GSM_KeyCode Key, bool Press); /** * Performs phone reset. */ GSM_Error (*Reset) (GSM_StateMachine *s, bool hard); /** * Resets phone settings. */ GSM_Error (*ResetPhoneSettings) (GSM_StateMachine *s, GSM_ResetSettingsType Type); /** * Enters security code (PIN, PUK,...) . */ GSM_Error (*EnterSecurityCode) (GSM_StateMachine *s, GSM_SecurityCode Code); /** * Queries whether some security code needs to be entered./ */ GSM_Error (*GetSecurityStatus) (GSM_StateMachine *s, GSM_SecurityCodeType *Status); /** * Acquired display status. */ GSM_Error (*GetDisplayStatus) (GSM_StateMachine *s, GSM_DisplayFeatures *features); /** * Enables network auto login. */ GSM_Error (*SetAutoNetworkLogin)(GSM_StateMachine *s); /** * Gets information about batery charge and phone charging state. */ GSM_Error (*GetBatteryCharge) (GSM_StateMachine *s, GSM_BatteryCharge *bat); /** * Reads signal quality (strength and error rate). */ GSM_Error (*GetSignalQuality) (GSM_StateMachine *s, GSM_SignalQuality *sig); /** * Gets network information. */ GSM_Error (*GetNetworkInfo) (GSM_StateMachine *s, GSM_NetworkInfo *netinfo); /** * Reads category from phone. */ GSM_Error (*GetCategory) (GSM_StateMachine *s, GSM_Category *Category); /** * Adds category to phone. */ GSM_Error (*AddCategory) (GSM_StateMachine *s, GSM_Category *Category); /** * Reads category status (number of used entries) from phone. */ GSM_Error (*GetCategoryStatus) (GSM_StateMachine *s, GSM_CategoryStatus *Status); /** * Gets memory (phonebooks or calls) status (eg. number of used and * free entries). */ GSM_Error (*GetMemoryStatus) (GSM_StateMachine *s, GSM_MemoryStatus *status); /** * Reads entry from memory (phonebooks or calls). Which entry should * be read is defined in entry. */ GSM_Error (*GetMemory) (GSM_StateMachine *s, GSM_MemoryEntry *entry); /** * Reads entry from memory (phonebooks or calls). Which entry should * be read is defined in entry. This can be easily used for reading all entries. */ GSM_Error (*GetNextMemory) (GSM_StateMachine *s, GSM_MemoryEntry *entry, bool start); /** * Sets memory (phonebooks or calls) entry. */ GSM_Error (*SetMemory) (GSM_StateMachine *s, GSM_MemoryEntry *entry); /** * Deletes memory (phonebooks or calls) entry. */ GSM_Error (*AddMemory) (GSM_StateMachine *s, GSM_MemoryEntry *entry); /** * Deletes memory (phonebooks or calls) entry. */ GSM_Error (*DeleteMemory) (GSM_StateMachine *s, GSM_MemoryEntry *entry); /** * Deletes all memory (phonebooks or calls) entries of specified type. */ GSM_Error (*DeleteAllMemory) (GSM_StateMachine *s, GSM_MemoryType MemoryType); /** * Gets speed dial. */ GSM_Error (*GetSpeedDial) (GSM_StateMachine *s, GSM_SpeedDial *Speed); /** * Sets speed dial. */ GSM_Error (*SetSpeedDial) (GSM_StateMachine *s, GSM_SpeedDial *Speed); /** * Gets SMS Service Center number and SMS settings. */ GSM_Error (*GetSMSC) (GSM_StateMachine *s, GSM_SMSC *smsc); /** * Sets SMS Service Center number and SMS settings. */ GSM_Error (*SetSMSC) (GSM_StateMachine *s, GSM_SMSC *smsc); /** * Gets information about SMS memory (read/unread/size of memory for * both SIM and phone). */ GSM_Error (*GetSMSStatus) (GSM_StateMachine *s, GSM_SMSMemoryStatus *status); /** * Reads SMS message. */ GSM_Error (*GetSMS) (GSM_StateMachine *s, GSM_MultiSMSMessage *sms); /** * Reads next (or first if start set) SMS message. This might be * faster for some phones than using @ref GetSMS for each message. */ GSM_Error (*GetNextSMS) (GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start); /** * Sets SMS. */ GSM_Error (*SetSMS) (GSM_StateMachine *s, GSM_SMSMessage *sms); /** * Adds SMS to specified folder. */ GSM_Error (*AddSMS) (GSM_StateMachine *s, GSM_SMSMessage *sms); /** * Deletes SMS. */ GSM_Error (*DeleteSMS) (GSM_StateMachine *s, GSM_SMSMessage *sms); /** * Sends SMS. */ GSM_Error (*SendSMS) (GSM_StateMachine *s, GSM_SMSMessage *sms); /** * Sends SMS already saved in phone. */ GSM_Error (*SendSavedSMS) (GSM_StateMachine *s, int Folder, int Location); GSM_Error (*SetFastSMSSending) (GSM_StateMachine *s, bool enable); /** * Enable/disable notification on incoming SMS. */ GSM_Error (*SetIncomingSMS) (GSM_StateMachine *s, bool enable); /** * Gets network information from phone. */ GSM_Error (*SetIncomingCB) (GSM_StateMachine *s, bool enable); /** * Returns SMS folders information. */ GSM_Error (*GetSMSFolders) (GSM_StateMachine *s, GSM_SMSFolders *folders); /** * Creates SMS folder. */ GSM_Error (*AddSMSFolder) (GSM_StateMachine *s, unsigned char *name); /** * Deletes SMS folder. */ GSM_Error (*DeleteSMSFolder) (GSM_StateMachine *s, int ID); /** * Dials number and starts voice call. */ GSM_Error (*DialVoice) (GSM_StateMachine *s, char *Number, GSM_CallShowNumber ShowNumber); /** * Accept current incoming call. */ GSM_Error (*AnswerCall) (GSM_StateMachine *s, int ID, bool all); /** * Deny current incoming call. */ GSM_Error (*CancelCall) (GSM_StateMachine *s, int ID, bool all); /** * Holds call. */ GSM_Error (*HoldCall) (GSM_StateMachine *s, int ID); /** * Unholds call. */ GSM_Error (*UnholdCall) (GSM_StateMachine *s, int ID); /** * Initiates conference call. */ GSM_Error (*ConferenceCall) (GSM_StateMachine *s, int ID); /** * Splits call. */ GSM_Error (*SplitCall) (GSM_StateMachine *s, int ID); /** * Transfers call. */ GSM_Error (*TransferCall) (GSM_StateMachine *s, int ID, bool next); /** * Switches call. */ GSM_Error (*SwitchCall) (GSM_StateMachine *s, int ID, bool next); /** * Gets call diverts. */ GSM_Error (*GetCallDivert) (GSM_StateMachine *s, GSM_MultiCallDivert *divert); /** * Sets call diverts. */ GSM_Error (*SetCallDivert) (GSM_StateMachine *s, GSM_MultiCallDivert *divert); /** * Cancels all diverts. */ GSM_Error (*CancelAllDiverts) (GSM_StateMachine *s); /** * Activates/deactivates noticing about incoming calls. */ GSM_Error (*SetIncomingCall) (GSM_StateMachine *s, bool enable); /** * Activates/deactivates noticing about incoming USSDs (UnStructured Supplementary Services). */ GSM_Error (*SetIncomingUSSD) (GSM_StateMachine *s, bool enable); /** * Sends DTMF (Dual Tone Multi Frequency) tone. */ GSM_Error (*SendDTMF) (GSM_StateMachine *s, char *sequence); /** * Gets ringtone from phone. */ GSM_Error (*GetRingtone) (GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone); /** * Sets ringtone in phone. */ GSM_Error (*SetRingtone) (GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength); /** * Acquires ringtone informaiton. */ GSM_Error (*GetRingtonesInfo) (GSM_StateMachine *s, GSM_AllRingtonesInfo *Info); /** * Deletes user defined ringtones from phone. */ GSM_Error (*DeleteUserRingtones)(GSM_StateMachine *s); /** * Plays tone. */ GSM_Error (*PlayTone) (GSM_StateMachine *s, int Herz, unsigned char Volume, bool start); /** * Reads WAP bookmark. */ GSM_Error (*GetWAPBookmark) (GSM_StateMachine *s, GSM_WAPBookmark *bookmark); /** * Sets WAP bookmark. */ GSM_Error (*SetWAPBookmark) (GSM_StateMachine *s, GSM_WAPBookmark *bookmark); /** * Deletes WAP bookmark. */ GSM_Error (*DeleteWAPBookmark) (GSM_StateMachine *s, GSM_WAPBookmark *bookmark); /** * Acquires WAP settings. */ GSM_Error (*GetWAPSettings) (GSM_StateMachine *s, GSM_MultiWAPSettings *settings); /** * Changes WAP settings. */ GSM_Error (*SetWAPSettings) (GSM_StateMachine *s, GSM_MultiWAPSettings *settings); /** * Acquires MMS settings. */ GSM_Error (*GetMMSSettings) (GSM_StateMachine *s, GSM_MultiWAPSettings *settings); /** * Changes MMS settings. */ GSM_Error (*SetMMSSettings) (GSM_StateMachine *s, GSM_MultiWAPSettings *settings); /** * Acquires SyncML settings. */ GSM_Error (*GetSyncMLSettings) (GSM_StateMachine *s, GSM_SyncMLSettings *settings); /** * Changes SyncML settings. */ GSM_Error (*SetSyncMLSettings) (GSM_StateMachine *s, GSM_SyncMLSettings *settings); /** * Acquires chat/presence settings. */ GSM_Error (*GetChatSettings) (GSM_StateMachine *s, GSM_ChatSettings *settings); /** * Changes chat/presence settings. */ GSM_Error (*SetChatSettings) (GSM_StateMachine *s, GSM_ChatSettings *settings); /** * Gets bitmap. */ GSM_Error (*GetBitmap) (GSM_StateMachine *s, GSM_Bitmap *Bitmap); /** * Sets bitmap. */ GSM_Error (*SetBitmap) (GSM_StateMachine *s, GSM_Bitmap *Bitmap); /** * Gets status of ToDos (count of used entries). */ GSM_Error (*GetToDoStatus) (GSM_StateMachine *s, GSM_ToDoStatus *status); /** * Reads ToDo from phone. */ GSM_Error (*GetToDo) (GSM_StateMachine *s, GSM_ToDoEntry *ToDo); /** * Reads ToDo from phone. */ GSM_Error (*GetNextToDo) (GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start); /** * Sets ToDo in phone. */ GSM_Error (*SetToDo) (GSM_StateMachine *s, GSM_ToDoEntry *ToDo); /** * Adds ToDo in phone. */ GSM_Error (*AddToDo) (GSM_StateMachine *s, GSM_ToDoEntry *ToDo); /** * Deletes ToDo entry in phone. */ GSM_Error (*DeleteToDo) (GSM_StateMachine *s, GSM_ToDoEntry *ToDo); /** * Deletes all todo entries in phone. */ GSM_Error (*DeleteAllToDo) (GSM_StateMachine *s); /** * Retrieves calendar status (number of used entries). */ GSM_Error (*GetCalendarStatus) (GSM_StateMachine *s, GSM_CalendarStatus *Status); /** * Retrieves calendar entry. */ GSM_Error (*GetCalendar) (GSM_StateMachine *s, GSM_CalendarEntry *Note); /** * Retrieves calendar entry. This is useful for continuous reading of all * calendar entries. */ GSM_Error (*GetNextCalendar) (GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start); /** * Sets calendar entry */ GSM_Error (*SetCalendar) (GSM_StateMachine *s, GSM_CalendarEntry *Note); /** * Adds calendar entry. */ GSM_Error (*AddCalendar) (GSM_StateMachine *s, GSM_CalendarEntry *Note); /** * Deletes calendar entry. */ GSM_Error (*DeleteCalendar) (GSM_StateMachine *s, GSM_CalendarEntry *Note); /** * Deletes all calendar entries. */ GSM_Error (*DeleteAllCalendar) (GSM_StateMachine *s); /** * Reads calendar settings. */ GSM_Error (*GetCalendarSettings)(GSM_StateMachine *s, GSM_CalendarSettings *settings); /** * Sets calendar settings. */ GSM_Error (*SetCalendarSettings)(GSM_StateMachine *s, GSM_CalendarSettings *settings); /** - * Gets note. + * Retrieves notes status (number of used entries). */ - GSM_Error (*GetNextNote) (GSM_StateMachine *s, GSM_NoteEntry *Note, bool refresh); + GSM_Error (*GetNotesStatus) (GSM_StateMachine *s, GSM_ToDoStatus *status); + /** + * Retrieves notes entry. + */ + GSM_Error (*GetNote) (GSM_StateMachine *s, GSM_NoteEntry *Note); + /** + * Retrieves note entry. This is useful for continuous reading of all + * notes entries. + */ + GSM_Error (*GetNextNote) (GSM_StateMachine *s, GSM_NoteEntry *Note, bool start); + /** + * Sets note entry + */ + GSM_Error (*SetNote) (GSM_StateMachine *s, GSM_NoteEntry *Note); + /** + * Adds note entry. + */ + GSM_Error (*AddNote) (GSM_StateMachine *s, GSM_NoteEntry *Note); + /** + * Deletes note entry. + */ + GSM_Error (*DeleteNote) (GSM_StateMachine *s, GSM_NoteEntry *Note); + /** + * Deletes all notes entries. + */ + GSM_Error (*DeleteAllNotes) (GSM_StateMachine *s); /** * Reads profile. */ GSM_Error (*GetProfile) (GSM_StateMachine *s, GSM_Profile *Profile); /** * Updates profile. */ GSM_Error (*SetProfile) (GSM_StateMachine *s, GSM_Profile *Profile); /** * Reads FM station. */ GSM_Error (*GetFMStation) (GSM_StateMachine *s, GSM_FMStation *FMStation); /** * Sets FM station. */ GSM_Error (*SetFMStation) (GSM_StateMachine *s, GSM_FMStation *FMStation); /** * Clears defined FM stations. */ GSM_Error (*ClearFMStations) (GSM_StateMachine *s); /** * Gets next filename from filesystem. */ GSM_Error (*GetNextFileFolder) (GSM_StateMachine *s, GSM_File *File, bool start); /** * Gets file part from filesystem. */ GSM_Error (*GetFilePart) (GSM_StateMachine *s, GSM_File *File); /** * Adds file part to filesystem. */ GSM_Error (*AddFilePart) (GSM_StateMachine *s, GSM_File *File, int *Pos); /** * Acquires filesystem status. */ GSM_Error (*GetFileSystemStatus)(GSM_StateMachine *s, GSM_FileSystemStatus *Status); /** * Deletes file from filessytem. */ GSM_Error (*DeleteFile) (GSM_StateMachine *s, unsigned char *ID); /** * Adds folder to filesystem. */ GSM_Error (*AddFolder) (GSM_StateMachine *s, GSM_File *File); /** * Gets GPRS access point. */ GSM_Error (*GetGPRSAccessPoint) (GSM_StateMachine *s, GSM_GPRSAccessPoint *point); /** * Sets GPRS access point. */ GSM_Error (*SetGPRSAccessPoint) (GSM_StateMachine *s, GSM_GPRSAccessPoint *point); } GSM_Phone_Functions; extern GSM_Phone_Functions NAUTOPhone; #ifdef GSM_ENABLE_NOKIA3320 extern GSM_Phone_Functions N3320Phone; #endif #ifdef GSM_ENABLE_NOKIA3650 extern GSM_Phone_Functions N3650Phone; #endif #ifdef GSM_ENABLE_NOKIA6110 extern GSM_Phone_Functions N6110Phone; #endif #ifdef GSM_ENABLE_NOKIA650 extern GSM_Phone_Functions N650Phone; #endif #ifdef GSM_ENABLE_NOKIA6510 extern GSM_Phone_Functions N6510Phone; #endif #ifdef GSM_ENABLE_NOKIA7110 extern GSM_Phone_Functions N7110Phone; #endif #ifdef GSM_ENABLE_NOKIA9210 extern GSM_Phone_Functions N9210Phone; #endif #ifdef GSM_ENABLE_ATGEN extern GSM_Phone_Functions ATGENPhone; #endif #ifdef GSM_ENABLE_ALCATEL extern GSM_Phone_Functions ALCATELPhone; #endif #ifdef GSM_ENABLE_OBEXGEN extern GSM_Phone_Functions OBEXGENPhone; #endif #ifdef GSM_ENABLE_MROUTERGEN extern GSM_Phone_Functions MROUTERGENPhone; #endif typedef struct { GSM_Phone_Data Data; GSM_Phone_Functions *Functions; } GSM_Phone; /* --------------------------- User layer ---------------------------------- */ struct _GSM_User { GSM_Reply_Function *UserReplyFunctions; void (*IncomingCall) (char *Device, GSM_Call call); void (*IncomingSMS) (char *Device, GSM_SMSMessage sms); void (*IncomingCB) (char *Device, GSM_CBMessage cb); void (*IncomingUSSD) (char *Device, char *Text); void (*SendSMSStatus) (char *Device, int status, int MessageReference); }; /* --------------------------- Statemachine layer -------------------------- */ typedef enum { GCT_MBUS2=1, GCT_FBUS2, GCT_FBUS2DLR3, GCT_FBUS2DKU5, GCT_FBUS2PL2303, GCT_FBUS2BLUE, GCT_FBUS2IRDA, GCT_PHONETBLUE, GCT_AT, GCT_MROUTERBLUE, GCT_IRDAOBEX, GCT_IRDAAT, GCT_IRDAPHONET, GCT_BLUEFBUS2, GCT_BLUEAT, GCT_BLUEPHONET, GCT_BLUEOBEX } GSM_ConnectionType; typedef struct { /* Config file (or Registry or...) variables */ char Model[50]; /* Model from config file */ char DebugLevel[50]; /* Debug level */ char *Device; /* Device name from config file */ char *Connection; /* Connection type as string */ char *SyncTime; /* Synchronize time on startup? */ char *LockDevice; /* Lock device ? (Unix) */ char *DebugFile; /* Name of debug file */ char *Localize; /* Name of localisation file */ char *StartInfo; /* Display something during start ? */ bool UseGlobalDebugFile;/* Should we use global debug file? */ bool DefaultModel; bool DefaultDebugLevel; bool DefaultDevice; bool DefaultConnection; bool DefaultSyncTime; bool DefaultLockDevice; bool DefaultDebugFile; bool DefaultLocalize; bool DefaultStartInfo; } GSM_Config; #define MAX_CONFIG_NUM 5 struct _GSM_StateMachine { GSM_ConnectionType ConnectionType; /* Type of connection as int */ char *LockFile; /* Lock file name for Unix */ Debug_Info di; /* Debug information */ bool opened; /* Is connection opened ? */ GSM_Config Config[MAX_CONFIG_NUM + 1]; GSM_Config *CurrentConfig; /* Config file (or Registry or...) variables */ int ConfigNum; INI_Section *msg; /* Localisation strings structure */ int ReplyNum; /* How many times make sth. */ int Speed; /* For some protocols used speed */ GSM_Device Device; GSM_Protocol Protocol; GSM_Phone Phone; GSM_User User; }; /* ------------------------ Other general definitions ---------------------- */ GSM_Error GSM_RegisterAllPhoneModules (GSM_StateMachine *s); GSM_Error GSM_InitConnection (GSM_StateMachine *s, int ReplyNum); GSM_Error GSM_TerminateConnection (GSM_StateMachine *s); int GSM_ReadDevice (GSM_StateMachine *s, bool wait); GSM_Error GSM_WaitForOnce (GSM_StateMachine *s, unsigned char *buffer, int length, unsigned char type, int time); GSM_Error GSM_WaitFor (GSM_StateMachine *s, unsigned char *buffer, int length, unsigned char type, int time, GSM_Phone_RequestID request); GSM_Error GSM_DispatchMessage (GSM_StateMachine *s); INI_Section *GSM_FindGammuRC(void); bool GSM_ReadConfig (INI_Section *cfg_info, GSM_Config *cfg, int num); void GSM_DumpMessageLevel2 (GSM_StateMachine *s, unsigned char *message, int messagesize, int type); void GSM_DumpMessageLevel3 (GSM_StateMachine *s, unsigned char *message, int messagesize, int type); /* ---------------------- Phone features ----------------------------------- */ typedef enum { /* n6110.c */ F_CAL33 = 1, /* Calendar,3310 style - 10 reminders, Unicode, 3 coding types */ F_CAL52, /* Calendar,5210 style - full Unicode, etc. */ F_CAL82, /* Calendar,8250 style - "normal", but with Unicode */ F_RING_SM, /* Ringtones returned in SM format - 33xx */ F_NORING, /* No ringtones */ F_NOPBKUNICODE, /* No phonebook in Unicode */ F_NOWAP, /* No WAP */ F_NOCALLER, /* No caller groups */ F_NOPICTURE, /* No Picture Images */ F_NOPICTUREUNI, /* No Picture Images text in Unicode */ F_NOSTARTUP, /* No startup logo */ F_NOCALENDAR, /* No calendar */ F_NOSTARTANI, /* Startup logo is not animated */ F_POWER_BATT, /* Network and battery level get from netmonitor */ F_PROFILES33, /* Phone profiles in 3310 style */ F_PROFILES51, /* Phone profiles in 5110 style */ F_MAGICBYTES, /* Phone can make authentication with magic bytes */ F_NODTMF, /* Phone can't send DTMF */ F_DISPSTATUS, /* Phone return display status */ F_NOCALLINFO, /* n3320.c */ F_DAYMONTH, /* Day and month reversed in pbk, when compare to GSM models */ /* n6510.c */ F_PBK35, /* Phonebook in 3510 style with ringtones ID */ F_PBKIMG, /* Phonebook in 7250 style with picture ID */ F_PBKTONEGAL, /* Phonebook with selecting ringtones from gallery */ F_PBKSMSLIST, /* Phonebook with SMS list */ F_PBKUSER, /* Phonebook with user ID */ F_RADIO, /* Phone with FM radio */ F_TODO63, /* ToDo in 6310 style - 0x55 msg type */ F_TODO66, /* ToDo in 6610 style - like calendar, with date and other */ F_NOMIDI, /* No ringtones in MIDI */ F_BLUETOOTH, /* Bluetooth support */ F_NOFILESYSTEM, /* No images, ringtones, java saved in special filesystem */ F_NOMMS, /* No MMS sets in phone */ F_NOGPRSPOINT, /* GPRS point are not useable */ F_CAL35, /* Calendar,3510 style - Reminder,Call,Birthday */ F_CAL65, /* Calendar,6510 style - CBMM, method 3 */ F_WAPMMSPROXY, /* WAP & MMS settings contains first & second proxy */ /* n6510.c && n7110.c */ F_VOICETAGS, /* Voice tags available */ F_CAL62, /* Calendar,6210 style - Call,Birthday,Memo,Meeting */ F_NOTES, /* AT modules */ F_SMSONLYSENT, /* Phone supports only sent/unsent messages */ F_BROKENCPBS, /* CPBS on some memories can hang phone */ F_M20SMS, /* Siemens M20 like SMS handling */ F_SLOWWRITE, /* Use slower writing which some phone need */ F_SMSME900, /* SMS in ME start from location 900 - case of Sagem */ F_ALCATEL /* Phone supports Alcatel protocol */ } Feature; /* For models table */ struct _OnePhoneModel { char *model; char *number; char *irdamodel; Feature features[12]; }; bool IsPhoneFeatureAvailable (OnePhoneModel *model, Feature feature); OnePhoneModel *GetModelData (char *model, char *number, char *irdamodel); #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif int smprintf(GSM_StateMachine *s, const char *format, ...); void GSM_OSErrorInfo(GSM_StateMachine *s, char *description); #ifdef GSM_ENABLE_BACKUP void GSM_GetPhoneFeaturesForBackup(GSM_StateMachine *s, GSM_Backup_Info *info); #endif #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/alcatel/alcatel.c b/gammu/emb/common/phone/alcatel/alcatel.c index 3821f13..b75077f 100644 --- a/gammu/emb/common/phone/alcatel/alcatel.c +++ b/gammu/emb/common/phone/alcatel/alcatel.c @@ -2446,1558 +2446,1564 @@ static GSM_Error ALCATEL_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not j++; break; } if (dt == NULL) { Note->Entries[i-j].EntryType = CAL_ALARM_DATETIME; Note->Entries[i-j].Date = Priv->ReturnDateTime; dt = &(Note->Entries[i-j].Date); } else { j++; Note->EntriesNum--; dt->Day = Priv->ReturnDateTime.Day; dt->Month = Priv->ReturnDateTime.Month; dt->Year = Priv->ReturnDateTime.Year; dt->Timezone = Priv->ReturnDateTime.Timezone; dt = NULL; } break; case 4: if (Priv->ReturnType != Alcatel_time) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckTime(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid time in phone, ignoring\n"); Note->EntriesNum--; j++; break; } if (dt == NULL) { Note->Entries[i-j].EntryType = CAL_ALARM_DATETIME; Note->Entries[i-j].Date = Priv->ReturnDateTime; dt = &(Note->Entries[i-j].Date); } else { j++; Note->EntriesNum--; dt->Hour = Priv->ReturnDateTime.Hour; dt->Minute = Priv->ReturnDateTime.Minute; dt->Second = Priv->ReturnDateTime.Second; dt = NULL; } break; case 5: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_TEXT; CopyUnicodeString(Note->Entries[i-j].Text, Priv->ReturnString); break; case 6: if (Priv->ReturnType != Alcatel_bool) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_PRIVATE; Note->Entries[i-j].Number = Priv->ReturnInt; break; case 7: if (Priv->ReturnType != Alcatel_enum) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } switch (Priv->ReturnInt) { case 0: Note->Type = GSM_CAL_MEETING; break; case 2: Note->Type = GSM_CAL_BIRTHDAY; break; case 3: Note->Type = GSM_CAL_CALL; break; case 4: Note->Type = GSM_CAL_ALARM; break; case 5: Note->Type = GSM_CAL_DAILY_ALARM; break; case 9: /* I'd call this repeating event, but it makes no sense creating one more type ... */ Note->Type = GSM_CAL_MEETING; break; default: smprintf(s,"WARNING: Received unknown event type %02X!\n", Priv->ReturnInt); break; } j++; Note->EntriesNum--; break; case 8: if (Priv->ReturnType != Alcatel_int) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } /* 0xffffffff indicates that there is phone (BF5), 0 means none (BF5, BE5)*/ if (Priv->ReturnInt == 0xffffffff || Priv->ReturnInt == 0) { j++; Note->EntriesNum--; } else { Note->Entries[i-j].EntryType = CAL_CONTACTID; Note->Entries[i-j].Number = Priv->ReturnInt; } break; case 9: if (Priv->ReturnType != Alcatel_phone) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_PHONE; CopyUnicodeString(Note->Entries[i-j].Text, Priv->ReturnString); break; case 10: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_DAYOFWEEK; Note->Entries[i-j].Number = Priv->ReturnInt; break; case 11: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_DAY; Note->Entries[i-j].Number = Priv->ReturnInt; break; case 12: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_WEEKOFMONTH; Note->Entries[i-j].Number = Priv->ReturnInt; break; case 13: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_MONTH; Note->Entries[i-j].Number = Priv->ReturnInt; break; case 17: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } /* In BF5 birthday has frequency = 1 */ if (Note->Type == GSM_CAL_BIRTHDAY) { Note->EntriesNum--; j++; } else { Note->Entries[i-j].EntryType = CAL_REPEAT_FREQUENCY; Note->Entries[i-j].Number = Priv->ReturnInt; } break; case 18: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_STARTDATE; Note->Entries[i-j].Date = Priv->ReturnDateTime; break; case 19: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); Note->EntriesNum--; j++; break; } Note->Entries[i-j].EntryType = CAL_REPEAT_STOPDATE; Note->Entries[i-j].Date = Priv->ReturnDateTime; break; case 20: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); Note->EntriesNum--; j++; break; } /* This entry had always same value as the 3rd (alarm date) */ j++; Note->EntriesNum--; break; case 21: if (Priv->ReturnType != Alcatel_time) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); Note->EntriesNum--; j++; break; } if (!CheckTime(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid time in phone, ignoring\n"); Note->EntriesNum--; j++; break; } /* This entry had always same value as the 4th (alarm time) */ j++; Note->EntriesNum--; break; default: Note->EntriesNum--; j++; smprintf(s,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv->CurrentFields[i], Priv->ReturnType); switch (Priv->ReturnType) { case Alcatel_date: smprintf(s, "%d.%d.%d", Priv->ReturnDateTime.Day, Priv->ReturnDateTime.Month, Priv->ReturnDateTime.Year); break; case Alcatel_time: smprintf(s, "%d:%d:%d", Priv->ReturnDateTime.Hour, Priv->ReturnDateTime.Minute, Priv->ReturnDateTime.Second); break; case Alcatel_string: case Alcatel_phone: smprintf(s, "\"%s\"",DecodeUnicodeString(Priv->ReturnString)); break; case Alcatel_enum: case Alcatel_bool: case Alcatel_int: case Alcatel_byte: smprintf(s, "%d", Priv->ReturnInt); break; } smprintf(s,"\n"); } } /* The event didn't have start/stop time -> we need only date */ if (!evdateused) { Note->EntriesNum++; Note->Entries[i-j].EntryType = CAL_START_DATETIME; Note->Entries[i-j].Date = evdate; } return ERR_NONE; } static GSM_Error ALCATEL_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if (Priv->CalendarItemsCount == 0) return ERR_EMPTY; if (start) Note->Location = 0; if ((error = ALCATEL_GetNextId(s, &(Note->Location))) != ERR_NONE) return error; return ALCATEL_GetCalendar(s, Note); } static GSM_Error ALCATEL_DeleteCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Error error; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; /* Delete Calendar */ if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= ERR_NONE) { /* Entry was empty => no error */ return ERR_NONE; } error = ALCATEL_DeleteItem(s, Note->Location); if (error != ERR_NONE) return error; /* Refresh list */ if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Error error; unsigned int val; bool contact_set = false; bool phone_set = false; bool date_set = false; bool repeating = false; int i; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeCalendar, 0))!= ERR_NONE) return error; for (i = 0; i < Note->EntriesNum; i++) { switch (Note->Entries[i].EntryType) { case CAL_START_DATETIME: if (!date_set) { if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error; date_set = true; } if ((error = ALCATEL_CreateField(s, Alcatel_time, 1, &(Note->Entries[i].Date))) != ERR_NONE) return error; break; case CAL_END_DATETIME: if (!date_set) { if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error; date_set = true; } if ((error = ALCATEL_CreateField(s, Alcatel_time, 2, &(Note->Entries[i].Date))) != ERR_NONE) return error; break; case CAL_ALARM_DATETIME: if ((error = ALCATEL_CreateField(s, Alcatel_date, 3, &(Note->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_time, 4, &(Note->Entries[i].Date))) != ERR_NONE) return error; if (Note->Type == GSM_CAL_ALARM || Note->Type == GSM_CAL_DAILY_ALARM) { if ((error = ALCATEL_CreateField(s, Alcatel_date, 20, &(Note->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_time, 21, &(Note->Entries[i].Date))) != ERR_NONE) return error; } break; case CAL_TEXT: if ((error = ALCATEL_CreateField(s, Alcatel_string, 5, Note->Entries[i].Text)) != ERR_NONE) return error; break; case CAL_PRIVATE: if ((error = ALCATEL_CreateField(s, Alcatel_bool, 6, &(Note->Entries[i].Number))) != ERR_NONE) return error; break; case CAL_CONTACTID: if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &(Note->Entries[i].Number))) != ERR_NONE) return error; contact_set = true; break; case CAL_PHONE: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, Note->Entries[i].Text)) != ERR_NONE) return error; phone_set = true; break; case CAL_REPEAT_DAYOFWEEK: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 10, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_DAY: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 11, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_WEEKOFMONTH: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 12, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_MONTH: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 13, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_FREQUENCY: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 17, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_STARTDATE: if ((error = ALCATEL_CreateField(s, Alcatel_date, 18, &(Note->Entries[i].Date))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_STOPDATE: if ((error = ALCATEL_CreateField(s, Alcatel_date, 19, &(Note->Entries[i].Date))) != ERR_NONE) return error; repeating = true; break; case CAL_SILENT_ALARM_DATETIME: case CAL_RECURRANCE: case CAL_LOCATION: smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", Note->Entries[i].EntryType); break; } } switch (Note->Type) { case GSM_CAL_CALL: val = 3; break; case GSM_CAL_BIRTHDAY: val = 2; break; case GSM_CAL_ALARM: val = 4; break; case GSM_CAL_DAILY_ALARM: val = 5; break; default: if (repeating) { val = 9; } else { val = 0; } } if ((error = ALCATEL_CreateField(s, Alcatel_enum, 7, &val)) != ERR_NONE) return error; if (!contact_set) { if (phone_set) { val = 0xffffffff; } else { val = 0; } if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &val)) != ERR_NONE) return error; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; Note->Location = Priv->CommitedRecord; /* Refresh list */ if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Error error; unsigned int val; bool contact_set = false; bool phone_set = false; bool date_set = false; bool repeating = false; int i; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; bool UpdatedFields[22]; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= ERR_NONE) { /* Entry doesn't exist, we will create new one */ return ALCATEL_AddCalendar(s, Note); } /* Get fields for current item */ if ((error = ALCATEL_GetFields(s, Note->Location))!= ERR_NONE) return error; for (i = 0; i < 22; i++) { UpdatedFields[i] = false; } if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeCalendar, Note->Location))!= ERR_NONE) return error; for (i = 0; i < Note->EntriesNum; i++) { switch (Note->Entries[i].EntryType) { case CAL_START_DATETIME: if (!date_set) { UpdatedFields[0] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error; date_set = true; } UpdatedFields[1] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 1, &(Note->Entries[i].Date))) != ERR_NONE) return error; break; case CAL_END_DATETIME: if (!date_set) { UpdatedFields[0] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error; date_set = true; } UpdatedFields[2] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 2, &(Note->Entries[i].Date))) != ERR_NONE) return error; break; case CAL_ALARM_DATETIME: UpdatedFields[3] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 3, &(Note->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[4] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 4, &(Note->Entries[i].Date))) != ERR_NONE) return error; if (Note->Type == GSM_CAL_ALARM || Note->Type == GSM_CAL_DAILY_ALARM) { UpdatedFields[20] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 20, &(Note->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[21] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 21, &(Note->Entries[i].Date))) != ERR_NONE) return error; } break; case CAL_TEXT: UpdatedFields[5] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, Note->Location, 5, Note->Entries[i].Text)) != ERR_NONE) return error; break; case CAL_PRIVATE: UpdatedFields[6] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_bool, Note->Location, 6, &(Note->Entries[i].Number))) != ERR_NONE) return error; break; case CAL_CONTACTID: UpdatedFields[8] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_int, Note->Location, 8, &(Note->Entries[i].Number))) != ERR_NONE) return error; contact_set = true; break; case CAL_PHONE: UpdatedFields[9] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, Note->Location, 9, Note->Entries[i].Text)) != ERR_NONE) return error; phone_set = true; break; case CAL_REPEAT_DAYOFWEEK: UpdatedFields[10] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 10, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_DAY: UpdatedFields[11] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 11, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_WEEKOFMONTH: UpdatedFields[12] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 12, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_MONTH: UpdatedFields[13] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 13, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_FREQUENCY: UpdatedFields[17] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 17, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_STARTDATE: UpdatedFields[18] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 18, &(Note->Entries[i].Date))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_STOPDATE: UpdatedFields[19] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 19, &(Note->Entries[i].Date))) != ERR_NONE) return error; repeating = true; break; case CAL_SILENT_ALARM_DATETIME: case CAL_RECURRANCE: case CAL_LOCATION: smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", Note->Entries[i].EntryType); break; } } switch (Note->Type) { case GSM_CAL_CALL: val = 3; break; case GSM_CAL_BIRTHDAY: val = 2; break; case GSM_CAL_ALARM: val = 4; break; case GSM_CAL_DAILY_ALARM: val = 5; break; default: if (repeating) { val = 9; } else { val = 0; } } UpdatedFields[7] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_enum, Note->Location, 7, &val)) != ERR_NONE) return error; if (!contact_set) { if (phone_set) { val = 0xffffffff; } else { val = 0; } UpdatedFields[8] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_int, Note->Location, 8, &val)) != ERR_NONE) return error; } /* If we didn't update some field, we have to delete it... */ for (i=0; i<Priv->CurrentFieldsCount; i++) { if (!UpdatedFields[Priv->CurrentFields[i]]) if ((error = ALCATEL_DeleteField(s, Note->Location, Priv->CurrentFields[i])) != ERR_NONE) return error; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_DeleteAllCalendar (GSM_StateMachine *s) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; for (i=0; i<Priv->CalendarItemsCount; i++) { error = ALCATEL_DeleteItem(s, Priv->CalendarItems[i]); if (error != ERR_NONE) return error; } /* Refresh list */ if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) { GSM_Error error; GSM_CalendarEntry Note; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; bool Found = false; bool DateSet = false; int alarm_number = alarm->Location; static GSM_DateTime nulldt = {0,0,0,0,0,0,0}; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; for (i=0; i<Priv->CalendarItemsCount; i++) { if ((error = ALCATEL_GetFieldValue(s, Priv->CalendarItems[i], 7))!= ERR_NONE) return error; if (Priv->ReturnType != Alcatel_enum) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); continue; } if (Priv->ReturnInt == 4 || Priv->ReturnInt == 5) { alarm_number--; if (alarm_number == 0) { Found = true; break; } } } if (!Found) return ERR_EMPTY; Note.Location = Priv->CalendarItems[i]; if ((error = ALCATEL_GetCalendar(s, &Note))!= ERR_NONE) return error; if (Note.Type == GSM_CAL_ALARM) { alarm->Repeating = false; } else { alarm->Repeating = true; } alarm->Text[0] = 0; alarm->Text[1] = 0; for (i = 0; i < Note.EntriesNum; i++) { if (Note.Entries[i].EntryType == CAL_TEXT) { CopyUnicodeString(alarm->Text, Note.Entries[i].Text); } else if (Note.Entries[i].EntryType == CAL_ALARM_DATETIME) { alarm->DateTime = Note.Entries[i].Date; DateSet = false; } } if (!DateSet) { alarm->DateTime = nulldt; } return ERR_NONE; } static GSM_Error ALCATEL_SetAlarm (GSM_StateMachine *s, GSM_Alarm *alarm) { GSM_Error error; GSM_CalendarEntry Note; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_DateTime dt; int i; bool Found = false; int alarm_number = alarm->Location; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; for (i=0; i<Priv->CalendarItemsCount; i++) { if ((error = ALCATEL_GetFieldValue(s, Priv->CalendarItems[i], 7))!= ERR_NONE) return error; if (Priv->ReturnType != Alcatel_enum) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); continue; } if (Priv->ReturnInt == 4 || Priv->ReturnInt == 5) { alarm_number--; if (alarm_number == 0) { Found = true; break; } } } if (Found) { Note.Location = Priv->CalendarItems[i]; } Note.EntriesNum = 1; Note.Entries[0].EntryType = CAL_ALARM_DATETIME; Note.Entries[0].Date = alarm->DateTime; if (alarm->Repeating) { Note.Type = GSM_CAL_DAILY_ALARM; GSM_GetCurrentDateTime(&dt); Note.Entries[0].Date.Day = dt.Day; Note.Entries[0].Date.Month = dt.Month; Note.Entries[0].Date.Year = dt.Year; } else { Note.Type = GSM_CAL_ALARM; } if (alarm->Text[0] != 0 || alarm->Text[1] != 0) { Note.EntriesNum++; Note.Entries[1].EntryType = CAL_TEXT; CopyUnicodeString(Note.Entries[1].Text, alarm->Text); } if (Found) { return ALCATEL_SetCalendar(s, &Note); } else { return ALCATEL_AddCalendar(s, &Note); } } static GSM_Error ALCATEL_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; status->Used = 0; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; status->Used = Priv->ToDoItemsCount; return ERR_NONE; } static GSM_Error ALCATEL_GetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; GSM_DateTime *dt = NULL; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; int j=0; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= ERR_NONE) { ToDo->EntriesNum = 0; return error; } if ((error = ALCATEL_GetFields(s, ToDo->Location))!= ERR_NONE) return error; ToDo->EntriesNum = Priv->CurrentFieldsCount; for (i=0; i < Priv->CurrentFieldsCount; i++) { if ((error = ALCATEL_GetFieldValue(s, ToDo->Location, Priv->CurrentFields[i]))!= ERR_NONE) return error; switch (Priv->CurrentFields[i]) { case 0: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); ToDo->EntriesNum--; j++; break; } ToDo->Entries[i-j].EntryType = TODO_END_DATETIME; ToDo->Entries[i-j].Date = Priv->ReturnDateTime; break; case 1: if (Priv->ReturnType != Alcatel_bool) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } ToDo->Entries[i-j].EntryType = TODO_COMPLETED; ToDo->Entries[i-j].Number = Priv->ReturnInt; break; case 2: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); ToDo->EntriesNum--; j++; break; } if (dt == NULL) { ToDo->Entries[i-j].EntryType = TODO_ALARM_DATETIME; ToDo->Entries[i-j].Date = Priv->ReturnDateTime; dt = &(ToDo->Entries[i-j].Date); } else { j++; ToDo->EntriesNum--; dt->Day = Priv->ReturnDateTime.Day; dt->Month = Priv->ReturnDateTime.Month; dt->Year = Priv->ReturnDateTime.Year; dt->Timezone = Priv->ReturnDateTime.Timezone; dt = NULL; } break; case 3: if (Priv->ReturnType != Alcatel_time) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (!CheckTime(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid time in phone, ignoring\n"); ToDo->EntriesNum--; j++; break; } if (dt == NULL) { ToDo->Entries[i-j].EntryType = TODO_ALARM_DATETIME; ToDo->Entries[i-j].Date = Priv->ReturnDateTime; dt = &(ToDo->Entries[i-j].Date); } else { j++; ToDo->EntriesNum--; dt->Hour = Priv->ReturnDateTime.Hour; dt->Minute = Priv->ReturnDateTime.Minute; dt->Second = Priv->ReturnDateTime.Second; dt = NULL; } break; case 4: if (Priv->ReturnType != Alcatel_string) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } ToDo->Entries[i-j].EntryType = TODO_TEXT; CopyUnicodeString(ToDo->Entries[i-j].Text, Priv->ReturnString); break; case 5: if (Priv->ReturnType != Alcatel_bool) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } ToDo->Entries[i-j].EntryType = TODO_PRIVATE; ToDo->Entries[i-j].Number = Priv->ReturnInt; break; case 6: if (Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (Priv->ReturnInt == 255) { /* 255 means no category */ j++; ToDo->EntriesNum--; } else { ToDo->Entries[i-j].EntryType = TODO_CATEGORY; ToDo->Entries[i-j].Number = Priv->ReturnInt; } break; case 7: /* This one seems to be byte for BF5 and enum for BE5 */ if (Priv->ReturnType != Alcatel_enum && Priv->ReturnType != Alcatel_byte) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } switch (Priv->ReturnInt) { case 0: ToDo->Priority = GSM_Priority_High; break; case 1: ToDo->Priority = GSM_Priority_Medium; break; case 2: ToDo->Priority = GSM_Priority_Low; break; default: ToDo->Priority = 0; smprintf(s,"WARNING: Received unexpected priority %02X, ignoring\n", Priv->ReturnInt); } j++; ToDo->EntriesNum--; break; case 8: if (Priv->ReturnType != Alcatel_int) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } /* 0xffffffff indicates that there is phone, 0 means none */ if (Priv->ReturnInt == 0xffffffff || Priv->ReturnInt == 0) { j++; ToDo->EntriesNum--; } else { ToDo->Entries[i-j].EntryType = TODO_CONTACTID; ToDo->Entries[i-j].Number = Priv->ReturnInt; } break; case 9: if (Priv->ReturnType != Alcatel_phone) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } ToDo->Entries[i-j].EntryType = TODO_PHONE; CopyUnicodeString(ToDo->Entries[i-j].Text, Priv->ReturnString); break; case 10: if (Priv->ReturnType != Alcatel_date) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (!CheckDate(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid date in phone, ignoring\n"); ToDo->EntriesNum--; j++; break; } /* This entry had always same value as the 2nd (alarm date) */ j++; ToDo->EntriesNum--; break; case 11: if (Priv->ReturnType != Alcatel_time) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); ToDo->EntriesNum--; j++; break; } if (!CheckTime(&(Priv->ReturnDateTime))) { smprintf(s,"WARNING: Invalid time in phone, ignoring\n"); ToDo->EntriesNum--; j++; break; } /* This entry had always same value as the 3rd (alarm time) */ j++; ToDo->EntriesNum--; break; default: ToDo->EntriesNum--; j++; smprintf(s,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv->CurrentFields[i], Priv->ReturnType); switch (Priv->ReturnType) { case Alcatel_date: smprintf(s, "%d.%d.%d", Priv->ReturnDateTime.Day, Priv->ReturnDateTime.Month, Priv->ReturnDateTime.Year); break; case Alcatel_time: smprintf(s, "%d:%d:%d", Priv->ReturnDateTime.Hour, Priv->ReturnDateTime.Minute, Priv->ReturnDateTime.Second); break; case Alcatel_string: case Alcatel_phone: smprintf(s, "\"%s\"",DecodeUnicodeString(Priv->ReturnString)); break; case Alcatel_enum: case Alcatel_bool: case Alcatel_int: case Alcatel_byte: smprintf(s, "%d", Priv->ReturnInt); break; } smprintf(s,"\n"); } } return ERR_NONE; } static GSM_Error ALCATEL_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if (Priv->ToDoItemsCount == 0) return ERR_EMPTY; if (start) ToDo->Location = 0; if ((error = ALCATEL_GetNextId(s, &(ToDo->Location))) != ERR_NONE) return error; return ALCATEL_GetToDo(s, ToDo); } static GSM_Error ALCATEL_DeleteAllToDo (GSM_StateMachine *s) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; for (i=0; i<Priv->ToDoItemsCount; i++) { error = ALCATEL_DeleteItem(s, Priv->ToDoItems[i]); if (error != ERR_NONE) return error; } /* Refresh list */ if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; unsigned int val; bool contact_set = false; bool phone_set = false; int i; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeToDo, 0))!= ERR_NONE) return error; switch (ToDo->Priority) { case GSM_Priority_High: val = 0; break; case GSM_Priority_Low: val = 2; break; case GSM_Priority_Medium: default: val = 1; break; } /* This one seems to be byte for BF5 and enum for BE5 */ if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) { if ((error = ALCATEL_CreateField(s, Alcatel_byte, 7, &val)) != ERR_NONE) return error; } else { if ((error = ALCATEL_CreateField(s, Alcatel_enum, 7, &val)) != ERR_NONE) return error; } for (i = 0; i < ToDo->EntriesNum; i++) { switch (ToDo->Entries[i].EntryType) { case TODO_END_DATETIME: if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; break; case TODO_COMPLETED: if ((error = ALCATEL_CreateField(s, Alcatel_bool, 1, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; break; case TODO_ALARM_DATETIME: if ((error = ALCATEL_CreateField(s, Alcatel_date, 2, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_time, 3, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_date, 10, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_time, 11, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; break; case TODO_TEXT: if ((error = ALCATEL_CreateField(s, Alcatel_string, 4, ToDo->Entries[i].Text)) != ERR_NONE) return error; break; case TODO_PRIVATE: if ((error = ALCATEL_CreateField(s, Alcatel_bool, 5, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; break; case TODO_CATEGORY: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 6, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; break; case TODO_CONTACTID: if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; contact_set = true; break; case TODO_PHONE: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, ToDo->Entries[i].Text)) != ERR_NONE) return error; phone_set = true; break; default: break; } } if (!contact_set) { if (phone_set) { val = 0xffffffff; } else { val = 0; } if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &val)) != ERR_NONE) return error; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; ToDo->Location = Priv->CommitedRecord; /* Refresh list */ if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_SetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; unsigned int val; bool contact_set = false; bool phone_set = false; bool UpdatedFields[12]; int i; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; /* Save modified ToDo */ if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= ERR_NONE) { /* Entry doesn't exist, we will create new one */ return ALCATEL_AddToDo(s, ToDo); } /* Get fields for current item */ if ((error = ALCATEL_GetFields(s, ToDo->Location))!= ERR_NONE) return error; for (i = 0; i < 12; i++) { UpdatedFields[i] = false; } if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeToDo, ToDo->Location))!= ERR_NONE) return error; switch (ToDo->Priority) { case GSM_Priority_High: val = 0; break; case GSM_Priority_Low: val = 2; break; case GSM_Priority_Medium: default: val = 1; break; } /* This one seems to be byte for BF5 and enum for BE5 */ if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) { if ((error = ALCATEL_UpdateField(s, Alcatel_byte, ToDo->Location, 7, &val)) != ERR_NONE) return error; } else { if ((error = ALCATEL_UpdateField(s, Alcatel_enum, ToDo->Location, 7, &val)) != ERR_NONE) return error; } UpdatedFields[7] = true; for (i = 0; i < ToDo->EntriesNum; i++) { switch (ToDo->Entries[i].EntryType) { case TODO_END_DATETIME: if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 0, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[0] = true; break; case TODO_COMPLETED: if ((error = ALCATEL_UpdateField(s, Alcatel_bool, ToDo->Location, 1, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; UpdatedFields[1] = true; break; case TODO_ALARM_DATETIME: if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 2, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[2] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 3, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[3] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 10, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[10] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 11, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; UpdatedFields[11] = true; break; case TODO_TEXT: if ((error = ALCATEL_UpdateField(s, Alcatel_string, ToDo->Location, 4, ToDo->Entries[i].Text)) != ERR_NONE) return error; UpdatedFields[4] = true; break; case TODO_PRIVATE: if ((error = ALCATEL_UpdateField(s, Alcatel_bool, ToDo->Location, 5, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; UpdatedFields[5] = true; break; case TODO_CATEGORY: if ((error = ALCATEL_UpdateField(s, Alcatel_byte, ToDo->Location, 6, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; UpdatedFields[6] = true; break; case TODO_CONTACTID: if ((error = ALCATEL_UpdateField(s, Alcatel_int, ToDo->Location, 8, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; UpdatedFields[8] = true; contact_set = true; break; case TODO_PHONE: if ((error = ALCATEL_UpdateField(s, Alcatel_phone, ToDo->Location, 9, ToDo->Entries[i].Text)) != ERR_NONE) return error; UpdatedFields[9] = true; phone_set = true; break; default: break; } } if (!contact_set) { if (phone_set) { val = 0xffffffff; } else { val = 0; } if ((error = ALCATEL_UpdateField(s, Alcatel_int, ToDo->Location, 8, &val)) != ERR_NONE) return error; UpdatedFields[8] = true; } /* If we didn't update some field, we have to delete it... */ for (i=0; i<Priv->CurrentFieldsCount; i++) { if (!UpdatedFields[Priv->CurrentFields[i]]) if ((error = ALCATEL_DeleteField(s, ToDo->Location, Priv->CurrentFields[i])) != ERR_NONE) return error; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_DeleteToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; /* Delete ToDo */ if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= ERR_NONE) { /* Entry was empty => no error */ return ERR_NONE; } error = ALCATEL_DeleteItem(s, ToDo->Location); if (error != ERR_NONE) return error; /* Refresh list */ if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; return ERR_NONE; } static GSM_Error ALCATEL_GetCategoryStatus(GSM_StateMachine *s, GSM_CategoryStatus *Status) { GSM_Alcatel_BinaryType type; GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; switch (Status->Type) { case Category_ToDo: type = TypeToDo; break; case Category_Phonebook: type = TypeContacts; break; default: return ERR_NOTSUPPORTED; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, type, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableCategoryIds(s))!= ERR_NONE) return error; Status->Used = Priv->CurrentCategoriesCount; return ERR_NONE; } static GSM_Error ALCATEL_GetCategory(GSM_StateMachine *s, GSM_Category *Category) { GSM_Alcatel_BinaryType type; GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; switch (Category->Type) { case Category_ToDo: type = TypeToDo; break; case Category_Phonebook: type = TypeContacts; break; default: return ERR_NOTSUPPORTED; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, type, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableCategoryIds(s))!= ERR_NONE) return error; if ((error = ALCATEL_IsCategoryIdAvailable(s, Category->Location))!= ERR_NONE) return error; if ((error = ALCATEL_GetCategoryText(s, Category->Location))!= ERR_NONE) return error; CopyUnicodeString(Category->Name, Priv->ReturnString); return ERR_NONE; } static GSM_Error ALCATEL_AddCategory(GSM_StateMachine *s, GSM_Category *Category) { GSM_Alcatel_BinaryType type; GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; switch (Category->Type) { case Category_ToDo: type = TypeToDo; break; case Category_Phonebook: type = TypeContacts; break; default: return ERR_NOTSUPPORTED; } if ((error = ALCATEL_GoToBinaryState(s, StateSession, type, 0))!= ERR_NONE) return error; if ((error = ALCATEL_AddCategoryText(s, Category->Name))!= ERR_NONE) return error; Category->Location = Priv->ReturnInt; return ERR_NONE; } static GSM_Error ALCATEL_GetProductCode(GSM_StateMachine *s, char *value) { strcpy(value, s->Phone.Data.ModelInfo->model); return ERR_NONE; } static GSM_Error ALCATEL_DispatchMessage(GSM_StateMachine *s) { if (s->Phone.Data.Priv.ALCATEL.Mode == ModeBinary) { return GSM_DispatchMessage(s); } else { return ATGEN_DispatchMessage(s); } } static GSM_Error ALCATEL_ReplyGeneric(GSM_Protocol_Message msg, GSM_StateMachine *s) { /* All error values are just VERY wild guesses, but these seems to work * almost as expected ... */ switch (msg.Buffer[8]) { case 0x00: /* no error */ return ERR_NONE; case 0x10: /* same thing opened in phone menus */ return ERR_INSIDEPHONEMENU; case 0x13: /* This appears in more cases: * - phone needs PIN code * - we want to close not opened session * For normal users the second case shouldn't occur... */ return ERR_SECURITYERROR; case 0x14: /* Bad data */ case 0x2f: /* Closing session when not opened */ case 0x1f: /* Bad in/out counter in packet/ack */ case 0x0e: /* Openning session when not closed */ case 0x0C: /* Bad id (item/database) */ case 0x11: /* Bad list id */ case 0x2A: /* Nonexistant field/item id */ case 0x35: /* Too long text */ return ERR_BUG; case 0x23: /* Session opened */ case 0x80: /* Transfer started */ return ERR_NONE; case 0x82: /* Transfer canceled */ return ERR_CANCELED; default: smprintf(s, "WARNING: Packet seems to indicate some status by %02X, ignoring!\n", msg.Buffer[8]); return ERR_NONE; } } static GSM_Error ALCATEL_ReplyCommit(GSM_Protocol_Message msg, GSM_StateMachine *s) { s->Phone.Data.Priv.ALCATEL.CommitedRecord = msg.Buffer[12] + (msg.Buffer[11] << 8) + (msg.Buffer[10] << 16) + (msg.Buffer[9] << 24); smprintf(s, "Created record %08x\n", s->Phone.Data.Priv.ALCATEL.CommitedRecord); return ERR_NONE; } static GSM_Error ALCATEL_SetIncomingCB (GSM_StateMachine *s, bool enable) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetIncomingCB(s, enable); } static GSM_Error ALCATEL_SetIncomingSMS (GSM_StateMachine *s, bool enable) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetIncomingSMS(s, enable); } static GSM_Error ALCATEL_SetFastSMSSending(GSM_StateMachine *s, bool enable) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetFastSMSSending(s, enable); } static GSM_Reply_Function ALCATELReplyFunctions[] = { {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelAttach }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDetach }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelCommit }, {ALCATEL_ReplyCommit, "\x02",0x00,0x00, ID_AlcatelCommit2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelEnd }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelClose }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelStart }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect1 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect3 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelBegin1 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelBegin2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetIds1 }, {ALCATEL_ReplyGetIds, "\x02",0x00,0x00, ID_AlcatelGetIds2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetCategories1 }, {ALCATEL_ReplyGetCategories, "\x02",0x00,0x00, ID_AlcatelGetCategories2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetCategoryText1 }, {ALCATEL_ReplyGetCategoryText, "\x02",0x00,0x00, ID_AlcatelGetCategoryText2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelAddCategoryText1 }, {ALCATEL_ReplyAddCategoryText, "\x02",0x00,0x00, ID_AlcatelAddCategoryText2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetFields1 }, {ALCATEL_ReplyGetFields, "\x02",0x00,0x00, ID_AlcatelGetFields2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetFieldValue1 }, {ALCATEL_ReplyGetFieldValue, "\x02",0x00,0x00, ID_AlcatelGetFieldValue2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDeleteField }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDeleteItem1 }, {ALCATEL_ReplyDeleteItem, "\x02",0x00,0x00, ID_AlcatelDeleteItem2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelCreateField }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelUpdateField }, {NULL, "\x00",0x00,0x00, ID_None } }; GSM_Phone_Functions ALCATELPhone = { /* AFAIK, any 50[0123] phone should work, but I'm not sure whether all * they were ever really released, if yes add them here also. */ "alcatel|OT501|OT701|OT715|OT535|OT735|BE5|BF5|BH4", ALCATELReplyFunctions, ALCATEL_Initialise, ALCATEL_Terminate, ALCATEL_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ ALCATEL_GetManufacturer, ALCATEL_GetModel, ALCATEL_GetFirmware, ALCATEL_GetIMEI, NOTSUPPORTED, /* GetOriginalIMEI */ NOTSUPPORTED, /* GetManufactureMonth */ ALCATEL_GetProductCode, NOTSUPPORTED, /* GetHardware */ NOTSUPPORTED, /* GetPPM */ ALCATEL_GetSIMIMSI, ALCATEL_GetDateTime, ALCATEL_SetDateTime, ALCATEL_GetAlarm, ALCATEL_SetAlarm, NOTSUPPORTED, /* GetLocale */ NOTSUPPORTED, /* SetLocale */ ALCATEL_PressKey, ALCATEL_Reset, ALCATEL_ResetPhoneSettings, ALCATEL_EnterSecurityCode, ALCATEL_GetSecurityStatus, ALCATEL_GetDisplayStatus, ALCATEL_SetAutoNetworkLogin, ALCATEL_GetBatteryCharge, ALCATEL_GetSignalStrength, ALCATEL_GetNetworkInfo, ALCATEL_GetCategory, ALCATEL_AddCategory, ALCATEL_GetCategoryStatus, ALCATEL_GetMemoryStatus, ALCATEL_GetMemory, ALCATEL_GetNextMemory, ALCATEL_SetMemory, ALCATEL_AddMemory, ALCATEL_DeleteMemory, ALCATEL_DeleteAllMemory, NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ ALCATEL_GetSMSC, ALCATEL_SetSMSC, ALCATEL_GetSMSStatus, ALCATEL_GetSMS, ALCATEL_GetNextSMS, NOTSUPPORTED, /* SetSMS */ ALCATEL_AddSMS, ALCATEL_DeleteSMS, ALCATEL_SendSMS, ALCATEL_SendSavedSMS, ALCATEL_SetFastSMSSending, ALCATEL_SetIncomingSMS, ALCATEL_SetIncomingCB, ALCATEL_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ ALCATEL_DialVoice, ALCATEL_AnswerCall, ALCATEL_CancelCall, NOTSUPPORTED, /* HoldCall */ NOTSUPPORTED, /* UnholdCall */ NOTSUPPORTED, /* ConferenceCall */ NOTSUPPORTED, /* SplitCall */ NOTSUPPORTED, /* TransferCall */ NOTSUPPORTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ NOTSUPPORTED, /* SetCallDivert */ NOTSUPPORTED, /* CancelAllDiverts */ NONEFUNCTION, /* SetIncomingCall */ NOTSUPPORTED, /* SetIncomingUSSD */ ALCATEL_SendDTMF, NOTSUPPORTED, /* GetRingtone */ NOTSUPPORTED, /* SetRingtone */ NOTSUPPORTED, /* GetRingtonesInfo */ NOTSUPPORTED, /* DeleteUserRingtones */ NOTSUPPORTED, /* PlayTone */ NOTSUPPORTED, /* GetWAPBookmark */ NOTSUPPORTED, /* SetWAPBookmark */ NOTSUPPORTED, /* DeleteWAPBookmark */ NOTSUPPORTED, /* GetWAPSettings */ NOTSUPPORTED, /* SetWAPSettings */ NOTSUPPORTED, /* GetMMSSettings */ NOTSUPPORTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetSyncMLSettings */ NOTSUPPORTED, /* SetSyncMLSettings */ NOTSUPPORTED, /* GetChatSettings */ NOTSUPPORTED, /* SetChatSettings */ NOTSUPPORTED, /* GetBitmap */ NOTSUPPORTED, /* SetBitmap */ ALCATEL_GetToDoStatus, ALCATEL_GetToDo, ALCATEL_GetNextToDo, ALCATEL_SetToDo, ALCATEL_AddToDo, ALCATEL_DeleteToDo, ALCATEL_DeleteAllToDo, ALCATEL_GetCalendarStatus, ALCATEL_GetCalendar, ALCATEL_GetNextCalendar, ALCATEL_SetCalendar, ALCATEL_AddCalendar, ALCATEL_DeleteCalendar, ALCATEL_DeleteAllCalendar, NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ + NOTSUPPORTED, /* GetNoteStatus */ + NOTSUPPORTED, /* GetNote */ NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* SetNote */ + NOTSUPPORTED, /* AddNote */ + NOTSUPPORTED, /* DeleteNote */ + NOTSUPPORTED, /* DeleteAllNotes */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFilePart */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ NOTSUPPORTED /* SetGPRSAccessPoint */ }; #endif #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/at/atgen.c b/gammu/emb/common/phone/at/atgen.c index ba23eb2..a875f0a 100644 --- a/gammu/emb/common/phone/at/atgen.c +++ b/gammu/emb/common/phone/at/atgen.c @@ -1,2235 +1,2235 @@ /* (c) 2002-2004 by Marcin Wiacek and Michal Cihar */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_ATGEN #include <string.h> #include <time.h> #include <ctype.h> #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" #include "../../service/sms/gsmsms.h" #include "../pfunc.h" #include "atgen.h" #include "samsung.h" #include "siemens.h" #include "sonyeric.h" #ifdef GSM_ENABLE_ALCATEL GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message, GSM_StateMachine *); #endif typedef struct { int Number; char Text[60]; } ATErrorCode; static ATErrorCode CMSErrorCodes[] = { /* * Error codes not specified here were either undefined or reserved in my * copy of specifications, if you have newer one, please fill in the gaps. */ /* 0...127 from GSM 04.11 Annex E-2 */ {1, "Unassigned (unallocated) number"}, {8, "Operator determined barring"}, {10, "Call barred"}, {21, "Short message transfer rejected"}, {27, "Destination out of service"}, {28, "Unidentified subscriber"}, {29, "Facility rejected"}, {30, "Unknown subscriber"}, {38, "Network out of order"}, {41, "Temporary failure"}, {42, "Congestion"}, {47, "Resources unavailable, unspecified"}, {50, "Requested facility not subscribed"}, {69, "Requested facility not implemented"}, {81, "Invalid short message transfer reference value"}, {95, "Invalid message, unspecified"}, {96, "Invalid mandatory information"}, {97, "Message type non-existent or not implemented"}, {98, "Message not compatible with short message protocol state"}, {99, "Information element non-existent or not implemented"}, {111, "Protocol error, unspecified"}, {127, "Interworking, unspecified"}, /* 128...255 from GSM 03.40 subclause 9.2.3.22 */ {0x80, "Telematic interworking not supported"}, {0x81, "Short message Type 0 not supported"}, {0x82, "Cannot replace short message"}, {0x8F, "Unspecified TP-PID error"}, {0x90, "Data coding scheme (alphabet) not supported"}, {0x91, "Message class not supported"}, {0x9F, "Unspecified TP-DCS error"}, {0xA0, "Command cannot be actioned"}, {0xA1, "Command unsupported"}, {0xAF, "Unspecified TP-Command error"}, {0xB0, "TPDU not supported"}, {0xC0, "SC busy"}, {0xC1, "No SC subscription"}, {0xC2, "SC system failure"}, {0xC3, "Invalid SME address"}, {0xC4, "Destination SME barred"}, {0xC5, "SM Rejected-Duplicate SM"}, {0xC6, "TP-VPF not supported"}, {0xC7, "TP-VP not supported"}, {0xD0, "SIM SMS storage full"}, {0xD1, "No SMS storage capability in SIM"}, {0xD2, "Error in MS"}, {0xD3, "Memory Capacity Exceede"}, {0xD4, "SIM Application Toolkit Busy"}, {0xFF, "Unspecified error cause"}, /* 300...511 from GSM 07.05 subclause 3.2.5 */ {300, "ME failure"}, {301, "SMS service of ME reserved"}, {302, "operation not allowed"}, {303, "operation not supported"}, {304, "invalid PDU mode parameter"}, {305, "invalid text mode parameter"}, {310, "SIM not inserted"}, {311, "SIM PIN required"}, {312, "PH-SIM PIN required"}, {313, "SIM failure"}, {314, "SIM busy"}, {315, "SIM wrong"}, {316, "SIM PUK required"}, {317, "SIM PIN2 required"}, {318, "SIM PUK2 required"}, {320, "memory failure"}, {321, "invalid memory index"}, {322, "memory full"}, {330, "SMSC address unknown"}, {331, "no network service"}, {332, "network timeout"}, {340, "no CNMA acknowledgement expected"}, {500, "unknown error"}, /* > 512 are manufacturer specific according to GSM 07.05 subclause 3.2.5 */ {-1, ""} }; static ATErrorCode CMEErrorCodes[] = { /* CME Error codes from GSM 07.07 section 9.2 */ {0, "phone failure"}, {1, "no connection to phone"}, {2, "phone-adaptor link reserved"}, {3, "operation not allowed"}, {4, "operation not supported"}, {5, "PH-SIM PIN required"}, {10, "SIM not inserted"}, {11, "SIM PIN required"}, {12, "SIM PUK required"}, {13, "SIM failure"}, {14, "SIM busy"}, {15, "SIM wrong"}, {16, "incorrect password"}, {17, "SIM PIN2 required"}, {18, "SIM PUK2 required"}, {20, "memory full"}, {21, "invalid index"}, {22, "not found"}, {23, "memory failure"}, {24, "text string too long"}, {25, "invalid characters in text string"}, {26, "dial string too long"}, {27, "invalid characters in dial string"}, {30, "no network service"}, {31, "network timeout"}, {100, "unknown"}, }; GSM_Error ATGEN_HandleCMEError(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->ErrorCode == 0) { smprintf(s, "CME Error occured, but it's type not detected\n"); } else if (Priv->ErrorText == NULL) { smprintf(s, "CME Error %i, no description available\n", Priv->ErrorCode); } else { smprintf(s, "CME Error %i: \"%s\"\n", Priv->ErrorCode, Priv->ErrorText); } /* For error codes descriptions see table a bit above */ switch (Priv->ErrorCode) { case -1: return ERR_EMPTY; case 3: return ERR_PERMISSION; case 4: return ERR_NOTSUPPORTED; case 5: case 11: case 12: case 16: case 17: case 18: return ERR_SECURITYERROR; case 20: return ERR_FULL; case 21: return ERR_INVALIDLOCATION; case 22: return ERR_EMPTY; case 23: return ERR_MEMORY; case 24: case 25: case 26: case 27: return ERR_INVALIDDATA; default: return ERR_UNKNOWN; } } GSM_Error ATGEN_HandleCMSError(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->ErrorCode == 0) { smprintf(s, "CMS Error occured, but it's type not detected\n"); } else if (Priv->ErrorText == NULL) { smprintf(s, "CMS Error %i, no description available\n", Priv->ErrorCode); } else { smprintf(s, "CMS Error %i: \"%s\"\n", Priv->ErrorCode, Priv->ErrorText); } /* For error codes descriptions see table a bit above */ switch (Priv->ErrorCode) { case 304: return ERR_NOTSUPPORTED; case 305: return ERR_BUG; case 311: case 312: case 316: case 317: case 318: return ERR_SECURITYERROR; case 322: return ERR_FULL; case 321: return ERR_INVALIDLOCATION; default: return ERR_UNKNOWN; } } /* FIXME: Function doesn't respect quoting of parameters and thus +FOO: * "ab","cd,ef" will consider as three arguments: "ab" >> "cd >> ef" */ int ATGEN_ExtractOneParameter(unsigned char *input, unsigned char *output) { int position=0; while (*input!=',' && *input!=0x0d && *input!=0x00) { *output=*input; input ++; output ++; position++; } *output=0; position++; return position; } void ATGEN_DecodeDateTime(GSM_DateTime *dt, unsigned char *input) { /* Samsung phones report year as %d instead of %02d */ if (input[2] == '/') { dt->Year=(*input-'0')*10; input++; } else { dt->Year=0; } dt->Year=dt->Year+(*input-'0'); input++; dt->Year+=2000; input++; dt->Month=(*input-'0')*10; input++; dt->Month=dt->Month+(*input-'0'); input++; input++; dt->Day=(*input-'0')*10; input++; dt->Day=dt->Day+(*input-'0'); input++; input++; dt->Hour=(*input-'0')*10; input++; dt->Hour=dt->Hour+(*input-'0'); input++; input++; dt->Minute=(*input-'0')*10; input++; dt->Minute=dt->Minute+(*input-'0');input++; input++; dt->Second=(*input-'0')*10; input++; dt->Second=dt->Second+(*input-'0');input++; if (input!=NULL) { input++; dt->Timezone=(*input-'0')*10; input++; dt->Timezone=dt->Timezone+(*input-'0');input++; input=input-2; if (*input=='-') dt->Timezone=-dt->Timezone; } } GSM_Error ATGEN_DispatchMessage(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Protocol_Message *msg = s->Phone.Data.RequestMsg; int i = 0, j, k; char *err, *line; ATErrorCode *ErrorCodes = NULL; SplitLines(msg->Buffer, msg->Length, &Priv->Lines, "\x0D\x0A", 2, true); /* Find number of lines */ while (Priv->Lines.numbers[i*2+1] != 0) { /* FIXME: handle special chars correctly */ smprintf(s, "%i \"%s\"\n",i+1,GetLineString(msg->Buffer,Priv->Lines,i+1)); i++; } Priv->ReplyState = AT_Reply_Unknown; Priv->ErrorText = NULL; Priv->ErrorCode = 0; line = GetLineString(msg->Buffer,Priv->Lines,i); if (!strcmp(line,"OK")) Priv->ReplyState = AT_Reply_OK; if (!strcmp(line,"> ")) Priv->ReplyState = AT_Reply_SMSEdit; if (!strcmp(line,"CONNECT")) Priv->ReplyState = AT_Reply_Connect; if (!strcmp(line,"ERROR" )) Priv->ReplyState = AT_Reply_Error; if (!strncmp(line,"+CME ERROR:",11)) { Priv->ReplyState = AT_Reply_CMEError; ErrorCodes = CMEErrorCodes; } if (!strncmp(line,"+CMS ERROR:",11)) { Priv->ReplyState = AT_Reply_CMSError; ErrorCodes = CMSErrorCodes; } /* FIXME: Samsung phones can answer +CME ERROR:-1 meaning empty location */ if (Priv->ReplyState == AT_Reply_CMEError && Priv->Manufacturer == AT_Samsung) { err = line + 11; Priv->ErrorCode = atoi(err); if (Priv->ErrorCode == -1) { Priv->ErrorText = "[Samsung] Empty location"; return GSM_DispatchMessage(s); } } if (Priv->ReplyState == AT_Reply_CMEError || Priv->ReplyState == AT_Reply_CMSError) { j = 0; /* One char behind +CM[SE] ERROR */ err = line + 12; while (err[j] && !isalnum(err[j])) j++; if (isdigit(err[j])) { Priv->ErrorCode = atoi(&(err[j])); k = 0; while (ErrorCodes[k].Number != -1) { if (ErrorCodes[k].Number == Priv->ErrorCode) { Priv->ErrorText = (char *)&(ErrorCodes[k].Text); break; } k++; } } else if (isalpha(err[j])) { k = 0; while (ErrorCodes[k].Number != -1) { if (!strncmp(err + j, ErrorCodes[k].Text, strlen(ErrorCodes[k].Text))) { Priv->ErrorCode = ErrorCodes[k].Number; Priv->ErrorText = (char *)&(ErrorCodes[k].Text); break; } k++; } } } return GSM_DispatchMessage(s); } GSM_Error ATGEN_GenericReply(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: case AT_Reply_Connect: return ERR_NONE; case AT_Reply_Error: return ERR_UNKNOWN; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); case AT_Reply_CMEError: return ATGEN_HandleCMEError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_ReplyGetUSSD(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char buffer[2000],buffer2[4000]; int i = 10; /* Ugly hack */ while (msg.Buffer[i]!=13) i++; i = i - 6; memcpy(buffer,msg.Buffer+10,i-11); buffer[i-11] = 0x00; smprintf(s, "USSD reply: \"%s\"\n",buffer); if (s->Phone.Data.EnableIncomingUSSD && s->User.IncomingUSSD!=NULL) { EncodeUnicode(buffer2,buffer,strlen(buffer)); s->User.IncomingUSSD(s->CurrentConfig->Device, buffer2); } return ERR_NONE; } GSM_Error ATGEN_SetIncomingUSSD(GSM_StateMachine *s, bool enable) { GSM_Error error; if (enable) { smprintf(s, "Enabling incoming USSD\n"); error=GSM_WaitFor (s, "AT+CUSD=1\r", 10, 0x00, 3, ID_SetUSSD); } else { smprintf(s, "Disabling incoming USSD\n"); error=GSM_WaitFor (s, "AT+CUSD=0\r", 10, 0x00, 3, ID_SetUSSD); } if (error==ERR_NONE) s->Phone.Data.EnableIncomingUSSD = enable; return error; } GSM_Error ATGEN_ReplyGetModel(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Phone_Data *Data = &s->Phone.Data; if (s->Phone.Data.Priv.ATGEN.ReplyState != AT_Reply_OK) return ERR_NOTSUPPORTED; if (strlen(GetLineString(msg.Buffer, Priv->Lines, 2)) <= MAX_MODEL_LENGTH) { CopyLineString(Data->Model, msg.Buffer, Priv->Lines, 2); /* Sometimes phone adds this before manufacturer (Sagem) */ if (strncmp("+CGMM: ", Data->Model, 7) == 0) { memmove(Data->Model, Data->Model + 7, strlen(Data->Model + 7) + 1); } Data->ModelInfo = GetModelData(NULL,Data->Model,NULL); if (Data->ModelInfo->number[0] == 0) Data->ModelInfo = GetModelData(NULL,NULL,Data->Model); if (Data->ModelInfo->number[0] == 0) Data->ModelInfo = GetModelData(Data->Model,NULL,NULL); if (Data->ModelInfo->number[0] != 0) strcpy(Data->Model,Data->ModelInfo->number); if (strstr(msg.Buffer,"Nokia")) Priv->Manufacturer = AT_Nokia; else if (strstr(msg.Buffer,"M20")) Priv->Manufacturer = AT_Siemens; else if (strstr(msg.Buffer,"MC35")) Priv->Manufacturer = AT_Siemens; else if (strstr(msg.Buffer,"TC35")) Priv->Manufacturer = AT_Siemens; else if (strstr(msg.Buffer, "iPAQ")) Priv->Manufacturer = AT_HP; if (strstr(msg.Buffer,"M20")) strcpy(Data->Model,"M20"); else if (strstr(msg.Buffer,"MC35")) strcpy(Data->Model,"MC35"); else if (strstr(msg.Buffer,"TC35")) strcpy(Data->Model,"TC35"); else if (strstr(msg.Buffer, "iPAQ")) strcpy(Data->Model,"iPAQ"); } else { smprintf(s, "WARNING: Model name too long, increase MAX_MODEL_LENGTH to at least %zd\n", strlen(GetLineString(msg.Buffer, Priv->Lines, 2))); } return ERR_NONE; } GSM_Error ATGEN_GetModel(GSM_StateMachine *s) { GSM_Error error; if (s->Phone.Data.Model[0] != 0) return ERR_NONE; smprintf(s, "Getting model\n"); error=GSM_WaitFor (s, "AT+CGMM\r", 8, 0x00, 3, ID_GetModel); if (error==ERR_NONE) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) { smprintf(s, "[Connected model - \"%s\"]\n",s->Phone.Data.Model); } } return error; } GSM_Error ATGEN_ReplyGetManufacturer(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; switch (Priv->ReplyState) { case AT_Reply_OK: smprintf(s, "Manufacturer info received\n"); Priv->Manufacturer = AT_Unknown; if (strlen(GetLineString(msg.Buffer, Priv->Lines, 2)) <= MAX_MANUFACTURER_LENGTH) { CopyLineString(s->Phone.Data.Manufacturer, msg.Buffer, Priv->Lines, 2); } else { smprintf(s, "WARNING: Manufacturer name too long, increase MAX_MANUFACTURER_LENGTH to at least %zd\n", strlen(GetLineString(msg.Buffer, Priv->Lines, 2))); s->Phone.Data.Manufacturer[0] = 0; } /* Sometimes phone adds this before manufacturer (Sagem) */ if (strncmp("+CGMI: ", s->Phone.Data.Manufacturer, 7) == 0) { memmove(s->Phone.Data.Manufacturer, s->Phone.Data.Manufacturer + 7, strlen(s->Phone.Data.Manufacturer + 7) + 1); } if (strstr(msg.Buffer,"Falcom")) { smprintf(s, "Falcom\n"); strcpy(s->Phone.Data.Manufacturer,"Falcom"); Priv->Manufacturer = AT_Falcom; if (strstr(msg.Buffer,"A2D")) { strcpy(s->Phone.Data.Model,"A2D"); s->Phone.Data.ModelInfo = GetModelData(NULL,s->Phone.Data.Model,NULL); smprintf(s, "Model A2D\n"); } } if (strstr(msg.Buffer,"Nokia")) { smprintf(s, "Nokia\n"); strcpy(s->Phone.Data.Manufacturer,"Nokia"); Priv->Manufacturer = AT_Nokia; } if (strstr(msg.Buffer,"SIEMENS")) { smprintf(s, "Siemens\n"); strcpy(s->Phone.Data.Manufacturer,"Siemens"); Priv->Manufacturer = AT_Siemens; } if (strstr(msg.Buffer,"ERICSSON")) { smprintf(s, "Ericsson\n"); strcpy(s->Phone.Data.Manufacturer,"Ericsson"); Priv->Manufacturer = AT_Ericsson; } if (strstr(msg.Buffer,"iPAQ")) { smprintf(s, "iPAQ\n"); strcpy(s->Phone.Data.Manufacturer,"HP"); Priv->Manufacturer = AT_HP; } if (strstr(msg.Buffer,"ALCATEL")) { smprintf(s, "Alcatel\n"); strcpy(s->Phone.Data.Manufacturer,"Alcatel"); Priv->Manufacturer = AT_Alcatel; } if (strstr(msg.Buffer,"SAGEM")) { smprintf(s, "Sagem\n"); strcpy(s->Phone.Data.Manufacturer,"Sagem"); Priv->Manufacturer = AT_Sagem; } if (strstr(msg.Buffer,"Samsung")) { smprintf(s, "Samsung\n"); strcpy(s->Phone.Data.Manufacturer,"Samsung"); Priv->Manufacturer = AT_Samsung; } return ERR_NONE; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetManufacturer(GSM_StateMachine *s) { if (s->Phone.Data.Manufacturer[0] != 0) return ERR_NONE; return GSM_WaitFor (s, "AT+CGMI\r", 8, 0x00, 4, ID_GetManufacturer); } GSM_Error ATGEN_ReplyGetFirmwareCGMR(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned int i = 0; strcpy(s->Phone.Data.Version,"unknown"); s->Phone.Data.VerNum = 0; if (Priv->ReplyState == AT_Reply_OK) { CopyLineString(s->Phone.Data.Version, msg.Buffer, Priv->Lines, 2); /* Sometimes phone adds this before manufacturer (Sagem) */ if (strncmp("+CGMR: ", s->Phone.Data.Version, 7) == 0) { memmove(s->Phone.Data.Version, s->Phone.Data.Version + 7, strlen(s->Phone.Data.Version + 7) + 1); } } if (Priv->Manufacturer == AT_Ericsson) { while (1) { if (s->Phone.Data.Version[i] == 0x20) { s->Phone.Data.Version[i] = 0x00; break; } if (i == strlen(s->Phone.Data.Version)) break; i++; } } smprintf(s, "Received firmware version: \"%s\"\n",s->Phone.Data.Version); GSM_CreateFirmwareNumber(s); return ERR_NONE; } GSM_Error ATGEN_ReplyGetFirmwareATI(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; switch (Priv->ReplyState) { case AT_Reply_OK: // strcpy(Data->Version,"0.00"); // *Data->VersionNum=0; // if (Data->Priv.ATGEN.ReplyState==AT_Reply_OK) { // CopyLineString(Data->Version, msg.Buffer, Priv->Lines, 2); // } // smprintf(s, "Received firmware version: \"%s\"\n",Data->Version); // GSM_CreateFirmwareNumber(Data); // return ERR_NONE; case AT_Reply_Error: return ERR_NOTSUPPORTED; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetFirmware(GSM_StateMachine *s) { GSM_Error error; if (s->Phone.Data.Version[0] != 0) return ERR_NONE; error=ATGEN_GetManufacturer(s); if (error != ERR_NONE) return error; // smprintf(s, "Getting firmware - method 1\n"); // error=GSM_WaitFor (s, "ATI\r", 4, 0x00, 3, ID_GetFirmware); // if (error != ERR_NONE) { smprintf(s, "Getting firmware - method 2\n"); error=GSM_WaitFor (s, "AT+CGMR\r", 8, 0x00, 3, ID_GetFirmware); // } if (error==ERR_NONE) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) { smprintf(s, "[Firmware version - \"%s\"]\n",s->Phone.Data.Version); } } return error; } GSM_Error ATGEN_Initialise(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; char buff[2]; Priv->SMSMode = 0; Priv->Manufacturer = 0; Priv->PhoneSMSMemory = 0; Priv->CanSaveSMS = false; Priv->SIMSMSMemory = 0; Priv->SMSMemory = 0; Priv->PBKMemory = 0; Priv->PBKSBNR = 0; Priv->PBKCharset = 0; Priv->UCS2CharsetFailed = false; Priv->NonUCS2CharsetFailed = false; Priv->PBKMemories[0] = 0; Priv->FirstCalendarPos = 0; Priv->NextMemoryEntry = 0; Priv->FirstMemoryEntry = 0; Priv->file.Used = 0; Priv->file.Buffer = NULL; Priv->OBEX = false; Priv->MemorySize = 0; Priv->TextLength = 0; Priv->NumberLength = 0; Priv->ErrorText = NULL; if (s->ConnectionType != GCT_IRDAAT && s->ConnectionType != GCT_BLUEAT) { /* We try to escape AT+CMGS mode, at least Siemens M20 * then needs to get some rest */ smprintf(s, "Escaping SMS mode\n"); error = s->Protocol.Functions->WriteMessage(s, "\x1B\r", 2, 0x00); if (error!=ERR_NONE) return error; /* Grab any possible garbage */ while (s->Device.Functions->ReadDevice(s, buff, 2) > 0) my_sleep(10); } /* When some phones (Alcatel BE5) is first time connected, it needs extra * time to react, sending just AT wakes up the phone and it then can react * to ATE1. We don't need to check whether this fails as it is just to * wake up the phone and does nothing. */ smprintf(s, "Sending simple AT command to wake up some devices\n"); GSM_WaitFor (s, "AT\r", 3, 0x00, 2, ID_IncomingFrame); smprintf(s, "Enabling echo\n"); error = GSM_WaitFor (s, "ATE1\r", 5, 0x00, 3, ID_EnableEcho); if (error != ERR_NONE) return error; smprintf(s, "Enabling CME errors\n"); /* Try numeric errors */ if (GSM_WaitFor (s, "AT+CMEE=1\r", 10, 0x00, 3, ID_EnableErrorInfo) != ERR_NONE) { /* Try textual errors */ if (GSM_WaitFor (s, "AT+CMEE=2\r", 10, 0x00, 3, ID_EnableErrorInfo) != ERR_NONE) { smprintf(s, "CME errors could not be enabled, some error types won't be detected.\n"); } } error = ATGEN_GetModel(s); if (error != ERR_NONE) return error; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SLOWWRITE)) { s->Protocol.Data.AT.FastWrite = true; } return error; } GSM_Error ATGEN_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) { unsigned char req[50]; - if (smsc->Location!=1) return ERR_NOTSUPPORTED; + if (smsc->Location!=1) return ERR_INVALIDLOCATION; sprintf(req, "AT+CSCA=\"%s\"\r",DecodeUnicodeString(smsc->Number)); smprintf(s, "Setting SMSC\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_SetSMSC); } GSM_Error ATGEN_ReplyGetSMSMemories(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: /* Reply here is: * (memories for reading)[, (memories for writing)[, (memories for storing received messages)]] * each memory is in quotes, * Example: ("SM"), ("SM"), ("SM") * * We need to get from this supported memories. For this case * we assume, that just appearence of memory makes it * available for everything. Then we need to find out whether * phone supports writing to memory. This is done by searching * for "), (", which will appear between lists. */ s->Phone.Data.Priv.ATGEN.CanSaveSMS = false; if (strstr(msg.Buffer, "), (") != NULL || strstr(msg.Buffer, "),(") != NULL) { s->Phone.Data.Priv.ATGEN.CanSaveSMS = true; } if (strstr(msg.Buffer, "\"SM\"") != NULL) s->Phone.Data.Priv.ATGEN.SIMSMSMemory = AT_AVAILABLE; else s->Phone.Data.Priv.ATGEN.SIMSMSMemory = AT_NOTAVAILABLE; if (strstr(msg.Buffer, "\"ME\"") != NULL) s->Phone.Data.Priv.ATGEN.PhoneSMSMemory = AT_AVAILABLE; else s->Phone.Data.Priv.ATGEN.PhoneSMSMemory = AT_NOTAVAILABLE; smprintf(s, "Available SMS memories received, ME = %d, SM = %d, cansavesms =", s->Phone.Data.Priv.ATGEN.PhoneSMSMemory, s->Phone.Data.Priv.ATGEN.SIMSMSMemory); if (s->Phone.Data.Priv.ATGEN.CanSaveSMS) smprintf(s, "true"); smprintf(s, "\n"); return ERR_NONE; case AT_Reply_Error: case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); case AT_Reply_CMEError: return ATGEN_HandleCMEError(s); default: return ERR_UNKNOWNRESPONSE; } } GSM_Error ATGEN_GetSMSMemories(GSM_StateMachine *s) { smprintf(s, "Getting available SMS memories\n"); return GSM_WaitFor (s, "AT+CPMS=?\r", 10, 0x00, 4, ID_GetSMSMemories); } GSM_Error ATGEN_SetSMSMemory(GSM_StateMachine *s, bool SIM) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; char req[] = "AT+CPMS=\"XX\",\"XX\"\r"; int reqlen = 18; GSM_Error error; if ((SIM && Priv->SIMSMSMemory == 0) || (!SIM && Priv->PhoneSMSMemory == 0)) { /* We silently ignore error here, because when this fails, we can try to setmemory anyway */ ATGEN_GetSMSMemories(s); } /* If phone can not save SMS, don't try to set memory for saving */ if (!Priv->CanSaveSMS) { req[12] = '\r'; reqlen = 13; } if (SIM) { if (Priv->SMSMemory == MEM_SM) return ERR_NONE; if (Priv->SIMSMSMemory == AT_NOTAVAILABLE) return ERR_NOTSUPPORTED; req[9] = 'S'; req[10] = 'M'; req[14] = 'S'; req[15] = 'M'; smprintf(s, "Setting SMS memory type to SM\n"); error=GSM_WaitFor (s, req, reqlen, 0x00, 3, ID_SetMemoryType); if (Priv->SIMSMSMemory == 0 && error == ERR_NONE) { Priv->SIMSMSMemory = AT_AVAILABLE; } if (error == ERR_NOTSUPPORTED) { smprintf(s, "Can't access SIM card?\n"); return ERR_SECURITYERROR; } if (error != ERR_NONE) return error; Priv->SMSMemory = MEM_SM; } else { if (Priv->SMSMemory == MEM_ME) return ERR_NONE; if (Priv->PhoneSMSMemory == AT_NOTAVAILABLE) return ERR_NOTSUPPORTED; req[9] = 'M'; req[10] = 'E'; req[14] = 'M'; req[15] = 'E'; smprintf(s, "Setting SMS memory type to ME\n"); error=GSM_WaitFor (s, req, reqlen, 0x00, 3, ID_SetMemoryType); if (Priv->PhoneSMSMemory == 0 && error == ERR_NONE) { Priv->PhoneSMSMemory = AT_AVAILABLE; } if (error == ERR_NONE) Priv->SMSMemory = MEM_ME; } return error; } GSM_Error ATGEN_GetSMSMode(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; if (Priv->SMSMode != 0) return ERR_NONE; smprintf(s, "Trying SMS PDU mode\n"); error=GSM_WaitFor (s, "AT+CMGF=0\r", 10, 0x00, 3, ID_GetSMSMode); if (error==ERR_NONE) { Priv->SMSMode = SMS_AT_PDU; return ERR_NONE; } smprintf(s, "Trying SMS text mode\n"); error=GSM_WaitFor (s, "AT+CMGF=1\r", 10, 0x00, 3, ID_GetSMSMode); if (error==ERR_NONE) { smprintf(s, "Enabling displaying all parameters in text mode\n"); error=GSM_WaitFor (s, "AT+CSDH=1\r", 10, 0x00, 3, ID_GetSMSMode); if (error == ERR_NONE) Priv->SMSMode = SMS_AT_TXT; } return error; } GSM_Error ATGEN_GetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *folderid, int *location) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; int ifolderid, maxfolder; GSM_Error error; if (Priv->PhoneSMSMemory == 0) { error = ATGEN_SetSMSMemory(s, false); if (error != ERR_NONE && error != ERR_NOTSUPPORTED) return error; } if (Priv->SIMSMSMemory == 0) { error = ATGEN_SetSMSMemory(s, true); if (error != ERR_NONE && error != ERR_NOTSUPPORTED) return error; } if (Priv->SIMSMSMemory != AT_AVAILABLE && Priv->PhoneSMSMemory != AT_AVAILABLE) { /* No SMS memory at all */ return ERR_NOTSUPPORTED; } if (Priv->SIMSMSMemory == AT_AVAILABLE && Priv->PhoneSMSMemory == AT_AVAILABLE) { /* Both available */ maxfolder = 2; } else { /* One available */ maxfolder = 1; } /* simulate flat SMS memory */ if (sms->Folder == 0x00) { ifolderid = sms->Location / PHONE_MAXSMSINFOLDER; if (ifolderid + 1 > maxfolder) return ERR_NOTSUPPORTED; *folderid = ifolderid + 1; *location = sms->Location - ifolderid * PHONE_MAXSMSINFOLDER; } else { if (sms->Folder > 2 * maxfolder) return ERR_NOTSUPPORTED; *folderid = sms->Folder <= 2 ? 1 : 2; *location = sms->Location; } smprintf(s, "SMS folder %i & location %i -> ATGEN folder %i & location %i\n", sms->Folder,sms->Location,*folderid,*location); if (Priv->SIMSMSMemory == AT_AVAILABLE && *folderid == 1) { return ATGEN_SetSMSMemory(s, true); } else { return ATGEN_SetSMSMemory(s, false); } } void ATGEN_SetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char folderid, int location) { sms->Folder = 0; sms->Location = (folderid - 1) * PHONE_MAXSMSINFOLDER + location; smprintf(s, "ATGEN folder %i & location %i -> SMS folder %i & location %i\n", folderid,location,sms->Folder,sms->Location); } GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_SMSMessage *sms = &s->Phone.Data.GetSMSMessage->SMS[0]; int current = 0, current2, i; unsigned char buffer[300],smsframe[800]; unsigned char firstbyte, TPDCS, TPUDL, TPStatus; GSM_Error error; switch (Priv->ReplyState) { case AT_Reply_OK: if (Priv->Lines.numbers[4] == 0x00) return ERR_EMPTY; s->Phone.Data.GetSMSMessage->Number = 1; s->Phone.Data.GetSMSMessage->SMS[0].Name[0] = 0; s->Phone.Data.GetSMSMessage->SMS[0].Name[1] = 0; switch (Priv->SMSMode) { case SMS_AT_PDU: CopyLineString(buffer, msg.Buffer, Priv->Lines, 2); switch (buffer[7]) { case '0': sms->State = SMS_UnRead; break; case '1': sms->State = SMS_Read; break; case '2': sms->State = SMS_UnSent; break; default : sms->State = SMS_Sent; break;//case '3' } DecodeHexBin (buffer, GetLineString(msg.Buffer,Priv->Lines,3), strlen(GetLineString(msg.Buffer,Priv->Lines,3))); /* Siemens MC35 (only ?) */ if (strstr(msg.Buffer,"+CMGR: 0,,0")!=NULL) return ERR_EMPTY; /* Siemens M20 */ if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) { /* we check for the most often visible */ if (buffer[1]!=NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN && buffer[1]!=NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN && buffer[1]!=NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) { /* Seems to be Delivery Report */ smprintf(s, "SMS type - status report (M20 style)\n"); sms->PDU = SMS_Status_Report; sms->Folder = 1; /*INBOX SIM*/ sms->InboxFolder = true; smsframe[12]=buffer[current++]; smsframe[PHONE_SMSStatusReport.TPMR]=buffer[current++]; current2=((buffer[current])+1)/2+1; for(i=0;i<current2+1;i++) smsframe[PHONE_SMSStatusReport.Number+i]=buffer[current++]; for(i=0;i<7;i++) smsframe[PHONE_SMSStatusReport.DateTime+i]=buffer[current++]; smsframe[0] = 0; for(i=0;i<7;i++) smsframe[PHONE_SMSStatusReport.SMSCTime+i]=buffer[current++]; smsframe[PHONE_SMSStatusReport.TPStatus]=buffer[current]; GSM_DecodeSMSFrame(sms,smsframe,PHONE_SMSStatusReport); return ERR_NONE; } } /* We use locations from SMS layouts like in ../phone2.c(h) */ for(i=0;i<buffer[0]+1;i++) smsframe[i]=buffer[current++]; smsframe[12]=buffer[current++]; /* See GSM 03.40 section 9.2.3.1 */ switch (smsframe[12] & 0x03) { case 0x00: smprintf(s, "SMS type - deliver\n"); sms->PDU = SMS_Deliver; if (Priv->SMSMemory == MEM_SM) { sms->Folder = 1; /*INBOX SIM*/ } else { sms->Folder = 3; /*INBOX ME*/ } sms->InboxFolder = true; current2=((buffer[current])+1)/2+1; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) { if (buffer[current+1]==NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) { smprintf(s, "Trying to read alphanumeric number\n"); for(i=0;i<4;i++) smsframe[PHONE_SMSDeliver.Number+i]=buffer[current++]; current+=6; for(i=0;i<current2-3;i++) smsframe[PHONE_SMSDeliver.Number+i+4]=buffer[current++]; } else { for(i=0;i<current2+1;i++) smsframe[PHONE_SMSDeliver.Number+i]=buffer[current++]; } } else { for(i=0;i<current2+1;i++) smsframe[PHONE_SMSDeliver.Number+i]=buffer[current++]; } smsframe[PHONE_SMSDeliver.TPPID] = buffer[current++]; smsframe[PHONE_SMSDeliver.TPDCS] = buffer[current++]; for(i=0;i<7;i++) smsframe[PHONE_SMSDeliver.DateTime+i]=buffer[current++]; smsframe[PHONE_SMSDeliver.TPUDL] = buffer[current++]; for(i=0;i<smsframe[PHONE_SMSDeliver.TPUDL];i++) smsframe[i+PHONE_SMSDeliver.Text]=buffer[current++]; GSM_DecodeSMSFrame(sms,smsframe,PHONE_SMSDeliver); return ERR_NONE; case 0x01: smprintf(s, "SMS type - submit\n"); sms->PDU = SMS_Submit; if (Priv->SMSMemory == MEM_SM) { sms->Folder = 2; /*OUTBOX SIM*/ smprintf(s, "Outbox SIM\n"); } else { sms->Folder = 4; /*OUTBOX ME*/ } sms->InboxFolder = false; smsframe[PHONE_SMSSubmit.TPMR] = buffer[current++]; current2=((buffer[current])+1)/2+1; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) { if (buffer[current+1]==NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) { smprintf(s, "Trying to read alphanumeric number\n"); for(i=0;i<4;i++) smsframe[PHONE_SMSSubmit.Number+i]=buffer[current++]; current+=6; for(i=0;i<current2-3;i++) smsframe[PHONE_SMSSubmit.Number+i+4]=buffer[current++]; } else { for(i=0;i<current2+1;i++) smsframe[PHONE_SMSSubmit.Number+i]=buffer[current++]; } } else { for(i=0;i<current2+1;i++) smsframe[PHONE_SMSSubmit.Number+i]=buffer[current++]; } smsframe[PHONE_SMSSubmit.TPPID] = buffer[current++]; smsframe[PHONE_SMSSubmit.TPDCS] = buffer[current++]; /* See GSM 03.40 9.2.3.3 - TPVP can not exist in frame */ if ((smsframe[12] & 0x18)!=0) current++; //TPVP is ignored now smsframe[PHONE_SMSSubmit.TPUDL] = buffer[current++]; for(i=0;i<smsframe[PHONE_SMSSubmit.TPUDL];i++) smsframe[i+PHONE_SMSSubmit.Text]=buffer[current++]; GSM_DecodeSMSFrame(sms,smsframe,PHONE_SMSSubmit); return ERR_NONE; case 0x02: smprintf(s, "SMS type - status report\n"); sms->PDU = SMS_Status_Report; sms->Folder = 1; /*INBOX SIM*/ sms->InboxFolder = true; smprintf(s, "TPMR is %d\n",buffer[current]); smsframe[PHONE_SMSStatusReport.TPMR] = buffer[current++]; current2=((buffer[current])+1)/2+1; for(i=0;i<current2+1;i++) smsframe[PHONE_SMSStatusReport.Number+i]=buffer[current++]; for(i=0;i<7;i++) smsframe[PHONE_SMSStatusReport.DateTime+i]=buffer[current++]; for(i=0;i<7;i++) smsframe[PHONE_SMSStatusReport.SMSCTime+i]=buffer[current++]; smsframe[PHONE_SMSStatusReport.TPStatus]=buffer[current]; GSM_DecodeSMSFrame(sms,smsframe,PHONE_SMSStatusReport); return ERR_NONE; } break; case SMS_AT_TXT: current = 0; while (msg.Buffer[current]!='"') current++; current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); if (!strcmp(buffer,"\"0\"") || !strcmp(buffer,"\"REC UNREAD\"")) { smprintf(s, "SMS type - deliver\n"); sms->State = SMS_UnRead; sms->PDU = SMS_Deliver; if (Priv->SMSMemory == MEM_SM) { sms->Folder = 1; /*INBOX SIM*/ } else { sms->Folder = 3; /*INBOX ME*/ } sms->InboxFolder = true; } else if (!strcmp(buffer,"\"1\"") || !strcmp(buffer,"\"REC READ\"")) { smprintf(s, "SMS type - deliver\n"); sms->State = SMS_Read; sms->PDU = SMS_Deliver; if (Priv->SMSMemory == MEM_SM) { sms->Folder = 1; /*INBOX SIM*/ } else { sms->Folder = 3; /*INBOX ME*/ } sms->InboxFolder = true; } else if (!strcmp(buffer,"\"2\"") || !strcmp(buffer,"\"STO UNSENT\"")) { smprintf(s, "SMS type - submit\n"); sms->State = SMS_UnSent; sms->PDU = SMS_Submit; if (Priv->SMSMemory == MEM_SM) { sms->Folder = 2; /*OUTBOX SIM*/ } else { sms->Folder = 4; /*OUTBOX ME*/ } sms->InboxFolder = false; } else if (!strcmp(buffer,"\"3\"") || !strcmp(buffer,"\"STO SENT\"")) { smprintf(s, "SMS type - submit\n"); sms->State = SMS_Sent; sms->PDU = SMS_Submit; if (Priv->SMSMemory == MEM_SM) { sms->Folder = 2; /*OUTBOX SIM*/ } else { sms->Folder = 4; /*OUTBOX ME*/ } sms->InboxFolder = false; } current += ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); /* It's delivery report according to Nokia AT standards */ if (sms->Folder==1 && buffer[0]!=0 && buffer[0]!='"') { /* ??? */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); /* format of sender number */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); /* Sender number */ /* FIXME: support for all formats */ EncodeUnicode(sms->Number,buffer+1,strlen(buffer)-2); smprintf(s, "Sender \"%s\"\n",DecodeUnicodeString(sms->Number)); /* ??? */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); /* Sending datetime */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); i = strlen(buffer); buffer[i] = ','; i++; current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer+i); smprintf(s, "\"%s\"\n",buffer); ATGEN_DecodeDateTime(&sms->DateTime, buffer+1); /* Date of SMSC response */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); i = strlen(buffer); buffer[i] = ','; i++; current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer+i); smprintf(s, "\"%s\"\n",buffer); ATGEN_DecodeDateTime(&sms->SMSCTime, buffer+1); /* TPStatus */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); TPStatus=atoi(buffer); buffer[PHONE_SMSStatusReport.TPStatus] = TPStatus; error=GSM_DecodeSMSFrameStatusReportData(sms, buffer, PHONE_SMSStatusReport); if (error!=ERR_NONE) return error; /* NO SMSC number */ sms->SMSC.Number[0]=0; sms->SMSC.Number[1]=0; sms->PDU = SMS_Status_Report; sms->ReplyViaSameSMSC=false; } else { /* Sender number */ /* FIXME: support for all formats */ EncodeUnicode(sms->Number,buffer+1,strlen(buffer)-2); /* Sender number in alphanumeric format ? */ current += ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); if (strlen(buffer)!=0) EncodeUnicode(sms->Number,buffer+1,strlen(buffer)-2); smprintf(s, "Sender \"%s\"\n",DecodeUnicodeString(sms->Number)); /* Sending datetime */ if (sms->Folder==1 || sms->Folder==3) { current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); /* FIXME: ATGEN_ExtractOneParameter() is broken as it doesn't respect * quoting of parameters and thus +FOO: "ab","cd,ef" will consider * as three arguments: "ab" >> "cd >> ef" */ if (*buffer=='"') { i = strlen(buffer); buffer[i] = ','; i++; current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer+i); } smprintf(s, "\"%s\"\n",buffer); if (*buffer) ATGEN_DecodeDateTime(&sms->DateTime, buffer+1); else { /* FIXME: What is the proper undefined GSM_DateTime ? */ memset(&sms->DateTime, 0, sizeof(sms->DateTime)); } ATGEN_DecodeDateTime(&sms->DateTime, buffer+1); } /* Sender number format */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); /* First byte */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); firstbyte=atoi(buffer); sms->ReplyViaSameSMSC=false; /* GSM 03.40 section 9.2.3.17 (TP-Reply-Path) */ if ((firstbyte & 128)==128) sms->ReplyViaSameSMSC=true; /* TP PID */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); sms->ReplaceMessage = 0; if (atoi(buffer) > 0x40 && atoi(buffer) < 0x48) { sms->ReplaceMessage = atoi(buffer) - 0x40; } smprintf(s, "TPPID: %02x %i\n",atoi(buffer),atoi(buffer)); /* TP DCS */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); TPDCS=atoi(buffer); if (sms->Folder==2 || sms->Folder==4) { /*TP VP */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); } /* SMSC number */ /* FIXME: support for all formats */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); EncodeUnicode(sms->SMSC.Number,buffer+1,strlen(buffer)-2); /* Format of SMSC number */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); /* TPUDL */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); TPUDL=atoi(buffer); current++; sms->Coding = SMS_Coding_Default; /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) * and GSM 03.38 section 4 */ if ((TPDCS & 0xf4) == 0xf4) sms->Coding=SMS_Coding_8bit; if ((TPDCS & 0x08) == 0x08) sms->Coding=SMS_Coding_Unicode; sms->Class = -1; if ((TPDCS & 0xF3)==0xF0) sms->Class = 0; if ((TPDCS & 0xF3)==0xF1) sms->Class = 1; if ((TPDCS & 0xF3)==0xF2) sms->Class = 2; if ((TPDCS & 0xF3)==0xF3) sms->Class = 3; smprintf(s, "SMS class: %i\n",sms->Class); switch (sms->Coding) { case SMS_Coding_Default: /* GSM 03.40 section 9.2.3.23 (TP-User-Data-Header-Indicator) */ /* If not SMS with UDH, it's coded normal */ /* If UDH available, treat it as Unicode or 8 bit */ if ((firstbyte & 0x40)!=0x40) { sms->UDH.Type = UDH_NoUDH; sms->Length = TPUDL; EncodeUnicode(sms->Text,msg.Buffer+Priv->Lines.numbers[2*2],TPUDL); break; } case SMS_Coding_Unicode: case SMS_Coding_8bit: DecodeHexBin(buffer+PHONE_SMSDeliver.Text, msg.Buffer+current, TPUDL*2); buffer[PHONE_SMSDeliver.firstbyte] = firstbyte; buffer[PHONE_SMSDeliver.TPDCS] = TPDCS; buffer[PHONE_SMSDeliver.TPUDL] = TPUDL; return GSM_DecodeSMSFrameText(sms, buffer, PHONE_SMSDeliver); } } return ERR_NONE; default: break; } break; case AT_Reply_CMSError: if (Priv->ErrorCode == 320 || Priv->ErrorCode == 500) { return ERR_EMPTY; } else { return ATGEN_HandleCMSError(s); } case AT_Reply_CMEError: return ATGEN_HandleCMEError(s); case AT_Reply_Error: /* A2D returns Error with empty location */ return ERR_EMPTY; default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms) { unsigned char req[20], folderid; GSM_Error error; int location, getfolder, add = 0; error=ATGEN_GetSMSLocation(s,&sms->SMS[0], &folderid, &location); if (error!=ERR_NONE) return error; if (s->Phone.Data.Priv.ATGEN.SMSMemory == MEM_ME && IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMSME900)) add = 899; sprintf(req, "AT+CMGR=%i\r", location + add); error=ATGEN_GetSMSMode(s); if (error != ERR_NONE) return error; error=ATGEN_GetManufacturer(s); if (error != ERR_NONE) return error; s->Phone.Data.GetSMSMessage=sms; smprintf(s, "Getting SMS\n"); error=GSM_WaitFor (s, req, strlen(req), 0x00, 5, ID_GetSMSMessage); if (error==ERR_NONE) { getfolder = sms->SMS[0].Folder; // if (getfolder != 0 && getfolder != sms->SMS[0].Folder) return ERR_EMPTY; ATGEN_SetSMSLocation(s, &sms->SMS[0], folderid, location); sms->SMS[0].Folder = getfolder; sms->SMS[0].Memory = MEM_SM; if (getfolder > 2) sms->SMS[0].Memory = MEM_ME; } return error; } GSM_Error ATGEN_GetNextSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; int usedsms; if (Priv->PhoneSMSMemory == 0) { error = ATGEN_SetSMSMemory(s, false); if (error != ERR_NONE && error != ERR_NOTSUPPORTED) return error; } if (Priv->SIMSMSMemory == 0) { error = ATGEN_SetSMSMemory(s, true); if (error != ERR_NONE && error != ERR_NOTSUPPORTED) return error; } if (Priv->SIMSMSMemory == AT_NOTAVAILABLE && Priv->PhoneSMSMemory == AT_NOTAVAILABLE) return ERR_NOTSUPPORTED; if (start) { error=s->Phone.Functions->GetSMSStatus(s,&Priv->LastSMSStatus); if (error!=ERR_NONE) return error; Priv->LastSMSRead = 0; sms->SMS[0].Location = 0; } while (true) { sms->SMS[0].Location++; if (sms->SMS[0].Location < PHONE_MAXSMSINFOLDER) { if (Priv->SIMSMSMemory == AT_AVAILABLE) { usedsms = Priv->LastSMSStatus.SIMUsed; } else { usedsms = Priv->LastSMSStatus.PhoneUsed; } if (Priv->LastSMSRead >= usedsms) { if (Priv->PhoneSMSMemory == AT_NOTAVAILABLE || Priv->LastSMSStatus.PhoneUsed==0) return ERR_EMPTY; Priv->LastSMSRead = 0; sms->SMS[0].Location = PHONE_MAXSMSINFOLDER + 1; } } else { if (Priv->PhoneSMSMemory == AT_NOTAVAILABLE) return ERR_EMPTY; if (Priv->LastSMSRead>=Priv->LastSMSStatus.PhoneUsed) return ERR_EMPTY; } sms->SMS[0].Folder = 0; error=s->Phone.Functions->GetSMS(s, sms); if (error==ERR_NONE) { Priv->LastSMSRead++; break; } if (error != ERR_EMPTY && error != ERR_INVALIDLOCATION) return error; } return error; } GSM_Error ATGEN_ReplyGetSMSStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_SMSMemoryStatus *SMSStatus = s->Phone.Data.SMSStatus; char *start; int current = 0; unsigned char buffer[50]; switch (Priv->ReplyState) { case AT_Reply_OK: smprintf(s, "SMS status received\n"); start = strstr(msg.Buffer, "+CPMS: ") + 7; if (strstr(msg.Buffer,"ME")!=NULL) { SMSStatus->PhoneUsed = atoi(start); current+=ATGEN_ExtractOneParameter(start+current, buffer); current+=ATGEN_ExtractOneParameter(start+current, buffer); SMSStatus->PhoneSize = atoi(buffer); smprintf(s, "Used : %i\n",SMSStatus->PhoneUsed); smprintf(s, "Size : %i\n",SMSStatus->PhoneSize); } else { SMSStatus->SIMUsed = atoi(start); current+=ATGEN_ExtractOneParameter(start+current, buffer); current+=ATGEN_ExtractOneParameter(start+current, buffer); SMSStatus->SIMSize = atoi(buffer); smprintf(s, "Used : %i\n",SMSStatus->SIMUsed); smprintf(s, "Size : %i\n",SMSStatus->SIMSize); if (SMSStatus->SIMSize == 0) { smprintf(s, "Can't access SIM card\n"); return ERR_SECURITYERROR; } } return ERR_NONE; case AT_Reply_Error: if (strstr(msg.Buffer,"SM")!=NULL) { smprintf(s, "Can't access SIM card\n"); return ERR_SECURITYERROR; } return ERR_NOTSUPPORTED; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; /* No templates at all */ status->TemplatesUsed = 0; status->SIMUsed = 0; status->SIMUnRead = 0; status->SIMSize = 0; s->Phone.Data.SMSStatus=status; if ((Priv->SIMSMSMemory == 0) || (Priv->PhoneSMSMemory == 0)) { /* We silently ignore error here, because when this fails, we can try to setmemory anyway */ ATGEN_GetSMSMemories(s); } if (Priv->PhoneSMSMemory == 0) { error = ATGEN_SetSMSMemory(s, false); if (error != ERR_NONE && error != ERR_NOTSUPPORTED) return error; } if (Priv->SIMSMSMemory == 0) { error = ATGEN_SetSMSMemory(s, true); if (error != ERR_NONE && error != ERR_NOTSUPPORTED) return error; } if (Priv->SIMSMSMemory == AT_AVAILABLE) { smprintf(s, "Getting SIM SMS status\n"); if (Priv->CanSaveSMS) { error=GSM_WaitFor (s, "AT+CPMS=\"SM\",\"SM\"\r", 18, 0x00, 4, ID_GetSMSStatus); } else { error=GSM_WaitFor (s, "AT+CPMS=\"SM\"\r", 13, 0x00, 4, ID_GetSMSStatus); } if (error!=ERR_NONE) return error; Priv->SMSMemory = MEM_SM; } status->PhoneUsed = 0; status->PhoneUnRead = 0; status->PhoneSize = 0; if (Priv->PhoneSMSMemory == AT_AVAILABLE) { smprintf(s, "Getting phone SMS status\n"); if (Priv->CanSaveSMS) { error = GSM_WaitFor (s, "AT+CPMS=\"ME\",\"ME\"\r", 18, 0x00, 4, ID_GetSMSStatus); } else { error = GSM_WaitFor (s, "AT+CPMS=\"ME\"\r", 13, 0x00, 4, ID_GetSMSStatus); } if (error!=ERR_NONE) return error; Priv->SMSMemory = MEM_ME; } return ERR_NONE; } GSM_Error ATGEN_ReplyGetIMEI(GSM_Protocol_Message msg, GSM_StateMachine *s) { CopyLineString(s->Phone.Data.IMEI, msg.Buffer, s->Phone.Data.Priv.ATGEN.Lines, 2); smprintf(s, "Received IMEI %s\n",s->Phone.Data.IMEI); return ERR_NONE; } GSM_Error ATGEN_GetIMEI (GSM_StateMachine *s) { if (s->Phone.Data.IMEI[0] != 0) return ERR_NONE; smprintf(s, "Getting IMEI\n"); return GSM_WaitFor (s, "AT+CGSN\r", 8, 0x00, 2, ID_GetIMEI); } GSM_Error ATGEN_ReplyAddSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { char *start; int i; if (s->Protocol.Data.AT.EditMode) { if (s->Phone.Data.Priv.ATGEN.ReplyState != AT_Reply_SMSEdit) { return ATGEN_HandleCMSError(s); } s->Protocol.Data.AT.EditMode = false; return ERR_NONE; } switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "SMS saved OK\n"); for(i=0;i<msg.Length;i++) { if (msg.Buffer[i] == 0x00) msg.Buffer[i] = 0x20; } start = strstr(msg.Buffer, "+CMGW: "); if (start == NULL) return ERR_UNKNOWN; s->Phone.Data.SaveSMSMessage->Location = atoi(start+7); smprintf(s, "Saved at location %i\n",s->Phone.Data.SaveSMSMessage->Location); return ERR_NONE; case AT_Reply_Error: smprintf(s, "Error\n"); return ERR_NOTSUPPORTED; case AT_Reply_CMSError: /* This error occurs in case that phone couldn't save SMS */ return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_MakeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *message, unsigned char *hexreq, int *current, int *length2) { GSM_Error error; int i, length; unsigned char req[1000], buffer[1000]; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_SMSC SMSC; error=ATGEN_GetSMSMode(s); if (error != ERR_NONE) return error; length = 0; *current = 0; switch (Priv->SMSMode) { case SMS_AT_PDU: if (message->PDU == SMS_Deliver) { smprintf(s, "SMS Deliver\n"); error=PHONE_EncodeSMSFrame(s,message,buffer,PHONE_SMSDeliver,&length,true); if (error != ERR_NONE) return error; length = length - PHONE_SMSDeliver.Text; for (i=0;i<buffer[PHONE_SMSDeliver.SMSCNumber]+1;i++) { req[(*current)++]=buffer[PHONE_SMSDeliver.SMSCNumber+i]; } req[(*current)++]=buffer[PHONE_SMSDeliver.firstbyte]; for (i=0;i<((buffer[PHONE_SMSDeliver.Number]+1)/2+1)+1;i++) { req[(*current)++]=buffer[PHONE_SMSDeliver.Number+i]; } req[(*current)++]=buffer[PHONE_SMSDeliver.TPPID]; req[(*current)++]=buffer[PHONE_SMSDeliver.TPDCS]; for(i=0;i<7;i++) req[(*current)++]=buffer[PHONE_SMSDeliver.DateTime+i]; req[(*current)++]=buffer[PHONE_SMSDeliver.TPUDL]; for(i=0;i<length;i++) req[(*current)++]=buffer[PHONE_SMSDeliver.Text+i]; EncodeHexBin(hexreq, req, *current); *length2 = *current * 2; *current = *current - (req[PHONE_SMSDeliver.SMSCNumber]+1); } else { smprintf(s, "SMS Submit\n"); error=PHONE_EncodeSMSFrame(s,message,buffer,PHONE_SMSSubmit,&length,true); if (error != ERR_NONE) return error; length = length - PHONE_SMSSubmit.Text; for (i=0;i<buffer[PHONE_SMSSubmit.SMSCNumber]+1;i++) { req[(*current)++]=buffer[PHONE_SMSSubmit.SMSCNumber+i]; } req[(*current)++]=buffer[PHONE_SMSSubmit.firstbyte]; req[(*current)++]=buffer[PHONE_SMSSubmit.TPMR]; for (i=0;i<((buffer[PHONE_SMSSubmit.Number]+1)/2+1)+1;i++) { req[(*current)++]=buffer[PHONE_SMSSubmit.Number+i]; } req[(*current)++]=buffer[PHONE_SMSSubmit.TPPID]; req[(*current)++]=buffer[PHONE_SMSSubmit.TPDCS]; req[(*current)++]=buffer[PHONE_SMSSubmit.TPVP]; req[(*current)++]=buffer[PHONE_SMSSubmit.TPUDL]; for(i=0;i<length;i++) req[(*current)++]=buffer[PHONE_SMSSubmit.Text+i]; EncodeHexBin(hexreq, req, *current); *length2 = *current * 2; *current = *current - (req[PHONE_SMSSubmit.SMSCNumber]+1); } break; case SMS_AT_TXT: if (Priv->Manufacturer == 0) { error=ATGEN_GetManufacturer(s); if (error != ERR_NONE) return error; } if (Priv->Manufacturer != AT_Nokia) { if (message->Coding != SMS_Coding_Default) return ERR_NOTSUPPORTED; } error=PHONE_EncodeSMSFrame(s,message,req,PHONE_SMSDeliver,&i,true); if (error != ERR_NONE) return error; CopyUnicodeString(SMSC.Number,message->SMSC.Number); SMSC.Location=1; error=ATGEN_SetSMSC(s,&SMSC); if (error!=ERR_NONE) return error; sprintf(buffer, "AT+CSMP=%i,%i,%i,%i\r", req[PHONE_SMSDeliver.firstbyte], req[PHONE_SMSDeliver.TPVP], req[PHONE_SMSDeliver.TPPID], req[PHONE_SMSDeliver.TPDCS]); error=GSM_WaitFor (s, buffer, strlen(buffer), 0x00, 4, ID_SetSMSParameters); if (error==ERR_NOTSUPPORTED) { /* Nokia Communicator 9000i doesn't support <vp> parameter */ sprintf(buffer, "AT+CSMP=%i,,%i,%i\r", req[PHONE_SMSDeliver.firstbyte], req[PHONE_SMSDeliver.TPPID], req[PHONE_SMSDeliver.TPDCS]); error=GSM_WaitFor (s, buffer, strlen(buffer), 0x00, 4, ID_SetSMSParameters); } if (error!=ERR_NONE) return error; switch (message->Coding) { case SMS_Coding_Default: /* If not SMS with UDH, it's as normal text */ if (message->UDH.Type==UDH_NoUDH) { strcpy(hexreq,DecodeUnicodeString(message->Text)); *length2 = UnicodeLength(message->Text); break; } case SMS_Coding_Unicode: case SMS_Coding_8bit: error=PHONE_EncodeSMSFrame(s,message,buffer,PHONE_SMSDeliver,current,true); if (error != ERR_NONE) return error; EncodeHexBin (hexreq, buffer+PHONE_SMSDeliver.Text, buffer[PHONE_SMSDeliver.TPUDL]); *length2 = buffer[PHONE_SMSDeliver.TPUDL] * 2; break; } break; } return ERR_NONE; } GSM_Error ATGEN_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { GSM_Error error, error2; int state,Replies,reply, current, current2; unsigned char buffer[1000], hexreq[1000]; GSM_Phone_Data *Phone = &s->Phone.Data; unsigned char *statetxt; /* This phone supports only sent/unsent messages on SIM */ if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMSONLYSENT)) { if (sms->Folder != 2) { smprintf(s, "This phone supports only folder = 2!\n"); return ERR_NOTSUPPORTED; } } sms->PDU = SMS_Submit; switch (sms->Folder) { case 1: sms->PDU = SMS_Deliver; /* Inbox SIM */ error=ATGEN_SetSMSMemory(s, true); break; case 2: error=ATGEN_SetSMSMemory(s, true); /* Outbox SIM */ break; case 3: sms->PDU = SMS_Deliver; error=ATGEN_SetSMSMemory(s, false); /* Inbox phone */ break; case 4: error=ATGEN_SetSMSMemory(s, false); /* Outbox phone */ break; default: return ERR_NOTSUPPORTED; } if (error!=ERR_NONE) return error; error = ATGEN_MakeSMSFrame(s, sms, hexreq, ¤t, ¤t2); if (error != ERR_NONE) return error; switch (Phone->Priv.ATGEN.SMSMode) { case SMS_AT_PDU: if (sms->PDU == SMS_Deliver) { state = 0; if (sms->State == SMS_Read || sms->State == SMS_Sent) state = 1; } else { state = 2; if (sms->State == SMS_Read || sms->State == SMS_Sent) state = 3; } /* Siemens M20 */ if (IsPhoneFeatureAvailable(Phone->ModelInfo, F_M20SMS)) { /* No (good and 100% working) support for alphanumeric numbers */ if (sms->Number[1]!='+' && (sms->Number[1]<'0' || sms->Number[1]>'9')) { EncodeUnicode(sms->Number,"123",3); error = ATGEN_MakeSMSFrame(s, sms, hexreq, ¤t, ¤t2); if (error != ERR_NONE) return error; } } sprintf(buffer, "AT+CMGW=%i,%i\r",current,state); break; case SMS_AT_TXT: if (sms->PDU == SMS_Deliver) { statetxt = "REC UNREAD"; if (sms->State == SMS_Read || sms->State == SMS_Sent) statetxt = "REC READ"; } else { statetxt = "STO UNSENT"; if (sms->State == SMS_Read || sms->State == SMS_Sent) statetxt = "STO SENT"; } /* Siemens M20 */ if (IsPhoneFeatureAvailable(Phone->ModelInfo, F_M20SMS)) { /* No (good and 100% working) support for alphanumeric numbers */ /* FIXME: Try to autodetect support for <stat> (statetxt) parameter although: * Siemens M20 supports +CMGW <stat> specification but on my model it just * reports ERROR (and <stat> is not respected). * Fortunately it will write "+CMGW: <index>\n" before and the message gets written */ if (sms->Number[1]!='+' && (sms->Number[1]<'0' || sms->Number[1]>'9')) { sprintf(buffer, "AT+CMGW=\"123\",,\"%s\"\r",statetxt); } else { sprintf(buffer, "AT+CMGW=\"%s\",,\"%s\"\r",DecodeUnicodeString(sms->Number),statetxt); } } else { sprintf(buffer, "AT+CMGW=\"%s\",,\"%s\"\r",DecodeUnicodeString(sms->Number),statetxt); } } Phone->SaveSMSMessage = sms; for (reply=0;reply<s->ReplyNum;reply++) { if (reply!=0) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { smprintf(s, "[Retrying %i]\n", reply+1); } } s->Protocol.Data.AT.EditMode = true; Replies = s->ReplyNum; s->ReplyNum = 1; smprintf(s,"Waiting for modem prompt\n"); error=GSM_WaitFor (s, buffer, strlen(buffer), 0x00, 3, ID_SaveSMSMessage); s->ReplyNum = Replies; if (error == ERR_NONE) { Phone->DispatchError = ERR_TIMEOUT; Phone->RequestID = ID_SaveSMSMessage; smprintf(s, "Saving SMS\n"); error = s->Protocol.Functions->WriteMessage(s, hexreq, current2, 0x00); if (error!=ERR_NONE) return error; my_sleep(500); /* CTRL+Z ends entering */ error = s->Protocol.Functions->WriteMessage(s, "\x1A", 1, 0x00); if (error!=ERR_NONE) return error; error = GSM_WaitForOnce(s, NULL, 0x00, 0x00, 4); if (error != ERR_TIMEOUT) return error; } else { smprintf(s, "Escaping SMS mode\n"); error2 = s->Protocol.Functions->WriteMessage(s, "\x1B\r", 2, 0x00); if (error2 != ERR_NONE) return error2; return error; } } return Phone->DispatchError; } GSM_Error ATGEN_ReplySendSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; char *start; if (s->Protocol.Data.AT.EditMode) { if (s->Phone.Data.Priv.ATGEN.ReplyState != AT_Reply_SMSEdit) { return ERR_UNKNOWN; } s->Protocol.Data.AT.EditMode = false; return ERR_NONE; } switch (Priv->ReplyState) { case AT_Reply_OK: smprintf(s, "SMS sent OK\n"); if (s->User.SendSMSStatus!=NULL) { start = strstr(msg.Buffer, "+CMGS: "); if (start != NULL) { s->User.SendSMSStatus(s->CurrentConfig->Device,0,atoi(start+7)); } else { s->User.SendSMSStatus(s->CurrentConfig->Device,0,-1); } } return ERR_NONE; case AT_Reply_CMSError: smprintf(s, "Error %i\n",Priv->ErrorCode); if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,Priv->ErrorCode,-1); return ATGEN_HandleCMSError(s); case AT_Reply_Error: return ERR_UNKNOWN; default: return ERR_UNKNOWNRESPONSE; } } GSM_Error ATGEN_SendSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { GSM_Error error,error2; int current, current2, Replies; unsigned char buffer[1000], hexreq[1000]; GSM_Phone_Data *Phone = &s->Phone.Data; if (sms->PDU == SMS_Deliver) sms->PDU = SMS_Submit; error = ATGEN_MakeSMSFrame(s, sms, hexreq, ¤t, ¤t2); if (error != ERR_NONE) return error; switch (Phone->Priv.ATGEN.SMSMode) { case SMS_AT_PDU: sprintf(buffer, "AT+CMGS=%i\r",current); break; case SMS_AT_TXT: sprintf(buffer, "AT+CMGS=\"%s\"\r",DecodeUnicodeString(sms->Number)); } s->Protocol.Data.AT.EditMode = true; Replies = s->ReplyNum; s->ReplyNum = 1; smprintf(s,"Waiting for modem prompt\n"); error=GSM_WaitFor (s, buffer, strlen(buffer), 0x00, 3, ID_IncomingFrame); s->ReplyNum = Replies; if (error == ERR_NONE) { smprintf(s, "Sending SMS\n"); error = s->Protocol.Functions->WriteMessage(s, hexreq, current2, 0x00); if (error!=ERR_NONE) return error; my_sleep(500); /* CTRL+Z ends entering */ error=s->Protocol.Functions->WriteMessage(s, "\x1A", 1, 0x00); my_sleep(100); return error; } else { smprintf(s, "Escaping SMS mode\n"); error2=s->Protocol.Functions->WriteMessage(s, "\x1B\r", 2, 0x00); if (error2 != ERR_NONE) return error2; } return error; } GSM_Error ATGEN_SendSavedSMS(GSM_StateMachine *s, int Folder, int Location) { GSM_Error error; int location; unsigned char smsfolder; unsigned char req[100]; GSM_MultiSMSMessage msms; msms.Number = 0; msms.SMS[0].Folder = Folder; msms.SMS[0].Location = Location; /* By reading SMS we check if it is really inbox/outbox */ error = ATGEN_GetSMS(s, &msms); if (error != ERR_NONE) return error; /* Can not send from other folder that outbox */ if (msms.SMS[0].Folder != 2 && msms.SMS[0].Folder != 4) return ERR_NOTSUPPORTED; error=ATGEN_GetSMSLocation(s, &msms.SMS[0], &smsfolder, &location); if (error != ERR_NONE) return error; sprintf(req, "AT+CMSS=%i\r",location); return s->Protocol.Functions->WriteMessage(s, req, strlen(req), 0x00); } GSM_Error ATGEN_ReplyGetDateTime_Alarm(GSM_Protocol_Message msg, GSM_StateMachine *s) { int current = 19; GSM_Phone_Data *Data = &s->Phone.Data; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: if (msg.Buffer[current]==0x0d || msg.Buffer[current-1]==0x0d) { smprintf(s, "Not set in phone\n"); return ERR_EMPTY; } else { if (Data->RequestID == ID_GetDateTime) { ATGEN_DecodeDateTime(Data->DateTime, msg.Buffer+current); } else { ATGEN_DecodeDateTime(&(Data->Alarm->DateTime), msg.Buffer+current); } return ERR_NONE; } case AT_Reply_Error: return ERR_NOTSUPPORTED; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { s->Phone.Data.DateTime=date_time; smprintf(s, "Getting date & time\n"); return GSM_WaitFor (s, "AT+CCLK?\r", 9, 0x00, 4, ID_GetDateTime); } GSM_Error ATGEN_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { char req[128]; sprintf(req, "AT+CCLK=\"%02i/%02i/%02i,%02i:%02i:%02i+00\"\r", date_time->Year-2000,date_time->Month,date_time->Day, date_time->Hour,date_time->Minute,date_time->Second); smprintf(s, "Setting date & time\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_SetDateTime); } GSM_Error ATGEN_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) { if (alarm->Location != 1) return ERR_NOTSUPPORTED; alarm->Repeating = true; alarm->Text[0] = 0; alarm->Text[1] = 0; s->Phone.Data.Alarm = alarm; smprintf(s, "Getting alarm\n"); return GSM_WaitFor (s, "AT+CALA?\r", 9, 0x00, 4, ID_GetAlarm); } /* R320 only takes HH:MM. Do other phones understand full date? */ GSM_Error ATGEN_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) { char req[20]; if (alarm->Location != 1) return ERR_INVALIDLOCATION; sprintf(req, "AT+CALA=\"%02i:%02i\"\r",alarm->DateTime.Hour,alarm->DateTime.Minute); smprintf(s, "Setting Alarm\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetAlarm); } GSM_Error ATGEN_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_SMSC *SMSC = s->Phone.Data.SMSC; int current; int len; unsigned char buffer[100]; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "SMSC info received\n"); current = 0; while (msg.Buffer[current]!='"') current++; /* SMSC number */ /* FIXME: support for all formats */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); /* * Some phones return this as unicode encoded when they are * switched to UCS2 mode, so we try to solve this correctly. */ len = strlen(buffer + 1) - 1; buffer[len + 1] = 0; if ((len > 20) && (len % 4 == 0) && (strchr(buffer + 1, '+') == NULL)) { /* This is probably unicode encoded number */ DecodeHexUnicode(SMSC->Number,buffer + 1,len); } else { EncodeUnicode(SMSC->Number,buffer + 1,len); } smprintf(s, "Number: \"%s\"\n",DecodeUnicodeString(SMSC->Number)); /* Format of SMSC number */ current+=ATGEN_ExtractOneParameter(msg.Buffer+current, buffer); smprintf(s, "Format %s\n",buffer); /* International number */ if (!strcmp(buffer,"145")) { sprintf(buffer+1,"%s",DecodeUnicodeString(SMSC->Number)); if (strlen(buffer+1)!=0 && buffer[1] != '+') { /* Sony Ericsson issue */ /* International number is without + */ buffer[0] = '+'; EncodeUnicode(SMSC->Number,buffer,strlen(buffer)); } } SMSC->Format = SMS_FORMAT_Text; SMSC->Validity.Format = SMS_Validity_RelativeFormat; SMSC->Validity.Relative = SMS_VALID_Max_Time; SMSC->Name[0] = 0; SMSC->Name[1] = 0; SMSC->DefaultNumber[0] = 0; SMSC->DefaultNumber[1] = 0; return ERR_NONE; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) { if (smsc->Location==0x00 || smsc->Location!=0x01) return ERR_INVALIDLOCATION; s->Phone.Data.SMSC=smsc; smprintf(s, "Getting SMSC\n"); return GSM_WaitFor (s, "AT+CSCA?\r", 9, 0x00, 4, ID_GetSMSC); } GSM_Error ATGEN_ReplyGetNetworkLAC_CID(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_NetworkInfo *NetworkInfo = s->Phone.Data.NetworkInfo; GSM_Lines Lines; int i=0; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; char *answer; if (s->Phone.Data.RequestID == ID_IncomingFrame) { smprintf(s, "Incoming LAC & CID info\n"); return ERR_NONE; } switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: break; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: return ERR_UNKNOWNRESPONSE; } SplitLines(GetLineString(msg.Buffer,Priv->Lines,2), strlen(GetLineString(msg.Buffer,Priv->Lines,2)), &Lines, ",", 1, true); /* Find number of lines */ while (Lines.numbers[i*2+1] != 0) { /* FIXME: handle special chars correctly */ smprintf(s, "%i \"%s\"\n",i+1,GetLineString(GetLineString(msg.Buffer,Priv->Lines,2),Lines,i+1)); i++; } smprintf(s, "Network LAC & CID & state received\n"); answer = GetLineString(GetLineString(msg.Buffer,Priv->Lines,2),Lines,2); while (*answer == 0x20) answer++; #ifdef DEBUG switch (answer[0]) { case '0': smprintf(s, "Not registered into any network. Not searching for network\n"); break; case '1': smprintf(s, "Home network\n"); break; case '2': smprintf(s, "Not registered into any network. Searching for network\n"); break; case '3': smprintf(s, "Registration denied\n"); break; case '4': smprintf(s, "Unknown\n"); break; case '5': smprintf(s, "Registered in roaming network\n"); break; default : smprintf(s, "Unknown\n"); } #endif switch (answer[0]) { case '0': NetworkInfo->State = GSM_NoNetwork; break; case '1': NetworkInfo->State = GSM_HomeNetwork; break; case '2': NetworkInfo->State = GSM_RequestingNetwork; break; case '3': NetworkInfo->State = GSM_RegistrationDenied; break; case '4': NetworkInfo->State = GSM_NetworkStatusUnknown;break; case '5': NetworkInfo->State = GSM_RoamingNetwork; break; default : NetworkInfo->State = GSM_NetworkStatusUnknown;break; } if (NetworkInfo->State == GSM_HomeNetwork || NetworkInfo->State == GSM_RoamingNetwork) { memset(NetworkInfo->CID,0,4); memset(NetworkInfo->LAC,0,4); if (Lines.numbers[3*2+1]==0) return ERR_NONE; answer = GetLineString(GetLineString(msg.Buffer,Priv->Lines,2),Lines,3); while (*answer == 0x20) answer++; sprintf(NetworkInfo->CID, "%c%c%c%c", answer[1], answer[2], answer[3], answer[4]); answer = GetLineString(GetLineString(msg.Buffer,Priv->Lines,2),Lines,4); while (*answer == 0x20) answer++; sprintf(NetworkInfo->LAC, "%c%c%c%c", answer[1], answer[2], answer[3], answer[4]); smprintf(s, "CID : %s\n",NetworkInfo->CID); smprintf(s, "LAC : %s\n",NetworkInfo->LAC); } return ERR_NONE; } GSM_Error ATGEN_ReplyGetNetworkCode(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_NetworkInfo *NetworkInfo = s->Phone.Data.NetworkInfo; switch (Priv->ReplyState) { case AT_Reply_OK: smprintf(s, "Network code received\n"); if (Priv->Manufacturer == AT_Falcom) { NetworkInfo->NetworkCode[0] = msg.Buffer[22]; NetworkInfo->NetworkCode[1] = msg.Buffer[23]; NetworkInfo->NetworkCode[2] = msg.Buffer[24]; NetworkInfo->NetworkCode[3] = ' '; NetworkInfo->NetworkCode[4] = msg.Buffer[25]; NetworkInfo->NetworkCode[5] = msg.Buffer[26]; } else { NetworkInfo->NetworkCode[0] = msg.Buffer[23]; NetworkInfo->NetworkCode[1] = msg.Buffer[24]; NetworkInfo->NetworkCode[2] = msg.Buffer[25]; NetworkInfo->NetworkCode[3] = ' '; NetworkInfo->NetworkCode[4] = msg.Buffer[26]; NetworkInfo->NetworkCode[5] = msg.Buffer[27]; } NetworkInfo->NetworkCode[6] = 0; smprintf(s, " Network code : %s\n", NetworkInfo->NetworkCode); smprintf(s, " Network name for Gammu : %s ", DecodeUnicodeString(GSM_GetNetworkName(NetworkInfo->NetworkCode))); smprintf(s, "(%s)\n",DecodeUnicodeString(GSM_GetCountryName(NetworkInfo->NetworkCode))); return ERR_NONE; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo) { GSM_Error error; s->Phone.Data.NetworkInfo=netinfo; netinfo->NetworkName[0] = 0; netinfo->NetworkName[1] = 0; netinfo->NetworkCode[0] = 0; smprintf(s, "Enable full network info\n"); error=GSM_WaitFor(s, "AT+CREG=2\r", 10, 0x00, 4, ID_GetNetworkInfo); if ((error != ERR_NONE) && (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) && (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Ericsson)) return error; smprintf(s, "Getting network LAC and CID and state\n"); error=GSM_WaitFor(s, "AT+CREG?\r", 9, 0x00, 4, ID_GetNetworkInfo); if (error != ERR_NONE) return error; if (netinfo->State == GSM_HomeNetwork || netinfo->State == GSM_RoamingNetwork) { smprintf(s, "Setting short network name format\n"); error=GSM_WaitFor(s, "AT+COPS=3,2\r", 12, 0x00, 4, ID_GetNetworkInfo); error=ATGEN_GetManufacturer(s); if (error != ERR_NONE) return error; smprintf(s, "Getting network code\n"); error=GSM_WaitFor(s, "AT+COPS?\r", 9, 0x00, 4, ID_GetNetworkInfo); } return error; } GSM_Error ATGEN_ReplyGetPBKMemories(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "PBK memories received\n"); if (strlen(msg.Buffer) > AT_PBK_MAX_MEMORIES) { smprintf(s, "ERROR: Too long phonebook memories information received! (Recevided %d, AT_PBK_MAX_MEMORIES is %d\n", strlen(msg.Buffer), AT_PBK_MAX_MEMORIES); return ERR_MOREMEMORY; } memcpy(s->Phone.Data.Priv.ATGEN.PBKMemories,msg.Buffer,strlen(msg.Buffer)); return ERR_NONE; } GSM_Error ATGEN_SetPBKMemory(GSM_StateMachine *s, GSM_MemoryType MemType) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; char req[] = "AT+CPBS=\"XX\"\r"; GSM_Error error; if (Priv->PBKMemory == MemType) return ERR_NONE; /* Zero values that are for actual memory */ Priv->MemorySize = 0; Priv->FirstMemoryEntry = 0; Priv->NextMemoryEntry = 0; Priv->TextLength = 0; Priv->NumberLength = 0; if (Priv->PBKMemories[0] == 0) { error=GSM_WaitFor (s, "AT+CPBS=?\r", 10, 0x00, 3, ID_SetMemoryType); if (error != ERR_NONE) return error; } switch (MemType) { case MEM_SM: req[9] = 'S'; req[10] = 'M'; break; case MEM_ME: if (strstr(Priv->PBKMemories,"ME")==NULL) return ERR_NOTSUPPORTED; req[9] = 'M'; req[10] = 'E'; break; case MEM_RC: if (strstr(Priv->PBKMemories,"RC")==NULL) return ERR_NOTSUPPORTED; req[9] = 'R'; req[10] = 'C'; break; case MEM_MC: if (strstr(Priv->PBKMemories,"MC")==NULL) return ERR_NOTSUPPORTED; req[9] = 'M'; req[10] = 'C'; break; case MEM_ON: if (strstr(Priv->PBKMemories,"ON")==NULL) return ERR_NOTSUPPORTED; req[9] = 'O'; req[10] = 'N'; break; case MEM_FD: if (strstr(Priv->PBKMemories,"FD")==NULL) return ERR_NOTSUPPORTED; req[9] = 'F'; req[10] = 'D'; break; case MEM_DC: if (strstr(Priv->PBKMemories,"DC")!=NULL) { req[9] = 'D'; req[10] = 'C'; break; } if (strstr(Priv->PBKMemories,"LD")!=NULL) { req[9] = 'L'; req[10] = 'D'; break; } return ERR_NOTSUPPORTED; break; default: return ERR_NOTSUPPORTED; } smprintf(s, "Setting memory type\n"); error=GSM_WaitFor (s, req, 13, 0x00, 3, ID_SetMemoryType); if (error == ERR_NONE) Priv->PBKMemory = MemType; return error; } GSM_Error ATGEN_ReplyGetCPBSMemoryStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_MemoryStatus *MemoryStatus = s->Phone.Data.MemoryStatus; char *start; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Memory status received\n"); MemoryStatus->MemoryUsed = 0; MemoryStatus->MemoryFree = 0; start = strchr(msg.Buffer, ','); if (start) { start++; MemoryStatus->MemoryUsed = atoi(start); start = strchr(start, ','); if (start) { start++; MemoryStatus->MemoryFree = atoi(start) - MemoryStatus->MemoryUsed; return ERR_NONE; } else return ERR_UNKNOWN; } else return ERR_UNKNOWN; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_ReplyGetCPBRMemoryInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; char *pos; switch (Priv->ReplyState) { case AT_Reply_OK: smprintf(s, "Memory info received\n"); /* Parse +CPBR: (first-last),max_number_len,max_name_len */ /* Parse first location */ pos = strchr(msg.Buffer, '('); if (!pos) return ERR_UNKNOWN; pos++; Priv->FirstMemoryEntry = atoi(pos); /* Parse last location*/ pos = strchr(pos, '-'); if (!pos) return ERR_UNKNOWN; pos++; Priv->MemorySize = atoi(pos) + 1 - Priv->FirstMemoryEntry; /* Parse number length*/ pos = strchr(pos, ','); if (!pos) return ERR_UNKNOWN; pos++; Priv->NumberLength = atoi(pos); /* Parse text length*/ pos = strchr(pos, ','); if (!pos) return ERR_UNKNOWN; pos++; Priv->TextLength = atoi(pos); return ERR_NONE; case AT_Reply_Error: return ERR_UNKNOWN; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: return ERR_UNKNOWNRESPONSE; } } GSM_Error ATGEN_ReplyGetCPBRMemoryStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_MemoryStatus *MemoryStatus = s->Phone.Data.MemoryStatus; int line=0; char *str; int cur; switch (Priv->ReplyState) { case AT_Reply_OK: smprintf(s, "Memory entries received\n"); @@ -2306,1557 +2306,1563 @@ GSM_Error ATGEN_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status) if (error != ERR_NONE) return error; s->Phone.Data.MemoryStatus=Status; /* in some phones doesn't work or doesn't return memory status inside */ /* Some workaround for buggy mobile, that hangs after "AT+CPBS?" for other * memory than SM. */ if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_BROKENCPBS) || (Status->MemoryType == MEM_SM)) { smprintf(s, "Getting memory status\n"); error=GSM_WaitFor (s, "AT+CPBS?\r", 9, 0x00, 4, ID_GetMemoryStatus); if (error == ERR_NONE) return ERR_NONE; } return ATGEN_GetMemoryInfo(s, Status, AT_Status); } GSM_Error ATGEN_SetPBKCharset(GSM_StateMachine *s, bool PreferUnicode) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; /* Have we already selected something? */ if (Priv->PBKCharset!=0) { /* If we want unicode charset and we have it already or setting of it * failed, we have nothing to do. */ if (PreferUnicode && (Priv->PBKCharset==AT_PBK_UCS2 || Priv->UCS2CharsetFailed)) return ERR_NONE; /* If we don't need unicode charset and we have some (or have unicode * charset when other failed), we have nothing to do. */ if (!PreferUnicode && (Priv->PBKCharset!=AT_PBK_UCS2 || Priv->NonUCS2CharsetFailed)) return ERR_NONE; } error=ATGEN_GetManufacturer(s); if (error != ERR_NONE) return error; /* Samsung (and Sagem?) phones use only PCCP437? */ if (Priv->Manufacturer == AT_Samsung) { Priv->PBKCharset = AT_PBK_PCCP437; return ERR_NONE; } if (PreferUnicode && !Priv->UCS2CharsetFailed) { smprintf(s, "Setting charset to UCS2\n"); error=GSM_WaitFor (s, "AT+CSCS=\"UCS2\"\r", 15, 0x00, 3, ID_SetMemoryCharset); if (error == ERR_NONE) { Priv->PBKCharset = AT_PBK_UCS2; return ERR_NONE; } else { Priv->UCS2CharsetFailed = true; } } smprintf(s, "Setting charset to HEX\n"); error=GSM_WaitFor (s, "AT+CSCS=\"HEX\"\r", 14, 0x00, 3, ID_SetMemoryCharset); /* Falcom replies OK for HEX mode and send everything * in normal format */ if (error == ERR_NONE && Priv->Manufacturer != AT_Falcom) { Priv->PBKCharset = AT_PBK_HEX; return ERR_NONE; } smprintf(s, "Setting charset to GSM\n"); error=GSM_WaitFor (s, "AT+CSCS=\"GSM\"\r", 14, 0x00, 3, ID_SetMemoryCharset); if (error == ERR_NONE) { Priv->PBKCharset = AT_PBK_GSM; return ERR_NONE; } if (!Priv->UCS2CharsetFailed) { Priv->NonUCS2CharsetFailed = true; smprintf(s, "Setting charset to UCS2\n"); error=GSM_WaitFor (s, "AT+CSCS=\"UCS2\"\r", 15, 0x00, 3, ID_SetMemoryCharset); if (error == ERR_NONE) { Priv->PBKCharset = AT_PBK_UCS2; return ERR_NONE; } else { Priv->UCS2CharsetFailed = true; } } return error; } GSM_Error ATGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_MemoryEntry *Memory = s->Phone.Data.Memory; char *pos; unsigned char buffer[500],buffer2[500]; int len; switch (Priv->ReplyState) { case AT_Reply_OK: smprintf(s, "Phonebook entry received\n"); Memory->EntriesNum = 0; if (Priv->Lines.numbers[4]==0) return ERR_EMPTY; pos = strstr(msg.Buffer, "+CPBR:"); if (pos == NULL) return ERR_UNKNOWN; /* Go after +CPBR: */ pos += 6; /* Location */ while (*pos && !isdigit(*pos)) pos++; Memory->Location = atoi(pos) + 1 - Priv->FirstMemoryEntry; smprintf(s, "Location: %d\n", Memory->Location); /* Number */ while (*pos != '"') pos++; pos += ATGEN_ExtractOneParameter(pos, buffer); smprintf(s, "Number: %s\n",buffer); Memory->EntriesNum++; Memory->Entries[0].EntryType = PBK_Number_General; Memory->Entries[0].VoiceTag = 0; Memory->Entries[0].SMSList[0] = 0; len = strlen(buffer + 1) - 1; if (Priv->PBKCharset == AT_PBK_HEX && (len > 10) && (len % 2 == 0) && (strchr(buffer + 1, '+') == NULL)) { /* This is probably hex encoded number */ DecodeHexBin(buffer2, buffer+1, len); DecodeDefault(Memory->Entries[0].Text ,buffer2, strlen(buffer2), false, NULL); } else if (Priv->PBKCharset == AT_PBK_UCS2 && (len > 20) && (len % 4 == 0) && (strchr(buffer + 1, '+') == NULL)) { /* This is probably unicode encoded number */ DecodeHexUnicode(Memory->Entries[0].Text, buffer + 1,len); } else { EncodeUnicode(Memory->Entries[0].Text, buffer + 1, len); } /* Number format */ pos += ATGEN_ExtractOneParameter(pos, buffer); smprintf(s, "Number format: %s\n",buffer); /* International number */ if (!strcmp(buffer,"145")) { sprintf(buffer+1,"%s",DecodeUnicodeString(Memory->Entries[0].Text)); if (strlen(buffer+1)!=0 && buffer[1] != '+') { /* Sony Ericsson issue */ /* International number is without + */ buffer[0] = '+'; EncodeUnicode(Memory->Entries[0].Text,buffer,strlen(buffer)); } } /* Name */ pos += ATGEN_ExtractOneParameter(pos, buffer); smprintf(s, "Name text: %s\n",buffer); Memory->EntriesNum++; Memory->Entries[1].EntryType=PBK_Text_Name; switch (Priv->PBKCharset) { case AT_PBK_HEX: DecodeHexBin(buffer2,buffer+1,strlen(buffer)-2); DecodeDefault(Memory->Entries[1].Text,buffer2,strlen(buffer2),false,NULL); break; case AT_PBK_GSM: DecodeDefault(Memory->Entries[1].Text,buffer+1,strlen(buffer)-2,false,NULL); break; case AT_PBK_UCS2: DecodeHexUnicode(Memory->Entries[1].Text,buffer+1,strlen(buffer+1) - 1); break; case AT_PBK_PCCP437: /* FIXME: correctly decode PCCP437 */ DecodeDefault(Memory->Entries[1].Text,buffer+1,strlen(buffer)-2,false,NULL); break; } /* Samsung number type */ if (Priv->Manufacturer == AT_Samsung) { int type; pos += ATGEN_ExtractOneParameter(pos, buffer); smprintf(s, "Number type: %s\n",buffer); type = strtoul(buffer, NULL, 0); switch (type) { case 0: Memory->Entries[0].EntryType = PBK_Number_Mobile; break; case 1: Memory->Entries[0].EntryType = PBK_Number_Work; break; case 2: Memory->Entries[0].EntryType = PBK_Number_Home; break; case 3: Memory->Entries[0].EntryType = PBK_Text_Email; break; default: Memory->Entries[0].EntryType = PBK_Number_General; } } return ERR_NONE; case AT_Reply_CMEError: return ATGEN_HandleCMEError(s); case AT_Reply_Error: smprintf(s, "Error - too high location ?\n"); return ERR_INVALIDLOCATION; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_PrivGetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry, int endlocation) { GSM_Error error; unsigned char req[20]; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (entry->Location==0x00) return ERR_INVALIDLOCATION; if (entry->MemoryType == MEM_ME) { if (Priv->PBKSBNR == 0) { sprintf(req, "AT^SBNR=?\r"); smprintf(s, "Checking availablity of SBNR\n"); error=GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetMemory); switch (error) { case ERR_NONE: Priv->PBKSBNR = AT_SBNR_AVAILABLE; break; case ERR_UNKNOWN: case ERR_NOTSUPPORTED: Priv->PBKSBNR = AT_SBNR_NOTAVAILABLE; break; default: return error; } } if (Priv->PBKSBNR == AT_SBNR_AVAILABLE) { sprintf(req, "AT^SBNR=vcf,%i\r",entry->Location-1); s->Phone.Data.Memory=entry; smprintf(s, "Getting phonebook entry\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetMemory); } } error=ATGEN_GetManufacturer(s); if (error != ERR_NONE) return error; error=ATGEN_SetPBKMemory(s, entry->MemoryType); if (error != ERR_NONE) return error; if (Priv->FirstMemoryEntry == 0) { error = ATGEN_GetMemoryInfo(s, NULL, AT_First); if (error != ERR_NONE) return error; } error=ATGEN_SetPBKCharset(s, true); /* For reading we prefer unicode */ if (error != ERR_NONE) return error; if (endlocation == 0) { sprintf(req, "AT+CPBR=%i\r", entry->Location + Priv->FirstMemoryEntry - 1); } else { sprintf(req, "AT+CPBR=%i,%i\r", entry->Location + Priv->FirstMemoryEntry - 1, endlocation + Priv->FirstMemoryEntry - 1); } s->Phone.Data.Memory=entry; smprintf(s, "Getting phonebook entry\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetMemory); } GSM_Error ATGEN_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry) { return ATGEN_PrivGetMemory(s, entry, 0); } GSM_Error ATGEN_GetNextMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry, bool start) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; int step = 0; if (Priv->MemorySize == 0) { error = ATGEN_GetMemoryInfo(s, NULL, AT_Total); if (error != ERR_NONE) return error; } if (start) { entry->Location = 1; } else { entry->Location++; } while ((error = ATGEN_PrivGetMemory(s, entry, step == 0 ? 0 : MIN(Priv->MemorySize, entry->Location + step))) == ERR_EMPTY) { entry->Location += step + 1; if (entry->Location > Priv->MemorySize) break; /* SNBR works only for one location */ if (entry->MemoryType != MEM_ME || Priv->PBKSBNR != AT_SBNR_AVAILABLE) step = MIN(step + 2, 20); } if (error == ERR_INVALIDLOCATION) return ERR_EMPTY; return error; } GSM_Error ATGEN_DeleteAllMemory(GSM_StateMachine *s, GSM_MemoryType type) { GSM_Error error; unsigned char req[100]; int i; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; error = ATGEN_SetPBKMemory(s, type); if (error != ERR_NONE) return error; if (Priv->MemorySize == 0) { error = ATGEN_GetMemoryInfo(s, NULL, AT_Total); if (error != ERR_NONE) return error; } if (Priv->FirstMemoryEntry == 0) { error = ATGEN_GetMemoryInfo(s, NULL, AT_First); if (error != ERR_NONE) return error; } smprintf(s, "Deleting all phonebook entries\n"); for (i = Priv->FirstMemoryEntry; i < Priv->FirstMemoryEntry + Priv->MemorySize; i++) { sprintf(req, "AT+CPBW=%d\r",i); error = GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_SetMemory); if (error != ERR_NONE) return error; } return ERR_NONE; } GSM_Error ATGEN_ReplyDialVoice(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Dial voice OK\n"); return ERR_NONE; case AT_Reply_Error: smprintf(s, "Dial voice error\n"); return ERR_UNKNOWN; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber) { char req[39] = "ATDT"; if (ShowNumber != GSM_CALL_DefaultNumberPresence) return ERR_NOTSUPPORTED; if (strlen(number) > 32) return (ERR_UNKNOWN); strcat(req, number); strcat(req, ";\r"); smprintf(s, "Making voice call\n"); return GSM_WaitFor (s, req, 4+2+strlen(number), 0x00, 5, ID_DialVoice); } GSM_Error ATGEN_ReplyEnterSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Security code was OK\n"); return ERR_NONE; case AT_Reply_Error: smprintf(s, "Incorrect security code\n"); return ERR_SECURITYERROR; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); case AT_Reply_CMEError: return ATGEN_HandleCMEError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode Code) { unsigned char req[50]; switch (Code.Type) { case SEC_Pin : sprintf(req, "AT+CPIN=\"%s\"\r" , Code.Code); break; case SEC_Pin2 : if (s->Phone.Data.Priv.ATGEN.Manufacturer == AT_Siemens) { sprintf(req, "AT+CPIN2=\"%s\"\r", Code.Code); } else { sprintf(req, "AT+CPIN=\"%s\"\r" , Code.Code); } break; default : return ERR_NOTIMPLEMENTED; } smprintf(s, "Entering security code\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 6, ID_EnterSecurityCode); } GSM_Error ATGEN_ReplyGetSecurityStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_SecurityCodeType *Status = s->Phone.Data.SecurityStatus; smprintf(s, "Security status received - "); if (strstr(msg.Buffer,"READY")) { *Status = SEC_None; smprintf(s, "nothing to enter\n"); return ERR_NONE; } if (strstr(msg.Buffer,"PH_SIM PIN")) { smprintf(s, "no SIM inside or other error\n"); return ERR_UNKNOWN; } if (strstr(msg.Buffer,"SIM PIN2")) { *Status = SEC_Pin2; smprintf(s, "waiting for PIN2\n"); return ERR_NONE; } if (strstr(msg.Buffer,"SIM PUK2")) { *Status = SEC_Puk2; smprintf(s, "waiting for PUK2\n"); return ERR_NONE; } if (strstr(msg.Buffer,"SIM PIN")) { *Status = SEC_Pin; smprintf(s, "waiting for PIN\n"); return ERR_NONE; } if (strstr(msg.Buffer,"SIM PUK")) { *Status = SEC_Puk; smprintf(s, "waiting for PUK\n"); return ERR_NONE; } smprintf(s, "unknown\n"); return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status) { s->Phone.Data.SecurityStatus=Status; smprintf(s, "Getting security code status\n"); /* Please note, that A2D doesn't return OK on the end. * Because of it ReplyGetSecurityStatus is called after receiving line * with +CPIN: */ return GSM_WaitFor (s, "AT+CPIN?\r", 9, 0x00, 4, ID_GetSecurityStatus); } GSM_Error ATGEN_AnswerCall(GSM_StateMachine *s, int ID, bool all) { if (all) { smprintf(s, "Answering all calls\n"); return GSM_WaitFor (s, "ATA\r", 4, 0x00, 4, ID_AnswerCall); } return ERR_NOTSUPPORTED; } GSM_Error ATGEN_ReplyCancelCall(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Call call; switch(s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Calls canceled\n"); call.CallIDAvailable = false; call.Status = GSM_CALL_CallLocalEnd; if (s->User.IncomingCall) s->User.IncomingCall(s->CurrentConfig->Device, call); return ERR_NONE; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: return ERR_UNKNOWN; } } GSM_Error ATGEN_CancelCall(GSM_StateMachine *s, int ID, bool all) { GSM_Error error; if (all) { smprintf(s, "Dropping all calls\n"); error = GSM_WaitFor (s, "ATH\r", 4, 0x00, 4, ID_CancelCall); if (error == ERR_UNKNOWN) { return GSM_WaitFor (s, "AT+CHUP\r", 8, 0x00, 4, ID_CancelCall); } return error; } return ERR_NOTSUPPORTED; } GSM_Error ATGEN_ReplyReset(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Reset done\n"); return ERR_NONE; } GSM_Error ATGEN_Reset(GSM_StateMachine *s, bool hard) { GSM_Error error; if (!hard) return ERR_NOTSUPPORTED; smprintf(s, "Resetting device\n"); /* Siemens 35 */ error=GSM_WaitFor (s, "AT+CFUN=1,1\r", 12, 0x00, 8, ID_Reset); if (error != ERR_NONE) { /* Siemens M20 */ error=GSM_WaitFor (s, "AT^SRESET\r", 10, 0x00, 8, ID_Reset); } return error; } GSM_Error ATGEN_ReplyResetPhoneSettings(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Reset done\n"); return ERR_NONE; } GSM_Error ATGEN_ResetPhoneSettings(GSM_StateMachine *s, GSM_ResetSettingsType Type) { smprintf(s, "Resetting settings to default\n"); return GSM_WaitFor (s, "AT&F\r", 5, 0x00, 4, ID_ResetPhoneSettings); } GSM_Error ATGEN_SetAutoNetworkLogin(GSM_StateMachine *s) { smprintf(s, "Enabling automatic network login\n"); return GSM_WaitFor (s, "AT+COPS=0\r", 10, 0x00, 4, ID_SetAutoNetworkLogin); } GSM_Error ATGEN_SendDTMF(GSM_StateMachine *s, char *sequence) { unsigned char req[80] = "AT+VTS="; int n; for (n = 0; n < 32; n++) { if (sequence[n] == '\0') break; if (n != 0) req[6 + 2 * n] = ','; req[7 + 2 * n] = sequence[n]; } strcat(req, ";\r"); smprintf(s, "Sending DTMF\n"); return GSM_WaitFor (s, req, 7+2+2*strlen(sequence), 0x00, 4, ID_SendDTMF); } GSM_Error ATGEN_ReplyDeleteSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "SMS deleted OK\n"); return ERR_NONE; case AT_Reply_Error: smprintf(s, "Invalid location\n"); return ERR_INVALIDLOCATION; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_DeleteSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { unsigned char req[20], folderid; GSM_Error error; int location; GSM_MultiSMSMessage msms; msms.Number = 0; msms.SMS[0] = *sms; /* By reading SMS we check if it is really inbox/outbox */ error = ATGEN_GetSMS(s, &msms); if (error != ERR_NONE) return error; error = ATGEN_GetSMSLocation(s, sms, &folderid, &location); if (error != ERR_NONE) return error; sprintf(req, "AT+CMGD=%i\r",location); smprintf(s, "Deleting SMS\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 5, ID_DeleteSMSMessage); } GSM_Error ATGEN_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; int used = 0; if (Priv->PhoneSMSMemory == 0) { error = ATGEN_SetSMSMemory(s, false); if (error != ERR_NONE && error != ERR_NOTSUPPORTED) return error; } if (Priv->SIMSMSMemory == 0) { error = ATGEN_SetSMSMemory(s, true); if (error != ERR_NONE && error != ERR_NOTSUPPORTED) return error; } folders->Number = 0; if (Priv->PhoneSMSMemory == AT_NOTAVAILABLE && Priv->SIMSMSMemory == AT_NOTAVAILABLE) { return ERR_NONE; } PHONE_GetSMSFolders(s,folders); if (Priv->SIMSMSMemory == AT_AVAILABLE) { used = 2; } if (Priv->PhoneSMSMemory == AT_AVAILABLE) { if (used != 0) { CopyUnicodeString(folders->Folder[used ].Name,folders->Folder[0].Name); CopyUnicodeString(folders->Folder[used + 1].Name,folders->Folder[1].Name); folders->Folder[used ].InboxFolder = true; folders->Folder[used + 1].InboxFolder = false; } folders->Folder[used ].Memory = MEM_ME; folders->Folder[used + 1].Memory = MEM_ME; folders->Number += 2; used += 2; } return ERR_NONE; } GSM_Error ATGEN_ReplySetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Phonebook entry written OK\n"); return ERR_NONE; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); case AT_Reply_CMEError: return ATGEN_HandleCMEError(s); case AT_Reply_Error: return ERR_INVALIDDATA; default: return ERR_UNKNOWNRESPONSE; } } GSM_Error ATGEN_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { GSM_Error error; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char req[100]; if (entry->Location < 1) return ERR_INVALIDLOCATION; error = ATGEN_SetPBKMemory(s, entry->MemoryType); if (error != ERR_NONE) return error; if (Priv->FirstMemoryEntry == 0) { error = ATGEN_GetMemoryInfo(s, NULL, AT_First); if (error != ERR_NONE) return error; } sprintf(req, "AT+CPBW=%d\r",entry->Location + Priv->FirstMemoryEntry - 1); smprintf(s, "Deleting phonebook entry\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_SetMemory); } GSM_Error ATGEN_PrivSetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { /* REQUEST_SIZE should be big enough to handle all possibl cases * correctly, especially with unicode entries */ #define REQUEST_SIZE ((4 * GSM_PHONEBOOK_TEXT_LENGTH) + 30) GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; int Group, Name, Number,NumberType=0, len; GSM_Error error; unsigned char req[REQUEST_SIZE + 1]; unsigned char name[2*(GSM_PHONEBOOK_TEXT_LENGTH + 1)]; unsigned char uname[2*(GSM_PHONEBOOK_TEXT_LENGTH + 1)]; unsigned char number[GSM_PHONEBOOK_TEXT_LENGTH + 1]; int reqlen; bool PreferUnicode = false; if (entry->Location == 0) return ERR_INVALIDLOCATION; error = ATGEN_SetPBKMemory(s, entry->MemoryType); if (error != ERR_NONE) return error; GSM_PhonebookFindDefaultNameNumberGroup(entry, &Name, &Number, &Group); name[0] = 0; if (Name != -1) { len = UnicodeLength(entry->Entries[Name].Text); /* Compare if we would loose some information when not using * unicode */ EncodeDefault(name, entry->Entries[Name].Text, &len, true, NULL); DecodeDefault(uname, name, len, true, NULL); if (!mywstrncmp(uname, entry->Entries[Name].Text, len)) { /* Get maximal text length */ if (Priv->TextLength == 0) { ATGEN_GetMemoryInfo(s, NULL, AT_Sizes); } /* I char stored in GSM alphabet takes 7 bits, one * unicode 16, if storing in unicode would truncate * text, do not use it, otherwise we will use it */ if ((Priv->TextLength != 0) && ((Priv->TextLength * 7 / 16) <= len)) { PreferUnicode = false; } else { PreferUnicode = true; } } error = ATGEN_SetPBKCharset(s, PreferUnicode); if (error != ERR_NONE) return error; switch (Priv->PBKCharset) { case AT_PBK_HEX: EncodeHexBin(name, DecodeUnicodeString(entry->Entries[Name].Text), UnicodeLength(entry->Entries[Name].Text)); len = strlen(name); break; case AT_PBK_GSM: smprintf(s, "str: %s\n", DecodeUnicodeString(entry->Entries[Name].Text)); len = UnicodeLength(entry->Entries[Name].Text); EncodeDefault(name, entry->Entries[Name].Text, &len, true, NULL); break; case AT_PBK_UCS2: EncodeHexUnicode(name, entry->Entries[Name].Text, UnicodeLength(entry->Entries[Name].Text)); len = strlen(name); break; case AT_PBK_PCCP437: /* FIXME: correctly decode PCCP437 */ smprintf(s, "str: %s\n", DecodeUnicodeString(entry->Entries[Name].Text)); len = UnicodeLength(entry->Entries[Name].Text); EncodeDefault(name, entry->Entries[Name].Text, &len, true, NULL); break; } } else { smprintf(s, "WARNING: No usable name found!\n"); len = 0; } if (Number != -1) { GSM_PackSemiOctetNumber(entry->Entries[Number].Text, number, false); NumberType = number[0]; sprintf(number,"%s",DecodeUnicodeString(entry->Entries[Number].Text)); } else { smprintf(s, "WARNING: No usable number found!\n"); number[0] = 0; } if (Priv->FirstMemoryEntry == 0) { error = ATGEN_GetMemoryInfo(s, NULL, AT_First); if (error != ERR_NONE) return error; } /* We can't use here: * sprintf(req, "AT+CPBW=%d, \"%s\", %i, \"%s\"\r", * entry->Location, number, NumberType, name); * because name can contain 0 when using GSM alphabet. */ sprintf(req, "AT+CPBW=%d, \"%s\", %i, \"", entry->Location + Priv->FirstMemoryEntry - 1, number, NumberType); reqlen = strlen(req); if (reqlen + len > REQUEST_SIZE - 2) { smprintf(s, "WARNING: Text truncated to fit in buffer!\n"); len = REQUEST_SIZE - 2 - reqlen; } memcpy(req + reqlen, name, len); reqlen += len; memcpy(req + reqlen, "\"\r", 2); reqlen += 2; smprintf(s, "Writing phonebook entry\n"); return GSM_WaitFor (s, req, reqlen, 0x00, 4, ID_SetMemory); #undef REQUEST_SIZE } GSM_Error ATGEN_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { if (entry->Location == 0) return ERR_INVALIDLOCATION; return ATGEN_PrivSetMemory(s, entry); } GSM_Error ATGEN_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { GSM_Error error; GSM_MemoryStatus Status; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; /* Find out empty location */ error = ATGEN_GetMemoryInfo(s, &Status, AT_NextEmpty); if (error != ERR_NONE) return error; if (Priv->NextMemoryEntry == 0) return ERR_FULL; entry->Location = Priv->NextMemoryEntry; return ATGEN_PrivSetMemory(s, entry); } /* Use ATGEN_ExtractOneParameter ?? */ void Extract_CLIP_number(char *dest, char *buf) { char *start, *stop; int i = 0; stop = strstr(buf, ","); if (stop != NULL) { start = strstr(buf, ":"); if (start != NULL) { for (start = start + 2; start + i < stop; i++) dest[i] = start[i]; } } dest[i] = 0; /* end the number */ return; } GSM_Error ATGEN_ReplyIncomingCallInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { char num[128]; GSM_Call call; smprintf(s, "Incoming call info\n"); if (s->Phone.Data.EnableIncomingCall && s->User.IncomingCall!=NULL) { call.CallIDAvailable = false; num[0] = 0; if (strstr(msg.Buffer, "RING")) { call.Status = GSM_CALL_IncomingCall; Extract_CLIP_number(num, msg.Buffer); } else if (strstr(msg.Buffer, "NO CARRIER")) { call.Status = GSM_CALL_CallEnd; } else if (strstr(msg.Buffer, "COLP:")) { call.Status = GSM_CALL_CallStart; Extract_CLIP_number(num, msg.Buffer); } else { smprintf(s, "CLIP: error\n"); return ERR_NONE; } EncodeUnicode(call.PhoneNumber, num, strlen(num)); s->User.IncomingCall(s->CurrentConfig->Device, call); } return ERR_NONE; } GSM_Error ATGEN_IncomingGPRS(GSM_Protocol_Message msg, GSM_StateMachine *s) { /* "+CGREG: 1,1" */ smprintf(s, "GPRS change\n"); return ERR_NONE; } GSM_Error ATGEN_IncomingBattery(GSM_Protocol_Message msg, GSM_StateMachine *s) { int level = 0; char *p; /* "_OBS: 92,1" */ p = strstr(msg.Buffer, "_OBS:"); if (p) level = atoi(p + 5); smprintf(s, "Battery level changed to %d\n", level); return ERR_NONE; } GSM_Error ATGEN_IncomingNetworkLevel(GSM_Protocol_Message msg, GSM_StateMachine *s) { int level = 0; char *p; /* "_OSIGQ: 12,0" */ p = strstr(msg.Buffer, "_OSIGQ: "); if (p) level = atoi(p + 7); smprintf(s, "Network level changed to %d\n", level); return ERR_NONE; } GSM_Error ATGEN_ReplyGetSIMIMSI(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Phone_Data *Data = &s->Phone.Data; char *c; switch (Priv->ReplyState) { case AT_Reply_OK: CopyLineString(Data->PhoneString, msg.Buffer, Priv->Lines, 2); /* Read just IMSI also on phones that prepend it by "<IMSI>:" (Alcatel BE5) */ c = strstr(Data->PhoneString, "<IMSI>:"); if (c != NULL) { c += 7; memmove(Data->PhoneString, c, strlen(c) + 1); } smprintf(s, "Received IMSI %s\n",Data->PhoneString); return ERR_NONE; case AT_Reply_Error: smprintf(s, "No access to SIM card or not supported by device\n"); return ERR_SECURITYERROR; case AT_Reply_CMEError: return ATGEN_HandleCMEError(s); case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetSIMIMSI(GSM_StateMachine *s, char *IMSI) { s->Phone.Data.PhoneString = IMSI; smprintf(s, "Getting SIM IMSI\n"); return GSM_WaitFor (s, "AT+CIMI\r", 8, 0x00, 4, ID_GetSIMIMSI); } GSM_Error ATGEN_GetDisplayStatus(GSM_StateMachine *s, GSM_DisplayFeatures *features) { return ERR_NOTSUPPORTED; s->Phone.Data.DisplayFeatures = features; smprintf(s, "Getting display status\n"); return GSM_WaitFor (s, "AT+CIND?\r",9, 0x00, 4, ID_GetDisplayStatus); } GSM_Error ATGEN_IncomingSMSCInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { return ERR_NONE; } GSM_Error ATGEN_ReplyGetBatteryCharge(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; int i; Data->BatteryCharge->BatteryPercent = -1; Data->BatteryCharge->ChargeState = 0; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Battery level received\n"); Data->BatteryCharge->BatteryPercent = atoi(msg.Buffer+17); i = atoi(msg.Buffer+14); if (i >= 0 && i <= 3) { Data->BatteryCharge->ChargeState = i + 1; } return ERR_NONE; case AT_Reply_Error: smprintf(s, "Can't get battery level\n"); return ERR_UNKNOWN; case AT_Reply_CMSError: smprintf(s, "Can't get battery level\n"); return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat) { s->Phone.Data.BatteryCharge = bat; smprintf(s, "Getting battery charge\n"); return GSM_WaitFor (s, "AT+CBC\r", 7, 0x00, 4, ID_GetBatteryCharge); } GSM_Error ATGEN_ReplyGetSignalQuality(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_SignalQuality *Signal = s->Phone.Data.SignalQuality; int i; char *pos; Signal->SignalStrength = -1; Signal->SignalPercent = -1; Signal->BitErrorRate = -1; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Signal quality info received\n"); i = atoi(msg.Buffer+15); if (i != 99) { /* from GSM 07.07 section 8.5 */ Signal->SignalStrength = 2 * i - 113; /* FIXME: this is wild guess and probably will be phone dependant */ Signal->SignalPercent = 15 * i; if (Signal->SignalPercent > 100) Signal->SignalPercent = 100; } pos = strchr(msg.Buffer + 15, ','); if (pos != NULL) { i = atoi(pos + 1); /* from GSM 05.08 section 8.2.4 */ switch (i) { case 0: Signal->BitErrorRate = 0; break; /* 0.14 */ case 1: Signal->BitErrorRate = 0; break; /* 0.28 */ case 2: Signal->BitErrorRate = 1; break; /* 0.57 */ case 3: Signal->BitErrorRate = 1; break; /* 1.13 */ case 4: Signal->BitErrorRate = 2; break; /* 2.26 */ case 5: Signal->BitErrorRate = 5; break; /* 4.53 */ case 6: Signal->BitErrorRate = 9; break; /* 9.05 */ case 7: Signal->BitErrorRate = 18; break; /* 18.10 */ } } return ERR_NONE; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig) { s->Phone.Data.SignalQuality = sig; smprintf(s, "Getting signal quality info\n"); return GSM_WaitFor (s, "AT+CSQ\r", 7, 0x00, 4, ID_GetSignalQuality); } /* When use AT+CPIN?, A2D returns it without OK and because of it Gammu parses answer without it. MC35 and other return OK after answer for AT+CPIN?. Here we handle it. Any better idea ? */ GSM_Error ATGEN_ReplyOK(GSM_Protocol_Message msg, GSM_StateMachine *s) { return ERR_NONE; } static GSM_Error ATGEN_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer==AT_Siemens ) return SIEMENS_GetNextCalendar(s,Note,start); if (Priv->Manufacturer==AT_Ericsson) return SONYERIC_GetNextCalendar(s,Note,start); return ERR_NOTSUPPORTED; } GSM_Error ATGEN_Terminate(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; free(Priv->file.Buffer); return ERR_NONE; } GSM_Error ATGEN_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer==AT_Siemens) return SIEMENS_AddCalendarNote(s, Note); if (Priv->Manufacturer==AT_Ericsson) return SONYERIC_AddCalendarNote(s, Note); return ERR_NOTSUPPORTED; } GSM_Error ATGEN_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer==AT_Siemens) return SIEMENS_DelCalendarNote(s, Note); if (Priv->Manufacturer==AT_Ericsson) return SONYERIC_DelCalendarNote(s, Note); return ERR_NOTSUPPORTED; } GSM_Error ATGEN_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer==AT_Siemens) return SIEMENS_GetBitmap(s, Bitmap); if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_GetBitmap(s, Bitmap); return ERR_NOTSUPPORTED; } GSM_Error ATGEN_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer==AT_Siemens) return SIEMENS_SetBitmap(s, Bitmap); if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_SetBitmap(s, Bitmap); return ERR_NOTSUPPORTED; } GSM_Error ATGEN_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer==AT_Siemens) return SIEMENS_GetRingtone(s, Ringtone, PhoneRingtone); if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_GetRingtone(s, Ringtone, PhoneRingtone); return ERR_NOTSUPPORTED; } GSM_Error ATGEN_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer==AT_Siemens) return SIEMENS_SetRingtone(s, Ringtone, maxlength); if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_SetRingtone(s, Ringtone, maxlength); return ERR_NOTSUPPORTED; } GSM_Error ATGEN_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press) { GSM_Error error; unsigned char Frame[] = "AT+CKPD=\"?\"\r"; if (Press) { switch (Key) { case GSM_KEY_1 : Frame[9] = '1'; break; case GSM_KEY_2 : Frame[9] = '2'; break; case GSM_KEY_3 : Frame[9] = '3'; break; case GSM_KEY_4 : Frame[9] = '4'; break; case GSM_KEY_5 : Frame[9] = '5'; break; case GSM_KEY_6 : Frame[9] = '6'; break; case GSM_KEY_7 : Frame[9] = '7'; break; case GSM_KEY_8 : Frame[9] = '8'; break; case GSM_KEY_9 : Frame[9] = '9'; break; case GSM_KEY_0 : Frame[9] = '0'; break; case GSM_KEY_HASH : Frame[9] = '#'; break; case GSM_KEY_ASTERISK : Frame[9] = '*'; break; case GSM_KEY_POWER : return ERR_NOTSUPPORTED; case GSM_KEY_GREEN : Frame[9] = 'S'; break; case GSM_KEY_RED : Frame[9] = 'E'; break; case GSM_KEY_INCREASEVOLUME : Frame[9] = 'U'; break; case GSM_KEY_DECREASEVOLUME : Frame[9] = 'D'; break; case GSM_KEY_UP : Frame[9] = '^'; break; case GSM_KEY_DOWN : Frame[9] = 'V'; break; case GSM_KEY_MENU : Frame[9] = 'F'; break; case GSM_KEY_NAMES : Frame[9] = 'C'; break; default : return ERR_NOTSUPPORTED; } smprintf(s, "Pressing key\n"); error = GSM_WaitFor (s, Frame, 12, 0x00, 4, ID_PressKey); if (error != ERR_NONE) return error; /* Strange. My T310 needs it */ return GSM_WaitFor (s, "ATE1\r", 5, 0x00, 4, ID_EnableEcho); } else { return ERR_NONE; } } #ifdef GSM_ENABLE_CELLBROADCAST GSM_Error ATGEN_ReplyIncomingCB(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_CBMessage CB; int i,j; char Buffer[300],Buffer2[300]; smprintf(s, "CB received\n"); return ERR_NONE; DecodeHexBin (Buffer,msg.Buffer+6,msg.Length-6); DumpMessage(stdout, di.dl ,Buffer,msg.Length-6); CB.Channel = Buffer[4]; for (j=0;j<msg.Length;j++) { smprintf(s, "j=%i\n",j); i=GSM_UnpackEightBitsToSeven(0, msg.Buffer[6], msg.Buffer[6], msg.Buffer+j, Buffer2); // i = msg.Buffer[6] - 1; // while (i!=0) { // if (Buffer[i] == 13) i = i - 1; else break; // } DecodeDefault(CB.Text, Buffer2, msg.Buffer[6], false, NULL); smprintf(s, "Channel %i, text \"%s\"\n",CB.Channel,DecodeUnicodeString(CB.Text)); } if (s->Phone.Data.EnableIncomingCB && s->User.IncomingCB!=NULL) { s->User.IncomingCB(s->CurrentConfig->Device,CB); } return ERR_NONE; } #endif GSM_Error ATGEN_SetIncomingCB(GSM_StateMachine *s, bool enable) { #ifdef GSM_ENABLE_CELLBROADCAST if (s->Phone.Data.EnableIncomingCB!=enable) { s->Phone.Data.EnableIncomingCB = enable; if (enable) { smprintf(s, "Enabling incoming CB\n"); return GSM_WaitFor(s, "AT+CNMI=3,,2\r", 13, 0x00, 4, ID_SetIncomingCB); } else { smprintf(s, "Disabling incoming CB\n"); return GSM_WaitFor(s, "AT+CNMI=3,,0\r", 13, 0x00, 4, ID_SetIncomingCB); } } return ERR_NONE; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error ATGEN_SetFastSMSSending(GSM_StateMachine *s, bool enable) { if (enable) { smprintf(s, "Enabling fast SMS sending\n"); return GSM_WaitFor(s, "AT+CMMS=2\r", 10, 0x00, 4, ID_SetFastSMSSending); } else { smprintf(s, "Disabling fast SMS sending\n"); return GSM_WaitFor(s, "AT+CMMS=0\r", 10, 0x00, 4, ID_SetFastSMSSending); } } GSM_Error ATGEN_IncomingSMSInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Incoming SMS\n"); return ERR_NONE; } GSM_Error ATGEN_IncomingSMSDeliver(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; GSM_SMSMessage sms; int current = 0, current2, i=0; unsigned char buffer[300],smsframe[800]; smprintf(s, "Incoming SMS received (Deliver)\n"); if (Data->EnableIncomingSMS && s->User.IncomingSMS!=NULL) { sms.State = SMS_UnRead; sms.InboxFolder = true; sms.PDU = SMS_Deliver; /* T310 with larger SMS goes crazy and mix this incoming * frame with normal answers. PDU is always last frame * We find its' number and parse it */ while (Data->Priv.ATGEN.Lines.numbers[i*2+1] != 0) { /* FIXME: handle special chars correctly */ i++; } DecodeHexBin (buffer, GetLineString(msg.Buffer,Data->Priv.ATGEN.Lines,i), strlen(GetLineString(msg.Buffer,Data->Priv.ATGEN.Lines,i))); /* We use locations from SMS layouts like in ../phone2.c(h) */ for(i=0;i<buffer[0]+1;i++) smsframe[i]=buffer[current++]; smsframe[12]=buffer[current++]; current2=((buffer[current])+1)/2+1; for(i=0;i<current2+1;i++) smsframe[PHONE_SMSDeliver.Number+i]=buffer[current++]; smsframe[PHONE_SMSDeliver.TPPID] = buffer[current++]; smsframe[PHONE_SMSDeliver.TPDCS] = buffer[current++]; for(i=0;i<7;i++) smsframe[PHONE_SMSDeliver.DateTime+i]=buffer[current++]; smsframe[PHONE_SMSDeliver.TPUDL] = buffer[current++]; for(i=0;i<smsframe[PHONE_SMSDeliver.TPUDL];i++) smsframe[i+PHONE_SMSDeliver.Text]=buffer[current++]; GSM_DecodeSMSFrame(&sms,smsframe,PHONE_SMSDeliver); s->User.IncomingSMS(s->CurrentConfig->Device,sms); } return ERR_NONE; } /* I don't have phone able to do it and can't fill it */ GSM_Error ATGEN_IncomingSMSReport(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Incoming SMS received (Report)\n"); return ERR_NONE; } GSM_Error ATGEN_SetIncomingSMS(GSM_StateMachine *s, bool enable) { /* Nokia returns OK, but doesn't return anything */ if (s->Phone.Data.Priv.ATGEN.Manufacturer == AT_Nokia) return ERR_NOTSUPPORTED; if (s->Phone.Data.EnableIncomingSMS!=enable) { s->Phone.Data.EnableIncomingSMS = enable; if (enable) { smprintf(s, "Enabling incoming SMS\n"); /* Delivery reports */ GSM_WaitFor(s, "AT+CNMI=3,,,1\r", 14, 0x00, 4, ID_SetIncomingSMS); /* SMS deliver */ return GSM_WaitFor(s, "AT+CNMI=3,3\r", 12, 0x00, 4, ID_SetIncomingSMS); } else { smprintf(s, "Disabling incoming SMS\n"); return GSM_WaitFor(s, "AT+CNMI=3,0\r", 12, 0x00, 4, ID_SetIncomingSMS); } } return ERR_NONE; } GSM_Error ATGEN_GetLocale(GSM_StateMachine *s, GSM_Locale *locale) { if (s->Phone.Data.Priv.ATGEN.Manufacturer==AT_Ericsson) return ERICSSON_GetLocale(s,locale); return ERR_NOTSUPPORTED; } GSM_Error ATGEN_SetLocale(GSM_StateMachine *s, GSM_Locale *locale) { if (s->Phone.Data.Priv.ATGEN.Manufacturer==AT_Ericsson) return ERICSSON_SetLocale(s,locale); return ERR_NOTSUPPORTED; } GSM_Reply_Function ATGENReplyFunctions[] = { {ATGEN_GenericReply, "AT\r" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "ATE1" ,0x00,0x00,ID_EnableEcho }, {ATGEN_GenericReply, "AT+CMEE=" ,0x00,0x00,ID_EnableErrorInfo }, {ATGEN_GenericReply, "AT+CKPD=" ,0x00,0x00,ID_PressKey }, {ATGEN_ReplyGetSIMIMSI, "AT+CIMI" ,0x00,0x00,ID_GetSIMIMSI }, {ATGEN_GenericReply, "AT*EOBEX" ,0x00,0x00,ID_SetOBEX }, {ERICSSON_ReplyGetDateLocale, "*ESDF:" ,0x00,0x00,ID_GetLocale }, {ERICSSON_ReplyGetTimeLocale, "*ESTF:" ,0x00,0x00,ID_GetLocale }, {ATGEN_GenericReply, "AT*ESDF=" ,0x00,0x00,ID_SetLocale }, {ATGEN_GenericReply, "AT*ESTF=" ,0x00,0x00,ID_SetLocale }, #ifdef GSM_ENABLE_CELLBROADCAST {ATGEN_ReplyIncomingCB, "+CBM:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "AT+CNMI" ,0x00,0x00,ID_SetIncomingCB }, #endif {ATGEN_IncomingBattery, "_OBS:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetBatteryCharge, "AT+CBC" ,0x00,0x00,ID_GetBatteryCharge }, {ATGEN_ReplyGetModel, "AT+CGMM" ,0x00,0x00,ID_GetModel }, {ATGEN_ReplyGetManufacturer, "AT+CGMI" ,0x00,0x00,ID_GetManufacturer }, {ATGEN_ReplyGetFirmwareCGMR, "AT+CGMR" ,0x00,0x00,ID_GetFirmware }, {ATGEN_ReplyGetFirmwareATI, "ATI" ,0x00,0x00,ID_GetFirmware }, {ATGEN_ReplyGetIMEI, "AT+CGSN" ,0x00,0x00,ID_GetIMEI }, {ATGEN_ReplySendSMS, "AT+CMGS" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplySendSMS, "AT+CMSS" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "AT+CNMI" ,0x00,0x00,ID_SetIncomingSMS }, {ATGEN_GenericReply, "AT+CMGF" ,0x00,0x00,ID_GetSMSMode }, {ATGEN_GenericReply, "AT+CSDH" ,0x00,0x00,ID_GetSMSMode }, {ATGEN_ReplyGetSMSMessage, "AT+CMGR" ,0x00,0x00,ID_GetSMSMessage }, {ATGEN_GenericReply, "AT+CPMS" ,0x00,0x00,ID_SetMemoryType }, {ATGEN_ReplyGetSMSStatus, "AT+CPMS" ,0x00,0x00,ID_GetSMSStatus }, {ATGEN_ReplyGetSMSMemories, "AT+CPMS=?" ,0x00,0x00,ID_GetSMSMemories }, {ATGEN_ReplyAddSMSMessage, "AT+CMGW" ,0x00,0x00,ID_SaveSMSMessage }, {ATGEN_GenericReply, "AT+CSMP" ,0x00,0x00,ID_SetSMSParameters }, {ATGEN_GenericReply, "AT+CSCA" ,0x00,0x00,ID_SetSMSC }, {ATGEN_ReplyGetSMSC, "AT+CSCA?" ,0x00,0x00,ID_GetSMSC }, {ATGEN_ReplyDeleteSMSMessage, "AT+CMGD" ,0x00,0x00,ID_DeleteSMSMessage }, {ATGEN_GenericReply, "ATE1" ,0x00,0x00,ID_SetSMSParameters }, {ATGEN_GenericReply, "\x1b\x0D" ,0x00,0x00,ID_SetSMSParameters }, {ATGEN_GenericReply, "AT+CMMS" ,0x00,0x00,ID_SetFastSMSSending }, {ATGEN_IncomingSMSInfo, "+CMTI:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingSMSDeliver, "+CMT:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingSMSReport, "+CDS:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingSMSCInfo, "^SCN:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetDateTime_Alarm, "AT+CCLK?" ,0x00,0x00,ID_GetDateTime }, {ATGEN_GenericReply, "AT+CCLK=" ,0x00,0x00,ID_SetDateTime }, {ATGEN_GenericReply, "AT+CALA=" ,0x00,0x00,ID_SetAlarm }, {ATGEN_ReplyGetDateTime_Alarm, "AT+CALA?" ,0x00,0x00,ID_GetAlarm }, {ATGEN_ReplyGetNetworkLAC_CID, "AT+CREG?" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_GenericReply, "AT+CREG=2" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_GenericReply, "AT+COPS=" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_GenericReply, "AT+COPS=" ,0x00,0x00,ID_SetAutoNetworkLogin}, {ATGEN_ReplyGetNetworkCode, "AT+COPS" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_ReplyGetSignalQuality, "AT+CSQ" ,0x00,0x00,ID_GetSignalQuality }, {ATGEN_IncomingNetworkLevel, "_OSIGQ:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingGPRS, "+CGREG:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetNetworkLAC_CID, "+CREG:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetPBKMemories, "AT+CPBS=?" ,0x00,0x00,ID_SetMemoryType }, {ATGEN_GenericReply, "AT+CPBS=" ,0x00,0x00,ID_SetMemoryType }, {ATGEN_ReplyGetCPBSMemoryStatus,"AT+CPBS?" ,0x00,0x00,ID_GetMemoryStatus }, // /* Samsung phones reply +CPBR: after OK --claudio*/ {ATGEN_ReplyGetCPBRMemoryInfo, "AT+CPBR=?" ,0x00,0x00,ID_GetMemoryStatus }, {ATGEN_ReplyGetCPBRMemoryInfo, "+CPBR:" ,0x00,0x00,ID_GetMemoryStatus }, {ATGEN_ReplyGetCPBRMemoryStatus,"AT+CPBR=" ,0x00,0x00,ID_GetMemoryStatus }, {ATGEN_GenericReply, "AT+CSCS=" ,0x00,0x00,ID_SetMemoryCharset }, {ATGEN_ReplyGetMemory, "AT+CPBR=" ,0x00,0x00,ID_GetMemory }, {ATGEN_GenericReply, "AT^SBNR=?" ,0x00,0x00,ID_GetMemory }, {SIEMENS_ReplyGetMemory, "AT^SBNR" ,0x00,0x00,ID_GetMemory }, {ATGEN_ReplySetMemory, "AT+CPBW" ,0x00,0x00,ID_SetMemory }, {SIEMENS_ReplyGetBitmap, "AT^SBNR=\"bmp\"" ,0x00,0x00,ID_GetBitmap }, {SIEMENS_ReplySetBitmap, "AT^SBNW=\"bmp\"" ,0x00,0x00,ID_SetBitmap }, {SIEMENS_ReplyGetRingtone, "AT^SBNR=\"mid\"" ,0x00,0x00,ID_GetRingtone }, {SIEMENS_ReplySetRingtone, "AT^SBNW=\"mid\"" ,0x00,0x00,ID_SetRingtone }, {SIEMENS_ReplyGetNextCalendar, "AT^SBNR=\"vcs\"" ,0x00,0x00,ID_GetCalendarNote }, {SIEMENS_ReplyAddCalendarNote, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_SetCalendarNote }, {SIEMENS_ReplyDelCalendarNote, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_DeleteCalendarNote }, {ATGEN_ReplyEnterSecurityCode, "AT+CPIN=" ,0x00,0x00,ID_EnterSecurityCode }, {ATGEN_ReplyEnterSecurityCode, "AT+CPIN2=" ,0x00,0x00,ID_EnterSecurityCode }, {ATGEN_ReplyGetSecurityStatus, "AT+CPIN?" ,0x00,0x00,ID_GetSecurityStatus }, {ATGEN_ReplyOK, "OK" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "AT+VTS" ,0x00,0x00,ID_SendDTMF }, {ATGEN_ReplyCancelCall, "AT+CHUP" ,0x00,0x00,ID_CancelCall }, {ATGEN_ReplyDialVoice, "ATDT" ,0x00,0x00,ID_DialVoice }, {ATGEN_ReplyCancelCall, "ATH" ,0x00,0x00,ID_CancelCall }, {ATGEN_GenericReply, "AT+CUSD" ,0x00,0x00,ID_SetUSSD }, {ATGEN_ReplyGetUSSD, "+CUSD" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "AT+CLIP=1" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "+CLIP" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "+COLP" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "RING" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "NO CARRIER" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyReset, "AT^SRESET" ,0x00,0x00,ID_Reset }, {ATGEN_ReplyReset, "AT+CFUN=1,1" ,0x00,0x00,ID_Reset }, {ATGEN_ReplyResetPhoneSettings, "AT&F" ,0x00,0x00,ID_ResetPhoneSettings }, {SAMSUNG_ReplyGetBitmap, "AT+IMGR=" ,0x00,0x00,ID_GetBitmap }, {SAMSUNG_ReplySetBitmap, "SDNDCRC =" ,0x00,0x00,ID_SetBitmap }, {SAMSUNG_ReplyGetRingtone, "AT+MELR=" ,0x00,0x00,ID_GetRingtone }, {SAMSUNG_ReplySetRingtone, "SDNDCRC =" ,0x00,0x00,ID_SetRingtone }, #ifdef GSM_ENABLE_ALCATEL /* Why do I give Alcatel specific things here? It's simple, Alcatel needs * some AT commands to start it's binary mode, so this needs to be in AT * related stuff. * * XXX: AT+IFC could later move outside this ifdef, because it is not Alcatel * specific and it's part of ETSI specifications */ {ATGEN_GenericReply, "AT+IFC" ,0x00,0x00,ID_SetFlowControl }, {ALCATEL_ProtocolVersionReply, "AT+CPROT=?" ,0x00,0x00,ID_AlcatelProtocol }, {ATGEN_GenericReply, "AT+CPROT" ,0x00,0x00,ID_AlcatelConnect }, #endif {NULL, "\x00" ,0x00,0x00,ID_None } }; GSM_Phone_Functions ATGENPhone = { "A2D|iPAQ|at|M20|S25|MC35|TC35|C35i|S300|5110|5130|5190|5210|6110|6130|6150|6190|6210|6250|6310|6310i|6510|7110|8210|8250|8290|8310|8390|8850|8855|8890|8910|9110|9210", ATGENReplyFunctions, ATGEN_Initialise, ATGEN_Terminate, ATGEN_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ ATGEN_GetManufacturer, ATGEN_GetModel, ATGEN_GetFirmware, ATGEN_GetIMEI, NOTSUPPORTED, /* GetOriginalIMEI */ NOTSUPPORTED, /* GetManufactureMonth */ NOTSUPPORTED, /* GetProductCode */ NOTSUPPORTED, /* GetHardware */ NOTSUPPORTED, /* GetPPM */ ATGEN_GetSIMIMSI, ATGEN_GetDateTime, ATGEN_SetDateTime, ATGEN_GetAlarm, ATGEN_SetAlarm, ATGEN_GetLocale, ATGEN_SetLocale, ATGEN_PressKey, ATGEN_Reset, ATGEN_ResetPhoneSettings, ATGEN_EnterSecurityCode, ATGEN_GetSecurityStatus, ATGEN_GetDisplayStatus, ATGEN_SetAutoNetworkLogin, ATGEN_GetBatteryCharge, ATGEN_GetSignalQuality, ATGEN_GetNetworkInfo, NOTSUPPORTED, /* GetCategory */ NOTSUPPORTED, /* AddCategory */ NOTSUPPORTED, /* GetCategoryStatus */ ATGEN_GetMemoryStatus, ATGEN_GetMemory, ATGEN_GetNextMemory, ATGEN_SetMemory, ATGEN_AddMemory, ATGEN_DeleteMemory, ATGEN_DeleteAllMemory, NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ ATGEN_GetSMSC, ATGEN_SetSMSC, ATGEN_GetSMSStatus, ATGEN_GetSMS, ATGEN_GetNextSMS, NOTSUPPORTED, /* SetSMS */ ATGEN_AddSMS, ATGEN_DeleteSMS, ATGEN_SendSMS, ATGEN_SendSavedSMS, ATGEN_SetFastSMSSending, ATGEN_SetIncomingSMS, ATGEN_SetIncomingCB, ATGEN_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ ATGEN_DialVoice, ATGEN_AnswerCall, ATGEN_CancelCall, NOTSUPPORTED, /* HoldCall */ NOTSUPPORTED, /* UnholdCall */ NOTSUPPORTED, /* ConferenceCall */ NOTSUPPORTED, /* SplitCall */ NOTSUPPORTED, /* TransferCall */ NOTSUPPORTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ NOTSUPPORTED, /* SetCallDivert */ NOTSUPPORTED, /* CancelAllDiverts */ NONEFUNCTION, /* SetIncomingCall */ ATGEN_SetIncomingUSSD, ATGEN_SendDTMF, ATGEN_GetRingtone, ATGEN_SetRingtone, NOTSUPPORTED, /* GetRingtonesInfo */ NOTSUPPORTED, /* DeleteUserRingtones */ NOTSUPPORTED, /* PlayTone */ NOTSUPPORTED, /* GetWAPBookmark */ NOTSUPPORTED, /* SetWAPBookmark */ NOTSUPPORTED, /* DeleteWAPBookmark */ NOTSUPPORTED, /* GetWAPSettings */ NOTSUPPORTED, /* SetWAPSettings */ NOTSUPPORTED, /* GetMMSSettings */ NOTSUPPORTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetSyncMLSettings */ NOTSUPPORTED, /* SetSyncMLSettings */ NOTSUPPORTED, /* GetChatSettings */ NOTSUPPORTED, /* SetChatSettings */ ATGEN_GetBitmap, /* GetBitmap */ ATGEN_SetBitmap, /* SetBitmap */ SONYERIC_GetToDoStatus, NOTSUPPORTED, /* GetToDo */ SONYERIC_GetNextToDo, NOTSUPPORTED, /* SetToDo */ SONYERIC_AddToDo, NOTSUPPORTED, /* DeleteToDo */ SONYERIC_DeleteAllToDo, SONYERIC_GetCalendarStatus, NOTIMPLEMENTED, /* GetCalendar */ ATGEN_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ ATGEN_AddCalendarNote, ATGEN_DelCalendarNote, NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ + NOTSUPPORTED, /* GetNoteStatus */ + NOTSUPPORTED, /* GetNote */ NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* SetNote */ + NOTSUPPORTED, /* AddNote */ + NOTSUPPORTED, /* DeleteNote */ + NOTSUPPORTED, /* DeleteAllNotes */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ NOTSUPPORTED /* SetGPRSAccessPoint */ }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/at/sonyeric.c b/gammu/emb/common/phone/at/sonyeric.c index 8eeb39b..363e043 100644 --- a/gammu/emb/common/phone/at/sonyeric.c +++ b/gammu/emb/common/phone/at/sonyeric.c @@ -1,520 +1,521 @@ /* (c) 2003 by Marcin Wiacek */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_ATGEN #include <string.h> #include <time.h> #include <ctype.h> #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" #include "atgen.h" #include "sonyeric.h" -#ifdef GSM_ENABLE_OBEXGEN +#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) #include "../obex/obexgen.h" +extern GSM_Protocol_Functions OBEXProtocol; extern GSM_Reply_Function OBEXGENReplyFunctions[]; extern GSM_Reply_Function ATGENReplyFunctions[]; static GSM_Error SONYERIC_SetOBEXMode(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; if (Priv->OBEX) return ERR_NONE; dbgprintf ("Changing to OBEX\n"); error=GSM_WaitFor (s, "AT*EOBEX\r", 9, 0x00, 4, ID_SetOBEX); if (error != ERR_NONE) return error; error = s->Protocol.Functions->Terminate(s); if (error != ERR_NONE) return error; s->Protocol.Functions = &OBEXProtocol; error = s->Protocol.Functions->Initialise(s); if (error != ERR_NONE) { s->Protocol.Functions = &ATProtocol; return error; } strcpy(s->CurrentConfig->Model,"seobex"); s->Phone.Data.Priv.OBEXGEN.Service = 0; s->Phone.Functions->DispatchMessage = GSM_DispatchMessage; s->Phone.Functions->ReplyFunctions = OBEXGENReplyFunctions; Priv->OBEX = true; return ERR_NONE; } static GSM_Error SONYERIC_SetATMode(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; if (!Priv->OBEX) return ERR_NONE; dbgprintf ("Changing to AT\n"); error = OBEXGEN_Disconnect(s); if (error != ERR_NONE) return error; error = s->Protocol.Functions->Terminate(s); if (error != ERR_NONE) return error; s->Protocol.Functions = &ATProtocol; error = s->Protocol.Functions->Initialise(s); if (error != ERR_NONE) { s->Protocol.Functions = &OBEXProtocol; return error; } strcpy(s->CurrentConfig->Model,"at"); s->Phone.Functions->DispatchMessage = ATGEN_DispatchMessage; s->Phone.Functions->ReplyFunctions = ATGENReplyFunctions; Priv->OBEX = false; return ERR_NONE; } static GSM_Error SONYERIC_GetFile(GSM_StateMachine *s, GSM_File *File, unsigned char *FileName) { GSM_Error error; strcpy(File->ID_FullName,FileName); File->Used = 0; if (File->Buffer != NULL) free(File->Buffer); File->Buffer = NULL; error = SONYERIC_SetOBEXMode(s); if (error != ERR_NONE) return error; error = ERR_NONE; while (error == ERR_NONE) error = OBEXGEN_GetFilePart(s,File); if (error != ERR_EMPTY) return error; return SONYERIC_SetATMode(s); } static GSM_Error SONYERIC_SetFile(GSM_StateMachine *s, unsigned char *FileName, unsigned char *Buffer, int Length) { GSM_Error error; GSM_File File; int Pos = 0; error = SONYERIC_SetOBEXMode(s); if (error != ERR_NONE) return error; strcpy(File.ID_FullName,FileName); EncodeUnicode(File.Name,FileName,strlen(FileName)); File.Used = Length; File.Buffer = malloc(Length); memcpy(File.Buffer,Buffer,Length); error = ERR_NONE; while (error == ERR_NONE) error = OBEXGEN_AddFilePart(s,&File,&Pos); free(File.Buffer); if (error != ERR_EMPTY) return error; return SONYERIC_SetATMode(s); } #endif GSM_Error SONYERIC_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) { -#ifdef GSM_ENABLE_OBEXGEN +#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) GSM_Error error; GSM_ToDoEntry ToDo; int Pos, num, Loc; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (start) { error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; Note->Location = 1; } else { Note->Location++; } smprintf(s, "Getting calendar note %i\n",Note->Location); Loc = Note->Location; Pos = 0; num = 0; while (1) { error = GSM_DecodeVCALENDAR_VTODO(Priv->file.Buffer, &Pos, Note, &ToDo, SonyEricsson_VCalendar, SonyEricsson_VToDo); if (error == ERR_EMPTY) break; if (error != ERR_NONE) return error; if (Note->EntriesNum != 0) { num++; if (num == Loc) return ERR_NONE; } } return ERR_EMPTY; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start) { -#ifdef GSM_ENABLE_OBEXGEN +#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) GSM_Error error; GSM_CalendarEntry Calendar; int Pos, num, Loc; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; if (start) { error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; ToDo->Location = 1; } else { ToDo->Location++; } smprintf(s,"Getting ToDo %i\n",ToDo->Location); Loc = ToDo->Location; Pos = 0; num = 0; while (1) { error = GSM_DecodeVCALENDAR_VTODO(Priv->file.Buffer, &Pos, &Calendar, ToDo, SonyEricsson_VCalendar, SonyEricsson_VToDo); if (error == ERR_EMPTY) break; if (error != ERR_NONE) return error; if (ToDo->EntriesNum != 0) { num++; if (num == Loc) return ERR_NONE; } } return ERR_EMPTY; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) { -#ifdef GSM_ENABLE_OBEXGEN +#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) GSM_Error error; GSM_ToDoEntry ToDo; GSM_CalendarEntry Calendar; int Pos; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; smprintf(s,"Getting ToDo status\n"); error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; status->Used = 0; Pos = 0; while (1) { error = GSM_DecodeVCALENDAR_VTODO(Priv->file.Buffer, &Pos, &Calendar, &ToDo, SonyEricsson_VCalendar, SonyEricsson_VToDo); if (error == ERR_EMPTY) break; if (error != ERR_NONE) return error; if (ToDo.EntriesNum != 0) status->Used++; } return ERR_NONE; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { -#ifdef GSM_ENABLE_OBEXGEN +#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) unsigned char req[5000]; int size=0; smprintf(s,"Adding calendar note\n"); GSM_EncodeVCALENDAR(req,&size,Note,true,SonyEricsson_VCalendar); return SONYERIC_SetFile(s, "telecom/cal/luid/.vcs", req, size); #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { -#ifdef GSM_ENABLE_OBEXGEN +#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char req[5000]; int size=0; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; smprintf(s,"Adding ToDo\n"); GSM_EncodeVTODO(req,&size,ToDo,true,SonyEricsson_VToDo); return SONYERIC_SetFile(s, "telecom/cal/luid/.vcs", req, size); #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_DeleteAllToDo(GSM_StateMachine *s) { -#ifdef GSM_ENABLE_OBEXGEN +#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) GSM_Error error; int Pos,Level = 0,Used; unsigned char *Buf; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char Line[2000]; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; smprintf(s,"Deleting all ToDo\n"); error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; Pos = 0; Buf = NULL; Used = 0; while (1) { MyGetLine(Priv->file.Buffer, &Pos, Line, Priv->file.Used); if (strlen(Line) == 0) break; dbgprintf("Line is %s,%i,%i\n",Line,Priv->file.Used,Pos); switch (Level) { case 0: if (strstr(Line,"BEGIN:VTODO")) { Level = 2; break; } Buf=(unsigned char *)realloc(Buf,Used+strlen(Line)+3); strcpy(Buf+Used,Line); Used=Used+strlen(Line)+3; Buf[Used-3] = 13; Buf[Used-2] = 10; Buf[Used-1] = 0x00; break; case 2: /* ToDo note */ if (strstr(Line,"END:VTODO")) { Level = 0; } break; } } error = SONYERIC_SetFile(s, "telecom/cal.vcs", Buf, Used); // if (Buf != NULL) free(Buf); return error; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { -#ifdef GSM_ENABLE_OBEXGEN +#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) GSM_Error error; int Pos,Level = 0,Loc=0,Used; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char Line[2000]; unsigned char *Buf; smprintf(s, "Deleting calendar note %i\n",Note->Location); error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; Pos = 0; Buf = NULL; Used = 0; while (1) { MyGetLine(Priv->file.Buffer, &Pos, Line, Priv->file.Used); if (strlen(Line) == 0) break; dbgprintf("Line is %s,%i,%i\n",Line,Priv->file.Used,Pos); switch (Level) { case 0: if (strstr(Line,"BEGIN:VEVENT")) { Loc++; if (Loc == Note->Location) { Level = 1; break; } } Buf=(unsigned char *)realloc(Buf,Used+strlen(Line)+3); strcpy(Buf+Used,Line); Used=Used+strlen(Line)+3; Buf[Used-3] = 13; Buf[Used-2] = 10; Buf[Used-1] = 0x00; break; case 1: /* Calendar note */ if (strstr(Line,"END:VEVENT")) { Level = 0; } break; } } DumpMessage(s->di.df, s->di.dl, Buf, Used); error = SONYERIC_SetFile(s, "telecom/cal.vcs", Buf, Used); if (Buf != NULL) free(Buf); return error; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status) { -#ifdef GSM_ENABLE_OBEXGEN +#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) GSM_Error error; GSM_ToDoEntry ToDo; GSM_CalendarEntry Calendar; int Pos; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; smprintf(s, "Getting calendar status\n"); error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; Status->Used = 0; Pos = 0; while (1) { error = GSM_DecodeVCALENDAR_VTODO(Priv->file.Buffer, &Pos, &Calendar, &ToDo, SonyEricsson_VCalendar, SonyEricsson_VToDo); if (error == ERR_EMPTY) break; if (error != ERR_NONE) return error; if (Calendar.EntriesNum != 0) Status->Used++; } return ERR_NONE; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error ERICSSON_ReplyGetDateLocale(GSM_Protocol_Message msg, GSM_StateMachine *s) { /* Author: Peter Ondraska, based on code by Marcin Wiacek and Michal Cihar License: Whatever the current maintainer of gammulib chooses, as long as there is an easy way to obtain the source under GPL, otherwise the author's parts of this function are GPL 2.0. */ GSM_Locale *locale = s->Phone.Data.Locale; char format; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Date settings received\n"); format=atoi(msg.Buffer); switch (format) { case 0: locale->DateFormat = GSM_Date_OFF; locale->DateSeparator = 0; break; case 1: locale->DateFormat = GSM_Date_DDMMMYY; locale->DateSeparator = '-'; break; case 2: locale->DateFormat = GSM_Date_DDMMYY; locale->DateSeparator = '-'; break; case 3: locale->DateFormat = GSM_Date_MMDDYY; locale->DateSeparator = '/'; break; case 4: locale->DateFormat = GSM_Date_DDMMYY; locale->DateSeparator = '/'; break; case 5: locale->DateFormat = GSM_Date_DDMMYY; locale->DateSeparator = '.'; break; case 6: locale->DateFormat = GSM_Date_YYMMDD; locale->DateSeparator = 0; break; case 7: locale->DateFormat = GSM_Date_YYMMDD; locale->DateSeparator = '-'; break; default:return ERR_UNKNOWNRESPONSE; } default: return ERR_NOTSUPPORTED; } } GSM_Error ERICSSON_ReplyGetTimeLocale(GSM_Protocol_Message msg, GSM_StateMachine *s) { /* Author: Peter Ondraska License: Whatever the current maintainer of gammulib chooses, as long as there is an easy way to obtain the source under GPL, otherwise the author's parts of this function are GPL 2.0. */ char format; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "Time settings received\n"); format=atoi(msg.Buffer); switch (format) { case 1: case 2: s->Phone.Data.Locale->AMPMTime=(format==2); return ERR_NONE; default:return ERR_UNKNOWNRESPONSE; } default: return ERR_NOTSUPPORTED; } } GSM_Error ERICSSON_GetLocale(GSM_StateMachine *s, GSM_Locale *locale) { GSM_Error error; s->Phone.Data.Locale = locale; smprintf(s, "Getting date format\n"); error=GSM_WaitFor (s, "AT+ESDF?\r", 9, 0x00, 3, ID_GetLocale); if (error!=ERR_NONE) return error; smprintf(s, "Getting time format\n"); return GSM_WaitFor (s, "AT+ESTF?\r", 9, 0x00, 3, ID_GetLocale); } GSM_Error ERICSSON_SetLocale(GSM_StateMachine *s, GSM_Locale *locale) { /* Author: Peter Ondraska License: Whatever the current maintainer of gammulib chooses, as long as there is an easy way to obtain the source under GPL, otherwise the author's parts of this function are GPL 2.0. */ /* this is not yet supported by gammu.c */ int format=0; char req[12]; if (locale->DateFormat==GSM_Date_OFF) { format=0; } else if ((locale->DateFormat==GSM_Date_DDMMMYY)&&(locale->DateSeparator=='-')) { format=1; } else if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='-')) { format=2; } else if ((locale->DateFormat==GSM_Date_MMDDYY)&&(locale->DateSeparator=='/')) { format=3; } else if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='/')) { format=4; } else if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='.')) { format=5; } else if ((locale->DateFormat==GSM_Date_YYMMDD)&&(locale->DateSeparator==0)) { format=6; } else if ((locale->DateFormat==GSM_Date_YYMMDD)&&(locale->DateSeparator=='-')) { format=7; } else { return ERR_NOTSUPPORTED; } /* ERR_WRONGINPUT */ sprintf(req,"AT+ESDF=%i\r",format); smprintf(s, "Setting date format\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetLocale); if (locale->AMPMTime) { format=2; } else { format=1; } sprintf(req,"AT+ESTF=%i\r",format); smprintf(s, "Setting time format\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetLocale); } #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/nokia/dct3/dct3func.c b/gammu/emb/common/phone/nokia/dct3/dct3func.c index 17cd0a4..9810a35 100644 --- a/gammu/emb/common/phone/nokia/dct3/dct3func.c +++ b/gammu/emb/common/phone/nokia/dct3/dct3func.c @@ -1,1539 +1,1548 @@ /* (c) 2001-2004 by Marcin Wiacek */ /* resetting DCT4 phones settings (c) by Walek */ /* based on some Markus Plail, Pavel Janik & others work from Gnokii (www.gnokii.org) * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot * GNU GPL version 2 or later */ +/* Due to a problem in the source code management, the names of some of + * the authors have unfortunately been lost. We do not mean to belittle + * their efforts and hope they will contact us to see their names + * properly added to the Copyright notice above. + * Having published their contributions under the terms of the GNU + * General Public License (GPL) [version 2], the Copyright of these + * authors will remain respected by adhering to the license they chose + * to publish their code under. + */ #include <string.h> /* memcpy only */ #include <stdio.h> #include <ctype.h> #include "../../../gsmstate.h" #include "../../../misc/coding/coding.h" #include "../../../service/sms/gsmsms.h" #include "../../pfunc.h" #include "../nfunc.h" #include "dct3func.h" #ifdef GSM_ENABLE_NOKIA_DCT3 GSM_Error DCT3_DeleteWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark) { GSM_Error error; /* We have to enable WAP frames in phone */ error=DCT3DCT4_EnableWAPFunctions(s); if (error!=ERR_NONE) return error; return DCT3DCT4_DeleteWAPBookmarkPart(s,bookmark); } GSM_Error DCT3_GetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark) { GSM_Error error; /* We have to enable WAP frames in phone */ error=DCT3DCT4_EnableWAPFunctions(s); if (error!=ERR_NONE) return error; return DCT3DCT4_GetWAPBookmarkPart(s,bookmark); } GSM_Error DCT3_ReplyPressKey(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[2]) { case 0x46: smprintf(s, "Pressing key OK\n"); if (Data->PressKey) return ERR_NONE; break; case 0x47: smprintf(s, "Releasing key OK\n"); if (!Data->PressKey) return ERR_NONE; break; } return ERR_UNKNOWNRESPONSE; } GSM_Error DCT3_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press) { unsigned char PressReq[] = {0x00, 0x01, 0x46, 0x00, 0x01, 0x0a}; /* Key code */ unsigned char ReleaseReq[] = {0x00, 0x01, 0x47, 0x00, 0x01, 0x0c}; if (Press) { PressReq[5] = Key; s->Phone.Data.PressKey = true; smprintf(s, "Pressing key\n"); return GSM_WaitFor (s, PressReq, 6, 0xd1, 4, ID_PressKey); } else { s->Phone.Data.PressKey = false; smprintf(s, "Releasing key\n"); return GSM_WaitFor (s, ReleaseReq, 6, 0xd1, 4, ID_PressKey); } } GSM_Error DCT3_ReplyPlayTone(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Tone played\n"); return ERR_NONE; } GSM_Error DCT3_PlayTone(GSM_StateMachine *s, int Herz, unsigned char Volume, bool start) { GSM_Error error; unsigned char req[] = {0x00,0x01,0x8f, 0x00, /* Volume */ 0x00, /* HerzLo */ 0x00}; /* HerzHi */ if (start) { error=DCT3_EnableSecurity (s, 0x01); if (error!=ERR_NONE) return error; } /* For Herz==255*255 we have silent */ if (Herz!=255*255) { req[3]=Volume; req[5]=Herz%256; req[4]=Herz/256; } else { req[3]=0; req[5]=0; req[4]=0; } return GSM_WaitFor (s, req, 6, 0x40, 4, ID_PlayTone); } #ifdef GSM_ENABLE_CELLBROADCAST GSM_Error DCT3_ReplyIncomingCB(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_CBMessage CB; int i; char Buffer[300]; smprintf(s, "CB received\n"); CB.Channel = msg.Buffer[7]; i = GSM_UnpackEightBitsToSeven(0, msg.Buffer[9], msg.Buffer[9], msg.Buffer+10, Buffer); i = msg.Buffer[9] - 1; while (i!=0) { if (Buffer[i] == 13) i = i - 1; else break; } DecodeDefault(CB.Text, Buffer, i + 1, false, NULL); smprintf(s, "Channel %i, text \"%s\"\n",CB.Channel,DecodeUnicodeString(CB.Text)); if (s->Phone.Data.EnableIncomingCB && s->User.IncomingCB!=NULL) { s->User.IncomingCB(s->CurrentConfig->Device,CB); } return ERR_NONE; } GSM_Error DCT3_ReplySetIncomingCB(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x21: smprintf(s, "CB set\n"); return ERR_NONE; case 0x22: smprintf(s, "CB not set\n"); return ERR_UNKNOWN; case 0xCA: smprintf(s, "No network and no CB\n"); return ERR_SECURITYERROR; } return ERR_UNKNOWNRESPONSE; } #endif GSM_Error DCT3_SetIncomingCB(GSM_StateMachine *s, bool enable) { #ifdef GSM_ENABLE_CELLBROADCAST unsigned char reqOn[] = {N6110_FRAME_HEADER, 0x20, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01}; unsigned char reqOff[] = {N6110_FRAME_HEADER, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (s->Phone.Data.EnableIncomingCB!=enable) { s->Phone.Data.EnableIncomingCB = enable; if (enable) { smprintf(s, "Enabling incoming CB\n"); return GSM_WaitFor(s, reqOn, 10, 0x02, 4, ID_SetIncomingCB); } else { smprintf(s, "Disabling incoming CB\n"); return GSM_WaitFor(s, reqOff, 10, 0x02, 4, ID_SetIncomingCB); } } return ERR_NONE; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error DCT3_ReplySetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "SMSC set\n"); return ERR_NONE; } GSM_Error DCT3_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) { unsigned char req[100] = {N6110_FRAME_HEADER, 0x30, 0x64}; memset(req+6,100-6,0); /* SMSC location */ req[5] = smsc->Location; /* SMSC format */ switch (smsc->Format) { case SMS_FORMAT_Text : req[7] = 0x00; break; case SMS_FORMAT_Fax : req[7] = 0x22; break; case SMS_FORMAT_Pager : req[7] = 0x26; break; case SMS_FORMAT_Email : req[7] = 0x32; break; } /* SMS validity */ req[9] = smsc->Validity.Relative; /* Default number for SMS messages */ req[10] = GSM_PackSemiOctetNumber(smsc->DefaultNumber, req+11, true); /* SMSC number */ req[22] = GSM_PackSemiOctetNumber(smsc->Number, req+23, false); /* SMSC name */ memcpy(req + 34, DecodeUnicodeString(smsc->Name),UnicodeLength(smsc->Name)); smprintf(s, "Setting SMSC\n"); return GSM_WaitFor (s, req, 35+UnicodeLength(smsc->Name), 0x02, 4, ID_SetSMSC); } GSM_Error DCT3_ReplyEnableSecurity(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "State of security commands set\n"); return ERR_NONE; } /* If you set make some things (for example, change Security Code from * phone's menu, disable and enable phone), it won't answer for 0x40 frames * and you won't be able to play tones, get netmonitor, etc. * This function do thing called "Enabling extended security commands" * and it enables 0x40 frame functions. * This frame can also some other things - see below */ GSM_Error DCT3_EnableSecurity (GSM_StateMachine *s, unsigned char status) { unsigned char req[] = {0x00, 0x01, 0x64, 0x01}; /* 0x00/0x01 - off/on, * 0x03/0x04 - soft/hard reset, * 0x06 - CONTACT SERVICE */ /* 0x06 MAKES CONTACT SERVICE! BE CAREFULL! */ /* When use 0x03 and had during session changed time & date * some phones (like 6150 or 6210) can ask for time & date after reset * or disable clock on the screen */ if (status!=0x06) req[3] = status; smprintf(s, "Setting state of security commands\n"); return GSM_WaitFor (s, req, 4, 0x40, 4, ID_EnableSecurity); } GSM_Error DCT3_ReplyGetIMEI(GSM_Protocol_Message msg, GSM_StateMachine *s) { memcpy(s->Phone.Data.IMEI,msg.Buffer + 4, 16); smprintf(s, "Received IMEI %s\n",s->Phone.Data.IMEI); return ERR_NONE; } GSM_Error DCT3_GetIMEI (GSM_StateMachine *s) { unsigned char req[] = {0x00, 0x01, 0x66, 0x00}; GSM_Error error; if (strlen(s->Phone.Data.IMEI)!=0) return ERR_NONE; error=DCT3_EnableSecurity (s, 0x01); if (error!=ERR_NONE) return error; smprintf(s, "Getting IMEI\n"); return GSM_WaitFor (s, req, 4, 0x40, 2, ID_GetIMEI); } GSM_Error DCT3_ReplySIMLogin(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Login for SIM card\n"); return ERR_NONE; } GSM_Error DCT3_ReplySIMLogout(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Logout for SIM card\n"); return ERR_NONE; } GSM_Error DCT3_ReplyGetDateTime(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Date & time received\n"); if (msg.Buffer[4]==0x01) { NOKIA_DecodeDateTime(s, msg.Buffer+8, s->Phone.Data.DateTime); return ERR_NONE; } smprintf(s, "Not set in phone\n"); return ERR_EMPTY; } GSM_Error DCT3_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time, unsigned char msgtype) { unsigned char req[] = {N6110_FRAME_HEADER, 0x62}; s->Phone.Data.DateTime=date_time; smprintf(s, "Getting date & time\n"); return GSM_WaitFor (s, req, 4, msgtype, 4, ID_GetDateTime); } GSM_Error DCT3_ReplyGetAlarm(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Alarm: "); if (msg.Buffer[8]==0x02) { smprintf(s, "set to %02i:%02i\n", msg.Buffer[9], msg.Buffer[10]); Data->Alarm->Repeating = true; Data->Alarm->Text[0] = 0; Data->Alarm->Text[1] = 0; Data->Alarm->DateTime.Hour = msg.Buffer[9]; Data->Alarm->DateTime.Minute = msg.Buffer[10]; Data->Alarm->DateTime.Second = 0; return ERR_NONE; } smprintf(s, "not set\n"); return ERR_EMPTY; } GSM_Error DCT3_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm, unsigned char msgtype) { unsigned char req[] = {N6110_FRAME_HEADER, 0x6d}; if (alarm->Location!=1) return ERR_NOTSUPPORTED; s->Phone.Data.Alarm=alarm; smprintf(s, "Getting alarm\n"); return GSM_WaitFor (s, req, 4, msgtype, 4, ID_GetAlarm); } GSM_Error DCT3_ReplySetDateTime(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Date & time: "); if (msg.Buffer[4]==0x01) { smprintf(s, "set OK\n"); return ERR_NONE; } smprintf(s, "error setting\n"); return ERR_UNKNOWN; } GSM_Error DCT3_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time, unsigned char msgtype) { unsigned char req[] = {N6110_FRAME_HEADER, 0x60, 0x01, 0x01, 0x07, 0x00, 0x00, /* Year */ 0x00, /* Month */ 0x00, /* Day */ 0x00, /* Hour */ 0x00, /* Minute */ 0x00}; /* Unknown. Not seconds */ NOKIA_EncodeDateTime(s, req+7, date_time); smprintf(s, "Setting date & time\n"); return GSM_WaitFor (s, req, 14, msgtype, 4, ID_SetDateTime); } GSM_Error DCT3_ReplySetAlarm(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Alarm: "); if (msg.Buffer[4]==0x01) { smprintf(s, "set OK\n"); return ERR_NONE; } smprintf(s, "error setting\n"); return ERR_UNKNOWN; } GSM_Error DCT3_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm, unsigned char msgtype) { unsigned char req[] = {N6110_FRAME_HEADER, 0x6b, 0x01, 0x20, 0x03, 0x02, /* Unknown. Not for enabling/disabling */ 0x00, /* Hour */ 0x00, /* Minute */ 0x00}; /* Unknown. Not seconds */ if (alarm->Location != 1) return ERR_NOTSUPPORTED; req[8] = alarm->DateTime.Hour; req[9] = alarm->DateTime.Minute; smprintf(s, "Setting alarm\n"); return GSM_WaitFor (s, req, 11, msgtype, 4, ID_SetAlarm); } GSM_Error DCT3_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x34: smprintf(s, "SMSC received\n"); Data->SMSC->Format = SMS_FORMAT_Text; switch (msg.Buffer[6]) { case 0x00: Data->SMSC->Format = SMS_FORMAT_Text; break; case 0x22: Data->SMSC->Format = SMS_FORMAT_Fax; break; case 0x26: Data->SMSC->Format = SMS_FORMAT_Pager; break; case 0x32: Data->SMSC->Format = SMS_FORMAT_Email; break; } Data->SMSC->Validity.Format = SMS_Validity_RelativeFormat; Data->SMSC->Validity.Relative = msg.Buffer[8]; if (msg.Buffer[8] == 0x00) Data->SMSC->Validity.Relative = SMS_VALID_Max_Time; i=33; while (msg.Buffer[i]!=0) {i++;} i=i-33; if (i>GSM_MAX_SMSC_NAME_LENGTH) { smprintf(s, "Too long name\n"); return ERR_UNKNOWNRESPONSE; } EncodeUnicode(Data->SMSC->Name,msg.Buffer+33,i); smprintf(s, "Name \"%s\"\n", DecodeUnicodeString(Data->SMSC->Name)); GSM_UnpackSemiOctetNumber(Data->SMSC->DefaultNumber,msg.Buffer+9,true); smprintf(s, "Default number \"%s\"\n", DecodeUnicodeString(Data->SMSC->DefaultNumber)); GSM_UnpackSemiOctetNumber(Data->SMSC->Number,msg.Buffer+21,false); smprintf(s, "Number \"%s\"\n", DecodeUnicodeString(Data->SMSC->Number)); return ERR_NONE; case 0x35: smprintf(s, "Getting SMSC failed\n"); return ERR_INVALIDLOCATION; } return ERR_UNKNOWNRESPONSE; } GSM_Error DCT3_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) { unsigned char req[] = {N6110_FRAME_HEADER, 0x33, 0x64, 0x00}; /* Location */ if (smsc->Location==0x00) return ERR_INVALIDLOCATION; req[5]=smsc->Location; s->Phone.Data.SMSC=smsc; smprintf(s, "Getting SMSC\n"); return GSM_WaitFor (s, req, 6, 0x02, 4, ID_GetSMSC); } GSM_Error DCT3_ReplyGetNetworkInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int count; GSM_Phone_Data *Data = &s->Phone.Data; #ifdef DEBUG GSM_NetworkInfo NetInfo; char name[100]; smprintf(s, "Network info received\n"); smprintf(s, "Status : "); switch (msg.Buffer[8]) { case 0x01: smprintf(s, "home network"); break; case 0x02: smprintf(s, "roaming network"); break; case 0x03: smprintf(s, "requesting network"); break; case 0x04: smprintf(s, "not registered in the network"); break; default : smprintf(s, "unknown"); } smprintf(s, "\n"); smprintf(s, "Network selection : %s\n", msg.Buffer[9]==1?"manual":"automatic"); if (msg.Buffer[8]<0x03) { - sprintf(NetInfo.CID, "%02x%02x", msg.Buffer[10], msg.Buffer[11]); + sprintf(NetInfo.CID, "%02X%02X", msg.Buffer[10], msg.Buffer[11]); smprintf(s, "CID : %s\n", NetInfo.CID); - sprintf(NetInfo.LAC, "%02x%02x", msg.Buffer[12], msg.Buffer[13]); + sprintf(NetInfo.LAC, "%02X%02X", msg.Buffer[12], msg.Buffer[13]); smprintf(s, "LAC : %s\n", NetInfo.LAC); NOKIA_DecodeNetworkCode(msg.Buffer+14,NetInfo.NetworkCode); smprintf(s, "Network code : %s\n", NetInfo.NetworkCode); smprintf(s, "Network name for Gammu : %s ", DecodeUnicodeString(GSM_GetNetworkName(NetInfo.NetworkCode))); smprintf(s, "(%s)\n",DecodeUnicodeString(GSM_GetCountryName(NetInfo.NetworkCode))); if (msg.Length>18) { if (msg.Buffer[18]==0x00) { /* In 6210 name is in "normal" Unicode */ memcpy(name,msg.Buffer+18,msg.Buffer[17]*2); name[msg.Buffer[17]*2] =0x00; name[msg.Buffer[17]*2+1]=0x00; smprintf(s, "Network name for phone : %s\n",DecodeUnicodeString(name)); } else { /* In 9210 first 0x00 is cut from Unicode string */ name[0] = 0; memcpy(name+1,msg.Buffer+18,msg.Buffer[17]*2); name[msg.Buffer[17]*2+1]=0x00; name[msg.Buffer[17]*2+2]=0x00; smprintf(s, "Network name for phone : %s\n",DecodeUnicodeString(name)); } } } #endif if (Data->RequestID==ID_GetNetworkInfo) { Data->NetworkInfo->NetworkName[0] = 0x00; Data->NetworkInfo->NetworkName[1] = 0x00; Data->NetworkInfo->State = 0; switch (msg.Buffer[8]) { case 0x01: Data->NetworkInfo->State = GSM_HomeNetwork; break; case 0x02: Data->NetworkInfo->State = GSM_RoamingNetwork; break; case 0x03: Data->NetworkInfo->State = GSM_RequestingNetwork; break; case 0x04: Data->NetworkInfo->State = GSM_NoNetwork; break; } if (Data->NetworkInfo->State == GSM_HomeNetwork || Data->NetworkInfo->State == GSM_RoamingNetwork) { if (msg.Buffer[18]==0x00) { /* In 6210 name is in "normal" Unicode */ memcpy(Data->NetworkInfo->NetworkName,msg.Buffer+18,msg.Buffer[17]*2); Data->NetworkInfo->NetworkName[msg.Buffer[17]*2] = 0x00; Data->NetworkInfo->NetworkName[msg.Buffer[17]*2+1] = 0x00; } else { /* In 9210 first 0x00 is cut from Unicode string */ Data->NetworkInfo->NetworkName[0] = 0; memcpy(Data->NetworkInfo->NetworkName+1,msg.Buffer+18,msg.Buffer[17]*2); Data->NetworkInfo->NetworkName[msg.Buffer[17]*2+1]=0x00; Data->NetworkInfo->NetworkName[msg.Buffer[17]*2+2]=0x00; } NOKIA_DecodeNetworkCode(msg.Buffer+14,Data->NetworkInfo->NetworkCode); - sprintf(Data->NetworkInfo->CID, "%02x%02x", msg.Buffer[10], msg.Buffer[11]); - sprintf(Data->NetworkInfo->LAC, "%02x%02x", msg.Buffer[12], msg.Buffer[13]); + sprintf(Data->NetworkInfo->CID, "%02X%02X", msg.Buffer[10], msg.Buffer[11]); + sprintf(Data->NetworkInfo->LAC, "%02X%02X", msg.Buffer[12], msg.Buffer[13]); } } /* 6210/6250/7110 */ if (Data->RequestID==ID_GetBitmap) { if (msg.Buffer[4]==0x02) { smprintf(s, "Operator logo available\n"); count = 7; /* skip network info */ count += msg.Buffer[count]; count ++; Data->Bitmap->BitmapWidth = msg.Buffer[count++]; Data->Bitmap->BitmapHeight = msg.Buffer[count++]; count+=4; PHONE_DecodeBitmap(GSM_Nokia7110OperatorLogo,msg.Buffer+count,Data->Bitmap); NOKIA_DecodeNetworkCode(msg.Buffer+14,Data->Bitmap->NetworkCode); } else { Data->Bitmap->BitmapWidth = 78; Data->Bitmap->BitmapHeight = 21; GSM_ClearBitmap(Data->Bitmap); strcpy(Data->Bitmap->NetworkCode,"000 00"); } } return ERR_NONE; } GSM_Error DCT3_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo) { unsigned char req[] = {N6110_FRAME_HEADER, 0x70}; s->Phone.Data.NetworkInfo=netinfo; smprintf(s, "Getting network info\n"); return GSM_WaitFor (s, req, 4, 0x0a, 4, ID_GetNetworkInfo); } GSM_Error DCT3_ReplyDialCommand(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Answer for call commands\n"); return ERR_NONE; } GSM_Error DCT3_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber) { unsigned int i = 0; GSM_Error error; unsigned char req[100] = {0x00, 0x01, 0x7c, 0x01}; /* call command */ if (ShowNumber != GSM_CALL_DefaultNumberPresence) return ERR_NOTSUPPORTED; error=DCT3_EnableSecurity (s, 0x01); if (error!=ERR_NONE) return error; for (i=0; i < strlen(number); i++) req[4+i]=number[i]; req[4+i+1]=0; smprintf(s, "Making voice call\n"); return GSM_WaitFor (s, req, 4+strlen(number)+1, 0x40, 4, ID_DialVoice); } static GSM_Error DCT3_CancelAllCalls(GSM_StateMachine *s) { GSM_Error error; unsigned char req[] = {0x00, 0x01, 0x7c, 0x03}; /* call command */ error=DCT3_EnableSecurity (s, 0x01); if (error!=ERR_NONE) return error; smprintf(s, "Canceling calls\n"); return GSM_WaitFor (s, req, 4, 0x40, 4, ID_CancelCall); } GSM_Error DCT3_CancelCall(GSM_StateMachine *s, int ID, bool all) { if (!all) return DCT3DCT4_CancelCall(s,ID); return DCT3_CancelAllCalls(s); } GSM_Error DCT3_AnswerAllCalls(GSM_StateMachine *s) { GSM_Error error; unsigned char req[] = {0x00, 0x01, 0x7c, 0x02}; /* call command */ error=DCT3_EnableSecurity (s, 0x01); if (error!=ERR_NONE) return error; smprintf(s, "Answering calls\n"); return GSM_WaitFor (s, req, 4, 0x40, 4, ID_AnswerCall); } GSM_Error DCT3_Reset(GSM_StateMachine *s, bool hard) { GSM_Error error; if (hard) { error=DCT3_EnableSecurity(s, 0x04); } else { error=DCT3_EnableSecurity(s, 0x03); } if (error == ERR_NONE) { s->Phone.Data.EnableIncomingSMS = false; s->Phone.Data.EnableIncomingCB = false; } return error; } GSM_Error DCT3_ReplyGetWAPBookmark(GSM_Protocol_Message msg, GSM_StateMachine *s) { return DCT3DCT4_ReplyGetWAPBookmark (msg,s,false); } GSM_Error DCT3_SetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark) { GSM_Error error; int count = 4, location; unsigned char req[600] = {N6110_FRAME_HEADER, 0x09}; /* We have to enable WAP frames in phone */ error=DCT3DCT4_EnableWAPFunctions(s); if (error!=ERR_NONE) return error; location = bookmark->Location - 1; if (bookmark->Location == 0) location = 0xffff; req[count++] = (location & 0xff00) >> 8; req[count++] = location & 0x00ff; count += NOKIA_SetUnicodeString(s, req+count, bookmark->Title, false); count += NOKIA_SetUnicodeString(s, req+count, bookmark->Address, false); /* unknown */ req[count++] = 0x01; req[count++] = 0x80; req[count++] = 0x00; req[count++] = 0x00; req[count++] = 0x00; req[count++] = 0x00; req[count++] = 0x00; req[count++] = 0x00; req[count++] = 0x00; smprintf(s, "Setting WAP bookmark\n"); error = GSM_WaitFor (s, req, count, 0x3f, 4, ID_SetWAPBookmark); if (error != ERR_NONE) { if (error == ERR_INSIDEPHONEMENU || error == ERR_EMPTY || error == ERR_FULL) { DCT3DCT4_DisableConnectionFunctions(s); } return error; } return DCT3DCT4_DisableConnectionFunctions(s); } GSM_Error DCT3_ReplyGetWAPSettings(GSM_Protocol_Message msg, GSM_StateMachine *s) { int tmp,Number; // int tmp2; GSM_Phone_Data *Data = &s->Phone.Data; #ifdef GSM_ENABLE_NOKIA6110 GSM_Phone_N6110Data *Priv6110 = &s->Phone.Data.Priv.N6110; #endif #ifdef GSM_ENABLE_NOKIA7110 GSM_Phone_N7110Data *Priv7110 = &s->Phone.Data.Priv.N7110; #endif switch(msg.Buffer[3]) { case 0x16: smprintf(s, "WAP settings part 1 received OK\n"); tmp = 4; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].Title,false); smprintf(s, "Title: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Title)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].HomePage,false); smprintf(s, "Homepage: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].HomePage)); #ifdef DEBUG smprintf(s, "Connection type: "); switch (msg.Buffer[tmp]) { case 0x00: smprintf(s, "temporary\n"); break; case 0x01: smprintf(s, "continuous\n"); break; default: smprintf(s, "unknown\n"); } smprintf(s, "Connection security: "); switch (msg.Buffer[tmp+13]) { case 0x00: smprintf(s, "off\n"); break; case 0x01: smprintf(s, "on\n"); break; default: smprintf(s, "unknown\n"); } #endif Data->WAPSettings->Settings[0].IsContinuous = false; if (msg.Buffer[tmp] == 0x01) Data->WAPSettings->Settings[0].IsContinuous = true; Data->WAPSettings->Settings[0].IsSecurity = false; if (msg.Buffer[tmp+13] == 0x01) Data->WAPSettings->Settings[0].IsSecurity = true; /* I'm not sure here. Experimental values from 6210 5.56 */ // tmp2 = DecodeUnicodeLength(Data->WAPSettings->Settings[0].Title); // if (tmp2 != 0) tmp2 --; // tmp2 += tmp; if (!(UnicodeLength(Data->WAPSettings->Settings[0].Title)) % 2) tmp++; if (UnicodeLength(Data->WAPSettings->Settings[0].HomePage)!=0) tmp++; smprintf(s, "ID for writing %i\n",msg.Buffer[tmp+5]); smprintf(s, "Current set location in phone %i\n",msg.Buffer[tmp+6]); smprintf(s, "1 location %i\n",msg.Buffer[tmp+8]); smprintf(s, "2 location %i\n",msg.Buffer[tmp+9]); smprintf(s, "3 location %i\n",msg.Buffer[tmp+10]); smprintf(s, "4 location %i\n",msg.Buffer[tmp+11]); #ifdef GSM_ENABLE_NOKIA7110 if (strstr(N7110Phone.models, Data->ModelInfo->model) != NULL) { Priv7110->WAPLocations.ID = msg.Buffer[tmp+5]; Priv7110->WAPLocations.CurrentLocation = msg.Buffer[tmp+6]; Priv7110->WAPLocations.Locations[0] = msg.Buffer[tmp+8]; Priv7110->WAPLocations.Locations[1] = msg.Buffer[tmp+9]; Priv7110->WAPLocations.Locations[2] = msg.Buffer[tmp+10]; Priv7110->WAPLocations.Locations[3] = msg.Buffer[tmp+11]; // Priv7110->WAPLocations.CurrentLocation = msg.Buffer[tmp2+1]; // Priv7110->WAPLocations.Locations[0] = msg.Buffer[tmp2+3]; // Priv7110->WAPLocations.Locations[1] = msg.Buffer[tmp2+4]; // Priv7110->WAPLocations.Locations[2] = msg.Buffer[tmp2+5]; // Priv7110->WAPLocations.Locations[3] = msg.Buffer[tmp2+6]; } #endif #ifdef GSM_ENABLE_NOKIA6110 if (strstr(N6110Phone.models, Data->ModelInfo->model) != NULL) { Priv6110->WAPLocations.ID = msg.Buffer[tmp+5]; Priv6110->WAPLocations.CurrentLocation = msg.Buffer[tmp+6]; Priv6110->WAPLocations.Locations[0] = msg.Buffer[tmp+8]; Priv6110->WAPLocations.Locations[1] = msg.Buffer[tmp+9]; Priv6110->WAPLocations.Locations[2] = msg.Buffer[tmp+10]; Priv6110->WAPLocations.Locations[3] = msg.Buffer[tmp+11]; } #endif return ERR_NONE; case 0x17: smprintf(s, "WAP settings part 1 receiving error\n"); switch (msg.Buffer[4]) { case 0x01: smprintf(s, "Security error. Inside WAP settings menu\n"); return ERR_INSIDEPHONEMENU; case 0x02: smprintf(s, "Invalid or empty\n"); return ERR_INVALIDLOCATION; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } break; case 0x1c: smprintf(s, "WAP settings part 2 received OK\n"); Number = Data->WAPSettings->Number; switch (msg.Buffer[5]) { case 0x00: Data->WAPSettings->Settings[Number].Bearer = WAPSETTINGS_BEARER_SMS; smprintf(s, "Settings for SMS bearer:\n"); tmp = 6; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].Service,false); smprintf(s, "Service number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Service)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].Server,false); smprintf(s, "Server number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Server)); break; case 0x01: Data->WAPSettings->Settings[Number].Bearer = WAPSETTINGS_BEARER_DATA; smprintf(s, "Settings for data bearer:\n"); Data->WAPSettings->Settings[Number].ManualLogin = false; tmp = 10; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].IPAddress,false); smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].IPAddress)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].DialUp,false); smprintf(s, "Dial-up number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].DialUp)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].User,false); smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].User)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].Password,false); smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Password)); #ifdef DEBUG smprintf(s, "Authentication type: "); switch (msg.Buffer[6]) { case 0x00: smprintf(s, "normal\n"); break; case 0x01: smprintf(s, "secure\n"); break; default: smprintf(s, "unknown\n"); break; } smprintf(s, "Data call type: "); switch (msg.Buffer[7]) { case 0x00: smprintf(s, "analogue\n"); break; case 0x01: smprintf(s, "ISDN\n"); break; default: smprintf(s, "unknown\n"); break; } smprintf(s, "Data call speed: "); switch (msg.Buffer[9]) { case 0x01: smprintf(s, "9600\n"); break; case 0x02: smprintf(s, "14400\n"); break; default: smprintf(s, "unknown\n"); break; } #endif Data->WAPSettings->Settings[Number].IsNormalAuthentication=true; if (msg.Buffer[6]==0x01) Data->WAPSettings->Settings[Number].IsNormalAuthentication=false; Data->WAPSettings->Settings[Number].IsISDNCall=false; if (msg.Buffer[7]==0x01) Data->WAPSettings->Settings[Number].IsISDNCall=true; Data->WAPSettings->Settings[Number].Speed = WAPSETTINGS_SPEED_9600; if (msg.Buffer[9]==0x02) Data->WAPSettings->Settings[Number].Speed = WAPSETTINGS_SPEED_14400; break; case 0x02: Data->WAPSettings->Settings[Number].Bearer=WAPSETTINGS_BEARER_USSD; smprintf(s, "Settings for USSD bearer:\n"); tmp = 7; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].Service,false); #ifdef DEBUG if (msg.Buffer[6]==0x01) smprintf(s, "Service number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Service)); else smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Service)); #endif Data->WAPSettings->Settings[Number].IsIP=true; if (msg.Buffer[6]==0x01) Data->WAPSettings->Settings[Number].IsIP=false; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].Code,false); smprintf(s, "Service code: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Code)); } Data->WAPSettings->Number++; return ERR_NONE; case 0x1d: smprintf(s, "Incorrect WAP settings location\n"); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } GSM_Error DCT3_GetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings) { #ifdef GSM_ENABLE_NOKIA6110 GSM_Phone_N6110Data *Priv6110 = &s->Phone.Data.Priv.N6110; #endif #ifdef GSM_ENABLE_NOKIA7110 GSM_Phone_N7110Data *Priv7110 = &s->Phone.Data.Priv.N7110; #endif GSM_Error error; int i; unsigned char req[] = {N6110_FRAME_HEADER,0x15, 0x00}; /* Location */ unsigned char req2[] = {N6110_FRAME_HEADER,0x1b, 0x00}; /* Location */ /* We have to enable WAP frames in phone */ error=DCT3DCT4_EnableWAPFunctions(s); if (error!=ERR_NONE) return error; s->Phone.Data.WAPSettings = settings; settings->Number = 0; settings->ReadOnly = false; req[4] = settings->Location-1; smprintf(s, "Getting WAP settings part 1\n"); error = GSM_WaitFor (s, req, 5, 0x3f, 4, ID_GetConnectSet); if (error != ERR_NONE) return error; #ifdef GSM_ENABLE_NOKIA7110 if (strstr(N7110Phone.models, s->Phone.Data.ModelInfo->model) != NULL) { for (i=0;i<4;i++) { req2[4] = Priv7110->WAPLocations.Locations[i]; smprintf(s, "Getting WAP settings part 2\n"); error=GSM_WaitFor (s, req2, 5, 0x3f, 4, ID_GetConnectSet); if (error != ERR_NONE) return error; if (Priv7110->WAPLocations.Locations[i] == Priv7110->WAPLocations.CurrentLocation) { settings->ActiveBearer = settings->Settings[settings->Number-1].Bearer; } } } #endif #ifdef GSM_ENABLE_NOKIA6110 if (strstr(N6110Phone.models, s->Phone.Data.ModelInfo->model) != NULL) { for (i=0;i<4;i++) { req2[4] = Priv6110->WAPLocations.Locations[i]; smprintf(s, "Getting WAP settings part 2\n"); error=GSM_WaitFor (s, req2, 5, 0x3f, 4, ID_GetConnectSet); if (error != ERR_NONE) return error; if (Priv6110->WAPLocations.Locations[i] == Priv6110->WAPLocations.CurrentLocation) { settings->ActiveBearer = settings->Settings[settings->Number-1].Bearer; } } } #endif if (error == ERR_NONE) { for (i=1;i<3;i++) { CopyUnicodeString(settings->Settings[i].Title,settings->Settings[0].Title); CopyUnicodeString(settings->Settings[i].HomePage,settings->Settings[0].HomePage); settings->Settings[i].IsContinuous = settings->Settings[0].IsContinuous; settings->Settings[i].IsSecurity = settings->Settings[0].IsSecurity; settings->Settings[i].IsContinuous = settings->Settings[0].IsContinuous; settings->Settings[i].IsSecurity = settings->Settings[0].IsSecurity; } error = DCT3DCT4_GetActiveConnectSet(s); } if (error != ERR_NONE) return error; settings->Proxy[0] = 0x00; settings->Proxy[1] = 0x00; settings->ProxyPort = 8080; settings->Proxy2[0] = 0x00; settings->Proxy2[1] = 0x00; settings->Proxy2Port = 8080; return DCT3DCT4_DisableConnectionFunctions(s); } GSM_Error DCT3_ReplySetWAPSettings(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch(msg.Buffer[3]) { case 0x19: smprintf(s, "WAP settings part 1 set OK\n"); return ERR_NONE; case 0x1a: smprintf(s, "WAP settings part 1 setting error\n"); switch (msg.Buffer[4]) { case 0x01: smprintf(s, "Security error. Inside WAP settings menu\n"); return ERR_INSIDEPHONEMENU; case 0x02: smprintf(s, "Incorrect data\n"); return ERR_UNKNOWN; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } case 0x1F: smprintf(s, "WAP settings part 2 set OK\n"); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } GSM_Error DCT3_SetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings) { #ifdef GSM_ENABLE_NOKIA6110 GSM_Phone_N6110Data *Priv6110 = &s->Phone.Data.Priv.N6110; #endif #ifdef GSM_ENABLE_NOKIA7110 GSM_Phone_N7110Data *Priv7110 = &s->Phone.Data.Priv.N7110; #endif GSM_Error error; GSM_MultiWAPSettings settings2; int i,pos,phone1=-1,phone2=-1,phone3=-1; int ID=0,locations[4],loc1=-1,loc2=-1,loc3=-1; unsigned char req[] = {N6110_FRAME_HEADER,0x15, 0x00}; /* Location */ unsigned char req2[] = {N6110_FRAME_HEADER,0x1b, 0x00}; /* Location */ unsigned char SetReq[200] = {N7110_FRAME_HEADER, 0x18, 0x00}; /* Location */ unsigned char SetReq2[200] = {N7110_FRAME_HEADER, 0x1e, 0x00}; /* Location */ /* We have to enable WAP frames in phone */ error=DCT3DCT4_EnableWAPFunctions(s); if (error!=ERR_NONE) return error; s->Phone.Data.WAPSettings = &settings2; settings2.Number = 0; req[4] = settings->Location-1; smprintf(s, "Getting WAP settings part 1\n"); error = GSM_WaitFor (s, req, 6, 0x3f, 4, ID_GetConnectSet); if (error != ERR_NONE) return error; #ifdef GSM_ENABLE_NOKIA6110 if (strstr(N6110Phone.models, s->Phone.Data.ModelInfo->model) != NULL) { for (i=0;i<4;i++) locations[i] = Priv6110->WAPLocations.Locations[i]; ID = Priv6110->WAPLocations.ID; } #endif #ifdef GSM_ENABLE_NOKIA7110 if (strstr(N7110Phone.models, s->Phone.Data.ModelInfo->model) != NULL) { for (i=0;i<4;i++) locations[i] = Priv7110->WAPLocations.Locations[i]; ID = Priv7110->WAPLocations.ID; } #endif /* Now we get info about supported types by phone and their locations */ for (i=0;i<4;i++) { settings2.Number = 0; settings2.Settings[0].Bearer = 0; req2[4] = locations[i]; smprintf(s, "Getting WAP settings part 2\n"); error=GSM_WaitFor (s, req2, 6, 0x3f, 4, ID_GetConnectSet); if (error != ERR_NONE) return error; switch (settings2.Settings[0].Bearer) { case WAPSETTINGS_BEARER_DATA: phone1 = locations[i]; break; case WAPSETTINGS_BEARER_SMS : phone2 = locations[i]; break; case WAPSETTINGS_BEARER_USSD: phone3 = locations[i]; break; default : break; } if (error != ERR_NONE) return error; } /* We have some phone locations and some data to set. We try to * find info about locations in phone used to write concrete bearers */ for (i=0;i<settings->Number;i++) { if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_DATA) { if (phone1 != -1) loc1=i; } if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_SMS) { if (phone2 != -1) loc2=i; } if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_USSD) { if (phone3 != -1) loc3=i; } } pos = 5; memset(SetReq + pos, 0, 200 - pos); SetReq[4] = settings->Location - 1; if (loc1 != -1) { /* Name */ pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc1].Title, false); /* HomePage */ pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc1].HomePage, false); if (settings->Settings[loc1].IsContinuous) SetReq[pos] = 0x01; pos++; SetReq[pos++] = ID; SetReq[pos] = phone1; /* bearer */ switch (settings->ActiveBearer) { case WAPSETTINGS_BEARER_DATA: if (loc1 != -1) SetReq[pos] = phone1; break; case WAPSETTINGS_BEARER_SMS: if (loc2 != -1) SetReq[pos] = phone2; break; case WAPSETTINGS_BEARER_USSD: if (loc3 != -1) SetReq[pos] = phone3; break; default: break; } pos++; if (settings->Settings[loc1].IsSecurity) SetReq[pos] = 0x01; pos++; } else if (loc2 != -1) { /* Name */ pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc2].Title, false); /* HomePage */ pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc2].HomePage, false); if (settings->Settings[loc2].IsContinuous) SetReq[pos] = 0x01; pos++; SetReq[pos++] = ID; SetReq[pos] = phone2; /* bearer */ switch (settings->ActiveBearer) { case WAPSETTINGS_BEARER_DATA: if (loc1 != -1) SetReq[pos] = phone1; break; case WAPSETTINGS_BEARER_SMS: if (loc2 != -1) SetReq[pos] = phone2; break; case WAPSETTINGS_BEARER_USSD: if (loc3 != -1) SetReq[pos] = phone3; break; default: break; } pos++; if (settings->Settings[loc2].IsSecurity) SetReq[pos] = 0x01; pos++; } else if (loc3 != -1) { /* Name */ pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc3].Title, false); /* HomePage */ pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc3].HomePage, false); if (settings->Settings[loc3].IsContinuous) SetReq[pos] = 0x01; pos++; SetReq[pos++] = ID; SetReq[pos] = phone3; /* bearer */ switch (settings->ActiveBearer) { case WAPSETTINGS_BEARER_DATA: if (loc1 != -1) SetReq[pos] = phone1; break; case WAPSETTINGS_BEARER_SMS: if (loc2 != -1) SetReq[pos] = phone2; break; case WAPSETTINGS_BEARER_USSD: if (loc3 != -1) SetReq[pos] = phone3; break; default: break; } pos++; if (settings->Settings[loc3].IsSecurity) SetReq[pos] = 0x01; pos++; } else { return ERR_UNKNOWN; /* We have to have write something known */ } memcpy(SetReq + pos, "\x01\x80\x00\x00\x00\x00\x00\x00\x00", 9); pos += 9; smprintf(s, "Writing WAP settings part 1\n"); error=GSM_WaitFor (s, SetReq, pos, 0x3f, 4, ID_SetConnectSet); if (error != ERR_NONE) return error; /* Data */ if (phone1 != -1) { pos = 4; memset(SetReq2 + pos, 0, 200 - pos); SetReq2[pos++] = phone1; SetReq2[pos++] = 0x02; SetReq2[pos++] = 0x01; /* GSMdata */ if (loc1 != -1) { if (!settings->Settings[loc1].IsNormalAuthentication) SetReq2[pos] = 0x01; } pos++; if (loc1 != -1) { if (settings->Settings[loc1].IsISDNCall) SetReq2[pos] = 0x01; } pos++; if (loc1 != -1) { switch (settings->Settings[loc1].Speed) { case WAPSETTINGS_SPEED_9600 : SetReq2[pos++] = 0x01; break; case WAPSETTINGS_SPEED_14400 : SetReq2[pos++] = 0x02; break; default : SetReq2[pos++] = 0x02; break; } switch (settings->Settings[loc1].Speed) { case WAPSETTINGS_SPEED_9600 : SetReq2[pos++] = 0x01; break; case WAPSETTINGS_SPEED_14400 : SetReq2[pos++] = 0x02; break; default : SetReq2[pos++] = 0x02; break; } } else pos+=2; if (loc1 != -1) { /* IP */ pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc1].IPAddress, false); /* Number */ pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc1].DialUp, false); /* Username */ pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc1].User, false); /* Password */ pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc1].Password, false); } else pos+=5; memcpy(SetReq2 + pos, "\x80\x00\x00\x00\x00\x00\x00\x00", 8); pos += 8; smprintf(s, "Writing WAP settings part 2 (Data bearer)\n"); error=GSM_WaitFor (s, SetReq2, pos, 0x3f, 4, ID_SetConnectSet); if (error != ERR_NONE) return error; } /* SMS */ if (phone2 != -1) { pos = 4; memset(SetReq2 + pos, 0, 200 - pos); SetReq2[pos++] = phone2; SetReq2[pos++] = 0x02; SetReq2[pos++] = 0x00; /* SMS */ if (loc2 != -1) { /* Service number */ pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc2].Service, false); /* Server number */ pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc2].Server, false); } else pos += 2; memcpy(SetReq2 + pos, "\x80\x00\x00\x00\x00\x00\x00\x00", 8); pos += 8; smprintf(s, "Writing WAP settings part 2 (SMS bearer)\n"); error=GSM_WaitFor (s, SetReq2, pos, 0x3f, 4, ID_SetConnectSet); if (error != ERR_NONE) return error; } /* USSD */ if (phone3 != -1) { pos = 4; memset(SetReq2 + pos, 0, 200 - pos); SetReq2[pos++] = phone3; SetReq2[pos++] = 0x02; SetReq2[pos++] = 0x02; /* USSD */ if (loc3 != -1) { if (!settings->Settings[loc3].IsIP) SetReq2[pos] = 0x01; } pos++; if (loc3 != -1) { /* Service number or IP address */ pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc3].Service, false); /* Code number */ pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc3].Code, false); } else pos+=2; memcpy(SetReq2 + pos, "\x80\x00\x00\x00\x00\x00\x00\x00", 8); pos += 8; smprintf(s, "Writing WAP settings part 2 (USSD bearer)\n"); error=GSM_WaitFor (s, SetReq2, pos, 0x3f, 4, ID_SetConnectSet); if (error != ERR_NONE) return error; } error = DCT3DCT4_SetActiveConnectSet(s, settings); if (error != ERR_NONE) return error; return DCT3DCT4_DisableConnectionFunctions(s); } GSM_Error DCT3_ReplySendSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x02: smprintf(s, "SMS sent OK\n"); if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,0,msg.Buffer[5]); return ERR_NONE; case 0x03: smprintf(s, "Error %i\n",msg.Buffer[6]); if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,msg.Buffer[6],-1); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } GSM_Error DCT3_SendSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms) { int length; GSM_Error error; unsigned char req[256] = {N6110_FRAME_HEADER, 0x01, 0x02, 0x00}; error=PHONE_EncodeSMSFrame(s,sms,req+6,PHONE_SMSSubmit,&length, true); if (error != ERR_NONE) return error; smprintf(s, "Sending sms\n"); return s->Protocol.Functions->WriteMessage(s, req, 6+length, 0x02); } GSM_Error DCT3_ReplyNetmonitor(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x00: smprintf(s, "Netmonitor correctly set\n"); break; default: smprintf(s, "Menu %i\n",msg.Buffer[3]); smprintf(s, "%s\n",msg.Buffer+4); strcpy(s->Phone.Data.Netmonitor,msg.Buffer+4); break; } return ERR_NONE; } GSM_Error DCT3_Netmonitor(GSM_StateMachine *s, int testnumber, char *value) { GSM_Error error; unsigned char req[] = {0x00, 0x01, 0x7e, 0x00}; /* Test number */ value[0] = 0; error=DCT3_EnableSecurity (s, 0x01); if (error != ERR_NONE) return error; req[3] = testnumber; smprintf(s, "Getting netmonitor test\n"); s->Phone.Data.Netmonitor = value; return GSM_WaitFor (s, req, 4, 0x40, 4, ID_Netmonitor); } GSM_Error DCT3_GetManufactureMonth(GSM_StateMachine *s, char *value) { GSM_Error error; error=DCT3_EnableSecurity (s, 0x01); if (error != ERR_NONE) return error; return NOKIA_GetPhoneString(s,"\x00\x01\xCC\x02",4,0x40,value,ID_GetManufactureMonth,5); } GSM_Error DCT3_GetProductCode(GSM_StateMachine *s, char *value) { GSM_Error error; if (strlen(s->Phone.Data.ProductCodeCache)!=0) { strcpy(value,s->Phone.Data.ProductCodeCache); return ERR_NONE; } error=DCT3_EnableSecurity (s, 0x01); if (error != ERR_NONE) return error; return NOKIA_GetPhoneString(s,"\x00\x01\xCA\x01",4,0x40,value,ID_GetProductCode,5); } GSM_Error DCT3_GetOriginalIMEI(GSM_StateMachine *s, char *value) { GSM_Error error; error=DCT3_EnableSecurity (s, 0x01); if (error != ERR_NONE) return error; return NOKIA_GetPhoneString(s,"\x00\x01\xCC\x01",4,0x40,value,ID_GetOriginalIMEI,5); } GSM_Error DCT3_GetHardware(GSM_StateMachine *s, char *value) { GSM_Error error; if (strlen(s->Phone.Data.HardwareCache)!=0) { strcpy(value,s->Phone.Data.HardwareCache); return ERR_NONE; } error=DCT3_EnableSecurity (s, 0x01); if (error != ERR_NONE) return error; return NOKIA_GetPhoneString(s,"\x00\x01\xC8\x05",4,0x40,value,ID_GetHardware,5); } GSM_Error DCT3_GetPPM(GSM_StateMachine *s, char *value) { GSM_Error error; error=DCT3_EnableSecurity (s, 0x01); if (error != ERR_NONE) return error; return NOKIA_GetPhoneString(s,"\x00\x01\xC8\x12",4,0x40,value,ID_GetPPM,5); } GSM_Error DCT3_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status) { unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64}; s->Phone.Data.SMSStatus=status; smprintf(s, "Getting SMS status\n"); return GSM_WaitFor (s, req, 5, 0x14, 2, ID_GetSMSStatus); /* 6210 family doesn't show in frame with SMS status info * about Templates. We get separately info about this SMS folder. */ } GSM_Error DCT3_ReplyDeleteSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch(msg.Buffer[3]) { case 0x0b: smprintf(s, "SMS deleted\n"); return ERR_NONE; case 0x0c: smprintf(s, "Error deleting SMS\n"); switch (msg.Buffer[4]) { case 0x00: /* Not tested on 6210 */ smprintf(s, "Unknown meaning, SMS seems to be deleted\n"); return ERR_NONE; case 0x02: /* Not tested on 6210 */ smprintf(s, "Invalid location\n"); return ERR_INVALIDLOCATION; case 0x06: /* Not tested on 6210 */ smprintf(s, "Phone is OFF\n"); return ERR_PHONEOFF; default: smprintf(s, "Unknown error: %02x\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } } return ERR_UNKNOWNRESPONSE; } GSM_Error N71_92_ReplyGetSignalQuality(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Network level received: %i\n",msg.Buffer[4]); Data->SignalQuality->SignalStrength = -1; Data->SignalQuality->SignalPercent = ((int)msg.Buffer[4]); Data->SignalQuality->BitErrorRate = -1; return ERR_NONE; } GSM_Error N71_92_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig) { unsigned char req[] = {N6110_FRAME_HEADER, 0x81}; s->Phone.Data.SignalQuality = sig; smprintf(s, "Getting network level\n"); return GSM_WaitFor (s, req, 4, 0x0a, 4, ID_GetSignalQuality); } GSM_Error N71_92_ReplyGetBatteryCharge(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Battery level received: %i\n",msg.Buffer[5]); Data->BatteryCharge->BatteryPercent = ((int)msg.Buffer[5]); Data->BatteryCharge->ChargeState = 0; return ERR_NONE; } GSM_Error N71_92_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat) { unsigned char req[] = {N6110_FRAME_HEADER, 0x02}; s->Phone.Data.BatteryCharge = bat; smprintf(s, "Getting battery level\n"); return GSM_WaitFor (s, req, 4, 0x17, 4, ID_GetBatteryCharge); } GSM_Error N71_92_ReplyPhoneSetting(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Bitmap_Types BmpType; GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[4]) { case 0x02: if (Data->RequestID == ID_GetBitmap || Data->RequestID == ID_EachFrame) { smprintf(s, "Welcome note text received\n"); CopyUnicodeString(Data->Bitmap->Text,msg.Buffer+6); smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text)); return ERR_NONE; } if (Data->RequestID == ID_SetBitmap || Data->RequestID == ID_EachFrame) { smprintf(s, "Startup text set\n"); return ERR_NONE; } case 0x15: if (Data->RequestID == ID_GetBitmap || Data->RequestID == ID_EachFrame) { smprintf(s, "Startup logo received\n"); BmpType=GSM_Nokia7110StartupLogo; if (msg.Buffer[17]==0x60) BmpType=GSM_Nokia6210StartupLogo; if (msg.Buffer[17]==0xc0) BmpType=GSM_NokiaStartupLogo; PHONE_DecodeBitmap(BmpType, msg.Buffer+22, Data->Bitmap); return ERR_NONE; } if (Data->RequestID == ID_SetBitmap || Data->RequestID == ID_EachFrame) { smprintf(s, "Startup logo set\n"); return ERR_NONE; } case 0x17: if (Data->RequestID == ID_GetBitmap || Data->RequestID == ID_EachFrame) { smprintf(s, "Dealer note text received\n"); CopyUnicodeString(Data->Bitmap->Text,msg.Buffer+6); smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text)); return ERR_NONE; } if (Data->RequestID == ID_SetBitmap || Data->RequestID == ID_EachFrame) { smprintf(s, "Dealer text set\n"); return ERR_NONE; } } return ERR_UNKNOWNRESPONSE; } GSM_Error N71_92_GetPhoneSetting(GSM_StateMachine *s, int Request, int Setting) { unsigned char req[] = {N7110_FRAME_HEADER, 0xee, 0x1c}; /* Setting */ req[4]=Setting; return GSM_WaitFor (s, req, 5, 0x7a, 4, Request); } GSM_Error N71_92_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { return DCT3_GetDateTime(s, date_time, 0x19); } GSM_Error N71_92_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { return DCT3_SetDateTime(s, date_time, 0x19); } GSM_Error DCT3_DecodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *SMS, unsigned char *buffer) { switch (buffer[12] & 0x03) { case 0x00: smprintf(s, "SMS type - deliver\n"); SMS->PDU = SMS_Deliver; return GSM_DecodeSMSFrame(SMS,buffer,PHONE_SMSDeliver); case 0x01: smprintf(s, "SMS type - submit\n"); SMS->PDU = SMS_Submit; return GSM_DecodeSMSFrame(SMS,buffer,PHONE_SMSSubmit); case 0x02: smprintf(s, "SMS type - delivery report\n"); SMS->PDU = SMS_Status_Report; return GSM_DecodeSMSFrame(SMS,buffer,PHONE_SMSStatusReport); } return ERR_UNKNOWN; } GSM_Error N61_91_ReplySetOpLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x31: smprintf(s, "Operator logo set OK\n"); return ERR_NONE; case 0x32: smprintf(s, "Error setting operator logo\n"); switch (msg.Buffer[4]) { case 0x7d: smprintf(s, "Too high location ?\n"); return ERR_INVALIDLOCATION; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } } return ERR_UNKNOWNRESPONSE; } GSM_Error N61_71_ReplyResetPhoneSettings(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Phone settings cleaned OK\n"); return ERR_NONE; } GSM_Error N61_71_ResetPhoneSettings(GSM_StateMachine *s, GSM_ResetSettingsType Type) { GSM_Error error; unsigned char req[] = {0x00, 0x01, 0x65, 0x01}; /* Reset type */ switch (Type) { case GSM_RESET_PHONESETTINGS : req[3] = 0x01; break; case GSM_RESET_DEVICE : req[3] = 0x02; break; case GSM_RESET_USERINTERFACE : req[3] = 0x08; break; case GSM_RESET_USERINTERFACE_PHONESETTINGS : req[3] = 0x38; break; case GSM_RESET_FULLFACTORY : req[3] = 0xff; break; } error=DCT3_EnableSecurity (s, 0x01); if (error != ERR_NONE) return error; return GSM_WaitFor (s, req, 4, 0x40, 4, ID_ResetPhoneSettings); } #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/nokia/dct3/n0650.c b/gammu/emb/common/phone/nokia/dct3/n0650.c new file mode 100644 index 0000000..3899a16 --- a/dev/null +++ b/gammu/emb/common/phone/nokia/dct3/n0650.c @@ -0,0 +1,150 @@ +/* (c) 2004 by Marcin Wiacek */ + +#include <string.h> +#include <time.h> + +#include "../../../gsmcomon.h" +#include "../../../gsmstate.h" +#include "../nfunc.h" + +#ifdef GSM_ENABLE_NOKIA650 + +static GSM_Reply_Function N650ReplyFunctions[] = { + {DCT3DCT4_ReplyGetModelFirmware,"\xD2",0x02,0x00,ID_GetModel }, + {DCT3DCT4_ReplyGetModelFirmware,"\xD2",0x02,0x00,ID_GetFirmware }, + + {NULL, "\x00",0x00,0x00,ID_None } +}; + +GSM_Phone_Functions N650Phone = { + "0650", + N650ReplyFunctions, + NONEFUNCTION, /* Initialise */ + NONEFUNCTION, /* Terminate */ + GSM_DispatchMessage, + NOTSUPPORTED, /* ShowStartInfo */ + NOKIA_GetManufacturer, + DCT3DCT4_GetModel, + DCT3DCT4_GetFirmware, + NOTSUPPORTED, /* GetIMEI */ + NOTSUPPORTED, /* GetOriginalIMEI */ + NOTSUPPORTED, /* GetManufactureMonth */ + NOTSUPPORTED, /* GetProductCode */ + NOTSUPPORTED, /* GetHardware */ + NOTSUPPORTED, /* GetPPM */ + NOTSUPPORTED, /* GetSIMIMSI */ + NOTSUPPORTED, /* GetDateTime */ + NOTSUPPORTED, /* SetDateTime */ + NOTSUPPORTED, /* GetAlarm */ + NOTSUPPORTED, /* SetAlarm */ + NOTSUPPORTED, /* GetLocale */ + NOTSUPPORTED, /* SetLocale */ + NOTSUPPORTED, /* PressKey */ + NOTSUPPORTED, /* Reset */ + NOTSUPPORTED, /* ResetPhoneSettings */ + NOTSUPPORTED, /* EnterSecurityCode */ + NOTSUPPORTED, /* GetSecurityStatus */ + NOTSUPPORTED, /* GetDisplayStatus */ + NOTSUPPORTED, /* SetAutoNetworkLogin */ + NOTSUPPORTED, /* GetBatteryCharge */ + NOTSUPPORTED, /* GetSignalQuality */ + NOTSUPPORTED, /* GetNetworkInfo */ + NOTSUPPORTED, /* GetCategory */ + NOTSUPPORTED, /* AddCategory */ + NOTSUPPORTED, /* GetCategoryStatus */ + NOTSUPPORTED, /* GetMemoryStatus */ + NOTSUPPORTED, /* GetMemory */ + NOTSUPPORTED, /* GetNextMemory */ + NOTSUPPORTED, /* SetMemory */ + NOTSUPPORTED, /* AddMemory */ + NOTSUPPORTED, /* DeleteMemory */ + NOTIMPLEMENTED, /* DeleteAllMemory */ + NOTSUPPORTED, /* GetSpeedDial */ + NOTSUPPORTED, /* SetSpeedDial */ + NOTSUPPORTED, /* GetSMSC */ + NOTSUPPORTED, /* SetSMSC */ + NOTSUPPORTED, /* GetSMSStatus */ + NOTSUPPORTED, /* GetSMS */ + NOTSUPPORTED, /* GetNextSMS */ + NOTSUPPORTED, /* SetSMS */ + NOTSUPPORTED, /* AddSMS */ + NOTSUPPORTED, /* DeleteSMS */ + NOTSUPPORTED, /* SendSMSMessage */ + NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetIncomingSMS */ + NOTSUPPORTED, /* SetIncomingCB */ + NOTSUPPORTED, /* GetSMSFolders */ + NOTSUPPORTED, /* AddSMSFolder */ + NOTSUPPORTED, /* DeleteSMSFolder */ + NOTSUPPORTED, /* DialVoice */ + NOTSUPPORTED, /* AnswerCall */ + NOTSUPPORTED, /* CancelCall */ + NOTSUPPORTED, /* HoldCall */ + NOTSUPPORTED, /* UnholdCall */ + NOTSUPPORTED, /* ConferenceCall */ + NOTSUPPORTED, /* SplitCall */ + NOTSUPPORTED, /* TransferCall */ + NOTSUPPORTED, /* SwitchCall */ + NOTSUPPORTED, /* GetCallDivert */ + NOTSUPPORTED, /* SetCallDivert */ + NOTSUPPORTED, /* CancelAllDiverts */ + NOTSUPPORTED, /* SetIncomingCall */ + NOTSUPPORTED, /* SetIncomingUSSD */ + NOTSUPPORTED, /* SendDTMF */ + NOTSUPPORTED, /* GetRingtone */ + NOTSUPPORTED, /* SetRingtone */ + NOTSUPPORTED, /* GetRingtonesInfo */ + NOTSUPPORTED, /* DeleteUserRingtones */ + NOTSUPPORTED, /* PlayTone */ + NOTSUPPORTED, /* GetWAPBookmark */ + NOTSUPPORTED, /* SetWAPBookmark */ + NOTSUPPORTED, /* DeleteWAPBookmark */ + NOTSUPPORTED, /* GetWAPSettings */ + NOTSUPPORTED, /* SetWAPSettings */ + NOTSUPPORTED, /* GetMMSSettings */ + NOTSUPPORTED, /* SetMMSSettings */ + NOTSUPPORTED, /* GetBitmap */ + NOTSUPPORTED, /* SetBitmap */ + NOTSUPPORTED, /* GetToDoStatus */ + NOTSUPPORTED, /* GetToDo */ + NOTSUPPORTED, /* GetNextToDo */ + NOTSUPPORTED, /* SetToDo */ + NOTSUPPORTED, /* AddToDo */ + NOTSUPPORTED, /* DeleteToDo */ + NOTSUPPORTED, /* DeleteAllToDo */ + NOTSUPPORTED, /* GetCalendarStatus */ + NOTSUPPORTED, /* GetCalendar */ + NOTSUPPORTED, /* GetNextCalendar */ + NOTSUPPORTED, /* SetCalendar */ + NOTSUPPORTED, /* AddCalendar */ + NOTSUPPORTED, /* DeleteCalendar */ + NOTSUPPORTED, /* DeleteAllCalendar */ + NOTSUPPORTED, /* GetCalendarSettings */ + NOTSUPPORTED, /* SetCalendarSettings */ + NOTSUPPORTED, /* GetNoteStatus */ + NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* SetNote */ + NOTSUPPORTED, /* AddNote */ + NOTSUPPORTED, /* DeleteNote */ + NOTSUPPORTED, /* DeleteAllNotes */ + NOTSUPPORTED, /* GetProfile */ + NOTSUPPORTED, /* SetProfile */ + NOTSUPPORTED, /* GetFMStation */ + NOTSUPPORTED, /* SetFMStation */ + NOTSUPPORTED, /* ClearFMStations */ + NOTSUPPORTED, /* GetNextFileFolder */ + NOTSUPPORTED, /* GetFilePart */ + NOTSUPPORTED, /* AddFilePart */ + NOTSUPPORTED, /* GetFileSystemStatus */ + NOTSUPPORTED, /* DeleteFile */ + NOTSUPPORTED, /* AddFolder */ + NOTSUPPORTED, /* GetGPRSAccessPoint */ + NOTSUPPORTED /* SetGPRSAccessPoint */ +}; + +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/gammu/emb/common/phone/nokia/dct3/n0650.h b/gammu/emb/common/phone/nokia/dct3/n0650.h new file mode 100644 index 0000000..be491eb --- a/dev/null +++ b/gammu/emb/common/phone/nokia/dct3/n0650.h @@ -0,0 +1,18 @@ +/* (c) 2004 by Marcin Wiacek */ + +#ifndef n650_h +#define n650_h + +typedef struct { + int fake; +} GSM_Phone_N650Data; + +#ifndef GSM_USED_MBUS2 +# define GSM_USED_MBUS2 +#endif + +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/gammu/emb/common/phone/nokia/dct3/n6110.c b/gammu/emb/common/phone/nokia/dct3/n6110.c index dac6c12..c3ddfb6 100644 --- a/gammu/emb/common/phone/nokia/dct3/n6110.c +++ b/gammu/emb/common/phone/nokia/dct3/n6110.c @@ -1,2891 +1,2906 @@ /* (c) 2001-2004 by Marcin Wiacek */ /* 5210 calendar IDs by Frederick Ros */ /* based on some Markus Plail, Pavel Janik & others work from Gnokii (www.gnokii.org) * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot * GNU GPL version 2 or later */ +/* Due to a problem in the source code management, the names of some of + * the authors have unfortunately been lost. We do not mean to belittle + * their efforts and hope they will contact us to see their names + * properly added to the Copyright notice above. + * Having published their contributions under the terms of the GNU + * General Public License (GPL) [version 2], the Copyright of these + * authors will remain respected by adhering to the license they chose + * to publish their code under. + */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA6110 #include <string.h> #include "../../../../cfg/config.h" #include "../../../misc/coding/coding.h" #include "../../../service/sms/gsmsms.h" #include "../../../gsmcomon.h" #include "../../pfunc.h" #include "../nfunc.h" #include "n6110.h" #include "dct3func.h" static unsigned char N6110_MEMORY_TYPES[] = { MEM_ME, 0x02, MEM_SM, 0x03, MEM_ON, 0x05, MEM_DC, 0x07, MEM_RC, 0x08, MEM_MC, 0x09, MEM_VM, 0x0b, 0x00, 0x00 }; static GSM_Error N6110_ReplyGetPhoneLanguage(GSM_Protocol_Message msg, GSM_StateMachine *s) { N6110_Language lang = N6110_Auto; if (msg.Buffer[3] == 0x15) return ERR_NONE; smprintf(s, "Phone language is %02x\n",msg.Buffer[6]); switch (msg.Buffer[6]) { case 0x21: lang = N6110_Europe; break; //Polish } s->Phone.Data.Priv.N6110.PhoneLanguage = lang; return ERR_NONE; } static GSM_Error N6110_GetPhoneLanguage(GSM_StateMachine *s) { unsigned char feat_req[] = {N6110_FRAME_HEADER, 0x13, 0x01, 0x00, /* Profile location */ 0x00}; /* Feature number */ s->Phone.Data.Priv.N6110.PhoneLanguage = N6110_Auto; feat_req[5] = 0; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) { feat_req[6] = 0x1E; } else { feat_req[6] = 0x21; } smprintf(s, "Getting profile feature\n"); return GSM_WaitFor (s, feat_req, 7, 0x05, 4, ID_GetLanguage); } struct N6110_Lang_Char { N6110_Language Lang; unsigned char Phone; unsigned char Unicode1; unsigned char Unicode2; }; static struct N6110_Lang_Char N6110_Lang_Table[] = { {N6110_Europe,0x13,0x01,0x04},//Latin capital letter a with ogonek {N6110_Europe,0x14,0x01,0x05},//Latin small letter a with ogonek {N6110_Europe,0x15,0x01,0x06},//Latin capital letter c with acute {N6110_Europe,0x17,0x01,0x07},//Latin small letter c with acute {N6110_Europe,0x1D,0x01,0x18},//Latin capital letter e with ogonek {N6110_Europe,0x1E,0x01,0x19},//Latin small letter e with ogonek {N6110_Europe,0x83,0x00,0xD3},//Latin capital letter o with acute {N6110_Europe,0x8E,0x01,0x41},//Latin capital letter l with stroke {N6110_Europe,0x90,0x01,0x42},//Latin small letter l with stroke {N6110_Europe,0x92,0x01,0x43},//Latin capital letter n with acute {N6110_Europe,0x93,0x01,0x44},//Latin small letter n with acute {N6110_Europe,0x9A,0x00,0xF3},//Latin small letter o with acute {N6110_Europe,0xB2,0x20,0xAC},//euro {N6110_Europe,0xB5,0x01,0x5A},//Latin capital letter s with acute {N6110_Europe,0xB6,0x01,0x5B},//Latin small letter s with acute {N6110_Europe,0xE7,0x01,0x79},//Latin capital letter z with acute {N6110_Europe,0xEE,0x01,0x7A},//Latin small letter z with acute {N6110_Europe,0xF4,0x01,0x7C},//Latin small letter z with dot above {N6110_Europe,0xF0,0x01,0x7B},//Latin capital letter z with dot above {0,0,0,0} }; static void N6110_EncodeUnicode(GSM_StateMachine *s, unsigned char *dest, const unsigned char *src, int len) { int i_len = 0, o_len, i; wchar_t wc; GSM_Phone_N6110Data *Priv = &s->Phone.Data.Priv.N6110; bool found; for (o_len = 0; i_len < len; o_len++) { found = false; if (Priv->PhoneLanguage != N6110_Auto) { i = 0; while(1) { if (N6110_Lang_Table[i].Lang == 0) break; if (N6110_Lang_Table[i].Lang == Priv->PhoneLanguage && N6110_Lang_Table[i].Phone == src[i_len]) { dest[o_len*2] = N6110_Lang_Table[i].Unicode1; dest[(o_len*2)+1] = N6110_Lang_Table[i].Unicode2; i_len++; found = true; break; } i++; } } if (!found) { i_len += EncodeWithUnicodeAlphabet(&src[i_len], &wc); dest[o_len*2] = (wc >> 8) & 0xff; dest[(o_len*2)+1] = wc & 0xff; } } dest[o_len*2] = 0; dest[(o_len*2)+1] = 0; } #ifndef ENABLE_LGPL /* Pavel Janik */ /* This function provides Nokia authentication protocol. * Nokia authentication protocol is used in the communication between Nokia * mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software, * commercially sold by Nokia Corp. * The authentication scheme is based on the token send by the phone to the * software. The software does it's magic (see the function * N6110_GetNokiaAuthentication) and returns the result back to the phone. * If the result is correct the phone responds with the message "Accessory * connected!" displayed on the LCD. Otherwise it will display "Accessory not * supported" and some functions will not be available for use (?). * The specification of the protocol is not publicly available, no comment. */ static void N6110_GetNokiaAuthentication(unsigned char *Imei, unsigned char *MagicBytes, unsigned char *MagicResponse) { int i, j, CRC=0; unsigned char Temp[16]; /* This is our temporary working area. */ /* Here we put FAC (Final Assembly Code) and serial number into our area. */ Temp[0] = Imei[6]; Temp[1] = Imei[7]; Temp[2] = Imei[8]; Temp[3] = Imei[9]; Temp[4] = Imei[10]; Temp[5] = Imei[11]; Temp[6] = Imei[12]; Temp[7] = Imei[13]; /* And now the TAC (Type Approval Code). */ Temp[8] = Imei[2]; Temp[9] = Imei[3]; Temp[10] = Imei[4]; Temp[11] = Imei[5]; /* And now we pack magic bytes from the phone. */ Temp[12] = MagicBytes[0]; Temp[13] = MagicBytes[1]; Temp[14] = MagicBytes[2]; Temp[15] = MagicBytes[3]; for (i=0; i<=11; i++) if (Temp[i + 1]& 1) Temp[i]<<=1; switch (Temp[15] & 0x03) { case 1: case 2: j = Temp[13] & 0x07; for (i=0; i<=3; i++) Temp[i+j] ^= Temp[i+12]; break; default: j = Temp[14] & 0x07; for (i=0; i<=3; i++) Temp[i + j] |= Temp[i + 12]; } for (i=0; i<=15; i++) CRC ^= Temp[i]; for (i=0; i<=15; i++) { switch (Temp[15 - i] & 0x06) { case 0: j = Temp[i] | CRC; break; case 2: case 4: j = Temp[i] ^ CRC; break; case 6: j = Temp[i] & CRC; break; } if (j == CRC) j = 0x2c; if (Temp[i] == 0) j = 0; MagicResponse[i] = j; } } static GSM_Error N6110_ReplyGetMagicBytes(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_N6110Data *Priv = &s->Phone.Data.Priv.N6110; GSM_Phone_Data *Data = &s->Phone.Data; sprintf(Data->IMEI, "%s", msg.Buffer+9); sprintf(Data->HardwareCache, "%s", msg.Buffer+39); sprintf(Data->ProductCodeCache, "%s", msg.Buffer+31); smprintf(s, "Message: Mobile phone identification received:\n"); smprintf(s, "IMEI : %s\n", msg.Buffer+9); smprintf(s, "Model : %s\n", msg.Buffer+25); smprintf(s, "Production Code : %s\n", msg.Buffer+31); smprintf(s, "HW : %s\n", msg.Buffer+39); smprintf(s, "Firmware : %s\n", msg.Buffer+44); /* These bytes are probably the source of the "Accessory not connected" * messages on the phone when trying to emulate NCDS... I hope.... * UPDATE: of course, now we have the authentication algorithm. */ smprintf(s, " Magic bytes : %02x %02x %02x %02x\n", msg.Buffer[50], msg.Buffer[51], msg.Buffer[52], msg.Buffer[53]); Priv->MagicBytes[0]=msg.Buffer[50]; Priv->MagicBytes[1]=msg.Buffer[51]; Priv->MagicBytes[2]=msg.Buffer[52]; Priv->MagicBytes[3]=msg.Buffer[53]; return ERR_NONE; } static GSM_Error N6110_MakeAuthentication(GSM_StateMachine *s) { GSM_Phone_N6110Data *Priv = &s->Phone.Data.Priv.N6110; GSM_Error error; unsigned char connect4[] = {N6110_FRAME_HEADER, 0x10}; unsigned char magic_connect[] = { N6110_FRAME_HEADER, 0x12, /* The real magic goes here ... These bytes are filled in * with the function N6110_GetNokiaAuthentication. */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* NOKIA&GNOKII Accessory */ 'N', 'O', 'K', 'I', 'A', '&', 'N', 'O', 'K', 'I', 'A', 'a', 'c', 'c', 'e', 's', 's', 'o', 'r', 'y', 0x00, 0x00, 0x00, 0x00}; smprintf(s, "Getting magic bytes for authentication\n"); error=GSM_WaitFor (s, connect4, 4, 0x64, 4, ID_MakeAuthentication); if (error!=ERR_NONE) return error; N6110_GetNokiaAuthentication(s->Phone.Data.IMEI, Priv->MagicBytes, magic_connect+4); smprintf(s, "Sending authentication bytes\n"); return s->Protocol.Functions->WriteMessage(s, magic_connect, 45, 0x64); } #endif static GSM_Error N6110_ShowStartInfo(GSM_StateMachine *s, bool enable) { #ifdef ENABLE_LGPL return ERR_NONE; #else GSM_Error error=ERR_NONE; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_MAGICBYTES)) { if (s->ConnectionType == GCT_FBUS2 || s->ConnectionType == GCT_FBUS2IRDA) { error=N6110_MakeAuthentication(s); } } return error; #endif } static GSM_Error N6110_Initialise (GSM_StateMachine *s) { #ifdef DEBUG DCT3_SetIncomingCB(s,true); #endif N6110_GetPhoneLanguage(s); return ERR_NONE; } static GSM_Error N6110_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { return DCT3_GetDateTime(s, date_time, 0x11); } static GSM_Error N6110_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) { return DCT3_GetAlarm(s, alarm, 0x11); } static GSM_Error N6110_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { return DCT3_SetDateTime(s, date_time, 0x11); } static GSM_Error N6110_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) { return DCT3_SetAlarm(s, alarm, 0x11); } static GSM_Error N6110_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { int count; GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Phonebook entry received\n"); switch (msg.Buffer[3]) { case 0x02: Data->Memory->EntriesNum = 0; count=5; /* If name is not empty */ if (msg.Buffer[count]!=0x00) { if (msg.Buffer[count]>GSM_PHONEBOOK_TEXT_LENGTH) { smprintf(s, "Too long text\n"); return ERR_UNKNOWNRESPONSE; } Data->Memory->Entries[Data->Memory->EntriesNum].EntryType=PBK_Text_Name; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOPBKUNICODE)) { if (Data->Memory->MemoryType==MEM_DC || Data->Memory->MemoryType==MEM_RC || Data->Memory->MemoryType==MEM_MC || Data->Memory->MemoryType==MEM_ME) { N6110_EncodeUnicode(s,Data->Memory->Entries[Data->Memory->EntriesNum].Text, msg.Buffer+count+1,msg.Buffer[count]); } else { EncodeUnicode(Data->Memory->Entries[Data->Memory->EntriesNum].Text, msg.Buffer+count+1,msg.Buffer[count]); } } else { memcpy(Data->Memory->Entries[Data->Memory->EntriesNum].Text, msg.Buffer+count+1,msg.Buffer[count]); Data->Memory->Entries[Data->Memory->EntriesNum].Text[msg.Buffer[count]]=0x00; Data->Memory->Entries[Data->Memory->EntriesNum].Text[msg.Buffer[count]+1]=0x00; } smprintf(s, "Name \"%s\"\n", DecodeUnicodeString(Data->Memory->Entries[Data->Memory->EntriesNum].Text)); Data->Memory->EntriesNum++; } count=count+msg.Buffer[count]+1; /* If number is empty */ if (msg.Buffer[count]==0x00) return ERR_EMPTY; if (msg.Buffer[count]>GSM_PHONEBOOK_TEXT_LENGTH) { smprintf(s, "Too long text\n"); return ERR_UNKNOWNRESPONSE; } Data->Memory->Entries[Data->Memory->EntriesNum].EntryType = PBK_Number_General; Data->Memory->Entries[Data->Memory->EntriesNum].VoiceTag = 0; Data->Memory->Entries[Data->Memory->EntriesNum].SMSList[0] = 0; EncodeUnicode(Data->Memory->Entries[Data->Memory->EntriesNum].Text, msg.Buffer+count+1,msg.Buffer[count]); smprintf(s, "Number \"%s\"\n", DecodeUnicodeString(Data->Memory->Entries[Data->Memory->EntriesNum].Text)); Data->Memory->EntriesNum++; count=count+msg.Buffer[count]+1; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOCALLER)) { if (msg.Buffer[count]<5) { Data->Memory->Entries[Data->Memory->EntriesNum].EntryType=PBK_Caller_Group; smprintf(s, "Caller group \"%i\"\n",msg.Buffer[count]); Data->Memory->Entries[Data->Memory->EntriesNum].Number=msg.Buffer[count]+1; Data->Memory->EntriesNum++; } } count++; if (Data->Memory->MemoryType==MEM_DC || Data->Memory->MemoryType==MEM_RC || Data->Memory->MemoryType==MEM_MC) { NOKIA_DecodeDateTime(s, msg.Buffer+count+1,&Data->Memory->Entries[Data->Memory->EntriesNum].Date); Data->Memory->Entries[Data->Memory->EntriesNum].EntryType=PBK_Date; /* These values are set, when date and time unavailable in phone. * Values from 3310 - in other can be different */ if (Data->Memory->Entries[2].Date.Day !=20 || Data->Memory->Entries[2].Date.Month !=1 || Data->Memory->Entries[2].Date.Year !=2118|| Data->Memory->Entries[2].Date.Hour !=3 || Data->Memory->Entries[2].Date.Minute!=14 || Data->Memory->Entries[2].Date.Second!=7) Data->Memory->EntriesNum++; } return ERR_NONE; default: switch (msg.Buffer[4]) { case 0x6f: smprintf(s, "Phone is OFF\n"); return ERR_PHONEOFF; case 0x74: /* TODO: check if not too high */ smprintf(s, "ERROR: Empty ????\n"); Data->Memory->EntriesNum = 0; return ERR_EMPTY; case 0x7d: smprintf(s, "ERROR: Invalid memory type\n"); return ERR_NOTSUPPORTED; case 0x8d: smprintf(s, "ERROR: no PIN\n"); return ERR_SECURITYERROR; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry) { unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, /* memory type */ 0x00, /* location */ 0x00}; req[4] = NOKIA_GetMemoryType(s, entry->MemoryType,N6110_MEMORY_TYPES); if (req[4]==0xff) return ERR_NOTSUPPORTED; req[5] = entry->Location; if (entry->MemoryType==MEM_DC || entry->MemoryType==MEM_RC || entry->MemoryType==MEM_MC) req[5]--; s->Phone.Data.Memory=entry; smprintf(s, "Getting phonebook entry\n"); return GSM_WaitFor (s, req, 7, 0x03, 4, ID_GetMemory); } static GSM_Error N6110_ReplyGetMemoryStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Memory status received\n"); switch (msg.Buffer[3]) { case 0x08: smprintf(s, "Memory type: %i\n",msg.Buffer[4]); smprintf(s, "Free : %i\n",msg.Buffer[5]); Data->MemoryStatus->MemoryFree=msg.Buffer[5]; smprintf(s, "Used : %i\n",msg.Buffer[6]); Data->MemoryStatus->MemoryUsed=msg.Buffer[6]; return ERR_NONE; break; case 0x09: switch (msg.Buffer[4]) { case 0x6f: smprintf(s, "Phone is probably powered off.\n"); return ERR_TIMEOUT; case 0x7d: smprintf(s, "Memory type not supported by phone model.\n"); return ERR_NOTSUPPORTED; case 0x8d: smprintf(s, "Waiting for security code.\n"); return ERR_SECURITYERROR; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } default: return ERR_UNKNOWNRESPONSE; } } static GSM_Error N6110_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status) { unsigned char req[] = {N6110_FRAME_HEADER, 0x07, 0x00}; /* memory type */ req[4] = NOKIA_GetMemoryType(s, Status->MemoryType,N6110_MEMORY_TYPES); if (req[4]==0xff) return ERR_NOTSUPPORTED; s->Phone.Data.MemoryStatus=Status; smprintf(s, "Getting memory status\n"); return GSM_WaitFor (s, req, 5, 0x03, 4, ID_GetMemoryStatus); } static GSM_Error N6110_ReplyGetSMSStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "SMS status received\n"); switch (msg.Buffer[3]) { case 0x37: smprintf(s, "SIM size : %i\n",msg.Buffer[7]); smprintf(s, "Used in SIM : %i\n",msg.Buffer[10]); smprintf(s, "Unread in SIM : %i\n",msg.Buffer[11]); Data->SMSStatus->SIMUsed = msg.Buffer[10]; Data->SMSStatus->SIMUnRead = msg.Buffer[11]; Data->SMSStatus->SIMSize = msg.Buffer[7]; Data->SMSStatus->PhoneUsed = 0; Data->SMSStatus->PhoneUnRead = 0; Data->SMSStatus->PhoneSize = 0; Data->SMSStatus->TemplatesUsed = 0; return ERR_NONE; case 0x38: smprintf(s, "Error. No PIN ?\n"); return ERR_SECURITYERROR; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "SMS Message received\n"); switch(msg.Buffer[3]) { case 0x08: Data->GetSMSMessage->Number = 1; Data->GetSMSMessage->SMS[0].Name[0] = 0; Data->GetSMSMessage->SMS[0].Name[1] = 0; Data->GetSMSMessage->SMS[0].Memory = MEM_SM; NOKIA_DecodeSMSState(s, msg.Buffer[4], &Data->GetSMSMessage->SMS[0]); switch (msg.Buffer[7]) { case 0x00: case 0x01: /* Report or SMS_Deliver */ Data->GetSMSMessage->SMS[0].Folder = 0x01; Data->GetSMSMessage->SMS[0].InboxFolder = true; break; case 0x02: /* SMS_Submit */ Data->GetSMSMessage->SMS[0].Folder = 0x02; Data->GetSMSMessage->SMS[0].InboxFolder = false; break; default: return ERR_UNKNOWNRESPONSE; } DCT3_DecodeSMSFrame(s, &Data->GetSMSMessage->SMS[0],msg.Buffer+8); return ERR_NONE; case 0x09: switch (msg.Buffer[4]) { case 0x00: smprintf(s, "Unknown. Probably phone too busy\n"); return ERR_UNKNOWN; case 0x02: smprintf(s, "Too high location ?\n"); return ERR_INVALIDLOCATION; case 0x06: smprintf(s, "Phone is OFF\n"); return ERR_PHONEOFF; case 0x07: smprintf(s, "Empty\n"); return ERR_EMPTY; case 0x0c: smprintf(s, "Access error. No PIN ?\n"); return ERR_SECURITYERROR; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_GetSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms) { unsigned char req[] = {N6110_FRAME_HEADER, 0x07, 0x02, 0x00, /* Location */ 0x01, 0x64}; if (sms->SMS[0].Folder!=0x00) return ERR_NOTSUPPORTED; req[5] = sms->SMS[0].Location; s->Phone.Data.GetSMSMessage=sms; smprintf(s, "Getting sms\n"); return GSM_WaitFor (s, req, 8, 0x02, 4, ID_GetSMSMessage); } static GSM_Error N6110_GetNextSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start) { GSM_Phone_N6110Data *Priv = &s->Phone.Data.Priv.N6110; GSM_Error error; if (start) { error=s->Phone.Functions->GetSMSStatus(s,&Priv->LastSMSStatus); if (error!=ERR_NONE) return error; Priv->LastSMSRead=0; sms->SMS[0].Location=0; } while (true) { sms->SMS[0].Location++; if (Priv->LastSMSRead>=(Priv->LastSMSStatus.SIMUsed+Priv->LastSMSStatus.PhoneUsed+Priv->LastSMSStatus.TemplatesUsed)) return ERR_EMPTY; error=s->Phone.Functions->GetSMS(s, sms); if (error==ERR_NONE) { Priv->LastSMSRead++; break; } if (error != ERR_EMPTY) return error; } return error; } static GSM_Error N6110_ReplyGetStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; #ifdef DEBUG smprintf(s, "Phone status received :\n"); smprintf(s, "Mode : "); switch (msg.Buffer[4]) { case 0x01: smprintf(s, "registered within the network\n"); break; case 0x02: smprintf(s, "call in progress\n"); break; /* ringing or already answered call */ case 0x03: smprintf(s, "waiting for security code\n"); break; case 0x04: smprintf(s, "powered off\n"); break; default : smprintf(s, "unknown\n"); } smprintf(s, "Power source : "); switch (msg.Buffer[7]) { case 0x01: smprintf(s, "AC/DC\n"); break; case 0x02: smprintf(s, "battery\n"); break; default : smprintf(s, "unknown\n"); } smprintf(s, "Battery Level : %d\n", msg.Buffer[8]); smprintf(s, "Signal strength : %d\n", msg.Buffer[5]); #endif switch (Data->RequestID) { case ID_GetBatteryCharge: Data->BatteryCharge->BatteryPercent = ((int)msg.Buffer[8])*25; switch (msg.Buffer[7]) { case 0x01: Data->BatteryCharge->ChargeState = GSM_BatteryConnected; break; case 0x02: Data->BatteryCharge->ChargeState = GSM_BatteryPowered; break; default : Data->BatteryCharge->ChargeState = 0; } return ERR_NONE; case ID_GetSignalQuality: Data->SignalQuality->SignalPercent = ((int)msg.Buffer[5])*25; return ERR_NONE; default: return ERR_UNKNOWNRESPONSE; } } static GSM_Error N6110_GetStatus(GSM_StateMachine *s, int ID) { unsigned char req[] = {N6110_FRAME_HEADER, 0x01}; return GSM_WaitFor (s, req, 4, 0x04, 4, ID); } static GSM_Error N6110_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig) { char value[100]; GSM_Error error; sig->BitErrorRate = -1; sig->SignalStrength = -1; /* TODO for netmon */ smprintf(s, "Getting network level\n"); if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_POWER_BATT)) { error = DCT3_Netmonitor(s, 1, value); if (error!=ERR_NONE) return error; sig->SignalPercent = 100; if (value[4]!='-') { if (value[5]=='9' && value[6]>'4') sig->SignalPercent = 25; if (value[5]=='9' && value[6]<'5') sig->SignalPercent = 50; if (value[5]=='8' && value[6]>'4') sig->SignalPercent = 75; } else sig->SignalPercent = 0; return ERR_NONE; } else { s->Phone.Data.SignalQuality = sig; return N6110_GetStatus(s, ID_GetSignalQuality); } } static GSM_Error N6110_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat) { char value[100]; GSM_Error error; smprintf(s, "Getting battery level\n"); if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_POWER_BATT)) { error = DCT3_Netmonitor(s, 23, value); if (error!=ERR_NONE) return error; bat->BatteryPercent = 100; bat->ChargeState = 0; if (value[29]=='7') bat->BatteryPercent = 75; if (value[29]=='5') bat->BatteryPercent = 50; if (value[29]=='2') bat->BatteryPercent = 25; return ERR_NONE; } else { s->Phone.Data.BatteryCharge = bat; return N6110_GetStatus(s, ID_GetBatteryCharge); } } static GSM_Error N6110_ReplySaveSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "SMS message saving status\n"); switch (msg.Buffer[3]) { case 0x05: smprintf(s, "Saved at location %i\n",msg.Buffer[5]); Data->SaveSMSMessage->Location=msg.Buffer[5]; return ERR_NONE; case 0x06: switch (msg.Buffer[4]) { case 0x02: smprintf(s, "All locations busy\n"); return ERR_FULL; case 0x03: smprintf(s, "Too high ?\n"); return ERR_INVALIDLOCATION; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_PrivSetSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms) { int length; GSM_Error error; unsigned char req[256] = {N6110_FRAME_HEADER, 0x04, 0x00, /* SMS status */ 0x02, 0x00, /* SMS location */ 0x02}; /* SMS type */ req[6] = sms->Location; if (sms->Folder==1) { /* Inbox */ req[4] = 1; /* SMS status - GSM_Read */ req[7] = 0x00; /* SMS type */ sms->PDU = SMS_Deliver; error=PHONE_EncodeSMSFrame(s,sms,req+8,PHONE_SMSDeliver,&length,true); } else { /* Outbox */ req[4] = 5; /* SMS status - GSM_Sent */ req[7] = 0x02; /* SMS type */ sms->PDU = SMS_Submit; error=PHONE_EncodeSMSFrame(s,sms,req+8,PHONE_SMSSubmit,&length,true); } if (error != ERR_NONE) return error; /* SMS State - GSM_Read -> GSM_Unread and GSM_Sent -> GSM_UnSent */ if (sms->State == SMS_UnSent || sms->State == SMS_UnRead) req[4] |= 0x02; s->Phone.Data.SaveSMSMessage=sms; smprintf(s, "Saving sms\n"); return GSM_WaitFor (s, req, 8+length, 0x14, 4, ID_SaveSMSMessage); } static GSM_Error N6110_SetSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { if (sms->Location == 0) return ERR_INVALIDLOCATION; return N6110_PrivSetSMSMessage(s, sms); } static GSM_Error N6110_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { sms->Location = 0; return N6110_PrivSetSMSMessage(s, sms); } static GSM_Error N6110_ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x37: smprintf(s, "Ringtone set OK\n"); return ERR_NONE; break; case 0x38: smprintf(s, "Error setting ringtone\n"); switch (msg.Buffer[4]) { case 0x7d: smprintf(s, "Too high location ?\n"); return ERR_INVALIDLOCATION; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_ReplySetBinRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[4]) { case 0x00: smprintf(s, "Set at location %i\n",msg.Buffer[3]+1); return ERR_NONE; default: smprintf(s, "Invalid location. Too high ?\n"); return ERR_INVALIDLOCATION; } } static GSM_Error N6110_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) { GSM_NetworkInfo NetInfo; GSM_Error error; int size=200,current=8; GSM_UDHHeader UDHHeader; unsigned char req[1000] = {N6110_FRAME_HEADER, 0x36, 0x00, /* Location */ 0x00,0x78}; unsigned char reqBin[1000] = {0x00,0x01,0xa0,0x00,0x00,0x0c,0x01,0x2c}; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NORING)) return ERR_NOTSUPPORTED; if (Ringtone->Location == 0) return ERR_INVALIDLOCATION; switch (Ringtone->Format) { case RING_NOTETONE: if (Ringtone->Location==255) { /* Only 6110, 6130 and 6150 support it */ if (strcmp(s->Phone.Data.Model,"NSE-3") == 0 || strcmp(s->Phone.Data.Model,"NSK-3") == 0 || strcmp(s->Phone.Data.Model,"NSM-1") == 0) { req[0] = 0x0c; req[1] = 0x01; UDHHeader.Type = UDH_NokiaRingtone; GSM_EncodeUDHHeader(&UDHHeader); /* We copy UDH now */ memcpy(req+2,UDHHeader.Text,UDHHeader.Length); *maxlength=GSM_EncodeNokiaRTTLRingtone(*Ringtone, req+2+UDHHeader.Length, &size); error = s->Protocol.Functions->WriteMessage(s, req, 2+UDHHeader.Length+size, 0x12); if (error!=ERR_NONE) return error; my_sleep(1000); /* We have to make something (not important, what) now */ /* no answer from phone*/ return DCT3_GetNetworkInfo(s,&NetInfo); } else { return ERR_NOTSUPPORTED; } } *maxlength=GSM_EncodeNokiaRTTLRingtone(*Ringtone, req+7, &size); req[4] = Ringtone->Location - 1; smprintf(s, "Setting ringtone\n"); return GSM_WaitFor (s, req, 7 + size, 0x05, 4, ID_SetRingtone); case RING_NOKIABINARY: error=DCT3_EnableSecurity (s, 0x01); if (error!=ERR_NONE) return error; memcpy(reqBin+current,DecodeUnicodeString(Ringtone->Name),UnicodeLength(Ringtone->Name)); current += UnicodeLength(Ringtone->Name); reqBin[current++] = 0x00; reqBin[current++] = 0x00; reqBin[current++] = 0x00;/*xxx*/ memcpy(reqBin+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length); current=current+Ringtone->NokiaBinary.Length; reqBin[3]=Ringtone->Location-1; if (!strcmp(s->Phone.Data.ModelInfo->model,"3210")) reqBin[5]=0x10; smprintf(s, "Setting binary ringtone\n"); return GSM_WaitFor (s, reqBin, current, 0x40, 4, ID_SetRingtone); case RING_MIDI: case RING_MMF: return ERR_NOTSUPPORTED; } return ERR_NOTSUPPORTED; } static GSM_Error N6110_ReplyGetOpLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int count=5; GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Operator logo received\n"); NOKIA_DecodeNetworkCode(msg.Buffer+count,Data->Bitmap->NetworkCode); count = count + 3; smprintf(s, "Network code : %s\n", Data->Bitmap->NetworkCode); smprintf(s, "Network name for Gammu : %s ", DecodeUnicodeString(GSM_GetNetworkName(Data->Bitmap->NetworkCode))); smprintf(s, "(%s)\n",DecodeUnicodeString(GSM_GetCountryName(Data->Bitmap->NetworkCode))); count = count + 3; /* We ignore size */ Data->Bitmap->BitmapWidth = msg.Buffer[count++]; Data->Bitmap->BitmapHeight = msg.Buffer[count++]; count++; PHONE_DecodeBitmap(GSM_NokiaOperatorLogo,msg.Buffer+count,Data->Bitmap); return ERR_NONE; } static GSM_Error N6110_ReplyGetStartup(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i, count = 5; GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Startup logo & notes received\n"); for (i=0;i<msg.Buffer[4];i++) { switch (msg.Buffer[count++]) { case 0x01: smprintf(s, "Startup logo\n"); if (Data->Bitmap->Type == GSM_StartupLogo) { Data->Bitmap->BitmapHeight = msg.Buffer[count++]; Data->Bitmap->BitmapWidth = msg.Buffer[count++]; PHONE_DecodeBitmap(GSM_NokiaStartupLogo, msg.Buffer + count, Data->Bitmap); } else { count = count + 2; } count = count + PHONE_GetBitmapSize(GSM_NokiaStartupLogo,0,0); break; case 0x02: smprintf(s, "Welcome note\n"); if (Data->Bitmap->Type == GSM_WelcomeNote_Text) { EncodeUnicode(Data->Bitmap->Text,msg.Buffer+count, msg.Buffer[count]); smprintf(s, "Text is \"%s\"\n",Data->Bitmap->Text); } count = count + msg.Buffer[count] + 1; break; case 0x03: smprintf(s, "Dealer welcome note\n"); if (Data->Bitmap->Type == GSM_DealerNote_Text) { EncodeUnicode(Data->Bitmap->Text,msg.Buffer+count, msg.Buffer[count]); smprintf(s, "Text is \"%s\"\n",Data->Bitmap->Text); } count = count + msg.Buffer[count] + 1; break; default: smprintf(s, "Unknown block\n"); return ERR_UNKNOWNRESPONSE; break; } } return ERR_NONE; } static GSM_Error N6110_ReplyGetCallerLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int count; GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x11: smprintf(s, "Caller group info received\n"); EncodeUnicode(Data->Bitmap->Text,msg.Buffer+6,msg.Buffer[5]); smprintf(s, "Name : \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text)); Data->Bitmap->DefaultName = false; if (msg.Buffer[5] == 0x00) Data->Bitmap->DefaultName = true; count = msg.Buffer[5] + 6; Data->Bitmap->RingtoneID = msg.Buffer[count++]; Data->Bitmap->DefaultRingtone = false; Data->Bitmap->FileSystemRingtone = false; if (Data->Bitmap->RingtoneID == 16) Data->Bitmap->DefaultRingtone = true; smprintf(s, "Ringtone ID: %02x\n",Data->Bitmap->RingtoneID); Data->Bitmap->BitmapEnabled=(msg.Buffer[count++]==1); #ifdef DEBUG smprintf(s, "Caller group logo "); if (Data->Bitmap->BitmapEnabled) { smprintf(s, "enabled\n"); } else { smprintf(s, "disabled\n"); } #endif count = count + 3; /* We ignore size */ Data->Bitmap->BitmapWidth = msg.Buffer[count++]; Data->Bitmap->BitmapHeight = msg.Buffer[count++]; count++; PHONE_DecodeBitmap(GSM_NokiaCallerLogo,msg.Buffer+count,Data->Bitmap); Data->Bitmap->DefaultBitmap = false; return ERR_NONE; case 0x12: smprintf(s, "Error getting caller group info\n"); return ERR_INVALIDLOCATION; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_ReplyGetSetPicture(GSM_Protocol_Message msg, GSM_StateMachine *s) { int count = 5, i; GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x02: smprintf(s, "Picture Image received\n"); if (msg.Buffer[count]!=0) { GSM_UnpackSemiOctetNumber(Data->Bitmap->Sender, msg.Buffer + 5, true); /* Convert number of semioctets to number of chars */ i = msg.Buffer[5]; if (i % 2) i++; i=i / 2 + 1; count = count + i + 1; } else { Data->Bitmap->Sender[0] = 0x00; Data->Bitmap->Sender[1] = 0x00; count+=2; } smprintf(s, "Sender : \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Sender)); if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOPICTUREUNI) || (!strcmp(Data->Model,"NHM-5") && Data->VerNum < 5.79)) { count++; EncodeUnicode(Data->Bitmap->Text,msg.Buffer+count+1,msg.Buffer[count]); count += UnicodeLength(Data->Bitmap->Text) + 1; } else { if (!strcmp(Data->Model,"NHM-5")) { i = msg.Buffer[count] * 256 + msg.Buffer[count+1]; } else { /* 3410 4.26 */ i = msg.Buffer[count] * 256 + msg.Buffer[count+1] - 2; count += 2; } memcpy(Data->Bitmap->Text,msg.Buffer+count+2,i); Data->Bitmap->Text[i] = 0; Data->Bitmap->Text[i+1] = 0; count += i + 2; } smprintf(s, "Text : \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text)); Data->Bitmap->BitmapWidth = msg.Buffer[count++]; Data->Bitmap->BitmapHeight = msg.Buffer[count++]; PHONE_DecodeBitmap(GSM_NokiaPictureImage, msg.Buffer + count + 2, Data->Bitmap); #ifdef DEBUG if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,Data->Bitmap); #endif return ERR_NONE; break; case 0x04: smprintf(s, "Picture Image set OK\n"); return ERR_NONE; case 0x05: smprintf(s, "Can't set Picture Image - invalid location ?\n"); return ERR_INVALIDLOCATION; break; case 0x06: smprintf(s, "Can't get Picture Image - invalid location ?\n"); return ERR_INVALIDLOCATION; break; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { GSM_Error error; unsigned char req[10] = {N6110_FRAME_HEADER}; s->Phone.Data.Bitmap=Bitmap; switch (Bitmap->Type) { case GSM_StartupLogo: case GSM_WelcomeNote_Text: case GSM_DealerNote_Text: if (Bitmap->Type == GSM_StartupLogo && IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOSTARTUP)) return ERR_NOTSUPPORTED; req[3] = 0x16; return GSM_WaitFor (s, req, 4, 0x05, 4, ID_GetBitmap); case GSM_CallerGroupLogo: if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOCALLER)) return ERR_NOTSUPPORTED; req[3] = 0x10; req[4] = Bitmap->Location - 1; error = GSM_WaitFor (s, req, 5, 0x03, 4, ID_GetBitmap); if (error==ERR_NONE) NOKIA_GetDefaultCallerGroupName(s,Bitmap); return error; case GSM_OperatorLogo: req[3] = 0x33; req[4] = 0x01; return GSM_WaitFor (s, req, 5, 0x05, 4, ID_GetBitmap); case GSM_PictureImage: if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOPICTURE)) return ERR_NOTSUPPORTED; req[3] = 0x01; req[4] = Bitmap->Location - 1; return GSM_WaitFor (s, req, 5, 0x47, 4, ID_GetBitmap); default: break; } return ERR_NOTSUPPORTED; } static GSM_Error N6110_ReplySetProfileFeature(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x11: smprintf(s, "Feature of profile set\n"); return ERR_NONE; case 0x12: smprintf(s, "Error setting profile feature\n"); return ERR_NOTSUPPORTED; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_SetProfileFeature(GSM_StateMachine *s, unsigned char profile, unsigned char feature, unsigned char value) { unsigned char req[] = {N6110_FRAME_HEADER, 0x10, 0x01, 0x00, /* Profile */ 0x00, /* Feature */ 0x00}; /* Value */ req[5]=profile; req[6]=feature; req[7]=value; smprintf(s, "Setting profile feature\n"); return GSM_WaitFor (s, req, 8, 0x05, 4, ID_SetProfile); } static GSM_Error N6110_ReplySetStartup(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Startup logo set OK\n"); return ERR_NONE; } static GSM_Error N6110_ReplySetCallerLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x14: smprintf(s, "Caller group set OK\n"); return ERR_NONE; case 0x15: smprintf(s, "Error setting caller group\n"); return ERR_INVALIDLOCATION; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { unsigned char reqPreview[1000] = {0x0c,0x01}; unsigned char req[600] = {N6110_FRAME_HEADER}; GSM_UDH UDHType = UDH_NokiaOperatorLogo; int count = 0, textlen, Width, Height; GSM_UDHHeader UDHHeader; GSM_NetworkInfo NetInfo; GSM_Error error; switch (Bitmap->Type) { case GSM_CallerGroupLogo: case GSM_OperatorLogo: if (Bitmap->Location == 255) { /* Only 6110, 6130 and 6150 support it */ if (strcmp(s->Phone.Data.Model,"NSE-3") == 0 || strcmp(s->Phone.Data.Model,"NSK-3") == 0 || strcmp(s->Phone.Data.Model,"NSM-1") == 0) { if (Bitmap->Type==GSM_CallerGroupLogo) UDHType = UDH_NokiaCallerLogo; UDHHeader.Type = UDHType; GSM_EncodeUDHHeader(&UDHHeader); /* We copy UDH now */ memcpy(reqPreview+2,UDHHeader.Text,UDHHeader.Length); count = count + UDHHeader.Length; if (Bitmap->Type == GSM_OperatorLogo) { NOKIA_EncodeNetworkCode(reqPreview+count,Bitmap->NetworkCode); count = count + 3; } else { if (Bitmap->DefaultBitmap) { Bitmap->BitmapWidth = 72; Bitmap->BitmapHeight = 14; GSM_ClearBitmap(Bitmap); } } NOKIA_CopyBitmap(GSM_NokiaOperatorLogo,Bitmap,reqPreview, &count); reqPreview[count]=0x00; error = s->Protocol.Functions->WriteMessage(s, reqPreview, count + 1, 0x12); if (error!=ERR_NONE) return error; my_sleep(1000); /* We have to make something (not important, what) now */ /* no answer from phone*/ return DCT3_GetNetworkInfo(s,&NetInfo); } else { smprintf(s, "%s\n",s->Phone.Data.Model); return ERR_NOTSUPPORTED; } } break; default: break; } count = 3; switch (Bitmap->Type) { case GSM_StartupLogo: if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOSTARTUP)) return ERR_NOTSUPPORTED; if (Bitmap->Location != 1) { if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOSTARTANI)) return ERR_NOTSUPPORTED; } if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOSTARTANI)) { if (!strcmp(s->Phone.Data.ModelInfo->model,"3210")) { error = N6110_SetProfileFeature(s,0,0x2e,((unsigned char)(Bitmap->Location-1))); } else { error = N6110_SetProfileFeature(s,0,0x29,((unsigned char)(Bitmap->Location-1))); } if (error == ERR_NOTSUPPORTED) error = ERR_SECURITYERROR; if (error != ERR_NONE) return error; if (Bitmap->Location != 1) return ERR_NONE; } req[count++] = 0x18; req[count++] = 0x01; /* One block */ req[count++] = 0x01; PHONE_GetBitmapWidthHeight(GSM_NokiaStartupLogo, &Width, &Height); req[count++] = Height; req[count++] = Width; PHONE_EncodeBitmap(GSM_NokiaStartupLogo, req + count, Bitmap); count = count + PHONE_GetBitmapSize(GSM_NokiaStartupLogo,0,0); return GSM_WaitFor (s, req, count, 0x05, 4, ID_SetBitmap); case GSM_WelcomeNote_Text: case GSM_DealerNote_Text: req[count++] = 0x18; req[count++] = 0x01; /* One block */ if (Bitmap->Type == GSM_WelcomeNote_Text) { req[count++] = 0x02; } else { req[count++] = 0x03; } textlen = UnicodeLength(Bitmap->Text); req[count++] = textlen; memcpy(req + count,DecodeUnicodeString(Bitmap->Text),textlen); count += textlen; return GSM_WaitFor (s, req, count, 0x05, 4, ID_SetBitmap); case GSM_CallerGroupLogo: if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOCALLER)) return ERR_NOTSUPPORTED; req[count++] = 0x13; req[count++] = Bitmap->Location - 1; if (Bitmap->DefaultName) { req[count++] = 0; } else { textlen = UnicodeLength(Bitmap->Text); req[count++] = textlen; memcpy(req+count,DecodeUnicodeString(Bitmap->Text),textlen); count += textlen; } if (Bitmap->DefaultRingtone) { req[count++] = 16; } else { req[count++] = Bitmap->RingtoneID; } /* Value here is number of phone menu connected * with caller logo in Nokia 61x0: 0x00 = Off, 0x01 = On, * 0x02 = View Graphics, 0x03 = Send Graphics, * 0x04 = Send via IR. For higher menu option connected with * caller logo is not displayed */ if (Bitmap->DefaultBitmap) { Bitmap->BitmapWidth = 72; Bitmap->BitmapHeight = 14; GSM_ClearBitmap(Bitmap); req[count++] = 0; } else { if (Bitmap->BitmapEnabled) req[count++] = 0x01; else req[count++] = 0x00; } req[count++] = (PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 4) / 256; req[count++] = (PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 4) % 256; NOKIA_CopyBitmap(GSM_NokiaCallerLogo, Bitmap, req, &count); return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetBitmap); case GSM_OperatorLogo: req[count++] = 0x30; req[count++] = 0x01; NOKIA_EncodeNetworkCode(req+count, Bitmap->NetworkCode); count = count + 3; req[count++] = (PHONE_GetBitmapSize(GSM_NokiaOperatorLogo,0,0) + 4) / 256; req[count++] = (PHONE_GetBitmapSize(GSM_NokiaOperatorLogo,0,0) + 4) % 256; NOKIA_CopyBitmap(GSM_NokiaOperatorLogo, Bitmap, req, &count); return GSM_WaitFor (s, req, count, 0x05, 4, ID_SetBitmap); case GSM_PictureImage: if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOPICTURE)) return ERR_NOTSUPPORTED; req[count++] = 0x03; req[count++] = Bitmap->Location - 1; if (Bitmap->Sender[0]!=0 || Bitmap->Sender[1]!=0) { req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true); /* Convert number of semioctets to number of chars and add count */ textlen = req[count]; if (textlen % 2) textlen++; count += textlen / 2 + 1; count++; } else { req[count++] = 0x00; req[count++] = 0x00; } req[count++] = 0x00; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOPICTUREUNI) || (!strcmp(s->Phone.Data.Model,"NHM-5") && s->Phone.Data.VerNum < 5.79)) { textlen = UnicodeLength(Bitmap->Text); req[count++] = textlen; memcpy(req+count,DecodeUnicodeString(Bitmap->Text),textlen); count += textlen; } else { textlen = UnicodeLength(Bitmap->Text)*2; if (!strcmp(s->Phone.Data.Model,"NHM-5")) { req[count++] = textlen; } else { /* 3410 4.26 */ req[count++] = textlen+2; req[count++] = 0x00; req[count++] = 0x1e; } memcpy(req+count,Bitmap->Text,textlen); count += textlen; } NOKIA_CopyBitmap(GSM_NokiaPictureImage, Bitmap, req, &count); return GSM_WaitFor (s, req, count, 0x47, 4, ID_SetBitmap); default: break; } return ERR_NOTSUPPORTED; } static GSM_Error N6110_ReplyCallInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; int tmp, count; GSM_Call call; call.CallIDAvailable = true; call.Status = 0; smprintf(s, "Call info, "); switch (msg.Buffer[3]) { case 0x02: smprintf(s, "Call established, waiting for answer\n"); call.Status = GSM_CALL_CallEstablished; break; case 0x03: smprintf(s, "Call started\n"); /* no phone number in frame */ call.Status = GSM_CALL_CallStart; break; case 0x04: smprintf(s, "Remote end hang up\n"); smprintf(s, "CC : %i\n",msg.Buffer[6]); call.Status = GSM_CALL_CallRemoteEnd; call.StatusCode = msg.Buffer[6]; break; case 0x05: smprintf(s, "Incoming call\n"); smprintf(s, "Number : \""); count=msg.Buffer[6]; for (tmp=0; tmp <count; tmp++) smprintf(s, "%c", msg.Buffer[7+tmp]); smprintf(s, "\"\nName : \""); for (tmp=0; tmp<msg.Buffer[7+count]; tmp++) smprintf(s, "%c", msg.Buffer[8+count+tmp]); smprintf(s, "\"\n"); call.Status = GSM_CALL_IncomingCall; EncodeUnicode(call.PhoneNumber, msg.Buffer+7, msg.Buffer[6]); break; case 0x07: smprintf(s, "Call answer initiated\n"); break; case 0x09: smprintf(s, "Call released\n"); call.Status = GSM_CALL_CallLocalEnd; break; case 0x0a: smprintf(s, "Call is being released\n"); break; case 0x23: smprintf(s, "Call held\n"); call.Status = GSM_CALL_CallHeld; break; case 0x25: smprintf(s, "Call resumed\n"); call.Status = GSM_CALL_CallResumed; break; case 0x27: smprintf(s, "Call switched\n"); /* incorrect call id in frame - 6150 5.22 */ call.CallIDAvailable = false; call.Status = GSM_CALL_CallSwitched; break; case 0x29: smprintf(s, "Joining call to the conference (conference)\n"); break; case 0x2A: smprintf(s, "Removing call from the conference (split)\n"); break; } if (call.CallIDAvailable) smprintf(s, "Call ID : %d\n",msg.Buffer[4]); if (Data->EnableIncomingCall && s->User.IncomingCall!=NULL && call.Status != 0) { if (call.CallIDAvailable) call.CallID = msg.Buffer[4]; s->User.IncomingCall(s->CurrentConfig->Device, call); } if (s->Phone.Data.RequestID == ID_CancelCall) { if (msg.Buffer[3] == 0x09) { if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE; /* when we canceled call and see frame about other * call releasing, we don't give ERR_NONE for "our" * call release command */ return ERR_NEEDANOTHERANSWER; } } if (s->Phone.Data.RequestID == ID_AnswerCall) { if (msg.Buffer[3] == 0x07) { if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE; return ERR_NEEDANOTHERANSWER; } } if (s->Phone.Data.RequestID == ID_UnholdCall) { if (msg.Buffer[3] == 0x25) { if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE; return ERR_NEEDANOTHERANSWER; } } if (s->Phone.Data.RequestID == ID_HoldCall) { if (msg.Buffer[3] == 0x23) { if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE; return ERR_NEEDANOTHERANSWER; } } if (s->Phone.Data.RequestID == ID_ConferenceCall) { if (msg.Buffer[3] == 0x29) { if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE; return ERR_NEEDANOTHERANSWER; } } if (s->Phone.Data.RequestID == ID_SplitCall) { if (msg.Buffer[3] == 0x2B) { if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE; return ERR_NEEDANOTHERANSWER; } } return ERR_NONE; } static GSM_Error N6110_DeleteSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms) { unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00}; /* Location */ if (sms->Folder!=0x00) return ERR_NOTSUPPORTED; req[5]=sms->Location; smprintf(s, "Deleting sms\n"); return GSM_WaitFor (s, req, 6, 0x14, 4, ID_DeleteSMSMessage); } static GSM_Error N6110_ReplySetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Reply for writing memory\n"); switch (msg.Buffer[3]) { case 0x05: smprintf(s, "Done OK\n"); return ERR_NONE; case 0x06: smprintf(s, "Error\n"); switch (msg.Buffer[4]) { case 0x7d: smprintf(s, "Too high location ?\n"); return ERR_INVALIDLOCATION; case 0x90: smprintf(s, "Too long name...or other error\n"); return ERR_NOTSUPPORTED; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { int current, Group, Name, Number; unsigned char req[128] = {N6110_FRAME_HEADER, 0x04, 0x00, /* memory type */ 0x00}; /* location */ if (entry->Location == 0) return ERR_NOTSUPPORTED; GSM_PhonebookFindDefaultNameNumberGroup(entry, &Name, &Number, &Group); req[4] = NOKIA_GetMemoryType(s, entry->MemoryType,N6110_MEMORY_TYPES); req[5] = entry->Location; current = 7; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOPBKUNICODE)) { if (Name != -1) { req[6] = UnicodeLength(entry->Entries[Name].Text); memcpy(req+current,DecodeUnicodeString(entry->Entries[Name].Text),UnicodeLength(entry->Entries[Name].Text)); current += UnicodeLength(entry->Entries[Name].Text); } else req[6] = 0; } else { if (Name != -1) { req[6] = UnicodeLength(entry->Entries[Name].Text)*2+2; memcpy(req+current,entry->Entries[Name].Text,UnicodeLength(entry->Entries[Name].Text)*2); current += UnicodeLength(entry->Entries[Name].Text)*2; } else req[6] = 0; req[current++]=0x00; req[current++]=0x00; } if (Number != -1) { req[current++]=UnicodeLength(entry->Entries[Number].Text); memcpy(req+current,DecodeUnicodeString(entry->Entries[Number].Text),UnicodeLength(entry->Entries[Number].Text)); current += UnicodeLength(entry->Entries[Number].Text); } else req[current++] = 0; /* This allow to save 14 characters name into SIM memory, when * no caller group is selected. */ if (Group == -1) { req[current++] = 0xff; } else { req[current++] = entry->Entries[Group].Number-1; } smprintf(s, "Writing phonebook entry\n"); return GSM_WaitFor (s, req, current, 0x03, 4, ID_SetMemory); } static GSM_Error N6110_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { GSM_MemoryEntry dwa; dwa.Location = entry->Location; dwa.MemoryType = entry->MemoryType; dwa.EntriesNum = 0; return N6110_SetMemory(s, &dwa); } static GSM_Error N6110_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; char buffer[2000]; GSM_Error error; int i,end,start; smprintf(s, "Ringtone received\n"); switch (msg.Buffer[4]) { case 0x00: switch (Data->Ringtone->Format) { case RING_NOTETONE: memcpy(buffer,msg.Buffer,msg.Length); i=7; if (buffer[9]==0x4a && buffer[10]==0x3a) i=8; buffer[i]=0x02; error=GSM_DecodeNokiaRTTLRingtone(Data->Ringtone, buffer+i, msg.Length-i); if (error!=ERR_NONE) return ERR_EMPTY; return ERR_NONE; case RING_NOKIABINARY: i=8; while (msg.Buffer[i]!=0) { i++; if (i>msg.Length) return ERR_EMPTY; } EncodeUnicode(Data->Ringtone->Name,msg.Buffer+8,i-8); smprintf(s, "Name \"%s\"\n",DecodeUnicodeString(Data->Ringtone->Name)); /* Looking for start && end */ end=0;start=0;i=0; while (true) { if (start!=0) { if (msg.Buffer[i]==0x07 && msg.Buffer[i+1]==0x0b) { end=i+2; break; } if (msg.Buffer[i]==0x0e && msg.Buffer[i+1]==0x0b) { end=i+2; break; } } else { if (msg.Buffer[i]==0x02 && msg.Buffer[i+1]==0xfc && msg.Buffer[i+2]==0x09) { start = i; } } i++; if (i==msg.Length-3) return ERR_EMPTY; } /* Copying frame */ memcpy(Data->Ringtone->NokiaBinary.Frame,msg.Buffer+start,end-start); Data->Ringtone->NokiaBinary.Length=end-start; #ifdef DEBUG if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, di.dl, Data->Ringtone->NokiaBinary.Frame, Data->Ringtone->NokiaBinary.Length); #endif return ERR_NONE; case RING_MIDI: case RING_MMF: return ERR_NOTSUPPORTED; } smprintf(s, "Ringtone format is %i\n",Data->Ringtone->Format); break; default: smprintf(s, "Invalid location. Too high ?\n"); return ERR_INVALIDLOCATION; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) { GSM_Error error; unsigned char req[] = {0x00, 0x01, 0x9e, 0x00}; /* location */ if (PhoneRingtone) return ERR_NOTSUPPORTED; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NORING)) return ERR_NOTSUPPORTED; if (Ringtone->Location == 0) return ERR_INVALIDLOCATION; if (Ringtone->Format == 0x00) { if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_RING_SM)) { Ringtone->Format = RING_NOTETONE; } else { Ringtone->Format = RING_NOKIABINARY; } } switch (Ringtone->Format) { case RING_NOTETONE: if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_RING_SM)) return ERR_NOTSUPPORTED; break; case RING_NOKIABINARY: if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_RING_SM)) return ERR_NOTSUPPORTED; break; case RING_MIDI: case RING_MMF: return ERR_NOTSUPPORTED; } error=DCT3_EnableSecurity (s, 0x01); if (error!=ERR_NONE) return error; req[3]=Ringtone->Location-1; s->Phone.Data.Ringtone=Ringtone; smprintf(s, "Getting (binary) ringtone\n"); return GSM_WaitFor (s, req, 4, 0x40, 4, ID_GetRingtone); } static GSM_Error N6110_ReplyGetSecurityStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { *s->Phone.Data.SecurityStatus = msg.Buffer[4]; #ifdef DEBUG smprintf(s, "Security code status\n"); switch(msg.Buffer[4]) { case SEC_SecurityCode: smprintf(s, "waiting for Security Code.\n"); break; case SEC_Pin : smprintf(s, "waiting for PIN.\n"); break; case SEC_Pin2 : smprintf(s, "waiting for PIN2.\n"); break; case SEC_Puk : smprintf(s, "waiting for PUK.\n"); break; case SEC_Puk2 : smprintf(s, "waiting for PUK2.\n"); break; case SEC_None : smprintf(s, "nothing to enter.\n"); break; default : smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } #endif return ERR_NONE; } static GSM_Error N6110_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status) { unsigned char req[4] = {N6110_FRAME_HEADER, 0x07}; s->Phone.Data.SecurityStatus=Status; smprintf(s, "Getting security code status\n"); return GSM_WaitFor (s, req, 4, 0x08, 2, ID_GetSecurityStatus); } static GSM_Error N6110_ReplyEnterSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x0b: smprintf(s, "Security code OK\n"); return ERR_NONE; case 0x0c: switch (msg.Buffer[4]) { case 0x88: smprintf(s, "Wrong code\n"); return ERR_SECURITYERROR; case 0x8b: smprintf(s, "Not required\n"); return ERR_NONE; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode Code) { int len = 0; unsigned char req[15] = {N6110_FRAME_HEADER, 0x0a, 0x00}; /* Type of code to enter */ req[4]=Code.Type; len = strlen(Code.Code); memcpy(req+5,Code.Code,len); req[5+len]=0x00; req[6+len]=0x00; smprintf(s, "Entering security code\n"); return GSM_WaitFor (s, req, 7+len, 0x08, 4, ID_EnterSecurityCode); } static GSM_Error N6110_ReplyGetSpeedDial(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x17: smprintf(s, "Speed dial received\n"); switch (msg.Buffer[4]) { case 0x02: Data->SpeedDial->MemoryType = MEM_ME; smprintf(s, "ME "); break; case 0x03: Data->SpeedDial->MemoryType = MEM_SM; smprintf(s, "SIM "); break; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } Data->SpeedDial->MemoryLocation = msg.Buffer[5]; if (msg.Buffer[5] == 0x00) Data->SpeedDial->MemoryLocation = Data->SpeedDial->Location; Data->SpeedDial->MemoryNumberID = 2; smprintf(s, "location %i\n",Data->SpeedDial->MemoryLocation); return ERR_NONE; case 0x18: smprintf(s, "Error getting speed dial. Invalid location\n"); return ERR_INVALIDLOCATION; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_GetSpeedDial(GSM_StateMachine *s, GSM_SpeedDial *SpeedDial) { unsigned char req[] = {N6110_FRAME_HEADER, 0x16, 0x01}; /* location */ req[4] = SpeedDial->Location; s->Phone.Data.SpeedDial=SpeedDial; smprintf(s, "Getting speed dial\n"); return GSM_WaitFor (s, req, 5, 0x03, 4, ID_GetSpeedDial); } static GSM_Error N6110_ReplySendDTMF(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x40: smprintf(s, "During sending DTMF\n"); return ERR_NONE; case 0x51: smprintf(s, "DTMF sent OK\n"); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_ReplyGetDisplayStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Display status received\n"); if (Data->RequestID == ID_GetDisplayStatus) Data->DisplayFeatures->Number=0; for (i=0;i<msg.Buffer[4];i++) { if (msg.Buffer[2*i+6] == 0x02) { #ifdef DEBUG switch (msg.Buffer[2*i+5]) { case 0x01: smprintf(s, "Call in progress\n"); break; case 0x02: smprintf(s, "Unknown\n"); break; case 0x03: smprintf(s, "Unread SMS\n"); break; case 0x04: smprintf(s, "Voice call\n"); break; case 0x05: smprintf(s, "Fax call active\n"); break; case 0x06: smprintf(s, "Data call active\n"); break; case 0x07: smprintf(s, "Keyboard lock\n"); break; case 0x08: smprintf(s, "SMS storage full\n"); break; } #endif if (Data->RequestID == ID_GetDisplayStatus) { switch (msg.Buffer[2*i+5]) { case 0x01: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_CallActive; break; case 0x03: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_UnreadSMS; break; case 0x04: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_VoiceCall; break; case 0x05: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_FaxCall; break; case 0x06: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_DataCall; break; case 0x07: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_KeypadLocked; break; case 0x08: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_SMSMemoryFull; break; } if (msg.Buffer[2*i+5]!=0x02) Data->DisplayFeatures->Number++; } } } return ERR_NONE; } static GSM_Error N6110_GetDisplayStatus(GSM_StateMachine *s, GSM_DisplayFeatures *features) { unsigned char req[] = {N6110_FRAME_HEADER, 0x51}; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_DISPSTATUS)) return ERR_NOTSUPPORTED; s->Phone.Data.DisplayFeatures = features; smprintf(s, "Getting display status\n"); return GSM_WaitFor (s, req, 4, 0x0d, 4, ID_GetDisplayStatus); } static GSM_Profile_PhoneTableValue Profile6110[] = { {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL1, 0x00,0x00}, {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL2, 0x00,0x01}, {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL3, 0x00,0x02}, {Profile_KeypadTone, PROFILE_KEYPAD_OFF, 0x00,0xff}, {Profile_Lights, PROFILE_LIGHTS_OFF, 0x01,0x00}, {Profile_Lights, PROFILE_LIGHTS_AUTO, 0x01,0x01}, {Profile_CallAlert, PROFILE_CALLALERT_RINGING, 0x02,0x01}, {Profile_CallAlert, PROFILE_CALLALERT_BEEPONCE, 0x02,0x02}, {Profile_CallAlert, PROFILE_CALLALERT_OFF, 0x02,0x04}, {Profile_CallAlert, PROFILE_CALLALERT_RINGONCE, 0x02,0x05}, {Profile_CallAlert, PROFILE_CALLALERT_ASCENDING, 0x02,0x06}, {Profile_CallAlert, PROFILE_CALLALERT_CALLERGROUPS,0x02,0x07}, /* Ringtone ID */ {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL1, 0x04,0x06}, {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL2, 0x04,0x07}, {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL3, 0x04,0x08}, {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL4, 0x04,0x09}, {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL5, 0x04,0x0a}, {Profile_MessageTone, PROFILE_MESSAGE_NOTONE, 0x05,0x00}, {Profile_MessageTone, PROFILE_MESSAGE_STANDARD, 0x05,0x01}, {Profile_MessageTone, PROFILE_MESSAGE_SPECIAL, 0x05,0x02}, {Profile_MessageTone, PROFILE_MESSAGE_BEEPONCE, 0x05,0x03}, {Profile_MessageTone, PROFILE_MESSAGE_ASCENDING, 0x05,0x04}, {Profile_Vibration, PROFILE_VIBRATION_OFF, 0x06,0x00}, {Profile_Vibration, PROFILE_VIBRATION_ON, 0x06,0x01}, {Profile_WarningTone, PROFILE_WARNING_OFF, 0x07,0xff}, {Profile_WarningTone, PROFILE_WARNING_ON, 0x07,0x04}, /* Caller groups */ {Profile_AutoAnswer, PROFILE_AUTOANSWER_OFF, 0x09,0x00}, {Profile_AutoAnswer, PROFILE_AUTOANSWER_ON, 0x09,0x01}, {0x00, 0x00, 0x00,0x00} }; static GSM_Profile_PhoneTableValue Profile3310[] = { {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL1, 0x00,0x00}, {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL2, 0x00,0x01}, {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL3, 0x00,0x02}, {Profile_KeypadTone, PROFILE_KEYPAD_OFF, 0x00,0xff}, {Profile_CallAlert, PROFILE_CALLALERT_RINGING, 0x01,0x01}, {Profile_CallAlert, PROFILE_CALLALERT_BEEPONCE, 0x01,0x02}, {Profile_CallAlert, PROFILE_CALLALERT_OFF, 0x01,0x04}, {Profile_CallAlert, PROFILE_CALLALERT_RINGONCE, 0x01,0x05}, {Profile_CallAlert, PROFILE_CALLALERT_ASCENDING, 0x01,0x06}, /* Ringtone ID */ {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL1, 0x03,0x06}, {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL2, 0x03,0x07}, {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL3, 0x03,0x08}, {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL4, 0x03,0x09}, {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL5, 0x03,0x0a}, {Profile_MessageTone, PROFILE_MESSAGE_NOTONE, 0x04,0x00}, {Profile_MessageTone, PROFILE_MESSAGE_STANDARD, 0x04,0x01}, {Profile_MessageTone, PROFILE_MESSAGE_SPECIAL, 0x04,0x02}, {Profile_MessageTone, PROFILE_MESSAGE_BEEPONCE, 0x04,0x03}, {Profile_MessageTone, PROFILE_MESSAGE_ASCENDING, 0x04,0x04}, {Profile_MessageTone, PROFILE_MESSAGE_PERSONAL, 0x04,0x05}, {Profile_Vibration, PROFILE_VIBRATION_OFF, 0x05,0x00}, {Profile_Vibration, PROFILE_VIBRATION_ON, 0x05,0x01}, {Profile_Vibration, PROFILE_VIBRATION_FIRST, 0x05,0x02}, {Profile_WarningTone, PROFILE_WARNING_OFF, 0x06,0xff}, {Profile_WarningTone, PROFILE_WARNING_ON, 0x06,0x04}, {Profile_ScreenSaver, PROFILE_SAVER_OFF, 0x07,0x00}, {Profile_ScreenSaver, PROFILE_SAVER_ON, 0x07,0x01}, {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_5SEC, 0x08,0x00}, {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_20SEC, 0x08,0x01}, {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_1MIN, 0x08,0x02}, {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_2MIN, 0x08,0x03}, {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_5MIN, 0x08,0x04}, {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_10MIN, 0x08,0x05}, {0x00, 0x00, 0x00,0x00} }; static GSM_Error N6110_ReplyGetProfileFeature(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x14: smprintf(s, "Profile feature %02x with value %02x\n",msg.Buffer[6],msg.Buffer[8]); if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) { switch (msg.Buffer[6]) { case 0x02: smprintf(s, "Ringtone ID\n"); Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_RingtoneID; Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = msg.Buffer[8]; Data->Profile->FeaturesNumber++; break; case 0x09 : smprintf(s, "screen saver number\n"); Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_ScreenSaverNumber; Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = msg.Buffer[8] + 1; Data->Profile->FeaturesNumber++; break; case 0x24: smprintf(s, "selected profile\n"); if (msg.Buffer[8] + 1 == Data->Profile->Location) Data->Profile->Active = true; break; default: NOKIA_FindFeatureValue(s, Profile3310,msg.Buffer[6],msg.Buffer[8],Data,false); } return ERR_NONE; } switch (msg.Buffer[6]) { case 0x01: /* Lights */ if (Data->Profile->CarKitProfile) { NOKIA_FindFeatureValue(s, Profile6110,msg.Buffer[6],msg.Buffer[8],Data,false); } break; case 0x03: smprintf(s, "Ringtone ID\n"); Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_RingtoneID; Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = msg.Buffer[8]; Data->Profile->FeaturesNumber++; break; case 0x08: /* Caller groups */ if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES51)) { NOKIA_FindFeatureValue(s, Profile6110,msg.Buffer[6],msg.Buffer[8],Data,true); } break; case 0x09: /* Autoanswer */ if (Data->Profile->CarKitProfile || Data->Profile->HeadSetProfile) { NOKIA_FindFeatureValue(s, Profile6110,msg.Buffer[6],msg.Buffer[8],Data,false); } break; case 0x2A: smprintf(s, "selected profile\n"); if (msg.Buffer[8] + 1 == Data->Profile->Location) Data->Profile->Active = true; break; default: NOKIA_FindFeatureValue(s, Profile6110,msg.Buffer[6],msg.Buffer[8],Data,false); } return ERR_NONE; case 0x15: smprintf(s, "Invalid profile location\n"); return ERR_INVALIDLOCATION; case 0x1b: Data->Profile->Name[0] = 0; Data->Profile->Name[1] = 0; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) { EncodeUnicode(Data->Profile->Name,msg.Buffer+10,msg.Buffer[9]); } else { if (msg.Length > 0x0A) { CopyUnicodeString(Data->Profile->Name,msg.Buffer+10); } } smprintf(s, "Profile name: \"%s\"\n",Data->Profile->Name); Data->Profile->DefaultName = false; if (msg.Buffer[9]==0x00) Data->Profile->DefaultName = true; return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_GetProfile(GSM_StateMachine *s, GSM_Profile *Profile) { GSM_Error error; int i,j; unsigned char name_req[] = {N6110_FRAME_HEADER, 0x1a, 0x00}; unsigned char feat_req[] = {N6110_FRAME_HEADER, 0x13, 0x01, 0x00, /* Profile location */ 0x00}; /* Feature number */ s->Phone.Data.Profile=Profile; smprintf(s, "Getting profile name\n"); error = GSM_WaitFor (s, name_req, 5, 0x05, 4, ID_GetProfile); if (error!=ERR_NONE) return error; if (Profile->DefaultName) { NOKIA_GetDefaultProfileName(s, Profile); if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES51)) { switch(Profile->Location) { case 1: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Personal"),strlen(GetMsg(s->msg,"Personal"))); break; case 2: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Car"),strlen(GetMsg(s->msg,"Car"))); break; case 3: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Headset"),strlen(GetMsg(s->msg,"Headset"))); break; } } if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) { switch(Profile->Location) { case 1: EncodeUnicode(Profile->Name,GetMsg(s->msg,"General"),strlen(GetMsg(s->msg,"General"))); break; case 2: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Silent"),strlen(GetMsg(s->msg,"Silent"))); break; case 3: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Discreet"),strlen(GetMsg(s->msg,"Discreet"))); break; case 4: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Loud"),strlen(GetMsg(s->msg,"Loud"))); break; case 5: EncodeUnicode(Profile->Name,GetMsg(s->msg,"My style"),strlen(GetMsg(s->msg,"My style"))); break; case 6: Profile->Name[0] = 0; Profile->Name[1] = 0; break; } } } Profile->FeaturesNumber = 0; Profile->CarKitProfile = false; Profile->HeadSetProfile = false; if (Profile->Location == 6) Profile->CarKitProfile = true; if (Profile->Location == 7) Profile->HeadSetProfile = true; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES51)) { if (Profile->Location == 2) Profile->CarKitProfile = true; if (Profile->Location == 3) Profile->HeadSetProfile = true; } if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) { Profile->HeadSetProfile = false; //fixme Profile->CarKitProfile = false; } for (i = 0x00; i <= 0x09; i++) { feat_req[5] = Profile->Location - 1; feat_req[6] = i; smprintf(s, "Getting profile feature\n"); error = GSM_WaitFor (s, feat_req, 7, 0x05, 4, ID_GetProfile); if (error!=ERR_NONE) return error; } for (i=0;i<Profile->FeaturesNumber;i++) { if (Profile->FeatureID[i] == Profile_CallAlert && Profile->FeatureValue[i] != PROFILE_CALLALERT_CALLERGROUPS) { for (j=0;j<5;j++) Profile->CallerGroups[j] = true; } } Profile->Active = false; feat_req[5] = 0; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) { feat_req[6] = 0x24; } else { feat_req[6] = 0x2A; } smprintf(s, "Getting profile feature\n"); error = GSM_WaitFor (s, feat_req, 7, 0x05, 4, ID_GetProfile); return error; } static GSM_Error N6110_SetProfile(GSM_StateMachine *s, GSM_Profile *Profile) { int i; bool found; unsigned char ID,Value; GSM_Error error; GSM_Profile_PhoneTableValue *ProfilePhone = Profile6110; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) ProfilePhone = Profile3310; for (i=0;i<Profile->FeaturesNumber;i++) { found = false; if (ProfilePhone == Profile3310) { switch (Profile->FeatureID[i]) { case Profile_RingtoneID: ID = 0x02; Value = Profile->FeatureValue[i]; found = true; break; case Profile_ScreenSaverNumber: ID = 0x09; Value = Profile->FeatureValue[i]; found = true; break; default: found=NOKIA_FindPhoneFeatureValue( s, ProfilePhone, Profile->FeatureID[i],Profile->FeatureValue[i], &ID,&Value); } } if (ProfilePhone == Profile6110) { switch (Profile->FeatureID[i]) { case Profile_RingtoneID: ID = 0x03; Value = Profile->FeatureValue[i]; found = true; break; default: found=NOKIA_FindPhoneFeatureValue( s, ProfilePhone, Profile->FeatureID[i],Profile->FeatureValue[i], &ID,&Value); } } if (found) { error=N6110_SetProfileFeature (s,((unsigned char)(Profile->Location-1)),ID,Value); if (error!=ERR_NONE) return error; } } return ERR_NONE; } static GSM_Error N6110_ReplyIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; GSM_SMSMessage sms; #ifdef DEBUG smprintf(s, "SMS message received\n"); sms.State = SMS_UnRead; sms.InboxFolder = true; DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+7); #endif if (Data->EnableIncomingSMS && s->User.IncomingSMS!=NULL) { sms.State = SMS_UnRead; sms.InboxFolder = true; DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+7); s->User.IncomingSMS(s->CurrentConfig->Device,sms); } return ERR_NONE; } static GSM_Error N6110_ReplyAddCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Writting calendar note: "); switch (msg.Buffer[4]) { case 0x01: smprintf(s, "OK\n"); return ERR_NONE; case 0x73: case 0x7d: smprintf(s, "error\n"); return ERR_UNKNOWN; case 0x81: smprintf(s,"during editing notes in phone menu\n"); return ERR_INSIDEPHONEMENU; default: smprintf(s, "unknown ERROR %i\n",msg.Buffer[4]); } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { bool Reminder3310 = false; int Text, Time, Alarm, Phone, Recurrance, EndTime, Location, i, current; unsigned char mychar1,mychar2; unsigned char req[200] = {N6110_FRAME_HEADER, 0x64, 0x01, 0x10, 0x00, /* Length of the rest of the frame */ 0x00, /* Calendar note type */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x66, 0x01}; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOCALENDAR)) return ERR_NOTSUPPORTED; GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note, &Text, &Time, &Alarm, &Phone, &Recurrance, &EndTime, &Location); if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL52)) { switch(Note->Type) { case GSM_CAL_REMINDER: req[7]=0x01; break; case GSM_CAL_CALL : req[7]=0x02; break; case GSM_CAL_MEETING : req[7]=0x03; break; case GSM_CAL_BIRTHDAY: req[7]=0x04; break; case GSM_CAL_T_ATHL : req[7]=0x05; break; case GSM_CAL_T_BALL : req[7]=0x06; break; case GSM_CAL_T_CYCL : req[7]=0x07; break; case GSM_CAL_T_BUDO : req[7]=0x08; break; case GSM_CAL_T_DANC : req[7]=0x09; break; case GSM_CAL_T_EXTR : req[7]=0x0a; break; case GSM_CAL_T_FOOT : req[7]=0x0b; break; case GSM_CAL_T_GOLF : req[7]=0x0c; break; case GSM_CAL_T_GYM : req[7]=0x0d; break; case GSM_CAL_T_HORS : req[7]=0x0e; break; case GSM_CAL_T_HOCK : req[7]=0x0f; break; case GSM_CAL_T_RACE : req[7]=0x10; break; case GSM_CAL_T_RUGB : req[7]=0x11; break; case GSM_CAL_T_SAIL : req[7]=0x12; break; case GSM_CAL_T_STRE : req[7]=0x13; break; case GSM_CAL_T_SWIM : req[7]=0x14; break; case GSM_CAL_T_TENN : req[7]=0x15; break; case GSM_CAL_T_TRAV : req[7]=0x16; break; case GSM_CAL_T_WINT : req[7]=0x17; break; default : req[7]=0x01; break; } } else { switch(Note->Type) { case GSM_CAL_CALL : req[7]=0x02; break; case GSM_CAL_MEETING : req[7]=0x03; break; case GSM_CAL_BIRTHDAY: req[7]=0x04; break; case GSM_CAL_REMINDER: default : req[7]=0x01; break; } } if (Time == -1) return ERR_UNKNOWN; NOKIA_EncodeDateTime(s, req+8, &Note->Entries[Time].Date); req[14] = Note->Entries[Time].Date.Second; if (Alarm != -1) { NOKIA_EncodeDateTime(s, req+15, &Note->Entries[Alarm].Date); req[21] = Note->Entries[Alarm].Date.Second; } current = 23; if (Text != -1) { if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL52) || IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL82)) { req[22] = UnicodeLength(Note->Entries[Text].Text)*2; memcpy(req+current,Note->Entries[Text].Text,UnicodeLength(Note->Entries[Text].Text)*2); current += UnicodeLength(Note->Entries[Text].Text)*2; } else { req[22] = UnicodeLength(Note->Entries[Text].Text); if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL33)) { Reminder3310 = true; if (!strcmp(s->Phone.Data.ModelInfo->model,"3310") && s->Phone.Data.VerNum<5.11) { if (Note->Type!=GSM_CAL_REMINDER) Reminder3310 = false; } if (!strcmp(s->Phone.Data.ModelInfo->model,"3330") && s->Phone.Data.VerNum<=4.50) { if (Note->Type!=GSM_CAL_REMINDER) Reminder3310 = false; } if (Reminder3310) { req[22]++; /* one additional char */ req[current++] = 0x01; /* we use now subset 1 */ for (i=0;i<((int)UnicodeLength(Note->Entries[Text].Text));i++) { /* Euro char */ if (Note->Entries[Text].Text[i*2]==0x20 && Note->Entries[Text].Text[i*2+1]==0xAC) { req[current++] = 0xe2; req[current++] = 0x82; req[current++] = 0xac; req[23] = 0x03; /* use subset 3 */ req[22]+=2; /* two additional chars */ } else if (EncodeWithUTF8Alphabet(Note->Entries[Text].Text[i*2],Note->Entries[Text].Text[i*2+1],&mychar1,&mychar2)) { req[current++] = mychar1; req[current++] = mychar2; req[23] = 0x03; /* use subset 3 */ req[22]++; /* one additional char */ } else { current+=DecodeWithUnicodeAlphabet(((wchar_t)(Note->Entries[Text].Text[i*2]*256+Note->Entries[Text].Text[i*2+1])),req+current); } } } } if (!Reminder3310) { memcpy(req+current,DecodeUnicodeString(Note->Entries[Text].Text),UnicodeLength(Note->Entries[Text].Text)); current += UnicodeLength(Note->Entries[Text].Text); } } } else req[22] = 0x00; if (Note->Type == GSM_CAL_CALL) { if (Phone != -1) { req[current++] = UnicodeLength(Note->Entries[Phone].Text); memcpy(req+current,DecodeUnicodeString(Note->Entries[Phone].Text),UnicodeLength(Note->Entries[Phone].Text)); current += UnicodeLength(Note->Entries[Phone].Text); } else req[current++] = 0x00; } req[6] = current - 8; smprintf(s, "Writing calendar note\n"); return GSM_WaitFor (s, req, current, 0x13, 4, ID_SetCalendarNote); } static GSM_Error N6110_ReplyDeleteCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Deleting calendar note: "); switch (msg.Buffer[4]) { case 0x01: smprintf(s, "done OK\n"); return ERR_NONE; case 0x81: smprintf(s,"during editing notes in phone menu\n"); return ERR_INSIDEPHONEMENU; case 0x93: smprintf(s, "Can't be done - too high location ?\n"); return ERR_INVALIDLOCATION; default: smprintf(s, "unknown ERROR %i\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } } static GSM_Error N6110_DeleteCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { unsigned char req[] = {N6110_FRAME_HEADER, 0x68, 0x00}; /* Location */ if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOCALENDAR)) return ERR_NOTSUPPORTED; req[4] = Note->Location; smprintf(s, "Deleting calendar note\n"); return GSM_WaitFor (s, req, 5, 0x13, 5, ID_DeleteCalendarNote); } /* for example: "Euro_char" text */ static void Decode3310Subset3(int j, GSM_Protocol_Message msg, GSM_Phone_Data *Data) { wchar_t wc; int len = 0; int i; bool charfound; GSM_CalendarEntry *Entry = Data->Cal; i = j; while (i!=msg.Buffer[23]) { EncodeWithUnicodeAlphabet(msg.Buffer+24+i,&wc); charfound = false; if (i!=msg.Buffer[23]-2) { if (msg.Buffer[24+i] ==0xe2 && msg.Buffer[24+i+1]==0x82 && msg.Buffer[24+i+2]==0xac) { wc = 0x20 * 256 + 0xac; i+=2; charfound = true; } } if (i!=msg.Buffer[23]-1 && !charfound) { if (msg.Buffer[24+i]>=0xc2) { wc = DecodeWithUTF8Alphabet(msg.Buffer[24+i],msg.Buffer[24+i+1]); i++; } } Entry->Entries[Entry->EntriesNum].Text[len++] = (wc >> 8) & 0xff; Entry->Entries[Entry->EntriesNum].Text[len++] = wc & 0xff; i++; } Entry->Entries[Entry->EntriesNum].Text[len++] = 0; Entry->Entries[Entry->EntriesNum].Text[len++] = 0; } /* For example: "a with : above" char */ static void Decode3310Subset2(int j, GSM_Protocol_Message msg, GSM_Phone_Data *Data) { int len = 0; int i; GSM_CalendarEntry *Entry = Data->Cal; i = j; while (i!=msg.Buffer[23]) { Entry->Entries[Entry->EntriesNum].Text[len++] = 0x00; Entry->Entries[Entry->EntriesNum].Text[len++] = msg.Buffer[24+i]; i++; } Entry->Entries[Entry->EntriesNum].Text[len++] = 0; Entry->Entries[Entry->EntriesNum].Text[len++] = 0; } static GSM_Error N6110_ReplyGetNextCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i = 0; bool SpecialSubSet = false; GSM_CalendarEntry *Entry = s->Phone.Data.Cal; switch (msg.Buffer[4]) { case 0x01: smprintf(s, "Calendar note received\n"); switch (msg.Buffer[8]) { case 0x01: Entry->Type = GSM_CAL_REMINDER; break; case 0x02: Entry->Type = GSM_CAL_CALL; break; case 0x03: Entry->Type = GSM_CAL_MEETING; break; case 0x04: Entry->Type = GSM_CAL_BIRTHDAY; break; case 0x05: Entry->Type = GSM_CAL_T_ATHL; break; case 0x06: Entry->Type = GSM_CAL_T_BALL; break; case 0x07: Entry->Type = GSM_CAL_T_CYCL; break; case 0x08: Entry->Type = GSM_CAL_T_BUDO; break; case 0x09: Entry->Type = GSM_CAL_T_DANC; break; case 0x0a: Entry->Type = GSM_CAL_T_EXTR; break; case 0x0b: Entry->Type = GSM_CAL_T_FOOT; break; case 0x0c: Entry->Type = GSM_CAL_T_GOLF; break; case 0x0d: Entry->Type = GSM_CAL_T_GYM; break; case 0x0e: Entry->Type = GSM_CAL_T_HORS; break; case 0x0f: Entry->Type = GSM_CAL_T_HOCK; break; case 0x10: Entry->Type = GSM_CAL_T_RACE; break; case 0x11: Entry->Type = GSM_CAL_T_RUGB; break; case 0x12: Entry->Type = GSM_CAL_T_SAIL; break; case 0x13: Entry->Type = GSM_CAL_T_STRE; break; case 0x14: Entry->Type = GSM_CAL_T_SWIM; break; case 0x15: Entry->Type = GSM_CAL_T_TENN; break; case 0x16: Entry->Type = GSM_CAL_T_TRAV; break; case 0x17: Entry->Type = GSM_CAL_T_WINT; break; default : smprintf(s, "Unknown note type %i\n",msg.Buffer[8]); return ERR_UNKNOWNRESPONSE; } #ifdef DEBUG switch (msg.Buffer[8]) { case 0x01: smprintf(s, "Reminder\n"); break; case 0x02: smprintf(s, "Call\n"); break; case 0x03: smprintf(s, "Meeting\n"); break; case 0x04: smprintf(s, "Birthday\n"); break; } #endif Entry->EntriesNum = 0; NOKIA_DecodeDateTime(s, msg.Buffer+9, &Entry->Entries[0].Date); smprintf(s, "Time : %02i-%02i-%04i %02i:%02i:%02i\n", Entry->Entries[0].Date.Day,Entry->Entries[0].Date.Month,Entry->Entries[0].Date.Year, Entry->Entries[0].Date.Hour,Entry->Entries[0].Date.Minute,Entry->Entries[0].Date.Second); Entry->Entries[0].EntryType = CAL_START_DATETIME; Entry->EntriesNum++; NOKIA_DecodeDateTime(s, msg.Buffer+16, &Entry->Entries[1].Date); if (Entry->Entries[1].Date.Year!=0) { smprintf(s, "Alarm : %02i-%02i-%04i %02i:%02i:%02i\n", Entry->Entries[1].Date.Day,Entry->Entries[1].Date.Month,Entry->Entries[1].Date.Year, Entry->Entries[1].Date.Hour,Entry->Entries[1].Date.Minute,Entry->Entries[1].Date.Second); Entry->Entries[1].EntryType = CAL_ALARM_DATETIME; Entry->EntriesNum++; } else { smprintf(s, "No alarm\n"); } if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL52) || IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL82)) { memcpy(Entry->Entries[Entry->EntriesNum].Text,msg.Buffer+24,msg.Buffer[23]); Entry->Entries[Entry->EntriesNum].Text[msg.Buffer[23] ]=0; Entry->Entries[Entry->EntriesNum].Text[msg.Buffer[23]+1]=0; } else { if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL33)) { /* first char is subset for 33xx and reminders */ if (Entry->Type == GSM_CAL_REMINDER) { i=1; smprintf(s, "Subset %i in reminder note !\n",msg.Buffer[24]); } SpecialSubSet = true; switch (msg.Buffer[24]) { case 2 : Decode3310Subset2(i,msg,&s->Phone.Data); break; case 3 : Decode3310Subset3(i,msg,&s->Phone.Data); break; default : SpecialSubSet = false; break; } } if (!SpecialSubSet) { N6110_EncodeUnicode(s,Entry->Entries[Entry->EntriesNum].Text,msg.Buffer+24+i,msg.Buffer[23]-i); } } smprintf(s, "Text \"%s\"\n",DecodeUnicodeString(Entry->Entries[Entry->EntriesNum].Text)); if (msg.Buffer[23] != 0x00) { Entry->Entries[Entry->EntriesNum].EntryType = CAL_TEXT; Entry->EntriesNum++; } if (Entry->Type == GSM_CAL_CALL) { EncodeUnicode(Entry->Entries[Entry->EntriesNum].Text,msg.Buffer+24+msg.Buffer[23]+1,msg.Buffer[24+msg.Buffer[23]]); smprintf(s, "Phone : \"%s\"\n",DecodeUnicodeString(Entry->Entries[Entry->EntriesNum].Text)); if (msg.Buffer[24+msg.Buffer[23]] != 0x00) { Entry->Entries[Entry->EntriesNum].EntryType = CAL_PHONE; Entry->EntriesNum++; } } return ERR_NONE; case 0x93: smprintf(s, "Can't get calendar note - too high location?\n"); return ERR_INVALIDLOCATION; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6110_GetNextCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) { int Text, Time, Alarm, Phone, Recurrance, EndTime, Location; GSM_Error error; GSM_DateTime date_time; GSM_Phone_N6110Data *Priv = &s->Phone.Data.Priv.N6110; unsigned char req[] = {N6110_FRAME_HEADER, 0x66, 0x00}; /* Location */ if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOCALENDAR)) return ERR_NOTSUPPORTED; if (start) { Priv->LastCalendarPos = 1; } else { Priv->LastCalendarPos++; } Note->Location = Priv->LastCalendarPos; req[4] = Priv->LastCalendarPos; s->Phone.Data.Cal=Note; smprintf(s, "Getting calendar note\n"); error=GSM_WaitFor (s, req, 5, 0x13, 4, ID_GetCalendarNote); GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note, &Text, &Time, &Alarm, &Phone, &Recurrance, &EndTime, &Location); /* 2090 year is set for example in 3310 */ if (error == ERR_NONE && Note->Entries[Time].Date.Year == 2090) { error=N6110_GetDateTime(s, &date_time); if (error == ERR_NONE) Note->Entries[Time].Date.Year = date_time.Year; } return error; } GSM_Error N6110_ReplyUSSDInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char buffer[2000],buffer2[4000]; int tmp; tmp=GSM_UnpackEightBitsToSeven(0, msg.Buffer[7], 82, msg.Buffer+8, buffer); buffer[tmp] = 0; smprintf(s, "USSD reply: \"%s\"\n",buffer); if (s->Phone.Data.EnableIncomingUSSD && s->User.IncomingUSSD!=NULL) { EncodeUnicode(buffer2,buffer,strlen(buffer)); s->User.IncomingUSSD(s->CurrentConfig->Device, buffer2); } return ERR_NONE; } GSM_Error N6110_AnswerCall(GSM_StateMachine *s, int ID, bool all) { GSM_Error error; unsigned char req1[] = {N6110_FRAME_HEADER, 0x42, 0x05, 0x01, 0x07, 0xa2, 0x88, 0x81, 0x21, 0x15, 0x63, 0xa8, 0x00, 0x00, 0x07, 0xa3, 0xb8, 0x81, 0x20, 0x15, 0x63, 0x80}; if (!all) { smprintf(s, "Answering call part 1\n"); error = GSM_WaitFor (s, req1, 24, 0x01, 5, ID_AnswerCall); if (error != ERR_NONE) return error; return DCT3DCT4_AnswerCall(s,ID); } return DCT3_AnswerAllCalls(s); } static GSM_Error N6110_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber) { unsigned int pos = 4; unsigned char req[100] = {N6110_FRAME_HEADER,0x01, 0x0c}; /* Length of number */ if (ShowNumber == GSM_CALL_DefaultNumberPresence) return DCT3_DialVoice(s,number,ShowNumber); req[pos++] = strlen(number); memcpy(req+pos,number,strlen(number)); pos += strlen(number); req[pos++] = 0x05; /* call type: voice - 0x05, data - 0x01 */ req[pos++] = 0x01; req[pos++] = 0x01; req[pos++] = 0x05; req[pos++] = 0x81; switch (ShowNumber) { case GSM_CALL_HideNumber: req[pos++] = 0x02; break; case GSM_CALL_ShowNumber: req[pos++] = 0x03; break; case GSM_CALL_DefaultNumberPresence: req[pos++] = 0x01; break; } req[pos++] = 0x00; req[pos++] = 0x00; smprintf(s, "Making voice call\n"); return GSM_WaitFor (s, req, pos, 0x01, 4, ID_DialVoice); } GSM_Error N6110_UnholdCall(GSM_StateMachine *s, int ID) { unsigned char req[] = {N6110_FRAME_HEADER, 0x24, 0x00, 0x02}; req[4] = (unsigned char)ID; s->Phone.Data.CallID = ID; smprintf(s, "Unholding call\n"); return GSM_WaitFor (s, req, 6, 0x01, 4, ID_UnholdCall); } GSM_Error N6110_HoldCall(GSM_StateMachine *s, int ID) { unsigned char req[] = {N6110_FRAME_HEADER, 0x22, 0x00, 0x00}; req[4] = (unsigned char)ID; s->Phone.Data.CallID = ID; smprintf(s, "Unholding call\n"); return GSM_WaitFor (s, req, 6, 0x01, 4, ID_HoldCall); } /* Joining selected call to current (and making conference) */ GSM_Error N6110_ConferenceCall(GSM_StateMachine *s, int ID) { unsigned char req[] = {N6110_FRAME_HEADER, 0x28, 0x00, 0x01}; req[4] = (unsigned char)ID; s->Phone.Data.CallID = ID; smprintf(s, "Conference call\n"); return GSM_WaitFor (s, req, 6, 0x01, 4, ID_ConferenceCall); } /* Removing selected call from conference and making private call with it * (conference call is on hold) */ GSM_Error N6110_SplitCall(GSM_StateMachine *s, int ID) { unsigned char req[] = {N6110_FRAME_HEADER, 0x2A, 0x00, 0x01}; req[4] = (unsigned char)ID; s->Phone.Data.CallID = ID; smprintf(s, "Split call\n"); return GSM_WaitFor (s, req, 6, 0x01, 4, ID_SplitCall); } /* This probably need more investigation */ GSM_Error N6110_SwitchCall(GSM_StateMachine *s, int ID, bool next) { // unsigned char req[] = {N6110_FRAME_HEADER, 0x20}; calls info unsigned char req[] = {N6110_FRAME_HEADER, 0x26, 0x00}; s->Phone.Data.CallID = ID; if (next) { smprintf(s, "Switch call\n"); return GSM_WaitFor (s, req, 4, 0x01, 4, ID_SwitchCall); } else { req[4] = (unsigned char)ID; smprintf(s, "Switch call\n"); return GSM_WaitFor (s, req, 5, 0x01, 4, ID_SwitchCall); } } /* This probably need more investigation */ GSM_Error N6110_TransferCall(GSM_StateMachine *s, int ID, bool next) { unsigned char req[] = {N6110_FRAME_HEADER, 0x2C, 0x00}; s->Phone.Data.CallID = ID; if (next) { smprintf(s, "Transfer call\n"); return GSM_WaitFor (s, req, 4, 0x01, 4, ID_TransferCall); } else { req[4] = (unsigned char)ID; smprintf(s, "Transfer call\n"); return GSM_WaitFor (s, req, 5, 0x01, 4, ID_TransferCall); } } static GSM_Reply_Function N6110ReplyFunctions[] = { {N6110_ReplyCallInfo, "\x01",0x03,0x02,ID_IncomingFrame }, {N6110_ReplyCallInfo, "\x01",0x03,0x03,ID_IncomingFrame }, {N6110_ReplyCallInfo, "\x01",0x03,0x04,ID_IncomingFrame }, {N6110_ReplyCallInfo, "\x01",0x03,0x05,ID_IncomingFrame }, {N6110_ReplyCallInfo, "\x01",0x03,0x07,ID_AnswerCall }, {N6110_ReplyCallInfo, "\x01",0x03,0x07,ID_IncomingFrame }, {N6110_ReplyCallInfo, "\x01",0x03,0x09,ID_CancelCall }, {N6110_ReplyCallInfo, "\x01",0x03,0x09,ID_IncomingFrame }, {N6110_ReplyCallInfo, "\x01",0x03,0x0A,ID_IncomingFrame }, {N6110_ReplyCallInfo, "\x01",0x03,0x23,ID_HoldCall }, {N6110_ReplyCallInfo, "\x01",0x03,0x23,ID_IncomingFrame }, {N6110_ReplyCallInfo, "\x01",0x03,0x25,ID_UnholdCall }, {N6110_ReplyCallInfo, "\x01",0x03,0x25,ID_IncomingFrame }, {N6110_ReplyCallInfo, "\x01",0x03,0x27,ID_IncomingFrame }, {N6110_ReplyCallInfo, "\x01",0x03,0x29,ID_ConferenceCall }, {N6110_ReplyCallInfo, "\x01",0x03,0x29,ID_IncomingFrame }, {N6110_ReplyCallInfo, "\x01",0x03,0x2B,ID_SplitCall }, {N6110_ReplyCallInfo, "\x01",0x03,0x2B,ID_IncomingFrame }, {N6110_ReplySendDTMF, "\x01",0x03,0x40,ID_SendDTMF }, {NoneReply, "\x01",0x03,0x40,ID_DialVoice }, {NoneReply, "\x01",0x03,0x40,ID_IncomingFrame }, {NoneReply, "\x01",0x03,0x43,ID_AnswerCall }, {N6110_ReplySendDTMF, "\x01",0x03,0x51,ID_SendDTMF }, {DCT3_ReplySendSMSMessage, "\x02",0x03,0x02,ID_IncomingFrame }, {DCT3_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame }, {N6110_ReplyIncomingSMS, "\x02",0x03,0x10,ID_IncomingFrame }, #ifdef GSM_ENABLE_CELLBROADCAST {DCT3_ReplySetIncomingCB, "\x02",0x03,0x21,ID_SetIncomingCB }, {DCT3_ReplySetIncomingCB, "\x02",0x03,0x22,ID_SetIncomingCB }, {DCT3_ReplyIncomingCB, "\x02",0x03,0x23,ID_IncomingFrame }, #endif {DCT3_ReplySetSMSC, "\x02",0x03,0x31,ID_SetSMSC }, {DCT3_ReplyGetSMSC, "\x02",0x03,0x34,ID_GetSMSC }, {DCT3_ReplyGetSMSC, "\x02",0x03,0x35,ID_GetSMSC }, {N6110_ReplyGetMemory, "\x03",0x03,0x02,ID_GetMemory }, {N6110_ReplyGetMemory, "\x03",0x03,0x03,ID_GetMemory }, {N6110_ReplySetMemory, "\x03",0x03,0x05,ID_SetMemory }, {N6110_ReplySetMemory, "\x03",0x03,0x06,ID_SetMemory }, {N6110_ReplyGetMemoryStatus, "\x03",0x03,0x08,ID_GetMemoryStatus }, {N6110_ReplyGetMemoryStatus, "\x03",0x03,0x09,ID_GetMemoryStatus }, {N6110_ReplyGetCallerLogo, "\x03",0x03,0x11,ID_GetBitmap }, {N6110_ReplyGetCallerLogo, "\x03",0x03,0x12,ID_GetBitmap }, {N6110_ReplySetCallerLogo, "\x03",0x03,0x14,ID_SetBitmap }, {N6110_ReplySetCallerLogo, "\x03",0x03,0x15,ID_SetBitmap }, {N6110_ReplyGetSpeedDial, "\x03",0x03,0x17,ID_GetSpeedDial }, {N6110_ReplyGetSpeedDial, "\x03",0x03,0x18,ID_GetSpeedDial }, /* 0x1A, 0x1B - reply set speed dial */ {N6110_ReplyGetStatus, "\x04",0x03,0x02,ID_GetSignalQuality }, {N6110_ReplyGetStatus, "\x04",0x03,0x02,ID_GetBatteryCharge }, {N6110_ReplySetProfileFeature, "\x05",0x03,0x11,ID_SetProfile }, {N6110_ReplySetProfileFeature, "\x05",0x03,0x12,ID_SetProfile }, {N6110_ReplyGetProfileFeature, "\x05",0x03,0x14,ID_GetProfile }, {N6110_ReplyGetPhoneLanguage, "\x05",0x03,0x14,ID_GetLanguage }, {N6110_ReplyGetProfileFeature, "\x05",0x03,0x15,ID_GetProfile }, {N6110_ReplyGetPhoneLanguage, "\x05",0x03,0x15,ID_GetLanguage }, {N6110_ReplyGetStartup, "\x05",0x03,0x17,ID_GetBitmap }, {N6110_ReplySetStartup, "\x05",0x03,0x19,ID_SetBitmap }, {N6110_ReplyGetProfileFeature, "\x05",0x03,0x1b,ID_GetProfile }, {N61_91_ReplySetOpLogo, "\x05",0x03,0x31,ID_SetBitmap }, {N61_91_ReplySetOpLogo, "\x05",0x03,0x32,ID_SetBitmap }, {N6110_ReplyGetOpLogo, "\x05",0x03,0x34,ID_GetBitmap }, {N6110_ReplySetRingtone, "\x05",0x03,0x37,ID_SetRingtone }, {N6110_ReplySetRingtone, "\x05",0x03,0x38,ID_SetRingtone }, {DCT3DCT4_ReplyCallDivert, "\x06",0x03,0x02,ID_Divert }, {DCT3DCT4_ReplyCallDivert, "\x06",0x03,0x03,ID_Divert }, {N6110_ReplyUSSDInfo, "\x06",0x03,0x05,ID_IncomingFrame }, {NoneReply, "\x06",0x03,0x06,ID_IncomingFrame },//incoming call divert info {N6110_ReplyGetSecurityStatus, "\x08",0x03,0x08,ID_GetSecurityStatus }, {N6110_ReplyEnterSecurityCode, "\x08",0x03,0x0b,ID_EnterSecurityCode }, {N6110_ReplyEnterSecurityCode, "\x08",0x03,0x0c,ID_EnterSecurityCode }, {DCT3_ReplySIMLogin, "\x09",0x03,0x80,ID_IncomingFrame }, {DCT3_ReplySIMLogout, "\x09",0x03,0x81,ID_IncomingFrame }, {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_GetNetworkInfo }, {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_IncomingFrame }, {N6110_ReplyGetDisplayStatus, "\x0D",0x03,0x52,ID_GetDisplayStatus }, {N6110_ReplyGetDisplayStatus, "\x0D",0x03,0x52,ID_IncomingFrame }, {DCT3_ReplySetDateTime, "\x11",0x03,0x61,ID_SetDateTime }, {DCT3_ReplyGetDateTime, "\x11",0x03,0x63,ID_GetDateTime }, {DCT3_ReplySetAlarm, "\x11",0x03,0x6C,ID_SetAlarm }, {DCT3_ReplyGetAlarm, "\x11",0x03,0x6E,ID_GetAlarm }, {N6110_ReplyAddCalendar, "\x13",0x03,0x65,ID_SetCalendarNote }, {N6110_ReplyAddCalendar, "\x13",0x03,0x65,ID_IncomingFrame }, {N6110_ReplyGetNextCalendar, "\x13",0x03,0x67,ID_GetCalendarNote }, {N6110_ReplyDeleteCalendar, "\x13",0x03,0x69,ID_DeleteCalendarNote }, {N6110_ReplyDeleteCalendar, "\x13",0x03,0x69,ID_IncomingFrame }, {N6110_ReplySaveSMSMessage, "\x14",0x03,0x05,ID_SaveSMSMessage }, {N6110_ReplySaveSMSMessage, "\x14",0x03,0x06,ID_SaveSMSMessage }, {N6110_ReplyGetSMSMessage, "\x14",0x03,0x08,ID_GetSMSMessage }, {N6110_ReplyGetSMSMessage, "\x14",0x03,0x09,ID_GetSMSMessage }, {DCT3_ReplyDeleteSMSMessage, "\x14",0x03,0x0B,ID_DeleteSMSMessage }, {DCT3_ReplyDeleteSMSMessage, "\x14",0x03,0x0C,ID_DeleteSMSMessage }, {N6110_ReplyGetSMSStatus, "\x14",0x03,0x37,ID_GetSMSStatus }, {N6110_ReplyGetSMSStatus, "\x14",0x03,0x38,ID_GetSMSStatus }, {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x01,ID_EnableConnectFunc }, {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x02,ID_EnableConnectFunc }, {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x04,ID_DisableConnectFunc }, {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x05,ID_DisableConnectFunc }, {DCT3_ReplyGetWAPBookmark, "\x3f",0x03,0x07,ID_GetWAPBookmark }, {DCT3_ReplyGetWAPBookmark, "\x3f",0x03,0x08,ID_GetWAPBookmark }, {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0A,ID_SetWAPBookmark }, {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0B,ID_SetWAPBookmark }, {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0D,ID_DeleteWAPBookmark }, {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0E,ID_DeleteWAPBookmark }, {DCT3DCT4_ReplyGetActiveConnectSet,"\x3f",0x03,0x10,ID_GetConnectSet }, {DCT3DCT4_ReplySetActiveConnectSet,"\x3f",0x03,0x13,ID_SetConnectSet }, {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x16,ID_GetConnectSet }, {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x17,ID_GetConnectSet }, {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x19,ID_SetConnectSet }, {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x1A,ID_SetConnectSet }, {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x1C,ID_GetConnectSet }, {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x1D,ID_GetConnectSet }, {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x1F,ID_SetConnectSet }, {DCT3_ReplyEnableSecurity, "\x40",0x02,0x64,ID_EnableSecurity }, {N61_71_ReplyResetPhoneSettings, "\x40",0x02,0x65,ID_ResetPhoneSettings }, {DCT3_ReplyGetIMEI, "\x40",0x02,0x66,ID_GetIMEI }, {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_DialVoice }, {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_CancelCall }, {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_AnswerCall }, {DCT3_ReplyNetmonitor, "\x40",0x02,0x7E,ID_Netmonitor }, {DCT3_ReplyPlayTone, "\x40",0x02,0x8F,ID_PlayTone }, {N6110_ReplyGetRingtone, "\x40",0x02,0x9E,ID_GetRingtone }, {N6110_ReplySetBinRingtone, "\x40",0x02,0xA0,ID_SetRingtone }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetHardware }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetPPM }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCA,ID_GetProductCode }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetManufactureMonth}, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetOriginalIMEI }, {N6110_ReplyGetSetPicture, "\x47",0x03,0x02,ID_GetBitmap }, {N6110_ReplyGetSetPicture, "\x47",0x03,0x04,ID_SetBitmap }, {N6110_ReplyGetSetPicture, "\x47",0x03,0x05,ID_SetBitmap }, {N6110_ReplyGetSetPicture, "\x47",0x03,0x06,ID_GetBitmap }, #ifndef ENABLE_LGPL {N6110_ReplyGetMagicBytes, "\x64",0x00,0x00,ID_MakeAuthentication }, #endif {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetModel }, {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetFirmware }, {DCT3_ReplyPressKey, "\xD2",0x02,0x46,ID_PressKey }, {DCT3_ReplyPressKey, "\xD2",0x02,0x47,ID_PressKey }, {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions N6110Phone = { "2100|3210|3310|3330|3390|3410|3610|5110|5110i|5130|5190|5210|5510|6110|6130|6150|6190|8210|8250|8290|8850|8855|8890", N6110ReplyFunctions, N6110_Initialise, PHONE_Terminate, GSM_DispatchMessage, N6110_ShowStartInfo, NOKIA_GetManufacturer, DCT3DCT4_GetModel, DCT3DCT4_GetFirmware, DCT3_GetIMEI, DCT3_GetOriginalIMEI, DCT3_GetManufactureMonth, DCT3_GetProductCode, DCT3_GetHardware, DCT3_GetPPM, NOTSUPPORTED, /* GetSIMIMSI */ N6110_GetDateTime, N6110_SetDateTime, N6110_GetAlarm, N6110_SetAlarm, NOTSUPPORTED, /* GetLocale */ NOTSUPPORTED, /* SetLocale */ DCT3_PressKey, DCT3_Reset, N61_71_ResetPhoneSettings, N6110_EnterSecurityCode, N6110_GetSecurityStatus, N6110_GetDisplayStatus, NOTIMPLEMENTED, /* SetAutoNetworkLogin */ N6110_GetBatteryCharge, N6110_GetSignalQuality, DCT3_GetNetworkInfo, NOTSUPPORTED, /* GetCategory */ NOTSUPPORTED, /* AddCategory */ NOTSUPPORTED, /* GetCategoryStatus */ N6110_GetMemoryStatus, N6110_GetMemory, NOTIMPLEMENTED, /* GetNextMemory */ N6110_SetMemory, NOTIMPLEMENTED, /* AddMemory */ N6110_DeleteMemory, NOTIMPLEMENTED, /* DeleteAllMemory */ N6110_GetSpeedDial, NOTIMPLEMENTED, /* SetSpeedDial */ DCT3_GetSMSC, DCT3_SetSMSC, DCT3_GetSMSStatus, N6110_GetSMSMessage, N6110_GetNextSMSMessage, N6110_SetSMS, N6110_AddSMS, N6110_DeleteSMSMessage, DCT3_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ NOTSUPPORTED, /* SetFastSMSSending */ NOKIA_SetIncomingSMS, DCT3_SetIncomingCB, PHONE_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ N6110_DialVoice, N6110_AnswerCall, DCT3_CancelCall, N6110_HoldCall, N6110_UnholdCall, N6110_ConferenceCall, N6110_SplitCall, N6110_TransferCall, N6110_SwitchCall, DCT3DCT4_GetCallDivert, DCT3DCT4_SetCallDivert, DCT3DCT4_CancelAllDiverts, NOKIA_SetIncomingCall, NOKIA_SetIncomingUSSD, DCT3DCT4_SendDTMF, N6110_GetRingtone, N6110_SetRingtone, NOTSUPPORTED, /* GetRingtonesInfo */ NOTSUPPORTED, /* DeleteUserRingtones */ DCT3_PlayTone, DCT3_GetWAPBookmark, DCT3_SetWAPBookmark, DCT3_DeleteWAPBookmark, DCT3_GetWAPSettings, DCT3_SetWAPSettings, NOTSUPPORTED, /* GetMMSSettings */ NOTSUPPORTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetSyncMLSettings */ NOTSUPPORTED, /* SetSyncMLSettings */ NOTSUPPORTED, /* GetChatSettings */ NOTSUPPORTED, /* SetChatSettings */ N6110_GetBitmap, N6110_SetBitmap, NOTSUPPORTED, /* GetToDoStatus */ NOTSUPPORTED, /* GetToDo */ NOTSUPPORTED, /* GetNextToDo */ NOTSUPPORTED, /* SetToDo */ NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ NOTIMPLEMENTED, /* GetCalendarStatus */ NOTIMPLEMENTED, /* GetCalendar */ N6110_GetNextCalendarNote, NOTIMPLEMENTED, /* SetCalendar */ N6110_AddCalendarNote, N6110_DeleteCalendarNote, NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* GetNoteStatus */ + NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* SetNote */ + NOTSUPPORTED, /* AddNote */ + NOTSUPPORTED, /* DeleteNote */ + NOTSUPPORTED, /* DeleteAllNotes */ N6110_GetProfile, N6110_SetProfile, NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ NOTSUPPORTED /* SetGPRSAccessPoint */ }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/nokia/dct3/n7110.c b/gammu/emb/common/phone/nokia/dct3/n7110.c index b597f9b..a8e0545 100644 --- a/gammu/emb/common/phone/nokia/dct3/n7110.c +++ b/gammu/emb/common/phone/nokia/dct3/n7110.c @@ -1,1729 +1,1744 @@ /* (c) 2001-2004 by Marcin Wiacek */ /* based on some Markus Plail work from Gnokii (www.gnokii.org) * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot * GNU GPL version 2 or later */ +/* Due to a problem in the source code management, the names of some of + * the authors have unfortunately been lost. We do not mean to belittle + * their efforts and hope they will contact us to see their names + * properly added to the Copyright notice above. + * Having published their contributions under the terms of the GNU + * General Public License (GPL) [version 2], the Copyright of these + * authors will remain respected by adhering to the license they chose + * to publish their code under. + */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA7110 #include <string.h> #include <time.h> #include "../../../misc/coding/coding.h" #include "../../../gsmcomon.h" #include "../../../service/gsmlogo.h" #include "../../pfunc.h" #include "../nfunc.h" #include "../nfuncold.h" #include "n7110.h" #include "dct3func.h" static GSM_Error N7110_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) { return DCT3_GetAlarm(s, alarm, 0x19); } static GSM_Error N7110_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) { return DCT3_SetAlarm(s, alarm, 0x19); } static GSM_Error N7110_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Phonebook entry received\n"); switch (msg.Buffer[6]) { case 0x0f: return N71_65_ReplyGetMemoryError(msg.Buffer[10], s); default: return N71_65_DecodePhonebook(s, Data->Memory,Data->Bitmap,Data->SpeedDial,msg.Buffer+18,msg.Length-18,false); } return ERR_UNKNOWN; } static GSM_Error N7110_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry) { unsigned char req[] = {N7110_FRAME_HEADER, 0x07, 0x01, 0x01, 0x00, 0x01, 0x02, /* memory type */ 0x05, 0x00, 0x00, /* location */ 0x00, 0x00}; req[9] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES); if (req[9]==0xff) return ERR_NOTSUPPORTED; if (entry->Location==0x00) return ERR_INVALIDLOCATION; req[10] = entry->Location / 256; req[11] = entry->Location % 256; s->Phone.Data.Memory=entry; smprintf(s, "Getting phonebook entry\n"); return GSM_WaitFor (s, req, 14, 0x03, 4, ID_GetMemory); } static GSM_Error N7110_ReplyGetMemoryStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Memory status received\n"); /* Quess ;-)) */ if (msg.Buffer[10]==0x10) { Data->MemoryStatus->MemoryFree = msg.Buffer[14]*256 + msg.Buffer[15]; } else { Data->MemoryStatus->MemoryFree = msg.Buffer[18]; } smprintf(s, " Size : %i\n",Data->MemoryStatus->MemoryFree); Data->MemoryStatus->MemoryUsed = msg.Buffer[16]*256 + msg.Buffer[17]; smprintf(s, " Used : %i\n",Data->MemoryStatus->MemoryUsed); Data->MemoryStatus->MemoryFree -= Data->MemoryStatus->MemoryUsed; smprintf(s, " Free : %i\n",Data->MemoryStatus->MemoryFree); return ERR_NONE; } static GSM_Error N7110_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status) { unsigned char req[] = {N6110_FRAME_HEADER, 0x03, 0x02, 0x05}; /* Memory type */ req[5] = NOKIA_GetMemoryType(s, Status->MemoryType,N71_65_MEMORY_TYPES); if (req[5]==0xff) return ERR_NOTSUPPORTED; s->Phone.Data.MemoryStatus=Status; smprintf(s, "Getting memory status\n"); return GSM_WaitFor (s, req, 6, 0x03, 4, ID_GetMemoryStatus); } static void N7110_GetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *folderid, int *location) { int ifolderid; /* simulate flat SMS memory */ if (sms->Folder==0x00) { ifolderid = sms->Location / PHONE_MAXSMSINFOLDER; *folderid = (ifolderid + 1) * 0x08; *location = sms->Location - ifolderid * PHONE_MAXSMSINFOLDER; } else { *folderid = sms->Folder * 0x08; *location = sms->Location; } smprintf(s, "SMS folder %i & location %i -> 7110 folder %i & location %i\n", sms->Folder,sms->Location,*folderid,*location); } static void N7110_SetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char folderid, int location) { sms->Folder = 0; sms->Location = (folderid / 0x08 - 1) * PHONE_MAXSMSINFOLDER + location; smprintf(s, "7110 folder %i & location %i -> SMS folder %i & location %i\n", folderid,location,sms->Folder,sms->Location); } static GSM_Error N7110_ReplyGetSMSFolders(GSM_Protocol_Message msg, GSM_StateMachine *s) { int j,current=5; unsigned char buffer[200]; GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x7B: smprintf(s, "Names for SMS folders received\n"); Data->SMSFolders->Number=msg.Buffer[4]; for (j=0;j<msg.Buffer[4];j++) { smprintf(s, "Folder index: %02x",msg.Buffer[current]); current++; smprintf(s, ", folder name: \""); CopyUnicodeString(buffer,msg.Buffer+current); if ((UnicodeLength(buffer))>GSM_MAX_SMS_FOLDER_NAME_LEN) { smprintf(s, "Too long text\n"); return ERR_UNKNOWNRESPONSE; } CopyUnicodeString(Data->SMSFolders->Folder[j].Name,buffer); smprintf(s, "%s\"\n",DecodeUnicodeString(buffer)); current=current+2+UnicodeLength(buffer)*2; Data->SMSFolders->Folder[j].InboxFolder = false; if (j==0) Data->SMSFolders->Folder[j].InboxFolder = true; Data->SMSFolders->Folder[j].Memory = MEM_ME; if (j==0 || j==1) Data->SMSFolders->Folder[j].InboxFolder = MEM_MT; } return ERR_NONE; case 0x7C: smprintf(s, "Security error ? No PIN ?\n"); return ERR_SECURITYERROR; case 0xCA: smprintf(s, "Wait a moment. Phone is during power on and busy now\n"); return ERR_SECURITYERROR; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N7110_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders) { unsigned char req[] = {N6110_FRAME_HEADER, 0x7A, 0x00, 0x00}; s->Phone.Data.SMSFolders=folders; smprintf(s, "Getting SMS folders\n"); return GSM_WaitFor (s, req, 6, 0x14, 4, ID_GetSMSFolders); } static GSM_Error N7110_ReplyGetSMSFolderStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; GSM_Phone_N7110Data *Priv = &s->Phone.Data.Priv.N7110; smprintf(s, "SMS folder status received\n"); Priv->LastSMSFolder.Number=msg.Buffer[4]*256+msg.Buffer[5]; smprintf(s, "Number of Entries: %i\n",Priv->LastSMSFolder.Number); smprintf(s, "Locations: "); for (i=0;i<Priv->LastSMSFolder.Number;i++) { Priv->LastSMSFolder.Location[i]=msg.Buffer[6+(i*2)]*256+msg.Buffer[(i*2)+7]; if (Priv->LastSMSFolder.Location[i] > PHONE_MAXSMSINFOLDER) { smprintf(s, "Increase PHONE_MAXSMSINFOLDER\n"); return ERR_UNKNOWNRESPONSE; } smprintf(s, "%i ",Priv->LastSMSFolder.Location[i]); } smprintf(s, "\n"); NOKIA_SortSMSFolderStatus(s, &Priv->LastSMSFolder); return ERR_NONE; } static GSM_Error N7110_PrivGetSMSFolderStatus(GSM_StateMachine *s, int folderid) { unsigned char req[] = {N7110_FRAME_HEADER, 0x6b, 0x08, /* folderID */ 0x0F, 0x01}; req[4] = folderid; smprintf(s, "Getting SMS folder status\n"); return GSM_WaitFor (s, req, 7, 0x14, 4, ID_GetSMSFolderStatus); } static GSM_Error N7110_GetSMSFolderStatus(GSM_StateMachine *s, int folderid) { GSM_Error error; int i; GSM_NOKIASMSFolder folder; error = N7110_PrivGetSMSFolderStatus(s,folderid); /* 0x08 contais read Inbox, 0xf8 unread Inbox. * we want all msg from Inbox, so read both 0x08 and 0xf8 */ if (folderid==0x08 && error==ERR_NONE) { folder=s->Phone.Data.Priv.N7110.LastSMSFolder; error = N7110_PrivGetSMSFolderStatus(s,0xf8); if (error==ERR_NONE) { for (i=0;i<folder.Number;i++) { s->Phone.Data.Priv.N7110.LastSMSFolder.Location[s->Phone.Data.Priv.N7110.LastSMSFolder.Number++]=folder.Location[i]; } } } return error; } static GSM_SMSMessageLayout N7110_SMSTemplate = { 36 /* SMS Text */, 17 /* Phone number */, 255 /* SMSC Number */, 15 /* TPDCS */, 255 /* SendingDateTime */, 255 /* SMSCDateTime */, 255 /* TPStatus */, 16 /* TPUDL */, 255 /* TPVP */, 12 /* firstbyte */, 13 /* TPMR */, 255 /* TPPID?? */}; static GSM_Error N7110_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; int Width, Height; unsigned char output[500], output2[500]; GSM_Phone_Data *Data = &s->Phone.Data; switch(msg.Buffer[3]) { case 0x08: switch (msg.Buffer[8]) { case 0x00: case 0x01: smprintf(s, "SMS message\n"); if (Data->RequestID == ID_GetSMSMessage) { Data->GetSMSMessage->Number=1; NOKIA_DecodeSMSState(s, msg.Buffer[4], &Data->GetSMSMessage->SMS[0]); DCT3_DecodeSMSFrame(s, &Data->GetSMSMessage->SMS[0],msg.Buffer+9); return ERR_NONE; } case 0x02: smprintf(s, "SMS template\n"); if (Data->RequestID == ID_GetSMSMessage) { Data->GetSMSMessage->Number=1; NOKIA_DecodeSMSState(s, msg.Buffer[4], &Data->GetSMSMessage->SMS[0]); Data->GetSMSMessage->SMS[0].PDU=SMS_Submit; GSM_DecodeSMSFrame(&Data->GetSMSMessage->SMS[0],msg.Buffer+9,N7110_SMSTemplate); return ERR_NONE; } case 0x07: smprintf(s, "Picture Image\n"); switch (Data->RequestID) { case ID_GetBitmap: PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height); Data->Bitmap->BitmapWidth = Width; Data->Bitmap->BitmapHeight = Height; PHONE_DecodeBitmap(GSM_NokiaPictureImage, msg.Buffer + 51, Data->Bitmap); GSM_UnpackSemiOctetNumber(Data->Bitmap->Sender,msg.Buffer+22,true); #ifdef DEBUG GSM_UnpackSemiOctetNumber(output,msg.Buffer+9,true); smprintf(s, "SMSC : %s\n",DecodeUnicodeString(output)); #endif Data->Bitmap->Text[0] = 0; Data->Bitmap->Text[1] = 0; if (msg.Length!=304) { GSM_UnpackEightBitsToSeven(0, msg.Length-304, msg.Length-304, msg.Buffer+52+PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0),output); DecodeDefault(Data->Bitmap->Text, output, msg.Length - 304, true, NULL); } return ERR_NONE; case ID_GetSMSMessage: Data->GetSMSMessage->Number = 0; i = 0; output[i++] = 0x30; /* Smart Messaging 3.0 */ output[i++] = SM30_OTA; output[i++] = 0x01; /* Length */ output[i++] = 0x00; /* Length */ output[i++] = 0x00; PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height); output[i++] = Width; output[i++] = Height; output[i++] = 0x01; memcpy(output+i,msg.Buffer+51,PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0)); i = i + PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0); if (msg.Length!=304) { output[i++] = SM30_UNICODETEXT; output[i++] = 0; output[i++] = 0; /* Length - later changed */ GSM_UnpackEightBitsToSeven(0, msg.Length-304, msg.Length-304, msg.Buffer+52+PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0),output2); DecodeDefault(output+i, output2, msg.Length - 304, true, NULL); output[i - 1] = UnicodeLength(output+i) * 2; i = i + output[i-1]; } GSM_MakeMultiPartSMS(Data->GetSMSMessage,output,i,UDH_NokiaProfileLong,SMS_Coding_8bit,1,0); for (i=0;i<3;i++) { Data->GetSMSMessage->SMS[i].Number[0]=0; Data->GetSMSMessage->SMS[i].Number[1]=0; } return ERR_NONE; default: smprintf(s, "Unknown SMS type: %i\n",msg.Buffer[8]); return ERR_UNKNOWNRESPONSE; } default: smprintf(s, "Unknown SMS type: %i\n",msg.Buffer[8]); } break; case 0x09: switch (msg.Buffer[4]) { case 0x02: smprintf(s, "Too high location ?\n"); return ERR_INVALIDLOCATION; case 0x07: smprintf(s, "Empty\n"); return ERR_EMPTY; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } case 0x6F: smprintf(s, "SMS message info received\n"); if (msg.Length == 43) { Data->GetSMSMessage->SMS[0].Name[0] = 0; Data->GetSMSMessage->SMS[0].Name[1] = 0; } else { CopyUnicodeString(Data->GetSMSMessage->SMS[0].Name,msg.Buffer+43); } smprintf(s, "Name: \"%s\"\n",DecodeUnicodeString(Data->GetSMSMessage->SMS[0].Name)); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N7110_PrivGetSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms) { GSM_Error error; unsigned char folderid; int location; int i; unsigned char req[] = {N6110_FRAME_HEADER, 0x07, 0x08, /* folder ID */ 0x00, 0x05, /* location */ 0x01, 0x65, 0x01}; unsigned char NameReq[] = {N6110_FRAME_HEADER, 0x6E, 0x08, /* folder ID */ 0x00, 0x05}; /* location */ N7110_GetSMSLocation(s, &sms->SMS[0], &folderid, &location); req[4]=folderid; req[5]=location / 256; req[6]=location; s->Phone.Data.GetSMSMessage=sms; smprintf(s, "Getting sms\n"); error=GSM_WaitFor (s, req, 10, 0x14, 4, ID_GetSMSMessage); if (error==ERR_NONE) { NameReq[4] = folderid; NameReq[5] = location / 256; NameReq[6] = location; smprintf(s, "Getting sms info\n"); error=GSM_WaitFor (s, NameReq, 7, 0x14, 4, ID_GetSMSMessage); if (error != ERR_NONE) return error; for (i=0;i<sms->Number;i++) { N7110_SetSMSLocation(s, &sms->SMS[i], folderid, location); sms->SMS[i].Folder = folderid/0x08; sms->SMS[i].InboxFolder = true; if (folderid/0x08 != 0x01) sms->SMS[i].InboxFolder = false; CopyUnicodeString(sms->SMS[i].Name,sms->SMS[0].Name); sms->SMS[i].Memory = MEM_ME; if (folderid/0x08 == 0x01 || folderid/0x08 == 0x02) { sms->SMS[i].Memory = MEM_MT; if (folderid/0x08 == 0x01) { /* Inbox */ if (sms->SMS[i].State == SMS_Sent) sms->SMS[i].Memory = MEM_ME; if (sms->SMS[i].State == SMS_UnSent) sms->SMS[i].Memory = MEM_ME; if (sms->SMS[i].State == SMS_Read) sms->SMS[i].Memory = MEM_SM; if (sms->SMS[i].State == SMS_UnRead) sms->SMS[i].Memory = MEM_SM; } if (folderid/0x08 == 0x02) { /* Outbox */ if (sms->SMS[i].State == SMS_Sent) sms->SMS[i].Memory = MEM_SM; if (sms->SMS[i].State == SMS_UnSent) sms->SMS[i].Memory = MEM_SM; if (sms->SMS[i].State == SMS_Read) sms->SMS[i].Memory = MEM_ME; if (sms->SMS[i].State == SMS_UnRead) sms->SMS[i].Memory = MEM_ME; } } } } return error; } static GSM_Error N7110_GetSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms) { GSM_Error error; unsigned char folderid; int location; GSM_Phone_N7110Data *Priv = &s->Phone.Data.Priv.N7110; int i; bool found = false; N7110_GetSMSLocation(s, &sms->SMS[0], &folderid, &location); error=N7110_GetSMSFolderStatus(s, folderid); if (error!=ERR_NONE) return error; for (i=0;i<Priv->LastSMSFolder.Number;i++) { if (Priv->LastSMSFolder.Location[i]==location) { found = true; break; } } if (!found) return ERR_EMPTY; return N7110_PrivGetSMSMessage(s,sms); } static GSM_Error N7110_GetNextSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start) { GSM_Phone_N7110Data *Priv = &s->Phone.Data.Priv.N7110; unsigned char folderid; int location; GSM_Error error; int i; bool findnextfolder = false; if (start) { folderid=0x00; findnextfolder=true; error=N7110_GetSMSFolders(s,&Priv->LastSMSFolders); if (error!=ERR_NONE) return error; } else { N7110_GetSMSLocation(s, &sms->SMS[0], &folderid, &location); for (i=0;i<Priv->LastSMSFolder.Number;i++) { if (Priv->LastSMSFolder.Location[i]==location) break; } /* Is this last location in this folder ? */ if (i==Priv->LastSMSFolder.Number-1) { findnextfolder=true; } else { location=Priv->LastSMSFolder.Location[i+1]; } } if (findnextfolder) { Priv->LastSMSFolder.Number=0; while (Priv->LastSMSFolder.Number==0) { folderid=folderid+0x08; /* Too high folder number */ if ((folderid/0x08)>Priv->LastSMSFolders.Number) return ERR_EMPTY; /* Get next folder status */ error=N7110_GetSMSFolderStatus(s, folderid); if (error!=ERR_NONE) return error; /* First location from this folder */ location=Priv->LastSMSFolder.Location[0]; } } N7110_SetSMSLocation(s, &sms->SMS[0], folderid, location); return N7110_PrivGetSMSMessage(s, sms); } static int N7110_ReturnBinaryRingtoneLocation(char *model) { if (strcmp(model,"NSE-5") == 0) return 0x72; /* first 0x72 - 7110 */ if (strcmp(model,"NPE-3") == 0) return 0x89; /* first 0x89 - 6210 */ if (strcmp(model,"NHM-3") == 0) return 0x89; /* quess for 6250 */ return 0; } static GSM_Error N7110_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) { int tmp,i; GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Ringtone received\n"); switch (msg.Buffer[3]) { case 0x23: tmp=0;i=4; while (msg.Buffer[i]!=0 || msg.Buffer[i+1]!=0) { tmp++; i=i+2; if (i>msg.Length) return ERR_EMPTY; } memcpy(Data->Ringtone->Name,msg.Buffer+6,tmp*2); smprintf(s, "Name \"%s\"\n",DecodeUnicodeString(Data->Ringtone->Name)); /* Looking for end */ i=37; while (true) { if (msg.Buffer[i]==0x07 && msg.Buffer[i+1]==0x0b) { i=i+2; break; } if (msg.Buffer[i]==0x0e && msg.Buffer[i+1]==0x0b) { i=i+2; break; } i++; if (i==msg.Length) return ERR_EMPTY; } /* Copying frame */ memcpy(Data->Ringtone->NokiaBinary.Frame,msg.Buffer+37,i-37); Data->Ringtone->NokiaBinary.Length=i-37; return ERR_NONE; case 0x24: smprintf(s, "Invalid location. Too high ?\n"); return ERR_INVALIDLOCATION; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N7110_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) { unsigned char req[] = {N7110_FRAME_HEADER, 0x22, 0x00, 0x00}; if (PhoneRingtone) return ERR_NOTSUPPORTED; if (Ringtone->Format == 0x00) Ringtone->Format = RING_NOKIABINARY; switch (Ringtone->Format) { case RING_NOTETONE: /* In the future get binary and convert */ return ERR_NOTSUPPORTED; case RING_NOKIABINARY: req[5]=N7110_ReturnBinaryRingtoneLocation(s->Phone.Data.Model)+Ringtone->Location; s->Phone.Data.Ringtone=Ringtone; smprintf(s, "Getting binary ringtone\n"); return GSM_WaitFor (s, req, 6, 0x1f, 4, ID_GetRingtone); case RING_MIDI: case RING_MMF: return ERR_NOTSUPPORTED; } return ERR_NOTSUPPORTED; } static GSM_Error N7110_ReplyGetPictureImageInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; GSM_Phone_N7110Data *Priv = &s->Phone.Data.Priv.N7110; smprintf(s, "Received info for Picture Images\n"); smprintf(s, "Number : %i\n",msg.Buffer[4]*256+msg.Buffer[5]); smprintf(s, "Locations :"); Priv->LastPictureImageFolder.Number=msg.Buffer[4]*256+msg.Buffer[5]; for (i=0;i<Priv->LastPictureImageFolder.Number;i++) { Priv->LastPictureImageFolder.Location[i]=msg.Buffer[6+i*2]*256+msg.Buffer[7+i*2]; smprintf(s, " %i",Priv->LastPictureImageFolder.Location[i]); } smprintf(s, "\n"); return ERR_NONE; } static GSM_Error N7110_GetPictureImageLocation(GSM_StateMachine *s, GSM_Bitmap *Bitmap, unsigned char *folder, int *location) { GSM_Phone_N7110Data *Priv = &s->Phone.Data.Priv.N7110; GSM_SMSFolders folders; GSM_Error error; int i, j = 0, count = 0; unsigned char req[] = {N6110_FRAME_HEADER, 0x96, 0x00, /* Folder ID */ 0x0f, 0x07}; error=N7110_GetSMSFolders (s, &folders); if (error!=ERR_NONE) return error; for (i=0;i<folders.Number;i++) { req[4] = (i+1) * 0x08; /* SMS folder ID */ error = GSM_WaitFor (s, req, 7, 0x14, 4, ID_GetBitmap); if (error!=ERR_NONE) return error; for (j=0;j<Priv->LastPictureImageFolder.Number;j++) { count++; if (count==Bitmap->Location) break; } if (count==Bitmap->Location) break; } if (count!=Bitmap->Location) return ERR_INVALIDLOCATION; *folder = (i+1) * 0x08; /* SMS Folder ID */ *location = Priv->LastPictureImageFolder.Location[j]; return ERR_NONE; } static GSM_Error N7110_GetPictureImage(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { unsigned char folder; int location; GSM_Error error; unsigned char req[] = {N6110_FRAME_HEADER, 0x07, 0x00, /* Folder ID */ 0x00, 0x00, /* Location */ 0x00, 0x64}; error = N7110_GetPictureImageLocation(s, Bitmap, &folder, &location); switch (error) { case ERR_NONE: req[4] = folder; req[5] = location / 256; req[6] = location % 256; return GSM_WaitFor (s, req, 9, 0x14, 4, ID_GetBitmap); default: return error; } } static GSM_Error N7110_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { GSM_MemoryEntry pbk; GSM_Error error; unsigned char OpReq[] = {N6110_FRAME_HEADER, 0x70}; s->Phone.Data.Bitmap=Bitmap; switch (Bitmap->Type) { case GSM_StartupLogo: smprintf(s, "Getting startup logo\n"); return N71_92_GetPhoneSetting(s, ID_GetBitmap, 0x15); case GSM_WelcomeNote_Text: smprintf(s, "Getting welcome note\n"); return N71_92_GetPhoneSetting(s, ID_GetBitmap, 0x02); case GSM_DealerNote_Text: smprintf(s, "Getting dealer note\n"); return N71_92_GetPhoneSetting(s, ID_GetBitmap, 0x17); case GSM_CallerGroupLogo: pbk.MemoryType = MEM7110_CG; pbk.Location = Bitmap->Location; smprintf(s, "Getting caller group logo\n"); error=N7110_GetMemory(s,&pbk); if (error==ERR_NONE) NOKIA_GetDefaultCallerGroupName(s,Bitmap); return error; case GSM_OperatorLogo: smprintf(s, "Getting operator logo\n"); /* This is like DCT3_GetNetworkInfo */ return GSM_WaitFor (s, OpReq, 4, 0x0a, 4, ID_GetBitmap); case GSM_PictureImage: /* 7110 doesn't support it */ if (strcmp(s->Phone.Data.Model,"NSE-5") == 0) return ERR_NOTSUPPORTED; return N7110_GetPictureImage(s, Bitmap); default: break; } return ERR_NOTSUPPORTED; } static GSM_Error N7110_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) { GSM_Ringtone dest; GSM_Error error; GSM_NetworkInfo NetInfo; int size=200; unsigned char req[1000] = {0x7C, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*Length*/ unsigned char req2[4000] = {N7110_FRAME_HEADER, 0x1F, 0x00, 0x87, /* Location */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; switch (Ringtone->Format) { case RING_NOTETONE: if (Ringtone->Location==255) { /* 7110 doesn't support it */ if (strcmp(s->Phone.Data.Model,"NSE-5") == 0) return ERR_NOTSUPPORTED; *maxlength=GSM_EncodeNokiaRTTLRingtone(*Ringtone, req+11, &size); req[10] = size; error = s->Protocol.Functions->WriteMessage(s, req, size+11, 0x00); if (error!=ERR_NONE) return error; my_sleep(1000); /* We have to make something (not important, what) now */ /* no answer from phone*/ return DCT3_GetNetworkInfo(s,&NetInfo); } GSM_RingtoneConvert(&dest, Ringtone, RING_NOKIABINARY); break; case RING_NOKIABINARY: memcpy(&dest,Ringtone,sizeof(GSM_Ringtone)); break; default: return ERR_NOTSUPPORTED; } req2[5]=N7110_ReturnBinaryRingtoneLocation(s->Phone.Data.Model)+Ringtone->Location; CopyUnicodeString(req2+6,Ringtone->Name); memcpy(req2+37,dest.NokiaBinary.Frame,dest.NokiaBinary.Length); error = s->Protocol.Functions->WriteMessage(s, req2, 37+dest.NokiaBinary.Length, 0x1F); if (error!=ERR_NONE) return error; my_sleep(1000); /* We have to make something (not important, what) now */ /* no answer from phone*/ return DCT3_GetNetworkInfo(s,&NetInfo); } static GSM_Error N7110_ReplySaveSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x05: smprintf(s, "SMS message saving status\n"); smprintf(s, "Saved in folder %i at location %i\n",msg.Buffer[4], msg.Buffer[5]*256+msg.Buffer[6]); if (msg.Buffer[4] == 0xf8) { N7110_SetSMSLocation(s, Data->SaveSMSMessage,0x08,msg.Buffer[5]*256+msg.Buffer[6]); Data->SaveSMSMessage->Folder = 0x01; } else { N7110_SetSMSLocation(s, Data->SaveSMSMessage,msg.Buffer[4],msg.Buffer[5]*256+msg.Buffer[6]); Data->SaveSMSMessage->Folder = msg.Buffer[4] / 0x08; } return ERR_NONE; case 0x06: smprintf(s, "SMS message saving status\n"); switch (msg.Buffer[4]) { case 0x03: smprintf(s, "Too high location ?\n"); return ERR_INVALIDLOCATION; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } break; case 0x84: smprintf(s, "Name for SMS changed OK to \"%s\"\n",DecodeUnicodeString(msg.Buffer+7)); smprintf(s, "Saved in folder %i at location %i\n",msg.Buffer[4], msg.Buffer[5]*256+msg.Buffer[6]); if (msg.Buffer[4] == 0xf8) { N7110_SetSMSLocation(s, Data->SaveSMSMessage,0x08,msg.Buffer[5]*256+msg.Buffer[6]); Data->SaveSMSMessage->Folder = 0x01; } else { N7110_SetSMSLocation(s, Data->SaveSMSMessage,msg.Buffer[4],msg.Buffer[5]*256+msg.Buffer[6]); Data->SaveSMSMessage->Folder = msg.Buffer[4] / 0x08; } return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N7110_PrivSetSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms) { int length, location; unsigned char folderid, folder; GSM_Error error; unsigned char req[256] = {N6110_FRAME_HEADER, 0x04, 0x03, /* sms status */ 0x10, /* folder */ 0x00,0x00, /* location */ 0x00}; unsigned char NameReq[200] = {N6110_FRAME_HEADER, 0x83}; switch (sms->State) { case SMS_Read : req[4] = 0x01; break; case SMS_UnRead : req[4] = 0x03; break; case SMS_Sent : req[4] = 0x05; break; case SMS_UnSent : req[4] = 0x07; break; } N7110_GetSMSLocation(s, sms, &folderid, &location); req[5] = folderid; req[6] = location / 256; req[7] = location; /* Outbox */ if (folderid == 0x10 && (sms->State == SMS_Sent || sms->State == SMS_UnSent)) { /* We will use SIM Outbox */ sms->PDU = SMS_Submit; } /* Inbox */ if (folderid == 0x08 && sms->State == SMS_UnRead) { /* We will use SIM Inbox */ req[5] = 0xf8; } switch (sms->PDU) { case SMS_Deliver: error = PHONE_EncodeSMSFrame(s,sms,req+9,PHONE_SMSDeliver,&length,true); break; case SMS_Submit: smprintf(s, "Saving SMS template\n"); error = PHONE_EncodeSMSFrame(s,sms,req+9,N7110_SMSTemplate,&length,true); req[8] = 0x02; /* SMS Template info */ break; default: return ERR_UNKNOWN; } if (error != ERR_NONE) return error; s->Phone.Data.SaveSMSMessage=sms; smprintf(s, "Saving sms\n"); error=GSM_WaitFor (s, req, 9+length, 0x14, 4, ID_SaveSMSMessage); if (error == ERR_NONE && UnicodeLength(sms->Name)!=0) { folder = sms->Folder; sms->Folder = 0; N7110_GetSMSLocation(s, sms, &folderid, &location); length = 4; NameReq[length++] = folderid; NameReq[length++] = location / 256; NameReq[length++] = location; CopyUnicodeString(NameReq+length, sms->Name); length = length+UnicodeLength(sms->Name)*2; NameReq[length++] = 0; NameReq[length++] = 0; error=GSM_WaitFor (s, NameReq, length, 0x14, 4, ID_SaveSMSMessage); sms->Folder = folder; } return error; } static GSM_Error N7110_SetSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { int location; unsigned char folderid; N7110_GetSMSLocation(s, sms, &folderid, &location); if (location == 0) return ERR_INVALIDLOCATION; return N7110_PrivSetSMSMessage(s, sms); } static GSM_Error N7110_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { int location; unsigned char folderid; N7110_GetSMSLocation(s, sms, &folderid, &location); location = 0; N7110_SetSMSLocation(s, sms, folderid, location); return N7110_PrivSetSMSMessage(s, sms); } static GSM_Error N7110_ReplyClearOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Clearing operator logo.....\n"); return ERR_NONE; } static GSM_Error N7110_ReplySetOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Setting operator logo.....\n"); return ERR_NONE; } static GSM_Error N7110_SetCallerLogo(GSM_StateMachine *s, GSM_Bitmap *bitmap) { int block=0, i, Width, Height; unsigned int count = 18; char string[500]; unsigned char req[500] = {N6110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x10, /* memory type */ 0x00, 0x00, /* location */ 0x00, 0x00, 0x00}; req[13] = bitmap->Location; /* Enabling/disabling logo */ if (bitmap->DefaultBitmap) { string[0] = 0; //disabling } else { string[0] = bitmap->BitmapEnabled?1:0; } string[1] = 0; count += N71_65_PackPBKBlock(s, N7110_PBK_LOGOON, 2, block++, string, req + count); /* Ringtone */ if (!bitmap->DefaultRingtone) { string[0] = bitmap->RingtoneID; string[1] = 0; count += N71_65_PackPBKBlock(s, N7110_PBK_RINGTONE_ID, 2, block++, string, req + count); } /* Number of group */ string[0] = bitmap->Location; string[1] = 0; count += N71_65_PackPBKBlock(s, N7110_PBK_GROUP, 2, block++, string, req + count); /* Name */ if (!bitmap->DefaultName) { i = UnicodeLength(bitmap->Text) * 2; string[0] = i + 2; memcpy(string + 1, bitmap->Text, i); string[i + 1] = 0; count += N71_65_PackPBKBlock(s, N7110_PBK_NAME, i + 2, block++, string, req + count); } /* Logo */ if (bitmap->DefaultBitmap) { bitmap->BitmapWidth = 72; bitmap->BitmapHeight = 14; GSM_ClearBitmap(bitmap); } PHONE_GetBitmapWidthHeight(GSM_NokiaCallerLogo, &Width, &Height); string[0] = Width; string[1] = Height; string[2] = 0; string[3] = 0; string[4] = PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0); PHONE_EncodeBitmap(GSM_NokiaCallerLogo, string + 5, bitmap); count += N71_65_PackPBKBlock(s, N7110_PBK_GROUPLOGO, PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 5, block++, string, req + count); req[17] = block; return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetBitmap); } static GSM_Error N7110_ReplySetPicture(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Picture Image written OK, folder %i, location %i\n",msg.Buffer[4],msg.Buffer[5]*256+msg.Buffer[6]); return ERR_NONE; } static GSM_Error N7110_SetPictureImage(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { unsigned char folder; GSM_Error error; int location, i, count, Width, Height; GSM_Phone_Bitmap_Types Type = GSM_NokiaPictureImage; unsigned char req[500] = {N6110_FRAME_HEADER, 0x50, 0x07, 0x00, /* location */ 0x00, 0x00, /* index */ 0x07}; error=N7110_GetPictureImageLocation(s, Bitmap, &folder, &location); switch (error) { case ERR_NONE: req[5] = folder; req[6] = location / 256; req[7] = location % 256; break; case ERR_INVALIDLOCATION: req[5] = 0x21; /* Save in Templates folder */ req[6] = 0; req[7] = 0; break; default: return error; } /* Cleaning */ for (i=0;i<36;i++) req[i+9]=0; count=8; if (UnicodeLength(Bitmap->Text)==0) { count+=2 ;req[count]=0x0c; count+=2 ;req[count]=0x0d; count+=2 ;req[count]=0x0e; count+=2 ;req[count]=0x0f; count+=2 ;req[count]=0x10; count+=2 ;req[count]=0x11; count+=23;req[count]=0x02; count++ ; } else { count+=2 ;req[count]=0x54; count++ ;req[count]=0xd4; count++ ;req[count]=0x0d; count+=2 ;req[count]=0x0e; count+=2 ;req[count]=0x0f; count+=2 ;req[count]=0x10; count+=2 ;req[count]=0x11; count+=21;req[count]=0x01; count+=3 ; } req[count] = 0x01; count+=2; req[count++] = 0x01; PHONE_GetBitmapWidthHeight(Type, &Width, &Height); req[count++] = Width; req[count++] = Height; req[count++] = PHONE_GetBitmapSize(Type,0,0) / 256; req[count++] = PHONE_GetBitmapSize(Type,0,0) % 256; PHONE_EncodeBitmap(Type, req + count, Bitmap); count += PHONE_GetBitmapSize(Type,0,0); if (UnicodeLength(Bitmap->Text)!=0) { req[count] = UnicodeLength(Bitmap->Text); GSM_PackSevenBitsToEight(0, Bitmap->Text, req+count+1,strlen(Bitmap->Text)); count = count + req[count]; } else { req[count++]=0x00; } req[count++]=0x00; smprintf(s, "Setting Picture Image\n"); return GSM_WaitFor (s, req, count, 0x14, 4, ID_SetBitmap); } static GSM_Error N7110_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { GSM_Error error; GSM_Phone_Bitmap_Types Type; int Width, Height, i; unsigned char reqStartup[1000] = {N7110_FRAME_HEADER, 0xec, 0x15, /* Startup Logo setting */ 0x00, 0x00, 0x00, 0x04, 0xc0, 0x02, 0x00, 0x00, /* Bitmap height */ 0xc0, 0x03, 0x00, 0x00, /* Bitmap width */ 0xc0, 0x04, 0x03, 0x00}; unsigned char reqOp[1000] = {N7110_FRAME_HEADER, 0xa3, 0x01, 0x00, /* logo disabled */ 0x00, 0xf0, 0x00, /* network code (000 00) */ 0x00 ,0x04, 0x08, /* length of rest */ 0x00, 0x00, /* Bitmap width / height */ 0x00, 0x00, /* Bitmap size */ 0x00, 0x00}; unsigned char reqClrOp[] = {0x00, 0x01, 0x00, 0xaf, 0x00}; unsigned char reqStartupText[500] = {N7110_FRAME_HEADER, 0xec, 0x02}; /* Startup Text setting */ switch (Bitmap->Type) { case GSM_StartupLogo: if (Bitmap->Location!=1) return ERR_NOTSUPPORTED; Type=GSM_Nokia6210StartupLogo; if (strcmp(s->Phone.Data.Model,"NSE-5") == 0) Type=GSM_Nokia7110StartupLogo; PHONE_GetBitmapWidthHeight(Type, &Width, &Height); reqStartup[12] = Height; reqStartup[16] = Width; PHONE_EncodeBitmap(Type, reqStartup + 21, Bitmap); smprintf(s, "Setting startup logo\n"); return GSM_WaitFor (s, reqStartup, 21+PHONE_GetBitmapSize(Type,0,0), 0x7A, 4, ID_SetBitmap); case GSM_WelcomeNote_Text: CopyUnicodeString(reqStartupText + 5, Bitmap->Text); i = 6 + UnicodeLength(Bitmap->Text) * 2; reqStartupText[i++] = 0; reqStartupText[i++] = 0; return GSM_WaitFor (s, reqStartupText, i, 0x7A, 4, ID_SetBitmap); case GSM_DealerNote_Text: reqStartupText[4] = 0x17; CopyUnicodeString(reqStartupText + 5, Bitmap->Text); i = 6 + UnicodeLength(Bitmap->Text) * 2; reqStartupText[i++] = 0; reqStartupText[i++] = 0; return GSM_WaitFor (s, reqStartupText, i, 0x7A, 4, ID_SetBitmap); case GSM_OperatorLogo: /* We want to set operator logo, not clear */ if (strcmp(Bitmap->NetworkCode,"000 00")) { reqOp[5] = 0x01; /* Logo enabled */ NOKIA_EncodeNetworkCode(reqOp+6, Bitmap->NetworkCode); Type = GSM_Nokia7110OperatorLogo; reqOp[11] = 8 + PHONE_GetBitmapSize(Type,0,0); PHONE_GetBitmapWidthHeight(Type, &Width, &Height); reqOp[12]=Width; reqOp[13]=Height; reqOp[15]=PHONE_GetBitmapSize(Type,0,0); PHONE_EncodeBitmap(Type, reqOp + 18, Bitmap); smprintf(s, "Setting operator logo\n"); return GSM_WaitFor (s, reqOp, 18+PHONE_GetBitmapSize(Type,0,0), 0x0A, 4, ID_SetBitmap); } else { smprintf(s, "Clearing operator logo\n"); for (i=0;i<5;i++) { reqClrOp[4]=i; error=GSM_WaitFor (s, reqClrOp, 5, 0x0A, 4, ID_SetBitmap); if (error!=ERR_NONE) return error; } return GSM_WaitFor (s, reqOp, 18, 0x0A, 4, ID_SetBitmap); } case GSM_CallerGroupLogo: return N7110_SetCallerLogo(s,Bitmap); case GSM_PictureImage: return N7110_SetPictureImage(s,Bitmap); default: break; } return ERR_NOTSUPPORTED; } static GSM_Error N7110_ReplyDeleteMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Phonebook entry deleted\n"); return ERR_NONE; } static GSM_Error N7110_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { unsigned char req[] = {N7110_FRAME_HEADER, 0x0f, 0x00, 0x01, 0x04, 0x00, 0x00, 0x0c, 0x01, 0xff, 0x00, 0x01, /* location */ 0x05, /* memory type */ 0x00, 0x00, 0x00}; req[12] = entry->Location / 256; req[13] = entry->Location % 256; req[14] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES); if (req[14]==0xff) return ERR_NOTSUPPORTED; smprintf(s, "Deleting phonebook entry\n"); return GSM_WaitFor (s, req, 18, 0x03, 4, ID_SetMemory); } static GSM_Error N7110_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { int count = 18, blocks; unsigned char req[500] = {N7110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, /* memory type */ 0x00, 0x00, /* location */ 0x00, 0x00, 0x00}; if (entry->Location == 0) return ERR_NOTSUPPORTED; req[11] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES); if (req[11]==0xff) return ERR_NOTSUPPORTED; req[12] = entry->Location >> 8; req[13] = entry->Location & 0xff; count = count + N71_65_EncodePhonebookFrame(s, req+18, *entry, &blocks, false, IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_VOICETAGS)); req[17] = blocks; smprintf(s, "Writing phonebook entry\n"); return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetMemory); } static GSM_Error N7110_DeleteSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { unsigned char folderid; int location; unsigned char req[] = {N7110_FRAME_HEADER, 0x0a, 0x00, /* folder */ 0x00, 0x00, /* location */ 0x01}; N7110_GetSMSLocation(s, sms, &folderid, &location); req[4] = folderid; req[5] = location / 256; req[6] = location; smprintf(s, "Deleting sms\n"); return GSM_WaitFor (s, req, 8, 0x14, 4, ID_DeleteSMSMessage); } static GSM_Error N7110_ReplyGetSMSStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "SMS status received\n"); switch (msg.Buffer[3]) { case 0x37: smprintf(s, "SIM size : %i\n",msg.Buffer[8]*256+msg.Buffer[9]); smprintf(s, "Used in phone memory : %i\n",msg.Buffer[10]*256+msg.Buffer[11]); smprintf(s, "Unread in phone memory : %i\n",msg.Buffer[12]*256+msg.Buffer[13]); smprintf(s, "Used in SIM : %i\n",msg.Buffer[14]*256+msg.Buffer[15]); smprintf(s, "Unread in SIM : %i\n",msg.Buffer[16]*256+msg.Buffer[17]); Data->SMSStatus->SIMSize = msg.Buffer[8]*256+msg.Buffer[9]; Data->SMSStatus->PhoneUsed = msg.Buffer[10]*256+msg.Buffer[11]; Data->SMSStatus->PhoneUnRead = msg.Buffer[12]*256+msg.Buffer[13]; Data->SMSStatus->PhoneSize = 150; Data->SMSStatus->SIMUsed = msg.Buffer[14]*256+msg.Buffer[15]; Data->SMSStatus->SIMUnRead = msg.Buffer[16]*256+msg.Buffer[17]; return ERR_NONE; case 0x38: smprintf(s, "Error. No PIN ?\n"); return ERR_SECURITYERROR; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N7110_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status) { GSM_Error error; GSM_Phone_N7110Data *Priv = &s->Phone.Data.Priv.N7110; error = DCT3_GetSMSStatus(s,status); if (error != ERR_NONE) return error; /* 6210 family doesn't show in frame with SMS status info * about Templates. We get separately info about this SMS folder. */ error = N7110_GetSMSFolderStatus(s, 0x20); if (error != ERR_NONE) return error; status->TemplatesUsed = Priv->LastSMSFolder.Number; return ERR_NONE; } static GSM_Error N7110_ReplyGetProfileFeature(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x02: smprintf(s, "Profile feature %02x with value %02x\n",msg.Buffer[6],msg.Buffer[10]); switch (msg.Buffer[6]) { case 0x03: smprintf(s, "Ringtone ID\n"); Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_RingtoneID; Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = msg.Buffer[10]; Data->Profile->FeaturesNumber++; break; case 0x08: /* Caller groups */ NOKIA_FindFeatureValue(s, Profile71_65,msg.Buffer[6],msg.Buffer[10],Data,true); break; case 0x09: /* Autoanswer */ if (Data->Profile->CarKitProfile || Data->Profile->HeadSetProfile) { NOKIA_FindFeatureValue(s, Profile71_65,msg.Buffer[6],msg.Buffer[10],Data,false); } break; case 0xff : CopyUnicodeString(Data->Profile->Name, msg.Buffer+10); smprintf(s, "profile Name: \"%s\"\n", DecodeUnicodeString(Data->Profile->Name)); Data->Profile->DefaultName = false; break; default: NOKIA_FindFeatureValue(s, Profile71_65,msg.Buffer[6],msg.Buffer[10],Data,false); } return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N7110_GetProfile(GSM_StateMachine *s, GSM_Profile *Profile) { GSM_Error error; int i; unsigned char Features[12] = {0x00,0x02,0x03,0x04,0x05,0x06, 0x07,0x08,0x09,0xff, 0x0a,0x22}; unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x01, 0x01, 0x01, 0x00, /* Profile Location */ 0xff}; /* Feature number */ if (Profile->Location > 7) return ERR_INVALIDLOCATION; Profile->CarKitProfile = false; Profile->HeadSetProfile = false; if (Profile->Location == 6) Profile->CarKitProfile = true; if (Profile->Location == 7) Profile->HeadSetProfile = true; Profile->FeaturesNumber = 0; s->Phone.Data.Profile=Profile; for (i = 0; i < 10; i++) { req[7] = Profile->Location; req[8] = Features[i]; smprintf(s, "Getting profile feature\n"); error = GSM_WaitFor (s, req, 9, 0x39, 4, ID_GetProfile); if (error!=ERR_NONE) return error; } NOKIA_GetDefaultProfileName(s, Profile); Profile->Active = false; return error; } static GSM_Error N7110_ReplySetProfileFeature(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Profile feature set\n"); return ERR_NONE; } static GSM_Error N7110_SetProfile(GSM_StateMachine *s, GSM_Profile *Profile) { int i; bool found; GSM_Error error; unsigned char ID,Value; unsigned char req[] = {N6110_FRAME_HEADER, 0x03, 0x01, 0x01, 0x03, 0x02, /* feature number */ 0x01, /* Profile Location */ 0x01, 0xff}; /* Value */ for (i=0;i<Profile->FeaturesNumber;i++) { found = false; switch (Profile->FeatureID[i]) { case Profile_RingtoneID: ID = 0x03; Value = Profile->FeatureValue[i]; found = true; break; default: found=NOKIA_FindPhoneFeatureValue( s, Profile71_65, Profile->FeatureID[i],Profile->FeatureValue[i], &ID,&Value); } if (found) { req[7] = ID; req[8] = Profile->Location; req[10] = Value; smprintf(s, "Setting profile feature\n"); error = GSM_WaitFor (s, req, 11, 0x39, 4, ID_SetProfile); if (error!=ERR_NONE) return error; } } return ERR_NONE; } static GSM_Error N7110_GetSpeedDial(GSM_StateMachine *s, GSM_SpeedDial *SpeedDial) { GSM_MemoryEntry pbk; GSM_Error error; pbk.MemoryType = MEM7110_SP; pbk.Location = SpeedDial->Location; SpeedDial->MemoryLocation = 0; s->Phone.Data.SpeedDial = SpeedDial; smprintf(s, "Getting speed dial\n"); error=N7110_GetMemory(s,&pbk); switch (error) { case ERR_NOTSUPPORTED: smprintf(s, "No speed dials set in phone\n"); return ERR_EMPTY; case ERR_NONE: if (SpeedDial->MemoryLocation == 0) { smprintf(s, "Speed dial not assigned or error in firmware\n"); return ERR_EMPTY; } return ERR_NONE; default: return error; } } static GSM_Error N7110_ReplyIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_SMSMessage sms; GSM_Phone_Data *Data = &s->Phone.Data; #ifdef DEBUG smprintf(s, "SMS message received\n"); sms.State = SMS_UnRead; sms.InboxFolder = true; DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+8); #endif if (Data->EnableIncomingSMS && s->User.IncomingSMS!=NULL) { sms.State = SMS_UnRead; sms.InboxFolder = true; DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+8); s->User.IncomingSMS(s->CurrentConfig->Device,sms); } return ERR_NONE; } static GSM_Error N7110_Initialise (GSM_StateMachine *s) { #ifdef DEBUG DCT3_SetIncomingCB(s,true); #endif #ifdef GSM_ENABLE_N71_92INCOMINGINFO /* Enables various things like incoming SMS, call info, etc. */ return N71_65_EnableFunctions (s, "\x01\x02\x06\x0A\x14\x17", 6); #endif return ERR_NONE; } static GSM_Error N7110_ReplyGetCalendarInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { /* Old method 1 for accessing calendar */ return N71_65_ReplyGetCalendarInfo1(msg, s, &s->Phone.Data.Priv.N7110.LastCalendar); } #ifdef DEBUG static GSM_Error N7110_ReplyGetCalendarNotePos(GSM_Protocol_Message msg, GSM_StateMachine *s) { /* Old method 1 for accessing calendar */ return N71_65_ReplyGetCalendarNotePos1(msg, s, &s->Phone.Data.Priv.N7110.FirstCalendarPos); } #endif static GSM_Error N7110_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) { return N71_65_GetNextCalendar1(s,Note,start,&s->Phone.Data.Priv.N7110.LastCalendar,&s->Phone.Data.Priv.N7110.LastCalendarYear,&s->Phone.Data.Priv.N7110.LastCalendarPos); // return N71_65_GetNextCalendar2(s,Note,start,&s->Phone.Data.Priv.N7110.LastCalendarYear,&s->Phone.Data.Priv.N7110.LastCalendarPos); } static GSM_Error N7110_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status) { GSM_Error error; /* Method 1 */ error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N7110.LastCalendar); if (error!=ERR_NONE) return error; Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number; return ERR_NONE; /* Method 2 */ // return GE_NOTSUPPORTED; } static GSM_Error N7110_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { // return N71_65_AddCalendar1(s, Note, NULL); return N71_65_AddCalendar2(s,Note); } static GSM_Error N7110_ReplyGetNetworkInfoError(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Probably means no PIN\n"); return ERR_SECURITYERROR; } static GSM_Error N7110_SetIncomingCall(GSM_StateMachine *s, bool enable) { #ifndef GSM_ENABLE_N71_92INCOMINGINFO return ERR_SOURCENOTAVAILABLE; #endif return NOKIA_SetIncomingCall(s,enable); } static GSM_Error N7110_SetIncomingUSSD(GSM_StateMachine *s, bool enable) { #ifndef GSM_ENABLE_N71_92INCOMINGINFO return ERR_SOURCENOTAVAILABLE; #endif return NOKIA_SetIncomingUSSD(s,enable); } static GSM_Error N7110_SetIncomingSMS(GSM_StateMachine *s, bool enable) { #ifndef GSM_ENABLE_N71_92INCOMINGINFO return ERR_SOURCENOTAVAILABLE; #endif return NOKIA_SetIncomingSMS(s,enable); } GSM_Error N7110_AnswerCall(GSM_StateMachine *s, int ID, bool all) { if (!all) return DCT3DCT4_AnswerCall(s,ID); return DCT3_AnswerAllCalls(s); } GSM_Error N7110_SetCallDivert(GSM_StateMachine *s, GSM_MultiCallDivert *divert) { GSM_Error error; int i; /* No answer from phone side */ i = s->ReplyNum; s->ReplyNum = 1; error = DCT3DCT4_SetCallDivert(s,divert); s->ReplyNum = i; return error; } GSM_Error N7110_CancelAllDiverts(GSM_StateMachine *s) { GSM_Error error; int i; /* No answer from phone side */ i = s->ReplyNum; s->ReplyNum = 1; error = DCT3DCT4_CancelAllDiverts(s); s->ReplyNum = i; return error; } static GSM_Reply_Function N7110ReplyFunctions[] = { {N71_65_ReplyCallInfo, "\x01",0x03,0x02,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x03,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x04,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x05,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_AnswerCall }, {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_CancelCall }, {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0A,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0B,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_IncomingFrame }, {N71_65_ReplySendDTMF, "\x01",0x03,0x51,ID_SendDTMF }, {N71_65_ReplyCallInfo, "\x01",0x03,0x53,ID_IncomingFrame }, {N71_65_ReplySendDTMF, "\x01",0x03,0x59,ID_SendDTMF }, {N71_65_ReplySendDTMF, "\x01",0x03,0x5E,ID_SendDTMF }, {DCT3_ReplySendSMSMessage, "\x02",0x03,0x02,ID_IncomingFrame }, {DCT3_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame }, {N7110_ReplyIncomingSMS, "\x02",0x03,0x10,ID_IncomingFrame }, #ifdef GSM_ENABLE_CELLBROADCAST {DCT3_ReplySetIncomingCB, "\x02",0x03,0x21,ID_SetIncomingCB }, {DCT3_ReplySetIncomingCB, "\x02",0x03,0x22,ID_SetIncomingCB }, {DCT3_ReplyIncomingCB, "\x02",0x03,0x23,ID_IncomingFrame }, #endif {DCT3_ReplySetSMSC, "\x02",0x03,0x31,ID_SetSMSC }, {DCT3_ReplyGetSMSC, "\x02",0x03,0x34,ID_GetSMSC }, {DCT3_ReplyGetSMSC, "\x02",0x03,0x35,ID_GetSMSC }, #ifdef GSM_ENABLE_CELLBROADCAST {DCT3_ReplySetIncomingCB, "\x02",0x03,0xCA,ID_SetIncomingCB }, #endif {N7110_ReplyGetMemoryStatus, "\x03",0x03,0x04,ID_GetMemoryStatus }, {N7110_ReplyGetMemory, "\x03",0x03,0x08,ID_GetMemory }, {N7110_ReplyDeleteMemory, "\x03",0x03,0x10,ID_SetMemory }, {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetBitmap }, {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetMemory }, {N71_65_ReplyUSSDInfo, "\x06",0x03,0x03,ID_IncomingFrame }, {NoneReply, "\x06",0x03,0x06,ID_IncomingFrame }, {DCT3_ReplySIMLogin, "\x09",0x03,0x80,ID_IncomingFrame }, {DCT3_ReplySIMLogout, "\x09",0x03,0x81,ID_IncomingFrame }, {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_GetNetworkInfo }, {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_GetBitmap }, {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_IncomingFrame }, {N7110_ReplyGetNetworkInfoError, "\x0A",0x03,0x72,ID_GetNetworkInfo }, {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x73,ID_IncomingFrame }, {N71_92_ReplyGetSignalQuality, "\x0A",0x03,0x82,ID_GetSignalQuality }, {N7110_ReplySetOperatorLogo, "\x0A",0x03,0xA4,ID_SetBitmap }, {N7110_ReplyClearOperatorLogo, "\x0A",0x03,0xB0,ID_SetBitmap }, {NoneReply, "\x0A",0x03,0xB5,ID_IncomingFrame }, #ifdef DEBUG {N71_65_ReplyAddCalendar1, "\x13",0x03,0x02,ID_SetCalendarNote },/*method 1*/ {N71_65_ReplyAddCalendar1, "\x13",0x03,0x04,ID_SetCalendarNote },/*method 1*/ {N71_65_ReplyAddCalendar1, "\x13",0x03,0x06,ID_SetCalendarNote },/*method 1*/ {N71_65_ReplyAddCalendar1, "\x13",0x03,0x08,ID_SetCalendarNote },/*method 1*/ #endif {N71_65_ReplyDelCalendar, "\x13",0x03,0x0C,ID_DeleteCalendarNote }, {N71_65_ReplyGetNextCalendar1, "\x13",0x03,0x1A,ID_GetCalendarNote },/*method 1*/ #ifdef DEBUG {N7110_ReplyGetCalendarNotePos, "\x13",0x03,0x32,ID_GetCalendarNotePos },/*method 1*/ #endif {N7110_ReplyGetCalendarInfo, "\x13",0x03,0x3B,ID_GetCalendarNotesInfo},/*method 1*/ #ifdef DEBUG {N71_65_ReplyGetNextCalendar2, "\x13",0x03,0x3F,ID_GetCalendarNote },/*method 2*/ #endif {N71_65_ReplyAddCalendar2, "\x13",0x03,0x41,ID_SetCalendarNote },/*method 2*/ {N7110_ReplySaveSMSMessage, "\x14",0x03,0x05,ID_SaveSMSMessage }, {N7110_ReplySaveSMSMessage, "\x14",0x03,0x06,ID_SaveSMSMessage }, {N7110_ReplyGetSMSMessage, "\x14",0x03,0x08,ID_GetSMSMessage }, {N7110_ReplyGetSMSMessage, "\x14",0x03,0x08,ID_GetBitmap }, {N7110_ReplyGetSMSMessage, "\x14",0x03,0x09,ID_GetSMSMessage }, {DCT3_ReplyDeleteSMSMessage, "\x14",0x03,0x0B,ID_DeleteSMSMessage }, {DCT3_ReplyDeleteSMSMessage, "\x14",0x03,0x0C,ID_DeleteSMSMessage }, {N7110_ReplyGetSMSStatus, "\x14",0x03,0x37,ID_GetSMSStatus }, {N7110_ReplyGetSMSStatus, "\x14",0x03,0x38,ID_GetSMSStatus }, {N7110_ReplySetPicture, "\x14",0x03,0x51,ID_SetBitmap }, {N7110_ReplyGetSMSFolderStatus, "\x14",0x03,0x6C,ID_GetSMSFolderStatus }, {N7110_ReplyGetSMSMessage, "\x14",0x03,0x6F,ID_GetSMSMessage }, {N7110_ReplyGetSMSFolders, "\x14",0x03,0x7B,ID_GetSMSFolders }, {N7110_ReplyGetSMSFolders, "\x14",0x03,0x7C,ID_GetSMSFolders }, {N7110_ReplySaveSMSMessage, "\x14",0x03,0x84,ID_SaveSMSMessage }, {N7110_ReplyGetPictureImageInfo, "\x14",0x03,0x97,ID_GetBitmap }, {N7110_ReplyGetSMSFolders, "\x14",0x03,0xCA,ID_GetSMSFolders }, {N71_92_ReplyGetBatteryCharge, "\x17",0x03,0x03,ID_GetBatteryCharge }, {DCT3_ReplySetDateTime, "\x19",0x03,0x61,ID_SetDateTime }, {DCT3_ReplyGetDateTime, "\x19",0x03,0x63,ID_GetDateTime }, {DCT3_ReplySetAlarm, "\x19",0x03,0x6C,ID_SetAlarm }, {DCT3_ReplyGetAlarm, "\x19",0x03,0x6E,ID_GetAlarm }, {N7110_ReplyGetRingtone, "\x1f",0x03,0x23,ID_GetRingtone }, {N7110_ReplyGetRingtone, "\x1f",0x03,0x24,ID_GetRingtone }, {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x01,ID_EnableConnectFunc }, {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x02,ID_EnableConnectFunc }, {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x04,ID_DisableConnectFunc }, {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x05,ID_DisableConnectFunc }, {DCT3_ReplyGetWAPBookmark, "\x3f",0x03,0x07,ID_GetWAPBookmark }, {DCT3_ReplyGetWAPBookmark, "\x3f",0x03,0x08,ID_GetWAPBookmark }, {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0A,ID_SetWAPBookmark }, {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0B,ID_SetWAPBookmark }, {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0D,ID_DeleteWAPBookmark }, {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0E,ID_DeleteWAPBookmark }, {DCT3DCT4_ReplyGetActiveConnectSet,"\x3f",0x03,0x10,ID_GetConnectSet }, {DCT3DCT4_ReplySetActiveConnectSet,"\x3f",0x03,0x13,ID_SetConnectSet }, {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x16,ID_GetConnectSet }, {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x17,ID_GetConnectSet }, {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x19,ID_SetConnectSet }, {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x1A,ID_SetConnectSet }, {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x1C,ID_GetConnectSet }, {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x1D,ID_GetConnectSet }, {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x1F,ID_SetConnectSet }, {N7110_ReplyGetProfileFeature, "\x39",0x03,0x02,ID_GetProfile }, {N7110_ReplySetProfileFeature, "\x39",0x03,0x04,ID_SetProfile }, {DCT3_ReplyEnableSecurity, "\x40",0x02,0x64,ID_EnableSecurity }, {N61_71_ReplyResetPhoneSettings, "\x40",0x02,0x65,ID_ResetPhoneSettings }, {DCT3_ReplyGetIMEI, "\x40",0x02,0x66,ID_GetIMEI }, {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_DialVoice }, {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_CancelCall }, {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_AnswerCall }, {DCT3_ReplyNetmonitor, "\x40",0x02,0x7E,ID_Netmonitor }, {DCT3_ReplyPlayTone, "\x40",0x02,0x8F,ID_PlayTone }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetHardware }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetPPM }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCA,ID_GetProductCode }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetManufactureMonth }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetOriginalIMEI }, {NoneReply, "\x40",0x02,0xFF,ID_IncomingFrame }, {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x02,ID_GetBitmap }, {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x02,ID_SetBitmap }, {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x15,ID_GetBitmap }, {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x15,ID_SetBitmap }, {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x17,ID_GetBitmap }, {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x17,ID_SetBitmap }, {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetModel }, {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetFirmware }, {DCT3_ReplyPressKey, "\xD2",0x02,0x46,ID_PressKey }, {DCT3_ReplyPressKey, "\xD2",0x02,0x47,ID_PressKey }, {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions N7110Phone = { "6210|6250|7110|7190", N7110ReplyFunctions, N7110_Initialise, PHONE_Terminate, GSM_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ NOKIA_GetManufacturer, DCT3DCT4_GetModel, DCT3DCT4_GetFirmware, DCT3_GetIMEI, DCT3_GetOriginalIMEI, DCT3_GetManufactureMonth, DCT3_GetProductCode, DCT3_GetHardware, DCT3_GetPPM, NOTSUPPORTED, /* GetSIMIMSI */ N71_92_GetDateTime, N71_92_SetDateTime, N7110_GetAlarm, N7110_SetAlarm, NOTSUPPORTED, /* GetLocale */ NOTSUPPORTED, /* SetLocale */ DCT3_PressKey, DCT3_Reset, N61_71_ResetPhoneSettings, NOTSUPPORTED, /* EnterSecurityCode */ NOTSUPPORTED, /* GetSecurityStatus */ NOTSUPPORTED, /* GetDisplayStatus */ NOTIMPLEMENTED, /* SetAutoNetworkLogin */ N71_92_GetBatteryCharge, N71_92_GetSignalQuality, DCT3_GetNetworkInfo, NOTSUPPORTED, /* GetCategory */ NOTSUPPORTED, /* AddCategory */ NOTSUPPORTED, /* GetCategoryStatus */ N7110_GetMemoryStatus, N7110_GetMemory, NOTIMPLEMENTED, /* GetNextMemory */ N7110_SetMemory, NOTIMPLEMENTED, /* AddMemory */ N7110_DeleteMemory, NOTIMPLEMENTED, /* DeleteAllMemory */ N7110_GetSpeedDial, NOTIMPLEMENTED, /* SetSpeedDial */ DCT3_GetSMSC, DCT3_SetSMSC, N7110_GetSMSStatus, N7110_GetSMSMessage, N7110_GetNextSMSMessage, N7110_SetSMS, N7110_AddSMS, N7110_DeleteSMS, DCT3_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ NOTSUPPORTED, /* SetFastSMSSending */ N7110_SetIncomingSMS, DCT3_SetIncomingCB, N7110_GetSMSFolders, NOTIMPLEMENTED, /* AddSMSFolder */ NOTIMPLEMENTED, /* DeleteSMSFolder */ DCT3_DialVoice, N7110_AnswerCall, DCT3_CancelCall, NOTIMPLEMENTED, /* HoldCall */ NOTIMPLEMENTED, /* UnholdCall */ NOTIMPLEMENTED, /* ConferenceCall */ NOTIMPLEMENTED, /* SplitCall */ NOTIMPLEMENTED, /* TransferCall */ NOTIMPLEMENTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ N7110_SetCallDivert, N7110_CancelAllDiverts, N7110_SetIncomingCall, N7110_SetIncomingUSSD, DCT3DCT4_SendDTMF, N7110_GetRingtone, N7110_SetRingtone, NOTSUPPORTED, /* GetRingtonesInfo */ NOTSUPPORTED, /* DeleteUserRingtones */ DCT3_PlayTone, DCT3_GetWAPBookmark, DCT3_SetWAPBookmark, DCT3_DeleteWAPBookmark, DCT3_GetWAPSettings, DCT3_SetWAPSettings, NOTSUPPORTED, /* GetMMSSettings */ NOTSUPPORTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetSyncMLSettings */ NOTSUPPORTED, /* SetSyncMLSettings */ NOTSUPPORTED, /* GetChatSettings */ NOTSUPPORTED, /* SetChatSettings */ N7110_GetBitmap, N7110_SetBitmap, NOTSUPPORTED, /* GetToDoStatus */ NOTSUPPORTED, /* GetToDo */ NOTSUPPORTED, /* GetNextToDo */ NOTSUPPORTED, /* SetToDo */ NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ N7110_GetCalendarStatus, NOTIMPLEMENTED, /* GetCalendar */ N7110_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ N7110_AddCalendar, N71_65_DelCalendar, NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ + NOTSUPPORTED, /* GetNoteStatus */ + NOTSUPPORTED, /* GetNote */ NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* SetNote */ + NOTSUPPORTED, /* AddNote */ + NOTSUPPORTED, /* DeleteNote */ + NOTSUPPORTED, /* DeleteAllNotes */ N7110_GetProfile, N7110_SetProfile, NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ NOTSUPPORTED /* SetGPRSAccessPoint */ }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/nokia/dct3/n9210.c b/gammu/emb/common/phone/nokia/dct3/n9210.c index ff71ad3..f535c2a 100644 --- a/gammu/emb/common/phone/nokia/dct3/n9210.c +++ b/gammu/emb/common/phone/nokia/dct3/n9210.c @@ -1,397 +1,403 @@ /* (c) 2002-2003 by Marcin Wiacek */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA9210 #include <string.h> #include <time.h> #include "../../../misc/coding/coding.h" #include "../../../gsmcomon.h" #include "../../../service/gsmlogo.h" #include "../../pfunc.h" #include "../nfunc.h" #include "n9210.h" #include "dct3func.h" static GSM_Error N9210_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { unsigned char OpReq[] = {N6110_FRAME_HEADER, 0x70}; s->Phone.Data.Bitmap=Bitmap; switch (Bitmap->Type) { case GSM_OperatorLogo: smprintf(s, "Getting operator logo\n"); /* This is like DCT3_GetNetworkInfo */ return GSM_WaitFor (s, OpReq, 4, 0x0a, 4, ID_GetBitmap); case GSM_StartupLogo: smprintf(s, "Getting startup logo\n"); return N71_92_GetPhoneSetting(s, ID_GetBitmap, 0x15); case GSM_WelcomeNote_Text: smprintf(s, "Getting welcome note\n"); return N71_92_GetPhoneSetting(s, ID_GetBitmap, 0x02); default: break; } return ERR_NOTSUPPORTED; } static GSM_Error N9210_ReplySetOpLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Operator logo clear/set\n"); return ERR_NONE; } static GSM_Error N9210_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { GSM_Error error; GSM_Phone_Bitmap_Types Type; int Width, Height, i,count=3; unsigned char req[600] = { N7110_FRAME_HEADER }; unsigned char reqStartup[1000] = { N6110_FRAME_HEADER, 0xec, 0x15, /* Startup Logo setting */ 0x04, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0xc0, 0x54, 0x00, 0x03, 0xc0, 0xf8, 0xf8, 0x01, 0x04}; unsigned char reqStartupText[500] = { N7110_FRAME_HEADER, 0xec, 0x02}; /* Startup Text setting */ unsigned char reqClrOp[] = { N7110_FRAME_HEADER, 0xAF, 0x02}; /* Number of logo = 0 - 0x04 */ switch (Bitmap->Type) { case GSM_StartupLogo: if (Bitmap->Location!=1) return ERR_NOTSUPPORTED; Type=GSM_NokiaStartupLogo; PHONE_GetBitmapWidthHeight(Type, &Width, &Height); PHONE_EncodeBitmap(Type, reqStartup + 21, Bitmap); smprintf(s, "Setting startup logo\n"); return GSM_WaitFor (s, reqStartup, 21+PHONE_GetBitmapSize(Type,0,0), 0x7A, 4, ID_SetBitmap); case GSM_WelcomeNote_Text: /* Nokia bug: Unicode text is moved one char to left */ CopyUnicodeString(reqStartupText + 4, Bitmap->Text); reqStartupText[4] = 0x02; i = 5 + UnicodeLength(Bitmap->Text) * 2; reqStartupText[i++] = 0; reqStartupText[i++] = 0; return GSM_WaitFor (s, reqStartupText, i, 0x7A, 4, ID_SetBitmap); case GSM_OperatorLogo: /* First part for clearing logo */ if (!strcmp(Bitmap->NetworkCode,"000 00")) { for (i=0;i<5;i++) { reqClrOp[4] = i; error=GSM_WaitFor (s, reqClrOp, 5, 0x0A, 4, ID_SetBitmap); if (error != ERR_NONE) return error; } } Type=GSM_NokiaOperatorLogo; req[count++] = 0xA3; req[count++] = 0x01; req[count++] = 0x00; /* Logo removed */ NOKIA_EncodeNetworkCode(req+count, "000 00"); count = count + 3; req[count++] = 0x00; req[count++] = 0x04; req[count++] = 0x08; /* Length of rest + 2 */ memcpy(req+count, "\x00\x00\x00\x00\x00\x00", 6); count += 6; error=GSM_WaitFor (s, req, count, 0x0A, 4, ID_SetBitmap); if (error != ERR_NONE) return error; /* We wanted only clear - now exit */ if (!strcmp(Bitmap->NetworkCode,"000 00")) return error; /* Now setting logo */ count=3; req[count++] = 0xA3; req[count++] = 0x01; req[count++] = 0x01; /* Logo set */ NOKIA_EncodeNetworkCode(req+count, Bitmap->NetworkCode); count = count + 3; req[count++] = 0x00; req[count++] = 0x04; req[count++] = PHONE_GetBitmapSize(Type,0,0)+8; PHONE_GetBitmapWidthHeight(Type, &Width, &Height); req[count++] = Width; req[count++] = Height; req[count++] = PHONE_GetBitmapSize(Type,0,0); req[count++] = 0x00; req[count++] = 0x00; req[count++] = 0x00; PHONE_EncodeBitmap(Type, req+count, Bitmap); return GSM_WaitFor (s, req, count+PHONE_GetBitmapSize(Type,0,0), 0x0A, 4, ID_SetBitmap); default: break; } return ERR_NOTSUPPORTED; } static GSM_Error N9210_ReplyIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_SMSMessage sms; GSM_Phone_Data *Data = &s->Phone.Data; #ifdef DEBUG smprintf(s, "SMS message received\n"); sms.State = SMS_UnRead; sms.InboxFolder = true; DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+5); #endif if (Data->EnableIncomingSMS && s->User.IncomingSMS!=NULL) { sms.State = SMS_UnRead; sms.InboxFolder = true; DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+5); s->User.IncomingSMS(s->CurrentConfig->Device,sms); } return ERR_NONE; } #ifdef GSM_ENABLE_N71_92INCOMINGINFO static GSM_Error N9210_ReplySetIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x0e: s->Phone.Data.EnableIncomingSMS = true; smprintf(s, "Incoming SMS enabled\n"); return ERR_NONE; case 0x0f: smprintf(s, "Error enabling incoming SMS\n"); switch (msg.Buffer[4]) { case 0x0c: smprintf(s, "No PIN ?\n"); return ERR_SECURITYERROR; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } } return ERR_UNKNOWNRESPONSE; } #endif static GSM_Error N9210_SetIncomingSMS(GSM_StateMachine *s, bool enable) { #ifdef GSM_ENABLE_N71_92INCOMINGINFO unsigned char req[] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x02}; if (enable!=s->Phone.Data.EnableIncomingSMS) { if (enable) { smprintf(s, "Enabling incoming SMS\n"); return GSM_WaitFor (s, req, 7, 0x02, 4, ID_SetIncomingSMS); } else { s->Phone.Data.EnableIncomingSMS = false; smprintf(s, "Disabling incoming SMS\n"); } } return ERR_NONE; #else return ERR_SOURCENOTAVAILABLE; #endif } static GSM_Error N9210_Initialise (GSM_StateMachine *s) { #ifdef DEBUG DCT3_SetIncomingCB(s,true); #ifdef GSM_ENABLE_N71_92INCOMINGINFO N9210_SetIncomingSMS(s,true); #endif #endif return ERR_NONE; } GSM_Error N9210_AnswerCall(GSM_StateMachine *s, int ID, bool all) { if (!all) return DCT3DCT4_AnswerCall(s,ID); return DCT3_AnswerAllCalls(s); } static GSM_Reply_Function N9210ReplyFunctions[] = { {DCT3_ReplySendSMSMessage, "\x02",0x03,0x02,ID_IncomingFrame }, {DCT3_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame }, #ifdef GSM_ENABLE_N71_92INCOMINGINFO {N9210_ReplySetIncomingSMS, "\x02",0x03,0x0E,ID_SetIncomingSMS }, {N9210_ReplySetIncomingSMS, "\x02",0x03,0x0F,ID_SetIncomingSMS }, #endif {N9210_ReplyIncomingSMS, "\x02",0x03,0x11,ID_IncomingFrame }, #ifdef GSM_ENABLE_CELLBROADCAST {DCT3_ReplySetIncomingCB, "\x02",0x03,0x21,ID_SetIncomingCB }, {DCT3_ReplySetIncomingCB, "\x02",0x03,0x22,ID_SetIncomingCB }, {DCT3_ReplyIncomingCB, "\x02",0x03,0x23,ID_IncomingFrame }, #endif {DCT3_ReplySetSMSC, "\x02",0x03,0x31,ID_SetSMSC }, {DCT3_ReplyGetSMSC, "\x02",0x03,0x34,ID_GetSMSC }, {DCT3_ReplyGetSMSC, "\x02",0x03,0x35,ID_GetSMSC }, {N61_91_ReplySetOpLogo, "\x05",0x03,0x31,ID_SetBitmap }, {N61_91_ReplySetOpLogo, "\x05",0x03,0x32,ID_SetBitmap }, {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_GetNetworkInfo }, {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_IncomingFrame }, {N71_92_ReplyGetSignalQuality, "\x0A",0x03,0x82,ID_GetSignalQuality }, {N9210_ReplySetOpLogo, "\x0A",0x03,0xA4,ID_SetBitmap }, {N9210_ReplySetOpLogo, "\x0A",0x03,0xB0,ID_SetBitmap }, {N71_92_ReplyGetBatteryCharge, "\x17",0x03,0x03,ID_GetBatteryCharge }, {DCT3_ReplySetDateTime, "\x19",0x03,0x61,ID_SetDateTime }, {DCT3_ReplyGetDateTime, "\x19",0x03,0x63,ID_GetDateTime }, {DCT3_ReplyEnableSecurity, "\x40",0x02,0x64,ID_EnableSecurity }, {DCT3_ReplyGetIMEI, "\x40",0x02,0x66,ID_GetIMEI }, {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_DialVoice }, {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_CancelCall }, {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_AnswerCall }, {DCT3_ReplyNetmonitor, "\x40",0x02,0x7E,ID_Netmonitor }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetHardware }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetPPM }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCA,ID_GetProductCode }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetManufactureMonth }, {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetOriginalIMEI }, {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x02,ID_GetBitmap }, {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x02,ID_SetBitmap }, {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x15,ID_GetBitmap }, {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x15,ID_SetBitmap }, {DCT3DCT4_ReplyGetModelFirmware,"\xD2",0x02,0x00,ID_GetModel }, {DCT3DCT4_ReplyGetModelFirmware,"\xD2",0x02,0x00,ID_GetFirmware }, {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions N9210Phone = { "9210|9210i", N9210ReplyFunctions, N9210_Initialise, PHONE_Terminate, GSM_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ NOKIA_GetManufacturer, DCT3DCT4_GetModel, DCT3DCT4_GetFirmware, DCT3_GetIMEI, DCT3_GetOriginalIMEI, DCT3_GetManufactureMonth, DCT3_GetProductCode, DCT3_GetHardware, DCT3_GetPPM, NOTSUPPORTED, /* GetSIMIMSI */ N71_92_GetDateTime, N71_92_SetDateTime, NOTIMPLEMENTED, /* GetAlarm */ NOTIMPLEMENTED, /* SetAlarm */ NOTSUPPORTED, /* GetLocale */ NOTSUPPORTED, /* SetLocale */ NOTIMPLEMENTED, /* PressKey */ NOTIMPLEMENTED, /* Reset */ NOTIMPLEMENTED, /* ResetPhoneSettings */ NOTSUPPORTED, /* EnterSecurityCode */ NOTSUPPORTED, /* GetSecurityStatus */ NOTSUPPORTED, /* GetDisplayStatus */ NOTIMPLEMENTED, /* SetAutoNetworkLogin */ N71_92_GetBatteryCharge, N71_92_GetSignalQuality, DCT3_GetNetworkInfo, NOTSUPPORTED, /* GetCategory */ NOTSUPPORTED, /* AddCategory */ NOTSUPPORTED, /* GetCategoryStatus */ NOTIMPLEMENTED, /* GetMemoryStatus */ NOTIMPLEMENTED, /* GetMemory */ NOTIMPLEMENTED, /* GetNextMemory */ NOTIMPLEMENTED, /* SetMemory */ NOTIMPLEMENTED, /* AddMemory */ NOTIMPLEMENTED, /* DeleteMemory */ NOTIMPLEMENTED, /* DeleteAllMemory */ NOTIMPLEMENTED, /* GetSpeedDial */ NOTIMPLEMENTED, /* SetSpeedDial */ DCT3_GetSMSC, DCT3_SetSMSC, /* FIXME: test it */ NOTIMPLEMENTED, /* GetSMSStatus */ NOTIMPLEMENTED, /* GetSMS */ NOTIMPLEMENTED, /* GetNextSMS */ NOTIMPLEMENTED, /* SetSMS */ NOTIMPLEMENTED, /* AddSMS */ NOTIMPLEMENTED, /* DeleteSMS */ DCT3_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ NOTSUPPORTED, /* SetFastSMSSending */ N9210_SetIncomingSMS, DCT3_SetIncomingCB, NOTIMPLEMENTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ DCT3_DialVoice, N9210_AnswerCall, DCT3_CancelCall, NOTSUPPORTED, /* HoldCall */ NOTSUPPORTED, /* UnholdCall */ NOTSUPPORTED, /* ConferenceCall */ NOTSUPPORTED, /* SplitCall */ NOTSUPPORTED, /* TransferCall */ NOTSUPPORTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ NOTSUPPORTED, /* SetCallDivert */ NOTSUPPORTED, /* CancelAllDiverts */ NOTSUPPORTED, /* SetIncomingCall */ NOTIMPLEMENTED, /* SetIncomingUSSD */ NOTSUPPORTED, /* SendDTMF */ NOTIMPLEMENTED, /* GetRingtone */ NOTIMPLEMENTED, /* SetRingtone */ NOTSUPPORTED, /* GetRingtonesInfo */ NOTSUPPORTED, /* DeleteUserRingtones */ NOTSUPPORTED, /* PlayTone */ NOTIMPLEMENTED, /* GetWAPBookmark */ NOTIMPLEMENTED, /* SetWAPBookmark */ NOTIMPLEMENTED, /* DeleteWAPBookmark */ NOTIMPLEMENTED, /* GetWAPSettings */ NOTSUPPORTED, /* SetWAPSettings */ NOTSUPPORTED, /* GetMMSSettings */ NOTSUPPORTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetSyncMLSettings */ NOTSUPPORTED, /* SetSyncMLSettings */ NOTSUPPORTED, /* GetChatSettings */ NOTSUPPORTED, /* SetChatSettings */ N9210_GetBitmap, N9210_SetBitmap, NOTSUPPORTED, /* GetToDoStatus */ NOTSUPPORTED, /* GetToDo */ NOTSUPPORTED, /* GetNextToDo */ NOTSUPPORTED, /* SetToDo */ NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ NOTSUPPORTED, /* GetCalendarStatus */ NOTSUPPORTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTSUPPORTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTSUPPORTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ + NOTSUPPORTED, /* GetNoteStatus */ + NOTSUPPORTED, /* GetNote */ NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* SetNote */ + NOTSUPPORTED, /* AddNote */ + NOTSUPPORTED, /* DeleteNote */ + NOTSUPPORTED, /* DeleteAllNotes */ NOTIMPLEMENTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ NOTSUPPORTED /* SetGPRSAccessPoint */ }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/nokia/dct4/n3320.c b/gammu/emb/common/phone/nokia/dct4/n3320.c index 9b1d6cd..9dd9ffb 100644 --- a/gammu/emb/common/phone/nokia/dct4/n3320.c +++ b/gammu/emb/common/phone/nokia/dct4/n3320.c @@ -1,272 +1,278 @@ /* (c) 2004 by Marcin Wiacek */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA3320 #include <string.h> #include <time.h> #include "../../../gsmcomon.h" #include "../../../misc/coding/coding.h" #include "../../../service/gsmlogo.h" #include "../nfunc.h" #include "../nfuncold.h" #include "../../pfunc.h" #include "n3320.h" static GSM_Error N3320_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Phonebook entry received\n"); switch (msg.Buffer[6]) { case 0x0f: return N71_65_ReplyGetMemoryError(msg.Buffer[10], s); default: return N71_65_DecodePhonebook(s, s->Phone.Data.Memory, s->Phone.Data.Bitmap, s->Phone.Data.SpeedDial, msg.Buffer+22, msg.Length-22,true); } return ERR_UNKNOWN; } static GSM_Error N3320_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry) { unsigned char req[] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x01, 0x00, 0x01, 0xfe, 0x10, /* memory type */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* location */ 0x00, 0x00, 0x01}; req[9] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES); if (entry->MemoryType == MEM_SM) return ERR_NOTSUPPORTED; if (req[9]==0xff) return ERR_NOTSUPPORTED; if (entry->Location==0x00) return ERR_INVALIDLOCATION; req[14] = entry->Location / 256; req[15] = entry->Location % 256; s->Phone.Data.Memory=entry; smprintf(s, "Getting phonebook entry\n"); return GSM_WaitFor (s, req, 19, 0x03, 4, ID_GetMemory); } static GSM_Error N3320_ReplyGetMemoryStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Memory status received\n"); /* Quess ;-)) */ if (msg.Buffer[14]==0x10) { Data->MemoryStatus->MemoryFree = msg.Buffer[18]*256 + msg.Buffer[19]; } else { Data->MemoryStatus->MemoryFree = msg.Buffer[17]; } smprintf(s, "Size : %i\n",Data->MemoryStatus->MemoryFree); Data->MemoryStatus->MemoryUsed = msg.Buffer[20]*256 + msg.Buffer[21]; smprintf(s, "Used : %i\n",Data->MemoryStatus->MemoryUsed); Data->MemoryStatus->MemoryFree -= Data->MemoryStatus->MemoryUsed; smprintf(s, "Free : %i\n",Data->MemoryStatus->MemoryFree); return ERR_NONE; } static GSM_Error N3320_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status) { unsigned char req[] = {N6110_FRAME_HEADER, 0x03, 0x02, 0x00, /* memory type */ 0x55, 0x55, 0x55, 0x00}; req[5] = NOKIA_GetMemoryType(s, Status->MemoryType,N71_65_MEMORY_TYPES); if (Status->MemoryType == MEM_SM) return ERR_NOTSUPPORTED; if (req[5]==0xff) return ERR_NOTSUPPORTED; s->Phone.Data.MemoryStatus=Status; smprintf(s, "Getting memory status\n"); return GSM_WaitFor (s, req, 10, 0x03, 4, ID_GetMemoryStatus); } static GSM_Error N3320_ReplyGetDateTime(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Date & time received\n"); if (msg.Buffer[4]==0x01) { NOKIA_DecodeDateTime(s, msg.Buffer+10, s->Phone.Data.DateTime); return ERR_NONE; } smprintf(s, "Not set in phone\n"); return ERR_EMPTY; } static GSM_Error N3320_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x00, 0x00}; s->Phone.Data.DateTime=date_time; smprintf(s, "Getting date & time\n"); return GSM_WaitFor (s, req, 6, 0x19, 4, ID_GetDateTime); } static GSM_Error N3320_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) { return N71_65_GetNextCalendar1(s,Note,start,&s->Phone.Data.Priv.N3320.LastCalendar,&s->Phone.Data.Priv.N3320.LastCalendarYear,&s->Phone.Data.Priv.N3320.LastCalendarPos); } static GSM_Error N3320_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status) { GSM_Error error; /* Method 1 */ error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N3320.LastCalendar); if (error!=ERR_NONE) return error; Status->Used = s->Phone.Data.Priv.N3320.LastCalendar.Number; return ERR_NONE; } static GSM_Error N3320_ReplyGetCalendarInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { return N71_65_ReplyGetCalendarInfo1(msg, s, &s->Phone.Data.Priv.N3320.LastCalendar); } static GSM_Reply_Function N3320ReplyFunctions[] = { {N3320_ReplyGetMemoryStatus, "\x03",0x03,0x04,ID_GetMemoryStatus }, {N3320_ReplyGetMemory, "\x03",0x03,0x08,ID_GetMemory }, {N71_65_ReplyGetNextCalendar1, "\x13",0x03,0x1A,ID_GetCalendarNote },/*method 1*/ {N3320_ReplyGetCalendarInfo, "\x13",0x03,0x3B,ID_GetCalendarNotesInfo},/*method 1*/ {N3320_ReplyGetDateTime, "\x19",0x03,0x0B,ID_GetDateTime }, {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetModel }, {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetFirmware }, {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions N3320Phone = { "3320", N3320ReplyFunctions, NONEFUNCTION, /* Initialise */ NONEFUNCTION, /* Terminate */ GSM_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ NOKIA_GetManufacturer, DCT3DCT4_GetModel, DCT3DCT4_GetFirmware, NOTSUPPORTED, /* GetIMEI */ NOTSUPPORTED, /* GetOriginalIMEI */ NOTSUPPORTED, /* GetManufactureMonth */ NOTSUPPORTED, /* GetProductCode */ NOTSUPPORTED, /* GetHardware */ NOTSUPPORTED, /* GetPPM */ NOTSUPPORTED, /* GetSIMIMSI */ N3320_GetDateTime, NOTSUPPORTED, /* SetDateTime */ NOTSUPPORTED, /* GetAlarm */ NOTSUPPORTED, /* SetAlarm */ NOTSUPPORTED, /* GetLocale */ NOTSUPPORTED, /* SetLocale */ NOTSUPPORTED, /* PressKey */ NOTSUPPORTED, /* Reset */ NOTSUPPORTED, /* ResetPhoneSettings */ NOTSUPPORTED, /* EnterSecurityCode */ NOTSUPPORTED, /* GetSecurityStatus */ NOTSUPPORTED, /* GetDisplayStatus */ NOTSUPPORTED, /* SetAutoNetworkLogin */ NOTSUPPORTED, /* GetBatteryCharge */ NOTSUPPORTED, /* GetSignalQuality */ NOTSUPPORTED, /* GetNetworkInfo */ NOTSUPPORTED, /* GetCategory */ NOTSUPPORTED, /* AddCategory */ NOTSUPPORTED, /* GetCategoryStatus */ N3320_GetMemoryStatus, N3320_GetMemory, NOTSUPPORTED, /* GetNextMemory */ NOTSUPPORTED, /* SetMemory */ NOTSUPPORTED, /* AddMemory */ NOTSUPPORTED, /* DeleteMemory */ NOTIMPLEMENTED, /* DeleteAllMemory */ NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ NOTSUPPORTED, /* GetSMSC */ NOTSUPPORTED, /* SetSMSC */ NOTSUPPORTED, /* GetSMSStatus */ NOTSUPPORTED, /* GetSMS */ NOTSUPPORTED, /* GetNextSMS */ NOTSUPPORTED, /* SetSMS */ NOTSUPPORTED, /* AddSMS */ NOTSUPPORTED, /* DeleteSMS */ NOTSUPPORTED, /* SendSMS */ NOTSUPPORTED, /* SendSavedSMS */ NOTSUPPORTED, /* SetFastSMSSending */ NOTSUPPORTED, /* SetIncomingSMS */ NOTSUPPORTED, /* SetIncomingCB */ NOTSUPPORTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ NOTIMPLEMENTED, /* DialVoice */ NOTIMPLEMENTED, /* AnswerCall */ NOTIMPLEMENTED, /* CancelCall */ NOTIMPLEMENTED, /* HoldCall */ NOTIMPLEMENTED, /* UnholdCall */ NOTIMPLEMENTED, /* ConferenceCall */ NOTIMPLEMENTED, /* SplitCall */ NOTIMPLEMENTED, /* TransferCall */ NOTIMPLEMENTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ NOTSUPPORTED, /* SetCallDivert */ NOTSUPPORTED, /* CancelAllDiverts */ NOTIMPLEMENTED, /* SetIncomingCall */ NOTIMPLEMENTED, /* SetIncomingUSSD */ NOTSUPPORTED, /* SendDTMF */ NOTSUPPORTED, /* GetRingtone */ NOTSUPPORTED, /* SetRingtone */ NOTSUPPORTED, /* GetRingtonesInfo */ NOTIMPLEMENTED, /* DeleteUserRingtones */ NOTSUPPORTED, /* PlayTone */ NOTSUPPORTED, /* GetWAPBookmark */ NOTSUPPORTED, /* SetWAPBookmark */ NOTSUPPORTED, /* DeleteWAPBookmark */ NOTSUPPORTED, /* GetWAPSettings */ NOTSUPPORTED, /* SetWAPSettings */ NOTSUPPORTED, /* GetMMSSettings */ NOTSUPPORTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetSyncMLSettings */ NOTSUPPORTED, /* SetSyncMLSettings */ NOTSUPPORTED, /* GetChatSettings */ NOTSUPPORTED, /* SetChatSettings */ NOTSUPPORTED, /* GetBitmap */ NOTSUPPORTED, /* SetBitmap */ NOTSUPPORTED, /* GetToDoStatus */ NOTSUPPORTED, /* GetToDo */ NOTSUPPORTED, /* GetNextToDo */ NOTSUPPORTED, /* SetToDo */ NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ N3320_GetCalendarStatus, NOTIMPLEMENTED, /* GetCalendar */ N3320_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ + NOTSUPPORTED, /* GetNoteStatus */ + NOTSUPPORTED, /* GetNote */ NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* SetNote */ + NOTSUPPORTED, /* AddNote */ + NOTSUPPORTED, /* DeleteNote */ + NOTSUPPORTED, /* DeleteAllNotes */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTIMPLEMENTED, /* AddFilePart */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTIMPLEMENTED, /* DeleteFile */ NOTIMPLEMENTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ NOTSUPPORTED /* SetGPRSAccessPoint */ }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/nokia/dct4/n3650.c b/gammu/emb/common/phone/nokia/dct4/n3650.c index d4746a7..f1fa826 100644 --- a/gammu/emb/common/phone/nokia/dct4/n3650.c +++ b/gammu/emb/common/phone/nokia/dct4/n3650.c @@ -1,393 +1,399 @@ /* (c) 2003 by Marcin Wiacek */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA3650 #include <string.h> #include <time.h> #include "../../../gsmcomon.h" #include "../../../misc/coding/coding.h" #include "../../../service/gsmlogo.h" #include "../nfunc.h" #include "../nfuncold.h" #include "../../pfunc.h" #include "dct4func.h" #include "n3650.h" static GSM_Error N3650_ReplyGetFilePart(GSM_Protocol_Message msg, GSM_StateMachine *s) { int old; smprintf(s,"File part received\n"); old = s->Phone.Data.File->Used; if (msg.Length < 10) { if (old == 0) return ERR_UNKNOWN; return ERR_EMPTY; } s->Phone.Data.File->Used += msg.Buffer[10]*256*256*256+ msg.Buffer[11]*256*256+ msg.Buffer[12]*256+ msg.Buffer[13]; smprintf(s,"Length: %i\n", msg.Buffer[10]*256*256*256+ msg.Buffer[11]*256*256+ msg.Buffer[12]*256+ msg.Buffer[13]); s->Phone.Data.File->Buffer = (unsigned char *)realloc(s->Phone.Data.File->Buffer,s->Phone.Data.File->Used); memcpy(s->Phone.Data.File->Buffer+old,msg.Buffer+18,s->Phone.Data.File->Used-old); if (s->Phone.Data.File->Used-old < 0x03 * 256 + 0xD4) return ERR_EMPTY; return ERR_NONE; } static GSM_Error N3650_GetFilePart(GSM_StateMachine *s, GSM_File *File) { unsigned int len=10,i; GSM_Error error; unsigned char StartReq[500] = { N7110_FRAME_HEADER, 0x0D, 0x10, 0x01, 0x07, 0x24, /* len1 */ 0x12, /* len2 */ 0x0E, /* len3 */ 0x00}; /* File name */ unsigned char ContinueReq[] = { N7110_FRAME_HEADER, 0x0D, 0x20, 0x01, 0xF0, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00}; if (File->Used == 0) { sprintf(StartReq+10,"%s",File->ID_FullName); len+=strlen(File->ID_FullName)-1; StartReq[7] = strlen(File->ID_FullName) + 3; StartReq[8] = strlen(File->ID_FullName); StartReq[9] = 0; while (File->ID_FullName[StartReq[8]] != '\\') { StartReq[8]--; StartReq[9]++; } for (i=StartReq[8];i<strlen(File->ID_FullName);i++) { StartReq[i+10] = StartReq[i+1+10]; } StartReq[9]--; EncodeUnicode(File->Name,File->ID_FullName+StartReq[8]+1,StartReq[9]); File->Folder = false; error = DCT4_SetPhoneMode(s, DCT4_MODE_TEST); if (error != ERR_NONE) return error; s->Phone.Data.File = File; return GSM_WaitFor (s, StartReq, len, 0x58, 4, ID_GetFile); } s->Phone.Data.File = File; error = GSM_WaitFor (s, ContinueReq, 14, 0x58, 4, ID_GetFile); // if (error == GE_EMPTY) { // error = DCT4_SetPhoneMode(s, DCT4_MODE_NORMAL); // if (error != ERR_NONE) return error; // return GE_EMPTY; // } return error; } static GSM_Error N3650_ReplyGetFolderInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_File *File = s->Phone.Data.FileInfo; GSM_Phone_N3650Data *Priv = &s->Phone.Data.Priv.N3650; int i,pos = 6; i = Priv->FilesLocationsUsed-1; while (1) { if (i==Priv->FilesLocationsCurrent-1) break; dbgprintf("Copying %i to %i, max %i, current %i\n", i,i+msg.Buffer[5], Priv->FilesLocationsUsed,Priv->FilesLocationsCurrent); memcpy(Priv->Files[i+msg.Buffer[5]],Priv->Files[i],sizeof(GSM_File)); i--; } Priv->FileEntries = msg.Buffer[5]; Priv->FilesLocationsUsed += msg.Buffer[5]; for (i=0;i<msg.Buffer[5];i++) { Priv->Files[Priv->FilesLocationsCurrent+i]->Folder = true; if (msg.Buffer[pos+2] == 0x01) { Priv->Files[Priv->FilesLocationsCurrent+i]->Folder = false; smprintf(s,"File "); } EncodeUnicode(Priv->Files[Priv->FilesLocationsCurrent+i]->Name,msg.Buffer+pos+9,msg.Buffer[pos+8]); smprintf(s,"%s\n",DecodeUnicodeString(Priv->Files[Priv->FilesLocationsCurrent+i]->Name)); Priv->Files[Priv->FilesLocationsCurrent+i]->Level = File->Level+1; sprintf(Priv->Files[Priv->FilesLocationsCurrent+i]->ID_FullName,"%s\\%s",File->ID_FullName,msg.Buffer+pos+9); pos+=msg.Buffer[pos+1]; } dbgprintf("\n"); return ERR_NONE; } static GSM_Error N3650_GetFolderInfo(GSM_StateMachine *s, GSM_File *File) { int len=10; unsigned char req[500] = { N7110_FRAME_HEADER, 0x0B, 0x00, 0x01, 0x07, 0x18, /* folder name length + 6 */ 0x12, /* folder name length */ 0x00, 0x00}; /* folder name */ sprintf(req+10,File->ID_FullName); len +=strlen(File->ID_FullName); req[7] = strlen(File->ID_FullName) + 6; req[8] = strlen(File->ID_FullName); req[len++] = 0x00; req[len++] = 0x00; s->Phone.Data.FileInfo = File; return GSM_WaitFor (s, req, len, 0x58, 4, ID_GetFile); } static GSM_Error N3650_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, bool start) { GSM_Error error; GSM_Phone_N3650Data *Priv = &s->Phone.Data.Priv.N3650; if (start) { error = DCT4_SetPhoneMode(s, DCT4_MODE_LOCAL); if (error != ERR_NONE) return error; Priv->Files[0]->Folder = true; Priv->Files[0]->Level = 1; Priv->Files[0]->Name[0] = 0; Priv->Files[0]->Name[1] = 0; Priv->Files[0]->ID_FullName[0] = 'Z'; Priv->Files[0]->ID_FullName[1] = ':'; Priv->Files[0]->ID_FullName[2] = 0; Priv->Files[1]->Folder = true; Priv->Files[1]->Level = 1; Priv->Files[1]->Name[0] = 0; Priv->Files[1]->Name[1] = 0; Priv->Files[1]->ID_FullName[0] = 'E'; Priv->Files[1]->ID_FullName[1] = ':'; Priv->Files[1]->ID_FullName[2] = 0; Priv->Files[2]->Folder = true; Priv->Files[2]->Level = 1; Priv->Files[2]->Name[0] = 0; Priv->Files[2]->Name[1] = 0; Priv->Files[2]->ID_FullName[0] = 'C'; Priv->Files[2]->ID_FullName[1] = ':'; Priv->Files[2]->ID_FullName[2] = 0; Priv->FilesLocationsUsed = 3; Priv->FilesLocationsCurrent = 0; Priv->FileLev = 1; } if (Priv->FilesLocationsCurrent == Priv->FilesLocationsUsed) { // error = DCT4_SetPhoneMode(s, DCT4_MODE_NORMAL); // if (error != ERR_NONE) return error; return ERR_EMPTY; } strcpy(File->ID_FullName,Priv->Files[Priv->FilesLocationsCurrent]->ID_FullName); File->Level = Priv->Files[Priv->FilesLocationsCurrent]->Level; File->Folder = Priv->Files[Priv->FilesLocationsCurrent]->Folder; CopyUnicodeString(File->Name,Priv->Files[Priv->FilesLocationsCurrent]->Name); Priv->FilesLocationsCurrent++; if (!File->Folder) return ERR_NONE; if (Priv->FilesLocationsCurrent > 1) { if (File->ID_FullName[0]!=Priv->Files[Priv->FilesLocationsCurrent-2]->ID_FullName[0]) { if (File->ID_FullName[0] == 'E') { error = DCT4_SetPhoneMode(s, DCT4_MODE_TEST); error = DCT4_SetPhoneMode(s, DCT4_MODE_TEST); } if (File->ID_FullName[0] == 'C') { error = DCT4_SetPhoneMode(s, DCT4_MODE_LOCAL); error = DCT4_SetPhoneMode(s, DCT4_MODE_LOCAL); } // if (error != ERR_NONE) return error; } } File->ReadOnly = false; File->System = false; File->Protected = false; File->Hidden = false; return N3650_GetFolderInfo(s, File); } static GSM_Error N3650_Initialise (GSM_StateMachine *s) { GSM_Phone_N3650Data *Priv = &s->Phone.Data.Priv.N3650; int i; for (i=0;i<10000;i++) { Priv->Files[i] = malloc(sizeof(GSM_File)); if (Priv->Files[i] == NULL) return ERR_MOREMEMORY; } return ERR_NONE; } static GSM_Error N3650_Terminate(GSM_StateMachine *s) { GSM_Phone_N3650Data *Priv = &s->Phone.Data.Priv.N3650; int i; for (i=0;i<10000;i++) free(Priv->Files[i]); return ERR_NONE; } static GSM_Reply_Function N3650ReplyFunctions[] = { {DCT4_ReplySetPhoneMode, "\x15",0x03,0x64,ID_Reset }, {DCT4_ReplyGetPhoneMode, "\x15",0x03,0x65,ID_Reset }, {NoneReply, "\x15",0x03,0x68,ID_Reset }, {DCT4_ReplyGetIMEI, "\x1B",0x03,0x01,ID_GetIMEI }, {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x08,ID_GetHardware }, {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x0C,ID_GetProductCode }, {N3650_ReplyGetFolderInfo, "\x58",0x03,0x0C,ID_GetFile }, {N3650_ReplyGetFilePart, "\x58",0x03,0x0E,ID_GetFile }, {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions N3650Phone = { "3650|NGAGE", N3650ReplyFunctions, N3650_Initialise, N3650_Terminate, GSM_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ NOKIA_GetManufacturer, DCT3DCT4_GetModel, DCT3DCT4_GetFirmware, DCT4_GetIMEI, NOTSUPPORTED, /* GetOriginalIMEI */ NOTSUPPORTED, /* GetManufactureMonth */ DCT4_GetProductCode, DCT4_GetHardware, NOTSUPPORTED, /* GetPPM */ NOTSUPPORTED, /* GetSIMIMSI */ NOTSUPPORTED, /* GetDateTime */ NOTSUPPORTED, /* SetDateTime */ NOTSUPPORTED, /* GetAlarm */ NOTSUPPORTED, /* SetAlarm */ NOTSUPPORTED, /* GetLocale */ NOTSUPPORTED, /* SetLocale */ NOTSUPPORTED, /* PressKey */ DCT4_Reset, NOTSUPPORTED, /* ResetPhoneSettings */ NOTSUPPORTED, /* EnterSecurityCode */ NOTSUPPORTED, /* GetSecurityStatus */ NOTSUPPORTED, /* GetDisplayStatus */ NOTSUPPORTED, /* SetAutoNetworkLogin */ NOTSUPPORTED, /* GetBatteryCharge */ NOTSUPPORTED, /* GetSignalQuality */ NOTSUPPORTED, /* GetNetworkInfo */ NOTSUPPORTED, /* GetCategory */ NOTSUPPORTED, /* AddCategory */ NOTSUPPORTED, /* GetCategoryStatus */ NOTSUPPORTED, /* GetMemoryStatus */ NOTSUPPORTED, /* GetMemory */ NOTSUPPORTED, /* GetNextMemory */ NOTSUPPORTED, /* SetMemory */ NOTSUPPORTED, /* AddMemory */ NOTSUPPORTED, /* DeleteMemory */ NOTIMPLEMENTED, /* DeleteAllMemory */ NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ NOTSUPPORTED, /* GetSMSC */ NOTSUPPORTED, /* SetSMSC */ NOTSUPPORTED, /* GetSMSStatus */ NOTSUPPORTED, /* GetSMS */ NOTSUPPORTED, /* GetNextSMS */ NOTSUPPORTED, /* SetSMS */ NOTSUPPORTED, /* AddSMS */ NOTSUPPORTED, /* DeleteSMS */ NOTSUPPORTED, /* SendSMS */ NOTSUPPORTED, /* SendSavedSMS */ NOTSUPPORTED, /* SetFastSMSSending */ NOTSUPPORTED, /* SetIncomingSMS */ NOTSUPPORTED, /* SetIncomingCB */ NOTSUPPORTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ NOTIMPLEMENTED, /* DialVoice */ NOTIMPLEMENTED, /* AnswerCall */ NOTIMPLEMENTED, /* CancelCall */ NOTIMPLEMENTED, /* HoldCall */ NOTIMPLEMENTED, /* UnholdCall */ NOTIMPLEMENTED, /* ConferenceCall */ NOTIMPLEMENTED, /* SplitCall */ NOTIMPLEMENTED, /* TransferCall */ NOTIMPLEMENTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ NOTSUPPORTED, /* SetCallDivert */ NOTSUPPORTED, /* CancelAllDiverts */ NOTIMPLEMENTED, /* SetIncomingCall */ NOTIMPLEMENTED, /* SetIncomingUSSD */ NOTSUPPORTED, /* SendDTMF */ NOTSUPPORTED, /* GetRingtone */ NOTSUPPORTED, /* SetRingtone */ NOTSUPPORTED, /* GetRingtonesInfo */ NOTIMPLEMENTED, /* DeleteUserRingtones */ NOTSUPPORTED, /* PlayTone */ NOTSUPPORTED, /* GetWAPBookmark */ NOTSUPPORTED, /* SetWAPBookmark */ NOTSUPPORTED, /* DeleteWAPBookmark */ NOTSUPPORTED, /* GetWAPSettings */ NOTSUPPORTED, /* SetWAPSettings */ NOTSUPPORTED, /* GetMMSSettings */ NOTSUPPORTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetSyncMLSettings */ NOTSUPPORTED, /* SetSyncMLSettings */ NOTSUPPORTED, /* GetChatSettings */ NOTSUPPORTED, /* SetChatSettings */ NOTSUPPORTED, /* GetBitmap */ NOTSUPPORTED, /* SetBitmap */ NOTSUPPORTED, /* GetToDoStatus */ NOTSUPPORTED, /* GetToDo */ NOTSUPPORTED, /* GetNextToDo */ NOTSUPPORTED, /* SetToDo */ NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ NOTIMPLEMENTED, /* GetCalendarStatus */ NOTIMPLEMENTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTIMPLEMENTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ + NOTSUPPORTED, /* GetNoteStatus */ + NOTSUPPORTED, /* GetNote */ NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* SetNote */ + NOTSUPPORTED, /* AddNote */ + NOTSUPPORTED, /* DeleteNote */ + NOTSUPPORTED, /* DeleteAllNotes */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ N3650_GetNextFileFolder, N3650_GetFilePart, NOTIMPLEMENTED, /* AddFilePart */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTIMPLEMENTED, /* DeleteFile */ NOTIMPLEMENTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ NOTSUPPORTED /* SetGPRSAccessPoint */ }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/nokia/dct4/n6510.c b/gammu/emb/common/phone/nokia/dct4/n6510.c index 2208def..c481863 100644 --- a/gammu/emb/common/phone/nokia/dct4/n6510.c +++ b/gammu/emb/common/phone/nokia/dct4/n6510.c @@ -1,5864 +1,5974 @@ /* (c) 2002-2004 by Marcin Wiacek */ /* based on some Markus Plail, Pawel Kot work from Gnokii (www.gnokii.org) * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot * GNU GPL version 2 or later */ /* function for making CRC for filesystem (c) 2003 by Michael Schroeder */ +/* Due to a problem in the source code management, the names of some of + * the authors have unfortunately been lost. We do not mean to belittle + * their efforts and hope they will contact us to see their names + * properly added to the Copyright notice above. + * Having published their contributions under the terms of the GNU + * General Public License (GPL) [version 2], the Copyright of these + * authors will remain respected by adhering to the license they chose + * to publish their code under. + */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA6510 #include <string.h> #include <time.h> #include "../../../misc/coding/coding.h" #include "../../../gsmcomon.h" #include "../../../service/gsmlogo.h" #include "../nfunc.h" #include "../nfuncold.h" #include "../../pfunc.h" #include "dct4func.h" #include "n6510.h" static GSM_Error N6510_Initialise (GSM_StateMachine *s) { s->Phone.Data.Priv.N6510.CalendarIconsNum = 0; /* Enables various things like incoming SMS, call info, etc. */ return N71_65_EnableFunctions (s, "\x01\x02\x06\x0A\x14\x17\x39", 7); } static GSM_Error N6510_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Phonebook entry received\n"); switch (msg.Buffer[6]) { case 0x0f: return N71_65_ReplyGetMemoryError(msg.Buffer[10], s); default: return N71_65_DecodePhonebook(s, s->Phone.Data.Memory, s->Phone.Data.Bitmap, s->Phone.Data.SpeedDial, msg.Buffer+22, msg.Length-22,false); } return ERR_UNKNOWN; } static GSM_Error N6510_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry) { unsigned char req[] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x01, 0x00, 0x01, 0xfe, 0x10, /* memory type */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* location */ 0x00, 0x00, 0x01}; req[9] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES); if (req[9]==0xff) return ERR_NOTSUPPORTED; if (entry->Location==0x00) return ERR_INVALIDLOCATION; req[14] = entry->Location / 256; req[15] = entry->Location % 256; s->Phone.Data.Memory=entry; smprintf(s, "Getting phonebook entry\n"); return GSM_WaitFor (s, req, 19, 0x03, 4, ID_GetMemory); } static GSM_Error N6510_ReplyGetMemoryStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Memory status received\n"); /* Quess ;-)) */ if (msg.Buffer[14]==0x10) { Data->MemoryStatus->MemoryFree = msg.Buffer[18]*256 + msg.Buffer[19]; } else { Data->MemoryStatus->MemoryFree = msg.Buffer[17]; } smprintf(s, "Size : %i\n",Data->MemoryStatus->MemoryFree); Data->MemoryStatus->MemoryUsed = msg.Buffer[20]*256 + msg.Buffer[21]; smprintf(s, "Used : %i\n",Data->MemoryStatus->MemoryUsed); Data->MemoryStatus->MemoryFree -= Data->MemoryStatus->MemoryUsed; smprintf(s, "Free : %i\n",Data->MemoryStatus->MemoryFree); return ERR_NONE; } static GSM_Error N6510_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status) { unsigned char req[] = {N6110_FRAME_HEADER, 0x03, 0x02, 0x00, /* memory type */ 0x55, 0x55, 0x55, 0x00}; req[5] = NOKIA_GetMemoryType(s, Status->MemoryType,N71_65_MEMORY_TYPES); if (req[5]==0xff) return ERR_NOTSUPPORTED; s->Phone.Data.MemoryStatus=Status; smprintf(s, "Getting memory status\n"); return GSM_WaitFor (s, req, 10, 0x03, 4, ID_GetMemoryStatus); } static GSM_Error N6510_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i, current, j; GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[4]) { case 0x00: smprintf(s, "SMSC received\n"); break; case 0x02: smprintf(s, "SMSC empty\n"); return ERR_INVALIDLOCATION; default: smprintf(s, "Unknown SMSC state: %02x\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } memset(Data->SMSC,0,sizeof(GSM_SMSC)); Data->SMSC->Location = msg.Buffer[8]; Data->SMSC->Format = SMS_FORMAT_Text; switch (msg.Buffer[10]) { case 0x00: Data->SMSC->Format = SMS_FORMAT_Text; break; case 0x22: Data->SMSC->Format = SMS_FORMAT_Fax; break; case 0x26: Data->SMSC->Format = SMS_FORMAT_Pager; break; case 0x32: Data->SMSC->Format = SMS_FORMAT_Email; break; } Data->SMSC->Validity.Format = SMS_Validity_RelativeFormat; Data->SMSC->Validity.Relative = msg.Buffer[12]; if (msg.Buffer[12] == 0x00) Data->SMSC->Validity.Relative = SMS_VALID_Max_Time; current = 14; for (i=0;i<msg.Buffer[13];i++) { switch (msg.Buffer[current]) { case 0x81: j=current+4; while (msg.Buffer[j]!=0) {j++;} j=j-33; if (j>GSM_MAX_SMSC_NAME_LENGTH) { smprintf(s, "Too long name\n"); return ERR_UNKNOWNRESPONSE; } CopyUnicodeString(Data->SMSC->Name,msg.Buffer+current+4); smprintf(s, " Name \"%s\"\n", DecodeUnicodeString(Data->SMSC->Name)); break; case 0x82: switch (msg.Buffer[current+2]) { case 0x01: GSM_UnpackSemiOctetNumber(Data->SMSC->DefaultNumber,msg.Buffer+current+4,true); smprintf(s, " Default number \"%s\"\n", DecodeUnicodeString(Data->SMSC->DefaultNumber)); break; case 0x02: GSM_UnpackSemiOctetNumber(Data->SMSC->Number,msg.Buffer+current+4,false); smprintf(s, " Number \"%s\"\n", DecodeUnicodeString(Data->SMSC->Number)); break; default: smprintf(s, "Unknown SMSC number: %02x\n",msg.Buffer[current+2]); return ERR_UNKNOWNRESPONSE; } break; default: smprintf(s, "Unknown SMSC block: %02x\n",msg.Buffer[current]); return ERR_UNKNOWNRESPONSE; } current = current + msg.Buffer[current+1]; } return ERR_NONE; } static GSM_Error N6510_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) { unsigned char req[] = {N6110_FRAME_HEADER, 0x14, 0x01, /* location */ 0x00}; if (smsc->Location==0x00) return ERR_INVALIDLOCATION; req[4]=smsc->Location; s->Phone.Data.SMSC=smsc; smprintf(s, "Getting SMSC\n"); return GSM_WaitFor (s, req, 6, 0x02, 4, ID_GetSMSC); } static GSM_Error N6510_ReplySetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[4]) { case 0x00: smprintf(s, "SMSC set OK\n"); return ERR_NONE; case 0x02: smprintf(s, "Invalid SMSC location\n"); return ERR_INVALIDLOCATION; default: smprintf(s, "Unknown SMSC state: %02x\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) { int count = 13,i; unsigned char req[256] = {N6110_FRAME_HEADER, 0x12, 0x55, 0x01, 0x0B, 0x34, 0x05, /* Location */ 0x00, 0x00, /* Format */ 0x00, 0xFF}; /* Validity */ req[8] = smsc->Location; switch (smsc->Format) { case SMS_FORMAT_Text: req[10] = 0x00; break; case SMS_FORMAT_Fax: req[10] = 0x22; break; case SMS_FORMAT_Pager: req[10] = 0x26; break; case SMS_FORMAT_Email: req[10] = 0x32; break; } req[12] = smsc->Validity.Relative; /* We have now blocks. Number of blocks = 3 */ req[count++] = 0x03; /* -------------- SMSC number ----------------- */ /* Block type: number */ req[count++] = 0x82; /* Offset to next block */ req[count++] = 0x1A; /* Type of number: SMSC number */ req[count++] = 0x02; req[count] = GSM_PackSemiOctetNumber(smsc->Number, req+count+2, false) + 1; if (req[count]>18) { smprintf(s, "Too long SMSC number in frame\n"); return ERR_UNKNOWN; } req[count+1] = req[count] - 1; count += 23; /* --------------- Default number ------------- */ /* Block type: number */ req[count++] = 0x82; /* Offset to next block */ req[count++] = 0x14; /* Type of number: default number */ req[count++] = 0x01; req[count] = GSM_PackSemiOctetNumber(smsc->DefaultNumber, req+count+2, true) + 1; if (req[count]*2>12) { smprintf(s, "Too long SMSC number in frame\n"); return ERR_UNKNOWN; } req[count+1] = req[count] - 1; count += 17; /* -------------- SMSC name ------------------- */ req[count++] = 0x81; req[count++] = UnicodeLength(smsc->Name)*2 + 2 + 4; req[count++] = UnicodeLength(smsc->Name)*2 + 2; req[count++] = 0x00; /* Can't make CopyUnicodeString(req+count,sms->Name) !!!! * with MSVC6 count is changed then */ i = count; CopyUnicodeString(req+i,smsc->Name); count += UnicodeLength(smsc->Name)*2 + 2; smprintf(s, "Setting SMSC\n"); return GSM_WaitFor (s, req, count, 0x02, 4, ID_SetSMSC); } static GSM_Error N6510_ReplyGetNetworkInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int current = msg.Buffer[7]+7, tmp; GSM_Phone_Data *Data = &s->Phone.Data; #ifdef DEBUG char name[100]; GSM_NetworkInfo NetInfo; smprintf(s, "Network status : "); switch (msg.Buffer[8]) { case 0x00 : smprintf(s, "home network\n"); break; case 0x01 : smprintf(s, "roaming network\n"); break; case 0x04 : smprintf(s, "not logged"); break; case 0x06 : smprintf(s, "SIM card rejected\n"); break; case 0x09 : smprintf(s, "not logged"); break; default : smprintf(s, "unknown %i!\n",msg.Buffer[8]); break; } if (msg.Buffer[8]==0x00 || msg.Buffer[8] == 0x01) { NOKIA_DecodeNetworkCode(msg.Buffer + (current + 7),NetInfo.NetworkCode); smprintf(s, "Network code : %s\n", NetInfo.NetworkCode); smprintf(s, "Network name for Gammu : %s ", DecodeUnicodeString(GSM_GetNetworkName(NetInfo.NetworkCode))); smprintf(s, "(%s)\n",DecodeUnicodeString(GSM_GetCountryName(NetInfo.NetworkCode))); - sprintf(NetInfo.LAC, "%02x%02x", msg.Buffer[current+1], msg.Buffer[current+2]); + sprintf(NetInfo.LAC, "%02X%02X", msg.Buffer[current+1], msg.Buffer[current+2]); smprintf(s, "LAC : %s\n", NetInfo.LAC); - sprintf(NetInfo.CID, "%02x%02x", msg.Buffer[current+5], msg.Buffer[current+6]); + sprintf(NetInfo.CID, "%02X%02X", msg.Buffer[current+5], msg.Buffer[current+6]); smprintf(s, "CID : %s\n", NetInfo.CID); tmp = 10; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer,name,true); smprintf(s, "Network name for phone : %s\n",DecodeUnicodeString(name)); } #endif if (Data->RequestID==ID_GetNetworkInfo) { Data->NetworkInfo->NetworkName[0] = 0x00; Data->NetworkInfo->NetworkName[1] = 0x00; Data->NetworkInfo->State = 0; switch (msg.Buffer[8]) { case 0x00: Data->NetworkInfo->State = GSM_HomeNetwork; break; case 0x01: Data->NetworkInfo->State = GSM_RoamingNetwork; break; case 0x04: case 0x06: case 0x09: Data->NetworkInfo->State = GSM_NoNetwork; break; } if (Data->NetworkInfo->State == GSM_HomeNetwork || Data->NetworkInfo->State == GSM_RoamingNetwork) { tmp = 10; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer,Data->NetworkInfo->NetworkName,true); - sprintf(Data->NetworkInfo->LAC, "%02x%02x", msg.Buffer[current+1], msg.Buffer[current+2]); - sprintf(Data->NetworkInfo->CID, "%02x%02x", msg.Buffer[current+5], msg.Buffer[current+6]); + sprintf(Data->NetworkInfo->LAC, "%02X%02X", msg.Buffer[current+1], msg.Buffer[current+2]); + sprintf(Data->NetworkInfo->CID, "%02X%02X", msg.Buffer[current+5], msg.Buffer[current+6]); NOKIA_DecodeNetworkCode(msg.Buffer + (current+7),Data->NetworkInfo->NetworkCode); } } return ERR_NONE; } static GSM_Error N6510_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo) { unsigned char req[] = {N6110_FRAME_HEADER, 0x00, 0x00}; s->Phone.Data.NetworkInfo=netinfo; smprintf(s, "Getting network info\n"); return GSM_WaitFor (s, req, 5, 0x0a, 4, ID_GetNetworkInfo); } static GSM_Error N6510_EncodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *req, GSM_SMSMessageLayout *Layout, int *length) { int start, count = 0, pos1, pos2, pos3, pos4, pos5; GSM_Error error; memset(Layout,255,sizeof(GSM_SMSMessageLayout)); start = *length; req[count++] = 0x01; if (sms->PDU != SMS_Deliver) { req[count++] = 0x02; } else { req[count++] = 0x00; } pos1 = count; count++; /* firstbyte set in SMS Layout */ Layout->firstbyte = count; count++; if (sms->PDU != SMS_Deliver) { Layout->TPMR = count; count++; Layout->TPPID = count; count++; /* TP.DCS set in SMS layout */ Layout->TPDCS = count; count++; req[count++] = 0x00; } else { Layout->TPPID = count; count++; /* TP.DCS set in SMS layout */ Layout->TPDCS = count; count++; Layout->DateTime = count; count += 7; req[count++] = 0x55; req[count++] = 0x55; req[count++] = 0x55; } /* We have now blocks. Number of blocks = 3 or 4 */ if (sms->PDU != SMS_Deliver) { req[count++] = 0x04; } else { req[count++] = 0x03; } /* -------------- Phone number ------------- */ /* Block type: number */ req[count++] = 0x82; /* Offset to next block */ req[count++] = 0x10; /* Type of number: default number */ req[count++] = 0x01; pos4 = count; count++; /* now coded Number in SMS Layout */ Layout->Number = count; count+= 12; /* -------------- SMSC number -------------- */ /* Block type: number */ req[count++] = 0x82; /* Offset to next block */ req[count++] = 0x10; /* Type of number: SMSC number */ req[count++] = 0x02; pos5 = count; count++; /* now coded SMSC number in SMS Layout */ Layout->SMSCNumber = count; count += 12; /* -------------- SMS validity ------------- */ if (sms->PDU != SMS_Deliver) { /* Block type: validity */ req[count++] = 0x08; req[count++] = 0x04; /* data length */ req[count++] = 0x01; Layout->TPVP = count; count++; } /* --------------- SMS text ---------------- */ /* Block type: SMS text */ req[count++] = 0x80; /* this the same as req[11] but starting from req[42] */ pos2 = count; count++; pos3 = count; count++; /* FIXME*/ Layout->TPUDL = count; count++; /* SMS text and UDH coded in SMS Layout */ Layout->Text = count; error = PHONE_EncodeSMSFrame(s,sms,req,*Layout,length,false); if (error != ERR_NONE) return error; req[pos1] = *length - 1; req[pos2] = *length - Layout->Text + 6; req[pos3] = *length - Layout->Text; /* Convert number of semioctets to number of chars */ req[pos4] = req[Layout->Number] + 4; if (req[pos4] % 2) req[pos4]++; req[pos4] /= 2; req[pos5] = req[Layout->SMSCNumber] + 1; if (req[pos4]>12 || req[pos5]>12) { smprintf(s, "Too long phone number in frame\n"); return ERR_UNKNOWN; } return ERR_NONE; } static GSM_Error N6510_ReplyGetSMSFolders(GSM_Protocol_Message msg, GSM_StateMachine *s) { int j, num = 0, pos; GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x13: smprintf(s, "SMS folders names received\n"); Data->SMSFolders->Number = msg.Buffer[5]+2; pos = 6; for (j=0;j<msg.Buffer[5];j++) { while (true) { if (msg.Buffer[pos] == msg.Buffer[6] && msg.Buffer[pos+1] == msg.Buffer[7]) break; if (pos+4 > msg.Length) return ERR_UNKNOWNRESPONSE; pos++; } pos+=4; smprintf(s, "Folder index: %02x",msg.Buffer[pos - 2]); if (msg.Buffer[pos - 1]>GSM_MAX_SMS_FOLDER_NAME_LEN) { smprintf(s, "Too long text\n"); return ERR_UNKNOWNRESPONSE; } CopyUnicodeString(Data->SMSFolders->Folder[num].Name,msg.Buffer + pos); smprintf(s, ", folder name: \"%s\"\n",DecodeUnicodeString(Data->SMSFolders->Folder[num].Name)); Data->SMSFolders->Folder[num].InboxFolder = false; Data->SMSFolders->Folder[num].Memory = MEM_ME; if (num == 0x01) { /* OUTBOX SIM */ Data->SMSFolders->Folder[0].Memory = MEM_SM; Data->SMSFolders->Folder[0].InboxFolder = true; Data->SMSFolders->Folder[1].Memory = MEM_SM; CopyUnicodeString(Data->SMSFolders->Folder[2].Name,Data->SMSFolders->Folder[0].Name); Data->SMSFolders->Folder[2].Memory = MEM_ME; Data->SMSFolders->Folder[2].InboxFolder = true; CopyUnicodeString(Data->SMSFolders->Folder[3].Name,Data->SMSFolders->Folder[1].Name); Data->SMSFolders->Folder[3].Memory = MEM_ME; Data->SMSFolders->Folder[3].InboxFolder = false; num+=2; } num++; } return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders) { unsigned char req[] = {N6110_FRAME_HEADER, 0x12, 0x00, 0x00}; s->Phone.Data.SMSFolders=folders; smprintf(s, "Getting SMS folders\n"); return GSM_WaitFor (s, req, 6, 0x14, 4, ID_GetSMSFolders); } static GSM_Error N6510_ReplyGetSMSFolderStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; smprintf(s, "SMS folder status received\n"); Priv->LastSMSFolder.Number=msg.Buffer[6]*256+msg.Buffer[7]; smprintf(s, "Number of Entries: %i\n",Priv->LastSMSFolder.Number); smprintf(s, "Locations: "); for (i=0;i<Priv->LastSMSFolder.Number;i++) { Priv->LastSMSFolder.Location[i]=msg.Buffer[8+(i*2)]*256+msg.Buffer[(i*2)+9]; smprintf(s, "%i ",Priv->LastSMSFolder.Location[i]); } smprintf(s, "\n"); NOKIA_SortSMSFolderStatus(s, &Priv->LastSMSFolder); return ERR_NONE; } static GSM_Error N6510_GetSMSFolderStatus(GSM_StateMachine *s, int folderid) { unsigned char req[] = {N7110_FRAME_HEADER, 0x0C, 0x01, /* 0x01=SIM, 0x02=ME */ 0x00, /* Folder ID */ 0x0f, 0x55, 0x55, 0x55}; switch (folderid) { case 0x01: req[5] = 0x02; break; /* INBOX SIM */ case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */ default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */ } smprintf(s, "Getting SMS folder status\n"); return GSM_WaitFor (s, req, 10, 0x14, 4, ID_GetSMSFolderStatus); } static void N6510_GetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *folderid, int *location) { int ifolderid; /* simulate flat SMS memory */ if (sms->Folder==0x00) { ifolderid = sms->Location / PHONE_MAXSMSINFOLDER; *folderid = ifolderid + 0x01; *location = sms->Location - ifolderid * PHONE_MAXSMSINFOLDER; } else { *folderid = sms->Folder; *location = sms->Location; } smprintf(s, "SMS folder %i & location %i -> 6510 folder %i & location %i\n", sms->Folder,sms->Location,*folderid,*location); } static void N6510_SetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char folderid, int location) { sms->Folder = 0; sms->Location = (folderid - 0x01) * PHONE_MAXSMSINFOLDER + location; smprintf(s, "6510 folder %i & location %i -> SMS folder %i & location %i\n", folderid,location,sms->Folder,sms->Location); } static GSM_Error N6510_DecodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *buffer) { int i, current, blocks=0, SMSTemplateDateTime = 0; GSM_SMSMessageLayout Layout; GSM_Error error; memset(&Layout,255,sizeof(GSM_SMSMessageLayout)); Layout.firstbyte = 2; switch (buffer[0]) { case 0x00: smprintf(s, "SMS deliver\n"); sms->PDU = SMS_Deliver; Layout.TPPID = 3; Layout.TPDCS = 4; Layout.DateTime = 5; blocks = 15; break; case 0x01: smprintf(s, "Delivery report\n"); sms->PDU = SMS_Status_Report; Layout.TPMR = 3; Layout.TPStatus = 4; Layout.DateTime = 5; Layout.SMSCTime = 12; blocks = 19; break; case 0x02: smprintf(s, "SMS template\n"); sms->PDU = SMS_Submit; Layout.TPMR = 3; Layout.TPPID = 4; Layout.TPDCS = 5; blocks = 7; break; } current = blocks + 1; for (i=0;i<buffer[blocks];i++) { switch (buffer[current]) { case 0x80: smprintf(s, "SMS text\n"); if (buffer[current + 2] > buffer[current + 3]) { Layout.TPUDL = current + 2; } else { Layout.TPUDL = current + 3; } Layout.Text = current + 4; break; case 0x82: switch (buffer[current+2]) { case 0x01: smprintf(s, "Phone number\n"); Layout.Number = current + 4; break; case 0x02: smprintf(s, "SMSC number\n"); Layout.SMSCNumber = current + 4; break; default: smprintf(s, "Unknown number\n"); break; } break; case 0x84: smprintf(s, "Date and time of saving for SMS template\n"); SMSTemplateDateTime = current + 2; break; default: smprintf(s, "Unknown block %02x\n",buffer[current]); } current = current + buffer[current + 1]; } error=GSM_DecodeSMSFrame(sms,buffer,Layout); if (SMSTemplateDateTime != 0) { sms->PDU = SMS_Deliver; NOKIA_DecodeDateTime(s, buffer+SMSTemplateDateTime, &sms->DateTime); sms->DateTime.Timezone = 0; } return error; } static GSM_Error N6510_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; int Width, Height; unsigned char output[500]; //output2[500]; GSM_Phone_Data *Data = &s->Phone.Data; switch(msg.Buffer[3]) { case 0x03: smprintf(s, "SMS Message received\n"); Data->GetSMSMessage->Number=1; NOKIA_DecodeSMSState(s, msg.Buffer[5], &Data->GetSMSMessage->SMS[0]); switch (msg.Buffer[14]) { case 0x00: case 0x01: case 0x02: return N6510_DecodeSMSFrame(s, &Data->GetSMSMessage->SMS[0],msg.Buffer+14); case 0xA0: smprintf(s, "Picture Image\n"); Data->GetSMSMessage->Number = 0; i = 0; output[i++] = 0x30; /* Smart Messaging 3.0 */ output[i++] = SM30_OTA; output[i++] = 0x01; /* Length */ output[i++] = 0x00; /* Length */ output[i++] = 0x00; PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height); output[i++] = Width; output[i++] = Height; output[i++] = 0x01; memcpy(output+i,msg.Buffer+30,PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0)); i = i + PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0); // if (msg.Length!=282) { // output[i++] = SM30_UNICODETEXT; // output[i++] = 0; // output[i++] = 0; /* Length - later changed */ // GSM_UnpackEightBitsToSeven(0, msg.Length-282, msg.Length-304, msg.Buffer+282,output2); // DecodeDefault(output+i, output2, msg.Length - 282, true); // output[i - 1] = UnicodeLength(output+i) * 2; // i = i + output[i-1]; // } GSM_MakeMultiPartSMS(Data->GetSMSMessage,output,i,UDH_NokiaProfileLong,SMS_Coding_8bit,1,0); for (i=0;i<3;i++) { Data->GetSMSMessage->SMS[i].Number[0]=0; Data->GetSMSMessage->SMS[i].Number[1]=0; } if (Data->Bitmap != NULL) { Data->Bitmap->Location = 0; PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height); Data->Bitmap->BitmapWidth = Width; Data->Bitmap->BitmapHeight = Height; PHONE_DecodeBitmap(GSM_NokiaPictureImage, msg.Buffer + 30, Data->Bitmap); Data->Bitmap->Sender[0] = 0x00; Data->Bitmap->Sender[1] = 0x00; Data->Bitmap->Text[0] = 0; Data->Bitmap->Text[1] = 0; } return ERR_NONE; default: smprintf(s, "Unknown SMS type: %i\n",msg.Buffer[8]); } break; case 0x0f: smprintf(s, "SMS message info received\n"); CopyUnicodeString(Data->GetSMSMessage->SMS[0].Name,msg.Buffer+52); smprintf(s, "Name: \"%s\"\n",DecodeUnicodeString(Data->GetSMSMessage->SMS[0].Name)); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_PrivGetSMSMessageBitmap(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, GSM_Bitmap *bitmap) { GSM_Error error; unsigned char folderid,namebuffer[200]; int location; int i; unsigned char req[] = { N6110_FRAME_HEADER, 0x02, /* msg type: 0x02 for getting sms, 0x0e for sms status */ 0x01, /* 0x01=SIM, 0x02=ME */ 0x00, /* FolderID */ 0x00, 0x02, /* Location */ 0x01, 0x00}; N6510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location); switch (folderid) { case 0x01: req[5] = 0x02; break; /* INBOX SIM */ case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */ default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */ } req[6]=location / 256; req[7]=location; s->Phone.Data.GetSMSMessage = sms; s->Phone.Data.Bitmap = bitmap; smprintf(s, "Getting sms message info\n"); req[3] = 0x0e; req[8] = 0x55; req[9] = 0x55; error=GSM_WaitFor (s, req, 10, 0x14, 4, ID_GetSMSMessage); if (error!=ERR_NONE) return error; CopyUnicodeString(namebuffer,sms->SMS[0].Name); smprintf(s, "Getting sms\n"); req[3] = 0x02; req[8] = 0x01; req[9] = 0x00; error=GSM_WaitFor (s, req, 10, 0x14, 4, ID_GetSMSMessage); if (error==ERR_NONE) { for (i=0;i<sms->Number;i++) { N6510_SetSMSLocation(s, &sms->SMS[i], folderid, location); sms->SMS[i].Folder = folderid; sms->SMS[i].InboxFolder = true; if (folderid != 0x01 && folderid != 0x03) sms->SMS[i].InboxFolder = false; sms->SMS[i].Memory = MEM_ME; if (folderid == 0x01 || folderid == 0x02) sms->SMS[i].Memory = MEM_SM; CopyUnicodeString(sms->SMS[i].Name,namebuffer); } } return error; } static GSM_Error N6510_GetSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms) { GSM_Error error; unsigned char folderid; int location; GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; int i; bool found = false; N6510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location); error=N6510_GetSMSFolderStatus(s, folderid); if (error!=ERR_NONE) return error; for (i=0;i<Priv->LastSMSFolder.Number;i++) { if (Priv->LastSMSFolder.Location[i]==location) { found = true; break; } } if (!found) return ERR_EMPTY; return N6510_PrivGetSMSMessageBitmap(s,sms,NULL); } static GSM_Error N6510_GetNextSMSMessageBitmap(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start, GSM_Bitmap *bitmap) { GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; unsigned char folderid; int location; GSM_Error error; int i; bool findnextfolder = false; if (start) { folderid = 0x00; findnextfolder = true; error=N6510_GetSMSFolders(s,&Priv->LastSMSFolders); if (error!=ERR_NONE) return error; } else { N6510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location); for (i=0;i<Priv->LastSMSFolder.Number;i++) { if (Priv->LastSMSFolder.Location[i]==location) break; } /* Is this last location in this folder ? */ if (i==Priv->LastSMSFolder.Number-1) { findnextfolder=true; } else { location=Priv->LastSMSFolder.Location[i+1]; } } if (findnextfolder) { Priv->LastSMSFolder.Number=0; while (Priv->LastSMSFolder.Number==0) { folderid++; /* Too high folder number */ if ((folderid-1)>Priv->LastSMSFolders.Number) return ERR_EMPTY; /* Get next folder status */ error=N6510_GetSMSFolderStatus(s, folderid); if (error!=ERR_NONE) return error; /* First location from this folder */ location=Priv->LastSMSFolder.Location[0]; } } N6510_SetSMSLocation(s, &sms->SMS[0], folderid, location); return N6510_PrivGetSMSMessageBitmap(s, sms, bitmap); } static GSM_Error N6510_GetNextSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start) { return N6510_GetNextSMSMessageBitmap(s, sms, start, NULL); } static GSM_Error N6510_ReplyStartupNoteLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; if (Data->RequestID == ID_GetBitmap) { switch (msg.Buffer[4]) { case 0x01: smprintf(s, "Welcome note text received\n"); CopyUnicodeString(Data->Bitmap->Text,msg.Buffer+6); smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text)); return ERR_NONE; case 0x10: smprintf(s, "Dealer note text received\n"); CopyUnicodeString(Data->Bitmap->Text,msg.Buffer+6); smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text)); return ERR_NONE; case 0x0f: smprintf(s, "Startup logo received\n"); PHONE_DecodeBitmap(GSM_Nokia7110StartupLogo, msg.Buffer + 22, Data->Bitmap); return ERR_NONE; } } if (Data->RequestID == ID_SetBitmap) { switch (msg.Buffer[4]) { case 0x01: case 0x10: case 0x0f: case 0x25: return ERR_NONE; } } return ERR_UNKNOWN; } static GSM_Error N6510_GetPictureImage(GSM_StateMachine *s, GSM_Bitmap *Bitmap, int *location) { GSM_MultiSMSMessage sms; int Number; GSM_Bitmap bitmap; GSM_Error error; sms.SMS[0].Folder = 0; Number = 0; bitmap.Location = 255; error=N6510_GetNextSMSMessageBitmap(s, &sms, true, &bitmap); while (error == ERR_NONE) { if (bitmap.Location != 255) { Number++; if (Number == Bitmap->Location) { bitmap.Location = Bitmap->Location; memcpy(Bitmap,&bitmap,sizeof(GSM_Bitmap)); *location = sms.SMS[0].Location; return ERR_NONE; } } bitmap.Location = 255; sms.SMS[0].Folder = 0; error=N6510_GetNextSMSMessageBitmap(s, &sms, false, &bitmap); } return ERR_INVALIDLOCATION; } static GSM_Error N6510_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { unsigned char reqOp [] = {N6110_FRAME_HEADER, 0x23, 0x00, 0x00, 0x55, 0x55, 0x55}; unsigned char reqStartup[] = {N6110_FRAME_HEADER, 0x02, 0x0f}; unsigned char reqNote [] = {N6110_FRAME_HEADER, 0x02, 0x01, 0x00}; GSM_MemoryEntry pbk; GSM_Error error; int Location; s->Phone.Data.Bitmap=Bitmap; switch (Bitmap->Type) { case GSM_StartupLogo: Bitmap->BitmapWidth = 96; Bitmap->BitmapHeight = 65; GSM_ClearBitmap(Bitmap); smprintf(s, "Getting startup logo\n"); return GSM_WaitFor (s, reqStartup, 5, 0x7A, 4, ID_GetBitmap); case GSM_DealerNote_Text: reqNote[4] = 0x10; smprintf(s, "Getting dealer note\n"); return GSM_WaitFor (s, reqNote, 6, 0x7A, 4, ID_GetBitmap); case GSM_WelcomeNote_Text: smprintf(s, "Getting welcome note\n"); return GSM_WaitFor (s, reqNote, 6, 0x7A, 4, ID_GetBitmap); case GSM_CallerGroupLogo: if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PBK35)) return ERR_NOTSUPPORTED; Bitmap->BitmapWidth = 72; Bitmap->BitmapHeight = 14; GSM_ClearBitmap(Bitmap); pbk.MemoryType = MEM7110_CG; pbk.Location = Bitmap->Location; smprintf(s, "Getting caller group logo\n"); error=N6510_GetMemory(s,&pbk); if (error==ERR_NONE) NOKIA_GetDefaultCallerGroupName(s, Bitmap); return error; case GSM_OperatorLogo: smprintf(s, "Getting operator logo\n"); return GSM_WaitFor (s, reqOp, 9, 0x0A, 4, ID_GetBitmap); case GSM_PictureImage: return N6510_GetPictureImage(s, Bitmap, &Location); default: break; } return ERR_NOTSUPPORTED; } static GSM_Error N6510_ReplyGetIncSignalQuality(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Network level changed to: %i\n",msg.Buffer[4]); return ERR_NONE; } static GSM_Error N6510_ReplyGetSignalQuality(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Network level received: %i\n",msg.Buffer[8]); Data->SignalQuality->SignalStrength = -1; Data->SignalQuality->SignalPercent = ((int)msg.Buffer[8]); Data->SignalQuality->BitErrorRate = -1; return ERR_NONE; } static GSM_Error N6510_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig) { unsigned char req[] = {N6110_FRAME_HEADER, 0x0B, 0x00, 0x02, 0x00, 0x00, 0x00}; s->Phone.Data.SignalQuality = sig; smprintf(s, "Getting network level\n"); return GSM_WaitFor (s, req, 9, 0x0a, 4, ID_GetSignalQuality); } static GSM_Error N6510_ReplyGetBatteryCharge(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Battery level received: %i\n",msg.Buffer[9]*100/7); Data->BatteryCharge->BatteryPercent = ((int)(msg.Buffer[9]*100/7)); Data->BatteryCharge->ChargeState = 0; return ERR_NONE; } static GSM_Error N6510_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat) { unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x02, 0x00}; s->Phone.Data.BatteryCharge = bat; smprintf(s, "Getting battery level\n"); return GSM_WaitFor (s, req, 6, 0x17, 4, ID_GetBatteryCharge); } static GSM_Error N6510_ReplyGetWAPBookmark(GSM_Protocol_Message msg, GSM_StateMachine *s) { return DCT3DCT4_ReplyGetWAPBookmark (msg, s, true); } static GSM_Error N6510_ReplyGetOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Operator logo received\n"); if (msg.Length == 18) return ERR_EMPTY; NOKIA_DecodeNetworkCode(msg.Buffer+12,Data->Bitmap->NetworkCode); smprintf(s, "Network code %s\n",Data->Bitmap->NetworkCode); Data->Bitmap->BitmapWidth = msg.Buffer[20]; Data->Bitmap->BitmapHeight = msg.Buffer[21]; PHONE_DecodeBitmap(GSM_Nokia6510OperatorLogo,msg.Buffer+26,Data->Bitmap); return ERR_NONE; } GSM_Error N6510_ReplyDeleteMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Phonebook entry deleted\n"); return ERR_NONE; } GSM_Error N6510_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { unsigned char req[] = {N7110_FRAME_HEADER, 0x0f, 0x55, 0x01, 0x04, 0x55, 0x00, 0x10, 0xFF, 0x02, 0x00, 0x01, /* location */ 0x00, 0x00, 0x00, 0x00, 0x05, /* memory type */ 0x55, 0x55, 0x55}; req[12] = entry->Location / 256; req[13] = entry->Location % 256; req[18] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES); if (req[18]==0xff) return ERR_NOTSUPPORTED; smprintf(s, "Deleting phonebook entry\n"); return GSM_WaitFor (s, req, 22, 0x03, 4, ID_SetMemory); } static GSM_Error N6510_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) { int count = 22, blocks; unsigned char req[500] = { N7110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x10, 0x02, 0x00, /* memory type */ 0x00, 0x00, /* location */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (entry->Location == 0) return ERR_NOTSUPPORTED; req[11] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES); if (req[11]==0xff) return ERR_NOTSUPPORTED; req[12] = entry->Location / 256; req[13] = entry->Location % 256; count = count + N71_65_EncodePhonebookFrame(s, req+22, *entry, &blocks, true, IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_VOICETAGS)); req[21] = blocks; smprintf(s, "Writing phonebook entry\n"); return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetMemory); } static GSM_Error N6510_ReplySetOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Operator logo set OK\n"); return ERR_NONE; } static GSM_Error N6510_SetCallerLogo(GSM_StateMachine *s, GSM_Bitmap *bitmap) { char string[500]; int block=0, i, Width, Height; unsigned int count = 22; unsigned char req[500] = { N6110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x10, 0xfe, 0x10, /* memory type */ 0x00, 0x00, /* location */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; req[13] = bitmap->Location; /* Enabling/disabling logo */ string[0] = bitmap->BitmapEnabled?1:0; string[1] = 0; count += N71_65_PackPBKBlock(s, N7110_PBK_LOGOON, 2, block++, string, req + count); /* Ringtone */ if (!bitmap->DefaultRingtone) { if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PBKTONEGAL)) { } else { string[0] = 0x00; string[1] = 0x00; string[2] = bitmap->RingtoneID; count += N71_65_PackPBKBlock(s, N7110_PBK_RINGTONE_ID, 3, block++, string, req + count); count --; req[count-5] = 8; } } /* Number of group */ string[0] = bitmap->Location; string[1] = 0; count += N71_65_PackPBKBlock(s, N7110_PBK_GROUP, 2, block++, string, req + count); /* Name */ if (!bitmap->DefaultName) { i = UnicodeLength(bitmap->Text) * 2; string[0] = i + 2; memcpy(string + 1, bitmap->Text, i); string[i + 1] = 0; count += N71_65_PackPBKBlock(s, N7110_PBK_NAME, i + 2, block++, string, req + count); } /* Logo */ if (!bitmap->DefaultBitmap) { PHONE_GetBitmapWidthHeight(GSM_NokiaCallerLogo, &Width, &Height); string[0] = Width; string[1] = Height; string[2] = 0; string[3] = 0; string[4] = PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0); PHONE_EncodeBitmap(GSM_NokiaCallerLogo, string + 5, bitmap); count += N71_65_PackPBKBlock(s, N7110_PBK_GROUPLOGO, PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 5, block++, string, req + count); } req[21] = block; return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetBitmap); } static GSM_Error N6510_ReplySetPicture(GSM_Protocol_Message msg, GSM_StateMachine *s) { // smprintf(s, "Picture Image written OK, folder %i, location %i\n",msg.Buffer[4],msg.Buffer[5]*256+msg.Buffer[6]); return ERR_NONE; } static GSM_Error N6510_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { GSM_SMSMessage sms; GSM_Phone_Bitmap_Types Type; int Width, Height, i, count; -#ifdef DEVELOP unsigned char folderid; - int location; -#endif + int location; GSM_NetworkInfo NetInfo; GSM_Error error; unsigned char reqStartup[1000] = { N7110_FRAME_HEADER, 0x04, 0x0F, 0x00, 0x00, 0x00, 0x04, 0xC0, 0x02, 0x00, 0x41, 0xC0, 0x03, 0x00, 0x60, 0xC0, 0x04}; unsigned char reqColourWallPaper[200] = { N6110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0xD5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18}; /* Bitmap ID */ unsigned char reqColourStartup[200] = { N6110_FRAME_HEADER, 0x04, 0x25, 0x00, 0x01, 0x00, 0x18}; unsigned char reqOp[1000] = { N7110_FRAME_HEADER, 0x25, 0x01, 0x55, 0x00, 0x00, 0x55, 0x01, /* 0x01 - not set, 0x02 - set */ 0x0C, 0x08, 0x62, 0xF0, 0x10, /* Network code */ 0x03, 0x55, 0x55}; unsigned char reqColourOp[200] = { N6110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x08, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, /* File ID */ 0x00, 0x00, 0x00, 0x00}; /* Network code */ unsigned char reqNote[200] = {N6110_FRAME_HEADER, 0x04, 0x01}; unsigned char reqPicture[2000] = { N6110_FRAME_HEADER, 0x00, 0x02, 0x05, /* SMS folder */ 0x00, 0x00, /* location */ 0x01, 0x01, 0xa0, 0x02, 0x01, 0x40, 0x00, 0x34, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x03, 0x82, 0x10, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x10, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0xa1, 0x55, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x48, 0x1c, 0x00, 0xfc, 0x00}; switch (Bitmap->Type) { case GSM_ColourWallPaper_ID: reqColourWallPaper[21] = Bitmap->ID; smprintf(s, "Setting colour wall paper\n"); return GSM_WaitFor (s, reqColourWallPaper, 22, 0x43, 4, ID_SetBitmap); case GSM_StartupLogo: Type = GSM_Nokia7110StartupLogo; switch (Bitmap->Location) { case 1: PHONE_EncodeBitmap(Type, reqStartup + 22, Bitmap); break; case 2: memset(reqStartup+5,0x00,15); PHONE_ClearBitmap(Type, reqStartup + 22,0,0); break; default: return ERR_NOTSUPPORTED; } smprintf(s, "Setting startup logo\n"); return GSM_WaitFor (s, reqStartup, 22+PHONE_GetBitmapSize(Type,0,0), 0x7A, 4, ID_SetBitmap); case GSM_DealerNote_Text: reqNote[4] = 0x10; CopyUnicodeString(reqNote + 5, Bitmap->Text); i = 6 + UnicodeLength(Bitmap->Text) * 2; reqNote[i++] = 0; reqNote[i] = 0; return GSM_WaitFor (s, reqNote, i, 0x7A, 4, ID_SetBitmap); case GSM_WelcomeNote_Text: CopyUnicodeString(reqNote + 5, Bitmap->Text); i = 6 + UnicodeLength(Bitmap->Text) * 2; reqNote[i++] = 0; reqNote[i] = 0; return GSM_WaitFor (s, reqNote, i, 0x7A, 4, ID_SetBitmap); case GSM_OperatorLogo: /* We want to set operator logo, not clear */ if (strcmp(Bitmap->NetworkCode,"000 00")) { memset(reqOp + 19, 0, 281); NOKIA_EncodeNetworkCode(reqOp+12, Bitmap->NetworkCode); Type = GSM_Nokia6510OperatorLogo; reqOp[9] = 0x02; /* Logo enabled */ reqOp[18] = 0x1a; /* FIXME */ reqOp[19] = PHONE_GetBitmapSize(Type,0,0) + 8 + 29 + 2; PHONE_GetBitmapWidthHeight(Type, &Width, &Height); reqOp[20] = Width; reqOp[21] = Height; reqOp[22] = 0x00; reqOp[23] = PHONE_GetBitmapSize(Type,0,0) + 29; reqOp[24] = 0x00; reqOp[25] = PHONE_GetBitmapSize(Type,0,0) + 29; PHONE_EncodeBitmap(Type, reqOp + 26, Bitmap); smprintf(s, "Setting operator logo\n"); return GSM_WaitFor (s, reqOp, reqOp[19]+reqOp[11]+10, 0x0A, 4, ID_SetBitmap); } else { error=N6510_GetNetworkInfo(s,&NetInfo); if (error != ERR_NONE) return error; NOKIA_EncodeNetworkCode(reqOp+12, NetInfo.NetworkCode); smprintf(s, "Clearing operator logo\n"); return GSM_WaitFor (s, reqOp, 18, 0x0A, 4, ID_SetBitmap); } case GSM_ColourOperatorLogo_ID: /* We want to set operator logo, not clear */ if (strcmp(Bitmap->NetworkCode,"000 00")) { EncodeBCD(reqColourOp+23, Bitmap->NetworkCode, 6, false); reqColourOp[21] = Bitmap->ID; } smprintf(s, "Setting colour operator logo\n"); return GSM_WaitFor (s, reqColourOp, 26, 0x43, 4, ID_SetBitmap); case GSM_ColourStartupLogo_ID: switch (Bitmap->Location) { case 0: reqColourStartup[6] = 0x00; reqColourStartup[8] = 0x00; smprintf(s, "Setting colour startup logo\n"); return GSM_WaitFor (s, reqColourStartup, 9, 0x7A, 4, ID_SetBitmap); case 1: reqColourStartup[8] = Bitmap->ID; smprintf(s, "Setting colour startup logo\n"); return GSM_WaitFor (s, reqColourStartup, 9, 0x7A, 4, ID_SetBitmap); default:return ERR_NOTSUPPORTED; } case GSM_CallerGroupLogo: return N6510_SetCallerLogo(s,Bitmap); case GSM_PictureImage: error = N6510_GetPictureImage(s, Bitmap, &sms.Location); if (error == ERR_NONE) { -#ifdef DEVELOP sms.Folder = 0; N6510_GetSMSLocation(s, &sms, &folderid, &location); switch (folderid) { case 0x01: reqPicture[5] = 0x02; break; /* INBOX SIM */ case 0x02: reqPicture[5] = 0x03; break; /* OUTBOX SIM */ default : reqPicture[5] = folderid - 1; reqPicture[4] = 0x02; break; /* ME folders */ } reqPicture[6]=location / 256; reqPicture[7]=location; -#else - return ERR_NOTSUPPORTED; -#endif } Type = GSM_NokiaPictureImage; count = 78; PHONE_EncodeBitmap(Type, reqPicture + count, Bitmap); count += PHONE_GetBitmapSize(Type,0,0); smprintf(s, "Setting Picture Image\n"); return GSM_WaitFor (s, reqPicture, count, 0x14, 4, ID_SetBitmap); default: break; } return ERR_NOTSUPPORTED; } static GSM_Error N6510_ReplyGetRingtoneID(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; smprintf(s, "Ringtone ID received\n"); Priv->RingtoneID = msg.Buffer[15]; return ERR_NONE; } static GSM_Error N6510_ReplySetBinRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Binary ringtone set\n"); return ERR_NONE; } static GSM_Error N6510_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) { GSM_Error error; GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; GSM_NetworkInfo NetInfo; int size=200, current; unsigned char GetIDReq[] = { N7110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x06, 0xE1, 0x00, 0xFF, 0x06, 0xE1, 0x01, 0x42}; unsigned char SetPreviewReq[1000] = { 0xAE, /* Ringtone ID */ 0x01, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*Length*/ unsigned char AddBinaryReq[33000] = { N7110_FRAME_HEADER, 0x0E, 0x7F, 0xFF, 0xFE}; if (Ringtone->Format == RING_NOTETONE && Ringtone->Location==255) { smprintf(s, "Getting ringtone ID\n"); error=GSM_WaitFor (s, GetIDReq, 14, 0xDB, 4, ID_SetRingtone); if (error != ERR_NONE) return error; *maxlength=GSM_EncodeNokiaRTTLRingtone(*Ringtone, SetPreviewReq+11, &size); SetPreviewReq[0] = Priv->RingtoneID; SetPreviewReq[10] = size; smprintf(s, "Setting ringtone\n"); error = s->Protocol.Functions->WriteMessage(s, SetPreviewReq, size+11, 0x00); if (error!=ERR_NONE) return error; my_sleep(1000); /* We have to make something (not important, what) now */ /* no answer from phone*/ return s->Phone.Functions->GetNetworkInfo(s,&NetInfo); } if (Ringtone->Format == RING_NOKIABINARY) { AddBinaryReq[7] = UnicodeLength(Ringtone->Name); CopyUnicodeString(AddBinaryReq+8,Ringtone->Name); current = 8 + UnicodeLength(Ringtone->Name)*2; AddBinaryReq[current++] = Ringtone->NokiaBinary.Length/256 + 1; AddBinaryReq[current++] = Ringtone->NokiaBinary.Length%256 + 1; AddBinaryReq[current++] = 0x00; memcpy(AddBinaryReq+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length); current += Ringtone->NokiaBinary.Length; smprintf(s, "Adding binary ringtone\n"); return GSM_WaitFor (s, AddBinaryReq, current, 0x1F, 4, ID_SetRingtone); } if (Ringtone->Format == RING_MIDI) { AddBinaryReq[7] = UnicodeLength(Ringtone->Name); CopyUnicodeString(AddBinaryReq+8,Ringtone->Name); current = 8 + UnicodeLength(Ringtone->Name)*2; AddBinaryReq[current++] = Ringtone->NokiaBinary.Length/256; AddBinaryReq[current++] = Ringtone->NokiaBinary.Length%256; memcpy(AddBinaryReq+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length); current += Ringtone->NokiaBinary.Length; AddBinaryReq[current++] = 0x00; AddBinaryReq[current++] = 0x00; smprintf(s, "Adding binary or MIDI ringtone\n"); return GSM_WaitFor (s, AddBinaryReq, current, 0x1F, 4, ID_SetRingtone); } return ERR_NOTSUPPORTED; } static GSM_Error N6510_ReplyDeleteRingtones(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Ringtones deleted\n"); return ERR_NONE; } static GSM_Error N6510_DeleteUserRingtones(GSM_StateMachine *s) { unsigned char DelAllRingtoneReq[] = {N7110_FRAME_HEADER, 0x10, 0x7F, 0xFE}; smprintf(s, "Deleting all user ringtones\n"); return GSM_WaitFor (s, DelAllRingtoneReq, 6, 0x1F, 4, ID_SetRingtone); } static GSM_Error N6510_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press) { #ifdef DEVELOP unsigned char req[] = {N6110_FRAME_HEADER, 0x11, 0x00, 0x01, 0x00, 0x00, 0x00, /* Event */ 0x01}; /* Number of presses */ // req[7] = Key; if (Press) { req[8] = NOKIA_PRESSPHONEKEY; s->Phone.Data.PressKey = true; smprintf(s, "Pressing key\n"); } else { req[8] = NOKIA_RELEASEPHONEKEY; s->Phone.Data.PressKey = false; smprintf(s, "Releasing key\n"); } return GSM_WaitFor (s, req, 10, 0x0c, 4, ID_PressKey); #else return ERR_NOTSUPPORTED; #endif } static GSM_Error N6510_EnableConnectionFunctions(GSM_StateMachine *s, N6510_Connection_Settings Type) { GSM_Error error; unsigned char req2[] = {N6110_FRAME_HEADER, 0x00, 0x01}; unsigned char req3[] = {N6110_FRAME_HEADER, 0x00, 0x03}; unsigned char req4[] = {N6110_FRAME_HEADER, 0x00, 0x04}; if (Type == N6510_MMS_SETTINGS && IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOMMS)) return ERR_NOTSUPPORTED; error=DCT3DCT4_DisableConnectionFunctions(s); if (error!=ERR_NONE) return error; switch (Type) { case N6510_WAP_SETTINGS: return DCT3DCT4_EnableWAPFunctions(s); case N6510_MMS_SETTINGS: dbgprintf("Enabling MMS\n"); return GSM_WaitFor (s, req2, 5, 0x3f, 4, ID_EnableConnectFunc); case N6510_SYNCML_SETTINGS: dbgprintf("Enabling SyncML\n"); return GSM_WaitFor (s, req3, 5, 0x3f, 5, ID_EnableConnectFunc); case N6510_CHAT_SETTINGS: dbgprintf("Enabling Chat\n"); return GSM_WaitFor (s, req4, 5, 0x3f, 5, ID_EnableConnectFunc); default: return ERR_UNKNOWN; } } static GSM_Error N6510_ReplyGetConnectionSettings(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; int tmp,num=0,i; GSM_Phone_Data *Data = &s->Phone.Data; unsigned char buff[2000]; switch(msg.Buffer[3]) { case 0x16: smprintf(s, "Connection settings received OK\n"); Data->WAPSettings->Number = Priv->BearerNumber; Data->WAPSettings->Proxy[0] = 0x00; Data->WAPSettings->Proxy[1] = 0x00; Data->WAPSettings->ProxyPort = 8080; Data->WAPSettings->Proxy2[0] = 0x00; Data->WAPSettings->Proxy2[1] = 0x00; Data->WAPSettings->Proxy2Port = 8080; tmp = 4; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].Title,true); CopyUnicodeString(Data->WAPSettings->Settings[1].Title,Data->WAPSettings->Settings[0].Title); smprintf(s, "Title: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Title)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].HomePage,true); CopyUnicodeString(Data->WAPSettings->Settings[1].HomePage,Data->WAPSettings->Settings[0].HomePage); smprintf(s, "Homepage: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].HomePage)); #ifdef DEBUG smprintf(s, "Connection type: "); switch (msg.Buffer[tmp]) { case 0x00: smprintf(s, "temporary\n"); break; case 0x01: smprintf(s, "continuous\n"); break; default: smprintf(s, "unknown\n"); } smprintf(s, "Connection security: "); switch (msg.Buffer[tmp+1]) { case 0x00: smprintf(s, "off\n"); break; case 0x01: smprintf(s, "on\n"); break; default: smprintf(s, "unknown\n"); } smprintf(s, "Bearer: "); switch (msg.Buffer[tmp+2]) { case 0x01: smprintf(s, "GSM data\n"); break; case 0x03: smprintf(s, "GPRS\n"); break; default: smprintf(s, "unknown\n"); } if (msg.Buffer[tmp+3] == 0x01) smprintf(s, "locked\n"); #endif Data->WAPSettings->Settings[0].IsContinuous = false; if (msg.Buffer[tmp] == 0x01) Data->WAPSettings->Settings[0].IsContinuous = true; Data->WAPSettings->Settings[1].IsContinuous = Data->WAPSettings->Settings[0].IsContinuous; Data->WAPSettings->Settings[0].IsSecurity = false; if (msg.Buffer[tmp+1] == 0x01) Data->WAPSettings->Settings[0].IsSecurity = true; Data->WAPSettings->Settings[1].IsSecurity = Data->WAPSettings->Settings[0].IsSecurity; Data->WAPSettings->ActiveBearer = WAPSETTINGS_BEARER_DATA; if (msg.Buffer[tmp+2] == 0x03) Data->WAPSettings->ActiveBearer = WAPSETTINGS_BEARER_GPRS; Data->WAPSettings->ReadOnly = false; if (msg.Buffer[tmp+3] == 0x01) Data->WAPSettings->ReadOnly = true; tmp+=3; if (Priv->BearerNumber == 2) { /* Here starts settings for data bearer */ Data->WAPSettings->Settings[0].Bearer = WAPSETTINGS_BEARER_DATA; while ((msg.Buffer[tmp] != 0x01) || (msg.Buffer[tmp + 1] != 0x00)) tmp++; tmp += 4; #ifdef DEBUG smprintf(s, "Authentication type: "); switch (msg.Buffer[tmp]) { case 0x00: smprintf(s, "normal\n"); break; case 0x01: smprintf(s, "secure\n"); break; default: smprintf(s, "unknown\n"); break; } smprintf(s, "Data call type: "); switch (msg.Buffer[tmp+1]) { case 0x00: smprintf(s, "analogue\n"); break; case 0x01: smprintf(s, "ISDN\n"); break; default: smprintf(s, "unknown\n"); break; } smprintf(s, "Data call speed: "); switch (msg.Buffer[tmp+2]) { case 0x00: smprintf(s, "automatic\n"); break; case 0x01: smprintf(s, "9600\n"); break; case 0x02: smprintf(s, "14400\n"); break; default: smprintf(s, "unknown\n"); break; } smprintf(s, "Login Type: "); switch (msg.Buffer[tmp+4]) { case 0x00: smprintf(s, "manual\n"); break; case 0x01: smprintf(s, "automatic\n"); break; default: smprintf(s, "unknown\n"); break; } #endif Data->WAPSettings->Settings[0].IsNormalAuthentication=true; if (msg.Buffer[tmp]==0x01) Data->WAPSettings->Settings[0].IsNormalAuthentication=false; Data->WAPSettings->Settings[0].IsISDNCall=false; if (msg.Buffer[tmp+1]==0x01) Data->WAPSettings->Settings[0].IsISDNCall=true; switch (msg.Buffer[tmp+2]) { case 0x00: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_AUTO; break; case 0x01: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_9600; break; case 0x02: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_14400; break; } Data->WAPSettings->Settings[0].ManualLogin=false; if (msg.Buffer[tmp+4]==0x00) Data->WAPSettings->Settings[0].ManualLogin = true; tmp+=5; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].IPAddress,false); smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].IPAddress)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].DialUp,true); smprintf(s, "Dial-up number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].DialUp)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].User,true); smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].User)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].Password,true); smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Password)); num = 1; } else { num = 0; } /* Here starts settings for gprs bearer */ Data->WAPSettings->Settings[num].Bearer = WAPSETTINGS_BEARER_GPRS; while (msg.Buffer[tmp] != 0x03) tmp++; tmp += 4; #ifdef DEBUG smprintf(s, "Authentication type: "); switch (msg.Buffer[tmp]) { case 0x00: smprintf(s, "normal\n"); break; case 0x01: smprintf(s, "secure\n"); break; default: smprintf(s, "unknown\n"); break; } smprintf(s, "GPRS connection: "); switch (msg.Buffer[tmp+1]) { case 0x00: smprintf(s, "ALWAYS online\n"); break; case 0x01: smprintf(s, "when needed\n"); break; default: smprintf(s, "unknown\n"); break; } smprintf(s, "Login Type: "); switch (msg.Buffer[tmp+2]) { case 0x00: smprintf(s, "manual\n"); break; case 0x01: smprintf(s, "automatic\n"); break; default: smprintf(s, "unknown\n"); break; } #endif Data->WAPSettings->Settings[num].IsNormalAuthentication=true; if (msg.Buffer[tmp]==0x01) Data->WAPSettings->Settings[num].IsNormalAuthentication=false; Data->WAPSettings->Settings[num].IsContinuous = true; if (msg.Buffer[tmp+1] == 0x01) Data->WAPSettings->Settings[num].IsContinuous = false; Data->WAPSettings->Settings[num].ManualLogin=false; if (msg.Buffer[tmp+2]==0x00) Data->WAPSettings->Settings[num].ManualLogin = true; tmp+=3; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].DialUp,false); smprintf(s, "Access point: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].DialUp)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].IPAddress,true); smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].IPAddress)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].User,true); smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].User)); NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].Password,true); smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].Password)); if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) { if (msg.Buffer[tmp] == 0x00 && msg.Buffer[tmp+1] == 0x00) tmp = tmp+2; memcpy(buff,msg.Buffer+tmp+10,msg.Buffer[tmp+4]); buff[msg.Buffer[tmp+4]] = 0x00; smprintf(s, "Proxy 1: \"%s\", port %i\n",buff,msg.Buffer[tmp+6]*256+msg.Buffer[tmp+7]); EncodeUnicode(Data->WAPSettings->Proxy,buff,strlen(buff)); Data->WAPSettings->ProxyPort = msg.Buffer[tmp+6]*256+msg.Buffer[tmp+7]; memcpy(buff,msg.Buffer+tmp+10+msg.Buffer[tmp+4],msg.Buffer[tmp+5]); buff[msg.Buffer[tmp+5]] = 0x00; smprintf(s, "Proxy 2: \"%s\", port %i\n",buff,msg.Buffer[tmp+8]*256+msg.Buffer[tmp+9]); EncodeUnicode(Data->WAPSettings->Proxy2,buff,strlen(buff)); Data->WAPSettings->Proxy2Port = msg.Buffer[tmp+8]*256+msg.Buffer[tmp+9]; tmp = tmp + msg.Buffer[tmp+3] + 19; for (i=0;i<4;i++) { #ifdef DEBUG smprintf(s, "Proxy data %i\n",i+1); if (msg.Buffer[tmp+2]!=0) memcpy(buff,msg.Buffer+tmp+9,msg.Buffer[tmp+2]*2); buff[msg.Buffer[tmp+2]*2] =0; buff[msg.Buffer[tmp+2]*2+1]=0; smprintf(s, "IP: \"%s\"",DecodeUnicodeString(buff)); smprintf(s, ", port %i\n",msg.Buffer[tmp+3]*256+msg.Buffer[tmp+4]); #endif tmp = tmp + msg.Buffer[tmp]; } #ifdef DEBUG smprintf(s, "%02x %02x\n",msg.Buffer[tmp],msg.Buffer[tmp+1]); smprintf(s, "Port %i\n",msg.Buffer[tmp+3]*256+msg.Buffer[tmp+4]); tmp = tmp + msg.Buffer[tmp]; #endif } return ERR_NONE; case 0x17: smprintf(s, "Connection settings receiving error\n"); switch (msg.Buffer[4]) { case 0x01: smprintf(s, "Security error. Inside phone settings menu\n"); return ERR_INSIDEPHONEMENU; case 0x02: smprintf(s, "Invalid or empty\n"); return ERR_INVALIDLOCATION; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } break; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetConnectionSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings, N6510_Connection_Settings Type) { GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; GSM_Error error; unsigned char req[] = {N6110_FRAME_HEADER, 0x15, 0x00}; /* Location */ error = N6510_EnableConnectionFunctions(s, Type); if (error!=ERR_NONE) return error; req[4] = settings->Location-1; s->Phone.Data.WAPSettings = settings; switch (Type) { case N6510_MMS_SETTINGS: smprintf(s, "Getting MMS settings\n"); Priv->BearerNumber = 1; break; case N6510_WAP_SETTINGS: smprintf(s, "Getting WAP settings\n"); Priv->BearerNumber = 2; break; case N6510_SYNCML_SETTINGS: smprintf(s, "Getting SyncML settings\n"); Priv->BearerNumber = 2; break; case N6510_CHAT_SETTINGS: smprintf(s, "Getting Chat settings\n"); Priv->BearerNumber = 1; break; } error=GSM_WaitFor (s, req, 5, 0x3f, 4, ID_GetConnectSet); if (error != ERR_NONE) { if (error == ERR_INVALIDLOCATION || error == ERR_INSIDEPHONEMENU) { DCT3DCT4_DisableConnectionFunctions(s); } return error; } error=DCT3DCT4_GetActiveConnectSet(s); if (error != ERR_NONE) return error; return DCT3DCT4_DisableConnectionFunctions(s); } static GSM_Error N6510_GetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings) { return N6510_GetConnectionSettings(s, settings, N6510_WAP_SETTINGS); } static GSM_Error N6510_GetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings) { return N6510_GetConnectionSettings(s, settings, N6510_MMS_SETTINGS); } static GSM_Error N6510_ReplyGetSyncMLSettings(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_SyncMLSettings *Sett = s->Phone.Data.SyncMLSettings; smprintf(s, "SyncML settings received OK\n"); CopyUnicodeString(Sett->User,msg.Buffer+18); CopyUnicodeString(Sett->Password,msg.Buffer+86); CopyUnicodeString(Sett->PhonebookDataBase,msg.Buffer+130); CopyUnicodeString(Sett->CalendarDataBase,msg.Buffer+234); CopyUnicodeString(Sett->Server,msg.Buffer+338); Sett->SyncPhonebook = false; Sett->SyncCalendar = false; if ((msg.Buffer[598] & 0x02)==0x02) Sett->SyncCalendar = true; if ((msg.Buffer[598] & 0x01)==0x01) Sett->SyncPhonebook = true; return ERR_NONE; } static GSM_Error N6510_ReplyGetSyncMLName(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_SyncMLSettings *Sett = s->Phone.Data.SyncMLSettings; smprintf(s, "SyncML names received OK\n"); CopyUnicodeString(Sett->Name,msg.Buffer+18); return ERR_NONE; } static GSM_Error N6510_GetSyncMLSettings(GSM_StateMachine *s, GSM_SyncMLSettings *settings) { GSM_Error error; // unsigned char NameReq[] = {N6110_FRAME_HEADER, 0x05, // 0x00, 0x00, 0x00, 0x31, 0x00, // 0x06, 0x00, 0x00, 0x00, 0xDE, 0x00, 0x00}; // unsigned char GetActive[] = {N6110_FRAME_HEADER, 0x05, // 0x00, 0x00, 0x00, 0x31, 0x00, // 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; unsigned char req[] = {N6110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x31, 0x00, 0x01, //location 0x00, 0x00, 0x02, 0x46, 0x00, 0x00}; settings->Connection.Location = settings->Location; error = N6510_GetConnectionSettings(s, &settings->Connection, N6510_SYNCML_SETTINGS); if (error != ERR_NONE) return error; settings->Active = settings->Connection.Active; settings->Name[0] = 0; settings->Name[1] = 0; s->Phone.Data.SyncMLSettings = settings; // smprintf(s, "Getting SyncML settings name\n"); // error = GSM_WaitFor (s, NameReq, 16, 0x43, 4, ID_GetSyncMLName); // if (error != ERR_NONE) return error; req[9] = settings->Location - 1; smprintf(s, "Getting additional SyncML settings\n"); return GSM_WaitFor (s, req, 16, 0x43, 4, ID_GetSyncMLSettings); } static GSM_Error N6510_ReplyGetChatSettings(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_ChatSettings *Sett = s->Phone.Data.ChatSettings; int i; Sett->Name[0] = 0; Sett->Name[1] = 0; Sett->HomePage[0] = 0; Sett->HomePage[1] = 0; Sett->User[0] = 0; Sett->User[1] = 0; Sett->Password[0] = 0; Sett->Password[1] = 0; switch(msg.Buffer[3]) { case 0x3B: smprintf(s, "Chat settings received OK\n"); memcpy(Sett->Name,msg.Buffer+20,msg.Buffer[12]*2); Sett->Name[msg.Buffer[12]*2] = 0; Sett->Name[msg.Buffer[12]*2+1] = 0; memcpy(Sett->HomePage,msg.Buffer+20+msg.Buffer[12]*2,msg.Buffer[15]*2); Sett->HomePage[msg.Buffer[15]*2] = 0; Sett->HomePage[msg.Buffer[15]*2+1] = 0; i = msg.Buffer[12]*2 + msg.Buffer[15]*2 + 29; memcpy(Sett->User,msg.Buffer+i+3,msg.Buffer[i]*2); Sett->User[msg.Buffer[i]*2] = 0; Sett->User[msg.Buffer[i]*2+1] = 0; memcpy(Sett->Password,msg.Buffer+i+3+msg.Buffer[i]*2,msg.Buffer[i+1]*2); Sett->Password[msg.Buffer[i+1]*2] = 0; Sett->Password[msg.Buffer[i+1]*2+1] = 0; return ERR_NONE; case 0x3C: smprintf(s, "Empty chat settings received\n"); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetChatSettings(GSM_StateMachine *s, GSM_ChatSettings *settings) { GSM_Error error; unsigned char req[] = {N6110_FRAME_HEADER, 0x3a, 0x09, // location 0x01, 0x0e}; settings->Connection.Location = settings->Location; error = N6510_GetConnectionSettings(s, &settings->Connection, N6510_CHAT_SETTINGS); if (error != ERR_NONE) return error; settings->Active = settings->Connection.Active; s->Phone.Data.ChatSettings = settings; req[4] = settings->Location - 1; smprintf(s, "Getting additional Chat settings\n"); return GSM_WaitFor (s, req, 7, 0x3f, 4, ID_GetChatSettings); } static GSM_Error N6510_ReplySetConnectionSettings(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x19: smprintf(s, "Connection settings cleaned\n"); return ERR_NONE; case 0x1a: smprintf(s, "Connection settings setting status\n"); switch (msg.Buffer[4]) { case 0x01: smprintf(s, "Security error. Inside phone settings menu\n"); return ERR_INSIDEPHONEMENU; case 0x03: smprintf(s, "Invalid location\n"); return ERR_INVALIDLOCATION; case 0x05: smprintf(s, "Written OK\n"); return ERR_NONE; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } case 0x28: case 0x2B: smprintf(s, "Set OK\n"); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_SetConnectionSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings, N6510_Connection_Settings Type) { GSM_Error error; int i, pad = 0, length, pos = 5, loc1=-1,loc2=-1,port; unsigned char *Proxy; unsigned char req[2000] = {N6110_FRAME_HEADER, 0x18, 0x00}; /* Location */ unsigned char Lock[5] = {N6110_FRAME_HEADER, 0x27, 0x00}; /* Location */ unsigned char UnLock[5] = {N6110_FRAME_HEADER, 0x2A, 0x00}; /* Location */ error = N6510_EnableConnectionFunctions(s, Type); if (error!=ERR_NONE) return error; memset(req + pos, 0, 1000 - pos); req[4] = settings->Location-1; for (i=0;i<settings->Number;i++) { if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_DATA) loc1=i; if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_GPRS) loc2=i; } if (loc1 != -1) { /* Name */ length = UnicodeLength(settings->Settings[loc1].Title); if (!(length % 2)) pad = 1; pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].Title, false); /* Home */ length = UnicodeLength(settings->Settings[loc1].HomePage); if (((length + pad) % 2)) pad = 2; else pad = 0; pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].HomePage, true); if (settings->Settings[loc1].IsContinuous) req[pos] = 0x01; pos++; if (settings->Settings[loc1].IsSecurity) req[pos] = 0x01; pos++; } else if (loc2 != -1) { /* Name */ length = UnicodeLength(settings->Settings[loc2].Title); if (!(length % 2)) pad = 1; pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].Title, false); /* Home */ length = UnicodeLength(settings->Settings[loc2].HomePage); if (((length + pad) % 2)) pad = 2; else pad = 0; pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].HomePage, true); if (settings->Settings[loc2].IsContinuous) req[pos] = 0x01; pos++; if (settings->Settings[loc2].IsSecurity) req[pos] = 0x01; pos++; } else { /* Name */ length = 0; if (!(length % 2)) pad = 1; pos ++; /* Home */ length = 0; if (((length + pad) % 2)) pad = 2; else pad = 0; pos += 2; pos += 2; } if (Type == N6510_MMS_SETTINGS || Type == N6510_CHAT_SETTINGS) { req[pos++] = 0x03; //active bearer: GPRS } else { if (settings->ActiveBearer == WAPSETTINGS_BEARER_GPRS && loc2 != -1) { req[pos++] = 0x03; //active bearer: GPRS } else { req[pos++] = 0x01; //active bearer: data set } } /* Number of sent bearers */ if (Type == N6510_MMS_SETTINGS || Type == N6510_CHAT_SETTINGS) { req[pos] = 0x01; } else { req[pos] = 0x02; } if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) req[pos] += 2; pos++; pos += pad; if (Type != N6510_MMS_SETTINGS && Type != N6510_CHAT_SETTINGS) { /* GSM data block */ memcpy(req + pos, "\x01\x00", 2); pos += 2; if (loc1 != -1) { length = UnicodeLength(settings->Settings[loc1].IPAddress)*2+1; length += UnicodeLength(settings->Settings[loc1].DialUp) *2+2; length += UnicodeLength(settings->Settings[loc1].User) *2+2; length += UnicodeLength(settings->Settings[loc1].Password) *2+2; } else { length = 1 + 2 + 2 + 2; } length += 11; req[pos++] = length / 256; req[pos++] = length % 256; if (loc1 != -1) { if (!settings->Settings[loc1].IsNormalAuthentication) req[pos]=0x01; pos++; if (settings->Settings[loc1].IsISDNCall) req[pos]=0x01; pos++; switch (settings->Settings[loc1].Speed) { case WAPSETTINGS_SPEED_AUTO : break; case WAPSETTINGS_SPEED_9600 : req[pos]=0x01; break; case WAPSETTINGS_SPEED_14400 : req[pos]=0x02; break; } pos++; req[pos++]=0x01; if (!settings->Settings[loc1].ManualLogin) req[pos] = 0x01; pos++; pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].IPAddress, false); pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].DialUp, true); pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].User, true); pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].Password, true); } else { pos += 3; req[pos++]=0x01; pos += 8; } /* Padding */ pos+=2; } /* GPRS block */ memcpy(req + pos, "\x03\x00", 2); pos += 2; if (loc2 != -1) { length = UnicodeLength(settings->Settings[loc2].DialUp) *2+1; length += UnicodeLength(settings->Settings[loc2].IPAddress)*2+2; length += UnicodeLength(settings->Settings[loc2].User) *2+2; length += UnicodeLength(settings->Settings[loc2].Password) *2+2; } else { length = 7; } if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) length+=2; length += 7; req[pos++] = length / 256; req[pos++] = length % 256; if (loc2 != -1) { if (!settings->Settings[loc2].IsNormalAuthentication) req[pos] = 0x01; pos++; if (!settings->Settings[loc2].IsContinuous) req[pos] = 0x01; pos++; if (!settings->Settings[loc2].ManualLogin) req[pos] = 0x01; pos++; pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].DialUp, false); pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].IPAddress, true); pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].User, true); pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].Password, true); } else { pos += 10; } if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) { req[pos++] = 0x00; req[pos++] = 0x00; /* Proxy block */ req[pos++] = 0x06; req[pos++] = 0x01; if (UnicodeLength(settings->Proxy)!=0 || UnicodeLength(settings->Proxy2)!=0) { req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+13)/256; req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+13)%256; } else { req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+12)/256; req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+12)%256; } req[pos++] = UnicodeLength(settings->Proxy); req[pos++] = UnicodeLength(settings->Proxy2); req[pos++] = settings->ProxyPort/256; req[pos++] = settings->ProxyPort%256; req[pos++] = settings->Proxy2Port/256; req[pos++] = settings->Proxy2Port%256; if (UnicodeLength(settings->Proxy)!=0) { sprintf(req+pos,"%s",DecodeUnicodeString(settings->Proxy)); pos+=UnicodeLength(settings->Proxy); } if (UnicodeLength(settings->Proxy2)!=0) { sprintf(req+pos,"%s",DecodeUnicodeString(settings->Proxy2)); pos+=UnicodeLength(settings->Proxy2); } if (UnicodeLength(settings->Proxy)!=0 || UnicodeLength(settings->Proxy2)!=0) { req[pos++] = 0x00; } req[pos++] = 0x00; req[pos++] = 0x00; req[pos++] = 0x07; //unknown req[pos++] = 0x00; req[pos++] = 0x00; req[pos++] = 0x80; //unknown req[pos++] = 0x01; //unknown req[pos++] = 0x05; //unknown req[pos++] = 0x00; req[pos++] = 0x00; /* Proxy data blocks */ for (i=0;i<4;i++) { port = 8080; Proxy = NULL; if (i==0) { port = settings->ProxyPort; Proxy = settings->Proxy; } else if (i==1) { port = settings->Proxy2Port; Proxy = settings->Proxy2; } req[pos++] = 0x08; req[pos++] = 0x00; if (Proxy != NULL && UnicodeLength(Proxy)!=0) { if (UnicodeLength(Proxy)%2 != 0) { req[pos++] = (12 + (UnicodeLength(Proxy)+1)*2)/256; req[pos++] = (12 + (UnicodeLength(Proxy)+1)*2)%256; } else { req[pos++] = (12 + UnicodeLength(Proxy)*2)/256; req[pos++] = (12 + UnicodeLength(Proxy)*2)%256; } } else { req[pos++] = 12/256; req[pos++] = 12%256; } req[pos++] = i+1; if (Proxy != NULL) { req[pos++] = UnicodeLength(Proxy); } else { req[pos++] = 0; } req[pos++] = port/256; req[pos++] = port%256; req[pos++] = 0x00; req[pos++] = 0x00; req[pos++] = 0x01; req[pos++] = 0x00; if (Proxy != NULL && UnicodeLength(Proxy)!=0) { CopyUnicodeString(req+pos,Proxy); pos+=UnicodeLength(Proxy)*2; if (UnicodeLength(Proxy)%2 != 0) { req[pos++] = 0x00; req[pos++] = 0x00; } } } req[pos++] = 0x09; req[pos++] = 0x00; req[pos++] = 0x00; req[pos++] = 0x0C; req[pos++] = 0x02; req[pos++] = 0x00; req[pos++] = 0x00; req[pos++] = 0x02; req[pos++] = 0x00; req[pos++] = 0x00; req[pos++] = 0x00; req[pos++] = 0x00; } else { /* end of blocks ? */ memcpy(req + pos, "\x80\x00\x00\x0c", 4); pos += 4; } UnLock[4] = settings->Location-1; smprintf(s, "Making Connection settings read-write\n"); error = GSM_WaitFor (s, UnLock, 5, 0x3f, 4, ID_SetConnectSet); if (error != ERR_NONE) return error; switch (Type) { case N6510_MMS_SETTINGS: smprintf(s, "Setting MMS settings\n"); break; case N6510_CHAT_SETTINGS: smprintf(s, "Setting Chat settings\n"); break; case N6510_WAP_SETTINGS: smprintf(s, "Setting WAP settings\n"); break; case N6510_SYNCML_SETTINGS: smprintf(s, "Setting SyncML settings\n"); break; } error = GSM_WaitFor (s, req, pos, 0x3f, 4, ID_SetConnectSet); if (error != ERR_NONE) { if (error == ERR_INSIDEPHONEMENU || error == ERR_INVALIDLOCATION) { DCT3DCT4_DisableConnectionFunctions(s); } return error; } if (settings->ReadOnly) { Lock[4] = settings->Location-1; smprintf(s, "Making Connection settings readonly\n"); error = GSM_WaitFor (s, Lock, 5, 0x3f, 4, ID_SetConnectSet); if (error != ERR_NONE) return error; } error = DCT3DCT4_SetActiveConnectSet(s, settings); if (error != ERR_NONE) return error; return DCT3DCT4_DisableConnectionFunctions(s); } static GSM_Error N6510_SetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings) { return N6510_SetConnectionSettings(s, settings, N6510_WAP_SETTINGS); } static GSM_Error N6510_SetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings) { return N6510_SetConnectionSettings(s, settings, N6510_MMS_SETTINGS); } static GSM_Error N6510_ReplyGetOriginalIMEI(GSM_Protocol_Message msg, GSM_StateMachine *s) { if (msg.Buffer[7] == 0x00) { smprintf(s, "No SIM card\n"); return ERR_SECURITYERROR; } else { return NOKIA_ReplyGetPhoneString(msg, s); } } static GSM_Error N6510_GetOriginalIMEI(GSM_StateMachine *s, char *value) { return NOKIA_GetPhoneString(s,"\x00\x07\x02\x01\x00\x01",6,0x42,value,ID_GetOriginalIMEI,14); } static GSM_Error N6510_ReplyGetSMSStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x09: switch (msg.Buffer[4]) { case 0x00: smprintf(s, "Max. in phone memory : %i\n",msg.Buffer[10]*256+msg.Buffer[11]); smprintf(s, "Used in phone memory : %i\n",msg.Buffer[12]*256+msg.Buffer[13]); smprintf(s, "Unread in phone memory : %i\n",msg.Buffer[14]*256+msg.Buffer[15]); smprintf(s, "Max. in SIM : %i\n",msg.Buffer[22]*256+msg.Buffer[23]); smprintf(s, "Used in SIM : %i\n",msg.Buffer[24]*256+msg.Buffer[25]); smprintf(s, "Unread in SIM : %i\n",msg.Buffer[26]*256+msg.Buffer[27]); Data->SMSStatus->PhoneSize = msg.Buffer[10]*256+msg.Buffer[11]; Data->SMSStatus->PhoneUsed = msg.Buffer[12]*256+msg.Buffer[13]; Data->SMSStatus->PhoneUnRead = msg.Buffer[14]*256+msg.Buffer[15]; Data->SMSStatus->SIMSize = msg.Buffer[22]*256+msg.Buffer[23]; Data->SMSStatus->SIMUsed = msg.Buffer[24]*256+msg.Buffer[25]; Data->SMSStatus->SIMUnRead = msg.Buffer[26]*256+msg.Buffer[27]; return ERR_NONE; case 0x0f: smprintf(s, "No PIN\n"); return ERR_SECURITYERROR; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } case 0x1a: smprintf(s, "Wait a moment. Phone is during power on and busy now\n"); return ERR_SECURITYERROR; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status) { GSM_Error error; GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; unsigned char req[] = {N6110_FRAME_HEADER, 0x08, 0x00, 0x00}; s->Phone.Data.SMSStatus=status; smprintf(s, "Getting SMS status\n"); error = GSM_WaitFor (s, req, 6, 0x14, 2, ID_GetSMSStatus); if (error != ERR_NONE) return error; /* DCT4 family doesn't show in frame with SMS status info * about Templates. We get separately info about this SMS folder. */ error = N6510_GetSMSFolderStatus(s, 0x06); if (error != ERR_NONE) return error; status->TemplatesUsed = Priv->LastSMSFolder.Number; return error; } static GSM_Error N6510_ReplyDeleteSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x05: smprintf(s, "SMS deleted OK\n"); return ERR_NONE; case 0x06: switch (msg.Buffer[4]) { case 0x02: smprintf(s, "Invalid location\n"); return ERR_INVALIDLOCATION; default: smprintf(s, "Unknown error: %02x\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_DeleteSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms) { unsigned char folderid; int location; unsigned char req[] = {N6110_FRAME_HEADER, 0x04, 0x01, /* 0x01=SM, 0x02=ME */ 0x00, /* FolderID */ 0x00, 0x02, /* Location */ 0x0F, 0x55}; N6510_GetSMSLocation(s, sms, &folderid, &location); switch (folderid) { case 0x01: req[5] = 0x02; break; /* INBOX SIM */ case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */ default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */ } req[6]=location / 256; req[7]=location; smprintf(s, "Deleting sms\n"); return GSM_WaitFor (s, req, 10, 0x14, 4, ID_DeleteSMSMessage); } static GSM_Error N6510_ReplySendSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[8]) { case 0x00: smprintf(s, "SMS sent OK, TPMR for sent sms is %d\n",msg.Buffer[10]); if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,0,msg.Buffer[10]); return ERR_NONE; default: smprintf(s, "SMS not sent OK, error code probably %i\n",msg.Buffer[8]); if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,msg.Buffer[8],msg.Buffer[10]); return ERR_NONE; } } static GSM_Error N6510_SendSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms) { int length = 11; GSM_Error error; GSM_SMSMessageLayout Layout; unsigned char req [300] = { N6110_FRAME_HEADER, 0x02, 0x00, 0x00, 0x00, 0x55, 0x55}; if (sms->PDU == SMS_Deliver) sms->PDU = SMS_Submit; memset(req+9,0x00,sizeof(req) - 9); error=N6510_EncodeSMSFrame(s, sms, req + 9, &Layout, &length); if (error != ERR_NONE) return error; smprintf(s, "Sending sms\n"); return s->Protocol.Functions->WriteMessage(s, req, length + 9, 0x02); } static GSM_Error N6510_ReplyGetSecurityStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Security Code status received: "); switch (msg.Buffer[4]) { case 0x01 : smprintf(s, "waiting for Security Code.\n"); *Data->SecurityStatus = SEC_SecurityCode; break; case 0x07 : case 0x02 : smprintf(s, "waiting for PIN.\n"); *Data->SecurityStatus = SEC_Pin; break; case 0x03 : smprintf(s, "waiting for PUK.\n"); *Data->SecurityStatus = SEC_Puk; break; case 0x05 : smprintf(s, "PIN ok, SIM ok\n"); *Data->SecurityStatus = SEC_None; break; case 0x06 : smprintf(s, "No input status\n"); *Data->SecurityStatus = SEC_None; break; case 0x16 : smprintf(s, "No SIM card\n"); *Data->SecurityStatus = SEC_None; break; case 0x1A : smprintf(s, "SIM card rejected!\n"); *Data->SecurityStatus = SEC_None; break; default : smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } return ERR_NONE; } static GSM_Error N6510_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status) { unsigned char req[5] = {N6110_FRAME_HEADER, 0x11, 0x00}; s->Phone.Data.SecurityStatus=Status; smprintf(s, "Getting security code status\n"); return GSM_WaitFor (s, req, 5, 0x08, 2, ID_GetSecurityStatus); } static GSM_Error N6510_ReplyEnterSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x08: smprintf(s, "Security code OK\n"); return ERR_NONE; case 0x09: switch (msg.Buffer[4]) { case 0x06: smprintf(s, "Wrong PIN\n"); return ERR_SECURITYERROR; case 0x09: smprintf(s, "Wrong PUK\n"); return ERR_SECURITYERROR; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); } } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode Code) { int len = 0; unsigned char req[15] = {N6110_FRAME_HEADER, 0x07, 0x00}; /* Code type */ switch (Code.Type) { case SEC_Pin : req[4] = 0x02; break; case SEC_Puk : req[4] = 0x03; break;/* FIXME */ default : return ERR_NOTSUPPORTED; } len = strlen(Code.Code); memcpy(req+5,Code.Code,len); req[5+len]=0x00; smprintf(s, "Entering security code\n"); return GSM_WaitFor (s, req, 6+len, 0x08, 4, ID_EnterSecurityCode); } static GSM_Error N6510_ReplySaveSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char folder; GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x01: switch (msg.Buffer[4]) { case 0x00: smprintf(s, "Done OK\n"); smprintf(s, "Folder info: %i %i\n",msg.Buffer[5],msg.Buffer[8]); switch (msg.Buffer[8]) { case 0x02 : if (msg.Buffer[5] == 0x02) { folder = 0x03; /* INBOX ME */ } else { folder = 0x01; /* INBOX SIM */ } break; case 0x03 : if (msg.Buffer[5] == 0x02) { folder = 0x04; /* OUTBOX ME */ } else { folder = 0x02; /* OUTBOX SIM */ } break; default : folder = msg.Buffer[8] + 1; } N6510_SetSMSLocation(s, Data->SaveSMSMessage,folder,msg.Buffer[6]*256+msg.Buffer[7]); smprintf(s, "Saved in folder %i at location %i\n",folder, msg.Buffer[6]*256+msg.Buffer[7]); Data->SaveSMSMessage->Folder = folder; return ERR_NONE; case 0x02: printf("Incorrect location\n"); return ERR_INVALIDLOCATION; + case 0x03: + printf("Memory full (for example no empty space in SIM)\n"); + return ERR_FULL; case 0x05: printf("Incorrect folder\n"); return ERR_INVALIDLOCATION; default: smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]); return ERR_UNKNOWNRESPONSE; } case 0x17: smprintf(s, "SMS name changed\n"); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_PrivSetSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms) { int location, length = 11; unsigned char folderid, folder; GSM_SMSMessageLayout Layout; GSM_Error error; unsigned char req [300] = { N6110_FRAME_HEADER, 0x00, 0x01, /* 1 = SIM, 2 = ME */ 0x02, /* Folder */ 0x00, 0x01, /* Location */ 0x01}; /* SMS state */ unsigned char NameReq[200] = { N6110_FRAME_HEADER, 0x16, 0x01, /* 1 = SIM, 2 = ME */ 0x02, /* Folder */ 0x00, 0x01}; /* Location */ N6510_GetSMSLocation(s, sms, &folderid, &location); switch (folderid) { case 0x01: req[5] = 0x02; break; /* INBOX SIM */ case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */ default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */ } req[6]=location / 256; req[7]=location; switch (sms->PDU) { case SMS_Submit: /* Inbox */ if (folderid == 0x01 || folderid == 0x03) sms->PDU = SMS_Deliver; break; case SMS_Deliver: /* SIM Outbox */ if (folderid == 0x02) sms->PDU = SMS_Submit; break; default: return ERR_UNKNOWN; } if (sms->PDU == SMS_Deliver) { switch (sms->State) { case SMS_Sent : /* We use GSM_Read, because phone return error */ case SMS_Read : req[8] = 0x01; break; case SMS_UnSent : /* We use GSM_UnRead, because phone return error */ case SMS_UnRead : req[8] = 0x03; break; } } else { switch (sms->State) { case SMS_Sent : /* We use GSM_Sent, because phone change folder */ case SMS_Read : req[8] = 0x05; break; case SMS_UnSent : /* We use GSM_UnSent, because phone change folder */ case SMS_UnRead : req[8] = 0x07; break; } } memset(req+9,0x00,sizeof(req) - 9); error=N6510_EncodeSMSFrame(s, sms, req + 9, &Layout, &length); if (error != ERR_NONE) return error; s->Phone.Data.SaveSMSMessage=sms; smprintf(s, "Saving sms\n"); error=GSM_WaitFor (s, req, length+9, 0x14, 4, ID_SaveSMSMessage); if (error == ERR_NONE && UnicodeLength(sms->Name)!=0) { folder = sms->Folder; sms->Folder = 0; N6510_GetSMSLocation(s, sms, &folderid, &location); switch (folderid) { case 0x01: NameReq[5] = 0x02; break; /* INBOX SIM */ case 0x02: NameReq[5] = 0x03; break; /* OUTBOX SIM */ default : NameReq[5] = folderid - 1; NameReq[4] = 0x02; break; /* ME folders */ } NameReq[6]=location / 256; NameReq[7]=location; length = 8; CopyUnicodeString(NameReq+length, sms->Name); length = length+UnicodeLength(sms->Name)*2; NameReq[length++] = 0; NameReq[length++] = 0; error=GSM_WaitFor (s, NameReq, length, 0x14, 4, ID_SaveSMSMessage); sms->Folder = folder; } return error; } static GSM_Error N6510_SetSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { int location; unsigned char folderid; N6510_GetSMSLocation(s, sms, &folderid, &location); if (location == 0) return ERR_INVALIDLOCATION; return N6510_PrivSetSMSMessage(s, sms); } static GSM_Error N6510_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) { int location; unsigned char folderid; N6510_GetSMSLocation(s, sms, &folderid, &location); location = 0; N6510_SetSMSLocation(s, sms, folderid, location); return N6510_PrivSetSMSMessage(s, sms); } static GSM_Error N6510_ReplyGetDateTime(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Date & time received\n"); if (msg.Buffer[4]==0x01) { NOKIA_DecodeDateTime(s, msg.Buffer+10, s->Phone.Data.DateTime); return ERR_NONE; } smprintf(s, "Not set in phone\n"); return ERR_EMPTY; } static GSM_Error N6510_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x00, 0x00}; s->Phone.Data.DateTime=date_time; smprintf(s, "Getting date & time\n"); return GSM_WaitFor (s, req, 6, 0x19, 4, ID_GetDateTime); } static GSM_Error N6510_ReplySetDateTime(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Date & time set\n"); return ERR_NONE; } static GSM_Error N6510_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time) { unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x01, 0x01, 0x0c, 0x01, 0x03, 0x00, 0x00, /* Year */ 0x08, 0x01, /* Month & Day */ 0x15, 0x1f, /* Hours & Minutes */ 0x2b, /* Second ? */ 0x00}; NOKIA_EncodeDateTime(s, req+10, date_time); req[16] = date_time->Second; smprintf(s, "Setting date & time\n"); return GSM_WaitFor (s, req, 18, 0x19, 4, ID_SetDateTime); } static GSM_Error N6510_ReplyGetManufactureMonth(GSM_Protocol_Message msg, GSM_StateMachine *s) { if (msg.Buffer[7] == 0x00) { smprintf(s, "No SIM card\n"); return ERR_SECURITYERROR; } else { sprintf(s->Phone.Data.PhoneString,"%02i/%04i",msg.Buffer[13],msg.Buffer[14]*256+msg.Buffer[15]); return ERR_NONE; } } static GSM_Error N6510_GetManufactureMonth(GSM_StateMachine *s, char *value) { unsigned char req[6] = {0x00, 0x05, 0x02, 0x01, 0x00, 0x02}; // unsigned char req[6] = {0x00, 0x03, 0x04, 0x0B, 0x01, 0x00}; s->Phone.Data.PhoneString=value; smprintf(s, "Getting manufacture month\n"); return GSM_WaitFor (s, req, 6, 0x42, 2, ID_GetManufactureMonth); // return GSM_WaitFor (s, req, 6, 0x1B, 2, ID_GetManufactureMonth); } static GSM_Error N6510_ReplyGetAlarm(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; switch(msg.Buffer[3]) { case 0x1A: smprintf(s, " Alarm: %02d:%02d\n", msg.Buffer[14], msg.Buffer[15]); Data->Alarm->Repeating = true; Data->Alarm->Text[0] = 0; Data->Alarm->Text[1] = 0; Data->Alarm->DateTime.Hour = msg.Buffer[14]; Data->Alarm->DateTime.Minute = msg.Buffer[15]; Data->Alarm->DateTime.Second = 0; return ERR_NONE; case 0x20: smprintf(s, "Alarm state received\n"); if (msg.Buffer[37] == 0x01) { smprintf(s, " Not set in phone\n"); return ERR_EMPTY; } smprintf(s, "Enabled\n"); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) { unsigned char StateReq[] = {N6110_FRAME_HEADER, 0x1f, 0x01, 0x00}; unsigned char GetReq [] = {N6110_FRAME_HEADER, 0x19, 0x00, 0x02}; GSM_Error error; if (alarm->Location != 1) return ERR_NOTSUPPORTED; s->Phone.Data.Alarm=alarm; smprintf(s, "Getting alarm state\n"); error = GSM_WaitFor (s, StateReq, 6, 0x19, 4, ID_GetAlarm); if (error != ERR_NONE) return error; smprintf(s, "Getting alarm\n"); return GSM_WaitFor (s, GetReq, 6, 0x19, 4, ID_GetAlarm); } static GSM_Error N6510_ReplySetAlarm(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Alarm set\n"); return ERR_NONE; } static GSM_Error N6510_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) { unsigned char req[] = {N6110_FRAME_HEADER, 0x11, 0x00, 0x01, 0x01, 0x0c, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Hours, Minutes */ 0x00, 0x00, 0x00 }; if (alarm->Location != 1) return ERR_NOTSUPPORTED; req[14] = alarm->DateTime.Hour; req[15] = alarm->DateTime.Minute; smprintf(s, "Setting alarm\n"); return GSM_WaitFor (s, req, 19, 0x19, 4, ID_SetAlarm); } static GSM_Error N6510_ReplyGetRingtonesInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int tmp,i; GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Ringtones info received\n"); memset(Data->RingtonesInfo,0,sizeof(GSM_AllRingtonesInfo)); if (msg.Buffer[4] * 256 + msg.Buffer[5] == 0x00) return ERR_EMPTY; Data->RingtonesInfo->Number = msg.Buffer[4] * 256 + msg.Buffer[5]; + // allocate array of ringtones based on number + Data->RingtonesInfo->Ringtone = calloc(Data->RingtonesInfo->Number, sizeof(GSM_RingtoneInfo)); tmp = 6; for (i=0;i<Data->RingtonesInfo->Number;i++) { Data->RingtonesInfo->Ringtone[i].Group = msg.Buffer[tmp+4]; Data->RingtonesInfo->Ringtone[i].ID = msg.Buffer[tmp+2] * 256 + msg.Buffer[tmp+3]; memcpy(Data->RingtonesInfo->Ringtone[i].Name,msg.Buffer+tmp+8,(msg.Buffer[tmp+6]*256+msg.Buffer[tmp+7])*2); smprintf(s, "%5i (%5i). \"%s\"\n", Data->RingtonesInfo->Ringtone[i].ID, Data->RingtonesInfo->Ringtone[i].Group, DecodeUnicodeString(Data->RingtonesInfo->Ringtone[i].Name)); tmp = tmp + (msg.Buffer[tmp]*256+msg.Buffer[tmp+1]); } return ERR_NONE; } static GSM_Error N6510_PrivGetRingtonesInfo(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info, bool AllRingtones) { GSM_Error error; unsigned char UserReq[8] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0x02}; // unsigned char All_Req[9] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x7D}; unsigned char All_Req[8] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0x00}; s->Phone.Data.RingtonesInfo=Info; smprintf(s, "Getting binary ringtones ID\n"); if (AllRingtones) { // error = GSM_WaitFor (s, All_Req, 9, 0x1f, 4, ID_GetRingtonesInfo); error = GSM_WaitFor (s, All_Req, 8, 0x1f, 4, ID_GetRingtonesInfo); if (error == ERR_EMPTY && Info->Number == 0) return ERR_NOTSUPPORTED; return error; } else { error = GSM_WaitFor (s, UserReq, 8, 0x1f, 4, ID_GetRingtonesInfo); if (error == ERR_EMPTY && Info->Number == 0) return ERR_NOTSUPPORTED; return error; } } static GSM_Error N6510_GetRingtonesInfo(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info) { return N6510_PrivGetRingtonesInfo(s, Info, true); } static GSM_Error N6510_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) { int tmp,i; GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Ringtone received\n"); memcpy(Data->Ringtone->Name,msg.Buffer+8,msg.Buffer[7]*2); Data->Ringtone->Name[msg.Buffer[7]*2]=0; Data->Ringtone->Name[msg.Buffer[7]*2+1]=0; smprintf(s, "Name \"%s\"\n",DecodeUnicodeString(Data->Ringtone->Name)); if (msg.Buffer[msg.Buffer[7]*2+10] == 'M' && msg.Buffer[msg.Buffer[7]*2+11] == 'T' && msg.Buffer[msg.Buffer[7]*2+12] == 'h' && msg.Buffer[msg.Buffer[7]*2+13] == 'd') { smprintf(s,"MIDI\n"); tmp = msg.Buffer[7]*2+10; i = msg.Length - 2; /* ?????? */ Data->Ringtone->Format = RING_MIDI; } else { /* Looking for end */ i=8+msg.Buffer[7]*2+3; tmp = i; while (true) { if (msg.Buffer[i]==0x07 && msg.Buffer[i+1]==0x0b) { i=i+2; break; } i++; if (i==msg.Length) return ERR_EMPTY; } } /* Copying frame */ memcpy(Data->Ringtone->NokiaBinary.Frame,msg.Buffer+tmp,i-tmp); Data->Ringtone->NokiaBinary.Length=i-tmp; return ERR_NONE; } static GSM_Error N6510_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) { - GSM_AllRingtonesInfo Info; + GSM_AllRingtonesInfo Info = {0, NULL}; GSM_Error error; unsigned char req2[6] = {N7110_FRAME_HEADER, 0x12, 0x00, 0xe7}; /* Location */ if (Ringtone->Format == 0x00) Ringtone->Format = RING_NOKIABINARY; switch (Ringtone->Format) { case RING_NOTETONE: /* In the future get binary and convert */ return ERR_NOTSUPPORTED; case RING_NOKIABINARY: s->Phone.Data.Ringtone = Ringtone; Info.Number = 0; error=N6510_PrivGetRingtonesInfo(s, &Info, PhoneRingtone); if (error != ERR_NONE) return error; if (Ringtone->Location > Info.Number) return ERR_INVALIDLOCATION; req2[4] = Info.Ringtone[Ringtone->Location-1].ID / 256; req2[5] = Info.Ringtone[Ringtone->Location-1].ID % 256; smprintf(s, "Getting binary ringtone\n"); - return GSM_WaitFor (s, req2, 6, 0x1f, 4, ID_GetRingtone); + error = GSM_WaitFor (s, req2, 6, 0x1f, 4, ID_GetRingtone); + if (Info.Ringtone) free(Info.Ringtone); + return error; case RING_MIDI: case RING_MMF: return ERR_NOTSUPPORTED; } return ERR_NOTSUPPORTED; } static GSM_Error N6510_PlayTone(GSM_StateMachine *s, int Herz, unsigned char Volume, bool start) { GSM_Error error; unsigned char reqStart[] = { 0x00,0x06,0x01,0x00,0x07,0x00 }; unsigned char reqPlay[] = { 0x00,0x06,0x01,0x14,0x05,0x04, 0x00,0x00,0x00,0x03,0x03,0x08, 0x00,0x00,0x00,0x01,0x00,0x00, 0x03,0x08,0x01,0x00, 0x07,0xd0, /*Frequency */ 0x00,0x00,0x03,0x08,0x02,0x00,0x00, 0x05, /*Volume */ 0x00,0x00}; unsigned char reqOff[] = { 0x00,0x06,0x01,0x14,0x05,0x05, 0x00,0x00,0x00,0x01,0x03,0x08, 0x05,0x00,0x00,0x08,0x00,0x00}; // unsigned char reqOff2[] = { // 0x00,0x06,0x01,0x14,0x05,0x04, // 0x00,0x00,0x00,0x01,0x03,0x08, // 0x00,0x00,0x00,0x00,0x00,0x00}; if (start) { smprintf(s, "Enabling sound - part 1\n"); error=GSM_WaitFor (s, reqStart, 6, 0x0b, 4, ID_PlayTone); if (error!=ERR_NONE) return error; smprintf(s, "Enabling sound - part 2 (disabling sound command)\n"); error=GSM_WaitFor (s, reqOff, 18, 0x0b, 4, ID_PlayTone); if (error!=ERR_NONE) return error; } /* For Herz==255*255 we have silent */ if (Herz!=255*255) { reqPlay[23] = Herz%256; reqPlay[22] = Herz/256; reqPlay[31] = Volume; smprintf(s, "Playing sound\n"); return GSM_WaitFor (s, reqPlay, 34, 0x0b, 4, ID_PlayTone); } else { reqPlay[23] = 0; reqPlay[22] = 0; reqPlay[31] = 0; smprintf(s, "Playing silent sound\n"); return GSM_WaitFor (s, reqPlay, 34, 0x0b, 4, ID_PlayTone); // smprintf(s, "Disabling sound - part 1\n"); // error=GSM_WaitFor (s, reqOff, 18, 0x0b, 4, ID_PlayTone); // if (error!=ERR_NONE) return error; // smprintf(s, "Disabling sound - part 2\n"); // return GSM_WaitFor (s, reqOff2, 18, 0x0b, 4, ID_PlayTone); } } static GSM_Error N6510_ReplyGetPPM(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; int pos = 6,len; smprintf(s, "Received phone info\n"); while(pos < msg.Length) { if (msg.Buffer[pos] == 0x55 && msg.Buffer[pos+1] == 0x55) { while(1) { if (msg.Buffer[pos] != 0x55) break; pos++; } } len = pos; while(1) { if (msg.Buffer[len] == 0x00 && msg.Buffer[len+1] == 0x00) break; len++; } while(1) { if (msg.Buffer[len] != 0x00) break; len++; } len = len-pos; smprintf(s, "Block with ID %02x",msg.Buffer[pos]); #ifdef DEBUG if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, di.dl, msg.Buffer+pos, len); #endif switch (msg.Buffer[pos]) { case 0x49: smprintf(s, "hardware version\n"); break; case 0x58: pos += 3; while (msg.Buffer[pos] != 0x00) pos++; Data->PhoneString[0] = msg.Buffer[pos - 1]; Data->PhoneString[1] = 0x00; smprintf(s, "PPM %s\n",Data->PhoneString); return ERR_NONE; default: break; } pos += len; } return ERR_NOTSUPPORTED; } static GSM_Error N6510_GetPPM(GSM_StateMachine *s,char *value) { // unsigned char req[6] = {N6110_FRAME_HEADER, 0x07, 0x01, 0xff}; unsigned char req[6] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x00}; s->Phone.Data.PhoneString=value; smprintf(s, "Getting PPM\n"); return GSM_WaitFor (s, req, 6, 0x1b, 3, ID_GetPPM); } static GSM_Error N6510_GetSpeedDial(GSM_StateMachine *s, GSM_SpeedDial *SpeedDial) { GSM_MemoryEntry pbk; GSM_Error error; pbk.MemoryType = MEM7110_SP; pbk.Location = SpeedDial->Location; SpeedDial->MemoryLocation = 0; s->Phone.Data.SpeedDial = SpeedDial; smprintf(s, "Getting speed dial\n"); error=N6510_GetMemory(s,&pbk); switch (error) { case ERR_NOTSUPPORTED: smprintf(s, "No speed dials set in phone\n"); return ERR_EMPTY; case ERR_NONE: if (SpeedDial->MemoryLocation == 0) { smprintf(s, "Speed dial not assigned or error in firmware\n"); return ERR_EMPTY; } return ERR_NONE; default: return error; } } static GSM_Error N6510_ReplyGetProfile(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char *blockstart; int i,j; GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x02: blockstart = msg.Buffer + 7; for (i = 0; i < 11; i++) { smprintf(s, "Profile feature %02x ",blockstart[1]); #ifdef DEBUG if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, di.dl, blockstart, blockstart[0]); #endif switch (blockstart[1]) { case 0x03: smprintf(s, "Ringtone ID\n"); Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_RingtoneID; Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = blockstart[7]; if (blockstart[7] == 0x00) { Data->Profile->FeatureValue[Data->Profile->FeaturesNumber] = blockstart[10]; } Data->Profile->FeaturesNumber++; break; case 0x05: /* SMS tone */ j = Data->Profile->FeaturesNumber; NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,false); if (j == Data->Profile->FeaturesNumber) { Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_MessageTone; Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = PROFILE_MESSAGE_PERSONAL; Data->Profile->FeaturesNumber++; Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_MessageToneID; Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = blockstart[7]; Data->Profile->FeaturesNumber++; } break; case 0x08: /* Caller groups */ NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,true); break; case 0x0c : CopyUnicodeString(Data->Profile->Name,blockstart + 7); smprintf(s, "profile Name: \"%s\"\n", DecodeUnicodeString(Data->Profile->Name)); Data->Profile->DefaultName = false; break; default: NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,false); } blockstart = blockstart + blockstart[0]; } return ERR_NONE; case 0x06: Data->Profile->Active = false; if (Data->Profile->Location == msg.Buffer[5]) Data->Profile->Active = true; return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetProfile(GSM_StateMachine *s, GSM_Profile *Profile) { unsigned char req[150] = {N6110_FRAME_HEADER, 0x01, 0x01, 0x0C, 0x01}; unsigned char reqActive[] = {N6110_FRAME_HEADER, 0x05}; int i, length = 7; GSM_Error error; /* For now !!! */ if (!strcmp(s->Phone.Data.ModelInfo->model,"3510")) { if (s->Phone.Data.VerNum>3.37) return ERR_NOTSUPPORTED; } if (!strcmp(s->Phone.Data.ModelInfo->model,"6230")) { return ERR_NOTSUPPORTED; } if (!strcmp(s->Phone.Data.ModelInfo->model,"5140")) { return ERR_NOTSUPPORTED; } if (Profile->Location>5) return ERR_INVALIDLOCATION; for (i = 0; i < 0x0a; i++) { req[length++] = 0x04; req[length++] = Profile->Location; req[length++] = i; req[length++] = 0x01; } req[length++] = 0x04; req[length++] = Profile->Location; req[length++] = 0x0c; req[length++] = 0x01; req[length++] = 0x04; Profile->CarKitProfile = false; Profile->HeadSetProfile = false; Profile->FeaturesNumber = 0; s->Phone.Data.Profile=Profile; smprintf(s, "Getting profile\n"); error = GSM_WaitFor (s, req, length, 0x39, 4, ID_GetProfile); if (error != ERR_NONE) return error; smprintf(s, "Checking, which profile is active\n"); return GSM_WaitFor (s, reqActive, 4, 0x39, 4, ID_GetProfile); } static GSM_Error N6510_ReplySetProfile(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char *blockstart; int i; smprintf(s, "Response to profile writing received!\n"); blockstart = msg.Buffer + 6; for (i = 0; i < msg.Buffer[5]; i++) { switch (blockstart[2]) { case 0x00: smprintf(s, "keypad tone level"); break; case 0x02: smprintf(s, "call alert"); break; case 0x03: smprintf(s, "ringtone"); break; case 0x04: smprintf(s, "ringtone volume"); break; case 0x05: smprintf(s, "SMS tone"); break; case 0x06: smprintf(s, "vibration"); break; case 0x07: smprintf(s, "warning tone level"); break; case 0x08: smprintf(s, "caller groups"); break; case 0x09: smprintf(s, "automatic answer"); break; case 0x0c: smprintf(s, "name"); break; default: smprintf(s, "Unknown block type %02x", blockstart[2]); break; } if (msg.Buffer[4] == 0x00) { smprintf(s, ": set OK\n"); } else { smprintf(s, ": setting error %i\n", msg.Buffer[4]); } blockstart = blockstart + blockstart[1]; } return ERR_NONE; } static GSM_Error N6510_SetProfile(GSM_StateMachine *s, GSM_Profile *Profile) { int i, length = 7, blocks = 0; bool found; unsigned char ID,Value; unsigned char req[150] = {N6110_FRAME_HEADER, 0x03, 0x01, 0x06, /* Number of blocks */ 0x03}; if (Profile->Location>5) return ERR_INVALIDLOCATION; for (i=0;i<Profile->FeaturesNumber;i++) { found = false; switch (Profile->FeatureID[i]) { case Profile_RingtoneID: ID = 0x03; Value = Profile->FeatureValue[i]; found = true; break; default: found=NOKIA_FindPhoneFeatureValue( s, Profile71_65, Profile->FeatureID[i],Profile->FeatureValue[i], &ID,&Value); } if (found) { req[length] = 0x09; req[length + 1] = ID; req[length + 2] = Profile->Location; memcpy(req + length + 4, "\x00\x00\x01", 3); req[length + 8] = 0x03; req[length + 3] = req[length + 7] = Value; blocks++; length += 9; } } smprintf(s, "Setting profile\n"); return GSM_WaitFor (s, req, length, 0x39, 4, ID_SetProfile); } static GSM_Error N6510_ReplyIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_SMSMessage sms; #ifdef DEBUG smprintf(s, "SMS message received\n"); N6510_DecodeSMSFrame(s, &sms, msg.Buffer+10); #endif if (s->Phone.Data.EnableIncomingSMS && s->User.IncomingSMS!=NULL) { sms.State = SMS_UnRead; sms.InboxFolder = true; N6510_DecodeSMSFrame(s, &sms, msg.Buffer+10); s->User.IncomingSMS(s->CurrentConfig->Device,sms); } return ERR_NONE; } static GSM_Error N6510_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber) { unsigned int pos2 = 15; unsigned int pos = 4; unsigned char req2[100] = {N6110_FRAME_HEADER,0x01, 0x00,0x02,0x07,0x04, 0x01, // 1 - voice, 2 - data 0x00,0x03, 0x18, // length of rest + 1 0x00,0x00,0x00}; unsigned char req[100] = {N6110_FRAME_HEADER,0x01, 0x0c}; /* Number length */ GSM_Error error; /* USSD not supported */ if (number[0] == '*') return ERR_NOTSUPPORTED; if (number[0] == '#') return ERR_NOTSUPPORTED; req[pos++] = strlen(number); EncodeUnicode(req+pos,number,strlen(number)); pos += strlen(number)*2; req[pos++] = 0x05; /* call type: voice - 0x05, data - 0x01 */ req[pos++] = 0x01; req[pos++] = 0x05; req[pos++] = 0x00; req[pos++] = 0x02; req[pos++] = 0x00; req[pos++] = 0x00; switch (ShowNumber) { case GSM_CALL_HideNumber: req[pos++] = 0x02; break; case GSM_CALL_ShowNumber: req[pos++] = 0x03; break; case GSM_CALL_DefaultNumberPresence: req[pos++] = 0x01; break; } smprintf(s, "Making voice call\n"); error = GSM_WaitFor (s, req, pos, 0x01, 4, ID_DialVoice); if (error != ERR_NOTSUPPORTED) return error; if (ShowNumber != GSM_CALL_DefaultNumberPresence) return ERR_NOTSUPPORTED; req2[11] = strlen(number)*2+6; req2[pos2++] = strlen(number); EncodeUnicode(req2+pos2,number,strlen(number)); pos2 += strlen(number)*2; smprintf(s, "Making voice call\n"); error = GSM_WaitFor (s, req2, pos2, 0x01, 4, ID_DialVoice); if (error == ERR_NOTSUPPORTED) return ERR_NONE; return error; } /* method 3 */ static GSM_Error N6510_ReplyGetCalendarInfo3(GSM_Protocol_Message msg, GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last) { int i=0,j=0; while (Last->Location[j] != 0x00) j++; if (j >= GSM_MAXCALENDARTODONOTES) { smprintf(s, "Increase GSM_MAXCALENDARTODONOTES\n"); return ERR_UNKNOWN; } if (j == 0) { Last->Number=msg.Buffer[8]*256+msg.Buffer[9]; smprintf(s, "Number of Entries: %i\n",Last->Number); } smprintf(s, "Locations: "); while (14+(i*4) <= msg.Length) { Last->Location[j++]=msg.Buffer[12+i*4]*256+msg.Buffer[13+i*4]; smprintf(s, "%i ",Last->Location[j-1]); i++; } smprintf(s, "\nNumber of Entries in frame: %i\n",i); Last->Location[j] = 0; smprintf(s, "\n"); if (i == 1 && msg.Buffer[12+0*4]*256+msg.Buffer[13+0*4] == 0) return ERR_EMPTY; if (i == 0) return ERR_EMPTY; return ERR_NONE; } /* method 3 */ static GSM_Error N6510_GetCalendarInfo3(GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last, char Type) { GSM_Error error = ERR_UNKNOWN; int i; unsigned char req[] = {N6110_FRAME_HEADER, 0x9E, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, /* First location */ 0x00}; /* 0 = calendar, 1 = ToDo in 6610 style, 2 = Notes */ Last->Location[0] = 0x00; Last->Number = 0; req[10] = Type; if (Type == 0) { smprintf(s, "Getting locations for calendar method 3\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo); } else if (Type == 1) { smprintf(s, "Getting locations for ToDo method 2\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo); } else if (Type == 2) { smprintf(s, "Getting locations for Notes\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetNote); } if (error != ERR_NONE && error != ERR_EMPTY) return error; while (1) { i=0; while (Last->Location[i] != 0x00) i++; smprintf(s, "i = %i %i\n",i,Last->Number); if (i == Last->Number) break; if (i != Last->Number && error == ERR_EMPTY) { smprintf(s, "Phone doesn't support some notes with this method. Workaround\n"); Last->Number = i; break; } req[8] = Last->Location[i-1] / 256; req[9] = Last->Location[i-1] % 256; if (Type == 0) { smprintf(s, "Getting locations for calendar method 3\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo); } else if (Type == 1) { smprintf(s, "Getting locations for todo method 2\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo); } else if (Type == 2) { smprintf(s, "Getting locations for Notes\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetNote); } if (error != ERR_NONE && error != ERR_EMPTY) return error; } return ERR_NONE; } /* method 3 */ GSM_Error N6510_ReplyGetCalendar3(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_CalendarEntry *entry = s->Phone.Data.Cal; GSM_DateTime Date; unsigned long diff; int i; bool found = false; GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; smprintf(s, "Calendar note received method 3\n"); smprintf(s,"Note type %02i: ",msg.Buffer[27]); switch(msg.Buffer[27]) { case 0x00: smprintf(s,"Reminder\n"); entry->Type = GSM_CAL_REMINDER; break; case 0x01: smprintf(s,"Meeting\n"); entry->Type = GSM_CAL_MEETING; break; case 0x02: smprintf(s,"Call\n"); entry->Type = GSM_CAL_CALL; break; case 0x04: smprintf(s,"Birthday\n"); entry->Type = GSM_CAL_BIRTHDAY; break; case 0x08: smprintf(s,"Memo\n"); entry->Type = GSM_CAL_MEMO; break; default : smprintf(s,"unknown\n"); } smprintf(s,"StartTime: %04i-%02i-%02i %02i:%02i\n", msg.Buffer[28]*256+msg.Buffer[29], msg.Buffer[30],msg.Buffer[31],msg.Buffer[32], msg.Buffer[33]); Date.Year = msg.Buffer[28]*256+msg.Buffer[29]; if (entry->Type == GSM_CAL_BIRTHDAY) { Date.Year = entry->Entries[0].Date.Year; smprintf(s,"%i\n",Date.Year); } Date.Month = msg.Buffer[30]; Date.Day = msg.Buffer[31]; Date.Hour = msg.Buffer[32]; Date.Minute = msg.Buffer[33]; /* Garbage seen with 3510i 3.51 */ if (Date.Month == 0 && Date.Day == 0 && Date.Hour == 0 && Date.Minute == 0) return ERR_EMPTY; Date.Second = 0; entry->Entries[0].EntryType = CAL_START_DATETIME; memcpy(&entry->Entries[0].Date,&Date,sizeof(GSM_DateTime)); entry->EntriesNum++; if (entry->Type != GSM_CAL_BIRTHDAY) { smprintf(s,"EndTime: %04i-%02i-%02i %02i:%02i\n", msg.Buffer[34]*256+msg.Buffer[35], msg.Buffer[36],msg.Buffer[37],msg.Buffer[38], msg.Buffer[39]); Date.Year = msg.Buffer[34]*256+msg.Buffer[35]; Date.Month = msg.Buffer[36]; Date.Day = msg.Buffer[37]; Date.Hour = msg.Buffer[38]; Date.Minute = msg.Buffer[39]; Date.Second = 0; entry->Entries[1].EntryType = CAL_END_DATETIME; memcpy(&entry->Entries[1].Date,&Date,sizeof(GSM_DateTime)); entry->EntriesNum++; } smprintf(s, "Note icon: %02x\n",msg.Buffer[21]); for(i=0;i<Priv->CalendarIconsNum;i++) { if (Priv->CalendarIconsTypes[i] == entry->Type) { found = true; } } if (!found) { Priv->CalendarIconsTypes[Priv->CalendarIconsNum] = entry->Type; Priv->CalendarIcons [Priv->CalendarIconsNum] = msg.Buffer[21]; Priv->CalendarIconsNum++; } if (msg.Buffer[14] == 0xFF && msg.Buffer[15] == 0xFF && msg.Buffer[16] == 0xff && msg.Buffer[17] == 0xff) { smprintf(s, "No alarm\n"); } else { diff = ((unsigned int)msg.Buffer[14]) << 24; diff += ((unsigned int)msg.Buffer[15]) << 16; diff += ((unsigned int)msg.Buffer[16]) << 8; diff += msg.Buffer[17]; memcpy(&entry->Entries[entry->EntriesNum].Date,&entry->Entries[0].Date,sizeof(GSM_DateTime)); GetTimeDifference(diff, &entry->Entries[entry->EntriesNum].Date, false, 60); smprintf(s, "Alarm date : %02i-%02i-%04i %02i:%02i:%02i\n", entry->Entries[entry->EntriesNum].Date.Day, entry->Entries[entry->EntriesNum].Date.Month, entry->Entries[entry->EntriesNum].Date.Year, entry->Entries[entry->EntriesNum].Date.Hour, entry->Entries[entry->EntriesNum].Date.Minute,entry->Entries[entry->EntriesNum].Date.Second); entry->Entries[entry->EntriesNum].EntryType = CAL_ALARM_DATETIME; if (msg.Buffer[22]==0x00 && msg.Buffer[23]==0x00 && msg.Buffer[24]==0x00 && msg.Buffer[25]==0x00) { entry->Entries[entry->EntriesNum].EntryType = CAL_SILENT_ALARM_DATETIME; smprintf(s, "Alarm type : Silent\n"); } entry->EntriesNum++; } N71_65_GetCalendarRecurrance(s, msg.Buffer+40, entry); if (entry->Type == GSM_CAL_BIRTHDAY) { if (msg.Buffer[42] == 0xff && msg.Buffer[43] == 0xff) { entry->Entries[0].Date.Year = 0; } else { entry->Entries[0].Date.Year = msg.Buffer[42]*256+msg.Buffer[43]; } } memcpy(entry->Entries[entry->EntriesNum].Text, msg.Buffer+54, msg.Buffer[51]*2); entry->Entries[entry->EntriesNum].Text[msg.Buffer[51]*2] = 0; entry->Entries[entry->EntriesNum].Text[msg.Buffer[51]*2+1] = 0; entry->Entries[entry->EntriesNum].EntryType = CAL_TEXT; entry->EntriesNum++; smprintf(s, "Note text: \"%s\"\n",DecodeUnicodeString(entry->Entries[entry->EntriesNum-1].Text)); if (entry->Type == GSM_CAL_CALL) { memcpy(entry->Entries[entry->EntriesNum].Text, msg.Buffer+(54+msg.Buffer[51]*2), msg.Buffer[52]*2); entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2] = 0; entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2+1] = 0; entry->Entries[entry->EntriesNum].EntryType = CAL_PHONE; entry->EntriesNum++; } if (entry->Type == GSM_CAL_MEETING) { memcpy(entry->Entries[entry->EntriesNum].Text, msg.Buffer+(54+msg.Buffer[51]*2), msg.Buffer[52]*2); entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2] = 0; entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2+1] = 0; entry->Entries[entry->EntriesNum].EntryType = CAL_LOCATION; entry->EntriesNum++; } return ERR_NONE; } static GSM_Error N6510_PrivGetGenericCalendar3(GSM_StateMachine *s, int Location, GSM_Phone_RequestID ID) { unsigned char req[] = {N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00, 0x00,0x99, /* Location */ 0xff,0xff,0xff,0xff}; req[8] = Location / 256; req[9] = Location % 256; return GSM_WaitFor (s, req, 14, 0x13, 4, ID); } static GSM_Error N6510_PrivGetCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start, int *LastCalendarYear) { GSM_Error error; GSM_DateTime date_time; if (start) { /* We have to get current year. It's NOT written in frame for * Birthday */ error=s->Phone.Functions->GetDateTime(s,&date_time); switch (error) { case ERR_EMPTY: case ERR_NOTIMPLEMENTED: GSM_GetCurrentDateTime(&date_time); break; case ERR_NONE: break; default: return error; } *LastCalendarYear = date_time.Year; } Note->EntriesNum = 0; Note->Entries[0].Date.Year = *LastCalendarYear; s->Phone.Data.Cal=Note; smprintf(s, "Getting calendar note method 3\n"); return N6510_PrivGetGenericCalendar3(s, Note->Location, ID_GetCalendarNote); } /* method 3 */ GSM_Error N6510_GetNextCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start, GSM_NOKIACalToDoLocations *LastCalendar, int *LastCalendarYear, int *LastCalendarPos) { GSM_Error error; bool start2; if (start) { error=N6510_GetCalendarInfo3(s,LastCalendar,0); if (error!=ERR_NONE) return error; if (LastCalendar->Number == 0) return ERR_EMPTY; *LastCalendarPos = 0; } else { (*LastCalendarPos)++; } error = ERR_EMPTY; start2 = start; while (error == ERR_EMPTY) { if (*LastCalendarPos >= LastCalendar->Number) return ERR_EMPTY; Note->Location = LastCalendar->Location[*LastCalendarPos]; error=N6510_PrivGetCalendar3(s, Note, start2, LastCalendarYear); if (error == ERR_EMPTY) (*LastCalendarPos)++; start2 = false; } return error; } static GSM_Error N6510_ReplyGetCalendarInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x3B: /* Old method 1 for accessing calendar */ return N71_65_ReplyGetCalendarInfo1(msg, s, &s->Phone.Data.Priv.N6510.LastCalendar); case 0x9F: smprintf(s, "Info with calendar notes locations received method 3\n"); return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastCalendar); } return ERR_UNKNOWNRESPONSE; } /* method 3 */ GSM_Error N6510_ReplyGetCalendarNotePos3(GSM_Protocol_Message msg, GSM_StateMachine *s,int *FirstCalendarPos) { smprintf(s, "First calendar location: %i\n",msg.Buffer[8]*256+msg.Buffer[9]); *FirstCalendarPos = msg.Buffer[8]*256+msg.Buffer[9]; return ERR_NONE; } /* method 3 */ static GSM_Error N6510_GetCalendarNotePos3(GSM_StateMachine *s) { unsigned char req[] = {N6110_FRAME_HEADER, 0x95, 0x00}; smprintf(s, "Getting first free calendar note location\n"); return GSM_WaitFor (s, req, 5, 0x13, 4, ID_GetCalendarNotePos); } static GSM_Error N6510_ReplyGetCalendarNotePos(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x32: /* Old method 1 for accessing calendar */ return N71_65_ReplyGetCalendarNotePos1(msg, s,&s->Phone.Data.Priv.N6510.FirstCalendarPos); case 0x96: return N6510_ReplyGetCalendarNotePos3(msg, s,&s->Phone.Data.Priv.N6510.FirstCalendarPos); } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_FindCalendarIconID3(GSM_StateMachine *s, GSM_CalendarEntry *Entry, unsigned char *ID) { int i,j,LastCalendarYear; GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; GSM_CalendarEntry Note; GSM_NOKIACalToDoLocations LastCalendar1,LastCalendar2; GSM_Error error; bool found; for(i=0;i<Priv->CalendarIconsNum;i++) { if (Priv->CalendarIconsTypes[i] == Entry->Type) { *ID = Priv->CalendarIcons[i]; return ERR_NONE; } } smprintf(s, "Starting finding note ID\n"); error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,0); memcpy(&LastCalendar1,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations)); if (error != ERR_NONE) return error; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL35) || IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL65) || IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) { error=N71_65_AddCalendar2(s,Entry); } else { if (Entry->Type == GSM_CAL_MEETING) { error=N71_65_AddCalendar1(s, Entry, &s->Phone.Data.Priv.N6510.FirstCalendarPos); } else { error=N71_65_AddCalendar2(s,Entry); } } if (error != ERR_NONE) return error; error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,0); memcpy(&LastCalendar2,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations)); if (error != ERR_NONE) return error; smprintf(s,"Number of entries: %i %i\n",LastCalendar1.Number,LastCalendar2.Number); for(i=0;i<LastCalendar2.Number;i++) { found = true; for(j=0;j<LastCalendar1.Number;j++) { if (LastCalendar1.Location[j] == LastCalendar2.Location[i]) { found = false; break; } } if (found) { Note.Location = LastCalendar2.Location[i]; error=N6510_PrivGetCalendar3(s, &Note, true, &LastCalendarYear); if (error != ERR_NONE) return error; error=N71_65_DelCalendar(s, &Note); if (error != ERR_NONE) return error; smprintf(s, "Ending finding note ID\n"); for(j=0;j<Priv->CalendarIconsNum;j++) { if (Priv->CalendarIconsTypes[j] == Entry->Type) { *ID = Priv->CalendarIcons[j]; return ERR_NONE; } } return ERR_UNKNOWN; } } return ERR_UNKNOWN; } /* method 3 */ static GSM_Error N6510_ReplyAddCalendar3(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Calendar note added\n"); return ERR_NONE; } /* method 3 */ GSM_Error N6510_AddCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, int *FirstCalendarPos) { GSM_CalendarNoteType NoteType, OldNoteType; time_t t_time1,t_time2; long diff; GSM_Error error; GSM_DateTime DT,date_time; int Text, Time, Alarm, Phone, Recurrance, EndTime, Location, count=54; unsigned char req[5000] = { N6110_FRAME_HEADER, 0x65, 0x00, /* 0 = calendar, 1 = todo */ 0x00, 0x00, 0x00, 0x00, 0x00, /* location */ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, /* alarm */ 0x80, 0x00, 0x00, 0x01, /* note icon */ 0xFF, 0xFF, 0xFF, 0xFF, /* alarm type */ 0x00, /* 0x02 or 0x00 */ 0x01, /* note type */ 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* start date/time */ 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* end date/time */ 0x00, 0x00, /* recurrance */ 0x00, 0x00, /* birth year */ 0x20, /* ToDo priority */ 0x00, /* ToDo completed ? */ 0x00, 0x00, 0x00, 0x00, /* note text length */ 0x00, /* phone length/meeting place */ 0x00, 0x00, 0x00}; error=N6510_GetCalendarNotePos3(s); if (error!=ERR_NONE) return error; req[8] = *FirstCalendarPos/256; req[9] = *FirstCalendarPos%256; NoteType = N71_65_FindCalendarType(Note->Type, s->Phone.Data.ModelInfo); switch(NoteType) { case GSM_CAL_REMINDER : req[27]=0x00; req[26]=0x02; break; case GSM_CAL_MEETING : req[27]=0x01; break; case GSM_CAL_CALL : req[27]=0x02; break; case GSM_CAL_BIRTHDAY : req[27]=0x04; break; case GSM_CAL_MEMO : req[27]=0x08; break; default : return ERR_UNKNOWN; } OldNoteType = Note->Type; Note->Type = NoteType; error=N6510_FindCalendarIconID3(s, Note, &req[21]); Note->Type = OldNoteType; if (error!=ERR_NONE) return error; GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note, &Text, &Time, &Alarm, &Phone, &Recurrance, &EndTime, &Location); if (Time == -1) return ERR_UNKNOWN; memcpy(&DT,&Note->Entries[Time].Date,sizeof(GSM_DateTime)); req[28] = DT.Year / 256; req[29] = DT.Year % 256; req[30] = DT.Month; req[31] = DT.Day; req[32] = DT.Hour; req[33] = DT.Minute; if (NoteType == GSM_CAL_BIRTHDAY) { error=s->Phone.Functions->GetDateTime(s,&date_time); switch (error) { case ERR_EMPTY: case ERR_NOTIMPLEMENTED: GSM_GetCurrentDateTime(&date_time); break; case ERR_NONE: break; default: return error; } req[28] = date_time.Year / 256; req[29] = date_time.Year % 256; if (DT.Year == 0) { req[42] = 0xff; req[43] = 0xff; } else { req[42] = DT.Year / 256; req[43] = DT.Year % 256; } } if (EndTime != -1) memcpy(&DT,&Note->Entries[EndTime].Date,sizeof(GSM_DateTime)); req[34] = DT.Year / 256; req[35] = DT.Year % 256; req[36] = DT.Month; req[37] = DT.Day; req[38] = DT.Hour; req[39] = DT.Minute; if (NoteType == GSM_CAL_BIRTHDAY) { req[34] = date_time.Year / 256; req[35] = date_time.Year % 256; } if (Recurrance != -1) { /* max. 1 Year = 8760 hours */ if (Note->Entries[Recurrance].Number >= 8760) { req[40] = 0xff; req[41] = 0xff; } else { req[40] = Note->Entries[Recurrance].Number / 256; req[41] = Note->Entries[Recurrance].Number % 256; } } if (Alarm != -1) { memcpy(&DT,&Note->Entries[Time].Date,sizeof(GSM_DateTime)); if (Note->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME) { req[22] = 0x00; req[23] = 0x00; req[24] = 0x00; req[25] = 0x00; } if (NoteType == GSM_CAL_BIRTHDAY) DT.Year = date_time.Year; t_time2 = Fill_Time_T(DT,8); t_time1 = Fill_Time_T(Note->Entries[Alarm].Date,8); diff = (t_time1-t_time2)/60; smprintf(s, " Difference : %li seconds or minutes\n", -diff); req[14] = (unsigned char)(-diff >> 24); req[15] = (unsigned char)(-diff >> 16); req[16] = (unsigned char)(-diff >> 8); req[17] = (unsigned char)(-diff); } if (Text != -1) { req[49] = UnicodeLength(Note->Entries[Text].Text); CopyUnicodeString(req+54,Note->Entries[Text].Text); count+= req[49]*2; } if (Phone != -1 && NoteType == GSM_CAL_CALL) { req[50] = UnicodeLength(Note->Entries[Phone].Text); CopyUnicodeString(req+54+req[49]*2,Note->Entries[Phone].Text); count+= req[50]*2; } if (Location != -1 && NoteType == GSM_CAL_MEETING) { if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62) || IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL65) || IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL35)) { } else { req[50] = UnicodeLength(Note->Entries[Location].Text); CopyUnicodeString(req+54+req[49]*2,Note->Entries[Location].Text); count+= req[50]*2; } } req[count++] = 0x00; smprintf(s, "Writing calendar note method 3\n"); return GSM_WaitFor (s, req, count, 0x13, 4, ID_SetCalendarNote); } static GSM_Error N6510_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) { #ifdef GSM_FORCE_DCT4_CALENDAR_6210 /* Method 1. Some features missed. Not working with some notes in 3510 */ return N71_65_GetNextCalendar1(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendar,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos); #endif if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) { /* Method 1. Some features missed. Not working with some notes in 3510 */ return N71_65_GetNextCalendar1(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendar,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos); /* Method 2. In known phones texts of notes cut to 50 chars. Some features missed */ // return N71_65_GetNextCalendar2(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos); } else { /* Method 3. All DCT4 features supported. Not supported by 8910 */ return N6510_GetNextCalendar3(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendar,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos); } } static GSM_Error N6510_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status) { GSM_Error error; #ifdef GSM_FORCE_DCT4_CALENDAR_6210 /* Method 1 */ error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N6510.LastCalendar); if (error!=ERR_NONE) return error; Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number; return ERR_NONE; #endif if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) { /* Method 1 */ error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N6510.LastCalendar); if (error!=ERR_NONE) return error; Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number; return ERR_NONE; /* Method 2 */ // return ERR_NOTSUPPORTED; } else { /* Method 3 */ error=N6510_GetCalendarInfo3(s,&s->Phone.Data.Priv.N6510.LastCalendar,0); if (error!=ERR_NONE) return error; Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number; return ERR_NONE; } } static GSM_Error N6510_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { #ifdef GSM_FORCE_DCT4_CALENDAR_6210 return N71_65_AddCalendar2(s,Note); #endif if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) { return N71_65_AddCalendar2(s,Note); // return N71_65_AddCalendar1(s, Note, &s->Phone.Data.Priv.N6510.FirstCalendarPos); } else { /* Method 3. All DCT4 features supported. Not supported by 8910 */ return N6510_AddCalendar3(s, Note, &s->Phone.Data.Priv.N6510.FirstCalendarPos); } } static GSM_Error N6510_ReplyLogIntoNetwork(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Probably phone says: I log into network\n"); return ERR_NONE; } void N6510_EncodeFMFrequency(double freq, unsigned char *buff) { double freq0; unsigned char buffer[20]; unsigned int i,freq2; sprintf(buffer,"%.3f",freq); for (i=0;i<strlen(buffer);i++) { if (buffer[i] == ',' || buffer[i] == '.') buffer[i] = ' '; } StringToDouble(buffer, &freq0); freq2 = (unsigned int)freq0; dbgprintf("Frequency: %s %i\n",buffer,freq2); freq2 = freq2 - 0xffff; buff[0] = freq2 / 0x100; buff[1] = freq2 % 0x100; } void N6510_DecodeFMFrequency(double *freq, unsigned char *buff) { unsigned char buffer[20]; sprintf(buffer,"%i.%i",(0xffff + buff[0] * 0x100 + buff[1])/1000, (0xffff + buff[0] * 0x100 + buff[1])%1000); dbgprintf("Frequency: %s\n",buffer); StringToDouble(buffer, freq); } static GSM_Error N6510_ReplyGetFMStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "getting FM status OK\n"); memcpy(s->Phone.Data.Priv.N6510.FMStatus,msg.Buffer,msg.Length); s->Phone.Data.Priv.N6510.FMStatusLength = msg.Length; return ERR_NONE; } static GSM_Error N6510_GetFMStatus(GSM_StateMachine *s) { unsigned char req[7] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x01}; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED; return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_GetFMStation); } static GSM_Error N6510_ReplyGetFMStation(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char name[GSM_MAX_FMSTATION_LENGTH*2+2]; int length; GSM_Phone_Data *Data = &s->Phone.Data; switch (msg.Buffer[3]) { case 0x06: smprintf(s, "Received FM station\n"); length = msg.Buffer[8]; memcpy(name,msg.Buffer+18,length*2); name[length*2] = 0x00; name[length*2+1] = 0x00; CopyUnicodeString(Data->FMStation->StationName,name); smprintf(s,"Station name: \"%s\"\n",DecodeUnicodeString(Data->FMStation->StationName)); N6510_DecodeFMFrequency(&Data->FMStation->Frequency, msg.Buffer+16); return ERR_NONE; case 0x16: smprintf(s, "Received FM station. Empty ?\n"); return ERR_EMPTY; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetFMStation (GSM_StateMachine *s, GSM_FMStation *FMStation) { GSM_Error error; int location; unsigned char req[7] = {N6110_FRAME_HEADER, 0x05, 0x00, // location 0x00,0x01}; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED; if (FMStation->Location > GSM_MAX_FM_STATION) return ERR_INVALIDLOCATION; s->Phone.Data.FMStation = FMStation; error = N6510_GetFMStatus(s); if (error != ERR_NONE) return error; location = FMStation->Location-1; if (s->Phone.Data.Priv.N6510.FMStatus[14+location] == 0xFF) return ERR_EMPTY; req[4] = s->Phone.Data.Priv.N6510.FMStatus[14+location]; smprintf(s, "Getting FM Station %i\n",FMStation->Location); return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_GetFMStation); } static GSM_Error N6510_ReplySetFMStation(GSM_Protocol_Message msg, GSM_StateMachine *s) { #ifdef DEBUG switch (msg.Buffer[4]){ case 0x03: smprintf(s, "FM stations cleaned\n"); break; case 0x11: smprintf(s, "Setting FM station status OK\n"); break; case 0x12: smprintf(s, "Setting FM station OK\n"); break; } #endif return ERR_NONE; } static GSM_Error N6510_ClearFMStations (GSM_StateMachine *s) { unsigned char req[7] = {N6110_FRAME_HEADER, 0x03,0x0f,0x00,0x01}; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED; smprintf(s, "Cleaning FM Stations\n"); return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_SetFMStation); } static GSM_Error N6510_SetFMStation (GSM_StateMachine *s, GSM_FMStation *FMStation) { unsigned int len, location; GSM_Error error; unsigned char setstatus[36] = {N6110_FRAME_HEADER,0x11,0x00,0x01,0x01, 0x00,0x00,0x1c,0x00,0x14,0x00,0x00, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0x01}; unsigned char req[64] = {N6110_FRAME_HEADER, 0x12,0x00,0x01,0x00, 0x00, // 0x0e + (strlen(name) * 2) 0x00, // strlen(name) 0x14,0x09,0x00, 0x00, // location 0x00,0x00,0x01, 0x00, // freqHi 0x00, // freqLo 0x01}; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED; s->Phone.Data.FMStation = FMStation; location = FMStation->Location-1; error = N6510_GetFMStatus(s); if (error != ERR_NONE) return error; memcpy(setstatus+14,s->Phone.Data.Priv.N6510.FMStatus+14,20); setstatus [14+location] = location; smprintf(s, "Setting FM status %i\n",FMStation->Location); error = GSM_WaitFor (s, setstatus, 36 , 0x3E, 2, ID_SetFMStation); if (error != ERR_NONE) return error; req[12] = location; /* Name */ len = UnicodeLength(FMStation->StationName); req[8] = len; req[7] = 0x0e + len * 2; memcpy (req+18,FMStation->StationName,len*2); /* Frequency */ N6510_EncodeFMFrequency(FMStation->Frequency, req+16); smprintf(s, "Setting FM Station %i\n",FMStation->Location); return GSM_WaitFor (s, req, 0x13+len*2, 0x3E, 2, ID_SetFMStation); } static GSM_Error N6510_ReplySetLight(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Light set\n"); return ERR_NONE; } GSM_Error N6510_SetLight(GSM_StateMachine *s, N6510_PHONE_LIGHTS light, bool enable) { unsigned char req[14] = { N6110_FRAME_HEADER, 0x05, 0x01, /* 0x01 = Display, 0x03 = keypad */ 0x01, /* 0x01 = Enable, 0x02 = disable */ 0x00, 0x00, 0x00, 0x01, 0x05, 0x04, 0x02, 0x00}; req[4] = light; if (!enable) req[5] = 0x02; smprintf(s, "Setting light\n"); return GSM_WaitFor (s, req, 14, 0x3A, 4, ID_SetLight); } static GSM_Error N6510_ShowStartInfo(GSM_StateMachine *s, bool enable) { GSM_Error error; if (enable) { error=N6510_SetLight(s,N6510_LIGHT_DISPLAY,true); if (error != ERR_NONE) return error; error=N6510_SetLight(s,N6510_LIGHT_TORCH,true); if (error != ERR_NONE) return error; return N6510_SetLight(s,N6510_LIGHT_KEYPAD,true); } else { error=N6510_SetLight(s,N6510_LIGHT_DISPLAY,false); if (error != ERR_NONE) return error; error=N6510_SetLight(s,N6510_LIGHT_TORCH,false); if (error != ERR_NONE) return error; return N6510_SetLight(s,N6510_LIGHT_KEYPAD,false); } } static GSM_Error N6510_ReplyGetNoteInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastNote); } static GSM_Error N6510_ReplyGetNote(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Note received\n"); memcpy(s->Phone.Data.Note->Text,msg.Buffer+54,(msg.Buffer[50]*256+msg.Buffer[51])*2); s->Phone.Data.Note->Text[(msg.Buffer[50]*256+msg.Buffer[51])*2] = 0; s->Phone.Data.Note->Text[(msg.Buffer[50]*256+msg.Buffer[51])*2+1] = 0; return ERR_NONE; } GSM_Error N6510_GetNextNote(GSM_StateMachine *s, GSM_NoteEntry *Note, bool start) { GSM_Error error; GSM_NOKIACalToDoLocations *LastNote = &s->Phone.Data.Priv.N6510.LastNote; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOTES)) return ERR_NOTSUPPORTED; if (start) { error=N6510_GetCalendarInfo3(s,LastNote,2); if (error!=ERR_NONE) return error; Note->Location = 1; } else { Note->Location++; } if (Note->Location > LastNote->Number) return ERR_EMPTY; s->Phone.Data.Note = Note; smprintf(s, "Getting note\n"); return N6510_PrivGetGenericCalendar3(s, LastNote->Location[Note->Location-1], ID_GetNote); } +static GSM_Error N6510_DeleteNote(GSM_StateMachine *s, GSM_NoteEntry *Not) +{ + GSM_Error error; + GSM_NOKIACalToDoLocations *LastNote = &s->Phone.Data.Priv.N6510.LastNote; + GSM_CalendarEntry Note; + + if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOTES)) return ERR_NOTSUPPORTED; + + error=N6510_GetCalendarInfo3(s,LastNote,2); + if (error!=ERR_NONE) return error; + + smprintf(s, "Deleting Note\n"); + + if (Not->Location > LastNote->Number || Not->Location == 0) return ERR_INVALIDLOCATION; + + Note.Location = LastNote->Location[Not->Location-1]; + return N71_65_DelCalendar(s,&Note); +} + +static GSM_Error N6510_ReplyGetNoteFirstLoc(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + smprintf(s, "First Note location: %i\n",msg.Buffer[8]*256+msg.Buffer[9]); + s->Phone.Data.Note->Location = msg.Buffer[8]*256+msg.Buffer[9]; + return ERR_NONE; +} + +static GSM_Error N6510_ReplyAddNote(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + smprintf(s, "ToDo added\n"); + return ERR_NONE; +} + +static GSM_Error N6510_AddNote(GSM_StateMachine *s, GSM_NoteEntry *Not) +{ + GSM_Error error; + int count=54; + unsigned char reqLoc[] = {N6110_FRAME_HEADER, 0x95, + 0x02}; /* 1 = todo, 2 = note */ + unsigned char req[5000] = { + N6110_FRAME_HEADER, 0x65, + 0x02, /* 0 = calendar, 1 = todo, 2 = note */ + 0x00, 0x00, 0x00, + 0x00, 0x00, /* location */ + 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, /* alarm */ + 0x80, 0x00, 0x00, + 0xA9, /* note icon */ + 0x00, 0x00, 0x00, 0x00, /* alarm type */ + 0x00, /* 0x02 or 0x00 */ + 0x80, /* note type */ + 0x07, 0xD2, 0x01, 0x01, 0x00, 0x00, /* start date/time */ + 0x07, 0xD2, 0x01, 0x11, 0x00, 0x00, /* end date/time */ + 0x00, 0x00, /* recurrance */ + 0xFF, 0xFF, /* birth year */ + 0x00, /* ToDo priority */ + 0x00, /* ToDo completed ? */ + 0x00, 0x00, 0x00, + 0x00, /* note text length */ + 0x00, /* phone length/meeting place */ + 0x00, 0x00, 0x00}; + + s->Phone.Data.Note = Not; + + smprintf(s, "Getting first free Note location\n"); + error = GSM_WaitFor (s, reqLoc, 5, 0x13, 4, ID_SetNote); + if (error!=ERR_NONE) return error; + req[8] = Not->Location/256; + req[9] = Not->Location%256; + + req[49] = UnicodeLength(Not->Text); + CopyUnicodeString(req+54,Not->Text); + count+= req[49]*2; + + req[count++] = 0x00; + + smprintf(s, "Adding Note\n"); + return GSM_WaitFor (s, req, count, 0x13, 4, ID_SetNote); +} + +static GSM_Error N6510_GetNoteStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) +{ + GSM_NOKIACalToDoLocations *LastNote = &s->Phone.Data.Priv.N6510.LastNote; + GSM_Error error; + + error = N6510_GetCalendarInfo3(s,LastNote,2); + if (error!=ERR_NONE) return error; + + status->Used = LastNote->Number; + return ERR_NONE; +} + static int N6510_FindFileCheckSum(unsigned char *ptr, int len) { int acc, i, accx; accx = 0; acc = 0xffff; while (len--) { accx = (accx & 0xffff00ff) | (acc & 0xff00); acc = (acc & 0xffff00ff) | *ptr++ << 8; for (i = 0; i < 8; i++) { acc <<= 1; if (acc & 0x10000) acc ^= 0x1021; if (accx & 0x80000000) acc ^= 0x1021; accx <<= 1; } } dbgprintf("Checksum from Gammu is %04X\n",(acc & 0xffff)); return (acc & 0xffff); } static GSM_Error N6510_ReplyGetFileFolderInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_File *File = s->Phone.Data.FileInfo; GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; int i; switch (msg.Buffer[3]) { case 0x15: smprintf(s,"File or folder details received\n"); CopyUnicodeString(File->Name,msg.Buffer+10); if (!strncmp(DecodeUnicodeString(File->Name),"GMSTemp",7)) return ERR_EMPTY; if (File->Name[0] == 0x00 && File->Name[1] == 0x00) return ERR_UNKNOWN; i = msg.Buffer[8]*256+msg.Buffer[9]; dbgprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x\n", msg.Buffer[i-5],msg.Buffer[i-4],msg.Buffer[i-3], msg.Buffer[i-2],msg.Buffer[i-1],msg.Buffer[i], msg.Buffer[i+1],msg.Buffer[i+2],msg.Buffer[i+3]); File->Folder = false; if (msg.Buffer[i-5] == 0x00) File->Folder = true; File->ReadOnly = false; File->Protected = false; File->System = false; File->Hidden = false; if (msg.Buffer[i+2] == 0x01) File->Protected = true; if (msg.Buffer[i+4] == 0x01) File->ReadOnly = true; if (msg.Buffer[i+5] == 0x01) File->Hidden = true; if (msg.Buffer[i+6] == 0x01) File->System = true;//fixme File->ModifiedEmpty = false; NOKIA_DecodeDateTime(s, msg.Buffer+i-22, &File->Modified); if (File->Modified.Year == 0x00) File->ModifiedEmpty = true; dbgprintf("%02x %02x %02x %02x\n",msg.Buffer[i-22],msg.Buffer[i-21],msg.Buffer[i-20],msg.Buffer[i-19]); Priv->FileToken = msg.Buffer[i-10]*256+msg.Buffer[i-9]; Priv->ParentID = msg.Buffer[i]*256+msg.Buffer[i+1]; smprintf(s,"ParentID is %i\n",Priv->ParentID); File->Type = GSM_File_Other; if (msg.Length > 240){ i = 227; if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x01) File->Type = GSM_File_Image_JPG; else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x02) File->Type = GSM_File_Image_BMP; else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x07) File->Type = GSM_File_Image_BMP; else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x03) File->Type = GSM_File_Image_PNG; else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x05) File->Type = GSM_File_Image_GIF; else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x09) File->Type = GSM_File_Image_WBMP; else if (msg.Buffer[i]==0x04 && msg.Buffer[i+2]==0x01) File->Type = GSM_File_Sound_AMR; else if (msg.Buffer[i]==0x04 && msg.Buffer[i+2]==0x02) File->Type = GSM_File_Sound_MIDI; else if (msg.Buffer[i]==0x08 && msg.Buffer[i+2]==0x05) File->Type = GSM_File_Video_3GP; else if (msg.Buffer[i]==0x10 && msg.Buffer[i+2]==0x01) File->Type = GSM_File_Java_JAR; #ifdef DEVELOP else if (msg.Buffer[i]==0x00 && msg.Buffer[i+2]==0x01) File->Type = GSM_File_MMS; #endif } return ERR_NONE; case 0x2F: smprintf(s,"File or folder used bytes received\n"); File->Used = msg.Buffer[6]*256*256*256+ msg.Buffer[7]*256*256+ msg.Buffer[8]*256+ msg.Buffer[9]; return ERR_NONE; case 0x33: if (s->Phone.Data.RequestID == ID_GetFileInfo) { i = Priv->FilesLocationsUsed-1; while (1) { if (i==Priv->FilesLocationsCurrent-1) break; dbgprintf("Copying %i to %i, max %i, current %i\n", i,i+msg.Buffer[9], Priv->FilesLocationsUsed,Priv->FilesLocationsCurrent); Priv->FilesLocations[i+msg.Buffer[9]] = Priv->FilesLocations[i]; Priv->FilesLevels[i+msg.Buffer[9]] = Priv->FilesLevels[i]; i--; } Priv->FilesLocationsUsed += msg.Buffer[9]; for (i=0;i<msg.Buffer[9];i++) { Priv->FilesLocations[Priv->FilesLocationsCurrent+i] = msg.Buffer[13+i*4-1]*256 + msg.Buffer[13+i*4]; Priv->FilesLevels[Priv->FilesLocationsCurrent+i] = File->Level+1; dbgprintf("%i ",Priv->FilesLocations[Priv->FilesLocationsCurrent+i]); } dbgprintf("\n"); } if (msg.Buffer[9] != 0x00) File->Folder = true; return ERR_NONE; case 0x43: Priv->FileCheckSum = msg.Buffer[6] * 256 + msg.Buffer[7]; smprintf(s,"File checksum from phone is %04X\n",Priv->FileCheckSum); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetFileFolderInfo(GSM_StateMachine *s, GSM_File *File, GSM_Phone_RequestID Request) { GSM_Error error; unsigned char req[10] = { N7110_FRAME_HEADER, 0x14, /* 0x14 - info, 0x22 - free/total, 0x2E - used, 0x32 - sublocations */ 0x01, /* 0x00 for sublocations reverse sorting, 0x01 for free */ 0x00, 0x00, 0x01, 0x00, 0x01}; /* Folder or file number */ unsigned char GetCRC[] = { N7110_FRAME_HEADER, 0x42, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1E}; /* file ID */ if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED; s->Phone.Data.FileInfo = File; req[8] = atoi(File->ID_FullName) / 256; req[9] = atoi(File->ID_FullName) % 256; req[3] = 0x14; req[4] = 0x01; smprintf(s,"Getting info for file in filesystem\n"); error=GSM_WaitFor (s, req, 10, 0x6D, 4, Request); if (error != ERR_NONE) return error; if (Request != ID_AddFile) { req[3] = 0x32; req[4] = 0x00; smprintf(s,"Getting subfolders for filesystem\n"); error=GSM_WaitFor (s, req, 10, 0x6D, 4, Request); if (error != ERR_NONE) return error; if (!File->Folder) { req[3] = 0x2E; req[4] = 0x01; smprintf(s,"Getting used memory for file in filesystem\n"); error=GSM_WaitFor (s, req, 10, 0x6D, 4, Request); if (error != ERR_NONE) return error; GetCRC[8] = atoi(File->ID_FullName) / 256; GetCRC[9] = atoi(File->ID_FullName) % 256; smprintf(s,"Getting CRC for file in filesystem\n"); error=GSM_WaitFor (s, GetCRC, 10, 0x6D, 4, Request); } } return error; } static GSM_Error N6510_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, bool start) { GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; GSM_Error error; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED; if (start) { Priv->FilesLocationsUsed = 1; Priv->FilesLocationsCurrent = 0; Priv->FilesLocations[0] = 0x01; Priv->FilesLevels[0] = 1; } while (1) { if (Priv->FilesLocationsCurrent == Priv->FilesLocationsUsed) return ERR_EMPTY; sprintf(File->ID_FullName,"%i",Priv->FilesLocations[Priv->FilesLocationsCurrent]); File->Level = Priv->FilesLevels[Priv->FilesLocationsCurrent]; Priv->FilesLocationsCurrent++; error = N6510_GetFileFolderInfo(s, File, ID_GetFileInfo); if (error == ERR_EMPTY) continue; return error; } } static GSM_Error N6510_ReplyGetFileSystemStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x23: if (!strcmp(s->Phone.Data.ModelInfo->model,"6310i")) { smprintf(s,"File or folder total bytes received\n"); s->Phone.Data.FileSystemStatus->Free = 3*256*256 + msg.Buffer[8]*256 + msg.Buffer[9] - s->Phone.Data.FileSystemStatus->Used; } else { smprintf(s,"File or folder free bytes received\n"); s->Phone.Data.FileSystemStatus->Free = msg.Buffer[6]*256*256*256+ msg.Buffer[7]*256*256+ msg.Buffer[8]*256+ msg.Buffer[9]; } return ERR_NONE; case 0x2F: smprintf(s,"File or folder used bytes received\n"); s->Phone.Data.FileSystemStatus->Used = msg.Buffer[6]*256*256*256+ msg.Buffer[7]*256*256+ msg.Buffer[8]*256+ msg.Buffer[9]; return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetFileSystemStatus(GSM_StateMachine *s, GSM_FileSystemStatus *status) { GSM_Error error; unsigned char req[10] = { N7110_FRAME_HEADER, 0x22, /* 0x14 - info, 0x22 - free/total, 0x2E - used, 0x32 - sublocations */ 0x01, /* 0x00 for sublocations reverse sorting, 0x01 for free */ 0x00, 0x00, 0x01, 0x00, 0x01}; /* Folder or file number */ if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED; s->Phone.Data.FileSystemStatus = status; status->Free = 0; req[3] = 0x2E; req[4] = 0x01; smprintf(s, "Getting used/total memory in filesystem\n"); error = GSM_WaitFor (s, req, 10, 0x6D, 4, ID_FileSystemStatus); req[3] = 0x22; req[4] = 0x01; smprintf(s, "Getting free memory in filesystem\n"); return GSM_WaitFor (s, req, 10, 0x6D, 4, ID_FileSystemStatus); } static GSM_Error N6510_SearchForFileName(GSM_StateMachine *s, GSM_File *File) { GSM_File File2; GSM_Error error; int FilesLocations[1000],FilesLocations2[1000]; int FilesLevels[1000]; int FilesLocationsUsed, FilesLocationsCurrent; int FilesLocationsUsed2, FilesLocationsCurrent2; GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; memcpy(FilesLocations, Priv->FilesLocations, sizeof(FilesLocations)); memcpy(FilesLevels, Priv->FilesLevels, sizeof(FilesLevels)); FilesLocationsUsed = Priv->FilesLocationsUsed; FilesLocationsCurrent = Priv->FilesLocationsCurrent; Priv->FilesLocationsUsed = 1; Priv->FilesLocationsCurrent = 1; Priv->FilesLocations[0] = atoi(File->ID_FullName); Priv->FilesLevels[0] = 1; strcpy(File2.ID_FullName,File->ID_FullName); error = N6510_GetFileFolderInfo(s, &File2, ID_GetFileInfo); memcpy(FilesLocations2, Priv->FilesLocations, sizeof(FilesLocations2)); FilesLocationsUsed2 = Priv->FilesLocationsUsed; FilesLocationsCurrent2 = Priv->FilesLocationsCurrent; memcpy(Priv->FilesLocations, FilesLocations, sizeof(FilesLocations)); memcpy(Priv->FilesLevels, FilesLevels, sizeof(FilesLevels)); Priv->FilesLocationsUsed = FilesLocationsUsed; Priv->FilesLocationsCurrent = FilesLocationsCurrent; if (error != ERR_NONE) return error; while (1) { if (FilesLocationsCurrent2 == FilesLocationsUsed2) return ERR_EMPTY; sprintf(File2.ID_FullName,"%i",FilesLocations2[FilesLocationsCurrent2]); dbgprintf("Current is %i\n",FilesLocations2[FilesLocationsCurrent2]); FilesLocationsCurrent2++; error = N6510_GetFileFolderInfo(s, &File2, ID_AddFile); if (error == ERR_EMPTY) continue; if (error != ERR_NONE) return error; dbgprintf("%s %s\n",DecodeUnicodeString(File->Name),DecodeUnicodeString(File2.Name)); if (mywstrncasecmp(File2.Name,File->Name,0)) return ERR_NONE; } return ERR_EMPTY; } static GSM_Error N6510_ReplyGetFilePart(GSM_Protocol_Message msg, GSM_StateMachine *s) { int old; smprintf(s,"File part received\n"); old = s->Phone.Data.File->Used; s->Phone.Data.File->Used += msg.Buffer[6]*256*256*256+ msg.Buffer[7]*256*256+ msg.Buffer[8]*256+ msg.Buffer[9]; smprintf(s,"Length of file part: %i\n", msg.Buffer[6]*256*256*256+ msg.Buffer[7]*256*256+ msg.Buffer[8]*256+ msg.Buffer[9]); s->Phone.Data.File->Buffer = (unsigned char *)realloc(s->Phone.Data.File->Buffer,s->Phone.Data.File->Used); memcpy(s->Phone.Data.File->Buffer+old,msg.Buffer+10,s->Phone.Data.File->Used-old); return ERR_NONE; } static GSM_Error N6510_GetFilePart(GSM_StateMachine *s, GSM_File *File) { GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; int old; GSM_Error error; unsigned char req[] = { N7110_FRAME_HEADER, 0x0E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, /* Folder or file number */ 0x00, 0x00, 0x00, 0x00, /* Start from xxx byte */ 0x00, 0x00, 0x03, 0xE8}; /* Read xxx bytes */ if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED; if (File->Used == 0x00) { error = N6510_GetFileFolderInfo(s, File, ID_GetFile); if (error != ERR_NONE) return error; File->Used = 0; } old = File->Used; req[8] = atoi(File->ID_FullName) / 256; req[9] = atoi(File->ID_FullName) % 256; req[10] = old / (256*256*256); req[11] = old / (256*256); req[12] = old / 256; req[13] = old % 256; s->Phone.Data.File = File; smprintf(s, "Getting file part from filesystem\n"); error=GSM_WaitFor (s, req, 18, 0x6D, 4, ID_GetFile); if (error != ERR_NONE) return error; if (File->Used - old != (0x03 * 256 + 0xE8)) { if (N6510_FindFileCheckSum(File->Buffer, File->Used) != Priv->FileCheckSum) { smprintf(s,"File2 checksum is %i, File checksum is %i\n",N6510_FindFileCheckSum(File->Buffer, File->Used),Priv->FileCheckSum); return ERR_WRONGCRC; } return ERR_EMPTY; } return ERR_NONE; } static GSM_Error N6510_SetReadOnly(GSM_StateMachine *s, unsigned char *ID, bool enable) { unsigned char SetAttr[] = { N7110_FRAME_HEADER, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20}; /* File ID */ if (!enable) SetAttr[4] = 0x06; SetAttr[8] = atoi(ID) / 256; SetAttr[9] = atoi(ID) % 256; smprintf(s, "Setting readonly attribute\n"); return GSM_WaitFor (s, SetAttr, 10, 0x6D, 4, ID_DeleteFile); } static GSM_Error N6510_ReplyAddFileHeader(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x03: smprintf(s,"File header added\n"); sprintf(s->Phone.Data.File->ID_FullName,"%i",msg.Buffer[9]); return ERR_NONE; case 0x13: return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_ReplyAddFilePart(GSM_Protocol_Message msg, GSM_StateMachine *s) { return ERR_NONE; } static GSM_Error N6510_AddFilePart(GSM_StateMachine *s, GSM_File *File, int *Pos) { GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; GSM_File File2; GSM_Error error; int j; unsigned char Header[400] = { N7110_FRAME_HEADER, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0C, /* parent folder ID */ 0x00, 0x00, 0x00, 0xE8}; unsigned char Add[15000] = { N7110_FRAME_HEADER, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, /* file ID */ 0x00, 0x00, 0x01, 0x28}; /* length */ unsigned char end[30] = { N7110_FRAME_HEADER, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, /* file ID */ 0x00, 0x00, 0x00, 0x00}; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED; s->Phone.Data.File = File; if (*Pos == 0) { error = N6510_SearchForFileName(s,File); if (error == ERR_NONE) return ERR_FILEALREADYEXIST; if (error != ERR_EMPTY) return error; Header[8] = atoi(File->ID_FullName) / 256; Header[9] = atoi(File->ID_FullName) % 256; memset(Header+14, 0x00, 300); CopyUnicodeString(Header+14,File->Name); Header[222] = File->Used / (256*256*256); Header[223] = File->Used / (256*256); Header[224] = File->Used / 256; Header[225] = File->Used % 256; switch(File->Type) { case GSM_File_Image_JPG : Header[231]=0x02; Header[233]=0x01; break; case GSM_File_Image_BMP : Header[231]=0x02; Header[233]=0x02; break; case GSM_File_Image_PNG : Header[231]=0x02; Header[233]=0x03; break; case GSM_File_Image_GIF : Header[231]=0x02; Header[233]=0x05; break; case GSM_File_Image_WBMP : Header[231]=0x02; Header[233]=0x09; break; case GSM_File_Sound_AMR : Header[231]=0x04; Header[233]=0x01; break; case GSM_File_Sound_MIDI : Header[231]=0x04; Header[233]=0x05; break; //Header[238]=0x01; case GSM_File_Sound_NRT : Header[231]=0x04; Header[233]=0x06; break; case GSM_File_Video_3GP : Header[231]=0x08; Header[233]=0x05; break; case GSM_File_Java_JAR : Header[231]=0x10; Header[233]=0x01; break; #ifdef DEVELOP case GSM_File_MMS: Header[214]=0x07; Header[215]=0xd3; Header[216]=0x06; Header[217]=0x01; Header[218]=0x12; Header[219]=0x13; Header[220]=0x29; Header[233]=0x01; break; #endif default : Header[231]=0x01; Header[233]=0x05; } Header[235] = 0x01; Header[236] = atoi(File->ID_FullName) / 256; Header[237] = atoi(File->ID_FullName) % 256; if (File->Protected) Header[238] = 0x01; //Nokia forward lock if (File->Hidden) Header[241] = 0x01; if (File->System) Header[242] = 0x01; //fixme smprintf(s, "Adding file header\n"); error=GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFile); if (error != ERR_NONE) return error; } j = 1000; if (File->Used - *Pos < 1000) j = File->Used - *Pos; Add[ 8] = atoi(File->ID_FullName) / 256; Add[ 9] = atoi(File->ID_FullName) % 256; Add[12] = j / 256; Add[13] = j % 256; memcpy(Add+14,File->Buffer+(*Pos),j); smprintf(s, "Adding file part %i %i\n",*Pos,j); error=GSM_WaitFor (s, Add, 14+j, 0x6D, 4, ID_AddFile); if (error != ERR_NONE) return error; *Pos = *Pos + j; if (j < 1000) { end[8] = atoi(File->ID_FullName) / 256; end[9] = atoi(File->ID_FullName) % 256; smprintf(s, "Frame for ending adding file\n"); error = GSM_WaitFor (s, end, 14, 0x6D, 4, ID_AddFile); if (error != ERR_NONE) return error; strcpy(File2.ID_FullName,File->ID_FullName); error = N6510_GetFileFolderInfo(s, &File2, ID_GetFileInfo); if (error != ERR_NONE) return error; if (!File->ModifiedEmpty) { Header[3] = 0x12; Header[4] = 0x01; Header[12] = 0x00; Header[13] = 0xE8; Header[8] = atoi(File->ID_FullName) / 256; Header[9] = atoi(File->ID_FullName) % 256; memset(Header+14, 0x00, 300); CopyUnicodeString(Header+14,File->Name); NOKIA_EncodeDateTime(s,Header+214,&File->Modified); /* When you save too big file for phone and it changes * size (some part is cut by firmware), you HAVE to write * here correct file size. In other case filesystem * will be damaged */ Header[224] = File2.Used / 256; Header[225] = File2.Used % 256; Header[226] = Priv->FileToken / 256; Header[227] = Priv->FileToken % 256; switch(File->Type) { case GSM_File_Image_JPG : Header[231]=0x02; Header[233]=0x01; break; case GSM_File_Image_BMP : Header[231]=0x02; Header[233]=0x02; break; case GSM_File_Image_PNG : Header[231]=0x02; Header[233]=0x03; break; case GSM_File_Image_GIF : Header[231]=0x02; Header[233]=0x05; break; case GSM_File_Image_WBMP : Header[231]=0x02; Header[233]=0x09; break; case GSM_File_Sound_AMR : Header[231]=0x04; Header[233]=0x01; break; case GSM_File_Sound_MIDI : Header[231]=0x04; Header[233]=0x05; break; //Header[238]=0x01; case GSM_File_Sound_NRT : Header[231]=0x04; Header[233]=0x06; break; case GSM_File_Video_3GP : Header[231]=0x08; Header[233]=0x05; break; case GSM_File_Java_JAR : Header[231]=0x10; Header[233]=0x01; break; #ifdef DEVELOP case GSM_File_MMS: Header[214]=0x07; Header[215]=0xd3; Header[216]=0x06; Header[217]=0x01; Header[218]=0x12; Header[219]=0x13; Header[220]=0x29; Header[233]=0x01; break; #endif default : Header[231]=0x01; Header[233]=0x05; } Header[235] = 0x01; Header[236] = Priv->ParentID / 256; Header[237] = Priv->ParentID % 256; smprintf(s, "Adding file header\n"); error=GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFile); if (error != ERR_NONE) return error; } /* Can't delete from phone menu */ if (File->ReadOnly) { error = N6510_SetReadOnly(s, File->ID_FullName, true); if (error != ERR_NONE) return error; } if (N6510_FindFileCheckSum(File->Buffer, File->Used) != Priv->FileCheckSum) { smprintf(s,"File2 checksum is %i, File checksum is %i\n",N6510_FindFileCheckSum(File->Buffer, File->Used),Priv->FileCheckSum); return ERR_WRONGCRC; } return ERR_EMPTY; } return ERR_NONE; } static GSM_Error N6510_ReplyDeleteFile(GSM_Protocol_Message msg, GSM_StateMachine *s) { return ERR_NONE; } static GSM_Error N6510_DeleteFile(GSM_StateMachine *s, unsigned char *ID) { GSM_Error error; unsigned char Delete[40] = { N7110_FRAME_HEADER, 0x1E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x35}; /* File ID */ if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED; error = N6510_SetReadOnly(s, ID, false); if (error != ERR_NONE) return error; Delete[8] = atoi(ID) / 256; Delete[9] = atoi(ID) % 256; return GSM_WaitFor (s, Delete, 10, 0x6D, 4, ID_DeleteFile); } static GSM_Error N6510_ReplyAddFolder(GSM_Protocol_Message msg, GSM_StateMachine *s) { sprintf(s->Phone.Data.File->ID_FullName,"%i",msg.Buffer[9]); return ERR_NONE; } static GSM_Error N6510_AddFolder(GSM_StateMachine *s, GSM_File *File) { GSM_Error error; unsigned char Header[400] = { N7110_FRAME_HEADER, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0C, /* parent folder ID */ 0x00, 0x00, 0x00, 0xE8}; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED; error = N6510_SearchForFileName(s,File); if (error == ERR_NONE) return ERR_INVALIDLOCATION; if (error != ERR_EMPTY) return error; Header[8] = atoi(File->ID_FullName) / 256; Header[9] = atoi(File->ID_FullName) % 256; memset(Header+14, 0x00, 300); CopyUnicodeString(Header+14,File->Name); Header[233] = 0x02; Header[235] = 0x01; Header[236] = atoi(File->ID_FullName) / 256; Header[237] = atoi(File->ID_FullName) % 256; s->Phone.Data.File = File; smprintf(s, "Adding folder\n"); error = GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFolder); if (error != ERR_NONE) return error; /* Can't delete from phone menu */ if (File->ReadOnly) { error = N6510_SetReadOnly(s, File->ID_FullName, true); if (error != ERR_NONE) return error; } return error; } #ifdef DEVELOP static GSM_Error N6510_ReplyEnableGPRSAccessPoint(GSM_Protocol_Message msg, GSM_StateMachine *s) { if (msg.Buffer[13] == 0x02) return ERR_NONE; return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_EnableGPRSAccessPoint(GSM_StateMachine *s) { GSM_Error error; int i; unsigned char req[] = { N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00}; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return ERR_NOTSUPPORTED; for (i=0;i<3;i++) { smprintf(s, "Activating full GPRS access point support\n"); error = GSM_WaitFor (s, req, 16, 0x43, 4, ID_EnableGPRSPoint); if (error != ERR_NONE) return error; } return error; } #endif static GSM_Error N6510_ReplyGetGPRSAccessPoint(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_GPRSAccessPoint *point = s->Phone.Data.GPRSPoint; switch (msg.Buffer[13]) { case 0x01: smprintf(s,"Active GPRS point received\n"); point->Active = false; if (point->Location == msg.Buffer[18]) point->Active = true; return ERR_NONE; case 0xD2: smprintf(s,"Names for GPRS points received\n"); CopyUnicodeString(point->Name,msg.Buffer+18+(point->Location-1)*42); smprintf(s,"\"%s\"\n",DecodeUnicodeString(point->Name)); return ERR_NONE; case 0xF2: smprintf(s,"URL for GPRS points received\n"); CopyUnicodeString(point->URL,msg.Buffer+18+(point->Location-1)*202); smprintf(s,"\"%s\"\n",DecodeUnicodeString(point->URL)); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetGPRSAccessPoint(GSM_StateMachine *s, GSM_GPRSAccessPoint *point) { GSM_Error error; unsigned char URL[] = { N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00}; unsigned char Name[] = { N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00}; unsigned char Active[] = { N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return ERR_NOTSUPPORTED; if (point->Location < 1) return ERR_UNKNOWN; if (point->Location > 5) return ERR_INVALIDLOCATION; s->Phone.Data.GPRSPoint = point; #ifdef DEVELOP error = N6510_EnableGPRSAccessPoint(s); if (error != ERR_NONE) return error; #endif smprintf(s, "Getting GPRS access point name\n"); error=GSM_WaitFor (s, Name, 16, 0x43, 4, ID_GetGPRSPoint); if (error != ERR_NONE) return error; smprintf(s, "Getting GPRS access point URL\n"); error=GSM_WaitFor (s, URL, 16, 0x43, 4, ID_GetGPRSPoint); if (error != ERR_NONE) return error; smprintf(s, "Getting number of active GPRS access point\n"); error=GSM_WaitFor (s, Active, 16, 0x43, 4, ID_GetGPRSPoint); if (error != ERR_NONE) return error; if (UnicodeLength(point->URL)==0 && UnicodeLength(point->Name)==0) return ERR_EMPTY; return error; } static GSM_Error N6510_ReplySetGPRSAccessPoint1(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[13]) { case 0x01: case 0xD2: case 0xF2: memcpy(s->Phone.Data.Priv.N6510.GPRSPoints,msg.Buffer,msg.Length); s->Phone.Data.Priv.N6510.GPRSPointsLength = msg.Length; return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_SetGPRSAccessPoint(GSM_StateMachine *s, GSM_GPRSAccessPoint *point) { unsigned char *buff = s->Phone.Data.Priv.N6510.GPRSPoints; GSM_Error error; unsigned char URL[] = { N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00}; unsigned char Name[] = { N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00}; unsigned char Active[] = { N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return ERR_NOTSUPPORTED; if (point->Location < 1) return ERR_UNKNOWN; if (point->Location > 5) return ERR_INVALIDLOCATION; s->Phone.Data.GPRSPoint = point; #ifdef DEVELOP error = N6510_EnableGPRSAccessPoint(s); if (error != ERR_NONE) return error; #endif smprintf(s, "Getting GPRS access point name\n"); error=GSM_WaitFor (s, Name, 16, 0x43, 4, ID_SetGPRSPoint); if (error != ERR_NONE) return error; CopyUnicodeString(buff+18+(point->Location-1)*42,point->Name); buff[0] = 0x00; buff[1] = 0x01; buff[2] = 0x01; buff[3] = 0x07; smprintf(s, "Setting GPRS access point name\n"); error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, 4, ID_SetGPRSPoint); if (error != ERR_NONE) return error; smprintf(s, "Getting GPRS access point URL\n"); error=GSM_WaitFor (s, URL, 16, 0x43, 4, ID_SetGPRSPoint); if (error != ERR_NONE) return error; CopyUnicodeString(buff+18+(point->Location-1)*42,point->URL); buff[0] = 0x00; buff[1] = 0x01; buff[2] = 0x01; buff[3] = 0x07; smprintf(s, "Setting GPRS access point URL\n"); error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, 4, ID_SetGPRSPoint); if (error != ERR_NONE) return error; if (point->Active) { smprintf(s, "Getting number of active GPRS access point\n"); error=GSM_WaitFor (s, Active, 16, 0x43, 4, ID_SetGPRSPoint); if (error != ERR_NONE) return error; buff[0] = 0x00; buff[1] = 0x01; buff[2] = 0x01; buff[3] = 0x07; buff[18]= point->Location; smprintf(s, "Setting number of active GPRS access point\n"); error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, 4, ID_SetGPRSPoint); if (error != ERR_NONE) return error; } return error; } /* ToDo support - 6310 style */ static GSM_Error N6510_ReplyGetToDoStatus1(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; GSM_NOKIACalToDoLocations *Last = &s->Phone.Data.Priv.N6510.LastToDo; smprintf(s, "TODO locations received\n"); Last->Number=msg.Buffer[6]*256+msg.Buffer[7]; smprintf(s, "Number of Entries: %i\n",Last->Number); smprintf(s, "Locations: "); for (i=0;i<Last->Number;i++) { Last->Location[i]=msg.Buffer[12+(i*4)]*256+msg.Buffer[(i*4)+13]; smprintf(s, "%i ",Last->Location[i]); } smprintf(s, "\n"); return ERR_NONE; } /* ToDo support - 6310 style */ static GSM_Error N6510_GetToDoStatus1(GSM_StateMachine *s, GSM_ToDoStatus *status) { GSM_Error error; GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo; unsigned char reqLoc[] = { N6110_FRAME_HEADER, 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}; smprintf(s, "Getting ToDo locations\n"); error = GSM_WaitFor (s, reqLoc, 10, 0x55, 4, ID_GetToDo); if (error != ERR_NONE) return error; status->Used = LastToDo->Number; return ERR_NONE; } static GSM_Error N6510_GetToDoStatus2(GSM_StateMachine *s, GSM_ToDoStatus *status) { GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo; GSM_Error error; error = N6510_GetCalendarInfo3(s,LastToDo,1); if (error!=ERR_NONE) return error; status->Used = LastToDo->Number; return ERR_NONE; } static GSM_Error N6510_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) { status->Used = 0; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) { return N6510_GetToDoStatus1(s, status); } else if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) { return N6510_GetToDoStatus2(s, status); } else { return ERR_NOTSUPPORTED; } } /* ToDo support - 6310 style */ static GSM_Error N6510_ReplyGetToDo1(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_ToDoEntry *Last = s->Phone.Data.ToDo; smprintf(s, "TODO received method 1\n"); switch (msg.Buffer[4]) { case 1 : Last->Priority = GSM_Priority_High; break; case 2 : Last->Priority = GSM_Priority_Medium; break; case 3 : Last->Priority = GSM_Priority_Low; break; default : return ERR_UNKNOWN; } smprintf(s, "Priority: %i\n",msg.Buffer[4]); CopyUnicodeString(Last->Entries[0].Text,msg.Buffer+14); Last->Entries[0].EntryType = TODO_TEXT; Last->EntriesNum = 1; smprintf(s, "Text: \"%s\"\n",DecodeUnicodeString(Last->Entries[0].Text)); return ERR_NONE; } /* ToDo support - 6310 style */ static GSM_Error N6510_GetNextToDo1(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh) { GSM_Error error; GSM_ToDoStatus status; GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo; unsigned char reqGet[] = { N6110_FRAME_HEADER, 0x03, 0x00, 0x00, 0x80, 0x00, 0x00, 0x17}; /* Location */ if (refresh) { error = N6510_GetToDoStatus(s, &status); if (error != ERR_NONE) return error; ToDo->Location = 1; } else { ToDo->Location++; } if (ToDo->Location > LastToDo->Number) return ERR_EMPTY; reqGet[8] = LastToDo->Location[ToDo->Location-1] / 256; reqGet[9] = LastToDo->Location[ToDo->Location-1] % 256; s->Phone.Data.ToDo = ToDo; smprintf(s, "Getting ToDo\n"); return GSM_WaitFor (s, reqGet, 10, 0x55, 4, ID_GetToDo); } static GSM_Error N6510_ReplyGetToDoStatus2(GSM_Protocol_Message msg, GSM_StateMachine *s) { return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastToDo); } /* Similiar to getting calendar method 3 */ static GSM_Error N6510_ReplyGetToDo2(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_ToDoEntry *Last = s->Phone.Data.ToDo; GSM_DateTime Date; unsigned long diff; smprintf(s, "ToDo received method 2\n"); switch (msg.Buffer[44]) { case 0x10: Last->Priority = GSM_Priority_Low; break; case 0x20: Last->Priority = GSM_Priority_Medium; break; case 0x30: Last->Priority = GSM_Priority_High; break; default : return ERR_UNKNOWN; } memcpy(Last->Entries[0].Text,msg.Buffer+54,msg.Buffer[51]*2); Last->Entries[0].Text[msg.Buffer[51]*2] = 0; Last->Entries[0].Text[msg.Buffer[51]*2+1] = 0; Last->Entries[0].EntryType = TODO_TEXT; smprintf(s, "Text: \"%s\"\n",DecodeUnicodeString(Last->Entries[0].Text)); smprintf(s,"EndTime: %04i-%02i-%02i %02i:%02i\n", msg.Buffer[34]*256+msg.Buffer[35], msg.Buffer[36],msg.Buffer[37],msg.Buffer[38], msg.Buffer[39]); Date.Year = msg.Buffer[34]*256+msg.Buffer[35]; Date.Month = msg.Buffer[36]; Date.Day = msg.Buffer[37]; Date.Hour = msg.Buffer[38]; Date.Minute = msg.Buffer[39]; Date.Second = 0; Last->Entries[1].EntryType = TODO_END_DATETIME; memcpy(&Last->Entries[1].Date,&Date,sizeof(GSM_DateTime)); smprintf(s,"StartTime: %04i-%02i-%02i %02i:%02i\n", msg.Buffer[28]*256+msg.Buffer[29], msg.Buffer[30],msg.Buffer[31],msg.Buffer[32], msg.Buffer[33]); Date.Year = msg.Buffer[28]*256+msg.Buffer[29]; Date.Month = msg.Buffer[30]; Date.Day = msg.Buffer[31]; Date.Hour = msg.Buffer[32]; Date.Minute = msg.Buffer[33]; Date.Second = 0; Last->EntriesNum = 2; if (msg.Buffer[45] == 0x01) { Last->Entries[2].Number = msg.Buffer[45]; Last->Entries[2].EntryType = TODO_COMPLETED; Last->EntriesNum++; smprintf(s,"Completed\n"); } if (msg.Buffer[14] == 0xFF && msg.Buffer[15] == 0xFF && msg.Buffer[16] == 0xff && msg.Buffer[17] == 0xff) { smprintf(s, "No alarm\n"); } else { diff = ((unsigned int)msg.Buffer[14]) << 24; diff += ((unsigned int)msg.Buffer[15]) << 16; diff += ((unsigned int)msg.Buffer[16]) << 8; diff += msg.Buffer[17]; memcpy(&Last->Entries[Last->EntriesNum].Date,&Date,sizeof(GSM_DateTime)); GetTimeDifference(diff, &Last->Entries[Last->EntriesNum].Date, false, 60); smprintf(s, "Alarm date : %02i-%02i-%04i %02i:%02i:%02i\n", Last->Entries[Last->EntriesNum].Date.Day, Last->Entries[Last->EntriesNum].Date.Month, Last->Entries[Last->EntriesNum].Date.Year, Last->Entries[Last->EntriesNum].Date.Hour, Last->Entries[Last->EntriesNum].Date.Minute,Last->Entries[Last->EntriesNum].Date.Second); Last->Entries[Last->EntriesNum].EntryType = TODO_ALARM_DATETIME; if (msg.Buffer[22]==0x00 && msg.Buffer[23]==0x00 && msg.Buffer[24]==0x00 && msg.Buffer[25]==0x00) { Last->Entries[Last->EntriesNum].EntryType = TODO_SILENT_ALARM_DATETIME; smprintf(s, "Alarm type : Silent\n"); } Last->EntriesNum++; } return ERR_NONE; } /* ToDo support - 6610 style */ static GSM_Error N6510_GetNextToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh) { GSM_Error error; GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo; if (refresh) { error=N6510_GetCalendarInfo3(s,LastToDo,1); if (error!=ERR_NONE) return error; ToDo->Location = 1; } else { ToDo->Location++; } if (ToDo->Location > LastToDo->Number) return ERR_EMPTY; s->Phone.Data.ToDo = ToDo; smprintf(s, "Getting todo method 2\n"); return N6510_PrivGetGenericCalendar3(s, LastToDo->Location[ToDo->Location-1], ID_GetToDo); } static GSM_Error N6510_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh) { if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) { return N6510_GetNextToDo1(s, ToDo, refresh); } else if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) { return N6510_GetNextToDo2(s, ToDo, refresh); } else { return ERR_NOTSUPPORTED; } } /* ToDo support - 6310 style */ static GSM_Error N6510_ReplyDeleteAllToDo1(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "All TODO deleted\n"); return ERR_NONE; } /* ToDo support - 6310 style */ static GSM_Error N6510_DeleteAllToDo1(GSM_StateMachine *s) { unsigned char req[] = {N6110_FRAME_HEADER, 0x11}; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) { return ERR_NOTSUPPORTED; } smprintf(s, "Deleting all ToDo method 1\n"); return GSM_WaitFor (s, req, 4, 0x55, 4, ID_DeleteAllToDo); } static GSM_Error N6510_DeleteToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_Error error; GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo; GSM_CalendarEntry Note; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) { return ERR_NOTSUPPORTED; } error=N6510_GetCalendarInfo3(s,LastToDo,1); if (error!=ERR_NONE) return error; smprintf(s, "Deleting ToDo method 2\n"); if (ToDo->Location > LastToDo->Number || ToDo->Location == 0) return ERR_INVALIDLOCATION; Note.Location = LastToDo->Location[ToDo->Location-1]; return N71_65_DelCalendar(s,&Note); } /* ToDo support - 6310 style */ static GSM_Error N6510_ReplyGetToDoFirstLoc1(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "TODO first location received method 1: %02x\n",msg.Buffer[9]); s->Phone.Data.ToDo->Location = msg.Buffer[9]; return ERR_NONE; } /* ToDo support - 6310 style */ static GSM_Error N6510_ReplyAddToDo1(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "TODO set OK\n"); return ERR_NONE; } /* ToDo support - 6310 style */ static GSM_Error N6510_AddToDo1(GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { int Text, Alarm, EndTime, Completed, ulen, Phone; GSM_Error error; unsigned char reqLoc[] = {N6110_FRAME_HEADER, 0x0F}; unsigned char reqSet[500] = { N6110_FRAME_HEADER, 0x01, 0x03, /* Priority */ 0x00, /* Length of text */ 0x80,0x00,0x00, 0x18}; /* Location */ s->Phone.Data.ToDo = ToDo; smprintf(s, "Getting first ToDo location\n"); error = GSM_WaitFor (s, reqLoc, 4, 0x55, 4, ID_SetToDo); if (error != ERR_NONE) return error; reqSet[9] = ToDo->Location; switch (ToDo->Priority) { case GSM_Priority_Low : reqSet[4] = 3; break; case GSM_Priority_Medium: reqSet[4] = 2; break; case GSM_Priority_High : reqSet[4] = 1; break; } GSM_ToDoFindDefaultTextTimeAlarmCompleted(ToDo, &Text, &Alarm, &Completed, &EndTime, &Phone); if (Text == -1) return ERR_NOTSUPPORTED; /* XXX: shouldn't this be handled different way? */ ulen = UnicodeLength(ToDo->Entries[Text].Text); reqSet[5] = ulen+1; CopyUnicodeString(reqSet+10,ToDo->Entries[Text].Text); reqSet[10+ulen*2] = 0x00; reqSet[10+ulen*2+1] = 0x00; smprintf(s, "Adding ToDo method 1\n"); return GSM_WaitFor (s, reqSet, 12+ulen*2, 0x55, 4, ID_SetToDo); } static GSM_Error N6510_ReplyAddToDo2(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "ToDo added method 2\n"); return ERR_NONE; } static GSM_Error N6510_ReplyGetToDoFirstLoc2(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "First ToDo location method 2: %i\n",msg.Buffer[8]*256+msg.Buffer[9]); - s->Phone.Data.ToDo->Location = msg.Buffer[9]; + s->Phone.Data.ToDo->Location = msg.Buffer[8]*256+msg.Buffer[9]; return ERR_NONE; } static GSM_Error N6510_AddToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { GSM_CalendarEntry Note; time_t t_time1,t_time2; long diff; GSM_Error error; GSM_DateTime DT; int Text, Alarm, EndTime, Completed, count=54, Phone; - unsigned char reqLoc[] = {N6110_FRAME_HEADER, 0x95, 0x01}; + unsigned char reqLoc[] = {N6110_FRAME_HEADER, 0x95, + 0x01}; /* 1 = todo, 2 = note */ unsigned char req[5000] = { N6110_FRAME_HEADER, 0x65, 0x01, /* 0 = calendar, 1 = todo */ 0x00, 0x00, 0x00, 0x00, 0x00, /* location */ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, /* alarm */ 0x80, 0x00, 0x00, 0x01, /* note icon */ 0xFF, 0xFF, 0xFF, 0xFF, /* alarm type */ 0x00, /* 0x02 or 0x00 */ 0x01, /* note type */ 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* start date/time */ 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* end date/time */ 0x00, 0x00, /* recurrance */ 0x00, 0x00, /* birth year */ 0x20, /* ToDo priority */ 0x00, /* ToDo completed ? */ 0x00, 0x00, 0x00, 0x00, /* note text length */ 0x00, /* phone length/meeting place */ 0x00, 0x00, 0x00}; s->Phone.Data.ToDo = ToDo; smprintf(s, "Getting first free ToDo location method 2\n"); error = GSM_WaitFor (s, reqLoc, 5, 0x13, 4, ID_SetToDo); if (error!=ERR_NONE) return error; req[8] = ToDo->Location/256; req[9] = ToDo->Location%256; Note.Type = GSM_CAL_MEETING; DT.Year = 2004; DT.Month = 1; DT.Day = 1; DT.Hour = 12; DT.Minute = 12; DT.Second = 0; memcpy(&Note.Entries[0].Date,&DT,sizeof(GSM_DateTime)); Note.Entries[0].EntryType = CAL_START_DATETIME; memcpy(&Note.Entries[1].Date,&DT,sizeof(GSM_DateTime)); Note.Entries[1].EntryType = CAL_END_DATETIME; EncodeUnicode(Note.Entries[2].Text,"ala",3); Note.Entries[2].EntryType = CAL_TEXT; Note.EntriesNum = 3; error=N6510_FindCalendarIconID3(s, &Note, &req[21]); if (error!=ERR_NONE) return error; switch (ToDo->Priority) { case GSM_Priority_Low : req[44] = 0x10; break; case GSM_Priority_Medium: req[44] = 0x20; break; case GSM_Priority_High : req[44] = 0x30; break; } GSM_ToDoFindDefaultTextTimeAlarmCompleted(ToDo, &Text, &Alarm, &Completed, &EndTime, &Phone); if (Completed != -1) req[45] = 0x01; if (EndTime == -1) { GSM_GetCurrentDateTime(&DT); } else { memcpy(&DT,&ToDo->Entries[EndTime].Date,sizeof(GSM_DateTime)); } /*Start time*/ req[28] = DT.Year / 256; req[29] = DT.Year % 256; req[30] = DT.Month; req[31] = DT.Day; req[32] = DT.Hour; req[33] = DT.Minute; /*End time*/ req[34] = DT.Year / 256; req[35] = DT.Year % 256; req[36] = DT.Month; req[37] = DT.Day; req[38] = DT.Hour; req[39] = DT.Minute; if (Alarm != -1) { if (ToDo->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME) { req[22] = 0x00; req[23] = 0x00; req[24] = 0x00; req[25] = 0x00; } t_time2 = Fill_Time_T(DT,8); t_time1 = Fill_Time_T(ToDo->Entries[Alarm].Date,8); diff = (t_time1-t_time2)/60; smprintf(s, " Difference : %li seconds or minutes\n", -diff); req[14] = (unsigned char)(-diff >> 24); req[15] = (unsigned char)(-diff >> 16); req[16] = (unsigned char)(-diff >> 8); req[17] = (unsigned char)(-diff); } if (Text != -1) { req[49] = UnicodeLength(ToDo->Entries[Text].Text); CopyUnicodeString(req+54,ToDo->Entries[Text].Text); count+= req[49]*2; } req[count++] = 0x00; smprintf(s, "Adding ToDo method 2\n"); return GSM_WaitFor (s, req, count, 0x13, 4, ID_SetToDo); } static GSM_Error N6510_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) { return N6510_AddToDo1(s, ToDo); } else if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) { return N6510_AddToDo2(s, ToDo); } else { return ERR_NOTSUPPORTED; } } static GSM_Error N6510_ReplyGetLocale(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Locale *locale = s->Phone.Data.Locale; switch (msg.Buffer[3]) { case 0x8A: smprintf(s, "Date settings received\n"); switch (msg.Buffer[4]) { case 0x00: locale->DateFormat = GSM_Date_DDMMYYYY; locale->DateSeparator = '.'; break; case 0x01: locale->DateFormat = GSM_Date_MMDDYYYY; locale->DateSeparator = '.'; break; case 0x02: locale->DateFormat = GSM_Date_YYYYMMDD; locale->DateSeparator = '.'; break; case 0x04: locale->DateFormat = GSM_Date_DDMMYYYY; locale->DateSeparator = '/'; break; case 0x05: locale->DateFormat = GSM_Date_MMDDYYYY; locale->DateSeparator = '/'; break; case 0x06: locale->DateFormat = GSM_Date_YYYYMMDD; locale->DateSeparator = '/'; break; case 0x08: locale->DateFormat = GSM_Date_DDMMYYYY; locale->DateSeparator = '-'; break; case 0x09: locale->DateFormat = GSM_Date_MMDDYYYY; locale->DateSeparator = '-'; break; case 0x0A: locale->DateFormat = GSM_Date_YYYYMMDD; locale->DateSeparator = '-'; break; default:/* FIXME */ locale->DateFormat = GSM_Date_DDMMYYYY; locale->DateSeparator = '/'; break; } return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetLocale(GSM_StateMachine *s, GSM_Locale *locale) { unsigned char req[] = {N6110_FRAME_HEADER, 0x89}; s->Phone.Data.Locale = locale; smprintf(s, "Getting date format\n"); return GSM_WaitFor (s, req, 4, 0x13, 4, ID_GetLocale); } static GSM_Error N6510_ReplyGetCalendarSettings(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_CalendarSettings *sett = s->Phone.Data.CalendarSettings; switch (msg.Buffer[3]) { case 0x86: smprintf(s, "Auto deleting setting received\n"); sett->AutoDelete = msg.Buffer[4]; return ERR_NONE; case 0x8E: smprintf(s, "Start day for calendar received\n"); switch(msg.Buffer[4]) { case 0x03: sett->StartDay = 6; return ERR_NONE; case 0x02: sett->StartDay = 7; return ERR_NONE; case 0x01: sett->StartDay = 1; return ERR_NONE; } break; } return ERR_UNKNOWNRESPONSE; } static GSM_Error N6510_GetCalendarSettings(GSM_StateMachine *s, GSM_CalendarSettings *settings) { GSM_Error error; unsigned char req1[] = {N6110_FRAME_HEADER, 0x85}; unsigned char req2[] = {N6110_FRAME_HEADER, 0x8D}; s->Phone.Data.CalendarSettings = settings; smprintf(s, "Getting auto delete\n"); error = GSM_WaitFor (s, req1, 4, 0x13, 4, ID_GetCalendarSettings); if (error != ERR_NONE) return error; smprintf(s, "Getting start day for week\n"); return GSM_WaitFor (s, req2, 4, 0x13, 4, ID_GetCalendarSettings); } GSM_Error N6510_CancelCall(GSM_StateMachine *s, int ID, bool all) { if (all) return ERR_NOTSUPPORTED; return DCT3DCT4_CancelCall(s,ID); } GSM_Error N6510_AnswerCall(GSM_StateMachine *s, int ID, bool all) { if (all) return ERR_NOTSUPPORTED; return DCT3DCT4_AnswerCall(s,ID); } static GSM_Error N6510_ReplyAddSMSFolder(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s,"SMS folder \"%s\" has been added\n",DecodeUnicodeString(msg.Buffer+10)); return ERR_NONE; } GSM_Error N6510_AddSMSFolder(GSM_StateMachine *s, unsigned char *name) { unsigned char req[200] = {N6110_FRAME_HEADER, 0x10, 0x01, 0x00, 0x01, 0x00, /* Length */ 0x00, 0x00}; CopyUnicodeString(req+10,name); req[7] = UnicodeLength(name)*2 + 6; smprintf(s, "Adding SMS folder\n"); return GSM_WaitFor (s, req, req[7] + 6, 0x14, 4, ID_AddSMSFolder); } static GSM_Error N6510_SetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark) { GSM_Error error; int count=4, location; unsigned char req[600] = {N6110_FRAME_HEADER, 0x09}; /* We have to enable WAP frames in phone */ error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS); if (error!=ERR_NONE) return error; location = bookmark->Location - 1; if (bookmark->Location == 0) location = 0xffff; req[count++] = (location & 0xff00) >> 8; req[count++] = location & 0x00ff; count += NOKIA_SetUnicodeString(s, req+count, bookmark->Title, true); count += NOKIA_SetUnicodeString(s, req+count, bookmark->Address, true); req[count++] = 0x00; req[count++] = 0x00; req[count++] = 0x00; req[count++] = 0x00; smprintf(s, "Setting WAP bookmark\n"); error = GSM_WaitFor (s, req, count, 0x3f, 4, ID_SetWAPBookmark); if (error != ERR_NONE) { if (error == ERR_INSIDEPHONEMENU || error == ERR_EMPTY || error == ERR_FULL) { DCT3DCT4_DisableConnectionFunctions(s); } return error; } return DCT3DCT4_DisableConnectionFunctions(s); } GSM_Error N6510_DeleteWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark) { GSM_Error error; /* We have to enable WAP frames in phone */ error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS); if (error!=ERR_NONE) return error; return DCT3DCT4_DeleteWAPBookmarkPart(s,bookmark); } GSM_Error N6510_GetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark) { GSM_Error error; /* We have to enable WAP frames in phone */ error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS); if (error!=ERR_NONE) return error; return DCT3DCT4_GetWAPBookmarkPart(s,bookmark); } static GSM_Reply_Function N6510ReplyFunctions[] = { {N71_65_ReplyCallInfo, "\x01",0x03,0x02,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x03,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x04,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x05,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_AnswerCall }, {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_CancelCall }, {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0A,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0B,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_DialVoice }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0F,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x10,ID_DialVoice }, {N71_65_ReplyCallInfo, "\x01",0x03,0x10,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x23,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x25,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x27,ID_IncomingFrame }, {N71_65_ReplySendDTMF, "\x01",0x03,0x51,ID_SendDTMF }, {N71_65_ReplyCallInfo, "\x01",0x03,0x53,ID_IncomingFrame }, {N71_65_ReplySendDTMF, "\x01",0x03,0x59,ID_SendDTMF }, {N71_65_ReplySendDTMF, "\x01",0x03,0x5E,ID_SendDTMF }, {N71_65_ReplyCallInfo, "\x01",0x03,0xA6,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0xD2,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0xD3,ID_IncomingFrame }, {N6510_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame }, {N6510_ReplyIncomingSMS, "\x02",0x03,0x04,ID_IncomingFrame }, {N6510_ReplySetSMSC, "\x02",0x03,0x13,ID_SetSMSC }, {N6510_ReplyGetSMSC, "\x02",0x03,0x15,ID_GetSMSC }, {N6510_ReplyGetMemoryStatus, "\x03",0x03,0x04,ID_GetMemoryStatus }, {N6510_ReplyGetMemory, "\x03",0x03,0x08,ID_GetMemory }, {N6510_ReplyDeleteMemory, "\x03",0x03,0x10,ID_SetMemory }, {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetBitmap }, {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetMemory }, {DCT3DCT4_ReplyCallDivert, "\x06",0x03,0x02,ID_Divert }, {N71_65_ReplyUSSDInfo, "\x06",0x03,0x03,ID_IncomingFrame }, {NoneReply, "\x06",0x03,0x06,ID_IncomingFrame }, {NoneReply, "\x06",0x03,0x09,ID_IncomingFrame }, {N6510_ReplyEnterSecurityCode, "\x08",0x03,0x08,ID_EnterSecurityCode }, {N6510_ReplyEnterSecurityCode, "\x08",0x03,0x09,ID_EnterSecurityCode }, {N6510_ReplyGetSecurityStatus, "\x08",0x03,0x12,ID_GetSecurityStatus }, {N6510_ReplyGetNetworkInfo, "\x0A",0x03,0x01,ID_GetNetworkInfo }, {N6510_ReplyGetNetworkInfo, "\x0A",0x03,0x01,ID_IncomingFrame }, {N6510_ReplyLogIntoNetwork, "\x0A",0x03,0x02,ID_IncomingFrame }, {N6510_ReplyGetSignalQuality, "\x0A",0x03,0x0C,ID_GetSignalQuality }, {N6510_ReplyGetIncSignalQuality, "\x0A",0x03,0x1E,ID_IncomingFrame }, {NoneReply, "\x0A",0x03,0x20,ID_IncomingFrame }, {N6510_ReplyGetOperatorLogo, "\x0A",0x03,0x24,ID_GetBitmap }, {N6510_ReplySetOperatorLogo, "\x0A",0x03,0x26,ID_SetBitmap }, {NoneReply, "\x0B",0x03,0x01,ID_PlayTone }, {NoneReply, "\x0B",0x03,0x15,ID_PlayTone }, {NoneReply, "\x0B",0x03,0x16,ID_PlayTone }, {N71_65_ReplyAddCalendar1, "\x13",0x03,0x02,ID_SetCalendarNote }, {N71_65_ReplyAddCalendar1, "\x13",0x03,0x04,ID_SetCalendarNote }, {N71_65_ReplyAddCalendar1, "\x13",0x03,0x06,ID_SetCalendarNote }, {N71_65_ReplyAddCalendar1, "\x13",0x03,0x08,ID_SetCalendarNote }, {N71_65_ReplyDelCalendar, "\x13",0x03,0x0C,ID_DeleteCalendarNote }, {N71_65_ReplyGetNextCalendar1, "\x13",0x03,0x1A,ID_GetCalendarNote },/*method 1*/ {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0x32,ID_GetCalendarNotePos },/*method 1*/ {N6510_ReplyGetCalendarInfo, "\x13",0x03,0x3B,ID_GetCalendarNotesInfo},/*method 1*/ #ifdef DEBUG {N71_65_ReplyGetNextCalendar2, "\x13",0x03,0x3F,ID_GetCalendarNote }, #endif {N71_65_ReplyAddCalendar2, "\x13",0x03,0x41,ID_SetCalendarNote },/*method 2*/ {N6510_ReplyAddCalendar3, "\x13",0x03,0x66,ID_SetCalendarNote },/*method 3*/ {N6510_ReplyAddToDo2, "\x13",0x03,0x66,ID_SetToDo }, + {N6510_ReplyAddNote, "\x13",0x03,0x66,ID_SetNote }, {N6510_ReplyGetCalendar3, "\x13",0x03,0x7E,ID_GetCalendarNote },/*method 3*/ {N6510_ReplyGetToDo2, "\x13",0x03,0x7E,ID_GetToDo }, {N6510_ReplyGetNote, "\x13",0x03,0x7E,ID_GetNote }, {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x86,ID_GetCalendarSettings }, {N6510_ReplyGetLocale, "\x13",0x03,0x8A,ID_GetLocale }, {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x8E,ID_GetCalendarSettings }, {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0x96,ID_GetCalendarNotePos },/*method 3*/ {N6510_ReplyGetToDoFirstLoc2, "\x13",0x03,0x96,ID_SetToDo }, + {N6510_ReplyGetNoteFirstLoc, "\x13",0x03,0x96,ID_SetNote }, {N6510_ReplyGetCalendarInfo, "\x13",0x03,0x9F,ID_GetCalendarNotesInfo},/*method 3*/ {N6510_ReplyGetToDoStatus2, "\x13",0x03,0x9F,ID_GetToDo }, {N6510_ReplyGetNoteInfo, "\x13",0x03,0x9F,ID_GetNote }, {N6510_ReplySaveSMSMessage, "\x14",0x03,0x01,ID_SaveSMSMessage }, {N6510_ReplySetPicture, "\x14",0x03,0x01,ID_SetBitmap }, {N6510_ReplyGetSMSMessage, "\x14",0x03,0x03,ID_GetSMSMessage }, {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x05,ID_DeleteSMSMessage }, {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x06,ID_DeleteSMSMessage }, {N6510_ReplyGetSMSStatus, "\x14",0x03,0x09,ID_GetSMSStatus }, {N6510_ReplyGetSMSFolderStatus, "\x14",0x03,0x0d,ID_GetSMSFolderStatus }, {N6510_ReplyGetSMSMessage, "\x14",0x03,0x0f,ID_GetSMSMessage }, {N6510_ReplyAddSMSFolder, "\x14",0x03,0x11,ID_AddSMSFolder }, {N6510_ReplyGetSMSFolders, "\x14",0x03,0x13,ID_GetSMSFolders }, {N6510_ReplySaveSMSMessage, "\x14",0x03,0x17,ID_SaveSMSMessage }, {N6510_ReplyGetSMSStatus, "\x14",0x03,0x1a,ID_GetSMSStatus }, {DCT4_ReplySetPhoneMode, "\x15",0x03,0x64,ID_Reset }, {DCT4_ReplyGetPhoneMode, "\x15",0x03,0x65,ID_Reset }, {NoneReply, "\x15",0x03,0x68,ID_Reset }, {N6510_ReplyGetBatteryCharge, "\x17",0x03,0x0B,ID_GetBatteryCharge }, {N6510_ReplySetDateTime, "\x19",0x03,0x02,ID_SetDateTime }, {N6510_ReplyGetDateTime, "\x19",0x03,0x0B,ID_GetDateTime }, {N6510_ReplySetAlarm, "\x19",0x03,0x12,ID_SetAlarm }, {N6510_ReplyGetAlarm, "\x19",0x03,0x1A,ID_GetAlarm }, {N6510_ReplyGetAlarm, "\x19",0x03,0x20,ID_GetAlarm }, {DCT4_ReplyGetIMEI, "\x1B",0x03,0x01,ID_GetIMEI }, {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x08,ID_GetHardware }, {N6510_ReplyGetPPM, "\x1B",0x03,0x08,ID_GetPPM }, {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x0C,ID_GetProductCode }, /* 0x1C - vibra */ {N6510_ReplyGetRingtonesInfo, "\x1f",0x03,0x08,ID_GetRingtonesInfo }, {N6510_ReplyDeleteRingtones, "\x1f",0x03,0x11,ID_SetRingtone }, {N6510_ReplyGetRingtone, "\x1f",0x03,0x13,ID_GetRingtone }, {N6510_ReplySetBinRingtone, "\x1f",0x03,0x0F,ID_SetRingtone }, /* 0x23 - voice records */ {N6510_ReplyGetProfile, "\x39",0x03,0x02,ID_GetProfile }, {N6510_ReplySetProfile, "\x39",0x03,0x04,ID_SetProfile }, {N6510_ReplyGetProfile, "\x39",0x03,0x06,ID_GetProfile }, {N6510_ReplySetLight, "\x3A",0x03,0x06,ID_SetLight }, {N6510_ReplyGetFMStation, "\x3E",0x03,0x06,ID_GetFMStation }, {N6510_ReplyGetFMStatus, "\x3E",0x03,0x0E,ID_GetFMStation }, {N6510_ReplySetFMStation, "\x3E",0x03,0x15,ID_SetFMStation }, {N6510_ReplyGetFMStation, "\x3E",0x03,0x16,ID_GetFMStation }, {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x01,ID_EnableConnectFunc }, {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x02,ID_EnableConnectFunc }, {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x04,ID_DisableConnectFunc }, {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x05,ID_DisableConnectFunc }, {N6510_ReplyGetWAPBookmark, "\x3f",0x03,0x07,ID_GetWAPBookmark }, {N6510_ReplyGetWAPBookmark, "\x3f",0x03,0x08,ID_GetWAPBookmark }, {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0A,ID_SetWAPBookmark }, {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0B,ID_SetWAPBookmark }, {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0D,ID_DeleteWAPBookmark }, {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0E,ID_DeleteWAPBookmark }, {DCT3DCT4_ReplyGetActiveConnectSet,"\x3f",0x03,0x10,ID_GetConnectSet }, {DCT3DCT4_ReplySetActiveConnectSet,"\x3f",0x03,0x13,ID_SetConnectSet }, {N6510_ReplyGetConnectionSettings,"\x3f",0x03,0x16,ID_GetConnectSet }, {N6510_ReplyGetConnectionSettings,"\x3f",0x03,0x17,ID_GetConnectSet }, {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x19,ID_SetConnectSet }, {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x1A,ID_SetConnectSet }, {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x28,ID_SetConnectSet }, {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x2B,ID_SetConnectSet }, {N6510_ReplyGetChatSettings, "\x3f",0x03,0x3B,ID_GetChatSettings }, {N6510_ReplyGetChatSettings, "\x3f",0x03,0x3C,ID_GetChatSettings }, {N6510_ReplyGetOriginalIMEI, "\x42",0x07,0x00,ID_GetOriginalIMEI }, {N6510_ReplyGetManufactureMonth, "\x42",0x07,0x00,ID_GetManufactureMonth }, {N6510_ReplyGetOriginalIMEI, "\x42",0x07,0x01,ID_GetOriginalIMEI }, {N6510_ReplyGetManufactureMonth, "\x42",0x07,0x02,ID_GetManufactureMonth }, {N6510_ReplySetOperatorLogo, "\x43",0x03,0x08,ID_SetBitmap }, {N6510_ReplyGetGPRSAccessPoint, "\x43",0x03,0x06,ID_GetGPRSPoint }, {N6510_ReplySetGPRSAccessPoint1, "\x43",0x03,0x06,ID_SetGPRSPoint }, #ifdef DEVELOP {N6510_ReplyEnableGPRSAccessPoint,"\x43",0x03,0x06,ID_EnableGPRSPoint }, #endif {N6510_ReplyGetSyncMLSettings, "\x43",0x03,0x06,ID_GetSyncMLSettings }, {N6510_ReplyGetSyncMLName, "\x43",0x03,0x06,ID_GetSyncMLName }, {NoneReply, "\x43",0x03,0x08,ID_SetGPRSPoint }, /* 0x4A - voice records */ /* 0x53 - simlock */ {N6510_ReplyAddToDo1, "\x55",0x03,0x02,ID_SetToDo }, {N6510_ReplyGetToDo1, "\x55",0x03,0x04,ID_GetToDo }, {N6510_ReplyGetToDoFirstLoc1, "\x55",0x03,0x10,ID_SetToDo }, {N6510_ReplyDeleteAllToDo1, "\x55",0x03,0x12,ID_DeleteAllToDo }, {N6510_ReplyGetToDoStatus1, "\x55",0x03,0x16,ID_GetToDo }, {N6510_ReplyAddFileHeader, "\x6D",0x03,0x03,ID_AddFile }, {N6510_ReplyAddFolder, "\x6D",0x03,0x05,ID_AddFolder }, {N6510_ReplyGetFilePart, "\x6D",0x03,0x0F,ID_GetFile }, {N6510_ReplyAddFileHeader, "\x6D",0x03,0x13,ID_AddFile }, {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x15,ID_GetFileInfo }, {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x15,ID_GetFile }, {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x15,ID_AddFile }, {N6510_ReplyDeleteFile, "\x6D",0x03,0x19,ID_DeleteFile }, {N6510_ReplyDeleteFile, "\x6D",0x03,0x1F,ID_DeleteFile }, {N6510_ReplyGetFileSystemStatus, "\x6D",0x03,0x23,ID_FileSystemStatus }, {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x2F,ID_GetFileInfo }, {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x2F,ID_GetFile }, {N6510_ReplyGetFileSystemStatus, "\x6D",0x03,0x2F,ID_FileSystemStatus }, {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x33,ID_GetFileInfo }, {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x33,ID_GetFile }, {N6510_ReplyAddFilePart, "\x6D",0x03,0x41,ID_AddFile }, {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x43,ID_AddFile }, {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x43,ID_GetFile }, {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x43,ID_GetFileInfo }, {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x01,ID_GetBitmap }, {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x01,ID_SetBitmap }, {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x0F,ID_GetBitmap }, {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x0F,ID_SetBitmap }, {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x10,ID_GetBitmap }, {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x10,ID_SetBitmap }, {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x25,ID_SetBitmap }, {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetModel }, {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetFirmware }, /* 0xD7 - Bluetooth */ {N6510_ReplyGetRingtoneID, "\xDB",0x03,0x02,ID_SetRingtone }, {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions N6510Phone = { - "1100|1100a|1100b|3100|3100b|3108|3200|3200a|3300|3510|3510i|3530|3589i|3590|3595|5100|5140|6100|6200|6220|6230|6310|6310i|6385|6510|6610|6610i|6800|6810|6820|7210|7250|7250i|7600|8310|8390|8910|8910i", + "1100|1100a|1100b|3100|3100b|3105|3108|3200|3200a|3300|3510|3510i|3530|3589i|3590|3595|5100|5140|6100|6200|6220|6230|6310|6310i|6385|6510|6610|6610i|6800|6810|6820|7210|7250|7250i|7600|8310|8390|8910|8910i", N6510ReplyFunctions, N6510_Initialise, NONEFUNCTION, /* Terminate */ GSM_DispatchMessage, N6510_ShowStartInfo, NOKIA_GetManufacturer, DCT3DCT4_GetModel, DCT3DCT4_GetFirmware, DCT4_GetIMEI, N6510_GetOriginalIMEI, N6510_GetManufactureMonth, DCT4_GetProductCode, DCT4_GetHardware, N6510_GetPPM, NOTSUPPORTED, /* GetSIMIMSI */ N6510_GetDateTime, N6510_SetDateTime, N6510_GetAlarm, N6510_SetAlarm, N6510_GetLocale, NOTSUPPORTED, /* SetLocale */ N6510_PressKey, DCT4_Reset, NOTIMPLEMENTED, /* ResetPhoneSettings */ N6510_EnterSecurityCode, N6510_GetSecurityStatus, NOTSUPPORTED, /* GetDisplayStatus */ NOTIMPLEMENTED, /* SetAutoNetworkLogin */ N6510_GetBatteryCharge, N6510_GetSignalQuality, N6510_GetNetworkInfo, NOTSUPPORTED, /* GetCategory */ NOTSUPPORTED, /* AddCategory */ NOTSUPPORTED, /* GetCategoryStatus */ N6510_GetMemoryStatus, N6510_GetMemory, NOTIMPLEMENTED, /* GetNextMemory */ N6510_SetMemory, NOTIMPLEMENTED, /* AddMemory */ N6510_DeleteMemory, NOTIMPLEMENTED, /* DeleteAllMemory */ N6510_GetSpeedDial, NOTIMPLEMENTED, /* SetSpeedDial */ N6510_GetSMSC, N6510_SetSMSC, N6510_GetSMSStatus, N6510_GetSMSMessage, N6510_GetNextSMSMessage, N6510_SetSMS, N6510_AddSMS, N6510_DeleteSMSMessage, N6510_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ NOTSUPPORTED, /* SetFastSMSSending */ NOKIA_SetIncomingSMS, NOTIMPLEMENTED, /* SetIncomingCB */ N6510_GetSMSFolders, N6510_AddSMSFolder, NOTIMPLEMENTED, /* DeleteSMSFolder */ N6510_DialVoice, N6510_AnswerCall, N6510_CancelCall, NOTIMPLEMENTED, /* HoldCall */ NOTIMPLEMENTED, /* UnholdCall */ NOTIMPLEMENTED, /* ConferenceCall */ NOTIMPLEMENTED, /* SplitCall */ NOTIMPLEMENTED, /* TransferCall */ NOTIMPLEMENTED, /* SwitchCall */ DCT3DCT4_GetCallDivert, DCT3DCT4_SetCallDivert, DCT3DCT4_CancelAllDiverts, NOKIA_SetIncomingCall, NOKIA_SetIncomingUSSD, DCT3DCT4_SendDTMF, N6510_GetRingtone, N6510_SetRingtone, N6510_GetRingtonesInfo, N6510_DeleteUserRingtones, N6510_PlayTone, N6510_GetWAPBookmark, N6510_SetWAPBookmark, N6510_DeleteWAPBookmark, N6510_GetWAPSettings, N6510_SetWAPSettings, N6510_GetMMSSettings, N6510_SetMMSSettings, N6510_GetSyncMLSettings, NOTSUPPORTED, /* SetSyncMLSettings */ N6510_GetChatSettings, NOTSUPPORTED, /* SetChatSettings */ N6510_GetBitmap, N6510_SetBitmap, N6510_GetToDoStatus, NOTIMPLEMENTED, /* GetToDo */ N6510_GetNextToDo, NOTIMPLEMENTED, /* SetToDo */ N6510_AddToDo, N6510_DeleteToDo2, N6510_DeleteAllToDo1, N6510_GetCalendarStatus, NOTIMPLEMENTED, /* GetCalendar */ N6510_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ N6510_AddCalendar, N71_65_DelCalendar, NOTIMPLEMENTED, /* DeleteAllCalendar */ N6510_GetCalendarSettings, NOTSUPPORTED, /* SetCalendarSettings */ + N6510_GetNoteStatus, + NOTIMPLEMENTED, /* GetNote */ N6510_GetNextNote, + NOTIMPLEMENTED, /* SetNote */ + N6510_AddNote, + N6510_DeleteNote, + NOTSUPPORTED, /* DeleteAllNotes */ N6510_GetProfile, N6510_SetProfile, N6510_GetFMStation, N6510_SetFMStation, N6510_ClearFMStations, N6510_GetNextFileFolder, N6510_GetFilePart, N6510_AddFilePart, N6510_GetFileSystemStatus, N6510_DeleteFile, N6510_AddFolder, N6510_GetGPRSAccessPoint, N6510_SetGPRSAccessPoint }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/nokia/nauto.c b/gammu/emb/common/phone/nokia/nauto.c index 3bb53ec..3c7f2cd 100644 --- a/gammu/emb/common/phone/nokia/nauto.c +++ b/gammu/emb/common/phone/nokia/nauto.c @@ -1,144 +1,150 @@ /* (c) 2002-2003 by Marcin Wiacek */ #include <string.h> #include <time.h> #include "../../gsmcomon.h" #include "../../gsmstate.h" #include "nfunc.h" #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4) static GSM_Reply_Function NAUTOReplyFunctions[] = { {DCT3DCT4_ReplyGetModelFirmware,"\xD2",0x02,0x00,ID_GetModel }, {DCT3DCT4_ReplyGetModelFirmware,"\xD2",0x02,0x00,ID_GetFirmware }, {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions NAUTOPhone = { "NAUTO", NAUTOReplyFunctions, NONEFUNCTION, /* Initialise */ NONEFUNCTION, /* Terminate */ GSM_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ NOKIA_GetManufacturer, DCT3DCT4_GetModel, DCT3DCT4_GetFirmware, NOTSUPPORTED, /* GetIMEI */ NOTSUPPORTED, /* GetOriginalIMEI */ NOTSUPPORTED, /* GetManufactureMonth */ NOTSUPPORTED, /* GetProductCode */ NOTSUPPORTED, /* GetHardware */ NOTSUPPORTED, /* GetPPM */ NOTSUPPORTED, /* GetSIMIMSI */ NOTSUPPORTED, /* GetDateTime */ NOTSUPPORTED, /* SetDateTime */ NOTSUPPORTED, /* GetAlarm */ NOTSUPPORTED, /* SetAlarm */ NOTSUPPORTED, /* GetLocale */ NOTSUPPORTED, /* SetLocale */ NOTSUPPORTED, /* PressKey */ NOTSUPPORTED, /* Reset */ NOTSUPPORTED, /* ResetPhoneSettings */ NOTSUPPORTED, /* EnterSecurityCode */ NOTSUPPORTED, /* GetSecurityStatus */ NOTSUPPORTED, /* GetDisplayStatus */ NOTSUPPORTED, /* SetAutoNetworkLogin */ NOTSUPPORTED, /* GetBatteryCharge */ NOTSUPPORTED, /* GetSignalQuality */ NOTSUPPORTED, /* GetNetworkInfo */ NOTSUPPORTED, /* GetCategory */ NOTSUPPORTED, /* AddCategory */ NOTSUPPORTED, /* GetCategoryStatus */ NOTSUPPORTED, /* GetMemoryStatus */ NOTSUPPORTED, /* GetMemory */ NOTSUPPORTED, /* GetNextMemory */ NOTSUPPORTED, /* SetMemory */ NOTSUPPORTED, /* AddMemory */ NOTSUPPORTED, /* DeleteMemory */ NOTIMPLEMENTED, /* DeleteAllMemory */ NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ NOTSUPPORTED, /* GetSMSC */ NOTSUPPORTED, /* SetSMSC */ NOTSUPPORTED, /* GetSMSStatus */ NOTSUPPORTED, /* GetSMS */ NOTSUPPORTED, /* GetNextSMS */ NOTSUPPORTED, /* SetSMS */ NOTSUPPORTED, /* AddSMS */ NOTSUPPORTED, /* DeleteSMS */ NOTSUPPORTED, /* SendSMSMessage */ NOTSUPPORTED, /* SendSavedSMS */ NOTSUPPORTED, /* SetIncomingSMS */ NOTSUPPORTED, /* SetIncomingCB */ NOTSUPPORTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ NOTSUPPORTED, /* DialVoice */ NOTSUPPORTED, /* AnswerCall */ NOTSUPPORTED, /* CancelCall */ NOTSUPPORTED, /* HoldCall */ NOTSUPPORTED, /* UnholdCall */ NOTSUPPORTED, /* ConferenceCall */ NOTSUPPORTED, /* SplitCall */ NOTSUPPORTED, /* TransferCall */ NOTSUPPORTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ NOTSUPPORTED, /* SetCallDivert */ NOTSUPPORTED, /* CancelAllDiverts */ NOTSUPPORTED, /* SetIncomingCall */ NOTSUPPORTED, /* SetIncomingUSSD */ NOTSUPPORTED, /* SendDTMF */ NOTSUPPORTED, /* GetRingtone */ NOTSUPPORTED, /* SetRingtone */ NOTSUPPORTED, /* GetRingtonesInfo */ NOTSUPPORTED, /* DeleteUserRingtones */ NOTSUPPORTED, /* PlayTone */ NOTSUPPORTED, /* GetWAPBookmark */ NOTSUPPORTED, /* SetWAPBookmark */ NOTSUPPORTED, /* DeleteWAPBookmark */ NOTSUPPORTED, /* GetWAPSettings */ NOTSUPPORTED, /* SetWAPSettings */ NOTSUPPORTED, /* GetMMSSettings */ NOTSUPPORTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetBitmap */ NOTSUPPORTED, /* SetBitmap */ NOTSUPPORTED, /* GetToDoStatus */ NOTSUPPORTED, /* GetToDo */ NOTSUPPORTED, /* GetNextToDo */ NOTSUPPORTED, /* SetToDo */ NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ NOTSUPPORTED, /* GetCalendarStatus */ NOTSUPPORTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTSUPPORTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTSUPPORTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ + NOTSUPPORTED, /* GetNoteStatus */ + NOTSUPPORTED, /* GetNote */ NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* SetNote */ + NOTSUPPORTED, /* AddNote */ + NOTSUPPORTED, /* DeleteNote */ + NOTSUPPORTED, /* DeleteAllNotes */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFilePart */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ NOTSUPPORTED /* SetGPRSAccessPoint */ }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/obex/obexgen.c b/gammu/emb/common/phone/obex/obexgen.c index 3106369..b91afac 100644 --- a/gammu/emb/common/phone/obex/obexgen.c +++ b/gammu/emb/common/phone/obex/obexgen.c @@ -1,852 +1,858 @@ /* (c) 2003 by Marcin Wiacek */ /* www.irda.org OBEX specs 1.3 */ /* Module connects to F9EC7BC4-953c-11d2-984E-525400DC9E09 UUID and in the * future there will required implementing reconnecting. See "ifdef xxxx" */ #include <string.h> #include <time.h> #include "../../misc/coding/coding.h" #include "../../gsmcomon.h" #include "../../gsmstate.h" #include "../../service/gsmmisc.h" #include "../../protocol/obex/obex.h" #ifdef GSM_ENABLE_OBEXGEN static GSM_Error OBEXGEN_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, bool start); static void OBEXGEN_FindNextDir(unsigned char *Path, int *Pos, unsigned char *Return) { unsigned char buff[200]; buff[0] = 0; while(1) { if (Path[*Pos] == 0x00) break; if (Path[*Pos] == '\\') { (*Pos)++; break; } buff[strlen(buff)+1] = 0; buff[strlen(buff)] = Path[(*Pos)]; (*Pos)++; } EncodeUnicode(Return,buff,strlen(buff)); } static GSM_Error OBEXGEN_ReplyConnect(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Type) { case 0xA0: smprintf(s,"Connected/disconnected OK\n"); if (msg.Length != 0) { s->Phone.Data.Priv.OBEXGEN.FrameSize = msg.Buffer[2]*256+msg.Buffer[3]; smprintf(s,"Maximal size of frame is %i 0x%x\n",s->Phone.Data.Priv.OBEXGEN.FrameSize,s->Phone.Data.Priv.OBEXGEN.FrameSize); } return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } GSM_Error OBEXGEN_Disconnect(GSM_StateMachine *s) { smprintf(s, "Disconnecting\n"); return GSM_WaitFor (s, NULL, 0, 0x81, 2, ID_Initialise); } GSM_Error OBEXGEN_Connect(GSM_StateMachine *s, OBEX_Service service) { int Current=4; unsigned char req2[200]; unsigned char req[200] = { 0x10, /* Version 1.0 */ 0x00, /* no flags */ 0x20,0x00}; /* 0x2000 max size of packet */ if (service == s->Phone.Data.Priv.OBEXGEN.Service) return ERR_NONE; switch (service) { case OBEX_None: break; case OBEX_BrowsingFolders: /* Server ID */ req2[0] = 0xF9; req2[1] = 0xEC; req2[2] = 0x7B; req2[3] = 0xC4; req2[4] = 0x95; req2[5] = 0x3C; req2[6] = 0x11; req2[7] = 0xD2; req2[8] = 0x98; req2[9] = 0x4E; req2[10]= 0x52; req2[11]= 0x54; req2[12]= 0x00; req2[13]= 0xDC; req2[14]= 0x9E; req2[15]= 0x09; /* Target block */ OBEXAddBlock(req, &Current, 0x46, req2, 16); } #ifndef xxxx //disconnect old service #else if (s->Phone.Data.Priv.OBEXGEN.Service != 0) return ERR_NONE; #endif s->Phone.Data.Priv.OBEXGEN.Service = service; smprintf(s, "Connecting\n"); return GSM_WaitFor (s, req, Current, 0x80, 2, ID_Initialise); } GSM_Error OBEXGEN_Initialise(GSM_StateMachine *s) { // GSM_File File; // GSM_Error error = ERR_NONE; s->Phone.Data.Priv.OBEXGEN.Service = 0; strcpy(s->Phone.Data.Model,"obex"); s->Phone.Data.VerNum = 0; s->Phone.Data.Version[0] = 0; s->Phone.Data.Manufacturer[0] = 0; // File.Used = 0; // File.ID_FullName[0] = 0; // File.Buffer = NULL; // while (error == ERR_NONE) error = OBEXGEN_GetFilePart(s,&File); return ERR_NONE; } static GSM_Error OBEXGEN_ReplyChangePath(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Type) { case 0xA0: smprintf(s,"Path set OK\n"); return ERR_NONE; case 0xA1: smprintf(s,"Folder created\n"); return ERR_NONE; case 0xC3: smprintf(s,"Security error\n"); return ERR_SECURITYERROR; } return ERR_UNKNOWNRESPONSE; } static GSM_Error OBEXGEN_ChangePath(GSM_StateMachine *s, char *Name, unsigned char Flag1) { unsigned char req[400]; int Current = 2; /* Flags */ req[0] = Flag1; req[1] = 0x00; /* Name block */ if (Name != NULL && UnicodeLength(Name) != 0) { OBEXAddBlock(req, &Current, 0x01, Name, UnicodeLength(Name)*2+2); } else { OBEXAddBlock(req, &Current, 0x01, NULL, 0); } /* connection ID block */ req[Current++] = 0xCB; // ID req[Current++] = 0x00; req[Current++] = 0x00; req[Current++] = 0x00; req[Current++] = 0x01; return GSM_WaitFor (s, req, Current, 0x85, 4, ID_SetPath); } static GSM_Error OBEXGEN_ReplyAddFilePart(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Type) { case 0x90: smprintf(s,"Last part of file added OK\n"); return ERR_NONE; case 0xA0: smprintf(s,"Part of file added OK\n"); return ERR_NONE; case 0xC0: smprintf(s,"Not understand. Probably not supported\n"); return ERR_NOTSUPPORTED; } return ERR_UNKNOWNRESPONSE; } GSM_Error OBEXGEN_AddFilePart(GSM_StateMachine *s, GSM_File *File, int *Pos) { GSM_Error error; int j; unsigned int Pos2, Current = 0; unsigned char req[2000],req2[200]; s->Phone.Data.File = File; if (*Pos == 0) { if (!strcmp(File->ID_FullName,"")) { #ifndef xxxx error = OBEXGEN_Connect(s,OBEX_None); #else error = OBEXGEN_Connect(s,OBEX_BrowsingFolders); #endif if (error != ERR_NONE) return error; } else { error = OBEXGEN_Connect(s,OBEX_BrowsingFolders); if (error != ERR_NONE) return error; if (strcmp(s->CurrentConfig->Model,"seobex")) { smprintf(s,"Changing to root\n"); error = OBEXGEN_ChangePath(s, NULL, 2); if (error != ERR_NONE) return error; Pos2 = 0; do { OBEXGEN_FindNextDir(File->ID_FullName, &Pos2, req2); smprintf(s,"%s %i %i\n",DecodeUnicodeString(req2),Pos2,strlen(File->ID_FullName)); smprintf(s,"Changing path down\n"); error=OBEXGEN_ChangePath(s, req2, 2); if (error != ERR_NONE) return error; if (Pos2 == strlen(File->ID_FullName)) break; } while (1); } } /* Name block */ OBEXAddBlock(req, &Current, 0x01, File->Name, UnicodeLength(File->Name)*2+2); /* File size block */ req[Current++] = 0xC3; // ID req[Current++] = 0; req[Current++] = 0; req[Current++] = File->Used / 256; req[Current++] = File->Used % 256; } if (s->Phone.Data.Priv.OBEXGEN.Service == OBEX_BrowsingFolders) { /* connection ID block */ req[Current++] = 0xCB; // ID req[Current++] = 0x00; req[Current++] = 0x00; req[Current++] = 0x00; req[Current++] = 0x01; } j = s->Phone.Data.Priv.OBEXGEN.FrameSize - Current - 20; if (j > 1000) j = 1000; if (File->Used - *Pos < j) { j = File->Used - *Pos; /* End of file body block */ OBEXAddBlock(req, &Current, 0x49, File->Buffer+(*Pos), j); smprintf(s, "Adding file part %i %i\n",*Pos,j); *Pos = *Pos + j; error = GSM_WaitFor (s, req, Current, 0x82, 4, ID_AddFile); if (error != ERR_NONE) return error; return ERR_EMPTY; } else { /* File body block */ OBEXAddBlock(req, &Current, 0x48, File->Buffer+(*Pos), j); smprintf(s, "Adding file part %i %i\n",*Pos,j); *Pos = *Pos + j; error=GSM_WaitFor (s, req, Current, 0x02, 4, ID_AddFile); } return error; } static GSM_Error OBEXGEN_ReplyGetFilePart(GSM_Protocol_Message msg, GSM_StateMachine *s) { int old,Pos=0; switch (msg.Type) { case 0xA0: smprintf(s,"File part received\n"); s->Phone.Data.Priv.OBEXGEN.FileLastPart = true; case 0x90: // if (msg.Length < 11) return ERR_NONE; if (msg.Type == 0x90) smprintf(s,"Last file part received\n"); while(1) { if (Pos >= msg.Length) break; switch (msg.Buffer[Pos]) { case 0x48: case 0x49: smprintf(s,"File part received\n"); old = s->Phone.Data.File->Used; s->Phone.Data.File->Used += msg.Buffer[Pos+1]*256+msg.Buffer[Pos+2]-3; smprintf(s,"Length of file part: %i\n", msg.Buffer[Pos+1]*256+msg.Buffer[Pos+2]-3); s->Phone.Data.File->Buffer = (unsigned char *)realloc(s->Phone.Data.File->Buffer,s->Phone.Data.File->Used); memcpy(s->Phone.Data.File->Buffer+old,msg.Buffer+Pos+3,s->Phone.Data.File->Used-old); return ERR_NONE; default: break; } Pos+=msg.Buffer[Pos+1]*256+msg.Buffer[Pos+2]; } return ERR_UNKNOWNRESPONSE; case 0xC3: return ERR_NOTSUPPORTED; case 0xC4: smprintf(s,"Not found\n"); return ERR_SECURITYERROR; } return ERR_UNKNOWNRESPONSE; } static GSM_Error OBEXGEN_ReplyGetFileInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int old,Pos=0; switch (msg.Type) { case 0x83: smprintf(s,"Not available ?\n"); return ERR_NONE; case 0x90: smprintf(s,"Last part of file info received\n"); return ERR_NONE; case 0xA0: while(1) { if (Pos >= msg.Length) break; switch (msg.Buffer[Pos]) { case 0x48: case 0x49: /* SE T310 */ smprintf(s,"File part received\n"); old = s->Phone.Data.File->Used; s->Phone.Data.File->Used += msg.Buffer[Pos+1]*256+msg.Buffer[Pos+2]-3; smprintf(s,"Length of file part: %i\n", msg.Buffer[Pos+1]*256+msg.Buffer[Pos+2]-3); s->Phone.Data.File->Buffer = (unsigned char *)realloc(s->Phone.Data.File->Buffer,s->Phone.Data.File->Used); memcpy(s->Phone.Data.File->Buffer+old,msg.Buffer+Pos+3,s->Phone.Data.File->Used-old); return ERR_EMPTY; default: break; } Pos+=msg.Buffer[Pos+1]*256+msg.Buffer[Pos+2]; } return ERR_UNKNOWNRESPONSE; } return ERR_UNKNOWNRESPONSE; } static GSM_Error OBEXGEN_PrivGetFilePart(GSM_StateMachine *s, GSM_File *File, bool FolderList) { unsigned int Current = 0, Pos; GSM_Error error; unsigned char req[2000], req2[200]; s->Phone.Data.File = File; File->ReadOnly = false; File->Protected = false; File->Hidden = false; File->System = false; if (File->Used == 0x00) { if (FolderList) { /* Type block */ strcpy(req2,"x-obex/folder-listing"); OBEXAddBlock(req, &Current, 0x42, req2, strlen(req2)+1); /* Name block */ if (UnicodeLength(File->Name) == 0x00) { OBEXAddBlock(req, &Current, 0x01, NULL, 0); } else { CopyUnicodeString(req2,File->Name); OBEXAddBlock(req, &Current, 0x01, req2, UnicodeLength(req2)*2+2); } } else { File->Folder = false; if (File->ID_FullName[0] == 0x00) { #ifndef xxxx error = OBEXGEN_Connect(s,OBEX_None); #else error = OBEXGEN_Connect(s,OBEX_BrowsingFolders); #endif if (error != ERR_NONE) return error; EncodeUnicode(File->Name,"one",3); if (strcmp(s->CurrentConfig->Model,"seobex")) { strcpy(req2,"x-obex/capability"); // strcpy(req2,"x-obex/object-profile"); /* Type block */ OBEXAddBlock(req, &Current, 0x42, req2, strlen(req2)+1); } else { EncodeUnicode(req2,"telecom/devinfo.txt",19); /* Name block */ OBEXAddBlock(req, &Current, 0x01, req2, UnicodeLength(req2)*2+2); } } else { // error = OBEXGEN_Connect(s,OBEX_None); error = OBEXGEN_Connect(s,OBEX_BrowsingFolders); if (error != ERR_NONE) return error; if (strcmp(s->CurrentConfig->Model,"seobex")) { smprintf(s,"Changing to root\n"); error = OBEXGEN_ChangePath(s, NULL, 2); if (error != ERR_NONE) return error; Pos = 0; do { OBEXGEN_FindNextDir(File->ID_FullName, &Pos, req2); smprintf(s,"%s %i %i\n",DecodeUnicodeString(req2),Pos,strlen(File->ID_FullName)); if (Pos == strlen(File->ID_FullName)) break; smprintf(s,"Changing path down\n"); error=OBEXGEN_ChangePath(s, req2, 2); if (error != ERR_NONE) return error; } while (1); } else { EncodeUnicode(req2,File->ID_FullName,strlen(File->ID_FullName)); } CopyUnicodeString(File->Name,req2); s->Phone.Data.File = File; Current = 0; /* Name block */ OBEXAddBlock(req, &Current, 0x01, req2, UnicodeLength(req2)*2+2); } } } if (s->Phone.Data.Priv.OBEXGEN.Service == OBEX_BrowsingFolders) { /* connection ID block */ req[Current++] = 0xCB; // ID req[Current++] = 0x00; req[Current++] = 0x00; req[Current++] = 0x00; req[Current++] = 0x01; } smprintf(s, "Getting file info from filesystem\n"); error=GSM_WaitFor (s, req, Current, 0x03, 4, ID_GetFileInfo); if (error != ERR_NONE) return error; s->Phone.Data.Priv.OBEXGEN.FileLastPart = false; while (!s->Phone.Data.Priv.OBEXGEN.FileLastPart) { Current = 0; if (s->Phone.Data.Priv.OBEXGEN.Service == OBEX_BrowsingFolders) { /* connection ID block */ req[Current++] = 0xCB; // ID req[Current++] = 0x00; req[Current++] = 0x00; req[Current++] = 0x00; req[Current++] = 0x01; } smprintf(s, "Getting file part from filesystem\n"); error=GSM_WaitFor (s, req, Current, 0x83, 4, ID_GetFile); if (error != ERR_NONE) return error; } return ERR_EMPTY; } GSM_Error OBEXGEN_GetFilePart(GSM_StateMachine *s, GSM_File *File) { return OBEXGEN_PrivGetFilePart(s,File,false); } static GSM_Error OBEXGEN_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, bool start) { GSM_Phone_OBEXGENData *Priv = &s->Phone.Data.Priv.OBEXGEN; GSM_Error error; unsigned char Line[500],Line2[500],*name,*size; int Pos,i,j,num,pos2,Current,z; if (start) { if (!strcmp(s->CurrentConfig->Model,"seobex")) return ERR_NOTSUPPORTED; Priv->Files[0].Folder = true; Priv->Files[0].Level = 1; Priv->Files[0].Name[0] = 0; Priv->Files[0].Name[1] = 0; Priv->Files[0].ID_FullName[0] = 0; Priv->Files[0].ID_FullName[1] = 0; Priv->FilesLocationsUsed = 1; Priv->FilesLocationsCurrent = 0; Priv->FileLev = 1; error = OBEXGEN_Connect(s,OBEX_BrowsingFolders); if (error != ERR_NONE) return error; smprintf(s,"Changing to root\n"); error = OBEXGEN_ChangePath(s, NULL, 2); if (error != ERR_NONE) return error; Current = 0; } while (1) { if (Priv->FilesLocationsCurrent == Priv->FilesLocationsUsed) { dbgprintf("Last file\n"); return ERR_EMPTY; } strcpy(File->ID_FullName,Priv->Files[Priv->FilesLocationsCurrent].ID_FullName); File->Level = Priv->Files[Priv->FilesLocationsCurrent].Level; File->Folder = Priv->Files[Priv->FilesLocationsCurrent].Folder; CopyUnicodeString(File->Name,Priv->Files[Priv->FilesLocationsCurrent].Name); Priv->FilesLocationsCurrent++; if (File->Folder) { if (File->Level < Priv->FileLev) { for (i=0;i<File->Level;i++) { smprintf(s,"Changing path up\n"); error=OBEXGEN_ChangePath(s, NULL, 2); if (error != ERR_NONE) return error; } } smprintf(s,"Level %i %i\n",File->Level,Priv->FileLev); File->Buffer = NULL; File->Used = 0; OBEXGEN_PrivGetFilePart(s, File,true); num = 0; Pos = 0; while (1) { MyGetLine(File->Buffer, &Pos, Line, File->Used); if (strlen(Line) == 0) break; name = strstr(Line,"folder name=\""); if (name != NULL) { name += 13; j = 0; while(1) { if (name[j] == '"') break; j++; } name[j] = 0; if (strcmp(name,".")) num++; } name = strstr(Line,"file name=\""); if (name != NULL) num++; } if (num != 0) { i = Priv->FilesLocationsUsed-1; while (1) { if (i==Priv->FilesLocationsCurrent-1) break; memcpy(&Priv->Files[i+num],&Priv->Files[i],sizeof(GSM_File)); i--; } } Pos = 0; pos2 = 0; while (1) { MyGetLine(File->Buffer, &Pos, Line, File->Used); if (strlen(Line) == 0) break; strcpy(Line2,Line); name = strstr(Line2,"folder name=\""); if (name != NULL) { name += 13; j = 0; while(1) { if (name[j] == '"') break; j++; } name[j] = 0; if (strcmp(name,".")) { dbgprintf("copying folder %s to %i parent %i\n",name,Priv->FilesLocationsCurrent+pos2,Priv->FilesLocationsCurrent); strcpy(Priv->Files[Priv->FilesLocationsCurrent+pos2].ID_FullName,File->ID_FullName); if (strlen(File->ID_FullName) != 0) strcat(Priv->Files[Priv->FilesLocationsCurrent+pos2].ID_FullName,"\\"); strcat(Priv->Files[Priv->FilesLocationsCurrent+pos2].ID_FullName,name); Priv->Files[Priv->FilesLocationsCurrent+pos2].Level = File->Level+1; Priv->Files[Priv->FilesLocationsCurrent+pos2].Folder = true; EncodeUnicode(Priv->Files[Priv->FilesLocationsCurrent+pos2].Name,name,strlen(name)); Priv->FilesLocationsUsed++; pos2++; } } strcpy(Line2,Line); name = strstr(Line2,"file name=\""); if (name != NULL) { name += 11; j = 0; while(1) { if (name[j] == '"') break; j++; } name[j] = 0; dbgprintf("copying file %s to %i\n",name,Priv->FilesLocationsCurrent+pos2); Priv->Files[Priv->FilesLocationsCurrent+pos2].Level = File->Level+1; Priv->Files[Priv->FilesLocationsCurrent+pos2].Folder = false; strcpy(Priv->Files[Priv->FilesLocationsCurrent+pos2].ID_FullName,File->ID_FullName); if (strlen(File->ID_FullName) != 0) strcat(Priv->Files[Priv->FilesLocationsCurrent+pos2].ID_FullName,"\\"); strcat(Priv->Files[Priv->FilesLocationsCurrent+pos2].ID_FullName,name); EncodeUnicode(Priv->Files[Priv->FilesLocationsCurrent+pos2].Name,name,strlen(name)); Priv->Files[Priv->FilesLocationsCurrent+pos2].Used = 0; strcpy(Line2,Line); size = strstr(Line2,"size=\""); if (size != NULL) Priv->Files[Priv->FilesLocationsCurrent+pos2].Used = atoi(size+6); Priv->Files[Priv->FilesLocationsCurrent+pos2].ModifiedEmpty = true; strcpy(Line2,Line); size = strstr(Line2,"modified=\""); if (size != NULL) { Priv->Files[Priv->FilesLocationsCurrent+pos2].ModifiedEmpty = false; ReadVCALDateTime(size+10, &Priv->Files[Priv->FilesLocationsCurrent+pos2].Modified); } Priv->FilesLocationsUsed++; pos2++; } } z = Priv->FilesLocationsCurrent; if (z != 1) { while (1) { if (z == Priv->FilesLocationsUsed) break; if (Priv->Files[z].Folder) { if (Priv->Files[z].Level > File->Level) { smprintf(s,"Changing path down\n"); error=OBEXGEN_ChangePath(s, File->Name, 2); if (error != ERR_NONE) return error; } break; } z++; } } Priv->FileLev = File->Level; free(File->Buffer); } else { File->Used = Priv->Files[Priv->FilesLocationsCurrent-1].Used; File->ModifiedEmpty = Priv->Files[Priv->FilesLocationsCurrent-1].ModifiedEmpty; if (!File->ModifiedEmpty) { memcpy(&File->Modified,&Priv->Files[Priv->FilesLocationsCurrent-1].Modified,sizeof(GSM_DateTime)); } File->ReadOnly = false; File->Protected = false; File->Hidden = false; File->System = false; } return ERR_NONE; } } static GSM_Error OBEXGEN_DeleteFile(GSM_StateMachine *s, unsigned char *ID) { GSM_Error error; unsigned int Current = 0, Pos; unsigned char req[200],req2[200]; if (!strcmp(s->CurrentConfig->Model,"seobex")) return ERR_NOTSUPPORTED; error = OBEXGEN_Connect(s,OBEX_BrowsingFolders); if (error != ERR_NONE) return error; smprintf(s,"Changing to root\n"); error = OBEXGEN_ChangePath(s, NULL, 2); if (error != ERR_NONE) return error; Pos = 0; do { OBEXGEN_FindNextDir(ID, &Pos, req2); smprintf(s,"%s %i %i\n",DecodeUnicodeString(req2),Pos,strlen(ID)); if (Pos == strlen(ID)) break; smprintf(s,"Changing path down\n"); error=OBEXGEN_ChangePath(s, req2, 2); if (error != ERR_NONE) return error; } while (1); /* Name block */ OBEXAddBlock(req, &Current, 0x01, req2, UnicodeLength(req2)*2+2); /* connection ID block */ req[Current++] = 0xCB; // ID req[Current++] = 0x00; req[Current++] = 0x00; req[Current++] = 0x00; req[Current++] = 0x01; return GSM_WaitFor (s, req, Current, 0x82, 4, ID_AddFile); } static GSM_Error OBEXGEN_AddFolder(GSM_StateMachine *s, GSM_File *File) { GSM_Error error; unsigned char req2[200]; unsigned int Pos; if (!strcmp(s->CurrentConfig->Model,"seobex")) return ERR_NOTSUPPORTED; error = OBEXGEN_Connect(s,OBEX_BrowsingFolders); if (error != ERR_NONE) return error; smprintf(s,"Changing to root\n"); error = OBEXGEN_ChangePath(s, NULL, 2); if (error != ERR_NONE) return error; Pos = 0; do { OBEXGEN_FindNextDir(File->ID_FullName, &Pos, req2); smprintf(s,"%s %i %i\n",DecodeUnicodeString(req2),Pos,strlen(File->ID_FullName)); smprintf(s,"Changing path down\n"); error=OBEXGEN_ChangePath(s, req2, 2); if (error != ERR_NONE) return error; if (Pos == strlen(File->ID_FullName)) break; } while (1); smprintf(s,"Adding directory\n"); return OBEXGEN_ChangePath(s, File->Name, 0); } GSM_Reply_Function OBEXGENReplyFunctions[] = { /* CONTINUE block */ {OBEXGEN_ReplyAddFilePart, "\x90",0x00,0x00,ID_AddFile }, {OBEXGEN_ReplyGetFilePart, "\x90",0x00,0x00,ID_GetFile }, {OBEXGEN_ReplyGetFileInfo, "\x90",0x00,0x00,ID_GetFileInfo }, /* OK block */ {OBEXGEN_ReplyChangePath, "\xA0",0x00,0x00,ID_SetPath }, {OBEXGEN_ReplyConnect, "\xA0",0x00,0x00,ID_Initialise }, {OBEXGEN_ReplyAddFilePart, "\xA0",0x00,0x00,ID_AddFile }, {OBEXGEN_ReplyGetFilePart, "\xA0",0x00,0x00,ID_GetFile }, {OBEXGEN_ReplyGetFileInfo, "\xA0",0x00,0x00,ID_GetFileInfo }, /* FOLDER CREATED block */ {OBEXGEN_ReplyChangePath, "\xA1",0x00,0x00,ID_SetPath }, /* NOT UNDERSTAND block */ {OBEXGEN_ReplyAddFilePart, "\xC0",0x00,0x00,ID_AddFile }, /* FORBIDDEN block */ {OBEXGEN_ReplyChangePath, "\xC3",0x00,0x00,ID_SetPath }, {OBEXGEN_ReplyGetFilePart, "\xC3",0x00,0x00,ID_GetFile }, /* NOT FOUND block */ {OBEXGEN_ReplyGetFilePart, "\xC4",0x00,0x00,ID_GetFile }, {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions OBEXGENPhone = { "obex|seobex", OBEXGENReplyFunctions, OBEXGEN_Initialise, NONEFUNCTION, /* Terminate */ GSM_DispatchMessage, NOTIMPLEMENTED, /* ShowStartInfo */ NONEFUNCTION, /* GetManufacturer */ NONEFUNCTION, /* GetModel */ NONEFUNCTION, /* GetFirmware */ NOTIMPLEMENTED, /* GetIMEI */ NOTIMPLEMENTED, /* GetOriginalIMEI */ NOTIMPLEMENTED, /* GetManufactureMonth */ NOTIMPLEMENTED, /* GetProductCode */ NOTIMPLEMENTED, /* GetHardware */ NOTIMPLEMENTED, /* GetPPM */ NOTIMPLEMENTED, /* GetSIMIMSI */ NOTIMPLEMENTED, /* GetDateTime */ NOTIMPLEMENTED, /* SetDateTime */ NOTIMPLEMENTED, /* GetAlarm */ NOTIMPLEMENTED, /* SetAlarm */ NOTSUPPORTED, /* GetLocale */ NOTSUPPORTED, /* SetLocale */ NOTIMPLEMENTED, /* PressKey */ NOTIMPLEMENTED, /* Reset */ NOTIMPLEMENTED, /* ResetPhoneSettings */ NOTIMPLEMENTED, /* EnterSecurityCode */ NOTIMPLEMENTED, /* GetSecurityStatus */ NOTIMPLEMENTED, /* GetDisplayStatus */ NOTIMPLEMENTED, /* SetAutoNetworkLogin */ NOTIMPLEMENTED, /* GetBatteryCharge */ NOTIMPLEMENTED, /* GetSignalQuality */ NOTIMPLEMENTED, /* GetNetworkInfo */ NOTIMPLEMENTED, /* GetCategory */ NOTSUPPORTED, /* AddCategory */ NOTIMPLEMENTED, /* GetCategoryStatus */ NOTIMPLEMENTED, /* GetMemoryStatus */ NOTIMPLEMENTED, /* GetMemory */ NOTIMPLEMENTED, /* GetNextMemory */ NOTIMPLEMENTED, /* SetMemory */ NOTIMPLEMENTED, /* AddMemory */ NOTIMPLEMENTED, /* DeleteMemory */ NOTIMPLEMENTED, /* DeleteAllMemory */ NOTIMPLEMENTED, /* GetSpeedDial */ NOTIMPLEMENTED, /* SetSpeedDial */ NOTIMPLEMENTED, /* GetSMSC */ NOTIMPLEMENTED, /* SetSMSC */ NOTIMPLEMENTED, /* GetSMSStatus */ NOTIMPLEMENTED, /* GetSMS */ NOTIMPLEMENTED, /* GetNextSMS */ NOTIMPLEMENTED, /* SetSMS */ NOTIMPLEMENTED, /* AddSMS */ NOTIMPLEMENTED, /* DeleteSMS */ NOTIMPLEMENTED, /* SendSMSMessage */ NOTSUPPORTED, /* SendSavedSMS */ NOTSUPPORTED, /* SetFastSMSSending */ NOTIMPLEMENTED, /* SetIncomingSMS */ NOTIMPLEMENTED, /* SetIncomingCB */ NOTIMPLEMENTED, /* GetSMSFolders */ NOTIMPLEMENTED, /* AddSMSFolder */ NOTIMPLEMENTED, /* DeleteSMSFolder */ NOTIMPLEMENTED, /* DialVoice */ NOTIMPLEMENTED, /* AnswerCall */ NOTIMPLEMENTED, /* CancelCall */ NOTIMPLEMENTED, /* HoldCall */ NOTIMPLEMENTED, /* UnholdCall */ NOTIMPLEMENTED, /* ConferenceCall */ NOTIMPLEMENTED, /* SplitCall */ NOTIMPLEMENTED, /* TransferCall */ NOTIMPLEMENTED, /* SwitchCall */ NOTIMPLEMENTED, /* GetCallDivert */ NOTIMPLEMENTED, /* SetCallDivert */ NOTIMPLEMENTED, /* CancelAllDiverts */ NOTIMPLEMENTED, /* SetIncomingCall */ NOTIMPLEMENTED, /* SetIncomingUSSD */ NOTIMPLEMENTED, /* SendDTMF */ NOTIMPLEMENTED, /* GetRingtone */ NOTIMPLEMENTED, /* SetRingtone */ NOTIMPLEMENTED, /* GetRingtonesInfo */ NOTIMPLEMENTED, /* DeleteUserRingtones */ NOTIMPLEMENTED, /* PlayTone */ NOTIMPLEMENTED, /* GetWAPBookmark */ NOTIMPLEMENTED, /* SetWAPBookmark */ NOTIMPLEMENTED, /* DeleteWAPBookmark */ NOTIMPLEMENTED, /* GetWAPSettings */ NOTIMPLEMENTED, /* SetWAPSettings */ NOTIMPLEMENTED, /* GetMMSSettings */ NOTIMPLEMENTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetSyncMLSettings */ NOTSUPPORTED, /* SetSyncMLSettings */ NOTSUPPORTED, /* GetChatSettings */ NOTSUPPORTED, /* SetChatSettings */ NOTIMPLEMENTED, /* GetBitmap */ NOTIMPLEMENTED, /* SetBitmap */ NOTIMPLEMENTED, /* GetToDoStatus */ NOTIMPLEMENTED, /* GetToDo */ NOTIMPLEMENTED, /* GetNextToDo */ NOTIMPLEMENTED, /* SetToDo */ NOTIMPLEMENTED, /* AddToDo */ NOTIMPLEMENTED, /* DeleteToDo */ NOTIMPLEMENTED, /* DeleteAllToDo */ NOTIMPLEMENTED, /* GetCalendarStatus */ NOTIMPLEMENTED, /* GetCalendar */ NOTIMPLEMENTED, /* GetNextCalendar */ NOTIMPLEMENTED, /* SetCalendar */ NOTIMPLEMENTED, /* AddCalendar */ NOTIMPLEMENTED, /* DeleteCalendar */ NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ + NOTSUPPORTED, /* GetNoteStatus */ + NOTSUPPORTED, /* GetNote */ NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* SetNote */ + NOTSUPPORTED, /* AddNote */ + NOTSUPPORTED, /* DeleteNote */ + NOTSUPPORTED, /* DeleteAllNotes */ NOTIMPLEMENTED, /* GetProfile */ NOTIMPLEMENTED, /* SetProfile */ NOTIMPLEMENTED, /* GetFMStation */ NOTIMPLEMENTED, /* SetFMStation */ NOTIMPLEMENTED, /* ClearFMStations */ OBEXGEN_GetNextFileFolder, OBEXGEN_GetFilePart, OBEXGEN_AddFilePart, NOTIMPLEMENTED, /* GetFileSystemStatus */ OBEXGEN_DeleteFile, OBEXGEN_AddFolder, NOTIMPLEMENTED, /* GetGPRSAccessPoint */ NOTIMPLEMENTED /* SetGPRSAccessPoint */ }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/pfunc.c b/gammu/emb/common/phone/pfunc.c index a03a81d..fe890fc 100644 --- a/gammu/emb/common/phone/pfunc.c +++ b/gammu/emb/common/phone/pfunc.c @@ -1,138 +1,139 @@ /* (c) 2002-2003 by Marcin Wiacek */ #include <string.h> #include <ctype.h> #include "../gsmstate.h" #include "../service/sms/gsmsms.h" #include "../misc/coding/coding.h" /* These SMS layouts are used exactly as written in Nokia DCT3 phones. * In AT module(s) we have to use some layouts to convert AT frame to format * understod by SMS module. To share source the same layouts are used */ GSM_SMSMessageLayout PHONE_SMSDeliver = { 35 /* SMS Text */, 16 /* Phone number */, 0 /* SMSC Number */, 14 /* TPDCS */, 28 /* SendingDateTime */, 255 /* SMSCDateTime */, 255 /* TPStatus */, 15 /* TPUDL */, 255 /* TPVP */, 12 /* firstbyte */, 255 /* TPMR */, 13 /* TPPID */}; GSM_SMSMessageLayout PHONE_SMSSubmit = { 36 /* SMS Text */, 17 /* Phone number */, 0 /* SMSC Number */, 15 /* TPDCS */, 255 /* SendingDateTime */, 255 /* SMSCDateTime */, 255 /* TPStatus */, 16 /* TPUDL */, 29 /* TPVP */, 12 /* firstbyte */, 13 /* TPMR */, 14 /* TPPID */}; GSM_SMSMessageLayout PHONE_SMSStatusReport = { 255 /* SMS Text */, 15 /* Phone number */, 0 /* SMSC Number */, 255 /* TPDCS */, 27 /* SendingDateTime */, 34 /* SMSCDateTime */, 14 /* TPStatus */, 255 /* TPUDL */, 255 /* TPVP */, 12 /* firstbyte */, 13 /* TPMR */, 255 /* TPPID?? */}; GSM_Error PHONE_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders) { folders->Number=2; EncodeUnicode(folders->Folder[0].Name,GetMsg(s->msg,"Inbox"),strlen(GetMsg(s->msg,"Inbox"))); EncodeUnicode(folders->Folder[1].Name,GetMsg(s->msg,"Outbox"),strlen(GetMsg(s->msg,"Outbox"))); folders->Folder[0].InboxFolder = true; folders->Folder[1].InboxFolder = false; folders->Folder[0].Memory = MEM_SM; folders->Folder[1].Memory = MEM_SM; return ERR_NONE; } void GSM_CreateFirmwareNumber(GSM_StateMachine *s) { StringToDouble(s->Phone.Data.Version, &s->Phone.Data.VerNum); dbgprintf("Number version is \"%f\"\n", s->Phone.Data.VerNum); } GSM_Error PHONE_EncodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout, int *length, bool clear) { GSM_Error error; if (SMS->SMSC.Location!=0) { error = s->Phone.Functions->GetSMSC(s, &SMS->SMSC); if (error != ERR_NONE) return error; SMS->SMSC.Location = 0; } if (SMS->PDU == SMS_Deliver) { if (SMS->SMSC.Number[0] == 0x00 && SMS->SMSC.Number[1] == 0x00) { + smprintf(s,"No SMSC in SMS Deliver\n"); return ERR_EMPTYSMSC; } } return GSM_EncodeSMSFrame(SMS, buffer, Layout, length, clear); } GSM_Error PHONE_Terminate(GSM_StateMachine *s) { GSM_Error error; if (s->Phone.Data.EnableIncomingCB==true) { error=s->Phone.Functions->SetIncomingCB(s,false); if (error!=ERR_NONE) return error; } if (s->Phone.Data.EnableIncomingSMS==true) { error=s->Phone.Functions->SetIncomingSMS(s,false); if (error!=ERR_NONE) return error; } return ERR_NONE; } GSM_Error PHONE_RTTLPlayOneNote(GSM_StateMachine *s, GSM_RingNote note, bool first) { int duration, Hz; GSM_Error error; Hz=GSM_RingNoteGetFrequency(note); error=s->Phone.Functions->PlayTone(s,Hz,5,first); if (error!=ERR_NONE) return error; duration = GSM_RingNoteGetFullDuration(note); /* Is it correct ? Experimental values here */ switch (note.Style) { case StaccatoStyle: my_sleep (7500); error=s->Phone.Functions->PlayTone(s,0,0,false); if (error != ERR_NONE) return error; my_sleep ((1400000/note.Tempo*duration)-(7500)); break; case ContinuousStyle: my_sleep (1400000/note.Tempo*duration); break; case NaturalStyle: my_sleep (1400000/note.Tempo*duration-50); error=s->Phone.Functions->PlayTone(s,0,0,false); if (error != ERR_NONE) return error; my_sleep (50); break; } return ERR_NONE; } GSM_Error PHONE_Beep(GSM_StateMachine *s) { GSM_Error error; error=s->Phone.Functions->PlayTone(s, 4000, 5,true); if (error!=ERR_NONE) return error; my_sleep(500); return s->Phone.Functions->PlayTone(s,255*255,0,false); } GSM_Error NoneReply(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s,"None answer\n"); return ERR_NONE; } /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/symbian/mroutgen.c b/gammu/emb/common/phone/symbian/mroutgen.c index a7382cf..63d26cf 100644 --- a/gammu/emb/common/phone/symbian/mroutgen.c +++ b/gammu/emb/common/phone/symbian/mroutgen.c @@ -1,221 +1,227 @@ /* (c) 2003 by Marcin Wiacek */ /* EXPERIMENTAL. NOT FUNCTIONAL */ #include <string.h> #include <time.h> #include "../../gsmcomon.h" #include "../../gsmstate.h" #include "../../misc/coding/coding.h" #include "../../service/gsmmisc.h" #ifdef GSM_ENABLE_MROUTERGEN GSM_Error MROUTERGEN_StartModem(GSM_StateMachine *s) { return ERR_NONE; } GSM_Error MROUTERGEN_Initialise(GSM_StateMachine *s) { unsigned char req2[]={0xFF,0x03,0x80,0xFD,0x04,0x01,0x00,0x09,0x11, 0x05,0x00,0x01,0x03,0x77,0xBC}; unsigned char req0[]={ 0xFF,0x7D,0x23,0xC0,0x21,0x7D,0x21,0x7D,0x24,0x7D, 0x20,0x7D,0x2E,0x7D,0x22,0x7D,0x26,0x7D,0x20,0x7D, 0x20,0x7D,0x20,0x7D,0x20,0x7D,0x27,0x7D,0x22,0x7D, 0x28,0x7D,0x22,0x69,0x27, 0x7E, 0x7E, 0xFF,0x7D,0x23,0xC0,0x21,0x7D,0x22,0x7D,0x21,0x7D, 0x20,0x7D,0x34,0x7D,0x25,0x7D,0x26,0x87,0xB9,0x7D, 0x28,0xCF,0x7D,0x22,0x7D,0x26,0x7D,0x20,0x7D,0x20, 0x7D,0x20,0x7D,0x20,0x7D,0x27,0x7D,0x22,0x7D,0x28, 0x7D,0x22,0x82,0xB0, 0x7E, 0x7E, 0xFF,0x7D,0x23,0xC0,0x21,0x7D,0x21,0x7D,0x24,0x7D, 0x20,0x7D,0x2E,0x7D,0x22,0x7D,0x26,0x7D,0x20,0x7D, 0x20,0x7D,0x20,0x7D,0x20,0x7D,0x27,0x7D,0x22,0x7D, 0x28,0x7D,0x22,0x69,0x27, 0x7E, 0x7E, 0xFF,0x7D,0x23,0xC0,0x21,0x7D,0x22,0x7D,0x21,0x7D, 0x20,0x7D,0x34,0x7D,0x25,0x7D,0x26,0x87,0xB9,0x7D, 0x28,0xCF,0x7D,0x22,0x7D,0x26,0x7D,0x20,0x7D,0x20, 0x7D,0x20,0x7D,0x20,0x7D,0x27,0x7D,0x22,0x7D,0x28, 0x7D,0x22,0x82,0xB0}; unsigned char req[]={0x2F,0x45,0x00,0x00,0x34,0x00,0xC6, 0x00,0x00,0x0A,0x0D,0x59,0xB4,0xA9,0xFE,0x01, 0x44,0xA9,0xFE,0x01,0x0A,0x04,0x09,0x0B,0xB8, 0x10,0x00,0x02,0x79,0x69,0x81,0x74,0x99,0x50, 0x18,0x60,0x00,0x9D,0x0C,0x00,0x00,0x08,0x00, 0x00,0x00,0x12,0x00,0x41,0x00,0x01,0x14,0x00, 0x00,0xBA,0x4A}; unsigned char req3[]={0x2D,0x5C,0x0D,0xEC,0x4C,0x10,0x26,0x08,0x00, 0x00,0x00,0x12,0x00,0x15,0x00,0x01,0x08,0x00,0x00, 0xAD,0xDE}; smprintf(s,"writing\n"); GSM_WaitFor (s, req0, 164, 0x00, 200, ID_Initialise); smprintf(s,"writing\n"); GSM_WaitFor (s, req3, 21, 0x00, 200, ID_Initialise); GSM_WaitFor (s, req, 55, 0x00, 200, ID_Initialise); GSM_WaitFor (s, req2, 15, 0x00, 200, ID_Initialise); while (1) { GSM_ReadDevice(s,false); } while (1) { GSM_ReadDevice(s,false); } return ERR_UNKNOWN; } static GSM_Reply_Function MROUTERGENReplyFunctions[] = { {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions MROUTERGENPhone = { "mrouter", MROUTERGENReplyFunctions, MROUTERGEN_Initialise, NONEFUNCTION, /* Terminate */ GSM_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ NONEFUNCTION, /* GetManufacturer */ NONEFUNCTION, /* GetModel */ NONEFUNCTION, /* GetFirmware */ NOTIMPLEMENTED, /* GetIMEI */ NOTSUPPORTED, /* GetOriginalIMEI */ NOTSUPPORTED, /* GetManufactureMonth */ NOTSUPPORTED, /* GetProductCode */ NOTSUPPORTED, /* GetHardware */ NOTSUPPORTED, /* GetPPM */ NOTSUPPORTED, /* GetSIMIMSI */ NOTSUPPORTED, /* GetDateTime */ NOTSUPPORTED, /* SetDateTime */ NOTSUPPORTED, /* GetAlarm */ NOTSUPPORTED, /* SetAlarm */ NOTSUPPORTED, /* GetLocale */ NOTSUPPORTED, /* SetLocale */ NOTSUPPORTED, /* PressKey */ NOTSUPPORTED, /* Reset */ NOTSUPPORTED, /* ResetPhoneSettings */ NOTSUPPORTED, /* EnterSecurityCode */ NOTSUPPORTED, /* GetSecurityStatus */ NOTSUPPORTED, /* GetDisplayStatus */ NOTSUPPORTED, /* SetAutoNetworkLogin */ NOTSUPPORTED, /* GetBatteryCharge */ NOTSUPPORTED, /* GetSignalQuality */ NOTSUPPORTED, /* GetNetworkInfo */ NOTSUPPORTED, /* GetCategory */ NOTSUPPORTED, /* GetCategoryStatus */ NOTSUPPORTED, /* GetMemoryStatus */ NOTSUPPORTED, /* GetMemory */ NOTSUPPORTED, /* GetNextMemory */ NOTSUPPORTED, /* SetMemory */ NOTSUPPORTED, /* AddMemory */ NOTSUPPORTED, /* DeleteMemory */ NOTIMPLEMENTED, /* DeleteAllMemory */ NOTSUPPORTED, /* GetSpeedDial */ NOTSUPPORTED, /* SetSpeedDial */ NOTSUPPORTED, /* GetSMSC */ NOTSUPPORTED, /* SetSMSC */ NOTSUPPORTED, /* GetSMSStatus */ NOTSUPPORTED, /* GetSMS */ NOTSUPPORTED, /* GetNextSMS */ NOTSUPPORTED, /* SetSMS */ NOTSUPPORTED, /* AddSMS */ NOTSUPPORTED, /* DeleteSMS */ NOTSUPPORTED, /* SendSMSMessage */ NOTSUPPORTED, /* SendSavedSMS */ NOTSUPPORTED, /* SetFastSMSSending */ NOTSUPPORTED, /* SetIncomingSMS */ NOTSUPPORTED, /* SetIncomingCB */ NOTSUPPORTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ NOTSUPPORTED, /* DialVoice */ NOTSUPPORTED, /* AnswerCall */ NOTSUPPORTED, /* CancelCall */ NOTSUPPORTED, /* HoldCall */ NOTSUPPORTED, /* UnholdCall */ NOTSUPPORTED, /* ConferenceCall */ NOTSUPPORTED, /* SplitCall */ NOTSUPPORTED, /* TransferCall */ NOTSUPPORTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ NOTSUPPORTED, /* SetCallDivert */ NOTSUPPORTED, /* CancelAllDiverts */ NOTSUPPORTED, /* SetIncomingCall */ NOTSUPPORTED, /* SetIncomingUSSD */ NOTSUPPORTED, /* SendDTMF */ NOTSUPPORTED, /* GetRingtone */ NOTSUPPORTED, /* SetRingtone */ NOTSUPPORTED, /* GetRingtonesInfo */ NOTSUPPORTED, /* DeleteUserRingtones */ NOTSUPPORTED, /* PlayTone */ NOTSUPPORTED, /* GetWAPBookmark */ NOTSUPPORTED, /* SetWAPBookmark */ NOTSUPPORTED, /* DeleteWAPBookmark */ NOTSUPPORTED, /* GetWAPSettings */ NOTSUPPORTED, /* SetWAPSettings */ NOTSUPPORTED, /* GetMMSSettings */ NOTSUPPORTED, /* SetMMSSettings */ NOTSUPPORTED, /* GetSyncMLSettings */ NOTSUPPORTED, /* SetSyncMLSettings */ NOTSUPPORTED, /* GetChatSettings */ NOTSUPPORTED, /* SetChatSettings */ NOTSUPPORTED, /* GetBitmap */ NOTSUPPORTED, /* SetBitmap */ NOTSUPPORTED, /* GetToDoStatus */ NOTSUPPORTED, /* GetToDo */ NOTSUPPORTED, /* GetNextToDo */ NOTSUPPORTED, /* SetToDo */ NOTSUPPORTED, /* AddToDo */ NOTSUPPORTED, /* DeleteToDo */ NOTSUPPORTED, /* DeleteAllToDo */ NOTSUPPORTED, /* GetCalendarStatus */ NOTSUPPORTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTSUPPORTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTSUPPORTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ + NOTSUPPORTED, /* GetNoteStatus */ + NOTSUPPORTED, /* GetNote */ NOTSUPPORTED, /* GetNextNote */ + NOTSUPPORTED, /* SetNote */ + NOTSUPPORTED, /* AddNote */ + NOTSUPPORTED, /* DeleteNote */ + NOTSUPPORTED, /* DeleteAllNotes */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFilePart */ NOTSUPPORTED, /* GetFileSystemStatus */ NOTSUPPORTED, /* DeleteFile */ NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ NOTSUPPORTED /* SetGPRSAccessPoint */ }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/protocol/nokia/fbus2.c b/gammu/emb/common/protocol/nokia/fbus2.c index 2b41f8b..967eaa4 100644 --- a/gammu/emb/common/protocol/nokia/fbus2.c +++ b/gammu/emb/common/protocol/nokia/fbus2.c @@ -1,448 +1,458 @@ /* (c) 2002-2003 by Marcin Wiacek */ /* based on some work from MyGnokii (www.mwiacek.com) */ /* Based on some work from Gnokii (www.gnokii.org) * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot * GNU GPL version 2 or later */ +/* Due to a problem in the source code management, the names of some of + * the authors have unfortunately been lost. We do not mean to belittle + * their efforts and hope they will contact us to see their names + * properly added to the Copyright notice above. + * Having published their contributions under the terms of the GNU + * General Public License (GPL) [version 2], the Copyright of these + * authors will remain respected by adhering to the license they chose + * to publish their code under. + */ #include "../../gsmstate.h" #if defined(GSM_ENABLE_FBUS2) || defined(GSM_ENABLE_FBUS2IRDA) || defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2BLUE) || defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2DKU5) || defined(GSM_ENABLE_FBUS2PL2303) #include <stdio.h> #include <string.h> #include "../../gsmcomon.h" #include "fbus2.h" static GSM_Error FBUS2_WriteFrame(GSM_StateMachine *s, unsigned char *MsgBuffer, int MsgLength, unsigned char MsgType) { unsigned char buffer2[FBUS2_MAX_TRANSMIT_LENGTH + 10]; unsigned char checksum=0; int i, len, sent; buffer2[0] = FBUS2_FRAME_ID; if (s->ConnectionType==GCT_FBUS2IRDA) buffer2[0] = FBUS2_IRDA_FRAME_ID; buffer2[1] = FBUS2_DEVICE_PHONE; //destination buffer2[2] = FBUS2_DEVICE_PC; //source buffer2[3] = MsgType; buffer2[4] = MsgLength / 256; buffer2[5] = MsgLength % 256; memcpy(buffer2 + 6, MsgBuffer, MsgLength); len = MsgLength + 6; /* Odd messages require additional 0x00 byte */ if (MsgLength % 2) buffer2[len++] = 0x00; checksum = 0; for (i = 0; i < len; i+=2) checksum ^= buffer2[i]; buffer2[len++] = checksum; checksum = 0; for (i = 1; i < len; i+=2) checksum ^= buffer2[i]; buffer2[len++] = checksum; /* Sending to phone */ sent=s->Device.Functions->WriteDevice(s,buffer2,len); if (sent!=len) return ERR_DEVICEWRITEERROR; return ERR_NONE; } static GSM_Error FBUS2_WriteMessage (GSM_StateMachine *s, unsigned char *MsgBuffer, int MsgLength, unsigned char MsgType) { int i, nom, togo, thislength; /* number of messages, ... */ unsigned char buffer2[FBUS2_MAX_TRANSMIT_LENGTH + 2], seqnum; GSM_Protocol_FBUS2Data *d = &s->Protocol.Data.FBUS2; GSM_Error error; GSM_DumpMessageLevel3(s, MsgBuffer, MsgLength, MsgType); nom = (MsgLength + FBUS2_MAX_TRANSMIT_LENGTH - 1) / FBUS2_MAX_TRANSMIT_LENGTH; togo = MsgLength; for (i = 0; i < nom; i++) { seqnum = d->MsgSequenceNumber; if (i==0) seqnum = seqnum + 0x40; d->MsgSequenceNumber = (d->MsgSequenceNumber + 1) & 0x07; thislength = togo; if (togo > FBUS2_MAX_TRANSMIT_LENGTH) thislength = FBUS2_MAX_TRANSMIT_LENGTH; memcpy(buffer2, MsgBuffer + (MsgLength - togo), thislength); buffer2[thislength] = nom - i; buffer2[thislength + 1] = seqnum; togo = togo - thislength; GSM_DumpMessageLevel2(s, buffer2, thislength, MsgType); error=FBUS2_WriteFrame(s, buffer2, thislength + 2, MsgType); if (error!=ERR_NONE) return error; } return ERR_NONE; } static GSM_Error FBUS2_SendAck(GSM_StateMachine *s, unsigned char MsgType, unsigned char MsgSequence) { unsigned char buffer2[2]; buffer2[0] = MsgType; buffer2[1] = MsgSequence; if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) { smprintf(s,"[Sending Ack of type %02x, seq %x]\n",buffer2[0],buffer2[1]); } /* Sending to phone */ return FBUS2_WriteFrame(s, buffer2, 2, FBUS2_ACK_BYTE); } static GSM_Error FBUS2_StateMachine(GSM_StateMachine *s, unsigned char rx_char) { GSM_Protocol_FBUS2Data *d = &s->Protocol.Data.FBUS2; unsigned char frm_num, seq_num; bool correct = false; /* XOR the byte with the earlier checksum */ d->Msg.CheckSum[d->Msg.Count & 1] ^= rx_char; if (d->MsgRXState == RX_GetMessage) { d->Msg.Buffer[d->Msg.Count] = rx_char; d->Msg.Count++; /* This is not last byte in frame */ if (d->Msg.Count != d->Msg.Length+(d->Msg.Length%2)+2) return ERR_NONE; /* Checksum is incorrect */ if (d->Msg.CheckSum[0] != d->Msg.CheckSum[1]) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { smprintf(s,"[ERROR: checksum]\n"); } free(d->Msg.Buffer); d->Msg.Length = 0; d->Msg.Buffer = NULL; d->MsgRXState = RX_Sync; return ERR_NONE; } seq_num = d->Msg.Buffer[d->Msg.Length-1]; if (d->Msg.Type == FBUS2_ACK_BYTE) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) { smprintf(s, "[Received Ack of type %02x, seq %02x]\n",d->Msg.Buffer[0],seq_num); } + free(d->Msg.Buffer); d->MsgRXState = RX_Sync; return ERR_NONE; } frm_num = d->Msg.Buffer[d->Msg.Length-2]; if ((seq_num & 0x40) == 0x40) { d->FramesToGo = frm_num; d->MultiMsg.Length = 0; d->MultiMsg.Type = d->Msg.Type; d->MultiMsg.Destination = d->Msg.Destination; d->MultiMsg.Source = d->Msg.Source; } if ((seq_num & 0x40) != 0x40 && d->FramesToGo != frm_num) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { smprintf(s, "[ERROR: Missed part of multiframe msg]\n"); } free(d->Msg.Buffer); d->Msg.Length = 0; d->Msg.Buffer = NULL; d->MsgRXState = RX_Sync; return ERR_NONE; } if ((seq_num & 0x40) != 0x40 && d->Msg.Type != d->MultiMsg.Type) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { smprintf(s, "[ERROR: Multiframe msg in multiframe msg]\n"); } free(d->Msg.Buffer); d->Msg.Length = 0; d->Msg.Buffer = NULL; d->MsgRXState = RX_Sync; return ERR_NONE; } if (d->MultiMsg.BufferUsed < d->MultiMsg.Length+d->Msg.Length-2) { d->MultiMsg.BufferUsed = d->MultiMsg.Length+d->Msg.Length-2; d->MultiMsg.Buffer = (unsigned char *)realloc(d->MultiMsg.Buffer,d->MultiMsg.BufferUsed); } memcpy(d->MultiMsg.Buffer+d->MultiMsg.Length,d->Msg.Buffer,d->Msg.Length-2); d->MultiMsg.Length = d->MultiMsg.Length+d->Msg.Length-2; free(d->Msg.Buffer); d->Msg.Length = 0; d->Msg.Buffer = NULL; d->FramesToGo--; /* do not ack debug trace, as this could generate a * (feedback loop) flood of which even Noah would be scared. */ if (d->Msg.Type != 0) { FBUS2_SendAck(s,d->Msg.Type,((unsigned char)(seq_num & 0x0f))); } if (d->FramesToGo == 0) { s->Phone.Data.RequestMsg = &d->MultiMsg; s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s); } d->MsgRXState = RX_Sync; return ERR_NONE; } if (d->MsgRXState == RX_GetLength2) { d->Msg.Length = d->Msg.Length + rx_char; d->Msg.Buffer = (unsigned char *)malloc(d->Msg.Length+3); d->MsgRXState = RX_GetMessage; return ERR_NONE; } if (d->MsgRXState == RX_GetLength1) { d->Msg.Length = rx_char * 256; d->MsgRXState = RX_GetLength2; return ERR_NONE; } if (d->MsgRXState == RX_GetType) { d->Msg.Type = rx_char; d->MsgRXState = RX_GetLength1; return ERR_NONE; } if (d->MsgRXState == RX_GetSource) { if (rx_char != FBUS2_DEVICE_PHONE) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, FBUS2_DEVICE_PHONE); } d->MsgRXState = RX_Sync; return ERR_NONE; } d->Msg.Source = rx_char; d->MsgRXState = RX_GetType; return ERR_NONE; } if (d->MsgRXState == RX_GetDestination) { if (rx_char != FBUS2_DEVICE_PC) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, FBUS2_DEVICE_PC); } d->MsgRXState = RX_Sync; return ERR_NONE; } d->Msg.Destination = rx_char; d->MsgRXState = RX_GetSource; return ERR_NONE; } if (d->MsgRXState == RX_Sync) { switch (s->ConnectionType) { case GCT_FBUS2: case GCT_FBUS2DLR3: case GCT_FBUS2DKU5: case GCT_FBUS2PL2303: case GCT_FBUS2BLUE: case GCT_BLUEFBUS2: if (rx_char == FBUS2_FRAME_ID) correct = true; break; case GCT_FBUS2IRDA: if (rx_char == FBUS2_IRDA_FRAME_ID) correct = true; break; default: break; } if (!correct) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { if (s->ConnectionType==GCT_FBUS2IRDA) { smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, FBUS2_IRDA_FRAME_ID); } else { smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, FBUS2_FRAME_ID); } } return ERR_NONE; } d->Msg.CheckSum[0] = rx_char; d->Msg.CheckSum[1] = 0; d->Msg.Count = 0; d->MsgRXState = RX_GetDestination; return ERR_NONE; } return ERR_NONE; } #if defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2DKU5) || defined(GSM_ENABLE_FBUS2BLUE) || defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2PL2303) static void FBUS2_WriteDLR3(GSM_StateMachine *s, char *command, int length, int timeout) { unsigned char buff[300]; int w = 0; bool wassomething = false; s->Device.Functions->WriteDevice(s,command,length); for (w=0;w<timeout;w++) { if (wassomething) { if (s->Device.Functions->ReadDevice(s, buff, 255)==0) return; } else { if (s->Device.Functions->ReadDevice(s, buff, 255)>0) wassomething = true; } my_sleep(50); } } #endif static GSM_Error FBUS2_Initialise(GSM_StateMachine *s) { unsigned char init_char = 0x55; #ifdef GSM_ENABLE_FBUS2IRDA unsigned char end_init_char = 0xc1; #endif GSM_Protocol_FBUS2Data *d = &s->Protocol.Data.FBUS2; GSM_Device_Functions *Device = s->Device.Functions; GSM_Error error; int count; d->Msg.Length = 0; d->Msg.Buffer = NULL; d->MultiMsg.BufferUsed = 0; d->MultiMsg.Length = 0; d->MultiMsg.Buffer = NULL; d->MsgSequenceNumber = 0; d->FramesToGo = 0; d->MsgRXState = RX_Sync; error=Device->DeviceSetParity(s,false); if (error!=ERR_NONE) return error; switch (s->ConnectionType) { #if defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2BLUE) case GCT_FBUS2BLUE: case GCT_BLUEFBUS2: FBUS2_WriteDLR3(s,"AT\r\n", 4,10); FBUS2_WriteDLR3(s,"AT&F\r\n", 6,10); FBUS2_WriteDLR3(s,"AT*NOKIAFBUS\r\n", 14,10); break; #endif #if defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2DKU5) || defined(GSM_ENABLE_FBUS2PL2303) case GCT_FBUS2DKU5: case GCT_FBUS2PL2303: case GCT_FBUS2DLR3: error=Device->DeviceSetDtrRts(s,false,false); if (error!=ERR_NONE) return error; my_sleep(1000); error=Device->DeviceSetDtrRts(s,true,true); if (error!=ERR_NONE) return error; error=Device->DeviceSetSpeed(s,19200); if (error!=ERR_NONE) return error; FBUS2_WriteDLR3(s,"AT\r\n", 4,10); FBUS2_WriteDLR3(s,"AT&F\r\n", 6,10); FBUS2_WriteDLR3(s,"AT*NOKIAFBUS\r\n", 14,10); error=Device->CloseDevice(s); if (error!=ERR_NONE) return error; my_sleep(1000); error=Device->OpenDevice(s); if (error!=ERR_NONE) return error; error=Device->DeviceSetParity(s,false); if (error!=ERR_NONE) return error; error=Device->DeviceSetSpeed(s,115200); if (error!=ERR_NONE) return error; error=Device->DeviceSetDtrRts(s,false,false); if (error!=ERR_NONE) return error; for (count = 0; count < 55; count ++) { if (Device->WriteDevice(s,&init_char,1)!=1) return ERR_DEVICEWRITEERROR; } break; #endif case GCT_FBUS2: error=Device->DeviceSetSpeed(s,115200); if (error!=ERR_NONE) return error; error=Device->DeviceSetDtrRts(s,true,false); /*DTR high,RTS low*/ if (error!=ERR_NONE) return error; for (count = 0; count < 55; count ++) { if (Device->WriteDevice(s,&init_char,1)!=1) return ERR_DEVICEWRITEERROR; my_sleep(10); } break; #ifdef GSM_ENABLE_FBUS2IRDA case GCT_FBUS2IRDA: error=Device->DeviceSetSpeed(s,9600); if (error!=ERR_NONE) return error; for (count = 0; count < 55; count ++) { if (Device->WriteDevice(s,&init_char,1)!=1) return ERR_DEVICEWRITEERROR; my_sleep(10); } if (Device->WriteDevice(s,&end_init_char,1)!=1) return ERR_DEVICEWRITEERROR; my_sleep(20); error=Device->DeviceSetSpeed(s,115200); if (error!=ERR_NONE) return error; break; #endif default: break; } return ERR_NONE; } static GSM_Error FBUS2_Terminate(GSM_StateMachine *s) { free(s->Protocol.Data.FBUS2.Msg.Buffer); free(s->Protocol.Data.FBUS2.MultiMsg.Buffer); my_sleep(200); return ERR_NONE; } GSM_Protocol_Functions FBUS2Protocol = { FBUS2_WriteMessage, FBUS2_StateMachine, FBUS2_Initialise, FBUS2_Terminate }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/protocol/nokia/fbus2.h b/gammu/emb/common/protocol/nokia/fbus2.h index 8dbcb07..3d31006 100644 --- a/gammu/emb/common/protocol/nokia/fbus2.h +++ b/gammu/emb/common/protocol/nokia/fbus2.h @@ -1,42 +1,51 @@ /* (c) 2002-2003 by Marcin Wiacek */ /* based on some work from MyGnokii (www.mwiacek.com) */ /* Based on some work from Gnokii (www.gnokii.org) * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot * GNU GPL version 2 or later */ +/* Due to a problem in the source code management, the names of some of + * the authors have unfortunately been lost. We do not mean to belittle + * their efforts and hope they will contact us to see their names + * properly added to the Copyright notice above. + * Having published their contributions under the terms of the GNU + * General Public License (GPL) [version 2], the Copyright of these + * authors will remain respected by adhering to the license they chose + * to publish their code under. + */ #ifndef fbus2_h #define fbus2_h #include "../protocol.h" #define FBUS2_FRAME_ID 0x1e #define FBUS2_IRDA_FRAME_ID 0x1c #define FBUS2_DEVICE_PHONE 0x00 /* Nokia mobile phone */ #define FBUS2_DEVICE_PC 0x0c /* Our PC */ #define FBUS2_ACK_BYTE 0x7f /* Acknowledge of the received frame */ #define FBUS2_MAX_TRANSMIT_LENGTH 120 typedef struct { int MsgSequenceNumber; int MsgRXState; int FramesToGo; GSM_Protocol_Message MultiMsg; GSM_Protocol_Message Msg; } GSM_Protocol_FBUS2Data; #ifndef GSM_USED_SERIALDEVICE # define GSM_USED_SERIALDEVICE #endif #if defined(GSM_ENABLE_BLUEFBUS2) # ifndef GSM_USED_BLUETOOTHDEVICE # define GSM_USED_BLUETOOTHDEVICE # endif #endif #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/protocol/nokia/phonet.c b/gammu/emb/common/protocol/nokia/phonet.c index db5bd72..495a1bf 100644 --- a/gammu/emb/common/protocol/nokia/phonet.c +++ b/gammu/emb/common/protocol/nokia/phonet.c @@ -1,220 +1,229 @@ /* (c) 2002-2003 by Marcin Wiacek */ /* Based on some work from Gnokii (www.gnokii.org) * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot * GNU GPL version 2 or later */ +/* Due to a problem in the source code management, the names of some of + * the authors have unfortunately been lost. We do not mean to belittle + * their efforts and hope they will contact us to see their names + * properly added to the Copyright notice above. + * Having published their contributions under the terms of the GNU + * General Public License (GPL) [version 2], the Copyright of these + * authors will remain respected by adhering to the license they chose + * to publish their code under. + */ #include "../../gsmstate.h" #if defined(GSM_ENABLE_IRDA) || defined(GSM_ENABLE_PHONETBLUE) || defined(GSM_ENABLE_BLUEPHONET) #include <stdio.h> #include <string.h> #include "../../gsmcomon.h" #include "phonet.h" static GSM_Error PHONET_WriteMessage (GSM_StateMachine *s, unsigned char *MsgBuffer, int MsgLength, unsigned char MsgType) { unsigned char *buffer2; int sent; GSM_DumpMessageLevel3(s, MsgBuffer, MsgLength, MsgType); buffer2 = (unsigned char *)malloc(MsgLength + 6); buffer2[0] = PHONET_FRAME_ID, buffer2[1] = PHONET_DEVICE_PHONE; //destination buffer2[2] = PHONET_DEVICE_PC; //source if (s->ConnectionType==GCT_PHONETBLUE || s->ConnectionType==GCT_BLUEPHONET) { buffer2[0] = PHONET_BLUE_FRAME_ID; buffer2[1] = PHONET_DEVICE_PHONE; //destination buffer2[2] = PHONET_BLUE_DEVICE_PC; //source } buffer2[3] = MsgType; buffer2[4] = MsgLength / 256; buffer2[5] = MsgLength % 256; memcpy(buffer2 + 6, MsgBuffer, MsgLength); GSM_DumpMessageLevel2(s, buffer2+6, MsgLength, MsgType); /* Sending to phone */ sent = s->Device.Functions->WriteDevice(s,buffer2,MsgLength+6); free(buffer2); if (sent!=MsgLength+6) return ERR_DEVICEWRITEERROR; return ERR_NONE; } static GSM_Error PHONET_StateMachine(GSM_StateMachine *s, unsigned char rx_char) { GSM_Protocol_PHONETData *d = &s->Protocol.Data.PHONET; bool correct = false; if (d->MsgRXState==RX_GetMessage) { d->Msg.Buffer[d->Msg.Count] = rx_char; d->Msg.Count++; /* This is not last byte in frame */ if (d->Msg.Count != d->Msg.Length) return ERR_NONE; s->Phone.Data.RequestMsg = &d->Msg; s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s); free(d->Msg.Buffer); d->Msg.Length = 0; d->Msg.Buffer = NULL; d->MsgRXState = RX_Sync; return ERR_NONE; } if (d->MsgRXState==RX_GetLength2) { d->Msg.Length = d->Msg.Length + rx_char; d->Msg.Buffer = (unsigned char *)malloc(d->Msg.Length); d->MsgRXState = RX_GetMessage; return ERR_NONE; } if (d->MsgRXState==RX_GetLength1) { d->Msg.Length = rx_char * 256; d->MsgRXState = RX_GetLength2; return ERR_NONE; } if (d->MsgRXState==RX_GetType) { d->Msg.Type = rx_char; d->MsgRXState = RX_GetLength1; return ERR_NONE; } if (d->MsgRXState==RX_GetSource) { if (rx_char != PHONET_DEVICE_PHONE) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, PHONET_DEVICE_PHONE); } d->MsgRXState = RX_Sync; return ERR_NONE; } d->Msg.Source = rx_char; d->MsgRXState = RX_GetType; return ERR_NONE; } if (d->MsgRXState==RX_GetDestination) { switch (s->ConnectionType) { case GCT_IRDAPHONET: if (rx_char == PHONET_DEVICE_PC) correct = true; break; case GCT_PHONETBLUE: case GCT_BLUEPHONET: if (rx_char == PHONET_BLUE_DEVICE_PC) correct = true; break; default: break; } if (!correct) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, PHONET_DEVICE_PC); } d->MsgRXState = RX_Sync; return ERR_NONE; } d->Msg.Destination = rx_char; d->MsgRXState = RX_GetSource; return ERR_NONE; } if (d->MsgRXState==RX_Sync) { switch (s->ConnectionType) { case GCT_IRDAPHONET: if (rx_char == PHONET_FRAME_ID) correct = true; break; case GCT_PHONETBLUE: case GCT_BLUEPHONET: if (rx_char == PHONET_BLUE_FRAME_ID) correct = true; break; default: break; } if (!correct) { if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { smprintf(s,"[ERROR: incorrect char - %02x, not %02x]\n", rx_char, PHONET_FRAME_ID); } return ERR_NONE; } d->Msg.Count = 0; d->MsgRXState = RX_GetDestination; return ERR_NONE; } return ERR_NONE; } static GSM_Error PHONET_Initialise(GSM_StateMachine *s) { int total = 0, i, n; GSM_Protocol_PHONETData *d = &s->Protocol.Data.PHONET; unsigned char req[50]; d->Msg.Length = 0; d->Msg.Buffer = NULL; d->MsgRXState = RX_Sync; if (s->ConnectionType == GCT_PHONETBLUE || s->ConnectionType == GCT_BLUEPHONET) { /* Send frame in PHONET style */ req[0] = PHONET_BLUE_FRAME_ID; req[1] = PHONET_DEVICE_PHONE; req[2] = PHONET_BLUE_DEVICE_PC; req[3] = 0xD0; req[4] = 0x00; req[5] = 0x01; req[6] = 0x04; if (s->Device.Functions->WriteDevice(s,req,7) != 7) return ERR_DEVICEWRITEERROR; while (total < 7) { n = s->Device.Functions->ReadDevice(s, req + total, 50 - total); total += n; } /* Answer frame in PHONET style */ req[10] = PHONET_BLUE_FRAME_ID; req[11] = PHONET_BLUE_DEVICE_PC; req[12] = PHONET_DEVICE_PHONE; req[13] = 0xD0; req[14] = 0x00; req[15] = 0x01; req[16] = 0x05; for (i = 0; i < 7; i++) { if (req[i] != req[10+i]) { smprintf(s,"Incorrect byte in the answer\n"); return ERR_UNKNOWN; } } } return ERR_NONE; } static GSM_Error PHONET_Terminate(GSM_StateMachine *s) { free(s->Protocol.Data.PHONET.Msg.Buffer); return ERR_NONE; } GSM_Protocol_Functions PHONETProtocol = { PHONET_WriteMessage, PHONET_StateMachine, PHONET_Initialise, PHONET_Terminate }; #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/protocol/nokia/phonet.h b/gammu/emb/common/protocol/nokia/phonet.h index e750bbd..7626c23 100644 --- a/gammu/emb/common/protocol/nokia/phonet.h +++ b/gammu/emb/common/protocol/nokia/phonet.h @@ -1,38 +1,47 @@ /* (c) 2002-2003 by Marcin Wiacek */ /* Based on some work from Gnokii (www.gnokii.org) * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot * GNU GPL version 2 or later */ +/* Due to a problem in the source code management, the names of some of + * the authors have unfortunately been lost. We do not mean to belittle + * their efforts and hope they will contact us to see their names + * properly added to the Copyright notice above. + * Having published their contributions under the terms of the GNU + * General Public License (GPL) [version 2], the Copyright of these + * authors will remain respected by adhering to the license they chose + * to publish their code under. + */ #ifndef PHONET_h #define PHONET_h #include "../protocol.h" #define PHONET_FRAME_ID 0x14 #define PHONET_BLUE_FRAME_ID 0x19 #define PHONET_DEVICE_PHONE 0x00 /* Nokia mobile phone */ #define PHONET_DEVICE_PC 0x0c /* Our PC */ #define PHONET_BLUE_DEVICE_PC 0x10 /* Our PC */ typedef struct { int MsgRXState; GSM_Protocol_Message Msg; } GSM_Protocol_PHONETData; #if defined(GSM_ENABLE_IRDAPHONET) # ifndef GSM_USED_IRDADEVICE # define GSM_USED_IRDADEVICE # endif #endif #if defined(GSM_ENABLE_BLUEPHONET) # ifndef GSM_USED_BLUETOOTHDEVICE # define GSM_USED_BLUETOOTHDEVICE # endif #endif #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/service/backup/backgen.h b/gammu/emb/common/service/backup/backgen.h index 9a930fc..9d97954 100644 --- a/gammu/emb/common/service/backup/backgen.h +++ b/gammu/emb/common/service/backup/backgen.h @@ -1,73 +1,73 @@ /* (c) 2002-2004 by Marcin Wiacek */ #ifndef __gsm_backgen_h #define __gsm_backgen_h #include "../../config.h" #include "../../misc/misc.h" #include "../gsmpbk.h" #include "../gsmcal.h" #include "../gsmlogo.h" #include "../gsmring.h" #include "../gsmdata.h" #include "../gsmprof.h" #include "../gsmmisc.h" #include "../sms/gsmsms.h" #define GSM_BACKUP_MAX_PHONEPHONEBOOK 501 #define GSM_BACKUP_MAX_SIMPHONEBOOK 251 #define GSM_BACKUP_MAX_CALLER 6 #define GSM_BACKUP_MAX_SMSC 10 #define GSM_BACKUP_MAX_WAPBOOKMARK 40 #define GSM_BACKUP_MAX_WAPSETTINGS 30 #define GSM_BACKUP_MAX_MMSSETTINGS 30 #define GSM_BACKUP_MAX_SYNCMLSETTINGS 10 #define GSM_BACKUP_MAX_CHATSETTINGS 10 #define GSM_BACKUP_MAX_RINGTONES 30 #define GSM_BACKUP_MAX_PROFILES 10 #define GSM_BACKUP_MAX_FMSTATIONS 20 #define GSM_BACKUP_MAX_GPRSPOINT 10 #define GSM_BACKUP_MAX_NOTE 10 /* FIXME */ typedef struct { char IMEI [MAX_IMEI_LENGTH]; char Model [MAX_MODEL_LENGTH+MAX_VERSION_LENGTH]; char Creator [80]; GSM_DateTime DateTime; bool DateTimeAvailable; char MD5Original [100]; char MD5Calculated [100]; GSM_MemoryEntry *PhonePhonebook [GSM_BACKUP_MAX_PHONEPHONEBOOK + 1]; GSM_MemoryEntry *SIMPhonebook [GSM_BACKUP_MAX_SIMPHONEBOOK + 1]; GSM_CalendarEntry *Calendar [GSM_MAXCALENDARTODONOTES + 1]; GSM_Bitmap *CallerLogos [GSM_BACKUP_MAX_CALLER + 1]; GSM_SMSC *SMSC [GSM_BACKUP_MAX_SMSC + 1]; GSM_WAPBookmark *WAPBookmark [GSM_BACKUP_MAX_WAPBOOKMARK + 1]; GSM_MultiWAPSettings *WAPSettings [GSM_BACKUP_MAX_WAPSETTINGS + 1]; GSM_MultiWAPSettings *MMSSettings [GSM_BACKUP_MAX_MMSSETTINGS + 1]; GSM_SyncMLSettings *SyncMLSettings [GSM_BACKUP_MAX_SYNCMLSETTINGS + 1]; GSM_ChatSettings *ChatSettings [GSM_BACKUP_MAX_CHATSETTINGS + 1]; GSM_Ringtone *Ringtone [GSM_BACKUP_MAX_RINGTONES + 1]; GSM_ToDoEntry *ToDo [GSM_MAXCALENDARTODONOTES + 1]; GSM_Profile *Profiles [GSM_BACKUP_MAX_PROFILES + 1]; GSM_FMStation *FMStation [GSM_BACKUP_MAX_FMSTATIONS +1]; GSM_GPRSAccessPoint *GPRSPoint [GSM_BACKUP_MAX_GPRSPOINT + 1]; GSM_NoteEntry *Note [GSM_BACKUP_MAX_NOTE + 1]; GSM_Bitmap *StartupLogo; GSM_Bitmap *OperatorLogo; } GSM_Backup; #define GSM_BACKUP_MAX_SMS 500 typedef struct { GSM_SMSMessage *SMS[GSM_BACKUP_MAX_SMS]; } GSM_SMS_Backup; extern GSM_Error GSM_ReadSMSBackupFile(char *FileName, GSM_SMS_Backup *backup); -extern GSM_Error GSM_SaveSMSBackupFile(char *FileName, GSM_SMS_Backup *backup); +extern GSM_Error GSM_AddSMSBackupFile (char *FileName, GSM_SMS_Backup *backup); #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/service/backup/backtext.c b/gammu/emb/common/service/backup/backtext.c index 4cb1bb7..07a3b22 100644 --- a/gammu/emb/common/service/backup/backtext.c +++ b/gammu/emb/common/service/backup/backtext.c @@ -1463,1647 +1463,1651 @@ static void ReadCalendarEntry(INI_Section *file_info, char *section, GSM_Calenda } else if (mystrncasecmp(readvalue,"Training/Tennis",0)) { note->Type = GSM_CAL_T_TENN; } else if (mystrncasecmp(readvalue,"Training/Travels",0)) { note->Type = GSM_CAL_T_TRAV; } else if (mystrncasecmp(readvalue,"Training/WinterGames",0)) { note->Type = GSM_CAL_T_WINT; } } note->EntriesNum = 0; sprintf(buffer,"Text"); if (ReadBackupText(file_info, section, buffer, note->Entries[note->EntriesNum].Text,UseUnicode)) { note->Entries[note->EntriesNum].EntryType = CAL_TEXT; note->EntriesNum++; } sprintf(buffer,"Phone"); if (ReadBackupText(file_info, section, buffer, note->Entries[note->EntriesNum].Text,UseUnicode)) { note->Entries[note->EntriesNum].EntryType = CAL_PHONE; note->EntriesNum++; } sprintf(buffer,"Private"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { note->Entries[note->EntriesNum].Number = atoi(readvalue); note->Entries[note->EntriesNum].EntryType = CAL_PRIVATE; note->EntriesNum++; } sprintf(buffer,"EventLocation"); if (ReadBackupText(file_info, section, buffer, note->Entries[note->EntriesNum].Text,UseUnicode)) { note->Entries[note->EntriesNum].EntryType = CAL_LOCATION; note->EntriesNum++; } sprintf(buffer,"ContactID"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { note->Entries[note->EntriesNum].Number = atoi(readvalue); note->Entries[note->EntriesNum].EntryType = CAL_CONTACTID; note->EntriesNum++; } sprintf(buffer,"Recurrance"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { note->Entries[note->EntriesNum].Number = atoi(readvalue) * 24; note->Entries[note->EntriesNum].EntryType = CAL_RECURRANCE; note->EntriesNum++; } sprintf(buffer,"StartTime"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ReadVCALDateTime(readvalue, ¬e->Entries[note->EntriesNum].Date); note->Entries[note->EntriesNum].EntryType = CAL_START_DATETIME; note->EntriesNum++; } sprintf(buffer,"StopTime"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ReadVCALDateTime(readvalue, ¬e->Entries[note->EntriesNum].Date); note->Entries[note->EntriesNum].EntryType = CAL_END_DATETIME; note->EntriesNum++; } sprintf(buffer,"Alarm"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ReadVCALDateTime(readvalue, ¬e->Entries[note->EntriesNum].Date); note->Entries[note->EntriesNum].EntryType = CAL_ALARM_DATETIME; sprintf(buffer,"AlarmType"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Silent",0)) { note->Entries[note->EntriesNum].EntryType = CAL_SILENT_ALARM_DATETIME; } } note->EntriesNum++; } sprintf(buffer,"RepeatStartDate"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ReadVCALDateTime(readvalue, ¬e->Entries[note->EntriesNum].Date); note->Entries[note->EntriesNum].EntryType = CAL_REPEAT_STARTDATE; note->EntriesNum++; } sprintf(buffer,"RepeatStopDate"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ReadVCALDateTime(readvalue, ¬e->Entries[note->EntriesNum].Date); note->Entries[note->EntriesNum].EntryType = CAL_REPEAT_STOPDATE; note->EntriesNum++; } sprintf(buffer,"RepeatDayOfWeek"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { note->Entries[note->EntriesNum].Number = atoi(readvalue); note->Entries[note->EntriesNum].EntryType = CAL_REPEAT_DAYOFWEEK; note->EntriesNum++; } sprintf(buffer,"RepeatDay"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { note->Entries[note->EntriesNum].Number = atoi(readvalue); note->Entries[note->EntriesNum].EntryType = CAL_REPEAT_DAY; note->EntriesNum++; } sprintf(buffer,"RepeatWeekOfMonth"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { note->Entries[note->EntriesNum].Number = atoi(readvalue); note->Entries[note->EntriesNum].EntryType = CAL_REPEAT_WEEKOFMONTH; note->EntriesNum++; } sprintf(buffer,"RepeatMonth"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { note->Entries[note->EntriesNum].Number = atoi(readvalue); note->Entries[note->EntriesNum].EntryType = CAL_REPEAT_MONTH; note->EntriesNum++; } sprintf(buffer,"RepeatFrequency"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { note->Entries[note->EntriesNum].Number = atoi(readvalue); note->Entries[note->EntriesNum].EntryType = CAL_REPEAT_FREQUENCY; note->EntriesNum++; } } static void ReadToDoEntry(INI_Section *file_info, char *section, GSM_ToDoEntry *ToDo, bool UseUnicode) { unsigned char buffer[10000]; char *readvalue; ToDo->EntriesNum = 0; sprintf(buffer,"Location"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) ToDo->Location = atoi(readvalue); ToDo->Priority = GSM_Priority_High; sprintf(buffer,"Priority"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (!strcmp(readvalue,"3") || !strcmp(readvalue,"Low")) { ToDo->Priority = GSM_Priority_Low; } if (!strcmp(readvalue,"2") || !strcmp(readvalue,"Medium")) { ToDo->Priority = GSM_Priority_Medium; } } sprintf(buffer,"Text"); if (ReadBackupText(file_info, section, buffer, ToDo->Entries[ToDo->EntriesNum].Text,UseUnicode)) { ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_TEXT; ToDo->EntriesNum++; } sprintf(buffer,"Phone"); if (ReadBackupText(file_info, section, buffer, ToDo->Entries[ToDo->EntriesNum].Text,UseUnicode)) { ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_PHONE; ToDo->EntriesNum++; } sprintf(buffer,"Private"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ToDo->Entries[ToDo->EntriesNum].Number = atoi(readvalue); ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_PRIVATE; ToDo->EntriesNum++; } sprintf(buffer,"Completed"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (strncmp(readvalue, "yes", 3) == 0) { ToDo->Entries[ToDo->EntriesNum].Number = 1; } else { ToDo->Entries[ToDo->EntriesNum].Number = 0; } ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_COMPLETED; ToDo->EntriesNum++; } sprintf(buffer,"Category"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ToDo->Entries[ToDo->EntriesNum].Number = atoi(readvalue); ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_CATEGORY; ToDo->EntriesNum++; } sprintf(buffer,"ContactID"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ToDo->Entries[ToDo->EntriesNum].Number = atoi(readvalue); ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_CONTACTID; ToDo->EntriesNum++; } sprintf(buffer,"DueTime"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ReadVCALDateTime(readvalue, &ToDo->Entries[ToDo->EntriesNum].Date); ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_END_DATETIME; ToDo->EntriesNum++; } sprintf(buffer,"Alarm"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ReadVCALDateTime(readvalue, &ToDo->Entries[ToDo->EntriesNum].Date); ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_ALARM_DATETIME; ToDo->EntriesNum++; } sprintf(buffer,"SilentAlarm"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ReadVCALDateTime(readvalue, &ToDo->Entries[ToDo->EntriesNum].Date); ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_SILENT_ALARM_DATETIME; ToDo->EntriesNum++; } } static bool ReadBitmapEntry(INI_Section *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) { char *readvalue; unsigned char buffer[10000]; unsigned char Width, Height; int x, y; GSM_GetMaxBitmapWidthHeight(bitmap->Type, &Width, &Height); sprintf(buffer,"Width"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue==NULL) bitmap->BitmapWidth = Width; else bitmap->BitmapWidth = atoi(readvalue); sprintf(buffer,"Height"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue==NULL) bitmap->BitmapHeight = Height; else bitmap->BitmapHeight = atoi(readvalue); GSM_ClearBitmap(bitmap); for (y=0;y<bitmap->BitmapHeight;y++) { sprintf(buffer,"Bitmap%02i",y); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { for (x=0;x<bitmap->BitmapWidth;x++) { if (readvalue[x+1]=='#') GSM_SetPointBitmap(bitmap,x,y); } } else return false; } return true; } static void ReadCallerEntry(INI_Section *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) { unsigned char buffer[10000]; char *readvalue; bitmap->Type = GSM_CallerGroupLogo; bitmap->DefaultBitmap = !ReadBitmapEntry(file_info, section, bitmap, UseUnicode); if (bitmap->DefaultBitmap) { bitmap->BitmapWidth = 72; bitmap->BitmapHeight = 14; GSM_ClearBitmap(bitmap); } sprintf(buffer,"Name"); ReadBackupText(file_info, section, buffer, bitmap->Text,UseUnicode); if (bitmap->Text[0] == 0x00 && bitmap->Text[1] == 0x00) { bitmap->DefaultName = true; } else { bitmap->DefaultName = false; } sprintf(buffer,"Ringtone"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue==NULL) { sprintf(buffer,"FileRingtone"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue==NULL) { bitmap->DefaultRingtone = true; } else { DecodeHexBin (&bitmap->RingtoneID, readvalue, 2); bitmap->DefaultRingtone = false; bitmap->FileSystemRingtone = true; } } else { DecodeHexBin (&bitmap->RingtoneID, readvalue, 2); bitmap->DefaultRingtone = false; bitmap->FileSystemRingtone = false; } sprintf(buffer,"Enabled"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); bitmap->BitmapEnabled = true; if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"False",0)) bitmap->BitmapEnabled = false; } } static void ReadStartupEntry(INI_Section *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) { unsigned char buffer[10000]; sprintf(buffer,"Text"); ReadBackupText(file_info, section, buffer, bitmap->Text,UseUnicode); if (bitmap->Text[0]!=0 || bitmap->Text[1]!=0) { bitmap->Type = GSM_WelcomeNote_Text; } else { bitmap->Type = GSM_StartupLogo; bitmap->Location = 1; ReadBitmapEntry(file_info, section, bitmap, UseUnicode); #ifdef DEBUG if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,bitmap); #endif } } static void ReadWAPBookmarkEntry(INI_Section *file_info, char *section, GSM_WAPBookmark *bookmark, bool UseUnicode) { unsigned char buffer[10000]; sprintf(buffer,"URL"); ReadBackupText(file_info, section, buffer, bookmark->Address,UseUnicode); sprintf(buffer,"Title"); ReadBackupText(file_info, section, buffer, bookmark->Title,UseUnicode); } static void ReadOperatorEntry(INI_Section *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) { unsigned char buffer[10000]; char *readvalue; sprintf(buffer,"Network"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); memcpy(bitmap->NetworkCode, readvalue + 1, 6); bitmap->NetworkCode[6] = 0; bitmap->Type = GSM_OperatorLogo; ReadBitmapEntry(file_info, section, bitmap, UseUnicode); } static void ReadSMSCEntry(INI_Section *file_info, char *section, GSM_SMSC *SMSC, bool UseUnicode) { unsigned char buffer[10000]; char *readvalue; sprintf(buffer,"Name"); ReadBackupText(file_info, section, buffer, SMSC->Name,UseUnicode); sprintf(buffer,"Number"); ReadBackupText(file_info, section, buffer, SMSC->Number,UseUnicode); sprintf(buffer,"DefaultNumber"); ReadBackupText(file_info, section, buffer, SMSC->DefaultNumber,UseUnicode); sprintf(buffer,"Format"); SMSC->Format = SMS_FORMAT_Text; readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Fax",0)) { SMSC->Format = SMS_FORMAT_Fax; } else if (mystrncasecmp(readvalue,"Email",0)) { SMSC->Format = SMS_FORMAT_Email; } else if (mystrncasecmp(readvalue,"Pager",0)) { SMSC->Format = SMS_FORMAT_Pager; } } sprintf(buffer,"Validity"); SMSC->Validity.Relative = SMS_VALID_Max_Time; readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"1hour",0)) { SMSC->Validity.Relative = SMS_VALID_1_Hour; } else if (mystrncasecmp(readvalue,"6hours",0)) { SMSC->Validity.Relative = SMS_VALID_6_Hours; } else if (mystrncasecmp(readvalue,"24hours",0)) { SMSC->Validity.Relative = SMS_VALID_1_Day; } else if (mystrncasecmp(readvalue,"72hours",0)) { SMSC->Validity.Relative = SMS_VALID_3_Days; } else if (mystrncasecmp(readvalue,"1week",0)) { SMSC->Validity.Relative = SMS_VALID_1_Week; } } } static void ReadWAPSettingsEntry(INI_Section *file_info, char *section, GSM_MultiWAPSettings *settings, bool UseUnicode) { unsigned char buffer[10000], *readvalue; int num; INI_Entry *e; settings->ActiveBearer = WAPSETTINGS_BEARER_DATA; sprintf(buffer,"Bearer"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"SMS",0)) { settings->ActiveBearer = WAPSETTINGS_BEARER_SMS; } else if (mystrncasecmp(readvalue,"GPRS",0)) { settings->ActiveBearer = WAPSETTINGS_BEARER_GPRS; } else if (mystrncasecmp(readvalue,"USSD",0)) { settings->ActiveBearer = WAPSETTINGS_BEARER_USSD; } } settings->Active = false; sprintf(buffer,"Active"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Yes",0)) settings->Active = true; } settings->ReadOnly = false; sprintf(buffer,"ReadOnly"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Yes",0)) settings->ReadOnly = true; } sprintf(buffer,"Proxy"); ReadBackupText(file_info, section, buffer, settings->Proxy,UseUnicode); sprintf(buffer,"ProxyPort"); settings->ProxyPort = 8080; readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) settings->ProxyPort = atoi(readvalue); sprintf(buffer,"Proxy2"); ReadBackupText(file_info, section, buffer, settings->Proxy2,UseUnicode); sprintf(buffer,"Proxy2Port"); settings->Proxy2Port = 8080; readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) settings->Proxy2Port = atoi(readvalue); settings->Number = 0; e = INI_FindLastSectionEntry(file_info, section, UseUnicode); while (e != NULL) { num = -1; if (UseUnicode) { sprintf(buffer,"%s",DecodeUnicodeString(e->EntryName)); } else { sprintf(buffer,"%s",e->EntryName); } if (strlen(buffer) == 7) { if (mystrncasecmp("Title", buffer,5)) num = atoi(buffer+5); } e = e->Prev; if (num != -1) { sprintf(buffer,"Title%02i",num); ReadBackupText(file_info, section, buffer, settings->Settings[settings->Number].Title,UseUnicode); sprintf(buffer,"HomePage%02i",num); ReadBackupText(file_info, section, buffer, settings->Settings[settings->Number].HomePage,UseUnicode); sprintf(buffer,"Type%02i",num); settings->Settings[settings->Number].IsContinuous = true; readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Temporary",0)) settings->Settings[settings->Number].IsContinuous = false; } sprintf(buffer,"Security%02i",num); settings->Settings[settings->Number].IsSecurity = true; readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Off",0)) settings->Settings[settings->Number].IsSecurity = false; } sprintf(buffer,"Bearer%02i",num); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"SMS",0)) { settings->Settings[settings->Number].Bearer = WAPSETTINGS_BEARER_SMS; sprintf(buffer,"Server%02i",num); ReadBackupText(file_info, section, buffer, settings->Settings[settings->Number].Server,UseUnicode); sprintf(buffer,"Service%02i",num); ReadBackupText(file_info, section, buffer, settings->Settings[settings->Number].Service,UseUnicode); } else if ((mystrncasecmp(readvalue,"Data",0) || mystrncasecmp(readvalue,"GPRS",0))) { settings->Settings[settings->Number].Bearer = WAPSETTINGS_BEARER_DATA; if (mystrncasecmp(readvalue,"GPRS",0)) settings->Settings[settings->Number].Bearer = WAPSETTINGS_BEARER_GPRS; sprintf(buffer,"Number%02i",num); ReadBackupText(file_info, section, buffer, settings->Settings[settings->Number].DialUp,UseUnicode); sprintf(buffer,"IP%02i",num); ReadBackupText(file_info, section, buffer, settings->Settings[settings->Number].IPAddress,UseUnicode); sprintf(buffer,"User%02i",num); ReadBackupText(file_info, section, buffer, settings->Settings[settings->Number].User,UseUnicode); sprintf(buffer,"Password%02i",num); ReadBackupText(file_info, section, buffer, settings->Settings[settings->Number].Password,UseUnicode); sprintf(buffer,"Authentication%02i",num); settings->Settings[settings->Number].IsNormalAuthentication = true; readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Secure",0)) settings->Settings[settings->Number].IsNormalAuthentication = false; } sprintf(buffer,"CallSpeed%02i",num); settings->Settings[settings->Number].Speed = WAPSETTINGS_SPEED_14400; readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"9600",0)) settings->Settings[settings->Number].Speed = WAPSETTINGS_SPEED_9600; if (mystrncasecmp(readvalue,"auto",0)) settings->Settings[settings->Number].Speed = WAPSETTINGS_SPEED_AUTO; } sprintf(buffer,"Login%02i",num); settings->Settings[settings->Number].ManualLogin = false; readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Manual",0)) settings->Settings[settings->Number].ManualLogin = true; } sprintf(buffer,"CallType%02i",num); settings->Settings[settings->Number].IsISDNCall = true; readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Analogue",0)) settings->Settings[settings->Number].IsISDNCall = false; } } else if (mystrncasecmp(readvalue,"USSD",0)) { settings->Settings[settings->Number].Bearer = WAPSETTINGS_BEARER_USSD; sprintf(buffer,"ServiceCode%02i",num); ReadBackupText(file_info, section, buffer, settings->Settings[settings->Number].Code,UseUnicode); sprintf(buffer,"IP%02i",num); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { settings->Settings[settings->Number].IsIP = true; sprintf(buffer,"IP%02i",num); } else { settings->Settings[settings->Number].IsIP = false; sprintf(buffer,"Number%02i",num); } ReadBackupText(file_info, section, buffer, settings->Settings[settings->Number].Service,UseUnicode); } } settings->Number++; } } } static void ReadRingtoneEntry(INI_Section *file_info, char *section, GSM_Ringtone *ringtone, bool UseUnicode) { unsigned char buffer[10000], buffer2[10000], *readvalue; sprintf(buffer,"Name"); ReadBackupText(file_info, section, buffer, ringtone->Name,UseUnicode); ringtone->Location = 0; sprintf(buffer,"Location"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) ringtone->Location = atoi(readvalue); sprintf(buffer,"NokiaBinary00"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ringtone->Format = RING_NOKIABINARY; ReadLinkedBackupText(file_info, section, "NokiaBinary", buffer2, UseUnicode); DecodeHexBin (ringtone->NokiaBinary.Frame, buffer2, strlen(buffer2)); ringtone->NokiaBinary.Length = strlen(buffer2)/2; } sprintf(buffer,"Pure Midi00"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { ringtone->Format = RING_MIDI; ReadLinkedBackupText(file_info, section, "Pure Midi", buffer2, UseUnicode); DecodeHexBin (ringtone->NokiaBinary.Frame, buffer2, strlen(buffer2)); ringtone->NokiaBinary.Length = strlen(buffer2)/2; } } static void ReadProfileEntry(INI_Section *file_info, char *section, GSM_Profile *Profile, bool UseUnicode) { unsigned char buffer[10000]; char *readvalue; bool unknown; int num,j; INI_Entry *e; sprintf(buffer,"Name"); ReadBackupText(file_info, section, buffer, Profile->Name,UseUnicode); sprintf(buffer,"Location"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); Profile->Location = atoi(readvalue); Profile->DefaultName = false; sprintf(buffer,"DefaultName"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL && mystrncasecmp(buffer,"true",0)) Profile->DefaultName = true; Profile->HeadSetProfile = false; sprintf(buffer,"HeadSetProfile"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL && mystrncasecmp(buffer,"true",0)) Profile->HeadSetProfile = true; Profile->CarKitProfile = false; sprintf(buffer,"CarKitProfile"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL && mystrncasecmp(buffer,"true",0)) Profile->CarKitProfile = true; Profile->FeaturesNumber = 0; e = INI_FindLastSectionEntry(file_info, section, UseUnicode); while (e != NULL) { num = -1; if (UseUnicode) { sprintf(buffer,"%s",DecodeUnicodeString(e->EntryName)); } else { sprintf(buffer,"%s",e->EntryName); } if (strlen(buffer) == 9) { if (mystrncasecmp("Feature", buffer, 7)) num = atoi(buffer+7); } e = e->Prev; if (num != -1) { sprintf(buffer,"Feature%02i",num); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue==NULL) break; unknown = true; if (mystrncasecmp(readvalue,"RingtoneID",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_RingtoneID; sprintf(buffer,"Value%02i",num); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); Profile->FeatureValue[Profile->FeaturesNumber]=atoi(readvalue); Profile->FeaturesNumber++; } else if (mystrncasecmp(readvalue,"MessageToneID",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_MessageToneID; sprintf(buffer,"Value%02i",num); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); Profile->FeatureValue[Profile->FeaturesNumber]=atoi(readvalue); Profile->FeaturesNumber++; } else if (mystrncasecmp(readvalue,"ScreenSaverNumber",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_ScreenSaverNumber; sprintf(buffer,"Value%02i",num); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); Profile->FeatureValue[Profile->FeaturesNumber]=atoi(readvalue); Profile->FeaturesNumber++; } else if (mystrncasecmp(readvalue,"CallerGroups",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_CallerGroups; sprintf(buffer,"Value%02i",num); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); for (j=0;j<5;j++) { Profile->CallerGroups[j]=false; if (strstr(readvalue,"1"+j)!=NULL) Profile->CallerGroups[j]=true; } Profile->FeaturesNumber++; } else if (mystrncasecmp(readvalue,"IncomingCallAlert",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_CallAlert; unknown = false; } else if (mystrncasecmp(readvalue,"RingtoneVolume",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_RingtoneVolume; unknown = false; } else if (mystrncasecmp(readvalue,"Vibrating",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_Vibration; unknown = false; } else if (mystrncasecmp(readvalue,"MessageTone",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_MessageTone; unknown = false; } else if (mystrncasecmp(readvalue,"KeypadTones",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_KeypadTone; unknown = false; } else if (mystrncasecmp(readvalue,"WarningTones",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_WarningTone; unknown = false; } else if (mystrncasecmp(readvalue,"ScreenSaver",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_ScreenSaver; unknown = false; } else if (mystrncasecmp(readvalue,"ScreenSaverTimeout",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_ScreenSaverTime; unknown = false; } else if (mystrncasecmp(readvalue,"AutomaticAnswer",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_AutoAnswer; unknown = false; } else if (mystrncasecmp(readvalue,"Lights",0)) { Profile->FeatureID[Profile->FeaturesNumber]=Profile_Lights; unknown = false; } if (!unknown) { sprintf(buffer,"Value%02i",num); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (mystrncasecmp(readvalue,"Level1",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_VOLUME_LEVEL1; if (Profile->FeatureID[Profile->FeaturesNumber]==Profile_KeypadTone) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_KEYPAD_LEVEL1; } } else if (mystrncasecmp(readvalue,"Level2",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_VOLUME_LEVEL2; if (Profile->FeatureID[Profile->FeaturesNumber]==Profile_KeypadTone) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_KEYPAD_LEVEL2; } } else if (mystrncasecmp(readvalue,"Level3",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_VOLUME_LEVEL3; if (Profile->FeatureID[Profile->FeaturesNumber]==Profile_KeypadTone) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_KEYPAD_LEVEL3; } } else if (mystrncasecmp(readvalue,"Level4",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_VOLUME_LEVEL4; } else if (mystrncasecmp(readvalue,"Level5",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_VOLUME_LEVEL5; } else if (mystrncasecmp(readvalue,"Off",0)) { switch (Profile->FeatureID[Profile->FeaturesNumber]) { case Profile_MessageTone: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_MESSAGE_NOTONE; break; case Profile_AutoAnswer: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_AUTOANSWER_OFF; break; case Profile_Lights: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_LIGHTS_OFF; break; case Profile_ScreenSaver: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_SAVER_OFF; break; case Profile_WarningTone: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_WARNING_OFF; break; case Profile_CallAlert: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_CALLALERT_OFF; break; case Profile_Vibration: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_VIBRATION_OFF; break; default: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_KEYPAD_OFF; break; } } else if (mystrncasecmp(readvalue,"Ringing",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_CALLALERT_RINGING; } else if (mystrncasecmp(readvalue,"BeepOnce",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_CALLALERT_BEEPONCE; if (Profile->FeatureID[Profile->FeaturesNumber]==Profile_MessageTone) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_MESSAGE_BEEPONCE; } } else if (mystrncasecmp(readvalue,"RingOnce",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_CALLALERT_RINGONCE; } else if (mystrncasecmp(readvalue,"Ascending",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_CALLALERT_ASCENDING; } else if (mystrncasecmp(readvalue,"CallerGroups",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_CALLALERT_CALLERGROUPS; } else if (mystrncasecmp(readvalue,"Standard",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_MESSAGE_STANDARD; } else if (mystrncasecmp(readvalue,"Special",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_MESSAGE_SPECIAL; } else if (mystrncasecmp(readvalue,"Ascending",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_MESSAGE_ASCENDING; } else if (mystrncasecmp(readvalue,"Personal",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_MESSAGE_PERSONAL; } else if (mystrncasecmp(readvalue,"VibrateFirst",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_VIBRATION_FIRST; } else if (mystrncasecmp(readvalue,"Auto",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_LIGHTS_AUTO; } else if (mystrncasecmp(readvalue,"5Seconds",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_SAVER_TIMEOUT_5SEC; } else if (mystrncasecmp(readvalue,"20Seconds",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_SAVER_TIMEOUT_20SEC; } else if (mystrncasecmp(readvalue,"1Minute",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_SAVER_TIMEOUT_1MIN; } else if (mystrncasecmp(readvalue,"2Minutes",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_SAVER_TIMEOUT_2MIN; } else if (mystrncasecmp(readvalue,"5Minutes",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_SAVER_TIMEOUT_5MIN; } else if (mystrncasecmp(readvalue,"10Minutes",0)) { Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_SAVER_TIMEOUT_10MIN; } else if (mystrncasecmp(readvalue,"On",0)) { switch (Profile->FeatureID[Profile->FeaturesNumber]) { case Profile_AutoAnswer: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_AUTOANSWER_ON; break; case Profile_WarningTone: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_WARNING_ON; break; case Profile_ScreenSaver: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_SAVER_ON; break; default: Profile->FeatureValue[Profile->FeaturesNumber]=PROFILE_VIBRATION_ON; break; } } else unknown = true; } if (!unknown) Profile->FeaturesNumber++; } } } static void ReadFMStationEntry(INI_Section *file_info, char *section, GSM_FMStation *FMStation, bool UseUnicode) { unsigned char buffer[10000], *readvalue; FMStation->Location = 0; FMStation->Frequency = 0; sprintf(buffer,"Location"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) FMStation->Location = atoi(readvalue); sprintf(buffer,"StationName"); ReadBackupText(file_info, section, buffer, FMStation->StationName,UseUnicode); sprintf(buffer,"Frequency"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) StringToDouble(readvalue, &FMStation->Frequency); } static void ReadGPRSPointEntry(INI_Section *file_info, char *section, GSM_GPRSAccessPoint *GPRSPoint, bool UseUnicode) { unsigned char buffer[10000], *readvalue; GPRSPoint->Name[0] = 0; GPRSPoint->Name[1] = 0; GPRSPoint->URL[0] = 0; GPRSPoint->URL[1] = 0; GPRSPoint->Location = 0; GPRSPoint->Active = false; sprintf(buffer,"Active"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Yes",0)) GPRSPoint->Active = true; } sprintf(buffer,"Location"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (readvalue!=NULL) GPRSPoint->Location = atoi(readvalue); sprintf(buffer,"Name"); ReadBackupText(file_info, section, buffer, GPRSPoint->Name,UseUnicode); sprintf(buffer,"URL"); ReadBackupText(file_info, section, buffer, GPRSPoint->URL,UseUnicode); } static void ReadNoteEntry(INI_Section *file_info, char *section, GSM_NoteEntry *Note, bool UseUnicode) { unsigned char buffer[100]; sprintf(buffer,"Text"); ReadBackupText(file_info, section, buffer, Note->Text,UseUnicode); } GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) { INI_Section *file_info, *h; char buffer[100], *readvalue; int num; GSM_MemoryEntry PBK; bool found; file_info = INI_ReadFile(FileName, UseUnicode); sprintf(buffer,"Backup"); if (UseUnicode) EncodeUnicode(buffer,"Backup",6); readvalue = ReadCFGText(file_info, buffer, "Format", UseUnicode); /* Did we read anything? */ if (readvalue == NULL) return ERR_FILENOTSUPPORTED; /* Is this format version supported ? */ if (strcmp(readvalue,"1.01")!=0 && strcmp(readvalue,"1.02")!=0 && strcmp(readvalue,"1.03")!=0) return ERR_FILENOTSUPPORTED; readvalue = ReadCFGText(file_info, buffer, "IMEI", UseUnicode); if (readvalue!=NULL) strcpy(backup->IMEI,readvalue); readvalue = ReadCFGText(file_info, buffer, "Phone", UseUnicode); if (readvalue!=NULL) strcpy(backup->Model,readvalue); readvalue = ReadCFGText(file_info, buffer, "Creator", UseUnicode); if (readvalue!=NULL) strcpy(backup->Creator,readvalue); readvalue = ReadCFGText(file_info, buffer, "DateTime", UseUnicode); if (readvalue!=NULL) { ReadVCALDateTime(readvalue, &backup->DateTime); backup->DateTimeAvailable = true; } sprintf(buffer,"Checksum"); if (UseUnicode) EncodeUnicode(buffer,"Checksum",8); readvalue = ReadCFGText(file_info, buffer, "MD5", UseUnicode); if (readvalue!=NULL) strcpy(backup->MD5Original,readvalue); num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Profile",7); if (mywstrncasecmp(buffer, h->SectionName, 7)) found = true; } else { if (mystrncasecmp("Profile", h->SectionName, 7)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Location", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_PROFILES) { backup->Profiles[num] = malloc(sizeof(GSM_Profile)); if (backup->Profiles[num] == NULL) return ERR_MOREMEMORY; backup->Profiles[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_PROFILES\n"); return ERR_MOREMEMORY; } ReadProfileEntry(file_info, h->SectionName, backup->Profiles[num], UseUnicode); num++; } } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"PhonePBK",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { if (mystrncasecmp("PhonePBK", h->SectionName, 8)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Location", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_PHONEPHONEBOOK) { backup->PhonePhonebook[num] = malloc(sizeof(GSM_MemoryEntry)); if (backup->PhonePhonebook[num] == NULL) return ERR_MOREMEMORY; backup->PhonePhonebook[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_PHONEPHONEBOOK\n"); return ERR_MOREMEMORY; } backup->PhonePhonebook[num]->Location = atoi (readvalue); backup->PhonePhonebook[num]->MemoryType = MEM_ME; ReadPbkEntry(file_info, h->SectionName, backup->PhonePhonebook[num],UseUnicode); dbgprintf("number of entries = %i\n",backup->PhonePhonebook[num]->EntriesNum); num++; } } num = 0; while (0) { if (backup->PhonePhonebook[num] == NULL) break; if (backup->PhonePhonebook[num+1] != NULL) { if (backup->PhonePhonebook[num+1]->Location < backup->PhonePhonebook[num]->Location) { memcpy(&PBK,backup->PhonePhonebook[num+1],sizeof(GSM_MemoryEntry)); memcpy(backup->PhonePhonebook[num+1],backup->PhonePhonebook[num],sizeof(GSM_MemoryEntry)); memcpy(backup->PhonePhonebook[num],&PBK,sizeof(GSM_MemoryEntry)); num = 0; continue; } } num++; } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"SIMPBK",6); if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; } else { if (mystrncasecmp("SIMPBK", h->SectionName, 6)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Location", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_SIMPHONEBOOK) { backup->SIMPhonebook[num] = malloc(sizeof(GSM_MemoryEntry)); if (backup->SIMPhonebook[num] == NULL) return ERR_MOREMEMORY; backup->SIMPhonebook[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_SIMPHONEBOOK\n"); return ERR_MOREMEMORY; } backup->SIMPhonebook[num]->Location = atoi (readvalue); backup->SIMPhonebook[num]->MemoryType = MEM_SM; ReadPbkEntry(file_info, h->SectionName, backup->SIMPhonebook[num],UseUnicode); num++; } } num = 0; while (0) { if (backup->SIMPhonebook[num] == NULL) break; if (backup->SIMPhonebook[num+1] != NULL) { if (backup->SIMPhonebook[num+1]->Location < backup->SIMPhonebook[num]->Location) { memcpy(&PBK,backup->SIMPhonebook[num+1],sizeof(GSM_MemoryEntry)); memcpy(backup->SIMPhonebook[num+1],backup->SIMPhonebook[num],sizeof(GSM_MemoryEntry)); memcpy(backup->SIMPhonebook[num],&PBK,sizeof(GSM_MemoryEntry)); num = 0; continue; } } num++; } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Calendar",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { if (mystrncasecmp("Calendar", h->SectionName, 8)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Type", UseUnicode); if (readvalue==NULL) break; if (num < GSM_MAXCALENDARTODONOTES) { backup->Calendar[num] = malloc(sizeof(GSM_CalendarEntry)); if (backup->Calendar[num] == NULL) return ERR_MOREMEMORY; backup->Calendar[num + 1] = NULL; } else { dbgprintf("Increase GSM_MAXCALENDARTODONOTES\n"); return ERR_MOREMEMORY; } backup->Calendar[num]->Location = num + 1; ReadCalendarEntry(file_info, h->SectionName, backup->Calendar[num],UseUnicode); num++; } } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Caller",6); if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; } else { if (mystrncasecmp("Caller", h->SectionName, 6)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Location", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_CALLER) { backup->CallerLogos[num] = malloc(sizeof(GSM_Bitmap)); if (backup->CallerLogos[num] == NULL) return ERR_MOREMEMORY; backup->CallerLogos[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_CALLER\n"); return ERR_MOREMEMORY; } backup->CallerLogos[num]->Location = atoi (readvalue); ReadCallerEntry(file_info, h->SectionName, backup->CallerLogos[num],UseUnicode); num++; } } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"SMSC",4); if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; } else { if (mystrncasecmp("SMSC", h->SectionName, 4)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Location", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_SMSC) { backup->SMSC[num] = malloc(sizeof(GSM_SMSC)); if (backup->SMSC[num] == NULL) return ERR_MOREMEMORY; backup->SMSC[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_SMSC\n"); return ERR_MOREMEMORY; } backup->SMSC[num]->Location = atoi (readvalue); ReadSMSCEntry(file_info, h->SectionName, backup->SMSC[num],UseUnicode); num++; } } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"WAPBookmark",11); if (mywstrncasecmp(buffer, h->SectionName, 11)) found = true; if (!found) { EncodeUnicode(buffer,"Bookmark",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } } else { if (mystrncasecmp("WAPBookmark", h->SectionName, 11)) found = true; if (!found) { if (mystrncasecmp("Bookmark", h->SectionName, 8)) found = true; } } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "URL", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_WAPBOOKMARK) { backup->WAPBookmark[num] = malloc(sizeof(GSM_WAPBookmark)); if (backup->WAPBookmark[num] == NULL) return ERR_MOREMEMORY; backup->WAPBookmark[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_WAPBOOKMARK\n"); return ERR_MOREMEMORY; } backup->WAPBookmark[num]->Location = num + 1; ReadWAPBookmarkEntry(file_info, h->SectionName, backup->WAPBookmark[num],UseUnicode); num++; } } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"WAPSettings",11); if (mywstrncasecmp(buffer, h->SectionName, 11)) found = true; if (!found) { EncodeUnicode(buffer,"Settings",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } } else { if (mystrncasecmp("WAPSettings", h->SectionName, 11)) found = true; if (!found) { if (mystrncasecmp("Settings", h->SectionName, 8)) found = true; } } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Title00", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_WAPSETTINGS) { backup->WAPSettings[num] = malloc(sizeof(GSM_MultiWAPSettings)); if (backup->WAPSettings[num] == NULL) return ERR_MOREMEMORY; backup->WAPSettings[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_WAPSETTINGS\n"); return ERR_MOREMEMORY; } backup->WAPSettings[num]->Location = num + 1; dbgprintf("reading wap settings\n"); ReadWAPSettingsEntry(file_info, h->SectionName, backup->WAPSettings[num],UseUnicode); num++; } } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"MMSSettings",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { if (mystrncasecmp("MMSSettings", h->SectionName, 8)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Title00", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_MMSSETTINGS) { backup->MMSSettings[num] = malloc(sizeof(GSM_MultiWAPSettings)); if (backup->MMSSettings[num] == NULL) return ERR_MOREMEMORY; backup->MMSSettings[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_MMSSETTINGS\n"); return ERR_MOREMEMORY; } backup->MMSSettings[num]->Location = num + 1; dbgprintf("reading mms settings\n"); ReadWAPSettingsEntry(file_info, h->SectionName, backup->MMSSettings[num],UseUnicode); num++; } } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Ringtone",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { if (mystrncasecmp("Ringtone", h->SectionName, 8)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Location", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_RINGTONES) { backup->Ringtone[num] = malloc(sizeof(GSM_Ringtone)); if (backup->Ringtone[num] == NULL) return ERR_MOREMEMORY; backup->Ringtone[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_RINGTONES\n"); return ERR_MOREMEMORY; } ReadRingtoneEntry(file_info, h->SectionName, backup->Ringtone[num],UseUnicode); num++; } } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"TODO",4); if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; } else { if (mystrncasecmp("TODO", h->SectionName, 4)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Location", UseUnicode); if (readvalue==NULL) break; if (num < GSM_MAXCALENDARTODONOTES) { backup->ToDo[num] = malloc(sizeof(GSM_ToDoEntry)); if (backup->ToDo[num] == NULL) return ERR_MOREMEMORY; backup->ToDo[num + 1] = NULL; } else { dbgprintf("Increase GSM_MAXCALENDARTODONOTES\n"); return ERR_MOREMEMORY; } backup->ToDo[num]->Location = num + 1; ReadToDoEntry(file_info, h->SectionName, backup->ToDo[num],UseUnicode); num++; } } sprintf(buffer,"Startup"); readvalue = ReadCFGText(file_info, buffer, "Text", UseUnicode); if (readvalue==NULL) { readvalue = ReadCFGText(file_info, buffer, "Width", UseUnicode); } if (readvalue!=NULL) { backup->StartupLogo = malloc(sizeof(GSM_Bitmap)); if (backup->StartupLogo == NULL) return ERR_MOREMEMORY; ReadStartupEntry(file_info, buffer, backup->StartupLogo,UseUnicode); } sprintf(buffer,"Operator"); readvalue = ReadCFGText(file_info, buffer, "Network", UseUnicode); if (readvalue!=NULL) { backup->OperatorLogo = malloc(sizeof(GSM_Bitmap)); if (backup->OperatorLogo == NULL) return ERR_MOREMEMORY; ReadOperatorEntry(file_info, buffer, backup->OperatorLogo,UseUnicode); } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"FMStation",9); if (mywstrncasecmp(buffer, h->SectionName, 9)) found = true; } else { if (mystrncasecmp("FMStation", h->SectionName, 9)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Location", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_FMSTATIONS) { backup->FMStation[num] = malloc(sizeof(GSM_FMStation)); if (backup->FMStation[num] == NULL) return ERR_MOREMEMORY; backup->FMStation[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_FMSTATIONS\n"); return ERR_MOREMEMORY; } backup->FMStation[num]->Location = num + 1; ReadFMStationEntry(file_info, h->SectionName, backup->FMStation[num],UseUnicode); num++; } } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"GPRSPoint",9); if (mywstrncasecmp(buffer, h->SectionName, 9)) found = true; } else { if (mystrncasecmp("GPRSPoint", h->SectionName, 9)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Location", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_GPRSPOINT) { backup->GPRSPoint[num] = malloc(sizeof(GSM_GPRSAccessPoint)); if (backup->GPRSPoint[num] == NULL) return ERR_MOREMEMORY; backup->GPRSPoint[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_GPRSPOINT\n"); return ERR_MOREMEMORY; } backup->GPRSPoint[num]->Location = num + 1; ReadGPRSPointEntry(file_info, h->SectionName, backup->GPRSPoint[num],UseUnicode); num++; } } num = 0; for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Note",4); if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; } else { if (mystrncasecmp("Note", h->SectionName, 4)) found = true; } if (found) { readvalue = ReadCFGText(file_info, h->SectionName, "Text", UseUnicode); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_NOTE) { backup->Note[num] = malloc(sizeof(GSM_NoteEntry)); if (backup->Note[num] == NULL) return ERR_MOREMEMORY; backup->Note[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_NOTE\n"); return ERR_MOREMEMORY; } ReadNoteEntry(file_info, h->SectionName, backup->Note[num],UseUnicode); num++; } } if (backup->MD5Original[0]!=0) { FindBackupChecksum(FileName, UseUnicode, backup->MD5Calculated); } for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Backup",4); if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; } else { if (mystrncasecmp("Backup", h->SectionName, 6)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"Checksum",4); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { if (mystrncasecmp("Checksum", h->SectionName, 8)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"Profile",7); if (mywstrncasecmp(buffer, h->SectionName, 7)) found = true; } else { if (mystrncasecmp("Profile", h->SectionName, 7)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"PhonePBK",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { if (mystrncasecmp("PhonePBK", h->SectionName, 8)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"SIMPBK",6); if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; } else { if (mystrncasecmp("SIMPBK", h->SectionName, 6)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"Calendar",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { if (mystrncasecmp("Calendar", h->SectionName, 8)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"Caller",6); if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; } else { if (mystrncasecmp("Caller", h->SectionName, 6)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"SMSC",4); if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; } else { if (mystrncasecmp("SMSC", h->SectionName, 4)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"WAPBookmark",11); if (mywstrncasecmp(buffer, h->SectionName, 11)) found = true; if (!found) { EncodeUnicode(buffer,"Bookmark",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } } else { if (mystrncasecmp("WAPBookmark", h->SectionName, 11)) found = true; if (!found) { if (mystrncasecmp("Bookmark", h->SectionName, 8)) found = true; } } if (UseUnicode) { EncodeUnicode(buffer,"WAPSettings",11); if (mywstrncasecmp(buffer, h->SectionName, 11)) found = true; if (!found) { EncodeUnicode(buffer,"Settings",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } } else { if (mystrncasecmp("WAPSettings", h->SectionName, 11)) found = true; if (!found) { if (mystrncasecmp("Settings", h->SectionName, 8)) found = true; } } if (UseUnicode) { EncodeUnicode(buffer,"MMSSettings",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { if (mystrncasecmp("MMSSettings", h->SectionName, 8)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"Ringtone",8); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { if (mystrncasecmp("Ringtone", h->SectionName, 8)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"TODO",4); if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; } else { if (mystrncasecmp("TODO", h->SectionName, 4)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"Startup",7); if (mywstrncasecmp(buffer, h->SectionName, 7)) found = true; } else { if (mystrncasecmp("Startup", h->SectionName, 7)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"Operator",7); if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { if (mystrncasecmp("Operator", h->SectionName, 8)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"FMStation",9); if (mywstrncasecmp(buffer, h->SectionName, 9)) found = true; } else { if (mystrncasecmp("FMStation", h->SectionName, 9)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"GPRSPoint",9); if (mywstrncasecmp(buffer, h->SectionName, 9)) found = true; } else { if (mystrncasecmp("GPRSPoint", h->SectionName, 9)) found = true; } if (UseUnicode) { EncodeUnicode(buffer,"Note",4); if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; } else { if (mystrncasecmp("Note", h->SectionName, 4)) found = true; } if (!found) return ERR_NOTIMPLEMENTED; } return ERR_NONE; } /* ---------------------- backup files for SMS ----------------------------- */ static void ReadSMSBackupEntry(INI_Section *file_info, char *section, GSM_SMSMessage *SMS) { unsigned char buffer[10000], *readvalue; GSM_SetDefaultSMSData(SMS); SMS->PDU = SMS_Submit; SMS->SMSC.Location = 0; sprintf(buffer,"SMSC"); ReadBackupText(file_info, section, buffer, SMS->SMSC.Number, false); sprintf(buffer,"ReplySMSC"); SMS->ReplyViaSameSMSC = false; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"True",0)) SMS->ReplyViaSameSMSC = true; } sprintf(buffer,"Class"); SMS->Class = -1; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) SMS->Class = atoi(readvalue); sprintf(buffer,"Sent"); readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) { ReadVCALDateTime(readvalue, &SMS->DateTime); SMS->PDU = SMS_Deliver; } sprintf(buffer,"RejectDuplicates"); SMS->RejectDuplicates = false; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"True",0)) SMS->RejectDuplicates = true; } sprintf(buffer,"ReplaceMessage"); SMS->ReplaceMessage = 0; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) SMS->ReplaceMessage = atoi(readvalue); sprintf(buffer,"MessageReference"); SMS->MessageReference = 0; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) SMS->MessageReference = atoi(readvalue); sprintf(buffer,"State"); SMS->State = SMS_UnRead; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Read",0)) SMS->State = SMS_Read; else if (mystrncasecmp(readvalue,"Sent",0)) SMS->State = SMS_Sent; else if (mystrncasecmp(readvalue,"UnSent",0)) SMS->State = SMS_UnSent; } sprintf(buffer,"Number"); ReadBackupText(file_info, section, buffer, SMS->Number, false); sprintf(buffer,"Name"); ReadBackupText(file_info, section, buffer, SMS->Name, false); sprintf(buffer,"Length"); SMS->Length = 0; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) SMS->Length = atoi(readvalue); sprintf(buffer,"Coding"); SMS->Coding = SMS_Coding_Default; readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) { if (mystrncasecmp(readvalue,"Unicode",0)) { SMS->Coding = SMS_Coding_Unicode; } else if (mystrncasecmp(readvalue,"8bit",0)) { SMS->Coding = SMS_Coding_8bit; } } ReadLinkedBackupText(file_info, section, "Text", buffer, false); DecodeHexBin (SMS->Text, buffer, strlen(buffer)); SMS->Text[strlen(buffer)/2] = 0; SMS->Text[strlen(buffer)/2+1] = 0; sprintf(buffer,"Folder"); readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) SMS->Folder = atoi(readvalue); SMS->UDH.Type = UDH_NoUDH; SMS->UDH.Length = 0; SMS->UDH.ID8bit = -1; SMS->UDH.ID16bit = -1; SMS->UDH.PartNumber = -1; SMS->UDH.AllParts = -1; sprintf(buffer,"UDH"); readvalue = ReadCFGText(file_info, section, buffer, false); if (readvalue!=NULL) { DecodeHexBin (SMS->UDH.Text, readvalue, strlen(readvalue)); SMS->UDH.Length = strlen(readvalue)/2; GSM_DecodeUDHHeader(&SMS->UDH); } } static GSM_Error GSM_ReadSMSBackupTextFile(char *FileName, GSM_SMS_Backup *backup) { INI_Section *file_info, *h; char *readvalue; int num; backup->SMS[0] = NULL; file_info = INI_ReadFile(FileName, false); num = 0; for (h = file_info; h != NULL; h = h->Next) { if (mystrncasecmp("SMSBackup", h->SectionName, 9)) { readvalue = ReadCFGText(file_info, h->SectionName, "Number", false); if (readvalue==NULL) break; if (num < GSM_BACKUP_MAX_SMS) { backup->SMS[num] = malloc(sizeof(GSM_SMSMessage)); if (backup->SMS[num] == NULL) return ERR_MOREMEMORY; backup->SMS[num + 1] = NULL; } else { dbgprintf("Increase GSM_BACKUP_MAX_SMS\n"); return ERR_MOREMEMORY; } backup->SMS[num]->Location = num + 1; ReadSMSBackupEntry(file_info, h->SectionName, backup->SMS[num]); num++; } } return ERR_NONE; } GSM_Error GSM_ReadSMSBackupFile(char *FileName, GSM_SMS_Backup *backup) { FILE *file; backup->SMS[0] = NULL; file = fopen(FileName, "rb"); if (file == NULL) return(ERR_CANTOPENFILE); fclose(file); return GSM_ReadSMSBackupTextFile(FileName, backup); } -GSM_Error SaveSMSBackupTextFile(FILE *file, GSM_SMS_Backup *backup) +static GSM_Error SaveSMSBackupTextFile(FILE *file, GSM_SMS_Backup *backup) { int i,w,current; unsigned char buffer[10000]; GSM_DateTime DT; fprintf(file,"\n# File created by Gammu (www.mwiacek.com) version %s\n",VERSION); GSM_GetCurrentDateTime (&DT); - fprintf(file,"# Saved %s\n\n",OSDateTime(DT,false)); + fprintf(file,"# Saved "); + fprintf(file, "%04d%02d%02dT%02d%02d%02d", + DT.Year, DT.Month, DT.Day, + DT.Hour, DT.Minute, DT.Second); + fprintf(file," (%s)\n\n",OSDateTime(DT,false)); i=0; while (backup->SMS[i]!=NULL) { fprintf(file,"[SMSBackup%03i]\n",i); switch (backup->SMS[i]->Coding) { case SMS_Coding_Unicode: case SMS_Coding_Default: sprintf(buffer,"%s",DecodeUnicodeString(backup->SMS[i]->Text)); fprintf(file,"#"); current = 0; for (w=0;w<(int)(strlen(buffer));w++) { switch (buffer[w]) { case 10: fprintf(file,"\n#"); current = 0; break; case 13: break; default: if (isprint(buffer[w])) { fprintf(file,"%c",buffer[w]); current ++; } if (current == 75) { fprintf(file,"\n#"); current = 0; } } } fprintf(file,"\n"); break; default: break; } if (backup->SMS[i]->PDU == SMS_Deliver) { SaveBackupText(file, "SMSC", backup->SMS[i]->SMSC.Number, false); if (backup->SMS[i]->ReplyViaSameSMSC) fprintf(file,"SMSCReply = true\n"); fprintf(file,"Sent"); SaveVCalDateTime(file,&backup->SMS[i]->DateTime, false); } fprintf(file,"State = "); switch (backup->SMS[i]->State) { case SMS_UnRead : fprintf(file,"UnRead\n"); break; case SMS_Read : fprintf(file,"Read\n"); break; case SMS_Sent : fprintf(file,"Sent\n"); break; case SMS_UnSent : fprintf(file,"UnSent\n"); break; } SaveBackupText(file, "Number", backup->SMS[i]->Number, false); SaveBackupText(file, "Name", backup->SMS[i]->Name, false); if (backup->SMS[i]->UDH.Type != UDH_NoUDH) { EncodeHexBin(buffer,backup->SMS[i]->UDH.Text,backup->SMS[i]->UDH.Length); fprintf(file,"UDH = %s\n",buffer); } switch (backup->SMS[i]->Coding) { case SMS_Coding_Unicode: case SMS_Coding_Default: EncodeHexBin(buffer,backup->SMS[i]->Text,backup->SMS[i]->Length*2); break; default: EncodeHexBin(buffer,backup->SMS[i]->Text,backup->SMS[i]->Length); break; } SaveLinkedBackupText(file, "Text", buffer, false); switch (backup->SMS[i]->Coding) { case SMS_Coding_Unicode : fprintf(file,"Coding = Unicode\n"); break; case SMS_Coding_Default : fprintf(file,"Coding = Default\n"); break; case SMS_Coding_8bit : fprintf(file,"Coding = 8bit\n"); break; } fprintf(file,"Folder = %i\n",backup->SMS[i]->Folder); fprintf(file,"Length = %i\n",backup->SMS[i]->Length); fprintf(file,"Class = %i\n",backup->SMS[i]->Class); fprintf(file,"ReplySMSC = "); if (backup->SMS[i]->ReplyViaSameSMSC) fprintf(file,"True\n"); else fprintf(file,"False\n"); fprintf(file,"RejectDuplicates = "); if (backup->SMS[i]->RejectDuplicates) fprintf(file,"True\n"); else fprintf(file,"False\n"); fprintf(file,"ReplaceMessage = %i\n",backup->SMS[i]->ReplaceMessage); fprintf(file,"MessageReference = %i\n",backup->SMS[i]->MessageReference); fprintf(file,"\n"); i++; } return ERR_NONE; } -GSM_Error GSM_SaveSMSBackupFile(char *FileName, GSM_SMS_Backup *backup) +GSM_Error GSM_AddSMSBackupFile(char *FileName, GSM_SMS_Backup *backup) { FILE *file; - file = fopen(FileName, "wb"); + file = fopen(FileName, "ab"); if (file == NULL) return(ERR_CANTOPENFILE); SaveSMSBackupTextFile(file,backup); fclose(file); return ERR_NONE; } #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/service/gsmring.h b/gammu/emb/common/service/gsmring.h index 2d2dd7a..33e5424 100644 --- a/gammu/emb/common/service/gsmring.h +++ b/gammu/emb/common/service/gsmring.h @@ -1,204 +1,204 @@ /* (c) 2002-2004 by Marcin Wiacek */ #ifndef __gsm_ring_h #define __gsm_ring_h /* --------------- Smart Messaging Specification 2.0 & 3.0 ----------------- */ #define SM_CommandEnd_CommandEnd 0x00 /* specification gives also other */ #define SM_Command_RingingToneProgramming 0x25<<1 #define SM_Command_Sound 0x1d<<1 /* specification gives also other */ #define SM_Song_BasicSongType 0x01<<5 /* specification gives also other */ #define SM_PatternID_A_part 0x00<<6 /* specification gives also other */ #define SM_InstructionID_PatternHeaderId 0x00<<5 #define SM_InstructionID_NoteInstructionId 0x01<<5 #define SM_InstructionID_ScaleInstructionId 0x02<<5 #define SM_InstructionID_StyleInstructionId 0x03<<5 #define SM_InstructionID_TempoInstructionId 0x04<<5 #define SM_InstructionID_VolumeInstructionId 0x05<<5 /* ------ end of Smart Messaging Specification 2.0 & 3.0 definitions ------- */ #define MAX_RINGTONE_NOTES 255 typedef enum { /** * Natural style (rest between notes) */ NaturalStyle = 0x00<<6, /** * Continuous style (no rest between notes) */ ContinuousStyle = 0x01<<6, /** * Staccato style (shorter notes and longer rest period) */ StaccatoStyle = 0x02<<6 } GSM_RingNoteStyle; typedef enum { Note_Pause = 0x00<<4, Note_C = 0x01<<4, Note_Cis = 0x02<<4, Note_D = 0x03<<4, Note_Dis = 0x04<<4, Note_E = 0x05<<4, Note_F = 0x06<<4, Note_Fis = 0x07<<4, Note_G = 0x08<<4, Note_Gis = 0x09<<4, Note_A = 0x0a<<4, Note_Ais = 0x0b<<4, Note_H = 0x0c<<4 } GSM_RingNoteNote; typedef enum { Duration_Full = 0x00<<5, Duration_1_2 = 0x01<<5, Duration_1_4 = 0x02<<5, Duration_1_8 = 0x03<<5, Duration_1_16 = 0x04<<5, Duration_1_32 = 0x05<<5 } GSM_RingNoteDuration; typedef enum { NoSpecialDuration = 0x00<<6, DottedNote = 0x01<<6, DoubleDottedNote = 0x02<<6, Length_2_3 = 0x03<<6 } GSM_RingNoteDurationSpec; typedef enum { Scale_55 = 1, /* 55 Hz for note A */ Scale_110, /* 110 Hz for note A */ Scale_220, Scale_440, /* first scale for Nokia */ Scale_880, Scale_1760, Scale_3520, /* last scale for Nokia */ Scale_7040, Scale_14080 } GSM_RingNoteScale; typedef struct { GSM_RingNoteDuration Duration; GSM_RingNoteDurationSpec DurationSpec; GSM_RingNoteNote Note; GSM_RingNoteStyle Style; GSM_RingNoteScale Scale; int Tempo; } GSM_RingNote; typedef enum { RING_Note = 1, RING_EnableVibra, RING_DisableVibra, RING_EnableLight, RING_DisableLight, RING_EnableLED, RING_DisableLED, RING_Repeat } GSM_RingCommandType; typedef struct { GSM_RingCommandType Type; GSM_RingNote Note; unsigned char Value; } GSM_RingCommand; typedef struct { int NrCommands; GSM_RingCommand Commands[MAX_RINGTONE_NOTES]; bool AllNotesScale; } GSM_NoteRingtone; /* FIXME: should use BinaryTone instead? */ /* Structure to hold Nokia binary ringtones. */ typedef struct { unsigned char Frame[50000]; int Length; } GSM_NokiaBinaryRingtone; typedef struct { unsigned char *Buffer; int Length; } GSM_BinaryTone; typedef enum { RING_NOTETONE = 1, RING_NOKIABINARY, RING_MIDI, RING_MMF } GSM_RingtoneFormat; /** * Structure for saving various ringtones formats */ typedef struct { /** * Ringtone saved in one of three formats */ GSM_NokiaBinaryRingtone NokiaBinary; GSM_BinaryTone BinaryTone; GSM_NoteRingtone NoteTone; /** * Ringtone format */ GSM_RingtoneFormat Format; /** * Ringtone name */ char Name[20*2]; /** * Ringtone location */ int Location; } GSM_Ringtone; typedef struct { int Group; //Nokia specific int ID; char Name[30*2]; } GSM_RingtoneInfo; typedef struct { int Number; - GSM_RingtoneInfo Ringtone[100]; + GSM_RingtoneInfo *Ringtone; } GSM_AllRingtonesInfo; GSM_Error GSM_SaveRingtoneFile(char *FileName, GSM_Ringtone *ringtone); GSM_Error GSM_ReadRingtoneFile(char *FileName, GSM_Ringtone *ringtone); void saveott(FILE *file, GSM_Ringtone *ringtone); void savemid(FILE *file, GSM_Ringtone *ringtone); void saverng(FILE *file, GSM_Ringtone *ringtone); void saveimelody(FILE *file, GSM_Ringtone *ringtone); GSM_Error savewav(FILE *file, GSM_Ringtone *ringtone); GSM_Error saverttl(FILE *file, GSM_Ringtone *ringtone); unsigned char GSM_EncodeNokiaRTTLRingtone (GSM_Ringtone ringtone, unsigned char *package, int *maxlength); unsigned char GSM_EncodeEMSSound (GSM_Ringtone ringtone, unsigned char *package, int *maxlength, double version, bool start); GSM_Error GSM_DecodeNokiaRTTLRingtone (GSM_Ringtone *ringtone, unsigned char *package, int maxlength); GSM_Error GSM_RingtoneConvert(GSM_Ringtone *dest, GSM_Ringtone *src, GSM_RingtoneFormat Format); int GSM_RTTLGetTempo (int Beats); int GSM_RingNoteGetFrequency (GSM_RingNote Note); int GSM_RingNoteGetFullDuration (GSM_RingNote Note); char *GSM_GetRingtoneName(GSM_AllRingtonesInfo *Info, int ID); #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/gammu/gammu.c b/gammu/emb/gammu/gammu.c index 684e67c..4c6486d 100644 --- a/gammu/emb/gammu/gammu.c +++ b/gammu/emb/gammu/gammu.c @@ -1,8534 +1,8609 @@ /* (c) 2002-2004 by Marcin Wiacek and Michal Cihar */ /* FM stuff by Walek */ #include <string.h> #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <locale.h> #include <signal.h> #include <ctype.h> #include <wchar.h> #ifdef WIN32 # include <windows.h> # include <process.h> # ifdef _MSC_VER # include <sys/utime.h> # else # include <utime.h> # endif #else # include <utime.h> #endif #include "../common/gammu.h" #include "gammu.h" #include "smsd/smsdcore.h" #ifdef DEBUG # include "sniff.h" #endif #ifdef GSM_ENABLE_NOKIA_DCT3 # include "depend/nokia/dct3.h" # include "depend/nokia/dct3trac/wmx.h" #endif #ifdef GSM_ENABLE_NOKIA_DCT4 # include "depend/nokia/dct4.h" #endif #ifdef GSM_ENABLE_ATGEN # include "depend/siemens/dsiemens.h" #endif #ifdef HAVE_PTHREAD # include <pthread.h> #endif #ifdef HAVE_SYS_IOCTL_H # include <sys/ioctl.h> #endif GSM_StateMachine s; GSM_Phone_Functions *Phone; static INI_Section *cfg = NULL; GSM_Error error = ERR_NONE; static int i; volatile bool gshutdown = false; void interrupt(int sign) { signal(sign, SIG_IGN); gshutdown = true; } #ifdef __GNUC__ __attribute__((format(printf, 1, 2))) #endif int printmsg(char *format, ...) { va_list argp; int result; va_start(argp, format); result = vfprintf(stdout,GetMsg(s.msg,format),argp); va_end(argp); return result; } #ifdef __GNUC__ __attribute__((format(printf, 1, 2))) #endif int printmsgerr(char *format, ...) { va_list argp; int result; va_start(argp, format); result = vfprintf(stderr,GetMsg(s.msg,format), argp); va_end(argp); return result; } static void PrintSecurityStatus() { GSM_SecurityCodeType Status; error=Phone->GetSecurityStatus(&s,&Status); Print_Error(error); switch(Status) { case SEC_SecurityCode: printmsg("Waiting for Security Code.\n"); break; case SEC_Pin: printmsg("Waiting for PIN.\n"); break; case SEC_Pin2: printmsg("Waiting for PIN2.\n"); break; case SEC_Puk: printmsg("Waiting for PUK.\n"); break; case SEC_Puk2: printmsg("Waiting for PUK2.\n"); break; case SEC_None: printmsg("Nothing to enter.\n"); break; default: printmsg("Unknown\n"); } } void Print_Error(GSM_Error error) { if (error != ERR_NONE) { printf("%s\n",print_error(error,s.di.df,s.msg)); if (error == ERR_SECURITYERROR) { printmsg("Security status: "); PrintSecurityStatus(); } if (s.opened) GSM_TerminateConnection(&s); exit (-1); } } void GSM_Init(bool checkerror) { error=GSM_InitConnection(&s,3); if (checkerror) Print_Error(error); Phone=s.Phone.Functions; } void GSM_Terminate(void) { error=GSM_TerminateConnection(&s); Print_Error(error); } static void GetStartStop(int *start, int *stop, int num, int argc, char *argv[]) { *start=atoi(argv[num]); if (*start==0) { printmsg("ERROR: enumerate locations from 1\n"); exit (-1); } if (stop!=NULL) { *stop=*start; if (argc>=num+2) *stop=atoi(argv[num+1]); if (*stop==0) { printmsg("ERROR: enumerate locations from 1\n"); exit (-1); } } } bool always_answer_yes = false; bool always_answer_no = false; static bool answer_yes(char *text) { int len; char ans[99]; while (1) { printmsgerr("%s (yes/no/ALL/ONLY/NONE) ? ",text); if (always_answer_yes) { printmsgerr("YES (always)\n"); return true; } if (always_answer_no) { printmsgerr("NO (always)\n"); return false; } len=GetLine(stdin, ans, 99); if (len==-1) exit(-1); if (!strcmp(ans, "NONE")) { always_answer_no = true; return false; } if (!strcmp(ans, "ONLY")) { always_answer_no = true; return true; } if (!strcmp(ans, "ALL")) { always_answer_yes = true; return true; } if (mystrncasecmp(ans, "yes",0)) return true; if (mystrncasecmp(ans, "no" ,0)) return false; } } #ifdef GSM_ENABLE_BEEP void GSM_PhoneBeep(void) { error = PHONE_Beep(&s); if (error != ERR_NOTSUPPORTED && error != ERR_NOTIMPLEMENTED) Print_Error(error); } #endif static GSM_Error GSM_PlayRingtone(GSM_Ringtone ringtone) { int i; bool first=true; GSM_Error error; signal(SIGINT, interrupt); printmsg("Press Ctrl+C to break...\n"); for (i=0;i<ringtone.NoteTone.NrCommands;i++) { if (gshutdown) break; if (ringtone.NoteTone.Commands[i].Type != RING_NOTETONE) continue; error=PHONE_RTTLPlayOneNote(&s,ringtone.NoteTone.Commands[i].Note,first); if (error!=ERR_NONE) return error; first = false; } /* Disables buzzer */ return s.Phone.Functions->PlayTone(&s,255*255,0,false); } static void PlayRingtone(int argc, char *argv[]) { GSM_Ringtone ringtone,ringtone2; ringtone.Format = 0; error=GSM_ReadRingtoneFile(argv[2],&ringtone); Print_Error(error); error=GSM_RingtoneConvert(&ringtone2,&ringtone,RING_NOTETONE); Print_Error(error); GSM_Init(true); error=GSM_PlayRingtone(ringtone2); Print_Error(error); GSM_Terminate(); } static void Identify(int argc, char *argv[]) { unsigned char buffer[100]; GSM_Init(true); error=Phone->GetManufacturer(&s); Print_Error(error); printmsg("Manufacturer : %s\n", s.Phone.Data.Manufacturer); error=Phone->GetModel(&s); Print_Error(error); printmsg("Model : %s (%s)\n", s.Phone.Data.ModelInfo->model, s.Phone.Data.Model); error=Phone->GetFirmware(&s); Print_Error(error); printmsg("Firmware : %s",s.Phone.Data.Version); error=Phone->GetPPM(&s, buffer); if (error != ERR_NOTSUPPORTED) { if (error != ERR_NOTIMPLEMENTED) Print_Error(error); if (error == ERR_NONE) printmsg(" %s",buffer); } if (s.Phone.Data.VerDate[0]!=0) printmsg(" (%s)",s.Phone.Data.VerDate); printf("\n"); error=Phone->GetHardware(&s, buffer); if (error != ERR_NOTSUPPORTED) { if (error != ERR_NOTIMPLEMENTED) Print_Error(error); if (error == ERR_NONE) printmsg("Hardware : %s\n",buffer); } error=Phone->GetIMEI(&s); if (error != ERR_NOTSUPPORTED) { if (error != ERR_NOTIMPLEMENTED) Print_Error(error); if (error == ERR_NONE) printmsg("IMEI : %s\n",s.Phone.Data.IMEI); error=Phone->GetOriginalIMEI(&s, buffer); if (error != ERR_NOTSUPPORTED && error != ERR_SECURITYERROR) { if (error != ERR_NOTIMPLEMENTED) Print_Error(error); if (error == ERR_NONE) printmsg("Original IMEI : %s\n",buffer); } } error=Phone->GetManufactureMonth(&s, buffer); if (error != ERR_NOTSUPPORTED && error != ERR_SECURITYERROR) { if (error != ERR_NOTIMPLEMENTED) Print_Error(error); if (error == ERR_NONE) printmsg("Manufactured : %s\n",buffer); } error=Phone->GetProductCode(&s, buffer); if (error != ERR_NOTSUPPORTED) { if (error != ERR_NOTIMPLEMENTED) Print_Error(error); if (error == ERR_NONE) printmsg("Product code : %s\n",buffer); } error=Phone->GetSIMIMSI(&s, buffer); switch (error) { case ERR_SECURITYERROR: case ERR_NOTSUPPORTED: case ERR_NOTIMPLEMENTED: break; case ERR_NONE: printmsg("SIM IMSI : %s\n",buffer); break; default: Print_Error(error); } #ifdef GSM_ENABLE_NOKIA_DCT3 DCT3Info(argc, argv); #endif #ifdef GSM_ENABLE_NOKIA_DCT4 DCT4Info(argc, argv); #endif GSM_Terminate(); } static void GetDateTime(int argc, char *argv[]) { GSM_DateTime date_time; GSM_Locale locale; GSM_Init(true); error=Phone->GetDateTime(&s, &date_time); switch (error) { case ERR_EMPTY: printmsg("Date and time not set in phone\n"); break; case ERR_NONE: printmsg("Phone time is %s\n",OSDateTime(date_time,false)); break; default: Print_Error(error); } error=Phone->GetLocale(&s, &locale); switch (error) { case ERR_NOTSUPPORTED: case ERR_NOTIMPLEMENTED: break; default: Print_Error(error); printmsg("Time format is "); if (locale.AMPMTime) printmsg("12 hours\n"); else printmsg("24 hours\n"); printmsg("Date format is "); switch (locale.DateFormat) { case GSM_Date_DDMMYYYY:printmsg("DD MM YYYY");break; case GSM_Date_MMDDYYYY:printmsg("MM DD YYYY");break; case GSM_Date_YYYYMMDD:printmsg("YYYY MM DD"); default :break; } printmsg(", date separator is %c\n",locale.DateSeparator); } GSM_Terminate(); } static void SetDateTime(int argc, char *argv[]) { GSM_DateTime date_time; GSM_GetCurrentDateTime(&date_time); GSM_Init(true); error=Phone->SetDateTime(&s, &date_time); Print_Error(error); GSM_Terminate(); } static void GetAlarm(int argc, char *argv[]) { GSM_Alarm alarm; GSM_Init(true); alarm.Location = 1; error=Phone->GetAlarm(&s, &alarm); switch (error) { case ERR_EMPTY: printmsg("Alarm not set in phone\n"); break; case ERR_NONE: if (alarm.Repeating) { printmsg("Date: %s\n","Every day"); } else { printmsg("Date: %s\n",OSDate(alarm.DateTime)); } printmsg("Time: %02d:%02d\n",alarm.DateTime.Hour, alarm.DateTime.Minute); if (alarm.Text[0] != 0 || alarm.Text[1] != 0) { printmsg("Text: \"%s\"\n", DecodeUnicodeConsole(alarm.Text)); } break; default: Print_Error(error); } GSM_Terminate(); } static void SetAlarm(int argc, char *argv[]) { GSM_Alarm alarm; alarm.DateTime.Hour = atoi(argv[2]); alarm.DateTime.Minute = atoi(argv[3]); alarm.DateTime.Second = 0; alarm.Location = 1; alarm.Repeating = true; alarm.Text[0] = 0; alarm.Text[1] = 0; GSM_Init(true); error=Phone->SetAlarm(&s, &alarm); Print_Error(error); GSM_Terminate(); } GSM_Bitmap caller[5]; -GSM_AllRingtonesInfo Info; +GSM_AllRingtonesInfo Info = {0, NULL}; bool callerinit[5] = {false, false, false, false, false}; bool ringinit = false; static void PrintMemoryEntry(GSM_MemoryEntry *entry) { GSM_Category Category; bool unknown; int z; for (i=0;i<entry->EntriesNum;i++) { unknown = false; switch (entry->Entries[i].EntryType) { case PBK_Date: printmsg("Date and time : %s\n",OSDateTime(entry->Entries[i].Date,false)); continue; case PBK_Category: Category.Location = entry->Entries[i].Number; Category.Type = Category_Phonebook; error=Phone->GetCategory(&s, &Category); if (error == ERR_NONE) { printmsg("Category : \"%s\" (%i)\n", DecodeUnicodeConsole(Category.Name), entry->Entries[i].Number); } else { printmsg("Category : %i\n", entry->Entries[i].Number); } continue; case PBK_Private: printmsg("Private : %s\n", entry->Entries[i].Number == 1 ? "Yes" : "No"); continue; case PBK_Number_General : printmsg("General number "); break; case PBK_Number_Mobile : printmsg("Mobile number "); break; case PBK_Number_Work : printmsg("Work number "); break; case PBK_Number_Fax : printmsg("Fax number "); break; case PBK_Number_Home : printmsg("Home number "); break; case PBK_Number_Pager : printmsg("Pager number "); break; case PBK_Number_Other : printmsg("Other number "); break; case PBK_Text_Note : printmsg("Text "); break; case PBK_Text_Postal : printmsg("Snail address "); break; case PBK_Text_Email : printmsg("Email address 1 "); break; case PBK_Text_Email2 : printmsg("Email address 2 "); break; case PBK_Text_URL : printmsg("URL address "); break; case PBK_Text_Name : printmsg("Name "); break; case PBK_Text_LastName : printmsg("Last name "); break; case PBK_Text_FirstName : printmsg("First name "); break; case PBK_Text_Company : printmsg("Company "); break; case PBK_Text_JobTitle : printmsg("Job title "); break; case PBK_Text_StreetAddress : printmsg("Street address "); break; case PBK_Text_City : printmsg("City "); break; case PBK_Text_State : printmsg("State "); break; case PBK_Text_Zip : printmsg("Zip code "); break; case PBK_Text_Country : printmsg("Country "); break; case PBK_Text_Custom1 : printmsg("Custom text 1 "); break; case PBK_Text_Custom2 : printmsg("Custom text 2 "); break; case PBK_Text_Custom3 : printmsg("Custom text 3 "); break; case PBK_Text_Custom4 : printmsg("Custom text 4 "); break; case PBK_Caller_Group : unknown = true; if (!callerinit[entry->Entries[i].Number]) { caller[entry->Entries[i].Number].Type = GSM_CallerGroupLogo; caller[entry->Entries[i].Number].Location = entry->Entries[i].Number; error=Phone->GetBitmap(&s,&caller[entry->Entries[i].Number]); Print_Error(error); if (caller[entry->Entries[i].Number].DefaultName) { NOKIA_GetDefaultCallerGroupName(&s,&caller[entry->Entries[i].Number]); } callerinit[entry->Entries[i].Number]=true; } printmsg("Caller group : \"%s\"\n",DecodeUnicodeConsole(caller[entry->Entries[i].Number].Text)); break; case PBK_RingtoneID : unknown = true; if (!ringinit) { error=Phone->GetRingtonesInfo(&s,&Info); if (error != ERR_NOTSUPPORTED) Print_Error(error); if (error == ERR_NONE) ringinit = true; } if (ringinit) { for (z=0;z<Info.Number;z++) { if (Info.Ringtone[z].ID == entry->Entries[i].Number) { printmsg("Ringtone : \"%s\"\n",DecodeUnicodeConsole(Info.Ringtone[z].Name)); break; } } } else { printmsg("Ringtone ID : %i\n",entry->Entries[i].Number); } break; case PBK_PictureID : unknown = true; printmsg("Picture ID : 0x%x\n",entry->Entries[i].Number); break; default : printmsg("UNKNOWN\n"); unknown = true; break; } if (!unknown) printmsg(" : \"%s\"\n", DecodeUnicodeConsole(entry->Entries[i].Text)); } printf("\n"); } static void GetAllMemory(int argc, char *argv[]) { GSM_MemoryEntry Entry; bool start = true; signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); Entry.MemoryType = 0; if (mystrncasecmp(argv[2],"DC",0)) Entry.MemoryType=MEM_DC; if (mystrncasecmp(argv[2],"ON",0)) Entry.MemoryType=MEM_ON; if (mystrncasecmp(argv[2],"RC",0)) Entry.MemoryType=MEM_RC; if (mystrncasecmp(argv[2],"MC",0)) Entry.MemoryType=MEM_MC; if (mystrncasecmp(argv[2],"ME",0)) Entry.MemoryType=MEM_ME; if (mystrncasecmp(argv[2],"SM",0)) Entry.MemoryType=MEM_SM; if (mystrncasecmp(argv[2],"VM",0)) Entry.MemoryType=MEM_VM; if (mystrncasecmp(argv[2],"FD",0)) Entry.MemoryType=MEM_FD; if (Entry.MemoryType==0) { printmsg("ERROR: unknown memory type (\"%s\")\n",argv[2]); exit (-1); } GSM_Init(true); while (!gshutdown) { error = Phone->GetNextMemory(&s, &Entry, start); if (error == ERR_EMPTY) break; + if (error != ERR_NONE && Info.Ringtone) free(Info.Ringtone); Print_Error(error); printmsg("Memory %s, Location %i\n",argv[2],Entry.Location); PrintMemoryEntry(&Entry); start = false; } + if (Info.Ringtone) free(Info.Ringtone); + GSM_Terminate(); } static void GetMemory(int argc, char *argv[]) { int j, start, stop, emptynum = 0, fillednum = 0; GSM_MemoryEntry entry; bool empty = true; entry.MemoryType=0; if (mystrncasecmp(argv[2],"DC",0)) entry.MemoryType=MEM_DC; if (mystrncasecmp(argv[2],"ON",0)) entry.MemoryType=MEM_ON; if (mystrncasecmp(argv[2],"RC",0)) entry.MemoryType=MEM_RC; if (mystrncasecmp(argv[2],"MC",0)) entry.MemoryType=MEM_MC; if (mystrncasecmp(argv[2],"ME",0)) entry.MemoryType=MEM_ME; if (mystrncasecmp(argv[2],"SM",0)) entry.MemoryType=MEM_SM; if (mystrncasecmp(argv[2],"VM",0)) entry.MemoryType=MEM_VM; if (mystrncasecmp(argv[2],"FD",0)) entry.MemoryType=MEM_FD; if (entry.MemoryType==0) { printmsg("ERROR: unknown memory type (\"%s\")\n",argv[2]); exit (-1); } GetStartStop(&start, &stop, 3, argc, argv); if (argc > 5 && strcmp(argv[5],"")) { if (mystrncasecmp(argv[5],"-nonempty",0)) { empty = false; } else { printmsg("ERROR: unknown parameter \"%s\"\n",argv[5]); exit (-1); } } GSM_Init(true); if (!strcmp(s.Phone.Data.ModelInfo->model,"3310")) { if (s.Phone.Data.VerNum<=4.06) printmsg("WARNING: you will have null names in entries. Upgrade firmware in phone to higher than 4.06\n"); } for (j=start;j<=stop;j++) { if (empty) printmsg("Memory %s, Location %i\n",argv[2],j); entry.Location=j; error=Phone->GetMemory(&s, &entry); - if (error != ERR_EMPTY) Print_Error(error); + if (error != ERR_EMPTY) { + if (Info.Ringtone) free(Info.Ringtone); + Print_Error(error); + } if (error == ERR_EMPTY) { emptynum++; if (empty) { printmsg("Entry is empty\n"); printf("\n"); } } else { fillednum++; if (!empty) printmsg("Memory %s, Location %i\n",argv[2],j); PrintMemoryEntry(&entry); } } printmsg("%i entries empty, %i entries filled\n",emptynum,fillednum); + + if (Info.Ringtone) free(Info.Ringtone); GSM_Terminate(); } #define MemoryLocationToString(x) ( \ x == MEM_ON ? "ON" : \ x == MEM_RC ? "RC" : \ x == MEM_MC ? "MC" : \ x == MEM_ME ? "ME" : \ x == MEM_SM ? "SM" : \ x == MEM_VM ? "VM" : \ x == MEM_FD ? "FD" : "XX") static void SearchOneEntry(GSM_MemoryEntry *Entry, unsigned char *Text) { int i; for (i=0;i<Entry->EntriesNum;i++) { switch (Entry->Entries[i].EntryType) { case PBK_Number_General : case PBK_Number_Mobile : case PBK_Number_Work : case PBK_Number_Fax : case PBK_Number_Home : case PBK_Number_Pager : case PBK_Number_Other : case PBK_Text_Note : case PBK_Text_Postal : case PBK_Text_Email : case PBK_Text_Email2 : case PBK_Text_URL : case PBK_Text_Name : case PBK_Text_LastName : case PBK_Text_FirstName : case PBK_Text_Company : case PBK_Text_JobTitle : case PBK_Text_StreetAddress : case PBK_Text_City : case PBK_Text_State : case PBK_Text_Zip : case PBK_Text_Country : case PBK_Text_Custom1 : case PBK_Text_Custom2 : case PBK_Text_Custom3 : case PBK_Text_Custom4 : case PBK_Caller_Group : if (mywstrstr(Entry->Entries[i].Text, Text) != NULL) { fprintf(stderr,"\n"); printmsg("Memory %s, Location %i\n",MemoryLocationToString(Entry->MemoryType),Entry->Location); PrintMemoryEntry(Entry); return; } break; default: break; } } } static void SearchOneMemory(GSM_MemoryType MemoryType, char *Title, unsigned char *Text) { GSM_MemoryEntry Entry; GSM_MemoryStatus Status; int i = 0, l = 1; bool start = true; Status.MemoryType = MemoryType; Entry.MemoryType = MemoryType; if (Phone->GetMemoryStatus(&s, &Status) == ERR_NONE) { fprintf(stderr,"%c%s: %i%%", 13, Title, (i+1)*100/(Status.MemoryUsed+1)); if (Phone->GetNextMemory != NOTSUPPORTED && Phone->GetNextMemory != NOTIMPLEMENTED) { while (i < Status.MemoryUsed) { if (gshutdown) return; i++; fprintf(stderr,"\r%s: %i%%", Title, (i+1)*100/(Status.MemoryUsed+1)); error = Phone->GetNextMemory(&s, &Entry, start); if (error == ERR_EMPTY) break; Print_Error(error); SearchOneEntry(&Entry, Text); start = false; } } else { while (i < Status.MemoryUsed) { Entry.Location = l; error = Phone->GetMemory(&s, &Entry); if (error != ERR_EMPTY) { Print_Error(error); i++; SearchOneEntry(&Entry, Text); } fprintf(stderr,"%c%s: %i%%", 13, Title, (i+1)*100/(Status.MemoryUsed+1)); l++; } } fprintf(stderr,"\n"); } } static void SearchMemory(int argc, char *argv[]) { unsigned char Text[(GSM_PHONEBOOK_TEXT_LENGTH+1)*2]; int Length; signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); Length = strlen(argv[2]); if (Length > GSM_PHONEBOOK_TEXT_LENGTH) { printmsg("Search text too long, truncating to %d chars!\n", GSM_PHONEBOOK_TEXT_LENGTH); Length = GSM_PHONEBOOK_TEXT_LENGTH; } EncodeUnicode(Text, argv[2], Length); GSM_Init(true); if (!gshutdown) SearchOneMemory(MEM_ME, "Phone phonebook", Text); if (!gshutdown) SearchOneMemory(MEM_SM, "SIM phonebook", Text); if (!gshutdown) SearchOneMemory(MEM_ON, "Own numbers", Text); if (!gshutdown) SearchOneMemory(MEM_DC, "Dialled numbers", Text); if (!gshutdown) SearchOneMemory(MEM_RC, "Received numbers", Text); if (!gshutdown) SearchOneMemory(MEM_MC, "Missed numbers", Text); if (!gshutdown) SearchOneMemory(MEM_FD, "Fix dialling", Text); if (!gshutdown) SearchOneMemory(MEM_VM, "Voice mailbox", Text); GSM_Terminate(); } static void ListMemoryCategoryEntries(int Category) { GSM_MemoryEntry Entry; bool start = true; int j; /* Category can be only for ME stored entries */ Entry.MemoryType = MEM_ME; while (!gshutdown) { error = Phone->GetNextMemory(&s, &Entry, start); if (error == ERR_EMPTY) break; Print_Error(error); for (j=0;j<Entry.EntriesNum;j++) { if (Entry.Entries[j].EntryType == PBK_Category && Entry.Entries[j].Number == Category) { printmsg("Memory %s, Location %i\n",MemoryLocationToString(Entry.MemoryType),Entry.Location); PrintMemoryEntry(&Entry); } } start = false; } } static void ListMemoryCategory(int argc, char *argv[]) { GSM_Category Category; GSM_CategoryStatus Status; int j, count; unsigned char Text[(GSM_MAX_CATEGORY_NAME_LENGTH+1)*2]; int Length; bool Number = true;; GSM_Init(true); signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); Length = strlen(argv[2]); for (j = 0; j < Length; j++) { if (!isdigit(argv[2][j])) { Number = false; break; } } if (Number) { j = atoi(argv[2]); if (j > 0) { ListMemoryCategoryEntries(j); } } else { if (Length > GSM_MAX_CATEGORY_NAME_LENGTH) { printmsg("Search text too long, truncating to %d chars!\n", GSM_MAX_CATEGORY_NAME_LENGTH); Length = GSM_MAX_CATEGORY_NAME_LENGTH; } EncodeUnicode(Text, argv[2], Length); Category.Type = Category_Phonebook; Status.Type = Category_Phonebook; if (Phone->GetCategoryStatus(&s, &Status) == ERR_NONE) { for (count=0,j=1;count<Status.Used;j++) { Category.Location=j; error=Phone->GetCategory(&s, &Category); if (error != ERR_EMPTY) { count++; if (mywstrstr(Category.Name, Text) != NULL) { ListMemoryCategoryEntries(j); } } } } } GSM_Terminate(); } static void displaysinglesmsinfo(GSM_SMSMessage sms, bool displaytext, bool displayudh) { switch (sms.PDU) { case SMS_Status_Report: printmsg("SMS status report\n"); printmsg("Status : "); switch (sms.State) { case SMS_Sent : printmsg("Sent"); break; case SMS_Read : printmsg("Read"); break; case SMS_UnRead : printmsg("UnRead"); break; case SMS_UnSent : printmsg("UnSent"); break; } printmsg("\nRemote number : \"%s\"\n",DecodeUnicodeConsole(sms.Number)); printmsg("Reference number: %d\n",sms.MessageReference); printmsg("Sent : %s\n",OSDateTime(sms.DateTime,true)); printmsg("SMSC number : \"%s\"\n",DecodeUnicodeConsole(sms.SMSC.Number)); printmsg("SMSC response : %s\n",OSDateTime(sms.SMSCTime,true)); printmsg("Delivery status : %s\n",DecodeUnicodeConsole(sms.Text)); printmsg("Details : "); if (sms.DeliveryStatus & 0x40) { if (sms.DeliveryStatus & 0x20) { printmsg("Temporary error, "); } else { printmsg("Permanent error, "); } } else if (sms.DeliveryStatus & 0x20) { printmsg("Temporary error, "); } switch (sms.DeliveryStatus) { case 0x00: printmsg("SM received by the SME"); break; case 0x01: printmsg("SM forwarded by the SC to the SME but the SC is unable to confirm delivery");break; case 0x02: printmsg("SM replaced by the SC"); break; case 0x20: printmsg("Congestion"); break; case 0x21: printmsg("SME busy"); break; case 0x22: printmsg("No response from SME"); break; case 0x23: printmsg("Service rejected"); break; case 0x24: printmsg("Quality of service not aviable"); break; case 0x25: printmsg("Error in SME"); break; case 0x40: printmsg("Remote procedure error"); break; case 0x41: printmsg("Incompatibile destination"); break; case 0x42: printmsg("Connection rejected by SME"); break; case 0x43: printmsg("Not obtainable"); break; case 0x44: printmsg("Quality of service not available"); break; case 0x45: printmsg("No internetworking available"); break; case 0x46: printmsg("SM Validity Period Expired"); break; case 0x47: printmsg("SM deleted by originating SME"); break; case 0x48: printmsg("SM Deleted by SC Administration"); break; case 0x49: printmsg("SM does not exist"); break; case 0x60: printmsg("Congestion"); break; case 0x61: printmsg("SME busy"); break; case 0x62: printmsg("No response from SME"); break; case 0x63: printmsg("Service rejected"); break; case 0x64: printmsg("Quality of service not available"); break; case 0x65: printmsg("Error in SME"); break; default : printmsg("Reserved/Specific to SC: %x",sms.DeliveryStatus); break; } printf("\n"); break; case SMS_Deliver: printmsg("SMS message\n"); if (sms.State==SMS_UnSent && sms.Memory==MEM_ME) { printmsg("Saved : %s\n",OSDateTime(sms.DateTime,true)); } else { printmsg("SMSC number : \"%s\"",DecodeUnicodeConsole(sms.SMSC.Number)); if (sms.ReplyViaSameSMSC) printmsg(" (set for reply)"); printmsg("\nSent : %s\n",OSDateTime(sms.DateTime,true)); } /* No break. The only difference for SMS_Deliver and SMS_Submit is, * that SMS_Deliver contains additional data. We wrote them and then go * for data shared with SMS_Submit */ case SMS_Submit: if (sms.ReplaceMessage != 0) printmsg("SMS replacing ID : %i\n",sms.ReplaceMessage); /* If we went here from "case SMS_Deliver", we don't write "SMS Message" */ if (sms.PDU==SMS_Submit) { printmsg("SMS message\n"); if (sms.State==SMS_UnSent && sms.Memory==MEM_ME) { } else { printmsg("Reference number : %d\n",sms.MessageReference); } } if (sms.Name[0] != 0x00 || sms.Name[1] != 0x00) { printmsg("Name : \"%s\"\n",DecodeUnicodeConsole(sms.Name)); } if (sms.Class != -1) { printmsg("Class : %i\n",sms.Class); } printmsg("Coding : "); switch (sms.Coding) { case SMS_Coding_Unicode : printmsg("Unicode\n"); break; case SMS_Coding_Default : printmsg("Default GSM alphabet\n"); break; case SMS_Coding_8bit : printmsg("8 bit\n"); break; } if (sms.State==SMS_UnSent && sms.Memory==MEM_ME) { } else { printmsg("Remote number : \"%s\"\n",DecodeUnicodeConsole(sms.Number)); } printmsg("Status : "); switch (sms.State) { case SMS_Sent : printmsg("Sent\n"); break; case SMS_Read : printmsg("Read\n"); break; case SMS_UnRead : printmsg("UnRead\n"); break; case SMS_UnSent : printmsg("UnSent\n"); break; } if (sms.UDH.Type != UDH_NoUDH) { printmsg("User Data Header : "); switch (sms.UDH.Type) { case UDH_ConcatenatedMessages : printmsg("Concatenated (linked) message"); break; case UDH_ConcatenatedMessages16bit : printmsg("Concatenated (linked) message"); break; case UDH_DisableVoice : printmsg("Disables voice indicator"); break; case UDH_EnableVoice : printmsg("Enables voice indicator"); break; case UDH_DisableFax : printmsg("Disables fax indicator"); break; case UDH_EnableFax : printmsg("Enables fax indicator"); break; case UDH_DisableEmail : printmsg("Disables email indicator"); break; case UDH_EnableEmail : printmsg("Enables email indicator"); break; case UDH_VoidSMS : printmsg("Void SMS"); break; case UDH_NokiaWAP : printmsg("Nokia WAP bookmark"); break; case UDH_NokiaOperatorLogoLong : printmsg("Nokia operator logo"); break; case UDH_NokiaWAPLong : printmsg("Nokia WAP bookmark or WAP/MMS settings"); break; case UDH_NokiaRingtone : printmsg("Nokia ringtone"); break; case UDH_NokiaRingtoneLong : printmsg("Nokia ringtone"); break; case UDH_NokiaOperatorLogo : printmsg("Nokia GSM operator logo"); break; case UDH_NokiaCallerLogo : printmsg("Nokia caller logo"); break; case UDH_NokiaProfileLong : printmsg("Nokia profile"); break; case UDH_NokiaCalendarLong : printmsg("Nokia calendar note"); break; case UDH_NokiaPhonebookLong : printmsg("Nokia phonebook entry"); break; case UDH_UserUDH : printmsg("User UDH"); break; case UDH_MMSIndicatorLong : printmsg("MMS indicator"); break; case UDH_NoUDH: break; } if (sms.UDH.Type != UDH_NoUDH) { if (sms.UDH.ID8bit != -1) printmsg(", ID (8 bit) %i",sms.UDH.ID8bit); if (sms.UDH.ID16bit != -1) printmsg(", ID (16 bit) %i",sms.UDH.ID16bit); if (sms.UDH.PartNumber != -1 && sms.UDH.AllParts != -1) { if (displayudh) { printmsg(", part %i of %i",sms.UDH.PartNumber,sms.UDH.AllParts); } else { printmsg(", %i parts",sms.UDH.AllParts); } } } printf("\n"); } if (displaytext) { printf("\n"); if (sms.Coding!=SMS_Coding_8bit) { printmsg("%s\n",DecodeUnicodeConsole(sms.Text)); } else { printmsg("8 bit SMS, cannot be displayed here\n"); } } break; } } static void displaymultismsinfo (GSM_MultiSMSMessage sms, bool eachsms, bool ems) { GSM_MultiPartSMSInfo SMSInfo; bool RetVal,udhinfo=true; int j; /* GSM_DecodeMultiPartSMS returns if decoded SMS contenst correctly */ RetVal = GSM_DecodeMultiPartSMS(&SMSInfo,&sms,ems); if (eachsms) { if (sms.SMS[0].UDH.Type != UDH_NoUDH && sms.SMS[0].UDH.AllParts == sms.Number) udhinfo = false; if (RetVal && !udhinfo) { displaysinglesmsinfo(sms.SMS[0],false,false); printf("\n"); } else { for (j=0;j<sms.Number;j++) { displaysinglesmsinfo(sms.SMS[j],!RetVal,udhinfo); printf("\n"); } } } else { for (j=0;j<sms.Number;j++) { displaysinglesmsinfo(sms.SMS[j],!RetVal,true); printf("\n"); } } if (!RetVal) { GSM_FreeMultiPartSMSInfo(&SMSInfo); return; } if (SMSInfo.Unknown) printmsg("Some details were ignored (unknown or not implemented in decoding functions)\n\n"); for (i=0;i<SMSInfo.EntriesNum;i++) { switch (SMSInfo.Entries[i].ID) { case SMS_NokiaRingtone: printmsg("Ringtone \"%s\"\n",DecodeUnicodeConsole(SMSInfo.Entries[i].Ringtone->Name)); saverttl(stdout,SMSInfo.Entries[i].Ringtone); printf("\n"); if (s.Phone.Functions->PlayTone!=NOTSUPPORTED && s.Phone.Functions->PlayTone!=NOTIMPLEMENTED) { if (answer_yes("Do you want to play it")) GSM_PlayRingtone(*SMSInfo.Entries[i].Ringtone); } break; case SMS_NokiaCallerLogo: printmsg("Caller logo\n\n"); GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]); break; case SMS_NokiaOperatorLogo: printmsg("Operator logo for %s network (%s, %s)\n\n", SMSInfo.Entries[i].Bitmap->Bitmap[0].NetworkCode, DecodeUnicodeConsole(GSM_GetNetworkName(SMSInfo.Entries[i].Bitmap->Bitmap[0].NetworkCode)), DecodeUnicodeConsole(GSM_GetCountryName(SMSInfo.Entries[i].Bitmap->Bitmap[0].NetworkCode))); GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]); break; case SMS_NokiaScreenSaverLong: printmsg("Screen saver\n"); GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]); break; case SMS_NokiaPictureImageLong: printmsg("Picture Image\n"); if (UnicodeLength(SMSInfo.Entries[i].Bitmap->Bitmap[0].Text)!=0) printmsg("Text: \"%s\"\n\n",DecodeUnicodeConsole(SMSInfo.Entries[i].Bitmap->Bitmap[0].Text)); GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]); break; case SMS_NokiaProfileLong: printmsg("Profile\n"); GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]); break; case SMS_ConcatenatedTextLong: case SMS_ConcatenatedAutoTextLong: case SMS_ConcatenatedTextLong16bit: case SMS_ConcatenatedAutoTextLong16bit: printmsg("%s\n",DecodeUnicodeConsole(SMSInfo.Entries[i].Buffer)); break; case SMS_EMSFixedBitmap: case SMS_EMSVariableBitmap: GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]); break; case SMS_EMSAnimation: /* Can't show animation, we show first frame */ GSM_PrintBitmap(stdout,&SMSInfo.Entries[i].Bitmap->Bitmap[0]); break; case SMS_EMSPredefinedSound: printmsg("\nEMS sound ID: %i\n",SMSInfo.Entries[i].Number); break; case SMS_EMSPredefinedAnimation: printmsg("\nEMS animation ID: %i\n",SMSInfo.Entries[i].Number); break; default: printf("Error\n"); break; } } printf("\n"); GSM_FreeMultiPartSMSInfo(&SMSInfo); } static void NetworkInfo(int argc, char *argv[]) { GSM_NetworkInfo NetInfo; GSM_Init(true); if (Phone->GetNetworkInfo(&s,&NetInfo)==ERR_NONE) { printmsg("Network state : "); switch (NetInfo.State) { case GSM_HomeNetwork : printmsg("home network\n"); break; case GSM_RoamingNetwork : printmsg("roaming network\n"); break; case GSM_RequestingNetwork : printmsg("requesting network\n"); break; case GSM_NoNetwork : printmsg("not logged into network\n"); break; case GSM_RegistrationDenied : printmsg("registration to network denied\n"); break; case GSM_NetworkStatusUnknown : printmsg("unknown\n"); break; default : printmsg("unknown\n"); } if (NetInfo.State == GSM_HomeNetwork || NetInfo.State == GSM_RoamingNetwork) { printmsg("Network : %s (%s", NetInfo.NetworkCode,DecodeUnicodeConsole(GSM_GetNetworkName(NetInfo.NetworkCode))); printmsg(", %s)", DecodeUnicodeConsole(GSM_GetCountryName(NetInfo.NetworkCode))); printmsg(", LAC %s, CellID %s\n", NetInfo.LAC,NetInfo.CID); if (NetInfo.NetworkName[0] != 0x00 || NetInfo.NetworkName[1] != 0x00) { printmsg("Name in phone : \"%s\"\n",DecodeUnicodeConsole(NetInfo.NetworkName)); } } } GSM_Terminate(); } static void IncomingSMS(char *Device, GSM_SMSMessage sms) { GSM_MultiSMSMessage SMS; printmsg("SMS message received\n"); SMS.Number = 1; memcpy(&SMS.SMS[0],&sms,sizeof(GSM_SMSMessage)); displaymultismsinfo(SMS,false,false); } static void IncomingCB(char *Device, GSM_CBMessage CB) { printmsg("CB message received\n"); printmsg("Channel %i, text \"%s\"\n",CB.Channel,DecodeUnicodeConsole(CB.Text)); } static void IncomingCall(char *Device, GSM_Call call) { printmsg("Call info : "); if (call.CallIDAvailable) printmsg("ID %i, ",call.CallID); switch(call.Status) { case GSM_CALL_IncomingCall : printmsg("incoming call from \"%s\"\n",DecodeUnicodeConsole(call.PhoneNumber)); break; case GSM_CALL_OutgoingCall : printmsg("outgoing call to \"%s\"\n",DecodeUnicodeConsole(call.PhoneNumber)); break; case GSM_CALL_CallStart : printmsg("call started\n"); break; case GSM_CALL_CallEnd : printmsg("end of call (unknown side)\n"); break; case GSM_CALL_CallLocalEnd : printmsg("call end from our side\n"); break; case GSM_CALL_CallRemoteEnd : printmsg("call end from remote side (code %i)\n",call.StatusCode); break; case GSM_CALL_CallEstablished : printmsg("call established. Waiting for answer\n"); break; case GSM_CALL_CallHeld : printmsg("call held\n"); break; case GSM_CALL_CallResumed : printmsg("call resumed\n"); break; case GSM_CALL_CallSwitched : printmsg("call switched\n"); break; } } static void IncomingUSSD(char *Device, char *Buffer) { printmsg("Service reply: \"%s\"\n",DecodeUnicodeConsole(Buffer)); } #define CHECKMEMORYSTATUS(x, m, a1, b1) { \ x.MemoryType=m; \ if (Phone->GetMemoryStatus(&s, &x) == ERR_NONE) \ printmsg("%s %03d, %s %03d\n", a1, x.MemoryUsed, b1, x.MemoryFree); \ } static void Monitor(int argc, char *argv[]) { GSM_MemoryStatus MemStatus; GSM_SMSMemoryStatus SMSStatus; GSM_ToDoStatus ToDoStatus; GSM_CalendarStatus CalendarStatus; GSM_NetworkInfo NetInfo; GSM_BatteryCharge BatteryCharge; GSM_SignalQuality SignalQuality; int count = -1; if (argc >= 3) { count = atoi(argv[2]); if (count <= 0) count = -1; } signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); printmsg("Entering monitor mode...\n\n"); GSM_Init(true); s.User.IncomingSMS = IncomingSMS; s.User.IncomingCB = IncomingCB; s.User.IncomingCall = IncomingCall; s.User.IncomingUSSD = IncomingUSSD; error=Phone->SetIncomingSMS (&s,true); printmsg("Enabling info about incoming SMS : %s\n",print_error(error,NULL,s.msg)); error=Phone->SetIncomingCB (&s,true); printmsg("Enabling info about incoming CB : %s\n",print_error(error,NULL,s.msg)); error=Phone->SetIncomingCall (&s,true); printmsg("Enabling info about calls : %s\n",print_error(error,NULL,s.msg)); error=Phone->SetIncomingUSSD (&s,true); printmsg("Enabling info about USSD : %s\n\n",print_error(error,NULL,s.msg)); while (!gshutdown && count != 0) { if (count > 0) count--; CHECKMEMORYSTATUS(MemStatus,MEM_SM,"SIM phonebook : Used","Free"); if (gshutdown) break; CHECKMEMORYSTATUS(MemStatus,MEM_DC,"Dialled numbers : Used","Free"); if (gshutdown) break; CHECKMEMORYSTATUS(MemStatus,MEM_RC,"Received numbers : Used","Free"); if (gshutdown) break; CHECKMEMORYSTATUS(MemStatus,MEM_MC,"Missed numbers : Used","Free"); if (gshutdown) break; CHECKMEMORYSTATUS(MemStatus,MEM_ON,"Own numbers : Used","Free"); if (gshutdown) break; CHECKMEMORYSTATUS(MemStatus,MEM_ME,"Phone phonebook : Used","Free"); if (gshutdown) break; if (Phone->GetToDoStatus(&s, &ToDoStatus) == ERR_NONE) { printmsg("ToDos : Used %d\n", ToDoStatus.Used); } if (gshutdown) break; if (Phone->GetCalendarStatus(&s, &CalendarStatus) == ERR_NONE) { printmsg("Calendar : Used %d\n", CalendarStatus.Used); } if (gshutdown) break; if (Phone->GetBatteryCharge(&s,&BatteryCharge)==ERR_NONE) { if (BatteryCharge.BatteryPercent != -1) printmsg("Battery level : %i percent\n", BatteryCharge.BatteryPercent); if (BatteryCharge.ChargeState != 0) { printmsg("Charge state : "); switch (BatteryCharge.ChargeState) { case GSM_BatteryPowered: printmsg("powered from battery"); break; case GSM_BatteryConnected: printmsg("battery connected, but not powered from battery"); break; case GSM_BatteryNotConnected: printmsg("battery not connected"); break; case GSM_PowerFault: printmsg("detected power failure"); break; default: printmsg("unknown"); break; } printf("\n"); } } if (gshutdown) break; if (Phone->GetSignalQuality(&s,&SignalQuality)==ERR_NONE) { if (SignalQuality.SignalStrength != -1) printmsg("Signal strength : %i dBm\n", SignalQuality.SignalStrength); if (SignalQuality.SignalPercent != -1) printmsg("Network level : %i percent\n", SignalQuality.SignalPercent); if (SignalQuality.BitErrorRate != -1) printmsg("Bit error rate : %i percent\n", SignalQuality.BitErrorRate); } if (gshutdown) break; if (Phone->GetSMSStatus(&s,&SMSStatus)==ERR_NONE) { if (SMSStatus.SIMSize > 0) { printmsg("SIM SMS status : %i used, %i unread, %i locations\n", SMSStatus.SIMUsed, SMSStatus.SIMUnRead, SMSStatus.SIMSize); } if (SMSStatus.PhoneSize > 0) { printmsg("Phone SMS status : %i used, %i unread, %i locations", SMSStatus.PhoneUsed, SMSStatus.PhoneUnRead, SMSStatus.PhoneSize); if (SMSStatus.TemplatesUsed!=0) printmsg(", %i templates", SMSStatus.TemplatesUsed); printf("\n"); } } if (gshutdown) break; if (Phone->GetNetworkInfo(&s,&NetInfo)==ERR_NONE) { printmsg("Network state : "); switch (NetInfo.State) { case GSM_HomeNetwork : printmsg("home network\n"); break; case GSM_RoamingNetwork : printmsg("roaming network\n"); break; case GSM_RequestingNetwork : printmsg("requesting network\n"); break; case GSM_NoNetwork : printmsg("not logged into network\n"); break; case GSM_RegistrationDenied : printmsg("registration to network denied\n"); break; case GSM_NetworkStatusUnknown : printmsg("unknown\n"); break; default : printmsg("unknown\n"); } if (NetInfo.State == GSM_HomeNetwork || NetInfo.State == GSM_RoamingNetwork) { printmsg("Network : %s (%s", NetInfo.NetworkCode,DecodeUnicodeConsole(GSM_GetNetworkName(NetInfo.NetworkCode))); printmsg(", %s)", DecodeUnicodeConsole(GSM_GetCountryName(NetInfo.NetworkCode))); printmsg(", LAC %s, CID %s\n", NetInfo.LAC,NetInfo.CID); if (NetInfo.NetworkName[0] != 0x00 || NetInfo.NetworkName[1] != 0x00) { printmsg("Name in phone : \"%s\"\n",DecodeUnicodeConsole(NetInfo.NetworkName)); } } } printf("\n"); } printmsg("Leaving monitor mode...\n"); GSM_Terminate(); } static void IncomingUSSD2(char *Device, char *Buffer) { printmsg("Service reply: \"%s\"\n",DecodeUnicodeConsole(Buffer)); gshutdown = true; } static void GetUSSD(int argc, char *argv[]) { GSM_Init(true); signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); s.User.IncomingUSSD = IncomingUSSD2; error=Phone->SetIncomingUSSD(&s,true); Print_Error(error); error=Phone->DialVoice(&s, argv[2], GSM_CALL_DefaultNumberPresence); Print_Error(error); while (!gshutdown) GSM_ReadDevice(&s,true); GSM_Terminate(); } static void GetSMSC(int argc, char *argv[]) { GSM_SMSC smsc; int start, stop; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { smsc.Location=i; error=Phone->GetSMSC(&s, &smsc); Print_Error(error); if (!strcmp(DecodeUnicodeConsole(smsc.Name),"")) { printmsg("%i. Set %i\n",smsc.Location, smsc.Location); } else { printmsg("%i. \"%s\"\n",smsc.Location, DecodeUnicodeConsole(smsc.Name)); } printmsg("Number : \"%s\"\n",DecodeUnicodeConsole(smsc.Number)); printmsg("Default number : \"%s\"\n",DecodeUnicodeConsole(smsc.DefaultNumber)); printmsg("Format : "); switch (smsc.Format) { case SMS_FORMAT_Text : printmsg("Text"); break; case SMS_FORMAT_Fax : printmsg("Fax"); break; case SMS_FORMAT_Email : printmsg("Email"); break; case SMS_FORMAT_Pager : printmsg("Pager"); break; } printf("\n"); printmsg("Validity : "); switch (smsc.Validity.Relative) { case SMS_VALID_1_Hour : printmsg("1 hour"); break; case SMS_VALID_6_Hours : printmsg("6 hours"); break; case SMS_VALID_1_Day : printmsg("24 hours"); break; case SMS_VALID_3_Days : printmsg("72 hours"); break; case SMS_VALID_1_Week : printmsg("1 week"); break; case SMS_VALID_Max_Time : printmsg("Maximum time"); break; default : if (smsc.Validity.Relative >= 0 && smsc.Validity.Relative <= 143) { printmsg("%i minutes",(smsc.Validity.Relative+1)*5); } else if (smsc.Validity.Relative >= 144 && smsc.Validity.Relative <= 167) { printmsg("%i minutes",12*60 + (smsc.Validity.Relative-143)*30); } else if (smsc.Validity.Relative >= 168 && smsc.Validity.Relative <= 196) { printmsg("%i days",smsc.Validity.Relative-166); } else if (smsc.Validity.Relative >= 197 && smsc.Validity.Relative <= 255) { printmsg("%i weeks",smsc.Validity.Relative-192); } } printf("\n"); } GSM_Terminate(); } static void GetSMS(int argc, char *argv[]) { GSM_MultiSMSMessage sms; GSM_SMSFolders folders; int start, stop; int j; GetStartStop(&start, &stop, 3, argc, argv); GSM_Init(true); error=Phone->GetSMSFolders(&s, &folders); Print_Error(error); for (j = start; j <= stop; j++) { sms.SMS[0].Folder = atoi(argv[2]); sms.SMS[0].Location = j; error=Phone->GetSMS(&s, &sms); switch (error) { case ERR_EMPTY: printmsg("Location %i\n",sms.SMS[0].Location); printmsg("Empty\n"); break; default: Print_Error(error); printmsg("Location %i, folder \"%s\"",sms.SMS[0].Location,DecodeUnicodeConsole(folders.Folder[sms.SMS[0].Folder-1].Name)); switch(sms.SMS[0].Memory) { case MEM_SM: printmsg(", SIM memory"); break; case MEM_ME: printmsg(", phone memory"); break; case MEM_MT: printmsg(", phone or SIM memory"); break; default : break; } if (sms.SMS[0].InboxFolder) printmsg(", Inbox folder"); printf("\n"); displaymultismsinfo(sms,false,false); } } GSM_Terminate(); } static void DeleteSMS(int argc, char *argv[]) { GSM_SMSMessage sms; int start, stop; sms.Folder=atoi(argv[2]); GetStartStop(&start, &stop, 3, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { sms.Folder = 0; sms.Location = i; error=Phone->DeleteSMS(&s, &sms); Print_Error(error); } #ifdef GSM_ENABLE_BEEP GSM_PhoneBeep(); #endif GSM_Terminate(); } static void GetAllSMS(int argc, char *argv[]) { GSM_MultiSMSMessage sms; GSM_SMSFolders folders; bool start = true; GSM_Init(true); error=Phone->GetSMSFolders(&s, &folders); Print_Error(error); while (error == ERR_NONE) { sms.SMS[0].Folder=0x00; error=Phone->GetNextSMS(&s, &sms, start); switch (error) { case ERR_EMPTY: break; default: Print_Error(error); printmsg("Location %i, folder \"%s\"",sms.SMS[0].Location,DecodeUnicodeConsole(folders.Folder[sms.SMS[0].Folder-1].Name)); switch(sms.SMS[0].Memory) { case MEM_SM: printmsg(", SIM memory"); break; case MEM_ME: printmsg(", phone memory"); break; case MEM_MT: printmsg(", phone or SIM memory"); break; default : break; } if (sms.SMS[0].InboxFolder) printmsg(", Inbox folder"); printf("\n"); displaymultismsinfo(sms,false,false); } start=false; } fprintf(stderr,"\n"); #ifdef GSM_ENABLE_BEEP GSM_PhoneBeep(); #endif GSM_Terminate(); } static void GetEachSMS(int argc, char *argv[]) { GSM_MultiSMSMessage *GetSMS[PHONE_MAXSMSINFOLDER],*SortedSMS[PHONE_MAXSMSINFOLDER],sms; int GetSMSNumber = 0,i,j; GSM_SMSFolders folders; bool start = true, ems = true; GetSMS[0] = NULL; GSM_Init(true); error=Phone->GetSMSFolders(&s, &folders); Print_Error(error); fprintf(stderr,"Reading: "); while (error == ERR_NONE) { sms.SMS[0].Folder=0x00; error=Phone->GetNextSMS(&s, &sms, start); switch (error) { case ERR_EMPTY: break; default: Print_Error(error); GetSMS[GetSMSNumber] = malloc(sizeof(GSM_MultiSMSMessage)); if (GetSMS[GetSMSNumber] == NULL) Print_Error(ERR_MOREMEMORY); GetSMS[GetSMSNumber+1] = NULL; memcpy(GetSMS[GetSMSNumber],&sms,sizeof(GSM_MultiSMSMessage)); GetSMSNumber++; if (GetSMSNumber==PHONE_MAXSMSINFOLDER) { fprintf(stderr,"SMS counter overflow\n"); return; } } fprintf(stderr,"*"); start=false; } fprintf(stderr,"\n"); #ifdef GSM_ENABLE_BEEP GSM_PhoneBeep(); #endif error = GSM_LinkSMS(GetSMS, SortedSMS, ems); Print_Error(error); i=0; while(GetSMS[i] != NULL) { free(GetSMS[i]); GetSMS[i] = NULL; i++; } i=0; while(SortedSMS[i] != NULL) { for (j=0;j<SortedSMS[i]->Number;j++) { if ((j==0) || (j!=0 && SortedSMS[i]->SMS[j].Location != SortedSMS[i]->SMS[j-1].Location)) { printmsg("Location %i, folder \"%s\"",SortedSMS[i]->SMS[j].Location,DecodeUnicodeConsole(folders.Folder[SortedSMS[i]->SMS[j].Folder-1].Name)); switch(SortedSMS[i]->SMS[j].Memory) { case MEM_SM: printmsg(", SIM memory"); break; case MEM_ME: printmsg(", phone memory"); break; case MEM_MT: printmsg(", phone or SIM memory"); break; default : break; } if (SortedSMS[i]->SMS[j].InboxFolder) printmsg(", Inbox folder"); printf("\n"); } } displaymultismsinfo(*SortedSMS[i],true,ems); free(SortedSMS[i]); SortedSMS[i] = NULL; i++; } GSM_Terminate(); } static void GetSMSFolders(int argc, char *argv[]) { GSM_SMSFolders folders; GSM_Init(true); error=Phone->GetSMSFolders(&s,&folders); Print_Error(error); for (i=0;i<folders.Number;i++) { printmsg("%i. \"%30s\"",i+1,DecodeUnicodeConsole(folders.Folder[i].Name)); switch(folders.Folder[i].Memory) { case MEM_SM: printmsg(", SIM memory"); break; case MEM_ME: printmsg(", phone memory"); break; case MEM_MT: printmsg(", phone or SIM memory"); break; default : break; } if (folders.Folder[i].InboxFolder) printmsg(", Inbox folder"); printf("\n"); } GSM_Terminate(); } static void GetRingtone(int argc, char *argv[]) { GSM_Ringtone ringtone; bool PhoneRingtone = false; if (mystrncasecmp(argv[1],"--getphoneringtone",0)) PhoneRingtone = true; GetStartStop(&ringtone.Location, NULL, 2, argc, argv); GSM_Init(true); ringtone.Format=0; error=Phone->GetRingtone(&s,&ringtone,PhoneRingtone); Print_Error(error); switch (ringtone.Format) { case RING_NOTETONE : printmsg("Smart Messaging"); break; case RING_NOKIABINARY : printmsg("Nokia binary"); break; case RING_MIDI : printmsg("MIDI"); break; case RING_MMF : printmsg("SMAF (MMF)"); break; } printmsg(" format, ringtone \"%s\"\n",DecodeUnicodeConsole(ringtone.Name)); if (argc==4) { error=GSM_SaveRingtoneFile(argv[3], &ringtone); Print_Error(error); } GSM_Terminate(); } static void GetRingtonesList(int argc, char *argv[]) { - GSM_AllRingtonesInfo Info; + GSM_AllRingtonesInfo Info = {0, NULL}; int i; GSM_Init(true); error=Phone->GetRingtonesInfo(&s,&Info); + if (error != ERR_NONE && Info.Ringtone) free(Info.Ringtone); Print_Error(error); GSM_Terminate(); for (i=0;i<Info.Number;i++) printmsg("%i. \"%s\"\n",i,DecodeUnicodeConsole(Info.Ringtone[i].Name)); + + if (Info.Ringtone) free(Info.Ringtone); } static void DialVoice(int argc, char *argv[]) { GSM_CallShowNumber ShowNumber = GSM_CALL_DefaultNumberPresence; if (argc > 3) { if (mystrncasecmp(argv[3],"show",0)) { ShowNumber = GSM_CALL_ShowNumber; } else if (mystrncasecmp(argv[3],"hide",0)) { ShowNumber = GSM_CALL_HideNumber; } else { printmsg("Unknown parameter (\"%s\")\n",argv[3]); exit(-1); } } GSM_Init(true); error=Phone->DialVoice(&s, argv[2], ShowNumber); Print_Error(error); GSM_Terminate(); } static void CancelCall(int argc, char *argv[]) { GSM_Init(true); if (argc>2) { error=Phone->CancelCall(&s,atoi(argv[2]),false); } else { error=Phone->CancelCall(&s,0,true); } Print_Error(error); GSM_Terminate(); } static void AnswerCall(int argc, char *argv[]) { GSM_Init(true); if (argc>2) { error=Phone->AnswerCall(&s,atoi(argv[2]),false); } else { error=Phone->AnswerCall(&s,0,true); } Print_Error(error); GSM_Terminate(); } static void UnholdCall(int argc, char *argv[]) { GSM_Init(true); error=Phone->UnholdCall(&s,atoi(argv[2])); Print_Error(error); GSM_Terminate(); } static void HoldCall(int argc, char *argv[]) { GSM_Init(true); error=Phone->HoldCall(&s,atoi(argv[2])); Print_Error(error); GSM_Terminate(); } static void ConferenceCall(int argc, char *argv[]) { GSM_Init(true); error=Phone->ConferenceCall(&s,atoi(argv[2])); Print_Error(error); GSM_Terminate(); } static void SplitCall(int argc, char *argv[]) { GSM_Init(true); error=Phone->SplitCall(&s,atoi(argv[2])); Print_Error(error); GSM_Terminate(); } static void SwitchCall(int argc, char *argv[]) { GSM_Init(true); if (argc > 2) { error=Phone->SwitchCall(&s,atoi(argv[2]),false); } else { error=Phone->SwitchCall(&s,0,true); } Print_Error(error); GSM_Terminate(); } static void TransferCall(int argc, char *argv[]) { GSM_Init(true); if (argc > 2) { error=Phone->TransferCall(&s,atoi(argv[2]),false); } else { error=Phone->TransferCall(&s,0,true); } Print_Error(error); GSM_Terminate(); } static void AddSMSFolder(int argc, char *argv[]) { unsigned char buffer[200]; GSM_Init(true); EncodeUnicode(buffer,argv[2],strlen(argv[2])); error=Phone->AddSMSFolder(&s,buffer); Print_Error(error); GSM_Terminate(); } static void Reset(int argc, char *argv[]) { bool hard; if (mystrncasecmp(argv[2],"SOFT",0)) { hard=false; } else if (mystrncasecmp(argv[2],"HARD",0)) { hard=true; } else { printmsg("What type of reset do you want (\"%s\") ?\n",argv[2]); exit(-1); } GSM_Init(true); error=Phone->Reset(&s, hard); Print_Error(error); GSM_Terminate(); } static void PrintCalendar(GSM_CalendarEntry *Note) { int i_age = 0,i; GSM_DateTime Alarm,DateTime; GSM_MemoryEntry entry; unsigned char *name; bool repeating = false; int repeat_dayofweek = -1; int repeat_day = -1; int repeat_weekofmonth = -1; int repeat_month = -1; int repeat_frequency = -1; GSM_DateTime repeat_startdate = {0,0,0,0,0,0,0}; GSM_DateTime repeat_stopdate = {0,0,0,0,0,0,0}; printmsg("Location : %d\n", Note->Location); printmsg("Note type : "); switch (Note->Type) { case GSM_CAL_REMINDER : printmsg("Reminder (Date)\n"); break; case GSM_CAL_CALL : printmsg("Call\n"); break; case GSM_CAL_MEETING : printmsg("Meeting\n"); break; case GSM_CAL_BIRTHDAY : printmsg("Birthday (Anniversary)\n"); break; case GSM_CAL_MEMO : printmsg("Memo (Miscellaneous)\n"); break; case GSM_CAL_TRAVEL : printmsg("Travel\n"); break; case GSM_CAL_VACATION : printmsg("Vacation\n"); break; case GSM_CAL_ALARM : printmsg("Alarm\n"); break; case GSM_CAL_DAILY_ALARM : printmsg("Daily alarm\n"); break; case GSM_CAL_T_ATHL : printmsg("Training/Athletism\n"); break; case GSM_CAL_T_BALL : printmsg("Training/Ball Games\n"); break; case GSM_CAL_T_CYCL : printmsg("Training/Cycling\n"); break; case GSM_CAL_T_BUDO : printmsg("Training/Budo\n"); break; case GSM_CAL_T_DANC : printmsg("Training/Dance\n"); break; case GSM_CAL_T_EXTR : printmsg("Training/Extreme Sports\n"); break; case GSM_CAL_T_FOOT : printmsg("Training/Football\n"); break; case GSM_CAL_T_GOLF : printmsg("Training/Golf\n"); break; case GSM_CAL_T_GYM : printmsg("Training/Gym\n"); break; case GSM_CAL_T_HORS : printmsg("Training/Horse Races\n"); break; case GSM_CAL_T_HOCK : printmsg("Training/Hockey\n"); break; case GSM_CAL_T_RACE : printmsg("Training/Races\n"); break; case GSM_CAL_T_RUGB : printmsg("Training/Rugby\n"); break; case GSM_CAL_T_SAIL : printmsg("Training/Sailing\n"); break; case GSM_CAL_T_STRE : printmsg("Training/Street Games\n"); break; case GSM_CAL_T_SWIM : printmsg("Training/Swimming\n"); break; case GSM_CAL_T_TENN : printmsg("Training/Tennis\n"); break; case GSM_CAL_T_TRAV : printmsg("Training/Travels\n"); break; case GSM_CAL_T_WINT : printmsg("Training/Winter Games\n"); break; default : printmsg("UNKNOWN\n"); } Alarm.Year = 0; repeating = false; repeat_dayofweek = -1; repeat_day = -1; repeat_weekofmonth = -1; repeat_month = -1; repeat_frequency = -1; repeat_startdate.Day = 0; repeat_stopdate.Day = 0; for (i=0;i<Note->EntriesNum;i++) { switch (Note->Entries[i].EntryType) { case CAL_START_DATETIME: printmsg("Start : %s\n",OSDateTime(Note->Entries[i].Date,false)); memcpy(&DateTime,&Note->Entries[i].Date,sizeof(GSM_DateTime)); break; case CAL_END_DATETIME: printmsg("Stop : %s\n",OSDateTime(Note->Entries[i].Date,false)); memcpy(&DateTime,&Note->Entries[i].Date,sizeof(GSM_DateTime)); break; case CAL_ALARM_DATETIME: printmsg("Tone alarm : %s\n",OSDateTime(Note->Entries[i].Date,false)); memcpy(&Alarm,&Note->Entries[i].Date,sizeof(GSM_DateTime)); break; case CAL_SILENT_ALARM_DATETIME: printmsg("Silent alarm : %s\n",OSDateTime(Note->Entries[i].Date,false)); memcpy(&Alarm,&Note->Entries[i].Date,sizeof(GSM_DateTime)); break; case CAL_RECURRANCE: printmsg("Repeat : %d day%s\n",Note->Entries[i].Number/24, ((Note->Entries[i].Number/24)>1) ? "s":"" ); break; case CAL_TEXT: printmsg("Text : \"%s\"\n",DecodeUnicodeConsole(Note->Entries[i].Text)); break; case CAL_LOCATION: printmsg("Location : \"%s\"\n",DecodeUnicodeConsole(Note->Entries[i].Text)); break; case CAL_PHONE: printmsg("Phone : \"%s\"\n",DecodeUnicodeConsole(Note->Entries[i].Text)); break; case CAL_PRIVATE: printmsg("Private : %s\n",Note->Entries[i].Number == 1 ? "Yes" : "No"); break; case CAL_CONTACTID: entry.Location = Note->Entries[i].Number; entry.MemoryType = MEM_ME; error=Phone->GetMemory(&s, &entry); if (error == ERR_NONE) { name = GSM_PhonebookGetEntryName(&entry); if (name != NULL) { printmsg("Contact ID : \"%s\" (%d)\n", DecodeUnicodeConsole(name), Note->Entries[i].Number); } else { printmsg("Contact ID : %d\n",Note->Entries[i].Number); } } else { printmsg("Contact ID : %d\n",Note->Entries[i].Number); } break; case CAL_REPEAT_DAYOFWEEK: repeat_dayofweek = Note->Entries[i].Number; repeating = true; break; case CAL_REPEAT_DAY: repeat_day = Note->Entries[i].Number; repeating = true; break; case CAL_REPEAT_WEEKOFMONTH: repeat_weekofmonth = Note->Entries[i].Number; repeating = true; break; case CAL_REPEAT_MONTH: repeat_month = Note->Entries[i].Number; repeating = true; break; case CAL_REPEAT_FREQUENCY: repeat_frequency = Note->Entries[i].Number; repeating = true; break; case CAL_REPEAT_STARTDATE: repeat_startdate = Note->Entries[i].Date; repeating = true; break; case CAL_REPEAT_STOPDATE: repeat_stopdate = Note->Entries[i].Date; repeating = true; break; } } if (repeating) { printmsg("Repeating : "); if ((repeat_startdate.Day == 0) && (repeat_stopdate.Day == 0)) { printmsg("Forever"); } else if (repeat_startdate.Day == 0) { printmsg("Till %s", OSDate(repeat_stopdate)); } else if (repeat_stopdate.Day == 0) { printmsg("Since %s", OSDate(repeat_startdate)); } else { printmsg("Since %s till %s", OSDate(repeat_startdate), OSDate(repeat_stopdate)); } if (repeat_frequency != -1) { if (repeat_frequency == 1) { printmsg (" on each "); } else { printmsg(" on each %d. ", repeat_frequency); } if (repeat_dayofweek > 0) { switch (repeat_dayofweek) { case 1 : printmsg("Monday"); break; case 2 : printmsg("Tuesday"); break; case 3 : printmsg("Wednesday"); break; case 4 : printmsg("Thursday"); break; case 5 : printmsg("Friday"); break; case 6 : printmsg("Saturday"); break; case 7 : printmsg("Sunday"); break; default: printmsg("Bad day!"); break; } if (repeat_weekofmonth > 0) { printmsg(" in %d. week of ", repeat_weekofmonth); } else { printmsg(" in "); } if (repeat_month > 0) { switch(repeat_month) { case 1 : printmsg("January"); break; case 2 : printmsg("February"); break; case 3 : printmsg("March"); break; case 4 : printmsg("April"); break; case 5 : printmsg("May"); break; case 6 : printmsg("June"); break; case 7 : printmsg("July"); break; case 8 : printmsg("August"); break; case 9 : printmsg("September"); break; case 10: printmsg("October"); break; case 11: printmsg("November"); break; case 12: printmsg("December"); break; default: printmsg("Bad month!"); break; } } else { printmsg("each month"); } } else if (repeat_day > 0) { printmsg("%d. day of ", repeat_day); if (repeat_month > 0) { switch(repeat_month) { case 1 : printmsg("January"); break; case 2 : printmsg("February"); break; case 3 : printmsg("March"); break; case 4 : printmsg("April"); break; case 5 : printmsg("May"); break; case 6 : printmsg("June"); break; case 7 : printmsg("July"); break; case 8 : printmsg("August"); break; case 9 : printmsg("September"); break; case 10: printmsg("October"); break; case 11: printmsg("November"); break; case 12: printmsg("December"); break; default: printmsg("Bad month!");break; } } else { printmsg("each month"); } } else { printmsg("day"); } } printf("\n"); } if (Note->Type == GSM_CAL_BIRTHDAY) { if (Alarm.Year == 0x00) GSM_GetCurrentDateTime (&Alarm); if (DateTime.Year != 0) { i_age = Alarm.Year - DateTime.Year; if (DateTime.Month < Alarm.Month) i_age++; if (DateTime.Month == Alarm.Month && DateTime.Day < Alarm.Day) { i_age++; } printmsg("Age : %d %s\n",i_age, (i_age==1)?"year":"years"); } } printf("\n"); } static void GetCalendar(int argc, char *argv[]) { GSM_CalendarEntry Note; int start,stop; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { Note.Location=i; error = Phone->GetCalendar(&s, &Note); if (error == ERR_EMPTY) continue; Print_Error(error); PrintCalendar(&Note); } GSM_Terminate(); } static void DeleteCalendar(int argc, char *argv[]) { GSM_CalendarEntry Note; int start,stop; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { Note.Location=i; error = Phone->DeleteCalendar(&s, &Note); if (error == ERR_EMPTY) continue; Print_Error(error); PrintCalendar(&Note); } GSM_Terminate(); } static void GetAllCalendar(int argc, char *argv[]) { GSM_CalendarEntry Note; bool refresh = true; signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); GSM_Init(true); while (!gshutdown) { error=Phone->GetNextCalendar(&s,&Note,refresh); if (error == ERR_EMPTY) break; Print_Error(error); PrintCalendar(&Note); refresh=false; } GSM_Terminate(); } static void GetCalendarSettings(int argc, char *argv[]) { GSM_CalendarSettings settings; GSM_Init(true); error=Phone->GetCalendarSettings(&s,&settings); Print_Error(error); if (settings.AutoDelete == 0) { printmsg("Auto deleting disabled"); } else { printmsg("Auto deleting notes after %i day(s)",settings.AutoDelete); } printmsg("\nWeek start on "); switch(settings.StartDay) { case 1: printmsg("Monday"); break; case 6: printmsg("Saturday"); break; case 7: printmsg("Sunday"); break; } printf("\n"); GSM_Terminate(); } static void GetWAPBookmark(int argc, char *argv[]) { GSM_WAPBookmark bookmark; int start,stop; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { bookmark.Location=i; error=Phone->GetWAPBookmark(&s,&bookmark); Print_Error(error); printmsg("Name : \"%s\"\n",DecodeUnicodeConsole(bookmark.Title)); printmsg("Address : \"%s\"\n",DecodeUnicodeConsole(bookmark.Address)); } GSM_Terminate(); } static void DeleteWAPBookmark(int argc, char *argv[]) { GSM_WAPBookmark bookmark; int start, stop; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { bookmark.Location=i; error=Phone->DeleteWAPBookmark(&s, &bookmark); Print_Error(error); } GSM_Terminate(); } static void GetGPRSPoint(int argc, char *argv[]) { GSM_GPRSAccessPoint point; int start,stop; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { point.Location=i; error=Phone->GetGPRSAccessPoint(&s,&point); if (error != ERR_EMPTY) { Print_Error(error); printmsg("%i. \"%s\"",point.Location,DecodeUnicodeConsole(point.Name)); } else { printmsg("%i. Access point %i",point.Location,point.Location); } if (point.Active) printmsg(" (active)"); if (error != ERR_EMPTY) { printmsg("\nAddress : \"%s\"\n\n",DecodeUnicodeConsole(point.URL)); } else { printmsg("\n\n"); } } GSM_Terminate(); } static void GetBitmap(int argc, char *argv[]) { GSM_File File; GSM_MultiBitmap MultiBitmap; int location=0; - GSM_AllRingtonesInfo Info; + GSM_AllRingtonesInfo Info = {0, NULL}; if (mystrncasecmp(argv[2],"STARTUP",0)) { MultiBitmap.Bitmap[0].Type=GSM_StartupLogo; } else if (mystrncasecmp(argv[2],"CALLER",0)) { MultiBitmap.Bitmap[0].Type=GSM_CallerGroupLogo; GetStartStop(&location, NULL, 3, argc, argv); if (location>5) { printmsg("Maximal location for caller logo can be 5\n"); exit (-1); } } else if (mystrncasecmp(argv[2],"PICTURE",0)) { MultiBitmap.Bitmap[0].Type=GSM_PictureImage; GetStartStop(&location, NULL, 3, argc, argv); } else if (mystrncasecmp(argv[2],"TEXT",0)) { MultiBitmap.Bitmap[0].Type=GSM_WelcomeNote_Text; } else if (mystrncasecmp(argv[2],"DEALER",0)) { MultiBitmap.Bitmap[0].Type=GSM_DealerNote_Text; } else if (mystrncasecmp(argv[2],"OPERATOR",0)) { MultiBitmap.Bitmap[0].Type=GSM_OperatorLogo; } else { printmsg("What type of logo do you want to get (\"%s\") ?\n",argv[2]); exit(-1); } MultiBitmap.Bitmap[0].Location=location; GSM_Init(true); error=Phone->GetBitmap(&s,&MultiBitmap.Bitmap[0]); Print_Error(error); MultiBitmap.Number = 1; error=ERR_NONE; switch (MultiBitmap.Bitmap[0].Type) { case GSM_CallerGroupLogo: if (!MultiBitmap.Bitmap[0].DefaultBitmap) GSM_PrintBitmap(stdout,&MultiBitmap.Bitmap[0]); printmsg("Group name : \"%s\"",DecodeUnicodeConsole(MultiBitmap.Bitmap[0].Text)); if (MultiBitmap.Bitmap[0].DefaultName) printmsg(" (default)"); printf("\n"); if (MultiBitmap.Bitmap[0].DefaultRingtone) { printmsg("Ringtone : default\n"); } else if (MultiBitmap.Bitmap[0].FileSystemRingtone) { sprintf(File.ID_FullName,"%i",MultiBitmap.Bitmap[0].RingtoneID); File.Buffer = NULL; File.Used = 0; error = ERR_NONE; // while (error == ERR_NONE) { error = Phone->GetFilePart(&s,&File); // } if (error != ERR_EMPTY && error != ERR_WRONGCRC) Print_Error(error); error = ERR_NONE; printmsg("Ringtone : \"%s\" (file with ID %i)\n", DecodeUnicodeString(File.Name), MultiBitmap.Bitmap[0].RingtoneID); } else { error = Phone->GetRingtonesInfo(&s,&Info); if (error != ERR_NONE) Info.Number = 0; error = ERR_NONE; printmsg("Ringtone : "); if (UnicodeLength(GSM_GetRingtoneName(&Info,MultiBitmap.Bitmap[0].RingtoneID))!=0) { printmsg("\"%s\" (ID %i)\n", DecodeUnicodeConsole(GSM_GetRingtoneName(&Info,MultiBitmap.Bitmap[0].RingtoneID)), MultiBitmap.Bitmap[0].RingtoneID); } else { printmsg("ID %i\n",MultiBitmap.Bitmap[0].RingtoneID); } + + if (Info.Ringtone) free(Info.Ringtone); } if (MultiBitmap.Bitmap[0].BitmapEnabled) { printmsg("Bitmap : enabled\n"); } else { printmsg("Bitmap : disabled\n"); } if (argc>4 && !MultiBitmap.Bitmap[0].DefaultBitmap) error=GSM_SaveBitmapFile(argv[4],&MultiBitmap); break; case GSM_StartupLogo: GSM_PrintBitmap(stdout,&MultiBitmap.Bitmap[0]); if (argc>3) error=GSM_SaveBitmapFile(argv[3],&MultiBitmap); break; case GSM_OperatorLogo: if (strcmp(MultiBitmap.Bitmap[0].NetworkCode,"000 00")!=0) { GSM_PrintBitmap(stdout,&MultiBitmap.Bitmap[0]); if (argc>3) error=GSM_SaveBitmapFile(argv[3],&MultiBitmap); } else { printmsg("No operator logo in phone\n"); } break; case GSM_PictureImage: GSM_PrintBitmap(stdout,&MultiBitmap.Bitmap[0]); printmsg("Text : \"%s\"\n",DecodeUnicodeConsole(MultiBitmap.Bitmap[0].Text)); printmsg("Sender : \"%s\"\n",DecodeUnicodeConsole(MultiBitmap.Bitmap[0].Sender)); if (MultiBitmap.Bitmap[0].Name) printmsg("Name : \"%s\"\n",DecodeUnicodeConsole(MultiBitmap.Bitmap[0].Name)); if (argc>4) error=GSM_SaveBitmapFile(argv[4],&MultiBitmap); break; case GSM_WelcomeNote_Text: printmsg("Welcome note text is \"%s\"\n",DecodeUnicodeConsole(MultiBitmap.Bitmap[0].Text)); break; case GSM_DealerNote_Text: printmsg("Dealer note text is \"%s\"\n",DecodeUnicodeConsole(MultiBitmap.Bitmap[0].Text)); break; default: break; } Print_Error(error); GSM_Terminate(); } static void SetBitmap(int argc, char *argv[]) { GSM_Bitmap Bitmap, NewBitmap; GSM_MultiBitmap MultiBitmap; GSM_NetworkInfo NetInfo; bool init = true; if (mystrncasecmp(argv[2],"STARTUP",0)) { if (argc<4) { printmsg("More arguments required\n"); exit(-1); } MultiBitmap.Bitmap[0].Type=GSM_StartupLogo; MultiBitmap.Bitmap[0].Location=1; if (!strcmp(argv[3],"1")) MultiBitmap.Bitmap[0].Location = 2; if (!strcmp(argv[3],"2")) MultiBitmap.Bitmap[0].Location = 3; if (!strcmp(argv[3],"3")) MultiBitmap.Bitmap[0].Location = 4; if (MultiBitmap.Bitmap[0].Location == 1) { error=GSM_ReadBitmapFile(argv[3],&MultiBitmap); Print_Error(error); } memcpy(&Bitmap,&MultiBitmap.Bitmap[0],sizeof(GSM_Bitmap)); } else if (mystrncasecmp(argv[2],"TEXT",0)) { if (argc<4) { printmsg("More arguments required\n"); exit(-1); } Bitmap.Type=GSM_WelcomeNote_Text; EncodeUnicode(Bitmap.Text,argv[3],strlen(argv[3])); } else if (mystrncasecmp(argv[2],"DEALER",0)) { if (argc<4) { printmsg("More arguments required\n"); exit(-1); } Bitmap.Type=GSM_DealerNote_Text; EncodeUnicode(Bitmap.Text,argv[3],strlen(argv[3])); } else if (mystrncasecmp(argv[2],"CALLER",0)) { if (argc<4) { printmsg("More arguments required\n"); exit(-1); } GetStartStop(&i, NULL, 3, argc, argv); if (i>5 && i!=255) { printmsg("Maximal location for caller logo can be 5\n"); exit (-1); } MultiBitmap.Bitmap[0].Type = GSM_CallerGroupLogo; MultiBitmap.Bitmap[0].Location = i; if (argc>4) { error=GSM_ReadBitmapFile(argv[4],&MultiBitmap); Print_Error(error); } memcpy(&Bitmap,&MultiBitmap.Bitmap[0],sizeof(GSM_Bitmap)); if (i!=255) { GSM_Init(true); init = false; NewBitmap.Type = GSM_CallerGroupLogo; NewBitmap.Location = i; error=Phone->GetBitmap(&s,&NewBitmap); Print_Error(error); Bitmap.RingtoneID = NewBitmap.RingtoneID; Bitmap.DefaultRingtone = NewBitmap.DefaultRingtone; Bitmap.FileSystemRingtone = false; CopyUnicodeString(Bitmap.Text, NewBitmap.Text); Bitmap.DefaultName = NewBitmap.DefaultName; } } else if (mystrncasecmp(argv[2],"PICTURE",0)) { if (argc<5) { printmsg("More arguments required\n"); exit(-1); } MultiBitmap.Bitmap[0].Type = GSM_PictureImage; MultiBitmap.Bitmap[0].Location = atoi(argv[4]); error=GSM_ReadBitmapFile(argv[3],&MultiBitmap); Print_Error(error); memcpy(&Bitmap,&MultiBitmap.Bitmap[0],sizeof(GSM_Bitmap)); Bitmap.Text[0]=0; Bitmap.Text[1]=0; if (argc == 6) EncodeUnicode(Bitmap.Text,argv[5],strlen(argv[5])); Bitmap.Sender[0]=0; Bitmap.Sender[1]=0; } else if (mystrncasecmp(argv[2],"COLOUROPERATOR",0)) { Bitmap.Type = GSM_ColourOperatorLogo_ID; strcpy(Bitmap.NetworkCode,"000 00"); if (argc > 3) { Bitmap.ID = atoi(argv[3]); if (argc>4) { strncpy(Bitmap.NetworkCode,argv[4],6); } else { GSM_Init(true); init = false; error=Phone->GetNetworkInfo(&s,&NetInfo); Print_Error(error); strcpy(Bitmap.NetworkCode,NetInfo.NetworkCode); } } } else if (mystrncasecmp(argv[2],"COLOURSTARTUP",0)) { Bitmap.Type = GSM_ColourStartupLogo_ID; Bitmap.Location = 0; if (argc > 3) { Bitmap.Location = 1; Bitmap.ID = atoi(argv[3]); } } else if (mystrncasecmp(argv[2],"WALLPAPER",0)) { Bitmap.Type = GSM_ColourWallPaper_ID; Bitmap.ID = 0; if (argc > 3) Bitmap.ID = atoi(argv[3]); } else if (mystrncasecmp(argv[2],"OPERATOR",0)) { MultiBitmap.Bitmap[0].Type = GSM_OperatorLogo; MultiBitmap.Bitmap[0].Location = 1; strcpy(MultiBitmap.Bitmap[0].NetworkCode,"000 00"); if (argc>3) { error=GSM_ReadBitmapFile(argv[3],&MultiBitmap); Print_Error(error); if (argc>4) { strncpy(MultiBitmap.Bitmap[0].NetworkCode,argv[4],6); } else { GSM_Init(true); init = false; error=Phone->GetNetworkInfo(&s,&NetInfo); Print_Error(error); strcpy(MultiBitmap.Bitmap[0].NetworkCode,NetInfo.NetworkCode); } } memcpy(&Bitmap,&MultiBitmap.Bitmap[0],sizeof(GSM_Bitmap)); } else { printmsg("What type of logo do you want to set (\"%s\") ?\n",argv[2]); exit(-1); } if (init) GSM_Init(true); error=Phone->SetBitmap(&s,&Bitmap); Print_Error(error); #ifdef GSM_ENABLE_BEEP GSM_PhoneBeep(); #endif GSM_Terminate(); } static void SetRingtone(int argc, char *argv[]) { GSM_Ringtone ringtone; int i,nextlong=0; ringtone.Format = 0; error=GSM_ReadRingtoneFile(argv[2],&ringtone); Print_Error(error); ringtone.Location = 255; for (i=3;i<argc;i++) { switch (nextlong) { case 0: if (mystrncasecmp(argv[i],"-scale",0)) { ringtone.NoteTone.AllNotesScale = true; break; } if (mystrncasecmp(argv[i],"-location",0)) { nextlong = 1; break; } if (mystrncasecmp(argv[i],"-name",0)) { nextlong = 2; break; } printmsg("Unknown parameter \"%s\"",argv[i]); exit(-1); case 1: ringtone.Location=atoi(argv[i]); nextlong = 0; break; case 2: EncodeUnicode(ringtone.Name,argv[i],strlen(argv[i])); nextlong = 0; break; } } if (nextlong!=0) { printmsg("Parameter missed...\n"); exit(-1); } if (ringtone.Location==0) { printmsg("ERROR: enumerate locations from 1\n"); exit (-1); } GSM_Init(true); error=Phone->SetRingtone(&s, &ringtone, &i); Print_Error(error); #ifdef GSM_ENABLE_BEEP GSM_PhoneBeep(); #endif GSM_Terminate(); } static void DisplaySMSFrame(GSM_SMSMessage *SMS) { GSM_Error error; int i, length, current = 0; unsigned char req[1000], buffer[1000], hexreq[1000]; #ifdef OSCAR unsigned char hexmsg[1000], hexudh[1000]; #endif error=PHONE_EncodeSMSFrame(&s,SMS,buffer,PHONE_SMSSubmit,&length,true); if (error != ERR_NONE) { printmsg("Error\n"); exit(-1); } length = length - PHONE_SMSSubmit.Text; #ifdef OSCAR for(i=SMS->UDH.Length;i<length;i++) { req[i-SMS->UDH.Length]=buffer[PHONE_SMSSubmit.Text+i]; } EncodeHexBin(hexmsg, req, length-SMS->UDH.Length); for(i=0;i<SMS->UDH.Length;i++) { req[i]=buffer[PHONE_SMSSubmit.Text+i]; } EncodeHexBin(hexudh, req, SMS->UDH.Length); printf("msg:%s nb:%i udh:%s\n", hexmsg, (buffer[PHONE_SMSSubmit.TPUDL]-SMS->UDH.Length)*8, hexudh); #else for (i=0;i<buffer[PHONE_SMSSubmit.SMSCNumber]+1;i++) { req[current++]=buffer[PHONE_SMSSubmit.SMSCNumber+i]; } req[current++]=buffer[PHONE_SMSSubmit.firstbyte]; req[current++]=buffer[PHONE_SMSSubmit.TPMR]; for (i=0;i<((buffer[PHONE_SMSSubmit.Number]+1)/2+1)+1;i++) { req[current++]=buffer[PHONE_SMSSubmit.Number+i]; } req[current++]=buffer[PHONE_SMSSubmit.TPPID]; req[current++]=buffer[PHONE_SMSSubmit.TPDCS]; req[current++]=buffer[PHONE_SMSSubmit.TPVP]; req[current++]=buffer[PHONE_SMSSubmit.TPUDL]; for(i=0;i<length;i++) req[current++]=buffer[PHONE_SMSSubmit.Text+i]; EncodeHexBin(hexreq, req, current); printmsg("%s\n\n",hexreq); #endif } #define SEND_SAVE_SMS_BUFFER_SIZE 10000 static GSM_Error SMSStatus; static void SendSMSStatus (char *Device, int status, int MessageReference) { dbgprintf("Sent SMS on device: \"%s\"\n",Device); if (status==0) { printmsg("..OK"); SMSStatus = ERR_NONE; } else { printmsg("..error %i",status); SMSStatus = ERR_UNKNOWN; } printmsg(", message reference=%d\n",MessageReference); } static void SendSaveDisplaySMS(int argc, char *argv[]) { #ifdef GSM_ENABLE_BACKUP GSM_Backup Backup; #endif int i,j,z,FramesNum = 0; int Protected = 0; GSM_SMSFolders folders; GSM_MultiSMSMessage sms; GSM_Ringtone ringtone[MAX_MULTI_SMS]; GSM_MultiBitmap bitmap[MAX_MULTI_SMS],bitmap2; GSM_MultiPartSMSInfo SMSInfo; GSM_NetworkInfo NetInfo; GSM_MMSIndicator MMSInfo; FILE *ReplaceFile,*f; char ReplaceBuffer2 [200],ReplaceBuffer[200]; char InputBuffer [SEND_SAVE_SMS_BUFFER_SIZE/2+1]; char Buffer [MAX_MULTI_SMS][SEND_SAVE_SMS_BUFFER_SIZE]; char Sender [(GSM_MAX_NUMBER_LENGTH+1)*2]; char Name [(GSM_MAX_NUMBER_LENGTH+1)*2]; char SMSC [(GSM_MAX_NUMBER_LENGTH+1)*2]; int startarg = 0; int chars_read = 0; int nextlong = 0; bool ReplyViaSameSMSC = false; int SMSCSet = 1; int MaxSMS = -1; bool EMS16Bit = false; bool SendSaved = false; /* Parameters required only during saving */ int Folder = 1; /*Inbox by default */ GSM_SMS_State State = SMS_Sent; /* Required only during sending */ GSM_SMSValidity Validity; GSM_SMSC PhoneSMSC; bool DeliveryReport = false; ReplaceBuffer[0] = 0; ReplaceBuffer[1] = 0; GSM_ClearMultiPartSMSInfo(&SMSInfo); SMSInfo.ReplaceMessage = 0; SMSInfo.EntriesNum = 1; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender,"Gammu",5); Name[0] = 0; Name[1] = 0; startarg = 0; } else { EncodeUnicode(Sender,argv[3],strlen(argv[3])); startarg = 1; Validity.Format = 0; } if (mystrncasecmp(argv[1],"--sendsmsdsms",0)) { startarg=startarg+2; EncodeUnicode(SMSC,"1234",4); SMSCSet = 0; } if (mystrncasecmp(argv[2],"TEXT",0)) { chars_read = fread(InputBuffer, 1, SEND_SAVE_SMS_BUFFER_SIZE/2, stdin); if (chars_read == 0) printmsg("Warning: 0 chars read !\n"); InputBuffer[chars_read] = 0x00; InputBuffer[chars_read+1] = 0x00; EncodeUnicode(Buffer[0],InputBuffer,strlen(InputBuffer)); SMSInfo.Entries[0].Buffer = Buffer[0]; SMSInfo.Entries[0].ID = SMS_Text; SMSInfo.UnicodeCoding = false; startarg += 3; } else if (mystrncasecmp(argv[2],"SMSTEMPLATE",0)) { SMSInfo.UnicodeCoding = false; SMSInfo.EntriesNum = 1; Buffer[0][0] = 0x00; Buffer[0][1] = 0x00; SMSInfo.Entries[0].Buffer = Buffer[0]; SMSInfo.Entries[0].ID = SMS_AlcatelSMSTemplateName; startarg += 3; } else if (mystrncasecmp(argv[2],"EMS",0)) { SMSInfo.UnicodeCoding = false; SMSInfo.EntriesNum = 0; startarg += 3; } else if (mystrncasecmp(argv[2],"MMSINDICATOR",0)) { if (argc<6+startarg) { printmsg("Where are parameters ?\n"); exit(-1); } SMSInfo.Entries[0].ID = SMS_MMSIndicatorLong; SMSInfo.Entries[0].MMSIndicator = &MMSInfo; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender,"MMS Info",8); } strcpy(MMSInfo.Address, argv[3+startarg]); strcpy(MMSInfo.Title, argv[4+startarg]); strcpy(MMSInfo.Sender, argv[5+startarg]); startarg += 6; } else if (mystrncasecmp(argv[2],"WAPINDICATOR",0)) { if (argc<5+startarg) { printmsg("Where are parameters ?\n"); exit(-1); } SMSInfo.Entries[0].ID = SMS_WAPIndicatorLong; SMSInfo.Entries[0].MMSIndicator = &MMSInfo; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender,"WAP Info",8); } strcpy(MMSInfo.Address, argv[3+startarg]); strcpy(MMSInfo.Title, argv[4+startarg]); startarg += 5; } else if (mystrncasecmp(argv[2],"RINGTONE",0)) { if (argc<4+startarg) { printmsg("Where is ringtone filename ?\n"); exit(-1); } ringtone[0].Format=RING_NOTETONE; error=GSM_ReadRingtoneFile(argv[3+startarg],&ringtone[0]); Print_Error(error); SMSInfo.Entries[0].ID = SMS_NokiaRingtone; SMSInfo.Entries[0].Ringtone = &ringtone[0]; if (mystrncasecmp(argv[1],"--savesms",0)) { CopyUnicodeString(Sender, ringtone[0].Name); EncodeUnicode(Name,"Ringtone ",9); CopyUnicodeString(Name+9*2, ringtone[0].Name); } startarg += 4; } else if (mystrncasecmp(argv[2],"OPERATOR",0)) { if (argc<4+startarg) { printmsg("Where is logo filename ?\n"); exit(-1); } bitmap[0].Bitmap[0].Type=GSM_OperatorLogo; error=GSM_ReadBitmapFile(argv[3+startarg],&bitmap[0]); Print_Error(error); strcpy(bitmap[0].Bitmap[0].NetworkCode,"000 00"); SMSInfo.Entries[0].ID = SMS_NokiaOperatorLogo; SMSInfo.Entries[0].Bitmap = &bitmap[0]; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "OpLogo",6); EncodeUnicode(Name,"OpLogo ",7); } startarg += 4; } else if (mystrncasecmp(argv[2],"CALLER",0)) { if (argc<4+startarg) { printmsg("Where is logo filename ?\n"); exit(-1); } bitmap[0].Bitmap[0].Type=GSM_CallerGroupLogo; error=GSM_ReadBitmapFile(argv[3+startarg],&bitmap[0]); Print_Error(error); SMSInfo.Entries[0].ID = SMS_NokiaCallerLogo; SMSInfo.Entries[0].Bitmap = &bitmap[0]; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "Caller",6); } startarg += 4; } else if (mystrncasecmp(argv[2],"ANIMATION",0)) { SMSInfo.UnicodeCoding = false; SMSInfo.EntriesNum = 1; if (argc<4+startarg) { printmsg("Where is number of frames ?\n"); exit(-1); } bitmap[0].Number = 0; i = 1; while (1) { bitmap2.Bitmap[0].Type=GSM_StartupLogo; error=GSM_ReadBitmapFile(argv[3+startarg+i],&bitmap2); Print_Error(error); for (j=0;j<bitmap2.Number;j++) { if (bitmap[0].Number == atoi(argv[3+startarg])) break; memcpy(&bitmap[0].Bitmap[bitmap[0].Number],&bitmap2.Bitmap[j],sizeof(GSM_Bitmap)); bitmap[0].Number++; } if (bitmap[0].Number == atoi(argv[3+startarg])) break; i++; } SMSInfo.Entries[0].ID = SMS_AlcatelMonoAnimationLong; SMSInfo.Entries[0].Bitmap = &bitmap[0]; bitmap[0].Bitmap[0].Text[0] = 0; bitmap[0].Bitmap[0].Text[1] = 0; startarg += 4 + atoi(argv[3+startarg]); } else if (mystrncasecmp(argv[2],"PICTURE",0)) { if (argc<4+startarg) { printmsg("Where is logo filename ?\n"); exit(-1); } bitmap[0].Bitmap[0].Type=GSM_PictureImage; error=GSM_ReadBitmapFile(argv[3+startarg],&bitmap[0]); printmsg("File \"%s\"\n",argv[3+startarg]); Print_Error(error); SMSInfo.Entries[0].ID = SMS_NokiaPictureImageLong; SMSInfo.Entries[0].Bitmap = &bitmap[0]; SMSInfo.UnicodeCoding = false; bitmap[0].Bitmap[0].Text[0] = 0; bitmap[0].Bitmap[0].Text[1] = 0; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "Picture",7); EncodeUnicode(Name,"Picture Image",13); } startarg += 4; #ifdef GSM_ENABLE_BACKUP } else if (mystrncasecmp(argv[2],"BOOKMARK",0)) { if (argc<5+startarg) { printmsg("Where is backup filename and location ?\n"); exit(-1); } error=GSM_ReadBackupFile(argv[3+startarg],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); i = 0; while (Backup.WAPBookmark[i]!=NULL) { if (i == atoi(argv[4+startarg])-1) break; i++; } if (i != atoi(argv[4+startarg])-1) { printmsg("Bookmark not found in file\n"); exit(-1); } SMSInfo.Entries[0].ID = SMS_NokiaWAPBookmarkLong; SMSInfo.Entries[0].Bookmark = Backup.WAPBookmark[i]; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "Bookmark",8); EncodeUnicode(Name,"WAP Bookmark",12); } startarg += 5; } else if (mystrncasecmp(argv[2],"WAPSETTINGS",0)) { if (argc<6+startarg) { printmsg("Where is backup filename and location ?\n"); exit(-1); } error=GSM_ReadBackupFile(argv[3+startarg],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); i = 0; while (Backup.WAPSettings[i]!=NULL) { if (i == atoi(argv[4+startarg])-1) break; i++; } if (i != atoi(argv[4+startarg])-1) { printmsg("WAP settings not found in file\n"); exit(-1); } SMSInfo.Entries[0].Settings = NULL; for (j=0;j<Backup.WAPSettings[i]->Number;j++) { switch (Backup.WAPSettings[i]->Settings[j].Bearer) { case WAPSETTINGS_BEARER_GPRS: if (mystrncasecmp(argv[5+startarg],"GPRS",0)) { SMSInfo.Entries[0].Settings = &Backup.WAPSettings[i]->Settings[j]; break; } case WAPSETTINGS_BEARER_DATA: if (mystrncasecmp(argv[5+startarg],"DATA",0)) { SMSInfo.Entries[0].Settings = &Backup.WAPSettings[i]->Settings[j]; break; } default: break; } } if (SMSInfo.Entries[0].Settings == NULL) { printmsg("Sorry. For now there is only support for GPRS or DATA bearers end\n"); exit(-1); } SMSInfo.Entries[0].ID = SMS_NokiaWAPSettingsLong; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "Settings",8); EncodeUnicode(Name,"WAP Settings",12); } startarg += 6; } else if (mystrncasecmp(argv[2],"MMSSETTINGS",0)) { if (argc<5+startarg) { printmsg("Where is backup filename and location ?\n"); exit(-1); } error=GSM_ReadBackupFile(argv[3+startarg],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); i = 0; while (Backup.MMSSettings[i]!=NULL) { if (i == atoi(argv[4+startarg])-1) break; i++; } if (i != atoi(argv[4+startarg])-1) { printmsg("MMS settings not found in file\n"); exit(-1); } SMSInfo.Entries[0].Settings = NULL; for (j=0;j<Backup.MMSSettings[i]->Number;j++) { switch (Backup.MMSSettings[i]->Settings[j].Bearer) { case WAPSETTINGS_BEARER_GPRS: SMSInfo.Entries[0].Settings = &Backup.MMSSettings[i]->Settings[j]; break; default: break; } } if (SMSInfo.Entries[0].Settings == NULL) { printmsg("Sorry. No GPRS bearer found in MMS settings\n"); exit(-1); } SMSInfo.Entries[0].ID = SMS_NokiaMMSSettingsLong; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "Settings",8); EncodeUnicode(Name,"MMS Settings",12); } startarg += 5; } else if (mystrncasecmp(argv[2],"CALENDAR",0)) { if (argc<5+startarg) { printmsg("Where is backup filename and location ?\n"); exit(-1); } error=GSM_ReadBackupFile(argv[3+startarg],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); i = 0; while (Backup.Calendar[i]!=NULL) { if (i == atoi(argv[4+startarg])-1) break; i++; } if (i != atoi(argv[4+startarg])-1) { printmsg("Calendar note not found in file\n"); exit(-1); } SMSInfo.Entries[0].ID = SMS_NokiaVCALENDAR10Long; SMSInfo.Entries[0].Calendar = Backup.Calendar[i]; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "Calendar",8); } startarg += 5; } else if (mystrncasecmp(argv[2],"TODO",0)) { if (argc<5+startarg) { printmsg("Where is backup filename and location ?\n"); exit(-1); } error=GSM_ReadBackupFile(argv[3+startarg],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); i = 0; while (Backup.ToDo[i]!=NULL) { if (i == atoi(argv[4+startarg])-1) break; i++; } if (i != atoi(argv[4+startarg])-1) { printmsg("ToDo note not found in file\n"); exit(-1); } SMSInfo.Entries[0].ID = SMS_NokiaVTODOLong; SMSInfo.Entries[0].ToDo = Backup.ToDo[i]; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "ToDo",8); } startarg += 5; } else if (mystrncasecmp(argv[2],"VCARD10",0) || mystrncasecmp(argv[2],"VCARD21",0)) { if (argc<6+startarg) { printmsg("Where is backup filename and location and memory type ?\n"); exit(-1); } error=GSM_ReadBackupFile(argv[3+startarg],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); i = 0; if (mystrncasecmp(argv[4+startarg],"SM",0)) { while (Backup.SIMPhonebook[i]!=NULL) { if (i == atoi(argv[5+startarg])-1) break; i++; } if (i != atoi(argv[5+startarg])-1) { printmsg("Phonebook entry not found in file\n"); exit(-1); } SMSInfo.Entries[0].Phonebook = Backup.SIMPhonebook[i]; } else if (mystrncasecmp(argv[4+startarg],"ME",0)) { while (Backup.PhonePhonebook[i]!=NULL) { if (i == atoi(argv[5+startarg])-1) break; i++; } if (i != atoi(argv[5+startarg])-1) { printmsg("Phonebook entry not found in file\n"); exit(-1); } SMSInfo.Entries[0].Phonebook = Backup.PhonePhonebook[i]; } else { printmsg("Unknown memory type: \"%s\"\n",argv[4+startarg]); exit(-1); } if (mystrncasecmp(argv[2],"VCARD10",0)) { SMSInfo.Entries[0].ID = SMS_VCARD10Long; } else { SMSInfo.Entries[0].ID = SMS_VCARD21Long; } if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "VCARD",5); EncodeUnicode(Name, "Phonebook entry",15); } startarg += 6; #endif } else if (mystrncasecmp(argv[2],"PROFILE",0)) { SMSInfo.Entries[0].ID = SMS_NokiaProfileLong; if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "Profile",7); } startarg += 3; } else { printmsg("What format of sms (\"%s\") ?\n",argv[2]); exit(-1); } for (i=startarg;i<argc;i++) { switch (nextlong) { case 0: if (mystrncasecmp(argv[1],"--savesms",0) || SendSaved) { if (mystrncasecmp(argv[i],"-folder",0)) { nextlong=1; continue; } } if (mystrncasecmp(argv[1],"--savesms",0)) { if (mystrncasecmp(argv[i],"-unread",0)) { State = SMS_UnRead; continue; } if (mystrncasecmp(argv[i],"-read",0)) { State = SMS_Read; continue; } if (mystrncasecmp(argv[i],"-unsent",0)) { State = SMS_UnSent; continue; } if (mystrncasecmp(argv[i],"-sent",0)) { State = SMS_Sent; continue; } if (mystrncasecmp(argv[i],"-sender",0)) { nextlong=2; continue; } } else { if (mystrncasecmp(argv[i],"-save",0)) { SendSaved=true; continue; } if (mystrncasecmp(argv[i],"-report",0)) { DeliveryReport=true; continue; } if (mystrncasecmp(argv[i],"-validity",0)) { nextlong=10; continue; } } if (mystrncasecmp(argv[i],"-smscset",0)) { nextlong=3; continue; } if (mystrncasecmp(argv[i],"-smscnumber",0)) { nextlong=4; continue; } if (mystrncasecmp(argv[i],"-protected",0)) { nextlong=19; continue; } if (mystrncasecmp(argv[i],"-reply",0)) { ReplyViaSameSMSC=true; continue; } if (mystrncasecmp(argv[i],"-maxsms",0)) { nextlong=21; continue; } if (mystrncasecmp(argv[2],"RINGTONE",0)) { if (mystrncasecmp(argv[i],"-long",0)) { SMSInfo.Entries[0].ID = SMS_NokiaRingtoneLong; break; } if (mystrncasecmp(argv[i],"-scale",0)) { ringtone[0].NoteTone.AllNotesScale=true; break; } } if (mystrncasecmp(argv[2],"TEXT",0)) { if (mystrncasecmp(argv[i],"-inputunicode",0)) { ReadUnicodeFile(Buffer[0],InputBuffer); break; } if (mystrncasecmp(argv[i],"-16bit",0)) { if (SMSInfo.Entries[0].ID == SMS_ConcatenatedTextLong) SMSInfo.Entries[0].ID = SMS_ConcatenatedTextLong16bit; if (SMSInfo.Entries[0].ID == SMS_ConcatenatedAutoTextLong) SMSInfo.Entries[0].ID = SMS_ConcatenatedAutoTextLong16bit; break; } if (mystrncasecmp(argv[i],"-flash",0)) { SMSInfo.Class = 0; break; } if (mystrncasecmp(argv[i],"-len",0)) { nextlong = 5; break; } if (mystrncasecmp(argv[i],"-autolen",0)) { nextlong = 5; break; } if (mystrncasecmp(argv[i],"-unicode",0)) { SMSInfo.UnicodeCoding = true; break; } if (mystrncasecmp(argv[i],"-enablevoice",0)) { SMSInfo.Entries[0].ID = SMS_EnableVoice; break; } if (mystrncasecmp(argv[i],"-disablevoice",0)) { SMSInfo.Entries[0].ID = SMS_DisableVoice; break; } if (mystrncasecmp(argv[i],"-enablefax",0)) { SMSInfo.Entries[0].ID = SMS_EnableFax; break; } if (mystrncasecmp(argv[i],"-disablefax",0)) { SMSInfo.Entries[0].ID = SMS_DisableFax; break; } if (mystrncasecmp(argv[i],"-enableemail",0)) { SMSInfo.Entries[0].ID = SMS_EnableEmail; break; } if (mystrncasecmp(argv[i],"-disableemail",0)) { SMSInfo.Entries[0].ID = SMS_DisableEmail; break; } if (mystrncasecmp(argv[i],"-voidsms",0)) { SMSInfo.Entries[0].ID = SMS_VoidSMS; break; } if (mystrncasecmp(argv[i],"-replacemessages",0) && SMSInfo.Entries[0].ID != SMS_ConcatenatedTextLong) { nextlong = 8; break; } if (mystrncasecmp(argv[i],"-replacefile",0)) { nextlong = 9; continue; } } if (mystrncasecmp(argv[2],"PICTURE",0)) { if (mystrncasecmp(argv[i],"-text",0)) { nextlong = 6; break; } if (mystrncasecmp(argv[i],"-unicode",0)) { SMSInfo.UnicodeCoding = true; break; } if (mystrncasecmp(argv[i],"-alcatelbmmi",0)) { bitmap[0].Bitmap[0].Type=GSM_StartupLogo; error=GSM_ReadBitmapFile(argv[startarg-1],&bitmap[0]); Print_Error(error); SMSInfo.UnicodeCoding = true; SMSInfo.Entries[0].ID = SMS_AlcatelMonoBitmapLong; break; } break; } if (mystrncasecmp(argv[2],"VCARD10",0)) { if (mystrncasecmp(argv[i],"-nokia",0)) { SMSInfo.Entries[0].ID = SMS_NokiaVCARD10Long; break; } break; } if (mystrncasecmp(argv[2],"VCARD21",0)) { if (mystrncasecmp(argv[i],"-nokia",0)) { SMSInfo.Entries[0].ID = SMS_NokiaVCARD21Long; break; } break; } if (mystrncasecmp(argv[2],"PROFILE",0)) { if (mystrncasecmp(argv[i],"-name",0)) { nextlong = 22; break; } if (mystrncasecmp(argv[i],"-ringtone",0)) { nextlong = 23; break; } if (mystrncasecmp(argv[i],"-bitmap",0)) { nextlong = 24; break; } } if (mystrncasecmp(argv[2],"SMSTEMPLATE",0)) { if (mystrncasecmp(argv[i],"-unicode",0)) { SMSInfo.UnicodeCoding = true; break; } if (mystrncasecmp(argv[i],"-text",0)) { nextlong = 11; break; } if (mystrncasecmp(argv[i],"-unicodefiletext",0)) { nextlong = 18; break; } if (mystrncasecmp(argv[i],"-defsound",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSPredefinedSound; nextlong = 12; break; } if (mystrncasecmp(argv[i],"-defanimation",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSPredefinedAnimation; nextlong = 12; break; } if (mystrncasecmp(argv[i],"-tone10",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSound10; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-tone10long",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSound10Long; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-tone12",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSound12; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-tone12long",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSound12Long; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-toneSE",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSonyEricssonSound; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-toneSElong",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSonyEricssonSoundLong; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-variablebitmap",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSVariableBitmap; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 15; break; } if (mystrncasecmp(argv[i],"-variablebitmaplong",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSVariableBitmapLong; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 15; break; } if (mystrncasecmp(argv[i],"-animation",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSAnimation; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } bitmap[SMSInfo.EntriesNum].Number = 0; nextlong = 16; break; } } if (mystrncasecmp(argv[2],"EMS",0)) { if (mystrncasecmp(argv[i],"-unicode",0)) { SMSInfo.UnicodeCoding = true; break; } if (mystrncasecmp(argv[i],"-16bit",0)) { EMS16Bit = true; break; } if (mystrncasecmp(argv[i],"-format",0)) { nextlong = 20; break; } if (mystrncasecmp(argv[i],"-text",0)) { nextlong = 11; break; } if (mystrncasecmp(argv[i],"-unicodefiletext",0)) { nextlong = 18; break; } if (mystrncasecmp(argv[i],"-defsound",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSPredefinedSound; nextlong = 12; break; } if (mystrncasecmp(argv[i],"-defanimation",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSPredefinedAnimation; nextlong = 12; break; } if (mystrncasecmp(argv[i],"-tone10",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSound10; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-tone10long",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSound10Long; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-tone12",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSound12; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-tone12long",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSound12Long; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-toneSE",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSonyEricssonSound; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-toneSElong",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSSonyEricssonSoundLong; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 14; break; } if (mystrncasecmp(argv[i],"-fixedbitmap",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSFixedBitmap; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 15; break; } if (mystrncasecmp(argv[i],"-variablebitmap",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSVariableBitmap; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 15; break; } if (mystrncasecmp(argv[i],"-variablebitmaplong",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSVariableBitmapLong; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } nextlong = 15; break; } if (mystrncasecmp(argv[i],"-animation",0)) { SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_EMSAnimation; if (Protected != 0) { SMSInfo.Entries[SMSInfo.EntriesNum].Protected = true; Protected --; } bitmap[SMSInfo.EntriesNum].Number = 0; nextlong = 16; break; } } if (mystrncasecmp(argv[2],"OPERATOR",0)) { if (mystrncasecmp(argv[i],"-netcode",0)) { nextlong = 7; break; } if (mystrncasecmp(argv[i],"-biglogo",0)) { SMSInfo.Entries[0].ID = SMS_NokiaOperatorLogoLong; break; } break; } printmsg("Unknown parameter (\"%s\")\n",argv[i]); exit(-1); break; case 1: /* SMS folder - only during saving SMS */ Folder = atoi(argv[i]); nextlong = 0; break; case 2: /* Sender number - only during saving SMS */ EncodeUnicode(Sender,argv[i],strlen(argv[i])); nextlong = 0; break; case 3: /* SMSC set number */ SMSCSet = atoi(argv[i]); nextlong = 0; break; case 4: /* Number of SMSC */ EncodeUnicode(SMSC,argv[i],strlen(argv[i])); SMSCSet = 0; nextlong = 0; break; case 5: /* Length of text SMS */ if (atoi(argv[i])<chars_read) { Buffer[0][atoi(argv[i])*2] = 0x00; Buffer[0][atoi(argv[i])*2+1] = 0x00; } SMSInfo.Entries[0].ID = SMS_ConcatenatedTextLong; if (mystrncasecmp(argv[i-1],"-autolen",0)) SMSInfo.Entries[0].ID = SMS_ConcatenatedAutoTextLong; nextlong = 0; break; case 6: /* Picture Images - text */ EncodeUnicode(bitmap[0].Bitmap[0].Text,argv[i],strlen(argv[i])); nextlong = 0; break; case 7: /* Operator Logo - network code */ strncpy(bitmap[0].Bitmap[0].NetworkCode,argv[i],7); if (!strcmp(DecodeUnicodeConsole(GSM_GetNetworkName(bitmap[0].Bitmap[0].NetworkCode)),"unknown")) { printmsg("Unknown GSM network code (\"%s\")\n",argv[i]); exit(-1); } if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "OpLogo",6); EncodeUnicode(Sender+6*2,bitmap[0].Bitmap[0].NetworkCode,3); EncodeUnicode(Sender+6*2+3*2,bitmap[0].Bitmap[0].NetworkCode+4,2); if (UnicodeLength(GSM_GetNetworkName(bitmap[0].Bitmap[0].NetworkCode))<GSM_MAX_SMS_NAME_LENGTH-7) { EncodeUnicode(Name,"OpLogo ",7); CopyUnicodeString(Name+7*2,GSM_GetNetworkName(bitmap[0].Bitmap[0].NetworkCode)); } else { CopyUnicodeString(Name,Sender); } } nextlong = 0; break; case 8:/* Reject duplicates ID */ SMSInfo.ReplaceMessage = atoi(argv[i]); if (SMSInfo.ReplaceMessage < 1 || SMSInfo.ReplaceMessage > 7) { printmsg("You have to give number between 1 and 7 (\"%s\")\n",argv[i]); exit(-1); } nextlong = 0; break; case 9:/* Replace file for text SMS */ ReplaceFile = fopen(argv[i], "rb"); if (ReplaceFile == NULL) Print_Error(ERR_CANTOPENFILE); memset(ReplaceBuffer,0,sizeof(ReplaceBuffer)); fread(ReplaceBuffer,1,sizeof(ReplaceBuffer),ReplaceFile); fclose(ReplaceFile); ReadUnicodeFile(ReplaceBuffer2,ReplaceBuffer); for(j=0;j<(int)(UnicodeLength(Buffer[0]));j++) { for (z=0;z<(int)(UnicodeLength(ReplaceBuffer2)/2);z++) { if (ReplaceBuffer2[z*4] == Buffer[0][j] && ReplaceBuffer2[z*4+1] == Buffer[0][j+1]) { Buffer[0][j] = ReplaceBuffer2[z*4+2]; Buffer[0][j+1] = ReplaceBuffer2[z*4+3]; break; } } } nextlong = 0; break; case 10: Validity.Format = SMS_Validity_RelativeFormat; if (mystrncasecmp(argv[i],"HOUR",0)) Validity.Relative = SMS_VALID_1_Hour; else if (mystrncasecmp(argv[i],"6HOURS",0)) Validity.Relative = SMS_VALID_6_Hours; else if (mystrncasecmp(argv[i],"DAY",0)) Validity.Relative = SMS_VALID_1_Day; else if (mystrncasecmp(argv[i],"3DAYS",0)) Validity.Relative = SMS_VALID_3_Days; else if (mystrncasecmp(argv[i],"WEEK",0)) Validity.Relative = SMS_VALID_1_Week; else if (mystrncasecmp(argv[i],"MAX",0)) Validity.Relative = SMS_VALID_Max_Time; else { printmsg("Unknown validity string (\"%s\")\n",argv[i]); exit(-1); } nextlong = 0; break; case 11:/* EMS text from parameter */ EncodeUnicode(Buffer[SMSInfo.EntriesNum],argv[i],strlen(argv[i])); dbgprintf("buffer is \"%s\"\n",DecodeUnicodeConsole(Buffer[SMSInfo.EntriesNum])); SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_ConcatenatedTextLong; SMSInfo.Entries[SMSInfo.EntriesNum].Buffer = Buffer[SMSInfo.EntriesNum]; SMSInfo.EntriesNum++; nextlong = 0; break; case 12:/* EMS predefined sound/animation number */ SMSInfo.Entries[SMSInfo.EntriesNum].Number = atoi(argv[i]); SMSInfo.EntriesNum++; nextlong = 0; break; case 14: /* EMS ringtone - IMelody */ ringtone[SMSInfo.EntriesNum].Format=RING_NOTETONE; error=GSM_ReadRingtoneFile(argv[i],&ringtone[SMSInfo.EntriesNum]); Print_Error(error); SMSInfo.Entries[SMSInfo.EntriesNum].Ringtone = &ringtone[SMSInfo.EntriesNum]; SMSInfo.EntriesNum++; nextlong = 0; break; case 15:/* EMS bitmap file */ bitmap[SMSInfo.EntriesNum].Bitmap[0].Type=GSM_StartupLogo; error=GSM_ReadBitmapFile(argv[i],&bitmap[SMSInfo.EntriesNum]); Print_Error(error); SMSInfo.Entries[SMSInfo.EntriesNum].Bitmap = &bitmap[SMSInfo.EntriesNum]; SMSInfo.EntriesNum++; nextlong = 0; break; case 16:/* Number of frames for EMS animation */ FramesNum = atoi(argv[i]); if (FramesNum < 1 || FramesNum > 4) { printmsg("You have to give number of EMS frames between 1 and 4 (\"%s\")\n",argv[i]); exit(-1); } bitmap[SMSInfo.EntriesNum].Number = 0; nextlong = 17; break; case 17:/*File for EMS animation */ bitmap2.Bitmap[0].Type=GSM_StartupLogo; error=GSM_ReadBitmapFile(argv[i],&bitmap2); for (j=0;j<bitmap2.Number;j++) { if (bitmap[SMSInfo.EntriesNum].Number == FramesNum) break; memcpy(&bitmap[SMSInfo.EntriesNum].Bitmap[bitmap[SMSInfo.EntriesNum].Number],&bitmap2.Bitmap[j],sizeof(GSM_Bitmap)); bitmap[SMSInfo.EntriesNum].Number++; } if (bitmap[SMSInfo.EntriesNum].Number == FramesNum) { SMSInfo.Entries[SMSInfo.EntriesNum].Bitmap = &bitmap[SMSInfo.EntriesNum]; SMSInfo.EntriesNum++; nextlong = 0; } break; case 18:/* EMS text from Unicode file */ f = fopen(argv[i],"rb"); if (f == NULL) { printmsg("Can't open file \"%s\"\n",argv[i]); exit(-1); } z=fread(InputBuffer,1,2000,f); InputBuffer[z] = 0; InputBuffer[z+1] = 0; fclose(f); ReadUnicodeFile(Buffer[SMSInfo.EntriesNum],InputBuffer); dbgprintf("buffer is \"%s\"\n",DecodeUnicodeConsole(Buffer[SMSInfo.EntriesNum])); SMSInfo.Entries[SMSInfo.EntriesNum].ID = SMS_ConcatenatedTextLong; SMSInfo.Entries[SMSInfo.EntriesNum].Buffer = Buffer[SMSInfo.EntriesNum]; SMSInfo.EntriesNum++; nextlong = 0; break; case 19:/* Number of protected items */ Protected = atoi(argv[i]); nextlong = 0; break; case 20:/* Formatting text for EMS */ if (SMSInfo.Entries[SMSInfo.EntriesNum-1].ID == SMS_ConcatenatedTextLong) { for(j=0;j<(int)strlen(argv[i]);j++) { switch(argv[i][j]) { case 'l': case 'L': SMSInfo.Entries[SMSInfo.EntriesNum-1].Left = true; break; case 'c': case 'C': SMSInfo.Entries[SMSInfo.EntriesNum-1].Center = true; break; case 'r': case 'R': SMSInfo.Entries[SMSInfo.EntriesNum-1].Right = true; break; case 'a': case 'A': SMSInfo.Entries[SMSInfo.EntriesNum-1].Large = true; break; case 's': case 'S': SMSInfo.Entries[SMSInfo.EntriesNum-1].Small = true; break; case 'b': case 'B': SMSInfo.Entries[SMSInfo.EntriesNum-1].Bold = true; break; case 'i': case 'I': SMSInfo.Entries[SMSInfo.EntriesNum-1].Italic = true; break; case 'u': case 'U': SMSInfo.Entries[SMSInfo.EntriesNum-1].Underlined = true; break; case 't': case 'T': SMSInfo.Entries[SMSInfo.EntriesNum-1].Strikethrough = true; break; default: printmsg("Unknown parameter \"%c\"\n",argv[i][j]); exit(-1); } } } else { printmsg("Last parameter wasn't text\n"); exit(-1); } nextlong = 0; break; case 21:/*MaxSMS*/ MaxSMS = atoi(argv[i]); nextlong = 0; break; case 22:/* profile name */ EncodeUnicode(Buffer[0],argv[i],strlen(argv[i])); SMSInfo.Entries[0].Buffer = Buffer[0]; nextlong = 0; break; case 23:/* profile ringtone */ ringtone[0].Format = RING_NOTETONE; error=GSM_ReadRingtoneFile(argv[i],&ringtone[0]); Print_Error(error); SMSInfo.Entries[0].Ringtone = &ringtone[0]; nextlong = 0; break; case 24:/* profile bitmap */ bitmap[0].Bitmap[0].Type = GSM_PictureImage; error=GSM_ReadBitmapFile(argv[i],&bitmap[0]); Print_Error(error); bitmap[0].Bitmap[0].Text[0] = 0; bitmap[0].Bitmap[0].Text[1] = 0; SMSInfo.Entries[0].Bitmap = &bitmap[0]; nextlong = 0; break; } } if (nextlong!=0) { printmsg("Parameter missed...\n"); exit(-1); } if (mystrncasecmp(argv[2],"EMS",0) && EMS16Bit) { for (i=0;i<SMSInfo.EntriesNum;i++) { switch (SMSInfo.Entries[i].ID) { case SMS_ConcatenatedTextLong: SMSInfo.Entries[i].ID = SMS_ConcatenatedTextLong16bit; default: break; } } } if (mystrncasecmp(argv[2],"TEXT",0)) { chars_read = UnicodeLength(Buffer[0]); if (chars_read != 0) { /* Trim \n at the end of string */ if (Buffer[0][chars_read*2-1] == '\n' && Buffer[0][chars_read*2-2] == 0) { Buffer[0][chars_read*2-1] = 0; } } } if (mystrncasecmp(argv[1],"--displaysms",0) || mystrncasecmp(argv[1],"--sendsmsdsms",0)) { if (mystrncasecmp(argv[2],"OPERATOR",0)) { if (bitmap[0].Bitmap[0].Type==GSM_OperatorLogo && strcmp(bitmap[0].Bitmap[0].NetworkCode,"000 00")==0) { printmsg("No network code\n"); exit(-1); } } } else { GSM_Init(true); if (mystrncasecmp(argv[2],"OPERATOR",0)) { if (bitmap[0].Bitmap[0].Type==GSM_OperatorLogo && strcmp(bitmap[0].Bitmap[0].NetworkCode,"000 00")==0) { error=Phone->GetNetworkInfo(&s,&NetInfo); Print_Error(error); strcpy(bitmap[0].Bitmap[0].NetworkCode,NetInfo.NetworkCode); if (mystrncasecmp(argv[1],"--savesms",0)) { EncodeUnicode(Sender, "OpLogo",6); EncodeUnicode(Sender+6*2,bitmap[0].Bitmap[0].NetworkCode,3); EncodeUnicode(Sender+6*2+3*2,bitmap[0].Bitmap[0].NetworkCode+4,2); if (UnicodeLength(GSM_GetNetworkName(bitmap[0].Bitmap[0].NetworkCode))<GSM_MAX_SMS_NAME_LENGTH-7) { EncodeUnicode(Name,"OpLogo ",7); CopyUnicodeString(Name+7*2,GSM_GetNetworkName(bitmap[0].Bitmap[0].NetworkCode)); } else { CopyUnicodeString(Name,Sender); } } } } } error=GSM_EncodeMultiPartSMS(&SMSInfo,&sms); Print_Error(error); for (i=0;i<SMSInfo.EntriesNum;i++) { switch (SMSInfo.Entries[i].ID) { case SMS_NokiaRingtone: case SMS_NokiaRingtoneLong: case SMS_NokiaProfileLong: case SMS_EMSSound10: case SMS_EMSSound12: case SMS_EMSSonyEricssonSound: case SMS_EMSSound10Long: case SMS_EMSSound12Long: case SMS_EMSSonyEricssonSoundLong: if (SMSInfo.Entries[i].RingtoneNotes!=SMSInfo.Entries[i].Ringtone->NoteTone.NrCommands) { printmsg("Warning: ringtone too long. %i percent part cut\n", (SMSInfo.Entries[i].Ringtone->NoteTone.NrCommands-SMSInfo.Entries[i].RingtoneNotes)*100/SMSInfo.Entries[i].Ringtone->NoteTone.NrCommands); } default: break; } } if (MaxSMS != -1 && sms.Number > MaxSMS) { printmsg("There is %i SMS packed and %i limit. Exiting\n",sms.Number,MaxSMS); if (!mystrncasecmp(argv[1],"--displaysms",0) && !mystrncasecmp(argv[1],"--sendsmsdsms",0)) GSM_Terminate(); exit(-1); } if (mystrncasecmp(argv[1],"--displaysms",0)) { if (SMSCSet != 0) { printmsg("Use -smscnumber option to give SMSC number\n"); exit(-1); } for (i=0;i<sms.Number;i++) { sms.SMS[i].Location = 0; sms.SMS[i].ReplyViaSameSMSC = ReplyViaSameSMSC; sms.SMS[i].SMSC.Location = 0; sms.SMS[i].PDU = SMS_Submit; if (DeliveryReport) sms.SMS[i].PDU = SMS_Status_Report; CopyUnicodeString(sms.SMS[i].Number, Sender); CopyUnicodeString(sms.SMS[i].SMSC.Number, SMSC); if (Validity.Format != 0) memcpy(&sms.SMS[i].SMSC.Validity,&Validity,sizeof(GSM_SMSValidity)); DisplaySMSFrame(&sms.SMS[i]); } printmsg("\nNumber of SMS: %i\n",sms.Number); exit(sms.Number); } if (mystrncasecmp(argv[1],"--sendsmsdsms",0)) { if (SMSCSet != 0) { printmsg("Use -smscnumber option to give SMSC number\n"); exit(-1); } for (i=0;i<sms.Number;i++) { sms.SMS[i].Location = 0; sms.SMS[i].ReplyViaSameSMSC = ReplyViaSameSMSC; sms.SMS[i].SMSC.Location = 0; sms.SMS[i].PDU = SMS_Submit; if (DeliveryReport) sms.SMS[i].PDU = SMS_Status_Report; CopyUnicodeString(sms.SMS[i].Number, Sender); CopyUnicodeString(sms.SMS[i].SMSC.Number, SMSC); if (Validity.Format != 0) memcpy(&sms.SMS[i].SMSC.Validity,&Validity,sizeof(GSM_SMSValidity)); } SMSDaemonSendSMS(argv[4],argv[5],&sms); exit(0); } if (mystrncasecmp(argv[1],"--savesms",0) || SendSaved) { error=Phone->GetSMSFolders(&s, &folders); Print_Error(error); if (SendSaved) { if (Validity.Format != 0 && SMSCSet != 0) { PhoneSMSC.Location = SMSCSet; error=Phone->GetSMSC(&s,&PhoneSMSC); Print_Error(error); CopyUnicodeString(SMSC,PhoneSMSC.Number); SMSCSet = 0; } s.User.SendSMSStatus = SendSMSStatus; signal(SIGINT, interrupt); printmsgerr("If you want break, press Ctrl+C...\n"); } for (i=0;i<sms.Number;i++) { printmsg("Saving SMS %i/%i\n",i+1,sms.Number); // sms.SMS[i].Location = 0; sms.SMS[i].Folder = Folder; sms.SMS[i].State = State; sms.SMS[i].ReplyViaSameSMSC = ReplyViaSameSMSC; sms.SMS[i].SMSC.Location = SMSCSet; if (SendSaved) { sms.SMS[i].PDU = SMS_Submit; if (DeliveryReport) sms.SMS[i].PDU = SMS_Status_Report; if (Validity.Format != 0) sms.SMS[i].SMSC.Validity = Validity; } else { sms.SMS[i].PDU = SMS_Deliver; } CopyUnicodeString(sms.SMS[i].Number, Sender); CopyUnicodeString(sms.SMS[i].Name, Name); if (SMSCSet==0) CopyUnicodeString(sms.SMS[i].SMSC.Number, SMSC); error=Phone->AddSMS(&s, &sms.SMS[i]); Print_Error(error); printmsg("Saved in folder \"%s\", location %i\n", DecodeUnicodeConsole(folders.Folder[sms.SMS[i].Folder-1].Name),sms.SMS[i].Location); if (SendSaved) { printmsg("Sending sms from folder \"%s\", location %i\n", DecodeUnicodeString(folders.Folder[sms.SMS[i].Folder-1].Name),sms.SMS[i].Location); SMSStatus = ERR_TIMEOUT; error=Phone->SendSavedSMS(&s, 0, sms.SMS[i].Location); Print_Error(error); printmsg("....waiting for network answer"); while (!gshutdown) { GSM_ReadDevice(&s,true); if (SMSStatus == ERR_UNKNOWN) { GSM_Terminate(); exit(-1); } if (SMSStatus == ERR_NONE) break; } } } } else { if (Validity.Format != 0 && SMSCSet != 0) { PhoneSMSC.Location = SMSCSet; error=Phone->GetSMSC(&s,&PhoneSMSC); Print_Error(error); CopyUnicodeString(SMSC,PhoneSMSC.Number); SMSCSet = 0; } signal(SIGINT, interrupt); printmsgerr("If you want break, press Ctrl+C...\n"); s.User.SendSMSStatus = SendSMSStatus; for (i=0;i<sms.Number;i++) { printmsg("Sending SMS %i/%i",i+1,sms.Number); sms.SMS[i].Location = 0; sms.SMS[i].ReplyViaSameSMSC = ReplyViaSameSMSC; sms.SMS[i].SMSC.Location = SMSCSet; sms.SMS[i].PDU = SMS_Submit; if (DeliveryReport) sms.SMS[i].PDU = SMS_Status_Report; CopyUnicodeString(sms.SMS[i].Number, Sender); if (SMSCSet==0) CopyUnicodeString(sms.SMS[i].SMSC.Number, SMSC); if (Validity.Format != 0) memcpy(&sms.SMS[i].SMSC.Validity,&Validity,sizeof(GSM_SMSValidity)); SMSStatus = ERR_TIMEOUT; error=Phone->SendSMS(&s, &sms.SMS[i]); Print_Error(error); printmsg("....waiting for network answer"); while (!gshutdown) { GSM_ReadDevice(&s,true); if (SMSStatus == ERR_UNKNOWN) { GSM_Terminate(); exit(-1); } if (SMSStatus == ERR_NONE) break; } } } GSM_Terminate(); } #ifdef GSM_ENABLE_BACKUP static void SaveFile(int argc, char *argv[]) { GSM_Backup Backup; int i,j; FILE *file; unsigned char Buffer[10000]; GSM_MemoryEntry *pbk; if (mystrncasecmp(argv[2],"CALENDAR",0)) { if (argc<5) { printmsg("Where is backup filename and location ?\n"); exit(-1); } error=GSM_ReadBackupFile(argv[4],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); i = 0; while (Backup.Calendar[i]!=NULL) { if (i == atoi(argv[5])-1) break; i++; } if (i != atoi(argv[5])-1) { printmsg("Calendar note not found in file\n"); exit(-1); } j = 0; GSM_EncodeVCALENDAR(Buffer, &j, Backup.Calendar[i],true,Nokia_VCalendar); } else if (mystrncasecmp(argv[2],"BOOKMARK",0)) { if (argc<5) { printmsg("Where is backup filename and location ?\n"); exit(-1); } error=GSM_ReadBackupFile(argv[4],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); i = 0; while (Backup.WAPBookmark[i]!=NULL) { if (i == atoi(argv[5])-1) break; i++; } if (i != atoi(argv[5])-1) { printmsg("WAP bookmark not found in file\n"); exit(-1); } j = 0; GSM_EncodeURLFile(Buffer, &j, Backup.WAPBookmark[i]); } else if (mystrncasecmp(argv[2],"NOTE",0)) { if (argc<5) { printmsg("Where is backup filename and location ?\n"); exit(-1); } error=GSM_ReadBackupFile(argv[4],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); i = 0; while (Backup.Note[i]!=NULL) { if (i == atoi(argv[5])-1) break; i++; } if (i != atoi(argv[5])-1) { printmsg("Note not found in file\n"); exit(-1); } j = 0; GSM_EncodeVNTFile(Buffer, &j, Backup.Note[i]); } else if (mystrncasecmp(argv[2],"TODO",0)) { if (argc<5) { printmsg("Where is backup filename and location ?\n"); exit(-1); } error=GSM_ReadBackupFile(argv[4],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); i = 0; while (Backup.ToDo[i]!=NULL) { if (i == atoi(argv[5])-1) break; i++; } if (i != atoi(argv[5])-1) { printmsg("ToDo note not found in file\n"); exit(-1); } j = 0; GSM_EncodeVTODO(Buffer, &j, Backup.ToDo[i], true, Nokia_VToDo); } else if (mystrncasecmp(argv[2],"VCARD10",0) || mystrncasecmp(argv[2],"VCARD21",0)) { if (argc<6) { printmsg("Where is backup filename and location and memory type ?\n"); exit(-1); } error=GSM_ReadBackupFile(argv[4],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); i = 0; if (mystrncasecmp(argv[5],"SM",0)) { while (Backup.SIMPhonebook[i]!=NULL) { if (i == atoi(argv[6])-1) break; i++; } if (i != atoi(argv[6])-1) { printmsg("Phonebook entry not found in file\n"); exit(-1); } pbk = Backup.SIMPhonebook[i]; } else if (mystrncasecmp(argv[5],"ME",0)) { while (Backup.PhonePhonebook[i]!=NULL) { if (i == atoi(argv[6])-1) break; i++; } if (i != atoi(argv[6])-1) { printmsg("Phonebook entry not found in file\n"); exit(-1); } pbk = Backup.PhonePhonebook[i]; } else { printmsg("Unknown memory type: \"%s\"\n",argv[5]); exit(-1); } j = 0; if (mystrncasecmp(argv[2],"VCARD10",0)) { GSM_EncodeVCARD(Buffer,&j,pbk,true,Nokia_VCard10); } else { GSM_EncodeVCARD(Buffer,&j,pbk,true,Nokia_VCard21); } } else { printmsg("What format of file (\"%s\") ?\n",argv[2]); exit(-1); } file = fopen(argv[3],"wb"); fwrite(Buffer,1,j,file); fclose(file); } static void Backup(int argc, char *argv[]) { int i, used; GSM_MemoryStatus MemStatus; GSM_ToDoEntry ToDo; GSM_ToDoStatus ToDoStatus; GSM_MemoryEntry Pbk; GSM_CalendarEntry Calendar; GSM_Bitmap Bitmap; GSM_WAPBookmark Bookmark; GSM_Profile Profile; GSM_MultiWAPSettings Settings; GSM_SyncMLSettings SyncML; GSM_ChatSettings Chat; GSM_Ringtone Ringtone; GSM_SMSC SMSC; GSM_Backup Backup; GSM_NoteEntry Note; GSM_Backup_Info Info; GSM_FMStation FMStation; GSM_GPRSAccessPoint GPRSPoint; bool DoBackup; if (argc == 4 && mystrncasecmp(argv[3],"-yes",0)) always_answer_yes = true; GSM_ClearBackup(&Backup); GSM_GetBackupFormatFeatures(argv[2],&Info); sprintf(Backup.Creator,"Gammu %s",VERSION); if (strlen(GetOS()) != 0) { strcat(Backup.Creator+strlen(Backup.Creator),", "); strcat(Backup.Creator+strlen(Backup.Creator),GetOS()); } if (strlen(GetCompiler()) != 0) { strcat(Backup.Creator+strlen(Backup.Creator),", "); strcat(Backup.Creator+strlen(Backup.Creator),GetCompiler()); } signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); GSM_Init(true); if (Info.UseUnicode) { Info.UseUnicode=answer_yes("Use Unicode subformat of backup file"); } if (Info.DateTime) { GSM_GetCurrentDateTime (&Backup.DateTime); Backup.DateTimeAvailable=true; } if (Info.Model) { error=Phone->GetManufacturer(&s); Print_Error(error); sprintf(Backup.Model,"%s ",s.Phone.Data.Manufacturer); if (s.Phone.Data.ModelInfo->model[0]!=0) { strcat(Backup.Model,s.Phone.Data.ModelInfo->model); } else { strcat(Backup.Model,s.Phone.Data.Model); } strcat(Backup.Model," "); strcat(Backup.Model,s.Phone.Data.Version); } if (Info.IMEI) { error=Phone->GetIMEI(&s); if (error != ERR_NOTSUPPORTED) { strcpy(Backup.IMEI, s.Phone.Data.IMEI); Print_Error(error); } else { Backup.IMEI[0] = 0; } } printf("\n"); DoBackup = false; if (Info.PhonePhonebook) { printmsg("Checking phone phonebook\n"); MemStatus.MemoryType = MEM_ME; error=Phone->GetMemoryStatus(&s, &MemStatus); if (error==ERR_NONE && MemStatus.MemoryUsed != 0) { /*LRif (answer_yes(" Backup phone phonebook")) */DoBackup = true; } } if (DoBackup) { Pbk.MemoryType = MEM_ME; i = 1; used = 0; while (used != MemStatus.MemoryUsed) { Pbk.Location = i; error=Phone->GetMemory(&s, &Pbk); if (error != ERR_EMPTY) { Print_Error(error); if (used < GSM_BACKUP_MAX_PHONEPHONEBOOK) { Backup.PhonePhonebook[used] = malloc(sizeof(GSM_MemoryEntry)); if (Backup.PhonePhonebook[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.PhonePhonebook[used+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_PHONEPHONEBOOK"); GSM_Terminate(); exit(-1); } *Backup.PhonePhonebook[used]=Pbk; used++; } printmsgerr("%c Reading: %i percent",13,used*100/MemStatus.MemoryUsed); i++; if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.SIMPhonebook) { printmsg("Checking SIM phonebook\n"); MemStatus.MemoryType = MEM_SM; error=Phone->GetMemoryStatus(&s, &MemStatus); if (error==ERR_NONE && MemStatus.MemoryUsed != 0) { if (answer_yes(" Backup SIM phonebook")) DoBackup=true; } } if (DoBackup) { Pbk.MemoryType = MEM_SM; i = 1; used = 0; while (used != MemStatus.MemoryUsed) { Pbk.Location = i; error=Phone->GetMemory(&s, &Pbk); if (error != ERR_EMPTY) { Print_Error(error); if (used < GSM_BACKUP_MAX_SIMPHONEBOOK) { Backup.SIMPhonebook[used] = malloc(sizeof(GSM_MemoryEntry)); if (Backup.SIMPhonebook[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.SIMPhonebook[used + 1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_SIMPHONEBOOK"); GSM_Terminate(); exit(-1); } *Backup.SIMPhonebook[used]=Pbk; used++; } printmsgerr("%c Reading: %i percent",13,used*100/MemStatus.MemoryUsed); i++; if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.Calendar) { printmsg("Checking calendar\n"); error=Phone->GetNextCalendar(&s,&Calendar,true); if (error==ERR_NONE) { if (answer_yes(" Backup calendar notes")) DoBackup = true; } } if (DoBackup) { used = 0; printmsgerr(" Reading : "); while (error == ERR_NONE) { if (used < GSM_MAXCALENDARTODONOTES) { Backup.Calendar[used] = malloc(sizeof(GSM_CalendarEntry)); if (Backup.Calendar[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.Calendar[used+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_MAXCALENDARTODONOTES"); GSM_Terminate(); exit(-1); } *Backup.Calendar[used]=Calendar; used ++; error=Phone->GetNextCalendar(&s,&Calendar,false); printmsgerr("*"); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.ToDo) { printmsg("Checking ToDo\n"); error=Phone->GetToDoStatus(&s,&ToDoStatus); if (error == ERR_NONE && ToDoStatus.Used != 0) { if (answer_yes(" Backup ToDo")) DoBackup = true; } } if (DoBackup) { used = 0; error=Phone->GetNextToDo(&s,&ToDo,true); while (error == ERR_NONE) { if (used < GSM_MAXCALENDARTODONOTES) { Backup.ToDo[used] = malloc(sizeof(GSM_ToDoEntry)); if (Backup.ToDo[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.ToDo[used+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_MAXCALENDARTODONOTES"); GSM_Terminate(); exit(-1); } *Backup.ToDo[used]=ToDo; used ++; error=Phone->GetNextToDo(&s,&ToDo,false); printmsgerr("%c Reading: %i percent",13,used*100/ToDoStatus.Used); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.Note) { printmsg("Checking notes\n"); error=Phone->GetNextNote(&s,&Note,true); if (error==ERR_NONE) { if (answer_yes(" Backup notes")) DoBackup = true; } } if (DoBackup) { used = 0; printmsgerr(" Reading : "); while (error == ERR_NONE) { if (used < GSM_BACKUP_MAX_NOTE) { Backup.Note[used] = malloc(sizeof(GSM_NoteEntry)); if (Backup.Note[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.Note[used+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_NOTE"); GSM_Terminate(); exit(-1); } *Backup.Note[used]=Note; used ++; error=Phone->GetNextNote(&s,&Note,false); printmsgerr("*"); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.CallerLogos) { printmsg("Checking caller logos\n"); Bitmap.Type = GSM_CallerGroupLogo; Bitmap.Location = 1; error=Phone->GetBitmap(&s,&Bitmap); if (error == ERR_NONE) { if (answer_yes(" Backup caller groups and logos")) DoBackup = true; } } if (DoBackup) { printmsgerr(" Reading : "); error = ERR_NONE; used = 0; while (error == ERR_NONE) { if (used < GSM_BACKUP_MAX_CALLER) { Backup.CallerLogos[used] = malloc(sizeof(GSM_Bitmap)); if (Backup.CallerLogos[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.CallerLogos[used+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_CALLER"); GSM_Terminate(); exit(-1); } *Backup.CallerLogos[used] = Bitmap; used ++; Bitmap.Location = used + 1; error=Phone->GetBitmap(&s,&Bitmap); printmsgerr("*"); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.SMSC) { printmsg("Checking SMS profiles\n"); if (answer_yes(" Backup SMS profiles")) DoBackup = true; } if (DoBackup) { used = 0; printmsgerr(" Reading: "); while (true) { SMSC.Location = used + 1; error = Phone->GetSMSC(&s,&SMSC); if (error != ERR_NONE) break; if (used < GSM_BACKUP_MAX_SMSC) { Backup.SMSC[used] = malloc(sizeof(GSM_SMSC)); if (Backup.SMSC[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.SMSC[used + 1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_SMSC"); GSM_Terminate(); exit(-1); } *Backup.SMSC[used]=SMSC; used++; printmsgerr("*"); } printmsgerr("\n"); } DoBackup = false; if (Info.StartupLogo) { printmsg("Checking startup text\n"); Bitmap.Type = GSM_WelcomeNote_Text; error = Phone->GetBitmap(&s,&Bitmap); if (error == ERR_NONE) { if (answer_yes(" Backup startup logo/text")) DoBackup = true; } } if (DoBackup) { Backup.StartupLogo = malloc(sizeof(GSM_Bitmap)); if (Backup.StartupLogo == NULL) Print_Error(ERR_MOREMEMORY); *Backup.StartupLogo = Bitmap; if (Bitmap.Text[0]==0 && Bitmap.Text[1]==0) { Bitmap.Type = GSM_StartupLogo; error = Phone->GetBitmap(&s,&Bitmap); if (error == ERR_NONE) *Backup.StartupLogo = Bitmap; } } DoBackup = false; if (Info.OperatorLogo) { printmsg("Checking operator logo\n"); Bitmap.Type = GSM_OperatorLogo; error=Phone->GetBitmap(&s,&Bitmap); if (error == ERR_NONE) { if (strcmp(Bitmap.NetworkCode,"000 00")!=0) { if (answer_yes(" Backup operator logo")) DoBackup = true; } } } if (DoBackup) { Backup.OperatorLogo = malloc(sizeof(GSM_Bitmap)); if (Backup.OperatorLogo == NULL) Print_Error(ERR_MOREMEMORY); *Backup.OperatorLogo = Bitmap; } DoBackup = false; if (Info.WAPBookmark) { printmsg("Checking WAP bookmarks\n"); Bookmark.Location = 1; error=Phone->GetWAPBookmark(&s,&Bookmark); if (error==ERR_NONE) { if (answer_yes(" Backup WAP bookmarks")) DoBackup = true; } } if (DoBackup) { used = 0; printmsgerr(" Reading : "); while (error == ERR_NONE) { if (used < GSM_BACKUP_MAX_WAPBOOKMARK) { Backup.WAPBookmark[used] = malloc(sizeof(GSM_WAPBookmark)); if (Backup.WAPBookmark[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.WAPBookmark[used+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_WAPBOOKMARK"); GSM_Terminate(); exit(-1); } *Backup.WAPBookmark[used]=Bookmark; used ++; Bookmark.Location = used+1; error=Phone->GetWAPBookmark(&s,&Bookmark); printmsgerr("*"); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.WAPSettings) { printmsg("Checking WAP settings\n"); Settings.Location = 1; error=Phone->GetWAPSettings(&s,&Settings); if (error==ERR_NONE) { if (answer_yes(" Backup WAP settings")) DoBackup = true; } } if (DoBackup) { used = 0; printmsgerr(" Reading : "); while (error == ERR_NONE) { if (used < GSM_BACKUP_MAX_WAPSETTINGS) { Backup.WAPSettings[used] = malloc(sizeof(GSM_MultiWAPSettings)); if (Backup.WAPSettings[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.WAPSettings[used+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_WAPSETTINGS"); GSM_Terminate(); exit(-1); } *Backup.WAPSettings[used]=Settings; used ++; Settings.Location = used+1; error=Phone->GetWAPSettings(&s,&Settings); printmsgerr("*"); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.MMSSettings) { printmsg("Checking MMS settings\n"); Settings.Location = 1; error=Phone->GetMMSSettings(&s,&Settings); if (error==ERR_NONE) { if (answer_yes(" Backup MMS settings")) DoBackup = true; } } if (DoBackup) { used = 0; printmsgerr(" Reading : "); while (error == ERR_NONE) { if (used < GSM_BACKUP_MAX_MMSSETTINGS) { Backup.MMSSettings[used] = malloc(sizeof(GSM_MultiWAPSettings)); if (Backup.MMSSettings[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.MMSSettings[used+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_MMSSETTINGS"); GSM_Terminate(); exit(-1); } *Backup.MMSSettings[used]=Settings; used ++; Settings.Location = used+1; error=Phone->GetMMSSettings(&s,&Settings); printmsgerr("*"); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.ChatSettings) { printmsg("Checking Chat settings\n"); Chat.Location = 1; error=Phone->GetChatSettings(&s,&Chat); if (error==ERR_NONE) { if (answer_yes(" Backup Chat settings")) DoBackup = true; } } if (DoBackup) { used = 0; printmsgerr(" Reading : "); while (error == ERR_NONE) { if (used < GSM_BACKUP_MAX_CHATSETTINGS) { Backup.ChatSettings[used] = malloc(sizeof(GSM_ChatSettings)); if (Backup.ChatSettings[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.ChatSettings[used+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_CHATSETTINGS"); GSM_Terminate(); exit(-1); } *Backup.ChatSettings[used]=Chat; used ++; Chat.Location = used+1; error=Phone->GetChatSettings(&s,&Chat); printmsgerr("*"); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.SyncMLSettings) { printmsg("Checking SyncML settings\n"); SyncML.Location = 1; error=Phone->GetSyncMLSettings(&s,&SyncML); if (error==ERR_NONE) { if (answer_yes(" Backup SyncML settings")) DoBackup = true; } } if (DoBackup) { used = 0; printmsgerr(" Reading : "); while (error == ERR_NONE) { if (used < GSM_BACKUP_MAX_SYNCMLSETTINGS) { Backup.SyncMLSettings[used] = malloc(sizeof(GSM_SyncMLSettings)); if (Backup.SyncMLSettings[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.SyncMLSettings[used+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_SYNCMLSETTINGS"); GSM_Terminate(); exit(-1); } *Backup.SyncMLSettings[used]=SyncML; used ++; SyncML.Location = used+1; error=Phone->GetSyncMLSettings(&s,&SyncML); printmsgerr("*"); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.Ringtone) { printmsg("Checking user ringtones\n"); Ringtone.Location = 1; Ringtone.Format = 0; error=Phone->GetRingtone(&s,&Ringtone,false); if (error==ERR_EMPTY || error == ERR_NONE) { if (answer_yes(" Backup user ringtones")) DoBackup = true; } } if (DoBackup) { used = 0; i = 1; printmsgerr(" Reading : "); while (error == ERR_NONE || error == ERR_EMPTY) { if (error == ERR_NONE) { if (used < GSM_BACKUP_MAX_RINGTONES) { Backup.Ringtone[used] = malloc(sizeof(GSM_Ringtone)); if (Backup.Ringtone[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.Ringtone[used+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_RINGTONES"); GSM_Terminate(); exit(-1); } *Backup.Ringtone[used]=Ringtone; used ++; } i++; Ringtone.Location = i; Ringtone.Format = 0; error=Phone->GetRingtone(&s,&Ringtone,false); printmsgerr("*"); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoBackup = false; if (Info.Profiles) { printmsg("Checking phone profiles\n"); Profile.Location = 1; error = Phone->GetProfile(&s,&Profile); if (error == ERR_NONE) { if (answer_yes(" Backup phone profiles")) DoBackup = true; } } if (DoBackup) { used = 0; printmsgerr(" Reading: "); while (true) { Profile.Location = used + 1; error = Phone->GetProfile(&s,&Profile); if (error != ERR_NONE) break; if (used < GSM_BACKUP_MAX_PROFILES) { Backup.Profiles[used] = malloc(sizeof(GSM_Profile)); if (Backup.Profiles[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.Profiles[used + 1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_PROFILES"); GSM_Terminate(); exit(-1); } *Backup.Profiles[used]=Profile; used++; printmsgerr("*"); } printmsgerr("\n"); } DoBackup = false; if (Info.FMStation) { printmsg("Checking FM stations\n"); FMStation.Location = 1; error = Phone->GetFMStation(&s,&FMStation); if (error == ERR_NONE || error == ERR_EMPTY) { if (answer_yes(" Backup phone FM stations")) DoBackup=true; } } if (DoBackup) { used = 0; i = 1; printmsgerr(" Reading: "); while (error == ERR_NONE || error == ERR_EMPTY) { error = Phone->GetFMStation(&s,&FMStation); if (error == ERR_NONE) { if (used < GSM_BACKUP_MAX_FMSTATIONS) { Backup.FMStation[used] = malloc(sizeof(GSM_FMStation)); if (Backup.FMStation[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.FMStation[used + 1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_FMSTATIONS"); GSM_Terminate(); exit(-1); } *Backup.FMStation[used]=FMStation; used++; } i++; FMStation.Location = i; printmsgerr("*"); } printmsgerr("\n"); } DoBackup = false; if (Info.GPRSPoint) { printmsg("Checking GPRS access points\n"); GPRSPoint.Location = 1; error = Phone->GetGPRSAccessPoint(&s,&GPRSPoint); if (error == ERR_NONE || error == ERR_EMPTY) { if (answer_yes(" Backup GPRS access points")) DoBackup = true; } } if (DoBackup) { used = 0; i = 1; printmsgerr(" Reading: "); while (error == ERR_NONE || error == ERR_EMPTY) { error = Phone->GetGPRSAccessPoint(&s,&GPRSPoint); if (error == ERR_NONE) { if (used < GSM_BACKUP_MAX_GPRSPOINT) { Backup.GPRSPoint[used] = malloc(sizeof(GSM_GPRSAccessPoint)); if (Backup.GPRSPoint[used] == NULL) Print_Error(ERR_MOREMEMORY); Backup.GPRSPoint[used + 1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_GPRSPOINT"); GSM_Terminate(); exit(-1); } *Backup.GPRSPoint[used]=GPRSPoint; used++; } i++; GPRSPoint.Location = i; printmsgerr("*"); } printmsgerr("\n"); } GSM_Terminate(); GSM_SaveBackupFile(argv[2],&Backup, Info.UseUnicode); GSM_FreeBackup(&Backup); } static void Restore(int argc, char *argv[]) { GSM_Backup Backup; GSM_FMStation FMStation; GSM_DateTime date_time; GSM_CalendarEntry Calendar; GSM_Bitmap Bitmap; GSM_Ringtone Ringtone; GSM_MemoryEntry Pbk; GSM_MemoryStatus MemStatus; GSM_ToDoEntry ToDo; GSM_ToDoStatus ToDoStatus; + GSM_NoteEntry Note; GSM_Profile Profile; GSM_MultiWAPSettings Settings; GSM_GPRSAccessPoint GPRSPoint; GSM_WAPBookmark Bookmark; int i, used, max = 0; bool Past = true; bool Found, DoRestore; error=GSM_ReadBackupFile(argv[2],&Backup); if (error!=ERR_NOTIMPLEMENTED) { Print_Error(error); } else { printmsgerr("WARNING: Some data not read from file. It can be damaged or restoring some settings from this file format not implemented (maybe higher Gammu required ?)\n"); } signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); if (Backup.DateTimeAvailable) printmsgerr("Time of backup : %s\n",OSDateTime(Backup.DateTime,false)); if (Backup.Model[0]!=0) printmsgerr("Phone : %s\n",Backup.Model); if (Backup.IMEI[0]!=0) printmsgerr("IMEI : %s\n",Backup.IMEI); if (Backup.Creator[0]!=0) printmsgerr("File created by : %s\n",Backup.Creator); if (Backup.MD5Calculated[0]!=0) { dbgprintf("\"%s\"\n",Backup.MD5Original); dbgprintf("\"%s\"\n",Backup.MD5Calculated); if (strcmp(Backup.MD5Original,Backup.MD5Calculated)) { if (!answer_yes("Checksum in backup file do not match. Continue")) return; } } GSM_Init(true); DoRestore = false; if (Backup.PhonePhonebook[0] != NULL) { MemStatus.MemoryType = MEM_ME; error=Phone->GetMemoryStatus(&s, &MemStatus); if (error==ERR_NONE) { max = 0; while (Backup.PhonePhonebook[max]!=NULL) max++; printmsgerr("%i entries in backup file\n",max); /* LR if (answer_yes("Restore phone phonebook")) */DoRestore = true; } } if (DoRestore) { used = 0; for (i=0;i<MemStatus.MemoryUsed+MemStatus.MemoryFree;i++) { Pbk.MemoryType = MEM_ME; Pbk.Location = i + 1; Pbk.EntriesNum = 0; if (used<max) { if (Backup.PhonePhonebook[used]->Location == Pbk.Location) { Pbk = *Backup.PhonePhonebook[used]; used++; dbgprintf("Location %i\n",Pbk.Location); if (Pbk.EntriesNum != 0) error=Phone->SetMemory(&s, &Pbk); } } if (Pbk.EntriesNum == 0) error=Phone->DeleteMemory(&s, &Pbk); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/(MemStatus.MemoryUsed+MemStatus.MemoryFree)); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoRestore = false; if (Backup.SIMPhonebook[0] != NULL) { MemStatus.MemoryType = MEM_SM; error=Phone->GetMemoryStatus(&s, &MemStatus); if (error==ERR_NONE) { max = 0; while (Backup.SIMPhonebook[max]!=NULL) max++; printmsgerr("%i entries in backup file\n",max); if (answer_yes("Restore SIM phonebook")) DoRestore = true; } } if (DoRestore) { used = 0; for (i=0;i<MemStatus.MemoryUsed+MemStatus.MemoryFree;i++) { Pbk.MemoryType = MEM_SM; Pbk.Location = i + 1; Pbk.EntriesNum = 0; if (used<max) { if (Backup.SIMPhonebook[used]->Location == Pbk.Location) { Pbk = *Backup.SIMPhonebook[used]; used++; dbgprintf("Location %i\n",Pbk.Location); if (Pbk.EntriesNum != 0) error=Phone->SetMemory(&s, &Pbk); } } if (Pbk.EntriesNum == 0) error=Phone->DeleteMemory(&s, &Pbk); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/(MemStatus.MemoryUsed+MemStatus.MemoryFree)); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoRestore = false; if (Backup.CallerLogos[0] != NULL) { Bitmap.Type = GSM_CallerGroupLogo; Bitmap.Location = 1; error=Phone->GetBitmap(&s,&Bitmap); if (error == ERR_NONE) { if (answer_yes("Restore caller groups and logos")) DoRestore = true; } } if (DoRestore) { max = 0; while (Backup.CallerLogos[max]!=NULL) max++; for (i=0;i<max;i++) { error=Phone->SetBitmap(&s,Backup.CallerLogos[i]); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } if (!mystrncasecmp(s.CurrentConfig->SyncTime,"yes",0)) { if ( true /*LRanswer_yes("Do you want to set date/time in phone (NOTE: in some phones it's required to correctly restore calendar notes and other items)")*/) { GSM_GetCurrentDateTime(&date_time); error=Phone->SetDateTime(&s, &date_time); Print_Error(error); } } DoRestore = false; if (Backup.Calendar[0] != NULL) { /* N6110 doesn't support getting calendar status */ error = Phone->GetNextCalendar(&s,&Calendar,true); if (error == ERR_NONE || error == ERR_INVALIDLOCATION || error == ERR_EMPTY) { max = 0; while (Backup.Calendar[max] != NULL) max++; printmsgerr("%i entries in backup file\n",max); // LR //if (answer_yes("Restore calendar notes")) { //Past = answer_yes("Restore notes from the past"); DoRestore = true; //} } } if (DoRestore) { printmsgerr("Deleting old notes: "); error = Phone->DeleteAllCalendar(&s); if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { while (1) { error = Phone->GetNextCalendar(&s,&Calendar,true); if (error != ERR_NONE) break; error = Phone->DeleteCalendar(&s,&Calendar); Print_Error(error); printmsgerr("*"); } printmsgerr("\n"); } else { printmsgerr("Done\n"); Print_Error(error); } for (i=0;i<max;i++) { if (!Past && IsCalendarNoteFromThePast(Backup.Calendar[i])) continue; Calendar = *Backup.Calendar[i]; error=Phone->AddCalendar(&s,&Calendar); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoRestore = false; if (Backup.ToDo[0] != NULL) { error = Phone->GetToDoStatus(&s,&ToDoStatus); if (error == ERR_NONE) { max = 0; while (Backup.ToDo[max]!=NULL) max++; printmsgerr("%i entries in backup file\n",max); //LR if (answer_yes("Restore ToDo")) DoRestore = true; } } if (DoRestore) { ToDo = *Backup.ToDo[0]; error = Phone->SetToDo(&s,&ToDo); } if (DoRestore && (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED)) { printmsgerr("Deleting old ToDo: "); error=Phone->DeleteAllToDo(&s); if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { while (1) { error = Phone->GetNextToDo(&s,&ToDo,true); if (error != ERR_NONE) break; error = Phone->DeleteToDo(&s,&ToDo); Print_Error(error); printmsgerr("*"); } printmsgerr("\n"); } else { printmsgerr("Done\n"); Print_Error(error); } for (i=0;i<max;i++) { ToDo = *Backup.ToDo[i]; ToDo.Location = 0; error=Phone->AddToDo(&s,&ToDo); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } else if (DoRestore) { /* At first delete entries, that were deleted */ used = 0; error = Phone->GetNextToDo(&s,&ToDo,true); while (error == ERR_NONE) { used++; Found = false; for (i=0;i<max;i++) { if (Backup.ToDo[i]->Location == ToDo.Location) { Found = true; break; } } if (!Found) { error=Phone->DeleteToDo(&s,&ToDo); Print_Error(error); } error = Phone->GetNextToDo(&s,&ToDo,false); printmsgerr("%cCleaning: %i percent",13,used*100/ToDoStatus.Used); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); /* Now write modified/new entries */ for (i=0;i<max;i++) { ToDo = *Backup.ToDo[i]; error = Phone->SetToDo(&s,&ToDo); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } + DoRestore = false; + if (Backup.ToDo[0] != NULL) { + error = Phone->GetNotesStatus(&s,&ToDoStatus); + if (error == ERR_NONE) { + max = 0; + while (Backup.Note[max]!=NULL) max++; + printmsgerr("%i entries in backup file\n",max); + + if (answer_yes("Restore Notes")) DoRestore = true; + } + } + if (DoRestore) { + printmsgerr("Deleting old Notes: "); + while (1) { + error = Phone->GetNextNote(&s,&Note,true); + if (error != ERR_NONE) break; + error = Phone->DeleteNote(&s,&Note); + Print_Error(error); + printmsgerr("*"); + } + printmsgerr("\n"); + + for (i=0;i<max;i++) { + Note = *Backup.Note[i]; + Note.Location = 0; + error=Phone->AddNote(&s,&Note); + Print_Error(error); + printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); + if (gshutdown) { + GSM_Terminate(); + exit(0); + } + } + printmsgerr("\n"); + } + if (Backup.SMSC[0] != NULL && answer_yes("Restore SMSC profiles")) { max = 0; while (Backup.SMSC[max]!=NULL) max++; for (i=0;i<max;i++) { error=Phone->SetSMSC(&s,Backup.SMSC[i]); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } if (Backup.StartupLogo != NULL && answer_yes("Restore startup logo/text")) { error=Phone->SetBitmap(&s,Backup.StartupLogo); Print_Error(error); } if (Backup.OperatorLogo != NULL && answer_yes("Restore operator logo")) { error=Phone->SetBitmap(&s,Backup.OperatorLogo); Print_Error(error); } DoRestore = false; if (Backup.WAPBookmark[0] != NULL) { Bookmark.Location = 1; error = Phone->GetWAPBookmark(&s,&Bookmark); if (error == ERR_NONE || error == ERR_INVALIDLOCATION) { if (answer_yes("Restore WAP bookmarks")) DoRestore = true; } } if (DoRestore) { printmsgerr("Deleting old bookmarks: "); /* One thing to explain: DCT4 phones seems to have bug here. * When delete for example first bookmark, phone change * numeration for getting frame, not for deleting. So, we try to * get 1'st bookmark. Inside frame is "correct" location. We use * it later */ while (error==ERR_NONE) { error = Phone->DeleteWAPBookmark(&s,&Bookmark); Bookmark.Location = 1; error = Phone->GetWAPBookmark(&s,&Bookmark); printmsgerr("*"); } printmsgerr("\n"); max = 0; while (Backup.WAPBookmark[max]!=NULL) max++; for (i=0;i<max;i++) { Bookmark = *Backup.WAPBookmark[i]; Bookmark.Location = 0; error=Phone->SetWAPBookmark(&s,&Bookmark); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoRestore = false; if (Backup.WAPSettings[0] != NULL) { Settings.Location = 1; error = Phone->GetWAPSettings(&s,&Settings); if (error == ERR_NONE) { if (answer_yes("Restore WAP settings")) DoRestore = true; } } if (DoRestore) { max = 0; while (Backup.WAPSettings[max]!=NULL) max++; for (i=0;i<max;i++) { error=Phone->SetWAPSettings(&s,Backup.WAPSettings[i]); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoRestore = false; if (Backup.MMSSettings[0] != NULL) { Settings.Location = 1; error = Phone->GetMMSSettings(&s,&Settings); if (error == ERR_NONE) { if (answer_yes("Restore MMS settings")) DoRestore = true; } } if (DoRestore) { max = 0; while (Backup.MMSSettings[max]!=NULL) max++; for (i=0;i<max;i++) { error=Phone->SetMMSSettings(&s,Backup.MMSSettings[i]); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoRestore = false; if (Backup.Ringtone[0] != NULL) { Ringtone.Location = 1; Ringtone.Format = 0; error = Phone->GetRingtone(&s,&Ringtone,false); if (error == ERR_NONE || error ==ERR_EMPTY) { if (Phone->DeleteUserRingtones != NOTSUPPORTED) { if (answer_yes("Delete all user ringtones")) DoRestore = true; } } } if (DoRestore) { printmsgerr("Deleting: "); error=Phone->DeleteUserRingtones(&s); Print_Error(error); printmsgerr("Done\n"); DoRestore = false; if (answer_yes("Restore user ringtones")) DoRestore = true; } if (DoRestore) { max = 0; while (Backup.Ringtone[max]!=NULL) max++; for (i=0;i<max;i++) { error=GSM_RingtoneConvert(&Ringtone, Backup.Ringtone[i], Ringtone.Format); Print_Error(error); error=Phone->SetRingtone(&s,&Ringtone,&i); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoRestore = false; if (Backup.Profiles[0] != NULL) { Profile.Location = 1; error = Phone->GetProfile(&s,&Profile); if (error == ERR_NONE) { if (answer_yes("Restore profiles")) DoRestore = true; } } if (DoRestore) { Profile.Location= 0; max = 0; while (Backup.Profiles[max]!=NULL) max++; for (i=0;i<max;i++) { Profile = *Backup.Profiles[i]; error=Phone->SetProfile(&s,&Profile); Print_Error(error); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoRestore = false; if (Backup.FMStation[0] != NULL) { FMStation.Location = 1; error = Phone->GetFMStation(&s,&FMStation); if (error == ERR_NONE || error == ERR_EMPTY) { if (answer_yes("Restore FM stations")) DoRestore = true; } } if (DoRestore) { printmsgerr("Deleting old FM stations: "); error=Phone->ClearFMStations(&s); Print_Error(error); printmsgerr("Done\n"); max = 0; while (Backup.FMStation[max]!=NULL) max++; for (i=0;i<max;i++) { FMStation = *Backup.FMStation[i]; error=Phone->SetFMStation(&s,&FMStation); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } DoRestore = false; if (Backup.GPRSPoint[0] != NULL) { GPRSPoint.Location = 1; error = Phone->GetGPRSAccessPoint(&s,&GPRSPoint); if (error == ERR_NONE || error == ERR_EMPTY) { if (answer_yes("Restore GPRS Points")) DoRestore = true; } } if (DoRestore) { max = 0; while (Backup.GPRSPoint[max]!=NULL) max++; for (i=0;i<max;i++) { error=Phone->SetGPRSAccessPoint(&s,Backup.GPRSPoint[i]); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } GSM_Terminate(); } static void AddNew(int argc, char *argv[]) { GSM_Backup Backup; GSM_DateTime date_time; GSM_MemoryEntry Pbk; GSM_MemoryStatus MemStatus; GSM_ToDoEntry ToDo; GSM_ToDoStatus ToDoStatus; GSM_CalendarEntry Calendar; GSM_WAPBookmark Bookmark; int i, max, j; error=GSM_ReadBackupFile(argv[2],&Backup); if (error!=ERR_NOTIMPLEMENTED) Print_Error(error); signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); if (Backup.DateTimeAvailable) printmsgerr("Time of backup : %s\n",OSDateTime(Backup.DateTime,false)); if (Backup.Model[0]!=0) printmsgerr("Phone : %s\n",Backup.Model); if (Backup.IMEI[0]!=0) printmsgerr("IMEI : %s\n",Backup.IMEI); GSM_Init(true); if (Backup.PhonePhonebook[0] != NULL) { MemStatus.MemoryType = MEM_ME; error=Phone->GetMemoryStatus(&s, &MemStatus); if (error==ERR_NONE) { max = 0; while (Backup.PhonePhonebook[max]!=NULL) max++; printmsgerr("%i entries in backup file\n",max); if (MemStatus.MemoryFree < max) { printmsgerr("Memory has only %i free locations.Exiting\n",MemStatus.MemoryFree); } else if (answer_yes("Add phone phonebook entries")) { for (i=0;i<max;i++) { Pbk = *Backup.PhonePhonebook[i]; Pbk.MemoryType = MEM_ME; error=Phone->AddMemory(&s, &Pbk); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } } } if (Backup.SIMPhonebook[0] != NULL) { MemStatus.MemoryType = MEM_SM; error=Phone->GetMemoryStatus(&s, &MemStatus); if (error==ERR_NONE) { max = 0; while (Backup.SIMPhonebook[max]!=NULL) max++; printmsgerr("%i entries in backup file\n",max); if (MemStatus.MemoryFree < max) { printmsgerr("Memory has only %i free locations.Exiting\n",MemStatus.MemoryFree); } else if (answer_yes("Add SIM phonebook entries")) { j = 1; for (i=0;i<max;i++) { Pbk = *Backup.SIMPhonebook[i]; Pbk.MemoryType = MEM_SM; error=Phone->AddMemory(&s, &Pbk); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } } } if (!mystrncasecmp(s.CurrentConfig->SyncTime,"yes",0)) { if (true /*LRanswer_yes("Do you want to set date/time in phone (NOTE: in some phones it's required to correctly restore calendar notes and other items)")*/) { GSM_GetCurrentDateTime(&date_time); error=Phone->SetDateTime(&s, &date_time); Print_Error(error); } } if (Backup.Calendar[0] != NULL) { error = Phone->GetNextCalendar(&s,&Calendar,true); if (error == ERR_NONE || error == ERR_INVALIDLOCATION || error == ERR_EMPTY) { if (answer_yes("Add calendar notes")) { max = 0; while (Backup.Calendar[max]!=NULL) max++; for (i=0;i<max;i++) { Calendar = *Backup.Calendar[i]; error=Phone->AddCalendar(&s,&Calendar); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } } } if (Backup.ToDo[0] != NULL) { ToDo.Location = 1; error=Phone->GetToDoStatus(&s,&ToDoStatus); if (error == ERR_NONE) { if (answer_yes("Add ToDo")) { max = 0; while (Backup.ToDo[max]!=NULL) max++; for (i=0;i<max;i++) { ToDo = *Backup.ToDo[i]; error = Phone->AddToDo(&s,&ToDo); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } } } if (Backup.WAPBookmark[0] != NULL) { Bookmark.Location = 1; error = Phone->GetWAPBookmark(&s,&Bookmark); if (error == ERR_NONE || error == ERR_INVALIDLOCATION) { if (answer_yes("Add WAP bookmarks")) { max = 0; while (Backup.WAPBookmark[max]!=NULL) max++; for (i=0;i<max;i++) { Bookmark = *Backup.WAPBookmark[i]; Bookmark.Location = 0; error=Phone->SetWAPBookmark(&s,&Bookmark); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/max); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } } } GSM_Terminate(); } #endif static void ClearAll(int argc, char *argv[]) { GSM_MemoryStatus MemStatus; GSM_ToDoStatus ToDoStatus; GSM_CalendarEntry Calendar; GSM_ToDoEntry ToDo; + GSM_NoteEntry Note; GSM_WAPBookmark Bookmark; GSM_FMStation Station; GSM_MemoryEntry Pbk; bool DoClear; GSM_Init(true); DoClear = false; MemStatus.MemoryType = MEM_ME; error=Phone->GetMemoryStatus(&s, &MemStatus); if (error==ERR_NONE && MemStatus.MemoryUsed !=0) { if (answer_yes("Delete phone phonebook")) DoClear = true; } if (DoClear) { error = Phone->DeleteAllMemory(&s,MEM_ME); if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { for (i=0;i<MemStatus.MemoryUsed+MemStatus.MemoryFree;i++) { Pbk.MemoryType = MEM_ME; Pbk.Location = i + 1; Pbk.EntriesNum = 0; error=Phone->DeleteMemory(&s, &Pbk); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/(MemStatus.MemoryUsed+MemStatus.MemoryFree)); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } else { printmsgerr("Done\n"); Print_Error(error); } } DoClear = false; MemStatus.MemoryType = MEM_SM; error=Phone->GetMemoryStatus(&s, &MemStatus); if (error==ERR_NONE && MemStatus.MemoryUsed !=0) { if (answer_yes("Delete SIM phonebook")) DoClear = true; } if (DoClear) { error = Phone->DeleteAllMemory(&s,MEM_SM); if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { for (i=0;i<MemStatus.MemoryUsed+MemStatus.MemoryFree;i++) { Pbk.MemoryType = MEM_SM; Pbk.Location = i + 1; Pbk.EntriesNum = 0; error=Phone->DeleteMemory(&s, &Pbk); Print_Error(error); printmsgerr("%cWriting: %i percent",13,(i+1)*100/(MemStatus.MemoryUsed+MemStatus.MemoryFree)); if (gshutdown) { GSM_Terminate(); exit(0); } } printmsgerr("\n"); } else { printmsgerr("Done\n"); Print_Error(error); } } DoClear = false; error = Phone->GetNextCalendar(&s,&Calendar,true); if (error == ERR_NONE) { if (answer_yes("Delete calendar notes")) DoClear = true; } if (DoClear) { printmsgerr("Deleting: "); error=Phone->DeleteAllCalendar(&s); if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { while (1) { error = Phone->GetNextCalendar(&s,&Calendar,true); if (error != ERR_NONE) break; error = Phone->DeleteCalendar(&s,&Calendar); Print_Error(error); printmsgerr("*"); } printmsgerr("\n"); } else { printmsgerr("Done\n"); Print_Error(error); } } DoClear = false; error = Phone->GetToDoStatus(&s,&ToDoStatus); if (error == ERR_NONE && ToDoStatus.Used != 0) { if (answer_yes("Delete ToDo")) DoClear = true; } if (DoClear) { printmsgerr("Deleting: "); error=Phone->DeleteAllToDo(&s); if (error == ERR_NOTSUPPORTED || error == ERR_NOTIMPLEMENTED) { while (1) { error = Phone->GetNextToDo(&s,&ToDo,true); if (error != ERR_NONE) break; error = Phone->DeleteToDo(&s,&ToDo); Print_Error(error); printmsgerr("*"); } printmsgerr("\n"); } else { printmsgerr("Done\n"); Print_Error(error); } } + DoClear = false; + error = Phone->GetNotesStatus(&s,&ToDoStatus); + if (error == ERR_NONE && ToDoStatus.Used != 0) { + if (answer_yes("Delete Notes")) DoClear = true; + } + if (DoClear) { + printmsgerr("Deleting: "); + while (1) { + error = Phone->GetNextNote(&s,&Note,true); + if (error != ERR_NONE) break; + error = Phone->DeleteNote(&s,&Note); + Print_Error(error); + printmsgerr("*"); + } + printmsgerr("\n"); + } + Bookmark.Location = 1; error = Phone->GetWAPBookmark(&s,&Bookmark); if (error == ERR_NONE || error == ERR_INVALIDLOCATION) { if (answer_yes("Delete WAP bookmarks")) { printmsgerr("Deleting: "); /* One thing to explain: DCT4 phones seems to have bug here. * When delete for example first bookmark, phone change * numeration for getting frame, not for deleting. So, we try to * get 1'st bookmark. Inside frame is "correct" location. We use * it later */ while (error==ERR_NONE) { error = Phone->DeleteWAPBookmark(&s,&Bookmark); Bookmark.Location = 1; error = Phone->GetWAPBookmark(&s,&Bookmark); printmsgerr("*"); } printmsgerr("\n"); } } if (Phone->DeleteUserRingtones != NOTSUPPORTED) { if (answer_yes("Delete all user ringtones")) { printmsgerr("Deleting: "); error=Phone->DeleteUserRingtones(&s); Print_Error(error); printmsgerr("Done\n"); } } Station.Location=i; error=Phone->GetFMStation(&s,&Station); if (error == ERR_NONE || error == ERR_EMPTY) { if (answer_yes("Delete all FM station")) { error=Phone->ClearFMStations(&s); Print_Error(error); } } GSM_Terminate(); } static void DisplayConnectionSettings(GSM_MultiWAPSettings *settings,int j) { if (settings->Settings[j].IsContinuous) { printmsg("Connection type : Continuous\n"); } else { printmsg("Connection type : Temporary\n"); } if (settings->Settings[j].IsSecurity) { printmsg("Connection security : On\n"); } else { printmsg("Connection security : Off\n"); } printmsg("Proxy : address \"%s\", port %i\n",DecodeUnicodeConsole(settings->Proxy),settings->ProxyPort); printmsg("2'nd proxy : address \"%s\", port %i\n",DecodeUnicodeConsole(settings->Proxy2),settings->Proxy2Port); switch (settings->Settings[j].Bearer) { case WAPSETTINGS_BEARER_SMS: printmsg("Bearer : SMS"); if (settings->ActiveBearer == WAPSETTINGS_BEARER_SMS) printf(" (active)"); printmsg("\nServer number : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].Server)); printmsg("Service number : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].Service)); break; case WAPSETTINGS_BEARER_DATA: printmsg("Bearer : Data (CSD)"); if (settings->ActiveBearer == WAPSETTINGS_BEARER_DATA) printf(" (active)"); printmsg("\nDial-up number : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].DialUp)); printmsg("IP address : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].IPAddress)); if (settings->Settings[j].ManualLogin) { printmsg("Login Type : Manual\n"); } else { printmsg("Login Type : Automatic\n"); } if (settings->Settings[j].IsNormalAuthentication) { printmsg("Authentication type : Normal\n"); } else { printmsg("Authentication type : Secure\n"); } if (settings->Settings[j].IsISDNCall) { printmsg("Data call type : ISDN\n"); } else { printmsg("Data call type : Analogue\n"); } switch (settings->Settings[j].Speed) { case WAPSETTINGS_SPEED_9600 : printmsg("Data call speed : 9600\n"); break; case WAPSETTINGS_SPEED_14400 : printmsg("Data call speed : 14400\n"); break; case WAPSETTINGS_SPEED_AUTO : printmsg("Data call speed : Auto\n"); break; } printmsg("User name : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].User)); printmsg("Password : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].Password)); break; case WAPSETTINGS_BEARER_USSD: printmsg("Bearer : USSD"); if (settings->ActiveBearer == WAPSETTINGS_BEARER_USSD) printf(" (active)"); printmsg("\nService code : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].Code)); if (settings->Settings[j].IsIP) { printmsg("Address type : IP address\nIPaddress : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].Service)); } else { printmsg("Address type : Service number\nService number : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].Service)); } break; case WAPSETTINGS_BEARER_GPRS: printmsg("Bearer : GPRS"); if (settings->ActiveBearer == WAPSETTINGS_BEARER_GPRS) printf(" (active)"); if (settings->Settings[j].ManualLogin) { printmsg("\nLogin Type : Manual\n"); } else { printmsg("\nLogin Type : Automatic\n"); } if (settings->Settings[j].IsNormalAuthentication) { printmsg("Authentication type : Normal\n"); } else { printmsg("Authentication type : Secure\n"); } printmsg("Access point : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].DialUp)); printmsg("IP address : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].IPAddress)); printmsg("User name : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].User)); printmsg("Password : \"%s\"\n",DecodeUnicodeConsole(settings->Settings[j].Password)); } } static void GetSyncMLSettings(int argc, char *argv[]) { GSM_SyncMLSettings settings; int start,stop,j; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { settings.Location=i; error=Phone->GetSyncMLSettings(&s,&settings); Print_Error(error); printmsg("%i. ",i); if (settings.Name[0]==0 && settings.Name[1]==0) { printmsg("Set %i",i); } else { printmsg("%s",DecodeUnicodeConsole(settings.Name)); } if (settings.Active) printmsg(" (active)"); // if (settings.ReadOnly) printmsg("\nRead only : yes"); printmsg("\n"); printmsg("User : \"%s\"\n",DecodeUnicodeConsole(settings.User)); printmsg("Password : \"%s\"\n",DecodeUnicodeConsole(settings.Password)); printmsg("Phonebook database : \"%s\"\n",DecodeUnicodeConsole(settings.PhonebookDataBase)); printmsg("Calendar database : \"%s\"\n",DecodeUnicodeConsole(settings.CalendarDataBase)); printmsg("Server : \"%s\"\n",DecodeUnicodeConsole(settings.Server)); printmsg("Sync. phonebook : "); if (settings.SyncPhonebook) printmsg("yes\n"); if (!settings.SyncPhonebook) printmsg("no\n"); printmsg("Sync. calendar : "); if (settings.SyncCalendar) printmsg("yes\n"); if (!settings.SyncCalendar) printmsg("no\n"); printmsg("\n"); for (j=0;j<settings.Connection.Number;j++) { if (settings.Connection.Settings[j].Title[0]==0 && settings.Connection.Settings[j].Title[1]==0) { printmsg("Connection set name : Set %i\n",i); } else { printmsg("Connection set name : %s\n",DecodeUnicodeConsole(settings.Connection.Settings[j].Title)); } DisplayConnectionSettings(&settings.Connection,j); printf("\n"); } } GSM_Terminate(); } static void GetChatSettings(int argc, char *argv[]) { GSM_ChatSettings settings; int start,stop,j; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { settings.Location=i; error=Phone->GetChatSettings(&s,&settings); Print_Error(error); printmsg("%i. ",i); if (settings.Name[0]==0 && settings.Name[1]==0) { printmsg("Set %i",i); } else { printmsg("%s",DecodeUnicodeConsole(settings.Name)); } if (settings.Active) printmsg(" (active)"); // if (settings.ReadOnly) printmsg("\nRead only : yes"); printmsg("\n"); printmsg("Homepage : \"%s\"\n",DecodeUnicodeConsole(settings.HomePage)); printmsg("User : \"%s\"\n",DecodeUnicodeConsole(settings.User)); printmsg("Password : \"%s\"\n",DecodeUnicodeConsole(settings.Password)); printmsg("\n"); for (j=0;j<settings.Connection.Number;j++) { if (settings.Connection.Settings[j].Title[0]==0 && settings.Connection.Settings[j].Title[1]==0) { printmsg("Connection set name : Set %i\n",i); } else { printmsg("Connection set name : %s\n",DecodeUnicodeConsole(settings.Connection.Settings[j].Title)); } DisplayConnectionSettings(&settings.Connection,j); printf("\n"); } } GSM_Terminate(); } static void GetWAPMMSSettings(int argc, char *argv[]) { GSM_MultiWAPSettings settings; int start,stop,j; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { settings.Location=i; if (mystrncasecmp(argv[1],"--getwapsettings",0)) { error=Phone->GetWAPSettings(&s,&settings); } else { error=Phone->GetMMSSettings(&s,&settings); } Print_Error(error); for (j=0;j<settings.Number;j++) { printmsg("%i. ",i); if (settings.Settings[j].Title[0]==0 && settings.Settings[j].Title[1]==0) { printmsg("Set %i",i); } else { printmsg("%s",DecodeUnicodeConsole(settings.Settings[j].Title)); } if (settings.Active) printmsg(" (active)"); if (settings.ReadOnly) printmsg("\nRead only : yes"); printmsg("\nHomepage : \"%s\"\n",DecodeUnicodeConsole(settings.Settings[j].HomePage)); DisplayConnectionSettings(&settings,j); printf("\n"); } } GSM_Terminate(); } #ifdef GSM_ENABLE_BACKUP static void BackupSMS(int argc, char *argv[]) { GSM_SMS_Backup Backup; GSM_MultiSMSMessage sms; GSM_SMSFolders folders; bool BackupFromFolder[GSM_MAX_SMS_FOLDERS]; - bool start = true; + bool start = true; bool DeleteAfter; - int j, smsnum; + int j, smsnum = 0; char buffer[200]; - /* We ignore return code, because (when file doesn't exist) we - * will create new later - */ - GSM_ReadSMSBackupFile(argv[2], &Backup); - smsnum = 0; - while (Backup.SMS[smsnum]!=NULL) smsnum++; - GSM_Init(true); error=Phone->GetSMSFolders(&s, &folders); Print_Error(error); DeleteAfter=answer_yes("Delete each sms after backup"); for (j=0;j<folders.Number;j++) { BackupFromFolder[j] = false; sprintf(buffer,"Backup sms from folder \"%s\"",DecodeUnicodeConsole(folders.Folder[j].Name)); + if (folders.Folder[j].Memory == MEM_SM) strcat(buffer," (SIM)"); if (answer_yes(buffer)) BackupFromFolder[j] = true; } while (error == ERR_NONE) { sms.SMS[0].Folder=0x00; error=Phone->GetNextSMS(&s, &sms, start); switch (error) { case ERR_EMPTY: break; default: Print_Error(error); for (j=0;j<sms.Number;j++) { if (BackupFromFolder[sms.SMS[j].Folder-1]) { switch (sms.SMS[j].PDU) { case SMS_Status_Report: break; case SMS_Submit: case SMS_Deliver: if (sms.SMS[j].Length == 0) break; if (smsnum < GSM_BACKUP_MAX_SMS) { Backup.SMS[smsnum] = malloc(sizeof(GSM_SMSMessage)); if (Backup.SMS[smsnum] == NULL) Print_Error(ERR_MOREMEMORY); Backup.SMS[smsnum+1] = NULL; } else { printmsg(" Increase %s\n" , "GSM_BACKUP_MAX_SMS"); GSM_Terminate(); exit(-1); } *Backup.SMS[smsnum] = sms.SMS[j]; smsnum++; break; } } } } start=false; } - error = GSM_SaveSMSBackupFile(argv[2],&Backup); + error = GSM_AddSMSBackupFile(argv[2],&Backup); Print_Error(error); if (DeleteAfter) { for (j=0;j<smsnum;j++) { Backup.SMS[j]->Folder = 0; error=Phone->DeleteSMS(&s, Backup.SMS[j]); Print_Error(error); printmsgerr("%cDeleting: %i percent",13,(j+1)*100/smsnum); } } GSM_Terminate(); } static void AddSMS(int argc, char *argv[]) { GSM_MultiSMSMessage SMS; GSM_SMS_Backup Backup; int smsnum = 0; int folder; folder = atoi(argv[2]); error = GSM_ReadSMSBackupFile(argv[3], &Backup); Print_Error(error); GSM_Init(true); while (Backup.SMS[smsnum] != NULL) { Backup.SMS[smsnum]->Folder = folder; Backup.SMS[smsnum]->SMSC.Location = 1; SMS.Number = 1; SMS.SMS[0] = *Backup.SMS[smsnum]; displaymultismsinfo(SMS,false,false); if (answer_yes("Restore sms")) { error=Phone->AddSMS(&s, Backup.SMS[smsnum]); Print_Error(error); } smsnum++; } GSM_Terminate(); } static void RestoreSMS(int argc, char *argv[]) { GSM_MultiSMSMessage SMS; GSM_SMS_Backup Backup; GSM_SMSFolders folders; int smsnum = 0; char buffer[200]; + bool restore8bit,doit; error=GSM_ReadSMSBackupFile(argv[2], &Backup); Print_Error(error); + sprintf(buffer,"Do you want to restore binary SMS"); + restore8bit = answer_yes(buffer); + GSM_Init(true); error=Phone->GetSMSFolders(&s, &folders); Print_Error(error); while (Backup.SMS[smsnum] != NULL) { - SMS.Number = 1; - memcpy(&SMS.SMS[0],Backup.SMS[smsnum],sizeof(GSM_SMSMessage)); - displaymultismsinfo(SMS,false,false); - sprintf(buffer,"Restore sms to folder \"%s\"",DecodeUnicodeConsole(folders.Folder[Backup.SMS[smsnum]->Folder-1].Name)); - if (answer_yes(buffer)) { - error=Phone->AddSMS(&s, Backup.SMS[smsnum]); - Print_Error(error); + doit = true; + if (!restore8bit && Backup.SMS[smsnum]->Coding == SMS_Coding_8bit) doit = false; + if (doit) { + SMS.Number = 1; + memcpy(&SMS.SMS[0],Backup.SMS[smsnum],sizeof(GSM_SMSMessage)); + displaymultismsinfo(SMS,false,false); + sprintf(buffer,"Restore %03i sms to folder \"%s\"",smsnum+1,DecodeUnicodeConsole(folders.Folder[Backup.SMS[smsnum]->Folder-1].Name)); + if (folders.Folder[Backup.SMS[smsnum]->Folder-1].Memory == MEM_SM) strcat(buffer," (SIM)"); + if (answer_yes(buffer)) { + smprintf(&s,"saving %i SMS\n",smsnum); + error=Phone->AddSMS(&s, Backup.SMS[smsnum]); + Print_Error(error); + } } smsnum++; } GSM_Terminate(); } #endif static void CopyBitmap(int argc, char *argv[]) { GSM_MultiBitmap Bitmap; int i; Bitmap.Bitmap[0].Type = GSM_None; error=GSM_ReadBitmapFile(argv[2],&Bitmap); Print_Error(error); if (argc==3) { for (i=0;i<Bitmap.Number;i++) { switch (Bitmap.Bitmap[i].Type) { case GSM_StartupLogo : printmsg("Startup logo"); break; case GSM_OperatorLogo: printmsg("Operator logo"); break; case GSM_PictureImage: printmsg("Picture Image"); break; case GSM_CallerGroupLogo : printmsg("Caller group logo"); break; default : break; } printmsg(", width %i, height %i\n",Bitmap.Bitmap[i].BitmapWidth,Bitmap.Bitmap[i].BitmapHeight); GSM_PrintBitmap(stdout,&Bitmap.Bitmap[i]); } } else { if (argc == 5) { for (i=0;i<Bitmap.Number;i++) { if (mystrncasecmp(argv[4],"PICTURE",0)) { Bitmap.Bitmap[i].Type = GSM_PictureImage; } else if (mystrncasecmp(argv[4],"STARTUP",0)) { Bitmap.Bitmap[i].Type = GSM_StartupLogo; } else if (mystrncasecmp(argv[4],"CALLER",0)) { Bitmap.Bitmap[i].Type = GSM_CallerGroupLogo; } else if (mystrncasecmp(argv[4],"OPERATOR",0)) { Bitmap.Bitmap[i].Type = GSM_OperatorLogo; } else { printmsg("What format of output file logo (\"%s\") ?\n",argv[4]); exit(-1); } } } error=GSM_SaveBitmapFile(argv[3],&Bitmap); Print_Error(error); } } static void NokiaComposer(int argc, char *argv[]) { GSM_Ringtone ringtone; bool started; int i,j; GSM_RingNote *Note; GSM_RingNoteDuration Duration; GSM_RingNoteDuration DefNoteDuration = 32; /* 32 = Duration_1_4 */ unsigned int DefNoteScale = Scale_880; ringtone.Format = 0; error=GSM_ReadRingtoneFile(argv[2],&ringtone); if (ringtone.Format != RING_NOTETONE) { printmsg("It can be RTTL ringtone only used with this option\n"); exit(-1); } started = false; j = 0; for (i=0;i<ringtone.NoteTone.NrCommands;i++) { if (ringtone.NoteTone.Commands[i].Type == RING_Note) { Note = &ringtone.NoteTone.Commands[i].Note; if (!started) { if (Note->Note != Note_Pause) { printmsg("Ringtone \"%s\" (tempo = %i Beats Per Minute)\n\n",DecodeUnicodeConsole(ringtone.Name),GSM_RTTLGetTempo(Note->Tempo)); started = true; } } if (started) j++; } } if (j>50) printmsg("WARNING: LENGTH=%i NOTES, BUT YOU WILL ENTER ONLY FIRST 50 TONES.",j); printmsg("\n\nThis ringtone in Nokia Composer in phone should look: "); started = false; for (i=0;i<ringtone.NoteTone.NrCommands;i++) { if (ringtone.NoteTone.Commands[i].Type == RING_Note) { Note = &ringtone.NoteTone.Commands[i].Note; if (!started) { if (Note->Note != Note_Pause) started = true; } if (started) { switch (Note->Duration) { case Duration_Full: printmsg("1"); break; case Duration_1_2 : printmsg("2"); break; case Duration_1_4 : printmsg("4"); break; case Duration_1_8 : printmsg("8"); break; case Duration_1_16: printmsg("16");break; case Duration_1_32: printmsg("32");break; } if (Note->DurationSpec == DottedNote) printmsg("."); switch (Note->Note) { case Note_C : printmsg("c"); break; case Note_Cis : printmsg("#c"); break; case Note_D :printmsg("d"); break; case Note_Dis : printmsg("#d"); break; case Note_E : printmsg("e"); break; case Note_F : printmsg("f"); break; case Note_Fis : printmsg("#f"); break; case Note_G : printmsg("g"); break; case Note_Gis : printmsg("#g"); break; case Note_A : printmsg("a"); break; case Note_Ais : printmsg("#a"); break; case Note_H : printmsg("h"); break; case Note_Pause : printmsg("-"); break; } if (Note->Note != Note_Pause) printmsg("%i",Note->Scale - 4); printmsg(" "); } } } printmsg("\n\nTo enter it please press: "); started = false; for (i=0;i<ringtone.NoteTone.NrCommands;i++) { if (ringtone.NoteTone.Commands[i].Type == RING_Note) { Note = &ringtone.NoteTone.Commands[i].Note; if (!started) { if (Note->Note != Note_Pause) started = true; } if (started) { switch (Note->Note) { case Note_C : case Note_Cis: printmsg("1");break; case Note_D : case Note_Dis: printmsg("2");break; case Note_E : printmsg("3");break; case Note_F : case Note_Fis: printmsg("4");break; case Note_G : case Note_Gis: printmsg("5");break; case Note_A : case Note_Ais: printmsg("6");break; case Note_H : printmsg("7");break; default : printmsg("0");break; } if (Note->DurationSpec == DottedNote) printmsg("(longer)"); switch (Note->Note) { case Note_Cis: case Note_Dis: case Note_Fis: case Note_Gis: case Note_Ais: printmsg("#"); break; default : break; } if (Note->Note != Note_Pause) { if ((unsigned int)Note->Scale != DefNoteScale) { while (DefNoteScale != (unsigned int)Note->Scale) { printmsg("*"); DefNoteScale++; if (DefNoteScale==Scale_7040) DefNoteScale = Scale_880; } } } Duration = 0; switch (Note->Duration) { case Duration_Full : Duration = 128; break; case Duration_1_2 : Duration = 64; break; case Duration_1_4 : Duration = 32; break; case Duration_1_8 : Duration = 16; break; case Duration_1_16 : Duration = 8; break; case Duration_1_32 : Duration = 4; break; default : dbgprintf("error\n");break; } if (Duration > DefNoteDuration) { while (DefNoteDuration != Duration) { printmsg("9"); DefNoteDuration = DefNoteDuration * 2; } } if (Duration < DefNoteDuration) { while (DefNoteDuration != Duration) { printmsg("8"); DefNoteDuration = DefNoteDuration / 2; } } printmsg(" "); } } } printf("\n"); } static void CopyRingtone(int argc, char *argv[]) { GSM_Ringtone ringtone, ringtone2; GSM_RingtoneFormat Format; ringtone.Format = 0; error=GSM_ReadRingtoneFile(argv[2],&ringtone); Print_Error(error); Format = ringtone.Format; if (argc == 5) { if (mystrncasecmp(argv[4],"RTTL",0)) { Format = RING_NOTETONE; } else if (mystrncasecmp(argv[4],"BINARY",0)) { Format = RING_NOKIABINARY; } else { printmsg("What format of output ringtone file (\"%s\") ?\n",argv[4]); exit(-1); } } error=GSM_RingtoneConvert(&ringtone2,&ringtone,Format); Print_Error(error); error=GSM_SaveRingtoneFile(argv[3],&ringtone2); Print_Error(error); } static void PressKeySequence(int argc, char *argv[]) { int i,Length; GSM_KeyCode KeyCode[500]; error = MakeKeySequence(argv[2], KeyCode, &Length); if (error == ERR_NOTSUPPORTED) { printmsg("Unknown key/function name: \"%c\"\n",argv[2][Length]); exit(-1); } GSM_Init(true); for (i=0;i<Length;i++) { error=Phone->PressKey(&s, KeyCode[i], true); Print_Error(error); error=Phone->PressKey(&s, KeyCode[i], false); Print_Error(error); } GSM_Terminate(); } static void GetAllCategories(int argc, char *argv[]) { GSM_Category Category; GSM_CategoryStatus Status; int j, count; if (mystrncasecmp(argv[2],"TODO",0)) { Category.Type = Category_ToDo; Status.Type = Category_ToDo; } else if (mystrncasecmp(argv[2],"PHONEBOOK",0)) { Category.Type = Category_Phonebook; Status.Type = Category_Phonebook; } else { printmsg("What type of categories do you want to get (\"%s\") ?\n",argv[2]); exit(-1); } GSM_Init(true); error=Phone->GetCategoryStatus(&s, &Status); Print_Error(error); for (count=0,j=1;count<Status.Used;j++) { Category.Location=j; error=Phone->GetCategory(&s, &Category); if (error != ERR_EMPTY) { printmsg("Location: %i\n",j); Print_Error(error); printmsg("Name : \"%s\"\n\n",DecodeUnicodeConsole(Category.Name)); count++; } } GSM_Terminate(); } static void GetCategory(int argc, char *argv[]) { GSM_Category Category; int start,stop,j; if (mystrncasecmp(argv[2],"TODO",0)) { Category.Type = Category_ToDo; } else if (mystrncasecmp(argv[2],"PHONEBOOK",0)) { Category.Type = Category_Phonebook; } else { printmsg("What type of categories do you want to get (\"%s\") ?\n",argv[2]); exit(-1); } GetStartStop(&start, &stop, 2, argc - 1, argv + 1); GSM_Init(true); for (j=start;j<=stop;j++) { printmsg("Location: %i\n",j); Category.Location=j; error=Phone->GetCategory(&s, &Category); if (error != ERR_EMPTY) Print_Error(error); if (error == ERR_EMPTY) { printmsg("Entry is empty\n\n"); } else { printmsg("Name : \"%s\"\n\n",DecodeUnicodeConsole(Category.Name)); } } GSM_Terminate(); } static void DeleteToDo(int argc, char *argv[]) { GSM_ToDoEntry ToDo; int i; int start,stop; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { ToDo.Location=i; printmsg("Location : %i\n",i); error=Phone->DeleteToDo(&s,&ToDo); if (error != ERR_EMPTY) Print_Error(error); if (error == ERR_EMPTY) { printmsg("Entry was empty\n"); } else { printmsg("Entry was deleted\n"); } printf("\n"); } GSM_Terminate(); } static void PrintToDo(GSM_ToDoEntry *ToDo) { int j; GSM_MemoryEntry entry; unsigned char *name; GSM_Category Category; printmsg("Location : %i\n",ToDo->Location); printmsg("Priority : "); switch (ToDo->Priority) { case GSM_Priority_Low : printmsg("Low\n"); break; case GSM_Priority_Medium : printmsg("Medium\n"); break; case GSM_Priority_High : printmsg("High\n"); break; default : printmsg("Unknown\n"); break; } for (j=0;j<ToDo->EntriesNum;j++) { switch (ToDo->Entries[j].EntryType) { case TODO_END_DATETIME: printmsg("DueTime : %s\n",OSDateTime(ToDo->Entries[j].Date,false)); break; case TODO_COMPLETED: printmsg("Completed : %s\n",ToDo->Entries[j].Number == 1 ? "Yes" : "No"); break; case TODO_ALARM_DATETIME: printmsg("Alarm : %s\n",OSDateTime(ToDo->Entries[j].Date,false)); break; case TODO_SILENT_ALARM_DATETIME: printmsg("Silent alarm : %s\n",OSDateTime(ToDo->Entries[j].Date,false)); break; case TODO_TEXT: printmsg("Text : \"%s\"\n",DecodeUnicodeConsole(ToDo->Entries[j].Text)); break; case TODO_PRIVATE: printmsg("Private : %s\n",ToDo->Entries[j].Number == 1 ? "Yes" : "No"); break; case TODO_CATEGORY: Category.Location = ToDo->Entries[j].Number; Category.Type = Category_ToDo; error=Phone->GetCategory(&s, &Category); if (error == ERR_NONE) { printmsg("Category : \"%s\" (%i)\n", DecodeUnicodeConsole(Category.Name), ToDo->Entries[j].Number); } else { printmsg("Category : %i\n", ToDo->Entries[j].Number); } break; case TODO_CONTACTID: entry.Location = ToDo->Entries[j].Number; entry.MemoryType = MEM_ME; error=Phone->GetMemory(&s, &entry); if (error == ERR_NONE) { name = GSM_PhonebookGetEntryName(&entry); if (name != NULL) { printmsg("Contact ID : \"%s\" (%d)\n", DecodeUnicodeConsole(name), ToDo->Entries[j].Number); } else { printmsg("Contact ID : %d\n",ToDo->Entries[j].Number); } } else { printmsg("Contact : %d\n",ToDo->Entries[j].Number); } break; case TODO_PHONE: printmsg("Phone : \"%s\"\n",DecodeUnicodeConsole(ToDo->Entries[j].Text)); break; } } printf("\n"); } static void ListToDoCategoryEntries(int Category) { GSM_ToDoEntry Entry; bool start = true; int j; while (!gshutdown) { error = Phone->GetNextToDo(&s, &Entry, start); if (error == ERR_EMPTY) break; Print_Error(error); for (j=0;j<Entry.EntriesNum;j++) { if (Entry.Entries[j].EntryType == TODO_CATEGORY && Entry.Entries[j].Number == (unsigned int)Category) PrintToDo(&Entry); } start = false; } } static void ListToDoCategory(int argc, char *argv[]) { GSM_Category Category; GSM_CategoryStatus Status; int j, count; unsigned char Text[(GSM_MAX_CATEGORY_NAME_LENGTH+1)*2]; int Length; bool Number = true;; GSM_Init(true); signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); Length = strlen(argv[2]); for (j = 0; j < Length; j++) { if (!isdigit(argv[2][j])) { Number = false; break; } } if (Number) { j = atoi(argv[2]); if (j > 0) { ListToDoCategoryEntries(j); } } else { if (Length > GSM_MAX_CATEGORY_NAME_LENGTH) { printmsg("Search text too long, truncating to %d chars!\n", GSM_MAX_CATEGORY_NAME_LENGTH); Length = GSM_MAX_CATEGORY_NAME_LENGTH; } EncodeUnicode(Text, argv[2], Length); Category.Type = Category_ToDo; Status.Type = Category_ToDo; if (Phone->GetCategoryStatus(&s, &Status) == ERR_NONE) { for (count=0,j=1;count<Status.Used;j++) { Category.Location=j; error=Phone->GetCategory(&s, &Category); if (error != ERR_EMPTY) { count++; if (mywstrstr(Category.Name, Text) != NULL) { ListToDoCategoryEntries(j); } } } } } GSM_Terminate(); } static void GetToDo(int argc, char *argv[]) { GSM_ToDoEntry ToDo; int i; int start,stop; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { ToDo.Location=i; error = Phone->GetToDo(&s,&ToDo); if (error == ERR_EMPTY) continue; Print_Error(error); PrintToDo(&ToDo); } GSM_Terminate(); } static void GetAllToDo(int argc, char *argv[]) { GSM_ToDoEntry ToDo; bool start = true; signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); GSM_Init(true); while (!gshutdown) { error = Phone->GetNextToDo(&s, &ToDo, start); if (error == ERR_EMPTY) break; Print_Error(error); PrintToDo(&ToDo); start = false; } GSM_Terminate(); } static void GetAllNotes(int argc, char *argv[]) { GSM_NoteEntry Note; bool start = true; signal(SIGINT, interrupt); printmsgerr("Press Ctrl+C to break...\n"); GSM_Init(true); while (!gshutdown) { error = Phone->GetNextNote(&s, &Note, start); if (error == ERR_EMPTY) break; Print_Error(error); printmsg("Text : \"%s\"\n",DecodeUnicodeConsole(Note.Text)); printf("\n"); start = false; } GSM_Terminate(); } static void GetSecurityStatus(int argc, char *argv[]) { GSM_Init(true); PrintSecurityStatus(); GSM_Terminate(); } static void EnterSecurityCode(int argc, char *argv[]) { GSM_SecurityCode Code; if (mystrncasecmp(argv[2],"PIN",0)) { Code.Type = SEC_Pin; } else if (mystrncasecmp(argv[2],"PUK",0)) { Code.Type = SEC_Puk; } else if (mystrncasecmp(argv[2],"PIN2",0)) { Code.Type = SEC_Pin2; } else if (mystrncasecmp(argv[2],"PUK2",0)) { Code.Type = SEC_Puk2; } else { printmsg("What security code (\"%s\") ?\n",argv[2]); exit(-1); } strcpy(Code.Code,argv[3]); GSM_Init(true); error=Phone->EnterSecurityCode(&s,Code); Print_Error(error); GSM_Terminate(); } static void GetProfile(int argc, char *argv[]) { GSM_Profile Profile; int start,stop,j,k; GSM_Bitmap caller[5]; bool callerinit[5],special; - GSM_AllRingtonesInfo Info; + GSM_AllRingtonesInfo Info = {0, NULL}; GetStartStop(&start, &stop, 2, argc, argv); for (i=0;i<5;i++) callerinit[i] = false; GSM_Init(true); error=Phone->GetRingtonesInfo(&s,&Info); if (error != ERR_NONE) Info.Number = 0; for (i=start;i<=stop;i++) { Profile.Location=i; error=Phone->GetProfile(&s,&Profile); + if (error != ERR_NONE && Info.Ringtone) free(Info.Ringtone); Print_Error(error); printmsg("%i. \"%s\"",i,DecodeUnicodeConsole(Profile.Name)); if (Profile.Active) printmsg(" (active)"); if (Profile.DefaultName) printmsg(" (default name)"); if (Profile.HeadSetProfile) printmsg(" (HeadSet profile)"); if (Profile.CarKitProfile) printmsg(" (CarKit profile)"); printf("\n"); for (j=0;j<Profile.FeaturesNumber;j++) { special = false; switch (Profile.FeatureID[j]) { case Profile_MessageToneID: case Profile_RingtoneID: special = true; if (Profile.FeatureID[j] == Profile_RingtoneID) { printmsg("Ringtone ID : "); } else { printmsg("Message alert tone ID : "); } if (UnicodeLength(GSM_GetRingtoneName(&Info,Profile.FeatureValue[j]))!=0) { printmsg("\"%s\"\n",DecodeUnicodeConsole(GSM_GetRingtoneName(&Info,Profile.FeatureValue[j]))); } else { printmsg("%i\n",Profile.FeatureValue[j]); } break; case Profile_CallerGroups: special = true; printmsg("Call alert for :"); for (k=0;k<5;k++) { if (Profile.CallerGroups[k]) { if (!callerinit[k]) { caller[k].Type = GSM_CallerGroupLogo; caller[k].Location = k + 1; error=Phone->GetBitmap(&s,&caller[k]); if (error == ERR_SECURITYERROR) { NOKIA_GetDefaultCallerGroupName(&s,&caller[k]); } else { Print_Error(error); } callerinit[k] = true; } printmsg(" \"%s\"",DecodeUnicodeConsole(caller[k].Text)); } } printf("\n"); break; case Profile_ScreenSaverNumber: special = true; printmsg("Screen saver number : "); printmsg("%i\n",Profile.FeatureValue[j]); break; case Profile_CallAlert : printmsg("Incoming call alert : "); break; case Profile_RingtoneVolume : printmsg("Ringtone volume : "); break; case Profile_Vibration : printmsg("Vibrating alert : "); break; case Profile_MessageTone : printmsg("Message alert tone : "); break; case Profile_KeypadTone : printmsg("Keypad tones : "); break; case Profile_WarningTone : printmsg("Warning (games) tones : "); break; case Profile_ScreenSaver : printmsg("Screen saver : "); break; case Profile_ScreenSaverTime : printmsg("Screen saver timeout : "); break; case Profile_AutoAnswer : printmsg("Automatic answer : "); break; case Profile_Lights : printmsg("Lights : "); break; default: printmsg("Unknown\n"); special = true; } if (!special) { switch (Profile.FeatureValue[j]) { case PROFILE_VOLUME_LEVEL1 : case PROFILE_KEYPAD_LEVEL1 : printmsg("Level 1\n"); break; case PROFILE_VOLUME_LEVEL2 : case PROFILE_KEYPAD_LEVEL2 : printmsg("Level 2\n"); break; case PROFILE_VOLUME_LEVEL3 : case PROFILE_KEYPAD_LEVEL3 : printmsg("Level 3\n"); break; case PROFILE_VOLUME_LEVEL4 : printmsg("Level 4\n"); break; case PROFILE_VOLUME_LEVEL5 : printmsg("Level 5\n"); break; case PROFILE_MESSAGE_NOTONE : case PROFILE_AUTOANSWER_OFF : case PROFILE_LIGHTS_OFF : case PROFILE_SAVER_OFF : case PROFILE_WARNING_OFF : case PROFILE_CALLALERT_OFF : case PROFILE_VIBRATION_OFF : case PROFILE_KEYPAD_OFF : printmsg("Off\n"); break; case PROFILE_CALLALERT_RINGING : printmsg("Ringing\n"); break; case PROFILE_CALLALERT_BEEPONCE : case PROFILE_MESSAGE_BEEPONCE : printmsg("Beep once\n"); break; case PROFILE_CALLALERT_RINGONCE : printmsg("Ring once\n"); break; case PROFILE_CALLALERT_ASCENDING : printmsg("Ascending\n"); break; case PROFILE_CALLALERT_CALLERGROUPS : printmsg("Caller groups\n"); break; case PROFILE_MESSAGE_STANDARD : printmsg("Standard\n"); break; case PROFILE_MESSAGE_SPECIAL : printmsg("Special\n"); break; case PROFILE_MESSAGE_ASCENDING : printmsg("Ascending\n"); break; case PROFILE_MESSAGE_PERSONAL : printmsg("Personal\n"); break; case PROFILE_AUTOANSWER_ON : case PROFILE_WARNING_ON : case PROFILE_SAVER_ON : case PROFILE_VIBRATION_ON : printmsg("On\n"); break; case PROFILE_VIBRATION_FIRST : printmsg("Vibrate first\n"); break; case PROFILE_LIGHTS_AUTO : printmsg("Auto\n"); break; case PROFILE_SAVER_TIMEOUT_5SEC : printmsg("5 seconds\n"); break; case PROFILE_SAVER_TIMEOUT_20SEC : printmsg("20 seconds\n"); break; case PROFILE_SAVER_TIMEOUT_1MIN : printmsg("1 minute\n"); break; case PROFILE_SAVER_TIMEOUT_2MIN : printmsg("2 minutes\n"); break; case PROFILE_SAVER_TIMEOUT_5MIN : printmsg("5 minutes\n"); break; case PROFILE_SAVER_TIMEOUT_10MIN : printmsg("10 minutes\n"); break; default : printmsg("UNKNOWN\n"); } } } printf("\n"); } GSM_Terminate(); + + if (Info.Ringtone) free(Info.Ringtone); } static void GetSpeedDial(int argc, char *argv[]) { GSM_SpeedDial SpeedDial; GSM_MemoryEntry Phonebook; int start,stop,Name,Number,Group; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { SpeedDial.Location=i; error=Phone->GetSpeedDial(&s,&SpeedDial); printmsg("%i.",i); switch (error) { case ERR_EMPTY: printmsg(" speed dial not assigned\n"); break; default: Print_Error(error); Phonebook.Location = SpeedDial.MemoryLocation; Phonebook.MemoryType = SpeedDial.MemoryType; error=Phone->GetMemory(&s,&Phonebook); GSM_PhonebookFindDefaultNameNumberGroup(&Phonebook, &Name, &Number, &Group); if (Name != -1) printmsg(" Name \"%s\",",DecodeUnicodeConsole(Phonebook.Entries[Name].Text)); printmsg(" Number \"%s\"",DecodeUnicodeConsole(Phonebook.Entries[SpeedDial.MemoryNumberID-1].Text)); } printf("\n"); } GSM_Terminate(); } static void ResetPhoneSettings(int argc, char *argv[]) { GSM_ResetSettingsType Type; if (mystrncasecmp(argv[2],"PHONE",0)) { Type = GSM_RESET_PHONESETTINGS; } else if (mystrncasecmp(argv[2],"UIF",0)) { Type = GSM_RESET_USERINTERFACE; } else if (mystrncasecmp(argv[2],"ALL",0)) { Type = GSM_RESET_USERINTERFACE_PHONESETTINGS; } else if (mystrncasecmp(argv[2],"DEV",0)) { Type = GSM_RESET_DEVICE; } else if (mystrncasecmp(argv[2],"FACTORY",0)) { Type = GSM_RESET_FULLFACTORY; } else { printmsg("What type of reset phone settings (\"%s\") ?\n",argv[2]); exit(-1); } GSM_Init(true); error=Phone->ResetPhoneSettings(&s,Type); Print_Error(error); GSM_Terminate(); } #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4) static void NokiaSecurityCode(int argc, char *argv[]) { GSM_Init(true); #ifdef GSM_ENABLE_NOKIA_DCT3 DCT3GetSecurityCode(argc,argv); #endif #ifdef GSM_ENABLE_NOKIA_DCT4 // DCT4ResetSecurityCode(argc, argv); DCT4GetSecurityCode(argc,argv); #endif GSM_Terminate(); } static void NokiaSetPhoneMenus(int argc, char *argv[]) { GSM_Init(true); #ifdef GSM_ENABLE_NOKIA_DCT3 DCT3SetPhoneMenus (argc, argv); #endif #ifdef GSM_ENABLE_NOKIA_DCT4 DCT4SetPhoneMenus (argc, argv); #endif GSM_Terminate(); } static void NokiaSelfTests(int argc, char *argv[]) { GSM_Init(true); #ifdef GSM_ENABLE_NOKIA_DCT3 DCT3SelfTests(argc, argv); #endif #ifdef GSM_ENABLE_NOKIA_DCT4 DCT4SelfTests(argc, argv); #endif GSM_Terminate(); } #endif static void DeleteAllSMS(int argc, char *argv[]) { GSM_MultiSMSMessage sms; GSM_SMSFolders folders; int foldernum; bool start = true; GSM_Init(true); error=Phone->GetSMSFolders(&s, &folders); Print_Error(error); GetStartStop(&foldernum, NULL, 2, argc, argv); if (foldernum > folders.Number) { printmsg("Too high folder number (max. %i)\n",folders.Number); GSM_Terminate(); exit(-1); } printmsg("Deleting SMS from \"%s\" folder: ",DecodeUnicodeConsole(folders.Folder[foldernum-1].Name)); while (error == ERR_NONE) { sms.SMS[0].Folder=0x00; error=Phone->GetNextSMS(&s, &sms, start); switch (error) { case ERR_EMPTY: break; default: Print_Error(error); if (sms.SMS[0].Folder == foldernum) { sms.SMS[0].Folder=0x00; error=Phone->DeleteSMS(&s, &sms.SMS[0]); Print_Error(error); printmsg("*"); } } start=false; } printf("\n"); GSM_Terminate(); } static void SendDTMF(int argc, char *argv[]) { GSM_Init(true); error=Phone->SendDTMF(&s,argv[2]); Print_Error(error); GSM_Terminate(); } static void GetDisplayStatus(int argc, char *argv[]) { GSM_DisplayFeatures Features; int i; GSM_Init(true); error=Phone->GetDisplayStatus(&s,&Features); Print_Error(error); printmsg("Current display features :\n"); for (i=0;i<Features.Number;i++) { switch(Features.Feature[i]) { case GSM_CallActive : printmsg("Call active\n"); break; case GSM_UnreadSMS : printmsg("Unread SMS\n"); break; case GSM_VoiceCall : printmsg("Voice call\n"); break; case GSM_FaxCall : printmsg("Fax call\n"); break; case GSM_DataCall : printmsg("Data call\n"); break; case GSM_KeypadLocked : printmsg("Keypad locked\n"); break; case GSM_SMSMemoryFull : printmsg("SMS memory full\n"); } } GSM_Terminate(); } static void SetAutoNetworkLogin(int argc, char *argv[]) { GSM_Init(true); error=Phone->SetAutoNetworkLogin(&s); Print_Error(error); GSM_Terminate(); } #ifdef DEBUG static void MakeConvertTable(int argc, char *argv[]) { unsigned char InputBuffer[10000], Buffer[10000]; FILE *file; int size,i,j=0; file = fopen(argv[2], "rb"); if (file == NULL) Print_Error(ERR_CANTOPENFILE); size=fread(InputBuffer, 1, 10000-1, file); fclose(file); InputBuffer[size] = 0; InputBuffer[size+1] = 0; ReadUnicodeFile(Buffer,InputBuffer); for(i=0;i<((int)UnicodeLength(Buffer));i++) { j++; if (j==100) { printf("\"\\\n\""); j=0; } printf("\\x%02x\\x%02x",Buffer[i*2],Buffer[i*2+1]); } printf("\\x00\\x00"); } #endif static void ListNetworks(int argc, char *argv[]) { extern unsigned char *GSM_Networks[]; extern unsigned char *GSM_Countries[]; int i=0; char country[4]=""; if (argc>2) { while (GSM_Countries[i*2]!=NULL) { if (!strncmp(GSM_Countries[i*2+1],argv[2],strlen(argv[2]))) { strcpy(country,GSM_Countries[i*2]); printmsg("Networks for %s:\n\n",GSM_Countries[i*2+1]); break; } i++; } if (!*country) { printmsg("Unknown country name."); exit(-1); } } printmsg("Network Name\n"); i=0; while (GSM_Networks[i*2]!=NULL) { if (argc>2) { if (!strncmp(GSM_Networks[i*2],country,strlen(country))) { printmsg("%s %s\n", GSM_Networks[i*2], GSM_Networks[i*2+1]); } } else { printmsg("%s %s\n", GSM_Networks[i*2], GSM_Networks[i*2+1]); } i++; } } static void Version(int argc, char *argv[]) { // unsigned char buff[10]; // int len; printmsg("[Gammu version %s built %s %s",VERSION,__TIME__,__DATE__); if (strlen(GetCompiler()) != 0) printmsg(" in %s",GetCompiler()); printmsg("]\n\n"); #ifdef DEBUG printf("GSM_SMSMessage - %i\n",sizeof(GSM_SMSMessage)); printf("GSM_SMSC - %i\n",sizeof(GSM_SMSC)); printf("GSM_SMS_State - %i\n",sizeof(GSM_SMS_State)); printf("GSM_UDHHeader - %i\n",sizeof(GSM_UDHHeader)); printf("bool - %i\n",sizeof(bool)); printf("GSM_DateTime - %i\n",sizeof(GSM_DateTime)); printf("int - %i\n",sizeof(int)); printf("GSM_NetworkInfo - %i\n",sizeof(GSM_NetworkInfo)); #endif // len=DecodeBASE64("AXw", buff, 3); // DumpMessage(stdout, buff, len); } static void GetFMStation(int argc, char *argv[]) { GSM_FMStation Station; int start,stop; GetStartStop(&start, &stop, 2, argc, argv); GSM_Init(true); for (i=start;i<=stop;i++) { Station.Location=i; error=Phone->GetFMStation(&s,&Station); switch (error) { case ERR_EMPTY: printmsg("Entry number %i is empty\n",i); break; case ERR_NONE: printmsg("Entry number %i\nStation name : \"%s\"\nFrequency : %.1f MHz\n", i,DecodeUnicodeConsole(Station.StationName), Station.Frequency); break; default: Print_Error(error); } } GSM_Terminate(); } static void GetFileSystemStatus(int argc, char *argv[]) { GSM_FileSystemStatus Status; GSM_Init(true); error = Phone->GetFileSystemStatus(&s,&Status); if (error != ERR_NOTSUPPORTED && error != ERR_NOTIMPLEMENTED) { Print_Error(error); printmsg("\nFree memory: %i, total memory: %i\n",Status.Free,Status.Free+Status.Used); } GSM_Terminate(); } static void GetFileSystem(int argc, char *argv[]) { bool Start = true; GSM_File Files; int j; GSM_FileSystemStatus Status; char FolderName[256]; GSM_Init(true); while (1) { error = Phone->GetNextFileFolder(&s,&Files,Start); if (error == ERR_EMPTY) break; Print_Error(error); if (argc <= 2 || !mystrncasecmp(argv[2],"-flatall",0)) { if (strlen(Files.ID_FullName) < 5 && strlen(Files.ID_FullName) != 0) { printf("%5s.",Files.ID_FullName); } if (Files.Protected) { printf("P"); } else { printf(" "); } if (Files.ReadOnly) { printf("R"); } else { printf(" "); } if (Files.Hidden) { printf("H"); } else { printf(" "); } if (Files.System) { printf("S"); } else { printf(" "); } if (argc > 2 && mystrncasecmp(argv[2],"-flat",0)) { if (!Files.Folder) { if (mystrncasecmp(argv[2],"-flatall",0)) { if (!Files.ModifiedEmpty) { printf(" %30s",OSDateTime(Files.Modified,false)); } else printf(" %30c",0x20); printf(" %9i",Files.Used); printf(" "); } else printf("|-- "); } else printf("Folder "); } else { if (Files.Level != 1) { for (j=0;j<Files.Level-2;j++) printf(" | "); printf(" |-- "); } if (Files.Folder) printf("Folder "); } printf("\"%s\"",DecodeUnicodeConsole(Files.Name)); } else if (argc > 2 && mystrncasecmp(argv[2],"-flatall",0)) { /* format for a folder ID;Folder;FOLDER_NAME;[FOLDER_PARAMETERS] * format for a file ID;File;FOLDER_NAME;FILE_NAME;DATESTAMP;FILE_SIZE;[FILE_PARAMETERS] */ if (!Files.Folder) { printf("%s;File;",Files.ID_FullName); printf("\"%s\";",FolderName); printf("\"%s\";",DecodeUnicodeConsole(Files.Name)); if (!Files.ModifiedEmpty) { printf("\"%s\";",OSDateTime(Files.Modified,false)); } else printf("\"%c\";",0x20); printf("%i;",Files.Used); } else { printf("%s;Folder;",Files.ID_FullName); printf("\"%s\";",DecodeUnicodeConsole(Files.Name)); strcpy(FolderName,DecodeUnicodeConsole(Files.Name)); } if (Files.Protected) printf("P"); if (Files.ReadOnly) printf("R"); if (Files.Hidden) printf("H"); if (Files.System) printf("S"); } Start = false; } error = Phone->GetFileSystemStatus(&s,&Status); if (error != ERR_NOTSUPPORTED && error != ERR_NOTIMPLEMENTED) { Print_Error(error); printmsg("\nFree memory: %i, total memory: %i\n",Status.Free,Status.Free+Status.Used); } GSM_Terminate(); } static void GetOneFile(GSM_File *File, bool newtime, int i) { FILE *file; bool start; unsigned char buffer[5000]; struct utimbuf filedate; if (File->Buffer != NULL) { free(File->Buffer); File->Buffer = NULL; } File->Used = 0; start = true; error = ERR_NONE; while (error == ERR_NONE) { error = Phone->GetFilePart(&s,File); if (error == ERR_NONE || error == ERR_EMPTY || error == ERR_WRONGCRC) { if (start) { printmsg("Getting \"%s\": ", DecodeUnicodeConsole(File->Name)); start = false; } if (File->Folder) { free(File->Buffer); GSM_Terminate(); printmsg("it's folder. Please give only file names\n"); exit(-1); } printmsg("*"); if (error == ERR_EMPTY) break; if (error == ERR_WRONGCRC) { printmsg("WARNING: File checksum calculated by phone doesn't match with value calculated by Gammu. File damaged or error in Gammu\n"); break; } } Print_Error(error); } printf("\n"); if (File->Used != 0) { sprintf(buffer,"%s",DecodeUnicodeConsole(File->Name)); file = fopen(buffer,"wb"); if (file == NULL) { sprintf(buffer,"file%s",File->ID_FullName); file = fopen(buffer,"wb"); } if (file == NULL) { sprintf(buffer,"file%i",i); file = fopen(buffer,"wb"); } printmsg(" Saving to %s\n",buffer); if (!file) Print_Error(ERR_CANTOPENFILE); fwrite(File->Buffer,1,File->Used,file); fclose(file); if (!newtime && !File->ModifiedEmpty) { /* access time */ filedate.actime = Fill_Time_T(File->Modified, 8); /* modification time */ filedate.modtime = Fill_Time_T(File->Modified, 8); dbgprintf("Setting date of %s\n",buffer); utime(buffer,&filedate); } } } static void GetFiles(int argc, char *argv[]) { GSM_File File; int i; bool newtime = false; File.Buffer = NULL; GSM_Init(true); for (i=2;i<argc;i++) { if (mystrncasecmp(argv[i],"-newtime",0)) { newtime = true; continue; } strcpy(File.ID_FullName,argv[i]); GetOneFile(&File, newtime, i); } free(File.Buffer); GSM_Terminate(); } static void GetFileFolder(int argc, char *argv[]) { bool Start = true; GSM_File File; int level=0,allnum=0,num=0,filelevel=0; bool newtime = false, found; File.Buffer = NULL; GSM_Init(true); for (i=2;i<argc;i++) { if (mystrncasecmp(argv[i],"-newtime",0)) { newtime = true; continue; } allnum++; } while (allnum != num) { error = Phone->GetNextFileFolder(&s,&File,Start); if (error == ERR_EMPTY) break; Print_Error(error); if (level == 0) { /* We search for file or folder */ found = false; for (i=2;i<argc;i++) { if (mystrncasecmp(argv[i],"-newtime",0)) { continue; } if (!strcmp(File.ID_FullName,argv[i])) { found = true; if (File.Folder) { level = 1; filelevel = File.Level + 1; Start = false; } else { level = 2; } break; } } if (found && File.Folder) continue; } if (level == 1) { /* We have folder */ dbgprintf("%i %i\n",File.Level,filelevel); if (File.Level != filelevel) { level = 0; num++; } } if (level != 0 && !File.Folder) GetOneFile(&File, newtime,num); if (level == 2) { level = 0; num++; } Start = false; } free(File.Buffer); GSM_Terminate(); } static void AddFile(int argc, char *argv[]) { GSM_File File; int Pos = 0,i,nextlong; File.Buffer = NULL; strcpy(File.ID_FullName,argv[2]); error = GSM_ReadFile(argv[3], &File); Print_Error(error); EncodeUnicode(File.Name,argv[3],strlen(argv[3])); GSM_IdentifyFileFormat(&File); File.Protected = false; File.ReadOnly = false; File.Hidden = false; File.System = false; if (argc > 4) { nextlong = 0; for (i=4;i<argc;i++) { switch(nextlong) { case 0: if (mystrncasecmp(argv[i],"-type",0)) { nextlong = 1; continue; } if (mystrncasecmp(argv[i],"-protected",0)) { File.Protected = true; continue; } if (mystrncasecmp(argv[i],"-readonly",0)) { File.ReadOnly = true; continue; } if (mystrncasecmp(argv[i],"-hidden",0)) { File.Hidden = true; continue; } if (mystrncasecmp(argv[i],"-system",0)) { File.System = true; continue; } if (mystrncasecmp(argv[i],"-newtime",0)) { File.ModifiedEmpty = true; continue; } printmsg("Parameter \"%s\" unknown\n",argv[i]); exit(-1); case 1: if (mystrncasecmp(argv[i],"JAR",0)) { File.Type = GSM_File_Java_JAR; } else if (mystrncasecmp(argv[i],"JPG",0)) { File.Type = GSM_File_Image_JPG; } else if (mystrncasecmp(argv[i],"BMP",0)) { File.Type = GSM_File_Image_BMP; } else if (mystrncasecmp(argv[i],"WBMP",0)) { File.Type = GSM_File_Image_WBMP; } else if (mystrncasecmp(argv[i],"GIF",0)) { File.Type = GSM_File_Image_GIF; } else if (mystrncasecmp(argv[i],"PNG",0)) { File.Type = GSM_File_Image_PNG; } else if (mystrncasecmp(argv[i],"MIDI",0)) { File.Type = GSM_File_Sound_MIDI; } else if (mystrncasecmp(argv[i],"AMR",0)) { File.Type = GSM_File_Sound_AMR; } else if (mystrncasecmp(argv[i],"NRT",0)) { File.Type = GSM_File_Sound_NRT; } else if (mystrncasecmp(argv[i],"3GP",0)) { File.Type = GSM_File_Video_3GP; } else { printmsg("What file type (\"%s\") ?\n",argv[i]); exit(-1); } nextlong = 0; break; } } if (nextlong!=0) { printmsg("Parameter missed...\n"); exit(-1); } } GSM_Init(true); error = ERR_NONE; while (error == ERR_NONE) { error = Phone->AddFilePart(&s,&File,&Pos); if (error != ERR_EMPTY && error != ERR_WRONGCRC) Print_Error(error); printmsgerr("%cWriting: %i percent",13,Pos*100/File.Used); } printmsgerr("\n"); if (error == ERR_WRONGCRC) { printmsg("WARNING: File checksum calculated by phone doesn't match with value calculated by Gammu. File damaged or error in Gammu\n"); } free(File.Buffer); GSM_Terminate(); } static void AddFolder(int argc, char *argv[]) { GSM_File File; strcpy(File.ID_FullName,argv[2]); EncodeUnicode(File.Name,argv[3],strlen(argv[3])); File.ReadOnly = false; GSM_Init(true); error = Phone->AddFolder(&s,&File); Print_Error(error); GSM_Terminate(); } struct NokiaFolderInfo { char *model; char *parameter; char *folder; char *level; }; static struct NokiaFolderInfo Folder[] = { /* Language indepedent in DCT4 */ {"", "MMSUnreadInbox", "INBOX", "3"}, {"", "MMSReadInbox", "INBOX", "3"}, {"", "MMSOutbox", "OUTBOX", "3"}, {"", "MMSSent", "SENT", "3"}, {"", "MMSDrafts", "DRAFTS", "3"}, {"", "Application", "applications", "3"}, {"", "Game", "games", "3"}, /* Language depedent in DCT4 */ {"", "Gallery", "Pictures", "2"}, /* 3510 */ {"", "Gallery", "Graphics", "3"}, /* 3510i */ {"", "Gallery", "Images", "3"}, /* 6610 */ {"3510", "Gallery", "", "8"}, {"3510i","Gallery", "", "3"}, {"5100", "Gallery", "", "3"}, {"6220", "Gallery", "", "5"}, {"6610", "Gallery", "", "2"}, {"7210", "Gallery", "", "2"}, {"", "Tones", "Tones", "3"}, {"3510i","Tones", "", "4"}, {"5100", "Tones", "", "4"}, {"6220", "Tones", "", "6"}, {"6610", "Tones", "", "4"}, {"7210", "Tones", "", "4"}, /* Language indepedent in OBEX */ {"obex", "MMSUnreadInbox", "", "predefMessages\\predefINBOX" }, {"obex", "MMSReadInbox", "", "predefMessages\\predefINBOX" }, {"obex", "MMSOutbox", "", "predefMessages\\predefOUTBOX" }, {"obex", "MMSSent", "", "predefMessages\\predefSENT" }, {"obex", "MMSDrafts", "", "predefMessages\\predefDRAFTS" }, // {"obex", "Application, "", "predefjava\\predefapplications"}, // {"obex", "Game", "", "predefjava\\predefgames" }, {"obex", "Gallery", "", "predefgallery\\predefgraphics" }, {"obex", "Tones", "", "predefgallery\\predeftones" }, /* End of list */ {"", "", "", ""} }; static void NokiaAddFile(int argc, char *argv[]) { GSM_File File, Files; FILE *file; GSM_DateTime DT,DT2; time_t t_time1,t_time2; unsigned char buffer[10000],JAR[500],Vendor[500],Name[500],Version[500],FileID[400]; bool Start = true, Found = false, wasclr; bool ModEmpty = false; int i = 0, Pos, Size, Size2, nextlong; while (Folder[i].level[0] != 0) { if (mystrncasecmp(argv[2],Folder[i].parameter,0)) { Found = true; break; } i++; } if (!Found) { printmsg("What folder type (\"%s\") ?\n",argv[2]); exit(-1); } GSM_Init(true); if (s.ConnectionType == GCT_IRDAOBEX || s.ConnectionType == GCT_BLUEOBEX) { Found = false; i = 0; while (Folder[i].level[0] != 0) { if (!strcmp("obex",Folder[i].model) && mystrncasecmp(argv[2],Folder[i].parameter,0)) { strcpy(Files.ID_FullName,Folder[i].level); Found = true; break; } i++; } } else { printmsgerr("Searching for phone folder: "); while (1) { error = Phone->GetNextFileFolder(&s,&Files,Start); if (error == ERR_EMPTY) break; Print_Error(error); if (Files.Folder) { dbgprintf("folder %s level %i\n",DecodeUnicodeConsole(Files.Name),Files.Level); Found = false; i = 0; while (Folder[i].level[0] != 0) { EncodeUnicode(buffer,Folder[i].folder,strlen(Folder[i].folder)); dbgprintf("comparing \"%s\" \"%s\" \"%s\"\n",s.Phone.Data.ModelInfo->model,Files.ID_FullName,Folder[i].level); if (mystrncasecmp(argv[2],Folder[i].parameter,0) && mywstrncasecmp(Files.Name,buffer,0) && Files.Level == atoi(Folder[i].level)) { Found = true; break; } if (!strcmp(s.Phone.Data.ModelInfo->model,Folder[i].model) && mystrncasecmp(argv[2],Folder[i].parameter,0) && !strcmp(Files.ID_FullName,Folder[i].level)) { Found = true; break; } i++; } if (Found) break; } printmsgerr("*"); Start = false; } printmsgerr("\n"); } if (!Found) { printmsg("Folder not found. Probably function not supported !\n"); GSM_Terminate(); exit(-1); } File.Buffer = NULL; File.Protected = false; File.ReadOnly = false; File.Hidden = false; File.System = false; if (mystrncasecmp(argv[2],"Application",0) || mystrncasecmp(argv[2],"Game",0)) { sprintf(buffer,"%s.jad",argv[3]); file = fopen(buffer,"rb"); if (file == NULL) Print_Error(ERR_CANTOPENFILE); fclose(file); sprintf(buffer,"%s.jar",argv[3]); file = fopen(buffer,"rb"); if (file == NULL) Print_Error(ERR_CANTOPENFILE); fclose(file); /* reading jar file */ sprintf(buffer,"%s.jar",argv[3]); error = GSM_ReadFile(buffer, &File); Print_Error(error); Size2 = File.Used; /* reading jad file */ sprintf(buffer,"%s.jad",argv[3]); error = GSM_ReadFile(buffer, &File); Print_Error(error); /* Getting values from JAD file */ error = GSM_JADFindData(File, Vendor, Name, JAR, Version, &Size); if (error == ERR_FILENOTSUPPORTED) { if (Vendor[0] == 0x00) { printmsgerr("No vendor info in JAD file\n"); GSM_Terminate(); return; } if (Name[0] == 0x00) { printmsgerr("No name info in JAD file\n"); GSM_Terminate(); return; } if (JAR[0] == 0x00) { printmsgerr("No JAR URL info in JAD file\n"); GSM_Terminate(); return; } if (Size == -1) { printmsgerr("No JAR size info in JAD file\n"); GSM_Terminate(); return; } } if (Size != Size2) { printmsgerr("Declared JAR file size is different than real\n"); GSM_Terminate(); return; } printmsgerr("Adding \"%s\"",Name); if (Version[0] != 0x00) printmsgerr(" version %s",Version); printmsgerr(" created by %s\n",Vendor); /* Bostjan Muller 3200 RH-30 3.08 */ if (strstr(JAR,"http://") != NULL) { i = strlen(JAR)-1; while (JAR[i] != '/') i--; strcpy(buffer,JAR+i+1); strcpy(JAR,buffer); dbgprintf("New file name is \"%s\"\n",JAR); } /* Changing all #13 or #10 to #13#10 in JAD */ Pos = 0; wasclr = false; for (i=0;i<File.Used;i++) { switch (File.Buffer[i]) { case 0x0D: case 0x0A: if (!wasclr) { buffer[Pos++] = 0x0D; buffer[Pos++] = 0x0A; wasclr = true; } else wasclr = false; break; default: buffer[Pos++] = File.Buffer[i]; wasclr = false; } } File.Buffer = realloc(File.Buffer, Pos); File.Used = Pos; memcpy(File.Buffer,buffer,Pos); /* adding folder */ strcpy(buffer,Vendor); strcat(buffer,Name); EncodeUnicode(File.Name,buffer,strlen(buffer)); strcpy(File.ID_FullName,Files.ID_FullName); error = Phone->AddFolder(&s,&File); Print_Error(error); strcpy(FileID,File.ID_FullName); /* adding jad file */ strcpy(buffer,JAR); buffer[strlen(buffer) - 1] = 'd'; EncodeUnicode(File.Name,buffer,strlen(buffer)); File.Type = GSM_File_Other; File.ModifiedEmpty = true; error = ERR_NONE; Pos = 0; while (error == ERR_NONE) { error = Phone->AddFilePart(&s,&File,&Pos); if (error != ERR_EMPTY && error != ERR_WRONGCRC) Print_Error(error); printmsgerr("%cWriting JAD file: %i percent",13,Pos*100/File.Used); } printmsgerr("\n"); if (error == ERR_WRONGCRC) { printmsg("WARNING: File checksum calculated by phone doesn't match with value calculated by Gammu. File damaged or error in Gammu\n"); } if (argc > 4) { if (mystrncasecmp(argv[4],"-readonly",0)) File.ReadOnly = true; } /* reading jar file */ sprintf(buffer,"%s.jar",argv[3]); error = GSM_ReadFile(buffer, &File); Print_Error(error); /* adding jar file */ strcpy(File.ID_FullName,FileID); strcpy(buffer,JAR); EncodeUnicode(File.Name,buffer,strlen(buffer)); File.Type = GSM_File_Java_JAR; File.ModifiedEmpty = true; error = ERR_NONE; Pos = 0; while (error == ERR_NONE) { error = Phone->AddFilePart(&s,&File,&Pos); if (error != ERR_EMPTY && error != ERR_WRONGCRC) Print_Error(error); printmsgerr("%cWriting JAR file: %i percent",13,Pos*100/File.Used); } printmsgerr("\n"); if (error == ERR_WRONGCRC) { printmsg("WARNING: File checksum calculated by phone doesn't match with value calculated by Gammu. File damaged or error in Gammu\n"); } free(File.Buffer); GSM_Terminate(); return; } if (mystrncasecmp(argv[2],"Gallery",0) || mystrncasecmp(argv[2],"Tones",0)) { strcpy(buffer,argv[3]); if (argc > 4) { nextlong = 0; for (i=4;i<argc;i++) { switch(nextlong) { case 0: if (mystrncasecmp(argv[i],"-name",0)) { nextlong = 1; continue; } if (mystrncasecmp(argv[i],"-protected",0)) { File.Protected = true; continue; } if (mystrncasecmp(argv[i],"-readonly",0)) { File.ReadOnly = true; continue; } if (mystrncasecmp(argv[i],"-hidden",0)) { File.Hidden = true; continue; } if (mystrncasecmp(argv[i],"-system",0)) { File.System = true; continue; } if (mystrncasecmp(argv[i],"-newtime",0)) { ModEmpty = true; continue; } printmsg("Parameter \"%s\" unknown\n",argv[i]); exit(-1); case 1: strcpy(buffer,argv[i]); nextlong = 0; break; } } if (nextlong!=0) { printmsg("Parameter missed...\n"); exit(-1); } } } else { /* MMS things */ DT2.Year = 2001; DT2.Month = 12; DT2.Day = 31; DT2.Hour = 14; DT2.Minute = 00; DT2.Second = 00; t_time2 = Fill_Time_T(DT2,8); GSM_GetCurrentDateTime(&DT); t_time1 = Fill_Time_T(DT,8); sprintf(buffer,"%07X %07X ",(int)(t_time1-t_time2-40),(int)(t_time1-t_time2-40)); #ifdef DEVELOP sprintf(buffer,"2A947BD 2A947DB "); #endif /* 40 = inbox "multimedia message received" message */ /* 30 = outbox sending failed */ if (mystrncasecmp(argv[2],"MMSUnreadInbox",0)) strcat(buffer,"43 "); else if (mystrncasecmp(argv[2],"MMSReadInbox",0)) strcat(buffer,"50 "); else if (mystrncasecmp(argv[2],"MMSOutbox",0)) strcat(buffer,"10 "); else if (mystrncasecmp(argv[2],"MMSSent",0)) strcat(buffer,"20 "); else if (mystrncasecmp(argv[2],"MMSDrafts",0)) strcat(buffer,"61 "); if (argc > 4) { if (!mystrncasecmp(argv[2],"MMSOutbox",0) && !mystrncasecmp(argv[2],"MMSSent",0)) { sprintf(Name,"%s",argv[4]); strcat(buffer,Name); } if (argc > 5) { sprintf(Name,"%zd%s/TYPE=PLMN",strlen(argv[5])+10,argv[5]); strcat(buffer,Name); } } ModEmpty = true; } error = GSM_ReadFile(argv[3], &File); Print_Error(error); if (ModEmpty) File.ModifiedEmpty = true; strcpy(File.ID_FullName,Files.ID_FullName); EncodeUnicode(File.Name,buffer,strlen(buffer)); GSM_IdentifyFileFormat(&File); #ifdef DEVELOP if (mystrncasecmp(argv[2],"Gallery",0) || mystrncasecmp(argv[2],"Tones",0)) { } else { /* MMS things */ File.Type = GSM_File_MMS; } #endif dbgprintf("Adding file to filesystem now\n"); error = ERR_NONE; Pos = 0; while (error == ERR_NONE) { error = Phone->AddFilePart(&s,&File,&Pos); if (error != ERR_EMPTY && error != ERR_WRONGCRC) Print_Error(error); if (File.Used != 0) printmsgerr("%cWriting file: %i percent",13,Pos*100/File.Used); } printmsgerr("\n"); if (error == ERR_WRONGCRC) { printmsg("WARNING: File checksum calculated by phone doesn't match with value calculated by Gammu. File damaged or error in Gammu\n"); } free(File.Buffer); GSM_Terminate(); } static void DeleteFiles(int argc, char *argv[]) { int i; GSM_Init(true); for (i=2;i<argc;i++) { error = Phone->DeleteFile(&s,argv[i]); Print_Error(error); } GSM_Terminate(); } static void SaveMMSFile(int argc, char *argv[]) { FILE *file; unsigned char Buffer[50000],Buffer2[20][2010]; int i,nextlong = 0,len = 0; GSM_EncodeMultiPartMMSInfo Info; GSM_ClearMultiPartMMSInfo(&Info); for (i=3;i<argc;i++) { switch (nextlong) { case 0: if (mystrncasecmp(argv[i],"-subject",0)) { nextlong=1; continue; } if (mystrncasecmp(argv[i],"-text",0)) { nextlong=2; continue; } if (mystrncasecmp(argv[i],"-from",0)) { nextlong=3; continue; } if (mystrncasecmp(argv[i],"-to",0)) { nextlong=4; continue; } printmsg("Unknown parameter (\"%s\")\n",argv[i]); exit(-1); break; case 1: /* Subject */ EncodeUnicode(Info.Subject,argv[i],strlen(argv[i])); nextlong = 0; break; case 2: /* Text */ EncodeUnicode(Buffer2[Info.EntriesNum],argv[i],strlen(argv[i])); Info.Entries[Info.EntriesNum].ID = MMS_Text; Info.Entries[Info.EntriesNum].Buffer = Buffer2[Info.EntriesNum]; Info.EntriesNum++; nextlong = 0; break; case 3: /* From */ EncodeUnicode(Info.Source,argv[i],strlen(argv[i])); nextlong = 0; break; case 4: /* To */ EncodeUnicode(Info.Destination,argv[i],strlen(argv[i])); nextlong = 0; break; } } if (nextlong!=0) { printmsg("Parameter missed...\n"); exit(-1); } GSM_EncodeMMSFile(&Info,Buffer,&len); file = fopen(argv[2],"wb"); if (file == NULL) Print_Error(ERR_CANTOPENFILE); fwrite(Buffer,1,len,file); fclose(file); } static void CallDivert(int argc, char *argv[]) { GSM_MultiCallDivert cd; if (mystrncasecmp("get", argv[2],0)) {} else if (mystrncasecmp("set", argv[2],0)) {} else { printmsg("Unknown divert action (\"%s\")\n",argv[2]); exit(-1); } if (mystrncasecmp("all" , argv[3],0)) {cd.Request.DivertType = GSM_DIVERT_AllTypes ;} else if (mystrncasecmp("busy" , argv[3],0)) {cd.Request.DivertType = GSM_DIVERT_Busy ;} else if (mystrncasecmp("noans" , argv[3],0)) {cd.Request.DivertType = GSM_DIVERT_NoAnswer ;} else if (mystrncasecmp("outofreach", argv[3],0)) {cd.Request.DivertType = GSM_DIVERT_OutOfReach;} else { printmsg("Unknown divert type (\"%s\")\n",argv[3]); exit(-1); } if (mystrncasecmp("all" , argv[4],0)) {cd.Request.CallType = GSM_DIVERT_AllCalls ;} else if (mystrncasecmp("voice", argv[4],0)) {cd.Request.CallType = GSM_DIVERT_VoiceCalls;} else if (mystrncasecmp("fax" , argv[4],0)) {cd.Request.CallType = GSM_DIVERT_FaxCalls ;} else if (mystrncasecmp("data" , argv[4],0)) {cd.Request.CallType = GSM_DIVERT_DataCalls ;} else { printmsg("Unknown call type (\"%s\")\n",argv[4]); exit(-1); } GSM_Init(true); if (mystrncasecmp("get", argv[2],0)) { error = Phone->GetCallDivert(&s,&cd); Print_Error(error); printmsg("Query:\n Divert type: "); } else { cd.Request.Number[0] = 0; cd.Request.Number[1] = 0; if (argc > 5) EncodeUnicode(cd.Request.Number,argv[5],strlen(argv[5])); cd.Request.Timeout = 0; if (argc > 6) cd.Request.Timeout = atoi(argv[6]); error = Phone->SetCallDivert(&s,&cd); Print_Error(error); printmsg("Changed:\n Divert type: "); } switch (cd.Request.DivertType) { case GSM_DIVERT_Busy : printmsg("when busy"); break; case GSM_DIVERT_NoAnswer : printmsg("when not answered"); break; case GSM_DIVERT_OutOfReach: printmsg("when phone off or no coverage"); break; case GSM_DIVERT_AllTypes : printmsg("all types of diverts"); break; default : printmsg("unknown %i",cd.Request.DivertType); break; } printmsg("\n Calls type : "); switch (cd.Request.CallType) { case GSM_DIVERT_VoiceCalls: printmsg("voice"); break; case GSM_DIVERT_FaxCalls : printmsg("fax"); break; case GSM_DIVERT_DataCalls : printmsg("data"); break; case GSM_DIVERT_AllCalls : printmsg("data & fax & voice"); break; default : printmsg("unknown %i",cd.Request.CallType); break; } printmsg("\nResponse:"); for (i=0;i<cd.Response.EntriesNum;i++) { printmsg("\n Calls type : "); switch (cd.Response.Entries[i].CallType) { case GSM_DIVERT_VoiceCalls: printmsg("voice"); break; case GSM_DIVERT_FaxCalls : printmsg("fax"); break; case GSM_DIVERT_DataCalls : printmsg("data"); break; default : printmsg("unknown %i",cd.Response.Entries[i].CallType);break; } printf("\n"); printmsg(" Timeout : %i seconds\n",cd.Response.Entries[i].Timeout); printmsg(" Number : %s\n",DecodeUnicodeString(cd.Response.Entries[i].Number)); } printf("\n"); GSM_Terminate(); } static void CancelAllDiverts(int argc, char *argv[]) { GSM_Init(true); error = Phone->CancelAllDiverts(&s); Print_Error(error); GSM_Terminate(); } typedef struct { unsigned char Connection[50]; } OneConnectionInfo; typedef struct { unsigned char Device[50]; OneConnectionInfo Connections[4]; } OneDeviceInfo; int num; bool SearchOutput; void SearchPhoneThread(OneDeviceInfo *Info) { //LR #if 0 int j; GSM_Error error; GSM_StateMachine ss; j = 0; while(strlen(Info->Connections[j].Connection) != 0) { memcpy(&ss.di,&s.di,sizeof(Debug_Info)); ss.msg = s.msg; ss.ConfigNum = 1; ss.opened = false; ss.Config[0].UseGlobalDebugFile = s.Config[0].UseGlobalDebugFile; ss.Config[0].Localize = s.Config[0].Localize; ss.Config[0].Device = Info->Device; ss.Config[0].Connection = Info->Connections[j].Connection; ss.Config[0].SyncTime = "no"; ss.Config[0].DebugFile = s.Config[0].DebugFile; ss.Config[0].Model[0] = 0; strcpy(ss.Config[0].DebugLevel,s.Config[0].DebugLevel); ss.Config[0].LockDevice = "no"; ss.Config[0].StartInfo = "no"; error = GSM_InitConnection(&ss,1); if (SearchOutput) printf("Connection \"%s\" on device \"%s\"\n",Info->Connections[j].Connection,Info->Device); if (error == ERR_NONE) { error=ss.Phone.Functions->GetManufacturer(&ss); if (error == ERR_NONE) { error=ss.Phone.Functions->GetModel(&ss); if (error == ERR_NONE) { if (!SearchOutput) printf("Connection \"%s\" on device \"%s\"\n",Info->Connections[j].Connection,Info->Device); printmsg(" Manufacturer : %s\n", ss.Phone.Data.Manufacturer); printmsg(" Model : %s (%s)\n", ss.Phone.Data.ModelInfo->model, ss.Phone.Data.Model); } else { if (SearchOutput) printf(" %s\n",print_error(error,ss.di.df,ss.msg)); } } else { if (SearchOutput) printf(" %s\n",print_error(error,ss.di.df,ss.msg)); } } else { if (SearchOutput) printf(" %s\n",print_error(error,ss.di.df,ss.msg)); } if (error != ERR_DEVICEOPENERROR) { GSM_TerminateConnection(&ss); dbgprintf("Closing done\n"); } if (error == ERR_DEVICEOPENERROR) break; j++; } num--; #endif } #if defined(WIN32) || defined(HAVE_PTHREAD) #ifdef HAVE_PTHREAD pthread_t Thread[100]; #endif OneDeviceInfo SearchDevices[60]; void MakeSearchThread(int i) { num++; #ifdef HAVE_PTHREAD if (pthread_create(&Thread[i],NULL,(void *)SearchPhoneThread,&SearchDevices[i])!=0) { dbgprintf("Error creating thread\n"); } #else if (CreateThread((LPSECURITY_ATTRIBUTES)NULL,0, (LPTHREAD_START_ROUTINE)SearchPhoneThread,&SearchDevices[i], 0,NULL)==NULL) { dbgprintf("Error creating thread\n"); } #endif } static void SearchPhone(int argc, char *argv[]) { int i,dev = 0, dev2 = 0; SearchOutput = false; if (argc == 3 && mystrncasecmp(argv[2], "-debug",0)) SearchOutput = true; num = 0; #ifdef WIN32 # ifdef GSM_ENABLE_IRDADEVICE sprintf(SearchDevices[dev].Device,""); sprintf(SearchDevices[dev].Connections[0].Connection,"irdaphonet"); sprintf(SearchDevices[dev].Connections[1].Connection,"irdaat"); SearchDevices[dev].Connections[2].Connection[0] = 0; dev++; # endif # ifdef GSM_ENABLE_SERIALDEVICE dev2 = dev; for(i=0;i<20;i++) { sprintf(SearchDevices[dev2].Device,"com%i:",i+1); sprintf(SearchDevices[dev2].Connections[0].Connection,"fbusdlr3"); sprintf(SearchDevices[dev2].Connections[1].Connection,"fbus"); sprintf(SearchDevices[dev2].Connections[2].Connection,"at19200"); sprintf(SearchDevices[dev2].Connections[3].Connection,"mbus"); SearchDevices[dev2].Connections[4].Connection[0] = 0; dev2++; } # endif #endif #ifdef __linux__ # ifdef GSM_ENABLE_IRDADEVICE for(i=0;i<6;i++) { sprintf(SearchDevices[dev].Device,"/dev/ircomm%i",i); sprintf(SearchDevices[dev].Connections[0].Connection,"irdaphonet"); sprintf(SearchDevices[dev].Connections[1].Connection,"at19200"); SearchDevices[dev].Connections[2].Connection[0] = 0; dev++; } # endif # ifdef GSM_ENABLE_SERIALDEVICE dev2 = dev; for(i=0;i<10;i++) { sprintf(SearchDevices[dev2].Device,"/dev/ttyS%i",i); sprintf(SearchDevices[dev2].Connections[0].Connection,"fbusdlr3"); sprintf(SearchDevices[dev2].Connections[1].Connection,"fbus"); sprintf(SearchDevices[dev2].Connections[2].Connection,"at19200"); sprintf(SearchDevices[dev2].Connections[3].Connection,"mbus"); SearchDevices[dev2].Connections[4].Connection[0] = 0; dev2++; } for(i=0;i<8;i++) { sprintf(SearchDevices[dev2].Device,"/dev/ttyD00%i",i); sprintf(SearchDevices[dev2].Connections[0].Connection,"fbusdlr3"); sprintf(SearchDevices[dev2].Connections[1].Connection,"fbus"); sprintf(SearchDevices[dev2].Connections[2].Connection,"at19200"); sprintf(SearchDevices[dev2].Connections[3].Connection,"mbus"); SearchDevices[dev2].Connections[4].Connection[0] = 0; dev2++; } for(i=0;i<4;i++) { sprintf(SearchDevices[dev2].Device,"/dev/usb/tts/%i",i); sprintf(SearchDevices[dev2].Connections[0].Connection,"fbusdlr3"); sprintf(SearchDevices[dev2].Connections[1].Connection,"fbus"); sprintf(SearchDevices[dev2].Connections[2].Connection,"at19200"); sprintf(SearchDevices[dev2].Connections[3].Connection,"mbus"); SearchDevices[dev2].Connections[4].Connection[0] = 0; dev2++; } # endif #endif for(i=0;i<dev;i++) MakeSearchThread(i); while (num != 0) my_sleep(5); for(i=dev;i<dev2;i++) MakeSearchThread(i); while (num != 0) my_sleep(5); } #endif /*Support for threads */ static void NokiaGetADC(int argc, char *argv[]) { GSM_Init(true); #ifdef GSM_ENABLE_NOKIA_DCT3 DCT3GetADC(argc,argv); #endif #ifdef GSM_ENABLE_NOKIA_DCT4 DCT4GetADC(argc, argv); #endif GSM_Terminate(); } static void NokiaDisplayTest(int argc, char *argv[]) { GSM_Init(true); #ifdef GSM_ENABLE_NOKIA_DCT3 DCT3DisplayTest(argc,argv); #endif #ifdef GSM_ENABLE_NOKIA_DCT4 DCT4DisplayTest(argc, argv); #endif GSM_Terminate(); } static void NokiaGetT9(int argc, char *argv[]) { GSM_Init(true); #ifdef GSM_ENABLE_NOKIA_DCT3 DCT3GetT9(argc,argv); #endif #ifdef GSM_ENABLE_NOKIA_DCT4 DCT4GetT9(argc, argv); #endif GSM_Terminate(); } static void NokiaVibraTest(int argc, char *argv[]) { GSM_Init(true); #ifdef GSM_ENABLE_NOKIA_DCT3 DCT3VibraTest(argc,argv); #endif #ifdef GSM_ENABLE_NOKIA_DCT4 DCT4VibraTest(argc, argv); #endif GSM_Terminate(); } static GSM_Parameters Parameters[] = { {"--identify", 0, 0, Identify, {H_Info,0}, ""}, {"--version", 0, 0, Version, {H_Other,0}, ""}, {"--getdisplaystatus", 0, 0, GetDisplayStatus, {H_Info,0}, ""}, {"--monitor", 0, 1, Monitor, {H_Info,H_Network,H_Call,0}, "[times]"}, {"--setautonetworklogin", 0, 0, SetAutoNetworkLogin, {H_Network,0}, ""}, {"--listnetworks", 0, 1, ListNetworks, {H_Network,0}, "[country]"}, {"--getgprspoint", 1, 2, GetGPRSPoint, {H_Nokia,H_Network,0}, "start [stop]"}, {"--addfolder", 2, 2, AddFolder, {H_Filesystem,0}, "parentfolderID name"}, {"--getfilesystem", 0, 1, GetFileSystem, {H_Filesystem,0}, "[-flatall|-flat]"}, {"--getfilesystemstatus", 0, 0, GetFileSystemStatus, {H_Filesystem,0}, ""}, {"--getfiles", 1,40, GetFiles, {H_Filesystem,0}, "ID1, ID2, ..."}, {"--getfilefolder", 1,40, GetFileFolder, {H_Filesystem,0}, "ID1, ID2, ..."}, {"--addfile", 2, 6, AddFile, {H_Filesystem,0}, "folderID name [-type JAR|BMP|PNG|GIF|JPG|MIDI|WBMP|AMR|3GP|NRT][-readonly][-protected][-system][-hidden][-newtime]"}, {"--nokiaaddfile", 2, 5, NokiaAddFile, {H_Filesystem,H_Nokia,0}, "MMSUnreadInbox|MMSReadInbox|MMSOutbox|MMSDrafts|MMSSent file sender title"}, {"--nokiaaddfile", 2, 5, NokiaAddFile, {H_Filesystem,H_Nokia,0}, "Application|Game file [-readonly]"}, {"--nokiaaddfile", 2, 5, NokiaAddFile, {H_Filesystem,H_Nokia,0}, "Gallery|Tones file [-name name][-protected][-readonly][-system][-hidden][-newtime]"}, {"--deletefiles", 1,20, DeleteFiles, {H_Filesystem,0}, "fileID"}, {"--playringtone", 1, 1, PlayRingtone, {H_Ringtone,0}, "file"}, - {"--playsavedringtone", 1, 1, DCT4PlaySavedRingtone, {H_Ringtone,0}, ""}, + {"--playsavedringtone", 1, 1, DCT4PlaySavedRingtone, {H_Ringtone,0}, "number"}, {"--getdatetime", 0, 0, GetDateTime, {H_DateTime,0}, ""}, {"--setdatetime", 0, 0, SetDateTime, {H_DateTime,0}, ""}, {"--getalarm", 0, 0, GetAlarm, {H_DateTime,0}, ""}, {"--setalarm", 2, 2, SetAlarm, {H_DateTime,0}, "hour minute"}, {"--resetphonesettings", 1, 1, ResetPhoneSettings, {H_Settings,0}, "PHONE|DEV|UIF|ALL|FACTORY"}, {"--getmemory", 2, 4, GetMemory, {H_Memory,0}, "DC|MC|RC|ON|VM|SM|ME|FD start [stop [-nonempty]]"}, {"--getallmemory", 1, 2, GetAllMemory, {H_Memory,0}, "DC|MC|RC|ON|VM|SM|ME|FD"}, {"--searchmemory", 1, 1, SearchMemory, {H_Memory,0}, "text"}, {"--listmemorycategory", 1, 1, ListMemoryCategory, {H_Memory, H_Category,0}, "text|number"}, {"--getfmstation", 1, 2, GetFMStation, {H_FM,0}, "start [stop]"}, {"--getsmsc", 1, 2, GetSMSC, {H_SMS,0}, "start [stop]"}, {"--getsms", 2, 3, GetSMS, {H_SMS,0}, "folder start [stop]"}, {"--deletesms", 2, 3, DeleteSMS, {H_SMS,0}, "folder start [stop]"}, {"--deleteallsms", 1, 1, DeleteAllSMS, {H_SMS,0}, "folder"}, {"--getsmsfolders", 0, 0, GetSMSFolders, {H_SMS,0}, ""}, {"--getallsms", 0, 0, GetAllSMS, {H_SMS,0}, ""}, {"--geteachsms", 0, 0, GetEachSMS, {H_SMS,0}, ""}, #define SMS_TEXT_OPTIONS "[-inputunicode][-16bit][-flash][-len len][-autolen len][-unicode][-enablevoice][-disablevoice][-enablefax][-disablefax][-enableemail][-disableemail][-voidsms][-replacemessages ID][-replacefile file]" #define SMS_PICTURE_OPTIONS "[-text text][-unicode][-alcatelbmmi]" #define SMS_PROFILE_OPTIONS "[-name name][-bitmap bitmap][-ringtone ringtone]" #define SMS_EMS_OPTIONS "[-unicode][-16bit][-format lcrasbiut][-text text][-unicodefiletext file][-defsound ID][-defanimation ID][-tone10 file][-tone10long file][-tone12 file][-tone12long file][-toneSE file][-toneSElong file][-fixedbitmap file][-variablebitmap file][-variablebitmaplong file][-animation frames file1 ...][-protected number]" #define SMS_SMSTEMPLATE_OPTIONS "[-unicode][-text text][-unicodefiletext file][-defsound ID][-defanimation ID][-tone10 file][-tone10long file][-tone12 file][-tone12long file][-toneSE file][-toneSElong file][-variablebitmap file][-variablebitmaplong file][-animation frames file1 ...]" #define SMS_ANIMATION_OPTIONS "" #define SMS_OPERATOR_OPTIONS "[-netcode netcode][-biglogo]" #define SMS_SAVE_OPTIONS "[-folder id][-unread][-read][-unsent][-sent][-sender number]" #define SMS_SEND_OPTIONS "[-report][-validity HOUR|6HOURS|DAY|3DAYS|WEEK|MAX][-save [-folder number]]" #define SMS_COMMON_OPTIONS "[-smscset number][-smscnumber number][-reply][-maxsms num]" {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,0}, "TEXT " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_TEXT_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Ringtone,0}, "RINGTONE file " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "OPERATOR file " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_OPERATOR_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "CALLER file " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "PICTURE file " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_PICTURE_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "ANIMATION frames file1 file2... " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_ANIMATION_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_MMS,0}, "MMSINDICATOR URL Title Sender " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "WAPINDICATOR URL Title " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS}, #ifdef GSM_ENABLE_BACKUP {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "BOOKMARK file location " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "WAPSETTINGS file location DATA|GPRS " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_MMS,0}, "MMSSETTINGS file location " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Calendar,0}, "CALENDAR file location " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_ToDo,0}, "TODO file location " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Memory,0}, "VCARD10|VCARD21 file SM|ME location [-nokia]" SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS}, #endif {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,H_Settings,0}, "PROFILE " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_PROFILE_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,0}, "EMS " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_EMS_OPTIONS}, {"--savesms", 1,30, SendSaveDisplaySMS, {H_SMS,0}, "SMSTEMPLATE " SMS_SAVE_OPTIONS SMS_COMMON_OPTIONS SMS_SMSTEMPLATE_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,0}, "TEXT destination " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_TEXT_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Ringtone,0}, "RINGTONE destination file " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "OPERATOR destination file " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_OPERATOR_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "CALLER destination file " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "PICTURE destination file " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_PICTURE_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Logo,0}, "ANIMATION destination frames file1 file2... " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_ANIMATION_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_MMS,0}, "MMSINDICATOR destination URL Title Sender " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "WAPINDICATOR destination URL Title " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS}, #ifdef GSM_ENABLE_BACKUP {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "BOOKMARK destination file location " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_WAP,0}, "WAPSETTINGS destination file location DATA|GPRS " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_MMS,0}, "MMSSETTINGS destination file location " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Calendar,0}, "CALENDAR destination file location " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_ToDo,0}, "TODO destination file location " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Memory,0}, "VCARD10|VCARD21 destination file SM|ME location [-nokia]" SMS_SEND_OPTIONS SMS_COMMON_OPTIONS}, #endif {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Settings,0}, "PROFILE destination " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS ""SMS_PROFILE_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,0}, "EMS destination " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_EMS_OPTIONS}, {"--sendsms", 2,30, SendSaveDisplaySMS, {H_SMS,0}, "SMSTEMPLATE destination " SMS_SEND_OPTIONS SMS_COMMON_OPTIONS SMS_SMSTEMPLATE_OPTIONS}, {"--displaysms", 2,30, SendSaveDisplaySMS, {H_SMS,0}, "... (options like in sendsms)"}, {"--addsmsfolder", 1, 1, AddSMSFolder, {H_SMS,0}, "name"}, #ifdef HAVE_MYSQL_MYSQL_H {"--smsd", 2, 2, SMSDaemon, {H_SMS,H_Other,0}, "MYSQL configfile"}, #endif {"--smsd", 2, 2, SMSDaemon, {H_SMS,H_Other,0}, "FILES configfile"}, {"--sendsmsdsms", 2,30, SendSaveDisplaySMS, {H_SMS,H_Other,0}, "TEXT|WAPSETTINGS|... destination FILES|MYSQL configfile ... (options like in sendsms)"}, {"--getringtone", 1, 2, GetRingtone, {H_Ringtone,0}, "location [file]"}, {"--getphoneringtone", 1, 2, GetRingtone, {H_Ringtone,0}, "location [file]"}, {"--getringtoneslist", 0, 0, GetRingtonesList, {H_Ringtone,0}, ""}, {"--setringtone", 1, 6, SetRingtone, {H_Ringtone,0}, "file [-location location][-scale][-name name]"}, {"--nokiacomposer", 1, 1, NokiaComposer, {H_Ringtone,H_Nokia,0}, "file"}, {"--copyringtone", 2, 3, CopyRingtone, {H_Ringtone,0}, "source destination [RTTL|BINARY]"}, {"--getussd", 1, 1, GetUSSD, {H_Call,0}, "code"}, {"--dialvoice", 1, 2, DialVoice, {H_Call,0}, "number [show|hide]"}, {"--getspeeddial", 1, 2, GetSpeedDial, {H_Call,H_Memory,0}, "start [stop]"}, {"--cancelcall", 0, 1, CancelCall, {H_Call,0}, "[ID]"}, {"--answercall", 0, 1, AnswerCall, {H_Call,0}, "[ID]"}, {"--unholdcall", 1, 1, UnholdCall, {H_Call,0}, "ID"}, {"--holdcall", 1, 1, HoldCall, {H_Call,0}, "ID"}, {"--conferencecall", 1, 1, ConferenceCall, {H_Call,0}, "ID"}, {"--splitcall", 1, 1, SplitCall, {H_Call,0}, "ID"}, {"--switchcall", 0, 1, SwitchCall, {H_Call,0}, "[ID]"}, {"--transfercall", 0, 1, TransferCall, {H_Call,0}, "[ID]"}, {"--divert", 3, 5, CallDivert, {H_Call,0}, "get|set all|busy|noans|outofreach all|voice|fax|data [number timeout]"}, {"--canceldiverts", 0, 0, CancelAllDiverts, {H_Call,0}, ""}, {"--senddtmf", 1, 1, SendDTMF, {H_Call,0}, "sequence"}, {"--getcalendarsettings", 0, 0, GetCalendarSettings, {H_Calendar,H_Settings,0}, ""}, {"--getalltodo", 0, 0, GetAllToDo, {H_ToDo,0}, ""}, {"--listtodocategory", 1, 1, ListToDoCategory, {H_ToDo, H_Category,0}, "text|number"}, {"--gettodo", 1, 2, GetToDo, {H_ToDo,0}, "start [stop]"}, {"--deletetodo", 1, 2, DeleteToDo, {H_ToDo,0}, "start [stop]"}, {"--getallnotes", 0, 0, GetAllNotes, {H_Note,0}, ""}, {"--deletecalendar", 1, 2, DeleteCalendar, {H_Calendar,0}, "start [stop]"}, {"--getallcalendar", 0, 0, GetAllCalendar, {H_Calendar,0}, ""}, {"--getcalendar", 1, 2, GetCalendar, {H_Calendar,0}, "start [stop]"}, {"--getcategory", 2, 3, GetCategory, {H_Category,H_ToDo,H_Memory,0}, "TODO|PHONEBOOK start [stop]"}, {"--getallcategory", 1, 1, GetAllCategories, {H_Category,H_ToDo,H_Memory,0}, "TODO|PHONEBOOK"}, {"--reset", 1, 1, Reset, {H_Other,0}, "SOFT|HARD"}, {"--getprofile", 1, 2, GetProfile, {H_Settings,0}, "start [stop]"}, {"--getsecuritystatus", 0, 0, GetSecurityStatus, {H_Info,0}, ""}, {"--entersecuritycode", 2, 2, EnterSecurityCode, {H_Other,0}, "PIN|PUK|PIN2|PUK2 code"}, {"--deletewapbookmark", 1, 2, DeleteWAPBookmark, {H_WAP,0}, "start [stop]"}, {"--getwapbookmark", 1, 2, GetWAPBookmark, {H_WAP,0}, "start [stop]"}, {"--getwapsettings", 1, 2, GetWAPMMSSettings, {H_WAP,0}, "start [stop]"}, {"--getmmssettings", 1, 2, GetWAPMMSSettings, {H_MMS,0}, "start [stop]"}, {"--getsyncmlsettings", 1, 2, GetSyncMLSettings, {H_WAP,0}, "start [stop]"}, {"--getchatsettings", 1, 2, GetChatSettings, {H_WAP,0}, "start [stop]"}, {"--savemmsfile", 3, 15,SaveMMSFile, {H_MMS,0}, "file [-subject text][-text text]"}, {"--getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "STARTUP [file]"}, {"--getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "CALLER location [file]"}, {"--getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "OPERATOR [file]"}, {"--getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "PICTURE location [file]"}, {"--getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "TEXT"}, {"--getbitmap", 1, 3, GetBitmap, {H_Logo,0}, "DEALER"}, {"--setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "STARTUP file|1|2|3"}, {"--setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "COLOURSTARTUP [fileID]"}, {"--setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "WALLPAPER fileID"}, {"--setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "CALLER location [file]"}, {"--setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "OPERATOR [file [netcode]]"}, {"--setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "COLOUROPERATOR [fileID [netcode]]"}, {"--setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "PICTURE file location [text]"}, {"--setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "TEXT text"}, {"--setbitmap", 1, 4, SetBitmap, {H_Logo,0}, "DEALER text"}, {"--copybitmap", 1, 3, CopyBitmap, {H_Logo,0}, "inputfile [outputfile [OPERATOR|PICTURE|STARTUP|CALLER]]"}, {"--presskeysequence", 1, 1, PressKeySequence, {H_Other,0}, "mMnNpPuUdD+-123456789*0#gGrRwW"}, #if defined(WIN32) || defined(HAVE_PTHREAD) {"--searchphone", 0, 1, SearchPhone, {H_Other,0}, "[-debug]"}, #endif #ifdef GSM_ENABLE_BACKUP {"--savefile", 4, 5, SaveFile, {H_Backup,H_Calendar,0}, "CALENDAR target.vcs file location"}, {"--savefile", 4, 5, SaveFile, {H_Backup,H_ToDo,0}, "TODO target.vcs file location"}, {"--savefile", 4, 5, SaveFile, {H_Backup,H_Memory,0}, "VCARD10|VCARD21 target.vcf file SM|ME location"}, {"--savefile", 4, 5, SaveFile, {H_Backup,H_WAP,0}, "BOOKMARK target.url file location"}, {"--backup", 1, 2, Backup, {H_Backup,H_Memory,H_Calendar,H_ToDo,H_Category,H_Ringtone,H_WAP,H_FM,0}, "file [-yes]"}, {"--backupsms", 1, 1, BackupSMS, {H_Backup,H_SMS,0}, "file"}, {"--restore", 1, 1, Restore, {H_Backup,H_Memory,H_Calendar,H_ToDo,H_Category,H_Ringtone,H_WAP,H_FM,0}, "file"}, {"--addnew", 1, 1, AddNew, {H_Backup,H_Memory,H_Calendar,H_ToDo,H_Category,H_Ringtone,H_WAP,H_FM,0}, "file"}, {"--restoresms", 1, 1, RestoreSMS, {H_Backup,H_SMS,0}, "file"}, {"--addsms", 2, 2, AddSMS, {H_Backup,H_SMS,0}, "folder file"}, #endif {"--clearall", 0, 0, ClearAll, {H_Memory,H_Calendar,H_ToDo,H_Category,H_Ringtone,H_WAP,H_FM,0}, ""}, {"--networkinfo", 0, 0, NetworkInfo, {H_Network,0}, ""}, #ifdef GSM_ENABLE_AT {"--siemenssatnetmon", 0, 0, ATSIEMENSSATNetmon, {H_Siemens,H_Network,0}, ""}, {"--siemensnetmonact", 1, 1, ATSIEMENSActivateNetmon, {H_Siemens,H_Network,0}, "netmon_type (1-full, 2-simple)"}, {"--siemensnetmonitor", 1, 1, ATSIEMENSNetmonitor, {H_Siemens,H_Network,0}, "test"}, #endif #ifdef GSM_ENABLE_NOKIA6110 {"--nokiagetoperatorname", 0, 0, DCT3GetOperatorName, {H_Nokia,H_Network,0}, ""}, {"--nokiasetoperatorname", 0, 2, DCT3SetOperatorName, {H_Nokia,H_Network,0}, "[networkcode name]"}, {"--nokiadisplayoutput", 0, 0, DCT3DisplayOutput, {H_Nokia,0}, ""}, #endif #ifdef GSM_ENABLE_NOKIA_DCT3 {"--nokianetmonitor", 1, 1, DCT3netmonitor, {H_Nokia,H_Network,0}, "test"}, {"--nokianetmonitor36", 0, 0, DCT3ResetTest36, {H_Nokia,0}, ""}, {"--nokiadebug", 1, 2, DCT3SetDebug, {H_Nokia,H_Network,0}, "filename [[v11-22][,v33-44]...]"}, #endif #ifdef GSM_ENABLE_NOKIA_DCT4 {"--nokiasetvibralevel", 1, 1, DCT4SetVibraLevel, {H_Nokia,H_Other,0}, "level"}, {"--nokiagetvoicerecord", 1, 1, DCT4GetVoiceRecord, {H_Nokia,H_Other,0}, "location"}, #ifdef GSM_ENABLE_NOKIA6510 {"--nokiasetlights", 2, 2, DCT4SetLight, {H_Nokia,H_Tests,0}, "keypad|display|torch on|off"}, {"--nokiatuneradio", 0, 0, DCT4TuneRadio, {H_Nokia,H_FM,0}, ""}, #endif {"--nokiamakecamerashoot", 0, 0, DCT4MakeCameraShoot, {H_Nokia,H_Other,0}, ""}, {"--nokiagetscreendump", 0, 0, DCT4GetScreenDump, {H_Nokia,H_Other,0}, ""}, #endif #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4) {"--nokiavibratest", 0, 0, NokiaVibraTest, {H_Nokia,H_Tests,0}, ""}, {"--nokiagett9", 0, 0, NokiaGetT9, {H_Nokia,H_SMS,0}, ""}, {"--nokiadisplaytest", 1, 1, NokiaDisplayTest, {H_Nokia,H_Tests,0}, "number"}, {"--nokiagetadc", 0, 0, NokiaGetADC, {H_Nokia,H_Tests,0}, ""}, {"--nokiasecuritycode", 0, 0, NokiaSecurityCode, {H_Nokia,H_Info,0}, ""}, {"--nokiaselftests", 0, 0, NokiaSelfTests, {H_Nokia,H_Tests,0}, ""}, {"--nokiasetphonemenus", 0, 0, NokiaSetPhoneMenus, {H_Nokia,H_Other,0}, ""}, #endif #ifdef DEBUG {"--decodesniff", 2, 3, decodesniff, {H_Decode,0}, "MBUS2|IRDA file [phonemodel]"}, {"--decodebinarydump", 1, 2, decodebinarydump, {H_Decode,0}, "file [phonemodel]"}, {"--makeconverttable", 1, 1, MakeConvertTable, {H_Decode,0}, "file"}, #endif {"", 0, 0, NULL } }; static HelpCategoryDescriptions HelpDescriptions[] = { {H_Call, "call", "Calls",}, {H_SMS, "sms", "SMS and EMS"}, {H_Memory, "memory", "Memory (phonebooks and calls)"}, {H_Filesystem, "filesystem", "Filesystem"}, {H_Logo, "logo", "Logo and pictures"}, {H_Ringtone, "ringtone", "Ringtones"}, {H_Calendar, "calendar", "Calendar notes"}, {H_ToDo, "todo", "To do lists"}, {H_Note, "note", "Notes"}, {H_DateTime, "datetime", "Date, time and alarms"}, {H_Category, "category", "Categories"}, #ifdef GSM_ENABLE_BACKUP {H_Backup, "backup", "Backing up and restoring"}, #endif #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4) {H_Nokia, "nokia", "Nokia specific"}, #endif #ifdef GSM_ENABLE_AT {H_Siemens, "siemens", "Siemens specific"}, #endif {H_Network, "network", "Network"}, {H_WAP, "wap", "WAP settings and bookmarks"}, {H_MMS, "mms", "MMS and MMS settings"}, {H_Tests, "tests", "Phone tests"}, {H_FM, "fm", "FM radio"}, {H_Info, "info", "Phone information"}, {H_Settings, "settings", "Phone settings"}, #ifdef DEBUG {H_Decode, "decode", "Dumps decoding"}, #endif {H_Other, "other", "Functions that don't fit elsewhere"}, {0, NULL, NULL} }; void HelpHeader(void) { printmsg("[Gammu version %s built %s %s]\n\n",VERSION,__TIME__,__DATE__); } static void HelpGeneral(void) { int i=0; HelpHeader(); printmsg("Usage: gammu [confign] [nothing|text|textall|binary|errors] [options]\n\n"); printmsg("First parameter optionally specifies which config section to use (all are probed by default).\n"); printmsg("Second parameter optionally controls debug level, next one specifies actions.\n\n"); /* We might want to put here some most used commands */ printmsg("For more details, call help on specific topic (gammu --help topic). Topics are:\n\n"); while (HelpDescriptions[i].category != 0) { printf("%11s - %s\n", HelpDescriptions[i].option, HelpDescriptions[i].description); i++; } printf("\n"); } static void HelpSplit(int cols, int len, unsigned char *buff) { int l, len2, pos, split; bool in_opt,first=true; char *remain, spaces[50], buffer[500]; if (cols == 0) { printf(" %s\n", buff); } else { printf(" "); spaces[0] = 0; len2 = strlen(buff); if (len + len2 < cols) { printf("%s\n", buff); } else { for(l = 0; l < len; l++) strcat(spaces, " "); remain = buff; while (strlen(remain) > 0) { split = 0; pos = 0; in_opt = false; if (!first) printf(spaces); while (pos < cols - len && remain[pos] != 0) { if (in_opt && remain[pos] == ']') { in_opt = false; split = pos; } else if (remain[pos] == '[') { in_opt = true; } else if (!in_opt && remain[pos] == ' ') { split = pos - 1; } pos++; } /* Can not be split */ if (split == 0) { printf("%s\n", remain); remain += strlen(remain); } else { first = false; split++; strncpy(buffer, remain, split); buffer[split] = 0; printf("%s\n", buffer); remain += split; if (remain[0] == ' ') remain++; } } } } } static void Help(int argc, char *argv[]) { int i = 0, j = 0, k, cols; bool disp; #ifdef TIOCGWINSZ struct winsize w; #endif #if defined(WIN32) || defined(DJGPP) #else char *columns; #endif /* Just --help */ if (argc == 2) { HelpGeneral(); return; } if (!strcmp(argv[2],"all")) { HelpHeader(); } else { while (HelpDescriptions[i].category != 0) { if (mystrncasecmp(argv[2], HelpDescriptions[i].option,strlen(argv[2]))) break; i++; } if (HelpDescriptions[i].category == 0) { HelpGeneral(); printmsg("Unknown help topic specified!\n"); return; } HelpHeader(); printmsg("Gammu parameters, topic: %s\n\n", HelpDescriptions[i].description); } #if defined(WIN32) || defined(DJGPP) cols = 80; #else cols = 0; /* If stdout is a tty, we will wrap to columns it has */ if (isatty(1)) { #ifdef TIOCGWINSZ if (ioctl(2, TIOCGWINSZ, &w) == 0) { if (w.ws_col > 0) cols = w.ws_col; } #endif if (cols == 0) { columns = getenv("COLUMNS"); if (columns != NULL) { cols = atoi(columns); if (cols <= 0) cols = 0; } } if (cols == 0) { /* Fallback */ cols = 80; } } #endif while (Parameters[j].Function != NULL) { k = 0; disp = false; if (!strcmp(argv[2],"all")) { if (j==0) disp = true; if (j!=0) { if (strcmp(Parameters[j].help,Parameters[j-1].help)) { disp = true; } else { if (strcmp(Parameters[j].parameter,Parameters[j-1].parameter)) { disp = true; } } } } else { while (Parameters[j].help_cat[k] != 0) { if (Parameters[j].help_cat[k] == HelpDescriptions[i].category) { disp = true; break; } k++; } } if (disp) { printf("%s", Parameters[j].parameter); if (Parameters[j].help[0] == 0) { printf("\n"); } else { HelpSplit(cols - 1, strlen(Parameters[j].parameter) + 1, Parameters[j].help); } } j++; } } int main(int argc, char *argv[]) { int z = 0,start=0,i; int only_config = -1; #if !defined(WIN32) && !defined(DJGPP) && defined(LOCALE_PATH) char *locale, locale_file[201]; #endif char *cp; bool count_failed = false; s.opened = false; s.msg = NULL; s.ConfigNum = 0; setlocale(LC_ALL, ""); #ifdef DEBUG di.dl = DL_TEXTALL; di.df = stdout; #endif /* Any parameters? */ if (argc == 1) { HelpGeneral(); printmsg("Too few parameters!\n"); exit(1); } /* Help? */ if (strncmp(argv[1 + start], "--help", 6) == 0) { Help(argc - start, argv + start); exit(1); } /* Is first parameter numeric? If so treat it as config that should be loaded. */ if (isdigit(argv[1][0])) { only_config = atoi(argv[1]); if (only_config >= 0) start++; else only_config = -1; } cfg = GSM_FindGammuRC(); if (cfg == NULL) printmsg("Warning: No configuration file found!\n"); for (i = 0; i <= MAX_CONFIG_NUM; i++) { if (cfg!=NULL) { cp = INI_GetValue(cfg, "gammu", "gammucoding", false); if (cp) di.coding = cp; s.Config[i].Localize = INI_GetValue(cfg, "gammu", "gammuloc", false); if (s.Config[i].Localize) { s.msg=INI_ReadFile(s.Config[i].Localize, true); } else { #if !defined(WIN32) && !defined(DJGPP) && defined(LOCALE_PATH) locale = setlocale(LC_MESSAGES, NULL); if (locale != NULL) { snprintf(locale_file, 200, "%s/gammu_%c%c.txt", LOCALE_PATH, tolower(locale[0]), tolower(locale[1])); s.msg = INI_ReadFile(locale_file, true); } #endif } } /* Wanted user specific configuration? */ if (only_config != -1) { /* Here we get only in first for loop */ if (!GSM_ReadConfig(cfg, &s.Config[0], only_config)) break; } else { if (!GSM_ReadConfig(cfg, &s.Config[i], i) && i != 0) break; } s.ConfigNum++; /* We want to use only one file descriptor for global and state machine debug output */ s.Config[i].UseGlobalDebugFile = true; /* It makes no sense to open several debug logs... */ if (i != 0) { strcpy(s.Config[i].DebugLevel, s.Config[0].DebugLevel); free(s.Config[i].DebugFile); s.Config[i].DebugFile = strdup(s.Config[0].DebugFile); } else { /* Just for first config */ /* When user gave debug level on command line */ if (argc > 1 + start && GSM_SetDebugLevel(argv[1 + start], &di)) { /* Debug level from command line will be used with phone too */ strcpy(s.Config[i].DebugLevel,argv[1 + start]); start++; } else { /* Try to set debug level from config file */ GSM_SetDebugLevel(s.Config[i].DebugLevel, &di); } /* If user gave debug file in gammurc, we will use it */ error=GSM_SetDebugFile(s.Config[i].DebugFile, &di); Print_Error(error); } /* We wanted to read just user specified configuration. */ if (only_config != -1) {break;} } /* Do we have enough parameters? */ if (argc == 1 + start) { HelpGeneral(); printmsg("Too few parameters!\n"); exit(-2); } /* Check used version vs. compiled */ if (!mystrncasecmp(GetGammuVersion(),VERSION,0)) { printmsg("ERROR: version of installed libGammu.so (%s) is different to version of Gammu (%s)\n", GetGammuVersion(),VERSION); exit(-1); } /* Check parameters */ while (Parameters[z].Function != NULL) { if (mystrncasecmp(Parameters[z].parameter,argv[1+start], 0)) { if (argc-2-start >= Parameters[z].min_arg && argc-2-start <= Parameters[z].max_arg) { Parameters[z].Function(argc - start, argv + start); break; } else { count_failed = true; } } z++; } /* Tell user when we did nothing */ if (Parameters[z].Function == NULL) { HelpGeneral(); if (count_failed) { printmsg("Bad parameter count!\n"); } else { printmsg("Bad option!\n"); } } /* Close debug output if opened */ if (di.df!=stdout) fclose(di.df); exit(0); } /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/gammu/smsd/s_files.c b/gammu/emb/gammu/smsd/s_files.c index b791e58..e1c626f 100644 --- a/gammu/emb/gammu/smsd/s_files.c +++ b/gammu/emb/gammu/smsd/s_files.c @@ -1,360 +1,360 @@ /* (c) 2002-2004 by Joergen Thomsen */ #include "../../cfg/config.h" #include <string.h> #include <stdio.h> #include <errno.h> #include <time.h> #ifdef WIN32 # include <io.h> #endif #if defined HAVE_DIRENT_H && defined HAVE_SCANDIR && defined HAVE_ALPHASORT # include <dirent.h> #endif #include "../../common/misc/coding/coding.h" #include "../../common/service/backup/gsmback.h" #include "smsdcore.h" /* Save SMS from phone (called Inbox sms - it's in phone Inbox) somewhere */ static GSM_Error SMSDFiles_SaveInboxSMS(GSM_MultiSMSMessage sms, GSM_SMSDConfig *Config) { GSM_Error error = ERR_NONE; int i,j; unsigned char FileName[100], FullName[400], ext[4], buffer[64],buffer2[400]; bool done; FILE *file; #ifdef GSM_ENABLE_BACKUP GSM_SMS_Backup backup; #endif j = 0; done = false; for (i=0;i<sms.Number && !done;i++) { strcpy(ext, "txt"); if (sms.SMS[i].Coding == SMS_Coding_8bit) strcpy(ext, "bin"); DecodeUnicode(sms.SMS[i].Number,buffer2); /* we loop on yy for the first SMS assuming that if xxxx_yy_00.ext is absent, any xxxx_yy_01,02, must be garbage, that can be overwritten */ file = NULL; do { sprintf(FileName, "IN%02d%02d%02d_%02d%02d%02d_%02i_%s_%02i.%s", sms.SMS[i].DateTime.Year, sms.SMS[i].DateTime.Month, sms.SMS[i].DateTime.Day, sms.SMS[i].DateTime.Hour, sms.SMS[i].DateTime.Minute, sms.SMS[i].DateTime.Second, j, buffer2, i, ext); strcpy(FullName, Config->inboxpath); strcat(FullName, FileName); if (file) fclose(file); file = fopen(FullName, "r"); } while ((i == 0) && (file && (++j < 100))); if (file) { fclose(file); if (i == 0) { WriteSMSDLog("Cannot save %s. No available file names", FileName); return ERR_CANTOPENFILE; } } errno = 0; if ((sms.SMS[i].PDU == SMS_Status_Report) && mystrncasecmp(Config->deliveryreport, "log", 3)) { strcpy(buffer, DecodeUnicodeString(sms.SMS[i].Number)); WriteSMSDLog("Delivery report: %s to %s", DecodeUnicodeString(sms.SMS[i].Text), buffer); } else { #ifdef GSM_ENABLE_BACKUP if (mystrncasecmp(Config->inboxformat, "detail", 0)) { for (j=0;j<sms.Number;j++) backup.SMS[j] = &sms.SMS[j]; backup.SMS[sms.Number] = NULL; - error = GSM_SaveSMSBackupFile(FullName, &backup); + error = GSM_AddSMSBackupFile(FullName, &backup); done = true; } #endif if (!mystrncasecmp(Config->inboxformat, "detail", 0)) { file = fopen(FullName, "wb"); if (file) { switch (sms.SMS[i].Coding) { case SMS_Coding_Unicode: case SMS_Coding_Default: DecodeUnicode(sms.SMS[i].Text,buffer2); if (mystrncasecmp(Config->inboxformat, "unicode", 0)) { buffer[0] = 0xFE; buffer[1] = 0xFF; fwrite(buffer,1,2,file); fwrite(sms.SMS[i].Text,1,strlen(buffer2)*2,file); } else { fwrite(buffer2,1,strlen(buffer2),file); } break; case SMS_Coding_8bit: fwrite(sms.SMS[i].Text,1,sms.SMS[i].Length,file); } fclose(file); } else error = ERR_CANTOPENFILE; } if (error == ERR_NONE) { WriteSMSDLog("%s %s", (sms.SMS[i].PDU == SMS_Status_Report?"Delivery report":"Received"), FileName); } else { WriteSMSDLog("Cannot save %s (%i)", FileName, errno); return ERR_CANTOPENFILE; } } } return ERR_NONE; } /* Find one multi SMS to sending and return it (or return ERR_EMPTY) * There is also set ID for SMS * File extension convention: * OUTxxxxx.txt : normal text SMS * Options appended to the extension applying to this SMS only: * d: delivery report requested * f: flash SMS * b: WAP bookmark as name,URL * e.g. OUTG20040620_193810_123_+4512345678_xpq.txtdf * is a flash text SMS requesting delivery reports */ static GSM_Error SMSDFiles_FindOutboxSMS(GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, unsigned char *ID) { GSM_Error error = ERR_NOTSUPPORTED; GSM_MultiPartSMSInfo SMSInfo; GSM_WAPBookmark Bookmark; unsigned char FileName[100],FullName[400]; unsigned char Buffer[(GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS+1)*2]; unsigned char Buffer2[(GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS+1)*2]; FILE *File; int i, len, phlen; char *pos1, *pos2, *options; #if defined HAVE_DIRENT_H && defined HAVE_SCANDIR & defined HAVE_ALPHASORT struct dirent **namelist = NULL; int l, m ,n; strcpy(FullName, Config->outboxpath); FullName[strlen(Config->outboxpath)-1] = '\0'; n = scandir(FullName, &namelist, 0, alphasort); m = 0; while ((m < n) && ((*(namelist[m]->d_name) == '.') || // directory and UNIX hidden file !mystrncasecmp(namelist[m]->d_name,"out", 3) || // must start with 'out' ((strlen(namelist[m]->d_name) >= 4) && !mystrncasecmp(strrchr(namelist[m]->d_name, '.'),".txt",4) ) ) ) m++; if (m < n) strcpy(FileName,namelist[m]->d_name); for (l=0; l < n; l++) free(namelist[l]); free(namelist); namelist = NULL; if (m >= n) return ERR_EMPTY; error = ERR_NONE; #else #ifdef WIN32 struct _finddata_t c_file; long hFile; strcpy(FullName, Config->outboxpath); strcat(FullName, "OUT*.txt*"); if((hFile = _findfirst( FullName, &c_file )) == -1L ) { return ERR_EMPTY; } else { strcpy(FileName,c_file.name); } _findclose( hFile ); error = ERR_NONE; #endif #endif if (error != ERR_NONE) return error; options = strrchr(FileName, '.') + 4; strcpy(FullName, Config->outboxpath); strcat(FullName, FileName); File = fopen(FullName, "rb"); len = fread(Buffer, 1, sizeof(Buffer)-2, File); fclose(File); if ((len < 2) || (len >= 2 && ((Buffer[0] != 0xFF || Buffer[1] != 0xFE) && (Buffer[0] != 0xFE || Buffer[1] != 0xFF)))) { if (len > GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS) len = GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS; EncodeUnicode(Buffer2, Buffer, len); len = len*2; memmove(Buffer, Buffer2, len); } Buffer[len] = 0; Buffer[len+1] = 0; ReadUnicodeFile(Buffer2,Buffer); GSM_ClearMultiPartSMSInfo(&SMSInfo); sms->Number = 0; SMSInfo.ReplaceMessage = 0; SMSInfo.Entries[0].Buffer = Buffer2; SMSInfo.Class = -1; SMSInfo.EntriesNum = 1; Config->currdeliveryreport = -1; if (strchr(options, 'd')) Config->currdeliveryreport = 1; if (strchr(options, 'f')) SMSInfo.Class = 0; /* flash SMS */ if (mystrncasecmp(Config->transmitformat, "unicode", 0)) { SMSInfo.Entries[0].ID = SMS_ConcatenatedTextLong; SMSInfo.UnicodeCoding = true; } else if (mystrncasecmp(Config->transmitformat, "7bit", 0)) { SMSInfo.Entries[0].ID = SMS_ConcatenatedTextLong; SMSInfo.UnicodeCoding = false; } else { /* auto */ SMSInfo.Entries[0].ID = SMS_ConcatenatedAutoTextLong; } if (strchr(options, 'b')) { // WAP bookmark as title,URL SMSInfo.Entries[0].Buffer = NULL; SMSInfo.Entries[0].Bookmark = &Bookmark; SMSInfo.Entries[0].ID = SMS_NokiaWAPBookmarkLong; SMSInfo.Entries[0].Bookmark->Location = 0; pos2 = mywstrstr(Buffer2, "\0,"); if (pos2 == NULL) { pos2 = Buffer2; } else { *pos2 = '\0'; pos2++; *pos2 = '\0'; pos2++; // replace comma by zero } len = UnicodeLength(Buffer2); if (len > 50) len = 50; memmove(&SMSInfo.Entries[0].Bookmark->Title, Buffer2, len * 2); pos1 = &SMSInfo.Entries[0].Bookmark->Title[0] + len * 2; *pos1 = '\0'; pos1++; *pos1 = '\0'; len = UnicodeLength(pos2); if (len > 255) len = 255; memmove(&SMSInfo.Entries[0].Bookmark->Address, pos2, len * 2); pos1 = &SMSInfo.Entries[0].Bookmark->Address[0] + len * 2; *pos1 = '\0'; pos1++; *pos1 = '\0'; } GSM_EncodeMultiPartSMS(&SMSInfo,sms); pos1 = FileName; strcpy(ID,FileName); for (i = 1; i <= 3 && pos1 != NULL ; i++) pos1 = strchr(++pos1, '_'); if (pos1 != NULL) { /* OUT<priority><date>_<time>_<serialno>_<phone number>_<anything>.txt */ pos2 = strchr(++pos1, '_'); if (pos2 != NULL) { phlen = strlen(pos1) - strlen(pos2); } else { /* something wrong */ return ERR_UNKNOWN; } } else if (i == 2) { /* OUTxxxxxxx.txt or OUTxxxxxxx */ pos1 = &FileName[3]; pos2 = strchr(pos1, '.'); if (pos2 == NULL) { phlen = strlen(pos1); } else { phlen = strlen(pos1) - strlen(pos2); } } else if (i == 4) { /* OUT<priority>_<phone number>_<serialno>.txt */ pos1 = strchr(FileName, '_'); pos2 = strchr(++pos1, '_'); phlen = strlen(pos1) - strlen(pos2); } else { /* something wrong */ return ERR_UNKNOWN; } for (len=0;len<sms->Number;len++) { EncodeUnicode(sms->SMS[len].Number, pos1, phlen); } #ifdef DEBUG if (sms->Number != 0) { DecodeUnicode(sms->SMS[0].Number,Buffer); dbgprintf("Found %i sms to \"%s\" with text \"%s\" cod %i lgt %i udh: t %i l %i dlr: %i fls: %i", sms->Number, Buffer, DecodeUnicodeString(sms->SMS[0].Text), sms->SMS[0].Coding, sms->SMS[0].Length, sms->SMS[0].UDH.Type, sms->SMS[0].UDH.Length, Config->currdeliveryreport, SMSInfo.Class); } else dbgprintf("error: SMS-count = 0"); #endif return ERR_NONE; } /* After sending SMS is moved to Sent Items or Error Items. */ static GSM_Error SMSDFiles_MoveSMS(GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, unsigned char *ID, bool alwaysDelete, bool sent) { FILE *oFile,*iFile; int ilen = 0, olen = 0; char Buffer[(GSM_MAX_SMS_LENGTH*MAX_MULTI_SMS+1)*2],ifilename[400],ofilename[400]; char *sourcepath, *destpath; sourcepath = Config->outboxpath; if (sent) { destpath = Config->sentsmspath; } else { destpath = Config->errorsmspath; } strcpy(ifilename, sourcepath); strcat(ifilename, ID); strcpy(ofilename, destpath); strcat(ofilename, ID); #ifdef WIN32 if (!mystrncasecmp(ifilename, ofilename, strlen(ofilename))) { #else if (strcmp(ifilename, ofilename) != 0) { #endif iFile = fopen(ifilename, "r"); ilen = fread(Buffer, 1, sizeof(Buffer), iFile); fclose(iFile); oFile = fopen(ofilename, "w"); olen = fwrite(Buffer, 1, ilen, oFile); fclose(oFile); } if (ilen == olen) { if ((strcmp(ifilename, "/") == 0) || (remove(ifilename) != 0)) { WriteSMSDLog("Could not delete %s (%i)", ifilename, errno); return ERR_UNKNOWN; } return ERR_NONE; } else { WriteSMSDLog("Error copying SMS %s -> %s", ifilename, ofilename); if (alwaysDelete) { if ((strcmp(ifilename, "/") == 0) || (remove(ifilename) != 0)) WriteSMSDLog("Could not delete %s (%i)", ifilename, errno); } return ERR_UNKNOWN; } } static GSM_Error SMSDFiles_AddSentSMSInfo(GSM_MultiSMSMessage *sms, GSM_SMSDConfig *Config, unsigned char *ID, int Part, GSM_SMSDSendingError err, int TPMR) { if (err == SMSD_SEND_OK) WriteSMSDLog("Transmitted %s (%s: %i) to %s", Config->SMSID, (Part == sms->Number?"total":"part"),Part,DecodeUnicodeString(sms->SMS[0].Number)); return ERR_NONE; } GSM_SMSDService SMSDFiles = { NONEFUNCTION, /* Init */ NONEFUNCTION, /* InitAfterConnect */ SMSDFiles_SaveInboxSMS, SMSDFiles_FindOutboxSMS, SMSDFiles_MoveSMS, NOTSUPPORTED, /* CreateOutboxSMS */ SMSDFiles_AddSentSMSInfo, NOTSUPPORTED, /* RefreshSendStatus */ NOTSUPPORTED /* RefreshPhoneStatus */ }; /* How should editor handle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/gammu/smsd/smsdcore.c b/gammu/emb/gammu/smsd/smsdcore.c index cc9accc..e69a6e7 100644 --- a/gammu/emb/gammu/smsd/smsdcore.c +++ b/gammu/emb/gammu/smsd/smsdcore.c @@ -1,583 +1,588 @@ /* (c) 2002-2004 by Marcin Wiacek and Joergen Thomsen */ #include <string.h> #include <signal.h> #include <stdarg.h> #include <time.h> #include "../../common/misc/coding/coding.h" #include "../gammu.h" #include "smsdcore.h" #include "s_files.h" #ifdef HAVE_MYSQL_MYSQL_H # include "s_mysql.h" #endif FILE *smsd_log_file = NULL; static int TPMR; static GSM_Error SendingSMSStatus; static void SMSSendingSMSStatus (char *Device, int status, int mr) { dbgprintf("Incoming SMS device: \"%s\" status=%d, reference=%d\n",Device, status, mr); TPMR = mr; if (status==0) { SendingSMSStatus = ERR_NONE; } else { SendingSMSStatus = ERR_UNKNOWN; } } void GSM_Terminate_SMSD(char *msg, int error, bool exitprogram, int rc) { int ret = ERR_NONE; if (s.opened) { WriteSMSDLog("Terminating communication"); ret=GSM_TerminateConnection(&s); if (ret!=ERR_NONE) { printf("%s\n",print_error(error,s.di.df,s.msg)); if (s.opened) GSM_TerminateConnection(&s); } } if (error != 0) { WriteSMSDLog(msg, error, print_error(error,s.di.df,s.msg)); fprintf(stderr, msg, error, print_error(error,s.di.df,s.msg)); fprintf(stderr, "\n"); } if (exitprogram) { if (smsd_log_file!=NULL) fclose(smsd_log_file); exit(rc); } } #ifdef __GNUC__ __attribute__((format(printf, 1, 2))) #endif void WriteSMSDLog(char *format, ...) { GSM_DateTime date_time; char Buffer[2000]; va_list argp; int result; if (smsd_log_file != NULL) { va_start(argp, format); result = vsprintf(Buffer,GetMsg(s.msg,format),argp); va_end(argp); GSM_GetCurrentDateTime(&date_time); fprintf(smsd_log_file,"%s %4d/%02d/%02d %02d:%02d:%02d : %s\n", DayOfWeek(date_time.Year, date_time.Month, date_time.Day), date_time.Year, date_time.Month, date_time.Day, date_time.Hour, date_time.Minute, date_time.Second,Buffer); fflush(smsd_log_file); } } void SMSD_ReadConfig(char *filename, GSM_SMSDConfig *Config, bool log, char *service) { INI_Section *smsdcfgfile = NULL; GSM_Config smsdcfg; unsigned char *str; static unsigned char emptyPath[1] = "\0"; smsdcfgfile=INI_ReadFile(filename, false); if (smsdcfgfile==NULL) { fprintf(stderr,"Can't find file \"%s\"\n",filename); exit(-1); } Config->logfilename=INI_GetValue(smsdcfgfile, "smsd", "logfile", false); if (Config->logfilename != NULL) { smsd_log_file=fopen(Config->logfilename,"ab"); if (smsd_log_file == NULL) { fprintf(stderr,"Can't open file \"%s\"\n",Config->logfilename); exit(-1); } fprintf(stderr,"Log filename is \"%s\"\n",Config->logfilename); } if (log) WriteSMSDLog("Start GAMMU smsd"); /* Include Numbers used, because we don't want create new variable */ Config->IncludeNumbers=INI_FindLastSectionEntry(smsdcfgfile, "gammu", false); if (Config->IncludeNumbers) { GSM_ReadConfig(smsdcfgfile, &smsdcfg, 0); memcpy(&s.Config,&smsdcfg,sizeof(GSM_Config)); error=GSM_SetDebugFile(s.Config[0].DebugFile, &di); } Config->PINCode=INI_GetValue(smsdcfgfile, "smsd", "PIN", false); if (Config->PINCode == NULL) { - if (log) WriteSMSDLog("No PIN code in %s file",filename); - fprintf(stderr,"No PIN code in %s file\n",filename); - exit(-1); + if (log) WriteSMSDLog("Warning: No PIN code in %s file",filename); + fprintf(stderr,"Warning: No PIN code in %s file\n",filename); + } else { + if (log) WriteSMSDLog("PIN code is \"%s\"",Config->PINCode); } - if (log) WriteSMSDLog("PIN code is \"%s\"",Config->PINCode); str = INI_GetValue(smsdcfgfile, "smsd", "commtimeout", false); if (str) Config->commtimeout=atoi(str); else Config->commtimeout = 1; str = INI_GetValue(smsdcfgfile, "smsd", "sendtimeout", false); if (str) Config->sendtimeout=atoi(str); else Config->sendtimeout = 10; str = INI_GetValue(smsdcfgfile, "smsd", "receivefrequency", false); if (str) Config->receivefrequency=atoi(str); else Config->receivefrequency = 0; str = INI_GetValue(smsdcfgfile, "smsd", "resetfrequency", false); if (str) Config->resetfrequency=atoi(str); else Config->resetfrequency = 0; if (log) WriteSMSDLog("commtimeout=%i, sendtimeout=%i, receivefrequency=%i, resetfrequency=%i", Config->commtimeout, Config->sendtimeout, Config->receivefrequency, Config->resetfrequency); Config->deliveryreport = INI_GetValue(smsdcfgfile, "smsd", "deliveryreport", false); if (Config->deliveryreport == NULL || (!mystrncasecmp(Config->deliveryreport, "log", 3) && !mystrncasecmp(Config->deliveryreport, "sms", 3))) { Config->deliveryreport = "no"; } if (log) WriteSMSDLog("deliveryreport = %s", Config->deliveryreport); Config->PhoneID = INI_GetValue(smsdcfgfile, "smsd", "phoneid", false); if (Config->PhoneID == NULL) Config->PhoneID = ""; if (log) WriteSMSDLog("phoneid = %s", Config->PhoneID); if (!strcmp(service,"FILES")) { Config->inboxpath=INI_GetValue(smsdcfgfile, "smsd", "inboxpath", false); if (Config->inboxpath == NULL) Config->inboxpath = emptyPath; Config->inboxformat=INI_GetValue(smsdcfgfile, "smsd", "inboxformat", false); if (Config->inboxformat == NULL || (!mystrncasecmp(Config->inboxformat, "detail", 6) && !mystrncasecmp(Config->inboxformat, "unicode", 7))) { Config->inboxformat = "standard"; } if (log) WriteSMSDLog("Inbox is \"%s\" with format \"%s\"", Config->inboxpath, Config->inboxformat); Config->outboxpath=INI_GetValue(smsdcfgfile, "smsd", "outboxpath", false); if (Config->outboxpath == NULL) Config->outboxpath = emptyPath; Config->transmitformat=INI_GetValue(smsdcfgfile, "smsd", "transmitformat", false); if (Config->transmitformat == NULL || (!mystrncasecmp(Config->transmitformat, "auto", 4) && !mystrncasecmp(Config->transmitformat, "unicode", 7))) { Config->transmitformat = "7bit"; } if (log) WriteSMSDLog("Outbox is \"%s\" with transmission format \"%s\"", Config->outboxpath, Config->transmitformat); Config->sentsmspath=INI_GetValue(smsdcfgfile, "smsd", "sentsmspath", false); if (Config->sentsmspath == NULL) Config->sentsmspath = Config->outboxpath; if (log) WriteSMSDLog("Sent SMS moved to \"%s\"",Config->sentsmspath); Config->errorsmspath=INI_GetValue(smsdcfgfile, "smsd", "errorsmspath", false); if (Config->errorsmspath == NULL) Config->errorsmspath = Config->sentsmspath; if (log) WriteSMSDLog("SMS with errors moved to \"%s\"",Config->errorsmspath); } #ifdef HAVE_MYSQL_MYSQL_H if (!strcmp(service,"MYSQL")) { Config->skipsmscnumber = INI_GetValue(smsdcfgfile, "smsd", "skipsmscnumber", false); if (Config->skipsmscnumber == NULL) Config->skipsmscnumber=""; Config->user = INI_GetValue(smsdcfgfile, "smsd", "user", false); if (Config->user == NULL) Config->user="root"; Config->password = INI_GetValue(smsdcfgfile, "smsd", "password", false); if (Config->password == NULL) Config->password=""; Config->PC = INI_GetValue(smsdcfgfile, "smsd", "pc", false); if (Config->PC == NULL) Config->PC="localhost"; Config->database = INI_GetValue(smsdcfgfile, "smsd", "database", false); if (Config->database == NULL) Config->database="sms"; } #endif Config->IncludeNumbers=INI_FindLastSectionEntry(smsdcfgfile, "include_numbers", false); Config->ExcludeNumbers=INI_FindLastSectionEntry(smsdcfgfile, "exclude_numbers", false); if (Config->IncludeNumbers != NULL) { if (log) WriteSMSDLog("Include numbers available"); } if (Config->ExcludeNumbers != NULL) { if (Config->IncludeNumbers == NULL) { if (log) WriteSMSDLog("Exclude numbers available"); } else { if (log) WriteSMSDLog("Exclude numbers available, but IGNORED"); } } Config->retries = 0; Config->prevSMSID[0] = 0; Config->SMSC.Location = 0; Config->relativevalidity = -1; } bool SMSD_CheckSecurity(GSM_SMSDConfig *Config) { GSM_SecurityCode SecurityCode; GSM_Error error; /* Need PIN ? */ error=Phone->GetSecurityStatus(&s,&SecurityCode.Type); /* Unknown error */ if (error != ERR_NOTSUPPORTED && error != ERR_NONE) { WriteSMSDLog("Error getting security status (%i)", error); return false; } /* No supported - do not check more */ if (error == ERR_NOTSUPPORTED) return true; /* If PIN, try to enter */ switch (SecurityCode.Type) { case SEC_Pin: - WriteSMSDLog("Trying to enter PIN"); - strcpy(SecurityCode.Code,Config->PINCode); - error=Phone->EnterSecurityCode(&s,SecurityCode); - if (error == ERR_SECURITYERROR) { - GSM_Terminate_SMSD("ERROR: incorrect PIN", error, true, -1); - } - if (error != ERR_NONE) { - WriteSMSDLog("Error entering PIN (%i)", error); + if (Config->PINCode==NULL) { + WriteSMSDLog("Warning: no PIN in config"); return false; - } + } else { + WriteSMSDLog("Trying to enter PIN"); + strcpy(SecurityCode.Code,Config->PINCode); + error=Phone->EnterSecurityCode(&s,SecurityCode); + if (error == ERR_SECURITYERROR) { + GSM_Terminate_SMSD("ERROR: incorrect PIN", error, true, -1); + } + if (error != ERR_NONE) { + WriteSMSDLog("Error entering PIN (%i)", error); + return false; + } + } break; case SEC_SecurityCode: case SEC_Pin2: case SEC_Puk: case SEC_Puk2: GSM_Terminate_SMSD("ERROR: phone requires not supported code type", 0, true, -1); case SEC_None: break; } return true; } bool SMSD_ReadDeleteSMS(GSM_SMSDConfig *Config, GSM_SMSDService *Service) { bool start,process; GSM_MultiSMSMessage sms; unsigned char buffer[100]; GSM_Error error=ERR_NONE; INI_Entry *e; int i; start=true; while (error == ERR_NONE && !gshutdown) { sms.SMS[0].Folder=0x00; error=Phone->GetNextSMS(&s, &sms, start); switch (error) { case ERR_EMPTY: break; case ERR_NONE: /* Not Inbox SMS - exit */ if (!sms.SMS[0].InboxFolder) break; process=true; DecodeUnicode(sms.SMS[0].Number,buffer); if (Config->IncludeNumbers != NULL) { e=Config->IncludeNumbers; process=false; while (1) { if (e == NULL) break; if (strcmp(buffer,e->EntryValue)==0) { process=true; break; } e = e->Prev; } } else if (Config->ExcludeNumbers != NULL) { e=Config->ExcludeNumbers; process=true; while (1) { if (e == NULL) break; if (strcmp(buffer,e->EntryValue)==0) { process=false; break; } e = e->Prev; } } if (process) { Service->SaveInboxSMS(sms, Config); } else { WriteSMSDLog("Excluded %s", buffer); } break; default: WriteSMSDLog("Error getting SMS (%i)", error); return false; } if (error == ERR_NONE && sms.SMS[0].InboxFolder) { for (i=0;i<sms.Number;i++) { sms.SMS[i].Folder=0; error=Phone->DeleteSMS(&s,&sms.SMS[i]); switch (error) { case ERR_NONE: case ERR_EMPTY: break; default: WriteSMSDLog("Error deleting SMS (%i)", error); return false; } } } start=false; } return true; } bool SMSD_CheckSMSStatus(GSM_SMSDConfig *Config,GSM_SMSDService *Service) { GSM_SMSMemoryStatus SMSStatus; GSM_Error error; /* Do we have any SMS in phone ? */ error=Phone->GetSMSStatus(&s,&SMSStatus); if (error != ERR_NONE) { WriteSMSDLog("Error getting SMS status (%i)", error); return false; } /* Yes. We have SMS in phone */ if (SMSStatus.SIMUsed+SMSStatus.PhoneUsed != 0) { return SMSD_ReadDeleteSMS(Config,Service); } return true; } bool SMSD_SendSMS(GSM_SMSDConfig *Config,GSM_SMSDService *Service) { GSM_MultiSMSMessage sms; GSM_DateTime Date; GSM_Error error; unsigned int i, j, z; error = Service->FindOutboxSMS(&sms, Config, Config->SMSID); if (error == ERR_EMPTY || error == ERR_NOTSUPPORTED) { /* No outbox sms - wait few seconds and escape */ for (j=0;j<Config->commtimeout && !gshutdown;j++) { GSM_GetCurrentDateTime (&Date); i=Date.Second; while (i==Date.Second && !gshutdown) { my_sleep(10); GSM_GetCurrentDateTime(&Date); } Service->RefreshPhoneStatus(Config); } return true; } if (error != ERR_NONE) { /* Unknown error - escape */ WriteSMSDLog("Error in outbox on %s", Config->SMSID); for (i=0;i<sms.Number;i++) { Service->AddSentSMSInfo(&sms, Config, Config->SMSID, i+1, SMSD_SEND_ERROR, -1); } Service->MoveSMS(&sms,Config, Config->SMSID, true,false); return false; } if (!gshutdown) { if (strcmp(Config->prevSMSID, Config->SMSID) == 0) { Config->retries++; if (Config->retries > MAX_RETRIES) { Config->retries = 0; strcpy(Config->prevSMSID, ""); WriteSMSDLog("Moved to errorbox: %s", Config->SMSID); for (i=0;i<sms.Number;i++) { Service->AddSentSMSInfo(&sms, Config, Config->SMSID, i+1, SMSD_SEND_ERROR, -1); } Service->MoveSMS(&sms,Config, Config->SMSID, true,false); return false; } } else { Config->retries = 0; strcpy(Config->prevSMSID, Config->SMSID); } for (i=0;i<sms.Number;i++) { if (sms.SMS[i].SMSC.Location == 1) { if (Config->SMSC.Location == 0) { Config->SMSC.Location = 1; error = Phone->GetSMSC(&s,&Config->SMSC); if (error!=ERR_NONE) { WriteSMSDLog("Error getting SMSC from phone"); return false; } } memcpy(&sms.SMS[i].SMSC,&Config->SMSC,sizeof(GSM_SMSC)); sms.SMS[i].SMSC.Location = 0; if (Config->relativevalidity != -1) { sms.SMS[i].SMSC.Validity.Format = SMS_Validity_RelativeFormat; sms.SMS[i].SMSC.Validity.Relative = Config->relativevalidity; } } if (Config->currdeliveryreport == 1) { sms.SMS[i].PDU = SMS_Status_Report; } else { if ((strcmp(Config->deliveryreport, "no") != 0 && (Config->currdeliveryreport == -1))) sms.SMS[i].PDU = SMS_Status_Report; } error=Phone->SendSMS(&s, &sms.SMS[i]); if (error!=ERR_NONE) { Service->AddSentSMSInfo(&sms, Config, Config->SMSID, i+1, SMSD_SEND_SENDING_ERROR, -1); WriteSMSDLog("Error sending SMS %s (%i): %s", Config->SMSID, error,print_error(error,s.di.df,s.msg)); return false; } Service->RefreshPhoneStatus(Config); j = 0; TPMR = -1; SendingSMSStatus = ERR_TIMEOUT; while (!gshutdown) { GSM_GetCurrentDateTime (&Date); z=Date.Second; while (z==Date.Second) { my_sleep(10); GSM_GetCurrentDateTime(&Date); GSM_ReadDevice(&s,true); if (SendingSMSStatus != ERR_TIMEOUT) break; } Service->RefreshSendStatus(Config, Config->SMSID); Service->RefreshPhoneStatus(Config); if (SendingSMSStatus != ERR_TIMEOUT) break; j++; if (j>Config->sendtimeout) break; } if (SendingSMSStatus != ERR_NONE) { Service->AddSentSMSInfo(&sms, Config, Config->SMSID, i+1, SMSD_SEND_SENDING_ERROR, TPMR); WriteSMSDLog("Error getting send status of %s (%i): %s", Config->SMSID, SendingSMSStatus,print_error(SendingSMSStatus,s.di.df,s.msg)); return false; } error = Service->AddSentSMSInfo(&sms, Config, Config->SMSID, i+1, SMSD_SEND_OK, TPMR); if (error!=ERR_NONE) { return false; } } strcpy(Config->prevSMSID, ""); if (Service->MoveSMS(&sms,Config, Config->SMSID, false, true) != ERR_NONE) { Service->MoveSMS(&sms,Config, Config->SMSID, true, false); } } return true; } void SMSDaemon(int argc, char *argv[]) { int errors = 255, initerrors=0; GSM_SMSDService *Service; GSM_Error error; time_t lastreceive, lastreset = 0; GSM_SMSDConfig Config; if (!strcmp(argv[2],"FILES")) { Service = &SMSDFiles; #ifdef HAVE_MYSQL_MYSQL_H } else if (!strcmp(argv[2],"MYSQL")) { Service = &SMSDMySQL; #endif } else { fprintf(stderr,"Unknown service type (\"%s\")\n",argv[2]); exit(-1); } SMSD_ReadConfig(argv[3], &Config, true, argv[2]); error = Service->Init(&Config); if (error!=ERR_NONE) { GSM_Terminate_SMSD("Stop GAMMU smsd (%i)", error, true, -1); } signal(SIGINT, interrupt); signal(SIGTERM, interrupt); fprintf(stderr,"Press Ctrl+C to stop the program ...\n"); lastreceive = time(NULL); lastreset = time(NULL); SendingSMSStatus = ERR_UNKNOWN; while (!gshutdown) { /* There were errors in communication - try to recover */ if (errors > 2) { if (errors != 255) { WriteSMSDLog("Terminating communication (%i,%i)", error, errors); error=GSM_TerminateConnection(&s); } if (initerrors++ > 3) my_sleep(30000); WriteSMSDLog("Starting communication"); error=GSM_InitConnection(&s,2); switch (error) { case ERR_NONE: s.User.SendSMSStatus = SMSSendingSMSStatus; Phone = s.Phone.Functions; if (errors == 255) { errors = 0; s.Phone.Data.IMEI[0] = 0; if (!(Phone->GetIMEI(&s))) { errors++; } else { error = Service->InitAfterConnect(&Config); if (error!=ERR_NONE) { GSM_Terminate_SMSD("Stop GAMMU smsd (%i)", error, true, -1); } Phone->SetFastSMSSending(&s,true); } } else { errors = 0; } if (initerrors > 3 || initerrors < 0) { error=Phone->Reset(&s, false); /* soft reset */ WriteSMSDLog("Reset return code: %s (%i) ", error == ERR_NONE? "OK":"ERROR", error); lastreset = time(NULL); my_sleep(5000); } /* Marcin Wiacek: FIXME. To check */ // di = s.di; break; case ERR_DEVICEOPENERROR: GSM_Terminate_SMSD("Can't open device (%i)", error, true, -1); default: WriteSMSDLog("Error at init connection (%i)", error); errors = 250; } continue; } if ((difftime(time(NULL), lastreceive) >= Config.receivefrequency) || (SendingSMSStatus != ERR_NONE)) { lastreceive = time(NULL); if (!SMSD_CheckSecurity(&Config)) { errors++; initerrors++; continue; } else errors=0; initerrors = 0; if (!SMSD_CheckSMSStatus(&Config,Service)) { /* read all incoming SMS */ errors++; continue; } else errors=0; if (Config.resetfrequency > 0 && difftime(time(NULL), lastreset) >= Config.resetfrequency) { /* time for preventive reset */ errors = 254; initerrors = -2; continue; } } if (!SMSD_SendSMS(&Config,Service)) continue; } Phone->SetFastSMSSending(&s,false); GSM_Terminate_SMSD("Stop GAMMU smsd", 0, false, 0); } GSM_Error SMSDaemonSendSMS(char *service, char *filename, GSM_MultiSMSMessage *sms) { GSM_SMSDService *Service; GSM_SMSDConfig Config; if (!strcmp(service,"FILES")) { Service = &SMSDFiles; #ifdef HAVE_MYSQL_MYSQL_H } else if (!strcmp(service,"MYSQL")) { Service = &SMSDMySQL; #endif } else { fprintf(stderr,"Unknown service type (\"%s\")\n",service); exit(-1); } SMSD_ReadConfig(filename, &Config, false, service); error = Service->Init(&Config); if (error!=ERR_NONE) return ERR_UNKNOWN; return Service->CreateOutboxSMS(sms,&Config); } /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ |