From 6750bf7bf3cdb5bdbde56395782b3f4b5ed82b4f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20=C4=8Ciha=C5=99?= Date: Sun, 7 Dec 2003 23:17:27 +0100 Subject: [PATCH] Imported gammu 0.90.7 --- cfg/Makefile.cfg | 2 +- cfg/Makefile.glo | 4 +- cfg/config.h | 4 +- cfg/doxygen/Doxyfile | 2 +- cfg/locale/locale.c | 50 +- cfg/pkgconfig/gammu.pc | 2 +- changelog | 53 + common/device/devfunc.c | 59 +- common/device/irda/irda.c | 377 +++-- common/device/irda/irda.h | 4 +- common/device/irda/irda_unx.h | 87 +- common/device/serial/ser_djg.c | 29 +- common/device/serial/ser_djg.h | 2 +- common/device/serial/ser_unx.c | 556 +++---- common/device/serial/ser_unx.h | 4 +- common/device/serial/ser_w32.c | 39 +- common/gsmcomon.c | 25 +- common/gsmcomon.h | 4 +- common/gsmstate.c | 100 +- common/gsmstate.h | 10 +- common/misc/cfg.c | 673 ++++---- common/misc/cfg.h | 80 +- common/misc/coding/coding.c | 20 +- common/misc/misc.c | 62 +- common/misc/misc.h | 18 +- common/phone/alcatel/alcatel.c | 23 +- common/phone/at/atgen.c | 578 ++++--- common/phone/at/atgen.h | 32 +- common/phone/at/siemens.c | 2 +- common/phone/nokia/dct3/dct3func.c | 8 +- common/phone/nokia/dct3/n6110.c | 52 +- common/phone/nokia/dct3/n6110.h | 5 +- common/phone/nokia/dct3/n7110.c | 2 + common/phone/nokia/dct4/dct4func.h | 2 +- common/phone/nokia/dct4/n3650.h | 2 +- common/phone/nokia/dct4/n6510.c | 14 +- common/phone/nokia/dct4/n6510.h | 2 +- common/phone/nokia/nfunc.c | 2 +- common/phone/nokia/nfuncold.c | 2 +- common/phone/obex/obexgen.h | 2 +- common/phone/pfunc.c | 2 +- common/phone/pfunc.h | 2 +- common/phone/symbian/mroutgen.h | 2 +- common/protocol/alcatel/alcabus.c | 75 +- common/protocol/at/at.c | 134 +- common/protocol/at/at.h | 4 +- common/protocol/nokia/mbus2.c | 44 +- common/service/backup/backgen.h | 2 +- common/service/backup/backtext.c | 296 ++-- common/service/gsmcal.h | 10 +- common/service/gsmcall.h | 2 +- common/service/gsmlogo.c | 98 +- common/service/gsmlogo.h | 67 +- common/service/gsmmisc.h | 121 +- common/service/gsmnet.c | 898 ++++++----- common/service/gsmnet.h | 50 +- common/service/gsmpbk.c | 22 + common/service/gsmpbk.h | 30 +- common/service/gsmprof.h | 19 +- common/service/gsmring.c | 17 +- common/service/gsmring.h | 2 +- common/service/gsmsms.c | 1962 ------------------------ common/service/sms/Makefile | 4 + common/service/sms/gsmems.c | 750 +++++++++ common/service/sms/gsmems.h | 19 + common/service/sms/gsmmulti.c | 929 +++++++++++ common/service/sms/gsmmulti.h | 238 +++ common/service/sms/gsmsms.c | 646 ++++++++ common/service/{ => sms}/gsmsms.h | 235 +-- copying | 10 + docs/docs/locale/gammu_cs.txt | Bin 49626 -> 46144 bytes docs/docs/locale/gammu_de.txt | Bin 69900 -> 60174 bytes docs/docs/locale/gammu_pl.txt | Bin 42304 -> 42132 bytes docs/docs/locale/gammu_us.txt | Bin 40828 -> 41900 bytes gammu.spec | 2 +- gammu/bcc6.mak/gammu.bpf | 4 +- gammu/bcc6.mak/gammu.bpr | 55 +- gammu/bcc6.mak/gammu.bpr.in | 51 +- gammu/bcc6.mak/gammu.mak | 43 +- gammu/depend/dct4.c | 48 + gammu/depend/dct4.h | 5 + gammu/gammu.c | 256 ++-- gammu/msvc6.mak/gammu.dsp | 20 +- gammu/msvc6.mak/gammu.rc | 8 +- gammu/msvc7.mak/gammu.rc | 8 +- gammu/msvc7.mak/gammu.vcproj | 16 +- gammu/smsd/smsdcore.c | 55 +- gammu/smsd/smsdcore.h | 5 +- gammu/sniff.c | 3 +- other/copying | 2 + {docs/develop => other}/protocol/TDMA 5120.txt | 0 {docs/develop => other}/protocol/carkit.txt | 0 {docs/develop => other}/protocol/n6110.txt | 0 {docs/develop => other}/protocol/n6510.txt | 0 {docs/develop => other}/protocol/n7110.txt | 0 {docs/develop => other}/protocol/nokia.txt | 0 {docs/develop => other}/protocol/readme | 0 version | 2 +- win32/delphi7.gui/classic2/Unit1.dfm | 22 +- win32/delphi7.gui/classic2/Unit1.pas | 6 + win32/delphi7.gui/gammu.pas | 1 + win32/dll/gammu.c | 49 + win32/dll/msvc6.mak/gammu.def | 3 +- win32/dll/msvc6.mak/gammu.dsp | 20 +- win32/dll/msvc6.mak/gammu.rc | 8 +- win32/dll/msvc7.mak/gammu.def | 1 + win32/dll/msvc7.mak/gammu.rc | 8 +- win32/dll/msvc7.mak/gammu.vcproj | 16 +- 108 files changed, 5763 insertions(+), 4638 deletions(-) rewrite common/device/irda/irda.c (64%) rewrite common/device/irda/irda_unx.h (69%) rewrite common/device/serial/ser_unx.c (83%) rewrite common/misc/cfg.c (89%) rewrite common/misc/cfg.h (82%) rewrite common/service/gsmnet.c (93%) delete mode 100644 common/service/gsmsms.c create mode 100644 common/service/sms/Makefile create mode 100644 common/service/sms/gsmems.c create mode 100644 common/service/sms/gsmems.h create mode 100644 common/service/sms/gsmmulti.c create mode 100644 common/service/sms/gsmmulti.h create mode 100644 common/service/sms/gsmsms.c rename common/service/{ => sms}/gsmsms.h (63%) rewrite docs/docs/locale/gammu_cs.txt (80%) rewrite docs/docs/locale/gammu_de.txt (82%) rewrite docs/docs/locale/gammu_pl.txt (79%) rewrite docs/docs/locale/gammu_us.txt (79%) create mode 100644 other/copying rename {docs/develop => other}/protocol/TDMA 5120.txt (100%) rename {docs/develop => other}/protocol/carkit.txt (100%) rename {docs/develop => other}/protocol/n6110.txt (100%) rename {docs/develop => other}/protocol/n6510.txt (100%) rename {docs/develop => other}/protocol/n7110.txt (100%) rename {docs/develop => other}/protocol/nokia.txt (100%) rename {docs/develop => other}/protocol/readme (100%) diff --git a/cfg/Makefile.cfg b/cfg/Makefile.cfg index 9f8c3e6dc..2674f9d12 100644 --- a/cfg/Makefile.cfg +++ b/cfg/Makefile.cfg @@ -2,7 +2,7 @@ # ------------- Makefile options, which depens on OS -------------------------- -VERSION = 0.90.0 +VERSION = 0.90.7 # what is used to delete files, compile, install and find RM = /bin/rm -f diff --git a/cfg/Makefile.glo b/cfg/Makefile.glo index 047e7334c..c5735f4f9 100644 --- a/cfg/Makefile.glo +++ b/cfg/Makefile.glo @@ -17,7 +17,9 @@ COMMON = $(TOPDIR)/common/gsmcomon.o \ $(TOPDIR)/common/misc/cfg.o \ $(TOPDIR)/common/misc/coding/coding.o \ $(TOPDIR)/common/misc/coding/md5.o \ - $(TOPDIR)/common/service/gsmsms.o \ + $(TOPDIR)/common/service/sms/gsmsms.o \ + $(TOPDIR)/common/service/sms/gsmems.o \ + $(TOPDIR)/common/service/sms/gsmmulti.o \ $(TOPDIR)/common/service/gsmcal.o \ $(TOPDIR)/common/service/gsmwap.o \ $(TOPDIR)/common/service/gsmpbk.o \ diff --git a/cfg/config.h b/cfg/config.h index 2c0de3332..26f4fe04b 100644 --- a/cfg/config.h +++ b/cfg/config.h @@ -6,8 +6,8 @@ /* -------------------------- Gammu specific ---------------------------- */ /* Version of package */ -#define VERSION "0.90.0" -#define VERSION_WIN "0,90,0,0" +#define VERSION "0.90.7" +#define VERSION_WIN "0,90,7,0" #ifndef _MSC_VER /* Define if want DEBUG info */ diff --git a/cfg/doxygen/Doxyfile b/cfg/doxygen/Doxyfile index d80a56955..85b2cdda2 100644 --- a/cfg/doxygen/Doxyfile +++ b/cfg/doxygen/Doxyfile @@ -4,7 +4,7 @@ # General configuration options #--------------------------------------------------------------------------- PROJECT_NAME = Gammu -PROJECT_NUMBER = 0.90.0 +PROJECT_NUMBER = 0.90.7 OUTPUT_DIRECTORY = gammu-doc OUTPUT_LANGUAGE = English USE_WINDOWS_ENCODING = NO diff --git a/cfg/locale/locale.c b/cfg/locale/locale.c index cb3e564b6..55be02be1 100644 --- a/cfg/locale/locale.c +++ b/cfg/locale/locale.c @@ -11,7 +11,7 @@ unsigned char line[1000]; int outputnum; FILE *output; -CFG_Header *cfg_info; +INI_Section *cfg_info; void WriteOutput(char *mystring) { @@ -84,15 +84,15 @@ void RemoveDuplicatedStrings(char *filename) { int num2,num,number; unsigned char buffer[500],buffer2[500],buff2[50]; - CFG_Entry *e,*ebackup,*e2; + INI_Entry *e,*ebackup,*e2; bool duplicated; printf("Removing duplicated strings from %s\n",filename); EncodeUnicode (buff2, "common", 6); - cfg_info = CFG_ReadFile(filename,true); - output = fopen(filename, "wb"); + cfg_info = INI_ReadFile(filename,true); + output = fopen(filename, "wb"); outputnum=0; @@ -104,12 +104,12 @@ void RemoveDuplicatedStrings(char *filename) WriteOutput(""); WriteOutput("[common]"); - e = CFG_FindLastSectionEntry(cfg_info, buff2,true); + e = INI_FindLastSectionEntry(cfg_info, buff2,true); ebackup = e; while (1) { if (e == NULL) break; num = -1; - sprintf(buffer,"%s",DecodeUnicodeString(e->key)); + sprintf(buffer,"%s",DecodeUnicodeString(e->EntryName)); if (strlen(buffer) == 5 && strncmp("F", buffer, 1) == 0) { num = atoi(buffer+2); } @@ -120,30 +120,30 @@ void RemoveDuplicatedStrings(char *filename) while (1) { if (e2 == NULL) break; num2 = -1; - sprintf(buffer,"%s",DecodeUnicodeString(e2->key)); + sprintf(buffer,"%s",DecodeUnicodeString(e2->EntryName)); if (strlen(buffer) == 5 && strncmp("F", buffer, 1) == 0) { num2 = atoi(buffer+2); number++; } if (num2 != -1 && num2 < num) { - if (mywstrncmp(e2->value, e->value, 0)) { + if (mywstrncmp(e2->EntryValue, e->EntryValue, 0)) { duplicated = true; break; } } - e2 = e2->prev; + e2 = e2->Prev; if (number == num) break; } if (!duplicated) { sprintf(buffer2,"F%04i=",outputnum); EncodeUnicode(buffer,buffer2,6); fwrite(buffer,1,12,output); - fwrite(e->value,1,UnicodeLength(e->value)*2,output); + fwrite(e->EntryValue,1,UnicodeLength(e->EntryValue)*2,output); WriteOutput(""); outputnum++; } } - e = e->prev; + e = e->Prev; printf("*"); } fclose(output); @@ -152,15 +152,15 @@ void RemoveDuplicatedStrings(char *filename) void ProcessLangFile(char *filename) { - CFG_Header *cfg_lang; - CFG_Entry *e,*e_lang,*e2; + INI_Section *cfg_lang; + INI_Entry *e,*e_lang,*e2; int num,num_lang; char *retval_lang; unsigned char buffer[10000],buffer2[10000],buff2[50]; printf("Processing file %s\n",filename); - cfg_lang = CFG_ReadFile(filename,true); + cfg_lang = INI_ReadFile(filename,true); output = fopen(filename, "wb"); buffer[0] = 0xfe; @@ -173,12 +173,12 @@ void ProcessLangFile(char *filename) EncodeUnicode (buff2, "common", 6); - e2 = CFG_FindLastSectionEntry(cfg_lang, buff2, true); - e = CFG_FindLastSectionEntry(cfg_info, buff2, true); + e2 = INI_FindLastSectionEntry(cfg_lang, buff2, true); + e = INI_FindLastSectionEntry(cfg_info, buff2, true); while (1) { if (e == NULL) break; num = -1; - sprintf(buffer,"%s",DecodeUnicodeString(e->key)); + sprintf(buffer,"%s",DecodeUnicodeString(e->EntryName)); if (strlen(buffer) == 5 && strncmp("F", buffer, 1) == 0) { num = atoi(buffer+2); } @@ -187,21 +187,21 @@ void ProcessLangFile(char *filename) sprintf(buffer2,"F%04i=",num); EncodeUnicode(buffer,buffer2,6); fwrite(buffer,1,12,output); - fwrite(e->value,1,UnicodeLength(e->value)*2,output); + fwrite(e->EntryValue,1,UnicodeLength(e->EntryValue)*2,output); WriteOutput(""); e_lang = e2; while (1) { if (e_lang == NULL) break; num_lang = -1; - sprintf(buffer,"%s",DecodeUnicodeString(e_lang->key)); + sprintf(buffer,"%s",DecodeUnicodeString(e_lang->EntryName)); if (strlen(buffer) == 5 && strncmp("F", buffer, 1) == 0) { num_lang = atoi(buffer+2); } if (num_lang!=-1) { - if (mywstrncmp(e_lang->value, e->value, 0)) { + if (mywstrncmp(e_lang->EntryValue, e->EntryValue, 0)) { sprintf(buffer2,"T%04i",num_lang); EncodeUnicode(buffer,buffer2,6); - retval_lang = CFG_Get(cfg_lang, buff2, buffer,true); + retval_lang = INI_GetValue(cfg_lang, buff2, buffer,true); if (retval_lang != NULL) { sprintf(buffer2,"T%04i=",num); EncodeUnicode(buffer,buffer2,6); @@ -212,10 +212,10 @@ void ProcessLangFile(char *filename) break; } } - e_lang = e_lang->prev; + e_lang = e_lang->Prev; } } - e = e->prev; + e = e->Prev; } fclose(output); printf("\n"); @@ -293,14 +293,14 @@ int main(int argc, char *argv[]) #ifdef WIN32 RemoveDuplicatedStrings("../../../../docs/docs/locale/gammu_us.txt"); - cfg_info = CFG_ReadFile("../../../../docs/docs/locale/gammu_us.txt",true); + cfg_info = INI_ReadFile("../../../../docs/docs/locale/gammu_us.txt",true); ProcessLangFile("../../../../docs/docs/locale/gammu_pl.txt"); ProcessLangFile("../../../../docs/docs/locale/gammu_de.txt"); ProcessLangFile("../../../../docs/docs/locale/gammu_cs.txt"); #else RemoveDuplicatedStrings("../../docs/docs/locale/gammu_us.txt"); - cfg_info = CFG_ReadFile("../../docs/docs/locale/gammu_us.txt",true); + cfg_info = INI_ReadFile("../../docs/docs/locale/gammu_us.txt",true); ProcessLangFile("../../docs/docs/locale/gammu_pl.txt"); ProcessLangFile("../../docs/docs/locale/gammu_de.txt"); diff --git a/cfg/pkgconfig/gammu.pc b/cfg/pkgconfig/gammu.pc index d5eabdf0c..f258a0e9d 100644 --- a/cfg/pkgconfig/gammu.pc +++ b/cfg/pkgconfig/gammu.pc @@ -5,6 +5,6 @@ includedir=${prefix}/include Name: gammu Description: Gammu library -Version: 0.90.0 +Version: 0.90.7 Libs: -L${libdir} -lGammu Cflags: -I${includedir}/gammu diff --git a/changelog b/changelog index 3e9b127ff..4591caa45 100644 --- a/changelog +++ b/changelog @@ -22,6 +22,59 @@ and others... For additionals materials and links to them see readme.txt -------------------- +20031207 - 0.90.7 +* new functionality: + * reading security code from all DCT4 + * --geteachsms can link EMS sequences. Currently there is majority (...) + of possible things recognized - linked text, fixed bitmaps, + variable bitmaps, animations, default ringtones/animations ID, etc. etc. + Improved API is ready now for it everything. In the future I will + probably add some default bitmaps/ringtones. + * added ID for various 1100,3100,3200 variants + * added ID for 2100,3610 (Rakesh) + * AT devices: + * keys pressing + * using AT support is more safe because incoming call info is + handled only, when enabled + * rewriten AT protocol module. Now should handle correctly all incoming + frames from phones. + * cleaned and rechecked possible answers in AT module. If something + was done wrong, please let me know + * it's possible to enable sending info about incoming sms to PC. + With T310 it's possible to receive info about SMS Deliver, Reports + are not supported. T310 sometimes goes crazy and mixes frame for + incoming SMS and we need some tricks. Nokia returns OK for enabling + commands, but doesn't work - I made, that all Nokia are not supported + here now. + * it's possible to enable incoming CB. Not decoded yet + * * AT+CPIN used instead for AT+CPIN2 for some models (Michal Cihar) + for PIN2 + * do not attempt to parse CME error when no happen + (in ATGEN_GenericReply) + * more info for network logging status + * * can get FD memory with command line options (Michal Cihar) + * GSM_PhonebookFindDefaultNameNumberGroup also tries to find + suitable name if PBK_Text_Name doesn't exist + * gammu prints security status when some operation fails with + GE_SECURITYERROR + +* fixes and improvements: + * removed problems with automatically linking sms (--geteachsms) with + some EMS sequences + * removed error visible in AT mode during saving SMS + * fixed makefile for MSVC6 and DLL (Michael T.S.) + * AT devices: (Michal Cihar) + * rewritten support for AT+CREG much more compatible with + various phones + +NOTE: written clear in copying files, that 3 party extensions are released + under own licenses. Changed some parts of source according to + requests from Pavel Janik connected with new license. For details + see Gammu mailing list. + +NOTE: CFG reader doesn't work 100% correctly for Unicode now. Please use + this version with care + 20031125 - 0.90.0 * new functionality: * * added lots of API documentation (Michal Cihar) diff --git a/common/device/devfunc.c b/common/device/devfunc.c index ea5727470..b44476524 100644 --- a/common/device/devfunc.c +++ b/common/device/devfunc.c @@ -14,17 +14,17 @@ int socket_read(GSM_StateMachine *s, void *buf, size_t nbytes, int hPhone) { #ifndef WIN32 - fd_set readfds; - - FD_ZERO(&readfds); - FD_SET(hPhone, &readfds); - if (select(hPhone+1, &readfds, NULL, NULL, 0)) { - return(read(hPhone, buf, nbytes)); - } else { - return 0; - } + fd_set readfds; + + FD_ZERO(&readfds); + FD_SET(hPhone, &readfds); + if (select(hPhone+1, &readfds, NULL, NULL, 0)) { + return(read(hPhone, buf, nbytes)); + } else { + return 0; + } #else - return(recv(hPhone, buf, nbytes, 0)); + return(recv(hPhone, buf, nbytes, 0)); #endif } @@ -34,15 +34,15 @@ int socket_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes, int hPh int socket_write(GSM_StateMachine *s, void *buf, size_t nbytes, int hPhone) #endif { - int ret; - size_t actual = 0; - - do { - if ((ret = send(hPhone, buf, nbytes - actual, 0)) < 0) return(actual); - actual += ret; - buf += ret; - } while (actual < nbytes); - return (actual); + int ret; + size_t actual = 0; + + do { + if ((ret = send(hPhone, buf, nbytes - actual, 0)) < 0) return(actual); + actual += ret; + buf += ret; + } while (actual < nbytes); + return (actual); } GSM_Error socket_close(GSM_StateMachine *s, int hPhone) @@ -58,6 +58,21 @@ GSM_Error socket_close(GSM_StateMachine *s, int hPhone) #endif +#ifdef ENABLE_LGPL + +GSM_Error lock_device(const char* port, char **lock_device) +{ + *lock_device = 0; + return GE_NONE; +} + +bool unlock_device(char **lock_file) +{ + return true; +} + +#else + #define max_buf_len 128 #define lock_path "/var/lock/LCK.." @@ -173,7 +188,7 @@ failed: #else *lock_device = 0; return GE_NONE; -#endif /* WIN32 */ +#endif } /* Removes lock and frees memory */ @@ -192,9 +207,11 @@ bool unlock_device(char **lock_file) return (err + 1); #else return true; -#endif /* WIN32 */ +#endif } +#endif + int FindSerialSpeed(char *buffer) { switch (atoi(buffer)) { diff --git a/common/device/irda/irda.c b/common/device/irda/irda.c dissimilarity index 64% index 7373bbdf0..02710cf61 100644 --- a/common/device/irda/irda.c +++ b/common/device/irda/irda.c @@ -1,189 +1,188 @@ - -/* Have to include wsock32.lib library to MS VC6 project to compile it */ - -#include "../../gsmstate.h" - -#ifdef GSM_ENABLE_IRDADEVICE -#ifndef DJGPP - -#ifndef WIN32 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else -# include -# include -#endif - -#include "../../gsmcomon.h" -#include "../devfunc.h" -#include "irda.h" - -static bool irda_discover_device(GSM_StateMachine *state) -{ - GSM_Device_IrdaData *d = &state->Device.Data.Irda; - struct irda_device_list *list; - unsigned char *buf; - unsigned int sec; - - int s, z, len, fd, i; - GSM_DateTime Date; - bool founddevice = false; - -#ifdef WIN32 - WSADATA wsaData; - int index; - - WSAStartup(MAKEWORD(1,1), &wsaData); -#endif - - fd = socket(AF_IRDA, SOCK_STREAM, 0); - - /* 10 = max devices in discover */ - len = sizeof(struct irda_device_list) + sizeof(struct irda_device_info) * 10; - buf = malloc(len); - list = (struct irda_device_list *)buf; - - /* Trying to find device during 2 seconds */ - for (z=0;z<2;z++) { - GSM_GetCurrentDateTime (&Date); - sec = Date.Second; - while (sec==Date.Second) - { - s = len; - memset(buf, 0, s); - - if (getsockopt(fd, SOL_IRLMP, IRLMP_ENUMDEVICES, buf, &s) == 0) { - for (i = 0; i < (int)list->numDevice; i++) { - dbgprintf("Irda: found device \"%s\" (address %x) - ",list->Device[i].irdaDeviceName,list->Device[i].irdaDeviceID); - if (strcmp(GetModelData(NULL,NULL,list->Device[i].irdaDeviceName)->number,"") != 0) { - founddevice = true; - /* Model AUTO */ - if (state->CurrentConfig->Model[0]==0) strcpy(state->Phone.Data.Model,GetModelData(NULL,NULL,list->Device[i].irdaDeviceName)->number); - state->Phone.Data.ModelInfo = GetModelData(NULL,state->Phone.Data.Model,NULL); - } - if (founddevice) { - dbgprintf("correct\n"); -#ifdef WIN32 - for(index=0; index <= 3; index++) - d->peer.irdaDeviceID[index] = list->Device[i].irdaDeviceID[index]; -#else - d->peer.irdaDeviceID = list->Device[i].irdaDeviceID; -#endif - break; - } - dbgprintf("\n"); - } - } - if (founddevice) break; - my_sleep(10); - GSM_GetCurrentDateTime(&Date); - } - if (founddevice) break; - } - free(buf); - close(fd); - - return founddevice; -} - -static GSM_Error irda_open (GSM_StateMachine *s) -{ -#ifdef WIN32 - int Enable9WireMode = 1; -#endif - GSM_Device_IrdaData *d = &s->Device.Data.Irda; - int fd = -1; - -#ifndef WIN32 - if (s->ConnectionType == GCT_IRDAAT) return GE_SOURCENOTAVAILABLE; -#endif - - /* discover the devices */ - if (irda_discover_device(s)==false) return GE_TIMEOUT; - - /* Create socket */ - fd = socket(AF_IRDA, SOCK_STREAM, 0); - - d->peer.irdaAddressFamily = AF_IRDA; -#ifndef WIN32 - d->peer.sir_lsap_sel = LSAP_ANY; -#endif - switch (s->ConnectionType) { - case GCT_IRDAAT: - strcpy(d->peer.irdaServiceName, "IrDA:IrCOMM"); - -#ifdef WIN32 - if (setsockopt(fd, SOL_IRLMP, IRLMP_9WIRE_MODE, (const char *) &Enable9WireMode, - sizeof(int))==SOCKET_ERROR) return GE_UNKNOWN; -#endif - break; - case GCT_IRDAPHONET: - strcpy(d->peer.irdaServiceName, "Nokia:PhoNet"); - break; - case GCT_IRDAOBEX: - /* IrDA:OBEX not supported by N3650 */ -// strcpy(d->peer.irdaServiceName, "IrDA:OBEX"); - - strcpy(d->peer.irdaServiceName, "OBEX"); - - /* Alternative server is "OBEX:IrXfer" */ - break; - default: - return GE_UNKNOWN; - } - - /* Connect to service "Nokia:PhoNet" or other */ - if (connect(fd, (struct sockaddr *)&d->peer, sizeof(d->peer))) { - dbgprintf("Can't connect to service %s\n",d->peer.irdaServiceName); - close(fd); - return GE_NOTSUPPORTED; - } - - d->hPhone=fd; - - return GE_NONE; -} - -static int irda_read(GSM_StateMachine *s, void *buf, size_t nbytes) -{ - return socket_read(s, buf, nbytes, s->Device.Data.Irda.hPhone); -} - -#ifdef WIN32 -static int irda_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes) -#else -static int irda_write(GSM_StateMachine *s, void *buf, size_t nbytes) -#endif -{ - return socket_write(s, buf, nbytes, s->Device.Data.Irda.hPhone); -} - -static GSM_Error irda_close(GSM_StateMachine *s) -{ - return socket_close(s, s->Device.Data.Irda.hPhone); -} - -GSM_Device_Functions IrdaDevice = { - irda_open, - irda_close, - NONEFUNCTION, - NONEFUNCTION, - NONEFUNCTION, - irda_read, - irda_write -}; - -#endif -#endif - -/* How should editor hadle tabs in this file? Add editor commands here. - * vim: noexpandtab sw=8 ts=8 sts=8: - */ + +/* Have to include wsock32.lib library to MS VC6 project to compile it */ + +#include "../../gsmstate.h" + +#ifdef GSM_ENABLE_IRDADEVICE +#ifndef DJGPP + +#ifndef WIN32 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#else +# include +# include +#endif + +#include "../../gsmcomon.h" +#include "../devfunc.h" +#include "irda.h" + +static bool irda_discover_device(GSM_StateMachine *state) +{ + GSM_Device_IrdaData *d = &state->Device.Data.Irda; + struct irda_device_list *list; + unsigned char *buf; + unsigned int sec; + + int s, z, len, fd, i; + GSM_DateTime Date; + bool founddevice = false; + +#ifdef WIN32 + WSADATA wsaData; + int index; + + WSAStartup(MAKEWORD(1,1), &wsaData); +#endif + + fd = socket(AF_IRDA, SOCK_STREAM, 0); + + /* maximally 10 devices in discover */ + len = sizeof(struct irda_device_list) + sizeof(struct irda_device_info) * 10; + buf = malloc(len); + list = (struct irda_device_list *)buf; + + /* Trying to find device during 2 seconds */ + for (z=0;z<2;z++) { + GSM_GetCurrentDateTime (&Date); + sec = Date.Second; + while (sec==Date.Second) { + s = len; + memset(buf, 0, s); + + if (getsockopt(fd, SOL_IRLMP, IRLMP_ENUMDEVICES, buf, &s) == 0) { + for (i = 0; i < (int)list->numDevice; i++) { + dbgprintf("Irda: found device \"%s\" (address %x) - ",list->Device[i].irdaDeviceName,list->Device[i].irdaDeviceID); + if (strcmp(GetModelData(NULL,NULL,list->Device[i].irdaDeviceName)->number,"") != 0) { + founddevice = true; + /* Model AUTO */ + if (state->CurrentConfig->Model[0]==0) strcpy(state->Phone.Data.Model,GetModelData(NULL,NULL,list->Device[i].irdaDeviceName)->number); + state->Phone.Data.ModelInfo = GetModelData(NULL,state->Phone.Data.Model,NULL); + } + if (founddevice) { + dbgprintf("correct\n"); +#ifdef WIN32 + for(index=0; index <= 3; index++) + d->peer.irdaDeviceID[index] = list->Device[i].irdaDeviceID[index]; +#else + d->peer.irdaDeviceID = list->Device[i].irdaDeviceID; +#endif + break; + } + dbgprintf("\n"); + } + } + if (founddevice) break; + my_sleep(10); + GSM_GetCurrentDateTime(&Date); + } + if (founddevice) break; + } + free(buf); + close(fd); + + return founddevice; +} + +static GSM_Error irda_open (GSM_StateMachine *s) +{ +#ifdef WIN32 + int Enable9WireMode = 1; +#endif + GSM_Device_IrdaData *d = &s->Device.Data.Irda; + int fd = -1; + +#ifndef WIN32 + if (s->ConnectionType == GCT_IRDAAT) return GE_SOURCENOTAVAILABLE; +#endif + + /* discover the devices */ + if (irda_discover_device(s)==false) return GE_TIMEOUT; + + /* Create socket */ + fd = socket(AF_IRDA, SOCK_STREAM, 0); + + d->peer.irdaAddressFamily = AF_IRDA; +#ifndef WIN32 + d->peer.sir_lsap_sel = LSAP_ANY; +#endif + switch (s->ConnectionType) { + case GCT_IRDAAT: + strcpy(d->peer.irdaServiceName, "IrDA:IrCOMM"); + +#ifdef WIN32 + if (setsockopt(fd, SOL_IRLMP, IRLMP_9WIRE_MODE, (const char *) &Enable9WireMode, + sizeof(int))==SOCKET_ERROR) return GE_UNKNOWN; +#endif + break; + case GCT_IRDAPHONET: + strcpy(d->peer.irdaServiceName, "Nokia:PhoNet"); + break; + case GCT_IRDAOBEX: + /* IrDA:OBEX not supported by N3650 */ +// strcpy(d->peer.irdaServiceName, "IrDA:OBEX"); + + strcpy(d->peer.irdaServiceName, "OBEX"); + + /* Alternative server is "OBEX:IrXfer" */ + break; + default: + return GE_UNKNOWN; + } + + /* Connect to service */ + if (connect(fd, (struct sockaddr *)&d->peer, sizeof(d->peer))) { + dbgprintf("Can't connect to service %s\n",d->peer.irdaServiceName); + close(fd); + return GE_NOTSUPPORTED; + } + + d->hPhone=fd; + + return GE_NONE; +} + +static int irda_read(GSM_StateMachine *s, void *buf, size_t nbytes) +{ + return socket_read(s, buf, nbytes, s->Device.Data.Irda.hPhone); +} + +#ifdef WIN32 +static int irda_write(GSM_StateMachine *s, unsigned char *buf, size_t nbytes) +#else +static int irda_write(GSM_StateMachine *s, void *buf, size_t nbytes) +#endif +{ + return socket_write(s, buf, nbytes, s->Device.Data.Irda.hPhone); +} + +static GSM_Error irda_close(GSM_StateMachine *s) +{ + return socket_close(s, s->Device.Data.Irda.hPhone); +} + +GSM_Device_Functions IrdaDevice = { + irda_open, + irda_close, + NONEFUNCTION, + NONEFUNCTION, + NONEFUNCTION, + irda_read, + irda_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/common/device/irda/irda.h b/common/device/irda/irda.h index 5fbb54862..455e6af01 100644 --- a/common/device/irda/irda.h +++ b/common/device/irda/irda.h @@ -10,8 +10,8 @@ #endif typedef struct { - int hPhone; - struct sockaddr_irda peer; + int hPhone; + struct sockaddr_irda peer; } GSM_Device_IrdaData; #endif diff --git a/common/device/irda/irda_unx.h b/common/device/irda/irda_unx.h dissimilarity index 69% index 5081f076e..f38911535 100644 --- a/common/device/irda/irda_unx.h +++ b/common/device/irda/irda_unx.h @@ -1,38 +1,49 @@ - -/* part of irda.h available in Linux kernel source */ - -#ifndef IRDA_H -#define IRDA_H - -#include -#include - -#define SOL_IRLMP 266 /* Same as SOL_IRDA for now */ -#define IRLMP_ENUMDEVICES 1 /* Return discovery log */ -#define LSAP_ANY 0xff - -struct sockaddr_irda { - sa_family_t irdaAddressFamily; /* AF_IRDA */ - u_int8_t sir_lsap_sel; /* LSAP selector */ - u_int32_t irdaDeviceID; /* Device address */ - char irdaServiceName[25]; /* Usually :IrDA:TinyTP */ -}; - -struct irda_device_info { - u_int32_t saddr; /* Address of local interface */ - u_int32_t irdaDeviceID; /* Address of remote device */ - char irdaDeviceName[22]; /* Description */ - u_int8_t charset; /* Charset used for description */ - u_int8_t hints[2]; /* Hint bits */ -}; - -struct irda_device_list { - u_int32_t numDevice; - struct irda_device_info Device[1]; -}; - -#endif /* IRDA_H */ - -/* How should editor hadle tabs in this file? Add editor commands here. - * vim: noexpandtab sw=8 ts=8 sts=8: - */ + +/* Taken from irda.h available in Linux kernel source */ + +#ifndef IRDA_H +#define IRDA_H + +#include +#include + +/* Same as SOL_IRDA for now */ +#define SOL_IRLMP 266 +/* Return discovery log */ +#define IRLMP_ENUMDEVICES 1 +#define LSAP_ANY 0xff + +struct sockaddr_irda { + /* AF_IRDA */ + sa_family_t irdaAddressFamily; + /* LSAP selector */ + u_int8_t sir_lsap_sel; + /* Device address */ + u_int32_t irdaDeviceID; + /* Usually :IrDA:TinyTP */ + char irdaServiceName[25]; +}; + +struct irda_device_info { + /* Address of local interface */ + u_int32_t saddr; + /* Address of remote device */ + u_int32_t irdaDeviceID; + /* Description */ + char irdaDeviceName[22]; + /* Charset used for description */ + u_int8_t charset; + /* Hint bits */ + u_int8_t hints[2]; +}; + +struct irda_device_list { + u_int32_t numDevice; + struct irda_device_info Device[1]; +}; + +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/common/device/serial/ser_djg.c b/common/device/serial/ser_djg.c index ea1302861..1256ab26c 100644 --- a/common/device/serial/ser_djg.c +++ b/common/device/serial/ser_djg.c @@ -10,31 +10,31 @@ /* Close the serial port and restore old settings. */ static GSM_Error serial_close(GSM_StateMachine *s) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; + GSM_Device_SerialData *d = &s->Device.Data.Serial; - return GE_NONE; + return GE_NONE; } static GSM_Error serial_open (GSM_StateMachine *s) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; + GSM_Device_SerialData *d = &s->Device.Data.Serial; - return GE_NONE; + return GE_NONE; } static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; + GSM_Device_SerialData *d = &s->Device.Data.Serial; - return GE_NONE; + return GE_NONE; } /* Set the DTR and RTS bit of the serial device. */ static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; + GSM_Device_SerialData *d = &s->Device.Data.Serial; - return GE_NONE; + return GE_NONE; // return GE_DEVICEDTRRTSERROR; } @@ -43,23 +43,22 @@ static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) */ static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; - return GE_NONE; + GSM_Device_SerialData *d = &s->Device.Data.Serial; + return GE_NONE; } /* Read from serial device. */ static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; - return 0; + GSM_Device_SerialData *d = &s->Device.Data.Serial; + return 0; } /* Write to serial device. */ static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) { - GSM_Device_SerialData *d = &s->Device.Data.Serial; - - return 0; + GSM_Device_SerialData *d = &s->Device.Data.Serial; + return 0; } GSM_Device_Functions SerialDevice = { diff --git a/common/device/serial/ser_djg.h b/common/device/serial/ser_djg.h index c199bc1f2..4645cf8a0 100644 --- a/common/device/serial/ser_djg.h +++ b/common/device/serial/ser_djg.h @@ -4,7 +4,7 @@ #define djgppserial_h typedef struct { - int hPhone; + int hPhone; } GSM_Device_SerialData; #endif diff --git a/common/device/serial/ser_unx.c b/common/device/serial/ser_unx.c dissimilarity index 83% index 3eb2afec6..098864059 100644 --- a/common/device/serial/ser_unx.c +++ b/common/device/serial/ser_unx.c @@ -1,278 +1,278 @@ - -#include "../../gsmstate.h" - -#ifdef GSM_ENABLE_SERIALDEVICE -#ifndef WIN32 -#ifndef DJGPP - -#include -#include -#include -#include -#include - -#include "../../gsmcomon.h" -#include "ser_unx.h" - -/* Close the serial port and restore old settings. */ -static GSM_Error serial_close(GSM_StateMachine *s) -{ - GSM_Device_SerialData *d = &s->Device.Data.Serial; - - /*FIXME: error checking */ - tcsetattr(d->hPhone, TCSANOW, &d->backup_termios); - close(d->hPhone); - - return GE_NONE; -} - -#ifndef O_NONBLOCK -# define O_NONBLOCK 0 -#endif - -static GSM_Error serial_open (GSM_StateMachine *s) -{ - GSM_Device_SerialData *d = &s->Device.Data.Serial; - struct termios t; - int i; - - /* O_NONBLOCK MUST be used here as the CLOCAL may be currently off - * and if DCD is down the "open" syscall would be stuck wating 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 GE_DEVICENOTEXIST; //no such file or directory - if (i == 13) return GE_DEVICENOPERMISSION; //permission denied - return GE_DEVICEOPENERROR; - } - -#ifdef TIOCEXCL - /* open() calls from other applications shall fail now */ - ioctl(d->hPhone, TIOCEXCL, (char *) 0); -#endif - - if (tcgetattr(d->hPhone, &d->backup_termios) == -1) { - /* Don't call serial_close since backup_termios is not valid */ - close(d->hPhone); - GSM_OSErrorInfo(s,"tcgetattr in serial_open"); - return GE_DEVICEREADERROR; - } - - if (tcflush(d->hPhone, TCIOFLUSH) == -1) { - serial_close(s); - GSM_OSErrorInfo(s,"tcflush in serial_open"); - return GE_DEVICEOPENERROR; - } - - /* Initialise the port settings */ - memcpy(&t, &d->backup_termios, sizeof(struct termios)); - - /* Set port settings for canonical input processing */ - /* 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 GE_DEVICEOPENERROR; - } - - /* Make filedescriptor asynchronous. */ - if (fcntl(d->hPhone, F_SETFL, FASYNC | FNONBLOCK) == -1) { - serial_close(s); - GSM_OSErrorInfo(s,"fcntl in serial_open"); - return GE_DEVICEOPENERROR; - } - - return GE_NONE; -} - -static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) -{ - GSM_Device_SerialData *d = &s->Device.Data.Serial; - struct termios t; - - if (tcgetattr(d->hPhone, &t)) { - GSM_OSErrorInfo(s,"tcgetattr in serial_setparity"); - return GE_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 GE_DEVICEPARITYERROR; - } - - return GE_NONE; -} - -/* Set the DTR and RTS bit of the serial device. */ -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; - - if (tcgetattr(d->hPhone, &t)) { - GSM_OSErrorInfo(s,"tcgetattr in serial_setdtrrts"); - return GE_DEVICEREADERROR; - } - -#ifdef CRTSCTS - /* Disable 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 GE_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 GE_DEVICEDTRRTSERROR; - if (((flags&TIOCM_RTS)==TIOCM_RTS) != rts) return GE_DEVICEDTRRTSERROR; - - return GE_NONE; -} - -/* Change the speed of the serial device. - * RETURNS: Success - */ -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 GE_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; - case 57600: speed2 = B57600; break; - case 115200: speed2 = B115200; break; - case 230400: speed2 = B230400; break; - } - - /* 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 GE_DEVICECHANGESPEEDERROR; - } - - return GE_NONE; -} - -/* Read from serial device. */ -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_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; -} - -/* Write to serial device. */ -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; - - do { - if ((ret = write(d->hPhone, (unsigned char *)buf, nbytes - actual)) < 0) { - if (actual!=nbytes) GSM_OSErrorInfo(s,"serial_write"); - return(actual); - } - actual += ret; - buf += ret; - } 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: - */ + +#include "../../gsmstate.h" + +#ifdef GSM_ENABLE_SERIALDEVICE +#ifndef WIN32 +#ifndef DJGPP + +#include +#include +#include +#include +#include + +#include "../../gsmcomon.h" +#include "ser_unx.h" + +/* Close the serial port and restore old settings. */ +static GSM_Error serial_close(GSM_StateMachine *s) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + + /*FIXME: error checking */ + tcsetattr(d->hPhone, TCSANOW, &d->backup_termios); + close(d->hPhone); + + return GE_NONE; +} + +#ifndef O_NONBLOCK +# define O_NONBLOCK 0 +#endif + +static GSM_Error serial_open (GSM_StateMachine *s) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + struct termios t; + int i; + + /* O_NONBLOCK MUST be used here as the CLOCAL may be currently off + * and if DCD is down the "open" syscall would be stuck wating 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 GE_DEVICENOTEXIST; //no such file or directory + if (i == 13) return GE_DEVICENOPERMISSION; //permission denied + return GE_DEVICEOPENERROR; + } + +#ifdef TIOCEXCL + /* open() calls from other applications shall fail now */ + ioctl(d->hPhone, TIOCEXCL, (char *) 0); +#endif + + if (tcgetattr(d->hPhone, &d->backup_termios) == -1) { + /* Don't call serial_close since backup_termios is not valid */ + close(d->hPhone); + GSM_OSErrorInfo(s,"tcgetattr in serial_open"); + return GE_DEVICEREADERROR; + } + + if (tcflush(d->hPhone, TCIOFLUSH) == -1) { + serial_close(s); + GSM_OSErrorInfo(s,"tcflush in serial_open"); + return GE_DEVICEOPENERROR; + } + + /* Initialise the port settings */ + memcpy(&t, &d->backup_termios, sizeof(struct termios)); + + /* Set port settings for canonical input processing */ + /* 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 GE_DEVICEOPENERROR; + } + + /* Make filedescriptor asynchronous. */ + if (fcntl(d->hPhone, F_SETFL, FASYNC | FNONBLOCK) == -1) { + serial_close(s); + GSM_OSErrorInfo(s,"fcntl in serial_open"); + return GE_DEVICEOPENERROR; + } + + return GE_NONE; +} + +static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) +{ + GSM_Device_SerialData *d = &s->Device.Data.Serial; + struct termios t; + + if (tcgetattr(d->hPhone, &t)) { + GSM_OSErrorInfo(s,"tcgetattr in serial_setparity"); + return GE_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 GE_DEVICEPARITYERROR; + } + + return GE_NONE; +} + +/* Set the DTR and RTS bit of the serial device. */ +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; + + if (tcgetattr(d->hPhone, &t)) { + GSM_OSErrorInfo(s,"tcgetattr in serial_setdtrrts"); + return GE_DEVICEREADERROR; + } + +#ifdef CRTSCTS + /* Disable 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 GE_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 GE_DEVICEDTRRTSERROR; + if (((flags&TIOCM_RTS)==TIOCM_RTS) != rts) return GE_DEVICEDTRRTSERROR; + + return GE_NONE; +} + +/* Change the speed of the serial device. + * RETURNS: Success + */ +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 GE_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; + case 57600: speed2 = B57600; break; + case 115200: speed2 = B115200; break; + case 230400: speed2 = B230400; break; + } + + /* 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 GE_DEVICECHANGESPEEDERROR; + } + + return GE_NONE; +} + +/* Read from serial device. */ +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_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; +} + +/* Write to serial device. */ +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; + + do { + if ((ret = write(d->hPhone, (unsigned char *)buf, nbytes - actual)) < 0) { + if (actual!=nbytes) GSM_OSErrorInfo(s,"serial_write"); + return(actual); + } + actual += ret; + buf += ret; + } 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/common/device/serial/ser_unx.h b/common/device/serial/ser_unx.h index a68871b51..3a0c85bef 100644 --- a/common/device/serial/ser_unx.h +++ b/common/device/serial/ser_unx.h @@ -9,8 +9,8 @@ #include typedef struct { - int hPhone; - struct termios backup_termios; /* Structure to backup the setting of the terminal. */ + int hPhone; + struct termios backup_termios; /* Structure to backup the setting of the terminal. */ } GSM_Device_SerialData; #endif diff --git a/common/device/serial/ser_w32.c b/common/device/serial/ser_w32.c index 9251b0a20..c837981c1 100644 --- a/common/device/serial/ser_w32.c +++ b/common/device/serial/ser_w32.c @@ -294,24 +294,23 @@ static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) */ if (!fWriteStat) { if(GetLastError() == ERROR_IO_PENDING) { - /* We should wait for the completion of the write operation - * so we know if it worked or not - * - * This is only one way to do this. It might be beneficial to - * place the write operation in a separate thread - * so that blocking on completion will not negatively - * affect the responsiveness of the UI - * - * If the write takes too long to complete, this - * function will timeout according to the - * CommTimeOuts.WriteTotalTimeoutMultiplier variable. - * This code logs the timeout but does not retry - * the write. - */ + /* We should wait for the completion of the write operation + * so we know if it worked or not + * + * This is only one way to do this. It might be beneficial to + * place the write operation in a separate thread + * so that blocking on completion will not negatively + * affect the responsiveness of the UI + * + * If the write takes too long to complete, this + * function will timeout according to the + * CommTimeOuts.WriteTotalTimeoutMultiplier variable. + * This code logs the timeout but does not retry + * the write. + */ while(!GetOverlappedResult(d->hPhone, &d->osWrite, &dwBytesWritten, TRUE)) { dwError = GetLastError(); - if(dwError == ERROR_IO_INCOMPLETE) - { + if(dwError == ERROR_IO_INCOMPLETE) { /* normal result if not finished */ dwBytesSent += dwBytesWritten; continue; @@ -324,10 +323,10 @@ static int serial_write(GSM_StateMachine *s, void *buf, size_t nbytes) } dwBytesSent += dwBytesWritten; } else { - GSM_OSErrorInfo(s, "serial_write"); - /* some other error occurred */ - ClearCommError(d->hPhone, &dwErrorFlags, &ComStat); - return dwBytesSent; + GSM_OSErrorInfo(s, "serial_write"); + /* some other error occurred */ + ClearCommError(d->hPhone, &dwErrorFlags, &ComStat); + return dwBytesSent; } } diff --git a/common/gsmcomon.c b/common/gsmcomon.c index 6e5331660..1d049bdd6 100644 --- a/common/gsmcomon.c +++ b/common/gsmcomon.c @@ -33,12 +33,12 @@ GSM_Error NotSupportedFunction(void) return GE_NOTSUPPORTED; } -unsigned char *GetMsg (CFG_Header *cfg, unsigned char *default_string) +unsigned char *GetMsg (INI_Section *cfg, unsigned char *default_string) { unsigned char *retval, buffer[40], buff2[40], buff[2000]; static unsigned char def_str[2000]; - CFG_Entry *e; - CFG_Header *h; + INI_Entry *e; + INI_Section *h; int num; if (cfg==NULL) return default_string; @@ -56,25 +56,25 @@ unsigned char *GetMsg (CFG_Header *cfg, unsigned char *default_string) e = NULL; /* First find our section */ - for (h = cfg; h != NULL; h = h->next) { - if (mywstrncasecmp(buff2, h->section, 0)) { - e = h->entries; + for (h = cfg; h != NULL; h = h->Next) { + if (mywstrncasecmp(buff2, h->SectionName, 0)) { + e = h->SubEntries; break; } } while (1) { if (e == NULL) break; num = -1; - DecodeUnicode(e->key,buffer); + DecodeUnicode(e->EntryName,buffer); if (strlen(buffer) == 5 && (buffer[0] == 'F' || buffer[0] == 'f')) { num = atoi(buffer+2); } if (num!=-1) { - DecodeUnicode(e->value+2,buff); + DecodeUnicode(e->EntryValue+2,buff); if (strncmp(buff,def_str,strlen(def_str))==0) { sprintf(buff,"T%04i",num); EncodeUnicode (buffer, buff, 5); - retval = CFG_Get(cfg, buff2, buffer, true); + retval = INI_GetValue(cfg, buff2, buffer, true); if (retval) { sprintf(buff,"%s",DecodeUnicodeConsole(retval+2)); buff[strlen(buff)-1] = 0; @@ -100,7 +100,7 @@ unsigned char *GetMsg (CFG_Header *cfg, unsigned char *default_string) return retval; } } - e = e->next; + e = e->Next; } return default_string; } @@ -157,7 +157,7 @@ static PrintErrorEntry PrintErrorEntries[] = { {0, ""} }; -unsigned char *print_error(GSM_Error e, FILE *df, CFG_Header *cfg) +unsigned char *print_error(GSM_Error e, FILE *df, INI_Section *cfg) { unsigned char *def = NULL; int i = 0; @@ -224,8 +224,7 @@ GSM_Error GSM_SetDebugFile(char *info, Debug_Info *privdi) dbgprintf("Can't open debug file\n"); return GE_CANTOPENFILE; } else { - if (privdi->df && privdi->df != stdout) - { + if (privdi->df && privdi->df != stdout) { fclose(privdi->df); } privdi->df = testfile; diff --git a/common/gsmcomon.h b/common/gsmcomon.h index 4ef8009c8..dda465ca5 100644 --- a/common/gsmcomon.h +++ b/common/gsmcomon.h @@ -74,8 +74,8 @@ extern GSM_Error NotSupportedFunction (void); #define NOTIMPLEMENTED (void *) NotImplementedFunction #define NOTSUPPORTED (void *) NotSupportedFunction -unsigned char *GetMsg (CFG_Header *cfg, unsigned char *default_string); -unsigned char *print_error (GSM_Error e, FILE *df, CFG_Header *cfg); +unsigned char *GetMsg (INI_Section *cfg, unsigned char *default_string); +unsigned char *print_error (GSM_Error e, FILE *df, INI_Section *cfg); GSM_Error GSM_SetDebugFile(char *info, Debug_Info *privdi); diff --git a/common/gsmstate.c b/common/gsmstate.c index d1bb9d808..e30267e2e 100644 --- a/common/gsmstate.c +++ b/common/gsmstate.c @@ -12,8 +12,7 @@ static void GSM_RegisterConnection(GSM_StateMachine *s, unsigned int connection, GSM_Device_Functions *device, GSM_Protocol_Functions *protocol) { - if ((unsigned int)s->ConnectionType == connection) - { + if ((unsigned int)s->ConnectionType == connection) { s->Device.Functions = device; s->Protocol.Functions = protocol; } @@ -700,44 +699,59 @@ GSM_Error GSM_DispatchMessage(GSM_StateMachine *s) return error; } -CFG_Header *CFG_FindGammuRC(void) +INI_Section *GSM_FindGammuRC(void) { - CFG_Header *cfg_info; - char *homedir; - char rcfile[201]; + INI_Section *ini_file; + char *HomeDrive,*HomePath,*FileName=malloc(1); + int FileNameUsed=1; + FileName[0] = 0; #if defined(WIN32) || defined(DJGPP) - homedir = getenv("HOMEDRIVE"); - strncpy(rcfile, homedir ? homedir : "", 200); - homedir = getenv("HOMEPATH"); - strncat(rcfile, homedir ? homedir : "", 200); - strncat(rcfile, "\\gammurc", 200); + 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 - homedir = getenv("HOME"); - if (homedir) strncpy(rcfile, homedir, 200); - strncat(rcfile, "/.gammurc", 200); + 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); - if ((cfg_info = CFG_ReadFile(rcfile, false)) == NULL) { + ini_file = INI_ReadFile(FileName, false); + free(FileName); + if (ini_file == NULL) { #if defined(WIN32) || defined(DJGPP) - if ((cfg_info = CFG_ReadFile("gammurc", false)) == NULL) { -// dbgprintf("CFG file - No config files. Using defaults.\n"); - return NULL; - } + ini_file = INI_ReadFile("gammurc", false); + if (ini_file == NULL) return NULL; #else - if ((cfg_info = CFG_ReadFile("/etc/gammurc", false)) == NULL) { -// dbgprintf("CFG file - No config files. Using defaults.\n"); - return NULL; - } + ini_file = INI_ReadFile("/etc/gammurc", false); + if (ini_file == NULL) return NULL; #endif } - return cfg_info; + return ini_file; } -bool CFG_ReadConfig(CFG_Header *cfg_info, GSM_Config *cfg, int num) +bool GSM_ReadConfig(INI_Section *cfg_info, GSM_Config *cfg, int num) { - CFG_Header *h; + INI_Section *h; unsigned char section[50]; bool found = false; @@ -784,59 +798,59 @@ bool CFG_ReadConfig(CFG_Header *cfg_info, GSM_Config *cfg, int num) } else { sprintf(section,"gammu%i",num); } - for (h = cfg_info; h != NULL; h = h->next) { - if (mystrncasecmp(section, h->section, strlen(section))) { + 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 = CFG_Get(cfg_info, section, "port", false); + cfg->Device = INI_GetValue(cfg_info, section, "port", false); if (!cfg->Device) { cfg->Device = DefaultPort; } else { cfg->DefaultDevice = false; } - cfg->Connection = CFG_Get(cfg_info, section, "connection", false); + cfg->Connection = INI_GetValue(cfg_info, section, "connection", false); if (!cfg->Connection) { cfg->Connection = DefaultConnection; } else { cfg->DefaultConnection = false; } - cfg->SyncTime = CFG_Get(cfg_info, section, "synchronizetime",false); + cfg->SyncTime = INI_GetValue(cfg_info, section, "synchronizetime", false); if (!cfg->SyncTime) { cfg->SyncTime = DefaultSynchronizeTime; } else { cfg->DefaultSyncTime = false; } - cfg->DebugFile = CFG_Get(cfg_info, section, "logfile", false); + cfg->DebugFile = INI_GetValue(cfg_info, section, "logfile", false); if (!cfg->DebugFile) { cfg->DebugFile = DefaultDebugFile; } else { cfg->DefaultDebugFile = false; } - cfg->LockDevice = CFG_Get(cfg_info, section, "use_locking", false); + cfg->LockDevice = INI_GetValue(cfg_info, section, "use_locking", false); if (!cfg->LockDevice) { cfg->LockDevice = DefaultLockDevice; } else { cfg->DefaultLockDevice = false; } - Temp = CFG_Get(cfg_info, section, "model", false); + Temp = INI_GetValue(cfg_info, section, "model", false); if (!Temp) { strcpy(cfg->Model,DefaultModel); } else { cfg->DefaultModel = false; strcpy(cfg->Model,Temp); } - Temp = CFG_Get(cfg_info, section, "logformat", false); + Temp = INI_GetValue(cfg_info, section, "logformat", false); if (!Temp) { strcpy(cfg->DebugLevel,DefaultDebugLevel); } else { cfg->DefaultDebugLevel = false; strcpy(cfg->DebugLevel,Temp); } - cfg->StartInfo = CFG_Get(cfg_info, section, "startinfo", false); + cfg->StartInfo = INI_GetValue(cfg_info, section, "startinfo", false); if (!cfg->StartInfo) { cfg->StartInfo = DefaultStartInfo; } else { @@ -847,7 +861,18 @@ bool CFG_ReadConfig(CFG_Header *cfg_info, GSM_Config *cfg, int num) static OnePhoneModel allmodels[] = { #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" ,"", {0}}, + {"3100b","RH-50" ,"", {0}}, + {"3200", "RH-30" ,"Nokia 3200", {0}}, + {"3200a","RH-31" ,"Nokia 3200", {0}}, #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}}, @@ -870,6 +895,9 @@ static OnePhoneModel allmodels[] = { {"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_NOKIA6510) {"3650" ,"NHL-8" ,"Nokia 3650", {F_RADIO,0}}, {"5100" ,"NPM-6" ,"Nokia 5100", {F_TODO66,F_RADIO,0}}, diff --git a/common/gsmstate.h b/common/gsmstate.h index f36b1b8a1..5b23a3bc0 100644 --- a/common/gsmstate.h +++ b/common/gsmstate.h @@ -159,7 +159,6 @@ #endif #include "service/gsmpbk.h" -#include "service/gsmsms.h" #include "service/gsmnet.h" #include "service/gsmring.h" #include "service/gsmcal.h" @@ -168,6 +167,9 @@ #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" typedef struct _GSM_StateMachine GSM_StateMachine; typedef struct _GSM_User GSM_User; @@ -1367,7 +1369,7 @@ struct _GSM_StateMachine { GSM_Config Config[5]; GSM_Config *CurrentConfig; /* Config file (or Registry or...) variables */ int ConfigNum; - CFG_Header *msg; /* Localisation strings structure */ + INI_Section *msg; /* Localisation strings structure */ int ReplyNum; /* How many times make sth. */ int Speed; /* For some protocols used speed */ @@ -1395,9 +1397,9 @@ GSM_Error GSM_WaitFor (GSM_StateMachine *s, unsigned char *buffer, GSM_Error GSM_DispatchMessage (GSM_StateMachine *s); -CFG_Header *CFG_FindGammuRC(void); +INI_Section *GSM_FindGammuRC(void); -bool CFG_ReadConfig (CFG_Header *cfg_info, GSM_Config *cfg, int num); +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); diff --git a/common/misc/cfg.c b/common/misc/cfg.c dissimilarity index 89% index d9156f331..824de7008 100644 --- a/common/misc/cfg.c +++ b/common/misc/cfg.c @@ -1,354 +1,319 @@ - -#include -#include -#include -#include -#include -#ifndef __OpenBSD__ -# include -# include -#endif - -#include "../config.h" -#include "coding/coding.h" -#include "cfg.h" -#include "misc.h" - -/* Read configuration information from a ".INI" style file */ -CFG_Header *CFG_ReadFile(char *filename, bool Unicode) -{ - FILE *handle; - unsigned char *line,*buf,ch; - CFG_Header *cfg_info = NULL, *cfg_head = NULL; - int i,pos; - bool process,FFEEUnicode=false,firstread=true; - - /* Error check */ - if (filename == NULL) return NULL; - - /* Initialisation */ - if ((buf = (char *)malloc(1400)) == NULL) return NULL; - - /* Open file */ - if ((handle = fopen(filename, "rb")) == NULL) { -// dbgprintf("CFG file - error opening \"%s\" file: %s\n", filename, strerror(errno)); - free(buf); - return NULL; - } else { -// dbgprintf("CFG file - opened file \"%s\"\n", filename ); - } - - /* Iterate over lines in the file */ - while (1) { - if (Unicode) { - /* Here is my own version of fgetws */ - pos = 0; - while (1) { - if (fread(buf+pos,1,2,handle) != 2) { - buf[pos] = 0; - buf[pos+1] = 0; - break; - } - if (firstread) { - FFEEUnicode = false; - firstread = false; - if (buf[0] == 0xFF && buf[1] == 0xFE) { - FFEEUnicode = true; - continue; - } - if (buf[0] == 0xFE && buf[1] == 0xFF) { - continue; - } - } - if (FFEEUnicode) { - ch = buf[pos]; - buf[pos] = buf[pos+1]; - buf[pos+1] = ch; - } - pos+=2; - buf[pos] = 0; - buf[pos+1] = 0; - if (buf[pos-2] == 0x00 && buf[pos-1] == 0x0a) break; - if (buf[pos-2] == 0x00 && buf[pos-1] == 0x0d) break; - if (pos == 1400) break; - } - if (pos == 0) break; - } else { - /* Here is my own version of fgets */ - pos = 0; - while (1) { - if (fread(buf+pos,1,1,handle) != 1) { - buf[pos] = 0; - break; - } - pos++; - buf[pos] = 0; - if (buf[pos-1] == 0x0a) break; - if (buf[pos-1] == 0x0d) break; - if (pos == 1400) break; - } - if (pos == 0) break; - } - - line = buf; - process = false; - - if (Unicode) { - /* Strip leading, trailing whitespace */ - while(myiswspace(line)) line+=2; - - while(1) { - i = UnicodeLength(line)*2; - if (i>0 && myiswspace(line+i-2)) - { - line[i - 2] = '\0'; - line[i - 1] = '\0'; - } else break; - } - - /* Ignore blank lines and comments */ - if ((*line == 0 && *(line+1) == 0x0a) || - (*line == 0 && *(line+1) == 0x0d) || - (*line == 0 && *(line+1) == 0) || - (*line == 0 && *(line+1) == '#')) - continue; - - /* Look for "headings" enclosed in square brackets */ - if ((line[0] == 0 && line[1] == '[') && - (line[UnicodeLength(line)*2 - 2] == 0 && - line[UnicodeLength(line)*2 - 1] == ']')) - process = true; - } else { - /* Strip leading, trailing whitespace */ - while(isspace((int) *line)) line++; - - while((strlen(line) > 0) && isspace((int) line[strlen(line) - 1])) - line[strlen(line) - 1] = '\0'; - - /* Ignore blank lines and comments */ - if ((*line == '\n') || (*line == '\0') || (*line == '#')) - continue; - - /* Look for "headings" enclosed in square brackets */ - if ((line[0] == '[') && (line[strlen(line) - 1] == ']')) process = true; - } - if (process) { - CFG_Header *heading; - - /* Allocate new heading entry */ - if ((heading = (CFG_Header *)malloc(sizeof(*heading))) == NULL) { - free(buf); - return NULL; - } - - /* Fill in fields */ - memset(heading, '\0', sizeof(*heading)); - - if (Unicode) { - line+=2; - i = UnicodeLength(line)*2; - line[i - 2] = '\0'; - line[i - 1] = '\0'; - - heading->section = (char *)malloc(UnicodeLength(line)*2+2); - memcpy(heading->section,line,UnicodeLength(line)*2+2); - } else { - line++; - line[strlen(line) - 1] = '\0'; - - heading->section = (char *)malloc(strlen(line)+1); - memcpy(heading->section,line,strlen(line)+1); - } - - /* Add to tail of list */ - heading->prev = cfg_info; - - if (cfg_info != NULL) { - cfg_info->next = heading; - } else { - /* Store copy of head of list for return value */ - cfg_head = heading; - } - - cfg_info = heading; - -// if (Unicode) dbgprintf( "CFG file - added new section \"%s\"\n", DecodeUnicodeString(heading->section)); -// printf( "CFG file - added new section \"%s\"\n", heading->section); - - /* Go on to next line */ - continue; - } - - /* Process key/value line */ - process = false; - if (Unicode) { - if ((strchr(DecodeUnicodeString(line), '=') != NULL) && cfg_info != NULL) process = true; - } else { - if ((strchr(line, '=') != NULL) && cfg_info != NULL) process = true; - } - if (process) { - CFG_Entry *entry; - char *value; - - /* Allocate new entry */ - if ((entry = (CFG_Entry *)malloc(sizeof(*entry))) == NULL) { - free(buf); - return NULL; - } - - /* Fill in fields */ - memset(entry, '\0', sizeof(*entry)); - - if (Unicode) { - value = line; - while(1) { - if (*(value) == 0 && *(value+1) == '=') break; - value += 2; - } - *(value) = 0; /* Split string */ - *(value+1) = 0; - value+=2; - - /* Remove leading white */ - while(myiswspace(value)) value+=2; - - entry->value = (char *)malloc(UnicodeLength(value)*2+2); - memcpy(entry->value,value,UnicodeLength(value)*2+2); - - while(1) { - i = UnicodeLength(line)*2; - if (i>0 && myiswspace(line+i-2)) - { - line[i - 2] = '\0'; - line[i - 1] = '\0'; - } else break; - } - - entry->key = (char *)malloc(UnicodeLength(line)*2+2); - memcpy(entry->key,line,UnicodeLength(line)*2+2); - } else { - value = strchr(line, '='); - *value = '\0'; /* Split string */ - value++; - - while(isspace((int) *value)) { /* Remove leading white */ - value++; - } - - entry->value = (char *)malloc(strlen(value)+1); - memcpy(entry->value,value,strlen(value)+1); - - while((strlen(line) > 0) && isspace((int) line[strlen(line) - 1])) { - line[strlen(line) - 1] = '\0'; /* Remove trailing white */ - } - - entry->key = (char *)malloc(strlen(line)+1); - memcpy(entry->key,line,strlen(line)+1); - } - - /* Add to head of list */ - entry->next = cfg_info->entries; - - if (cfg_info->entries != NULL) cfg_info->entries->prev = entry; - - cfg_info->entries = entry; - -// if (Unicode) { -// dbgprintf("CFG file - adding key/value \"%s/",DecodeUnicodeString(entry->key)); -// dbgprintf("%s\"\n", DecodeUnicodeString(entry->value)); -// } - - /* Go on to next line */ - continue; - } - - /* Line not part of any heading */ -// dbgprintf("CFG file - orphaned line: \"%s\"\n", line); - } - - free(buf); - - /* Return pointer to configuration information */ - return cfg_head; -} - -/* - * Find the value of a key in a config file. Return value associated - * with key or NULL if no such key exists. - */ -unsigned char *CFG_Get(CFG_Header *cfg, unsigned char *section, unsigned char *key, bool Unicode) -{ - CFG_Header *h; - CFG_Entry *e; - - if ((cfg == NULL) || (section == NULL) || (key == NULL)) { - return NULL; - } - - if (Unicode) { -// printf("searching for %s",DecodeUnicodeString(section)); -// printf("/%s\n",DecodeUnicodeString(key)); - /* Search for section name */ - for (h = cfg; h != NULL; h = h->next) { - if (mywstrncasecmp(section, h->section, 0)) { - /* Search for key within section */ - for (e = h->entries; e != NULL; e = e->next) { - if (mywstrncasecmp(key,e->key,0)) { - /* Found! */ - return e->value; - } - } - } - } - } else { - /* Search for section name */ - for (h = cfg; h != NULL; h = h->next) { - if (mystrncasecmp(section, h->section, 0)) { - /* Search for key within section */ - for (e = h->entries; e != NULL; e = e->next) { - if (mystrncasecmp(key, e->key, 0)) { - /* Found! */ - return e->value; - } - } - } - } - } - /* Key not found in section */ - return NULL; -} - -/* Return last value in specified section */ -CFG_Entry *CFG_FindLastSectionEntry(CFG_Header *file_info, unsigned char *section, bool Unicode) -{ - CFG_Header *h; - CFG_Entry *e; - - e = NULL; - /* First find our section */ - for (h = file_info; h != NULL; h = h->next) { - if (Unicode) { - if (mywstrncasecmp(section, h->section, 0)) { - e = h->entries; - break; - } - } else { - if (mystrncasecmp(section, h->section, 0)) { - e = h->entries; - break; - } - } - } - /* Goes into last value in section */ - while (1) { - if (e == NULL) break; - if (e->next != NULL) { - e = e->next; - } else break; - } - return e; -} - -/* How should editor hadle tabs in this file? Add editor commands here. - * vim: noexpandtab sw=8 ts=8 sts=8: - */ + +#include +#include +#include +#include +#include +#ifndef __OpenBSD__ +# include +# include +#endif + +#include "../config.h" +#include "coding/coding.h" +#include "cfg.h" +#include "misc.h" + +/* + * Read information from file in Windows INI format style + */ +INI_Section *INI_ReadFile(char *FileName, bool Unicode) +{ + FILE *f; + bool FFEEUnicode=false; + int level = -1, buffer1used, buffer2used, bufferused, i, buffused=1000,buffread=1000; + unsigned char ch[3], *buffer = NULL, *buffer1 = NULL, *buffer2 = NULL; + unsigned char buff[1000]; + INI_Section *INI_info = NULL, *INI_head = NULL, *heading; + INI_Entry *entry; + + f = fopen(FileName,"rb"); + if (f == NULL) return NULL; + + while(1) { + /* We read one line from file */ + bufferused = 0; + while (1) { + if (buffused == buffread) { + buffused = fread(buff,1,1000,f); + buffread = 0; + if (buffused == 0) { + free(buffer); free(buffer1); free(buffer2); + fclose(f); + return INI_head; + } + } + if (Unicode) { + ch[0] = buff[buffread++]; + if (buffused == buffread) continue; + ch[1] = buff[buffread++]; + if (buffused == buffread) continue; + if (level == -1) { + if (ch[0] == 0xFF && ch[1] == 0xFE) FFEEUnicode = true; + level = 0; + continue; + } + if (FFEEUnicode) { + ch[2] = ch[0]; ch[0] = ch[1]; ch[1] = ch[2]; + } + } else { + ch[0] = 0; + ch[1] = buff[buffread++]; + if (buffused == buffread) continue; + if (level == -1) level = 0; + } + if ((ch[0] == 0 && ch[1] == 13) || + (ch[0] == 0 && ch[1] == 10)) { + break; + } + buffer = realloc(buffer,bufferused+2); + buffer[bufferused] = ch[0]; + buffer[bufferused+1] = ch[1]; + bufferused = bufferused + 2; + } +// printf("line \"%s\"\n",DecodeUnicodeConsole(buffer)); + + buffer1used = 0; + buffer2used = 0; + if (level == 1) level = 0; + if (level == 3 || level == 4 || level == 5) level = 2; + + /* We parse read line */ + for (i=0;iSectionName = (char *)malloc(buffer1used); + memcpy(heading->SectionName,buffer1,buffer1used); + heading->Prev = INI_info; + heading->Next = NULL; + if (INI_info != NULL) { + INI_info->Next = heading; + } else { + INI_head = heading; + } + INI_info = heading; + INI_info->SubEntries = NULL; + level = 2; +// printf("[%s]\n",DecodeUnicodeConsole(buffer1)); + break; + } + if (Unicode) { + buffer1 = realloc(buffer1,buffer1used+2); + buffer1[buffer1used] = ch[0]; + buffer1[buffer1used+1] = ch[1]; + buffer1used = buffer1used + 2; + } else { + buffer1 = realloc(buffer1,buffer1used+1); + buffer1[buffer1used] = ch[1]; + buffer1used = buffer1used + 1; + } + continue; + } + if (level == 2) { //search for key name + if (ch[0] == 0 && ch[1] == ';') break; + if (ch[0] == 0 && ch[1] == '#') break; + if (ch[0] == 0 && ch[1] == '[') { + level = 1; + continue; + } + if (Unicode) { + if (myiswspace(ch)) continue; + } else { + if (isspace((int) ch[1])) continue; + } + level = 3; + } + if (level == 3) { //key name + if (ch[0] == 0 && ch[1] == '=') { + if (buffer1used == 0) break; + while(1) { + if (Unicode) { + if (!myiswspace(buffer1+(buffer1used-2))) break; + buffer1used = buffer1used - 2; + } else { + if (!isspace((int)buffer1[buffer1used-1])) break; + buffer1used = buffer1used - 1; + } + } + level = 4; + continue; + } + if (Unicode) { + buffer1 = realloc(buffer1,buffer1used+2); + buffer1[buffer1used] = ch[0]; + buffer1[buffer1used+1] = ch[1]; + buffer1used = buffer1used + 2; + } else { + buffer1 = realloc(buffer1,buffer1used+1); + buffer1[buffer1used] = ch[1]; + buffer1used = buffer1used + 1; + } + } + if (level == 4) { //search for key value + if (Unicode) { + if (myiswspace(ch)) continue; + } else { + if (isspace((int) ch[1])) continue; + } + level = 5; + } + if (level == 5) { //key value + if (Unicode) { + buffer2 = realloc(buffer2,buffer2used+2); + buffer2[buffer2used] = ch[0]; + buffer2[buffer2used+1] = ch[1]; + buffer2used = buffer2used + 2; + } else { + buffer2 = realloc(buffer2,buffer2used+1); + buffer2[buffer2used] = ch[1]; + buffer2used = buffer2used + 1; + } + } + } + if (level == 5) { + if (buffer2used == 0) continue; + + entry = (INI_Entry *)malloc(sizeof(*entry)); + if (entry == NULL) { + free(buffer); free(buffer1); free(buffer2); + fclose(f); + return NULL; + } + if (Unicode) { + buffer1 = realloc(buffer1,buffer1used+2); + buffer1[buffer1used] = 0; + buffer1[buffer1used+1] = 0; + buffer1used = buffer1used + 2; + buffer2 = realloc(buffer2,buffer2used+2); + buffer2[buffer2used] = 0; + buffer2[buffer2used+1] = 0; + buffer2used = buffer2used + 2; + } else { + buffer1 = realloc(buffer1,buffer1used+1); + buffer1[buffer1used] = 0x00; + buffer1used = buffer1used + 1; + buffer2 = realloc(buffer2,buffer2used+1); + buffer2[buffer2used] = 0x00; + buffer2used = buffer2used + 1; + } +// printf("\"%s\"=\"%s\"\n",buffer1,buffer2); +// printf("\"%s\"=",DecodeUnicodeConsole(buffer1)); +// printf("\"%s\"\n",DecodeUnicodeConsole(buffer2)); + + entry->EntryName = (char *)malloc(buffer1used); + memcpy(entry->EntryName,buffer1,buffer1used); + + entry->EntryValue = (char *)malloc(buffer2used); + memcpy(entry->EntryValue,buffer2,buffer2used); + + entry->Prev = NULL; + entry->Next = INI_info->SubEntries; + if (INI_info->SubEntries != NULL) INI_info->SubEntries->Prev = entry; + INI_info->SubEntries = entry; + } + } + free(buffer); free(buffer1); free(buffer2); + fclose(f); + return INI_head; +} + +/* + * Search for key value in file in Windows INI format style + * Returns found value or NULL + */ +unsigned char *INI_GetValue(INI_Section *cfg, unsigned char *section, unsigned char *key, bool Unicode) +{ + INI_Section *h; + INI_Entry *e; + + if (cfg == NULL || section == NULL || key == NULL) return NULL; + + if (Unicode) { + /* Search for section */ + for (h = cfg; h != NULL; h = h->Next) { + if (mywstrncasecmp(section, h->SectionName, 0)) { + /* Search for key inside section */ + for (e = h->SubEntries; e != NULL; e = e->Next) { + if (mywstrncasecmp(key,e->EntryName,0)) { + return e->EntryValue; + } + } + } + } + } else { + /* Search for section */ + for (h = cfg; h != NULL; h = h->Next) { +// printf("[%s]\n",h->SectionName); + if (mystrncasecmp(section, h->SectionName, 0)) { + /* Search for key inside section */ + for (e = h->SubEntries; e != NULL; e = e->Next) { +// printf("\"%s\"=\"%s\"\n",e->EntryName,e->EntryValue); + if (mystrncasecmp(key, e->EntryName, 0)) { + return e->EntryValue; + } + } + } + } + } + return NULL; +} + +/* Return last value in specified section */ +INI_Entry *INI_FindLastSectionEntry(INI_Section *file_info, unsigned char *section, bool Unicode) +{ + INI_Section *h; + INI_Entry *e; + + e = NULL; + /* First find our section */ + for (h = file_info; h != NULL; h = h->Next) { + if (Unicode) { + if (mywstrncasecmp(section, h->SectionName, 0)) { + e = h->SubEntries; + break; + } + } else { + if (mystrncasecmp(section, h->SectionName, 0)) { + e = h->SubEntries; + break; + } + } + } + /* Goes into last value in section */ + while (1) { + if (e == NULL) break; + if (e->Next != NULL) { + e = e->Next; + } else break; + } + return e; +} + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/common/misc/cfg.h b/common/misc/cfg.h dissimilarity index 82% index 7bba7e721..295a9a134 100644 --- a/common/misc/cfg.h +++ b/common/misc/cfg.h @@ -1,37 +1,43 @@ - -#ifndef _CFGREADER_H -#define _CFGREADER_H - -#include "misc.h" - -/* Structure definitions */ - -/* A linked list of key/value pairs */ - -typedef struct _CFG_Entry CFG_Entry; - -struct _CFG_Entry { - CFG_Entry *next, *prev; - unsigned char *key; - unsigned char *value; -}; - -typedef struct _CFG_Header CFG_Header; - -struct _CFG_Header { - CFG_Header *next, *prev; - CFG_Entry *entries; - unsigned char *section; -}; - -/* Function prototypes */ - -CFG_Header *CFG_ReadFile(char *filename, bool Unicode); -unsigned char *CFG_Get(CFG_Header *cfg, unsigned char *section, unsigned char *key, bool Unicode); -CFG_Entry *CFG_FindLastSectionEntry(CFG_Header *file_info, unsigned char *section, bool Unicode); - -#endif /* _CFGREADER_H */ - -/* How should editor hadle tabs in this file? Add editor commands here. - * vim: noexpandtab sw=8 ts=8 sts=8: - */ + +#ifndef _INI_READER_H +#define _INI_READER_H + +#include "misc.h" + +/* -------------------------------- structures ----------------------------- */ + +typedef struct _INI_Entry INI_Entry; + +/* + * Structure used to save value for single key in INI style file + */ +struct _INI_Entry { + INI_Entry *Next, *Prev; + + unsigned char *EntryName; + unsigned char *EntryValue; +}; + +typedef struct _INI_Section INI_Section; + +/* + * Structure used to save section in INI style file + */ +struct _INI_Section { + INI_Section *Next, *Prev; + INI_Entry *SubEntries; + + unsigned char *SectionName; +}; + +/* ------------------------- function prototypes --------------------------- */ + +INI_Section *INI_ReadFile (char *FileName, bool Unicode); +INI_Entry *INI_FindLastSectionEntry (INI_Section *file_info, unsigned char *section, bool Unicode); +unsigned char *INI_GetValue (INI_Section *cfg, unsigned char *section, unsigned char *key, bool Unicode); + +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/common/misc/coding/coding.c b/common/misc/coding/coding.c index 374ad7455..01708edeb 100644 --- a/common/misc/coding/coding.c +++ b/common/misc/coding/coding.c @@ -236,7 +236,7 @@ void EncodeHexBin (unsigned char *dest, const unsigned char *src, int len) dest[current++] = 0; } -/* ETSI GSM 03.38, version 6.0.1, section 6.2.1; Default alphabet */ +/* ETSI GSM 03.38, section 6.2.1: Default alphabet for SMS messages */ static unsigned char GSM_DefaultAlphabetUnicode[128+1][2] = { {0x00,0x40},{0x00,0xa3},{0x00,0x24},{0x00,0xA5}, @@ -490,6 +490,7 @@ void FindDefaultAlphabetLen(const unsigned char *src, int *srclen, int *smslen, int GSM_UnpackEightBitsToSeven(int offset, int in_length, int out_length, unsigned char *input, unsigned char *output) { +#ifndef ENABLE_LGPL unsigned char *OUTPUT = output; /* Current pointer to the output buffer */ unsigned char *INPUT = input; /* Current pointer to the input buffer */ unsigned char Rest = 0x00; @@ -523,10 +524,14 @@ int GSM_UnpackEightBitsToSeven(int offset, int in_length, int out_length, } return OUTPUT - output; +#else + return 0; +#endif } int GSM_PackSevenBitsToEight(int offset, unsigned char *input, unsigned char *output, int length) { +#ifndef ENABLE_LGPL unsigned char *OUTPUT = output; /* Current pointer to the output buffer */ unsigned char *INPUT = input; /* Current pointer to the input buffer */ int Bits; /* Number of bits directly copied to @@ -556,6 +561,9 @@ int GSM_PackSevenBitsToEight(int offset, unsigned char *input, unsigned char *ou INPUT++; } return (OUTPUT - output); +#else + return 0; +#endif } void GSM_UnpackSemiOctetNumber(unsigned char *retval, unsigned char *Number, bool semioctet) @@ -593,8 +601,9 @@ void GSM_UnpackSemiOctetNumber(unsigned char *retval, unsigned char *Number, boo EncodeUnicode(retval,Buffer,strlen(Buffer)); } -/* This function implements packing of numbers (SMS Center number and - destination number) for SMS sending function. */ +/* Packing of numbers (SMS Center number and destination number) for SMS + * sending function. + */ /* See GSM 03.40 9.1.1: 1 byte - length of number given in semioctets or bytes (when given in bytes, includes one byte for byte with number format. @@ -628,11 +637,10 @@ int GSM_PackSemiOctetNumber(unsigned char *Number, unsigned char *Output, bool s } /* The first byte in the Semi-octet representation of the address field is - * the Type-of-Address. This field is described in the official GSM - * specification 03.40 version 5.3.0, section 9.1.2.5, page 33.*/ + * the Type-of-Address. GSM 03.40 section 9.1.2.5 */ *OUTPUT++=format; - /* The next field is the number. See GSM 03.40 section 9.1.2 */ + /* Now we will have number. GSM 03.40 section 9.1.2 */ switch (format) { case GNT_ALPHANUMERIC: length=GSM_PackSevenBitsToEight(0, buffer, OUTPUT, strlen(buffer))*2; diff --git a/common/misc/misc.c b/common/misc/misc.c index 2b6735ddb..2535d7fa1 100644 --- a/common/misc/misc.c +++ b/common/misc/misc.c @@ -212,13 +212,13 @@ char *OSDate (GSM_DateTime dt) /* If don't have weekday name, include it */ strftime(retval, 200, "%A", &timeptr); if (strstr(retval2,retval)==NULL) { - /* Check also for short name */ - strftime(retval, 200, "%a", &timeptr); - if (strstr(retval2,retval)==NULL) { - strcat(retval2," ("); - strcat(retval2,retval); - strcat(retval2,")"); - } + /* Check also for short name */ + strftime(retval, 200, "%a", &timeptr); + if (strstr(retval2,retval)==NULL) { + strcat(retval2," ("); + strcat(retval2,retval); + strcat(retval2,")"); + } } #ifdef WIN32 @@ -228,14 +228,16 @@ char *OSDate (GSM_DateTime dt) return retval2; } -bool CheckDate(GSM_DateTime *date) { +bool CheckDate(GSM_DateTime *date) +{ /* FIXME: This could also check if day is correct for selected month */ return date->Year != 0 && date->Month >= 1 && date->Month <= 12 && date->Day >= 1 && date->Day <= 31; } -bool CheckTime(GSM_DateTime *date) { +bool CheckTime(GSM_DateTime *date) +{ return date->Hour <= 23 && date->Hour >= 0 && date->Minute <= 59 && date->Minute >= 0 && date->Second <= 59 && date->Second >= 0; @@ -358,8 +360,7 @@ int smfprintf(FILE *f, const char *format, ...) va_start(argp, format); result = vsprintf(buffer, format, argp); strcat(nextline, buffer); - if (strstr(buffer, "\n")) - { + if (strstr(buffer, "\n")) { if (ftell(f) < 5000000) { GSM_GetCurrentDateTime(&date_time); if (linecount > 0) { @@ -406,35 +407,36 @@ bool GSM_SetDebugLevel(char *info, Debug_Info *di) /* Dumps a message */ void DumpMessage(FILE *df, const unsigned char *message, int messagesize) { - int i; - char buf[17]; + int i,j=0,len=16; + unsigned char buffer[200]; if (df==NULL || messagesize == 0) return; - buf[16] = 0; + smfprintf(df, "\n"); + + memset(buffer,0x20,sizeof(buffer)); + buffer[len*5-1]=0; for (i = 0; i < messagesize; i++) { - if (i % 16 == 0) { - if (i != 0) smfprintf(df, " %s", buf); - smfprintf(df, "\n"); - memset(buf, ' ', 16); + sprintf(buffer+j*4,"%02x",message[i]); + buffer[j*4+2] = 0x20; + if (isprint(message[i]) && message[i]!=0x09) { + if (j != len-1) buffer[j*4+2] = message[i]; + buffer[(len-1)*4+j+3] = message[i]; } else { - smfprintf(df, "|"); + buffer[(len-1)*4+j+3] = '.'; } - smfprintf(df, "%02x", message[i]); - if (isprint(message[i]) && message[i]!=0x09) { - if ((i+1) % 16 != 0) smfprintf(df, "%c", message[i]); - buf[i % 16] = message[i]; + if (j != len-1 && i != messagesize-1) buffer[j*4+3] = '|'; + if (j == len-1) { + smfprintf(df,"%s\n",buffer); + memset(buffer,0x20,sizeof(buffer)); + buffer[len*5-1]=0; + j = 0; } else { - if ((i+1) % 16 != 0) smfprintf(df, " "); - buf[i % 16] = '.'; + j++; } } - if (i % 16 == 0) { - smfprintf(df, " %s", buf); - } else { - smfprintf(df, "%*s %s", 4 * (16 - i % 16) - 1, "", buf); - } + if (j != 0) smfprintf(df,"%s",buffer); smfprintf(df, "\n"); } diff --git a/common/misc/misc.h b/common/misc/misc.h index e400e209a..9dae75a21 100644 --- a/common/misc/misc.h +++ b/common/misc/misc.h @@ -86,16 +86,20 @@ bool GSM_SetDebugLevel(char *info, Debug_Info *di); /* ------------------------------------------------------------------------- */ -/* Structure used for passing dates/times to date/time functions such as - GSM_GetTime and GSM_GetAlarm etc. */ +/** + * Structure used for saving date and time + */ typedef struct { - unsigned int Year; /* The complete year specification - e.g.1999.Y2K :-) */ - unsigned int Month; /* January = 1 */ + /* Complete year number */ + unsigned int Year; + /* January = 1 */ + unsigned int Month; unsigned int Day; unsigned int Hour; unsigned int Minute; unsigned int Second; - int Timezone; /* The difference between local time and GMT */ + /* The difference between local time and GMT */ + int Timezone; } GSM_DateTime; void GSM_GetCurrentDateTime (GSM_DateTime *Date); @@ -105,8 +109,8 @@ char *DayOfWeek (int year, int month, int day); time_t Fill_Time_T (GSM_DateTime DT, int TZ); void GetTimeDifference (unsigned long diff, GSM_DateTime *DT, bool Plus, int multi); void Fill_GSM_DateTime (GSM_DateTime *Date, time_t timet); -bool CheckDate (GSM_DateTime *date); -bool CheckTime (GSM_DateTime *date); +bool CheckDate (GSM_DateTime *date); +bool CheckTime (GSM_DateTime *date); #endif diff --git a/common/phone/alcatel/alcatel.c b/common/phone/alcatel/alcatel.c index 5a968c022..aaee39141 100644 --- a/common/phone/alcatel/alcatel.c +++ b/common/phone/alcatel/alcatel.c @@ -28,7 +28,7 @@ #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" #include "../../misc/misc.h" -#include "../../service/gsmsms.h" +#include "../../service/sms/gsmsms.h" #include "../pfunc.h" #include "alcatel.h" @@ -98,6 +98,8 @@ extern GSM_Error ATGEN_SetAutoNetworkLogin (GSM_StateMachine *s); extern GSM_Error ATGEN_DeleteAllMemory (GSM_StateMachine *s, GSM_MemoryType type); extern GSM_Error ATGEN_DispatchMessage (GSM_StateMachine *s); +extern GSM_Error ATGEN_SetIncomingCB (GSM_StateMachine *s, bool enable); +extern GSM_Error ATGEN_SetIncomingSMS (GSM_StateMachine *s, bool enable); /** * Alcatel uses some 8-bit characters in contacts, calendar etc.. This table @@ -3719,6 +3721,21 @@ static GSM_Error ALCATEL_ReplyCommit(GSM_Protocol_Message msg, GSM_StateMachine return GE_NONE; } +static GSM_Error ALCATEL_SetIncomingCB (GSM_StateMachine *s, bool enable) +{ + GSM_Error error; + + if ((error = ALCATEL_SetATMode(s))!= GE_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))!= GE_NONE) return error; + return ATGEN_SetIncomingSMS(s, enable); +} static GSM_Reply_Function ALCATELReplyFunctions[] = { {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelAttach }, @@ -3807,8 +3824,8 @@ GSM_Phone_Functions ALCATELPhone = { ALCATEL_AddSMS, ALCATEL_DeleteSMS, ALCATEL_SendSMS, - NOTIMPLEMENTED, /* SetIncomingSMS */ - NOTIMPLEMENTED, /* SetIncomingCB */ + ALCATEL_SetIncomingSMS, + ALCATEL_SetIncomingCB, ALCATEL_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ diff --git a/common/phone/at/atgen.c b/common/phone/at/atgen.c index d384e4697..aeb45ff65 100644 --- a/common/phone/at/atgen.c +++ b/common/phone/at/atgen.c @@ -9,7 +9,7 @@ #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" -#include "../../service/gsmsms.h" +#include "../../service/sms/gsmsms.h" #include "../pfunc.h" #include "atgen.h" @@ -44,106 +44,106 @@ extern GSM_Error SONYERIC_DelCalendarNote (GSM_StateMachine *s, GSM_CalendarEntr extern GSM_Error SONYERIC_GetCalendarStatus (GSM_StateMachine *s, GSM_CalendarStatus *Status); typedef struct { - int Number; - char Text[60]; + 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, ""} + /* + * 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, ""} }; GSM_Error ATGEN_HandleCMSError(GSM_StateMachine *s) { - GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + 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: + 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: case 305: return GE_BUG; case 311: @@ -158,7 +158,7 @@ GSM_Error ATGEN_HandleCMSError(GSM_StateMachine *s) return GE_INVALIDLOCATION; default: return GE_UNKNOWN; - } + } } /* FIXME: Function doesn't respect quoting of parameters and thus +FOO: @@ -279,6 +279,7 @@ GSM_Error ATGEN_GenericReply(GSM_Protocol_Message msg, GSM_StateMachine *s) case AT_Reply_Connect: return GE_NONE; case AT_Reply_Error: + return GE_UNKNOWN; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); case AT_Reply_CMEError: @@ -1157,7 +1158,8 @@ GSM_Error ATGEN_GetIMEI (GSM_StateMachine *s) GSM_Error ATGEN_ReplyAddSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { - char *start; + char *start; + int i; if (s->Protocol.Data.AT.EditMode) { s->Protocol.Data.AT.EditMode = false; @@ -1167,8 +1169,11 @@ GSM_Error ATGEN_ReplyAddSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: smprintf(s, "SMS saved OK\n"); - start = strstr(msg.Buffer, "+CMGW: ") + 7; - s->Phone.Data.SaveSMSMessage->Location = atoi(start); + for(i=0;iPhone.Data.SaveSMSMessage->Location = atoi(start+7); smprintf(s, "Saved at location %i\n",s->Phone.Data.SaveSMSMessage->Location); return GE_NONE; case AT_Reply_Error: @@ -1608,15 +1613,18 @@ GSM_Error ATGEN_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) return GSM_WaitFor (s, "AT+CSCA?\r", 9, 0x00, 4, ID_GetSMSC); } -GSM_Error ATGEN_ReplyIncomingLAC_CID(GSM_Protocol_Message msg, GSM_StateMachine *s) -{ - smprintf(s, "Incoming LAC & CID info\n"); - return GE_NONE; -} - GSM_Error ATGEN_ReplyGetNetworkLAC_CID(GSM_Protocol_Message msg, GSM_StateMachine *s) { - GSM_NetworkInfo *NetworkInfo = s->Phone.Data.NetworkInfo; + 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 GE_NONE; + } switch (s->Phone.Data.Priv.ATGEN.ReplyState) { case AT_Reply_OK: @@ -1627,9 +1635,22 @@ GSM_Error ATGEN_ReplyGetNetworkLAC_CID(GSM_Protocol_Message msg, GSM_StateMachin return GE_UNKNOWNRESPONSE; } + SplitLines(GetLineString(msg.Buffer,Priv->Lines,2), + strlen(GetLineString(msg.Buffer,Priv->Lines,2)), + &Lines, ",", 1, true); + + /* Find number of lines */ + while (1) { + if (Lines.numbers[i*2+1]==0) break; + /* 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); #ifdef DEBUG - switch (msg.Buffer[20]) { + 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; @@ -1639,19 +1660,28 @@ GSM_Error ATGEN_ReplyGetNetworkLAC_CID(GSM_Protocol_Message msg, GSM_StateMachin default : smprintf(s, "Unknown\n"); } #endif - switch (msg.Buffer[20]) { + 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_NoNetwork; break; - case '4': NetworkInfo->State = GSM_NoNetwork; 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_NoNetwork; break; + default : NetworkInfo->State = GSM_NetworkStatusUnknown;break; } if (NetworkInfo->State == GSM_HomeNetwork || NetworkInfo->State == GSM_RoamingNetwork) { - sprintf(NetworkInfo->CellID, "%c%c%c%c", msg.Buffer[23], msg.Buffer[24], msg.Buffer[25], msg.Buffer[26]); - sprintf(NetworkInfo->LAC, "%c%c%c%c", msg.Buffer[30], msg.Buffer[31], msg.Buffer[32], msg.Buffer[33]); + memset(NetworkInfo->CellID,0,4); + memset(NetworkInfo->LAC,0,4); + + if (Lines.numbers[3*2+1]==0) return GE_NONE; + + answer = GetLineString(GetLineString(msg.Buffer,Priv->Lines,2),Lines,3); + sprintf(NetworkInfo->CellID, "%c%c%c%c", answer[1], answer[2], answer[3], answer[4]); + + answer = GetLineString(GetLineString(msg.Buffer,Priv->Lines,2),Lines,4); + sprintf(NetworkInfo->LAC, "%c%c%c%c", answer[1], answer[2], answer[3], answer[4]); + smprintf(s, "CellID: %s\n",NetworkInfo->CellID); smprintf(s, "LAC : %s\n",NetworkInfo->LAC); } @@ -1707,7 +1737,9 @@ GSM_Error ATGEN_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo) smprintf(s, "Enable full network info\n"); error=GSM_WaitFor(s, "AT+CREG=2\r", 10, 0x00, 4, ID_GetNetworkInfo); - if ((error != GE_NONE) && (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens)) return error; + if ((error != GE_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); @@ -1869,7 +1901,7 @@ GSM_Error ATGEN_ReplyGetCPBRMemoryStatus(GSM_Protocol_Message msg, GSM_StateMach switch (Priv->ReplyState) { case AT_Reply_OK: - smprintf(s, "Memory status received\n"); + smprintf(s, "Memory entries received\n"); /* Walk through lines with +CPBR: */ while (Priv->Lines.numbers[line*2+1]!=0) { str = GetLineString(msg.Buffer,Priv->Lines,line+1); @@ -1919,7 +1951,7 @@ GSM_Error ATGEN_GetMemoryInfo(GSM_StateMachine *s, GSM_MemoryStatus *Status) Status->Free = Size - Status->Used; return GE_NONE; } - start = end + 1; + start = end + 1; } } @@ -2218,9 +2250,17 @@ GSM_Error ATGEN_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode Code) unsigned char req[50]; switch (Code.Type) { - case GSCT_Pin : sprintf(req, "AT+CPIN=\"%s\"\r" , Code.Code); break; - case GSCT_Pin2 : sprintf(req, "AT+CPIN2=\"%s\"\r", Code.Code); break; - default : return GE_NOTIMPLEMENTED; + case GSCT_Pin : + sprintf(req, "AT+CPIN=\"%s\"\r" , Code.Code); + break; + case GSCT_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 GE_NOTIMPLEMENTED; } smprintf(s, "Entering security code\n"); @@ -2583,43 +2623,34 @@ GSM_Error ATGEN_ReplyIncomingCallInfo(GSM_Protocol_Message msg, GSM_StateMachine char num[128]; GSM_Call call; - call.CallIDAvailable = false; - num[0] = 0; smprintf(s, "Incoming call info\n"); - if (strstr(msg.Buffer, "RING")) { - call.Status = GN_CALL_IncomingCall; - Extract_CLIP_number(num, msg.Buffer); - } else if (strstr(msg.Buffer, "NO CARRIER")) { - call.Status = GN_CALL_CallEnd; - } else if (strstr(msg.Buffer, "COLP:")) { - call.Status = GN_CALL_CallStart; - Extract_CLIP_number(num, msg.Buffer); - } else { - smprintf(s, "CLIP: error\n"); - return GE_NONE; - } - EncodeUnicode(call.PhoneNumber, num, strlen(num)); - - if (s->Phone.Data.EnableIncomingCall && s->User.IncomingCall!=NULL) s->User.IncomingCall(s->CurrentConfig->Device, call); - - return GE_NONE; -} - -GSM_Error ATGEN_IncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) -{ -/* GSM_SMSMessage sms; */ + if (s->Phone.Data.EnableIncomingCall && s->User.IncomingCall!=NULL) { + call.CallIDAvailable = false; + num[0] = 0; + if (strstr(msg.Buffer, "RING")) { + call.Status = GN_CALL_IncomingCall; + Extract_CLIP_number(num, msg.Buffer); + } else if (strstr(msg.Buffer, "NO CARRIER")) { + call.Status = GN_CALL_CallEnd; + } else if (strstr(msg.Buffer, "COLP:")) { + call.Status = GN_CALL_CallStart; + Extract_CLIP_number(num, msg.Buffer); + } else { + smprintf(s, "CLIP: error\n"); + return GE_NONE; + } + EncodeUnicode(call.PhoneNumber, num, strlen(num)); - smprintf(s, "Incoming SMS\n"); -/* if (User->IncomingSMS) User->IncomingSMS(Data->Device, sms); */ + s->User.IncomingCall(s->CurrentConfig->Device, call); + } return GE_NONE; } GSM_Error ATGEN_IncomingGPRS(GSM_Protocol_Message msg, GSM_StateMachine *s) { - smprintf(s, "GPRS change\n"); /* "+CGREG: 1,1" */ - + smprintf(s, "GPRS change\n"); return GE_NONE; } @@ -2632,9 +2663,6 @@ GSM_Error ATGEN_IncomingBattery(GSM_Protocol_Message msg, GSM_StateMachine *s) p = strstr(msg.Buffer, "_OBS:"); if (p) level = atoi(p + 5); smprintf(s, "Battery level changed to %d\n", level); - -/* if (User->BattChange) User->BattChange(level); */ - return GE_NONE; } @@ -2647,9 +2675,6 @@ GSM_Error ATGEN_IncomingNetworkLevel(GSM_Protocol_Message msg, GSM_StateMachine p = strstr(msg.Buffer, "_OSIGQ: "); if (p) level = atoi(p + 7); smprintf(s, "Network level changed to %d\n", level); - -/* if (User->SignalChange) User->SignalChange(level); */ - return GE_NONE; } @@ -2841,9 +2866,8 @@ GSM_Error ATGEN_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) GSM_Error ATGEN_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press) { - unsigned char Frame[] = "AT+CKPD=\"?\"\r"; - - return GE_NOTIMPLEMENTED; + GSM_Error error; + unsigned char Frame[] = "AT+CKPD=\"?\"\r"; if (Press) { switch (Key) { @@ -2871,76 +2895,242 @@ GSM_Error ATGEN_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press) default : return GE_NOTSUPPORTED; } smprintf(s, "Pressing key\n"); - return GSM_WaitFor (s, Frame, 12, 0x00, 4, ID_PressKey); + error = GSM_WaitFor (s, Frame, 12, 0x00, 4, ID_PressKey); + if (error != GE_NONE) return error; + + /* Strange. My T310 needs it */ + return GSM_WaitFor (s, "ATE1\r", 5, 0x00, 4, ID_EnableEcho); } else { return GE_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 GE_NONE; + + DecodeHexBin (Buffer,msg.Buffer+6,msg.Length-6); + DumpMessage(stdout,Buffer,msg.Length-6); + + CB.Channel = Buffer[4]; + + for (j=0;jPhone.Data.EnableIncomingCB && s->User.IncomingCB!=NULL) { + s->User.IncomingCB(s->CurrentConfig->Device,CB); + } + return GE_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 GE_NONE; +#else + return GE_SOURCENOTAVAILABLE; +#endif +} + +GSM_Error ATGEN_IncomingSMSInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + smprintf(s, "Incoming SMS\n"); + return GE_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 = GSM_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 (1) { + if (Data->Priv.ATGEN.Lines.numbers[i*2+1]==0) break; + /* 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;iUser.IncomingSMS(s->CurrentConfig->Device,sms); + } + return GE_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 GE_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 GE_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 GE_NONE; +} + GSM_Reply_Function ATGENReplyFunctions[] = { -{ATGEN_ReplyOK, "OK" ,0x00,0x00,ID_IncomingFrame }, +{ATGEN_GenericReply, "AT\r" ,0x00,0x00,ID_IncomingFrame }, +{ATGEN_GenericReply, "ATE1" ,0x00,0x00,ID_EnableEcho }, +{ATGEN_GenericReply, "AT+CKPD=" ,0x00,0x00,ID_PressKey }, +{ATGEN_ReplyGetSIMIMSI, "AT+CIMI" ,0x00,0x00,ID_GetSIMIMSI }, +{ATGEN_GenericReply, "AT*EOBEX" ,0x00,0x00,ID_SetOBEX }, + +#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_ReplyGetSignalQuality, "AT+CSQ" ,0x00,0x00,ID_GetSignalQuality }, + {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_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_GenericReply, "AT+CPMS" ,0x00,0x00,ID_SetMemoryType }, -{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_ReplyAddSMSMessage, "AT+CMGW" ,0x00,0x00,ID_SaveSMSMessage }, {ATGEN_GenericReply, "AT+CSMP" ,0x00,0x00,ID_SetSMSParameters }, -{ATGEN_ReplySendSMS, "AT+CMGS" ,0x00,0x00,ID_IncomingFrame }, {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_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_ReplyGetDateTime_Alarm, "AT+CALA?" ,0x00,0x00,ID_GetAlarm }, {ATGEN_GenericReply, "AT+CCLK=" ,0x00,0x00,ID_SetDateTime }, -{ATGEN_GenericReply, "AT+CKPD=" ,0x00,0x00,ID_PressKey }, -{ATGEN_ReplyGetSMSC, "AT+CSCA?" ,0x00,0x00,ID_GetSMSC }, -{ATGEN_GenericReply, "AT+CREG=2" ,0x00,0x00,ID_GetNetworkInfo }, -{ATGEN_ReplyIncomingLAC_CID, "\x0D\x0A+CREG?" ,0x00,0x00,ID_IncomingFrame }, +{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 }, {ATGEN_ReplyGetCPBRMemoryInfo, "AT+CPBR=?" ,0x00,0x00,ID_GetMemoryStatus }, {ATGEN_ReplyGetCPBRMemoryStatus,"AT+CPBR=" ,0x00,0x00,ID_GetMemoryStatus }, {ATGEN_GenericReply, "AT+CSCS=" ,0x00,0x00,ID_SetMemoryCharset }, -{ATGEN_GenericReply, "ATE1" ,0x00,0x00,ID_SetSMSParameters }, -{ATGEN_GenericReply, "\x1b\x0D" ,0x00,0x00,ID_SetSMSParameters }, {ATGEN_ReplyGetMemory, "AT+CPBR=" ,0x00,0x00,ID_GetMemory }, {ATGEN_GenericReply, "AT^SBNR=?" ,0x00,0x00,ID_GetMemory }, {ATGEN_SL45ReplyGetMemory, "AT^SBNR" ,0x00,0x00,ID_GetMemory }, +{ATGEN_ReplySetMemory, "AT+CPBW" ,0x00,0x00,ID_SetMemory }, + {ATGEN_CMS35ReplyGetBitmap, "AT^SBNR=\"bmp\"" ,0x00,0x00,ID_GetBitmap }, {ATGEN_CMS35ReplySetBitmap, "AT^SBNW=\"bmp\"" ,0x00,0x00,ID_SetBitmap }, + {ATGEN_CMS35ReplyGetRingtone, "AT^SBNR=\"mid\"" ,0x00,0x00,ID_GetRingtone }, {ATGEN_CMS35ReplySetRingtone, "AT^SBNW=\"mid\"" ,0x00,0x00,ID_SetRingtone }, + {ATGEN_CMS35ReplyGetNextCal, "AT^SBNR=\"vcs\"" ,0x00,0x00,ID_GetCalendarNote }, {ATGEN_CMS35ReplySetCalendar, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_SetCalendarNote }, {ATGEN_CMS35ReplyDeleteCalendar,"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_ReplyDialVoice, "ATDT" ,0x00,0x00,ID_DialVoice }, +{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+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 }, -{ATGEN_GenericReply, "AT+VTS" ,0x00,0x00,ID_SendDTMF }, -{ATGEN_ReplyDeleteSMSMessage, "AT+CMGD" ,0x00,0x00,ID_DeleteSMSMessage }, -{ATGEN_ReplySetMemory, "AT+CPBW" ,0x00,0x00,ID_SetMemory }, -{ATGEN_GenericReply, "AT+CLIP=1" ,0x00,0x00,ID_IncomingFrame }, -{ATGEN_ReplyGetSIMIMSI, "AT+CIMI" ,0x00,0x00,ID_GetSIMIMSI }, -{ATGEN_GenericReply, "AT\r" ,0x00,0x00,ID_IncomingFrame }, #ifdef GSM_ENABLE_ALCATEL /* Why do I give Alcatel specific things here? It's simple, Alcatel needs @@ -2950,35 +3140,11 @@ GSM_Reply_Function ATGENReplyFunctions[] = { * 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 }, +{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 -{ATGEN_GenericReply, "ATE1" ,0x00,0x00, ID_EnableEcho }, - -{ATGEN_ReplyIncomingCallInfo, "+CLIP" ,0x00,0x00,ID_IncomingFrame }, -{ATGEN_ReplyIncomingCallInfo, "\x0D\x0ARING" ,0x00,0x00,ID_IncomingFrame }, -{ATGEN_ReplyIncomingCallInfo, "\x0D\x0A+COLP:" ,0x00,0x00,ID_IncomingFrame }, -{ATGEN_ReplyIncomingCallInfo, "\x0D\x0ANO CARRIER" ,0x00,0x00,ID_IncomingFrame }, - -{ATGEN_IncomingNetworkLevel, "\x0D\x0A_OSIGQ:" ,0x00,0x00,ID_IncomingFrame }, -{ATGEN_IncomingNetworkLevel, "_OSIGQ:" ,0x00,0x00,ID_IncomingFrame }, - -{ATGEN_IncomingGPRS, "\x0D\x0A+CGREG:" ,0x00,0x00,ID_IncomingFrame }, -{ATGEN_IncomingGPRS, "+CGREG:" ,0x00,0x00,ID_IncomingFrame }, - -{ATGEN_IncomingBattery, "\x0D\x0A_OBS:" ,0x00,0x00,ID_IncomingFrame }, -{ATGEN_IncomingBattery, "_OBS:" ,0x00,0x00,ID_IncomingFrame }, - -{ATGEN_IncomingSMS, "\x0D\x0A+CMTI:" ,0x00,0x00,ID_IncomingFrame }, -{ATGEN_IncomingSMS, "+CMTI:" ,0x00,0x00,ID_IncomingFrame }, - -{ATGEN_IncomingSMSCInfo, "\x0D\x0A^SCN:" ,0x00,0x00,ID_IncomingFrame }, -{ATGEN_IncomingSMSCInfo, "^SCN:" ,0x00,0x00,ID_IncomingFrame }, - -{ATGEN_GenericReply, "AT*EOBEX" ,0x00,0x00,ID_SetOBEX }, - {NULL, "\x00" ,0x00,0x00,ID_None } }; @@ -3035,8 +3201,8 @@ GSM_Phone_Functions ATGENPhone = { ATGEN_AddSMS, ATGEN_DeleteSMS, ATGEN_SendSMS, - NOTIMPLEMENTED, /* SetIncomingSMS */ - NOTIMPLEMENTED, /* SetIncomingCB */ + ATGEN_SetIncomingSMS, + ATGEN_SetIncomingCB, ATGEN_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ diff --git a/common/phone/at/atgen.h b/common/phone/at/atgen.h index ee8a13b36..eb4b780e6 100644 --- a/common/phone/at/atgen.h +++ b/common/phone/at/atgen.h @@ -4,7 +4,7 @@ #include "../../gsmcomon.h" #include "../../gsmstate.h" -#include "../../service/gsmsms.h" +#include "../../service/sms/gsmsms.h" #ifndef GSM_USED_AT # define GSM_USED_AT @@ -61,26 +61,26 @@ typedef enum { #define AT_PBK_MAX_MEMORIES 200 typedef struct { - GSM_AT_Manufacturer Manufacturer; /* Who is manufacturer */ - GSM_Lines Lines; /* Allow to simply get each line in response */ - GSM_AT_Reply_State ReplyState; /* What response type - error, OK, etc. */ - int ErrorCode; /* Error codes from responses */ - char *ErrorText; /* Error description */ - - GSM_MemoryType PBKMemory; /* Last read PBK memory */ - char PBKMemories[AT_PBK_MAX_MEMORIES + 1]; /* Supported by phone PBK memories */ - int NextMemoryEntry; /* Next empty memory entry */ - GSM_AT_PBK_Charset PBKCharset; /* Last read PBK charset */ - bool UCS2CharsetFailed;/* Whether setting of UCS2 charset has already failed */ - bool NonUCS2CharsetFailed;/* Whether setting of non-UCS2 charset has already failed */ + GSM_AT_Manufacturer Manufacturer; /* Who is manufacturer */ + GSM_Lines Lines; /* Allow to simply get each line in response */ + GSM_AT_Reply_State ReplyState; /* What response type - error, OK, etc. */ + int ErrorCode; /* Error codes from responses */ + char *ErrorText; /* Error description */ + + GSM_MemoryType PBKMemory; /* Last read PBK memory */ + char PBKMemories[AT_PBK_MAX_MEMORIES + 1]; /* Supported by phone PBK memories */ + int NextMemoryEntry; /* Next empty memory entry */ + GSM_AT_PBK_Charset PBKCharset; /* Last read PBK charset */ + bool UCS2CharsetFailed; /* Whether setting of UCS2 charset has already failed */ + bool NonUCS2CharsetFailed; /* Whether setting of non-UCS2 charset has already failed */ GSM_AT_SBNR PBKSBNR; GSM_SMSMemoryStatus LastSMSStatus; int LastSMSRead; int FirstCalendarPos; - GSM_AT_PHONE_SMSMemory PhoneSMSMemory; /* Is phone SMS memory available ? */ - GSM_MemoryType SMSMemory; /* Last read SMS memory */ - GSM_AT_SMS_Modes SMSMode; /* PDU or TEXT mode for SMS ? */ + GSM_AT_PHONE_SMSMemory PhoneSMSMemory; /* Is phone SMS memory available ? */ + GSM_MemoryType SMSMemory; /* Last read SMS memory */ + GSM_AT_SMS_Modes SMSMode; /* PDU or TEXT mode for SMS ? */ bool OBEX; GSM_File file; diff --git a/common/phone/at/siemens.c b/common/phone/at/siemens.c index 76024f684..9ef59efc7 100644 --- a/common/phone/at/siemens.c +++ b/common/phone/at/siemens.c @@ -9,7 +9,7 @@ #include "../../misc/coding/coding.h" #include "../../gsmcomon.h" -#include "../../service/gsmsms.h" +#include "../../service/sms/gsmsms.h" #include "../pfunc.h" extern GSM_Error ATGEN_HandleCMSError(GSM_StateMachine *s); diff --git a/common/phone/nokia/dct3/dct3func.c b/common/phone/nokia/dct3/dct3func.c index 6c3744436..df4fb55a0 100644 --- a/common/phone/nokia/dct3/dct3func.c +++ b/common/phone/nokia/dct3/dct3func.c @@ -5,7 +5,7 @@ #include "../../../gsmstate.h" #include "../../../misc/coding/coding.h" -#include "../../../service/gsmsms.h" +#include "../../../service/sms/gsmsms.h" #include "../../pfunc.h" #include "../nfunc.h" #include "dct3func.h" @@ -314,7 +314,7 @@ GSM_Error DCT3_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time, unsigne 0x00, 0x00, /* Year (0x07cf = 1999) */ 0x00, 0x00, /* Month & Day */ 0x00, 0x00, /* Hours & Minutes */ - 0x00 }; /* Unknown, but not seconds - try 59 and wait 1 sec. */ + 0x00}; /* Can't be seconds. Try 59 and wait 1 sec. */ NOKIA_EncodeDateTime(s, req+7, date_time); smprintf(s, "Setting date & time\n"); @@ -338,7 +338,7 @@ GSM_Error DCT3_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm, unsigned char msg N6110_FRAME_HEADER, 0x6b, 0x01, 0x20, 0x03, 0x02, /* should be alarm on/off, but it doesn't work */ 0x00, 0x00, /* Hours Minutes */ - 0x00 }; /* Unknown, but not seconds - try 59 and wait 1 sec. */ + 0x00}; /* Can't be seconds. Try 59 and wait 1 sec. */ if (alarm->Location != 1) return GE_NOTSUPPORTED; @@ -1291,11 +1291,13 @@ GSM_Error DCT3_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status) smprintf(s, "Getting SMS status\n"); return GSM_WaitFor (s, req, 5, 0x14, 2, ID_GetSMSStatus); +#ifndef ENABLE_LGPL /* Nokia 6210 and family does not show not "fixed" messages from the * Templates folder, ie. when you save a message to the Templates folder, * SMSStatus does not change! Workaround: get Templates folder status, which * does show these messages. */ +#endif } GSM_Error DCT3_ReplyDeleteSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) diff --git a/common/phone/nokia/dct3/n6110.c b/common/phone/nokia/dct3/n6110.c index 07539d1fa..cd5f0f22d 100644 --- a/common/phone/nokia/dct3/n6110.c +++ b/common/phone/nokia/dct3/n6110.c @@ -5,9 +5,10 @@ #include +#include "../../../../cfg/config.h" #include "../../../misc/coding/coding.h" +#include "../../../service/sms/gsmsms.h" #include "../../../gsmcomon.h" -#include "../../../service/gsmsms.h" #include "../../pfunc.h" #include "../nfunc.h" #include "n6110.h" @@ -65,20 +66,25 @@ struct N6110_Lang_Char { }; static struct N6110_Lang_Char N6110_Lang_Table[] = { -//Polish small chars acelnoszz with ogonek -{N6110_Europe,0x14,0x01,0x05},{N6110_Europe,0x17,0x01,0x07}, -{N6110_Europe,0x1E,0x01,0x19},{N6110_Europe,0x90,0x01,0x42}, -{N6110_Europe,0x93,0x01,0x44},{N6110_Europe,0x9A,0x00,0xF3}, -{N6110_Europe,0xB6,0x01,0x5B},{N6110_Europe,0xF4,0x01,0x7C}, -{N6110_Europe,0xEE,0x01,0x7A}, -//Polish large chars acelnoszz with ogonek -{N6110_Europe,0x13,0x01,0x04},{N6110_Europe,0x15,0x01,0x06}, -{N6110_Europe,0x1D,0x01,0x18},{N6110_Europe,0x8E,0x01,0x41}, -{N6110_Europe,0x92,0x01,0x43},{N6110_Europe,0x83,0x00,0xD3}, -{N6110_Europe,0xB5,0x01,0x5A},{N6110_Europe,0xF0,0x01,0x7B}, -{N6110_Europe,0xE7,0x01,0x79}, -//euro -{N6110_Europe,0xB2,0x20,0xAC}, +{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} }; @@ -116,6 +122,7 @@ static void N6110_EncodeUnicode(GSM_StateMachine *s, unsigned char *dest, const dest[(o_len*2)+1] = 0; } +#ifndef ENABLE_LGPL /* This function provides Nokia authentication protocol. * Nokia authentication protocol is used in the communication between Nokia @@ -226,8 +233,13 @@ static GSM_Error N6110_MakeAuthentication(GSM_StateMachine *s) 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 GE_NONE; +#else GSM_Error error=GE_NONE; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_MAGICBYTES)) { @@ -237,6 +249,7 @@ static GSM_Error N6110_ShowStartInfo(GSM_StateMachine *s, bool enable) } } return error; +#endif } static GSM_Error N6110_Initialise (GSM_StateMachine *s) @@ -1183,9 +1196,8 @@ static GSM_Error N6110_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) * 0x02 - View Graphics * 0x03 - Send Graphics * 0x04 - Send via IR - * You can even set it higher but Nokia phones (my - * 6110 at least) will not show you the name of this - * item in menu ;-)) Nokia is really joking here. + * When set to higher, some phones (like 6110) will not show + * the name of this item in menu */ if (Bitmap->DefaultBitmap) { Bitmap->Width = 72; @@ -2747,7 +2759,9 @@ static GSM_Reply_Function N6110ReplyFunctions[] = { {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 }, @@ -2758,7 +2772,7 @@ static GSM_Reply_Function N6110ReplyFunctions[] = { }; GSM_Phone_Functions N6110Phone = { - "3210|3310|3330|3390|3410|5110|5110i|5130|5190|5210|5510|6110|6130|6150|6190|8210|8250|8290|8850|8855|8890", + "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, diff --git a/common/phone/nokia/dct3/n6110.h b/common/phone/nokia/dct3/n6110.h index 0a1f203eb..b1deb8f1c 100644 --- a/common/phone/nokia/dct3/n6110.h +++ b/common/phone/nokia/dct3/n6110.h @@ -2,11 +2,14 @@ #ifndef n6110_h #define n6110_h -#include "../../../service/gsmsms.h" +#include "../../../../cfg/config.h" +#include "../../../service/sms/gsmsms.h" #include "dct3comm.h" typedef struct { +#ifndef ENABLE_LGPL unsigned char MagicBytes[4]; +#endif int LastCalendarPos; DCT3_WAPSettings_Locations WAPLocations; diff --git a/common/phone/nokia/dct3/n7110.c b/common/phone/nokia/dct3/n7110.c index 91d4a4688..522340d5c 100644 --- a/common/phone/nokia/dct3/n7110.c +++ b/common/phone/nokia/dct3/n7110.c @@ -1176,11 +1176,13 @@ static GSM_Error N7110_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *st error = DCT3_GetSMSStatus(s,status); if (error != GE_NONE) return error; +#ifndef ENABLE_LGPL /* Nokia 6210 and family does not show not "fixed" messages from the * Templates folder, ie. when you save a message to the Templates folder, * SMSStatus does not change! Workaround: get Templates folder status, which * does show these messages. */ +#endif error = N7110_GetSMSFolderStatus(s, 0x20); if (error != GE_NONE) return error; status->TemplatesUsed = Priv->LastSMSFolder.Number; diff --git a/common/phone/nokia/dct4/dct4func.h b/common/phone/nokia/dct4/dct4func.h index e8f7cc297..a757ef28d 100644 --- a/common/phone/nokia/dct4/dct4func.h +++ b/common/phone/nokia/dct4/dct4func.h @@ -3,7 +3,7 @@ #define dct4func_h #include "../ncommon.h" -#include "../../../service/gsmsms.h" +#include "../../../service/sms/gsmsms.h" typedef enum { DCT4_MODE_NORMAL = 0x01, diff --git a/common/phone/nokia/dct4/n3650.h b/common/phone/nokia/dct4/n3650.h index fa9534ff9..109bf8908 100644 --- a/common/phone/nokia/dct4/n3650.h +++ b/common/phone/nokia/dct4/n3650.h @@ -4,8 +4,8 @@ #include "../../../gsmcomon.h" #include "../../../gsmstate.h" -#include "../../../service/gsmsms.h" #include "../../../service/gsmmisc.h" +#include "../../../service/sms/gsmsms.h" #ifndef GSM_USED_MBUS2 # define GSM_USED_MBUS2 diff --git a/common/phone/nokia/dct4/n6510.c b/common/phone/nokia/dct4/n6510.c index 44f638ce7..b6760d5ea 100644 --- a/common/phone/nokia/dct4/n6510.c +++ b/common/phone/nokia/dct4/n6510.c @@ -208,7 +208,7 @@ static GSM_Error N6510_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) } req[12] = smsc->Validity.Relative; - /* Magic. Nokia new ideas: coding data in the sequent blocks */ + /* coding data in the sequent blocks */ req[count++] = 0x03; /* Number of blocks */ /* Block 2. SMSC Number */ @@ -993,8 +993,8 @@ 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 */ + 0x02, 0x00, /* memory type */ + 0x00, 0x00, /* location */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (entry->Location == 0) return GE_NOTSUPPORTED; @@ -1346,8 +1346,8 @@ 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 */ + 0x00, /* Event */ + 0x01}; /* Number of presses */ // req[7] = Key; if (Press) { @@ -1903,11 +1903,13 @@ static GSM_Error N6510_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *st error = GSM_WaitFor (s, req, 6, 0x14, 2, ID_GetSMSStatus); if (error != GE_NONE) return error; +#ifndef ENABLE_LGPL /* Nokia 6310 and family does not show not "fixed" messages from the * Templates folder, ie. when you save a message to the Templates folder, * SMSStatus does not change! Workaround: get Templates folder status, which * does show these messages. */ +#endif error = N6510_GetSMSFolderStatus(s, 0x06); if (error != GE_NONE) return error; status->TemplatesUsed = Priv->LastSMSFolder.Number; @@ -5301,7 +5303,7 @@ static GSM_Reply_Function N6510ReplyFunctions[] = { }; GSM_Phone_Functions N6510Phone = { - "3100|3300|3510|3510i|3530|3590|3595|5100|6100|6200|6220|6310|6310i|6510|6610|6800|7210|7250|7250i|8310|8390|8910|8910i", + "1100|1100a|1100b|3100|3100b|3200|3200a|3300|3510|3510i|3530|3590|3595|5100|6100|6200|6220|6310|6310i|6510|6610|6800|7210|7250|7250i|8310|8390|8910|8910i", N6510ReplyFunctions, N6510_Initialise, NONEFUNCTION, /* Terminate */ diff --git a/common/phone/nokia/dct4/n6510.h b/common/phone/nokia/dct4/n6510.h index e94dbaad9..9d657da78 100644 --- a/common/phone/nokia/dct4/n6510.h +++ b/common/phone/nokia/dct4/n6510.h @@ -3,7 +3,7 @@ #define n6510_h #include "../ncommon.h" -#include "../../../service/gsmsms.h" +#include "../../../service/sms/gsmsms.h" typedef enum { N6510_LIGHT_DISPLAY = 0x01, diff --git a/common/phone/nokia/nfunc.c b/common/phone/nokia/nfunc.c index 206bab5c1..ca669075e 100644 --- a/common/phone/nokia/nfunc.c +++ b/common/phone/nokia/nfunc.c @@ -6,7 +6,7 @@ #include "../../gsmstate.h" #include "../../misc/coding/coding.h" -#include "../../service/gsmsms.h" +#include "../../service/sms/gsmsms.h" #include "../pfunc.h" #include "nfunc.h" diff --git a/common/phone/nokia/nfuncold.c b/common/phone/nokia/nfuncold.c index 8d4c0c2c5..a26ac2729 100644 --- a/common/phone/nokia/nfuncold.c +++ b/common/phone/nokia/nfuncold.c @@ -6,7 +6,7 @@ #include "../../misc/coding/coding.h" #include "../../gsmstate.h" -#include "../../service/gsmsms.h" +#include "../../service/sms/gsmsms.h" #include "../pfunc.h" #include "nfunc.h" diff --git a/common/phone/obex/obexgen.h b/common/phone/obex/obexgen.h index a10647e59..85546c512 100644 --- a/common/phone/obex/obexgen.h +++ b/common/phone/obex/obexgen.h @@ -4,8 +4,8 @@ #include "../../gsmcomon.h" #include "../../gsmstate.h" -#include "../../service/gsmsms.h" #include "../../service/gsmmisc.h" +#include "../../service/sms/gsmsms.h" #ifndef GSM_USED_IRDAOBEX # define GSM_USED_IRDAOBEX diff --git a/common/phone/pfunc.c b/common/phone/pfunc.c index 2158e497f..080dcb07b 100644 --- a/common/phone/pfunc.c +++ b/common/phone/pfunc.c @@ -3,7 +3,7 @@ #include #include "../gsmstate.h" -#include "../service/gsmsms.h" +#include "../service/sms/gsmsms.h" #include "../misc/coding/coding.h" /* These SMS layouts are used exactly as written in Nokia DCT3 phones. diff --git a/common/phone/pfunc.h b/common/phone/pfunc.h index 8e193d02b..0c7480096 100644 --- a/common/phone/pfunc.h +++ b/common/phone/pfunc.h @@ -2,7 +2,7 @@ #ifndef phone_common2_h #define phone_common2_h -#include "../service/gsmsms.h" +#include "../service/sms/gsmsms.h" extern GSM_SMSMessageLayout PHONE_SMSSubmit; extern GSM_SMSMessageLayout PHONE_SMSDeliver; diff --git a/common/phone/symbian/mroutgen.h b/common/phone/symbian/mroutgen.h index 9dd11f6e1..e924ef100 100644 --- a/common/phone/symbian/mroutgen.h +++ b/common/phone/symbian/mroutgen.h @@ -4,8 +4,8 @@ #include "../../gsmcomon.h" #include "../../gsmstate.h" -#include "../../service/gsmsms.h" #include "../../service/gsmmisc.h" +#include "../../service/sms/gsmsms.h" #ifndef GSM_USED_MROUTERBLUE # define GSM_USED_MROUTERBLUE diff --git a/common/protocol/alcatel/alcabus.c b/common/protocol/alcatel/alcabus.c index 267be0417..1a41c7a9f 100644 --- a/common/protocol/alcatel/alcabus.c +++ b/common/protocol/alcatel/alcabus.c @@ -27,42 +27,42 @@ static GSM_Error ALCABUS_WriteMessage (GSM_StateMachine *s, unsigned char *data, buffer[1] = type; switch (type) { case ALCATEL_CONNECT: - buffer[2] = 0x0A; - buffer[3] = 0x04; - buffer[4] = 0x00; - size = 5; - d->next_frame = ALCATEL_CONNECT_ACK; - d->busy = true; - break; + buffer[2] = 0x0A; + buffer[3] = 0x04; + buffer[4] = 0x00; + size = 5; + d->next_frame = ALCATEL_CONNECT_ACK; + d->busy = true; + break; case ALCATEL_DISCONNECT: - size = 2; - d->next_frame = ALCATEL_DISCONNECT_ACK; - d->busy = true; - break; + size = 2; + d->next_frame = ALCATEL_DISCONNECT_ACK; + d->busy = true; + break; case ALCATEL_DATA: - buffer[2] = d->out_counter; - - /* Increase outgoing packet counter */ - if (d->out_counter == ALCATEL_MAX_COUNTER) d->out_counter = 0; - else d->out_counter++; - - buffer[3] = '\0'; - buffer[4] = len; - memcpy(buffer+5, data, len); - size = 5 + len; - d->next_frame = ALCATEL_ACK; - d->busy = true; - break; + buffer[2] = d->out_counter; + + /* Increase outgoing packet counter */ + if (d->out_counter == ALCATEL_MAX_COUNTER) d->out_counter = 0; + else d->out_counter++; + + buffer[3] = '\0'; + buffer[4] = len; + memcpy(buffer+5, data, len); + size = 5 + len; + d->next_frame = ALCATEL_ACK; + d->busy = true; + break; case ALCATEL_ACK: - buffer[2] = d->in_counter; - if (d->in_counter == 0) d->in_counter = 1; - size = 3; - d->next_frame = ALCATEL_DATA; - break; + buffer[2] = d->in_counter; + if (d->in_counter == 0) d->in_counter = 1; + size = 3; + d->next_frame = ALCATEL_DATA; + break; default: - /* In fact, other types probably can came just from mobile... */ - smprintf(s,"WARNING: Wanted to send some unknown packet (%02X)\n", type); - return GE_NOTIMPLEMENTED; + /* In fact, other types probably can came just from mobile... */ + smprintf(s,"WARNING: Wanted to send some unknown packet (%02X)\n", type); + return GE_NOTIMPLEMENTED; } /* Calculate packet checksum */ @@ -84,10 +84,10 @@ static GSM_Error ALCABUS_WriteMessage (GSM_StateMachine *s, unsigned char *data, /* For connect and disconnect we need a bit larger delay */ // my_sleep(10); while (d->busy) { - GSM_ReadDevice(s,true); - my_sleep(1); - i++; - if (i == 10) return GE_TIMEOUT; + GSM_ReadDevice(s,true); + my_sleep(1); + i++; + if (i == 10) return GE_TIMEOUT; } } return GE_NONE; @@ -208,7 +208,7 @@ static GSM_Error ALCABUS_StateMachine(GSM_StateMachine *s, unsigned char rx_byte /* Was it unexpected type? */ if ((d->Msg.Type != d->next_frame) && (d->Msg.Type != ALCATEL_CONTROL)) { - return GE_FRAMENOTREQUESTED; + return GE_FRAMENOTREQUESTED; } } /* Last byte of packet */ @@ -228,7 +228,6 @@ static GSM_Error ALCABUS_Initialise(GSM_StateMachine *s) d->out_counter = 0; d->busy = false; - /* Initialise protocol */ dbgprintf ("Initializing binary mode\n"); return ALCABUS_WriteMessage (s, 0, 0, ALCATEL_CONNECT); diff --git a/common/protocol/at/at.c b/common/protocol/at/at.c index fd49ca576..734eb82e3 100644 --- a/common/protocol/at/at.c +++ b/common/protocol/at/at.c @@ -37,54 +37,122 @@ static GSM_Error AT_WriteMessage (GSM_StateMachine *s, unsigned char *buffer, return GE_NONE; } +typedef struct { + char *text; + int lines; +} SpecialAnswersStruct; + static GSM_Error AT_StateMachine(GSM_StateMachine *s, unsigned char rx_byte) { + GSM_Protocol_Message Msg2; GSM_Protocol_ATData *d = &s->Protocol.Data.AT; int i; + + /* These are lines with end of "normal" answers */ static char *StartStrings[] = { - "OK" , "ERROR" , "+CME ERROR:" , - "+CMS ERROR:" , "RING" , "NO CARRIER" , - "NO ANSWER" , "AT+CREG=1" , "\x0D\x0A+COLP" , - "+CPIN: " , "\x0D\x0A+CREG:", - "\x0D\x0A_OSIGQ:" , "_OSIGQ:" , - "\x0D\x0A_OBS:" , "_OBS:" , - "\x0D\x0A+CGREG:" , "+CGREG:" , - "\x0D\x0A+CMTI:" , "CMIT:" , - "\x0D\x0A^SCN:" , "^SCN:"}; + "OK" , "ERROR" , + "+CME ERROR:" , "+CMS ERROR:" , + + "+CPIN: " , /*A2D issue*/ + + NULL}; + + /* Some info from phone can be inside "normal" answers + * It starts with strings written here + */ + static SpecialAnswersStruct SpecialAnswers[] = { + {"_OSIGQ:" ,1}, {"_OBS:" ,1}, + {"^SCN:" ,1}, {"+CGREG:" ,1}, + {"+CBM:" ,1}, {"+CMT:" ,2}, + {"+CMTI:" ,1}, {"+CDS:" ,2}, + + {"RING" ,1}, {"NO CARRIER" ,1}, + {"NO ANSWER" ,1}, {"+COLP" ,1}, + {"+CLIP" ,1}, + + {NULL ,1}}; /* Ignore leading CR, LF and ESC */ - if (d->Msg.Length == 0 && (rx_byte == 10 || rx_byte == 13 || rx_byte == 27)) return GE_NONE; + if (d->Msg.Length == 0) { + if (rx_byte == 10 || rx_byte == 13 || rx_byte == 27) return GE_NONE; + d->LineStart = d->Msg.Length; + } if (d->Msg.BufferUsed < d->Msg.Length + 2) { d->Msg.BufferUsed = d->Msg.Length + 2; d->Msg.Buffer = (unsigned char *)realloc(d->Msg.Buffer,d->Msg.BufferUsed); - if (d->linestart != NULL) { - d->linestart = d->Msg.Buffer+d->linestartnum; - } } d->Msg.Buffer[d->Msg.Length++] = rx_byte; d->Msg.Buffer[d->Msg.Length ] = 0; - if (d->linestart == NULL) { - d->linestart = d->Msg.Buffer; - d->linestartnum = 0; - } switch (rx_byte) { case 0: break; case 10: case 13: + if (!d->wascrlf) d->LineEnd = d->Msg.Length-1; d->wascrlf = true; if (d->Msg.Length > 0 && rx_byte == 10 && d->Msg.Buffer[d->Msg.Length-2]==13) { - for (i=0;i<21;i++) { - if (strncmp(StartStrings[i],d->linestart,strlen(StartStrings[i])) == 0) { - s->Phone.Data.RequestMsg = &d->Msg; + i = 0; + while (StartStrings[i] != NULL) { + if (strlen(StartStrings[i])==0) break; + if (strncmp(StartStrings[i],d->Msg.Buffer+d->LineStart,strlen(StartStrings[i])) == 0) { + s->Phone.Data.RequestMsg = &d->Msg; + s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s); + d->Msg.Length = 0; + break; + } + i++; + } + if (d->Msg.Length == 0) break; + + i = 0; + while (SpecialAnswers[i].text != NULL) { + if (strlen(SpecialAnswers[i].text)==0) break; + if (strncmp(SpecialAnswers[i].text,d->Msg.Buffer+d->LineStart,strlen(SpecialAnswers[i].text)) == 0) { + d->SpecialAnswerStart = d->LineStart; + d->SpecialAnswerLines = SpecialAnswers[i].lines; + } + i++; + } + + if (d->SpecialAnswerLines == 1) { + /* This is end of special answer. We copy it and send to phone module */ + Msg2.Buffer = malloc(d->LineEnd - d->SpecialAnswerStart + 3); + memcpy(Msg2.Buffer,d->Msg.Buffer+d->SpecialAnswerStart,d->LineEnd - d->SpecialAnswerStart + 2); + Msg2.Length = d->LineEnd - d->SpecialAnswerStart + 2; + Msg2.Buffer[Msg2.Length] = 0; + + s->Phone.Data.RequestMsg = &Msg2; s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s); - d->linestart = NULL; - d->Msg.Length = 0; - break; - } + free(Msg2.Buffer); + + /* We cut special answer from main buffer */ + d->Msg.Length = d->SpecialAnswerStart; + if (d->Msg.Length != 0) d->Msg.Length = d->Msg.Length - 2; + + /* We need to find earlier values of all variables */ + d->wascrlf = false; + d->LineStart = 0; + for (i=0;iMsg.Length;i++) { + switch(d->Msg.Buffer[i]) { + case 0: + break; + case 10: + case 13: + if (!d->wascrlf) d->LineEnd = d->Msg.Length-1; + d->wascrlf = true; + break; + default: + if (d->wascrlf) { + d->LineStart = d->Msg.Length-1; + d->wascrlf = false; + } + } + } + d->Msg.Buffer[d->Msg.Length] = 0; } + if (d->SpecialAnswerLines > 0) d->SpecialAnswerLines--; } break; case 'T': @@ -92,21 +160,20 @@ static GSM_Error AT_StateMachine(GSM_StateMachine *s, unsigned char rx_byte) * anything AT related, after CONNECT can follow ppp data, alcabus * data and also other things. */ - if (strncmp(d->linestart, "CONNECT", 7) == 0) { + if (strncmp(d->Msg.Buffer+d->LineStart, "CONNECT", 7) == 0) { s->Phone.Data.RequestMsg = &d->Msg; s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s); - d->linestart = NULL; + d->LineStart = -1; d->Msg.Length = 0; break; } default: if (d->wascrlf) { - d->linestart = d->Msg.Buffer + (d->Msg.Length - 1); - d->linestartnum = d->Msg.Length - 1; + d->LineStart = d->Msg.Length-1; d->wascrlf = false; } if (d->EditMode) { - if (strlen(d->linestart) == 2 && strncmp(d->linestart,"> ",2)==0) { + if (strlen(d->Msg.Buffer+d->LineStart) == 2 && strncmp(d->Msg.Buffer+d->LineStart,"> ",2)==0) { s->Phone.Data.RequestMsg = &d->Msg; s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s); } @@ -119,13 +186,16 @@ static GSM_Error AT_Initialise(GSM_StateMachine *s) { GSM_Protocol_ATData *d = &s->Protocol.Data.AT; - d->Msg.BufferUsed = 0; d->Msg.Buffer = NULL; + d->Msg.BufferUsed = 0; d->Msg.Length = 0; + d->Msg.Type = 0; - d->linestart = NULL; + d->SpecialAnswerLines = 0; + d->LineStart = -1; + d->LineEnd = -1; + d->wascrlf = false; d->EditMode = false; - d->Msg.Type = 0; d->FastWrite = false; s->Device.Functions->DeviceSetDtrRts(s,true,true); diff --git a/common/protocol/at/at.h b/common/protocol/at/at.h index 0aa8f8941..af2b2ef62 100644 --- a/common/protocol/at/at.h +++ b/common/protocol/at/at.h @@ -7,8 +7,8 @@ typedef struct { GSM_Protocol_Message Msg; bool wascrlf; - char *linestart; - int linestartnum; + int LineStart,LineEnd; + int SpecialAnswerLines,SpecialAnswerStart; bool EditMode; /* wait for modem answer or not */ bool FastWrite; diff --git a/common/protocol/nokia/mbus2.c b/common/protocol/nokia/mbus2.c index 00fb76216..d84e2f72d 100644 --- a/common/protocol/nokia/mbus2.c +++ b/common/protocol/nokia/mbus2.c @@ -20,47 +20,43 @@ static GSM_Error MBUS2_WriteMessage (GSM_StateMachine *s, unsigned char *buffer, out_buffer = (unsigned char *)malloc(length + 8); - /* Now construct the message header. */ - out_buffer[current++] = MBUS2_FRAME_ID; /* Start of the frame indicator */ - out_buffer[current++] = MBUS2_DEVICE_PHONE; /* Destination */ - out_buffer[current++] = MBUS2_DEVICE_PC; /* Source */ - out_buffer[current++] = type; /* Type */ - out_buffer[current++] = length/256; /* Length */ - out_buffer[current++] = length%256; /* Length */ - - /* Copy in data if any. */ + /* Preparing header of message */ + out_buffer[current++] = MBUS2_FRAME_ID; + out_buffer[current++] = MBUS2_DEVICE_PHONE; /* Frame destination */ + out_buffer[current++] = MBUS2_DEVICE_PC; /* Frame source */ + out_buffer[current++] = type; /* Frame type */ + out_buffer[current++] = length/256; /* Frame length */ + out_buffer[current++] = length%256; /* Frame length */ + + /* Copying frame */ if (length != 0) { memcpy(out_buffer + current, buffer, length); current+=length; } - /* Checksum problem: - * It seems that some phones have problems with a checksum of 1F. - * The frame will be recognized but it will not respond with a ACK - * frame. - * Workaround: - * If the checksum will be 1F, increment the sequence number so that - * the checksum will be different., recalculate the checksum then and - * send. - * Source: http://www.flosys.com/tdma/n5160.html - */ + /* According to http://www.flosys.com/tdma/n5160.html some phones + * can have problems with checksum equal 0x1F. Phones can recognize + * received frame, but won't send ACK for it. When checksum is 0x1F, + * we increment the sequence number + */ do { d->MsgSequenceNumber++; out_buffer[current] = d->MsgSequenceNumber; - /* Now calculate checksum over entire message */ + /* Calculating checksum */ checksum = 0; for (count = 0; count < current + 1; count++) checksum ^= out_buffer[count]; } while (checksum == 0x1f); - /* Now append sequence and checksum to message. */ + /* Adding sequence and checksum */ out_buffer[current++] = d->MsgSequenceNumber; out_buffer[current++] = checksum; + /* Writing debug output */ GSM_DumpMessageLevel2(s, out_buffer+6, length, type); - /* Send it out... */ + /* Sending to phone */ my_sleep(10); sent=s->Device.Functions->WriteDevice(s,out_buffer,current); @@ -83,7 +79,7 @@ static GSM_Error MBUS2_SendAck(GSM_StateMachine *s, unsigned char type, unsigned out_buffer[4] = sequence; out_buffer[5] = 0; - /* Checksum */ + /* Calculating checksum */ for (count = 0; count < 5; count++) out_buffer[5] ^= out_buffer[count]; if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || @@ -91,7 +87,7 @@ static GSM_Error MBUS2_SendAck(GSM_StateMachine *s, unsigned char type, unsigned smprintf(s,"[Sending Ack of type %02x, seq: %x]\n",type,sequence); } - /* Send it out... */ + /* Sending to phone */ my_sleep(10); if (Device->WriteDevice(s,out_buffer,6)!=6) return GE_DEVICEWRITEERROR; diff --git a/common/service/backup/backgen.h b/common/service/backup/backgen.h index fd0a07a4b..3c021b08d 100644 --- a/common/service/backup/backgen.h +++ b/common/service/backup/backgen.h @@ -7,10 +7,10 @@ #include "../gsmcal.h" #include "../gsmlogo.h" #include "../gsmring.h" -#include "../gsmsms.h" #include "../gsmwap.h" #include "../gsmprof.h" #include "../gsmmisc.h" +#include "../sms/gsmsms.h" #define GSM_BACKUP_MAX_PHONEPHONEBOOK 501 #define GSM_BACKUP_MAX_SIMPHONEBOOK 251 diff --git a/common/service/backup/backtext.c b/common/service/backup/backtext.c index 7870b38c6..685c42ea0 100644 --- a/common/service/backup/backtext.c +++ b/common/service/backup/backtext.c @@ -15,69 +15,75 @@ GSM_Error FindBackupChecksum(char *FileName, bool UseUnicode, char *checksum) { - CFG_Header *file_info, *h; - CFG_Entry *e; + INI_Section *file_info, *h; + INI_Entry *e; char *buffer = NULL,buff[100]; int len=0; +int i; + file_info = INI_ReadFile(FileName, UseUnicode); - file_info = CFG_ReadFile(FileName, UseUnicode); + dbgprintf("Checking checksum\n"); - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { if (UseUnicode) { EncodeUnicode(buff,"Checksum",8); - if (mywstrncasecmp(buff, h->section, 8)) continue; + if (mywstrncasecmp(buff, h->SectionName, 8)) continue; } else { - if (mystrncasecmp("Checksum", h->section, 8)) continue; + if (mystrncasecmp("Checksum", h->SectionName, 8)) continue; } if (UseUnicode) { - buffer = (unsigned char *)realloc(buffer,len+UnicodeLength(h->section)*2+2); - CopyUnicodeString(buffer+len,h->section); - len+=UnicodeLength(h->section)*2; + buffer = (unsigned char *)realloc(buffer,len+UnicodeLength(h->SectionName)*2+2); + CopyUnicodeString(buffer+len,h->SectionName); + len+=UnicodeLength(h->SectionName)*2; + dbgprintf("[%s]\n",DecodeUnicodeConsole(h->SectionName)); } else { - buffer = (unsigned char *)realloc(buffer,len+strlen(h->section)+1); - strcpy(buffer+len,h->section); - len+=strlen(h->section); + buffer = (unsigned char *)realloc(buffer,len+strlen(h->SectionName)+1); + strcpy(buffer+len,h->SectionName); + len+=strlen(h->SectionName); } - for (e = h->entries; e != NULL; e = e->next) { + for (e = h->SubEntries; e != NULL; e = e->Next) { if (UseUnicode) { - buffer = (unsigned char *)realloc(buffer,len+UnicodeLength(e->key)*2+2); - CopyUnicodeString(buffer+len,e->key); - len+=UnicodeLength(e->key)*2; - buffer = (unsigned char *)realloc(buffer,len+UnicodeLength(e->value)*2+2); - CopyUnicodeString(buffer+len,e->value); - len+=UnicodeLength(e->value)*2; + buffer = (unsigned char *)realloc(buffer,len+UnicodeLength(e->EntryName)*2+2); + CopyUnicodeString(buffer+len,e->EntryName); + len+=UnicodeLength(e->EntryName)*2; + buffer = (unsigned char *)realloc(buffer,len+UnicodeLength(e->EntryValue)*2+2); + CopyUnicodeString(buffer+len,e->EntryValue); + len+=UnicodeLength(e->EntryValue)*2; + dbgprintf("\"%s\"",DecodeUnicodeConsole(e->EntryName)); + dbgprintf("=\"%s\"\n",DecodeUnicodeConsole(e->EntryValue)); } else { - dbgprintf("%s=%s\n",e->key,e->value); - buffer = (unsigned char *)realloc(buffer,len+strlen(e->key)+1); - strcpy(buffer+len,e->key); - len+=strlen(e->key); - buffer = (unsigned char *)realloc(buffer,len+strlen(e->value)+1); - strcpy(buffer+len,e->value); - len+=strlen(e->value); + dbgprintf("%s=%s\n",e->EntryName,e->EntryValue); + buffer = (unsigned char *)realloc(buffer,len+strlen(e->EntryName)+1); + strcpy(buffer+len,e->EntryName); + len+=strlen(e->EntryName); + buffer = (unsigned char *)realloc(buffer,len+strlen(e->EntryValue)+1); + strcpy(buffer+len,e->EntryValue); + len+=strlen(e->EntryValue); } } } +for (i=0;iEntriesNum = 0; - e = CFG_FindLastSectionEntry(file_info, section, UseUnicode); + e = INI_FindLastSectionEntry(file_info, section, UseUnicode); sprintf(buffer,"PreferUnicode"); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); @@ -1148,9 +1154,9 @@ static void ReadPbkEntry(CFG_Header *file_info, char *section, GSM_MemoryEntry * if (e == NULL) break; num = -1; if (UseUnicode) { - sprintf(buffer,"%s",DecodeUnicodeString(e->key)); + sprintf(buffer,"%s",DecodeUnicodeString(e->EntryName)); } else { - sprintf(buffer,"%s",e->key); + sprintf(buffer,"%s",e->EntryName); } if (strlen(buffer) == 11) { if (mystrncasecmp("Entry", buffer, 5) && @@ -1158,7 +1164,7 @@ static void ReadPbkEntry(CFG_Header *file_info, char *section, GSM_MemoryEntry * num = atoi(buffer+5); } } - e = e->prev; + e = e->Prev; if (num != -1) { sprintf(buffer,"Entry%02iType",num); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); @@ -1279,7 +1285,7 @@ static void ReadPbkEntry(CFG_Header *file_info, char *section, GSM_MemoryEntry * } } -static void ReadCalendarEntry(CFG_Header *file_info, char *section, GSM_CalendarEntry *note, bool UseUnicode) +static void ReadCalendarEntry(INI_Section *file_info, char *section, GSM_CalendarEntry *note, bool UseUnicode) { unsigned char buffer[10000]; char *readvalue; @@ -1467,7 +1473,7 @@ static void ReadCalendarEntry(CFG_Header *file_info, char *section, GSM_Calendar } } -static void ReadToDoEntry(CFG_Header *file_info, char *section, GSM_ToDoEntry *ToDo, bool UseUnicode) +static void ReadToDoEntry(INI_Section *file_info, char *section, GSM_ToDoEntry *ToDo, bool UseUnicode) { unsigned char buffer[10000]; char *readvalue; @@ -1563,7 +1569,7 @@ static void ReadToDoEntry(CFG_Header *file_info, char *section, GSM_ToDoEntry *T } } -static bool ReadBitmapEntry(CFG_Header *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) +static bool ReadBitmapEntry(INI_Section *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) { char *readvalue; unsigned char buffer[10000]; @@ -1590,7 +1596,7 @@ static bool ReadBitmapEntry(CFG_Header *file_info, char *section, GSM_Bitmap *bi return true; } -static void ReadCallerEntry(CFG_Header *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) +static void ReadCallerEntry(INI_Section *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) { unsigned char buffer[10000]; char *readvalue; @@ -1625,7 +1631,7 @@ static void ReadCallerEntry(CFG_Header *file_info, char *section, GSM_Bitmap *bi } } -static void ReadStartupEntry(CFG_Header *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) +static void ReadStartupEntry(INI_Section *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) { unsigned char buffer[10000]; @@ -1643,7 +1649,7 @@ static void ReadStartupEntry(CFG_Header *file_info, char *section, GSM_Bitmap *b } } -static void ReadWAPBookmarkEntry(CFG_Header *file_info, char *section, GSM_WAPBookmark *bookmark, bool UseUnicode) +static void ReadWAPBookmarkEntry(INI_Section *file_info, char *section, GSM_WAPBookmark *bookmark, bool UseUnicode) { unsigned char buffer[10000]; @@ -1653,7 +1659,7 @@ static void ReadWAPBookmarkEntry(CFG_Header *file_info, char *section, GSM_WAPBo ReadBackupText(file_info, section, buffer, bookmark->Title,UseUnicode); } -static void ReadOperatorEntry(CFG_Header *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) +static void ReadOperatorEntry(INI_Section *file_info, char *section, GSM_Bitmap *bitmap, bool UseUnicode) { unsigned char buffer[10000]; char *readvalue; @@ -1666,7 +1672,7 @@ static void ReadOperatorEntry(CFG_Header *file_info, char *section, GSM_Bitmap * ReadBitmapEntry(file_info, section, bitmap, UseUnicode); } -static void ReadSMSCEntry(CFG_Header *file_info, char *section, GSM_SMSC *SMSC, bool UseUnicode) +static void ReadSMSCEntry(INI_Section *file_info, char *section, GSM_SMSC *SMSC, bool UseUnicode) { unsigned char buffer[10000]; char *readvalue; @@ -1708,11 +1714,11 @@ static void ReadSMSCEntry(CFG_Header *file_info, char *section, GSM_SMSC *SMSC, } } -static void ReadWAPSettingsEntry(CFG_Header *file_info, char *section, GSM_MultiWAPSettings *settings, bool UseUnicode) +static void ReadWAPSettingsEntry(INI_Section *file_info, char *section, GSM_MultiWAPSettings *settings, bool UseUnicode) { unsigned char buffer[10000], *readvalue; int num; - CFG_Entry *e; + INI_Entry *e; settings->ActiveBearer = WAPSETTINGS_BEARER_DATA; sprintf(buffer,"Bearer"); @@ -1735,19 +1741,19 @@ static void ReadWAPSettingsEntry(CFG_Header *file_info, char *section, GSM_Multi } settings->Number = 0; - e = CFG_FindLastSectionEntry(file_info, section, UseUnicode); + e = INI_FindLastSectionEntry(file_info, section, UseUnicode); while (1) { if (e == NULL) break; num = -1; if (UseUnicode) { - sprintf(buffer,"%s",DecodeUnicodeString(e->key)); + sprintf(buffer,"%s",DecodeUnicodeString(e->EntryName)); } else { - sprintf(buffer,"%s",e->key); + sprintf(buffer,"%s",e->EntryName); } if (strlen(buffer) == 7) { if (mystrncasecmp("Title", buffer,5)) num = atoi(buffer+5); } - e = e->prev; + e = e->Prev; if (num != -1) { sprintf(buffer,"Title%02i",num); ReadBackupText(file_info, section, buffer, settings->Settings[settings->Number].Title,UseUnicode); @@ -1837,7 +1843,7 @@ static void ReadWAPSettingsEntry(CFG_Header *file_info, char *section, GSM_Multi } } -static void ReadRingtoneEntry(CFG_Header *file_info, char *section, GSM_Ringtone *ringtone, bool UseUnicode) +static void ReadRingtoneEntry(INI_Section *file_info, char *section, GSM_Ringtone *ringtone, bool UseUnicode) { unsigned char buffer[10000], buffer2[10000], *readvalue; @@ -1866,13 +1872,13 @@ static void ReadRingtoneEntry(CFG_Header *file_info, char *section, GSM_Ringtone } -static void ReadProfileEntry(CFG_Header *file_info, char *section, GSM_Profile *Profile, bool UseUnicode) +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; - CFG_Entry *e; + INI_Entry *e; sprintf(buffer,"Name"); ReadBackupText(file_info, section, buffer, Profile->Name,UseUnicode); @@ -1897,19 +1903,19 @@ static void ReadProfileEntry(CFG_Header *file_info, char *section, GSM_Profile * if (readvalue!=NULL && mystrncasecmp(buffer,"true",0)) Profile->CarKitProfile = true; Profile->FeaturesNumber = 0; - e = CFG_FindLastSectionEntry(file_info, section, UseUnicode); + e = INI_FindLastSectionEntry(file_info, section, UseUnicode); while (1) { if (e == NULL) break; num = -1; if (UseUnicode) { - sprintf(buffer,"%s",DecodeUnicodeString(e->key)); + sprintf(buffer,"%s",DecodeUnicodeString(e->EntryName)); } else { - sprintf(buffer,"%s",e->key); + sprintf(buffer,"%s",e->EntryName); } if (strlen(buffer) == 9) { if (mystrncasecmp("Feature", buffer, 7)) num = atoi(buffer+7); } - e = e->prev; + e = e->Prev; if (num != -1) { sprintf(buffer,"Feature%02i",num); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); @@ -2081,7 +2087,7 @@ static void ReadProfileEntry(CFG_Header *file_info, char *section, GSM_Profile * } } -static void ReadFMStationEntry(CFG_Header *file_info, char *section, GSM_FMStation *FMStation, bool UseUnicode) +static void ReadFMStationEntry(INI_Section *file_info, char *section, GSM_FMStation *FMStation, bool UseUnicode) { unsigned char buffer[10000], *readvalue; @@ -2100,7 +2106,7 @@ static void ReadFMStationEntry(CFG_Header *file_info, char *section, GSM_FMStati if (readvalue!=NULL) StringToDouble(readvalue, &FMStation->Frequency); } -static void ReadGPRSPointEntry(CFG_Header *file_info, char *section, GSM_GPRSAccessPoint *GPRSPoint, bool UseUnicode) +static void ReadGPRSPointEntry(INI_Section *file_info, char *section, GSM_GPRSAccessPoint *GPRSPoint, bool UseUnicode) { unsigned char buffer[10000], *readvalue; @@ -2128,7 +2134,7 @@ static void ReadGPRSPointEntry(CFG_Header *file_info, char *section, GSM_GPRSAcc ReadBackupText(file_info, section, buffer, GPRSPoint->URL,UseUnicode); } -static void ReadNoteEntry(CFG_Header *file_info, char *section, GSM_NoteEntry *Note, bool UseUnicode) +static void ReadNoteEntry(INI_Section *file_info, char *section, GSM_NoteEntry *Note, bool UseUnicode) { unsigned char buffer[100]; @@ -2138,13 +2144,13 @@ static void ReadNoteEntry(CFG_Header *file_info, char *section, GSM_NoteEntry *N GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) { - CFG_Header *file_info, *h; + INI_Section *file_info, *h; char buffer[100], *readvalue; int num; GSM_MemoryEntry PBK; bool found; - file_info = CFG_ReadFile(FileName, UseUnicode); + file_info = INI_ReadFile(FileName, UseUnicode); sprintf(buffer,"Backup"); if (UseUnicode) EncodeUnicode(buffer,"Backup",6); @@ -2172,16 +2178,16 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) if (readvalue!=NULL) strcpy(backup->MD5Original,readvalue); num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Profile",7); - if (mywstrncasecmp(buffer, h->section, 7)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 7)) found = true; } else { - if (mystrncasecmp("Profile", h->section, 7)) found = true; + if (mystrncasecmp("Profile", h->SectionName, 7)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Location", UseUnicode); + 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)); @@ -2191,21 +2197,21 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) dbgprintf("Increase GSM_BACKUP_MAX_PROFILES\n"); return GE_MOREMEMORY; } - ReadProfileEntry(file_info, h->section, backup->Profiles[num], UseUnicode); + ReadProfileEntry(file_info, h->SectionName, backup->Profiles[num], UseUnicode); num++; } } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"PhonePBK",8); - if (mywstrncasecmp(buffer, h->section, 8)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { - if (mystrncasecmp("PhonePBK", h->section, 8)) found = true; + if (mystrncasecmp("PhonePBK", h->SectionName, 8)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Location", UseUnicode); + 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)); @@ -2217,7 +2223,7 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) } backup->PhonePhonebook[num]->Location = atoi (readvalue); backup->PhonePhonebook[num]->MemoryType = GMT_ME; - ReadPbkEntry(file_info, h->section, backup->PhonePhonebook[num],UseUnicode); + ReadPbkEntry(file_info, h->SectionName, backup->PhonePhonebook[num],UseUnicode); dbgprintf("number of entries = %i\n",backup->PhonePhonebook[num]->EntriesNum); num++; } @@ -2237,16 +2243,16 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) num++; } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"SIMPBK",6); - if (mywstrncasecmp(buffer, h->section, 6)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; } else { - if (mystrncasecmp("SIMPBK", h->section, 6)) found = true; + if (mystrncasecmp("SIMPBK", h->SectionName, 6)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Location", UseUnicode); + 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)); @@ -2258,7 +2264,7 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) } backup->SIMPhonebook[num]->Location = atoi (readvalue); backup->SIMPhonebook[num]->MemoryType = GMT_SM; - ReadPbkEntry(file_info, h->section, backup->SIMPhonebook[num],UseUnicode); + ReadPbkEntry(file_info, h->SectionName, backup->SIMPhonebook[num],UseUnicode); num++; } } @@ -2277,16 +2283,16 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) num++; } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Calendar",8); - if (mywstrncasecmp(buffer, h->section, 8)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { - if (mystrncasecmp("Calendar", h->section, 8)) found = true; + if (mystrncasecmp("Calendar", h->SectionName, 8)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Type", UseUnicode); + readvalue = ReadCFGText(file_info, h->SectionName, "Type", UseUnicode); if (readvalue==NULL) break; if (num < GSM_MAXCALENDARTODONOTES) { backup->Calendar[num] = malloc(sizeof(GSM_CalendarEntry)); @@ -2297,21 +2303,21 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) return GE_MOREMEMORY; } backup->Calendar[num]->Location = num + 1; - ReadCalendarEntry(file_info, h->section, backup->Calendar[num],UseUnicode); + ReadCalendarEntry(file_info, h->SectionName, backup->Calendar[num],UseUnicode); num++; } } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Caller",6); - if (mywstrncasecmp(buffer, h->section, 6)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; } else { - if (mystrncasecmp("Caller", h->section, 6)) found = true; + if (mystrncasecmp("Caller", h->SectionName, 6)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Location", UseUnicode); + 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)); @@ -2322,21 +2328,21 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) return GE_MOREMEMORY; } backup->CallerLogos[num]->Location = atoi (readvalue); - ReadCallerEntry(file_info, h->section, backup->CallerLogos[num],UseUnicode); + ReadCallerEntry(file_info, h->SectionName, backup->CallerLogos[num],UseUnicode); num++; } } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"SMSC",4); - if (mywstrncasecmp(buffer, h->section, 4)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; } else { - if (mystrncasecmp("SMSC", h->section, 4)) found = true; + if (mystrncasecmp("SMSC", h->SectionName, 4)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Location", UseUnicode); + 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)); @@ -2347,28 +2353,28 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) return GE_MOREMEMORY; } backup->SMSC[num]->Location = atoi (readvalue); - ReadSMSCEntry(file_info, h->section, backup->SMSC[num],UseUnicode); + ReadSMSCEntry(file_info, h->SectionName, backup->SMSC[num],UseUnicode); num++; } } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"WAPBookmark",11); - if (mywstrncasecmp(buffer, h->section, 11)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 11)) found = true; if (!found) { EncodeUnicode(buffer,"Bookmark",8); - if (mywstrncasecmp(buffer, h->section, 8)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } } else { - if (mystrncasecmp("WAPBookmark", h->section, 11)) found = true; + if (mystrncasecmp("WAPBookmark", h->SectionName, 11)) found = true; if (!found) { - if (mystrncasecmp("Bookmark", h->section, 8)) found = true; + if (mystrncasecmp("Bookmark", h->SectionName, 8)) found = true; } } if (found) { - readvalue = ReadCFGText(file_info, h->section, "URL", UseUnicode); + 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)); @@ -2379,28 +2385,28 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) return GE_MOREMEMORY; } backup->WAPBookmark[num]->Location = num + 1; - ReadWAPBookmarkEntry(file_info, h->section, backup->WAPBookmark[num],UseUnicode); + ReadWAPBookmarkEntry(file_info, h->SectionName, backup->WAPBookmark[num],UseUnicode); num++; } } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"WAPSettings",11); - if (mywstrncasecmp(buffer, h->section, 11)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 11)) found = true; if (!found) { EncodeUnicode(buffer,"Settings",8); - if (mywstrncasecmp(buffer, h->section, 8)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } } else { - if (mystrncasecmp("WAPSettings", h->section, 11)) found = true; + if (mystrncasecmp("WAPSettings", h->SectionName, 11)) found = true; if (!found) { - if (mystrncasecmp("Settings", h->section, 8)) found = true; + if (mystrncasecmp("Settings", h->SectionName, 8)) found = true; } } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Title00", UseUnicode); + 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)); @@ -2412,21 +2418,21 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) } backup->WAPSettings[num]->Location = num + 1; dbgprintf("reading wap settings\n"); - ReadWAPSettingsEntry(file_info, h->section, backup->WAPSettings[num],UseUnicode); + ReadWAPSettingsEntry(file_info, h->SectionName, backup->WAPSettings[num],UseUnicode); num++; } } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"MMSSettings",8); - if (mywstrncasecmp(buffer, h->section, 8)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { - if (mystrncasecmp("MMSSettings", h->section, 8)) found = true; + if (mystrncasecmp("MMSSettings", h->SectionName, 8)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Title00", UseUnicode); + 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)); @@ -2438,21 +2444,21 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) } backup->MMSSettings[num]->Location = num + 1; dbgprintf("reading mms settings\n"); - ReadWAPSettingsEntry(file_info, h->section, backup->MMSSettings[num],UseUnicode); + ReadWAPSettingsEntry(file_info, h->SectionName, backup->MMSSettings[num],UseUnicode); num++; } } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Ringtone",8); - if (mywstrncasecmp(buffer, h->section, 8)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; } else { - if (mystrncasecmp("Ringtone", h->section, 8)) found = true; + if (mystrncasecmp("Ringtone", h->SectionName, 8)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Location", UseUnicode); + 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)); @@ -2462,21 +2468,21 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) dbgprintf("Increase GSM_BACKUP_MAX_RINGTONES\n"); return GE_MOREMEMORY; } - ReadRingtoneEntry(file_info, h->section, backup->Ringtone[num],UseUnicode); + ReadRingtoneEntry(file_info, h->SectionName, backup->Ringtone[num],UseUnicode); num++; } } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"TODO",4); - if (mywstrncasecmp(buffer, h->section, 4)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; } else { - if (mystrncasecmp("TODO", h->section, 4)) found = true; + if (mystrncasecmp("TODO", h->SectionName, 4)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Location", UseUnicode); + readvalue = ReadCFGText(file_info, h->SectionName, "Location", UseUnicode); if (readvalue==NULL) break; if (num < GSM_MAXCALENDARTODONOTES) { backup->ToDo[num] = malloc(sizeof(GSM_ToDoEntry)); @@ -2487,7 +2493,7 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) return GE_MOREMEMORY; } backup->ToDo[num]->Location = num + 1; - ReadToDoEntry(file_info, h->section, backup->ToDo[num],UseUnicode); + ReadToDoEntry(file_info, h->SectionName, backup->ToDo[num],UseUnicode); num++; } } @@ -2509,16 +2515,16 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) ReadOperatorEntry(file_info, buffer, backup->OperatorLogo,UseUnicode); } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"FMStation",9); - if (mywstrncasecmp(buffer, h->section, 9)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 9)) found = true; } else { - if (mystrncasecmp("FMStation", h->section, 9)) found = true; + if (mystrncasecmp("FMStation", h->SectionName, 9)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Location", UseUnicode); + 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)); @@ -2529,21 +2535,21 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) return GE_MOREMEMORY; } backup->FMStation[num]->Location = num + 1; - ReadFMStationEntry(file_info, h->section, backup->FMStation[num],UseUnicode); + ReadFMStationEntry(file_info, h->SectionName, backup->FMStation[num],UseUnicode); num++; } } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"GPRSPoint",9); - if (mywstrncasecmp(buffer, h->section, 9)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 9)) found = true; } else { - if (mystrncasecmp("GPRSPoint", h->section, 9)) found = true; + if (mystrncasecmp("GPRSPoint", h->SectionName, 9)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Location", UseUnicode); + 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)); @@ -2554,21 +2560,21 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) return GE_MOREMEMORY; } backup->GPRSPoint[num]->Location = num + 1; - ReadGPRSPointEntry(file_info, h->section, backup->GPRSPoint[num],UseUnicode); + ReadGPRSPointEntry(file_info, h->SectionName, backup->GPRSPoint[num],UseUnicode); num++; } } num = 0; - for (h = file_info; h != NULL; h = h->next) { + for (h = file_info; h != NULL; h = h->Next) { found = false; if (UseUnicode) { EncodeUnicode(buffer,"Note",4); - if (mywstrncasecmp(buffer, h->section, 4)) found = true; + if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; } else { - if (mystrncasecmp("Note", h->section, 4)) found = true; + if (mystrncasecmp("Note", h->SectionName, 4)) found = true; } if (found) { - readvalue = ReadCFGText(file_info, h->section, "Text", UseUnicode); + 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)); @@ -2578,7 +2584,7 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) dbgprintf("Increase GSM_BACKUP_MAX_NOTE\n"); return GE_MOREMEMORY; } - ReadNoteEntry(file_info, h->section, backup->Note[num],UseUnicode); + ReadNoteEntry(file_info, h->SectionName, backup->Note[num],UseUnicode); num++; } } @@ -2591,7 +2597,7 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) /* ---------------------- backup files for SMS ----------------------------- */ -static void ReadSMSBackupEntry(CFG_Header *file_info, char *section, GSM_SMSMessage *SMS) +static void ReadSMSBackupEntry(INI_Section *file_info, char *section, GSM_SMSMessage *SMS) { unsigned char buffer[10000], *readvalue; @@ -2681,18 +2687,18 @@ static void ReadSMSBackupEntry(CFG_Header *file_info, char *section, GSM_SMSMess static GSM_Error GSM_ReadSMSBackupTextFile(char *FileName, GSM_SMS_Backup *backup) { - CFG_Header *file_info, *h; + INI_Section *file_info, *h; char *readvalue; int num; backup->SMS[0] = NULL; - file_info = CFG_ReadFile(FileName, false); + file_info = INI_ReadFile(FileName, false); num = 0; - for (h = file_info; h != NULL; h = h->next) { - if (mystrncasecmp("SMSBackup", h->section, 9)) { - readvalue = ReadCFGText(file_info, h->section, "Number", false); + 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)); @@ -2703,7 +2709,7 @@ static GSM_Error GSM_ReadSMSBackupTextFile(char *FileName, GSM_SMS_Backup *backu return GE_MOREMEMORY; } backup->SMS[num]->Location = num + 1; - ReadSMSBackupEntry(file_info, h->section, backup->SMS[num]); + ReadSMSBackupEntry(file_info, h->SectionName, backup->SMS[num]); num++; } } diff --git a/common/service/gsmcal.h b/common/service/gsmcal.h index a5d71e2a0..fbeaa82ef 100644 --- a/common/service/gsmcal.h +++ b/common/service/gsmcal.h @@ -257,8 +257,14 @@ GSM_Error GSM_EncodeVCALENDAR(char *Buffer, int *Length, GSM_CalendarEntry *note bool IsCalendarNoteFromThePast(GSM_CalendarEntry *note); typedef struct { - int StartDay; // Monday = 1, Tuesday = 2,... - int AutoDelete; // 0 = no delete, 1 = after day,... + /** + * Monday = 1, Tuesday = 2,... + */ + int StartDay; + /** + * 0 = no delete, 1 = after day,... + */ + int AutoDelete; } GSM_CalendarSettings; /** diff --git a/common/service/gsmcall.h b/common/service/gsmcall.h index 0594ab49d..c8265ab95 100644 --- a/common/service/gsmcall.h +++ b/common/service/gsmcall.h @@ -176,7 +176,7 @@ typedef enum { GN_CALL_Default } GSM_CallShowNumber; -#endif /* _gsm_call_h */ +#endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: diff --git a/common/service/gsmlogo.c b/common/service/gsmlogo.c index afa0e457b..6d4a931a2 100644 --- a/common/service/gsmlogo.c +++ b/common/service/gsmlogo.c @@ -72,17 +72,16 @@ static bool PHONE_IsPointBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, int x case GSM_NokiaOperatorLogo: case GSM_Nokia7110OperatorLogo: case GSM_NokiaCallerLogo: + case GSM_EMSVariablePicture: + case GSM_EMSSmallPicture: + case GSM_EMSMediumPicture: + case GSM_EMSBigPicture: pixel=width*y + x; i=(buffer[pixel/8] & 1<<(7-(pixel%8))); break; case GSM_NokiaPictureImage: i=(buffer[9*y + (x/8)] & 1<<(7-(x%8))); break; - case GSM_EMSVariablePicture: - case GSM_EMSSmallPicture: - case GSM_EMSMediumPicture: - case GSM_EMSBigPicture: - break; } if (i) return true; else return false; } @@ -119,7 +118,7 @@ void PHONE_DecodeBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, GSM_Bitmap *B int width, height, x,y; PHONE_GetBitmapWidthHeight(Type, &width, &height); - if (Type != GSM_Nokia6510OperatorLogo && Type != GSM_Nokia7110OperatorLogo) { + if (Type != GSM_Nokia6510OperatorLogo && Type != GSM_Nokia7110OperatorLogo && Type != GSM_EMSVariablePicture) { Bitmap->Height = height; Bitmap->Width = width; } @@ -131,12 +130,13 @@ void PHONE_DecodeBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, GSM_Bitmap *B case GSM_NokiaStartupLogo : case GSM_Nokia7110StartupLogo : case GSM_Nokia6210StartupLogo : Bitmap->Type=GSM_StartupLogo; break; - case GSM_NokiaPictureImage : Bitmap->Type=GSM_PictureImage; break; + case GSM_NokiaPictureImage : case GSM_EMSVariablePicture : case GSM_EMSSmallPicture : case GSM_EMSMediumPicture : - case GSM_EMSBigPicture : break; + case GSM_EMSBigPicture : Bitmap->Type=GSM_PictureImage; break; } + GSM_ClearBitmap(Bitmap); for (x=0;xWidth;x++) { for (y=0;yHeight;y++) { @@ -311,8 +311,8 @@ GSM_Error Bitmap2BMP(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) header[22]=bitmap->Height; header[18]=bitmap->Width; - pos=7; - sizeimage=0; + pos = 7; + sizeimage = 0; /*lines are written from the last to the first*/ for (y=bitmap->Height-1;y>=0;y--) { i=1; @@ -333,8 +333,7 @@ GSM_Error Bitmap2BMP(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) sizeimage++; if (i!=1) { /*each line is written in multiply of 4 bytes*/ - while (i!=5) - { + while (i!=5) { sizeimage++; i++; } @@ -389,8 +388,7 @@ GSM_Error Bitmap2BMP(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) } if (i!=1) { /*each line is written in multiply of 4 bytes*/ - while (i!=5) - { + while (i!=5) { buff[0]=0; if (isfile) fwrite(buff, 1, sizeof(buff), file); else { @@ -631,8 +629,11 @@ GSM_Error BMP2Bitmap(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) if (bitmap->Type == GSM_None) bitmap->Type = GSM_StartupLogo; if (file!=NULL) isfile=true; - if (isfile) fread(buff, 1, 34, file); - else memcpy(buff,buffer,34); + if (isfile) { + fread(buff, 1, 34, file); + } else { + memcpy(buff,buffer,34); + } /* height and width of image in the file */ h=buff[22]+256*buff[21]; @@ -649,11 +650,11 @@ GSM_Error BMP2Bitmap(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) #ifdef DEBUG dbgprintf("Number of colors in BMP file: "); switch (buff[28]) { - case 1 : dbgprintf("2 (supported)\n"); break; - case 4 : dbgprintf("16 (NOT SUPPORTED)\n"); break; - case 8 : dbgprintf("256 (NOT SUPPORTED)\n"); break; - case 24 : dbgprintf("True Color (NOT SUPPORTED)\n"); break; - default : dbgprintf("unknown\n"); break; + case 1 : dbgprintf("2 (supported)\n"); break; + case 4 : dbgprintf("16 (NOT SUPPORTED)\n"); break; + case 8 : dbgprintf("256 (NOT SUPPORTED)\n"); break; + case 24 : dbgprintf("True Color (NOT SUPPORTED)\n"); break; + default : dbgprintf("unknown\n"); break; } #endif if (buff[28]!=1) { @@ -664,10 +665,10 @@ GSM_Error BMP2Bitmap(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) #ifdef DEBUG dbgprintf("Compression in BMP file: "); switch (buff[30]) { - case 0 :dbgprintf("no compression (supported)\n"); break; - case 1 :dbgprintf("RLE8 (NOT SUPPORTED)\n"); break; - case 2 :dbgprintf("RLE4 (NOT SUPPORTED)\n"); break; - default :dbgprintf("unknown\n"); break; + case 0 :dbgprintf("no compression (supported)\n"); break; + case 1 :dbgprintf("RLE8 (NOT SUPPORTED)\n"); break; + case 2 :dbgprintf("RLE4 (NOT SUPPORTED)\n"); break; + default :dbgprintf("unknown\n"); break; } #endif if (buff[30]!=0) { @@ -677,12 +678,12 @@ GSM_Error BMP2Bitmap(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) /* read rest of header (if exists) and color palette */ if (isfile) { - pos=buff[10]-34; - fread(buff, 1, pos, file); - } else { - pos=buff[10]-34; - buffpos=buff[10]; - memcpy (buff,buffer+34,pos); + pos=buff[10]-34; + fread(buff, 1, pos, file); + } else { + pos=buff[10]-34; + buffpos=buff[10]; + memcpy (buff,buffer+34,pos); } #ifdef DEBUG @@ -701,16 +702,14 @@ GSM_Error BMP2Bitmap(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) pos=7; /* lines are written from the last to the first */ - for (y=h-1;y>=0;y--) { - i=1; - for (x=0;x=0;y--) { i=1; + for (x=0;xWidth && y<=bitmap->Height) { - if (first_white) { + if (x<=bitmap->Width && y<=bitmap->Height) { if (first_white) { if ((buff[0]&(1<0) GSM_SetPointBitmap(bitmap,x,y); @@ -734,13 +732,13 @@ GSM_Error BMP2Bitmap(unsigned char *buffer, FILE *file,GSM_Bitmap *bitmap) pos=7; if (i!=1) { /* each line is written in multiply of 4 bytes */ - while (i!=5) { - - if (isfile) fread(buff, 1, 1, file); - else { - memcpy (buff,buffer+buffpos,1); - buffpos++; - } + while (i!=5) { + if (isfile) { + fread(buff, 1, 1, file); + } else { + memcpy (buff,buffer+buffpos,1); + buffpos++; + } #ifdef DEBUG sizeimage++; #endif diff --git a/common/service/gsmlogo.h b/common/service/gsmlogo.h index 4eb5f8c2f..b371fb2be 100644 --- a/common/service/gsmlogo.h +++ b/common/service/gsmlogo.h @@ -19,23 +19,58 @@ typedef enum { #define GSM_BITMAP_SIZE 864 -/* Structure to hold incoming/outgoing bitmaps (and welcome-notes). */ +/** + * Structure to hold incoming/outgoing bitmaps (and welcome-notes). + */ typedef struct { - unsigned char Location; /* Caller group number */ - unsigned char Height; /* Bitmap height (pixels) */ - unsigned char Width; /* Bitmap width (pixels) */ - GSM_Bitmap_Types Type; /* Bitmap type */ - char NetworkCode[7]; /* Network operator code */ - char Text [256]; /* Text used for (dealer) welcome-note - * or callergroup name or Picture Image text */ - bool DefaultName; /* When get caller group - is default name ? */ - unsigned char Bitmap [GSM_BITMAP_SIZE]; /* Actual Bitmap ((65+7)/8*96=864) */ - bool DefaultBitmap; - unsigned char Ringtone; /* Ringtone ID sent with caller group */ - bool DefaultRingtone; - bool Enabled; /* With caller logos = displayed or not */ - char Sender [GSM_MAX_NUMBER_LENGTH+1];/* For Picture Images - number of sender */ - unsigned char ID; + /** + * Caller group number + */ + unsigned char Location; + /** + * Bitmap height in pixels + */ + unsigned char Height; + /** + * Bitmap width in pixels + */ + unsigned char Width; + /** + * Bitmap type + */ + GSM_Bitmap_Types Type; + /** + * Network operator code + */ + char NetworkCode[7]; + /** + * Text used for (dealer) welcome-note + * or callergroup name or Picture Image text + */ + char Text [256]; + /** + * When get caller group - is default name ? + */ + bool DefaultName; + /** + * Actual Bitmap ((65+7)/8*96=864) + */ + unsigned char Bitmap[GSM_BITMAP_SIZE]; + bool DefaultBitmap; + /** + * Ringtone ID sent with caller group + */ + unsigned char Ringtone; + bool DefaultRingtone; + /** + * With caller logos = displayed or not + */ + bool Enabled; + /** + * For Picture Images - number of sender + */ + char Sender [GSM_MAX_NUMBER_LENGTH+1]; + unsigned char ID; } GSM_Bitmap; #define MAX_MULTI_BITMAP 6 diff --git a/common/service/gsmmisc.h b/common/service/gsmmisc.h index 6889c1107..a4cd9f329 100644 --- a/common/service/gsmmisc.h +++ b/common/service/gsmmisc.h @@ -3,13 +3,11 @@ #include "../gsmcomon.h" -/* Define an enum for specifying memory types for retrieving phonebook - * entries, SMS messages etc. This type is not mobile specific - the model - * code should take care of translation to mobile specific numbers - see 6110 - * code. +/* Define an enum for specifying memory types for getting phonebook entries, + * SMS messages etc. Phone modules can translate it to own values */ typedef enum { - /* 01/07/99: Two letter codes follow GSM 07.07 release 6.2.0 */ + /* Two letter codes are from GSM 07.07 release 6.2.0 */ /** * Internal memory of the mobile equipment */ @@ -61,23 +59,49 @@ typedef enum { /* --------------------------- security codes ------------------------------ */ -/* Definition of security codes. */ +/** + * Definition of security codes. + */ typedef enum { - GSCT_SecurityCode = 0x01, /* Security code. */ - GSCT_Pin, /* PIN. */ - GSCT_Pin2, /* PIN 2. */ - GSCT_Puk, /* PUK. */ - GSCT_Puk2, /* PUK 2. */ - GSCT_None /* Code not needed. */ + /** + * Security code. + */ + GSCT_SecurityCode = 0x01, + /** + * PIN. + */ + GSCT_Pin, + /** + * PIN 2. + */ + GSCT_Pin2, + /** + * PUK. + */ + GSCT_Puk, + /** + * PUK 2. + */ + GSCT_Puk2, + /** + * Code not needed. + */ + GSCT_None } GSM_SecurityCodeType; #define GSM_SECURITY_CODE_LEN 15 -/* Security code definition. */ +/** + * Security code definition. + */ typedef struct { - /* Type of the code. */ + /** + * Type of the code. + */ GSM_SecurityCodeType Type; - /* Actual code. */ + /** + * Actual code. + */ char Code[GSM_SECURITY_CODE_LEN+1]; } GSM_SecurityCode; @@ -95,17 +119,38 @@ typedef enum { GSM_KEY_8, GSM_KEY_9, GSM_KEY_0, - GSM_KEY_HASH, /* # */ - GSM_KEY_ASTERISK, /* * */ + /** + * # + */ + GSM_KEY_HASH, + /** + * * + */ + GSM_KEY_ASTERISK, GSM_KEY_POWER, - GSM_KEY_GREEN, /* in some phone ie. N5110 sometimes works identical to POWER */ - GSM_KEY_RED, /* (c) key in some phone: ie. N5110 */ - GSM_KEY_INCREASEVOLUME, /* doesn't available in some phones as separate button: ie. N5110 */ - GSM_KEY_DECREASEVOLUME, /* doesn't available in some phones as separate button: ie. N5110 */ + /** + * in some phone ie. N5110 sometimes works identical to POWER + */ + GSM_KEY_GREEN, + /** + * (c) key in some phone: ie. N5110 + */ + GSM_KEY_RED, + /** + * doesn't available in some phones as separate button: ie. N5110 + */ + GSM_KEY_INCREASEVOLUME, + /** + * doesn't available in some phones as separate button: ie. N5110 + */ + GSM_KEY_DECREASEVOLUME, GSM_KEY_UP = 0x17, GSM_KEY_DOWN, GSM_KEY_MENU, - GSM_KEY_NAMES /* doesn't available in some phone: ie. N5110 */ + /** + * doesn't available in some phone: ie. N5110 + */ + GSM_KEY_NAMES } GSM_KeyCode; GSM_Error MakeKeySequence(char *text, GSM_KeyCode *KeyCode, int *Length); @@ -130,15 +175,21 @@ typedef struct { /* ----------------------------- power source ------------------------------ */ typedef enum { - GSM_BatteryPowered = 1, - GSM_BatteryConnected, - GSM_BatteryNotConnected, - GSM_PowerFault + GSM_BatteryPowered = 1, + GSM_BatteryConnected, + GSM_BatteryNotConnected, + GSM_PowerFault } GSM_ChargeState; typedef struct { - int BatteryPercent; /* Signal strength in percent, -1 = unknown */ - GSM_ChargeState ChargeState; /* Charge state */ + /** + * Signal strength in percent, -1 = unknown + */ + int BatteryPercent; + /** + * Charge state + */ + GSM_ChargeState ChargeState; } GSM_BatteryCharge; /* ------------------------------ categories ------------------------------- */ @@ -146,19 +197,19 @@ typedef struct { #define GSM_MAX_CATEGORY_NAME_LENGTH 50 typedef enum { - Category_ToDo, - Category_Phonebook + Category_ToDo, + Category_Phonebook } GSM_CategoryType; typedef struct { - GSM_CategoryType Type; - int Location; - unsigned char Name[(GSM_MAX_CATEGORY_NAME_LENGTH + 1)*2]; + GSM_CategoryType Type; + int Location; + unsigned char Name[(GSM_MAX_CATEGORY_NAME_LENGTH + 1)*2]; } GSM_Category; typedef struct { - GSM_CategoryType Type; - int Used; + GSM_CategoryType Type; + int Used; } GSM_CategoryStatus; /* ------------------- radio FM stations ---------------------------------- */ diff --git a/common/service/gsmnet.c b/common/service/gsmnet.c dissimilarity index 93% index e04fbb9e7..85aebb5c1 100644 --- a/common/service/gsmnet.c +++ b/common/service/gsmnet.c @@ -1,456 +1,442 @@ -#include - -#include "gsmnet.h" -#include "../misc/coding/coding.h" - -GSM_Country GSM_Countries[] = { - { "202", "Greece" }, - { "204", "Netherlands" }, - { "206", "Belgium" }, - { "208", "France" }, - { "213", "Andorra" }, - { "214", "Spain" }, - { "216", "Hungary" }, - { "218", "Bosnia Herzegovina" }, - { "219", "Croatia" }, - { "220", "Yugoslavia" }, - { "222", "Italy" }, - { "226", "Romania" }, - { "228", "Switzerland" }, - { "230", "Czech Republic" }, - { "231", "Slovak Republic" }, - { "232", "Austria" }, - { "234", "United Kingdom" }, - { "238", "Denmark" }, - { "240", "Sweden" }, - { "242", "Norway" }, - { "244", "Finland" }, - { "246", "Lithuania" }, - { "247", "Latvia" }, - { "248", "Estonia" }, - { "250", "Russia" }, - { "255", "Ukraine" }, - { "259", "Moldova" }, - { "260", "Poland" }, - { "262", "Germany" }, - { "266", "Gibraltar" }, - { "268", "Portugal" }, - { "270", "Luxembourg" }, - { "272", "Ireland" }, - { "274", "Iceland" }, - { "276", "Albania" }, - { "278", "Malta" }, - { "280", "Cyprus" }, - { "282", "Georgia" }, - { "283", "Armenia" }, - { "284", "Bulgaria" }, - { "286", "Turkey" }, - { "290", "Greenland" }, - { "293", "Slovenia" }, - { "294", "Macedonia" }, - { "302", "Canada" }, - { "310", "U.S.A." }, - { "340", "French West Indies" }, - { "400", "Azerbaijan" }, - { "404", "India" }, - { "410", "Pakistan" }, - { "413", "Sri Lanka" }, - { "415", "Lebanon" }, - { "416", "Jordan" }, - { "417", "Syria" }, - { "418", "Iraq" }, - { "419", "Kuwait" }, - { "420", "Saudi Arabia" }, - { "422", "Oman" }, - { "424", "United Arab Emirates" }, - { "425", "Israel" }, - { "426", "Bahrain" }, - { "427", "Qatar" }, - { "432", "Iran" }, - { "434", "Uzbekistan" }, - { "437", "Kyrgyz Republic" }, - { "452", "Vietnam" }, - { "454", "Hong Kong" }, - { "455", "Macau" }, - { "456", "Cambodia" }, - { "457", "Lao" }, - { "460", "China" }, - { "466", "Taiwan" }, - { "470", "Bangladesh" }, - { "502", "Malaysia" }, - { "505", "Australia" }, - { "510", "Indonesia" }, - { "515", "Philippines" }, - { "520", "Thailand" }, - { "525", "Singapore" }, - { "528", "Brunei Darussalam" }, - { "530", "New Zealand" }, - { "542", "Fiji" }, - { "546", "New Caledonia" }, - { "547", "French Polynesia" }, - { "602", "Egypt" }, - { "603", "Algeria" }, - { "604", "Morocco" }, - { "605", "Tunisia" }, - { "608", "Senegal" }, - { "611", "Guinea" }, - { "612", "Cote d'Ivoire" }, - { "615", "Togo" }, - { "617", "Mauritius" }, - { "618", "Liberia" }, - { "620", "Ghana" }, - { "624", "Cameroon" }, - { "625", "Cape Verde" }, - { "633", "Seychelles" }, - { "634", "Mozambique" }, - { "634", "Sudan" }, - { "635", "Rwanda" }, - { "636", "Ethiopia" }, - { "640", "Tanzania" }, - { "641", "Uganda" }, - { "645", "Zambia" }, - { "646", "Madagascar" }, - { "647", "Reunion" }, - { "648", "Zimbabwe" }, - { "649", "Namibia" }, - { "650", "Malawi" }, - { "651", "Lesotho" }, - { "652", "Botswana" }, - { "655", "South Africa" }, - { "730", "Chile" }, - { "734", "Venezuela" }, - - { "undefined", "unknown" } -}; - -GSM_Network GSM_Networks[] = { - { "202 01", "Cosmote" }, - { "202 05", "PANAFON" }, - { "202 10", "TELESTET" }, - { "204 04", "LIBERTEL" }, - { "204 08", "KPN Telecom" }, - { "204 12", "O2" }, - { "204 16", "BEN" }, - { "204 20", "Dutchtone NV" }, - { "206 01", "PROXIMUS" }, - { "206 10", "Mobistar" }, - { "206 20", "Base" }, - { "208 01", "ITINERIS" }, - { "208 10", "SFR" }, - { "208 20", "Bouygues Telecom" }, - { "213 03", "MOBILAND" }, - { "214 01", "Airtel GSM 900-Spain" }, - { "214 03", "Retevision Movil" }, - { "214 07", "MOVISTAR" }, - { "216 01", "Pannon GSM" }, - { "216 70", "Vodafone" }, - { "216 30", "Westel 900" }, - { "218 90", "GSMBIH" }, - { "219 01", "CRONET" }, - { "219 10", "VIP" }, - { "220 01", "MOBTEL" }, - { "220 02", "ProMonte GSM" }, - { "220 03", "Telekom Srbije" }, - { "222 01", "Telecom Italia Mobile" }, - { "222 10", "OMNITEL" }, - { "222 88", "Wind Telecomunicazioni SpA" }, - { "226 01", "CONNEX GSM" }, - { "226 10", "DIALOG" }, - { "228 01", "NATEL International" }, - { "228 02", "diAx Mobile AG" }, - { "230 01", "T-Mobile CZ" }, - { "230 02", "EuroTel" }, - { "230 03", "Oskar" }, - { "231 01", "Orange" }, - { "231 02", "EuroTel GSM" }, - { "232 01", "A1" }, - { "232 03", "T-Mobile AT" }, - { "232 05", "ONE" }, - { "232 07", "tele.ring" }, - { "234 10", "Cellnet" }, - { "234 15", "Vodafone" }, - { "234 30", "T-Mobile UK" }, - { "234 33", "ORANGE" }, - { "234 50", "Jersey Telecoms GSM" }, - { "234 55", "Guernsey Telecoms GSM" }, - { "234 58", "PRONTO GSM" }, - { "238 01", "TDK-MOBIL" }, - { "238 02", "SONOFON" }, - { "238 20", "TELIA DK" }, - { "238 30", "Mobilix" }, - { "240 01", "Telia AB" }, - { "240 07", "COMVIQ" }, - { "240 08", "EUROPOLITAN" }, - { "242 01", "Telenor Mobil" }, - { "242 02", "NetCom GSM" }, - { "244 03", "Telia City (Finland)" }, - { "244 05", "Radiolinja" }, - { "244 09", "Finnet" }, - { "244 12", "DNA (FI2G)" }, - { "244 14", "Alands Mobiltelefon" }, - { "244 91", "Sonera" }, - { "246 01", "OMNITEL" }, - { "246 02", "Bite GSM" }, - { "247 01", "LMT LV" }, - { "247 02", "BALTCOM GSM" }, - { "248 01", "EMT GSM" }, - { "248 02", "Radiolinja Eesti AS" }, - { "248 03", "Q GSM" }, - { "250 01", "Mobile Telesystems" }, - { "250 02", "North-West GSM" }, - { "250 05", "Siberian Cellular Systems 900" }, - { "250 07", "BM Telecom" }, - { "250 10", "Don Telecom" }, - { "250 12", "FECS-900" }, - { "250 13", "Kuban GSM" }, - { "250 39", "Uraltel" }, - { "250 44", "North Caucasian GSM" }, - { "250 99", "BeeLine" }, - { "255 01", "UMC" }, - { "255 02", "WellCOM" }, - { "255 03", "Kyivstar" }, - { "255 05", "Golden Telecom" }, - { "259 01", "VOXTEL" }, - { "260 01", "PLUS GSM" }, - { "260 02", "ERA GSM" }, - { "260 03", "IDEA Centertel" }, - { "262 01", "T-Mobile D" }, - { "262 02", "D2 PRIVAT" }, - { "262 03", "E-Plus" }, - { "262 07", "Interkom" }, - { "266 01", "Gibtel GSM" }, - { "268 01", "TELECEL" }, - { "268 03", "OPTIMUS" }, - { "268 06", "TMN" }, - { "270 01", "LUXGSM" }, - { "270 77", "TANGO" }, - { "272 01", "EIRCELL-GSM" }, - { "272 02", "Digifone" }, - { "274 01", "Landssiminn GSM 900" }, - { "274 02", "TAL hf" }, - { "276 01", "AMC" }, - { "278 01", "Vodafone Malta Limited" }, - { "280 01", "CYTAGSM" }, - { "282 01", "Geocell Limited" }, - { "282 02", "Magti GSM" }, - { "283 01", "ArmGSM" }, - { "284 01", "M-TEL GSM BG" }, - { "286 01", "Turkcell" }, - { "286 02", "TELSIM GSM" }, - { "288 01", "Faroese Telecom" }, - { "290 01", "Tele Greenland" }, - { "293 40", "SI.MOBIL d. d." }, - { "293 41", "MOBITEL" }, - { "293 70", "SI VEGA 070" }, - { "294 01", "MobiMak" }, - { "302 37", "Microcell Connexions Inc" }, - { "302 72", "Rogers AT&T" }, - { "310 01", "Cellnet" }, - { "310 02", "Sprint Spectrum" }, - { "310 11", "Wireless 2000 Telephone Co." }, - { "310 15", "BellSouth Mobility DCS" }, - { "310 16", "T-Mobile" }, - { "310 17", "Pac Bell" }, - { "310 20", "T-Mobile" }, - { "310 21", "T-Mobile" }, - { "310 22", "T-Mobile" }, - { "310 23", "T-Mobile" }, - { "310 24", "T-Mobile" }, - { "310 25", "T-Mobile" }, - { "310 26", "T-Mobile" }, - { "310 27", "T-Mobile" }, - { "310 31", "T-Mobile" }, - { "310 38", "AT&T Wireless" }, - { "310 58", "T-Mobile" }, - { "310 66", "T-Mobile" }, - { "310 77", "Iowa Wireless Services LP" }, - { "310 80", "T-Mobile" }, - { "340 01", "AMERIS" }, - { "400 01", "AZERCELL GSM" }, - { "400 02", "Bakcell GSM 2000" }, - { "404 07", "TATA Cellular" }, - { "404 10", "AirTel" }, - { "404 11", "Essar Cellphone" }, - { "404 12", "Escotel" }, - { "404 14", "Modicom" }, - { "404 15", "Essar Cellphone" }, - { "404 20", "Max Touch" }, - { "404 21", "BPL - Mobile" }, - { "404 27", "BPL USWEST Cellular" }, - { "404 30", "Command" }, - { "404 40", "SkyCell" }, - { "404 41", "RPG Cellular" }, - { "404 42", "AIRCEL" }, - { "410 01", "Mobilink" }, - { "413 02", "DIALOG GSM" }, - { "415 01", "CELLIS" }, - { "415 03", "LIBANCELL" }, - { "416 01", "Fastlink" }, - { "417 09", "MOBILE SYRIA" }, - { "419 02", "MTCNet" }, - { "420 01", "Al Jawwal" }, - { "420 07", "E.A.E" }, - { "422 02", "GTO" }, - { "424 02", "UAE-ETISALAT" }, - { "425 01", "Partner Communications Company Ltd" }, - { "425 02", "Cellcom Israel Ltd" }, - { "426 01", "BHR MOBILE PLUS" }, - { "427 01", "QATARNET" }, - { "432 11", "TCI" }, - { "434 04", "Daewoo Unitel" }, - { "434 05", "Coscom" }, - { "437 01", "Bitel" }, - { "454 00", "TCSL GSM" }, - { "454 04", "HKGHT" }, - { "454 06", "SMARTONE GSM" }, - { "454 10", "New World PCS" }, - { "454 12", "PEOPLES" }, - { "454 16", "SUNDAY" }, - { "455 01", "TELEMOVEL+ GSM900-Macau" }, - { "456 01", "MobiTel" }, - { "456 02", "SAMART-GSM" }, - { "457 01", "Lao Shinawatra Telecom" }, - { "460 00", "China Telecom GSM" }, - { "460 01", "CU-GSM" }, - { "466 01", "Far EasTone Telecoms 900" }, - { "466 06", "TUNTEX GSM 1800" }, - { "466 88", "KG Telecom" }, - { "466 92", "Chunghwa GSM" }, - { "466 93", "MobiTai" }, - { "466 97", "TWNGSM" }, - { "466 99", "TransAsia" }, - { "470 01", "GrameenPhone Ltd" }, - { "470 19", "Mobile 2000" }, - { "502 12", "Maxis Mobile" }, - { "502 13", "TM Touch" }, - { "502 16", "DiGi 1800" }, - { "502 17", "ADAM" }, - { "502 19", "CELCOM" }, - { "505 01", "MobileNet" }, - { "505 02", "OPTUS" }, - { "505 03", "VODAFONE" }, - { "505 08", "One.Tel" }, - { "510 01", "SATELINDO" }, - { "510 08", "LIPPO TELECOM" }, - { "510 10", "TELKOMSEL" }, - { "510 11", "Excelcom" }, - { "510 21", "INDOSAT" }, - { "515 01", "ISLACOM" }, - { "515 02", "Globe Telecom" }, - { "520 01", "AIS GSM" }, - { "520 10", "WCS" }, - { "520 18", "Worldphone 1800" }, - { "520 23", "HELLO" }, - { "525 01", "SingTel Mobile" }, - { "525 02", "ST-PCN" }, - { "525 03", "MOBILEONE" }, - { "528 11", "DSTCom" }, - { "530 01", "Vodafone New Zealand Limited" }, - { "542 01", "Vodafone" }, - { "546 01", "Mobilis" }, - { "547 20", "VINI" }, - { "602 01", "MobiNil" }, - { "602 02", "Tunicell" }, - { "603 01", "ALGERIAN MOBILE NETWORK" }, - { "604 01", "I A M" }, - { "608 01", "ALIZE" }, - { "611 02", "Lagui" }, - { "612 03", "IVOIRIS" }, - { "612 05", "Telecel" }, - { "615 01", "TOGO CELL" }, - { "617 01", "Cellplus Mobile Comms" }, - { "618 01", "Omega" }, - { "620 01", "SPACEFON" }, - { "625 01", "CVMOVEL" }, - { "633 01", "Seychelles Cellular Services" }, - { "633 10", "AIRTEL" }, - { "634 01", "MobiTel" }, - { "635 10", "Rwandacell" }, - { "636 01", "ETMTN" }, - { "640 01", "TRITEL" }, - { "641 10", "MTN-Uganda" }, - { "642 02", "ANTARIS" }, - { "643 01", "T.D.M GSM 900" }, - { "645 01", "ZAMCELL" }, - { "646 01", "Madacom" }, - { "646 03", "Sacel Madagascar S.A." }, - { "647 10", "SRR" }, - { "648 01", "NET*ONE" }, - { "648 03", "Telecel" }, - { "649 01", "MTC" }, - { "650 01", "Callpoint 900" }, - { "651 01", "Vodacom Lesotho (Pty) Ltd" }, - { "655 01", "Vodacom" }, - { "655 10", "MTN" }, - { "680 38", "NPI Wireless" }, - { "730 01", "Entel Telefonia Movi" }, - { "730 10", "Entel PCS" }, - { "734 01", "Infonet" }, - - { "undefined", "unknown" } -}; - -char *GSM_GetNetworkName(char *NetworkCode) -{ - int index = 0; - static char retval[200]; - - while (strcmp(GSM_Networks[index].Code, NetworkCode) && - strcmp(GSM_Networks[index].Code, "undefined")) index++; - - EncodeUnicode(retval, GSM_Networks[index].Name, strlen(GSM_Networks[index].Name)); - - return retval; -} - -char *GSM_GetNetworkCode(char *NetworkName) -{ - int index = 0; - - while (strcmp(GSM_Networks[index].Name, DecodeUnicodeString(NetworkName)) && - strcmp(GSM_Networks[index].Code, "undefined")) index++; - - return GSM_Networks[index].Code; -} - -char *GSM_GetCountryName(char *CountryCode) -{ - int index = 0; - static char retval[200]; - - while (strncmp(GSM_Countries[index].Code, CountryCode, 3) && - strcmp(GSM_Countries[index].Code, "undefined")) index++; - - EncodeUnicode(retval, GSM_Countries[index].Name, strlen(GSM_Countries[index].Name)); - - return retval; -} - -char *GSM_GetCountryCode(char *CountryName) -{ - int index = 0; - - while (strcmp(GSM_Countries[index].Name, DecodeUnicodeString(CountryName)) && - strcmp(GSM_Countries[index].Code, "undefined")) index++; - - return GSM_Countries[index].Code; -} - -void NOKIA_EncodeNetworkCode(unsigned char* buffer, unsigned char* output) -{ - EncodeBCD(buffer, output, 6, false); - buffer[1] = buffer[1] | 0xf0; -} - -void NOKIA_DecodeNetworkCode(unsigned char* buffer, unsigned char* output) -{ - DecodeBCD(output, buffer, 3); - output[6] = output[5]; - output[5] = output[4]; - output[4] = output[3]; - output[3] = ' '; -} - -/* How should editor hadle tabs in this file? Add editor commands here. - * vim: noexpandtab sw=8 ts=8 sts=8: - */ +#include + +#include "gsmnet.h" +#include "../misc/coding/coding.h" + +unsigned char *GSM_Countries[] = { + "202", "Greece", + "204", "Netherlands", + "206", "Belgium", + "208", "France", + "213", "Andorra" , + "214", "Spain", + "216", "Hungary", + "218", "Bosnia Herzegovina", + "219", "Croatia", + "220", "Yugoslavia", + "222", "Italy", + "226", "Romania", + "228", "Switzerland", + "230", "Czech Republic", + "231", "Slovak Republic", + "232", "Austria", + "234", "United Kingdom", + "238", "Denmark", + "240", "Sweden", + "242", "Norway", + "244", "Finland", + "246", "Lithuania", + "247", "Latvia", + "248", "Estonia", + "250", "Russia", + "255", "Ukraine", + "259", "Moldova", + "260", "Poland", + "262", "Germany", + "266", "Gibraltar", + "268", "Portugal", + "270", "Luxembourg", + "272", "Ireland", + "274", "Iceland", + "276", "Albania", + "278", "Malta", + "280", "Cyprus", + "282", "Georgia", + "283", "Armenia", + "284", "Bulgaria", + "286", "Turkey", + "290", "Greenland", + "293", "Slovenia", + "294", "Macedonia", + "302", "Canada", + "310", "U.S.A.", + "340", "French West Indies", + "400", "Azerbaijan", + "404", "India", + "410", "Pakistan", + "413", "Sri Lanka", + "415", "Lebanon", + "416", "Jordan", + "417", "Syria", + "418", "Iraq", + "419", "Kuwait", + "420", "Saudi Arabia", + "422", "Oman", + "424", "United Arab Emirates", + "425", "Israel", + "426", "Bahrain", + "427", "Qatar", + "432", "Iran", + "434", "Uzbekistan", + "437", "Kyrgyz Republic", + "452", "Vietnam", + "454", "Hong Kong", + "455", "Macau", + "456", "Cambodia", + "457", "Lao", + "460", "China", + "466", "Taiwan", + "470", "Bangladesh", + "502", "Malaysia", + "505", "Australia", + "510", "Indonesia", + "515", "Philippines", + "520", "Thailand", + "525", "Singapore", + "528", "Brunei Darussalam", + "530", "New Zealand", + "542", "Fiji", + "546", "New Caledonia", + "547", "French Polynesia", + "602", "Egypt", + "603", "Algeria", + "604", "Morocco", + "605", "Tunisia", + "608", "Senegal", + "611", "Guinea", + "612", "Cote d'Ivoire", + "615", "Togo", + "617", "Mauritius", + "618", "Liberia", + "620", "Ghana", + "624", "Cameroon", + "625", "Cape Verde", + "633", "Seychelles", + "634", "Mozambique", + "634", "Sudan", + "635", "Rwanda", + "636", "Ethiopia", + "640", "Tanzania", + "641", "Uganda", + "645", "Zambia", + "646", "Madagascar", + "647", "Reunion", + "648", "Zimbabwe", + "649", "Namibia", + "650", "Malawi", + "651", "Lesotho", + "652", "Botswana", + "655", "South Africa", + "730", "Chile", + "734", "Venezuela", + + NULL +}; + +unsigned char *GSM_Networks[] = { + "202 01", "Cosmote", + "202 05", "PANAFON", + "202 10", "TELESTET", + "204 04", "LIBERTEL", + "204 08", "KPN Telecom", + "204 12", "O2", + "204 16", "BEN", + "204 20", "Dutchtone NV", + "206 01", "PROXIMUS", + "206 10", "Mobistar", + "206 20", "Base", + "208 01", "ITINERIS", + "208 10", "SFR", + "208 20", "Bouygues Telecom", + "213 03", "MOBILAND", + "214 01", "Airtel GSM 900-Spain", + "214 03", "Retevision Movil", + "214 07", "MOVISTAR", + "216 01", "Pannon GSM", + "216 70", "Vodafone", + "216 30", "Westel 900", + "218 90", "GSMBIH", + "219 01", "CRONET", + "219 10", "VIP", + "220 01", "MOBTEL", + "220 02", "ProMonte GSM", + "220 03", "Telekom Srbije", + "222 01", "Telecom Italia Mobile", + "222 10", "OMNITEL", + "222 88", "Wind Telecomunicazioni SpA", + "226 01", "CONNEX GSM", + "226 10", "DIALOG", + "228 01", "NATEL International", + "228 02", "diAx Mobile AG", + "230 01", "T-Mobile CZ", + "230 02", "EuroTel", + "230 03", "Oskar", + "231 01", "Orange", + "231 02", "EuroTel GSM", + "232 01", "A1", + "232 03", "T-Mobile AT", + "232 05", "ONE", + "232 07", "tele.ring", + "234 10", "Cellnet", + "234 15", "Vodafone", + "234 30", "T-Mobile UK", + "234 33", "ORANGE", + "234 50", "Jersey Telecoms GSM", + "234 55", "Guernsey Telecoms GSM", + "234 58", "PRONTO GSM", + "238 01", "TDK-MOBIL", + "238 02", "SONOFON", + "238 20", "TELIA DK", + "238 30", "Mobilix", + "240 01", "Telia AB", + "240 07", "COMVIQ", + "240 08", "EUROPOLITAN", + "242 01", "Telenor Mobil", + "242 02", "NetCom GSM", + "244 03", "Telia City (Finland)", + "244 05", "Radiolinja", + "244 09", "Finnet", + "244 12", "DNA (FI2G)", + "244 14", "Alands Mobiltelefon", + "244 91", "Sonera", + "246 01", "OMNITEL", + "246 02", "Bite GSM", + "247 01", "LMT LV", + "247 02", "BALTCOM GSM", + "248 01", "EMT GSM", + "248 02", "Radiolinja Eesti AS", + "248 03", "Q GSM", + "250 01", "Mobile Telesystems", + "250 02", "North-West GSM", + "250 05", "Siberian Cellular Systems 900", + "250 07", "BM Telecom", + "250 10", "Don Telecom", + "250 12", "FECS-900", + "250 13", "Kuban GSM", + "250 39", "Uraltel", + "250 44", "North Caucasian GSM", + "250 99", "BeeLine", + "255 01", "UMC", + "255 02", "WellCOM", + "255 03", "Kyivstar", + "255 05", "Golden Telecom", + "259 01", "VOXTEL", + "260 01", "PLUS GSM", + "260 02", "ERA GSM", + "260 03", "IDEA Centertel", + "262 01", "T-Mobile D", + "262 02", "D2 PRIVAT", + "262 03", "E-Plus", + "262 07", "Interkom", + "266 01", "Gibtel GSM", + "268 01", "TELECEL", + "268 03", "OPTIMUS", + "268 06", "TMN", + "270 01", "LUXGSM", + "270 77", "TANGO", + "272 01", "EIRCELL-GSM", + "272 02", "Digifone", + "274 01", "Landssiminn GSM 900", + "274 02", "TAL hf", + "276 01", "AMC", + "278 01", "Vodafone Malta Limited", + "280 01", "CYTAGSM", + "282 01", "Geocell Limited", + "282 02", "Magti GSM", + "283 01", "ArmGSM", + "284 01", "M-TEL GSM BG", + "286 01", "Turkcell", + "286 02", "TELSIM GSM", + "288 01", "Faroese Telecom", + "290 01", "Tele Greenland", + "293 40", "SI.MOBIL d. d.", + "293 41", "MOBITEL", + "293 70", "SI VEGA 070", + "294 01", "MobiMak", + "302 37", "Microcell Connexions Inc", + "302 72", "Rogers AT&T", + "310 01", "Cellnet", + "310 02", "Sprint Spectrum", + "310 11", "Wireless 2000 Telephone Co.", + "310 15", "BellSouth Mobility DCS", + "310 16", "T-Mobile", + "310 17", "Pac Bell", + "310 20", "T-Mobile", + "310 21", "T-Mobile", + "310 22", "T-Mobile", + "310 23", "T-Mobile", + "310 24", "T-Mobile", + "310 25", "T-Mobile", + "310 26", "T-Mobile", + "310 27", "T-Mobile", + "310 31", "T-Mobile", + "310 38", "AT&T Wireless", + "310 58", "T-Mobile", + "310 66", "T-Mobile", + "310 77", "Iowa Wireless Services LP", + "310 80", "T-Mobile", + "340 01", "AMERIS", + "400 01", "AZERCELL GSM", + "400 02", "Bakcell GSM 2000", + "404 07", "TATA Cellular", + "404 10", "AirTel", + "404 11", "Essar Cellphone", + "404 12", "Escotel", + "404 14", "Modicom", + "404 15", "Essar Cellphone", + "404 20", "Max Touch", + "404 21", "BPL - Mobile", + "404 27", "BPL USWEST Cellular", + "404 30", "Command", + "404 40", "SkyCell", + "404 41", "RPG Cellular", + "404 42", "AIRCEL", + "410 01", "Mobilink", + "413 02", "DIALOG GSM", + "415 01", "CELLIS", + "415 03", "LIBANCELL", + "416 01", "Fastlink", + "417 09", "MOBILE SYRIA", + "419 02", "MTCNet", + "420 01", "Al Jawwal", + "420 07", "E.A.E", + "422 02", "GTO", + "424 02", "UAE-ETISALAT", + "425 01", "Partner Communications Company Ltd", + "425 02", "Cellcom Israel Ltd", + "426 01", "BHR MOBILE PLUS", + "427 01", "QATARNET", + "432 11", "TCI", + "434 04", "Daewoo Unitel", + "434 05", "Coscom", + "437 01", "Bitel", + "454 00", "TCSL GSM", + "454 04", "HKGHT", + "454 06", "SMARTONE GSM", + "454 10", "New World PCS", + "454 12", "PEOPLES", + "454 16", "SUNDAY", + "455 01", "TELEMOVEL+ GSM900-Macau", + "456 01", "MobiTel", + "456 02", "SAMART-GSM", + "457 01", "Lao Shinawatra Telecom", + "460 00", "China Telecom GSM", + "460 01", "CU-GSM", + "466 01", "Far EasTone Telecoms 900", + "466 06", "TUNTEX GSM 1800", + "466 88", "KG Telecom", + "466 92", "Chunghwa GSM", + "466 93", "MobiTai", + "466 97", "TWNGSM", + "466 99", "TransAsia", + "470 01", "GrameenPhone Ltd", + "470 19", "Mobile 2000", + "502 12", "Maxis Mobile", + "502 13", "TM Touch", + "502 16", "DiGi 1800", + "502 17", "ADAM", + "502 19", "CELCOM", + "505 01", "MobileNet", + "505 02", "OPTUS", + "505 03", "VODAFONE", + "505 08", "One.Tel", + "510 01", "SATELINDO", + "510 08", "LIPPO TELECOM", + "510 10", "TELKOMSEL", + "510 11", "Excelcom", + "510 21", "INDOSAT", + "515 01", "ISLACOM", + "515 02", "Globe Telecom", + "520 01", "AIS GSM", + "520 10", "WCS", + "520 18", "Worldphone 1800", + "520 23", "HELLO", + "525 01", "SingTel Mobile", + "525 02", "ST-PCN", + "525 03", "MOBILEONE", + "528 11", "DSTCom", + "530 01", "Vodafone New Zealand Limited", + "542 01", "Vodafone", + "546 01", "Mobilis", + "547 20", "VINI", + "602 01", "MobiNil", + "602 02", "Tunicell", + "603 01", "ALGERIAN MOBILE NETWORK", + "604 01", "I A M", + "608 01", "ALIZE", + "611 02", "Lagui", + "612 03", "IVOIRIS", + "612 05", "Telecel", + "615 01", "TOGO CELL", + "617 01", "Cellplus Mobile Comms", + "618 01", "Omega", + "620 01", "SPACEFON", + "625 01", "CVMOVEL", + "633 01", "Seychelles Cellular Services", + "633 10", "AIRTEL", + "634 01", "MobiTel", + "635 10", "Rwandacell", + "636 01", "ETMTN", + "640 01", "TRITEL", + "641 10", "MTN-Uganda", + "642 02", "ANTARIS", + "643 01", "T.D.M GSM 900", + "645 01", "ZAMCELL", + "646 01", "Madacom", + "646 03", "Sacel Madagascar S.A.", + "647 10", "SRR", + "648 01", "NET*ONE", + "648 03", "Telecel", + "649 01", "MTC", + "650 01", "Callpoint 900", + "651 01", "Vodacom Lesotho (Pty) Ltd", + "655 01", "Vodacom", + "655 10", "MTN", + "680 38", "NPI Wireless", + "730 01", "Entel Telefonia Movi", + "730 10", "Entel PCS", + "734 01", "Infonet", + + NULL +}; + +char *GSM_GetNetworkName(char *NetworkCode) +{ + int i = 0; + static char retval[200]; + + EncodeUnicode(retval,"unknown",7); + while (GSM_Networks[i*2] != NULL) { + if (strcmp(GSM_Networks[i*2],NetworkCode)) { + EncodeUnicode(retval, GSM_Networks[i*2+1], strlen(GSM_Networks[i*2+1])); + break; + } + i++; + } + return retval; +} + +char *GSM_GetCountryName(char *CountryCode) +{ + int i = 0; + static char retval[200]; + + EncodeUnicode(retval,"unknown",7); + while (GSM_Countries[i*2] != NULL) { + if (strcmp(GSM_Countries[i*2],CountryCode)) { + EncodeUnicode(retval, GSM_Countries[i*2+1], strlen(GSM_Countries[i*2+1])); + break; + } + i++; + } + return retval; +} + +void NOKIA_EncodeNetworkCode(unsigned char* buffer, unsigned char* output) +{ + EncodeBCD(buffer, output, 6, false); + buffer[1] = buffer[1] | 0xf0; +} + +void NOKIA_DecodeNetworkCode(unsigned char* buffer, unsigned char* output) +{ + DecodeBCD(output, buffer, 3); + output[6] = output[5]; + output[5] = output[4]; + output[4] = output[3]; + output[3] = ' '; +} + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/common/service/gsmnet.h b/common/service/gsmnet.h index d72228cf5..8307ad301 100644 --- a/common/service/gsmnet.h +++ b/common/service/gsmnet.h @@ -2,52 +2,14 @@ #define __gsm_networks_h /** - * This type is used to hold information about various GSM networks. - */ -typedef struct { - /** - * GSM network code. - */ - char *Code; - /** - * GSM network name. - */ - char *Name; -} GSM_Network; - -/** - * This type is used to hold information about various GSM countries. - */ -typedef struct { - /** - * GSM country code. - */ - char *Code; - /** - * GSM country name. - */ - char *Name; -} GSM_Country; - -/* These functions are used to search the structure defined above.*/ - -/** * Lookup GSM network by code. */ char *GSM_GetNetworkName(char *NetworkCode); -/** - * Lookup GSM network by name. - */ -char *GSM_GetNetworkCode(char *NetworkName); /** * Lookup GSM country by code. */ char *GSM_GetCountryName(char *CountryCode); -/** - * Lookup GSM country by name. - */ -char *GSM_GetCountryCode(char *CountryName); /** * State of network. @@ -68,7 +30,15 @@ typedef enum { /** * No network available. */ - GSM_NoNetwork + GSM_NoNetwork, + /** + * Network registration denied. + */ + GSM_RegistrationDenied, + /** + * Uknown network status. + */ + GSM_NetworkStatusUnknown } GSM_NetworkInfo_State; /** @@ -118,7 +88,7 @@ typedef struct { int BitErrorRate; } GSM_SignalQuality; -#endif /* __gsm_networks_h */ +#endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: diff --git a/common/service/gsmpbk.c b/common/service/gsmpbk.c index f90513613..f07199e1f 100644 --- a/common/service/gsmpbk.c +++ b/common/service/gsmpbk.c @@ -81,6 +81,28 @@ void GSM_PhonebookFindDefaultNameNumberGroup(GSM_MemoryEntry *entry, int *Name, } } } + if ((*Name) == -1) { + for (i = 0; i < entry->EntriesNum; i++) { + switch (entry->Entries[i].EntryType) { + case PBK_Text_LastName: + if (*Name == -1) *Name = i; + break; + default: + break; + } + } + } + if ((*Name) == -1) { + for (i = 0; i < entry->EntriesNum; i++) { + switch (entry->Entries[i].EntryType) { + case PBK_Text_FirstName: + if (*Name == -1) *Name = i; + break; + default: + break; + } + } + } } void GSM_EncodeVCARD(char *Buffer, int *Length, GSM_MemoryEntry *pbk, bool header, GSM_VCardVersion Version) diff --git a/common/service/gsmpbk.h b/common/service/gsmpbk.h index 060f0f95b..8cd295b4e 100644 --- a/common/service/gsmpbk.h +++ b/common/service/gsmpbk.h @@ -7,20 +7,21 @@ #include "../gsmcomon.h" #include "gsmmisc.h" -/* This data type is used to report the number of used - * and free positions in memory (sim or internal). +/** + * This structure contains info about number of used/free entries in phonebook + * memory */ typedef struct { /** - * Type of the memory + * Memory type */ GSM_MemoryType MemoryType; /** - * umber of used positions + * Number of used entries */ int Used; /** - * Number of free positions + * Number of free entries */ int Free; } GSM_MemoryStatus; @@ -29,6 +30,7 @@ typedef struct { * Type of specific phonebook entry. In parenthesis is specified in which * member of @ref GSM_SubMemoryEntry value is stored. */ +/* Originally created for MyGnokii */ typedef enum { /** * General number. (Text) @@ -160,10 +162,6 @@ typedef enum { PBK_PictureID } GSM_EntryType; -/* Limits for sizing of array in GSM_MemoryEntry. - * Individual handsets may not support these lengths - * so they have their own limits set. - */ #define GSM_PHONEBOOK_TEXT_LENGTH (200) #define GSM_PHONEBOOK_ENTRIES (26) @@ -193,7 +191,7 @@ typedef struct { int VoiceTag; } GSM_SubMemoryEntry; -/* Define datatype for phonebook entry, +/* Define datatype for phonebook entry * used for getting/writing phonebook entries. */ typedef struct { @@ -235,28 +233,28 @@ GSM_Error GSM_DecodeVCARD(unsigned char *Buffer, int *Pos, GSM_MemoryEntry *Pbk, void DecodeVCARD21Text(char *VCard, GSM_MemoryEntry *pbk); /** - * This define speed dialing entries. + * Define datatype for saving speed dials */ typedef struct { /** - * Which number is used to dialing? + * Specify number of speed dial */ int Location; /** - * Memory type of the number. + * Memory, where is saved used phonebook entry */ GSM_MemoryType MemoryType; /** - * Location of the number in MemoryType. + * Location in memory, where is saved used phonebook entry */ int MemoryLocation; /** - * Which number in location is used + * ID of phone number used in phonebook entry */ int MemoryNumberID; } GSM_SpeedDial; -#endif /* __gsm_phonebook_h */ +#endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: diff --git a/common/service/gsmprof.h b/common/service/gsmprof.h index 5d0fd45d4..c1a604fad 100644 --- a/common/service/gsmprof.h +++ b/common/service/gsmprof.h @@ -60,13 +60,24 @@ typedef enum { Profile_CallerGroups } GSM_Profile_Feat_ID; -/* Structure to hold profile entries. */ +/** + * It contains phone profiles + */ typedef struct { bool Active; - int Location; /* The number of the profile. */ - char Name[40*2]; /* The name of the profile. */ - bool DefaultName; /* Default name for profile ? */ + /** + * Profile number + */ + int Location; + /** + * Profile name + */ + char Name[40*2]; + /** + * Is it default name for profile ? + */ + bool DefaultName; bool HeadSetProfile; bool CarKitProfile; diff --git a/common/service/gsmring.c b/common/service/gsmring.c index b2f8fa233..85d2710df 100644 --- a/common/service/gsmring.c +++ b/common/service/gsmring.c @@ -11,7 +11,7 @@ #include "../misc/coding/coding.h" #include "../gsmstate.h" #include "gsmring.h" -#include "gsmsms.h" +#include "sms/gsmsms.h" int GSM_RingNoteGetFrequency(GSM_RingNote Note) { @@ -1312,8 +1312,7 @@ static void Binary2RTTL(GSM_Ringtone *dest, GSM_Ringtone *src) } else break; } - for (accuracy=1; accuracy<5; accuracy++) - { + for (accuracy=1; accuracy<5; accuracy++) { i = 1; while (i < 1000) { Lengths[0] = 30000/i; @@ -1345,8 +1344,7 @@ static void Binary2RTTL(GSM_Ringtone *dest, GSM_Ringtone *src) i++; } - if (foundlen) - { + if (foundlen) { Speed = i; Duration[5] = Duration_1_32; Duration[4] = Duration_1_16; Duration[3] = Duration_1_8; Duration[2] = Duration_1_4; @@ -1406,19 +1404,16 @@ GSM_Error GSM_RingtoneConvert(GSM_Ringtone *dest, GSM_Ringtone *src, GSM_Rington { dest->Format = Format; CopyUnicodeString(dest->Name,src->Name); - if (src->Format==RING_NOTETONE && Format==RING_NOKIABINARY) - { + if (src->Format==RING_NOTETONE && Format==RING_NOKIABINARY) { RTTL2Binary(dest, src); return GE_NONE; } - if (src->Format==RING_NOKIABINARY && Format==RING_NOTETONE) - { + if (src->Format==RING_NOKIABINARY && Format==RING_NOTETONE) { Binary2RTTL(dest, src); return GE_NONE; } /* The same source and target format */ - if (src->Format==Format) - { + if (src->Format==Format) { memcpy(dest,src,sizeof(GSM_Ringtone)); return GE_NONE; } diff --git a/common/service/gsmring.h b/common/service/gsmring.h index 544334f59..8b34281c4 100644 --- a/common/service/gsmring.h +++ b/common/service/gsmring.h @@ -172,7 +172,7 @@ int GSM_RingNoteGetFullDuration (GSM_RingNote Note); char *GSM_GetRingtoneName(GSM_AllRingtonesInfo *Info, int ID); -#endif /* __gsm_ringtones_h */ +#endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: diff --git a/common/service/gsmsms.c b/common/service/gsmsms.c deleted file mode 100644 index 3e2379536..000000000 --- a/common/service/gsmsms.c +++ /dev/null @@ -1,1962 +0,0 @@ - -#include -#include -#include - -#include "../gsmcomon.h" -#include "../misc/coding/coding.h" -#include "gsmsms.h" -#include "gsmcal.h" -#include "gsmpbk.h" -#include "gsmlogo.h" -#include "gsmring.h" -#include "gsmwap.h" -#include "gsmnet.h" - -/* User data headers */ -static GSM_UDHHeader UDHHeaders[] = { - /* See GSM 03.40 section 9.2.3.24.1 - * 1 byte 0x00 - * 1 byte 0x03 - * 1 byte 0x01: unique ID for message series - * 1 byte 0x00: how many SMS in sequence - * 1 byte 0x00: number of current SMS in sequence */ - { UDH_ConcatenatedMessages, 0x05, "\x00\x03\x01\x00\x00",2,-1,4,3}, - - /* See GSM 03.40 section 9.2.3.24.2 for voice, fax and email messages */ - { UDH_DisableVoice, 0x04, "\x01\x02\x00\x00",-1,-1,-1,-1}, - { UDH_DisableFax, 0x04, "\x01\x02\x01\x00",-1,-1,-1,-1}, - { UDH_DisableEmail, 0x04, "\x01\x02\x02\x00",-1,-1,-1,-1}, - { UDH_EnableVoice, 0x04, "\x01\x02\x00\x01",-1,-1,-1,-1}, - { UDH_EnableFax, 0x04, "\x01\x02\x01\x01",-1,-1,-1,-1}, - { UDH_EnableEmail, 0x04, "\x01\x02\x02\x01",-1,-1,-1,-1}, - - /* When send such SMS to some phones, they don't display anything, - * only beep and enable vibra/light - */ - { UDH_VoidSMS, 0x08, "\x01\x02\x02\x01\x01\x02\x02\x00",-1,-1,-1,-1}, - - /* Nokia Smart Messaging (short version) UDH - * General format : - * 1 byte 0x05 : IEI application port addressing scheme, 16 bit address - * 1 byte 0x04 : IEI length - * 2 bytes : destination address : high & low byte - * 2 bytes 0x00 0x00 : originator address : high & low byte */ - { UDH_NokiaRingtone, 0x06, "\x05\x04\x15\x81\x00\x00",-1,-1,-1,-1}, - { UDH_NokiaOperatorLogo, 0x06, "\x05\x04\x15\x82\x00\x00",-1,-1,-1,-1}, - { UDH_NokiaCallerLogo, 0x06, "\x05\x04\x15\x83\x00\x00",-1,-1,-1,-1}, - { UDH_NokiaWAP, 0x06, "\x05\x04\xc3\x4f\x00\x00",-1,-1,-1,-1}, - - /* Nokia Smart Messaging (long version) UDH and other - * General format: - * 1 byte 0x05 : IEI application port addressing scheme, 16 bit address - * 1 byte 0x04 : IEI length - * 2 bytes 0x00 0x00 : destination address : high & low byte - * 2 bytes 0x00 0x00 : originator address : high & low byte - * 1 byte 0x00 : SAR - * 1 byte 0x03 : SAR length - * 1 byte : diagram reference number (unique ID for message series) - * 1 byte : number of all SMS - * 1 byte : number of current SMS */ - { UDH_NokiaCalendarLong, 0x0b, "\x05\x04\x00\xe4\x00\x00\x00\x03\xc7\x00\x00",8,-1,10,9}, - { UDH_MMSIndicatorLong, 0x0b, "\x05\x04\x0b\x84\x23\xf0\x00\x03\xe5\x00\x00",8,-1,10,9}, - { UDH_NokiaRingtoneLong, 0x0b, "\x05\x04\x15\x81\x00\x00\x00\x03\x01\x00\x00",8,-1,10,9}, - { UDH_NokiaOperatorLogoLong, 0x0b, "\x05\x04\x15\x82\x00\x00\x00\x03\x02\x00\x00",8,-1,10,9}, - { UDH_NokiaProfileLong, 0x0b, "\x05\x04\x15\x8a\x00\x00\x00\x03\xce\x00\x00",8,-1,10,9}, - { UDH_NokiaPhonebookLong, 0x0b, "\x05\x04\x23\xf4\x00\x00\x00\x03\x01\x00\x00",8,-1,10,9}, - { UDH_NokiaWAPLong, 0x0b, "\x05\x04\xc3\x4f\x00\x00\x00\x03\x7f\x00\x00",8,-1,10,9}, - - { UDH_ConcatenatedMessages16bit,0x06, "\x08\x04\x00\x00\x00\x00",-1,2,5,4}, - - { UDH_NoUDH, 0x00, "",-1,-1,-1,-1} -}; - -/* --------------------------- Unpacking SMS ------------------------------- */ - -/* See GSM 03.40 section 9.2.3.11 */ -static GSM_Error GSM_DecodeSMSDateTime(GSM_DateTime *DT, unsigned char *req) -{ - DT->Year = DecodeWithBCDAlphabet(req[0]); - if (DT->Year<90) DT->Year=DT->Year+2000; else DT->Year=DT->Year+1990; - DT->Month = DecodeWithBCDAlphabet(req[1]); - DT->Day = DecodeWithBCDAlphabet(req[2]); - DT->Hour = DecodeWithBCDAlphabet(req[3]); - DT->Minute = DecodeWithBCDAlphabet(req[4]); - DT->Second = DecodeWithBCDAlphabet(req[5]); - - /* The timezone is given in quarters. The base is GMT. */ - DT->Timezone=(10*(req[6]&0x07)+(req[6]>>4))/4; - - if (req[6]&0x08) DT->Timezone = -DT->Timezone; - - dbgprintf("Decoding date & time: "); - dbgprintf("%s %4d/%02d/%02d ", DayOfWeek(DT->Year, DT->Month, DT->Day), - DT->Year, DT->Month, DT->Day); - dbgprintf("%02d:%02d:%02d %02d00\n", DT->Hour, DT->Minute, DT->Second, DT->Timezone); - - return GE_NONE; -} - -void GSM_DecodeUDHHeader(GSM_UDHHeader *UDH) -{ - int i, tmp, w; - bool UDHOK; - - UDH->Type = UDH_UserUDH; - UDH->ID8bit = -1; - UDH->ID16bit = -1; - UDH->PartNumber = -1; - UDH->AllParts = -1; - - i=-1; - while (true) { - i++; - if (UDHHeaders[i].Type==UDH_NoUDH) break; - - tmp=UDHHeaders[i].Length; - /* if length is the same */ - if (tmp==UDH->Text[0]) { - - if (tmp==0x05) tmp=tmp-3;/*three last bytes can be different for such UDH*/ - if (tmp==0x0b) tmp=tmp-3;/*three last bytes can be different for such UDH*/ - if (tmp==0x06 && UDH->Text[1] == 0x08) tmp=tmp-4; - - UDHOK=true; - for (w=0;wText[w+1]) { - UDHOK=false; - break; - } - } - if (UDHOK) { - UDH->Type=UDHHeaders[i].Type; - - if (UDHHeaders[i].ID8bit !=-1) UDH->ID8bit = UDH->Text[UDHHeaders[i].ID8bit+1]; - if (UDHHeaders[i].ID16bit !=-1) UDH->ID16bit = UDH->Text[UDHHeaders[i].ID16bit+1]*256+UDH->Text[UDHHeaders[i].ID16bit+2]; - if (UDHHeaders[i].PartNumber !=-1) UDH->PartNumber = UDH->Text[UDHHeaders[i].PartNumber+1]; - if (UDHHeaders[i].AllParts !=-1) UDH->AllParts = UDH->Text[UDHHeaders[i].AllParts+1]; - break; - } - } - } - -#ifdef DEBUG - dbgprintf("Type of UDH: "); - switch (UDH->Type) { - case UDH_ConcatenatedMessages : dbgprintf("Concatenated (linked) message"); break; - case UDH_ConcatenatedMessages16bit : dbgprintf("Concatenated (linked) message"); break; - case UDH_DisableVoice : dbgprintf("Disables voice indicator"); break; - case UDH_EnableVoice : dbgprintf("Enables voice indicator"); break; - case UDH_DisableFax : dbgprintf("Disables fax indicator"); break; - case UDH_EnableFax : dbgprintf("Enables fax indicator"); break; - case UDH_DisableEmail : dbgprintf("Disables email indicator"); break; - case UDH_EnableEmail : dbgprintf("Enables email indicator"); break; - case UDH_VoidSMS : dbgprintf("Void SMS"); break; - case UDH_NokiaWAP : dbgprintf("Nokia WAP Bookmark"); break; - case UDH_NokiaOperatorLogoLong : dbgprintf("Nokia operator logo"); break; - case UDH_NokiaWAPLong : dbgprintf("Nokia WAP Bookmark or WAP/MMS Settings"); break; - case UDH_NokiaRingtone : dbgprintf("Nokia ringtone"); break; - case UDH_NokiaRingtoneLong : dbgprintf("Nokia ringtone"); break; - case UDH_NokiaOperatorLogo : dbgprintf("Nokia GSM operator logo"); break; - case UDH_NokiaCallerLogo : dbgprintf("Nokia caller logo"); break; - case UDH_NokiaProfileLong : dbgprintf("Nokia profile"); break; - case UDH_NokiaCalendarLong : dbgprintf("Nokia calendar note"); break; - case UDH_NokiaPhonebookLong : dbgprintf("Nokia phonebook entry"); break; - case UDH_UserUDH : dbgprintf("User UDH"); break; - case UDH_MMSIndicatorLong : dbgprintf("MMS indicator"); break; - case UDH_NoUDH: break; - } - if (UDH->ID8bit != -1) dbgprintf(", ID 8 bit %i",UDH->ID8bit); - if (UDH->ID16bit != -1) dbgprintf(", ID 16 bit %i",UDH->ID16bit); - if (UDH->PartNumber != -1 && UDH->AllParts != -1) { - dbgprintf(", part %i of %i",UDH->PartNumber,UDH->AllParts); - } - dbgprintf("\n"); - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, UDH->Text, UDH->Length); -#endif -} - -GSM_Error GSM_DecodeSMSFrameText(GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout) -{ - int off=0; /* off - length of the user data header */ - int w,i,tmp=0; - unsigned char output[161]; - - SMS->UDH.Length = 0; - /* UDH header available */ - if (buffer[Layout.firstbyte] & 64) { - /* Length of UDH header */ - off = (buffer[Layout.Text] + 1); - SMS->UDH.Length = off; - dbgprintf("UDH header available (length %i)\n",off); - - /* Copy UDH header into SMS->UDH */ - for (i = 0; i < off; i++) SMS->UDH.Text[i] = buffer[Layout.Text + i]; - - GSM_DecodeUDHHeader(&SMS->UDH); - } - - /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) and GSM 03.38 section 4 */ - if ((buffer[Layout.TPDCS] & 0xf4) == 0xf4) SMS->Coding=GSM_Coding_8bit; - if ((buffer[Layout.TPDCS] & 0x08) == 0x08) SMS->Coding=GSM_Coding_Unicode; - - switch (SMS->Coding) { - case GSM_Coding_Default: - i = 0; - do { - i+=7; - w=(i-off)%i; - } while (w<0); - SMS->Length=buffer[Layout.TPUDL] - (off*8 + w) / 7; - tmp=GSM_UnpackEightBitsToSeven(w, buffer[Layout.TPUDL]-off, SMS->Length, buffer+(Layout.Text+off), output); - dbgprintf("7 bit SMS, length %i\n",SMS->Length); - DecodeDefault (SMS->Text, output, SMS->Length, true, NULL); - dbgprintf("%s\n",DecodeUnicodeString(SMS->Text)); - break; - case GSM_Coding_8bit: - SMS->Length=buffer[Layout.TPUDL] - off; - memcpy(SMS->Text,buffer+(Layout.Text+off),SMS->Length); -#ifdef DEBUG - dbgprintf("8 bit SMS, length %i\n",SMS->Length); - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, SMS->Text, SMS->Length); -#endif - break; - case GSM_Coding_Unicode: - SMS->Length=(buffer[Layout.TPUDL] - off) / 2; - DecodeUnicodeSpecialNOKIAChars(SMS->Text,buffer+(Layout.Text+off), SMS->Length); -#ifdef DEBUG - dbgprintf("Unicode SMS, length %i\n",SMS->Length); - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df,buffer+(Layout.Text+off), SMS->Length*2); - dbgprintf("%s\n",DecodeUnicodeString(SMS->Text)); -#endif - break; - } - - return GE_NONE; -} - -GSM_Error GSM_DecodeSMSFrameStatusReportData(GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout) -{ - SMS->DeliveryStatus = buffer[Layout.TPStatus]; - - if (buffer[Layout.TPStatus] < 0x03) { - EncodeUnicode(SMS->Text,"Delivered",9); - SMS->Length = 9; - } else if (buffer[Layout.TPStatus] & 0x40) { - EncodeUnicode(SMS->Text,"Failed",6); - SMS->Length = 6; - } else if (buffer[Layout.TPStatus] & 0x20) { - EncodeUnicode(SMS->Text,"Pending",7); - SMS->Length = 7; - } else { - EncodeUnicode(SMS->Text,"Unknown",7); - SMS->Length = 7; - } - -#ifdef DEBUG - /* See GSM 03.40 section 9.2.3.15 (TP-Status) */ - if (buffer[Layout.TPStatus] & 0x40) { - if (buffer[Layout.TPStatus] & 0x20) { - /* 0x60, 0x61, ... */ - dbgprintf("Temporary error, SC is not making any more transfer attempts\n"); - } else { - /* 0x40, 0x41, ... */ - dbgprintf("Permanent error, SC is not making any more transfer attempts\n"); - } - } else if (buffer[Layout.TPStatus] & 0x20) { - /* 0x20, 0x21, ... */ - dbgprintf("Temporary error, SC still trying to transfer SM\n"); - } - switch (buffer[Layout.TPStatus]) { - case 0x00: dbgprintf("SM received by the SME"); break; - case 0x01: dbgprintf("SM forwarded by the SC to the SME but the SC is unable to confirm delivery");break; - case 0x02: dbgprintf("SM replaced by the SC"); break; - case 0x20: dbgprintf("Congestion"); break; - case 0x21: dbgprintf("SME busy"); break; - case 0x22: dbgprintf("No response from SME"); break; - case 0x23: dbgprintf("Service rejected"); break; - case 0x24: dbgprintf("Quality of service not aviable"); break; - case 0x25: dbgprintf("Error in SME"); break; - case 0x40: dbgprintf("Remote procedure error"); break; - case 0x41: dbgprintf("Incompatibile destination"); break; - case 0x42: dbgprintf("Connection rejected by SME"); break; - case 0x43: dbgprintf("Not obtainable"); break; - case 0x44: dbgprintf("Quality of service not available"); break; - case 0x45: dbgprintf("No internetworking available"); break; - case 0x46: dbgprintf("SM Validity Period Expired"); break; - case 0x47: dbgprintf("SM deleted by originating SME"); break; - case 0x48: dbgprintf("SM Deleted by SC Administration"); break; - case 0x49: dbgprintf("SM does not exist"); break; - case 0x60: dbgprintf("Congestion"); break; - case 0x61: dbgprintf("SME busy"); break; - case 0x62: dbgprintf("No response from SME"); break; - case 0x63: dbgprintf("Service rejected"); break; - case 0x64: dbgprintf("Quality of service not available"); break; - case 0x65: dbgprintf("Error in SME"); break; - default : dbgprintf("Reserved/Specific to SC: %x",buffer[Layout.TPStatus]); break; - } - dbgprintf("\n"); -#endif /* DEBUG */ - - return GE_NONE; -} - -GSM_Error GSM_DecodeSMSFrame(GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout) -{ -#ifdef DEBUG - if (Layout.firstbyte == 255) { - dbgprintf("ERROR: firstbyte in SMS layout not set\n"); - return GE_UNKNOWN; - } - if (Layout.TPDCS != 255) dbgprintf("TPDCS : %02x %i\n",buffer[Layout.TPDCS] ,buffer[Layout.TPDCS]); - if (Layout.TPMR != 255) dbgprintf("TPMR : %02x %i\n",buffer[Layout.TPMR] ,buffer[Layout.TPMR]); - if (Layout.TPPID != 255) dbgprintf("TPPID : %02x %i\n",buffer[Layout.TPPID] ,buffer[Layout.TPPID]); - if (Layout.TPUDL != 255) dbgprintf("TPUDL : %02x %i\n",buffer[Layout.TPUDL] ,buffer[Layout.TPUDL]); - if (Layout.firstbyte != 255) dbgprintf("FirstByte : %02x %i\n",buffer[Layout.firstbyte],buffer[Layout.firstbyte]); - if (Layout.Text != 255) dbgprintf("Text : %02x %i\n",buffer[Layout.Text] ,buffer[Layout.Text]); -#endif - - SMS->UDH.Type = UDH_NoUDH; - SMS->Coding = GSM_Coding_Default; - SMS->Length = 0; - SMS->SMSC.Number[0] = 0; - SMS->SMSC.Number[1] = 0; - SMS->Number[0] = 0; - SMS->Number[1] = 0; - SMS->Name[0] = 0; - SMS->Name[1] = 0; - SMS->ReplyViaSameSMSC = false; - if (Layout.SMSCNumber!=255) { - GSM_UnpackSemiOctetNumber(SMS->SMSC.Number,buffer+Layout.SMSCNumber,false); - dbgprintf("SMS center number : \"%s\"\n",DecodeUnicodeString(SMS->SMSC.Number)); - } - if ((buffer[Layout.firstbyte] & 0x80)!=0) SMS->ReplyViaSameSMSC=true; -#ifdef DEBUG - if (SMS->ReplyViaSameSMSC) dbgprintf("SMS centre set for reply\n"); -#endif - if (Layout.Number!=255) { - GSM_UnpackSemiOctetNumber(SMS->Number,buffer+Layout.Number,true); - dbgprintf("Remote number : \"%s\"\n",DecodeUnicodeString(SMS->Number)); - } - if (Layout.Text != 255 && Layout.TPDCS!=255 && Layout.TPUDL!=255) { - GSM_DecodeSMSFrameText(SMS, buffer, Layout); - } - if (Layout.DateTime != 255) { - GSM_DecodeSMSDateTime(&SMS->DateTime,buffer+(Layout.DateTime)); - } - if (Layout.SMSCTime != 255 && Layout.TPStatus != 255) { - /* See GSM 03.40 section 9.2.3.11 (TP-Service-Centre-Time-Stamp) */ - dbgprintf("SMSC response date: "); - GSM_DecodeSMSDateTime(&SMS->SMSCTime, buffer+(Layout.SMSCTime)); - GSM_DecodeSMSFrameStatusReportData(SMS,buffer,Layout); - } - SMS->Class = -1; - if (Layout.TPDCS != 255) { - if ((buffer[Layout.TPDCS] & 0xF3)==0xF0) SMS->Class = 0; - if ((buffer[Layout.TPDCS] & 0xF3)==0xF1) SMS->Class = 1; - if ((buffer[Layout.TPDCS] & 0xF3)==0xF2) SMS->Class = 2; - if ((buffer[Layout.TPDCS] & 0xF3)==0xF3) SMS->Class = 3; - } - dbgprintf("SMS class: %i\n",SMS->Class); - SMS->MessageReference = 0; - if (Layout.TPMR != 255) { - SMS->MessageReference = buffer[Layout.TPMR]; - } - SMS->ReplaceMessage = 0; - if (Layout.TPPID != 255) { - if (buffer[Layout.TPPID] > 0x40 && buffer[Layout.TPPID] < 0x48) { - SMS->ReplaceMessage = buffer[Layout.TPPID] - 0x40; - } - } - SMS->RejectDuplicates = false; - if ((buffer[Layout.firstbyte] & 0x04)==0x04) SMS->RejectDuplicates = true; - - return GE_NONE; -} - -/* ----------------------------- Packing SMS ------------------------------- */ - -/* See GSM 03.40 section 9.2.3.11 */ -static GSM_Error GSM_EncodeSMSDateTime(GSM_DateTime *DT, unsigned char *req) -{ - int Year; - - dbgprintf("Encoding SMS datetime: %02i/%02i/%04i %02i:%02i:%02i\n", - DT->Day,DT->Month,DT->Year,DT->Hour,DT->Minute,DT->Second); - - /* We need to have only two last digits of year */ - if (DT->Year>1900) - { - if (DT->Year<2000) Year = DT->Year-1900; - else Year = DT->Year-2000; - } else Year = DT->Year; - - req[0]=EncodeWithBCDAlphabet(Year); - req[1]=EncodeWithBCDAlphabet(DT->Month); - req[2]=EncodeWithBCDAlphabet(DT->Day); - req[3]=EncodeWithBCDAlphabet(DT->Hour); - req[4]=EncodeWithBCDAlphabet(DT->Minute); - req[5]=EncodeWithBCDAlphabet(DT->Second); - - /* FIXME: do it */ - req[6]=0; /* TimeZone = +-0 */ - - return GE_NONE; -} - -static int GSM_EncodeSMSFrameText(GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout) -{ - int off = 0; /* off - length of the user data header */ - int size = 0, size2 = 0, w,p; - char buff[200]; - - if (SMS->UDH.Type!=UDH_NoUDH) { - buffer[Layout.firstbyte] |= 0x40; /* GSM 03.40 section 9.2.3.23 (TP-User-Data-Header-Indicator) */ - off = 1 + SMS->UDH.Text[0]; /* off - length of the user data header */ - memcpy(buffer+Layout.Text, SMS->UDH.Text, off); /* we copy the udh */ -#ifdef DEBUG - dbgprintf("UDH, length %i\n",off); - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, SMS->UDH.Text, off); -#endif - } - switch (SMS->Coding) { - case GSM_Coding_8bit: - /* the mask for the 8-bit data */ - /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) - * and GSM 03.38 section 4 */ - buffer[Layout.TPDCS] |= 0xf4; - memcpy(buffer+(Layout.Text+off), SMS->Text, SMS->Length); - size2 = size = SMS->Length+off; -#ifdef DEBUG - dbgprintf("8 bit SMS, length %i\n",SMS->Length); - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df,SMS->Text,SMS->Length); -#endif - break; - case GSM_Coding_Default: - p = 0; - do { - p+=7; - w=(p-off)%p; - } while (w<0); - p = UnicodeLength(SMS->Text); - EncodeDefault(buff, SMS->Text, &p, true, NULL); - size = GSM_PackSevenBitsToEight(w, buff, buffer+(Layout.Text+off), p); - size += off; - size2 = (off*8 + w) / 7 + p; - dbgprintf("7 bit SMS, length %i, %i\n",size,size2); - dbgprintf("%s\n",DecodeUnicodeString(SMS->Text)); - if (size > GSM_MAX_8BIT_SMS_LENGTH) { - size = 0; size2 = 0; - } - break; - case GSM_Coding_Unicode: - /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) - * and GSM 03.38 section 4 */ - buffer[Layout.TPDCS] |= 0x08; - EncodeUnicodeSpecialNOKIAChars(buffer+(Layout.Text+off), SMS->Text, UnicodeLength(SMS->Text)); - size=size2=UnicodeLength(buffer+(Layout.Text+off))*2+off; -#ifdef DEBUG - dbgprintf("Unicode SMS, length %i\n",(size2-off)/2); - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df,buffer+(Layout.Text+off), size2-off); - dbgprintf("%s\n",DecodeUnicodeString(buffer+(Layout.Text+off))); -#endif - break; - } - - /* SMS->Length is: - - integer representation of the number od octets within the user data - when UD is coded using 8bit data - - the sum of the number of septets in UDH including any padding - and number of septets in UD in other case */ - /* GSM 03.40 section 9.2.3.16 (TP-User-Data-Length) */ - buffer[Layout.TPUDL] = size2; - return size; -} - -GSM_Error GSM_EncodeSMSFrame(GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout, int *length, bool clear) -{ - int i; - - if (clear) { - /* Cleaning up to the SMS text */ - for (i=0;iPDU) { - case SMS_Submit: - buffer[Layout.firstbyte] |= 0x01; - break; - /* SMS_Status_Report when Submit sms should have delivery report */ - /* We DON'T CREATE FRAME FOR REAL SMS_STATUS_REPORT */ - case SMS_Status_Report: - buffer[Layout.firstbyte] |= 0x01; - /* GSM 03.40 section 9.2.3.5 (TP-Status-Raport-Request) */ - /* Mask for request for delivery report from SMSC */ - buffer[Layout.firstbyte] |= 0x20; - break; - case SMS_Deliver: - buffer[Layout.firstbyte] |= 0x00; - } - - /* GSM 03.40 section 9.2.3.17 (TP-Reply-Path) */ - if (SMS->ReplyViaSameSMSC) buffer[Layout.firstbyte] |= 0x80; - - if (Layout.Number!=255) { - buffer[Layout.Number] = GSM_PackSemiOctetNumber(SMS->Number,buffer+(Layout.Number+1),true); - dbgprintf("Recipient number \"%s\"\n",DecodeUnicodeString(SMS->Number)); - } - if (Layout.SMSCNumber!=255) { - buffer[Layout.SMSCNumber]=GSM_PackSemiOctetNumber(SMS->SMSC.Number,buffer+(Layout.SMSCNumber+1), false); - dbgprintf("SMSC number \"%s\"\n",DecodeUnicodeString(SMS->SMSC.Number)); - } - - /* Message Class*/ - /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) and GSM 03.38 section 4 */ - if (Layout.TPDCS != 255) { - if (SMS->Class>=0 && SMS->Class<5) buffer[Layout.TPDCS] |= (240+SMS->Class); - } - - if (Layout.TPVP != 255) { - /* GSM 03.40 section 9.2.3.3 (TP-Validity-Period-Format) */ - /* Bits 4 and 3: 10. TP-VP field present and integer represent (relative) */ - buffer[Layout.firstbyte] |= 0x10; - buffer[Layout.TPVP]=((unsigned char)SMS->SMSC.Validity.Relative); - dbgprintf("SMS validity %02x\n",SMS->SMSC.Validity.Relative); - } - - if (Layout.DateTime != 255) { - GSM_EncodeSMSDateTime(&SMS->DateTime, buffer+Layout.DateTime); - } - - if (Layout.TPMR != 255) { - buffer[Layout.TPMR] = SMS->MessageReference; - } - - if (SMS->RejectDuplicates) { - /* GSM 03.40 section 9.2.3.25 (TP Reject Duplicates) */ - buffer[Layout.firstbyte] |= 0x04; - } - - if (Layout.TPPID != 255) { - buffer[Layout.TPPID] = 0; - if (SMS->ReplaceMessage > 0 && SMS->ReplaceMessage < 8) { - buffer[Layout.TPPID] = 0x40 + SMS->ReplaceMessage; - } - } - - /* size is the length of the data in octets including udh */ - *length=GSM_EncodeSMSFrameText(SMS,buffer,Layout); -// if (*length == 0) return GE_UNKNOWN; - *length += Layout.Text; - - return GE_NONE; -} - -/* ----------------- Some help functions ----------------------------------- */ - -void GSM_SetDefaultSMSData(GSM_SMSMessage *SMS) -{ - SMS->Class = -1; - SMS->SMSC.Location = 1; - SMS->SMSC.Validity.VPF = GSM_RelativeFormat; - SMS->SMSC.Validity.Relative = GSMV_Max_Time; - SMS->ReplyViaSameSMSC = false; - SMS->UDH.Type = UDH_NoUDH; - SMS->UDH.Length = 0; - SMS->UDH.Text[0] = 0; - SMS->UDH.ID8bit = 0; - SMS->UDH.ID16bit = 0; - SMS->UDH.PartNumber = 0; - SMS->UDH.AllParts = 0; - SMS->Coding = GSM_Coding_Default; - SMS->Text[0] = 0; - SMS->Text[1] = 0; - SMS->PDU = SMS_Submit; - SMS->RejectDuplicates = false; - SMS->MessageReference = 0; - SMS->ReplaceMessage = 0; - SMS->Length = 0; - - /* This part is required to save SMS */ - SMS->State = GSM_UnSent; - SMS->Location = 0; - SMS->Folder = 0x02; /*Outbox*/ - GSM_GetCurrentDateTime (&SMS->DateTime); - SMS->Name[0] = 0; - SMS->Name[1] = 0; -} - -/* This function encodes the UserDataHeader as described in: - * - GSM 03.40 version 6.1.0 Release 1997, section 9.2.3.24 - * - Smart Messaging Specification, Revision 1.0.0, September 15, 1997 - */ -void GSM_EncodeUDHHeader(GSM_UDHHeader *UDH) -{ - int i=0; - - switch (UDH->Type) { - case UDH_NoUDH: - UDH->Length = 0; - break; - case UDH_UserUDH: - UDH->Length = UDH->Text[0] + 1; - break; - default: - while (true) { - if (UDHHeaders[i].Type==UDH_NoUDH) - { - dbgprintf("Not supported UDH type\n"); - break; - } - if (UDHHeaders[i].Type==UDH->Type) - { - /* UDH Length */ - UDH->Text[0] = UDHHeaders[i].Length; - memcpy(UDH->Text+1, UDHHeaders[i].Text, UDHHeaders[i].Length); - UDH->Length = UDH->Text[0] + 1; - - if (UDHHeaders[i].ID8bit != -1) { - UDH->Text[UDHHeaders[i].ID8bit+1] = UDH->ID8bit % 256; - } else { - UDH->ID8bit = -1; - } - if (UDHHeaders[i].ID16bit != -1) { - UDH->Text[UDHHeaders[i].ID16bit+1] = UDH->ID16bit / 256; - UDH->Text[UDHHeaders[i].ID16bit+2] = UDH->ID16bit % 256; - } else { - UDH->ID16bit = -1; - } - if (UDHHeaders[i].PartNumber != -1) { - UDH->Text[UDHHeaders[i].PartNumber+1] = UDH->PartNumber; - } else { - UDH->PartNumber = -1; - } - if (UDHHeaders[i].AllParts != -1) { - UDH->Text[UDHHeaders[i].AllParts+1] = UDH->AllParts; - } else { - UDH->AllParts = -1; - } - break; - } - i++; - } - } -} - -/* ----------------- Splitting SMS into parts ------------------------------ */ - -static unsigned char GSM_MakeSMSIDFromTime() -{ - GSM_DateTime Date; - unsigned char retval; - - GSM_GetCurrentDateTime (&Date); - retval = Date.Second; - switch (Date.Minute/10) { - case 2: case 7: retval = retval + 60; break; - case 4: case 8: retval = retval + 120; break; - case 9: case 5: case 0: retval = retval + 180; break; - } - retval += Date.Minute/10; - return retval; -} - -static void GSM_Find_Free_Used_SMS2(GSM_Coding_Type Coding,GSM_SMSMessage SMS, int *UsedText, int *FreeText, int *FreeBytes) -{ - int UsedBytes; - - switch (Coding) { - case GSM_Coding_Default: - FindDefaultAlphabetLen(SMS.Text,&UsedBytes,UsedText,500); - UsedBytes = *UsedText * 7 / 8; - if (UsedBytes * 8 / 7 != *UsedText) UsedBytes++; - *FreeBytes = GSM_MAX_8BIT_SMS_LENGTH - SMS.UDH.Length - UsedBytes; - *FreeText = (GSM_MAX_8BIT_SMS_LENGTH - SMS.UDH.Length) * 8 / 7 - *UsedText; - break; - case GSM_Coding_Unicode: - *UsedText = UnicodeLength(SMS.Text); - UsedBytes = *UsedText * 2; - *FreeBytes = GSM_MAX_8BIT_SMS_LENGTH - SMS.UDH.Length - UsedBytes; - *FreeText = *FreeBytes / 2; - break; - case GSM_Coding_8bit: - *UsedText = UsedBytes = SMS.Length; - *FreeBytes = GSM_MAX_8BIT_SMS_LENGTH - SMS.UDH.Length - UsedBytes; - *FreeText = *FreeBytes; - break; - } - dbgprintf("UDH len %i, UsedBytes %i, FreeText %i, UsedText %i, FreeBytes %i\n",SMS.UDH.Length,UsedBytes,*FreeText,*UsedText,*FreeBytes); -} - -GSM_Error GSM_AddSMS_Text_UDH(GSM_MultiSMSMessage *SMS, - GSM_Coding_Type Coding, - char *Buffer, - int BufferLen, - bool UDH, - int *UsedText, - int *CopiedText, - int *CopiedSMSText) -{ - int FreeText,FreeBytes,Copy,i,j; - - dbgprintf("Checking used\n"); - GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], UsedText, &FreeText, &FreeBytes); - - if (UDH) { - dbgprintf("Adding UDH\n"); - if (FreeBytes - BufferLen <= 0) { - dbgprintf("Going to the new SMS\n"); - SMS->Number++; - GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], UsedText, &FreeText, &FreeBytes); - } - if (SMS->SMS[SMS->Number].UDH.Length == 0) { - SMS->SMS[SMS->Number].UDH.Length = 1; - SMS->SMS[SMS->Number].UDH.Text[0] = 0x00; - } - memcpy(SMS->SMS[SMS->Number].UDH.Text+SMS->SMS[SMS->Number].UDH.Length,Buffer,BufferLen); - SMS->SMS[SMS->Number].UDH.Length += BufferLen; - SMS->SMS[SMS->Number].UDH.Text[0] += BufferLen; - SMS->SMS[SMS->Number].UDH.Type = UDH_UserUDH; - dbgprintf("UDH added %i\n",BufferLen); - } else { - dbgprintf("Adding text\n"); - if (FreeText == 0) { - dbgprintf("Going to the new SMS\n"); - SMS->Number++; - GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], UsedText, &FreeText, &FreeBytes); - } - - Copy = FreeText; - dbgprintf("copy %i\n",Copy); - if (BufferLen < Copy) Copy = BufferLen; - dbgprintf("copy %i\n",Copy); - - switch (Coding) { - case GSM_Coding_Default: - FindDefaultAlphabetLen(Buffer,&i,&j,FreeText); - dbgprintf("def length %i %i\n",i,j); - SMS->SMS[SMS->Number].Text[UnicodeLength(SMS->SMS[SMS->Number].Text)*2+i*2] = 0; - SMS->SMS[SMS->Number].Text[UnicodeLength(SMS->SMS[SMS->Number].Text)*2+i*2+1] = 0; - memcpy(SMS->SMS[SMS->Number].Text+UnicodeLength(SMS->SMS[SMS->Number].Text)*2,Buffer,i*2); - *CopiedText = i; - *CopiedSMSText = j; - SMS->SMS[SMS->Number].Length += i; - break; - case GSM_Coding_Unicode: - SMS->SMS[SMS->Number].Text[UnicodeLength(SMS->SMS[SMS->Number].Text)*2+Copy*2] = 0; - SMS->SMS[SMS->Number].Text[UnicodeLength(SMS->SMS[SMS->Number].Text)*2+Copy*2+1] = 0; - memcpy(SMS->SMS[SMS->Number].Text+UnicodeLength(SMS->SMS[SMS->Number].Text)*2,Buffer,Copy*2); - *CopiedText = *CopiedSMSText = Copy; - SMS->SMS[SMS->Number].Length += Copy; - break; - case GSM_Coding_8bit: - memcpy(SMS->SMS[SMS->Number].Text+SMS->SMS[SMS->Number].Length,Buffer,Copy); - SMS->SMS[SMS->Number].Length += Copy; - *CopiedText = *CopiedSMSText = Copy; - break; - } - dbgprintf("Text added\n"); - } - - dbgprintf("Checking on the end\n"); - GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], UsedText, &FreeText, &FreeBytes); - - return GE_NONE; -} - -void GSM_MakeMultiPartSMS(GSM_MultiSMSMessage *SMS, - unsigned char *MessageBuffer, - int MessageLength, - GSM_UDH UDHType, - GSM_Coding_Type Coding, - int Class, - unsigned char ReplaceMessage) -{ - int j,Len,UsedText,CopiedText,CopiedSMSText; - unsigned char UDHID; - GSM_DateTime Date; - - Len = 0; - while(1) { - GSM_SetDefaultSMSData(&SMS->SMS[SMS->Number]); - SMS->SMS[SMS->Number].Class = Class; - SMS->SMS[SMS->Number].Coding = Coding; - - SMS->SMS[SMS->Number].UDH.Type = UDHType; - GSM_EncodeUDHHeader(&SMS->SMS[SMS->Number].UDH); - - if (Coding == GSM_Coding_8bit) { - GSM_AddSMS_Text_UDH(SMS,Coding,MessageBuffer+Len,MessageLength - Len,false,&UsedText,&CopiedText,&CopiedSMSText); - } else { - GSM_AddSMS_Text_UDH(SMS,Coding,MessageBuffer+Len*2,MessageLength - Len,false,&UsedText,&CopiedText,&CopiedSMSText); - } - Len += CopiedText; - dbgprintf("%i %i\n",Len,MessageLength); - if (Len == MessageLength) break; - if (SMS->Number == MAX_MULTI_SMS) break; - SMS->Number++; - } - - SMS->Number++; - - UDHID = GSM_MakeSMSIDFromTime(); - GSM_GetCurrentDateTime (&Date); - for (j=0;jNumber;j++) - { - SMS->SMS[j].UDH.Type = UDHType; - SMS->SMS[j].UDH.ID8bit = UDHID; - SMS->SMS[j].UDH.ID16bit = UDHID + 256 * Date.Hour; - SMS->SMS[j].UDH.PartNumber = j+1; - SMS->SMS[j].UDH.AllParts = SMS->Number; - GSM_EncodeUDHHeader(&SMS->SMS[j].UDH); - } - if (SMS->Number == 1) SMS->SMS[0].ReplaceMessage = ReplaceMessage; -} - -/* Calculates number of SMS and number of left chars in SMS */ -void GSM_SMSCounter(int MessageLength, - unsigned char *MessageBuffer, - GSM_UDH UDHType, - GSM_Coding_Type Coding, - int *SMSNum, - int *CharsLeft) -{ - int UsedText,FreeBytes; - GSM_MultiSMSMessage MultiSMS; - - MultiSMS.Number = 0; - GSM_MakeMultiPartSMS(&MultiSMS,MessageBuffer,MessageLength,UDHType,Coding,-1,false); - GSM_Find_Free_Used_SMS2(Coding,MultiSMS.SMS[MultiSMS.Number-1], &UsedText, CharsLeft, &FreeBytes); - *SMSNum = MultiSMS.Number; -} - -/* Nokia Smart Messaging 3.0 */ -static void GSM_EncodeSMS30MultiPartSMS(GSM_EncodeMultiPartSMSInfo *Info, - char *Buffer, int *Length) -{ - int len; - - /*SM version. Here 3.0*/ - Buffer[(*Length)++] = 0x30; - - if (Info->Entries[0].ID == SMS_NokiaProfileLong) { - if (Info->Entries[0].Buffer != NULL) { - if (Info->Entries[0].Buffer[0]!=0x00 || Info->Entries[0].Buffer[1]!=0x00) { - Buffer[(*Length)++] = SM30_PROFILENAME; - Buffer[(*Length)++] = 0x00; - Buffer[(*Length)++] = 2*UnicodeLength(Info->Entries[0].Buffer); - CopyUnicodeString(Buffer+(*Length),Info->Entries[0].Buffer); - *Length = *Length + 2*UnicodeLength(Info->Entries[0].Buffer); - } - } - if (Info->Entries[0].Ringtone != NULL) { - Buffer[(*Length)++] = SM30_RINGTONE; - /* Length for this part later will be changed */ - Buffer[(*Length)++] = 0x01; - Buffer[(*Length)++] = 0x00; - /* Smart Messaging 3.0 says: 16*9=144 bytes, - * but on 3310 4.02 it was possible to save about 196 chars - * (without cutting) */ - len = 196; - Info->Entries[0].RingtoneNotes=GSM_EncodeNokiaRTTLRingtone(*Info->Entries[0].Ringtone,Buffer+(*Length),&len); - Buffer[(*Length)-2] = len / 256; - Buffer[(*Length)-1] = len % 256; - *Length = *Length + len; - } - } - if (Info->Entries[0].Bitmap != NULL) { - if (Info->Entries[0].ID == SMS_NokiaPictureImageLong) { - Buffer[(*Length)++] = SM30_OTA; - } else { - Buffer[(*Length)++] = SM30_SCREENSAVER; - } - Buffer[(*Length)++] = 0x01; - Buffer[(*Length)++] = 0x00; - NOKIA_CopyBitmap(GSM_NokiaPictureImage, &Info->Entries[0].Bitmap->Bitmap[0], Buffer, Length); - if (Info->Entries[0].Bitmap->Bitmap[0].Text[0]!=0 || Info->Entries[0].Bitmap->Bitmap[0].Text[1]!=0) { - if (Info->UnicodeCoding) { - Buffer[(*Length)++] = SM30_UNICODETEXT; - /* Length for text part */ - Buffer[(*Length)++] = 0x00; - Buffer[(*Length)++] = UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text)*2; - memcpy(Buffer+(*Length),Info->Entries[0].Bitmap->Bitmap[0].Text,UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text)*2); - *Length = *Length + UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text)*2; - } else { - /*ID for ISO-8859-1 text*/ - Buffer[(*Length)++] = SM30_ISOTEXT; - Buffer[(*Length)++] = 0x00; - Buffer[(*Length)++] = UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text); - memcpy(Buffer+(*Length),DecodeUnicodeString(Info->Entries[0].Bitmap->Bitmap[0].Text),UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text)); - *Length = *Length +UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text); - } - } - } -} - -/* EMS Developers' Guidelines from www.sonyericsson.com - * docs from Alcatel - */ -static GSM_Error GSM_EncodeEMSMultiPartSMS(GSM_EncodeMultiPartSMSInfo *Info, - GSM_MultiSMSMessage *SMS, - GSM_UDH UDHType) -{ - unsigned char Buffer[GSM_MAX_SMS_LENGTH*2*MAX_MULTI_SMS]; - int i,UsedText,j,Length,Width,Height,z,x,y; - unsigned int Len; - int Used,FreeText,FreeBytes,Width2,CopiedText,CopiedSMSText; - unsigned char UDHID; - GSM_Bitmap Bitmap,Bitmap2; - GSM_Ringtone Ring; - GSM_Coding_Type Coding = GSM_Coding_Default; - GSM_Phone_Bitmap_Types BitmapType; - EncodeMultiPartSMSEntry *Entry; - bool start; - GSM_DateTime Date; - -#ifdef DEBUG - if (UDHType != UDH_NoUDH) dbgprintf("linked EMS\n"); -#endif - - if (Info->UnicodeCoding) Coding = GSM_Coding_Unicode; - - /* Cleaning on the start */ - for (i=0;iSMS[i]); - SMS->SMS[i].UDH.Type = UDHType; - GSM_EncodeUDHHeader(&SMS->SMS[i].UDH); - SMS->SMS[i].Coding = Coding; - } - - /* Packing */ - for (i=0;iEntriesNum;i++) { - Entry = &Info->Entries[i]; - - switch (Entry->ID) { - case SMS_ConcatenatedTextLong: - case SMS_ConcatenatedTextLong16bit: - Len = 0; - while(1) { - if (Entry->Left || Entry->Right || - Entry->Center || Entry->Large || - Entry->Small || Entry->Bold || - Entry->Italic || Entry->Underlined || - Entry->Strikethrough) { - Buffer[0] = 0x0A; /* ID for text format */ - Buffer[1] = 0x03; /* length of rest */ - Buffer[2] = 0x00; /* Position in EMS msg */ - Buffer[3] = 0x00; /* how many chars */ - Buffer[4] = 0x00; /* formatting bits */ - if (Entry->Left) { - } else if (Entry->Right) { Buffer[4] |= 1; - } else if (Entry->Center) { Buffer[4] |= 2; - } else Buffer[4] |= 3; - if (Entry->Large) { Buffer[4] |= 4; - } else if (Entry->Small) { Buffer[4] |= 8;} - if (Entry->Bold) Buffer[4] |= 16; - if (Entry->Italic) Buffer[4] |= 32; - if (Entry->Underlined) Buffer[4] |= 64; - if (Entry->Strikethrough) Buffer[4] |= 128; - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,5,true,&UsedText,&CopiedText,&CopiedSMSText); - GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); - if (FreeText == 0) continue; - } - GSM_AddSMS_Text_UDH(SMS,Coding,Entry->Buffer+Len*2,UnicodeLength(Entry->Buffer) - Len,false,&UsedText,&CopiedText,&CopiedSMSText); - if (Entry->Left || Entry->Right || - Entry->Center || Entry->Large || - Entry->Small || Entry->Bold || - Entry->Italic || Entry->Underlined || - Entry->Strikethrough) { - SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3] = UsedText; - SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-2] = CopiedSMSText; - } - Len += CopiedText; - if (Len == UnicodeLength(Entry->Buffer)) break; - dbgprintf("%i %i\n",Len,UnicodeLength(Entry->Buffer)); - } - break; - case SMS_EMSPredefinedSound: - case SMS_EMSPredefinedAnimation: - if (Entry->ID == SMS_EMSPredefinedSound) { - Buffer[0] = 0x0B; /* ID for def.sound */ - } else { - Buffer[0] = 0x0D; /* ID for def.animation */ - } - Buffer[1] = 0x02; /* Length of rest */ - Buffer[2] = 0x00; /* Position in EMS msg */ - Buffer[3] = Entry->Number; /* Number of anim. */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); - SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-2] = UsedText; - break; - case SMS_EMSSonyEricssonSound: - case SMS_EMSSound10: - case SMS_EMSSound12: - if (Entry->Protected) { - Buffer[0] = 0x17; /* ID for ODI */ - Buffer[1] = 2; /* Length of rest */ - Buffer[2] = 1; /* Number of protected objects */ - Buffer[3] = 1; /* 1=Protected,0=Not protected */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); - } - - Length = 128; /* 128 bytes is maximal length from specs */ - switch (Entry->ID) { - case SMS_EMSSound10: - Entry->RingtoneNotes = GSM_EncodeEMSSound(*Entry->Ringtone, Buffer+3, &Length, 1.0, true); - break; - case SMS_EMSSound12: - Entry->RingtoneNotes = GSM_EncodeEMSSound(*Entry->Ringtone, Buffer+3, &Length, 1.2, true); - break; - case SMS_EMSSonyEricssonSound: - Entry->RingtoneNotes = GSM_EncodeEMSSound(*Entry->Ringtone, Buffer+3, &Length, 0, true); - break; - default: - break; - } - - Buffer[0] = 0x0C; /* ID for EMS sound */ - Buffer[1] = Length+1; /* Length of rest */ - Buffer[2] = 0x00; /* Position in EMS msg */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,Length+3,true,&UsedText,&CopiedText,&CopiedSMSText); - SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-Length-1] = UsedText; - break; - case SMS_EMSSonyEricssonSoundLong: - case SMS_EMSSound10Long: - case SMS_EMSSound12Long: - memcpy(&Ring,Entry->Ringtone,sizeof(GSM_Ringtone)); - - /* First check if we can use classic format */ - Length = 128; /* 128 bytes is maximal length from specs */ - switch (Entry->ID) { - case SMS_EMSSound10Long: - Entry->RingtoneNotes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.0, true); - break; - case SMS_EMSSound12Long: - Entry->RingtoneNotes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.2, true); - break; - case SMS_EMSSonyEricssonSoundLong: - Entry->RingtoneNotes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 0, true); - break; - default: - break; - } - if (Entry->RingtoneNotes == Ring.NoteTone.NrCommands) { - if (Entry->Protected) { - Buffer[0] = 0x17; /* ID for ODI */ - Buffer[1] = 2; /* Length of rest */ - Buffer[2] = 1; /* Number of protected objects */ - Buffer[3] = 1; /* 1=Protected,0=Not protected */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); - } - - Buffer[0] = 0x0C; /* ID for EMS sound */ - Buffer[1] = Length+1; /* Length of rest */ - Buffer[2] = 0x00; /* Position in EMS msg */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,Length+3,true,&UsedText,&CopiedText,&CopiedSMSText); - SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-Length-1] = UsedText; - break; - } - - /* Find free place in first SMS */ - GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); - Length = FreeBytes - 3; - if (Entry->Protected) Length = Length - 4; - if (Length < 0) Length = 128; - if (Length > 128) Length = 128; - - memcpy(&Ring,Entry->Ringtone,sizeof(GSM_Ringtone)); - - /* Checking number of SMS */ - Used = 0; - FreeBytes = 0; - start = true; - while (1) { - if (FreeBytes != 0) { - z = 0; - for (j=FreeBytes;jID) { - case SMS_EMSSound10Long: - FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.0, start); - break; - case SMS_EMSSound12Long: - FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.2, start); - break; - case SMS_EMSSonyEricssonSoundLong: - FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 0, start); - break; - default: - break; - } - start = false; - Used++; - } - dbgprintf("Used SMS: %i\n",Used); - - if (Entry->Protected) { - Buffer[0] = 0x17; /* ID for ODI */ - Buffer[1] = 2; /* Length of rest */ - Buffer[2] = Used+1; /* Number of protected objects */ - Buffer[3] = 1; /* 1=Protected,0=Not protected */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); - } - - /* Save UPI UDH */ - Buffer[0] = 0x13; /* ID for UPI */ - Buffer[1] = 1; /* Length of rest */ - Buffer[2] = Used; /* Number of used parts */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3,true,&UsedText,&CopiedText,&CopiedSMSText); - - /* Find free place in first SMS */ - GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); - Length = FreeBytes - 3; - if (Length < 0) Length = 128; - if (Length > 128) Length = 128; - - memcpy(&Ring,Entry->Ringtone,sizeof(GSM_Ringtone)); - - /* Saving */ - FreeBytes = 0; - start = true; - while (1) { - if (FreeBytes != 0) { - z = 0; - for (j=FreeBytes;jID) { - case SMS_EMSSound10Long: - FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.0, start); - break; - case SMS_EMSSound12Long: - FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.2, start); - break; - case SMS_EMSSonyEricssonSoundLong: - FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 0, start); - break; - default: - break; - } - Buffer[0] = 0x0C; /* ID for EMS sound */ - Buffer[1] = Length+1; /* Length of rest */ - Buffer[2] = 0x00; /* Position in EMS msg */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,Length+3,true,&UsedText,&CopiedText,&CopiedSMSText); - SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-Length-1] = UsedText; - start = false; - } - - Entry->RingtoneNotes = Entry->Ringtone->NoteTone.NrCommands; - - break; - case SMS_EMSAnimation: - if (Entry->Protected) { - Buffer[0] = 0x17; /* ID for ODI */ - Buffer[1] = 2; /* Length of rest */ - Buffer[2] = 1; /* Number of protected objects */ - Buffer[3] = 1; /* 1=Protected,0=Not protected */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); - } - - if (Entry->Bitmap->Bitmap[0].Width > 8 || Entry->Bitmap->Bitmap[0].Height > 8) { - BitmapType = GSM_EMSMediumPicture; /* Bitmap 16x16 */ - Buffer[0] = 0x0E; /* ID for 16x16 animation */ - } else { - BitmapType = GSM_EMSSmallPicture; /* Bitmap 8x8 */ - Buffer[0] = 0x0F; /* ID for 8x8 animation */ - } - Length = PHONE_GetBitmapSize(BitmapType,0,0); - - Buffer[1] = Length*Entry->Bitmap->Number + 1; /* Length of rest */ - Buffer[2] = 0x00; /* Position in EMS msg */ - for (j=0;jBitmap->Number;j++) { - PHONE_EncodeBitmap(BitmapType, Buffer+3+j*Length, &Entry->Bitmap->Bitmap[j]); - } - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3+Length*Entry->Bitmap->Number,true,&UsedText,&CopiedText,&CopiedSMSText); - SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-1-Length*Entry->Bitmap->Number] = UsedText; - break; - case SMS_EMSFixedBitmap: - if (Entry->Protected) { - Buffer[0] = 0x17; /* ID for ODI */ - Buffer[1] = 2; /* Length of rest */ - Buffer[2] = 1; /* Number of protected objects */ - Buffer[3] = 1; /* 1=Protected,0=Not protected */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); - } - - if (Entry->Bitmap->Bitmap[0].Width > 16 || Entry->Bitmap->Bitmap[0].Height > 16) { - BitmapType = GSM_EMSBigPicture; /* Bitmap 32x32 */ - Buffer[0] = 0x10; /* ID for EMS bitmap */ - } else { - BitmapType = GSM_EMSMediumPicture; /* Bitmap 16x16 */ - Buffer[0] = 0x11; /* ID for EMS bitmap */ - } - Length = PHONE_GetBitmapSize(BitmapType,0,0); - PHONE_GetBitmapWidthHeight(BitmapType, &Width, &Height); - - Buffer[1] = Length + 1; /* Length of rest */ - Buffer[2] = 0x00; /* Position in EMS msg */ - PHONE_EncodeBitmap(BitmapType,Buffer+3, &Entry->Bitmap->Bitmap[0]); - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3+Length,true,&UsedText,&CopiedText,&CopiedSMSText); - SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-1-Length] = UsedText; - break; - case SMS_EMSVariableBitmapLong: - BitmapType = GSM_EMSVariablePicture; - Width = Entry->Bitmap->Bitmap[0].Width; - Height = Entry->Bitmap->Bitmap[0].Height; - memcpy(&Bitmap,&Entry->Bitmap->Bitmap[0],sizeof(GSM_Bitmap)); - - /* First check if we can use classical format */ - while (1) { - /* Width should be multiply of 8 */ - while (Width % 8 != 0) Width--; - - /* specs */ - if (Width <= 96 && Height <= 128) break; - - Height--; - } - Length = PHONE_GetBitmapSize(BitmapType,Width,Height); - if (Length <= 128) { - if (Entry->Protected) { - Buffer[0] = 0x17; /* ID for ODI */ - Buffer[1] = 2; /* Length of rest */ - Buffer[2] = 1; /* Number of protected objects */ - Buffer[3] = 1; /* 1=Protected,0=Not protected */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); - } - - Buffer[0] = 0x12; /* ID for EMS bitmap */ - Buffer[1] = Length + 3; /* Length of rest */ - Buffer[2] = 0x00; /* Position in EMS msg */ - Buffer[3] = Width/8; /* Bitmap width/8 */ - Buffer[4] = Height; /* Bitmap height */ - - GSM_ResizeBitmap(&Bitmap, &Entry->Bitmap->Bitmap[0], Width, Height); -#ifdef DEBUG - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Bitmap); -#endif - PHONE_EncodeBitmap(BitmapType,Buffer+5, &Bitmap); - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,5+Length,true,&UsedText,&CopiedText,&CopiedSMSText); - SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3-Length] = UsedText; - break; - } - - /* Find free place in first SMS */ - GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); - Used = 0; - Length = FreeBytes - 3; - if (Entry->Protected) Length = Length - 4; - if (Length < 0) Length = 128; - if (Length > 128) Length = 128; - - /* Checking number of SMS */ - FreeBytes = 0; - while (FreeBytes != Width) { - Width2 = 8; - while(1) { - if (FreeBytes+Width2 == Width) break; - - if (PHONE_GetBitmapSize(BitmapType,Width2+8,Height) > Length) break; - - Width2 = Width2 + 8; - } - FreeBytes = FreeBytes + Width2; - Length = 128; - Used ++; - } - dbgprintf("Used SMS: %i\n",Used); - - if (Entry->Protected) { - Buffer[0] = 0x17; /* ID for ODI */ - Buffer[1] = 2; /* Length of rest */ - Buffer[2] = Used+1; /* Number of protected objects */ - Buffer[3] = 1; /* 1=Protected,0=Not protected */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); - } - - /* Save UPI UDH */ - Buffer[0] = 0x13; /* ID for UPI */ - Buffer[1] = 1; /* Length of rest */ - Buffer[2] = Used; /* Number of used parts */ - - /* Find free place in first SMS */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3,true,&UsedText,&CopiedText,&CopiedSMSText); - GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); - Length = FreeBytes - 3; - if (Length < 0) Length = 128; - if (Length > 128) Length = 128; - -#ifdef DEBUG - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Bitmap); -#endif - - /* Saving SMS */ - FreeBytes = 0; - while (FreeBytes != Width) { - Width2 = 8; - while(1) { - if (FreeBytes+Width2 == Width) break; - - if (PHONE_GetBitmapSize(BitmapType,Width2+8,Height) > Length) break; - - Width2 = Width2 + 8; - } - - /* Copying part of bitmap to new structure */ - Bitmap2.Width = Width2; - Bitmap2.Height = Height; - GSM_ClearBitmap(&Bitmap2); - for (x=0;xSMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3-Length] = UsedText; - - FreeBytes = FreeBytes + Width2; - Length = 128; - } - break; - case SMS_EMSVariableBitmap: - if (Entry->Protected) { - Buffer[0] = 0x17; /* ID for ODI */ - Buffer[1] = 2; /* Length of rest */ - Buffer[2] = 1; /* Number of protected objects */ - Buffer[3] = 1; /* 1=Protected,0=Not protected */ - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); - } - - BitmapType = GSM_EMSVariablePicture; - Width = Entry->Bitmap->Bitmap[0].Width; - Height = Entry->Bitmap->Bitmap[0].Height; - - while (1) { - /* Width should be multiply of 8 */ - while (Width % 8 != 0) Width--; - - /* specs */ - if (PHONE_GetBitmapSize(BitmapType,Width,Height) <= 128) break; - - Height--; - } - - Length = PHONE_GetBitmapSize(BitmapType,Width,Height); - - Buffer[0] = 0x12; /* ID for EMS bitmap */ - Buffer[1] = Length + 3; /* Length of rest */ - Buffer[2] = 0x00; /* Position in EMS msg */ - Buffer[3] = Width/8; /* Bitmap width/8 */ - Buffer[4] = Height; /* Bitmap height */ - - GSM_ResizeBitmap(&Bitmap, &Entry->Bitmap->Bitmap[0], Width, Height); -#ifdef DEBUG - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Bitmap); -#endif - PHONE_EncodeBitmap(BitmapType,Buffer+5, &Bitmap); - GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,5+Length,true,&UsedText,&CopiedText,&CopiedSMSText); - SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3-Length] = UsedText; - break; - default: - break; - } - } - - SMS->Number++; - - if (UDHType == UDH_ConcatenatedMessages) { - UDHID = GSM_MakeSMSIDFromTime(); - for (i=0;iNumber;i++) { - SMS->SMS[i].UDH.Text[2+1] = UDHID; - SMS->SMS[i].UDH.Text[3+1] = SMS->Number; - SMS->SMS[i].UDH.Text[4+1] = i+1; - } - } - if (UDHType == UDH_ConcatenatedMessages16bit) { - UDHID = GSM_MakeSMSIDFromTime(); - GSM_GetCurrentDateTime (&Date); - for (i=0;iNumber;i++) { - SMS->SMS[i].UDH.Text[2+1] = Date.Hour; - SMS->SMS[i].UDH.Text[3+1] = UDHID; - SMS->SMS[i].UDH.Text[4+1] = SMS->Number; - SMS->SMS[i].UDH.Text[5+1] = i+1; - } - } - -#ifdef DEBUG - dbgprintf("SMS number is %i\n",SMS->Number); - for (i=0;iNumber;i++) { - dbgprintf("UDH length %i\n",SMS->SMS[i].UDH.Length); - DumpMessage(di.df, SMS->SMS[i].UDH.Text, SMS->SMS[i].UDH.Length); - dbgprintf("SMS length %i\n",UnicodeLength(SMS->SMS[i].Text)*2); - DumpMessage(di.df, SMS->SMS[i].Text, UnicodeLength(SMS->SMS[i].Text)*2); - } -#endif - return GE_NONE; -} - -GSM_Error GSM_EncodeMultiPartSMS(GSM_EncodeMultiPartSMSInfo *Info, - GSM_MultiSMSMessage *SMS) -{ - unsigned char Buffer[GSM_MAX_SMS_LENGTH*2*MAX_MULTI_SMS]; - unsigned char Buffer2[GSM_MAX_SMS_LENGTH*2*MAX_MULTI_SMS]; - int Length = 0,smslen,i, Class = -1; - GSM_Error error; - GSM_Coding_Type Coding = GSM_Coding_8bit; - GSM_UDH UDH = UDH_NoUDH; - GSM_UDHHeader UDHHeader; - bool EMS = false; - - SMS->Number = 0; - - for (i=0;iEntriesNum;i++) { - switch (Info->Entries[i].ID) { - case SMS_EMSPredefinedAnimation: - case SMS_EMSPredefinedSound: - case SMS_EMSSound10: - case SMS_EMSSound12: - case SMS_EMSSonyEricssonSound: - case SMS_EMSSound10Long: - case SMS_EMSSound12Long: - case SMS_EMSSonyEricssonSoundLong: - case SMS_EMSFixedBitmap: - case SMS_EMSVariableBitmap: - case SMS_EMSAnimation: - case SMS_EMSVariableBitmapLong: - EMS = true; - break; - case SMS_ConcatenatedTextLong: - case SMS_ConcatenatedTextLong16bit: - if (Info->Entries[i].Left || Info->Entries[i].Right || - Info->Entries[i].Center || Info->Entries[i].Large || - Info->Entries[i].Small || Info->Entries[i].Bold || - Info->Entries[i].Italic || Info->Entries[i].Underlined || - Info->Entries[i].Strikethrough) { - EMS = true; - } - default: - break; - } - if (EMS) break; - } - if (EMS) { - error=GSM_EncodeEMSMultiPartSMS(Info,SMS,UDH_NoUDH); - if (error != GE_NONE) return error; - if (SMS->Number != 1) { - SMS->Number = 0; - for (i=0;iEntriesNum;i++) { - if (Info->Entries[i].ID == SMS_ConcatenatedTextLong16bit) { - return GSM_EncodeEMSMultiPartSMS(Info,SMS,UDH_ConcatenatedMessages); - } - } - return GSM_EncodeEMSMultiPartSMS(Info,SMS,UDH_ConcatenatedMessages16bit); - } - return error; - } - if (Info->EntriesNum != 1) return GE_UNKNOWN; - - switch (Info->Entries[0].ID) { - case SMS_MMSIndicatorLong: - Class = 1; - UDH = UDH_MMSIndicatorLong; - GSM_EncodeMMSIndicatorSMSText(Buffer,&Length,*Info->Entries[0].MMSIndicator); - break; - case SMS_NokiaRingtoneLong: - case SMS_NokiaRingtone: - UDH = UDH_NokiaRingtone; - Class = 1; - /* 7 = length of UDH_NokiaRingtone UDH header */ - Length = GSM_MAX_8BIT_SMS_LENGTH-7; - Info->Entries[0].RingtoneNotes = GSM_EncodeNokiaRTTLRingtone(*Info->Entries[0].Ringtone,Buffer,&Length); - if (Info->Entries[0].ID == SMS_NokiaRingtone) break; - if (Info->Entries[0].RingtoneNotes != Info->Entries[0].Ringtone->NoteTone.NrCommands) { - UDH = UDH_NokiaRingtoneLong; - Length = (GSM_MAX_8BIT_SMS_LENGTH-12)*3; - Info->Entries[0].RingtoneNotes = GSM_EncodeNokiaRTTLRingtone(*Info->Entries[0].Ringtone,Buffer,&Length); - } - break; - case SMS_NokiaOperatorLogoLong: - if (Info->Entries[0].Bitmap->Bitmap[0].Width > 72 || Info->Entries[0].Bitmap->Bitmap[0].Height > 14) { - UDH = UDH_NokiaOperatorLogoLong; - Class = 1; - NOKIA_EncodeNetworkCode(Buffer, Info->Entries[0].Bitmap->Bitmap[0].NetworkCode); - Length = Length + 3; - NOKIA_CopyBitmap(GSM_Nokia7110OperatorLogo, &Info->Entries[0].Bitmap->Bitmap[0], Buffer, &Length); - break; - } - case SMS_NokiaOperatorLogo: - UDH = UDH_NokiaOperatorLogo; - Class = 1; - NOKIA_EncodeNetworkCode(Buffer, Info->Entries[0].Bitmap->Bitmap[0].NetworkCode); - Length = Length + 3; - NOKIA_CopyBitmap(GSM_NokiaOperatorLogo, &Info->Entries[0].Bitmap->Bitmap[0], Buffer, &Length); - break; - case SMS_NokiaCallerLogo: - UDH = UDH_NokiaCallerLogo; - Class = 1; - NOKIA_CopyBitmap(GSM_NokiaCallerLogo, &Info->Entries[0].Bitmap->Bitmap[0], Buffer, &Length); - break; - case SMS_NokiaProfileLong: - case SMS_NokiaPictureImageLong: - case SMS_NokiaScreenSaverLong: - Class = 1; - UDH = UDH_NokiaProfileLong; - GSM_EncodeSMS30MultiPartSMS(Info,Buffer,&Length); - break; - case SMS_NokiaWAPBookmarkLong: - Class = 1; - NOKIA_EncodeWAPBookmarkSMSText(Buffer,&Length,Info->Entries[0].Bookmark); - /* 7 = length of UDH_NokiaWAP UDH header */ - if (Length>(GSM_MAX_8BIT_SMS_LENGTH-7)) { - UDH=UDH_NokiaWAPLong; - } else { - UDH=UDH_NokiaWAP; - } - break; - case SMS_NokiaWAPSettingsLong: - Class = 1; - UDH = UDH_NokiaWAPLong; - NOKIA_EncodeWAPMMSSettingsSMSText(Buffer,&Length,Info->Entries[0].Settings,false); - break; - case SMS_NokiaMMSSettingsLong: - Class = 1; - UDH = UDH_NokiaWAPLong; - NOKIA_EncodeWAPMMSSettingsSMSText(Buffer,&Length,Info->Entries[0].Settings,true); - break; - case SMS_NokiaVCARD10Long: - GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard10); - /* is 1 SMS ? 8 = length of ..SCKE2 */ - if (Length<=GSM_MAX_SMS_LENGTH-8) { - sprintf(Buffer,"//SCKE2 "); - Length = 8; - GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard10); - } else { - /* FIXME: It wasn't checked */ - UDH = UDH_NokiaPhonebookLong; - } - Coding = GSM_Coding_Default; - memcpy(Buffer2,Buffer,Length); - EncodeUnicode(Buffer,Buffer2,Length); - break; - case SMS_NokiaVCARD21Long: - GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard21); - /* Is 1 SMS ? 12 = length of ..SCKL23F4 */ - if (Length<=GSM_MAX_SMS_LENGTH-12) { - sprintf(Buffer,"//SCKL23F4%c%c",13,10); - Length = 12; - GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard21); - } else { - UDH = UDH_NokiaPhonebookLong; - /* Here can be also 8 bit coding */ - } - Coding = GSM_Coding_Default; - memcpy(Buffer2,Buffer,Length); - EncodeUnicode(Buffer,Buffer2,Length); - break; - case SMS_VCARD10Long: - GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard10); - if (Length>GSM_MAX_SMS_LENGTH) UDH = UDH_ConcatenatedMessages; - Coding = GSM_Coding_Default; - memcpy(Buffer2,Buffer,Length); - EncodeUnicode(Buffer,Buffer2,Length); - break; - case SMS_VCARD21Long: - GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard21); - if (Length>GSM_MAX_SMS_LENGTH) UDH = UDH_ConcatenatedMessages; - Coding = GSM_Coding_Default; - memcpy(Buffer2,Buffer,Length); - EncodeUnicode(Buffer,Buffer2,Length); - break; - case SMS_NokiaVCALENDAR10Long: - error=GSM_EncodeVCALENDAR(Buffer,&Length,Info->Entries[0].Calendar,true,Nokia_VCalendar); - if (error != GE_NONE) return error; - /* Is 1 SMS ? 8 = length of ..SCKE4 */ - if (Length<=GSM_MAX_SMS_LENGTH-8) { - sprintf(Buffer,"//SCKE4 "); - Length = 8; - GSM_EncodeVCALENDAR(Buffer,&Length,Info->Entries[0].Calendar,true,Nokia_VCalendar); - } else { - UDH = UDH_NokiaCalendarLong; - /* can be here 8 bit coding ? */ - } - Coding = GSM_Coding_Default; - memcpy(Buffer2,Buffer,Length); - EncodeUnicode(Buffer,Buffer2,Length); - break; - case SMS_NokiaVTODOLong: - error=GSM_EncodeVTODO(Buffer,&Length,Info->Entries[0].ToDo,true,Nokia_VToDo); - if (error != GE_NONE) return error; - UDH = UDH_NokiaCalendarLong; - Coding = GSM_Coding_Default; - memcpy(Buffer2,Buffer,Length); - EncodeUnicode(Buffer,Buffer2,Length); - break; - case SMS_DisableVoice: - case SMS_DisableFax: - case SMS_DisableEmail: - case SMS_EnableVoice: - case SMS_EnableFax: - case SMS_EnableEmail: - case SMS_VoidSMS: - case SMS_Text: - Class = Info->Class; - switch (Info->Entries[0].ID) { - case SMS_DisableVoice : UDH = UDH_DisableVoice; break; - case SMS_DisableFax : UDH = UDH_DisableFax; break; - case SMS_DisableEmail : UDH = UDH_DisableEmail; break; - case SMS_EnableVoice : UDH = UDH_EnableVoice; break; - case SMS_EnableFax : UDH = UDH_EnableFax; break; - case SMS_EnableEmail : UDH = UDH_EnableEmail; break; - case SMS_VoidSMS : UDH = UDH_VoidSMS; break; - case SMS_Text : UDH = UDH_NoUDH; break; - default : break; - } - UDHHeader.Type = UDH; - GSM_EncodeUDHHeader(&UDHHeader); - memcpy(Buffer,Info->Entries[0].Buffer,UnicodeLength(Info->Entries[0].Buffer)*2+2); - if (Info->UnicodeCoding) { - Coding = GSM_Coding_Unicode; - Length = UnicodeLength(Info->Entries[0].Buffer); - if (Length>(140-UDHHeader.Length)/2) Length = (140-UDHHeader.Length)/2; - } else { - Coding = GSM_Coding_Default; - FindDefaultAlphabetLen(Info->Entries[0].Buffer,&Length,&smslen,(GSM_MAX_8BIT_SMS_LENGTH-UDHHeader.Length)*8/7); - } - break; - case SMS_ConcatenatedAutoTextLong: - case SMS_ConcatenatedAutoTextLong16bit: - smslen = UnicodeLength(Info->Entries[0].Buffer); - memcpy(Buffer,Info->Entries[0].Buffer,smslen*2); - EncodeDefault(Buffer2, Buffer, &smslen, true, NULL); - DecodeDefault(Buffer, Buffer2, smslen, true, NULL); -#ifdef DEBUG - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) { - dbgprintf("Info->Entries[0].Buffer:\n"); - DumpMessage(di.df, Info->Entries[0].Buffer, UnicodeLength(Info->Entries[0].Buffer)*2); - dbgprintf("Buffer:\n"); - DumpMessage(di.df, Buffer, UnicodeLength(Buffer)*2); - } -#endif - Info->UnicodeCoding = false; - for (smslen=0;smslen<(int)(UnicodeLength(Info->Entries[0].Buffer)*2);smslen++) { - if (Info->Entries[0].Buffer[smslen] != Buffer[smslen]) { - Info->UnicodeCoding = true; - dbgprintf("Setting to Unicode %i\n",smslen); - break; - } - } - /* No break here - we go to the SMS_ConcatenatedTextLong */ - case SMS_ConcatenatedTextLong: - case SMS_ConcatenatedTextLong16bit: - Class = Info->Class; - memcpy(Buffer,Info->Entries[0].Buffer,UnicodeLength(Info->Entries[0].Buffer)*2+2); - UDH = UDH_NoUDH; - if (Info->UnicodeCoding) { - Coding = GSM_Coding_Unicode; - Length = UnicodeLength(Info->Entries[0].Buffer); - if (Info->Entries[0].ID == SMS_ConcatenatedTextLong16bit || - Info->Entries[0].ID == SMS_ConcatenatedAutoTextLong16bit) { - if (Length>70) UDH=UDH_ConcatenatedMessages16bit; - } else { - if (Length>70) UDH=UDH_ConcatenatedMessages; - } - } else { - Coding = GSM_Coding_Default; - FindDefaultAlphabetLen(Info->Entries[0].Buffer,&Length,&smslen,5000); - if (Info->Entries[0].ID == SMS_ConcatenatedTextLong16bit || - Info->Entries[0].ID == SMS_ConcatenatedAutoTextLong16bit) { - if (smslen>GSM_MAX_SMS_LENGTH) UDH=UDH_ConcatenatedMessages16bit; - } else { - if (smslen>GSM_MAX_SMS_LENGTH) UDH=UDH_ConcatenatedMessages; - } - } - default: - break; - } - GSM_MakeMultiPartSMS(SMS,Buffer,Length,UDH,Coding,Class,Info->ReplaceMessage); - return GE_NONE; -} - -void GSM_ClearMultiPartSMSInfo(GSM_EncodeMultiPartSMSInfo *Info) -{ - int i; - - for (i=0;iEntries[i].Buffer = NULL; - Info->Entries[i].Ringtone = NULL; - Info->Entries[i].Bitmap = NULL; - Info->Entries[i].Phonebook = NULL; - Info->Entries[i].Bookmark = NULL; - Info->Entries[i].Settings = NULL; - Info->Entries[i].Calendar = NULL; - Info->Entries[i].ToDo = NULL; - Info->Entries[i].MMSIndicator = NULL; - Info->Entries[i].Left = false; - Info->Entries[i].Right = false; - Info->Entries[i].Center = false; - Info->Entries[i].Large = false; - Info->Entries[i].Small = false; - Info->Entries[i].Bold = false; - Info->Entries[i].Italic = false; - Info->Entries[i].Underlined = false; - Info->Entries[i].Strikethrough = false; - - Info->Entries[i].Protected = false; - } -} - -/* ----------------- Joining SMS from parts -------------------------------- */ - -bool GSM_DecodeMultiPartSMS(GSM_EncodeMultiPartSMSInfo *Info, - GSM_MultiSMSMessage *SMS) -{ - int i; - char Buffer[GSM_MAX_SMS_LENGTH*2*MAX_MULTI_SMS]; - int Length = 0; - bool RetVal = false, Bitmap = false, Ringtone = false, TextBuffer = false; - - if (SMS->SMS[0].UDH.Type == UDH_NokiaRingtone && SMS->Number == 1) { - if (GSM_DecodeNokiaRTTLRingtone(Info->Entries[0].Ringtone, SMS->SMS[0].Text, SMS->SMS[0].Length)==GE_NONE) - { - RetVal = true; - Ringtone = true; - } - } - if (SMS->SMS[0].UDH.Type == UDH_NokiaCallerLogo && SMS->Number == 1) { - PHONE_DecodeBitmap(GSM_NokiaCallerLogo, SMS->SMS[0].Text+4, &Info->Entries[0].Bitmap->Bitmap[0]); -#ifdef DEBUG - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Info->Entries[0].Bitmap->Bitmap[0]); -#endif - Bitmap = true; - RetVal = true; - } - if (SMS->SMS[0].UDH.Type == UDH_NokiaOperatorLogo && SMS->Number == 1) { - PHONE_DecodeBitmap(GSM_NokiaOperatorLogo, SMS->SMS[0].Text+7, &Info->Entries[0].Bitmap->Bitmap[0]); - NOKIA_DecodeNetworkCode(SMS->SMS[0].Text, Info->Entries[0].Bitmap->Bitmap[0].NetworkCode); -#ifdef DEBUG - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Info->Entries[0].Bitmap->Bitmap[0]); -#endif - Bitmap = true; - RetVal = true; - } - - if (SMS->SMS[0].UDH.Type == UDH_ConcatenatedMessages || - SMS->SMS[0].UDH.Type == UDH_ConcatenatedMessages16bit) { - for (i=0;iNumber;i++) { - switch (SMS->SMS[i].Coding) { - case GSM_Coding_8bit: - memcpy(Info->Entries[0].Buffer+Length,SMS->SMS[i].Text,SMS->SMS[i].Length); - Length=Length+SMS->SMS[i].Length; - break; - case GSM_Coding_Unicode: - case GSM_Coding_Default: - memcpy(Info->Entries[0].Buffer+Length,SMS->SMS[i].Text,UnicodeLength(SMS->SMS[i].Text)*2); - Length=Length+UnicodeLength(SMS->SMS[i].Text)*2; - break; - } - } - Info->Entries[0].Buffer[Length] = 0; - Info->Entries[0].Buffer[Length+1] = 0; - TextBuffer = true; - RetVal = true; - } - - /* Generally Smart Messaging 3.0 decoding */ - if (SMS->SMS[0].UDH.Type == UDH_NokiaProfileLong) { - RetVal = true; - for (i=0;iNumber;i++) { - if (SMS->SMS[i].UDH.Type != UDH_NokiaProfileLong || - SMS->SMS[i].UDH.Text[11] != i+1 || - SMS->SMS[i].UDH.Text[10] != SMS->Number) - { - return false; - } - memcpy(Buffer+Length,SMS->SMS[i].Text,SMS->SMS[i].Length); - Length = Length + SMS->SMS[i].Length; - } - Info->Entries[0].Bitmap->Bitmap[0].Text[0] = 0; - Info->Entries[0].Bitmap->Bitmap[0].Text[1] = 0; - i=1; - while (i!=Length) { - switch (Buffer[i]) { - case SM30_ISOTEXT: - dbgprintf("ISO 8859-2 text\n"); - break; - case SM30_UNICODETEXT: - dbgprintf("Unicode text\n"); - memcpy(Info->Entries[0].Bitmap->Bitmap[0].Text,Buffer+i+3,Buffer[i+1]*256+Buffer[i+2]); - Info->Entries[0].Bitmap->Bitmap[0].Text[Buffer[i+1]*256 + Buffer[i+2]] = 0; - Info->Entries[0].Bitmap->Bitmap[0].Text[Buffer[i+1]*256 + Buffer[i+2]+ 1] = 0; - dbgprintf("Unicode Text \"%s\"\n",DecodeUnicodeString(Info->Entries[0].Bitmap->Bitmap[0].Text)); - break; - case SM30_OTA: - dbgprintf("OTA bitmap as Picture Image\n"); - PHONE_DecodeBitmap(GSM_NokiaPictureImage, Buffer + i + 7, &Info->Entries[0].Bitmap->Bitmap[0]); -#ifdef DEBUG - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Info->Entries[0].Bitmap->Bitmap[0]); -#endif - Bitmap = true; - break; - case SM30_RINGTONE: - dbgprintf("RTTL ringtone\n"); - break; - case SM30_PROFILENAME: - dbgprintf("Profile Name\n"); - break; - case SM30_SCREENSAVER: - dbgprintf("OTA bitmap as Screen Saver\n"); - PHONE_DecodeBitmap(GSM_NokiaPictureImage, Buffer + i + 7, &Info->Entries[0].Bitmap->Bitmap[0]); -#ifdef DEBUG - if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Info->Entries[0].Bitmap->Bitmap[0]); -#endif - Bitmap = true; - break; - } - i = i + Buffer[i+1]*256 + Buffer[i+2] + 3; - dbgprintf("%i %i\n",i,Length); - } - } - if (!Bitmap) Info->Entries[0].Bitmap = NULL; - if (!TextBuffer) Info->Entries[0].Buffer = NULL; - if (!Ringtone) Info->Entries[0].Ringtone = NULL; - return RetVal; -} - -GSM_Error GSM_SortSMS(GSM_MultiSMSMessage *INPUT[150], GSM_MultiSMSMessage *OUTPUT[150]) -{ - bool INPUTSorted[150],copyit; - int i,OUTPUTNum,j,z,loop; - - for (i=0;i<150;i++) INPUTSorted[i] = false; - - OUTPUTNum = 0; - OUTPUT[0] = NULL; - - i=0; - while (INPUT[i]!=NULL) { - loop = true; - /* If this one SMS was sorted earlier, do not touch */ - if (INPUTSorted[i]) { - i++; - loop=false; - } - if (loop) { - /* If we have: - * - linked sms returned by phone driver - * - sms without linking - * - unknown sms - * we copy it to OUTPUT - */ - if (INPUT[i]->Number != 1 || - INPUT[i]->SMS[0].UDH.Type == UDH_NoUDH || - INPUT[i]->SMS[0].UDH.Type == UDH_UserUDH || - INPUT[i]->SMS[0].UDH.PartNumber == -1) { - OUTPUT[OUTPUTNum] = malloc(sizeof(GSM_MultiSMSMessage)); - if (OUTPUT[OUTPUTNum] == NULL) return GE_MOREMEMORY; - OUTPUT[OUTPUTNum+1] = NULL; - - memcpy(OUTPUT[OUTPUTNum],INPUT[i],sizeof(GSM_MultiSMSMessage)); - INPUTSorted[i]=true; - OUTPUTNum++; - i=0; - loop = false; - } - } - if (loop) { - /* We have 1'st part of linked sms. It's single. - * We will try to find other parts - */ - if (INPUT[i]->SMS[0].UDH.PartNumber == 1) { - OUTPUT[OUTPUTNum] = malloc(sizeof(GSM_MultiSMSMessage)); - if (OUTPUT[OUTPUTNum] == NULL) return GE_MOREMEMORY; - OUTPUT[OUTPUTNum+1] = NULL; - - memcpy(&OUTPUT[OUTPUTNum]->SMS[0],&INPUT[i]->SMS[0],sizeof(GSM_SMSMessage)); - OUTPUT[OUTPUTNum]->Number = 1; - INPUTSorted[i]=true; - j=1; - while (j!=INPUT[i]->SMS[0].UDH.AllParts) { - z=0; - while(INPUT[z]!=NULL) { - copyit=false; - /* Look for - * - non sorted earlier - * - single - * - with the same UDH (with the same ID, etc.) to the first sms - */ - if (!INPUTSorted[z] && - INPUT[z]->Number == 1 && - INPUT[z]->SMS[0].UDH.Type == INPUT[i]->SMS[0].UDH.Type && - INPUT[z]->SMS[0].UDH.ID8bit == INPUT[i]->SMS[0].UDH.ID8bit && - INPUT[z]->SMS[0].UDH.ID16bit == INPUT[i]->SMS[0].UDH.ID16bit && - INPUT[z]->SMS[0].UDH.AllParts == INPUT[i]->SMS[0].UDH.AllParts && - INPUT[z]->SMS[0].UDH.PartNumber == j+1) { - /* For SMS_Deliver compare also SMSC and Sender number */ - if (INPUT[z]->SMS[0].PDU == SMS_Deliver) { - if (!strcmp(DecodeUnicodeString(INPUT[z]->SMS[0].SMSC.Number),DecodeUnicodeString(INPUT[i]->SMS[0].SMSC.Number)) && - !strcmp(DecodeUnicodeString(INPUT[z]->SMS[0].Number),DecodeUnicodeString(INPUT[i]->SMS[0].Number))) { - if (UnicodeLength(INPUT[z]->SMS[0].SMSC.Number)!=0 || UnicodeLength(INPUT[z]->SMS[0].Number)!=0) { - copyit=true; - } else { - if (INPUT[z]->SMS[0].DateTime.Day == INPUT[i]->SMS[0].DateTime.Day && - INPUT[z]->SMS[0].DateTime.Month == INPUT[i]->SMS[0].DateTime.Month && - INPUT[z]->SMS[0].DateTime.Year == INPUT[i]->SMS[0].DateTime.Year && - INPUT[z]->SMS[0].DateTime.Hour == INPUT[i]->SMS[0].DateTime.Hour && - INPUT[z]->SMS[0].DateTime.Minute == INPUT[i]->SMS[0].DateTime.Minute && - INPUT[z]->SMS[0].DateTime.Second == INPUT[i]->SMS[0].DateTime.Second) { - copyit=true; - } - - } - } - } else copyit=true; - } - /* We found correct sms. Copy it */ - if (copyit) { - memcpy(&OUTPUT[OUTPUTNum]->SMS[j],&INPUT[z]->SMS[0],sizeof(GSM_SMSMessage)); - OUTPUT[OUTPUTNum]->Number++; - INPUTSorted[z]=true; - break; - } - z++; - } - /* Incomplete sequence */ - if (OUTPUT[OUTPUTNum]->Number==j) break; - j++; - } - OUTPUTNum++; - i=0; - } - } - } - return GE_NONE; -} - -/* How should editor hadle tabs in this file? Add editor commands here. - * vim: noexpandtab sw=8 ts=8 sts=8: - */ diff --git a/common/service/sms/Makefile b/common/service/sms/Makefile new file mode 100644 index 000000000..ccba67734 --- /dev/null +++ b/common/service/sms/Makefile @@ -0,0 +1,4 @@ + +TOPDIR=../../.. + +include $(TOPDIR)/cfg/Makefile.glo diff --git a/common/service/sms/gsmems.c b/common/service/sms/gsmems.c new file mode 100644 index 000000000..5b55a48b4 --- /dev/null +++ b/common/service/sms/gsmems.c @@ -0,0 +1,750 @@ + +#include +#include +#include + +#include "../../gsmcomon.h" +#include "../../misc/coding/coding.h" +#include "../gsmcal.h" +#include "../gsmpbk.h" +#include "../gsmlogo.h" +#include "../gsmring.h" +#include "../gsmwap.h" +#include "../gsmnet.h" +#include "gsmsms.h" +#include "gsmmulti.h" + +/* EMS Developers' Guidelines from www.sonyericsson.com + * docs from Alcatel + */ +GSM_Error GSM_EncodeEMSMultiPartSMS(GSM_EncodeMultiPartSMSInfo *Info, + GSM_MultiSMSMessage *SMS, + GSM_UDH UDHType) +{ + unsigned char Buffer[GSM_MAX_SMS_LENGTH*2*MAX_MULTI_SMS]; + int i,UsedText,j,Length,Width,Height,z,x,y; + unsigned int Len; + int Used,FreeText,FreeBytes,Width2,CopiedText,CopiedSMSText; + unsigned char UDHID; + GSM_Bitmap Bitmap,Bitmap2; + GSM_Ringtone Ring; + GSM_Coding_Type Coding = GSM_Coding_Default; + GSM_Phone_Bitmap_Types BitmapType; + EncodeMultiPartSMSEntry *Entry; + bool start; + GSM_DateTime Date; + +#ifdef DEBUG + if (UDHType != UDH_NoUDH) dbgprintf("linked EMS\n"); +#endif + + if (Info->UnicodeCoding) Coding = GSM_Coding_Unicode; + + /* Cleaning on the start */ + for (i=0;iSMS[i]); + SMS->SMS[i].UDH.Type = UDHType; + GSM_EncodeUDHHeader(&SMS->SMS[i].UDH); + SMS->SMS[i].Coding = Coding; + } + + /* Packing */ + for (i=0;iEntriesNum;i++) { + Entry = &Info->Entries[i]; + + switch (Entry->ID) { + case SMS_ConcatenatedTextLong: + case SMS_ConcatenatedTextLong16bit: + Len = 0; + while(1) { + if (Entry->Left || Entry->Right || + Entry->Center || Entry->Large || + Entry->Small || Entry->Bold || + Entry->Italic || Entry->Underlined || + Entry->Strikethrough) { + Buffer[0] = 0x0A; /* ID for text format */ + Buffer[1] = 0x03; /* length of rest */ + Buffer[2] = 0x00; /* Position in EMS msg */ + Buffer[3] = 0x00; /* how many chars */ + Buffer[4] = 0x00; /* formatting bits */ + if (Entry->Left) { + } else if (Entry->Right) { Buffer[4] |= 1; + } else if (Entry->Center) { Buffer[4] |= 2; + } else Buffer[4] |= 3; + if (Entry->Large) { Buffer[4] |= 4; + } else if (Entry->Small) { Buffer[4] |= 8;} + if (Entry->Bold) Buffer[4] |= 16; + if (Entry->Italic) Buffer[4] |= 32; + if (Entry->Underlined) Buffer[4] |= 64; + if (Entry->Strikethrough) Buffer[4] |= 128; + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,5,true,&UsedText,&CopiedText,&CopiedSMSText); + GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); + if (FreeText == 0) continue; + } + GSM_AddSMS_Text_UDH(SMS,Coding,Entry->Buffer+Len*2,UnicodeLength(Entry->Buffer) - Len,false,&UsedText,&CopiedText,&CopiedSMSText); + if (Entry->Left || Entry->Right || + Entry->Center || Entry->Large || + Entry->Small || Entry->Bold || + Entry->Italic || Entry->Underlined || + Entry->Strikethrough) { + SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3] = UsedText; + SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-2] = CopiedSMSText; + } + Len += CopiedText; + if (Len == UnicodeLength(Entry->Buffer)) break; + dbgprintf("%i %i\n",Len,UnicodeLength(Entry->Buffer)); + } + break; + case SMS_EMSPredefinedSound: + case SMS_EMSPredefinedAnimation: + if (Entry->ID == SMS_EMSPredefinedSound) { + Buffer[0] = 0x0B; /* ID for def.sound */ + } else { + Buffer[0] = 0x0D; /* ID for def.animation */ + } + Buffer[1] = 0x02; /* Length of rest */ + Buffer[2] = 0x00; /* Position in EMS msg */ + Buffer[3] = Entry->Number; /* Number of anim. */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); + SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-2] = UsedText; + break; + case SMS_EMSSonyEricssonSound: + case SMS_EMSSound10: + case SMS_EMSSound12: + if (Entry->Protected) { + Buffer[0] = 0x17; /* ID for ODI */ + Buffer[1] = 2; /* Length of rest */ + Buffer[2] = 1; /* Number of protected objects */ + Buffer[3] = 1; /* 1=Protected,0=Not protected */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); + } + + Length = 128; /* 128 bytes is maximal length from specs */ + switch (Entry->ID) { + case SMS_EMSSound10: + Entry->RingtoneNotes = GSM_EncodeEMSSound(*Entry->Ringtone, Buffer+3, &Length, 1.0, true); + break; + case SMS_EMSSound12: + Entry->RingtoneNotes = GSM_EncodeEMSSound(*Entry->Ringtone, Buffer+3, &Length, 1.2, true); + break; + case SMS_EMSSonyEricssonSound: + Entry->RingtoneNotes = GSM_EncodeEMSSound(*Entry->Ringtone, Buffer+3, &Length, 0, true); + break; + default: + break; + } + + Buffer[0] = 0x0C; /* ID for EMS sound */ + Buffer[1] = Length+1; /* Length of rest */ + Buffer[2] = 0x00; /* Position in EMS msg */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,Length+3,true,&UsedText,&CopiedText,&CopiedSMSText); + SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-Length-1] = UsedText; + break; + case SMS_EMSSonyEricssonSoundLong: + case SMS_EMSSound10Long: + case SMS_EMSSound12Long: + memcpy(&Ring,Entry->Ringtone,sizeof(GSM_Ringtone)); + + /* First check if we can use classic format */ + Length = 128; /* 128 bytes is maximal length from specs */ + switch (Entry->ID) { + case SMS_EMSSound10Long: + Entry->RingtoneNotes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.0, true); + break; + case SMS_EMSSound12Long: + Entry->RingtoneNotes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.2, true); + break; + case SMS_EMSSonyEricssonSoundLong: + Entry->RingtoneNotes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 0, true); + break; + default: + break; + } + if (Entry->RingtoneNotes == Ring.NoteTone.NrCommands) { + if (Entry->Protected) { + Buffer[0] = 0x17; /* ID for ODI */ + Buffer[1] = 2; /* Length of rest */ + Buffer[2] = 1; /* Number of protected objects */ + Buffer[3] = 1; /* 1=Protected,0=Not protected */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); + } + + Buffer[0] = 0x0C; /* ID for EMS sound */ + Buffer[1] = Length+1; /* Length of rest */ + Buffer[2] = 0x00; /* Position in EMS msg */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,Length+3,true,&UsedText,&CopiedText,&CopiedSMSText); + SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-Length-1] = UsedText; + break; + } + + /* Find free place in first SMS */ + GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); + Length = FreeBytes - 3; + if (Entry->Protected) Length = Length - 4; + if (Length < 0) Length = 128; + if (Length > 128) Length = 128; + + memcpy(&Ring,Entry->Ringtone,sizeof(GSM_Ringtone)); + + /* Checking number of SMS */ + Used = 0; + FreeBytes = 0; + start = true; + while (1) { + if (FreeBytes != 0) { + z = 0; + for (j=FreeBytes;jID) { + case SMS_EMSSound10Long: + FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.0, start); + break; + case SMS_EMSSound12Long: + FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.2, start); + break; + case SMS_EMSSonyEricssonSoundLong: + FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 0, start); + break; + default: + break; + } + start = false; + Used++; + } + dbgprintf("Used SMS: %i\n",Used); + + if (Entry->Protected) { + Buffer[0] = 0x17; /* ID for ODI */ + Buffer[1] = 2; /* Length of rest */ + Buffer[2] = Used+1; /* Number of protected objects */ + Buffer[3] = 1; /* 1=Protected,0=Not protected */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); + } + + /* Save UPI UDH */ + Buffer[0] = 0x13; /* ID for UPI */ + Buffer[1] = 1; /* Length of rest */ + Buffer[2] = Used; /* Number of used parts */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3,true,&UsedText,&CopiedText,&CopiedSMSText); + + /* Find free place in first SMS */ + GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); + Length = FreeBytes - 3; + if (Length < 0) Length = 128; + if (Length > 128) Length = 128; + + memcpy(&Ring,Entry->Ringtone,sizeof(GSM_Ringtone)); + + /* Saving */ + FreeBytes = 0; + start = true; + while (1) { + if (FreeBytes != 0) { + z = 0; + for (j=FreeBytes;jID) { + case SMS_EMSSound10Long: + FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.0, start); + break; + case SMS_EMSSound12Long: + FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 1.2, start); + break; + case SMS_EMSSonyEricssonSoundLong: + FreeBytes = GSM_EncodeEMSSound(Ring, Buffer+3, &Length, 0, start); + break; + default: + break; + } + Buffer[0] = 0x0C; /* ID for EMS sound */ + Buffer[1] = Length+1; /* Length of rest */ + Buffer[2] = 0x00; /* Position in EMS msg */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,Length+3,true,&UsedText,&CopiedText,&CopiedSMSText); + SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-Length-1] = UsedText; + start = false; + } + + Entry->RingtoneNotes = Entry->Ringtone->NoteTone.NrCommands; + + break; + case SMS_EMSAnimation: + if (Entry->Protected) { + Buffer[0] = 0x17; /* ID for ODI */ + Buffer[1] = 2; /* Length of rest */ + Buffer[2] = 1; /* Number of protected objects */ + Buffer[3] = 1; /* 1=Protected,0=Not protected */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); + } + + if (Entry->Bitmap->Bitmap[0].Width > 8 || Entry->Bitmap->Bitmap[0].Height > 8) { + BitmapType = GSM_EMSMediumPicture; /* Bitmap 16x16 */ + Buffer[0] = 0x0E; /* ID for 16x16 animation */ + } else { + BitmapType = GSM_EMSSmallPicture; /* Bitmap 8x8 */ + Buffer[0] = 0x0F; /* ID for 8x8 animation */ + } + Length = PHONE_GetBitmapSize(BitmapType,0,0); + + Buffer[1] = Length*Entry->Bitmap->Number + 1; /* Length of rest */ + Buffer[2] = 0x00; /* Position in EMS msg */ + for (j=0;jBitmap->Number;j++) { + PHONE_EncodeBitmap(BitmapType, Buffer+3+j*Length, &Entry->Bitmap->Bitmap[j]); + } + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3+Length*Entry->Bitmap->Number,true,&UsedText,&CopiedText,&CopiedSMSText); + SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-1-Length*Entry->Bitmap->Number] = UsedText; + break; + case SMS_EMSFixedBitmap: + if (Entry->Protected) { + Buffer[0] = 0x17; /* ID for ODI */ + Buffer[1] = 2; /* Length of rest */ + Buffer[2] = 1; /* Number of protected objects */ + Buffer[3] = 1; /* 1=Protected,0=Not protected */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); + } + + if (Entry->Bitmap->Bitmap[0].Width > 16 || Entry->Bitmap->Bitmap[0].Height > 16) { + BitmapType = GSM_EMSBigPicture; /* Bitmap 32x32 */ + Buffer[0] = 0x10; /* ID for EMS bitmap */ + } else { + BitmapType = GSM_EMSMediumPicture; /* Bitmap 16x16 */ + Buffer[0] = 0x11; /* ID for EMS bitmap */ + } + Length = PHONE_GetBitmapSize(BitmapType,0,0); + PHONE_GetBitmapWidthHeight(BitmapType, &Width, &Height); + + Buffer[1] = Length + 1; /* Length of rest */ + Buffer[2] = 0x00; /* Position in EMS msg */ + PHONE_EncodeBitmap(BitmapType,Buffer+3, &Entry->Bitmap->Bitmap[0]); + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3+Length,true,&UsedText,&CopiedText,&CopiedSMSText); + SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-1-Length] = UsedText; + break; + case SMS_EMSVariableBitmapLong: + BitmapType = GSM_EMSVariablePicture; + Width = Entry->Bitmap->Bitmap[0].Width; + Height = Entry->Bitmap->Bitmap[0].Height; + memcpy(&Bitmap,&Entry->Bitmap->Bitmap[0],sizeof(GSM_Bitmap)); + + /* First check if we can use classical format */ + while (1) { + /* Width should be multiply of 8 */ + while (Width % 8 != 0) Width--; + + /* specs */ + if (Width <= 96 && Height <= 128) break; + + Height--; + } + Length = PHONE_GetBitmapSize(BitmapType,Width,Height); + if (Length <= 128) { + if (Entry->Protected) { + Buffer[0] = 0x17; /* ID for ODI */ + Buffer[1] = 2; /* Length of rest */ + Buffer[2] = 1; /* Number of protected objects */ + Buffer[3] = 1; /* 1=Protected,0=Not protected */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); + } + + Buffer[0] = 0x12; /* ID for EMS bitmap */ + Buffer[1] = Length + 3; /* Length of rest */ + Buffer[2] = 0x00; /* Position in EMS msg */ + Buffer[3] = Width/8; /* Bitmap width/8 */ + Buffer[4] = Height; /* Bitmap height */ + + GSM_ResizeBitmap(&Bitmap, &Entry->Bitmap->Bitmap[0], Width, Height); +#ifdef DEBUG + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Bitmap); +#endif + PHONE_EncodeBitmap(BitmapType,Buffer+5, &Bitmap); + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,5+Length,true,&UsedText,&CopiedText,&CopiedSMSText); + SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3-Length] = UsedText; + break; + } + + /* Find free place in first SMS */ + GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); + Used = 0; + Length = FreeBytes - 3; + if (Entry->Protected) Length = Length - 4; + if (Length < 0) Length = 128; + if (Length > 128) Length = 128; + + /* Checking number of SMS */ + FreeBytes = 0; + while (FreeBytes != Width) { + Width2 = 8; + while(1) { + if (FreeBytes+Width2 == Width) break; + + if (PHONE_GetBitmapSize(BitmapType,Width2+8,Height) > Length) break; + + Width2 = Width2 + 8; + } + FreeBytes = FreeBytes + Width2; + Length = 128; + Used ++; + } + dbgprintf("Used SMS: %i\n",Used); + + if (Entry->Protected) { + Buffer[0] = 0x17; /* ID for ODI */ + Buffer[1] = 2; /* Length of rest */ + Buffer[2] = Used+1; /* Number of protected objects */ + Buffer[3] = 1; /* 1=Protected,0=Not protected */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); + } + + /* Save UPI UDH */ + Buffer[0] = 0x13; /* ID for UPI */ + Buffer[1] = 1; /* Length of rest */ + Buffer[2] = Used; /* Number of used parts */ + + /* Find free place in first SMS */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,3,true,&UsedText,&CopiedText,&CopiedSMSText); + GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], &UsedText, &FreeText, &FreeBytes); + Length = FreeBytes - 3; + if (Length < 0) Length = 128; + if (Length > 128) Length = 128; + +#ifdef DEBUG + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Bitmap); +#endif + + /* Saving SMS */ + FreeBytes = 0; + while (FreeBytes != Width) { + Width2 = 8; + while(1) { + if (FreeBytes+Width2 == Width) break; + + if (PHONE_GetBitmapSize(BitmapType,Width2+8,Height) > Length) break; + + Width2 = Width2 + 8; + } + + /* Copying part of bitmap to new structure */ + Bitmap2.Width = Width2; + Bitmap2.Height = Height; + GSM_ClearBitmap(&Bitmap2); + for (x=0;xSMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3-Length] = UsedText; + + FreeBytes = FreeBytes + Width2; + Length = 128; + } + break; + case SMS_EMSVariableBitmap: + if (Entry->Protected) { + Buffer[0] = 0x17; /* ID for ODI */ + Buffer[1] = 2; /* Length of rest */ + Buffer[2] = 1; /* Number of protected objects */ + Buffer[3] = 1; /* 1=Protected,0=Not protected */ + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,4,true,&UsedText,&CopiedText,&CopiedSMSText); + } + + BitmapType = GSM_EMSVariablePicture; + Width = Entry->Bitmap->Bitmap[0].Width; + Height = Entry->Bitmap->Bitmap[0].Height; + + while (1) { + /* Width should be multiply of 8 */ + while (Width % 8 != 0) Width--; + + /* specs */ + if (PHONE_GetBitmapSize(BitmapType,Width,Height) <= 128) break; + + Height--; + } + + Length = PHONE_GetBitmapSize(BitmapType,Width,Height); + + Buffer[0] = 0x12; /* ID for EMS bitmap */ + Buffer[1] = Length + 3; /* Length of rest */ + Buffer[2] = 0x00; /* Position in EMS msg */ + Buffer[3] = Width/8; /* Bitmap width/8 */ + Buffer[4] = Height; /* Bitmap height */ + + GSM_ResizeBitmap(&Bitmap, &Entry->Bitmap->Bitmap[0], Width, Height); +#ifdef DEBUG + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Bitmap); +#endif + PHONE_EncodeBitmap(BitmapType,Buffer+5, &Bitmap); + GSM_AddSMS_Text_UDH(SMS,Coding,Buffer,5+Length,true,&UsedText,&CopiedText,&CopiedSMSText); + SMS->SMS[SMS->Number].UDH.Text[SMS->SMS[SMS->Number].UDH.Length-3-Length] = UsedText; + break; + default: + break; + } + } + + SMS->Number++; + + if (UDHType == UDH_ConcatenatedMessages) { + UDHID = GSM_MakeSMSIDFromTime(); + for (i=0;iNumber;i++) { + SMS->SMS[i].UDH.Text[2+1] = UDHID; + SMS->SMS[i].UDH.Text[3+1] = SMS->Number; + SMS->SMS[i].UDH.Text[4+1] = i+1; + } + } + if (UDHType == UDH_ConcatenatedMessages16bit) { + UDHID = GSM_MakeSMSIDFromTime(); + GSM_GetCurrentDateTime (&Date); + for (i=0;iNumber;i++) { + SMS->SMS[i].UDH.Text[2+1] = Date.Hour; + SMS->SMS[i].UDH.Text[3+1] = UDHID; + SMS->SMS[i].UDH.Text[4+1] = SMS->Number; + SMS->SMS[i].UDH.Text[5+1] = i+1; + } + } + +#ifdef DEBUG + dbgprintf("SMS number is %i\n",SMS->Number); + for (i=0;iNumber;i++) { + dbgprintf("UDH length %i\n",SMS->SMS[i].UDH.Length); + DumpMessage(di.df, SMS->SMS[i].UDH.Text, SMS->SMS[i].UDH.Length); + dbgprintf("SMS length %i\n",UnicodeLength(SMS->SMS[i].Text)*2); + DumpMessage(di.df, SMS->SMS[i].Text, UnicodeLength(SMS->SMS[i].Text)*2); + } +#endif + return GE_NONE; +} + +static void AddEMSText(GSM_SMSMessage *SMS, GSM_EncodeMultiPartSMSInfo *Info, int *Pos, int Len) +{ + int L; + + if (Len==0) return; + + if (Info->Entries[Info->EntriesNum].ID!=SMS_ConcatenatedTextLong && + Info->Entries[Info->EntriesNum].ID!=0) { + (Info->EntriesNum)++; + } + L = UnicodeLength(Info->Entries[Info->EntriesNum].Buffer)*2; + switch (SMS->Coding) { + case GSM_Coding_8bit: +// memcpy(Info->Entries[Info->EntriesNum].Buffer+L,SMS->Text+(*Pos),Len); +// L+=Len; +// (*Pos)+=Len; + break; + case GSM_Coding_Unicode: + case GSM_Coding_Default: + memcpy(Info->Entries[Info->EntriesNum].Buffer+L,SMS->Text+(*Pos)*2,Len*2); + L+=Len*2; + break; + } + (*Pos)+=Len; + Info->Entries[Info->EntriesNum].Buffer[L] = 0; + Info->Entries[Info->EntriesNum].Buffer[L+1] = 0; + Info->Entries[Info->EntriesNum].ID = SMS_ConcatenatedTextLong; +} + +bool GSM_DecodeEMSMultiPartSMS(GSM_EncodeMultiPartSMSInfo *Info, + GSM_MultiSMSMessage *SMS) +{ + int i, w, Pos, z, UPI = 1, width, height; + bool RetVal = false, NewPicture = true; + GSM_Phone_Bitmap_Types BitmapType; + GSM_Bitmap Bitmap,Bitmap2; + + for (i=0;iEntries[i].Buffer[0] = 0; + Info->Entries[i].Buffer[1] = 0; + Info->Entries[i].ID = 0; + } + + for (i=0;iNumber;i++) { + Pos = 0; + w = 1; + while (1) { + if (w >= SMS->SMS[i].UDH.Length) break; + switch(SMS->SMS[i].UDH.Text[w]) { + case 0x00: + dbgprintf("UDH part - linked SMS with 8 bit ID\n"); + break; + case 0x08: + dbgprintf("UDH part - linked SMS with 16 bit ID\n"); + break; +// case 0x0A: +// dbgprintf("UDH part - EMS text formatting\n"); +// break; + case 0x0B: + dbgprintf("UDH part - default EMS sound\n"); + if (SMS->SMS[i].UDH.Text[w+2] > Pos) { + z = Pos; + AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].UDH.Text[w+2]-z); + } + if (Info->Entries[Info->EntriesNum].ID != 0) (Info->EntriesNum)++; + Info->Entries[Info->EntriesNum].Number = SMS->SMS[i].UDH.Text[w+3]; + Info->Entries[Info->EntriesNum].ID = SMS_EMSPredefinedSound; + RetVal = true; + break; +// case 0x0C: +// dbgprintf("UDH part - EMS sound\n"); +// break; + case 0x0D: + dbgprintf("UDH part - default EMS animation\n"); + if (SMS->SMS[i].UDH.Text[w+2] > Pos) { + z = Pos; + AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].UDH.Text[w+2]-z); + } + if (Info->Entries[Info->EntriesNum].ID != 0) (Info->EntriesNum)++; + Info->Entries[Info->EntriesNum].Number = SMS->SMS[i].UDH.Text[w+3]; + Info->Entries[Info->EntriesNum].ID = SMS_EMSPredefinedAnimation; + RetVal = true; + break; + case 0x0E: + case 0x0F: + if (SMS->SMS[i].UDH.Text[w] == 0x0E) { + dbgprintf("UDH part - EMS 16x16 animation\n"); + BitmapType = GSM_EMSMediumPicture; + } else { + dbgprintf("UDH part - EMS 8x8 animation\n"); + BitmapType = GSM_EMSSmallPicture; + } + dbgprintf("Position - %i\n",SMS->SMS[i].UDH.Text[w+2]); + if (SMS->SMS[i].UDH.Text[w+2] > Pos) { + z = Pos; + AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].UDH.Text[w+2]-z); + } + (Info->EntriesNum)++; + Info->Entries[Info->EntriesNum].ID = SMS_EMSAnimation; + Info->Entries[Info->EntriesNum].Bitmap->Number = 0; + for (z=0;z<((SMS->SMS[i].UDH.Text[w+1]-1)/PHONE_GetBitmapSize(BitmapType,0,0));z++) { + Info->Entries[Info->EntriesNum].Bitmap->Bitmap[z].Type = GSM_PictureImage; + PHONE_DecodeBitmap(BitmapType, SMS->SMS[i].UDH.Text+w+3+PHONE_GetBitmapSize(BitmapType,0,0)*z, &Info->Entries[Info->EntriesNum].Bitmap->Bitmap[z]); + Info->Entries[Info->EntriesNum].Bitmap->Number++; + } + RetVal = true; + break; + case 0x10: + case 0x11: + if (SMS->SMS[i].UDH.Text[w] == 0x10) { + dbgprintf("UDH part - EMS 32x32 picture\n"); + BitmapType = GSM_EMSBigPicture; + } else { + dbgprintf("UDH part - EMS 16x16 picture\n"); + BitmapType = GSM_EMSMediumPicture; + } + dbgprintf("Position - %i\n",SMS->SMS[i].UDH.Text[w+2]); + if (SMS->SMS[i].UDH.Text[w+2] > Pos) { + z = Pos; + AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].UDH.Text[w+2]-z); + } + if (Info->Entries[Info->EntriesNum].ID != 0) (Info->EntriesNum)++; + PHONE_DecodeBitmap(BitmapType, SMS->SMS[i].UDH.Text+w+3, &Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0]); + Info->Entries[Info->EntriesNum].Bitmap->Number = 1; + Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Text[0] = 0; + Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Text[1] = 0; + Info->Entries[Info->EntriesNum].ID = SMS_EMSFixedBitmap; + RetVal = true; + break; + case 0x12: + dbgprintf("UDH part - EMS variable width bitmap\n"); + if (SMS->SMS[i].UDH.Text[w+2] > Pos) { + z = Pos; + AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].UDH.Text[w+2]-z); + } + if (NewPicture) { + (Info->EntriesNum)++; + Info->Entries[Info->EntriesNum].Bitmap->Number = 0; + Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Width = 0; + Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Height = 0; + } + Bitmap.Width = SMS->SMS[i].UDH.Text[w+3]*8; + Bitmap.Height = SMS->SMS[i].UDH.Text[w+4]; + if (NewPicture) { + Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Width = Bitmap.Width; + Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Height = Bitmap.Height; + PHONE_DecodeBitmap(GSM_EMSVariablePicture, SMS->SMS[i].UDH.Text+w+5, &Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0]); + } else { + PHONE_DecodeBitmap(GSM_EMSVariablePicture, SMS->SMS[i].UDH.Text+w+5, &Bitmap); + memcpy(&Bitmap2,&Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0],sizeof(GSM_Bitmap)); + Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Width = Bitmap.Width+Bitmap2.Width; + Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Height = Bitmap2.Height; + for (width=0;widthEntries[Info->EntriesNum].Bitmap->Bitmap[0],width,height); + } else { + GSM_ClearPointBitmap(&Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0],width,height); + } + } + } + for (width=0;widthEntries[Info->EntriesNum].Bitmap->Bitmap[0],width+Bitmap2.Width,height); + } else { + GSM_ClearPointBitmap(&Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0],width+Bitmap2.Width,height); + } + } + } + } + if (UPI == 1) { + Info->Entries[Info->EntriesNum].Bitmap->Number = 1; + Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Text[0] = 0; + Info->Entries[Info->EntriesNum].Bitmap->Bitmap[0].Text[1] = 0; + Info->Entries[Info->EntriesNum].ID = SMS_EMSVariableBitmap; + RetVal = true; + NewPicture = true; + dbgprintf("New variable picture\n"); + } else { + NewPicture = false; + UPI--; + } + break; + case 0x13: + dbgprintf("UDH part - UPI\n"); + dbgprintf("Value %i\n",SMS->SMS[i].UDH.Text[w+2]); + UPI = SMS->SMS[i].UDH.Text[w+2]; + break; + case 0x17: + dbgprintf("UDH part - Object Distribution Indicator (Media Rights Protecting) ignored now\n"); + break; + default: + dbgprintf("UDH part - block %02x\n",SMS->SMS[i].UDH.Text[w]); + Info->Unknown = true; + } + w=w+SMS->SMS[i].UDH.Text[w+1]+2; + } + AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].Length-Pos); + RetVal = true; + } + if (RetVal) (Info->EntriesNum)++; + return RetVal; +} + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/common/service/sms/gsmems.h b/common/service/sms/gsmems.h new file mode 100644 index 000000000..a1a72a486 --- /dev/null +++ b/common/service/sms/gsmems.h @@ -0,0 +1,19 @@ + +#ifndef __gsm_ems_h +#define __gsm_ems_h + +#include "../../gsmcomon.h" +#include "gsmmulti.h" + +GSM_Error GSM_EncodeEMSMultiPartSMS(GSM_EncodeMultiPartSMSInfo *Info, + GSM_MultiSMSMessage *SMS, + GSM_UDH UDHType); + +bool GSM_DecodeEMSMultiPartSMS(GSM_EncodeMultiPartSMSInfo *Info, + GSM_MultiSMSMessage *SMS); + +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/common/service/sms/gsmmulti.c b/common/service/sms/gsmmulti.c new file mode 100644 index 000000000..7d6b5151c --- /dev/null +++ b/common/service/sms/gsmmulti.c @@ -0,0 +1,929 @@ + +#include +#include +#include + +#include "../../gsmcomon.h" +#include "../../misc/coding/coding.h" +#include "../gsmcal.h" +#include "../gsmpbk.h" +#include "../gsmlogo.h" +#include "../gsmring.h" +#include "../gsmwap.h" +#include "../gsmnet.h" +#include "gsmsms.h" +#include "gsmmulti.h" +#include "gsmems.h" + +/* ----------------- Splitting SMS into parts ------------------------------ */ + +unsigned char GSM_MakeSMSIDFromTime() +{ + GSM_DateTime Date; + unsigned char retval; + + GSM_GetCurrentDateTime (&Date); + retval = Date.Second; + switch (Date.Minute/10) { + case 2: case 7: retval = retval + 60; break; + case 4: case 8: retval = retval + 120; break; + case 9: case 5: case 0: retval = retval + 180; break; + } + retval += Date.Minute/10; + return retval; +} + +void GSM_Find_Free_Used_SMS2(GSM_Coding_Type Coding,GSM_SMSMessage SMS, int *UsedText, int *FreeText, int *FreeBytes) +{ + int UsedBytes; + + switch (Coding) { + case GSM_Coding_Default: + FindDefaultAlphabetLen(SMS.Text,&UsedBytes,UsedText,500); + UsedBytes = *UsedText * 7 / 8; + if (UsedBytes * 8 / 7 != *UsedText) UsedBytes++; + *FreeBytes = GSM_MAX_8BIT_SMS_LENGTH - SMS.UDH.Length - UsedBytes; + *FreeText = (GSM_MAX_8BIT_SMS_LENGTH - SMS.UDH.Length) * 8 / 7 - *UsedText; + break; + case GSM_Coding_Unicode: + *UsedText = UnicodeLength(SMS.Text); + UsedBytes = *UsedText * 2; + *FreeBytes = GSM_MAX_8BIT_SMS_LENGTH - SMS.UDH.Length - UsedBytes; + *FreeText = *FreeBytes / 2; + break; + case GSM_Coding_8bit: + *UsedText = UsedBytes = SMS.Length; + *FreeBytes = GSM_MAX_8BIT_SMS_LENGTH - SMS.UDH.Length - UsedBytes; + *FreeText = *FreeBytes; + break; + } + dbgprintf("UDH len %i, UsedBytes %i, FreeText %i, UsedText %i, FreeBytes %i\n",SMS.UDH.Length,UsedBytes,*FreeText,*UsedText,*FreeBytes); +} + +GSM_Error GSM_AddSMS_Text_UDH(GSM_MultiSMSMessage *SMS, + GSM_Coding_Type Coding, + char *Buffer, + int BufferLen, + bool UDH, + int *UsedText, + int *CopiedText, + int *CopiedSMSText) +{ + int FreeText,FreeBytes,Copy,i,j; + + dbgprintf("Checking used\n"); + GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], UsedText, &FreeText, &FreeBytes); + + if (UDH) { + dbgprintf("Adding UDH\n"); + if (FreeBytes - BufferLen <= 0) { + dbgprintf("Going to the new SMS\n"); + SMS->Number++; + GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], UsedText, &FreeText, &FreeBytes); + } + if (SMS->SMS[SMS->Number].UDH.Length == 0) { + SMS->SMS[SMS->Number].UDH.Length = 1; + SMS->SMS[SMS->Number].UDH.Text[0] = 0x00; + } + memcpy(SMS->SMS[SMS->Number].UDH.Text+SMS->SMS[SMS->Number].UDH.Length,Buffer,BufferLen); + SMS->SMS[SMS->Number].UDH.Length += BufferLen; + SMS->SMS[SMS->Number].UDH.Text[0] += BufferLen; + SMS->SMS[SMS->Number].UDH.Type = UDH_UserUDH; + dbgprintf("UDH added %i\n",BufferLen); + } else { + dbgprintf("Adding text\n"); + if (FreeText == 0) { + dbgprintf("Going to the new SMS\n"); + SMS->Number++; + GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], UsedText, &FreeText, &FreeBytes); + } + + Copy = FreeText; + dbgprintf("copy %i\n",Copy); + if (BufferLen < Copy) Copy = BufferLen; + dbgprintf("copy %i\n",Copy); + + switch (Coding) { + case GSM_Coding_Default: + FindDefaultAlphabetLen(Buffer,&i,&j,FreeText); + dbgprintf("def length %i %i\n",i,j); + SMS->SMS[SMS->Number].Text[UnicodeLength(SMS->SMS[SMS->Number].Text)*2+i*2] = 0; + SMS->SMS[SMS->Number].Text[UnicodeLength(SMS->SMS[SMS->Number].Text)*2+i*2+1] = 0; + memcpy(SMS->SMS[SMS->Number].Text+UnicodeLength(SMS->SMS[SMS->Number].Text)*2,Buffer,i*2); + *CopiedText = i; + *CopiedSMSText = j; + SMS->SMS[SMS->Number].Length += i; + break; + case GSM_Coding_Unicode: + SMS->SMS[SMS->Number].Text[UnicodeLength(SMS->SMS[SMS->Number].Text)*2+Copy*2] = 0; + SMS->SMS[SMS->Number].Text[UnicodeLength(SMS->SMS[SMS->Number].Text)*2+Copy*2+1] = 0; + memcpy(SMS->SMS[SMS->Number].Text+UnicodeLength(SMS->SMS[SMS->Number].Text)*2,Buffer,Copy*2); + *CopiedText = *CopiedSMSText = Copy; + SMS->SMS[SMS->Number].Length += Copy; + break; + case GSM_Coding_8bit: + memcpy(SMS->SMS[SMS->Number].Text+SMS->SMS[SMS->Number].Length,Buffer,Copy); + SMS->SMS[SMS->Number].Length += Copy; + *CopiedText = *CopiedSMSText = Copy; + break; + } + dbgprintf("Text added\n"); + } + + dbgprintf("Checking on the end\n"); + GSM_Find_Free_Used_SMS2(Coding,SMS->SMS[SMS->Number], UsedText, &FreeText, &FreeBytes); + + return GE_NONE; +} + +void GSM_MakeMultiPartSMS(GSM_MultiSMSMessage *SMS, + unsigned char *MessageBuffer, + int MessageLength, + GSM_UDH UDHType, + GSM_Coding_Type Coding, + int Class, + unsigned char ReplaceMessage) +{ + int j,Len,UsedText,CopiedText,CopiedSMSText; + unsigned char UDHID; + GSM_DateTime Date; + + Len = 0; + while(1) { + GSM_SetDefaultSMSData(&SMS->SMS[SMS->Number]); + SMS->SMS[SMS->Number].Class = Class; + SMS->SMS[SMS->Number].Coding = Coding; + + SMS->SMS[SMS->Number].UDH.Type = UDHType; + GSM_EncodeUDHHeader(&SMS->SMS[SMS->Number].UDH); + + if (Coding == GSM_Coding_8bit) { + GSM_AddSMS_Text_UDH(SMS,Coding,MessageBuffer+Len,MessageLength - Len,false,&UsedText,&CopiedText,&CopiedSMSText); + } else { + GSM_AddSMS_Text_UDH(SMS,Coding,MessageBuffer+Len*2,MessageLength - Len,false,&UsedText,&CopiedText,&CopiedSMSText); + } + Len += CopiedText; + dbgprintf("%i %i\n",Len,MessageLength); + if (Len == MessageLength) break; + if (SMS->Number == MAX_MULTI_SMS) break; + SMS->Number++; + } + + SMS->Number++; + + UDHID = GSM_MakeSMSIDFromTime(); + GSM_GetCurrentDateTime (&Date); + for (j=0;jNumber;j++) + { + SMS->SMS[j].UDH.Type = UDHType; + SMS->SMS[j].UDH.ID8bit = UDHID; + SMS->SMS[j].UDH.ID16bit = UDHID + 256 * Date.Hour; + SMS->SMS[j].UDH.PartNumber = j+1; + SMS->SMS[j].UDH.AllParts = SMS->Number; + GSM_EncodeUDHHeader(&SMS->SMS[j].UDH); + } + if (SMS->Number == 1) SMS->SMS[0].ReplaceMessage = ReplaceMessage; +} + +/* Calculates number of SMS and number of left chars in SMS */ +void GSM_SMSCounter(int MessageLength, + unsigned char *MessageBuffer, + GSM_UDH UDHType, + GSM_Coding_Type Coding, + int *SMSNum, + int *CharsLeft) +{ + int UsedText,FreeBytes; + GSM_MultiSMSMessage MultiSMS; + + MultiSMS.Number = 0; + GSM_MakeMultiPartSMS(&MultiSMS,MessageBuffer,MessageLength,UDHType,Coding,-1,false); + GSM_Find_Free_Used_SMS2(Coding,MultiSMS.SMS[MultiSMS.Number-1], &UsedText, CharsLeft, &FreeBytes); + *SMSNum = MultiSMS.Number; +} + +/* Nokia Smart Messaging 3.0 */ +static void GSM_EncodeSMS30MultiPartSMS(GSM_EncodeMultiPartSMSInfo *Info, + char *Buffer, int *Length) +{ + int len; + + /*SM version. Here 3.0*/ + Buffer[(*Length)++] = 0x30; + + if (Info->Entries[0].ID == SMS_NokiaProfileLong) { + if (Info->Entries[0].Buffer != NULL) { + if (Info->Entries[0].Buffer[0]!=0x00 || Info->Entries[0].Buffer[1]!=0x00) { + Buffer[(*Length)++] = SM30_PROFILENAME; + Buffer[(*Length)++] = 0x00; + Buffer[(*Length)++] = 2*UnicodeLength(Info->Entries[0].Buffer); + CopyUnicodeString(Buffer+(*Length),Info->Entries[0].Buffer); + *Length = *Length + 2*UnicodeLength(Info->Entries[0].Buffer); + } + } + if (Info->Entries[0].Ringtone != NULL) { + Buffer[(*Length)++] = SM30_RINGTONE; + /* Length for this part later will be changed */ + Buffer[(*Length)++] = 0x01; + Buffer[(*Length)++] = 0x00; + /* Smart Messaging 3.0 says: 16*9=144 bytes, + * but on 3310 4.02 it was possible to save about 196 chars + * (without cutting) */ + len = 196; + Info->Entries[0].RingtoneNotes=GSM_EncodeNokiaRTTLRingtone(*Info->Entries[0].Ringtone,Buffer+(*Length),&len); + Buffer[(*Length)-2] = len / 256; + Buffer[(*Length)-1] = len % 256; + *Length = *Length + len; + } + } + if (Info->Entries[0].Bitmap != NULL) { + if (Info->Entries[0].ID == SMS_NokiaPictureImageLong) { + Buffer[(*Length)++] = SM30_OTA; + } else { + Buffer[(*Length)++] = SM30_SCREENSAVER; + } + Buffer[(*Length)++] = 0x01; + Buffer[(*Length)++] = 0x00; + NOKIA_CopyBitmap(GSM_NokiaPictureImage, &Info->Entries[0].Bitmap->Bitmap[0], Buffer, Length); + if (Info->Entries[0].Bitmap->Bitmap[0].Text[0]!=0 || Info->Entries[0].Bitmap->Bitmap[0].Text[1]!=0) { + if (Info->UnicodeCoding) { + Buffer[(*Length)++] = SM30_UNICODETEXT; + /* Length for text part */ + Buffer[(*Length)++] = 0x00; + Buffer[(*Length)++] = UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text)*2; + memcpy(Buffer+(*Length),Info->Entries[0].Bitmap->Bitmap[0].Text,UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text)*2); + *Length = *Length + UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text)*2; + } else { + /*ID for ISO-8859-1 text*/ + Buffer[(*Length)++] = SM30_ISOTEXT; + Buffer[(*Length)++] = 0x00; + Buffer[(*Length)++] = UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text); + memcpy(Buffer+(*Length),DecodeUnicodeString(Info->Entries[0].Bitmap->Bitmap[0].Text),UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text)); + *Length = *Length +UnicodeLength(Info->Entries[0].Bitmap->Bitmap[0].Text); + } + } + } +} + +GSM_Error GSM_EncodeMultiPartSMS(GSM_EncodeMultiPartSMSInfo *Info, + GSM_MultiSMSMessage *SMS) +{ + unsigned char Buffer[GSM_MAX_SMS_LENGTH*2*MAX_MULTI_SMS]; + unsigned char Buffer2[GSM_MAX_SMS_LENGTH*2*MAX_MULTI_SMS]; + int Length = 0,smslen,i, Class = -1; + GSM_Error error; + GSM_Coding_Type Coding = GSM_Coding_8bit; + GSM_UDH UDH = UDH_NoUDH; + GSM_UDHHeader UDHHeader; + bool EMS = false; + + SMS->Number = 0; + + for (i=0;iEntriesNum;i++) { + switch (Info->Entries[i].ID) { + case SMS_EMSPredefinedAnimation: + case SMS_EMSPredefinedSound: + case SMS_EMSSound10: + case SMS_EMSSound12: + case SMS_EMSSonyEricssonSound: + case SMS_EMSSound10Long: + case SMS_EMSSound12Long: + case SMS_EMSSonyEricssonSoundLong: + case SMS_EMSFixedBitmap: + case SMS_EMSVariableBitmap: + case SMS_EMSAnimation: + case SMS_EMSVariableBitmapLong: + EMS = true; + break; + case SMS_ConcatenatedTextLong: + case SMS_ConcatenatedTextLong16bit: + if (Info->Entries[i].Left || Info->Entries[i].Right || + Info->Entries[i].Center || Info->Entries[i].Large || + Info->Entries[i].Small || Info->Entries[i].Bold || + Info->Entries[i].Italic || Info->Entries[i].Underlined || + Info->Entries[i].Strikethrough) { + EMS = true; + } + default: + break; + } + if (EMS) break; + } + if (EMS) { + error=GSM_EncodeEMSMultiPartSMS(Info,SMS,UDH_NoUDH); + if (error != GE_NONE) return error; + if (SMS->Number != 1) { + SMS->Number = 0; + for (i=0;iEntriesNum;i++) { + if (Info->Entries[i].ID == SMS_ConcatenatedTextLong16bit) { + return GSM_EncodeEMSMultiPartSMS(Info,SMS,UDH_ConcatenatedMessages); + } + } + return GSM_EncodeEMSMultiPartSMS(Info,SMS,UDH_ConcatenatedMessages16bit); + } + return error; + } + if (Info->EntriesNum != 1) return GE_UNKNOWN; + + switch (Info->Entries[0].ID) { + case SMS_MMSIndicatorLong: + Class = 1; + UDH = UDH_MMSIndicatorLong; + GSM_EncodeMMSIndicatorSMSText(Buffer,&Length,*Info->Entries[0].MMSIndicator); + break; + case SMS_NokiaRingtoneLong: + case SMS_NokiaRingtone: + UDH = UDH_NokiaRingtone; + Class = 1; + /* 7 = length of UDH_NokiaRingtone UDH header */ + Length = GSM_MAX_8BIT_SMS_LENGTH-7; + Info->Entries[0].RingtoneNotes = GSM_EncodeNokiaRTTLRingtone(*Info->Entries[0].Ringtone,Buffer,&Length); + if (Info->Entries[0].ID == SMS_NokiaRingtone) break; + if (Info->Entries[0].RingtoneNotes != Info->Entries[0].Ringtone->NoteTone.NrCommands) { + UDH = UDH_NokiaRingtoneLong; + Length = (GSM_MAX_8BIT_SMS_LENGTH-12)*3; + Info->Entries[0].RingtoneNotes = GSM_EncodeNokiaRTTLRingtone(*Info->Entries[0].Ringtone,Buffer,&Length); + } + break; + case SMS_NokiaOperatorLogoLong: + if (Info->Entries[0].Bitmap->Bitmap[0].Width > 72 || Info->Entries[0].Bitmap->Bitmap[0].Height > 14) { + UDH = UDH_NokiaOperatorLogoLong; + Class = 1; + NOKIA_EncodeNetworkCode(Buffer, Info->Entries[0].Bitmap->Bitmap[0].NetworkCode); + Length = Length + 3; + NOKIA_CopyBitmap(GSM_Nokia7110OperatorLogo, &Info->Entries[0].Bitmap->Bitmap[0], Buffer, &Length); + break; + } + case SMS_NokiaOperatorLogo: + UDH = UDH_NokiaOperatorLogo; + Class = 1; + NOKIA_EncodeNetworkCode(Buffer, Info->Entries[0].Bitmap->Bitmap[0].NetworkCode); + Length = Length + 3; + NOKIA_CopyBitmap(GSM_NokiaOperatorLogo, &Info->Entries[0].Bitmap->Bitmap[0], Buffer, &Length); + break; + case SMS_NokiaCallerLogo: + UDH = UDH_NokiaCallerLogo; + Class = 1; + NOKIA_CopyBitmap(GSM_NokiaCallerLogo, &Info->Entries[0].Bitmap->Bitmap[0], Buffer, &Length); + break; + case SMS_NokiaProfileLong: + case SMS_NokiaPictureImageLong: + case SMS_NokiaScreenSaverLong: + Class = 1; + UDH = UDH_NokiaProfileLong; + GSM_EncodeSMS30MultiPartSMS(Info,Buffer,&Length); + break; + case SMS_NokiaWAPBookmarkLong: + Class = 1; + NOKIA_EncodeWAPBookmarkSMSText(Buffer,&Length,Info->Entries[0].Bookmark); + /* 7 = length of UDH_NokiaWAP UDH header */ + if (Length>(GSM_MAX_8BIT_SMS_LENGTH-7)) { + UDH=UDH_NokiaWAPLong; + } else { + UDH=UDH_NokiaWAP; + } + break; + case SMS_NokiaWAPSettingsLong: + Class = 1; + UDH = UDH_NokiaWAPLong; + NOKIA_EncodeWAPMMSSettingsSMSText(Buffer,&Length,Info->Entries[0].Settings,false); + break; + case SMS_NokiaMMSSettingsLong: + Class = 1; + UDH = UDH_NokiaWAPLong; + NOKIA_EncodeWAPMMSSettingsSMSText(Buffer,&Length,Info->Entries[0].Settings,true); + break; + case SMS_NokiaVCARD10Long: + GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard10); + /* is 1 SMS ? 8 = length of ..SCKE2 */ + if (Length<=GSM_MAX_SMS_LENGTH-8) { + sprintf(Buffer,"//SCKE2 "); + Length = 8; + GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard10); + } else { + /* FIXME: It wasn't checked */ + UDH = UDH_NokiaPhonebookLong; + } + Coding = GSM_Coding_Default; + memcpy(Buffer2,Buffer,Length); + EncodeUnicode(Buffer,Buffer2,Length); + break; + case SMS_NokiaVCARD21Long: + GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard21); + /* Is 1 SMS ? 12 = length of ..SCKL23F4 */ + if (Length<=GSM_MAX_SMS_LENGTH-12) { + sprintf(Buffer,"//SCKL23F4%c%c",13,10); + Length = 12; + GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard21); + } else { + UDH = UDH_NokiaPhonebookLong; + /* Here can be also 8 bit coding */ + } + Coding = GSM_Coding_Default; + memcpy(Buffer2,Buffer,Length); + EncodeUnicode(Buffer,Buffer2,Length); + break; + case SMS_VCARD10Long: + GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard10); + if (Length>GSM_MAX_SMS_LENGTH) UDH = UDH_ConcatenatedMessages; + Coding = GSM_Coding_Default; + memcpy(Buffer2,Buffer,Length); + EncodeUnicode(Buffer,Buffer2,Length); + break; + case SMS_VCARD21Long: + GSM_EncodeVCARD(Buffer,&Length,Info->Entries[0].Phonebook,true,Nokia_VCard21); + if (Length>GSM_MAX_SMS_LENGTH) UDH = UDH_ConcatenatedMessages; + Coding = GSM_Coding_Default; + memcpy(Buffer2,Buffer,Length); + EncodeUnicode(Buffer,Buffer2,Length); + break; + case SMS_NokiaVCALENDAR10Long: + error=GSM_EncodeVCALENDAR(Buffer,&Length,Info->Entries[0].Calendar,true,Nokia_VCalendar); + if (error != GE_NONE) return error; + /* Is 1 SMS ? 8 = length of ..SCKE4 */ + if (Length<=GSM_MAX_SMS_LENGTH-8) { + sprintf(Buffer,"//SCKE4 "); + Length = 8; + GSM_EncodeVCALENDAR(Buffer,&Length,Info->Entries[0].Calendar,true,Nokia_VCalendar); + } else { + UDH = UDH_NokiaCalendarLong; + /* can be here 8 bit coding ? */ + } + Coding = GSM_Coding_Default; + memcpy(Buffer2,Buffer,Length); + EncodeUnicode(Buffer,Buffer2,Length); + break; + case SMS_NokiaVTODOLong: + error=GSM_EncodeVTODO(Buffer,&Length,Info->Entries[0].ToDo,true,Nokia_VToDo); + if (error != GE_NONE) return error; + UDH = UDH_NokiaCalendarLong; + Coding = GSM_Coding_Default; + memcpy(Buffer2,Buffer,Length); + EncodeUnicode(Buffer,Buffer2,Length); + break; + case SMS_DisableVoice: + case SMS_DisableFax: + case SMS_DisableEmail: + case SMS_EnableVoice: + case SMS_EnableFax: + case SMS_EnableEmail: + case SMS_VoidSMS: + case SMS_Text: + Class = Info->Class; + switch (Info->Entries[0].ID) { + case SMS_DisableVoice : UDH = UDH_DisableVoice; break; + case SMS_DisableFax : UDH = UDH_DisableFax; break; + case SMS_DisableEmail : UDH = UDH_DisableEmail; break; + case SMS_EnableVoice : UDH = UDH_EnableVoice; break; + case SMS_EnableFax : UDH = UDH_EnableFax; break; + case SMS_EnableEmail : UDH = UDH_EnableEmail; break; + case SMS_VoidSMS : UDH = UDH_VoidSMS; break; + case SMS_Text : UDH = UDH_NoUDH; break; + default : break; + } + UDHHeader.Type = UDH; + GSM_EncodeUDHHeader(&UDHHeader); + memcpy(Buffer,Info->Entries[0].Buffer,UnicodeLength(Info->Entries[0].Buffer)*2+2); + if (Info->UnicodeCoding) { + Coding = GSM_Coding_Unicode; + Length = UnicodeLength(Info->Entries[0].Buffer); + if (Length>(140-UDHHeader.Length)/2) Length = (140-UDHHeader.Length)/2; + } else { + Coding = GSM_Coding_Default; + FindDefaultAlphabetLen(Info->Entries[0].Buffer,&Length,&smslen,(GSM_MAX_8BIT_SMS_LENGTH-UDHHeader.Length)*8/7); + } + break; + case SMS_ConcatenatedAutoTextLong: + case SMS_ConcatenatedAutoTextLong16bit: + smslen = UnicodeLength(Info->Entries[0].Buffer); + memcpy(Buffer,Info->Entries[0].Buffer,smslen*2); + EncodeDefault(Buffer2, Buffer, &smslen, true, NULL); + DecodeDefault(Buffer, Buffer2, smslen, true, NULL); +#ifdef DEBUG + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) { + dbgprintf("Info->Entries[0].Buffer:\n"); + DumpMessage(di.df, Info->Entries[0].Buffer, UnicodeLength(Info->Entries[0].Buffer)*2); + dbgprintf("Buffer:\n"); + DumpMessage(di.df, Buffer, UnicodeLength(Buffer)*2); + } +#endif + Info->UnicodeCoding = false; + for (smslen=0;smslen<(int)(UnicodeLength(Info->Entries[0].Buffer)*2);smslen++) { + if (Info->Entries[0].Buffer[smslen] != Buffer[smslen]) { + Info->UnicodeCoding = true; + dbgprintf("Setting to Unicode %i\n",smslen); + break; + } + } + /* No break here - we go to the SMS_ConcatenatedTextLong */ + case SMS_ConcatenatedTextLong: + case SMS_ConcatenatedTextLong16bit: + Class = Info->Class; + memcpy(Buffer,Info->Entries[0].Buffer,UnicodeLength(Info->Entries[0].Buffer)*2+2); + UDH = UDH_NoUDH; + if (Info->UnicodeCoding) { + Coding = GSM_Coding_Unicode; + Length = UnicodeLength(Info->Entries[0].Buffer); + if (Info->Entries[0].ID == SMS_ConcatenatedTextLong16bit || + Info->Entries[0].ID == SMS_ConcatenatedAutoTextLong16bit) { + if (Length>70) UDH=UDH_ConcatenatedMessages16bit; + } else { + if (Length>70) UDH=UDH_ConcatenatedMessages; + } + } else { + Coding = GSM_Coding_Default; + FindDefaultAlphabetLen(Info->Entries[0].Buffer,&Length,&smslen,5000); + if (Info->Entries[0].ID == SMS_ConcatenatedTextLong16bit || + Info->Entries[0].ID == SMS_ConcatenatedAutoTextLong16bit) { + if (smslen>GSM_MAX_SMS_LENGTH) UDH=UDH_ConcatenatedMessages16bit; + } else { + if (smslen>GSM_MAX_SMS_LENGTH) UDH=UDH_ConcatenatedMessages; + } + } + default: + break; + } + GSM_MakeMultiPartSMS(SMS,Buffer,Length,UDH,Coding,Class,Info->ReplaceMessage); + return GE_NONE; +} + +void GSM_ClearMultiPartSMSInfo(GSM_EncodeMultiPartSMSInfo *Info) +{ + int i; + + for (i=0;iEntries[i].Buffer = NULL; + Info->Entries[i].Ringtone = NULL; + Info->Entries[i].Bitmap = NULL; + Info->Entries[i].Phonebook = NULL; + Info->Entries[i].Bookmark = NULL; + Info->Entries[i].Settings = NULL; + Info->Entries[i].Calendar = NULL; + Info->Entries[i].ToDo = NULL; + Info->Entries[i].MMSIndicator = NULL; + Info->Entries[i].Left = false; + Info->Entries[i].Right = false; + Info->Entries[i].Center = false; + Info->Entries[i].Large = false; + Info->Entries[i].Small = false; + Info->Entries[i].Bold = false; + Info->Entries[i].Italic = false; + Info->Entries[i].Underlined = false; + Info->Entries[i].Strikethrough = false; + + Info->Entries[i].Protected = false; + } + Info->Unknown = false; +} + +/* ----------------- Joining SMS from parts -------------------------------- */ + +bool GSM_DecodeMultiPartSMS(GSM_EncodeMultiPartSMSInfo *Info, + GSM_MultiSMSMessage *SMS, + bool ems) +{ + int i, Length = 0; + char Buffer[GSM_MAX_SMS_LENGTH*2*MAX_MULTI_SMS]; + bool emsexist = false; + + Info->EntriesNum = 0; + if (ems) { + emsexist = true; + for (i=0;iNumber;i++) { + if (SMS->SMS[i].UDH.Type != UDH_ConcatenatedMessages && + SMS->SMS[i].UDH.Type != UDH_ConcatenatedMessages16bit && + SMS->SMS[i].UDH.Type != UDH_UserUDH) { + emsexist = false; + break; + } + } + } + + /* EMS decoding */ + if (emsexist) return GSM_DecodeEMSMultiPartSMS(Info,SMS); + + /* Smart Messaging decoding */ + if (SMS->SMS[0].UDH.Type == UDH_NokiaRingtone && SMS->Number == 1) { + if (GSM_DecodeNokiaRTTLRingtone(Info->Entries[0].Ringtone, SMS->SMS[0].Text, SMS->SMS[0].Length)==GE_NONE) { + Info->Entries[0].ID = SMS_NokiaRingtone; + Info->EntriesNum = 1; + return true; + } + } + if (SMS->SMS[0].UDH.Type == UDH_NokiaCallerLogo && SMS->Number == 1) { + PHONE_DecodeBitmap(GSM_NokiaCallerLogo, SMS->SMS[0].Text+4, &Info->Entries[0].Bitmap->Bitmap[0]); +#ifdef DEBUG + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Info->Entries[0].Bitmap->Bitmap[0]); +#endif + Info->Entries[0].ID = SMS_NokiaCallerLogo; + Info->EntriesNum = 1; + return true; + } + if (SMS->SMS[0].UDH.Type == UDH_NokiaOperatorLogo && SMS->Number == 1) { + PHONE_DecodeBitmap(GSM_NokiaOperatorLogo, SMS->SMS[0].Text+7, &Info->Entries[0].Bitmap->Bitmap[0]); + NOKIA_DecodeNetworkCode(SMS->SMS[0].Text, Info->Entries[0].Bitmap->Bitmap[0].NetworkCode); +#ifdef DEBUG + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Info->Entries[0].Bitmap->Bitmap[0]); +#endif + Info->Entries[0].ID = SMS_NokiaOperatorLogo; + Info->EntriesNum = 1; + return true; + } + if (SMS->SMS[0].UDH.Type == UDH_NokiaProfileLong) { + for (i=0;iNumber;i++) { + if (SMS->SMS[i].UDH.Type != UDH_NokiaProfileLong || + SMS->SMS[i].UDH.Text[11] != i+1 || + SMS->SMS[i].UDH.Text[10] != SMS->Number) { + return false; + } + memcpy(Buffer+Length,SMS->SMS[i].Text,SMS->SMS[i].Length); + Length = Length + SMS->SMS[i].Length; + } + Info->EntriesNum = 1; + Info->Entries[0].ID = SMS_NokiaPictureImageLong; + Info->Entries[0].Bitmap->Bitmap[0].Text[0] = 0; + Info->Entries[0].Bitmap->Bitmap[0].Text[1] = 0; + i=1; + while (i!=Length) { + switch (Buffer[i]) { + case SM30_ISOTEXT: + dbgprintf("ISO 8859-2 text\n"); + Info->Unknown = true; + break; + case SM30_UNICODETEXT: + dbgprintf("Unicode text\n"); + memcpy(Info->Entries[0].Bitmap->Bitmap[0].Text,Buffer+i+3,Buffer[i+1]*256+Buffer[i+2]); + Info->Entries[0].Bitmap->Bitmap[0].Text[Buffer[i+1]*256 + Buffer[i+2]] = 0; + Info->Entries[0].Bitmap->Bitmap[0].Text[Buffer[i+1]*256 + Buffer[i+2]+ 1] = 0; + dbgprintf("Unicode Text \"%s\"\n",DecodeUnicodeString(Info->Entries[0].Bitmap->Bitmap[0].Text)); + break; + case SM30_OTA: + dbgprintf("OTA bitmap as Picture Image\n"); + PHONE_DecodeBitmap(GSM_NokiaPictureImage, Buffer + i + 7, &Info->Entries[0].Bitmap->Bitmap[0]); +#ifdef DEBUG + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Info->Entries[0].Bitmap->Bitmap[0]); +#endif + break; + case SM30_RINGTONE: + dbgprintf("RTTL ringtone\n"); + Info->Unknown = true; + break; + case SM30_PROFILENAME: + dbgprintf("Profile Name\n"); + Info->Entries[0].ID = SMS_NokiaProfileLong; + Info->Unknown = true; + break; + case SM30_SCREENSAVER: + dbgprintf("OTA bitmap as Screen Saver\n"); + PHONE_DecodeBitmap(GSM_NokiaPictureImage, Buffer + i + 7, &Info->Entries[0].Bitmap->Bitmap[0]); +#ifdef DEBUG + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&Info->Entries[0].Bitmap->Bitmap[0]); +#endif + Info->Entries[0].ID = SMS_NokiaScreenSaverLong; + break; + } + i = i + Buffer[i+1]*256 + Buffer[i+2] + 3; + dbgprintf("%i %i\n",i,Length); + } + return true; + } + + /* Linked sms */ + if (SMS->SMS[0].UDH.Type == UDH_ConcatenatedMessages || + SMS->SMS[0].UDH.Type == UDH_ConcatenatedMessages16bit) { + Info->EntriesNum = 1; + Info->Entries[0].ID = SMS_ConcatenatedTextLong; + if (SMS->SMS[0].UDH.Type == UDH_ConcatenatedMessages16bit) { + Info->Entries[0].ID = SMS_ConcatenatedTextLong16bit; + } + + for (i=0;iNumber;i++) { + switch (SMS->SMS[i].Coding) { + case GSM_Coding_8bit: + memcpy(Info->Entries[0].Buffer+Length,SMS->SMS[i].Text,SMS->SMS[i].Length); + Length=Length+SMS->SMS[i].Length; + break; + case GSM_Coding_Unicode: + if (Info->Entries[0].ID == SMS_ConcatenatedTextLong) { + Info->Entries[0].ID = SMS_ConcatenatedAutoTextLong; + } + if (Info->Entries[0].ID == SMS_ConcatenatedTextLong16bit) { + Info->Entries[0].ID = SMS_ConcatenatedAutoTextLong16bit; + } + case GSM_Coding_Default: + memcpy(Info->Entries[0].Buffer+Length,SMS->SMS[i].Text,UnicodeLength(SMS->SMS[i].Text)*2); + Length=Length+UnicodeLength(SMS->SMS[i].Text)*2; + break; + } + } + Info->Entries[0].Buffer[Length] = 0; + Info->Entries[0].Buffer[Length+1] = 0; + return true; + } + + return false; +} + +GSM_Error GSM_LinkSMS(GSM_MultiSMSMessage *INPUT[150], GSM_MultiSMSMessage *OUTPUT[150], bool ems) +{ + bool INPUTSorted[150],copyit; + int i,OUTPUTNum,j,z,w; + + for (i=0;i<150;i++) INPUTSorted[i] = false; + + OUTPUTNum = 0; + OUTPUT[0] = NULL; + + if (ems) { + i=0; + while (INPUT[i] != NULL) { + if (INPUT[i]->SMS[0].UDH.Type == UDH_UserUDH) { + w=1; + while (1) { + if (w >= INPUT[i]->SMS[0].UDH.Length) break; + switch(INPUT[i]->SMS[0].UDH.Text[w]) { + case 0x00: + dbgprintf("Adding ID to user UDH - linked SMS with 8 bit ID\n"); + INPUT[i]->SMS[0].UDH.ID8bit = INPUT[i]->SMS[0].UDH.Text[w+2]; + INPUT[i]->SMS[0].UDH.AllParts = INPUT[i]->SMS[0].UDH.Text[w+3]; + INPUT[i]->SMS[0].UDH.PartNumber = INPUT[i]->SMS[0].UDH.Text[w+4]; + break; + case 0x08: + dbgprintf("Adding ID to user UDH - linked SMS with 16 bit ID\n"); + INPUT[i]->SMS[0].UDH.ID16bit = INPUT[i]->SMS[0].UDH.Text[w+2]*256+INPUT[i]->SMS[0].UDH.Text[w+3]; + INPUT[i]->SMS[0].UDH.AllParts = INPUT[i]->SMS[0].UDH.Text[w+4]; + INPUT[i]->SMS[0].UDH.PartNumber = INPUT[i]->SMS[0].UDH.Text[w+5]; + break; + default: + dbgprintf("Block %02x\n",INPUT[i]->SMS[0].UDH.Text[w]); + } + dbgprintf("%i %i %i %i\n", + INPUT[i]->SMS[0].UDH.ID8bit, + INPUT[i]->SMS[0].UDH.ID16bit, + INPUT[i]->SMS[0].UDH.PartNumber, + INPUT[i]->SMS[0].UDH.AllParts); + w=w+INPUT[i]->SMS[0].UDH.Text[w+1]+2; + } + } + i++; + } + } + + i=0; + while (INPUT[i]!=NULL) { + /* If this one SMS was sorted earlier, do not touch */ + if (INPUTSorted[i]) { + i++; + continue; + } + copyit = false; + /* If we have: + * - linked sms returned by phone driver + * - sms without linking + * we copy it to OUTPUT + */ + if (INPUT[i]->Number != 1 || + INPUT[i]->SMS[0].UDH.Type == UDH_NoUDH || + INPUT[i]->SMS[0].UDH.PartNumber == -1) { + copyit = true; + } + /* If we have unknown UDH, we copy it to OUTPUT */ + if (INPUT[i]->SMS[0].UDH.Type == UDH_UserUDH) { + if (!ems) copyit = true; + if (ems && INPUT[i]->SMS[0].UDH.PartNumber == -1) copyit = true; + } + if (copyit) { + OUTPUT[OUTPUTNum] = malloc(sizeof(GSM_MultiSMSMessage)); + if (OUTPUT[OUTPUTNum] == NULL) return GE_MOREMEMORY; + OUTPUT[OUTPUTNum+1] = NULL; + + memcpy(OUTPUT[OUTPUTNum],INPUT[i],sizeof(GSM_MultiSMSMessage)); + INPUTSorted[i]=true; + OUTPUTNum++; + i = 0; + continue; + } + /* We have 1'st part of linked sms. It's single. + * We will try to find other parts + */ + if (INPUT[i]->SMS[0].UDH.PartNumber == 1) { + OUTPUT[OUTPUTNum] = malloc(sizeof(GSM_MultiSMSMessage)); + if (OUTPUT[OUTPUTNum] == NULL) return GE_MOREMEMORY; + OUTPUT[OUTPUTNum+1] = NULL; + + memcpy(&OUTPUT[OUTPUTNum]->SMS[0],&INPUT[i]->SMS[0],sizeof(GSM_SMSMessage)); + OUTPUT[OUTPUTNum]->Number = 1; + INPUTSorted[i] = true; + j = 1; + /* We're searching for other parts in sequence */ + while (j!=INPUT[i]->SMS[0].UDH.AllParts) { + z=0; + while(INPUT[z]!=NULL) { + /* This was sorted earlier or is not single */ + if (INPUTSorted[z] || INPUT[z]->Number != 1) { + z++; + continue; + } + if (ems && INPUT[i]->SMS[0].UDH.Type != UDH_ConcatenatedMessages && + INPUT[i]->SMS[0].UDH.Type != UDH_ConcatenatedMessages16bit && + INPUT[i]->SMS[0].UDH.Type != UDH_UserUDH && + INPUT[z]->SMS[0].UDH.Type != UDH_ConcatenatedMessages && + INPUT[z]->SMS[0].UDH.Type != UDH_ConcatenatedMessages16bit && + INPUT[z]->SMS[0].UDH.Type != UDH_UserUDH) { + if (INPUT[z]->SMS[0].UDH.Type != INPUT[i]->SMS[0].UDH.Type) { + z++; + continue; + } + } + if (!ems && INPUT[z]->SMS[0].UDH.Type != INPUT[i]->SMS[0].UDH.Type) { + z++; + continue; + } + dbgprintf("compare %i %i %i %i %i", + j+1, + INPUT[i]->SMS[0].UDH.ID8bit, + INPUT[i]->SMS[0].UDH.ID16bit, + INPUT[i]->SMS[0].UDH.PartNumber, + INPUT[i]->SMS[0].UDH.AllParts); + dbgprintf(" %i %i %i %i\n", + INPUT[z]->SMS[0].UDH.ID8bit, + INPUT[z]->SMS[0].UDH.ID16bit, + INPUT[z]->SMS[0].UDH.PartNumber, + INPUT[z]->SMS[0].UDH.AllParts); + if (INPUT[z]->SMS[0].UDH.ID8bit != INPUT[i]->SMS[0].UDH.ID8bit || + INPUT[z]->SMS[0].UDH.ID16bit != INPUT[i]->SMS[0].UDH.ID16bit || + INPUT[z]->SMS[0].UDH.AllParts != INPUT[i]->SMS[0].UDH.AllParts || + INPUT[z]->SMS[0].UDH.PartNumber != j+1) { + z++; + continue; + } + /* For SMS_Deliver compare also SMSC and Sender number */ + if (INPUT[z]->SMS[0].PDU == SMS_Deliver && + (strcmp(DecodeUnicodeString(INPUT[z]->SMS[0].SMSC.Number),DecodeUnicodeString(INPUT[i]->SMS[0].SMSC.Number)) || + strcmp(DecodeUnicodeString(INPUT[z]->SMS[0].Number),DecodeUnicodeString(INPUT[i]->SMS[0].Number)))) { + z++; + continue; + } + /* DCT4 Outbox: SMS Deliver. Empty number and SMSC. We compare dates */ + if (INPUT[z]->SMS[0].PDU == SMS_Deliver && + UnicodeLength(INPUT[z]->SMS[0].SMSC.Number)==0 && + UnicodeLength(INPUT[z]->SMS[0].Number)==0 && + (INPUT[z]->SMS[0].DateTime.Day != INPUT[i]->SMS[0].DateTime.Day || + INPUT[z]->SMS[0].DateTime.Month != INPUT[i]->SMS[0].DateTime.Month || + INPUT[z]->SMS[0].DateTime.Year != INPUT[i]->SMS[0].DateTime.Year || + INPUT[z]->SMS[0].DateTime.Hour != INPUT[i]->SMS[0].DateTime.Hour || + INPUT[z]->SMS[0].DateTime.Minute != INPUT[i]->SMS[0].DateTime.Minute || + INPUT[z]->SMS[0].DateTime.Second != INPUT[i]->SMS[0].DateTime.Second)) { + z++; + continue; + } + /* We found correct sms. Copy it */ + memcpy(&OUTPUT[OUTPUTNum]->SMS[j],&INPUT[z]->SMS[0],sizeof(GSM_SMSMessage)); + OUTPUT[OUTPUTNum]->Number++; + INPUTSorted[z]=true; + break; + } + /* Incomplete sequence */ + if (OUTPUT[OUTPUTNum]->Number==j) { + dbgprintf("Incomplete sequence\n"); + break; + } + j++; + } + OUTPUTNum++; + i = 0; + continue; + } + /* We have some next linked sms from sequence */ + if (INPUT[i]->SMS[0].UDH.PartNumber > 1) { + j = 0; + while (INPUT[j]!=NULL) { + if (INPUTSorted[j]) { + j++; + continue; + } + /* We have some not unassigned first sms from sequence. + * We can't touch other sms from sequences + */ + if (INPUT[j]->SMS[0].UDH.PartNumber == 1) break; + j++; + } + if (INPUT[j]==NULL) { + OUTPUT[OUTPUTNum] = malloc(sizeof(GSM_MultiSMSMessage)); + if (OUTPUT[OUTPUTNum] == NULL) return GE_MOREMEMORY; + OUTPUT[OUTPUTNum+1] = NULL; + + memcpy(OUTPUT[OUTPUTNum],INPUT[i],sizeof(GSM_MultiSMSMessage)); + INPUTSorted[i]=true; + OUTPUTNum++; + i = 0; + continue; + } else i++; + } + } + return GE_NONE; +} + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/common/service/sms/gsmmulti.h b/common/service/sms/gsmmulti.h new file mode 100644 index 000000000..fbcda4eee --- /dev/null +++ b/common/service/sms/gsmmulti.h @@ -0,0 +1,238 @@ + +#ifndef __gsm_multisms_h +#define __gsm_multisms_h + +#include "../../gsmcomon.h" +#include "../gsmlogo.h" +#include "../gsmcal.h" +#include "../gsmpbk.h" +#include "../gsmwap.h" +#include "../gsmring.h" +#include "gsmsms.h" + +/* ---------------------- multi SMS --------------------------------------- */ + +/* Identifiers for Smart Messaging 3.0 multipart SMS */ + +#define SM30_ISOTEXT 0 /* ISO 8859-1 text */ +#define SM30_UNICODETEXT 1 +#define SM30_OTA 2 +#define SM30_RINGTONE 3 +#define SM30_PROFILENAME 4 +#define SM30_SCREENSAVER 6 + +void GSM_SMSCounter(int MessageLength, + unsigned char *MessageBuffer, + GSM_UDH UDHType, + GSM_Coding_Type Coding, + int *SMSNum, + int *CharsLeft); + +#define MAX_MULTI_SMS 10 + +/** + * Multiple SMS messages, used for Smart Messaging 3.0/EMS. + */ +typedef struct { + /** + * Sender or recipient number. + */ + unsigned char Number; + /** + * Array of SMSes. + */ + GSM_SMSMessage SMS[MAX_MULTI_SMS]; +} GSM_MultiSMSMessage; + +GSM_Error GSM_AddSMS_Text_UDH(GSM_MultiSMSMessage *SMS, + GSM_Coding_Type Coding, + char *Buffer, + int BufferLen, + bool UDH, + int *UsedText, + int *CopiedText, + int *CopiedSMSText); + +void GSM_MakeMultiPartSMS(GSM_MultiSMSMessage *SMS, + unsigned char *MessageBuffer, + int MessageLength, + GSM_UDH UDHType, + GSM_Coding_Type Coding, + int Class, + unsigned char RejectDuplicates); + +void GSM_Find_Free_Used_SMS2(GSM_Coding_Type Coding,GSM_SMSMessage SMS, int *UsedText, int *FreeText, int *FreeBytes); + +unsigned char GSM_MakeSMSIDFromTime(); + +/** + * ID during packing SMS for Smart Messaging 3.0, EMS and other + */ +typedef enum { + /** + * 1 text SMS. + */ + SMS_Text = 1, + /** + * Contacenated SMS, when longer than 1 SMS. + */ + SMS_ConcatenatedTextLong, + /** + * Contacenated SMS, auto Default/Unicode coding. + */ + SMS_ConcatenatedAutoTextLong, + SMS_ConcatenatedTextLong16bit, + SMS_ConcatenatedAutoTextLong16bit, + /** + * Nokia profile = Name, Ringtone, ScreenSaver + */ + SMS_NokiaProfileLong, + /** + * Nokia Picture Image + (text) + */ + SMS_NokiaPictureImageLong, + /** + * Nokia screen saver + (text) + */ + SMS_NokiaScreenSaverLong, + /** + * Nokia ringtone - old SM2.0 format, 1 SMS + */ + SMS_NokiaRingtone, + /** + * Nokia ringtone contacenated, when very long + */ + SMS_NokiaRingtoneLong, + /** + * Nokia 72x14 operator logo, 1 SMS + */ + SMS_NokiaOperatorLogo, + /** + * Nokia 72x14 op logo or 78x21 in 2 SMS + */ + SMS_NokiaOperatorLogoLong, + /** + * Nokia 72x14 caller logo, 1 SMS + */ + SMS_NokiaCallerLogo, + /** + * Nokia WAP bookmark in 1 or 2 SMS + */ + SMS_NokiaWAPBookmarkLong, + /** + * Nokia WAP settings in 2 SMS + */ + SMS_NokiaWAPSettingsLong, + /** + * Nokia MMS settings in 2 SMS + */ + SMS_NokiaMMSSettingsLong, + /** + * Nokia VCARD 1.0 - only name and default number + */ + SMS_NokiaVCARD10Long, + /** + * Nokia VCARD 2.1 - all numbers + text + */ + SMS_NokiaVCARD21Long, + /** + * Nokia VCALENDAR 1.0 - can be in few sms + */ + SMS_NokiaVCALENDAR10Long, + SMS_NokiaVTODOLong, + SMS_VCARD10Long, + SMS_VCARD21Long, + SMS_DisableVoice, + SMS_DisableFax, + SMS_DisableEmail, + SMS_EnableVoice, + SMS_EnableFax, + SMS_EnableEmail, + SMS_VoidSMS, + /** + * IMelody 1.0 + */ + SMS_EMSSound10, + /** + * IMelody 1.2 + */ + SMS_EMSSound12, + /** + * IMelody without header - SonyEricsson extension + */ + SMS_EMSSonyEricssonSound, + /** + * IMelody 1.0 with UPI. + */ + SMS_EMSSound10Long, + /*** + * IMelody 1.2 with UPI. + */ + SMS_EMSSound12Long, + /** + * IMelody without header with UPI. + */ + SMS_EMSSonyEricssonSoundLong, + SMS_EMSPredefinedSound, + SMS_EMSPredefinedAnimation, + SMS_EMSAnimation, + /** + * Fixed bitmap of size 16x16 or 32x32. + */ + SMS_EMSFixedBitmap, + SMS_EMSVariableBitmap, + SMS_EMSVariableBitmapLong, + SMS_MMSIndicatorLong +} EncodeMultiPartSMSID; + +typedef struct { + EncodeMultiPartSMSID ID; + + int Number; + GSM_Ringtone *Ringtone; + GSM_MultiBitmap *Bitmap; + GSM_WAPBookmark *Bookmark; + GSM_WAPSettings *Settings; + GSM_MMSIndicator *MMSIndicator; + GSM_MemoryEntry *Phonebook; + GSM_CalendarEntry *Calendar; + GSM_ToDoEntry *ToDo; + bool Protected; + + unsigned char *Buffer; + bool Left; + bool Right; + bool Center; + bool Large; + bool Small; + bool Bold; + bool Italic; + bool Underlined; + bool Strikethrough; + + /* Return values */ + int RingtoneNotes; +} EncodeMultiPartSMSEntry; + +typedef struct { + /* Input values */ + EncodeMultiPartSMSEntry Entries[MAX_MULTI_SMS]; + int EntriesNum; + bool UnicodeCoding; + int Class; + unsigned char ReplaceMessage; + + bool Unknown; +} GSM_EncodeMultiPartSMSInfo; + +GSM_Error GSM_EncodeMultiPartSMS (GSM_EncodeMultiPartSMSInfo *Info, GSM_MultiSMSMessage *SMS); +bool GSM_DecodeMultiPartSMS (GSM_EncodeMultiPartSMSInfo *Info, GSM_MultiSMSMessage *SMS, bool ems); +void GSM_ClearMultiPartSMSInfo (GSM_EncodeMultiPartSMSInfo *Info); + +GSM_Error GSM_LinkSMS(GSM_MultiSMSMessage *INPUT[200], GSM_MultiSMSMessage *OUTPUT[200], bool ems); + +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/common/service/sms/gsmsms.c b/common/service/sms/gsmsms.c new file mode 100644 index 000000000..d5c1b6b79 --- /dev/null +++ b/common/service/sms/gsmsms.c @@ -0,0 +1,646 @@ + +#include +#include +#include + +#include "../../gsmcomon.h" +#include "../../misc/coding/coding.h" +#include "../gsmcal.h" +#include "../gsmpbk.h" +#include "../gsmlogo.h" +#include "../gsmring.h" +#include "../gsmwap.h" +#include "../gsmnet.h" +#include "gsmsms.h" + +/* User data headers */ +static GSM_UDHHeader UDHHeaders[] = { + /* See GSM 03.40 section 9.2.3.24.1 + * 1 byte 0x00 + * 1 byte 0x03 + * 1 byte 0x01: unique ID for message series + * 1 byte 0x00: how many SMS in sequence + * 1 byte 0x00: number of current SMS in sequence */ + { UDH_ConcatenatedMessages, 0x05, "\x00\x03\x01\x00\x00",2,-1,4,3}, + + /* See GSM 03.40 section 9.2.3.24.2 for voice, fax and email messages */ + { UDH_DisableVoice, 0x04, "\x01\x02\x00\x00",-1,-1,-1,-1}, + { UDH_DisableFax, 0x04, "\x01\x02\x01\x00",-1,-1,-1,-1}, + { UDH_DisableEmail, 0x04, "\x01\x02\x02\x00",-1,-1,-1,-1}, + { UDH_EnableVoice, 0x04, "\x01\x02\x00\x01",-1,-1,-1,-1}, + { UDH_EnableFax, 0x04, "\x01\x02\x01\x01",-1,-1,-1,-1}, + { UDH_EnableEmail, 0x04, "\x01\x02\x02\x01",-1,-1,-1,-1}, + + /* When send such SMS to some phones, they don't display anything, + * only beep and enable vibra/light + */ + { UDH_VoidSMS, 0x08, "\x01\x02\x02\x01\x01\x02\x02\x00",-1,-1,-1,-1}, + + /* Nokia Smart Messaging (short version) UDH + * General format : + * 1 byte 0x05 : IEI application port addressing scheme, 16 bit address + * 1 byte 0x04 : IEI length + * 2 bytes : destination address : high & low byte + * 2 bytes 0x00 0x00 : originator address : high & low byte */ + { UDH_NokiaRingtone, 0x06, "\x05\x04\x15\x81\x00\x00",-1,-1,-1,-1}, + { UDH_NokiaOperatorLogo, 0x06, "\x05\x04\x15\x82\x00\x00",-1,-1,-1,-1}, + { UDH_NokiaCallerLogo, 0x06, "\x05\x04\x15\x83\x00\x00",-1,-1,-1,-1}, + { UDH_NokiaWAP, 0x06, "\x05\x04\xc3\x4f\x00\x00",-1,-1,-1,-1}, + + /* Nokia Smart Messaging (long version) UDH and other + * General format: + * 1 byte 0x05 : IEI application port addressing scheme, 16 bit address + * 1 byte 0x04 : IEI length + * 2 bytes 0x00 0x00 : destination address : high & low byte + * 2 bytes 0x00 0x00 : originator address : high & low byte + * 1 byte 0x00 : SAR + * 1 byte 0x03 : SAR length + * 1 byte : diagram reference number (unique ID for message series) + * 1 byte : number of all SMS + * 1 byte : number of current SMS */ + { UDH_NokiaCalendarLong, 0x0b, "\x05\x04\x00\xe4\x00\x00\x00\x03\xc7\x00\x00",8,-1,10,9}, + { UDH_MMSIndicatorLong, 0x0b, "\x05\x04\x0b\x84\x23\xf0\x00\x03\xe5\x00\x00",8,-1,10,9}, + { UDH_NokiaRingtoneLong, 0x0b, "\x05\x04\x15\x81\x00\x00\x00\x03\x01\x00\x00",8,-1,10,9}, + { UDH_NokiaOperatorLogoLong, 0x0b, "\x05\x04\x15\x82\x00\x00\x00\x03\x02\x00\x00",8,-1,10,9}, + { UDH_NokiaProfileLong, 0x0b, "\x05\x04\x15\x8a\x00\x00\x00\x03\xce\x00\x00",8,-1,10,9}, + { UDH_NokiaPhonebookLong, 0x0b, "\x05\x04\x23\xf4\x00\x00\x00\x03\x01\x00\x00",8,-1,10,9}, + { UDH_NokiaWAPLong, 0x0b, "\x05\x04\xc3\x4f\x00\x00\x00\x03\x7f\x00\x00",8,-1,10,9}, + + { UDH_ConcatenatedMessages16bit,0x06, "\x08\x04\x00\x00\x00\x00",-1,2,5,4}, + + { UDH_NoUDH, 0x00, "",-1,-1,-1,-1} +}; + +/* --------------------------- Unpacking SMS ------------------------------- */ + +/* See GSM 03.40 section 9.2.3.11 */ +static GSM_Error GSM_DecodeSMSDateTime(GSM_DateTime *DT, unsigned char *req) +{ + DT->Year = DecodeWithBCDAlphabet(req[0]); + if (DT->Year<90) DT->Year=DT->Year+2000; else DT->Year=DT->Year+1990; + DT->Month = DecodeWithBCDAlphabet(req[1]); + DT->Day = DecodeWithBCDAlphabet(req[2]); + DT->Hour = DecodeWithBCDAlphabet(req[3]); + DT->Minute = DecodeWithBCDAlphabet(req[4]); + DT->Second = DecodeWithBCDAlphabet(req[5]); + + /* Base for timezone is GMT. It's in quarters */ + DT->Timezone=(10*(req[6]&0x07)+(req[6]>>4))/4; + + if (req[6]&0x08) DT->Timezone = -DT->Timezone; + + dbgprintf("Decoding date & time: "); + dbgprintf("%s %4d/%02d/%02d ", DayOfWeek(DT->Year, DT->Month, DT->Day), + DT->Year, DT->Month, DT->Day); + dbgprintf("%02d:%02d:%02d %02d00\n", DT->Hour, DT->Minute, DT->Second, DT->Timezone); + + return GE_NONE; +} + +void GSM_DecodeUDHHeader(GSM_UDHHeader *UDH) +{ + int i, tmp, w; + bool UDHOK; + + UDH->Type = UDH_UserUDH; + UDH->ID8bit = -1; + UDH->ID16bit = -1; + UDH->PartNumber = -1; + UDH->AllParts = -1; + + i=-1; + while (true) { + i++; + if (UDHHeaders[i].Type==UDH_NoUDH) break; + + tmp=UDHHeaders[i].Length; + /* if length is the same */ + if (tmp==UDH->Text[0]) { + + if (tmp==0x05) tmp=tmp-3;/*three last bytes can be different for such UDH*/ + if (tmp==0x0b) tmp=tmp-3;/*three last bytes can be different for such UDH*/ + if (tmp==0x06 && UDH->Text[1] == 0x08) tmp=tmp-4; + + UDHOK=true; + for (w=0;wText[w+1]) { + UDHOK=false; + break; + } + } + if (UDHOK) { + UDH->Type=UDHHeaders[i].Type; + + if (UDHHeaders[i].ID8bit !=-1) UDH->ID8bit = UDH->Text[UDHHeaders[i].ID8bit+1]; + if (UDHHeaders[i].ID16bit !=-1) UDH->ID16bit = UDH->Text[UDHHeaders[i].ID16bit+1]*256+UDH->Text[UDHHeaders[i].ID16bit+2]; + if (UDHHeaders[i].PartNumber !=-1) UDH->PartNumber = UDH->Text[UDHHeaders[i].PartNumber+1]; + if (UDHHeaders[i].AllParts !=-1) UDH->AllParts = UDH->Text[UDHHeaders[i].AllParts+1]; + break; + } + } + } + +#ifdef DEBUG + dbgprintf("Type of UDH: "); + switch (UDH->Type) { + case UDH_ConcatenatedMessages : dbgprintf("Concatenated (linked) message"); break; + case UDH_ConcatenatedMessages16bit : dbgprintf("Concatenated (linked) message"); break; + case UDH_DisableVoice : dbgprintf("Disables voice indicator"); break; + case UDH_EnableVoice : dbgprintf("Enables voice indicator"); break; + case UDH_DisableFax : dbgprintf("Disables fax indicator"); break; + case UDH_EnableFax : dbgprintf("Enables fax indicator"); break; + case UDH_DisableEmail : dbgprintf("Disables email indicator"); break; + case UDH_EnableEmail : dbgprintf("Enables email indicator"); break; + case UDH_VoidSMS : dbgprintf("Void SMS"); break; + case UDH_NokiaWAP : dbgprintf("Nokia WAP Bookmark"); break; + case UDH_NokiaOperatorLogoLong : dbgprintf("Nokia operator logo"); break; + case UDH_NokiaWAPLong : dbgprintf("Nokia WAP Bookmark or WAP/MMS Settings"); break; + case UDH_NokiaRingtone : dbgprintf("Nokia ringtone"); break; + case UDH_NokiaRingtoneLong : dbgprintf("Nokia ringtone"); break; + case UDH_NokiaOperatorLogo : dbgprintf("Nokia GSM operator logo"); break; + case UDH_NokiaCallerLogo : dbgprintf("Nokia caller logo"); break; + case UDH_NokiaProfileLong : dbgprintf("Nokia profile"); break; + case UDH_NokiaCalendarLong : dbgprintf("Nokia calendar note"); break; + case UDH_NokiaPhonebookLong : dbgprintf("Nokia phonebook entry"); break; + case UDH_UserUDH : dbgprintf("User UDH"); break; + case UDH_MMSIndicatorLong : dbgprintf("MMS indicator"); break; + case UDH_NoUDH: break; + } + if (UDH->ID8bit != -1) dbgprintf(", ID 8 bit %i",UDH->ID8bit); + if (UDH->ID16bit != -1) dbgprintf(", ID 16 bit %i",UDH->ID16bit); + if (UDH->PartNumber != -1 && UDH->AllParts != -1) { + dbgprintf(", part %i of %i",UDH->PartNumber,UDH->AllParts); + } + dbgprintf("\n"); + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, UDH->Text, UDH->Length); +#endif +} + +GSM_Error GSM_DecodeSMSFrameText(GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout) +{ + int off=0; /* off - length of the user data header */ + int w,i,tmp=0; + unsigned char output[161]; + + SMS->UDH.Length = 0; + /* UDH header available */ + if (buffer[Layout.firstbyte] & 64) { + /* Length of UDH header */ + off = (buffer[Layout.Text] + 1); + SMS->UDH.Length = off; + dbgprintf("UDH header available (length %i)\n",off); + + /* Copy UDH header into SMS->UDH */ + for (i = 0; i < off; i++) SMS->UDH.Text[i] = buffer[Layout.Text + i]; + + GSM_DecodeUDHHeader(&SMS->UDH); + } + + /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) and GSM 03.38 section 4 */ + if ((buffer[Layout.TPDCS] & 0xf4) == 0xf4) SMS->Coding=GSM_Coding_8bit; + if ((buffer[Layout.TPDCS] & 0x08) == 0x08) SMS->Coding=GSM_Coding_Unicode; + + switch (SMS->Coding) { + case GSM_Coding_Default: + i = 0; + do { + i+=7; + w=(i-off)%i; + } while (w<0); + SMS->Length=buffer[Layout.TPUDL] - (off*8 + w) / 7; + tmp=GSM_UnpackEightBitsToSeven(w, buffer[Layout.TPUDL]-off, SMS->Length, buffer+(Layout.Text+off), output); + dbgprintf("7 bit SMS, length %i\n",SMS->Length); + DecodeDefault (SMS->Text, output, SMS->Length, true, NULL); + dbgprintf("%s\n",DecodeUnicodeString(SMS->Text)); + break; + case GSM_Coding_8bit: + SMS->Length=buffer[Layout.TPUDL] - off; + memcpy(SMS->Text,buffer+(Layout.Text+off),SMS->Length); +#ifdef DEBUG + dbgprintf("8 bit SMS, length %i\n",SMS->Length); + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, SMS->Text, SMS->Length); +#endif + break; + case GSM_Coding_Unicode: + SMS->Length=(buffer[Layout.TPUDL] - off) / 2; + DecodeUnicodeSpecialNOKIAChars(SMS->Text,buffer+(Layout.Text+off), SMS->Length); +#ifdef DEBUG + dbgprintf("Unicode SMS, length %i\n",SMS->Length); + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df,buffer+(Layout.Text+off), SMS->Length*2); + dbgprintf("%s\n",DecodeUnicodeString(SMS->Text)); +#endif + break; + } + + return GE_NONE; +} + +GSM_Error GSM_DecodeSMSFrameStatusReportData(GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout) +{ + SMS->DeliveryStatus = buffer[Layout.TPStatus]; + + if (buffer[Layout.TPStatus] < 0x03) { + EncodeUnicode(SMS->Text,"Delivered",9); + SMS->Length = 9; + } else if (buffer[Layout.TPStatus] & 0x40) { + EncodeUnicode(SMS->Text,"Failed",6); + SMS->Length = 6; + } else if (buffer[Layout.TPStatus] & 0x20) { + EncodeUnicode(SMS->Text,"Pending",7); + SMS->Length = 7; + } else { + EncodeUnicode(SMS->Text,"Unknown",7); + SMS->Length = 7; + } + +#ifdef DEBUG + /* See GSM 03.40 section 9.2.3.15 (TP-Status) */ + if (buffer[Layout.TPStatus] & 0x40) { + if (buffer[Layout.TPStatus] & 0x20) { + /* 0x60, 0x61, ... */ + dbgprintf("Temporary error, SC is not making any more transfer attempts\n"); + } else { + /* 0x40, 0x41, ... */ + dbgprintf("Permanent error, SC is not making any more transfer attempts\n"); + } + } else if (buffer[Layout.TPStatus] & 0x20) { + /* 0x20, 0x21, ... */ + dbgprintf("Temporary error, SC still trying to transfer SM\n"); + } + switch (buffer[Layout.TPStatus]) { + case 0x00: dbgprintf("SM received by the SME"); break; + case 0x01: dbgprintf("SM forwarded by the SC to the SME but the SC is unable to confirm delivery");break; + case 0x02: dbgprintf("SM replaced by the SC"); break; + case 0x20: dbgprintf("Congestion"); break; + case 0x21: dbgprintf("SME busy"); break; + case 0x22: dbgprintf("No response from SME"); break; + case 0x23: dbgprintf("Service rejected"); break; + case 0x24: dbgprintf("Quality of service not available"); break; + case 0x25: dbgprintf("Error in SME"); break; + case 0x40: dbgprintf("Remote procedure error"); break; + case 0x41: dbgprintf("Incompatibile destination"); break; + case 0x42: dbgprintf("Connection rejected by SME"); break; + case 0x43: dbgprintf("Not obtainable"); break; + case 0x44: dbgprintf("Quality of service not available"); break; + case 0x45: dbgprintf("No internetworking available"); break; + case 0x46: dbgprintf("SM Validity Period Expired"); break; + case 0x47: dbgprintf("SM deleted by originating SME"); break; + case 0x48: dbgprintf("SM Deleted by SC Administration"); break; + case 0x49: dbgprintf("SM does not exist"); break; + case 0x60: dbgprintf("Congestion"); break; + case 0x61: dbgprintf("SME busy"); break; + case 0x62: dbgprintf("No response from SME"); break; + case 0x63: dbgprintf("Service rejected"); break; + case 0x64: dbgprintf("Quality of service not available"); break; + case 0x65: dbgprintf("Error in SME"); break; + default : dbgprintf("Reserved/Specific to SC: %x",buffer[Layout.TPStatus]); break; + } + dbgprintf("\n"); +#endif /* DEBUG */ + + return GE_NONE; +} + +GSM_Error GSM_DecodeSMSFrame(GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout) +{ +#ifdef DEBUG + if (Layout.firstbyte == 255) { + dbgprintf("ERROR: firstbyte in SMS layout not set\n"); + return GE_UNKNOWN; + } + if (Layout.TPDCS != 255) dbgprintf("TPDCS : %02x %i\n",buffer[Layout.TPDCS] ,buffer[Layout.TPDCS]); + if (Layout.TPMR != 255) dbgprintf("TPMR : %02x %i\n",buffer[Layout.TPMR] ,buffer[Layout.TPMR]); + if (Layout.TPPID != 255) dbgprintf("TPPID : %02x %i\n",buffer[Layout.TPPID] ,buffer[Layout.TPPID]); + if (Layout.TPUDL != 255) dbgprintf("TPUDL : %02x %i\n",buffer[Layout.TPUDL] ,buffer[Layout.TPUDL]); + if (Layout.firstbyte != 255) dbgprintf("FirstByte : %02x %i\n",buffer[Layout.firstbyte],buffer[Layout.firstbyte]); + if (Layout.Text != 255) dbgprintf("Text : %02x %i\n",buffer[Layout.Text] ,buffer[Layout.Text]); +#endif + + SMS->UDH.Type = UDH_NoUDH; + SMS->Coding = GSM_Coding_Default; + SMS->Length = 0; + SMS->SMSC.Number[0] = 0; + SMS->SMSC.Number[1] = 0; + SMS->Number[0] = 0; + SMS->Number[1] = 0; + SMS->Name[0] = 0; + SMS->Name[1] = 0; + SMS->ReplyViaSameSMSC = false; + if (Layout.SMSCNumber!=255) { + GSM_UnpackSemiOctetNumber(SMS->SMSC.Number,buffer+Layout.SMSCNumber,false); + dbgprintf("SMS center number : \"%s\"\n",DecodeUnicodeString(SMS->SMSC.Number)); + } + if ((buffer[Layout.firstbyte] & 0x80)!=0) SMS->ReplyViaSameSMSC=true; +#ifdef DEBUG + if (SMS->ReplyViaSameSMSC) dbgprintf("SMS centre set for reply\n"); +#endif + if (Layout.Number!=255) { + GSM_UnpackSemiOctetNumber(SMS->Number,buffer+Layout.Number,true); + dbgprintf("Remote number : \"%s\"\n",DecodeUnicodeString(SMS->Number)); + } + if (Layout.Text != 255 && Layout.TPDCS!=255 && Layout.TPUDL!=255) { + GSM_DecodeSMSFrameText(SMS, buffer, Layout); + } + if (Layout.DateTime != 255) { + GSM_DecodeSMSDateTime(&SMS->DateTime,buffer+(Layout.DateTime)); + } + if (Layout.SMSCTime != 255 && Layout.TPStatus != 255) { + /* See GSM 03.40 section 9.2.3.11 (TP-Service-Centre-Time-Stamp) */ + dbgprintf("SMSC response date: "); + GSM_DecodeSMSDateTime(&SMS->SMSCTime, buffer+(Layout.SMSCTime)); + GSM_DecodeSMSFrameStatusReportData(SMS,buffer,Layout); + } + SMS->Class = -1; + if (Layout.TPDCS != 255) { + if ((buffer[Layout.TPDCS] & 0xF3)==0xF0) SMS->Class = 0; + if ((buffer[Layout.TPDCS] & 0xF3)==0xF1) SMS->Class = 1; + if ((buffer[Layout.TPDCS] & 0xF3)==0xF2) SMS->Class = 2; + if ((buffer[Layout.TPDCS] & 0xF3)==0xF3) SMS->Class = 3; + } + dbgprintf("SMS class: %i\n",SMS->Class); + SMS->MessageReference = 0; + if (Layout.TPMR != 255) { + SMS->MessageReference = buffer[Layout.TPMR]; + } + SMS->ReplaceMessage = 0; + if (Layout.TPPID != 255) { + if (buffer[Layout.TPPID] > 0x40 && buffer[Layout.TPPID] < 0x48) { + SMS->ReplaceMessage = buffer[Layout.TPPID] - 0x40; + } + } + SMS->RejectDuplicates = false; + if ((buffer[Layout.firstbyte] & 0x04)==0x04) SMS->RejectDuplicates = true; + + return GE_NONE; +} + +/* ----------------------------- Packing SMS ------------------------------- */ + +/* See GSM 03.40 section 9.2.3.11 */ +static GSM_Error GSM_EncodeSMSDateTime(GSM_DateTime *DT, unsigned char *req) +{ + int Year; + + dbgprintf("Encoding SMS datetime: %02i/%02i/%04i %02i:%02i:%02i\n", + DT->Day,DT->Month,DT->Year,DT->Hour,DT->Minute,DT->Second); + + /* We need to have only two last digits of year */ + if (DT->Year>1900) + { + if (DT->Year<2000) Year = DT->Year-1900; + else Year = DT->Year-2000; + } else Year = DT->Year; + + req[0]=EncodeWithBCDAlphabet(Year); + req[1]=EncodeWithBCDAlphabet(DT->Month); + req[2]=EncodeWithBCDAlphabet(DT->Day); + req[3]=EncodeWithBCDAlphabet(DT->Hour); + req[4]=EncodeWithBCDAlphabet(DT->Minute); + req[5]=EncodeWithBCDAlphabet(DT->Second); + + /* FIXME: do it */ + req[6]=0; /* TimeZone = +-0 */ + + return GE_NONE; +} + +static int GSM_EncodeSMSFrameText(GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout) +{ + int off = 0; /* off - length of the user data header */ + int size = 0, size2 = 0, w,p; + char buff[200]; + + if (SMS->UDH.Type!=UDH_NoUDH) { + buffer[Layout.firstbyte] |= 0x40; /* GSM 03.40 section 9.2.3.23 (TP-User-Data-Header-Indicator) */ + off = 1 + SMS->UDH.Text[0]; /* off - length of the user data header */ + memcpy(buffer+Layout.Text, SMS->UDH.Text, off); /* we copy the udh */ +#ifdef DEBUG + dbgprintf("UDH, length %i\n",off); + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, SMS->UDH.Text, off); +#endif + } + switch (SMS->Coding) { + case GSM_Coding_8bit: + /* the mask for the 8-bit data */ + /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) + * and GSM 03.38 section 4 */ + buffer[Layout.TPDCS] |= 0xf4; + memcpy(buffer+(Layout.Text+off), SMS->Text, SMS->Length); + size2 = size = SMS->Length+off; +#ifdef DEBUG + dbgprintf("8 bit SMS, length %i\n",SMS->Length); + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df,SMS->Text,SMS->Length); +#endif + break; + case GSM_Coding_Default: + p = 0; + do { + p+=7; + w=(p-off)%p; + } while (w<0); + p = UnicodeLength(SMS->Text); + EncodeDefault(buff, SMS->Text, &p, true, NULL); + size = GSM_PackSevenBitsToEight(w, buff, buffer+(Layout.Text+off), p); + size += off; + size2 = (off*8 + w) / 7 + p; + dbgprintf("7 bit SMS, length %i, %i\n",size,size2); + dbgprintf("%s\n",DecodeUnicodeString(SMS->Text)); + if (size > GSM_MAX_8BIT_SMS_LENGTH) { + size = 0; size2 = 0; + } + break; + case GSM_Coding_Unicode: + /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) + * and GSM 03.38 section 4 */ + buffer[Layout.TPDCS] |= 0x08; + EncodeUnicodeSpecialNOKIAChars(buffer+(Layout.Text+off), SMS->Text, UnicodeLength(SMS->Text)); + size=size2=UnicodeLength(buffer+(Layout.Text+off))*2+off; +#ifdef DEBUG + dbgprintf("Unicode SMS, length %i\n",(size2-off)/2); + if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df,buffer+(Layout.Text+off), size2-off); + dbgprintf("%s\n",DecodeUnicodeString(buffer+(Layout.Text+off))); +#endif + break; + } + + /* SMS->Length is: + - integer representation of the number od octets within the user data + when UD is coded using 8bit data + - the sum of the number of septets in UDH including any padding + and number of septets in UD in other case */ + /* GSM 03.40 section 9.2.3.16 (TP-User-Data-Length) */ + buffer[Layout.TPUDL] = size2; + return size; +} + +GSM_Error GSM_EncodeSMSFrame(GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout, int *length, bool clear) +{ + int i; + + if (clear) { + /* Cleaning up to the SMS text */ + for (i=0;iPDU) { + case SMS_Submit: + buffer[Layout.firstbyte] |= 0x01; + break; + /* SMS_Status_Report when Submit sms should have delivery report */ + /* We DON'T CREATE FRAME FOR REAL SMS_STATUS_REPORT */ + case SMS_Status_Report: + buffer[Layout.firstbyte] |= 0x01; + /* GSM 03.40 section 9.2.3.5 (TP-Status-Raport-Request) */ + /* Mask when want delivery report from SMSC */ + buffer[Layout.firstbyte] |= 0x20; + break; + case SMS_Deliver: + buffer[Layout.firstbyte] |= 0x00; + } + + /* GSM 03.40 section 9.2.3.17 (TP-Reply-Path) */ + if (SMS->ReplyViaSameSMSC) buffer[Layout.firstbyte] |= 0x80; + + if (Layout.Number!=255) { + buffer[Layout.Number] = GSM_PackSemiOctetNumber(SMS->Number,buffer+(Layout.Number+1),true); + dbgprintf("Recipient number \"%s\"\n",DecodeUnicodeString(SMS->Number)); + } + if (Layout.SMSCNumber!=255) { + buffer[Layout.SMSCNumber]=GSM_PackSemiOctetNumber(SMS->SMSC.Number,buffer+(Layout.SMSCNumber+1), false); + dbgprintf("SMSC number \"%s\"\n",DecodeUnicodeString(SMS->SMSC.Number)); + } + + /* Message Class*/ + /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) and GSM 03.38 section 4 */ + if (Layout.TPDCS != 255) { + if (SMS->Class>=0 && SMS->Class<5) buffer[Layout.TPDCS] |= (240+SMS->Class); + } + + if (Layout.TPVP != 255) { + /* GSM 03.40 section 9.2.3.3 (TP-Validity-Period-Format) */ + /* Bits 4 and 3: 10. TP-VP field present and integer represent (relative) */ + buffer[Layout.firstbyte] |= 0x10; + buffer[Layout.TPVP]=((unsigned char)SMS->SMSC.Validity.Relative); + dbgprintf("SMS validity %02x\n",SMS->SMSC.Validity.Relative); + } + + if (Layout.DateTime != 255) { + GSM_EncodeSMSDateTime(&SMS->DateTime, buffer+Layout.DateTime); + } + + if (Layout.TPMR != 255) { + buffer[Layout.TPMR] = SMS->MessageReference; + } + + if (SMS->RejectDuplicates) { + /* GSM 03.40 section 9.2.3.25 (TP Reject Duplicates) */ + buffer[Layout.firstbyte] |= 0x04; + } + + if (Layout.TPPID != 255) { + buffer[Layout.TPPID] = 0; + if (SMS->ReplaceMessage > 0 && SMS->ReplaceMessage < 8) { + buffer[Layout.TPPID] = 0x40 + SMS->ReplaceMessage; + } + } + + /* size is the length of the data in octets including udh */ + *length=GSM_EncodeSMSFrameText(SMS,buffer,Layout); +// if (*length == 0) return GE_UNKNOWN; + *length += Layout.Text; + + return GE_NONE; +} + +/* ----------------- Some help functions ----------------------------------- */ + +void GSM_SetDefaultSMSData(GSM_SMSMessage *SMS) +{ + SMS->Class = -1; + SMS->SMSC.Location = 1; + SMS->SMSC.Validity.VPF = GSM_RelativeFormat; + SMS->SMSC.Validity.Relative = GSMV_Max_Time; + SMS->ReplyViaSameSMSC = false; + SMS->UDH.Type = UDH_NoUDH; + SMS->UDH.Length = 0; + SMS->UDH.Text[0] = 0; + SMS->UDH.ID8bit = 0; + SMS->UDH.ID16bit = 0; + SMS->UDH.PartNumber = 0; + SMS->UDH.AllParts = 0; + SMS->Coding = GSM_Coding_Default; + SMS->Text[0] = 0; + SMS->Text[1] = 0; + SMS->PDU = SMS_Submit; + SMS->RejectDuplicates = false; + SMS->MessageReference = 0; + SMS->ReplaceMessage = 0; + SMS->Length = 0; + + /* This part is required to save SMS */ + SMS->State = GSM_UnSent; + SMS->Location = 0; + SMS->Folder = 0x02; /*Outbox*/ + GSM_GetCurrentDateTime (&SMS->DateTime); + SMS->Name[0] = 0; + SMS->Name[1] = 0; +} + +/** + * GSM 03.40 section 9.2.3.24 + */ +void GSM_EncodeUDHHeader(GSM_UDHHeader *UDH) +{ + int i=0; + + switch (UDH->Type) { + case UDH_NoUDH: + UDH->Length = 0; + break; + case UDH_UserUDH: + UDH->Length = UDH->Text[0] + 1; + break; + default: + while (true) { + if (UDHHeaders[i].Type==UDH_NoUDH) { + dbgprintf("Not supported UDH type\n"); + break; + } + if (UDHHeaders[i].Type==UDH->Type) { + /* UDH Length */ + UDH->Text[0] = UDHHeaders[i].Length; + memcpy(UDH->Text+1, UDHHeaders[i].Text, UDHHeaders[i].Length); + UDH->Length = UDH->Text[0] + 1; + + if (UDHHeaders[i].ID8bit != -1) { + UDH->Text[UDHHeaders[i].ID8bit+1] = UDH->ID8bit % 256; + } else { + UDH->ID8bit = -1; + } + if (UDHHeaders[i].ID16bit != -1) { + UDH->Text[UDHHeaders[i].ID16bit+1] = UDH->ID16bit / 256; + UDH->Text[UDHHeaders[i].ID16bit+2] = UDH->ID16bit % 256; + } else { + UDH->ID16bit = -1; + } + if (UDHHeaders[i].PartNumber != -1) { + UDH->Text[UDHHeaders[i].PartNumber+1] = UDH->PartNumber; + } else { + UDH->PartNumber = -1; + } + if (UDHHeaders[i].AllParts != -1) { + UDH->Text[UDHHeaders[i].AllParts+1] = UDH->AllParts; + } else { + UDH->AllParts = -1; + } + break; + } + i++; + } + } +} + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/common/service/gsmsms.h b/common/service/sms/gsmsms.h similarity index 63% rename from common/service/gsmsms.h rename to common/service/sms/gsmsms.h index e46af4978..c5f5c1305 100644 --- a/common/service/gsmsms.h +++ b/common/service/sms/gsmsms.h @@ -2,12 +2,12 @@ #ifndef __gsm_sms_h #define __gsm_sms_h -#include "../gsmcomon.h" -#include "gsmlogo.h" -#include "gsmcal.h" -#include "gsmpbk.h" -#include "gsmwap.h" -#include "gsmring.h" +#include "../../gsmcomon.h" +#include "../gsmlogo.h" +#include "../gsmcal.h" +#include "../gsmpbk.h" +#include "../gsmwap.h" +#include "../gsmring.h" /* --------------------- Some general definitions ------------------------- */ @@ -18,7 +18,7 @@ /* -------------------- Cell Broadcast ------------------------------------ */ /** - * Define datatype for Cell Broadcast message. + * Structure for Cell Broadcast message. */ typedef struct { /** @@ -46,7 +46,7 @@ typedef struct { */ int SIMUsed; /** - * Number of all possible messafes on SIM. + * Number of all possible messages on SIM. */ int SIMSize; /** @@ -436,7 +436,7 @@ void GSM_SetDefaultSMSData(GSM_SMSMessage *SMS); /* ---------------------- SMS folders ------------------------------------- */ /** - * Maximum number of SMS folders. + * Number of possible SMS folders. */ #define GSM_MAX_SMS_FOLDERS 24 /** @@ -476,222 +476,7 @@ typedef struct { unsigned char Number; } GSM_SMSFolders; -/* ---------------------- multi SMS --------------------------------------- */ - -/* Identifiers for Smart Messaging 3.0 multipart SMS */ - -#define SM30_ISOTEXT 0 /* ISO 8859-1 text */ -#define SM30_UNICODETEXT 1 -#define SM30_OTA 2 -#define SM30_RINGTONE 3 -#define SM30_PROFILENAME 4 -#define SM30_SCREENSAVER 6 - -void GSM_SMSCounter(int MessageLength, - unsigned char *MessageBuffer, - GSM_UDH UDHType, - GSM_Coding_Type Coding, - int *SMSNum, - int *CharsLeft); - -#define MAX_MULTI_SMS 10 - -/** - * Multiple SMS messages, used for Smart Messaging 3.0/EMS. - */ -typedef struct { - /** - * Sender or recipient number. - */ - unsigned char Number; - /** - * Array of SMSes. - */ - GSM_SMSMessage SMS[MAX_MULTI_SMS]; -} GSM_MultiSMSMessage; - -GSM_Error GSM_AddSMS_Text_UDH(GSM_MultiSMSMessage *SMS, - GSM_Coding_Type Coding, - char *Buffer, - int BufferLen, - bool UDH, - int *UsedText, - int *CopiedText, - int *CopiedSMSText); - -void GSM_MakeMultiPartSMS(GSM_MultiSMSMessage *SMS, - unsigned char *MessageBuffer, - int MessageLength, - GSM_UDH UDHType, - GSM_Coding_Type Coding, - int Class, - unsigned char RejectDuplicates); - -/** - * ID during packing SMS for Smart Messaging 3.0, EMS and other - */ -typedef enum { - /** - * 1 text SMS. - */ - SMS_Text = 1, - /** - * Contacenated SMS, when longer than 1 SMS. - */ - SMS_ConcatenatedTextLong, - /** - * Contacenated SMS, auto Default/Unicode coding. - */ - SMS_ConcatenatedAutoTextLong, - SMS_ConcatenatedTextLong16bit, - SMS_ConcatenatedAutoTextLong16bit, - /** - * Nokia profile = Name, Ringtone, ScreenSaver - */ - SMS_NokiaProfileLong, - /** - * Nokia Picture Image + (text) - */ - SMS_NokiaPictureImageLong, - /** - * Nokia screen saver + (text) - */ - SMS_NokiaScreenSaverLong, - /** - * Nokia ringtone - old SM2.0 format, 1 SMS - */ - SMS_NokiaRingtone, - /** - * Nokia ringtone contacenated, when very long - */ - SMS_NokiaRingtoneLong, - /** - * Nokia 72x14 operator logo, 1 SMS - */ - SMS_NokiaOperatorLogo, - /** - * Nokia 72x14 op logo or 78x21 in 2 SMS - */ - SMS_NokiaOperatorLogoLong, - /** - * Nokia 72x14 caller logo, 1 SMS - */ - SMS_NokiaCallerLogo, - /** - * Nokia WAP bookmark in 1 or 2 SMS - */ - SMS_NokiaWAPBookmarkLong, - /** - * Nokia WAP settings in 2 SMS - */ - SMS_NokiaWAPSettingsLong, - /** - * Nokia MMS settings in 2 SMS - */ - SMS_NokiaMMSSettingsLong, - /** - * Nokia VCARD 1.0 - only name and default number - */ - SMS_NokiaVCARD10Long, - /** - * Nokia VCARD 2.1 - all numbers + text - */ - SMS_NokiaVCARD21Long, - /** - * Nokia VCALENDAR 1.0 - can be in few sms - */ - SMS_NokiaVCALENDAR10Long, - SMS_NokiaVTODOLong, - SMS_VCARD10Long, - SMS_VCARD21Long, - SMS_DisableVoice, - SMS_DisableFax, - SMS_DisableEmail, - SMS_EnableVoice, - SMS_EnableFax, - SMS_EnableEmail, - SMS_VoidSMS, - /** - * IMelody 1.0 - */ - SMS_EMSSound10, - /** - * IMelody 1.2 - */ - SMS_EMSSound12, - /** - * IMelody without header - SonyEricsson extension - */ - SMS_EMSSonyEricssonSound, - /** - * IMelody 1.0 with UPI. - */ - SMS_EMSSound10Long, - /*** - * IMelody 1.2 with UPI. - */ - SMS_EMSSound12Long, - /** - * IMelody without header with UPI. - */ - SMS_EMSSonyEricssonSoundLong, - SMS_EMSPredefinedSound, - SMS_EMSPredefinedAnimation, - SMS_EMSAnimation, - /** - * Fixed bitmap of size 16x16 or 32x32. - */ - SMS_EMSFixedBitmap, - SMS_EMSVariableBitmap, - SMS_EMSVariableBitmapLong, - SMS_MMSIndicatorLong -} EncodeMultiPartSMSID; - -typedef struct { - EncodeMultiPartSMSID ID; - - int Number; - GSM_Ringtone *Ringtone; - GSM_MultiBitmap *Bitmap; - GSM_WAPBookmark *Bookmark; - GSM_WAPSettings *Settings; - GSM_MMSIndicator *MMSIndicator; - GSM_MemoryEntry *Phonebook; - GSM_CalendarEntry *Calendar; - GSM_ToDoEntry *ToDo; - bool Protected; - - unsigned char *Buffer; - bool Left; - bool Right; - bool Center; - bool Large; - bool Small; - bool Bold; - bool Italic; - bool Underlined; - bool Strikethrough; - - /* Return values */ - int RingtoneNotes; -} EncodeMultiPartSMSEntry; - -typedef struct { - /* Input values */ - EncodeMultiPartSMSEntry Entries[MAX_MULTI_SMS]; - int EntriesNum; - bool UnicodeCoding; - int Class; - unsigned char ReplaceMessage; -} GSM_EncodeMultiPartSMSInfo; - -GSM_Error GSM_EncodeMultiPartSMS (GSM_EncodeMultiPartSMSInfo *Info, GSM_MultiSMSMessage *SMS); -bool GSM_DecodeMultiPartSMS (GSM_EncodeMultiPartSMSInfo *Info, GSM_MultiSMSMessage *SMS); -void GSM_ClearMultiPartSMSInfo (GSM_EncodeMultiPartSMSInfo *Info); - -GSM_Error GSM_SortSMS(GSM_MultiSMSMessage *INPUT[200], GSM_MultiSMSMessage *OUTPUT[200]); - -#endif /* __gsm_sms_h */ +#endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: diff --git a/copying b/copying index c02bd2311..5642cc87a 100644 --- a/copying +++ b/copying @@ -1,4 +1,11 @@ +Version 0.90.7 has canceled possibility of getting LGPL up to explaining +all possible issues. + +Marcin Wiacek +07.12.2003 +------------------------------------------------------------------------------- + After long developing GSM source in Gammu I decided to change license of it. Starting from 0.89.1 version project has two licenses. The idea is simple: @@ -54,6 +61,9 @@ In this place in the future will be put info about projects, which can use Gammu under LGPL after compiling it with enabled ENABLE_LGPL compiler directive (for example after "./configure --enable-lgpl"). +Please note, that this license is not given for 3 party tools available +in source tarball in other directory + Marcin Wiacek 21.11.2003 ------------------------------------------------------------------------------- diff --git a/docs/docs/locale/gammu_cs.txt b/docs/docs/locale/gammu_cs.txt dissimilarity index 80% index c6fbe75c84150de7e6bfae76e529f705eeabff32..fc22f4afb564682aebd17bc2658500d572487dec 100644 GIT binary patch delta 7426 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 A6#xJL delta 10341 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 Q0N=0YM!sUlO;gtY0(!TFI{*Lx diff --git a/docs/docs/locale/gammu_de.txt b/docs/docs/locale/gammu_de.txt dissimilarity index 82% index dc092e7a62bb2293fb515a706ed7e6f2f3010327..d25b2c725e6cbd4e075d65d58441cf727912ae68 100644 GIT binary patch delta 10845 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 ZJn=!&PG7Zd&x^s52vc%A{|S~7{~zW#OTqvE literal 69900 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 I?@{Uh4~lj;x&QzG diff --git a/docs/docs/locale/gammu_pl.txt b/docs/docs/locale/gammu_pl.txt dissimilarity index 79% index 0943eea019a55e4dde7af159486f42b22a367c68..013b34292893546a6c2e5f9ea335060b73a7934d 100644 GIT binary patch delta 6717 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 Fe*x>9eGLEr diff --git a/gammu.spec b/gammu.spec index 0516d0523..dc8f04a3f 100644 --- a/gammu.spec +++ b/gammu.spec @@ -1,4 +1,4 @@ -%define ver 0.90.0 +%define ver 0.90.7 %define name gammu %define bluetooth 1 %define relnum 1 diff --git a/gammu/bcc6.mak/gammu.bpf b/gammu/bcc6.mak/gammu.bpf index 539b4d661..22f437802 100644 --- a/gammu/bcc6.mak/gammu.bpf +++ b/gammu/bcc6.mak/gammu.bpf @@ -27,8 +27,10 @@ USEUNIT("..\..\common\service\gsmnet.c"); USEUNIT("..\..\common\service\gsmpbk.c"); USEUNIT("..\..\common\service\gsmmisc.c"); USEUNIT("..\..\common\service\gsmring.c"); -USEUNIT("..\..\common\service\gsmsms.c"); USEUNIT("..\..\common\service\gsmwap.c"); +USEUNIT("..\..\common\service\sms\gsmsms.c"); +USEUNIT("..\..\common\service\sms\gsmmulti.c"); +USEUNIT("..\..\common\service\sms\gsmems.c"); USEUNIT("..\..\common\service\backup\gsmback.c"); USEUNIT("..\..\common\service\backup\backtext.c"); USEUNIT("..\..\common\service\backup\backldif.c"); diff --git a/gammu/bcc6.mak/gammu.bpr b/gammu/bcc6.mak/gammu.bpr index 907b02481..988ee431d 100644 --- a/gammu/bcc6.mak/gammu.bpr +++ b/gammu/bcc6.mak/gammu.bpr @@ -13,14 +13,14 @@ Output\gsmback.obj Output\gsmcal.obj Output\backldif.obj Output\backlmb.obj Output\backvcs.obj Output\backvcf.obj Output\backtext.obj Output\backics.obj Output\gsmlogo.obj Output\gsmnet.obj - Output\gsmpbk.obj Output\gsmring.obj Output\gsmsms.obj Output\sonyeric.obj - Output\gsmwap.obj Output\gsmmisc.obj Output\gsmcomon.obj - Output\gsmstate.obj Output\n6110.obj Output\n6510.obj Output\n3650.obj - Output\dct4func.obj Output\n7110.obj Output\n9210.obj Output\dct3func.obj - Output\nauto.obj Output\nfunc.obj Output\nfuncold.obj Output\alcatel.obj - Output\obexgen.obj Output\mroutgen.obj Output\pfunc.obj Output\atgen.obj - Output\siemens.obj Output\irda.obj Output\bluetoth.obj Output\ser_w32.obj - Output\devfunc.obj"/> + Output\gsmpbk.obj Output\gsmring.obj Output\gsmsms.obj Output\gsmems.obj + Output\gsmmulti.obj Output\sonyeric.obj Output\gsmwap.obj + Output\gsmmisc.obj Output\gsmcomon.obj Output\gsmstate.obj + Output\n6110.obj Output\n6510.obj Output\n3650.obj Output\dct4func.obj + Output\n7110.obj Output\n9210.obj Output\dct3func.obj Output\nauto.obj + Output\nfunc.obj Output\nfuncold.obj Output\alcatel.obj Output\obexgen.obj + Output\mroutgen.obj Output\pfunc.obj Output\atgen.obj Output\siemens.obj + Output\irda.obj Output\bluetoth.obj Output\ser_w32.obj Output\devfunc.obj"/> @@ -33,7 +33,7 @@ ibsmp.bpi bdertl.bpi vcldbx.bpi qrpt.bpi teeui.bpi teedb.bpi tee.bpi dss.bpi teeqr.bpi ibxpress.bpi dsnap.bpi vclie.bpi inetdb.bpi inet.bpi nmfast.bpi webdsnap.bpi bcbie.bpi dclocx.bpi bcb2kaxserver.bpi"/> - + @@ -43,24 +43,25 @@ - - + + + -I..\..\common\service\sms -I..\..\common\misc\coding + -I..\..\common\phone\symbian -I..\..\common\device\serial -I..\smsd + -I..\..\common\phone -I..\depend -I..\..\common\protocol\alcatel + -I..\..\common\device\bluetoth -I..\..\common\phone\nokia + -I..\..\common\service\backup -I..\depend\dct3trac + -I..\..\common\phone\alcatel -I..\..\common\protocol\symbian + -I..\..\common\phone\nokia\dct4 -I..\..\common\phone\nokia\dct3 + -I..\..\common\device\irda -I..\..\common -I..\..\common\service + -I..\..\common\protocol\nokia -I..\..\common\misc -I..\..\common\phone\at + -I..\..\common\protocol\at -I$(BCB)\include -I$(BCB)\include\mfc + -I$(BCB)\include\atl"/> @@ -111,7 +112,9 @@ - + + + @@ -161,23 +164,23 @@ CodePage=1252 [Version Info Keys] CompanyName=http://www.mwiacek.com FileDescription=Gammu - manager for cellular modems and phones -FileVersion=0,90,0,0 +FileVersion=0,90,7,0 InternalName=Gammu LegalCopyright=Copyright © 2002-2003 Marcin Wiacek LegalTrademarks= OriginalFilename=gammu.exe ProductName=Gammu (GNU All Mobile Management Utilities) -ProductVersion=0,90,0,0 +ProductVersion=0,90,7,0 Comments= [HistoryLists\hlIncludePath] Count=2 -Item0=..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..\..\common\phone\symbian;..\..\common\protocol\symbian;..;..\..\common\protocol\obex;..\..\common\phone\obex;..\..\common\device;..\smsd;..\depend;..\..\common\device\serial;..\..\common\protocol\alcatel;..\..\common\phone\alcatel;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common\device\bluetoth;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\include;$(BCB)\include\mfc;$(BCB)\include\atl +Item0=..\..\common\service\sms;..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..\..\common\phone\symbian;..\..\common\protocol\symbian;..;..\..\common\protocol\obex;..\..\common\phone\obex;..\..\common\device;..\smsd;..\depend;..\..\common\device\serial;..\..\common\protocol\alcatel;..\..\common\phone\alcatel;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common\device\bluetoth;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\include;$(BCB)\include\mfc;$(BCB)\include\atl Item1=..\..\common\phone\symbian;..\..\common\protocol\symbian;..\;..;..\..\common\protocol\obex;..\..\common\phone\obex;..\..\common\device;..\smsd;..\depend;..\..\common\device\serial;..\..\common\protocol\alcatel;..\..\common\phone\alcatel;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common\device\bluetoth;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\include;$(BCB)\include\mfc;$(BCB)\include\atl [HistoryLists\hlLibraryPath] Count=2 -Item0=..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..\..\common\phone\symbian;..\..\common\protocol\symbian;..;..\..\common\device;..\..\common\protocol\obex;..\..\common\phone\obex;..\smsd;..\depend;..\..\common\phone\alcatel;..\..\common\protocol\alcatel;..\..\common\device\serial;..\..\common\device\bluetoth;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\lib;$(RELEASELIBPATH);$(BCB)\lib\psdk +Item0=..\..\common\service\sms;..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..\..\common\phone\symbian;..\..\common\protocol\symbian;..;..\..\common\device;..\..\common\protocol\obex;..\..\common\phone\obex;..\smsd;..\depend;..\..\common\phone\alcatel;..\..\common\protocol\alcatel;..\..\common\device\serial;..\..\common\device\bluetoth;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\lib;$(RELEASELIBPATH);$(BCB)\lib\psdk Item1=..\..\common\phone\symbian;..\..\common\protocol\symbian;..\;..;..\..\common\device;..\..\common\protocol\obex;..\..\common\phone\obex;..\smsd;..\depend;..\..\common\phone\alcatel;..\..\common\protocol\alcatel;..\..\common\device\serial;..\..\common\device\bluetoth;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\lib;$(RELEASELIBPATH);$(BCB)\lib\psdk [HistoryLists\hlDebugSourcePath] diff --git a/gammu/bcc6.mak/gammu.bpr.in b/gammu/bcc6.mak/gammu.bpr.in index 614497f3b..23a8b36b3 100644 --- a/gammu/bcc6.mak/gammu.bpr.in +++ b/gammu/bcc6.mak/gammu.bpr.in @@ -13,14 +13,14 @@ Output\gsmback.obj Output\gsmcal.obj Output\backldif.obj Output\backlmb.obj Output\backvcs.obj Output\backvcf.obj Output\backtext.obj Output\backics.obj Output\gsmlogo.obj Output\gsmnet.obj - Output\gsmpbk.obj Output\gsmring.obj Output\gsmsms.obj Output\sonyeric.obj - Output\gsmwap.obj Output\gsmmisc.obj Output\gsmcomon.obj - Output\gsmstate.obj Output\n6110.obj Output\n6510.obj Output\n3650.obj - Output\dct4func.obj Output\n7110.obj Output\n9210.obj Output\dct3func.obj - Output\nauto.obj Output\nfunc.obj Output\nfuncold.obj Output\alcatel.obj - Output\obexgen.obj Output\mroutgen.obj Output\pfunc.obj Output\atgen.obj - Output\siemens.obj Output\irda.obj Output\bluetoth.obj Output\ser_w32.obj - Output\devfunc.obj"/> + Output\gsmpbk.obj Output\gsmring.obj Output\gsmsms.obj Output\gsmems.obj + Output\gsmmulti.obj Output\sonyeric.obj Output\gsmwap.obj + Output\gsmmisc.obj Output\gsmcomon.obj Output\gsmstate.obj + Output\n6110.obj Output\n6510.obj Output\n3650.obj Output\dct4func.obj + Output\n7110.obj Output\n9210.obj Output\dct3func.obj Output\nauto.obj + Output\nfunc.obj Output\nfuncold.obj Output\alcatel.obj Output\obexgen.obj + Output\mroutgen.obj Output\pfunc.obj Output\atgen.obj Output\siemens.obj + Output\irda.obj Output\bluetoth.obj Output\ser_w32.obj Output\devfunc.obj"/> @@ -33,7 +33,7 @@ ibsmp.bpi bdertl.bpi vcldbx.bpi qrpt.bpi teeui.bpi teedb.bpi tee.bpi dss.bpi teeqr.bpi ibxpress.bpi dsnap.bpi vclie.bpi inetdb.bpi inet.bpi nmfast.bpi webdsnap.bpi bcbie.bpi dclocx.bpi bcb2kaxserver.bpi"/> - + @@ -43,24 +43,25 @@ - - + + + -I..\..\common\service\sms -I..\..\common\misc\coding + -I..\..\common\phone\symbian -I..\..\common\device\serial -I..\smsd + -I..\..\common\phone -I..\depend -I..\..\common\protocol\alcatel + -I..\..\common\device\bluetoth -I..\..\common\phone\nokia + -I..\..\common\service\backup -I..\depend\dct3trac + -I..\..\common\phone\alcatel -I..\..\common\protocol\symbian + -I..\..\common\phone\nokia\dct4 -I..\..\common\phone\nokia\dct3 + -I..\..\common\device\irda -I..\..\common -I..\..\common\service + -I..\..\common\protocol\nokia -I..\..\common\misc -I..\..\common\phone\at + -I..\..\common\protocol\at -I$(BCB)\include -I$(BCB)\include\mfc + -I$(BCB)\include\atl"/> @@ -111,7 +112,9 @@ - + + + @@ -172,12 +175,12 @@ Comments= [HistoryLists\hlIncludePath] Count=2 -Item0=..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..\..\common\phone\symbian;..\..\common\protocol\symbian;..;..\..\common\protocol\obex;..\..\common\phone\obex;..\..\common\device;..\smsd;..\depend;..\..\common\device\serial;..\..\common\protocol\alcatel;..\..\common\phone\alcatel;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common\device\bluetoth;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\include;$(BCB)\include\mfc;$(BCB)\include\atl +Item0=..\..\common\service\sms;..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..\..\common\phone\symbian;..\..\common\protocol\symbian;..;..\..\common\protocol\obex;..\..\common\phone\obex;..\..\common\device;..\smsd;..\depend;..\..\common\device\serial;..\..\common\protocol\alcatel;..\..\common\phone\alcatel;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common\device\bluetoth;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\include;$(BCB)\include\mfc;$(BCB)\include\atl Item1=..\..\common\phone\symbian;..\..\common\protocol\symbian;..\;..;..\..\common\protocol\obex;..\..\common\phone\obex;..\..\common\device;..\smsd;..\depend;..\..\common\device\serial;..\..\common\protocol\alcatel;..\..\common\phone\alcatel;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common\device\bluetoth;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\include;$(BCB)\include\mfc;$(BCB)\include\atl [HistoryLists\hlLibraryPath] Count=2 -Item0=..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..\..\common\phone\symbian;..\..\common\protocol\symbian;..;..\..\common\device;..\..\common\protocol\obex;..\..\common\phone\obex;..\smsd;..\depend;..\..\common\phone\alcatel;..\..\common\protocol\alcatel;..\..\common\device\serial;..\..\common\device\bluetoth;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\lib;$(RELEASELIBPATH);$(BCB)\lib\psdk +Item0=..\..\common\service\sms;..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..\..\common\phone\symbian;..\..\common\protocol\symbian;..;..\..\common\device;..\..\common\protocol\obex;..\..\common\phone\obex;..\smsd;..\depend;..\..\common\phone\alcatel;..\..\common\protocol\alcatel;..\..\common\device\serial;..\..\common\device\bluetoth;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\lib;$(RELEASELIBPATH);$(BCB)\lib\psdk Item1=..\..\common\phone\symbian;..\..\common\protocol\symbian;..\;..;..\..\common\device;..\..\common\protocol\obex;..\..\common\phone\obex;..\smsd;..\depend;..\..\common\phone\alcatel;..\..\common\protocol\alcatel;..\..\common\device\serial;..\..\common\device\bluetoth;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\lib;$(RELEASELIBPATH);$(BCB)\lib\psdk [HistoryLists\hlDebugSourcePath] diff --git a/gammu/bcc6.mak/gammu.mak b/gammu/bcc6.mak/gammu.mak index 0455f3a61..339462ef0 100644 --- a/gammu/bcc6.mak/gammu.mak +++ b/gammu/bcc6.mak/gammu.mak @@ -23,14 +23,14 @@ OBJFILES = Output\gammu.obj Output\sniff.obj Output\dct3.obj Output\wmx.obj \ Output\gsmback.obj Output\gsmcal.obj Output\backldif.obj \ Output\backlmb.obj Output\backvcs.obj Output\backvcf.obj \ Output\backtext.obj Output\backics.obj Output\gsmlogo.obj Output\gsmnet.obj \ - Output\gsmpbk.obj Output\gsmring.obj Output\gsmsms.obj Output\sonyeric.obj \ - Output\gsmwap.obj Output\gsmmisc.obj Output\gsmcomon.obj \ - Output\gsmstate.obj Output\n6110.obj Output\n6510.obj Output\n3650.obj \ - Output\dct4func.obj Output\n7110.obj Output\n9210.obj Output\dct3func.obj \ - Output\nauto.obj Output\nfunc.obj Output\nfuncold.obj Output\alcatel.obj \ - Output\obexgen.obj Output\mroutgen.obj Output\pfunc.obj Output\atgen.obj \ - Output\siemens.obj Output\irda.obj Output\bluetoth.obj Output\ser_w32.obj \ - Output\devfunc.obj + Output\gsmpbk.obj Output\gsmring.obj Output\gsmsms.obj Output\gsmems.obj \ + Output\gsmmulti.obj Output\sonyeric.obj Output\gsmwap.obj \ + Output\gsmmisc.obj Output\gsmcomon.obj Output\gsmstate.obj \ + Output\n6110.obj Output\n6510.obj Output\n3650.obj Output\dct4func.obj \ + Output\n7110.obj Output\n9210.obj Output\dct3func.obj Output\nauto.obj \ + Output\nfunc.obj Output\nfuncold.obj Output\alcatel.obj Output\obexgen.obj \ + Output\mroutgen.obj Output\pfunc.obj Output\atgen.obj Output\siemens.obj \ + Output\irda.obj Output\bluetoth.obj Output\ser_w32.obj Output\devfunc.obj RESFILES = gammu.res MAINSOURCE = gammu.bpf RESDEPEN = $(RESFILES) @@ -50,10 +50,10 @@ DEBUGLIBPATH = $(BCB)\lib\debug RELEASELIBPATH = $(BCB)\lib\release USERDEFINES = WIN32;NDEBUG;_CONSOLE SYSDEFINES = _NO_VCL;_ASSERTE;NO_STRICT -INCLUDEPATH = ..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..;..\..\common\phone\symbian;..\..\common\protocol\symbian;..\..\common\protocol\obex;..\..\common\phone\obex;..\..\common\device;..\smsd;..\depend;..\..\common\device\serial;..\..\common\protocol\alcatel;..\..\common\phone\alcatel;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common\device\bluetoth;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\include;$(BCB)\include\mfc;$(BCB)\include\atl -LIBPATH = ..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..;..\..\common\phone\symbian;..\..\common\protocol\symbian;..\..\common\device;..\..\common\protocol\obex;..\..\common\phone\obex;..\smsd;..\depend;..\..\common\phone\alcatel;..\..\common\protocol\alcatel;..\..\common\device\serial;..\..\common\device\bluetoth;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\lib;$(RELEASELIBPATH);$(BCB)\lib\psdk +INCLUDEPATH = ..\..\common\service\sms;..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..;..\..\common\phone\symbian;..\..\common\protocol\symbian;..\..\common\protocol\obex;..\..\common\phone\obex;..\..\common\device;..\smsd;..\depend;..\..\common\device\serial;..\..\common\protocol\alcatel;..\..\common\phone\alcatel;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common\device\bluetoth;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\include;$(BCB)\include\mfc;$(BCB)\include\atl +LIBPATH = ..\..\common\service\sms;..\depend\dct3trac;..\..\common\misc\coding;..\..\common\service\backup;..\;..;..\..\common\phone\symbian;..\..\common\protocol\symbian;..\..\common\device;..\..\common\protocol\obex;..\..\common\phone\obex;..\smsd;..\depend;..\..\common\phone\alcatel;..\..\common\protocol\alcatel;..\..\common\device\serial;..\..\common\device\bluetoth;..\..\common\phone;..\..\common\phone\nokia;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\device\irda;..\..\common;..\..\common\service;..\..\common\protocol\nokia;..\..\common\misc;..\..\common\phone\at;..\..\common\protocol\at;$(BCB)\lib;$(RELEASELIBPATH);$(BCB)\lib\psdk WARNINGS= -w-par -w-8027 -w-8026 -w-csu -PATHCPP = .;..;..;..\depend;..\depend\dct3trac;..\depend\dct3trac;..\depend\dct3trac;..\depend\dct3trac;..\depend\dct3trac;..\depend;..\depend;..\smsd;..\smsd;..\..\common\misc;..\..\common\misc\coding;..\..\common\misc\coding;..\..\common\misc;..\..\common\protocol\at;..\..\common\protocol\obex;..\..\common\protocol\symbian;..\..\common\protocol\nokia;..\..\common\protocol\alcatel;..\..\common\protocol\nokia;..\..\common\protocol\nokia;..\..\common\service\backup;..\..\common\service;..\..\common\service\backup;..\..\common\service\backup;..\..\common\service\backup;..\..\common\service\backup;..\..\common\service\backup;..\..\common\service\backup;..\..\common\service;..\..\common\service;..\..\common\service;..\..\common\service;..\..\common\service;..\..\common\phone\at;..\..\common\service;..\..\common\service;..\..\common;..\..\common;..\..\common\phone\nokia\dct3;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\phone\nokia\dct3;..\..\common\phone\nokia\dct3;..\..\common\phone\nokia;..\..\common\phone\nokia;..\..\common\phone\nokia;..\..\common\phone\alcatel;..\..\common\phone\obex;..\..\common\phone\symbian;..\..\common\phone;..\..\common\phone\at;..\..\common\phone\at;..\..\common\device\irda;..\..\common\device\bluetoth;..\..\common\device\serial;..\..\common\device +PATHCPP = .;..;..;..\depend;..\depend\dct3trac;..\depend\dct3trac;..\depend\dct3trac;..\depend\dct3trac;..\depend\dct3trac;..\depend;..\depend;..\smsd;..\smsd;..\..\common\misc;..\..\common\misc\coding;..\..\common\misc\coding;..\..\common\misc;..\..\common\protocol\at;..\..\common\protocol\obex;..\..\common\protocol\symbian;..\..\common\protocol\nokia;..\..\common\protocol\alcatel;..\..\common\protocol\nokia;..\..\common\protocol\nokia;..\..\common\service\backup;..\..\common\service;..\..\common\service\backup;..\..\common\service\backup;..\..\common\service\backup;..\..\common\service\backup;..\..\common\service\backup;..\..\common\service\backup;..\..\common\service;..\..\common\service;..\..\common\service;..\..\common\service;..\..\common\service\sms;..\..\common\service\sms;..\..\common\service\sms;..\..\common\phone\at;..\..\common\service;..\..\common\service;..\..\common;..\..\common;..\..\common\phone\nokia\dct3;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct4;..\..\common\phone\nokia\dct3;..\..\common\phone\nokia\dct3;..\..\common\phone\nokia\dct3;..\..\common\phone\nokia;..\..\common\phone\nokia;..\..\common\phone\nokia;..\..\common\phone\alcatel;..\..\common\phone\obex;..\..\common\phone\symbian;..\..\common\phone;..\..\common\phone\at;..\..\common\phone\at;..\..\common\device\irda;..\..\common\device\bluetoth;..\..\common\device\serial;..\..\common\device PATHASM = .; PATHPAS = .; PATHRC = .; @@ -62,16 +62,17 @@ PATHOBJ = .;$(LIBPATH) CFLAG1 = -O2 -w- -VF -fp -X- -a8 -5 -b -k -vi -q -c IDLCFLAGS = -src_suffix cpp -DWIN32 -DNDEBUG -D_CONSOLE -I..\. -I.. \ -I..\..\common\protocol\obex -I..\..\common\phone\obex \ - -I..\..\common\misc\coding -I..\..\common\phone\symbian \ - -I..\..\common\device\serial -I..\smsd -I..\..\common\phone -I..\depend \ - -I..\..\common\protocol\alcatel -I..\..\common\device\bluetoth \ - -I..\..\common\phone\nokia -I..\..\common\service\backup \ - -I..\depend\dct3trac -I..\..\common\phone\alcatel \ - -I..\..\common\protocol\symbian -I..\..\common\phone\nokia\dct4 \ - -I..\..\common\phone\nokia\dct3 -I..\..\common\device\irda -I..\..\common \ - -I..\..\common\service -I..\..\common\protocol\nokia -I..\..\common\misc \ - -I..\..\common\phone\at -I..\..\common\protocol\at -I$(BCB)\include \ - -I$(BCB)\include\mfc -I$(BCB)\include\atl + -I..\..\common\service\sms -I..\..\common\misc\coding \ + -I..\..\common\phone\symbian -I..\..\common\device\serial -I..\smsd \ + -I..\..\common\phone -I..\depend -I..\..\common\protocol\alcatel \ + -I..\..\common\device\bluetoth -I..\..\common\phone\nokia \ + -I..\..\common\service\backup -I..\depend\dct3trac \ + -I..\..\common\phone\alcatel -I..\..\common\protocol\symbian \ + -I..\..\common\phone\nokia\dct4 -I..\..\common\phone\nokia\dct3 \ + -I..\..\common\device\irda -I..\..\common -I..\..\common\service \ + -I..\..\common\protocol\nokia -I..\..\common\misc -I..\..\common\phone\at \ + -I..\..\common\protocol\at -I$(BCB)\include -I$(BCB)\include\mfc \ + -I$(BCB)\include\atl PFLAGS = -N2Output -N0Output -$YD -$A8 RFLAGS = /l 0x415 /d "NDEBUG" /i$(BCB)\include;$(BCB)\include\mfc AFLAGS = /mx /w2 /zd diff --git a/gammu/depend/dct4.c b/gammu/depend/dct4.c index 893909a20..0500c0d94 100644 --- a/gammu/depend/dct4.c +++ b/gammu/depend/dct4.c @@ -428,6 +428,7 @@ void DCT4VibraTest(int argc, char *argv[]) Print_Error(error); } +#ifdef DEBUG static GSM_Error DCT4_ReplyResetSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { @@ -468,6 +469,49 @@ void DCT4ResetSecurityCode(int argc, char *argv[]) } } else Print_Error(error); } +#endif + +char SecLength; + +static GSM_Error DCT4_ReplyGetSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + if (msg.Length > 12) { + SecLength = msg.Buffer[13]; + if ((msg.Buffer[17]+18) == msg.Length) { + printf("Security code is %s\n",msg.Buffer+18); +// DumpMessage(stdout, msg.Buffer, msg.Length); + } + } + return GE_NONE; +} + +void DCT4GetSecurityCode(int argc, char *argv[]) +{ + GSM_Error error; + unsigned char getlen[]={0x00, 0x08, 0x01, 0x0C, + 0x00, 0x23, //ID + 0x00, 0x00, //Index + 0x00, 0x00}; + unsigned char read[]={0x00, 0x08, 0x02, 0x04, + 0x00, 0x23, //ID + 0x00, 0x00, //Index + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00}; //Length + + if (CheckDCT4Only()!=GE_NONE) return; + + s.User.UserReplyFunctions=UserReplyFunctions4; + + SecLength = 0; + error=GSM_WaitFor (&s, getlen, sizeof(getlen), 0x23, 1, ID_User1); + Print_Error(error); + if (SecLength != 0) { + read[17] = SecLength; + error=GSM_WaitFor (&s, read, sizeof(read), 0x23, 5, ID_User1); + Print_Error(error); + } +} static GSM_Error DCT4_ReplyGetVoiceRecord(GSM_Protocol_Message msg, GSM_StateMachine *s) { @@ -1091,8 +1135,10 @@ void DCT4TuneRadio(int argc, char *argv[]) static GSM_Reply_Function UserReplyFunctions4[] = { +#ifdef DEBUG {DCT4_ReplyResetSecurityCode, "\x08",0x03,0x05,ID_User2 }, {DCT4_ReplyResetSecurityCode, "\x08",0x03,0x06,ID_User2 }, +#endif {DCT4_ReplyGetADC, "\x17",0x03,0x10,ID_User3 }, {DCT4_ReplyGetADC, "\x17",0x03,0x12,ID_User3 }, @@ -1103,9 +1149,11 @@ static GSM_Reply_Function UserReplyFunctions4[] = { {DCT4_ReplyVibra, "\x1C",0x03,0x0D,ID_User3 }, {DCT4_ReplyVibra, "\x1C",0x03,0x0F,ID_User3 }, + {DCT4_ReplyGetSecurityCode, "\x23",0x03,0x05,ID_User1 }, {DCT4_ReplyGetT9, "\x23",0x03,0x05,ID_User3 }, {DCT4_ReplyGetVoiceRecord, "\x23",0x03,0x05,ID_User4 }, {DCT4_ReplyGetVoiceRecord, "\x23",0x03,0x0D,ID_User4 }, + {DCT4_ReplyGetSecurityCode, "\x23",0x03,0x0D,ID_User1 }, {DCT4_ReplyTestsStartup, "\x35",0x02,0x01,ID_User3 }, {DCT4_ReplyTestsStartup, "\x35",0x02,0x02,ID_User3 }, diff --git a/gammu/depend/dct4.h b/gammu/depend/dct4.h index 7c6717e79..c7ec59968 100644 --- a/gammu/depend/dct4.h +++ b/gammu/depend/dct4.h @@ -1,8 +1,13 @@ +#include "../../common/gsmstate.h" + void DCT4SetPhoneMenus (int argc, char *argv[]); void DCT4SelfTests (int argc, char *argv[]); void DCT4SetVibraLevel (int argc, char *argv[]); +void DCT4GetSecurityCode (int argc, char *argv[]); +#ifdef DEBUG void DCT4ResetSecurityCode (int argc, char *argv[]); +#endif void DCT4GetVoiceRecord (int argc, char *argv[]); void DCT4Info (int argc, char *argv[]); void DCT4GetT9 (int argc, char *argv[]); diff --git a/gammu/gammu.c b/gammu/gammu.c index 97e21dff2..ead9545fe 100644 --- a/gammu/gammu.c +++ b/gammu/gammu.c @@ -47,14 +47,13 @@ GSM_StateMachine s; GSM_Phone_Functions *Phone; -static CFG_Header *cfg = NULL; +static INI_Section *cfg = NULL; GSM_Error error = GE_NONE; static int i; volatile bool bshutdown = false; -/* SIGINT signal handler. */ void interrupted(int sig) { signal(sig, SIG_IGN); @@ -83,13 +82,47 @@ int printmsgerr(char *format, ...) return result; } +static void PrintSecurityStatus() +{ + GSM_SecurityCodeType Status; + + error=Phone->GetSecurityStatus(&s,&Status); + Print_Error(error); + switch(Status) { + case GSCT_SecurityCode: + printmsg("Waiting for Security Code.\n"); + break; + case GSCT_Pin: + printmsg("Waiting for PIN.\n"); + break; + case GSCT_Pin2: + printmsg("Waiting for PIN2.\n"); + break; + case GSCT_Puk: + printmsg("Waiting for PUK.\n"); + break; + case GSCT_Puk2: + printmsg("Waiting for PUK2.\n"); + break; + case GSCT_None: + printmsg("Nothing to enter.\n"); + break; + default: + printmsg("Unknown\n"); + } +} + void Print_Error(GSM_Error error) { - if (error!=GE_NONE) { - printf("%s\n",print_error(error,s.di.df,s.msg)); + if (error != GE_NONE) { + printf("%s\n",print_error(error,s.di.df,s.msg)); + if (error == GE_SECURITYERROR) { + printmsg("Security status: "); + PrintSecurityStatus(); + } if (s.opened) GSM_TerminateConnection(&s); - exit (-1); - } + exit (-1); + } } void GSM_Init(bool checkerror) @@ -514,6 +547,7 @@ static void GetAllMemory(int argc, char *argv[]) if (mystrncasecmp(argv[2],"ME",0)) Entry.MemoryType=GMT_ME; if (mystrncasecmp(argv[2],"SM",0)) Entry.MemoryType=GMT_SM; if (mystrncasecmp(argv[2],"VM",0)) Entry.MemoryType=GMT_VM; + if (mystrncasecmp(argv[2],"FD",0)) Entry.MemoryType=GMT_FD; if (Entry.MemoryType==0) { printmsg("ERROR: unknown memory type (\"%s\")\n",argv[2]); exit (-1); @@ -548,6 +582,7 @@ static void GetMemory(int argc, char *argv[]) if (mystrncasecmp(argv[2],"ME",0)) entry.MemoryType=GMT_ME; if (mystrncasecmp(argv[2],"SM",0)) entry.MemoryType=GMT_SM; if (mystrncasecmp(argv[2],"VM",0)) entry.MemoryType=GMT_VM; + if (mystrncasecmp(argv[2],"FD",0)) entry.MemoryType=GMT_FD; if (entry.MemoryType==0) { printmsg("ERROR: unknown memory type (\"%s\")\n",argv[2]); exit (-1); @@ -580,7 +615,14 @@ static void GetMemory(int argc, char *argv[]) GSM_Terminate(); } -#define MemoryLocationToString(x) ( x == GMT_ON ? "ON" : x == GMT_RC ? "RC" : x == GMT_MC ? "MC" : x == GMT_ME ? "ME" : x == GMT_SM ? "SM" : x == GMT_VM ? "MV" : "XX") +#define MemoryLocationToString(x) ( \ + x == GMT_ON ? "ON" : \ + x == GMT_RC ? "RC" : \ + x == GMT_MC ? "MC" : \ + x == GMT_ME ? "ME" : \ + x == GMT_SM ? "SM" : \ + x == GMT_VM ? "VM" : \ + x == GMT_FD ? "FD" : "XX") static void SearchOneEntry(GSM_MemoryEntry *Entry, unsigned char *Text) { @@ -639,20 +681,20 @@ static void SearchOneMemory(GSM_MemoryType MemoryType, char *Title, unsigned cha Entry.MemoryType = MemoryType; if (Phone->GetMemoryStatus(&s, &Status) == GE_NONE) { + fprintf(stderr,"%c%s: %i%%", 13, Title, (i+1)*100/(Status.Used+1)); if (Phone->GetNextMemory != NOTSUPPORTED && Phone->GetNextMemory != NOTIMPLEMENTED) { - while (1) { + while (i < Status.Used) { if (bshutdown) return; - fprintf(stderr,"\r%s: %i", Title, i*100/Status.Used); + i++; + fprintf(stderr,"\r%s: %i%%", Title, (i+1)*100/(Status.Used+1)); error = Phone->GetNextMemory(&s, &Entry, start); if (error == GE_EMPTY) break; - i++; Print_Error(error); SearchOneEntry(&Entry, Text); start = false; } } else { while (i < Status.Used) { - fprintf(stderr,"%c%s: %i", 13, Title, i*100/Status.Used); Entry.Location = l; error = Phone->GetMemory(&s, &Entry); if (error != GE_EMPTY) { @@ -660,6 +702,7 @@ static void SearchOneMemory(GSM_MemoryType MemoryType, char *Title, unsigned cha i++; SearchOneEntry(&Entry, Text); } + fprintf(stderr,"%c%s: %i%%", 13, Title, (i+1)*100/(Status.Used+1)); l++; } } @@ -916,21 +959,28 @@ static void displaysinglesmsinfo(GSM_SMSMessage sms, bool displaytext, bool disp } } -static void displaymultismsinfo (GSM_MultiSMSMessage sms, bool eachsms) +typedef struct { + GSM_MultiBitmap Bitmap; + GSM_Ringtone Ringtone; + char Buffer[5000]; +} SMSValues; + +static void displaymultismsinfo (GSM_MultiSMSMessage sms, bool eachsms, bool ems) { GSM_EncodeMultiPartSMSInfo SMSInfo; - GSM_MultiBitmap Bitmap; - GSM_Ringtone Ringtone; - char Buffer[5000]; + SMSValues Values[MAX_MULTI_SMS]; bool RetVal,udhinfo=true; int j; - SMSInfo.Entries[0].Bitmap = &Bitmap; - SMSInfo.Entries[0].Ringtone = &Ringtone; - SMSInfo.Entries[0].Buffer = Buffer; + for (i=0;iBitmap[0].Type) { - case GSM_CallerLogo: - printmsg("Caller logo\n\n"); - break; - case GSM_OperatorLogo: - printmsg("Operator logo for %s network (%s, %s)\n\n", - SMSInfo.Entries[0].Bitmap->Bitmap[0].NetworkCode, - DecodeUnicodeConsole(GSM_GetNetworkName(SMSInfo.Entries[0].Bitmap->Bitmap[0].NetworkCode)), - DecodeUnicodeConsole(GSM_GetCountryName(SMSInfo.Entries[0].Bitmap->Bitmap[0].NetworkCode))); - break; - case GSM_PictureImage: - printmsg("Picture Image\n"); - printmsg("Text: \"%s\"\n\n",DecodeUnicodeConsole(SMSInfo.Entries[0].Bitmap->Bitmap[0].Text)); - break; - default: - break; - } - GSM_PrintBitmap(stdout,&SMSInfo.Entries[0].Bitmap->Bitmap[0]); - printf("\n"); - } - if (SMSInfo.Entries[0].Buffer != NULL) { - printmsg("%s\n",DecodeUnicodeConsole(Buffer)); - } - if (SMSInfo.Entries[0].Ringtone != NULL) { - printmsg("Ringtone \"%s\"\n",DecodeUnicodeConsole(SMSInfo.Entries[0].Ringtone->Name)); - saverttl(stdout,SMSInfo.Entries[0].Ringtone); + if (!RetVal) return; + + if (SMSInfo.Unknown) printmsg("Some details were ignored (unknown or not implemented in decoding functions)\n\n"); + + for (i=0;iName)); + 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[0].Ringtone); + 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"); } + printf("\n"); } static void IncomingSMS(char *Device, GSM_SMSMessage sms) @@ -994,7 +1073,7 @@ static void IncomingSMS(char *Device, GSM_SMSMessage sms) printmsg("SMS message received\n"); SMS.Number = 1; memcpy(&SMS.SMS[0],&sms,sizeof(GSM_SMSMessage)); - displaymultismsinfo(SMS,false); + displaymultismsinfo(SMS,false,false); } static void IncomingCB(char *Device, GSM_CBMessage CB) @@ -1138,11 +1217,13 @@ static void Monitor(int argc, char *argv[]) } if (Phone->GetNetworkInfo(&s,&NetInfo)==GE_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; + 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) { @@ -1243,7 +1324,7 @@ static void GetSMS(int argc, char *argv[]) } if (sms.SMS[0].InboxFolder) printmsg(", Inbox folder"); printf("\n"); - displaymultismsinfo(sms,false); + displaymultismsinfo(sms,false,false); } } @@ -1302,7 +1383,7 @@ static void GetAllSMS(int argc, char *argv[]) } if (sms.SMS[0].InboxFolder) printmsg(", Inbox folder"); printf("\n"); - displaymultismsinfo(sms,false); + displaymultismsinfo(sms,false,false); } fprintf(stderr,"*"); start=false; @@ -1320,7 +1401,7 @@ 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; + bool start = true, ems = true; GetSMS[0] = NULL; @@ -1359,7 +1440,7 @@ static void GetEachSMS(int argc, char *argv[]) GSM_Terminate(); - error = GSM_SortSMS(GetSMS, SortedSMS); + error = GSM_LinkSMS(GetSMS, SortedSMS, ems); Print_Error(error); i=0; @@ -1378,7 +1459,7 @@ static void GetEachSMS(int argc, char *argv[]) printf("\n"); } } - displaymultismsinfo(*SortedSMS[i],true); + displaymultismsinfo(*SortedSMS[i],true,ems); } i++; } @@ -4136,6 +4217,8 @@ static void Restore(int argc, char *argv[]) if (Backup.IMEI[0]!=0) printmsgerr("IMEI : %s\n",Backup.IMEI); 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; } @@ -5107,7 +5190,7 @@ static void RestoreSMS(int argc, char *argv[]) while (Backup.SMS[smsnum] != NULL) { SMS.Number = 1; memcpy(&SMS.SMS[0],Backup.SMS[smsnum],sizeof(GSM_SMSMessage)); - displaymultismsinfo(SMS,false); + displaymultismsinfo(SMS,false,false); sprintf(buffer,"Restore sms to folder \"%s\"",DecodeUnicodeConsole(folders.Folder[Backup.SMS[smsnum]->Folder-1].Name)); if (answer_yes(buffer)) { Backup.SMS[smsnum]->Location = 0; @@ -5671,22 +5754,10 @@ static void GetNote(int argc, char *argv[]) static void GetSecurityStatus(int argc, char *argv[]) { - GSM_SecurityCodeType Status; - GSM_Init(true); - error=Phone->GetSecurityStatus(&s,&Status); - Print_Error(error); - switch(Status) { - case GSCT_SecurityCode: printmsg("Waiting for Security Code.\n"); break; - case GSCT_Pin : printmsg("Waiting for PIN.\n"); break; - case GSCT_Pin2 : printmsg("Waiting for PIN2.\n"); break; - case GSCT_Puk : printmsg("Waiting for PUK.\n"); break; - case GSCT_Puk2 : printmsg("Waiting for PUK2.\n"); break; - case GSCT_None : printmsg("Nothing to enter.\n"); break; - default : printmsg("Unknown\n"); - } - + PrintSecurityStatus(); + GSM_Terminate(); } @@ -5915,7 +5986,8 @@ static void NokiaSecurityCode(int argc, char *argv[]) DCT3GetSecurityCode(argc,argv); #endif #ifdef GSM_ENABLE_NOKIA_DCT4 - DCT4ResetSecurityCode(argc, argv); +// DCT4ResetSecurityCode(argc, argv); + DCT4GetSecurityCode(argc,argv); #endif GSM_Terminate(); @@ -6071,13 +6143,15 @@ static void MakeConvertTable(int argc, char *argv[]) static void ListNetworks(int argc, char *argv[]) { - extern GSM_Network GSM_Networks[]; - int i; + extern unsigned char *GSM_Networks[]; + int i=0; printmsg("Network Name\n"); printmsg("-----------------------------------------\n"); - for (i = 0; strcmp(GSM_Networks[i].Name, "unknown"); i++) - printmsg("%-7s %s\n", GSM_Networks[i].Code, GSM_Networks[i].Name); + while (GSM_Networks[i*2]!=NULL) { + printmsg("%-7s %s\n", GSM_Networks[i*2], GSM_Networks[i*2+1]); + i++; + } } static void Version(int argc, char *argv[]) @@ -7193,8 +7267,8 @@ static GSM_Parameters Parameters[] = { {"--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, 3, GetMemory, {H_Memory,0}, "DC|MC|RC|ON|VM|SM|ME start [stop]"}, - {"--getallmemory", 1, 1, GetAllMemory, {H_Memory,0}, "DC|MC|RC|ON|VM|SM|ME"}, + {"--getmemory", 2, 3, GetMemory, {H_Memory,0}, "DC|MC|RC|ON|VM|SM|ME|FD start [stop]"}, + {"--getallmemory", 1, 1, 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]"}, @@ -7598,8 +7672,8 @@ int main(int argc, char *argv[]) } /* Help? */ - if (strncmp(argv[1], "--help", 6) == 0) { - Help(argc, argv); + if (strncmp(argv[1 + start], "--help", 6) == 0) { + Help(argc - start, argv + start); exit(1); } @@ -7610,15 +7684,15 @@ int main(int argc, char *argv[]) else only_config = -1; } - cfg=CFG_FindGammuRC(); + cfg=GSM_FindGammuRC(); for (i=0;i<5;i++) { if (cfg!=NULL) { - cp = CFG_Get(cfg, "gammu", "gammucoding", false); + cp = INI_GetValue(cfg, "gammu", "gammucoding", false); if (cp) di.coding = cp; - s.Config[i].Localize = CFG_Get(cfg, "gammu", "gammuloc", false); + s.Config[i].Localize = INI_GetValue(cfg, "gammu", "gammuloc", false); if (s.Config[i].Localize) { - s.msg=CFG_ReadFile(s.Config[i].Localize, true); + s.msg=INI_ReadFile(s.Config[i].Localize, true); } else { #if !defined(WIN32) && defined(LOCALE_PATH) locale = setlocale(LC_MESSAGES, NULL); @@ -7627,7 +7701,7 @@ int main(int argc, char *argv[]) LOCALE_PATH, tolower(locale[0]), tolower(locale[1])); - s.msg = CFG_ReadFile(locale_file, true); + s.msg = INI_ReadFile(locale_file, true); } #endif } @@ -7636,9 +7710,9 @@ int main(int argc, char *argv[]) /* Wanted user specific configuration? */ if (only_config != -1) { /* Here we get only in first for loop */ - if (!CFG_ReadConfig(cfg, &s.Config[0], only_config)) break; + if (!GSM_ReadConfig(cfg, &s.Config[0], only_config)) break; } else { - if (!CFG_ReadConfig(cfg, &s.Config[i], i) && i != 0) break; + if (!GSM_ReadConfig(cfg, &s.Config[i], i) && i != 0) break; } s.ConfigNum++; diff --git a/gammu/msvc6.mak/gammu.dsp b/gammu/msvc6.mak/gammu.dsp index c88891a86..4fc196602 100644 --- a/gammu/msvc6.mak/gammu.dsp +++ b/gammu/msvc6.mak/gammu.dsp @@ -229,7 +229,15 @@ SOURCE=..\..\common\service\gsmring.c # End Source File # Begin Source File -SOURCE=..\..\common\service\gsmsms.c +SOURCE=..\..\common\service\sms\gsmsms.c +# End Source File +# Begin Source File + +SOURCE=..\..\common\service\sms\gsmems.c +# End Source File +# Begin Source File + +SOURCE=..\..\common\service\sms\gsmmulti.c # End Source File # Begin Source File @@ -509,7 +517,15 @@ SOURCE=..\..\common\service\gsmring.h # End Source File # Begin Source File -SOURCE=..\..\common\service\gsmsms.h +SOURCE=..\..\common\service\sms\gsmsms.h +# End Source File +# Begin Source File + +SOURCE=..\..\common\service\sms\gsmems.h +# End Source File +# Begin Source File + +SOURCE=..\..\common\service\sms\gsmmulti.h # End Source File # Begin Source File diff --git a/gammu/msvc6.mak/gammu.rc b/gammu/msvc6.mak/gammu.rc index 2cf2a760e..f699d82b4 100644 --- a/gammu/msvc6.mak/gammu.rc +++ b/gammu/msvc6.mak/gammu.rc @@ -54,8 +54,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,90,0,0 - PRODUCTVERSION 0,90,0,0 + FILEVERSION 0,90,7,0 + PRODUCTVERSION 0,90,7,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -73,14 +73,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "http://www.mwiacek.com\0" VALUE "FileDescription", "Gammu - manager for cellular modems and phones\0" - VALUE "FileVersion", "0,90,0,0\0" + VALUE "FileVersion", "0,90,7,0\0" VALUE "InternalName", "Gammu\0" VALUE "LegalCopyright", "Copyright © 2002-2003 Marcin Wiacek\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "gammu.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Gammu (GNU All Mobile Management Utilities)\0" - VALUE "ProductVersion", "0,90,0,0\0" + VALUE "ProductVersion", "0,90,7,0\0" VALUE "SpecialBuild", "\0" END END diff --git a/gammu/msvc7.mak/gammu.rc b/gammu/msvc7.mak/gammu.rc index 64ff0bed0..3b349bd94 100644 --- a/gammu/msvc7.mak/gammu.rc +++ b/gammu/msvc7.mak/gammu.rc @@ -53,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,90,0,0 - PRODUCTVERSION 0,90,0,0 + FILEVERSION 0,90,7,0 + PRODUCTVERSION 0,90,7,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -71,12 +71,12 @@ BEGIN BEGIN VALUE "CompanyName", "http://www.mwiacek.com" VALUE "FileDescription", "Gammu - manager for cellular modems and phones" - VALUE "FileVersion", "0,90,0,0" + VALUE "FileVersion", "0,90,7,0" VALUE "InternalName", "Gammu" VALUE "LegalCopyright", "Copyright © 2002-2003 Marcin Wiacek" VALUE "OriginalFilename", "gammu.exe" VALUE "ProductName", "Gammu (GNU All Mobile Management Utilities)" - VALUE "ProductVersion", "0,90,0,0" + VALUE "ProductVersion", "0,90,7,0" END END BLOCK "VarFileInfo" diff --git a/gammu/msvc7.mak/gammu.vcproj b/gammu/msvc7.mak/gammu.vcproj index 64b791a8f..f95be4ccd 100644 --- a/gammu/msvc7.mak/gammu.vcproj +++ b/gammu/msvc7.mak/gammu.vcproj @@ -208,12 +208,18 @@ RelativePath="..\..\common\gsmcomon.c"> + + + + + RelativePath="..\..\common\service\sms\gsmsms.c"> @@ -404,9 +410,15 @@ RelativePath="..\..\common\gsmcomon.h"> + + + + + RelativePath="..\..\common\service\sms\gsmsms.h"> diff --git a/gammu/smsd/smsdcore.c b/gammu/smsd/smsdcore.c index b0f81fb91..b540fe585 100644 --- a/gammu/smsd/smsdcore.c +++ b/gammu/smsd/smsdcore.c @@ -69,18 +69,18 @@ void WriteSMSDLog(unsigned char *format, ...) void SMSD_ReadConfig(int argc, char *argv[], GSM_SMSDConfig *Config) { - CFG_Header *smsdcfgfile = NULL; + INI_Section *smsdcfgfile = NULL; GSM_Config smsdcfg; unsigned char *str; static unsigned char emptyPath[1] = "\0"; - smsdcfgfile=CFG_ReadFile(argv[3], false); + smsdcfgfile=INI_ReadFile(argv[3], false); if (smsdcfgfile==NULL) { fprintf(stderr,"Can't find file \"%s\"\n",argv[3]); exit(-1); } - Config->logfilename=CFG_Get(smsdcfgfile, "smsd", "logfile", false); + Config->logfilename=INI_GetValue(smsdcfgfile, "smsd", "logfile", false); if (Config->logfilename != NULL) { smsd_log_file=fopen(Config->logfilename,"ab"); if (smsd_log_file == NULL) { @@ -92,13 +92,13 @@ void SMSD_ReadConfig(int argc, char *argv[], GSM_SMSDConfig *Config) WriteSMSDLog("Start GAMMU smsd"); /* Include Numbers used, because we don't want create new variable */ - Config->IncludeNumbers=CFG_FindLastSectionEntry(smsdcfgfile, "gammu", false); + Config->IncludeNumbers=INI_FindLastSectionEntry(smsdcfgfile, "gammu", false); if (Config->IncludeNumbers) { - CFG_ReadConfig(smsdcfgfile, &smsdcfg, 0); + GSM_ReadConfig(smsdcfgfile, &smsdcfg, 0); memcpy(&s.Config,&smsdcfg,sizeof(GSM_Config)); } - Config->PINCode=CFG_Get(smsdcfgfile, "smsd", "PIN", false); + Config->PINCode=INI_GetValue(smsdcfgfile, "smsd", "PIN", false); if (Config->PINCode == NULL) { WriteSMSDLog("No PIN code in %s file",argv[3]); fprintf(stderr,"No PIN code in %s file\n",argv[3]); @@ -106,51 +106,48 @@ void SMSD_ReadConfig(int argc, char *argv[], GSM_SMSDConfig *Config) } WriteSMSDLog("PIN code is \"%s\"",Config->PINCode); - str = CFG_Get(smsdcfgfile, "smsd", "commtimeout", false); + str = INI_GetValue(smsdcfgfile, "smsd", "commtimeout", false); if (str) Config->commtimeout=atoi(str); else Config->commtimeout = 1; - str = CFG_Get(smsdcfgfile, "smsd", "sendtimeout", false); + str = INI_GetValue(smsdcfgfile, "smsd", "sendtimeout", false); if (str) Config->sendtimeout=atoi(str); else Config->sendtimeout = 10; - str = CFG_Get(smsdcfgfile, "smsd", "receivefrequency", false); + str = INI_GetValue(smsdcfgfile, "smsd", "receivefrequency", false); if (str) Config->receivefrequency=atoi(str); else Config->receivefrequency = 0; WriteSMSDLog("commtimeout=%i, sendtimeout=%i, receivefrequency=%i", Config->commtimeout, Config->sendtimeout, Config->receivefrequency); - Config->deliveryreport = CFG_Get(smsdcfgfile, "smsd", "deliveryreport", false); - if (Config->deliveryreport == NULL || (!mystrncasecmp(Config->deliveryreport, "log", 3) && !mystrncasecmp(Config->deliveryreport, "sms", 3))) - { + 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"; } WriteSMSDLog("deliveryreport = %s", Config->deliveryreport); - Config->inboxpath=CFG_Get(smsdcfgfile, "smsd", "inboxpath", false); + Config->inboxpath=INI_GetValue(smsdcfgfile, "smsd", "inboxpath", false); if (Config->inboxpath == NULL) Config->inboxpath = emptyPath; - Config->inboxformat=CFG_Get(smsdcfgfile, "smsd", "inboxformat", false); - if (Config->inboxformat == NULL || (!mystrncasecmp(Config->inboxformat, "detail", 6) && !mystrncasecmp(Config->inboxformat, "unicode", 7))) - { + 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"; } WriteSMSDLog("Inbox is \"%s\" with format \"%s\"", Config->inboxpath, Config->inboxformat); - Config->outboxpath=CFG_Get(smsdcfgfile, "smsd", "outboxpath", false); + Config->outboxpath=INI_GetValue(smsdcfgfile, "smsd", "outboxpath", false); if (Config->outboxpath == NULL) Config->outboxpath = emptyPath; - Config->transmitformat=CFG_Get(smsdcfgfile, "smsd", "transmitformat", false); - if (Config->transmitformat == NULL || (!mystrncasecmp(Config->transmitformat, "auto", 4) && !mystrncasecmp(Config->transmitformat, "unicode", 7))) - { + 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"; } WriteSMSDLog("Outbox is \"%s\" with transmission format \"%s\"", Config->outboxpath, Config->transmitformat); - Config->sentsmspath=CFG_Get(smsdcfgfile, "smsd", "sentsmspath", false); + Config->sentsmspath=INI_GetValue(smsdcfgfile, "smsd", "sentsmspath", false); if (Config->sentsmspath == NULL) Config->sentsmspath = Config->outboxpath; WriteSMSDLog("Sent SMS moved to \"%s\"",Config->sentsmspath); - Config->errorsmspath=CFG_Get(smsdcfgfile, "smsd", "errorsmspath", false); + Config->errorsmspath=INI_GetValue(smsdcfgfile, "smsd", "errorsmspath", false); if (Config->errorsmspath == NULL) Config->errorsmspath = Config->sentsmspath; WriteSMSDLog("SMS with errors moved to \"%s\"",Config->errorsmspath); - Config->IncludeNumbers=CFG_FindLastSectionEntry(smsdcfgfile, "include_numbers", false); - Config->ExcludeNumbers=CFG_FindLastSectionEntry(smsdcfgfile, "exclude_numbers", false); + Config->IncludeNumbers=INI_FindLastSectionEntry(smsdcfgfile, "include_numbers", false); + Config->ExcludeNumbers=INI_FindLastSectionEntry(smsdcfgfile, "exclude_numbers", false); if (Config->IncludeNumbers != NULL) { WriteSMSDLog("Include numbers available"); } @@ -211,7 +208,7 @@ bool SMSD_ReadDeleteSMS(GSM_SMSDConfig *Config, GSM_SMSDService *Service) GSM_MultiSMSMessage sms; unsigned char buffer[100]; GSM_Error error=GE_NONE; - CFG_Entry *e; + INI_Entry *e; int i; start=true; @@ -231,22 +228,22 @@ bool SMSD_ReadDeleteSMS(GSM_SMSDConfig *Config, GSM_SMSDService *Service) process=false; while (1) { if (e == NULL) break; - if (strcmp(buffer,e->value)==0) { + if (strcmp(buffer,e->EntryValue)==0) { process=true; break; } - e = e->prev; + e = e->Prev; } } else if (Config->ExcludeNumbers != NULL) { e=Config->ExcludeNumbers; process=true; while (1) { if (e == NULL) break; - if (strcmp(buffer,e->value)==0) { + if (strcmp(buffer,e->EntryValue)==0) { process=false; break; } - e = e->prev; + e = e->Prev; } } if (process) { diff --git a/gammu/smsd/smsdcore.h b/gammu/smsd/smsdcore.h index 9b616db89..cd1a45b0c 100644 --- a/gammu/smsd/smsdcore.h +++ b/gammu/smsd/smsdcore.h @@ -1,12 +1,13 @@ -#include "../../common/service/gsmsms.h" +#include "../../common/service/sms/gsmsms.h" +#include "../../common/service/sms/gsmmulti.h" #define MAX_RETRIES 1 void SMSDaemon(int argc, char *argv[]); typedef struct { - CFG_Entry *IncludeNumbers, *ExcludeNumbers; + INI_Entry *IncludeNumbers, *ExcludeNumbers; unsigned int commtimeout, sendtimeout, receivefrequency; unsigned char *inboxpath, *outboxpath, *sentsmspath; unsigned char *errorsmspath, *inboxformat, *transmitformat; diff --git a/gammu/sniff.c b/gammu/sniff.c index ec51b9260..dab7b2993 100644 --- a/gammu/sniff.c +++ b/gammu/sniff.c @@ -92,8 +92,7 @@ static void DecodeInputMBUS2(unsigned char rx_byte) d->Msg.Count++; if (d->Msg.Count == d->Msg.Length+2) { - /* If this is the last byte, it's the checksum. */ - /* Is the checksum correct? */ + /* When we have last byte, it's the checksum. */ if (d->Msg.CheckSum[0] == rx_byte) { if (d->Msg.Destination != MBUS2_DEVICE_PHONE) { printf("Received frame"); diff --git a/other/copying b/other/copying new file mode 100644 index 000000000..89cecf20c --- /dev/null +++ b/other/copying @@ -0,0 +1,2 @@ +These are some 3 party extensions written for Gammu here. They have +own licenses. diff --git a/docs/develop/protocol/TDMA 5120.txt b/other/protocol/TDMA 5120.txt similarity index 100% rename from docs/develop/protocol/TDMA 5120.txt rename to other/protocol/TDMA 5120.txt diff --git a/docs/develop/protocol/carkit.txt b/other/protocol/carkit.txt similarity index 100% rename from docs/develop/protocol/carkit.txt rename to other/protocol/carkit.txt diff --git a/docs/develop/protocol/n6110.txt b/other/protocol/n6110.txt similarity index 100% rename from docs/develop/protocol/n6110.txt rename to other/protocol/n6110.txt diff --git a/docs/develop/protocol/n6510.txt b/other/protocol/n6510.txt similarity index 100% rename from docs/develop/protocol/n6510.txt rename to other/protocol/n6510.txt diff --git a/docs/develop/protocol/n7110.txt b/other/protocol/n7110.txt similarity index 100% rename from docs/develop/protocol/n7110.txt rename to other/protocol/n7110.txt diff --git a/docs/develop/protocol/nokia.txt b/other/protocol/nokia.txt similarity index 100% rename from docs/develop/protocol/nokia.txt rename to other/protocol/nokia.txt diff --git a/docs/develop/protocol/readme b/other/protocol/readme similarity index 100% rename from docs/develop/protocol/readme rename to other/protocol/readme diff --git a/version b/version index a062e02ce..40bce1ba5 100644 --- a/version +++ b/version @@ -1 +1 @@ -0,90,0 \ No newline at end of file +0,90,7 \ No newline at end of file diff --git a/win32/delphi7.gui/classic2/Unit1.dfm b/win32/delphi7.gui/classic2/Unit1.dfm index 13333222d..2ec31b50a 100644 --- a/win32/delphi7.gui/classic2/Unit1.dfm +++ b/win32/delphi7.gui/classic2/Unit1.dfm @@ -4,7 +4,7 @@ object Form1: TForm1 BorderIcons = [biSystemMenu, biMinimize] BorderStyle = bsSingle Caption = 'Example' - ClientHeight = 156 + ClientHeight = 145 ClientWidth = 410 Color = clBtnFace Font.Charset = DEFAULT_CHARSET @@ -50,6 +50,13 @@ object Form1: TForm1 Height = 13 Caption = 'Model:' end + object Label6: TLabel + Left = 8 + Top = 112 + Width = 68 + Height = 13 + Caption = 'Security code:' + end object Edit1: TEdit Left = 296 Top = 16 @@ -81,9 +88,9 @@ object Form1: TForm1 Text = 'com2:' end object Button1: TButton - Left = 32 - Top = 120 - Width = 89 + Left = 296 + Top = 104 + Width = 97 Height = 25 Caption = 'Make job' TabOrder = 4 @@ -96,4 +103,11 @@ object Form1: TForm1 Height = 21 TabOrder = 5 end + object Edit6: TEdit + Left = 96 + Top = 112 + Width = 121 + Height = 21 + TabOrder = 6 + end end diff --git a/win32/delphi7.gui/classic2/Unit1.pas b/win32/delphi7.gui/classic2/Unit1.pas index 69b90afa6..dc6c9827a 100644 --- a/win32/delphi7.gui/classic2/Unit1.pas +++ b/win32/delphi7.gui/classic2/Unit1.pas @@ -19,6 +19,8 @@ type Button1: TButton; Label5: TLabel; Edit5: TEdit; + Label6: TLabel; + Edit6: TEdit; procedure Button1Click(Sender: TObject); private { Private declarations } @@ -61,6 +63,10 @@ begin if (error <> GE_NONE) then application.MessageBox(pchar('Get IMEI: error '+inttostr(integer(error))),'',0); if (error = GE_NONE) then Form1.Edit2.Text:=buffer; + error:=GSM_GetDCT4SecurityCode(Form1.PhoneID,@buffer); + if (error <> GE_NONE) then application.MessageBox(pchar('Get security code: error '+inttostr(integer(error))),'',0); + if (error = GE_NONE) then Form1.Edit6.Text:=buffer; + error:=GSM_EndConnection(Form1.PhoneID); if (error <> GE_NONE) then application.MessageBox(pchar('End connection: error '+inttostr(integer(error))),'',0); end; diff --git a/win32/delphi7.gui/gammu.pas b/win32/delphi7.gui/gammu.pas index 5974039cd..cf525d36f 100644 --- a/win32/delphi7.gui/gammu.pas +++ b/win32/delphi7.gui/gammu.pas @@ -264,6 +264,7 @@ function GSM_AddSMSMessage (Phone : integer; SMS : PGSM_SMSMessage): GSM function GSM_EnterSecurityCode (Phone : integer; Code : PGSM_SecurityCode): GSM_Error; stdcall ; external 'gammu.dll' name 'myentersecuritycode'; function GSM_GetIMEI (Phone : integer; IMEI:PAnsiString): GSM_Error; stdcall; external 'gammu.dll' name 'mygetimei'; function GSM_GetDCT4SimlockNetwork (Phone : integer; Info:PAnsiString): GSM_Error; stdcall; external 'gammu.dll' name 'mygetdct4simlocknetwork'; +function GSM_GetDCT4SecurityCode (Phone : integer; Code:PAnsiString): GSM_Error; stdcall; external 'gammu.dll' name 'mygetdct4securitycode'; function GSM_GetManufacturer (Phone : integer; IMEI:PAnsiString): GSM_Error; stdcall; external 'gammu.dll' name 'mygetmanufacturer'; function GSM_GetModel (Phone : integer; Model:PAnsiString): GSM_Error; stdcall; external 'gammu.dll' name 'mygetmodel'; function GSM_GetModelName (Phone : integer; Model:PAnsiString): GSM_Error; stdcall; external 'gammu.dll' name 'mygetmodelname'; diff --git a/win32/dll/gammu.c b/win32/dll/gammu.c index 0e0906fbb..6e1bd5e68 100644 --- a/win32/dll/gammu.c +++ b/win32/dll/gammu.c @@ -578,7 +578,23 @@ static GSM_Error DCT4_ReplyGetSimlock(GSM_Protocol_Message msg, GSM_StateMachine return GE_UNKNOWNRESPONSE; } +char SecLength; + +static GSM_Error DCT4_ReplyGetSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + if (msg.Length > 12) { + SecLength = msg.Buffer[13]; + if ((msg.Buffer[17]+18) == msg.Length) { + sprintf(s->Phone.Data.PhoneString,"%s",msg.Buffer+18); + } + } + return GE_NONE; +} + static GSM_Reply_Function UserReplyFunctions4[] = { + {DCT4_ReplyGetSecurityCode, "\x23",0x03,0x05,ID_User1 }, + {DCT4_ReplyGetSecurityCode, "\x23",0x03,0x0D,ID_User1 }, + {DCT4_ReplyGetSimlock, "\x53",0x03,0x0D,ID_User6 }, {NULL, "\x00",0x00,0x00,ID_None } }; @@ -600,6 +616,39 @@ GSM_Error WINAPI mygetdct4simlocknetwork(int phone, char *network) return error; } +GSM_Error WINAPI mygetdct4securitycode(int phone, char *code) +{ + GSM_Error error; + unsigned char getlen[]={0x00, 0x08, 0x01, 0x0C, + 0x00, 0x23, //ID + 0x00, 0x00, //Index + 0x00, 0x00}; + unsigned char read[]={0x00, 0x08, 0x02, 0x04, + 0x00, 0x23, //ID + 0x00, 0x00, //Index + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00}; //Length + + if (!s[phone].s.opened) return GE_NOTCONNECTED; + + WaitForSingleObject(s[phone].Mutex, INFINITE ); + s[phone].s.User.UserReplyFunctions = UserReplyFunctions4; + code[0] = 0; + s[phone].s.Phone.Data.PhoneString = code; + + SecLength = 0; + error=GSM_WaitFor (&s[phone].s, getlen, sizeof(getlen), 0x23, 1, ID_User1); + SetErrorCounter(phone, error); + if (SecLength != 0) { + read[17] = SecLength; + error=GSM_WaitFor (&s[phone].s, read, sizeof(read), 0x23, 5, ID_User1); + SetErrorCounter(phone, error); + } + ReleaseMutex(s[phone].Mutex); + return error; +} + /* ------------------------------------------------------------------------- */ int WINAPI mygetstructuresize(int i) diff --git a/win32/dll/msvc6.mak/gammu.def b/win32/dll/msvc6.mak/gammu.def index a8bbecddb..9a48cd615 100644 --- a/win32/dll/msvc6.mak/gammu.def +++ b/win32/dll/msvc6.mak/gammu.def @@ -14,7 +14,7 @@ EXPORTS mydeletesmsmessage @7 mysendsmsmessage @8 mygetsmsstatus @9 - mysavesmsmessage @10 + myaddsmsmessage @10 mygetnetworkname @11 mygetgammuversion @12 @@ -28,3 +28,4 @@ EXPORTS mymakemultipartsms @21 mygetstructuresize @22 mygetdct4simlocknetwork @23 + mygetdct4securitycode @24 diff --git a/win32/dll/msvc6.mak/gammu.dsp b/win32/dll/msvc6.mak/gammu.dsp index f205c4e07..af436b523 100644 --- a/win32/dll/msvc6.mak/gammu.dsp +++ b/win32/dll/msvc6.mak/gammu.dsp @@ -174,7 +174,15 @@ SOURCE=..\..\..\common\service\gsmring.c # End Source File # Begin Source File -SOURCE=..\..\..\common\service\gsmsms.c +SOURCE=..\..\..\common\service\sms\gsmsms.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\common\service\sms\gsmems.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\common\service\sms\gsmmulti.c # End Source File # Begin Source File @@ -374,7 +382,15 @@ SOURCE=..\..\..\common\service\gsmmisc.h # End Source File # Begin Source File -SOURCE=..\..\..\common\service\gsmsms.h +SOURCE=..\..\..\common\service\sms\gsmsms.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\common\service\sms\gsmems.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\common\service\sms\gsmmulti.h # End Source File # Begin Source File diff --git a/win32/dll/msvc6.mak/gammu.rc b/win32/dll/msvc6.mak/gammu.rc index 64d1cf941..44918013e 100644 --- a/win32/dll/msvc6.mak/gammu.rc +++ b/win32/dll/msvc6.mak/gammu.rc @@ -54,8 +54,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,90,0,0 - PRODUCTVERSION 0,90,0,0 + FILEVERSION 0,90,7,0 + PRODUCTVERSION 0,90,7,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -73,14 +73,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "http://www.mwiacek.com\0" VALUE "FileDescription", "Gammu DLL\0" - VALUE "FileVersion", "0,90,0,0\0" + VALUE "FileVersion", "0,90,7,0\0" VALUE "InternalName", "Gammu\0" VALUE "LegalCopyright", "Copyright © 2002 - 2003 by Marcin Wiacek\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "gammu.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Gammu (GNU All Mobile Management Utilities) DLL\0" - VALUE "ProductVersion", "0,90,0,0\0" + VALUE "ProductVersion", "0,90,7,0\0" VALUE "SpecialBuild", "\0" END END diff --git a/win32/dll/msvc7.mak/gammu.def b/win32/dll/msvc7.mak/gammu.def index 4c467b4a3..9a48cd615 100644 --- a/win32/dll/msvc7.mak/gammu.def +++ b/win32/dll/msvc7.mak/gammu.def @@ -28,3 +28,4 @@ EXPORTS mymakemultipartsms @21 mygetstructuresize @22 mygetdct4simlocknetwork @23 + mygetdct4securitycode @24 diff --git a/win32/dll/msvc7.mak/gammu.rc b/win32/dll/msvc7.mak/gammu.rc index 64d1cf941..44918013e 100644 --- a/win32/dll/msvc7.mak/gammu.rc +++ b/win32/dll/msvc7.mak/gammu.rc @@ -54,8 +54,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,90,0,0 - PRODUCTVERSION 0,90,0,0 + FILEVERSION 0,90,7,0 + PRODUCTVERSION 0,90,7,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -73,14 +73,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "http://www.mwiacek.com\0" VALUE "FileDescription", "Gammu DLL\0" - VALUE "FileVersion", "0,90,0,0\0" + VALUE "FileVersion", "0,90,7,0\0" VALUE "InternalName", "Gammu\0" VALUE "LegalCopyright", "Copyright © 2002 - 2003 by Marcin Wiacek\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "gammu.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Gammu (GNU All Mobile Management Utilities) DLL\0" - VALUE "ProductVersion", "0,90,0,0\0" + VALUE "ProductVersion", "0,90,7,0\0" VALUE "SpecialBuild", "\0" END END diff --git a/win32/dll/msvc7.mak/gammu.vcproj b/win32/dll/msvc7.mak/gammu.vcproj index eca111fb9..9a9c7c4ed 100644 --- a/win32/dll/msvc7.mak/gammu.vcproj +++ b/win32/dll/msvc7.mak/gammu.vcproj @@ -140,12 +140,18 @@ RelativePath="..\..\..\common\gsmcomon.c"> + + + + + RelativePath="..\..\..\common\service\sms\gsmsms.c"> @@ -297,12 +303,18 @@ RelativePath="..\..\..\common\gsmcomon.h"> + + + + + RelativePath="..\..\..\common\service\sms\gsmsms.h"> -- 2.11.4.GIT