This commit was generated by cvs2svn to compensate for changes in r158,
[gnokii.git] / common / gsm-api.c
index 3c090a0..5f86eff 100644 (file)
@@ -1,9 +1,13 @@
 /*
 
+  $Id$
+  
   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.
+
   Released under the terms of the GNU GPL, see file COPYING for more details.
        
   Provides a generic API for accessing functions on the phone, wherever
   Unless otherwise noted, all functions herein block until they complete.  The
   functions themselves are defined in a structure in gsm-common.h.
 
+  $Log$
+  Revision 1.1.1.5  2002/04/03 00:07:54  short
+  Found in "gnokii-working" directory, some November-patches version
+
+  Revision 1.31  2001/11/08 16:45:58  pkot
+  Obsolete old structure, kill treads where possible and make shared library
+
+  Revision 1.30  2001/08/09 11:51:38  pkot
+  Generic AT support updates and cleanup (Manfred Jonsson)
+
+  Revision 1.29  2001/07/27 00:02:20  pkot
+  Generic AT support for the new structure (Manfred Jonsson)
+
+  Revision 1.28  2001/06/06 09:05:56  machek
+  Convert Grab/Release display to new structure.
+
+  Revision 1.27  2001/05/07 14:13:06  machek
+  nokia-2110 module converted to suit new API better. --identify now works.
+
+  Revision 1.26  2001/04/25 12:54:47  machek
+  Partly converted nokia 2110 to "new" form, and moved it to phone
+  directory.
+
+  Revision 1.25  2001/03/26 23:39:21  pkot
+  Minor updates:
+   - Windows INLINE patch (Manfred Jonsson)
+   - patch to configure.in to compile under FreeBSD (Panagiotis Astithas)
+   - other cleanups (me)
+
+  
 */
 
 #include <stdio.h>
 #include <string.h>
-#include <stdlib.h>
-#include <time.h>
 
-#ifdef WIN32
-  #include <windows.h>
-  #include "misc_win32.h"
-#endif
+#include "misc.h"
+#include "gsm-common.h"
+#include "data/rlp-common.h"
+#include "gsm-statemachine.h"
+#include "phones/nk7110.h"
+#include "phones/nk6100.h"
+#include "phones/nk3110.h"
+#include "phones/nk2110.h"
 
-#include "gsm-api.h"
-
-#include "newmodules/n3110.h"
-#include "newmodules/n6110.h"
-#include "newmodules/n7110.h"
-#include "newmodules/newat.h"
-#ifdef DEBUG
-  #include "newmodules/sniff/sniff.h"
-#endif
-#include "protocol/fbusirda.h"
-#include "protocol/fbus.h"
-#include "protocol/fbus3110.h"
-#include "protocol/mbus.h"
-#include "protocol/at.h"
-#include "files/cfgreader.h"
-
-#ifndef WIN32
-  #include "devices/device.h"
-#endif
-
-#ifdef VC6
-  /* for VC6 make scripts save VERSION constant in mversion.h file */
-  #include "mversion.h"
-#endif
 
 /* GSM_LinkOK is set to true once normal communications with the phone have
    been established. */
 
 bool *GSM_LinkOK;
+bool LinkAlwaysOK = true;
 
 /* Define pointer to the GSM_Functions structure used by external code to call
    relevant API functions. This structure is defined in gsm-common.h. */
@@ -69,773 +82,622 @@ GSM_Functions *GSM;
 
 GSM_Information                *GSM_Info;
 
-/* Initialise interface to the phone. Model number should be a string such as
-   3810, 5110, 6110 etc. Device is the serial port to use e.g. /dev/ttyS0, the
-   user must have write permission to the device. */
 
-GSM_Protocol *Protocol;
 
-/* Local variables used by get/set phonebook entry code. Buffer is used as a
-   source or destination for phonebook data and other functions... Error is
-   set to GE_NONE by calling function, set to GE_COMPLETE or an error code by
-   handler routines as appropriate. */
-                                  
-GSM_PhonebookEntry *CurrentPhonebookEntry;
-GSM_Error          CurrentPhonebookError;
+/* From here starts the ugly compatibility cludge to complete WIPE OUT the
+ * insane "Sorry, phone has not yet been converted to new style.
+ * Phone.Functions == NULL!" message out of the Earth surface to make the world
+ * a happy place back again! Wiping out, wiping out, wiping out!
+ * The most World's evil GSM_Error code: GE_NOTIMPLEMENTED
+ * Completely non-systematic naming is not my souvenir - it is just copied
+ * from the existing include files. (Jan Kratochvil)
+ */
+
+static GSM_Statemachine *compat_Functions_Statemachine;
+
+#define INVOKE_COMPAT_FUNCTIONS_SM(gop) \
+       (compat_Functions_Statemachine->Phone.Functions((gop),&data,compat_Functions_Statemachine))
+#define RETURN_COMPAT_FUNCTIONS_SM(gop) \
+       return((INVOKE_COMPAT_FUNCTIONS_SM((gop))))
+#define BODY_COMPAT_FUNCTIONS_SM_CORE(core,gop) \
+       GSM_Data data; \
+       core \
+       RETURN_COMPAT_FUNCTIONS_SM((gop));
+#define BODY_COMPAT_FUNCTIONS_SM0(gop) \
+       BODY_COMPAT_FUNCTIONS_SM_CORE(  ,(gop))
+#define BODY_COMPAT_FUNCTIONS_SM1(field1,arg1,gop) \
+       BODY_COMPAT_FUNCTIONS_SM_CORE( data.field1=(arg1); ,(gop))
+#define BODY_COMPAT_FUNCTIONS_SM2(field1,arg1,field2,arg2,gop) \
+       BODY_COMPAT_FUNCTIONS_SM_CORE( data.field1=(arg1);data.field2=(arg2); ,(gop))
+#define BODY_COMPAT_FUNCTIONS_SM3(field1,arg1,field2,arg2,field3,arg3,gop) \
+       BODY_COMPAT_FUNCTIONS_SM_CORE( data.field1=(arg1);data.field2=(arg2);data.field3=(arg3); ,(gop))
+
+static GSM_Error compat_Functions_Initialise
+       (char *port_device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame))
+{
+       fprintf(stderr,"FATAL: GSM->Initialise called for new style phone implementation!\n");
+       return(GE_NOTIMPLEMENTED);
+}
 
-GSM_SpeedDial      *CurrentSpeedDialEntry;
-GSM_Error          CurrentSpeedDialError;
+static void compat_Functions_Terminate(void)
+{
+GSM_Data data; /* void */
 
-unsigned char      Current_IMEI[GSM_MAX_IMEI_LENGTH];
-unsigned char      Current_Revision[GSM_MAX_REVISION_LENGTH];
-unsigned char      Current_Model[GSM_MAX_MODEL_LENGTH];
+       INVOKE_COMPAT_FUNCTIONS_SM(GOP_Terminate);
+}
 
-GSM_SMSMessage     *CurrentSMSMessage;
-GSM_Error          CurrentSMSMessageError;
-int                CurrentSMSPointer;
+static GSM_Error compat_Functions_GetMemoryLocation( GSM_PhonebookEntry *entry )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(PhonebookEntry,entry,GOP_ReadPhonebook);
+}
 
