summaryrefslogtreecommitdiff
path: root/libgammu
diff options
context:
space:
mode:
authorMichal Čihař <michal@cihar.com>2011-02-10 15:32:59 +0100
committerMichal Čihař <michal@cihar.com>2011-02-10 15:32:59 +0100
commit66ce5a2dc79d6132a0db61f880782e56d4f8bfcf (patch)
tree60a4edadc2ad333cc9984f71f0a364bb7eab7c93 /libgammu
parenta92feb0ede986fd672d2fc6d642ac93084c4da62 (diff)
Imported Upstream version 1.29.90
Diffstat (limited to 'libgammu')
-rw-r--r--libgammu/CMakeLists.txt4
-rw-r--r--libgammu/api.c30
-rw-r--r--libgammu/device/bluetoth/bluetoth.c3
-rw-r--r--libgammu/device/devfunc.c4
-rw-r--r--libgammu/gsmcomon.c2
-rw-r--r--libgammu/gsmphones.c6
-rw-r--r--libgammu/gsmreply.h8
-rw-r--r--libgammu/gsmstate.c67
-rw-r--r--libgammu/gsmstate.h45
-rw-r--r--libgammu/misc/coding/coding.c86
-rw-r--r--libgammu/misc/coding/coding.h3
-rw-r--r--libgammu/misc/misc.c19
-rw-r--r--libgammu/phone/alcatel/alcatel.c112
-rw-r--r--libgammu/phone/at/at-sms.c39
-rw-r--r--libgammu/phone/at/atgen.c50
-rw-r--r--libgammu/phone/at/motorola.c15
-rw-r--r--libgammu/phone/at/samsung.c21
-rw-r--r--libgammu/phone/at/siemens.c3
-rw-r--r--libgammu/phone/atobex/atobex.c202
-rw-r--r--libgammu/phone/dummy/dummy.c6
-rw-r--r--libgammu/phone/nokia/dct3/dct3func.c16
-rw-r--r--libgammu/phone/nokia/dct3/n0650.c4
-rw-r--r--libgammu/phone/nokia/dct3/n6110.c16
-rw-r--r--libgammu/phone/nokia/dct3/n7110.c18
-rw-r--r--libgammu/phone/nokia/dct3/n9210.c4
-rw-r--r--libgammu/phone/nokia/dct4s40/6510/6510file.c1
-rw-r--r--libgammu/phone/nokia/dct4s40/6510/n6510.c126
-rw-r--r--libgammu/phone/nokia/dct4s40/6510/n6510.h2
-rw-r--r--libgammu/phone/nokia/dct4s40/n3320.c4
-rw-r--r--libgammu/phone/nokia/nauto.c4
-rw-r--r--libgammu/phone/nokia/ncommon.h1
-rw-r--r--libgammu/phone/nokia/nfunc.c50
-rw-r--r--libgammu/phone/nokia/wd2/n3650.c8
-rw-r--r--libgammu/phone/obex/obexgen.c4
-rw-r--r--libgammu/phone/pfunc.c46
-rw-r--r--libgammu/phone/pfunc.h2
-rw-r--r--libgammu/phone/s60/s60phone.c2170
-rw-r--r--libgammu/phone/s60/s60phone.h65
-rw-r--r--libgammu/phone/symbian/gnapgen.c158
-rw-r--r--libgammu/protocol/alcatel/alcabus.c2
-rw-r--r--libgammu/protocol/at/at.c5
-rw-r--r--libgammu/protocol/nokia/fbus2.c2
-rw-r--r--libgammu/protocol/nokia/mbus2.c2
-rw-r--r--libgammu/protocol/nokia/phonet.c2
-rw-r--r--libgammu/protocol/obex/obex.c2
-rw-r--r--libgammu/protocol/protocol.h2
-rw-r--r--libgammu/protocol/s60/s60-ids.h104
-rw-r--r--libgammu/protocol/s60/s60.c161
-rw-r--r--libgammu/protocol/s60/s60.h46
-rw-r--r--libgammu/protocol/symbian/gnapbus.c2
-rw-r--r--libgammu/service/backup/backldif.c139
-rw-r--r--libgammu/service/backup/backtext.c156
-rw-r--r--libgammu/service/gsmcal.c16
-rw-r--r--libgammu/service/gsmlogo.c1
-rw-r--r--libgammu/service/gsmmisc.c2
-rw-r--r--libgammu/service/gsmpbk.c360
-rw-r--r--libgammu/service/gsmring.c19
-rw-r--r--libgammu/service/sms/gsmems.c14
-rw-r--r--libgammu/service/sms/gsmmulti.c4
-rw-r--r--libgammu/service/sms/gsmmulti.h7
-rw-r--r--libgammu/service/sms/gsmsms.c38
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;