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.
28 #include "misc_win32.h"
33 #include "newmodules/n3110.h"
34 #include "newmodules/n6110.h"
35 #include "newmodules/n7110.h"
36 #include "newmodules/newat.h"
38 #include "newmodules/sniff/sniff.h"
40 #include "protocol/fbusirda.h"
41 #include "protocol/fbus.h"
42 #include "protocol/fbus3110.h"
43 #include "protocol/mbus.h"
44 #include "protocol/at.h"
45 #include "files/cfgreader.h"
48 #include "devices/device.h"
52 /* for VC6 make scripts save VERSION constant in mversion.h file */
56 /* GSM_LinkOK is set to true once normal communications with the phone have
61 /* Define pointer to the GSM_Functions structure used by external code to call
62 relevant API functions. This structure is defined in gsm-common.h. */
66 /* Define pointer to the GSM_Information structure used by external code to
67 obtain information that varies from model to model. This structure is also
68 defined in gsm-common.h */
70 GSM_Information *GSM_Info;
72 /* Initialise interface to the phone. Model number should be a string such as
73 3810, 5110, 6110 etc. Device is the serial port to use e.g. /dev/ttyS0, the
74 user must have write permission to the device. */
76 GSM_Protocol *Protocol;
78 /* Local variables used by get/set phonebook entry code. Buffer is used as a
79 source or destination for phonebook data and other functions... Error is
80 set to GE_NONE by calling function, set to GE_COMPLETE or an error code by
81 handler routines as appropriate. */
83 GSM_PhonebookEntry *CurrentPhonebookEntry;
84 GSM_Error CurrentPhonebookError;
86 GSM_SpeedDial *CurrentSpeedDialEntry;
87 GSM_Error CurrentSpeedDialError;
89 unsigned char Current_IMEI[GSM_MAX_IMEI_LENGTH];
90 unsigned char Current_Revision[GSM_MAX_REVISION_LENGTH];
91 unsigned char Current_Model[GSM_MAX_MODEL_LENGTH];
93 GSM_SMSMessage *CurrentSMSMessage;
94 GSM_Error CurrentSMSMessageError;
95 int CurrentSMSPointer;
97 GSM_SMSFolders *CurrentSMSFolders;
98 GSM_Error CurrentSMSFoldersError;
99 int CurrentSMSFoldersCount;
101 GSM_OneSMSFolder CurrentSMSFolder;
102 GSM_Error CurrentSMSFolderError;
103 int CurrentSMSFolderID;
105 GSM_MemoryStatus *CurrentMemoryStatus;
106 GSM_Error CurrentMemoryStatusError;
108 GSM_NetworkInfo *CurrentNetworkInfo;
109 GSM_Error CurrentNetworkInfoError;
111 GSM_SMSStatus *CurrentSMSStatus;
112 GSM_Error CurrentSMSStatusError;
114 GSM_MessageCenter *CurrentMessageCenter;
115 GSM_Error CurrentMessageCenterError;
117 int *CurrentSecurityCodeStatus;
118 GSM_Error CurrentSecurityCodeError;
119 GSM_SecurityCode *CurrentSecurityCode;
121 GSM_DateTime *CurrentDateTime;
122 GSM_Error CurrentDateTimeError;
124 GSM_DateTime *CurrentAlarm;
125 GSM_Error CurrentAlarmError;
127 GSM_CalendarNote *CurrentCalendarNote;
128 GSM_Error CurrentCalendarNoteError;
130 GSM_NotesInfo CurrentCalendarNotesInfo,*CurrentCalendarNotesInfo2;
131 GSM_Error CurrentCalendarNotesInfoError;
133 GSM_Error CurrentSetDateTimeError;
134 GSM_Error CurrentSetAlarmError;
136 GSM_Error CurrentEnableExtendedCommandsError;
142 int CurrentDisplayStatus;
143 GSM_Error CurrentDisplayStatusError;
145 GSM_Error CurrentResetPhoneSettingsError;
147 char *CurrentNetmonitor;
148 GSM_Error CurrentNetmonitorError;
150 GSM_Bitmap *CurrentGetBitmap=NULL;
151 GSM_Error CurrentGetBitmapError;
153 GSM_Error CurrentSetBitmapError;
155 GSM_Error CurrentSendDTMFError;
157 GSM_Profile *CurrentProfile;
158 GSM_Error CurrentProfileError;
160 GSM_Error CurrentDisplayOutputError;
162 GSM_CBMessage *CurrentCBMessage;
163 GSM_Error CurrentCBError;
165 int CurrentPressKeyEvent;
166 GSM_Error CurrentPressKeyError;
168 GSM_Error CurrentPlayToneError=GE_UNKNOWN;
170 GSM_Error CurrentDialVoiceError;
172 GSM_Error CurrentGetOperatorNameError;
173 GSM_Network *CurrentGetOperatorNameNetwork;
174 GSM_Error CurrentSetOperatorNameError;
176 GSM_Error CurrentGetIMEIError;
178 GSM_Error CurrentGetHWError;
180 unsigned char CurrentPPS[4];
181 GSM_Error CurrentProductProfileSettingsError;
183 char CurrentIncomingCall[20];
185 GSM_Error CurrentBinRingtoneError;
186 GSM_BinRingtone *CurrentGetBinRingtone=NULL;
188 GSM_Error CurrentRingtoneError;
190 GSM_Error CurrentMagicError;
192 GSM_Error CurrentSimlockInfoError;
193 GSM_AllSimlocks *CurrentSimLock;
195 GSM_Error CurrentGetWAPBookmarkError;
196 GSM_Error CurrentSetWAPBookmarkError;
197 GSM_WAPBookmark *WAPBookmark;
199 GSM_Error CurrentGetWAPSettingsError;
200 GSM_WAPSettings *WAPSettings;
202 GSM_Error CurrentCallDivertError;
203 GSM_CallDivert *CurrentCallDivert;
205 char *CurrentManufacturer;
207 /* This is the connection type used in gnokii. */
208 GSM_ConnectionType CurrentConnectionType;
210 /* Pointer to a callback function used to return changes to a calls status */
211 /* This saves unreliable polling */
212 void (*CurrentCallPassup)(char c);
214 /* Pointer to callback function in user code to be called when RLP frames
216 void (*CurrentRLP_RXCallback)(RLP_F96Frame *frame);
218 /* Used to disconnect the call */
219 u8 CurrentCallSequenceNumber;
223 bool CurrentRequestTerminate;
225 bool CurrentDisableKeepAlive;
227 bool CheckModel (GSM_Information InfoToCheck, char *model, GSM_ConnectionType connection) {
229 bool found_match=false;
231 if (strstr(InfoToCheck.FBUSModels, model) != NULL) {
232 if (connection==GCT_FBUS) found_match=true;
234 if (strstr(InfoToCheck.MBUSModels, model) != NULL) {
235 if (connection==GCT_MBUS) found_match=true;
237 if (strstr(InfoToCheck.InfraredModels, model) != NULL) {
238 if (connection==GCT_Infrared) found_match=true;
240 if (strstr(InfoToCheck.DLR3Models, model) != NULL) {
241 if (connection==GCT_DLR3) found_match=true;
243 if (strstr(InfoToCheck.IrdaModels, model) != NULL) {
244 if (connection==GCT_Irda) found_match=true;
246 if (strstr(InfoToCheck.ATModels, model) != NULL) {
247 if (connection==GCT_AT) found_match=true;
249 if (strstr(InfoToCheck.TekramModels, model) != NULL) {
250 if (connection==GCT_Tekram) found_match=true;
252 if (strstr(InfoToCheck.FBUS3110Models, model) != NULL) {
253 if (connection==GCT_FBUS3110) found_match=true;
259 GSM_Error TryNewNokia(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame)) {
262 unsigned char init_char = N6110_SYNC_BYTE;
264 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
267 if (Protocol->Initialise(device,initlength,connection,rlp_callback)!=GE_NONE)
269 return GE_NOTSUPPORTED;
272 if (connection!=GCT_MBUS) {
273 InitLength = atoi(initlength);
275 if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
276 InitLength = 250; /* This is the usual value, lower may work. */
280 fprintf(stdout,_("Writing init chars...."));
283 /* Initialise link with phone or what have you */
284 /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
286 for (count = 0; count < InitLength; count ++) {
288 Protocol->WritePhone(1,&init_char);
292 fprintf(stdout,_("Done\n"));
295 N6110_SendStatusRequest();
300 if (N6110_SendIDFrame()!=GE_NONE)
303 while (N6110_GetModel(phonemodel) != GE_NONE)
306 if (!strcmp(phonemodel,"NPE-3") || !strcmp(phonemodel,"NSE-5") ||
307 !strcmp(phonemodel,"NHM-3"))
311 /* Set pointers to relevant addresses */
312 GSM = &N7110_Functions;
313 GSM_Info = &N7110_Information;
314 GSM_LinkOK = &CurrentLinkOK;
321 GSM_Error GSM_Initialise(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame), char* SynchronizeTime)
323 bool found_match=false;
325 GSM_ConnectionType connection2;
332 connection2=connection;
334 CurrentRLP_RXCallback = rlp_callback;
335 CurrentCallPassup=NULL;
336 CurrentCallDivert=NULL;
337 CurrentPhonebookEntry=NULL;
338 CurrentNetworkInfo = NULL;
339 CurrentGetBitmap=NULL;
340 CurrentPlayToneError=GE_UNKNOWN;
341 strcpy(CurrentIncomingCall," ");
342 CurrentGetBinRingtone=NULL;
343 CurrentNetworkInfo=NULL;
344 CurrentRequestTerminate=false;
345 CurrentDisableKeepAlive=false;
346 CurrentCalendarNotesInfo.HowMany=2000;
347 CurrentSMSMessage=NULL;
348 CurrentMagicError = GE_BUSY;
350 if (!strcmp(model,"auto")) {
353 GSM = &N6110_Functions;
354 GSM_Info = &N6110_Information;
355 GSM_LinkOK = &CurrentLinkOK;
357 fprintf(stdout,_("Trying FBUS for new Nokia phones...\n"));
360 Protocol = &FBUS_Functions;
361 CurrentConnectionType=GCT_FBUS;
362 connection2=GCT_FBUS;
363 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
374 GSM = &N6110_Functions;
375 GSM_Info = &N6110_Information;
376 GSM_LinkOK = &CurrentLinkOK;
378 fprintf(stdout,_("Trying DLR3 for new Nokia phones...\n"));
381 Protocol = &FBUS_Functions;
382 CurrentConnectionType=GCT_DLR3;
383 connection2=GCT_DLR3;
384 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
396 GSM = &N6110_Functions;
397 GSM_Info = &N6110_Information;
398 GSM_LinkOK = &CurrentLinkOK;
400 fprintf(stdout,_("Trying MBUS for new Nokia phones...\n"));
403 Protocol = &MBUS_Functions;
404 CurrentConnectionType=GCT_MBUS;
405 connection2=GCT_MBUS;
406 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
414 if (!found_match) return GE_NOTSUPPORTED;
419 if (!strcmp(model,"modelauto")) {
421 GSM = &N6110_Functions;
422 GSM_Info = &N6110_Information;
423 GSM_LinkOK = &CurrentLinkOK;
425 fprintf(stdout,_("Trying to find connected model...\n"));
427 switch (connection) {
428 case GCT_FBUS : Protocol = &FBUS_Functions; break;
429 case GCT_Infrared: Protocol = &FBUS_Functions; break;
430 case GCT_Tekram : Protocol = &FBUS_Functions; break;
431 case GCT_DLR3 : Protocol = &FBUS_Functions; break;
432 case GCT_MBUS : Protocol = &MBUS_Functions; break;
433 case GCT_Irda : Protocol = &FBUSIRDA_Functions;break;
434 case GCT_AT : Protocol = &AT_Functions; break;
435 case GCT_FBUS3110: Protocol = &FBUS3110_Functions;break;
437 CurrentConnectionType=connection;
438 connection2=connection;
439 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
446 if (!found_match) return GE_NOTSUPPORTED;
452 if (CheckModel (Nsniff_Information, model, connection)) {
453 /* Set pointers to relevant addresses */
454 GSM = &Nsniff_Functions;
455 GSM_Info = &Nsniff_Information;
456 GSM_LinkOK = &CurrentLinkOK;
461 if (CheckModel (N3110_Information, model, connection)) {
462 /* Set pointers to relevant addresses */
463 GSM = &N3110_Functions;
464 GSM_Info = &N3110_Information;
465 GSM_LinkOK = &CurrentLinkOK;
468 if (CheckModel (N6110_Information, model, connection)) {
469 /* Set pointers to relevant addresses */
470 GSM = &N6110_Functions;
471 GSM_Info = &N6110_Information;
472 GSM_LinkOK = &CurrentLinkOK;
475 if (CheckModel (N7110_Information, model, connection)) {
476 /* Set pointers to relevant addresses */
477 GSM = &N7110_Functions;
478 GSM_Info = &N7110_Information;
479 GSM_LinkOK = &CurrentLinkOK;
482 if (CheckModel (Nat_Information, model, connection)) {
483 /* Set pointers to relevant addresses */
484 GSM = &Nat_Functions;
485 GSM_Info = &Nat_Information;
486 GSM_LinkOK = &CurrentLinkOK;
491 switch (connection) {
492 case GCT_FBUS : Protocol = &FBUS_Functions; break;
493 case GCT_Infrared: Protocol = &FBUS_Functions; break;
494 case GCT_Tekram : Protocol = &FBUS_Functions; break;
495 case GCT_DLR3 : Protocol = &FBUS_Functions; break;
496 case GCT_MBUS : Protocol = &MBUS_Functions; break;
497 case GCT_Irda : Protocol = &FBUSIRDA_Functions;break;
498 case GCT_AT : Protocol = &AT_Functions; break;
499 case GCT_FBUS3110: Protocol = &FBUS3110_Functions;break;
502 return GE_NOTSUPPORTED;
507 /* Now call model specific initialisation code. */
508 error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
510 /* RTH: FIXME: second try for Irda (6210 only?)*/
511 if ( error!=GE_NONE && connection == GCT_Irda)
514 fprintf(stdout,"Irda connection: second try!\n");
517 error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
520 if (error==GE_NONE && !strcmp(SynchronizeTime,"yes"))
523 now=localtime(&nowh);
525 Date.Year = now->tm_year;
526 Date.Month = now->tm_mon+1;
527 Date.Day = now->tm_mday;
528 Date.Hour = now->tm_hour;
529 Date.Minute = now->tm_min;
530 Date.Second = now->tm_sec;
535 /* Well, this thing is copyrighted in U.S. This technique is known as
536 Windowing and you can read something about it in LinuxWeekly News:
537 http://lwn.net/1999/features/Windowing.phtml. This thing is beeing
538 written in Czech republic and Poland where algorithms are not allowed
542 Date.Year = Date.Year+1900;
544 Date.Year = Date.Year+2000;
547 /* FIXME: Error checking should be here. */
548 GSM->SetDateTime(&Date);
554 GSM_Error Unimplemented(void)
556 return GE_NOTIMPLEMENTED;
559 GSM_Error NotSupported(void)
561 return GE_NOTSUPPORTED;
564 /* Applications should call N6110_Terminate to shut down the N6110 thread and
565 close the serial port. */
566 void NULL_Terminate(void)
568 Protocol->Terminate();
572 /* Here are things made for keeping connecting */
573 void NULL_KeepAlive()
577 /* Here are things made for keeping connecting */
578 void NULL_KeepAlive()
584 void NULL_TX_DisplayMessage(u16 MessageLength, u8 *MessageBuffer)
586 fprintf(stdout, _("PC: "));
588 txhexdump(MessageLength,MessageBuffer);
592 bool NULL_WritePhone (u16 length, u8 *buffer) {
593 if (device_write(buffer,length)!=length) return false;
597 GSM_Error NULL_WaitUntil (int time, GSM_Error *value)
603 /* Wait for timeout or other error. */
604 while (timeout != 0 && *value == GE_BUSY ) {
615 GSM_Error NULL_SendMessageSequence (int time, GSM_Error *value,
616 u16 message_length, u8 message_type, u8 *buffer)
620 Protocol->SendMessage(message_length, message_type, buffer);
622 return NULL_WaitUntil (time, value);
625 GSM_ConnectionType GetConnectionTypeFromString(char *Connection) {
627 GSM_ConnectionType connection=GCT_FBUS;
629 if (!strcmp(Connection, "irda")) connection=GCT_Irda;
630 if (!strcmp(Connection, "infrared")) connection=GCT_Infrared;
631 if (!strcmp(Connection, "mbus")) connection=GCT_MBUS;
632 if (!strcmp(Connection, "dlr3")) connection=GCT_DLR3;
633 if (!strcmp(Connection, "fbus3110")) connection=GCT_FBUS3110;
634 if (!strcmp(Connection, "at")) connection=GCT_AT;
635 if (!strcmp(Connection, "tekram210"))connection=GCT_Tekram;
640 bool GetMemoryTypeString(char *memorytext, GSM_MemoryType *type)
649 GSM_MTStrings mystring[] = {
663 while (strcmp(mystring[i].name,"undefined")) {
664 if (*type==mystring[i].type) {
665 strcpy(memorytext,mystring[i].name);
673 bool GetMemoryTypeID(char *memorytext, GSM_MemoryType *type)
682 GSM_MTStrings mystring[] = {
696 while (strcmp(mystring[i].name,"undefined")) {
697 if (strcmp(mystring[i].name,memorytext)==0) {
698 *type=mystring[i].type;
707 char *GetMygnokiiVersion() {
709 static char Buffer[1000]="";
711 sprintf(Buffer, "%s",VERSION);
717 1.Name,2.CodeName,3.Calendar,4.Netmonitor,5.Caller groups,6.Phonebook,
718 7.Authentication 8.Datacalls 9.KeysPressing 10.SMSC Default Recipient
719 11.SpeedDials 12.ScreenSavers 13.DTMF 14.SMS 15.NoPowerFrame 16.StartUpLogo
720 17.Profiles 18.Ringtones 19.WAP 20.RIngtonesNumber
723 static OnePhoneModel allmodels[] = {
725 /*1, 2, 3, 4, 5, 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 */
726 {"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}},
727 {"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}},
728 {"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}},
729 {"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}},
730 {"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}},
731 {"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}},
732 {"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}},
733 {"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}},
734 {"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}},
735 {"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}},
736 {"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}},
737 {"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}},
738 {"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}},
739 {"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}},
740 {"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}},
741 {"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}},
742 {"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 !
743 {"" ,"" ,{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
746 OnePhoneModel *GetPhoneModelData (const char *num)
750 while (allmodels[i].number != "") {
751 if (strcmp (num, allmodels[i].number) == 0) {
752 return (&allmodels[i]);
757 return (&allmodels[i]);
760 char *GetModelName ()
762 static char model[64];
764 while (GSM->GetModel(model) != GE_NONE) sleep(1);
766 return (GetPhoneModelData(model)->model);
769 int GetModelFeature (featnum_index num)
771 static char model[64];
773 while (GSM->GetModel(model) != GE_NONE) sleep(1);
775 return (GetPhoneModelData(model)->features[num]);
778 int LogAvailable=-1; //-1 not checked earlier, 0 not, 1 yes
781 bool AppendLog(u8 *buffer, int length,bool format)
787 struct CFG_Header *cfg_info;
790 if (LogAvailable==-1) {
794 cfg_info=CFG_FindGnokiirc();
795 if (cfg_info==NULL) return false;
797 LogFile = CFG_Get(cfg_info, "global", "logfile");
802 file=fopen(logfilename, "a+");
804 /* We have first entry in this session and too large file */
805 if (fread( buffer2, 1, 50000,file )==50000) {
807 file=fopen(logfilename, "w");
811 if (LogAvailable==1) {
812 file=fopen(logfilename, "a");
816 if (LogAvailable==1) {
817 for (i=0;i<length;i++) {
819 fprintf(file, "%02x",buffer[i]);
821 case 0x09:fprintf(file,_(" |"));break;
823 if (isprint(buffer[i])) fprintf(file, _("%c|"),buffer[i]);
824 else fprintf(file, _(" |"));
828 fprintf(file, "%c",buffer[i]);
831 if (format) fprintf(file, "\n");
835 return (LogAvailable==1);
838 bool AppendLogText(u8 *buffer,bool format)
840 return AppendLog(buffer,strlen(buffer),format);