-GSM_SMSFolders      *CurrentSMSFolders;
-GSM_Error          CurrentSMSFoldersError;
-int                CurrentSMSFoldersCount;
+static GSM_Error compat_Functions_WritePhonebookLocation( GSM_PhonebookEntry *entry )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(PhonebookEntry,entry,GOP_WritePhonebook);
+}
 
-GSM_OneSMSFolder   CurrentSMSFolder;
-GSM_Error          CurrentSMSFolderError;
-int                CurrentSMSFolderID;
+static GSM_Error compat_Functions_GetSpeedDial( GSM_SpeedDial *entry )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(SpeedDial,entry,GOP_GetSpeedDial);
+}
 
-GSM_MemoryStatus   *CurrentMemoryStatus;
-GSM_Error          CurrentMemoryStatusError;
+static GSM_Error compat_Functions_SetSpeedDial( GSM_SpeedDial *entry )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(SpeedDial,entry,GOP_SetSpeedDial);
+}
 
-GSM_NetworkInfo    *CurrentNetworkInfo;
-GSM_Error          CurrentNetworkInfoError;
+static GSM_Error compat_Functions_GetMemoryStatus( GSM_MemoryStatus *Status )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(MemoryStatus,Status,GOP_GetMemoryStatus);
+}
 
-GSM_SMSStatus      *CurrentSMSStatus;
-GSM_Error          CurrentSMSStatusError;
+static GSM_Error compat_Functions_GetSMSStatus( GSM_SMSStatus *Status )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(SMSStatus,Status,GOP_GetSMSStatus);
+}
 
-GSM_MessageCenter  *CurrentMessageCenter;
-GSM_Error          CurrentMessageCenterError;
+static GSM_Error compat_Functions_GetSMSCenter( GSM_MessageCenter *MessageCenter )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(MessageCenter,MessageCenter,GOP_GetSMSCenter);
+}
 
-int                *CurrentSecurityCodeStatus;
-GSM_Error          CurrentSecurityCodeError;
-GSM_SecurityCode   *CurrentSecurityCode;
+static GSM_Error compat_Functions_SetSMSCenter( GSM_MessageCenter *MessageCenter )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(MessageCenter,MessageCenter,GOP_SetSMSCenter);
+}
 
-GSM_DateTime       *CurrentDateTime;
-GSM_Error          CurrentDateTimeError;
+static GSM_Error compat_Functions_GetSMSMessage( GSM_SMSMessage *Message )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(SMSMessage,Message,GOP_GetSMS);
+}
 
-GSM_DateTime       *CurrentAlarm;
-GSM_Error          CurrentAlarmError;
+static GSM_Error compat_Functions_DeleteSMSMessage( GSM_SMSMessage *Message )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(SMSMessage,Message,GOP_DeleteSMS);
+}
 
-GSM_CalendarNote   *CurrentCalendarNote;
-GSM_Error          CurrentCalendarNoteError;
+static GSM_Error compat_Functions_SendSMSMessage( GSM_SMSMessage *Message )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(SMSMessage,Message,GOP_SendSMS);
+}
 
-GSM_NotesInfo      CurrentCalendarNotesInfo,*CurrentCalendarNotesInfo2;
-GSM_Error          CurrentCalendarNotesInfoError;
+static GSM_Error compat_Functions_SaveSMSMessage( GSM_SMSMessage *Message )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(SMSMessage,Message,GOP_SaveSMS);
+}
 
-GSM_Error          CurrentSetDateTimeError;
-GSM_Error          CurrentSetAlarmError;
+static GSM_Error compat_Functions_GetRFLevel( GSM_RFUnits *units, float *level )
+{
+       BODY_COMPAT_FUNCTIONS_SM2(RFUnits,units,RFLevel,level,GOP_GetRFLevel);
+}
 
-GSM_Error          CurrentEnableExtendedCommandsError;
+static GSM_Error compat_Functions_GetBatteryLevel( GSM_BatteryUnits *units, float *level )
+{
+       BODY_COMPAT_FUNCTIONS_SM2(BatteryUnits,units,BatteryLevel,level,GOP_GetBatteryLevel);
+}
 
-int                CurrentRFLevel,
-                   CurrentBatteryLevel,
-                   CurrentPowerSource;
+static GSM_Error compat_Functions_GetPowerSource( GSM_PowerSource *source )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(PowerSource,source,GOP_GetPowersource);
+}
 
-int                CurrentDisplayStatus;
-GSM_Error          CurrentDisplayStatusError;
+static GSM_Error compat_Functions_GetDisplayStatus( int *Status )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(DisplayStatus,Status,GOP_GetDisplayStatus);
+}
 
-GSM_Error          CurrentResetPhoneSettingsError;
+static GSM_Error compat_Functions_EnterSecurityCode( GSM_SecurityCode Code )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(SecurityCode,&Code,GOP_EnterSecurityCode);
+}
 
-char               *CurrentNetmonitor;
-GSM_Error          CurrentNetmonitorError;
+/* FIXME: GetSecurityCodeStatus() should have GSM_SecurityCodeType as its argument!
+ */
+static GSM_Error compat_Functions_GetSecurityCodeStatus( int *Status )
+{
+GSM_SecurityCodeType status_local;
+GSM_Data data;
+GSM_Error err;
+
+       data.SecurityCodeStatus=&status_local;
+       err=INVOKE_COMPAT_FUNCTIONS_SM(GOP_GetSecurityCodeStatus);
+       *Status=status_local;
+       return(err);
+}
 
-GSM_Bitmap         *CurrentGetBitmap=NULL;
-GSM_Error          CurrentGetBitmapError;
+static GSM_Error compat_Functions_GetIMEI( char *imei )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(Imei,imei,GOP_GetImei);
+}
 
-GSM_Error          CurrentSetBitmapError;
+static GSM_Error compat_Functions_GetRevision( char *revision )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(Revision,revision,GOP_GetRevision);
+}
 
-GSM_Error          CurrentSendDTMFError;
+static GSM_Error compat_Functions_GetModel( char *model )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(Model,model,GOP_GetModel);
+}
 
-GSM_Profile        *CurrentProfile;
-GSM_Error          CurrentProfileError;
+static GSM_Error compat_Functions_GetManufacturer( char *manufacturer )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(Manufacturer,manufacturer,GOP_GetManufacturer);
+}
 
-GSM_Error          CurrentDisplayOutputError;
+static GSM_Error compat_Functions_GetDateTime( GSM_DateTime *date_time)
+{
+       BODY_COMPAT_FUNCTIONS_SM1(DateTime,date_time,GOP_GetDateTime);
+}
 
-GSM_CBMessage      *CurrentCBMessage;
-GSM_Error          CurrentCBError;
+static GSM_Error compat_Functions_SetDateTime( GSM_DateTime *date_time)
+{
+       BODY_COMPAT_FUNCTIONS_SM1(DateTime,date_time,GOP_SetDateTime);
+}
 
