62 files changed, 2118 insertions, 471 deletions
diff --git a/gammu/emb/common/common.pro b/gammu/emb/common/common.pro index 0e719ee..797199b 100644 --- a/gammu/emb/common/common.pro +++ b/gammu/emb/common/common.pro @@ -151,16 +151,17 @@ protocol/alcatel/alcabus.c \ protocol/nokia/mbus2.c \ protocol/nokia/fbus2.c \ protocol/nokia/phonet.c \ protocol/obex/obex.c \ protocol/symbian/mrouter.c \ phone/pfunc.c \ phone/at/atgen.c \ phone/at/siemens.c \ +phone/at/samsung.c \ phone/at/sonyeric.c \ phone/alcatel/alcatel.c \ phone/nokia/dct3/n6110.c \ phone/nokia/dct3/n7110.c \ phone/nokia/dct3/n9210.c \ phone/nokia/dct3/dct3func.c \ phone/nokia/dct4/n3320.c \ phone/nokia/dct4/n3650.c \ diff --git a/gammu/emb/common/commonE.pro b/gammu/emb/common/commonE.pro index a36947b..f5b559d 100644 --- a/gammu/emb/common/commonE.pro +++ b/gammu/emb/common/commonE.pro @@ -152,16 +152,17 @@ protocol/alcatel/alcabus.c \ protocol/nokia/mbus2.c \ protocol/nokia/fbus2.c \ protocol/nokia/phonet.c \ protocol/obex/obex.c \ protocol/symbian/mrouter.c \ phone/pfunc.c \ phone/at/atgen.c \ phone/at/siemens.c \ +phone/at/samsung.c \ phone/at/sonyeric.c \ phone/alcatel/alcatel.c \ phone/nokia/dct3/n6110.c \ phone/nokia/dct3/n7110.c \ phone/nokia/dct3/n9210.c \ phone/nokia/dct3/dct3func.c \ phone/nokia/dct4/n3320.c \ phone/nokia/dct4/n3650.c \ diff --git a/gammu/emb/common/device/bluetoth/bluez.c b/gammu/emb/common/device/bluetoth/bluez.c index 8a4807e..e7e8adf 100644 --- a/gammu/emb/common/device/bluetoth/bluez.c +++ b/gammu/emb/common/device/bluetoth/bluez.c @@ -1,9 +1,18 @@ -/* Based on work by Marcel Holtmann and other authors of Bluez */ +/* Based on some work from Bluez (www.bluez.org) + * (C) 2000-2001 Qualcomm Incorporated + * (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> + * (C) 2002-2004 Marcel Holtmann <marcel@holtmann.org> + * GNU GPL version 2 + */ +/* based on some Marcel Holtmann work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_BLUETOOTHDEVICE #ifdef GSM_ENABLE_BLUEZ #include <stdlib.h> #include <stdio.h> @@ -76,17 +85,17 @@ static void print_service_desc(void *value, void *user) sdp_data_t *p = (sdp_data_t *)value; int i = 0, proto = 0, *channel = (int *)user; for (; p; p = p->next, i++) { switch (p->dtd) { case SDP_UUID16: case SDP_UUID32: case SDP_UUID128: - proto = 1;//sdp_uuid_to_proto(&p->val.uuid); + proto = sdp_uuid_to_proto(&p->val.uuid); break; case SDP_UINT8: if (proto == RFCOMM_UUID) { (*channel) = p->val.uint8; return; } break; } @@ -99,23 +108,23 @@ void print_access_protos(value, user) int *channel = (int *)user; sdp_list_foreach(protDescSeq,print_service_desc,channel); } static GSM_Error bluetooth_checkdevice(GSM_StateMachine *s, bdaddr_t *bdaddr, struct search_context *context) { sdp_session_t *sess; - sdp_list_t *attrid, *search, *seq, *next, *proto = 0; - uint32_t range = 0x0000ffff; - char str[20]; sdp_record_t *rec; + sdp_list_t *attrid, *search, *seq, *next, *proto = 0; sdp_data_t *d; bdaddr_t interface; + uint32_t range = 0x0000ffff; struct search_context subcontext; + char str[20]; int channel,channel2; bacpy(&interface,BDADDR_ANY); ba2str(bdaddr, str); smprintf(s,"%s\n", str); sess = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY); @@ -137,55 +146,55 @@ static GSM_Error bluetooth_checkdevice(GSM_StateMachine *s, bdaddr_t *bdaddr, st channel2 = -1; for (; seq; seq = next) { rec = (sdp_record_t *) seq->data; if (channel2 == -1) { if (!context->tree) { d = sdp_data_get(rec,SDP_ATTR_SVCNAME_PRIMARY); - if (false) { + if (sdp_get_access_protos(rec,&proto) == 0) { channel = -1; sdp_list_foreach(proto,print_access_protos,&channel); - //sdp_list_free(proto,(sdp_free_func_t)sdp_data_free); + sdp_list_free(proto,(sdp_free_func_t)sdp_data_free); } smprintf(s,"Channel %i",channel); if (d) smprintf(s," - \"%s\"",d->val.str); smprintf(s,"\n"); if (channel2 == -1 && bluetooth_checkservicename(s, d->val.str) == ERR_NONE) { channel2 = channel; } } if (sdp_get_group_id(rec,&subcontext.group) != -1) { memcpy(&subcontext, context, sizeof(struct search_context)); if (subcontext.group.value.uuid16 != context->group.value.uuid16) bluetooth_checkdevice(s,bdaddr,&subcontext); } } next = seq->next; free(seq); - //sdp_record_free(rec); + sdp_record_free(rec); } sdp_close(sess); if (channel2 != -1) return bluetooth_connect(s, channel2, str); - return ERR_UNKNOWN; + return ERR_NOTSUPPORTED; } GSM_Error bluetooth_findchannel(GSM_StateMachine *s) { inquiry_info ii[20]; uint8_t count = 0; int i; struct search_context context; GSM_Error error = ERR_NOTSUPPORTED; memset(&context, '\0', sizeof(struct search_context)); - //sdp_uuid16_create(&(context.group),PUBLIC_BROWSE_GROUP); + sdp_uuid16_create(&(context.group),PUBLIC_BROWSE_GROUP); if (!strcmp(s->CurrentConfig->Device,"/dev/ttyS1")) { dbgprintf("Searching for devices\n"); if (sdp_general_inquiry(ii, 20, 8, &count) < 0) { return ERR_UNKNOWN; } } else { count = 1; diff --git a/gammu/emb/common/device/devfunc.c b/gammu/emb/common/device/devfunc.c index d31ebbf..c58a01f 100644 --- a/gammu/emb/common/device/devfunc.c +++ b/gammu/emb/common/device/devfunc.c @@ -1,8 +1,16 @@ +/* Some source from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ +/* Some source from Minicom (http://alioth.debian.org/projects/minicom) + * (C) 1991,1992,1993,1994,1995,1996 by Miquel van Smoorenburg + * GNU GPL version 2 + */ #include <string.h> #ifdef WIN32 # include <io.h> #else # include <errno.h> # include <signal.h> #endif @@ -100,17 +108,17 @@ bool unlock_device(char **lock_file) #define max_buf_len 128 #define lock_path "/var/lock/LCK.." /* Lock the device. Allocated string with a lock name is returned * in lock_device */ GSM_Error lock_device(const char* port, char **lock_device) { -#ifndef WIN32 +#if !defined(WIN32) && !defined(DJGPP) char *lock_file = NULL; char buffer[max_buf_len]; const char *aux; int fd, len; GSM_Error error = ERR_NONE; dbgprintf("Locking device\n"); @@ -213,17 +221,17 @@ failed: *lock_device = 0; return ERR_NONE; #endif } /* Removes lock and frees memory */ bool unlock_device(char **lock_file) { -#ifndef WIN32 +#if !defined(WIN32) && !defined(DJGPP) int err; if (!lock_file) { dbgprintf("Cannot unlock device\n"); return false; } err = unlink(*lock_file); free(*lock_file); diff --git a/gammu/emb/common/device/irda/irda.c b/gammu/emb/common/device/irda/irda.c index fef50ac..e680377 100644 --- a/gammu/emb/common/device/irda/irda.c +++ b/gammu/emb/common/device/irda/irda.c @@ -1,11 +1,15 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Ralf Thelen and MyGnokii */ -/* based on some work from Gnokii and MSDN */ +/* based on some work from Ralf Thelen and MyGnokii (www.mwiacek.com) */ +/* based on some work from MSDN */ +/* based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ /* You have to include wsock32.lib library to MS VC project to compile it */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_IRDADEVICE #ifndef DJGPP diff --git a/gammu/emb/common/device/irda/irda_unx.h b/gammu/emb/common/device/irda/irda_unx.h index 8dbcb97..7a55273 100644 --- a/gammu/emb/common/device/irda/irda_unx.h +++ b/gammu/emb/common/device/irda/irda_unx.h @@ -1,9 +1,9 @@ -/* part of irda.h available in Linux kernel source */ +/* part of irda.h available in Linux kernel source (www.kernel.org) */ /********************************************************************* * * Filename: irda.h * Version: * Description: * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> diff --git a/gammu/emb/common/device/serial/ser_djg.c b/gammu/emb/common/device/serial/ser_djg.c index ac9d7c8..2524187 100644 --- a/gammu/emb/common/device/serial/ser_djg.c +++ b/gammu/emb/common/device/serial/ser_djg.c @@ -6,45 +6,45 @@ #include "../../gsmcomon.h" #include "ser_djg.h" static GSM_Error serial_close(GSM_StateMachine *s) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - return ERR_NONE; + return ERR_NOTIMPLEMENTED; } static GSM_Error serial_open (GSM_StateMachine *s) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - return ERR_NONE; + return ERR_NOTIMPLEMENTED; } static GSM_Error serial_setparity(GSM_StateMachine *s, bool parity) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - return ERR_NONE; + return ERR_NOTIMPLEMENTED; } static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - return ERR_NONE; + return ERR_NOTIMPLEMENTED; } static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) { GSM_Device_SerialData *d = &s->Device.Data.Serial; - return ERR_NONE; + return ERR_NOTIMPLEMENTED; } static int serial_read(GSM_StateMachine *s, void *buf, size_t nbytes) { GSM_Device_SerialData *d = &s->Device.Data.Serial; return 0; } diff --git a/gammu/emb/common/device/serial/ser_unx.c b/gammu/emb/common/device/serial/ser_unx.c index 2a87b11..69c7515 100644 --- a/gammu/emb/common/device/serial/ser_unx.c +++ b/gammu/emb/common/device/serial/ser_unx.c @@ -1,43 +1,67 @@ /* (c) 2002-2004 by Marcin Wiacek */ /* locking device and settings all speeds by Michal Cihar */ +/* based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_SERIALDEVICE #ifndef WIN32 #ifndef DJGPP #include <sys/file.h> #include <sys/time.h> #include <string.h> #include <termios.h> #include <errno.h> #include "../../gsmcomon.h" #include "ser_unx.h" +#ifndef O_NONBLOCK +# define O_NONBLOCK 0 +#endif + +#ifdef __NetBSD__ +# define FNONBLOCK O_NONBLOCK + +# define B57600 0010001 +# define B115200 0010002 +# define B230400 0010003 +# define B460800 0010004 +# define B500000 0010005 +# define B576000 0010006 +# define B921600 0010007 +# define B1000000 0010010 +# define B1152000 0010011 +# define B1500000 0010012 +# define B2000000 0010013 +# define B2500000 0010014 +# define B3000000 0010015 +# define B3500000 0010016 +# define B4000000 0010017 +#endif + static GSM_Error serial_close(GSM_StateMachine *s) { GSM_Device_SerialData *d = &s->Device.Data.Serial; /* Restores old settings */ tcsetattr(d->hPhone, TCSANOW, &d->old_settings); /* Closes device */ close(d->hPhone); return ERR_NONE; } -#ifndef O_NONBLOCK -# define O_NONBLOCK 0 -#endif - static GSM_Error serial_open (GSM_StateMachine *s) { GSM_Device_SerialData *d = &s->Device.Data.Serial; struct termios t; int i; /* O_NONBLOCK MUST is required to avoid waiting for DCD */ d->hPhone = open(s->CurrentConfig->Device, O_RDWR | O_NOCTTY | O_NONBLOCK); @@ -172,17 +196,17 @@ static GSM_Error serial_setdtrrts(GSM_StateMachine *s, bool dtr, bool rts) return ERR_NONE; } static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) { GSM_Device_SerialData *d = &s->Device.Data.Serial; struct termios t; - int speed2 = B19200; + int speed2 = B19200; if (tcgetattr(d->hPhone, &t)) { GSM_OSErrorInfo(s,"tcgetattr in serial_setspeed"); return ERR_DEVICEREADERROR; } smprintf(s, "Setting speed to %d\n", speed); @@ -197,31 +221,35 @@ static GSM_Error serial_setspeed(GSM_StateMachine *s, int speed) case 600: speed2 = B600; break; case 1200: speed2 = B1200; break; case 1800: speed2 = B1800; break; case 2400: speed2 = B2400; break; case 4800: speed2 = B4800; break; case 9600: speed2 = B9600; break; case 19200: speed2 = B19200; break; case 38400: speed2 = B38400; break; +#ifdef B57600 case 57600: speed2 = B57600; break; case 115200: speed2 = B115200; break; case 230400: speed2 = B230400; break; case 460800: speed2 = B460800; break; +#ifdef B500000 case 500000: speed2 = B500000; break; case 576000: speed2 = B576000; break; case 921600: speed2 = B921600; break; case 1000000: speed2 = B1000000; break; case 1152000: speed2 = B1152000; break; case 1500000: speed2 = B1500000; break; case 2000000: speed2 = B2000000; break; case 2500000: speed2 = B2500000; break; case 3000000: speed2 = B3000000; break; case 3500000: speed2 = B3500000; break; case 4000000: speed2 = B4000000; break; +#endif +#endif } /* This should work on all systems because it is done according to POSIX */ cfsetispeed(&t, speed2); cfsetospeed(&t, speed2); if (tcsetattr(d->hPhone, TCSADRAIN, &t) == -1) { serial_close(s); diff --git a/gammu/emb/common/device/serial/ser_w32.c b/gammu/emb/common/device/serial/ser_w32.c index 9fa0135..7d88fc7 100644 --- a/gammu/emb/common/device/serial/ser_w32.c +++ b/gammu/emb/common/device/serial/ser_w32.c @@ -1,10 +1,14 @@ /* (c) 2002-2004 by Marcin Wiacek */ -/* based on some work from Gnokii, MSDN and others */ +/* based on some work from MSDN and others */ +/* based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_SERIALDEVICE #ifdef WIN32 #include <windows.h> #include <string.h> diff --git a/gammu/emb/common/gsmcomon.c b/gammu/emb/common/gsmcomon.c index d094ef3..445c3a6 100644 --- a/gammu/emb/common/gsmcomon.c +++ b/gammu/emb/common/gsmcomon.c @@ -116,26 +116,26 @@ typedef struct { GSM_Error ErrorNum; unsigned char *ErrorText; } PrintErrorEntry; static PrintErrorEntry PrintErrorEntries[] = { {ERR_NONE, "No error."}, {ERR_DEVICEOPENERROR, "Error opening device. Unknown/busy or no permissions."}, {ERR_DEVICELOCKED, "Error opening device. Device locked."}, - {ERR_DEVICENOTEXIST, "Error opening device. Not exist."}, + {ERR_DEVICENOTEXIST, "Error opening device. Doesn't exist."}, {ERR_DEVICEBUSY, "Error opening device. Already opened by other application."}, {ERR_DEVICENOPERMISSION, "Error opening device. No permissions."}, {ERR_DEVICENODRIVER, "Error opening device. No required driver in operating system."}, {ERR_DEVICENOTWORK, "Error opening device. Some hardware not connected/wrong configured."}, {ERR_DEVICEDTRRTSERROR, "Error setting device DTR or RTS."}, {ERR_DEVICECHANGESPEEDERROR, "Error setting device speed. Maybe speed not supported."}, {ERR_DEVICEWRITEERROR, "Error writing device."}, - {ERR_DEVICEREADERROR, "Error during reading device"}, - {ERR_DEVICEPARITYERROR, "Can't set parity on device"}, + {ERR_DEVICEREADERROR, "Error during reading device."}, + {ERR_DEVICEPARITYERROR, "Can't set parity on device."}, {ERR_TIMEOUT, "No response in specified timeout. Probably phone not connected."}, /* Some missed */ {ERR_UNKNOWNRESPONSE, "Unknown response from phone. See readme.txt, how to report it."}, /* Some missed */ {ERR_UNKNOWNCONNECTIONTYPESTRING,"Unknown connection type string. Check config file."}, {ERR_UNKNOWNMODELSTRING, "Unknown model type string. Check config file."}, {ERR_SOURCENOTAVAILABLE, "Some required functions not compiled for your OS. Please contact."}, {ERR_NOTSUPPORTED, "Function not supported by phone."}, @@ -144,29 +144,30 @@ static PrintErrorEntry PrintErrorEntries[] = { {ERR_INVALIDLOCATION, "Invalid location. Maybe too high ?"}, {ERR_NOTIMPLEMENTED, "Function not implemented. Help required."}, {ERR_FULL, "Memory full."}, {ERR_UNKNOWN, "Unknown error."}, /* Some missed */ {ERR_CANTOPENFILE, "Can't open specified file. Read only ?"}, {ERR_MOREMEMORY, "More memory required..."}, {ERR_PERMISSION, "Permission to file/device required..."}, - {ERR_EMPTYSMSC, "Empty SMSC number. Set in phone or use -smscnumber"}, + {ERR_EMPTYSMSC, "Empty SMSC number. Set in phone or use -smscnumber."}, {ERR_INSIDEPHONEMENU, "You're inside phone menu (during editing ?). Leave it and try again."}, {ERR_WORKINPROGRESS, "Function is during writing. If want help, please contact with authors."}, - {ERR_PHONEOFF, "Phone is disabled and connected to charger"}, - {ERR_FILENOTSUPPORTED, "File format not supported by Gammu"}, + {ERR_PHONEOFF, "Phone is disabled and connected to charger."}, + {ERR_FILENOTSUPPORTED, "File format not supported by Gammu."}, {ERR_BUG, "Nobody is perfect, some bug appeared in protocol implementation. Please contact authors."}, - {ERR_CANCELED, "Transfer was canceled by phone (you pressed cancel on phone?)."}, + {ERR_CANCELED, "Transfer was canceled by phone (you pressed cancel on phone?)"}, /* Some missed */ {ERR_OTHERCONNECTIONREQUIRED, "Current connection type doesn't support called function."}, - /* Some missed */ + {ERR_WRONGCRC, "CRC error."}, {ERR_INVALIDDATETIME, "Invalid date or time specified."}, - {ERR_MEMORY, "Phone memory error, maybe it is read only"}, - {ERR_INVALIDDATA, "Invalid data"}, + {ERR_MEMORY, "Phone memory error, maybe it is read only."}, + {ERR_INVALIDDATA, "Invalid data."}, + {ERR_FILEALREADYEXIST, "File with specified name already exist."}, {0, ""} }; unsigned char *print_error(GSM_Error e, FILE *df, INI_Section *cfg) { unsigned char *def = NULL; int i = 0; diff --git a/gammu/emb/common/gsmcomon.h b/gammu/emb/common/gsmcomon.h index cd36708..e067955 100644 --- a/gammu/emb/common/gsmcomon.h +++ b/gammu/emb/common/gsmcomon.h @@ -61,17 +61,18 @@ typedef enum { ERR_FILENOTSUPPORTED, /* File format not supported by Gammu */ ERR_BUG, /* Found bug in implementation or phone */ ERR_CANCELED, /* Action was canceled by user */ ERR_NEEDANOTHERANSWER, /* Inside Gammu: phone module need to send another answer frame */ /*40*/ ERR_OTHERCONNECTIONREQUIRED, ERR_WRONGCRC, ERR_INVALIDDATETIME, /* Invalid date/time */ ERR_MEMORY, /* Phone memory error, maybe it is read only */ - ERR_INVALIDDATA /* Invalid data */ + ERR_INVALIDDATA, /* Invalid data */ + ERR_FILEALREADYEXIST /* File with specified name already exist */ } GSM_Error; extern GSM_Error NoneFunction (void); extern GSM_Error NotImplementedFunction (void); extern GSM_Error NotSupportedFunction (void); #define NONEFUNCTION (void *) NoneFunction #define NOTIMPLEMENTED (void *) NotImplementedFunction diff --git a/gammu/emb/common/gsmstate.c b/gammu/emb/common/gsmstate.c index b8f5f89..31e365d 100644 --- a/gammu/emb/common/gsmstate.c +++ b/gammu/emb/common/gsmstate.c @@ -181,16 +181,19 @@ GSM_Error GSM_RegisterAllPhoneModules(GSM_StateMachine *s) GSM_RegisterModule(s,&MROUTERGENPhone); #endif #ifdef GSM_ENABLE_NOKIA3320 GSM_RegisterModule(s,&N3320Phone); #endif #ifdef GSM_ENABLE_NOKIA3650 GSM_RegisterModule(s,&N3650Phone); #endif +#ifdef GSM_ENABLE_NOKIA650 + GSM_RegisterModule(s,&N650Phone); +#endif #ifdef GSM_ENABLE_NOKIA6110 GSM_RegisterModule(s,&N6110Phone); #endif #ifdef GSM_ENABLE_NOKIA6510 GSM_RegisterModule(s,&N6510Phone); #endif #ifdef GSM_ENABLE_NOKIA7110 GSM_RegisterModule(s,&N7110Phone); @@ -205,17 +208,16 @@ GSM_Error GSM_RegisterAllPhoneModules(GSM_StateMachine *s) return ERR_NONE; } GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum) { GSM_Error error; GSM_DateTime time; int i; - char Buffer[80]; for (i=0;i<s->ConfigNum;i++) { s->CurrentConfig = &s->Config[i]; s->Speed = 0; s->ReplyNum = ReplyNum; s->Phone.Data.ModelInfo = GetModelData("unknown",NULL,NULL); s->Phone.Data.Manufacturer[0] = 0; @@ -245,28 +247,26 @@ GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum) s->di = di; s->di.use_global = s->CurrentConfig->UseGlobalDebugFile; GSM_SetDebugLevel(s->CurrentConfig->DebugLevel, &s->di); error=GSM_SetDebugFile(s->CurrentConfig->DebugFile, &s->di); if (error != ERR_NONE) return error; if (s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXT || s->di.dl == DL_TEXTERROR || s->di.dl == DL_TEXTALLDATE || s->di.dl == DL_TEXTDATE || s->di.dl == DL_TEXTERRORDATE) { - smprintf(s,"[Gammu - version %s built %s %s]\n",VERSION,__TIME__,__DATE__); - smprintf(s,"[Connection - \"%s\"]\n",s->CurrentConfig->Connection); + smprintf(s,"[Gammu - %s built %s %s",VERSION,__TIME__,__DATE__); + if (strlen(GetCompiler()) != 0) { + smprintf(s," in %s",GetCompiler()); + } + smprintf(s,"]\n[Connection - \"%s\"]\n",s->CurrentConfig->Connection); smprintf(s,"[Model type - \"%s\"]\n",s->CurrentConfig->Model); smprintf(s,"[Device - \"%s\"]\n",s->CurrentConfig->Device); - - Buffer[0] = 0; - if (strlen(GetOS()) != 0) sprintf(Buffer,"%s",GetOS()); - if (strlen(GetCompiler()) != 0) { - if (Buffer[0] != 0) strcat(Buffer+strlen(Buffer),", "); - strcat(Buffer+strlen(Buffer),GetCompiler()); + if (strlen(GetOS()) != 0) { + smprintf(s,"[Run on - %s]\n",GetOS()); } - if (Buffer[0] != 0) smprintf(s,"[OS/compiler - %s]\n",Buffer); } if (s->di.dl==DL_BINARY) { smprintf(s,"%c",((unsigned char)strlen(VERSION))); smprintf(s,"%s",VERSION); } error=GSM_RegisterAllConnections(s, s->CurrentConfig->Connection); if (error!=ERR_NONE) return error; @@ -549,32 +549,43 @@ GSM_Error GSM_WaitFor (GSM_StateMachine *s, unsigned char *buffer, static GSM_Error CheckReplyFunctions(GSM_StateMachine *s, GSM_Reply_Function *Reply, int *reply) { GSM_Phone_Data *Data = &s->Phone.Data; GSM_Protocol_Message *msg = s->Phone.Data.RequestMsg; bool execute; bool available = false; int i = 0; +// int j; while (Reply[i].requestID!=ID_None) { execute=false; /* Binary frames like in Nokia */ if (strlen(Reply[i].msgtype) < 2) { if (Reply[i].msgtype[0]==msg->Type) { if (Reply[i].subtypechar!=0) { if (Reply[i].subtypechar<=msg->Length) { if (msg->Buffer[Reply[i].subtypechar]==Reply[i].subtype) execute=true; } } else execute=true; } } else { - if (strncmp(Reply[i].msgtype,msg->Buffer,strlen(Reply[i].msgtype))==0) { - execute=true; +// printf("msg length %i %i\n",strlen(Reply[i].msgtype),msg->Length); + if ((int)strlen(Reply[i].msgtype)<msg->Length) { +// printf("Comparing \"%s\" and \"",Reply[i].msgtype); +// for (j=0;j<strlen(Reply[i].msgtype);j++) { +// if (msg->Buffer[j]!=13 && msg->Buffer[j]!=10) { +// printf("%c",msg->Buffer[j]); +// } +// } +// printf("\"\n"); + if (strncmp(Reply[i].msgtype,msg->Buffer,strlen(Reply[i].msgtype))==0) { + execute=true; + } } } if (execute) { *reply=i; if (Reply[i].requestID == ID_IncomingFrame || Reply[i].requestID == Data->RequestID || Data->RequestID == ID_EachFrame) { @@ -840,38 +851,41 @@ bool GSM_ReadConfig(INI_Section *cfg_info, GSM_Config *cfg, int num) cfg->StartInfo = strdup(DefaultStartInfo); } else { cfg->DefaultStartInfo = false; } return true; } static OnePhoneModel allmodels[] = { +#ifdef GSM_ENABLE_NOKIA650 + {"0650" ,"THF-12","", {0}}, +#endif #ifdef GSM_ENABLE_NOKIA6510 - {"1100", "RH-18" ,"", {0}}, + {"1100" ,"RH-18" ,"", {0}}, {"1100a","RH-38" ,"", {0}}, {"1100b","RH-36" ,"", {0}}, #endif #ifdef GSM_ENABLE_NOKIA6110 {"2100" ,"NAM-2" ,"", {F_NOWAP,F_NOCALLER,F_RING_SM,F_CAL33,F_POWER_BATT,F_PROFILES33,F_NOCALLINFO,F_NODTMF,0}},//quess #endif #ifdef GSM_ENABLE_NOKIA6510 - {"3100" ,"RH-19" ,"", {F_PBKTONEGAL,F_PBKSMSLIST,0}}, - {"3100b","RH-50" ,"", {F_PBKTONEGAL,F_PBKSMSLIST,0}}, + {"3100" ,"RH-19" ,"", {F_PBKTONEGAL,F_PBKSMSLIST,0}},//fixme + {"3100b","RH-50" ,"", {F_PBKTONEGAL,F_PBKSMSLIST,0}},//fixme {"3108", "RH-6", "Nokia 3108", {0}}, //does it have irda ? - {"3200", "RH-30" ,"Nokia 3200", {F_PBKTONEGAL,0}}, - {"3200a","RH-31" ,"Nokia 3200", {F_PBKTONEGAL,0}}, + {"3200", "RH-30" ,"Nokia 3200", {F_PBKTONEGAL,0}},//fixme + {"3200a","RH-31" ,"Nokia 3200", {F_PBKTONEGAL,0}},//fixme #endif #ifdef GSM_ENABLE_NOKIA6110 {"3210" ,"NSE-8" ,"", {F_NOWAP,F_NOCALLER,F_NOCALENDAR,F_NOPBKUNICODE,F_POWER_BATT,F_PROFILES51,F_NOPICTUREUNI,F_NOCALLINFO,F_NODTMF,0}}, {"3210" ,"NSE-9" ,"", {F_NOWAP,F_NOCALLER,F_NOCALENDAR,F_NOPBKUNICODE,F_POWER_BATT,F_PROFILES51,F_NOPICTUREUNI,F_NOCALLINFO,F_NODTMF,0}}, #endif #ifdef GSM_ENABLE_NOKIA6510 - {"3300" ,"NEM-1" ,"Nokia 3300", {F_PBKTONEGAL,0}}, - {"3300" ,"NEM-2" ,"Nokia 3300", {F_PBKTONEGAL,0}}, + {"3300" ,"NEM-1" ,"Nokia 3300", {F_PBKTONEGAL,0}},//fixme + {"3300" ,"NEM-2" ,"Nokia 3300", {F_PBKTONEGAL,0}},//fixme #endif #ifdef GSM_ENABLE_NOKIA6110 {"3310" ,"NHM-5" ,"", {F_NOWAP,F_NOCALLER,F_RING_SM,F_CAL33,F_POWER_BATT,F_PROFILES33,F_NOCALLINFO,F_NODTMF,0}}, #endif #ifdef GSM_ENABLE_NOKIA3320 {"3320" ,"NPC-1" ,"Nokia 3320", {F_CAL62,F_DAYMONTH,0}},//fixme #endif #ifdef GSM_ENABLE_NOKIA6110 @@ -893,16 +907,18 @@ static OnePhoneModel allmodels[] = { #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA3650) {"3650" ,"NHL-8" ,"Nokia 3650", {0}}, {"NGAGE","NEM-4" ,"", {F_RADIO,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) {"5100" ,"NPM-6" ,"Nokia 5100", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, {"5100" ,"NPM-6U","Nokia 5100", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, {"5100" ,"NPM-6X","Nokia 5100", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, + {"5140" ,"NPL-4" ,"Nokia 5140", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKUSER,F_WAPMMSPROXY,0}}, + {"5140" ,"NPL-5" ,"Nokia 5140", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKUSER,F_WAPMMSPROXY,0}}, #endif #ifdef GSM_ENABLE_NOKIA6110 {"5110" ,"NSE-1" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, {"5110i","NSE-2" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, {"5130" ,"NSK-1" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, {"5190" ,"NSB-1" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6110) @@ -917,37 +933,41 @@ static OnePhoneModel allmodels[] = { #ifdef GSM_ENABLE_NOKIA6110 {"6110" ,"NSE-3" ,"", {F_NOWAP,F_NOPICTURE,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,0}}, {"6130" ,"NSK-3" ,"", {F_NOWAP,F_NOPICTURE,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,0}}, {"6150" ,"NSM-1" ,"", {F_NOWAP,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,F_NOPICTUREUNI,0}}, {"6190" ,"NSB-3" ,"", {F_NOWAP,F_NOPICTURE,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) {"6200" ,"NPL-3" ,"Nokia 6200", {F_PBKTONEGAL,0}}, - {"6220" ,"RH-20" ,"Nokia 6220", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,F_PBKUSER,F_WAPMMSPROXY,0}}, + {"6220" ,"RH-20" ,"Nokia 6220", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,F_PBKUSER,F_WAPMMSPROXY,F_NOTES,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA7110) {"6210" ,"NPE-3" ,"Nokia 6210", {F_VOICETAGS,F_CAL62,0}}, {"6250" ,"NHM-3" ,"Nokia 6250", {F_VOICETAGS,F_CAL62,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) - {"6230" ,"RH-12" ,"Nokia 6230", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,F_PBKUSER,0}}, + {"6230" ,"RH-12" ,"Nokia 6230", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,F_PBKUSER,F_WAPMMSPROXY,F_NOTES,0}}, {"6310" ,"NPE-4" ,"Nokia 6310", {F_TODO63,F_CAL65,F_NOMIDI,F_NOMMS,F_VOICETAGS,0}}, {"6310i","NPL-1" ,"Nokia 6310i",{F_TODO63,F_CAL65,F_NOMIDI,F_BLUETOOTH,F_NOMMS,F_VOICETAGS,0}}, {"6385" ,"NHP-2AX","Nokia 6385",{F_TODO63,F_CAL65,F_NOMIDI,F_NOMMS,F_VOICETAGS,0}}, {"6510" ,"NPM-9" ,"Nokia 6510", {F_TODO63,F_CAL65,F_NOMIDI,F_RADIO,F_NOFILESYSTEM,F_NOMMS,F_VOICETAGS,0}}, {"6610" ,"NHL-4U","Nokia 6610", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, + {"6610i","RM-37" ,"Nokia 6610i",{F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, {"6800" ,"NSB-9" ,"Nokia 6800", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,0}}, {"6800" ,"NHL-6" ,"Nokia 6800", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,0}}, + {"6810" ,"RM-2" ,"Nokia 6810", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,0}},//quess + {"6820" ,"NHL-9" ,"Nokia 6820", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,0}},//quess #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA7110) {"7110" ,"NSE-5" ,"Nokia 7110", {F_CAL62,0}}, {"7190" ,"NSB-5" ,"Nokia 7190", {F_CAL62,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) + {"7200" ,"RH-23" ,"Nokia 7200", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,F_PBKUSER,0}},//quess {"7210" ,"NHL-4" ,"Nokia 7210", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, {"7250" ,"NHL-4J","Nokia 7250", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKIMG,0}}, {"7250i","NHL-4JX","Nokia 7250i",{F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKIMG,0}}, {"7600", "NMM-3", "Nokia 7600", {F_TODO66,0}}, #endif #if defined(GSM_ENABLE_ATGEN) {"7650" ,"NHL-2" ,"Nokia 7650", {0}}, #endif @@ -970,45 +990,57 @@ static OnePhoneModel allmodels[] = { {"8910i","NHM-4" ,"Nokia 8910i",{F_CAL62,F_NOMIDI,F_NOFILESYSTEM,F_NOMMS,0}}, #endif #ifdef GSM_ENABLE_NOKIA9210 {"9210" ,"RAE-3" ,"", {0}}, {"9210i","RAE-5" ,"", {0}}, #endif #ifdef GSM_ENABLE_ATGEN {"at" , "at", "", {0}}, + /* Siemens */ {"M20" , "M20", "", {F_M20SMS,F_SLOWWRITE,0}}, {"MC35" , "MC35", "", {0}}, + {"TC35" , "TC35", "", {0}}, {"S25", "S25", "SIEMENS S25", {0}}, {"C35i" , "C35i", "", {0}}, {"S35i" , "S35i", "", {0}}, {"M35i" , "M35i", "", {0}}, {"S40" , "Siemens S40", "", {0}}, {"C45" , "C45", "", {0}}, {"S45" , "S45", "", {0}}, {"ME45" , "ME45", "", {0}}, {"SL45" , "SL45", "", {0}}, {"SL45i" , "SL45i", "", {0}}, {"M50" , "M50", "", {0}}, {"S45" , "6618" , "", {0}}, {"ME45" , "3618" , "", {0}}, {"S55" , "S55" , "", {0}}, + /* Samsung */ + {"S100" , "SGH-S100" , "", {0}}, + {"S200" , "SGH-S200" , "", {0}}, + {"S300" , "SGH-S300" , "", {0}}, + {"S500" , "SGH-S500" , "", {0}}, + {"V200" , "SGH-V200" , "", {0}}, + {"T100" , "SGH-T100" , "", {0}}, + {"E700" , "SGH-E700" , "", {0}}, + /* Ericsson/Sony Ericsson */ {"T28s", "1101101-BVT28s","", {0}}, {"R320s" , "1101201-BV R320s","", {0}}, {"R380s", "7100101-BVR380s" ,"", {0}}, {"R520m", "1130101-BVR520m" ,"", {0}}, {"T39m", "1130102-BVT39m" ,"", {0}}, {"T65", "1101901-BVT65" , "", {0}}, {"T68", "1130201-BVT68" , "", {0}}, {"T68i", "1130202-BVT68" , "", {0}}, {"R600", "102001-BVR600" , "", {0}}, {"T200", "1130501-BVT200" ,"", {0}}, {"T300", "1130601-BVT300" ,"T300", {0}}, {"T310", "1130602-BVT310" ,"", {0}}, {"P800", "7130501-BVP800" ,"", {0}}, + /* Other */ {"iPAQ" , "iPAQ" , "" , {0}}, {"A2D" , "A2D" , "" , {0}}, {"9210" , "RAE-3", "Nokia Communicator GSM900/1800",{0}}, {"myV-65", "myV-65 GPRS", "", {F_SMSME900,0}}, #endif #if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_ALCATEL) {"BE5", "ONE TOUCH 500","", {F_ALCATEL,F_SMSONLYSENT,F_BROKENCPBS,0}}, {"BH4", "ONE TOUCH 535","ALCATEL OT535", {F_ALCATEL,F_SMSONLYSENT,0}}, diff --git a/gammu/emb/common/gsmstate.h b/gammu/emb/common/gsmstate.h index cb17623..2b4806c 100644 --- a/gammu/emb/common/gsmstate.h +++ b/gammu/emb/common/gsmstate.h @@ -3,22 +3,30 @@ #ifndef __gsm_state_h #define __gsm_state_h #include <time.h> #include "config.h" #include "misc/cfg.h" +typedef struct _GSM_StateMachine GSM_StateMachine; +typedef struct _GSM_User GSM_User; +typedef struct _OnePhoneModel OnePhoneModel; +typedef struct _GSM_Reply_Function GSM_Reply_Function; + #ifdef GSM_ENABLE_NOKIA3320 # include "phone/nokia/dct4/n3320.h" #endif #ifdef GSM_ENABLE_NOKIA3650 # include "phone/nokia/dct4/n3650.h" #endif +#ifdef GSM_ENABLE_NOKIA650 +# include "phone/nokia/dct3/n0650.h" +#endif #ifdef GSM_ENABLE_NOKIA6110 # include "phone/nokia/dct3/n6110.h" #endif #ifdef GSM_ENABLE_NOKIA6510 # include "phone/nokia/dct4/n6510.h" #endif #ifdef GSM_ENABLE_NOKIA7110 # include "phone/nokia/dct3/n7110.h" @@ -89,17 +97,17 @@ #endif #ifndef GSM_USED_IRDAAT # undef GSM_ENABLE_IRDAAT #endif #ifndef GSM_USED_MROUTERBLUE # undef GSM_ENABLE_MROUTERBLUE #endif -#if defined(GSM_ENABLE_NOKIA3320) || defined(GSM_ENABLE_NOKIA6110) || defined(GSM_ENABLE_NOKIA7110) || defined(GSM_ENABLE_NOKIA9210) +#if defined(GSM_ENABLE_NOKIA3320) || defined(GSM_ENABLE_NOKIA650) || defined(GSM_ENABLE_NOKIA6110) || defined(GSM_ENABLE_NOKIA7110) || defined(GSM_ENABLE_NOKIA9210) # define GSM_ENABLE_NOKIA_DCT3 #endif #if defined(GSM_ENABLE_NOKIA3650) || defined(GSM_ENABLE_NOKIA6510) # define GSM_ENABLE_NOKIA_DCT4 #endif #include "protocol/protocol.h" #if defined(GSM_ENABLE_FBUS2) || defined(GSM_ENABLE_FBUS2IRDA) || defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2BLUE) || defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2DKU5) || defined(GSM_ENABLE_FBUS2PL2303) @@ -194,19 +202,16 @@ #include "service/gsmmisc.h" #include "service/gsmprof.h" #include "service/gsmcall.h" #include "service/sms/gsmsms.h" #include "service/sms/gsmems.h" #include "service/sms/gsmmulti.h" #include "service/backup/gsmback.h" -typedef struct _GSM_StateMachine GSM_StateMachine; -typedef struct _GSM_User GSM_User; -typedef struct _OnePhoneModel OnePhoneModel; /* ------------------------- Device layer ---------------------------------- */ /** * Device functions, each device has to provide these. */ typedef struct { /** @@ -366,16 +371,18 @@ typedef enum { ID_GetAlarm, ID_GetMemory, ID_GetMemoryStatus, ID_GetSMSC, ID_GetSMSMessage, ID_EnableEcho, ID_EnableErrorInfo, ID_SetOBEX, + ID_SetUSSD, + ID_GetNote, ID_GetSignalQuality, ID_GetBatteryCharge, ID_GetSMSFolders, ID_GetSMSFolderStatus, ID_GetSMSStatus, ID_AddSMSFolder, ID_GetNetworkInfo, ID_GetRingtone, @@ -433,16 +440,17 @@ typedef enum { ID_GetManufacturer, ID_SetMemoryType, ID_SetMemoryCharset, ID_GetMMSSettings, ID_SetSMSParameters, ID_GetFMStation, ID_SetFMStation, ID_GetLanguage, + ID_SetFastSMSSending, ID_Reset, ID_GetToDo, ID_PressKey, ID_DeleteAllToDo, ID_SetLight, ID_Divert, ID_SetToDo, ID_PlayTone, @@ -664,16 +672,17 @@ typedef struct { /** * Pointer to structure used internally by phone drivers. */ GSM_MultiCallDivert *Divert; /** * Pointer to structure used internally by phone drivers. */ GSM_ToDoEntry *ToDo; + GSM_NoteEntry *Note; /** * Used internally by phone drivers. */ bool PressKey; /** * Pointer to structure used internally by phone drivers. */ GSM_SecurityCodeType *SecurityStatus; @@ -765,16 +774,19 @@ typedef struct { struct { int fake; #ifdef GSM_ENABLE_NOKIA3320 GSM_Phone_N3320Data N3320; #endif #ifdef GSM_ENABLE_NOKIA3650 GSM_Phone_N3650Data N3650; #endif +#ifdef GSM_ENABLE_NOKIA650 + GSM_Phone_N650Data N650; +#endif #ifdef GSM_ENABLE_NOKIA6110 GSM_Phone_N6110Data N6110; #endif #ifdef GSM_ENABLE_NOKIA6510 GSM_Phone_N6510Data N6510; #endif #ifdef GSM_ENABLE_NOKIA7110 GSM_Phone_N7110Data N7110; @@ -799,17 +811,17 @@ typedef struct { * * Function is called when requestID matches current operation or is * ID_IncomingFrame and msgtype matches start message and (if msgtype is just * one character) subtypechar is zero or subtypechar-th character of message * matches subtype. * * Should be used in array with last element containing ID_None as requestID. */ -typedef struct { +struct _GSM_Reply_Function { /** * Pointer to function that should be executed. */ GSM_Error (*Function) (GSM_Protocol_Message msg, GSM_StateMachine *s); /** * Message type, if it is longer than 1 character, it disables subtype * checking. */ @@ -823,17 +835,17 @@ typedef struct { * Subtype to be checked. */ unsigned char subtype; /** * Phone request when this can be called, use ID_IncomingFrame when * you want to use this in any state. */ GSM_Phone_RequestID requestID; -} GSM_Reply_Function; +}; /** * Structure defining phone functions. */ typedef struct { /** * Names of supported models separated by |. Must contain at least one * name. @@ -1054,16 +1066,17 @@ typedef struct { /** * Sends SMS. */ GSM_Error (*SendSMS) (GSM_StateMachine *s, GSM_SMSMessage *sms); /** * Sends SMS already saved in phone. */ GSM_Error (*SendSavedSMS) (GSM_StateMachine *s, int Folder, int Location); + GSM_Error (*SetFastSMSSending) (GSM_StateMachine *s, bool enable); /** * Enable/disable notification on incoming SMS. */ GSM_Error (*SetIncomingSMS) (GSM_StateMachine *s, bool enable); /** * Gets network information from phone. */ GSM_Error (*SetIncomingCB) (GSM_StateMachine *s, bool enable); @@ -1274,17 +1287,17 @@ typedef struct { GSM_Error (*GetCalendarSettings)(GSM_StateMachine *s, GSM_CalendarSettings *settings); /** * Sets calendar settings. */ GSM_Error (*SetCalendarSettings)(GSM_StateMachine *s, GSM_CalendarSettings *settings); /** * Gets note. */ - GSM_Error (*GetNote) (GSM_StateMachine *s, GSM_NoteEntry *Note, bool refresh); + GSM_Error (*GetNextNote) (GSM_StateMachine *s, GSM_NoteEntry *Note, bool refresh); /** * Reads profile. */ GSM_Error (*GetProfile) (GSM_StateMachine *s, GSM_Profile *Profile); /** * Updates profile. */ GSM_Error (*SetProfile) (GSM_StateMachine *s, GSM_Profile *Profile); @@ -1339,16 +1352,19 @@ typedef struct { extern GSM_Phone_Functions N3320Phone; #endif #ifdef GSM_ENABLE_NOKIA3650 extern GSM_Phone_Functions N3650Phone; #endif #ifdef GSM_ENABLE_NOKIA6110 extern GSM_Phone_Functions N6110Phone; #endif +#ifdef GSM_ENABLE_NOKIA650 + extern GSM_Phone_Functions N650Phone; +#endif #ifdef GSM_ENABLE_NOKIA6510 extern GSM_Phone_Functions N6510Phone; #endif #ifdef GSM_ENABLE_NOKIA7110 extern GSM_Phone_Functions N7110Phone; #endif #ifdef GSM_ENABLE_NOKIA9210 extern GSM_Phone_Functions N9210Phone; @@ -1518,16 +1534,17 @@ typedef enum { F_NOGPRSPOINT, /* GPRS point are not useable */ F_CAL35, /* Calendar,3510 style - Reminder,Call,Birthday */ F_CAL65, /* Calendar,6510 style - CBMM, method 3 */ F_WAPMMSPROXY, /* WAP & MMS settings contains first & second proxy */ /* n6510.c && n7110.c */ F_VOICETAGS, /* Voice tags available */ F_CAL62, /* Calendar,6210 style - Call,Birthday,Memo,Meeting */ + F_NOTES, /* AT modules */ F_SMSONLYSENT, /* Phone supports only sent/unsent messages */ F_BROKENCPBS, /* CPBS on some memories can hang phone */ F_M20SMS, /* Siemens M20 like SMS handling */ F_SLOWWRITE, /* Use slower writing which some phone need */ F_SMSME900, /* SMS in ME start from location 900 - case of Sagem */ F_ALCATEL /* Phone supports Alcatel protocol */ diff --git a/gammu/emb/common/misc/coding/coding.c b/gammu/emb/common/misc/coding/coding.c index 62543ac..b30b645 100644 --- a/gammu/emb/common/misc/coding/coding.c +++ b/gammu/emb/common/misc/coding/coding.c @@ -1,26 +1,179 @@ /* (c) 2002-2004 by Marcin Wiacek, Michal Cihar and others */ -/* based on some work from MyGnokii and Gnokii */ +/* based on some work from MyGnokii (www.mwiacek.com) */ +/* based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <locale.h> #ifndef __OpenBSD__ # include <wctype.h> #endif #ifdef WIN32 # include "windows.h" #endif #include "../misc.h" #include "coding.h" +/* function changes #10 #13 chars to \n \r */ +char *EncodeUnicodeSpecialChars(unsigned char *buffer) +{ + int Pos=0, Pos2=0; + static unsigned char Buf[20000]; + + while (buffer[Pos*2]!=0x00 || buffer[Pos*2+1]!=0x00) { + if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 10) { + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = '\\'; + Pos2++; + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = 'n'; + Pos2++; + } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 13) { + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = '\\'; + Pos2++; + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = 'r'; + Pos2++; + } else if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') { + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = '\\'; + Pos2++; + Buf[Pos2*2] = 0x00; + Buf[Pos2*2+1] = '\\'; + Pos2++; + } else { + Buf[Pos2*2] = buffer[Pos*2]; + Buf[Pos2*2+1] = buffer[Pos*2+1]; + Pos2++; + } + Pos++; + } + Buf[Pos2*2] = 0; + Buf[Pos2*2+1] = 0; + return Buf; +} + +/* function changes #10 #13 chars to \n \r */ +char *EncodeSpecialChars(unsigned char *buffer) +{ + int Pos=0, Pos2=0; + static unsigned char Buf[10000]; + + while (buffer[Pos]!=0x00) { + switch (buffer[Pos]) { + case 10: + Buf[Pos2++] = '\\'; + Buf[Pos2++] = 'n'; + break; + case 13: + Buf[Pos2++] = '\\'; + Buf[Pos2++] = 'r'; + break; + case '\\': + Buf[Pos2++] = '\\'; + Buf[Pos2++] = '\\'; + break; + default: + Buf[Pos2++] = buffer[Pos]; + } + Pos++; + } + Buf[Pos2] = 0; + return Buf; +} + +char *DecodeUnicodeSpecialChars(unsigned char *buffer) +{ + int Pos=0, Pos2=0, level=0; + static unsigned char Buf[10000]; + + while (buffer[Pos*2]!=0x00 || buffer[Pos*2+1]!=0x00) { + Buf[Pos2*2] = buffer[Pos*2]; + Buf[Pos2*2+1] = buffer[Pos*2+1]; + switch (level) { + case 0: + if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') { + level = 1; + } else { + Pos2++; + } + break; + case 1: + if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 'n') { + Buf[Pos2*2] = 0; + Buf[Pos2*2+1] = 10; + } + if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == 'r') { + Buf[Pos2*2] = 0; + Buf[Pos2*2+1] = 13; + } + if (buffer[Pos*2] == 0x00 && buffer[Pos*2+1] == '\\') { + Buf[Pos2*2] = 0; + Buf[Pos2*2+1] = '\\'; + } + Pos2++; + level = 0; + } + Pos++; + } + Buf[Pos2*2] = 0; + Buf[Pos2*2+1] = 0; + return Buf; +} + +char *DecodeSpecialChars(unsigned char *buffer) +{ + int Pos=0, Pos2=0, level=0; + static unsigned char Buf[10000]; + + while (buffer[Pos]!=0x00) { + Buf[Pos2] = buffer[Pos]; + switch (level) { + case 0: + if (buffer[Pos] == '\\') { + level = 1; + } else { + Pos2++; + } + break; + case 1: + if (buffer[Pos] == 'n') Buf[Pos2] = 10; + if (buffer[Pos] == 'r') Buf[Pos2] = 13; + if (buffer[Pos] == '\\') Buf[Pos2] = '\\'; + Pos2++; + level = 0; + } + Pos++; + } + Buf[Pos2] = 0; + return Buf; +} + +char *mystrcasestr(unsigned const char *a, unsigned const char *b) +{ + unsigned char A[2000], B[200]; + int i; + + memset(A,0,sizeof(A)); + memset(B,0,sizeof(B)); + for (i=0;i<(int)strlen(a);i++) A[i] = tolower(a[i]); + for (i=0;i<(int)strlen(b);i++) B[i] = tolower(b[i]); + + return strstr(A,B); +} + unsigned int UnicodeLength(const unsigned char *str) { unsigned int len = 0; if (str == NULL) return 0; while(str[len*2] != 0 || str[len*2+1] != 0) len++; @@ -581,24 +734,24 @@ void GSM_UnpackSemiOctetNumber(unsigned char *retval, unsigned char *Number, boo /* Convert number of semioctets to number of chars */ if (length % 2) length++; length=length / 2 + 1; } /*without leading byte with format of number*/ length--; - switch (Number[1]) { - case NUMBER_ALPHANUMERIC: + switch ((Number[1] & 112)) { + case (NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN & 112): if (length > 6) length++; dbgprintf("Alphanumeric number, length %i\n",length); GSM_UnpackEightBitsToSeven(0, length, length, Number+2, Buffer); Buffer[length]=0; break; - case NUMBER_INTERNATIONAL: + case (NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN & 112): dbgprintf("International number\n"); Buffer[0]='+'; DecodeBCD(Buffer+1,Number+2, length); break; default: dbgprintf("Default number %02x\n",Number[1]); DecodeBCD (Buffer, Number+2, length); break; @@ -626,40 +779,40 @@ int GSM_PackSemiOctetNumber(unsigned char *Number, unsigned char *Output, bool s { unsigned char format, buffer[50]; int length, i; length=UnicodeLength(Number); memcpy(buffer,DecodeUnicodeString(Number),length+1); /* Checking for format number */ - format = NUMBER_UNKNOWN; + format = NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN; for (i=0;i<length;i++) { /* first byte is '+'. Number can be international */ if (i==0 && buffer[i]=='+') { - format=NUMBER_INTERNATIONAL; + format=NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN; } else { /*char is not number. It must be alphanumeric*/ - if (!isdigit(buffer[i])) format=NUMBER_ALPHANUMERIC; + if (!isdigit(buffer[i])) format=NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN; } } /** * First byte is used for saving type of number. See GSM 03.40 * section 9.1.2.5 */ Output[0]=format; /* After number type we will have number. GSM 03.40 section 9.1.2 */ switch (format) { - case NUMBER_ALPHANUMERIC: + case NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN: length=GSM_PackSevenBitsToEight(0, buffer, Output+1, strlen(buffer))*2; if (strlen(buffer)==7) length--; break; - case NUMBER_INTERNATIONAL: + case NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN: length--; EncodeBCD (Output+1, buffer+1, length, true); break; default: EncodeBCD (Output+1, buffer, length, true); break; } @@ -914,17 +1067,17 @@ void DecodeUnicodeSpecialNOKIAChars(unsigned char *dest, const unsigned char *sr } bool mystrncasecmp(unsigned const char *a, unsigned const char *b, int num) { int i; if (a == NULL || b == NULL) return false; - num--; + if (num == 0) num = -1; for (i = 0; i != num; i++) { if (a[i] == 0x00 && b[i] == 0x00) return true; if (a[i] == 0x00 || b[i] == 0x00) return false; if (tolower(a[i]) != tolower(b[i])) return false; } return true; } @@ -934,17 +1087,17 @@ bool mystrncasecmp(unsigned const char *a, unsigned const char *b, int num) */ bool mywstrncasecmp(unsigned const char *a, unsigned const char *b, int num) { int i; wchar_t wc,wc2; if (a == NULL || b == NULL) return false; - num--; + if (num == 0) num = -1; for (i = 0; i != num; i++) { if ((a[i*2] == 0x00 && a[i*2+1] == 0x00) && (b[i*2] == 0x00 && b[i*2+1] == 0x00)) return true; if ((a[i*2] == 0x00 && a[i*2+1] == 0x00) || (b[i*2] == 0x00 && b[i*2+1] == 0x00)) return false; wc = a[i*2+1] | (a[i*2] << 8); wc2 = b[i*2+1] | (b[i*2] << 8); if (mytowlower(wc) != mytowlower(wc2)) return false; } @@ -1010,17 +1163,17 @@ int mytowlower(wchar_t c) * My personal strstr() implementation that beats most other algorithms. * Until someone tells me otherwise, I assume that this is the * fastest implementation of strstr() in C. * I deliberately chose not to comment it. You should have at least * as much fun trying to understand it, as I had to write it :-). * * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */ -unsigned char *mystrstr (const unsigned char *haystack, const unsigned char *needle) +unsigned char *mywstrstr (const unsigned char *haystack, const unsigned char *needle) { /* One crazy define to convert unicode used in Gammu to standard wchar_t */ #define tolowerwchar(x) (mytowlower((wchar_t)( (((&(x))[0] & 0xff) << 8) | (((&(x))[1] & 0xff)) ))) register wchar_t b, c; if ((b = tolowerwchar(*needle)) != L'\0') { haystack -= 2; /* possible ANSI violation */ do { diff --git a/gammu/emb/common/misc/coding/coding.h b/gammu/emb/common/misc/coding/coding.h index d0c334d..4cf0038 100644 --- a/gammu/emb/common/misc/coding/coding.h +++ b/gammu/emb/common/misc/coding/coding.h @@ -1,24 +1,28 @@ /* (c) 2002-2004 by Marcin Wiacek and others */ #ifndef __coding_h #define __coding_h +#if defined(_MSC_VER) && defined(__cplusplus) + extern "C" { +#endif + #include <stdlib.h> #include "../misc.h" #ifdef __OpenBSD__ typedef int wint_t; #endif /* ---------------------------- Unicode ------------------------------------ */ bool mywstrncasecmp (unsigned const char *a, unsigned const char *b, int num); -unsigned char *mystrstr (unsigned const char *haystack, unsigned const char *needle); +unsigned char *mywstrstr (unsigned const char *haystack, unsigned const char *needle); bool mywstrncmp (unsigned const char *a, unsigned const char *b, int num); bool myiswspace (unsigned const char *src); int mytowlower (wchar_t c); unsigned int EncodeWithUnicodeAlphabet (const unsigned char *value, wchar_t *dest); unsigned int DecodeWithUnicodeAlphabet (wchar_t value, unsigned char *dest); unsigned int UnicodeLength (const unsigned char *str); @@ -30,16 +34,19 @@ void EncodeUnicode (unsigned char *dest, const unsigned char *src, int len); void CopyUnicodeString (unsigned char *Dest, unsigned char *Source); void ReverseUnicodeString (unsigned char *String); void ReadUnicodeFile (unsigned char *Dest, unsigned char *Source); void DecodeUnicodeSpecialNOKIAChars (unsigned char *dest, const unsigned char *src, int len); void EncodeUnicodeSpecialNOKIAChars (unsigned char *dest, const unsigned char *src, int len); +char *EncodeUnicodeSpecialChars (unsigned char *buffer); +char *DecodeUnicodeSpecialChars (unsigned char *buffer); + /* ------------------------------- BCD ------------------------------------- */ unsigned char EncodeWithBCDAlphabet (int value); int DecodeWithBCDAlphabet (unsigned char value); void DecodeBCD (unsigned char *dest, const unsigned char *src, int len); void EncodeBCD (unsigned char *dest, const unsigned char *src, int len, bool fill); /* ------------------------------ UTF7 ------------------------------------- */ @@ -81,25 +88,25 @@ int GSM_UnpackEightBitsToSeven (int offset, int in_length, int out_length, /** * Enum to handle types of phones numbers like * specified in GSM 03.40 section 9.1.2.5 */ typedef enum { /** * Unknown number type */ - NUMBER_UNKNOWN = 0x81, + NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN = 0x81, /** * International number (full number with code of country) */ - NUMBER_INTERNATIONAL = 0x91, + NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN = 0x91, /** * Alphanumeric number (with chars too) */ - NUMBER_ALPHANUMERIC = 0xD0 + NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN = 0xD0 /* specification give also other values */ } GSM_NumberType; void GSM_UnpackSemiOctetNumber (unsigned char *retval, unsigned char *Number, bool semioctet); int GSM_PackSemiOctetNumber (unsigned char *Number, unsigned char *Output, bool semioctet); /* ---------------------------- Bits --------------------------------------- */ @@ -117,17 +124,25 @@ void GetBufferI (unsigned char *Source, int *CurrentBit, int *result, int Bits int GetBit (unsigned char *Buffer, int BitNum); int SetBit (unsigned char *Buffer, int BitNum); int ClearBit (unsigned char *Buffer, int BitNum); /* ---------------------------- Other -------------------------------------- */ void StringToDouble (char *text, double *d); -bool mystrncasecmp (unsigned const char *a, unsigned const char *b, int num); +bool mystrncasecmp (unsigned const char *a, unsigned const char *b, int num); +char *mystrcasestr (unsigned const char *a, unsigned const char *b); -void MyGetLine(unsigned char *Buffer, int *Pos, unsigned char *OutBuffer, int MaxLen); +void MyGetLine (unsigned char *Buffer, int *Pos, unsigned char *OutBuffer, int MaxLen); + +char *EncodeSpecialChars(unsigned char *buffer); +char *DecodeSpecialChars(unsigned char *buffer); + +#if defined(_MSC_VER) && defined(__cplusplus) + } +#endif #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/misc/coding/md5.c b/gammu/emb/common/misc/coding/md5.c index 30fe33f..abb61be 100644 --- a/gammu/emb/common/misc/coding/md5.c +++ b/gammu/emb/common/misc/coding/md5.c @@ -1,9 +1,9 @@ -/* Taken from ReHash (see http://www.reichlsoft.de.vu/) and released +/* Taken from ReHash (www.reichlsoft.de.vu) and released * under GPL/LGPL with permission from ReHash author * Dominik Reichl <dominik.reichl@t-online.de>, Germany */ /* ********************************************************************** ** MD5.cpp ** ** ** diff --git a/gammu/emb/common/misc/misc.c b/gammu/emb/common/misc/misc.c index c2f09e4..7227e7b 100644 --- a/gammu/emb/common/misc/misc.c +++ b/gammu/emb/common/misc/misc.c @@ -6,16 +6,19 @@ #include <time.h> #include <stdarg.h> #include <stdio.h> #include <locale.h> #include <sys/timeb.h> #ifdef WIN32 # include "windows.h" #endif +#if defined(linux) || defined(__linux) || defined(__linux__) +# include <sys/utsname.h> +#endif #include "../gsmstate.h" #include "misc.h" /* Based on article in Polish PC-Kurier 8/1998 page 104 * Archive on http://www.pckurier.pl */ char *DayOfWeek (int year, int month, int day) @@ -225,21 +228,23 @@ char *OSDate (GSM_DateTime dt) #ifdef WIN32 setlocale(LC_ALL, ".ACP"); #endif return retval2; } bool CheckDate(GSM_DateTime *date) -{ - /* FIXME: This could also check if day is correct for selected month */ +{ + const unsigned int days[]={31,29,31,30,31,30,31,31,30,31,30,31}; + + /* FIXME: This could also check for leap years */ return date->Year != 0 && - date->Month >= 1 && date->Month <= 12 && - date->Day >= 1 && date->Day <= 31; + date->Month >= 1 && date->Month <= 12 && + date->Day >= 1 && date->Day <= days[date->Month]; } bool CheckTime(GSM_DateTime *date) { return date->Hour <= 23 && date->Hour >= 0 && date->Minute <= 59 && date->Minute >= 0 && date->Second <= 59 && date->Second >= 0; } @@ -446,16 +451,19 @@ void DumpMessage(FILE *df, Debug_Level dl, const unsigned char *message, int mes } char *GetOS(void) { #ifdef WIN32 OSVERSIONINFOEX Ver; bool Extended = true; #endif +#if defined(linux) || defined(__linux) || defined(__linux__) + struct utsname Ver; +#endif static char Buffer[100] = {0x00}; #ifdef WIN32 memset(&Ver,sizeof(OSVERSIONINFOEX),0); Ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if (!GetVersionEx((OSVERSIONINFO *)&Ver)) { Extended = false; @@ -515,17 +523,18 @@ char *GetOS(void) } else { sprintf(Buffer, "Windows %i.%i.%i",Ver.dwMajorVersion,Ver.dwMinorVersion,Ver.dwBuildNumber); } if (Extended && Ver.wServicePackMajor != 0) { sprintf(Buffer+strlen(Buffer)," SP%i",Ver.wServicePackMajor); } #elif defined(linux) || defined(__linux) || defined(__linux__) - sprintf(Buffer, "Linux"); + uname(&Ver); + sprintf(Buffer, "Linux, kernel %s",Ver.release); #elif defined(__FreeBSD__) sprintf(Buffer, "FreeBSD"); #elif defined(__NetBSD__) sprintf(Buffer, "NetBSD"); #elif defined(__OpenBSD__) sprintf(Buffer, "OpenBSD"); #elif defined(__GNU__) sprintf(Buffer, "GNU/Hurd"); diff --git a/gammu/emb/common/misc/misc.h b/gammu/emb/common/misc/misc.h index 8b46170..c461001 100644 --- a/gammu/emb/common/misc/misc.h +++ b/gammu/emb/common/misc/misc.h @@ -1,13 +1,17 @@ /* (c) 2002-2004 by Marcin Wiacek */ #ifndef __misc_h #define __misc_h +#if defined(_MSC_VER) && defined(__cplusplus) + extern "C" { +#endif + #include <stdio.h> #include <time.h> #ifdef WIN32 # include <windows.h> #endif #include "../config.h" @@ -125,13 +129,17 @@ time_t Fill_Time_T (GSM_DateTime DT, int TZ); void GetTimeDifference (unsigned long diff, GSM_DateTime *DT, bool Plus, int multi); void Fill_GSM_DateTime (GSM_DateTime *Date, time_t timet); bool CheckDate (GSM_DateTime *date); bool CheckTime (GSM_DateTime *date); char *GetCompiler(void); char *GetOS(void); +#if defined(_MSC_VER) && defined(__cplusplus) + } +#endif + #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/alcatel/alcatel.c b/gammu/emb/common/phone/alcatel/alcatel.c index f004ad4..3821f13 100644 --- a/gammu/emb/common/phone/alcatel/alcatel.c +++ b/gammu/emb/common/phone/alcatel/alcatel.c @@ -4,19 +4,19 @@ * High level functions for communication with Alcatel One Touch 501 and * compatible mobile phone. * * This code implements functions to communicate with Alcatel phones, * currently seem to work: * - BE5 series (501/701) * - BF5 series (715) * - BH4 series (535/735) - * For some functions it uses normal AT mode (not implemented here, look at - * ../at/atgen.[ch]) for others it switches into binary mode and initialises - * underlaying protocol (see ../../protocol/alcatel/alcabus.[ch]) and + * For some functions it uses normal AT mode (not implemented here, look at + * ../at/atgen.[ch]) for others it switches into binary mode and initialises + * underlaying protocol (see ../../protocol/alcatel/alcabus.[ch]) and * communicates over it. Don't ask me why Alcatel uses such silly thing... * * Notes for future features: * - max phone number length is 61 (BE5) * - max name length is 50 (BE5) */ #include "../../gsmstate.h" @@ -96,32 +96,33 @@ extern GSM_Error ATGEN_HandleCMSError (GSM_StateMachine *s); extern GSM_Error ATGEN_GetNetworkInfo (GSM_StateMachine *s, GSM_NetworkInfo *netinfo); extern GSM_Error ATGEN_Reset (GSM_StateMachine *s, bool hard); extern GSM_Error ATGEN_PressKey (GSM_StateMachine *s, GSM_KeyCode Key, bool Press); extern GSM_Error ATGEN_GetDisplayStatus (GSM_StateMachine *s, GSM_DisplayFeatures *features); extern GSM_Error ATGEN_SetAutoNetworkLogin (GSM_StateMachine *s); extern GSM_Error ATGEN_DeleteAllMemory (GSM_StateMachine *s, GSM_MemoryType type); extern GSM_Error ATGEN_DispatchMessage (GSM_StateMachine *s); +extern GSM_Error ATGEN_SetFastSMSSending (GSM_StateMachine *s, bool enable); extern GSM_Error ATGEN_SetIncomingCB (GSM_StateMachine *s, bool enable); extern GSM_Error ATGEN_SetIncomingSMS (GSM_StateMachine *s, bool enable); /** * Alcatel uses some 8-bit characters in contacts, calendar etc.. This table * attempts to decode it, it is probably not complete, here are just chars * that I found... */ unsigned char GSM_AlcatelAlphabet[] = { /* in phone unicode description */ 0x80, 0x00,0x20, /* empty */ 0x81, 0x00,0x20, /* empty */ 0x82, 0x00,0x20, /* empty */ 0x83, 0x00,0x20, /* empty */ - + 0x84, 0x00,0xe7, /* c cedilla */ 0x85, 0x20,0x26, /* ... */ 0x86, 0x03,0xc0, /* pi */ 0x87, 0x01,0x3e, /* l caron */ 0x88, 0x00,0xc0, /* A grave */ 0x89, 0x00,0xc1, /* A acute */ 0x8a, 0x00,0xc2, /* A circumflex */ 0x8b, 0x00,0xc3, /* A tilde */ @@ -163,115 +164,115 @@ unsigned char GSM_AlcatelAlphabet[] = 0xaf, 0x01,0x05, /* a ogonek */ 0xb0, 0x01,0x7c, /* z dot */ 0xb1, 0x01,0x7a, /* z acute */ 0xb2, 0x01,0x5b, /* s acute */ 0xb3, 0x01,0x44, /* n acute */ 0xb4, 0x01,0x42, /* l stroke */ 0xb5, 0x00,0x20, /* empty */ - + 0xb6, 0x01,0x48, /* n caron */ 0xb7, 0x01,0x65, /* t caron */ - + 0xb8, 0x00,0x20, /* empty */ - + 0xb9, 0x01,0x7e, /* z caron */ 0xba, 0x01,0xe7, /* g caron */ - + 0xbb, 0x00,0x20, /* empty */ 0xbc, 0x00,0x20, /* empty */ - + 0xbd, 0x1e,0x20, /* G macron */ 0xbe, 0x1e,0x21, /* g macron */ 0xbf, 0x01,0x5e, /* S cedilla */ 0xc0, 0x01,0x5f, /* s cedilla */ 0xc1, 0x01,0x2f, /* i ogonek */ /* FIXME: not sure with this, it look like normal i */ 0xc2, 0x01,0x31, /* i dotless */ 0xc3, 0x01,0x68, /* U tilde */ 0xc4, 0x01,0x50, /* O dbl acute */ 0xc5, 0x01,0x69, /* u tilde */ 0xc6, 0x01,0x51, /* o dbl acute */ 0xc7, 0x27,0xa9, /* => */ 0xc8, 0x27,0xa8, /* filled => */ 0xc9, 0x00,0xd7, /* x */ 0xca, 0x00,0x5d, /* ] */ 0xcb, 0x26,0x0f, /* phone */ 0xcc, 0x01,0x0f, /* d caron */ - + 0xcd, 0x00,0x20, /* empty */ 0xce, 0x00,0x7e, /* ~ */ 0xcf, 0x00,0x5c, /* \ */ 0xd0, 0x00,0x5e, /* ^ */ - + 0xd1, 0x00,0x20, /* empty */ - + 0xd2, 0x00,0x7b, /* { */ 0xd3, 0x00,0x7c, /* | */ 0xd4, 0x00,0x7d, /* } */ - + 0xd5, 0x00,0x20, /* empty */ - + 0xd6, 0x01,0x63, /* t cedilla */ - + 0xd7, 0x00,0x20, /* empty */ 0xd8, 0x00,0x20, /* empty */ 0xd9, 0x00,0x20, /* empty */ 0xda, 0x00,0x20, /* empty */ 0xdb, 0x00,0x20, /* empty */ 0xdc, 0x00,0x20, /* empty */ 0xdd, 0x00,0x20, /* empty */ 0xde, 0x00,0x20, /* empty */ 0xdf, 0x00,0x20, /* empty */ 0xe0, 0x00,0x20, /* empty */ - + 0xe1, 0x00,0x20, /* two candles */ /* FIXME */ - + 0xe2, 0x00,0x20, /* empty */ 0xe3, 0x00,0x20, /* empty */ 0xe4, 0x00,0x20, /* empty */ - + 0xe5, 0x01,0xce, /* a caron */ 0xe6, 0x01,0x01, /* a macron */ 0xe7, 0x01,0x13, /* e macron */ 0xe8, 0x01,0x2b, /* i macron */ 0xe9, 0x01,0x4d, /* o macron */ 0xea, 0x01,0x6b, /* u macron */ 0xeb, 0x00,0x41, /* A */ 0xec, 0x00,0x40, /* @ */ 0xed, 0x00,0x20, /* some strange char :-) */ /* FIXME */ - + 0xee, 0x00,0x20, /* big key stroken */ /* FIXME */ 0xef, 0x00,0x20, /* big key */ /* FIXME */ - + 0xf0, 0x00,0x20, /* empty */ - + 0xf1, 0x00,0x31, /* 1 */ 0xf2, 0x00,0x21, /* bold ! */ 0xf3, 0x26,0x0e, /* black phone */ 0xf4, 0x00,0x26, /* & */ 0xf5, 0x23,0x7e, /* bell */ 0xf6, 0x26,0x6a, /* note */ - + 0xf7, 0x27,0x13, /* okay inv */ /* FIXME */ 0xf8, 0x27,0x13, /* okay */ - + 0xf9, 0x00,0x20, /* empty */ - + 0xfa, 0x00,0x20, /* key */ /* FIXME */ - + 0xfb, 0x00,0x20, /* empty */ - + 0xfc, 0x20,0xac, /* Euro */ 0xfd, 0x21,0x97, /* NE arrow */ 0xfe, 0x21,0x98, /* SE arrow */ 0xff, 0x00,0x20, /* empty */ - + 0x00, 0x00,0x00 }; /* This is being called from atgen */ GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message msg, GSM_StateMachine *s) { char *str, *str2; /* @@ -310,30 +311,30 @@ static GSM_Error ALCATEL_SetBinaryMode(GSM_StateMachine *s) GSM_Error error; if (Priv->Mode == ModeBinary) return ERR_NONE; dbgprintf ("Changing to binary mode\n"); error=GSM_WaitFor (s, "AT+IFC=2,2\r", 11, 0x02, 4, ID_SetFlowControl); if (error != ERR_NONE) return error; - + error=GSM_WaitFor (s, "AT+CPROT=?\r", 11, 0x02, 4, ID_AlcatelProtocol); if (error != ERR_NONE) return error; if (Priv->ProtocolVersion == V_1_0) { error=GSM_WaitFor (s, "AT+CPROT=16,\"V1.0\",16\r", 22, 0x00, 4, ID_AlcatelConnect); } else { error=GSM_WaitFor (s, "AT+CPROT=16,\"V1.1\",16\r", 22, 0x00, 4, ID_AlcatelConnect); } - + if (error == ERR_TIMEOUT && s->Speed != 19200) { smprintf(s, "HINT: Try changing speed to 19200, it is sometimes needed for Alcatel binary mode.\n"); } - + if (error != ERR_NONE) return error; dbgprintf ("Changing protocol to Alcabus\n"); s->Protocol.Functions = &ALCABUSProtocol; error = s->Protocol.Functions->Initialise(s); if (error != ERR_NONE) { s->Protocol.Functions = &ATProtocol; @@ -371,17 +372,17 @@ static GSM_Error ALCATEL_GoToBinaryState(GSM_StateMachine *s, GSM_Alcatel_Binary {0x00, 0x04, 0x00, /*type */ 0x22, 0x01, 0x00}; unsigned char begin_buffer[] = {0x00, 0x04, 0x7C, 0x81, 0x00, /*type */ 0x00, 0x85, 0x00}; unsigned char commit_buffer[] = - {0x00, 0x04, + {0x00, 0x04, 0x00, /*type */ 0x20, 0x01}; smprintf(s, "Alcatel state switcher: %d -> %d, %d -> %d, %d -> %d\n", Priv->BinaryState, state, Priv->BinaryType, type, Priv->BinaryItem, item); error = ALCATEL_SetBinaryMode(s); if (error != ERR_NONE) return error; /* Do we need to do anything? */ @@ -438,17 +439,17 @@ static GSM_Error ALCATEL_GoToBinaryState(GSM_StateMachine *s, GSM_Alcatel_Binary end_buffer[4] = ALCATEL_BEGIN_SYNC_CONTACTS; break; case TypeToDo: end_buffer[4] = ALCATEL_BEGIN_SYNC_TODO; break; } error=GSM_WaitFor (s, end_buffer, 9, 0x02, ALCATEL_TIMEOUT, ID_AlcatelEnd); if (error != ERR_NONE) return error; - + switch (Priv->BinaryType) { case TypeCalendar: close_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; break; case TypeContacts: close_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; break; case TypeToDo: @@ -539,16 +540,18 @@ static GSM_Error ALCATEL_SetATMode(GSM_StateMachine *s) error = s->Protocol.Functions->Terminate(s); if (error != ERR_NONE) return error; dbgprintf ("Changing protocol to AT\n"); s->Protocol.Functions = &ATProtocol; s->Phone.Functions->ReplyFunctions = ATGENReplyFunctions; Priv->Mode = ModeAT; + s->Phone.Data.Priv.ATGEN.PBKCharset = 0; + s->Phone.Data.Priv.ATGEN.PBKMemory = 0; my_sleep(100); /* In case we don't send AT command short after closing binary mode, * phone takes VERY long to react next time. The error code in * intetionally ignored. */ GSM_WaitFor (s, "AT\r", 3, 0x00, 0, ID_IncomingFrame); @@ -623,21 +626,21 @@ static GSM_Error ALCATEL_IsIdAvailable(GSM_StateMachine *s, int id) { Priv->CurrentList = &(Priv->ContactsItems); Priv->CurrentCount = &(Priv->ContactsItemsCount); break; case TypeToDo: Priv->CurrentList = &(Priv->ToDoItems); Priv->CurrentCount = &(Priv->ToDoItemsCount); break; } - + for (i=0; i<*Priv->CurrentCount; i++) { if ((*Priv->CurrentList)[i] == id) return ERR_NONE; } - + return ERR_EMPTY; } /* finds next id that is available in the phone */ static GSM_Error ALCATEL_GetNextId(GSM_StateMachine *s, int *id) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; int i = 0; int next = ALCATEL_MAX_LOCATION; @@ -841,17 +844,17 @@ static GSM_Error ALCATEL_ReplyGetFieldValue(GSM_Protocol_Message msg, GSM_StateM Priv->ReturnDateTime.Minute = 0; Priv->ReturnDateTime.Second = 0; } else if (buffer[1] == 0x06 && buffer[2] == 0x68) { /* time */ Priv->ReturnType = Alcatel_time; Priv->ReturnDateTime.Hour = buffer[4]; Priv->ReturnDateTime.Minute = buffer[5]; Priv->ReturnDateTime.Second = buffer[6]; - + Priv->ReturnDateTime.Day = 0; Priv->ReturnDateTime.Month = 0; Priv->ReturnDateTime.Year = 0; Priv->ReturnDateTime.Timezone = 0; } else if (buffer[1] == 0x08 && buffer[2] == 0x3C) { /* string */ Priv->ReturnType = Alcatel_string; if (GSM_PHONEBOOK_TEXT_LENGTH < buffer[3]) @@ -1091,22 +1094,22 @@ static GSM_Error ALCATEL_ReplyGetCategoryText(GSM_Protocol_Message msg, GSM_Stat } return ERR_NONE; } static GSM_Error ALCATEL_GetCategoryText(GSM_StateMachine *s, int id) { unsigned char buffer[] = {0x00, 0x04, 0x00 /*type*/, 0x0c, 0x00 /*list*/, 0x0A, 0x01, 0x00 /*item*/ }; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; - + if (Priv->CurrentCategoriesCache[id][0] != '\000' || Priv->CurrentCategoriesCache[id][1] != '\000') { CopyUnicodeString(Priv->ReturnString, Priv->CurrentCategoriesCache[id]); return ERR_NONE; } - + smprintf(s,"Reading category %d\n", id); switch (Priv->BinaryType) { case TypeContacts: buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; buffer[4] = ALCATEL_LIST_CONTACTS_CAT; break; case TypeToDo: @@ -1118,17 +1121,17 @@ static GSM_Error ALCATEL_GetCategoryText(GSM_StateMachine *s, int id) { } buffer[7] = (id & 0xff); error=GSM_WaitFor (s, buffer, 8, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetCategoryText1); if (error != ERR_NONE) return error; error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetCategoryText2); if (error != ERR_NONE) return error; - + CopyUnicodeString(Priv->CurrentCategoriesCache[id], Priv->ReturnString); return ERR_NONE; } static GSM_Error ALCATEL_DeleteField(GSM_StateMachine *s, int id, int field) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; @@ -1208,19 +1211,19 @@ static GSM_Error ALCATEL_DeleteItem(GSM_StateMachine *s, int id) { static GSM_Error ALCATEL_ReplyDeleteItem(GSM_Protocol_Message msg, GSM_StateMachine *s) { if (msg.Buffer[8] != 0x25) return ERR_UNKNOWNRESPONSE; return ERR_NONE; } static GSM_Error ALCATEL_BuildWriteBuffer(unsigned char * buffer, GSM_Alcatel_FieldType type, int field, void *data) { int len; - + buffer[1] = field & 0xff; - + switch(type) { case Alcatel_date: if (!CheckDate((GSM_DateTime *)data)) return ERR_INVALIDDATETIME; buffer[3] = 0x05; buffer[4] = 0x67; buffer[0] = 0x09; @@ -1324,38 +1327,38 @@ static GSM_Error ALCATEL_CreateField(GSM_StateMachine *s, GSM_Alcatel_FieldType buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; break; } error = ALCATEL_BuildWriteBuffer(buffer + 6, type, field, data); if (error != ERR_NONE) return error; - + error = GSM_WaitFor (s, buffer, 8 + buffer[6], 0x02, ALCATEL_TIMEOUT, ID_AlcatelCreateField); if (error != ERR_NONE) return error; - + return ERR_NONE; } static GSM_Error ALCATEL_UpdateField(GSM_StateMachine *s, GSM_Alcatel_FieldType type, int id, int field, void *data) { GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; GSM_Error error; unsigned char buffer[200] = {0x00, 0x04, 0x00, /* type */ - 0x26, 0x01, + 0x26, 0x01, 0x00, 0x00, 0x00, 0x00, /* id */ 0x65, 0x00, /* length of remaining part */ 0x00, /* field */ 0x37}; /* data follows here */ smprintf(s,"Updating field (%08x.%02x)\n", id, field); - + buffer[5] = (id >> 24); buffer[6] = ((id >> 16) & 0xff); buffer[7] = ((id >> 8) & 0xff); buffer[8] = (id & 0xff); switch (Priv->BinaryType) { case TypeCalendar: buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR; @@ -1364,20 +1367,20 @@ static GSM_Error ALCATEL_UpdateField(GSM_StateMachine *s, GSM_Alcatel_FieldType buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS; break; case TypeToDo: buffer[2] = ALCATEL_SYNC_TYPE_TODO; break; } error = ALCATEL_BuildWriteBuffer(buffer + 10, type, field, data); if (error != ERR_NONE) return error; - + error = GSM_WaitFor (s, buffer, 12 + buffer[10], 0x02, ALCATEL_TIMEOUT, ID_AlcatelUpdateField); if (error != ERR_NONE) return error; - + return ERR_NONE; } static GSM_Error ALCATEL_GetManufacturer(GSM_StateMachine *s) { strcpy(s->Phone.Data.Manufacturer, "Alcatel"); return ERR_NONE; } @@ -1738,17 +1741,17 @@ static GSM_Error ALCATEL_GetNextMemory(GSM_StateMachine *s, GSM_MemoryEntry *ent { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if (entry->MemoryType == MEM_ME) { if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if (Priv->ContactsItemsCount == 0) return ERR_EMPTY; - + if (start) entry->Location = 0; if ((error = ALCATEL_GetNextId(s, &(entry->Location))) != ERR_NONE) return error; return ALCATEL_GetMemory(s, entry); } else { if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetNextMemory(s, entry, start); } @@ -1763,26 +1766,26 @@ static GSM_Error ALCATEL_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) int i; if (entry->MemoryType == MEM_ME) { if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeContacts, 0))!= ERR_NONE) return error; for (i = 0; i < entry->EntriesNum; i++) { switch (entry->Entries[i].EntryType) { - case PBK_Number_General: + case PBK_Number_General: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 8, entry->Entries[i].Text)) != ERR_NONE) return error; 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: + 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; @@ -1804,23 +1807,23 @@ static GSM_Error ALCATEL_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; case PBK_Text_FirstName: if ((error = ALCATEL_CreateField(s, Alcatel_string, 1, entry->Entries[i].Text)) != ERR_NONE) return error; NameSet = true; break; case PBK_Text_Company: if ((error = ALCATEL_CreateField(s, Alcatel_string, 2, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Text_JobTitle: + case PBK_Text_JobTitle: if ((error = ALCATEL_CreateField(s, Alcatel_string, 3, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Category: + case PBK_Category: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 5, &(entry->Entries[i].Number))) != ERR_NONE) return error; break; - case PBK_Private: + case PBK_Private: if ((error = ALCATEL_CreateField(s, Alcatel_bool, 6, &(entry->Entries[i].Number))) != ERR_NONE) return error; break; case PBK_Text_StreetAddress: if ((error = ALCATEL_CreateField(s, Alcatel_string, 16, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_City: if ((error = ALCATEL_CreateField(s, Alcatel_string, 17, entry->Entries[i].Text)) != ERR_NONE) return error; break; @@ -1835,22 +1838,22 @@ static GSM_Error ALCATEL_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) break; case PBK_Text_Custom1: if ((error = ALCATEL_CreateField(s, Alcatel_string, 21, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom2: if ((error = ALCATEL_CreateField(s, Alcatel_string, 22, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom3: - if ((error = ALCATEL_CreateField(s, Alcatel_string, 23, entry->Entries[i].Text)) != ERR_NONE) return error; + if ((error = ALCATEL_CreateField(s, Alcatel_string, 23, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom4: if ((error = ALCATEL_CreateField(s, Alcatel_string, 24, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_PictureID: + case PBK_PictureID: if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) { if ((error = ALCATEL_CreateField(s, Alcatel_int, 25, &(entry->Entries[i].Number))) != ERR_NONE) return error; } else { smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType); } break; case PBK_Text_Name: NamePosition = i; break; @@ -1901,123 +1904,123 @@ static GSM_Error ALCATEL_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) /* Save modified entry */ if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, entry->Location))!= ERR_NONE) { /* Entry doesn't exist, we will create new one */ return ALCATEL_AddMemory(s, entry); } /* Get fields for current item */ if ((error = ALCATEL_GetFields(s, entry->Location))!= ERR_NONE) return error; - + for (i = 0; i < 26; i++) { UpdatedFields[i] = false; } - + if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeContacts, entry->Location))!= ERR_NONE) return error; for (i = 0; i < entry->EntriesNum; i++) { 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; + 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; 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; + 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; + 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; + 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; + 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; + 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; break; case PBK_Number_Other: UpdatedFields[10] = true; - if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 10, entry->Entries[i].Text)) != ERR_NONE) return error; + if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 10, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Text_Note: + case PBK_Text_Note: UpdatedFields[4] = true; - if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 4, entry->Entries[i].Text)) != ERR_NONE) return error; + if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 4, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Text_Email: - UpdatedFields[14] = true; + case PBK_Text_Email: + UpdatedFields[14] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 14, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Text_Email2: - UpdatedFields[15] = true; - if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 15, entry->Entries[i].Text)) != ERR_NONE) return error; + case PBK_Text_Email2: + UpdatedFields[15] = true; + if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 15, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Text_LastName: - UpdatedFields[0] = true; - if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 0, entry->Entries[i].Text)) != ERR_NONE) return error; NameSet = true; + case PBK_Text_LastName: + UpdatedFields[0] = true; + if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 0, entry->Entries[i].Text)) != ERR_NONE) return error; NameSet = true; break; - case PBK_Text_FirstName: - UpdatedFields[1] = true; - if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 1, entry->Entries[i].Text)) != ERR_NONE) return error; NameSet = true; + case PBK_Text_FirstName: + UpdatedFields[1] = true; + if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 1, entry->Entries[i].Text)) != ERR_NONE) return error; NameSet = true; break; case PBK_Text_Company: - UpdatedFields[2] = true; - if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 2, entry->Entries[i].Text)) != ERR_NONE) return error; + UpdatedFields[2] = true; + if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 2, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Text_JobTitle: + case PBK_Text_JobTitle: UpdatedFields[3] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 3, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Category: - UpdatedFields[5] = true; + UpdatedFields[5] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, entry->Location, 5, &(entry->Entries[i].Number))) != ERR_NONE) return error; break; case PBK_Private: UpdatedFields[6] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_bool, entry->Location, 6, &(entry->Entries[i].Number))) != ERR_NONE) return error; break; - case PBK_Text_StreetAddress: + case PBK_Text_StreetAddress: UpdatedFields[16] = true; - if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 16, entry->Entries[i].Text)) != ERR_NONE) return error; + if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 16, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Text_City: - UpdatedFields[17] = true; - if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 17, entry->Entries[i].Text)) != ERR_NONE) return error; + case PBK_Text_City: + UpdatedFields[17] = true; + if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 17, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Text_State: - UpdatedFields[18] = true; - if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 18, entry->Entries[i].Text)) != ERR_NONE) return error; + case PBK_Text_State: + UpdatedFields[18] = true; + if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 18, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Text_Zip: - UpdatedFields[19] = true; - if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 19, entry->Entries[i].Text)) != ERR_NONE) return error; + case PBK_Text_Zip: + UpdatedFields[19] = true; + if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 19, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Country: UpdatedFields[20] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 20, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom1: UpdatedFields[21] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 21, entry->Entries[i].Text)) != ERR_NONE) return error; break; - case PBK_Text_Custom2: + case PBK_Text_Custom2: UpdatedFields[22] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 22, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom3: UpdatedFields[23] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 23, entry->Entries[i].Text)) != ERR_NONE) return error; break; case PBK_Text_Custom4: - UpdatedFields[24] = true; + UpdatedFields[24] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 24, entry->Entries[i].Text)) != ERR_NONE) return error ; break; - case PBK_PictureID: + case PBK_PictureID: if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) { UpdatedFields[25] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_int, entry->Location, 25, &(entry->Entries[i].Number))) != ERR_NONE) return error; } else { smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType); } break; @@ -2064,21 +2067,21 @@ static GSM_Error ALCATEL_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entr if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, entry->Location))!= ERR_NONE) { /* Entry was empty => no error */ return ERR_NONE; } /* Do real delete */ error = ALCATEL_DeleteItem(s, entry->Location); if (error != ERR_NONE) return error; - + /* Refresh list */ if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; - + return ERR_NONE; } else { if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_DeleteMemory(s, entry); } } static GSM_Error ALCATEL_DeleteAllMemory(GSM_StateMachine *s, GSM_MemoryType type) @@ -2223,17 +2226,17 @@ static GSM_Error ALCATEL_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *ne static GSM_Error ALCATEL_GetDisplayStatus(GSM_StateMachine *s, GSM_DisplayFeatures *features) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetDisplayStatus(s, features); } - + static GSM_Error ALCATEL_SetAutoNetworkLogin(GSM_StateMachine *s) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetAutoNetworkLogin(s); } @@ -2332,19 +2335,19 @@ static GSM_Error ALCATEL_GetSIMIMSI(GSM_StateMachine *s, char *IMSI) if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_GetSIMIMSI(s, IMSI); } static GSM_Error ALCATEL_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *status) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; - + status->Used = 0; - + if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; status->Used = Priv->CalendarItemsCount; return ERR_NONE; } static GSM_Error ALCATEL_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) @@ -2722,17 +2725,17 @@ static GSM_Error ALCATEL_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not static GSM_Error ALCATEL_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if (Priv->CalendarItemsCount == 0) return ERR_EMPTY; - + if (start) Note->Location = 0; if ((error = ALCATEL_GetNextId(s, &(Note->Location))) != ERR_NONE) return error; return ALCATEL_GetCalendar(s, Note); } static GSM_Error ALCATEL_DeleteCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) @@ -2763,17 +2766,17 @@ static GSM_Error ALCATEL_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not bool phone_set = false; bool date_set = false; bool repeating = false; int i; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeCalendar, 0))!= ERR_NONE) return error; - + for (i = 0; i < Note->EntriesNum; i++) { switch (Note->Entries[i].EntryType) { case CAL_START_DATETIME: if (!date_set) { if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error; date_set = true; } if ((error = ALCATEL_CreateField(s, Alcatel_time, 1, &(Note->Entries[i].Date))) != ERR_NONE) return error; @@ -2801,17 +2804,17 @@ static GSM_Error ALCATEL_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not break; case CAL_CONTACTID: if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &(Note->Entries[i].Number))) != ERR_NONE) return error; contact_set = true; break; case CAL_PHONE: if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, Note->Entries[i].Text)) != ERR_NONE) return error; phone_set = true; - break; + break; case CAL_REPEAT_DAYOFWEEK: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 10, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_DAY: if ((error = ALCATEL_CreateField(s, Alcatel_byte, 11, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; @@ -2837,17 +2840,17 @@ static GSM_Error ALCATEL_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not break; case CAL_SILENT_ALARM_DATETIME: case CAL_RECURRANCE: case CAL_LOCATION: smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", Note->Entries[i].EntryType); break; } } - + switch (Note->Type) { case GSM_CAL_CALL: val = 3; break; case GSM_CAL_BIRTHDAY: val = 2; break; case GSM_CAL_ALARM: @@ -2895,26 +2898,26 @@ static GSM_Error ALCATEL_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= ERR_NONE) { /* Entry doesn't exist, we will create new one */ return ALCATEL_AddCalendar(s, Note); } /* Get fields for current item */ if ((error = ALCATEL_GetFields(s, Note->Location))!= ERR_NONE) return error; - + for (i = 0; i < 22; i++) { UpdatedFields[i] = false; } if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeCalendar, Note->Location))!= ERR_NONE) return error; - + for (i = 0; i < Note->EntriesNum; i++) { switch (Note->Entries[i].EntryType) { case CAL_START_DATETIME: if (!date_set) { - UpdatedFields[0] = true; + UpdatedFields[0] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error; date_set = true; } UpdatedFields[1] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 1, &(Note->Entries[i].Date))) != ERR_NONE) return error; break; case CAL_END_DATETIME: if (!date_set) { @@ -2948,17 +2951,17 @@ static GSM_Error ALCATEL_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not UpdatedFields[8] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_int, Note->Location, 8, &(Note->Entries[i].Number))) != ERR_NONE) return error; contact_set = true; break; case CAL_PHONE: UpdatedFields[9] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_phone, Note->Location, 9, Note->Entries[i].Text)) != ERR_NONE) return error; phone_set = true; - break; + break; case CAL_REPEAT_DAYOFWEEK: UpdatedFields[10] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 10, &(Note->Entries[i].Number))) != ERR_NONE) return error; repeating = true; break; case CAL_REPEAT_DAY: UpdatedFields[11] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 11, &(Note->Entries[i].Number))) != ERR_NONE) return error; @@ -2991,17 +2994,17 @@ static GSM_Error ALCATEL_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Not break; case CAL_SILENT_ALARM_DATETIME: case CAL_RECURRANCE: case CAL_LOCATION: smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", Note->Entries[i].EntryType); break; } } - + switch (Note->Type) { case GSM_CAL_CALL: val = 3; break; case GSM_CAL_BIRTHDAY: val = 2; break; case GSM_CAL_ALARM: @@ -3067,17 +3070,17 @@ static GSM_Error ALCATEL_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) int i; bool Found = false; bool DateSet = false; int alarm_number = alarm->Location; static GSM_DateTime nulldt = {0,0,0,0,0,0,0}; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; - + for (i=0; i<Priv->CalendarItemsCount; i++) { if ((error = ALCATEL_GetFieldValue(s, Priv->CalendarItems[i], 7))!= ERR_NONE) return error; if (Priv->ReturnType != Alcatel_enum) { smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType); continue; } if (Priv->ReturnInt == 4 || Priv->ReturnInt == 5) { alarm_number--; @@ -3086,25 +3089,25 @@ static GSM_Error ALCATEL_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) break; } } } if (!Found) return ERR_EMPTY; Note.Location = Priv->CalendarItems[i]; - + if ((error = ALCATEL_GetCalendar(s, &Note))!= ERR_NONE) return error; if (Note.Type == GSM_CAL_ALARM) { alarm->Repeating = false; } else { alarm->Repeating = true; } - + alarm->Text[0] = 0; alarm->Text[1] = 0; for (i = 0; i < Note.EntriesNum; i++) { if (Note.Entries[i].EntryType == CAL_TEXT) { CopyUnicodeString(alarm->Text, Note.Entries[i].Text); } else if (Note.Entries[i].EntryType == CAL_ALARM_DATETIME) { alarm->DateTime = Note.Entries[i].Date; @@ -3141,17 +3144,17 @@ static GSM_Error ALCATEL_SetAlarm (GSM_StateMachine *s, GSM_Alarm *alarm) if (Priv->ReturnInt == 4 || Priv->ReturnInt == 5) { alarm_number--; if (alarm_number == 0) { Found = true; break; } } } - + if (Found) { Note.Location = Priv->CalendarItems[i]; } Note.EntriesNum = 1; Note.Entries[0].EntryType = CAL_ALARM_DATETIME; Note.Entries[0].Date = alarm->DateTime; @@ -3179,19 +3182,19 @@ static GSM_Error ALCATEL_SetAlarm (GSM_StateMachine *s, GSM_Alarm *alarm) } } static GSM_Error ALCATEL_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; - + status->Used = 0; - + if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, true))!= ERR_NONE) return error; status->Used = Priv->ToDoItemsCount; return ERR_NONE; } static GSM_Error ALCATEL_GetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) @@ -3446,17 +3449,17 @@ static GSM_Error ALCATEL_GetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) static GSM_Error ALCATEL_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start) { GSM_Error error; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if (Priv->ToDoItemsCount == 0) return ERR_EMPTY; - + if (start) ToDo->Location = 0; if ((error = ALCATEL_GetNextId(s, &(ToDo->Location))) != ERR_NONE) return error; return ALCATEL_GetToDo(s, ToDo); } static GSM_Error ALCATEL_DeleteAllToDo (GSM_StateMachine *s) { @@ -3485,17 +3488,17 @@ static GSM_Error ALCATEL_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) unsigned int val; bool contact_set = false; bool phone_set = false; int i; GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL; if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error; if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeToDo, 0))!= ERR_NONE) return error; - + switch (ToDo->Priority) { case GSM_Priority_High: val = 0; break; case GSM_Priority_Low: val = 2; break; case GSM_Priority_Medium: @@ -3513,17 +3516,17 @@ static GSM_Error ALCATEL_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) for (i = 0; i < ToDo->EntriesNum; i++) { switch (ToDo->Entries[i].EntryType) { case TODO_END_DATETIME: if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; break; case TODO_COMPLETED: if ((error = ALCATEL_CreateField(s, Alcatel_bool, 1, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; break; - case TODO_ALARM_DATETIME: + case TODO_ALARM_DATETIME: if ((error = ALCATEL_CreateField(s, Alcatel_date, 2, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_time, 3, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_date, 10, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; if ((error = ALCATEL_CreateField(s, Alcatel_time, 11, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; break; case TODO_TEXT: if ((error = ALCATEL_CreateField(s, Alcatel_string, 4, ToDo->Entries[i].Text)) != ERR_NONE) return error; break; @@ -3574,19 +3577,19 @@ static GSM_Error ALCATEL_SetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) /* Save modified ToDo */ if ((error = ALCATEL_GetAvailableIds(s, false))!= ERR_NONE) return error; if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= ERR_NONE) { /* Entry doesn't exist, we will create new one */ return ALCATEL_AddToDo(s, ToDo); } /* Get fields for current item */ if ((error = ALCATEL_GetFields(s, ToDo->Location))!= ERR_NONE) return error; - + for (i = 0; i < 12; i++) { UpdatedFields[i] = false; } - + if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeToDo, ToDo->Location))!= ERR_NONE) return error; switch (ToDo->Priority) { case GSM_Priority_High: val = 0; break; case GSM_Priority_Low: val = 2; @@ -3603,52 +3606,52 @@ static GSM_Error ALCATEL_SetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo) if ((error = ALCATEL_UpdateField(s, Alcatel_enum, ToDo->Location, 7, &val)) != ERR_NONE) return error; } UpdatedFields[7] = true; for (i = 0; i < ToDo->EntriesNum; i++) { switch (ToDo->Entries[i].EntryType) { case TODO_END_DATETIME: if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 0, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; - UpdatedFields[0] = true; + UpdatedFields[0] = true; break; case TODO_COMPLETED: if ((error = ALCATEL_UpdateField(s, Alcatel_bool, ToDo->Location, 1, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; - UpdatedFields[1] = true; + UpdatedFields[1] = true; break; - case TODO_ALARM_DATETIME: + case TODO_ALARM_DATETIME: if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 2, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; - UpdatedFields[2] = true; + UpdatedFields[2] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 3, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; - UpdatedFields[3] = true; + UpdatedFields[3] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 10, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; - UpdatedFields[10] = true; + UpdatedFields[10] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 11, &(ToDo->Entries[i].Date))) != ERR_NONE) return error; - UpdatedFields[11] = true; + UpdatedFields[11] = true; break; case TODO_TEXT: if ((error = ALCATEL_UpdateField(s, Alcatel_string, ToDo->Location, 4, ToDo->Entries[i].Text)) != ERR_NONE) return error; - UpdatedFields[4] = true; + UpdatedFields[4] = true; break; case TODO_PRIVATE: if ((error = ALCATEL_UpdateField(s, Alcatel_bool, ToDo->Location, 5, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; - UpdatedFields[5] = true; + UpdatedFields[5] = true; break; case TODO_CATEGORY: if ((error = ALCATEL_UpdateField(s, Alcatel_byte, ToDo->Location, 6, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; - UpdatedFields[6] = true; + UpdatedFields[6] = true; break; case TODO_CONTACTID: if ((error = ALCATEL_UpdateField(s, Alcatel_int, ToDo->Location, 8, &(ToDo->Entries[i].Number))) != ERR_NONE) return error; - UpdatedFields[8] = true; + UpdatedFields[8] = true; contact_set = true; break; case TODO_PHONE: if ((error = ALCATEL_UpdateField(s, Alcatel_phone, ToDo->Location, 9, ToDo->Entries[i].Text)) != ERR_NONE) return error; - UpdatedFields[9] = true; + UpdatedFields[9] = true; phone_set = true; break; default: break; } } if (!contact_set) { if (phone_set) { @@ -3817,16 +3820,24 @@ static GSM_Error ALCATEL_SetIncomingCB (GSM_StateMachine *s, bool enable) static GSM_Error ALCATEL_SetIncomingSMS (GSM_StateMachine *s, bool enable) { GSM_Error error; if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; return ATGEN_SetIncomingSMS(s, enable); } +static GSM_Error ALCATEL_SetFastSMSSending(GSM_StateMachine *s, bool enable) +{ + GSM_Error error; + + if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error; + return ATGEN_SetFastSMSSending(s, enable); +} + static GSM_Reply_Function ALCATELReplyFunctions[] = { {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelAttach }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDetach }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelCommit }, {ALCATEL_ReplyCommit, "\x02",0x00,0x00, ID_AlcatelCommit2 }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelEnd }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelClose }, {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelStart }, @@ -3908,16 +3919,17 @@ GSM_Phone_Functions ALCATELPhone = { ALCATEL_GetSMSStatus, ALCATEL_GetSMS, ALCATEL_GetNextSMS, NOTSUPPORTED, /* SetSMS */ ALCATEL_AddSMS, ALCATEL_DeleteSMS, ALCATEL_SendSMS, ALCATEL_SendSavedSMS, + ALCATEL_SetFastSMSSending, ALCATEL_SetIncomingSMS, ALCATEL_SetIncomingCB, ALCATEL_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ ALCATEL_DialVoice, ALCATEL_AnswerCall, ALCATEL_CancelCall, @@ -3962,17 +3974,17 @@ GSM_Phone_Functions ALCATELPhone = { ALCATEL_GetCalendar, ALCATEL_GetNextCalendar, ALCATEL_SetCalendar, ALCATEL_AddCalendar, ALCATEL_DeleteCalendar, ALCATEL_DeleteAllCalendar, NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFilePart */ diff --git a/gammu/emb/common/phone/at/atgen.c b/gammu/emb/common/phone/at/atgen.c index 1834f15..ba23eb2 100644 --- a/gammu/emb/common/phone/at/atgen.c +++ b/gammu/emb/common/phone/at/atgen.c @@ -7,47 +7,27 @@ #include <string.h> #include <time.h> #include <ctype.h> #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" #include "../../service/sms/gsmsms.h" #include "../pfunc.h" + #include "atgen.h" +#include "samsung.h" +#include "siemens.h" +#include "sonyeric.h" + #ifdef GSM_ENABLE_ALCATEL -extern GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message msg, GSM_StateMachine *s); +GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message, GSM_StateMachine *); #endif -extern GSM_Error ATGEN_CMS35ReplyGetBitmap (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplySetBitmap (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplyGetRingtone (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplySetRingtone (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplyGetNextCal (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplySetCalendar (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_CMS35ReplyDeleteCalendar (GSM_Protocol_Message msg, GSM_StateMachine *s); -extern GSM_Error ATGEN_SL45ReplyGetMemory (GSM_Protocol_Message msg, GSM_StateMachine *s); - -extern GSM_Error ATGEN_GetRingtone (GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone); -extern GSM_Error ATGEN_SetRingtone (GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength); -extern GSM_Error ATGEN_GetBitmap (GSM_StateMachine *s, GSM_Bitmap *Bitmap); -extern GSM_Error ATGEN_SetBitmap (GSM_StateMachine *s, GSM_Bitmap *Bitmap); -extern GSM_Error SIEMENS_GetNextCalendar (GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start); -extern GSM_Error SIEMENS_AddCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note); -extern GSM_Error SIEMENS_DelCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note); - -extern GSM_Error SONYERIC_GetNextCalendar (GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start); -extern GSM_Error SONYERIC_GetNextToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start); -extern GSM_Error SONYERIC_GetToDoStatus (GSM_StateMachine *s, GSM_ToDoStatus *status); -extern GSM_Error SONYERIC_AddCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note); -extern GSM_Error SONYERIC_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo); -extern GSM_Error SONYERIC_DeleteAllToDo (GSM_StateMachine *s); -extern GSM_Error SONYERIC_DelCalendarNote (GSM_StateMachine *s, GSM_CalendarEntry *Note); -extern GSM_Error SONYERIC_GetCalendarStatus (GSM_StateMachine *s, GSM_CalendarStatus *Status); typedef struct { int Number; char Text[60]; } ATErrorCode; static ATErrorCode CMSErrorCodes[] = { /* @@ -170,16 +150,18 @@ GSM_Error ATGEN_HandleCMEError(GSM_StateMachine *s) smprintf(s, "CME Error occured, but it's type not detected\n"); } else if (Priv->ErrorText == NULL) { smprintf(s, "CME Error %i, no description available\n", Priv->ErrorCode); } else { smprintf(s, "CME Error %i: \"%s\"\n", Priv->ErrorCode, Priv->ErrorText); } /* For error codes descriptions see table a bit above */ switch (Priv->ErrorCode) { + case -1: + return ERR_EMPTY; case 3: return ERR_PERMISSION; case 4: return ERR_NOTSUPPORTED; case 5: case 11: case 12: case 16: @@ -251,18 +233,26 @@ int ATGEN_ExtractOneParameter(unsigned char *input, unsigned char *output) } *output=0; position++; return position; } void ATGEN_DecodeDateTime(GSM_DateTime *dt, unsigned char *input) { - dt->Year=2000+(*input-'0')*10; input++; + /* Samsung phones report year as %d instead of %02d */ + if (input[2] == '/') { + dt->Year=(*input-'0')*10; + input++; + } else { + dt->Year=0; + } + dt->Year=dt->Year+(*input-'0'); input++; + dt->Year+=2000; input++; dt->Month=(*input-'0')*10; input++; dt->Month=dt->Month+(*input-'0'); input++; input++; dt->Day=(*input-'0')*10; input++; dt->Day=dt->Day+(*input-'0'); input++; @@ -317,16 +307,28 @@ GSM_Error ATGEN_DispatchMessage(GSM_StateMachine *s) if (!strncmp(line,"+CME ERROR:",11)) { Priv->ReplyState = AT_Reply_CMEError; ErrorCodes = CMEErrorCodes; } if (!strncmp(line,"+CMS ERROR:",11)) { Priv->ReplyState = AT_Reply_CMSError; ErrorCodes = CMSErrorCodes; } + + /* FIXME: Samsung phones can answer +CME ERROR:-1 meaning empty location */ + if (Priv->ReplyState == AT_Reply_CMEError && Priv->Manufacturer == AT_Samsung) { + err = line + 11; + Priv->ErrorCode = atoi(err); + + if (Priv->ErrorCode == -1) { + Priv->ErrorText = "[Samsung] Empty location"; + return GSM_DispatchMessage(s); + } + } + if (Priv->ReplyState == AT_Reply_CMEError || Priv->ReplyState == AT_Reply_CMSError) { j = 0; /* One char behind +CM[SE] ERROR */ err = line + 12; while (err[j] && !isalnum(err[j])) j++; if (isdigit(err[j])) { Priv->ErrorCode = atoi(&(err[j])); k = 0; @@ -365,16 +367,52 @@ GSM_Error ATGEN_GenericReply(GSM_Protocol_Message msg, GSM_StateMachine *s) case AT_Reply_CMEError: return ATGEN_HandleCMEError(s); default: break; } return ERR_UNKNOWNRESPONSE; } +GSM_Error ATGEN_ReplyGetUSSD(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + unsigned char buffer[2000],buffer2[4000]; + int i = 10; + + /* Ugly hack */ + while (msg.Buffer[i]!=13) i++; + i = i - 6; + memcpy(buffer,msg.Buffer+10,i-11); + buffer[i-11] = 0x00; + + smprintf(s, "USSD reply: \"%s\"\n",buffer); + + if (s->Phone.Data.EnableIncomingUSSD && s->User.IncomingUSSD!=NULL) { + EncodeUnicode(buffer2,buffer,strlen(buffer)); + s->User.IncomingUSSD(s->CurrentConfig->Device, buffer2); + } + + return ERR_NONE; +} + +GSM_Error ATGEN_SetIncomingUSSD(GSM_StateMachine *s, bool enable) +{ + GSM_Error error; + + if (enable) { + smprintf(s, "Enabling incoming USSD\n"); + error=GSM_WaitFor (s, "AT+CUSD=1\r", 10, 0x00, 3, ID_SetUSSD); + } else { + smprintf(s, "Disabling incoming USSD\n"); + error=GSM_WaitFor (s, "AT+CUSD=0\r", 10, 0x00, 3, ID_SetUSSD); + } + if (error==ERR_NONE) s->Phone.Data.EnableIncomingUSSD = enable; + return error; +} + GSM_Error ATGEN_ReplyGetModel(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Phone_Data *Data = &s->Phone.Data; if (s->Phone.Data.Priv.ATGEN.ReplyState != AT_Reply_OK) return ERR_NOTSUPPORTED; if (strlen(GetLineString(msg.Buffer, Priv->Lines, 2)) <= MAX_MODEL_LENGTH) { @@ -389,20 +427,22 @@ GSM_Error ATGEN_ReplyGetModel(GSM_Protocol_Message msg, GSM_StateMachine *s) if (Data->ModelInfo->number[0] == 0) Data->ModelInfo = GetModelData(NULL,NULL,Data->Model); if (Data->ModelInfo->number[0] == 0) Data->ModelInfo = GetModelData(Data->Model,NULL,NULL); if (Data->ModelInfo->number[0] != 0) strcpy(Data->Model,Data->ModelInfo->number); if (strstr(msg.Buffer,"Nokia")) Priv->Manufacturer = AT_Nokia; else if (strstr(msg.Buffer,"M20")) Priv->Manufacturer = AT_Siemens; else if (strstr(msg.Buffer,"MC35")) Priv->Manufacturer = AT_Siemens; + else if (strstr(msg.Buffer,"TC35")) Priv->Manufacturer = AT_Siemens; else if (strstr(msg.Buffer, "iPAQ")) Priv->Manufacturer = AT_HP; if (strstr(msg.Buffer,"M20")) strcpy(Data->Model,"M20"); else if (strstr(msg.Buffer,"MC35")) strcpy(Data->Model,"MC35"); + else if (strstr(msg.Buffer,"TC35")) strcpy(Data->Model,"TC35"); else if (strstr(msg.Buffer, "iPAQ")) strcpy(Data->Model,"iPAQ"); } else { smprintf(s, "WARNING: Model name too long, increase MAX_MODEL_LENGTH to at least %zd\n", strlen(GetLineString(msg.Buffer, Priv->Lines, 2))); } return ERR_NONE; } @@ -476,16 +516,21 @@ GSM_Error ATGEN_ReplyGetManufacturer(GSM_Protocol_Message msg, GSM_StateMachine strcpy(s->Phone.Data.Manufacturer,"Alcatel"); Priv->Manufacturer = AT_Alcatel; } if (strstr(msg.Buffer,"SAGEM")) { smprintf(s, "Sagem\n"); strcpy(s->Phone.Data.Manufacturer,"Sagem"); Priv->Manufacturer = AT_Sagem; } + if (strstr(msg.Buffer,"Samsung")) { + smprintf(s, "Samsung\n"); + strcpy(s->Phone.Data.Manufacturer,"Samsung"); + Priv->Manufacturer = AT_Samsung; + } return ERR_NONE; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); default: break; } return ERR_UNKNOWNRESPONSE; } @@ -669,26 +714,36 @@ GSM_Error ATGEN_ReplyGetSMSMemories(GSM_Protocol_Message msg, GSM_StateMachine * * Example: ("SM"), ("SM"), ("SM") * * We need to get from this supported memories. For this case * we assume, that just appearence of memory makes it * available for everything. Then we need to find out whether * phone supports writing to memory. This is done by searching * for "), (", which will appear between lists. */ - s->Phone.Data.Priv.ATGEN.CanSaveSMS = (strstr(msg.Buffer, "), (") != NULL); + s->Phone.Data.Priv.ATGEN.CanSaveSMS = false; + if (strstr(msg.Buffer, "), (") != NULL || strstr(msg.Buffer, "),(") != NULL) { + s->Phone.Data.Priv.ATGEN.CanSaveSMS = true; + } + if (strstr(msg.Buffer, "\"SM\"") != NULL) s->Phone.Data.Priv.ATGEN.SIMSMSMemory = AT_AVAILABLE; else s->Phone.Data.Priv.ATGEN.SIMSMSMemory = AT_NOTAVAILABLE; + if (strstr(msg.Buffer, "\"ME\"") != NULL) s->Phone.Data.Priv.ATGEN.PhoneSMSMemory = AT_AVAILABLE; else s->Phone.Data.Priv.ATGEN.PhoneSMSMemory = AT_NOTAVAILABLE; - smprintf(s, "Available SMS memories received, ME = %d, SM = %d\n", s->Phone.Data.Priv.ATGEN.PhoneSMSMemory, s->Phone.Data.Priv.ATGEN.SIMSMSMemory); + + smprintf(s, "Available SMS memories received, ME = %d, SM = %d, cansavesms =", s->Phone.Data.Priv.ATGEN.PhoneSMSMemory, s->Phone.Data.Priv.ATGEN.SIMSMSMemory); + if (s->Phone.Data.Priv.ATGEN.CanSaveSMS) smprintf(s, "true"); + smprintf(s, "\n"); return ERR_NONE; case AT_Reply_Error: case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); + case AT_Reply_CMEError: + return ATGEN_HandleCMEError(s); default: return ERR_UNKNOWNRESPONSE; } } GSM_Error ATGEN_GetSMSMemories(GSM_StateMachine *s) { smprintf(s, "Getting available SMS memories\n"); @@ -853,18 +908,19 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s case '2': sms->State = SMS_UnSent; break; default : sms->State = SMS_Sent; break;//case '3' } DecodeHexBin (buffer, GetLineString(msg.Buffer,Priv->Lines,3), strlen(GetLineString(msg.Buffer,Priv->Lines,3))); /* Siemens MC35 (only ?) */ if (strstr(msg.Buffer,"+CMGR: 0,,0")!=NULL) return ERR_EMPTY; /* Siemens M20 */ if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) { - if (buffer[1]!=NUMBER_UNKNOWN && buffer[1]!=NUMBER_INTERNATIONAL && - buffer[1]!=NUMBER_ALPHANUMERIC) { + /* we check for the most often visible */ + if (buffer[1]!=NUMBER_UNKNOWN_NUMBERING_PLAN_ISDN && buffer[1]!=NUMBER_INTERNATIONAL_NUMBERING_PLAN_ISDN && + buffer[1]!=NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) { /* Seems to be Delivery Report */ smprintf(s, "SMS type - status report (M20 style)\n"); sms->PDU = SMS_Status_Report; sms->Folder = 1; /*INBOX SIM*/ sms->InboxFolder = true; smsframe[12]=buffer[current++]; smsframe[PHONE_SMSStatusReport.TPMR]=buffer[current++]; @@ -889,17 +945,17 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s if (Priv->SMSMemory == MEM_SM) { sms->Folder = 1; /*INBOX SIM*/ } else { sms->Folder = 3; /*INBOX ME*/ } sms->InboxFolder = true; current2=((buffer[current])+1)/2+1; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) { - if (buffer[current+1]==NUMBER_ALPHANUMERIC) { + if (buffer[current+1]==NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) { smprintf(s, "Trying to read alphanumeric number\n"); for(i=0;i<4;i++) smsframe[PHONE_SMSDeliver.Number+i]=buffer[current++]; current+=6; for(i=0;i<current2-3;i++) smsframe[PHONE_SMSDeliver.Number+i+4]=buffer[current++]; } else { for(i=0;i<current2+1;i++) smsframe[PHONE_SMSDeliver.Number+i]=buffer[current++]; } } else { @@ -920,17 +976,17 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s smprintf(s, "Outbox SIM\n"); } else { sms->Folder = 4; /*OUTBOX ME*/ } sms->InboxFolder = false; smsframe[PHONE_SMSSubmit.TPMR] = buffer[current++]; current2=((buffer[current])+1)/2+1; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_M20SMS)) { - if (buffer[current+1]==NUMBER_ALPHANUMERIC) { + if (buffer[current+1]==NUMBER_ALPHANUMERIC_NUMBERING_PLAN_UNKNOWN) { smprintf(s, "Trying to read alphanumeric number\n"); for(i=0;i<4;i++) smsframe[PHONE_SMSSubmit.Number+i]=buffer[current++]; current+=6; for(i=0;i<current2-3;i++) smsframe[PHONE_SMSSubmit.Number+i+4]=buffer[current++]; } else { for(i=0;i<current2+1;i++) smsframe[PHONE_SMSSubmit.Number+i]=buffer[current++]; } } else { @@ -944,17 +1000,17 @@ GSM_Error ATGEN_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s for(i=0;i<smsframe[PHONE_SMSSubmit.TPUDL];i++) smsframe[i+PHONE_SMSSubmit.Text]=buffer[current++]; GSM_DecodeSMSFrame(sms,smsframe,PHONE_SMSSubmit); return ERR_NONE; case 0x02: smprintf(s, "SMS type - status report\n"); sms->PDU = SMS_Status_Report; sms->Folder = 1; /*INBOX SIM*/ sms->InboxFolder = true; - smprintf(s, "TPMR is %02x\n",buffer[current]); + smprintf(s, "TPMR is %d\n",buffer[current]); smsframe[PHONE_SMSStatusReport.TPMR] = buffer[current++]; current2=((buffer[current])+1)/2+1; for(i=0;i<current2+1;i++) smsframe[PHONE_SMSStatusReport.Number+i]=buffer[current++]; for(i=0;i<7;i++) smsframe[PHONE_SMSStatusReport.DateTime+i]=buffer[current++]; for(i=0;i<7;i++) smsframe[PHONE_SMSStatusReport.SMSCTime+i]=buffer[current++]; smsframe[PHONE_SMSStatusReport.TPStatus]=buffer[current]; GSM_DecodeSMSFrame(sms,smsframe,PHONE_SMSStatusReport); return ERR_NONE; @@ -1635,27 +1691,27 @@ GSM_Error ATGEN_ReplySendSMS(GSM_Protocol_Message msg, GSM_StateMachine *s) s->Protocol.Data.AT.EditMode = false; return ERR_NONE; } switch (Priv->ReplyState) { case AT_Reply_OK: smprintf(s, "SMS sent OK\n"); if (s->User.SendSMSStatus!=NULL) { - start = strstr(msg.Buffer, "+CMGW: "); + start = strstr(msg.Buffer, "+CMGS: "); if (start != NULL) { s->User.SendSMSStatus(s->CurrentConfig->Device,0,atoi(start+7)); } else { - s->User.SendSMSStatus(s->CurrentConfig->Device,0,0); + s->User.SendSMSStatus(s->CurrentConfig->Device,0,-1); } } return ERR_NONE; case AT_Reply_CMSError: smprintf(s, "Error %i\n",Priv->ErrorCode); - if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,Priv->ErrorCode,0); + if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,Priv->ErrorCode,-1); return ATGEN_HandleCMSError(s); case AT_Reply_Error: return ERR_UNKNOWN; default: return ERR_UNKNOWNRESPONSE; } } @@ -1782,16 +1838,29 @@ GSM_Error ATGEN_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) alarm->Repeating = true; alarm->Text[0] = 0; alarm->Text[1] = 0; s->Phone.Data.Alarm = alarm; smprintf(s, "Getting alarm\n"); return GSM_WaitFor (s, "AT+CALA?\r", 9, 0x00, 4, ID_GetAlarm); } +/* R320 only takes HH:MM. Do other phones understand full date? */ +GSM_Error ATGEN_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm) +{ + char req[20]; + + if (alarm->Location != 1) return ERR_INVALIDLOCATION; + + sprintf(req, "AT+CALA=\"%02i:%02i\"\r",alarm->DateTime.Hour,alarm->DateTime.Minute); + + smprintf(s, "Setting Alarm\n"); + return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetAlarm); +} + GSM_Error ATGEN_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_SMSC *SMSC = s->Phone.Data.SMSC; int current; int len; unsigned char buffer[100]; switch (s->Phone.Data.Priv.ATGEN.ReplyState) { @@ -2197,16 +2266,18 @@ GSM_Error ATGEN_GetMemoryInfo(GSM_StateMachine *s, GSM_MemoryStatus *Status, GSM smprintf(s, "Getting memory information\n"); Priv->MemorySize = 0; Priv->TextLength = 0; Priv->NumberLength = 0; error = GSM_WaitFor (s, "AT+CPBR=?\r", 10, 0x00, 4, ID_GetMemoryStatus); + if (Priv->Manufacturer == AT_Samsung) + error = GSM_WaitFor (s, "", 0, 0x00, 4, ID_GetMemoryStatus); if (error != ERR_NONE) return error; if (NeededInfo == AT_Total || NeededInfo == AT_Sizes || NeededInfo == AT_First) return ERR_NONE; smprintf(s, "Getting memory status by reading values\n"); s->Phone.Data.MemoryStatus = Status; Status->MemoryUsed = 0; Status->MemoryFree = 0; @@ -2263,16 +2334,22 @@ GSM_Error ATGEN_SetPBKCharset(GSM_StateMachine *s, bool PreferUnicode) /* If we don't need unicode charset and we have some (or have unicode * charset when other failed), we have nothing to do. */ if (!PreferUnicode && (Priv->PBKCharset!=AT_PBK_UCS2 || Priv->NonUCS2CharsetFailed)) return ERR_NONE; } error=ATGEN_GetManufacturer(s); if (error != ERR_NONE) return error; + /* Samsung (and Sagem?) phones use only PCCP437? */ + if (Priv->Manufacturer == AT_Samsung) { + Priv->PBKCharset = AT_PBK_PCCP437; + return ERR_NONE; + } + if (PreferUnicode && !Priv->UCS2CharsetFailed) { smprintf(s, "Setting charset to UCS2\n"); error=GSM_WaitFor (s, "AT+CSCS=\"UCS2\"\r", 15, 0x00, 3, ID_SetMemoryCharset); if (error == ERR_NONE) { Priv->PBKCharset = AT_PBK_UCS2; return ERR_NONE; } else { Priv->UCS2CharsetFailed = true; @@ -2380,17 +2457,47 @@ GSM_Error ATGEN_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) DecodeDefault(Memory->Entries[1].Text,buffer2,strlen(buffer2),false,NULL); break; case AT_PBK_GSM: DecodeDefault(Memory->Entries[1].Text,buffer+1,strlen(buffer)-2,false,NULL); break; case AT_PBK_UCS2: DecodeHexUnicode(Memory->Entries[1].Text,buffer+1,strlen(buffer+1) - 1); break; + case AT_PBK_PCCP437: + /* FIXME: correctly decode PCCP437 */ + DecodeDefault(Memory->Entries[1].Text,buffer+1,strlen(buffer)-2,false,NULL); + break; + } + + /* Samsung number type */ + if (Priv->Manufacturer == AT_Samsung) { + int type; + + pos += ATGEN_ExtractOneParameter(pos, buffer); + smprintf(s, "Number type: %s\n",buffer); + type = strtoul(buffer, NULL, 0); + switch (type) { + case 0: + Memory->Entries[0].EntryType = PBK_Number_Mobile; + break; + case 1: + Memory->Entries[0].EntryType = PBK_Number_Work; + break; + case 2: + Memory->Entries[0].EntryType = PBK_Number_Home; + break; + case 3: + Memory->Entries[0].EntryType = PBK_Text_Email; + break; + default: + Memory->Entries[0].EntryType = PBK_Number_General; + } } + return ERR_NONE; case AT_Reply_CMEError: return ATGEN_HandleCMEError(s); case AT_Reply_Error: smprintf(s, "Error - too high location ?\n"); return ERR_INVALIDLOCATION; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); @@ -2557,16 +2664,18 @@ GSM_Error ATGEN_ReplyEnterSecurityCode(GSM_Protocol_Message msg, GSM_StateMachin case AT_Reply_OK: smprintf(s, "Security code was OK\n"); return ERR_NONE; case AT_Reply_Error: smprintf(s, "Incorrect security code\n"); return ERR_SECURITYERROR; case AT_Reply_CMSError: return ATGEN_HandleCMSError(s); + case AT_Reply_CMEError: + return ATGEN_HandleCMEError(s); default: break; } return ERR_UNKNOWNRESPONSE; } GSM_Error ATGEN_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode Code) { @@ -2919,16 +3028,22 @@ GSM_Error ATGEN_PrivSetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry) smprintf(s, "str: %s\n", DecodeUnicodeString(entry->Entries[Name].Text)); len = UnicodeLength(entry->Entries[Name].Text); EncodeDefault(name, entry->Entries[Name].Text, &len, true, NULL); break; case AT_PBK_UCS2: EncodeHexUnicode(name, entry->Entries[Name].Text, UnicodeLength(entry->Entries[Name].Text)); len = strlen(name); break; + case AT_PBK_PCCP437: + /* FIXME: correctly decode PCCP437 */ + smprintf(s, "str: %s\n", DecodeUnicodeString(entry->Entries[Name].Text)); + len = UnicodeLength(entry->Entries[Name].Text); + EncodeDefault(name, entry->Entries[Name].Text, &len, true, NULL); + break; } } else { smprintf(s, "WARNING: No usable name found!\n"); len = 0; } if (Number != -1) { GSM_PackSemiOctetNumber(entry->Entries[Number].Text, number, false); @@ -3247,16 +3362,53 @@ GSM_Error ATGEN_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer==AT_Siemens) return SIEMENS_DelCalendarNote(s, Note); if (Priv->Manufacturer==AT_Ericsson) return SONYERIC_DelCalendarNote(s, Note); return ERR_NOTSUPPORTED; } + +GSM_Error ATGEN_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + + if (Priv->Manufacturer==AT_Siemens) return SIEMENS_GetBitmap(s, Bitmap); + if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_GetBitmap(s, Bitmap); + return ERR_NOTSUPPORTED; +} + +GSM_Error ATGEN_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + + if (Priv->Manufacturer==AT_Siemens) return SIEMENS_SetBitmap(s, Bitmap); + if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_SetBitmap(s, Bitmap); + return ERR_NOTSUPPORTED; +} + +GSM_Error ATGEN_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + + if (Priv->Manufacturer==AT_Siemens) return SIEMENS_GetRingtone(s, Ringtone, PhoneRingtone); + if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_GetRingtone(s, Ringtone, PhoneRingtone); + return ERR_NOTSUPPORTED; +} + +GSM_Error ATGEN_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + + if (Priv->Manufacturer==AT_Siemens) return SIEMENS_SetRingtone(s, Ringtone, maxlength); + if (Priv->Manufacturer==AT_Samsung) return SAMSUNG_SetRingtone(s, Ringtone, maxlength); + return ERR_NOTSUPPORTED; +} + GSM_Error ATGEN_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press) { GSM_Error error; unsigned char Frame[] = "AT+CKPD=\"?\"\r"; if (Press) { switch (Key) { case GSM_KEY_1 : Frame[9] = '1'; break; @@ -3341,16 +3493,27 @@ GSM_Error ATGEN_SetIncomingCB(GSM_StateMachine *s, bool enable) } } return ERR_NONE; #else return ERR_SOURCENOTAVAILABLE; #endif } +GSM_Error ATGEN_SetFastSMSSending(GSM_StateMachine *s, bool enable) +{ + if (enable) { + smprintf(s, "Enabling fast SMS sending\n"); + return GSM_WaitFor(s, "AT+CMMS=2\r", 10, 0x00, 4, ID_SetFastSMSSending); + } else { + smprintf(s, "Disabling fast SMS sending\n"); + return GSM_WaitFor(s, "AT+CMMS=0\r", 10, 0x00, 4, ID_SetFastSMSSending); + } +} + GSM_Error ATGEN_IncomingSMSInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Incoming SMS\n"); return ERR_NONE; } GSM_Error ATGEN_IncomingSMSDeliver(GSM_Protocol_Message msg, GSM_StateMachine *s) { @@ -3419,24 +3582,41 @@ GSM_Error ATGEN_SetIncomingSMS(GSM_StateMachine *s, bool enable) } else { smprintf(s, "Disabling incoming SMS\n"); return GSM_WaitFor(s, "AT+CNMI=3,0\r", 12, 0x00, 4, ID_SetIncomingSMS); } } return ERR_NONE; } +GSM_Error ATGEN_GetLocale(GSM_StateMachine *s, GSM_Locale *locale) +{ + if (s->Phone.Data.Priv.ATGEN.Manufacturer==AT_Ericsson) return ERICSSON_GetLocale(s,locale); + return ERR_NOTSUPPORTED; +} + +GSM_Error ATGEN_SetLocale(GSM_StateMachine *s, GSM_Locale *locale) +{ + if (s->Phone.Data.Priv.ATGEN.Manufacturer==AT_Ericsson) return ERICSSON_SetLocale(s,locale); + return ERR_NOTSUPPORTED; +} + GSM_Reply_Function ATGENReplyFunctions[] = { {ATGEN_GenericReply, "AT\r" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "ATE1" ,0x00,0x00,ID_EnableEcho }, {ATGEN_GenericReply, "AT+CMEE=" ,0x00,0x00,ID_EnableErrorInfo }, {ATGEN_GenericReply, "AT+CKPD=" ,0x00,0x00,ID_PressKey }, {ATGEN_ReplyGetSIMIMSI, "AT+CIMI" ,0x00,0x00,ID_GetSIMIMSI }, {ATGEN_GenericReply, "AT*EOBEX" ,0x00,0x00,ID_SetOBEX }, +{ERICSSON_ReplyGetDateLocale, "*ESDF:" ,0x00,0x00,ID_GetLocale }, +{ERICSSON_ReplyGetTimeLocale, "*ESTF:" ,0x00,0x00,ID_GetLocale }, +{ATGEN_GenericReply, "AT*ESDF=" ,0x00,0x00,ID_SetLocale }, +{ATGEN_GenericReply, "AT*ESTF=" ,0x00,0x00,ID_SetLocale }, + #ifdef GSM_ENABLE_CELLBROADCAST {ATGEN_ReplyIncomingCB, "+CBM:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "AT+CNMI" ,0x00,0x00,ID_SetIncomingCB }, #endif {ATGEN_IncomingBattery, "_OBS:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetBatteryCharge, "AT+CBC" ,0x00,0x00,ID_GetBatteryCharge }, @@ -3457,75 +3637,87 @@ GSM_Reply_Function ATGENReplyFunctions[] = { {ATGEN_ReplyGetSMSMemories, "AT+CPMS=?" ,0x00,0x00,ID_GetSMSMemories }, {ATGEN_ReplyAddSMSMessage, "AT+CMGW" ,0x00,0x00,ID_SaveSMSMessage }, {ATGEN_GenericReply, "AT+CSMP" ,0x00,0x00,ID_SetSMSParameters }, {ATGEN_GenericReply, "AT+CSCA" ,0x00,0x00,ID_SetSMSC }, {ATGEN_ReplyGetSMSC, "AT+CSCA?" ,0x00,0x00,ID_GetSMSC }, {ATGEN_ReplyDeleteSMSMessage, "AT+CMGD" ,0x00,0x00,ID_DeleteSMSMessage }, {ATGEN_GenericReply, "ATE1" ,0x00,0x00,ID_SetSMSParameters }, {ATGEN_GenericReply, "\x1b\x0D" ,0x00,0x00,ID_SetSMSParameters }, +{ATGEN_GenericReply, "AT+CMMS" ,0x00,0x00,ID_SetFastSMSSending }, {ATGEN_IncomingSMSInfo, "+CMTI:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingSMSDeliver, "+CMT:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingSMSReport, "+CDS:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingSMSCInfo, "^SCN:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetDateTime_Alarm, "AT+CCLK?" ,0x00,0x00,ID_GetDateTime }, {ATGEN_GenericReply, "AT+CCLK=" ,0x00,0x00,ID_SetDateTime }, +{ATGEN_GenericReply, "AT+CALA=" ,0x00,0x00,ID_SetAlarm }, {ATGEN_ReplyGetDateTime_Alarm, "AT+CALA?" ,0x00,0x00,ID_GetAlarm }, {ATGEN_ReplyGetNetworkLAC_CID, "AT+CREG?" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_GenericReply, "AT+CREG=2" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_GenericReply, "AT+COPS=" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_GenericReply, "AT+COPS=" ,0x00,0x00,ID_SetAutoNetworkLogin}, {ATGEN_ReplyGetNetworkCode, "AT+COPS" ,0x00,0x00,ID_GetNetworkInfo }, {ATGEN_ReplyGetSignalQuality, "AT+CSQ" ,0x00,0x00,ID_GetSignalQuality }, {ATGEN_IncomingNetworkLevel, "_OSIGQ:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_IncomingGPRS, "+CGREG:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetNetworkLAC_CID, "+CREG:" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyGetPBKMemories, "AT+CPBS=?" ,0x00,0x00,ID_SetMemoryType }, {ATGEN_GenericReply, "AT+CPBS=" ,0x00,0x00,ID_SetMemoryType }, {ATGEN_ReplyGetCPBSMemoryStatus,"AT+CPBS?" ,0x00,0x00,ID_GetMemoryStatus }, +// /* Samsung phones reply +CPBR: after OK --claudio*/ {ATGEN_ReplyGetCPBRMemoryInfo, "AT+CPBR=?" ,0x00,0x00,ID_GetMemoryStatus }, +{ATGEN_ReplyGetCPBRMemoryInfo, "+CPBR:" ,0x00,0x00,ID_GetMemoryStatus }, {ATGEN_ReplyGetCPBRMemoryStatus,"AT+CPBR=" ,0x00,0x00,ID_GetMemoryStatus }, {ATGEN_GenericReply, "AT+CSCS=" ,0x00,0x00,ID_SetMemoryCharset }, {ATGEN_ReplyGetMemory, "AT+CPBR=" ,0x00,0x00,ID_GetMemory }, {ATGEN_GenericReply, "AT^SBNR=?" ,0x00,0x00,ID_GetMemory }, -{ATGEN_SL45ReplyGetMemory, "AT^SBNR" ,0x00,0x00,ID_GetMemory }, +{SIEMENS_ReplyGetMemory, "AT^SBNR" ,0x00,0x00,ID_GetMemory }, {ATGEN_ReplySetMemory, "AT+CPBW" ,0x00,0x00,ID_SetMemory }, -{ATGEN_CMS35ReplyGetBitmap, "AT^SBNR=\"bmp\"" ,0x00,0x00,ID_GetBitmap }, -{ATGEN_CMS35ReplySetBitmap, "AT^SBNW=\"bmp\"" ,0x00,0x00,ID_SetBitmap }, +{SIEMENS_ReplyGetBitmap, "AT^SBNR=\"bmp\"" ,0x00,0x00,ID_GetBitmap }, +{SIEMENS_ReplySetBitmap, "AT^SBNW=\"bmp\"" ,0x00,0x00,ID_SetBitmap }, -{ATGEN_CMS35ReplyGetRingtone, "AT^SBNR=\"mid\"" ,0x00,0x00,ID_GetRingtone }, -{ATGEN_CMS35ReplySetRingtone, "AT^SBNW=\"mid\"" ,0x00,0x00,ID_SetRingtone }, +{SIEMENS_ReplyGetRingtone, "AT^SBNR=\"mid\"" ,0x00,0x00,ID_GetRingtone }, +{SIEMENS_ReplySetRingtone, "AT^SBNW=\"mid\"" ,0x00,0x00,ID_SetRingtone }, -{ATGEN_CMS35ReplyGetNextCal, "AT^SBNR=\"vcs\"" ,0x00,0x00,ID_GetCalendarNote }, -{ATGEN_CMS35ReplySetCalendar, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_SetCalendarNote }, -{ATGEN_CMS35ReplyDeleteCalendar,"AT^SBNW=\"vcs\"" ,0x00,0x00,ID_DeleteCalendarNote }, +{SIEMENS_ReplyGetNextCalendar, "AT^SBNR=\"vcs\"" ,0x00,0x00,ID_GetCalendarNote }, +{SIEMENS_ReplyAddCalendarNote, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_SetCalendarNote }, +{SIEMENS_ReplyDelCalendarNote, "AT^SBNW=\"vcs\"" ,0x00,0x00,ID_DeleteCalendarNote }, {ATGEN_ReplyEnterSecurityCode, "AT+CPIN=" ,0x00,0x00,ID_EnterSecurityCode }, {ATGEN_ReplyEnterSecurityCode, "AT+CPIN2=" ,0x00,0x00,ID_EnterSecurityCode }, {ATGEN_ReplyGetSecurityStatus, "AT+CPIN?" ,0x00,0x00,ID_GetSecurityStatus }, {ATGEN_ReplyOK, "OK" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "AT+VTS" ,0x00,0x00,ID_SendDTMF }, {ATGEN_ReplyCancelCall, "AT+CHUP" ,0x00,0x00,ID_CancelCall }, {ATGEN_ReplyDialVoice, "ATDT" ,0x00,0x00,ID_DialVoice }, {ATGEN_ReplyCancelCall, "ATH" ,0x00,0x00,ID_CancelCall }, +{ATGEN_GenericReply, "AT+CUSD" ,0x00,0x00,ID_SetUSSD }, +{ATGEN_ReplyGetUSSD, "+CUSD" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_GenericReply, "AT+CLIP=1" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "+CLIP" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "+COLP" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "RING" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyIncomingCallInfo, "NO CARRIER" ,0x00,0x00,ID_IncomingFrame }, {ATGEN_ReplyReset, "AT^SRESET" ,0x00,0x00,ID_Reset }, {ATGEN_ReplyReset, "AT+CFUN=1,1" ,0x00,0x00,ID_Reset }, {ATGEN_ReplyResetPhoneSettings, "AT&F" ,0x00,0x00,ID_ResetPhoneSettings }, +{SAMSUNG_ReplyGetBitmap, "AT+IMGR=" ,0x00,0x00,ID_GetBitmap }, +{SAMSUNG_ReplySetBitmap, "SDNDCRC =" ,0x00,0x00,ID_SetBitmap }, + +{SAMSUNG_ReplyGetRingtone, "AT+MELR=" ,0x00,0x00,ID_GetRingtone }, +{SAMSUNG_ReplySetRingtone, "SDNDCRC =" ,0x00,0x00,ID_SetRingtone }, + #ifdef GSM_ENABLE_ALCATEL /* Why do I give Alcatel specific things here? It's simple, Alcatel needs * some AT commands to start it's binary mode, so this needs to be in AT * related stuff. * * XXX: AT+IFC could later move outside this ifdef, because it is not Alcatel * specific and it's part of ETSI specifications */ @@ -3533,17 +3725,17 @@ GSM_Reply_Function ATGENReplyFunctions[] = { {ALCATEL_ProtocolVersionReply, "AT+CPROT=?" ,0x00,0x00,ID_AlcatelProtocol }, {ATGEN_GenericReply, "AT+CPROT" ,0x00,0x00,ID_AlcatelConnect }, #endif {NULL, "\x00" ,0x00,0x00,ID_None } }; GSM_Phone_Functions ATGENPhone = { - "A2D|iPAQ|at|M20|S25|MC35|C35i|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", + "A2D|iPAQ|at|M20|S25|MC35|TC35|C35i|S300|5110|5130|5190|5210|6110|6130|6150|6190|6210|6250|6310|6310i|6510|7110|8210|8250|8290|8310|8390|8850|8855|8890|8910|9110|9210", ATGENReplyFunctions, ATGEN_Initialise, ATGEN_Terminate, ATGEN_DispatchMessage, NOTSUPPORTED, /* ShowStartInfo */ ATGEN_GetManufacturer, ATGEN_GetModel, ATGEN_GetFirmware, @@ -3552,19 +3744,19 @@ GSM_Phone_Functions ATGENPhone = { NOTSUPPORTED, /* GetManufactureMonth */ NOTSUPPORTED, /* GetProductCode */ NOTSUPPORTED, /* GetHardware */ NOTSUPPORTED, /* GetPPM */ ATGEN_GetSIMIMSI, ATGEN_GetDateTime, ATGEN_SetDateTime, ATGEN_GetAlarm, - NOTIMPLEMENTED, /* SetAlarm */ - NOTSUPPORTED, /* GetLocale */ - NOTSUPPORTED, /* SetLocale */ + ATGEN_SetAlarm, + ATGEN_GetLocale, + ATGEN_SetLocale, ATGEN_PressKey, ATGEN_Reset, ATGEN_ResetPhoneSettings, ATGEN_EnterSecurityCode, ATGEN_GetSecurityStatus, ATGEN_GetDisplayStatus, ATGEN_SetAutoNetworkLogin, ATGEN_GetBatteryCharge, @@ -3587,16 +3779,17 @@ GSM_Phone_Functions ATGENPhone = { ATGEN_GetSMSStatus, ATGEN_GetSMS, ATGEN_GetNextSMS, NOTSUPPORTED, /* SetSMS */ ATGEN_AddSMS, ATGEN_DeleteSMS, ATGEN_SendSMS, ATGEN_SendSavedSMS, + ATGEN_SetFastSMSSending, ATGEN_SetIncomingSMS, ATGEN_SetIncomingCB, ATGEN_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ ATGEN_DialVoice, ATGEN_AnswerCall, ATGEN_CancelCall, @@ -3605,17 +3798,17 @@ GSM_Phone_Functions ATGENPhone = { NOTSUPPORTED, /* ConferenceCall */ NOTSUPPORTED, /* SplitCall */ NOTSUPPORTED, /* TransferCall */ NOTSUPPORTED, /* SwitchCall */ NOTSUPPORTED, /* GetCallDivert */ NOTSUPPORTED, /* SetCallDivert */ NOTSUPPORTED, /* CancelAllDiverts */ NONEFUNCTION, /* SetIncomingCall */ - NOTSUPPORTED, /* SetIncomingUSSD */ + ATGEN_SetIncomingUSSD, ATGEN_SendDTMF, ATGEN_GetRingtone, ATGEN_SetRingtone, NOTSUPPORTED, /* GetRingtonesInfo */ NOTSUPPORTED, /* DeleteUserRingtones */ NOTSUPPORTED, /* PlayTone */ NOTSUPPORTED, /* GetWAPBookmark */ NOTSUPPORTED, /* SetWAPBookmark */ @@ -3641,17 +3834,17 @@ GSM_Phone_Functions ATGENPhone = { NOTIMPLEMENTED, /* GetCalendar */ ATGEN_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ ATGEN_AddCalendarNote, ATGEN_DelCalendarNote, NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ diff --git a/gammu/emb/common/phone/at/atgen.h b/gammu/emb/common/phone/at/atgen.h index 0e08ee4..bb5c559 100644 --- a/gammu/emb/common/phone/at/atgen.h +++ b/gammu/emb/common/phone/at/atgen.h @@ -37,23 +37,25 @@ typedef enum { typedef enum { AT_Nokia = 1, AT_Alcatel, AT_Siemens, AT_HP, AT_Falcom, AT_Ericsson, AT_Sagem, + AT_Samsung, AT_Unknown } GSM_AT_Manufacturer; typedef enum { AT_PBK_HEX = 1, AT_PBK_GSM, - AT_PBK_UCS2 + AT_PBK_UCS2, + AT_PBK_PCCP437 } GSM_AT_PBK_Charset; typedef enum { AT_AVAILABLE = 1, AT_NOTAVAILABLE } GSM_AT_SMSMemory; typedef enum { @@ -98,13 +100,17 @@ typedef struct { GSM_AT_SMSMemory SIMSMSMemory; /* Is SIM SMS memory available ? */ GSM_MemoryType SMSMemory; /* Last read SMS memory */ GSM_AT_SMS_Modes SMSMode; /* PDU or TEXT mode for SMS ? */ bool OBEX; GSM_File file; } GSM_Phone_ATGENData; +GSM_Error ATGEN_HandleCMSError (GSM_StateMachine *); +GSM_Error ATGEN_HandleCMEError (GSM_StateMachine *); +GSM_Error ATGEN_DispatchMessage (GSM_StateMachine *); + #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/at/samsung.c b/gammu/emb/common/phone/at/samsung.c new file mode 100644 index 0000000..55a42e5 --- a/dev/null +++ b/gammu/emb/common/phone/at/samsung.c @@ -0,0 +1,447 @@ +/* Samsung-specific functions + * Copyright (C) 2004 Claudio Matsuoka <cmatsuoka@gmail.com> + * Tested with S300 only! + */ + +#include "../../gsmstate.h" + +#ifdef GSM_ENABLE_ATGEN + +#include <string.h> +#include <time.h> +#include <ctype.h> + +#include "../../misc/coding/coding.h" +#include "../../gsmcomon.h" +#include "../../service/sms/gsmsms.h" +#include "../pfunc.h" + +#include "atgen.h" +#include "samsung.h" + +/* Binary frame size */ +#define BLKSZ 1024 + +struct ModelRes { + char *model; + int width; + int height; +}; + +static struct ModelRes modres[] = { + { "S100", 128, 128 }, + { "S200", 128, 113 }, + { "S300", 128, 97 }, + { "S500", 128, 128 }, + { "T100", 128, 128 }, + { "E700", 128, 128 }, + { NULL, 0, 0 } +}; + +/* + * CRC functions from the Granch SBNI12 Linux driver by + * Denis I. Timofeev <timofeev@granch.ru> + */ +static unsigned int crc32tab[] = { + 0xD202EF8D, 0xA505DF1B, 0x3C0C8EA1, 0x4B0BBE37, + 0xD56F2B94, 0xA2681B02, 0x3B614AB8, 0x4C667A2E, + 0xDCD967BF, 0xABDE5729, 0x32D70693, 0x45D03605, + 0xDBB4A3A6, 0xACB39330, 0x35BAC28A, 0x42BDF21C, + 0xCFB5FFE9, 0xB8B2CF7F, 0x21BB9EC5, 0x56BCAE53, + 0xC8D83BF0, 0xBFDF0B66, 0x26D65ADC, 0x51D16A4A, + 0xC16E77DB, 0xB669474D, 0x2F6016F7, 0x58672661, + 0xC603B3C2, 0xB1048354, 0x280DD2EE, 0x5F0AE278, + 0xE96CCF45, 0x9E6BFFD3, 0x0762AE69, 0x70659EFF, + 0xEE010B5C, 0x99063BCA, 0x000F6A70, 0x77085AE6, + 0xE7B74777, 0x90B077E1, 0x09B9265B, 0x7EBE16CD, + 0xE0DA836E, 0x97DDB3F8, 0x0ED4E242, 0x79D3D2D4, + 0xF4DBDF21, 0x83DCEFB7, 0x1AD5BE0D, 0x6DD28E9B, + 0xF3B61B38, 0x84B12BAE, 0x1DB87A14, 0x6ABF4A82, + 0xFA005713, 0x8D076785, 0x140E363F, 0x630906A9, + 0xFD6D930A, 0x8A6AA39C, 0x1363F226, 0x6464C2B0, + 0xA4DEAE1D, 0xD3D99E8B, 0x4AD0CF31, 0x3DD7FFA7, + 0xA3B36A04, 0xD4B45A92, 0x4DBD0B28, 0x3ABA3BBE, + 0xAA05262F, 0xDD0216B9, 0x440B4703, 0x330C7795, + 0xAD68E236, 0xDA6FD2A0, 0x4366831A, 0x3461B38C, + 0xB969BE79, 0xCE6E8EEF, 0x5767DF55, 0x2060EFC3, + 0xBE047A60, 0xC9034AF6, 0x500A1B4C, 0x270D2BDA, + 0xB7B2364B, 0xC0B506DD, 0x59BC5767, 0x2EBB67F1, + 0xB0DFF252, 0xC7D8C2C4, 0x5ED1937E, 0x29D6A3E8, + 0x9FB08ED5, 0xE8B7BE43, 0x71BEEFF9, 0x06B9DF6F, + 0x98DD4ACC, 0xEFDA7A5A, 0x76D32BE0, 0x01D41B76, + 0x916B06E7, 0xE66C3671, 0x7F6567CB, 0x0862575D, + 0x9606C2FE, 0xE101F268, 0x7808A3D2, 0x0F0F9344, + 0x82079EB1, 0xF500AE27, 0x6C09FF9D, 0x1B0ECF0B, + 0x856A5AA8, 0xF26D6A3E, 0x6B643B84, 0x1C630B12, + 0x8CDC1683, 0xFBDB2615, 0x62D277AF, 0x15D54739, + 0x8BB1D29A, 0xFCB6E20C, 0x65BFB3B6, 0x12B88320, + 0x3FBA6CAD, 0x48BD5C3B, 0xD1B40D81, 0xA6B33D17, + 0x38D7A8B4, 0x4FD09822, 0xD6D9C998, 0xA1DEF90E, + 0x3161E49F, 0x4666D409, 0xDF6F85B3, 0xA868B525, + 0x360C2086, 0x410B1010, 0xD80241AA, 0xAF05713C, + 0x220D7CC9, 0x550A4C5F, 0xCC031DE5, 0xBB042D73, + 0x2560B8D0, 0x52678846, 0xCB6ED9FC, 0xBC69E96A, + 0x2CD6F4FB, 0x5BD1C46D, 0xC2D895D7, 0xB5DFA541, + 0x2BBB30E2, 0x5CBC0074, 0xC5B551CE, 0xB2B26158, + 0x04D44C65, 0x73D37CF3, 0xEADA2D49, 0x9DDD1DDF, + 0x03B9887C, 0x74BEB8EA, 0xEDB7E950, 0x9AB0D9C6, + 0x0A0FC457, 0x7D08F4C1, 0xE401A57B, 0x930695ED, + 0x0D62004E, 0x7A6530D8, 0xE36C6162, 0x946B51F4, + 0x19635C01, 0x6E646C97, 0xF76D3D2D, 0x806A0DBB, + 0x1E0E9818, 0x6909A88E, 0xF000F934, 0x8707C9A2, + 0x17B8D433, 0x60BFE4A5, 0xF9B6B51F, 0x8EB18589, + 0x10D5102A, 0x67D220BC, 0xFEDB7106, 0x89DC4190, + 0x49662D3D, 0x3E611DAB, 0xA7684C11, 0xD06F7C87, + 0x4E0BE924, 0x390CD9B2, 0xA0058808, 0xD702B89E, + 0x47BDA50F, 0x30BA9599, 0xA9B3C423, 0xDEB4F4B5, + 0x40D06116, 0x37D75180, 0xAEDE003A, 0xD9D930AC, + 0x54D13D59, 0x23D60DCF, 0xBADF5C75, 0xCDD86CE3, + 0x53BCF940, 0x24BBC9D6, 0xBDB2986C, 0xCAB5A8FA, + 0x5A0AB56B, 0x2D0D85FD, 0xB404D447, 0xC303E4D1, + 0x5D677172, 0x2A6041E4, 0xB369105E, 0xC46E20C8, + 0x72080DF5, 0x050F3D63, 0x9C066CD9, 0xEB015C4F, + 0x7565C9EC, 0x0262F97A, 0x9B6BA8C0, 0xEC6C9856, + 0x7CD385C7, 0x0BD4B551, 0x92DDE4EB, 0xE5DAD47D, + 0x7BBE41DE, 0x0CB97148, 0x95B020F2, 0xE2B71064, + 0x6FBF1D91, 0x18B82D07, 0x81B17CBD, 0xF6B64C2B, + 0x68D2D988, 0x1FD5E91E, 0x86DCB8A4, 0xF1DB8832, + 0x616495A3, 0x1663A535, 0x8F6AF48F, 0xF86DC419, + 0x660951BA, 0x110E612C, 0x88073096, 0xFF000000 +}; + +static unsigned int GetCRC(char *data, int size) +{ + unsigned int crc = 0; + + while (size--) + crc = crc32tab[(crc ^ *data++) & 0xff] ^ ((crc >> 8) & 0x00FFFFFF); + + return crc; +} + +/* + * Frame transfer + */ + +static GSM_Error WaitFor(GSM_StateMachine *s, char *t, int ttl) +{ + char readbuf[100]; + int n; + unsigned int sec; + GSM_DateTime Date; + + GSM_GetCurrentDateTime (&Date); + sec = Date.Second; + + n = s->Device.Functions->ReadDevice(s, readbuf, 80); + readbuf[n] = 0; + while (strstr(readbuf, t) == NULL && (sec + ttl) >= Date.Second) { + my_sleep(5000); + n = s->Device.Functions->ReadDevice(s, readbuf, 80); + readbuf[n] = 0; + GSM_GetCurrentDateTime (&Date); + } + + return (sec + ttl) >= Date.Second ? ERR_NONE : ERR_TIMEOUT; +} + +static GSM_Error SetSamsungFrame(GSM_StateMachine *s, unsigned char *buff, int size, GSM_Phone_RequestID id) +{ + GSM_Phone_Data *Phone = &s->Phone.Data; + GSM_Error error; + int i, count; + + count = size / BLKSZ; + + for (i = 0; i < count; i++) { + error = WaitFor(s, ">", 4); + if (error!=ERR_NONE) return error; + + error = s->Protocol.Functions->WriteMessage(s, + buff + i * BLKSZ, BLKSZ, 0x00); + if (error!=ERR_NONE) return error; + } + + error = WaitFor(s, ">", 4); + if (error!=ERR_NONE) return error; + error = s->Protocol.Functions->WriteMessage(s, + buff + i * BLKSZ, size%BLKSZ, 0x00); + if (error!=ERR_NONE) return error; + + error = GSM_WaitFor(s, "", 0, 0x00, 4, id); + if (error!=ERR_NONE) return error; + + return Phone->DispatchError; +} + +/* Answer format for binary data transfer + * + * SDNDCRC = 0xa : RECEIVECRC = 0xcbf53a1c : BINSIZE = 5 + * CRCERR + */ +static GSM_Error ReplySetSamsungFrame(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + unsigned long txcrc, rxcrc; + int binsize; + char *pos; + + /* Parse SDNDCRC */ + pos = strchr(msg.Buffer, '='); + if (!pos) return ERR_UNKNOWN; + pos++; + txcrc = strtoul(pos, NULL, 0); + smprintf(s, "Sent CRC : 0x%lx\n", txcrc); + + /* Parse RECEIVECRC */ + pos = strchr(pos, '='); + if (!pos) return ERR_UNKNOWN; + pos++; + rxcrc = strtoul(pos, NULL, 0); + smprintf(s, "Reveived CRC : 0x%lx\n", rxcrc); + + /* Parse BINSIZE */ + pos = strchr(pos, '='); + if (!pos) return ERR_UNKNOWN; + pos++; + binsize = strtoul(pos, NULL, 0); + smprintf(s, "Binary size : %d\n", binsize); + + return txcrc == rxcrc ? ERR_NONE : ERR_WRONGCRC; +} + +/* + * Bitmaps + */ + +GSM_Error SAMSUNG_ReplyGetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + unsigned char buffer[32]; + char *pos; + int location, count; + + switch (Priv->ReplyState) { + case AT_Reply_OK: + smprintf(s, "Bitmap info received\n"); + /* Parse +IMGR:location,name,0,0,0,0 */ + + /* Parse location */ + pos = strchr(msg.Buffer, ':'); + if (!pos) return ERR_UNKNOWN; + pos++; + location = atoi(pos); + smprintf(s, "Location : %d\n", location); + + /* Parse name */ + pos = strchr(pos, '"'); + if (!pos) return ERR_UNKNOWN; + pos++; + for (count = 0; count < 31; count++) { + if (pos[count] == '"') + break; + buffer[count] = pos[count]; + } + buffer[count] = 0; + smprintf(s, "Name : %s\n", buffer); + s->Phone.Data.Bitmap->Name = malloc((strlen(buffer) + 1) * 2); + if (s->Phone.Data.Bitmap->Name == NULL) + return ERR_MOREMEMORY; + EncodeUnicode(s->Phone.Data.Bitmap->Name, buffer, strlen(buffer)); + + s->Phone.Data.Bitmap->Location = location; + + return ERR_NONE; + case AT_Reply_Error: + return ERR_UNKNOWN; + case AT_Reply_CMSError: + return ATGEN_HandleCMSError(s); + case AT_Reply_CMEError: + return ATGEN_HandleCMEError(s); + default: + return ERR_UNKNOWNRESPONSE; + } +} + +GSM_Error SAMSUNG_ReplySetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + smprintf(s, "Bitmap sent\n"); + return ReplySetSamsungFrame(msg, s); +} + +GSM_Error SAMSUNG_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +{ + unsigned char req[100]; + + s->Phone.Data.Bitmap=Bitmap; + smprintf(s, "Getting bitmap\n"); + sprintf(req, "AT+IMGR=%d\r", Bitmap->Location-1); + return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetBitmap); +} + +GSM_Error SAMSUNG_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +{ + unsigned char req[100]; + unsigned long crc; + GSM_Error error; + char name[50], *dot, *model; + GSM_Phone_Data *Data = &s->Phone.Data; + int i; + + s->Phone.Data.Bitmap = Bitmap; + smprintf(s, "Setting bitmap\n"); + + if (Bitmap->Type != GSM_PictureBinary) { + smprintf(s, "Invalid picture type\n"); + return ERR_INVALIDDATA; + } + + if (Bitmap->BinaryPic.Type != PICTURE_GIF) { + smprintf(s, "Invalid binary picture type\n"); + return ERR_INVALIDDATA; + } + + /* Check if picture size matches phone model */ + model = GetModelData(NULL,Data->Model,NULL)->model; + smprintf(s, "Checking picture size for %s\n", model); + for (i = 0; modres[i].model; i++) { + if (!strcmp(model, modres[i].model)) { + if (Bitmap->BitmapWidth != modres[i].width || + Bitmap->BitmapHeight != modres[i].height) { + smprintf(s, "Model %s must use %d x %d picture size\n", + modres[i].model, modres[i].width, + modres[i].height); + return ERR_INVALIDDATA; + } + break; + } + } + if (modres[i].model == NULL) { + smprintf(s, "Model \"%s\" is not supported.\n", Data->Model); + return ERR_NOTSUPPORTED; + } + + crc = GetCRC(Bitmap->BinaryPic.Buffer, Bitmap->BinaryPic.Length); + + /* Remove extension from file name */ + strncpy(name, DecodeUnicodeString(Bitmap->Name), 50); + if ((dot = strrchr(name, '.')) != NULL) + *dot = 0; + + sprintf(req, "AT+IMGW=0,\"%s\",2,0,0,0,0,100,%d,%u\r", name, + Bitmap->BinaryPic.Length, (unsigned int)crc); + + error = s->Protocol.Functions->WriteMessage(s, req, strlen(req), 0x00); + if (error!=ERR_NONE) return error; + + return SetSamsungFrame(s, Bitmap->BinaryPic.Buffer, + Bitmap->BinaryPic.Length, ID_SetBitmap); +} + +/* + * Ringtones + */ + +GSM_Error SAMSUNG_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; + unsigned char buffer[32]; + char *pos; + int location, length, count; + + switch (Priv->ReplyState) { + case AT_Reply_OK: + smprintf(s, "Ringtone info received\n"); + /* Parse +MELR:location,name,size */ + + /* Parse location */ + pos = strchr(msg.Buffer, ':'); + if (!pos) return ERR_UNKNOWN; + pos++; + location = atoi(pos); + smprintf(s, "Location : %d\n", location); + + /* Parse name */ + pos = strchr(pos, '"'); + if (!pos) return ERR_UNKNOWN; + pos++; + /* Ringtone.Name size is 20 chars */ + for (count = 0; count < 19; count++) { + if (pos[count] == '"') + break; + buffer[count] = pos[count]; + } + buffer[count] = 0; + smprintf(s, "Name : %s\n", buffer); + EncodeUnicode(s->Phone.Data.Ringtone->Name,buffer,strlen(buffer)); + + /* Parse ringtone length */ + pos = strchr(pos, ','); + if (!pos) return ERR_UNKNOWN; + pos++; + length = atoi(pos); + smprintf(s, "Length : %d\n", length); + + /* S300 ringtones are always MMF */ + s->Phone.Data.Ringtone->Format = RING_MMF; + s->Phone.Data.Ringtone->Location = location; + s->Phone.Data.Ringtone->BinaryTone.Length = length; + + return ERR_NONE; + case AT_Reply_Error: + return ERR_UNKNOWN; + case AT_Reply_CMSError: + return ATGEN_HandleCMSError(s); + case AT_Reply_CMEError: + return ATGEN_HandleCMEError(s); + default: + return ERR_UNKNOWNRESPONSE; + } +} + +GSM_Error SAMSUNG_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) +{ + unsigned char req[100]; + + s->Phone.Data.Ringtone = Ringtone; + smprintf(s, "Getting ringtone\n"); + sprintf(req, "AT+MELR=%d\r", Ringtone->Location-1); + return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetRingtone); +} + +GSM_Error SAMSUNG_ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + smprintf(s, "Ringtone sent\n"); + return ReplySetSamsungFrame(msg, s); +} + +GSM_Error SAMSUNG_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) +{ + unsigned char req[100]; + unsigned long crc; + GSM_Error error; + char name[50], *dot; + + s->Phone.Data.Ringtone = Ringtone; + smprintf(s, "Setting ringtone\n"); + + if (Ringtone->Format != RING_MMF) { + smprintf(s, "Not MMF ringtone\n"); + return ERR_INVALIDDATA; + } + + /* Remove extension from file name */ + strncpy(name, DecodeUnicodeString(Ringtone->Name), 50); + if ((dot = strrchr(name, '.')) != NULL) *dot = 0; + + crc = GetCRC(Ringtone->BinaryTone.Buffer, Ringtone->BinaryTone.Length); + sprintf(req, "AT+MELW=0,\"%s\",4,%d,%u\r", name, + Ringtone->BinaryTone.Length, (unsigned int)crc); + + error = s->Protocol.Functions->WriteMessage(s, req, strlen(req), 0x00); + if (error!=ERR_NONE) return error; + + return SetSamsungFrame(s, Ringtone->BinaryTone.Buffer, + Ringtone->BinaryTone.Length, ID_SetRingtone); +} + +#endif diff --git a/gammu/emb/common/phone/at/samsung.h b/gammu/emb/common/phone/at/samsung.h new file mode 100644 index 0000000..3b2947c --- a/dev/null +++ b/gammu/emb/common/phone/at/samsung.h @@ -0,0 +1,16 @@ +#ifndef samsung_h +#define samsung_h + +#include "../../gsmstate.h" + +GSM_Error SAMSUNG_ReplyGetRingtone (GSM_Protocol_Message, GSM_StateMachine *); +GSM_Error SAMSUNG_ReplySetRingtone (GSM_Protocol_Message, GSM_StateMachine *); +GSM_Error SAMSUNG_ReplyGetBitmap (GSM_Protocol_Message, GSM_StateMachine *); +GSM_Error SAMSUNG_ReplySetBitmap (GSM_Protocol_Message, GSM_StateMachine *); +GSM_Error SAMSUNG_GetRingtone (GSM_StateMachine *, GSM_Ringtone *, bool); +GSM_Error SAMSUNG_SetRingtone (GSM_StateMachine *, GSM_Ringtone *, int *); +GSM_Error SAMSUNG_GetBitmap (GSM_StateMachine *, GSM_Bitmap *); +GSM_Error SAMSUNG_SetBitmap (GSM_StateMachine *, GSM_Bitmap *); +GSM_Error SAMSUNG_GetCallLogs (GSM_StateMachine *, GSM_MemoryEntry *, int); + +#endif diff --git a/gammu/emb/common/phone/at/siemens.c b/gammu/emb/common/phone/at/siemens.c index ab7dd2c..7f66cf8 100644 --- a/gammu/emb/common/phone/at/siemens.c +++ b/gammu/emb/common/phone/at/siemens.c @@ -8,35 +8,21 @@ #include <time.h> #include <ctype.h> #include "../../misc/coding/coding.h" #include "../../gsmcomon.h" #include "../../service/sms/gsmsms.h" #include "../pfunc.h" -extern GSM_Error ATGEN_HandleCMSError(GSM_StateMachine *s); +#include "atgen.h" +#include "siemens.h" -GSM_Error ATGEN_CMS35ReplySetFunction (GSM_Protocol_Message msg, GSM_StateMachine *s,char *function) -{ - if (s->Protocol.Data.AT.EditMode) { - s->Protocol.Data.AT.EditMode = false; - return ERR_NONE; - } - dbgprintf ("Written %s",function); - if (s->Phone.Data.Priv.ATGEN.ReplyState == AT_Reply_OK){ - dbgprintf (" - OK\n"); - return ERR_NONE; - } else { - dbgprintf (" - error\n"); - return ERR_UNKNOWN; - } -} -GSM_Error GetSiemensFrame(GSM_Protocol_Message msg, GSM_StateMachine *s, char *templ, +static GSM_Error GetSiemensFrame(GSM_Protocol_Message msg, GSM_StateMachine *s, char *templ, unsigned char *buffer, int *len) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; int i=2, pos=0, length=0; unsigned char buf[512]; if (strstr(GetLineString(msg.Buffer,Priv->Lines,2),"OK")) return ERR_EMPTY; if (!strstr(GetLineString(msg.Buffer,Priv->Lines,2),templ)) return ERR_UNKNOWN; @@ -52,17 +38,17 @@ GSM_Error GetSiemensFrame(GSM_Protocol_Message msg, GSM_StateMachine *s, char *t pos+=length; } i++; } *len = pos; return ERR_NONE; } -GSM_Error SetSiemensFrame (GSM_StateMachine *s, unsigned char *buff, char *templ, +static GSM_Error SetSiemensFrame (GSM_StateMachine *s, unsigned char *buff, char *templ, int Location, GSM_Phone_RequestID RequestID, int len) { GSM_Phone_Data *Phone = &s->Phone.Data; GSM_Error error; unsigned char req[20],req1[512],hexreq[2096]; int MaxFrame,CurrentFrame,size,sz,pos=0; EncodeHexBin(hexreq,buff,len); @@ -85,117 +71,127 @@ GSM_Error SetSiemensFrame (GSM_StateMachine *s, unsigned char *buff, char *templ error = s->Protocol.Functions->WriteMessage(s,"\x1A", 1, 0x00); if (error!=ERR_NONE) return error; error = GSM_WaitForOnce(s, NULL, 0x00, 0x00, 4); if (error == ERR_TIMEOUT) return error; } return Phone->DispatchError; } -GSM_Error ATGEN_CMS35ReplyGetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyGetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char buffer[4096]; int length; GSM_Error error; error = GetSiemensFrame(msg,s,"bmp",buffer,&length); if (error!=ERR_NONE) return error; dbgprintf ("Operator logo received lenght=%i\n",length); error = BMP2Bitmap (buffer,NULL,s->Phone.Data.Bitmap); if (error==ERR_NONE) return error; else return ERR_UNKNOWN; } -GSM_Error ATGEN_CMS35ReplySetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplySetFunction (GSM_Protocol_Message msg, GSM_StateMachine *s,char *function) { - return ATGEN_CMS35ReplySetFunction (msg, s, "Operator Logo");
+ if (s->Protocol.Data.AT.EditMode) { + s->Protocol.Data.AT.EditMode = false; + return ERR_NONE; + } + dbgprintf ("Written %s",function); + if (s->Phone.Data.Priv.ATGEN.ReplyState == AT_Reply_OK){ + dbgprintf (" - OK\n"); + return ERR_NONE; + } else { + dbgprintf (" - error\n"); + return ERR_UNKNOWN; + } } -GSM_Error ATGEN_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +GSM_Error SIEMENS_ReplySetBitmap(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + return SIEMENS_ReplySetFunction (msg, s, "Operator Logo");
+} + +GSM_Error SIEMENS_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { unsigned char req[32]; - if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; if (Bitmap->Type!=GSM_OperatorLogo) return ERR_NOTSUPPORTED; if (Bitmap->Location-1 < 0) Bitmap->Location++; s->Phone.Data.Bitmap=Bitmap; sprintf(req, "AT^SBNR=\"bmp\",%i\r", Bitmap->Location-1); smprintf(s, "Getting Bitmap\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetBitmap); } -GSM_Error ATGEN_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) +GSM_Error SIEMENS_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap) { unsigned char buffer[4096]; int length; GSM_Error error; - if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; if (Bitmap->Type!=GSM_OperatorLogo) return ERR_NOTSUPPORTED; error = Bitmap2BMP (buffer,NULL,Bitmap); if (error!=ERR_NONE) return error; length = 0x100 * buffer[3] + buffer[2]; buffer[58]=0xff; buffer[59]=0xff; buffer[60]=0xff; if (Bitmap->Location-1 < 0) Bitmap->Location++; s->Phone.Data.Bitmap=Bitmap; return SetSiemensFrame(s, buffer,"bmp",Bitmap->Location-1, ID_SetBitmap,length); } -GSM_Error ATGEN_CMS35ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char buffer[32]; int length; GSM_Error error; error = GetSiemensFrame(msg,s,"mid",s->Phone.Data.Ringtone->NokiaBinary.Frame,&length); if (error!=ERR_NONE) return error; dbgprintf ("Midi ringtone received\n"); s->Phone.Data.Ringtone->Format = RING_MIDI; s->Phone.Data.Ringtone->NokiaBinary.Length = length; sprintf(buffer,"Individual"); EncodeUnicode (s->Phone.Data.Ringtone->Name,buffer,strlen(buffer)); return ERR_NONE; } -GSM_Error ATGEN_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) +GSM_Error SIEMENS_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone) { unsigned char req[32]; - if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; - s->Phone.Data.Ringtone=Ringtone; sprintf(req, "AT^SBNR=\"mid\",%i\r", Ringtone->Location-1); smprintf(s, "Getting RingTone\n"); return GSM_WaitFor (s, req, strlen(req), 0x00, 4, ID_GetRingtone); } -GSM_Error ATGEN_CMS35ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s) { - return ATGEN_CMS35ReplySetFunction (msg, s, "Ringtone"); + return SIEMENS_ReplySetFunction (msg, s, "Ringtone"); } -GSM_Error ATGEN_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) +GSM_Error SIEMENS_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength) { GSM_Phone_Data *Phone = &s->Phone.Data; - if (s->Phone.Data.Priv.ATGEN.Manufacturer!=AT_Siemens) return ERR_NOTSUPPORTED; - if (Ringtone->Location==255) Ringtone->Location=1; if (Ringtone->Location-1 > 1) return ERR_INVALIDLOCATION; s->Phone.Data.Ringtone = Ringtone; Phone->Ringtone = Ringtone; return SetSiemensFrame(s, Ringtone->NokiaBinary.Frame,"mid",Ringtone->Location-1, ID_SetRingtone,Ringtone->NokiaBinary.Length); } -GSM_Error ATGEN_CMS35ReplyGetNextCal(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyGetNextCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; GSM_CalendarEntry *Calendar = Data->Cal; GSM_ToDoEntry ToDo; GSM_Error error; unsigned char buffer[354]; int len, pos=0; @@ -230,22 +226,22 @@ GSM_Error SIEMENS_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, Note->Location = Location; Priv->FirstCalendarPos = Location; if (Location > MAX_VCALENDAR_LOCATION) return ERR_EMPTY; if (error==ERR_NONE) return error; } return error; } -GSM_Error ATGEN_CMS35ReplySetCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyAddCalendarNote(GSM_Protocol_Message msg, GSM_StateMachine *s) { - return ATGEN_CMS35ReplySetFunction (msg, s, "Calendar Note"); + return SIEMENS_ReplySetFunction (msg, s, "Calendar Note"); } -GSM_Error ATGEN_CMS35ReplyDeleteCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyDelCalendarNote(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; if (Data->Cal->Location > MAX_VCALENDAR_LOCATION) return ERR_UNKNOWN; if (Data->Priv.ATGEN.ReplyState== AT_Reply_OK) { smprintf(s, "Calendar note deleted\n"); return ERR_NONE; @@ -278,17 +274,17 @@ GSM_Error SIEMENS_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) s->Phone.Data.Cal = Note; error=GSM_EncodeVCALENDAR(req,&size,Note,true,Siemens_VCalendar); return SetSiemensFrame (s,req,"vcs",Note->Location,ID_SetCalendarNote,size); } /* (c) by Timo Teras */ -GSM_Error ATGEN_SL45ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) +GSM_Error SIEMENS_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { #ifndef ENABLE_LGPL GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_MemoryEntry *Memory = s->Phone.Data.Memory; unsigned char buffer[500],buffer2[500]; switch (Priv->ReplyState) { case AT_Reply_OK: diff --git a/gammu/emb/common/phone/at/sonyeric.c b/gammu/emb/common/phone/at/sonyeric.c index 4b2670a..8eeb39b 100644 --- a/gammu/emb/common/phone/at/sonyeric.c +++ b/gammu/emb/common/phone/at/sonyeric.c @@ -6,27 +6,25 @@ #include <string.h> #include <time.h> #include <ctype.h> #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" -extern GSM_Reply_Function ATGENReplyFunctions[]; -extern GSM_Error ATGEN_DispatchMessage (GSM_StateMachine *s); +#include "atgen.h" +#include "sonyeric.h" #ifdef GSM_ENABLE_OBEXGEN -extern GSM_Reply_Function OBEXGENReplyFunctions[]; -extern GSM_Error OBEXGEN_GetFilePart (GSM_StateMachine *s, GSM_File *File); -extern GSM_Error OBEXGEN_AddFilePart (GSM_StateMachine *s, GSM_File *File, int *Pos); -extern GSM_Error OBEXGEN_Disconnect (GSM_StateMachine *s); +#include "../obex/obexgen.h" -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +extern GSM_Reply_Function OBEXGENReplyFunctions[]; +extern GSM_Reply_Function ATGENReplyFunctions[]; static GSM_Error SONYERIC_SetOBEXMode(GSM_StateMachine *s) { GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; GSM_Error error; if (Priv->OBEX) return ERR_NONE; @@ -121,17 +119,17 @@ static GSM_Error SONYERIC_SetFile(GSM_StateMachine *s, unsigned char *FileName, return SONYERIC_SetATMode(s); } #endif GSM_Error SONYERIC_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; GSM_ToDoEntry ToDo; int Pos, num, Loc; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (start) { error = SONYERIC_GetFile(s, &Priv->file, "telecom/cal.vcs"); if (error != ERR_NONE) return error; @@ -157,17 +155,17 @@ GSM_Error SONYERIC_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, return ERR_EMPTY; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; GSM_CalendarEntry Calendar; int Pos, num, Loc; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; if (start) { @@ -196,17 +194,17 @@ GSM_Error SONYERIC_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool st return ERR_EMPTY; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; GSM_ToDoEntry ToDo; GSM_CalendarEntry Calendar; int Pos; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; @@ -227,33 +225,33 @@ GSM_Error SONYERIC_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) return ERR_NONE; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN unsigned char req[5000]; int size=0; smprintf(s,"Adding calendar note\n"); GSM_EncodeVCALENDAR(req,&size,Note,true,SonyEricsson_VCalendar); return SONYERIC_SetFile(s, "telecom/cal/luid/.vcs", req, size); #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char req[5000]; int size=0; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; smprintf(s,"Adding ToDo\n"); @@ -262,17 +260,17 @@ GSM_Error SONYERIC_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo) return SONYERIC_SetFile(s, "telecom/cal/luid/.vcs", req, size); #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_DeleteAllToDo(GSM_StateMachine *s) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; int Pos,Level = 0,Used; unsigned char *Buf; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char Line[2000]; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; @@ -314,17 +312,17 @@ GSM_Error SONYERIC_DeleteAllToDo(GSM_StateMachine *s) return error; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; int Pos,Level = 0,Loc=0,Used; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; unsigned char Line[2000]; unsigned char *Buf; smprintf(s, "Deleting calendar note %i\n",Note->Location); @@ -369,17 +367,17 @@ GSM_Error SONYERIC_DelCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note) return error; #else return ERR_SOURCENOTAVAILABLE; #endif } GSM_Error SONYERIC_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status) { -#if defined(GSM_ENABLE_BLUEOBEX) || defined(GSM_ENABLE_IRDAOBEX) +#ifdef GSM_ENABLE_OBEXGEN GSM_Error error; GSM_ToDoEntry ToDo; GSM_CalendarEntry Calendar; int Pos; GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN; if (Priv->Manufacturer!=AT_Ericsson) return ERR_NOTSUPPORTED; @@ -398,14 +396,125 @@ GSM_Error SONYERIC_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *St } return ERR_NONE; #else return ERR_SOURCENOTAVAILABLE; #endif } -#endif +GSM_Error ERICSSON_ReplyGetDateLocale(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ /* Author: Peter Ondraska, based on code by Marcin Wiacek and Michal Cihar + License: Whatever the current maintainer of gammulib chooses, as long as there + is an easy way to obtain the source under GPL, otherwise the author's parts + of this function are GPL 2.0. + */ + GSM_Locale *locale = s->Phone.Data.Locale; + char format; + + switch (s->Phone.Data.Priv.ATGEN.ReplyState) { + case AT_Reply_OK: + smprintf(s, "Date settings received\n"); + format=atoi(msg.Buffer); + switch (format) { + case 0: locale->DateFormat = GSM_Date_OFF; + locale->DateSeparator = 0; + break; + case 1: locale->DateFormat = GSM_Date_DDMMMYY; + locale->DateSeparator = '-'; + break; + case 2: locale->DateFormat = GSM_Date_DDMMYY; + locale->DateSeparator = '-'; + break; + case 3: locale->DateFormat = GSM_Date_MMDDYY; + locale->DateSeparator = '/'; + break; + case 4: locale->DateFormat = GSM_Date_DDMMYY; + locale->DateSeparator = '/'; + break; + case 5: locale->DateFormat = GSM_Date_DDMMYY; + locale->DateSeparator = '.'; + break; + case 6: locale->DateFormat = GSM_Date_YYMMDD; + locale->DateSeparator = 0; + break; + case 7: locale->DateFormat = GSM_Date_YYMMDD; + locale->DateSeparator = '-'; + break; + default:return ERR_UNKNOWNRESPONSE; + } + default: + return ERR_NOTSUPPORTED; + } +} + +GSM_Error ERICSSON_ReplyGetTimeLocale(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ /* Author: Peter Ondraska + License: Whatever the current maintainer of gammulib chooses, as long as there + is an easy way to obtain the source under GPL, otherwise the author's parts + of this function are GPL 2.0. + */ + char format; + + switch (s->Phone.Data.Priv.ATGEN.ReplyState) { + case AT_Reply_OK: + smprintf(s, "Time settings received\n"); + format=atoi(msg.Buffer); + switch (format) { + case 1: + case 2: s->Phone.Data.Locale->AMPMTime=(format==2); + return ERR_NONE; + default:return ERR_UNKNOWNRESPONSE; + } + default: return ERR_NOTSUPPORTED; + } +} + +GSM_Error ERICSSON_GetLocale(GSM_StateMachine *s, GSM_Locale *locale) +{ + GSM_Error error; + + s->Phone.Data.Locale = locale; + + smprintf(s, "Getting date format\n"); + error=GSM_WaitFor (s, "AT+ESDF?\r", 9, 0x00, 3, ID_GetLocale); + if (error!=ERR_NONE) return error; + + smprintf(s, "Getting time format\n"); + return GSM_WaitFor (s, "AT+ESTF?\r", 9, 0x00, 3, ID_GetLocale); +} + + +GSM_Error ERICSSON_SetLocale(GSM_StateMachine *s, GSM_Locale *locale) +{ /* Author: Peter Ondraska + License: Whatever the current maintainer of gammulib chooses, as long as there + is an easy way to obtain the source under GPL, otherwise the author's parts + of this function are GPL 2.0. + */ + /* this is not yet supported by gammu.c */ + int format=0; + char req[12]; + + if (locale->DateFormat==GSM_Date_OFF) { format=0; } else + if ((locale->DateFormat==GSM_Date_DDMMMYY)&&(locale->DateSeparator=='-')) { format=1; } else + if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='-')) { format=2; } else + if ((locale->DateFormat==GSM_Date_MMDDYY)&&(locale->DateSeparator=='/')) { format=3; } else + if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='/')) { format=4; } else + if ((locale->DateFormat==GSM_Date_DDMMYY)&&(locale->DateSeparator=='.')) { format=5; } else + if ((locale->DateFormat==GSM_Date_YYMMDD)&&(locale->DateSeparator==0)) { format=6; } else + if ((locale->DateFormat==GSM_Date_YYMMDD)&&(locale->DateSeparator=='-')) { format=7; } + else { return ERR_NOTSUPPORTED; } /* ERR_WRONGINPUT */ + + sprintf(req,"AT+ESDF=%i\r",format); + smprintf(s, "Setting date format\n"); + return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetLocale); + + if (locale->AMPMTime) { format=2; } else { format=1; } + sprintf(req,"AT+ESTF=%i\r",format); + smprintf(s, "Setting time format\n"); + return GSM_WaitFor (s, req, strlen(req), 0x00, 3, ID_SetLocale); +} + #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/nokia/dct3/dct3func.c b/gammu/emb/common/phone/nokia/dct3/dct3func.c index beef33c..17cd0a4 100644 --- a/gammu/emb/common/phone/nokia/dct3/dct3func.c +++ b/gammu/emb/common/phone/nokia/dct3/dct3func.c @@ -1,11 +1,14 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Markus Plail, Pavel Janik, others and Gnokii */ /* resetting DCT4 phones settings (c) by Walek */ +/* based on some Markus Plail, Pavel Janik & others work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include <string.h> /* memcpy only */ #include <stdio.h> #include <ctype.h> #include "../../../gsmstate.h" #include "../../../misc/coding/coding.h" #include "../../../service/sms/gsmsms.h" @@ -389,16 +392,17 @@ GSM_Error DCT3_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s) switch (msg.Buffer[6]) { case 0x00: Data->SMSC->Format = SMS_FORMAT_Text; break; case 0x22: Data->SMSC->Format = SMS_FORMAT_Fax; break; case 0x26: Data->SMSC->Format = SMS_FORMAT_Pager; break; case 0x32: Data->SMSC->Format = SMS_FORMAT_Email; break; } Data->SMSC->Validity.Format = SMS_Validity_RelativeFormat; Data->SMSC->Validity.Relative = msg.Buffer[8]; + if (msg.Buffer[8] == 0x00) Data->SMSC->Validity.Relative = SMS_VALID_Max_Time; i=33; while (msg.Buffer[i]!=0) {i++;} i=i-33; if (i>GSM_MAX_SMSC_NAME_LENGTH) { smprintf(s, "Too long name\n"); return ERR_UNKNOWNRESPONSE; } @@ -437,35 +441,35 @@ GSM_Error DCT3_ReplyGetNetworkInfo(GSM_Protocol_Message msg, GSM_StateMachine *s { int count; GSM_Phone_Data *Data = &s->Phone.Data; #ifdef DEBUG GSM_NetworkInfo NetInfo; char name[100]; smprintf(s, "Network info received\n"); - smprintf(s, " Status : "); + smprintf(s, "Status : "); switch (msg.Buffer[8]) { case 0x01: smprintf(s, "home network"); break; case 0x02: smprintf(s, "roaming network"); break; case 0x03: smprintf(s, "requesting network"); break; case 0x04: smprintf(s, "not registered in the network"); break; default : smprintf(s, "unknown"); } smprintf(s, "\n"); - smprintf(s, "Network selection : %s\n", msg.Buffer[9]==1?"manual":"automatic"); + smprintf(s, "Network selection : %s\n", msg.Buffer[9]==1?"manual":"automatic"); if (msg.Buffer[8]<0x03) { sprintf(NetInfo.CID, "%02x%02x", msg.Buffer[10], msg.Buffer[11]); smprintf(s, "CID : %s\n", NetInfo.CID); sprintf(NetInfo.LAC, "%02x%02x", msg.Buffer[12], msg.Buffer[13]); smprintf(s, "LAC : %s\n", NetInfo.LAC); - smprintf(s, "Network code : %s\n", NetInfo.NetworkCode); NOKIA_DecodeNetworkCode(msg.Buffer+14,NetInfo.NetworkCode); + smprintf(s, "Network code : %s\n", NetInfo.NetworkCode); smprintf(s, "Network name for Gammu : %s ", DecodeUnicodeString(GSM_GetNetworkName(NetInfo.NetworkCode))); smprintf(s, "(%s)\n",DecodeUnicodeString(GSM_GetCountryName(NetInfo.NetworkCode))); if (msg.Length>18) { if (msg.Buffer[18]==0x00) { /* In 6210 name is in "normal" Unicode */ memcpy(name,msg.Buffer+18,msg.Buffer[17]*2); @@ -1203,21 +1207,21 @@ GSM_Error DCT3_SetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *setting return DCT3DCT4_DisableConnectionFunctions(s); } GSM_Error DCT3_ReplySendSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[3]) { case 0x02: smprintf(s, "SMS sent OK\n"); - if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,0,0); + if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,0,msg.Buffer[5]); return ERR_NONE; case 0x03: smprintf(s, "Error %i\n",msg.Buffer[6]); - if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,msg.Buffer[6],0); + if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,msg.Buffer[6],-1); return ERR_NONE; } return ERR_UNKNOWNRESPONSE; } GSM_Error DCT3_SendSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms) { int length; diff --git a/gammu/emb/common/phone/nokia/dct3/dct3func.h b/gammu/emb/common/phone/nokia/dct3/dct3func.h index 66b67ec..18b2026 100644 --- a/gammu/emb/common/phone/nokia/dct3/dct3func.h +++ b/gammu/emb/common/phone/nokia/dct3/dct3func.h @@ -1,13 +1,15 @@ /* (c) 2002-2003 by Marcin Wiacek */ #ifndef phone_nokia_dct3_h #define phone_nokia_dct3_h +#include "../ncommon.h" + GSM_Error DCT3_ReplyPressKey (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyPlayTone (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyEnableSecurity (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyGetIMEI (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyGetSMSC (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplySIMLogin (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplySIMLogout (GSM_Protocol_Message msg, GSM_StateMachine *s); GSM_Error DCT3_ReplyGetDateTime (GSM_Protocol_Message msg, GSM_StateMachine *s); diff --git a/gammu/emb/common/phone/nokia/dct3/n6110.c b/gammu/emb/common/phone/nokia/dct3/n6110.c index 263d12b..dac6c12 100644 --- a/gammu/emb/common/phone/nokia/dct3/n6110.c +++ b/gammu/emb/common/phone/nokia/dct3/n6110.c @@ -1,12 +1,14 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Markus Plail and Gnokii */ -/* Authentication function (c) 1999 or earlier by Pavel Janik */ /* 5210 calendar IDs by Frederick Ros */ +/* based on some Markus Plail, Pavel Janik & others work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA6110 #include <string.h> #include "../../../../cfg/config.h" @@ -122,16 +124,17 @@ static void N6110_EncodeUnicode(GSM_StateMachine *s, unsigned char *dest, const } } dest[o_len*2] = 0; dest[(o_len*2)+1] = 0; } #ifndef ENABLE_LGPL +/* Pavel Janik */ /* This function provides Nokia authentication protocol. * Nokia authentication protocol is used in the communication between Nokia * mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software, * commercially sold by Nokia Corp. * The authentication scheme is based on the token send by the phone to the * software. The software does it's magic (see the function * N6110_GetNokiaAuthentication) and returns the result back to the phone. * If the result is correct the phone responds with the message "Accessory @@ -819,16 +822,17 @@ static GSM_Error N6110_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, reqBin[current++] = 0x00;/*xxx*/ memcpy(reqBin+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length); current=current+Ringtone->NokiaBinary.Length; reqBin[3]=Ringtone->Location-1; if (!strcmp(s->Phone.Data.ModelInfo->model,"3210")) reqBin[5]=0x10; smprintf(s, "Setting binary ringtone\n"); return GSM_WaitFor (s, reqBin, current, 0x40, 4, ID_SetRingtone); case RING_MIDI: + case RING_MMF: return ERR_NOTSUPPORTED; } return ERR_NOTSUPPORTED; } static GSM_Error N6110_ReplyGetOpLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int count=5; @@ -1519,16 +1523,17 @@ static GSM_Error N6110_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachi /* Copying frame */ memcpy(Data->Ringtone->NokiaBinary.Frame,msg.Buffer+start,end-start); Data->Ringtone->NokiaBinary.Length=end-start; #ifdef DEBUG if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, di.dl, Data->Ringtone->NokiaBinary.Frame, Data->Ringtone->NokiaBinary.Length); #endif return ERR_NONE; case RING_MIDI: + case RING_MMF: return ERR_NOTSUPPORTED; } smprintf(s, "Ringtone format is %i\n",Data->Ringtone->Format); break; default: smprintf(s, "Invalid location. Too high ?\n"); return ERR_INVALIDLOCATION; } @@ -1556,16 +1561,17 @@ static GSM_Error N6110_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, switch (Ringtone->Format) { case RING_NOTETONE: if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_RING_SM)) return ERR_NOTSUPPORTED; break; case RING_NOKIABINARY: if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_RING_SM)) return ERR_NOTSUPPORTED; break; case RING_MIDI: + case RING_MMF: return ERR_NOTSUPPORTED; } error=DCT3_EnableSecurity (s, 0x01); if (error!=ERR_NONE) return error; req[3]=Ringtone->Location-1; s->Phone.Data.Ringtone=Ringtone; @@ -2438,18 +2444,18 @@ static GSM_Error N6110_GetNextCalendarNote(GSM_StateMachine *s, GSM_CalendarEntr return error; } GSM_Error N6110_ReplyUSSDInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { unsigned char buffer[2000],buffer2[4000]; int tmp; - tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, msg.Buffer+8, buffer); - msg.Buffer[tmp] = 0; + tmp=GSM_UnpackEightBitsToSeven(0, msg.Buffer[7], 82, msg.Buffer+8, buffer); + buffer[tmp] = 0; smprintf(s, "USSD reply: \"%s\"\n",buffer); if (s->Phone.Data.EnableIncomingUSSD && s->User.IncomingUSSD!=NULL) { EncodeUnicode(buffer2,buffer,strlen(buffer)); s->User.IncomingUSSD(s->CurrentConfig->Device, buffer2); } @@ -2802,16 +2808,17 @@ GSM_Phone_Functions N6110Phone = { DCT3_GetSMSStatus, N6110_GetSMSMessage, N6110_GetNextSMSMessage, N6110_SetSMS, N6110_AddSMS, N6110_DeleteSMSMessage, DCT3_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOKIA_SetIncomingSMS, DCT3_SetIncomingCB, PHONE_GetSMSFolders, NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ N6110_DialVoice, N6110_AnswerCall, DCT3_CancelCall, @@ -2856,17 +2863,17 @@ GSM_Phone_Functions N6110Phone = { NOTIMPLEMENTED, /* GetCalendar */ N6110_GetNextCalendarNote, NOTIMPLEMENTED, /* SetCalendar */ N6110_AddCalendarNote, N6110_DeleteCalendarNote, NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ N6110_GetProfile, N6110_SetProfile, NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ diff --git a/gammu/emb/common/phone/nokia/dct3/n7110.c b/gammu/emb/common/phone/nokia/dct3/n7110.c index 5a02c9c..b597f9b 100644 --- a/gammu/emb/common/phone/nokia/dct3/n7110.c +++ b/gammu/emb/common/phone/nokia/dct3/n7110.c @@ -1,10 +1,13 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Markus Plail and Gnokii */ +/* based on some Markus Plail work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA7110 #include <string.h> #include <time.h> @@ -521,16 +524,17 @@ static GSM_Error N7110_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, /* In the future get binary and convert */ return ERR_NOTSUPPORTED; case RING_NOKIABINARY: req[5]=N7110_ReturnBinaryRingtoneLocation(s->Phone.Data.Model)+Ringtone->Location; s->Phone.Data.Ringtone=Ringtone; smprintf(s, "Getting binary ringtone\n"); return GSM_WaitFor (s, req, 6, 0x1f, 4, ID_GetRingtone); case RING_MIDI: + case RING_MMF: return ERR_NOTSUPPORTED; } return ERR_NOTSUPPORTED; } static GSM_Error N7110_ReplyGetPictureImageInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int i; @@ -1642,16 +1646,17 @@ GSM_Phone_Functions N7110Phone = { N7110_GetSMSStatus, N7110_GetSMSMessage, N7110_GetNextSMSMessage, N7110_SetSMS, N7110_AddSMS, N7110_DeleteSMS, DCT3_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ N7110_SetIncomingSMS, DCT3_SetIncomingCB, N7110_GetSMSFolders, NOTIMPLEMENTED, /* AddSMSFolder */ NOTIMPLEMENTED, /* DeleteSMSFolder */ DCT3_DialVoice, N7110_AnswerCall, DCT3_CancelCall, @@ -1696,17 +1701,17 @@ GSM_Phone_Functions N7110Phone = { NOTIMPLEMENTED, /* GetCalendar */ N7110_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ N7110_AddCalendar, N71_65_DelCalendar, NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ N7110_GetProfile, N7110_SetProfile, NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ diff --git a/gammu/emb/common/phone/nokia/dct3/n9210.c b/gammu/emb/common/phone/nokia/dct3/n9210.c index e82d530..ff71ad3 100644 --- a/gammu/emb/common/phone/nokia/dct3/n9210.c +++ b/gammu/emb/common/phone/nokia/dct3/n9210.c @@ -314,16 +314,17 @@ GSM_Phone_Functions N9210Phone = { NOTIMPLEMENTED, /* GetSMSStatus */ NOTIMPLEMENTED, /* GetSMS */ NOTIMPLEMENTED, /* GetNextSMS */ NOTIMPLEMENTED, /* SetSMS */ NOTIMPLEMENTED, /* AddSMS */ NOTIMPLEMENTED, /* DeleteSMS */ DCT3_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ N9210_SetIncomingSMS, DCT3_SetIncomingCB, NOTIMPLEMENTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ DCT3_DialVoice, N9210_AnswerCall, DCT3_CancelCall, @@ -368,17 +369,17 @@ GSM_Phone_Functions N9210Phone = { NOTSUPPORTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTSUPPORTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTSUPPORTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTIMPLEMENTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFile */ diff --git a/gammu/emb/common/phone/nokia/dct4/n3320.c b/gammu/emb/common/phone/nokia/dct4/n3320.c index 51e6f18..9b1d6cd 100644 --- a/gammu/emb/common/phone/nokia/dct4/n3320.c +++ b/gammu/emb/common/phone/nokia/dct4/n3320.c @@ -189,16 +189,17 @@ GSM_Phone_Functions N3320Phone = { NOTSUPPORTED, /* GetSMSStatus */ NOTSUPPORTED, /* GetSMS */ NOTSUPPORTED, /* GetNextSMS */ NOTSUPPORTED, /* SetSMS */ NOTSUPPORTED, /* AddSMS */ NOTSUPPORTED, /* DeleteSMS */ NOTSUPPORTED, /* SendSMS */ NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOTSUPPORTED, /* SetIncomingSMS */ NOTSUPPORTED, /* SetIncomingCB */ NOTSUPPORTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ NOTIMPLEMENTED, /* DialVoice */ NOTIMPLEMENTED, /* AnswerCall */ NOTIMPLEMENTED, /* CancelCall */ @@ -243,17 +244,17 @@ GSM_Phone_Functions N3320Phone = { NOTIMPLEMENTED, /* GetCalendar */ N3320_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTIMPLEMENTED, /* AddFilePart */ diff --git a/gammu/emb/common/phone/nokia/dct4/n3650.c b/gammu/emb/common/phone/nokia/dct4/n3650.c index 2da55bf..d4746a7 100644 --- a/gammu/emb/common/phone/nokia/dct4/n3650.c +++ b/gammu/emb/common/phone/nokia/dct4/n3650.c @@ -310,16 +310,17 @@ GSM_Phone_Functions N3650Phone = { NOTSUPPORTED, /* GetSMSStatus */ NOTSUPPORTED, /* GetSMS */ NOTSUPPORTED, /* GetNextSMS */ NOTSUPPORTED, /* SetSMS */ NOTSUPPORTED, /* AddSMS */ NOTSUPPORTED, /* DeleteSMS */ NOTSUPPORTED, /* SendSMS */ NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOTSUPPORTED, /* SetIncomingSMS */ NOTSUPPORTED, /* SetIncomingCB */ NOTSUPPORTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ NOTIMPLEMENTED, /* DialVoice */ NOTIMPLEMENTED, /* AnswerCall */ NOTIMPLEMENTED, /* CancelCall */ @@ -364,17 +365,17 @@ GSM_Phone_Functions N3650Phone = { NOTIMPLEMENTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTIMPLEMENTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ N3650_GetNextFileFolder, N3650_GetFilePart, NOTIMPLEMENTED, /* AddFilePart */ diff --git a/gammu/emb/common/phone/nokia/dct4/n6510.c b/gammu/emb/common/phone/nokia/dct4/n6510.c index 67fe492..2208def 100644 --- a/gammu/emb/common/phone/nokia/dct4/n6510.c +++ b/gammu/emb/common/phone/nokia/dct4/n6510.c @@ -1,10 +1,13 @@ /* (c) 2002-2004 by Marcin Wiacek */ -/* based on some work from Markus Plail, Pawel Kot and Gnokii */ +/* based on some Markus Plail, Pawel Kot work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ /* function for making CRC for filesystem (c) 2003 by Michael Schroeder */ #include "../../../gsmstate.h" #ifdef GSM_ENABLE_NOKIA6510 #include <string.h> #include <time.h> @@ -114,16 +117,18 @@ static GSM_Error N6510_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine * switch (msg.Buffer[10]) { case 0x00: Data->SMSC->Format = SMS_FORMAT_Text; break; case 0x22: Data->SMSC->Format = SMS_FORMAT_Fax; break; case 0x26: Data->SMSC->Format = SMS_FORMAT_Pager; break; case 0x32: Data->SMSC->Format = SMS_FORMAT_Email; break; } Data->SMSC->Validity.Format = SMS_Validity_RelativeFormat; Data->SMSC->Validity.Relative = msg.Buffer[12]; + if (msg.Buffer[12] == 0x00) Data->SMSC->Validity.Relative = SMS_VALID_Max_Time; + current = 14; for (i=0;i<msg.Buffer[13];i++) { switch (msg.Buffer[current]) { case 0x81: j=current+4; while (msg.Buffer[j]!=0) {j++;} j=j-33; if (j>GSM_MAX_SMSC_NAME_LENGTH) { @@ -260,17 +265,17 @@ static GSM_Error N6510_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc) static GSM_Error N6510_ReplyGetNetworkInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) { int current = msg.Buffer[7]+7, tmp; GSM_Phone_Data *Data = &s->Phone.Data; #ifdef DEBUG char name[100]; GSM_NetworkInfo NetInfo; - smprintf(s, "Network status: "); + smprintf(s, "Network status : "); switch (msg.Buffer[8]) { case 0x00 : smprintf(s, "home network\n"); break; case 0x01 : smprintf(s, "roaming network\n"); break; case 0x04 : smprintf(s, "not logged"); break; case 0x06 : smprintf(s, "SIM card rejected\n"); break; case 0x09 : smprintf(s, "not logged"); break; default : smprintf(s, "unknown %i!\n",msg.Buffer[8]); break; } @@ -980,21 +985,21 @@ static GSM_Error N6510_ReplyGetWAPBookmark(GSM_Protocol_Message msg, GSM_StateMa return DCT3DCT4_ReplyGetWAPBookmark (msg, s, true); } static GSM_Error N6510_ReplyGetOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s) { GSM_Phone_Data *Data = &s->Phone.Data; smprintf(s, "Operator logo received\n"); + if (msg.Length == 18) return ERR_EMPTY; NOKIA_DecodeNetworkCode(msg.Buffer+12,Data->Bitmap->NetworkCode); smprintf(s, "Network code %s\n",Data->Bitmap->NetworkCode); Data->Bitmap->BitmapWidth = msg.Buffer[20]; Data->Bitmap->BitmapHeight = msg.Buffer[21]; - if (msg.Length == 18) return ERR_EMPTY; PHONE_DecodeBitmap(GSM_Nokia6510OperatorLogo,msg.Buffer+26,Data->Bitmap); return ERR_NONE; } GSM_Error N6510_ReplyDeleteMemory(GSM_Protocol_Message msg, GSM_StateMachine *s) { smprintf(s, "Phonebook entry deleted\n"); return ERR_NONE; @@ -1760,17 +1765,18 @@ static GSM_Error N6510_GetSyncMLSettings(GSM_StateMachine *s, GSM_SyncMLSettings settings->Connection.Location = settings->Location; error = N6510_GetConnectionSettings(s, &settings->Connection, N6510_SYNCML_SETTINGS); if (error != ERR_NONE) return error; settings->Active = settings->Connection.Active; settings->Name[0] = 0; settings->Name[1] = 0; -// s->Phone.Data.SyncMLSettings = settings; + s->Phone.Data.SyncMLSettings = settings; + // smprintf(s, "Getting SyncML settings name\n"); // error = GSM_WaitFor (s, NameReq, 16, 0x43, 4, ID_GetSyncMLName); // if (error != ERR_NONE) return error; req[9] = settings->Location - 1; smprintf(s, "Getting additional SyncML settings\n"); return GSM_WaitFor (s, req, 16, 0x43, 4, ID_GetSyncMLSettings); } @@ -2278,17 +2284,17 @@ static GSM_Error N6510_DeleteSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms smprintf(s, "Deleting sms\n"); return GSM_WaitFor (s, req, 10, 0x14, 4, ID_DeleteSMSMessage); } static GSM_Error N6510_ReplySendSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s) { switch (msg.Buffer[8]) { case 0x00: - smprintf(s, "SMS sent OK, TPMR for sent sms is %02x\n",msg.Buffer[10]); + smprintf(s, "SMS sent OK, TPMR for sent sms is %d\n",msg.Buffer[10]); if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,0,msg.Buffer[10]); return ERR_NONE; default: smprintf(s, "SMS not sent OK, error code probably %i\n",msg.Buffer[8]); if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,msg.Buffer[8],msg.Buffer[10]); return ERR_NONE; } } @@ -2765,16 +2771,17 @@ static GSM_Error N6510_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, error=N6510_PrivGetRingtonesInfo(s, &Info, PhoneRingtone); if (error != ERR_NONE) return error; if (Ringtone->Location > Info.Number) return ERR_INVALIDLOCATION; req2[4] = Info.Ringtone[Ringtone->Location-1].ID / 256; req2[5] = Info.Ringtone[Ringtone->Location-1].ID % 256; smprintf(s, "Getting binary ringtone\n"); return GSM_WaitFor (s, req2, 6, 0x1f, 4, ID_GetRingtone); case RING_MIDI: + case RING_MMF: return ERR_NOTSUPPORTED; } return ERR_NOTSUPPORTED; } static GSM_Error N6510_PlayTone(GSM_StateMachine *s, int Herz, unsigned char Volume, bool start) { GSM_Error error; @@ -2981,16 +2988,19 @@ static GSM_Error N6510_GetProfile(GSM_StateMachine *s, GSM_Profile *Profile) /* For now !!! */ if (!strcmp(s->Phone.Data.ModelInfo->model,"3510")) { if (s->Phone.Data.VerNum>3.37) return ERR_NOTSUPPORTED; } if (!strcmp(s->Phone.Data.ModelInfo->model,"6230")) { return ERR_NOTSUPPORTED; } + if (!strcmp(s->Phone.Data.ModelInfo->model,"5140")) { + return ERR_NOTSUPPORTED; + } if (Profile->Location>5) return ERR_INVALIDLOCATION; for (i = 0; i < 0x0a; i++) { req[length++] = 0x04; req[length++] = Profile->Location; req[length++] = i; req[length++] = 0x01; @@ -3110,19 +3120,31 @@ static GSM_Error N6510_ReplyIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachi s->User.IncomingSMS(s->CurrentConfig->Device,sms); } return ERR_NONE; } static GSM_Error N6510_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber) { + unsigned int pos2 = 15; unsigned int pos = 4; + unsigned char req2[100] = {N6110_FRAME_HEADER,0x01, + 0x00,0x02,0x07,0x04, + 0x01, // 1 - voice, 2 - data + 0x00,0x03, + 0x18, // length of rest + 1 + 0x00,0x00,0x00}; unsigned char req[100] = {N6110_FRAME_HEADER,0x01, 0x0c}; /* Number length */ + GSM_Error error; + + /* USSD not supported */ + if (number[0] == '*') return ERR_NOTSUPPORTED; + if (number[0] == '#') return ERR_NOTSUPPORTED; req[pos++] = strlen(number); EncodeUnicode(req+pos,number,strlen(number)); pos += strlen(number)*2; req[pos++] = 0x05; /* call type: voice - 0x05, data - 0x01 */ req[pos++] = 0x01; req[pos++] = 0x05; req[pos++] = 0x00; @@ -3135,19 +3157,31 @@ static GSM_Error N6510_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShow break; case GSM_CALL_ShowNumber: req[pos++] = 0x03; break; case GSM_CALL_DefaultNumberPresence: req[pos++] = 0x01; break; } + smprintf(s, "Making voice call\n"); + error = GSM_WaitFor (s, req, pos, 0x01, 4, ID_DialVoice); + if (error != ERR_NOTSUPPORTED) return error; + + if (ShowNumber != GSM_CALL_DefaultNumberPresence) return ERR_NOTSUPPORTED; + + req2[11] = strlen(number)*2+6; + req2[pos2++] = strlen(number); + EncodeUnicode(req2+pos2,number,strlen(number)); + pos2 += strlen(number)*2; smprintf(s, "Making voice call\n"); - return GSM_WaitFor (s, req, pos, 0x01, 4, ID_DialVoice); + error = GSM_WaitFor (s, req2, pos2, 0x01, 4, ID_DialVoice); + if (error == ERR_NOTSUPPORTED) return ERR_NONE; + return error; } /* method 3 */ static GSM_Error N6510_ReplyGetCalendarInfo3(GSM_Protocol_Message msg, GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last) { int i=0,j=0; while (Last->Location[j] != 0x00) j++; @@ -3169,55 +3203,61 @@ static GSM_Error N6510_ReplyGetCalendarInfo3(GSM_Protocol_Message msg, GSM_State Last->Location[j] = 0; smprintf(s, "\n"); if (i == 1 && msg.Buffer[12+0*4]*256+msg.Buffer[13+0*4] == 0) return ERR_EMPTY; if (i == 0) return ERR_EMPTY; return ERR_NONE; } /* method 3 */ -static GSM_Error N6510_GetCalendarInfo3(GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last, bool Calendar) +static GSM_Error N6510_GetCalendarInfo3(GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last, char Type) { - GSM_Error error; + GSM_Error error = ERR_UNKNOWN; int i; unsigned char req[] = {N6110_FRAME_HEADER, 0x9E, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, /* First location */ - 0x00}; /* 0 = calendar, 1 = ToDo in 6610 style */ + 0x00}; /* 0 = calendar, 1 = ToDo in 6610 style, 2 = Notes */ Last->Location[0] = 0x00; Last->Number = 0; - if (Calendar) { + req[10] = Type; + if (Type == 0) { smprintf(s, "Getting locations for calendar method 3\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo); - } else { - req[10] = 0x01; + } else if (Type == 1) { smprintf(s, "Getting locations for ToDo method 2\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo); + } else if (Type == 2) { + smprintf(s, "Getting locations for Notes\n"); + error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetNote); } if (error != ERR_NONE && error != ERR_EMPTY) return error; while (1) { i=0; while (Last->Location[i] != 0x00) i++; smprintf(s, "i = %i %i\n",i,Last->Number); if (i == Last->Number) break; if (i != Last->Number && error == ERR_EMPTY) { smprintf(s, "Phone doesn't support some notes with this method. Workaround\n"); Last->Number = i; break; } req[8] = Last->Location[i-1] / 256; req[9] = Last->Location[i-1] % 256; - if (Calendar) { + if (Type == 0) { smprintf(s, "Getting locations for calendar method 3\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo); - } else { + } else if (Type == 1) { smprintf(s, "Getting locations for todo method 2\n"); error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo); + } else if (Type == 2) { + smprintf(s, "Getting locations for Notes\n"); + error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetNote); } if (error != ERR_NONE && error != ERR_EMPTY) return error; } return ERR_NONE; } /* method 3 */ GSM_Error N6510_ReplyGetCalendar3(GSM_Protocol_Message msg, GSM_StateMachine *s) @@ -3345,23 +3385,32 @@ GSM_Error N6510_ReplyGetCalendar3(GSM_Protocol_Message msg, GSM_StateMachine *s) entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2+1] = 0; entry->Entries[entry->EntriesNum].EntryType = CAL_LOCATION; entry->EntriesNum++; } return ERR_NONE; } +static GSM_Error N6510_PrivGetGenericCalendar3(GSM_StateMachine *s, int Location, GSM_Phone_RequestID ID) +{ + unsigned char req[] = {N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00, + 0x00,0x99, /* Location */ + 0xff,0xff,0xff,0xff}; + + req[8] = Location / 256; + req[9] = Location % 256; + + return GSM_WaitFor (s, req, 14, 0x13, 4, ID); +} + static GSM_Error N6510_PrivGetCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start, int *LastCalendarYear) { GSM_Error error; GSM_DateTime date_time; - unsigned char req[] = {N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00, - 0x00,0x99, /* Location */ - 0xff,0xff,0xff,0xff,0x01}; if (start) { /* We have to get current year. It's NOT written in frame for * Birthday */ error=s->Phone.Functions->GetDateTime(s,&date_time); switch (error) { case ERR_EMPTY: @@ -3374,32 +3423,29 @@ static GSM_Error N6510_PrivGetCalendar3(GSM_StateMachine *s, GSM_CalendarEntry * return error; } *LastCalendarYear = date_time.Year; } Note->EntriesNum = 0; Note->Entries[0].Date.Year = *LastCalendarYear; - req[8] = Note->Location / 256; - req[9] = Note->Location % 256; - s->Phone.Data.Cal=Note; smprintf(s, "Getting calendar note method 3\n"); - return GSM_WaitFor (s, req, 15, 0x13, 4, ID_GetCalendarNote); + return N6510_PrivGetGenericCalendar3(s, Note->Location, ID_GetCalendarNote); } /* method 3 */ GSM_Error N6510_GetNextCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start, GSM_NOKIACalToDoLocations *LastCalendar, int *LastCalendarYear, int *LastCalendarPos) { GSM_Error error; bool start2; if (start) { - error=N6510_GetCalendarInfo3(s,LastCalendar,true); + error=N6510_GetCalendarInfo3(s,LastCalendar,0); if (error!=ERR_NONE) return error; if (LastCalendar->Number == 0) return ERR_EMPTY; *LastCalendarPos = 0; } else { (*LastCalendarPos)++; } @@ -3472,34 +3518,34 @@ static GSM_Error N6510_FindCalendarIconID3(GSM_StateMachine *s, GSM_CalendarEntr if (Priv->CalendarIconsTypes[i] == Entry->Type) { *ID = Priv->CalendarIcons[i]; return ERR_NONE; } } smprintf(s, "Starting finding note ID\n"); - error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,true); + error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,0); memcpy(&LastCalendar1,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations)); if (error != ERR_NONE) return error; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL35) || IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL65) || IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) { error=N71_65_AddCalendar2(s,Entry); } else { if (Entry->Type == GSM_CAL_MEETING) { error=N71_65_AddCalendar1(s, Entry, &s->Phone.Data.Priv.N6510.FirstCalendarPos); } else { error=N71_65_AddCalendar2(s,Entry); } } if (error != ERR_NONE) return error; - error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,true); + error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,0); memcpy(&LastCalendar2,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations)); if (error != ERR_NONE) return error; smprintf(s,"Number of entries: %i %i\n",LastCalendar1.Number,LastCalendar2.Number); for(i=0;i<LastCalendar2.Number;i++) { found = true; for(j=0;j<LastCalendar1.Number;j++) { @@ -3732,17 +3778,17 @@ static GSM_Error N6510_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus if (error!=ERR_NONE) return error; Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number; return ERR_NONE; /* Method 2 */ // return ERR_NOTSUPPORTED; } else { /* Method 3 */ - error=N6510_GetCalendarInfo3(s,&s->Phone.Data.Priv.N6510.LastCalendar,true); + error=N6510_GetCalendarInfo3(s,&s->Phone.Data.Priv.N6510.LastCalendar,0); if (error!=ERR_NONE) return error; Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number; return ERR_NONE; } } static GSM_Error N6510_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note) { @@ -3967,16 +4013,52 @@ static GSM_Error N6510_ShowStartInfo(GSM_StateMachine *s, bool enable) error=N6510_SetLight(s,N6510_LIGHT_TORCH,false); if (error != ERR_NONE) return error; return N6510_SetLight(s,N6510_LIGHT_KEYPAD,false); } } +static GSM_Error N6510_ReplyGetNoteInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastNote); +} + +static GSM_Error N6510_ReplyGetNote(GSM_Protocol_Message msg, GSM_StateMachine *s) +{ + smprintf(s, "Note received\n"); + memcpy(s->Phone.Data.Note->Text,msg.Buffer+54,(msg.Buffer[50]*256+msg.Buffer[51])*2); + s->Phone.Data.Note->Text[(msg.Buffer[50]*256+msg.Buffer[51])*2] = 0; + s->Phone.Data.Note->Text[(msg.Buffer[50]*256+msg.Buffer[51])*2+1] = 0; + return ERR_NONE; +} + +GSM_Error N6510_GetNextNote(GSM_StateMachine *s, GSM_NoteEntry *Note, bool start) +{ + GSM_Error error; + GSM_NOKIACalToDoLocations *LastNote = &s->Phone.Data.Priv.N6510.LastNote; + + if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOTES)) return ERR_NOTSUPPORTED; + + if (start) { + error=N6510_GetCalendarInfo3(s,LastNote,2); + if (error!=ERR_NONE) return error; + Note->Location = 1; + } else { + Note->Location++; + } + + if (Note->Location > LastNote->Number) return ERR_EMPTY; + + s->Phone.Data.Note = Note; + smprintf(s, "Getting note\n"); + return N6510_PrivGetGenericCalendar3(s, LastNote->Location[Note->Location-1], ID_GetNote); +} + static int N6510_FindFileCheckSum(unsigned char *ptr, int len) { int acc, i, accx; accx = 0; acc = 0xffff; while (len--) { accx = (accx & 0xffff00ff) | (acc & 0xff00); @@ -4050,17 +4132,17 @@ static GSM_Error N6510_ReplyGetFileFolderInfo(GSM_Protocol_Message msg, GSM_Stat else if (msg.Buffer[i]==0x04 && msg.Buffer[i+2]==0x01) File->Type = GSM_File_Sound_AMR; else if (msg.Buffer[i]==0x04 && msg.Buffer[i+2]==0x02) File->Type = GSM_File_Sound_MIDI; else if (msg.Buffer[i]==0x08 && msg.Buffer[i+2]==0x05) File->Type = GSM_File_Video_3GP; else if (msg.Buffer[i]==0x10 && msg.Buffer[i+2]==0x01) File->Type = GSM_File_Java_JAR; -#if DEVELOP +#ifdef DEVELOP else if (msg.Buffer[i]==0x00 && msg.Buffer[i+2]==0x01) File->Type = GSM_File_MMS; #endif } return ERR_NONE; case 0x2F: smprintf(s,"File or folder used bytes received\n"); File->Used = msg.Buffer[6]*256*256*256+ @@ -4393,17 +4475,17 @@ static GSM_Error N6510_AddFilePart(GSM_StateMachine *s, GSM_File *File, int *Pos 0x00, 0x00, 0x00, 0x00}; if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED; s->Phone.Data.File = File; if (*Pos == 0) { error = N6510_SearchForFileName(s,File); - if (error == ERR_NONE) return ERR_INVALIDLOCATION; + if (error == ERR_NONE) return ERR_FILEALREADYEXIST; if (error != ERR_EMPTY) return error; Header[8] = atoi(File->ID_FullName) / 256; Header[9] = atoi(File->ID_FullName) % 256; memset(Header+14, 0x00, 300); CopyUnicodeString(Header+14,File->Name); Header[222] = File->Used / (256*256*256); Header[223] = File->Used / (256*256); @@ -4809,17 +4891,17 @@ static GSM_Error N6510_GetToDoStatus1(GSM_StateMachine *s, GSM_ToDoStatus *statu return ERR_NONE; } static GSM_Error N6510_GetToDoStatus2(GSM_StateMachine *s, GSM_ToDoStatus *status) { GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo; GSM_Error error; - error = N6510_GetCalendarInfo3(s,LastToDo,false); + error = N6510_GetCalendarInfo3(s,LastToDo,1); if (error!=ERR_NONE) return error; status->Used = LastToDo->Number; return ERR_NONE; } static GSM_Error N6510_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status) { @@ -4939,18 +5021,17 @@ static GSM_Error N6510_ReplyGetToDo2(GSM_Protocol_Message msg, GSM_StateMachine if (msg.Buffer[45] == 0x01) { Last->Entries[2].Number = msg.Buffer[45]; Last->Entries[2].EntryType = TODO_COMPLETED; Last->EntriesNum++; smprintf(s,"Completed\n"); } - if (msg.Buffer[14] == 0xFF && msg.Buffer[15] == 0xFF && msg.Buffer[16] == 0xff && msg.Buffer[17] == 0xff) - { + if (msg.Buffer[14] == 0xFF && msg.Buffer[15] == 0xFF && msg.Buffer[16] == 0xff && msg.Buffer[17] == 0xff) { smprintf(s, "No alarm\n"); } else { diff = ((unsigned int)msg.Buffer[14]) << 24; diff += ((unsigned int)msg.Buffer[15]) << 16; diff += ((unsigned int)msg.Buffer[16]) << 8; diff += msg.Buffer[17]; memcpy(&Last->Entries[Last->EntriesNum].Date,&Date,sizeof(GSM_DateTime)); @@ -4973,38 +5054,30 @@ static GSM_Error N6510_ReplyGetToDo2(GSM_Protocol_Message msg, GSM_StateMachine return ERR_NONE; } /* ToDo support - 6610 style */ static GSM_Error N6510_GetNextToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh) { GSM_Error error; GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo; - /* The same to getting calendar method 3 */ - unsigned char req[] = { - N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00, - 0x00,0x99, /* Location */ - 0xff,0xff,0xff,0xff,0x01}; if (refresh) { - error=N6510_GetCalendarInfo3(s,LastToDo,false); + error=N6510_GetCalendarInfo3(s,LastToDo,1); if (error!=ERR_NONE) return error; ToDo->Location = 1; } else { ToDo->Location++; } if (ToDo->Location > LastToDo->Number) return ERR_EMPTY; - req[8] = LastToDo->Location[ToDo->Location-1] / 256; - req[9] = LastToDo->Location[ToDo->Location-1] % 256; - s->Phone.Data.ToDo = ToDo; smprintf(s, "Getting todo method 2\n"); - return GSM_WaitFor (s, req, 15, 0x13, 4, ID_GetToDo); + return N6510_PrivGetGenericCalendar3(s, LastToDo->Location[ToDo->Location-1], ID_GetToDo); } static GSM_Error N6510_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh) { if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) { return N6510_GetNextToDo1(s, ToDo, refresh); } else if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) { return N6510_GetNextToDo2(s, ToDo, refresh); @@ -5038,17 +5111,17 @@ static GSM_Error N6510_DeleteToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo) GSM_Error error; GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo; GSM_CalendarEntry Note; if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) { return ERR_NOTSUPPORTED; } - error=N6510_GetCalendarInfo3(s,LastToDo,false); + error=N6510_GetCalendarInfo3(s,LastToDo,1); if (error!=ERR_NONE) return error; smprintf(s, "Deleting ToDo method 2\n"); if (ToDo->Location > LastToDo->Number || ToDo->Location == 0) return ERR_INVALIDLOCATION; Note.Location = LastToDo->Location[ToDo->Location-1]; return N71_65_DelCalendar(s,&Note); @@ -5446,23 +5519,29 @@ static GSM_Reply_Function N6510ReplyFunctions[] = { {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_AnswerCall }, {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_CancelCall }, {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0A,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0B,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_DialVoice }, {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_IncomingFrame }, + {N71_65_ReplyCallInfo, "\x01",0x03,0x0F,ID_IncomingFrame }, + {N71_65_ReplyCallInfo, "\x01",0x03,0x10,ID_DialVoice }, + {N71_65_ReplyCallInfo, "\x01",0x03,0x10,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x23,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x25,ID_IncomingFrame }, {N71_65_ReplyCallInfo, "\x01",0x03,0x27,ID_IncomingFrame }, {N71_65_ReplySendDTMF, "\x01",0x03,0x51,ID_SendDTMF }, {N71_65_ReplyCallInfo, "\x01",0x03,0x53,ID_IncomingFrame }, {N71_65_ReplySendDTMF, "\x01",0x03,0x59,ID_SendDTMF }, {N71_65_ReplySendDTMF, "\x01",0x03,0x5E,ID_SendDTMF }, + {N71_65_ReplyCallInfo, "\x01",0x03,0xA6,ID_IncomingFrame }, + {N71_65_ReplyCallInfo, "\x01",0x03,0xD2,ID_IncomingFrame }, + {N71_65_ReplyCallInfo, "\x01",0x03,0xD3,ID_IncomingFrame }, {N6510_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame }, {N6510_ReplyIncomingSMS, "\x02",0x03,0x04,ID_IncomingFrame }, {N6510_ReplySetSMSC, "\x02",0x03,0x13,ID_SetSMSC }, {N6510_ReplyGetSMSC, "\x02",0x03,0x15,ID_GetSMSC }, {N6510_ReplyGetMemoryStatus, "\x03",0x03,0x04,ID_GetMemoryStatus }, {N6510_ReplyGetMemory, "\x03",0x03,0x08,ID_GetMemory }, @@ -5503,23 +5582,25 @@ static GSM_Reply_Function N6510ReplyFunctions[] = { #ifdef DEBUG {N71_65_ReplyGetNextCalendar2, "\x13",0x03,0x3F,ID_GetCalendarNote }, #endif {N71_65_ReplyAddCalendar2, "\x13",0x03,0x41,ID_SetCalendarNote },/*method 2*/ {N6510_ReplyAddCalendar3, "\x13",0x03,0x66,ID_SetCalendarNote },/*method 3*/ {N6510_ReplyAddToDo2, "\x13",0x03,0x66,ID_SetToDo }, {N6510_ReplyGetCalendar3, "\x13",0x03,0x7E,ID_GetCalendarNote },/*method 3*/ {N6510_ReplyGetToDo2, "\x13",0x03,0x7E,ID_GetToDo }, + {N6510_ReplyGetNote, "\x13",0x03,0x7E,ID_GetNote }, {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x86,ID_GetCalendarSettings }, {N6510_ReplyGetLocale, "\x13",0x03,0x8A,ID_GetLocale }, {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x8E,ID_GetCalendarSettings }, {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0x96,ID_GetCalendarNotePos },/*method 3*/ {N6510_ReplyGetToDoFirstLoc2, "\x13",0x03,0x96,ID_SetToDo }, {N6510_ReplyGetCalendarInfo, "\x13",0x03,0x9F,ID_GetCalendarNotesInfo},/*method 3*/ {N6510_ReplyGetToDoStatus2, "\x13",0x03,0x9F,ID_GetToDo }, + {N6510_ReplyGetNoteInfo, "\x13",0x03,0x9F,ID_GetNote }, {N6510_ReplySaveSMSMessage, "\x14",0x03,0x01,ID_SaveSMSMessage }, {N6510_ReplySetPicture, "\x14",0x03,0x01,ID_SetBitmap }, {N6510_ReplyGetSMSMessage, "\x14",0x03,0x03,ID_GetSMSMessage }, {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x05,ID_DeleteSMSMessage }, {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x06,ID_DeleteSMSMessage }, {N6510_ReplyGetSMSStatus, "\x14",0x03,0x09,ID_GetSMSStatus }, {N6510_ReplyGetSMSFolderStatus, "\x14",0x03,0x0d,ID_GetSMSFolderStatus }, @@ -5646,17 +5727,17 @@ static GSM_Reply_Function N6510ReplyFunctions[] = { /* 0xD7 - Bluetooth */ {N6510_ReplyGetRingtoneID, "\xDB",0x03,0x02,ID_SetRingtone }, {NULL, "\x00",0x00,0x00,ID_None } }; GSM_Phone_Functions N6510Phone = { - "1100|1100a|1100b|3100|3100b|3108|3200|3200a|3300|3510|3510i|3530|3589i|3590|3595|5100|6100|6200|6220|6230|6310|6310i|6385|6510|6610|6800|7210|7250|7250i|7600|8310|8390|8910|8910i", + "1100|1100a|1100b|3100|3100b|3108|3200|3200a|3300|3510|3510i|3530|3589i|3590|3595|5100|5140|6100|6200|6220|6230|6310|6310i|6385|6510|6610|6610i|6800|6810|6820|7210|7250|7250i|7600|8310|8390|8910|8910i", N6510ReplyFunctions, N6510_Initialise, NONEFUNCTION, /* Terminate */ GSM_DispatchMessage, N6510_ShowStartInfo, NOKIA_GetManufacturer, DCT3DCT4_GetModel, DCT3DCT4_GetFirmware, @@ -5700,16 +5781,17 @@ GSM_Phone_Functions N6510Phone = { N6510_GetSMSStatus, N6510_GetSMSMessage, N6510_GetNextSMSMessage, N6510_SetSMS, N6510_AddSMS, N6510_DeleteSMSMessage, N6510_SendSMSMessage, NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOKIA_SetIncomingSMS, NOTIMPLEMENTED, /* SetIncomingCB */ N6510_GetSMSFolders, N6510_AddSMSFolder, NOTIMPLEMENTED, /* DeleteSMSFolder */ N6510_DialVoice, N6510_AnswerCall, N6510_CancelCall, @@ -5754,17 +5836,17 @@ GSM_Phone_Functions N6510Phone = { NOTIMPLEMENTED, /* GetCalendar */ N6510_GetNextCalendar, NOTIMPLEMENTED, /* SetCalendar */ N6510_AddCalendar, N71_65_DelCalendar, NOTIMPLEMENTED, /* DeleteAllCalendar */ N6510_GetCalendarSettings, NOTSUPPORTED, /* SetCalendarSettings */ - NOTIMPLEMENTED, /* GetNote */ + N6510_GetNextNote, N6510_GetProfile, N6510_SetProfile, N6510_GetFMStation, N6510_SetFMStation, N6510_ClearFMStations, N6510_GetNextFileFolder, N6510_GetFilePart, N6510_AddFilePart, diff --git a/gammu/emb/common/phone/nokia/dct4/n6510.h b/gammu/emb/common/phone/nokia/dct4/n6510.h index 4717aeb..26623d6 100644 --- a/gammu/emb/common/phone/nokia/dct4/n6510.h +++ b/gammu/emb/common/phone/nokia/dct4/n6510.h @@ -29,16 +29,18 @@ typedef struct { GSM_CalendarNoteType CalendarIconsTypes[10]; int CalendarIconsNum; GSM_NOKIASMSFolder LastSMSFolder; GSM_SMSFolders LastSMSFolders; GSM_NOKIACalToDoLocations LastToDo; + GSM_NOKIACalToDoLocations LastNote; + unsigned char RingtoneID; /* When set with preview */ int FilesLocations[1000]; int FilesLevels[1000]; int FilesLocationsUsed; int FilesLocationsCurrent; int FileToken; int ParentID; diff --git a/gammu/emb/common/phone/nokia/nauto.c b/gammu/emb/common/phone/nokia/nauto.c index bf74bc9..3bb53ec 100644 --- a/gammu/emb/common/phone/nokia/nauto.c +++ b/gammu/emb/common/phone/nokia/nauto.c @@ -116,17 +116,17 @@ GSM_Phone_Functions NAUTOPhone = { NOTSUPPORTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTSUPPORTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTSUPPORTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFilePart */ diff --git a/gammu/emb/common/phone/nokia/nfunc.c b/gammu/emb/common/phone/nokia/nfunc.c index 3acfb10..d4d8b03 100644 --- a/gammu/emb/common/phone/nokia/nfunc.c +++ b/gammu/emb/common/phone/nokia/nfunc.c @@ -1388,16 +1388,21 @@ GSM_Error N71_65_ReplyCallInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) call.CallIDAvailable = false; break; case 0x0c: smprintf(s, "Audio status\n"); if (msg.Buffer[4] == 0x01) smprintf(s, "Audio enabled\n"); else smprintf(s, "Audio disabled\n"); call.CallIDAvailable = false; break; + case 0x0f: + case 0x10: + smprintf(s, "Meaning not known\n"); + call.CallIDAvailable = false; + break; case 0x23: smprintf(s, "Call held\n"); call.Status = GSM_CALL_CallHeld; break; case 0x25: smprintf(s, "Call resumed\n"); call.Status = GSM_CALL_CallResumed; break; @@ -1411,22 +1416,31 @@ GSM_Error N71_65_ReplyCallInfo(GSM_Protocol_Message msg, GSM_StateMachine *s) tmp = 6; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer,buffer,false); smprintf(s, "Number : \"%s\"\n",DecodeUnicodeString(buffer)); /* FIXME: read name from frame */ call.Status = GSM_CALL_OutgoingCall; tmp = 6; NOKIA_GetUnicodeString(s, &tmp, msg.Buffer,call.PhoneNumber,false); break; + case 0xA6: + case 0xD2: + case 0xD3: + smprintf(s, "Meaning not known\n"); + call.CallIDAvailable = false; + break; } if (call.CallIDAvailable) smprintf(s, "Call ID : %d\n",msg.Buffer[4]); if (s->Phone.Data.EnableIncomingCall && s->User.IncomingCall!=NULL && call.Status != 0) { if (call.CallIDAvailable) call.CallID = msg.Buffer[4]; s->User.IncomingCall(s->CurrentConfig->Device, call); } + if (s->Phone.Data.RequestID == ID_DialVoice) { + if (msg.Buffer[3] == 0x10) return ERR_NOTSUPPORTED; + } if (s->Phone.Data.RequestID == ID_CancelCall) { if (msg.Buffer[3] == 0x09) { if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE; /* when we canceled call and see frame about other * call releasing, we don't give ERR_NONE for "our" * call release command */ return ERR_NEEDANOTHERANSWER; diff --git a/gammu/emb/common/phone/obex/obexgen.c b/gammu/emb/common/phone/obex/obexgen.c index dd14f8e..3106369 100644 --- a/gammu/emb/common/phone/obex/obexgen.c +++ b/gammu/emb/common/phone/obex/obexgen.c @@ -769,16 +769,17 @@ GSM_Phone_Functions OBEXGENPhone = { NOTIMPLEMENTED, /* GetSMSStatus */ NOTIMPLEMENTED, /* GetSMS */ NOTIMPLEMENTED, /* GetNextSMS */ NOTIMPLEMENTED, /* SetSMS */ NOTIMPLEMENTED, /* AddSMS */ NOTIMPLEMENTED, /* DeleteSMS */ NOTIMPLEMENTED, /* SendSMSMessage */ NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOTIMPLEMENTED, /* SetIncomingSMS */ NOTIMPLEMENTED, /* SetIncomingCB */ NOTIMPLEMENTED, /* GetSMSFolders */ NOTIMPLEMENTED, /* AddSMSFolder */ NOTIMPLEMENTED, /* DeleteSMSFolder */ NOTIMPLEMENTED, /* DialVoice */ NOTIMPLEMENTED, /* AnswerCall */ NOTIMPLEMENTED, /* CancelCall */ @@ -823,17 +824,17 @@ GSM_Phone_Functions OBEXGENPhone = { NOTIMPLEMENTED, /* GetCalendar */ NOTIMPLEMENTED, /* GetNextCalendar */ NOTIMPLEMENTED, /* SetCalendar */ NOTIMPLEMENTED, /* AddCalendar */ NOTIMPLEMENTED, /* DeleteCalendar */ NOTIMPLEMENTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTIMPLEMENTED, /* GetProfile */ NOTIMPLEMENTED, /* SetProfile */ NOTIMPLEMENTED, /* GetFMStation */ NOTIMPLEMENTED, /* SetFMStation */ NOTIMPLEMENTED, /* ClearFMStations */ OBEXGEN_GetNextFileFolder, OBEXGEN_GetFilePart, OBEXGEN_AddFilePart, diff --git a/gammu/emb/common/phone/obex/obexgen.h b/gammu/emb/common/phone/obex/obexgen.h index 466fef5..b7033de 100644 --- a/gammu/emb/common/phone/obex/obexgen.h +++ b/gammu/emb/common/phone/obex/obexgen.h @@ -26,13 +26,17 @@ typedef struct { int FilesLocationsCurrent; GSM_File Files[500]; bool FileLastPart; int FrameSize; OBEX_Service Service; } GSM_Phone_OBEXGENData; +GSM_Error OBEXGEN_GetFilePart (GSM_StateMachine *s, GSM_File *File); +GSM_Error OBEXGEN_AddFilePart (GSM_StateMachine *s, GSM_File *File, int *Pos); +GSM_Error OBEXGEN_Disconnect (GSM_StateMachine *s); + #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/phone/symbian/mroutgen.c b/gammu/emb/common/phone/symbian/mroutgen.c index 2c339be..a7382cf 100644 --- a/gammu/emb/common/phone/symbian/mroutgen.c +++ b/gammu/emb/common/phone/symbian/mroutgen.c @@ -138,16 +138,17 @@ GSM_Phone_Functions MROUTERGENPhone = { NOTSUPPORTED, /* GetSMSStatus */ NOTSUPPORTED, /* GetSMS */ NOTSUPPORTED, /* GetNextSMS */ NOTSUPPORTED, /* SetSMS */ NOTSUPPORTED, /* AddSMS */ NOTSUPPORTED, /* DeleteSMS */ NOTSUPPORTED, /* SendSMSMessage */ NOTSUPPORTED, /* SendSavedSMS */ + NOTSUPPORTED, /* SetFastSMSSending */ NOTSUPPORTED, /* SetIncomingSMS */ NOTSUPPORTED, /* SetIncomingCB */ NOTSUPPORTED, /* GetSMSFolders */ NOTSUPPORTED, /* AddSMSFolder */ NOTSUPPORTED, /* DeleteSMSFolder */ NOTSUPPORTED, /* DialVoice */ NOTSUPPORTED, /* AnswerCall */ NOTSUPPORTED, /* CancelCall */ @@ -192,17 +193,17 @@ GSM_Phone_Functions MROUTERGENPhone = { NOTSUPPORTED, /* GetCalendar */ NOTSUPPORTED, /* GetNextCalendar */ NOTSUPPORTED, /* SetCalendar */ NOTSUPPORTED, /* AddCalendar */ NOTSUPPORTED, /* DeleteCalendar */ NOTSUPPORTED, /* DeleteAllCalendar */ NOTSUPPORTED, /* GetCalendarSettings */ NOTSUPPORTED, /* SetCalendarSettings */ - NOTSUPPORTED, /* GetNote */ + NOTSUPPORTED, /* GetNextNote */ NOTSUPPORTED, /* GetProfile */ NOTSUPPORTED, /* SetProfile */ NOTSUPPORTED, /* GetFMStation */ NOTSUPPORTED, /* SetFMStation */ NOTSUPPORTED, /* ClearFMStations */ NOTSUPPORTED, /* GetNextFileFolder */ NOTSUPPORTED, /* GetFilePart */ NOTSUPPORTED, /* AddFilePart */ diff --git a/gammu/emb/common/protocol/at/at.c b/gammu/emb/common/protocol/at/at.c index f4a75b7..f8ddc06 100644 --- a/gammu/emb/common/protocol/at/at.c +++ b/gammu/emb/common/protocol/at/at.c @@ -61,24 +61,28 @@ static GSM_Error AT_StateMachine(GSM_StateMachine *s, unsigned char rx_char) /* Some info from phone can be inside "normal" answers * It starts with strings written here */ static SpecialAnswersStruct SpecialAnswers[] = { {"_OSIGQ:" ,1}, {"_OBS:" ,1}, {"^SCN:" ,1}, {"+CGREG:" ,1}, {"+CBM:" ,1}, {"+CMT:" ,2}, {"+CMTI:" ,1}, {"+CDS:" ,2}, - {"+CREG:" ,1}, + {"+CREG:" ,1}, {"+CUSD" ,1}, {"RING" ,1}, {"NO CARRIER" ,1}, {"NO ANSWER" ,1}, {"+COLP" ,1}, {"+CLIP" ,1}, + {"SDNDCRC =" ,1}, /* Samsung binary transfer end */ + {NULL ,1}}; +//printf("%c",rx_char); + /* Ignore leading CR, LF and ESC */ if (d->Msg.Length == 0) { if (rx_char == 10 || rx_char == 13 || rx_char == 27) return ERR_NONE; d->LineStart = d->Msg.Length; } if (d->Msg.BufferUsed < d->Msg.Length + 2) { d->Msg.BufferUsed = d->Msg.Length + 2; diff --git a/gammu/emb/common/protocol/nokia/fbus2.c b/gammu/emb/common/protocol/nokia/fbus2.c index 8b3e024..2b41f8b 100644 --- a/gammu/emb/common/protocol/nokia/fbus2.c +++ b/gammu/emb/common/protocol/nokia/fbus2.c @@ -1,10 +1,14 @@ /* (c) 2002-2003 by Marcin Wiacek */ -/* based on some work from Gnokii and MyGnokii */ +/* based on some work from MyGnokii (www.mwiacek.com) */ +/* Based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include "../../gsmstate.h" #if defined(GSM_ENABLE_FBUS2) || defined(GSM_ENABLE_FBUS2IRDA) || defined(GSM_ENABLE_FBUS2DLR3) || defined(GSM_ENABLE_FBUS2BLUE) || defined(GSM_ENABLE_BLUEFBUS2) || defined(GSM_ENABLE_FBUS2DKU5) || defined(GSM_ENABLE_FBUS2PL2303) #include <stdio.h> #include <string.h> diff --git a/gammu/emb/common/protocol/nokia/fbus2.h b/gammu/emb/common/protocol/nokia/fbus2.h index 5dd45d7..8dbcb07 100644 --- a/gammu/emb/common/protocol/nokia/fbus2.h +++ b/gammu/emb/common/protocol/nokia/fbus2.h @@ -1,10 +1,14 @@ /* (c) 2002-2003 by Marcin Wiacek */ -/* based on some work from Gnokii and MyGnokii */ +/* based on some work from MyGnokii (www.mwiacek.com) */ +/* Based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #ifndef fbus2_h #define fbus2_h #include "../protocol.h" #define FBUS2_FRAME_ID 0x1e #define FBUS2_IRDA_FRAME_ID 0x1c diff --git a/gammu/emb/common/protocol/nokia/mbus2.c b/gammu/emb/common/protocol/nokia/mbus2.c index f07d6c5..8353b46 100644 --- a/gammu/emb/common/protocol/nokia/mbus2.c +++ b/gammu/emb/common/protocol/nokia/mbus2.c @@ -1,10 +1,10 @@ /* (c) 2001-2003 by Marcin Wiacek */ -/* based on some work from MyGnokii */ +/* based on some work from MyGnokii (www.mwiacek.com) */ #include "../../gsmstate.h" #ifdef GSM_ENABLE_MBUS2 #include <stdio.h> #include <string.h> diff --git a/gammu/emb/common/protocol/nokia/mbus2.h b/gammu/emb/common/protocol/nokia/mbus2.h index 86fcab6..5dbd8cb 100644 --- a/gammu/emb/common/protocol/nokia/mbus2.h +++ b/gammu/emb/common/protocol/nokia/mbus2.h @@ -1,10 +1,10 @@ /* (c) 2001-2003 by Marcin Wiacek */ -/* based on some work from MyGnokii */ +/* based on some work from MyGnokii (www.mwiacek.com) */ #ifndef mbus2_h #define mbus2_h #include "../protocol.h" #define MBUS2_FRAME_ID 0x1f #define MBUS2_DEVICE_PHONE 0x00 /* Nokia mobile phone */ diff --git a/gammu/emb/common/protocol/nokia/phonet.c b/gammu/emb/common/protocol/nokia/phonet.c index bc5717d..db5bd72 100644 --- a/gammu/emb/common/protocol/nokia/phonet.c +++ b/gammu/emb/common/protocol/nokia/phonet.c @@ -1,10 +1,13 @@ /* (c) 2002-2003 by Marcin Wiacek */ -/* based on some work from Gnokii */ +/* Based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include "../../gsmstate.h" #if defined(GSM_ENABLE_IRDA) || defined(GSM_ENABLE_PHONETBLUE) || defined(GSM_ENABLE_BLUEPHONET) #include <stdio.h> #include <string.h> diff --git a/gammu/emb/common/protocol/nokia/phonet.h b/gammu/emb/common/protocol/nokia/phonet.h index 2f6e836..e750bbd 100644 --- a/gammu/emb/common/protocol/nokia/phonet.h +++ b/gammu/emb/common/protocol/nokia/phonet.h @@ -1,10 +1,13 @@ /* (c) 2002-2003 by Marcin Wiacek */ -/* based on some work from Gnokii */ +/* Based on some work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #ifndef PHONET_h #define PHONET_h #include "../protocol.h" #define PHONET_FRAME_ID 0x14 #define PHONET_BLUE_FRAME_ID 0x19 diff --git a/gammu/emb/common/service/backup/backgen.h b/gammu/emb/common/service/backup/backgen.h index 9d7d973..9a930fc 100644 --- a/gammu/emb/common/service/backup/backgen.h +++ b/gammu/emb/common/service/backup/backgen.h @@ -16,16 +16,18 @@ #define GSM_BACKUP_MAX_PHONEPHONEBOOK 501 #define GSM_BACKUP_MAX_SIMPHONEBOOK 251 #define GSM_BACKUP_MAX_CALLER 6 #define GSM_BACKUP_MAX_SMSC 10 #define GSM_BACKUP_MAX_WAPBOOKMARK 40 #define GSM_BACKUP_MAX_WAPSETTINGS 30 #define GSM_BACKUP_MAX_MMSSETTINGS 30 +#define GSM_BACKUP_MAX_SYNCMLSETTINGS 10 +#define GSM_BACKUP_MAX_CHATSETTINGS 10 #define GSM_BACKUP_MAX_RINGTONES 30 #define GSM_BACKUP_MAX_PROFILES 10 #define GSM_BACKUP_MAX_FMSTATIONS 20 #define GSM_BACKUP_MAX_GPRSPOINT 10 #define GSM_BACKUP_MAX_NOTE 10 /* FIXME */ typedef struct { char IMEI [MAX_IMEI_LENGTH]; @@ -38,16 +40,18 @@ typedef struct { GSM_MemoryEntry *PhonePhonebook [GSM_BACKUP_MAX_PHONEPHONEBOOK + 1]; GSM_MemoryEntry *SIMPhonebook [GSM_BACKUP_MAX_SIMPHONEBOOK + 1]; GSM_CalendarEntry *Calendar [GSM_MAXCALENDARTODONOTES + 1]; GSM_Bitmap *CallerLogos [GSM_BACKUP_MAX_CALLER + 1]; GSM_SMSC *SMSC [GSM_BACKUP_MAX_SMSC + 1]; GSM_WAPBookmark *WAPBookmark [GSM_BACKUP_MAX_WAPBOOKMARK + 1]; GSM_MultiWAPSettings *WAPSettings [GSM_BACKUP_MAX_WAPSETTINGS + 1]; GSM_MultiWAPSettings *MMSSettings [GSM_BACKUP_MAX_MMSSETTINGS + 1]; + GSM_SyncMLSettings *SyncMLSettings [GSM_BACKUP_MAX_SYNCMLSETTINGS + 1]; + GSM_ChatSettings *ChatSettings [GSM_BACKUP_MAX_CHATSETTINGS + 1]; GSM_Ringtone *Ringtone [GSM_BACKUP_MAX_RINGTONES + 1]; GSM_ToDoEntry *ToDo [GSM_MAXCALENDARTODONOTES + 1]; GSM_Profile *Profiles [GSM_BACKUP_MAX_PROFILES + 1]; GSM_FMStation *FMStation [GSM_BACKUP_MAX_FMSTATIONS +1]; GSM_GPRSAccessPoint *GPRSPoint [GSM_BACKUP_MAX_GPRSPOINT + 1]; GSM_NoteEntry *Note [GSM_BACKUP_MAX_NOTE + 1]; GSM_Bitmap *StartupLogo; GSM_Bitmap *OperatorLogo; diff --git a/gammu/emb/common/service/backup/backtext.c b/gammu/emb/common/service/backup/backtext.c index fee0f73..4cb1bb7 100644 --- a/gammu/emb/common/service/backup/backtext.c +++ b/gammu/emb/common/service/backup/backtext.c @@ -146,42 +146,43 @@ static void SaveBackupText(FILE *file, char *myname, char *myvalue, bool UseUnic fwrite(buffer,1,strlen(myvalue)*2,file); } else fprintf(file,"%s",myvalue); } else { if (UseUnicode) { sprintf(buffer,"%s = \"",myname); EncodeUnicode(buffer2,buffer,strlen(buffer)); fwrite(buffer2,1,strlen(buffer)*2,file); - fwrite(myvalue,1,UnicodeLength(myvalue)*2,file); + fwrite(EncodeUnicodeSpecialChars(myvalue),1,UnicodeLength(EncodeUnicodeSpecialChars(myvalue))*2,file); sprintf(buffer,"\"%c%c",13,10); EncodeUnicode(buffer2,buffer,strlen(buffer)); fwrite(buffer2,1,strlen(buffer)*2,file); } else { - sprintf(buffer,"%s = \"%s\"%c%c",myname,DecodeUnicodeString(myvalue),13,10); + sprintf(buffer,"%s = \"%s\"%c%c",myname,EncodeSpecialChars(DecodeUnicodeString(myvalue)),13,10); fprintf(file,"%s",buffer); EncodeHexBin(buffer,myvalue,UnicodeLength(myvalue)*2); fprintf(file,"%sUnicode = %s%c%c",myname,buffer,13,10); } } } static bool ReadBackupText(INI_Section *file_info, char *section, char *myname, char *myvalue, bool UseUnicode) { - unsigned char paramname[10000],*readvalue; + unsigned char paramname[10000],*readvalue; if (UseUnicode) { EncodeUnicode(paramname,myname,strlen(myname)); readvalue = INI_GetValue(file_info, section, paramname, UseUnicode); if (readvalue!=NULL) { - CopyUnicodeString(myvalue,readvalue+2); - myvalue[UnicodeLength(readvalue)*2-4]=0; - myvalue[UnicodeLength(readvalue)*2-3]=0; + CopyUnicodeString(myvalue,DecodeUnicodeSpecialChars(readvalue+2)); + myvalue[UnicodeLength(myvalue)*2-2]=0; + myvalue[UnicodeLength(myvalue)*2-1]=0; + dbgprintf("%s\n",DecodeUnicodeString(readvalue)); } else { myvalue[0]=0; myvalue[1]=0; return false; } } else { strcpy(paramname,myname); @@ -192,17 +193,17 @@ static bool ReadBackupText(INI_Section *file_info, char *section, char *myname, DecodeHexBin (myvalue, readvalue, strlen(readvalue)); myvalue[strlen(readvalue)/2]=0; myvalue[strlen(readvalue)/2+1]=0; dbgprintf("%s\n",DecodeUnicodeString(myvalue)); } else { strcpy(paramname,myname); readvalue = ReadCFGText(file_info, section, paramname, UseUnicode); if (readvalue!=NULL) { - EncodeUnicode(myvalue,readvalue+1,strlen(readvalue)-2); + EncodeUnicode(myvalue,DecodeSpecialChars(readvalue+1),strlen(DecodeSpecialChars(readvalue+1))-1); } else { myvalue[0]=0; myvalue[1]=0; return false; } } } return true; @@ -413,34 +414,45 @@ static void SavePbkEntry(FILE *file, GSM_MemoryEntry *Pbk, bool UseUnicode) default: break; } } sprintf(buffer,"%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); } +static void SaveNoteEntry(FILE *file, GSM_NoteEntry *Note, bool UseUnicode) +{ + char buffer[1000]; + + sprintf(buffer,"Location = %d%c%c", Note->Location,13,10); + SaveBackupText(file, "", buffer, UseUnicode); + SaveBackupText(file, "Text", Note->Text, UseUnicode); + sprintf(buffer, "%c%c",13,10); + SaveBackupText(file, "", buffer, UseUnicode); +} + static void SaveCalendarEntry(FILE *file, GSM_CalendarEntry *Note, bool UseUnicode) { int i; char buffer[1000]; sprintf(buffer,"Location = %d%c%c", Note->Location,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveBackupText(file, "", "Type = ", UseUnicode); switch (Note->Type) { case GSM_CAL_REMINDER : sprintf(buffer,"Reminder%c%c", 13,10); break; case GSM_CAL_CALL : sprintf(buffer,"Call%c%c", 13,10); break; case GSM_CAL_MEETING : sprintf(buffer,"Meeting%c%c", 13,10); break; case GSM_CAL_BIRTHDAY : sprintf(buffer,"Birthday%c%c", 13,10); break; case GSM_CAL_TRAVEL : sprintf(buffer,"Travel%c%c", 13,10); break; case GSM_CAL_VACATION : sprintf(buffer,"Vacation%c%c", 13,10); break; - case GSM_CAL_MEMO : sprintf(buffer,"Memo%c%c", 13,10); break; + case GSM_CAL_MEMO : sprintf(buffer,"Memo%c%c", 13,10); break; case GSM_CAL_ALARM : sprintf(buffer,"Alarm%c%c", 13,10); break; - case GSM_CAL_DAILY_ALARM : sprintf(buffer,"DailyAlarm%c%c", 13,10); break; + case GSM_CAL_DAILY_ALARM: sprintf(buffer,"DailyAlarm%c%c", 13,10); break; case GSM_CAL_T_ATHL : sprintf(buffer,"Training/Athletism%c%c", 13,10); break; case GSM_CAL_T_BALL : sprintf(buffer,"Training/BallGames%c%c", 13,10); break; case GSM_CAL_T_CYCL : sprintf(buffer,"Training/Cycling%c%c", 13,10); break; case GSM_CAL_T_BUDO : sprintf(buffer,"Training/Budo%c%c", 13,10); break; case GSM_CAL_T_DANC : sprintf(buffer,"Training/Dance%c%c", 13,10); break; case GSM_CAL_T_EXTR : sprintf(buffer,"Training/ExtremeSports%c%c", 13,10); break; case GSM_CAL_T_FOOT : sprintf(buffer,"Training/Football%c%c", 13,10); break; case GSM_CAL_T_GOLF : sprintf(buffer,"Training/Golf%c%c", 13,10); break; @@ -652,16 +664,58 @@ static void SaveWAPSettingsEntry(FILE *file, GSM_MultiWAPSettings *settings, boo } SaveBackupText(file, buffer, settings->Settings[i].Service, UseUnicode); } sprintf(buffer,"%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); } } +static void SaveChatSettingsEntry(FILE *file, GSM_ChatSettings *settings, bool UseUnicode) +{ + char buffer[10000]; + + sprintf(buffer,"HomePage"); + SaveBackupText(file, buffer, settings->HomePage, UseUnicode); + sprintf(buffer,"User"); + SaveBackupText(file, buffer, settings->User, UseUnicode); + sprintf(buffer,"Password"); + SaveBackupText(file, buffer, settings->Password, UseUnicode); + SaveWAPSettingsEntry(file, &settings->Connection, UseUnicode); +} + +static void SaveSyncMLSettingsEntry(FILE *file, GSM_SyncMLSettings *settings, bool UseUnicode) +{ + char buffer[10000]; + + sprintf(buffer,"User"); + SaveBackupText(file, buffer, settings->User, UseUnicode); + sprintf(buffer,"Password"); + SaveBackupText(file, buffer, settings->Password, UseUnicode); + sprintf(buffer,"PhonebookDB"); + SaveBackupText(file, buffer, settings->PhonebookDataBase, UseUnicode); + sprintf(buffer,"CalendarDB"); + SaveBackupText(file, buffer, settings->CalendarDataBase, UseUnicode); + sprintf(buffer,"Server"); + SaveBackupText(file, buffer, settings->Server, UseUnicode); + if (settings->SyncPhonebook) { + sprintf(buffer,"SyncPhonebook = True%c%c",13,10); + } else { + sprintf(buffer,"SyncPhonebook = False%c%c",13,10); + } + SaveBackupText(file, "", buffer, UseUnicode); + if (settings->SyncCalendar) { + sprintf(buffer,"SyncCalendar = True%c%c",13,10); + } else { + sprintf(buffer,"SyncCalendar = False%c%c",13,10); + } + SaveBackupText(file, "", buffer, UseUnicode); + SaveWAPSettingsEntry(file, &settings->Connection, UseUnicode); +} + static void SaveBitmapEntry(FILE *file, GSM_Bitmap *bitmap, bool UseUnicode) { unsigned char buffer[10000],buffer2[10000]; int x,y; sprintf(buffer,"Width = %i%c%c",bitmap->BitmapWidth,13,10); SaveBackupText(file, "", buffer, UseUnicode); sprintf(buffer,"Height = %i%c%c",bitmap->BitmapHeight,13,10); @@ -759,33 +813,34 @@ static void SaveSMSCEntry(FILE *file, GSM_SMSC *SMSC, bool UseUnicode) } SaveBackupText(file, "", buffer, UseUnicode); sprintf(buffer,"%c%c%c%c",13,10,13,10); SaveBackupText(file, "", buffer, UseUnicode); } static void SaveRingtoneEntry(FILE *file, GSM_Ringtone *ringtone, bool UseUnicode) { - unsigned char buffer[45000]; - int i,j; + unsigned char buffer[45000]; sprintf(buffer,"Location = %i%c%c",ringtone->Location,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveBackupText(file, "Name", ringtone->Name, UseUnicode); switch (ringtone->Format) { case RING_NOKIABINARY: - j = 0; i = 0; EncodeHexBin(buffer,ringtone->NokiaBinary.Frame,ringtone->NokiaBinary.Length); SaveLinkedBackupText(file, "NokiaBinary", buffer, UseUnicode); break; case RING_MIDI: - j = 0; i = 0; EncodeHexBin(buffer,ringtone->NokiaBinary.Frame,ringtone->NokiaBinary.Length); SaveLinkedBackupText(file, "Pure Midi", buffer, UseUnicode); break; + case RING_MMF: + EncodeHexBin(buffer,ringtone->NokiaBinary.Frame,ringtone->NokiaBinary.Length); + SaveLinkedBackupText(file, "SMAF", buffer, UseUnicode); + break; case RING_NOTETONE: break; } sprintf(buffer,"%c%c",13,10); SaveBackupText(file, "", buffer, UseUnicode); } static void SaveOperatorEntry(FILE *file, GSM_Bitmap *bitmap, bool UseUnicode) @@ -1070,16 +1125,23 @@ GSM_Error SaveBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) i=0; while (backup->Calendar[i]!=NULL) { sprintf(buffer,"[Calendar%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveCalendarEntry(file, backup->Calendar[i], UseUnicode); i++; } i=0; + while (backup->Note[i]!=NULL) { + sprintf(buffer,"[Note%03i]%c%c",i+1,13,10); + SaveBackupText(file, "", buffer, UseUnicode); + SaveNoteEntry(file, backup->Note[i], UseUnicode); + i++; + } + i=0; while (backup->CallerLogos[i]!=NULL) { sprintf(buffer,"[Caller%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveCallerEntry(file, backup->CallerLogos[i], UseUnicode); i++; } i=0; while (backup->SMSC[i]!=NULL) { @@ -1105,16 +1167,30 @@ GSM_Error SaveBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) i=0; while (backup->MMSSettings[i]!=NULL) { sprintf(buffer,"[MMSSettings%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveWAPSettingsEntry(file, backup->MMSSettings[i], UseUnicode); i++; } i=0; + while (backup->SyncMLSettings[i]!=NULL) { + sprintf(buffer,"[SyncMLSettings%03i]%c%c",i+1,13,10); + SaveBackupText(file, "", buffer, UseUnicode); + SaveSyncMLSettingsEntry(file, backup->SyncMLSettings[i], UseUnicode); + i++; + } + i=0; + while (backup->ChatSettings[i]!=NULL) { + sprintf(buffer,"[ChatSettings%03i]%c%c",i+1,13,10); + SaveBackupText(file, "", buffer, UseUnicode); + SaveChatSettingsEntry(file, backup->ChatSettings[i], UseUnicode); + i++; + } + i=0; while (backup->Ringtone[i]!=NULL) { sprintf(buffer,"[Ringtone%03i]%c%c",i+1,13,10); SaveBackupText(file, "", buffer, UseUnicode); SaveRingtoneEntry(file, backup->Ringtone[i], UseUnicode); i++; } i=0; while (backup->ToDo[i]!=NULL) { @@ -2651,17 +2727,142 @@ GSM_Error LoadBackup(char *FileName, GSM_Backup *backup, bool UseUnicode) } ReadNoteEntry(file_info, h->SectionName, backup->Note[num],UseUnicode); num++; } } if (backup->MD5Original[0]!=0) { FindBackupChecksum(FileName, UseUnicode, backup->MD5Calculated); } - + for (h = file_info; h != NULL; h = h->Next) { + found = false; + if (UseUnicode) { + EncodeUnicode(buffer,"Backup",4); + if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; + } else { + if (mystrncasecmp("Backup", h->SectionName, 6)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Checksum",4); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("Checksum", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Profile",7); + if (mywstrncasecmp(buffer, h->SectionName, 7)) found = true; + } else { + if (mystrncasecmp("Profile", h->SectionName, 7)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"PhonePBK",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("PhonePBK", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"SIMPBK",6); + if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; + } else { + if (mystrncasecmp("SIMPBK", h->SectionName, 6)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Calendar",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("Calendar", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Caller",6); + if (mywstrncasecmp(buffer, h->SectionName, 6)) found = true; + } else { + if (mystrncasecmp("Caller", h->SectionName, 6)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"SMSC",4); + if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; + } else { + if (mystrncasecmp("SMSC", h->SectionName, 4)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"WAPBookmark",11); + if (mywstrncasecmp(buffer, h->SectionName, 11)) found = true; + if (!found) { + EncodeUnicode(buffer,"Bookmark",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } + } else { + if (mystrncasecmp("WAPBookmark", h->SectionName, 11)) found = true; + if (!found) { + if (mystrncasecmp("Bookmark", h->SectionName, 8)) found = true; + } + } + if (UseUnicode) { + EncodeUnicode(buffer,"WAPSettings",11); + if (mywstrncasecmp(buffer, h->SectionName, 11)) found = true; + if (!found) { + EncodeUnicode(buffer,"Settings",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } + } else { + if (mystrncasecmp("WAPSettings", h->SectionName, 11)) found = true; + if (!found) { + if (mystrncasecmp("Settings", h->SectionName, 8)) found = true; + } + } + if (UseUnicode) { + EncodeUnicode(buffer,"MMSSettings",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("MMSSettings", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Ringtone",8); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("Ringtone", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"TODO",4); + if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; + } else { + if (mystrncasecmp("TODO", h->SectionName, 4)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Startup",7); + if (mywstrncasecmp(buffer, h->SectionName, 7)) found = true; + } else { + if (mystrncasecmp("Startup", h->SectionName, 7)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Operator",7); + if (mywstrncasecmp(buffer, h->SectionName, 8)) found = true; + } else { + if (mystrncasecmp("Operator", h->SectionName, 8)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"FMStation",9); + if (mywstrncasecmp(buffer, h->SectionName, 9)) found = true; + } else { + if (mystrncasecmp("FMStation", h->SectionName, 9)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"GPRSPoint",9); + if (mywstrncasecmp(buffer, h->SectionName, 9)) found = true; + } else { + if (mystrncasecmp("GPRSPoint", h->SectionName, 9)) found = true; + } + if (UseUnicode) { + EncodeUnicode(buffer,"Note",4); + if (mywstrncasecmp(buffer, h->SectionName, 4)) found = true; + } else { + if (mystrncasecmp("Note", h->SectionName, 4)) found = true; + } + if (!found) return ERR_NOTIMPLEMENTED; + } return ERR_NONE; } /* ---------------------- backup files for SMS ----------------------------- */ static void ReadSMSBackupEntry(INI_Section *file_info, char *section, GSM_SMSMessage *SMS) { unsigned char buffer[10000], *readvalue; diff --git a/gammu/emb/common/service/backup/gsmback.c b/gammu/emb/common/service/backup/gsmback.c index 91ac745..c94a4d2 100644 --- a/gammu/emb/common/service/backup/gsmback.c +++ b/gammu/emb/common/service/backup/gsmback.c @@ -68,16 +68,28 @@ void GSM_FreeBackup(GSM_Backup *backup) } i=0; while (backup->MMSSettings[i]!=NULL) { free(backup->MMSSettings[i]); backup->MMSSettings[i] = NULL; i++; } i=0; + while (backup->SyncMLSettings[i]!=NULL) { + free(backup->SyncMLSettings[i]); + backup->SyncMLSettings[i] = NULL; + i++; + } + i=0; + while (backup->ChatSettings[i]!=NULL) { + free(backup->ChatSettings[i]); + backup->ChatSettings[i] = NULL; + i++; + } + i=0; while (backup->Ringtone[i]!=NULL) { free(backup->Ringtone[i]); backup->Ringtone[i] = NULL; i++; } i=0; while (backup->ToDo[i]!=NULL) { free(backup->ToDo[i]); @@ -115,25 +127,25 @@ void GSM_FreeBackup(GSM_Backup *backup) free(backup->Note[i]); backup->Note[i] = NULL; i++; } } GSM_Error GSM_SaveBackupFile(char *FileName, GSM_Backup *backup, bool UseUnicode) { - if (strstr(FileName,".lmb")) { + if (mystrcasestr(FileName,".lmb")) { return SaveLMB(FileName,backup); - } else if (strstr(FileName,".vcs")) { + } else if (mystrcasestr(FileName,".vcs")) { return SaveVCalendar(FileName,backup); - } else if (strstr(FileName,".vcf")) { + } else if (mystrcasestr(FileName,".vcf")) { return SaveVCard(FileName,backup); - } else if (strstr(FileName,".ldif")) { + } else if (mystrcasestr(FileName,".ldif")) { return SaveLDIF(FileName,backup); - } else if (strstr(FileName,".ics")) { + } else if (mystrcasestr(FileName,".ics")) { return SaveICS(FileName,backup); } else { return SaveBackup(FileName,backup, UseUnicode); } } GSM_Error GSM_ReadBackupFile(char *FileName, GSM_Backup *backup) { @@ -143,23 +155,23 @@ GSM_Error GSM_ReadBackupFile(char *FileName, GSM_Backup *backup) file = fopen(FileName, "rb"); if (file == NULL) return ERR_CANTOPENFILE; fread(buffer, 1, 9, file); /* Read the header of the file. */ fclose(file); GSM_ClearBackup(backup); /* Attempt to identify filetype */ - if (strstr(FileName,".vcs")) { + if (mystrcasestr(FileName,".vcs")) { return LoadVCalendar(FileName,backup); - } else if (strstr(FileName,".vcf")) { + } else if (mystrcasestr(FileName,".vcf")) { return LoadVCard(FileName,backup); - } else if (strstr(FileName,".ldif")) { + } else if (mystrcasestr(FileName,".ldif")) { return LoadLDIF(FileName,backup); - } else if (strstr(FileName,".ics")) { + } else if (mystrcasestr(FileName,".ics")) { return LoadICS(FileName,backup); } else if (memcmp(buffer, "LMB ",4)==0) { return LoadLMB(FileName,backup); } else if (buffer[0] == 0xFE && buffer[1] == 0xFF) { return LoadBackup(FileName,backup,true); } else if (buffer[0] == 0xFF && buffer[1] == 0xFE) { return LoadBackup(FileName,backup,true); } else { @@ -172,16 +184,18 @@ void GSM_ClearBackup(GSM_Backup *backup) backup->PhonePhonebook [0] = NULL; backup->SIMPhonebook [0] = NULL; backup->Calendar [0] = NULL; backup->CallerLogos [0] = NULL; backup->SMSC [0] = NULL; backup->WAPBookmark [0] = NULL; backup->WAPSettings [0] = NULL; backup->MMSSettings [0] = NULL; + backup->SyncMLSettings [0] = NULL; + backup->ChatSettings [0] = NULL; backup->Ringtone [0] = NULL; backup->Profiles [0] = NULL; backup->ToDo [0] = NULL; backup->GPRSPoint [0] = NULL; backup->FMStation [0] = NULL; backup->Note [0] = NULL; backup->StartupLogo = NULL; backup->OperatorLogo = NULL; @@ -204,16 +218,18 @@ void GSM_GetBackupFormatFeatures(char *FileName, GSM_Backup_Info *info) info->SIMPhonebook = false; info->ToDo = false; info->Calendar = false; info->CallerLogos = false; info->SMSC = false; info->WAPBookmark = false; info->WAPSettings = false; info->MMSSettings = false; + info->SyncMLSettings = false; + info->ChatSettings = false; info->Ringtone = false; info->StartupLogo = false; info->OperatorLogo = false; info->Profiles = false; info->FMStation = false; info->GPRSPoint = false; info->Note = false; @@ -241,16 +257,18 @@ void GSM_GetBackupFormatFeatures(char *FileName, GSM_Backup_Info *info) info->SIMPhonebook = true; info->ToDo = true; info->Calendar = true; info->CallerLogos = true; info->SMSC = true; info->WAPBookmark = true; info->WAPSettings = true; info->MMSSettings = true; + info->SyncMLSettings = true; + info->ChatSettings = true; info->Ringtone = true; info->StartupLogo = true; info->OperatorLogo = true; info->Profiles = true; info->FMStation = true; info->GPRSPoint = true; info->Note = true; } diff --git a/gammu/emb/common/service/backup/gsmback.h b/gammu/emb/common/service/backup/gsmback.h index 1fd99b0..791e81d 100644 --- a/gammu/emb/common/service/backup/gsmback.h +++ b/gammu/emb/common/service/backup/gsmback.h @@ -24,16 +24,18 @@ typedef struct { bool SIMPhonebook; bool Calendar; bool CallerLogos; bool SMSC; bool WAPBookmark; bool Profiles; bool WAPSettings; bool MMSSettings; + bool SyncMLSettings; + bool ChatSettings; bool Ringtone; bool StartupLogo; bool OperatorLogo; bool FMStation; bool GPRSPoint; bool Note; } GSM_Backup_Info; diff --git a/gammu/emb/common/service/gsmcal.h b/gammu/emb/common/service/gsmcal.h index 067a4a4..0a41b7b 100644 --- a/gammu/emb/common/service/gsmcal.h +++ b/gammu/emb/common/service/gsmcal.h @@ -400,17 +400,17 @@ typedef struct { */ int Used; } GSM_ToDoStatus; /* --------------------------- note ---------------------------------------- */ typedef struct { int Location; - char Text[100]; + char Text[3000*2]; } GSM_NoteEntry; GSM_Error GSM_EncodeVNTFile(unsigned char *Buffer, int *Length, GSM_NoteEntry *Note); /* --------------------------- alarm --------------------------------------- */ /** * Alarm values. diff --git a/gammu/emb/common/service/gsmdata.c b/gammu/emb/common/service/gsmdata.c index 94e9b7b..9303b57 100644 --- a/gammu/emb/common/service/gsmdata.c +++ b/gammu/emb/common/service/gsmdata.c @@ -241,63 +241,141 @@ void NOKIA_EncodeWAPMMSSettingsSMSText(unsigned char *Buffer, int *Length, GSM_W Buffer[(*Length)++] = 0x01; //END PARMeter /* Settings name */ AddWAPSMSParameterText(Buffer, Length, 0x15, DecodeUnicodeString(settings->Title), UnicodeLength(settings->Title)); Buffer[(*Length)++] = 0x01; //END PARMeter Buffer[(*Length)++] = 0x01; //END PARMeter } /* http://forum.nokia.com: OTA Settings 7.0 */ +/* first it used default/ISO coding */ +/* Joergen Thomsen changed to UTF8 */ void NOKIA_EncodeWAPBookmarkSMSText(unsigned char *Buffer, int *Length, GSM_WAPBookmark *bookmark) { unsigned char buffer[100]; - bool UnicodeCoding = false; - EncodeUTF8QuotedPrintable(buffer,bookmark->Title); - if (UnicodeLength(bookmark->Title)!=strlen(buffer)) UnicodeCoding = true; +// bool UnicodeCoding = false; +// EncodeUTF8QuotedPrintable(buffer,bookmark->Title); +// if (UnicodeLength(bookmark->Title)!=strlen(buffer)) UnicodeCoding = true; Buffer[(*Length)++] = 0x01; //Push ID Buffer[(*Length)++] = 0x06; //PDU Type (push) Buffer[(*Length)++] = 0x2D; //Headers length (content type + headers) strcpy(Buffer+(*Length),"\x1F\x2B"); (*Length)=(*Length)+2; //Value length strcpy(Buffer+(*Length),"application/x-wap-prov.browser-bookmarks"); (*Length)=(*Length)+40; //MIME-Type Buffer[(*Length)++] = 0x00; //end inline string strcpy(Buffer+(*Length),"\x81\xEA"); (*Length)=(*Length)+2; //charset UTF-8 short int. + /* removed by Joergen Thomsen */ /* Block from sniffs. UNKNOWN */ - if (!UnicodeCoding) { - Buffer[(*Length)++] = 0x00; - Buffer[(*Length)++] = 0x01; - } else { - strcpy(Buffer+(*Length),"\x01\x01\x87\x68"); - (*Length)=(*Length)+4; - } - Buffer[(*Length)++] = 0x00; +// if (!UnicodeCoding) { +// Buffer[(*Length)++] = 0x00; +// Buffer[(*Length)++] = 0x01; +// } else { +// strcpy(Buffer+(*Length),"\x01\x01\x87\x68"); +// (*Length)=(*Length)+4; +// } +// Buffer[(*Length)++] = 0x00; + + /* added by Joergen Thomsen */ + Buffer[(*Length)++] = 0x01; // Version WBXML 1.1 + Buffer[(*Length)++] = 0x01; // Unknown public identifier + Buffer[(*Length)++] = 0x6A; // charset UTF-8 + Buffer[(*Length)++] = 0x00; // string table length Buffer[(*Length)++] = 0x45; //CHARACTERISTIC-LIST with content /* URL */ Buffer[(*Length)++] = 0xC6; //CHARACTERISTIC with content and attributes Buffer[(*Length)++] = 0x7F; //TYPE = BOOKMARK Buffer[(*Length)++] = 0x01; //END PARMeter - if (!UnicodeCoding) { - /* TITLE */ - AddWAPSMSParameterText(Buffer, Length, 0x15, DecodeUnicodeString(bookmark->Title), UnicodeLength(bookmark->Title)); - /* URL */ - AddWAPSMSParameterText(Buffer, Length, 0x17, DecodeUnicodeString(bookmark->Address), UnicodeLength(bookmark->Address)); - } else { - /* TITLE */ - AddWAPSMSParameterText(Buffer, Length, 0x15, bookmark->Title, UnicodeLength(bookmark->Title)*2+1); - /* URL */ - AddWAPSMSParameterText(Buffer, Length, 0x17, bookmark->Address, UnicodeLength(bookmark->Address)*2+1); + + /* removed by Joergen Thomsen */ +// if (!UnicodeCoding) { +// /* TITLE */ +// AddWAPSMSParameterText(Buffer, Length, 0x15, DecodeUnicodeString(bookmark->Title), UnicodeLength(bookmark->Title)); +// /* URL */ +// AddWAPSMSParameterText(Buffer, Length, 0x17, DecodeUnicodeString(bookmark->Address), UnicodeLength(bookmark->Address)); +// } else { +// /* TITLE */ +// AddWAPSMSParameterText(Buffer, Length, 0x15, bookmark->Title, UnicodeLength(bookmark->Title)*2+1); +// /* URL */ +// AddWAPSMSParameterText(Buffer, Length, 0x17, bookmark->Address, UnicodeLength(bookmark->Address)*2+1); +// } + + /* added by Joergen Thomsen */ + /* TITLE */ + EncodeUTF8(buffer, bookmark->Title); + AddWAPSMSParameterText(Buffer, Length, 0x15, buffer, strlen(buffer)); + /* URL */ + EncodeUTF8(buffer, bookmark->Address); + AddWAPSMSParameterText(Buffer, Length, 0x17, buffer, strlen(buffer)); + + Buffer[(*Length)++] = 0x01; //END (CHARACTERISTIC) + Buffer[(*Length)++] = 0x01; //END (CHARACTERISTIC-LIST) +} + +void GSM_EncodeWAPIndicatorSMSText(unsigned char *Buffer, int *Length, char *Text, char *URL) +{ + int i; + + Buffer[(*Length)++] = 0x01; //Push ID + Buffer[(*Length)++] = 0x06; //PDU Type (push) + Buffer[(*Length)++] = 28; //Headers length (content type + headers) + strcpy(Buffer+(*Length),"\x1F\x23"); + (*Length)=(*Length)+2; //Value length + strcpy(Buffer+(*Length),"application/vnd.wap.sic"); + (*Length)=(*Length)+23; //MIME-Type + Buffer[(*Length)++] = 0x00; //end inline string + strcpy(Buffer+(*Length),"\x81\xEA"); + (*Length)=(*Length)+2; //charset UTF-8 short int. + + Buffer[(*Length)++] = 0x02; // WBXML 1.2 + Buffer[(*Length)++] = 0x05; // SI 1.0 Public Identifier + Buffer[(*Length)++] = 0x6A; // charset UTF-8 + Buffer[(*Length)++] = 0x00; // string table length + Buffer[(*Length)++] = 0x45; // SI with content + Buffer[(*Length)++] = 0xC6; // indication with content and attributes + Buffer[(*Length)++] = 0x0B; // address + Buffer[(*Length)++] = 0x03; // Inline string + for (i=0;i<(int)strlen(URL);i++) { + Buffer[(*Length)++] = URL[i];//Text } - Buffer[(*Length)++] = 0x01; //END PARMeter - Buffer[(*Length)++] = 0x01; //END PARMeter + Buffer[(*Length)++] = 0x00; // END Inline string + +#ifdef XXX + Buffer[(*Length)++] = 0x0A; // created... + Buffer[(*Length)++] = 0xC3; // OPAQUE + Buffer[(*Length)++] = 0x07; // length + Buffer[(*Length)++] = 0x19; // year + Buffer[(*Length)++] = 0x80; // year + Buffer[(*Length)++] = 0x21; // month + Buffer[(*Length)++] = 0x12; // .. + Buffer[(*Length)++] = 0x00; // .. + Buffer[(*Length)++] = 0x00; // .. + Buffer[(*Length)++] = 0x00; // .. + Buffer[(*Length)++] = 0x10; // expires + Buffer[(*Length)++] = 0xC3; // OPAQUE + Buffer[(*Length)++] = 0x04; // length + Buffer[(*Length)++] = 0x20; // year + Buffer[(*Length)++] = 0x10; // year + Buffer[(*Length)++] = 0x06; // month + Buffer[(*Length)++] = 0x25; // day +#endif + + Buffer[(*Length)++] = 0x01; // END (indication) + Buffer[(*Length)++] = 0x03; // Inline string + for (i=0;i<(int)strlen(Text);i++) { + Buffer[(*Length)++] = Text[i]; //Text + } + Buffer[(*Length)++] = 0x00; // END Inline string + Buffer[(*Length)++] = 0x01; // END (indication) + Buffer[(*Length)++] = 0x01; // END (SI) } void GSM_EncodeMMSFile(GSM_EncodeMultiPartMMSInfo *Info, unsigned char *Buffer, int *Length) { int i; strcpy(Buffer+(*Length),"\x8C\x80\x98\x4F"); (*Length)=(*Length)+4; diff --git a/gammu/emb/common/service/gsmdata.h b/gammu/emb/common/service/gsmdata.h index f5f8e07..e81589f 100644 --- a/gammu/emb/common/service/gsmdata.h +++ b/gammu/emb/common/service/gsmdata.h @@ -83,16 +83,18 @@ GSM_Error GSM_EncodeURLFile (unsigned char *Buffer, int *Length, GSM_WAPBookma typedef struct { unsigned char Address[500]; unsigned char Title[200]; unsigned char Sender[200]; } GSM_MMSIndicator; void GSM_EncodeMMSIndicatorSMSText(unsigned char *Buffer, int *Length, GSM_MMSIndicator Indicator); +void GSM_EncodeWAPIndicatorSMSText(unsigned char *Buffer, int *Length, char *Text, char *URL); + /* ------------------------------ MMS file --------------------------------- */ #define MAX_MULTI_MMS 20 typedef enum { MMS_Text = 1, MMS_Bitmap_JPG } EncodeMultiPartMMSID; diff --git a/gammu/emb/common/service/gsmlogo.c b/gammu/emb/common/service/gsmlogo.c index c992915..7c19967 100644 --- a/gammu/emb/common/service/gsmlogo.c +++ b/gammu/emb/common/service/gsmlogo.c @@ -1,12 +1,13 @@ /* (c) 2001-2004 by Marcin Wiacek */ #include <string.h> #include <stdlib.h> +#include <sys/stat.h> #include "../misc/misc.h" #include "../misc/coding/coding.h" #include "gsmlogo.h" #include "gsmnet.h" void PHONE_GetBitmapWidthHeight(GSM_Phone_Bitmap_Types Type, int *width, int *height) { @@ -156,16 +157,17 @@ void PHONE_DecodeBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, GSM_Bitmap *B Bitmap->DefaultName = false; Bitmap->DefaultBitmap = false; Bitmap->DefaultRingtone = false; Bitmap->RingtoneID = 0; Bitmap->NetworkCode[0] = 0; Bitmap->Sender[0] = 0; Bitmap->Sender[1] = 0; Bitmap->ID = 0; + Bitmap->Name = NULL; GSM_ClearBitmap(Bitmap); for (x=0;x<Bitmap->BitmapWidth;x++) { for (y=0;y<Bitmap->BitmapHeight;y++) { if (PHONE_IsPointBitmap(Type, buffer, x, y, Bitmap->BitmapWidth, Bitmap->BitmapHeight)) { GSM_SetPointBitmap(Bitmap,x,y); } } @@ -621,27 +623,27 @@ GSM_Error GSM_SaveBitmapFile(char *FileName, GSM_MultiBitmap *bitmap) { FILE *file; GSM_Error error=ERR_NONE; file = fopen(FileName, "wb"); if (file == NULL) return ERR_CANTOPENFILE; /* Attempt to identify filetype */ - if (strstr(FileName,".nlm")) { + if (mystrcasestr(FileName,".nlm")) { error=savenlm(file,bitmap); - } else if (strstr(FileName,".ngg")) { + } else if (mystrcasestr(FileName,".ngg")) { error=savengg(file,bitmap); - } else if (strstr(FileName,".nol")) { + } else if (mystrcasestr(FileName,".nol")) { error=savenol(file,bitmap); - } else if (strstr(FileName,".xpm")) { + } else if (mystrcasestr(FileName,".xpm")) { error=savexpm(file,bitmap); - } else if (strstr(FileName,".nsl")) { + } else if (mystrcasestr(FileName,".nsl")) { error=savensl(file,bitmap); - } else if (strstr(FileName,".wbmp")) { + } else if (mystrcasestr(FileName,".wbmp")) { error=savewbmp(file,bitmap); } else { error=savebmp(file,bitmap); } fclose(file); return error; } @@ -950,24 +952,55 @@ static GSM_Error loadwbmp(FILE *file, GSM_MultiBitmap *bitmap) fread(buffer,1,10000,file); PHONE_DecodeBitmap(GSM_Nokia7110OperatorLogo, buffer, &bitmap->Bitmap[0]); GSM_ReverseBitmap(&bitmap->Bitmap[0]); return ERR_NONE; } +static GSM_Error loadgif(FILE *file, GSM_MultiBitmap *bitmap) +{ + GSM_Bitmap *bmap = &bitmap->Bitmap[0]; + char *buffer; + struct stat st; + int length; + + dbgprintf("loading gif file\n"); + fstat(fileno(file), &st); + bmap->BinaryPic.Length = length = st.st_size; + bmap->BinaryPic.Buffer = buffer = malloc(length); + if (bmap->BinaryPic.Buffer == NULL) + return ERR_MOREMEMORY; + + fread(buffer, 1, length, file); + dbgprintf("Length %i name \"%s\"\n", length, + DecodeUnicodeString(bmap->Name)); + + bmap->Type = GSM_PictureBinary; + bmap->BinaryPic.Type = PICTURE_GIF; + bmap->BitmapWidth = 256 * buffer[7] + buffer[6]; + bmap->BitmapHeight = 256 * buffer[9] + buffer[8]; + bitmap->Number = 1; + + return ERR_NONE; +} + GSM_Error GSM_ReadBitmapFile(char *FileName, GSM_MultiBitmap *bitmap) { FILE *file; unsigned char buffer[300]; file = fopen(FileName, "rb"); if (file == NULL) return ERR_CANTOPENFILE; + bitmap->Bitmap[0].Name = malloc((strlen(FileName) + 1) * 2); + if (bitmap->Bitmap[0].Name == NULL) return ERR_MOREMEMORY; + EncodeUnicode(bitmap->Bitmap[0].Name, FileName, strlen(FileName)); + fread(buffer, 1, 9, file); /* Read the header of the file. */ rewind(file); bitmap->Bitmap[0].DefaultBitmap = false; /* Attempt to identify filetype */ if (memcmp(buffer, "BM",2)==0) { return loadbmp(file,bitmap); @@ -976,16 +1009,18 @@ GSM_Error GSM_ReadBitmapFile(char *FileName, GSM_MultiBitmap *bitmap) } else if (memcmp(buffer, "NLM",3)==0) { return loadnlm(file,bitmap); } else if (memcmp(buffer, "NOL",3)==0) { return loadnolngg(file,bitmap,true); } else if (memcmp(buffer, "NGG",3)==0) { return loadnolngg(file,bitmap,false); } else if (memcmp(buffer, "FORM",4)==0) { return loadnsl(file,bitmap); + } else if (memcmp(buffer, "GIF",3)==0) { + return loadgif(file,bitmap); } return ERR_UNKNOWN; } void NOKIA_CopyBitmap(GSM_Phone_Bitmap_Types Type, GSM_Bitmap *Bitmap, char *Buffer, int *Length) { int Width, Height; diff --git a/gammu/emb/common/service/gsmlogo.h b/gammu/emb/common/service/gsmlogo.h index b1b579d..6c6e2d8 100644 --- a/gammu/emb/common/service/gsmlogo.h +++ b/gammu/emb/common/service/gsmlogo.h @@ -1,15 +1,29 @@ /* (c) 2002-2004 by Marcin Wiacek */ #ifndef __gsm_bitmaps_h #define __gsm_bitmaps_h #include "../gsmcomon.h" +typedef enum { + PICTURE_BMP = 1, + PICTURE_GIF, + PICTURE_JPG, + PICTURE_ICN, + PICTURE_PNG +} GSM_BinaryPicture_Types; + +typedef struct { + GSM_BinaryPicture_Types Type; + unsigned char *Buffer; + int Length; +} GSM_BinaryPicture; + /** * Enum to handle all possible bitmaps, which are not saved in various filesystems. */ typedef enum { GSM_None = 1, /** * ID of static file in filesystem displayed during startup */ @@ -40,17 +54,21 @@ typedef enum { GSM_DealerNote_Text, /** * Text displayed during startup */ GSM_WelcomeNote_Text, /** * Image defined in Smart Messaging specification */ - GSM_PictureImage + GSM_PictureImage, + /** + * Binary picture (BMP, GIF, etc.) + */ + GSM_PictureBinary } GSM_Bitmap_Types; #define GSM_BITMAP_SIZE (65+7)/8*96 #define GSM_BITMAP_TEXT_LENGTH 128 /** * Structure for all possible bitmaps, which are not saved in various filesystems */ @@ -110,16 +128,24 @@ typedef struct { /** * For picture images: number of sender */ unsigned char Sender[2 * (GSM_MAX_NUMBER_LENGTH + 1)]; /** * For colour bitmaps: ID */ unsigned char ID; + /** + * For binary pictures (GIF, BMP, etc.): frame and length + */ + GSM_BinaryPicture BinaryPic; + /** + * Bitmap name + */ + char *Name; } GSM_Bitmap; #define MAX_MULTI_BITMAP 6 /** * Structure to handle more than one bitmap */ typedef struct { diff --git a/gammu/emb/common/service/gsmmisc.h b/gammu/emb/common/service/gsmmisc.h index 37501ad..793d3d1 100644 --- a/gammu/emb/common/service/gsmmisc.h +++ b/gammu/emb/common/service/gsmmisc.h @@ -287,17 +287,22 @@ typedef struct { bool Active; } GSM_GPRSAccessPoint; /* ------------------------------------------------------------------------ */ typedef enum { GSM_Date_DDMMYYYY = 1, GSM_Date_MMDDYYYY, - GSM_Date_YYYYMMDD + GSM_Date_YYYYMMDD, + GSM_Date_DDMMMYY, + GSM_Date_MMDDYY, + GSM_Date_DDMMYY, + GSM_Date_YYMMDD, + GSM_Date_OFF } GSM_DateFormat; typedef struct { unsigned char DateSeparator; GSM_DateFormat DateFormat; bool AMPMTime; } GSM_Locale; diff --git a/gammu/emb/common/service/gsmring.c b/gammu/emb/common/service/gsmring.c index 7df46f1..dab028c 100644 --- a/gammu/emb/common/service/gsmring.c +++ b/gammu/emb/common/service/gsmring.c @@ -1,17 +1,20 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* Based on some work from Ralf Thelen (7110 ringtones), - * Gnokii (RTTL and SM) and others +/* Based on some work from Ralf Thelen (7110 ringtones) and others */ +/* Based on some work (RTTL and SM) from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later */ #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> +#include <sys/stat.h> #ifdef WIN32 # include <windows.h> #endif #include "../gsmcomon.h" #include "../misc/coding/coding.h" #include "../gsmstate.h" #include "gsmring.h" @@ -151,16 +154,22 @@ static GSM_Error savebin(FILE *file, GSM_Ringtone *ringtone) } static GSM_Error savepuremidi(FILE *file, GSM_Ringtone *ringtone) { fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); return ERR_NONE; } +static GSM_Error savemmf(FILE *file, GSM_Ringtone *ringtone) +{ + fwrite(ringtone->NokiaBinary.Frame,1,ringtone->NokiaBinary.Length,file); + return ERR_NONE; +} + GSM_Error saverttl(FILE *file, GSM_Ringtone *ringtone) { GSM_RingNoteScale DefNoteScale; GSM_RingNoteDuration DefNoteDuration; GSM_RingNoteStyle DefNoteStyle=0; int DefNoteTempo=0; @@ -480,16 +489,19 @@ GSM_Error GSM_SaveRingtoneFile(char *FileName, GSM_Ringtone *ringtone) } break; case RING_NOKIABINARY: savebin(file, ringtone); break; case RING_MIDI: savepuremidi(file, ringtone); break; + case RING_MMF: + savemmf(file, ringtone); + break; } fclose(file); return ERR_NONE; } static GSM_Error loadrttl(FILE *file, GSM_Ringtone *ringtone) @@ -764,16 +776,36 @@ static GSM_Error loadpuremidi(FILE *file, GSM_Ringtone *ringtone) dbgprintf("loading midi\n"); EncodeUnicode(ringtone->Name,"MIDI",4); ringtone->NokiaBinary.Length=fread(buffer, 1, 30000, file); memcpy(ringtone->NokiaBinary.Frame,buffer,ringtone->NokiaBinary.Length); dbgprintf("Length %i name \"%s\"\n",ringtone->NokiaBinary.Length,DecodeUnicodeString(ringtone->Name)); return ERR_NONE; } +static GSM_Error loadmmf(FILE *file, GSM_Ringtone *ringtone) +{ + struct stat st; + char *buffer; + int length; + + dbgprintf("loading smaf file\n"); + fstat(fileno(file), &st); + ringtone->BinaryTone.Length = length = st.st_size; + ringtone->BinaryTone.Buffer = buffer = malloc(length); + if (buffer == NULL) + return ERR_MOREMEMORY; + fread(buffer, 1, length, file); + + dbgprintf("Length %i name \"%s\"\n", length, + DecodeUnicodeString(ringtone->Name)); + + return ERR_NONE; +} + static GSM_Error loadre(FILE *file, GSM_Ringtone *ringtone) { unsigned char buffer[2000]; ringtone->NokiaBinary.Length=fread(buffer, 1, 500, file); if (buffer[18]==0x00 && buffer[21]!=0x02) { /* DCT3, Unicode subformat, 62xx & 7110 */ @@ -811,16 +843,20 @@ GSM_Error GSM_ReadRingtoneFile(char *FileName, GSM_Ringtone *ringtone) if (buffer[0]==0x00 && buffer[1]==0x00 && buffer[2]==0x00) { ringtone->Format = RING_NOKIABINARY; } if (buffer[0]==0x4D && buffer[1]==0x54 && buffer[2]==0x68 && buffer[3]==0x64) { ringtone->Format = RING_MIDI; } + if (buffer[0]==0x4D && buffer[1]==0x4D && + buffer[2]==0x4D && buffer[3]==0x44) { + ringtone->Format = RING_MMF; + } } rewind(file); switch (ringtone->Format) { case RING_NOTETONE: if (buffer[0]==0x02 && buffer[1]==0x4A) { error=loadott(file,ringtone); } else if (buffer[0]==0xC7 && buffer[1]==0x45) { error=loadcommunicator(file,ringtone); @@ -837,16 +873,21 @@ GSM_Error GSM_ReadRingtoneFile(char *FileName, GSM_Ringtone *ringtone) if (buffer[0]==0x00 && buffer[1]==0x00 && buffer[2]==0x00) { error=loadre(file,ringtone); } break; case RING_MIDI: EncodeUnicode(ringtone->Name,FileName,strlen(FileName)); error = loadpuremidi(file,ringtone); + break; + case RING_MMF: + EncodeUnicode(ringtone->Name,FileName,strlen(FileName)); + error = loadmmf(file,ringtone); + break; } fclose(file); return(error); } /* -------------------------- required with Nokia & RTTL ------------------- */ /* Beats per Minute like written in Smart Messaging */ diff --git a/gammu/emb/common/service/gsmring.h b/gammu/emb/common/service/gsmring.h index 207cf31..2d2dd7a 100644 --- a/gammu/emb/common/service/gsmring.h +++ b/gammu/emb/common/service/gsmring.h @@ -115,31 +115,33 @@ typedef struct { } GSM_RingCommand; typedef struct { int NrCommands; GSM_RingCommand Commands[MAX_RINGTONE_NOTES]; bool AllNotesScale; } GSM_NoteRingtone; +/* FIXME: should use BinaryTone instead? */ /* Structure to hold Nokia binary ringtones. */ typedef struct { - unsigned char Frame[30000]; + unsigned char Frame[50000]; int Length; } GSM_NokiaBinaryRingtone; typedef struct { - unsigned char *Frame; + unsigned char *Buffer; int Length; } GSM_BinaryTone; typedef enum { RING_NOTETONE = 1, RING_NOKIABINARY, - RING_MIDI + RING_MIDI, + RING_MMF } GSM_RingtoneFormat; /** * Structure for saving various ringtones formats */ typedef struct { /** * Ringtone saved in one of three formats diff --git a/gammu/emb/common/service/sms/gsmmulti.c b/gammu/emb/common/service/sms/gsmmulti.c index 6c1cdcd..bdb5ee9 100644 --- a/gammu/emb/common/service/sms/gsmmulti.c +++ b/gammu/emb/common/service/sms/gsmmulti.c @@ -482,16 +482,21 @@ GSM_Error GSM_EncodeMultiPartSMS(GSM_MultiPartSMSInfo *Info, Length += PHONE_GetBitmapSize(GSM_AlcatelBMMIPicture,Info->Entries[0].Bitmap->Bitmap[i].BitmapWidth,Info->Entries[0].Bitmap->Bitmap[i].BitmapHeight); } return GSM_EncodeAlcatelMultiPartSMS(SMS,Buffer,Length,Info->Entries[0].Bitmap->Bitmap[0].Text,ALCATELTDD_ANIMATION); case SMS_MMSIndicatorLong: Class = 1; UDH = UDH_MMSIndicatorLong; GSM_EncodeMMSIndicatorSMSText(Buffer,&Length,*Info->Entries[0].MMSIndicator); break; + case SMS_WAPIndicatorLong: + Class = 1; + UDH = UDH_MMSIndicatorLong; + GSM_EncodeWAPIndicatorSMSText(Buffer,&Length,Info->Entries[0].MMSIndicator->Title,Info->Entries[0].MMSIndicator->Address); + break; case SMS_NokiaRingtoneLong: case SMS_NokiaRingtone: UDH = UDH_NokiaRingtone; Class = 1; /* 7 = length of UDH_NokiaRingtone UDH header */ Length = GSM_MAX_8BIT_SMS_LENGTH-7; Info->Entries[0].RingtoneNotes = GSM_EncodeNokiaRTTLRingtone(*Info->Entries[0].Ringtone,Buffer,&Length); if (Info->Entries[0].ID == SMS_NokiaRingtone) break; diff --git a/gammu/emb/common/service/sms/gsmmulti.h b/gammu/emb/common/service/sms/gsmmulti.h index c672261..3f70d81 100644 --- a/gammu/emb/common/service/sms/gsmmulti.h +++ b/gammu/emb/common/service/sms/gsmmulti.h @@ -1,13 +1,17 @@ /* (c) 2002-2004 by Marcin Wiacek */ #ifndef __gsm_multi_h #define __gsm_multi_h +#if defined(_MSC_VER) && defined(__cplusplus) + extern "C" { +#endif + #include "../../gsmcomon.h" #include "../gsmlogo.h" #include "../gsmcal.h" #include "../gsmpbk.h" #include "../gsmdata.h" #include "../gsmring.h" #include "gsmsms.h" @@ -167,17 +171,17 @@ typedef enum { /** * IMelody without header - SonyEricsson extension */ SMS_EMSSonyEricssonSound, /** * IMelody 1.0 with UPI. */ SMS_EMSSound10Long, - /*** + /** * IMelody 1.2 with UPI. */ SMS_EMSSound12Long, /** * IMelody without header with UPI. */ SMS_EMSSonyEricssonSoundLong, SMS_EMSPredefinedSound, @@ -185,16 +189,17 @@ typedef enum { SMS_EMSAnimation, /** * Fixed bitmap of size 16x16 or 32x32. */ SMS_EMSFixedBitmap, SMS_EMSVariableBitmap, SMS_EMSVariableBitmapLong, SMS_MMSIndicatorLong, + SMS_WAPIndicatorLong, /** * Variable bitmap with black and white colors */ SMS_AlcatelMonoBitmapLong, /** * Variable animation with black and white colors */ SMS_AlcatelMonoAnimationLong, @@ -259,13 +264,17 @@ void GSM_ClearMultiPartSMSInfo (GSM_MultiPartSMSInfo *Info); */ void GSM_FreeMultiPartSMSInfo (GSM_MultiPartSMSInfo *Info); /** * Links SMS messages according to IDs. */ GSM_Error GSM_LinkSMS(GSM_MultiSMSMessage **INPUT, GSM_MultiSMSMessage **OUTPUT, bool ems); +#if defined(_MSC_VER) && defined(__cplusplus) + } +#endif + #endif /* How should editor hadle tabs in this file? Add editor commands here. * vim: noexpandtab sw=8 ts=8 sts=8: */ diff --git a/gammu/emb/common/service/sms/gsmsms.c b/gammu/emb/common/service/sms/gsmsms.c index 9920835..feceba4 100644 --- a/gammu/emb/common/service/sms/gsmsms.c +++ b/gammu/emb/common/service/sms/gsmsms.c @@ -1,10 +1,13 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Pawel Kot, others and Gnokii */ +/* Based on some Pawel Kot and others work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #include <ctype.h> #include <string.h> #include <time.h> #include "../../gsmcomon.h" #include "../../misc/coding/coding.h" #include "../gsmcal.h" diff --git a/gammu/emb/common/service/sms/gsmsms.h b/gammu/emb/common/service/sms/gsmsms.h index d87ff60..0b950d3 100644 --- a/gammu/emb/common/service/sms/gsmsms.h +++ b/gammu/emb/common/service/sms/gsmsms.h @@ -1,10 +1,13 @@ /* (c) 2001-2004 by Marcin Wiacek */ -/* based on some work from Pawel Kot, others and Gnokii */ +/* Based on some Pawel Kot and others work from Gnokii (www.gnokii.org) + * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot + * GNU GPL version 2 or later + */ #ifndef __gsm_sms_h #define __gsm_sms_h #include "../../gsmcomon.h" #include "../gsmlogo.h" #include "../gsmcal.h" #include "../gsmpbk.h" |