diff options
author | Michal Čihař <michal@cihar.com> | 2011-02-10 15:32:59 +0100 |
---|---|---|
committer | Michal Čihař <michal@cihar.com> | 2011-02-10 15:32:59 +0100 |
commit | 66ce5a2dc79d6132a0db61f880782e56d4f8bfcf (patch) | |
tree | 60a4edadc2ad333cc9984f71f0a364bb7eab7c93 /libgammu | |
parent | a92feb0ede986fd672d2fc6d642ac93084c4da62 (diff) |
Imported Upstream version 1.29.90
Diffstat (limited to 'libgammu')
61 files changed, 4054 insertions, 456 deletions
diff --git a/libgammu/CMakeLists.txt b/libgammu/CMakeLists.txt index 004094f..890139a 100644 --- a/libgammu/CMakeLists.txt +++ b/libgammu/CMakeLists.txt @@ -45,6 +45,7 @@ set (LIBRARY_SRC protocol/nokia/phonet.c protocol/obex/obex.c protocol/symbian/gnapbus.c + protocol/s60/s60.c phone/pfunc.c phone/at/atgen.c phone/at/at-sms.c @@ -69,7 +70,8 @@ set (LIBRARY_SRC phone/nokia/nfuncold.c phone/obex/obexgen.c phone/obex/mobex.c - phone/symbian/gnapgen.c) + phone/symbian/gnapgen.c + phone/s60/s60phone.c) if (WITH_BACKUP) list (APPEND LIBRARY_SRC phone/dummy/dummy.c) diff --git a/libgammu/api.c b/libgammu/api.c index d9a56e2..3479a9b 100644 --- a/libgammu/api.c +++ b/libgammu/api.c @@ -1844,6 +1844,36 @@ GSM_Error GSM_SetGPRSAccessPoint(GSM_StateMachine *s, GSM_GPRSAccessPoint *point return err; } +/** + * Gets phone screenshot + */ +GSM_Error GSM_GetScreenshot(GSM_StateMachine *s, GSM_BinaryPicture *picture) +{ + GSM_Error err; + + CHECK_PHONE_CONNECTION(); + + picture->Length = 0; + picture->Buffer = NULL; + picture->Type = 0; + + err = s->Phone.Functions->GetScreenshot(s, picture); + PRINT_LOG_ERROR(err); + return err; +} + +/** + * Gets phone screenshot + */ +GSM_Error GSM_Install(GSM_StateMachine *s, const char *ExtraPath) +{ + GSM_Error err; + + err = s->Phone.Functions->Install(s, ExtraPath); + PRINT_LOG_ERROR(err); + return err; +} + /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/libgammu/device/bluetoth/bluetoth.c b/libgammu/device/bluetoth/bluetoth.c index 5739055..01a492a 100644 --- a/libgammu/device/bluetoth/bluetoth.c +++ b/libgammu/device/bluetoth/bluetoth.c @@ -76,6 +76,9 @@ GSM_Error bluetooth_findrfchannel(GSM_StateMachine *s) case GCT_BLUEPHONET: channel_id = 15; break; + case GCT_BLUES60: + channel_id = 18; + break; default: channel_id = 0; break; diff --git a/libgammu/device/devfunc.c b/libgammu/device/devfunc.c index ccf4a29..548e305 100644 --- a/libgammu/device/devfunc.c +++ b/libgammu/device/devfunc.c @@ -38,6 +38,10 @@ int bluetooth_checkservicename(GSM_StateMachine *s, const char *name) if (s->ConnectionType == GCT_BLUEPHONET) { if (strstr(name, "Nokia PC Suite") != NULL) return 1; + /* Series 60 remote */ + } else if (s->ConnectionType == GCT_BLUES60) { + if (strstr(name, "pys60_remote") != NULL) return 1; + /* OBEX */ } else if (s->ConnectionType == GCT_BLUEOBEX) { /* Prefer this on Nokia as this gives better access to filesystem */ diff --git a/libgammu/gsmcomon.c b/libgammu/gsmcomon.c index 9b565c6..2e672f8 100644 --- a/libgammu/gsmcomon.c +++ b/libgammu/gsmcomon.c @@ -150,6 +150,8 @@ static PrintErrorEntry PrintErrorEntries[] = { {ERR_COULDNT_CONNECT, "COULDNT_CONNECT", N_("Could not connect to the server.")}, {ERR_COULDNT_RESOLVE, "COULDNT_RESOLVE", N_("Could not resolve the host name.")}, {ERR_GETTING_SMSC, "GETTING_SMSC", N_("Failed to get SMSC number from phone.")}, + {ERR_ABORTED, "ABORTED", N_("Operation aborted.")}, + {ERR_INSTALL_NOT_FOUND, "INSTALL_NOT_FOUND", N_("Installation data not found, please consult debug log and/or documentation for more details.")}, {0, "", ""} }; diff --git a/libgammu/gsmphones.c b/libgammu/gsmphones.c index 3d0f35e..9d5f256 100644 --- a/libgammu/gsmphones.c +++ b/libgammu/gsmphones.c @@ -289,6 +289,7 @@ GSM_PhoneModel allmodels[] = { {"3600s" ,"RM-352","Nokia 3600s", {F_SERIES40_30,F_PBKTONEGAL,F_TODO66,F_PBKSMSLIST,F_PBKUSER,F_NOTES,F_CHAT,F_SYNCML,F_FILES2,0}},/* guess */ {"3720c","RM-518","Nokia 3720c",{F_SERIES40_30,F_PBKTONEGAL,F_TODO66,F_PBKSMSLIST,F_PBKUSER,F_NOTES,F_CHAT,F_SYNCML,F_FILES2,0}},/* guess */ {"5000", "RM-362","Nokia 5000", {F_SERIES40_30,F_FILES2,F_TODO66,F_RADIO,F_NOTES,F_SMS_FILES,0}},/* guess */ + {"5000d-2b", "RM-363","Nokia 5000d-2b", {F_SERIES40_30,F_FILES2,F_TODO66,F_RADIO,F_NOTES,F_SMS_FILES,0}},/* guess */ {"5100" ,"NPM-6" ,"Nokia 5100", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, {"5130" ,"RM-495","Nokia 5130", {F_SERIES40_30,F_FILES2,F_TODO66,F_RADIO,F_NOTES,F_SMS_FILES,0}},/* guess */ {"5100" ,"NPM-6U","Nokia 5100", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, @@ -396,6 +397,9 @@ GSM_PhoneModel allmodels[] = { {"9210" ,"RAE-3" ,"", {0}}, {"9210i","RAE-5" ,"", {0}}, #endif +#if defined(GSM_ENABLE_S90) || defined(GSM_ENABLE_ATGEN) + {"E52", "RM-469", "Nokia E52", {0}}, +#endif #ifdef GSM_ENABLE_ATGEN /* Generic AT */ {"at" , "at", "", {0}}, @@ -984,7 +988,7 @@ gboolean GSM_AddPhoneFeature(GSM_PhoneModel *model, GSM_Feature feature) } if (i == GSM_MAX_PHONE_FEATURES) return FALSE; model->features[i++] = feature; - model->features[i++] = 0; + model->features[i] = 0; return TRUE; } diff --git a/libgammu/gsmreply.h b/libgammu/gsmreply.h index ab334d5..ed3902e 100644 --- a/libgammu/gsmreply.h +++ b/libgammu/gsmreply.h @@ -78,12 +78,14 @@ typedef enum { ID_SetMemory, ID_DeleteMemory, ID_SetCalendarNote, + ID_AddCalendarNote, ID_SetIncomingSMS, ID_SetIncomingCB, ID_SetIncomingCall, ID_GetCNMIMode, ID_GetCalendarNotePos, ID_Initialise, + ID_Terminate, ID_GetConnectSet, ID_SetWAPBookmark, ID_GetLocale, @@ -118,12 +120,14 @@ typedef enum { ID_GetLanguage, ID_SetFastSMSSending, ID_Reset, + ID_GetToDoInfo, ID_GetToDo, ID_PressKey, ID_DeleteAllToDo, ID_SetLight, ID_Divert, ID_SetToDo, + ID_AddToDo, ID_PlayTone, ID_GetChatSettings, ID_GetSyncMLSettings, @@ -149,6 +153,8 @@ typedef enum { ID_DeleteFile, ID_ModeSwitch, ID_GetProtocol, + ID_Screenshot, + ID_GetScreenSize, /* Alcatel AT mode */ ID_SetFlowControl, @@ -230,7 +236,7 @@ typedef struct { /** * Subtype to be checked. */ - const unsigned char subtype; + const int subtype; /** * Phone request when this can be called, use ID_IncomingFrame when * you want to use this in any state. diff --git a/libgammu/gsmstate.c b/libgammu/gsmstate.c index 637af15..375844d 100644 --- a/libgammu/gsmstate.c +++ b/libgammu/gsmstate.c @@ -135,6 +135,8 @@ static const GSM_ConnectionInfo GSM_Connections[] = { {"bluerfphonet", GCT_BLUEPHONET, FALSE}, {"bluerfat", GCT_BLUEAT, FALSE}, {"bluerfgnapbus", GCT_BLUEGNAPBUS, FALSE}, + {"blues60", GCT_BLUES60, FALSE}, + {"bluerfs60", GCT_BLUES60, FALSE}, /* old "serial" irda */ {"infrared", GCT_FBUS2IRDA, FALSE}, @@ -286,6 +288,9 @@ static GSM_Error GSM_RegisterAllConnections(GSM_StateMachine *s, const char *con GSM_RegisterConnection(s, GCT_IRDAOBEX, &IrdaDevice, &OBEXProtocol); #endif #ifdef GSM_ENABLE_BLUEGNAPBUS + GSM_RegisterConnection(s, GCT_BLUES60, &BlueToothDevice,&S60Protocol); +#endif +#ifdef GSM_ENABLE_BLUEGNAPBUS GSM_RegisterConnection(s, GCT_BLUEGNAPBUS,&BlueToothDevice,&GNAPBUSProtocol); #endif #ifdef GSM_ENABLE_BLUEFBUS2 @@ -387,6 +392,13 @@ GSM_Error GSM_RegisterAllPhoneModules(GSM_StateMachine *s) return ERR_NONE; } #endif +#ifdef GSM_ENABLE_S60 + if (s->ConnectionType == GCT_BLUES60) { + smprintf(s,"[Module - \"%s\"]\n",S60Phone.models); + s->Phone.Functions = &S60Phone; + return ERR_NONE; + } +#endif #ifdef GSM_ENABLE_NOKIA6510 if ( s->ConnectionType == GCT_MBUS2 || @@ -458,6 +470,9 @@ GSM_Error GSM_RegisterAllPhoneModules(GSM_StateMachine *s) #ifdef GSM_ENABLE_GNAPGEN GSM_RegisterModule(s,&GNAPGENPhone); #endif +#ifdef GSM_ENABLE_S60 + GSM_RegisterModule(s,&S60Phone); +#endif #ifdef GSM_ENABLE_NOKIA3320 GSM_RegisterModule(s,&N3320Phone); #endif @@ -594,6 +609,11 @@ GSM_Error GSM_TryGetModel(GSM_StateMachine *s) s->Phone.Functions = &GNAPGENPhone; break; #endif +#ifdef GSM_ENABLE_S60 + case GCT_BLUES60: + s->Phone.Functions = &S60Phone; + break; +#endif #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4) case GCT_MBUS2: case GCT_FBUS2: @@ -723,7 +743,18 @@ GSM_Error GSM_InitConnection_Log(GSM_StateMachine *s, int ReplyNum, GSM_Log_Func autodetect: /* Model auto */ - if (s->CurrentConfig->Model[0] == 0) { + /* Try to guess correct driver based on model */ + if (s->CurrentConfig->Model[0] == 0 && + s->ConnectionType != GCT_NONE && + s->ConnectionType != GCT_IRDAOBEX && + s->ConnectionType != GCT_BLUEOBEX && + s->ConnectionType != GCT_BLUEGNAPBUS && + s->ConnectionType != GCT_IRDAGNAPBUS && + s->ConnectionType != GCT_DKU2AT && + s->ConnectionType != GCT_AT && + s->ConnectionType != GCT_IRDAAT && + s->ConnectionType != GCT_BLUEAT && + s->ConnectionType != GCT_BLUES60) { error = GSM_TryGetModel(s); if ((i != s->ConfigNum - 1) && ( (error == ERR_DEVICEOPENERROR) || @@ -843,7 +874,7 @@ int GSM_ReadDevice (GSM_StateMachine *s, gboolean waitforreply) GSM_GetCurrentDateTime (&Date); i=Date.Second; - while (i==Date.Second) { + while (i==Date.Second && !s->Abort) { res = s->Device.Functions->ReadDevice(s, buff, sizeof(buff)); if (!waitforreply) { @@ -865,7 +896,7 @@ GSM_Error GSM_TerminateConnection(GSM_StateMachine *s) { GSM_Error error; - if (!s->opened) return ERR_UNKNOWN; + if (!s->opened) return ERR_NONE; smprintf(s,"[Terminating]\n"); @@ -892,8 +923,14 @@ gboolean GSM_IsConnected(GSM_StateMachine *s) { return (s != NULL) && s->Phone.Functions != NULL && s->opened; } +GSM_Error GSM_AbortOperation(GSM_StateMachine * s) +{ + s->Abort = TRUE; + return ERR_NONE; +} + GSM_Error GSM_WaitForOnce(GSM_StateMachine *s, unsigned const char *buffer, - int length, unsigned char type, int timeout) + int length, int type, int timeout) { GSM_Phone_Data *Phone = &s->Phone.Data; GSM_Protocol_Message sentmsg; @@ -912,6 +949,9 @@ GSM_Error GSM_WaitForOnce(GSM_StateMachine *s, unsigned const char *buffer, if (GSM_ReadDevice(s, TRUE) > 0) { i = 0; } else { + if (s->Abort) { + return ERR_ABORTED; + } usleep(10000); } @@ -932,7 +972,7 @@ GSM_Error GSM_WaitForOnce(GSM_StateMachine *s, unsigned const char *buffer, } GSM_Error GSM_WaitFor (GSM_StateMachine *s, unsigned const char *buffer, - int length, unsigned char type, int timeout, + int length, int type, int timeout, GSM_Phone_RequestID request) { GSM_Phone_Data *Phone = &s->Phone.Data; @@ -956,6 +996,11 @@ GSM_Error GSM_WaitFor (GSM_StateMachine *s, unsigned const char *buffer, error = s->Protocol.Functions->WriteMessage(s, buffer, length, type); if (error!=ERR_NONE) return error; + /* Special case when no reply is expected */ + if (request == ID_None) { + return ERR_NONE; + } + error = GSM_WaitForOnce(s, buffer, length, type, timeout); if (error != ERR_TIMEOUT) return error; } @@ -973,8 +1018,13 @@ static GSM_Error CheckReplyFunctions(GSM_StateMachine *s, GSM_Reply_Function *Re while (Reply[i].requestID!=ID_None) { execute=FALSE; + /* Long ID frames like S60 */ + if (Reply[i].msgtype[0] == 0 && Reply[i].subtypechar == 0) { + if (Reply[i].subtype == msg->Type) { + execute = TRUE; + } /* Binary frames like in Nokia */ - if (strlen(Reply[i].msgtype) < 2) { + } else if (strlen(Reply[i].msgtype) < 2) { if (Reply[i].msgtype[0]==msg->Type) { if (Reply[i].subtypechar!=0) { if (Reply[i].subtypechar<=msg->Length) { @@ -1235,10 +1285,10 @@ GSM_Error GSM_ReadConfig(INI_Section *cfg_info, GSM_Config *cfg, int num) #if defined(WIN32) || defined(DJGPP) static const char *DefaultPort = "com2:"; #else - static const char *DefaultPort = "/dev/ttyS1"; + static const char *DefaultPort = "/dev/ttyACM0"; #endif static const char *DefaultModel = ""; - static const char *DefaultConnection = "fbus"; + static const char *DefaultConnection = "at"; static gboolean DefaultSynchronizeTime = FALSE; static const char *DefaultDebugFile = ""; static const char *DefaultDebugLevel = ""; @@ -1655,6 +1705,7 @@ GSM_StateMachine *GSM_AllocStateMachine(void) GSM_StateMachine *ret; ret = (GSM_StateMachine *)calloc(1, sizeof(GSM_StateMachine)); ret->CurrentConfig = &(ret->Config[0]); + ret->Abort = FALSE; return ret; } diff --git a/libgammu/gsmstate.h b/libgammu/gsmstate.h index 6e5fe98..e914bde 100644 --- a/libgammu/gsmstate.h +++ b/libgammu/gsmstate.h @@ -66,6 +66,9 @@ typedef struct _GSM_User GSM_User; #ifdef GSM_ENABLE_GNAPGEN # include "phone/symbian/gnapgen.h" #endif +#ifdef GSM_ENABLE_S60 +# include "phone/s60/s60phone.h" +#endif # include "phone/dummy/dummy.h" #ifndef GSM_USED_MBUS2 @@ -151,6 +154,9 @@ typedef struct _GSM_User GSM_User; #if defined(GSM_ENABLE_BLUEGNAPBUS) || defined(GSM_ENABLE_IRDAGNAPBUS) # include "protocol/symbian/gnapbus.h" #endif +#if defined(GSM_ENABLE_S60) +# include "protocol/s60/s60.h" +#endif #define GSM_ENABLE_SERIALDEVICE #ifndef GSM_USED_SERIALDEVICE @@ -321,7 +327,7 @@ typedef struct { * Writes message to device. */ GSM_Error (*WriteMessage) (GSM_StateMachine *s, unsigned const char *buffer, - int length, unsigned char type); + int length, int type); /** * This one is called when character is received from device. */ @@ -357,6 +363,9 @@ typedef struct { #if defined(GSM_ENABLE_BLUEGNAPBUS) || defined(GSM_ENABLE_IRDAGNAPBUS) extern GSM_Protocol_Functions GNAPBUSProtocol; #endif +#if defined(GSM_ENABLE_S60) + extern GSM_Protocol_Functions S60Protocol; +#endif /** * Structure containing protocol specific data and pointer to protocol @@ -387,6 +396,9 @@ typedef struct { #if defined(GSM_ENABLE_BLUEGNAPBUS) || defined(GSM_ENABLE_IRDAGNAPBUS) GSM_Protocol_GNAPBUSData GNAPBUS; #endif +#if defined(GSM_ENABLE_S60) + GSM_Protocol_S60Data S60; +#endif } Data; /** * Functions for currently used protocol layer. @@ -522,6 +534,10 @@ typedef struct { */ GSM_CalendarStatus *CalStatus; /** + * Todo status. + */ + GSM_ToDoStatus *ToDoStatus; + /** * Used internally by phone drivers. */ unsigned char *SecurityCode; @@ -554,6 +570,10 @@ typedef struct { */ GSM_NoteEntry *Note; /** + * Pointer to picture structure used internally by phone drivers. + */ + GSM_BinaryPicture *Picture; + /** * Used internally by phone drivers. */ gboolean PressKey; @@ -687,6 +707,9 @@ typedef struct { #ifdef GSM_ENABLE_GNAPGEN GSM_Phone_GNAPGENData GNAPGEN; #endif +#ifdef GSM_ENABLE_S60 + GSM_Phone_S60Data S60; +#endif GSM_Phone_DUMMYData DUMMY; } Priv; } GSM_Phone_Data; @@ -706,6 +729,10 @@ typedef struct { */ GSM_Reply_Function *ReplyFunctions; /** + * Installs required applets to the phone. + */ + GSM_Error (*Install) (GSM_StateMachine *s, const char *ExtraPath); + /** * Initializes phone. */ GSM_Error (*Initialise) (GSM_StateMachine *s); @@ -1254,6 +1281,10 @@ typedef struct { * Sets GPRS access point. */ GSM_Error (*SetGPRSAccessPoint) (GSM_StateMachine *s, GSM_GPRSAccessPoint *point); + /** + * Gets phone screenshot + */ + GSM_Error (*GetScreenshot) (GSM_StateMachine *s, GSM_BinaryPicture *picture); } GSM_Phone_Functions; extern GSM_Phone_Functions NAUTOPhone; @@ -1293,6 +1324,9 @@ typedef struct { #ifdef GSM_ENABLE_GNAPGEN extern GSM_Phone_Functions GNAPGENPhone; #endif +#ifdef GSM_ENABLE_S60 + extern GSM_Phone_Functions S60Phone; +#endif extern GSM_Phone_Functions DUMMYPhone; /** @@ -1353,6 +1387,11 @@ struct _GSM_StateMachine { int ReplyNum; /**< How many times make sth. */ int Speed; /**< For some protocols used speed */ + /** + * Flag for interrupting communication. + */ + volatile gboolean Abort; + GSM_Device Device; /**< Device driver data and functions */ GSM_Protocol Protocol; /**< Protocol driver data and functions */ GSM_Phone Phone; /**< Phone driver data and functions */ @@ -1371,7 +1410,7 @@ struct _GSM_StateMachine { GSM_Error GSM_RegisterAllPhoneModules (GSM_StateMachine *s); GSM_Error GSM_WaitForOnce (GSM_StateMachine *s, unsigned const char *buffer, - int length, unsigned char type, int timeout); + int length, int type, int timeout); /** * Wait for reply from the phone. @@ -1386,7 +1425,7 @@ GSM_Error GSM_WaitForOnce (GSM_StateMachine *s, unsigned const char *buffer, * \return Error code, ERR_NONE on sucecss. */ GSM_Error GSM_WaitFor (GSM_StateMachine *s, unsigned const char *buffer, - int length, unsigned char type, int timeout, + int length, int type, int timeout, GSM_Phone_RequestID request) WARNUNUSED; /** diff --git a/libgammu/misc/coding/coding.c b/libgammu/misc/coding/coding.c index f87e73d..0d27aff 100644 --- a/libgammu/misc/coding/coding.c +++ b/libgammu/misc/coding/coding.c @@ -327,7 +327,7 @@ void DecodeBCD (unsigned char *dest, const unsigned char *src, int len) digit=src[i] >> 4; if (digit<10) dest[current++]=digit + '0'; } - dest[current++]=0; + dest[current]=0; } void EncodeBCD (unsigned char *dest, const unsigned char *src, int len, gboolean fill) @@ -383,7 +383,7 @@ void DecodeHexUnicode (unsigned char *dest, const char *src, size_t len) DecodeWithHexBinAlphabet(src[i + 3]); } dest[current++] = 0; - dest[current++] = 0; + dest[current] = 0; } void EncodeHexUnicode (char *dest, const unsigned char *src, size_t len) @@ -401,7 +401,7 @@ gboolean DecodeHexBin (unsigned char *dest, const unsigned char *src, int len) if (low < 0 || high < 0) return FALSE; dest[current++] = (high << 4) | low; } - dest[current++] = 0; + dest[current] = 0; return TRUE; } @@ -413,7 +413,7 @@ void EncodeHexBin (char *dest, const unsigned char *src, size_t len) dest[outpos++] = EncodeWithHexBinAlphabet(src[i] >> 4); dest[outpos++] = EncodeWithHexBinAlphabet(src[i] & 0xF); } - dest[outpos++] = 0; + dest[outpos] = 0; } /* ETSI GSM 03.38, section 6.2.1: Default alphabet for SMS messages */ @@ -517,7 +517,7 @@ void DecodeDefault (unsigned char *dest, const unsigned char *src, size_t len, g dest[current++] = GSM_DefaultAlphabetUnicode[src[pos]][1]; } dest[current++]=0; - dest[current++]=0; + dest[current]=0; #ifdef DEBUG DumpMessageText(&GSM_global_debug, dest, UnicodeLength(dest)*2); #endif @@ -734,16 +734,22 @@ int GSM_PackSevenBitsToEight(int offset, const unsigned char *input, unsigned ch return (output_pos - output); } -int GSM_UnpackSemiOctetNumber(GSM_Debug_Info *di, unsigned char *retval, const unsigned char *Number, gboolean semioctet) +GSM_Error GSM_UnpackSemiOctetNumber(GSM_Debug_Info *di, unsigned char *retval, const unsigned char *Number, size_t *pos, size_t bufferlength, gboolean semioctet) { unsigned char Buffer[GSM_MAX_NUMBER_LENGTH + 1]; - int length = Number[0]; + size_t length = Number[*pos]; + GSM_Error ret = ERR_NONE; - smfprintf(di, "Number Length=%d\n", length); + smfprintf(di, "Number Length=%ld\n", (long)length); /* Default ouput on error */ strcpy(Buffer, "<NOT DECODED>"); + if (length > bufferlength) { + smfprintf(di, "Number too long!\n"); + return ERR_UNKNOWN; + } + if (semioctet) { /* Convert number of semioctets to number of chars */ if (length % 2) length++; @@ -752,48 +758,50 @@ int GSM_UnpackSemiOctetNumber(GSM_Debug_Info *di, unsigned char *retval, const u /* Check length */ if (length > GSM_MAX_NUMBER_LENGTH) { - smfprintf(di, "Number too big, not decoding! (Length=%d, MAX=%d)\n", length, GSM_MAX_NUMBER_LENGTH); + smfprintf(di, "Number too big, not decoding! (Length=%ld, MAX=%d)\n", (long)length, GSM_MAX_NUMBER_LENGTH); + ret = ERR_UNKNOWN; goto out; } /*without leading byte with format of number*/ length--; - switch ((Number[1] & 0x70)) { + switch ((Number[*pos + 1] & 0x70)) { case (NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN & 0x70): if (length > 6) length++; - smfprintf(di, "Alphanumeric number, length %i\n",length); - GSM_UnpackEightBitsToSeven(0, length, length, Number+2, Buffer); + smfprintf(di, "Alphanumeric number, length %ld\n", (long)length); + GSM_UnpackEightBitsToSeven(0, length, length, Number+*pos+2, Buffer); Buffer[length]=0; break; case (NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN & 0x70): smfprintf(di, "International number\n"); Buffer[0]='+'; - DecodeBCD(Buffer+1,Number+2, length); + DecodeBCD(Buffer+1,Number+*pos+2, length); break; default: - smfprintf(di, "Default number %02x (%d %d %d %d|%d %d %d %d)\n",Number[1], - Number[1] & 0x80 ? 1 : 0, - Number[1] & 0x40 ? 1 : 0, - Number[1] & 0x20 ? 1 : 0, - Number[1] & 0x10 ? 1 : 0, - Number[1] & 0x08 ? 1 : 0, - Number[1] & 0x04 ? 1 : 0, - Number[1] & 0x02 ? 1 : 0, - Number[1] & 0x01 ? 1 : 0 + smfprintf(di, "Default number %02x (%d %d %d %d|%d %d %d %d)\n",Number[*pos], + Number[*pos] & 0x80 ? 1 : 0, + Number[*pos] & 0x40 ? 1 : 0, + Number[*pos] & 0x20 ? 1 : 0, + Number[*pos] & 0x10 ? 1 : 0, + Number[*pos] & 0x08 ? 1 : 0, + Number[*pos] & 0x04 ? 1 : 0, + Number[*pos] & 0x02 ? 1 : 0, + Number[*pos] & 0x01 ? 1 : 0 ); - DecodeBCD (Buffer, Number+2, length); + DecodeBCD (Buffer, Number+*pos+2, length); break; } - smfprintf(di, "Len %i\n",length); + smfprintf(di, "Len %ld\n", (long)length); out: EncodeUnicode(retval,Buffer,strlen(Buffer)); if (semioctet) { - return 2 + ((Number[0] + 1) / 2); + *pos += 2 + ((Number[*pos] + 1) / 2); } else { - return 1 + Number[0]; + *pos += 1 + Number[*pos]; } + return ret; } /** @@ -931,7 +939,7 @@ void ReadUnicodeFile(unsigned char *Dest, const unsigned char *Source) j=j+2; } Dest[current++] = 0; - Dest[current++] = 0; + Dest[current] = 0; } INLINE int GetBit(unsigned char *Buffer, size_t BitNum) @@ -1089,7 +1097,7 @@ void EncodeUnicodeSpecialNOKIAChars(unsigned char *dest, const unsigned char *sr dest[current++] = 0x01; } dest[current++] = 0x00; - dest[current++] = 0x00; + dest[current] = 0x00; } void DecodeUnicodeSpecialNOKIAChars(unsigned char *dest, const unsigned char *src, int len) @@ -1121,7 +1129,7 @@ void DecodeUnicodeSpecialNOKIAChars(unsigned char *dest, const unsigned char *sr } } dest[current++] = 0x00; - dest[current++] = 0x00; + dest[current] = 0x00; } @@ -1484,7 +1492,7 @@ gboolean EncodeUTF8QuotedPrintable(char *dest, const unsigned char *src) } } } - dest[j++]=0; + dest[j]=0; return retval; } @@ -1504,7 +1512,7 @@ gboolean EncodeUTF8(char *dest, const unsigned char *src) j+= DecodeWithUnicodeAlphabet(((wchar_t)(src[i*2]*256+src[i*2+1])), dest + j); } } - dest[j++]=0; + dest[j]=0; return retval; } @@ -1550,7 +1558,7 @@ void DecodeISO88591QuotedPrintable(unsigned char *dest, const unsigned char *src i++; } dest[j++] = 0; - dest[j++] = 0; + dest[j] = 0; } /* Make Unicode string from UTF8 string */ @@ -1586,7 +1594,7 @@ void DecodeUTF8QuotedPrintable(unsigned char *dest, const char *src, int len) dest[j++] = ret & 0xff; } dest[j++] = 0; - dest[j++] = 0; + dest[j] = 0; } void DecodeUTF8(unsigned char *dest, const char *src, int len) @@ -1605,7 +1613,7 @@ void DecodeUTF8(unsigned char *dest, const char *src, int len) dest[j++] = ret & 0xff; } dest[j++] = 0; - dest[j++] = 0; + dest[j] = 0; } void DecodeXMLUTF8(unsigned char *dest, const char *src, int len) @@ -1624,10 +1632,14 @@ void DecodeXMLUTF8(unsigned char *dest, const char *src, int len) DecodeUTF8(dest, src, len); return; } + if (src == NULL) { + *dest = 0; + return; + } /* Find ampersand and decode the */ lastpos = src; - while ((lastpos != 0) && ((pos = strchr(lastpos, '&')) != NULL)) { + while ((*lastpos != 0) && ((pos = strchr(lastpos, '&')) != NULL)) { /* Store current string */ strncat(tmp, lastpos, pos - lastpos); lastpos = pos; @@ -1714,7 +1726,7 @@ void DecodeUTF7(unsigned char *dest, const unsigned char *src, int len) } } dest[j++] = 0; - dest[j++] = 0; + dest[j] = 0; } /* @@ -1776,7 +1788,7 @@ void EncodeBASE64(const unsigned char *Input, char *Output, const size_t Length) } } - Output[outpos++] = 0; + Output[outpos] = 0; } static void DecodeBASE64Block(const char in[4], unsigned char out[3]) diff --git a/libgammu/misc/coding/coding.h b/libgammu/misc/coding/coding.h index 8b1c90b..ac4a727 100644 --- a/libgammu/misc/coding/coding.h +++ b/libgammu/misc/coding/coding.h @@ -101,7 +101,8 @@ typedef enum { /* specification give also other values */ } GSM_NumberType; -int GSM_UnpackSemiOctetNumber(GSM_Debug_Info *di, unsigned char *retval, const unsigned char *Number, gboolean semioctet); +//int GSM_UnpackSemiOctetNumber(GSM_Debug_Info *di, unsigned char *retval, const unsigned char *Number, gboolean semioctet); +GSM_Error GSM_UnpackSemiOctetNumber(GSM_Debug_Info *di, unsigned char *retval, const unsigned char *Number, size_t *pos, size_t bufferlength, gboolean semioctet); int GSM_PackSemiOctetNumber (const unsigned char *Number, unsigned char *Output, gboolean semioctet); /* ---------------------------- Bits --------------------------------------- */ diff --git a/libgammu/misc/misc.c b/libgammu/misc/misc.c index 8576a31..31a2e9a 100644 --- a/libgammu/misc/misc.c +++ b/libgammu/misc/misc.c @@ -151,6 +151,21 @@ int GSM_GetLocalTimezoneOffset() { return (tl->tm_hour - tg->tm_hour) * 3600 + (tl->tm_min - tg->tm_min) * 60 + (tl->tm_sec - tg->tm_sec); } +void GSM_DateTimeToTimestamp(GSM_DateTime *Date, char *str) +{ + time_t timet; + timet = Fill_Time_T(*Date); + sprintf(str, "%ld", (long)timet); +} + +void GSM_DateTimeFromTimestamp(GSM_DateTime *Date, const char *str) +{ + time_t timet; + + timet = atof(str); + Fill_GSM_DateTime(Date, timet); +} + void Fill_GSM_DateTime(GSM_DateTime *Date, time_t timet) { struct tm *now; @@ -186,7 +201,11 @@ time_t Fill_Time_T(GSM_DateTime DT) tzset(); +#ifdef HAVE_DAYLIGHT tm_starttime.tm_isdst = daylight; +#else + tm_starttime.tm_isdst = -1; +#endif #ifdef HAVE_STRUCT_TM_TM_ZONE /* No time zone information */ tm_starttime.tm_gmtoff = timezone; diff --git a/libgammu/phone/alcatel/alcatel.c b/libgammu/phone/alcatel/alcatel.c index 83595fa..5e8c65b 100644 --- a/libgammu/phone/alcatel/alcatel.c +++ b/libgammu/phone/alcatel/alcatel.c @@ -760,7 +760,6 @@ static GSM_Error ALCATEL_GetAvailableIds(GSM_StateMachine *s, gboolean refresh) if (error != ERR_NONE) return error; } - i = 0; smprintf(s,"Received %d ids: ", *Priv->CurrentCount); for (i=0; i < *Priv->CurrentCount; i++) { smprintf(s,"%x ", (*Priv->CurrentList)[i]); @@ -831,7 +830,6 @@ static GSM_Error ALCATEL_GetFields(GSM_StateMachine *s, int id) { error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetFields2); if (error != ERR_NONE) return error; - i = 0; smprintf(s,"Received %d fields: ", Priv->CurrentFieldsCount); for (i=0; i < Priv->CurrentFieldsCount; i++) { smprintf(s,"%x ", Priv->CurrentFields[i]); @@ -1084,7 +1082,6 @@ static GSM_Error ALCATEL_GetAvailableCategoryIds(GSM_StateMachine *s) { error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetCategories2); if (error != ERR_NONE) return error; - i = 0; smprintf(s,"Received %d ids: ", Priv->CurrentCategoriesCount); for (i=0; i < Priv->CurrentCategoriesCount; i++) { smprintf(s,"%i ", Priv->CurrentCategories[i]); @@ -1506,6 +1503,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_LastName; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 1: @@ -1516,6 +1514,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_FirstName; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 2: @@ -1526,6 +1525,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_Company; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 3: @@ -1536,6 +1536,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_JobTitle; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 4: @@ -1546,6 +1547,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_Note; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 5: @@ -1556,6 +1558,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Category; + entry->Entries[i - j].Location = PBK_Location_Unknown; entry->Entries[i - j].Number = Priv->ReturnInt; break; case 6: @@ -1566,6 +1569,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Private; + entry->Entries[i - j].Location = PBK_Location_Unknown; entry->Entries[i - j].Number = Priv->ReturnInt; break; case 7: @@ -1575,7 +1579,8 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) j++; break; } - entry->Entries[i - j].EntryType = PBK_Number_Work; + entry->Entries[i - j].EntryType = PBK_Number_General; + entry->Entries[i - j].Location = PBK_Location_Work; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 8: @@ -1596,6 +1601,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Number_Fax; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 10: @@ -1606,6 +1612,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Number_Other; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 11: @@ -1616,6 +1623,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Number_Pager; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 12: @@ -1626,6 +1634,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Number_Mobile; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 13: @@ -1635,7 +1644,8 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) j++; break; } - entry->Entries[i - j].EntryType = PBK_Number_Home; + entry->Entries[i - j].EntryType = PBK_Number_General; + entry->Entries[i - j].Location = PBK_Location_Home; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 14: @@ -1646,6 +1656,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_Email; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 15: @@ -1656,6 +1667,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_Email2; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 16: @@ -1666,6 +1678,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_StreetAddress; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 17: @@ -1676,6 +1689,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_City; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 18: @@ -1686,6 +1700,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_State; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 19: @@ -1696,6 +1711,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_Zip; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 20: @@ -1706,6 +1722,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_Country; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 21: @@ -1716,6 +1733,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_Custom1; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 22: @@ -1726,6 +1744,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_Custom2; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 23: @@ -1736,6 +1755,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_Custom3; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 24: @@ -1746,6 +1766,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; } entry->Entries[i - j].EntryType = PBK_Text_Custom4; + entry->Entries[i - j].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString); break; case 25: @@ -1757,6 +1778,7 @@ static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) } if (Priv->ReturnInt != 0) { entry->Entries[i - j].EntryType = PBK_PictureID; + entry->Entries[i - j].Location = PBK_Location_Unknown; entry->Entries[i - j].Number = Priv->ReturnInt; } else { entry->EntriesNum--; @@ -1831,20 +1853,24 @@ static GSM_Error ALCATEL_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) entry->Entries[i].AddError = ERR_NONE; switch (entry->Entries[i].EntryType) { case PBK_Number_General: - if ((error = ALCATEL_CreateField(s, Alcatel_phone, 8, entry->Entries[i].Text)) != ERR_NONE) return error; + switch (entry->Entries[i].Location) { + case PBK_Location_Unknown: + if ((error = ALCATEL_CreateField(s, Alcatel_phone, 8, entry->Entries[i].Text)) != ERR_NONE) return error; + break; + case PBK_Location_Work: + if ((error = ALCATEL_CreateField(s, Alcatel_phone, 7, entry->Entries[i].Text)) != ERR_NONE) return error; + break; + case PBK_Location_Home: + if ((error = ALCATEL_CreateField(s, Alcatel_phone, 13, entry->Entries[i].Text)) != ERR_NONE) return error; + break; + } break; case PBK_Number_Mobile: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 12, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Number_Work: - if ((error = ALCATEL_CreateField(s, Alcatel_phone, 7, entry->Entries[i].Text)) != ERR_NONE) return error; - break; case PBK_Number_Fax: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Number_Home: - if ((error = ALCATEL_CreateField(s, Alcatel_phone, 13, entry->Entries[i].Text)) != ERR_NONE) return error; - break; case PBK_Number_Pager: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 11, entry->Entries[i].Text)) != ERR_NONE) return error; break; @@ -1926,21 +1952,22 @@ static GSM_Error ALCATEL_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) case PBK_Text_Postal: case PBK_Text_URL: case PBK_Text_LUID: + case PBK_Text_VOIP: + case PBK_Text_SWIS: + case PBK_Text_WVID: + case PBK_Text_SIP: + case PBK_Text_DTMF: case PBK_CallLength: case PBK_Text_NickName: case PBK_Text_FormalName: - case PBK_Text_WorkPostal: - case PBK_Text_WorkStreetAddress: - case PBK_Text_WorkCity: - case PBK_Text_WorkState: - case PBK_Text_WorkZip: - case PBK_Text_WorkCountry: + case PBK_Text_NameSuffix: + case PBK_Text_NamePrefix: case PBK_Text_PictureName: case PBK_PushToTalkID: case PBK_Number_Messaging: + case PBK_Number_Video: case PBK_Photo: - case PBK_Number_Mobile_Work: - case PBK_Number_Mobile_Home: + case PBK_Text_SecondName: entry->Entries[i].AddError = ERR_NOTSUPPORTED; smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType); break; @@ -1994,25 +2021,29 @@ static GSM_Error ALCATEL_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) entry->Entries[i].AddError = ERR_NONE; switch (entry->Entries[i].EntryType) { case PBK_Number_General: - UpdatedFields[8] = TRUE; - if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 8, entry->Entries[i].Text)) != ERR_NONE) return error; + switch (entry->Entries[i].Location) { + case PBK_Location_Unknown: + UpdatedFields[8] = TRUE; + if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 8, entry->Entries[i].Text)) != ERR_NONE) return error; + break; + case PBK_Location_Work: + UpdatedFields[7] = TRUE; + if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 7, entry->Entries[i].Text)) != ERR_NONE) return error; + break; + case PBK_Location_Home: + UpdatedFields[13] = TRUE; + if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 13, entry->Entries[i].Text)) != ERR_NONE) return error; + break; + } break; case PBK_Number_Mobile: UpdatedFields[12] = TRUE; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 12, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Number_Work: - UpdatedFields[7] = TRUE; - if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 7, entry->Entries[i].Text)) != ERR_NONE) return error; - break; case PBK_Number_Fax: UpdatedFields[9] = TRUE; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 9, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Number_Home: - UpdatedFields[13] = TRUE; - if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 13, entry->Entries[i].Text)) != ERR_NONE) return error; - break; case PBK_Number_Pager: UpdatedFields[11] = TRUE; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 11, entry->Entries[i].Text)) != ERR_NONE) return error; @@ -2112,21 +2143,22 @@ static GSM_Error ALCATEL_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) case PBK_Text_Postal: case PBK_Text_URL: case PBK_Text_LUID: + case PBK_Text_VOIP: + case PBK_Text_SWIS: + case PBK_Text_WVID: + case PBK_Text_SIP: + case PBK_Text_DTMF: case PBK_CallLength: case PBK_Text_NickName: case PBK_Text_FormalName: - case PBK_Text_WorkPostal: - case PBK_Text_WorkStreetAddress: - case PBK_Text_WorkCity: - case PBK_Text_WorkState: - case PBK_Text_WorkZip: - case PBK_Text_WorkCountry: + case PBK_Text_NameSuffix: + case PBK_Text_NamePrefix: case PBK_Text_PictureName: case PBK_PushToTalkID: case PBK_Number_Messaging: + case PBK_Number_Video: case PBK_Photo: - case PBK_Number_Mobile_Work: - case PBK_Number_Mobile_Home: + case PBK_Text_SecondName: entry->Entries[i].AddError = ERR_NOTSUPPORTED; smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType); break; @@ -4031,6 +4063,7 @@ GSM_Phone_Functions ALCATELPhone = { */ "alcatel|OT501|OT701|OT715|OT535|OT735|BE5|BF5|BH4", ALCATELReplyFunctions, + NOTSUPPORTED, /* Install */ ALCATEL_Initialise, ALCATEL_Terminate, ALCATEL_DispatchMessage, @@ -4165,7 +4198,8 @@ GSM_Phone_Functions ALCATELPhone = { NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/phone/at/at-sms.c b/libgammu/phone/at/at-sms.c index c01527e..9aa4f7f 100644 --- a/libgammu/phone/at/at-sms.c +++ b/libgammu/phone/at/at-sms.c @@ -152,6 +152,7 @@ completed: return ERR_NONE; case AT_Reply_Error: + return ERR_NOTSUPPORTED; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); case AT_Reply_CMEError: @@ -561,7 +562,7 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s GetLineString(msg.Buffer, &Priv->Lines, 2), "+CMGR: @r, @p, @d", buffer, sizeof(buffer), sms->Number, sizeof(sms->Number), - &sms->DateTime, sizeof(sms->DateTime)); + &sms->DateTime); if (error != ERR_NONE) { return error; @@ -1143,10 +1144,12 @@ GSM_Error ATGEN_GetNextSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboole /* Get list of messages */ error = ATGEN_GetSMSList(s, TRUE); + } else { + error = ERR_NONE; } /* Use listed locations if we have them */ - if (Priv->SMSCache != NULL) { + if (error == ERR_NONE && Priv->SMSCache != NULL) { if (start) { found = 0; } else { @@ -1416,14 +1419,14 @@ GSM_Error ATGEN_ReplyAddSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s size_t i = 0; int folder = 0; - if (s->Protocol.Data.AT.EditMode) { - if (Priv->ReplyState != AT_Reply_SMSEdit) { - return ATGEN_HandleCMSError(s); - } - s->Protocol.Data.AT.EditMode = FALSE; - return ERR_NONE; - } switch (Priv->ReplyState) { + case AT_Reply_SMSEdit: + if (s->Protocol.Data.AT.EditMode) { + s->Protocol.Data.AT.EditMode = FALSE; + return ERR_NONE; + } + smprintf(s, "Received unexpected SMS edit prompt!\n"); + return ERR_UNKNOWN; case AT_Reply_OK: smprintf(s, "SMS saved OK\n"); @@ -1776,15 +1779,14 @@ GSM_Error ATGEN_ReplySendSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; int i = 0,reference = 0; - if (s->Protocol.Data.AT.EditMode) { - if (Priv->ReplyState != AT_Reply_SMSEdit) { - return ERR_UNKNOWN; - } - s->Protocol.Data.AT.EditMode = FALSE; - return ERR_NONE; - } - switch (Priv->ReplyState) { + case AT_Reply_SMSEdit: + if (s->Protocol.Data.AT.EditMode) { + s->Protocol.Data.AT.EditMode = FALSE; + return ERR_NONE; + } + smprintf(s, "Received unexpected SMS edit prompt!\n"); + return ERR_UNKNOWN; case AT_Reply_OK: smprintf(s, "SMS sent OK\n"); @@ -2332,6 +2334,9 @@ int *GetRange(GSM_StateMachine *s, const char *buffer) return NULL; } } + if (result == NULL) { + return NULL; + } smprintf(s, "Returning range: "); for (i = 0; result[i] != -1; i++) { diff --git a/libgammu/phone/at/atgen.c b/libgammu/phone/at/atgen.c index 46a7e7f..c8fbdf4 100644 --- a/libgammu/phone/at/atgen.c +++ b/libgammu/phone/at/atgen.c @@ -1391,6 +1391,9 @@ GSM_Error ATGEN_DispatchMessage(GSM_StateMachine *s) } if (Priv->ReplyState == AT_Reply_CMEError || Priv->ReplyState == AT_Reply_CMSError) { + if (ErrorCodes == NULL) { + return ERR_BUG; + } j = 0; /* One char behind +CM[SE] ERROR */ err = line + 11; @@ -1398,24 +1401,19 @@ GSM_Error ATGEN_DispatchMessage(GSM_StateMachine *s) if (isdigit((int)err[j])) { Priv->ErrorCode = atoi(&(err[j])); - k = 0; - - while (ErrorCodes[k].Number != -1) { + for (k = 0; ErrorCodes[k].Number != -1; k++) { if (ErrorCodes[k].Number == Priv->ErrorCode) { Priv->ErrorText = ErrorCodes[k].Text; break; } - k++; } } else if (isalpha((int)err[j])) { - k = 0; - while (ErrorCodes[k].Number != -1) { + for (k = 0; ErrorCodes[k].Number != -1; k++) { if (!strncmp(err + j, ErrorCodes[k].Text, strlen(ErrorCodes[k].Text))) { Priv->ErrorCode = ErrorCodes[k].Number; Priv->ErrorText = ErrorCodes[k].Text; break; } - k++; } } } @@ -2787,6 +2785,16 @@ GSM_Error ATGEN_ReplyGetNetworkLAC_CID(GSM_Protocol_Message msg, GSM_StateMachin NetworkInfo->LAC, sizeof(NetworkInfo->LAC), NetworkInfo->CID, sizeof(NetworkInfo->CID)); + /* Reply without mode */ + if (error == ERR_UNKNOWNRESPONSE) { + error = ATGEN_ParseReply(s, + GetLineString(msg.Buffer, &Priv->Lines, 2), + "+CREG: @i, @r, @r", + &state, + NetworkInfo->LAC, sizeof(NetworkInfo->LAC), + NetworkInfo->CID, sizeof(NetworkInfo->CID)); + } + /* Reply without LAC/CID */ if (error == ERR_UNKNOWNRESPONSE) { error = ATGEN_ParseReply(s, @@ -3529,8 +3537,8 @@ GSM_Error ATGEN_GetMemoryInfo(GSM_StateMachine *s, GSM_MemoryStatus *Status, GSM Status->MemoryUsed = Priv->MemoryUsed; Status->MemoryFree = Priv->MemorySize - Priv->MemoryUsed; } - if ((NeededInfo != AT_NextEmpty) && - (NeededInfo != AT_Status || free_read)) { + if (((NeededInfo != AT_NextEmpty) && + (NeededInfo != AT_Status || free_read)) || Status == NULL) { return ERR_NONE; } @@ -3635,11 +3643,13 @@ GSM_Error ATGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) /* Set number type */ Memory->Entries[0].EntryType = PBK_Number_General; + Memory->Entries[0].Location = PBK_Location_Unknown; Memory->Entries[0].VoiceTag = 0; Memory->Entries[0].SMSList[0] = 0; /* Set name type */ Memory->Entries[1].EntryType = PBK_Text_Name; + Memory->Entries[1].Location = PBK_Location_Unknown; /* Try standard reply */ if (Priv->Manufacturer == AT_Motorola) { @@ -3709,6 +3719,7 @@ GSM_Error ATGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type); /* Set date type */ Memory->Entries[2].EntryType = PBK_Date; + Memory->Entries[2].Location = PBK_Location_Unknown; /* Set number of entries */ Memory->EntriesNum = 3; /* Check whether date is correct */ @@ -3797,12 +3808,19 @@ GSM_Error ATGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) smprintf(s, "Samsung reply detected\n"); /* Set types */ Memory->Entries[1].EntryType = PBK_Text_LastName; + Memory->Entries[1].Location = PBK_Location_Unknown; Memory->Entries[2].EntryType = PBK_Text_FirstName; + Memory->Entries[2].Location = PBK_Location_Unknown; Memory->Entries[7].EntryType = PBK_Text_Email; + Memory->Entries[7].Location = PBK_Location_Unknown; Memory->Entries[8].EntryType = PBK_Text_Note; + Memory->Entries[8].Location = PBK_Location_Unknown; Memory->Entries[9].EntryType = PBK_Category; + Memory->Entries[9].Location = PBK_Location_Unknown; Memory->Entries[10].EntryType = PBK_RingtoneID; + Memory->Entries[10].Location = PBK_Location_Unknown; Memory->Entries[11].EntryType = PBK_Text_PictureName; + Memory->Entries[11].Location = PBK_Location_Unknown; /* Adjust location */ Memory->Location = Memory->Location + 1 - Priv->FirstMemoryEntry; @@ -3831,21 +3849,27 @@ GSM_Error ATGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) switch (types[index]) { \ case 2: \ Memory->Entries[index - offset].EntryType = PBK_Number_Fax; \ + Memory->Entries[index - offset].Location = PBK_Location_Unknown; \ break; \ case 4: \ Memory->Entries[index - offset].EntryType = PBK_Number_Mobile; \ + Memory->Entries[index - offset].Location = PBK_Location_Unknown; \ break; \ case 5: \ Memory->Entries[index - offset].EntryType = PBK_Number_Other; \ + Memory->Entries[index - offset].Location = PBK_Location_Unknown; \ break; \ case 6: \ - Memory->Entries[index - offset].EntryType = PBK_Number_Home; \ + Memory->Entries[index - offset].EntryType = PBK_Number_General; \ + Memory->Entries[index - offset].Location = PBK_Location_Home; \ break; \ case 7: \ - Memory->Entries[index - offset].EntryType = PBK_Number_Work; \ + Memory->Entries[index - offset].EntryType = PBK_Number_General; \ + Memory->Entries[index - offset].Location = PBK_Location_Work; \ break; \ default: \ Memory->Entries[index - offset].EntryType = PBK_Number_Other; \ + Memory->Entries[index - offset].Location = PBK_Location_Unknown; \ smprintf(s, "WARNING: Unknown memory entry type %d\n", types[index]); \ break; \ } \ @@ -5707,6 +5731,7 @@ GSM_Reply_Function ATGENReplyFunctions[] = { GSM_Phone_Functions ATGENPhone = { "A2D|iPAQ|at|M20|S25|MC35|TC35|C35i|S65|S300|5110|5130|5190|5210|6110|6130|6150|6190|6210|6250|6310|6310i|6510|7110|8210|8250|8290|8310|8390|8850|8855|8890|8910|9110|9210", ATGENReplyFunctions, + NOTSUPPORTED, /* Install */ ATGEN_Initialise, ATGEN_Terminate, ATGEN_DispatchMessage, @@ -5841,7 +5866,8 @@ GSM_Phone_Functions ATGENPhone = { NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/phone/at/motorola.c b/libgammu/phone/at/motorola.c index 5377120..de13964 100644 --- a/libgammu/phone/at/motorola.c +++ b/libgammu/phone/at/motorola.c @@ -255,7 +255,9 @@ GSM_Error MOTOROLA_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) Memory->Entries[0].AddError = ERR_NONE; Memory->Entries[0].VoiceTag = 0; Memory->Entries[0].SMSList[0] = 0; + Memory->Entries[0].Location = PBK_Location_Unknown; Memory->Entries[1].EntryType = PBK_Text_Name; + Memory->Entries[1].Location = PBK_Location_Unknown; Memory->Entries[1].AddError = ERR_NONE; Memory->Entries[1].VoiceTag = 0; Memory->Entries[1].SMSList[0] = 0; @@ -280,39 +282,48 @@ GSM_Error MOTOROLA_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) &entry_type); switch (entry_type) { case 0: - Memory->Entries[0].EntryType = PBK_Number_Work; + Memory->Entries[0].EntryType = PBK_Number_General; + Memory->Entries[0].Location = PBK_Location_Work; GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type); break; case 1: - Memory->Entries[0].EntryType = PBK_Number_Home; + Memory->Entries[0].EntryType = PBK_Number_General; + Memory->Entries[0].Location = PBK_Location_Home; GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type); break; case 2: case 10: case 11: Memory->Entries[0].EntryType = PBK_Number_General; + Memory->Entries[0].Location = PBK_Location_Unknown; GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type); break; case 3: Memory->Entries[0].EntryType = PBK_Number_Mobile; + Memory->Entries[0].Location = PBK_Location_Unknown; GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type); break; case 4: Memory->Entries[0].EntryType = PBK_Number_Fax; + Memory->Entries[0].Location = PBK_Location_Unknown; GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type); break; case 5: Memory->Entries[0].EntryType = PBK_Number_Pager; + Memory->Entries[0].Location = PBK_Location_Unknown; GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type); break; case 6: Memory->Entries[0].EntryType = PBK_Text_Email; + Memory->Entries[0].Location = PBK_Location_Unknown; break; case 7: Memory->Entries[0].EntryType = PBK_Text_Email; /* Mailing list */ + Memory->Entries[0].Location = PBK_Location_Unknown; break; default: Memory->Entries[0].EntryType = PBK_Text_Note; + Memory->Entries[0].Location = PBK_Location_Unknown; } if (error != ERR_NONE) { diff --git a/libgammu/phone/at/samsung.c b/libgammu/phone/at/samsung.c index bfd5ff8..745e271 100644 --- a/libgammu/phone/at/samsung.c +++ b/libgammu/phone/at/samsung.c @@ -327,8 +327,8 @@ GSM_Error SAMSUNG_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) if ((dot = strrchr(name, '.')) != NULL) *dot = 0; - len = sprintf(req, "AT+IMGW=0,\"%s\",2,0,0,0,0,100,%d,%u\r", name, - Bitmap->BinaryPic.Length, (unsigned int)crc); + len = sprintf(req, "AT+IMGW=0,\"%s\",2,0,0,0,0,100,%ld,%u\r", name, + (long int)Bitmap->BinaryPic.Length, (unsigned int)crc); error = s->Protocol.Functions->WriteMessage(s, req, len, 0x00); if (error!=ERR_NONE) return error; @@ -513,38 +513,47 @@ GSM_Error SAMSUNG_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) smprintf(s, "Phonebook entry received\n"); Memory->EntriesNum = 9; Memory->Entries[0].EntryType = PBK_Number_Mobile; + Memory->Entries[0].Location = PBK_Location_Unknown; Memory->Entries[0].AddError = ERR_NONE; Memory->Entries[0].VoiceTag = 0; Memory->Entries[0].SMSList[0] = 0; - Memory->Entries[1].EntryType = PBK_Number_Home; + Memory->Entries[1].EntryType = PBK_Number_General; + Memory->Entries[1].Location = PBK_Location_Home; Memory->Entries[1].AddError = ERR_NONE; Memory->Entries[1].VoiceTag = 0; Memory->Entries[1].SMSList[0] = 0; - Memory->Entries[2].EntryType = PBK_Number_Work; + Memory->Entries[2].EntryType = PBK_Number_General; + Memory->Entries[2].Location = PBK_Location_Work; Memory->Entries[2].AddError = ERR_NONE; Memory->Entries[2].VoiceTag = 0; Memory->Entries[2].SMSList[0] = 0; Memory->Entries[3].EntryType = PBK_Number_Fax; + Memory->Entries[3].Location = PBK_Location_Unknown; Memory->Entries[3].AddError = ERR_NONE; Memory->Entries[3].VoiceTag = 0; Memory->Entries[3].SMSList[0] = 0; Memory->Entries[4].EntryType = PBK_Number_General; + Memory->Entries[4].Location = PBK_Location_Unknown; Memory->Entries[4].AddError = ERR_NONE; Memory->Entries[4].VoiceTag = 0; Memory->Entries[4].SMSList[0] = 0; Memory->Entries[5].EntryType = PBK_Text_Email; + Memory->Entries[5].Location = PBK_Location_Unknown; Memory->Entries[5].AddError = ERR_NONE; Memory->Entries[5].VoiceTag = 0; Memory->Entries[5].SMSList[0] = 0; Memory->Entries[6].EntryType = PBK_Text_FirstName; + Memory->Entries[6].Location = PBK_Location_Unknown; Memory->Entries[6].AddError = ERR_NONE; Memory->Entries[6].VoiceTag = 0; Memory->Entries[6].SMSList[0] = 0; Memory->Entries[7].EntryType = PBK_Text_LastName; + Memory->Entries[7].Location = PBK_Location_Unknown; Memory->Entries[7].AddError = ERR_NONE; Memory->Entries[7].VoiceTag = 0; Memory->Entries[7].SMSList[0] = 0; Memory->Entries[8].EntryType = PBK_Text_Note; + Memory->Entries[8].Location = PBK_Location_Unknown; Memory->Entries[8].AddError = ERR_NONE; Memory->Entries[8].VoiceTag = 0; Memory->Entries[8].SMSList[0] = 0; @@ -566,9 +575,11 @@ GSM_Error SAMSUNG_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) if (error == ERR_NONE) { /* Set name type */ Memory->Entries[0].EntryType = PBK_Text_Name; + Memory->Entries[0].Location = PBK_Location_Unknown; /* Set number type */ Memory->Entries[1].EntryType = PBK_Number_General; + Memory->Entries[1].Location = PBK_Location_Unknown; Memory->Entries[1].VoiceTag = 0; Memory->Entries[1].SMSList[0] = 0; @@ -624,6 +635,7 @@ GSM_Error SAMSUNG_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) for (j = i + 1; j < Memory->EntriesNum; j++) { CopyUnicodeString(Memory->Entries[j - 1].Text, Memory->Entries[j].Text); Memory->Entries[j - 1].EntryType = Memory->Entries[j].EntryType; + Memory->Entries[j - 1].Location = Memory->Entries[j].Location; } Memory->EntriesNum--; } @@ -631,6 +643,7 @@ GSM_Error SAMSUNG_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) /* Was there stored birthday? */ if (year > 1900) { Memory->Entries[Memory->EntriesNum].EntryType = PBK_Date; + Memory->Entries[Memory->EntriesNum].Location = PBK_Location_Unknown; Memory->Entries[Memory->EntriesNum].Date.Year = year; Memory->Entries[Memory->EntriesNum].Date.Month = month; Memory->Entries[Memory->EntriesNum].Date.Day = day; diff --git a/libgammu/phone/at/siemens.c b/libgammu/phone/at/siemens.c index 4d19825..09063d1 100644 --- a/libgammu/phone/at/siemens.c +++ b/libgammu/phone/at/siemens.c @@ -376,6 +376,9 @@ GSM_Error SIEMENS_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) if (Priv->Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; error=GSM_EncodeVCALENDAR(req, sizeof(req),&size,Note,TRUE,Siemens_VCalendar); + if (error != ERR_NONE) { + return error; + } Note->Location = Priv->FirstFreeCalendarPos; s->Phone.Data.Cal = Note; diff --git a/libgammu/phone/atobex/atobex.c b/libgammu/phone/atobex/atobex.c index e909581..335a19e 100644 --- a/libgammu/phone/atobex/atobex.c +++ b/libgammu/phone/atobex/atobex.c @@ -637,7 +637,10 @@ GSM_Error ATOBEX_AddFilePart(GSM_StateMachine *s, GSM_File *File, int *Pos, int { GSM_Error error; - if ((error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_AddFilePart(s, File, Pos, Handle); } @@ -645,7 +648,10 @@ GSM_Error ATOBEX_SendFilePart(GSM_StateMachine *s, GSM_File *File, int *Pos, int { GSM_Error error; - if ((error = ATOBEX_SetOBEXMode(s, OBEX_None))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, OBEX_None); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_SendFilePart(s, File, Pos, Handle); } @@ -653,7 +659,10 @@ GSM_Error ATOBEX_GetFilePart(GSM_StateMachine *s, GSM_File *File, int *Handle, i { GSM_Error error; - if ((error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_GetFilePart(s, File, Handle, Size); } @@ -661,7 +670,10 @@ GSM_Error ATOBEX_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, gboolean { GSM_Error error; - if ((error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_GetNextFileFolder(s, File, start); } @@ -669,7 +681,10 @@ GSM_Error ATOBEX_DeleteFile(GSM_StateMachine *s, unsigned char *ID) { GSM_Error error; - if ((error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_DeleteFile(s, ID); } @@ -677,7 +692,10 @@ GSM_Error ATOBEX_AddFolder(GSM_StateMachine *s, GSM_File *File) { GSM_Error error; - if ((error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, OBEX_BrowsingFolders); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_AddFolder(s, File); } @@ -694,13 +712,18 @@ GSM_Error ATOBEX_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status) GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (Status->MemoryType == MEM_ME) { - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { goto atgen; + } return OBEXGEN_GetMemoryStatus(s, Status); } atgen: - if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; + error = ATOBEX_SetATMode(s); + if (error != ERR_NONE) { + return error; + } return ATGEN_GetMemoryStatus(s, Status); } @@ -710,13 +733,18 @@ GSM_Error ATOBEX_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (entry->MemoryType == MEM_ME) { - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { goto atgen; + } return OBEXGEN_GetMemory(s, entry); } atgen: - if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; + error = ATOBEX_SetATMode(s); + if (error != ERR_NONE) { + return error; + } return ATGEN_GetMemory(s, entry); } @@ -726,13 +754,18 @@ GSM_Error ATOBEX_GetNextMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry, gboo GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (entry->MemoryType == MEM_ME) { - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { goto atgen; + } return OBEXGEN_GetNextMemory(s, entry, start); } atgen: - if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; + error = ATOBEX_SetATMode(s); + if (error != ERR_NONE) { + return error; + } return ATGEN_GetNextMemory(s, entry, start); } @@ -742,13 +775,18 @@ GSM_Error ATOBEX_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (entry->MemoryType == MEM_ME) { - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { goto atgen; + } return OBEXGEN_SetMemory(s, entry); } atgen: - if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; + error = ATOBEX_SetATMode(s); + if (error != ERR_NONE) { + return error; + } return ATGEN_SetMemory(s, entry); } @@ -758,13 +796,18 @@ GSM_Error ATOBEX_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (entry->MemoryType == MEM_ME) { - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { goto atgen; + } return OBEXGEN_AddMemory(s, entry); } atgen: - if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; + error = ATOBEX_SetATMode(s); + if (error != ERR_NONE) { + return error; + } return ATGEN_AddMemory(s, entry); } @@ -774,13 +817,18 @@ GSM_Error ATOBEX_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (entry->MemoryType == MEM_ME) { - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { goto atgen; + } return OBEXGEN_DeleteMemory(s, entry); } atgen: - if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; + error = ATOBEX_SetATMode(s); + if (error != ERR_NONE) { + return error; + } return ATGEN_DeleteMemory(s, entry); } @@ -790,13 +838,18 @@ GSM_Error ATOBEX_DeleteAllMemory(GSM_StateMachine *s, GSM_MemoryType type) GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; if (type == MEM_ME) { - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { goto atgen; + } return OBEXGEN_DeleteAllMemory(s, type); } atgen: - if ((error = ATOBEX_SetATMode(s))!= ERR_NONE) return error; + error = ATOBEX_SetATMode(s); + if (error != ERR_NONE) { + return error; + } return ATGEN_DeleteAllMemory(s, type); } @@ -812,7 +865,10 @@ GSM_Error ATOBEX_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_GetTodoStatus(s, status); } @@ -821,7 +877,10 @@ GSM_Error ATOBEX_GetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_GetTodo(s, ToDo); } @@ -830,7 +889,10 @@ GSM_Error ATOBEX_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, gboolean GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_GetNextTodo(s, ToDo, start); } @@ -839,7 +901,10 @@ GSM_Error ATOBEX_DeleteAllToDo (GSM_StateMachine *s) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_DeleteAllTodo(s); } @@ -848,7 +913,10 @@ GSM_Error ATOBEX_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_AddTodo(s, ToDo); } @@ -857,7 +925,10 @@ GSM_Error ATOBEX_SetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_SetTodo(s, ToDo); } @@ -866,7 +937,10 @@ GSM_Error ATOBEX_DeleteToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_DeleteTodo(s, ToDo); } @@ -875,7 +949,10 @@ GSM_Error ATOBEX_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *stat GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_GetCalendarStatus(s, status); } @@ -884,7 +961,10 @@ GSM_Error ATOBEX_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_GetCalendar(s, Note); } @@ -893,7 +973,10 @@ GSM_Error ATOBEX_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, g GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_GetNextCalendar(s, Note, start); } @@ -902,7 +985,10 @@ GSM_Error ATOBEX_DeleteCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_DeleteCalendar(s, Note); } @@ -911,7 +997,10 @@ GSM_Error ATOBEX_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_AddCalendar(s, Note); } @@ -920,7 +1009,10 @@ GSM_Error ATOBEX_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_SetCalendar(s, Note); } @@ -929,7 +1021,10 @@ GSM_Error ATOBEX_DeleteAllCalendar (GSM_StateMachine *s) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_DeleteAllCalendar(s); } @@ -938,7 +1033,10 @@ GSM_Error ATOBEX_GetNoteStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_GetNoteStatus(s, status); } @@ -947,7 +1045,10 @@ GSM_Error ATOBEX_GetNote (GSM_StateMachine *s, GSM_NoteEntry *Note) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_GetNote(s, Note); } @@ -956,7 +1057,10 @@ GSM_Error ATOBEX_GetNextNote(GSM_StateMachine *s, GSM_NoteEntry *Note, gboolean GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_GetNextNote(s, Note, start); } @@ -965,7 +1069,10 @@ GSM_Error ATOBEX_DeleteAllNotes(GSM_StateMachine *s) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_DeleteAllNotes(s); } @@ -974,7 +1081,10 @@ GSM_Error ATOBEX_AddNote (GSM_StateMachine *s, GSM_NoteEntry *Note) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_AddNote(s, Note); } @@ -983,7 +1093,10 @@ GSM_Error ATOBEX_SetNote (GSM_StateMachine *s, GSM_NoteEntry *Note) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_SetNote(s, Note); } @@ -992,7 +1105,10 @@ GSM_Error ATOBEX_DeleteNote (GSM_StateMachine *s, GSM_NoteEntry *Note) GSM_Error error; GSM_Phone_ATOBEXData *Priv = &s->Phone.Data.Priv.ATOBEX; - if ((error = ATOBEX_SetOBEXMode(s, Priv->DataService))!= ERR_NONE) return error; + error = ATOBEX_SetOBEXMode(s, Priv->DataService); + if (error != ERR_NONE) { + return error; + } return OBEXGEN_DeleteNote(s, Note); } @@ -1395,6 +1511,7 @@ GSM_Phone_Functions ATOBEXPhone = { /* There is much more SE phones which support this! */ "sonyericsson|ericsson|atobex", ATGENReplyFunctions, + NOTSUPPORTED, /* Install */ ATOBEX_Initialise, ATOBEX_Terminate, ATOBEX_DispatchMessage, @@ -1529,7 +1646,8 @@ GSM_Phone_Functions ATOBEXPhone = { ATOBEX_AddFolder, ATOBEX_DeleteFile, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/phone/dummy/dummy.c b/libgammu/phone/dummy/dummy.c index 01c9c56..c821be3 100644 --- a/libgammu/phone/dummy/dummy.c +++ b/libgammu/phone/dummy/dummy.c @@ -1005,7 +1005,7 @@ GSM_Error DUMMY_SetAlarm(GSM_StateMachine *s, GSM_Alarm *entry) error = GSM_SaveBackupFile(filename, &backup, GSM_Backup_VCalendar); free(filename); filename=NULL; - return ERR_NONE; + return error; } GSM_Error DUMMY_SetIncomingUSSD(GSM_StateMachine *s, gboolean enable) @@ -1872,6 +1872,7 @@ GSM_Reply_Function DUMMYReplyFunctions[] = { GSM_Phone_Functions DUMMYPhone = { "dummy", DUMMYReplyFunctions, + NOTSUPPORTED, /* Install */ DUMMY_Initialise, DUMMY_Terminate, DUMMY_DispatchMessage, @@ -2006,7 +2007,8 @@ GSM_Phone_Functions DUMMYPhone = { DUMMY_AddFolder, DUMMY_DeleteFolder, NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; /*@}*/ diff --git a/libgammu/phone/nokia/dct3/dct3func.c b/libgammu/phone/nokia/dct3/dct3func.c index f0326bb..a1ecf20 100644 --- a/libgammu/phone/nokia/dct3/dct3func.c +++ b/libgammu/phone/nokia/dct3/dct3func.c @@ -402,6 +402,8 @@ GSM_Error DCT3_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; GSM_Phone_Data *Data = &s->Phone.Data; + size_t pos; + GSM_Error error; switch (msg.Buffer[3]) { case 0x34: @@ -427,10 +429,18 @@ GSM_Error DCT3_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s) EncodeUnicode(Data->SMSC->Name,msg.Buffer+33,i); smprintf(s, "Name \"%s\"\n", DecodeUnicodeString(Data->SMSC->Name)); - GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->DefaultNumber,msg.Buffer+9,TRUE); + pos = 9; + error = GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->DefaultNumber, msg.Buffer, &pos, msg.Length, TRUE); + if (error != ERR_NONE) { + return error; + } smprintf(s, "Default number \"%s\"\n", DecodeUnicodeString(Data->SMSC->DefaultNumber)); - GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->Number,msg.Buffer+21,FALSE); + pos = 21; + error = GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->Number, msg.Buffer, &pos, msg.Length, FALSE); + if (error != ERR_NONE) { + return error; + } smprintf(s, "Number \"%s\"\n", DecodeUnicodeString(Data->SMSC->Number)); return ERR_NONE; @@ -977,7 +987,7 @@ GSM_Error DCT3_SetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *setting GSM_Error error; GSM_MultiWAPSettings settings2; int i,pos,phone1=-1,phone2=-1,phone3=-1; - int ID=0,locations[4],loc1=-1,loc2=-1,loc3=-1; + int ID=0,locations[4] = {0, 0, 0, 0},loc1=-1,loc2=-1,loc3=-1; unsigned char req[] = {N6110_FRAME_HEADER,0x15, 0x00}; /* Location */ unsigned char req2[] = {N6110_FRAME_HEADER,0x1b, diff --git a/libgammu/phone/nokia/dct3/n0650.c b/libgammu/phone/nokia/dct3/n0650.c index 83f4dde..b577314 100644 --- a/libgammu/phone/nokia/dct3/n0650.c +++ b/libgammu/phone/nokia/dct3/n0650.c @@ -19,6 +19,7 @@ static GSM_Reply_Function N650ReplyFunctions[] = { GSM_Phone_Functions N650Phone = { "0650", N650ReplyFunctions, + NOTSUPPORTED, /* Install */ NONEFUNCTION, /* Initialise */ NONEFUNCTION, /* Terminate */ GSM_DispatchMessage, @@ -153,7 +154,8 @@ GSM_Phone_Functions N650Phone = { NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/phone/nokia/dct3/n6110.c b/libgammu/phone/nokia/dct3/n6110.c index 01a081b..ea1eb9d 100644 --- a/libgammu/phone/nokia/dct3/n6110.c +++ b/libgammu/phone/nokia/dct3/n6110.c @@ -312,6 +312,7 @@ static GSM_Error N6110_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine return ERR_UNKNOWNRESPONSE; } Data->Memory->Entries[Data->Memory->EntriesNum].EntryType=PBK_Text_Name; + Data->Memory->Entries[Data->Memory->EntriesNum].Location = PBK_Location_Unknown; if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOPBKUNICODE)) { if (Data->Memory->MemoryType==MEM_DC || Data->Memory->MemoryType==MEM_RC || @@ -343,6 +344,7 @@ static GSM_Error N6110_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine return ERR_UNKNOWNRESPONSE; } Data->Memory->Entries[Data->Memory->EntriesNum].EntryType = PBK_Number_General; + Data->Memory->Entries[Data->Memory->EntriesNum].Location = PBK_Location_Unknown; Data->Memory->Entries[Data->Memory->EntriesNum].VoiceTag = 0; Data->Memory->Entries[Data->Memory->EntriesNum].SMSList[0] = 0; EncodeUnicode(Data->Memory->Entries[Data->Memory->EntriesNum].Text, @@ -355,6 +357,7 @@ static GSM_Error N6110_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOCALLER)) { if (msg.Buffer[count]<5) { Data->Memory->Entries[Data->Memory->EntriesNum].EntryType=PBK_Caller_Group; + Data->Memory->Entries[Data->Memory->EntriesNum].Location = PBK_Location_Unknown; smprintf(s, "Caller group \"%i\"\n",msg.Buffer[count]); Data->Memory->Entries[Data->Memory->EntriesNum].Number=msg.Buffer[count]+1; Data->Memory->EntriesNum++; @@ -367,6 +370,7 @@ static GSM_Error N6110_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine Data->Memory->MemoryType==MEM_MC) { NOKIA_DecodeDateTime(s, msg.Buffer+count+1,&Data->Memory->Entries[Data->Memory->EntriesNum].Date, TRUE, FALSE); Data->Memory->Entries[Data->Memory->EntriesNum].EntryType=PBK_Date; + Data->Memory->Entries[Data->Memory->EntriesNum].Location = PBK_Location_Unknown; /* These values are set, when date and time unavailable in phone. * Values from 3310 - in other can be different */ @@ -955,12 +959,18 @@ static GSM_Error N6110_ReplyGetSetPicture(GSM_Protocol_Message msg, GSM_StateMac { int count = 5, i; GSM_Phone_Data *Data = &s->Phone.Data; + GSM_Error error; + size_t pos; switch (msg.Buffer[3]) { case 0x02: smprintf(s, "Picture Image received\n"); if (msg.Buffer[count]!=0) { - GSM_UnpackSemiOctetNumber(&(s->di), Data->Bitmap->Sender, msg.Buffer + 5, TRUE); + pos = 5; + error = GSM_UnpackSemiOctetNumber(&(s->di), Data->Bitmap->Sender, msg.Buffer, &pos, msg.Length, TRUE); + if (error != ERR_NONE) { + return error; + } /* Convert number of semioctets to number of chars */ i = msg.Buffer[5]; if (i % 2) i++; @@ -2788,6 +2798,7 @@ static GSM_Reply_Function N6110ReplyFunctions[] = { GSM_Phone_Functions N6110Phone = { "2100|3210|3310|3330|3390|3390b|3410|3610|5110|5110i|5130|5190|5210|5510|6110|6130|6150|6190|8210|8250|8290|8850|8855|8890", N6110ReplyFunctions, + NOTSUPPORTED, /* Install */ N6110_Initialise, PHONE_Terminate, GSM_DispatchMessage, @@ -2922,7 +2933,8 @@ GSM_Phone_Functions N6110Phone = { NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/phone/nokia/dct3/n7110.c b/libgammu/phone/nokia/dct3/n7110.c index 52b8680..5bedf01 100644 --- a/libgammu/phone/nokia/dct3/n7110.c +++ b/libgammu/phone/nokia/dct3/n7110.c @@ -253,6 +253,8 @@ static GSM_Error N7110_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMac size_t Width, Height; unsigned char output[500], output2[500]; GSM_Phone_Data *Data = &s->Phone.Data; + size_t pos; + GSM_Error error; switch(msg.Buffer[3]) { case 0x08: @@ -283,9 +285,17 @@ static GSM_Error N7110_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMac Data->Bitmap->BitmapWidth = Width; Data->Bitmap->BitmapHeight = Height; PHONE_DecodeBitmap(GSM_NokiaPictureImage, msg.Buffer + 51, Data->Bitmap); - GSM_UnpackSemiOctetNumber(&(s->di), Data->Bitmap->Sender,msg.Buffer+22,TRUE); + pos = 22; + error = GSM_UnpackSemiOctetNumber(&(s->di), Data->Bitmap->Sender, msg.Buffer, &pos, msg.Length, TRUE); + if (error != ERR_NONE) { + return error; + } #ifdef DEBUG - GSM_UnpackSemiOctetNumber(&(s->di), output,msg.Buffer+9,TRUE); + pos = 9; + error = GSM_UnpackSemiOctetNumber(&(s->di), output, msg.Buffer, &pos, msg.Length, TRUE); + if (error != ERR_NONE) { + return error; + } smprintf(s, "SMSC : %s\n",DecodeUnicodeString(output)); #endif Data->Bitmap->Text[0] = 0; @@ -1631,6 +1641,7 @@ static GSM_Reply_Function N7110ReplyFunctions[] = { GSM_Phone_Functions N7110Phone = { "6210|6250|7110|7190", N7110ReplyFunctions, + NOTSUPPORTED, /* Install */ N7110_Initialise, PHONE_Terminate, GSM_DispatchMessage, @@ -1765,7 +1776,8 @@ GSM_Phone_Functions N7110Phone = { NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/phone/nokia/dct3/n9210.c b/libgammu/phone/nokia/dct3/n9210.c index e5773bb..6f2dc22 100644 --- a/libgammu/phone/nokia/dct3/n9210.c +++ b/libgammu/phone/nokia/dct3/n9210.c @@ -270,6 +270,7 @@ static GSM_Reply_Function N9210ReplyFunctions[] = { GSM_Phone_Functions N9210Phone = { "9210|9210i", N9210ReplyFunctions, + NOTSUPPORTED, /* Install */ N9210_Initialise, PHONE_Terminate, GSM_DispatchMessage, @@ -404,7 +405,8 @@ GSM_Phone_Functions N9210Phone = { NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/phone/nokia/dct4s40/6510/6510file.c b/libgammu/phone/nokia/dct4s40/6510/6510file.c index 7591384..b3cb7cd 100644 --- a/libgammu/phone/nokia/dct4s40/6510/6510file.c +++ b/libgammu/phone/nokia/dct4s40/6510/6510file.c @@ -854,6 +854,7 @@ static GSM_Error N6510_GetFolderListing1(GSM_StateMachine *s, GSM_File *File, gb memcpy(File,&Priv->FilesCache[0],sizeof(GSM_File)); error = N6510_GetFileFolderInfo1(s, File, FALSE); + if (error != ERR_NONE) return error; error = N6510_ShiftFileCache(s, -1); if (error != ERR_NONE) return error; diff --git a/libgammu/phone/nokia/dct4s40/6510/n6510.c b/libgammu/phone/nokia/dct4s40/6510/n6510.c index 8092971..fcac72c 100644 --- a/libgammu/phone/nokia/dct4s40/6510/n6510.c +++ b/libgammu/phone/nokia/dct4s40/6510/n6510.c @@ -19,6 +19,9 @@ #include <string.h> #include <time.h> +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif #include <gammu-nokia.h> @@ -45,6 +48,8 @@ static GSM_Error N6510_Initialise (GSM_StateMachine *s) s->Phone.Data.Priv.N6510.FilesLocationsAvail = 0; s->Phone.Data.Priv.N6510.FilesLocationsUsed = 0; s->Phone.Data.Priv.N6510.FilesCache = NULL; + s->Phone.Data.Priv.N6510.ScreenWidth = 0; + s->Phone.Data.Priv.N6510.ScreenHeight = 0; /* Default timeout for cables */ s->Phone.Data.Priv.N6510.Timeout = 8; @@ -157,6 +162,8 @@ static GSM_Error N6510_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine * { int i, current, j; GSM_Phone_Data *Data = &s->Phone.Data; + size_t pos; + GSM_Error error; switch (msg.Buffer[4]) { case 0x00: @@ -202,11 +209,19 @@ static GSM_Error N6510_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine * case 0x82: switch (msg.Buffer[current+2]) { case 0x01: - GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->DefaultNumber,msg.Buffer+current+4,TRUE); + pos = current + 4; + error = GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->DefaultNumber, msg.Buffer, &pos, msg.Length, TRUE); + if (error != ERR_NONE) { + return error; + } smprintf(s, " Default number \"%s\"\n", DecodeUnicodeString(Data->SMSC->DefaultNumber)); break; case 0x02: - GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->Number,msg.Buffer+current+4,FALSE); + pos = current + 4; + error = GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->Number, msg.Buffer, &pos, msg.Length, FALSE); + if (error != ERR_NONE) { + return error; + } smprintf(s, " Number \"%s\"\n", DecodeUnicodeString(Data->SMSC->Number)); break; default: @@ -4114,6 +4129,106 @@ GSM_Error N6510_GetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark) return DCT3DCT4_GetWAPBookmarkPart(s,bookmark); } +static GSM_Error DCT4_ReplyGetScreenDump(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + int len; + + /* Data is at offset 10 */ + + len = msg.Buffer[7] | (msg.Buffer[6] << 8); + smprintf(s, "Received screenshot part, length %d\n", len); + s->Phone.Data.Picture->Buffer = realloc(s->Phone.Data.Picture->Buffer, s->Phone.Data.Picture->Length + len); + if (s->Phone.Data.Picture->Buffer == NULL) { + return ERR_MOREMEMORY; + } + memcpy(s->Phone.Data.Picture->Buffer + s->Phone.Data.Picture->Length, msg.Buffer + 10, len); + s->Phone.Data.Picture->Length += len; + if (len < 500) { + return ERR_NONE; + } + return ERR_NEEDANOTHERANSWER; +} + +static GSM_Error DCT4_ReplyGetScreenInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + s->Phone.Data.Priv.N6510.ScreenWidth = msg.Buffer[5] | (msg.Buffer[4] << 8); + s->Phone.Data.Priv.N6510.ScreenHeight = msg.Buffer[7] | (msg.Buffer[6] << 8); + smprintf(s, "Screen size %dx%d\n", s->Phone.Data.Priv.N6510.ScreenWidth, s->Phone.Data.Priv.N6510.ScreenHeight); + + return ERR_NONE; +} + +GSM_Error DCT4_Screenshot(GSM_StateMachine *s, GSM_BinaryPicture *picture) +{ + unsigned char req_data[] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x00}; + unsigned char req_screen[] = {N6110_FRAME_HEADER, 0x06, 0x01, 0x00}; + unsigned char bmp_header[] = {0x42, 0x4D, /* BMP magic "BM" */ + 0, 0, 0, 0, /* Size of BMP in bytes */ + 0, 0, 0, 0, /* reserved */ + 0x7a, 0, 0, 0 , /* Offset of data */ + 0x6c, 0, 0, 0, /* Size of header */ + 0, 0, 0, 0, /* width */ + 0, 0, 0, 0, /* height */ + 1, 0, /* color planes */ + 32, 0, /* bpp */ + 3, 0, 0, 0, /* compression, BI_BITFIELDS */ + 32, 0, 0, 0, /* Size of image pixel */ + 0x13,0x0b,0x00,0x00, /* XPelsPerMeter */ + 0x13,0x0b,0x00,0x00, /* YPelsPerMeter */ + 0, 0, 0, 0, /* palette */ + 0, 0, 0, 0, /* important colors */ + 0, 0xFF, 0, 0, /* red mask */ + 0, 0, 0xFF, 0, /* green mask */ + 0, 0, 0, 0xFF, /* blue mask */ + 0xFF, 0, 0, 0, /* alpha mask */ + 0x20, 0x6E, 0x69, 0x57, /* LCS_WINDOWS_COLOR_SPACE */ + 0, 0, 0, 0, /* CIEXYZTRIPLE */ + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, /* red gamma */ + 0, 0, 0, 0, /* green gamma */ + 0, 0, 0, 0, /* blue gamma */ + }; + GSM_Error error; + int32_t tmp; + + /* Get screen size */ + error = GSM_WaitFor(s, req_screen, 6, 0x0E, 4, ID_GetScreenSize); + if (error != ERR_NONE) { + return error; + } + + /* Allocate buffer */ + s->Phone.Data.Picture = picture; + picture->Type = PICTURE_BMP; + picture->Buffer = malloc(sizeof(bmp_header)); + if (picture->Buffer == NULL) { + return ERR_MOREMEMORY; + } + memcpy(picture->Buffer, bmp_header, sizeof(bmp_header)); + picture->Length = sizeof(bmp_header); + + /* Fill BMP header */ +#define STORE_INT(data, pos) picture->Buffer[pos] = data & 0xff; picture->Buffer[pos + 1] = (data >> 8) & 0xff; picture->Buffer[pos + 2] = (data >> 16) & 0xff; picture->Buffer[pos + 3] = (data >> 24) & 0xff; + /* Size */ + tmp = 0x7a + (s->Phone.Data.Priv.N6510.ScreenWidth * s->Phone.Data.Priv.N6510.ScreenHeight * 4); + STORE_INT(tmp, 2); + tmp = s->Phone.Data.Priv.N6510.ScreenWidth; + STORE_INT(tmp, 18); + tmp = -s->Phone.Data.Priv.N6510.ScreenHeight; + STORE_INT(tmp, 22); + + /* And fill in bitmap */ + return GSM_WaitFor(s, req_data, 6, 0x0E, 4, ID_Screenshot); +} + + static GSM_Reply_Function N6510ReplyFunctions[] = { {N71_65_ReplyCallInfo, "\x01",0x03,0x02,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x03,ID_IncomingFrame }, @@ -4358,12 +4473,16 @@ static GSM_Reply_Function N6510ReplyFunctions[] = { {N6510_ReplyGetRingtoneID, "\xDB",0x03,0x02,ID_SetRingtone }, + {DCT4_ReplyGetScreenDump, "\x0E",0x00,0x00,ID_Screenshot }, + {DCT4_ReplyGetScreenInfo, "\x0E",0x00,0x00,ID_GetScreenSize }, + {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions N6510Phone = { "1100|1100a|1100b|1112|1200|1209|1600|1650|1680|2600|2610|2630|2650|2660|2680|2760|3100|3100b|3105|3108|3109c|3200|3200a|3205|3220|3300|3510|3510i|3530|3589i|3590|3595|5000|5100|5140|5140i|5200|5220|5300|5310|6020|6020b|6021|6030|6060|6070|6085|6086|6100|6101|6103|6111|6125|6131|6151|6170|6200|6220|6220c|6230|6230i|6233|6234|6270|6275i|6280|6300|6303c|6310|6310i|6340i|6385|6500c|6500s|6510|6600|6610|6610i|6800|6810|6820|6822|7200|7210|7210s|7250|7250i|7260|7270|7360|7370|7500|7600|7900|8310|8390|8800|8910|8910i", N6510ReplyFunctions, + NOTSUPPORTED, /* Install */ N6510_Initialise, N6510_Terminate, GSM_DispatchMessage, @@ -4498,7 +4617,8 @@ GSM_Phone_Functions N6510Phone = { N6510_AddFolder, N6510_DeleteFolder, N6510_GetGPRSAccessPoint, - N6510_SetGPRSAccessPoint + N6510_SetGPRSAccessPoint, + DCT4_Screenshot }; #endif diff --git a/libgammu/phone/nokia/dct4s40/6510/n6510.h b/libgammu/phone/nokia/dct4s40/6510/n6510.h index 471e36a..32fadbb 100644 --- a/libgammu/phone/nokia/dct4s40/6510/n6510.h +++ b/libgammu/phone/nokia/dct4s40/6510/n6510.h @@ -82,6 +82,8 @@ typedef struct { * links as IrDA. */ int Timeout; + int ScreenWidth; + int ScreenHeight; } GSM_Phone_N6510Data; void N6510_EncodeFMFrequency(double freq, unsigned char *buff); diff --git a/libgammu/phone/nokia/dct4s40/n3320.c b/libgammu/phone/nokia/dct4s40/n3320.c index 43cdcb4..dcf3e45 100644 --- a/libgammu/phone/nokia/dct4s40/n3320.c +++ b/libgammu/phone/nokia/dct4s40/n3320.c @@ -144,6 +144,7 @@ static GSM_Reply_Function N3320ReplyFunctions[] = { GSM_Phone_Functions N3320Phone = { "3320", N3320ReplyFunctions, + NOTSUPPORTED, /* Install */ NONEFUNCTION, /* Initialise */ NONEFUNCTION, /* Terminate */ GSM_DispatchMessage, @@ -278,7 +279,8 @@ GSM_Phone_Functions N3320Phone = { NOTIMPLEMENTED, /* AddFolder */ NOTSUPPORTED, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/phone/nokia/nauto.c b/libgammu/phone/nokia/nauto.c index 4095c67..be97c92 100644 --- a/libgammu/phone/nokia/nauto.c +++ b/libgammu/phone/nokia/nauto.c @@ -38,6 +38,7 @@ static GSM_Error NAUTO_Initialise(GSM_StateMachine *s) GSM_Phone_Functions NAUTOPhone = { "NAUTO", NAUTOReplyFunctions, + NOTSUPPORTED, /* Install */ NAUTO_Initialise, /* Initialise */ NONEFUNCTION, /* Terminate */ GSM_DispatchMessage, @@ -172,7 +173,8 @@ GSM_Phone_Functions NAUTOPhone = { NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/phone/nokia/ncommon.h b/libgammu/phone/nokia/ncommon.h index 5f6d185..fc48c8d 100644 --- a/libgammu/phone/nokia/ncommon.h +++ b/libgammu/phone/nokia/ncommon.h @@ -61,6 +61,7 @@ typedef enum { /* Unknown/Other series */ N2630_PBK_FAVMESSAGING = 0x65, + N3600_PBK_UNKNOWN1 = 0x7b, /* Unknown so far */ N6303_PBK_UNKNOWN1 = 0x8b, } GSM_71_65_Phonebook_Entries_Types; diff --git a/libgammu/phone/nokia/nfunc.c b/libgammu/phone/nokia/nfunc.c index 7f6ab41..80557dc 100644 --- a/libgammu/phone/nokia/nfunc.c +++ b/libgammu/phone/nokia/nfunc.c @@ -135,11 +135,11 @@ size_t N71_65_EncodePhonebookFrame(GSM_StateMachine *s, unsigned char *req, GSM_ } for (i = 0; i < entry->EntriesNum; i++) { type = 0; - if (entry->Entries[i].EntryType == PBK_Number_General) type = N7110_PBK_NUMBER_GENERAL; + if (entry->Entries[i].EntryType == PBK_Number_General && entry->Entries[i].Location == PBK_Location_Work) type = N7110_PBK_NUMBER_WORK; + else if (entry->Entries[i].EntryType == PBK_Number_General && entry->Entries[i].Location == PBK_Location_Home) type = N7110_PBK_NUMBER_HOME; + else if (entry->Entries[i].EntryType == PBK_Number_General) type = N7110_PBK_NUMBER_GENERAL; if (entry->Entries[i].EntryType == PBK_Number_Mobile) type = N7110_PBK_NUMBER_MOBILE; - if (entry->Entries[i].EntryType == PBK_Number_Work) type = N7110_PBK_NUMBER_WORK; if (entry->Entries[i].EntryType == PBK_Number_Fax) type = N7110_PBK_NUMBER_FAX; - if (entry->Entries[i].EntryType == PBK_Number_Home) type = N7110_PBK_NUMBER_HOME; if (type != 0) { entry->Entries[i].AddError = ERR_NONE; @@ -372,6 +372,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, unsigned char *Block; int length = 0, i, bs = 0; GSM_71_65_Phonebook_Entries_Types Type; + GSM_EntryLocation Location = PBK_Location_Unknown; gboolean found=FALSE; gboolean foundbb5add=FALSE; int favorite_messaging_numbers[10]; @@ -429,6 +430,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; } } @@ -446,11 +448,11 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, Block = &Block[bs]; } bs = 256*Block[2]+Block[3]; -#ifdef DEBUG smprintf(s, "Phonebook entry block 0x%02x - length %i\n", Block[0], bs-6); - if (s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXTALLDATE) DumpMessage(&s->di, Block+0, bs-1); -#endif + if (s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXTALLDATE) { + DumpMessage(&s->di, Block+0, bs-1); + } if (entry->EntriesNum >= GSM_PHONEBOOK_ENTRIES) { smprintf(s, "Too many entries\n"); return ERR_MOREMEMORY; @@ -494,6 +496,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, entry->Entries[entry->EntriesNum].Text[Block[5] + 1] = 0; } entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; smprintf(s, " \"%s\"\n",DecodeUnicodeString(entry->Entries[entry->EntriesNum].Text)); if (Block[0] == N7110_PBK_NAME) { if ((int)entry->MemoryType == MEM7110_CG || (int)entry->MemoryType == MEM6510_CG2) { @@ -511,6 +514,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, } if (Block[0] == N7110_PBK_DATETIME) { entry->Entries[entry->EntriesNum].EntryType=PBK_Date; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; NOKIA_DecodeDateTime(s, Block+6, &entry->Entries[entry->EntriesNum].Date, TRUE, DayMonthReverse); if (CheckDate(&entry->Entries[entry->EntriesNum].Date) && CheckDate(&entry->Entries[entry->EntriesNum].Date)) { @@ -527,6 +531,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, bitmap->PictureID = Block[10]*256+Block[11]; } else { entry->Entries[entry->EntriesNum].EntryType=PBK_PictureID; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; smprintf(s, "Picture ID \"%i\"\n",Block[10]*256+Block[11]); entry->Entries[entry->EntriesNum].Number=Block[10]*256+Block[11]; entry->EntriesNum ++; @@ -558,7 +563,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, Type = PBK_Number_General; smprintf(s,"General number "); } if (Block[5] == N7110_PBK_NUMBER_WORK) { - Type = PBK_Number_Work; smprintf(s,"Work number "); + Type = PBK_Number_General; Location = PBK_Location_Work; smprintf(s,"Work number "); } if (Block[5] == N7110_PBK_NUMBER_FAX) { Type = PBK_Number_Fax; smprintf(s,"Fax number "); @@ -567,13 +572,14 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, Type = PBK_Number_Mobile; smprintf(s,"Mobile number "); } if (Block[5] == N7110_PBK_NUMBER_HOME) { - Type = PBK_Number_Home; smprintf(s,"Home number "); + Type = PBK_Number_General; Location = PBK_Location_Home; smprintf(s,"Home number "); } if (Type == 0x00) { smprintf(s, "Unknown number type %02x\n",Block[5]); return ERR_UNKNOWNRESPONSE; } entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = Location; if (! N71_65_PB_CopyString(s, entry, Block+10, Block[9])) return ERR_UNKNOWNRESPONSE; /* DCT3 phones like 6210 */ @@ -589,6 +595,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (Block[0] == S4030_PBK_CALLLENGTH) { entry->Entries[entry->EntriesNum].CallLength = Block[9]*256*256+Block[10]*256+Block[11]; entry->Entries[entry->EntriesNum].EntryType=PBK_CallLength; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } @@ -621,6 +628,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, return ERR_UNKNOWNRESPONSE; } entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; if (! N71_65_PB_CopyString(s, entry, Block+10, Block[9])) return ERR_UNKNOWNRESPONSE; entry->EntriesNum ++; @@ -633,6 +641,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } @@ -641,6 +650,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } @@ -649,6 +659,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } @@ -657,6 +668,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } @@ -665,6 +677,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } @@ -673,6 +686,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } @@ -681,6 +695,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } @@ -689,6 +704,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } @@ -697,6 +713,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } @@ -705,11 +722,13 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=Type; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } if (Block[0] == S4030_PBK_BIRTHDAY) { entry->Entries[entry->EntriesNum].EntryType=PBK_Date; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; NOKIA_DecodeDateTime(s, Block+6, &entry->Entries[entry->EntriesNum].Date, FALSE, DayMonthReverse); entry->EntriesNum ++; continue; @@ -725,6 +744,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, bitmap->FileSystemRingtone = FALSE; } else { entry->Entries[entry->EntriesNum].EntryType=PBK_RingtoneID; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; smprintf(s, "Ringtone ID \"%i\"\n",Block[7]); entry->Entries[entry->EntriesNum].Number=Block[7]; entry->EntriesNum ++; @@ -752,6 +772,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, } if (Block[0] == N7110_PBK_GROUP) { entry->Entries[entry->EntriesNum].EntryType=PBK_Caller_Group; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; smprintf(s, "Caller group \"%i\"\n",Block[5]); entry->Entries[entry->EntriesNum].Number=Block[5]; if (Block[5]!=0) entry->EntriesNum ++; @@ -823,6 +844,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, /* series 40 3.0 */ smprintf(s, "Filesystem ringtone ID: %02x\n",Block[10]*256+Block[11]); entry->Entries[entry->EntriesNum].EntryType=PBK_RingtoneID; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->Entries[entry->EntriesNum].Number=Block[10]*256+Block[11]; entry->EntriesNum ++; } @@ -839,6 +861,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (Block[0] == N7110_PBK_UNKNOWN1 || Block[0] == N7110_PBK_UNKNOWN2 || Block[0] == N7110_PBK_UNKNOWN3 + || Block[0] == N3600_PBK_UNKNOWN1 || Block[0] == N6303_PBK_UNKNOWN1) { smprintf(s,"Unknown entry type 0x%02x data length %d\n", Block[0], bs-6); continue; @@ -860,6 +883,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5])) return ERR_UNKNOWNRESPONSE; entry->Entries[entry->EntriesNum].EntryType=PBK_PushToTalkID; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; entry->EntriesNum ++; continue; } @@ -871,6 +895,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, smprintf(s,"Group ID (6230i or later)\n"); entry->Entries[entry->EntriesNum].EntryType=PBK_Caller_Group; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; smprintf(s, "Caller group \"%i\"\n",Block[7]); entry->Entries[entry->EntriesNum].Number=Block[7]; entry->EntriesNum ++; @@ -903,6 +928,7 @@ GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, * entry->Entries doesn't retain order. */ entry->Entries[entry->EntriesNum].EntryType = PBK_Number_Messaging; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; CopyUnicodeString(entry->Entries[entry->EntriesNum].Text,entry->Entries[favorite_messaging_numbers[i] - 1].Text); smprintf(s,"Marked entry #%i (%s) as favorite messaging number\n", favorite_messaging_numbers[i], @@ -1126,6 +1152,8 @@ GSM_Error DCT3DCT4_ReplyCallDivert(GSM_Protocol_Message msg, GSM_StateMachine *s { GSM_MultiCallDivert *cd = s->Phone.Data.Divert; int i,pos = 11,j; + size_t number_pos; + GSM_Error error; switch (msg.Buffer[3]) { case 0x02: @@ -1169,7 +1197,11 @@ GSM_Error DCT3DCT4_ReplyCallDivert(GSM_Protocol_Message msg, GSM_StateMachine *s j = pos + 2; while (msg.Buffer[j] != 0x00) j++; msg.Buffer[pos+1] = j - pos - 2; - GSM_UnpackSemiOctetNumber(&(s->di), cd->Response.Entries[i].Number,msg.Buffer+(pos+1),FALSE); + number_pos = pos + 1; + error = GSM_UnpackSemiOctetNumber(&(s->di), cd->Response.Entries[i].Number, msg.Buffer, &number_pos, msg.Length, FALSE); + if (error != ERR_NONE) { + return error; + } smprintf(s," Number : %s\n",DecodeUnicodeString(cd->Response.Entries[i].Number)); cd->Response.Entries[i].Timeout = msg.Buffer[pos+34]; smprintf(s," Timeout : %i seconds\n",msg.Buffer[pos+34]); diff --git a/libgammu/phone/nokia/wd2/n3650.c b/libgammu/phone/nokia/wd2/n3650.c index 771f453..f4c98ed 100644 --- a/libgammu/phone/nokia/wd2/n3650.c +++ b/libgammu/phone/nokia/wd2/n3650.c @@ -213,11 +213,15 @@ static GSM_Error N3650_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, gb if (File->ID_FullName[0]!=Priv->Files[Priv->FilesLocationsCurrent-2]->ID_FullName[0]) { if (File->ID_FullName[0] == 'E') { error = DCT4_SetPhoneMode(s, DCT4_MODE_TEST); + if (error != ERR_NONE) return error; error = DCT4_SetPhoneMode(s, DCT4_MODE_TEST); + if (error != ERR_NONE) return error; } if (File->ID_FullName[0] == 'C') { error = DCT4_SetPhoneMode(s, DCT4_MODE_LOCAL); + if (error != ERR_NONE) return error; error = DCT4_SetPhoneMode(s, DCT4_MODE_LOCAL); + if (error != ERR_NONE) return error; } #if 0 if (error != ERR_NONE) return error; @@ -275,6 +279,7 @@ static GSM_Reply_Function N3650ReplyFunctions[] = { GSM_Phone_Functions N3650Phone = { "3650|NGAGE", N3650ReplyFunctions, + NOTSUPPORTED, /* Install */ N3650_Initialise, N3650_Terminate, GSM_DispatchMessage, @@ -409,7 +414,8 @@ GSM_Phone_Functions N3650Phone = { NOTIMPLEMENTED, /* AddFolder */ NOTSUPPORTED, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/phone/obex/obexgen.c b/libgammu/phone/obex/obexgen.c index c80f414..7f9bc20 100644 --- a/libgammu/phone/obex/obexgen.c +++ b/libgammu/phone/obex/obexgen.c @@ -3706,6 +3706,7 @@ GSM_Reply_Function OBEXGENReplyFunctions[] = { GSM_Phone_Functions OBEXGENPhone = { "obex|seobex|obexfs|obexirmc|obexnone|mobex", OBEXGENReplyFunctions, + NOTSUPPORTED, /* Install */ OBEXGEN_Initialise, OBEXGEN_Terminate, GSM_DispatchMessage, @@ -3840,7 +3841,8 @@ GSM_Phone_Functions OBEXGENPhone = { OBEXGEN_AddFolder, OBEXGEN_DeleteFile, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/phone/pfunc.c b/libgammu/phone/pfunc.c index 9e1bb59..0a32fe8 100644 --- a/libgammu/phone/pfunc.c +++ b/libgammu/phone/pfunc.c @@ -136,6 +136,52 @@ GSM_Error PHONE_Beep(GSM_StateMachine *s) return s->Phone.Functions->PlayTone(s,255*255,0,FALSE); } +GSM_Error PHONE_FindDataFile(GSM_StateMachine *s, GSM_File * File, const char *ExtraPath, const char *filename) +{ + char *path; + GSM_Error error; + + EncodeUnicode(File->Name, filename, strlen(filename)); + + path = malloc(MAX(strlen(GAMMU_DATA_PATH), ExtraPath == NULL ? 0 : strlen(ExtraPath)) + 50); + if (path == NULL) { + return ERR_MOREMEMORY; + } + + if (ExtraPath != NULL) { + sprintf(path, "%s/%s", ExtraPath, filename); + smprintf(s, "Trying to load from extra path: %s\n", path); + + error = GSM_ReadFile(path, File); + if (error == ERR_NONE) { + free(path); + return error; + } + } + + sprintf(path, "%s/%s", GAMMU_DATA_PATH, filename); + smprintf(s, "Trying to load from data path: %s\n", path); + + error = GSM_ReadFile(path, File); + free(path); + + return error; +} + +GSM_Error PHONE_UploadFile(GSM_StateMachine *s, GSM_File * File) +{ + int Pos = 0, Handle = 0; + GSM_Error error = ERR_NONE;; + + while (error == ERR_NONE) { + error = GSM_SendFilePart(s, File, &Pos, &Handle); + } + if (error == ERR_EMPTY) { + return ERR_NONE; + } + return error; +} + GSM_Error NoneReply(GSM_Protocol_Message msg UNUSED, GSM_StateMachine *s) { smprintf(s,"None answer\n"); diff --git a/libgammu/phone/pfunc.h b/libgammu/phone/pfunc.h index 80ffb93..2a573d2 100644 --- a/libgammu/phone/pfunc.h +++ b/libgammu/phone/pfunc.h @@ -42,6 +42,8 @@ GSM_Error PHONE_Terminate (GSM_StateMachine *s); */ GSM_Error NoneReply(GSM_Protocol_Message msg, GSM_StateMachine *s); +GSM_Error PHONE_FindDataFile(GSM_StateMachine *s, GSM_File * File, const char *ExtraPath, const char *filename); +GSM_Error PHONE_UploadFile(GSM_StateMachine *s, GSM_File * File); #endif /*@}*/ /*@}*/ diff --git a/libgammu/phone/s60/s60phone.c b/libgammu/phone/s60/s60phone.c new file mode 100644 index 0000000..4b01ac7 --- /dev/null +++ b/libgammu/phone/s60/s60phone.c @@ -0,0 +1,2170 @@ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (c) 2011 Michal Cihar <michal@cihar.com> + */ + + +#include "../../gsmstate.h" +#include "../../protocol/s60/s60-ids.h" +#include "../../gsmcomon.h" +#include "../../misc/coding/coding.h" +#include "../../gsmphones.h" +#include "../../gsmstate.h" +#include "../../service/gsmmisc.h" +#include "../../misc/locales.h" +#include "../pfunc.h" +#include <string.h> + +#if defined(GSM_ENABLE_S60) + +GSM_Error S60_Install(GSM_StateMachine *s, const char *ExtraPath) +{ + GSM_StateMachine *gsm; + GSM_Debug_Info *debug_info; + GSM_Config *cfg; + GSM_Error error; + GSM_File PythonFile, PIPSFile, AppletFile; + gboolean install_python, install_pips; + + PythonFile.Buffer = NULL; + PythonFile.Used = 0; + PIPSFile.Buffer = NULL; + PIPSFile.Used = 0; + AppletFile.Buffer = NULL; + AppletFile.Used = 0; + + error = PHONE_FindDataFile(s, &AppletFile, ExtraPath, "series60-remote.sis"); + if (error != ERR_NONE) { + smprintf(s, "Failed to find applet, trying another filename!\n"); + error = PHONE_FindDataFile(s, &AppletFile, ExtraPath, "series60-remote-sign.sis"); + if (error != ERR_NONE) { + smprintf(s, "Failed to load applet data!\n"); + return ERR_INSTALL_NOT_FOUND; + } + } + + error = PHONE_FindDataFile(s, &PythonFile, ExtraPath, "Python_2.0.0.sis"); + if (error == ERR_NONE) { + install_python = TRUE; + } else { + smprintf(s, "Could not find Python for S60 to install, skipping!\n"); + install_python = FALSE; + install_pips = FALSE; + } + + if (install_python) { + error = PHONE_FindDataFile(s, &PIPSFile, ExtraPath, "pips.sis"); + if (error == ERR_NONE) { + install_pips = TRUE; + } else { + smprintf(s, "Could not find PIPS to install, skipping!\n"); + install_pips = FALSE; + } + } + + gsm = GSM_AllocStateMachine(); + if (gsm == NULL) { + return ERR_MOREMEMORY; + } + + /* Copy debug configuration */ + debug_info = GSM_GetDebug(gsm); + *debug_info = *GSM_GetDebug(s); + debug_info->closable = FALSE; + GSM_SetDebugFileDescriptor(GSM_GetDebug(s)->df, FALSE, debug_info); + GSM_SetDebugLevel(s->CurrentConfig->DebugLevel, debug_info); + + /* Generate configuration */ + cfg = GSM_GetConfig(gsm, 0); + cfg->Device = strdup(s->CurrentConfig->Device); + cfg->Connection = strdup("blueobex"); + strcpy(cfg->Model, "obexnone"); + strcpy(cfg->DebugLevel, s->CurrentConfig->DebugLevel); + cfg->UseGlobalDebugFile = s->CurrentConfig->UseGlobalDebugFile; + + /* We have one configuration */ + GSM_SetConfigNum(gsm, 1); + + error = GSM_InitConnection(gsm, 1); + if (error != ERR_NONE) { + return error; + } + + if (install_pips) { + error = PHONE_UploadFile(gsm, &PIPSFile); + free(PIPSFile.Buffer); + if (error != ERR_NONE) { + return error; + } + } + + if (install_python) { + error = PHONE_UploadFile(gsm, &PythonFile); + free(PythonFile.Buffer); + if (error != ERR_NONE) { + return error; + } + } + + error = PHONE_UploadFile(gsm, &AppletFile); + free(AppletFile.Buffer); + if (error != ERR_NONE) { + return error; + } + + error = GSM_TerminateConnection(gsm); + if (error != ERR_NONE) { + return error; + } + + /* Free up used memory */ + GSM_FreeStateMachine(gsm); + + return ERR_NONE; +} + +GSM_Error S60_Initialise(GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + GSM_Error error; + size_t i; + + Priv->SMSLocations = NULL; + Priv->SMSLocationsSize = 0; + Priv->SMSLocationsPos = 0; + + Priv->ContactLocations = NULL; + Priv->ContactLocationsSize = 0; + Priv->ContactLocationsPos = 0; + + Priv->CalendarLocations = NULL; + Priv->CalendarLocationsSize = 0; + Priv->CalendarLocationsPos = 0; + + Priv->ToDoLocations = NULL; + Priv->ToDoLocationsSize = 0; + Priv->ToDoLocationsPos = 0; + + s->Phone.Data.NetworkInfo = NULL; + s->Phone.Data.SignalQuality = NULL; + s->Phone.Data.BatteryCharge = NULL; + s->Phone.Data.Memory = NULL; + s->Phone.Data.MemoryStatus = NULL; + s->Phone.Data.CalStatus = NULL; + s->Phone.Data.ToDoStatus = NULL; + + for (i = 0; i < sizeof(Priv->MessageParts) / sizeof(Priv->MessageParts[0]); i++) { + Priv->MessageParts[i] = NULL; + } + + error = GSM_WaitFor (s, NULL, 0, 0, S60_TIMEOUT, ID_Initialise); + if (error != ERR_NONE) { + return error; + } + + if (Priv->MajorVersion != 1 || Priv->MinorVersion != 5) { + smprintf(s, "Unsupported protocol version\n"); + return ERR_NOTSUPPORTED; + } + + error = GSM_WaitFor(s, NULL, 0, NUM_HELLO_REQUEST, S60_TIMEOUT, ID_EnableEcho); + if (error != ERR_NONE) { + return error; + } + + return error; + +// return ERR_NONE; +} + +/** + * Splits values from S60 reply. + */ +GSM_Error S60_SplitValues(GSM_Protocol_Message *msg, GSM_StateMachine *s) +{ + unsigned char * pos = msg->Buffer - 1; + size_t i; + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + + for (i = 0; i < sizeof(Priv->MessageParts) / sizeof(Priv->MessageParts[0]); i++) { + Priv->MessageParts[i] = NULL; + } + + i = 0; + + if (msg->Length == 0) { + return ERR_NONE; + } + + while ((pos - msg->Buffer) < (ssize_t)msg->Length) { + if (i > sizeof(Priv->MessageParts) / sizeof(Priv->MessageParts[0])) { + smprintf(s, "Too many reply parts!\n"); + return ERR_MOREMEMORY; + } + Priv->MessageParts[i++] = pos + 1; + + /* Find end of next field */ + pos = strchr(pos + 1, NUM_SEPERATOR); + if (pos == NULL) { + break; + } + + /* Zero terminate string */ + *pos = 0; + } + return ERR_NONE; +} + +GSM_Error S60_Terminate(GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + + free(Priv->SMSLocations); + Priv->SMSLocations = NULL; + Priv->SMSLocationsSize = 0; + Priv->SMSLocationsPos = 0; + + free(Priv->ContactLocations); + Priv->ContactLocations = NULL; + Priv->ContactLocationsSize = 0; + Priv->ContactLocationsPos = 0; + + free(Priv->CalendarLocations); + Priv->CalendarLocations = NULL; + Priv->CalendarLocationsSize = 0; + Priv->CalendarLocationsPos = 0; + + free(Priv->ToDoLocations); + Priv->ToDoLocations = NULL; + Priv->ToDoLocationsSize = 0; + Priv->ToDoLocationsPos = 0; + + return GSM_WaitFor(s, NULL, 0, NUM_QUIT, S60_TIMEOUT, ID_Terminate); +} + +static GSM_Error S60_Reply_Generic(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + switch (msg.Type) { + case NUM_SYSINFO_REPLY_START: + case NUM_CONTACTS_REPLY_HASH_SINGLE_START: + case NUM_CONTACTS_REPLY_CONTACT_START: + case NUM_CALENDAR_REPLY_ENTRIES_START: + return ERR_NEEDANOTHERANSWER; + case NUM_LOCATION_REPLY_NA: + return ERR_NOTSUPPORTED; + case NUM_CONTACTS_REPLY_CONTACT_NOT_FOUND: + case NUM_CALENDAR_REPLY_ENTRY_NOT_FOUND: + return ERR_EMPTY; + default: + return ERR_NONE; + } +} + +static GSM_Error S60_Reply_SendSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + switch (msg.Type) { + case NUM_MESSAGE_SEND_REPLY_RETRY: + if (s->User.SendSMSStatus != NULL) { + s->User.SendSMSStatus(s, 1, -1, s->User.SendSMSStatusUserData); + } + return ERR_UNKNOWN; + case NUM_MESSAGE_SEND_REPLY_STATUS: + return ERR_NONE; + case NUM_MESSAGE_SEND_REPLY_OK: + if (s->User.SendSMSStatus != NULL) { + s->User.SendSMSStatus(s, 0, -1, s->User.SendSMSStatusUserData); + } + return ERR_NONE; + case NUM_MESSAGE_SEND_REPLY_FAILURE: + if (s->User.SendSMSStatus != NULL) { + s->User.SendSMSStatus(s, 1, -1, s->User.SendSMSStatusUserData); + } + return ERR_UNKNOWN; + default: + return ERR_UNKNOWN; + } +} + +static GSM_Error S60_Reply_Connect(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + char *pos; + + Priv->MajorVersion = atoi(msg.Buffer); + pos = strchr(msg.Buffer, '.'); + if (pos == NULL) { + return ERR_UNKNOWN; + } + Priv->MinorVersion = atoi(pos + 1); + smprintf(s, "Connected to series60-remote version %d.%d\n", Priv->MajorVersion, Priv->MinorVersion); + + return ERR_NONE; +} + +static GSM_Error S60_GetInfo(GSM_StateMachine *s) +{ + return GSM_WaitFor(s, "1", 1, NUM_SYSINFO_REQUEST, S60_TIMEOUT, ID_GetModel); +} + +static GSM_Error S60_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig) +{ + GSM_Error error; + + sig->BitErrorRate = -1; + sig->SignalStrength = -1; + sig->SignalPercent = -1; + + s->Phone.Data.SignalQuality = sig; + error = S60_GetInfo(s); + s->Phone.Data.SignalQuality = NULL; + return error; +} + +static GSM_Error S60_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo) +{ + GSM_Error error; + + s->Phone.Data.NetworkInfo = netinfo; + error = GSM_WaitFor(s, NULL, 0, NUM_LOCATION_REQUEST, S60_TIMEOUT, ID_GetNetworkInfo); + s->Phone.Data.NetworkInfo = NULL; + return error; +} + +static GSM_Error S60_Reply_GetNetworkInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + GSM_Error error; + char *mcc, *mnc, *lac, *cellid; + + if (s->Phone.Data.NetworkInfo == NULL) { + return ERR_NONE; + } + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + } + + /* Grab values */ + mcc = Priv->MessageParts[0]; + mnc = Priv->MessageParts[1]; + lac = Priv->MessageParts[2]; + cellid =Priv->MessageParts[3]; + + /* We need all of them */ + if (mcc == NULL || mnc == NULL || lac == NULL || cellid == NULL) { + return ERR_UNKNOWN; + } + + strcpy(s->Phone.Data.NetworkInfo->CID, cellid); + strcpy(s->Phone.Data.NetworkInfo->NetworkCode, mcc); + strcat(s->Phone.Data.NetworkInfo->NetworkCode, " "); + strcat(s->Phone.Data.NetworkInfo->NetworkCode, mnc); + s->Phone.Data.NetworkInfo->State = GSM_NetworkStatusUnknown; + strcpy(s->Phone.Data.NetworkInfo->LAC, lac); + s->Phone.Data.NetworkInfo->NetworkName[0] = 0; + s->Phone.Data.NetworkInfo->NetworkName[1] = 0; + s->Phone.Data.NetworkInfo->GPRS = 0; + s->Phone.Data.NetworkInfo->PacketCID[0] = 0; + s->Phone.Data.NetworkInfo->PacketState = 0; + s->Phone.Data.NetworkInfo->PacketLAC[0] = 0; + + return ERR_NONE; +} + +static GSM_Error S60_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat) +{ + GSM_Error error; + + GSM_ClearBatteryCharge(bat); + s->Phone.Data.BatteryCharge = bat; + error = S60_GetInfo(s); + s->Phone.Data.BatteryCharge = NULL; + return error; +} + + +static GSM_Error S60_Reply_GetInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + GSM_Error error; + char *pos; + GSM_SignalQuality *Signal = s->Phone.Data.SignalQuality; + GSM_BatteryCharge *BatteryCharge = s->Phone.Data.BatteryCharge; + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + } + if (Priv->MessageParts[0] == NULL || Priv->MessageParts[1] == NULL) { + return ERR_UNKNOWN; + } + smprintf(s, "Received %s=%s\n", Priv->MessageParts[0], Priv->MessageParts[1]); + if (strcmp(Priv->MessageParts[0], "imei") == 0) { + strcpy(s->Phone.Data.IMEI, Priv->MessageParts[1]); + } else if (strcmp(Priv->MessageParts[0], "model") == 0) { + /* Parse manufacturer */ + pos = strstr(Priv->MessageParts[1], "(C)"); + if (pos != NULL) { + strcpy(s->Phone.Data.Manufacturer, pos + 3); + } + /* Try to find model */ + pos = strchr(Priv->MessageParts[1], ' '); + if (pos != NULL) { + pos = strchr(pos + 1, ' '); + if (pos != NULL) { + strcpy(s->Phone.Data.Model, pos + 1); + pos = strchr(s->Phone.Data.Model, ' '); + if (pos != NULL) { + *pos = 0; + } + } else { + strcpy(s->Phone.Data.Model, Priv->MessageParts[1]); + } + } else { + strcpy(s->Phone.Data.Model, Priv->MessageParts[1]); + } + s->Phone.Data.ModelInfo = GetModelData(s, NULL, s->Phone.Data.Model, NULL); + + if (s->Phone.Data.ModelInfo->number[0] == 0) + s->Phone.Data.ModelInfo = GetModelData(s, NULL, NULL, s->Phone.Data.Model); + + if (s->Phone.Data.ModelInfo->number[0] == 0) + s->Phone.Data.ModelInfo = GetModelData(s, s->Phone.Data.Model, NULL, NULL); + + if (s->Phone.Data.ModelInfo->number[0] == 0) { + smprintf(s, "Unknown model, but it should still work\n"); + } + smprintf(s, "[Model name: `%s']\n", s->Phone.Data.Model); + smprintf(s, "[Model data: `%s']\n", s->Phone.Data.ModelInfo->number); + smprintf(s, "[Model data: `%s']\n", s->Phone.Data.ModelInfo->model); + } else if (strcmp(Priv->MessageParts[0], "s60_version") == 0) { + strcpy(s->Phone.Data.Version, Priv->MessageParts[1]); + strcat(s->Phone.Data.Version, "."); + strcat(s->Phone.Data.Version, Priv->MessageParts[2]); + GSM_CreateFirmwareNumber(s); + } else if (Signal != NULL && strcmp(Priv->MessageParts[0], "signal_dbm") == 0) { + Signal->SignalStrength = atoi(Priv->MessageParts[1]); + } else if (Signal != NULL && strcmp(Priv->MessageParts[0], "signal_bars") == 0) { + Signal->SignalPercent = 100 * 7 / atoi(Priv->MessageParts[1]); + } else if (BatteryCharge != NULL && strcmp(Priv->MessageParts[0], "battery") == 0) { + BatteryCharge->BatteryPercent = atoi(Priv->MessageParts[1]); + } + return ERR_NEEDANOTHERANSWER; +} + +static GSM_Error S60_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status) +{ + GSM_Error error; + + if (Status->MemoryType != MEM_ME) { + return ERR_NOTSUPPORTED; + } + + s->Phone.Data.MemoryStatus = Status; + Status->MemoryUsed = 0; + Status->MemoryFree = 1000; + error = GSM_WaitFor(s, "", 0, NUM_CONTACTS_REQUEST_COUNT, S60_TIMEOUT, ID_GetMemoryStatus); + s->Phone.Data.MemoryStatus = NULL; + return error; +} + +static GSM_Error S60_GetMemoryLocations(GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + Priv->ContactLocationsPos = 0; + return GSM_WaitFor(s, "", 0, NUM_CONTACTS_REQUEST_HASH_SINGLE, S60_TIMEOUT, ID_GetMemoryStatus); +} + +static GSM_Error S60_StoreLocation(GSM_StateMachine *s, int **locations, size_t *size, size_t *pos, int location) +{ + if ((*pos) + 3 >= (*size)) { + *locations = (int *)realloc(*locations, ((*size) + 20) * sizeof(int)); + if (*locations == NULL) { + return ERR_MOREMEMORY; + } + *size += 20; + } + (*locations)[(*pos)] = location; + (*locations)[(*pos) + 1] = 0; + (*pos) += 1; + return ERR_NONE; +} + + +static GSM_Error S60_Reply_GetMemoryStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + s->Phone.Data.MemoryStatus->MemoryUsed = atoi(msg.Buffer); + + return ERR_NONE; +} + +static GSM_Error S60_Reply_ContactHash(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + GSM_Error error; + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + + } + + if (Priv->MessageParts[0] == NULL) { + return ERR_UNKNOWN; + } + + error = S60_StoreLocation(s, &Priv->ContactLocations, &Priv->ContactLocationsSize, &Priv->ContactLocationsPos, atoi(Priv->MessageParts[0])); + if (error != ERR_NONE) { + return error; + + } + + return ERR_NEEDANOTHERANSWER; +} + +static GSM_Error S60_Reply_GetCalendarStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + GSM_Error error; + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + } + + if (Priv->MessageParts[0] == NULL || Priv->MessageParts[1] == NULL || Priv->MessageParts[2] == NULL) { + return ERR_UNKNOWN; + } + + if (s->Phone.Data.CalStatus != NULL) { + s->Phone.Data.CalStatus->Used = atoi(Priv->MessageParts[1]); + } + if (s->Phone.Data.ToDoStatus != NULL) { + s->Phone.Data.ToDoStatus->Used = atoi(Priv->MessageParts[2]); + } + + return ERR_NONE; +} + +static GSM_Error S60_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status) +{ + GSM_Error error; + + s->Phone.Data.CalStatus = Status; + Status->Used = 0; + Status->Free = 1000; + error = GSM_WaitFor(s, "", 0, NUM_CALENDAR_REQUEST_COUNT, S60_TIMEOUT, ID_GetCalendarNotesInfo); + s->Phone.Data.CalStatus = NULL; + return error; +} + +static GSM_Error S60_GetCalendarLocations(GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + + Priv->CalendarLocationsPos = 0; + return GSM_WaitFor(s, "", 0, NUM_CALENDAR_REQUEST_ENTRIES_ALL, S60_TIMEOUT, ID_GetCalendarNotesInfo); +} + +static GSM_Error S60_Reply_CalendarCount(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + GSM_Error error; + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + + } + + if (Priv->MessageParts[0] == NULL || Priv->MessageParts[1] == NULL) { + return ERR_UNKNOWN; + } + + if (strcmp(Priv->MessageParts[1], "appointment") != 0 && + strcmp(Priv->MessageParts[1], "event") != 0 && + strcmp(Priv->MessageParts[1], "reminder") != 0 && + strcmp(Priv->MessageParts[1], "anniversary") != 0) { + return ERR_NEEDANOTHERANSWER; + } + + error = S60_StoreLocation(s, &Priv->CalendarLocations, &Priv->CalendarLocationsSize, &Priv->CalendarLocationsPos, atoi(Priv->MessageParts[0])); + if (error != ERR_NONE) { + return error; + + } + + if (s->Phone.Data.CalStatus != NULL) { + s->Phone.Data.CalStatus->Used++; + } + return ERR_NEEDANOTHERANSWER; +} + +static GSM_Error S60_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *Status) +{ + GSM_Error error; + + s->Phone.Data.ToDoStatus = Status; + Status->Used = 0; + Status->Free = 1000; + error = GSM_WaitFor(s, "", 0, NUM_CALENDAR_REQUEST_COUNT, S60_TIMEOUT, ID_GetCalendarNotesInfo); + s->Phone.Data.ToDoStatus = NULL; + return error; +} + +static GSM_Error S60_GetToDoLocations(GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + + Priv->ToDoLocationsPos = 0; + return GSM_WaitFor(s, "", 0, NUM_CALENDAR_REQUEST_ENTRIES_ALL, S60_TIMEOUT, ID_GetToDoInfo); +} + +static GSM_Error S60_Reply_ToDoCount(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + GSM_Error error; + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + + } + + if (Priv->MessageParts[0] == NULL || Priv->MessageParts[1] == NULL) { + return ERR_UNKNOWN; + } + + if (strcmp(Priv->MessageParts[1], "todo") != 0) { + return ERR_NEEDANOTHERANSWER; + } + + error = S60_StoreLocation(s, &Priv->ToDoLocations, &Priv->ToDoLocationsSize, &Priv->ToDoLocationsPos, atoi(Priv->MessageParts[0])); + if (error != ERR_NONE) { + return error; + + } + + if (s->Phone.Data.ToDoStatus != NULL) { + s->Phone.Data.ToDoStatus->Used++; + } + return ERR_NEEDANOTHERANSWER; +} + +GSM_Error S60_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *Entry) +{ + char buffer[100]; + GSM_Error error; + + if (Entry->MemoryType != MEM_ME) { + return ERR_NOTSUPPORTED; + } + Entry->EntriesNum = 0; + + sprintf(buffer, "%d", Entry->Location); + + s->Phone.Data.Memory = Entry; + error = GSM_WaitFor(s, buffer, strlen(buffer), NUM_CONTACTS_REQUEST_CONTACT, S60_TIMEOUT, ID_GetMemory); + s->Phone.Data.Memory = NULL; + + return error; +} + +GSM_Error S60_GetNextMemory(GSM_StateMachine *s, GSM_MemoryEntry *Entry, gboolean Start) +{ + GSM_Error error; + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + + if (Entry->MemoryType != MEM_ME) { + return ERR_NOTSUPPORTED; + } + + if (Start) { + error = S60_GetMemoryLocations(s); + if (error != ERR_NONE) { + return error; + } + Priv->ContactLocationsPos = 0; + } + + if (Priv->ContactLocations[Priv->ContactLocationsPos] == 0) { + return ERR_EMPTY; + } + + Entry->Location = Priv->ContactLocations[Priv->ContactLocationsPos++]; + + return S60_GetMemory(s, Entry); +} + +static GSM_Error S60_Reply_GetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + GSM_Error error; + char *pos, *type, *location, *value; + GSM_MemoryEntry *Entry; + gboolean text = FALSE; + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + } + + Entry = s->Phone.Data.Memory; + + /* Grab values */ + pos = Priv->MessageParts[0]; + type = Priv->MessageParts[1]; + location = Priv->MessageParts[2]; + value =Priv->MessageParts[3]; + + /* We need all of them */ + if (pos == NULL || type == NULL || location == NULL || value == NULL) { + return ERR_UNKNOWN; + } + + /* Handle location */ + if ((strcmp(location, "work") == 0)) { + Entry->Entries[Entry->EntriesNum].Location = PBK_Location_Work; + } else if ((strcmp(location, "home") == 0)) { + Entry->Entries[Entry->EntriesNum].Location = PBK_Location_Home; + } else { + Entry->Entries[Entry->EntriesNum].Location = PBK_Location_Unknown; + } + + /* Store in contacts */ + if(strcmp(type, "city") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_City; + } else if(strcmp(type, "company_name") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_Company; + } else if(strcmp(type, "country") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_Country; + } else if(strcmp(type, "date") == 0) { + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Date; + if (!ReadVCALDateTime(value, &(Entry->Entries[Entry->EntriesNum].Date))) { + return ERR_UNKNOWN; + } + } else if(strcmp(type, "dtmf_string") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_DTMF; + } else if(strcmp(type, "email_address") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_Email; + } else if(strcmp(type, "extended_address") == 0) { + text = TRUE; + } else if(strcmp(type, "fax_number") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Number_Fax; + } else if(strcmp(type, "first_name") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_FirstName; + } else if(strcmp(type, "second_name") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_SecondName; + } else if(strcmp(type, "job_title") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_JobTitle; + } else if(strcmp(type, "last_name") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_LastName; + } else if(strcmp(type, "voip") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_VOIP; + } else if(strcmp(type, "sip_id") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_SIP; + } else if(strcmp(type, "push_to_talk") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_PushToTalkID; + } else if(strcmp(type, "mobile_number") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Number_Mobile; + } else if(strcmp(type, "note") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_Note; + } else if(strcmp(type, "pager_number") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Number_Pager; + } else if(strcmp(type, "phone_number") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Number_General; + } else if(strcmp(type, "postal_address") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_Postal; + } else if(strcmp(type, "postal_code") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_Zip; + } else if(strcmp(type, "state") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_State; + } else if(strcmp(type, "street_address") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_StreetAddress; + } else if(strcmp(type, "url") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_URL; + } else if(strcmp(type, "video_number") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Number_Video; + } else if(strcmp(type, "wvid") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_WVID; + } else if(strcmp(type, "thumbnail_image") == 0) { + /* TODO */ + } else if(strcmp(type, "suffix") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_NameSuffix; + } else if(strcmp(type, "prefix") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_NamePrefix; + } else if(strcmp(type, "share_view") == 0) { + text = TRUE; + Entry->Entries[Entry->EntriesNum].EntryType = PBK_Text_SWIS; + } else { + smprintf(s, "WARNING: Ignoring unknown field type: %s\n", type); + return ERR_NEEDANOTHERANSWER; + } + + if (text) { + DecodeUTF8(Entry->Entries[Entry->EntriesNum].Text, value, strlen(value)); + } + + Entry->EntriesNum++; + + return ERR_NEEDANOTHERANSWER; +} + +GSM_Error S60_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *Entry) +{ + char buffer[100]; + GSM_Error error; + + if (Entry->MemoryType != MEM_ME) { + return ERR_NOTSUPPORTED; + } + + sprintf(buffer, "%d", Entry->Location); + + error = GSM_WaitFor(s, buffer, strlen(buffer), NUM_CONTACTS_DELETE, S60_TIMEOUT, ID_None); + + return error; +} + +GSM_Error S60_SetMemoryEntry(GSM_StateMachine *s, GSM_SubMemoryEntry *Entry, int pos, int reqtype) +{ + const char *type, *location = "none"; + char value[(GSM_PHONEBOOK_TEXT_LENGTH + 1) * 2]; + char buffer [100 + (GSM_PHONEBOOK_TEXT_LENGTH + 1) * 2]; + gboolean text = FALSE; + + switch (Entry->Location) { + case PBK_Location_Unknown: + location = "none"; + break; + case PBK_Location_Home: + location = "home"; + break; + case PBK_Location_Work: + location = "work"; + break; + } + + switch (Entry->EntryType) { + case PBK_Text_City: + type = "city"; + text = TRUE; + break; + case PBK_Text_Company: + type = "company_name"; + text = TRUE; + break; + case PBK_Text_Country: + type = "country"; + text = TRUE; + break; + case PBK_Date: + type = "date"; + snprintf(value, sizeof(value), "%04d%02d%02d", Entry->Date.Year, Entry->Date.Month, Entry->Date.Day); + break; + case PBK_Text_DTMF: + type = "dtmf_string"; + text = TRUE; + break; + case PBK_Text_Email: + type = "email_address"; + text = TRUE; + break; + case PBK_Number_Fax: + type = "fax_number"; + text = TRUE; + break; + case PBK_Text_FirstName: + type = "first_name"; + text = TRUE; + break; + case PBK_Text_SecondName: + type = "second_name"; + text = TRUE; + break; + case PBK_Text_JobTitle: + type = "job_title"; + text = TRUE; + break; + case PBK_Text_LastName: + type = "last_name"; + text = TRUE; + break; + case PBK_Text_VOIP: + type = "voip"; + text = TRUE; + break; + case PBK_Text_SIP: + type = "sip_id"; + text = TRUE; + break; + case PBK_PushToTalkID: + type = "push_to_talk"; + text = TRUE; + break; + case PBK_Number_Mobile: + type = "mobile_number"; + text = TRUE; + break; + case PBK_Text_Note: + type = "note"; + text = TRUE; + break; + case PBK_Number_Pager: + type = "pager"; + text = TRUE; + break; + case PBK_Number_General: + type = "phone_number"; + text = TRUE; + break; + case PBK_Text_Postal: + type = "postal_address"; + text = TRUE; + break; + case PBK_Text_Zip: + type = "postal_code"; + text = TRUE; + break; + case PBK_Text_State: + type = "state"; + text = TRUE; + break; + case PBK_Text_StreetAddress: + type = "street_address"; + text = TRUE; + break; + case PBK_Text_URL: + type = "url"; + text = TRUE; + break; + case PBK_Number_Video: + type = "video_number"; + text = TRUE; + break; + case PBK_Text_WVID: + type = "wvid"; + text = TRUE; + break; + case PBK_Text_NameSuffix: + type = "suffix"; + text = TRUE; + break; + case PBK_Text_NamePrefix: + type = "prefix"; + text = TRUE; + break; + case PBK_Text_SWIS: + type = "share_view"; + text = TRUE; + break; + default: + Entry->AddError = ERR_NOTIMPLEMENTED; + return ERR_NONE; + } + + if (text) { + EncodeUTF8(value, Entry->Text); + } + + snprintf(buffer, sizeof(buffer), "%d%c%s%c%s%c%s%c", + pos, NUM_SEPERATOR, + type , NUM_SEPERATOR, + location, NUM_SEPERATOR, + value, NUM_SEPERATOR); + + return GSM_WaitFor(s, buffer, strlen(buffer), reqtype, S60_TIMEOUT, ID_None); +} + +GSM_Error S60_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *Entry) +{ + GSM_MemoryEntry oldentry; + GSM_Error error; + int i; + + if (Entry->MemoryType != MEM_ME) { + return ERR_NOTSUPPORTED; + } + oldentry.MemoryType = Entry->MemoryType; + oldentry.Location = Entry->Location; + + /* Read existing entry */ + error = S60_GetMemory(s, &oldentry); + if (error != ERR_NONE) { + return error; + } + + /* TODO: Here should be some clever method for doing only needed changes */ + + /* Delete all existing fields */ + for (i = 0; i < oldentry.EntriesNum; i++) { + error = S60_SetMemoryEntry(s, &(oldentry.Entries[i]), Entry->Location, NUM_CONTACTS_CHANGE_REMOVEFIELD); + if (error != ERR_NONE) { + return error; + } + } + + /* Set all new fields */ + for (i = 0; i < Entry->EntriesNum; i++) { + error = S60_SetMemoryEntry(s, &(Entry->Entries[i]), Entry->Location, NUM_CONTACTS_CHANGE_ADDFIELD); + if (error != ERR_NONE) { + return error; + } + } + + return ERR_NONE; +} + +GSM_Error S60_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *Entry) +{ + GSM_Error error; + + if (Entry->MemoryType != MEM_ME) { + return ERR_NOTSUPPORTED; + } + + s->Phone.Data.Memory = Entry; + error = GSM_WaitFor(s, NULL, 0, NUM_CONTACTS_ADD, S60_TIMEOUT, ID_SetMemory); + s->Phone.Data.Memory = NULL; + + if (error != ERR_NONE) { + return error; + } + + return S60_SetMemory(s, Entry); +} + +static GSM_Error S60_Reply_AddMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + s->Phone.Data.Memory->Location = atoi(msg.Buffer); + smprintf(s, "Added contact ID %d\n", s->Phone.Data.Memory->Location); + return ERR_NONE; +} + +static GSM_Error S60_Reply_GetCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + GSM_Error error; + char *type, *content, *location, *start, *end, *modified, *replication, *alarm_time, *repeat, *repeat_rule, *repeat_start, *repeat_end, *interval; + GSM_CalendarEntry *Entry; + int i; + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + } + + /* Check for required fields */ + for (i = 0; i < 16; i++) { + if (Priv->MessageParts[i] == NULL) { + smprintf(s, "Not enough parts in reply!\n"); + return ERR_UNKNOWN; + } + } + + Entry = s->Phone.Data.Cal; + + /* Grab values */ + /* No need to parse position */ + type = Priv->MessageParts[1]; + content = Priv->MessageParts[2]; + location = Priv->MessageParts[3]; + start = Priv->MessageParts[4]; + end = Priv->MessageParts[5]; + modified = Priv->MessageParts[6]; + replication = Priv->MessageParts[7]; + alarm_time = Priv->MessageParts[8]; + /* Priority not used for calendar */ + repeat = Priv->MessageParts[10]; + repeat_rule = Priv->MessageParts[11]; + /* We do not handle repeat_exceptions for now */ + repeat_start = Priv->MessageParts[13]; + repeat_end = Priv->MessageParts[14]; + interval = Priv->MessageParts[15]; + + /* Check for correct type */ + if (strcmp(type, "appointment") == 0) { + Entry->Type = GSM_CAL_MEETING; + } else if (strcmp(type, "event") == 0) { + Entry->Type = GSM_CAL_MEMO; + } else if (strcmp(type, "anniversary") == 0) { + Entry->Type = GSM_CAL_BIRTHDAY; + } else if (strcmp(type, "reminder") == 0) { + Entry->Type = GSM_CAL_REMINDER; + } else { + return ERR_EMPTY; + } + + if (strlen(content) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_TEXT; + DecodeUTF8(Entry->Entries[Entry->EntriesNum].Text, content, strlen(content)); + Entry->EntriesNum++; + } + + if (strlen(location) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_LOCATION; + DecodeUTF8(Entry->Entries[Entry->EntriesNum].Text, location, strlen(location)); + Entry->EntriesNum++; + } + + if (strlen(start) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_START_DATETIME; + GSM_DateTimeFromTimestamp(&(Entry->Entries[Entry->EntriesNum].Date), start); + Entry->EntriesNum++; + } + + if (strlen(end) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_END_DATETIME; + GSM_DateTimeFromTimestamp(&(Entry->Entries[Entry->EntriesNum].Date), end); + Entry->EntriesNum++; + } + + if (strlen(modified) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_LAST_MODIFIED; + GSM_DateTimeFromTimestamp(&(Entry->Entries[Entry->EntriesNum].Date), modified); + Entry->EntriesNum++; + } + + if (strlen(replication) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_PRIVATE; + if (strcmp(replication, "open") == 0) { + Entry->Entries[Entry->EntriesNum].Number = 0; + } else { + Entry->Entries[Entry->EntriesNum].Number = 1; + } + Entry->EntriesNum++; + } + + if (strlen(alarm_time) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_TONE_ALARM_DATETIME; + GSM_DateTimeFromTimestamp(&(Entry->Entries[Entry->EntriesNum].Date), alarm_time); + Entry->EntriesNum++; + } + + if ((strlen(repeat) > 0) && (strlen(repeat_rule) > 0)) { + if (strcmp(repeat, "daily") == 0 ) { + } else if (strcmp(repeat, "weekly") == 0 ) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_REPEAT_DAYOFWEEK; + Entry->Entries[Entry->EntriesNum].Number = atoi(repeat_rule); + Entry->EntriesNum++; + } else if (strcmp(repeat, "monthly_by_dates") == 0 ) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_REPEAT_DAY; + Entry->Entries[Entry->EntriesNum].Number = atoi(repeat_rule); + Entry->EntriesNum++; + } else if (strcmp(repeat, "monthly_by_days") == 0 ) { + } else if (strcmp(repeat, "yearly_by_date") == 0 ) { + } else if (strcmp(repeat, "yearly_by_day") == 0 ) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_REPEAT_DAYOFYEAR; + Entry->Entries[Entry->EntriesNum].Number = atoi(repeat_rule); + Entry->EntriesNum++; + } else { + smprintf(s, "Unknown value for repeating: %s\n", repeat); + return ERR_UNKNOWN; + } + } + + if (strlen(repeat_start) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_REPEAT_STARTDATE; + GSM_DateTimeFromTimestamp(&(Entry->Entries[Entry->EntriesNum].Date), repeat_start); + Entry->EntriesNum++; + } + + if (strlen(repeat_end) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_REPEAT_STOPDATE; + GSM_DateTimeFromTimestamp(&(Entry->Entries[Entry->EntriesNum].Date), repeat_end); + Entry->EntriesNum++; + } + + if (strlen(interval) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = CAL_REPEAT_FREQUENCY; + Entry->Entries[Entry->EntriesNum].Number = atoi(interval); + Entry->EntriesNum++; + } + + + /* TODO: implement rest of repeating */ + + return ERR_NONE; +} + +GSM_Error S60_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Entry) +{ + char buffer[100]; + GSM_Error error; + + Entry->EntriesNum = 0; + + sprintf(buffer, "%d", Entry->Location); + + s->Phone.Data.Cal = Entry; + error = GSM_WaitFor(s, buffer, strlen(buffer), NUM_CALENDAR_REQUEST_ENTRY, S60_TIMEOUT, ID_GetCalendarNote); + s->Phone.Data.Cal = NULL; + + return error; +} + +static GSM_Error S60_Reply_AddCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + s->Phone.Data.Cal->Location = atoi(msg.Buffer); + smprintf(s, "Added calendar ID %d\n", s->Phone.Data.Cal->Location); + return ERR_NONE; +} + +int S60_FindCalendarField(GSM_StateMachine *s, GSM_CalendarEntry *Entry, GSM_CalendarType Type) +{ + int i; + + for (i = 0; i < Entry->EntriesNum; i++) { + if (Entry->Entries[i].EntryType == Type && Entry->Entries[i].AddError == ERR_NOTSUPPORTED) { + Entry->Entries[i].AddError = ERR_NONE; + return i; + } + } + return -1; +} + +void S60_SetCalendarError(GSM_StateMachine *s, GSM_CalendarEntry *Entry) +{ + int i; + + for (i = 0; i < Entry->EntriesNum; i++) { + Entry->Entries[i].AddError = ERR_NOTSUPPORTED; + } +} + +GSM_Error S60_SetAddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Entry, int request, int ID_request) +{ + int i; + char buffer[1024]; + const char *type; + + if (ID_request == ID_SetCalendarNote) { + sprintf(buffer, "%d%s", Entry->Location, NUM_SEPERATOR_STR); + } else { + switch (Entry->Type) { + case GSM_CAL_MEETING: + type = "appointment"; + break; + case GSM_CAL_MEMO: + type = "event"; + break; + case GSM_CAL_BIRTHDAY: + type = "anniversary"; + break; + case GSM_CAL_REMINDER: + type = "reminder"; + break; + default: + type = "appointment"; + break; + } + sprintf(buffer, "%s%s", type, NUM_SEPERATOR_STR); + } + + + S60_SetCalendarError(s, Entry); + + i = S60_FindCalendarField(s, Entry, CAL_TEXT); + if (i == -1) { + i = S60_FindCalendarField(s, Entry, CAL_DESCRIPTION); + } + if (i != -1) { + EncodeUTF8(buffer + strlen(buffer), Entry->Entries[i].Text); + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindCalendarField(s, Entry, CAL_LOCATION); + if (i != -1) { + EncodeUTF8(buffer + strlen(buffer), Entry->Entries[i].Text); + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindCalendarField(s, Entry, CAL_START_DATETIME); + if (i != -1) { + GSM_DateTimeToTimestamp(&(Entry->Entries[i].Date), buffer + strlen(buffer)); + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindCalendarField(s, Entry, CAL_END_DATETIME); + if (i != -1) { + GSM_DateTimeToTimestamp(&(Entry->Entries[i].Date), buffer + strlen(buffer)); + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindCalendarField(s, Entry, CAL_PRIVATE); + if (i == -1) { + if (Entry->Entries[i].Number) { + strcat(buffer, "private"); + } else { + strcat(buffer, "open"); + } + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindCalendarField(s, Entry, CAL_TONE_ALARM_DATETIME); + if (i == -1) { + i = S60_FindCalendarField(s, Entry, CAL_SILENT_ALARM_DATETIME); + } + if (i != -1) { + GSM_DateTimeToTimestamp(&(Entry->Entries[i].Date), buffer + strlen(buffer)); + } + strcat(buffer, NUM_SEPERATOR_STR); + + /* Priority */ + strcat(buffer, "2"); + strcat(buffer, NUM_SEPERATOR_STR); + + /* TODO: implement repeating */ + strcat(buffer, NUM_SEPERATOR_STR); /* Type */ + strcat(buffer, NUM_SEPERATOR_STR); /* Days */ + strcat(buffer, NUM_SEPERATOR_STR); /* Exceptions */ + + i = S60_FindCalendarField(s, Entry, CAL_REPEAT_STARTDATE); + if (i != -1) { + GSM_DateTimeToTimestamp(&(Entry->Entries[i].Date), buffer + strlen(buffer)); + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindCalendarField(s, Entry, CAL_REPEAT_STOPDATE); + if (i != -1) { + GSM_DateTimeToTimestamp(&(Entry->Entries[i].Date), buffer + strlen(buffer)); + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindCalendarField(s, Entry, CAL_REPEAT_FREQUENCY); + if (i != -1) { + sprintf(buffer + strlen(buffer), "%d", Entry->Entries[i].Number); + } + strcat(buffer, NUM_SEPERATOR_STR); + + return GSM_WaitFor(s, buffer, strlen(buffer), request, S60_TIMEOUT, ID_request); +} + +GSM_Error S60_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Entry) +{ + return S60_SetAddCalendar(s, Entry, NUM_CALENDAR_ENTRY_CHANGE, ID_SetCalendarNote); +} + +GSM_Error S60_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Entry) +{ + s->Phone.Data.Cal = Entry; + return S60_SetAddCalendar(s, Entry, NUM_CALENDAR_ENTRY_ADD, ID_AddCalendarNote); +} + +GSM_Error S60_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Entry, gboolean Start) +{ + GSM_Error error; + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + + if (Start) { + error = S60_GetCalendarLocations(s); + if (error != ERR_NONE) { + return error; + } + Priv->CalendarLocationsPos = 0; + } + + if (Priv->CalendarLocations[Priv->CalendarLocationsPos] == 0) { + return ERR_EMPTY; + } + + Entry->Location = Priv->CalendarLocations[Priv->CalendarLocationsPos++]; + + return S60_GetCalendar(s, Entry); +} + +GSM_Error S60_DeleteCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Entry) +{ + char buffer[100]; + GSM_Error error; + + sprintf(buffer, "%d", Entry->Location); + + error = GSM_WaitFor(s, buffer, strlen(buffer), NUM_CALENDAR_ENTRY_DELETE, S60_TIMEOUT, ID_None); + + return error; +} + +static GSM_Error S60_Reply_GetToDo(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + GSM_Error error; + char *type, *content, *location, *start, *end, *modified, *replication, *alarm_time, *priority, *crossedout, *crossedout_time; + GSM_ToDoEntry *Entry; + int i; + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + } + + /* Check for required fields */ + for (i = 0; i < 18; i++) { + if (Priv->MessageParts[i] == NULL) { + smprintf(s, "Not enough parts in reply!\n"); + return ERR_UNKNOWN; + } + } + + Entry = s->Phone.Data.ToDo; + + /* Grab values */ + /* No need to parse position */ + type = Priv->MessageParts[1]; + content = Priv->MessageParts[2]; + location = Priv->MessageParts[3]; + start = Priv->MessageParts[4]; + end = Priv->MessageParts[5]; + modified = Priv->MessageParts[6]; + replication = Priv->MessageParts[7]; + alarm_time = Priv->MessageParts[8]; + priority = Priv->MessageParts[9]; + /* Repeating does not make sense for todo */ + crossedout = Priv->MessageParts[16]; + crossedout_time = Priv->MessageParts[17]; + + /* Check for correct type */ + if (strcmp(type, "todo") == 0) { + Entry->Type = GSM_CAL_MEMO; + } else { + return ERR_EMPTY; + } + + if (strlen(content) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = TODO_TEXT; + DecodeUTF8(Entry->Entries[Entry->EntriesNum].Text, content, strlen(content)); + Entry->EntriesNum++; + } + + if (strlen(location) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = TODO_LOCATION; + DecodeUTF8(Entry->Entries[Entry->EntriesNum].Text, location, strlen(location)); + Entry->EntriesNum++; + } + + if (strlen(start) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = TODO_START_DATETIME; + GSM_DateTimeFromTimestamp(&(Entry->Entries[Entry->EntriesNum].Date), start); + Entry->EntriesNum++; + } + + if (strlen(end) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = TODO_END_DATETIME; + GSM_DateTimeFromTimestamp(&(Entry->Entries[Entry->EntriesNum].Date), end); + Entry->EntriesNum++; + } + + if (strlen(modified) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = TODO_LAST_MODIFIED; + GSM_DateTimeFromTimestamp(&(Entry->Entries[Entry->EntriesNum].Date), modified); + Entry->EntriesNum++; + } + + if (strlen(replication) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = TODO_PRIVATE; + if (strcmp(replication, "open") == 0) { + Entry->Entries[Entry->EntriesNum].Number = 0; + } else { + Entry->Entries[Entry->EntriesNum].Number = 1; + } + Entry->EntriesNum++; + } + + if (strlen(alarm_time) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = TODO_ALARM_DATETIME; + GSM_DateTimeFromTimestamp(&(Entry->Entries[Entry->EntriesNum].Date), alarm_time); + Entry->EntriesNum++; + } + + if (strlen(priority) > 0) { + Entry->Priority = atoi(priority); + } + + if (strlen(crossedout) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = TODO_COMPLETED; + Entry->Entries[Entry->EntriesNum].Number = atoi(crossedout); + Entry->EntriesNum++; + } + + if (strlen(crossedout_time) > 0) { + Entry->Entries[Entry->EntriesNum].EntryType = TODO_COMPLETED_DATETIME; + GSM_DateTimeFromTimestamp(&(Entry->Entries[Entry->EntriesNum].Date), crossedout_time); + Entry->EntriesNum++; + } + + return ERR_NONE; +} + +GSM_Error S60_GetToDo(GSM_StateMachine *s, GSM_ToDoEntry *Entry) +{ + char buffer[100]; + GSM_Error error; + + Entry->EntriesNum = 0; + + sprintf(buffer, "%d", Entry->Location); + + s->Phone.Data.ToDo = Entry; + error = GSM_WaitFor(s, buffer, strlen(buffer), NUM_CALENDAR_REQUEST_ENTRY, S60_TIMEOUT, ID_GetToDo); + s->Phone.Data.ToDo = NULL; + + return error; +} + +GSM_Error S60_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *Entry, gboolean Start) +{ + GSM_Error error; + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + + if (Start) { + error = S60_GetToDoLocations(s); + if (error != ERR_NONE) { + return error; + } + Priv->ToDoLocationsPos = 0; + } + + if (Priv->ToDoLocations[Priv->ToDoLocationsPos] == 0) { + return ERR_EMPTY; + } + + Entry->Location = Priv->ToDoLocations[Priv->ToDoLocationsPos++]; + + return S60_GetToDo(s, Entry); +} + +GSM_Error S60_DeleteToDo(GSM_StateMachine *s, GSM_ToDoEntry *Entry) +{ + char buffer[100]; + GSM_Error error; + + sprintf(buffer, "%d", Entry->Location); + + error = GSM_WaitFor(s, buffer, strlen(buffer), NUM_CALENDAR_ENTRY_DELETE, S60_TIMEOUT, ID_None); + + return error; +} + +static GSM_Error S60_Reply_AddToDo(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + s->Phone.Data.ToDo->Location = atoi(msg.Buffer); + smprintf(s, "Added todo ID %d\n", s->Phone.Data.ToDo->Location); + return ERR_NONE; +} + +int S60_FindToDoField(GSM_StateMachine *s, GSM_ToDoEntry *Entry, GSM_ToDoType Type) +{ + int i; + + for (i = 0; i < Entry->EntriesNum; i++) { + if (Entry->Entries[i].EntryType == Type) { + return i; + } + } + return -1; +} + +GSM_Error S60_SetAddToDo(GSM_StateMachine *s, GSM_ToDoEntry *Entry, int request, int ID_request) +{ + int i; + char buffer[1024]; + + if (ID_request == ID_SetToDo) { + sprintf(buffer, "%d%s", Entry->Location, NUM_SEPERATOR_STR); + } else { + sprintf(buffer, "%s%s", "todo", NUM_SEPERATOR_STR); + } + + i = S60_FindToDoField(s, Entry, TODO_TEXT); + if (i == -1) { + i = S60_FindToDoField(s, Entry, TODO_DESCRIPTION); + } + if (i != -1) { + EncodeUTF8(buffer + strlen(buffer), Entry->Entries[i].Text); + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindToDoField(s, Entry, TODO_LOCATION); + if (i != -1) { + EncodeUTF8(buffer + strlen(buffer), Entry->Entries[i].Text); + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindToDoField(s, Entry, TODO_START_DATETIME); + if (i != -1) { + GSM_DateTimeToTimestamp(&(Entry->Entries[i].Date), buffer + strlen(buffer)); + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindToDoField(s, Entry, TODO_END_DATETIME); + if (i != -1) { + GSM_DateTimeToTimestamp(&(Entry->Entries[i].Date), buffer + strlen(buffer)); + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindToDoField(s, Entry, TODO_PRIVATE); + if (i == -1) { + if (Entry->Entries[i].Number) { + strcat(buffer, "private"); + } else { + strcat(buffer, "open"); + } + } + strcat(buffer, NUM_SEPERATOR_STR); + + i = S60_FindToDoField(s, Entry, TODO_ALARM_DATETIME); + if (i == -1) { + i = S60_FindToDoField(s, Entry, TODO_SILENT_ALARM_DATETIME); + } + if (i != -1) { + GSM_DateTimeToTimestamp(&(Entry->Entries[i].Date), buffer + strlen(buffer)); + } + strcat(buffer, NUM_SEPERATOR_STR); + + /* Priority */ + sprintf(buffer + strlen(buffer), "%d", Entry->Priority); + strcat(buffer, NUM_SEPERATOR_STR); + + strcat(buffer, NUM_SEPERATOR_STR); /* Type */ + strcat(buffer, NUM_SEPERATOR_STR); /* Days */ + strcat(buffer, NUM_SEPERATOR_STR); /* Exceptions */ + strcat(buffer, NUM_SEPERATOR_STR); /* Start */ + strcat(buffer, NUM_SEPERATOR_STR); /* End */ + strcat(buffer, NUM_SEPERATOR_STR); /* Frequency */ + + return GSM_WaitFor(s, buffer, strlen(buffer), request, S60_TIMEOUT, ID_request); +} + +GSM_Error S60_SetToDo(GSM_StateMachine *s, GSM_ToDoEntry *Entry) +{ + return S60_SetAddToDo(s, Entry, NUM_CALENDAR_ENTRY_CHANGE, ID_SetToDo); +} + +GSM_Error S60_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *Entry) +{ + s->Phone.Data.ToDo = Entry; + return S60_SetAddToDo(s, Entry, NUM_CALENDAR_ENTRY_ADD, ID_AddToDo); +} + +GSM_Error S60_GetScreenshot(GSM_StateMachine *s, GSM_BinaryPicture *picture) +{ + GSM_Error error; + + s->Phone.Data.Picture = picture; + error = GSM_WaitFor(s, NULL, 0, NUM_SCREENSHOT, S60_TIMEOUT, ID_Screenshot); + s->Phone.Data.Picture = NULL; + + return error; +} + +GSM_Error S60_Reply_Screenshot(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + s->Phone.Data.Picture->Type = PICTURE_PNG; + s->Phone.Data.Picture->Buffer = (unsigned char *)malloc(msg.Length); + if (s->Phone.Data.Picture->Buffer == NULL) { + return ERR_MOREMEMORY; + } + s->Phone.Data.Picture->Length = DecodeBASE64(msg.Buffer, s->Phone.Data.Picture->Buffer, msg.Length); + return ERR_NONE; +} + +GSM_Error S60_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status) +{ + GSM_Error error; + + status->SIMUnRead = 0; + status->SIMUsed = 0; + status->SIMSize = 0; + status->TemplatesUsed = 0; + status->PhoneUnRead = 0; + status->PhoneUsed = 0; + status->PhoneSize = 0; + + s->Phone.Data.SMSStatus = status; + error = GSM_WaitFor(s, NULL, 0, NUM_MESSAGE_REQUEST_COUNT, S60_TIMEOUT, ID_GetSMSStatus); + s->Phone.Data.SMSStatus = NULL; + + return error; +} + +GSM_Error S60_Reply_GetSMSStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Error error; + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + } + + if (Priv->MessageParts[0] == NULL || Priv->MessageParts[1] == NULL) { + return ERR_UNKNOWN; + } + s->Phone.Data.SMSStatus->PhoneUsed = atoi(Priv->MessageParts[0]); + s->Phone.Data.SMSStatus->PhoneUnRead = atoi(Priv->MessageParts[1]); + s->Phone.Data.SMSStatus->PhoneSize = s->Phone.Data.SMSStatus->PhoneUsed + 1000; + + return ERR_NONE; +} + +GSM_Error S60_GetSMSFolders(GSM_StateMachine *s UNUSED, GSM_SMSFolders *folders) +{ + folders->Number=2; + EncodeUnicode(folders->Folder[0].Name,_("Inbox"),strlen(_("Inbox"))); + EncodeUnicode(folders->Folder[1].Name,_("Outbox"),strlen(_("Outbox"))); + folders->Folder[0].InboxFolder = TRUE; + folders->Folder[1].InboxFolder = FALSE; + folders->Folder[0].OutboxFolder = FALSE; + folders->Folder[1].OutboxFolder = TRUE; + folders->Folder[0].Memory = MEM_ME; + folders->Folder[1].Memory = MEM_ME; + return ERR_NONE; +} + +GSM_Error S60_GetSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms) +{ + + char buffer[100]; + + sprintf(buffer, "%d", sms->SMS[0].Location); + + sms->Number = 1; + GSM_SetDefaultReceivedSMSData(&(sms->SMS[0])); + s->Phone.Data.SaveSMSMessage = &(sms->SMS[0]); + + + return GSM_WaitFor(s, buffer, strlen(buffer), NUM_MESSAGE_REQUEST_ONE, S60_TIMEOUT, ID_GetSMSMessage); +} + +GSM_Error S60_DeleteSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) +{ + + char buffer[100]; + + sprintf(buffer, "%d", sms->Location); + + return GSM_WaitFor(s, buffer, strlen(buffer), NUM_MESSAGE_DELETE, S60_TIMEOUT, ID_None); +} + +GSM_Error S60_Reply_GetSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Error error; + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + int i; + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + } + + if (Priv->MessageParts[0] == NULL || Priv->MessageParts[0][0] == 0) { + return ERR_EMPTY; + } + + /* Check for required fields */ + for (i = 0; i < 6; i++) { + if (Priv->MessageParts[i] == NULL) { + smprintf(s, "Not enough parts in reply!\n"); + return ERR_UNKNOWN; + } + } + + /* Folder */ + if (strcmp(Priv->MessageParts[0], "inbox") == 0) { + s->Phone.Data.SaveSMSMessage->Folder = 1; + s->Phone.Data.SaveSMSMessage->InboxFolder = TRUE; + s->Phone.Data.SaveSMSMessage->PDU = SMS_Deliver; + } else { + s->Phone.Data.SaveSMSMessage->Folder = 2; + s->Phone.Data.SaveSMSMessage->InboxFolder = FALSE; + s->Phone.Data.SaveSMSMessage->PDU = SMS_Submit; + } + + /* ID */ + + /* Time */ + GSM_DateTimeFromTimestamp(&(s->Phone.Data.SaveSMSMessage->DateTime), Priv->MessageParts[2]); + + /* Address */ + DecodeUTF8(s->Phone.Data.SaveSMSMessage->Number, Priv->MessageParts[3], strlen(Priv->MessageParts[3])); + + /* Content */ + DecodeUTF8(s->Phone.Data.SaveSMSMessage->Text, Priv->MessageParts[4], strlen(Priv->MessageParts[4])); + s->Phone.Data.SaveSMSMessage->Length = UnicodeLength(s->Phone.Data.SaveSMSMessage->Text); + s->Phone.Data.SaveSMSMessage->Coding = SMS_Coding_Default_No_Compression; + + /* Unread */ + if (strcmp(Priv->MessageParts[5], "1") == 0) { + s->Phone.Data.SaveSMSMessage->State = SMS_UnRead; + } else if (s->Phone.Data.SaveSMSMessage->InboxFolder) { + s->Phone.Data.SaveSMSMessage->State = SMS_Read; + } else { + s->Phone.Data.SaveSMSMessage->State = SMS_Sent; + } + return ERR_NONE; +} + +GSM_Error S60_Reply_SMSLocation(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + GSM_Error error; + + error = S60_SplitValues(&msg, s); + if (error != ERR_NONE) { + return error; + + } + + if (Priv->MessageParts[0] == NULL) { + return ERR_UNKNOWN; + } + + error = S60_StoreLocation(s, &Priv->SMSLocations, &Priv->SMSLocationsSize, &Priv->SMSLocationsPos, atoi(Priv->MessageParts[0])); + if (error != ERR_NONE) { + return error; + + } + + return ERR_NEEDANOTHERANSWER; +} + + +static GSM_Error S60_GetSMSLocations(GSM_StateMachine *s) +{ + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + Priv->SMSLocationsPos = 0; + return GSM_WaitFor(s, "", 0, NUM_MESSAGE_REQUEST_LIST, S60_TIMEOUT, ID_GetSMSStatus); +} + +GSM_Error S60_GetNextSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboolean Start) +{ + GSM_Error error; + GSM_Phone_S60Data *Priv = &s->Phone.Data.Priv.S60; + + if (Start) { + error = S60_GetSMSLocations(s); + if (error != ERR_NONE) { + return error; + } + Priv->SMSLocationsPos = 0; + } + + if (Priv->SMSLocations[Priv->SMSLocationsPos] == 0) { + return ERR_EMPTY; + } + + sms->SMS[0].Location = Priv->SMSLocations[Priv->SMSLocationsPos++]; + + return S60_GetSMS(s, sms); +} + +GSM_Error S60_SendSMS(GSM_StateMachine *s, GSM_SMSMessage *sms) +{ + char buffer[((GSM_MAX_SMS_LENGTH + 1) * 2) + ((GSM_MAX_SMS_NAME_LENGTH + 1) * 2) + ((GSM_MAX_NUMBER_LENGTH + 1) * 2)]; + + if (sms->UDH.Type != UDH_NoUDH) { + return ERR_NOTSUPPORTED; + } + + EncodeUTF8(buffer, sms->Name); + strcat(buffer, NUM_SEPERATOR_STR); + EncodeUTF8(buffer + strlen(buffer), sms->Number); + strcat(buffer, NUM_SEPERATOR_STR); + switch (sms->Coding) { + case SMS_Coding_Unicode_No_Compression: + case SMS_Coding_Unicode_Compression: + strcat(buffer, "UCS2"); + break; + case SMS_Coding_Default_No_Compression: + case SMS_Coding_Default_Compression: + strcat(buffer, "7bit"); + break; + case SMS_Coding_8bit: + strcat(buffer, "8bit"); + break; + } + strcat(buffer, NUM_SEPERATOR_STR); + EncodeUTF8(buffer + strlen(buffer), sms->Text); + strcat(buffer, NUM_SEPERATOR_STR); + + return GSM_WaitFor(s, buffer, strlen(buffer), NUM_MESSAGE_SEND_REQUEST, S60_TIMEOUT, ID_None); +} + +GSM_Error S60_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) +{ + if (smsc->Location != 1) { + return ERR_EMPTY; + } + smsc->Name[0] = 0; + smsc->Name[1] = 0; + smsc->Number[0] = 0; + smsc->Number[1] = 0; + smsc->Validity.Format = SMS_Validity_NotAvailable; + smsc->Validity.Relative = SMS_VALID_Max_Time; + smsc->DefaultNumber[0] = 0; + smsc->DefaultNumber[1] = 0; + smsc->Format = SMS_FORMAT_Text; + return ERR_NONE; +} + +GSM_Error S60_DialVoice(GSM_StateMachine *s, char *Number, GSM_CallShowNumber ShowNumber) +{ + return GSM_WaitFor(s, Number, strlen(Number), NUM_DIAL, S60_TIMEOUT, ID_None); +} + +GSM_Error S60_CancelCall(GSM_StateMachine *s, int ID, gboolean all) +{ + return GSM_WaitFor(s, "", 0, NUM_HANGUP, S60_TIMEOUT, ID_None); +} + +GSM_Reply_Function S60ReplyFunctions[] = { + + {S60_Reply_Connect, "", 0x00, NUM_CONNECTED, ID_Initialise }, + {S60_Reply_Generic, "", 0x00, NUM_HELLO_REPLY, ID_EnableEcho }, + + {S60_Reply_Generic, "", 0x00, NUM_SYSINFO_REPLY_START, ID_GetModel }, + {S60_Reply_GetInfo, "", 0x00, NUM_SYSINFO_REPLY_LINE, ID_GetModel }, + {S60_Reply_Generic, "", 0x00, NUM_SYSINFO_REPLY_END, ID_GetModel }, + + {S60_Reply_Generic, "", 0x00, NUM_CONTACTS_REPLY_HASH_SINGLE_START, ID_GetMemoryStatus }, + {S60_Reply_ContactHash, "", 0x00, NUM_CONTACTS_REPLY_HASH_SINGLE_LINE, ID_GetMemoryStatus }, + {S60_Reply_Generic, "", 0x00, NUM_CONTACTS_REPLY_HASH_SINGLE_END, ID_GetMemoryStatus }, + + {S60_Reply_SMSLocation, "", 0x00, NUM_MESSAGE_REPLY_LIST, ID_GetSMSStatus }, + {S60_Reply_Generic, "", 0x00, NUM_MESSAGE_REPLY_END, ID_GetSMSStatus }, + + {S60_Reply_GetMemoryStatus, "", 0x00, NUM_CONTACTS_REPLY_COUNT, ID_GetMemoryStatus }, + + {S60_Reply_Generic, "", 0x00, NUM_CALENDAR_REPLY_ENTRIES_START, ID_GetCalendarNotesInfo }, + {S60_Reply_CalendarCount, "", 0x00, NUM_CALENDAR_REPLY_ENTRY, ID_GetCalendarNotesInfo }, + {S60_Reply_Generic, "", 0x00, NUM_CALENDAR_REPLY_ENTRIES_END, ID_GetCalendarNotesInfo }, + + {S60_Reply_Generic, "", 0x00, NUM_CALENDAR_REPLY_ENTRIES_START, ID_GetToDoInfo }, + {S60_Reply_ToDoCount, "", 0x00, NUM_CALENDAR_REPLY_ENTRY, ID_GetToDoInfo }, + {S60_Reply_Generic, "", 0x00, NUM_CALENDAR_REPLY_ENTRIES_END, ID_GetToDoInfo }, + + {S60_Reply_Generic, "", 0x00, NUM_CONTACTS_REPLY_CONTACT_START, ID_GetMemory }, + {S60_Reply_GetMemory, "", 0x00, NUM_CONTACTS_REPLY_CONTACT_LINE, ID_GetMemory }, + {S60_Reply_Generic, "", 0x00, NUM_CONTACTS_REPLY_CONTACT_END, ID_GetMemory }, + {S60_Reply_Generic, "", 0x00, NUM_CONTACTS_REPLY_CONTACT_NOT_FOUND, ID_GetMemory }, + + {S60_Reply_GetCalendar, "", 0x00, NUM_CALENDAR_REPLY_ENTRY, ID_GetCalendarNote }, + {S60_Reply_Generic, "", 0x00, NUM_CALENDAR_REPLY_ENTRY_NOT_FOUND, ID_GetCalendarNote }, + + {S60_Reply_GetToDo, "", 0x00, NUM_CALENDAR_REPLY_ENTRY, ID_GetToDo }, + {S60_Reply_Generic, "", 0x00, NUM_CALENDAR_REPLY_ENTRY_NOT_FOUND, ID_GetToDo }, + + {S60_Reply_AddMemory, "", 0x00, NUM_CONTACTS_ADD_REPLY_ID, ID_SetMemory }, + + {S60_Reply_GetNetworkInfo, "", 0x00, NUM_LOCATION_REPLY, ID_GetNetworkInfo }, + {S60_Reply_Generic, "", 0x00, NUM_LOCATION_REPLY_NA, ID_GetNetworkInfo }, + + {S60_Reply_Generic, "", 0x00, NUM_QUIT, ID_Terminate }, + + {S60_Reply_Screenshot, "", 0x00, NUM_SCREENSHOT_REPLY, ID_Screenshot }, + + {S60_Reply_GetSMSStatus, "", 0x00,NUM_MESSAGE_REPLY_COUNT, ID_GetSMSStatus }, + {S60_Reply_GetSMS, "", 0x00, NUM_MESSAGE_REPLY_ONE, ID_GetSMSMessage }, + + {S60_Reply_GetCalendarStatus, "", 0x00, NUM_CALENDAR_REPLY_COUNT, ID_GetCalendarNotesInfo }, + + {S60_Reply_SendSMS, "", 0x00, NUM_MESSAGE_SEND_REPLY_RETRY, ID_IncomingFrame }, + {S60_Reply_SendSMS, "", 0x00, NUM_MESSAGE_SEND_REPLY_STATUS, ID_IncomingFrame }, + {S60_Reply_SendSMS, "", 0x00, NUM_MESSAGE_SEND_REPLY_OK, ID_IncomingFrame }, + {S60_Reply_SendSMS, "", 0x00, NUM_MESSAGE_SEND_REPLY_FAILURE, ID_IncomingFrame }, + + {S60_Reply_Generic, "", 0x00, NUM_CALENDAR_ENTRY_CHANGE_REPLY_TIME, ID_SetCalendarNote }, + {S60_Reply_AddCalendar, "", 0x00, NUM_CALENDAR_ENTRY_ADD_REPLY, ID_AddCalendarNote }, + + {S60_Reply_Generic, "", 0x00, NUM_CALENDAR_ENTRY_CHANGE_REPLY_TIME, ID_SetToDo }, + {S60_Reply_AddToDo, "", 0x00, NUM_CALENDAR_ENTRY_ADD_REPLY, ID_AddToDo }, + + {NULL, "", 0x00, 0x00, ID_None } +}; + +GSM_Phone_Functions S60Phone = { + "s60", + S60ReplyFunctions, + S60_Install, + S60_Initialise, + S60_Terminate, + GSM_DispatchMessage, + NOTIMPLEMENTED, /* ShowStartInfo */ + S60_GetInfo, /* GetManufacturer */ + S60_GetInfo, /* GetModel */ + S60_GetInfo, /* GetFirmware */ + S60_GetInfo, /* GetIMEI */ + NOTIMPLEMENTED, /* GetOriginalIMEI */ + NOTIMPLEMENTED, /* GetManufactureMonth */ + NOTIMPLEMENTED, /* GetProductCode */ + NOTIMPLEMENTED, /* GetHardware */ + NOTIMPLEMENTED, /* GetPPM */ + NOTIMPLEMENTED, /* GetSIMIMSI */ + NOTIMPLEMENTED, /* GetDateTime */ + NOTIMPLEMENTED, /* SetDateTime */ + NOTIMPLEMENTED, /* GetAlarm */ + NOTIMPLEMENTED, /* SetAlarm */ + NOTSUPPORTED, /* GetLocale */ + NOTSUPPORTED, /* SetLocale */ + NOTIMPLEMENTED, /* PressKey */ + NOTIMPLEMENTED, /* Reset */ + NOTIMPLEMENTED, /* ResetPhoneSettings */ + NOTIMPLEMENTED, /* EnterSecurityCode */ + NOTIMPLEMENTED, /* GetSecurityStatus */ + NOTIMPLEMENTED, /* GetDisplayStatus */ + NOTIMPLEMENTED, /* SetAutoNetworkLogin */ + S60_GetBatteryCharge, + S60_GetSignalQuality, + S60_GetNetworkInfo, + NOTIMPLEMENTED, /* GetCategory */ + NOTSUPPORTED, /* AddCategory */ + NOTIMPLEMENTED, /* GetCategoryStatus */ + S60_GetMemoryStatus, + S60_GetMemory, + S60_GetNextMemory, + S60_SetMemory, + S60_AddMemory, + S60_DeleteMemory, + NOTIMPLEMENTED, /* DeleteAllMemory */ + NOTIMPLEMENTED, /* GetSpeedDial */ + NOTIMPLEMENTED, /* SetSpeedDial */ + S60_GetSMSC, + NOTIMPLEMENTED, /* SetSMSC */ + S60_GetSMSStatus, + S60_GetSMS, + S60_GetNextSMS, + NOTIMPLEMENTED, /* SetSMS */ + NOTIMPLEMENTED, /* AddSMS */ + S60_DeleteSMS, + S60_SendSMS, + NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ + NOTIMPLEMENTED, /* SetIncomingSMS */ + NOTIMPLEMENTED, /* SetIncomingCB */ + S60_GetSMSFolders, + NOTIMPLEMENTED, /* AddSMSFolder */ + NOTIMPLEMENTED, /* DeleteSMSFolder */ + S60_DialVoice, + NOTIMPLEMENTED, /* DialService */ + NOTIMPLEMENTED, /* AnswerCall */ + S60_CancelCall, + NOTIMPLEMENTED, /* HoldCall */ + NOTIMPLEMENTED, /* UnholdCall */ + NOTIMPLEMENTED, /* ConferenceCall */ + NOTIMPLEMENTED, /* SplitCall */ + NOTIMPLEMENTED, /* TransferCall */ + NOTIMPLEMENTED, /* SwitchCall */ + NOTIMPLEMENTED, /* GetCallDivert */ + NOTIMPLEMENTED, /* SetCallDivert */ + NOTIMPLEMENTED, /* CancelAllDiverts */ + NOTIMPLEMENTED, /* SetIncomingCall */ + NOTIMPLEMENTED, /* SetIncomingUSSD */ + NOTIMPLEMENTED, /* SendDTMF */ + NOTIMPLEMENTED, /* GetRingtone */ + NOTIMPLEMENTED, /* SetRingtone */ + NOTIMPLEMENTED, /* GetRingtonesInfo */ + NOTIMPLEMENTED, /* DeleteUserRingtones */ + NOTIMPLEMENTED, /* PlayTone */ + NOTIMPLEMENTED, /* GetWAPBookmark */ + NOTIMPLEMENTED, /* SetWAPBookmark */ + NOTIMPLEMENTED, /* DeleteWAPBookmark */ + NOTIMPLEMENTED, /* GetWAPSettings */ + NOTIMPLEMENTED, /* SetWAPSettings */ + NOTSUPPORTED, /* GetSyncMLSettings */ + NOTSUPPORTED, /* SetSyncMLSettings */ + NOTSUPPORTED, /* GetChatSettings */ + NOTSUPPORTED, /* SetChatSettings */ + NOTSUPPORTED, /* GetMMSSettings */ + NOTSUPPORTED, /* SetMMSSettings */ + NOTSUPPORTED, /* GetMMSFolders */ + NOTSUPPORTED, /* GetNextMMSFileInfo */ + NOTIMPLEMENTED, /* GetBitmap */ + NOTIMPLEMENTED, /* SetBitmap */ + S60_GetToDoStatus, + S60_GetToDo, + S60_GetNextToDo, + NOTIMPLEMENTED, /* SetTodo */ + NOTIMPLEMENTED, /* AddTodo */ + NOTIMPLEMENTED, /* DeleteTodo */ + NOTIMPLEMENTED, /* DeleteAllTodo */ + S60_GetCalendarStatus, + S60_GetCalendar, + S60_GetNextCalendar, + S60_SetCalendar, + S60_AddCalendar, + NOTIMPLEMENTED, /* DeleteCalendar */ + NOTIMPLEMENTED, /* DeleteAllCalendar */ + NOTSUPPORTED, /* GetCalendarSettings */ + NOTSUPPORTED, /* SetCalendarSettings */ + NOTIMPLEMENTED, /* GetNoteStatus */ + NOTIMPLEMENTED, /* GetNote */ + NOTIMPLEMENTED, /* GetNextNote */ + NOTIMPLEMENTED, /* SetNote */ + NOTIMPLEMENTED, /* AddNote */ + NOTIMPLEMENTED, /* DeleteNote */ + NOTIMPLEMENTED, /* DeleteAllNotes */ + NOTIMPLEMENTED, /* GetProfile */ + NOTIMPLEMENTED, /* SetProfile */ + NOTIMPLEMENTED, /* GetFMStation */ + NOTIMPLEMENTED, /* SetFMStation */ + NOTIMPLEMENTED, /* ClearFMStations */ + NOTIMPLEMENTED, /* GetNextFileFolder */ + NOTIMPLEMENTED, /* GetFolderListing */ + NOTSUPPORTED, /* GetNextRootFolder */ + NOTSUPPORTED, /* SetFileAttributes */ + NOTIMPLEMENTED, /* GetFilePart */ + NOTIMPLEMENTED, /* AddFilePart */ + NOTIMPLEMENTED, /* SendFilePart */ + NOTIMPLEMENTED, /* GetFileSystemStatus */ + NOTIMPLEMENTED, /* DeleteFile */ + NOTIMPLEMENTED, /* AddFolder */ + NOTIMPLEMENTED, /* DeleteFile */ /* DeleteFolder */ + NOTSUPPORTED, /* GetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + S60_GetScreenshot +}; +#endif + + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/libgammu/phone/s60/s60phone.h b/libgammu/phone/s60/s60phone.h new file mode 100644 index 0000000..93efeaf --- /dev/null +++ b/libgammu/phone/s60/s60phone.h @@ -0,0 +1,65 @@ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (c) 2011 Michal Cihar <michal@cihar.com> + */ + +/** + * \file s60phone.h + * @author Michal Čihař + */ +/** + * @addtogroup Phone + * @{ + */ +/** + * @addtogroup S60Phone + * @{ + */ + +#ifndef __s60phone_h +#define __s60phone_h + +#include "../../gsmstate.h" + +#define S60_TIMEOUT 60 + +typedef struct { + int MajorVersion; + int MinorVersion; + char *MessageParts[50]; + int *SMSLocations; + size_t SMSLocationsSize; + size_t SMSLocationsPos; + int *ContactLocations; + size_t ContactLocationsSize; + size_t ContactLocationsPos; + int *CalendarLocations; + size_t CalendarLocationsSize; + size_t CalendarLocationsPos; + int *ToDoLocations; + size_t ToDoLocationsSize; + size_t ToDoLocationsPos; +} GSM_Phone_S60Data; + +#endif + + +/*@}*/ +/*@}*/ + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ + diff --git a/libgammu/phone/symbian/gnapgen.c b/libgammu/phone/symbian/gnapgen.c index 0900beb..008d63a 100644 --- a/libgammu/phone/symbian/gnapgen.c +++ b/libgammu/phone/symbian/gnapgen.c @@ -25,6 +25,81 @@ unsigned char GNAPGEN_MEMORY_TYPES[] = { 0x00, 0x00 }; +GSM_Error GNAPGEN_Install(GSM_StateMachine *s, const char *ExtraPath) +{ + GSM_StateMachine *gsm; + GSM_Debug_Info *debug_info; + GSM_Config *cfg; + GSM_Error error; + GSM_File INIFile, AppletFile; + + AppletFile.Buffer = NULL; + AppletFile.Used = 0; + INIFile.Buffer = NULL; + INIFile.Used = 0; + + error = PHONE_FindDataFile(s, &AppletFile, ExtraPath, "gnapplet.sis"); + if (error != ERR_NONE) { + smprintf(s, "Failed to load applet data!\n"); + return ERR_INSTALL_NOT_FOUND; + } + + error = PHONE_FindDataFile(s, &INIFile, ExtraPath, "gnapplet.ini"); + if (error != ERR_NONE) { + smprintf(s, "Failed to load applet configuration!\n"); + return ERR_INSTALL_NOT_FOUND; + } + + gsm = GSM_AllocStateMachine(); + if (gsm == NULL) { + return ERR_MOREMEMORY; + } + + /* Copy debug configuration */ + debug_info = GSM_GetDebug(gsm); + *debug_info = *GSM_GetDebug(s); + debug_info->closable = FALSE; + GSM_SetDebugFileDescriptor(GSM_GetDebug(s)->df, FALSE, debug_info); + GSM_SetDebugLevel(s->CurrentConfig->DebugLevel, debug_info); + + /* Generate configuration */ + cfg = GSM_GetConfig(gsm, 0); + cfg->Device = strdup(s->CurrentConfig->Device); + cfg->Connection = strdup("blueobex"); + strcpy(cfg->Model, "obexnone"); + strcpy(cfg->DebugLevel, s->CurrentConfig->DebugLevel); + cfg->UseGlobalDebugFile = s->CurrentConfig->UseGlobalDebugFile; + + /* We have one configuration */ + GSM_SetConfigNum(gsm, 1); + + error = GSM_InitConnection(gsm, 1); + if (error != ERR_NONE) { + return error; + } + + error = PHONE_UploadFile(gsm, &AppletFile); + free(AppletFile.Buffer); + if (error != ERR_NONE) { + return error; + } + + error = PHONE_UploadFile(gsm, &INIFile); + free(AppletFile.Buffer); + if (error != ERR_NONE) { + return error; + } + + error = GSM_TerminateConnection(gsm); + if (error != ERR_NONE) { + return error; + } + + /* Free up used memory */ + GSM_FreeStateMachine(gsm); + + return ERR_NONE; +} GSM_Error GNAPGEN_ReplyGetSMSFolderStatus(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_GNAPGENData *Priv = &s->Phone.Data.Priv.GNAPGEN; int i; @@ -189,9 +264,12 @@ GSM_Error GNAPGEN_PrivSetSMSLayout(GSM_StateMachine *s, GSM_SMSMessage *sms, uns return ERR_NONE; } -GSM_Error GNAPGEN_DecodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout *Layout) +GSM_Error GNAPGEN_DecodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *SMS, unsigned char *buffer, size_t length, GSM_SMSMessageLayout *Layout) { GSM_DateTime zerodt = {0,0,0,0,0,0,0}; + size_t pos; + GSM_Error error; + #ifdef DEBUG if (Layout->firstbyte == 255) { smprintf(s, "ERROR: firstbyte in SMS layout not set\n"); @@ -225,7 +303,11 @@ GSM_Error GNAPGEN_DecodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *SMS, unsig SMS->Name[1] = 0; SMS->ReplyViaSameSMSC = FALSE; if (Layout->SMSCNumber!=255) { - GSM_UnpackSemiOctetNumber(&(s->di), SMS->SMSC.Number,buffer+Layout->SMSCNumber,TRUE); + pos = Layout->SMSCNumber; + error = GSM_UnpackSemiOctetNumber(&(s->di), SMS->SMSC.Number, buffer, &pos, length, TRUE); + if (error != ERR_NONE) { + return error; + } smprintf(s, "SMS center number : \"%s\"\n",DecodeUnicodeString(SMS->SMSC.Number)); } if ((buffer[Layout->firstbyte] & 0x80)!=0) SMS->ReplyViaSameSMSC=TRUE; @@ -233,7 +315,11 @@ GSM_Error GNAPGEN_DecodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *SMS, unsig if (SMS->ReplyViaSameSMSC) smprintf(s, "SMS centre set for reply\n"); #endif if (Layout->Number!=255) { - GSM_UnpackSemiOctetNumber(&(s->di), SMS->Number,buffer+Layout->Number,TRUE); + pos = Layout->Number; + error = GSM_UnpackSemiOctetNumber(&(s->di), SMS->Number,buffer, &pos, length, TRUE); + if (error != ERR_NONE) { + return error; + } smprintf(s, "Remote number : \"%s\"\n",DecodeUnicodeString(SMS->Number)); } if (Layout->Text != 255 && Layout->TPDCS!=255 && Layout->TPUDL!=255) { @@ -332,7 +418,7 @@ static GSM_Error GNAPGEN_ReplyGetSMS(GSM_Protocol_Message msg, GSM_StateMachine s->Phone.Data.GetSMSMessage->SMS[i].Name[1] = 0; GNAPGEN_PrivSetSMSLayout(s, sms, buffer, &layout ); - GNAPGEN_DecodeSMSFrame(s, sms,buffer,&layout); + GNAPGEN_DecodeSMSFrame(s, sms,buffer,messageLen,&layout); } return ERR_NONE; @@ -701,6 +787,7 @@ GSM_Error GNAPGEN_ReplyGetNextMemory( GSM_Protocol_Message msg, GSM_StateMachine len = msg.Buffer[pos]*256+msg.Buffer[pos+1]; if (len!=0) { entry->Entries[entry->EntriesNum].EntryType=PBK_Text_Name; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; memcpy(entry->Entries[entry->EntriesNum].Text,msg.Buffer+pos+2,len*2); entry->Entries[entry->EntriesNum].Text[len*2]=0; entry->Entries[entry->EntriesNum].Text[len*2+1]=0; @@ -712,6 +799,7 @@ GSM_Error GNAPGEN_ReplyGetNextMemory( GSM_Protocol_Message msg, GSM_StateMachine case 0x08: len = msg.Buffer[pos]*256+msg.Buffer[pos+1]; entry->Entries[entry->EntriesNum].EntryType=PBK_Text_Email; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; memcpy(entry->Entries[entry->EntriesNum].Text,msg.Buffer+pos+2,len*2); entry->Entries[entry->EntriesNum].Text[len*2]=0; entry->Entries[entry->EntriesNum].Text[len*2+1]=0; @@ -724,22 +812,27 @@ GSM_Error GNAPGEN_ReplyGetNextMemory( GSM_Protocol_Message msg, GSM_StateMachine /* fax */ case 0x04: entry->Entries[entry->EntriesNum].EntryType=PBK_Number_Fax; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; break; /* work */ case 0x06: - entry->Entries[entry->EntriesNum].EntryType=PBK_Number_Work; + entry->Entries[entry->EntriesNum].EntryType=PBK_Number_General; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Work; break; /* mobile */ case 0x03: entry->Entries[entry->EntriesNum].EntryType=PBK_Number_Mobile; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; break; /* home */ case 0x02: - entry->Entries[entry->EntriesNum].EntryType=PBK_Number_Home; + entry->Entries[entry->EntriesNum].EntryType=PBK_Number_General; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Home; break; /* general */ case 0x0a: default: entry->Entries[entry->EntriesNum].EntryType=PBK_Number_General; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; break; } len = msg.Buffer[pos]*256+msg.Buffer[pos+1]; @@ -752,6 +845,7 @@ GSM_Error GNAPGEN_ReplyGetNextMemory( GSM_Protocol_Message msg, GSM_StateMachine /* date */ case 0x13: entry->Entries[entry->EntriesNum].EntryType=PBK_Date; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; NOKIA_DecodeDateTime(s, msg.Buffer+pos, &entry->Entries[entry->EntriesNum].Date, TRUE, FALSE); entry->EntriesNum++; pos+=2+7; @@ -760,6 +854,7 @@ GSM_Error GNAPGEN_ReplyGetNextMemory( GSM_Protocol_Message msg, GSM_StateMachine case 0x0a: len = msg.Buffer[pos]*256+msg.Buffer[pos+1]; entry->Entries[entry->EntriesNum].EntryType=PBK_Text_Note; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; memcpy(entry->Entries[entry->EntriesNum].Text,msg.Buffer+pos+2,len*2); entry->Entries[entry->EntriesNum].Text[len*2]=0; entry->Entries[entry->EntriesNum].Text[len*2+1]=0; @@ -770,6 +865,7 @@ GSM_Error GNAPGEN_ReplyGetNextMemory( GSM_Protocol_Message msg, GSM_StateMachine case 0x2c: len = msg.Buffer[pos]*256+msg.Buffer[pos+1]; entry->Entries[entry->EntriesNum].EntryType=PBK_Text_URL; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; memcpy(entry->Entries[entry->EntriesNum].Text,msg.Buffer+pos+2,len*2); entry->Entries[entry->EntriesNum].Text[len*2]=0; entry->Entries[entry->EntriesNum].Text[len*2+1]=0; @@ -830,6 +926,7 @@ static GSM_Error GNAPGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachi len = msg.Buffer[pos]*256+msg.Buffer[pos+1]; if (len!=0) { entry->Entries[entry->EntriesNum].EntryType=PBK_Text_Name; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; memcpy(entry->Entries[entry->EntriesNum].Text,msg.Buffer+pos+2,len*2); entry->Entries[entry->EntriesNum].Text[len*2]=0; entry->Entries[entry->EntriesNum].Text[len*2+1]=0; @@ -841,6 +938,7 @@ static GSM_Error GNAPGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachi case 0x08: len = msg.Buffer[pos]*256+msg.Buffer[pos+1]; entry->Entries[entry->EntriesNum].EntryType=PBK_Text_Email; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; memcpy(entry->Entries[entry->EntriesNum].Text,msg.Buffer+pos+2,len*2); entry->Entries[entry->EntriesNum].Text[len*2]=0; entry->Entries[entry->EntriesNum].Text[len*2+1]=0; @@ -853,22 +951,27 @@ static GSM_Error GNAPGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachi /* fax */ case 0x04: entry->Entries[entry->EntriesNum].EntryType=PBK_Number_Fax; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; break; /* work */ case 0x06: - entry->Entries[entry->EntriesNum].EntryType=PBK_Number_Work; + entry->Entries[entry->EntriesNum].EntryType=PBK_Number_General; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Work; break; /* mobile */ case 0x03: entry->Entries[entry->EntriesNum].EntryType=PBK_Number_Mobile; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; break; /* home */ case 0x02: - entry->Entries[entry->EntriesNum].EntryType=PBK_Number_Home; + entry->Entries[entry->EntriesNum].EntryType=PBK_Number_General; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Home; break; /* general */ case 0x0a: default: entry->Entries[entry->EntriesNum].EntryType=PBK_Number_General; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; break; } len = msg.Buffer[pos]*256+msg.Buffer[pos+1]; @@ -881,6 +984,7 @@ static GSM_Error GNAPGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachi /* date */ case 0x13: entry->Entries[entry->EntriesNum].EntryType=PBK_Date; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; NOKIA_DecodeDateTime(s, msg.Buffer+pos, &entry->Entries[entry->EntriesNum].Date, TRUE, FALSE); entry->EntriesNum++; pos+=2+7; @@ -889,6 +993,7 @@ static GSM_Error GNAPGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachi case 0x0a: len = msg.Buffer[pos]*256+msg.Buffer[pos+1]; entry->Entries[entry->EntriesNum].EntryType=PBK_Text_Note; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; memcpy(entry->Entries[entry->EntriesNum].Text,msg.Buffer+pos+2,len*2); entry->Entries[entry->EntriesNum].Text[len*2]=0; entry->Entries[entry->EntriesNum].Text[len*2+1]=0; @@ -899,6 +1004,7 @@ static GSM_Error GNAPGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachi case 0x2c: len = msg.Buffer[pos]*256+msg.Buffer[pos+1]; entry->Entries[entry->EntriesNum].EntryType=PBK_Text_URL; + entry->Entries[entry->EntriesNum].Location = PBK_Location_Unknown; memcpy(entry->Entries[entry->EntriesNum].Text,msg.Buffer+pos+2,len*2); entry->Entries[entry->EntriesNum].Text[len*2]=0; entry->Entries[entry->EntriesNum].Text[len*2+1]=0; @@ -971,26 +1077,26 @@ static GSM_Error GNAPGEN_SetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry) for( i=0; i< entry->EntriesNum; i++ ) { subMemoryEntry = &entry->Entries[i]; switch( subMemoryEntry->EntryType ) { - case PBK_Number_Home: - req[currentByte++] = 0x00; - req[currentByte++] = 0x0b; - req[currentByte++] = 0x00; - req[currentByte++] = 0x02; break; case PBK_Number_General: case PBK_Number_Mobile: - req[currentByte++] = 0x00; - req[currentByte++] = 0x0b; - req[currentByte++] = 0x00; - req[currentByte++] = 0x03; - break; - - case PBK_Number_Work: - req[currentByte++] = 0x00; - req[currentByte++] = 0x0b; - req[currentByte++] = 0x00; - req[currentByte++] = 0x06; + if (subMemoryEntry->Location == PBK_Location_Home) { + req[currentByte++] = 0x00; + req[currentByte++] = 0x0b; + req[currentByte++] = 0x00; + req[currentByte++] = 0x02; + } else if (subMemoryEntry->Location == PBK_Location_Home) { + req[currentByte++] = 0x00; + req[currentByte++] = 0x0b; + req[currentByte++] = 0x00; + req[currentByte++] = 0x06; + } else { + req[currentByte++] = 0x00; + req[currentByte++] = 0x0b; + req[currentByte++] = 0x00; + req[currentByte++] = 0x03; + } break; case PBK_Number_Fax: @@ -1741,6 +1847,7 @@ static GSM_Reply_Function GNAPGENReplyFunctions[] = { GSM_Phone_Functions GNAPGENPhone = { "gnap", GNAPGENReplyFunctions, + NOTIMPLEMENTED, /* Install */ GNAPGEN_Initialise, NONEFUNCTION, /* Terminate */ GSM_DispatchMessage, @@ -1875,7 +1982,8 @@ GSM_Phone_Functions GNAPGENPhone = { NOTSUPPORTED, /* AddFolder */ NOTSUPPORTED, /* DeleteFolder */ NOTSUPPORTED, /* GetGPRSAccessPoint */ - NOTSUPPORTED /* SetGPRSAccessPoint */ + NOTSUPPORTED, /* SetGPRSAccessPoint */ + NOTSUPPORTED /* GetScreenshot */ }; #endif diff --git a/libgammu/protocol/alcatel/alcabus.c b/libgammu/protocol/alcatel/alcabus.c index 1495d53..6ee418b 100644 --- a/libgammu/protocol/alcatel/alcabus.c +++ b/libgammu/protocol/alcatel/alcabus.c @@ -15,7 +15,7 @@ #include "../../gsmcomon.h" #include "alcabus.h" -static GSM_Error ALCABUS_WriteMessage (GSM_StateMachine *s, unsigned const char *data, int len, unsigned char type) +static GSM_Error ALCABUS_WriteMessage (GSM_StateMachine *s, unsigned const char *data, int len, int type) { GSM_Protocol_ALCABUSData *d = &s->Protocol.Data.ALCABUS; unsigned char buffer[1024]; diff --git a/libgammu/protocol/at/at.c b/libgammu/protocol/at/at.c index ec7b499..d8f52e2 100644 --- a/libgammu/protocol/at/at.c +++ b/libgammu/protocol/at/at.c @@ -12,7 +12,7 @@ #include "at.h" static GSM_Error AT_WriteMessage (GSM_StateMachine *s, unsigned const char *buffer, - int length, unsigned char type) + int length, int type) { int sent=0, write_data=0, i=0; @@ -286,7 +286,8 @@ static GSM_Error AT_Initialise(GSM_StateMachine *s) d->LineEnd = -1; d->wascrlf = FALSE; d->EditMode = FALSE; - d->FastWrite = FALSE; + /* Slow write makes sense only on cable for some phones */ + d->FastWrite = (s->ConnectionType != GCT_AT); d->CPINNoOK = FALSE; error = s->Device.Functions->DeviceSetParity(s, FALSE); diff --git a/libgammu/protocol/nokia/fbus2.c b/libgammu/protocol/nokia/fbus2.c index 79b1530..878eb12 100644 --- a/libgammu/protocol/nokia/fbus2.c +++ b/libgammu/protocol/nokia/fbus2.c @@ -78,7 +78,7 @@ static GSM_Error FBUS2_WriteFrame(GSM_StateMachine *s, static GSM_Error FBUS2_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, int MsgLength, - unsigned char MsgType) + int MsgType) { int i=0, nom=0, togo=0, thislength=0; /* number of messages, ... */ unsigned char buffer[FBUS2_MAX_TRANSMIT_LENGTH + 2]={0}, seqnum=0; diff --git a/libgammu/protocol/nokia/mbus2.c b/libgammu/protocol/nokia/mbus2.c index b780d35..eb51748 100644 --- a/libgammu/protocol/nokia/mbus2.c +++ b/libgammu/protocol/nokia/mbus2.c @@ -15,7 +15,7 @@ static GSM_Error MBUS2_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, int MsgLength, - unsigned char MsgType) + int MsgType) { unsigned char *buffer=NULL, checksum = 0; GSM_Protocol_MBUS2Data *d = &s->Protocol.Data.MBUS2; diff --git a/libgammu/protocol/nokia/phonet.c b/libgammu/protocol/nokia/phonet.c index dd3fc6a..cfa73df 100644 --- a/libgammu/protocol/nokia/phonet.c +++ b/libgammu/protocol/nokia/phonet.c @@ -27,7 +27,7 @@ static GSM_Error PHONET_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, int MsgLength, - unsigned char MsgType) + int MsgType) { unsigned char *buffer=NULL; int sent=0,length=0; diff --git a/libgammu/protocol/obex/obex.c b/libgammu/protocol/obex/obex.c index ec04a98..144df07 100644 --- a/libgammu/protocol/obex/obex.c +++ b/libgammu/protocol/obex/obex.c @@ -14,7 +14,7 @@ #include "obex.h" static GSM_Error OBEX_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, - int MsgLength, unsigned char type) + int MsgLength, int type) { unsigned char *buffer=NULL; int length=0,sent=0; diff --git a/libgammu/protocol/protocol.h b/libgammu/protocol/protocol.h index a5642f7..91708eb 100644 --- a/libgammu/protocol/protocol.h +++ b/libgammu/protocol/protocol.h @@ -16,7 +16,7 @@ typedef enum { typedef struct { size_t Length; size_t Count; - unsigned char Type; + int Type; unsigned char Source; unsigned char Destination; unsigned char *Buffer; diff --git a/libgammu/protocol/s60/s60-ids.h b/libgammu/protocol/s60/s60-ids.h new file mode 100644 index 0000000..a2b4abd --- /dev/null +++ b/libgammu/protocol/s60/s60-ids.h @@ -0,0 +1,104 @@ +/* Copyright (c) 2008 - 2010 Lukas Hetzenecker <LuHe@gmx.at> */ +/* Generated fro pc/devices/status_numbers.py from series60-remote */ + +#define MAX_LENGTH 600 + +#define NUM_CONNECTED 100 +#define NUM_HELLO_REQUEST 110 +#define NUM_HELLO_REPLY 111 +#define NUM_QUIT 120 +#define NUM_PARTIAL_MESSAGE 130 + +#define NUM_CONTACTS_REQUEST_HASH_ALL 200 +#define NUM_CONTACTS_REQUEST_HASH_SINGLE 201 +#define NUM_CONTACTS_REQUEST_COUNT 202 +#define NUM_CONTACTS_REQUEST_CONTACT 204 +#define NUM_CONTACTS_REQUEST_CONTACTS_ALL 205 +#define NUM_CONTACTS_REPLY_HASH_ALL 210 +#define NUM_CONTACTS_REPLY_HASH_SINGLE_START 211 +#define NUM_CONTACTS_REPLY_HASH_SINGLE_LINE 212 +#define NUM_CONTACTS_REPLY_HASH_SINGLE_END 213 +#define NUM_CONTACTS_REPLY_COUNT 214 +#define NUM_CONTACTS_REPLY_CONTACT_START 220 +#define NUM_CONTACTS_REPLY_CONTACT_LINE 221 +#define NUM_CONTACTS_REPLY_CONTACT_END 222 +#define NUM_CONTACTS_REPLY_CONTACTS_ALL_END 223 +#define NUM_CONTACTS_REPLY_CONTACT_NOT_FOUND 224 +#define NUM_CONTACTS_ADD 230 +#define NUM_CONTACTS_ADD_REPLY_ID 231 +#define NUM_CONTACTS_DELETE 232 +#define NUM_CONTACTS_CHANGE_ADDFIELD 233 +#define NUM_CONTACTS_CHANGE_REMOVEFIELD 234 + +#define NUM_SYSINFO_REQUEST 250 +#define NUM_SYSINFO_REPLY_START 260 +#define NUM_SYSINFO_REPLY_LINE 261 +#define NUM_SYSINFO_REPLY_END 262 + +#define NUM_LOCATION_REQUEST 270 +#define NUM_LOCATION_REPLY 271 +#define NUM_LOCATION_REPLY_NA 272 + +#define NUM_DIAL 280 +#define NUM_HANGUP 281 + +#define NUM_MESSAGE_SEND_REQUEST 300 +#define NUM_MESSAGE_SEND_REPLY_OK 301 +#define NUM_MESSAGE_SEND_REPLY_STATUS 302 +#define NUM_MESSAGE_SEND_REPLY_FAILURE 303 +#define NUM_MESSAGE_SEND_REPLY_RETRY 304 +#define NUM_SET_READ 320 +#define NUM_MESSAGE_DELETE 321 + +#define NUM_MESSAGE_NEW 350 +#define NUM_MESSAGE_REQUEST 351 +#define NUM_MESSAGE_REPLY_LINE 352 +#define NUM_MESSAGE_REPLY_END 353 + +#define NUM_MESSAGE_REQUEST_UNREAD 370 +#define NUM_MESSAGE_REPLY_UNREAD 371 + +#define NUM_MESSAGE_REQUEST_LIST 372 +#define NUM_MESSAGE_REPLY_LIST 373 + +#define NUM_MESSAGE_REQUEST_COUNT 374 +#define NUM_MESSAGE_REPLY_COUNT 375 + +#define NUM_MESSAGE_REQUEST_ONE 376 +#define NUM_MESSAGE_REPLY_ONE 377 + +#define NUM_CALENDAR_REQUEST_COUNT 378 +#define NUM_CALENDAR_REPLY_COUNT 379 + +#define NUM_CALENDAR_REQUEST_HASH_ALL 380 +#define NUM_CALENDAR_REQUEST_HASH_SINGLE 381 +#define NUM_CALENDAR_REQUEST_ENTRY 382 +#define NUM_CALENDAR_REQUEST_ENTRIES_ALL 383 +#define NUM_CALENDAR_REPLY_HASH_ALL 384 +#define NUM_CALENDAR_REPLY_HASH_SINGLE_START 385 +#define NUM_CALENDAR_REPLY_HASH_SINGLE_LINE 386 +#define NUM_CALENDAR_REPLY_HASH_SINGLE_END 387 +#define NUM_CALENDAR_REPLY_ENTRIES_START 388 +#define NUM_CALENDAR_REPLY_ENTRY 389 +#define NUM_CALENDAR_REPLY_ENTRIES_END 390 +#define NUM_CALENDAR_REPLY_ENTRY_NOT_FOUND 391 +#define NUM_CALENDAR_ENTRY_ADD 395 +#define NUM_CALENDAR_ENTRY_ADD_REPLY 396 +#define NUM_CALENDAR_ENTRY_DELETE 397 +#define NUM_CALENDAR_ENTRY_CHANGE 398 +#define NUM_CALENDAR_ENTRY_CHANGE_REPLY_TIME 399 + +#define NUM_INCOMING_CALL 400 + +#define NUM_SCREENSHOT 900 +#define NUM_SCREENSHOT_REPLY 901 + +#define NUM_DEBUG 999 + +#define NUM_END_HEADER 0x02 /* Start of Text */ +#define NUM_SEPERATOR 0x1E /* Record Separator */ +#define NUM_SEPERATOR_STR "\x1E" /* Record Separator */ +#define NUM_END_TEXT 0x03 /* End of Text */ + +#define PROTOCOL_VERSION 1.5 + diff --git a/libgammu/protocol/s60/s60.c b/libgammu/protocol/s60/s60.c new file mode 100644 index 0000000..45743da --- /dev/null +++ b/libgammu/protocol/s60/s60.c @@ -0,0 +1,161 @@ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (c) 2011 Michal Cihar <michal@cihar.com> + */ + + +#include "../../gsmstate.h" + +#if defined(GSM_ENABLE_S60) + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "../../gsmcomon.h" +#include "s60.h" +#include "s60-ids.h" + +static GSM_Error S60_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, + int MsgLength, int MsgType) +{ + unsigned char *buffer=NULL; + int pos, sent, length, buflen, bufpos; + GSM_Error error; + + /* No type */ + if (MsgType == 0) { + return ERR_NONE; + } + + /* Debugging */ + GSM_DumpMessageLevel3(s, MsgBuffer, MsgLength, MsgType); + GSM_DumpMessageLevel2(s, MsgBuffer, MsgLength, MsgType); + + /* Allocate buffer for composing message */ + buflen = MIN(MAX_LENGTH, MsgLength) + 10; + buffer = (unsigned char *)malloc(buflen); + if (buffer == NULL) { + return ERR_MOREMEMORY; + } + + /* Send message parts */ + for (pos = 0; MsgLength - pos > MAX_LENGTH; pos += MAX_LENGTH) { + error = S60_WriteMessage(s, MsgBuffer + pos, MAX_LENGTH, NUM_PARTIAL_MESSAGE); + if (error != ERR_NONE) { + return ERR_DEVICEWRITEERROR; + } + } + + /* Send final message */ + buffer[0] = MsgType; + length = MsgLength - pos; + + bufpos = snprintf(buffer, buflen, "%d%c", MsgType, NUM_END_HEADER); + memcpy(buffer + bufpos, MsgBuffer + pos, length); + buffer[bufpos + length] = '\n'; + length += bufpos + 1; + sent = s->Device.Functions->WriteDevice(s, buffer, length); + if (sent != length) { + return ERR_DEVICEWRITEERROR; + } + + return ERR_NONE; +} + +static GSM_Error S60_StateMachine(GSM_StateMachine *s, unsigned char rxchar) +{ + GSM_Protocol_S60Data *d = &s->Protocol.Data.S60; + + /* Did we complete part of packet? */ + switch (d->State) { + case S60_Header: + if (rxchar == NUM_END_HEADER) { + d->Msg.Type = atoi(d->idbuffer); + d->State = S60_Data; + d->idpos = 0; + } else { + d->idbuffer[d->idpos++] = rxchar; + d->idbuffer[d->idpos] = 0; + } + break; + case S60_Data: + if (rxchar == NUM_END_TEXT) { + d->State = S60_Header; + /* Should we wait for other parts? */ + if (d->Msg.Type == NUM_PARTIAL_MESSAGE) { + return ERR_NONE; + } + + /* We've got data to process */ + s->Phone.Data.RequestMsg = &d->Msg; + s->Phone.Data.DispatchError = s->Phone.Functions->DispatchMessage(s); + + /* Reset message length */ + d->Msg.Length = 0; + } else { + /* Allocate buffer */ + 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->Msg.Buffer == NULL) { + return ERR_MOREMEMORY; + } + } + + /* Store received byte */ + d->Msg.Buffer[d->Msg.Length++] = rxchar; + d->Msg.Buffer[d->Msg.Length] = 0; + } + break; + } + + return ERR_NONE; +} + +static GSM_Error S60_Initialise(GSM_StateMachine *s) +{ + GSM_Protocol_S60Data *d = &s->Protocol.Data.S60; + + d->Msg.BufferUsed = 0; + d->Msg.Buffer = NULL; + d->Msg.Length = 0; + d->State = S60_Header; + d->idpos = 0; + + return ERR_NONE; +} + +static GSM_Error S60_Terminate(GSM_StateMachine *s) +{ + free(s->Protocol.Data.S60.Msg.Buffer); + s->Protocol.Data.S60.Msg.Buffer = NULL; + + return ERR_NONE; +} + +GSM_Protocol_Functions S60Protocol = { + S60_WriteMessage, + S60_StateMachine, + S60_Initialise, + S60_Terminate +}; + +#endif + + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ diff --git a/libgammu/protocol/s60/s60.h b/libgammu/protocol/s60/s60.h new file mode 100644 index 0000000..ba7c0c8 --- /dev/null +++ b/libgammu/protocol/s60/s60.h @@ -0,0 +1,46 @@ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (c) 2011 Michal Cihar <michal@cihar.com> + */ + +#ifndef __s60_h +#define __s60_h + +#include "../protocol.h" + +typedef enum { + S60_Header, + S60_Data, +} S60_State; + +typedef struct { + GSM_Protocol_Message Msg; + S60_State State; + char idbuffer[20]; + int idpos; +} GSM_Protocol_S60Data; + +#if defined(GSM_ENABLE_S60) +# ifndef GSM_USED_BLUETOOTHDEVICE +# define GSM_USED_BLUETOOTHDEVICE +# endif +#endif + +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ + diff --git a/libgammu/protocol/symbian/gnapbus.c b/libgammu/protocol/symbian/gnapbus.c index 49b19f5..3bb0999 100644 --- a/libgammu/protocol/symbian/gnapbus.c +++ b/libgammu/protocol/symbian/gnapbus.c @@ -12,7 +12,7 @@ #include "gnapbus.h" static GSM_Error GNAPBUS_WriteMessage (GSM_StateMachine *s, unsigned const char *MsgBuffer, - int MsgLength, unsigned char MsgType) + int MsgLength, int MsgType) { unsigned char *buffer=NULL; int sent=0,length=0,i=0; diff --git a/libgammu/service/backup/backldif.c b/libgammu/service/backup/backldif.c index 8aedb09..fc45690 100644 --- a/libgammu/service/backup/backldif.c +++ b/libgammu/service/backup/backldif.c @@ -76,7 +76,6 @@ GSM_Error SaveLDIF(const char *FileName, GSM_Backup *backup) } Text[2*pos] = 0; Text[2*pos + 1] = 0; - pos++; SaveLDIFText(file, "dn", Text); } @@ -88,11 +87,14 @@ GSM_Error SaveLDIF(const char *FileName, GSM_Backup *backup) for (j=0;j<backup->PhonePhonebook[i]->EntriesNum;j++) { switch (backup->PhonePhonebook[i]->Entries[j].EntryType) { case PBK_Text_Postal: - SaveLDIFText(file, "homePostalAddress", backup->PhonePhonebook[i]->Entries[j].Text); - break; - case PBK_Text_WorkPostal: - /* This does not conform to standard, but I think it's better to have it saved */ - SaveLDIFText(file, "workPostalAddress", backup->PhonePhonebook[i]->Entries[j].Text); + if (backup->PhonePhonebook[i]->Entries[j].Location == PBK_Location_Home) { + SaveLDIFText(file, "homePostalAddress", backup->PhonePhonebook[i]->Entries[j].Text); + } else if (backup->PhonePhonebook[i]->Entries[j].Location == PBK_Location_Work) { + /* This does not conform to standard, but I think it's better to have it saved */ + SaveLDIFText(file, "workPostalAddress", backup->PhonePhonebook[i]->Entries[j].Text); + } else { + SaveLDIFText(file, "postalAddress", backup->PhonePhonebook[i]->Entries[j].Text); + } break; case PBK_Text_URL: SaveLDIFText(file, "homeurl", backup->PhonePhonebook[i]->Entries[j].Text); @@ -103,19 +105,9 @@ GSM_Error SaveLDIF(const char *FileName, GSM_Backup *backup) case PBK_Text_Note: SaveLDIFText(file, "Description", backup->PhonePhonebook[i]->Entries[j].Text); break; - case PBK_Number_Work: - /* not exist in Mozilla 1.4 win32 */ - SaveLDIFText(file, "workPhone", backup->PhonePhonebook[i]->Entries[j].Text); - break; case PBK_Number_Mobile: SaveLDIFText(file, "mobile", backup->PhonePhonebook[i]->Entries[j].Text); break; - case PBK_Number_Mobile_Home: - SaveLDIFText(file, "mobile", backup->PhonePhonebook[i]->Entries[j].Text); - break; - case PBK_Number_Mobile_Work: - SaveLDIFText(file, "mobile", backup->PhonePhonebook[i]->Entries[j].Text); - break; case PBK_Number_Pager: SaveLDIFText(file, "pager", backup->PhonePhonebook[i]->Entries[j].Text); break; @@ -126,12 +118,16 @@ GSM_Error SaveLDIF(const char *FileName, GSM_Backup *backup) /* facsimileTelephoneNumber */ SaveLDIFText(file, "fax", backup->PhonePhonebook[i]->Entries[j].Text); break; - case PBK_Number_Home: - SaveLDIFText(file, "homePhone", backup->PhonePhonebook[i]->Entries[j].Text); - break; case PBK_Number_General: - /* work in Mozilla 1.4 win32 */ - SaveLDIFText(file, "telephoneNumber", backup->PhonePhonebook[i]->Entries[j].Text); + if (backup->PhonePhonebook[i]->Entries[j].Location == PBK_Location_Home) { + SaveLDIFText(file, "homePhone", backup->PhonePhonebook[i]->Entries[j].Text); + } else if (backup->PhonePhonebook[i]->Entries[j].Location == PBK_Location_Work) { + /* not exist in Mozilla 1.4 win32 */ + SaveLDIFText(file, "workPhone", backup->PhonePhonebook[i]->Entries[j].Text); + } else { + /* work in Mozilla 1.4 win32 */ + SaveLDIFText(file, "telephoneNumber", backup->PhonePhonebook[i]->Entries[j].Text); + } break; case PBK_Text_Email: SaveLDIFText(file, "mail", backup->PhonePhonebook[i]->Entries[j].Text); @@ -160,35 +156,40 @@ GSM_Error SaveLDIF(const char *FileName, GSM_Backup *backup) case PBK_Text_JobTitle: SaveLDIFText(file, "title", backup->PhonePhonebook[i]->Entries[j].Text); break; - case PBK_Text_WorkStreetAddress: - SaveLDIFText(file, "workPostalAddress", backup->PhonePhonebook[i]->Entries[j].Text); - break; - case PBK_Text_WorkCity: - SaveLDIFText(file, "workLocalityName", backup->PhonePhonebook[i]->Entries[j].Text); - break; - case PBK_Text_WorkState: - SaveLDIFText(file, "workState", backup->PhonePhonebook[i]->Entries[j].Text); - break; - case PBK_Text_WorkZip: - SaveLDIFText(file, "workPostalCode", backup->PhonePhonebook[i]->Entries[j].Text); - break; - case PBK_Text_WorkCountry: - SaveLDIFText(file, "workCountryName", backup->PhonePhonebook[i]->Entries[j].Text); - break; case PBK_Text_StreetAddress: - SaveLDIFText(file, "homePostalAddress", backup->PhonePhonebook[i]->Entries[j].Text); + if (backup->PhonePhonebook[i]->Entries[j].Location == PBK_Location_Work) { + SaveLDIFText(file, "workPostalAddress", backup->PhonePhonebook[i]->Entries[j].Text); + } else { + SaveLDIFText(file, "homePostalAddress", backup->PhonePhonebook[i]->Entries[j].Text); + } break; case PBK_Text_City: - SaveLDIFText(file, "mozillaHomeLocalityName", backup->PhonePhonebook[i]->Entries[j].Text); + if (backup->PhonePhonebook[i]->Entries[j].Location == PBK_Location_Work) { + SaveLDIFText(file, "workLocalityName", backup->PhonePhonebook[i]->Entries[j].Text); + } else { + SaveLDIFText(file, "mozillaHomeLocalityName", backup->PhonePhonebook[i]->Entries[j].Text); + } break; case PBK_Text_State: - SaveLDIFText(file, "mozillaHomeState", backup->PhonePhonebook[i]->Entries[j].Text); + if (backup->PhonePhonebook[i]->Entries[j].Location == PBK_Location_Work) { + SaveLDIFText(file, "workState", backup->PhonePhonebook[i]->Entries[j].Text); + } else { + SaveLDIFText(file, "mozillaHomeState", backup->PhonePhonebook[i]->Entries[j].Text); + } break; case PBK_Text_Zip: - SaveLDIFText(file, "mozillaHomePostalCode", backup->PhonePhonebook[i]->Entries[j].Text); + if (backup->PhonePhonebook[i]->Entries[j].Location == PBK_Location_Work) { + SaveLDIFText(file, "workPostalCode", backup->PhonePhonebook[i]->Entries[j].Text); + } else { + SaveLDIFText(file, "mozillaHomePostalCode", backup->PhonePhonebook[i]->Entries[j].Text); + } break; case PBK_Text_Country: - SaveLDIFText(file, "mozillaHomeCountryName", backup->PhonePhonebook[i]->Entries[j].Text); + if (backup->PhonePhonebook[i]->Entries[j].Location == PBK_Location_Work) { + SaveLDIFText(file, "workCountryName", backup->PhonePhonebook[i]->Entries[j].Text); + } else { + SaveLDIFText(file, "mozillaHomeCountryName", backup->PhonePhonebook[i]->Entries[j].Text); + } break; case PBK_Text_LastName: SaveLDIFText(file, "sn", backup->PhonePhonebook[i]->Entries[j].Text); @@ -199,10 +200,21 @@ GSM_Error SaveLDIF(const char *FileName, GSM_Backup *backup) case PBK_Text_NickName: SaveLDIFText(file, "nickname", backup->PhonePhonebook[i]->Entries[j].Text); break; + case PBK_Text_SecondName: + SaveLDIFText(file, "nickname", backup->PhonePhonebook[i]->Entries[j].Text); + break; case PBK_Text_FormalName: SaveLDIFText(file, "cn", backup->PhonePhonebook[i]->Entries[j].Text); break; case PBK_Number_Other: + case PBK_Number_Video: + case PBK_Text_VOIP: + case PBK_Text_SIP: + case PBK_Text_DTMF: + case PBK_Text_SWIS: + case PBK_Text_WVID: + case PBK_Text_NamePrefix: + case PBK_Text_NameSuffix: case PBK_Caller_Group: case PBK_RingtoneID: case PBK_PictureID: @@ -287,156 +299,187 @@ static GSM_Error GSM_DecodeLDIFEntry(char *Buffer, size_t *Pos, GSM_MemoryEntry if (ReadLDIFText(Line, "givenName", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_FirstName; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "sn", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_LastName; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "telephoneNumber", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_General; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "mobile", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "pager", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Pager; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "messaging", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Messaging; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "workPhone", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Work; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_General; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "fax", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Fax; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "homePhone",Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Home; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_General; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "Description", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Note; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "homePostalAddress", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Postal; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "mozillaHomeLocalityName", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_City; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "mozillaHomeState", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_State; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "mozillaHomePostalCode", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Zip; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "mozillaHomeCountryName", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Country; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "workPostalAddress", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkPostal; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Postal; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "workLocalityName", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkCity; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_City; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "workState", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkState; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_State; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "workPostalCode", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkZip; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Zip; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "workCountryName", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkCountry; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Country; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "mail", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Email; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "mozillaSecondEmail", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Email2; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "homeurl", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_URL; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "luid", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_LUID; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "custom1", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Custom1; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "custom2", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Custom2; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "custom3", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Custom3; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "custom4", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Custom4; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "o", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Company; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "title", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_JobTitle; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } if (ReadLDIFText(Line, "nickname", Buff)) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_NickName; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } break; diff --git a/libgammu/service/backup/backtext.c b/libgammu/service/backup/backtext.c index 3abf385..7aeace0 100644 --- a/libgammu/service/backup/backtext.c +++ b/libgammu/service/backup/backtext.c @@ -185,8 +185,7 @@ static GSM_Error SaveBackupText(FILE *file, const char *myname, const char *myva } else { EncodeSpecialChars(buffer, DecodeUnicodeString(myvalue)); - sprintf(buffer, "%s = \"%s\"%c%c", myname, buffer, 13, 10); - fprintf(file, "%s", buffer); + fprintf(file, "%s = \"%s\"%c%c", myname, buffer, 13, 10); EncodeHexBin(buffer, myvalue, UnicodeLength(myvalue) * 2); fprintf(file, "%sUnicode = %s%c%c", myname, buffer, 13, 10); } @@ -320,29 +319,33 @@ static GSM_Error SavePbkEntry(FILE *file, GSM_MemoryEntry *Pbk, gboolean UseUnic if (error != ERR_NONE) return error; for (j=0;j<Pbk->EntriesNum;j++) { text = TRUE; - switch (Pbk->Entries[j].EntryType) { - case PBK_Number_General: - sprintf(buffer,"Entry%02iType = NumberGeneral%c%c",j,13,10); + switch (Pbk->Entries[j].Location) { + case PBK_Location_Home: + sprintf(buffer,"Entry%02iLocation = Home%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Number_Mobile: - sprintf(buffer,"Entry%02iType = NumberMobile%c%c",j,13,10); + case PBK_Location_Work: + sprintf(buffer,"Entry%02iLocation = Work%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Number_Mobile_Home: - sprintf(buffer,"Entry%02iType = NumberMobileHome%c%c",j,13,10); + case PBK_Location_Unknown: + break; + } + switch (Pbk->Entries[j].EntryType) { + case PBK_Number_General: + sprintf(buffer,"Entry%02iType = NumberGeneral%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Number_Mobile_Work: - sprintf(buffer,"Entry%02iType = NumberMobileWork%c%c",j,13,10); + case PBK_Number_Video: + sprintf(buffer,"Entry%02iType = NumberVideo%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Number_Work: - sprintf(buffer,"Entry%02iType = NumberWork%c%c",j,13,10); + case PBK_Number_Mobile: + sprintf(buffer,"Entry%02iType = NumberMobile%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; @@ -351,11 +354,6 @@ static GSM_Error SavePbkEntry(FILE *file, GSM_MemoryEntry *Pbk, gboolean UseUnic error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Number_Home: - sprintf(buffer,"Entry%02iType = NumberHome%c%c",j,13,10); - error = SaveBackupText(file, "", buffer, UseUnicode); - if (error != ERR_NONE) return error; - break; case PBK_Number_Pager: sprintf(buffer,"Entry%02iType = NumberPager%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); @@ -381,11 +379,6 @@ static GSM_Error SavePbkEntry(FILE *file, GSM_MemoryEntry *Pbk, gboolean UseUnic error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Text_WorkPostal: - sprintf(buffer,"Entry%02iType = WorkPostal%c%c",j,13,10); - error = SaveBackupText(file, "", buffer, UseUnicode); - if (error != ERR_NONE) return error; - break; case PBK_Text_Email: sprintf(buffer,"Entry%02iType = Email%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); @@ -473,6 +466,11 @@ static GSM_Error SavePbkEntry(FILE *file, GSM_MemoryEntry *Pbk, gboolean UseUnic error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; + case PBK_Text_SecondName: + sprintf(buffer,"Entry%02iType = SecondName%c%c",j,13,10); + error = SaveBackupText(file, "", buffer, UseUnicode); + if (error != ERR_NONE) return error; + break; case PBK_Text_NickName: sprintf(buffer,"Entry%02iType = NickName%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); @@ -483,6 +481,16 @@ static GSM_Error SavePbkEntry(FILE *file, GSM_MemoryEntry *Pbk, gboolean UseUnic error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; + case PBK_Text_NamePrefix: + sprintf(buffer,"Entry%02iType = NamePrefix%c%c",j,13,10); + error = SaveBackupText(file, "", buffer, UseUnicode); + if (error != ERR_NONE) return error; + break; + case PBK_Text_NameSuffix: + sprintf(buffer,"Entry%02iType = NameSuffix%c%c",j,13,10); + error = SaveBackupText(file, "", buffer, UseUnicode); + if (error != ERR_NONE) return error; + break; case PBK_Text_Company: sprintf(buffer,"Entry%02iType = Company%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); @@ -518,53 +526,53 @@ static GSM_Error SavePbkEntry(FILE *file, GSM_MemoryEntry *Pbk, gboolean UseUnic error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Text_WorkStreetAddress: - sprintf(buffer,"Entry%02iType = WorkAddress%c%c",j,13,10); + case PBK_Text_Custom1: + sprintf(buffer,"Entry%02iType = Custom1%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Text_WorkCity: - sprintf(buffer,"Entry%02iType = WorkCity%c%c",j,13,10); + case PBK_Text_Custom2: + sprintf(buffer,"Entry%02iType = Custom2%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Text_WorkState: - sprintf(buffer,"Entry%02iType = WorkState%c%c",j,13,10); + case PBK_Text_Custom3: + sprintf(buffer,"Entry%02iType = Custom3%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Text_WorkZip: - sprintf(buffer,"Entry%02iType = WorkZip%c%c",j,13,10); + case PBK_Text_Custom4: + sprintf(buffer,"Entry%02iType = Custom4%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Text_WorkCountry: - sprintf(buffer,"Entry%02iType = WorkCountry%c%c",j,13,10); + case PBK_Text_LUID: + sprintf(buffer,"Entry%02iType = LUID%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Text_Custom1: - sprintf(buffer,"Entry%02iType = Custom1%c%c",j,13,10); + case PBK_Text_VOIP: + sprintf(buffer,"Entry%02iType = VOIP%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Text_Custom2: - sprintf(buffer,"Entry%02iType = Custom2%c%c",j,13,10); + case PBK_Text_WVID: + sprintf(buffer,"Entry%02iType = WVID%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Text_Custom3: - sprintf(buffer,"Entry%02iType = Custom3%c%c",j,13,10); + case PBK_Text_SWIS: + sprintf(buffer,"Entry%02iType = SWIS%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Text_Custom4: - sprintf(buffer,"Entry%02iType = Custom4%c%c",j,13,10); + case PBK_Text_SIP: + sprintf(buffer,"Entry%02iType = SIP%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; - case PBK_Text_LUID: - sprintf(buffer,"Entry%02iType = LUID%c%c",j,13,10); + case PBK_Text_DTMF: + sprintf(buffer,"Entry%02iType = DTMF%c%c",j,13,10); error = SaveBackupText(file, "", buffer, UseUnicode); if (error != ERR_NONE) return error; break; @@ -629,10 +637,9 @@ static GSM_Error SavePbkEntry(FILE *file, GSM_MemoryEntry *Pbk, gboolean UseUnic } switch (Pbk->Entries[j].EntryType) { case PBK_Number_General: + case PBK_Number_Video: case PBK_Number_Mobile: - case PBK_Number_Work: case PBK_Number_Fax: - case PBK_Number_Home: case PBK_Number_Other: case PBK_Number_Pager: if (Pbk->Entries[j].VoiceTag!=0) { @@ -1834,22 +1841,39 @@ static void ReadPbkEntry(INI_Section *file_info, char *section, GSM_MemoryEntry e = e->Prev; if (num != -1) { Pbk->Entries[Pbk->EntriesNum].AddError = ERR_NONE; + sprintf(buffer,"Entry%02iLocation",num); + readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); + if (readvalue == NULL) { + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + } else if (strcasecmp(readvalue, "Home") == 0) { + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; + } else if (strcasecmp(readvalue, "Work") == 0) { + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; + } else { + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + } sprintf(buffer,"Entry%02iType",num); readvalue = ReadCFGText(file_info, section, buffer, UseUnicode); if (strcasecmp(readvalue,"NumberGeneral") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_General; + } else if (strcasecmp(readvalue,"NumberVideo") == 0) { + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Video; } else if (strcasecmp(readvalue,"NumberMobileWork") == 0) { - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile_Work; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; } else if (strcasecmp(readvalue,"NumberMobileHome") == 0) { - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile_Home; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; } else if (strcasecmp(readvalue,"NumberMobile") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile; } else if (strcasecmp(readvalue,"NumberWork") == 0) { - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Work; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_General; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; } else if (strcasecmp(readvalue,"NumberFax") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Fax; } else if (strcasecmp(readvalue,"NumberHome") == 0) { - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Home; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_General; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; } else if (strcasecmp(readvalue,"NumberOther") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Other; } else if (strcasecmp(readvalue,"NumberMessaging") == 0) { @@ -1861,7 +1885,8 @@ static void ReadPbkEntry(INI_Section *file_info, char *section, GSM_MemoryEntry } else if (strcasecmp(readvalue,"Postal") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Postal; } else if (strcasecmp(readvalue,"WorkPostal") == 0) { - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkPostal; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Postal; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; } else if (strcasecmp(readvalue,"Email") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Email; } else if (strcasecmp(readvalue,"Email2") == 0) { @@ -1870,10 +1895,16 @@ static void ReadPbkEntry(INI_Section *file_info, char *section, GSM_MemoryEntry Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_URL; } else if (strcasecmp(readvalue,"FirstName") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_FirstName; + } else if (strcasecmp(readvalue,"SecondName") == 0) { + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_SecondName; } else if (strcasecmp(readvalue,"NickName") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_NickName; } else if (strcasecmp(readvalue,"FormalName") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_FormalName; + } else if (strcasecmp(readvalue,"NamePrefix") == 0) { + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_NamePrefix; + } else if (strcasecmp(readvalue,"NameSuffix") == 0) { + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_NameSuffix; } else if (strcasecmp(readvalue,"LastName") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_LastName; } else if (strcasecmp(readvalue,"Company") == 0) { @@ -1891,15 +1922,20 @@ static void ReadPbkEntry(INI_Section *file_info, char *section, GSM_MemoryEntry } else if (strcasecmp(readvalue,"Country") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Country; } else if (strcasecmp(readvalue,"WorkAddress") == 0) { - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkStreetAddress; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_StreetAddress; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; } else if (strcasecmp(readvalue,"WorkCity") == 0) { - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkCity; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_City; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; } else if (strcasecmp(readvalue,"WorkState") == 0) { - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkState; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_State; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; } else if (strcasecmp(readvalue,"WorkZip") == 0) { - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkZip; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Zip; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; } else if (strcasecmp(readvalue,"WorkCountry") == 0) { - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkCountry; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Country; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; } else if (strcasecmp(readvalue,"Custom1") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Custom1; } else if (strcasecmp(readvalue,"Custom2") == 0) { @@ -1910,6 +1946,16 @@ static void ReadPbkEntry(INI_Section *file_info, char *section, GSM_MemoryEntry Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Custom4; } else if (strcasecmp(readvalue,"LUID") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_LUID; + } else if (strcasecmp(readvalue,"VOIP") == 0) { + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_VOIP; + } else if (strcasecmp(readvalue,"SWIS") == 0) { + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_SWIS; + } else if (strcasecmp(readvalue,"WVID") == 0) { + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WVID; + } else if (strcasecmp(readvalue,"SIP") == 0) { + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_SIP; + } else if (strcasecmp(readvalue,"DTMF") == 0) { + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_DTMF; } else if (strcasecmp(readvalue,"Name") == 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Name; } else if (strcasecmp(readvalue,"Category") == 0) { diff --git a/libgammu/service/gsmcal.c b/libgammu/service/gsmcal.c index 65e2d1b..ec47886 100644 --- a/libgammu/service/gsmcal.c +++ b/libgammu/service/gsmcal.c @@ -1531,7 +1531,6 @@ GSM_Error GSM_DecodeVCAL_RRULE(GSM_Debug_Info *di, const char *Buffer, GSM_Calen NEXT_NOSPACE(0); while (isalpha((int)*pos)) { - have_info = TRUE; GET_DOW(CAL_REPEAT_DAYOFWEEK, 0); NEXT_NOSPACE(0); } @@ -1713,7 +1712,7 @@ GSM_Error GSM_DecodeVCALENDAR_VTODO(GSM_Debug_Info *di, char *Buffer, size_t *Po gboolean is_date_only; gboolean date_only = FALSE; int lBuffer; - int Time=-1, Alarm=-1; + int Time=-1; char *rrule = NULL; if (!Buffer) return ERR_EMPTY; @@ -1739,14 +1738,14 @@ GSM_Error GSM_DecodeVCALENDAR_VTODO(GSM_Debug_Info *di, char *Buffer, size_t *Po Calendar->Type = 0; date_only = TRUE; dstflag = 0; - Time=-1; Alarm=-1; + Time=-1; Level = 1; } if (strstr(Line,"BEGIN:VTODO")) { ToDo->Priority = GSM_Priority_None; ToDo->Type = GSM_CAL_MEMO; dstflag = 0; - Time=-1; Alarm=-1; + Time=-1; Level = 2; } break; @@ -1773,9 +1772,8 @@ GSM_Error GSM_DecodeVCALENDAR_VTODO(GSM_Debug_Info *di, char *Buffer, size_t *Po if (Calendar->EntriesNum == 0) return ERR_EMPTY; if (trigger.Timezone != -999 * 3600) { - Alarm = Calendar->EntriesNum; - Calendar->Entries[Alarm].Date = GSM_AddTime (Calendar->Entries[Time].Date, trigger); - Calendar->Entries[Alarm].EntryType = CAL_TONE_ALARM_DATETIME; + Calendar->Entries[Calendar->EntriesNum].Date = GSM_AddTime (Calendar->Entries[Time].Date, trigger); + Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_TONE_ALARM_DATETIME; Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE; Calendar->EntriesNum++; } @@ -1908,14 +1906,12 @@ GSM_Error GSM_DecodeVCALENDAR_VTODO(GSM_Debug_Info *di, char *Buffer, size_t *Po } else { Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_SILENT_ALARM_DATETIME; } - Alarm = Calendar->EntriesNum; Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE; Calendar->EntriesNum++; } if (ReadVCALDate(Line, "AALARM", &Date, &is_date_only)) { Calendar->Entries[Calendar->EntriesNum].Date = Date; Calendar->Entries[Calendar->EntriesNum].EntryType = CAL_TONE_ALARM_DATETIME; - Alarm = Calendar->EntriesNum; Calendar->Entries[Calendar->EntriesNum].AddError = ERR_NONE; Calendar->EntriesNum++; } @@ -2003,7 +1999,6 @@ GSM_Error GSM_DecodeVCALENDAR_VTODO(GSM_Debug_Info *di, char *Buffer, size_t *Po if (ReadVCALDate(Line, "DALARM", &Date, &is_date_only)) { ToDo->Entries[ToDo->EntriesNum].Date = Date; ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_SILENT_ALARM_DATETIME; - Alarm = Calendar->EntriesNum; ToDo->EntriesNum++; } if (ReadVCALDate(Line, "LAST-MODIFIED", &Date, &is_date_only)) { @@ -2014,7 +2009,6 @@ GSM_Error GSM_DecodeVCALENDAR_VTODO(GSM_Debug_Info *di, char *Buffer, size_t *Po if (ReadVCALDate(Line, "AALARM", &Date, &is_date_only)) { ToDo->Entries[ToDo->EntriesNum].Date = Date; ToDo->Entries[ToDo->EntriesNum].EntryType = TODO_ALARM_DATETIME; - Alarm = Calendar->EntriesNum; ToDo->EntriesNum++; } diff --git a/libgammu/service/gsmlogo.c b/libgammu/service/gsmlogo.c index 3b296d6..37ebe3e 100644 --- a/libgammu/service/gsmlogo.c +++ b/libgammu/service/gsmlogo.c @@ -867,6 +867,7 @@ static GSM_Error loadnlm (FILE *file, GSM_MultiBitmap *bitmap) size_t readbytes; readbytes = fread(buffer,1,5,file); + if (readbytes != 5) return ERR_FILENOTSUPPORTED; readbytes = fread(buffer,1,1,file); if (readbytes != 1) return ERR_FILENOTSUPPORTED; diff --git a/libgammu/service/gsmmisc.c b/libgammu/service/gsmmisc.c index c2cf299..6cae6aa 100644 --- a/libgammu/service/gsmmisc.c +++ b/libgammu/service/gsmmisc.c @@ -500,7 +500,7 @@ gboolean ReadVCALText(char *Buffer, const char *Start, unsigned char *Value, con } } /* Store last token */ - tokens[token++] = begin; + tokens[token] = begin; /* Compare first token, it must be in place */ pos = Buffer; diff --git a/libgammu/service/gsmpbk.c b/libgammu/service/gsmpbk.c index 012e88a..20ef25d 100644 --- a/libgammu/service/gsmpbk.c +++ b/libgammu/service/gsmpbk.c @@ -94,9 +94,8 @@ void GSM_PhonebookFindDefaultNameNumberGroup(const GSM_MemoryEntry *entry, int * for (i = 0; i < entry->EntriesNum; i++) { switch (entry->Entries[i].EntryType) { case PBK_Number_Mobile: - case PBK_Number_Work: + case PBK_Number_General: case PBK_Number_Fax: - case PBK_Number_Home: case PBK_Number_Pager: case PBK_Number_Other: *Number = i; @@ -127,7 +126,7 @@ void GSM_PhonebookFindDefaultNameNumberGroup(const GSM_MemoryEntry *entry, int * GSM_Error GSM_EncodeVCARD(GSM_Debug_Info *di, char *Buffer, const size_t buff_len, size_t *Length, GSM_MemoryEntry *pbk, const gboolean header, const GSM_VCardVersion Version) { int Name, Number, Group, i; - int firstname = -1, lastname = -1; + int firstname = -1, secondname = -1, lastname = -1; int address = -1, city = -1, state = -1, zip = -1, country = -1; int workaddress = -1, workcity = -1, workstate = -1, workzip = -1, workcountry = -1; unsigned char buffer[1024]; @@ -183,52 +182,64 @@ GSM_Error GSM_EncodeVCARD(GSM_Debug_Info *di, char *Buffer, const size_t buff_le error = VC_Store(Buffer, buff_len, Length, "FN"); if (error != ERR_NONE) return error; break; + case PBK_Text_NamePrefix: + error = VC_Store(Buffer, buff_len, Length, "X-NAME-PREFIX"); + if (error != ERR_NONE) return error; + break; + case PBK_Text_NameSuffix: + error = VC_Store(Buffer, buff_len, Length, "X-NAME-SUFFIX"); + if (error != ERR_NONE) return error; + break; case PBK_Text_FirstName: firstname = i; ignore = TRUE; break; + case PBK_Text_SecondName: + secondname = i; + ignore = TRUE; + break; case PBK_Text_LastName: lastname = i; ignore = TRUE; break; case PBK_Text_StreetAddress: - address = i; + if (pbk->Entries[i].Location == PBK_Location_Work) { + workaddress = i; + } else { + address = i; + } ignore = TRUE; break; case PBK_Text_City: - city = i; + if (pbk->Entries[i].Location == PBK_Location_Work) { + workcity = i; + } else { + city = i; + } ignore = TRUE; break; case PBK_Text_State: - state = i; + if (pbk->Entries[i].Location == PBK_Location_Work) { + workstate = i; + } else { + state = i; + } ignore = TRUE; break; case PBK_Text_Zip: - zip = i; + if (pbk->Entries[i].Location == PBK_Location_Work) { + workzip = i; + } else { + zip = i; + } ignore = TRUE; break; case PBK_Text_Country: - country = i; - ignore = TRUE; - break; - case PBK_Text_WorkStreetAddress: - workaddress = i; - ignore = TRUE; - break; - case PBK_Text_WorkCity: - workcity = i; - ignore = TRUE; - break; - case PBK_Text_WorkState: - workstate = i; - ignore = TRUE; - break; - case PBK_Text_WorkZip: - workzip = i; - ignore = TRUE; - break; - case PBK_Text_WorkCountry: - workcountry = i; + if (pbk->Entries[i].Location == PBK_Location_Work) { + workcountry = i; + } else { + country = i; + } ignore = TRUE; break; case PBK_Date: @@ -242,15 +253,12 @@ GSM_Error GSM_EncodeVCARD(GSM_Debug_Info *di, char *Buffer, const size_t buff_le ignore = TRUE; break; case PBK_Number_General: + case PBK_Number_Video: case PBK_Number_Other: case PBK_Number_Pager: case PBK_Number_Mobile : - case PBK_Number_Work : case PBK_Number_Fax : - case PBK_Number_Home : case PBK_Number_Messaging : - case PBK_Number_Mobile_Work: - case PBK_Number_Mobile_Home: if (UnicodeLength(pbk->Entries[i].Text) == 0) { ignore = TRUE; break; @@ -262,6 +270,18 @@ GSM_Error GSM_EncodeVCARD(GSM_Debug_Info *di, char *Buffer, const size_t buff_le error = VC_Store(Buffer, buff_len, Length, ";PREF"); if (error != ERR_NONE) return error; } + switch (pbk->Entries[i].Location) { + case PBK_Location_Home: + error = VC_Store(Buffer, buff_len, Length, ";HOME"); + if (error != ERR_NONE) return error; + break; + case PBK_Location_Work: + error = VC_Store(Buffer, buff_len, Length, ";WORK"); + if (error != ERR_NONE) return error; + break; + case PBK_Location_Unknown: + break; + } switch (pbk->Entries[i].EntryType) { case PBK_Number_Other: error = VC_Store(Buffer, buff_len, Length, ";OTHER"); @@ -275,30 +295,18 @@ GSM_Error GSM_EncodeVCARD(GSM_Debug_Info *di, char *Buffer, const size_t buff_le error = VC_Store(Buffer, buff_len, Length, ";CELL"); if (error != ERR_NONE) return error; break; - case PBK_Number_Mobile_Home: - error = VC_Store(Buffer, buff_len, Length, ";HOME;CELL"); - if (error != ERR_NONE) return error; - break; - case PBK_Number_Mobile_Work: - error = VC_Store(Buffer, buff_len, Length, ";WORK;CELL"); - if (error != ERR_NONE) return error; - break; - case PBK_Number_Work: - error = VC_Store(Buffer, buff_len, Length, ";WORK"); - if (error != ERR_NONE) return error; - break; case PBK_Number_Fax: error = VC_Store(Buffer, buff_len, Length, ";FAX"); if (error != ERR_NONE) return error; break; - case PBK_Number_Home: - error = VC_Store(Buffer, buff_len, Length, ";HOME"); - if (error != ERR_NONE) return error; - break; case PBK_Number_Messaging: error = VC_Store(Buffer, buff_len, Length, ";MSG"); if (error != ERR_NONE) return error; break; + case PBK_Number_Video: + error = VC_Store(Buffer, buff_len, Length, ";VIDEO"); + if (error != ERR_NONE) return error; + break; default: break; } @@ -321,15 +329,13 @@ GSM_Error GSM_EncodeVCARD(GSM_Debug_Info *di, char *Buffer, const size_t buff_le */ error = VC_StoreText(Buffer, buff_len, Length, pbk->Entries[i].Text, "LABEL", FALSE); if (error != ERR_NONE) return error; - error = VC_Store(Buffer, buff_len, Length, "ADR;HOME"); - if (error != ERR_NONE) return error; - break; - case PBK_Text_WorkPostal : - if (UnicodeLength(pbk->Entries[i].Text) == 0) { - ignore = TRUE; - break; + if (pbk->Entries[i].Location == PBK_Location_Work) { + error = VC_Store(Buffer, buff_len, Length, "ADR;WORK"); + } else if (pbk->Entries[i].Location == PBK_Location_Home) { + error = VC_Store(Buffer, buff_len, Length, "ADR;HOME"); + } else { + error = VC_Store(Buffer, buff_len, Length, "ADR"); } - error = VC_Store(Buffer, buff_len, Length, "ADR;WORK"); if (error != ERR_NONE) return error; break; case PBK_Text_Email : @@ -357,6 +363,54 @@ GSM_Error GSM_EncodeVCARD(GSM_Debug_Info *di, char *Buffer, const size_t buff_le error = VC_Store(Buffer, buff_len, Length, "X-IRMC-LUID"); if (error != ERR_NONE) return error; break; + case PBK_Text_VOIP : + if (UnicodeLength(pbk->Entries[i].Text) == 0) { + ignore = TRUE; + break; + } + error = VC_Store(Buffer, buff_len, Length, "X-SIP;VOIP"); + if (error != ERR_NONE) return error; + break; + case PBK_Text_SWIS : + if (UnicodeLength(pbk->Entries[i].Text) == 0) { + ignore = TRUE; + break; + } + error = VC_Store(Buffer, buff_len, Length, "X-SIP;SWIS"); + if (error != ERR_NONE) return error; + break; + case PBK_Text_WVID : + if (UnicodeLength(pbk->Entries[i].Text) == 0) { + ignore = TRUE; + break; + } + error = VC_Store(Buffer, buff_len, Length, "X-WV-ID"); + if (error != ERR_NONE) return error; + break; + case PBK_Text_SIP : + if (UnicodeLength(pbk->Entries[i].Text) == 0) { + ignore = TRUE; + break; + } + error = VC_Store(Buffer, buff_len, Length, "X-SIP"); + if (error != ERR_NONE) return error; + break; + case PBK_Text_DTMF : + if (UnicodeLength(pbk->Entries[i].Text) == 0) { + ignore = TRUE; + break; + } + error = VC_Store(Buffer, buff_len, Length, "X-DTMF"); + if (error != ERR_NONE) return error; + break; + case PBK_PushToTalkID: + if (UnicodeLength(pbk->Entries[i].Text) == 0) { + ignore = TRUE; + break; + } + error = VC_Store(Buffer, buff_len, Length, "X-SIP;POC"); + if (error != ERR_NONE) return error; + break; case PBK_Text_JobTitle: if (UnicodeLength(pbk->Entries[i].Text) == 0) { ignore = TRUE; @@ -426,7 +480,6 @@ GSM_Error GSM_EncodeVCARD(GSM_Debug_Info *di, char *Buffer, const size_t buff_le case PBK_Text_Custom3: case PBK_Text_Custom4: case PBK_Text_PictureName: - case PBK_PushToTalkID: pbk->Entries[i].AddError = ERR_NOTSUPPORTED; ignore = TRUE; break; @@ -437,7 +490,7 @@ GSM_Error GSM_EncodeVCARD(GSM_Debug_Info *di, char *Buffer, const size_t buff_le } } /* Save name if it is composed from parts */ - if (firstname != -1 || lastname != -1) { + if (firstname != -1 || secondname != -1 || lastname != -1) { pos = 0; if (lastname != -1) { CopyUnicodeString(buffer + 2*pos, pbk->Entries[lastname].Text); @@ -450,6 +503,13 @@ GSM_Error GSM_EncodeVCARD(GSM_Debug_Info *di, char *Buffer, const size_t buff_le CopyUnicodeString(buffer + 2*pos, pbk->Entries[firstname].Text); pos += UnicodeLength(pbk->Entries[firstname].Text); } + if (secondname != -1) { + buffer[2*pos] = 0; + buffer[2*pos + 1] = ' '; + pos++; + CopyUnicodeString(buffer + 2*pos, pbk->Entries[secondname].Text); + pos += UnicodeLength(pbk->Entries[secondname].Text); + } buffer[2*pos] = 0; buffer[2*pos + 1] = 0; error = VC_StoreText(Buffer, buff_len, Length, buffer, "N", FALSE); @@ -656,6 +716,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem if (s == NULL) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Name; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } else { @@ -663,6 +724,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem /* Skip empty name */ if (UnicodeLength(Pbk->Entries[Pbk->EntriesNum].Text) > 0) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_LastName; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; } @@ -671,6 +733,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem CHECK_NUM_ENTRIES; CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_FirstName; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } @@ -690,6 +753,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem while (isspace((int)*s) && *s) s++; Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Photo; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->Entries[Pbk->EntriesNum].Picture.Type = PICTURE_JPG; /* We allocate here more memory than is actually required */ @@ -711,6 +775,20 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem } CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_General; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->Entries[Pbk->EntriesNum].SMSList[0] = 0; + Pbk->Entries[Pbk->EntriesNum].VoiceTag = 0; + Pbk->EntriesNum++; + continue; + } + if (ReadVCALText(Line, "TEL;VIDEO", Buff, (version >= 3)) || + ReadVCALText(Line, "TEL;TYPE=VIDEO", Buff, (version >= 3))) { + if (Buff[1] == '+') { + GSM_TweakInternationalNumber(Buff, NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN); + } + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Video; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->Entries[Pbk->EntriesNum].SMSList[0] = 0; Pbk->Entries[Pbk->EntriesNum].VoiceTag = 0; Pbk->EntriesNum++; @@ -727,6 +805,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem } CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->Entries[Pbk->EntriesNum].SMSList[0] = 0; Pbk->Entries[Pbk->EntriesNum].VoiceTag = 0; Pbk->EntriesNum++; @@ -741,7 +820,8 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem GSM_TweakInternationalNumber(Buff, NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN); } CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile_Work; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->Entries[Pbk->EntriesNum].SMSList[0] = 0; Pbk->Entries[Pbk->EntriesNum].VoiceTag = 0; Pbk->EntriesNum++; @@ -756,7 +836,8 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem GSM_TweakInternationalNumber(Buff, NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN); } CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile_Home; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Mobile; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; Pbk->Entries[Pbk->EntriesNum].SMSList[0] = 0; Pbk->Entries[Pbk->EntriesNum].VoiceTag = 0; Pbk->EntriesNum++; @@ -772,7 +853,8 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem GSM_TweakInternationalNumber(Buff, NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN); } CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Work; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_General; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->Entries[Pbk->EntriesNum].SMSList[0] = 0; Pbk->Entries[Pbk->EntriesNum].VoiceTag = 0; Pbk->EntriesNum++; @@ -789,6 +871,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem } CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Other; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->Entries[Pbk->EntriesNum].SMSList[0] = 0; Pbk->Entries[Pbk->EntriesNum].VoiceTag = 0; Pbk->EntriesNum++; @@ -805,6 +888,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem } CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Other; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->Entries[Pbk->EntriesNum].SMSList[0] = 0; Pbk->Entries[Pbk->EntriesNum].VoiceTag = 0; Pbk->EntriesNum++; @@ -821,6 +905,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem } CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Other; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->Entries[Pbk->EntriesNum].SMSList[0] = 0; Pbk->Entries[Pbk->EntriesNum].VoiceTag = 0; Pbk->EntriesNum++; @@ -838,6 +923,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem } CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Fax; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->Entries[Pbk->EntriesNum].SMSList[0] = 0; Pbk->Entries[Pbk->EntriesNum].VoiceTag = 0; Pbk->EntriesNum++; @@ -853,7 +939,8 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem GSM_TweakInternationalNumber(Buff, NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN); } CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_Home; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Number_General; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; Pbk->Entries[Pbk->EntriesNum].SMSList[0] = 0; Pbk->Entries[Pbk->EntriesNum].VoiceTag = 0; Pbk->EntriesNum++; @@ -862,23 +949,78 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem if (ReadVCALText(Line, "TITLE", Buff, (version >= 3))) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_JobTitle; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } if (ReadVCALText(Line, "NOTE", Buff, (version >= 3))) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Note; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } if (ReadVCALText(Line, "LABEL", Buff, (version >= 3)) || - ReadVCALText(Line, "ADR", Buff, (version >= 3)) || - ReadVCALText(Line, "ADR;HOME", Buff, (version >= 3))) { + ReadVCALText(Line, "ADR", Buff, (version >= 3))) { + pos = 0; + s = VCALGetTextPart(Buff, &pos); /* PO box, ignore for now */ + if (s == NULL) { + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Postal; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + continue; + } else { + s = VCALGetTextPart(Buff, &pos); /* Don't know ... */ + + s = VCALGetTextPart(Buff, &pos); + if (s == NULL) continue; + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_StreetAddress; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + CHECK_NUM_ENTRIES; + + s = VCALGetTextPart(Buff, &pos); + if (s == NULL) continue; + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_City; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + CHECK_NUM_ENTRIES; + + s = VCALGetTextPart(Buff, &pos); + if (s == NULL) continue; + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_State; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + CHECK_NUM_ENTRIES; + + s = VCALGetTextPart(Buff, &pos); + if (s == NULL) continue; + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Zip; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + CHECK_NUM_ENTRIES; + + s = VCALGetTextPart(Buff, &pos); + if (s == NULL) continue; + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Country; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + continue; + } + } + if (ReadVCALText(Line, "ADR;HOME", Buff, (version >= 3))) { pos = 0; s = VCALGetTextPart(Buff, &pos); /* PO box, ignore for now */ if (s == NULL) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Postal; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; Pbk->EntriesNum++; continue; } else { @@ -888,6 +1030,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem if (s == NULL) continue; CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_StreetAddress; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; Pbk->EntriesNum++; CHECK_NUM_ENTRIES; @@ -895,6 +1038,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem if (s == NULL) continue; CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_City; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; Pbk->EntriesNum++; CHECK_NUM_ENTRIES; @@ -902,6 +1046,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem if (s == NULL) continue; CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_State; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; Pbk->EntriesNum++; CHECK_NUM_ENTRIES; @@ -909,6 +1054,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem if (s == NULL) continue; CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Zip; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; Pbk->EntriesNum++; CHECK_NUM_ENTRIES; @@ -916,6 +1062,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem if (s == NULL) continue; CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Country; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Home; Pbk->EntriesNum++; continue; } @@ -925,7 +1072,8 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem s = VCALGetTextPart(Buff, &pos); /* PO box, ignore for now */ if (s == NULL) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkPostal; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Postal; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; continue; } else { @@ -934,35 +1082,40 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem s = VCALGetTextPart(Buff, &pos); if (s == NULL) continue; CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkStreetAddress; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_StreetAddress; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; CHECK_NUM_ENTRIES; s = VCALGetTextPart(Buff, &pos); if (s == NULL) continue; CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkCity; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_City; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; CHECK_NUM_ENTRIES; s = VCALGetTextPart(Buff, &pos); if (s == NULL) continue; CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkState; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_State; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; CHECK_NUM_ENTRIES; s = VCALGetTextPart(Buff, &pos); if (s == NULL) continue; CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkZip; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Zip; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; CHECK_NUM_ENTRIES; s = VCALGetTextPart(Buff, &pos); if (s == NULL) continue; CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text, s); - Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WorkCountry; + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Country; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Work; Pbk->EntriesNum++; continue; } @@ -972,36 +1125,98 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem ReadVCALText(Line, "EMAIL;INTERNET", Buff, (version >= 3))) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Email; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } if (ReadVCALText(Line, "X-IRMC-LUID", Buff, (version >= 3))) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_LUID; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + continue; + } + if (ReadVCALText(Line, "X-DTMF", Buff, (version >= 3))) { + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_DTMF; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + continue; + } + if (ReadVCALText(Line, "X-SIP", Buff, (version >= 3))) { + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_SIP; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + continue; + } + if (ReadVCALText(Line, "X-SIP;VOIP", Buff, (version >= 3))) { + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_VOIP; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + continue; + } + if (ReadVCALText(Line, "X-WV-ID", Buff, (version >= 3))) { + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_WVID; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + continue; + } + if (ReadVCALText(Line, "X-SIP;SWIS", Buff, (version >= 3))) { + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_SWIS; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + continue; + } + if (ReadVCALText(Line, "X-SIP;POC", Buff, (version >= 3))) { + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_PushToTalkID; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } if (ReadVCALText(Line, "URL", Buff, (version >= 3))) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_URL; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } if (ReadVCALText(Line, "ORG", Buff, (version >= 3))) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_Company; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } if (ReadVCALText(Line, "NICKNAME", Buff, (version >= 3))) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_NickName; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } if (ReadVCALText(Line, "FN", Buff, (version >= 3))) { CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_FormalName; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + continue; + } + if (ReadVCALText(Line, "X-NAME-PREFIX", Buff, (version >= 3))) { + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_NamePrefix; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; + Pbk->EntriesNum++; + continue; + } + if (ReadVCALText(Line, "X-NAME-SUFFIX", Buff, (version >= 3))) { + CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); + Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Text_NameSuffix; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } @@ -1009,12 +1224,14 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem CopyUnicodeString(Pbk->Entries[Pbk->EntriesNum].Text,Buff); Pbk->Entries[Pbk->EntriesNum].Number = -1; Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Category; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } if (ReadVCALText(Line, "BDAY", Buff, (version >= 3))) { if (ReadVCALDateTime(DecodeUnicodeString(Buff), &Pbk->Entries[Pbk->EntriesNum].Date)) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Date; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } @@ -1022,6 +1239,7 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem if (ReadVCALText(Line, "LAST-MODIFIED", Buff, (version >= 3))) { if (ReadVCALDateTime(DecodeUnicodeString(Buff), &Pbk->Entries[Pbk->EntriesNum].Date)) { Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_LastModified; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } @@ -1029,12 +1247,14 @@ GSM_Error GSM_DecodeVCARD(GSM_Debug_Info *di, char *Buffer, size_t *Pos, GSM_Mem if (ReadVCALText(Line, "X-PRIVATE", Buff, (version >= 3))) { Pbk->Entries[Pbk->EntriesNum].Number = atoi(DecodeUnicodeString(Buff)); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Private; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } if (ReadVCALText(Line, "X-CALLER-GROUP", Buff, (version >= 3))) { Pbk->Entries[Pbk->EntriesNum].Number = atoi(DecodeUnicodeString(Buff)); Pbk->Entries[Pbk->EntriesNum].EntryType = PBK_Caller_Group; + Pbk->Entries[Pbk->EntriesNum].Location = PBK_Location_Unknown; Pbk->EntriesNum++; continue; } diff --git a/libgammu/service/gsmring.c b/libgammu/service/gsmring.c index 3195b92..1bbb09c 100644 --- a/libgammu/service/gsmring.c +++ b/libgammu/service/gsmring.c @@ -477,7 +477,7 @@ GSM_Error GSM_SaveRingtoneMidi(FILE* file, GSM_Ringtone *ringtone) midifile[current++] = 0x2F; midifile[current++] = 0x00; midifile[length++] = (current-22) >> 8; - midifile[length++] = current-22; + midifile[length] = current-22; chk_fwrite(midifile,1,current,file); return ERR_NONE; @@ -788,20 +788,20 @@ static GSM_Error loadott(FILE *file, GSM_Ringtone *ringtone) static GSM_Error loadcommunicator(FILE *file, GSM_Ringtone *ringtone) { char Buffer[4000]; - int i,j; + int bytes_read,j; - i = fread(Buffer, 1, 4000, file); + bytes_read = fread(Buffer, 1, 4000, file); - i=0;j=0; + j=0; while (TRUE) { if (Buffer[j] ==0x00 && Buffer[j+1]==0x02 && Buffer[j+2]==0x4a && Buffer[j+3]==0x3a) break; - if (j==i-4) return ERR_UNKNOWN; + if (j==bytes_read-4) return ERR_UNKNOWN; j++; } j++; - return GSM_DecodeNokiaRTTLRingtone(ringtone, Buffer+j, i-j); + return GSM_DecodeNokiaRTTLRingtone(ringtone, Buffer+j, bytes_read-j); } static GSM_Error loadbin(FILE *file, GSM_Ringtone *ringtone) @@ -1365,6 +1365,8 @@ static void Binary2RTTL(GSM_Ringtone *dest, GSM_Ringtone *src) NotesScale[NrNotes] = Scale_1760; command -= 138; } else if (command >= 150 && command <= 161) { NotesScale[NrNotes] = Scale_3520; command -= 150; + } else { + NotesScale[NrNotes] = Scale_440; } switch (command) { case 0 : Notes[NrNotes] = Note_C; break; @@ -1379,6 +1381,7 @@ static void Binary2RTTL(GSM_Ringtone *dest, GSM_Ringtone *src) case 9 : Notes[NrNotes] = Note_A; break; case 10 : Notes[NrNotes] = Note_Ais; break; case 11 : Notes[NrNotes] = Note_H; break; + default : Notes[NrNotes] = Note_Pause; break; } if (NrNotes > 0 && Notes[NrNotes - 1] == Notes[NrNotes] && @@ -1618,9 +1621,9 @@ unsigned char GSM_EncodeEMSSound(GSM_Ringtone ringtone, unsigned char *package, Len+=sprintf(package+Len,"MELODY:"); if (version != GSM_Ring_NoHeader) { /* 15 = Len of END:IMELODY... */ - if ((Len+15) > Max) { end = TRUE; break; } + if ((Len+15) > Max) { break; } } else { - if (Len > Max) { end = TRUE; break; } + if (Len > Max) { break; } } *maxlength = Len; break; diff --git a/libgammu/service/sms/gsmems.c b/libgammu/service/sms/gsmems.c index 5062a86..5d1aa03 100644 --- a/libgammu/service/sms/gsmems.c +++ b/libgammu/service/sms/gsmems.c @@ -590,7 +590,7 @@ gboolean GSM_DecodeEMSMultiPartSMS(GSM_Debug_Info *di, int i, w, Pos, UPI = 1, fmt; size_t width, height; size_t z; - gboolean RetVal = FALSE, NewPicture = TRUE; + gboolean NewPicture = TRUE; GSM_Phone_Bitmap_Types BitmapType; GSM_Bitmap Bitmap,Bitmap2; @@ -634,7 +634,6 @@ gboolean GSM_DecodeEMSMultiPartSMS(GSM_Debug_Info *di, smfprintf(di, "UDH part - unknown application data - 0x%04x\n", Info->Entries[Info->EntriesNum].Number); break; } - RetVal = TRUE; break; case 0x08: smfprintf(di, "UDH part - linked SMS with 16 bit ID\n"); @@ -681,7 +680,6 @@ gboolean GSM_DecodeEMSMultiPartSMS(GSM_Debug_Info *di, } Info->Entries[Info->EntriesNum].Number = SMS->SMS[i].UDH.Text[w+3]; Info->Entries[Info->EntriesNum].ID = SMS_ConcatenatedTextLong; - RetVal = TRUE; break; case 0x0B: smfprintf(di, "UDH part - default EMS sound\n"); @@ -692,7 +690,6 @@ gboolean GSM_DecodeEMSMultiPartSMS(GSM_Debug_Info *di, 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; #if 0 case 0x0C: @@ -708,7 +705,6 @@ gboolean GSM_DecodeEMSMultiPartSMS(GSM_Debug_Info *di, 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: @@ -736,7 +732,6 @@ gboolean GSM_DecodeEMSMultiPartSMS(GSM_Debug_Info *di, &Info->Entries[Info->EntriesNum].Bitmap->Bitmap[z]); Info->Entries[Info->EntriesNum].Bitmap->Number++; } - RetVal = TRUE; break; case 0x10: case 0x11: @@ -762,7 +757,6 @@ gboolean GSM_DecodeEMSMultiPartSMS(GSM_Debug_Info *di, 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: smfprintf(di, "UDH part - EMS variable width bitmap\n"); @@ -812,7 +806,6 @@ gboolean GSM_DecodeEMSMultiPartSMS(GSM_Debug_Info *di, 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; smfprintf(di, "New variable picture\n"); } else { @@ -835,10 +828,9 @@ gboolean GSM_DecodeEMSMultiPartSMS(GSM_Debug_Info *di, w=w+SMS->SMS[i].UDH.Text[w+1]+2; } /* while */ if (!AddEMSText(&SMS->SMS[i], Info, &Pos, SMS->SMS[i].Length-Pos)) return FALSE; - RetVal = TRUE; } - if (RetVal) (Info->EntriesNum)++; - return RetVal; + if (SMS->Number > 0) (Info->EntriesNum)++; + return TRUE; } /* How should editor hadle tabs in this file? Add editor commands here. diff --git a/libgammu/service/sms/gsmmulti.c b/libgammu/service/sms/gsmmulti.c index 7ed31d2..0dda2d3 100644 --- a/libgammu/service/sms/gsmmulti.c +++ b/libgammu/service/sms/gsmmulti.c @@ -198,7 +198,7 @@ void GSM_MakeMultiPartSMS(GSM_Debug_Info *di, GSM_MultiSMSMessage *SMS, } /* Calculates number of SMS and number of left chars in SMS */ -void GSM_SMSCounter(GSM_Debug_Info *di, size_t MessageLength, +void GSM_SMSCounter(GSM_Debug_Info *di, unsigned char *MessageBuffer, GSM_UDH UDHType, GSM_Coding_Type Coding, @@ -209,7 +209,7 @@ void GSM_SMSCounter(GSM_Debug_Info *di, size_t MessageLength, GSM_MultiSMSMessage MultiSMS; MultiSMS.Number = 0; - GSM_MakeMultiPartSMS(di, &MultiSMS,MessageBuffer,MessageLength,UDHType,Coding,-1,FALSE); + GSM_MakeMultiPartSMS(di, &MultiSMS,MessageBuffer,UnicodeLength(MessageBuffer),UDHType,Coding,-1,FALSE); GSM_Find_Free_Used_SMS2(di, Coding,MultiSMS.SMS[MultiSMS.Number-1], &UsedText, CharsLeft, &FreeBytes); *SMSNum = MultiSMS.Number; } diff --git a/libgammu/service/sms/gsmmulti.h b/libgammu/service/sms/gsmmulti.h index 62f98df..09a57bc 100644 --- a/libgammu/service/sms/gsmmulti.h +++ b/libgammu/service/sms/gsmmulti.h @@ -26,13 +26,6 @@ #define ALCATELTDD_ANIMATION 5 #define ALCATELTDD_SMSTEMPLATE 6 -void GSM_SMSCounter(GSM_Debug_Info *di, size_t MessageLength, - unsigned char *MessageBuffer, - GSM_UDH UDHType, - GSM_Coding_Type Coding, - int *SMSNum, - size_t *CharsLeft); - GSM_Error GSM_AddSMS_Text_UDH(GSM_Debug_Info *di, GSM_MultiSMSMessage *SMS, GSM_Coding_Type Coding, char *Buffer, diff --git a/libgammu/service/sms/gsmsms.c b/libgammu/service/sms/gsmsms.c index 076024a..1ec0194 100644 --- a/libgammu/service/sms/gsmsms.c +++ b/libgammu/service/sms/gsmsms.c @@ -378,13 +378,17 @@ GSM_Error GSM_DecodePDUFrame(GSM_Debug_Info *di, GSM_SMSMessage *SMS, const unsi unsigned char output[161]; int datalength; gboolean have_data = FALSE; + GSM_Error error; /* Set some sane data */ GSM_SetDefaultReceivedSMSData(SMS); /* Parse SMSC if it is included */ if (SMSC) { - pos += GSM_UnpackSemiOctetNumber(di, SMS->SMSC.Number, buffer + pos, FALSE); + error = GSM_UnpackSemiOctetNumber(di, SMS->SMSC.Number, buffer, &pos, length, FALSE); + if (error != ERR_NONE) { + return error; + } smfprintf(di, "SMS center number : \"%s\"\n",DecodeUnicodeString(SMS->SMSC.Number)); } @@ -449,7 +453,10 @@ GSM_Error GSM_DecodePDUFrame(GSM_Debug_Info *di, GSM_SMSMessage *SMS, const unsi } /* Remote number */ - pos += GSM_UnpackSemiOctetNumber(di, SMS->Number, buffer + pos, TRUE); + error = GSM_UnpackSemiOctetNumber(di, SMS->Number, buffer, &pos, length, TRUE); + if (error != ERR_NONE) { + return error; + } smfprintf(di, "Remote number : \"%s\"\n",DecodeUnicodeString(SMS->Number)); if (pos >= length) { smfprintf(di, "Ran out of buffer when parsing PDU!\n"); @@ -652,6 +659,9 @@ GSM_Error GSM_DecodePDUFrame(GSM_Debug_Info *di, GSM_SMSMessage *SMS, const unsi GSM_Error GSM_DecodeSMSFrame(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout) { GSM_DateTime zerodt = {0,0,0,0,0,0,0}; + size_t pos; + GSM_Error error; + #ifdef DEBUG if (Layout.firstbyte == 255) { smfprintf(di, "ERROR: firstbyte in SMS layout not set\n"); @@ -670,7 +680,11 @@ GSM_Error GSM_DecodeSMSFrame(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsigned c GSM_SetDefaultReceivedSMSData(SMS); if (Layout.SMSCNumber!=255) { - GSM_UnpackSemiOctetNumber(di, SMS->SMSC.Number,buffer+Layout.SMSCNumber,FALSE); + pos = Layout.SMSCNumber; + error = GSM_UnpackSemiOctetNumber(di, SMS->SMSC.Number, buffer, &pos, 1000, FALSE); + if (error != ERR_NONE) { + return error; + } smfprintf(di, "SMS center number : \"%s\"\n",DecodeUnicodeString(SMS->SMSC.Number)); } if ((buffer[Layout.firstbyte] & 0x80)!=0) SMS->ReplyViaSameSMSC=TRUE; @@ -678,7 +692,11 @@ GSM_Error GSM_DecodeSMSFrame(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsigned c if (SMS->ReplyViaSameSMSC) smfprintf(di, "SMS centre set for reply\n"); #endif if (Layout.Number!=255) { - GSM_UnpackSemiOctetNumber(di, SMS->Number,buffer+Layout.Number,TRUE); + pos = Layout.Number; + error = GSM_UnpackSemiOctetNumber(di, SMS->Number, buffer, &pos, 1000, TRUE); + if (error != ERR_NONE) { + return error; + } smfprintf(di, "Remote number : \"%s\"\n",DecodeUnicodeString(SMS->Number)); } if (Layout.TPDCS != 255) { @@ -776,10 +794,8 @@ static int GSM_EncodeSMSFrameText(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsig 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 smfprintf(di, "UDH, length %i\n",off); DumpMessageText(di, SMS->UDH.Text, off); -#endif } switch (SMS->Coding) { case SMS_Coding_8bit: @@ -787,12 +803,10 @@ static int GSM_EncodeSMSFrameText(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsig /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) * and GSM 03.38 section 4 */ buffer[Layout.TPDCS] |= (1 << 2); - memcpy(buffer+(Layout.Text+off), SMS->Text, SMS->Length); + memcpy(buffer+(Layout.Text+off), SMS->Text, MIN(SMS->Length, 140)); size2 = size = SMS->Length+off; -#ifdef DEBUG smfprintf(di, "8 bit SMS, length %i\n",SMS->Length); DumpMessageText(di, SMS->Text, SMS->Length); -#endif break; case SMS_Coding_Default_No_Compression: p = 0; @@ -800,7 +814,7 @@ static int GSM_EncodeSMSFrameText(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsig p+=7; w=(p-off)%p; } while (w<0); - p = UnicodeLength(SMS->Text); + p = MIN(UnicodeLength(SMS->Text), 160); EncodeDefault(buff, SMS->Text, &p, TRUE, NULL); size = GSM_PackSevenBitsToEight(w, buff, buffer+(Layout.Text+off), p); size += off; @@ -815,13 +829,11 @@ static int GSM_EncodeSMSFrameText(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsig /* GSM 03.40 section 9.2.3.10 (TP-Data-Coding-Scheme) * and GSM 03.38 section 4 */ buffer[Layout.TPDCS] |= (1 << 3); - EncodeUnicodeSpecialNOKIAChars(buffer+(Layout.Text+off), SMS->Text, UnicodeLength(SMS->Text)); + EncodeUnicodeSpecialNOKIAChars(buffer+(Layout.Text+off), SMS->Text, MIN(UnicodeLength(SMS->Text), 70)); size=size2=UnicodeLength(buffer+(Layout.Text+off))*2+off; -#ifdef DEBUG smfprintf(di, "Unicode SMS, length %i\n",(size2-off)/2); DumpMessageText(di, buffer+(Layout.Text+off), size2-off); smfprintf(di, "%s\n",DecodeUnicodeString(buffer+(Layout.Text+off))); -#endif break; default: break; |