-int                CurrentPressKeyEvent;
-GSM_Error          CurrentPressKeyError;
+static GSM_Error compat_Functions_GetAlarm( int alarm_number, GSM_DateTime *date_time )
+{
+       BODY_COMPAT_FUNCTIONS_SM2(AlarmNumber,&alarm_number,AlarmDateTime,date_time,GOP_GetAlarm);
+}
 
-GSM_Error          CurrentPlayToneError=GE_UNKNOWN;
+static GSM_Error compat_Functions_SetAlarm( int alarm_number, GSM_DateTime *date_time )
+{
+       BODY_COMPAT_FUNCTIONS_SM2(AlarmNumber,&alarm_number,AlarmDateTime,date_time,GOP_SetAlarm);
+}
+
+static GSM_Error compat_Functions_DialVoice( char *Number )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(VoiceNumber,Number,GOP_DialVoice);
+}
 
-GSM_Error          CurrentDialVoiceError;
+static GSM_Error compat_Functions_DialData( char *Number, char type, void (* callpassup)(char c) )
+{
+       BODY_COMPAT_FUNCTIONS_SM3(DataNumber,Number,DataType,&type,DataCallPassUp,callpassup,GOP_DialData);
+}
 
-GSM_Error          CurrentGetOperatorNameError;
-GSM_Network        *CurrentGetOperatorNameNetwork;
-GSM_Error          CurrentSetOperatorNameError;
+static GSM_Error compat_Functions_GetIncomingCallNr( char *Number )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(IncomingCallNr,Number,GOP_GetIncomingCallNr);
+}
 
-GSM_Error          CurrentGetIMEIError;
+static GSM_Error compat_Functions_GetNetworkInfo ( GSM_NetworkInfo *NetworkInfo )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(NetworkInfo,NetworkInfo,GOP_GetNetworkInfo);
+}
 
-GSM_Error          CurrentGetHWError;
+static GSM_Error compat_Functions_GetCalendarNote ( GSM_CalendarNote *CalendarNote)
+{
+       BODY_COMPAT_FUNCTIONS_SM1(CalendarNote,CalendarNote,GOP_GetCalendarNote);
+}
 
-unsigned char      CurrentPPS[4];
-GSM_Error          CurrentProductProfileSettingsError;
+static GSM_Error compat_Functions_WriteCalendarNote ( GSM_CalendarNote *CalendarNote)
+{
+       BODY_COMPAT_FUNCTIONS_SM1(CalendarNote,CalendarNote,GOP_WriteCalendarNote);
+}
 
-char               CurrentIncomingCall[20];
+static GSM_Error compat_Functions_DeleteCalendarNote ( GSM_CalendarNote *CalendarNote)
+{
+       BODY_COMPAT_FUNCTIONS_SM1(CalendarNote,CalendarNote,GOP_DeleteCalendarNote);
+}
 
-GSM_Error          CurrentBinRingtoneError;
-GSM_BinRingtone    *CurrentGetBinRingtone=NULL;
+static GSM_Error compat_Functions_NetMonitor ( unsigned char mode, char *Screen )
+{
+       BODY_COMPAT_FUNCTIONS_SM2(NetMonitorMode,&mode,NetMonitorScreen,Screen,GOP_NetMonitor);
+}
 
-GSM_Error          CurrentRingtoneError;
+static GSM_Error compat_Functions_SendDTMF ( char *String )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(DTMF,String,GOP_SendDTMF);
+}
 
-GSM_Error          CurrentMagicError;
+static GSM_Error compat_Functions_GetBitmap ( GSM_Bitmap *Bitmap )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(Bitmap,Bitmap,GOP_GetBitmap);
+}
+  
+static GSM_Error compat_Functions_SetBitmap ( GSM_Bitmap *Bitmap )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(Bitmap,Bitmap,GOP_SetBitmap);
+}
 
-GSM_Error          CurrentSimlockInfoError;
-GSM_AllSimlocks    *CurrentSimLock;
+static GSM_Error compat_Functions_SetRingtone ( GSM_Ringtone *ringtone )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(Ringtone,ringtone,GOP_SetRingtone);
+}
 
-GSM_Error          CurrentGetWAPBookmarkError;
-GSM_Error          CurrentSetWAPBookmarkError;
-GSM_WAPBookmark    *WAPBookmark;
+static GSM_Error compat_Functions_Reset ( unsigned char type )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(ResetType,&type,GOP_Reset);
+}
 
-GSM_Error          CurrentGetWAPSettingsError;
-GSM_WAPSettings    *WAPSettings;
+static GSM_Error compat_Functions_GetProfile ( GSM_Profile *Profile )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(Profile,Profile,GOP_GetProfile);
+}
 
-GSM_Error          CurrentCallDivertError;
-GSM_CallDivert    *CurrentCallDivert;
+static GSM_Error compat_Functions_SetProfile ( GSM_Profile *Profile )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(Profile,Profile,GOP_SetProfile);
+}
 
-char              *CurrentManufacturer;
+/* return type "bool" is fortunately compatible with "GSM_Error"
+ */
+static bool      compat_Functions_SendRLPFrame ( RLP_F96Frame *frame, bool out_dtx )
+{
+       BODY_COMPAT_FUNCTIONS_SM2(RLPFrame,frame,RLPFrame_out_dtx,&out_dtx,GOP_SendRLPFrame);
+}
 
-/* This is the connection type used in gnokii. */
-GSM_ConnectionType CurrentConnectionType;
+static GSM_Error compat_Functions_CancelCall ( void )
+{
+       BODY_COMPAT_FUNCTIONS_SM0(GOP_CancelCall);
+}
+  
+static GSM_Error compat_Functions_EnableDisplayOutput ( void )
+{
+       BODY_COMPAT_FUNCTIONS_SM0(GOP_EnableDisplayOutput);
+}
+  
+static GSM_Error compat_Functions_DisableDisplayOutput ( void )
+{
+       BODY_COMPAT_FUNCTIONS_SM0(GOP_DisableDisplayOutput);
+}
+static GSM_Error compat_Functions_EnableCellBroadcast ( void )
+{
+       BODY_COMPAT_FUNCTIONS_SM0(GOP_EnableCellBroadcast);
+}
 
-/* Pointer to a callback function used to return changes to a calls status */
-/* This saves unreliable polling */
-void (*CurrentCallPassup)(char c);
+static GSM_Error compat_Functions_DisableCellBroadcast ( void )
+{
+       BODY_COMPAT_FUNCTIONS_SM0(GOP_DisableCellBroadcast);
+}
 
-/* Pointer to callback function in user code to be called when RLP frames
-   are received. */
-void (*CurrentRLP_RXCallback)(RLP_F96Frame *frame);
+static GSM_Error compat_Functions_ReadCellBroadcast ( GSM_CBMessage *Message )
+{
+       BODY_COMPAT_FUNCTIONS_SM1(CBMessage,Message,GOP_ReadCellBroadcast);
+}
+  
+static GSM_Error compat_Functions_SetKey (int c, int up)
+{
+       BODY_COMPAT_FUNCTIONS_SM2(SetKeyKey,&c,SetKeyUp,&up,GOP_SetKey);
+}
+  
+static GSM_Error compat_Functions_HandleString (char *s)
+{
+       BODY_COMPAT_FUNCTIONS_SM1(HandleString,s,GOP_HandleString);
+}
+       
+static GSM_Error compat_Functions_AnswerCall (char s)
+{
+       BODY_COMPAT_FUNCTIONS_SM1(CallNo,&s,GOP_AnswerCall);
+}
 
