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/n6110.h"
34 #include "newmodules/n7110.h"
35 #include "newmodules/newat.h"
37 #include "newmodules/sniff/sniff.h"
39 #include "protocol/fbusirda.h"
40 #include "protocol/fbus.h"
41 #include "protocol/mbus.h"
42 #include "protocol/at.h"
43 #include "files/cfgreader.h"
46 #include "devices/device.h"
50 /* for VC6 make scripts save VERSION constant in mversion.h file */
54 /* GSM_LinkOK is set to true once normal communications with the phone have
59 /* Define pointer to the GSM_Functions structure used by external code to call
60 relevant API functions. This structure is defined in gsm-common.h. */
64 /* Define pointer to the GSM_Information structure used by external code to
65 obtain information that varies from model to model. This structure is also
66 defined in gsm-common.h */
68 GSM_Information *GSM_Info;
70 /* Initialise interface to the phone. Model number should be a string such as
71 3810, 5110, 6110 etc. Device is the serial port to use e.g. /dev/ttyS0, the
72 user must have write permission to the device. */
74 GSM_Protocol *Protocol;
76 /* Local variables used by get/set phonebook entry code. Buffer is used as a
77 source or destination for phonebook data and other functions... Error is
78 set to GE_NONE by calling function, set to GE_COMPLETE or an error code by
79 handler routines as appropriate. */
81 GSM_PhonebookEntry *CurrentPhonebookEntry;
82 GSM_Error CurrentPhonebookError;
84 GSM_SpeedDial *CurrentSpeedDialEntry;
85 GSM_Error CurrentSpeedDialError;
87 unsigned char Current_IMEI[GSM_MAX_IMEI_LENGTH];
88 unsigned char Current_Revision[GSM_MAX_REVISION_LENGTH];
89 unsigned char Current_Model[GSM_MAX_MODEL_LENGTH];
91 GSM_SMSMessage *CurrentSMSMessage;
92 GSM_Error CurrentSMSMessageError;
93 int CurrentSMSPointer;
95 GSM_SMSFolders *CurrentSMSFolders;
96 GSM_Error CurrentSMSFoldersError;
97 int CurrentSMSFoldersCount;
99 GSM_OneSMSFolder CurrentSMSFolder;
100 GSM_Error CurrentSMSFolderError;
101 int CurrentSMSFolderID;
103 GSM_MemoryStatus *CurrentMemoryStatus;
104 GSM_Error CurrentMemoryStatusError;
106 GSM_NetworkInfo *CurrentNetworkInfo;
107 GSM_Error CurrentNetworkInfoError;
109 GSM_SMSStatus *CurrentSMSStatus;
110 GSM_Error CurrentSMSStatusError;
112 GSM_MessageCenter *CurrentMessageCenter;
113 GSM_Error CurrentMessageCenterError;
115 int *CurrentSecurityCodeStatus;
116 GSM_Error CurrentSecurityCodeError;
117 GSM_SecurityCode *CurrentSecurityCode;
119 GSM_DateTime *CurrentDateTime;
120 GSM_Error CurrentDateTimeError;
122 GSM_DateTime *CurrentAlarm;
123 GSM_Error CurrentAlarmError;
125 GSM_CalendarNote *CurrentCalendarNote;
126 GSM_Error CurrentCalendarNoteError;
128 GSM_NotesInfo CurrentCalendarNotesInfo,*CurrentCalendarNotesInfo2;
129 GSM_Error CurrentCalendarNotesInfoError;
131 GSM_Error CurrentSetDateTimeError;
132 GSM_Error CurrentSetAlarmError;
134 GSM_Error CurrentEnableExtendedCommandsError;
140 int CurrentDisplayStatus;
141 GSM_Error CurrentDisplayStatusError;
143 GSM_Error CurrentResetPhoneSettingsError;
145 char *CurrentNetmonitor;
146 GSM_Error CurrentNetmonitorError;
148 GSM_Bitmap *CurrentGetBitmap=NULL;
149 GSM_Error CurrentGetBitmapError;
151 GSM_Error CurrentSetBitmapError;
153 GSM_Error CurrentSendDTMFError;
155 GSM_Profile *CurrentProfile;
156 GSM_Error CurrentProfileError;
158 GSM_Error CurrentDisplayOutputError;
160 GSM_CBMessage *CurrentCBMessage;
161 GSM_Error CurrentCBError;
163 int CurrentPressKeyEvent;
164 GSM_Error CurrentPressKeyError;
166 GSM_Error CurrentPlayToneError=GE_UNKNOWN;
168 GSM_Error CurrentDialVoiceError;
170 GSM_Error CurrentGetOperatorNameError;
171 GSM_Network *CurrentGetOperatorNameNetwork;
172 GSM_Error CurrentSetOperatorNameError;
174 GSM_Error CurrentGetIMEIError;
176 GSM_Error CurrentGetHWError;
178 unsigned char CurrentPPS[4];
179 GSM_Error CurrentProductProfileSettingsError;
181 char CurrentIncomingCall[20];
183 GSM_Error CurrentBinRingtoneError;
184 GSM_BinRingtone *CurrentGetBinRingtone=NULL;
186 GSM_Error CurrentRingtoneError;
188 GSM_Error CurrentMagicError;
190 GSM_Error CurrentSimlockInfoError;
191 GSM_AllSimlocks *CurrentSimLock;
193 GSM_Error CurrentGetWAPBookmarkError;
194 GSM_Error CurrentSetWAPBookmarkError;
195 GSM_WAPBookmark *WAPBookmark;
197 GSM_Error CurrentGetWAPSettingsError;
198 GSM_WAPSettings *WAPSettings;
200 GSM_Error CurrentCallDivertError;
201 GSM_CallDivert *CurrentCallDivert;
203 char *CurrentManufacturer;
205 /* This is the connection type used in gnokii. */
206 GSM_ConnectionType CurrentConnectionType;
208 /* Pointer to a callback function used to return changes to a calls status */
209 /* This saves unreliable polling */
210 void (*CurrentCallPassup)(char c);
212 /* Pointer to callback function in user code to be called when RLP frames
214 void (*CurrentRLP_RXCallback)(RLP_F96Frame *frame);
216 /* Used to disconnect the call */
217 u8 CurrentCallSequenceNumber;
221 bool CurrentRequestTerminate;
223 bool CurrentDisableKeepAlive;
225 bool CheckModel (GSM_Information InfoToCheck, char *model, GSM_ConnectionType connection) {
227 bool found_match=false;
229 if (strstr(InfoToCheck.FBUSModels, model) != NULL) {
230 if (connection==GCT_FBUS) found_match=true;
232 if (strstr(InfoToCheck.MBUSModels, model) != NULL) {
233 if (connection==GCT_MBUS) found_match=true;
235 if (strstr(InfoToCheck.InfraredModels, model) != NULL) {
236 if (connection==GCT_Infrared) found_match=true;
238 if (strstr(InfoToCheck.DLR3Models, model) != NULL) {
239 if (connection==GCT_DLR3) found_match=true;
241 if (strstr(InfoToCheck.IrdaModels, model) != NULL) {
242 if (connection==GCT_Irda) found_match=true;
244 if (strstr(InfoToCheck.ATModels, model) != NULL) {
245 if (connection==GCT_AT) found_match=true;
247 if (strstr(InfoToCheck.TekramModels, model) != NULL) {
248 if (connection==GCT_Tekram) found_match=true;
254 GSM_Error TryNewNokia(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame)) {
257 unsigned char init_char = N6110_SYNC_BYTE;
259 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
262 if (Protocol->Initialise(device,initlength,connection,rlp_callback)!=GE_NONE)
264 return GE_NOTSUPPORTED;
267 if (connection!=GCT_MBUS) {
268 InitLength = atoi(initlength);
270 if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
271 InitLength = 250; /* This is the usual value, lower may work. */
275 fprintf(stdout,_("Writing init chars...."));
278 /* Initialise link with phone or what have you */
279 /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
281 for (count = 0; count < InitLength; count ++) {
283 Protocol->WritePhone(1,&init_char);
287 fprintf(stdout,_("Done\n"));
290 N6110_SendStatusRequest();
295 if (N6110_SendIDFrame()!=GE_NONE)
298 while (N6110_GetModel(phonemodel) != GE_NONE)
301 if (!strcmp(phonemodel,"NPE-3") || !strcmp(phonemodel,"NSE-5"))
305 /* Set pointers to relevant addresses */
306 GSM = &N7110_Functions;
307 GSM_Info = &N7110_Information;
308 GSM_LinkOK = &CurrentLinkOK;
315 GSM_Error GSM_Initialise(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame), char* SynchronizeTime)
317 bool found_match=false;
319 GSM_ConnectionType connection2;
326 connection2=connection;
328 CurrentRLP_RXCallback = rlp_callback;
329 CurrentCallPassup=NULL;
330 CurrentCallDivert=NULL;
331 CurrentPhonebookEntry=NULL;
332 CurrentNetworkInfo = NULL;
333 CurrentGetBitmap=NULL;
334 CurrentPlayToneError=GE_UNKNOWN;
335 strcpy(CurrentIncomingCall," ");
336 CurrentGetBinRingtone=NULL;
337 CurrentNetworkInfo=NULL;
338 CurrentRequestTerminate=false;
339 CurrentDisableKeepAlive=false;
340 CurrentCalendarNotesInfo.HowMany=2000;
341 CurrentSMSMessage=NULL;
342 CurrentMagicError = GE_BUSY;
344 if (!strcmp(model,"auto")) {
347 GSM = &N6110_Functions;
348 GSM_Info = &N6110_Information;
349 GSM_LinkOK = &CurrentLinkOK;
351 fprintf(stdout,_("Trying FBUS for new Nokia phones...\n"));
354 Protocol = &FBUS_Functions;
355 CurrentConnectionType=GCT_FBUS;
356 connection2=GCT_FBUS;
357 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
368 GSM = &N6110_Functions;
369 GSM_Info = &N6110_Information;
370 GSM_LinkOK = &CurrentLinkOK;
372 fprintf(stdout,_("Trying DLR3 for new Nokia phones...\n"));
375 Protocol = &FBUS_Functions;
376 CurrentConnectionType=GCT_DLR3;
377 connection2=GCT_DLR3;
378 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
390 GSM = &N6110_Functions;
391 GSM_Info = &N6110_Information;
392 GSM_LinkOK = &CurrentLinkOK;
394 fprintf(stdout,_("Trying MBUS for new Nokia phones...\n"));
397 Protocol = &MBUS_Functions;
398 CurrentConnectionType=GCT_MBUS;
399 connection2=GCT_MBUS;
400 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
408 if (!found_match) return GE_NOTSUPPORTED;
413 if (!strcmp(model,"modelauto")) {
415 GSM = &N6110_Functions;
416 GSM_Info = &N6110_Information;
417 GSM_LinkOK = &CurrentLinkOK;
419 fprintf(stdout,_("Trying to find connected model...\n"));
421 switch (connection) {
422 case GCT_FBUS : Protocol = &FBUS_Functions; break;
423 case GCT_Infrared: Protocol = &FBUS_Functions; break;
424 case GCT_Tekram : Protocol = &FBUS_Functions; break;
425 case GCT_DLR3 : Protocol = &FBUS_Functions; break;
426 case GCT_MBUS : Protocol = &MBUS_Functions; break;
427 case GCT_Irda : Protocol = &FBUSIRDA_Functions;break;
428 case GCT_AT : Protocol = &AT_Functions; break;
429 case GCT_Default : Protocol = NULL; break;
431 CurrentConnectionType=connection;
432 connection2=connection;
433 if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
440 if (!found_match) return GE_NOTSUPPORTED;
446 if (CheckModel (Nsniff_Information, model, connection)) {
447 /* Set pointers to relevant addresses */
448 GSM = &Nsniff_Functions;
449 GSM_Info = &Nsniff_Information;
450 GSM_LinkOK = &CurrentLinkOK;
455 if (CheckModel (N6110_Information, model, connection)) {
456 /* Set pointers to relevant addresses */
457 GSM = &N6110_Functions;
458 GSM_Info = &N6110_Information;
459 GSM_LinkOK = &CurrentLinkOK;
462 if (CheckModel (N7110_Information, model, connection)) {
463 /* Set pointers to relevant addresses */
464 GSM = &N7110_Functions;
465 GSM_Info = &N7110_Information;
466 GSM_LinkOK = &CurrentLinkOK;
469 if (CheckModel (Nat_Information, model, connection)) {
470 /* Set pointers to relevant addresses */
471 GSM = &Nat_Functions;
472 GSM_Info = &Nat_Information;
473 GSM_LinkOK = &CurrentLinkOK;
478 switch (connection) {
479 case GCT_FBUS : Protocol = &FBUS_Functions; break;
480 case GCT_Infrared: Protocol = &FBUS_Functions; break;
481 case GCT_Tekram : Protocol = &FBUS_Functions; break;
482 case GCT_DLR3 : Protocol = &FBUS_Functions; break;
483 case GCT_MBUS : Protocol = &MBUS_Functions; break;
484 case GCT_Irda : Protocol = &FBUSIRDA_Functions;break;
485 case GCT_AT : Protocol = &AT_Functions; break;
486 case GCT_Default : Protocol = NULL; break;
489 return GE_NOTSUPPORTED;
494 /* Now call model specific initialisation code. */
495 error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
497 /* RTH: FIXME: second try for Irda (6210 only?)*/
498 if ( error!=GE_NONE && connection == GCT_Irda)
501 fprintf(stdout,"Irda connection: second try!\n");
504 error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
507 if (error==GE_NONE && !strcmp(SynchronizeTime,"yes"))
510 now=localtime(&nowh);
512 Date.Year = now->tm_year;
513 Date.Month = now->tm_mon+1;
514 Date.Day = now->tm_mday;
515 Date.Hour = now->tm_hour;
516 Date.Minute = now->tm_min;
517 Date.Second = now->tm_sec;
522 /* Well, this thing is copyrighted in U.S. This technique is known as
523 Windowing and you can read something about it in LinuxWeekly News:
524 http://lwn.net/1999/features/Windowing.phtml. This thing is beeing
525 written in Czech republic and Poland where algorithms are not allowed
529 Date.Year = Date.Year+1900;
531 Date.Year = Date.Year+2000;
534 /* FIXME: Error checking should be here. */
535 GSM->SetDateTime(&Date);
541 GSM_Error Unimplemented(void)
543 return GE_NOTIMPLEMENTED;
546 GSM_Error NotSupported(void)
548 return GE_NOTSUPPORTED;
551 /* Applications should call N6110_Terminate to shut down the N6110 thread and
552 close the serial port. */
553 void NULL_Terminate(void)
555 Protocol->Terminate();
559 /* Here are things made for keeping connecting */
560 void NULL_KeepAlive()
564 /* Here are things made for keeping connecting */
565 void NULL_KeepAlive()
571 void NULL_TX_DisplayMessage(u16 MessageLength, u8 *MessageBuffer)
573 fprintf(stdout, _("PC: "));
575 txhexdump(MessageLength,MessageBuffer);
579 bool NULL_WritePhone (u16 length, u8 *buffer) {
580 if (device_write(buffer,length)!=length) return false;
584 GSM_Error NULL_WaitUntil (int time, GSM_Error *value)
590 /* Wait for timeout or other error. */
591 while (timeout != 0 && *value == GE_BUSY ) {
602 GSM_Error NULL_SendMessageSequence (int time, GSM_Error *value,
603 u16 message_length, u8 message_type, u8 *buffer)
607 Protocol->SendMessage(message_length, message_type, buffer);
609 return NULL_WaitUntil (time, value);
612 GSM_ConnectionType GetConnectionTypeFromString(char *Connection) {
614 GSM_ConnectionType connection=GCT_FBUS;
616 if (!strcmp(Connection, "irda")) connection=GCT_Irda;
617 if (!strcmp(Connection, "infrared")) connection=GCT_Infrared;
618 if (!strcmp(Connection, "mbus")) connection=GCT_MBUS;
619 if (!strcmp(Connection, "dlr3")) connection=GCT_DLR3;
620 if (!strcmp(Connection, "at")) connection=GCT_AT;
621 if (!strcmp(Connection, "tekram210"))connection=GCT_Tekram;
626 bool GetMemoryTypeString(char *memorytext, GSM_MemoryType *type)
635 GSM_MTStrings mystring[] = {
649 while (strcmp(mystring[i].name,"undefined")) {
650 if (*type==mystring[i].type) {
651 strcpy(memorytext,mystring[i].name);
659 bool GetMemoryTypeID(char *memorytext, GSM_MemoryType *type)
668 GSM_MTStrings mystring[] = {
682 while (strcmp(mystring[i].name,"undefined")) {
683 if (strcmp(mystring[i].name,memorytext)==0) {
684 *type=mystring[i].type;
693 char *GetMygnokiiVersion() {
695 static char Buffer[1000]="";
697 sprintf(Buffer, "%s",VERSION);
703 1.Name,2.CodeName,3.Calendar,4.Netmonitor,5.Caller groups,6.Phonebook,
704 7.Authentication 8.Datacalls 9.KeysPressing 10.SMSC Default Recipient
705 11.SpeedDials 12.ScreenSavers 13.DTMF 14.SMS 15.NoPowerFrame 16.StartUpLogo
706 17.Profiles 18.Ringtones 19.WAP 20.RIngtonesNumber
709 static OnePhoneModel allmodels[] = {
711 /*1, 2, 3, 4, 5, 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 */
712 {"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}},
713 {"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}},
714 {"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}},
715 {"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}},
716 {"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}},
717 {"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}},
718 {"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}},
719 {"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}},
720 {"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}},
721 {"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}},
722 {"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}},
723 {"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}},
724 {"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}},
725 {"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}},
726 {"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}},
727 {"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}},
728 {"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 !
729 {"" ,"" ,{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
732 OnePhoneModel *GetPhoneModelData (const char *num)
736 while (allmodels[i].number != "") {
737 if (strcmp (num, allmodels[i].number) == 0) {
738 return (&allmodels[i]);
743 return (&allmodels[i]);
746 char *GetModelName ()
748 static char model[64];
750 while (GSM->GetModel(model) != GE_NONE) sleep(1);
752 return (GetPhoneModelData(model)->model);
755 int GetModelFeature (featnum_index num)
757 static char model[64];
759 while (GSM->GetModel(model) != GE_NONE) sleep(1);
761 return (GetPhoneModelData(model)->features[num]);
764 int LogAvailable=-1; //-1 not checked earlier, 0 not, 1 yes
767 bool AppendLog(u8 *buffer, int length,bool format)
773 struct CFG_Header *cfg_info;
776 if (LogAvailable==-1) {
780 cfg_info=CFG_FindGnokiirc();
781 if (cfg_info==NULL) return false;
783 LogFile = CFG_Get(cfg_info, "global", "logfile");
788 file=fopen(logfilename, "a+");
790 /* We have first entry in this session and too large file */
791 if (fread( buffer2, 1, 50000,file )==50000) {
793 file=fopen(logfilename, "w");
797 if (LogAvailable==1) {
798 file=fopen(logfilename, "a");
802 if (LogAvailable==1) {
803 for (i=0;i<length;i++) {
805 fprintf(file, "%02x",buffer[i]);
807 case 0x09:fprintf(file,_(" |"));break;
809 if (isprint(buffer[i])) fprintf(file, _("%c|"),buffer[i]);
810 else fprintf(file, _(" |"));
814 fprintf(file, "%c",buffer[i]);
817 if (format) fprintf(file, "\n");
821 return (LogAvailable==1);
824 bool AppendLogText(u8 *buffer,bool format)
826 return AppendLog(buffer,strlen(buffer),format);