5 A Linux/Unix toolset and driver for Nokia mobile phones.
7 Released under the terms of the GNU GPL, see file COPYING for more details.
9 Provides a generic API for accessing functions on the phone, wherever
10 possible hiding the model specific details.
12 The underlying code should run in it's own thread to allow communications to
13 the phone to be run independantly of mailing code that calls these API
16 Unless otherwise noted, all functions herein block until they complete. The
17 functions themselves are defined in a structure in gsm-common.h.
30 #include "misc_win32.h"
36 #include "newmodules/n3110.h"
37 #include "newmodules/n6110.h"
38 #include "newmodules/n7110.h"
39 #include "newmodules/newat.h"
41 #include "newmodules/sniff/sniff.h"
43 #include "protocol/fbusirda.h"
45 #include "protocol/fbus.h"
47 #include "protocol/fbus3110.h"
48 #include "protocol/mbus.h"
49 #include "protocol/at.h"
51 #include "files/cfgreader.h"
54 #include "devices/device.h"
58 /* for VC6 make scripts save VERSION constant in mversion.h file */
62 /* GSM_LinkOK is set to true once normal communications with the phone have
67 /* Define pointer to the GSM_Functions structure used by external code to call
68 relevant API functions. This structure is defined in gsm-common.h. */
72 /* Define pointer to the GSM_Information structure used by external code to
73 obtain information that varies from model to model. This structure is also
74 defined in gsm-common.h */
76 GSM_Information *GSM_Info;
78 /* Initialise interface to the phone. Model number should be a string such as
79 3810, 5110, 6110 etc. Device is the serial port to use e.g. /dev/ttyS0, the
80 user must have write permission to the device. */
82 GSM_Protocol *Protocol;
84 /* Local variables used by get/set phonebook entry code. Buffer is used as a
85 source or destination for phonebook data and other functions... Error is
86 set to GE_NONE by calling function, set to GE_COMPLETE or an error code by
87 handler routines as appropriate. */
89 GSM_PhonebookEntry *CurrentPhonebookEntry;
90 GSM_Error CurrentPhonebookError;
92 GSM_SpeedDial *CurrentSpeedDialEntry;
93 GSM_Error CurrentSpeedDialError;
95 unsigned char Current_IMEI[GSM_MAX_IMEI_LENGTH];
96 unsigned char Current_Revision[GSM_MAX_REVISION_LENGTH];
97 unsigned char Current_Model[GSM_MAX_MODEL_LENGTH];
100 GSM_SMSMessage *CurrentSMSMessage;
101 GSM_Error CurrentSMSMessageError;
102 int CurrentSMSPointer;
104 GSM_SMSFolders *CurrentSMSFolders;
105 GSM_Error CurrentSMSFoldersError;
106 int CurrentSMSFoldersCount;
108 GSM_OneSMSFolder CurrentSMSFolder;
109 GSM_Error CurrentSMSFolderError;
110 int CurrentSMSFolderID;
113 GSM_MemoryStatus *CurrentMemoryStatus;
114 GSM_Error CurrentMemoryStatusError;
117 GSM_NetworkInfo *CurrentNetworkInfo;
118 GSM_Error CurrentNetworkInfoError;
120 GSM_SMSStatus *CurrentSMSStatus;
121 GSM_Error CurrentSMSStatusError;
123 GSM_MessageCenter *CurrentMessageCenter;
124 GSM_Error CurrentMessageCenterError;
126 int *CurrentSecurityCodeStatus;
127 GSM_Error CurrentSecurityCodeError;
128 GSM_SecurityCode *CurrentSecurityCode;
130 GSM_DateTime *CurrentDateTime;
131 GSM_Error CurrentDateTimeError;
133 GSM_Error CurrentResetPhoneSettingsError;
135 GSM_DateTime *CurrentAlarm;
136 GSM_Error CurrentAlarmError;
138 GSM_CalendarNote *CurrentCalendarNote;
139 GSM_Error CurrentCalendarNoteError;
141 GSM_NotesInfo CurrentCalendarNotesInfo,*CurrentCalendarNotesInfo2;
142 GSM_Error CurrentCalendarNotesInfoError;
144 GSM_Error CurrentSetDateTimeError;
145 GSM_Error CurrentSetAlarmError;
147 int *CurrentFirstCalendarFreePos;
148 GSM_Error CurrentFirstCalendarFreePosError;
151 GSM_Error CurrentEnableExtendedCommandsError;
158 int CurrentDisplayStatus;
159 GSM_Error CurrentDisplayStatusError;
161 char *CurrentNetmonitor;
162 GSM_Error CurrentNetmonitorError;
164 GSM_Bitmap *CurrentGetBitmap=NULL;
165 GSM_Error CurrentGetBitmapError;
167 GSM_Error CurrentSetBitmapError;
169 GSM_Error CurrentSendDTMFError;
171 GSM_Profile *CurrentProfile;
172 GSM_Error CurrentProfileError;
174 GSM_Error CurrentDisplayOutputError;
176 GSM_CBMessage *CurrentCBMessage;
177 GSM_Error CurrentCBError;
179 int CurrentPressKeyEvent;
180 GSM_Error CurrentPressKeyError;
182 GSM_Error CurrentPlayToneError=GE_UNKNOWN;
185 GSM_Error CurrentDialVoiceError;
188 GSM_Error CurrentGetOperatorNameError;
189 GSM_Network *CurrentGetOperatorNameNetwork;
190 GSM_Error CurrentSetOperatorNameError;
193 GSM_Error CurrentGetIMEIError;
195 GSM_Error CurrentGetHWError;
198 unsigned char CurrentPPS[4];
199 GSM_Error CurrentProductProfileSettingsError;
201 char CurrentIncomingCall[20];
203 GSM_Error CurrentBinRingtoneError;
204 GSM_BinRingtone *CurrentGetBinRingtone=NULL;
206 GSM_Error CurrentRingtoneError;
209 GSM_Error CurrentMagicError;
212 GSM_Error CurrentSimlockInfoError;
213 GSM_AllSimlocks *CurrentSimLock;
215 GSM_Error CurrentGetWAPBookmarkError;
216 GSM_Error CurrentSetWAPBookmarkError;
217 GSM_WAPBookmark *WAPBookmark;
219 GSM_Error CurrentGetWAPSettingsError;
220 GSM_WAPSettings *WAPSettings;
222 GSM_Error CurrentCallDivertError;
223 GSM_CallDivert *CurrentCallDivert;
225 char *CurrentManufacturer;
228 /* This is the connection type used in gnokii. */
229 GSM_ConnectionType CurrentConnectionType;
231 /* Pointer to a callback function used to return changes to a calls status */
232 /* This saves unreliable polling */
233 void (*CurrentCallPassup)(char c);
235 /* Pointer to callback function in user code to be called when RLP frames
237 void (*CurrentRLP_RXCallback)(RLP_F96Frame *frame);
239 /* Used to disconnect the call */
240 u8 CurrentCallSequenceNumber;
244 bool CurrentRequestTerminate;
247 bool CurrentDisableKeepAlive;
253 bool CheckModel (GSM_Information InfoToCheck, char *model, GSM_ConnectionType connection) {
255 bool found_match=false;
257 if (strstr(InfoToCheck.FBUSModels, model) != NULL) {
258 if (connection==GCT_FBUS) found_match=true;
261 if (strstr(InfoToCheck.MBUSModels, model) != NULL) {
262 if (connection==GCT_MBUS) found_match=true;
264 if (strstr(InfoToCheck.InfraredModels, model) != NULL) {
265 if (connection==GCT_Infrared) found_match=true;
267 if (strstr(InfoToCheck.DLR3Models, model) != NULL) {
268 if (connection==GCT_DLR3) found_match=true;
270 if (strstr(InfoToCheck.IrdaModels, model) != NULL) {
271 if (connection==GCT_Irda) found_match=true;
273 if (strstr(InfoToCheck.ATModels, model) != NULL) {
274 if (connection==GCT_AT) found_match=true;
276 if (strstr(InfoToCheck.TekramModels, model) != NULL) {
277 if (connection==GCT_Tekram) found_match=true;
279 if (strstr(InfoToCheck.FBUS3110Models, model) != NULL) {
280 if (connection==GCT_FBUS3110) found_match=true;
289 GSM_Error TryNewNokia(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame)) {
292 unsigned char init_char = N6110_SYNC_BYTE;
294 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
297 if (Protocol->Initialise(device,initlength,connection,rlp_callback)!=GE_NONE)
299 return GE_NOTSUPPORTED;
302 if (connection!=GCT_MBUS) {
303 InitLength = atoi(initlength);
305 if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
306 InitLength = 250; /* This is the usual value, lower may work. */
310 fprintf(stdout,_("Writing init chars...."));
313 /* Initialise link with phone or what have you */
314 /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
316 for (count = 0; count < InitLength; count ++) {
318 Protocol->WritePhone(1,&init_char);
322 fprintf(stdout,_("Done\n"));
325 N6110_SendStatusRequest();
330 if (N6110_SendIDFrame()!=GE_NONE)
333 while (N6110_GetModel(phonemodel) != GE_NONE)
337 if (!strcmp(phonemodel,"NPE-3") || !strcmp(phonemodel,"NSE-5") ||
338 !strcmp(phonemodel,"NHM-3"))
342 /* Set pointers to relevant addresses */
343 GSM = &N7110_Functions;
344 GSM_Info = &N7110_Information;
345 GSM_LinkOK = &CurrentLinkOK;
354 extern GSM_Information N6110_Information;
355 extern GSM_Functions N6110_Functions;
357 GSM_Error GSM_Initialise(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame), char* SynchronizeTime)
359 bool found_match=false;
361 GSM_ConnectionType connection2;
370 connection2=connection;
372 CurrentRLP_RXCallback = rlp_callback;
373 CurrentCallPassup=NULL;
375 CurrentCallDivert=NULL;
377 CurrentPhonebookEntry=NULL;
379 CurrentNetworkInfo = NULL;
380 CurrentGetBitmap=NULL;
381 CurrentPlayToneError=GE_UNKNOWN;
382 strcpy(CurrentIncomingCall," ");
383 CurrentGetBinRingtone=NULL;
384 CurrentNetworkInfo=NULL;
386 CurrentRequestTerminate=false;
388 CurrentDisableKeepAlive=false;
389 CurrentCalendarNotesInfo.HowMany=2000;
390 CurrentSMSMessage=NULL;
392 CurrentMagicError = GE_BUSY;
395 if (!strcmp(model,"auto")) {
398 GSM = &N6110_Functions;
399 GSM_Info = &N6110_Information;
400 GSM_LinkOK = &CurrentLinkOK;
402 fprintf(stdout,_("Trying FBUS for new Nokia phones...\n"));
405 Protocol = &FBUS_Functions;
406 CurrentConnectionType=GCT_FBUS;
407 connection2=GCT_FBUS;
408 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
419 GSM = &N6110_Functions;
420 GSM_Info = &N6110_Information;
421 GSM_LinkOK = &CurrentLinkOK;
423 fprintf(stdout,_("Trying DLR3 for new Nokia phones...\n"));
426 Protocol = &FBUS_Functions;
427 CurrentConnectionType=GCT_DLR3;
428 connection2=GCT_DLR3;
429 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
441 GSM = &N6110_Functions;
442 GSM_Info = &N6110_Information;
443 GSM_LinkOK = &CurrentLinkOK;
445 fprintf(stdout,_("Trying MBUS for new Nokia phones...\n"));
448 Protocol = &MBUS_Functions;
449 CurrentConnectionType=GCT_MBUS;
450 connection2=GCT_MBUS;
451 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
459 if (!found_match) return GE_NOTSUPPORTED;
464 if (!strcmp(model,"modelauto")) {
466 GSM = &N6110_Functions;
467 GSM_Info = &N6110_Information;
468 GSM_LinkOK = &CurrentLinkOK;
470 fprintf(stdout,_("Trying to find connected model...\n"));
472 switch (connection) {
473 case GCT_FBUS : Protocol = &FBUS_Functions; break;
474 case GCT_Infrared: Protocol = &FBUS_Functions; break;
475 case GCT_Tekram : Protocol = &FBUS_Functions; break;
476 case GCT_DLR3 : Protocol = &FBUS_Functions; break;
477 case GCT_MBUS : Protocol = &MBUS_Functions; break;
478 case GCT_Irda : Protocol = &FBUSIRDA_Functions;break;
479 case GCT_AT : Protocol = &AT_Functions; break;
480 case GCT_FBUS3110: Protocol = &FBUS3110_Functions;break;
482 CurrentConnectionType=connection;
483 connection2=connection;
484 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
491 if (!found_match) return GE_NOTSUPPORTED;
500 if (CheckModel (Nsniff_Information, model, connection)) {
501 /* Set pointers to relevant addresses */
502 GSM = &Nsniff_Functions;
503 GSM_Info = &Nsniff_Information;
504 GSM_LinkOK = &CurrentLinkOK;
509 if (CheckModel (N3110_Information, model, connection)) {
510 /* Set pointers to relevant addresses */
511 GSM = &N3110_Functions;
512 GSM_Info = &N3110_Information;
513 GSM_LinkOK = &CurrentLinkOK;
517 if (CheckModel (N6110_Information, model, connection)) {
518 /* Set pointers to relevant addresses */
519 GSM = &N6110_Functions;
520 GSM_Info = &N6110_Information;
521 GSM_LinkOK = &CurrentLinkOK;
525 if (CheckModel (N7110_Information, model, connection)) {
526 /* Set pointers to relevant addresses */
527 GSM = &N7110_Functions;
528 GSM_Info = &N7110_Information;
529 GSM_LinkOK = &CurrentLinkOK;
532 if (CheckModel (Nat_Information, model, connection)) {
533 /* Set pointers to relevant addresses */
534 GSM = &Nat_Functions;
535 GSM_Info = &Nat_Information;
536 GSM_LinkOK = &CurrentLinkOK;
542 switch (connection) {
543 case GCT_FBUS : Protocol = &FBUS_Functions; break;
545 case GCT_Infrared: Protocol = &FBUS_Functions; break;
546 case GCT_Tekram : Protocol = &FBUS_Functions; break;
547 case GCT_DLR3 : Protocol = &FBUS_Functions; break;
548 case GCT_MBUS : Protocol = &MBUS_Functions; break;
549 case GCT_Irda : Protocol = &FBUSIRDA_Functions;break;
550 case GCT_AT : Protocol = &AT_Functions; break;
551 case GCT_FBUS3110: Protocol = &FBUS3110_Functions;break;
555 return GE_NOTSUPPORTED;
562 /* Now call model specific initialisation code. */
563 error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
566 /* RTH: FIXME: second try for Irda (6210 only?)*/
567 if ( error!=GE_NONE && connection == GCT_Irda)
570 fprintf(stdout,"Irda connection: second try!\n");
573 error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
578 if (error==GE_NONE && !strcmp(SynchronizeTime,"yes"))
581 now=localtime(&nowh);
583 Date.Year = now->tm_year;
584 Date.Month = now->tm_mon+1;
585 Date.Day = now->tm_mday;
586 Date.Hour = now->tm_hour;
587 Date.Minute = now->tm_min;
588 Date.Second = now->tm_sec;
593 /* Well, this thing is copyrighted in U.S. This technique is known as
594 Windowing and you can read something about it in LinuxWeekly News:
595 http://lwn.net/1999/features/Windowing.phtml. This thing is beeing
596 written in Czech republic and Poland where algorithms are not allowed
600 Date.Year = Date.Year+1900;
602 Date.Year = Date.Year+2000;
605 /* FIXME: Error checking should be here. */
606 GSM->SetDateTime(&Date);
615 GSM_Error Unimplemented(void)
617 return GE_NOTIMPLEMENTED;
620 GSM_Error NotSupported(void)
622 return GE_NOTSUPPORTED;
627 /* Applications should call N6110_Terminate to shut down the N6110 thread and
628 close the serial port. */
629 void NULL_Terminate(void)
631 Protocol->Terminate();
635 /* Here are things made for keeping connecting */
636 void NULL_KeepAlive()
640 /* Here are things made for keeping connecting */
641 void NULL_KeepAlive()
647 void NULL_TX_DisplayMessage(u16 MessageLength, u8 *MessageBuffer)
649 fprintf(stdout, _("PC: "));
651 txhexdump(MessageLength,MessageBuffer);
655 bool NULL_WritePhone (u16 length, u8 *buffer) {
656 if (device_write(buffer,length)!=length) return false;
660 GSM_Error NULL_WaitUntil (int time, GSM_Error *value)
666 /* Wait for timeout or other error. */
667 while (timeout != 0 && *value == GE_BUSY ) {
678 GSM_Error NULL_SendMessageSequence (int time, GSM_Error *value,
679 u16 message_length, u8 message_type, u8 *buffer)
683 Protocol->SendMessage(message_length, message_type, buffer);
685 return NULL_WaitUntil (time, value);
688 GSM_ConnectionType GetConnectionTypeFromString(char *Connection) {
690 GSM_ConnectionType connection=GCT_FBUS;
693 if (!strcmp(Connection, "irda")) connection=GCT_Irda;
694 if (!strcmp(Connection, "infrared")) connection=GCT_Infrared;
695 if (!strcmp(Connection, "mbus")) connection=GCT_MBUS;
696 if (!strcmp(Connection, "dlr3")) connection=GCT_DLR3;
697 if (!strcmp(Connection, "fbus3110")) connection=GCT_FBUS3110;
698 if (!strcmp(Connection, "at")) connection=GCT_AT;
699 if (!strcmp(Connection, "tekram210"))connection=GCT_Tekram;
705 bool GetMemoryTypeString(char *memorytext, GSM_MemoryType *type)
714 static GSM_MTStrings mystring[] = {
728 while (strcmp(mystring[i].name,"undefined")) {
729 if (*type==mystring[i].type) {
730 strcpy(memorytext,mystring[i].name);
738 bool GetMemoryTypeID(char *memorytext, GSM_MemoryType *type)
747 static GSM_MTStrings mystring[] = {
761 while (strcmp(mystring[i].name,"undefined")) {
762 if (strcmp(mystring[i].name,memorytext)==0) {
763 *type=mystring[i].type;
772 char *GetMygnokiiVersion() {
774 static char Buffer[1000]="";
776 sprintf(Buffer, "%s",VERSION);
782 1.Name,2.CodeName,3.Calendar,4.Netmonitor,5.Caller groups,6.Phonebook,
783 7.Authentication 8.Datacalls 9.KeysPressing 10.SMSC Default Recipient
784 11.SpeedDials 12.ScreenSavers 13.DTMF 14.SMS 15.NoPowerFrame 16.StartUpLogo
785 17.Profiles 18.Ringtones 19.WAP 20.RIngtonesNumber
788 static OnePhoneModel allmodels[] = {
790 /*1, 2, 3, 4, 5, 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 */
791 {"3210","NSE-8",{ 0,F_NETMON, 0, 0, 0, 0, 0,F_SMSCDEF,F_SPEED, 0, 0,F_SMS ,F_NOPOWER,F_STANIM,F_PROF51,F_RINGBIN, 0, 2}},
792 {"3210","NSE-9",{ 0,F_NETMON, 0, 0, 0, 0, 0,F_SMSCDEF,F_SPEED, 0, 0,F_SMS ,F_NOPOWER,F_STANIM,F_PROF51,F_RINGBIN, 0, 2}},
793 {"3310","NHM-5",{F_CAL33,F_NETMON, 0,F_PBK33SIM, 0, 0, 0,F_SMSCDEF,F_SPEED,F_SCRSAV, 0,F_SMS ,F_NOPOWER,F_STANIM,F_PROF33,F_RING_SM, 0, 7}},
794 {"3330","NHM-6",{F_CAL33,F_NETMON, 0,F_PBK33INT, 0, 0,F_KEYB,F_SMSCDEF,F_SPEED,F_SCRSAV, 0,F_SMS , 0,F_STANIM,F_PROF33,F_RING_SM,F_WAP, 7}},
795 {"5110","NSE-1",{ 0,F_NETMON, 0, 0,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED, 0,F_DTMF,F_SMS , 0, 0,F_PROF51, 0, 0, 0}},
796 {"5130","NSK-1",{ 0,F_NETMON, 0, 0,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED, 0,F_DTMF,F_SMS , 0, 0,F_PROF51, 0, 0, 0}},
797 {"5190","NSB-1",{ 0,F_NETMON, 0, 0,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED, 0,F_DTMF,F_SMS , 0, 0,F_PROF51, 0, 0, 0}},
798 {"6110","NSE-3",{F_CAL61,F_NETMON,F_CALER61,F_PBK61INT,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED, 0,F_DTMF,F_SMS , 0,F_STA ,F_PROF61,F_RINGBIN, 0, 1}},
799 {"6130","NSK-3",{F_CAL61,F_NETMON,F_CALER61,F_PBK61INT,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED, 0,F_DTMF,F_SMS , 0,F_STA ,F_PROF61,F_RINGBIN, 0, 1}},
800 {"6150","NSM-1",{F_CAL61,F_NETMON,F_CALER61,F_PBK61INT,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED, 0,F_DTMF,F_SMS , 0,F_STA ,F_PROF61,F_RINGBIN, 0, 1}},
801 {"6190","NSB-3",{F_CAL61,F_NETMON,F_CALER61,F_PBK61INT,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED, 0,F_DTMF,F_SMS , 0,F_STA ,F_PROF61,F_RINGBIN, 0, 1}},
802 {"6210","NPE-3",{F_CAL71,F_NETMON,F_CALER61,F_PBK71INT, 0,F_DATA71, 0,F_SMSCDEF,F_SPEED, 0, 0,F_SMS71, 0,F_STA62 ,F_PROF61,F_RINGBIN,F_WAP, 5}},
803 {"6250","NHM-3",{F_CAL71,F_NETMON,F_CALER61,F_PBK71INT, 0,F_DATA71, 0,F_SMSCDEF,F_SPEED, 0, 0,F_SMS71, 0,F_STA62 ,F_PROF61,F_RINGBIN,F_WAP, 5}},
804 {"7110","NSE-5",{F_CAL71,F_NETMON,F_CALER61,F_PBK71INT, 0,F_DATA71, 0,F_SMSCDEF,F_SPEED, 0, 0,F_SMS71, 0,F_STA71 ,F_PROF61,F_RINGBIN,F_WAP, 5}},
805 {"8210","NSM-3",{ 0,F_NETMON,F_CALER61,F_PBK61INT, 0,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED, 0,F_DTMF,F_SMS , 0,F_STA ,F_PROF61,F_RINGBIN, 0, 1}},
806 {"8850","NSM-2",{ 0,F_NETMON,F_CALER61,F_PBK61INT, 0,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED, 0,F_DTMF,F_SMS , 0,F_STA ,F_PROF61,F_RINGBIN, 0, 1}},
807 {"9210","RAE-3",{ 0,F_NETMON,F_CALER61, 0, 0,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED, 0,F_DTMF,F_SMS , 0,F_STA ,F_PROF61,F_RINGBIN, 0, 0}},//quesses only !
808 {"" ,"" ,{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
811 static OnePhoneModel *GetPhoneModelData (const char *num)
815 while (allmodels[i].number != "") {
816 if (strcmp (num, allmodels[i].number) == 0) {
817 return (&allmodels[i]);
822 return (&allmodels[i]);
825 char *GetModelName ()
827 static char model[64];
829 while (GSM->GetModel(model) != GE_NONE) sleep(1);
831 return (GetPhoneModelData(model)->model);
834 int GetModelFeature (featnum_index num)
836 static char model[64];
838 while (GSM->GetModel(model) != GE_NONE) sleep(1);
840 return (GetPhoneModelData(model)->features[num]);
844 int LogAvailable=-1; //-1 not checked earlier, 0 not, 1 yes
847 bool AppendLog(u8 *buffer, int length,bool format)
853 struct CFG_Header *cfg_info;
856 if (LogAvailable==-1) {
860 cfg_info=CFG_FindGnokiirc();
861 if (cfg_info==NULL) return false;
863 LogFile = CFG_Get(cfg_info, "global", "logfile");
868 file=fopen(logfilename, "a+");
870 /* We have first entry in this session and too large file */
871 if (fread( buffer2, 1, 50000,file )==50000) {
873 file=fopen(logfilename, "w");
877 if (LogAvailable==1) {
878 file=fopen(logfilename, "a");
882 if (LogAvailable==1) {
883 for (i=0;i<length;i++) {
885 fprintf(file, "%02x",buffer[i]);
887 case 0x09:fprintf(file,_(" |"));break;
889 if (isprint(buffer[i])) fprintf(file, _("%c|"),buffer[i]);
890 else fprintf(file, _(" |"));
894 fprintf(file, "%c",buffer[i]);
897 if (format) fprintf(file, "\n");
901 return (LogAvailable==1);
904 bool AppendLogText(u8 *buffer,bool format)
906 return AppendLog(buffer,strlen(buffer),format);