-/* Used to disconnect the call */
-u8 CurrentCallSequenceNumber;
+static GSM_Functions compat_Functions={
+       compat_Functions_Initialise,
+       compat_Functions_Terminate,
+       compat_Functions_GetMemoryLocation,
+       compat_Functions_WritePhonebookLocation,
+       compat_Functions_GetSpeedDial,
+       compat_Functions_SetSpeedDial,
+       compat_Functions_GetMemoryStatus,
+       compat_Functions_GetSMSStatus,
+       compat_Functions_GetSMSCenter,
+       compat_Functions_SetSMSCenter,
+       compat_Functions_GetSMSMessage,
+       compat_Functions_DeleteSMSMessage,
+       compat_Functions_SendSMSMessage,
+       compat_Functions_SaveSMSMessage,
+       compat_Functions_GetRFLevel,
+       compat_Functions_GetBatteryLevel,
+       compat_Functions_GetPowerSource,
+       compat_Functions_GetDisplayStatus,
+       compat_Functions_EnterSecurityCode,
+       compat_Functions_GetSecurityCodeStatus,
+       compat_Functions_GetIMEI,
+       compat_Functions_GetRevision,
+       compat_Functions_GetModel,
+       compat_Functions_GetManufacturer,
+       compat_Functions_GetDateTime,
+       compat_Functions_SetDateTime,
+       compat_Functions_GetAlarm,
+       compat_Functions_SetAlarm,
+       compat_Functions_DialVoice,
+       compat_Functions_DialData,
+       compat_Functions_GetIncomingCallNr,
+       compat_Functions_GetNetworkInfo,
+       compat_Functions_GetCalendarNote,
+       compat_Functions_WriteCalendarNote,
+       compat_Functions_DeleteCalendarNote,
+       compat_Functions_NetMonitor,
+       compat_Functions_SendDTMF,
+       compat_Functions_GetBitmap,
+       compat_Functions_SetBitmap,
+       compat_Functions_SetRingtone,
+       compat_Functions_Reset,
+       compat_Functions_GetProfile,
+       compat_Functions_SetProfile,
+       compat_Functions_SendRLPFrame,
+       compat_Functions_CancelCall,
+       compat_Functions_EnableDisplayOutput,
+       compat_Functions_DisableDisplayOutput,
+       compat_Functions_EnableCellBroadcast,
+       compat_Functions_DisableCellBroadcast,
+       compat_Functions_ReadCellBroadcast,
+       compat_Functions_SetKey,
+       compat_Functions_HandleString,
+       compat_Functions_AnswerCall,
+       };
+
+GSM_Error compat_Phone_Functions(GSM_Operation op, GSM_Data *data, GSM_Statemachine *state)
+{
+       switch (op) {
+       
+       case GOP_Init:
+               fprintf(stderr,"FATAL: compat_Phone_Functions(GOP_Init) called for old style phone implementation!\n");
+               return(GE_NOTIMPLEMENTED);
 
-bool CurrentLinkOK;
+       case GOP_Terminate:
+               GSM->Terminate();
+               return(GE_NONE);
 
-bool CurrentRequestTerminate;
+       case GOP_ReadPhonebook:
+               return(GSM->GetMemoryLocation(data->PhonebookEntry/*entry*/));
 
-bool CurrentDisableKeepAlive;
+       case GOP_WritePhonebook:
+               return(GSM->WritePhonebookLocation(data->PhonebookEntry/*entry*/));
 
-bool CheckModel (GSM_Information InfoToCheck, char *model, GSM_ConnectionType connection) {
+       case GOP_GetSpeedDial:
+               return(GSM->GetSpeedDial(data->SpeedDial/*entry*/));
 
-  bool found_match=false;
+       case GOP_SetSpeedDial:
+               return(GSM->SetSpeedDial(data->SpeedDial/*entry*/));
 
-  if (strstr(InfoToCheck.FBUSModels, model) != NULL) {
-    if (connection==GCT_FBUS) found_match=true;
-  }
-  if (strstr(InfoToCheck.MBUSModels, model) != NULL) {
-    if (connection==GCT_MBUS) found_match=true;
-  }
-  if (strstr(InfoToCheck.InfraredModels, model) != NULL) {
-    if (connection==GCT_Infrared) found_match=true;
-  }
-  if (strstr(InfoToCheck.DLR3Models, model) != NULL) {
-    if (connection==GCT_DLR3) found_match=true;
-  }
-  if (strstr(InfoToCheck.IrdaModels, model) != NULL) {
-    if (connection==GCT_Irda) found_match=true;
-  }
-  if (strstr(InfoToCheck.ATModels, model) != NULL) {
-    if (connection==GCT_AT) found_match=true;
-  }
-  if (strstr(InfoToCheck.TekramModels, model) != NULL) {
-    if (connection==GCT_Tekram) found_match=true;
-  }
-  if (strstr(InfoToCheck.FBUS3110Models, model) != NULL) {
-    if (connection==GCT_FBUS3110) found_match=true;
-  }
+       case GOP_GetMemoryStatus:
+               return(GSM->GetMemoryStatus(data->MemoryStatus/*Status*/));
 
-  return found_match;
-}
-GSM_Error TryNewNokia(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame)) {
-  int InitLength;
-  int count;
-  unsigned char init_char = N6110_SYNC_BYTE;
+       case GOP_GetSMSStatus:
+               return(GSM->GetSMSStatus(data->SMSStatus/*Status*/));
 
-  /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
-  char phonemodel[64];
+       case GOP_GetSMSCenter:
+               return(GSM->GetSMSCenter(data->MessageCenter/*MessageCenter*/));
 
-  if (Protocol->Initialise(device,initlength,connection,rlp_callback)!=GE_NONE)
-  {
-    return GE_NOTSUPPORTED; 
-  }
+       case GOP_SetSMSCenter:
+               return(GSM->SetSMSCenter(data->MessageCenter/*MessageCenter*/));
 
-  if (connection!=GCT_MBUS) {
-    InitLength = atoi(initlength);
+       case GOP_GetSMS:
+               return(GSM->GetSMSMessage(data->SMSMessage/*Message*/));
 
-    if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
-      InitLength = 250;        /* This is the usual value, lower may work. */
-    }
+       case GOP_DeleteSMS:
+               return(GSM->DeleteSMSMessage(data->SMSMessage/*Message*/));
 
-#ifdef DEBUG
-    fprintf(stdout,_("Writing init chars...."));
-#endif
+       case GOP_SendSMS:
+               return(GSM->SendSMSMessage(data->SMSMessage/*Message*/));
 
-    /* Initialise link with phone or what have you */
-    /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
-       empirical. */
-    for (count = 0; count < InitLength; count ++) {
-      usleep(100);
-      Protocol->WritePhone(1,&init_char);
-    }
+       case GOP_SaveSMS:
+               return(GSM->SaveSMSMessage(data->SMSMessage/*Message*/));
 
-#ifdef DEBUG
-    fprintf(stdout,_("Done\n"));  
-#endif
+       case GOP_GetRFLevel:
+               return(GSM->GetRFLevel(data->RFUnits/*units*/,data->RFLevel/*level*/));
 
-    N6110_SendStatusRequest();
-  }
+       case GOP_GetBatteryLevel:
+               return(GSM->GetBatteryLevel(data->BatteryUnits/*units*/,data->BatteryLevel/*level*/));
 
-  usleep(100);
+       case GOP_GetPowersource:
+               return(GSM->GetPowerSource(data->PowerSource/*source*/));
 
-  if (N6110_SendIDFrame()!=GE_NONE)
-    return GE_TIMEOUT;
-  while (N6110_GetModel(phonemodel) != GE_NONE)
-    sleep(1);
+       case GOP_GetDisplayStatus:
+               return(GSM->GetDisplayStatus(data->DisplayStatus/*Status*/));
 
-  if (!strcmp(phonemodel,"NPE-3") || !strcmp(phonemodel,"NSE-5") || 
-      !strcmp(phonemodel,"NHM-3"))
-  {
-    GSM->Terminate();      
-    
-    /* Set pointers to relevant addresses */
-    GSM = &N7110_Functions;
-    GSM_Info = &N7110_Information;
-    GSM_LinkOK = &CurrentLinkOK;
-    return GE_NONE;
-  }
+       case GOP_EnterSecurityCode:
+               return(GSM->EnterSecurityCode(*data->SecurityCode/*Code*/));
 
-  return GE_NONE;
-}
+       case GOP_GetSecurityCodeStatus: {
+int status_local=*data->SecurityCodeStatus;
+GSM_Error err;
 
-GSM_Error GSM_Initialise(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame), char* SynchronizeTime)
-{
-  bool found_match=false;
-  
-  GSM_ConnectionType connection2;
+               err=GSM->GetSecurityCodeStatus(&status_local);
+               *data->SecurityCodeStatus=status_local;
+               return(err);
+               }
 
