/* $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 possible hiding the model specific details. The underlying code should run in it's own thread to allow communications to the phone to be run independantly of mailing code that calls these API functions. 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 #include #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" /* 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. */ GSM_Functions *GSM; /* Define pointer to the GSM_Information structure used by external code to obtain information that varies from model to model. This structure is also defined in gsm-common.h */ GSM_Information *GSM_Info; /* 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); } static void compat_Functions_Terminate(void) { GSM_Data data; /* void */ INVOKE_COMPAT_FUNCTIONS_SM(GOP_Terminate); } static GSM_Error compat_Functions_GetMemoryLocation( GSM_PhonebookEntry *entry ) { BODY_COMPAT_FUNCTIONS_SM1(PhonebookEntry,entry,GOP_ReadPhonebook); } static GSM_Error compat_Functions_WritePhonebookLocation( GSM_PhonebookEntry *entry ) { BODY_COMPAT_FUNCTIONS_SM1(PhonebookEntry,entry,GOP_WritePhonebook); } static GSM_Error compat_Functions_GetSpeedDial( GSM_SpeedDial *entry ) { BODY_COMPAT_FUNCTIONS_SM1(SpeedDial,entry,GOP_GetSpeedDial); } static GSM_Error compat_Functions_SetSpeedDial( GSM_SpeedDial *entry ) { BODY_COMPAT_FUNCTIONS_SM1(SpeedDial,entry,GOP_SetSpeedDial); } static GSM_Error compat_Functions_GetMemoryStatus( GSM_MemoryStatus *Status ) { BODY_COMPAT_FUNCTIONS_SM1(MemoryStatus,Status,GOP_GetMemoryStatus); } static GSM_Error compat_Functions_GetSMSStatus( GSM_SMSStatus *Status ) { BODY_COMPAT_FUNCTIONS_SM1(SMSStatus,Status,GOP_GetSMSStatus); } static GSM_Error compat_Functions_GetSMSCenter( GSM_MessageCenter *MessageCenter ) { BODY_COMPAT_FUNCTIONS_SM1(MessageCenter,MessageCenter,GOP_GetSMSCenter); } static GSM_Error compat_Functions_SetSMSCenter( GSM_MessageCenter *MessageCenter ) { BODY_COMPAT_FUNCTIONS_SM1(MessageCenter,MessageCenter,GOP_SetSMSCenter); } static GSM_Error compat_Functions_GetSMSMessage( GSM_SMSMessage *Message ) { BODY_COMPAT_FUNCTIONS_SM1(SMSMessage,Message,GOP_GetSMS); } static GSM_Error compat_Functions_DeleteSMSMessage( GSM_SMSMessage *Message ) { BODY_COMPAT_FUNCTIONS_SM1(SMSMessage,Message,GOP_DeleteSMS); } static GSM_Error compat_Functions_SendSMSMessage( GSM_SMSMessage *Message ) { BODY_COMPAT_FUNCTIONS_SM1(SMSMessage,Message,GOP_SendSMS); } static GSM_Error compat_Functions_SaveSMSMessage( GSM_SMSMessage *Message ) { BODY_COMPAT_FUNCTIONS_SM1(SMSMessage,Message,GOP_SaveSMS); } static GSM_Error compat_Functions_GetRFLevel( GSM_RFUnits *units, float *level ) { BODY_COMPAT_FUNCTIONS_SM2(RFUnits,units,RFLevel,level,GOP_GetRFLevel); } static GSM_Error compat_Functions_GetBatteryLevel( GSM_BatteryUnits *units, float *level ) { BODY_COMPAT_FUNCTIONS_SM2(BatteryUnits,units,BatteryLevel,level,GOP_GetBatteryLevel); } static GSM_Error compat_Functions_GetPowerSource( GSM_PowerSource *source ) { BODY_COMPAT_FUNCTIONS_SM1(PowerSource,source,GOP_GetPowersource); } static GSM_Error compat_Functions_GetDisplayStatus( int *Status ) { BODY_COMPAT_FUNCTIONS_SM1(DisplayStatus,Status,GOP_GetDisplayStatus); } static GSM_Error compat_Functions_EnterSecurityCode( GSM_SecurityCode Code ) { BODY_COMPAT_FUNCTIONS_SM1(SecurityCode,&Code,GOP_EnterSecurityCode); } /* 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); } static GSM_Error compat_Functions_GetIMEI( char *imei ) { BODY_COMPAT_FUNCTIONS_SM1(Imei,imei,GOP_GetImei); } static GSM_Error compat_Functions_GetRevision( char *revision ) { BODY_COMPAT_FUNCTIONS_SM1(Revision,revision,GOP_GetRevision); } static GSM_Error compat_Functions_GetModel( char *model ) { BODY_COMPAT_FUNCTIONS_SM1(Model,model,GOP_GetModel); } static GSM_Error compat_Functions_GetManufacturer( char *manufacturer ) { BODY_COMPAT_FUNCTIONS_SM1(Manufacturer,manufacturer,GOP_GetManufacturer); } static GSM_Error compat_Functions_GetDateTime( GSM_DateTime *date_time) { BODY_COMPAT_FUNCTIONS_SM1(DateTime,date_time,GOP_GetDateTime); } static GSM_Error compat_Functions_SetDateTime( GSM_DateTime *date_time) { BODY_COMPAT_FUNCTIONS_SM1(DateTime,date_time,GOP_SetDateTime); } 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); } 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); } 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); } static GSM_Error compat_Functions_GetIncomingCallNr( char *Number ) { BODY_COMPAT_FUNCTIONS_SM1(IncomingCallNr,Number,GOP_GetIncomingCallNr); } static GSM_Error compat_Functions_GetNetworkInfo ( GSM_NetworkInfo *NetworkInfo ) { BODY_COMPAT_FUNCTIONS_SM1(NetworkInfo,NetworkInfo,GOP_GetNetworkInfo); } static GSM_Error compat_Functions_GetCalendarNote ( GSM_CalendarNote *CalendarNote) { BODY_COMPAT_FUNCTIONS_SM1(CalendarNote,CalendarNote,GOP_GetCalendarNote); } static GSM_Error compat_Functions_WriteCalendarNote ( GSM_CalendarNote *CalendarNote) { BODY_COMPAT_FUNCTIONS_SM1(CalendarNote,CalendarNote,GOP_WriteCalendarNote); } static GSM_Error compat_Functions_DeleteCalendarNote ( GSM_CalendarNote *CalendarNote) { BODY_COMPAT_FUNCTIONS_SM1(CalendarNote,CalendarNote,GOP_DeleteCalendarNote); } static GSM_Error compat_Functions_NetMonitor ( unsigned char mode, char *Screen ) { BODY_COMPAT_FUNCTIONS_SM2(NetMonitorMode,&mode,NetMonitorScreen,Screen,GOP_NetMonitor); } static GSM_Error compat_Functions_SendDTMF ( char *String ) { BODY_COMPAT_FUNCTIONS_SM1(DTMF,String,GOP_SendDTMF); } 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); } static GSM_Error compat_Functions_SetRingtone ( GSM_Ringtone *ringtone ) { BODY_COMPAT_FUNCTIONS_SM1(Ringtone,ringtone,GOP_SetRingtone); } static GSM_Error compat_Functions_Reset ( unsigned char type ) { BODY_COMPAT_FUNCTIONS_SM1(ResetType,&type,GOP_Reset); } static GSM_Error compat_Functions_GetProfile ( GSM_Profile *Profile ) { BODY_COMPAT_FUNCTIONS_SM1(Profile,Profile,GOP_GetProfile); } static GSM_Error compat_Functions_SetProfile ( GSM_Profile *Profile ) { BODY_COMPAT_FUNCTIONS_SM1(Profile,Profile,GOP_SetProfile); } /* 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); } 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); } static GSM_Error compat_Functions_DisableCellBroadcast ( void ) { BODY_COMPAT_FUNCTIONS_SM0(GOP_DisableCellBroadcast); } 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); } 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); case GOP_Terminate: GSM->Terminate(); return(GE_NONE); case GOP_ReadPhonebook: return(GSM->GetMemoryLocation(data->PhonebookEntry/*entry*/)); case GOP_WritePhonebook: return(GSM->WritePhonebookLocation(data->PhonebookEntry/*entry*/)); case GOP_GetSpeedDial: return(GSM->GetSpeedDial(data->SpeedDial/*entry*/)); case GOP_SetSpeedDial: return(GSM->SetSpeedDial(data->SpeedDial/*entry*/)); case GOP_GetMemoryStatus: return(GSM->GetMemoryStatus(data->MemoryStatus/*Status*/)); case GOP_GetSMSStatus: return(GSM->GetSMSStatus(data->SMSStatus/*Status*/)); case GOP_GetSMSCenter: return(GSM->GetSMSCenter(data->MessageCenter/*MessageCenter*/)); case GOP_SetSMSCenter: return(GSM->SetSMSCenter(data->MessageCenter/*MessageCenter*/)); case GOP_GetSMS: return(GSM->GetSMSMessage(data->SMSMessage/*Message*/)); case GOP_DeleteSMS: return(GSM->DeleteSMSMessage(data->SMSMessage/*Message*/)); case GOP_SendSMS: return(GSM->SendSMSMessage(data->SMSMessage/*Message*/)); case GOP_SaveSMS: return(GSM->SaveSMSMessage(data->SMSMessage/*Message*/)); case GOP_GetRFLevel: return(GSM->GetRFLevel(data->RFUnits/*units*/,data->RFLevel/*level*/)); case GOP_GetBatteryLevel: return(GSM->GetBatteryLevel(data->BatteryUnits/*units*/,data->BatteryLevel/*level*/)); case GOP_GetPowersource: return(GSM->GetPowerSource(data->PowerSource/*source*/)); case GOP_GetDisplayStatus: return(GSM->GetDisplayStatus(data->DisplayStatus/*Status*/)); case GOP_EnterSecurityCode: return(GSM->EnterSecurityCode(*data->SecurityCode/*Code*/)); case GOP_GetSecurityCodeStatus: { int status_local=*data->SecurityCodeStatus; GSM_Error err; err=GSM->GetSecurityCodeStatus(&status_local); *data->SecurityCodeStatus=status_local; return(err); } case GOP_GetImei: return(GSM->GetIMEI(data->Imei/*imei*/)); case GOP_GetRevision: return(GSM->GetRevision(data->Revision/*revision*/)); case GOP_GetModel: return(GSM->GetModel(data->Model/*model*/)); case GOP_GetManufacturer: return(GSM->GetManufacturer(data->Manufacturer/*manufacturer*/)); case GOP_GetDateTime: return(GSM->GetDateTime(data->DateTime/*date_time*/)); case GOP_SetDateTime: return(GSM->SetDateTime(data->DateTime/*date_time*/)); case GOP_GetAlarm: return(GSM->GetAlarm((!data->AlarmNumber ? 0 : *data->AlarmNumber)/*alarm_number*/, data->AlarmDateTime/*date_time*/)); case GOP_SetAlarm: return(GSM->SetAlarm((!data->AlarmNumber ? 0 : *data->AlarmNumber)/*alarm_number*/, data->AlarmDateTime/*date_time*/)); case GOP_DialVoice: return(GSM->DialVoice(data->VoiceNumber/*Number*/)); case GOP_DialData: return(GSM->DialData(data->DataNumber/*Number*/, (!data->DataType ? -1 : *data->DataType)/*type*/, data->DataCallPassUp/*callpassup*/)); case GOP_GetIncomingCallNr: return(GSM->GetIncomingCallNr(data->IncomingCallNr/*Number*/)); case GOP_GetNetworkInfo: return(GSM->GetNetworkInfo(data->NetworkInfo/*NetworkInfo*/)); case GOP_GetCalendarNote: return(GSM->GetCalendarNote(data->CalendarNote/*CalendarNote*/)); case GOP_WriteCalendarNote: return(GSM->WriteCalendarNote(data->CalendarNote/*CalendarNote*/)); case GOP_DeleteCalendarNote: return(GSM->DeleteCalendarNote(data->CalendarNote/*CalendarNote*/)); case GOP_NetMonitor: return(GSM->NetMonitor((!data->NetMonitorMode ? 0 : *data->NetMonitorMode)/*mode*/, data->NetMonitorScreen/*Screen*/)); case GOP_SendDTMF: return(GSM->SendDTMF(data->DTMF/*String*/)); case GOP_GetBitmap: return(GSM->GetBitmap(data->Bitmap/*Bitmap*/)); case GOP_SetBitmap: return(GSM->SetBitmap(data->Bitmap/*Bitmap*/)); case GOP_SetRingtone: return(GSM->SetRingtone(data->Ringtone/*ringtone*/)); case GOP_Reset: return(GSM->Reset((!data->ResetType ? 0x03 : *data->ResetType)/*type*/)); case GOP_GetProfile: return(GSM->GetProfile(data->Profile/*Profile*/)); case GOP_SetProfile: return(GSM->SetProfile(data->Profile/*Profile*/)); /* 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*/)); case GOP_CancelCall: return(GSM->CancelCall()); case GOP_EnableDisplayOutput: return(GSM->EnableDisplayOutput()); case GOP_DisableDisplayOutput: return(GSM->DisableDisplayOutput()); case GOP_EnableCellBroadcast: return(GSM->EnableCellBroadcast()); case GOP_DisableCellBroadcast: return(GSM->DisableCellBroadcast()); case GOP_ReadCellBroadcast: return(GSM->ReadCellBroadcast(data->CBMessage/*Message*/)); case GOP_SetKey: return(GSM->SetKey(*data->SetKeyKey/*c*/, (!data->SetKeyUp ? 0 : *data->SetKeyUp)/*up*/)); case GOP_HandleString: return(GSM->HandleString(data->HandleString/*s*/)); case GOP_AnswerCall: return(GSM->AnswerCall((!data->CallNo ? 0 : *data->CallNo)/*s*/)); default: return(GE_NOTIMPLEMENTED); } } /* 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. */ static GSM_Error register_phone(GSM_Phone *phone, char *model, char *setupmodel, GSM_Statemachine *sm) { 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; } #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)); \ } \ } #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 #endif /* WIN32 */ return (GE_UNKNOWNMODEL); }