Implemented connection type "tcp" (GCT_TCP), use <hostname>:<port> as "port"
[gnokii.git] / gnokii / gnokii.c
index 43beca6..b7f0850 100644 (file)
 /*
 
 /*
 
+  $Id$
+  
   G N O K I I
 
   A Linux/Unix toolset and driver for Nokia mobile phones.
 
   G N O K I I
 
   A Linux/Unix toolset and driver for Nokia mobile phones.
 
+  Copyright (C) 1999, 2000 Hugh Blemings & Pavel Janík ml.
+  Copyright (C) 2001       Pavel Machek
+  Copyright (C) 2001       Pawe³ Kot
+
   Released under the terms of the GNU GPL, see file COPYING for more details.
        
   Mainline code for gnokii utility.  Handles command line parsing and
   reading/writing phonebook entries and other stuff.
 
   Released under the terms of the GNU GPL, see file COPYING for more details.
        
   Mainline code for gnokii utility.  Handles command line parsing and
   reading/writing phonebook entries and other stuff.
 
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <string.h>
-#include <ctype.h>
-#include <time.h>
-#include <sys/stat.h>
-
-#ifndef VC6
-  #if defined(__svr4__) || defined(__FreeBSD__)
-  #  include <strings.h>       /* for bzero */
-  #endif
-#else
-  /* for VC6 make scripts save VERSION constant in mversion.h file */
-  #include "mversion.h"
-#endif
-
-#ifdef WIN32
-
-  #include <windows.h>
+  WARNING: this code is the test tool. Well, our test tool is now
+  really powerful and useful :-)
 
 
-  #include "misc_win32.h"
-  #include "getopt.h"
+  $Log$
+  Revision 1.1.1.12  2002/04/03 01:44:15  short
+  Implemented connection type "tcp" (GCT_TCP), use <hostname>:<port> as "port"
 
 
-  #define DEV_CONSOLE "CON:"
+  Revision 1.1.1.11  2002/04/03 00:08:17  short
+  Found in "gnokii-working" directory, some November-patches version
 
 
-#else
+  Revision 1.143  2001/09/14 13:30:07  pkot
+  Fixed bugs introduced during 0.3.3 merge
 
 
-  #include <unistd.h>
-  #include <termios.h>
-  #include <fcntl.h>
-  #include <sys/types.h>
-  #include <sys/time.h>
-  #include <getopt.h>
+  Revision 1.142  2001/09/14 13:02:03  pkot
+  Gnokii calendar changes from 0.3.3
 
 
-  #define DEV_CONSOLE "/dev/tty"
-#endif
+  Revision 1.141  2001/09/14 12:53:00  pkot
+  New preview logos.
+  Localization fixes.
+  Set valid operator on logos xgnokii screen.
 
 
-#include "misc.h"
-#include "gsm-common.h"
-#include "gsm-api.h"
-#include "gsm-networks.h"
-#include "gsm-ringtones.h"
-#include "gsm-bitmaps.h"
-#include "gsm-wap.h"
-#include "gsm-sms.h"
-#include "gsm-datetime.h"
-#include "gsm-phonebook.h"
-#include "gsm-calendar.h"
-#include "gsm-coding.h"
-#include "newmodules/n6110.h"
-#include "files/cfgreader.h"
-#include "files/gsm-filetypes.h"
-#include "gnokii.h"
+  Revision 1.140  2001/07/27 00:02:21  pkot
+  Generic AT support for the new structure (Manfred Jonsson)
 
 
-#ifdef USE_NLS
-  #include <locale.h>
-#endif
+  Revision 1.139  2001/07/01 23:16:45  pkot
+  Fixed a typo in gnokii.c avoiding saving logo (Jan Havelka)
 
 
-char *model;           /* Model from .gnokiirc file. */
-char *Port;            /* Port from .gnokiirc file */
-char *Initlength;      /* Init length from .gnokiirc file */
-char *Connection;      /* Connection type from .gnokiirc file */
-char *SynchronizeTime; /* If we set date and time from computer to phone (from .gnokiirc file) */
-char *BinDir;          /* Binaries directory from .gnokiirc file - not used here yet */
+  Revision 1.138  2001/06/28 00:28:45  pkot
+  Small docs updates (Pawel Kot)
 
 
-GSM_SMSMessage SMS[4];
-  
-char *GetProfileCallAlertString(int code) {
-
-  switch (code) {
-    case PROFILE_CALLALERT_RINGING     : return "Ringing";
-    case PROFILE_CALLALERT_ASCENDING   : return "Ascending";
-    case PROFILE_CALLALERT_RINGONCE    : return "Ring once";
-    case PROFILE_CALLALERT_BEEPONCE    : return "Beep once";
-    case PROFILE_CALLALERT_CALLERGROUPS: return "Caller groups";
-    case PROFILE_CALLALERT_OFF         : return "Off";
-    default                            : return "Unknown";
-  }
-}
+  Revision 1.137  2001/06/27 23:52:50  pkot
+  7110/6210 updates (Marian Jancar)
 
 
-char *GetProfileVolumeString(int code) {
+  Revision 1.136  2001/06/10 23:49:49  pkot
+  Small fixes to hide compilation warnings and allow gnokii.c to compile
 
 
-  switch (code) {
-    case PROFILE_VOLUME_LEVEL1 : return "Level 1";
-    case PROFILE_VOLUME_LEVEL2 : return "Level 2";
-    case PROFILE_VOLUME_LEVEL3 : return "Level 3";
-    case PROFILE_VOLUME_LEVEL4 : return "Level 4";
-    case PROFILE_VOLUME_LEVEL5 : return "Level 5";
-    default                    : return "Unknown";
-  }
-}
+  Revision 1.135  2001/06/10 11:42:26  machek
+  Cleanup: some formating, made Statemachine global, converted to new
+  structure w.r.t. SMS-es
 
 
-char *GetProfileKeypadToneString(int code) {
+  Revision 1.134  2001/05/24 20:47:30  chris
+  More updating of 7110 code and some of xgnokii_lowlevel changed over.
 
 
-  switch (code) {
-    case PROFILE_KEYPAD_OFF    : return "Off";
-    case PROFILE_KEYPAD_LEVEL1 : return "Level 1";
-    case PROFILE_KEYPAD_LEVEL2 : return "Level 2";
-    case PROFILE_KEYPAD_LEVEL3 : return "Level 3";
-    default                    : return "Unknown";
-  }
-}
+  Revision 1.133  2001/04/23 17:20:01  pkot
+  Added possibility for viewing logos (currently nol and ngg) on console (Bartek Klepacz)
 
 
-char *GetProfileMessageToneString(int code) {
+  Revision 1.132  2001/03/21 23:36:06  chris
+  Added the statemachine
+  This will break gnokii --identify and --monitor except for 6210/7110
 
 
-  switch (code) {
-    case PROFILE_MESSAGE_NOTONE    : return "No tone";
-    case PROFILE_MESSAGE_STANDARD  : return "Standard";
-    case PROFILE_MESSAGE_SPECIAL   : return "Special";
-    case PROFILE_MESSAGE_BEEPONCE  : return "Beep once";
-    case PROFILE_MESSAGE_ASCENDING : return "Ascending";
-    default                        : return "Unknown";
-  }
-}
+  Revision 1.131  2001/03/19 23:43:46  pkot
+  Solaris / BSD '#if defined' cleanup
 
 
-char *GetProfileWarningToneString(int code) {
+  Revision 1.130  2001/03/13 01:23:18  pkot
+  Windows updates (Manfred Jonsson)
 
 
-  switch (code) {
-    case PROFILE_WARNING_OFF : return "Off";
-    case PROFILE_WARNING_ON  : return "On";
-    default                  : return "Unknown";
-  }
-}
+  Revision 1.129  2001/03/13 01:21:39  pkot
+  *BSD updates (Bert Driehuis)
 
 
-char *GetProfileOnOffString(int code) {
+  Revision 1.128  2001/03/08 00:49:06  pkot
+  Fixed bug (introduced by me) in getmemory function. Now gnokii.c should compile
 
 
-  switch (code) {
-    case 0x00 : return "Off";
-    case 0x01 : return "On";
-    default   : return "Unknown";
-  }
-}
+  Revision 1.127  2001/03/08 00:18:13  pkot
+  Fixed writephonebook once again. Someone kick me please...
 
 
-static char *GetProfileVibrationString(int code)
-{
-       switch (code) {
-       case PROFILE_VIBRATION_OFF:     return "Off";
-       case PROFILE_VIBRATION_ON:      return "On";
-       case PROFILE_VIBRATION_FIRST:   return "Vibrate first";
-       default:                        return "Unknown";
-       }
-}
+  Revision 1.126  2001/03/07 21:46:12  pkot
+  Fixed writephonebook patch
 
 
-char BufferProfileGroups[90];
+  Revision 1.125  2001/03/06 22:19:14  pkot
+  Cleanups and fixes in gnokii.c:
+   - reindenting
+   - fixed bug reported by Gabriele Zappi
+   - fixed small bugs introduced by Pavel Machek
 
 
-char *GetProfileCallerGroups(int code) 
-{
-  static char az_group_name[5][MAX_BITMAP_TEXT_LENGTH];
-  static bool enteronce=false;
-  register int i;
-  GSM_Bitmap bitmap;
+  Revision 1.124  2001/02/28 21:42:00  machek
+  Possibility to force overwrite in --getsms (-F). Possibility to get
+  multiple files (use --getsms -f xyzzy%d), cleanup.
 
 
-  if( code == PROFILE_CALLERGROUPS_ALL )
-       return _("All calls alert");
+  Revision 1.123  2001/02/20 21:55:11  pkot
+  Small #include updates
 
 
-  if( !enteronce ) {
-    for(i=0;i<5;i++) az_group_name[i][0]='\0';
-    enteronce=true;
-  }
+  Revision 1.122  2001/02/16 14:29:53  chris
+  Restructure of common/.  Fixed a problem in fbus-phonet.c
+  Lots of dprintfs for Marcin
+  Any size xpm can now be loaded (eg for 7110 startup logos)
+  nk7110 code detects 7110/6210 and alters startup logo size to suit
+  Moved Marcin's extended phonebook code into gnokii.c
 
 
-  BufferProfileGroups[0]=0;
-    
-  for(i=0;i<5;i++)
-  {
-    int code2test;
-    char z_gtype[12];
-
-    code2test=(i==0) ? 1 : 2<<(i-1);
-
-    if( code & code2test )
-    {
-      if (!strcmp(az_group_name[i],"")) 
-      {
-        if (GetModelFeature (FN_CALLERGROUPS)!=0) {
-          bitmap.type=GSM_CallerLogo;
-          bitmap.number=i;
-          strcpy(z_gtype,_("unknown"));
-          if (GSM->GetBitmap(&bitmap)==GE_NONE)
-            strcpy( az_group_name[i], bitmap.text );
-        }
-        if ((!strcmp(az_group_name[i],""))) {
-            switch(i) {
-            case 0:strcpy(az_group_name[i],_("Family"));break;
-            case 1:strcpy(az_group_name[i],_("VIP"));break;
-            case 2:strcpy(az_group_name[i],_("Friends"));break;
-            case 3:strcpy(az_group_name[i],_("Colleagues"));break;
-            case 4:strcpy(az_group_name[i],_("Other"));break;
-            default:break;
-          }
-        }
-      }
-      strcpy(z_gtype,az_group_name[i]);
-
-      if( strlen(BufferProfileGroups) ) strcat(BufferProfileGroups,"+");
-      strcat(BufferProfileGroups, z_gtype);
-    }
-    
-  }
+  Revision 1.121  2001/02/06 21:15:35  chris
+  Preliminary irda support for 7110 etc.  Not well tested!
 
 
-  return BufferProfileGroups;
-}
+  Revision 1.120  2001/02/06 08:13:32  pkot
+  One more include in gnokii.c needed
 
 
-char *print_error(GSM_Error e)
-{
+  Revision 1.119  2001/02/05 12:29:37  pkot
+  Changes needed to let unicode work
 
 
-//     case GE_DEVICEOPENFAILED:         return "Couldn't open specified serial device.";
-//     case GE_UNKNOWNMODEL:             return "Model specified isn't known/supported.";
-//     case GE_NOLINK:                   return "Couldn't establish link with phone.";
-//     case GE_TRYAGAIN:                 return "Try again.";
-//     case GE_INVALIDSMSLOCATION:       return "Invalid SMS location.";
-//     case GE_INVALIDPHBOOKLOCATION:    return "Invalid phonebook location.";
-//     case GE_INVALIDMEMORYTYPE:        return "Invalid type of memory.";
-//     case GE_INVALIDSPEEDDIALLOCATION: return "Invalid speed dial location.";
-//     case GE_INVALIDCALNOTELOCATION:   return "Invalid calendar note location.";
-//     case GE_INVALIDDATETIME:          return "Invalid date, time or alarm specification.";
-//     case GE_EMPTYSMSLOCATION:         return "SMS location is empty.";
-//     case GE_PHBOOKNAMETOOLONG:        return "Phonebook name is too long.";
-//     case GE_PHBOOKNUMBERTOOLONG:      return "Phonebook number is too long.";
-//     case GE_PHBOOKWRITEFAILED:        return "Phonebook write failed.";
-//     case GE_SMSSENDOK:                return "SMS was send correctly.";
-//     case GE_SMSSENDFAILED:            return "SMS send fail.";
-//     case GE_SMSTOOLONG:               return "SMS message too long.";
-//     case GE_NONEWCBRECEIVED:          return "Attempt to read CB when no new CB received";
-//     case GE_INTERNALERROR:            return "Problem occured internal to model specific code.";
-//     case GE_NOTSUPPORTED:             return "Function not supported by the phone";
-//     case GE_BUSY:                     return "Command is still being executed.";
-//     case GE_USERCANCELED:             return "User has cancelled the action.";   
-//     case GE_UNKNOWN:                  return "Unknown error - well better than nothing!!";
-//     case GE_MEMORYFULL:               return "Memory is full";
-//     case GE_LINEBUSY:                 return "Outgoing call requested reported line busy";
-//     case GE_NOCARRIER:                return "No Carrier error during data call setup ?";
-
-       switch (e) {
-       case GE_NONE:                     return "No error, done OK";
-       case GE_INVALIDSECURITYCODE:      return "Invalid Security code.";
-       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";
-       case GE_TIMEOUT:                  return "Command timed out.";
-       case GE_CANTOPENFILE:             return "Can't open file with bitmap/ringtone";
-       case GE_SUBFORMATNOTSUPPORTED:    return "Subformat of file not supported";
-       case GE_WRONGNUMBEROFCOLORS:      return "Wrong number of colors in specified bitmap file (only 2 colors files supported)";
-       case GE_WRONGCOLORS:              return "Wrong colors in bitmap file";
-       case GE_INVALIDIMAGESIZE:         return "Invalid size of bitmap (in file, sms etc.)";
-       case GE_INVALIDFILEFORMAT:        return "Invalid format of file";
-        case GE_TOOSHORT:                 return "File too short";
-        case GE_INSIDEBOOKMARKSMENU:      return "Inside WAP Bookmarks menu. Please leave it and try again";
-        case GE_INVALIDBOOKMARKLOCATION:  return "Invalid or empty WAP bookmark location";
-        case GE_INSIDESETTINGSMENU:       return "Inside WAP Settings menu. Please leave it and try again";
-        case GE_INVALIDSETTINGSLOCATION:  return "Invalid or empty WAP settings location";
-       default:                          return "Unknown error.";
-       }
-}
+  Revision 1.118  2001/02/01 15:17:33  pkot
+  Fixed --identify and added Manfred's manufacturer patch
 
 
+  Revision 1.117  2001/01/31 23:45:27  pkot
+  --identify should work ok now
 
 
-GSM_Error GSM_ReadRingtoneFileOnConsole(char *FileName, GSM_Ringtone *ringtone)
-{
-  GSM_Error error;
-  
-  error=GSM_ReadRingtoneFile(FileName, ringtone);
-  
-  switch (error) {
-    case GE_CANTOPENFILE:
-    case GE_SUBFORMATNOTSUPPORTED:
-      fprintf(stderr, _("File \"%s\"\nError: %s\n"),FileName,print_error(error));
-      break;
-    default:
-      break;
-  }
-  
-  return error;
-}
+  Revision 1.116  2001/01/24 20:19:55  machek
+  Do not retry identification, if it is not implemented, it is bad idea.
 
 
-GSM_Error GSM_SaveRingtoneFileOnConsole(char *FileName, GSM_Ringtone *ringtone)
-{
-  int confirm,confirm2;
-  char ans[4];
-  struct stat buf;
-  GSM_Error error;
+  Revision 1.115  2001/01/22 01:25:10  hugh
+  Tweaks for 3810 series, datacalls seem to be broken so need to do
+  some more debugging...
 
 
-  /* Ask before overwriting */
-  while (stat(FileName, &buf) == 0) {
-  
-    confirm=-1;
-    confirm2=-1;
-    
-    while (confirm < 0) {
-      fprintf(stderr, _("Saving ringtone. File \"%s\" exists. (O)verwrite, create (n)ew or (s)kip ? "),FileName);
-      GetLine(stdin, ans, 4);
-      if (!strcmp(ans, "O") || !strcmp(ans, "o")) confirm = 1;
-      if (!strcmp(ans, "N") || !strcmp(ans, "n")) confirm = 2;
-      if (!strcmp(ans, "S") || !strcmp(ans, "s")) return GE_USERCANCELED;
-    }  
-    if (confirm==1) break;
-    if (confirm==2) {
-      while (confirm2 < 0) {
-        fprintf(stderr, _("Enter name of new file: "));
-        GetLine(stdin, FileName, 50);
-        if (&FileName[0]==0) return GE_USERCANCELED;
-       confirm2=1;
-      }  
-    }
-  }
-  
-  error=GSM_SaveRingtoneFile(FileName,ringtone);
-  
-  switch (error) {
-    case GE_CANTOPENFILE:        fprintf(stderr, _("Failed to write file \"%s\"\n"),FileName);
-                                 break;
-    default:                     break;
-  }
-  
-  return error;
-}
+  Revision 1.114  2001/01/17 02:54:55  chris
+  More 7110 work.  Use with care! (eg it is not possible to delete phonebook entries)
+  I can now edit my phonebook in xgnokii but it is 'work in progress'.
 
 
-GSM_Error GSM_ReadBitmapFileOnConsole(char *FileName, GSM_Bitmap *bitmap)
-{
-  GSM_Error error;
-  
-  error=GSM_ReadBitmapFile(FileName, bitmap);
-
-  switch (error) {
-    case GE_CANTOPENFILE:
-    case GE_WRONGNUMBEROFCOLORS:
-    case GE_WRONGCOLORS:        
-    case GE_INVALIDFILEFORMAT:  
-    case GE_SUBFORMATNOTSUPPORTED:
-    case GE_TOOSHORT:
-    case GE_INVALIDIMAGESIZE:
-      fprintf(stderr, _("File \"%s\"\nError: %s\n"),FileName,print_error(error));
-      break;
-    default: 
-      break;
-  }
-  
-  return error;
-}
+  Revision 1.113  2001/01/15 17:00:49  pkot
+  Initial keypress sequence support. Disable compilation warning
 
 
-GSM_Error GSM_SaveBitmapFileOnConsole(char *FileName, GSM_Bitmap *bitmap)
-{
-  int confirm,confirm2;
-  char ans[4];
-  struct stat buf;
-  GSM_Error error;
+  Revision 1.112  2001/01/12 14:09:13  pkot
+  More cleanups. This time mainly in the code.
 
 
-  /* Ask before overwriting */
-  while (stat(FileName, &buf) == 0) {
-  
-    confirm=-1;
-    confirm2=-1;
-    
-    while (confirm < 0) {
-      fprintf(stderr, _("Saving logo. File \"%s\" exists. (O)verwrite, create (n)ew or (s)kip ? "),FileName);
-      GetLine(stdin, ans, 4);
-      if (!strcmp(ans, "O") || !strcmp(ans, "o")) confirm = 1;
-      if (!strcmp(ans, "N") || !strcmp(ans, "n")) confirm = 2;
-      if (!strcmp(ans, "S") || !strcmp(ans, "s")) return GE_USERCANCELED;
-    }  
-    if (confirm==1) break;
-    if (confirm==2) {
-      while (confirm2 < 0) {
-        fprintf(stderr, _("Enter name of new file: "));
-        GetLine(stdin, FileName, 50);
-        if (&FileName[0]==0) return GE_USERCANCELED;
-       confirm2=1;
-      }  
-    }
-  }
-  
-  error=GSM_SaveBitmapFile(FileName,bitmap);
-  
-  switch (error) {
-    case GE_CANTOPENFILE:        fprintf(stderr, _("Failed to write file \"%s\"\n"),FileName);
-                                 break;
-    default:                     break;
-  }
-  
-  return error;
-}
+  Revision 1.111  2001/01/10 16:32:18  pkot
+  Documentation updates.
+  FreeBSD fix for 3810 code.
+  Added possibility for deleting SMS just after reading it in gnokii.
+  2110 code updates.
+  Many cleanups.
 
 
-/* mode == 0 -> overwrite
- * mode == 1 -> ask
- * mode == 2 -> append
- */
-int GSM_SaveTextFileOnConsole(char *FileName, char *text, int mode)
-{
-  int confirm, confirm2;
-  char ans[4];
-  struct stat buf;
-  int error;
-
-  /* Ask before overwriting */
-  if (mode==1) {
-    while (stat(FileName, &buf) == 0 && mode==1) {
-      
-      confirm=-1;
-      confirm2=-1;
-      
-      while (confirm < 0) {
-        fprintf(stderr, _("File \"%s\" exists. (O)verwrite, (a)ppend, create (n)ew or (s)kip ? "),FileName);
-        GetLine(stdin, ans, 4);
-        if (!strcmp(ans, "O") || !strcmp(ans, "o")) {
-          mode = 0;
-          confirm = 1;
-        }
-        if (!strcmp(ans, "A") || !strcmp(ans, "a")) {
-         mode = 2;
-          confirm = 1;
-        }
-        if (!strcmp(ans, "N") || !strcmp(ans, "n")) confirm=2;
-        if (!strcmp(ans, "S") || !strcmp(ans, "s")) return -1;
-      }
-      
-      if (confirm==2) {
-        while (confirm2 < 0) {
-          fprintf(stderr, _("Enter name of new file: "));
-          GetLine(stdin, FileName, 50);
-          if (&FileName[0]==0) return -1;
-         mode=1;
-         confirm2=1;
-        }  
-      }
-      
-    }  
-  }
-  
-  error=GSM_SaveTextFile(FileName, text, mode);
-  
-  switch (error) {
-    case -1: fprintf(stderr, _("Failed to write file \"%s\"\n"),  FileName);
-             break;
-    default: break;
-  }
+  Revision 1.110  2001/01/08 15:11:37  pkot
+  Documentation updates.
+  Fixed some bugs and removed FIXMEs.
+  We need to move some stuff from configure.in to aclocal.m4
 
 
-  return error;
-}
+  Revision 1.109  2000/12/29 15:39:07  pkot
+  Reverted a change in fbus-3810.c which broke compling with --enable-debug.
+  Small fixes in gnokii.c
 
 
-int GSM_SendMultiPartSMSOnConsole(GSM_MultiSMSMessage *MultiSMS, int argnum, int argc, char *argv[],
-                                  bool unicode, bool profile, bool scale) {
+  Revision 1.108  2000/12/19 16:18:16  pkot
+  configure script updates and added shared function for configfile reading
 
 
-  int w,i;
-  
-  struct option options[] = {
-             { "smscno",       required_argument, NULL, '1'},
-             { "smsc",         required_argument, NULL, '2'},
-            { "name",         required_argument, NULL, '3'},
-             { "unicode",      no_argument,       NULL, '4'},
-             { "profilestyle", no_argument,       NULL, '5'},
-            { "scale",        no_argument,       NULL, '6'},
-             { NULL,           0,                 NULL,  0 }
-  };
-
-  GSM_Error error;  
-
-  for (w=0;w<MultiSMS->number;w++) {
-
-    if (argnum!=0) {
-      optarg = NULL;
   
   
-      /* We check optional parameters from ... */
-      optind = argnum;
-
-      while ((i = getopt_long(argc, argv, "v:ds", options, NULL)) != -1) {
-        switch (i) {
-
-          case '1': /* SMSC number */
-            MultiSMS->SMS[w].MessageCenter.No = 0;
-            strcpy(MultiSMS->SMS[w].MessageCenter.Number,optarg);
-            break;
-
-          case '2': /* SMSC number index in phone memory */
-            MultiSMS->SMS[w].MessageCenter.No = atoi(optarg);
-
-            if (MultiSMS->SMS[w].MessageCenter.No < 1 || MultiSMS->SMS[w].MessageCenter.No > 5) {
-             fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
-              GSM->Terminate();
-              return -1;
-           }
-            break;
-
-         case '3': /* Receiver/recipient */
-           strncpy(MultiSMS->SMS[w].Destination,optarg,11); break;
-
-         case '4': /* Unicode */
-           if (unicode) break;
-
-         case '5': /* Profile */
-           if (profile) break;
+*/
 
 
-         case '6': /* Scale */
-           if (scale) break;
+#include "config.h"
+#include "misc.h"
 
 
-          case 'v': /* Set validaty of SMS */
-            MultiSMS->SMS[w].Validity = atoi(optarg);
-            break;
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#if __unices__
+#  include <strings.h> /* for memset */
+#endif
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 
-          case 'd': /* delivery report */
-            MultiSMS->SMS[w].Type=GST_DR;
-            break;     
+#ifdef WIN32
 
 
-          case 's': /* Set replying via the same SMSC */
-            MultiSMS->SMS[w].ReplyViaSameSMSC = true; break;
+#include <windows.h>
+#define sleep(x) Sleep((x) * 1000)
+#define usleep(x) Sleep(((x) < 1000) ? 1 : ((x) / 1000))
+#define stat _stat
+#include "win32/getopt.h"
 
 
-        default:
-          fprintf(stderr,_("Unknown option number %i\n"),argc);
-          GSM->Terminate();    
-          return -1;
+#else
 
 
-        }
-      }
-    }
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <getopt.h>
 
 
-    error=GSM->SendSMSMessage(&MultiSMS->SMS[w]);
+#endif
 
 
-    if (error == GE_SMSSENDOK) {
-      fprintf(stdout, _("SMS %i/%i sent OK !\n"),w+1,MultiSMS->number);
-    } else {
-      fprintf(stdout, _("SMS %i/%i, sending failed (error=%d)\n"),w+1,MultiSMS->number, error);
-    }
+#ifdef USE_NLS
+#include <locale.h>
+#endif
 
 
-  }
+#include "gsm-common.h"
+#include "gsm-api.h"
+#include "gsm-networks.h"
+#include "cfgreader.h"
+#include "gnokii.h"
+#include "gsm-filetypes.h"
+#include "gsm-bitmaps.h"
+#include "gsm-ringtones.h"
+#include "gsm-statemachine.h"
 
 
-  GSM->Terminate();  
+char *model;      /* Model from .gnokiirc file. */
+char *Port;       /* Serial port from .gnokiirc file */
+char *Initlength; /* Init length from .gnokiirc file */
+char *Connection; /* Connection type from .gnokiirc file */
+char *BinDir;     /* Binaries directory from .gnokiirc file - not used here yet */
+/* Local variables */
 
 
-  return 0;
+char *GetProfileCallAlertString(int code)
+{
+       switch (code) {
+       case PROFILE_CALLALERT_RINGING:         return "Ringing";
+       case PROFILE_CALLALERT_ASCENDING:       return "Ascending";
+       case PROFILE_CALLALERT_RINGONCE:        return "Ring once";
+       case PROFILE_CALLALERT_BEEPONCE:        return "Beep once";
+       case PROFILE_CALLALERT_CALLERGROUPS:    return "Caller groups";
+       case PROFILE_CALLALERT_OFF:             return "Off";
+       default:                                return "Unknown";
+       }
 }
 
 }
 
-int GSM_SaveMultiPartSMSOnConsole(GSM_MultiSMSMessage *MultiSMS, int argnum, int argc, char *argv[],
-                                  bool inter, bool unicode, bool profile, bool scale) {
-
-  int w,i;
-  
-  GSM_SMSMessage SMSold;
-
-  struct option options[] = {
-             { "smscno",       required_argument, NULL, '1'},
-             { "smsc",         required_argument, NULL, '2'},
-            { "name",         required_argument, NULL, '3'},
-             { "unicode",      no_argument,       NULL, '4'},
-             { "profilestyle", no_argument,       NULL, '5'},
-            { "scale",        no_argument,       NULL, '6'},
-             { NULL,           0,                 NULL,  0 }
-  };
-
-  int interactive;
-  int confirm = -1;
-  char ans[8];
-
-  GSM_Error error;  
-
-  interactive = inter;
-
-  for (w=0;w<MultiSMS->number;w++) {
-
-    if (argnum!=0) {
-      optarg = NULL;
-  
-      /* We check optional parameters from ... */
-      optind = argnum;
-
-      while ((i = getopt_long(argc, argv, "risal:", options, NULL)) != -1) {
-        switch (i) {
-
-          case '1': /* SMSC number */
-            MultiSMS->SMS[w].MessageCenter.No = 0;
-            strcpy(MultiSMS->SMS[w].MessageCenter.Number,optarg);
-            break;
-
-          case '2': /* SMSC number index in phone memory */
-            MultiSMS->SMS[w].MessageCenter.No = atoi(optarg);
-
-            if (MultiSMS->SMS[w].MessageCenter.No < 1 || MultiSMS->SMS[w].MessageCenter.No > 5) {
-             fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
-              GSM->Terminate();
-              return -1;
-           }
-            break;
-
-         case '3': /* Receiver/recipient */
-           strncpy(MultiSMS->SMS[w].Destination,optarg,11); break;
-
-         case '4': /* Unicode */
-           if (unicode) break;
-
-         case '5': /* Profile */
-           if (profile) break;
-
-         case '6': /* Scale */
-           if (scale) break;
-
-          case 'r': /* mark as read */
-            MultiSMS->SMS[w].Status = GSS_SENTREAD; break;
-
-         case 'i': /* Save into Inbox */
-            MultiSMS->SMS[w].folder = GST_INBOX; break;
-         
-          case 's': /* Set replying via the same SMSC */
-            MultiSMS->SMS[w].ReplyViaSameSMSC = true; break;
-
-          case 'a': /* Ask before overwriting */
-            interactive=true;break;     
-       
-          case 'l': /* Specify location */
-            MultiSMS->SMS[0].Location = atoi(optarg); break;     
-
-        default:
-          fprintf(stderr,_("Unknown option number %i\n"),argc);
-          GSM->Terminate();    
-          return -1;
-        }
-      }
-    }
-
-    if (interactive && MultiSMS->SMS[0].Location!=0 && w==0) {
-      SMSold.Location=MultiSMS->SMS[0].Location;
-      error = GSM->GetSMSMessage(&SMSold);
-      switch (error) {
-        case GE_NONE:
-          fprintf(stderr, _("Message at specified location exists. "));
-          while (confirm < 0) {
-            fprintf(stderr, _("Overwrite? (yes/no) "));
-            GetLine(stdin, ans, 7);
-            if (!strcmp(ans, "yes")) confirm = 1;
-            if (!strcmp(ans, "no")) confirm = 0;
-          }  
-          if (!confirm) { GSM->Terminate(); return 0; }
-          else break;
-        case GE_INVALIDSMSLOCATION:
-          fprintf(stderr, _("Invalid location\n"));
-          GSM->Terminate();
-          return -1;
-        default:
-/* FIXME: Remove this fprintf when the function is thoroughly tested */
-#ifdef DEBUG
-            fprintf(stderr, _("Location %d empty. Saving\n"), SMS[w].Location);
-#endif
-          break;
-      }
-    }
-
-    error=GSM->SaveSMSMessage(&MultiSMS->SMS[w]);
-
-    if (error == GE_NONE)
-      fprintf(stdout, _("SMS %i/%i saved at location %i !\n"),w+1,MultiSMS->number,MultiSMS->SMS[w].MessageNumber);
-    else
-      fprintf(stdout, _("SMS %i/%i saving failed (error=%d, location=%i)\n"), w+1, MultiSMS->number, error,MultiSMS->SMS[w].Location);
-  }
+char *GetProfileVolumeString(int code)
+{
+       switch (code) {
+       case PROFILE_VOLUME_LEVEL1:             return "Level 1";
+       case PROFILE_VOLUME_LEVEL2:             return "Level 2";
+       case PROFILE_VOLUME_LEVEL3:             return "Level 3";
+       case PROFILE_VOLUME_LEVEL4:             return "Level 4";
+       case PROFILE_VOLUME_LEVEL5:             return "Level 5";
+       default:                                return "Unknown";
+       }
+}
 
 
-  GSM->Terminate();  
+char *GetProfileKeypadToneString(int code)
+{
+       switch (code) {
+       case PROFILE_KEYPAD_OFF:                return "Off";
+       case PROFILE_KEYPAD_LEVEL1:             return "Level 1";
+       case PROFILE_KEYPAD_LEVEL2:             return "Level 2";
+       case PROFILE_KEYPAD_LEVEL3:             return "Level 3";
+       default:                                return "Unknown";
+       }
+}
 
 
-  return 0;
+char *GetProfileMessageToneString(int code)
+{
+       switch (code) {
+       case PROFILE_MESSAGE_NOTONE:            return "No tone";
+       case PROFILE_MESSAGE_STANDARD:          return "Standard";
+       case PROFILE_MESSAGE_SPECIAL:           return "Special";
+       case PROFILE_MESSAGE_BEEPONCE:          return "Beep once";
+       case PROFILE_MESSAGE_ASCENDING:         return "Ascending";
+       default:                                return "Unknown";
+       }
 }
 
 }
 
-void GSM_PlayRingtoneOnConsole(GSM_Ringtone *ringtone)
+char *GetProfileWarningToneString(int code)
 {
 {
-  int i;
-#ifdef VC6
-  char mychar;
-#endif
+       switch (code) {
+       case PROFILE_WARNING_OFF:               return "Off";
+       case PROFILE_WARNING_ON:                return "On";
+       default:                                return "Unknown";
+       }
+}
 
 
-  for (i=0;i<ringtone->NrNotes;i++) {
-#ifdef VC6
-    if (_kbhit()) {
-      mychar=_getch();
-      break;
-    }
-#endif
-    GSM_PlayOneNote (ringtone->notes[i]);
-  }
-  GSM->PlayTone(255*255,0);
+char *GetProfileVibrationString(int code)
+{
+       switch (code) {
+       case PROFILE_VIBRATION_OFF:             return "Off";
+       case PROFILE_VIBRATION_ON:              return "On";
+       default:                                return "Unknown";
+       }
 }
 
 /* This function shows the copyright and some informations usefull for
    debugging. */
 }
 
 /* This function shows the copyright and some informations usefull for
    debugging. */
+
 int version(void)
 {
 int version(void)
 {
-
-  fprintf(stdout, _("GNOKII Version %s\n"
-"Copyright (C) Hugh Blemings <hugh@linuxcare.com>, 1999, 2000\n"
-"Copyright (C) Pavel Janík ml. <Pavel.Janik@linux.cz>, 1999, 2000\n"
-"Built %s %s for %s on %s \n"), VERSION, __TIME__, __DATE__, model, Port);
-
-  return 0;
+       fprintf(stdout, _("GNOKII Version %s\n"
+                         "Copyright (C) Hugh Blemings <hugh@blemings.org>, 1999, 2000\n"
+                         "Copyright (C) Pavel Janík ml. <Pavel.Janik@suse.cz>, 1999, 2000\n"
+                         "Copyright (C) Pavel Machek <pavel@ucw.cz>, 2001\n"
+                         "Copyright (C) Pawe³ Kot <pkot@linuxnews.pl>, 2001\n"
+                         "gnokii is free software, covered by the GNU General Public License, and you are\n"
+                         "welcome to change it and/or distribute copies of it under certain conditions.\n"
+                         "There is absolutely no warranty for gnokii.  See GPL for details.\n"
+                         "Built %s %s for %s on %s \n"), VERSION, __TIME__, __DATE__, model, Port);
+       return 0;
 }
 
 /* The function usage is only informative - it prints this program's usage and
 }
 
 /* The function usage is only informative - it prints this program's usage and
@@ -700,6657 +297,1825 @@ int version(void)
 
 int usage(void)
 {
 
 int usage(void)
 {
-
-  fprintf(stdout, _("   usage: gnokii [--help|--monitor [-noloop|-nl]|--version]\n"
-"          gnokii --getmemory memory_type [start [end]] [-short|-v30|-v21|-v]\n"
-"          gnokii --writephonebook [-i]\n"
-"          gnokii --sendphonebookentry destination memory_type location\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-s] [-v n] [-d]\n"
-"          gnokii --savephonebookentry memory_type location\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-r] [-i] [-s] [-a] [--name name]\n"
-"          gnokii --getvoicemailbox\n"
-"          gnokii --getspeeddial number\n"
-"          gnokii --setspeeddial number memory_type location\n\n"
-
-"          gnokii --getsms memory_type start [end] [-f file]\n"
-"          gnokii --getsmsstatus\n"
-"          gnokii --getsmsfolders\n"
-"          gnokii --deletesms memory_type start [end]\n"
-"          gnokii --sendsms destination [--smsc message_center_number |\n"
-"                 --smscno message_center_index] [--long n] [-s] [-C n]\n"
-"                 [--enablevoice|--disablevoice|--enablefax|--disablefax|\n"
-"                  --enableemail|--disableemail|--void][--unicode][-v n][-d]\n"
-"          gnokii --savesms destination|\"\" [--smsc \n"
-"                 message_center_number] [--smscno message_center_index]\n"
-"                 [--long n] [-r] [-i] [-s][-C n][-a][-l][F n][--smsname name]\n"
-"                 [--enablevoice|--disablevoice|--enablefax|--disablefax|\n"
-"                  --enableemail|--disableemail|--void|--hang|--bug][--unicode]\n"
-"          gnokii --receivesms\n"
-"          gnokii --getsmsc message_center_number\n"
-"          gnokii --renamesmsc number new_name\n\n"
-
-"          gnokii --setdatetime [YYYY [MM [DD [HH [MM]]]]]\n"
-"          gnokii --getdatetime\n"
-"          gnokii --setalarm HH MM\n"
-"          gnokii --getalarm\n\n"
-
-"          gnokii --getcalendarnote { start end [-v30|-v10] | --short|-s }\n"
-"          gnokii --writecalendarnote vcardfile number\n"
-"          gnokii --deletecalendarnote index\n"
-"          gnokii --sendcalendarnote destination vcardfile number\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-s] [-v n] [-d]\n"
-"          gnokii --savecalendarnote vcardfile number\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-r] [-i] [-s] [-a] [--name name]\n\n"
-
-"          gnokii --netmonitor {reset|off|field|devel|next|nr}\n"
-"          gnokii --nm_collect screen1|-d [screen2|-d]...\n"
-"          gnokii --netmonitordata [-S file] [-I file] [-h] [-n n] [-ts n][-tm n]\n"
-"                 [-fs str] [-ls str] FLD1:FLD2:FLDn:... \n"
-"                 (see files netmonitordata_????_??? for details)\n\n"
-
-"          gnokii --bitmapconvert source destination\n"
-"          gnokii --bitmapconvert source destination op|7110op [network code]\n"
-"          gnokii --bitmapconvert source destination caller [caller group number]\n"
-"          gnokii --bitmapconvert source destination\n"
-"                   startup|7110startup|6210startup\n"
-"          gnokii --bitmapconvert source destination picture\n"
-"          gnokii --showbitmap logofile\n"
-"          gnokii --sendlogo op destination logofile network_code\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-s] [-v n] [-d]\n"
-"          gnokii --sendlogo picture destination logofile text\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-s] [-v n] [-d] [--unicode]\n"
-"          gnokii --sendlogo screensaver destination logofile\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-s] [-v n] [-d]\n"
-"          gnokii --sendlogo caller destination logofile\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-s] [-v n] [-d]\n"
-"          gnokii --savelogo op logofile network_code\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
-"          gnokii --savelogo picture logofile text\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-r] [-i] [-s] [-a] [-l] [--name name] [--unicode]\n"
-"          gnokii --savelogo screensaver logofile\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
-"          gnokii --savelogo caller logofile\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
-"          gnokii --setlogo op|7110op [logofile] [network code]\n"
-"          gnokii --setlogo startup|7110startup|6210startup [logofile]\n"
-"          gnokii --setlogo startup 1|2|3\n"
-"          gnokii --setlogo caller [logofile] [caller group number] [group name]\n"
-"          gnokii --setlogo picture [logofile] [number] [text] [sender]\n"
-"          gnokii --setlogo {dealer|text} [text]\n"
-"          gnokii --getlogo op|7110op [logofile] [network code]\n"
-"          gnokii --getlogo startup|7110startup|6210startup [logofile]\n"
-"          gnokii --getlogo caller [logofile][caller group number]\n"
-"          gnokii --getlogo picture [logofile][number]\n"
-"          gnokii --getlogo {dealer|text}\n\n"
-
-"          gnokii --sendringtone destination ringtonefile\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-s] [-v n] [-d] [--scale] [--profilestyle]\n"
-"          gnokii --saveringtone ringtonefile\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-r] [-i] [-s] [-a] [--name name] [--scale] [--profilestyle]\n"
-"          gnokii --setringtone ringtonefile [location]\n"
-"          gnokii --getringtone ringtonefile [location]\n"
-"          gnokii --ringtoneconvert source destination\n"
-"          gnokii --binringtoneconvert source destination\n"
-"          gnokii --playringtone ringtonefile\n"
-"          gnokii --composer ringtonefile\n"
-"          gnokii --allringtones\n\n"
-
-"          gnokii --getprofile [number]\n"
-"          gnokii --setprofile number feature value\n"
-"          gnokii --sendprofile destination profile_name ringtonefile\n"
-"                 picturefile [--smsc message_center_number]\n"
-"                 [--smscno message_center_index] [-s] [-v n] [-d] [--scale]\n\n"
-
-"          gnokii --reset [soft|hard]\n"
-"          gnokii --dialvoice number\n"
-"          gnokii --cancelcall\n"
-"          gnokii --displayoutput\n"
-"          gnokii --presskeysequence sequence\n"
-"          gnokii --backupsettings file\n"
-"          gnokii --restoresettings file\n"
-"          gnokii --getphoneprofile\n"
-"          gnokii --setphoneprofile feature value\n"
-"          gnokii --getoperatorname\n"
-"          gnokii --setoperatorname code name\n"
-"          gnokii --senddtmf string\n"
-"          gnokii --divert register|enable|query|disable|erasure\n"
-"                 all|busy|noans|outofreach all|voice|fax|data\n"
-"                 [number timeout]\n\n"
-
-"          gnokii --phonetests\n"
-"          gnokii --simlock\n"
-"          gnokii --getdisplaystatus\n"
-"          gnokii --identify\n\n"
-
-"          gnokii --getwapbookmark location\n"
-"          gnokii --setwapbookmark title url [location]\n"
-"          gnokii --sendwapbookmark location destination\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-s] [-v n] [-d]\n"
-"          gnokii --savewapbookmark location\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
-"          gnokii --getwapsettings location\n"
-"          gnokii --savewapsettings location\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-r] [-i] [-s] [-a] [-l] [--name name]\n"
-"          gnokii --sendwapsettings location destination\n"
-"                 [--smsc message_center_number] [--smscno message_center_index]\n"
-"                 [-s] [-v n] [-d]\n"
-  ));
-
+       fprintf(stdout, _("   usage: gnokii [--help|--monitor|--version]\n"
+                         "          gnokii --getmemory memory_type start [end]\n"
+                         "          gnokii --writephonebook [-i]\n"
+                         "          gnokii --getspeeddial number\n"
+                         "          gnokii --setspeeddial number memory_type location\n"
+                         "          gnokii --getsms memory_type start [end] [-f file] [-F file] [-d]\n"
+                         "          gnokii --deletesms memory_type start [end]\n"
+                         "          gnokii --sendsms destination [-r] [-C n] [-v n]\n"
+                         "                 [--longtext|--longudh] [--udh] [-8]\n"
+                         "                 [--smsc message_center_number | --smscno message_center_index]\n"
+                         "          gnokii --savesms [-m] [-l n] [-i]\n"
+                         "          gnokii --getsmsc message_center_number\n"
+                         "          gnokii --setdatetime [YYYY [MM [DD [HH [MM]]]]]\n"
+                         "          gnokii --getdatetime\n"
+                         "          gnokii --setalarm HH MM\n"
+                         "          gnokii --getalarm\n"
+                         "          gnokii --dialvoice number\n"
+                         "          gnokii --getcalendarnote start [end] [-v]\n"
+                         "          gnokii --writecalendarnote vcardfile number\n"
+                         "          gnokii --deletecalendarnote start [end]\n"
+                         "          gnokii --getdisplaystatus\n"
+                         "          gnokii --netmonitor {reset|off|field|devel|next|nr}\n"
+                         "          gnokii --identify\n"
+                         "          gnokii --senddtmf string\n"
+                         "          gnokii --sendlogo {caller|op} destination logofile [network code]\n"
+                         "                 [--smsc message_center_number | --smscno message_center_index]\n"
+                         "          gnokii --sendringtone destination rtttlfile\n"
+                         "                 [--smsc message_center_number | --smscno message_center_index]\n"
+                         "          gnokii --setlogo op [logofile] [network code]\n"
+                         "          gnokii --setlogo startup [logofile]\n"
+                         "          gnokii --setlogo caller [logofile] [caller group number] [group name]\n"
+                         "          gnokii --setlogo {dealer|text} [text]\n"
+                         "          gnokii --getlogo op [logofile] [network code]\n"
+                         "          gnokii --getlogo startup [logofile] [network code]\n"
+                         "          gnokii --getlogo caller [logofile][caller group number][network code]\n"
+                         "          gnokii --getlogo {dealer|text}\n"
+                         "          gnokii --viewlogo logofile\n"
+                         "          gnokii --setringtone rtttlfile\n"
+                         "          gnokii --reset [soft|hard]\n"
+                         "          gnokii --getprofile [number]\n"
+                         "          gnokii --displayoutput\n"
+                         "          gnokii --keysequence\n"
+               ));
 #ifdef SECURITY
 #ifdef SECURITY
-  fprintf(stdout, _(
-"\n          gnokii --entersecuritycode PIN|PIN2|PUK|PUK2\n"
-"          gnokii --getsecuritycodestatus\n"
-"          gnokii --getsecuritycode PIN|PIN2|PUK|PUK2|SecurityCode\n"
-"          gnokii --geteeprom\n"
-"          gnokii --resetphonesettings\n"
-  ));
-#endif
-
-#ifdef DEBUG
-  fprintf(stdout, _(
-"          gnokii --sniff [port]\n"
-"          gnokii --decodefile file\n"
-  ));
+       fprintf(stdout, _(
+               "          gnokii --entersecuritycode PIN|PIN2|PUK|PUK2\n"
+               "          gnokii --getsecuritycodestatus\n"
+               ));
 #endif
 #endif
-
-  return 0;
+       exit(-1);
 }
 
 /* fbusinit is the generic function which waits for the FBUS link. The limit
    is 10 seconds. After 10 seconds we quit. */
 
 }
 
 /* fbusinit is the generic function which waits for the FBUS link. The limit
    is 10 seconds. After 10 seconds we quit. */
 
+static GSM_Statemachine State;
+static GSM_Data data;
+
 void fbusinit(void (*rlp_handler)(RLP_F96Frame *frame))
 {
 void fbusinit(void (*rlp_handler)(RLP_F96Frame *frame))
 {
+       int count=0;
+       GSM_Error error;
+       GSM_ConnectionType connection=GCT_Serial;
 
 
-  int count=0;
-  GSM_Error error;
+       GSM_DataClear(&data);
 
 
-#ifndef WIN32
-  if (strcmp(GetMygnokiiVersion(),VERSION)!=0)
-    fprintf(stderr,_("WARNING: version of installed libmygnokii.so (%s) is different to version of gnokii (%s)\n"),GetMygnokiiVersion(),VERSION);
-#endif
+       if (!strcmp(Connection, "infrared")) connection=GCT_Infrared;
+       if (!strcmp(Connection, "irda"))     connection=GCT_Irda;
+       if (!strcmp(Connection, "tcp"))      connection=GCT_TCP;
 
 
-  /* Initialise the code for the GSM interface. */     
-  error = GSM_Initialise(model, Port, Initlength, GetConnectionTypeFromString(Connection), rlp_handler, SynchronizeTime);
+       /* Initialise the code for the GSM interface. */     
+
+       error = GSM_Initialise(model, Port, Initlength, connection, rlp_handler, &State);
+
+       if (error != GE_NONE) {
+               fprintf(stderr, _("GSM/FBUS init failed! (Unknown model ?). Quitting.\n"));
+               exit(-1);
+       }
 
 
-  if (error != GE_NONE) {
-    fprintf(stderr, _("GSM/FBUS init failed! (Unknown model ?). Quitting.\n"));
-    exit(-1);
-  }
+       /* First (and important!) wait for GSM link to be active. We allow 10
+          seconds... */
 
 
-  /* First (and important!) wait for GSM link to be active. We allow 10
-     seconds... */
-  while (count++ < 200 && *GSM_LinkOK == false)
-    usleep(50000);
+       while (count++ < 200 && *GSM_LinkOK == false)
+               usleep(50000);
 
 
-  if (*GSM_LinkOK == false) {
-    fprintf (stderr, _("Hmmm... GSM_LinkOK never went true. Quitting.\n"));
-    exit(-1);
-  }  
+       if (*GSM_LinkOK == false) {
+               fprintf (stderr, _("Hmmm... GSM_LinkOK never went true. Quitting.\n"));
+               exit(-1);
+       }
 }
 
 /* This function checks that the argument count for a given options is withing
    an allowed range. */
 }
 
 /* This function checks that the argument count for a given options is withing
    an allowed range. */
-
 int checkargs(int opt, struct gnokii_arg_len gals[], int argc)
 {
 int checkargs(int opt, struct gnokii_arg_len gals[], int argc)
 {
+       int i;
 
 
-  int i;
-
-  /* Walk through the whole array with options requiring arguments. */
-
-  for(i = 0;!(gals[i].gal_min == 0 && gals[i].gal_max == 0); i++) {
-
-    /* Current option. */
-
-    if(gals[i].gal_opt == opt) {
-
-      /* Argument count checking. */
-
-      if(gals[i].gal_flags == GAL_XOR) {
-       if(gals[i].gal_min == argc || gals[i].gal_max == argc) return 0;
-      }
-      else {
-       if(gals[i].gal_min <= argc && gals[i].gal_max >= argc) return 0;
-      }
-
-      return 1;
+       /* Walk through the whole array with options requiring arguments. */
+       for (i = 0; !(gals[i].gal_min == 0 && gals[i].gal_max == 0); i++) {
 
 
-    }
+               /* Current option. */
+               if (gals[i].gal_opt == opt) {
 
 
-  }
+                       /* Argument count checking. */
+                       if (gals[i].gal_flags == GAL_XOR) {
+                               if (gals[i].gal_min == argc || gals[i].gal_max == argc)
+                                       return 0;
+                       } else {
+                               if (gals[i].gal_min <= argc && gals[i].gal_max >= argc)
+                                       return 0;
+                       }
 
 
-  /* We do not have options without arguments in the array, so check them. */
+                       return 1;
+               }
+       }
 
 
-  if (argc==0) return 0;
-          else return 1;
+       /* We do not have options without arguments in the array, so check them. */
+       if (argc == 0) return 0;
+       else return 1;
 }
 
 /* Main function - handles command line arguments, passes them to separate
    functions accordingly. */
 }
 
 /* Main function - handles command line arguments, passes them to separate
    functions accordingly. */
-
 int main(int argc, char *argv[])
 {
 int main(int argc, char *argv[])
 {
+       int c, i, rc = -1;
+       int nargc = argc-2;
+       char **nargv;
 
 
-  int c, i, rc = -1;
-  int nargc = argc-2;
-  char **nargv;
-
-  /* Every option should be in this array. */
-
-  static struct option long_options[] =
-  {
-
-    { "help",               no_argument,       NULL, OPT_HELP             },// Display usage.
-    { "version",            no_argument,       NULL, OPT_VERSION          },// Display version and build information.
-    { "getsmsfolders",      no_argument,       NULL, OPT_GETSMSFOLDERS    },// Gets SMS folders
-    { "getsmsstatus",       no_argument,       NULL, OPT_GETSMSSTATUS     },// Get SMS Folder Status
-    { "identify",           no_argument,       NULL, OPT_IDENTIFY         },// Identify
-    { "pmon",               no_argument,       NULL, OPT_PMON             },// For development purposes: run in passive monitoring mode
-    { "foogle",             no_argument,       NULL, OPT_FOOGLE           },// For development purposes: insert you function calls here
-    { "getdatetime",        no_argument,       NULL, OPT_GETDATETIME      },// Get date and time mode    
-    { "getalarm",           no_argument,       NULL, OPT_GETALARM         },// Get alarm    
-    { "cancelcall",         no_argument,       NULL, OPT_CANCELCALL       },// Cancel Call    
-    { "getdisplaystatus",   no_argument,       NULL, OPT_GETDISPLAYSTATUS },// Get display status mode    
-    { "allringtones",       no_argument,       NULL, OPT_ALLRINGTONES     },/* Displays names of available ringtones */    
-    { "displayoutput",      no_argument,       NULL, OPT_DISPLAYOUTPUT    },/* Show texts from phone's display */
-    { "getphoneprofile",    no_argument,       NULL, OPT_GETPHONEPROFILE  },/* Get/Set phone profile settings */
-    { "getoperatorname",    no_argument,       NULL, OPT_GETOPERATORNAME  },/* Get downloaded operator name */    
-    { "getvoicemailbox",    no_argument,       NULL, OPT_GETVOICEMAILBOX  },/* Gets voice mailbox number */    
-    { "phonetests",         no_argument,       NULL, OPT_PHONETESTS       },
-    { "simlockinfo",        no_argument,       NULL, OPT_SIMLOCKINFO      },    
-    { "receivesms",         no_argument,       NULL, OPT_RECEIVESMS       },    
-    { "setoperatorname",    optional_argument, NULL, OPT_SETOPERATORNAME  },/* Set downloaded operator name */    
-    { "setdatetime",        optional_argument, NULL, OPT_SETDATETIME      },// Set date and time    
-    { "writephonebook",     optional_argument, NULL, OPT_WRITEPHONEBOOK   },// Write phonebook (memory) mode
-    { "reset",              optional_argument, NULL, OPT_RESET            },// Resets the phone
-    { "monitor",            optional_argument, NULL, OPT_MONITOR          },// Monitor mode
-    { "setlogo",            optional_argument, NULL, OPT_SETLOGO          },// Set logo
-    { "getprofile",         optional_argument, NULL, OPT_GETPROFILE       },// Show profile
-    { "setalarm",           required_argument, NULL, OPT_SETALARM         },// Set alarm
-    { "dialvoice",          required_argument, NULL, OPT_DIALVOICE        },// Voice call mode
-    { "getcalendarnote",    required_argument, NULL, OPT_GETCALENDARNOTE  },// Get calendar note mode    
-    { "writecalendarnote",  required_argument, NULL, OPT_WRITECALENDARNOTE},// Write calendar note mode
-    { "sendcalendarnote",   required_argument, NULL, OPT_SENDCALENDARNOTE },
-    { "savecalendarnote",   required_argument, NULL, OPT_SAVECALENDARNOTE },
-    { "sendphonebookentry", required_argument, NULL, OPT_SENDPHONEBOOKENTRY},
-    { "savephonebookentry", required_argument, NULL, OPT_SAVEPHONEBOOKENTRY},
-    { "deletecalendarnote", required_argument, NULL, OPT_DELCALENDARNOTE  },// Delete calendar note mode    
-    { "getmemory",          required_argument, NULL, OPT_GETMEMORY        },// Get memory mode
-    { "getspeeddial",       required_argument, NULL, OPT_GETSPEEDDIAL     },// Get speed dial mode
-    { "setspeeddial",       required_argument, NULL, OPT_SETSPEEDDIAL     },// Set speed dial mode
-    { "getsms",             required_argument, NULL, OPT_GETSMS           },// Get SMS message mode
-    { "deletesms",          required_argument, NULL, OPT_DELETESMS        },// Delete SMS message mode
-    { "sendsms",            required_argument, NULL, OPT_SENDSMS          },// Send SMS message mode
-    { "savesms",            required_argument, NULL, OPT_SAVESMS          },// Save SMS message mode
-    { "sendlogo",           required_argument, NULL, OPT_SENDLOGO         },// Send logo as SMS message mode
-    { "savelogo",           required_argument, NULL, OPT_SAVELOGO         },// Save logo on SIM
-    { "sendringtone",       required_argument, NULL, OPT_SENDRINGTONE     },// Send ringtone as SMS message
-    { "saveringtone",       required_argument, NULL, OPT_SAVERINGTONE     },// Saves ringtone on SIM
-    { "setringtone",        required_argument, NULL, OPT_SETRINGTONE      },// Set ringtone    
-    { "getringtone",        required_argument, NULL, OPT_GETRINGTONE      },// Get bin/normal ringtone    
-    { "presskeysequence",   required_argument, NULL, OPT_PRESSKEYSEQUENCE },/* Presses keys in phone's display */
-    { "getsmsc",            required_argument, NULL, OPT_GETSMSC          },// Get SMS center number mode
-    { "renamesmsc",         required_argument, NULL, OPT_RENAMESMSC       },// Rename SMSC
-    { "netmonitor",         required_argument, NULL, OPT_NETMONITOR       },// NetMonitor mode
-    { "senddtmf",           required_argument, NULL, OPT_SENDDTMF         },// Send DTMF sequence
-    { "getlogo",            required_argument, NULL, OPT_GETLOGO          },// Get logo
-    { "setprofile",         required_argument, NULL, OPT_SETPROFILE       },// Set profile feature
-    { "sendprofile",        required_argument, NULL, OPT_SENDPROFILE      },// Send profile via SMS
-    { "setphoneprofile",    required_argument, NULL, OPT_SETPHONEPROFILE  },/* Get/Set phone profile settings */
-    { "restoresettings",    required_argument, NULL, OPT_RESTORESETTINGS  },//Restore various settings from one file
-    { "backupsettings",     required_argument, NULL, OPT_BACKUPSETTINGS   },//Backup various settings to one file
-    { "playringtone",       required_argument, NULL, OPT_PLAYRINGTONE     },/* Plays ringtones */    
-    { "composer",           required_argument, NULL, OPT_COMPOSER         },/* Shows ringtone like in Nokia Composer */    
-    { "ringtoneconvert",    required_argument, NULL, OPT_RINGTONECONVERT  },/* Convert ringtone files */    
-    { "binringtoneconvert", required_argument, NULL, OPT_BINRINGTONECONVERT},/* Convert binary ringtone files */    
-    { "bitmapconvert",      required_argument, NULL, OPT_BITMAPCONVERT    },/* Convert bitmap files */    
-    { "showbitmap",         required_argument, NULL, OPT_SHOWBITMAP       },    
-    { "nm_collect",         required_argument, NULL, OPT_NM_COLLECT       },// NetMonitor periodical data collection mode (newbiee)
-    { "netmonitordata",     required_argument, NULL, OPT_NETMONITORDATA   },// NetMonitor periodical data collection mode (advanced)
-    { "getwapbookmark",     required_argument, NULL, OPT_GETWAPBOOKMARK   },    
-    { "setwapbookmark",     required_argument, NULL, OPT_SETWAPBOOKMARK   },    
-    { "savewapbookmark",    required_argument, NULL, OPT_SAVEWAPBOOKMARK  },    
-    { "savewapsettings",    required_argument, NULL, OPT_SAVEWAPSETTINGS  },    
-    { "sendwapsettings",    required_argument, NULL, OPT_SENDWAPSETTINGS  },    
-    { "sendwapbookmark",    required_argument, NULL, OPT_SENDWAPBOOKMARK  },    
-    { "getwapsettings",     required_argument, NULL, OPT_GETWAPSETTINGS   },    
-    { "divert",             required_argument, NULL, OPT_DIVERT           },
-
-#ifdef SECURITY
-    { "entersecuritycode",  required_argument, NULL, OPT_ENTERSECURITYCODE    },// Enter Security Code mode
-    { "getsecuritycode",    required_argument, NULL, OPT_GETSECURITYCODE      },// Get Security Code
-  { "getsecuritycodestatus",no_argument,       NULL, OPT_GETSECURITYCODESTATUS},// Get Security Code status
-    { "geteeprom",          no_argument,       NULL, OPT_GETEEPROM            },// Gets EEPROM
-    { "resetphonesettings", no_argument,       NULL, OPT_RESETPHONESETTINGS   },// Reset phone settings
-    { "setsimlock",         no_argument,       NULL, OPT_SETSIMLOCK           },// Sets simlock
-#endif
-
-#ifdef DEBUG
-    { "sniff",              optional_argument, NULL, OPT_SNIFFER    },// Will show datas from port
-    { "decodefile",         required_argument, NULL, OPT_DECODEFILE },//decode input file
-#endif
-
-    { 0, 0, 0, 0},
-  };
+       /* Every option should be in this array. */
+       static struct option long_options[] =
+       {
+               /* FIXME: these comments are nice, but they would be more usefull as docs for the user */
+               // Display usage.
+               { "help",               no_argument,       NULL, OPT_HELP },
 
 
-  /* Every command which requires arguments should have an appropriate entry
-     in this array. */
-       
-  struct gnokii_arg_len gals[] =
-  {
+               // Display version and build information.
+               { "version",            no_argument,       NULL, OPT_VERSION },
 
 
-    { OPT_MONITOR,           0, 1, 0 },
+               // Monitor mode
+               { "monitor",            no_argument,       NULL, OPT_MONITOR },
 
 #ifdef SECURITY
 
 #ifdef SECURITY
-    { OPT_ENTERSECURITYCODE, 1, 1, 0 },
-    { OPT_GETSECURITYCODE,   1, 1, 0 },
-#endif
-
-#ifdef DEBUG
-    { OPT_SNIFFER,           0, 1, 0 },
-    { OPT_DECODEFILE,        1, 1, 0 },
-#endif
 
 
-    { OPT_SETDATETIME,       0, 5, 0 },
-    { OPT_BACKUPSETTINGS,    1, 1, 0 },
-    { OPT_RESTORESETTINGS,   1, 1, 0 },
-    { OPT_SETALARM,          2, 2, 0 },
-    { OPT_DIALVOICE,         1, 1, 0 },
-    { OPT_GETCALENDARNOTE,   1, 3, 0 },
-    { OPT_WRITECALENDARNOTE, 2, 2, 0 },
-    { OPT_SAVECALENDARNOTE,  2, 9, 0 },
-    { OPT_SENDCALENDARNOTE,  3, 9, 0 },
-    { OPT_SAVEPHONEBOOKENTRY,2, 9, 0 },
-    { OPT_SENDPHONEBOOKENTRY,3, 9, 0 },
-    { OPT_DELCALENDARNOTE,   1, 1, 0 },
-    { OPT_GETMEMORY,         2, 4, 0 },
-    { OPT_GETSPEEDDIAL,      1, 1, 0 },
-    { OPT_SETSPEEDDIAL,      3, 3, 0 },
-    { OPT_GETSMS,            2, 5, 0 },
-    { OPT_DELETESMS,         2, 3, 0 },
-    { OPT_SENDSMS,           1,10, 0 },
-    { OPT_SAVESMS,           1,11, 0 },
-    { OPT_SENDLOGO,          3, 9, 0 },
-    { OPT_SAVELOGO,          2,10, 0 },
-    { OPT_SENDRINGTONE,      2, 7, 0 },
-    { OPT_SAVERINGTONE,      1, 9, 0 },
-    { OPT_GETSMSC,           1, 1, 0 },
-    { OPT_RENAMESMSC,        2, 2, 0 },
-    { OPT_NETMONITOR,        1, 1, 0 },
-    { OPT_SENDDTMF,          1, 1, 0 },
-    { OPT_SETLOGO,           1, 5, 0 },
-    { OPT_GETLOGO,           1, 4, 0 },
-    { OPT_SETRINGTONE,       1, 3, 0 },
-    { OPT_GETRINGTONE,       1, 2, 0 },
-    { OPT_PRESSKEYSEQUENCE,  1, 1, 0 },
-    { OPT_RESET,             0, 1, 0 },
-    { OPT_GETPROFILE,        0, 1, 0 },
-    { OPT_SETPROFILE,        3, 3, 0 },
-    { OPT_SENDPROFILE,       4,10, 0 },
-    { OPT_WRITEPHONEBOOK,    0, 1, 0 },
-    { OPT_PLAYRINGTONE,      1, 1, 0 },
-    { OPT_COMPOSER,          1, 1, 0 },
-    { OPT_RINGTONECONVERT,   2, 2, 0 },
-    { OPT_BINRINGTONECONVERT,2, 2, 0 },
-    { OPT_BITMAPCONVERT,     2, 4, 0 },
-    { OPT_SHOWBITMAP,        1, 1, 0 },
-    { OPT_SETOPERATORNAME,   0, 2, 0 },    
-    { OPT_SETPHONEPROFILE,   2, 2, 0 },        
-    { OPT_NM_COLLECT,        1, MAX_NM_COLLECT, 0 },
-    { OPT_NETMONITORDATA,    0,99, 0 },
-    { OPT_GETWAPBOOKMARK,    1, 1, 0 },
-    { OPT_SETWAPBOOKMARK,    2, 3, 0 },
-    { OPT_SAVEWAPBOOKMARK,   1, 9, 0 },
-    { OPT_SENDWAPBOOKMARK,   2, 9, 0 },
-    { OPT_GETWAPSETTINGS,    1, 1, 0 },
-    { OPT_SAVEWAPSETTINGS,   1, 9, 0 },
-    { OPT_SENDWAPSETTINGS,   2, 9, 0 },
-    { OPT_DIVERT,            3, 5, 0 },    
-
-    { 0, 0, 0, 0 },
-  };
-
-  opterr = 0;
-
-  /* For GNU gettext */
+               // Enter Security Code mode
+               { "entersecuritycode",  required_argument, NULL, OPT_ENTERSECURITYCODE },
 
 
-#ifdef USE_NLS
-#ifndef VC6
-  textdomain("gnokii");
-  setlocale(LC_ALL, "pl_PL"); //here is string for Polish localisation
-#else
-  setlocale(LC_ALL, ".852"); //Polish codepage for console, not "real" WIN CP
-#endif
+               // Get Security Code status
+               { "getsecuritycodestatus",  no_argument,   NULL, OPT_GETSECURITYCODESTATUS },
 
 #endif
 
 
 #endif
 
-    /* Read config file */
-    if (CFG_ReadConfig(&model, &Port, &Initlength, &Connection, &BinDir, &SynchronizeTime,false) < 0) {
-       exit(-1);
-    }
-
-  /* Handle command line arguments. */
-
-  c = getopt_long(argc, argv, "", long_options, NULL);
+               // Set date and time
+               { "setdatetime",        optional_argument, NULL, OPT_SETDATETIME },
 
 
-  if (c == -1) {
+               // Get date and time mode
+               { "getdatetime",        no_argument,       NULL, OPT_GETDATETIME },
 
 
-    /* No argument given - we should display usage. */
-    usage();
-    exit(-1);
-  }
+               // Set alarm
+               { "setalarm",           required_argument, NULL, OPT_SETALARM },
 
 
-  /* We have to build an array of the arguments which will be passed to the
-     functions.  Please note that every text after the --command will be
-     passed as arguments.  A syntax like gnokii --cmd1 args --cmd2 args will
-     not work as expected; instead args --cmd2 args is passed as a
-     parameter. */
+               // Get alarm
+               { "getalarm",           no_argument,       NULL, OPT_GETALARM },
 
 
-  if((nargv = malloc(sizeof(char *) * argc)) != NULL) {
+               // Voice call mode
+               { "dialvoice",          required_argument, NULL, OPT_DIALVOICE },
 
 
-    for(i = 2; i < argc; i++)
-      nargv[i-2] = argv[i];
-       
-    if(checkargs(c, gals, nargc)) {
-
-      free(nargv);
+               // Get calendar note mode
+               { "getcalendarnote",    required_argument, NULL, OPT_GETCALENDARNOTE },
 
 
-      /* Wrong number of arguments - we should display usage. */
-      usage();
-      exit(-1);
-    }
-
-#ifndef VC6
-#if defined(__svr4__)
-    /* have to ignore SIGALARM */
-    sigignore(SIGALRM);
-#endif
-#endif
+               // Write calendar note mode
+               { "writecalendarnote",  required_argument, NULL, OPT_WRITECALENDARNOTE },
 
 
-    switch(c) {
+               // Delete calendar note mode
+               { "deletecalendarnote", required_argument, NULL, OPT_DELCALENDARNOTE },
 
 
-    // First, error conditions 
-    case '?':
-      fprintf(stderr, _("Use '%s --help' for usage informations.\n"), argv[0]);
-      break;
-       
-    // Then, options with no arguments
-    case OPT_HELP:                  rc = usage();                   break;
-    case OPT_VERSION:               rc = version();                 break;
-    case OPT_MONITOR:               rc = monitormode(nargc, nargv); break;
-    case OPT_GETSMSFOLDERS:         rc = getsmsfolders();           break;
-    case OPT_GETDATETIME:           rc = getdatetime();             break;
-    case OPT_GETALARM:              rc = getalarm();                break;
-    case OPT_GETDISPLAYSTATUS:      rc = getdisplaystatus();        break;
-    case OPT_PMON:                  rc = pmon();                    break;
-    case OPT_WRITEPHONEBOOK:        rc = writephonebook(nargc, nargv);break;
+               // Get display status mode
+               { "getdisplaystatus",   no_argument,       NULL, OPT_GETDISPLAYSTATUS },
 
 
-#ifdef SECURITY
-    case OPT_ENTERSECURITYCODE:     rc = entersecuritycode(optarg); break;
-    case OPT_GETSECURITYCODESTATUS: rc = getsecuritycodestatus();   break;
-    case OPT_GETSECURITYCODE:       rc = getsecuritycode(optarg);   break;
-    case OPT_GETEEPROM:             rc = geteeprom();               break;
-    case OPT_RESETPHONESETTINGS:    rc = resetphonesettings();      break;
-    case OPT_SETSIMLOCK:            rc = setsimlock();              break;
-#endif
+               // Get memory mode
+               { "getmemory",          required_argument, NULL, OPT_GETMEMORY },
 
 
-#ifdef DEBUG
-    case OPT_SNIFFER:               rc = sniff(nargc, nargv);       break;
-    case OPT_DECODEFILE:            rc = decodefile(nargc, nargv);  break;
-#endif                                 
-       
-    // Now, options with arguments
-    case OPT_SETDATETIME:           rc = setdatetime(nargc, nargv); break;
-    case OPT_SETALARM:              rc = setalarm(nargv);           break;
-    case OPT_DIALVOICE:             rc = dialvoice(optarg);         break;
-    case OPT_CANCELCALL:            rc = cancelcall();              break;
-    case OPT_GETCALENDARNOTE:       rc = getcalendarnote(nargc, nargv);break;
-    case OPT_DELCALENDARNOTE:       rc = deletecalendarnote(optarg);break;
-    case OPT_SAVECALENDARNOTE:      rc = savecalendarnote(nargc, nargv);break;
-    case OPT_SENDCALENDARNOTE:      rc = sendcalendarnote(nargc, nargv);break;
-    case OPT_SAVEPHONEBOOKENTRY:    rc = savephonebookentry(nargc, nargv);break;
-    case OPT_SENDPHONEBOOKENTRY:    rc = sendphonebookentry(nargc, nargv);break;
-    case OPT_WRITECALENDARNOTE:     rc = writecalendarnote(nargv);  break;
-    case OPT_GETMEMORY:             rc = getmemory(nargc, nargv);   break;
-    case OPT_GETSPEEDDIAL:          rc = getspeeddial(optarg);      break;
-    case OPT_SETSPEEDDIAL:          rc = setspeeddial(nargv);       break;
-    case OPT_GETSMS:                rc = getsms(argc, argv);        break;
-    case OPT_GETSMSSTATUS:          rc = getsmsstatus(argc, argv);  break;
-    case OPT_DELETESMS:             rc = deletesms(nargc, nargv);   break;
-    case OPT_SENDSMS:               rc = sendsms(nargc, nargv);     break;
-    case OPT_SAVESMS:               rc = savesms(nargc, nargv);     break;
-    case OPT_DIVERT:                rc = divert(nargc, nargv);      break;
-    case OPT_SENDLOGO:              rc = sendlogo(nargc, nargv);    break;
-    case OPT_SAVELOGO:              rc = savelogo(nargc, nargv);    break;
-    case OPT_GETSMSC:               rc = getsmsc(optarg);           break;
-    case OPT_RENAMESMSC:            rc = renamesmsc(nargc,nargv);   break;
-    case OPT_NETMONITOR:            rc = netmonitor(optarg);        break;
-    case OPT_IDENTIFY:              rc = identify();                break;
-    case OPT_SETLOGO:               rc = setlogo(nargc, nargv);     break;
-    case OPT_GETLOGO:               rc = getlogo(nargc, nargv);     break;
-    case OPT_RECEIVESMS:            rc = receivesms(nargc, nargv);  break;
-    case OPT_SETRINGTONE:           rc = setringtone(nargc, nargv); break;
-    case OPT_GETRINGTONE:           rc = getringtone(nargc, nargv); break;
-    case OPT_PRESSKEYSEQUENCE:      rc = presskeysequence(nargv);   break;
-    case OPT_SENDRINGTONE:          rc = sendringtone(nargc, nargv);break;
-    case OPT_SAVERINGTONE:          rc = saveringtone(nargc, nargv);break;
-    case OPT_GETPROFILE:            rc = getprofile(nargc, nargv);  break;
-    case OPT_SETPROFILE:            rc = setprofile(nargc, nargv);  break;
-    case OPT_SENDPROFILE:           rc = sendprofile(nargc, nargv); break;
-    case OPT_DISPLAYOUTPUT:         rc = displayoutput();           break;
-    case OPT_RESTORESETTINGS:       rc = restoresettings(nargv);    break;
-    case OPT_BACKUPSETTINGS:        rc = backupsettings(nargv);     break;
-    case OPT_RINGTONECONVERT:       rc = ringtoneconvert(nargc, nargv);break;
-    case OPT_BINRINGTONECONVERT:    rc = binringtoneconvert(nargc, nargv);break;
-    case OPT_BITMAPCONVERT:         rc = bitmapconvert(nargc, nargv);break;
-    case OPT_SHOWBITMAP:            rc = showbitmap(nargc, nargv);  break;
-    case OPT_PLAYRINGTONE:          rc = playringtone(nargc, nargv);break;
-    case OPT_COMPOSER:              rc = composer(nargc, nargv);    break;
-    case OPT_FOOGLE:                rc = foogle(nargv);             break;
-    case OPT_PHONETESTS:            rc = phonetests();              break;
-    case OPT_SIMLOCKINFO:           rc = simlockinfo();             break;
-    case OPT_SENDDTMF:              rc = senddtmf(optarg);          break;
-    case OPT_RESET:                 rc = reset(nargc,nargv);        break;
-    case OPT_GETOPERATORNAME:       rc = getoperatorname();         break;
-    case OPT_SETOPERATORNAME:       rc = setoperatorname(nargc,nargv);break;
-    case OPT_GETWAPBOOKMARK:        rc = getwapbookmark(nargc,nargv);break;
-    case OPT_SETWAPBOOKMARK:        rc = setwapbookmark(nargc,nargv);break;
-    case OPT_SAVEWAPBOOKMARK:       rc = savewapbookmark(nargc,nargv);break;
-    case OPT_SENDWAPBOOKMARK:       rc = sendwapbookmark(nargc,nargv);break;
-    case OPT_GETWAPSETTINGS:        rc = getwapsettings(nargc,nargv);break;
-    case OPT_SAVEWAPSETTINGS:       rc = savewapsettings(nargc,nargv);break;
-    case OPT_SENDWAPSETTINGS:       rc = sendwapsettings(nargc,nargv);break;
-    case OPT_ALLRINGTONES:          rc = allringtones();            break;
-    case OPT_GETPHONEPROFILE:       rc = getphoneprofile();         break;
-    case OPT_SETPHONEPROFILE:       rc = setphoneprofile(nargc,nargv);break;
-    case OPT_GETVOICEMAILBOX:       rc = getvoicemailbox();         break;
-    case OPT_NM_COLLECT:            rc = nm_collect(nargc, nargv);  break;
-    case OPT_NETMONITORDATA:        rc = netmonitordata(nargc, nargv);break;
-
-    default:         fprintf(stderr, _("Unknown option: %d\n"), c); break;
-
-    }
-
-    free(nargv);
-
-    return(rc);
-  }
-
-  fprintf(stderr, _("Wrong number of arguments\n"));
-
-  exit(-1);
-}
+               // Write phonebook (memory) mode
+               { "writephonebook",     optional_argument, NULL, OPT_WRITEPHONEBOOK },
 
 
-/* Restores various phone settings from one file */
-int restoresettings(char *argv[])
-{
-  fprintf(stdout,_("Work in progress. Not usefull now. Sorry\n"));
-  return 0;
-}
+               // Get speed dial mode
+               { "getspeeddial",       required_argument, NULL, OPT_GETSPEEDDIAL },
 
 
-/* Backup various phone settings from one file */
-int backupsettings(char *argv[])
-{
-  GSM_PhonebookEntry PbkEntry;
-  GSM_Error error;
-  GSM_Backup Backup;
-  int i;
+               // Set speed dial mode
+               { "setspeeddial",       required_argument, NULL, OPT_SETSPEEDDIAL },
 
 
-  GSM_MemoryStatus SIMMemoryStatus = {GMT_SM, 0, 0};
-  GSM_MemoryStatus PhoneMemoryStatus = {GMT_ME, 0, 0};
+               // Get SMS message mode
+               { "getsms",             required_argument, NULL, OPT_GETSMS },
 
 
-  fbusinit(NULL);
+               // Delete SMS message mode
+               { "deletesms",          required_argument, NULL, OPT_DELETESMS },
 
 
-  fprintf(stderr,_("Backup phonebook from SIM..."));
-  Backup.SIMPhonebookUsed=0;
-  if (GSM->GetMemoryStatus(&SIMMemoryStatus) == GE_NONE) {//FIXME
-    Backup.SIMPhonebookSize=SIMMemoryStatus.Used+SIMMemoryStatus.Free;
+               // Send SMS message mode
+               { "sendsms",            required_argument, NULL, OPT_SENDSMS },
 
 
-    PbkEntry.MemoryType=GMT_SM;
+               // Save SMS message mode
+               { "savesms",            optional_argument, NULL, OPT_SAVESMS },
 
 
-    for (i=0;i<Backup.SIMPhonebookSize;i++)
-    {
-      if (SIMMemoryStatus.Used==Backup.SIMPhonebookUsed) break;
+               // Send logo as SMS message mode
+               { "sendlogo",           required_argument, NULL, OPT_SENDLOGO },
 
 
-      PbkEntry.Location=i;
-    
-      error=GSM->GetMemoryLocation(&PbkEntry);
-      switch (error) {
-        case GE_NONE:
-          Backup.SIMPhonebook[Backup.SIMPhonebookUsed]=PbkEntry;
-          Backup.SIMPhonebookUsed++;
-          fprintf(stderr,_("."));
-          break;
-        default:
-          break;
-      }
-    }
-    fprintf(stderr,_("Done\n"));
-  } else fprintf(stderr,_("ERROR\n"));
-
-  fprintf(stderr,_("Backup phonebook from phone..."));
-  Backup.PhonePhonebookUsed=0;
-  if (GSM->GetMemoryStatus(&PhoneMemoryStatus) == GE_NONE) {
-    Backup.PhonePhonebookSize=PhoneMemoryStatus.Used+PhoneMemoryStatus.Free;
-
-    PbkEntry.MemoryType=GMT_ME;
-
-    for (i=0;i<Backup.PhonePhonebookSize;i++)
-    {
-      if (PhoneMemoryStatus.Used==Backup.PhonePhonebookUsed) break;
-
-      PbkEntry.Location=i;
-    
-      error=GSM->GetMemoryLocation(&PbkEntry);
-      switch (error) {
-        case GE_NONE:
-          Backup.PhonePhonebook[Backup.PhonePhonebookUsed]=PbkEntry;
-          Backup.PhonePhonebookUsed++;
-          fprintf(stderr,_("."));
-          break;
-        default:
-          break;
-      }
-    }
-    fprintf(stderr,_("Done\n"));
-  } else fprintf(stderr,_("ERROR\n"));
-
-  if( GetModelFeature (FN_CALLERGROUPS)!=0) {
-    fprintf(stderr,_("Backup caller logos..."));
-    Backup.CallerAvailable=true;
-    for (i=0;i<5;i++) {
-      Backup.CallerGroups[i].number=i;
-      Backup.CallerGroups[i].type=GSM_CallerLogo;
-      if (GSM->GetBitmap(&Backup.CallerGroups[i])!=GE_NONE) return 1;
-    }
-    fprintf(stderr,_("Done\n"));
-  } else Backup.CallerAvailable=false;
-
-//  fprintf(stderr,_("Backup speed dials..."));
-  Backup.SpeedAvailable=false;
-//  for (i=0;i<8;i++) {
-//    Backup.SpeedDials[i].Number=i+1;
-//    if (GSM->GetSpeedDial(&Backup.SpeedDials[i])!=GE_NONE) return 1;
-//  }
-//  fprintf(stderr,_("Done\n"));
-
-  fprintf(stderr,_("Backup operator logo..."));
-  Backup.OperatorLogoAvailable=true;
-  Backup.OperatorLogo.type=GSM_7110OperatorLogo;
-  if (GSM->GetBitmap(&Backup.OperatorLogo)!=GE_NONE) {
-    Backup.OperatorLogoAvailable=true;
-    Backup.OperatorLogo.type=GSM_OperatorLogo;
-    if (GSM->GetBitmap(&Backup.OperatorLogo)!=GE_NONE) {
-      Backup.OperatorLogoAvailable=false;
-      fprintf(stderr,_("Error\n"));
-    } else fprintf(stderr,_("Done\n"));
-  } else fprintf(stderr,_("Done\n"));
-
-  Backup.StartupLogoAvailable=false;
-  if( GetModelFeature (FN_STARTUP)!=0) {
-    fprintf(stderr,_("Backup startup logo..."));
-    Backup.StartupLogoAvailable=true;
-    switch (GetModelFeature (FN_STARTUP)) {
-      case F_STA62: Backup.StartupLogo.type=GSM_6210StartupLogo;break;
-      case F_STA71: Backup.StartupLogo.type=GSM_7110StartupLogo;break;
-      default     : Backup.StartupLogo.type=GSM_StartupLogo;break;
-    }
-    if (GSM->GetBitmap(&Backup.StartupLogo)!=GE_NONE) {
-      Backup.StartupLogoAvailable=false;
-      fprintf(stderr,_("Error\n"));
-    } else fprintf(stderr,_("Done\n"));
-  }
-
-  fprintf(stderr,_("Backup welcome note..."));
-  Backup.StartupText.type=GSM_WelcomeNoteText;
-  if (GSM->GetBitmap(&Backup.StartupText)!=GE_NONE) {
-    fprintf(stderr,_("Error\n"));
-  } else fprintf(stderr,_("Done\n"));
-
-  GSM->Terminate();
-
-  GSM_SaveBackupFile(argv[0], &Backup);
-
-  return 0;
-}
+               // Send ringtone as SMS message
+               { "sendringtone",       required_argument, NULL, OPT_SENDRINGTONE },
 
 
-/* Presses keys on phone's keyboard */
+               // Set ringtone
+               { "setringtone",        required_argument, NULL, OPT_SETRINGTONE },
 
 
-int presskeysequence(char *argv[])
-{
-  int i,j;
-  int keycode;
-  char key;
-  
-  sleep(1);
+               // Get SMS center number mode
+               { "getsmsc",            required_argument, NULL, OPT_GETSMSC },
 
 
-  /* We need to make sure that the init is finished to avoid interrupted */
-  /* multiframe packets... */
+               // For development purposes: run in passive monitoring mode
+               { "pmon",               no_argument,       NULL, OPT_PMON },
 
 
-  fbusinit(NULL);
-  
-  for (i=0;i<strlen(argv[0]);i++)
-  {
-    key=argv[0][i];
-    keycode=0;
-    j=0;
-    
-    if (key!='w' && key!='W')
-    {
-      while (Keys[j].whatchar!=' ') {
-        if (Keys[j].whatchar==key) {    
-          keycode=Keys[j].whatcode;
-          break;
-        }
-        j++;
-      }
-    
-      if (keycode==0) {
-        fprintf(stderr,_("Unknown key: %c !\n"),key);
-        GSM->Terminate();
-        return -1;
-      }
-    
-      if (GSM->PressKey(keycode,PRESSPHONEKEY)!=GE_NONE)
-      {
-        fprintf(stderr,_("Can't press key !\n"));
-        GSM->Terminate();
-        return -1;
-      }
-      if (GSM->PressKey(keycode,RELEASEPHONEKEY)!=GE_NONE)
-      {
-        fprintf(stderr,_("Can't release key !\n"));
-        GSM->Terminate();
-        return -1;
-      }
-    } else
-    {
-      sleep(2);
-    }
-  }
-  
-  GSM->Terminate();
+               // NetMonitor mode
+               { "netmonitor",         required_argument, NULL, OPT_NETMONITOR },
 
 
-  return 0;
-}
+               // Identify
+               { "identify",           no_argument,       NULL, OPT_IDENTIFY },
 
 
-/* Send  SMS messages. */
-int sendsms(int argc, char *argv[])
-{
-  GSM_MultiSMSMessage MultiSMS;
-  char message_buffer[GSM_MAX_CONCATENATED_SMS_LENGTH];
-  int input_len, chars_read,i,msgnum;
-
-  GSM_SMSMessageType SMSType=GST_SMS;
-  int SMSValidity= 4320; /* 4320 minutes == 72 hours */
-  bool SMSReply=false;
-  int SMSClass=-1,SMSCenter=1;
-  char SMSCNumber[100];
-  GSM_Coding_Type SMSCoding=GSM_Coding_Default;
-  GSM_UDH SMSUDHType=GSM_NoUDH;
-
-  struct option options[] = {
-             { "smscno",       required_argument, NULL, '1'},
-             { "smsc",         required_argument, NULL, '2'},
-             { "long",        required_argument, NULL, '3'},
-             { "enablevoice",  no_argument,       NULL, '4'},
-            { "disablevoice", no_argument,       NULL, '5'},
-            { "enableemail",  no_argument,       NULL, '6'},
-            { "disableemail", no_argument,       NULL, '7'},
-            { "enablefax",    no_argument,       NULL, '8'},
-            { "disablefax",   no_argument,       NULL, '9'},
-            { "unicode",      no_argument,       NULL, '-'},
-            { "void",         no_argument,       NULL, '+'},
-            { "hang",         no_argument,       NULL, '('},
-            { "bug",          no_argument,       NULL, ')'},
-             { NULL,           0,                 NULL, 0}
-  };
-  
-  input_len = GSM_MAX_SMS_LENGTH;
-
-  if (argc!=0) {
-
-    optarg = NULL;
-    optind = 0;
-
-    while ((i = getopt_long(argc, argv, "v:dsC:", options, NULL)) != -1) {
-      switch (i) {
-
-        case '1': /* SMSC number */
-          SMSCenter = 0;
-          strcpy(SMSCNumber,optarg);
-          break;
-
-        case '2': /* SMSC number index in phone memory */
-          SMSCenter = atoi(optarg);
-
-          if (SMSCenter < 1 || SMSCenter > 5) {
-            fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
-            GSM->Terminate();
-            return -1;
-         }
-          break;
-
-        case '3': /* we send long message */
-          SMSUDHType=GSM_ConcatenatedMessages;
-          input_len = atoi(optarg);
-          if (input_len > GSM_MAX_CONCATENATED_SMS_LENGTH) {
-           fprintf(stderr, _("Input too long, max %i!\n"),GSM_MAX_CONCATENATED_SMS_LENGTH);
-           exit(-1);
-          }
-          break;
-
-        case '4': /* SMS enables voice indicator */
-          SMSUDHType=GSM_EnableVoice;    break;
-
-        case '5': /* SMS disables voice indicator */
-          SMSUDHType=GSM_DisableVoice;   break;          
-
-        case '6': /* SMS enables email indicator */
-          SMSUDHType=GSM_EnableEmail;    break;          
-
-        case '7': /* SMS disables email indicator */
-          SMSUDHType=GSM_DisableEmail;   break;          
-
-        case '8': /* SMS enables fax indicator */
-          SMSUDHType=GSM_EnableFax;      break;          
-
-        case '9': /* SMS disables fax indicator */
-          SMSUDHType=GSM_DisableFax;     break;          
-
-        case '-': /* SMS coding type */
-          SMSCoding=GSM_Coding_Unicode;  break;
-
-        case '+': /* SMS ghost */
-          SMSUDHType=GSM_VoidSMS;        break;
-
-        case '(': /* SMS hanging phone, when saved to Outbox */
-          SMSUDHType=GSM_HangSMS;        break;
-
-        case ')': /* SMS showed incorrectly in phone */
-          SMSUDHType=GSM_BugSMS;         break;
-
-        case 'v': /* Set validaty of SMS */
-          SMSValidity = atoi(optarg);    break;
-
-        case 'd': /* delivery report */
-          SMSType=GST_DR;                break;        
-
-        case 's': /* Set replying via the same SMSC */
-          SMSReply = true;               break;
-
-        case 'C': /* class Message */
-          
-         if (SMSUDHType!=GSM_NoUDH) {
-            fprintf(stderr, _("Can't specify SMS Class with --enablevoice, --disablevoice, --enableemail, --disableemail, --enablefax, --disablefax options !\n"));        
-           return -1;
-         }
-         
-          switch (*optarg) {
-            case '0': SMSClass = 0; break;
-            case '1': SMSClass = 1; break;
-            case '2': SMSClass = 2; break;
-            case '3': SMSClass = 3; break; 
-            default:
-             fprintf(stderr, _("SMS Class (\"C\" option) can be 0, 1, 2 or 3 only !\n"));
-              return -1;
-          }
-          break;
-         
-        default:
-          fprintf(stderr,_("Unknown option number %i\n"),argc);
-          return -1;
-      }
-    }
-  }
-  
-  /* Get message text from stdin. */
-  chars_read = fread(message_buffer, 1, input_len, stdin);
-
-  if (chars_read == 0) {
-    fprintf(stderr, _("Couldn't read from stdin!\n")); 
-    return -1;
-  }
-  if (chars_read > input_len) {
-    fprintf(stderr, _("Input too long!\n"));   
-    return -1;
-  }
-  
-  /*  Null terminate. */
-  message_buffer[chars_read] = 0x00;   
-
-  GSM_MakeMultiPartSMS2(&MultiSMS,message_buffer,chars_read,SMSUDHType,SMSCoding);
-  msgnum=MultiSMS.number;
-
-  switch (SMSUDHType) {
-    case GSM_NoUDH:
-    case GSM_BugSMS:
-    case GSM_VoidSMS:
-    case GSM_HangSMS:
-    case GSM_EnableVoice:
-    case GSM_DisableVoice:
-    case GSM_EnableFax:
-    case GSM_DisableFax:
-    case GSM_EnableEmail:
-    case GSM_DisableEmail:
-      fprintf(stdout,_("Warning: saving %i chars\n"),strlen(MultiSMS.SMS[0].MessageText));
-      msgnum=1;
-      break;
-    default:
-      break;
-  }
-
-  for (i=0;i<msgnum;i++) {
-    strcpy(MultiSMS.SMS[i].Destination,argv[0]);
-
-    MultiSMS.SMS[i].Class=SMSClass;
-    MultiSMS.SMS[i].ReplyViaSameSMSC=SMSReply;
-    MultiSMS.SMS[i].Type=SMSType;
-    MultiSMS.SMS[i].Validity=SMSValidity;
-  }
-
-  /* Initialise the GSM interface. */     
-  fbusinit(NULL);
-
-  MultiSMS.number=msgnum;
-  GSM_SendMultiPartSMSOnConsole(&MultiSMS, 0,0,NULL,false,false,false);
-  
-  return 0;
-}
+               // Send DTMF sequence
+               { "senddtmf",           required_argument, NULL, OPT_SENDDTMF },
 
 
-int savesms(int argc, char *argv[])
-{
-  GSM_MultiSMSMessage MultiSMS;
-  char message_buffer[GSM_MAX_CONCATENATED_SMS_LENGTH];
-  int input_len, chars_read,i,msgnum;
-
-  int SMSClass=-1,SMSCenter=1;
-  char SMSName[25+1];
-  char SMSCNumber[100];
-  GSM_Coding_Type SMSCoding=GSM_Coding_Default;
-  GSM_UDH SMSUDHType=GSM_NoUDH;
-  GSM_SMSMessageStatus SMSStatus;
-  int SMSFolder;
-  bool SMSReply=false;
-  int SMSLocation=0;
-  bool interactive=false;
-
-  struct option options[] = {
-             { "smscno",       required_argument, NULL, '1'},
-             { "smsc",         required_argument, NULL, '2'},
-             { "long",        required_argument, NULL, '3'},
-             { "enablevoice",  no_argument,       NULL, '4'},
-            { "disablevoice", no_argument,       NULL, '5'},
-            { "enableemail",  no_argument,       NULL, '6'},
-            { "disableemail", no_argument,       NULL, '7'},
-            { "enablefax",    no_argument,       NULL, '8'},
-            { "disablefax",   no_argument,       NULL, '9'},
-            { "unicode",      no_argument,       NULL, '-'},
-            { "void",         no_argument,       NULL, '+'},
-            { "hang",         no_argument,       NULL, '('},
-            { "bug",          no_argument,       NULL, ')'},
-            { "smsname",      required_argument, NULL, '/'},
-             { NULL,           0,                 NULL, 0}
-  };
-
-  SMSCNumber[0]=0;
-  SMSName[0]=0;
-  SMSStatus=GSS_NOTSENTREAD;
-  SMSFolder=GST_OUTBOX;
-  
-  input_len = GSM_MAX_SMS_LENGTH;
+               // Resets the phone
+               { "reset",              optional_argument, NULL, OPT_RESET },
 
 
-  if (argc!=0) {
+               // Set logo
+               { "setlogo",            optional_argument, NULL, OPT_SETLOGO },
 
 
-    optarg = NULL;
-    optind = 0;
+               // Get logo
+               { "getlogo",            required_argument, NULL, OPT_GETLOGO },
 
 
-    while ((i = getopt_long(argc, argv, "risal:C:F:", options, NULL)) != -1) {
-      switch (i) {
+               // View logo
+               { "viewlogo",           required_argument, NULL, OPT_VIEWLOGO },
 
 
-        case '1': /* SMSC number */
-          SMSCenter = 0;
-          strcpy(SMSCNumber,optarg);
-          break;
+               // Show profile
+               { "getprofile",         optional_argument, NULL, OPT_GETPROFILE },
 
 
-        case '2': /* SMSC number index in phone memory */
-          SMSCenter = atoi(optarg);
+               // Show texts from phone's display
+               { "displayoutput",      no_argument,       NULL, OPT_DISPLAYOUTPUT },
 
 
-          if (SMSCenter < 1 || SMSCenter > 5) {
-            fprintf(stderr, _("Incorrect SMSC number with \"smscno\" option (can't be <1 and >5) !\n"));
-            GSM->Terminate();
-            return -1;
-         }
-          break;
+               // Simulate pressing the keys
+               { "keysequence",        no_argument,       NULL, OPT_KEYPRESS },
+    
+               // For development purposes: insert you function calls here
+               { "foogle",             no_argument,       NULL, OPT_FOOGLE },
 
 
-        case '3': /* we send long message */
-          SMSUDHType=GSM_ConcatenatedMessages;
-          input_len = atoi(optarg);
-          if (input_len > GSM_MAX_CONCATENATED_SMS_LENGTH) {
-           fprintf(stderr, _("Input too long, max %i!\n"),GSM_MAX_CONCATENATED_SMS_LENGTH);
-           exit(-1);
-          }
-          break;
+               { 0, 0, 0, 0},
+       };
 
 
-        case '4': /* SMS enables voice indicator */
-          SMSUDHType=GSM_EnableVoice;    break;
+       /* Every command which requires arguments should have an appropriate entry
+          in this array. */
+       struct gnokii_arg_len gals[] =
+       {
 
 
-        case '5': /* SMS disables voice indicator */
-          SMSUDHType=GSM_DisableVoice;   break;          
+#ifdef SECURITY
+               { OPT_ENTERSECURITYCODE, 1, 1, 0 },
+#endif
 
 
-        case '6': /* SMS enables email indicator */
-          SMSUDHType=GSM_EnableEmail;    break;          
+               { OPT_SETDATETIME,       0, 5, 0 },
+               { OPT_SETALARM,          2, 2, 0 },
+               { OPT_DIALVOICE,         1, 1, 0 },
+               { OPT_GETCALENDARNOTE,   1, 3, 0 },
+               { OPT_WRITECALENDARNOTE, 2, 2, 0 },
+               { OPT_DELCALENDARNOTE,   1, 2, 0 },
+               { OPT_GETMEMORY,         2, 3, 0 },
+               { OPT_GETSPEEDDIAL,      1, 1, 0 },
+               { OPT_SETSPEEDDIAL,      3, 3, 0 },
+               { OPT_GETSMS,            2, 5, 0 },
+               { OPT_DELETESMS,         2, 3, 0 },
+               { OPT_SENDSMS,           1, 10, 0 },
+               { OPT_SAVESMS,           0, 6, 0 },
+               { OPT_SENDLOGO,          3, 6, 0 },
+               { OPT_SENDRINGTONE,      2, 6, 0 },
+               { OPT_GETSMSC,           1, 1, 0 },
+               { OPT_GETWELCOMENOTE,    1, 1, 0 },
+               { OPT_SETWELCOMENOTE,    1, 1, 0 },
+               { OPT_NETMONITOR,        1, 1, 0 },
+               { OPT_SENDDTMF,          1, 1, 0 },
+               { OPT_SETLOGO,           1, 4, 0 },
+               { OPT_GETLOGO,           1, 4, 0 },
+               { OPT_VIEWLOGO,          1, 1, 0 },
+               { OPT_SETRINGTONE,       1, 1, 0 },
+               { OPT_RESET,             0, 1, 0 },
+               { OPT_GETPROFILE,        0, 1, 0 },
+               { OPT_WRITEPHONEBOOK,    0, 1, 0 },
+
+               { 0, 0, 0, 0 },
+       };
+
+       opterr = 0;
+
+       /* For GNU gettext */
+#ifdef USE_NLS
+       textdomain("gnokii");
+       setlocale(LC_ALL, "");
+#endif
 
 
-        case '7': /* SMS disables email indicator */
-          SMSUDHType=GSM_DisableEmail;   break;          
+       /* Read config file */
+       if (readconfig(&model, &Port, &Initlength, &Connection, &BinDir) < 0) {
+               exit(-1);
+       }
 
 
-        case '8': /* SMS enables fax indicator */
-          SMSUDHType=GSM_EnableFax;      break;          
+       /* Handle command line arguments. */
+       c = getopt_long(argc, argv, "", long_options, NULL);
+       if (c == -1)            /* No argument given - we should display usage. */
+               usage();
 
 
-        case '9': /* SMS disables fax indicator */
-          SMSUDHType=GSM_DisableFax;     break;          
+       switch(c) {
+       // First, error conditions
+       case '?':
+       case ':':
+               fprintf(stderr, _("Use '%s --help' for usage informations.\n"), argv[0]);
+               exit(0);
+       // Then, options with no arguments
+       case OPT_HELP:
+               usage();
+       case OPT_VERSION:
+               return version();
+       }
+       
+       /* We have to build an array of the arguments which will be passed to the
+          functions.  Please note that every text after the --command will be
+          passed as arguments.  A syntax like gnokii --cmd1 args --cmd2 args will
+          not work as expected; instead args --cmd2 args is passed as a
+          parameter. */
+       if ((nargv = malloc(sizeof(char *) * argc)) != NULL) {
+               for (i = 2; i < argc; i++)
+                       nargv[i-2] = argv[i];
+       
+               if (checkargs(c, gals, nargc)) {
+                       free(nargv); /* Wrong number of arguments - we should display usage. */
+                       usage();
+               }
 
 
-        case '-': /* SMS coding type */
-          SMSCoding=GSM_Coding_Unicode;  break;
+#ifdef __svr4__
+               /* have to ignore SIGALARM */
+               sigignore(SIGALRM);
+#endif
 
 
-        case '+': /* SMS ghost */
-          SMSUDHType=GSM_VoidSMS;        break;
+               /* Initialise the code for the GSM interface. */     
+               fbusinit(NULL);
 
 
-        case '(': /* SMS hanging phone, when saved to Outbox */
-          SMSUDHType=GSM_HangSMS;        break;
+               switch(c) {
+               case OPT_MONITOR:
+                       rc = monitormode();
+                       break;
+#ifdef SECURITY
+               case OPT_ENTERSECURITYCODE:
+                       rc = entersecuritycode(optarg);
+                       break;
+               case OPT_GETSECURITYCODESTATUS:
+                       rc = getsecuritycodestatus();
+                       break;
+#endif
+               case OPT_GETDATETIME:
+                       rc = getdatetime();
+                       break;
+               case OPT_GETALARM:
+                       rc = getalarm();
+                       break;
+               case OPT_GETDISPLAYSTATUS:
+                       rc = getdisplaystatus();
+                       break;
+               case OPT_PMON:
+                       rc = pmon();
+                       break;
+               case OPT_WRITEPHONEBOOK:
+                       rc = writephonebook(nargc, nargv);
+                       break;
+               // Now, options with arguments
+               case OPT_SETDATETIME:
+                       rc = setdatetime(nargc, nargv);
+                       break;
+               case OPT_SETALARM:
+                       rc = setalarm(nargv);
+                       break;
+               case OPT_DIALVOICE:
+                       rc = dialvoice(optarg);
+                       break;
+               case OPT_GETCALENDARNOTE:
+                       rc = getcalendarnote(nargc, nargv);
+                       break;
+               case OPT_DELCALENDARNOTE:
+                       rc = deletecalendarnote(nargc, nargv);
+                       break;
+               case OPT_WRITECALENDARNOTE:
+                       rc = writecalendarnote(nargv);
+                       break;
+               case OPT_GETMEMORY:
+                       rc = getmemory(nargc, nargv);
+                       break;
+               case OPT_GETSPEEDDIAL:
+                       rc = getspeeddial(optarg);
+                       break;
+               case OPT_SETSPEEDDIAL:
+                       rc = setspeeddial(nargv);
+                       break;
+               case OPT_GETSMS:
+                       rc = getsms(argc, argv);
+                       break;
+               case OPT_DELETESMS:
+                       rc = deletesms(nargc, nargv);
+                       break;
+               case OPT_SENDSMS:
+                       rc = sendsms(nargc, nargv);
+                       break;
+               case OPT_SAVESMS:
+                       rc = savesms(argc, argv);
+                       break;
+               case OPT_SENDLOGO:
+                       rc = sendlogo(nargc, nargv);
+                       break;
+               case OPT_GETSMSC:
+                       rc = getsmsc(optarg);
+                       break;
+               case OPT_NETMONITOR:
+                       rc = netmonitor(optarg);
+                       break;
+               case OPT_IDENTIFY:
+                       rc = identify();
+                       break;
+               case OPT_SETLOGO:
+                       rc = setlogo(nargc, nargv);
+                       break;
+               case OPT_GETLOGO:
+                       rc = getlogo(nargc, nargv);
+                       break;
+               case OPT_VIEWLOGO:
+                       rc = viewlogo(optarg);
+                       break;
+               case OPT_SETRINGTONE:
+                       rc = setringtone(nargc, nargv);
+                       break;
+               case OPT_SENDRINGTONE:
+                       rc = sendringtone(argc, argv);
+                       break;
+               case OPT_GETPROFILE:
+                       rc = getprofile(nargc, nargv);
+                       break;
+               case OPT_DISPLAYOUTPUT:
+                       rc = displayoutput();
+                       break;
+               case OPT_KEYPRESS:
+                       rc = presskeysequence();
+                       break;
+#ifndef WIN32
+               case OPT_FOOGLE:
+                       rc = foogle(nargv);
+                       break;
+#endif
+               case OPT_SENDDTMF:
+                       rc = senddtmf(optarg);
+                       break;
+               case OPT_RESET:
+                       rc = reset(optarg);
+                       break;
+               default:
+                       fprintf(stderr, _("Unknown option: %d\n"), c);
+                       break;
 
 
-        case ')': /* SMS showed incorrectly in phone */
-          SMSUDHType=GSM_BugSMS;         break;
+               }
+               return(rc);
+       }
 
 
-        case 'r': /* mark as read */
-          SMSStatus = GSS_SENTREAD; break;
-        case 'i': /* Save into Inbox */
-          SMSFolder = GST_INBOX; break;
-         
-        case 's': /* Set replying via the same SMSC */
-          SMSReply = true; break;
-
-        case 'a': /* Ask before overwriting */
-          interactive=true;break;     
-       
-        case 'l': /* Specify location */
-          SMSLocation = atoi(optarg); break;     
-
-        case '/': /* Name */
-          strncpy(SMSName,optarg,25);break;
-
-        case 'C': /* class Message */
-          
-         if (SMSUDHType!=GSM_NoUDH) {
-            fprintf(stderr, _("Can't specify SMS Class with --enablevoice, --disablevoice, --enableemail, --disableemail, --enablefax, --disablefax options !\n"));        
-           return -1;
-         }
-         
-          switch (*optarg) {
-            case '0': SMSClass = 0; break;
-            case '1': SMSClass = 1; break;
-            case '2': SMSClass = 2; break;
-            case '3': SMSClass = 3; break; 
-            default:
-             fprintf(stderr, _("SMS Class (\"C\" option) can be 0, 1, 2 or 3 only !\n"));
-              return -1;
-          }
-          break;
-
-        case 'F': /* save into folder n */
-         SMSFolder = atoi(optarg);
-          break;
-
-        default:
-          fprintf(stderr,_("Unknown option number %i\n"),argc);
-          return -1;
-      }
-    }
-  }
-  
-  /* Get message text from stdin. */
-  chars_read = fread(message_buffer, 1, input_len, stdin);
-
-  if (chars_read == 0) {
-    fprintf(stderr, _("Couldn't read from stdin!\n")); 
-    return -1;
-  }
-  if (chars_read > input_len) {
-    fprintf(stderr, _("Input too long!\n"));   
-    return -1;
-  }
-  
-  /*  Null terminate. */
-  message_buffer[chars_read] = 0x00;   
-
-  GSM_MakeMultiPartSMS2(&MultiSMS,message_buffer,chars_read,SMSUDHType,SMSCoding);
-  msgnum=MultiSMS.number;
-
-  switch (SMSUDHType) {
-    case GSM_NoUDH:
-    case GSM_BugSMS:
-    case GSM_VoidSMS:
-    case GSM_HangSMS:
-    case GSM_EnableVoice:
-    case GSM_DisableVoice:
-    case GSM_EnableFax:
-    case GSM_DisableFax:
-    case GSM_EnableEmail:
-    case GSM_DisableEmail:
-      fprintf(stdout,_("Warning: saving %i chars\n"),strlen(MultiSMS.SMS[0].MessageText));
-      msgnum=1;
-      break;
-    default:
-      break;
-  }
-
-  for (i=0;i<msgnum;i++) {
-    MultiSMS.SMS[i].Destination[0]=0;
-    if (argc!=0) strcpy(MultiSMS.SMS[i].Destination,argv[0]);
-
-    MultiSMS.SMS[i].Location=0;
-    MultiSMS.SMS[i].Class=SMSClass;
-    MultiSMS.SMS[i].MessageCenter.No=SMSCenter;
-    strcpy(MultiSMS.SMS[i].MessageCenter.Number,SMSCNumber);
-    MultiSMS.SMS[i].Status=SMSStatus;
-    strcpy(MultiSMS.SMS[i].Name,SMSName);
-    MultiSMS.SMS[i].folder=SMSFolder;
-    MultiSMS.SMS[i].ReplyViaSameSMSC=SMSReply;
-  }
-
-  MultiSMS.SMS[0].Location=SMSLocation;
-
-  /* Initialise the GSM interface. */     
-  fbusinit(NULL);
-
-  MultiSMS.number=msgnum;
-  GSM_SaveMultiPartSMSOnConsole(&MultiSMS, 0,0,NULL,interactive,false,false,false);
-  
-  return 0;
+       fprintf(stderr, _("Wrong number of arguments\n"));
+       exit(-1);
 }
 
 }
 
-/* Get SMSC number */
+#define SMSC_SHORTCHAR_SMSC   (0xF0)
+#define SMSC_SHORTCHAR_SMSCNO (0xF1)
+#define SMSC_OPTIONS \
+               { "smsc",     required_argument, NULL, SMSC_SHORTCHAR_SMSC}, \
+               { "smscno",   required_argument, NULL, SMSC_SHORTCHAR_SMSCNO}
 
 
-int getsmsc(char *MessageCenterNumber)
+/* RETURNS: Whether the options was found as ours (=>rerun getopt_long())
+ */
+static bool smsc_options_parse(int option,GSM_SMSMessage *SMS)
 {
 {
+       switch (option) {
 
 
-  GSM_MessageCenter MessageCenter;
+       case SMSC_SHORTCHAR_SMSC: /* SMSC number */
+               SMS->MessageCenter.No = 0;
+               strcpy(SMS->MessageCenter.Number,optarg);
+               break;
 
 
-  MessageCenter.No=atoi(MessageCenterNumber);
+       case SMSC_SHORTCHAR_SMSCNO: /* SMSC number index in phone memory */
+               SMS->MessageCenter.No = atoi(optarg);
 
 
-  fbusinit(NULL);
+               if (SMS->MessageCenter.No < 1 || SMS->MessageCenter.No > 5)
+                       usage();
+               break;
 
 
-  if (GSM->GetSMSCenter(&MessageCenter) == GE_NONE) {
+       default:
+               return(false);          /* option not recognized */
+       }
 
 
-    fprintf(stdout, _("%d. SMS center ("),MessageCenter.No);
-    
-    if (!strcmp(MessageCenter.Name,""))
-      fprintf(stdout,_("Set %d"),MessageCenter.No);
-    else fprintf(stdout,_("%s"),MessageCenter.Name);
-      
-    fprintf(stdout,_(") number is "));
+       return(true);   /* option was successfuly processed */
+}
 
 
-    if (!strcmp(MessageCenter.Number,"")) fprintf(stdout,_("not set\n"));
-    else fprintf(stdout,_("%s\n"),MessageCenter.Number);
+/* RETURNS: Success
+ */
+bool sendsms_deconcatenated(GSM_SMSMessage *sms,char *buf,size_t buflen,bool useudh)
+{
+       GSM_Deconcatenate_state SMS_Deconcatenate_state;
+       GSM_Error error;
 
 
-    fprintf(stdout,_("Default recipient number is "));
+       SMS_Deconcatenate_state.first=true;
+       while (SMS_Deconcatenate(&SMS_Deconcatenate_state,sms,buf,buflen,useudh)) {
+               /* Send the message. */
+               error = GSM->SendSMSMessage(sms);
 
 
-    if (!strcmp(MessageCenter.DefaultRecipient,""))
-      fprintf(stdout,_("not set\n"));
-    else fprintf(stdout,_("%s\n"),MessageCenter.DefaultRecipient);
+               if (error == GE_SMSSENDOK) {
+                       fprintf(stdout, _("Send succeeded!\n"));
+               } else {
+                       fprintf(stdout, _("SMS Send failed (error=%d)\n"), error);
+                       return(false);
+               }
+               /* Here the sleep have no meaning.
+                * If it is required by some backend phone driver, it should be done THERE!
+                */
+               /* sleep(10); */
+       }
+       return(true);
+}
 
 
-    fprintf(stdout, _("Messages sent as "));
+/* Send  SMS messages. */
+int sendsms(int argc, char *argv[])
+{
+       GSM_SMSMessage SMS;
+       /* The maximum length of an uncompressed concatenated short message is
+          255 * 153 = 39015 default alphabet characters */
+       char message_buffer[GSM_MAX_CONCATENATED_SMS_LENGTH];
+       int input_len, chars_read;
+       int i;
+       bool useudh = false;
+
+       struct option options[] = {
+               SMSC_OPTIONS,
+               { "longtext", no_argument,       NULL, '3'},
+               { "longudh",  no_argument,       NULL, '4'},
+               { "udh",      no_argument,       NULL, '5'},
+               { NULL,       0,                 NULL, 0}
+       };
+
+       input_len = GSM_MAX_SMS_LENGTH;
+
+       /* Default settings:
+          - no delivery report
+          - no Class Message
+          - no compression
+          - 7 bit data
+          - SMSC no. 1
+          - message validity for 3 days
+          - unset user data header indicator
+       */
+
+       SMS.Type = GST_MO;
+       SMS.Class = -1;
+       SMS.Compression = false;
+       SMS.EightBit = false;
+       SMS.MessageCenter.No = 1;
+       SMS.Validity = 4320; /* 4320 minutes == 72 hours */
+       SMS.UDHPresent = false;
+
+       strcpy(SMS.Destination, argv[0]);
+
+       optarg = NULL;
+       optind = 0;
+
+       while ((i = getopt_long(argc, argv, "r8cC:v:", options, NULL)) != -1) {
+               if (smsc_options_parse(i,&SMS))
+                       continue;
+               switch (i) {       // -c for compression. not yet implemented.
+               case '3': /* we send long message in text format */
+                       input_len = GSM_MAX_CONCATENATED_SMS_LENGTH;
+                       useudh = false;
+                       break;
+               case '4': /* we send long message in UDH format */
+                       input_len = GSM_MAX_CONCATENATED_SMS_LENGTH;
+                       useudh = true;
+                       break;
+               case '5': /* UDH indication requested */
+                       SMS.UDHPresent = true;
+                       break;
+               case 'r': /* request for delivery report */
+                       SMS.Type = GST_DR;
+                       break;
+               case 'C': /* class Message */
+                       switch (*optarg) {
+                       case '0':
+                               SMS.Class = 0;
+                               break;
+                       case '1':
+                               SMS.Class = 1;
+                               break;
+                       case '2':
+                               SMS.Class = 2;
+                               break;
+                       case '3':
+                               SMS.Class = 3;
+                               break;
+                       default:
+                               usage();
+                       }
+                       break;
+               case '8': /* 8-bit data */
+                       SMS.EightBit = true;
+                       break;
+               case 'v':
+                       SMS.Validity = atoi(optarg);
+                       break;
+               default:
+                       usage(); /* Would be better to have an sendsms_usage() here. */
+               }
+       }
 
 
-    switch (MessageCenter.Format) {
-      case GSMF_Text  :fprintf(stdout, _("Text"));break;
-      case GSMF_Paging:fprintf(stdout, _("Paging"));break;
-      case GSMF_Fax   :fprintf(stdout, _("Fax"));break;
-      case GSMF_Email :
-      case GSMF_UCI   :fprintf(stdout, _("Email"));break;
-      case GSMF_ERMES :fprintf(stdout, _("ERMES"));break;
-      case GSMF_X400  :fprintf(stdout, _("X.400"));break;
-      default         :fprintf(stdout, _("Unknown"));
-    }
+       /* Get message text from stdin. */
+       chars_read = fread(message_buffer, 1, input_len, stdin);
 
 
-    printf("\n");
+       if (chars_read == 0) {
+               fprintf(stderr, _("Couldn't read from stdin!\n"));      
+               return -1;
+       } else if (chars_read > input_len) {
+               fprintf(stderr, _("Input too long!\n"));        
+               return -1;
+       }
 
 
-    fprintf(stdout, _("Message validity is "));
+       if (SMS.UDHPresent) {
+u8 UDHlen = 1 + message_buffer[0];     /* designifify */
 
 
-    switch (MessageCenter.Validity) {
-      case GSMV_1_Hour  :fprintf(stdout, _("1 hour"));break;
-      case GSMV_6_Hours :fprintf(stdout, _("6 hours"));break;
-      case GSMV_24_Hours:fprintf(stdout, _("24 hours"));break;
-      case GSMV_72_Hours:fprintf(stdout, _("72 hours"));break;
-      case GSMV_1_Week  :fprintf(stdout, _("1 week"));break;
-      case GSMV_Max_Time:fprintf(stdout, _("Maximum time"));break;
-      default           :fprintf(stdout, _("Unknown"));
-    }
+               if (chars_read < UDHlen || sizeof(SMS.UDH) < UDHlen) {
+                       fprintf(stderr, _("Input too short to satisfy UDH!\n"));
+                       return -1;
+               }
+               memcpy(SMS.UDH, message_buffer, UDHlen);
+               chars_read-=UDHlen;
+               memmove(message_buffer, message_buffer + UDHlen, chars_read);
+       }
 
 
-    fprintf(stdout, "\n");
+       /*  Null terminate. */
+       message_buffer[chars_read] = 0x00;      
 
 
-  }
-  else
-    fprintf(stdout, _("SMS center can not be found :-(\n"));
+       sendsms_deconcatenated(&SMS,message_buffer,chars_read,useudh);
 
 
-  GSM->Terminate();
+       GSM->Terminate();
 
 
-  return 0;
+       return 0;
 }
 
 }
 
-/* Get SMS messages. */
-int getsms(int argc, char *argv[])
+int savesms(int argc, char *argv[])
 {
 {
+       GSM_SMSMessage SMS;
+       GSM_Error error;
+       /* The maximum length of an uncompressed concatenated short message is
+          255 * 153 = 39015 default alphabet characters */
+       char message_buffer[GSM_MAX_CONCATENATED_SMS_LENGTH];
+       int input_len, chars_read;
+       int i, confirm = -1;
+       int interactive = 0;
+       char ans[8];
+
+       /* Defaults */
+       SMS.Type = GST_MO;
+       SMS.Destination[0] = '\0';
+       SMS.Class = -1;
+       SMS.Compression = false;
+       SMS.EightBit = false;
+       SMS.MessageCenter.No = 1;
+       SMS.Validity = 4320; /* 4320 minutes == 72 hours */
+       SMS.UDHPresent = false;
+       SMS.Status = GSS_NOTSENTREAD;
+       SMS.Location = 0;
+       SMS.MemoryType = GMT_SM;
+
+       input_len = GSM_MAX_SMS_LENGTH;
+
+       /* Option parsing */
+       while ((i = getopt(argc, argv, "ml:in:s:c:")) != -1) {
+               switch (i) {
+               case 'm': /* mark the message as sent */
+                       SMS.Status = GSS_SENTREAD;
+                       break;
+               case 'l': /* Specify the location */
+                       SMS.Location = atoi(optarg);
+                       break;
+               case 'i': /* Ask before overwriting */
+                       interactive = 1;
+                       break;
+               case 'n': /* Specify the from number */
+                       break;
+               case 's': /* Specify the smsc number */
+                       break;
+               case 'c': /* Specify the smsc location */
+                       break;
+               default:
+                       usage();
+                       return -1;
+               }
+       }
 
 
-  GSM_SMSMessage message;
-  GSM_WAPBookmark bookmark;
-  char memory_type_string[20];
-  int start_message, end_message, count, mode = 1;
-  char filename[64];
-  GSM_Error error;
-  GSM_Bitmap bitmap;
-  GSM_Ringtone ringtone;
-  GSM_SMSFolders folders;
-  
-  int confirm = -1, i;
-  char ans[8];
-
-  /* Handle command line args that set type, start and end locations. */
-  if (!GetMemoryTypeID(argv[2], &message.MemoryType))
-  {
-    fprintf(stderr, _("Unknown memory type %s!\n"), argv[2]);
-    return (-1);
-  }
-  GetMemoryTypeString(memory_type_string, &message.MemoryType);
-
-  for (i=0;i<64;i++) filename[i]=0;
-
-  start_message = atoi(argv[3]);
-  if (argc > 4) {
-     int i;
-     
-     /* [end] can be only argv[4] */
-     if (argv[4][0] == '-') {
-        end_message = start_message;
-     } else {
-        end_message = atoi(argv[4]);
-     }
-
-     /* parse all options (beginning with '-' */
-     while ((i = getopt(argc, argv, "f:")) != -1) {
-       switch (i) {
-         case 'f':
-           if (optarg) {
+       if (interactive) {
+               GSM_SMSMessage aux;
+
+               aux.Location = SMS.Location;
+               data.SMSMessage = &aux;
+               error = SM_Functions(GOP_GetSMS, &data, &State);
+               switch (error) {
+               case GE_NONE:
+                       fprintf(stderr, _("Message at specified location exists. "));
+                       while (confirm < 0) {
+                               fprintf(stderr, _("Overwrite? (yes/no) "));
+                               GetLine(stdin, ans, 7);
+                               if (!strcmp(ans, "yes")) confirm = 1;
+                               else if (!strcmp(ans, "no")) confirm = 0;
+                       }  
+                       if (!confirm) { GSM->Terminate(); return 0; }
+                       else break;
+               case GE_INVALIDSMSLOCATION:
+                       fprintf(stderr, _("Invalid location\n"));
+                       GSM->Terminate();
+                       return -1;
+               default:
+/* FIXME: Remove this fprintf when the function is thoroughly tested */
 #ifdef DEBUG
 #ifdef DEBUG
-          fprintf(stderr, _("Saving into file \"%s\"\n"), optarg);
-#endif /* DEBUG */
-             strncpy(filename, optarg, 64);
-              if (strlen(optarg) > 63) {
-                fprintf(stderr, _("Filename too long - will be truncated to 63 characters.\n"));
-                filename[63] = 0;
-              } else {
-                filename[strlen(optarg)] = 0;
-              }
-           } else {
-             usage();
-             exit(1);
-           }
-           break;
-         default:
-           usage();
-           exit(1);
+                       fprintf(stderr, _("Location %d empty. Saving\n"), SMS.Location);
+#endif
+                       break;
+               }
        }
        }
-      }
-  } else {
-    end_message = start_message;
-  }
-
-  /* Initialise the code for the GSM interface. */     
-
-  fbusinit(NULL);
+       chars_read = fread(message_buffer, 1, input_len, stdin);
 
 
-  GSM->GetSMSFolders(&folders);
+       if (chars_read == 0) {
 
 
-  
-  /* Now retrieve the requested entries. */
+               fprintf(stderr, _("Couldn't read from stdin!\n"));
+               return -1;
 
 
-  for (count = start_message; count <= end_message; count ++) {
+       } else if (chars_read > input_len) {
 
 
-    message.Location = count;
+               fprintf(stderr, _("Input too long!\n"));
+               return -1;
 
 
-    error = GSM->GetSMSMessage(&message);
+       }
 
 
-    switch (error) {
+       strncpy (SMS.MessageText, message_buffer, chars_read);
+       SMS.MessageText[chars_read] = 0;
+       SMS.MessageTextLength=chars_read;
 
 
-    case GE_NONE:
+       error = GSM->SaveSMSMessage(&SMS);
 
 
-      switch (message.Type) {
+       if (error == GE_NONE) {
+               fprintf(stdout, _("Saved!\n"));
+       } else {
+               fprintf(stdout, _("Saving failed (error=%d)\n"), error);
+       }
+       sleep(10);
+       GSM->Terminate();
 
 
-        case GST_DR:
+       return 0;
+}
 
 
-         /* RTH FIXME: Test that out ! */
-          fprintf(stdout, _("%d. Delivery Report "), message.MessageNumber);
-          switch (message.Status)
-          {
-           case  GSS_SENTREAD:
-                if (message.folder==0) //GST_INBOX
-                 fprintf(stdout, _("(read)\n"));
-                else
-                 fprintf(stdout, _("(sent)\n"));
-               break;
-           case  GSS_NOTSENTREAD:
-                if (message.folder==0) //GST_INBOX
-                 fprintf(stdout, _("(unread)\n"));
-                else
-                 fprintf(stdout, _("(not sent)\n"));
-               break;
-           case  GSS_UNKNOWN:
-               fprintf(stdout, _("(not known :-()\n"));
-               break;
-           case  GSS_TEMPLATE:
-               fprintf(stdout, _("(template)\n"));
-               break;
-           default:
-               fprintf(stdout, _("(unknown: %d)\n"),message.Status);
+/* Get SMSC number */
+int getsmsc(char *MessageCenterNumber)
+{
+       GSM_MessageCenter       MessageCenter;
+       GSM_Data                data;
+       GSM_Error               error;
+       
+       memset(&MessageCenter, 0, sizeof(MessageCenter));
+       MessageCenter.No=atoi(MessageCenterNumber);
+       
+       if (GSM && GSM->GetSMSCenter && GSM->Terminate) {
+               error = GSM->GetSMSCenter(&MessageCenter);
+               GSM->Terminate();
+       } else {
+               GSM_DataClear(&data);
+               data.MessageCenter = &MessageCenter;
+               error = SM_Functions(GOP_GetSMSCenter, &data, &State);
+       }
+       
+       switch (error) {
+       case GE_NONE:
+               fprintf(stdout, _("%d. SMS center (%s) number is %s\n"), MessageCenter.No, MessageCenter.Name, MessageCenter.Number);
+               fprintf(stdout, _("Default recipient number is %s\n"), MessageCenter.Recipient);
+               fprintf(stdout, _("Messages sent as "));
+               
+               switch (MessageCenter.Format) {
+               case GSMF_Text:
+                       fprintf(stdout, _("Text"));
+                       break;
+               case GSMF_Paging:
+                       fprintf(stdout, _("Paging"));
+                       break;
+               case GSMF_Fax:
+                       fprintf(stdout, _("Fax"));
+                       break;
+               case GSMF_Email:
+               case GSMF_UCI:
+                       fprintf(stdout, _("Email"));
+                       break;
+               case GSMF_ERMES:
+                       fprintf(stdout, _("ERMES"));
+                       break;
+               case GSMF_X400:
+                       fprintf(stdout, _("X.400"));
+                       break;
+               default:
+                       fprintf(stdout, _("Unknown"));
+                       break;
+               }
+               
+               printf("\n");
+               fprintf(stdout, _("Message validity is "));
+               
+               switch (MessageCenter.Validity) {
+               case GSMV_1_Hour:
+                       fprintf(stdout, _("1 hour"));
+                       break;
+               case GSMV_6_Hours:
+                       fprintf(stdout, _("6 hours"));
+                       break;
+               case GSMV_24_Hours:
+                       fprintf(stdout, _("24 hours"));
+                       break;
+               case GSMV_72_Hours:
+                       fprintf(stdout, _("72 hours"));
+                       break;
+               case GSMV_1_Week:
+                       fprintf(stdout, _("1 week"));
+                       break;
+               case GSMV_Max_Time:
+                       fprintf(stdout, _("Maximum time"));
+                       break;
+               default:
+                       fprintf(stdout, _("Unknown"));
+                       break;
+               }
+               
+               fprintf(stdout, "\n");
+               
                break;
                break;
-          }
-
-          fprintf(stdout, _("Sending date/time : %s %02d/%02d/%02d %d:%02d:%02d "), \
-                  DayOfWeek(message.Time.Year, message.Time.Month, message.Time.Day), \
-                 message.Time.Day, message.Time.Month, message.Time.Year, \
-                  message.Time.Hour, message.Time.Minute, message.Time.Second);
-
-          if (message.Time.Timezone) {
-            if (message.Time.Timezone > 0)
-              fprintf(stdout,_("+%02d00"), message.Time.Timezone);
-            else
-              fprintf(stdout,_("%02d00"), message.Time.Timezone);
-          }
-
-          fprintf(stdout, "\n");
-
-          fprintf(stdout, _("Response date/time: %s %02d/%02d/%02d %d:%02d:%02d "), \
-                  DayOfWeek(message.SMSCTime.Year, message.SMSCTime.Month, message.SMSCTime.Day), \
-                  message.SMSCTime.Day, message.SMSCTime.Month, message.SMSCTime.Year, \
-                  message.SMSCTime.Hour, message.SMSCTime.Minute, message.SMSCTime.Second);
-
-          if (message.SMSCTime.Timezone) {
-            if (message.SMSCTime.Timezone > 0)
-              fprintf(stdout,_("+%02d00"),message.SMSCTime.Timezone);
-            else
-              fprintf(stdout,_("%02d00"),message.SMSCTime.Timezone);
-          }
-
-          fprintf(stdout, "\n");
-
-          fprintf(stdout, _("Receiver: %s Msg Center: %s\n"), message.Sender, message.MessageCenter.Number);
-          fprintf(stdout, _("Text: %s\n\n"), message.MessageText); 
-
-          break;
-
-        case GST_SMS:
-          fprintf(stdout, _("%d. %s Message "), message.MessageNumber,
-                          folders.Folder[message.folder].Name);
-
-         switch (message.Status)
-           {
-           case  GSS_SENTREAD:
-                if (message.folder==0) //GST_INBOX
-                 fprintf(stdout, _("(read)\n"));
-                else
-                 fprintf(stdout, _("(sent)\n"));
+       case GE_NOTIMPLEMENTED:
+               fprintf(stderr, _("Function not implemented in %s model!\n"), model);
                break;
                break;
-           case  GSS_NOTSENTREAD:
-                if (message.folder==0) //GST_INBOX
-                 fprintf(stdout, _("(unread)\n"));
-                else
-                 fprintf(stdout, _("(not sent)\n"));
+       default:
+               fprintf(stdout, _("SMS center can not be found :-(\n"));
                break;
                break;
-            case  GSS_UNKNOWN:
-                fprintf(stdout, _("(not known :-()\n"));
-                break;
-            case  GSS_TEMPLATE:
-                fprintf(stdout, _("(template)\n"));
-                break;
-            default:
-                fprintf(stdout, _("(unknown: %d)\n"),message.Status);
-                break;
-           }
-        
-         /* RTH FIXME: date for other status ok ? */ 
-         if (message.SMSData) {
-
-            fprintf(stdout, _("Date/time: %s %02d/%02d/%02d %d:%02d:%02d "), \
-                    DayOfWeek(message.Time.Year, message.Time.Month, message.Time.Day), \
-                    message.Time.Day, message.Time.Month, message.Time.Year, \
-                    message.Time.Hour, message.Time.Minute, message.Time.Second);
-
-            if (message.Time.Timezone) {
-              if (message.Time.Timezone > 0)
-                fprintf(stdout,_("+%02d00"),message.Time.Timezone);
-              else
-                fprintf(stdout,_("%02d00"),message.Time.Timezone);
-            }
-
-            fprintf(stdout, "\n");
-
-           fprintf(stdout, _("Msg Center: %s "), message.MessageCenter.Number);
-           
-           if (message.ReplyViaSameSMSC)
-             fprintf(stdout, _("(centre set for reply) "));
-         }
-
-          if (strcmp(message.Sender,"")) {
-           if (message.folder==1) { //GST_OUTBOX
-             fprintf(stdout, _("Recipient: %s"),message.Sender);
-           } else {
-             fprintf(stdout, _("Sender: %s"),message.Sender);
-           }
-         }
-
-          if (strcmp(message.Sender,"") || message.folder==0)
-            fprintf(stdout, "\n");
-           
-          switch (message.UDHType) {
-
-          case GSM_OpLogo:
+       }
+       
+       return error;
+}
 
 
-            /* put bitmap into bitmap structure */
-           switch (GSM_ReadBitmap(&message, &bitmap)) {
-             case GE_INVALIDIMAGESIZE:
-               fprintf(stdout,_("Image size not supported\n"));
-               break;
-             case GE_NONE:
-               fprintf(stdout, _("GSM operator logo for %s (%s) network.\n"), bitmap.netcode, GSM_GetNetworkName(bitmap.netcode));         
-           
-                GSM_PrintBitmap(&bitmap);
+/* Get SMS messages. */
+int getsms(int argc, char *argv[])
+{
+       int del = 0;
+       GSM_SMSMessage message;
+       char *memory_type_string;
+       int start_message, end_message, count, mode = 1;
+       char filename[64];
+       GSM_Error error;
+       GSM_Bitmap bitmap;
+       char ans[5];
+       struct stat buf;
+
+       /* Handle command line args that set type, start and end locations. */
+       memory_type_string = argv[2];
+       message.MemoryType = StrToMemoryType(memory_type_string);
+       if (message.MemoryType == GMT_XX) {
+               fprintf(stderr, _("Unknown memory type %s (use ME, SM, ...)!\n"), argv[2]);
+               return (-1);
+       }
 
 
-                if (filename[0]!=0) {
-                  GSM_SaveBitmapFileOnConsole(filename, &bitmap);
-                }
+       memset(&filename, 0, 64);
 
 
-               break;
-             default:
-               fprintf(stdout,_("Error reading image\n"));  
-               break;
-           }
+       start_message = end_message = atoi(argv[3]);
+       if (argc > 4) {
+               int i;
 
 
-#ifdef DEBUG
-            if (message.folder==0) { //GST_INBOX
-              if (!strcmp(message.Sender, "+998000005") &&
-                 !strcmp(message.MessageCenter.Number, "+886935074443") &&
-                 message.Time.Day==27 &&
-                 message.Time.Month==7 &&
-                 message.Time.Year==99 &&
-                 message.Time.Hour==0 &&
-                 message.Time.Minute==10 &&
-                 message.Time.Second==48) fprintf(stdout, _("Saved by Logo Express\n"));
-
-              /* Is it changed in next versions ? Or what ? */
-              if (!strcmp(message.Sender, "+998000002") ||
-                  !strcmp(message.Sender, "+998000003") ||
-                 !strcmp(message.Sender, "+998000004")) fprintf(stdout, _("Saved by Operator Logo Uploader by Thomas Kessler\n"));
-            } else {
-              if (!strcmp(message.Sender, "+8861234567890") &&
-                 !strcmp(message.MessageCenter.Number, "+886935074443")) fprintf(stdout, _("Saved by Logo Express\n"));
-           }
-           if (!strncmp(message.Sender, "OpLogo",6) &&
-               strlen(message.Sender)==11)
-              fprintf(stdout, _("Saved by gnokii\n"));         
-#endif
+               /* [end] can be only argv[4] */
+               if (argv[4][0] != '-') {
+                       end_message = atoi(argv[4]);
+               }
 
 
-            break;
+               /* parse all options (beginning with '-' */
+               while ((i = getopt(argc, argv, "f:F:d")) != -1) {
+                       switch (i) {
+                       case 'd':
+                               del = 1;
+                               break;
+                       case 'F':
+                               mode = 0;
+                       case 'f':
+                               if (optarg) {
+                                       dprintf(_("Saving into %s\n"), optarg);
+                                       strncpy(filename, optarg, 64);
+                                       if (strlen(optarg) > 63) {
+                                               fprintf(stderr, _("Filename too long - will be truncated to 63 characters.\n"));
+                                               filename[63] = 0;
+                                       } else {
+                                               filename[strlen(optarg)] = 0;
+                                       }
+                               } else  usage();
+                               break;
+                       default:
+                               usage();
+                       }
+               }
+       }
 
 
-          case GSM_WAPBookmarkUDH:
+       /* Now retrieve the requested entries. */
+       for (count = start_message; count <= end_message; count ++) {
 
 
-            /* put bookmark into bookmark structure */
-           switch (GSM_ReadWAPBookmark(&message, &bookmark)) {
-             case GE_NONE:
-                fprintf(stdout, ("WAP Bookmark\n"));
+               message.Location = count;
+               data.SMSMessage = &message;
+               error = SM_Functions(GOP_GetSMS, &data, &State);
 
 
-                fprintf(stdout,_("Address: \"%s\"\n"),bookmark.address);
+               switch (error) {
+               case GE_NONE:
+                       switch (message.Type) {
+                       case GST_MO:
+                               fprintf(stdout, _("%d. Outbox Message "), message.MessageNumber);
+                               if (message.Status)
+                                       fprintf(stdout, _("(sent)\n"));
+                               else
+                                       fprintf(stdout, _("(not sent)\n"));
+                               fprintf(stdout, _("Text: %s\n\n"), message.MessageText); 
+                               break;
+                       case GST_DR:
+                               fprintf(stdout, _("%d. Delivery Report "), message.MessageNumber);
+                               if (message.Status)
+                                       fprintf(stdout, _("(read)\n"));
+                               else
+                                       fprintf(stdout, _("(not read)\n"));
+                               fprintf(stdout, _("Sending date/time: %d/%d/%d %d:%02d:%02d "), \
+                                       message.Time.Day, message.Time.Month, message.Time.Year, \
+                                       message.Time.Hour, message.Time.Minute, message.Time.Second);
+                               if (message.Time.Timezone) {
+                                       if (message.Time.Timezone > 0)
+                                               fprintf(stdout,_("+%02d00"), message.Time.Timezone);
+                                       else
+                                               fprintf(stdout,_("%02d00"), message.Time.Timezone);
+                               }
+                               fprintf(stdout, "\n");
+                               fprintf(stdout, _("Response date/time: %d/%d/%d %d:%02d:%02d "), \
+                                       message.SMSCTime.Day, message.SMSCTime.Month, message.SMSCTime.Year, \
+                                       message.SMSCTime.Hour, message.SMSCTime.Minute, message.SMSCTime.Second);
+                               if (message.SMSCTime.Timezone) {
+                                       if (message.SMSCTime.Timezone > 0)
+                                               fprintf(stdout,_("+%02d00"),message.SMSCTime.Timezone);
+                                       else
+                                               fprintf(stdout,_("%02d00"),message.SMSCTime.Timezone);
+                               }
+                               fprintf(stdout, "\n");
+                               fprintf(stdout, _("Receiver: %s Msg Center: %s\n"), message.Sender, message.MessageCenter.Number);
+                               fprintf(stdout, _("Text: %s\n\n"), message.MessageText); 
+                               break;
+                       default:
+                               fprintf(stdout, _("%d. Inbox Message "), message.MessageNumber);
+                               if (message.Status)
+                                       fprintf(stdout, _("(read)\n"));
+                               else
+                                       fprintf(stdout, _("(not read)\n"));
+                               fprintf(stdout, _("Date/time: %d/%d/%d %d:%02d:%02d "), \
+                                       message.Time.Day, message.Time.Month, message.Time.Year, \
+                                       message.Time.Hour, message.Time.Minute, message.Time.Second);
+                               if (message.Time.Timezone) {
+                                       if (message.Time.Timezone > 0)
+                                               fprintf(stdout,_("+%02d00"),message.Time.Timezone);
+                                       else
+                                               fprintf(stdout,_("%02d00"),message.Time.Timezone);
+                               }
+                               fprintf(stdout, "\n");
+                               fprintf(stdout, _("Sender: %s Msg Center: %s\n"), message.Sender, message.MessageCenter.Number);
+                               switch (SMS_DetectUDH(&message)) {
+                               case GSM_OpLogo:
+                                       fprintf(stdout, _("GSM operator logo for %s (%s) network.\n"), bitmap.netcode, GSM_GetNetworkName(bitmap.netcode));
+                                       if (!strcmp(message.Sender, "+998000005") && !strcmp(message.MessageCenter.Number, "+886935074443")) dprintf(_("Saved by Logo Express\n"));
+                                       if (!strcmp(message.Sender, "+998000002") || !strcmp(message.Sender, "+998000003")) dprintf(_("Saved by Operator Logo Uploader by Thomas Kessler\n"));
+                               case GSM_CallerIDLogo:
+                                       fprintf(stdout, ("Logo:\n"));
+                                       /* put bitmap into bitmap structure */
+                                       GSM_ReadSMSBitmap(&message, &bitmap);
+                                       GSM_PrintBitmap(&bitmap);
+                                       if (*filename) {
+                                               error = GE_NONE;
+                                               if ((stat(filename, &buf) == 0)) {
+                                                       fprintf(stdout, _("File %s exists.\n"), filename);
+                                                       fprintf(stderr, _("Overwrite? (yes/no) "));
+                                                       GetLine(stdin, ans, 4);
+                                                       if (!strcmp(ans, "yes")) {
+                                                               error = GSM_SaveBitmapFile(filename, &bitmap);
+                                                       }
+                                               } else error = GSM_SaveBitmapFile(filename, &bitmap);          
+                                               if (error!=GE_NONE) fprintf(stderr, _("Couldn't save logofile %s!\n"), filename);
+                                       }
+                                       break;
+                               case GSM_RingtoneUDH:
+                                       fprintf(stdout, ("Ringtone\n"));
+                                       break;
+                               case GSM_ConcatenatedMessages:
+                                       fprintf(stdout, _("Linked (%d/%d):\n"),message.UDH[5],message.UDH[4]);
+                               case GSM_NoUDH:
+                                       fprintf(stdout, _("Text:\n%s\n\n"), message.MessageText);
+                                       if ((mode != -1) && *filename) {
+                                               char buf[1024];
+                                               sprintf(buf, "%s%d", filename, count);
+                                               mode = GSM_SaveTextFile(buf, message.MessageText, mode);
+                                       }
+                                       break;
+                               default:
+                                       fprintf(stderr, _("Unknown\n"));
+                                       break;
+                               }
+                               break;
+                       }
+                       if (del) {
+                               data.SMSMessage = &message;
+                               if (GE_NONE != SM_Functions(GOP_DeleteSMS, &data, &State))
+                                       fprintf(stdout, _("(delete failed)\n"));
+                               else
+                                       fprintf(stdout, _("(message deleted)\n"));
+                       }
+                       break;
+               case GE_NOTIMPLEMENTED:
+                       fprintf(stderr, _("Function not implemented in %s model!\n"), model);
+                       if (GSM && GSM->Terminate) GSM->Terminate();
+                       return -1;      
+               case GE_INVALIDSMSLOCATION:
+                       fprintf(stderr, _("Invalid location: %s %d\n"), memory_type_string, count);
+                       break;
+               case GE_EMPTYSMSLOCATION:
+                       fprintf(stderr, _("SMS location %s %d empty.\n"), memory_type_string, count);
+                       break;
+               default:
+                       fprintf(stdout, _("GetSMS %s %d failed!(%d)\n\n"), memory_type_string, count, error);
+                       break;
+               }
+       }
+       
+       if (GSM && GSM->Terminate) GSM->Terminate();
+       
+       return 0;
+}
 
 
-                if (bookmark.title[0]==0)
-                  fprintf(stdout,_("Title: \"%s\"\n"),bookmark.address);
-                else
-                  fprintf(stdout,_("Title: \"%s\"\n"),bookmark.title);
+/* Delete SMS messages. */
+int deletesms(int argc, char *argv[])
+{
+       GSM_SMSMessage message;
+       char *memory_type_string;
+       int start_message, end_message, count;
+       GSM_Error error;
 
 
-               break;
-             default:
-               fprintf(stdout,_("Error reading WAP Bookmark\n"));  
-               break;
-           }
+       /* Handle command line args that set type, start and end locations. */
+       memory_type_string = argv[0];
+       message.MemoryType = StrToMemoryType(memory_type_string);
+       if (message.MemoryType == GMT_XX) {
+               fprintf(stderr, _("Unknown memory type %s (use ME, SM, ...)!\n"), argv[0]);
+               return (-1);
+       }
+                
+       start_message = end_message = atoi (argv[1]);
+       if (argc > 2) end_message = atoi (argv[2]);
+
+       /* Now delete the requested entries. */
+       for (count = start_message; count <= end_message; count ++) {
+
+               message.Location = count;
+               data.SMSMessage = &message;
+               error = SM_Functions(GOP_DeleteSMS, &data, &State);
+
+               if (error == GE_NONE)
+                       fprintf(stdout, _("Deleted SMS %s %d\n"), memory_type_string, count);
+               else {
+                       if (error == GE_NOTIMPLEMENTED) {
+                               fprintf(stderr, _("Function not implemented in %s model!\n"), model);
+                               GSM->Terminate();
+                               return -1;      
+                       }
+                       fprintf(stdout, _("DeleteSMS %s %d failed!(%d)\n\n"), memory_type_string, count, error);
+               }
+       }
 
 
-#ifdef DEBUG
-           if (!strcmp(message.Sender, "WAPBookmark"))
-              fprintf(stdout, _("Saved by gnokii\n"));         
-#endif
+       GSM->Terminate();
 
 
-            break;
+       return 0;
+}
 
 
-          case GSM_CallerIDLogo:
+static volatile bool bshutdown = false;
 
 
-            /* put bitmap into bitmap structure */
-           switch (GSM_ReadBitmap(&message, &bitmap)) {
-             case GE_INVALIDIMAGESIZE:
-               fprintf(stdout,_("Image size not supported\n"));
-               break;
-             case GE_NONE:
-                fprintf(stdout, ("Caller Logo\n"));
-           
-                GSM_PrintBitmap(&bitmap);
+/* SIGINT signal handler. */
+static void interrupted(int sig)
+{
+       signal(sig, SIG_IGN);
+       bshutdown = true;
+}
 
 
-                if (filename[0]!=0) {
-                  GSM_SaveBitmapFileOnConsole(filename, &bitmap);
-                }
+#ifdef SECURITY
 
 
-               break;
-             default:
-               fprintf(stdout,_("Error reading image\n"));  
-               break;
-           }
+/* In this mode we get the code from the keyboard and send it to the mobile
+   phone. */
+int entersecuritycode(char *type)
+{
+       GSM_Error test;
+       GSM_SecurityCode SecurityCode;
+
+       if (!strcmp(type,"PIN"))
+               SecurityCode.Type=GSCT_Pin;
+       else if (!strcmp(type,"PUK"))
+               SecurityCode.Type=GSCT_Puk;
+       else if (!strcmp(type,"PIN2"))
+               SecurityCode.Type=GSCT_Pin2;
+       else if (!strcmp(type,"PUK2"))
+               SecurityCode.Type=GSCT_Puk2;
+       // FIXME: Entering of SecurityCode does not work :-(
+       //  else if (!strcmp(type,"SecurityCode"))
+       //    SecurityCode.Type=GSCT_SecurityCode;
+       else
+               usage();
 
 
-#ifdef DEBUG
-            if (message.folder==0) { //GST_INBOX
-              if (!strcmp(message.Sender, "+998000005") &&
-                 !strcmp(message.MessageCenter.Number, "+886935074443") &&
-                 message.Time.Day==27 &&
-                 message.Time.Month==7 &&
-                 message.Time.Year==99 &&
-                 message.Time.Hour==0 &&
-                 message.Time.Minute==10 &&
-                 message.Time.Second==48) fprintf(stdout, _("Saved by Logo Express\n"));
-            } else {
-              if (!strcmp(message.Sender, "+8861234567890") &&
-                 !strcmp(message.MessageCenter.Number, "+886935074443")) fprintf(stdout, _("Saved by Logo Express\n"));
-           }
-           if (!strcmp(message.Sender, "GroupLogo"))
-              fprintf(stdout, _("Saved by gnokii\n"));         
+#ifdef WIN32
+       printf("Enter your code: ");
+       gets(SecurityCode.Code);
+#else
+       strcpy(SecurityCode.Code,getpass(_("Enter your code: ")));
 #endif
 
 #endif
 
-            break;
+       test = GSM->EnterSecurityCode(SecurityCode);
+       if (test == GE_INVALIDSECURITYCODE)
+               fprintf(stdout, _("Error: invalid code.\n"));
+       else if (test == GE_NONE)
+               fprintf(stdout, _("Code ok.\n"));
+       else if (test == GE_NOTIMPLEMENTED)
+               fprintf(stderr, _("Function not implemented in %s model!\n"), model);
+       else
+               fprintf(stdout, _("Other error.\n"));
 
 
-          case GSM_ProfileUDH:
-               fprintf(stdout, ("Profile SMS, part %i/%i\n"),message.UDH[11],message.UDH[10]);
-               break;
+       GSM->Terminate();
 
 
-          case GSM_WAPBookmarkUDHLong:
-               fprintf(stdout, ("WAP Bookmark, part %i/%i\n"),message.UDH[11],message.UDH[10]);
-               break;
+       return 0;
+}
 
 
-          case GSM_WAPSettingsUDH:
-               fprintf(stdout, ("WAP Settings, part %i/%i\n"),message.UDH[11],message.UDH[10]);
-               break;
-         
-          case GSM_RingtoneUDH:
+int getsecuritycodestatus(void)
+{
+       int Status;
 
 
-            /* put ringtone into ringtone structure */
-            switch (GSM_ReadRingtone(&message, &ringtone)) {
-             case GE_NONE:
+       if (GSM->GetSecurityCodeStatus(&Status) == GE_NONE) {
 
 
-               fprintf(stdout, ("Ringtone \"%s\"\n"),ringtone.name);
+               fprintf(stdout, _("Security code status: "));
 
 
-                while (confirm < 0) {
-                  fprintf(stderr, _("Do you want to play it ? (yes/no) "));
-                  GetLine(stdin, ans, 7);
-                  if (!strcmp(ans, "yes")) confirm = 1;
-                  if (!strcmp(ans, "no")) confirm = 0;
-                }  
+               switch(Status) {
+               case GSCT_SecurityCode:
+                       fprintf(stdout, _("waiting for Security Code.\n"));
+                       break;
+               case GSCT_Pin:
+                       fprintf(stdout, _("waiting for PIN.\n"));
+                       break;
+               case GSCT_Pin2:
+                       fprintf(stdout, _("waiting for PIN2.\n"));
+                       break;
+               case GSCT_Puk:
+                       fprintf(stdout, _("waiting for PUK.\n"));
+                       break;
+               case GSCT_Puk2:
+                       fprintf(stdout, _("waiting for PUK2.\n"));
+                       break;
+               case GSCT_None:
+                       fprintf(stdout, _("nothing to enter.\n"));
+                       break;
+               default:
+                       fprintf(stdout, _("Unknown!\n"));
+                       break;
+               }
+       }
 
 
-                if (confirm==1) GSM_PlayRingtoneOnConsole(&ringtone);
-               
-                if (filename[0]!=0) GSM_SaveRingtoneFileOnConsole(filename, &ringtone);
-               
-               break;
-               
-              default:
-               fprintf(stdout,_("Gnokii can't read this ringtone - there is probably error inside\n"));
-               break;
-           }
-
-            break;
-
-          case GSM_CalendarNoteUDH:
-           fprintf(stdout, ("Calendar note SMS, part %i/%i\n"),message.UDH[11],message.UDH[10]);
-           fprintf(stdout, _("Text:\n%s\n\n"), message.MessageText);
-            if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
-           break;
-
-          case GSM_ConcatenatedMessages:
-            fprintf(stdout, _("Linked (%d/%d)\nText:\n%s\n\n"),message.UDH[5],message.UDH[4], message.MessageText);
-            if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
-           break;
-
-          case GSM_EnableVoice:
-            fprintf(stdout, _("Enables voice indicator\nText:\n%s\n\n"), message.MessageText);
-            if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
-            break;
-
-          case GSM_DisableVoice:
-            fprintf(stdout, _("Disables voice indicator\nText:\n%s\n\n"), message.MessageText);
-            if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
-            break;
-
-          case GSM_EnableFax:
-            fprintf(stdout, _("Enables fax indicator\nText:\n%s\n\n"), message.MessageText);
-            if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
-            break;
-
-          case GSM_DisableFax:
-            fprintf(stdout, _("Disables fax indicator\nText:\n%s\n\n"), message.MessageText);
-            if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
-            break;
-
-          case GSM_EnableEmail:
-            fprintf(stdout, _("Enables email indicator\nText:\n%s\n\n"), message.MessageText);
-            if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
-            break;
-
-          case GSM_DisableEmail:
-            fprintf(stdout, _("Disables email indicator\nText:\n%s\n\n"), message.MessageText);
-            if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
-            break;
-
-          case GSM_VoidSMS:
-            fprintf(stdout, _("Void SMS\nText:\n%s\n\n"), message.MessageText);
-            if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
-            break;
-
-          case GSM_NoUDH:
-           if (message.Coding!=GSM_Coding_8bit) {
-              fprintf(stdout, _("Text:\n%s\n\n"), message.MessageText);
-              if (filename[0]!=0 && mode != -1) mode = GSM_SaveTextFileOnConsole(filename, message.MessageText, mode);
-           } else {
-             fprintf(stdout, _("Message cannot be displayed here\n")); // like in phone :-)
-           }
-            break;
-
-          default:  //GSM_UnknownUDH and other
-            fprintf(stderr, _("Unknown\n"));
-          }
-
-          break;
-         
-       default:
-         fprintf(stdout,_("Unknown SMS type. Report it\n"));
-         break;
-      }
-
-      break;
-
-    case GE_NOTIMPLEMENTED:
-
-      fprintf(stderr, _("Function not implemented in %s model!\n"), model);
-      GSM->Terminate();
-      return -1;       
-
-    case GE_INVALIDSMSLOCATION:
-
-      fprintf(stderr, _("Invalid location: %s %d\n"), memory_type_string, count);
-
-      break;
-
-    case GE_EMPTYSMSLOCATION:
-
-      fprintf(stderr, _("SMS location %s %d empty.\n"), memory_type_string, count);
-
-      break;
-
-    case GE_NOACCESS:
-
-      fprintf(stderr, _("No access to %s memory.\n"), memory_type_string);
-
-      break;
-
-    default:
-
-      fprintf(stderr, _("GetSMS %s %d failed!(%d)\n\n"), memory_type_string, count, error);
-    }
-  }
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-int getsmsstatus(int argc, char *argv[])
-{
-  GSM_SMSStatus SMSStatus;
-  GSM_SMSFolders folders;
-  GSM_Error error;
-  GSM_SMSMessage SMS;
-
-  int i,j;
-
-  /* Initialise the code for the GSM interface. */     
-  fbusinit(NULL);
-
-  error = GSM->GetSMSStatus(&SMSStatus);
-  if (error!=GE_NONE) return error;
-
-  fprintf(stdout, _("SMS Messages: UnRead %d, Number %d\n"),SMSStatus.UnRead, SMSStatus.Number);
-
-  error=GSM->GetSMSFolders(&folders);  
-  if (error!=GE_NONE) return error;
-
-  /* For not 7110 compatible phones we have to read all SMS and prepare sms table */
-  if( GetModelFeature (FN_SMS)!=F_SMS71 )
-  {
-    i=1;j=0;
-    while (true) {
-      if (j==SMSStatus.Number) break;
-      SMS.Location=i;
-      if (GSM->GetSMSMessage(&SMS)==GE_NONE) {
-        SMSStatus.foldertable[j].smsnum=i;
-
-        /* We set such folders ID like in 7110 compatible phones */
-        if (SMS.Status==GSS_NOTSENTREAD && SMS.folder==0) //GST_INBOX
-          SMSStatus.foldertable[j].folder=0;
-        else {
-          switch (SMS.folder) {
-            case 0://GST_INBOX
-              SMSStatus.foldertable[j].folder=GST_7110_INBOX;
-              break;
-            case 1://GST_OUTBOX
-              SMSStatus.foldertable[j].folder=GST_7110_OUTBOX;
-              break;
-          }
-        }
-        j++;
-      }
-      i++;
-    }
-  }
-
-  printf("0.Unread         : ");
-  for(j=0; j<SMSStatus.Number; j++)
-  {
-    if (SMSStatus.foldertable[j].folder == 0)
-      printf("%d ",SMSStatus.foldertable[j].smsnum);
-  }
-  printf("\n");
-
-  for (i=0;i<folders.number;i++) {
-    fprintf(stdout,_("%d.%-15s: "),i+1,folders.Folder[i].Name);
-    for(j=0; j<SMSStatus.Number; j++)
-    {
-      if ( SMSStatus.foldertable[j].folder / 8 == i+1)
-       printf("%d ",SMSStatus.foldertable[j].smsnum);
-    }
-    printf("\n");
-  }
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Delete SMS messages. */
-int deletesms(int argc, char *argv[])
-{
-
-  GSM_SMSMessage message;
-  char memory_type_string[20];
-  int start_message, end_message, count;
-  GSM_Error error;
-
-  /* Handle command line args that set type, start and end locations. */
-  if (!GetMemoryTypeID(argv[0], &message.MemoryType))
-  {
-    fprintf(stderr, _("Unknown memory type %s!\n"), argv[0]);
-    return (-1);
-  }
-  GetMemoryTypeString(memory_type_string, &message.MemoryType);
-
-  start_message = atoi (argv[1]);
-  if (argc > 2) end_message = atoi (argv[2]);
-  else end_message = start_message;
-
-  /* Initialise the code for the GSM interface. */     
-
-  fbusinit(NULL);
-
-  /* Now delete the requested entries. */
-
-  for (count = start_message; count <= end_message; count ++) {
-
-    message.Location = count;
-
-    error = GSM->DeleteSMSMessage(&message);
-
-    if (error == GE_NONE)
-      fprintf(stdout, _("Deleted SMS %s %d\n"), memory_type_string, count);
-    else {
-      if (error == GE_NOTIMPLEMENTED) {
-       fprintf(stderr, _("Function not implemented in %s model!\n"), model);
        GSM->Terminate();
        GSM->Terminate();
-       return -1;      
-      }
-      fprintf(stdout, _("DeleteSMS %s %d failed!(%d)\n\n"), memory_type_string, count, error);
-    }
-  }
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-static volatile bool bshutdown = false;
-
-/* SIGINT signal handler. */
-
-static void interrupted(int sig)
-{
-
-  signal(sig, SIG_IGN);
-  bshutdown = true;
-
-}
-
-#ifdef SECURITY
-
-/* In this mode we get the code from the keyboard and send it to the mobile
-   phone. */
-
-int entersecuritycode(char *type)
-{
-  GSM_Error test;
-  GSM_SecurityCode SecurityCode;
-
-  if (!strcmp(type,"PIN"))      SecurityCode.Type=GSCT_Pin;
-  else if (!strcmp(type,"PUK")) SecurityCode.Type=GSCT_Puk;
-  else if (!strcmp(type,"PIN2"))SecurityCode.Type=GSCT_Pin2;
-  else if (!strcmp(type,"PUK2"))SecurityCode.Type=GSCT_Puk2;
-
-  // FIXME: Entering of SecurityCode does not work :-(
-  //  else if (!strcmp(type,"SecurityCode"))
-  //    SecurityCode.Type=GSCT_SecurityCode;
-
-  else {
-    fprintf(stdout, _("Wrong code in second parameter (allowed: PIN,PUK,PIN2,PUK2,SecurityCode)\n"));
-    return -1;
-  }
-
-#ifdef WIN32
-  printf("Enter your code: ");
-  gets(SecurityCode.Code);
-#else
-  strcpy(SecurityCode.Code,getpass(_("Enter your code: ")));
-#endif
-
-  fbusinit(NULL);
-
-  test = GSM->EnterSecurityCode(SecurityCode);
-  if (test==GE_NONE)
-    fprintf(stdout,_("Code OK !\n"));
-  else
-    fprintf(stderr,_("%s\n"),print_error(test));
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-int getsecuritycodestatus(void)
-{
-
-  int Status;
-
-  fbusinit(NULL);
-
-  if (GSM->GetSecurityCodeStatus(&Status) == GE_NONE) {
-
-    fprintf(stdout, _("Security code status: "));
-
-      switch(Status) {
-      case GSCT_SecurityCode:fprintf(stdout, _("waiting for Security Code.\n"));break;
-      case GSCT_Pin:         fprintf(stdout, _("waiting for PIN.\n"));          break;
-      case GSCT_Pin2:        fprintf(stdout, _("waiting for PIN2.\n"));         break;
-      case GSCT_Puk:         fprintf(stdout, _("waiting for PUK.\n"));          break;
-      case GSCT_Puk2:        fprintf(stdout, _("waiting for PUK2.\n"));         break;
-      case GSCT_None:        fprintf(stdout, _("nothing to enter.\n"));         break;
-      default:               fprintf(stdout, _("Unknown!\n"));
-      }
-  }
 
 
-  GSM->Terminate();
-
-  return 0;
+       return 0;
 }
 
 }
 
-int getsecuritycode(char *type)
-{
-
-  GSM_SecurityCode SecurityCode;
-  GSM_Error error;
-
-  if (!strcmp(type,"PIN"))              SecurityCode.Type=GSCT_Pin;
-  else if (!strcmp(type,"PUK"))         SecurityCode.Type=GSCT_Puk;
-  else if (!strcmp(type,"PIN2"))        SecurityCode.Type=GSCT_Pin2;
-  else if (!strcmp(type,"PUK2"))        SecurityCode.Type=GSCT_Puk2;
-  else if (!strcmp(type,"SecurityCode"))SecurityCode.Type=GSCT_SecurityCode;
-  else {
-    fprintf(stdout, _("Wrong code in second parameter (allowed: PIN,PUK,PIN2,PUK2,SecurityCode)\n"));
-    return -1;
-  }
-    
-  fbusinit(NULL);
-
-  error=GSM->GetSecurityCode(&SecurityCode);
-  
-  switch (error) {
-    case GE_INVALIDSECURITYCODE:
-      fprintf(stdout, _("Error: getting "));
-      switch (SecurityCode.Type) {
-        case GSCT_SecurityCode:fprintf(stdout, _("security code"));break;
-        case GSCT_Pin :fprintf(stdout, _("PIN"));break;
-        case GSCT_Pin2:fprintf(stdout, _("PIN2"));break;
-        case GSCT_Puk :fprintf(stdout, _("PUK"));break;
-        case GSCT_Puk2:fprintf(stdout, _("PUK2"));break;
-       default:break;
-      }
-      fprintf(stdout, _(" not allowed\n"));
-      break;
-    case GE_NONE:
-      switch (SecurityCode.Type) {
-        case GSCT_SecurityCode:fprintf(stdout, _("Security code"));break;
-        case GSCT_Pin :fprintf(stdout, _("PIN"));break;
-        case GSCT_Pin2:fprintf(stdout, _("PIN2"));break;
-        case GSCT_Puk :fprintf(stdout, _("PUK"));break;
-        case GSCT_Puk2:fprintf(stdout, _("PUK2"));break;
-       default:break;
-      }
-      fprintf(stdout, _(" is %s\n"),SecurityCode.Code);
-      break;
-    default:
-      fprintf(stderr, _("%s\n"),print_error(error));
-      break;
-  }
-
-  GSM->Terminate();
-
-  return 0;
-}
 
 #endif
 
 /* Voice dialing mode. */
 
 #endif
 
 /* Voice dialing mode. */
-
 int dialvoice(char *Number)
 {
 int dialvoice(char *Number)
 {
-  fbusinit(NULL);
-
-  if (GSM->DialVoice(Number)!=GE_NONE) fprintf(stdout,_("Error!\n"));
+       GSM->DialVoice(Number);
 
 
-  GSM->Terminate();
+       GSM->Terminate();
 
 
-  return 0;
+       return 0;
 }
 
 }
 
-/* Cancel a call */
-int cancelcall(void)
+/* The following function allows to send logos using SMS */
+int sendlogo(int argc, char *argv[])
 {
 {
-  fbusinit(NULL);
-
-  if (GSM->CancelCall()!=GE_NONE) fprintf(stdout,_("Error!\n"));
-
-  GSM->Terminate();
+       GSM_SMSMessage SMS;
+       GSM_Bitmap bitmap;
+
+       char Data[sizeof(bitmap.bitmap) +64/*headers safety*/];
+
+       int current=0, i;
+
+       struct option options[] = {
+               SMSC_OPTIONS,
+               { NULL,       0,                 NULL, 0}
+       };
+
+       /* Default settings for SMS message:
+          - no delivery report
+          - Class Message 1
+          - no compression
+          - 8 bit data
+          - SMSC no. 1
+          - validity 3 days
+          - set UserDataHeaderIndicator
+       */
+
+       SMS.Type = GST_MO;
+       SMS.Class = 1;
+       SMS.Compression = false;
+       SMS.EightBit = true;
+       SMS.MessageCenter.No = 1;
+       SMS.Validity = 4320; /* 4320 minutes == 72 hours */
+
+       optarg = NULL;
+       optind = 0;
+       while ((i = getopt_long(argc, argv, "", options, NULL)) != -1) {
+               if (smsc_options_parse(i,&SMS))
+                       continue;
+               switch (i) {
+               default:
+                       usage(); /* Would be better to have an sendsms_usage() here. */
+               }
+       }
 
 
-  return 0;
-}
+/*
+       if (argc!=3 && argc!=4)
+               usage();
+*/
 
 
-int savelogo(int argc, char *argv[])
-{
-  GSM_Bitmap bitmap;
-  GSM_NetworkInfo NetworkInfo;
-  GSM_MultiSMSMessage MultiSMS;
-
-  /* Operator logos will be saved with this number */  
-  char oplogonumber[]={'O','p','L','o','g','o',
-                      '0','0','0','0','0',   /* MMC+MNC */
-                      '\0'};
-  int i=0;
-  
-  bool UnicodeText=false;
-
-  /* The first argument is the type of the logo. */
-  if (!strcmp(argv[0], "op")) {
-    fprintf(stdout, _("Saving operator logo.\n"));
-  } else if (!strcmp(argv[0], "caller")) {
-    fprintf(stdout, _("Saving caller line identification logo.\n"));
-  } else if (!strcmp(argv[0], "startup")) {
-    fprintf(stderr, _("It isn't possible to save startup logo!\n"));
-    return (-1);
-  } else if (!strcmp(argv[0], "7110startup")) {
-    fprintf(stderr, _("It isn't possible to save startup logo!\n"));
-    return (-1);
-  } else if (!strcmp(argv[0], "6210startup")) {
-    fprintf(stderr, _("It isn't possible to save startup logo!\n"));
-    return (-1);
-  } else if (!strcmp(argv[0], "7110op")) {
-    fprintf(stderr, _("It isn't possible to save big operator logos!\n"));
-    return (-1);
-  } else if (!strcmp(argv[0], "picture")) {
-    fprintf(stderr, _("Saving picture image.\n"));
-  } else if (!strcmp(argv[0], "screensaver")) {
-    fprintf(stderr, _("Saving screen saver.\n"));
-  } else {
-    fprintf(stderr, _("You should specify what kind of logo to save!\n"));
-    return (-1);
-  }
-
-  /* The second argument is the bitmap file. */
-  if (GSM_ReadBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) return -1;
-
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
-
-  /* We check optional parameters from 2'rd */
-  optind = 2;
-
-  if (!strcmp(argv[0], "op")) {
-    GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
-  
-    /* The third argument, if present, is the Network code of the operator.
-     * Network code is in this format: "xxx yy" */
-    if (argc > 2) {
-      strcpy(bitmap.netcode, argv[2]);
-#ifdef DEBUG
-      fprintf(stdout, _("Operator code: %s\n"), argv[2]);
-#endif
-      if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown")) {
-       fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
-       GSM->Terminate();
-       return -1;
-      }
-      optind++;
-    } else
-    {
-      if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
-    }
-    bitmap.type=GSM_OperatorLogo;
-
-    /* Put bitmap into SMS structure */
-    GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,false,false);
-
-    oplogonumber[6]=bitmap.netcode[0];
-    oplogonumber[7]=bitmap.netcode[1];
-    oplogonumber[8]=bitmap.netcode[2];
-    oplogonumber[9]=bitmap.netcode[4];
-    oplogonumber[10]=bitmap.netcode[5];
-    for(i=0;i<MultiSMS.number;i++)
-      strcpy(MultiSMS.SMS[i].Destination,oplogonumber);
-  }
-  if (!strcmp(argv[0], "caller")) {
-    GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
-  
-    bitmap.type=GSM_CallerLogo;
-
-    /* Put bitmap into SMS structure */
-    GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,false,false);
-
-    for(i=0;i<MultiSMS.number;i++)
-      strcpy(MultiSMS.SMS[i].Destination,"GroupLogo");
-  }
-  if (!strcmp(argv[0], "screensaver")) {
-    GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
-
-    bitmap.text[0]=0;
-
-    for(i=0;i<argc;i++)
-      if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
-
-    /* Put bitmap into SMS structure */
-    GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,true,UnicodeText);
-
-    for(i=0;i<MultiSMS.number;i++)
-      strcpy(MultiSMS.SMS[i].Destination,"ScreenSaver");
-  }
-  if (!strcmp(argv[0], "picture")) {  
-    GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
-
-    for(i=0;i<argc;i++)
-      if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
-
-    bitmap.text[0]=0;
-    if (argc>2) {
-      optind++;
-      if (strlen(argv[2])>121) {
-        fprintf(stdout,_("Sorry: length of text (parameter \"%s\") can be 121 chars or shorter only !\n"),argv[2]);
-        return -1;
-      }
-      strcpy(bitmap.text,argv[2]);
-    }
-    
-    /* Put bitmap into SMS structure */
-    GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,false,UnicodeText);
+       /* The first argument is the type of the logo. */
+       if (!strcmp(argv[0], "op")) {
+               SMS_SetupUDH(&SMS,GSM_OpLogo);          /* error ignored */
+               fprintf(stdout, _("Sending operator logo.\n"));
+       } else if (!strcmp(argv[0], "caller")) {        /* error ignored */
+               SMS_SetupUDH(&SMS,GSM_CallerIDLogo);
+               fprintf(stdout, _("Sending caller line identification logo.\n"));
+       } else {
+               fprintf(stderr, _("You should specify what kind of logo to send!\n"));
+               return (-1);
+       }
 
 
-    for(i=0;i<MultiSMS.number;i++)
-      strcpy(MultiSMS.SMS[i].Destination,"Picture");
-  }
+       /* The second argument is the destination, ie the phone number of recipient. */
+       strcpy(SMS.Destination,argv[1]);
 
 
-  GSM_SaveMultiPartSMSOnConsole(&MultiSMS, optind,argc,argv,false,true,false,false);
-  
-  return i;
-}
+       /* The third argument is the bitmap file. */
+       GSM_ReadBitmapFile(argv[2], &bitmap);
 
 
-/* The following function allows to send logos using SMS */
-int sendlogo(int argc, char *argv[])
-{
-  GSM_Bitmap bitmap;
-  GSM_NetworkInfo NetworkInfo;
-  GSM_MultiSMSMessage MultiSMS;
-
-  int i;
-
-  bool UnicodeText=false;
-  bool ScreenSaver=false;
-
-  /* The first argument is the type of the logo. */
-  if (!strcmp(argv[0], "op")) {
-    fprintf(stdout, _("Sending operator logo.\n"));
-  } else if (!strcmp(argv[0], "caller")) {
-    fprintf(stdout, _("Sending caller line identification logo.\n"));
-  } else if (!strcmp(argv[0], "picture")) {
-    fprintf(stdout, _("Sending picture image.\n"));
-  } else if (!strcmp(argv[0], "screensaver")) {
-    fprintf(stdout, _("Sending screen saver.\n"));
-  } else if (!strcmp(argv[0], "startup")) {
-    fprintf(stderr, _("It isn't possible to send startup logo!\n"));
-    return (-1);
-  } else if (!strcmp(argv[0], "7110startup")) {
-    fprintf(stderr, _("It isn't possible to send startup logo!\n"));
-    return (-1);
-  } else if (!strcmp(argv[0], "6210startup")) {
-    fprintf(stderr, _("It isn't possible to send startup logo!\n"));
-    return (-1);
-  } else if (!strcmp(argv[0], "7110op")) {
-    fprintf(stderr, _("It isn't possible to send big operator logos!\n"));
-    return (-1);
-  } else {
-    fprintf(stderr, _("You should specify what kind of logo to send!\n"));
-    return (-1);
-  }
-
-  /* The third argument is the bitmap file. */
-  if (GSM_ReadBitmapFileOnConsole(argv[2], &bitmap)!=GE_NONE) return -1;
-
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
-
-  optind = 3;
-
-  if (!strcmp(argv[0], "op")) {
-    GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
-  
-    /* The third argument, if present, is the Network code of the operator.
-     * Network code is in this format: "xxx yy" */
-    if (argc > 3) {
-      strcpy(bitmap.netcode, argv[3]);
+       /* If we are sending op logo we can rewrite network code. */
+       if (!strcmp(argv[0], "op")) {
+               /*
+                * The fourth argument, if present, is the Network code of the operator.
+                * Network code is in this format: "xxx yy".
+                */
+               if (argc > 3) {
+                       strcpy(bitmap.netcode, argv[3]);
 #ifdef DEBUG
 #ifdef DEBUG
-      fprintf(stdout, _("Operator code: %s\n"), argv[3]);
+                       fprintf(stdout, _("Operator code: %s\n"), argv[3]);
 #endif
 #endif
-      if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown")) {
-       fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
-       GSM->Terminate();
-       return -1;
-      }
-      optind++;
-    } else
-    {
-      if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
-    }
-    bitmap.type=GSM_OperatorLogo;
-  }
-  if (!strcmp(argv[0], "caller")) {
-    GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
-  
-    bitmap.type=GSM_CallerLogo;
-  }
-  if (!strcmp(argv[0], "screensaver")) {
-    GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
-
-    bitmap.text[0]=0;
-
-    for(i=0;i<argc;i++)
-      if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
-    
-    ScreenSaver=true;
-  }
-  if (!strcmp(argv[0], "picture")) {  
-    GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
-
-    for(i=0;i<argc;i++)
-      if (!strcmp(argv[i],"--unicode")) UnicodeText=true;
-
-    bitmap.text[0]=0;
-    if (argc>3) {
-      optind++;
-      if (strlen(argv[3])>121) {
-        fprintf(stdout,_("Sorry: length of text (parameter \"%s\") can be 121 chars or shorter only !\n"),argv[3]);
-        return -1;
-      }
-      strcpy(bitmap.text,argv[3]);
-    }
-  }
-
-  /* Put bitmap into SMS structure */
-  GSM_SaveBitmapToSMS(&MultiSMS,&bitmap,ScreenSaver,UnicodeText);
-
-  /* The second argument is the destination, ie the phone number of recipient. */
-  for(i=0;i<MultiSMS.number;i++)
-    strcpy(MultiSMS.SMS[i].Destination,argv[1]);
-
-  GSM_SendMultiPartSMSOnConsole(&MultiSMS, optind,argc,argv,true,false,false);
-
-  return i;
-}
-
-/* Getting logos. */
+               }
 
 
-int getlogo(int argc, char *argv[])
-{
-  GSM_Bitmap bitmap;
-  GSM_Error error;
-  int num;
+               /* Set the network code */
+               Data[current++] = ((bitmap.netcode[1] & 0x0f) << 4) | (bitmap.netcode[0] & 0xf);
+               Data[current++] = 0xf0 | (bitmap.netcode[2] & 0x0f);
+               Data[current++] = ((bitmap.netcode[5] & 0x0f) << 4) | (bitmap.netcode[4] & 0xf);
+       }
 
 
-  bitmap.type=GSM_None;
+       /* Set the logo size */
+       Data[current++] = 0x00;         /* RFU by Nokia */
+       Data[current++] = bitmap.width;
+       Data[current++] = bitmap.height;
 
 
-  if (!strcmp(argv[0],"7110op"))
-    bitmap.type=GSM_7110OperatorLogo;
-    
-  if (!strcmp(argv[0],"op"))
-    bitmap.type=GSM_OperatorLogo;
-    
-  if (!strcmp(argv[0],"caller")) {
-    /* There is caller group number missing in argument list. */
-    if (argc==3) {     
-      num=argv[2][0]-'0';
-      if ((num<1)||(num>9)) num=1;
-      bitmap.number=num;
-    } else
-    {
-      bitmap.number=1;
-    }
-    bitmap.number--;
-    bitmap.type=GSM_CallerLogo;
-  }
-
-  if (!strcmp(argv[0],"picture")) {
-    /* There is a number missing in argument list. */
-    if (argc==3) {     
-      if (strlen(argv[2])==2) {
-        num=(argv[2][0]-'0')*10+(argv[2][1]-'0');
-      } else {
-        num=argv[2][0]-'0';
-      }
-      if (num<1) num=1;
-      bitmap.number=num;
-    } else
-    {
-      bitmap.number=1;
-    }
-    bitmap.number--;
-    bitmap.type=GSM_PictureImage;
-  }    
-
-  if (!strcmp(argv[0],"startup"))
-    bitmap.type=GSM_StartupLogo;
-
-  if (!strcmp(argv[0],"7110startup"))
-    bitmap.type=GSM_7110StartupLogo;
-
-  if (!strcmp(argv[0],"6210startup"))
-    bitmap.type=GSM_6210StartupLogo;
-    
-  if (!strcmp(argv[0],"dealer"))
-    bitmap.type=GSM_DealerNoteText;  
-    
-  if (!strcmp(argv[0],"text"))
-    bitmap.type=GSM_WelcomeNoteText;  
+       Data[current++] = 0x01;         /* depth=number of grayscales */
 
 
-  if (bitmap.type!=GSM_None) {
-  
-    fbusinit(NULL);
-    
-    fprintf(stdout, _("Getting Logo\n"));
-        
-    error=GSM->GetBitmap(&bitmap);
+       memcpy(Data+current,bitmap.bitmap,bitmap.size);
+       current+=bitmap.size;
+       
+       /* Send the message. */
+       sendsms_deconcatenated(&SMS,Data,current,true/*useudh*/);
 
 
-    GSM->Terminate();
-    
-    switch (error)
-    {
-      case GE_NONE:
-        if (bitmap.type==GSM_DealerNoteText) fprintf(stdout, _("Dealer welcome note "));
-        if (bitmap.type==GSM_WelcomeNoteText) fprintf(stdout, _("Welcome note "));     
-        if (bitmap.type==GSM_DealerNoteText || bitmap.type==GSM_WelcomeNoteText)
-       {
-          if (bitmap.text[0]!=0)
-         {
-           fprintf(stdout, _("currently set to \"%s\"\n"), bitmap.text);
-         } else {
-            fprintf(stdout, _("currently empty\n"));
-         }
-        } else
-        {
-          if (bitmap.width!=0)
-          {
-            if (bitmap.type==GSM_OperatorLogo || bitmap.type==GSM_7110OperatorLogo)
-           {
-              fprintf(stdout,"Operator logo for %s (%s) network got succesfully\n",bitmap.netcode,GSM_GetNetworkName(bitmap.netcode));
-           }
-            if (bitmap.type==GSM_StartupLogo || bitmap.type==GSM_7110StartupLogo || bitmap.type==GSM_6210StartupLogo)
-           {
-              fprintf(stdout,"Startup logo got successfully\n");
-           }
-            if (bitmap.type==GSM_CallerLogo)
-           {
-              fprintf(stdout,"Caller logo got successfully\n");
-           }
-            if (bitmap.type==GSM_PictureImage)
-           {
-              fprintf(stdout,"Picture Image got successfully");
-             if (strcmp(bitmap.text,""))
-                fprintf(stdout,_(", text \"%s\""),bitmap.text);                
-             if (strcmp(bitmap.Sender,""))
-                fprintf(stdout,_(", sender \"%s\""),bitmap.Sender);            
-              fprintf(stdout,"\n");
-           }
-            if (argc>1)
-           {
-             if (GSM_SaveBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) return(-1);
-           }
-          } else
-          {
-            fprintf(stdout,"Your phone doesn't have logo uploaded !\n");
-           return -1;
-          }
-        }
-       break;
-      case GE_NOTIMPLEMENTED:
-        fprintf(stderr, _("Function not implemented !\n"));
-        return -1;
-      case GE_NOTSUPPORTED:
-        fprintf(stderr, _("This kind of logo is not supported !\n"));
-        return -1;
-      default:
-        fprintf(stderr, _("Error getting logo (wrong location ?) !\n"));
-        return -1;
-    }
-  } else
-  {
-    fprintf(stderr, _("What kind of logo do you want to get ?\n"));
-    return -1;
-  }
-
-  return 0;
+       GSM->Terminate();
+       return 0;
 }
 
 }
 
-/* Setting logos. */
-
-int setlogo(int argc, char *argv[])
+/* Getting logos. */
+GSM_Error SaveBitmapFileOnConsole(char *FileName, GSM_Bitmap *bitmap)
 {
 {
+       int confirm;
+       char ans[4];
+       struct stat buf;
+       GSM_Error error;
 
 
-  GSM_Bitmap bitmap,oldbit;
-  GSM_NetworkInfo NetworkInfo;
-  GSM_Error error;
-  char model[64];
-  int num;
-  
-  bool ok=true;
-  
-  int i;
-  
-  fbusinit(NULL);
-  
-  if (!strcmp(argv[0],"text") || !strcmp(argv[0],"dealer"))
-  {
-    if (!strcmp(argv[0],"text")) bitmap.type=GSM_WelcomeNoteText;
-                            else bitmap.type=GSM_DealerNoteText;
-    bitmap.text[0]=0x00;
-    if (argc>1) strncpy(bitmap.text,argv[1],255);
-  } else
-  {
-    if (!strcmp(argv[0],"op") || !strcmp(argv[0],"startup") || !strcmp(argv[0],"caller") ||
-        !strcmp(argv[0],"7110op") || !strcmp(argv[0],"6210startup") || !strcmp(argv[0],"7110startup") ||
-       !strcmp(argv[0],"picture"))
-    {
-      if (argc>1)
-      {
-        if (!strcmp(argv[0],"startup"))
-        {
-          bitmap.type=GSM_StartupLogo;
-          bitmap.width=84;
-          bitmap.height=48;
-         bitmap.size=bitmap.width*bitmap.height/8;
-          num=argv[1][0]-'0';
-          if (num>=1 && num<=3) {
-           bitmap.number=num;
-          } else {
-            if (GSM_ReadBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) {
-              GSM->Terminate();
-              return(-1);
-            }
-           bitmap.number=0;
-            GSM_ResizeBitmap(&bitmap,GSM_StartupLogo);
-          }
-        } else {
-          if (GSM_ReadBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) {
-            GSM->Terminate();
-           return(-1);
-          }
-        }
-        if (!strcmp(argv[0],"op"))
-        {
-          if (bitmap.type!=GSM_OperatorLogo || argc<3)
-          {
-           if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
-         }
-          GSM_ResizeBitmap(&bitmap,GSM_OperatorLogo);
-         if (argc==3)
-         {
-           strncpy(bitmap.netcode,argv[2],7);
-           if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown"))
-           {
-             fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
-             return -1;
-           }
-         }
-        }
-        if (!strcmp(argv[0],"7110op"))
-        {
-          if (bitmap.type!=GSM_7110OperatorLogo || argc<3)
-          {
-           if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
-         }
-          GSM_ResizeBitmap(&bitmap,GSM_7110OperatorLogo);
-         if (argc==3)
-         {
-           strncpy(bitmap.netcode,argv[2],7);
-           if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown"))
-           {
-             fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
-             return -1;
-           }
-         }
-        }
-        if (!strcmp(argv[0],"picture"))
-        {
-          GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
-         bitmap.number=1;
-         if (argc>2)
-         {
-            if (strlen(argv[2])==2) {
-              num=(argv[2][0]-'0')*10+(argv[2][1]-'0');
-            } else {
-              num=argv[2][0]-'0';
-            }
-            if (num<1) num=1;  
-           bitmap.number=num;
-          }
-         bitmap.number--;
-         bitmap.text[0]=0;
-         if (argc>3)
-           strncpy(bitmap.text,argv[3],121);
-         strcpy(bitmap.Sender,"\0");
-         if (argc>4)
-           strncpy(bitmap.Sender,argv[4],GSM_MAX_SENDER_LENGTH);
-        }
-        if (!strcmp(argv[0],"7110startup"))
-        {
-          GSM_ResizeBitmap(&bitmap,GSM_7110StartupLogo);
-        }
-        if (!strcmp(argv[0],"6210startup"))
-        {
-          GSM_ResizeBitmap(&bitmap,GSM_6210StartupLogo);
-        }
-        if (!strcmp(argv[0],"caller"))
-        {
-          GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
-          if (argc>2)
-         {
-           num=argv[2][0]-'0';
-           if ((num<0)||(num>9)) num=0;
-           bitmap.number=num;
-          } else
-         {
-           bitmap.number=0;
-         }
-          oldbit.type=GSM_CallerLogo;
-          oldbit.number=bitmap.number;
-          if (GSM->GetBitmap(&oldbit)==GE_NONE)
-         {
-            /* We have to get the old name and ringtone!! */
-           bitmap.ringtone=oldbit.ringtone;
-           strncpy(bitmap.text,oldbit.text,255);
-         }
-          if (argc>3) strncpy(bitmap.text,argv[3],255);          
-        }
-       fprintf(stdout, _("Setting Logo.\n"));
-      } else
-      {
-        /* FIX ME: is it possible to permanently remove op logo ? */
-        if (!strcmp(argv[0],"op"))
-        {
-         bitmap.type=GSM_OperatorLogo;
-         strncpy(bitmap.netcode,"000 00",7);
-         bitmap.width=72;
-         bitmap.height=14;
-         bitmap.size=bitmap.width*bitmap.height/8;
-         GSM_ClearBitmap(&bitmap);
-       }
-        if (!strcmp(argv[0],"7110op"))
-        {
-         bitmap.type=GSM_7110OperatorLogo;
-         strncpy(bitmap.netcode,"000 00",7);
-         bitmap.width=78;
-         bitmap.height=21;
-          bitmap.size=(bitmap.width*bitmap.height + 7)/8;
-         GSM_ClearBitmap(&bitmap);
+       /* Ask before overwriting */
+       while (stat(FileName, &buf) == 0) {
+               confirm = 0;
+               while (!confirm) {
+                       fprintf(stderr, _("Saving logo. File \"%s\" exists. (O)verwrite, create (n)ew or (s)kip ? "), FileName);
+                       GetLine(stdin, ans, 4);
+                       if (!strcmp(ans, "O") || !strcmp(ans, "o")) confirm = 1;
+                       if (!strcmp(ans, "N") || !strcmp(ans, "n")) confirm = 2;
+                       if (!strcmp(ans, "S") || !strcmp(ans, "s")) return GE_USERCANCELED;
+               }  
+               if (confirm == 1) break;
+               if (confirm == 2) {
+                       fprintf(stderr, _("Enter name of new file: "));
+                       GetLine(stdin, FileName, 50);
+                       if (!FileName || (*FileName == 0)) return GE_USERCANCELED;
+               }
        }
        }
-       /* FIX ME: how to remove startup and group logos ? */
-       fprintf(stdout, _("Removing Logo.\n"));
-      }  
-    } else
-    {
-      fprintf(stderr, _("What kind of logo do you want to set ?\n"));
-      GSM->Terminate();
-      return -1;
-    }
-  }
-    
-  while (GSM->GetModel(model)  != GE_NONE)
-    sleep(1);
   
   
-  /* For Nokia 6110/6130/6150 we use different method of uploading.
-     Phone will display menu, when received it */
-  if (!strcmp(model,"NSE-3") || !strcmp(model,"NSK-3") || !strcmp(model,"NSM-1"))
-  {
-    if (!strcmp(argv[0],"caller") && argc<3)
-      bitmap.number=255;
-    if (!strcmp(argv[0],"op") && argc<3)
-      bitmap.number=255;
-  }
-
-  error=GSM->SetBitmap(&bitmap);
+       error = GSM_SaveBitmapFile(FileName, bitmap);
   
   
-  switch (error)
-  {
-    case GE_NONE: oldbit.type=bitmap.type;
-                  oldbit.number=bitmap.number;
-                  if (GSM->GetBitmap(&oldbit)==GE_NONE) {
-                   if (bitmap.type==GSM_WelcomeNoteText ||
-                       bitmap.type==GSM_DealerNoteText) {
-                     if (strcmp(bitmap.text,oldbit.text)) {
-                        fprintf(stderr, _("Error setting"));
-                       if (bitmap.type==GSM_DealerNoteText) fprintf(stderr, _(" dealer"));
-                       fprintf(stderr, _(" welcome note - "));
-
-                        /* I know, it looks horrible, but... */
-                       /* I set it to the short string - if it won't be set */
-                       /* it means, PIN is required. If it will be correct, previous */
-                       /* (user) text was too long */
-
-                       /* Without it, I could have such thing: */
-                       /* user set text to very short string (for example, "Marcin") */
-                       /* then enable phone without PIN and try to set it to the very long (too long for phone) */
-                       /* string (which start with "Marcin"). If we compare them as only length different, we could think, */
-                       /* that phone accepts strings 6 chars length only (length of "Marcin") */
-                       /* When we make it correct, we don't have this mistake */
-                       
-                       strcpy(oldbit.text,"!\0");
-                       GSM->SetBitmap(&oldbit);
-                       GSM->GetBitmap(&oldbit);
-                       if (oldbit.text[0]!='!') {
-                         fprintf(stderr, _("SIM card and PIN is required\n"));
-                       } else {
-                         GSM->SetBitmap(&bitmap);
-                         GSM->GetBitmap(&oldbit);
-                         fprintf(stderr, _("too long, truncated to \"%s\" (length %i)\n"),oldbit.text,strlen(oldbit.text));
-                       }
-                        ok=false;
-                     }
-                   } else {
-                     if (bitmap.type==GSM_StartupLogo) {
-                       for (i=0;i<oldbit.size;i++) {
-                         if (oldbit.bitmap[i]!=bitmap.bitmap[i]) {
-                           fprintf(stderr, _("Error setting startup logo - SIM card and PIN is required\n"));
-                           ok=false;
-                           break;
-                         }
-                       }
-                     }
-                   }
-                 }
-                 if (ok) fprintf(stdout, _("Done.\n"));
-                  break;
-    case GE_NOTIMPLEMENTED:fprintf(stderr, _("Function not implemented.\n"));
-                           break;
-    case GE_NOTSUPPORTED:fprintf(stderr, _("This kind of logo is not supported.\n"));
-                           break;
-    default:fprintf(stderr, _("Error (wrong location ?) !\n"));
-            break;
-  }
+       switch (error) {
+       case GE_CANTOPENFILE:
+               fprintf(stderr, _("Failed to write file \"%s\"\n"), FileName);
+               break;
+       default:
+               break;
+       }
   
   
-  GSM->Terminate();
-
-  return 0;
+       return error;
 }
 
 }
 
-/* Calendar notes receiving. */
-
-int getcalendarnote(int argc, char *argv[])
+int getlogo(int argc, char *argv[])
 {
 {
-  GSM_CalendarNote CalendarNote;
-  GSM_NotesInfo NotesInfo;
-  GSM_Error error;
-  int i;
-  int vCalVer=0;
-  bool vInfo=false;
-  int start, stop;
-  bool was_note=false;
-  char z_text[MAX_CALENDAR_TEXT_LENGTH+11];
-
-  /* Hopefully is 64 larger as FB38_MAX* / FB61_MAX* */
-  char model[64];
-
-  struct tm *now;
-  time_t nowh;
-  GSM_DateTime Date;
-
-  nowh=time(NULL);
-  now=localtime(&nowh);
-  
-  Date.Year = now->tm_year;
-
-  /* I have 100 (for 2000) Year now :-) */
-  if (Date.Year>99 && Date.Year<1900) {
-    Date.Year=Date.Year+1900;
-  }
-
-  start=atoi(argv[0]);  
-  stop=start;
-  
-  switch (argc) {
-    case 2:
-      if (!strcmp(argv[argc-1],"-v10")) {
-        vCalVer=10;
-      } else {
-        if (!strcmp(argv[argc-1],"-v30")) {
-          vCalVer=30;
-        } else {
-          stop=atoi(argv[1]);
-        }
-      }
-      break;
-    case 3:
-      stop=atoi(argv[1]);
-      if (!strcmp(argv[argc-1],"-v10")) {
-        vCalVer=10;
-      } else {
-        if (!strcmp(argv[argc-1],"-v30")) {
-          vCalVer=30;
-        } else {      
-          usage();
-          return -1;
-       }
-      }
-      break;
-  }
-
-  fbusinit(NULL);
+       GSM_Bitmap bitmap;
+       GSM_Error error;
+       GSM_Statemachine *sm = &State;
 
 
-  while (GSM->GetModel(model)  != GE_NONE)
-    sleep(1);
+       bitmap.type=GSM_None;
 
 
-  if (!strcmp(argv[0],"-s") || !strcmp(argv[0],"--short")) 
-    vInfo=true;
-  else if (!isdigit(argv[0][0])) {
-    usage();
-    return -1;
-  }
+       if (!strcmp(argv[0], "op"))
+               bitmap.type = GSM_OperatorLogo;
     
     
-  error=GSM->GetCalendarNotesInfo(&NotesInfo);
-  if ( error == GE_NONE ) {
-     if( NotesInfo.HowMany == 0 ) {
-        fprintf(stderr, _("Sorry! No Calendar Notes present on phone.\n"));
-        start=0; stop=(-1); /* This for skipping next 'for' loop ;-> */
-      }
-#ifdef DEBUG
-      fprintf(stdout, _(" CALENDAR NOTES INFO \n"));
-      fprintf(stdout, _("---------------------\n"));
-      fprintf(stdout, _("How Many Locations :%d\n"), NotesInfo.HowMany);
-
-      /* For 6210 (NPE-3) and 7110 (NSE-5), Locations have a different behaviour */
-      if ( GetModelFeature (FN_CALENDAR)==F_CAL71 ) {
-       fprintf(stdout, _("Locations are :\n"));
-       for(i=0;i<NotesInfo.HowMany;i++)
-           fprintf(stdout, _("%4d) %4d\n"), i+1, NotesInfo.Location[i]);
-      }
-#endif
-  } else {
-      /* For 6210 (NPE-3) and 7110 (NSE-5), Locations have a different behaviour */
-      if ( GetModelFeature (FN_CALENDAR)==F_CAL71 ) {
-        fprintf(stderr, _("Can't read Notes Infos from phone.\n"));
-       start=0; stop=(-1); /* This for skipping next 'for' loop ;-> */
-      }
-  }
-
-  if (GetModelFeature (FN_CALENDAR)!=F_CAL71) {
-    error=GE_NONE;
-    NotesInfo.HowMany=200;
-    for (i=0;i<200;i++) {
-      NotesInfo.Location[i]=i+1;
-    }
-  }
-  
-  if( vInfo && stop!=(-1) && error==GE_NONE )
-  {
-    /* Info datas (for 7110 and comp.) */
-    fprintf(stdout, _(" CALENDAR NOTES SUMMARY INFORMATION \n"));
-    fprintf(stdout, _(" ==================================\n"));
-    if (GetModelFeature (FN_CALENDAR)==F_CAL71) {
-      fprintf(stdout, _("Calendar notes present on phone: %d\n"), NotesInfo.HowMany);
-      fprintf(stdout, _("Locations are :\n"));
-    }
-    fprintf(stdout,  "----------------------------------------------------------------------------\n");
-    fprintf(stdout,_(" Loc Phys Type    Summary description              Dt start    Alarm  Recurs\n") );
-    fprintf(stdout,  "----------------------------------------------------------------------------\n");
-
-    for(i=0;i<NotesInfo.HowMany;i++)
-    {
-      /* very short format ... */
-      /*
-      fprintf(stdout, _("%4d) %4d\n"), i, NotesInfo.Location[i]);
-      */
-      CalendarNote.Location=i+1;
-      CalendarNote.ReadNotesInfo=false;
-
-      if (GSM->GetCalendarNote(&CalendarNote) == GE_NONE) {
-        char z_type[11];
-        char z_recur[15];
-        switch (CalendarNote.Type) {
-           case GCN_REMINDER:strcpy(z_type, "REMIND");  break;
-           case GCN_CALL:    strcpy(z_type, "CALL");    break;
-           case GCN_MEETING: strcpy(z_type, "MEETING"); break;
-           case GCN_BIRTHDAY:strcpy(z_type, "BDAY");    break;
-           default:          strcpy(z_type, "UNKNOWN"); break;
-          }
-
-        if( CalendarNote.Recurrance ) {
-          sprintf( z_recur,"%d ", CalendarNote.Recurrance/24 );
-          strcat( z_recur, CalendarNote.Recurrance == 1 ? "day" : "days" );
-        }
-        else
-          strcpy( z_recur, "No" );
-
-        strcpy(z_text,"");
-       
-        if( CalendarNote.Type == GCN_CALL )
-          sprintf(z_text, "\"%s\"", CalendarNote.Phone );
-         
-        if (CalendarNote.Text[0]!=0)
-          sprintf(z_text, "\"%s\"", CalendarNote.Text );
-         
-        if(CalendarNote.Type == GCN_BIRTHDAY) {
-          int i_age;
-          i_age = Date.Year - CalendarNote.Time.Year;
-          sprintf(z_text, "\"%s (%d %s)\"", CalendarNote.Text,
-             i_age, (i_age==1)?"year":"years");
-          strcpy( z_recur, "-" );
-         if (GetModelFeature (FN_CALENDAR)==F_CAL71)
-            fprintf(stdout,
-                _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s %s\n"), 
-              i+1,NotesInfo.Location[i], z_type, z_text,
-              CalendarNote.Time.Year, 
-              CalendarNote.Time.Month, 
-              CalendarNote.Time.Day,
-              (CalendarNote.AlarmType==0x00) ? "Tone  " : "Silent",
-              " " );
-         else
-            fprintf(stdout,
-                _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s %s\n"), 
-              i+1,NotesInfo.Location[i], z_type, z_text,
-              CalendarNote.Time.Year, 
-              CalendarNote.Time.Month, 
-              CalendarNote.Time.Day,
-             (CalendarNote.Alarm.Year) ? "Yes" : "No ",
-              " " );
-        } else
-         if (GetModelFeature (FN_CALENDAR)==F_CAL71)
-            fprintf(stdout,
-                _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s    %s\n"), 
-              i+1,NotesInfo.Location[i], z_type, z_text,
-              CalendarNote.Time.Year, 
-              CalendarNote.Time.Month, 
-              CalendarNote.Time.Day,
-              (CalendarNote.Alarm.Year) ? "Yes" : "No ",
-              z_recur );
-           else
-            fprintf(stdout,
-                _("%4d %4d %-7.7s %-32.32s %04d-%02d-%02d  %s\n"), 
-              i+1,NotesInfo.Location[i], z_type, z_text,
-              CalendarNote.Time.Year, 
-              CalendarNote.Time.Month, 
-              CalendarNote.Time.Day,
-              (CalendarNote.Alarm.Year) ? "Yes" : "No ");
-      } else {
-        if (GetModelFeature (FN_CALENDAR)!=F_CAL71) break;
-      }
-    }
-  }
-  else
-  for (i=start;i<=stop;i++) {
-    if (error==GE_NONE) {
-       if( i>NotesInfo.HowMany ) {
-           fprintf(stderr, _("Only %d Calendar Notes present on phone!\n"),NotesInfo.HowMany);
-           break;
-       }
-       if( i==0 ) {
-           fprintf(stderr, _("Calendar Notes location can't be zero... skipping.\n"));
-           continue;
+       if (!strcmp(argv[0], "caller")) {
+               /* There is caller group number missing in argument list. */
+               if (argc == 3) {     
+                       bitmap.number=argv[2][0]-'0';
+                       if ((bitmap.number < 0) || (bitmap.number > 9)) bitmap.number = 0;
+               } else {
+                       bitmap.number = 0;
+               }
+               bitmap.type = GSM_CallerLogo;
        }
        }
-    }
     
     
-    CalendarNote.Location=i;
-    CalendarNote.ReadNotesInfo=false;
-
-    if (GSM->GetCalendarNote(&CalendarNote) == GE_NONE) {
-
-      if (vCalVer!=0) {
-        if (!was_note) {
-          fprintf(stdout, GSM_GetVCALENDARStart(vCalVer));
-         was_note=true;
-        }
-
-        fprintf(stdout, GSM_GetVCALENDARNote(&CalendarNote,vCalVer));
-
-      } else {  /* not vCal */
-
-        if (was_note) {
-         fprintf(stdout, "\n");
-        } else {
-          was_note=true;
-       }
-
-        fprintf(stdout, _("   Type of the note: "));
-
-        switch (CalendarNote.Type) {
-
-         case GCN_REMINDER:fprintf(stdout, _("Reminder\n"));break;
-          case GCN_CALL    :fprintf(stdout, _("Call\n"));    break;
-          case GCN_MEETING :fprintf(stdout, _("Meeting\n")); break;
-          case GCN_BIRTHDAY:fprintf(stdout, _("Birthday\n"));break;
-         default:          fprintf(stdout, _("Unknown\n"));
-
-       }
-
-        /* For 3310: set date to 2090! */
-        if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
-          fprintf(stdout, _("   Date: xxxx-%02d-%02d\n"), CalendarNote.Time.Month,
-                                                          CalendarNote.Time.Day);
+       if (!strcmp(argv[0],"startup"))
+               bitmap.type = GSM_StartupLogo;
+       else if (!strcmp(argv[0], "dealer"))
+               bitmap.type = GSM_DealerNoteText;  
+       else if (!strcmp(argv[0], "text"))
+               bitmap.type=GSM_WelcomeNoteText;  
+
+       if (bitmap.type != GSM_None) {
+    
+               fprintf(stdout, _("Getting Logo\n"));
+        
+               data.Bitmap=&bitmap;
+               error=SM_Functions(GOP_GetBitmap, &data, sm);
+               switch (error) {
+               case GE_NONE:
+                       if (bitmap.type == GSM_DealerNoteText) fprintf(stdout, _("Dealer welcome note "));
+                       if (bitmap.type == GSM_WelcomeNoteText) fprintf(stdout, _("Welcome note "));    
+                       if (bitmap.type == GSM_DealerNoteText || bitmap.type==GSM_WelcomeNoteText) {
+                               if (bitmap.text[0]) {
+                                       fprintf(stdout, _("currently set to \"%s\"\n"), bitmap.text);
+                               } else {
+                                       fprintf(stdout, _("currently empty\n"));
+                               }
+                       } else {
+                               if (bitmap.width) {
+                                       switch (bitmap.type) {
+                                       case GSM_OperatorLogo:
+                                               fprintf(stdout,"Operator logo for %s (%s) network got succesfully\n",bitmap.netcode,GSM_GetNetworkName(bitmap.netcode));
+                                               if (argc==3) {
+                                                       strncpy(bitmap.netcode,argv[2], 7);
+                                                       if (!strcmp(GSM_GetNetworkName(bitmap.netcode), "unknown")) {
+                                                               fprintf(stderr, "Sorry, gnokii doesn't know %s network !\n", bitmap.netcode);
+                                                               return -1;
+                                                       }
+                                               }
+                                               break;
+                                       case GSM_StartupLogo:
+                                               fprintf(stdout, "Startup logo got successfully\n");
+                                               if (argc == 3) {
+                                                       strncpy(bitmap.netcode,argv[2], 7);
+                                                       if (!strcmp(GSM_GetNetworkName(bitmap.netcode), "unknown")) {
+                                                               fprintf(stderr, "Sorry, gnokii doesn't know %s network !\n", bitmap.netcode);
+                                                               return -1;
+                                                       }
+                                               }
+                                               break;
+                                       case GSM_CallerLogo:
+                                               fprintf(stdout,"Caller logo got successfully\n");
+                                               if (argc == 4) {
+                                                       strncpy(bitmap.netcode,argv[3],7);
+                                                       if (!strcmp(GSM_GetNetworkName(bitmap.netcode), "unknown")) {
+                                                               fprintf(stderr, "Sorry, gnokii doesn't know %s network !\n", bitmap.netcode);
+                                                               return -1;
+                                                       }
+                                               }
+                                               break;
+                                       default:
+                                               fprintf(stdout,"Unknown bitmap type.\n");
+                                               break;
+                                       }
+                                       if (argc > 1) {
+                                               if (SaveBitmapFileOnConsole(argv[1], &bitmap) != GE_NONE) return (-1);
+                                       }
+                               } else {
+                                       fprintf(stdout,"Your phone doesn't have logo uploaded !\n");
+                                       return -1;
+                               }
+                       }
+                       break;
+               case GE_NOTIMPLEMENTED:
+                       fprintf(stderr, _("Function not implemented !\n"));
+                       return -1;
+               case GE_NOTSUPPORTED:
+                       fprintf(stderr, _("This kind of logo is not supported !\n"));
+                       return -1;
+               default:
+                       fprintf(stderr, _("Error getting logo !\n"));
+                       return -1;
+               }
        } else {
        } else {
-          fprintf(stdout, _("   Date: %s %d-%02d-%02d\n"), 
-               DayOfWeek(CalendarNote.Time.Year, CalendarNote.Time.Month, CalendarNote.Time.Day),
-                                                       CalendarNote.Time.Year,
-                                                        CalendarNote.Time.Month,
-                                                        CalendarNote.Time.Day);
-       }
-       
-        fprintf(stdout, _("   Time: %02d:%02d:%02d\n"), CalendarNote.Time.Hour,
-                                                        CalendarNote.Time.Minute,
-                                                        CalendarNote.Time.Second);
-
-        if (CalendarNote.Alarm.Year!=0) {
-          fprintf(stdout, _("   Alarm date: %s %d-%02d-%02d\n"), 
-                       DayOfWeek(CalendarNote.Alarm.Year, CalendarNote.Alarm.Month, CalendarNote.Alarm.Day),
-                                                             CalendarNote.Alarm.Year,
-                                                              CalendarNote.Alarm.Month,
-                                                              CalendarNote.Alarm.Day);
-
-          fprintf(stdout, _("   Alarm time: %02d:%02d:%02d\n"), CalendarNote.Alarm.Hour,
-                                                                CalendarNote.Alarm.Minute,
-                                                                CalendarNote.Alarm.Second);
-          if ( GetModelFeature (FN_CALENDAR)==F_CAL71 ) 
-            fprintf(stdout, _("   Alarm type: %s\n"), (CalendarNote.AlarmType==0x00) ?
-                                                          "With Tone" : "Silent" );
-        }
-
-        if ( GetModelFeature (FN_CALENDAR)==F_CAL71 && CalendarNote.Recurrance!= 0 ) 
-           fprintf(stdout, "   It repeat every %d day%s\n", CalendarNote.Recurrance/24,
-                       ((CalendarNote.Recurrance/24)>1) ? "s":"" );
-
-        if (CalendarNote.Type == GCN_BIRTHDAY)
-        {
-          int i_age;
-          i_age = Date.Year - CalendarNote.Time.Year;
-          fprintf(stdout, _("   Text: %s (%d %s)\n"), CalendarNote.Text,
-              i_age, (i_age==1)?"year":"years");
-        } else {
-          if (CalendarNote.Text[0]!=0)
-           fprintf(stdout, _("   Text: %s\n"), CalendarNote.Text);
+               fprintf(stderr, _("What kind of logo do you want to get ?\n"));
+               return -1;
        }
 
        }
 
-        if (CalendarNote.Type == GCN_CALL)
-          fprintf(stdout, _("   Phone: %s\n"), CalendarNote.Phone);
-      }
-    } else {
-      fprintf(stderr, _("The calendar note %i can not be read\n"),i);
-    }
-  }
-
-  if (was_note && vCalVer!=0) {
-    fprintf(stdout, GSM_GetVCALENDAREnd(vCalVer));
-  }
-  
-  GSM->Terminate();
-
-  return 0;
+       return 0;
 }
 
 }
 
-/* Writing calendar notes. */
 
 
-int writecalendarnote(char *argv[])
+/* Sending logos. */
+GSM_Error ReadBitmapFileOnConsole(char *FileName, GSM_Bitmap *bitmap)
 {
 {
-  GSM_CalendarNote CalendarNote;
-  GSM_Error error;
-  int number;
-
-  number=atoi(argv[1]);
+       GSM_Error error;
   
   
-  if (number<1) {
-    fprintf(stdout, _("Number of calendar note must be 1 or higher\n"));
-    return -1;
-  }
+       error = GSM_ReadBitmapFile(FileName, bitmap);
   
   
-  switch ( GSM_ReadVCalendarFile(argv[0], &CalendarNote, &number) ) {
-    case GE_NONE:
-      break;
-    case GE_CANTOPENFILE:
-      fprintf(stdout, _("Failed to open vCalendar file \"%s\"\n"),argv[0]);
-      return -1;
-    case GE_TOOSHORT:
-      fprintf(stdout, _("Number of given calendar note is too high (max=%i)\n"),number);
-      return(-1);
-    default:
-      fprintf(stdout, _("Failed to parse vCalendar file \"%s\"\n"),argv[0]);
-      return -1;    
-  }
-
-  fbusinit(NULL);
-
-  /* Error 22=Calendar full ;-) */
-
-  error=GSM->WriteCalendarNote(&CalendarNote);
-  switch (error) {
-    case GE_NONE:
-      fprintf(stdout, _("Succesfully written!\n"));break;
-    case GE_TOOLONG:
-      fprintf(stdout, _("Too long text in calendar note!\n"));break;
-    default:
-      fprintf(stdout, _("Failed to write calendar note!\n"));break;
-  }
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Calendar note deleting. */
-
-int deletecalendarnote(char *Index)
-{
-
-  GSM_CalendarNote CalendarNote;
-
-  CalendarNote.Location=atoi(Index);
-
-  fbusinit(NULL);
-
-  if (GSM->DeleteCalendarNote(&CalendarNote) == GE_NONE) {
-    fprintf(stdout, _("   Calendar note deleted.\n"));
-  }
-  else {
-    fprintf(stderr, _("The calendar note can not be deleted\n"));
-
-    GSM->Terminate();
-    return -1;
-  }
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Setting the date and time. */
-
-int setdatetime(int argc, char *argv[])
-{
-  struct tm *now;
-  time_t nowh;
-  GSM_DateTime Date;
-
-  fbusinit(NULL);
-
-  nowh=time(NULL);
-  now=localtime(&nowh);
-
-  Date.Year = now->tm_year;
-  Date.Month = now->tm_mon+1;
-  Date.Day = now->tm_mday;
-  Date.Hour = now->tm_hour;
-  Date.Minute = now->tm_min;
-  Date.Second = now->tm_sec;
-
-  if (argc>0) Date.Year = atoi (argv[0]);
-  if (argc>1) Date.Month = atoi (argv[1]);
-  if (argc>2) Date.Day = atoi (argv[2]);
-  if (argc>3) Date.Hour = atoi (argv[3]);
-  if (argc>4) Date.Minute = atoi (argv[4]);
-
-  if (Date.Year<1900)
-  {
-
-    /* Well, this thing is copyrighted in U.S. This technique is known as
-       Windowing and you can read something about it in LinuxWeekly News:
-       http://lwn.net/1999/features/Windowing.phtml. This thing is beeing
-       written in Czech republic and Poland where algorithms are not allowed
-       to be patented. */
-
-    if (Date.Year>90)
-      Date.Year = Date.Year+1900;
-    else
-      Date.Year = Date.Year+2000;
-  }
-
-  /* FIXME: Error checking should be here. */
-  GSM->SetDateTime(&Date);
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* In this mode we receive the date and time from mobile phone. */
-
-int getdatetime(void) {
-
-  GSM_DateTime date_time;
-
-  fbusinit(NULL);
-
-  if (GSM->GetDateTime(&date_time)==GE_NONE) {
-    if (date_time.IsSet) {
-      fprintf(stdout, _("Date: %s %4d/%02d/%02d\n"), 
-          DayOfWeek(date_time.Year, date_time.Month, date_time.Day),
-          date_time.Year, date_time.Month, date_time.Day);
-      fprintf(stdout, _("Time: %02d:%02d:%02d\n"), date_time.Hour, date_time.Minute, date_time.Second);
-    } else {
-      fprintf(stdout, _("Date and time not set in phone\n"));
-    }
-  } else {
-    fprintf(stdout,_("Error!\n"));
-  }
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Setting the alarm. */
-
-int setalarm(char *argv[])
-{
-
-  GSM_DateTime Date;
-
-  fbusinit(NULL);
-
-  Date.Hour = atoi(argv[0]);
-  Date.Minute = atoi(argv[1]);
-
-  GSM->SetAlarm(1, &Date);
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Getting the alarm. */
-
-int getalarm(void) {
-
-  GSM_DateTime date_time;
-
-  fbusinit(NULL);
-
-  if (GSM->GetAlarm(0, &date_time)==GE_NONE) {
-    fprintf(stdout, _("Alarm: %s\n"), (date_time.IsSet)?"on":"off");
-    fprintf(stdout, _("Time: %02d:%02d\n"), date_time.Hour, date_time.Minute);
-  } else {
-    fprintf(stdout,_("Error!\n"));
-  }
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* In monitor mode we don't do much, we just initialise the fbus code.
-   Note that the fbus code no longer has an internal monitor mode switch,
-   instead compile with DEBUG enabled to get all the gumpf. */
-
-int monitormode(int argc, char *argv[])
-{
-
-  float rflevel=-1, batterylevel=-1;
-       unsigned char loop=1;
-
-  GSM_PowerSource powersource=-1;
-  GSM_RFUnits rf_units = GRF_Arbitrary;
-  GSM_BatteryUnits batt_units = GBU_Arbitrary;
-
-  GSM_NetworkInfo NetworkInfo;
-  GSM_CBMessage CBMessage;
-
-  GSM_MemoryStatus SIMMemoryStatus = {GMT_SM, 0, 0};
-  GSM_MemoryStatus PhoneMemoryStatus = {GMT_ME, 0, 0};
-  GSM_MemoryStatus DC_MemoryStatus = {GMT_DC, 0, 0};
-  GSM_MemoryStatus EN_MemoryStatus = {GMT_EN, 0, 0};
-  GSM_MemoryStatus FD_MemoryStatus = {GMT_FD, 0, 0};
-  GSM_MemoryStatus LD_MemoryStatus = {GMT_LD, 0, 0};
-  GSM_MemoryStatus MC_MemoryStatus = {GMT_MC, 0, 0};
-  GSM_MemoryStatus ON_MemoryStatus = {GMT_ON, 0, 0};
-  GSM_MemoryStatus RC_MemoryStatus = {GMT_RC, 0, 0};
-
-  GSM_SMSStatus SMSStatus = {0, 0};
-
-  char Number[20];
-
-       /* evaluate for presence of "-noloop" argument in parameter */
-       if(argc>0)
-       {
-               if( strcmp(argv[0],"-noloop" ) && strcmp(argv[0],"-nl" ))
-               {
-                       usage();
-                       return -1;
-               }
-               else
-                       loop=0;
-       }
-
-  /* We do not want to monitor serial line forever - press Ctrl+C to stop the
-     monitoring mode. */
-
-  signal(SIGINT, interrupted);
-
-  fprintf (stderr, _("Entering monitor mode...\n"));
-  fprintf (stderr, _("Initialising GSM interface...\n"));
-
-  /* Initialise the code for the GSM interface. */     
-
-  fbusinit(NULL);
-
-  sleep(1);
-  GSM->EnableCellBroadcast();
-
-  /* Loop here indefinitely - allows you to see messages from GSM code in
-     response to unknown messages etc. The loops ends after pressing the
-     Ctrl+C. */
-  while (!bshutdown) {
-    if (GSM->GetRFLevel(&rf_units, &rflevel) == GE_NONE)
-      fprintf(stdout, _("RFLevel: %d\n"), (int)rflevel);
-
-    if (GSM->GetBatteryLevel(&batt_units, &batterylevel) == GE_NONE)
-      fprintf(stdout, _("Battery: %d\n"), (int)batterylevel);
-
-    if (GSM->GetPowerSource(&powersource) == GE_NONE)
-      fprintf(stdout, _("Power Source: %s\n"), (powersource==GPS_ACDC)?_("AC/DC"):_("battery"));
-
-    if (GSM->GetMemoryStatus(&SIMMemoryStatus) == GE_NONE)
-      fprintf(stdout, _("SIM: Used %d, Free %d\n"), SIMMemoryStatus.Used, SIMMemoryStatus.Free);
-
-    if (GSM->GetMemoryStatus(&PhoneMemoryStatus) == GE_NONE)
-      fprintf(stdout, _("Phone: Used %d, Free %d\n"), PhoneMemoryStatus.Used, PhoneMemoryStatus.Free);
-
-    if (GSM->GetMemoryStatus(&DC_MemoryStatus) == GE_NONE)
-      fprintf(stdout, _("DC: Used %d, Free %d\n"), DC_MemoryStatus.Used, DC_MemoryStatus.Free);
-
-    if (GSM->GetMemoryStatus(&EN_MemoryStatus) == GE_NONE)
-      fprintf(stdout, _("EN: Used %d, Free %d\n"), EN_MemoryStatus.Used, EN_MemoryStatus.Free);
-
-    if (GSM->GetMemoryStatus(&FD_MemoryStatus) == GE_NONE)
-      fprintf(stdout, _("FD: Used %d, Free %d\n"), FD_MemoryStatus.Used, FD_MemoryStatus.Free);
-
-    if (GSM->GetMemoryStatus(&LD_MemoryStatus) == GE_NONE)
-      fprintf(stdout, _("LD: Used %d, Free %d\n"), LD_MemoryStatus.Used, LD_MemoryStatus.Free);
-
-    if (GSM->GetMemoryStatus(&MC_MemoryStatus) == GE_NONE)
-      fprintf(stdout, _("MC: Used %d, Free %d\n"), MC_MemoryStatus.Used, MC_MemoryStatus.Free);
-
-    if (GSM->GetMemoryStatus(&ON_MemoryStatus) == GE_NONE)
-      fprintf(stdout, _("ON: Used %d, Free %d\n"), ON_MemoryStatus.Used, ON_MemoryStatus.Free);
-
-    if (GSM->GetMemoryStatus(&RC_MemoryStatus) == GE_NONE)
-      fprintf(stdout, _("RC: Used %d, Free %d\n"), RC_MemoryStatus.Used, RC_MemoryStatus.Free);
-
-    if (GSM->GetSMSStatus(&SMSStatus) == GE_NONE)
-      fprintf(stdout, _("SMS Messages: UnRead %d, Number %d\n"), SMSStatus.UnRead, SMSStatus.Number);
-
-    if (GSM->GetIncomingCallNr(Number) == GE_NONE)
-      fprintf(stdout, _("Incoming call: %s\n"), Number);
-
-    if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE)
-      fprintf(stdout, _("Network: %s (%s), LAC: %s, CellID: %s\n"), GSM_GetNetworkName (NetworkInfo.NetworkCode), GSM_GetCountryName(NetworkInfo.NetworkCode), NetworkInfo.LAC, NetworkInfo.CellID);
-
-    if (GSM->ReadCellBroadcast(&CBMessage) == GE_NONE)
-      fprintf(stdout, _("Cell broadcast received on channel %d: %s\n"), CBMessage.Channel, CBMessage.Message);
-
-    if( !loop ) break;
-           
-    sleep(1);
-  }
-
-  if( loop ) fprintf (stderr, _("Leaving monitor mode...\n"));
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Shows texts from phone's display */
-
-int displayoutput()
-{
-
-  GSM_Error error;
-  
-  fbusinit(NULL);
-
-  error=GSM->EnableDisplayOutput();
-
-  if (error == GE_NONE)
-  {
-
-    /* We do not want to see texts forever - press Ctrl+C to stop. */
-
-    signal(SIGINT, interrupted);    
-
-    fprintf (stderr, _("Entering display monitoring mode...\n"));
-
-    /* Loop here indefinitely - allows you to read texts from phone's
-       display. The loops ends after pressing the Ctrl+C. */
-
-    while (!bshutdown)
-      sleep(1);
-
-    fprintf (stderr, _("Leaving display monitor mode...\n"));
-
-    error=GSM->DisableDisplayOutput();
-    if (error!=GE_NONE)
-      fprintf (stderr, _("Error!\n"));
-  } else
-      fprintf (stderr, _("Error!\n"));
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Displays names of available ringtones */
-int allringtones()
-{
-  char model[64], rev[64];
-  int i;
-
-  fbusinit(NULL);
-
-  while (GSM->GetRevision(rev) != GE_NONE)
-    sleep(1);
-
-  while (GSM->GetModel(model)  != GE_NONE)
-    sleep(1);
-
-  strncpy(rev,rev+2,5);
-  rev[5]=0;
-  PrepareRingingTones(model,rev);
-  
-  for (i=1;i<=NumberOfRingtones();i++)
-  {
-    fprintf(stdout,_("%i. %s\n"),i,RingingToneName(0,i));
-  }
-  
-  GSM->Terminate();
-
-  return 0;
-
-}
-
-/* Reads profile from phone and displays its' settings */
-
-int getprofile(int argc, char *argv[])
-{
-
-  int max_profiles;
-  int start, stop, i;
-  GSM_Profile profile;
-  GSM_Error error;
-  
-  /* Hopefully is 64 larger as FB38_MAX* / FB61_MAX* */
-  char model[64], rev[64];
-
-  /* Initialise the code for the GSM interface. */     
-
-  fbusinit(NULL);
-
-  profile.Number = 0;
-  error=GSM->GetProfile(&profile);
-
-  if (error == GE_NONE)
-  {
-  
-    while (GSM->GetModel(model)  != GE_NONE) sleep(1);
-
-    while (GSM->GetRevision(rev) != GE_NONE) sleep(1);
-
-    strncpy(rev,rev+2,5);
-    rev[5]=0;
-    PrepareRingingTones(model,rev);
-
-    switch(GetModelFeature (FN_PROFILES)) {
-      case F_PROF33:max_profiles=6;break;
-      case F_PROF51:max_profiles=3;break;
-      default      :max_profiles=7;break;
-    }
-
-    if (argc>0)
-    {
-      profile.Number=atoi(argv[0])-1;
-      start=profile.Number;
-      stop=start+1;
-
-      if (profile.Number < 0)
-      {
-         fprintf(stderr, _("Profile number must be value from 1 to %d!\n"), max_profiles);
-         GSM->Terminate();
-         return -1;
-      }
-
-      if (profile.Number >= max_profiles)
-      {
-         fprintf(stderr, _("This phone supports only %d profiles!\n"), max_profiles);
-         GSM->Terminate();
-         return -1;
-      }
-    } else {
-      start=0;
-      stop=max_profiles;
-    }
-
-    i=start;
-    while (i<stop)
-    {
-      profile.Number=i;
-
-      if (profile.Number!=0) GSM->GetProfile(&profile);
-
-      printf("%d. \"%s\"", (profile.Number+1), profile.Name);
-      if (profile.DefaultName==-1) printf(" (name defined)");
-      printf("\n");
-
-#ifdef DEBUG
-      printf("Incoming call alert: %d\n", profile.CallAlert);
-      printf("Ringtone ID: %d\n", profile.Ringtone);
-      printf("Ringing volume: %d\n", profile.Volume);
-      printf("Message alert tone: %d\n", profile.MessageTone);
-      printf("Keypad tones: %d\n", profile.KeypadTone);
-      printf("Warning and game tones: %d\n", profile.WarningTone);
-      printf("Lights: %d\n", profile.Lights);
-      printf("Vibration: %d\n", profile.Vibration);
-      printf("Caller groups: 0x%02x\n", profile.CallerGroups);
-      printf("Automatic answer: %d\n", profile.AutomaticAnswer);
-      printf("Screen saver: %d\n", profile.ScreenSaver);
-      printf("\n");
-#endif
-      
-      printf("Incoming call alert: %s\n", GetProfileCallAlertString(profile.CallAlert));
-
-      /* For different phones different ringtones names */
-      if (strcmp(RingingToneName(profile.Ringtone,0),""))
-        printf(_("Ringing tone: %s (number %d in phone menu)\n"), 
-          RingingToneName(profile.Ringtone,0), RingingToneMenu(profile.Ringtone));
-      else
-        printf(_("Ringtone number: %d\n"), profile.Ringtone);
-
-      printf(_("Ringing volume: %s\n"), GetProfileVolumeString(profile.Volume));
-
-      printf(_("Message alert tone: %s\n"), GetProfileMessageToneString(profile.MessageTone));
-
-      printf(_("Keypad tones: %s\n"), GetProfileKeypadToneString(profile.KeypadTone));
-
-      printf(_("Warning and game tones: %s\n"), GetProfileWarningToneString(profile.WarningTone));
-
-      if (GetModelFeature (FN_SCREENSAVER)!=0)
-        printf(_("Screen saver: %s\n"), GetProfileOnOffString(profile.ScreenSaver));
-      
-      printf(_("Vibration: %s\n"), GetProfileVibrationString(profile.Vibration));
-
-      /* It has been nice to add here reading caller group name. ;^) */
-      if (GetModelFeature (FN_CALENDAR)==F_CAL71) 
-        printf(_("Caller groups: %s\n"), 
-                              GetProfileCallerGroups(profile.CallerGroups) );
-
-      /* FIXME: need make investigation for 3310 for these features. For now unknown */
-      if (GetModelFeature (FN_PROFILES)!=F_PROF33) {
-        /* FIXME: Light settings is only used for Car */
-        if (profile.Number==(max_profiles-2)) printf(_("Lights: %s\n"), profile.Lights ? _("On") : _("Automatic"));
-
-        /* FIXME: Automatic answer is only used for Car and Headset. */
-        if (profile.Number>=(max_profiles-2)) printf(_("Automatic answer: %s\n"), GetProfileOnOffString(profile.AutomaticAnswer));
-      }
-
-      printf("\n");
-
-      i++;
-    }
-  } else {
-    if (error == GE_NOTIMPLEMENTED) {
-       fprintf(stderr, _("Function not implemented in %s model!\n"), model);
-       GSM->Terminate();
-       return -1;
-    } else
-    {
-      fprintf(stderr, _("Unspecified error\n"));
-      GSM->Terminate();
-      return -1;
-    }
-  }
-
-  GSM->Terminate();
-
-  return 0;
-
-}
-
-/* Sets profile feature */
-
-int setprofile(int argc, char *argv[])
-{
-
-/* Hopefully is 64 larger as FB38_MAX* / FB61_MAX* */
-  char model[64], rev[64];
-
-  int max_profiles;
-  GSM_Profile profile;
-  GSM_Profile profile2, profile3;
-  GSM_Error error;
-  bool correct_arg1;
-  bool correct_arg2;
-  
-/* Initialise the code for the GSM interface. */     
-
-  fbusinit(NULL);
-  
-  profile.Number = 0;
-
-  error = GSM->GetProfile(&profile);
-  
-  if (error == GE_NONE)
-  {
-    while (GSM->GetModel(model)  != GE_NONE) sleep(1);
-      
-    while (GSM->GetRevision(rev) != GE_NONE) sleep(1);
-
-    strncpy(rev,rev+2,5);
-    rev[5]=0;
-    PrepareRingingTones(model,rev);
-
-    switch(GetModelFeature (FN_PROFILES)) {
-      case F_PROF33:max_profiles=6;break;
-      case F_PROF51:max_profiles=3;break;
-      default      :max_profiles=7;break;
-    }
-
-    profile.Number=atoi (argv[0]);
-    profile.Number=profile.Number-1;
-    
-    if (profile.Number < 0)
-    {
-      fprintf(stderr, _("Profile number must be value from 1 to %i!\n"), max_profiles);
-      GSM->Terminate();
-      return -1;
-    }
-    
-    if (profile.Number >= max_profiles)
-    {
-      fprintf(stderr, _("This phone supports only %i profiles!\n"), max_profiles);
-      GSM->Terminate();
-      return -1;
-    }
-      
-    if (profile.Number!=0) GSM->GetProfile(&profile);
-        
-    correct_arg1=false;
-    correct_arg2=false;
-
-    if (strcmp(argv[1], "callalert")==0)
-    {
-       if (strcmp(argv[2], "ringing")==0) {profile.CallAlert=PROFILE_CALLALERT_RINGING;correct_arg2=true;}
-       if (strcmp(argv[2], "ascending")==0) {profile.CallAlert=PROFILE_CALLALERT_ASCENDING;correct_arg2=true;}
-       if (strcmp(argv[2], "ringonce")==0) {profile.CallAlert=PROFILE_CALLALERT_RINGONCE;correct_arg2=true;}
-       if (strcmp(argv[2], "beeponce")==0) {profile.CallAlert=PROFILE_CALLALERT_BEEPONCE;correct_arg2=true;}
-       if (strcmp(argv[2], "groups")==0)
-       {
-         profile.CallAlert=PROFILE_CALLALERT_CALLERGROUPS;
-        correct_arg2=true;
-        /*Ignored by N5110*/
-        /*FIX ME: it's ignored by N5130 and 3210 too*/
-        if (max_profiles==3) fprintf(stdout, _("Warning: value \"groups\" for profile feature \"callalert\" will be ignored in this phone model !\n"));
-       }
-       if (strcmp(argv[2], "off")==0 || strcmp(argv[2], "0")==0) {profile.CallAlert=PROFILE_CALLALERT_OFF;correct_arg2=true;}
-       if (!correct_arg2)
-       {
-        fprintf(stderr, _("Correct parameters for profile feature \"callalert\" are ringing|ascending|ringonce|beeponce|groups|off|0 !\n"));
-         GSM->Terminate();
-         return -1;
-        }
-       correct_arg1=true;
-    }
-    if (strcmp(argv[1], "volume")==0)
-    {
-       if (strcmp(argv[2], "1")==0) {profile.Volume=PROFILE_VOLUME_LEVEL1;correct_arg2=true;}
-       if (strcmp(argv[2], "2")==0) {profile.Volume=PROFILE_VOLUME_LEVEL2;correct_arg2=true;}
-       if (strcmp(argv[2], "3")==0) {profile.Volume=PROFILE_VOLUME_LEVEL3;correct_arg2=true;}
-       if (strcmp(argv[2], "4")==0) {profile.Volume=PROFILE_VOLUME_LEVEL4;correct_arg2=true;}
-       if (strcmp(argv[2], "5")==0) {profile.Volume=PROFILE_VOLUME_LEVEL5;correct_arg2=true;}
-       if (!correct_arg2)
-       {
-        fprintf(stderr, _("Correct parameters for profile feature \"volume\" are 0|1|2|3|4|5 !\n"));
-         GSM->Terminate();
-         return -1;
-        }
-       correct_arg1=true;
-    }
-    if (strcmp(argv[1], "keypad")==0 || strcmp(argv[1], "keypadtone")==0)
-    {
-       if (strcmp(argv[2], "0")==0 || strcmp(argv[2], "off")==0) {profile.KeypadTone=PROFILE_KEYPAD_OFF;correct_arg2=true;}
-       if (strcmp(argv[2], "1")==0) {profile.KeypadTone=PROFILE_KEYPAD_LEVEL1;correct_arg2=true;}
-       if (strcmp(argv[2], "2")==0) {profile.KeypadTone=PROFILE_KEYPAD_LEVEL2;correct_arg2=true;}
-       if (strcmp(argv[2], "3")==0) {profile.KeypadTone=PROFILE_KEYPAD_LEVEL3;correct_arg2=true;}
-       if (!correct_arg2)
-       {
-        fprintf(stderr, _("Correct parameters for profile feature \"keypad|keypadtone\" are off|0|1|2|3 !\n"));
-         GSM->Terminate();
-         return -1;
-        }
-       correct_arg1=true;
-    }
-    if (strcmp(argv[1], "messagetone")==0 || strcmp(argv[1], "smstone")==0 || strcmp(argv[1], "sms")==0 || strcmp(argv[1], "message")==0)
-    {
-       if (strcmp(argv[2], "0")==0 || strcmp(argv[2], "off")==0) {profile.MessageTone=PROFILE_MESSAGE_NOTONE;correct_arg2=true;}
-       if (strcmp(argv[2], "standard")==0) {profile.MessageTone=PROFILE_MESSAGE_STANDARD;correct_arg2=true;}
-       if (strcmp(argv[2], "special")==0) {profile.MessageTone=PROFILE_MESSAGE_SPECIAL;correct_arg2=true;}
-       if (strcmp(argv[2], "beeponce")==0 || strcmp(argv[2], "once")==0) {profile.MessageTone=PROFILE_MESSAGE_BEEPONCE;correct_arg2=true;}
-       if (strcmp(argv[2], "ascending")==0) {profile.MessageTone=PROFILE_MESSAGE_ASCENDING;correct_arg2=true;}
-       if (!correct_arg2)
-       {
-        fprintf(stderr, _("Correct parameters for profile feature \"messagetone|smstone|message|sms\" are 0|off|standard|special|beeponce|once|ascending !\n"));
-         GSM->Terminate();
-         return -1;
-        }
-       correct_arg1=true;
-    }
-    if (strcmp(argv[1], "warningtone")==0 || strcmp(argv[1], "warning")==0)
-    {
-       if (strcmp(argv[2], "0")==0 || strcmp(argv[2], "off")==0) {profile.WarningTone=PROFILE_WARNING_OFF;correct_arg2=true;}
-       if (strcmp(argv[2], "1")==0 || strcmp(argv[2], "on")==0) {profile.WarningTone=PROFILE_WARNING_ON;correct_arg2=true;}
-       if (!correct_arg2)
-       {
-        fprintf(stderr, _("Correct parameters for profile feature \"warningtone|warning\" are 0|off|1|on !\n"));
-         GSM->Terminate();
-         return -1;
-        }
-       correct_arg1=true;
-    }
-    if (strcmp(argv[1], "vibra")==0 || strcmp(argv[1], "vibration")==0)
-    {
-       if (strcmp(argv[2], "0")==0 || strcmp(argv[2], "off")==0) {profile.Vibration=PROFILE_VIBRATION_OFF;correct_arg2=true;}
-       if (strcmp(argv[2], "1")==0 || strcmp(argv[2], "on")==0) {profile.Vibration=PROFILE_VIBRATION_ON;correct_arg2=true;}
-       if (!correct_arg2)
-       {
-        fprintf(stderr, _("Correct parameters for profile feature \"vibration|vibra\" are 0|off|1|on !\n"));
-         GSM->Terminate();
-         return -1;
-        }
-       correct_arg1=true;
-    }
-    if (strcmp(argv[1], "lights")==0)
-    {
-       if (strcmp(argv[2], "0")==0 || strcmp(argv[2], "off")==0) {profile.Lights=-1;correct_arg2=true;}
-       if (strcmp(argv[2], "1")==0 || strcmp(argv[2], "on")==0) {profile.Lights=0;correct_arg2=true;}
-       if (!correct_arg2)
-       {
-        fprintf(stderr, _("Correct parameters for profile feature \"lights\" are 0|off|1|on !\n"));
-         GSM->Terminate();
-         return -1;
-       }
-       if (profile.Number!=(max_profiles-2))
-       {
-         profile2.Number=max_profiles-2;
-        if (GSM->GetProfile(&profile2)==GE_NONE)
-        {
-           fprintf(stdout, _("Warning: \"Lights\" feature is ignored in this profile (only setting it for \"%s\" profile get some results) !\n"), profile2.Name);
-        }
-       }
-       correct_arg1=true;
-    }
-    if (strcmp(argv[1], "answer")==0)
-    {
-       if (strcmp(argv[2], "0")==0 || strcmp(argv[2], "off")==0) {profile.AutomaticAnswer=-1;correct_arg2=true;}
-       if (strcmp(argv[2], "1")==0 || strcmp(argv[2], "on")==0) {profile.AutomaticAnswer=0;correct_arg2=true;}
-       if (!correct_arg2)
-       {
-        fprintf(stderr, _("Correct parameters for profile feature \"answer\" are 0|off|1|on !\n"));
-         GSM->Terminate();
-         return -1;
-       }
-       if (profile.Number<(max_profiles-2))
-       {
-         profile2.Number=max_profiles-2;
-        if (GSM->GetProfile(&profile2)==GE_NONE)
-        {
-          profile3.Number=max_profiles-1;
-          if (GSM->GetProfile(&profile3)==GE_NONE)
-          {
-             fprintf(stdout, _("Warning: \"Automatic Answer\" feature is ignored in this profile (only setting it for \"%s\" and \"%s\" profiles get some results) !\n"), profile2.Name, profile3.Name);
-          }
-        }
-       }
-       correct_arg1=true;
-    }
-    if (strcmp(argv[1], "name")==0)
-    {
-       strcpy(profile.Name,argv[2]);
-       /*Ignored by N5110*/
-       /*FIX ME: it's ignored by N5130 and 3210 too*/
-       if (max_profiles==3) fprintf(stdout, _("Warning: this phone model doesn't allow to change profile name !\n"));
-       correct_arg1=true;
-    }
-    if (strcmp(argv[1], "ringtone")==0)
-    {
-      profile.Ringtone=atoi(argv[2]);
-      if (profile.Ringtone<1)
-      {
-        /*With value 0 results are interesting in N5110, but can't be used for anything*/
-        fprintf(stderr, _("Ringtone number must be higher than 0 !\n"));
-        GSM->Terminate();
-        return -1; 
-      } else
-      {
-        if (profile.Ringtone>NumberOfRingtones())
-       {
-          fprintf(stderr, _("Ringtone number too high (max %i) !\n"),NumberOfRingtones());
-          GSM->Terminate();
-          return -1;
-        }  
-       profile.Ringtone=RingingToneCode(profile.Ringtone);
-       if (profile.Ringtone==0)
-       {
-          fprintf(stderr, _("Warning: we don't know ringtones codes for this model ! Can you contact with gnokii authors to add it into source ?\n"));
-          GSM->Terminate();
-          return -1;
-       }
-       if (max_profiles==3) fprintf(stdout, _("Warning: ringtone is changed for all profiles. You must reset phone or select profile in phone againg to see result.\n"));
-      }
-      correct_arg1=true;
-    }
-    if (strcmp(argv[1], "groups")==0)
-    {
-       /*Ignored by N5110*/
-       /*FIX ME: it's ignored by N5130 and 3210 too*/
-       if (max_profiles==3) fprintf(stdout, _("Warning: this phone model doesn't allow to change caller group name !\n"));
-       profile.CallerGroups=atoi(argv[2]);
-       correct_arg1=true;
-    }
-
-    if (!correct_arg1)
-    {
-      fprintf(stderr, _("Correct profile feature names are callalert|volume|keypad|keypadtone|messagetone|smstone|message|sms|warningtone|warning|vibra|vibration|lights|answer|name|groups !\n"));
-      GSM->Terminate();
-      return -1;
-    }
-    
-    GSM->SetProfile(&profile);
-    
-  } else {
-    if (error == GE_NOTIMPLEMENTED) {
-       fprintf(stderr, _("Function not implemented in %s model!\n"), model);
-       GSM->Terminate();
-       return -1;
-    } else
-    {
-      fprintf(stderr, _("Unspecified error\n"));
-      GSM->Terminate();
-      return -1;
-    }
-  }
-  GSM->Terminate();
-
-  return 0;
-
-}
-
-/* Get requested range of memory storage entries and output to stdout in
-   easy-to-parse format */
-
-int getmemory(int argc, char *argv[])
-{
-
-  GSM_PhonebookEntry entry;
-  int count;
-  register int i;
-  GSM_Error error;
-  GSM_Bitmap bitmap;
-  char memory_type_string[20];
-  int start_entry;
-  int end_entry;
-  int i_used = 0, n_used=0;
-  int do_all;
-  char *output_opt = NULL;
-  bool wasdate=false;
-  char az_group_name[5][MAX_BITMAP_TEXT_LENGTH];
-  bool formatdone=false;
-  char buf[64];
-
-  /* group names init */
-  for(i=0;i<5;i++) az_group_name[i][0]='\0';
-
-  /* Handle command line args that set type, start and end locations. */
-  if (!GetMemoryTypeID(argv[0], &entry.MemoryType))
-  {
-    fprintf(stderr, _("Unknown memory type %s!\n"), argv[0]);
-    return (-1);
-  }
-  GetMemoryTypeString(memory_type_string, &entry.MemoryType);
-
-  if (argv[argc-1][0] == '-')
-    output_opt = argv[--argc];
-
-  /* Do generic initialisation routine */
-
-  fbusinit(NULL);
-
-  while ((error = GSM->GetModel(buf)) != GE_NONE && i++ < 15)
-    sleep(1);
-
-  if (argc > 1) {
-    do_all = 0;
-    start_entry = atoi (argv[1]);
-    end_entry = argc > 2 ? atoi( argv[2]) : start_entry;
-  } else {
-    GSM_MemoryStatus stats = {entry.MemoryType, 0, 0};
-
-    do_all = 1;
-    start_entry = 1;
-    if (GSM->GetMemoryStatus( &stats) != GE_NONE) {
-      fprintf( stderr, _("Error reading memory status.\n"));
-      GSM->Terminate();
-      return -1;
-    }
-    n_used = stats.Used;
-    end_entry = stats.Used + stats.Free;
-  }
-    
-
-  /* Now retrieve the requested entries. */
-
-  for (count = start_entry;
-       count <= end_entry && (!do_all || i_used < n_used);
-       count++) {
-
-    entry.Location=count;
-    
-    error=GSM->GetMemoryLocation(&entry);
-
-    switch (error) {
-    case GE_NONE:
-      if (entry.SubEntriesCount || strcmp( entry.Number, ""))
-       i_used++;
-      else if (do_all)
-       break;
-      if (output_opt && !strcmp( output_opt,"-v30")) {
-       semicolon_pipe_substitution( &entry, 0 );
-        fprintf(stdout,_("%s"),GSM_GetVCARD(&entry,30));
-       formatdone=true;
-      } 
-      if (output_opt && !strcmp(output_opt,"-v21")) {
-       semicolon_pipe_substitution( &entry, 0 );
-        fprintf(stdout,_("%s"),GSM_GetVCARD(&entry,21));
-       formatdone=true;
-      } 
-      if (output_opt && !strcmp(output_opt,"-v")) {
-       semicolon_pipe_substitution( &entry, 0 );
-        fprintf(stdout,_("%s"),GSM_GetVCARD(&entry,10));
-       formatdone=true;
-      } 
-      if (output_opt && !strcmp(output_opt,"-short")) {
-        semicolon_pipe_substitution( &entry, 0 );
-        fprintf(stdout, "%s;%s;%s;%d;%d;", entry.Name, entry.Number, memory_type_string, entry.Location, entry.Group);
-        for( i = 0; i <  entry.SubEntriesCount; i++ )
-        {
-          if( entry.SubEntries[i].EntryType == GSM_Date )
-            fprintf(stdout,_("%u;%u;%u;%02u.%02u.%04u;%02u:%02u:%02u;"),
-                entry.SubEntries[i].EntryType,
-                entry.SubEntries[i].NumberType,
-                entry.SubEntries[i].BlockNumber,
-                entry.SubEntries[i].data.Date.Day,
-                entry.SubEntries[i].data.Date.Month,
-                entry.SubEntries[i].data.Date.Year,
-                entry.SubEntries[i].data.Date.Hour,
-                entry.SubEntries[i].data.Date.Minute,
-                entry.SubEntries[i].data.Date.Second );
-          else
-            fprintf(stdout,_("%u;%u;%u;%s;"),
-                entry.SubEntries[i].EntryType,
-                entry.SubEntries[i].NumberType,
-                entry.SubEntries[i].BlockNumber,
-                entry.SubEntries[i].data.Number );
-        }
-        fprintf(stdout,_("\n"));
-       formatdone=true;
-      }
-      if (!formatdone) {
-         char z_gtype[12];
-          wasdate=false;
-          fprintf(stdout, "Memory %s, location %d\n",memory_type_string, entry.Location);
-
-         // check if some info in subentries 
-          for( i = 0; i <  entry.SubEntriesCount; i++ )
-                 if( entry.SubEntries[i].EntryType != GSM_Date &&
-                         strcmp(entry.SubEntries[i].data.Number,"") )
-                     break;
-
-          if (strcmp(entry.Number,"") || i <  entry.SubEntriesCount) {
-           if (strcmp(entry.Name,"")) fprintf(stdout,_("   Name: %s\n"),entry.Name);
-           if (strcmp(entry.Number,"")) fprintf(stdout,_("   Number: %s\n"),entry.Number);
-           bitmap.type=GSM_CallerLogo;
-            bitmap.number=entry.Group;
-            strcpy(z_gtype,"unknown");
-           if (entry.Group==5) strcpy(z_gtype,"No group");
-           if (entry.Group<5 && entry.Group>=0) {
-              if (!strcmp(az_group_name[entry.Group],"")) {
-               if (GetModelFeature (FN_CALLERGROUPS)!=0) {
-                  if (GSM->GetBitmap(&bitmap)==GE_NONE)
-                    strcpy( az_group_name[entry.Group], bitmap.text );
-               }
-               if ((!strcmp(az_group_name[entry.Group],""))) {
-                 switch(entry.Group) {
-                   case 0:strcpy(az_group_name[entry.Group],"Family");break;
-                   case 1:strcpy(az_group_name[entry.Group],"VIP");break;
-                   case 2:strcpy(az_group_name[entry.Group],"Friends");break;
-                   case 3:strcpy(az_group_name[entry.Group],"Colleagues");break;
-                   case 4:strcpy(az_group_name[entry.Group],"Other");break;
-                   default:break;
-                 }
-               }
-             }
-             strcpy(z_gtype,az_group_name[entry.Group]);
-            }
-           fprintf(stdout,_("   Group: %d (%s)\n"),entry.Group+1,z_gtype);
-            for( i = 0; i <  entry.SubEntriesCount; i++ )
-            {
-              if( entry.SubEntries[i].EntryType == GSM_Date ) {
-                 fprintf(stdout, "   Date and time: %s %02u.%02u.%04u %02u:%02u:%02u\n", 
-                   DayOfWeek(entry.SubEntries[i].data.Date.Year,
-                       entry.SubEntries[i].data.Date.Month,
-                       entry.SubEntries[i].data.Date.Day),
-                   entry.SubEntries[i].data.Date.Day,
-                   entry.SubEntries[i].data.Date.Month,
-                   entry.SubEntries[i].data.Date.Year,
-                   entry.SubEntries[i].data.Date.Hour,
-                   entry.SubEntries[i].data.Date.Minute,
-                   entry.SubEntries[i].data.Date.Second);
-                wasdate=true;
-             } else {
-                if( strcmp(entry.SubEntries[i].data.Number,"") ) {
-                   char z_etype[19];
-                   switch( entry.SubEntries[i].EntryType ) {
-                     case GSM_Number:
-                       switch( entry.SubEntries[i].NumberType ) {
-                         case GSM_General: strcpy(z_etype,"General "); break;
-                         case GSM_Home: strcpy(z_etype,"Home "); break;
-                         case GSM_Mobile: strcpy(z_etype,"Mobile "); break;
-                         case GSM_Work: strcpy(z_etype,"Work "); break;
-                         case GSM_Fax: strcpy(z_etype,"Fax "); break;
-                         default: strcpy(z_etype,""); break;
-                       }
-                       strcat(z_etype,"Number"); break;
-                     case GSM_Note:
-                       strcpy(z_etype,"Note"); break;
-                     case GSM_Postal:
-                       strcpy(z_etype,"Postal"); break;
-                     case GSM_Email:
-                       strcpy(z_etype,"E-Mail"); break;
-                     default:
-                       strcpy(z_etype,"unknown data"); break;
-                   }
-#ifdef DEBUG
-                   fprintf(stdout,_("   ---> Subentry: %u\n"),i+1);
-                   fprintf(stdout,_("   Entry type: %u (%s)\n"),entry.SubEntries[i].EntryType,z_etype);
-                   fprintf(stdout,_("   Number type: %u\n"),entry.SubEntries[i].NumberType);
-                   fprintf(stdout,_("   Block Number: %u\n"),entry.SubEntries[i].BlockNumber);
-#endif
-                   fprintf(stdout,_("   %s: %s\n"),z_etype,entry.SubEntries[i].data.Number);
-                 }
-             }
-           }
-            if ((entry.MemoryType==GMT_DC ||
-                entry.MemoryType==GMT_RC ||
-                entry.MemoryType==GMT_MC) && !wasdate)
-             fprintf(stdout,_("   Date and time not available\n"));        
-         } else
-           fprintf(stdout,_("   Location empty\n"));
-      }
-      break;
-    case GE_NOTIMPLEMENTED:
-      fprintf( stderr, _("Function not implemented in %s model!\n"), model);
-      GSM->Terminate();
-      return -1;
-    case GE_INVALIDMEMORYTYPE:
-      fprintf( stderr, _("Memory type %s not supported!\n"),
-              memory_type_string);
-      GSM->Terminate();
-      return -1;
-    default:
-      fprintf(stdout, _("%s|%d|Bad location or other error!(%d)\n"),
-             memory_type_string, count, error);
-    }
-  }
-       
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Read data from stdin, parse and write to phone.  The parsing is relatively
-   crude and doesn't allow for much variation from the stipulated format. */
-
-int writephonebook(int argc, char *args[])
-{
-
-  GSM_PhonebookEntry entry;
-  GSM_Error error;
-  char *memory_type_string;
-  int line_count=0,current,i;
-  int subentry;
-
-  char *Line, OLine[1024], BackLine[1024];
-  char *ptr;
-
-  /* Check argument */
-  if (argc) {
-    if (strcmp("-i", args[0])) {
-      usage();
-      return 0;
-    }
-  }
-  /* Initialise fbus code */
-
-  fbusinit(NULL);
-
-  Line = OLine;
-
-  /* Go through data from stdin. */
-
-  while (GetLine(stdin, Line, sizeof(OLine))!=-1) {
-
-    current=0;BackLine[current++]=Line[0];
-    for (i=1;i<strlen(Line);i++) {
-      if (Line[i-1]==';' && Line[i]==';') BackLine[current++]=' ';
-      BackLine[current++]=Line[i];
-    }
-    BackLine[current++]=0;
-
-    strcpy(Line,BackLine);
-
-    line_count++;
-
-#if defined(__svr4__) || defined(__FreeBSD__)
-    ptr=strtok(Line, ";"); if (ptr) strcpy(entry.Name, ptr);
-
-    entry.Number[0]=0;
-    ptr=strtok(NULL, ";"); if (ptr && ptr[0]!=' ') strcpy(entry.Number, ptr);
-
-    ptr=strtok(NULL, ";");
-#else
-    ptr=strsep(&Line, ";"); if (ptr) strcpy(entry.Name, ptr);
-
-    entry.Number[0]=0;
-    ptr=strsep(&Line, ";"); if (ptr && ptr[0]!=' ') strcpy(entry.Number, ptr);
-
-    ptr=strsep(&Line, ";");
-#endif
-
-    if (!ptr) {
-      fprintf(stderr, _("Format problem on line %d [%s] 1\n"), line_count, BackLine);
-      Line = OLine;
-      continue;
-    }
-
-    if (!strncmp(ptr,"ME", 2))
-    {
-      memory_type_string = "int";
-      entry.MemoryType = GMT_ME;
-    }
-    else if (!strncmp(ptr,"SM", 2))
-    {
-        memory_type_string = "sim";
-        entry.MemoryType = GMT_SM;
-    }
-    else
-    {
-      fprintf(stderr, _("Format problem on line %d [%s] 2: %s\n"),
-        line_count, BackLine,ptr);
-      break;
-    }
-
-#if defined(__svr4__) || defined(__FreeBSD__)
-    ptr=strtok(NULL, ";"); if (ptr) entry.Location=atoi(ptr);
-
-    ptr=strtok(NULL, ";"); if (ptr) entry.Group=atoi(ptr);
-#else
-    ptr=strsep(&Line, ";"); if (ptr) entry.Location=atoi(ptr);
-
-    ptr=strsep(&Line, ";"); if (ptr) entry.Group=atoi(ptr);
-#endif
-
-    if (!ptr) {
-      fprintf(stderr, _("Format problem on line %d [%s] 3\n"),
-        line_count, BackLine);
-      continue;
-    }
-
-    for( subentry = 0; ; subentry++ )
-    {
-#if defined(__svr4__) || defined(__FreeBSD__)
-      ptr=strtok(NULL, ";");
-#else
-      ptr=strsep(&Line, ";");
-#endif
-      if( ptr &&  *ptr != 0 )
-        entry.SubEntries[subentry].EntryType=atoi(ptr);
-      else
-        break;
-
-#if defined(__svr4__) || defined(__FreeBSD__)
-      ptr=strtok(NULL, ";");
-#else
-      ptr=strsep(&Line, ";");
-#endif
-      if(ptr)
-        entry.SubEntries[subentry].NumberType=atoi(ptr);
-      // Phone Numbers need to have a number type.
-      if(!ptr && entry.SubEntries[subentry].EntryType == GSM_Number)
-      {
-        fprintf(stderr, _("Missing phone number type on line %d"
-          " entry %d [%s]\n"), line_count, subentry, BackLine);
-        subentry--;
-        break;
-      }
-
-#if defined(__svr4__) || defined(__FreeBSD__)
-      ptr=strtok(NULL, ";");
-#else
-      ptr=strsep(&Line, ";");
-#endif
-      if(ptr)
-        entry.SubEntries[subentry].BlockNumber=atoi(ptr);
-
-#if defined(__svr4__) || defined(__FreeBSD__)
-      ptr=strtok(NULL, ";");
-#else
-      ptr=strsep(&Line, ";");
-#endif
-      // 0x13 Date Type; it is only for Dailed Numbers, etc.
-      // we don't store to this memories so it's an error to use it.
-      if(!ptr || entry.SubEntries[subentry].EntryType == GSM_Date) 
-      {
-        fprintf(stderr, _("Is not a phone number on line %d entry %d [%s]\n"),
-          line_count, subentry, BackLine);
-        subentry--;
-        break;
-      }
-      else
-        strcpy( entry.SubEntries[subentry].data.Number, ptr );
-    }
-
-    entry.SubEntriesCount = subentry;
-
-
-    /* This is to send other exports (like from 6110) to 7110 */
-    if (!entry.SubEntriesCount) {
-       entry.SubEntriesCount = 1;
-       entry.SubEntries[subentry].EntryType   = GSM_Number;
-       entry.SubEntries[subentry].NumberType  = GSM_General;
-       entry.SubEntries[subentry].BlockNumber = 2;
-       strcpy(entry.SubEntries[subentry].data.Number, entry.Number);
-    }
-
-    Line = OLine;
-
-    if (argc) {
-      GSM_PhonebookEntry tmp_entry;
-
-      memcpy(&tmp_entry, &entry, sizeof(GSM_PhonebookEntry) );
-      error = GSM->GetMemoryLocation(&tmp_entry);
-      if (error == GE_NONE) {
-        if (!tmp_entry.Empty) {
-          int confirm = -1;
-          char ans[8];
-         FILE *input_flow; //for reading from console, even when input redir.
-                               
-         input_flow = fopen(DEV_CONSOLE, "r");
-
-         if (!input_flow) {
-               fprintf(stderr, _("Can't open \"%s\" for input !\n"),DEV_CONSOLE);
-               return(-1);
-         }
-         
-          fprintf(stderr, _("Location busy. "));
-          while (confirm < 0) {
-            fprintf(stderr, _("Overwrite? (yes/no) "));
-            GetLine(input_flow, ans, 7);
-            if (!strcmp(ans, "yes")) confirm = 1;
-            else if (!strcmp(ans, "no")) confirm = 0;
-          }
-          if (!confirm) continue;
-        }
-      } else {
-        fprintf(stderr, _("Unknown error (%d)\n"), error);
-        GSM->Terminate();
-        return 0;
-      }
-    }
-
-    /* Do write and report success/failure. */
-    semicolon_pipe_substitution( &entry, 1 );
-
-    error = GSM->WritePhonebookLocation(&entry);
-
-    if (error == GE_NONE)
-      fprintf (stdout, _("Write Succeeded: memory type: %s, loc: %d, name: %s, number: %s\n"), memory_type_string, entry.Location, entry.Name, entry.Number);
-    else
-      fprintf (stdout, _("Write FAILED(%d): memory type: %s, loc: %d, name: %s, number: %s\n"), error, memory_type_string, entry.Location, entry.Name, entry.Number);
-
-  }
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Getting speed dials. */
-
-int getspeeddial(char *Number) {
-
-  GSM_SpeedDial entry;
-  GSM_Error error;
-  GSM_PhonebookEntry pbentry;
-
-  entry.Number = atoi(Number);
-
-  fbusinit(NULL);
-
-  if (GSM->GetSpeedDial(&entry)==GE_NONE) {
-        pbentry.Location=entry.Location;
-        if (pbentry.Location==0) pbentry.Location=entry.Number;
-        pbentry.MemoryType=entry.MemoryType;
-
-        error=GSM->GetMemoryLocation(&pbentry);
-
-        if (error == GE_NONE)
-        {
-          fprintf(stdout, _("SpeedDial nr. %d: %d:%d (%s)\n"), entry.Number, entry.MemoryType, entry.Location,pbentry.Name);
-        } else
-          fprintf(stdout, _("Error\n"));
-  } else {
-    fprintf(stdout, _("Error\n"));
-  }
-  
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Setting speed dials. */
-
-int setspeeddial(char *argv[]) {
-
-  GSM_SpeedDial entry;
-
-  char *memory_type_string;
-
-  /* Handle command line args that set type, start and end locations. */
-
-  if (strcmp(argv[1], "ME") == 0) {
-    entry.MemoryType = GMT_ME;
-    memory_type_string = "ME";
-  }
-  else if (strcmp(argv[1], "SM") == 0) {
-    entry.MemoryType = GMT_SM;
-    memory_type_string = "SM";
-  }
-  else {
-    fprintf(stderr, _("Unknown memory type %s!\n"), argv[1]);
-
-    return -1;
-  }
-  
-  entry.Number = atoi(argv[0]);
-  entry.Location = atoi(argv[2]);
-
-  fbusinit(NULL);
-
-  if (GSM->SetSpeedDial(&entry) == GE_NONE) {
-    fprintf(stdout, _("Succesfully written!\n"));
-  }
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Getting the status of the display. */
-
-int getdisplaystatus()
-{ 
-
-  int Status;
-
-  /* Initialise the code for the GSM interface. */     
-
-  fbusinit(NULL);
-
-  if (GSM->GetDisplayStatus(&Status)==GE_NONE) {
-
-    printf(_("Call in progress: %s\n"), Status & (1<<DS_Call_In_Progress)?_("on"):_("off"));
-    printf(_("Unknown: %s\n"),          Status & (1<<DS_Unknown)?_("on"):_("off"));
-    printf(_("Unread SMS: %s\n"),       Status & (1<<DS_Unread_SMS)?_("on"):_("off"));
-    printf(_("Voice call: %s\n"),       Status & (1<<DS_Voice_Call)?_("on"):_("off"));
-    printf(_("Fax call active: %s\n"),  Status & (1<<DS_Fax_Call)?_("on"):_("off"));
-    printf(_("Data call active: %s\n"), Status & (1<<DS_Data_Call)?_("on"):_("off"));
-    printf(_("Keyboard lock: %s\n"),    Status & (1<<DS_Keyboard_Lock)?_("on"):_("off"));
-    printf(_("SMS storage full: %s\n"), Status & (1<<DS_SMS_Storage_Full)?_("on"):_("off"));
-
-  } else {
-    printf(_("Error\n"));
-  }
-  
-  GSM->Terminate();
-
-  return 0;
-}
-
-int netmonitor(char *Mode)
-{
-
-  unsigned char mode=atoi(Mode);
-  char Screen[NM_MAX_SCREEN_WIDTH];
-  int i;
-
-  fbusinit(NULL);
-
-  if (!strcmp(Mode,"reset"))     mode=0xf0;
-  else if (!strcmp(Mode,"off"))  mode=0xf1;
-  else if (!strcmp(Mode,"field"))mode=0xf2;
-  else if (!strcmp(Mode,"devel"))mode=0xf3;
-  else if (!strcmp(Mode,"next")) mode=0x00;
-
-  /* We clear it */
-  for (i=0;i<NM_MAX_SCREEN_WIDTH;i++) Screen[i]=0;
-
-  GSM->NetMonitor(mode, Screen);
-
-  if (Screen)
-    printf("%s\n", Screen);
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-int identify( void )
-{
-  /* Hopefully is 64 larger as FB38_MAX* / FB61_MAX* */
-  char imei[64], model[64], rev[64], manufacturer[64];
-
-  fbusinit(NULL);
-
-  while (GSM->GetIMEI(imei)    != GE_NONE) sleep(1);
-  while (GSM->GetRevision(rev) != GE_NONE) sleep(1);
-  while (GSM->GetModel(model)  != GE_NONE) sleep(1);
-
-  strcpy(manufacturer, "(unknown)");
-  GSM->GetManufacturer(manufacturer);
-
-  fprintf(stdout, _("IMEI:     %s\n"), imei);
-  fprintf(stdout, _("Model:    %s %s (%s)\n"), manufacturer, GetModelName (model), model);
-  fprintf(stdout, _("Revision: %s\n"), rev);
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-int senddtmf(char *String)
-{
-
-  fbusinit(NULL);
-
-  if (GSM->SendDTMF(String)!=GE_NONE) fprintf(stdout,_("Error!\n"));
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* Resets the phone */
-int reset(int argc, char *argv[])
-{
-
-  unsigned char _type=0x03;
-
-  if (argc>0) {
-    _type=0x10;
-
-    if (!strcmp(argv[0],"soft")) _type = 0x03;
-    
-    /* Doesn't work with 5110 */
-    if (!strcmp(argv[0],"hard")) _type = 0x04;
-
-    if (_type==0x10) {
-      fprintf(stderr, _("What kind of reset do you want (second parameter can be \"soft\" or \"hard\") ?\n"));
-      return -1;
-    }
-  }
-
-  fbusinit(NULL);
-
-  GSM->Reset(_type);
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* This is a "convenience" function to allow quick test of new API stuff which
-   doesn't warrant a "proper" command line function. */
-
-int foogle(char *argv[])
-{
-  /* Initialise the code for the GSM interface. */     
-
-  fbusinit(NULL);
-
-  // Fill in what you would like to test here...
-
-  sleep(5);
-  
-  GSM->Terminate();
-
-  return 0;
-}
-
-int phonetests()
-{
-  /* Initialise the code for the GSM interface. */     
-
-  fbusinit(NULL);
-
-  if (GSM->PhoneTests()!=GE_NONE) fprintf(stderr,_("Error\n"));
-  
-  GSM->Terminate();
-
-  return 0;
-}
-
-/* pmon allows fbus code to run in a passive state - it doesn't worry about
-   whether comms are established with the phone.  A debugging/development
-   tool. */
-
-int pmon()
-{ 
-
-  GSM_Error error;
-  GSM_ConnectionType connection=GCT_FBUS;
-
-  /* Initialise the code for the GSM interface. */     
-
-  error = GSM_Initialise(model, Port, Initlength, connection, RLP_DisplayF96Frame, SynchronizeTime);
-
-  if (error != GE_NONE) {
-    fprintf(stderr, _("GSM/FBUS init failed! (Unknown model ?). Quitting.\n"));
-    return -1;
-  }
-
-
-  while (1) {
-    usleep(50000);
-  }
-
-  return 0;
-}
-
-int setringtone(int argc, char *argv[])
-{
-  GSM_Ringtone ringtone;
-  GSM_BinRingtone binringtone,binringtone2;
-
-  GSM_Error error;
-
-  int current=0; //number of packed notes or location
-  int i;
-
-  char model[64];
-
-  /* If not binary ringtone */
-  if (GSM_ReadBinRingtoneFile(argv[0],&binringtone2)!=GE_NONE) {
-    fprintf(stdout,_("Not binary ringtone, trying RTTL\n"));
-
-    if (GSM_ReadRingtoneFileOnConsole(argv[0], &ringtone)!=GE_NONE) return(-1);
-
-    ringtone.location=1;
-    if (argc>1) ringtone.location=atoi(argv[1]);
-
-    ringtone.allnotesscale=false;
-  
-    /* Initialise the GSM interface. */
-    fbusinit(NULL);
-
-    while (GSM->GetModel(model)  != GE_NONE)
-      sleep(1);
-
-    /* For Nokia 6110/6130/6150/6210 we use different method of uploading.
-       Phone will display menu, when received it */
-    if ( !strcmp(model,"NSE-3") || !strcmp(model,"NSK-3") ||
-         !strcmp(model,"NSM-1") || !strcmp(model,"NPE-3") ) {
-      if (argc==1) ringtone.location=255;
-    }
-
-    error=GSM->SetRingtone(&ringtone,&current);
-  
-    if (current!=ringtone.NrNotes) {
-      if (current>FB61_MAX_RINGTONE_NOTES) {
-        fprintf(stderr,_("Warning: due to phone limitation"));
-      } else {
-        fprintf(stderr,_("Warning: ringtone was too long to be saved into frame,"));
-      }
-      fprintf(stderr, _(" only %i first notes were packed (%i cut)\n"),current,ringtone.NrNotes-current);
-    }
-
-    if (error==GE_NONE) 
-      fprintf(stdout, _("Set succeeded!\n"));
-    else
-      fprintf(stdout, _("Setting failed\n"));
-
-  } else { /* This IS binary ringtone */
-    fprintf(stdout,_("Binary ringtone format\n"));
-
-    if (argc==3) {
-      binringtone.frame[current++]=0x00;
-      binringtone.frame[current++]=0x00;
-      binringtone.frame[current++]=0x0c;
-      binringtone.frame[current++]=0x01;
-      binringtone.frame[current++]=0x2c;
-    
-      //copy new name
-      memcpy(binringtone.frame+current,argv[2],strlen(argv[2]));
-      current=current+strlen(argv[2]);
-
-      /*don't use old*/
-      i=2;
-      while(binringtone2.frame[i]!=0x00) {
-        if (i==binringtone.length) break;
-        i++;
-      }
-    
-      //copy binringtone
-      memcpy(binringtone.frame+current,binringtone2.frame+i,binringtone2.length-i);
-      binringtone.length=binringtone2.length-i+current;    
-    } else
-    {
-      memcpy(binringtone.frame+current,binringtone2.frame,binringtone2.length);
-      binringtone.length=binringtone2.length;
-    }
-  
-    binringtone.location=1;
-    if (argc>1) binringtone.location=atoi(argv[1]);
-  
-    /* Initialise the GSM interface. */
-    fbusinit(NULL);
-
-    error=GSM->SetBinRingtone(&binringtone);
-
-    switch (error) {
-      case GE_NONE:
-        fprintf(stdout, _("Set succeeded!\n"));
-        break;
-      case GE_INVALIDRINGLOCATION:
-        fprintf(stdout, _("Invalid location %i!\n"),binringtone.location);
-        break;
-      case GE_UNKNOWNMODEL:
-        fprintf(stdout, _("Mygnokii doesn't know format for this model!\n"));
-        break;
-      case GE_NOTIMPLEMENTED:
-        fprintf(stdout, _("Not implemented for this model!\n"));
-        break;
-      default:
-        fprintf(stdout, _("Not supported by this model!\n"));
-        break;
-    }
-  }
-
-  GSM->Terminate();
-
-  return 0;
-}
-
-int ringtoneconvert(int argc, char *argv[])
-{
-  GSM_Ringtone ringtone;
-
-  if (!strcmp(argv[0],argv[1]))
-  {
-    fprintf(stderr, _("Files can't have the same names !\n"));
-    return -1;  
-  }
-  
-  if (GSM_ReadRingtoneFileOnConsole(argv[0], &ringtone)!=GE_NONE) return(-1);
-
-  ringtone.allnotesscale=false;
-
-  GSM_SaveRingtoneFileOnConsole(argv[1], &ringtone);
-  
-  return 0;
-}
-
-int playringtone(int argc, char *argv[])
-{
-  GSM_Ringtone ringtone;
-
-  GSM_BinRingtone binringtone;
-  
-  int i,j,z;
-  int Hz;
-  bool isok;
-
-//{ "c", "c#", "d", "d#", "e",  "f", "f#", "g", "g#", "a", "a#", "h" };
-  int binary_notes[12] =
-  { 0,    1,    2,   3,    4,   6,   7,    8,   9,    10,  11 ,   12};
-
-  if (GSM_ReadBinRingtoneFile(argv[0],&binringtone)!=GE_NONE) {
-    fprintf(stdout,_("Not binary ringtone, trying RTTL\n"));
-
-    if (GSM_ReadRingtoneFileOnConsole(argv[0], &ringtone)!=GE_NONE) return(-1);
-
-    /* Initialise the GSM interface. */
-    fbusinit(NULL);
-
-    fprintf(stdout,_("Playing \"%s\" (%i notes)\n"),ringtone.name,ringtone.NrNotes);
-  
-    GSM_PlayRingtoneOnConsole(&ringtone);
-
-  } else {
-
-    fprintf(stdout,_("Binary ringtone format\n"));  
-
-    /* Initialise the GSM interface. */
-    fbusinit(NULL);
-
-    i=5;
-    while (true) { //skipping name
-      if (binringtone.frame[i]==0) break;
-      i++;
-    }
-
-    i=i+5;j=0;z=0;
-    while (true) {
-      if (binringtone.frame[i]!=j) {
-        if (j!=0) {
-//#ifdef DEBUG
-          fprintf(stdout,_("Block in binary ringtone %i %i\n"),j,z);
-//#endif
-          isok=false;
-          if (j==64) {
-           j=255;//Pause
-            isok=true;
-         }
-         if (!isok && j>=114 && j<=125) {
-           j=14*3+binary_notes[j-114];
-           isok=true;
-         }
-         if (!isok && j>=126 && j<=137) {
-           j=14*1+binary_notes[j-126];
-           isok=true;
-         }
-         if (!isok && j>=138 && j<=149) {
-           j=14*2+binary_notes[j-138];
-           isok=true;
-          }
-         if (!isok && j>=150 && j<=161) {
-           j=14*4+binary_notes[j-150];
-           isok=true;
-         }
-         if (!isok) {
-//#ifdef DEBUG
-           fprintf(stdout,_("Unknown block in binary ringtone %i %i\n"),j,z);
-//#endif
-          } else {
-           Hz=GSM_GetFrequency(j);
-           if (GSM->PlayTone(Hz,5)!=GE_NONE) fprintf(stdout,_("error during playing\n"));
-           usleep(z*5000);
-         }
-        }
-        j=binringtone.frame[i];
-        z=binringtone.frame[i+1];
-      } else {
-        z=z+binringtone.frame[i+1];
-      }
-      i=i+2;
-      if (i>=binringtone.length) break;
-    }
-  
-    GSM->PlayTone(0,0);
-  }
-
-  GSM->Terminate();    
-
-  return 0;
-}
-
-int composer(int argc, char *argv[])
-{
-  GSM_Ringtone ringtone;
-  int i;
-  bool unknown;
-  int oldnoteslen=4,nownoteslen,oldnoteslen2;
-  int oldnotesscale=1,nownotesscale;  
-  bool firstnote=true;
-  int DefNoteTempo=63;
-  
-  if (GSM_ReadRingtoneFileOnConsole(argv[0], &ringtone)!=GE_NONE) return(-1);
-  if (ringtone.NrNotes!=0)
-    DefNoteTempo=ringtone.notes[0].tempo;
-
-  fprintf(stdout,_("Ringtone \"%s\" (tempo = %i Beats Per Minute)\n\n"),ringtone.name,GSM_GetTempo(DefNoteTempo));
-  
-  for (i=0;i<ringtone.NrNotes;i++) {    
-    if (DefNoteTempo!=ringtone.notes[i].tempo) {
-      fprintf(stdout,_("WARNING: IN FACT RINGTONE HAS DIFFERENT TEMPO FOR DIFFERENT NOTES AND THAT'S WHY YOU CAN'T ENTER IT ALL IN THE COMPOSITOR\n\n"));
-      break;
-    }
-  }
-    
-  for (i=0;i<ringtone.NrNotes;i++) {
-
-    if (firstnote) {
-      if (GSM_GetNote(ringtone.notes[i].note)!=Note_Pause)
-        firstnote=false;
-    }
-    
-    if (!firstnote) {
-      break;
-    }
-    
-  }
-
-  if ((ringtone.NrNotes-i)>50)
-    fprintf(stdout,_("WARNING: LENGTH=%i, BUT YOU WILL ENTER ONLY FIRST 50 TONES. TO ENTER FULL RINGTONE MUST SEND IT (--sendringtone) OR DOWNLOAD (--setringtone)\n\n"),ringtone.NrNotes-i);
-
-  fprintf(stdout,_("This ringtone in Nokia Composer in phone should look: "));  
-
-  firstnote=true;
-    
-  for (i=0;i<ringtone.NrNotes;i++) {
-
-    if (firstnote) {
-      if (GSM_GetNote(ringtone.notes[i].note)!=Note_Pause)
-        firstnote=false;
-    }
-    
-    if (!firstnote) {
-    
-      switch (ringtone.notes[i].duration) {
-        case 192:fprintf(stdout,_("1."));break; //192=128*1.5
-        case 128:fprintf(stdout,_("1"));break;
-        case 96 :fprintf(stdout,_("2."));break; //96=64*1.5
-        case 64 :fprintf(stdout,_("2"));break;
-        case 48 :fprintf(stdout,_("4."));break; //48=32*1.5
-        case 32 :fprintf(stdout,_("4"));break;
-        case 24 :fprintf(stdout,_("8."));break; //24=16*1.5
-        case 16 :fprintf(stdout,_("8"));break;
-        case 12 :fprintf(stdout,_("16."));break; //12=8*1.5
-        case 8  :fprintf(stdout,_("16"));break;
-        case 6  :fprintf(stdout,_("32."));break; //6=4*1.5
-        case 4  :fprintf(stdout,_("32"));break;
-      }
-    
-    unknown=false;
-    
-    /* What note here ? */
-    switch (GSM_GetNote(ringtone.notes[i].note)) {
-      case Note_C  :fprintf(stdout,_("c"));break;
-      case Note_Cis:fprintf(stdout,_("#c"));break;
-      case Note_D  :fprintf(stdout,_("d"));break;
-      case Note_Dis:fprintf(stdout,_("#d"));break;
-      case Note_E  :fprintf(stdout,_("e"));break;
-      case Note_F  :fprintf(stdout,_("f"));break;
-      case Note_Fis:fprintf(stdout,_("#f"));break;
-      case Note_G  :fprintf(stdout,_("g"));break;
-      case Note_Gis:fprintf(stdout,_("#g"));break;
-      case Note_A  :fprintf(stdout,_("a"));break;
-      case Note_Ais:fprintf(stdout,_("#a"));break;
-      case Note_H  :fprintf(stdout,_("h"));break;
-      default      :fprintf(stdout,_("-"));unknown=true;break; //Pause ?
-    }
-
-    if (!unknown)
-      fprintf(stdout,_("%i"),ringtone.notes[i].note/14);
-    
-    /* And separator before next note */
-    if (i!=ringtone.NrNotes-1)
-      fprintf(stdout,_(" "));
-      
-    }
-
-  }
-
-  fprintf(stdout,_("\n\nTo enter it please press: "));  
-  
-  firstnote=true;
-  
-  for (i=0;i<ringtone.NrNotes;i++) {
-
-    if (firstnote) {
-      if (GSM_GetNote(ringtone.notes[i].note)!=Note_Pause)
-        firstnote=false;
-    }
-    
-    if (!firstnote) {
-
-    unknown=false;
-    
-    /* What note here ? */
-    switch (GSM_GetNote(ringtone.notes[i].note)) {
-      case Note_C  :fprintf(stdout,_("1"));break;
-      case Note_Cis:fprintf(stdout,_("1"));break;
-      case Note_D  :fprintf(stdout,_("2"));break;
-      case Note_Dis:fprintf(stdout,_("2"));break;
-      case Note_E  :fprintf(stdout,_("3"));break;
-      case Note_F  :fprintf(stdout,_("4"));break;
-      case Note_Fis:fprintf(stdout,_("4"));break;
-      case Note_G  :fprintf(stdout,_("5"));break;
-      case Note_Gis:fprintf(stdout,_("5"));break;
-      case Note_A  :fprintf(stdout,_("6"));break;
-      case Note_Ais:fprintf(stdout,_("6"));break;
-      case Note_H  :fprintf(stdout,_("7"));break;
-      default      :fprintf(stdout,_("0"));unknown=true;break;
-    }
-
-      switch (ringtone.notes[i].duration) {
-        case 192:fprintf(stdout,_("(longer)"));break; //192=128*1.5
-        case 96 :fprintf(stdout,_("(longer)"));break; //96=64*1.5
-        case 48 :fprintf(stdout,_("(longer)"));break; //48=32*1.5
-        case 24 :fprintf(stdout,_("(longer)"));break; //24=16*1.5
-        case 12 :fprintf(stdout,_("(longer)"));break; //12=8*1.5
-        case 6  :fprintf(stdout,_("(longer)"));break; //6=4*1.5
-        default:break;
-      }
-
-    /* What note here ? */
-    switch (GSM_GetNote(ringtone.notes[i].note)) {
-      case Note_Cis:fprintf(stdout,_("#"));break;
-      case Note_Dis:fprintf(stdout,_("#"));break;
-      case Note_Fis:fprintf(stdout,_("#"));break;
-      case Note_Gis:fprintf(stdout,_("#"));break;
-      case Note_Ais:fprintf(stdout,_("#"));break;
-      default      :break;
-    }
-
-    if (!unknown)
-    {
-      nownotesscale=ringtone.notes[i].note/14;
-
-      if (nownotesscale!=oldnotesscale) {
-        switch (nownotesscale) {
-         case 1:
-           switch (oldnotesscale) {
-             case 2:fprintf(stdout,_("**"));break;
-             case 3:fprintf(stdout,_("*"));break;
-           }
-           break;
-         case 2:
-           switch (oldnotesscale) {
-             case 1:fprintf(stdout,_("*"));break;
-             case 3:fprintf(stdout,_("**"));break;
-           }
-           break;
-         case 3:
-           switch (oldnotesscale) {
-             case 1:fprintf(stdout,_("**"));break;
-             case 2:fprintf(stdout,_("*"));break;
-           }
-           break;
-       }
-      }
-      
-      oldnotesscale=nownotesscale;
-    }
-
-     nownoteslen=0;
-     oldnoteslen2=oldnoteslen;
-     
-      switch (ringtone.notes[i].duration) {
-        case 192:nownoteslen=1;break; //192=128*1.5
-        case 128:nownoteslen=1;break;
-        case 96 :nownoteslen=2;break; //96=64*1.5
-        case 64 :nownoteslen=2;break;
-        case 48 :nownoteslen=4;break; //48=32*1.5
-        case 32 :nownoteslen=4;break;
-        case 24 :nownoteslen=8;break; //24=16*1.5
-        case 16 :nownoteslen=8;break;
-        case 12 :nownoteslen=16;break; //12=8*1.5
-        case 8  :nownoteslen=16;break;
-        case 6  :nownoteslen=32;break; //6=4*1.5
-        case 4  :nownoteslen=32;break;
-      }    
-      
-      if (nownoteslen>oldnoteslen) {
-        while (oldnoteslen!=nownoteslen) {
-         fprintf(stdout,_("8"));
-         oldnoteslen=oldnoteslen*2;
-       }
-      }
-
-      if (nownoteslen<oldnoteslen) {
-        while (oldnoteslen!=nownoteslen) {
-         fprintf(stdout,_("9"));
-         oldnoteslen=oldnoteslen/2;
-       }
-      }      
-
-    if (GSM_GetNote(ringtone.notes[i].note)==Note_Pause)
-      oldnoteslen=oldnoteslen2;
-      
-    /* And separator before next note */
-    if (i!=ringtone.NrNotes-1)
-      fprintf(stdout,_("  "));
-
-  }
-  }  
-
-  fprintf(stdout,_("\n"));
-
-  return 0;
-
-}
-
-int sendringtone(int argc, char *argv[])
-{
-  GSM_Ringtone ringtone;
-  GSM_MultiSMSMessage SMS;
-  int current,i;
-  bool ProfileStyle=false; /* If we use profile style available in new Nokia models */
-
-  if (GSM_ReadRingtoneFileOnConsole(argv[1], &ringtone)!=GE_NONE) return(-1);
-
-  ringtone.allnotesscale=false;
-
-  for (i=0;i<argc;i++) {
-    if (!strcmp(argv[i],"--profilestyle")) ProfileStyle=true;
-    if (!strcmp(argv[i],"--scale")) ringtone.allnotesscale=true;
-  }
-
-  current=GSM_SaveRingtoneToSMS(&SMS,&ringtone,ProfileStyle);
-
-  if (current!=ringtone.NrNotes) {
-    if (current>FB61_MAX_RINGTONE_NOTES) {
-      fprintf(stderr,_("Warning: due to phone limitation"));
-    } else {
-      fprintf(stderr,_("Warning: ringtone was too long to be saved into SMS,"));
-    }
-    fprintf(stderr, _(" only %i first notes were packed (%i cut)\n"),current,ringtone.NrNotes-current);
-  }
-
-  for (i=0;i<SMS.number;i++) {
-    strcpy(SMS.SMS[i].Destination,argv[0]);
-  }
-
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
-
-  GSM_SendMultiPartSMSOnConsole(&SMS, 2,argc,argv,false,true,true);
-
-  return 0;
-}
-
-int saveringtone(int argc, char *argv[])
-{
-  GSM_Ringtone ringtone;
-  GSM_MultiSMSMessage SMS;
-  int current,i;
-  bool ProfileStyle=false; /* If we use profile style available in new Nokia models */
-
-  if (GSM_ReadRingtoneFileOnConsole(argv[0], &ringtone)!=GE_NONE) return(-1);
-
-  ringtone.allnotesscale=false;
-
-  for (i=0;i<argc;i++) {
-    if (!strcmp(argv[i],"--profilestyle")) ProfileStyle=true;
-    if (!strcmp(argv[i],"--scale")) ringtone.allnotesscale=true;
-  }
-
-  current=GSM_SaveRingtoneToSMS(&SMS,&ringtone,ProfileStyle);
-
-  if (current!=ringtone.NrNotes) {
-    if (current>FB61_MAX_RINGTONE_NOTES) {
-      fprintf(stderr,_("Warning: due to phone limitation"));
-    } else {
-      fprintf(stderr,_("Warning: ringtone was too long to be saved into SMS,"));
-    }
-    fprintf(stderr, _(" only %i first notes were packed (%i cut)\n"),current,ringtone.NrNotes-current);
-  }
-
-  for (i=0;i<SMS.number;i++) {
-    /* Only 11 chars could be here */
-    strncpy(SMS.SMS[i].Destination,ringtone.name,11);
-  }
-
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
-
-  GSM_SaveMultiPartSMSOnConsole(&SMS,1,argc,argv,false,false,true,true);
-
-  return 0;
-}
-
-/* Converts logo files. */
-
-int bitmapconvert(int argc, char *argv[])
-{
-  GSM_Bitmap bitmap;
-  GSM_NetworkInfo NetworkInfo;
-  bool doit;
-  int num;
-  
-  if (!strcmp(argv[0],argv[1]))
-  {
-    fprintf(stderr, _("Files can't have the same names !\n"));
-    return -1;  
-  }
-  
-  if (GSM_ReadBitmapFileOnConsole(argv[0], &bitmap)!=GE_NONE) return(-1);
-
-  if (argc>2)
-  {
-    doit=false;
-    if (!strcmp(argv[2],"op"))
-    {
-      doit=false;
-      if (argc<4) doit=true;
-      if (argc<4 && bitmap.type!=GSM_OperatorLogo) doit=true;
-      if (doit)
-      {
-        fbusinit(NULL);
-        if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
-        GSM->Terminate();
-      }
-      GSM_ResizeBitmap(&bitmap,GSM_OperatorLogo);
-      if (argc==4)
-      {
-        strncpy(bitmap.netcode,argv[3],7);
-       if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown"))
-       {
-         fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
-         return -1;
-        }
-      }
-      doit=true;
-    }
-    if (!strcmp(argv[2],"7110op"))
-    {
-      doit=false;
-      if (argc<4) doit=true;
-      if (argc<4 && bitmap.type!=GSM_7110OperatorLogo) doit=true;
-      if (doit)
-      {
-        fbusinit(NULL);
-        if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode,NetworkInfo.NetworkCode,7);
-        GSM->Terminate();
-      }
-      GSM_ResizeBitmap(&bitmap,GSM_7110OperatorLogo);
-      if (argc==4)
-      {
-        strncpy(bitmap.netcode,argv[3],7);
-       if (!strcmp(GSM_GetNetworkName(bitmap.netcode),"unknown"))
-       {
-         fprintf(stderr,"Sorry, gnokii doesn't know \"%s\" network !\n",bitmap.netcode);
-         return -1;
-        }
-      }
-      doit=true;
-    }
-    if (!strcmp(argv[2],"caller"))
-    {
-      GSM_ResizeBitmap(&bitmap,GSM_CallerLogo);
-      if (argc>3)
-      {
-        num=argv[3][0]-'0';
-        if ((num<0)||(num>9)) num=0;
-       bitmap.number=num;
-      } else
-      {
-        bitmap.number=0;
-      }
-      doit=true;
-    }
-    if (!strcmp(argv[2],"startup"))
-    {
-      GSM_ResizeBitmap(&bitmap,GSM_StartupLogo);
-      doit=true;
-    }
-    if (!strcmp(argv[2],"7110startup"))
-    {
-      GSM_ResizeBitmap(&bitmap,GSM_7110StartupLogo);
-      doit=true;
-    }
-    if (!strcmp(argv[2],"6210startup"))
-    {
-      GSM_ResizeBitmap(&bitmap,GSM_6210StartupLogo);
-      doit=true;
-    }
-    if (!strcmp(argv[2],"picture"))
-    {
-      GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
-      doit=true;
-    }
-    if (!doit)
-    {
-      fprintf(stderr,"Unknown type of logo: %s !\n",argv[2]);
-      return -1;
-    }
-  }
-    
-  if (GSM_SaveBitmapFileOnConsole(argv[1], &bitmap)!=GE_NONE) return(-1);
-  
-  return 0;
-}
-
-int getphoneprofile()
-{
-  GSM_PPS PPS;
-  GSM_Error error;
-
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
-
-  PPS.Name=PPS_ALS;
-  error=GSM->GetProductProfileSetting(&PPS);
-  if (error!=GE_NONE) {
-    fprintf(stdout,_("Error!\n"));
-    GSM->Terminate();    
-    return -1;
-  }
-  fprintf(stdout,_("ALS           : "));
-  if (PPS.bool_value) fprintf(stdout,_("on\n"));
-                 else fprintf(stdout,_("off\n"));
-
-  PPS.Name=PPS_VibraMenu;
-  GSM->GetProductProfileSetting(&PPS);
-  fprintf(stdout,_("Vibra menu    : "));
-  if (PPS.bool_value) fprintf(stdout,_("on\n"));
-                 else fprintf(stdout,_("off\n"));
-
-  PPS.Name=PPS_GamesMenu;
-  GSM->GetProductProfileSetting(&PPS);
-  fprintf(stdout,_("Games menu    : "));
-  if (PPS.bool_value) fprintf(stdout,_("on\n"));
-                 else fprintf(stdout,_("off\n"));
-
-  PPS.Name=PPS_HRData;
-  GSM->GetProductProfileSetting(&PPS);
-  fprintf(stdout,_("HR Data       : "));
-  if (PPS.bool_value) fprintf(stdout,_("on\n"));
-                 else fprintf(stdout,_("off\n"));
-
-  PPS.Name=PPS_14400Data;
-  GSM->GetProductProfileSetting(&PPS);
-  fprintf(stdout,_("14400 Data    : "));
-  if (PPS.bool_value) fprintf(stdout,_("on\n"));
-                 else fprintf(stdout,_("off\n"));
-
-  PPS.Name=PPS_LCDContrast;
-  GSM->GetProductProfileSetting(&PPS);
-  fprintf(stdout,_("LCD Contrast  : %i%%\n"),PPS.int_value);
-
-  PPS.Name=PPS_EFR;
-  GSM->GetProductProfileSetting(&PPS);
-  fprintf(stdout,_("EFR           : "));
-  switch (PPS.int_value) {
-    case 0: fprintf(stdout,_("off\n"));   break;
-    case 1: fprintf(stdout,_("last\n"));  break;
-    case 2: fprintf(stdout,_("second\n"));break;
-    case 3: fprintf(stdout,_("first\n")); break;
-  }
-
-  PPS.Name=PPS_FR;
-  GSM->GetProductProfileSetting(&PPS);
-  fprintf(stdout,_("FR            : "));
-  switch (PPS.int_value) {
-    case 0: fprintf(stdout,_("off\n"));   break;
-    case 1: fprintf(stdout,_("last\n"));  break;
-    case 2: fprintf(stdout,_("second\n"));break;
-    case 3: fprintf(stdout,_("first\n")); break;
-  }
-
-  PPS.Name=PPS_HR;
-  GSM->GetProductProfileSetting(&PPS);
-  fprintf(stdout,_("HR            : "));
-  switch (PPS.int_value) {
-    case 0: fprintf(stdout,_("off\n"));   break;
-    case 1: fprintf(stdout,_("last\n"));  break;
-    case 2: fprintf(stdout,_("second\n"));break;
-    case 3: fprintf(stdout,_("first\n")); break;
-  }
-    
-  GSM->Terminate();    
-
-  return 0;
-
-}
-
-int setphoneprofile(int argc, char *argv[])
-{
-  GSM_PPS PPS;
-  GSM_Error error;
-  bool correct_arg1=false, correct_arg2=false;
-
-  if (!strcmp(argv[0],"ALS")) {
-    PPS.Name=PPS_ALS;
-    correct_arg1=true;
-    if (!strcmp(argv[1],"1")) {
-      PPS.bool_value=true;
-      correct_arg2=true;
-    }
-    if (!strcmp(argv[1],"0")) {
-      PPS.bool_value=false;
-      correct_arg2=true;
-    }
-    if (!correct_arg2) {
-      fprintf(stdout,_("Settings for ALS parameter can be \"0\" or \"1\" !\n"));
-      return -1;
-    }
-  }
-  if (!strcmp(argv[0],"HRData")) {
-    PPS.Name=PPS_HRData;
-    correct_arg1=true;
-    if (!strcmp(argv[1],"1")) {
-      PPS.bool_value=true;
-      correct_arg2=true;
-    }
-    if (!strcmp(argv[1],"0")) {
-      PPS.bool_value=false;
-      correct_arg2=true;
-    }
-    if (!correct_arg2) {
-      fprintf(stdout,_("Settings for HRData parameter can be \"0\" or \"1\" !\n"));
-      return -1;
-    }
-  }  
-  if (!correct_arg1) {
-    fprintf(stdout,_("First parameter can be \"ALS\" or \"HRData\" only !\n"));
-    return -1;
-  }
-
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
-
-  error=GSM->SetProductProfileSetting(&PPS);
-
-  if (error!=GE_NONE) {
-    fprintf(stdout,_("Error!\n"));
-    GSM->Terminate();    
-    return -1;
-  }
-
-  GSM->Reset(0x03);
-  
-  GSM->Terminate();    
-
-  return 0;
-
-}
-
-int getoperatorname()
-{
-
-  GSM_Network network;
-
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
-
-  if (GSM->GetOperatorName(&network)==GE_NONE)
-  {
-    if (!strcmp(network.Name,"")) {
-      fprintf(stdout,_("Phone doesn't have downloaded operator name\n"));
-    } else {
-      fprintf(stdout,_("Phone has downloaded operator name (\"%s\") for \"%s\" (\"%s\") network\n"),
-              network.Name,network.Code,GSM_GetNetworkName(network.Code));
-    }
-  }
-  
-  GSM->Terminate();    
-
-  return 0;
-
-}
-
-int setoperatorname(int argc, char *argv[])
-{
-
-  GSM_Network network;
-
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
-
-  if (argc==2) {
-    strncpy(network.Code,argv[0],7);
-    strncpy(network.Name,argv[1],50);
-  } else {
-    strcpy(network.Code,"000 00\0");
-    strcpy(network.Name,"\0");
-  }
-  
-  if (GSM->SetOperatorName(&network)==GE_NONE) {
-    if (GSM->GetOperatorName(&network)==GE_NONE) {
-      if (!strcmp(network.Name,"")) {
-        fprintf(stdout,_("Downloaded operator name is removed\n"));
-      } else {
-        fprintf(stdout,_("Downloaded operator name changed for \"%s\" network (\"%s\") to \"%s\"\n"),
-                network.Code,GSM_GetNetworkName(network.Code),network.Name);
-      }
-    }
-  }
-
-  GSM->Terminate();    
-
-  return 0;
-
-}
-
-int getvoicemailbox()
-{
-  GSM_PhonebookEntry entry;
-
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
-  
-  if (GSM->GetVoiceMailbox(&entry)==GE_NONE) {
-    fprintf(stdout,_("Voice mailbox number is "));
-    if (!strcmp(entry.Number,""))
-      fprintf(stdout,_("not set\n"));
-    else
-      fprintf(stdout,_("\"%s\"\n"),entry.Number);
-  }
-
-  GSM->Terminate();    
-
-  return 0;
-
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// flow diagram of netmonitordata():
-///////////////////////////////////////////////////////////////////////////////
-//
-//             get command line argument
-//                     |                       
-//                     v       
-//
-//             if specific phone model
-//                 use that model
-//             else
-//                 identify-phone:     (((((((( TO DO )))))))))))))
-//
-//                     |
-//                     v
-//             get_mon_param_info()    get phone netmonitor parameters name
-//                                     specifically to a 'model'
-//                     |
-//                     v
-//             parse_check()           check command line arguments
-//                     |               if all OK, go on else stop.
-//                     |               because we can have a input file
-//                     v               containing multiple
-//             parse_process()         command lines, we process each at once
-//                                     so we can exit early on errors.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-// private functions, see netmonitordata()
-void free_nm_info(PARAM_INFO_MON *info)
-{
-       PARAM_INFO_MON *tmp;    // pointer, iterator on info
-
-       // go to end of list
-
-       while (info->next != NULL)
-       {       tmp = info->next;
-               free(info->name);
-               free(info->mname);
-               free(info);
-               info = tmp;
-       }
-       free(info);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// this func retrieve parameters info from a file
-// and load it in a dynamic array, NULL terminated,
-// if 2rd parameter is not NULL, it load also description of screen
-// return (PARAM_INFO_MON *start) if all is OK, else NULL
-///////////////////////////////////////////////////////////////////////////////
-// start->->next->next->next-> ...->next->NULL
-//   |      |     |     |           |
-//   V      V     V     V           V
-//        par0  par1  par2        parN
-///////////////////////////////////////////////////////////////////////////////
-// this should be de-allocated from calling function,
-// also, screen_name should be deallocated from calling function
-///////////////////////////////////////////////////////////////////////////////
-
-PARAM_INFO_MON *get_mon_param_info(char *f_name, char *screen_name[NM_MAX_SCREEN+1])
-{
-       PARAM_INFO_MON *start;  // pointer to netmonitor parameters info
-       PARAM_INFO_MON *info;   // pointer, iterator on info
-       PARAM_INFO_MON *check;  // pointer, iterator on info, for check usage
-
-       FILE *f_info;
-
-       char buf[256];
-       char *param;
-       char *param_name;
-       char *tmp;
-
-       char tmp_mname[55];             // very larger, but if netmon bug ...
-       int x, y, len, s, t;            // x & y coord, len, screen nr, type
-       int i;
-
-       if (screen_name != NULL)
-               for (i = 0; i <= NM_MAX_SCREEN; i++)
-                       screen_name[i] = NULL;
-               
-
-       if ((f_info = fopen(f_name, "r")) == NULL)
-       {       fprintf(stderr, "Can' t open file parameter info: <%s>\n", f_name);
-               return(NULL);
-       }
-       
-       if ((start = malloc(sizeof(PARAM_INFO_MON))) == NULL)
-       {       fprintf(stderr, "no mem\n");
-               return(NULL);
-       }
-       else
-       {       start->next = NULL;
-       }
-
-       info = start;
-       while (fgets(buf, 256, f_info) != NULL)
-       {
-               param = buf;
-
-               // Truncate from '#' at right of comments
-               if ((tmp = strchr(param, '#')) != NULL)
-                       *tmp = '\0';
-
-               // Strip leading, trailing whitespace
-               while(isspace((int) *param))
-                       param++;
-
-               while((strlen(param) > 0) && isspace((int) param[strlen(param) - 1]))
-                       param[strlen(param) - 1] = '\0';
-       
-               // Ignore blank lines
-               if ((*param == '\n') || (*param == '\0'))
-                       continue;
-
-
-#ifdef DEBUG
-               fprintf(stderr, "%s: info line: <%s>\n", f_name, param);
-#endif
-               // check for param name
-               if ((param_name = strtok(param, "=\t\n")) == NULL)
-                       continue;
-
-               // check if screen name
-               if (strncmp("SCREEN", param_name, 6) == 0)
-               {       
-                       // if we do not want screen names ...
-                       if (screen_name == NULL)
-                               continue;
-
-// FIXME check for screen nr
-                       if ((tmp = strtok(NULL, ":\n")) == NULL)
-                               continue;
-       
-                       i = atoi(tmp);
-// FIXME: check if already defined screen
-
-                       if ((i <= 0) || (i > NM_MAX_SCREEN))
-                               continue;
-                       // check for screen name
-                       if ((tmp = strtok(NULL, ":\n")) == NULL)
-                               continue;
-
-                       screen_name[i] = strdup(tmp);
-               }
-               else 
-               {
-                       // parameter
-
-// FIXME: check for NM_MAX_FIELDS
-
-                       // check for x coord
-                       if ((tmp = strtok(NULL, ":\t\n")) == NULL)
-                               continue;
-                       x = atoi(tmp);
-
-                       // check for y coord
-                       if ((tmp = strtok(NULL, ":\t\n")) == NULL)
-                               continue;
-                       y = atoi(tmp);
-
-                       // check for len
-                       if ((tmp = strtok(NULL, ":\t\n")) == NULL)
-                               continue;
-                       len = atoi(tmp);
-       
-                       // check for screen
-                       if ((tmp = strtok(NULL, ":\t\n")) == NULL)
-                               continue;
-                       s = atoi(tmp);
-
-                       // check for netmon manual name
-                       if ((tmp = strtok(NULL, ":\t\n")) == NULL)
-                       {       fprintf(stderr,
-                                       "%s: PARAMETER <%s> in screen <%d>, not have netmon manual reference\n",
-                                       f_name, param_name, s);
-                               free_nm_info(start);
-                               return(NULL);
-                       }
-                       strcpy(tmp_mname, tmp);
-
-                       // check for data type (optional)
-                       if ((tmp = strtok(NULL, ":\t\n")) != NULL)      
-                               t = *tmp;
-                       else
-                               t = '\0';
-
-                       // check len, here, so we print parameter name
-                       if (len == 0)
-                       {       fprintf(stderr,
-                                       "%s: PARAMETER <%s> in screen <%d>, has invalid data lenght\n",
-                                       f_name, param_name, s);
-                               free_nm_info(start);
-                               return(NULL);
-                       }
-
-                       // check if already defined same param_name
-                       check = start;
-                       while (check->next != NULL)
-                       {       check = check->next;
-                               if (strcmp(param_name, check->name) == 0)
-                               {
-                                       fprintf(stderr,
-                                       "%s: PARAMETER <%s> in screen <%d> already defined as in screen <%d>\n",
-                                       f_name, param_name, s, check->s_nr);
-                                       free_nm_info(start);
-                                       return(NULL);
-                               }
-                       }
-
-                       // make space, and add parameter
-                       if ((info->next = malloc(sizeof(PARAM_INFO_MON))) != NULL)
-                       {
-                               info = info->next;
-                               info->name = strdup(param_name);
-                               info->x = x;
-                               info->y = y;
-                               info->len = len;
-                               info->s_nr = s;
-                               info->mname = strdup(tmp_mname);
-                               info->type = t;
-
-                               info->next = NULL;      // mark end
-                       }
-                       else
-                       {
-                               fprintf(stderr, "no mem");
-                               free_nm_info(start);
-                               return(NULL);
-                       }
-
-               }
-       
-       }
-
-       fclose(f_info);
-       
-#ifdef DEBUG
-       info = start;
-       while (info->next != NULL)
-       {
-               info = info->next;
-               fprintf(stderr, "info name %s\n", info->name);
-       }
-#endif
-       return(start);
-}
-
-// 2, parse the arguments and check command(s) line 
-// command line, phone spec input, and output are complex,
-// so we exit printing info about error instead of std help
-///////////////////////////////////////////////////////////////////////////////
-
-int parse_check(int argc, char *argv[], PARAM_INFO_MON *start, char *f_name, int line)
-{
-       int ctr;
-       int i;
-       int time_spec;
-       int found_data;
-       char *p;
-       char *tmp;
-       char *o;
-       PARAM_INFO_MON *info;                   // iterator on this list
-
-#ifdef DEBUG
-       for (i = 0; i < argc; i++)
-               fprintf(stderr, "argv[%d] = <%s>\n",i, argv[i]);
-#endif
-
-       time_spec = 0;
-       ctr = 0; 
-       i = 0;
-       while (i < argc)
-       {
-               p = argv[i];
-               if (*p == '-')
-               {                       // should be one of the short option
-                       if (strcmp(argv[i], "-fs") == 0)
-                       {               // field separator, next arg should be a string
-                               if (((i+1) < argc) && (strlen(argv[i+1]) < 10))
-                               {       i++;
-                                       // arg OK, do nothing
-                               }
-                               else
-                               {       if (line)
-                                               fprintf(stderr,
-                                                       "-fs: Invalid field separator in <%s> at line %d\n",
-                                                       f_name, line);
-                                       else
-                                               fprintf(stderr, "-fs: Invalid field separator\n");
-                                       return(-1);
-                               }
-                       }
-                       else if (strcmp(argv[i], "-ls") == 0) 
-                       {               // line separator, next arg should be a string
-                               if (((i+1) < argc) && (strlen(argv[i+1]) < 10))
-                               {       i++;
-                                       // arg OK, do nothing
-                               }
-                               else
-                               {       if (line)
-                                               fprintf(stderr,
-                                                       "-ls: Invalid line separator in <%s> at line %d\n",
-                                                       f_name, line);
-                                       else
-                                               fprintf(stderr, "-ls: Invalid line separator\n");
-                                       return(-1);
-                               }
-                       }
-                       else if (strcmp(argv[i], "-tm") == 0) 
-                       {               // time separator, next arg should be a millisecond (200-10000)
-                               if (time_spec)
-                               {       if (line)
-                                               fprintf(stderr,
-                                               "-tm, -ts, are mutually exclusive in <%s> at line %d\n",
-                                               f_name, line);
-                                       else
-                                               fprintf(stderr, "-tm, -ts, are mutually exclusive\n");
-                                       return(-1);
-                               }
-
-                               if (((i+1) < argc) && (atoi(argv[i+1]) >= 200) && (atoi(argv[i+1]) <= 10000))
-                               {       i++;
-                                       time_spec = 1;
-                                       // arg OK, do nothing
-                               }
-                               else
-                               {       if (line)
-                                               fprintf(stderr,
-                       "-tm: Invalid argument (200-10000 milliseconds), in <%s> at line %d\n",
-                                                       f_name, line);
-                                       else
-                                               fprintf(stderr, "-tm: Invalid argument (200-10000 milliseconds)\n");
-                                       return(-1);
-                               }
-                       }
-                       else if (strcmp(argv[i], "-ts") == 0) 
-                       {               // time separator, next arg should be a seconds (1-3600)
-                               if (time_spec)
-                               {       if (line)
-                                               fprintf(stderr,
-                                               "-tm, -ts, are mutually exclusive, in <%s> at line %d\n",
-                                                       f_name, line);
-                                       else
-                                               fprintf(stderr, "-tm, -ts, are mutually exclusive\n");
-                                       return(-1);
-                               }
-
-                               if (((i+1) < argc) && (atoi(argv[i+1]) >= 1) && (atoi(argv[i+1]) <= 3600))
-                               {       i++;
-                                       time_spec = 1;
-                                       // arg OK, do nothing
-                               }
-                               else
-                               {       if (line)
-                                               fprintf(stderr,
-                                       "-ts: Invalid argument (1-3600 seconds) in <%s> at line %d\n",  
-                                                       f_name, line);
-                                       else
-                                               fprintf(stderr, "-ts: Invalid argument (1-3600 seconds)\n");
-                                       return(-1);
-                               }
-                       }
-                       else if (strcmp(argv[i], "-n") == 0) 
-                       {               // nr of data pump, before stop collection,
-                                       // next arg should be a int > 0
-                               if (((i+1) < argc) && (atoi(argv[i+1]) >= 1) && (atoi(argv[i+1]) <= 99999))
-                               {       i++;
-                                       // arg OK, do nothing
-                               }
-                               else
-                               {       if (line)
-                                               fprintf(stderr,
-                                               "-n: Invalid argument (1-99999 times) in <%s> at line %d\n",
-                                                       f_name, line);
-                                       else
-                                               fprintf(stderr, "-n: Invalid argument (1-99999 times)\n");
-                                       return(-1);
-                               }
-                       }
-                       else if (strcmp(argv[i], "-h") == 0) 
-                       {               // we do NOT want header (default with header)
-                                       // arg OK, do nothing
-                       }
-                       else if (strcmp(argv[i], "-S") == 0) 
-                       {               // we have used use specs from a file instead of standard info,
-                                       // next arg is an existing readable filename
-                                       // as already parsed correctly, we skip here.
-                               i++;
-                       }
-                       else if (strcmp(argv[i], "-I") == 0) 
-                       {               // we have used input from a file instead of command line
-                                       // next arg is an existing readable filename
-                                       // as already parsed correctly, we skip here.
-                               i++;
-                       }       
-                       else
-                       {       
-                               if (line)
-                                       fprintf(stderr, "Unrecognized option %s in <%s> at line %d\n",
-                                               argv[i], f_name, line);
-                                       else
-                                               fprintf(stderr, "Unrecognized option %s\n", argv[i]);
-                               return(-1);
-                       }
-               }
-               else
-               {                       // should be required data
-                       tmp = strdup(argv[i]);
-                       p = strtok(tmp, ":\t\n");
-                       while (p != NULL)
-                       {
-                               // check if there is an output format specification
-                               o = p;
-                               while (*o)
-                               {
-                                       o++;
-                                       if (*o == '-')
-                                       {       *o = '\0';
-                                               o++;
-                                               if (strlen(o) == 0)
-                                               {
-                                                       // we have 'minus', so, probably forget format ...
-
-                                                       if (line)
-                                                               fprintf(stderr,
-                                        "Required data <%s->, without format specifiers in <%s> at line %d\n",
-                                                                       p, f_name, line);
-                                                       else
-                                                               fprintf(stderr,
-                                        "Required data <%s->, without format specifiers\n", p);
-                                                       return(-1);
-                                               }
-                                       }
-                               }
-                       
-                                                               // we check for params
-                               found_data = 0;
-                               info = start;
-                               while (info->next != NULL)
-                               {       
-                                       info = info->next;
-                                       if (strcmp(p, info->name) == 0)
-                                       {
-                                               if (ctr > NM_MAX_FIELDS)
-                                               {
-                                                       if (line)
-                                                               fprintf(stderr,
-                                               "too much data field ... in file <%s> at line %d\n",
-                                                                       f_name, line);
-                                                       else
-                                               fprintf(stderr, "too much data field ...\n");
-                                                       return (-1);
-                                               }
-/*
-                                               data[ctr] = info;
-                                               out_f[ctr] = *o;
-*/
-                                               found_data = 1;
-                                               ctr++;
-                                               break;
-                                       }
-                               }
-                       
-                               if (found_data == 0)
-                               {
-                                       if (line)
-                                               fprintf(stderr,
-                       "Required data <%s>, not found in info-mon specifications in <%s> at line %d\n",
-                                                       p, f_name, line);
-                                       else
-                                               fprintf(stderr,
-                       "Required data <%s>, not found in info-mon specifications\n", p);
-                                       return(-1);
-                               }
-       
-                               p = strtok(NULL, ":\t\n");
-
-                       } // end while strtok
-
-               } // end else '-' (short options)
-               
-               i++;
-
-       } // end while
-       
-       if (ctr == 0)
-       {
-               if (line)
-                       fprintf(stderr, "no required data! in <%s> at line %d\n", f_name, line);
-               else
-                       fprintf(stderr, "no required data!\n");
-               return(-1);
-       }
-
-       return 0;
-}
-                                                         
-// 2, parse the arguments and process the command line
-// no checks are needed here, because already do in parse_check
-// it return a pointer to info needed for make output, or NULL if errors
-///////////////////////////////////////////////////////////////////////////////
-OUT_INFO_MON *parse_process(int argc, char *argv[], PARAM_INFO_MON *start)
-{
-       int ctr;
-       int i;
-       int time_spec;
-       int found_data;
-       int req_tm;
-       int req_ts;
-       char *p;
-       char *tmp;
-       char *o;
-       PARAM_INFO_MON *info;                   // iterator on this list
-       OUT_INFO_MON *out_param;                // iterator on this list
-
-       if ((out_param = malloc(sizeof(OUT_INFO_MON))) == NULL)
-       {       fprintf(stderr, "no mem\n");
-               return(NULL);
-       }
-
-#ifdef DEBUG
-       fprintf(stderr, "parse_process: argc = %d\n", argc);
-               for (i = 0; i < argc; i++)
-                       fprintf(stderr, "argv[%d] = <%s>\n",i, argv[i]);
-#endif
-
-       for (i = 0; i < NM_MAX_FIELDS; i++)
-               out_param->data[i] = NULL;
-
-       strcpy(out_param->req_fs, " ");
-#ifdef WIN32
-       strcpy(out_param->req_ls, "\n\r");
-#else
-       strcpy(out_param->req_ls, "\n");
-#endif
-       time_spec = 0;
-       out_param->req_n = 0;
-       out_param->req_header = 1;
-
-       time_spec = 0;
-       req_tm = 200;                   /* default wait */
-       req_ts = 0;     
-       
-       ctr = 0; 
-       i = 0;
-       while (i < argc)
-       {
-               p = argv[i];
-               if (*p == '-')
-               {                       // should be one of the short option
-                       if (strcmp(argv[i], "-fs") == 0)
-                       {               // field separator, next arg should be a string
-                               if (((i+1) < argc) && (strlen(argv[i+1]) < 10))
-                               {       i++;
-                                       strcpy(out_param->req_fs, argv[i]);
-                               }
-                               else
-                               {       fprintf(stderr, "NEVER BE:-fs: Invalid field separator\n");
-                                       return(NULL);
-                               }
-                       }
-                       else if (strcmp(argv[i], "-ls") == 0) 
-                       {               // line separator, next arg should be a string
-                               if (((i+1) < argc) && (strlen(argv[i+1]) < 10))
-                               {       i++;
-                                       strcpy(out_param->req_ls, argv[i]);
-                               }
-                               else
-                               {       fprintf(stderr, "NEVER BE:-ls: Invalid line separator\n");
-                                       return(NULL);
-                               }
-                       }
-                       else if (strcmp(argv[i], "-tm") == 0) 
-                       {               // time separator, next arg should be a millisecond (200-10000)
-                               if (time_spec)
-                               {       fprintf(stderr, "NEVER BE:-tm, -ts, are mutually exclusive");
-                                       return(NULL);
-                               }
-
-                               if (((i+1) < argc) && (atoi(argv[i+1]) >= 200) && (atoi(argv[i+1]) <= 10000))
-                               {       i++;
-                                       req_tm = atoi(argv[i]);
-                                       time_spec = 1;
-                               }
-                               else
-                               {       fprintf(stderr, "NEVER BE:-tm: Invalid argument (200-10000 milliseconds)\n");
-                                       return(NULL);
-                               }
-                       }
-                       else if (strcmp(argv[i], "-ts") == 0) 
-                       {               // time separator, next arg should be a seconds (1-3600)
-                               if (time_spec)
-                               {       fprintf(stderr, "NEVER BE:-tm, -ts, are mutually exclusive");
-                                       return(NULL);
-                               }
-
-                               if (((i+1) < argc) && (atoi(argv[i+1]) >= 1) && (atoi(argv[i+1]) <= 3600))
-                               {       i++;
-                                       req_ts = atoi(argv[i]);
-                                       time_spec = 1;
-
-                                       // delete default
-                                       req_tm = 0;
-                               }
-                               else
-                               {       fprintf(stderr, "NEVER BE:-ts: Invalid argument (1-3600 seconds)\n");
-                                       return(NULL);
-                               }
-                       }
-                       else if (strcmp(argv[i], "-n") == 0) 
-                       {               // nr of data pump, before stop collection,
-                                       // next arg should be a int > 0
-                               if (((i+1) < argc) && (atoi(argv[i+1]) >= 1) && (atoi(argv[i+1]) <= 99999))
-                               {       i++;
-                                       out_param->req_n = atoi(argv[i]);
-                               }
-                               else
-                               {       fprintf(stderr, "NEVER BE:-n: Invalid argument (1-99999 times)\n");
-                                       return(NULL);
-                               }
-                       }
-                       else if (strcmp(argv[i], "-h") == 0) 
-                       {               // we do NOT want header (default with header)
-                               out_param->req_header = 0;
-                       }
-                       else if (strcmp(argv[i], "-S") == 0) 
-                       {               // we have used use specs from a file instead of standard info,
-                                       // next arg is an existing readable filename
-                                       // as already parsed correctly, we skip here.
-                               i++;
-                       }
-                       else if (strcmp(argv[i], "-I") == 0) 
-                       {               // we have used input from a file instead of command line
-                                       // next arg is an existing readable filename
-                                       // as already parsed correctly, we skip here.
-                               i++;
-                       }       
-                       else
-                       {       
-                               fprintf(stderr, "NEVER BE:Unrecognized option %s\n", argv[i]);
-                               return(NULL);
-                       }
-               }
-               else
-               {                       // should be required data
-                       tmp = strdup(argv[i]);
-                       p = strtok(tmp, ":\t\n");
-                       while (p != NULL)
-                       {
-                               // check if there is an output format specification
-                               o = p;
-                               while (*o)
-                               {
-                                       o++;
-                                       if (*o == '-')
-                                       {       *o = '\0';
-                                               o++;
-                                               if (strlen(o) == 0)
-                                               {
-                                                       // we have 'minus', so, probably forget format ...
-
-                                                       fprintf(stderr,
-                                                        "NEVER BE:Required data <%s->, without format specifiers\n", p);
-                                                       return(NULL);
-                                               }
-                                       }
-                               }
-                       
-                                                       // we check for params
-                               found_data = 0;
-                               info = start;
-                               while (info->next != NULL)
-                               {       
-                                       info = info->next;
-                                       if (strcmp(p, info->name) == 0)
-                                       {
-                                               if (ctr > NM_MAX_FIELDS)
-                                               {
-                                                       fprintf(stderr, "NEVER BE:too much data field ...");
-                                                       return(NULL);
-                                               }
-                                               out_param->data[ctr] = info;
-                                               out_param->out_f[ctr] = *o;
-                                               found_data = 1;
-                                               ctr++;
-                                               break;
-                                       }
-                               }
-                               
-                               if (found_data == 0)
-                               {
-                                       fprintf(stderr,
-                                               "NEVER BE:Required data <%s>, not found in info-mon specifications\n", p);
-                                       return(NULL);
-                               }
-       
-
-                               p = strtok(NULL, ":\t\n");
-
-                       } // end while strtok
-
-                       // here, we have an array of pointers to required data
-                       // and an array of output specifiers, from 0 to [ctr-1]
-
-               } // end else '-' (short options)
-               
-               i++;
-
-       } // end while
-       
-       if (ctr == 0)
-       {
-               fprintf(stderr, "NEVER BE:no required data!\n");
-               return(NULL);
-       }
-       
-       // now, what netmon screen we need to retrieve ?
-       // we need somewhat were checking is faster, as our goal is lower cicle time
-
-       // we can have NM_MAX_SCREEN=254 screens, so we use an array, of unsigned char,
-       // each char contain number of needed screen, 255 is list terminator
-       
-       for (i = 0; i <= NM_MAX_SCREEN; i++)
-               out_param->req_screen[i] = 255;
-
-       ctr = 0;
-#ifdef DEBUG
-fprintf(stderr, "Start Required data %s screen %d\n", out_param->data[ctr]->name, out_param->data[ctr]->s_nr);
-#endif
-       while (out_param->data[ctr] != NULL)
-       {
-#ifdef DEBUG
-fprintf(stderr, "Required data %s screen %d\n", out_param->data[ctr]->name, out_param->data[ctr]->s_nr);
-#endif
-               // check if screen already in 
-               found_data = 0;
-               i = 0;
-               while (out_param->req_screen[i] != 255)
-               {
-                       if (out_param->req_screen[i] == out_param->data[ctr]->s_nr)
-                       {               // already load, skip
-                               found_data = 1;
-                               break;
-                       }
-                       i++;
-               }
-
-               if (found_data == 0)
-               {       
-#ifdef DEBUG
-fprintf(stderr, "i = %d, out_param->req_screen[%d] = %d\n", i, i, out_param->data[ctr]->s_nr);
-#endif
-                       out_param->req_screen[i] = out_param->data[ctr]->s_nr;
-                       i++;
-               }
-
-               ctr++;
-       }
-
-#ifdef DEBUG
-i = 0;
-while (out_param->req_screen[i] != 255)
-{
-       fprintf(stderr, "Required screen %d\n", out_param->req_screen[i]);
-       i++;
-}
-#endif
-       
-       if (req_tm)
-               out_param->req_wait = req_tm * 1000;
-       else if (req_ts)
-               out_param->req_wait = req_ts * 1000000;
-       else
-               out_param->req_wait = req_tm * 1000;
-       
-
-       return(out_param);
-}
-
-int nmd_output(OUT_INFO_MON *out_param)
-{
-       int d;
-       int len;
-       int ctr;
-       int i;
-       int nr_line;
-       char *p;
-       int nr_chr;
-       int n;
-       char Screen[NM_MAX_SCREEN_WIDTH];
-       time_t sec;
-       struct tm *date_time;
-
-       if (out_param->req_header)
-       {
-// print phone help header
-               d = 0;
-               while (out_param->data[d] != NULL)
-               {       len = out_param->data[d]->len;
-                       if (strlen(out_param->data[d]->name) > len)
-                               len = strlen(out_param->data[d]->name);
-                       if (strlen(out_param->data[d]->mname) > len)
-                               len = strlen(out_param->data[d]->mname);
-                       printf("%*.*s%s", len, len, out_param->data[d]->name, out_param->req_fs);
-                       d++;
-               }
-               printf("%s", out_param->req_ls);
-
-// print netmon manual header
-               d = 0;
-               while (out_param->data[d] != NULL)
-               {       len = out_param->data[d]->len;
-                       if (strlen(out_param->data[d]->name) > len)
-                               len = strlen(out_param->data[d]->name);
-                       if (strlen(out_param->data[d]->mname) > len)
-                               len = strlen(out_param->data[d]->mname);
-                       printf("%*.*s%s", len, len, out_param->data[d]->mname, out_param->req_fs);
-                       d++;
-               }
-               printf("%s", out_param->req_ls);
-               printf("%s", out_param->req_ls);
+       switch (error) {
+       case GE_CANTOPENFILE:
+               fprintf(stderr, _("Failed to read file \"%s\"\n"), FileName);
+               break;
+       case GE_WRONGNUMBEROFCOLORS:
+               fprintf(stderr, _("Wrong number of colors in \"%s\" logofile (accepted only 2-colors files) !\n"), FileName);
+               break;
+       case GE_WRONGCOLORS:
+               fprintf(stderr, _("Wrong colors in \"%s\" logofile !\n"), FileName);
+               break;
+       case GE_INVALIDFILEFORMAT:
+               fprintf(stderr, _("Invalid format of \"%s\" logofile !\n"), FileName);
+               break;
+       case GE_SUBFORMATNOTSUPPORTED:
+               fprintf(stderr, _("Sorry, gnokii doesn't support used subformat in file \"%s\" !\n"), FileName);
+               break;
+       case GE_FILETOOSHORT:
+               fprintf(stderr, _("\"%s\" logofile is too short !\n"), FileName);
+               break;  
+       case GE_INVALIDIMAGESIZE:
+               fprintf(stderr, _("Bitmap size doesn't supported by fileformat or different from 72x14, 84x48 and 72x28 !\n"));
+               break;
+       default:
+               break;
        }
        }
+  
+       return error;
+}
 
 
-       ctr = 0;
-       while (!bshutdown)
-       {
-// stop after n data punp
-
-               ctr++;
-               if ((out_param->req_n) && (ctr > out_param->req_n))
-                       break;
-
-//             datapump: for each screen, for each required data, load data info->value
-
-               i = 0;
-               while(out_param->req_screen[i] != 255)
-               {       
-                       if (out_param->req_screen[i] == 0)
-                       {       
-                               sec = time(0);
-                               date_time = localtime(&sec);
-                               sprintf(Screen, "%02d-%02d-%04d\n%02d:%02d:%02d\n",
-                                       date_time->tm_mday,
-                                       date_time->tm_mon+1,
-                                       date_time->tm_year+1900,
-                                       date_time->tm_hour,
-                                       date_time->tm_min,
-                                       date_time->tm_sec);
-#ifdef DEBUG
-                               fprintf(stderr, "%02d-%02d-%04d\n%02d:%02d:%02d\n",
-                                       date_time->tm_mday,
-                                       date_time->tm_mon+1,
-                                       date_time->tm_year+1900,
-                                       date_time->tm_hour,
-                                       date_time->tm_min,
-                                       date_time->tm_sec);
-#endif
-                       }
-                       else
-                       {
-                               GSM->NetMonitor(out_param->req_screen[i], Screen);
-                       }
 
 
-// we have one screen of data, load those required
+int setlogo(int argc, char *argv[])
+{
+       GSM_Bitmap bitmap,oldbit;
+       GSM_NetworkInfo NetworkInfo;
+       GSM_Error error;
+  
+       bool ok = true;
+       int i;
+  
+       if (!strcmp(argv[0],"text") || !strcmp(argv[0],"dealer")) {
+               if (!strcmp(argv[0], "text")) bitmap.type = GSM_WelcomeNoteText;
+               else bitmap.type = GSM_DealerNoteText;
+               bitmap.text[0] = 0x00;
+               if (argc > 1) strncpy(bitmap.text, argv[1], 255);
+       } else {
+               if (!strcmp(argv[0], "op") || !strcmp(argv[0], "startup") || !strcmp(argv[0], "caller")) {
+                       if (argc > 1) {
+                               if (ReadBitmapFileOnConsole(argv[1], &bitmap) != GE_NONE) {
+                                       GSM->Terminate();
+                                       return(-1);
+                               }
 
 
-                       d = 0;
-                       while (out_param->data[d] != NULL)
-                       {       
-                               if (out_param->data[d]->s_nr == out_param->req_screen[i])
-                               {
-                                       p = Screen;
-// goto req y          
-                                       nr_line = out_param->data[d]->y;
-                                       while ((*p) && (nr_line))
-                                       {       
-                                               if (*p == '\n')
-                                               {       nr_line--;
+                               if (!strcmp(argv[0], "op")) {
+                                       if (bitmap.type != GSM_OperatorLogo || argc < 3) {
+                                               if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE) strncpy(bitmap.netcode, NetworkInfo.NetworkCode, 7);
+                                       }
+                                       GSM_ResizeBitmap(&bitmap, GSM_OperatorLogo, GSM_Info);
+                                       if (argc == 3) {
+                                               strncpy(bitmap.netcode, argv[2], 7);
+                                               if (!strcmp(GSM_GetNetworkName(bitmap.netcode), "unknown")) {
+                                                       fprintf(stderr, "Sorry, gnokii doesn't know %s network !\n", bitmap.netcode);
+                                                       return -1;
                                                }
                                                }
-                                               p++;
                                        }
                                        }
-#ifdef DEBUG
-fprintf(stderr, "\nthis line: %s\n\n", p);
-#endif
-
-// goto req x
-                                       nr_chr = out_param->data[d]->x;
-                                       while ((*p) && (nr_chr))
-                                       {       p++;
-                                               nr_chr--;
+                               }
+                               if (!strcmp(argv[0], "startup")) {
+                                       GSM_ResizeBitmap(&bitmap, GSM_StartupLogo, GSM_Info);
+                               }
+                               if (!strcmp(argv[0],"caller")) {
+                                       GSM_ResizeBitmap(&bitmap, GSM_CallerLogo, GSM_Info);
+                                       if (argc > 2) {
+                                               bitmap.number = argv[2][0] - '0';
+                                               if ((bitmap.number < 0) || (bitmap.number > 9)) bitmap.number = 0;
+                                       } else {
+                                               bitmap.number = 0;
+                                       }
+                                       oldbit.type = GSM_CallerLogo;
+                                       oldbit.number = bitmap.number;
+                                       if (GSM->GetBitmap(&oldbit) == GE_NONE) {
+                                               /* We have to get the old name and ringtone!! */
+                                               bitmap.ringtone = oldbit.ringtone;
+                                               strncpy(bitmap.text, oldbit.text, 255);
                                        }
                                        }
-// this the start of data
-                                       n = 0;
-                                       len = out_param->data[d]->len;
-                                       while ((*p) && (len))
-                                       {       out_param->data[d]->value[n] = *p;
-                                               p++;
-                                               n++;
-                                               len--;
+                                       if (argc > 3) strncpy(bitmap.text, argv[3], 255);         
+                               }
+                               fprintf(stdout, _("Setting Logo.\n"));
+                       } else {
+                               /* FIX ME: is it possible to permanently remove op logo ? */
+                               if (!strcmp(argv[0], "op"))
+                               {
+                                       bitmap.type = GSM_OperatorLogo;
+                                       strncpy(bitmap.netcode, "000 00", 7);
+                                       bitmap.width = 72;
+                                       bitmap.height = 14;
+                                       bitmap.size = bitmap.width * bitmap.height / 8;
+                                       GSM_ClearBitmap(&bitmap);
+                               }
+                               /* FIX ME: how to remove startup and group logos ? */
+                               fprintf(stdout, _("Removing Logo.\n"));
+                       }  
+               } else {
+                       fprintf(stderr, _("What kind of logo do you want to set ?\n"));
+                       GSM->Terminate();
+                       return -1;
+               }
+       }
+    
+       error=GSM->SetBitmap(&bitmap);
+  
+       switch (error) {
+       case GE_NONE:
+               oldbit.type = bitmap.type;
+               oldbit.number = bitmap.number;
+               if (GSM->GetBitmap(&oldbit) == GE_NONE) {
+                       if (bitmap.type == GSM_WelcomeNoteText ||
+                           bitmap.type == GSM_DealerNoteText) {
+                               if (strcmp(bitmap.text, oldbit.text)) {
+                                       fprintf(stderr, _("Error setting"));
+                                       if (bitmap.type == GSM_DealerNoteText) fprintf(stderr, _(" dealer"));
+                                       fprintf(stderr, _(" welcome note - "));
+
+                                       /* I know, it looks horrible, but... */
+                                       /* I set it to the short string - if it won't be set */
+                                       /* it means, PIN is required. If it will be correct, previous */
+                                       /* (user) text was too long */
+
+                                       /* Without it, I could have such thing: */
+                                       /* user set text to very short string (for example, "Marcin") */
+                                       /* then enable phone without PIN and try to set it to the very long (too long for phone) */
+                                       /* string (which start with "Marcin"). If we compare them as only length different, we could think, */
+                                       /* that phone accepts strings 6 chars length only (length of "Marcin") */
+                                       /* When we make it correct, we don't have this mistake */
+                       
+                                       strcpy(oldbit.text, "!\0");
+                                       GSM->SetBitmap(&oldbit);
+                                       GSM->GetBitmap(&oldbit);
+                                       if (oldbit.text[0]!='!') {
+                                               fprintf(stderr, _("SIM card and PIN is required\n"));
+                                       } else {
+                                               GSM->SetBitmap(&bitmap);
+                                               GSM->GetBitmap(&oldbit);
+                                               fprintf(stderr, _("too long, truncated to \"%s\" (length %i)\n"),oldbit.text,strlen(oldbit.text));
                                        }
                                        }
-// pad with space if shorter than presumed
-                                       while ((*p) && (len))
-                                       {       out_param->data[d]->value[n] = ' ';
-                                               n++;
-                                               len--;
+                                       ok = false;
+                               }
+                       } else {
+                               if (bitmap.type == GSM_StartupLogo) {
+                                       for (i = 0; i < oldbit.size; i++) {
+                                               if (oldbit.bitmap[i] != bitmap.bitmap[i]) {
+                                                       fprintf(stderr, _("Error setting startup logo - SIM card and PIN is required\n"));
+                                                       ok = false;
+                                                       break;
+                                               }
                                        }
                                        }
-
-                                       out_param->data[d]->value[n] = '\0';
                                }
                                }
-
-                               d++;    // next screen
                        }
                        }
-
-                       i++;            // next screen
                }
                }
+               if (ok) fprintf(stdout, _("Done.\n"));
+               break;
+       case GE_NOTIMPLEMENTED:
+               fprintf(stderr, _("Function not implemented.\n"));
+               break;
+       case GE_NOTSUPPORTED:
+               fprintf(stderr, _("This kind of logo is not supported.\n"));
+               break;
+       default:
+               fprintf(stderr, _("Error !\n"));
+               break;
+       }
+  
+       GSM->Terminate();
 
 
-// print row of data
-               d = 0;
-               while (out_param->data[d] != NULL)
-               {       
-                       len = out_param->data[d]->len;
-                       if (out_param->req_header)
-                       {       if (strlen(out_param->data[d]->name) > len)
-                                       len = strlen(out_param->data[d]->name);
-                               if (strlen(out_param->data[d]->mname) > len)
-                                       len = strlen(out_param->data[d]->mname);
-                       }
-// FIXME check format
-                       printf("%*.*s%s", len, len, out_param->data[d]->value, out_param->req_fs);
-                       d++;
-               }
-               printf("%s", out_param->req_ls);
+       return 0;
+}
 
 
-               usleep(out_param->req_wait);
-               
-       }
 
 
-       printf("%s%s", out_param->req_ls, out_param->req_ls);
+int viewlogo(char *filename)
+{
+       GSM_Error error;
 
 
-       return(0);
+       error = GSM_ShowBitmapFile(filename);
+       return 0;
 }
 
 }
 
-// main func
-///////////////////////////////////////////////////////////////////////////////
-int netmonitordata(int argc, char *argv[])
+/* Calendar notes receiving. */
+int getcalendarnote(int argc, char *argv[])
 {
 {
-       char *loc_info = NULL;                  // path to --netmonitordata directory
-       char *f_name;                           // absolute path of phone info-file
-       int flag_phone_spec = 0;                // flags, set if used -S option
-
-       char model[20] = "phonepar";            // TO DO: PHONE AUTODETECTION
-//     char phver[20] = "";
-
-       PARAM_INFO_MON *start;                  // pointer to list of parsed phone params
-       OUT_INFO_MON *out_param;                // pointer to struct of output data
-
-       char *f_commands = NULL;                // file containings input line arguments
-       FILE *commands;                         // Handle for this file
-       char buf[1024];                         // buffer
-       char *f_argv[NM_MAX_FIELDS+30];         // space for parameters and cmdline options
-       int f_argc;
-       char *p, *tmp;                          // various counter, flags, tmp area ...
-       int i;
-       int line;
+       GSM_CalendarNote        CalendarNote;
+       GSM_Data                data;
+       GSM_Error               error = GE_NONE;
+       int                     i, first_location, last_location;
+       bool                    vCal = false;
        
        
-
-       fbusinit(NULL);
-
-       signal(SIGINT, interrupted);
+       struct option options[] = {
+               { "vCard",    optional_argument, NULL, '1'},
+               { NULL,      0,                 NULL, 0}
+       };
        
        
-// FIXME model, phone_version
-
-       // before parsing phone-info-file, we check for user specified phone-info-file
-
-       i = 0;
-       while (i < argc)
-       {
-               if (strcmp(argv[i], "-S") == 0)
-               {
-                       if ((i+1) < argc)
-                       {
-                               flag_phone_spec = 1;
-                               loc_info = strdup(argv[i+1]);
-                               break;
-                       }
-                       else
-                       {       fprintf(stderr, "option -S require an argument ...\n");
-                               return -1;
-                       }
-               }
+       optarg = NULL;
+       optind = 0;
 
 
-               i++;
+       first_location = last_location = atoi(argv[0]);
+       if ((argc > 1) && (argv[1][0] != '-')) {
+               last_location = atoi(argv[1]);
        }
        
        }
        
-       if (loc_info != NULL)
-       {       f_name = strdup(loc_info);
-       }
-       else                            // we use standard file specification
-       {
-               if ((tmp = getenv("INFOMONPATH")) == NULL)
-               {       loc_info = strdup(".");
-               }
-               else
-               {       loc_info = strdup(tmp);
+       while ((i = getopt_long(argc, argv, "v", options, NULL)) != -1) {
+               switch (i) {       
+               case 'v':
+                       vCal=true;
+                       break;
+               default:
+                       usage(); /* Would be better to have an calendar_usage() here. */
+                       return -1;
                }
                }
-
-               f_name = malloc(strlen(loc_info)+strlen(model)+10); 
-               sprintf(f_name, "%s/%s", loc_info, model);
        }
 
        }
 
-
-#ifdef DEBUG
-//     fprintf(stderr, "Loc_info <%s> model <%s> version <%s>\n", loc_info, model, phver);
-       fprintf(stderr, "Info file: <%s>\n", f_name);
-#endif
-       if ((start = get_mon_param_info(f_name, NULL)) == NULL)
-               return(-1);             
-
-       // option -I give us the possibility of specify a filename,
-       // containing a "sequence" of command line args.
-       // if you specify this option, you can use (on command line) only -S option.
-       // other options may be specified inside the input-file.
-       // contents of this file as the same sintax as the command line,
-       // except it must not contain "--netmonitordata" or "-I" or "-S" options 
-        ///////////////////////////////////////////////////////////////////////
-
-       i = 0;
-       while (i < argc)
-       {
-               if (strcmp(argv[i], "-I") == 0)
-               {
-                       if ((i+1) < argc)
-                       {
-                               if ((argc == 2) || ((argc == 4) && flag_phone_spec == 1))
-                               {       f_commands = strdup(argv[i+1]);
+                                                                                                        
+       for (i = first_location; i <= last_location; i++) {
+               CalendarNote.Location = i;
+               if (GSM && GSM->GetCalendarNote && GSM->Terminate) {
+                       error = GSM->GetCalendarNote(&CalendarNote);
+                       GSM->Terminate();
+               } else {
+                       GSM_DataClear(&data);
+                       data.CalendarNote = &CalendarNote;
+
+                       error = SM_Functions(GOP_GetCalendarNote, &data, &State);
+               }
+               switch (error) {
+               case GE_NONE:
+                       if (vCal) {
+                               fprintf(stdout, "BEGIN:VCALENDAR\n");
+                               fprintf(stdout, "VERSION:1.0\n");
+                               fprintf(stdout, "BEGIN:VEVENT\n");
+                               fprintf(stdout, "CATEGORIES:");
+                               switch (CalendarNote.Type) {
+                               case GCN_REMINDER:
+                                       fprintf(stdout, "MISCELLANEOUS\n");
+                                       break;
+                               case GCN_CALL:
+                                       fprintf(stdout, "PHONE CALL\n");
+                                       break;
+                               case GCN_MEETING:
+                                       fprintf(stdout, "MEETING\n");
+                                       break;
+                               case GCN_BIRTHDAY:
+                                       fprintf(stdout, "SPECIAL OCCASION\n");
+                                       break;
+                               default:
+                                       fprintf(stdout, "UNKNOWN\n");
+                                       break;
                                }
                                }
-                               else
-                               {       fprintf(stderr, "option -I accept only additional -S option.\n");
-                                       return -1;
+                               fprintf(stdout, "SUMMARY:%s\n",CalendarNote.Text);
+                               fprintf(stdout, "DTSTART:%04d%02d%02dT%02d%02d%02d\n", CalendarNote.Time.Year,
+                                       CalendarNote.Time.Month, CalendarNote.Time.Day, CalendarNote.Time.Hour,
+                                       CalendarNote.Time.Minute, CalendarNote.Time.Second);
+                               if (CalendarNote.Alarm.Year!=0) {
+                                       fprintf(stdout, "DALARM:%04d%02d%02dT%02d%02d%02d\n", CalendarNote.Alarm.Year,
+                                               CalendarNote.Alarm.Month, CalendarNote.Alarm.Day, CalendarNote.Alarm.Hour,
+                                               CalendarNote.Alarm.Minute, CalendarNote.Alarm.Second);
+                               }
+                               fprintf(stdout, "END:VEVENT\n");
+                               fprintf(stdout, "END:VCALENDAR\n");
+
+                       } else {  /* not vCal */
+                               fprintf(stdout, _("   Type of the note: "));
+
+                               switch (CalendarNote.Type) {
+                               case GCN_REMINDER:
+                                       fprintf(stdout, _("Reminder\n"));
+                                       break;
+                               case GCN_CALL:
+                                       fprintf(stdout, _("Call\n"));
+                                       break;
+                               case GCN_MEETING:
+                                       fprintf(stdout, _("Meeting\n"));
+                                       break;
+                               case GCN_BIRTHDAY:
+                                       fprintf(stdout, _("Birthday\n"));
+                                       break;
+                               default:
+                                       fprintf(stdout, _("Unknown\n"));
+                                       break;
                                }
 
                                }
 
-                               break;
-                       }
-                       else
-                       {       fprintf(stderr, "option -I require an argument ...\n");
-                               return -1;
-                       }
-               }
-
-               i++;
-       }
-       
-       // before all, we check all command line
-       
-       if (f_commands != NULL)
-       {       
-#ifdef DEBUG
-               fprintf(stderr, "netmonitordata(check): commands from <%s>\n", f_commands);
-#endif
-               // for each line
-               // do
-               //      read line, make array f_argv, and counter f_argc
-               //      parse & check args, so errors are checked before real processing
-               //                             (-I option here is ignored)
-               //                             (-S option can be here, and it is used)
-               // done
-
-               if ((commands = fopen(f_commands, "r")) == NULL)
-               {       fprintf(stderr, "Can' t open file commands input :<%s>n", f_commands);
-                       return(-1);
-               }
-       
-// FIXME line may be be splitted
-               line = 0;
-               while (fgets(buf, 1024, commands) != NULL)
-               {       
-                       p = buf;
-                       line++;
-
-                       // Truncate from '#' at right of comments
-                       if ((tmp = strchr(p, '#')) != NULL)
-                               *tmp = '\0';
-
-                       // Strip leading, trailing whitespace
-                       while(isspace((int) *p))
-                               p++;
-
-                       while((strlen(p) > 0) && isspace((int) p[strlen(p) - 1]))
-                               p[strlen(p) - 1] = '\0';
-       
-                       // Ignore blank lines
-                       if ((*p == '\n') || (*p == '\0'))
-                               continue;
-                       
-#ifdef DEBUG
-fprintf(stderr, "netmonitordata(check): row <%s>\n", p);
-#endif
-                       // make args
-                       f_argc = 0;
-
-                       p = strtok(p, " \t");
-                       do
-                       {       f_argv[f_argc++] = strdup(p);
-#ifdef DEBUG
-fprintf(stderr, "netmonitordata(check): token <%s>\n", p);
-#endif
-                               p = strtok(NULL, " \t");                // OK p,  (NULL)
-                       }
-                       while ((p != NULL) && (*p));
-       
-                       // here we have f_argc, f_argv, this line is OK
-               
-                       if (parse_check(f_argc, f_argv, start, f_commands, line) != 0)
-                       {       free_nm_info(start);
-                               return(-1);
-                       }
-               }
-       
-               fclose(commands);
-       }
-       else    // as above, but we have only command line, argv, argc.
-       {
-               if (parse_check(argc, argv, start, NULL, 0) != 0)
-               {       free_nm_info(start);
-                       return(-1);
-               }
-       }
-       
-       // here, all commands line are checked, and are correct
-
-       if (f_commands != NULL)
-       {       
-#ifdef DEBUG
-               fprintf(stderr, "netmonitordata(process): commands from <%s>\n", f_commands);
-#endif
+                               fprintf(stdout, _("   Date: %d-%02d-%02d\n"), CalendarNote.Time.Year,
+                                       CalendarNote.Time.Month,
+                                       CalendarNote.Time.Day);
 
 
-               // for each line
-               // do
-               //      read line, make array f_argv, and counter f_argc
-               //      parse_process argument,   (-I option here is ignored)
-               //                                (-S option can be here, and it is used)
-               //      (make header                    // these are in nmd_output();
-               //       loop
-               //              get net-mon-info 
-               //              make output
-               //       done)
-               // done
-
-               if ((commands = fopen(f_commands, "r")) == NULL)
-               {       fprintf(stderr, "Can' t open file commands input :<%s>n", f_commands);
-                       return(-1);
-               }
-       
-// FIXME line may be be splitted
-               while (fgets(buf, 1024, commands) != NULL)
-               {       
-                       p = buf;
+                               fprintf(stdout, _("   Time: %02d:%02d:%02d\n"), CalendarNote.Time.Hour,
+                                       CalendarNote.Time.Minute,
+                                       CalendarNote.Time.Second);
 
 
-                       // Truncate from '#' at right of comments
-                       if ((tmp = strchr(p, '#')) != NULL)
-                               *tmp = '\0';
+                               if (CalendarNote.Alarm.AlarmEnabled == 1) {
+                                       fprintf(stdout, _("   Alarm date: %d-%02d-%02d\n"), CalendarNote.Alarm.Year,
+                                               CalendarNote.Alarm.Month,
+                                               CalendarNote.Alarm.Day);
 
 
-                       // Strip leading, trailing whitespace
-                       while(isspace((int) *p))
-                               p++;
+                                       fprintf(stdout, _("   Alarm time: %02d:%02d:%02d\n"), CalendarNote.Alarm.Hour,
+                                               CalendarNote.Alarm.Minute,
+                                               CalendarNote.Alarm.Second);
+                               }
 
 
-                       while((strlen(p) > 0) && isspace((int) p[strlen(p) - 1]))
-                               p[strlen(p) - 1] = '\0';
-       
-                       // Ignore blank lines
-                       if ((*p == '\n') || (*p == '\0'))
-                               continue;
-                       
-                       // make args
+                               fprintf(stdout, _("   Text: %s\n"), CalendarNote.Text);
 
 
-                       f_argc = 0;
-                       p = strtok(p, " \t");
-                       do
-                       {       f_argv[f_argc++] = strdup(p);
-                               p = strtok(NULL, " \t");                // OK p,  (NULL)
+                               if (CalendarNote.Type == GCN_CALL)
+                                       fprintf(stdout, _("   Phone: %s\n"), CalendarNote.Phone);
                        }
                        }
-                       while ((p != NULL) && (*p));
-       
-                       // here we have f_argc, f_argv, this line is OK
-               
-                       if ((out_param = parse_process(f_argc, f_argv, start)) == NULL)
-                       {       free_nm_info(start);
-                               return(-1);     /* NEVER BE */
-                       }
-               
-                       // here, command line has no error ...
-
-                       nmd_output(out_param);
-
-                       free(out_param);
-               }
-       
-               fclose(commands);
-       }
-       else    // as above, but we have only command line, argv, argc.
-       {
-               if ((out_param = parse_process(argc, argv, start)) == NULL)
-               {       free_nm_info(start);
-                       return(-1);     /* NEVER BE */
+                       break;
+               case GE_NOTIMPLEMENTED:
+                       fprintf(stderr, _("Function not implemented.\n"));
+                       break;
+               default:
+                       fprintf(stderr, _("The calendar note can not be read\n"));
+                       break;
                }
                }
-               nmd_output(out_param);
-
-               free(out_param);
        }
        }
+       
        GSM->Terminate();
        GSM->Terminate();
-
-       free(loc_info);
-       free(f_name);
-
-/* I analised this source and this should be done. But when compile with VC6 */
-/* I have error. So, commented... MW */
-#ifndef VC6
-       free_nm_info(start);
-#endif
-
-       return(0);
+       return error;
 }
 
 }
 
-
-// used by nm_collect()
-///////////////////////////////////////////////////////////////////////////////
-char *rowScreen(char *s)
+/* Writing calendar notes. */
+int writecalendarnote(char *argv[])
 {
 {
-       char *p;
-       
-       // make Screen in one row
-       p = s;
-       while(*p)
-       {
-           if (*p == '\n')
-                       *p = ' ';
-           p++;
-       }
+       GSM_CalendarNote CalendarNote;
 
 
-       return(s);
-}
+       if (GSM_ReadVCalendarFile(argv[0], &CalendarNote, atoi(argv[1]))) {
+               fprintf(stdout, _("Failed to load vCalendar file.\n"));
+               return(-1);
+       }
 
 
-void printtime(void)
-{
+        /* Error 22=Calendar full ;-) */
+       if ((GSM->WriteCalendarNote(&CalendarNote)) == GE_NONE)
+               fprintf(stdout, _("Succesfully written!\n"));
+       else
+               fprintf(stdout, _("Failed to write calendar note!\n"));
 
 
-  struct mydate {
-    int Year;          /* The complete year specification - e.g. 1999. Y2K :-) */
-    int Month;         /* January = 1 */
-    int Day;
-    int Hour;
-    int Minute;
-    int Second;
-    int Timezone;      /* The difference between local time and GMT */
-  } Date;
-
-  struct tm *now;
-  time_t nowh;
-  nowh=time(NULL);
-  now=localtime(&nowh);
-
-  Date.Year = now->tm_year;
-  Date.Month = now->tm_mon+1;
-  Date.Day = now->tm_mday;
-  Date.Hour = now->tm_hour;
-  Date.Minute = now->tm_min;
-  Date.Second = now->tm_sec;
-
-  /* I have 100 (for 2000) Year now :-) */
-  if (Date.Year>99 && Date.Year<1900) {
-    Date.Year=Date.Year+1900;
-  }
-
-  printf("%d:%d:%d:%d:%d:%d      ",Date.Day,Date.Month,Date.Year,Date.Hour,Date.Minute,Date.Second);
+       GSM->Terminate();
 
 
+       return 0;
 }
 
 }
 
-// like netmonitor(), but print in one row, 1, 2 or 3 screen, every ~0.3 s
-///////////////////////////////////////////////////////////////////////////////
-int nm_collect(int argc, char *argv[])
+/* Calendar note deleting. */
+int deletecalendarnote(int argc, char *argv[])
 {
 {
-       int mode[MAX_NM_COLLECT];
-       char Screen[NM_MAX_SCREEN_WIDTH];
-       int i;
-
-       for (i=0;i<argc;i++) {
-           argc > i ? (mode[i] = atoi(argv[i])): (mode[i] = 0);
-       }
+       GSM_CalendarNote CalendarNote;
+       int i, first_location, last_location;
 
 
-       for (i=0;i<argc;i++) {
-           if (mode[i]==0 && strcmp(argv[i],"-d")) {
-               fprintf(stderr, "Wrong %i parameter (not number and not -d)\n",i);
-               return(-1);
-           }
-       }
-
-       signal(SIGINT, interrupted);
+       first_location = last_location = atoi(argv[0]);
+       if (argc > 1) last_location = atoi(argv[1]);
+       
+       for (i = first_location; i <= last_location; i++) {
 
 
-       fbusinit(NULL);
+               CalendarNote.Location = i;
 
 
-       // end on CTRL-C
-       while (!bshutdown) 
-       {
-               for (i=0;i<argc;i++) {
-                 if (!strcmp(argv[i],"-d")) {
-                    printtime();
-                    break;
-                 }
-               }
-               
-               for (i=0;i<argc;i++) {
-                 if (mode[i]!=0)
-                 {
-                       GSM->NetMonitor(mode[i], Screen);
-                       printf("%s::", rowScreen(Screen));
-                 }
+               if (GSM->DeleteCalendarNote(&CalendarNote) == GE_NONE) {
+                       fprintf(stdout, _("   Calendar note deleted.\n"));
+               } else {
+                       fprintf(stderr, _("The calendar note can not be deleted\n"));
                }
                }
-               
-               printf("\n\n");
 
 
-               usleep(150000);
        }
 
        GSM->Terminate();
        }
 
        GSM->Terminate();
@@ -7358,1391 +2123,967 @@ int nm_collect(int argc, char *argv[])
        return 0;
 }
 
        return 0;
 }
 
-#ifdef DEBUG
-int sniff(int argc, char *argv[])
+/* Setting the date and time. */
+int setdatetime(int argc, char *argv[])
 {
 {
-  /* base model comes from gnokiirc */
-  strcat(model,"sniff");
-  
-  if (argc>0) strcpy(Port,argv[0]);
-    
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
-
-  /* Loop here indefinitely - allows you to see messages from GSM code in
-     response to unknown messages etc. The loops ends after pressing the
-     Ctrl+C. */
-  while (!bshutdown) {
-    sleep(1);
-  }
+       struct tm *now;
+       time_t nowh;
+       GSM_DateTime Date;
 
 
-  GSM->Terminate();    
+       nowh = time(NULL);
+       now = localtime(&nowh);
 
 
-  return 0;
+       Date.Year = now->tm_year;
+       Date.Month = now->tm_mon+1;
+       Date.Day = now->tm_mday;
+       Date.Hour = now->tm_hour;
+       Date.Minute = now->tm_min;
+       Date.Second = now->tm_sec;
 
 
-}
+       if (argc > 0) Date.Year = atoi (argv[0]);
+       if (argc > 1) Date.Month = atoi (argv[1]);
+       if (argc > 2) Date.Day = atoi (argv[2]);
+       if (argc > 3) Date.Hour = atoi (argv[3]);
+       if (argc > 4) Date.Minute = atoi (argv[4]);
 
 
-int decodefile(int argc, char *argv[])
-{
- FILE *infile;
- unsigned char in_buffer[255];
- int nr_read = 0;
- int i = 0;
+       if (Date.Year < 1900) {
 
 
-  /* base model comes from gnokiirc */
-  strcat(model,"decode");
+               /* Well, this thing is copyrighted in U.S. This technique is known as
+                  Windowing and you can read something about it in LinuxWeekly News:
+                  http://lwn.net/1999/features/Windowing.phtml. This thing is beeing
+                  written in Czech republic and Poland where algorithms are not allowed
+                  to be patented. */
 
 
- /* Initialise the GSM interface. */
- fbusinit(NULL);
+               if (Date.Year > 90)
+                       Date.Year = Date.Year + 1900;
+               else
+                       Date.Year = Date.Year + 2000;
+       }
 
 
- printf ("open InPutFile: %s\n", argv[0]);
- if ( (infile = fopen( argv[0], "rb")) == NULL ) {
-   printf ("Failed to open InPutFile: %s\n", argv[0]);
-   exit (1); }
+       /* FIXME: Error checking should be here. */
+       GSM->SetDateTime(&Date);
 
 
- while ( (nr_read = fread(in_buffer, 1, 16, infile)) > 0 ) {
-  for (i=0; i < nr_read; i++)
-     Protocol->StateMachine(in_buffer[i]);
-  }
+       GSM->Terminate();
 
 
-   return 0;
+       return 0;
 }
 
 }
 
-#endif
+/* In this mode we receive the date and time from mobile phone. */
+int getdatetime(void) {
+       GSM_Data        data;
+       GSM_DateTime    date_time;
+       GSM_Error       error;
+       
+       if (GSM && GSM->GetDateTime && GSM->Terminate) {
+               error = GSM->GetDateTime(&date_time);
+               GSM->Terminate();
+       } else {
+               GSM_DataClear(&data);
+               data.DateTime = &date_time;
+               
+               error = SM_Functions(GOP_GetDateTime, &data, &State);
+       }
+       
+       switch (error) {
+       case GE_NONE:
+               fprintf(stdout, _("Date: %4d/%02d/%02d\n"), date_time.Year, date_time.Month, date_time.Day);
+               fprintf(stdout, _("Time: %02d:%02d:%02d\n"), date_time.Hour, date_time.Minute, date_time.Second);
+               break;
+       case GE_NOTIMPLEMENTED:
+               fprintf(stdout, _("Function not implemented in %s !\n"), model);
+               break;
+       default:
+               fprintf(stdout, _("Internal error\n"));
+               break;
+       }
+       
+       return error;
+}
 
 
-int getringtone(int argc, char *argv[])
+/* Setting the alarm. */
+int setalarm(char *argv[])
 {
 {
-  GSM_BinRingtone ringtone;
-  GSM_Error error;
-  GSM_Ringtone SMringtone;
-
-  int i;
-  
-  char model[64];
-
-  FILE *file;
+       GSM_DateTime Date;
 
 
-  ringtone.location=1;
-  if (argc>1) ringtone.location=atoi(argv[1]);
+       Date.Hour = atoi(argv[0]);
+       Date.Minute = atoi(argv[1]);
 
 
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
+       GSM->SetAlarm(1, &Date);
 
 
-  error=GSM->GetBinRingtone(&ringtone);
-
-  while (GSM->GetModel(model)  != GE_NONE)
-    sleep(1);
+       GSM->Terminate();
 
 
-  GSM->Terminate();
+       return 0;
+}
 
 
-  fprintf(stdout, _("Downloaded ringtone, location %i: "),ringtone.location);
-  
-  switch (error) {
-    case GE_NONE:
-      fprintf(stdout, _("get succeeded!\n"));
-      fprintf(stdout, _("Name: %s (binary format)\n"),ringtone.name);
-      break;
-    case GE_INVALIDRINGLOCATION:
-      fprintf(stdout, _("invalid location %i!\n"),ringtone.location);
-      break;
-    case GE_UNKNOWNMODEL:
-    
-      /* In 3310 we have normal "Smart Messaging" format */
-      if (GetModelFeature (FN_RINGTONES)==F_RING_SM) {
-      
-        i=7;
-       if (ringtone.frame[9]==0x4a && ringtone.frame[10]==0x3a) i=8;
-       ringtone.frame[i]=0x02;
+/* Getting the alarm. */
+int getalarm(void)
+{
+       GSM_Error       error;
+       GSM_Data        data;
+       GSM_DateTime    date_time;
        
        
-        GSM_UnPackRingtone(&SMringtone, ringtone.frame+i, ringtone.length-i);
-
-        fprintf(stdout, _("Name: %s (normal format)\n"),SMringtone.name);
-
-        GSM_SaveRingtoneFileOnConsole(argv[0], &SMringtone);
+       if (GSM && GSM->GetAlarm && GSM->Terminate) {
+               error = GSM->GetAlarm(0, &date_time);
+               GSM->Terminate();
+       } else {
+               GSM_DataClear(&data);
+               data.DateTime = &date_time;
+               
+               error = SM_Functions(GOP_GetAlarm, &data, &State);
+       }
        
        
-       return 0;
-      }
-
-      fprintf(stdout, _("mygnokii doesn't know format for this model!\n"));
-      break;
-    case GE_NOTIMPLEMENTED:
-      fprintf(stdout, _("not implemented for this model!\n"));
-      break;
-    default:
-      fprintf(stdout, _("not supported by this model!\n"));
-      break;
-  }
-  
-  if (error!=GE_NONE)
-    return(-1);
-  
-  file = fopen(argv[0], "wb");
-      
-  if (!file)
-    return(GE_CANTOPENFILE);
+       switch (error) {
+       case GE_NONE:
+               fprintf(stdout, _("Alarm: %s\n"), (date_time.AlarmEnabled==0)?"off":"on");
+               fprintf(stdout, _("Time: %02d:%02d\n"), date_time.Hour, date_time.Minute);
+               break;
+       case GE_NOTIMPLEMENTED:
+               fprintf(stdout, _("Function not implemented in %s !\n"), model);
+               break;
+       default:
+               fprintf(stdout, _("Internal error\n"));
+               break;
+       }
+       
+       return error;
+}
 
 
-  fwrite(ringtone.frame, 1, ringtone.length, file);    
-  
-  fclose(file);
-  
-  return 0;
+/* In monitor mode we don't do much, we just initialise the fbus code.
+   Note that the fbus code no longer has an internal monitor mode switch,
+   instead compile with DEBUG enabled to get all the gumpf. */
+int monitormode(void)
+{
+       float rflevel = -1, batterylevel = -1;
+//     GSM_PowerSource powersource = -1;
+       GSM_RFUnits rf_units = GRF_Arbitrary;
+       GSM_BatteryUnits batt_units = GBU_Arbitrary;
+       GSM_Statemachine *sm = &State;
+       GSM_Data data;
+
+//     GSM_NetworkInfo NetworkInfo;
+//     GSM_CBMessage CBMessage;
+
+       GSM_MemoryStatus SIMMemoryStatus   = {GMT_SM, 0, 0};
+       GSM_MemoryStatus PhoneMemoryStatus = {GMT_ME, 0, 0};
+       GSM_MemoryStatus DC_MemoryStatus   = {GMT_DC, 0, 0};
+       GSM_MemoryStatus EN_MemoryStatus   = {GMT_EN, 0, 0};
+       GSM_MemoryStatus FD_MemoryStatus   = {GMT_FD, 0, 0};
+       GSM_MemoryStatus LD_MemoryStatus   = {GMT_LD, 0, 0};
+       GSM_MemoryStatus MC_MemoryStatus   = {GMT_MC, 0, 0};
+       GSM_MemoryStatus ON_MemoryStatus   = {GMT_ON, 0, 0};
+       GSM_MemoryStatus RC_MemoryStatus   = {GMT_RC, 0, 0};
+
+//     GSM_SMSStatus SMSStatus = {0, 0};
+
+//     char Number[20];
+       
+       GSM_DataClear(&data);
 
 
-}
+       /* We do not want to monitor serial line forever - press Ctrl+C to stop the
+          monitoring mode. */
+       signal(SIGINT, interrupted);
 
 
-int binringtoneconvert(int argc, char *argv[])
-{
-  GSM_BinRingtone ringtone;
-  
-  int i,j,z;
-  bool isok;
-  int deflen=7,m,w;
-  bool pause;
+       fprintf (stderr, _("Entering monitor mode...\n"));
 
 
-  FILE *file;
-  
-//{ "c", "c#", "d", "d#", "e",  "f", "f#", "g", "g#", "a", "a#", "h" };
-  int binary_notes[12] =
-  { 0,    1,    2,   3,    4,   6,   7,    8,   9,    10,  11 ,   12};
-
-  if (GSM_ReadBinRingtoneFile(argv[0],&ringtone)!=GE_NONE) {
-    fprintf(stdout,_("Failed to read %s file!\n"),argv[0]);
-    return -1;
-  }
-
-  file = fopen(argv[1], "wb");
-      
-  if (!file)
-    return(GE_CANTOPENFILE);
-
-  i=5;
-  while (true) {
-    if (ringtone.frame[i]==0) break;
-    fprintf(file,_("%c"),ringtone.frame[i]);
-    i++;
-  }
-
-  fprintf(file,_(":d=32,o=5,b=300:"));
-    
-  i=i+5;j=0;z=0;
-  while (true) {
-    if (ringtone.frame[i]!=j) {
-      if (j!=0) {
-        isok=false;
-       if (j==64) {
-         j=255;//Pause
-         isok=true;
-       }
-       if (!isok && j>=114 && j<=125) {
-         j=14*3+binary_notes[j-114];
-         isok=true;
-       }
-       if (!isok && j>=126 && j<=137) {
-         j=14*1+binary_notes[j-126];
-         isok=true;
-       }
-       if (!isok && j>=138 && j<=149) {
-         j=14*2+binary_notes[j-138];
-         isok=true;
-       }
-       if (!isok && j>=150 && j<=161) {
-         j=14*4+binary_notes[j-150];
-         isok=true;
-       }
-       if (!isok) {
-         if (j!=10) { 
-           fprintf(stdout,_("Unknown block in binary ringtone %i %i\n"),j,z);
-         }
-       } else {
-         w=deflen;
-         for (m=0;m<6;m++) {
-           w=w*2;
-           if (w>z && (w/2)<=z) {
-             switch (m) {
-               case 1:fprintf(file,_("16"));break;
-               case 2:fprintf(file,_("8"));break;
-               case 3:fprintf(file,_("4"));break;
-               case 4:fprintf(file,_("2"));break;
-               case 5:fprintf(file,_("1"));break;
-             }
-             break;
-           }
-         }
-         if (z>w) fprintf(file,_("1"));
-         pause=false;
-          switch (GSM_GetNote(j)) {
-            case Note_C  :fprintf(file,_("c"));break;
-            case Note_Cis:fprintf(file,_("c#"));break;
-            case Note_D  :fprintf(file,_("d"));break;
-            case Note_Dis:fprintf(file,_("d#"));break;
-            case Note_E  :fprintf(file,_("e"));break;
-            case Note_F  :fprintf(file,_("f"));break;
-            case Note_Fis:fprintf(file,_("f#"));break;
-            case Note_G  :fprintf(file,_("g"));break;
-            case Note_Gis:fprintf(file,_("g#"));break;
-            case Note_A  :fprintf(file,_("a"));break;
-            case Note_Ais:fprintf(file,_("a#"));break;
-            case Note_H  :fprintf(file,_("h"));break;
-            default      :pause=true;fprintf(file,_("p"));break; //Pause ?
-          }
-         w=deflen*1.5;
-         for (m=0;m<6;m++) {
-           w=w*2;
-           if (w>z && (w/2)<=z) {
-             fprintf(file,_("."));
-             break;
-           }
-         }
-         if ((j/14)!=1 && !pause) fprintf(file,_("%i"),j/14);
-         fprintf(file,_(","));
-       }
-      }
-      j=ringtone.frame[i];
-      z=ringtone.frame[i+1];
-    } else {
-      z=z+ringtone.frame[i+1];
-    }
-    i=i+2;
-    if (i>=ringtone.length) break;
-  }
-
-  fclose(file);
-  
-  return 0;
+       //sleep(1);
+       //GSM->EnableCellBroadcast();
 
 
-}
+       /* Loop here indefinitely - allows you to see messages from GSM code in
+          response to unknown messages etc. The loops ends after pressing the
+          Ctrl+C. */
+       data.RFUnits=&rf_units;
+       data.RFLevel=&rflevel;
+       data.BatteryUnits=&batt_units;
+       data.BatteryLevel=&batterylevel;
 
 
-int renamesmsc(int argc, char *argv[])
-{
-  GSM_MessageCenter MessageCenter;
-
-  MessageCenter.No=atoi(argv[0]);
-
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
-
-  if (GSM->GetSMSCenter(&MessageCenter) == GE_NONE) {
-    fprintf(stdout,_("SMSC number %i get OK\n"),MessageCenter.No);  
-  } else {
-    GSM->Terminate();
-    fprintf(stdout,_("Error getting SMSC number %i\n"),MessageCenter.No);
-    return 0;  
-  }
-
-  strncpy(MessageCenter.Name,argv[1],10);
-
-  if (GSM->SetSMSCenter(&MessageCenter) == GE_NONE) {
-    fprintf(stdout,_("SMSC number %i set OK (renamed to \"%s\")\n"),MessageCenter.No,MessageCenter.Name);
-  } else {
-    GSM->Terminate();
-    fprintf(stdout,_("Error setting SMSC number %i\n"),MessageCenter.No);
-    return 0;  
-  }
-  
-  GSM->Terminate();
+       while (!bshutdown) {
+               if (SM_Functions(GOP_GetRFLevel,&data,sm) == GE_NONE)
+                       fprintf(stdout, _("RFLevel: %d\n"), (int)rflevel);
 
 
-  return 0;
-}
+               if (SM_Functions(GOP_GetBatteryLevel,&data,sm) == GE_NONE)
+                       fprintf(stdout, _("Battery: %d\n"), (int)batterylevel);
 
 
-/*
- * Returns number of sostituited characters.
- * ... may be useful one day ??
- */
-int semicolon_pipe_substitution( GSM_PhonebookEntry *pentry, unsigned int direction )
-       /* direction = 0 : after reading phone memory (
-        *             1 : writing phone memory
-        */
-{
-       register int i;
-       register int count=0;
-       char charfrom, charto;
+//             if (GSM->GetPowerSource(&powersource) == GE_NONE)
+//                     fprintf(stdout, _("Power Source: %s\n"), (powersource==GPS_ACDC)?_("AC/DC"):_("battery"));
 
 
-       charfrom= (direction==0) ? ';' : '|';
-       charto  = (direction==0) ? '|' : ';';
+               data.MemoryStatus=&SIMMemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+                       fprintf(stdout, _("SIM: Used %d, Free %d\n"), SIMMemoryStatus.Used, SIMMemoryStatus.Free);
 
 
-       count+=str_substch(pentry->Name, charfrom, charto );
-       count+=str_substch(pentry->Number, charfrom, charto );
+               data.MemoryStatus=&PhoneMemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+                       fprintf(stdout, _("Phone: Used %d, Free %d\n"), PhoneMemoryStatus.Used, PhoneMemoryStatus.Free);
 
 
-       for( i = 0; i < pentry->SubEntriesCount; i++ )
-       {
-               if( pentry->SubEntries[i].EntryType != GSM_Date )
-                               count+=str_substch(pentry->SubEntries[i].data.Number ,charfrom,charto);
-       }
+               data.MemoryStatus=&DC_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+                       fprintf(stdout, _("DC: Used %d, Free %d\n"), DC_MemoryStatus.Used, DC_MemoryStatus.Free);
 
 
-       return( count );
-}
+               data.MemoryStatus=&EN_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+                       fprintf(stdout, _("EN: Used %d, Free %d\n"), EN_MemoryStatus.Used, EN_MemoryStatus.Free);
 
 
-int str_substch( char *str, const char toric, const char sost )
-{
-       unsigned int ct;
-       int i_sost=0;
-        
-               for( ct = 0; ct < strlen(str); ct++ )
-                       if( str[ct] == (unsigned char) toric )
-                       { str[ct] = sost; i_sost++; }
-                
-       return( i_sost );
-}                                                                               
-
-/* Allows to set simlock state.
-   With older phone (older 51xx, 61xx) can open them, with older
-   and newer should be able to close them */
-/* DO NOT TRY, IF DON'T WANT, WHAT YOU DO !!!!!!!!!! */
-int setsimlock()
-{
-  GSM_AllSimlocks siml;
-
-  unsigned char closebuffer[20]=
-                             { 0x00, 0x01, 0x82, 0x01,
-                              0x00,                         /* which simlock */
-                              0x00, 0x00,
-                              0x00, 0x00, 0x00,             /* lock 1 info */
-                              0x00, 0x00, 0x00, 0x00, 0x00, /* lock 4 info */
-                              0x00, 0x00,                   /* lock 2 info */
-                              0x00, 0x00,                   /* lock 3 info */
-                              0x00};
-  unsigned char openbuffer[10]= { 0x00, 0x01, 0x81, 0x01,
-                                  0x00, /* lock number */
-                                 0x10, 0x10, 0x10, 0x10, 0x10 };
-  unsigned char openbuffer0[10]= {0x00, 0x01, 0x02, 0x03, 0x1f, 0x11, 0x01, 0x01, 0x10, 0x00 };
-
-  unsigned char info[120];
-  int i,j;
-  
-  /* Initialise the code for the GSM interface. */     
-  fbusinit(NULL);
-  if (strstr(GSM_Info->FBUSModels, "3310") == NULL)
-  {
-    fprintf(stderr,("Not supported\n"));
-    GSM->Terminate();
-    return -1;
-  }
-  N6110_EnableExtendedCommands(0x02);
-  /* Initial info */
-  if (GSM->SimlockInfo(&siml)!=GE_NONE) {
-    fprintf(stderr,_("Error getting simlock info\n"));GSM->Terminate();return -1;
-  }
-  /* Opening all locks (we must check, if we can open them) */
-  NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer0);
-  openbuffer[4]=1;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=2;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=4;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=8;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  if (GSM->SimlockInfo(&siml)!=GE_NONE) {
-    fprintf(stderr,_("Error getting simlock info\n"));GSM->Terminate();return -1;
-  }
-  for (i=0;i<4;i++) {
-    if (siml.simlocks[i].enabled) {
-      fprintf(stderr,_("Can not open simlock %i\n"),i+1);GSM->Terminate();return -1;
-    }
-  }
-  /* Making frame for closing simlocks */
-  strcpy(info,"00101");
-  j=0;i=7;
-  while (j!=strlen(info)) {
-    if (j+2<=strlen(info)) {
-      closebuffer[i]=((info[j] & 0x0f)<<4) | (info[j+1] & 0x0f);j=j+2;
-    } else {
-      closebuffer[i]=(info[j] & 0x0f) << 4;j++;
-    }i++;
-  }
-  strcpy(info,"0000");j=0;i=15;
-  while (j!=strlen(info)) {
-    if (j+2<=strlen(info)) {
-      closebuffer[i]=((info[j] & 0x0f)<<4) | (info[j+1] & 0x0f);j=j+2;
-    } else {
-      closebuffer[i]=(info[j] & 0x0f) << 4;j++;
-    }i++;
-  }
-  strcpy(info,"0000");j=0;i=17;
-  while (j!=strlen(info)) {
-    if (j+2<=strlen(info)) {
-      closebuffer[i]=((info[j] & 0x0f)<<4) | (info[j+1] & 0x0f);j=j+2;
-    } else {
-      closebuffer[i]=(info[j] & 0x0f) << 4;j++;
-    }i++;
-  }
-  strcpy(info,"0000000001");j=0;i=9;
-  while (j!=strlen(info)) {
-    if (j+2<=strlen(info)) {
-      if (j==0) {
-        closebuffer[i]=closebuffer[i] | (info[j] & 0x0f);j++;
-      } else {
-        closebuffer[i]=((info[j] & 0x0f)<<4) | (info[j+1] & 0x0f);j=j+2;
-      }
-    } else {
-      closebuffer[i]=(info[j] & 0x0f) << 4;j++;
-    }i++;
-  }  
-  /* Closing simlock with given values */
-  closebuffer[4]=1+2+4+8;
-  NULL_SendMessageSequence(50, &CurrentMagicError, 20, 0x40,closebuffer);  
-  /* Opening all locks */
-  NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer0);
-  openbuffer[4]=1;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=2;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=4;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  openbuffer[4]=8;NULL_SendMessageSequence(50, &CurrentMagicError, 10, 0x40,openbuffer);
-  GSM->Reset(0x03);
-  GSM->Terminate();
-  return 0;
-}
+               data.MemoryStatus=&FD_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+                       fprintf(stdout, _("FD: Used %d, Free %d\n"), FD_MemoryStatus.Used, FD_MemoryStatus.Free);
 
 
-int simlockinfo()
-{
-  GSM_AllSimlocks siml;
-  char s[7];
-
-  /* Initialise the code for the GSM interface. */     
-  fbusinit(NULL);
-
-  if (GSM->SimlockInfo(&siml)!=GE_NONE) fprintf(stderr,_("Error\n"));
-
-  fprintf(stdout,_("MCC + MNC : %s      ("),siml.simlocks[0].data);
-  if (siml.simlocks[0].enabled) fprintf(stdout,_("CLOSED"));
-                           else fprintf(stdout,_("opened"));
-  if (siml.simlocks[0].factory) fprintf(stdout,_(") (factory"));
-                           else fprintf(stdout,_(")    (user"));
-  fprintf(stdout,_(") (counter %i"),siml.simlocks[0].counter);
-
-  s[0]=siml.simlocks[0].data[0];
-  s[1]=siml.simlocks[0].data[1];
-  s[2]=siml.simlocks[0].data[2];
-  s[3]=' ';
-  s[4]=siml.simlocks[0].data[3];
-  s[5]=siml.simlocks[0].data[4];
-  s[6]=0;
-
-  if (strcmp(GSM_GetNetworkName(s),"unknown"))
-    fprintf(stdout,_(") (network \"%s\""),GSM_GetNetworkName(s));
-
-  fprintf(stdout,_(")\n"));
-
-  fprintf(stdout,_("GID1      : %s       ("),siml.simlocks[1].data);
-  if (siml.simlocks[1].enabled) fprintf(stdout,_("CLOSED"));
-                           else fprintf(stdout,_("opened"));
-  if (siml.simlocks[1].factory) fprintf(stdout,_(") (factory"));
-                           else fprintf(stdout,_(")    (user"));
-  fprintf(stdout,_(") (counter %i"),siml.simlocks[1].counter);
-  fprintf(stdout,_(")\n"));
-
-  fprintf(stdout,_("GID2      : %s       ("),siml.simlocks[2].data);
-  if (siml.simlocks[2].enabled) fprintf(stdout,_("CLOSED"));
-                           else fprintf(stdout,_("opened"));
-  if (siml.simlocks[2].factory) fprintf(stdout,_(") (factory"));
-                           else fprintf(stdout,_(")    (user"));
-  fprintf(stdout,_(") (counter %i"),siml.simlocks[2].counter);
-  fprintf(stdout,_(")\n"));
-
-  fprintf(stdout,_("MSIN      : %s ("),siml.simlocks[3].data);
-  if (siml.simlocks[3].enabled) fprintf(stdout,_("CLOSED"));
-                           else fprintf(stdout,_("opened"));
-  if (siml.simlocks[3].factory) fprintf(stdout,_(") (factory"));
-                           else fprintf(stdout,_(")    (user"));
-  fprintf(stdout,_(") (counter %i"),siml.simlocks[3].counter);
-  fprintf(stdout,_(")\n"));
-
-  GSM->Terminate();
-
-  return 0;
-}
+               data.MemoryStatus=&LD_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+                       fprintf(stdout, _("LD: Used %d, Free %d\n"), LD_MemoryStatus.Used, LD_MemoryStatus.Free);
 
 
-/* Getting EEPROM from older phones */
-/* Tested with N5110 5.07, 6150 5.22 */
-int geteeprom()
-{
-  int i=0x40;
+               data.MemoryStatus=&MC_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+                       fprintf(stdout, _("MC: Used %d, Free %d\n"), MC_MemoryStatus.Used, MC_MemoryStatus.Free);
 
 
-  unsigned char buffer[1000]={ 0x00, 0x01, 0xd4, 0x02, 0x00, 0xa0, 
-                               0x00, 0x00, /* location Lo and Hi */
-                              0x10 };     /* how many bytes */
+               data.MemoryStatus=&ON_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+                       fprintf(stdout, _("ON: Used %d, Free %d\n"), ON_MemoryStatus.Used, ON_MemoryStatus.Free);
 
 
-  strcpy(Connection,"mbus");
-  fprintf(stderr,_("Switching connection type to MBUS\n"));
+               data.MemoryStatus=&RC_MemoryStatus;
+               if (SM_Functions(GOP_GetMemoryStatus,&data,sm) == GE_NONE)
+                       fprintf(stdout, _("RC: Used %d, Free %d\n"), RC_MemoryStatus.Used, RC_MemoryStatus.Free);
 
 
-  strcpy(model,"5110");  
-  
-  /* Initialise the code for the GSM interface. */     
-  fbusinit(NULL);
-
-  if (strstr(GSM_Info->FBUSModels, "3310") == NULL)
-  {
-    fprintf(stderr,("Not supported\n"));
-    GSM->Terminate();
-    return -1;
-  }
-
-  for (i=0;i<64;i++) {
-    fprintf(stdout,_("%c"),0xff);
-  }
-  
-  while (i<300000) {
-    buffer[6] = i/256;
-    buffer[7] = i%256;
-    
-    if ((i/256)!=((i-1)/256)) fprintf(stderr,_("."));
-    
-    if (NULL_SendMessageSequence(50, &CurrentMagicError, 9, 0x40,buffer)!=GE_NONE)       break;
+//             if (GSM->GetSMSStatus(&SMSStatus) == GE_NONE)
+//                     fprintf(stdout, _("SMS Messages: UnRead %d, Number %d\n"), SMSStatus.UnRead, SMSStatus.Number);
 
 
-    i=i+0x10;
-  }
+//             if (GSM->GetIncomingCallNr(Number) == GE_NONE)
+//                     fprintf(stdout, _("Incoming call: %s\n"), Number);
 
 
-  fprintf(stderr,_("\n"));
-  
-  GSM->Terminate();
+//             if (GSM->GetNetworkInfo(&NetworkInfo) == GE_NONE)
+//                     fprintf(stdout, _("Network: %s (%s), LAC: %s, CellID: %s\n"), GSM_GetNetworkName (NetworkInfo.NetworkCode), GSM_GetCountryName(NetworkInfo.NetworkCode), NetworkInfo.LAC, NetworkInfo.CellID);
 
 
-  return 0;
-}
+//             if (GSM->ReadCellBroadcast(&CBMessage) == GE_NONE)
+//                     fprintf(stdout, _("Cell broadcast received on channel %d: %s\n"), CBMessage.Channel, CBMessage.Message);
+           
+               sleep(1);
+       }
 
 
-int getsmsfolders()
-{
-  GSM_SMSFolders folders;
-  GSM_Error error;
+       fprintf (stderr, _("Leaving monitor mode...\n"));
 
 
-  int i;
-    
-  /* Initialise the code for the GSM interface. */     
-  fbusinit(NULL);
+       //GSM->Terminate();
 
 
-  folders.number = 0;
+       return 0;
+}
 
 
-  error=GSM->GetSMSFolders(&folders);
-  
-  GSM->Terminate();
 
 
-  if (error!=GE_NONE && !folders.number) {
-    fprintf(stdout,_("Error!\n"));
-    return -1;
-  }
-  
-  for (i=0;i<folders.number;i++) {
-      fprintf(stdout,_("%i. %s\n"),i+1,folders.Folder[i].Name);
-  }
-  
-  return 0;
+#define ESC "\e"
+
+static GSM_Error PrettyOutputFn(char *Display, char *Indicators)
+{
+       if (Display)
+               printf(ESC "[10;0H Display is:\n%s\n", Display);
+       if (Indicators)
+               printf(ESC "[9;0H Indicators: %s                                                    \n", Indicators);
+       printf(ESC "[1;1H");
+       return GE_NONE;
 }
 
 }
 
-int resetphonesettings()
+#if 0
+// Uncomment it if used
+static GSM_Error OutputFn(char *Display, char *Indicators)
 {
 {
-  /* Initialise the code for the GSM interface. */     
-  fbusinit(NULL);
+       if (Display)
+               printf("New display is:\n%s\n", Display);
+       if (Indicators)
+               printf("Indicators: %s\n", Indicators);
+       return GE_NONE;
+}
+#endif
 
 
-  GSM->ResetPhoneSettings();
+void console_raw(void)
+{
+#ifndef WIN32
+       struct termios it;
 
 
-  GSM->Reset(0x03);  
-  
-  GSM->Terminate();
+       tcgetattr(fileno(stdin), &it);
+       it.c_lflag &= ~(ICANON);
+       //it.c_iflag &= ~(INPCK|ISTRIP|IXON);
+       it.c_cc[VMIN] = 1;
+       it.c_cc[VTIME] = 0;
 
 
-  return 0;
+       tcsetattr(fileno(stdin), TCSANOW, &it);
+#endif
 }
 
 }
 
-/* Checked on 3310 4.02 and doesn't work.
-   Possible reasons: SMSC has problems (possible), bug in phone firmware
-   (very possible) or here in code.
-   I quess, that the second is the most possible - 3310 treat only 3 SMS
-   as linked (the most often profile needs 4 - 2 and few bytes in 3'th
-   for screen saver, few bytes for profile name and 1 or 2 sms for ringtone).
-   When send separate ringtone (see --sendringtone with --profilestyle)
-   and screen saver (--sendlogo screensaver...), it's received OK.
-   It's for checking in higher firmware. */
-int sendprofile(int argc, char *argv[])
+int displayoutput(void)
 {
 {
-  GSM_Ringtone ringtone;
-  GSM_Bitmap bitmap;
-  GSM_MultiSMSMessage MultiSMS;
+       GSM_Data data;
+       GSM_Statemachine *sm = &State;
+       GSM_Error error;
 
 
-  int current=0,i,j;
+       data.OutputFn = PrettyOutputFn;
 
 
-  u8 MessageBuffer[140*4];
-  u16 MessageLength=0;
-  
-  char profilename[10+1];
-  
-  if (GSM_ReadRingtoneFileOnConsole(argv[2], &ringtone)!=GE_NONE) return(-1);
+       error = SM_Functions(GOP_DisplayOutput, &data, sm);
+       console_raw();
+       fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
 
 
-  ringtone.allnotesscale=false;
-  for (i=0;i<argc;i++)
-    if (!strcmp(argv[i],"--scale")) ringtone.allnotesscale=true;
+       if (error == GE_NONE) {
 
 
-  /* The fourth argument is the bitmap file. */
-  if (GSM_ReadBitmapFileOnConsole(argv[3], &bitmap)!=GE_NONE) return -1;
+               /* We do not want to see texts forever - press Ctrl+C to stop. */
+               signal(SIGINT, interrupted);    
+
+               fprintf (stderr, _("Entered display monitoring mode...\n"));
+               fprintf (stderr, ESC "c" );
+
+               /* Loop here indefinitely - allows you to read texts from phone's
+                  display. The loops ends after pressing the Ctrl+C. */
+               while (!bshutdown) {
+                       char buf[105];
+                       memset(&buf[0], 0, 102);
+                       while (read(0, buf, 100) > 0) {
+                               fprintf(stderr, "handling keys (%d).\n", strlen(buf));
+                               if (GSM->HandleString(buf) != GE_NONE)
+                                       fprintf(stdout, _("Key press simulation failed.\n"));
+                               memset(buf, 0, 102);
+                       }
+                       SM_Loop(sm, 1);
+               }
+               fprintf (stderr, "Shutting down\n");
 
 
-  GSM_ResizeBitmap(&bitmap,GSM_PictureImage);
+               fprintf (stderr, _("Leaving display monitor mode...\n"));
+               data.OutputFn = NULL;
 
 
-  strncpy(profilename,argv[1],10);
+               error = SM_Functions(GOP_DisplayOutput, &data, sm);
+               if (error != GE_NONE)
+                       fprintf (stderr, _("Error!\n"));
+       } else
+               fprintf (stderr, _("Error!\n"));
 
 
-  MessageBuffer[MessageLength++]=0x30;               //SM version. Here 3.0
+       GSM->Terminate();
+       return 0;
+}
 
 
-  MessageBuffer[MessageLength++]=SM30_PROFILENAME;   //ID for profile name
-  MessageBuffer[MessageLength++]=0x00;               //length hi  
-  MessageBuffer[MessageLength++]=strlen(profilename);//length lo
+/* Reads profile from phone and displays its' settings */
+int getprofile(int argc, char *argv[])
+{
+       int max_profiles;
+       int start, stop, i;
+       GSM_Profile profile;
+       GSM_Error error;
   
   
-  EncodeUnicode (MessageBuffer+MessageLength,profilename ,strlen(profilename));
-  MessageLength=MessageLength+2*strlen(profilename);
-
-  MessageBuffer[MessageLength++]=SM30_RINGTONE; //ID for ringtone
-  i=MessageLength;
-  MessageBuffer[MessageLength++]=0x01;          //length hi
-  MessageBuffer[MessageLength++]=0x00;          //length lo
-
-  j=SM30_MAX_RINGTONE_FRAME_LENGTH;
-  current=GSM_PackRingtone(&ringtone, MessageBuffer+MessageLength, &j);
-  MessageLength=MessageLength+j;
-
-  if (current!=ringtone.NrNotes) {
-    if (current>FB61_MAX_RINGTONE_NOTES) {
-      fprintf(stderr,_("Warning: due to phone limitation"));
-    } else {
-      fprintf(stderr,_("Warning: ringtone was too long to be saved into SMS,"));
-    }
-    fprintf(stderr, _(" only %i first notes were packed (%i cut)\n"),current,ringtone.NrNotes-current);
-  }
-    
-  MessageBuffer[i]=(j)/256;
-  MessageBuffer[i+1]=(j)%256;
+       /* Hopefully is 64 larger as FB38_MAX* / FB61_MAX* */
+       char model[64];
 
 
-  MessageBuffer[MessageLength++]=SM30_SCREENSAVER; //ID for OTA screen saver
-  MessageBuffer[MessageLength++]=0x01;             //length hi
-  MessageBuffer[MessageLength++]=0x00;             //length lo
-  MessageBuffer[MessageLength++]=0x00;
-  MessageBuffer[MessageLength++]=bitmap.width;
-  MessageBuffer[MessageLength++]=bitmap.height;          
-  MessageBuffer[MessageLength++]=0x01;   
+       profile.Number = 0;
+       error = GSM->GetProfile(&profile);
 
 
-  memcpy(MessageBuffer+MessageLength,bitmap.bitmap,bitmap.size);
-  MessageLength=MessageLength+bitmap.size;
+       if (error == GE_NONE) {
+  
+               while (GSM->GetModel(model) != GE_NONE)
+                       sleep(1);
 
 
-  GSM_MakeMultiPartSMS2(&MultiSMS,MessageBuffer,MessageLength, GSM_ProfileUDH, GSM_Coding_Default);
+               max_profiles = 7; /* This is correct for 6110 (at least my). How do we get
+                                    the number of profiles? */
 
 
-  optind = 4;
+               /*For N5110*/
+               /*FIX ME: It should be set to 3 for N5130 and 3210 too*/
+               if (!strcmp(model, "NSE-1"))
+                       max_profiles = 3;
 
 
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
+               if (argc > 0) {
+                       profile.Number = atoi(argv[0]) - 1;
+                       start = profile.Number;
+                       stop = start + 1;
 
 
-  for (i=0;i<MultiSMS.number;i++)
-    strcpy(MultiSMS.SMS[i].Destination,argv[0]);
+                       if (profile.Number < 0) {
+                               fprintf(stderr, _("Profile number must be value from 1 to %d!\n"), max_profiles);
+                               GSM->Terminate();
+                               return -1;
+                       }
 
 
-  return GSM_SaveMultiPartSMSOnConsole(&MultiSMS, optind,argc,argv,false,false,false,false);
-}
+                       if (profile.Number >= max_profiles) {
+                               fprintf(stderr, _("This phone supports only %d profiles!\n"), max_profiles);
+                               GSM->Terminate();
+                               return -1;
+                       }
+               } else {
+                       start = 0;
+                       stop = max_profiles;
+               }
 
 
-int showbitmap(int argc, char *argv[])
-{
-  GSM_Bitmap bitmap;
+               i = start;
+               while (i < stop) {
+                       profile.Number = i;
 
 
-  if (GSM_ReadBitmapFileOnConsole(argv[0], &bitmap)!=GE_NONE) return(-1);
+                       if (profile.Number != 0)
+                               GSM->GetProfile(&profile);
 
 
-  GSM_PrintBitmap(&bitmap);
+                       fprintf(stdout, "%d. \"%s\"\n", profile.Number + 1, profile.Name);
+                       if (profile.DefaultName == -1) fprintf(stdout, _(" (name defined)\n"));
 
 
-  return 0;
-}
+                       fprintf(stdout, _("Incoming call alert: %s\n"), GetProfileCallAlertString(profile.CallAlert));
 
 
-int getwapsettings(int argc, char *argv[])
-{
-  GSM_WAPSettings settings;
-  GSM_Error error;
+                       /* For different phones different ringtones names */
 
 
-  settings.location=atoi(argv[0]);
-  
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
+                       if (!strcmp(model, "NSE-3"))
+                               fprintf(stdout, _("Ringing tone: %s (%d)\n"), RingingTones[profile.Ringtone], profile.Ringtone);
+                       else
+                               fprintf(stdout, _("Ringtone number: %d\n"), profile.Ringtone);
 
 
-  error=GSM->GetWAPSettings(&settings);
-  
-  switch (error) {
-    case GE_NONE:
-      fprintf(stdout,_("%s."),argv[0]);
-      if (!(strcmp(settings.title,""))) fprintf(stdout,_("Set %s\n"),argv[0]);
-                                   else fprintf(stdout,_("%s\n"),settings.title);
-      fprintf(stdout,_("Homepage: %s\n"),settings.homepage);
-      if (settings.iscontinuous) fprintf(stdout,_("Connection type: continuous\n"));
-                            else fprintf(stdout,_("Connection type: temporary\n"));
-      if (settings.issecurity) fprintf(stdout,_("Connection security: on\n"));
-                          else fprintf(stdout,_("Connection security: off\n"));
-      switch (settings.bearer) {
-        case WAPSETTINGS_BEARER_SMS:
-          fprintf(stdout,_("Bearer: SMS\n"));
-          fprintf(stdout,_("Server number: %s\n"),settings.server);
-          fprintf(stdout,_("Service number: %s\n"),settings.service);
-         break;
-        case WAPSETTINGS_BEARER_DATA:
-          fprintf(stdout,_("Bearer: Data (CSD)\n"));
-         fprintf(stdout,_("Dial-up number: %s\n"),settings.dialup);
-          fprintf(stdout,_("IP address: %s\n"),settings.ipaddress);
-          if (settings.isnormalauthentication) fprintf(stdout,_("Authentication type: normal\n"));
-                                          else fprintf(stdout,_("Authentication type: secure\n"));  
-          if (settings.isISDNcall) fprintf(stdout,_("Data call type: ISDN\n"));
-                              else fprintf(stdout,_("Data call type: analogue\n"));  
-          if (settings.isspeed14400) fprintf(stdout,_("Data call speed: 14400\n"));
-                                else fprintf(stdout,_("Data call speed: 9600\n"));  
-          fprintf(stdout,_("User name: %s\n"),settings.user);
-          fprintf(stdout,_("Password: %s\n"),settings.password);
-         break;
-        case WAPSETTINGS_BEARER_USSD:
-          fprintf(stdout,_("Bearer: USSD\n"));
-         fprintf(stdout,_("Service code: %s\n"),settings.code);
-         if (settings.isIP) fprintf(stdout,_("Address type: IP address\nIPaddress: %s\n"),settings.service);
-                       else fprintf(stdout,_("Address type: service number\nService number: %s\n"),settings.service);
-         break;
-      }
-      break;
-    default:
-      fprintf(stderr,_("%s\n"),print_error(error));
-  }
-
-  GSM->Terminate();    
-
-  return 0;
+                       fprintf(stdout, _("Ringing volume: %s\n"), GetProfileVolumeString(profile.Volume));
 
 
-}
+                       fprintf(stdout, _("Message alert tone: %s\n"), GetProfileMessageToneString(profile.MessageTone));
 
 
-/* Not full done now */
-int savewapsettings(int argc, char *argv[])
-{
-  GSM_WAPSettings settings;
-  GSM_MultiSMSMessage MultiSMS;
-  GSM_Error error;
-  int w;
+                       fprintf(stdout, _("Keypad tones: %s\n"), GetProfileKeypadToneString(profile.KeypadTone));
 
 
-  settings.location=atoi(argv[0]);
-  
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
+                       fprintf(stdout, _("Warning and game tones: %s\n"), GetProfileWarningToneString(profile.WarningTone));
 
 
-  error=GSM->GetWAPSettings(&settings);
-//  strcpy(settings.homepage,"http://OtherSites/");
-//  strcpy(settings.title,"Orange");
+                       /* FIXME: Light settings is only used for Car */
+                       if (profile.Number == (max_profiles - 2)) fprintf(stdout, _("Lights: %s\n"), profile.Lights ? _("On") : _("Automatic"));
 
 
-  error=GE_NONE;
-  
-  switch (error) {
-    case GE_NONE:
-      /* Put settings into SMS structure */
-      GSM_SaveWAPSettingsToSMS(&MultiSMS,&settings);
+                       fprintf(stdout, _("Vibration: %s\n"), GetProfileVibrationString(profile.Vibration));
 
 
-      for (w=0;w<MultiSMS.number;w++)
-        strcpy(MultiSMS.SMS[w].Destination,"WAPSettings");
+                       /* FIXME: it will be nice to add here reading caller group name. */
+                       if (max_profiles != 3) fprintf(stdout, _("Caller groups: 0x%02x\n"), profile.CallerGroups);
 
 
-      GSM_SaveMultiPartSMSOnConsole(&MultiSMS,1,argc,argv,false,false,false,false);
-      return 0;
+                       /* FIXME: Automatic answer is only used for Car and Headset. */
+                       if (profile.Number >= (max_profiles - 2)) fprintf(stdout, _("Automatic answer: %s\n"), profile.AutomaticAnswer ? _("On") : _("Off"));
 
 
-      break;
-    default:
-      fprintf(stderr,_("%s\n"),print_error(error));
-  }
+                       fprintf(stdout, "\n");
 
 
-  GSM->Terminate();    
+                       i++;
+               }
+       } else {
+               if (error == GE_NOTIMPLEMENTED) {
+                       fprintf(stderr, _("Function not implemented in %s model!\n"), model);
+                       GSM->Terminate();
+                       return -1;
+               } else {
+                       fprintf(stderr, _("Unspecified error\n"));
+                       GSM->Terminate();
+                       return -1;
+               }
+       }
 
 
-  return 0;
+       GSM->Terminate();
+       return 0;
 }
 
 }
 
-int sendwapsettings(int argc, char *argv[])
+/* Get requested range of memory storage entries and output to stdout in
+   easy-to-parse format */
+int getmemory(int argc, char *argv[])
 {
 {
-  GSM_WAPSettings settings;
-  GSM_MultiSMSMessage MultiSMS;
-  GSM_Error error;
-  int w;
+       GSM_PhonebookEntry entry;
+       int count;
+       GSM_Error error;
+       char *memory_type_string;
+       int start_entry;
+       int end_entry;
+       GSM_Statemachine *sm = &State;
+       
+       /* Handle command line args that set type, start and end locations. */
+       memory_type_string = argv[0];
+       entry.MemoryType = StrToMemoryType(memory_type_string);
+       if (entry.MemoryType == GMT_XX) {
+               fprintf(stderr, _("Unknown memory type %s (use ME, SM, ...)!\n"), argv[0]);
+               return (-1);
+       }
 
 
-  settings.location=atoi(argv[0]);
-  
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
+       start_entry = atoi (argv[1]);
+       if (argc > 2) end_entry = atoi (argv[2]);
+       else end_entry = start_entry;
 
 
-  error=GSM->GetWAPSettings(&settings);
-//  strcpy(settings.homepage,"http://OtherSites/");
-//  strcpy(settings.title,"Orange");
+       /* Now retrieve the requested entries. */
+       for (count = start_entry; count <= end_entry; count ++) {
 
 
-  error=GE_NONE;
-  
-  switch (error) {
-    case GE_NONE:
-      /* Put settings into SMS structure */
-      GSM_SaveWAPSettingsToSMS(&MultiSMS,&settings);
+               entry.Location = count;
+
+               data.PhonebookEntry=&entry;
+               error=SM_Functions(GOP_ReadPhonebook,&data,sm);
+
+               if (error == GE_NONE) {
+                       fprintf(stdout, "%s;%s;%s;%d;%d\n", entry.Name, entry.Number, memory_type_string, entry.Location, entry.Group);
+                       if (entry.MemoryType == GMT_MC || entry.MemoryType == GMT_DC || entry.MemoryType == GMT_RC)
+                               fprintf(stdout, "%02u.%02u.%04u %02u:%02u:%02u\n", entry.Date.Day, entry.Date.Month, entry.Date.Year, entry.Date.Hour, entry.Date.Minute, entry.Date.Second);
+               }  
+               else {
+                       if (error == GE_NOTIMPLEMENTED) {
+                               fprintf(stderr, _("Function not implemented in %s model!\n"), model);
+                               return -1;
+                       }
+                       else if (error == GE_INVALIDMEMORYTYPE) {
+                               fprintf(stderr, _("Memory type %s not supported!\n"), memory_type_string);
+                               return -1;
+                       }
 
 
-      for (w=0;w<MultiSMS.number;w++)
-        strcpy(MultiSMS.SMS[w].Destination,argv[1]);
+                       fprintf(stdout, _("%s|%d|Bad location or other error!(%d)\n"), memory_type_string, count, error);
+               }
+       }
+       return 0;
+}
 
 
-      GSM_SendMultiPartSMSOnConsole(&MultiSMS, 2,argc,argv,false,false,false);
+/* Read data from stdin, parse and write to phone.  The parsing is relatively
+   crude and doesn't allow for much variation from the stipulated format. */
+/* FIXME: I guess there's *very* similar code in xgnokii */
+int writephonebook(int argc, char *args[])
+{
+       GSM_PhonebookEntry entry;
+       GSM_Error error;
+       char *memory_type_string;
+       int line_count=0;
+       int subentry;
 
 
-      return 0;
+       char *Line, OLine[100], BackLine[100];
+       char *ptr;
 
 
-      break;
-    default:
-      fprintf(stderr,_("%s\n"),print_error(error));
-  }
+       /* Check argument */
+       if (argc && (strcmp("-i", args[0])))
+               usage();
 
 
-  GSM->Terminate();    
+       Line = OLine;
 
 
-  return 0;
-}
+       /* Go through data from stdin. */
+       while (GetLine(stdin, Line, 99)) {
+               strcpy(BackLine, Line);
+               line_count++;
 
 
-int getwapbookmark(int argc, char *argv[])
-{
-  GSM_WAPBookmark bookmark;
-  GSM_Error error;
+               ptr = strtok(Line, ";");
+               if (ptr) strcpy(entry.Name, ptr);
+               else entry.Name[0] = 0;
 
 
-  bookmark.location=atoi(argv[0]);
-  
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
+               ptr = strtok(NULL, ";");
+               if (ptr) strcpy(entry.Number, ptr);
+               else entry.Number[0] = 0;
 
 
-  error=GSM->GetWAPBookmark(&bookmark);
-  
-  switch (error) {
-    case GE_NONE:
-      if (bookmark.address[0]==0) {
-        fprintf(stdout,_("Empty bookmark location\n"));
-      } else {
-        fprintf(stdout,_("Address: \"%s\"\n"),bookmark.address);
-        if (bookmark.title[0]==0)
-          fprintf(stdout,_("Title: \"%s\"\n"),bookmark.address);
-        else
-          fprintf(stdout,_("Title: \"%s\"\n"),bookmark.title);
-      }
-      break;
-    default:
-      fprintf(stderr,_("%s\n"),print_error(error));
-  }
-
-  GSM->Terminate();    
-
-  return 0;
+               ptr = strtok(NULL, ";");
 
 
-}
+               if (!ptr) {
+                       fprintf(stderr, _("Format problem on line %d [%s]\n"), line_count, BackLine);
+                       Line = OLine;
+                       continue;
+               }
 
 
-int setwapbookmark(int argc, char *argv[])
-{
-  GSM_WAPBookmark bookmark;
-  GSM_Error error;
+               if (!strncmp(ptr,"ME", 2)) {
+                       memory_type_string = "int";
+                       entry.MemoryType = GMT_ME;
+               } else {
+                       if (!strncmp(ptr,"SM", 2)) {
+                               memory_type_string = "sim";
+                               entry.MemoryType = GMT_SM;
+                       } else {
+                               fprintf(stderr, _("Format problem on line %d [%s]\n"), line_count, BackLine);
+                               break;
+                       }
+               }
 
 
-  if (argc == 3)       /* if location given, use it */
-    bookmark.location=atoi(argv[2]);
-  else                 /* else use first empty location */
-    bookmark.location=0xffff;
+               ptr = strtok(NULL, ";");
+               if (ptr) entry.Location = atoi(ptr);
+               else entry.Location = 0;
 
 
-  strcpy(bookmark.title, argv[0]);
-  strcpy(bookmark.address, argv[1]);
+               ptr = strtok(NULL, ";");
+               if (ptr) entry.Group = atoi(ptr);
+               else entry.Group = 0;
 
 
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
+               if (!ptr) {
+                       fprintf(stderr, _("Format problem on line %d [%s]\n"), line_count, BackLine);
+                       continue;
+               }
 
 
-  error=GSM->SetWAPBookmark(&bookmark);
-  
-  switch (error) {
-    case GE_NONE:
-      fprintf(stdout,_("No errors\n"));
-      break;
-    default:
-      fprintf(stderr,_("%s\n"),print_error(error));
-  }
+               for (subentry = 0; ; subentry++) {
+                       ptr = strtok(NULL, ";");
 
 
-  GSM->Terminate();    
+                       if (ptr &&  *ptr != 0)
+                               entry.SubEntries[subentry].EntryType = atoi(ptr);
+                       else
+                               break;
 
 
-  return 0;
+                       ptr = strtok(NULL, ";");
+                       if (ptr)
+                               entry.SubEntries[subentry].NumberType=atoi(ptr);
 
 
-}
+                       /* Phone Numbers need to have a number type. */
+                       if (!ptr && entry.SubEntries[subentry].EntryType == GSM_Number) {
+                               fprintf(stderr, _("Missing phone number type on line %d"
+                                                 " entry %d [%s]\n"), line_count, subentry, BackLine);
+                               subentry--;
+                               break;
+                       }
 
 
-int savewapbookmark(int argc, char *argv[])
-{
-  GSM_WAPBookmark bookmark;
-  GSM_MultiSMSMessage MultiSMS;
-  GSM_Error error;
-  int w;
+                       ptr = strtok(NULL, ";");
+                       if (ptr)
+                               entry.SubEntries[subentry].BlockNumber=atoi(ptr);
 
 
-  bookmark.location=atoi(argv[0]);
-  
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
+                       ptr = strtok(NULL, ";");
 
 
-  error=GSM->GetWAPBookmark(&bookmark);
+                       /* 0x13 Date Type; it is only for Dailed Numbers, etc.
+                          we don't store to this memories so it's an error to use it. */
+                       if (!ptr || entry.SubEntries[subentry].EntryType == GSM_Date) {
+                               fprintf(stdout, _("There is no phone number on line %d entry %d [%s]\n"),
+                                       line_count, subentry, BackLine);
+                               subentry--;
+                               break;
+                       } else
+                               strcpy(entry.SubEntries[subentry].data.Number, ptr);
+               }
 
 
-//  strcpy(bookmark.title,"tytulagagagagagagagagagagagagagagagagagagagagagend");
-//  strcpy(bookmark.address,"http://jajajajajajajajajajajajagagagagagagagagagagagagagagagagagagagagagpapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapapap¥papapapapapapapapagagagagagagagagagagagagagagagagagagagagagagagagagadadadadadadadajdjdjdjdjdjdjdjdjdjdjdjdjdjdjdjdstp");  
-  error=GE_NONE;
+               entry.SubEntriesCount = subentry;
 
 
-  switch (error) {
-    case GE_NONE:
+               /* This is to send other exports (like from 6110) to 7110 */
+               if (!entry.SubEntriesCount) {
+                       entry.SubEntriesCount = 1;
+                       entry.SubEntries[subentry].EntryType   = GSM_Number;
+                       entry.SubEntries[subentry].NumberType  = GSM_General;
+                       entry.SubEntries[subentry].BlockNumber = 2;
+                       strcpy(entry.SubEntries[subentry].data.Number, entry.Number);
+               }
 
 
-      if (bookmark.address[0]==0) {
-        fprintf(stdout,_("Empty bookmark location\n"));
-        GSM->Terminate();   
-        return 1;
-      }
+               Line = OLine;
 
 
-      /* Put bookmark into SMS structure */
-      GSM_SaveWAPBookmarkToSMS(&MultiSMS,&bookmark);
+               if (argc) {
+                       GSM_PhonebookEntry aux;
 
 
-      for (w=0;w<MultiSMS.number;w++)
-        strcpy(MultiSMS.SMS[w].Destination,"WAPBookmark");
+                       aux.Location = entry.Location;
+                       error = GSM->GetMemoryLocation(&aux);
+                       
+                       if (error == GE_NONE) {
+                               if (!aux.Empty) {
+                                       int confirm = -1;
+                                       char ans[8];
+
+                                       fprintf(stdout, _("Location busy. "));
+                                       while (confirm < 0) {
+                                               fprintf(stdout, _("Overwrite? (yes/no) "));
+                                               GetLine(stdin, ans, 7);
+                                               if (!strcmp(ans, _("yes"))) confirm = 1;
+                                               else if (!strcmp(ans, _("no"))) confirm = 0;
+                                       }
+                                       if (!confirm) continue;
+                               }
+                       } else {
+                               fprintf(stderr, _("Unknown error (%d)\n"), error);
+                               GSM->Terminate();
+                               return 0;
+                       }
+               }
 
 
-      GSM_SaveMultiPartSMSOnConsole(&MultiSMS, 1,argc,argv,false,false,false,false);
-      return 0;
+               /* Do write and report success/failure. */
+               error = GSM->WritePhonebookLocation(&entry);
 
 
-      break;
-    default:
-      fprintf(stderr,_("%s\n"),print_error(error));
-  }
+               if (error == GE_NONE)
+                       fprintf (stdout, _("Write Succeeded: memory type: %s, loc: %d, name: %s, number: %s\n"), memory_type_string, entry.Location, entry.Name, entry.Number);
+               else
+                       fprintf (stdout, _("Write FAILED(%d): memory type: %s, loc: %d, name: %s, number: %s\n"), error, memory_type_string, entry.Location, entry.Name, entry.Number);
 
 
-  GSM->Terminate();    
+       }
 
 
-  return 0;
+       GSM->Terminate();
+       return 0;
+}
 
 
+/* Getting speed dials. */
+int getspeeddial(char *Number)
+{
+       GSM_SpeedDial   SpeedDial;
+       GSM_Data        data;
+       GSM_Error       error;
+       
+       SpeedDial.Number = atoi(Number);
+       
+       if (GSM && GSM->GetSpeedDial && GSM->Terminate) {
+               error = GSM->GetSpeedDial(&SpeedDial);
+               GSM->Terminate();
+       } else {
+               GSM_DataClear(&data);
+               data.SpeedDial = &SpeedDial;
+               
+               error = SM_Functions(GOP_GetSpeedDial, &data, &State);
+       }
+       
+       switch (error) {
+       case GE_NONE:
+               fprintf(stdout, _("SpeedDial nr. %d: %d:%d\n"), SpeedDial.Number, SpeedDial.MemoryType, SpeedDial.Location);
+               break;
+       case GE_NOTIMPLEMENTED:
+               fprintf(stdout, _("Function not implemented in %s !\n"), model);
+               break;
+       default:
+               fprintf(stdout, _("Internal error\n"));
+               break;
+       }
+       
+       return error;
 }
 
 }
 
-int sendwapbookmark(int argc, char *argv[])
+/* Setting speed dials. */
+int setspeeddial(char *argv[])
 {
 {
-  GSM_WAPBookmark bookmark;
-  GSM_MultiSMSMessage MultiSMS;
-  GSM_Error error;
-  int w;
+       GSM_SpeedDial entry;
 
 
-  bookmark.location=atoi(argv[0]);
-  
-  /* Initialise the GSM interface. */
-  fbusinit(NULL);
+       char *memory_type_string;
 
 
-  error=GSM->GetWAPBookmark(&bookmark);
-  
-  switch (error) {
-    case GE_NONE:
+       /* Handle command line args that set type, start and end locations. */
 
 
-      if (bookmark.address[0]==0) {
-        fprintf(stdout,_("Empty bookmark location\n"));
-        GSM->Terminate();   
-        return 1;
-      }
+       if (strcmp(argv[1], "ME") == 0) {
+               entry.MemoryType = 0x02;
+               memory_type_string = "ME";
+       } else if (strcmp(argv[1], "SM") == 0) {
+               entry.MemoryType = 0x03;
+               memory_type_string = "SM";
+       } else {
+               fprintf(stderr, _("Unknown memory type %s!\n"), argv[1]);
+               return -1;
+       }
 
 
-      /* Put bookmark into SMS structure */
-      GSM_SaveWAPBookmarkToSMS(&MultiSMS,&bookmark);
+       entry.Number = atoi(argv[0]);
+       entry.Location = atoi(argv[2]);
 
 
-      for (w=0;w<MultiSMS.number;w++)
-        strcpy(MultiSMS.SMS[w].Destination,argv[1]);
+       if (GSM->SetSpeedDial(&entry) == GE_NONE) {
+               fprintf(stdout, _("Succesfully written!\n"));
+       }
 
 
-      GSM_SendMultiPartSMSOnConsole(&MultiSMS, 2,argc,argv,false,false,false);
-      return 0;
+       GSM->Terminate();
+       return 0;
+}
 
 
-      break;
-    default:
-      fprintf(stderr,_("%s\n"),print_error(error));
-  }
+/* Getting the status of the display. */
+int getdisplaystatus(void)
+{ 
+       int Status;
 
 
-  GSM->Terminate();    
+       GSM->GetDisplayStatus(&Status);
 
 
-  return 0;
+       fprintf(stdout, _("Call in progress: %s\n"), Status & (1<<DS_Call_In_Progress)?_("on"):_("off"));
+       fprintf(stdout, _("Unknown: %s\n"),          Status & (1<<DS_Unknown)?_("on"):_("off"));
+       fprintf(stdout, _("Unread SMS: %s\n"),       Status & (1<<DS_Unread_SMS)?_("on"):_("off"));
+       fprintf(stdout, _("Voice call: %s\n"),       Status & (1<<DS_Voice_Call)?_("on"):_("off"));
+       fprintf(stdout, _("Fax call active: %s\n"),  Status & (1<<DS_Fax_Call)?_("on"):_("off"));
+       fprintf(stdout, _("Data call active: %s\n"), Status & (1<<DS_Data_Call)?_("on"):_("off"));
+       fprintf(stdout, _("Keyboard lock: %s\n"),    Status & (1<<DS_Keyboard_Lock)?_("on"):_("off"));
+       fprintf(stdout, _("SMS storage full: %s\n"), Status & (1<<DS_SMS_Storage_Full)?_("on"):_("off"));
 
 
+       GSM->Terminate();
+       return 0;
 }
 
 }
 
-int savecalendarnote(int argc, char *argv[])
+int netmonitor(char *Mode)
 {
 {
-  GSM_MultiSMSMessage MultiSMS;
-  int w;
-  GSM_CalendarNote CalendarNote;
-  int number;
+       unsigned char mode = atoi(Mode);
+       char Screen[50];
 
 
-  number=atoi(argv[1]);
-  
-  if (number<1) {
-    fprintf(stdout, _("Number of calendar note must be 1 or higher\n"));
-    return -1;
-  }
-  
-  switch ( GSM_ReadVCalendarFile(argv[0], &CalendarNote, &number) ) {
-    case GE_NONE:
-      break;
-    case GE_CANTOPENFILE:
-      fprintf(stdout, _("Failed to open vCalendar file \"%s\"\n"),argv[0]);
-      return -1;
-    case GE_TOOSHORT:
-      fprintf(stdout, _("Number of given calendar note is too high (max=%i)\n"),number);
-      return(-1);
-    default:
-      fprintf(stdout, _("Failed to parse vCalendar file \"%s\"\n"),argv[0]);
-      return -1;    
-  }
-
-  fbusinit(NULL);
-
-  /* Put note into SMS structure */
-  GSM_SaveCalendarNoteToSMS(&MultiSMS,&CalendarNote);
-
-  for (w=0;w<MultiSMS.number;w++)
-    strcpy(MultiSMS.SMS[w].Destination,"Calendar");
-
-  GSM_SaveMultiPartSMSOnConsole(&MultiSMS, 2,argc,argv,false,false,false,false);
-
-  return 0;
-}
+       if (!strcmp(Mode, "reset"))
+               mode = 0xf0;
+       else if (!strcmp(Mode, "off"))
+               mode = 0xf1;
+       else if (!strcmp(Mode, "field"))
+               mode = 0xf2;
+       else if (!strcmp(Mode, "devel"))
+               mode = 0xf3;
+       else if (!strcmp(Mode, "next"))
+               mode = 0x00;
 
 
-int sendcalendarnote(int argc, char *argv[])
-{
-  GSM_MultiSMSMessage MultiSMS;
-  int w;
-  GSM_CalendarNote CalendarNote;
-  int number;
+       memset(&Screen, 0, 50);
+       GSM->NetMonitor(mode, Screen);
 
 
-  number=atoi(argv[2]);
-  
-  if (number<1) {
-    fprintf(stdout, _("Number of calendar note must be 1 or higher\n"));
-    return -1;
-  }
-  
-  switch ( GSM_ReadVCalendarFile(argv[1], &CalendarNote, &number) ) {
-    case GE_NONE:
-      break;
-    case GE_CANTOPENFILE:
-      fprintf(stdout, _("Failed to open vCalendar file \"%s\"\n"),argv[1]);
-      return -1;
-    case GE_TOOSHORT:
-      fprintf(stdout, _("Number of given calendar note is too high (max=%i)\n"),number);
-      return(-1);
-    default:
-      fprintf(stdout, _("Failed to parse vCalendar file \"%s\"\n"),argv[1]);
-      return -1;    
-  }
-
-  fbusinit(NULL);
-
-  /* Put note into SMS structure */
-  GSM_SaveCalendarNoteToSMS(&MultiSMS,&CalendarNote);
-
-  for (w=0;w<MultiSMS.number;w++)
-    strcpy(MultiSMS.SMS[w].Destination,argv[0]);
-
-  GSM_SendMultiPartSMSOnConsole(&MultiSMS, 3,argc,argv,false,false,false);
-
-  return 0;
-}
+       if (Screen)
+               fprintf(stdout, "%s\n", Screen);
 
 
-/* Example function for continuous receiving SMS */
-/* When phone receives SMS, it's read by mygnokii, ID number is created
-   and SMS is saved to file. After it it's deleted
-   Checking many errors is also done */   
-int receivesms(int argc, char *argv[])
-{
-  char Dir[500];
-
-  GSM_SMSStatus SMSStatus = {0, 0};
-  GSM_SMSMessage SMS;
-  int read, location, number;
-  unsigned char name[50],filename[400];
-  char nowdate[12]="", nowtime[12]="";
-  FILE *file;
-  FILE *logfile;
-  struct CFG_Header *cfg_info;
-
-  /* We do not want to monitor serial line forever - press Ctrl+C to stop the
-     monitoring mode. */
-
-  signal(SIGINT, interrupted);
-
-  fprintf (stderr, _("Entering monitor mode (press CTRL+C to break)...\n"));
-
-  cfg_info=CFG_FindGnokiirc();
-
-  strcpy(Dir,"");
-  if (cfg_info!=NULL) {        
-    if (CFG_Get(cfg_info, "receivesms", "path")) {
-      strcpy(Dir,CFG_Get(cfg_info, "receivesms", "path"));
-    }
-  }
-
-  fprintf(stderr,_("Path for sms files is \"%s\"\n"),Dir);
-
-  fprintf (stderr, _("Initialising GSM interface..."));
-
-  /* Initialise the code for the GSM interface. */     
-  fbusinit(NULL);
-
-  fprintf (stderr, _("done\n"));
-
-  sleep(1);
-
-  /* Loop here indefinitely - allows you to see messages from GSM code in
-     response to unknown messages etc. The loops ends after pressing the
-     Ctrl+C. */
-  while (!bshutdown) {
-    if (GSM->GetSMSStatus(&SMSStatus) == GE_NONE) {
-      if (SMSStatus.Number!=0) {
-
-        GetMachineDateTime(nowdate, nowtime );
-        logfile = fopen("log", "a");
-        if (logfile) {
-          fprintf(logfile, _("%s %s SMS Messages: UnRead %d, Number %d\n"),
-             nowdate, nowtime, SMSStatus.UnRead, SMSStatus.Number);
-          fclose(logfile);
-        }
-
-        read=0;
-        location=1;
-
-        while (!bshutdown) {
-
-          SMS.Location=location;
-          if (GSM->GetSMSMessage(&SMS)==GE_NONE) {
-            if (SMS.folder==0 || SMS.folder==0x08) { //GST_7110_INBOX
-
-              GetMachineDateTime(nowdate, nowtime );
-              logfile = fopen("log", "a");
-              if (logfile) {
-                fprintf(logfile,_("%s %s SMS on location %i\n"),
-                  nowdate,nowtime,SMS.MessageNumber);
-                fclose(logfile);
-              }
-
-              number=             16*(SMS.MessageText[2] >> 4)+      (SMS.MessageText[2] & 0x0f);
-              number=number+  256*16*(SMS.MessageText[1] >> 4)+  256*(SMS.MessageText[1] & 0x0f);
-              number=number+65536*16*(SMS.MessageText[0] >> 4)+65536*(SMS.MessageText[0] & 0x0f);
-
-              sprintf( name, "%07i_%02d%02d%02d_%02d%02d%02d.sms", number,
-                 SMS.Time.Year, SMS.Time.Month, SMS.Time.Day,
-                 SMS.Time.Hour, SMS.Time.Minute, SMS.Time.Second);
-
-              strcpy(filename,Dir);
-              strcat(filename,name);
-
-              logfile = fopen("log", "a");
-              if (logfile) {
-                fprintf(logfile,_("%s %s Name is \"%s\"\n"),nowdate,nowtime,filename);
-                fclose(logfile);
-              }
-
-              file = fopen(filename, "rb");
-              if (!file) {
-                file = fopen(filename, "wb");
-                if (!file) {
-                  GetMachineDateTime(nowdate, nowtime );
-                  fprintf(stderr,_("%s %s ERROR: opening file \"%s\" failed !\n"),nowdate,nowtime,filename);
-                  logfile = fopen("log", "a");
-                  if (logfile) {
-                    fprintf(logfile,_("%s %s ERROR: opening file \"%s\" failed !\n"),nowdate,nowtime,filename);
-                    fclose(logfile);
-                  }
-                } else {
-                  fwrite(SMS.MessageText,1,SMS.Length,file);
-                  fclose(file);
-                }
-              } else {
-                fclose(file);
-  
-                GetMachineDateTime(nowdate, nowtime );
-                fprintf(stderr,_("%s %s ERROR: file \"%s\" already exist !\n"),nowdate,nowtime,filename);
-                logfile = fopen("log", "a");
-                if (logfile) { 
-                  fprintf(logfile,_("%s %s ERROR: file \"%s\" already exist !\n"),nowdate,nowtime,filename);
-                  fclose(logfile);
-                }
-              }
-  
-              SMS.Location=SMS.MessageNumber;
-              if (GSM->DeleteSMSMessage(&SMS)!=GE_NONE) {
-                GetMachineDateTime(nowdate, nowtime );
-                fprintf(stderr,_("%s %s ERROR: Deleting SMS location %i failed !\n"),nowdate,nowtime,SMS.MessageNumber);
-                logfile = fopen("log", "a");
-                if (logfile) {
-                  fprintf(logfile,_("%s %s ERROR: Deleting SMS location %i failed !\n"),nowdate,nowtime,SMS.MessageNumber);
-                  fclose(logfile);
-                }
-              }
-            }
-            read++;
-          }
-          location++;
-          if (read==SMSStatus.Number) break;
-        }
-      }
-    } else {
-      GetMachineDateTime(nowdate, nowtime );
-      fprintf(stderr,_("%s %s ERROR: Can't get SMS status !\n"),nowdate,nowtime);
-      logfile = fopen("log", "a");
-      if (logfile) {
-        fprintf(logfile,_("%s %s ERROR: Can't get SMS status !\n"),nowdate,nowtime);
-        fclose(logfile);
-      }
-    }
-
-    sleep(1);
-  }
-
-  fprintf (stderr, _("Leaving monitor mode...\n"));
-
-  GSM->Terminate();
-  
-  return 0;
+       GSM->Terminate();
+       return 0;
 }
 
 }
 
-int divert(int argc, char *argv[])
+int identify(void)
 {
 {
-       GSM_CallDivert cd;
-       GSM_Error error;
-
-       memset(&cd, 0, sizeof(GSM_CallDivert));
-
-            if (!strcmp("register", argv[0])){cd.Operation = GSM_CDV_Register ;} 
-        else if (!strcmp("enable"  , argv[0])){cd.Operation = GSM_CDV_Enable   ;} 
-        else if (!strcmp("disable" , argv[0])){cd.Operation = GSM_CDV_Disable  ;}
-        else if (!strcmp("erasure" , argv[0])){cd.Operation = GSM_CDV_Erasure  ;}
-       else if (!strcmp("query"   , argv[0])){cd.Operation = GSM_CDV_Query    ;}
-        else {
-               usage();
-               exit(-1);
-       }
+       /* Hopefully is 64 larger as FB38_MAX* / FB61_MAX* */
+       char imei[64], model[64], rev[64], manufacturer[64];
+       GSM_Statemachine *sm = &State;
 
 
-            if (!strcmp("all"       , argv[1])) {cd.DType = GSM_CDV_AllTypes  ;}
-       else if (!strcmp("busy"      , argv[1])) {cd.DType = GSM_CDV_Busy      ;}
-       else if (!strcmp("noans"     , argv[1])) {cd.DType = GSM_CDV_NoAnswer  ;}
-       else if (!strcmp("outofreach", argv[1])) {cd.DType = GSM_CDV_OutOfReach;}
-       else {
-               usage();
-               exit(-1);
-       }
+       data.Manufacturer=manufacturer;
+       data.Model=model;
+       data.Revision=rev;
+       data.Imei=imei;
 
 
-            if (!strcmp("all"  , argv[2])) {cd.CType = GSM_CDV_AllCalls  ;}
-       else if (!strcmp("voice", argv[2])) {cd.CType = GSM_CDV_VoiceCalls;}
-       else if (!strcmp("fax"  , argv[2])) {cd.CType = GSM_CDV_FaxCalls  ;}
-       else if (!strcmp("data" , argv[2])) {cd.CType = GSM_CDV_DataCalls ;}
-       else {
-               usage();
-               exit(-1);
-       }
+       /* Retrying is bad idea: what if function is simply not implemented?
+          Anyway let's wait 2 seconds for the right packet from the phone. */
+       sleep(2);
 
 
-       if (argc>3) strcpy(cd.Number, argv[3]);
+       strcpy(imei, "(unknown)");
+       strcpy(manufacturer, "(unknown)");
+       strcpy(model, "(unknown)");
+       strcpy(rev, "(unknown)");
 
 
-       if (argc>4) cd.Timeout = atoi(argv[4]);
+       SM_Functions(GOP_Identify, &data, sm);
 
 
-       /* Initialise the code for the GSM interface. */     
-       fbusinit(NULL);
+       fprintf(stdout, _("IMEI:     %s\n"), imei);
+       fprintf(stdout, _("Manufacturer: %s\n"), manufacturer);
+       fprintf(stdout, _("Model:    %s\n"), model);
+       fprintf(stdout, _("Revision: %s\n"), rev);
 
 
-       error=GSM->CallDivert(&cd);
+       //GSM->Terminate();
 
 
-       if (error == GE_NONE) {
-          switch (cd.Operation)
-          {
-            case GSM_CDV_Query:
-             fprintf(stdout, _("Divert type: "));
-             switch (cd.DType) {
-               case GSM_CDV_Busy      :fprintf(stdout, _("when busy"));break;
-               case GSM_CDV_NoAnswer  :fprintf(stdout, _("when not answered"));break;
-               case GSM_CDV_OutOfReach:fprintf(stdout, _("when phone off or no coverage"));break;
-                case GSM_CDV_AllTypes  :fprintf(stdout, _("all call diverts"));break; //?
-                default:                fprintf(stdout, _("unknown %i"),cd.DType);break;
-              }
-
-              fprintf(stdout, _("\nCalls type : "));
-              switch (cd.CType) {
-                case GSM_CDV_VoiceCalls: fprintf(stdout, _("voice"));break;
-                case GSM_CDV_FaxCalls  : fprintf(stdout, _("fax"));break;
-                case GSM_CDV_DataCalls : fprintf(stdout, _("data"));break;
-                case GSM_CDV_AllCalls  : fprintf(stdout, _("voice, fax & data"));break;
-                default:   fprintf(stdout, _("unknown %i"),cd.CType);break;
-              }
-              fprintf(stdout, _("\n"));
-
-              if (cd.Enabled) {
-                fprintf(stdout, _("Status     : active\n"));
-                fprintf(stdout, _("Timeout    : %i seconds\n"),cd.Timeout);
-                fprintf(stdout, _("Number     : %s\n"),cd.Number);
-              } else {
-                fprintf(stdout, _("Status     : deactivated\n"));
-              }
-
-              break;
-            default:
-              fprintf(stdout,_("Divert done\n"));
-          }
-        } else 
-          fprintf(stderr,_("%s\n"),print_error(error));
+       return 0;
+}
 
 
+int senddtmf(char *String)
+{
+       GSM->SendDTMF(String);
        GSM->Terminate();
        GSM->Terminate();
-
        return 0;
 }
 
        return 0;
 }
 
-int savephonebookentry(int argc, char *argv[])
+/* Resets the phone */
+int reset( char *type)
 {
 {
-  GSM_MultiSMSMessage MultiSMS;
-  GSM_PhonebookEntry entry;
-  GSM_Error error;
-  int w;
+       unsigned char _type = 0x03;
 
 
-  fbusinit(NULL);
-
-  /* Handle command line args that set type, start and end locations. */
-  if (!GetMemoryTypeID(argv[0], &entry.MemoryType))
-  {
-    fprintf(stderr, _("Unknown memory type %s!\n"), argv[0]);
-    return (-1);
-  }
-
-  entry.Location=atoi(argv[1]);
+       if (type) {
+               if(!strcmp(type, "soft"))
+                       _type = 0x03;
+               else
+                       if(!strcmp(type, "hard"))
+                               _type = 0x04;
+                       else {
+                               fprintf(stderr, _("What kind of reset do you want??\n"));
+                               return -1;
+                       }
+       }
 
 
-  fbusinit(NULL);
+       GSM->Reset(_type);
+       GSM->Terminate();
 
 
-  error=GSM->GetMemoryLocation(&entry);
+       return 0;
+}
 
 
-  switch (error) {
-    case GE_NONE:
+/* pmon allows fbus code to run in a passive state - it doesn't worry about
+   whether comms are established with the phone.  A debugging/development
+   tool. */
+int pmon(void)
+{ 
 
 
-      /* Put entry into SMS structure */
-      if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) {
-        GSM_SavePhonebookEntryToSMS(&MultiSMS,&entry,21);
-      } else {
-        GSM_SavePhonebookEntryToSMS(&MultiSMS,&entry,10);
-      }
+       GSM_Error error;
+       GSM_ConnectionType connection=GCT_Serial;
+       GSM_Statemachine sm;
 
 
-      for (w=0;w<MultiSMS.number;w++)
-        strcpy(MultiSMS.SMS[w].Destination,"Phonebook");
+       /* Initialise the code for the GSM interface. */     
+       error = GSM_Initialise(model, Port, Initlength, connection, NULL, &sm);
 
 
-      GSM_SaveMultiPartSMSOnConsole(&MultiSMS, 2,argc,argv,false,false,false,false);
-      break;
+       if (error != GE_NONE) {
+               fprintf(stderr, _("GSM/FBUS init failed! (Unknown model ?). Quitting.\n"));
+               return -1;
+       }
 
 
-    default:
-      fprintf(stdout,_("Error\n"));break;
-  }
+       while (1) {
+               usleep(50000);
+       }
 
 
-  return 0;
+       return 0;
 }
 
 }
 
-int sendphonebookentry(int argc, char *argv[])
+int sendringtone(int argc, char *argv[])
 {
 {
-  GSM_MultiSMSMessage MultiSMS;
-  GSM_PhonebookEntry entry;
-  GSM_Error error;
-  int w;
+       GSM_SMSMessage SMS;
+       GSM_Ringtone ringtone;
+       int i;
+       int size = GSM_MAX_RINGTONE_PACKAGE_LENGTH;
+       char Package[GSM_MAX_RINGTONE_PACKAGE_LENGTH];
+
+       struct option options[] = {
+               SMSC_OPTIONS,
+               { NULL,       0,                 NULL, 0}
+       };
+
+       /* Default settings for SMS message:
+          - no delivery report
+          - Class Message 1
+          - no compression
+          - 8 bit data
+          - SMSC no. 1
+          - validity 3 days
+          - set UserDataHeaderIndicator
+       */
+
+       SMS.Type = GST_MO;
+       SMS.Class = 1;
+       SMS.Compression = false;
+       SMS.EightBit = true;
+       SMS.MessageCenter.No = 1;
+       SMS.Validity = 4320; /* 4320 minutes == 72 hours */
+
+       SMS_SetupUDH(&SMS,GSM_RingtoneUDH);             /* error ignored */
+
+       optarg = NULL;
+       optind = 0;
+       argv[1]=argv[0];
+       argv++;
+       argc--;
+       while ((i = getopt_long(argc, argv, "", options, NULL)) != -1) {
+               if (smsc_options_parse(i,&SMS))
+                       continue;
+               switch (i) {
+               default:
+                       usage(); /* Would be better to have an sendsms_usage() here. */
+               }
+       }
+       argc-=optind;
+       argv+=optind;
+
+       if (argc!=2)
+               usage();
+
+       if (GSM_ReadRingtoneFile(argv[1], &ringtone)) {
+               fprintf(stdout, _("Failed to load ringtone.\n"));
+               return(-1);
+       }  
+       if (strlen(argv[0])+1 > sizeof(SMS.Destination)) {
+               fprintf(stdout, _("Destination number \"%s\" length too long!\n"), argv[0]);
+               return(-1);
+       }
+       strcpy(SMS.Destination, argv[0]);
+       GSM_PackRingtone(&ringtone, Package, &size);
 
 
-  fbusinit(NULL);
+       sendsms_deconcatenated(&SMS,Package,size,true/*useudh*/);
 
 
-  /* Handle command line args that set type, start and end locations. */
-  if (!GetMemoryTypeID(argv[1], &entry.MemoryType))
-  {
-    fprintf(stderr, _("Unknown memory type %s!\n"), argv[1]);
-    return (-1);
-  }
+       GSM->Terminate();
+       return 0;
+}
 
 
-  entry.Location=atoi(argv[2]);
 
 
-  fbusinit(NULL);
+int setringtone(int argc, char *argv[])
+{
+       GSM_Ringtone ringtone;
+       GSM_Error error;
 
 
-  error=GSM->GetMemoryLocation(&entry);
+       if (GSM_ReadRingtoneFile(argv[0], &ringtone)) {
+               fprintf(stdout, _("Failed to load ringtone.\n"));
+               return(-1);
+       }  
 
 
-  switch (error) {
-    case GE_NONE:
+       error = GSM->SetRingtone(&ringtone);
 
 
-      /* Put entry into SMS structure */
-      if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) {
-        GSM_SavePhonebookEntryToSMS(&MultiSMS,&entry,21);
-      } else {
-        GSM_SavePhonebookEntryToSMS(&MultiSMS,&entry,10);
-      }
+       if (error == GE_NONE) 
+               fprintf(stdout, _("Send succeeded!\n"));
+       else
+               fprintf(stdout, _("Send failed\n"));
 
 
-      for (w=0;w<MultiSMS.number;w++)
-        strcpy(MultiSMS.SMS[w].Destination,argv[0]);
+       GSM->Terminate();
+       return 0;
+}
 
 
-      GSM_SendMultiPartSMSOnConsole(&MultiSMS, 3,argc,argv,false,false,false);
+int presskeysequence(void)
+{
+       char buf[105];
 
 
-      break;
+       console_raw();
 
 
-    default:
-      fprintf(stdout,_("Error\n"));break;
-  }
+       memset(&buf[0], 0, 102);
+       while (read(0, buf, 100) > 0) {
+               fprintf(stderr, "handling keys (%d).\n", strlen(buf));
+               if (GSM->HandleString(buf) != GE_NONE)
+                       fprintf(stdout, _("Key press simulation failed.\n"));
+               memset(buf, 0, 102);
+       }
 
 
-  return 0;
+       GSM->Terminate();
+       return 0;
+}
+/* This is a "convenience" function to allow quick test of new API stuff which
+   doesn't warrant a "proper" command line function. */
+#ifndef WIN32
+int foogle(char *argv[])
+{
+       /* Initialise the code for the GSM interface. */     
+       fbusinit(NULL);
+       // Fill in what you would like to test here...
+       return 0;
 }
 }
+#endif
+