-  struct tm *now;
-  time_t nowh;
-  GSM_DateTime Date;
-  GSM_Error error;
-  
-  connection2=connection;
-
-  CurrentRLP_RXCallback = rlp_callback;
-  CurrentCallPassup=NULL;
-  CurrentCallDivert=NULL;
-  CurrentPhonebookEntry=NULL;
-  CurrentNetworkInfo = NULL;
-  CurrentGetBitmap=NULL;
-  CurrentPlayToneError=GE_UNKNOWN;
-  strcpy(CurrentIncomingCall," ");
-  CurrentGetBinRingtone=NULL;
-  CurrentNetworkInfo=NULL;
-  CurrentRequestTerminate=false;
-  CurrentDisableKeepAlive=false;
-  CurrentCalendarNotesInfo.HowMany=2000;
-  CurrentSMSMessage=NULL;
-  CurrentMagicError = GE_BUSY;  
-  
-  if (!strcmp(model,"auto")) {
-
-    /* For now */
-    GSM = &N6110_Functions;
-    GSM_Info = &N6110_Information;
-    GSM_LinkOK = &CurrentLinkOK;
-#ifdef DEBUG
-    fprintf(stdout,_("Trying FBUS for new Nokia phones...\n"));
-#endif
-    /* Trying FBUS */
-    Protocol = &FBUS_Functions;
-    CurrentConnectionType=GCT_FBUS;    
-    connection2=GCT_FBUS;
-    if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
-    {
-      found_match=true;
-    } else {
-      GSM->Terminate();      
-    }
-
-    if (!found_match) {
-      usleep(100);          
-      
-      /* For now */
-      GSM = &N6110_Functions;
-      GSM_Info = &N6110_Information;
-      GSM_LinkOK = &CurrentLinkOK;
-#ifdef DEBUG
-      fprintf(stdout,_("Trying DLR3 for new Nokia phones...\n"));
-#endif
-      /* Trying DLR3 */
-      Protocol = &FBUS_Functions;
-      CurrentConnectionType=GCT_DLR3;    
-      connection2=GCT_DLR3;
-      if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
-      {
-        found_match=true;
-      } else {
-        GSM->Terminate();      
-      }
-    }
-    
-    if (!found_match) {
-      usleep(100);          
-      
-      /* For now */
-      GSM = &N6110_Functions;
-      GSM_Info = &N6110_Information;
-      GSM_LinkOK = &CurrentLinkOK;
-#ifdef DEBUG
-      fprintf(stdout,_("Trying MBUS for new Nokia phones...\n"));
-#endif
-      /* Trying MBUS */
-      Protocol = &MBUS_Functions;
-      CurrentConnectionType=GCT_MBUS;    
-      connection2=GCT_MBUS;
-      if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
-      {
-        found_match=true;
-      } else {
-        GSM->Terminate();      
-      }
-    }
-
-    if (!found_match) return GE_NOTSUPPORTED;
-
-    usleep(50);
-        
-  } else {
-    if (!strcmp(model,"modelauto")) {
-      /* For now */
-      GSM = &N6110_Functions;
-      GSM_Info = &N6110_Information;
-      GSM_LinkOK = &CurrentLinkOK;
-#ifdef DEBUG
-      fprintf(stdout,_("Trying to find connected model...\n"));
-#endif
-      switch (connection) {
-        case GCT_FBUS    : Protocol = &FBUS_Functions;    break;
-        case GCT_Infrared: Protocol = &FBUS_Functions;    break;
-        case GCT_Tekram  : Protocol = &FBUS_Functions;    break;
-        case GCT_DLR3    : Protocol = &FBUS_Functions;    break;
-        case GCT_MBUS    : Protocol = &MBUS_Functions;    break;
-        case GCT_Irda    : Protocol = &FBUSIRDA_Functions;break;
-        case GCT_AT      : Protocol = &AT_Functions;      break;
-        case GCT_FBUS3110: Protocol = &FBUS3110_Functions;break;
-      }
-      CurrentConnectionType=connection;    
-      connection2=connection;
-      if (TryNewNokia(model,device,initlength,CurrentConnectionType,rlp_callback)==GE_NONE)
-      {
-        found_match=true;
-      } else {
-        GSM->Terminate();      
-      }
-
-      if (!found_match) return GE_NOTSUPPORTED;
-
-      usleep(50);
-
-    } else {
-#ifdef DEBUG
-      if (CheckModel (Nsniff_Information, model, connection)) {
-        /* Set pointers to relevant addresses */
-        GSM = &Nsniff_Functions;
-        GSM_Info = &Nsniff_Information;
-        GSM_LinkOK = &CurrentLinkOK;
-        found_match=true;
-      }
-#endif
+       case GOP_GetImei:
+               return(GSM->GetIMEI(data->Imei/*imei*/));
 
-      if (CheckModel (N3110_Information, model, connection)) {
-        /* Set pointers to relevant addresses */
-        GSM = &N3110_Functions;
-        GSM_Info = &N3110_Information;
-        GSM_LinkOK = &CurrentLinkOK;
-        found_match=true;
-      }
-      if (CheckModel (N6110_Information, model, connection)) {
-        /* Set pointers to relevant addresses */
-        GSM = &N6110_Functions;
-        GSM_Info = &N6110_Information;
-        GSM_LinkOK = &CurrentLinkOK;
-        found_match=true;
-      }
-      if (CheckModel (N7110_Information, model, connection)) {
-        /* Set pointers to relevant addresses */
-        GSM = &N7110_Functions;
-        GSM_Info = &N7110_Information;
-        GSM_LinkOK = &CurrentLinkOK;
-        found_match=true;
-      }
-      if (CheckModel (Nat_Information, model, connection)) {
-        /* Set pointers to relevant addresses */
-        GSM = &Nat_Functions;
-        GSM_Info = &Nat_Information;
-        GSM_LinkOK = &CurrentLinkOK;
-        found_match=true;
-      }
-
-      if (found_match) {
-        switch (connection) {
-          case GCT_FBUS    : Protocol = &FBUS_Functions;    break;
-          case GCT_Infrared: Protocol = &FBUS_Functions;    break;
-          case GCT_Tekram  : Protocol = &FBUS_Functions;    break;
-          case GCT_DLR3    : Protocol = &FBUS_Functions;    break;
-          case GCT_MBUS    : Protocol = &MBUS_Functions;    break;
-          case GCT_Irda    : Protocol = &FBUSIRDA_Functions;break;
-          case GCT_AT      : Protocol = &AT_Functions;      break;
-          case GCT_FBUS3110: Protocol = &FBUS3110_Functions;break;
-        }
-      } else
-        return GE_NOTSUPPORTED;
-    }
-  }
-
-    
-  /* Now call model specific initialisation code. */
-  error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
-
-  /* RTH: FIXME: second try for Irda (6210 only?)*/
-  if ( error!=GE_NONE && connection == GCT_Irda)
-  {
-   #ifdef DEBUG
-     fprintf(stdout,"Irda connection: second try!\n");
-   #endif
-   device_close();
-   error=(GSM->Initialise(device, initlength, connection2, rlp_callback));
-  }
-
-  if (error==GE_NONE && !strcmp(SynchronizeTime,"yes"))
-  {
-    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 (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);
-  }
-
-  return error;
-}
-
-GSM_Error Unimplemented(void)
-{
-       return GE_NOTIMPLEMENTED;
-}
-
-GSM_Error NotSupported(void)
-{
-       return GE_NOTSUPPORTED;
-}
-
-/* Applications should call N6110_Terminate to shut down the N6110 thread and
-   close the serial port. */
-void NULL_Terminate(void)
-{
-  Protocol->Terminate();
-}
-
-#ifdef WIN32
-/* Here are things made for keeping connecting */
-void NULL_KeepAlive()
-{
-}
-#else
-/* Here are things made for keeping connecting */
-void NULL_KeepAlive()
-{
-}
-#endif
+       case GOP_GetRevision:
+               return(GSM->GetRevision(data->Revision/*revision*/));
 
