Not yet working stack checking (symbol STACKCHECK)
[gnokii.git] / common / gsm-api.c
1 /*
2
3   G N O K I I
4
5   A Linux/Unix toolset and driver for Nokia mobile phones.
6
7   Released under the terms of the GNU GPL, see file COPYING for more details.
8         
9   Provides a generic API for accessing functions on the phone, wherever
10   possible hiding the model specific details.
11
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
14   functions.
15
16   Unless otherwise noted, all functions herein block until they complete.  The
17   functions themselves are defined in a structure in gsm-common.h.
18
19 */
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <time.h>
27
28 #ifdef WIN32
29   #include <windows.h>
30   #include "misc_win32.h"
31 #endif
32
33 #include "gsm-api.h"
34
35 #ifndef UCLINUX
36 #include "newmodules/n6110.h"
37 #include "newmodules/n7110.h"
38 #include "newmodules/newat.h"
39 #ifdef DEBUG
40   #include "newmodules/sniff/sniff.h"
41 #endif
42 #include "protocol/fbusirda.h"
43 #endif /* UCLINUX */
44 #include "protocol/fbus.h"
45 #ifndef UCLINUX
46 #include "protocol/mbus.h"
47 #include "protocol/at.h"
48 #endif /* UCLINUX */
49 #include "files/cfgreader.h"
50
51 #ifndef WIN32
52   #include "devices/device.h"
53 #endif
54
55 #ifdef VC6
56   /* for VC6 make scripts save VERSION constant in mversion.h file */
57   #include "mversion.h"
58 #endif
59
60 /* GSM_LinkOK is set to true once normal communications with the phone have
61    been established. */
62
63 bool *GSM_LinkOK;
64
65 /* Define pointer to the GSM_Functions structure used by external code to call
66    relevant API functions. This structure is defined in gsm-common.h. */
67
68 GSM_Functions *GSM;
69
70 /* Define pointer to the GSM_Information structure used by external code to
71    obtain information that varies from model to model. This structure is also
72    defined in gsm-common.h */
73
74 GSM_Information         *GSM_Info;
75
76 /* Initialise interface to the phone. Model number should be a string such as
77    3810, 5110, 6110 etc. Device is the serial port to use e.g. /dev/ttyS0, the
78    user must have write permission to the device. */
79
80 GSM_Protocol *Protocol;
81
82 /* Local variables used by get/set phonebook entry code. Buffer is used as a
83    source or destination for phonebook data and other functions... Error is
84    set to GE_NONE by calling function, set to GE_COMPLETE or an error code by
85    handler routines as appropriate. */
86                                    
87 GSM_PhonebookEntry *CurrentPhonebookEntry;
88 GSM_Error          CurrentPhonebookError;
89
90 GSM_SpeedDial      *CurrentSpeedDialEntry;
91 GSM_Error          CurrentSpeedDialError;
92
93 unsigned char      Current_IMEI[GSM_MAX_IMEI_LENGTH];
94 unsigned char      Current_Revision[GSM_MAX_REVISION_LENGTH];
95 unsigned char      Current_Model[GSM_MAX_MODEL_LENGTH];
96
97 #ifndef UCLINUX
98 GSM_SMSMessage     *CurrentSMSMessage;
99 GSM_Error          CurrentSMSMessageError;
100 int                CurrentSMSPointer;
101
102 GSM_SMSFolders      *CurrentSMSFolders;
103 GSM_Error          CurrentSMSFoldersError;
104 int                CurrentSMSFoldersCount;
105
106 GSM_OneSMSFolder   CurrentSMSFolder;
107 GSM_Error          CurrentSMSFolderError;
108 int                CurrentSMSFolderID;
109 #endif /* UCLINUX */
110
111 GSM_MemoryStatus   *CurrentMemoryStatus;
112 GSM_Error          CurrentMemoryStatusError;
113
114 #ifndef UCLINUX
115 GSM_NetworkInfo    *CurrentNetworkInfo;
116 GSM_Error          CurrentNetworkInfoError;
117
118 GSM_SMSStatus      *CurrentSMSStatus;
119 GSM_Error          CurrentSMSStatusError;
120
121 GSM_MessageCenter  *CurrentMessageCenter;
122 GSM_Error          CurrentMessageCenterError;
123
124 int                *CurrentSecurityCodeStatus;
125 GSM_Error          CurrentSecurityCodeError;
126 GSM_SecurityCode   *CurrentSecurityCode;
127
128 GSM_DateTime       *CurrentDateTime;
129 GSM_Error          CurrentDateTimeError;
130
131 GSM_Error          CurrentResetPhoneSettingsError;
132
133 GSM_DateTime       *CurrentAlarm;
134 GSM_Error          CurrentAlarmError;
135
136 GSM_CalendarNote   *CurrentCalendarNote;
137 GSM_Error          CurrentCalendarNoteError;
138
139 GSM_NotesInfo      CurrentCalendarNotesInfo,*CurrentCalendarNotesInfo2;
140 GSM_Error          CurrentCalendarNotesInfoError;
141
142 GSM_Error          CurrentSetDateTimeError;
143 GSM_Error          CurrentSetAlarmError;
144
145 int                *CurrentFirstCalendarFreePos;
146 GSM_Error          CurrentFirstCalendarFreePosError;
147 #endif /* UCLINUX */
148
149 GSM_Error          CurrentEnableExtendedCommandsError;
150
151 int                CurrentRFLevel,
152                    CurrentBatteryLevel,
153                    CurrentPowerSource;
154
155 #ifndef UCLINUX
156 int                CurrentDisplayStatus;
157 GSM_Error          CurrentDisplayStatusError;
158
159 char               *CurrentNetmonitor;
160 GSM_Error          CurrentNetmonitorError;
161
162 GSM_Bitmap         *CurrentGetBitmap=NULL;
163 GSM_Error          CurrentGetBitmapError;
164
165 GSM_Error          CurrentSetBitmapError;
166
167 GSM_Error          CurrentSendDTMFError;
168
169 GSM_Profile        *CurrentProfile;
170 GSM_Error          CurrentProfileError;
171
172 GSM_Error          CurrentDisplayOutputError;
173
174 GSM_CBMessage      *CurrentCBMessage;
175 GSM_Error          CurrentCBError;
176
177 int                CurrentPressKeyEvent;
178 GSM_Error          CurrentPressKeyError;
179
180 GSM_Error          CurrentPlayToneError=GE_UNKNOWN;
181 #endif /* UCLINUX */
182
183 GSM_Error          CurrentDialVoiceError;
184
185 #ifndef UCLINUX
186 GSM_Error          CurrentGetOperatorNameError;
187 GSM_Network        *CurrentGetOperatorNameNetwork;
188 GSM_Error          CurrentSetOperatorNameError;
189 #endif /* UCLINUX */
190
191 GSM_Error          CurrentGetIMEIError;
192
193 GSM_Error          CurrentGetHWError;
194
195 #ifndef UCLINUX
196 unsigned char      CurrentPPS[4];
197 GSM_Error          CurrentProductProfileSettingsError;
198
199 char               CurrentIncomingCall[20];
200
201 GSM_Error          CurrentBinRingtoneError;
202 GSM_BinRingtone    *CurrentGetBinRingtone=NULL;
203
204 GSM_Error          CurrentRingtoneError;
205 #endif /* UCLINUX */
206
207 GSM_Error          CurrentMagicError;
208
209 #ifndef UCLINUX
210 GSM_Error          CurrentSimlockInfoError;
211 GSM_AllSimlocks    *CurrentSimLock;
212
213 GSM_Error          CurrentGetWAPBookmarkError;
214 GSM_Error          CurrentSetWAPBookmarkError;
215 GSM_WAPBookmark    *WAPBookmark;
216
217 GSM_Error          CurrentGetWAPSettingsError;
218 GSM_WAPSettings    *WAPSettings;
219
220 GSM_Error          CurrentCallDivertError;
221 GSM_CallDivert    *CurrentCallDivert;
222
223 char              *CurrentManufacturer;
224 #endif /* UCLINUX */
225
226 /* This is the connection type used in gnokii. */
227 GSM_ConnectionType CurrentConnectionType;
228
229 /* Pointer to a callback function used to return changes to a calls status */
230 /* This saves unreliable polling */
231 void (*CurrentCallPassup)(char c);
232
233 /* Pointer to callback function in user code to be called when RLP frames
234    are received. */
235 void (*CurrentRLP_RXCallback)(RLP_F96Frame *frame);
236
237 /* Used to disconnect the call */
238 u8 CurrentCallSequenceNumber;
239
240 bool CurrentLinkOK;
241
242 bool CurrentRequestTerminate;
243
244 #ifndef UCLINUX
245 bool CurrentDisableKeepAlive;
246 #endif /* UCLINUX */
247
248 #ifdef UCLINUX
249 static
250 #endif /* UCLINUX */
251 bool CheckModel (GSM_Information InfoToCheck, char *model, GSM_ConnectionType connection) {
252
253   bool found_match=false;
254
255   if (strstr(InfoToCheck.FBUSModels, model) != NULL) {
256     if (connection==GCT_FBUS) found_match=true;
257   }
258 #ifndef UCLINUX
259   if (strstr(InfoToCheck.MBUSModels, model) != NULL) {
260     if (connection==GCT_MBUS) found_match=true;
261   }
262   if (strstr(InfoToCheck.InfraredModels, model) != NULL) {
263     if (connection==GCT_Infrared) found_match=true;
264   }
265   if (strstr(InfoToCheck.DLR3Models, model) != NULL) {
266     if (connection==GCT_DLR3) found_match=true;
267   }
268   if (strstr(InfoToCheck.IrdaModels, model) != NULL) {
269     if (connection==GCT_Irda) found_match=true;
270   }
271   if (strstr(InfoToCheck.ATModels, model) != NULL) {
272     if (connection==GCT_AT) found_match=true;
273   }
274   if (strstr(InfoToCheck.TekramModels, model) != NULL) {
275     if (connection==GCT_Tekram) found_match=true;
276   }
277 #endif /* UCLINUX */
278
279   return found_match;
280 }
281  
282 #ifndef UCLINUX
283
284 GSM_Error TryNewNokia(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame)) {
285   int InitLength;
286   int count;
287   unsigned char init_char = N6110_SYNC_BYTE;
288
289   /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
290   char phonemodel[64];
291
292   if (Protocol->Initialise(device,initlength,connection,rlp_callback)!=GE_NONE)
293   {
294     return GE_NOTSUPPORTED; 
295   }
296
297   if (connection!=GCT_MBUS) {
298     InitLength = atoi(initlength);
299
300     if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
301       InitLength = 250; /* This is the usual value, lower may work. */
302     }
303
304 #ifdef DEBUG
305     fprintf(stdout,_("Writing init chars...."));
306 #endif
307
308     /* Initialise link with phone or what have you */
309     /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
310        empirical. */
311     for (count = 0; count < InitLength; count ++) {
312       usleep(100);
313       Protocol->WritePhone(1,&init_char);
314     }
315
316 #ifdef DEBUG
317     fprintf(stdout,_("Done\n"));  
318 #endif
319
320     N6110_SendStatusRequest();
321   }
322
323   usleep(100);
324
325   if (N6110_SendIDFrame()!=GE_NONE)
326     return GE_TIMEOUT;
327  
328   while (N6110_GetModel(phonemodel) != GE_NONE)
329     sleep(1);
330
331 #ifndef UCLINUX
332   if (!strcmp(phonemodel,"NPE-3") || !strcmp(phonemodel,"NSE-5"))
333   {
334     GSM->Terminate();      
335     
336     /* Set pointers to relevant addresses */
337     GSM = &N7110_Functions;
338     GSM_Info = &N7110_Information;
339     GSM_LinkOK = &CurrentLinkOK;
340     return GE_NONE;
341   }
342 #endif /* UCLINUX */
343
344   return GE_NONE;
345 }
346 #endif /* UCLINUX */
347
348 extern GSM_Information N6110_Information;
349 extern GSM_Functions   N6110_Functions;
350
351 GSM_Error GSM_Initialise(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame), char* SynchronizeTime)
352 {
353   bool found_match=false;
354   
355   GSM_ConnectionType connection2;
356
357 #ifndef UCLINUX
358   struct tm *now;
359   time_t nowh;
360   GSM_DateTime Date;
361 #endif /* UCLINUX */
362   GSM_Error error;
363   
364   connection2=connection;
365
366   CurrentRLP_RXCallback = rlp_callback;
367   CurrentCallPassup=NULL;
368   CurrentPhonebookEntry=NULL;
369 #ifndef UCLINUX
370   CurrentNetworkInfo = NULL;
371   CurrentGetBitmap=NULL;
372   CurrentPlayToneError=GE_UNKNOWN;
373   strcpy(CurrentIncomingCall," ");
374   CurrentGetBinRingtone=NULL;
375   CurrentNetworkInfo=NULL;
376 #endif /* UCLINUX */
377   CurrentRequestTerminate=false;
378 #ifndef UCLINUX
379   CurrentDisableKeepAlive=false;
380   CurrentCalendarNotesInfo.HowMany=2000;
381 #endif /* UCLINUX */
382   CurrentMagicError = GE_BUSY;  
383   
384 #ifndef UCLINUX
385   if (!strcmp(model,"auto")) {
386
387     /* For now */
388     GSM = &N6110_Functions;
389     GSM_Info = &N6110_Information;
390     GSM_LinkOK = &CurrentLinkOK;
391 #ifdef DEBUG
392     fprintf(stdout,_("Trying FBUS for new Nokia phones...\n"));
393 #endif
394     /* Trying FBUS */
395     Protocol = &FBUS_Functions;
396     CurrentConnectionType=GCT_FBUS;    
397     connection2=GCT_FBUS;
398     if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
399     {
400       found_match=true;
401     } else {
402       GSM->Terminate();      
403     }
404
405     if (!found_match) {
406       usleep(100);          
407       
408       /* For now */
409       GSM = &N6110_Functions;
410       GSM_Info = &N6110_Information;
411       GSM_LinkOK = &CurrentLinkOK;
412 #ifdef DEBUG
413       fprintf(stdout,_("Trying DLR3 for new Nokia phones...\n"));
414 #endif
415       /* Trying DLR3 */
416       Protocol = &FBUS_Functions;
417       CurrentConnectionType=GCT_DLR3;    
418       connection2=GCT_DLR3;
419       if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
420       {
421         found_match=true;
422       } else {
423         GSM->Terminate();      
424       }
425     }
426     
427     if (!found_match) {
428       usleep(100);          
429       
430       /* For now */
431       GSM = &N6110_Functions;
432       GSM_Info = &N6110_Information;
433       GSM_LinkOK = &CurrentLinkOK;
434 #ifdef DEBUG
435       fprintf(stdout,_("Trying MBUS for new Nokia phones...\n"));
436 #endif
437       /* Trying MBUS */
438       Protocol = &MBUS_Functions;
439       CurrentConnectionType=GCT_MBUS;    
440       connection2=GCT_MBUS;
441 #ifndef UCLINUX
442       if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
443       {
444         found_match=true;
445       } else
446 #endif /* UCLINUX */
447                                 {
448         GSM->Terminate();      
449       }
450     }
451
452     if (!found_match) return GE_NOTSUPPORTED;
453
454     usleep(50);
455         
456   } else
457 #endif /* UCLINUX */
458                 {
459 #ifndef UCLINUX
460 #ifdef DEBUG
461     if (CheckModel (Nsniff_Information, model, connection)) {
462       /* Set pointers to relevant addresses */
463       GSM = &Nsniff_Functions;
464       GSM_Info = &Nsniff_Information;
465       GSM_LinkOK = &CurrentLinkOK;
466       found_match=true;
467     }
468 #endif
469 #endif /* UCLINUX */
470
471     if (CheckModel (N6110_Information, model, connection)) {
472       /* Set pointers to relevant addresses */
473       GSM = &N6110_Functions;
474       GSM_Info = &N6110_Information;
475       GSM_LinkOK = &CurrentLinkOK;
476       found_match=true;
477     }
478 #ifndef UCLINUX
479     if (CheckModel (N7110_Information, model, connection)) {
480       /* Set pointers to relevant addresses */
481       GSM = &N7110_Functions;
482       GSM_Info = &N7110_Information;
483       GSM_LinkOK = &CurrentLinkOK;
484       found_match=true;
485     }
486     if (CheckModel (Nat_Information, model, connection)) {
487       /* Set pointers to relevant addresses */
488       GSM = &Nat_Functions;
489       GSM_Info = &Nat_Information;
490       GSM_LinkOK = &CurrentLinkOK;
491       found_match=true;
492     }
493 #endif /* UCLINUX */
494
495     if (found_match) {
496       switch (connection) {
497         case GCT_FBUS    : Protocol = &FBUS_Functions;    break;
498 #ifndef UCLINUX
499         case GCT_Infrared: Protocol = &FBUS_Functions;    break;
500         case GCT_Tekram  : Protocol = &FBUS_Functions;    break;
501         case GCT_DLR3    : Protocol = &FBUS_Functions;    break;
502         case GCT_MBUS    : Protocol = &MBUS_Functions;    break;
503         case GCT_Irda    : Protocol = &FBUSIRDA_Functions;break;
504         case GCT_AT      : Protocol = &AT_Functions;      break;
505         case GCT_Default : Protocol = NULL;               break;
506 #endif /* UCLINUX */
507       }
508     } else
509       return GE_NOTSUPPORTED;
510   }
511
512     
513   /* Now call model specific initialisation code. */
514   error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
515
516 #ifndef UCLINUX
517   /* RTH: FIXME: second try for Irda (6210 only?)*/
518   if ( error!=GE_NONE && connection == GCT_Irda)
519   {
520    #ifdef DEBUG
521      fprintf(stdout,"Irda connection: second try!\n");
522    #endif
523    device_close();
524    error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
525   }
526 #endif /* UCLINUX */
527
528 #ifndef UCLINUX
529   if (error==GE_NONE && !strcmp(SynchronizeTime,"yes"))
530   {
531     nowh=time(NULL);
532     now=localtime(&nowh);
533
534     Date.Year = now->tm_year;
535     Date.Month = now->tm_mon+1;
536     Date.Day = now->tm_mday;
537     Date.Hour = now->tm_hour;
538     Date.Minute = now->tm_min;
539     Date.Second = now->tm_sec;
540
541     if (Date.Year<1900)
542     {
543
544       /* Well, this thing is copyrighted in U.S. This technique is known as
545          Windowing and you can read something about it in LinuxWeekly News:
546          http://lwn.net/1999/features/Windowing.phtml. This thing is beeing
547          written in Czech republic and Poland where algorithms are not allowed
548          to be patented. */
549
550       if (Date.Year>90)
551         Date.Year = Date.Year+1900;
552       else
553         Date.Year = Date.Year+2000;
554     }
555
556     /* FIXME: Error checking should be here. */
557     GSM->SetDateTime(&Date);
558   }
559 #endif /* UCLINUX */
560
561   return error;
562 }
563
564 #ifndef UCLINUX
565
566 GSM_Error Unimplemented(void)
567 {
568         return GE_NOTIMPLEMENTED;
569 }
570
571 GSM_Error NotSupported(void)
572 {
573         return GE_NOTSUPPORTED;
574 }
575
576 #endif /* UCLINUX */
577
578 /* Applications should call N6110_Terminate to shut down the N6110 thread and
579    close the serial port. */
580 void NULL_Terminate(void)
581 {
582   Protocol->Terminate();
583 }
584
585 #ifdef WIN32
586 /* Here are things made for keeping connecting */
587 void NULL_KeepAlive()
588 {
589 }
590 #else
591 /* Here are things made for keeping connecting */
592 void NULL_KeepAlive()
593 {
594 }
595 #endif
596
597 #ifdef DEBUG
598 void NULL_TX_DisplayMessage(u16 MessageLength, u8 *MessageBuffer)
599 {
600   fprintf(stdout, _("PC: "));
601
602   txhexdump(MessageLength,MessageBuffer);
603 }
604 #endif
605
606 bool NULL_WritePhone (u16 length, u8 *buffer) {
607   if (device_write(buffer,length)!=length) return false;
608                                       else return true;
609 }
610
611 GSM_Error NULL_WaitUntil (int time, GSM_Error *value)
612 {
613   int timeout;
614
615   timeout=time;
616   
617   /* Wait for timeout or other error. */
618   while (timeout != 0 && *value == GE_BUSY ) {
619           
620     if (--timeout == 0)
621       return (GE_TIMEOUT);
622                     
623     usleep (100000);
624   }
625
626   return *value;
627 }
628
629 GSM_Error NULL_SendMessageSequence (int time, GSM_Error *value,
630                  u16 message_length, u8 message_type, u8 *buffer)
631 {
632   *value=GE_BUSY;
633   
634   Protocol->SendMessage(message_length, message_type, buffer);  
635
636   return NULL_WaitUntil (time, value);
637 }
638
639 GSM_ConnectionType GetConnectionTypeFromString(char *Connection) {
640
641   GSM_ConnectionType connection=GCT_FBUS;
642
643 #ifndef UCLINUX
644   if (!strcmp(Connection, "irda"))     connection=GCT_Irda;
645   if (!strcmp(Connection, "infrared")) connection=GCT_Infrared;
646   if (!strcmp(Connection, "mbus"))     connection=GCT_MBUS;
647   if (!strcmp(Connection, "dlr3"))     connection=GCT_DLR3;
648   if (!strcmp(Connection, "at"))       connection=GCT_AT;
649   if (!strcmp(Connection, "tekram210"))connection=GCT_Tekram;
650 #endif /* UCLINUX */
651   
652   return connection;
653 }
654
655 bool GetMemoryTypeString(char *memorytext, GSM_MemoryType *type)
656 {
657   int i=0;
658
659   typedef struct {
660     GSM_MemoryType type;
661     char *name;
662   } GSM_MTStrings;
663
664 static  GSM_MTStrings mystring[] = {
665     {GMT_ME,"ME"},
666     {GMT_SM,"SM"},
667     {GMT_FD,"FD"},
668     {GMT_ON,"ON"},
669     {GMT_EN,"EN"},
670     {GMT_DC,"DC"},
671     {GMT_RC,"RC"},  
672     {GMT_MC,"MC"},
673     {GMT_LD,"LD"},
674     {GMT_MT,"MT"},
675     {GMT_ME,"undefined"}
676   };
677
678   while (strcmp(mystring[i].name,"undefined")) {
679     if (*type==mystring[i].type) {
680       strcpy(memorytext,mystring[i].name);
681       return true;
682     }
683     i++;
684   }
685   return false;
686 }
687
688 bool GetMemoryTypeID(char *memorytext, GSM_MemoryType *type)
689 {
690   int i=0;
691
692   typedef struct {
693     GSM_MemoryType type;
694     char *name;
695   } GSM_MTStrings;
696
697 static  GSM_MTStrings mystring[] = {
698     {GMT_ME,"ME"},
699     {GMT_SM,"SM"},
700     {GMT_FD,"FD"},
701     {GMT_ON,"ON"},
702     {GMT_EN,"EN"},
703     {GMT_DC,"DC"},
704     {GMT_RC,"RC"},  
705     {GMT_MC,"MC"},
706     {GMT_LD,"LD"},
707     {GMT_MT,"MT"},
708     {GMT_ME,"undefined"}
709   };
710
711   while (strcmp(mystring[i].name,"undefined")) {
712     if (strcmp(mystring[i].name,memorytext)==0) {
713       *type=mystring[i].type;
714       return true;
715     }
716     i++;
717   }
718
719   return false;
720 }
721
722 char *GetMygnokiiVersion() {
723
724   static char Buffer[1000]="";
725
726   sprintf(Buffer, "%s",VERSION);
727
728   return Buffer;
729 }
730
731 /*
732 1.Name,2.CodeName,3.Calendar,4.Netmonitor,5.Caller groups,6.Phonebook,
733 7.Authentication 8.Datacalls 9.KeysPressing 10.SMSC Default Recipient
734 11.SpeedDials 12.ScreenSavers 13.DTMF 14.SMS 15.NoPowerFrame 16.StartUpLogo
735 17.Profiles 18.Ringtones 19.WAP
736 */
737
738 static OnePhoneModel allmodels[] = {
739
740 /*1,    2,       3,      4,       5,        6       7      8        9      10        11      12       13     14      15        16       17       18        19 */
741 {"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}},
742 {"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}},
743 {"3310","NHM-5",{F_CAL33,F_NETMON,        0,F_PBK33,     0,       0,     0,F_SMSCDEF,F_SPEED,F_SCRSAV,     0,F_SMS  ,F_NOPOWER,F_STANIM,F_PROF33,F_RING_SM,    0}},
744 {"3330","NHM-6",{F_CAL33,F_NETMON,        0,F_PBK33,     0,       0,F_KEYB,F_SMSCDEF,F_SPEED,F_SCRSAV,     0,F_SMS  ,        0,F_STANIM,F_PROF33,F_RING_SM,F_WAP}},
745 {"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}},
746 {"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}},
747 {"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}},
748 {"6110","NSE-3",{F_CAL61,F_NETMON,F_CALER61,      0,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,F_STA   ,F_PROF61,F_RINGBIN,    0}},
749 {"6130","NSK-3",{F_CAL61,F_NETMON,F_CALER61,      0,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,F_STA   ,F_PROF61,F_RINGBIN,    0}},
750 {"6150","NSM-1",{F_CAL61,F_NETMON,F_CALER61,      0,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,F_STA   ,F_PROF61,F_RINGBIN,    0}},
751 {"6190","NSB-3",{F_CAL61,F_NETMON,F_CALER61,      0,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,F_STA   ,F_PROF61,F_RINGBIN,    0}},
752 {"6210","NPE-3",{F_CAL71,F_NETMON,F_CALER61,F_PBK71,     0,F_DATA71,     0,F_SMSCDEF,F_SPEED,       0,     0,F_SMS71,        0,F_STA62 ,F_PROF61,F_RINGBIN,F_WAP}},
753 {"6250","NHM-3",{F_CAL71,F_NETMON,F_CALER61,F_PBK71,     0,F_DATA71,     0,F_SMSCDEF,F_SPEED,       0,     0,F_SMS71,        0,F_STA62 ,F_PROF61,F_RINGBIN,F_WAP}},     
754 {"7110","NSE-5",{F_CAL71,F_NETMON,F_CALER61,F_PBK71,     0,F_DATA71,     0,F_SMSCDEF,F_SPEED,       0,     0,F_SMS71,        0,F_STA71 ,F_PROF61,F_RINGBIN,F_WAP}},
755 {"8210","NSM-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}},
756 {"8850","NSM-2",{      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}},
757 {"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}},//quesses only !
758 {""    ,""     ,{      0,       0,        0,      0,     0,       0,     0,        0,      0,       0,     0,      0,        0,       0,       0,        0,    0}}
759 };
760
761 static OnePhoneModel *GetPhoneModelData (const char *num)
762 {
763         register int i = 0;
764
765         while (allmodels[i].number != "") {
766                 if (strcmp (num, allmodels[i].number) == 0) {
767                         return (&allmodels[i]);
768                 }
769                 i++;
770         }
771
772         return (&allmodels[i]);
773 }
774
775 char *GetModelName ()
776 {
777   static char model[64];
778
779   while (GSM->GetModel(model)  != GE_NONE) sleep(1);
780
781   return (GetPhoneModelData(model)->model);
782 }
783
784 int GetModelFeature (featnum_index num)
785 {
786   static char model[64];
787
788   while (GSM->GetModel(model)  != GE_NONE) sleep(1);
789
790   return (GetPhoneModelData(model)->features[num]);
791 }
792
793 #ifndef UCLINUX
794 int LogAvailable=-1; //-1 not checked earlier, 0 not, 1 yes
795 char *logfilename;
796
797 bool AppendLog(u8 *buffer, int length,bool format)
798 {
799   FILE *file=NULL;
800   char buffer2[50001];
801   int i;
802
803   struct CFG_Header *cfg_info;
804   char *LogFile;        
805
806   if (LogAvailable==-1) {
807
808     LogAvailable=0;
809
810     cfg_info=CFG_FindGnokiirc();
811     if (cfg_info==NULL) return false;
812
813     LogFile = CFG_Get(cfg_info, "global", "logfile");
814     if (LogFile) {
815       LogAvailable=1;
816       logfilename=LogFile;
817
818       file=fopen(logfilename, "a+");
819
820       /* We have first entry in this session and too large file */
821       if (fread( buffer2, 1, 50000,file )==50000) {
822         fclose(file);
823         file=fopen(logfilename, "w");
824       }
825     }
826   } else {
827     if (LogAvailable==1) {
828       file=fopen(logfilename, "a");
829     }
830   }
831   
832   if (LogAvailable==1) {
833     for (i=0;i<length;i++) {
834       if (format) {
835         fprintf(file, "%02x",buffer[i]);
836         switch (buffer[i]) {
837           case 0x09:fprintf(file,_(" |"));break;
838           default:
839             if (isprint(buffer[i])) fprintf(file, _("%c|"),buffer[i]);
840                                else fprintf(file, _(" |"));
841             break;
842         } 
843       } else {
844         fprintf(file, "%c",buffer[i]);
845       }
846     }
847     if (format) fprintf(file, "\n");
848     fclose(file);
849   }
850
851   return (LogAvailable==1);
852 }
853
854 bool AppendLogText(u8 *buffer,bool format)
855 {
856   return AppendLog(buffer,strlen(buffer),format);
857 }
858 #endif /* UCLINUX */