This commit was manufactured by cvs2svn to create tag
[gnokii.git] / gnokii / gnokii.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   Mainline code for gnokii utility.  Handles command line parsing and
10   reading/writing phonebook entries and other stuff.
11
12 */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <signal.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include <time.h>
20 #include <sys/stat.h>
21
22 #ifndef VC6
23   #if defined(__svr4__) || defined(__FreeBSD__)
24   #  include <strings.h>        /* for bzero */
25   #endif
26 #else
27   /* for VC6 make scripts save VERSION constant in mversion.h file */
28   #include "mversion.h"
29 #endif
30
31 #ifdef WIN32
32
33   #include <windows.h>
34
35   #include "misc_win32.h"
36   #include "getopt.h"
37
38   #define DEV_CONSOLE "CON:"
39
40 #else
41
42   #include <unistd.h>
43   #include <termios.h>
44   #include <fcntl.h>
45   #include <sys/types.h>
46   #include <sys/time.h>
47   #include <getopt.h>
48
49   #define DEV_CONSOLE "/dev/tty"
50 #endif
51
52 #include "misc.h"
53 #include "gsm-common.h"
54 #include "gsm-api.h"
55 #include "gsm-networks.h"
56 #include "gsm-ringtones.h"
57 #include "gsm-bitmaps.h"
58 #include "gsm-wap.h"
59 #include "gsm-sms.h"
60 #include "gsm-datetime.h"
61 #include "gsm-phonebook.h"
62 #include "gsm-calendar.h"
63 #include "gsm-coding.h"
64 #include "newmodules/n6110.h"
65 #include "files/cfgreader.h"
66 #include "files/gsm-filetypes.h"
67 #include "gnokii.h"
68
69 #ifdef USE_NLS
70   #include <locale.h>
71 #endif
72
73 char *model;           /* Model from .gnokiirc file. */
74 char *Port;            /* Port from .gnokiirc file */
75 char *Initlength;      /* Init length from .gnokiirc file */
76 char *Connection;      /* Connection type from .gnokiirc file */
77 char *SynchronizeTime; /* If we set date and time from computer to phone (from .gnokiirc file) */
78 char *BinDir;          /* Binaries directory from .gnokiirc file - not used here yet */
79
80 GSM_SMSMessage SMS[4];
81   
82 char *GetProfileCallAlertString(int code) {
83
84   switch (code) {
85     case PROFILE_CALLALERT_RINGING     : return "Ringing";
86     case PROFILE_CALLALERT_ASCENDING   : return "Ascending";
87     case PROFILE_CALLALERT_RINGONCE    : return "Ring once";
88     case PROFILE_CALLALERT_BEEPONCE    : return "Beep once";
89     case PROFILE_CALLALERT_CALLERGROUPS: return "Caller groups";
90     case PROFILE_CALLALERT_OFF         : return "Off";
91     default                            : return "Unknown";
92   }
93 }
94
95 char *GetProfileVolumeString(int code) {
96
97   switch (code) {
98     case PROFILE_VOLUME_LEVEL1 : return "Level 1";
99     case PROFILE_VOLUME_LEVEL2 : return "Level 2";
100     case PROFILE_VOLUME_LEVEL3 : return "Level 3";
101     case PROFILE_VOLUME_LEVEL4 : return "Level 4";
102     case PROFILE_VOLUME_LEVEL5 : return "Level 5";
103     default                    : return "Unknown";
104   }
105 }
106
107 char *GetProfileKeypadToneString(int code) {
108
109   switch (code) {
110     case PROFILE_KEYPAD_OFF    : return "Off";
111     case PROFILE_KEYPAD_LEVEL1 : return "Level 1";
112     case PROFILE_KEYPAD_LEVEL2 : return "Level 2";
113     case PROFILE_KEYPAD_LEVEL3 : return "Level 3";
114     default                    : return "Unknown";
115   }
116 }
117
118 char *GetProfileMessageToneString(int code) {
119
120   switch (code) {
121     case PROFILE_MESSAGE_NOTONE    : return "No tone";
122     case PROFILE_MESSAGE_STANDARD  : return "Standard";
123     case PROFILE_MESSAGE_SPECIAL   : return "Special";
124     case PROFILE_MESSAGE_BEEPONCE  : return "Beep once";
125     case PROFILE_MESSAGE_ASCENDING : return "Ascending";
126     default                        : return "Unknown";
127   }
128 }
129
130 char *GetProfileWarningToneString(int code) {
131
132   switch (code) {
133     case PROFILE_WARNING_OFF : return "Off";
134     case PROFILE_WARNING_ON  : return "On";
135     default                  : return "Unknown";
136   }
137 }
138
139 char *GetProfileOnOffString(int code) {
140
141   switch (code) {
142     case 0x00 : return "Off";
143     case 0x01 : return "On";
144     default   : return "Unknown";
145   }
146 }
147
148 static char *GetProfileVibrationString(int code)
149 {
150         switch (code) {
151         case PROFILE_VIBRATION_OFF:     return "Off";
152         case PROFILE_VIBRATION_ON:      return "On";
153         case PROFILE_VIBRATION_FIRST:   return "Vibrate first";
154         default:                        return "Unknown";
155         }
156 }
157
158 char BufferProfileGroups[90];
159
160 char *GetProfileCallerGroups(int code) 
161 {
162   static char az_group_name[5][MAX_BITMAP_TEXT_LENGTH];
163   static bool enteronce=false;
164   register int i;
165   GSM_Bitmap bitmap;
166
167   if( code == PROFILE_CALLERGROUPS_ALL )
168        return _("All calls alert");
169
170   if( !enteronce ) {
171     for(i=0;i<5;i++) az_group_name[i][0]='\0';
172     enteronce=true;
173   }
174
175   BufferProfileGroups[0]=0;
176     
177   for(i=0;i<5;i++)
178   {
179     int code2test;
180     char z_gtype[12];
181
182     code2test=(i==0) ? 1 : 2<<(i-1);
183
184     if( code & code2test )
185     {
186       if (!strcmp(az_group_name[i],"")) 
187       {
188         if (GetModelFeature (FN_CALLERGROUPS)!=0) {
189           bitmap.type=GSM_CallerLogo;
190           bitmap.number=i;
191           strcpy(z_gtype,_("unknown"));
192           if (GSM->GetBitmap(&bitmap)==GE_NONE)
193             strcpy( az_group_name[i], bitmap.text );
194         }
195         if ((!strcmp(az_group_name[i],""))) {
196             switch(i) {
197             case 0:strcpy(az_group_name[i],_("Family"));break;
198             case 1:strcpy(az_group_name[i],_("VIP"));break;
199             case 2:strcpy(az_group_name[i],_("Friends"));break;
200             case 3:strcpy(az_group_name[i],_("Colleagues"));break;
201             case 4:strcpy(az_group_name[i],_("Other"));break;
202             default:break;
203           }
204         }
205       }
206       strcpy(z_gtype,az_group_name[i]);
207
208       if( strlen(BufferProfileGroups) ) strcat(BufferProfileGroups,"+");
209       strcat(BufferProfileGroups, z_gtype);
210     }
211     
212   }
213
214   return BufferProfileGroups;
215 }
216
217 char *print_error(GSM_Error e)
218 {
219
220 //      case GE_DEVICEOPENFAILED:         return "Couldn't open specified serial device.";
221 //      case GE_UNKNOWNMODEL:             return "Model specified isn't known/supported.";
222 //      case GE_NOLINK:                   return "Couldn't establish link with phone.";
223 //      case GE_TRYAGAIN:                 return "Try again.";
224 //      case GE_INVALIDSMSLOCATION:       return "Invalid SMS location.";
225 //      case GE_INVALIDPHBOOKLOCATION:    return "Invalid phonebook location.";
226 //      case GE_INVALIDMEMORYTYPE:        return "Invalid type of memory.";
227 //      case GE_INVALIDSPEEDDIALLOCATION: return "Invalid speed dial location.";
228 //      case GE_INVALIDCALNOTELOCATION:   return "Invalid calendar note location.";
229 //      case GE_INVALIDDATETIME:          return "Invalid date, time or alarm specification.";
230 //      case GE_EMPTYSMSLOCATION:         return "SMS location is empty.";
231 //      case GE_PHBOOKNAMETOOLONG:        return "Phonebook name is too long.";
232 //      case GE_PHBOOKNUMBERTOOLONG:      return "Phonebook number is too long.";
233 //      case GE_PHBOOKWRITEFAILED:        return "Phonebook write failed.";
234 //      case GE_SMSSENDOK:                return "SMS was send correctly.";
235 //      case GE_SMSSENDFAILED:            return "SMS send fail.";
236 //      case GE_SMSTOOLONG:               return "SMS message too long.";
237 //      case GE_NONEWCBRECEIVED:          return "Attempt to read CB when no new CB received";
238 //      case GE_INTERNALERROR:            return "Problem occured internal to model specific code.";
239 //      case GE_NOTSUPPORTED:             return "Function not supported by the phone";
240 //      case GE_BUSY:                     return "Command is still being executed.";
241 //      case GE_USERCANCELED:             return "User has cancelled the action.";   
242 //      case GE_UNKNOWN:                  return "Unknown error - well better than nothing!!";
243 //      case GE_MEMORYFULL:               return "Memory is full";
244 //      case GE_LINEBUSY:                 return "Outgoing call requested reported line busy";
245 //      case GE_NOCARRIER:                return "No Carrier error during data call setup ?";
246
247         switch (e) {
248         case GE_NONE:                     return "No error, done OK";
249         case GE_INVALIDSECURITYCODE:      return "Invalid Security code.";
250         case GE_NOTIMPLEMENTED:           return "Called command is not implemented for the used model. Please contact marcin-wiacek@topnet.pl, if you want to help in implementing it";
251         case GE_TIMEOUT:                  return "Command timed out.";
252         case GE_CANTOPENFILE:             return "Can't open file with bitmap/ringtone";
253         case GE_SUBFORMATNOTSUPPORTED:    return "Subformat of file not supported";
254         case GE_WRONGNUMBEROFCOLORS:      return "Wrong number of colors in specified bitmap file (only 2 colors files supported)";
255         case GE_WRONGCOLORS:              return "Wrong colors in bitmap file";
256         case GE_INVALIDIMAGESIZE:         return "Invalid size of bitmap (in file, sms etc.)";
257         case GE_INVALIDFILEFORMAT:        return "Invalid format of file";
258         case GE_TOOSHORT:                 return "File too short";
259         case GE_INSIDEBOOKMARKSMENU:      return "Inside WAP Bookmarks menu. Please leave it and try again";
260         case GE_INVALIDBOOKMARKLOCATION:  return "Invalid or empty WAP bookmark location";
261         case GE_INSIDESETTINGSMENU:       return "Inside WAP Settings menu. Please leave it and try again";
262         case GE_INVALIDSETTINGSLOCATION:  return "Invalid or empty WAP settings location";
263         default:                          return "Unknown error.";
264         }
265 }
266
267
268 GSM_Error GSM_ReadRingtoneFileOnConsole(char *FileName, GSM_Ringtone *ringtone)
269 {
270   GSM_Error error;
271   
272   error=GSM_ReadRingtoneFile(FileName, ringtone);
273   
274   switch (error) {
275     case GE_CANTOPENFILE:
276     case GE_SUBFORMATNOTSUPPORTED:
277       fprintf(stderr, _("File \"%s\"\nError: %s\n"),FileName,print_error(error));
278       break;
279     default:
280       break;
281   }
282   
283   return error;
284 }
285
286 GSM_Error GSM_SaveRingtoneFileOnConsole(char *FileName, GSM_Ringtone *ringtone)
287 {
288   int confirm,confirm2;
289   char ans[4];
290   struct stat buf;
291   GSM_Error error;
292
293   /* Ask before overwriting */
294   while (stat(FileName, &buf) == 0) {
295   
296     confirm=-1;
297     confirm2=-1;
298     
299     while (confirm < 0) {
300       fprintf(stderr, _("Saving ringtone. File \"%s\" exists. (O)verwrite, create (n)ew or (s)kip ? "),FileName);
301       GetLine(stdin, ans, 4);
302       if (!strcmp(ans, "O") || !strcmp(ans, "o")) confirm = 1;
303       if (!strcmp(ans, "N") || !strcmp(ans, "n")) confirm = 2;
304       if (!strcmp(ans, "S") || !strcmp(ans, "s")) return GE_USERCANCELED;
305     }  
306     if (confirm==1) break;
307     if (confirm==2) {
308       while (confirm2 < 0) {
309         fprintf(stderr, _("Enter name of new file: "));
310         GetLine(stdin, FileName, 50);
311         if (&FileName[0]==0) return GE_USERCANCELED;
312         confirm2=1;
313       }  
314     }
315   }
316   
317   error=GSM_SaveRingtoneFile(FileName,ringtone);
318   
319   switch (error) {
320     case GE_CANTOPENFILE:        fprintf(stderr, _("Failed to write file \"%s\"\n"),FileName);
321                                  break;
322     default:                     break;
323   }
324   
325   return error;
326 }
327
328 GSM_Error GSM_ReadBitmapFileOnConsole(char *FileName, GSM_Bitmap *bitmap)
329 {
330   GSM_Error error;
331   
332   error=GSM_ReadBitmapFile(FileName, bitmap);
333
334   switch (error) {
335     case GE_CANTOPENFILE:
336     case GE_WRONGNUMBEROFCOLORS:
337     case GE_WRONGCOLORS:        
338     case GE_INVALIDFILEFORMAT:  
339     case GE_SUBFORMATNOTSUPPORTED:
340     case GE_TOOSHORT:
341     case GE_INVALIDIMAGESIZE:
342       fprintf(stderr, _("File \"%s\"\nError: %s\n"),FileName,print_error(error));
343       break;
344     default: 
345       break;
346   }
347   
348   return error;
349 }
350
351 GSM_Error GSM_SaveBitmapFileOnConsole(char *FileName, GSM_Bitmap *bitmap)
352 {
353   int confirm,confirm2;
354   char ans[4];
355   struct stat buf;
356   GSM_Error error;
357
358   /* Ask before overwriting */
359   while (stat(FileName, &buf) == 0) {
360   
361     confirm=-1;
362     confirm2=-1;
363     
364     while (confirm < 0) {
365       fprintf(stderr, _("Saving logo. File \"%s\" exists. (O)verwrite, create (n)ew or (s)kip ? "),FileName);
366       GetLine(stdin, ans, 4);
367       if (!strcmp(ans, "O") || !strcmp(ans, "o")) confirm = 1;
368       if (!strcmp(ans, "N") || !strcmp(ans, "n")) confirm = 2;
369       if (!strcmp(ans, "S") || !strcmp(ans, "s")) return GE_USERCANCELED;
370     }  
371     if (confirm==1) break;
372     if (confirm==2) {
373       while (confirm2 < 0) {
374         fprintf(stderr, _("Enter name of new file: "));
375         GetLine(stdin, FileName, 50);
376         if (&FileName[0]==0) return GE_USERCANCELED;
377         confirm2=1;
378       }  
379     }
380   }
381   
382   error=GSM_SaveBitmapFile(FileName,bitmap);
383   
384   switch (error) {
385     case GE_CANTOPENFILE:        fprintf(stderr, _("Failed to write file \"%s\"\n"),FileName);
386                                  break;
387     default:                     break;
388   }
389   
390   return error;
391 }
392
393 /* mode == 0 -> overwrite
394  * mode == 1 -> ask
395  * mode == 2 -> append
396  */
397 int GSM_SaveTextFileOnConsole(char *FileName, char *text, int mode)
398 {
399   int confirm, confirm2;
400   char ans[4];
401   struct stat buf;
402   int error;
403
404   /* Ask before overwriting */
405   if (mode==1) {
406     while (stat(FileName, &buf) == 0 && mode==1) {
407       
408       confirm=-1;
409       confirm2=-1;
410       
411       while (confirm < 0) {
412         fprintf(stderr, _("File \"%s\" exists. (O)verwrite, (a)ppend, create (n)ew or (s)kip ? "),FileName);
413         GetLine(stdin, ans, 4);
414         if (!strcmp(ans, "O") || !strcmp(ans, "o")) {
415           mode = 0;
416           confirm = 1;
417         }
418         if (!strcmp(ans, "A") || !strcmp(ans, "a")) {
419           mode = 2;
420           confirm = 1;
421         }
422         if (!strcmp(ans, "N") || !strcmp(ans, "n")) confirm=2;
423         if (!strcmp(ans, "S") || !strcmp(ans, "s")) return -1;
424       }
425       
426       if (confirm==2) {
427         while (confirm2 < 0) {
428           fprintf(stderr, _("Enter name of new file: "));
429           GetLine(stdin, FileName, 50);
430           if (&FileName[0]==0) return -1;
431           mode=1;
432           confirm2=1;
433         }  
434       }
435       
436     }  
437   }
438   
439   error=GSM_SaveTextFile(FileName, text, mode);
440   
441   switch (error) {
442     case -1: fprintf(stderr, _("Failed to write file \"%s\"\n"),  FileName);
443              break;
444     default: break;
445   }
446
447   return error;
448 }
449
450 int GSM_SendMultiPartSMSOnConsole(GSM_MultiSMSMessage *MultiSMS, int argnum, int argc, char *argv[],
451                                   bool unicode, bool profile, bool scale) {
452
453   int w,i;
454   
455   struct option options[] = {
456              { "smscno",       required_argument, NULL, '1'},
457              { "smsc",         required_argument, NULL, '2'},
458              { "name",         required_argument, NULL, '3'},
459              { "unicode",      no_argument,       NULL, '4'},
460              { "profilestyle", no_argument,       NULL, '5'},
461              { "scale",        no_argument,       NULL, '6'},
462              { NULL,           0,                 NULL,  0 }
463   };
464
465   GSM_Error error;  
466
467   for (w=0;w<MultiSMS->number;w++) {
468
469     if (argnum!=0) {
470       optarg = NULL;
471   
472       /* We check optional parameters from ... */
473       optind = argnum;
474
475       while ((i = getopt_long(argc, argv, "v:ds", options, NULL)) != -1) {
476         switch (i) {
477
478           case '1': /* SMSC number */
479             MultiSMS->SMS[w].MessageCenter.No = 0;
480             strcpy(MultiSMS->SMS[w].MessageCenter.Number,optarg);
481             break;
482
483           case '2': /* SMSC number index in phone memory */
484             MultiSMS->SMS[w].MessageCenter.No = atoi(optarg);
485
486             if (MultiSMS->SMS[w].MessageCenter.No < 1 || MultiSMS->SMS[w].MessageCenter.No > 5) {
487               fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
488               GSM->Terminate();
489               return -1;
490             }
491             break;
492
493           case '3': /* Receiver/recipient */
494             strncpy(MultiSMS->SMS[w].Destination,optarg,11); break;
495
496           case '4': /* Unicode */
497             if (unicode) break;
498
499           case '5': /* Profile */
500             if (profile) break;
501
502           case '6': /* Scale */
503             if (scale) break;
504
505           case 'v': /* Set validaty of SMS */
506             MultiSMS->SMS[w].Validity = atoi(optarg);
507             break;
508
509           case 'd': /* delivery report */
510             MultiSMS->SMS[w].Type=GST_DR;
511             break;      
512
513           case 's': /* Set replying via the same SMSC */
514             MultiSMS->SMS[w].ReplyViaSameSMSC = true; break;
515
516         default:
517           fprintf(stderr,_("Unknown option number %i\n"),argc);
518           GSM->Terminate();    
519           return -1;
520
521         }
522       }
523     }
524
525     error=GSM->SendSMSMessage(&MultiSMS->SMS[w]);
526
527     if (error == GE_SMSSENDOK) {
528       fprintf(stdout, _("SMS %i/%i sent OK !\n"),w+1,MultiSMS->number);
529     } else {
530       fprintf(stdout, _("SMS %i/%i, sending failed (error=%d)\n"),w+1,MultiSMS->number, error);
531     }
532
533   }
534
535   GSM->Terminate();  
536
537   return 0;
538 }
539
540 int GSM_SaveMultiPartSMSOnConsole(GSM_MultiSMSMessage *MultiSMS, int argnum, int argc, char *argv[],
541                                   bool inter, bool unicode, bool profile, bool scale) {
542
543   int w,i;
544   
545   GSM_SMSMessage SMSold;
546
547   struct option options[] = {
548              { "smscno",       required_argument, NULL, '1'},
549              { "smsc",         required_argument, NULL, '2'},
550              { "name",         required_argument, NULL, '3'},
551              { "unicode",      no_argument,       NULL, '4'},
552              { "profilestyle", no_argument,       NULL, '5'},
553              { "scale",        no_argument,       NULL, '6'},
554              { NULL,           0,                 NULL,  0 }
555   };
556
557   int interactive;
558   int confirm = -1;
559   char ans[8];
560
561   GSM_Error error;  
562
563   interactive = inter;
564
565   for (w=0;w<MultiSMS->number;w++) {
566
567     if (argnum!=0) {
568       optarg = NULL;
569   
570       /* We check optional parameters from ... */
571       optind = argnum;
572
573       while ((i = getopt_long(argc, argv, "risal:", options, NULL)) != -1) {
574         switch (i) {
575
576           case '1': /* SMSC number */
577             MultiSMS->SMS[w].MessageCenter.No = 0;
578             strcpy(MultiSMS->SMS[w].MessageCenter.Number,optarg);
579             break;
580
581           case '2': /* SMSC number index in phone memory */
582             MultiSMS->SMS[w].MessageCenter.No = atoi(optarg);
583
584             if (MultiSMS->SMS[w].MessageCenter.No < 1 || MultiSMS->SMS[w].MessageCenter.No > 5) {
585               fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
586               GSM->Terminate();
587               return -1;
588             }
589             break;
590
591           case '3': /* Receiver/recipient */
592             strncpy(MultiSMS->SMS[w].Destination,optarg,11); break;
593
594           case '4': /* Unicode */
595             if (unicode) break;
596
597           case '5': /* Profile */
598             if (profile) break;
599
600           case '6': /* Scale */
601             if (scale) break;
602
603           case 'r': /* mark as read */
604             MultiSMS->SMS[w].Status = GSS_SENTREAD; break;
605
606           case 'i': /* Save into Inbox */
607             MultiSMS->SMS[w].folder = GST_INBOX; break;
608           
609           case 's': /* Set replying via the same SMSC */
610             MultiSMS->SMS[w].ReplyViaSameSMSC = true; break;
611
612           case 'a': /* Ask before overwriting */
613             interactive=true;break;     
614         
615           case 'l': /* Specify location */
616             MultiSMS->SMS[0].Location = atoi(optarg); break;     
617
618         default:
619           fprintf(stderr,_("Unknown option number %i\n"),argc);
620           GSM->Terminate();    
621           return -1;
622         }
623       }
624     }
625
626     if (interactive && MultiSMS->SMS[0].Location!=0 && w==0) {
627       SMSold.Location=MultiSMS->SMS[0].Location;
628       error = GSM->GetSMSMessage(&SMSold);
629       switch (error) {
630         case GE_NONE:
631           fprintf(stderr, _("Message at specified location exists. "));
632           while (confirm < 0) {
633             fprintf(stderr, _("Overwrite? (yes/no) "));
634             GetLine(stdin, ans, 7);
635             if (!strcmp(ans, "yes")) confirm = 1;
636             if (!strcmp(ans, "no")) confirm = 0;
637           }  
638           if (!confirm) { GSM->Terminate(); return 0; }
639           else break;
640         case GE_INVALIDSMSLOCATION:
641           fprintf(stderr, _("Invalid location\n"));
642           GSM->Terminate();
643           return -1;
644         default:
645 /* FIXME: Remove this fprintf when the function is thoroughly tested */
646 #ifdef DEBUG
647             fprintf(stderr, _("Location %d empty. Saving\n"), SMS[w].Location);
648 #endif
649           break;
650       }
651     }
652
653     error=GSM->SaveSMSMessage(&MultiSMS->SMS[w]);
654
655     if (error == GE_NONE)
656       fprintf(stdout, _("SMS %i/%i saved at location %i !\n"),w+1,MultiSMS->number,MultiSMS->SMS[w].MessageNumber);
657     else
658       fprintf(stdout, _("SMS %i/%i saving failed (error=%d, location=%i)\n"), w+1, MultiSMS->number, error,MultiSMS->SMS[w].Location);
659   }
660
661   GSM->Terminate();  
662
663   return 0;
664 }
665
666 void GSM_PlayRingtoneOnConsole(GSM_Ringtone *ringtone)
667 {
668   int i;
669 #ifdef VC6
670   char mychar;
671 #endif
672
673   for (i=0;i<ringtone->NrNotes;i++) {
674 #ifdef VC6
675     if (_kbhit()) {
676       mychar=_getch();
677       break;
678     }
679 #endif
680     GSM_PlayOneNote (ringtone->notes[i]);
681   }
682   GSM->PlayTone(255*255,0);
683 }
684
685 /* This function shows the copyright and some informations usefull for
686    debugging. */
687 int version(void)
688 {
689
690   fprintf(stdout, _("GNOKII Version %s\n"
691 "Copyright (C) Hugh Blemings <hugh@linuxcare.com>, 1999, 2000\n"
692 "Copyright (C) Pavel Janík ml. <Pavel.Janik@linux.cz>, 1999, 2000\n"
693 "Built %s %s for %s on %s \n"), VERSION, __TIME__, __DATE__, model, Port);
694
695   return 0;
696 }
697
698 /* The function usage is only informative - it prints this program's usage and
699    command-line options. */
700
701 int usage(void)
702 {
703
704   fprintf(stdout, _("   usage: gnokii [--help|--monitor [-noloop|-nl]|--version]\n"
705 "          gnokii --getmemory memory_type [start [end]] [-short|-v30|-v21|-v]\n"
706 "          gnokii --writephonebook [-i]\n"
707 "          gnokii --sendphonebookentry destination memory_type location\n"
708 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
709 "                 [-s] [-v n] [-d]\n"
710 "          gnokii --savephonebookentry memory_type location\n"
711 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
712 "                 [-r] [-i] [-s] [-a] [--name name]\n"
713 "          gnokii --getvoicemailbox\n"
714 "          gnokii --getspeeddial number\n"
715 "          gnokii --setspeeddial number memory_type location\n\n"
716
717 "          gnokii --getsms memory_type start [end] [-f file]\n"
718 "          gnokii --getsmsstatus\n"
719 "          gnokii --getsmsfolders\n"
720 "          gnokii --deletesms memory_type start [end]\n"
721 "          gnokii --sendsms destination [--smsc message_center_number |\n"
722 "                 --smscno message_center_index] [--long n] [-s] [-C n]\n"
723 "                 [--enablevoice|--disablevoice|--enablefax|--disablefax|\n"
724 "                  --enableemail|--disableemail|--void][--unicode][-v n][-d]\n"
725 "          gnokii --savesms destination|\"\" [--smsc \n"
726 "                 message_center_number] [--smscno message_center_index]\n"
727 "                 [--long n] [-r] [-i] [-s][-C n][-a][-l][F n][--smsname name]\n"
728 "                 [--enablevoice|--disablevoice|--enablefax|--disablefax|\n"
729 "                  --enableemail|--disableemail|--void|--hang|--bug][--unicode]\n"
730 "          gnokii --receivesms\n"
731 "          gnokii --getsmsc message_center_number\n"
732 "          gnokii --renamesmsc number new_name\n\n"
733
734 "          gnokii --setdatetime [YYYY [MM [DD [HH [MM]]]]]\n"
735 "          gnokii --getdatetime\n"
736 "          gnokii --setalarm HH MM\n"
737 "          gnokii --getalarm\n\n"
738
739 "          gnokii --getcalendarnote { start end [-v30|-v10] | --short|-s }\n"
740 "          gnokii --writecalendarnote vcardfile number\n"
741 "          gnokii --deletecalendarnote index\n"
742 "          gnokii --sendcalendarnote destination vcardfile number\n"
743 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
744 "                 [-s] [-v n] [-d]\n"
745 "          gnokii --savecalendarnote vcardfile number\n"
746 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
747 "                 [-r] [-i] [-s] [-a] [--name name]\n\n"
748
749 "          gnokii --netmonitor {reset|off|field|devel|next|nr}\n"
750 "          gnokii --nm_collect screen1|-d [screen2|-d]...\n"
751 "          gnokii --netmonitordata [-S file] [-I file] [-h] [-n n] [-ts n][-tm n]\n"
752 "                 [-fs str] [-ls str] FLD1:FLD2:FLDn:... \n"
753 "                 (see files netmonitordata_????_??? for details)\n\n"
754
755 "          gnokii --bitmapconvert source destination\n"
756 "          gnokii --bitmapconvert source destination op|7110op [network code]\n"
757 "          gnokii --bitmapconvert source destination caller [caller group number]\n"
758 "          gnokii --bitmapconvert source destination\n"
759 "                   startup|7110startup|6210startup\n"
760 "          gnokii --bitmapconvert source destination picture\n"
761 "          gnokii --showbitmap logofile\n"
762 "          gnokii --sendlogo op destination logofile network_code\n"
763 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
764 "                 [-s] [-v n] [-d]\n"
765 "          gnokii --sendlogo picture destination logofile text\n"
766 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
767 "                 [-s] [-v n] [-d] [--unicode]\n"
768 "          gnokii --sendlogo screensaver destination logofile\n"
769 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
770 "                 [-s] [-v n] [-d]\n"
771 "          gnokii --sendlogo caller destination logofile\n"
772 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
773 "                 [-s] [-v n] [-d]\n"
774 "          gnokii --savelogo op logofile network_code\n"
775 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
776 "                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
777 "          gnokii --savelogo picture logofile text\n"
778 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
779 "                 [-r] [-i] [-s] [-a] [-l] [--name name] [--unicode]\n"
780 "          gnokii --savelogo screensaver logofile\n"
781 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
782 "                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
783 "          gnokii --savelogo caller logofile\n"
784 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
785 "                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
786 "          gnokii --setlogo op|7110op [logofile] [network code]\n"
787 "          gnokii --setlogo startup|7110startup|6210startup [logofile]\n"
788 "          gnokii --setlogo startup 1|2|3\n"
789 "          gnokii --setlogo caller [logofile] [caller group number] [group name]\n"
790 "          gnokii --setlogo picture [logofile] [number] [text] [sender]\n"
791 "          gnokii --setlogo {dealer|text} [text]\n"
792 "          gnokii --getlogo op|7110op [logofile] [network code]\n"
793 "          gnokii --getlogo startup|7110startup|6210startup [logofile]\n"
794 "          gnokii --getlogo caller [logofile][caller group number]\n"
795 "          gnokii --getlogo picture [logofile][number]\n"
796 "          gnokii --getlogo {dealer|text}\n\n"
797
798 "          gnokii --sendringtone destination ringtonefile\n"
799 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
800 "                 [-s] [-v n] [-d] [--scale] [--profilestyle]\n"
801 "          gnokii --saveringtone ringtonefile\n"
802 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
803 "                 [-r] [-i] [-s] [-a] [--name name] [--scale] [--profilestyle]\n"
804 "          gnokii --setringtone ringtonefile [location]\n"
805 "          gnokii --getringtone ringtonefile [location]\n"
806 "          gnokii --ringtoneconvert source destination\n"
807 "          gnokii --binringtoneconvert source destination\n"
808 "          gnokii --playringtone ringtonefile\n"
809 "          gnokii --composer ringtonefile\n"
810 "          gnokii --allringtones\n\n"
811
812 "          gnokii --getprofile [number]\n"
813 "          gnokii --setprofile number feature value\n"
814 "          gnokii --sendprofile destination profile_name ringtonefile\n"
815 "                 picturefile [--smsc message_center_number]\n"
816 "                 [--smscno message_center_index] [-s] [-v n] [-d] [--scale]\n\n"
817
818 "          gnokii --reset [soft|hard]\n"
819 "          gnokii --dialvoice number\n"
820 "          gnokii --cancelcall\n"
821 "          gnokii --displayoutput\n"
822 "          gnokii --presskeysequence sequence\n"
823 "          gnokii --backupsettings file\n"
824 "          gnokii --restoresettings file\n"
825 "          gnokii --getphoneprofile\n"
826 "          gnokii --setphoneprofile feature value\n"
827 "          gnokii --getoperatorname\n"
828 "          gnokii --setoperatorname code name\n"
829 "          gnokii --senddtmf string\n"
830 "          gnokii --divert register|enable|query|disable|erasure\n"
831 "                 all|busy|noans|outofreach all|voice|fax|data\n"
832 "                 [number timeout]\n\n"
833
834 "          gnokii --phonetests\n"
835 "          gnokii --simlock\n"
836 "          gnokii --getdisplaystatus\n"
837 "          gnokii --identify\n\n"
838
839 "          gnokii --getwapbookmark location\n"
840 "          gnokii --setwapbookmark title url [location]\n"
841 "          gnokii --sendwapbookmark location destination\n"
842 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
843 "                 [-s] [-v n] [-d]\n"
844 "          gnokii --savewapbookmark location\n"
845 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
846 "                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
847 "          gnokii --getwapsettings location\n"
848 "          gnokii --savewapsettings location\n"
849 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
850 "                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
851 "          gnokii --sendwapsettings location destination\n"
852 "                 [--smsc message_center_number] [--smscno message_center_index]\n"
853 "                 [-s] [-v n] [-d]\n"
854   ));
855
856 #ifdef SECURITY
857   fprintf(stdout, _(
858 "\n          gnokii --entersecuritycode PIN|PIN2|PUK|PUK2\n"
859 "          gnokii --getsecuritycodestatus\n"
860 "          gnokii --getsecuritycode PIN|PIN2|PUK|PUK2|SecurityCode\n"
861 "          gnokii --geteeprom\n"
862 "          gnokii --resetphonesettings\n"
863   ));
864 #endif
865
866 #ifdef DEBUG
867   fprintf(stdout, _(
868 "          gnokii --sniff [port]\n"
869 "          gnokii --decodefile file\n"
870 "          gnokii --getbinringfromfile file name offset file2\n"
871   ));
872 #endif
873
874   return 0;
875 }
876
877 /* fbusinit is the generic function which waits for the FBUS link. The limit
878    is 10 seconds. After 10 seconds we quit. */
879
880 void fbusinit(void (*rlp_handler)(RLP_F96Frame *frame))
881 {
882
883   int count=0;
884   GSM_Error error;
885
886 #ifndef WIN32
887   if (strcmp(GetMygnokiiVersion(),VERSION)!=0)
888     fprintf(stderr,_("WARNING: version of installed libmygnokii.so (%s) is different to version of gnokii (%s)\n"),GetMygnokiiVersion(),VERSION);
889 #endif
890
891   /* Initialise the code for the GSM interface. */     
892   error = GSM_Initialise(model, Port, Initlength, GetConnectionTypeFromString(Connection), rlp_handler, SynchronizeTime);
893
894   if (error != GE_NONE) {
895     fprintf(stderr, _("GSM/FBUS init failed! (Unknown model ?). Quitting.\n"));
896     exit(-1);
897   }
898
899   /* First (and important!) wait for GSM link to be active. We allow 10
900      seconds... */
901   while (count++ < 200 && *GSM_LinkOK == false)
902     usleep(50000);
903
904   if (*GSM_LinkOK == false) {
905     fprintf (stderr, _("Hmmm... GSM_LinkOK never went true. Quitting.\n"));
906     exit(-1);
907   }  
908 }
909
910 /* This function checks that the argument count for a given options is withing
911    an allowed range. */
912
913 int checkargs(int opt, struct gnokii_arg_len gals[], int argc)
914 {
915
916   int i;
917
918   /* Walk through the whole array with options requiring arguments. */
919
920   for(i = 0;!(gals[i].gal_min == 0 && gals[i].gal_max == 0); i++) {
921
922     /* Current option. */
923
924     if(gals[i].gal_opt == opt) {
925
926       /* Argument count checking. */
927
928       if(gals[i].gal_flags == GAL_XOR) {
929         if(gals[i].gal_min == argc || gals[i].gal_max == argc) return 0;
930       }
931       else {
932         if(gals[i].gal_min <= argc && gals[i].gal_max >= argc) return 0;
933       }
934
935       return 1;
936
937     }
938
939   }
940
941   /* We do not have options without arguments in the array, so check them. */
942
943   if (argc==0) return 0;
944           else return 1;
945 }
946
947 /* Main function - handles command line arguments, passes them to separate
948    functions accordingly. */
949
950 int main(int argc, char *argv[])
951 {
952
953   int c, i, rc = -1;
954   int nargc = argc-2;
955   char **nargv;
956
957   /* Every option should be in this array. */
958
959   static struct option long_options[] =
960   {
961
962     { "help",               no_argument,       NULL, OPT_HELP             },// Display usage.
963     { "version",            no_argument,       NULL, OPT_VERSION          },// Display version and build information.
964     { "getsmsfolders",      no_argument,       NULL, OPT_GETSMSFOLDERS    },// Gets SMS folders
965     { "getsmsstatus",       no_argument,       NULL, OPT_GETSMSSTATUS     },// Get SMS Folder Status
966     { "identify",           no_argument,       NULL, OPT_IDENTIFY         },// Identify
967     { "pmon",               no_argument,       NULL, OPT_PMON             },// For development purposes: run in passive monitoring mode
968     { "foogle",             no_argument,       NULL, OPT_FOOGLE           },// For development purposes: insert you function calls here
969     { "getdatetime",        no_argument,       NULL, OPT_GETDATETIME      },// Get date and time mode    
970     { "getalarm",           no_argument,       NULL, OPT_GETALARM         },// Get alarm    
971     { "cancelcall",         no_argument,       NULL, OPT_CANCELCALL       },// Cancel Call    
972     { "getdisplaystatus",   no_argument,       NULL, OPT_GETDISPLAYSTATUS },// Get display status mode    
973     { "allringtones",       no_argument,       NULL, OPT_ALLRINGTONES     },/* Displays names of available ringtones */    
974     { "displayoutput",      no_argument,       NULL, OPT_DISPLAYOUTPUT    },/* Show texts from phone's display */
975     { "getphoneprofile",    no_argument,       NULL, OPT_GETPHONEPROFILE  },/* Get/Set phone profile settings */
976     { "getoperatorname",    no_argument,       NULL, OPT_GETOPERATORNAME  },/* Get downloaded operator name */    
977     { "getvoicemailbox",    no_argument,       NULL, OPT_GETVOICEMAILBOX  },/* Gets voice mailbox number */    
978     { "phonetests",         no_argument,       NULL, OPT_PHONETESTS       },
979     { "simlockinfo",        no_argument,       NULL, OPT_SIMLOCKINFO      },    
980     { "receivesms",         no_argument,       NULL, OPT_RECEIVESMS       },    
981     { "setoperatorname",    optional_argument, NULL, OPT_SETOPERATORNAME  },/* Set downloaded operator name */    
982     { "setdatetime",        optional_argument, NULL, OPT_SETDATETIME      },// Set date and time    
983     { "writephonebook",     optional_argument, NULL, OPT_WRITEPHONEBOOK   },// Write phonebook (memory) mode
984     { "reset",              optional_argument, NULL, OPT_RESET            },// Resets the phone
985     { "monitor",            optional_argument, NULL, OPT_MONITOR          },// Monitor mode
986     { "setlogo",            optional_argument, NULL, OPT_SETLOGO          },// Set logo
987     { "getprofile",         optional_argument, NULL, OPT_GETPROFILE       },// Show profile
988     { "setalarm",           required_argument, NULL, OPT_SETALARM         },// Set alarm
989     { "dialvoice",          required_argument, NULL, OPT_DIALVOICE        },// Voice call mode
990     { "getcalendarnote",    required_argument, NULL, OPT_GETCALENDARNOTE  },// Get calendar note mode    
991     { "writecalendarnote",  required_argument, NULL, OPT_WRITECALENDARNOTE},// Write calendar note mode
992     { "sendcalendarnote",   required_argument, NULL, OPT_SENDCALENDARNOTE },
993     { "savecalendarnote",   required_argument, NULL, OPT_SAVECALENDARNOTE },
994     { "sendphonebookentry", required_argument, NULL, OPT_SENDPHONEBOOKENTRY},
995     { "savephonebookentry", required_argument, NULL, OPT_SAVEPHONEBOOKENTRY},
996     { "deletecalendarnote", required_argument, NULL, OPT_DELCALENDARNOTE  },// Delete calendar note mode    
997     { "getmemory",          required_argument, NULL, OPT_GETMEMORY        },// Get memory mode
998     { "getspeeddial",       required_argument, NULL, OPT_GETSPEEDDIAL     },// Get speed dial mode
999     { "setspeeddial",       required_argument, NULL, OPT_SETSPEEDDIAL     },// Set speed dial mode
1000     { "getsms",             required_argument, NULL, OPT_GETSMS           },// Get SMS message mode
1001     { "deletesms",          required_argument, NULL, OPT_DELETESMS        },// Delete SMS message mode
1002     { "sendsms",            required_argument, NULL, OPT_SENDSMS          },// Send SMS message mode
1003     { "savesms",            required_argument, NULL, OPT_SAVESMS          },// Save SMS message mode
1004     { "sendlogo",           required_argument, NULL, OPT_SENDLOGO         },// Send logo as SMS message mode
1005     { "savelogo",           required_argument, NULL, OPT_SAVELOGO         },// Save logo on SIM
1006     { "sendringtone",       required_argument, NULL, OPT_SENDRINGTONE     },// Send ringtone as SMS message
1007     { "saveringtone",       required_argument, NULL, OPT_SAVERINGTONE     },// Saves ringtone on SIM
1008     { "setringtone",        required_argument, NULL, OPT_SETRINGTONE      },// Set ringtone    
1009     { "getringtone",        required_argument, NULL, OPT_GETRINGTONE      },// Get bin/normal ringtone    
1010     { "presskeysequence",   required_argument, NULL, OPT_PRESSKEYSEQUENCE },/* Presses keys in phone's display */
1011     { "getsmsc",            required_argument, NULL, OPT_GETSMSC          },// Get SMS center number mode
1012     { "renamesmsc",         required_argument, NULL, OPT_RENAMESMSC       },// Rename SMSC
1013     { "netmonitor",         required_argument, NULL, OPT_NETMONITOR       },// NetMonitor mode
1014     { "senddtmf",           required_argument, NULL, OPT_SENDDTMF         },// Send DTMF sequence
1015     { "getlogo",            required_argument, NULL, OPT_GETLOGO          },// Get logo
1016     { "setprofile",         required_argument, NULL, OPT_SETPROFILE       },// Set profile feature
1017     { "sendprofile",        required_argument, NULL, OPT_SENDPROFILE      },// Send profile via SMS
1018     { "setphoneprofile",    required_argument, NULL, OPT_SETPHONEPROFILE  },/* Get/Set phone profile settings */
1019     { "restoresettings",    required_argument, NULL, OPT_RESTORESETTINGS  },//Restore various settings from one file
1020     { "backupsettings",     required_argument, NULL, OPT_BACKUPSETTINGS   },//Backup various settings to one file
1021     { "playringtone",       required_argument, NULL, OPT_PLAYRINGTONE     },/* Plays ringtones */    
1022     { "composer",           required_argument, NULL, OPT_COMPOSER         },/* Shows ringtone like in Nokia Composer */    
1023     { "ringtoneconvert",    required_argument, NULL, OPT_RINGTONECONVERT  },/* Convert ringtone files */    
1024     { "binringtoneconvert", required_argument, NULL, OPT_BINRINGTONECONVERT},/* Convert binary ringtone files */    
1025     { "bitmapconvert",      required_argument, NULL, OPT_BITMAPCONVERT    },/* Convert bitmap files */    
1026     { "showbitmap",         required_argument, NULL, OPT_SHOWBITMAP       },    
1027     { "nm_collect",         required_argument, NULL, OPT_NM_COLLECT       },// NetMonitor periodical data collection mode (newbiee)
1028     { "netmonitordata",     required_argument, NULL, OPT_NETMONITORDATA   },// NetMonitor periodical data collection mode (advanced)
1029     { "getwapbookmark",     required_argument, NULL, OPT_GETWAPBOOKMARK   },    
1030     { "setwapbookmark",     required_argument, NULL, OPT_SETWAPBOOKMARK   },    
1031     { "savewapbookmark",    required_argument, NULL, OPT_SAVEWAPBOOKMARK  },    
1032     { "savewapsettings",    required_argument, NULL, OPT_SAVEWAPSETTINGS  },    
1033     { "sendwapsettings",    required_argument, NULL, OPT_SENDWAPSETTINGS  },    
1034     { "sendwapbookmark",    required_argument, NULL, OPT_SENDWAPBOOKMARK  },    
1035     { "getwapsettings",     required_argument, NULL, OPT_GETWAPSETTINGS   },    
1036     { "divert",             required_argument, NULL, OPT_DIVERT           },
1037
1038 #ifdef SECURITY
1039     { "entersecuritycode",  required_argument, NULL, OPT_ENTERSECURITYCODE    },// Enter Security Code mode
1040     { "getsecuritycode",    required_argument, NULL, OPT_GETSECURITYCODE      },// Get Security Code
1041   { "getsecuritycodestatus",no_argument,       NULL, OPT_GETSECURITYCODESTATUS},// Get Security Code status
1042     { "geteeprom",          no_argument,       NULL, OPT_GETEEPROM            },// Gets EEPROM
1043     { "resetphonesettings", no_argument,       NULL, OPT_RESETPHONESETTINGS   },// Reset phone settings
1044     { "setsimlock",         no_argument,       NULL, OPT_SETSIMLOCK           },// Sets simlock
1045 #endif
1046
1047 #ifdef DEBUG
1048     { "sniff",              optional_argument, NULL, OPT_SNIFFER    },// Will show datas from port
1049     { "decodefile",         required_argument, NULL, OPT_DECODEFILE },//decode input file
1050     { "getbinringfromfile", required_argument, NULL, OPT_GETBINRINGFROMFILE },
1051 #endif
1052
1053     { 0, 0, 0, 0},
1054   };
1055
1056   /* Every command which requires arguments should have an appropriate entry
1057      in this array. */
1058         
1059   struct gnokii_arg_len gals[] =
1060   {
1061
1062     { OPT_MONITOR,           0, 1, 0 },
1063
1064 #ifdef SECURITY
1065     { OPT_ENTERSECURITYCODE, 1, 1, 0 },
1066     { OPT_GETSECURITYCODE,   1, 1, 0 },
1067 #endif
1068
1069 #ifdef DEBUG
1070     { OPT_SNIFFER,           0, 1, 0 },
1071     { OPT_DECODEFILE,        1, 1, 0 },
1072     { OPT_GETBINRINGFROMFILE,4, 4, 0 },
1073 #endif
1074
1075     { OPT_SETDATETIME,       0, 5, 0 },
1076     { OPT_BACKUPSETTINGS,    1, 1, 0 },
1077     { OPT_RESTORESETTINGS,   1, 1, 0 },
1078     { OPT_SETALARM,          2, 2, 0 },
1079     { OPT_DIALVOICE,         1, 1, 0 },
1080     { OPT_GETCALENDARNOTE,   1, 3, 0 },
1081     { OPT_WRITECALENDARNOTE, 2, 2, 0 },
1082     { OPT_SAVECALENDARNOTE,  2, 9, 0 },
1083     { OPT_SENDCALENDARNOTE,  3, 9, 0 },
1084     { OPT_SAVEPHONEBOOKENTRY,2, 9, 0 },
1085     { OPT_SENDPHONEBOOKENTRY,3, 9, 0 },
1086     { OPT_DELCALENDARNOTE,   1, 1, 0 },
1087     { OPT_GETMEMORY,         2, 4, 0 },
1088     { OPT_GETSPEEDDIAL,      1, 1, 0 },
1089     { OPT_SETSPEEDDIAL,      3, 3, 0 },
1090     { OPT_GETSMS,            2, 5, 0 },
1091     { OPT_DELETESMS,         2, 3, 0 },
1092     { OPT_SENDSMS,           1,10, 0 },
1093     { OPT_SAVESMS,           1,11, 0 },
1094     { OPT_SENDLOGO,          3, 9, 0 },
1095     { OPT_SAVELOGO,          2,10, 0 },
1096     { OPT_SENDRINGTONE,      2, 7, 0 },
1097     { OPT_SAVERINGTONE,      1, 9, 0 },
1098     { OPT_GETSMSC,           1, 1, 0 },
1099     { OPT_RENAMESMSC,        2, 2, 0 },
1100     { OPT_NETMONITOR,        1, 1, 0 },
1101     { OPT_SENDDTMF,          1, 1, 0 },
1102     { OPT_SETLOGO,           1, 5, 0 },
1103     { OPT_GETLOGO,           1, 4, 0 },
1104     { OPT_SETRINGTONE,       1, 3, 0 },
1105     { OPT_GETRINGTONE,       1, 2, 0 },
1106     { OPT_PRESSKEYSEQUENCE,  1, 1, 0 },
1107     { OPT_RESET,             0, 1, 0 },
1108     { OPT_GETPROFILE,        0, 1, 0 },
1109     { OPT_SETPROFILE,        3, 3, 0 },
1110     { OPT_SENDPROFILE,       4,10, 0 },
1111     { OPT_WRITEPHONEBOOK,    0, 1, 0 },
1112     { OPT_PLAYRINGTONE,      1, 1, 0 },
1113     { OPT_COMPOSER,          1, 1, 0 },
1114     { OPT_RINGTONECONVERT,   2, 2, 0 },
1115     { OPT_BINRINGTONECONVERT,2, 2, 0 },
1116     { OPT_BITMAPCONVERT,     2, 4, 0 },
1117     { OPT_SHOWBITMAP,        1, 1, 0 },
1118     { OPT_SETOPERATORNAME,   0, 2, 0 },    
1119     { OPT_SETPHONEPROFILE,   2, 2, 0 },        
1120     { OPT_NM_COLLECT,        1, MAX_NM_COLLECT, 0 },
1121     { OPT_NETMONITORDATA,    0,99, 0 },
1122     { OPT_GETWAPBOOKMARK,    1, 1, 0 },
1123     { OPT_SETWAPBOOKMARK,    2, 3, 0 },
1124     { OPT_SAVEWAPBOOKMARK,   1, 9, 0 },
1125     { OPT_SENDWAPBOOKMARK,   2, 9, 0 },
1126     { OPT_GETWAPSETTINGS,    1, 1, 0 },
1127     { OPT_SAVEWAPSETTINGS,   1, 9, 0 },
1128     { OPT_SENDWAPSETTINGS,   2, 9, 0 },
1129     { OPT_DIVERT,            3, 5, 0 },    
1130
1131     { 0, 0, 0, 0 },
1132   };
1133
1134   opterr = 0;
1135
1136   /* For GNU gettext */
1137
1138 #ifdef USE_NLS
1139 #ifndef VC6
1140   textdomain("gnokii");
1141   setlocale(LC_ALL, "pl_PL"); //here is string for Polish localisation
1142 #else
1143   setlocale(LC_ALL, ".852"); //Polish codepage for console, not "real" WIN CP
1144 #endif
1145
1146 #endif
1147
1148     /* Read config file */
1149     if (CFG_ReadConfig(&model, &Port, &Initlength, &Connection, &BinDir, &SynchronizeTime,false) < 0) {
1150         exit(-1);
1151     }
1152
1153   /* Handle command line arguments. */
1154
1155   c = getopt_long(argc, argv, "", long_options, NULL);
1156
1157   if (c == -1) {
1158
1159     /* No argument given - we should display usage. */
1160     usage();
1161     exit(-1);
1162   }
1163
1164   /* We have to build an array of the arguments which will be passed to the
1165      functions.  Please note that every text after the --command will be
1166      passed as arguments.  A syntax like gnokii --cmd1 args --cmd2 args will
1167      not work as expected; instead args --cmd2 args is passed as a
1168      parameter. */
1169
1170   if((nargv = malloc(sizeof(char *) * argc)) != NULL) {
1171
1172     for(i = 2; i < argc; i++)
1173       nargv[i-2] = argv[i];
1174         
1175     if(checkargs(c, gals, nargc)) {
1176
1177       free(nargv);
1178
1179       /* Wrong number of arguments - we should display usage. */
1180       usage();
1181       exit(-1);
1182     }
1183
1184 #ifndef VC6
1185 #if defined(__svr4__)
1186     /* have to ignore SIGALARM */
1187     sigignore(SIGALRM);
1188 #endif
1189 #endif
1190
1191     switch(c) {
1192
1193     // First, error conditions  
1194     case '?':
1195       fprintf(stderr, _("Use '%s --help' for usage informations.\n"), argv[0]);
1196       break;
1197         
1198     // Then, options with no arguments
1199     case OPT_HELP:                  rc = usage();                   break;
1200     case OPT_VERSION:               rc = version();                 break;
1201     case OPT_MONITOR:               rc = monitormode(nargc, nargv); break;
1202     case OPT_GETSMSFOLDERS:         rc = getsmsfolders();           break;
1203     case OPT_GETDATETIME:           rc = getdatetime();             break;
1204     case OPT_GETALARM:              rc = getalarm();                break;
1205     case OPT_GETDISPLAYSTATUS:      rc = getdisplaystatus();        break;
1206     case OPT_PMON:                  rc = pmon();                    break;
1207     case OPT_WRITEPHONEBOOK:        rc = writephonebook(nargc, nargv);break;
1208
1209 #ifdef SECURITY
1210     case OPT_ENTERSECURITYCODE:     rc = entersecuritycode(optarg); break;
1211     case OPT_GETSECURITYCODESTATUS: rc = getsecuritycodestatus();   break;
1212     case OPT_GETSECURITYCODE:       rc = getsecuritycode(optarg);   break;
1213     case OPT_GETEEPROM:             rc = geteeprom();               break;
1214     case OPT_RESETPHONESETTINGS:    rc = resetphonesettings();      break;
1215     case OPT_SETSIMLOCK:            rc = setsimlock();              break;
1216 #endif
1217
1218 #ifdef DEBUG
1219     case OPT_SNIFFER:               rc = sniff(nargc, nargv);       break;
1220     case OPT_DECODEFILE:            rc = decodefile(nargc, nargv);  break;
1221     case OPT_GETBINRINGFROMFILE:    rc = getbinringfromfile(nargc, nargv);break;
1222 #endif                                  
1223         
1224     // Now, options with arguments
1225     case OPT_SETDATETIME:           rc = setdatetime(nargc, nargv); break;
1226     case OPT_SETALARM:              rc = setalarm(nargv);           break;
1227     case OPT_DIALVOICE:             rc = dialvoice(optarg);         break;
1228     case OPT_CANCELCALL:            rc = cancelcall();              break;
1229     case OPT_GETCALENDARNOTE:       rc = getcalendarnote(nargc, nargv);break;
1230     case OPT_DELCALENDARNOTE:       rc = deletecalendarnote(optarg);break;
1231     case OPT_SAVECALENDARNOTE:      rc = savecalendarnote(nargc, nargv);break;
1232     case OPT_SENDCALENDARNOTE:      rc = sendcalendarnote(nargc, nargv);break;
1233     case OPT_SAVEPHONEBOOKENTRY:    rc = savephonebookentry(nargc, nargv);break;
1234     case OPT_SENDPHONEBOOKENTRY:    rc = sendphonebookentry(nargc, nargv);break;
1235     case OPT_WRITECALENDARNOTE:     rc = writecalendarnote(nargv);  break;
1236     case OPT_GETMEMORY:             rc = getmemory(nargc, nargv);   break;
1237     case OPT_GETSPEEDDIAL:          rc = getspeeddial(optarg);      break;
1238     case OPT_SETSPEEDDIAL:          rc = setspeeddial(nargv);       break;
1239     case OPT_GETSMS:                rc = getsms(argc, argv);        break;
1240     case OPT_GETSMSSTATUS:          rc = getsmsstatus(argc, argv);  break;
1241     case OPT_DELETESMS:             rc = deletesms(nargc, nargv);   break;
1242     case OPT_SENDSMS:               rc = sendsms(nargc, nargv);     break;
1243     case OPT_SAVESMS:               rc = savesms(nargc, nargv);     break;
1244     case OPT_DIVERT:                rc = divert(nargc, nargv);      break;
1245     case OPT_SENDLOGO:              rc = sendlogo(nargc, nargv);    break;
1246     case OPT_SAVELOGO:              rc = savelogo(nargc, nargv);    break;
1247     case OPT_GETSMSC:               rc = getsmsc(optarg);           break;
1248     case OPT_RENAMESMSC:            rc = renamesmsc(nargc,nargv);   break;
1249     case OPT_NETMONITOR:            rc = netmonitor(optarg);        break;
1250     case OPT_IDENTIFY:              rc = identify();                break;
1251     case OPT_SETLOGO:               rc = setlogo(nargc, nargv);     break;
1252     case OPT_GETLOGO:               rc = getlogo(nargc, nargv);     break;
1253     case OPT_RECEIVESMS:            rc = receivesms(nargc, nargv);  break;
1254     case OPT_SETRINGTONE:           rc = setringtone(nargc, nargv); break;
1255     case OPT_GETRINGTONE:           rc = getringtone(nargc, nargv); break;
1256     case OPT_PRESSKEYSEQUENCE:      rc = presskeysequence(nargv);   break;
1257     case OPT_SENDRINGTONE:          rc = sendringtone(nargc, nargv);break;
1258     case OPT_SAVERINGTONE:          rc = saveringtone(nargc, nargv);break;
1259     case OPT_GETPROFILE:            rc = getprofile(nargc, nargv);  break;
1260     case OPT_SETPROFILE:            rc = setprofile(nargc, nargv);  break;
1261     case OPT_SENDPROFILE:           rc = sendprofile(nargc, nargv); break;
1262     case OPT_DISPLAYOUTPUT:         rc = displayoutput();           break;
1263     case OPT_RESTORESETTINGS:       rc = restoresettings(nargv);    break;
1264     case OPT_BACKUPSETTINGS:        rc = backupsettings(nargv);     break;
1265     case OPT_RINGTONECONVERT:       rc = ringtoneconvert(nargc, nargv);break;
1266     case OPT_BINRINGTONECONVERT:    rc = binringtoneconvert(nargc, nargv);break;
1267     case OPT_BITMAPCONVERT:         rc = bitmapconvert(nargc, nargv);break;
1268     case OPT_SHOWBITMAP:            rc = showbitmap(nargc, nargv);  break;
1269     case OPT_PLAYRINGTONE:          rc = playringtone(nargc, nargv);break;
1270     case OPT_COMPOSER:              rc = composer(nargc, nargv);    break;
1271     case OPT_FOOGLE:                rc = foogle(nargv);             break;
1272     case OPT_PHONETESTS:            rc = phonetests();              break;
1273     case OPT_SIMLOCKINFO:           rc = simlockinfo();             break;
1274     case OPT_SENDDTMF:              rc = senddtmf(optarg);          break;
1275     case OPT_RESET:                 rc = reset(nargc,nargv);        break;
1276     case OPT_GETOPERATORNAME:       rc = getoperatorname();         break;
1277     case OPT_SETOPERATORNAME:       rc = setoperatorname(nargc,nargv);break;
1278     case OPT_GETWAPBOOKMARK:        rc = getwapbookmark(nargc,nargv);break;
1279     case OPT_SETWAPBOOKMARK:        rc = setwapbookmark(nargc,nargv);break;
1280     case OPT_SAVEWAPBOOKMARK:       rc = savewapbookmark(nargc,nargv);break;
1281     case OPT_SENDWAPBOOKMARK:       rc = sendwapbookmark(nargc,nargv);break;
1282     case OPT_GETWAPSETTINGS:        rc = getwapsettings(nargc,nargv);break;
1283     case OPT_SAVEWAPSETTINGS:       rc = savewapsettings(nargc,nargv);break;
1284     case OPT_SENDWAPSETTINGS:       rc = sendwapsettings(nargc,nargv);break;
1285     case OPT_ALLRINGTONES:          rc = allringtones();            break;
1286     case OPT_GETPHONEPROFILE:       rc = getphoneprofile();         break;
1287     case OPT_SETPHONEPROFILE:       rc = setphoneprofile(nargc,nargv);break;
1288     case OPT_GETVOICEMAILBOX:       rc = getvoicemailbox();         break;
1289     case OPT_NM_COLLECT:            rc = nm_collect(nargc, nargv);  break;
1290     case OPT_NETMONITORDATA:        rc = netmonitordata(nargc, nargv);break;
1291
1292     default:         fprintf(stderr, _("Unknown option: %d\n"), c); break;
1293
1294     }
1295
1296     free(nargv);
1297
1298     return(rc);
1299   }
1300
1301   fprintf(stderr, _("Wrong number of arguments\n"));
1302
1303   exit(-1);
1304 }
1305
1306 /* Restores various phone settings from one file */
1307 int restoresettings(char *argv[])
1308 {
1309   GSM_Backup Backup;
1310   GSM_PhonebookEntry pbk;
1311
1312   int confirm;
1313   char ans[4];
1314
1315   int i,pos;
1316
1317   GSM_MemoryStatus SIMMemoryStatus = {GMT_SM, 0, 0};
1318   GSM_MemoryStatus PhoneMemoryStatus = {GMT_ME, 0, 0};
1319
1320   if (GSM_ReadBackupFile(argv[0], &Backup)!=GE_NONE) return 1;
1321
1322   fbusinit(NULL);
1323
1324   if (Backup.SIMPhonebookUsed!=0) {
1325     confirm=-1;    
1326     while (confirm < 0) {
1327       fprintf(stderr, _("Restore SIM phonebook ? "));
1328       GetLine(stdin, ans, 99);
1329       if (!strcmp(ans, "yes")) confirm = 1;
1330       if (!strcmp(ans, "no" )) confirm = 0;
1331     }
1332     if (confirm==1) {
1333       if (GSM->GetMemoryStatus(&SIMMemoryStatus) != GE_NONE) {
1334         fprintf(stderr,_("Error getting memory status !\n"));
1335         GSM->Terminate();
1336       }
1337       i=0;pos=1;
1338
1339       while ((pos-1)!=SIMMemoryStatus.Used+SIMMemoryStatus.Free) {
1340         pbk.Location=pos;
1341         pbk.MemoryType=GMT_SM;
1342         pbk.Name[0]=0;
1343         pbk.Number[0]=0;
1344         pbk.SubEntriesCount = 0;
1345         if (i<Backup.SIMPhonebookUsed) {
1346           if (Backup.SIMPhonebook[i].Location==pbk.Location) {
1347             pbk=Backup.SIMPhonebook[i];
1348             i++;
1349 //#ifdef DEBUG
1350 //            fprintf(stdout,_("Copying from backup\n"));
1351 //#endif
1352           }
1353         }
1354 //#ifdef DEBUG
1355 //        fprintf(stdout,_("Setting location %i\n"),pbk.Location);
1356 //#endif
1357         GSM->WritePhonebookLocation(&pbk);
1358         fprintf(stderr,_("."));
1359         pos++;
1360       }
1361       fprintf(stderr,_("\n"));
1362     }
1363   }
1364   if (Backup.PhonePhonebookUsed!=0) {
1365     confirm=-1;    
1366     while (confirm < 0) {
1367       fprintf(stderr, _("Restore phone phonebook ? "));
1368       GetLine(stdin, ans, 99);
1369       if (!strcmp(ans, "yes")) confirm = 1;
1370       if (!strcmp(ans, "no" )) confirm = 0;
1371     }
1372     if (confirm==1) {
1373       if (GSM->GetMemoryStatus(&PhoneMemoryStatus) != GE_NONE) {
1374         fprintf(stderr,_("Error getting memory status !\n"));
1375         GSM->Terminate();
1376       }
1377
1378       i=0;pos=1;
1379
1380       while ((pos-1)!=PhoneMemoryStatus.Used+PhoneMemoryStatus.Free) {
1381         pbk.Location=pos;
1382         pbk.MemoryType=GMT_ME;
1383         pbk.Name[0]=0;
1384         pbk.Number[0]=0;
1385         pbk.SubEntriesCount = 0;
1386         if (i<Backup.PhonePhonebookUsed) {
1387           if (Backup.PhonePhonebook[i].Location==pbk.Location) {
1388             pbk=Backup.PhonePhonebook[i];
1389             i++;
1390 //#ifdef DEBUG
1391 //            fprintf(stdout,_("Copying from backup\n"));
1392 //#endif
1393           }
1394         }
1395 //#ifdef DEBUG
1396 //        fprintf(stdout,_("Setting location %i\n"),pbk.Location);
1397 //#endif
1398         GSM->WritePhonebookLocation(&pbk);
1399         fprintf(stderr,_("."));
1400         pos++;
1401       }
1402       fprintf(stderr,_("\n"));
1403     }
1404   }
1405   if (Backup.CallerAvailable==true) {
1406     confirm=-1;    
1407     while (confirm < 0) {
1408       fprintf(stderr, _("Restore caller groups ? "));
1409       GetLine(stdin, ans, 99);
1410       if (!strcmp(ans, "yes")) confirm = 1;
1411       if (!strcmp(ans, "no" )) confirm = 0;
1412     }
1413     if (confirm==1) {
1414       for (i=0;i<5;i++) GSM->SetBitmap(&Backup.CallerGroups[i]);
1415     }
1416   }
1417   if (Backup.OperatorLogoAvailable==true) {
1418     confirm=-1;    
1419     while (confirm < 0) {
1420       fprintf(stderr, _("Restore operator logo ? "));
1421       GetLine(stdin, ans, 99);
1422       if (!strcmp(ans, "yes")) confirm = 1;
1423       if (!strcmp(ans, "no" )) confirm = 0;
1424     }
1425     if (confirm==1) {
1426       GSM->SetBitmap(&Backup.OperatorLogo);
1427     }
1428   }
1429   if (Backup.StartupLogoAvailable==true) {
1430     confirm=-1;    
1431     while (confirm < 0) {
1432       fprintf(stderr, _("Restore startup logo ? "));
1433       GetLine(stdin, ans, 99);
1434       if (!strcmp(ans, "yes")) confirm = 1;
1435       if (!strcmp(ans, "no" )) confirm = 0;
1436     }
1437     if (confirm==1) {
1438       GSM->SetBitmap(&Backup.StartupLogo);
1439     }
1440   }
1441
1442   GSM->Terminate();
1443
1444   return 0;
1445 }
1446
1447 /* Backup various phone settings from one file */
1448 int backupsettings(char *argv[])
1449 {
1450   GSM_PhonebookEntry PbkEntry;
1451   GSM_Error error;
1452   GSM_Backup Backup;
1453   int i;
1454
1455   GSM_MemoryStatus SIMMemoryStatus = {GMT_SM, 0, 0};
1456   GSM_MemoryStatus PhoneMemoryStatus = {GMT_ME, 0, 0};
1457
1458   fbusinit(NULL);
1459
1460   fprintf(stderr,_("Backup phonebook from SIM..."));
1461   Backup.SIMPhonebookUsed=0;
1462   if (GSM->GetMemoryStatus(&SIMMemoryStatus) == GE_NONE) {
1463     Backup.SIMPhonebookSize=SIMMemoryStatus.Used+SIMMemoryStatus.Free;
1464
1465     PbkEntry.MemoryType=GMT_SM;
1466
1467     for (i=0;i<Backup.SIMPhonebookSize;i++)
1468     {
1469       if (SIMMemoryStatus.Used==Backup.SIMPhonebookUsed) break;
1470
1471       PbkEntry.Location=i;
1472     
1473       error=GSM->GetMemoryLocation(&PbkEntry);
1474       switch (error) {
1475         case GE_NONE:
1476           Backup.SIMPhonebook[Backup.SIMPhonebookUsed]=PbkEntry;
1477           Backup.SIMPhonebookUsed++;
1478           fprintf(stderr,_("."));
1479           break;
1480         default:
1481           break;
1482       }
1483     }
1484     fprintf(stderr,_("Done\n"));
1485   } else fprintf(stderr,_("ERROR\n"));
1486
1487   fprintf(stderr,_("Backup phonebook from phone..."));
1488   Backup.PhonePhonebookUsed=0;
1489   if (GSM->GetMemoryStatus(&PhoneMemoryStatus) == GE_NONE) {
1490     Backup.PhonePhonebookSize=PhoneMemoryStatus.Used+PhoneMemoryStatus.Free;
1491
1492     PbkEntry.MemoryType=GMT_ME;
1493
1494     for (i=0;i<Backup.PhonePhonebookSize;i++)
1495     {
1496       if (PhoneMemoryStatus.Used==Backup.PhonePhonebookUsed) break;
1497
1498       PbkEntry.Location=i;
1499     
1500       error=GSM->GetMemoryLocation(&PbkEntry);
1501       switch (error) {
1502         case GE_NONE:
1503           Backup.PhonePhonebook[Backup.PhonePhonebookUsed]=PbkEntry;
1504           Backup.PhonePhonebookUsed++;
1505           fprintf(stderr,_("."));
1506           break;
1507         default:
1508           break;
1509       }
1510     }
1511     fprintf(stderr,_("Done\n"));
1512   } else fprintf(stderr,_("ERROR\n"));
1513
1514   if( GetModelFeature (FN_CALLERGROUPS)!=0) {
1515     fprintf(stderr,_("Backup caller logos..."));
1516     Backup.CallerAvailable=true;
1517     for (i=0;i<5;i++) {
1518       Backup.CallerGroups[i].number=i;
1519       Backup.CallerGroups[i].type=GSM_CallerLogo;
1520       if (GSM->GetBitmap(&Backup.CallerGroups[i])!=GE_NONE) return 1;
1521     }
1522     fprintf(stderr,_("Done\n"));
1523   } else Backup.CallerAvailable=false;
1524
1525 //  fprintf(stderr,_("Backup speed dials..."));
1526   Backup.SpeedAvailable=false;
1527 //  for (i=0;i<8;i++) {
1528 //    Backup.SpeedDials[i].Number=i+1;
1529 //    if (GSM->GetSpeedDial(&Backup.SpeedDials[i])!=GE_NONE) return 1;
1530 //  }
1531 //  fprintf(stderr,_("Done\n"));
1532
1533   fprintf(stderr,_("Backup operator logo..."));
1534   Backup.OperatorLogoAvailable=true;
1535   Backup.OperatorLogo.type=GSM_7110OperatorLogo;
1536   if (GSM->GetBitmap(&Backup.OperatorLogo)!=GE_NONE) {
1537     Backup.OperatorLogo.type=GSM_OperatorLogo;
1538     if (GSM->GetBitmap(&Backup.OperatorLogo)!=GE_NONE) {
1539       Backup.OperatorLogoAvailable=false;
1540      fprintf(stderr,_("Error\n"));
1541     } else fprintf(stderr,_("Done\n"));
1542   } else fprintf(stderr,_("Done\n"));
1543
1544   Backup.StartupLogoAvailable=false;
1545   if( GetModelFeature (FN_STARTUP)!=0) {
1546     fprintf(stderr,_("Backup startup logo..."));
1547     Backup.StartupLogoAvailable=true;
1548     switch (GetModelFeature (FN_STARTUP)) {
1549       case F_STA62: Backup.StartupLogo.type=GSM_6210StartupLogo;break;
1550       case F_STA71: Backup.StartupLogo.type=GSM_7110StartupLogo;break;
1551       default     : Backup.StartupLogo.type=GSM_StartupLogo;break;
1552     }
1553     if (GSM->GetBitmap(&Backup.StartupLogo)!=GE_NONE) {
1554       Backup.StartupLogoAvailable=false;
1555       fprintf(stderr,_("Error\n"));
1556     } else fprintf(stderr,_("Done\n"));
1557   }
1558
1559   fprintf(stderr,_("Backup welcome note..."));
1560   Backup.StartupText.type=GSM_WelcomeNoteText;
1561   if (GSM->GetBitmap(&Backup.StartupText)!=GE_NONE) {
1562     fprintf(stderr,_("Error\n"));
1563   } else fprintf(stderr,_("Done\n"));
1564
1565   GSM->Terminate();
1566
1567   GSM_SaveBackupFile(argv[0], &Backup);
1568
1569   return 0;
1570 }
1571
1572 /* Presses keys on phone's keyboard */
1573
1574 int presskeysequence(char *argv[])
1575 {
1576   int i,j;
1577   int keycode;
1578   char key;
1579   
1580   sleep(1);
1581
1582   fbusinit(NULL);
1583   
1584   for (i=0;i<strlen(argv[0]);i++)
1585   {
1586     key=argv[0][i];
1587     keycode=0;
1588     j=0;
1589     
1590     if (key!='w' && key!='W')
1591     {
1592       while (Keys[j].whatchar!=' ') {
1593         if (Keys[j].whatchar==key) {    
1594           keycode=Keys[j].whatcode;
1595           break;
1596         }
1597         j++;
1598       }
1599     
1600       if (keycode==0) {
1601         fprintf(stderr,_("Unknown key: %c !\n"),key);
1602         GSM->Terminate();
1603         return -1;
1604       }
1605     
1606       if (GSM->PressKey(keycode,PRESSPHONEKEY)!=GE_NONE)
1607       {
1608         fprintf(stderr,_("Can't press key !\n"));
1609         GSM->Terminate();
1610         return -1;
1611       }
1612       if (GSM->PressKey(keycode,RELEASEPHONEKEY)!=GE_NONE)
1613       {
1614         fprintf(stderr,_("Can't release key !\n"));
1615         GSM->Terminate();
1616         return -1;
1617       }
1618     } else
1619     {
1620       sleep(2);
1621     }
1622   }
1623   
1624   GSM->Terminate();
1625
1626   return 0;
1627 }
1628
1629 /* Send  SMS messages. */
1630 int sendsms(int argc, char *argv[])
1631 {
1632   GSM_MultiSMSMessage MultiSMS;
1633   char message_buffer[GSM_MAX_CONCATENATED_SMS_LENGTH];
1634   int input_len, chars_read,i,msgnum;
1635
1636   GSM_SMSMessageType SMSType=GST_SMS;
1637   int SMSValidity= 4320; /* 4320 minutes == 72 hours */
1638   bool SMSReply=false;
1639   int SMSClass=-1,SMSCenter=1;
1640   char SMSCNumber[100];
1641   GSM_Coding_Type SMSCoding=GSM_Coding_Default;
1642   GSM_UDH SMSUDHType=GSM_NoUDH;
1643
1644   struct option options[] = {
1645              { "smscno",       required_argument, NULL, '1'},
1646              { "smsc",         required_argument, NULL, '2'},
1647              { "long",         required_argument, NULL, '3'},
1648              { "enablevoice",  no_argument,       NULL, '4'},
1649              { "disablevoice", no_argument,       NULL, '5'},
1650              { "enableemail",  no_argument,       NULL, '6'},
1651              { "disableemail", no_argument,       NULL, '7'},
1652              { "enablefax",    no_argument,       NULL, '8'},
1653              { "disablefax",   no_argument,       NULL, '9'},
1654              { "unicode",      no_argument,       NULL, '-'},
1655              { "void",         no_argument,       NULL, '+'},
1656              { "hang",         no_argument,       NULL, '('},
1657              { "bug",          no_argument,       NULL, ')'},
1658              { NULL,           0,                 NULL, 0}
1659   };
1660   
1661   input_len = GSM_MAX_SMS_LENGTH;
1662
1663   if (argc!=0) {
1664
1665     optarg = NULL;
1666     optind = 0;
1667
1668     while ((i = getopt_long(argc, argv, "v:dsC:", options, NULL)) != -1) {
1669       switch (i) {
1670
1671         case '1': /* SMSC number */
1672           SMSCenter = 0;
1673           strcpy(SMSCNumber,optarg);
1674           break;
1675
1676         case '2': /* SMSC number index in phone memory */
1677           SMSCenter = atoi(optarg);
1678
1679           if (SMSCenter < 1 || SMSCenter > 5) {
1680             fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
1681             GSM->Terminate();
1682             return -1;
1683           }
1684           break;
1685
1686         case '3': /* we send long message */
1687           SMSUDHType=GSM_ConcatenatedMessages;
1688           input_len = atoi(optarg);
1689           if (input_len > GSM_MAX_CONCATENATED_SMS_LENGTH) {
1690             fprintf(stderr, _("Input too long, max %i!\n"),GSM_MAX_CONCATENATED_SMS_LENGTH);
1691             exit(-1);
1692           }
1693           break;
1694
1695         case '4': /* SMS enables voice indicator */
1696           SMSUDHType=GSM_EnableVoice;    break;
1697
1698         case '5': /* SMS disables voice indicator */
1699           SMSUDHType=GSM_DisableVoice;   break;   
1700
1701         case '6': /* SMS enables email indicator */
1702           SMSUDHType=GSM_EnableEmail;    break;   
1703
1704         case '7': /* SMS disables email indicator */
1705           SMSUDHType=GSM_DisableEmail;   break;   
1706
1707         case '8': /* SMS enables fax indicator */
1708           SMSUDHType=GSM_EnableFax;      break;   
1709
1710         case '9': /* SMS disables fax indicator */
1711           SMSUDHType=GSM_DisableFax;     break;   
1712
1713         case '-': /* SMS coding type */
1714           SMSCoding=GSM_Coding_Unicode;  break;
1715
1716         case '+': /* SMS ghost */
1717           SMSUDHType=GSM_VoidSMS;        break;
1718
1719         case '(': /* SMS hanging phone, when saved to Outbox */
1720           SMSUDHType=GSM_HangSMS;        break;
1721
1722         case ')': /* SMS showed incorrectly in phone */
1723           SMSUDHType=GSM_BugSMS;         break;
1724
1725         case 'v': /* Set validaty of SMS */
1726           SMSValidity = atoi(optarg);    break;
1727
1728         case 'd': /* delivery report */
1729           SMSType=GST_DR;                break; 
1730
1731         case 's': /* Set replying via the same SMSC */
1732           SMSReply = true;               break;
1733
1734         case 'C': /* class Message */
1735           
1736           if (SMSUDHType!=GSM_NoUDH) {
1737             fprintf(stderr, _("Can't specify SMS Class with --enablevoice, --disablevoice, --enableemail, --disableemail, --enablefax, --disablefax options !\n"));         
1738             return -1;
1739           }
1740           
1741           switch (*optarg) {
1742             case '0': SMSClass = 0; break;
1743             case '1': SMSClass = 1; break;
1744             case '2': SMSClass = 2; break;
1745             case '3': SMSClass = 3; break; 
1746             default:
1747               fprintf(stderr, _("SMS Class (\"C\" option) can be 0, 1, 2 or 3 only !\n"));
1748               return -1;
1749           }
1750           break;
1751           
1752         default:
1753           fprintf(stderr,_("Unknown option number %i\n"),argc);
1754           return -1;
1755       }
1756     }
1757   }
1758   
1759   /* Get message text from stdin. */
1760   chars_read = fread(message_buffer, 1, input_len, stdin);
1761
1762   if (chars_read == 0) {
1763     fprintf(stderr, _("Couldn't read from stdin!\n"));  
1764     return -1;
1765   }
1766   if (chars_read > input_len) {
1767     fprintf(stderr, _("Input too long!\n"));    
1768     return -1;
1769   }
1770   
1771   /*  Null terminate. */
1772   message_buffer[chars_read] = 0x00;    
1773
1774   GSM_MakeMultiPartSMS2(&MultiSMS,message_buffer,chars_read,SMSUDHType,SMSCoding);
1775   msgnum=MultiSMS.number;
1776
1777   switch (SMSUDHType) {
1778     case GSM_NoUDH:
1779     case GSM_BugSMS:
1780     case GSM_VoidSMS:
1781     case GSM_HangSMS:
1782     case GSM_EnableVoice:
1783     case GSM_DisableVoice:
1784     case GSM_EnableFax:
1785     case GSM_DisableFax:
1786     case GSM_EnableEmail:
1787     case GSM_DisableEmail:
1788       fprintf(stdout,_("Warning: saving %i chars\n"),strlen(MultiSMS.SMS[0].MessageText));
1789       msgnum=1;
1790       break;
1791     default:
1792       break;
1793   }
1794
1795   for (i=0;i<msgnum;i++) {
1796     strcpy(MultiSMS.SMS[i].Destination,argv[0]);
1797
1798     MultiSMS.SMS[i].Class=SMSClass;
1799     MultiSMS.SMS[i].ReplyViaSameSMSC=SMSReply;
1800     MultiSMS.SMS[i].Type=SMSType;
1801     MultiSMS.SMS[i].Validity=SMSValidity;
1802   }
1803
1804   /* Initialise the GSM interface. */     
1805   fbusinit(NULL);
1806
1807   MultiSMS.number=msgnum;
1808   GSM_SendMultiPartSMSOnConsole(&MultiSMS, 0,0,NULL,false,false,false);
1809   
1810   return 0;
1811 }
1812
1813 int savesms(int argc, char *argv[])
1814 {
1815   GSM_MultiSMSMessage MultiSMS;
1816   char message_buffer[GSM_MAX_CONCATENATED_SMS_LENGTH];
1817   int input_len, chars_read,i,msgnum;
1818
1819   int SMSClass=-1,SMSCenter=1;
1820   char SMSName[25+1];
1821   char SMSCNumber[100];
1822   GSM_Coding_Type SMSCoding=GSM_Coding_Default;
1823   GSM_UDH SMSUDHType=GSM_NoUDH;
1824   GSM_SMSMessageStatus SMSStatus;
1825   int SMSFolder;
1826   bool SMSReply=false;
1827   int SMSLocation=0;
1828   bool interactive=false;
1829
1830   struct option options[] = {
1831              { "smscno",       required_argument, NULL, '1'},
1832              { "smsc",         required_argument, NULL, '2'},
1833              { "long",         required_argument, NULL, '3'},
1834              { "enablevoice",  no_argument,       NULL, '4'},
1835              { "disablevoice", no_argument,       NULL, '5'},
1836              { "enableemail",  no_argument,       NULL, '6'},
1837              { "disableemail", no_argument,       NULL, '7'},
1838              { "enablefax",    no_argument,       NULL, '8'},
1839              { "disablefax",   no_argument,       NULL, '9'},
1840              { "unicode",      no_argument,       NULL, '-'},
1841              { "void",         no_argument,       NULL, '+'},
1842              { "hang",         no_argument,       NULL, '('},
1843              { "bug",          no_argument,       NULL, ')'},
1844              { "smsname",      required_argument, NULL, '/'},
1845              { NULL,           0,                 NULL, 0}
1846   };
1847
1848   SMSCNumber[0]=0;
1849   SMSName[0]=0;
1850   SMSStatus=GSS_NOTSENTREAD;
1851   SMSFolder=GST_OUTBOX;
1852   
1853   input_len = GSM_MAX_SMS_LENGTH;
1854
1855   if (argc!=0) {
1856
1857     optarg = NULL;
1858     optind = 0;
1859
1860     while ((i = getopt_long(argc, argv, "risal:C:F:", options, NULL)) != -1) {
1861       switch (i) {
1862
1863         case '1': /* SMSC number */
1864           SMSCenter = 0;
1865           strcpy(SMSCNumber,optarg);
1866           break;
1867
1868         case '2': /* SMSC number index in phone memory */
1869           SMSCenter = atoi(optarg);
1870
1871           if (SMSCenter < 1 || SMSCenter > 5) {
1872             fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
1873             GSM->Terminate();
1874             return -1;
1875           }
1876           break;
1877
1878         case '3': /* we send long message */
1879           SMSUDHType=GSM_ConcatenatedMessages;
1880           input_len = atoi(optarg);
1881           if (input_len > GSM_MAX_CONCATENATED_SMS_LENGTH) {
1882             fprintf(stderr, _("Input too long, max %i!\n"),GSM_MAX_CONCATENATED_SMS_LENGTH);
1883             exit(-1);
1884           }
1885           break;
1886
1887         case '4': /* SMS enables voice indicator */
1888           SMSUDHType=GSM_EnableVoice;    break;
1889
1890         case '5': /* SMS disables voice indicator */
1891           SMSUDHType=GSM_DisableVoice;   break;   
1892
1893         case '6': /* SMS enables email indicator */
1894           SMSUDHType=GSM_EnableEmail;    break;   
1895
1896         case '7': /* SMS disables email indicator */
1897           SMSUDHType=GSM_DisableEmail;   break;   
1898
1899         case '8': /* SMS enables fax indicator */
1900           SMSUDHType=GSM_EnableFax;      break;   
1901
1902         case '9': /* SMS disables fax indicator */
1903           SMSUDHType=GSM_DisableFax;     break;   
1904
1905         case '-': /* SMS coding type */
1906           SMSCoding=GSM_Coding_Unicode;  break;
1907
1908         case '+': /* SMS ghost */
1909           SMSUDHType=GSM_VoidSMS;        break;
1910
1911         case '(': /* SMS hanging phone, when saved to Outbox */
1912           SMSUDHType=GSM_HangSMS;        break;
1913
1914         case ')': /* SMS showed incorrectly in phone */
1915           SMSUDHType=GSM_BugSMS;         break;
1916
1917         case 'r': /* mark as read */
1918           SMSStatus = GSS_SENTREAD; break;
1919  
1920         case 'i': /* Save into Inbox */
1921           SMSFolder = GST_INBOX; break;
1922           
1923         case 's': /* Set replying via the same SMSC */
1924           SMSReply = true; break;
1925
1926         case 'a': /* Ask before overwriting */
1927           interactive=true;break;     
1928         
1929         case 'l': /* Specify location */
1930           SMSLocation = atoi(optarg); break;     
1931
1932         case '/': /* Name */
1933           strncpy(SMSName,optarg,25);break;
1934
1935         case 'C': /* class Message */
1936           
1937           if (SMSUDHType!=GSM_NoUDH) {
1938             fprintf(stderr, _("Can't specify SMS Class with --enablevoice, --disablevoice, --enableemail, --disableemail, --enablefax, --disablefax options !\n"));         
1939             return -1;
1940           }
1941           
1942           switch (*optarg) {
1943             case '0': SMSClass = 0; break;
1944             case '1': SMSClass = 1; break;
1945             case '2': SMSClass = 2; break;
1946             case '3': SMSClass = 3; break; 
1947             default:
1948               fprintf(stderr, _("SMS Class (\"C\" option) can be 0, 1, 2 or 3 only !\n"));
1949               return -1;
1950           }
1951           break;
1952
1953         case 'F': /* save into folder n */
1954           SMSFolder = atoi(optarg);
1955           break;
1956
1957         default:
1958           fprintf(stderr,_("Unknown option number %i\n"),argc);
1959           return -1;
1960       }
1961     }
1962   }
1963   
1964   /* Get message text from stdin. */
1965   chars_read = fread(message_buffer, 1, input_len, stdin);
1966
1967   if (chars_read == 0) {
1968     fprintf(stderr, _("Couldn't read from stdin!\n"));  
1969     return -1;
1970   }
1971   if (chars_read > input_len) {
1972     fprintf(stderr, _("Input too long!\n"));    
1973     return -1;
1974   }
1975   
1976   /*  Null terminate. */
1977   message_buffer[chars_read] = 0x00;    
1978
1979   GSM_MakeMultiPartSMS2(&MultiSMS,message_buffer,chars_read,SMSUDHType,SMSCoding);
1980   msgnum=MultiSMS.number;
1981
1982   switch (SMSUDHType) {
1983     case GSM_NoUDH:
1984     case GSM_BugSMS:
1985     case GSM_VoidSMS:
1986     case GSM_HangSMS:
1987     case GSM_EnableVoice:
1988     case GSM_DisableVoice:
1989     case GSM_EnableFax:
1990     case GSM_DisableFax:
1991     case GSM_EnableEmail:
1992     case GSM_DisableEmail:
1993       fprintf(stdout,_("Warning: saving %i chars\n"),strlen(MultiSMS.SMS[0].MessageText));
1994       msgnum=1;
1995       break;
1996     default:
1997       break;
1998   }
1999
2000   for (i=0;i<msgnum;i++) {
2001     MultiSMS.SMS[i].Destination[0]=0;
2002     if (argc!=0) strcpy(MultiSMS.SMS[i].Destination,argv[0]);
2003
2004     MultiSMS.SMS[i].Location=0;
2005     MultiSMS.SMS[i].Class=SMSClass;
2006     MultiSMS.SMS[i].MessageCenter.No=SMSCenter;
2007     strcpy(MultiSMS.SMS[i].MessageCenter.Number,SMSCNumber);
2008     MultiSMS.SMS[i].Status=SMSStatus;
2009     strcpy(MultiSMS.SMS[i].Name,SMSName);
2010     MultiSMS.SMS[i].folder=SMSFolder;
2011     MultiSMS.SMS[i].ReplyViaSameSMSC=SMSReply;
2012   }
2013
2014   MultiSMS.SMS[0].Location=SMSLocation;
2015
2016   /* Initialise the GSM interface. */     
2017   fbusinit(NULL);
2018
2019   MultiSMS.number=msgnum;
2020   GSM_SaveMultiPartSMSOnConsole(&MultiSMS, 0,0,NULL,interactive,false,false,false);
2021   
2022   return 0;
2023 }
2024
2025 /* Get SMSC number */
2026
2027 int getsmsc(char *MessageCenterNumber)
2028 {
2029
2030   GSM_MessageCenter MessageCenter;
2031
2032   MessageCenter.No=atoi(MessageCenterNumber);
2033
2034   fbusinit(NULL);
2035
2036   if (GSM->GetSMSCenter(&MessageCenter) == GE_NONE) {
2037
2038     fprintf(stdout, _("%d. SMS center ("),MessageCenter.No);
2039     
2040     if (!strcmp(MessageCenter.Name,""))
2041       fprintf(stdout,_("Set %d"),MessageCenter.No);
2042     else fprintf(stdout,_("%s"),MessageCenter.Name);
2043       
2044     fprintf(stdout,_(") number is "));
2045
2046     if (!strcmp(MessageCenter.Number,"")) fprintf(stdout,_("not set\n"));
2047     else fprintf(stdout,_("%s\n"),MessageCenter.Number);
2048
2049     fprintf(stdout,_("Default recipient number is "));
2050
2051     if (!strcmp(MessageCenter.DefaultRecipient,""))
2052       fprintf(stdout,_("not set\n"));
2053     else fprintf(stdout,_("%s\n"),MessageCenter.DefaultRecipient);
2054
2055     fprintf(stdout, _("Messages sent as "));
2056
2057     switch (MessageCenter.Format) {
2058       case GSMF_Text  :fprintf(stdout, _("Text"));break;
2059       case GSMF_Paging:fprintf(stdout, _("Paging"));break;
2060       case GSMF_Fax   :fprintf(stdout, _("Fax"));break;
2061       case GSMF_Email :
2062       case GSMF_UCI   :fprintf(stdout, _("Email"));break;
2063       case GSMF_ERMES :fprintf(stdout, _("ERMES"));break;
2064       case GSMF_X400  :fprintf(stdout, _("X.400"));break;
2065       default         :fprintf(stdout, _("Unknown"));
2066     }
2067
2068     printf("\n");
2069
2070     fprintf(stdout, _("Message validity is "));
2071
2072     switch (MessageCenter.Validity) {
2073       case GSMV_1_Hour  :fprintf(stdout, _("1 hour"));break;
2074       case GSMV_6_Hours :fprintf(stdout, _("6 hours"));break;
2075       case GSMV_24_Hours:fprintf(stdout, _("24 hours"));break;
2076       case GSMV_72_Hours:fprintf(stdout, _("72 hours"));break;
2077       case GSMV_1_Week  :fprintf(stdout, _("1 week"));break;
2078       case GSMV_Max_Time:fprintf(stdout, _("Maximum time"));break;
2079       default           :fprintf(stdout, _("Unknown"));
2080     }
2081
2082     fprintf(stdout, "\n");
2083
2084   }
2085   else
2086     fprintf(stdout, _("SMS center can not be found :-(\n"));
2087
2088   GSM->Terminate();
2089
2090   return 0;
2091 }
2092
2093 /* Get SMS messages. */
2094 int getsms(int argc, char *argv[])
2095 {
2096
2097   GSM_SMSMessage message;
2098   GSM_WAPBookmark bookmark;
2099   char memory_type_string[20];
2100   int start_message, end_message, count, mode = 1;
2101   char filename[64];
2102   GSM_Error error;
2103   GSM_Bitmap bitmap;
2104   GSM_Ringtone ringtone;
2105   GSM_SMSFolders folders;
2106   
2107   int confirm = -1, i;
2108   char ans[8];
2109
2110   /* Handle command line args that set type, start and end locations. */
2111   if (!GetMemoryTypeID(argv[2], &message.MemoryType))
2112   {
2113     fprintf(stderr, _("Unknown memory type %s!\n"), argv[2]);
2114     return (-1);
2115   }
2116   GetMemoryTypeString(memory_type_string, &message.MemoryType);
2117
2118   for (i=0;i<64;i++) filename[i]=0;
2119
2120   start_message = atoi(argv[3]);
2121   if (argc > 4) {
2122      int i;
2123      
2124      /* [end] can be only argv[4] */
2125      if (argv[4][0] == '-') { end_message = start_message; }
2126                        else { end_message = atoi(argv[4]); }
2127
2128      /* parse all options (beginning with '-' */
2129      while ((i = getopt(argc, argv, "f:")) != -1) {
2130         switch (i) {
2131           case 'f':
2132             if (optarg) {
2133 #ifdef DEBUG
2134           fprintf(stderr, _("Saving into file \"%s\"\n"), optarg);
2135 #endif /* DEBUG */
2136               strncpy(filename, optarg, 64);
2137               if (strlen(optarg) > 63) {
2138                 fprintf(stderr, _("Filename too long - will be truncated to 63 characters.\n"));
2139                 filename[63] = 0;
2140               } else {
2141                 filename[strlen(optarg)] = 0;
2142               }
2143             } else {
2144               usage();
2145               exit(1);
2146             }
2147             break;
2148           default:
2149             usage();
2150             exit(1);
2151         }
2152       }
2153   } else {
2154     end_message = start_message;
2155   }
2156
2157   /* Initialise the code for the GSM interface. */     
2158
2159   fbusinit(NULL);
2160
2161   GSM->GetSMSFolders(&folders);
2162
2163   
2164   /* Now retrieve the requested entries. */
2165
2166   for (count = start_message; count <= end_message; count ++) {
2167
2168     message.Location = count;
2169
2170     error = GSM->GetSMSMessage(&message);
2171
2172     switch (error) {
2173
2174     case GE_NONE:
2175
2176       switch (message.Type) {
2177
2178         case GST_DR:
2179
2180           /* RTH FIXME: Test that out ! */
2181           fprintf(stdout, _("%d. Delivery Report "), message.MessageNumber);
2182           switch (message.Status)
2183            {
2184             case  GSS_SENTREAD:
2185                 if (message.folder==0) fprintf(stdout, _("(read)\n")); //GST_INBOX
2186                                   else fprintf(stdout, _("(sent)\n"));
2187                 break;
2188             case  GSS_NOTSENTREAD:
2189                 if (message.folder==0) fprintf(stdout, _("(unread)\n")); //GST_INBOX
2190                                   else fprintf(stdout, _("(not sent)\n"));
2191                 break;
2192             case  GSS_UNKNOWN:
2193                 fprintf(stdout, _("(not known :-()\n"));
2194                 break;
2195             case  GSS_TEMPLATE:
2196                 fprintf(stdout, _("(template)\n"));
2197                 break;
2198             default:
2199                 fprintf(stdout, _("(unknown: %d)\n"),message.Status);
2200                 break;
2201            }
2202
2203           fprintf(stdout, _("Sending date/time : %s %02d/%02d/%02d %d:%02d:%02d "), \
2204                   DayOfWeek(message.Time.Year, message.Time.Month, message.Time.Day), \
2205                   message.Time.Day, message.Time.Month, message.Time.Year, \
2206                   message.Time.Hour, message.Time.Minute, message.Time.Second);
2207
2208           if (message.Time.Timezone) {
2209             if (message.Time.Timezone > 0)
2210               fprintf(stdout,_("+%02d00"), message.Time.Timezone);
2211             else
2212               fprintf(stdout,_("%02d00"), message.Time.Timezone);
2213           }
2214
2215           fprintf(stdout, "\n");
2216
2217           fprintf(stdout, _("Response date/time: %s %02d/%02d/%02d %d:%02d:%02d "), \
2218                   DayOfWeek(message.SMSCTime.Year, message.SMSCTime.Month, message.SMSCTime.Day), \
2219                   message.SMSCTime.Day, message.SMSCTime.Month, message.SMSCTime.Year, \
2220                   message.SMSCTime.Hour, message.SMSCTime.Minute, message.SMSCTime.Second);
2221
2222           if (message.SMSCTime.Timezone) {
2223             if (message.SMSCTime.Timezone > 0)
2224               fprintf(stdout,_("+%02d00"),message.SMSCTime.Timezone);
2225             else
2226               fprintf(stdout,_("%02d00"),message.SMSCTime.Timezone);
2227           }
2228
2229           fprintf(stdout, "\n");
2230
2231           fprintf(stdout, _("Receiver: %s Msg Center: %s\n"), message.Sender, message.MessageCenter.Number);
2232           fprintf(stdout, _("Text: %s\n\n"), message.MessageText); 
2233
2234           break;
2235
2236         case GST_SMS:
2237           fprintf(stdout, _("%d. %s Message "), message.MessageNumber,
2238                           folders.Folder[message.folder].Name);
2239
2240           switch (message.Status)
2241            {
2242             case  GSS_SENTREAD:
2243                 if (message.folder==0) fprintf(stdout, _("(read)\n")); //GST_INBOX
2244                                   else fprintf(stdout, _("(sent)\n"));
2245                 break;
2246             case  GSS_NOTSENTREAD:
2247                 if (message.folder==0) fprintf(stdout, _("(unread)\n")); //GST_INBOX
2248                                   else fprintf(stdout, _("(not sent)\n"));
2249                 break;
2250             case  GSS_UNKNOWN:
2251                 fprintf(stdout, _("(not known :-()\n"));
2252                 break;
2253             case  GSS_TEMPLATE:
2254                 fprintf(stdout, _("(template)\n"));
2255                 break;
2256             default:
2257                 fprintf(stdout, _("(unknown: %d)\n"),message.Status);
2258                 break;
2259            }
2260          
2261           /* RTH FIXME: date for other status ok ? */ 
2262           if (message.SMSData) {
2263
2264             fprintf(stdout, _("Date/time: %s %02d/%02d/%02d %d:%02d:%02d "), \
2265                     DayOfWeek(message.Time.Year, message.Time.Month, message.Time.Day), \
2266                     message.Time.Day, message.Time.Month, message.Time.Year, \
2267                     message.Time.Hour, message.Time.Minute, message.Time.Second);
2268
2269             if (message.Time.Timezone) {
2270               if (message.Time.Timezone > 0)
2271                 fprintf(stdout,_("+%02d00"),message.Time.Timezone);
2272               else
2273                 fprintf(stdout,_("%02d00"),message.Time.Timezone);
2274             }
2275
2276             fprintf(stdout, "\n");
2277
2278             fprintf(stdout, _("Msg Center: %s "), message.MessageCenter.Number);
2279             
2280             if (message.ReplyViaSameSMSC)
2281               fprintf(stdout, _("(centre set for reply) "));
2282           }
2283
2284           if (strcmp(message.Sender,"")) {
2285             if (message.folder==1) { //GST_OUTBOX
2286               fprintf(stdout, _("Recipient: %s"),message.Sender);
2287             } else {
2288               fprintf(stdout, _("Sender: %s"),message.Sender);
2289             }
2290           }
2291
2292           if (strcmp(message.Sender,"") || message.folder==0)
2293             fprintf(stdout, "\n");
2294             
2295           switch (message.UDHType) {
2296
2297           case GSM_OpLogo:
2298
2299             /* put bitmap into bitmap structure */
2300             switch (GSM_ReadBitmap(&message, &bitmap)) {
2301               case GE_INVALIDIMAGESIZE:
2302                 fprintf(stdout,_("Image size not supported\n"));
2303                 break;
2304               case GE_NONE:
2305                 fprintf(stdout, _("GSM operator logo for %s (%s) network.\n"), bitmap.netcode, GSM_GetNetworkName(bitmap.netcode));         
2306             
2307                 GSM_PrintBitmap(&bitmap);
2308
2309                 if (filename[0]!=0) {
2310                   GSM_SaveBitmapFileOnConsole(filename, &bitmap);
2311                 }
2312
2313                 break;
2314               default:
2315                 fprintf(stdout,_("Error reading image\n"));  
2316                 break;
2317             }
2318
2319 #ifdef DEBUG
2320             if (message.folder==0) { //GST_INBOX
2321               if (!strcmp(message.Sender, "+998000005") &&
2322                   !strcmp(message.MessageCenter.Number, "+886935074443") &&
2323                   message.Time.Day==27 &&
2324                   message.Time.Month==7 &&
2325                   message.Time.Year==99 &&
2326                   message.Time.Hour==0 &&
2327                   message.Time.Minute==10 &&
2328                   message.Time.Second==48) fprintf(stdout, _("Saved by Logo Express\n"));
2329
2330               /* Is it changed in next versions ? Or what ? */
2331               if (!strcmp(message.Sender, "+998000002") ||
2332                   !strcmp(message.Sender, "+998000003") ||
2333                   !strcmp(message.Sender, "+998000004")) fprintf(stdout, _("Saved by Operator Logo Uploader by Thomas Kessler\n"));
2334             } else {
2335               if (!strcmp(message.Sender, "+8861234567890") &&
2336                   !strcmp(message.MessageCenter.Number, "+886935074443")) fprintf(stdout, _("Saved by Logo Express\n"));
2337             }
2338             if (!strncmp(message.Sender, "OpLogo",6) &&
2339                 strlen(message.Sender)==11)
2340               fprintf(stdout, _("Saved by gnokii\n"));          
2341 #endif
2342
2343             break;
2344
2345           case GSM_WAPBookmarkUDH:
2346
2347             /* put bookmark into bookmark structure */
2348             switch (GSM_ReadWAPBookmark(&message, &bookmark)) {
2349               case GE_NONE:
2350                 fprintf(stdout, ("WAP Bookmark\n"));
2351
2352                 fprintf(stdout,_("Address: \"%s\"\n"),bookmark.address);
2353
2354                 if (bookmark.title[0]==0)
2355                   fprintf(stdout,_("Title: \"%s\"\n"),bookmark.address);
2356                 else
2357                   fprintf(stdout,_("Title: \"%s\"\n"),bookmark.title);
2358
2359                 break;
2360               default:
2361                 fprintf(stdout,_("Error reading WAP Bookmark\n"));  
2362                 break;
2363             }
2364
2365 #ifdef DEBUG
2366             if (!strcmp(message.Sender, "WAPBookmark"))
2367               fprintf(stdout, _("Saved by gnokii\n"));          
2368 #endif
2369
2370             break;
2371
2372           case GSM_CallerIDLogo:
2373
2374             /* put bitmap into bitmap structure */
2375             switch (GSM_ReadBitmap(&message, &bitmap)) {
2376               case GE_INVALIDIMAGESIZE:
2377                 fprintf(stdout,_("Image size not supported\n"));
2378                 break;
2379               case GE_NONE:
2380                 fprintf(stdout, ("Caller Logo\n"));
2381             
2382                 GSM_PrintBitmap(&bitmap);
2383
2384                 if (filename[0]!=0) {
2385                   GSM_SaveBitmapFileOnConsole(filename, &bitmap);
2386                 }
2387
2388                 break;
2389               default:
2390                 fprintf(stdout,_("Error reading image\n"));  
2391                 break;
2392             }
2393
2394 #ifdef DEBUG
2395             if (message.folder==0) { //GST_INBOX
2396               if (!strcmp(message.Sender, "+998000005") &&
2397                   !strcmp(message.MessageCenter.Number, "+886935074443") &&
2398                   message.Time.Day==27 &&
2399                   message.Time.Month==7 &&
2400                   message.Time.Year==99 &&
2401                   message.Time.Hour==0 &&
2402                   message.Time.Minute==10 &&
2403                   message.Time.Second==48) fprintf(stdout, _("Saved by Logo Express\n"));
2404             } else {
2405               if (!strcmp(message.Sender, "+8861234567890") &&
2406                   !strcmp(message.MessageCenter.Number, "+886935074443")) fprintf(stdout, _("Saved by Logo Express\n"));
2407             }
2408             if (!strcmp(message.Sender, "GroupLogo"))
2409               fprintf(stdout, _("Saved by gnokii\n"));          
2410 #endif
2411
2412             break;
2413
2414           case GSM_ProfileUDH:
2415                 fprintf(stdout, ("Profile SMS, part %i/%i\n"),message.UDH[11],message.UDH[10]);
2416                 break;
2417
2418           case GSM_WAPBookmarkUDHLong:
2419                 fprintf(stdout, ("WAP Bookmark, part %i/%i\n"),message.UDH[11],message.UDH[10]);
2420                 break;
2421
2422           case GSM_WAPSettingsUDH:
2423                 fprintf(stdout, ("WAP Settings, part %i/%i\n"),message.UDH[11],message.UDH[10]);
2424                 break;
2425           
2426           case GSM_RingtoneUDH:
2427
2428             /* put ringtone into ringtone structure */
2429             switch (GSM_ReadRingtone(&message, &ringtone)) {
2430               case GE_NONE:
2431
2432                 fprintf(stdout, ("Ringtone \"%s\"\n"),ringtone.name);
2433
2434                 while (confirm < 0) {
2435                   fprintf(stderr, _("Do you want to play it ? (yes/no) "));
2436                   GetLine(stdin, ans, 7);
2437                   if (!strcmp(ans, "yes")) confirm = 1;
2438                   if (!strcmp(ans, "no")) confirm = 0;
2439                 }  
2440
2441                 if (confirm==1) GSM_PlayRingtoneOnConsole(&ringtone);
2442                 
2443                 if (filename[0]!=0) GSM_SaveRingtoneFileOnConsole(filename, &ringtone);
2444                 
2445                 break;
2446                 
2447               default:
2448                 fprintf(stdout,_("Gnokii can't read this ringtone - there is probably error inside\n"));
2449                 break;
2450             }
2451
2452             break;
2453
2454           case GSM_CalendarNoteUDH:
2455             fprintf(stdout, ("Calendar note SMS, part %i/%i\n"),message.UDH[11],message.UDH[10]);
2456             fprintf(stdout, _("Text:\n%s\n\n"), message.MessageText);
2457             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2458             break;
2459
2460           case GSM_ConcatenatedMessages:
2461             fprintf(stdout, _("Linked (%d/%d)\nText:\n%s\n\n"),message.UDH[5],message.UDH[4], message.MessageText);
2462             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2463             break;
2464
2465           case GSM_EnableVoice:
2466             fprintf(stdout, _("Enables voice indicator\nText:\n%s\n\n"), message.MessageText);
2467             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2468             break;
2469
2470           case GSM_DisableVoice:
2471             fprintf(stdout, _("Disables voice indicator\nText:\n%s\n\n"), message.MessageText);
2472             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2473             break;
2474
2475           case GSM_EnableFax:
2476             fprintf(stdout, _("Enables fax indicator\nText:\n%s\n\n"), message.MessageText);
2477             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2478             break;
2479
2480           case GSM_DisableFax:
2481             fprintf(stdout, _("Disables fax indicator\nText:\n%s\n\n"), message.MessageText);
2482             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2483             break;
2484
2485           case GSM_EnableEmail:
2486             fprintf(stdout, _("Enables email indicator\nText:\n%s\n\n"), message.MessageText);
2487             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2488             break;
2489
2490           case GSM_DisableEmail:
2491             fprintf(stdout, _("Disables email indicator\nText:\n%s\n\n"), message.MessageText);
2492             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2493             break;
2494
2495           case GSM_VoidSMS:
2496             fprintf(stdout, _("Void SMS\nText:\n%s\n\n"), message.MessageText);
2497             if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2498             break;
2499
2500           case GSM_NoUDH:
2501             if (message.Coding!=GSM_Coding_8bit) {
2502               fprintf(stdout, _("Text:\n%s\n\n"), message.MessageText);
2503               if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
2504             } else {
2505               fprintf(stdout, _("Message cannot be displayed here\n")); // like in phone :-)
2506             }
2507             break;
2508
2509           default:  //GSM_UnknownUDH and other
2510             fprintf(stderr, _("Unknown\n"));
2511           }
2512
2513           break;
2514           
2515         default:
2516           fprintf(stdout,_("Unknown SMS type. Report it\n"));
2517           break;
2518       }
2519
2520       break;
2521
2522     case GE_NOTIMPLEMENTED:
2523
2524       fprintf(stderr, _("Function not implemented in %s model!\n"), model);
2525       GSM->Terminate();
2526       return -1;        
2527
2528     case GE_INVALIDSMSLOCATION:
2529
2530       fprintf(stderr, _("Invalid location: %s %d\n"), memory_type_string, count);
2531
2532       break;
2533
2534     case GE_EMPTYSMSLOCATION:
2535
2536       fprintf(stderr, _("SMS location %s %d empty.\n"), memory_type_string, count);
2537
2538       break;
2539
2540     case GE_NOACCESS:
2541
2542       fprintf(stderr, _("No access to %s memory.\n"), memory_type_string);
2543
2544       break;
2545
2546     default:
2547
2548       fprintf(stderr, _("GetSMS %s %d failed!(%d)\n\n"), memory_type_string, count, error);
2549     }
2550   }
2551
2552   GSM->Terminate();
2553
2554   return 0;
2555 }
2556
2557 int getsmsstatus(int argc, char *argv[])
2558 {
2559   GSM_SMSStatus SMSStatus;
2560   GSM_SMSFolders folders;
2561   GSM_Error error;
2562   GSM_SMSMessage SMS;
2563
2564   int i,j;
2565
2566   /* Initialise the code for the GSM interface. */     
2567   fbusinit(NULL);
2568
2569   error = GSM->GetSMSStatus(&SMSStatus);
2570   if (error!=GE_NONE) return error;
2571
2572   fprintf(stdout, _("SMS Messages: UnRead %d, Number %d\n"),SMSStatus.UnRead, SMSStatus.Number);
2573
2574   error=GSM->GetSMSFolders(&folders);  
2575   if (error!=GE_NONE) return error;
2576
2577   /* For not 7110 compatible phones we have to read all SMS and prepare sms table */
2578   if( GetModelFeature (FN_SMS)!=F_SMS71 )
2579   {
2580     i=1;j=0;
2581     while (true) {
2582       if (j==SMSStatus.Number) break;
2583       SMS.Location=i;
2584       if (GSM->GetSMSMessage(&SMS)==GE_NONE) {
2585         SMSStatus.foldertable[j].smsnum=i;
2586
2587         /* We set such folders ID like in 7110 compatible phones */
2588         if (SMS.Status==GSS_NOTSENTREAD && SMS.folder==0) //GST_INBOX
2589           SMSStatus.foldertable[j].folder=0;
2590         else {
2591           switch (SMS.folder) {
2592             case 0://GST_INBOX
2593               SMSStatus.foldertable[j].folder=GST_7110_INBOX;
2594               break;
2595             case 1://GST_OUTBOX
2596               SMSStatus.foldertable[j].folder=GST_7110_OUTBOX;
2597               break;
2598           }
2599         }
2600         j++;
2601       }
2602       i++;
2603     }
2604   }
2605
2606   printf("0.Unread         : ");
2607   for(j=0; j<SMSStatus.Number; j++)
2608   {
2609     if (SMSStatus.foldertable[j].folder == 0)
2610       printf("%d ",SMSStatus.foldertable[j].smsnum);
2611   }
2612   printf("\n");
2613
2614   for (i=0;i<folders.number;i++) {
2615     fprintf(stdout,_("%d.%-15s: "),i+1,folders.Folder[i].Name);
2616     for(j=0; j<SMSStatus.Number; j++)
2617     {
2618       if ( SMSStatus.foldertable[j].folder / 8 == i+1)
2619         printf("%d ",SMSStatus.foldertable[j].smsnum);
2620     }
2621     printf("\n");
2622   }
2623
2624   GSM->Terminate();
2625
2626   return 0;
2627 }
2628
2629 /* Delete SMS messages. */
2630 int deletesms(int argc, char *argv[])
2631 {
2632
2633   GSM_SMSMessage message;
2634   char memory_type_string[20];
2635   int start_message, end_message, count;
2636   GSM_Error error;
2637
2638   /* Handle command line args that set type, start and end locations. */
2639   if (!GetMemoryTypeID(argv[0], &message.MemoryType))
2640   {
2641     fprintf(stderr, _("Unknown memory type %s!\n"), argv[0]);
2642     return (-1);
2643   }
2644   GetMemoryTypeString(memory_type_string, &message.MemoryType);
2645
2646   start_message = atoi (argv[1]);
2647   if (argc > 2) end_message = atoi (argv[2]);
2648   else end_message = start_message;
2649
2650   /* Initialise the code for the GSM interface. */     
2651
2652   fbusinit(NULL);
2653
2654   /* Now delete the requested entries. */
2655
2656   for (count = start_message; count <= end_message; count ++) {
2657
2658     message.Location = count;
2659
2660     error = GSM->DeleteSMSMessage(&message);
2661
2662     if (error == GE_NONE)
2663       fprintf(stdout, _("Deleted SMS %s %d\n"), memory_type_string, count);
2664     else {
2665       if (error == GE_NOTIMPLEMENTED) {
2666         fprintf(stderr, _("Function not implemented in %s model!\n"), model);
2667         GSM->Terminate();
2668         return -1;      
2669       }
2670       fprintf(stdout, _("DeleteSMS %s %d failed!(%d)\n\n"), memory_type_string, count, error);
2671     }
2672   }
2673
2674   GSM->Terminate();
2675
2676   return 0;
2677 }
2678
2679 static volatile bool bshutdown = false;
2680
2681 /* SIGINT signal handler. */
2682
2683 static void interrupted(int sig)
2684 {
2685
2686   signal(sig, SIG_IGN);
2687   bshutdown = true;
2688
2689 }
2690
2691 #ifdef SECURITY
2692
2693 /* In this mode we get the code from the keyboard and send it to the mobile
2694    phone. */
2695
2696 int entersecuritycode(char *type)
2697 {
2698   GSM_Error test;
2699   GSM_SecurityCode SecurityCode;
2700
2701   if (!strcmp(type,"PIN"))      SecurityCode.Type=GSCT_Pin;
2702   else if (!strcmp(type,"PUK")) SecurityCode.Type=GSCT_Puk;
2703   else if (!strcmp(type,"PIN2"))SecurityCode.Type=GSCT_Pin2;
2704   else if (!strcmp(type,"PUK2"))SecurityCode.Type=GSCT_Puk2;
2705
2706   // FIXME: Entering of SecurityCode does not work :-(
2707   //  else if (!strcmp(type,"SecurityCode"))
2708   //    SecurityCode.Type=GSCT_SecurityCode;
2709
2710   else {
2711     fprintf(stdout, _("Wrong code in second parameter (allowed: PIN,PUK,PIN2,PUK2,SecurityCode)\n"));
2712     return -1;
2713   }
2714
2715 #ifdef WIN32
2716   printf("Enter your code: ");
2717   gets(SecurityCode.Code);
2718 #else
2719   strcpy(SecurityCode.Code,getpass(_("Enter your code: ")));
2720 #endif
2721
2722   fbusinit(NULL);
2723
2724   test = GSM->EnterSecurityCode(SecurityCode);
2725   if (test==GE_NONE)
2726     fprintf(stdout,_("Code OK !\n"));
2727   else
2728     fprintf(stderr,_("%s\n"),print_error(test));
2729
2730   GSM->Terminate();
2731
2732   return 0;
2733 }
2734
2735 int getsecuritycodestatus(void)
2736 {
2737
2738   int Status;
2739
2740   fbusinit(NULL);
2741
2742   if (GSM->GetSecurityCodeStatus(&Status) == GE_NONE) {
2743
2744     fprintf(stdout, _("Security code status: "));
2745
2746       switch(Status) {
2747       case GSCT_SecurityCode:fprintf(stdout, _("waiting for Security Code.\n"));break;
2748       case GSCT_Pin:         fprintf(stdout, _("waiting for PIN.\n"));          break;
2749       case GSCT_Pin2:        fprintf(stdout, _("waiting for PIN2.\n"));         break;
2750       case GSCT_Puk:         fprintf(stdout, _("waiting for PUK.\n"));          break;
2751       case GSCT_Puk2:        fprintf(stdout, _("waiting for PUK2.\n"));         break;
2752       case GSCT_None:        fprintf(stdout, _("nothing to enter.\n"));         break;
2753       default:               fprintf(stdout, _("Unknown!\n"));
2754       }
2755   }
2756
2757   GSM->Terminate();
2758
2759   return 0;
2760 }
2761
2762 int getsecuritycode(char *type)
2763 {
2764
2765   GSM_SecurityCode SecurityCode;
2766   GSM_Error error;
2767
2768   if (!strcmp(type,"PIN"))              SecurityCode.Type=GSCT_Pin;
2769   else if (!strcmp(type,"PUK"))         SecurityCode.Type=GSCT_Puk;
2770   else if (!strcmp(type,"PIN2"))        SecurityCode.Type=GSCT_Pin2;
2771   else if (!strcmp(type,"PUK2"))        SecurityCode.Type=GSCT_Puk2;
2772   else if (!strcmp(type,"SecurityCode"))SecurityCode.Type=GSCT_SecurityCode;
2773   else {
2774     fprintf(stdout, _("Wrong code in second parameter (allowed: PIN,PUK,PIN2,PUK2,SecurityCode)\n"));
2775     return -1;
2776   }
2777     
2778   fbusinit(NULL);
2779
2780   error=GSM->GetSecurityCode(&SecurityCode);
2781   
2782   switch (error) {
2783     case GE_INVALIDSECURITYCODE:
2784       fprintf(stdout, _("Error: getting "));
2785       switch (SecurityCode.Type) {
2786         case GSCT_SecurityCode:fprintf(stdout, _("security code"));break;
2787         case GSCT_Pin :fprintf(stdout, _("PIN"));break;
2788         case GSCT_Pin2:fprintf(stdout, _("PIN2"));break;
2789         case GSCT_Puk :fprintf(stdout, _("PUK"));break;
2790         case GSCT_Puk2:fprintf(stdout, _("PUK2"));break;
2791         default:break;
2792       }
2793       fprintf(stdout, _(" not allowed\n"));
2794       break;
2795     case GE_NONE:
2796       switch (SecurityCode.Type) {
2797         case GSCT_SecurityCode:fprintf(stdout, _("Security code"));break;
2798         case GSCT_Pin :fprintf(stdout, _("PIN"));break;
2799         case GSCT_Pin2:fprintf(stdout, _("PIN2"));break;
2800         case GSCT_Puk :fprintf(stdout, _("PUK"));break;
2801         case GSCT_Puk2:fprintf(stdout, _("PUK2"));break;
2802         default:break;
2803       }
2804       fprintf(stdout, _(" is %s\n"),SecurityCode.Code);
2805       break;
2806     default:
2807       fprintf(stderr, _("%s\n"),print_error(error));
2808       break;
2809   }
2810
2811   GSM->Terminate();
2812
2813   return 0;
2814 }
2815
2816 #endif
2817
2818 /* Voice dialing mode. */
2819
2820 int dialvoice(char *Number)
2821 {
2822   fbusinit(NULL);
2823
2824   if (GSM->DialVoice(Number)!=GE_NONE) fprintf(stdout,_("Error!\n"));
2825
2826   GSM->Terminate();
2827
2828   return 0;
2829 }
2830
2831 /* Cancel a call */
2832 int cancelcall(void)
2833 {
2834   fbusinit(NULL);
2835
2836   if (GSM->CancelCall()!=GE_NONE) fprintf(stdout,_("Error!\n"));
2837
2838   GSM->Terminate();
2839
2840   return 0;
2841 }
2842
2843 int savelogo(int argc, char *argv[])
2844 {
2845   GSM_Bitmap bitmap;
2846   GSM_NetworkInfo NetworkInfo;
2847   GSM_MultiSMSMessage MultiSMS;
2848
2849   /* Operator logos will be saved with this number */  
2850   char oplogonumber[]={'O','p','L','o','g','o',
2851                        '0','0','0','0','0',   /* MMC+MNC */
2852                        '\0'};
2853   int i=0;
2854   
2855   bool UnicodeText=false;
2856
2857   /* The first argument is the type of the logo. */
2858   if (!strcmp(argv[0], "op")) {
2859     fprintf(stdout, _("Saving operator logo.\n"));
2860   } else if (!strcmp(argv[0], "caller")) {
2861     fprintf(stdout, _("Saving caller line identification logo.\n"));
2862   } else if (!strcmp(argv[0], "startup")) {
2863     fprintf(stderr, _("It isn't possible to save startup logo!\n"));
2864     return (-1);
2865   } else if (!strcmp(argv[0], "7110startup")) {
2866     fprintf(stderr, _("It isn't possible to save startup logo!\n"));
2867     return (-1);
2868   } else if (!strcmp(argv[0], "6210startup")) {
2869     fprintf(stderr, _("It isn't possible to save startup logo!\n"));
2870     return (-1);
2871   } else if (!strcmp(argv[0], "7110op")) {
2872     fprintf(stderr, _("It isn't possible to save big operator logos!\n"));
2873     return (-1);
2874   } else if (!strcmp(argv[0], "picture")) {
2875     fprintf(stderr, _("Saving picture image.\n"));
2876   } else if (!strcmp(argv[0], "screensaver")) {
2877     fprintf(stderr, _("Saving screen saver.\n"));
2878   } else {
2879     fprintf(stderr, _("You should specify what kind of logo to save!\n"));
2880     return (-1);
2881   }
2882
2883   /* The second argument is the bitmap file. */
2884   if (GSM_ReadBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) return -1;
2885
2886   /* Initialise the GSM interface. */
2887   fbusinit(NULL);
2888
2889   /* We check optional parameters from 2'rd */
2890   optind = 2;
2891
2892   if (!strcmp(argv[0], "op")) {
2893     GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
2894   
2895     /* The third argument, if present, is the Network code of the operator.
2896      * Network code is in this format: "xxx yy" */
2897     if (argc > 2) {
2898       strcpy(bitmap.netcode, argv[2]);
2899 #ifdef DEBUG
2900       fprintf(stdout, _("Operator code: %s\n"), argv[2]);
2901 #endif
2902       if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown")) {
2903         fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
2904         GSM->Terminate();
2905         return -1;
2906       }
2907       optind++;
2908     } else
2909     {
2910       if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
2911     }
2912     bitmap.type=GSM_OperatorLogo;
2913
2914     /* Put bitmap into SMS structure */
2915     GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,false,false);
2916
2917     oplogonumber[6]=bitmap.netcode[0];
2918     oplogonumber[7]=bitmap.netcode[1];
2919     oplogonumber[8]=bitmap.netcode[2];
2920     oplogonumber[9]=bitmap.netcode[4];
2921     oplogonumber[10]=bitmap.netcode[5];
2922     for(i=0;i<MultiSMS.number;i++)
2923       strcpy(MultiSMS.SMS[i].Destination,oplogonumber);
2924   }
2925   if (!strcmp(argv[0], "caller")) {
2926     GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
2927   
2928     bitmap.type=GSM_CallerLogo;
2929
2930     /* Put bitmap into SMS structure */
2931     GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,false,false);
2932
2933     for(i=0;i<MultiSMS.number;i++)
2934       strcpy(MultiSMS.SMS[i].Destination,"GroupLogo");
2935   }
2936   if (!strcmp(argv[0], "screensaver")) {
2937     GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
2938
2939     bitmap.text[0]=0;
2940
2941     for(i=0;i<argc;i++)
2942       if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
2943
2944     /* Put bitmap into SMS structure */
2945     GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,true,UnicodeText);
2946
2947     for(i=0;i<MultiSMS.number;i++)
2948       strcpy(MultiSMS.SMS[i].Destination,"ScreenSaver");
2949   }
2950   if (!strcmp(argv[0], "picture")) {  
2951     GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
2952
2953     for(i=0;i<argc;i++)
2954       if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
2955
2956     bitmap.text[0]=0;
2957     if (argc>2) {
2958       optind++;
2959       if (strlen(argv[2])>121) {
2960         fprintf(stdout,_("Sorry: length of text (parameter \"%s\") can be 121 chars or shorter only !\n"),argv[2]);
2961         return -1;
2962       }
2963       strcpy(bitmap.text,argv[2]);
2964     }
2965     
2966     /* Put bitmap into SMS structure */
2967     GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,false,UnicodeText);
2968
2969     for(i=0;i<MultiSMS.number;i++)
2970       strcpy(MultiSMS.SMS[i].Destination,"Picture");
2971   }
2972
2973   GSM_SaveMultiPartSMSOnConsole(&MultiSMS, optind,argc,argv,false,true,false,false);
2974   
2975   return i;
2976 }
2977
2978 /* The following function allows to send logos using SMS */
2979 int sendlogo(int argc, char *argv[])
2980 {
2981   GSM_Bitmap bitmap;
2982   GSM_NetworkInfo NetworkInfo;
2983   GSM_MultiSMSMessage MultiSMS;
2984
2985   int i;
2986
2987   bool UnicodeText=false;
2988   bool ScreenSaver=false;
2989
2990   /* The first argument is the type of the logo. */
2991   if (!strcmp(argv[0], "op")) {
2992     fprintf(stdout, _("Sending operator logo.\n"));
2993   } else if (!strcmp(argv[0], "caller")) {
2994     fprintf(stdout, _("Sending caller line identification logo.\n"));
2995   } else if (!strcmp(argv[0], "picture")) {
2996     fprintf(stdout, _("Sending picture image.\n"));
2997   } else if (!strcmp(argv[0], "screensaver")) {
2998     fprintf(stdout, _("Sending screen saver.\n"));
2999   } else if (!strcmp(argv[0], "startup")) {
3000     fprintf(stderr, _("It isn't possible to send startup logo!\n"));
3001     return (-1);
3002   } else if (!strcmp(argv[0], "7110startup")) {
3003     fprintf(stderr, _("It isn't possible to send startup logo!\n"));
3004     return (-1);
3005   } else if (!strcmp(argv[0], "6210startup")) {
3006     fprintf(stderr, _("It isn't possible to send startup logo!\n"));
3007     return (-1);
3008   } else if (!strcmp(argv[0], "7110op")) {
3009     fprintf(stderr, _("It isn't possible to send big operator logos!\n"));
3010     return (-1);
3011   } else {
3012     fprintf(stderr, _("You should specify what kind of logo to send!\n"));
3013     return (-1);
3014   }
3015
3016   /* The third argument is the bitmap file. */
3017   if (GSM_ReadBitmapFileOnConsole(argv[2], &bitmap)!=GE_NONE) return -1;
3018
3019   /* Initialise the GSM interface. */
3020   fbusinit(NULL);
3021
3022   optind = 3;
3023
3024   if (!strcmp(argv[0], "op")) {
3025     GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
3026   
3027     /* The third argument, if present, is the Network code of the operator.
3028      * Network code is in this format: "xxx yy" */
3029     if (argc > 3) {
3030       strcpy(bitmap.netcode, argv[3]);
3031 #ifdef DEBUG
3032       fprintf(stdout, _("Operator code: %s\n"), argv[3]);
3033 #endif
3034       if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown")) {
3035         fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
3036         GSM->Terminate();
3037         return -1;
3038       }
3039       optind++;
3040     } else
3041     {
3042       if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
3043     }
3044     bitmap.type=GSM_OperatorLogo;
3045   }
3046   if (!strcmp(argv[0], "caller")) {
3047     GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
3048   
3049     bitmap.type=GSM_CallerLogo;
3050   }
3051   if (!strcmp(argv[0], "screensaver")) {
3052     GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
3053
3054     bitmap.text[0]=0;
3055
3056     for(i=0;i<argc;i++)
3057       if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
3058     
3059     ScreenSaver=true;
3060   }
3061   if (!strcmp(argv[0], "picture")) {  
3062     GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
3063
3064     for(i=0;i<argc;i++)
3065       if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
3066
3067     bitmap.text[0]=0;
3068     if (argc>3) {
3069       optind++;
3070       if (strlen(argv[3])>121) {
3071         fprintf(stdout,_("Sorry: length of text (parameter \"%s\") can be 121 chars or shorter only !\n"),argv[3]);
3072         return -1;
3073       }
3074       strcpy(bitmap.text,argv[3]);
3075     }
3076   }
3077
3078   /* Put bitmap into SMS structure */
3079   GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,ScreenSaver,UnicodeText);
3080
3081   /* The second argument is the destination, ie the phone number of recipient. */
3082   for(i=0;i<MultiSMS.number;i++)
3083     strcpy(MultiSMS.SMS[i].Destination,argv[1]);
3084
3085   GSM_SendMultiPartSMSOnConsole(&MultiSMS, optind,argc,argv,true,false,false);
3086
3087   return i;
3088 }
3089
3090 /* Getting logos. */
3091
3092 int getlogo(int argc, char *argv[])
3093 {
3094   GSM_Bitmap bitmap;
3095   GSM_Error error;
3096   int num;
3097
3098   bitmap.type=GSM_None;
3099
3100   if (!strcmp(argv[0],"7110op"))
3101     bitmap.type=GSM_7110OperatorLogo;
3102     
3103   if (!strcmp(argv[0],"op"))
3104     bitmap.type=GSM_OperatorLogo;
3105     
3106   if (!strcmp(argv[0],"caller")) {
3107     /* There is caller group number missing in argument list. */
3108     if (argc==3) {     
3109       num=argv[2][0]-'0';
3110       if ((num<1)||(num>9)) num=1;
3111       bitmap.number=num;
3112     } else
3113     {
3114       bitmap.number=1;
3115     }
3116     bitmap.number--;
3117     bitmap.type=GSM_CallerLogo;
3118   }
3119
3120   if (!strcmp(argv[0],"picture")) {
3121     /* There is a number missing in argument list. */
3122     if (argc==3) {     
3123       if (strlen(argv[2])==2) {
3124         num=(argv[2][0]-'0')*10+(argv[2][1]-'0');
3125       } else {
3126         num=argv[2][0]-'0';
3127       }
3128       if (num<1) num=1;
3129       bitmap.number=num;
3130     } else
3131     {
3132       bitmap.number=1;
3133     }
3134     bitmap.number--;
3135     bitmap.type=GSM_PictureImage;
3136   }    
3137
3138   if (!strcmp(argv[0],"startup"))
3139     bitmap.type=GSM_StartupLogo;
3140
3141   if (!strcmp(argv[0],"7110startup"))
3142     bitmap.type=GSM_7110StartupLogo;
3143
3144   if (!strcmp(argv[0],"6210startup"))
3145     bitmap.type=GSM_6210StartupLogo;
3146     
3147   if (!strcmp(argv[0],"dealer"))
3148     bitmap.type=GSM_DealerNoteText;  
3149     
3150   if (!strcmp(argv[0],"text"))
3151     bitmap.type=GSM_WelcomeNoteText;  
3152
3153   if (bitmap.type!=GSM_None) {
3154   
3155     fbusinit(NULL);
3156     
3157     fprintf(stdout, _("Getting Logo\n"));
3158         
3159     error=GSM->GetBitmap(&bitmap);
3160
3161     GSM->Terminate();
3162     
3163     switch (error)
3164     {
3165       case GE_NONE:
3166         if (bitmap.type==GSM_DealerNoteText) fprintf(stdout, _("Dealer welcome note "));
3167         if (bitmap.type==GSM_WelcomeNoteText) fprintf(stdout, _("Welcome note "));      
3168         if (bitmap.type==GSM_DealerNoteText || bitmap.type==GSM_WelcomeNoteText)
3169         {
3170           if (bitmap.text[0]!=0)
3171           {
3172             fprintf(stdout, _("currently set to \"%s\"\n"), bitmap.text);
3173           } else {
3174             fprintf(stdout, _("currently empty\n"));
3175           }
3176         } else
3177         {
3178           if (bitmap.width!=0)
3179           {
3180             if (bitmap.type==GSM_OperatorLogo || bitmap.type==GSM_7110OperatorLogo)
3181             {
3182               fprintf(stdout,"Operator logo for %s (%s) network got succesfully\n",bitmap.netcode,GSM_GetNetworkName(bitmap.netcode));
3183             }
3184             if (bitmap.type==GSM_StartupLogo || bitmap.type==GSM_7110StartupLogo || bitmap.type==GSM_6210StartupLogo)
3185             {
3186               fprintf(stdout,"Startup logo got successfully\n");
3187             }
3188             if (bitmap.type==GSM_CallerLogo)
3189             {
3190               fprintf(stdout,"Caller logo got successfully\n");
3191             }
3192             if (bitmap.type==GSM_PictureImage)
3193             {
3194               fprintf(stdout,"Picture Image got successfully");
3195               if (strcmp(bitmap.text,""))
3196                 fprintf(stdout,_(", text \"%s\""),bitmap.text);         
3197               if (strcmp(bitmap.Sender,""))
3198                 fprintf(stdout,_(", sender \"%s\""),bitmap.Sender);             
3199               fprintf(stdout,"\n");
3200             }
3201             if (argc>1)
3202             {
3203               if (GSM_SaveBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) return(-1);
3204             }
3205           } else
3206           {
3207             fprintf(stdout,"Your phone doesn't have logo uploaded !\n");
3208             return -1;
3209           }
3210         }
3211         break;
3212       case GE_NOTIMPLEMENTED:
3213         fprintf(stderr, _("Function not implemented !\n"));
3214         return -1;
3215       case GE_NOTSUPPORTED:
3216         fprintf(stderr, _("This kind of logo is not supported !\n"));
3217         return -1;
3218       default:
3219         fprintf(stderr, _("Error getting logo (wrong location ?) !\n"));
3220         return -1;
3221     }
3222   } else
3223   {
3224     fprintf(stderr, _("What kind of logo do you want to get ?\n"));
3225     return -1;
3226   }
3227
3228   return 0;
3229 }
3230
3231 /* Setting logos. */
3232
3233 int setlogo(int argc, char *argv[])
3234 {
3235
3236   GSM_Bitmap bitmap,oldbit;
3237   GSM_NetworkInfo NetworkInfo;
3238   GSM_Error error;
3239   char model[64];
3240   int num;
3241   
3242   bool ok=true;
3243   
3244   int i;
3245   
3246   fbusinit(NULL);
3247   
3248   if (!strcmp(argv[0],"text") || !strcmp(argv[0],"dealer"))
3249   {
3250     if (!strcmp(argv[0],"text")) bitmap.type=GSM_WelcomeNoteText;
3251                             else bitmap.type=GSM_DealerNoteText;
3252     bitmap.text[0]=0x00;
3253     if (argc>1) strncpy(bitmap.text,argv[1],255);
3254   } else
3255   {
3256     if (!strcmp(argv[0],"op") || !strcmp(argv[0],"startup") || !strcmp(argv[0],"caller") ||
3257         !strcmp(argv[0],"7110op") || !strcmp(argv[0],"6210startup") || !strcmp(argv[0],"7110startup") ||
3258         !strcmp(argv[0],"picture"))
3259     {
3260       if (argc>1)
3261       {
3262         if (!strcmp(argv[0],"startup"))
3263         {
3264           bitmap.type=GSM_StartupLogo;
3265           bitmap.width=84;
3266           bitmap.height=48;
3267           bitmap.size=GSM_GetBitmapSize(&bitmap);
3268           num=argv[1][0]-'0';
3269           if (num>=1 && num<=3) {
3270             bitmap.number=num;
3271           } else {
3272             if (GSM_ReadBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) {
3273               GSM->Terminate();
3274               return(-1);
3275             }
3276             bitmap.number=0;
3277             GSM_ResizeBitmap(&bitmap,GSM_StartupLogo);
3278           }
3279         } else {
3280           if (GSM_ReadBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) {
3281             GSM->Terminate();
3282             return(-1);
3283           }
3284         }
3285         if (!strcmp(argv[0],"op"))
3286         {
3287           if (bitmap.type!=GSM_OperatorLogo || argc<3)
3288           {
3289             if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
3290           }
3291           GSM_ResizeBitmap(&bitmap,GSM_OperatorLogo);
3292           if (argc==3)
3293           {
3294             strncpy(bitmap.netcode,argv[2],7);
3295             if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown"))
3296             {
3297               fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
3298               return -1;
3299             }
3300           }
3301         }
3302         if (!strcmp(argv[0],"7110op"))
3303         {
3304           if (bitmap.type!=GSM_7110OperatorLogo || argc<3)
3305           {
3306             if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
3307           }
3308           GSM_ResizeBitmap(&bitmap,GSM_7110OperatorLogo);
3309           if (argc==3)
3310           {
3311             strncpy(bitmap.netcode,argv[2],7);
3312             if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown"))
3313             {
3314               fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
3315               return -1;
3316             }
3317           }
3318         }
3319         if (!strcmp(argv[0],"picture"))
3320         {
3321           GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
3322           bitmap.number=1;
3323           if (argc>2)
3324           {
3325             if (strlen(argv[2])==2) {
3326               num=(argv[2][0]-'0')*10+(argv[2][1]-'0');
3327             } else {
3328               num=argv[2][0]-'0';
3329             }
3330             if (num<1) num=1;   
3331             bitmap.number=num;
3332           }
3333           bitmap.number--;
3334           bitmap.text[0]=0;
3335           if (argc>3)
3336             strncpy(bitmap.text,argv[3],121);
3337           strcpy(bitmap.Sender,"\0");
3338           if (argc>4)
3339             strncpy(bitmap.Sender,argv[4],GSM_MAX_SENDER_LENGTH);
3340         }
3341         if (!strcmp(argv[0],"7110startup"))
3342         {
3343           GSM_ResizeBitmap(&bitmap,GSM_7110StartupLogo);
3344         }
3345         if (!strcmp(argv[0],"6210startup"))
3346         {
3347           GSM_ResizeBitmap(&bitmap,GSM_6210StartupLogo);
3348         }
3349         if (!strcmp(argv[0],"caller"))
3350         {
3351           GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
3352           if (argc>2)
3353           {
3354             num=argv[2][0]-'0';
3355             if ((num<0)||(num>9)) num=0;
3356             bitmap.number=num;
3357           } else
3358           {
3359             bitmap.number=0;
3360           }
3361           oldbit.type=GSM_CallerLogo;
3362           oldbit.number=bitmap.number;
3363           if (GSM->GetBitmap(&oldbit)==GE_NONE)
3364           {
3365             /* We have to get the old name and ringtone!! */
3366             bitmap.ringtone=oldbit.ringtone;
3367             strncpy(bitmap.text,oldbit.text,255);
3368           }
3369           if (argc>3) strncpy(bitmap.text,argv[3],255);   
3370         }
3371         fprintf(stdout, _("Setting Logo.\n"));
3372       } else
3373       {
3374         /* FIX ME: is it possible to permanently remove op logo ? */
3375         if (!strcmp(argv[0],"op"))
3376         {
3377           bitmap.type=GSM_OperatorLogo;
3378           strncpy(bitmap.netcode,"000 00",7);
3379           bitmap.width=72;
3380           bitmap.height=14;
3381           bitmap.size=GSM_GetBitmapSize(&bitmap);
3382           GSM_ClearBitmap(&bitmap);
3383         }
3384         if (!strcmp(argv[0],"7110op"))
3385         {
3386           bitmap.type=GSM_7110OperatorLogo;
3387           strncpy(bitmap.netcode,"000 00",7);
3388           bitmap.width=78;
3389           bitmap.height=21;
3390           bitmap.size=GSM_GetBitmapSize(&bitmap);
3391           GSM_ClearBitmap(&bitmap);
3392         }
3393         /* FIX ME: how to remove startup and group logos ? */
3394         fprintf(stdout, _("Removing Logo.\n"));
3395       }  
3396     } else
3397     {
3398       fprintf(stderr, _("What kind of logo do you want to set ?\n"));
3399       GSM->Terminate();
3400       return -1;
3401     }
3402   }
3403     
3404   while (GSM->GetModel(model)  != GE_NONE)
3405     sleep(1);
3406   
3407   /* For Nokia 6110/6130/6150 we use different method of uploading.
3408      Phone will display menu, when received it */
3409   if (!strcmp(model,"NSE-3") || !strcmp(model,"NSK-3") || !strcmp(model,"NSM-1"))
3410   {
3411     if (!strcmp(argv[0],"caller") && argc<3)
3412       bitmap.number=255;
3413     if (!strcmp(argv[0],"op") && argc<3)
3414       bitmap.number=255;
3415   }
3416
3417   error=GSM->SetBitmap(&bitmap);
3418   
3419   switch (error)
3420   {
3421     case GE_NONE: oldbit.type=bitmap.type;
3422                   oldbit.number=bitmap.number;
3423                   if (GSM->GetBitmap(&oldbit)==GE_NONE) {
3424                     if (bitmap.type==GSM_WelcomeNoteText ||
3425                         bitmap.type==GSM_DealerNoteText) {
3426                       if (strcmp(bitmap.text,oldbit.text)) {
3427                         fprintf(stderr, _("Error setting"));
3428                         if (bitmap.type==GSM_DealerNoteText) fprintf(stderr, _(" dealer"));
3429                         fprintf(stderr, _(" welcome note - "));
3430
3431                         /* I know, it looks horrible, but... */
3432                         /* I set it to the short string - if it won't be set */
3433                         /* it means, PIN is required. If it will be correct, previous */
3434                         /* (user) text was too long */
3435
3436                         /* Without it, I could have such thing: */
3437                         /* user set text to very short string (for example, "Marcin") */
3438                         /* then enable phone without PIN and try to set it to the very long (too long for phone) */
3439                         /* string (which start with "Marcin"). If we compare them as only length different, we could think, */
3440                         /* that phone accepts strings 6 chars length only (length of "Marcin") */
3441                         /* When we make it correct, we don't have this mistake */
3442                         
3443                         strcpy(oldbit.text,"!\0");
3444                         GSM->SetBitmap(&oldbit);
3445                         GSM->GetBitmap(&oldbit);
3446                         if (oldbit.text[0]!='!') {
3447                           fprintf(stderr, _("SIM card and PIN is required\n"));
3448                         } else {
3449                           GSM->SetBitmap(&bitmap);
3450                           GSM->GetBitmap(&oldbit);
3451                           fprintf(stderr, _("too long, truncated to \"%s\" (length %i)\n"),oldbit.text,strlen(oldbit.text));
3452                         }
3453                         ok=false;
3454                       }
3455                     } else {
3456                       if (bitmap.type==GSM_StartupLogo) {
3457                         for (i=0;i<oldbit.size;i++) {
3458                           if (oldbit.bitmap[i]!=bitmap.bitmap[i]) {
3459                             fprintf(stderr, _("Error setting startup logo - SIM card and PIN is required\n"));
3460                             ok=false;
3461                             break;
3462                           }
3463                         }
3464                       }
3465                     }
3466                   }
3467                   if (ok) fprintf(stdout, _("Done.\n"));
3468                   break;
3469     case GE_NOTIMPLEMENTED:fprintf(stderr, _("Function not implemented.\n"));
3470                            break;
3471     case GE_NOTSUPPORTED:fprintf(stderr, _("This kind of logo is not supported.\n"));
3472                            break;
3473     default:fprintf(stderr, _("Error (wrong location ?) !\n"));
3474             break;
3475   }
3476   
3477   GSM->Terminate();
3478
3479   return 0;
3480 }
3481
3482 /* Calendar notes receiving. */
3483
3484 int getcalendarnote(int argc, char *argv[])
3485 {
3486   GSM_CalendarNote CalendarNote;
3487   GSM_NotesInfo NotesInfo;
3488   GSM_Error error;
3489   int i;
3490   int vCalVer=0;
3491   bool vInfo=false;
3492   int start, stop;
3493   bool was_note=false;
3494   char z_text[MAX_CALENDAR_TEXT_LENGTH+11];
3495
3496   /* Hopefully is 64 larger as FB38_MAX* / FB61_MAX* */
3497   char model[64];
3498
3499   struct tm *now;
3500   time_t nowh;
3501   GSM_DateTime Date;
3502
3503   nowh=time(NULL);
3504   now=localtime(&nowh);
3505   
3506   Date.Year = now->tm_year;
3507
3508   /* I have 100 (for 2000) Year now :-) */
3509   if (Date.Year>99 && Date.Year<1900) {
3510     Date.Year=Date.Year+1900;
3511   }
3512
3513   start=atoi(argv[0]);  
3514   stop=start;
3515   
3516   switch (argc) {
3517     case 2:
3518       if (!strcmp(argv[argc-1],"-v10")) {
3519         vCalVer=10;
3520       } else {
3521         if (!strcmp(argv[argc-1],"-v30")) {
3522           vCalVer=30;
3523         } else {
3524           stop=atoi(argv[1]);
3525         }
3526       }
3527       break;
3528     case 3:
3529       stop=atoi(argv[1]);
3530       if (!strcmp(argv[argc-1],"-v10")) {
3531         vCalVer=10;
3532       } else {
3533         if (!strcmp(argv[argc-1],"-v30")) {
3534           vCalVer=30;
3535         } else {      
3536           usage();
3537           return -1;
3538         }
3539       }
3540       break;
3541   }
3542
3543   fbusinit(NULL);
3544
3545   while (GSM->GetModel(model)  != GE_NONE)
3546     sleep(1);
3547
3548   if (!strcmp(argv[0],"-s") || !strcmp(argv[0],"--short")) 
3549     vInfo=true;
3550   else if (!isdigit(argv[0][0])) {
3551     usage();
3552     return -1;
3553   }
3554     
3555   error=GSM->GetCalendarNotesInfo(&NotesInfo);
3556   if ( error == GE_NONE ) {
3557      if( NotesInfo.HowMany == 0 ) {
3558          fprintf(stderr, _("Sorry! No Calendar Notes present on phone.\n"));
3559          start=0; stop=(-1); /* This for skipping next 'for' loop ;-> */
3560       }
3561 #ifdef DEBUG
3562       fprintf(stdout, _(" CALENDAR NOTES INFO \n"));
3563       fprintf(stdout, _("---------------------\n"));
3564       fprintf(stdout, _("How Many Locations :%d\n"), NotesInfo.HowMany);
3565
3566       /* For 6210 (NPE-3) and 7110 (NSE-5), Locations have a different behaviour */
3567       if ( GetModelFeature (FN_CALENDAR)==F_CAL71 ) {
3568         fprintf(stdout, _("Locations are :\n"));
3569         for(i=0;i<NotesInfo.HowMany;i++)
3570             fprintf(stdout, _("%4d) %4d\n"), i+1, NotesInfo.Location[i]);
3571       }
3572 #endif
3573   } else {
3574       /* For 6210 (NPE-3) and 7110 (NSE-5), Locations have a different behaviour */
3575       if ( GetModelFeature (FN_CALENDAR)==F_CAL71 ) {
3576         fprintf(stderr, _("Can't read Notes Infos from phone.\n"));
3577         start=0; stop=(-1); /* This for skipping next 'for' loop ;-> */
3578       }
3579   }
3580
3581   if (GetModelFeature (FN_CALENDAR)!=F_CAL71) {
3582     error=GE_NONE;
3583     NotesInfo.HowMany=200;
3584     for (i=0;i<200;i++) {
3585       NotesInfo.Location[i]=i+1;
3586     }
3587   }
3588   
3589   if( vInfo && stop!=(-1) && error==GE_NONE )
3590   {
3591     /* Info datas (for 7110 and comp.) */
3592     fprintf(stdout, _(" CALENDAR NOTES SUMMARY INFORMATION \n"));
3593     fprintf(stdout, _(" ==================================\n"));
3594     if (GetModelFeature (FN_CALENDAR)==F_CAL71) {
3595       fprintf(stdout, _("Calendar notes present on phone: %d\n"), NotesInfo.HowMany);
3596       fprintf(stdout, _("Locations are :\n"));
3597     }
3598     fprintf(stdout,  "----------------------------------------------------------------------------\n");
3599     fprintf(stdout,_(" Loc Phys Type    Summary description              Dt start    Alarm  Recurs\n") );
3600     fprintf(stdout,  "----------------------------------------------------------------------------\n");
3601
3602     for(i=0;i<NotesInfo.HowMany;i++)
3603     {
3604       /* very short format ... */
3605       /*
3606       fprintf(stdout, _("%4d) %4d\n"), i, NotesInfo.Location[i]);
3607       */
3608       CalendarNote.Location=i+1;
3609       CalendarNote.ReadNotesInfo=false;
3610
3611       if (GSM->GetCalendarNote(&CalendarNote) == GE_NONE) {
3612         char z_type[11];
3613         char z_recur[15];
3614         switch (CalendarNote.Type) {
3615            case GCN_REMINDER:strcpy(z_type, "REMIND");  break;
3616            case GCN_CALL:    strcpy(z_type, "CALL");    break;
3617            case GCN_MEETING: strcpy(z_type, "MEETING"); break;
3618            case GCN_BIRTHDAY:strcpy(z_type, "BDAY");    break;
3619            default:          strcpy(z_type, "UNKNOWN"); break;
3620           }
3621
3622         if( CalendarNote.Recurrance ) {
3623           sprintf( z_recur,"%d ", CalendarNote.Recurrance/24 );
3624           strcat( z_recur, CalendarNote.Recurrance == 1 ? "day" : "days" );
3625         }
3626         else
3627           strcpy( z_recur, "No" );
3628
3629         strcpy(z_text,"");
3630         
3631         if( CalendarNote.Type == GCN_CALL )
3632           sprintf(z_text, "\"%s\"", CalendarNote.Phone );
3633           
3634         if (CalendarNote.Text[0]!=0)
3635           sprintf(z_text, "\"%s\"", CalendarNote.Text );
3636           
3637         if(CalendarNote.Type == GCN_BIRTHDAY) {
3638           int i_age;
3639           i_age = Date.Year - CalendarNote.Time.Year;
3640           sprintf(z_text, "\"%s (%d %s)\"", CalendarNote.Text,
3641              i_age, (i_age==1)?"year":"years");
3642           strcpy( z_recur, "-" );
3643           if (GetModelFeature (FN_CALENDAR)==F_CAL71)
3644             fprintf(stdout,
3645                 _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s %s\n"), 
3646               i+1,NotesInfo.Location[i], z_type, z_text,
3647               CalendarNote.Time.Year, 
3648               CalendarNote.Time.Month, 
3649               CalendarNote.Time.Day,
3650               (CalendarNote.AlarmType==0x00) ? "Tone  " : "Silent",
3651               " " );
3652           else
3653             fprintf(stdout,
3654                 _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s %s\n"), 
3655               i+1,NotesInfo.Location[i], z_type, z_text,
3656               CalendarNote.Time.Year, 
3657               CalendarNote.Time.Month, 
3658               CalendarNote.Time.Day,
3659               (CalendarNote.Alarm.Year) ? "Yes" : "No ",
3660               " " );
3661         } else
3662           if (GetModelFeature (FN_CALENDAR)==F_CAL71)
3663             fprintf(stdout,
3664                 _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s    %s\n"), 
3665               i+1,NotesInfo.Location[i], z_type, z_text,
3666               CalendarNote.Time.Year, 
3667               CalendarNote.Time.Month, 
3668               CalendarNote.Time.Day,
3669               (CalendarNote.Alarm.Year) ? "Yes" : "No ",
3670               z_recur );
3671            else
3672             fprintf(stdout,
3673                 _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s\n"), 
3674               i+1,NotesInfo.Location[i], z_type, z_text,
3675               CalendarNote.Time.Year, 
3676               CalendarNote.Time.Month, 
3677               CalendarNote.Time.Day,
3678               (CalendarNote.Alarm.Year) ? "Yes" : "No ");
3679       } else {
3680         if (GetModelFeature (FN_CALENDAR)!=F_CAL71) break;
3681       }
3682     }
3683   }
3684   else
3685   for (i=start;i<=stop;i++) {
3686     if (error==GE_NONE) {
3687         if( i>NotesInfo.HowMany ) {
3688             fprintf(stderr, _("Only %d Calendar Notes present on phone!\n"),NotesInfo.HowMany);
3689             break;
3690         }
3691         if( i==0 ) {
3692             fprintf(stderr, _("Calendar Notes location can't be zero... skipping.\n"));
3693             continue;
3694         }
3695     }
3696     
3697     CalendarNote.Location=i;
3698     CalendarNote.ReadNotesInfo=false;
3699
3700     if (GSM->GetCalendarNote(&CalendarNote) == GE_NONE) {