-#ifdef DEBUG
-void NULL_TX_DisplayMessage(u16 MessageLength, u8 *MessageBuffer)
-{
-  fprintf(stdout, _("PC: "));
+       case GOP_GetModel:
+               return(GSM->GetModel(data->Model/*model*/));
 
-  txhexdump(MessageLength,MessageBuffer);
-}
-#endif
+       case GOP_GetManufacturer:
+               return(GSM->GetManufacturer(data->Manufacturer/*manufacturer*/));
 
-bool NULL_WritePhone (u16 length, u8 *buffer) {
-  if (device_write(buffer,length)!=length) return false;
-                                      else return true;
-}
+       case GOP_GetDateTime:
+               return(GSM->GetDateTime(data->DateTime/*date_time*/));
 
-GSM_Error NULL_WaitUntil (int time, GSM_Error *value)
-{
-  int timeout;
+       case GOP_SetDateTime:
+               return(GSM->SetDateTime(data->DateTime/*date_time*/));
 
-  timeout=time;
-  
-  /* Wait for timeout or other error. */
-  while (timeout != 0 && *value == GE_BUSY ) {
-          
-    if (--timeout == 0)
-      return (GE_TIMEOUT);
-                    
-    usleep (100000);
-  }
+       case GOP_GetAlarm:
+               return(GSM->GetAlarm((!data->AlarmNumber ? 0 : *data->AlarmNumber)/*alarm_number*/,
+                               data->AlarmDateTime/*date_time*/));
 
-  return *value;
-}
+       case GOP_SetAlarm:
+               return(GSM->SetAlarm((!data->AlarmNumber ? 0 : *data->AlarmNumber)/*alarm_number*/,
+                               data->AlarmDateTime/*date_time*/));
 
-GSM_Error NULL_SendMessageSequence (int time, GSM_Error *value,
-                 u16 message_length, u8 message_type, u8 *buffer)
-{
-  *value=GE_BUSY;
-  
-  Protocol->SendMessage(message_length, message_type, buffer);  
+       case GOP_DialVoice:
+               return(GSM->DialVoice(data->VoiceNumber/*Number*/));
 
-  return NULL_WaitUntil (time, value);
-}
+       case GOP_DialData:
+               return(GSM->DialData(data->DataNumber/*Number*/,
+                               (!data->DataType ? -1 : *data->DataType)/*type*/,
+                               data->DataCallPassUp/*callpassup*/));
 
-GSM_ConnectionType GetConnectionTypeFromString(char *Connection) {
+       case GOP_GetIncomingCallNr:
+               return(GSM->GetIncomingCallNr(data->IncomingCallNr/*Number*/));
 
-  GSM_ConnectionType connection=GCT_FBUS;
+       case GOP_GetNetworkInfo:
+               return(GSM->GetNetworkInfo(data->NetworkInfo/*NetworkInfo*/));
 
-  if (!strcmp(Connection, "irda"))     connection=GCT_Irda;
-  if (!strcmp(Connection, "infrared")) connection=GCT_Infrared;
-  if (!strcmp(Connection, "mbus"))     connection=GCT_MBUS;
-  if (!strcmp(Connection, "dlr3"))     connection=GCT_DLR3;
-  if (!strcmp(Connection, "fbus3110")) connection=GCT_FBUS3110;
-  if (!strcmp(Connection, "at"))       connection=GCT_AT;
-  if (!strcmp(Connection, "tekram210"))connection=GCT_Tekram;
-  
-  return connection;
-}
+       case GOP_GetCalendarNote:
+               return(GSM->GetCalendarNote(data->CalendarNote/*CalendarNote*/));
 
