-rw-r--r-- | gammu/emb/common/gsmstate.c | 1246 |
1 files changed, 1246 insertions, 0 deletions
diff --git a/gammu/emb/common/gsmstate.c b/gammu/emb/common/gsmstate.c new file mode 100644 index 0000000..b8f5f89 --- a/dev/null +++ b/gammu/emb/common/gsmstate.c @@ -0,0 +1,1246 @@ +/* (c) 2002-2004 by Marcin Wiacek */ +/* Phones ID (c) partially by Walek */ + +#include <stdarg.h> +#include <string.h> +#include <errno.h> + +#include "gsmcomon.h" +#include "gsmstate.h" +#include "misc/cfg.h" +#include "misc/coding/coding.h" +#include "device/devfunc.h" + +static void GSM_RegisterConnection(GSM_StateMachine *s, unsigned int connection, + GSM_Device_Functions *device, GSM_Protocol_Functions *protocol) +{ + if ((unsigned int)s->ConnectionType == connection) { + s->Device.Functions = device; + s->Protocol.Functions = protocol; + } +} + +static GSM_Error GSM_RegisterAllConnections(GSM_StateMachine *s, char *connection) +{ + /* We check here is used connection string type is correct for ANY + * OS. If not, we return with error, that string is incorrect at all + */ + s->ConnectionType = 0; + if (mystrncasecmp("mbus" ,connection,0)) s->ConnectionType = GCT_MBUS2; + if (mystrncasecmp("fbus" ,connection,0)) s->ConnectionType = GCT_FBUS2; + if (mystrncasecmp("fbusdlr3" ,connection,0)) s->ConnectionType = GCT_FBUS2DLR3; + if (mystrncasecmp("fbusdku5" ,connection,0)) s->ConnectionType = GCT_FBUS2DKU5; + if (mystrncasecmp("fbuspl2303" ,connection,0)) s->ConnectionType = GCT_FBUS2PL2303; + if (mystrncasecmp("fbusblue" ,connection,0)) s->ConnectionType = GCT_FBUS2BLUE; + if (mystrncasecmp("fbusirda" ,connection,0)) s->ConnectionType = GCT_FBUS2IRDA; + if (mystrncasecmp("phonetblue" ,connection,0)) s->ConnectionType = GCT_PHONETBLUE; + if (mystrncasecmp("mrouterblue" ,connection,0)) s->ConnectionType = GCT_MROUTERBLUE; + if (mystrncasecmp("irdaphonet" ,connection,0)) s->ConnectionType = GCT_IRDAPHONET; + if (mystrncasecmp("irdaat" ,connection,0)) s->ConnectionType = GCT_IRDAAT; + if (mystrncasecmp("irdaobex" ,connection,0)) s->ConnectionType = GCT_IRDAOBEX; + if (mystrncasecmp("blueobex" ,connection,0)) s->ConnectionType = GCT_BLUEOBEX; + if (mystrncasecmp("bluefbus" ,connection,0)) s->ConnectionType = GCT_BLUEFBUS2; + if (mystrncasecmp("bluephonet" ,connection,0)) s->ConnectionType = GCT_BLUEPHONET; + if (mystrncasecmp("blueat" ,connection,0)) s->ConnectionType = GCT_BLUEAT; + if (mystrncasecmp("bluerfobex" ,connection,0)) s->ConnectionType = GCT_BLUEOBEX; + if (mystrncasecmp("bluerffbus" ,connection,0)) s->ConnectionType = GCT_BLUEFBUS2; + if (mystrncasecmp("bluerfphonet",connection,0)) s->ConnectionType = GCT_BLUEPHONET; + if (mystrncasecmp("bluerfat" ,connection,0)) s->ConnectionType = GCT_BLUEAT; + + /* These are for compatibility only */ + if (mystrncasecmp("atblue" ,connection,0)) s->ConnectionType = GCT_BLUEAT; + if (mystrncasecmp("dlr3blue" ,connection,0)) s->ConnectionType = GCT_BLUEFBUS2; + if (mystrncasecmp("irda" ,connection,0)) s->ConnectionType = GCT_IRDAPHONET; + if (mystrncasecmp("dlr3" ,connection,0)) s->ConnectionType = GCT_FBUS2DLR3; + if (mystrncasecmp("infrared" ,connection,0)) s->ConnectionType = GCT_FBUS2IRDA; + + if (mystrncasecmp("at" ,connection,2)) { + /* Use some resonable default, when no speed defined */ + if (strlen(connection) == 2) { + s->Speed = 19200; + } else { + s->Speed = FindSerialSpeed(connection+2); + } + if (s->Speed != 0) s->ConnectionType = GCT_AT; + } + if (s->ConnectionType==0) return ERR_UNKNOWNCONNECTIONTYPESTRING; + + /* We check now if user gave connection type compiled & available + * for used OS (if not, we return, that source not available) + */ + s->Device.Functions = NULL; + s->Protocol.Functions = NULL; +#ifdef GSM_ENABLE_MBUS2 + GSM_RegisterConnection(s, GCT_MBUS2, &SerialDevice, &MBUS2Protocol); +#endif +#ifdef GSM_ENABLE_FBUS2 + GSM_RegisterConnection(s, GCT_FBUS2, &SerialDevice, &FBUS2Protocol); +#endif +#ifdef GSM_ENABLE_FBUS2DLR3 + GSM_RegisterConnection(s, GCT_FBUS2DLR3, &SerialDevice, &FBUS2Protocol); +#endif +#ifdef GSM_ENABLE_FBUS2DKU5 + GSM_RegisterConnection(s, GCT_FBUS2DKU5, &SerialDevice, &FBUS2Protocol); +#endif +#ifdef GSM_ENABLE_FBUS2PL2303 + GSM_RegisterConnection(s, GCT_FBUS2PL2303,&SerialDevice, &FBUS2Protocol); +#endif +#ifdef GSM_ENABLE_FBUS2BLUE + GSM_RegisterConnection(s, GCT_FBUS2BLUE, &SerialDevice, &FBUS2Protocol); +#endif +#ifdef GSM_ENABLE_FBUS2IRDA + GSM_RegisterConnection(s, GCT_FBUS2IRDA, &SerialDevice, &FBUS2Protocol); +#endif +#ifdef GSM_ENABLE_PHONETBLUE + GSM_RegisterConnection(s, GCT_PHONETBLUE,&SerialDevice, &PHONETProtocol); +#endif +#ifdef GSM_ENABLE_MROUTERBLUE + GSM_RegisterConnection(s, GCT_MROUTERBLUE,&SerialDevice, &MROUTERProtocol); +#endif +#ifdef GSM_ENABLE_IRDAPHONET + GSM_RegisterConnection(s, GCT_IRDAPHONET,&IrdaDevice, &PHONETProtocol); +#endif +#ifdef GSM_ENABLE_BLUEFBUS2 + GSM_RegisterConnection(s, GCT_BLUEFBUS2, &BlueToothDevice,&FBUS2Protocol); +#endif +#ifdef GSM_ENABLE_BLUEPHONET + GSM_RegisterConnection(s, GCT_BLUEPHONET,&BlueToothDevice,&PHONETProtocol); +#endif +#ifdef GSM_ENABLE_BLUEAT + GSM_RegisterConnection(s, GCT_BLUEAT, &BlueToothDevice,&ATProtocol); +#endif +#ifdef GSM_ENABLE_AT + GSM_RegisterConnection(s, GCT_AT, &SerialDevice, &ATProtocol); +#endif +#ifdef GSM_ENABLE_IRDAAT + GSM_RegisterConnection(s, GCT_IRDAAT, &IrdaDevice, &ATProtocol); +#endif +#ifdef GSM_ENABLE_IRDAOBEX + GSM_RegisterConnection(s, GCT_IRDAOBEX, &IrdaDevice, &OBEXProtocol); +#endif +#ifdef GSM_ENABLE_BLUEOBEX + GSM_RegisterConnection(s, GCT_BLUEOBEX, &BlueToothDevice,&OBEXProtocol); +#endif + if (s->Device.Functions==NULL || s->Protocol.Functions==NULL) + return ERR_SOURCENOTAVAILABLE; + return ERR_NONE; +} + +static void GSM_RegisterModule(GSM_StateMachine *s,GSM_Phone_Functions *phone) +{ + /* Auto model */ + if (s->CurrentConfig->Model[0] == 0) { + if (strstr(phone->models,GetModelData(NULL,s->Phone.Data.Model,NULL)->model) != NULL) { + smprintf(s,"[Module - \"%s\"]\n",phone->models); + s->Phone.Functions = phone; + } + } else { + if (strstr(phone->models,s->CurrentConfig->Model) != NULL) { + smprintf(s,"[Module - \"%s\"]\n",phone->models); + s->Phone.Functions = phone; + } + } +} + +GSM_Error GSM_RegisterAllPhoneModules(GSM_StateMachine *s) +{ + OnePhoneModel *model; + + /* Auto model */ + if (s->CurrentConfig->Model[0] == 0) { + model = GetModelData(NULL,s->Phone.Data.Model,NULL); +#ifdef GSM_ENABLE_ALCATEL + if (model->model[0] != 0 && IsPhoneFeatureAvailable(model, F_ALCATEL)) { + smprintf(s,"[Module - \"%s\"]\n",ALCATELPhone.models); + s->Phone.Functions = &ALCATELPhone; + return ERR_NONE; + } +#endif +#ifdef GSM_ENABLE_ATGEN + /* With ATgen and auto model we can work with unknown models too */ + if (s->ConnectionType==GCT_AT || s->ConnectionType==GCT_BLUEAT || s->ConnectionType==GCT_IRDAAT) { + smprintf(s,"[Module - \"%s\"]\n",ATGENPhone.models); + s->Phone.Functions = &ATGENPhone; + return ERR_NONE; + } +#endif + if (model->model[0] == 0) return ERR_UNKNOWNMODELSTRING; + } + s->Phone.Functions=NULL; +#ifdef GSM_ENABLE_ATGEN + /* AT module can have the same models ID to "normal" Nokia modules */ + if (s->ConnectionType==GCT_AT || s->ConnectionType==GCT_BLUEAT || s->ConnectionType==GCT_IRDAAT) { + GSM_RegisterModule(s,&ATGENPhone); + if (s->Phone.Functions!=NULL) return ERR_NONE; + } +#endif +#ifdef GSM_ENABLE_OBEXGEN + GSM_RegisterModule(s,&OBEXGENPhone); +#endif +#ifdef GSM_ENABLE_MROUTERGEN + GSM_RegisterModule(s,&MROUTERGENPhone); +#endif +#ifdef GSM_ENABLE_NOKIA3320 + GSM_RegisterModule(s,&N3320Phone); +#endif +#ifdef GSM_ENABLE_NOKIA3650 + GSM_RegisterModule(s,&N3650Phone); +#endif +#ifdef GSM_ENABLE_NOKIA6110 + GSM_RegisterModule(s,&N6110Phone); +#endif +#ifdef GSM_ENABLE_NOKIA6510 + GSM_RegisterModule(s,&N6510Phone); +#endif +#ifdef GSM_ENABLE_NOKIA7110 + GSM_RegisterModule(s,&N7110Phone); +#endif +#ifdef GSM_ENABLE_NOKIA9210 + GSM_RegisterModule(s,&N9210Phone); +#endif +#ifdef GSM_ENABLE_ALCATEL + GSM_RegisterModule(s,&ALCATELPhone); +#endif + if (s->Phone.Functions==NULL) return ERR_UNKNOWNMODELSTRING; + return ERR_NONE; +} + +GSM_Error GSM_InitConnection(GSM_StateMachine *s, int ReplyNum) +{ + GSM_Error error; + GSM_DateTime time; + int i; + 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; + s->Phone.Data.Model[0] = 0; + s->Phone.Data.Version[0] = 0; + s->Phone.Data.VerDate[0] = 0; + s->Phone.Data.VerNum = 0; + s->Phone.Data.StartInfoCounter = 0; + s->Phone.Data.SentMsg = NULL; + + s->Phone.Data.HardwareCache[0] = 0; + s->Phone.Data.ProductCodeCache[0] = 0; + s->Phone.Data.EnableIncomingCall = false; + s->Phone.Data.EnableIncomingSMS = false; + s->Phone.Data.EnableIncomingCB = false; + s->Phone.Data.EnableIncomingUSSD = false; + s->User.UserReplyFunctions = NULL; + s->User.IncomingCall = NULL; + s->User.IncomingSMS = NULL; + s->User.IncomingCB = NULL; + s->User.IncomingUSSD = NULL; + s->User.SendSMSStatus = NULL; + s->LockFile = NULL; + s->opened = false; + s->Phone.Functions = NULL; + + s->di = di; + s->di.use_global = s->CurrentConfig->UseGlobalDebugFile; + GSM_SetDebugLevel(s->CurrentConfig->DebugLevel, &s->di); + error=GSM_SetDebugFile(s->CurrentConfig->DebugFile, &s->di); + if (error != ERR_NONE) return error; + + if (s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXT || s->di.dl == DL_TEXTERROR || + s->di.dl == DL_TEXTALLDATE || s->di.dl == DL_TEXTDATE || s->di.dl == DL_TEXTERRORDATE) { + smprintf(s,"[Gammu - version %s built %s %s]\n",VERSION,__TIME__,__DATE__); + smprintf(s,"[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 (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; + + /* Model auto */ + if (s->CurrentConfig->Model[0]==0) { + if (mystrncasecmp(s->CurrentConfig->LockDevice,"yes",0)) { + error = lock_device(s->CurrentConfig->Device, &(s->LockFile)); + if (error != ERR_NONE) return error; + } + + /* Irda devices can set now model to some specific and + * we don't have to make auto detection later */ + error=s->Device.Functions->OpenDevice(s); + if (i != s->ConfigNum - 1) { + if (error == ERR_DEVICEOPENERROR) continue; + if (error == ERR_DEVICELOCKED) continue; + if (error == ERR_DEVICENOTEXIST) continue; + if (error == ERR_DEVICEBUSY) continue; + if (error == ERR_DEVICENOPERMISSION) continue; + if (error == ERR_DEVICENODRIVER) continue; + if (error == ERR_DEVICENOTWORK) continue; + } + if (error!=ERR_NONE) { + if (s->LockFile!=NULL) unlock_device(&(s->LockFile)); + return error; + } + + s->opened = true; + + error=s->Protocol.Functions->Initialise(s); + if (error!=ERR_NONE) return error; + + /* If still auto model, try to get model by asking phone for it */ + if (s->Phone.Data.Model[0]==0) { + smprintf(s,"[Module - \"auto\"]\n"); + switch (s->ConnectionType) { +#ifdef GSM_ENABLE_ATGEN + case GCT_AT: + case GCT_BLUEAT: + case GCT_IRDAAT: + s->Phone.Functions = &ATGENPhone; + break; +#endif +#ifdef GSM_ENABLE_OBEXGEN + case GCT_IRDAOBEX: + case GCT_BLUEOBEX: + s->Phone.Functions = &OBEXGENPhone; + break; +#endif +#ifdef GSM_ENABLE_MROUTERGEN + case GCT_MROUTERBLUE: + s->Phone.Functions = &MROUTERGENPhone; + break; +#endif +#if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4) + case GCT_MBUS2: + case GCT_FBUS2: + case GCT_FBUS2DLR3: + case GCT_FBUS2DKU5: + case GCT_FBUS2PL2303: + case GCT_FBUS2BLUE: + case GCT_FBUS2IRDA: + case GCT_PHONETBLUE: + case GCT_IRDAPHONET: + case GCT_BLUEFBUS2: + case GCT_BLUEPHONET: + s->Phone.Functions = &NAUTOPhone; + break; +#endif + default: + s->Phone.Functions = NULL; + } + if (s->Phone.Functions == NULL) return ERR_UNKNOWN; + + /* Please note, that AT module need to send first + * command for enabling echo + */ + error=s->Phone.Functions->Initialise(s); + if (error == ERR_TIMEOUT && i != s->ConfigNum - 1) continue; + if (error != ERR_NONE) return error; + + error=s->Phone.Functions->GetModel(s); + if (error == ERR_TIMEOUT && i != s->ConfigNum - 1) continue; + if (error != ERR_NONE) return error; + } + } + + /* Switching to "correct" module */ + error=GSM_RegisterAllPhoneModules(s); + if (error!=ERR_NONE) return error; + + /* We didn't open device earlier ? Make it now */ + if (!s->opened) { + if (mystrncasecmp(s->CurrentConfig->LockDevice,"yes",0)) { + error = lock_device(s->CurrentConfig->Device, &(s->LockFile)); + if (error != ERR_NONE) return error; + } + + error=s->Device.Functions->OpenDevice(s); + if (i != s->ConfigNum - 1) { + if (error == ERR_DEVICEOPENERROR) continue; + if (error == ERR_DEVICELOCKED) continue; + if (error == ERR_DEVICENOTEXIST) continue; + if (error == ERR_DEVICEBUSY) continue; + if (error == ERR_DEVICENOPERMISSION) continue; + if (error == ERR_DEVICENODRIVER) continue; + if (error == ERR_DEVICENOTWORK) continue; + } + if (error!=ERR_NONE) { + if (s->LockFile!=NULL) unlock_device(&(s->LockFile)); + return error; + } + + s->opened = true; + + error=s->Protocol.Functions->Initialise(s); + if (error!=ERR_NONE) return error; + } + + error=s->Phone.Functions->Initialise(s); + if (error == ERR_TIMEOUT && i != s->ConfigNum - 1) continue; + if (error != ERR_NONE) return error; + + if (mystrncasecmp(s->CurrentConfig->StartInfo,"yes",0)) { + s->Phone.Functions->ShowStartInfo(s,true); + s->Phone.Data.StartInfoCounter = 30; + } + + if (mystrncasecmp(s->CurrentConfig->SyncTime,"yes",0)) { + GSM_GetCurrentDateTime (&time); + s->Phone.Functions->SetDateTime(s,&time); + } + + /* For debug it's good to have firmware and real model version and manufacturer */ + error=s->Phone.Functions->GetManufacturer(s); + if (error == ERR_TIMEOUT && i != s->ConfigNum - 1) continue; + if (error != ERR_NONE) return error; + error=s->Phone.Functions->GetModel(s); + if (error != ERR_NONE) return error; + error=s->Phone.Functions->GetFirmware(s); + if (error != ERR_NONE) return error; + return ERR_NONE; + } + return ERR_UNKNOWN; +} + +int GSM_ReadDevice (GSM_StateMachine *s, bool wait) +{ + unsigned char buff[255]; + int res = 0, count; + + unsigned int i; + GSM_DateTime Date; + + GSM_GetCurrentDateTime (&Date); + i=Date.Second; + while (i==Date.Second) { + res = s->Device.Functions->ReadDevice(s, buff, 255); + if (!wait) break; + if (res > 0) break; + my_sleep(5); + GSM_GetCurrentDateTime(&Date); + } + + for (count = 0; count < res; count++) + s->Protocol.Functions->StateMachine(s,buff[count]); + + return res; +} + +GSM_Error GSM_TerminateConnection(GSM_StateMachine *s) +{ + GSM_Error error; + + if (!s->opened) return ERR_UNKNOWN; + + smprintf(s,"[Closing]\n"); + + if (mystrncasecmp(s->CurrentConfig->StartInfo,"yes",0)) { + if (s->Phone.Data.StartInfoCounter > 0) s->Phone.Functions->ShowStartInfo(s,false); + } + + if (s->Phone.Functions != NULL) { + error=s->Phone.Functions->Terminate(s); + if (error!=ERR_NONE) return error; + } + + error=s->Protocol.Functions->Terminate(s); + if (error!=ERR_NONE) return error; + + error = s->Device.Functions->CloseDevice(s); + if (error!=ERR_NONE) return error; + + s->Phone.Data.ModelInfo = NULL; + s->Phone.Data.Manufacturer[0] = 0; + s->Phone.Data.Model[0] = 0; + s->Phone.Data.Version[0] = 0; + s->Phone.Data.VerDate[0] = 0; + s->Phone.Data.VerNum = 0; + + if (s->LockFile!=NULL) unlock_device(&(s->LockFile)); + + if (!s->di.use_global && s->di.dl!=0 && fileno(s->di.df) != 1 && fileno(s->di.df) != 2) fclose(s->di.df); + + s->opened = false; + + return ERR_NONE; +} + +GSM_Error GSM_WaitForOnce(GSM_StateMachine *s, unsigned char *buffer, + int length, unsigned char type, int time) +{ + GSM_Phone_Data *Phone = &s->Phone.Data; + GSM_Protocol_Message sentmsg; + int i; + + i=0; + do { + if (length != 0) { + sentmsg.Length = length; + sentmsg.Type = type; + sentmsg.Buffer = (unsigned char *)malloc(length); + memcpy(sentmsg.Buffer,buffer,length); + Phone->SentMsg = &sentmsg; + } + + /* Some data received. Reset timer */ + if (GSM_ReadDevice(s,true)!=0) i=0; + + if (length != 0) { + free (sentmsg.Buffer); + Phone->SentMsg = NULL; + } + + /* Request completed */ + if (Phone->RequestID==ID_None) return Phone->DispatchError; + + i++; + } while (i<time); + + return ERR_TIMEOUT; +} + +GSM_Error GSM_WaitFor (GSM_StateMachine *s, unsigned char *buffer, + int length, unsigned char type, int time, + GSM_Phone_RequestID request) +{ + GSM_Phone_Data *Phone = &s->Phone.Data; + GSM_Error error; + int reply; + + if (mystrncasecmp(s->CurrentConfig->StartInfo,"yes",0)) { + if (Phone->StartInfoCounter > 0) { + Phone->StartInfoCounter--; + if (Phone->StartInfoCounter == 0) s->Phone.Functions->ShowStartInfo(s,false); + } + } + + Phone->RequestID = request; + Phone->DispatchError = ERR_TIMEOUT; + + for (reply=0;reply<s->ReplyNum;reply++) { + if (reply!=0) { + if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl == DL_TEXTERROR || + s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl == DL_TEXTERRORDATE) + { + smprintf(s, "[Retrying %i type 0x%02X]\n", reply, type); + } + } + error = s->Protocol.Functions->WriteMessage(s, buffer, length, type); + if (error!=ERR_NONE) return error; + + error = GSM_WaitForOnce(s, buffer, length, type, time); + if (error != ERR_TIMEOUT) return error; + } + + return Phone->DispatchError; +} + +static GSM_Error CheckReplyFunctions(GSM_StateMachine *s, GSM_Reply_Function *Reply, int *reply) +{ + GSM_Phone_Data *Data = &s->Phone.Data; + GSM_Protocol_Message *msg = s->Phone.Data.RequestMsg; + bool execute; + bool available = false; + int i = 0; + + 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; + } + } + + if (execute) { + *reply=i; + if (Reply[i].requestID == ID_IncomingFrame || + Reply[i].requestID == Data->RequestID || + Data->RequestID == ID_EachFrame) { + return ERR_NONE; + } + available=true; + } + i++; + } + + if (available) { + return ERR_FRAMENOTREQUESTED; + } else { + return ERR_UNKNOWNFRAME; + } +} + +GSM_Error GSM_DispatchMessage(GSM_StateMachine *s) +{ + GSM_Error error = ERR_UNKNOWNFRAME; + GSM_Protocol_Message *msg = s->Phone.Data.RequestMsg; + GSM_Phone_Data *Phone = &s->Phone.Data; + bool disp = false; + GSM_Reply_Function *Reply; + int reply, i; + + if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || + s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) { + smprintf(s, "RECEIVED frame "); + smprintf(s, "type 0x%02X/length 0x%02X/%i", msg->Type, msg->Length, msg->Length); + DumpMessage(s->di.use_global ? di.df : s->di.df, s->di.dl, msg->Buffer, msg->Length); + if (msg->Length == 0) smprintf(s, "\n"); + fflush(s->di.df); + } + if (s->di.dl==DL_BINARY) { + smprintf(s,"%c",0x02); /* Receiving */ + smprintf(s,"%c",msg->Type); + smprintf(s,"%c",msg->Length/256); + smprintf(s,"%c",msg->Length%256); + for (i=0;i<msg->Length;i++) { + smprintf(s,"%c",msg->Buffer[i]); + } + } + + Reply=s->User.UserReplyFunctions; + if (Reply!=NULL) error=CheckReplyFunctions(s,Reply,&reply); + + if (error==ERR_UNKNOWNFRAME) { + Reply=s->Phone.Functions->ReplyFunctions; + error=CheckReplyFunctions(s,Reply,&reply); + } + + if (error==ERR_NONE) { + error=Reply[reply].Function(*msg, s); + if (Reply[reply].requestID==Phone->RequestID) { + if (error == ERR_NEEDANOTHERANSWER) { + error = ERR_NONE; + } else { + Phone->RequestID=ID_None; + } + } + } + + if (strcmp(s->Phone.Functions->models,"NAUTO")) { + if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || s->di.dl==DL_TEXTERROR || + s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE || s->di.dl==DL_TEXTERRORDATE) { + disp = true; + switch (error) { + case ERR_UNKNOWNRESPONSE: + smprintf(s, "\nUNKNOWN response"); + break; + case ERR_UNKNOWNFRAME: + smprintf(s, "\nUNKNOWN frame"); + break; + case ERR_FRAMENOTREQUESTED: + smprintf(s, "\nFrame not request now"); + break; + default: + disp = false; + } + } + + if (error == ERR_UNKNOWNFRAME || error == ERR_FRAMENOTREQUESTED) { + error = ERR_TIMEOUT; + } + } + + if (disp) { + smprintf(s,". If you can, PLEASE report it (see readme.txt). THANK YOU\n"); + if (Phone->SentMsg != NULL) { + smprintf(s,"LAST SENT frame "); + smprintf(s, "type 0x%02X/length %i", Phone->SentMsg->Type, Phone->SentMsg->Length); + DumpMessage(s->di.use_global ? di.df : s->di.df, s->di.dl, Phone->SentMsg->Buffer, Phone->SentMsg->Length); + } + smprintf(s, "RECEIVED frame "); + smprintf(s, "type 0x%02X/length 0x%02X/%i", msg->Type, msg->Length, msg->Length); + DumpMessage(s->di.use_global ? di.df : s->di.df, s->di.dl, msg->Buffer, msg->Length); + smprintf(s, "\n"); + } + + return error; +} + +INI_Section *GSM_FindGammuRC(void) +{ + INI_Section *ini_file; + char *HomeDrive,*HomePath,*FileName=malloc(1); + int FileNameUsed=1; + + FileName[0] = 0; +#if defined(WIN32) || defined(DJGPP) + HomeDrive = getenv("HOMEDRIVE"); + if (HomeDrive) { + FileName = realloc(FileName,FileNameUsed+strlen(HomeDrive)+1); + FileName = strcat(FileName, HomeDrive); + FileNameUsed += strlen(HomeDrive)+1; + } + HomePath = getenv("HOMEPATH"); + if (HomePath) { + FileName = realloc(FileName,FileNameUsed+strlen(HomePath)+1); + FileName = strcat(FileName, HomePath); + FileNameUsed += strlen(HomePath)+1; + } + FileName = realloc(FileName,FileNameUsed+8+1); + strcat(FileName, "\\gammurc"); +#else + HomeDrive = NULL; + HomePath = getenv("HOME"); + if (HomePath) { + FileName = realloc(FileName,FileNameUsed+strlen(HomePath)+1); + FileName = strcat(FileName, HomePath); + FileNameUsed += strlen(HomePath)+1; + } + FileName = realloc(FileName,FileNameUsed+9+1); + strcat(FileName, "/.gammurc"); +#endif +// dbgprintf("\"%s\"\n",FileName); + + ini_file = INI_ReadFile(FileName, false); + free(FileName); + if (ini_file == NULL) { +#if defined(WIN32) || defined(DJGPP) + ini_file = INI_ReadFile("gammurc", false); + if (ini_file == NULL) return NULL; +#else + ini_file = INI_ReadFile("/etc/gammurc", false); + if (ini_file == NULL) return NULL; +#endif + } + + return ini_file; +} + +bool GSM_ReadConfig(INI_Section *cfg_info, GSM_Config *cfg, int num) +{ + INI_Section *h; + unsigned char section[50]; + bool found = false; + +#if defined(WIN32) || defined(DJGPP) + char *DefaultPort = "com2:"; +#else + char *DefaultPort = "/dev/ttyS1"; +#endif + char *DefaultModel = ""; + char *DefaultConnection = "fbus"; + char *DefaultSynchronizeTime = "no"; + char *DefaultDebugFile = ""; + char *DefaultDebugLevel = ""; + char *DefaultLockDevice = "no"; + char *DefaultStartInfo = "no"; + char *Temp; + + /* By default all debug output will go to one filedescriptor */ + bool DefaultUseGlobalDebugFile = true; + + cfg->Device = DefaultPort; + cfg->Connection = DefaultConnection; + cfg->SyncTime = DefaultSynchronizeTime; + cfg->DebugFile = DefaultDebugFile; + strcpy(cfg->Model,DefaultModel); + strcpy(cfg->DebugLevel,DefaultDebugLevel); + cfg->LockDevice = DefaultLockDevice; + cfg->StartInfo = DefaultStartInfo; + cfg->DefaultDevice = true; + cfg->DefaultModel = true; + cfg->DefaultConnection = true; + cfg->DefaultSyncTime = true; + cfg->DefaultDebugFile = true; + cfg->DefaultDebugLevel = true; + cfg->DefaultLockDevice = true; + cfg->DefaultStartInfo = true; + + cfg->UseGlobalDebugFile = DefaultUseGlobalDebugFile; + + if (cfg_info==NULL) return false; + + if (num == 0) { + sprintf(section,"gammu"); + } else { + sprintf(section,"gammu%i",num); + } + for (h = cfg_info; h != NULL; h = h->Next) { + if (mystrncasecmp(section, h->SectionName, strlen(section))) { + found = true; + break; + } + } + if (!found) return false; + + cfg->Device = INI_GetValue(cfg_info, section, "port", false); + if (!cfg->Device) { + free(cfg->Device); + cfg->Device = strdup(DefaultPort); + } else { + cfg->DefaultDevice = false; + } + cfg->Connection = INI_GetValue(cfg_info, section, "connection", false); + if (!cfg->Connection) { + free(cfg->Connection); + cfg->Connection = strdup(DefaultConnection); + } else { + cfg->DefaultConnection = false; + } + cfg->SyncTime = INI_GetValue(cfg_info, section, "synchronizetime", false); + if (!cfg->SyncTime) { + free(cfg->SyncTime); + cfg->SyncTime = strdup(DefaultSynchronizeTime); + } else { + cfg->DefaultSyncTime = false; + } + cfg->DebugFile = INI_GetValue(cfg_info, section, "logfile", false); + if (!cfg->DebugFile) { + free(cfg->DebugFile); + cfg->DebugFile = strdup(DefaultDebugFile); + } else { + cfg->DefaultDebugFile = false; + } + cfg->LockDevice = INI_GetValue(cfg_info, section, "use_locking", false); + if (!cfg->LockDevice) { + free(cfg->LockDevice); + cfg->LockDevice = strdup(DefaultLockDevice); + } else { + cfg->DefaultLockDevice = false; + } + Temp = INI_GetValue(cfg_info, section, "model", false); + if (!Temp) { + strcpy(cfg->Model,DefaultModel); + } else { + cfg->DefaultModel = false; + strcpy(cfg->Model,Temp); + } + Temp = INI_GetValue(cfg_info, section, "logformat", false); + if (!Temp) { + strcpy(cfg->DebugLevel,DefaultDebugLevel); + } else { + cfg->DefaultDebugLevel = false; + strcpy(cfg->DebugLevel,Temp); + } + cfg->StartInfo = INI_GetValue(cfg_info, section, "startinfo", false); + if (!cfg->StartInfo) { + free(cfg->StartInfo); + cfg->StartInfo = strdup(DefaultStartInfo); + } else { + cfg->DefaultStartInfo = false; + } + return true; +} + +static OnePhoneModel allmodels[] = { +#ifdef GSM_ENABLE_NOKIA6510 + {"1100", "RH-18" ,"", {0}}, + {"1100a","RH-38" ,"", {0}}, + {"1100b","RH-36" ,"", {0}}, +#endif +#ifdef GSM_ENABLE_NOKIA6110 + {"2100" ,"NAM-2" ,"", {F_NOWAP,F_NOCALLER,F_RING_SM,F_CAL33,F_POWER_BATT,F_PROFILES33,F_NOCALLINFO,F_NODTMF,0}},//quess +#endif +#ifdef GSM_ENABLE_NOKIA6510 + {"3100" ,"RH-19" ,"", {F_PBKTONEGAL,F_PBKSMSLIST,0}}, + {"3100b","RH-50" ,"", {F_PBKTONEGAL,F_PBKSMSLIST,0}}, + {"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}}, +#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}}, +#endif +#ifdef GSM_ENABLE_NOKIA6110 + {"3310" ,"NHM-5" ,"", {F_NOWAP,F_NOCALLER,F_RING_SM,F_CAL33,F_POWER_BATT,F_PROFILES33,F_NOCALLINFO,F_NODTMF,0}}, +#endif +#ifdef GSM_ENABLE_NOKIA3320 + {"3320" ,"NPC-1" ,"Nokia 3320", {F_CAL62,F_DAYMONTH,0}},//fixme +#endif +#ifdef GSM_ENABLE_NOKIA6110 + {"3330" ,"NHM-6" ,"", {F_NOCALLER,F_RING_SM,F_CAL33,F_PROFILES33,F_NOPICTUREUNI,F_NOCALLINFO,F_NODTMF,0}}, + {"3390" ,"NPB-1" ,"", {F_NOWAP,F_NOCALLER,F_RING_SM,F_CAL33,F_PROFILES33,F_NOPICTUREUNI,F_NOCALLINFO,F_NODTMF,0}}, + {"3410" ,"NHM-2" ,"", {F_RING_SM,F_CAL33,F_PROFILES33,F_NOCALLINFO,F_NODTMF,0}}, +#endif +#ifdef GSM_ENABLE_NOKIA6510 + {"3510" ,"NHM-8" ,"", {F_CAL35,F_PBK35,F_NOGPRSPOINT,F_VOICETAGS,0}}, + {"3510i","RH-9" ,"", {F_CAL35,F_PBK35,F_NOGPRSPOINT,F_VOICETAGS,0}}, + {"3530" ,"RH-9" ,"", {F_CAL35,F_PBK35,F_NOGPRSPOINT,F_VOICETAGS,0}}, + {"3589i","RH-44" ,"", {F_VOICETAGS,0}}, + {"3590" ,"NPM-8" ,"", {0}},//irda? + {"3595" ,"NPM-10" ,"", {0}},//irda? +#endif +#ifdef GSM_ENABLE_NOKIA6110 + {"3610" ,"NAM-1" ,"", {F_NOCALLER,F_RING_SM,F_CAL33,F_POWER_BATT,F_PROFILES33,F_NOCALLINFO,F_NODTMF,0}},//quess +#endif +#if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA3650) + {"3650" ,"NHL-8" ,"Nokia 3650", {0}}, + {"NGAGE","NEM-4" ,"", {F_RADIO,0}}, +#endif +#if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) + {"5100" ,"NPM-6" ,"Nokia 5100", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, + {"5100" ,"NPM-6U","Nokia 5100", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, + {"5100" ,"NPM-6X","Nokia 5100", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, +#endif +#ifdef GSM_ENABLE_NOKIA6110 + {"5110" ,"NSE-1" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, + {"5110i","NSE-2" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, + {"5130" ,"NSK-1" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, + {"5190" ,"NSB-1" ,"", {F_NOWAP,F_NOCALLER,F_NORING,F_NOPICTURE,F_NOSTARTUP,F_NOCALENDAR,F_NOPBKUNICODE,F_PROFILES51,F_MAGICBYTES,F_DISPSTATUS,0}}, +#endif +#if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6110) + {"5210" ,"NSM-5" ,"Nokia 5210", {F_CAL52,F_NOSTARTANI,F_NOPICTUREUNI,F_NODTMF,0}}, +#endif +#ifdef GSM_ENABLE_NOKIA6110 + {"5510" ,"NPM-5" ,"", {F_NOCALLER,F_PROFILES33,F_NOPICTUREUNI,0}}, +#endif +#if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) + {"6100" ,"NPL-2" ,"Nokia 6100", {F_PBKTONEGAL,F_TODO66,0}}, +#endif +#ifdef GSM_ENABLE_NOKIA6110 + {"6110" ,"NSE-3" ,"", {F_NOWAP,F_NOPICTURE,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,0}}, + {"6130" ,"NSK-3" ,"", {F_NOWAP,F_NOPICTURE,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,0}}, + {"6150" ,"NSM-1" ,"", {F_NOWAP,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,F_NOPICTUREUNI,0}}, + {"6190" ,"NSB-3" ,"", {F_NOWAP,F_NOPICTURE,F_NOSTARTANI,F_NOPBKUNICODE,F_MAGICBYTES,F_DISPSTATUS,0}}, +#endif +#if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) + {"6200" ,"NPL-3" ,"Nokia 6200", {F_PBKTONEGAL,0}}, + {"6220" ,"RH-20" ,"Nokia 6220", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKSMSLIST,F_PBKUSER,F_WAPMMSPROXY,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}}, + {"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}}, + {"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}}, +#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) + {"7210" ,"NHL-4" ,"Nokia 7210", {F_PBKTONEGAL,F_TODO66,F_RADIO,0}}, + {"7250" ,"NHL-4J","Nokia 7250", {F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKIMG,0}}, + {"7250i","NHL-4JX","Nokia 7250i",{F_PBKTONEGAL,F_TODO66,F_RADIO,F_PBKIMG,0}}, + {"7600", "NMM-3", "Nokia 7600", {F_TODO66,0}}, +#endif +#if defined(GSM_ENABLE_ATGEN) + {"7650" ,"NHL-2" ,"Nokia 7650", {0}}, +#endif +#if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6110) + {"8210" ,"NSM-3" ,"Nokia 8210", {F_NOWAP,F_NOSTARTANI,F_NOPBKUNICODE,F_NOPICTUREUNI,0}}, + {"8250" ,"NSM-3D","Nokia 8250", {F_NOWAP,F_NOSTARTANI,F_CAL82,F_NOPICTUREUNI,0}}, + {"8290" ,"NSB-7" ,"Nokia 8290", {F_NOWAP,F_NOSTARTANI,F_NOPBKUNICODE,F_NOPICTUREUNI,0}}, +#endif +#if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) + {"8310" ,"NHM-7" ,"Nokia 8310", {F_CAL62,F_NOMIDI,F_RADIO,F_NOFILESYSTEM,F_NOMMS,F_VOICETAGS,0}}, + {"8390" ,"NSB-8" ,"Nokia 8390", {F_CAL62,F_NOMIDI,F_RADIO,F_NOFILESYSTEM,F_NOMMS,F_VOICETAGS,0}}, +#endif +#if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6110) + {"8850" ,"NSM-2" ,"Nokia 8850", {0}}, + {"8855" ,"NSM-4" ,"Nokia 8855", {0}}, + {"8890" ,"NSB-6" ,"Nokia 8890", {0}}, +#endif +#if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_NOKIA6510) + {"8910" ,"NHM-4" ,"Nokia 8910", {F_CAL62,F_NOMIDI,F_NOFILESYSTEM,F_NOMMS,0}}, + {"8910i","NHM-4" ,"Nokia 8910i",{F_CAL62,F_NOMIDI,F_NOFILESYSTEM,F_NOMMS,0}}, +#endif +#ifdef GSM_ENABLE_NOKIA9210 + {"9210" ,"RAE-3" ,"", {0}}, + {"9210i","RAE-5" ,"", {0}}, +#endif +#ifdef GSM_ENABLE_ATGEN + {"at" , "at", "", {0}}, + {"M20" , "M20", "", {F_M20SMS,F_SLOWWRITE,0}}, + {"MC35" , "MC35", "", {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}}, + {"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}}, + {"iPAQ" , "iPAQ" , "" , {0}}, + {"A2D" , "A2D" , "" , {0}}, + {"9210" , "RAE-3", "Nokia Communicator GSM900/1800",{0}}, + {"myV-65", "myV-65 GPRS", "", {F_SMSME900,0}}, +#endif +#if defined(GSM_ENABLE_ATGEN) || defined(GSM_ENABLE_ALCATEL) + {"BE5", "ONE TOUCH 500","", {F_ALCATEL,F_SMSONLYSENT,F_BROKENCPBS,0}}, + {"BH4", "ONE TOUCH 535","ALCATEL OT535", {F_ALCATEL,F_SMSONLYSENT,0}}, + {"BF5", "ONE TOUCH 715","ALCATEL OT715", {F_ALCATEL,F_SMSONLYSENT,F_BROKENCPBS,0}}, +#endif + {"unknown", "" ,"", {0}} +}; + +OnePhoneModel *GetModelData(char *model, char *number, char *irdamodel) +{ + int i = 0; + + while (strcmp(allmodels[i].number,"") != 0) { + if (model !=NULL) { + if (strcmp (model, allmodels[i].model) == 0) { + return (&allmodels[i]); + } + } + if (number !=NULL) { + if (strcmp (number, allmodels[i].number) == 0) { + return (&allmodels[i]); + } + } + if (irdamodel !=NULL) { + if (strcmp (irdamodel, allmodels[i].irdamodel) == 0) { + return (&allmodels[i]); + } + } + i++; + } + return (&allmodels[i]); +} + +bool IsPhoneFeatureAvailable(OnePhoneModel *model, Feature feature) +{ + int i = 0; + bool retval = false; + + while (model->features[i] != 0) { + if (model->features[i] == feature) { + retval = true; + break; + } + i++; + } + return retval; +} + +void GSM_DumpMessageLevel2(GSM_StateMachine *s, unsigned char *message, int messagesize, int type) +{ + if (s->di.dl==DL_TEXT || s->di.dl==DL_TEXTALL || + s->di.dl==DL_TEXTDATE || s->di.dl==DL_TEXTALLDATE) { + smprintf(s,"SENDING frame "); + smprintf(s,"type 0x%02X/length 0x%02X/%i", type, messagesize, messagesize); + DumpMessage(s->di.use_global ? di.df : s->di.df, s->di.dl, message, messagesize); + if (messagesize == 0) smprintf(s,"\n"); + if (s->di.df) fflush(s->di.df); + } +} + +void GSM_DumpMessageLevel3(GSM_StateMachine *s, unsigned char *message, int messagesize, int type) +{ + int i; + + if (s->di.dl==DL_BINARY) { + smprintf(s,"%c",0x01); /* Sending */ + smprintf(s,"%c",type); + smprintf(s,"%c",messagesize/256); + smprintf(s,"%c",messagesize%256); + for (i=0;i<messagesize;i++) smprintf(s,"%c",message[i]); + } +} + +#ifdef __GNUC__ +__attribute__((format(printf, 2, 3))) +#endif +int smprintf(GSM_StateMachine *s, const char *format, ...) +{ + va_list argp; + int result=0; + unsigned char buffer[2000]; + Debug_Level dl; + FILE *df; + + va_start(argp, format); + if (s == NULL) { + dl = di.dl; + df = di.df; + } else { + dl = s->di.dl; + if (s->di.use_global) { + df = di.df; + } else { + df = s->di.df; + } + } + + if (dl != 0) { + result = vsprintf(buffer, format, argp); + result = smfprintf(df, dl, "%s", buffer); + } + + va_end(argp); + return result; +} + +void GSM_OSErrorInfo(GSM_StateMachine *s, char *description) +{ +#ifdef WIN32 + int i; + unsigned char *lpMsgBuf; + + /* We don't use errno in win32 - GetLastError gives better info */ + if (GetLastError()!=-1) { + if (s->di.dl == DL_TEXTERROR || s->di.dl == DL_TEXT || s->di.dl == DL_TEXTALL || + s->di.dl == DL_TEXTERRORDATE || s->di.dl == DL_TEXTDATE || s->di.dl == DL_TEXTALLDATE) { + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + for (i=0;i<(int)strlen(lpMsgBuf);i++) { + if (lpMsgBuf[i] == 13 || lpMsgBuf[i] == 10) { + lpMsgBuf[i] = ' '; + } + } + smprintf(s,"[System error - %s, %i, \"%s\"]\n",description,GetLastError(),(LPCTSTR)lpMsgBuf); + LocalFree(lpMsgBuf); + } + } + return; +#endif + + if (errno!=-1) { + if (s->di.dl == DL_TEXTERROR || s->di.dl == DL_TEXT || s->di.dl == DL_TEXTALL || + s->di.dl == DL_TEXTERRORDATE || s->di.dl == DL_TEXTDATE || s->di.dl == DL_TEXTALLDATE) { + smprintf(s,"[System error - %s, %i, \"%s\"]\n",description,errno,strerror(errno)); + } + } +} + +#ifdef GSM_ENABLE_BACKUP + +void GSM_GetPhoneFeaturesForBackup(GSM_StateMachine *s, GSM_Backup_Info *info) +{ + GSM_Error error; + GSM_MemoryStatus MemStatus; + GSM_ToDoStatus ToDoStatus; + GSM_CalendarEntry Note; + GSM_WAPBookmark Bookmark; + GSM_MultiWAPSettings WAPSettings; + GSM_FMStation FMStation; + GSM_GPRSAccessPoint GPRSPoint; +// GSM_Profile Profile; + + if (info->PhonePhonebook) { + MemStatus.MemoryType = MEM_ME; + error=s->Phone.Functions->GetMemoryStatus(s, &MemStatus); + if (error==ERR_NONE && MemStatus.MemoryUsed != 0) { + } else { + info->PhonePhonebook = false; + } + } + if (info->SIMPhonebook) { + MemStatus.MemoryType = MEM_SM; + error=s->Phone.Functions->GetMemoryStatus(s, &MemStatus); + if (error==ERR_NONE && MemStatus.MemoryUsed != 0) { + } else { + info->SIMPhonebook = false; + } + } + if (info->Calendar) { + error=s->Phone.Functions->GetNextCalendar(s,&Note,true); + if (error!=ERR_NONE) info->Calendar = false; + } + if (info->ToDo) { + error=s->Phone.Functions->GetToDoStatus(s,&ToDoStatus); + if (error == ERR_NONE && ToDoStatus.Used != 0) { + } else { + info->ToDo = false; + } + } + if (info->WAPBookmark) { + Bookmark.Location = 1; + error=s->Phone.Functions->GetWAPBookmark(s,&Bookmark); + if (error == ERR_NONE) { + } else { + info->WAPBookmark = false; + } + } + if (info->WAPSettings) { + WAPSettings.Location = 1; + error=s->Phone.Functions->GetWAPSettings(s,&WAPSettings); + if (error == ERR_NONE) { + } else { + info->WAPSettings = false; + } + } + if (info->MMSSettings) { + WAPSettings.Location = 1; + error=s->Phone.Functions->GetMMSSettings(s,&WAPSettings); + if (error == ERR_NONE) { + } else { + info->WAPSettings = false; + } + } + if (info->FMStation) { + FMStation.Location = 1; + error = s->Phone.Functions->GetFMStation(s,&FMStation); + if (error == ERR_NONE || error == ERR_EMPTY) { + } else { + info->FMStation = false; + } + } + if (info->GPRSPoint) { + GPRSPoint.Location = 1; + error = s->Phone.Functions->GetGPRSAccessPoint(s,&GPRSPoint); + if (error == ERR_NONE || error == ERR_EMPTY) { + } else { + info->GPRSPoint = false; + } + } +} + +#endif + +/* How should editor hadle tabs in this file? Add editor commands here. + * vim: noexpandtab sw=8 ts=8 sts=8: + */ |