+
+/* This enum is used for display status. */
+
+typedef enum {
+ DS_Call_In_Progress, /* Call in progress. */
+ DS_Unknown, /* The meaning is unknown now :-( */
+ DS_Unread_SMS, /* There is Unread SMS. */
+ DS_Voice_Call, /* Voice call active. */
+ DS_Fax_Call, /* Fax call active. */
+ DS_Data_Call, /* Data call active. */
+ DS_Keyboard_Lock, /* Keyboard lock status. */
+ DS_SMS_Storage_Full /* Full SMS Memory. */
+} DisplayStatusEntity;
+
+/* Bitmap types. */
+
+typedef enum {
+ GSM_None=0,
+ GSM_StartupLogo,
+ GSM_OperatorLogo,
+ GSM_CallerLogo,
+ GSM_PictureImage,
+ GSM_WelcomeNoteText,
+ GSM_DealerNoteText
+} GSM_Bitmap_Types;
+
+#define GSM_MAX_BITMAP_SIZE 864
+
+/* Structure to hold incoming/outgoing bitmaps (and welcome-notes). */
+
+typedef struct {
+ u8 height; /* Bitmap height (pixels) */
+ u8 width; /* Bitmap width (pixels) */
+ u16 size; /* Bitmap size (bytes) */
+ GSM_Bitmap_Types type; /* Bitmap type */
+ char netcode[7]; /* Network operator code */
+ char text[256]; /* Text used for welcome-note or callergroup name */
+ char dealertext[256]; /* Text used for dealer welcome-note */
+ bool dealerset; /* Is dealer welcome-note set now ? */
+ unsigned char bitmap[GSM_MAX_BITMAP_SIZE]; /* Actual Bitmap */
+ char number; /* Caller group number */
+ char ringtone; /* Ringtone no sent with caller group */
+} GSM_Bitmap;
+
+
+/* NoteValue is encoded as octave(scale)*14 + note */
+/* where for note: c=0, d=2, e=4 .... */
+/* ie. c#=1 and 5 and 13 are invalid */
+/* note=255 means a pause */
+
+#define MAX_RINGTONE_NOTES 256
+
+/* Structure to hold note of ringtone. */
+
+typedef struct {
+ u8 duration;
+ u8 note;
+} GSM_RingtoneNote;
+
+/* Structure to hold ringtones. */
+
+typedef struct {
+ char name[20];
+ u8 tempo;
+ u8 NrNotes;
+ GSM_RingtoneNote notes[MAX_RINGTONE_NOTES];
+} GSM_Ringtone;
+
+/* Structure to hold profile entries. */
+
+typedef struct {
+ int Number; /* The number of the profile. */
+ char Name[40]; /* The name of the profile. */
+ int DefaultName; /* 0-6, when default name is used, -1, when not. */
+ int KeypadTone; /* Volume level for keypad tones. */
+ int Lights; /* Lights on/off. */
+ int CallAlert; /* Incoming call alert. */
+ int Ringtone; /* Ringtone for incoming call alert. */
+ int Volume; /* Volume of the ringing. */
+ int MessageTone; /* The tone for message indication. */
+ int WarningTone; /* The tone for warning messages. */
+ int Vibration; /* Vibration? */
+ int CallerGroups; /* CallerGroups. */
+ int AutomaticAnswer; /* Does the phone auto-answer incoming call? */
+} GSM_Profile;
+
+
+#define FO_SUBMIT 0x01
+#define FO_RD 0x40
+#define FO_VPF_NONE 0x00
+#define FO_VPF_REL 0x10
+#define FO_VPF_ABS 0x18
+#define FO_VPF_ENH 0x08
+#define FO_SRR 0x20
+#define FO_UDHI 0x40
+#define FO_RP 0x80
+#define FO_DEFAULT (FO_SUBMIT | FO_VPF_REL | FO_SRR)
+
+#define PID_DEFAULT 0x00
+#define PID_TYPE0 0x40
+#define PID_REPLACE1 0x41
+#define PID_REPLACE2 0x42
+#define PID_REPLACE3 0x43
+#define PID_REPLACE4 0x44
+#define PID_REPLACE5 0x45
+#define PID_REPLACE6 0x46
+#define PID_REPLACE7 0x47
+#define PID_RETURN_CALL 0x5f
+
+#define DCS_DEFAULT 0x00
+#define DCS_MSG_WAIT_VOICE_DISCARD 0xc8
+#define DCS_MSG_WAIT_VOICE_OFF 0xc0
+#define DCS_MSG_WAIT_VOICE_STORE 0xd8
+#define DCS_DATA 0xf4
+#define DCS_CLASS0 0xf0
+#define DCS_CLASS1 0xf1
+#define DCS_CLASS2 0xf2
+#define DCS_CLASS3 0xf3
+
+/* Limits for IMEI, Revision and Model string storage. */
+
+#define GSM_MAX_IMEI_LENGTH (20)
+#define GSM_MAX_REVISION_LENGTH (16)
+#define GSM_MAX_MODEL_LENGTH (64)
+#define GSM_MAX_MANUFACTURER_LENGTH (36)
+
+
+
+/* This is a generic holder for high level information - eg a GSM_Bitmap */
+
+typedef struct {
+ GSM_SMSMessage *SMSMessage;
+ GSM_PhonebookEntry *PhonebookEntry;
+ GSM_SpeedDial *SpeedDial;
+ GSM_MemoryStatus *MemoryStatus;
+ GSM_SMSStatus *SMSStatus;
+ GSM_MessageCenter *MessageCenter;
+ char *Imei;
+ char *Revision;
+ char *Model;
+ char *Manufacturer;
+ GSM_NetworkInfo *NetworkInfo;
+ GSM_CalendarNote *CalendarNote;
+ GSM_Bitmap *Bitmap;
+ char *BitmapDest;
+ GSM_Ringtone *Ringtone;
+ char *RingtoneDest;
+ GSM_Profile *Profile;
+ GSM_BatteryUnits *BatteryUnits;
+ float *BatteryLevel;
+ GSM_RFUnits *RFUnits;
+ float *RFLevel;
+ GSM_Error (*OutputFn)(char *Display, char *Indicators);
+ char *IncomingCallNr;
+ GSM_PowerSource *PowerSource;
+ GSM_SecurityCode *SecurityCode;
+ GSM_SecurityCodeType *SecurityCodeStatus;
+ GSM_DateTime *DateTime;
+ int *AlarmNumber;
+ GSM_DateTime *AlarmDateTime;
+ char *VoiceNumber;
+ char *DataNumber;
+ char *DataType;
+ void (*DataCallPassUp)(char c);
+ unsigned char *NetMonitorMode;
+ char *NetMonitorScreen;
+ char *DTMF;
+ char *ResetType;
+ RLP_F96Frame *RLPFrame;
+ bool *RLPFrame_out_dtx;
+ GSM_CBMessage *CBMessage;
+ int *SetKeyKey;
+ int *SetKeyUp;
+ char *HandleString;
+ char *CallNo;
+ int *DisplayStatus;
+} GSM_Data;
+
+
+/* Global structures intended to be independant of phone etc */
+/* Obviously currently rather Nokia biased but I think most things */
+/* (eg at commands) can be enumerated */
+
+
+/* A structure to hold information about the particular link */
+/* The link comes 'under' the phone */
+typedef struct {
+ char PortDevice[20]; /* The port device */
+ int InitLength; /* Number of chars sent to sync the serial port */
+ GSM_ConnectionType ConnectionType; /* Connection type, serial, ir etc */
+
+ /* A regularly called loop function */
+ /* timeout can be used to make the function block or not */
+ GSM_Error (*Loop)(struct timeval *timeout);
+
+ /* A pointer to the function used to send out a message */
+ /* This is used by the phone specific code to send a message over the link */
+ GSM_Error (*SendMessage)(u16 messagesize, u8 messagetype, void *message);
+
+} GSM_Link;
+
+
+/* Small structure used in GSM_Phone */
+/* Messagetype is passed to the function in case it is a 'generic' one */
+typedef struct {
+ u8 MessageType;
+ GSM_Error (*Functions)(int messagetype, unsigned char *buffer, int length, GSM_Data *data);
+} GSM_IncomingFunctionType;
+
+typedef enum {
+ GOP_Init,
+ GOP_Terminate,
+ GOP_GetModel,
+ GOP_GetRevision,
+ GOP_GetImei,
+ GOP_GetManufacturer,
+ GOP_Identify,
+ GOP_GetBitmap,
+ GOP_SetBitmap,
+ GOP_SetRingtone,
+ GOP_GetBatteryLevel,
+ GOP_GetRFLevel,
+ GOP_DisplayOutput,
+ GOP_GetMemoryStatus,
+ GOP_ReadPhonebook,
+ GOP_WritePhonebook,
+ GOP_GetPowersource,
+ GOP_GetDisplayStatus,
+ GOP_EnterSecurityCode,
+ GOP_GetSecurityCodeStatus,
+ GOP_GetAlarm,
+ GOP_SetAlarm,
+ GOP_DialVoice,
+ GOP_DialData,
+ GOP_GetSMSStatus,
+ GOP_SetSMSStatus,
+ GOP_GetIncomingCallNr,
+ GOP_GetNetworkInfo,
+ GOP_GetSMS,
+ GOP_DeleteSMS,
+ GOP_SendSMS,
+ GOP_SaveSMS,
+ GOP_GetSpeedDial,
+ GOP_SetSpeedDial,
+ GOP_GetSMSCenter,
+ GOP_SetSMSCenter,
+ GOP_GetDateTime,
+ GOP_SetDateTime,
+ GOP_GetCalendarNote,
+ GOP_WriteCalendarNote,
+ GOP_DeleteCalendarNote,
+ GOP_NetMonitor,
+ GOP_SendDTMF,
+ GOP_Reset,
+ GOP_GetProfile,
+ GOP_SetProfile,
+ GOP_SendRLPFrame,
+ GOP_CancelCall,
+ GOP_EnableDisplayOutput,
+ GOP_DisableDisplayOutput,
+ GOP_EnableCellBroadcast,
+ GOP_DisableCellBroadcast,
+ GOP_ReadCellBroadcast,
+ GOP_SetKey,
+ GOP_HandleString,
+ GOP_AnswerCall,
+ GOP_Max /* don't append anything after this entry */
+} GSM_Operation;
+
+/* This structure contains the 'callups' needed by the statemachine */
+/* to deal with messages from the phone and other information */
+
+typedef struct _GSM_Statemachine GSM_Statemachine;
+
+typedef struct {
+ /* These make up a list of functions, one for each message type and NULL terminated */
+ GSM_IncomingFunctionType *IncomingFunctions;
+ GSM_Error (*DefaultFunction)(int messagetype, unsigned char *buffer, int length);
+ GSM_Information Info;
+ GSM_Error (*Functions)(GSM_Operation op, GSM_Data *data, GSM_Statemachine *state);
+} GSM_Phone;
+
+
+/* The states the statemachine can take */
+
+typedef enum {
+ Startup, /* Not yet initialised */
+ Initialised, /* Ready! */
+ MessageSent, /* A command has been sent to the link(phone) */
+ WaitingForResponse, /* We are waiting for a response from the link(phone) */
+ ResponseReceived /* A response has been received - waiting for the phone layer to collect it */
+} GSM_State;
+
+/* How many message types we can wait for at one */
+#define SM_MAXWAITINGFOR 3
+
+
+/* All properties of the state machine */
+
+struct _GSM_Statemachine{
+ GSM_State CurrentState;
+ GSM_Link Link;
+ GSM_Phone Phone;
+
+ /* Store last message for resend purposes */
+ u8 LastMsgType;
+ u16 LastMsgSize;
+ void *LastMsg;
+
+ /* The responses we are waiting for */
+ unsigned char NumWaitingFor;
+ unsigned char NumReceived;
+ unsigned char WaitingFor[SM_MAXWAITINGFOR];
+ GSM_Error ResponseError[SM_MAXWAITINGFOR];
+ /* Data structure to be filled in with the response */
+ GSM_Data *Data[SM_MAXWAITINGFOR];
+};
+
+
+
+/* Define the structure used to hold pointers to the various API functions.
+ This is in effect the master list of functions provided by the gnokii API.
+ Modules containing the model specific code each contain one of these
+ structures which is "filled in" with the corresponding function within the
+ model specific code. If a function is not supported or not implemented, a
+ generic not implemented function is used to return a GE_NOTIMPLEMENTED
+ error code. */
+
+typedef struct {
+
+ /* FIXME: comment this. */
+
+ GSM_Error (*Initialise)( char *port_device, char *initlength,
+ GSM_ConnectionType connection,
+ void (*rlp_callback)(RLP_F96Frame *frame));
+
+ void (*Terminate)(void);
+
+ GSM_Error (*GetMemoryLocation)( GSM_PhonebookEntry *entry );
+
+ GSM_Error (*WritePhonebookLocation)( GSM_PhonebookEntry *entry );
+
+ GSM_Error (*GetSpeedDial)( GSM_SpeedDial *entry);
+
+ GSM_Error (*SetSpeedDial)( GSM_SpeedDial *entry);
+
+ GSM_Error (*GetMemoryStatus)( GSM_MemoryStatus *Status);
+
+ GSM_Error (*GetSMSStatus)( GSM_SMSStatus *Status);
+
+ GSM_Error (*GetSMSCenter)( GSM_MessageCenter *MessageCenter );
+
+ GSM_Error (*SetSMSCenter)( GSM_MessageCenter *MessageCenter );
+
+ GSM_Error (*GetSMSMessage)( GSM_SMSMessage *Message );
+
+ GSM_Error (*DeleteSMSMessage)( GSM_SMSMessage *Message );
+
+ GSM_Error (*SendSMSMessage)( GSM_SMSMessage *Message );
+
+ GSM_Error (*SaveSMSMessage)( GSM_SMSMessage *Message );
+
+ /* If units is set to a valid GSM_RFUnits value, the code
+ will return level in these units if it is able. Otherwise
+ value will be returned as GRF_Arbitary. If phone doesn't
+ support GetRFLevel, function returns GE_NOTSUPPORTED */
+ GSM_Error (*GetRFLevel)( GSM_RFUnits *units, float *level );
+
+ /* Works the same as GetRFLevel, except returns battery
+ level if known. */
+ GSM_Error (*GetBatteryLevel)( GSM_BatteryUnits *units, float *level );
+
+ GSM_Error (*GetPowerSource)( GSM_PowerSource *source);
+
+ GSM_Error (*GetDisplayStatus)( int *Status);
+
+ GSM_Error (*EnterSecurityCode)( GSM_SecurityCode Code);
+
+ GSM_Error (*GetSecurityCodeStatus)( int *Status );
+
+ GSM_Error (*GetIMEI)( char *imei );
+
+ GSM_Error (*GetRevision)( char *revision );
+
+ GSM_Error (*GetModel)( char *model );
+
+ GSM_Error (*GetManufacturer)( char *manufacturer );
+
+ GSM_Error (*GetDateTime)( GSM_DateTime *date_time);
+
+ GSM_Error (*SetDateTime)( GSM_DateTime *date_time);
+
+ GSM_Error (*GetAlarm)( int alarm_number, GSM_DateTime *date_time );
+
+ GSM_Error (*SetAlarm)( int alarm_number, GSM_DateTime *date_time );
+
+ GSM_Error (*DialVoice)( char *Number);
+
+ GSM_Error (*DialData)( char *Number, char type, void (* callpassup)(char c));
+
+ GSM_Error (*GetIncomingCallNr)( char *Number );
+
+ GSM_Error (*GetNetworkInfo) ( GSM_NetworkInfo *NetworkInfo );
+
+ GSM_Error (*GetCalendarNote) ( GSM_CalendarNote *CalendarNote);
+
+ GSM_Error (*WriteCalendarNote) ( GSM_CalendarNote *CalendarNote);
+
+ GSM_Error (*DeleteCalendarNote) ( GSM_CalendarNote *CalendarNote);
+
+ GSM_Error (*NetMonitor) ( unsigned char mode, char *Screen );
+
+ GSM_Error (*SendDTMF) ( char *String );
+
+ GSM_Error (*GetBitmap) ( GSM_Bitmap *Bitmap );
+
+ GSM_Error (*SetBitmap) ( GSM_Bitmap *Bitmap );
+
+ GSM_Error (*SetRingtone) ( GSM_Ringtone *ringtone );
+
+ GSM_Error (*Reset) ( unsigned char type );
+
+ GSM_Error (*GetProfile) ( GSM_Profile *Profile );
+
+ GSM_Error (*SetProfile) ( GSM_Profile *Profile );
+
+ bool (*SendRLPFrame) ( RLP_F96Frame *frame, bool out_dtx );
+
+ GSM_Error (*CancelCall) ();
+
+ GSM_Error (*EnableDisplayOutput) ();
+
+ GSM_Error (*DisableDisplayOutput) ();
+
+ GSM_Error (*EnableCellBroadcast) ();
+
+ GSM_Error (*DisableCellBroadcast) ();
+
+ GSM_Error (*ReadCellBroadcast) ( GSM_CBMessage *Message );
+
+ GSM_Error (*SetKey) (int c, int up);
+
+ GSM_Error (*HandleString) (char *s);
+
+ GSM_Error (*AnswerCall) (char s);
+
+} GSM_Functions;
+
+typedef struct {
+ bool first; /* MUST be set to "true" during the first call of SMS_Deconcatenate() */
+ bool singleshot; /* no concatenation wrapping was needed */
+ unsigned sequence; /* =1 for the first part etc. */
+ u8 *sequencep; /* For updating inside-PDU header sequence number */
+ size_t cargoitems; /* How many items of MessageText fit in one SMS part */
+ } GSM_Deconcatenate_state;
+
+/* Undefined functions in fbus/mbus files */
+extern GSM_Error Unimplemented(void);
+#define UNIMPLEMENTED (void *) Unimplemented
+
+extern unsigned char GSM_Default_Alphabet[];
+
+/* Coding functions */
+extern void EncodeAscii (unsigned char* dest, const unsigned char* src, int len);
+extern void DecodeAscii (unsigned char* dest, const unsigned char* src, int len);
+extern void EncodeUnicode (unsigned char* dest, const unsigned char* src, int len);
+extern void DecodeUnicode (unsigned char* dest, const unsigned char* src, int len);
+
+extern unsigned char EncodeWithDefaultAlphabet(unsigned char);
+extern unsigned char DecodeWithDefaultAlphabet(unsigned char);
+extern wchar_t EncodeWithUnicodeAlphabet(unsigned char);
+extern unsigned char DecodeWithUnicodeAlphabet(wchar_t);
+extern GSM_MemoryType StrToMemoryType (const char *s);
+extern unsigned char SMS_Validity_to_VP(int Validity);
+extern int SMS_VP_to_Validity(GSM_SMSMessageValidity Validity);
+extern int SemiOctetPack(char *Number, unsigned char *Output);
+extern char *SemiOctetUnpack(char *dest,size_t destlen,u8 *Number,size_t nibbles);
+extern char *SemiOctetUnpack_static(u8 *Number,size_t nibbles);
+#define SEMIOCTETUNPACK_STATIC_BYTES(Number) (SemiOctetUnpack_static((Number)+1,*(Number)*2))
+#define SEMIOCTETUNPACK_STATIC_NIBBLES(Number) (SemiOctetUnpack_static((Number)+1,*(Number) ))
+extern int PackSevenBitsToEight(int UsedBits, unsigned char *input, unsigned char *output);
+extern int UnpackEightBitsToSeven(int offset, int in_length, int out_length,
+ unsigned char *input, unsigned char *output);
+extern GSM_Error SMS_SetupUDH(GSM_SMSMessage *sms,GSM_UDH UDHType);
+extern GSM_UDH SMS_DetectUDH(GSM_SMSMessage *sms);
+extern bool SMS_Deconcatenate(GSM_Deconcatenate_state *state,GSM_SMSMessage *sms,char *buf,size_t buflen,bool useudh);
+extern u8 *SMS_BlockFromHex(u8 *d,const char *s,size_t len);
+extern char *SMS_BlockToHex(char *d,const u8 *s,size_t len);
+
+inline void GSM_DataClear(GSM_Data *data);
+