-bool GetMemoryTypeString(char *memorytext, GSM_MemoryType *type)
-{
-  int i=0;
+       case GOP_WriteCalendarNote:
+               return(GSM->WriteCalendarNote(data->CalendarNote/*CalendarNote*/));
 
-  typedef struct {
-    GSM_MemoryType type;
-    char *name;
-  } GSM_MTStrings;
+       case GOP_DeleteCalendarNote:
+               return(GSM->DeleteCalendarNote(data->CalendarNote/*CalendarNote*/));
 
-  GSM_MTStrings mystring[] = {
-    {GMT_ME,"ME"},
-    {GMT_SM,"SM"},
-    {GMT_FD,"FD"},
-    {GMT_ON,"ON"},
-    {GMT_EN,"EN"},
-    {GMT_DC,"DC"},
-    {GMT_RC,"RC"},  
-    {GMT_MC,"MC"},
-    {GMT_LD,"LD"},
-    {GMT_MT,"MT"},
-    {GMT_ME,"undefined"}
-  };
+       case GOP_NetMonitor:
+               return(GSM->NetMonitor((!data->NetMonitorMode ? 0 : *data->NetMonitorMode)/*mode*/,
+                               data->NetMonitorScreen/*Screen*/));
 
-  while (strcmp(mystring[i].name,"undefined")) {
-    if (*type==mystring[i].type) {
-      strcpy(memorytext,mystring[i].name);
-      return true;
-    }
-    i++;
-  }
-  return false;
-}
+       case GOP_SendDTMF:
+               return(GSM->SendDTMF(data->DTMF/*String*/));
 
-bool GetMemoryTypeID(char *memorytext, GSM_MemoryType *type)
-{
-  int i=0;
+       case GOP_GetBitmap:
+               return(GSM->GetBitmap(data->Bitmap/*Bitmap*/));
 
-  typedef struct {
-    GSM_MemoryType type;
-    char *name;
-  } GSM_MTStrings;
+       case GOP_SetBitmap:
+               return(GSM->SetBitmap(data->Bitmap/*Bitmap*/));
 
-  GSM_MTStrings mystring[] = {
-    {GMT_ME,"ME"},
-    {GMT_SM,"SM"},
-    {GMT_FD,"FD"},
-    {GMT_ON,"ON"},
-    {GMT_EN,"EN"},
-    {GMT_DC,"DC"},
-    {GMT_RC,"RC"},  
-    {GMT_MC,"MC"},
-    {GMT_LD,"LD"},
-    {GMT_MT,"MT"},
-    {GMT_ME,"undefined"}
-  };
+       case GOP_SetRingtone:
+               return(GSM->SetRingtone(data->Ringtone/*ringtone*/));
 
-  while (strcmp(mystring[i].name,"undefined")) {
-    if (strcmp(mystring[i].name,memorytext)==0) {
-      *type=mystring[i].type;
-      return true;
-    }
-    i++;
-  }
+       case GOP_Reset:
+               return(GSM->Reset((!data->ResetType ? 0x03 : *data->ResetType)/*type*/));
 
-  return false;
-}
+       case GOP_GetProfile:
+               return(GSM->GetProfile(data->Profile/*Profile*/));
 
-char *GetMygnokiiVersion() {
+       case GOP_SetProfile:
+               return(GSM->SetProfile(data->Profile/*Profile*/));
 
-  static char Buffer[1000]="";
+       /* return type "bool" is fortunately compatible with "GSM_Error"
+        */
+       case GOP_SendRLPFrame:
+               return(GSM->SendRLPFrame(data->RLPFrame/*frame*/,
+                               (!data->RLPFrame_out_dtx ? 0 : *data->RLPFrame_out_dtx)/*out_dtx*/));
 
-  sprintf(Buffer, "%s",VERSION);
+       case GOP_CancelCall:
+               return(GSM->CancelCall());
 
-  return Buffer;
-}
+       case GOP_EnableDisplayOutput:
+               return(GSM->EnableDisplayOutput());
 
-/*
-1.Name,2.CodeName,3.Calendar,4.Netmonitor,5.Caller groups,6.Phonebook,
-7.Authentication 8.Datacalls 9.KeysPressing 10.SMSC Default Recipient
-11.SpeedDials 12.ScreenSavers 13.DTMF 14.SMS 15.NoPowerFrame 16.StartUpLogo
-17.Profiles 18.Ringtones 19.WAP 20.RIngtonesNumber
-*/
+       case GOP_DisableDisplayOutput:
+               return(GSM->DisableDisplayOutput());
 
-static OnePhoneModel allmodels[] = {
-
-/*1,    2,       3,      4,       5,        6          7      8        9      10        11      12       13     14      15        16       17       18        19    20 */
-{"3210","NSE-8",{      0,F_NETMON,        0,         0,     0,       0,     0,F_SMSCDEF,F_SPEED,       0,     0,F_SMS  ,F_NOPOWER,F_STANIM,F_PROF51,F_RINGBIN,    0, 2}},
-{"3210","NSE-9",{      0,F_NETMON,        0,         0,     0,       0,     0,F_SMSCDEF,F_SPEED,       0,     0,F_SMS  ,F_NOPOWER,F_STANIM,F_PROF51,F_RINGBIN,    0, 2}},
-{"3310","NHM-5",{F_CAL33,F_NETMON,        0,F_PBK33SIM,     0,       0,     0,F_SMSCDEF,F_SPEED,F_SCRSAV,     0,F_SMS  ,F_NOPOWER,F_STANIM,F_PROF33,F_RING_SM,    0, 7}},
-{"3330","NHM-6",{F_CAL33,F_NETMON,        0,F_PBK33INT,     0,       0,F_KEYB,F_SMSCDEF,F_SPEED,F_SCRSAV,     0,F_SMS  ,        0,F_STANIM,F_PROF33,F_RING_SM,F_WAP, 7}},
-{"5110","NSE-1",{      0,F_NETMON,        0,         0,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,       0,F_PROF51,        0,    0, 0}},
-{"5130","NSK-1",{      0,F_NETMON,        0,         0,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,       0,F_PROF51,        0,    0, 0}},
-{"5190","NSB-1",{      0,F_NETMON,        0,         0,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,       0,F_PROF51,        0,    0, 0}},
-{"6110","NSE-3",{F_CAL61,F_NETMON,F_CALER61,F_PBK61INT,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,F_STA   ,F_PROF61,F_RINGBIN,    0, 1}},
-{"6130","NSK-3",{F_CAL61,F_NETMON,F_CALER61,F_PBK61INT,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,F_STA   ,F_PROF61,F_RINGBIN,    0, 1}},
-{"6150","NSM-1",{F_CAL61,F_NETMON,F_CALER61,F_PBK61INT,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,F_STA   ,F_PROF61,F_RINGBIN,    0, 1}},
-{"6190","NSB-3",{F_CAL61,F_NETMON,F_CALER61,F_PBK61INT,F_AUTH,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,F_STA   ,F_PROF61,F_RINGBIN,    0, 1}},
-{"6210","NPE-3",{F_CAL71,F_NETMON,F_CALER61,F_PBK71INT,     0,F_DATA71,     0,F_SMSCDEF,F_SPEED,       0,     0,F_SMS71,        0,F_STA62 ,F_PROF61,F_RINGBIN,F_WAP, 5}},
-{"6250","NHM-3",{F_CAL71,F_NETMON,F_CALER61,F_PBK71INT,     0,F_DATA71,     0,F_SMSCDEF,F_SPEED,       0,     0,F_SMS71,        0,F_STA62 ,F_PROF61,F_RINGBIN,F_WAP, 5}},      
-{"7110","NSE-5",{F_CAL71,F_NETMON,F_CALER61,F_PBK71INT,     0,F_DATA71,     0,F_SMSCDEF,F_SPEED,       0,     0,F_SMS71,        0,F_STA71 ,F_PROF61,F_RINGBIN,F_WAP, 5}},
-{"8210","NSM-3",{      0,F_NETMON,F_CALER61,F_PBK61INT,     0,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,F_STA   ,F_PROF61,F_RINGBIN,    0, 1}},
-{"8850","NSM-2",{      0,F_NETMON,F_CALER61,F_PBK61INT,     0,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,F_STA   ,F_PROF61,F_RINGBIN,    0, 1}},
-{"9210","RAE-3",{      0,F_NETMON,F_CALER61,         0,     0,F_DATA61,F_KEYB,F_SMSCDEF,F_SPEED,       0,F_DTMF,F_SMS  ,        0,F_STA   ,F_PROF61,F_RINGBIN,    0, 0}},//quesses only !
-{""    ,""     ,{      0,       0,        0,         0,     0,       0,     0,        0,      0,       0,     0,      0,        0,       0,       0,        0,    0, 0}}
-};
-
-OnePhoneModel *GetPhoneModelData (const char *num)
-{
-       register int i = 0;
-
-       while (allmodels[i].number != "") {
-               if (strcmp (num, allmodels[i].number) == 0) {
-                       return (&allmodels[i]);
-               }
-               i++;
-       }
+       case GOP_EnableCellBroadcast:
+               return(GSM->EnableCellBroadcast());
 
-       return (&allmodels[i]);
-}
+       case GOP_DisableCellBroadcast:
+               return(GSM->DisableCellBroadcast());
 
