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;
265 if (strstr(InfoToCheck.InfraredModels, model) != NULL) {
266 if (connection==GCT_Infrared) found_match=true;
269 if (strstr(InfoToCheck.DLR3Models, model) != NULL) {
270 if (connection==GCT_DLR3) found_match=true;
272 if (strstr(InfoToCheck.IrdaModels, model) != NULL) {
273 if (connection==GCT_Irda) found_match=true;
275 if (strstr(InfoToCheck.ATModels, model) != NULL) {
276 if (connection==GCT_AT) found_match=true;
278 if (strstr(InfoToCheck.TekramModels, model) != NULL) {
279 if (connection==GCT_Tekram) found_match=true;
281 if (strstr(InfoToCheck.FBUS3110Models, model) != NULL) {
282 if (connection==GCT_FBUS3110) found_match=true;
291 GSM_Error TryNewNokia(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame)) {
294 unsigned char init_char = N6110_SYNC_BYTE;
296 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
299 if (Protocol->Initialise(device,initlength,connection,rlp_callback)!=GE_NONE)
301 return GE_NOTSUPPORTED;
304 if (connection!=GCT_MBUS) {
305 InitLength = atoi(initlength);
307 if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
308 InitLength = 250; /* This is the usual value, lower may work. */
312 fprintf(stdout,_("Writing init chars...."));
315 /* Initialise link with phone or what have you */
316 /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
318 for (count = 0; count < InitLength; count ++) {
320 Protocol->WritePhone(1,&init_char);
324 fprintf(stdout,_("Done\n"));
327 N6110_SendStatusRequest();
332 if (N6110_SendIDFrame()!=GE_NONE)
335 while (N6110_GetModel(phonemodel) != GE_NONE)
339 if (!strcmp(phonemodel,"NPE-3") || !strcmp(phonemodel,"NSE-5") ||
340 !strcmp(phonemodel,"NHM-3"))
344 /* Set pointers to relevant addresses */
345 GSM = &N7110_Functions;
346 GSM_Info = &N7110_Information;
347 GSM_LinkOK = &CurrentLinkOK;
356 extern GSM_Information N6110_Information;
357 extern GSM_Functions N6110_Functions;
359 GSM_Error GSM_Initialise(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame), char* SynchronizeTime)
361 bool found_match=false;
363 GSM_ConnectionType connection2;
372 connection2=connection;
374 CurrentRLP_RXCallback = rlp_callback;
375 CurrentCallPassup=NULL;
377 CurrentCallDivert=NULL;
379 CurrentPhonebookEntry=NULL;
381 CurrentNetworkInfo = NULL;
382 CurrentGetBitmap=NULL;
383 CurrentPlayToneError=GE_UNKNOWN;
384 strcpy(CurrentIncomingCall," ");
385 CurrentGetBinRingtone=NULL;
386 CurrentNetworkInfo=NULL;
388 CurrentRequestTerminate=false;
390 CurrentDisableKeepAlive=false;
391 CurrentCalendarNotesInfo.HowMany=2000;
392 CurrentSMSMessage=NULL;
394 CurrentMagicError = GE_BUSY;
397 if (!strcmp(model,"auto")) {
400 GSM = &N6110_Functions;
401 GSM_Info = &N6110_Information;
402 GSM_LinkOK = &CurrentLinkOK;
404 fprintf(stdout,_("Trying FBUS for new Nokia phones...\n"));
407 Protocol = &FBUS_Functions;
408 CurrentConnectionType=GCT_FBUS;
409 connection2=GCT_FBUS;
410 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
421 GSM = &N6110_Functions;
422 GSM_Info = &N6110_Information;
423 GSM_LinkOK = &CurrentLinkOK;
425 fprintf(stdout,_("Trying DLR3 for new Nokia phones...\n"));
428 Protocol = &FBUS_Functions;
429 CurrentConnectionType=GCT_DLR3;
430 connection2=GCT_DLR3;
431 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
443 GSM = &N6110_Functions;
444 GSM_Info = &N6110_Information;
445 GSM_LinkOK = &CurrentLinkOK;
447 fprintf(stdout,_("Trying MBUS for new Nokia phones...\n"));
450 Protocol = &MBUS_Functions;
451 CurrentConnectionType=GCT_MBUS;
452 connection2=GCT_MBUS;
453 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
461 if (!found_match) return GE_NOTSUPPORTED;
466 if (!strcmp(model,"modelauto")) {
468 GSM = &N6110_Functions;
469 GSM_Info = &N6110_Information;
470 GSM_LinkOK = &CurrentLinkOK;
472 fprintf(stdout,_("Trying to find connected model...\n"));
474 switch (connection) {
475 case GCT_FBUS : Protocol = &FBUS_Functions; break;
476 case GCT_Infrared: Protocol = &FBUS_Functions; break;
477 case GCT_Tekram : Protocol = &FBUS_Functions; break;
478 case GCT_DLR3 : Protocol = &FBUS_Functions; break;
479 case GCT_MBUS : Protocol = &MBUS_Functions; break;
480 case GCT_Irda : Protocol = &FBUSIRDA_Functions;break;
481 case GCT_AT : Protocol = &AT_Functions; break;
482 case GCT_FBUS3110: Protocol = &FBUS3110_Functions;break;
484 CurrentConnectionType=connection;
485 connection2=connection;
486 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
493 if (!found_match) return GE_NOTSUPPORTED;
502 if (CheckModel (Nsniff_Information, model, connection)) {
503 /* Set pointers to relevant addresses */
504 GSM = &Nsniff_Functions;
505 GSM_Info = &Nsniff_Information;
506 GSM_LinkOK = &CurrentLinkOK;
511 if (CheckModel (N3110_Information, model, connection)) {
512 /* Set pointers to relevant addresses */
513 GSM = &N3110_Functions;
514 GSM_Info = &N3110_Information;
515 GSM_LinkOK = &CurrentLinkOK;
519 if (CheckModel (N6110_Information, model, connection)) {
520 /* Set pointers to relevant addresses */
521 GSM = &N6110_Functions;
522 GSM_Info = &N6110_Information;
523 GSM_LinkOK = &CurrentLinkOK;
527 if (CheckModel (N7110_Information, model, connection)) {
528 /* Set pointers to relevant addresses */
529 GSM = &N7110_Functions;
530 GSM_Info = &N7110_Information;
531 GSM_LinkOK = &CurrentLinkOK;
534 if (CheckModel (Nat_Information, model, connection)) {
535 /* Set pointers to relevant addresses */
536 GSM = &Nat_Functions;
537 GSM_Info = &Nat_Information;
538 GSM_LinkOK = &CurrentLinkOK;
544 switch (connection) {
545 case GCT_FBUS : Protocol = &FBUS_Functions; break;
546 case GCT_Infrared: Protocol = &FBUS_Functions; break;
548 case GCT_Tekram : Protocol = &FBUS_Functions; break;
549 case GCT_DLR3 : Protocol = &FBUS_Functions; break;
550 case GCT_MBUS : Protocol = &MBUS_Functions; break;
551 case GCT_Irda : Protocol = &FBUSIRDA_Functions;break;
552 case GCT_AT : Protocol = &AT_Functions; break;
553 case GCT_FBUS3110: Protocol = &FBUS3110_Functions;break;
557 return GE_NOTSUPPORTED;
564 /* Now call model specific initialisation code. */
565 error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
568 /* RTH: FIXME: second try for Irda (6210 only?)*/
569 if ( error!=GE_NONE && connection == GCT_Irda)
572 fprintf(stdout,"Irda connection: second try!\n");
575 error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
580 if (error==GE_NONE && !strcmp(SynchronizeTime,"yes"))
583 now=localtime(&nowh);
585 Date.Year = now->tm_year;
586 Date.Month = now->tm_mon+1;
587 Date.Day = now->tm_mday;
588 Date.Hour = now->tm_hour;
589 Date.Minute = now->tm_min;
590 Date.Second = now->tm_sec;
595 /* Well, this thing is copyrighted in U.S. This technique is known as
596 Windowing and you can read something about it in LinuxWeekly News:
597 http://lwn.net/1999/features/Windowing.phtml. This thing is beeing
598 written in Czech republic and Poland where algorithms are not allowed
602 Date.Year = Date.Year+1900;
604 Date.Year = Date.Year+2000;
607 /* FIXME: Error checking should be here. */
608 GSM->SetDateTime(&Date);
617 GSM_Error Unimplemented(void)
619 return GE_NOTIMPLEMENTED;
622 GSM_Error NotSupported(void)
624 return GE_NOTSUPPORTED;
629 /* Applications should call N6110_Terminate to shut down the N6110 thread and
630 close the serial port. */
631 void NULL_Terminate(void)
633 Protocol->Terminate();
637 /* Here are things made for keeping connecting */
638 void NULL_KeepAlive()
642 /* Here are things made for keeping connecting */
643 void NULL_KeepAlive()
649 void NULL_TX_DisplayMessage(u16 MessageLength, u8 *MessageBuffer)
651 fprintf(stdout, _("PC: "));
653 txhexdump(MessageLength,MessageBuffer);
657 bool NULL_WritePhone (u16 length, u8 *buffer) {
658 if (device_write(buffer,length)!=length) return false;
662 GSM_Error NULL_WaitUntil (int time, GSM_Error *value)
668 /* Wait for timeout or other error. */
669 while (timeout != 0 && *value == GE_BUSY ) {
680 GSM_Error NULL_SendMessageSequence (int time, GSM_Error *value,
681 u16 message_length, u8 message_type, u8 *buffer)
685 Protocol->SendMessage(message_length, message_type, buffer);
687 return NULL_WaitUntil (time, value);
690 GSM_ConnectionType GetConnectionTypeFromString(char *Connection) {
692 GSM_ConnectionType connection=GCT_FBUS;
695 if (!strcmp(Connection, "irda")) connection=GCT_Irda;
697 if (!strcmp(Connection, "infrared")) connection=GCT_Infrared;
699 if (!strcmp(Connection, "mbus")) connection=GCT_MBUS;
700 if (!strcmp(Connection, "dlr3")) connection=GCT_DLR3;
701 if (!strcmp(Connection, "fbus3110")) connection=GCT_FBUS3110;
702 if (!strcmp(Connection, "at")) connection=GCT_AT;
703 if (!strcmp(Connection, "tekram210"))connection=GCT_Tekram;
709 bool GetMemoryTypeString(char *memorytext, GSM_MemoryType *type)
718 static GSM_MTStrings mystring[] = {
732 while (strcmp(mystring[i].name,"undefined")) {
733 if (*type==mystring[i].type) {
734 strcpy(memorytext,mystring[i].name);
742 bool GetMemoryTypeID(char *memorytext, GSM_MemoryType *type)
751 static GSM_MTStrings mystring[] = {
765 while (strcmp(mystring[i].name,"undefined")) {
766 if (strcmp(mystring[i].name,memorytext)==0) {
767 *type=mystring[i].type;
776 char *GetMygnokiiVersion() {
778 static char Buffer[1000]="";
780 sprintf(Buffer, "%s",VERSION);
786 1.Name,2.CodeName,3.Calendar,4.Netmonitor,5.Caller groups,6.Phonebook,
787 7.Authentication 8.Datacalls 9.KeysPressing 10.SMSC Default Recipient
788 11.SpeedDials 12.ScreenSavers 13.DTMF 14.SMS 15.NoPowerFrame 16.StartUpLogo
789 17.Profiles 18.Ringtones 19.WAP 20.RIngtonesNumber
792 static OnePhoneModel allmodels[] = {
794 /*1, 2, 3, 4, 5, 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 */
795 {"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}},
796 {"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}},
797 {"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}},
798 {"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}},
799 {"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}},
800 {"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}},
801 {"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}},
802 {"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}},
803 {"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}},
804 {"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}},
805 {"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}},
806 {"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}},
807 {"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}},
808 {"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}},
809 {"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}},
810 {"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}},
811 {"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 !
812 {"" ,"" ,{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
815 static OnePhoneModel *GetPhoneModelData (const char *num)
819 while (allmodels[i].number != "") {
820 if (strcmp (num, allmodels[i].number) == 0) {
821 return (&allmodels[i]);
826 return (&allmodels[i]);
829 char *GetModelName ()
831 static char model[64];
833 while (GSM->GetModel(model) != GE_NONE) sleep(1);
835 return (GetPhoneModelData(model)->model);
838 int GetModelFeature (featnum_index num)
840 static char model[64];
842 while (GSM->GetModel(model) != GE_NONE) sleep(1);
844 return (GetPhoneModelData(model)->features[num]);
848 int LogAvailable=-1; //-1 not checked earlier, 0 not, 1 yes
851 bool AppendLog(u8 *buffer, int length,bool format)
857 struct CFG_Header *cfg_info;
860 if (LogAvailable==-1) {
864 cfg_info=CFG_FindGnokiirc();
865 if (cfg_info==NULL) return false;
867 LogFile = CFG_Get(cfg_info, "global", "logfile");
872 file=fopen(logfilename, "a+");
874 /* We have first entry in this session and too large file */
875 if (fread( buffer2, 1, 50000,file )==50000) {
877 file=fopen(logfilename, "w");
881 if (LogAvailable==1) {
882 file=fopen(logfilename, "a");
886 if (LogAvailable==1) {
887 for (i=0;i<length;i++) {
889 fprintf(file, "%02x",buffer[i]);
891 case 0x09:fprintf(file,_(" |"));break;
893 if (isprint(buffer[i])) fprintf(file, _("%c|"),buffer[i]);
894 else fprintf(file, _(" |"));
898 fprintf(file, "%c",buffer[i]);
901 if (format) fprintf(file, "\n");
905 return (LogAvailable==1);
908 bool AppendLogText(u8 *buffer,bool format)
910 return AppendLog(buffer,strlen(buffer),format);