-char *GetModelName ()
-{
-  static char model[64];
+       case GOP_ReadCellBroadcast:
+               return(GSM->ReadCellBroadcast(data->CBMessage/*Message*/));
 
-  while (GSM->GetModel(model)  != GE_NONE) sleep(1);
+       case GOP_SetKey:
+               return(GSM->SetKey(*data->SetKeyKey/*c*/,
+                               (!data->SetKeyUp ? 0 : *data->SetKeyUp)/*up*/));
 
-  return (GetPhoneModelData(model)->model);
-}
+       case GOP_HandleString:
+               return(GSM->HandleString(data->HandleString/*s*/));
 
-int GetModelFeature (featnum_index num)
-{
-  static char model[64];
+       case GOP_AnswerCall:
+               return(GSM->AnswerCall((!data->CallNo ? 0 : *data->CallNo)/*s*/));
 
-  while (GSM->GetModel(model)  != GE_NONE) sleep(1);
 
-  return (GetPhoneModelData(model)->features[num]);
+       default:
+               return(GE_NOTIMPLEMENTED);
+       }
 }
 
-int LogAvailable=-1; //-1 not checked earlier, 0 not, 1 yes
-char *logfilename;
+/* Initialise interface to the phone. Model number should be a string such as
+   3810, 5110, 6110 etc. Device is the serial port to use e.g. /dev/ttyS0, the
+   user must have write permission to the device. */
 
-bool AppendLog(u8 *buffer, int length,bool format)
+static GSM_Error register_phone(GSM_Phone *phone, char *model, char *setupmodel, GSM_Statemachine *sm)
 {
-  FILE *file=NULL;
-  char buffer2[50001];
-  int i;
-
-  struct CFG_Header *cfg_info;
-  char *LogFile;       
-
-  if (LogAvailable==-1) {
-
-    LogAvailable=0;
-
-    cfg_info=CFG_FindGnokiirc();
-    if (cfg_info==NULL) return false;
+       GSM_Data data;
+       GSM_Data *p_data;
+       if (setupmodel) {
+               GSM_DataClear(&data);
+               data.Model = setupmodel;
+               p_data = &data;
+       } else {
+               p_data = NULL;
+       }
+       sm->Phone=*phone;
+       if (strstr(phone->Info.Models, model) != NULL)
+               return phone->Functions(GOP_Init, p_data, sm);
+       return GE_UNKNOWNMODEL;
+}
 
-    LogFile = CFG_Get(cfg_info, "global", "logfile");
-    if (LogFile) {
-      LogAvailable=1;
-      logfilename=LogFile;
+#define MODULE(x) { \
+       extern GSM_Functions x##_Functions; \
+       extern GSM_Information x##_Information; \
+       extern bool x##_LinkOK; \
+       if (strstr(x##_Information.Models, model) != NULL) { \
+               GSM = & x##_Functions; \
+               GSM_Info = & x##_Information; \
+               GSM_LinkOK = & x##_LinkOK; \
+               return (GSM->Initialise(device, initlength, connection, rlp_callback)); \
+       } \
+}
 
-      file=fopen(logfilename, "a+");
+#define REGISTER_PHONE(x, y) { \
+        extern GSM_Phone phone_##x; \
+        if ((ret = register_phone(&phone_##x, model, y, sm)) != GE_UNKNOWNMODEL) \
+                return ret; \
+ } 
+GSM_Error GSM_Initialise(char *model, char *device, char *initlength, GSM_ConnectionType connection, void (*rlp_callback)(RLP_F96Frame *frame), GSM_Statemachine *sm)
+{
+        GSM_Error ret;
+       compat_Functions_Statemachine=sm;
+#ifndef WIN32  /* MB21 not supported in win32 */
+       if (strstr("2110", model)) {
+               extern GSM_Phone phone_nokia_2110;
+               memcpy(&(sm->Phone), &phone_nokia_2110, sizeof(GSM_Phone));
+               sm->Phone.Functions(GOP_Init, NULL, sm);
+       }
+       MODULE(N2110);
+        GSM_LinkOK = &LinkAlwaysOK;
+        sm->Link.ConnectionType=connection;
+        sm->Link.InitLength=atoi(initlength);
+        strcpy(sm->Link.PortDevice,device);
+       GSM=&compat_Functions;
+        REGISTER_PHONE(nokia_7110, NULL);
+        REGISTER_PHONE(at_hw, model);  /* FIXME: why 7110 does not to set sm->Model? */
+        REGISTER_PHONE(cimd, model);   /* FIXME: why 7110 does not to set sm->Model? */
+#if 0
+       REGISTER_PHONE(nokia_3110, NULL);
+#endif
 
-      /* We have first entry in this session and too large file */
-      if (fread( buffer2, 1, 50000,file )==50000) {
-        fclose(file);
-        file=fopen(logfilename, "w");
-      }
-    }
-  } else {
-    if (LogAvailable==1) {
-      file=fopen(logfilename, "a");
-    }
-  }
-  
-  if (LogAvailable==1) {
-    for (i=0;i<length;i++) {
-      if (format) {
-        fprintf(file, "%02x",buffer[i]);
-        switch (buffer[i]) {
-          case 0x09:fprintf(file,_(" |"));break;
-          default:
-            if (isprint(buffer[i])) fprintf(file, _("%c|"),buffer[i]);
-                               else fprintf(file, _(" |"));
-            break;
-        } 
-      } else {
-        fprintf(file, "%c",buffer[i]);
-      }
-    }
-    if (format) fprintf(file, "\n");
-    fclose(file);
-  }
-
-  return (LogAvailable==1);
-}
-
-bool AppendLogText(u8 *buffer,bool format)
-{
-  return AppendLog(buffer,strlen(buffer),format);
+#endif /* WIN32 */ 
+        return (GE_UNKNOWNMODEL);
 }