-/*\r
-\r
- G N O K I I\r
-\r
- A Linux/Unix toolset and driver for Nokia mobile phones.\r
-\r
- Released under the terms of the GNU GPL, see file COPYING for more details.\r
-\r
- This file provides an API for accessing functions on the 6110 and similar\r
- phones.\r
-\r
-*/\r
-\r
-/* "Turn on" prototypes in n-6110.h */\r
-\r
-#define __n_6110_c \r
-\r
-/* System header files */\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#ifdef WIN32\r
- #include "misc_win32.h"\r
-#endif\r
- \r
-/* Various header file */\r
-#ifndef VC6\r
- #include "config.h"\r
-#endif\r
-\r
-#include "gsm-api.h"\r
-#include "gsm-coding.h"\r
-#include "newmodules/n6110.h"\r
-#include "newmodules/n7110.h"\r
-#include "protocol/fbus.h"\r
-#include "devices/device.h"\r
-\r\r/* Global variables used by code in gsm-api.c to expose the functions\r
- supported by this model of phone. */\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-/* Here we initialise model specific functions. */\r
-GSM_Functions N6110_Functions = {\r
- N6110_Initialise,\r
- N6110_DispatchMessage,\r
- NULL_Terminate,\r
- NULL_KeepAlive,\r
- N6110_GetMemoryLocation,\r
- N6110_WritePhonebookLocation,\r
- N6110_GetSpeedDial,\r
- N6110_SetSpeedDial,\r
- N6110_GetMemoryStatus,\r
- N6110_GetSMSStatus,\r
- N6110_GetSMSCenter,\r
- N6110_SetSMSCenter,\r
- N6110_GetSMSMessage,\r
- N6110_DeleteSMSMessage,\r
- N6110_SendSMSMessage,\r
- N6110_SaveSMSMessage,\r
- N6110_GetRFLevel,\r
- N6110_GetBatteryLevel,\r
- N6110_GetPowerSource,\r
- N6110_GetDisplayStatus,\r
- N6110_EnterSecurityCode,\r
- N6110_GetSecurityCodeStatus,\r
- N6110_GetSecurityCode,\r
- N6110_GetIMEI,\r
- N6110_GetRevision,\r
- N6110_GetModel,\r
- N6110_GetDateTime,\r
- N6110_SetDateTime,\r
- N6110_GetAlarm,\r
- N6110_SetAlarm,\r
- N6110_DialVoice,\r
- N6110_DialData,\r
- N6110_GetIncomingCallNr,\r
- N6110_GetNetworkInfo,\r
- N6110_GetCalendarNote,\r
- N6110_WriteCalendarNote,\r
- N6110_DeleteCalendarNote,\r
- N6110_NetMonitor,\r
- N6110_SendDTMF,\r
- N6110_GetBitmap,\r
- N6110_SetBitmap,\r
- N6110_SetRingTone,\r
- N6110_SetBinRingTone,\r
- N6110_GetBinRingTone,\r
- N6110_Reset,\r
- N6110_GetProfile,\r
- N6110_SetProfile,\r
- N6110_SendRLPFrame,\r
- N6110_CancelCall,\r
- N6110_PressKey,\r
- N6110_EnableDisplayOutput,\r
- N6110_DisableDisplayOutput,\r
- N6110_EnableCellBroadcast,\r
- N6110_DisableCellBroadcast,\r
- N6110_ReadCellBroadcast,\r
- N6110_PlayTone,\r
- N6110_GetProductProfileSetting,\r
- N6110_SetProductProfileSetting,\r
- N6110_GetOperatorName,\r
- N6110_SetOperatorName,\r
- N6110_GetVoiceMailbox,\r N6110_Tests,
+/*
+
+ G N O K I I
+
+ A Linux/Unix toolset and driver for Nokia mobile phones.
+
+ Released under the terms of the GNU GPL, see file COPYING for more details.
+
+ This file provides an API for accessing functions on the 6110 and similar
+ phones.
+
+*/
+
+/* "Turn on" prototypes in n-6110.h */
+
+#define __n_6110_c
+
+/* System header files */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef WIN32
+ #include "misc_win32.h"
+#endif
+
+/* Various header file */
+#ifndef VC6
+ #include "config.h"
+#endif
+
+#include "gsm-api.h"
+#include "gsm-coding.h"
+#include "newmodules/n6110.h"
+#include "newmodules/n7110.h"
+#include "protocol/fbus.h"
+#include "devices/device.h"
+/* Global variables used by code in gsm-api.c to expose the functions
+ supported by this model of phone. */
+
+
+
+
+
+
+
+/* Here we initialise model specific functions. */
+GSM_Functions N6110_Functions = {
+ N6110_Initialise,
+ N6110_DispatchMessage,
+ NULL_Terminate,
+ NULL_KeepAlive,
+ N6110_GetMemoryLocation,
+ N6110_WritePhonebookLocation,
+ N6110_GetSpeedDial,
+ N6110_SetSpeedDial,
+ N6110_GetMemoryStatus,
+ N6110_GetSMSStatus,
+ N6110_GetSMSCenter,
+ N6110_SetSMSCenter,
+ N6110_GetSMSMessage,
+ N6110_DeleteSMSMessage,
+ N6110_SendSMSMessage,
+ N6110_SaveSMSMessage,
+ N6110_GetRFLevel,
+ N6110_GetBatteryLevel,
+ N6110_GetPowerSource,
+ N6110_GetDisplayStatus,
+ N6110_EnterSecurityCode,
+ N6110_GetSecurityCodeStatus,
+ N6110_GetSecurityCode,
+ N6110_GetIMEI,
+ N6110_GetRevision,
+ N6110_GetModel,
+ N6110_GetDateTime,
+ N6110_SetDateTime,
+ N6110_GetAlarm,
+ N6110_SetAlarm,
+ N6110_DialVoice,
+ N6110_DialData,
+ N6110_GetIncomingCallNr,
+ N6110_GetNetworkInfo,
+ N6110_GetCalendarNote,
+ N6110_WriteCalendarNote,
+ N6110_DeleteCalendarNote,
+ N6110_NetMonitor,
+ N6110_SendDTMF,
+ N6110_GetBitmap,
+ N6110_SetBitmap,
+ N6110_SetRingTone,
+ N6110_SetBinRingTone,
+ N6110_GetBinRingTone,
+ N6110_Reset,
+ N6110_GetProfile,
+ N6110_SetProfile,
+ N6110_SendRLPFrame,
+ N6110_CancelCall,
+ N6110_PressKey,
+ N6110_EnableDisplayOutput,
+ N6110_DisableDisplayOutput,
+ N6110_EnableCellBroadcast,
+ N6110_DisableCellBroadcast,
+ N6110_ReadCellBroadcast,
+ N6110_PlayTone,
+ N6110_GetProductProfileSetting,
+ N6110_SetProductProfileSetting,
+ N6110_GetOperatorName,
+ N6110_SetOperatorName,
+ N6110_GetVoiceMailbox, N6110_Tests,
N6110_SimlockInfo,
UNIMPLEMENTED, //GetCalendarNotesInfo
N6110_GetSMSFolders,
N6110_CallDivert,
N6110_AnswerCall,
N6110_GetManufacturer
-};\r
-\r
-/* Mobile phone information */\r
-\r
-GSM_Information N6110_Information = {\r
- "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",\r
- /* Supported models in FBUS */\r
- "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",\r
- /* Supported models in MBUS */\r
- "6110|6130|6150|8210|8850",\r
- /* Supported models in FBUS over infrared */\r
- "",\r
- /* Supported models in FBUS over DLR3 */\r
+};
+
+/* Mobile phone information */
+
+GSM_Information N6110_Information = {
+ "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
+ /* Supported models in FBUS */
+ "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850|9210",
+ /* Supported models in MBUS */
+ "6110|6130|6150|8210|8850",
+ /* Supported models in FBUS over infrared */
+ "",
+ /* Supported models in FBUS over DLR3 */
"",
/* AT commands */
"8210|8850",
/* infrared sockets */
"6110|6130|6150|8210|8850",
- /* Supported models in FBUS over infrared with Tekram device */\r
- 4, /* Max RF Level */\r
- 0, /* Min RF Level */\r
- GRF_Arbitrary, /* RF level units */\r
- 4, /* Max Battery Level */\r
- 0, /* Min Battery Level */\r
- GBU_Arbitrary, /* Battery level units */\r
- GDT_DateTime, /* Have date/time support */\r
- GDT_TimeOnly, /* Alarm supports time only */\r
- 1 /* Only one alarm available */\r
-};\r
-\r
-const char *N6110_MemoryType_String [] = {\r
- "", /* 0x00 */\r
- "MT", /* 0x01 */\r
- "ME", /* 0x02 */\r
- "SM", /* 0x03 */\r
- "FD", /* 0x04 */\r
- "ON", /* 0x05 */\r
- "EN", /* 0x06 */\r
- "DC", /* 0x07 */\r
- "RC", /* 0x08 */\r
- "MC", /* 0x09 */\r
-};\r
-\r
-/* Magic bytes from the phone. */\r
-unsigned char MagicBytes[4] = { 0x00, 0x00, 0x00, 0x00 };\r
-\r
-/* For DisplayOutput */\r
-char PhoneScreen[5+1][27+1];\r
-int OldX=1000,OldY=0,NewX=0,NewY=0;\r
-\r
-void N6110_ReplyEnableExtendedCommands(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Answer for EnableExtendedSecurityCommands frame, meaning not known :-(\n"));\r
-#endif /* DEBUG */\r
-\r
- CurrentEnableExtendedCommandsError=GE_NONE; \r
-}\r
-\r
-/* If you set make some things (for example,\r
- change Security Code from phone's menu, disable and enable\r
- phone), it won't answer for 0x40 frame - you won't be able\r
- to play tones, get netmonitor, etc.\r
-\r
- This function do thing called "Enabling extended security commands" -\r
- it enables 0x40 frame functions.\r
-\r
- This frame can also some other things - see below */\r
-GSM_Error N6110_EnableExtendedCommands (unsigned char status)\r
-{\r
- unsigned char req[4] = { 0x00,\r
- 0x01,0x64, /* Enable extended commands request */\r
- 0x01 }; /* 0x01 - on, 0x00 - off,\r
- 0x03 & 0x04 - soft & hard reset,\r
- 0x06 - CONTACT SERVICE */\r
-\r
- /* 0x06 MAKES CONTACT SERVICE! BE CAREFULL! */\r
+ /* Supported models in FBUS over infrared with Tekram device */ "",
+ 4, /* Max RF Level */
+ 0, /* Min RF Level */
+ GRF_Arbitrary, /* RF level units */
+ 4, /* Max Battery Level */
+ 0, /* Min Battery Level */
+ GBU_Arbitrary, /* Battery level units */
+ GDT_DateTime, /* Have date/time support */
+ GDT_TimeOnly, /* Alarm supports time only */
+ 1 /* Only one alarm available */
+};
+
+const char *N6110_MemoryType_String [] = {
+ "", /* 0x00 */
+ "MT", /* 0x01 */
+ "ME", /* 0x02 */
+ "SM", /* 0x03 */
+ "FD", /* 0x04 */
+ "ON", /* 0x05 */
+ "EN", /* 0x06 */
+ "DC", /* 0x07 */
+ "RC", /* 0x08 */
+ "MC", /* 0x09 */
+};
+
+/* Magic bytes from the phone. */
+unsigned char MagicBytes[4] = { 0x00, 0x00, 0x00, 0x00 };
+
+/* For DisplayOutput */
+char PhoneScreen[5+1][27+1];
+int OldX=1000,OldY=0,NewX=0,NewY=0;
+
+void N6110_ReplyEnableExtendedCommands(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Answer for EnableExtendedSecurityCommands frame, meaning not known :-(\n"));
+#endif /* DEBUG */
+
+ CurrentEnableExtendedCommandsError=GE_NONE;
+}
+
+/* If you set make some things (for example,
+ change Security Code from phone's menu, disable and enable
+ phone), it won't answer for 0x40 frame - you won't be able
+ to play tones, get netmonitor, etc.
+
+ This function do thing called "Enabling extended security commands" -
+ it enables 0x40 frame functions.
+
+ This frame can also some other things - see below */
+GSM_Error N6110_EnableExtendedCommands (unsigned char status)
+{
+ unsigned char req[4] = { 0x00,
+ 0x01,0x64, /* Enable extended commands request */
+ 0x01 }; /* 0x01 - on, 0x00 - off,
+ 0x03 & 0x04 - soft & hard reset,
+ 0x06 - CONTACT SERVICE */
+
+ /* 0x06 MAKES CONTACT SERVICE! BE CAREFULL! */
/* When use 0x03 and had during session changed time & date
some phones (like 6150 or 6210) can ask for time & date after reset
or disable clock on the screen */
- if (status!=0x06) req[3] = status;\r
-\r
- return NULL_SendMessageSequence\r
- (50, &CurrentEnableExtendedCommandsError, 4, 0x40, req);\r
-}\r
-\r
-void N6110_ReplyIMEI(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#if defined WIN32 || !defined HAVE_SNPRINTF\r
- sprintf(Current_IMEI, "%s", MessageBuffer+4);\r
-#else\r
- snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+4);\r
-#endif\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: IMEI %s received\n"),Current_IMEI);\r
-#endif\r
-\r
- CurrentGetIMEIError=GE_NONE; \r
-}\r
-\r
-GSM_Error N6110_SendIMEIFrame()\r
-{\r
- unsigned char req[4] = {0x00, 0x01, 0x66, 0x00}; \r
-\r
- GSM_Error error;\r
-\r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
- \r
- return NULL_SendMessageSequence (20, &CurrentGetIMEIError, 4, 0x40, req);\r
-}\r
-\r
-void N6110_ReplyHW(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int i, j;\r
- \r
- if (MessageBuffer[3]==0x05) {\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Message: Hardware version received: "));\r
-#endif\r
-\r
- j=strlen(Current_Revision);\r
- Current_Revision[j++]=',';\r
- Current_Revision[j++]=' ';\r
- Current_Revision[j++]='H';\r
- Current_Revision[j++]='W';\r
- \r
- for (i=5;i<9;i++) {\r
-#ifdef DEBUG\r
- fprintf(stdout,_("%c"), MessageBuffer[i]);\r
-#endif\r
- Current_Revision[j++]=MessageBuffer[i];\r
- }\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("\n"));\r
-#endif\r
-\r
- CurrentGetHWError=GE_NONE;\r
- }\r
-}\r
-\r
-GSM_Error N6110_SendHWFrame()\r
-{\r
- unsigned char req[4] = {0x00, 0x01, 0xc8, 0x05}; \r
-\r
- GSM_Error error;\r
-\r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
- \r
- return NULL_SendMessageSequence (20, &CurrentGetHWError, 4, 0x40, req);\r
-}\r
-\r
-void N6110_ReplyID(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int i, j;\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Mobile phone model identification received:\n"));\r
- fprintf(stdout, _(" Firmware: "));\r
-#endif\r
-\r
- strcpy(Current_Revision,"SW");\r
- \r
- i=6;j=2;\r
- while (MessageBuffer[i]!=0x0a) {\r
- Current_Revision[j]=MessageBuffer[i];\r
-#ifdef DEBUG\r
- fprintf(stdout, _("%c"),MessageBuffer[i]);\r
-#endif\r
- if (j==GSM_MAX_REVISION_LENGTH-1) {\r
-#ifdef DEBUG\r
- fprintf(stderr,_("ERROR: increase GSM_MAX_REVISION_LENGTH!\n"));\r
-#endif \r
- break;\r
- }\r
- j++;\r
- i++;\r
- }\r
- Current_Revision[j+1]=0;\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("\n Firmware date: "));\r
-#endif\r
-\r
- i++;\r
- while (MessageBuffer[i]!=0x0a) {\r
-#ifdef DEBUG\r
- fprintf(stdout, _("%c"),MessageBuffer[i]);\r
-#endif\r
- i++;\r
- }\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("\n Model: "));\r
-#endif /* DEBUG */\r
-\r
- i++;j=0;\r
- while (MessageBuffer[i]!=0x0a) {\r
- Current_Model[j]=MessageBuffer[i];\r
-#ifdef DEBUG\r
- fprintf(stdout, _("%c"),MessageBuffer[i]);\r
-#endif\r
- if (j==GSM_MAX_MODEL_LENGTH-1) {\r
-#ifdef DEBUG\r
- fprintf(stderr,_("ERROR: increase GSM_MAX_MODEL_LENGTH!\n"));\r
-#endif \r
- break;\r
- }\r
- j++;\r
- i++;\r
- }\r
- Current_Model[j+1]=0;\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("\n"));\r
-#endif /* DEBUG */\r
- \r
- CurrentMagicError=GE_NONE;\r
-}\r
-\r
-GSM_Error N6110_SendIDFrame()\r
-{\r
- unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00}; \r
-\r
- return NULL_SendMessageSequence (50, &CurrentMagicError, 5, 0xd1, req);\r
-}\r
-\r
-/* This function send the status request to the phone. */\r
-/* Seems to be ignored in N3210 */\r
-GSM_Error N6110_SendStatusRequest(void)\r
-{\r
- unsigned char req[] = {N6110_FRAME_HEADER, 0x01};\r
-\r
- Protocol->SendMessage(4, 0x04, req);\r
-\r
- return (GE_NONE);\r
-}\r
-\r
-void N6110_ReplyGetAuthentication(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#if defined WIN32 || !defined HAVE_SNPRINTF\r
- sprintf(Current_IMEI, "%s", MessageBuffer+9);\r
- sprintf(Current_Model, "%s", MessageBuffer+25);\r
- sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);\r
-#else\r
- snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+9);\r
- snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+25);\r
- snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);\r
-#endif\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Mobile phone identification received:\n"));\r
- fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);\r
- fprintf(stdout, _(" Model: %s\n"), Current_Model);\r
- fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+31);\r
- fprintf(stdout, _(" HW: %s\n"), MessageBuffer+39);\r
- fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+44);\r
-\r
- /* These bytes are probably the source of the "Accessory not connected"\r
- messages on the phone when trying to emulate NCDS... I hope....\r
- UPDATE: of course, now we have the authentication algorithm. */\r
- fprintf(stdout, _(" Magic bytes: %02x %02x %02x %02x\n"), MessageBuffer[50], MessageBuffer[51], MessageBuffer[52], MessageBuffer[53]);\r
-#endif /* DEBUG */\r
-\r
- MagicBytes[0]=MessageBuffer[50];\r
- MagicBytes[1]=MessageBuffer[51];\r
- MagicBytes[2]=MessageBuffer[52];\r
- MagicBytes[3]=MessageBuffer[53];\r
-\r
- CurrentMagicError=GE_NONE;\r
-}\r
-\r
-/* This function provides Nokia authentication protocol.\r
-\r
- This code is written specially for gnokii project by Odinokov Serge.\r
- If you have some special requests for Serge just write him to\r
- apskaita@post.omnitel.net or serge@takas.lt\r
-\r
- Reimplemented in C by Pavel JanÃk ml.\r
-\r
- Nokia authentication protocol is used in the communication between Nokia\r
- mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software,\r
- commercially sold by Nokia Corp.\r
-\r
- The authentication scheme is based on the token send by the phone to the\r
- software. The software does it's magic (see the function\r
- FB61_GetNokiaAuth()) and returns the result back to the phone. If the\r
- result is correct the phone responds with the message "Accessory\r
- connected!" displayed on the LCD. Otherwise it will display "Accessory not\r
- supported" and some functions will not be available for use.\r
-\r
- The specification of the protocol is not publicly available, no comment. */\r
-void N6110_GetNokiaAuth(unsigned char *Imei, unsigned char *MagicBytes, unsigned char *MagicResponse)\r
-{\r
-\r
- int i, j, CRC=0;\r
-\r
- /* This is our temporary working area. */\r
-\r
- unsigned char Temp[16];\r
-\r
- /* Here we put FAC (Final Assembly Code) and serial number into our area. */\r
-\r
- Temp[0] = Imei[6];\r
- Temp[1] = Imei[7];\r
- Temp[2] = Imei[8];\r
- Temp[3] = Imei[9];\r
- Temp[4] = Imei[10];\r
- Temp[5] = Imei[11];\r
- Temp[6] = Imei[12];\r
- Temp[7] = Imei[13];\r
-\r
- /* And now the TAC (Type Approval Code). */\r
-\r
- Temp[8] = Imei[2];\r
- Temp[9] = Imei[3];\r
- Temp[10] = Imei[4];\r
- Temp[11] = Imei[5];\r
-\r
- /* And now we pack magic bytes from the phone. */\r
-\r
- Temp[12] = MagicBytes[0];\r
- Temp[13] = MagicBytes[1];\r
- Temp[14] = MagicBytes[2];\r
- Temp[15] = MagicBytes[3];\r
-\r
- for (i=0; i<=11; i++)\r
- if (Temp[i + 1]& 1)\r
- Temp[i]<<=1;\r
-\r
- switch (Temp[15] & 0x03) {\r
-\r
- case 1:\r
- case 2:\r
- j = Temp[13] & 0x07;\r
-\r
- for (i=0; i<=3; i++)\r
- Temp[i+j] ^= Temp[i+12];\r
-\r
- break;\r
-\r
- default:\r
- j = Temp[14] & 0x07;\r
-\r
- for (i=0; i<=3; i++)\r
- Temp[i + j] |= Temp[i + 12];\r
- }\r
-\r
- for (i=0; i<=15; i++)\r
- CRC ^= Temp[i];\r
-\r
- for (i=0; i<=15; i++) {\r
-\r
- switch (Temp[15 - i] & 0x06) {\r
-\r
- case 0:\r
- j = Temp[i] | CRC;\r
- break;\r
-\r
- case 2:\r
- case 4:\r
- j = Temp[i] ^ CRC;\r
- break;\r
-\r
- case 6:\r
- j = Temp[i] & CRC;\r
- break;\r
- }\r
- \r
- if (j == CRC)\r
- j = 0x2c;\r
-\r
- if (Temp[i] == 0)\r
- j = 0;\r
-\r
- MagicResponse[i] = j;\r
-\r
- }\r
-}\r
-\r
-GSM_Error N6110_Authentication()\r
-{\r
- unsigned char connect1[] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x02};\r
- unsigned char connect2[] = {N6110_FRAME_HEADER, 0x20, 0x02};\r
- unsigned char connect3[] = {N6110_FRAME_HEADER, 0x0d, 0x01, 0x00, 0x02};\r
- unsigned char connect4[] = {N6110_FRAME_HEADER, 0x10};\r
- \r
- unsigned char magic_connect[] = {N6110_FRAME_HEADER,\r
- 0x12,\r
-\r
- /* The real magic goes here ... These bytes are filled in with the\r
- function N6110_GetNokiaAuth(). */\r
-\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \r
-\r
- /* NOKIA&GNOKII Accessory */\r
-\r
- 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x26, 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x20,\r
- 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x79,\r
- \r
- 0x00, 0x00, 0x00, 0x00};\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Making authentication!\n"));\r
-#endif\r
-\r
- usleep(100); Protocol->SendMessage(7, 0x02, connect1);\r
- usleep(100); Protocol->SendMessage(5, 0x02, connect2);\r
- usleep(100); Protocol->SendMessage(7, 0x02, connect3);\r
- \r
- CurrentMagicError = GE_BUSY;\r
-\r
- usleep(100); Protocol->SendMessage(4, 0x64, connect4);\r
- if (NULL_WaitUntil(50,&CurrentMagicError)!=GE_NONE) return GE_TIMEOUT;\r
-\r
- N6110_GetNokiaAuth(Current_IMEI, MagicBytes, magic_connect+4);\r
-\r
- Protocol->SendMessage(45, 0x64, magic_connect);\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("End of authentication!\n"));\r
-#endif\r
-\r
- return GE_NONE;\r
-}\r
-\r
-/* Initialise variables and state machine. */\r
-GSM_Error N6110_Initialise(char *port_device, char *initlength,\r
- GSM_ConnectionType connection,\r
- void (*rlp_callback)(RLP_F96Frame *frame))\r
-{\r
- unsigned char init_char = N6110_SYNC_BYTE;\r
- unsigned char end_init_char = N6110_IR_END_SYNC_BYTE;\r
-\r
- int count;\r
- int InitLength;\r
- \r
- if (Protocol->Initialise(port_device,initlength,connection,rlp_callback)!=GE_NONE)\r
- {\r
- return GE_NOTSUPPORTED;\r
- }\r
+ if (status!=0x06) req[3] = status;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentEnableExtendedCommandsError, 4, 0x40, req);
+}
+
+void N6110_ReplyIMEI(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#if defined WIN32 || !defined HAVE_SNPRINTF
+ sprintf(Current_IMEI, "%s", MessageBuffer+4);
+#else
+ snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+4);
+#endif
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: IMEI %s received\n"),Current_IMEI);
+#endif
+
+ CurrentGetIMEIError=GE_NONE;
+}
+
+GSM_Error N6110_SendIMEIFrame()
+{
+ unsigned char req[4] = {0x00, 0x01, 0x66, 0x00};
+
+ GSM_Error error;
+
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
+
+ return NULL_SendMessageSequence (20, &CurrentGetIMEIError, 4, 0x40, req);
+}
+
+void N6110_ReplyHW(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int i, j;
+
+ if (MessageBuffer[3]==0x05) {
+
+#ifdef DEBUG
+ fprintf(stdout,_("Message: Hardware version received: "));
+#endif
+
+ j=strlen(Current_Revision);
+ Current_Revision[j++]=',';
+ Current_Revision[j++]=' ';
+ Current_Revision[j++]='H';
+ Current_Revision[j++]='W';
+
+ for (i=5;i<9;i++) {
+#ifdef DEBUG
+ fprintf(stdout,_("%c"), MessageBuffer[i]);
+#endif
+ Current_Revision[j++]=MessageBuffer[i];
+ }
+
+#ifdef DEBUG
+ fprintf(stdout,_("\n"));
+#endif
+
+ CurrentGetHWError=GE_NONE;
+ }
+}
+
+GSM_Error N6110_SendHWFrame()
+{
+ unsigned char req[4] = {0x00, 0x01, 0xc8, 0x05};
+
+ GSM_Error error;
+
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
+
+ return NULL_SendMessageSequence (20, &CurrentGetHWError, 4, 0x40, req);
+}
+
+void N6110_ReplyID(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int i, j;
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Mobile phone model identification received:\n"));
+ fprintf(stdout, _(" Firmware: "));
+#endif
+
+ strcpy(Current_Revision,"SW");
+
+ i=6;j=2;
+ while (MessageBuffer[i]!=0x0a) {
+ Current_Revision[j]=MessageBuffer[i];
+#ifdef DEBUG
+ fprintf(stdout, _("%c"),MessageBuffer[i]);
+#endif
+ if (j==GSM_MAX_REVISION_LENGTH-1) {
+#ifdef DEBUG
+ fprintf(stderr,_("ERROR: increase GSM_MAX_REVISION_LENGTH!\n"));
+#endif
+ break;
+ }
+ j++;
+ i++;
+ }
+ Current_Revision[j+1]=0;
+
+#ifdef DEBUG
+ fprintf(stdout, _("\n Firmware date: "));
+#endif
+
+ i++;
+ while (MessageBuffer[i]!=0x0a) {
+#ifdef DEBUG
+ fprintf(stdout, _("%c"),MessageBuffer[i]);
+#endif
+ i++;
+ }
+
+#ifdef DEBUG
+ fprintf(stdout, _("\n Model: "));
+#endif /* DEBUG */
+
+ i++;j=0;
+ while (MessageBuffer[i]!=0x0a) {
+ Current_Model[j]=MessageBuffer[i];
+#ifdef DEBUG
+ fprintf(stdout, _("%c"),MessageBuffer[i]);
+#endif
+ if (j==GSM_MAX_MODEL_LENGTH-1) {
+#ifdef DEBUG
+ fprintf(stderr,_("ERROR: increase GSM_MAX_MODEL_LENGTH!\n"));
+#endif
+ break;
+ }
+ j++;
+ i++;
+ }
+ Current_Model[j+1]=0;
+
+#ifdef DEBUG
+ fprintf(stdout, _("\n"));
+#endif /* DEBUG */
+
+ CurrentMagicError=GE_NONE;
+}
+
+GSM_Error N6110_SendIDFrame()
+{
+ unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
+
+ return NULL_SendMessageSequence (50, &CurrentMagicError, 5, 0xd1, req);
+}
+
+/* This function send the status request to the phone. */
+/* Seems to be ignored in N3210 */
+GSM_Error N6110_SendStatusRequest(void)
+{
+ unsigned char req[] = {N6110_FRAME_HEADER, 0x01};
+
+ Protocol->SendMessage(4, 0x04, req);
+
+ return (GE_NONE);
+}
+
+void N6110_ReplyGetAuthentication(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#if defined WIN32 || !defined HAVE_SNPRINTF
+ sprintf(Current_IMEI, "%s", MessageBuffer+9);
+ sprintf(Current_Model, "%s", MessageBuffer+25);
+ sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
+#else
+ snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+9);
+ snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+25);
+ snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
+#endif
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Mobile phone identification received:\n"));
+ fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
+ fprintf(stdout, _(" Model: %s\n"), Current_Model);
+ fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+31);
+ fprintf(stdout, _(" HW: %s\n"), MessageBuffer+39);
+ fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+44);
+
+ /* These bytes are probably the source of the "Accessory not connected"
+ messages on the phone when trying to emulate NCDS... I hope....
+ UPDATE: of course, now we have the authentication algorithm. */
+ fprintf(stdout, _(" Magic bytes: %02x %02x %02x %02x\n"), MessageBuffer[50], MessageBuffer[51], MessageBuffer[52], MessageBuffer[53]);
+#endif /* DEBUG */
+
+ MagicBytes[0]=MessageBuffer[50];
+ MagicBytes[1]=MessageBuffer[51];
+ MagicBytes[2]=MessageBuffer[52];
+ MagicBytes[3]=MessageBuffer[53];
+
+ CurrentMagicError=GE_NONE;
+}
+
+/* This function provides Nokia authentication protocol.
+
+ This code is written specially for gnokii project by Odinokov Serge.
+ If you have some special requests for Serge just write him to
+ apskaita@post.omnitel.net or serge@takas.lt
+
+ Reimplemented in C by Pavel JanÃk ml.
+
+ Nokia authentication protocol is used in the communication between Nokia
+ mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software,
+ commercially sold by Nokia Corp.
+
+ The authentication scheme is based on the token send by the phone to the
+ software. The software does it's magic (see the function
+ FB61_GetNokiaAuth()) and returns the result back to the phone. If the
+ result is correct the phone responds with the message "Accessory
+ connected!" displayed on the LCD. Otherwise it will display "Accessory not
+ supported" and some functions will not be available for use.
+
+ The specification of the protocol is not publicly available, no comment. */
+void N6110_GetNokiaAuth(unsigned char *Imei, unsigned char *MagicBytes, unsigned char *MagicResponse)
+{
+
+ int i, j, CRC=0;
+
+ /* This is our temporary working area. */
+
+ unsigned char Temp[16];
+
+ /* Here we put FAC (Final Assembly Code) and serial number into our area. */
+
+ Temp[0] = Imei[6];
+ Temp[1] = Imei[7];
+ Temp[2] = Imei[8];
+ Temp[3] = Imei[9];
+ Temp[4] = Imei[10];
+ Temp[5] = Imei[11];
+ Temp[6] = Imei[12];
+ Temp[7] = Imei[13];
+
+ /* And now the TAC (Type Approval Code). */
+
+ Temp[8] = Imei[2];
+ Temp[9] = Imei[3];
+ Temp[10] = Imei[4];
+ Temp[11] = Imei[5];
+
+ /* And now we pack magic bytes from the phone. */
+
+ Temp[12] = MagicBytes[0];
+ Temp[13] = MagicBytes[1];
+ Temp[14] = MagicBytes[2];
+ Temp[15] = MagicBytes[3];
+
+ for (i=0; i<=11; i++)
+ if (Temp[i + 1]& 1)
+ Temp[i]<<=1;
+
+ switch (Temp[15] & 0x03) {
+
+ case 1:
+ case 2:
+ j = Temp[13] & 0x07;
+
+ for (i=0; i<=3; i++)
+ Temp[i+j] ^= Temp[i+12];
+
+ break;
+
+ default:
+ j = Temp[14] & 0x07;
+
+ for (i=0; i<=3; i++)
+ Temp[i + j] |= Temp[i + 12];
+ }
+
+ for (i=0; i<=15; i++)
+ CRC ^= Temp[i];
+
+ for (i=0; i<=15; i++) {
+
+ switch (Temp[15 - i] & 0x06) {
+
+ case 0:
+ j = Temp[i] | CRC;
+ break;
+
+ case 2:
+ case 4:
+ j = Temp[i] ^ CRC;
+ break;
+
+ case 6:
+ j = Temp[i] & CRC;
+ break;
+ }
+
+ if (j == CRC)
+ j = 0x2c;
+
+ if (Temp[i] == 0)
+ j = 0;
+
+ MagicResponse[i] = j;
+
+ }
+}
+
+GSM_Error N6110_Authentication()
+{
+ unsigned char connect1[] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x02};
+ unsigned char connect2[] = {N6110_FRAME_HEADER, 0x20, 0x02};
+ unsigned char connect3[] = {N6110_FRAME_HEADER, 0x0d, 0x01, 0x00, 0x02};
+ unsigned char connect4[] = {N6110_FRAME_HEADER, 0x10};
+
+ unsigned char magic_connect[] = {N6110_FRAME_HEADER,
+ 0x12,
+
+ /* The real magic goes here ... These bytes are filled in with the
+ function N6110_GetNokiaAuth(). */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ /* NOKIA&GNOKII Accessory */
+
+ 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x26, 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x20,
+ 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x79,
+
+ 0x00, 0x00, 0x00, 0x00};
+
+#ifdef DEBUG
+ fprintf(stdout,_("Making authentication!\n"));
+#endif
+
+ usleep(100); Protocol->SendMessage(7, 0x02, connect1);
+ usleep(100); Protocol->SendMessage(5, 0x02, connect2);
+ usleep(100); Protocol->SendMessage(7, 0x02, connect3);
+
+ CurrentMagicError = GE_BUSY;
+
+ usleep(100); Protocol->SendMessage(4, 0x64, connect4);
+ if (NULL_WaitUntil(50,&CurrentMagicError)!=GE_NONE) return GE_TIMEOUT;
+
+ N6110_GetNokiaAuth(Current_IMEI, MagicBytes, magic_connect+4);
+
+ Protocol->SendMessage(45, 0x64, magic_connect);
+
+#ifdef DEBUG
+ fprintf(stdout,_("End of authentication!\n"));
+#endif
+
+ return GE_NONE;
+}
+
+/* Initialise variables and state machine. */
+GSM_Error N6110_Initialise(char *port_device, char *initlength,
+ GSM_ConnectionType connection,
+ void (*rlp_callback)(RLP_F96Frame *frame))
+{
+ unsigned char init_char = N6110_SYNC_BYTE;
+ unsigned char end_init_char = N6110_IR_END_SYNC_BYTE;
+
+ int count;
+ int InitLength;
+
+ if (Protocol->Initialise(port_device,initlength,connection,rlp_callback)!=GE_NONE)
+ {
+ return GE_NOTSUPPORTED;
+ }
switch (CurrentConnectionType) {
case GCT_Irda:
/* We don't think about authentication in Irda, because
AFAIK there are no phones working over sockets
and having authentication. In MBUS it doesn't work */
- usleep(100);\r
-\r
- if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;\r
- \r
- if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT; \r
-\r
- if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT; \r
-
- CurrentLinkOK = true; \r \r
+ usleep(100);
+
+ if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
+
+ if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
+
+ if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
+
+ CurrentLinkOK = true;
break;
case GCT_FBUS:
case GCT_Infrared:
case GCT_Tekram:
- InitLength = atoi(initlength);\r
-\r
- if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {\r
- InitLength = 250; /* This is the usual value, lower may work. */\r
- }\r
-\r
+ InitLength = atoi(initlength);
+
+ if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
+ InitLength = 250; /* This is the usual value, lower may work. */
+ }
+
if (CurrentConnectionType==GCT_Infrared ||
- CurrentConnectionType==GCT_Tekram) {\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Setting infrared for FBUS communication...\n"));\r
-#endif\r
- device_changespeed(9600);\r
- }\r
-
-#ifdef DEBUG\r
- fprintf(stdout,_("Writing init chars...."));\r
-#endif\r
-\r
- /* Initialise link with phone or what have you */\r
- /* Send init string to phone, this is a bunch of 0x55 characters. Timing is\r
- empirical. */\r
- for (count = 0; count < InitLength; count ++) {\r
+ CurrentConnectionType==GCT_Tekram) {
+#ifdef DEBUG
+ fprintf(stdout,_("Setting infrared for FBUS communication...\n"));
+#endif
+ device_changespeed(9600);
+ }
+
+#ifdef DEBUG
+ fprintf(stdout,_("Writing init chars...."));
+#endif
+
+ /* 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 ++) {
if (CurrentConnectionType!=GCT_Infrared &&
- CurrentConnectionType!=GCT_Tekram) \r usleep(100);\r
- Protocol->WritePhone(1,&init_char);\r
- }\r
-\r
+ CurrentConnectionType!=GCT_Tekram) usleep(100);
+ Protocol->WritePhone(1,&init_char);
+ }
+
if (CurrentConnectionType==GCT_Infrared ||
- CurrentConnectionType==GCT_Tekram)\r {
- Protocol->WritePhone(1,&end_init_char);\r
+ CurrentConnectionType==GCT_Tekram) {
+ Protocol->WritePhone(1,&end_init_char);
usleep(200000);
}
-#ifdef DEBUG\r
- fprintf(stdout,_("Done\n")); \r
-#endif\r
+#ifdef DEBUG
+ fprintf(stdout,_("Done\n"));
+#endif
if (CurrentConnectionType==GCT_Infrared ||
- CurrentConnectionType==GCT_Tekram)\r {
- device_changespeed(115200); \r
+ CurrentConnectionType==GCT_Tekram) {
+ device_changespeed(115200);
}
- N6110_SendStatusRequest();\r
- \r
- usleep(100);\r
-\r
- if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;\r
- \r
- /* N51xx/61xx have something called authentication.\r
- After making it phone display "Accessory connected"\r
- and probably give access to some function (I'm not too sure about it !)\r
- Anyway, I make it now for N51xx/61xx */\r
- if (GetModelFeature (FN_AUTHENTICATION)!=0) {\r
- if (N6110_Authentication()!=GE_NONE) return GE_TIMEOUT;\r
- } else {\r /* No authentication */
- if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT; \r
-\r
- if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT; \r
- }\r
+ N6110_SendStatusRequest();
+
+ usleep(100);
+
+ if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
+
+ /* N51xx/61xx have something called authentication.
+ After making it phone display "Accessory connected"
+ and probably give access to some function (I'm not too sure about it !)
+ Anyway, I make it now for N51xx/61xx */
+ if (GetModelFeature (FN_AUTHENTICATION)!=0) {
+ if (N6110_Authentication()!=GE_NONE) return GE_TIMEOUT;
+ } else { /* No authentication */
+ if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
+
+ if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
+ }
break;
default:
-#ifdef DEBUG\r
- fprintf(stdout,_("Unknown connection type in n6110.c!\n"));\r
-#endif\r
+#ifdef DEBUG
+ fprintf(stdout,_("Unknown connection type in n6110.c!\n"));
+#endif
break;
}
- return (GE_NONE);\r
-}\r
-\r
-/* This function translates GMT_MemoryType to N6110_MEMORY_xx */\r
-int N6110_GetMemoryType(GSM_MemoryType memory_type)\r
-{\r
-\r
- int result;\r
-\r
- switch (memory_type) {\r
-\r
- case GMT_MT: result = N6110_MEMORY_MT; break;\r
- case GMT_ME: result = N6110_MEMORY_ME; break;\r
- case GMT_SM: result = N6110_MEMORY_SM; break;\r
- case GMT_FD: result = N6110_MEMORY_FD; break;\r
- case GMT_ON: result = N6110_MEMORY_ON; break;\r
- case GMT_EN: result = N6110_MEMORY_EN; break;\r
- case GMT_DC: result = N6110_MEMORY_DC; break;\r
- case GMT_RC: result = N6110_MEMORY_RC; break;\r
- case GMT_MC: result = N6110_MEMORY_MC; break;\r
- default : result = N6110_MEMORY_XX;\r
-\r
- }\r
-\r
- return (result);\r
-}\r
+ return (GE_NONE);
+}
+
+/* This function translates GMT_MemoryType to N6110_MEMORY_xx */
+int N6110_GetMemoryType(GSM_MemoryType memory_type)
+{
+
+ int result;
+
+ switch (memory_type) {
+
+ case GMT_MT: result = N6110_MEMORY_MT; break;
+ case GMT_ME: result = N6110_MEMORY_ME; break;
+ case GMT_SM: result = N6110_MEMORY_SM; break;
+ case GMT_FD: result = N6110_MEMORY_FD; break;
+ case GMT_ON: result = N6110_MEMORY_ON; break;
+ case GMT_EN: result = N6110_MEMORY_EN; break;
+ case GMT_DC: result = N6110_MEMORY_DC; break;
+ case GMT_RC: result = N6110_MEMORY_RC; break;
+ case GMT_MC: result = N6110_MEMORY_MC; break;
+ default : result = N6110_MEMORY_XX;
+
+ }
+
+ return (result);
+}
void N6110_ReplyCallDivert(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
case 0x02:
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Call divert status received\n"));\r
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Call divert status received\n"));
fprintf(stdout, _(" Divert type: "));
switch (MessageBuffer[6]) {
case 0x43: fprintf(stdout, _("when busy"));break;
} else {
CurrentCallDivert->Enabled=false;
}
- CurrentCallDivertError=GE_NONE;\r
+ CurrentCallDivertError=GE_NONE;
}
break;
- case 0x03:\r
+ case 0x03:
#ifdef DEBUG
fprintf(stdout, _("Message: Call divert status receiving error ?\n"));
-#endif\r
- CurrentCallDivertError=GE_UNKNOWN;\r
+#endif
+ CurrentCallDivertError=GE_UNKNOWN;
break;
}
}
int length = 0x09;
switch (cd->Operation) {
- case GSM_CDV_Register:\r
- case GSM_CDV_Enable:\r
+ case GSM_CDV_Register:
+ case GSM_CDV_Enable:
req[4] = 0x03;
req[8] = 0x01;
req[29]= GSM_PackSemiOctetNumber(cd->Number, req + 9, false);
return error;
}
-\r
-GSM_Error N6110_Tests()\r
-{\r
- unsigned char buffer[3]={0x00,0x01,0xcf};\r
- unsigned char buffer3[8]={0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00};\r
+
+GSM_Error N6110_Tests()
+{
+ unsigned char buffer[3]={0x00,0x01,0xcf};
+ unsigned char buffer3[8]={0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00};
GSM_Error error;
-\r
- error=N6110_EnableExtendedCommands(0x01);\r
+
+ error=N6110_EnableExtendedCommands(0x01);
if (error!=GE_NONE) return error;
-\r
- //make almost all tests\r
- Protocol->SendMessage(8, 0x40, buffer3);\r
-\r
- while (GSM->Initialise(PortDevice, "50", CurrentConnectionType, CurrentRLP_RXCallback)!=GE_NONE) {};\r
-\r
- sleep(2);\r
-\r
- return NULL_SendMessageSequence\r
- (200, &CurrentNetworkInfoError, 3, 0x40, buffer); \r
-}\r
-\r
-void N6110_DisplayTestsInfo(u8 *MessageBuffer) {\r
-\r
- int i;\r
-\r
- CurrentNetworkInfoError=GE_NONE;\r
-\r
- for (i=0;i<MessageBuffer[3];i++) {\r
- switch (i) {\r
- case 0: fprintf(stdout,_("Unknown(%i) "),i);break;\r
- case 1: fprintf(stdout,_("MCU ROM checksum "));break;\r
- case 2: fprintf(stdout,_("MCU RAM interface "));break;\r
- case 3: fprintf(stdout,_("MCU RAM component "));break;\r
- case 4: fprintf(stdout,_("MCU EEPROM interface "));break;\r
- case 5: fprintf(stdout,_("MCU EEPROM component "));break;\r
- case 6: fprintf(stdout,_("Real Time Clock battery "));break;\r
- case 7: fprintf(stdout,_("CCONT interface "));break;\r
- case 8: fprintf(stdout,_("AD converter "));break;\r
- case 9: fprintf(stdout,_("SW Reset "));break;\r
- case 10:fprintf(stdout,_("Power Off "));break;\r
- case 11:fprintf(stdout,_("Security Data "));break;\r
- case 12:fprintf(stdout,_("EEPROM Tune checksum "));break;\r
- case 13:fprintf(stdout,_("PPM checksum "));break;\r
- case 14:fprintf(stdout,_("MCU download DSP "));break;\r
- case 15:fprintf(stdout,_("DSP alive "));break;\r
- case 16:fprintf(stdout,_("COBBA serial "));break;\r
- case 17:fprintf(stdout,_("COBBA paraller "));break;\r
- case 18:fprintf(stdout,_("EEPROM security checksum"));break;\r
- case 19:fprintf(stdout,_("PPM validity "));break;\r
- case 20:fprintf(stdout,_("Warranty state "));break;\r
- case 21:fprintf(stdout,_("Simlock check "));break;\r
- case 22:fprintf(stdout,_("IMEI check? "));break;//from PC-Locals.is OK?\r
- default:fprintf(stdout,_("Unknown(%i) "),i);break;\r
- }\r
- switch (MessageBuffer[4+i]) {\r
- case 0: fprintf(stdout,_(" : done, result OK"));break;\r
- case 0xff:fprintf(stdout,_(" : not done, result unknown"));break;\r
- case 254: fprintf(stdout,_(" : done, result NOT OK"));break;\r
- default: fprintf(stdout,_(" : result unknown(%i)"),MessageBuffer[4+i]);break;\r
- }\r
- fprintf(stdout,_("\n"));\r
- }\r
-}\r
-void N6110_ReplySimlockInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+ //make almost all tests
+ Protocol->SendMessage(8, 0x40, buffer3);
- int i, j;
-
- char uni[100];
- \r
-#ifdef DEBUG
- fprintf(stdout, _("Message: Simlock info received\n"));
-\r
- j=0;\r
- for (i=0; i < 12; i++)\r
- {\r
- if (j<24) {\r
- fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] >> 4)));\r
- j++;\r
- }\r
- if (j==5 || j==15) fprintf(stdout, _("\n"));\r
- if (j!=15) {\r
- if (j<24) {\r
- fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] & 0x0f)));\r
- j++;\r
- }\r
- } else j++;\r
- if (j==20 || j==24) fprintf(stdout, _("\n"));\r
- }\r
-
- if ((MessageBuffer[6] & 1) == 1) fprintf(stdout,_("lock 1 closed\n"));
- if ((MessageBuffer[6] & 2) == 2) fprintf(stdout,_("lock 2 closed\n"));
+ while (GSM->Initialise(PortDevice, "50", CurrentConnectionType, CurrentRLP_RXCallback)!=GE_NONE) {};
+
+ sleep(2);
+
+ return NULL_SendMessageSequence
+ (200, &CurrentNetworkInfoError, 3, 0x40, buffer);
+}
+
+void N6110_DisplayTestsInfo(u8 *MessageBuffer) {
+
+ int i;
+
+ CurrentNetworkInfoError=GE_NONE;
+
+ for (i=0;i<MessageBuffer[3];i++) {
+ switch (i) {
+ case 0: fprintf(stdout,_("Unknown(%i) "),i);break;
+ case 1: fprintf(stdout,_("MCU ROM checksum "));break;
+ case 2: fprintf(stdout,_("MCU RAM interface "));break;
+ case 3: fprintf(stdout,_("MCU RAM component "));break;
+ case 4: fprintf(stdout,_("MCU EEPROM interface "));break;
+ case 5: fprintf(stdout,_("MCU EEPROM component "));break;
+ case 6: fprintf(stdout,_("Real Time Clock battery "));break;
+ case 7: fprintf(stdout,_("CCONT interface "));break;
+ case 8: fprintf(stdout,_("AD converter "));break;
+ case 9: fprintf(stdout,_("SW Reset "));break;
+ case 10:fprintf(stdout,_("Power Off "));break;
+ case 11:fprintf(stdout,_("Security Data "));break;
+ case 12:fprintf(stdout,_("EEPROM Tune checksum "));break;
+ case 13:fprintf(stdout,_("PPM checksum "));break;
+ case 14:fprintf(stdout,_("MCU download DSP "));break;
+ case 15:fprintf(stdout,_("DSP alive "));break;
+ case 16:fprintf(stdout,_("COBBA serial "));break;
+ case 17:fprintf(stdout,_("COBBA paraller "));break;
+ case 18:fprintf(stdout,_("EEPROM security checksum"));break;
+ case 19:fprintf(stdout,_("PPM validity "));break;
+ case 20:fprintf(stdout,_("Warranty state "));break;
+ case 21:fprintf(stdout,_("Simlock check "));break;
+ case 22:fprintf(stdout,_("IMEI check? "));break;//from PC-Locals.is OK?
+ default:fprintf(stdout,_("Unknown(%i) "),i);break;
+ }
+ switch (MessageBuffer[4+i]) {
+ case 0: fprintf(stdout,_(" : done, result OK"));break;
+ case 0xff:fprintf(stdout,_(" : not done, result unknown"));break;
+ case 254: fprintf(stdout,_(" : done, result NOT OK"));break;
+ default: fprintf(stdout,_(" : result unknown(%i)"),MessageBuffer[4+i]);break;
+ }
+ fprintf(stdout,_("\n"));
+ }
+}
+
+void N6110_ReplySimlockInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int i, j;
+
+ char uni[100];
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Simlock info received\n"));
+
+ j=0;
+ for (i=0; i < 12; i++)
+ {
+ if (j<24) {
+ fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] >> 4)));
+ j++;
+ }
+ if (j==5 || j==15) fprintf(stdout, _("\n"));
+ if (j!=15) {
+ if (j<24) {
+ fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] & 0x0f)));
+ j++;
+ }
+ } else j++;
+ if (j==20 || j==24) fprintf(stdout, _("\n"));
+ }
+
+ if ((MessageBuffer[6] & 1) == 1) fprintf(stdout,_("lock 1 closed\n"));
+ if ((MessageBuffer[6] & 2) == 2) fprintf(stdout,_("lock 2 closed\n"));
if ((MessageBuffer[6] & 4) == 4) fprintf(stdout,_("lock 3 closed\n"));
if ((MessageBuffer[6] & 8) == 8) fprintf(stdout,_("lock 4 closed\n"));
CurrentSimlockInfoError=GE_NONE;
}
-GSM_Error N6110_SimlockInfo(GSM_AllSimlocks *siml)\r
-{\r
-\r GSM_Error error;
- unsigned char req[] = {0x00,0x01,0x8a,0x00};\r\r
- error=N6110_EnableExtendedCommands(0x01);\r
+GSM_Error N6110_SimlockInfo(GSM_AllSimlocks *siml)
+{
+ GSM_Error error;
+ unsigned char req[] = {0x00,0x01,0x8a,0x00};
+ error=N6110_EnableExtendedCommands(0x01);
if (error!=GE_NONE) return error;
CurrentSimLock=siml;
- return NULL_SendMessageSequence (50, &CurrentSimlockInfoError, 4, 0x40, req); \r
-}\r
+ return NULL_SendMessageSequence (50, &CurrentSimlockInfoError, 4, 0x40, req);
+}
void N6110_ReplyResetPhoneSettings(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
CurrentResetPhoneSettingsError=GE_NONE;
}
-GSM_Error N6110_ResetPhoneSettings()\r
-{\r
-\r GSM_Error error;
- unsigned char req[] = {0x00,0x01,0x65,0x08,0x00};\r \r
- error=N6110_EnableExtendedCommands(0x01);\r
+GSM_Error N6110_ResetPhoneSettings()
+{
+ GSM_Error error;
+ unsigned char req[] = {0x00,0x01,0x65,0x08,0x00};
+ error=N6110_EnableExtendedCommands(0x01);
if (error!=GE_NONE) return error;
- return NULL_SendMessageSequence\r
- (50, &CurrentResetPhoneSettingsError, 5, 0x40, req); \r
-}\r\r
+ return NULL_SendMessageSequence
+ (50, &CurrentResetPhoneSettingsError, 5, 0x40, req);
+}
GSM_Error N6110_GetManufacturer(char *manufacturer)
{
strcpy (manufacturer, "Nokia");
return (GE_NONE);
}
-GSM_Error N6110_GetVoiceMailbox ( GSM_PhonebookEntry *entry)\r
-{\r
- unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};\r
-\r
- GSM_Error error;\r
- \r
- CurrentPhonebookEntry = entry;\r
-\r
- req[4] = N6110_MEMORY_VOICE;\r
- req[5] = 0x00; /* Location - isn't important, but... */\r
-\r
- error=NULL_SendMessageSequence\r
- (20, &CurrentPhonebookError, 7, 0x03, req);\r
- \r
- CurrentPhonebookEntry = NULL;\r
- \r
- return error;\r
-}\r
-\r
-void N6110_ReplyGetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int i, count;\r
- \r
- GSM_Bitmap NullBitmap;\r
-\r
- DecodeNetworkCode(MessageBuffer+5, NullBitmap.netcode);\r
- \r
- count=8;\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Info about downloaded operator name received: %s network (for gnokii \"%s\", for phone \""),\r
- NullBitmap.netcode,\r
- GSM_GetNetworkName(NullBitmap.netcode)); \r
-#endif\r
- \r
- i=count;\r
- while (MessageBuffer[count]!=0) {\r
-#ifdef DEBUG\r
- fprintf(stdout,_("%c"),MessageBuffer[count]);\r
-#endif\r
- count++;\r
- }\r
- \r
- strcpy(CurrentGetOperatorNameNetwork->Code, NullBitmap.netcode);\r
- strncpy(CurrentGetOperatorNameNetwork->Name, MessageBuffer+i,count-i+1);\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("\")\n"));\r
-#endif\r
- \r
- CurrentGetOperatorNameError=GE_NONE;\r
-}\r
-\r
-GSM_Error N6110_GetOperatorName (GSM_Network *operator)\r
-{\r
- unsigned char req[] = { 0x00,0x01,0x8c,0x00};\r
-\r
- GSM_Error error;\r
-\r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
-\r
- CurrentGetOperatorNameNetwork = operator;\r
-\r
- error=NULL_SendMessageSequence\r
- (20, &CurrentGetOperatorNameError, 4, 0x40, req);\r
-\r
- CurrentGetOperatorNameNetwork = NULL;\r
- \r
- return error;\r
-}\r
-\r
-void N6110_ReplySetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Downloaded operator name changed\n"));\r
-#endif \r
-\r
- CurrentSetOperatorNameError=GE_NONE; \r
-}\r
-\r
-GSM_Error N6110_SetOperatorName (GSM_Network *operator)\r
-{\r
- unsigned char req[256] = { 0x00,0x01,0x8b,0x00,\r
- 0x00,0x00, /* MCC */\r
- 0x00}; /* MNC */\r
-\r
- GSM_Error error;\r
-\r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
-\r
- EncodeNetworkCode(req+4,operator->Code);\r
-\r
- strncpy(req+7,operator->Name,200);\r
- \r
- return NULL_SendMessageSequence\r
- (20, &CurrentSetOperatorNameError, 8+strlen(operator->Name), 0x40, req);\r
-}\r
-\r
-void N6110_ReplyGetMemoryStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[3]) {\r
-\r
- case 0x08:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Memory status received:\n"));\r
-\r
- fprintf(stdout, _(" Memory Type: %s\n"), N6110_MemoryType_String[MessageBuffer[4]]);\r
- fprintf(stdout, _(" Used: %d\n"), MessageBuffer[6]);\r
- fprintf(stdout, _(" Free: %d\n"), MessageBuffer[5]);\r
-#endif /* DEBUG */\r
-\r
- CurrentMemoryStatus->Used = MessageBuffer[6];\r
- CurrentMemoryStatus->Free = MessageBuffer[5];\r
- CurrentMemoryStatusError = GE_NONE;\r
-\r
- break;\r
-\r
- case 0x09:\r
-\r
-#ifdef DEBUG\r
- switch (MessageBuffer[4]) {\r
- case 0x6f:\r
- fprintf(stdout, _("Message: Memory status error, phone is probably powered off.\n"));break;\r
- case 0x7d:\r
- fprintf(stdout, _("Message: Memory status error, memory type not supported by phone model.\n"));break;\r
- case 0x8d:\r
- fprintf(stdout, _("Message: Memory status error, waiting for security code.\n"));break;\r
- default:\r
- fprintf(stdout, _("Message: Unknown Memory status error, subtype (MessageBuffer[4]) = %02x\n"),MessageBuffer[4]);break;\r
- }\r
-#endif\r
-\r
- switch (MessageBuffer[4]) {\r
- case 0x6f:CurrentMemoryStatusError = GE_TIMEOUT;break;\r
- case 0x7d:CurrentMemoryStatusError = GE_INTERNALERROR;break;\r
- case 0x8d:CurrentMemoryStatusError = GE_INVALIDSECURITYCODE;break;\r
- default:break;\r
- }\r
-\r
- break;\r
-\r
- }\r
-}\r
-\r
-/* This function is used to get storage status from the phone. It currently\r
- supports two different memory areas - internal and SIM. */\r
-GSM_Error N6110_GetMemoryStatus(GSM_MemoryStatus *Status)\r
-{\r
- unsigned char req[] = { N6110_FRAME_HEADER,\r
- 0x07, /* MemoryStatus request */\r
- 0x00 /* MemoryType */\r
- };\r
-\r
- GSM_Error error;\r
- \r
- CurrentMemoryStatus = Status;\r
-\r
- req[4] = N6110_GetMemoryType(Status->MemoryType);\r
-\r
- error=NULL_SendMessageSequence\r
- (20, &CurrentMemoryStatusError, 5, 0x03, req);\r
-\r
- CurrentMemoryStatus = NULL;\r
-\r
- return error;\r
-}\r
-\r
-void N6110_ReplyGetNetworkInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- GSM_NetworkInfo NullNetworkInfo;\r
- \r
- /* Make sure we are expecting NetworkInfo frame */\r
- if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY) {\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Network informations:\n"));\r
-#endif\r
- } else {\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Network informations not requested, but received:\n"));\r
-#endif\r
- }\r
- \r
- sprintf(NullNetworkInfo.NetworkCode, "%x%x%x %x%x", MessageBuffer[14] & 0x0f, MessageBuffer[14] >>4, MessageBuffer[15] & 0x0f, MessageBuffer[16] & 0x0f, MessageBuffer[16] >>4);\r
-\r
- sprintf(NullNetworkInfo.CellID, "%02x%02x", MessageBuffer[10], MessageBuffer[11]);\r
-\r
- sprintf(NullNetworkInfo.LAC, "%02x%02x", MessageBuffer[12], MessageBuffer[13]);\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _(" CellID: %s\n"), NullNetworkInfo.CellID);\r
- fprintf(stdout, _(" LAC: %s\n"), NullNetworkInfo.LAC);\r
- fprintf(stdout, _(" Network code: %s\n"), NullNetworkInfo.NetworkCode);\r
- fprintf(stdout, _(" Network name: %s (%s)\n"),\r
- GSM_GetNetworkName(NullNetworkInfo.NetworkCode),\r
- GSM_GetCountryName(NullNetworkInfo.NetworkCode));\r
- fprintf(stdout, _(" Status: "));\r
-\r
- switch (MessageBuffer[8]) {\r
- case 0x01: fprintf(stdout, _("home network selected")); break;\r
- case 0x02: fprintf(stdout, _("roaming network")); break;\r
- case 0x03: fprintf(stdout, _("requesting network")); break;\r
- case 0x04: fprintf(stdout, _("not registered in the network")); break;\r
- default: fprintf(stdout, _("unknown"));\r
- }\r
-\r
- fprintf(stdout, "\n");\r
-\r
- fprintf(stdout, _(" Network selection: %s\n"), MessageBuffer[9]==1?_("manual"):_("automatic"));\r
-#endif /* DEBUG */\r
-\r
- /* Make sure we are expecting NetworkInfo frame */\r
- if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY)\r
- *CurrentNetworkInfo=NullNetworkInfo;\r
-\r
- CurrentNetworkInfoError = GE_NONE; \r
-}\r
-\r
-GSM_Error N6110_GetNetworkInfo(GSM_NetworkInfo *NetworkInfo)\r
-{\r
- unsigned char req[] = { N6110_FRAME_HEADER,\r
- 0x70\r
- };\r
-\r
- GSM_Error error;\r
- \r
- CurrentNetworkInfo = NetworkInfo;\r
- \r
- error=NULL_SendMessageSequence\r
- (20, &CurrentNetworkInfoError, 4, 0x0a, req);\r
-\r
- CurrentNetworkInfo = NULL;\r
-\r
- return error;\r
-}\r
-\r
-void N6110_ReplyGetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int i;\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Product Profile Settings received -"));\r
- for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),MessageBuffer[3+i]);\r
- fprintf(stdout, _("\n")); \r
-#endif\r
-\r
- for (i=0;i<4;i++) CurrentPPS[i]=MessageBuffer[3+i];\r
-\r
- CurrentProductProfileSettingsError=GE_NONE; \r
-}\r
-\r
-GSM_Error N6110_GetProductProfileSetting (GSM_PPS *PPS)\r
-{\r
- unsigned char req[] = { 0x00, 0x01,0x6a };\r
- \r
- int i,j;\r
-\r
- GSM_Error error;\r
-\r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
-\r
- error=NULL_SendMessageSequence\r
- (20, &CurrentProductProfileSettingsError, 3, 0x40, req);\r
- if (error!=GE_NONE) return error; \r
- \r
- switch (PPS->Name) {\r
- case PPS_ALS : PPS->bool_value=(CurrentPPS[1]&32); break;\r
- case PPS_GamesMenu: PPS->bool_value=(CurrentPPS[3]&64); break;\r
- case PPS_HRData : PPS->bool_value=(CurrentPPS[0]&64); break;\r
- case PPS_14400Data: PPS->bool_value=(CurrentPPS[0]&128);break;\r
- case PPS_EFR : PPS->int_value =(CurrentPPS[0]&1) +(CurrentPPS[0]&2); break;\r
- case PPS_FR : PPS->int_value =(CurrentPPS[0]&16)/16+(CurrentPPS[0]&32)/16;break;\r
- case PPS_HR : PPS->int_value =(CurrentPPS[0]&4)/4 +(CurrentPPS[0]&8)/4; break;\r
- case PPS_VibraMenu: PPS->bool_value=(CurrentPPS[4]&64); break;\r
- case PPS_LCDContrast:\r
- PPS->int_value=0;\r
- j=1;\r
- for (i=0;i<5;i++) {\r
- if (CurrentPPS[3]&j) PPS->int_value=PPS->int_value+j;\r
- j=j*2;\r
- }\r
- PPS->int_value=PPS->int_value*100/32;\r
- break;\r
-\r
- }\r
- \r
- return (GE_NONE);\r
-}\r
-\r
-void N6110_ReplySetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#ifdef DEBUG\r
- int i;\r
-
- fprintf(stdout, _("Message: Product Profile Settings set to"));\r
- for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),CurrentPPS[i]);\r
- fprintf(stdout, _("\n")); \r
-#endif\r
- \r
- CurrentProductProfileSettingsError=GE_NONE; \r
-}\r
-\r
-GSM_Error N6110_SetProductProfileSetting (GSM_PPS *PPS)\r
-{\r
- unsigned char req[] = { 0x00, 0x01,0x6b, \r
- 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */\r
- unsigned char settings[32];\r
- \r
- GSM_PPS OldPPS;\r
- \r
- int i,j,z;\r
- \r
- GSM_Error error;\r
-\r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
- \r
- OldPPS.Name=PPS_ALS;\r
- error=N6110_GetProductProfileSetting(&OldPPS);\r
- if (error!=GE_NONE) return error;\r
- \r
- j=128;z=0;\r
- for (i=0;i<32;i++) {\r
- if (CurrentPPS[z]&j)\r
- settings[i]='1';\r
- else\r
- settings[i]='0'; \r
- if (j==1) {\r
- j=128;\r
- z++;\r
- } else j=j/2;\r
- }\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout,_("Current settings: "));\r
- for (i=0;i<32;i++) {\r
- fprintf(stdout,_("%c"),settings[i]); \r
- }\r
- fprintf(stdout,_("\n"));\r
-#endif\r
-\r
- switch (PPS->Name) {\r
- case PPS_ALS :settings[10]=PPS->bool_value?'1':'0';break;\r
- case PPS_HRData :settings[ 5]=PPS->bool_value?'1':'0';break;\r
- case PPS_14400Data:settings[ 6]=PPS->bool_value?'1':'0';break;\r
- default :break;\r
- }\r
- \r
- j=128;z=0;\r
- for (i=0;i<32;i++) {\r
- if (settings[i]=='1') req[z+3]=req[z+3]+j;\r
- if (j==1) {\r
- j=128;\r
- z++;\r
- } else j=j/2;\r
- } \r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Current settings: "));\r
- for (i=0;i<4;i++) {\r
- fprintf(stdout,_("%i "),req[i+3]); \r
- }\r
- fprintf(stdout,_("\n"));\r
-#endif\r
-\r
- for (i=0;i<4;i++) {\r
- CurrentPPS[i]=req[i+3]; \r
- }\r
-\r
- return NULL_SendMessageSequence\r
- (20, &CurrentProductProfileSettingsError, 7, 0x40, req);\r
-}\r
-\r
-void N6110_ReplyPressKey(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- if (MessageBuffer[4]==CurrentPressKeyEvent) CurrentPressKeyError=GE_NONE;\r
- else CurrentPressKeyError=GE_UNKNOWN; /* MessageBuffer[4] = 0x05 */\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Result of key "));\r
- switch (MessageBuffer[4])\r
- {\r
- case PRESSPHONEKEY: fprintf(stdout, _("press OK\n"));break;\r
- case RELEASEPHONEKEY: fprintf(stdout, _("release OK\n"));break;\r
- default: fprintf(stdout, _("press or release - error\n"));break;\r
- }\r
-#endif /* DEBUG */\r
-}\r
-\r
-GSM_Error N6110_PressKey(int key, int event)\r
-{\r
- unsigned char req[] = {N6110_FRAME_HEADER, 0x42, 0x01, 0x00, 0x01};\r
- \r
- req[4]=event; /* if we press or release key */\r
- req[5]=key;\r
- \r
- CurrentPressKeyEvent=event;\r
- \r
- return NULL_SendMessageSequence\r
- (10, &CurrentPressKeyError, 7, 0x0c, req);\r
-}\r
-\r
-void N6110_ReplyDisplayOutput(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */\r
- char model[64];\r
-\r
- int i, j;\r
-\r
- char uni[100];\r
- \r
- switch(MessageBuffer[3]) {\r
-\r
- /* Phone sends displayed texts */\r
- case 0x50:\r
- NewX=MessageBuffer[6];\r
- NewY=MessageBuffer[5];\r
-\r
- DecodeUnicode (uni, MessageBuffer+8, MessageBuffer[7]);\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("New displayed text (%i %i): \"%s\"\n"),NewX,NewY,uni); \r
-#endif /* DEBUG */\r
-\r
- while (N6110_GetModel(model) != GE_NONE)\r
- sleep(1);\r
-\r
- /* With these rules it works almost excellent with my N5110 */\r
- /* I don't have general rule :-(, that's why you must experiment */\r
- /* with your phone. Nokia could make it better. MW */\r
- /* It's almost OK for N5110*/\r
- /* FIX ME: it will be the same for N5130 and 3210 too*/\r
- if (!strcmp(model,"NSE-1"))\r
- {\r
- /* OldX==1000 means - it's first time */\r
- if (OldX==1000) {\r
- \r
- /* Clean table */\r
- for (i=0;i<5+1;i++) {\r
- for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}\r
- }\r
- OldX=0;\r
- }\r
-\r
- if ((OldX==0 && OldY==31 && NewX==29 && NewY==46) ||\r
- (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {\r
- /* Clean the line with current text */\r
- for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}\r
- \r
- /* Inserts text into table */\r
- for (i=0; i<MessageBuffer[7];i++) { \r
- PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];\r
- }\r
-\r
- }\r
-\r
- if ((OldX==0 && OldY==21 && NewX==0 && NewY==10) ||\r
- (OldX==0 && OldY==10 && NewX==35 && NewY==46)) {\r
- } else {\r
- if ((OldX!=0 && NewX==0 && NewY!=6) ||\r
- (OldX==0 && NewX!=0 && OldY!=13 && OldY!=22) ||\r
- (OldX==0 && NewX==0 && NewY<OldY && (NewY!=13 || OldY!=26)) ||\r
- (OldY==5 && NewY!=5) ||\r
- (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {\r
-\r
- /* Writes "old" screen */\r
- for (i=0;i<5+1;i++) {\r
- for (j=0;j<27+1;j++) {fprintf(stdout,_("%c"),PhoneScreen[i][j]);}\r
- fprintf(stdout,_("\n"));\r
- }\r
- \r
- /* Clean table */\r
- for (i=0;i<5+1;i++) {\r
- for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}\r
- }\r
- }\r
- }\r
- \r
- /* Clean the line with current text */\r
- for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}\r
- \r
- /* Inserts text into table */\r
- for (i=0; i<MessageBuffer[7];i++) { \r
- PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];\r
- }\r
- \r
- OldY=NewY;\r
- OldX=NewX;\r
- } else {\r
-#ifndef DEBUG\r
- fprintf(stdout, _("%s\n"),uni); \r
-#endif\r
- }\r
-\r
- break;\r
- \r
- case 0x54:\r
- \r
- if (MessageBuffer[4]==1)\r
- {\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Display output successfully disabled/enabled.\n"));\r
-#endif /* DEBUG */\r
-\r
- CurrentDisplayOutputError=GE_NONE;\r
- }\r
- \r
- break;\r
- }\r
-}\r
-\r
-GSM_Error SetDisplayOutput(unsigned char state)\r
-{\r
- unsigned char req[] = { N6110_FRAME_HEADER,\r
- 0x53, 0x00};\r
-\r
- req[4]=state;\r
- \r
- return NULL_SendMessageSequence\r
- (30, &CurrentDisplayOutputError, 5, 0x0d, req);\r
-}\r
-\r
-GSM_Error N6110_EnableDisplayOutput()\r
-{\r
- return SetDisplayOutput(0x01);\r
-}\r
- \r
-GSM_Error N6110_DisableDisplayOutput()\r
-{\r
- return SetDisplayOutput(0x02);\r
-}\r
-\r
-/* If it is interesting for somebody: we can use 0x40 msg for it\r
- and it will work for all phones. See n6110.txt for details */\r
-GSM_Error N6110_AnswerCall(char s)\r
-{\r
- unsigned char req0[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,0x07, 0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,\r
- 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80};\r
- unsigned char req[] = { N6110_FRAME_HEADER, 0x06, 0x00, 0x00};\r
-\r
- req[4]=s;\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Answering call %d\n\r"),s);\r
-#endif\r
-\r
- Protocol->SendMessage(sizeof(req0), 0x01, req0);\r
- sleep(1);\r
-\r
- return NULL_SendMessageSequence\r
- (20, &CurrentMagicError, sizeof(req) , 0x01, req);\r
-}\r
-\r
-void N6110_ReplyGetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[3]) {\r
-\r
- /* Profile feature */\r
- case 0x14: \r
-\r
- switch(GetModelFeature (FN_PROFILES)) {\r
- case F_PROF33:\r
- switch (MessageBuffer[6]) {\r
- case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8]; break;\r
- case 0x01: CurrentProfile->CallAlert = MessageBuffer[8]; break;\r
- case 0x02: CurrentProfile->Ringtone = MessageBuffer[8]; break;\r
- case 0x03: CurrentProfile->Volume = MessageBuffer[8]; break;\r
- case 0x04: CurrentProfile->MessageTone = MessageBuffer[8]; break;\r
- case 0x05: CurrentProfile->Vibration = MessageBuffer[8]; break;\r
- case 0x06: CurrentProfile->WarningTone = MessageBuffer[8]; break;\r
- case 0x07: CurrentProfile->ScreenSaver = MessageBuffer[8]; break; \r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);\r
-#endif\r
- break;\r
- }\r
- break;\r
- default:\r
- switch (MessageBuffer[6]) {\r
- case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8];break;\r
- case 0x01: CurrentProfile->Lights = MessageBuffer[8];break;\r
- case 0x02: CurrentProfile->CallAlert = MessageBuffer[8];break;\r
- case 0x03: CurrentProfile->Ringtone = MessageBuffer[8];break;\r
- case 0x04: CurrentProfile->Volume = MessageBuffer[8];break;\r
- case 0x05: CurrentProfile->MessageTone = MessageBuffer[8];break;\r
- case 0x06: CurrentProfile->Vibration = MessageBuffer[8];break;\r
- case 0x07: CurrentProfile->WarningTone = MessageBuffer[8];break;\r
- case 0x08: CurrentProfile->CallerGroups = MessageBuffer[8];break;\r
- case 0x09: CurrentProfile->AutomaticAnswer = MessageBuffer[8];break;\r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);\r
-#endif\r
- break;\r
- }\r
- break;\r
- }\r
-\r
- CurrentProfileError = GE_NONE;\r
- break;\r
-\r
- /* Incoming profile name */\r
- case 0x1b: \r
-\r
- if (MessageBuffer[9] == 0x00) {\r
- CurrentProfile->DefaultName=MessageBuffer[8];\r
- } else {\r
- CurrentProfile->DefaultName=-1; \r
- \r
- /* Here name is in Unicode */\r
- if (GetModelFeature (FN_PROFILES)==F_PROF33) {\r
- DecodeUnicode (CurrentProfile->Name, MessageBuffer+10, MessageBuffer[9]/2);\r
- } else {\r
- /* ...here not */\r
- sprintf(CurrentProfile->Name, MessageBuffer + 10, MessageBuffer[9]);\r
- CurrentProfile->Name[MessageBuffer[9]] = '\0';\r
- }\r
- }\r
-\r
- CurrentProfileError = GE_NONE;\r
- break;\r
-\r
- }\r
-}\r
-\r
-/* Needs SIM card with PIN in phone */\r
-GSM_Error N6110_GetProfile(GSM_Profile *Profile)\r
-{\r
- int i;\r
- \r
- unsigned char name_req[] = { N6110_FRAME_HEADER, 0x1a, 0x00};\r
- unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x13, 0x01, 0x00, 0x00};\r
-\r
- GSM_Error error;\r
- \r
- CurrentProfile = Profile;\r
-\r
- /* When after sending all frames feature==253, it means, that it is not\r
- supported */\r
- CurrentProfile->KeypadTone=253;\r
- CurrentProfile->Lights=253; \r
- CurrentProfile->CallAlert=253; \r
- CurrentProfile->Ringtone=253; \r
- CurrentProfile->Volume=253; \r
- CurrentProfile->MessageTone=253;\r
- CurrentProfile->WarningTone=253;\r
- CurrentProfile->Vibration=253; \r
- CurrentProfile->CallerGroups=253;\r
- CurrentProfile->ScreenSaver=253; \r
- CurrentProfile->AutomaticAnswer=253;\r
-\r
- name_req[4] = Profile->Number;\r
-\r
- error=NULL_SendMessageSequence\r
- (20, &CurrentProfileError, 5, 0x05, name_req);\r
- if (error!=GE_NONE) return error;\r
-\r
- for (i = 0x00; i <= 0x09; i++) {\r
-\r
- feat_req[5] = Profile->Number;\r
- \r
- feat_req[6] = i;\r
-\r
- error=NULL_SendMessageSequence\r
- (20, &CurrentProfileError, 7, 0x05, feat_req);\r
- if (error!=GE_NONE) return error;\r
- }\r
-\r
- if (Profile->DefaultName > -1)\r
- {\r
- switch(GetModelFeature (FN_PROFILES)) {\r
- case F_PROF33:\r
- switch (Profile->DefaultName) {\r
- case 0x00: sprintf(Profile->Name, "General");break;\r
- case 0x01: sprintf(Profile->Name, "Silent");break;\r
- case 0x02: sprintf(Profile->Name, "Descreet");break;\r
- case 0x03: sprintf(Profile->Name, "Loud");break;\r
- case 0x04: sprintf(Profile->Name, "My style");break;\r
- case 0x05: Profile->Name[0]=0;break;\r
- default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;\r
- }\r
- break;\r
- case F_PROF51:\r
- switch (Profile->DefaultName) {\r
- case 0x00: sprintf(Profile->Name, "Personal");break;\r
- case 0x01: sprintf(Profile->Name, "Car");break;\r
- case 0x02: sprintf(Profile->Name, "Headset");break;\r
- default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;\r
- }\r
- break;\r
- case F_PROF61:\r
- switch (Profile->DefaultName) {\r
- case 0x00: sprintf(Profile->Name, "General");break;\r
- case 0x01: sprintf(Profile->Name, "Silent");break;\r
- case 0x02: sprintf(Profile->Name, "Meeting");break;\r
- case 0x03: sprintf(Profile->Name, "Outdoor");break;\r
- case 0x04: sprintf(Profile->Name, "Pager");break;\r
- case 0x05: sprintf(Profile->Name, "Car");break;\r
- case 0x06: sprintf(Profile->Name, "Headset");break;\r
- default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;\r
- }\r
- break;\r
- }\r
- }\r
- \r
- return (GE_NONE);\r
-\r
-}\r
-\r
-void N6110_ReplySetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[3]) {\r
-\r
- /* Profile feature change result */\r
- case 0x11: \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Profile feature change result.\n"));\r
-#endif /* DEBUG */\r
- CurrentProfileError = GE_NONE;\r
- break;\r
-\r
- /* Profile name set result */\r
- case 0x1d: \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Profile name change result.\n"));\r
-#endif /* DEBUG */\r
- CurrentProfileError = GE_NONE;\r
- break;\r
-\r
- }\r
-}\r
-\r
-GSM_Error N6110_SetProfileFeature(u8 profile, u8 feature, u8 value)\r
-{\r
- unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x10, 0x01,\r
- 0x00, 0x00, 0x00};\r
-\r
- feat_req[5]=profile;\r
- feat_req[6]=feature;\r
- feat_req[7]=value;\r
-\r
- return NULL_SendMessageSequence\r
- (20, &CurrentProfileError, 8, 0x05, feat_req);\r
-}\r
-\r
-GSM_Error N6110_SetProfile(GSM_Profile *Profile)\r
-{\r
- int i,value;\r
-\r
- unsigned char name_req[40] = { N6110_FRAME_HEADER, 0x1c, 0x01, 0x03,\r
- 0x00, 0x00, 0x00};\r
-\r
- GSM_Error error;\r
- \r
- name_req[7] = Profile->Number;\r
- name_req[8] = strlen(Profile->Name);\r
- name_req[6] = name_req[8] + 2;\r
-\r
- for (i = 0; i < name_req[8]; i++)\r
- name_req[9 + i] = Profile->Name[i];\r
-\r
- error=NULL_SendMessageSequence\r
- (20, &CurrentProfileError, name_req[8] + 9, 0x05, name_req);\r
- if (error!=GE_NONE) return error;\r
-\r
- for (i = 0x00; i <= 0x09; i++) {\r
-\r
- switch (i) {\r
- case 0x00: value = Profile->KeypadTone; break;\r
- case 0x01: value = Profile->Lights; break;\r
- case 0x02: value = Profile->CallAlert; break;\r
- case 0x03: value = Profile->Ringtone; break;\r
- case 0x04: value = Profile->Volume; break;\r
- case 0x05: value = Profile->MessageTone; break;\r
- case 0x06: value = Profile->Vibration; break;\r
- case 0x07: value = Profile->WarningTone; break;\r
- case 0x08: value = Profile->CallerGroups; break;\r
- case 0x09: value = Profile->AutomaticAnswer; break;\r
- default : value = 0; break;
- }\r
-\r
- error=N6110_SetProfileFeature(Profile->Number,i,value);\r
- if (error!=GE_NONE) return error;\r
- }\r
-\r
- return (GE_NONE);\r
-}\r
-\r
-bool N6110_SendRLPFrame(RLP_F96Frame *frame, bool out_dtx)\r
-{\r
- u8 req[60] = { 0x00, 0xd9 };\r
- \r
- /* Discontinuos transmission (DTX). See section 5.6 of GSM 04.22 version\r
- 7.0.1. */\r
- \r
- if (out_dtx)\r
- req[1]=0x01;\r
-\r
- memcpy(req+2, (u8 *) frame, 32);\r
-\r
- return (Protocol->SendFrame(32, 0xf0, req));\r
-}\r
-\r
-void N6110_ReplyGetCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int i, j;\r
-\r
- u8 mychar1;\r
-\r
- wchar_t wc; \r
- \r
- switch (MessageBuffer[4]) {\r
-\r
- case 0x01:\r
- \r
- CurrentCalendarNote->Type=MessageBuffer[8];\r
-\r
- DecodeDateTime(MessageBuffer+9, &CurrentCalendarNote->Time);\r
-\r
- DecodeDateTime(MessageBuffer+16, &CurrentCalendarNote->Alarm);\r
-\r
- CurrentCalendarNote->Text[0]=0;\r
- \r
- if (GetModelFeature (FN_CALENDAR)==F_CAL33) {\r
- i=0;\r
- if (CurrentCalendarNote->Type == GCN_REMINDER) i=1; //first char is subset\r
- switch (MessageBuffer[24]) {\r
- case 3:\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Subset 3 in reminder note !\n"));\r
-#endif\r
- while (i!=MessageBuffer[23]) {\r
- j=0;\r
- if (i!=MessageBuffer[23]-1) {\r
- if (MessageBuffer[24+i]>=0xc2) {\r
- DecodeWithUTF8Alphabet(MessageBuffer[24+i], MessageBuffer[24+i+1], &mychar1);\r
- CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;\r
- CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=mychar1;\r
- j=-1;\r
- i++;\r
- }\r
- }\r
- if (j!=-1) {\r
- CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;\r
- CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=MessageBuffer[24+i];\r
- }\r
- i++;\r
- }\r
- break;\r
- case 2:\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Subset 2 in reminder note !\n"));\r
-#endif\r
- while (i!=MessageBuffer[23]) {\r
- wc = MessageBuffer[24+i] | (0x00 << 8);\r
- CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;\r
- CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=\r
- DecodeWithUnicodeAlphabet(wc);\r
- i++;\r
- }\r
- break;\r
- case 1:\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Subset 1 in reminder note !\n"));\r
-#endif\r
- memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);\r
- CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;\r
- break;\r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Unknown subset in reminder note !\n"));\r
-#endif\r
- memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);\r
- CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;\r
- break;\r
- }\r
- } else {\r
- memcpy(CurrentCalendarNote->Text,MessageBuffer+24,MessageBuffer[23]);\r
- CurrentCalendarNote->Text[MessageBuffer[23]]=0;\r
- }\r
- \r
- if (CurrentCalendarNote->Type == GCN_CALL) {\r
- memcpy(CurrentCalendarNote->Phone,MessageBuffer+24+MessageBuffer[23]+1,MessageBuffer[24+MessageBuffer[23]]);\r
- CurrentCalendarNote->Phone[MessageBuffer[24+MessageBuffer[23]]]=0;\r
- }\r
-\r
- CurrentCalendarNote->Recurrance=0;\r
-\r
- CurrentCalendarNote->AlarmType=0;\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Calendar note received.\n"));\r
-\r
- fprintf(stdout, _(" Date: %d-%02d-%02d\n"), CurrentCalendarNote->Time.Year,\r
- CurrentCalendarNote->Time.Month,\r
- CurrentCalendarNote->Time.Day);\r
-\r
- fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentCalendarNote->Time.Hour,\r
- CurrentCalendarNote->Time.Minute,\r
- CurrentCalendarNote->Time.Second);\r
-\r
- /* Some messages do not have alarm set up */\r
- if (CurrentCalendarNote->Alarm.Year != 0) {\r
- fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"), CurrentCalendarNote->Alarm.Year,\r
- CurrentCalendarNote->Alarm.Month,\r
- CurrentCalendarNote->Alarm.Day);\r
-\r
- fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"), CurrentCalendarNote->Alarm.Hour,\r
- CurrentCalendarNote->Alarm.Minute,\r
- CurrentCalendarNote->Alarm.Second);\r
- }\r
-\r
- fprintf(stdout, _(" Type: %d\n"), CurrentCalendarNote->Type);\r
- fprintf(stdout, _(" Text: %s\n"), CurrentCalendarNote->Text);\r
-\r
- if (CurrentCalendarNote->Type == GCN_CALL)\r
- fprintf(stdout, _(" Phone: %s\n"), CurrentCalendarNote->Phone);\r
-#endif /* DEBUG */\r
-\r
- CurrentCalendarNoteError=GE_NONE;\r
- break;\r
-\r
- case 0x93:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Calendar note not available\n"));\r
-#endif /* DEBUG */\r
-\r
- CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;\r
- break;\r
-\r
- default:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Calendar note error\n"));\r
-#endif /* DEBUG */\r
-\r
- CurrentCalendarNoteError=GE_INTERNALERROR;\r
- break;\r
-\r
- }\r
-}\r
-\r
-GSM_Error N6110_GetCalendarNote(GSM_CalendarNote *CalendarNote)\r
-{\r
-\r
- unsigned char req[] = { N6110_FRAME_HEADER,\r
- 0x66, 0x00\r
- };\r
- GSM_Error error;\r
-\r
- req[4]=CalendarNote->Location;\r
-\r
- CurrentCalendarNote = CalendarNote;\r
-\r
- error=NULL_SendMessageSequence\r
- (20, &CurrentCalendarNoteError, 5, 0x13, req);\r
-\r
- CurrentCalendarNote = NULL;\r
-\r
- return error;\r
-}\r
-\r
-void N6110_ReplyWriteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#ifdef DEBUG\r
- switch(MessageBuffer[4]) {\r
- /* This message is also sent when the user enters the new entry on keypad */\r
- case 0x01:\r
- fprintf(stdout, _("Message: Calendar note write succesfull!\n"));break; \r
- case 0x73:\r
- fprintf(stdout, _("Message: Calendar note write failed!\n"));break;\r
- case 0x7d:\r
- fprintf(stdout, _("Message: Calendar note write failed!\n"));break;\r
- default:\r
- fprintf(stdout, _("Unknown message of type 0x13 and subtype 0x65\n"));break;\r
- }\r
-#endif\r
-\r
- switch(MessageBuffer[4]) {\r
- case 0x01: CurrentCalendarNoteError=GE_NONE; break; \r
- case 0x73: CurrentCalendarNoteError=GE_INTERNALERROR; break;\r
- case 0x7d: CurrentCalendarNoteError=GE_INTERNALERROR; break;\r
- default : AppendLogText("Unknown msg\n",false); break;\r
- }\r
-}\r
-\r
-GSM_Error N6110_WriteCalendarNote(GSM_CalendarNote *CalendarNote)\r
-{\r
-\r
- unsigned char req[200] = { N6110_FRAME_HEADER,\r
- 0x64, 0x01, 0x10,\r
- 0x00, /* Length of the rest of the frame. */\r
- 0x00, /* The type of calendar note */\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
- };\r
-\r
- typedef struct {\r
- char *model;\r
- unsigned char call;\r
- unsigned char meeting;\r
- unsigned char birthday;\r
- unsigned char reminder;\r
- } calendar_model_length;\r
- \r
- /* Length of entries */\r
- calendar_model_length calendar_lengths[] =\r
- {\r
- /*model,CallTo,Meeting,Birthday,Reminder*/\r
- {"NHM-5",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses\r
- {"NHM-6",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses\r
- {"NSE-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 [HKEY_LOCAL_MACHINE\Software\Nokia\Data Suite\3.0\Calendar]\r
- {"NSM-1",0x1e,0x18,0x18,0x24}, //from NCDS3 \r
- {"NSK-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 \r
- {"NSB-3",0x20,0x14,0x14,0x1e}, //from NCDS3\r
- {"", 0, 0, 0, 0 } //end of table\r
- };\r
-\r
- int i, j, current;\r
-\r
- u8 mychar;\r
-
- u8 mychar1,mychar2;
- \r
- GSM_Error error;\r
- \r
- /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */\r
- char model[64];\r
-\r
- req[7]=CalendarNote->Type;\r
-\r
- EncodeDateTime(req+8, &CalendarNote->Time);\r
- req[14] = CalendarNote->Time.Timezone;\r
-\r
- if (CalendarNote->Alarm.Year) {\r
- EncodeDateTime(req+15, &CalendarNote->Alarm);\r
- req[21] = CalendarNote->Alarm.Timezone;\r
- }\r
-\r
- req[22]=strlen(CalendarNote->Text);\r
- \r
- current=23;\r
-\r
- if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {\r
- req[22]++; // one additional char\r
- req[current++]=0x01; //we use now subset 1\r
- }\r
- \r
- for (i=0; i<strlen(CalendarNote->Text); i++) {\r
- j=0;\r
- mychar=CalendarNote->Text[i];\r
- if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {\r
- if (EncodeWithUTF8Alphabet(mychar,&mychar1,&mychar2)) {
- req[current++]=mychar1;\r
- req[current++]=mychar2;\r
- req[23]=0x03; //use subset 3\r
- req[22]++; // one additional char\r
- j=-1;\r
- }
- }\r
- if (j!=-1) {\r
- /* Enables/disables blinking */\r
- if (mychar=='~') req[current++]=0x01;\r
- else req[current++]=mychar;\r
- }\r
- }\r
-\r
- req[current++]=strlen(CalendarNote->Phone);\r
-\r
- for (i=0; i<strlen(CalendarNote->Phone); i++)\r
- req[current++]=CalendarNote->Phone[i];\r
-\r
- while (N6110_GetModel(model) != GE_NONE)\r
- sleep(1);\r
-\r
- /* Checking maximal length */\r
- i=0;\r
- while (strcmp(calendar_lengths[i].model,"")) {\r
- if (!strcmp(calendar_lengths[i].model,model)) {\r
- switch (CalendarNote->Type) {\r
- case GCN_REMINDER:if (req[22]>calendar_lengths[i].reminder) return GE_TOOLONG;break;\r
- case GCN_MEETING :if (req[22]>calendar_lengths[i].meeting) return GE_TOOLONG;break;\r
- case GCN_BIRTHDAY:if (req[22]>calendar_lengths[i].birthday) return GE_TOOLONG;break;\r
- case GCN_CALL :if (strlen(CalendarNote->Phone)>calendar_lengths[i].call) return GE_TOOLONG;break;\r
- }\r
- break;\r
- }\r
- i++;\r
- }\r
-\r
- CurrentCalendarNote = CalendarNote;\r
-\r
- error=NULL_SendMessageSequence\r
- (20, &CurrentCalendarNoteError, current, 0x13, req);\r
-\r
- CurrentCalendarNote = NULL;\r
-\r
- return error;\r
-}\r
-\r
-void N6110_ReplyDeleteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#ifdef DEBUG\r
- switch (MessageBuffer[4]) {\r
- /* This message is also sent when the user deletes an old entry on\r
- keypad or moves an old entry somewhere (there is also `write'\r
- message). */\r
- case 0x01:fprintf(stdout, _("Message: Calendar note deleted\n"));break;\r
- case 0x93:fprintf(stdout, _("Message: Calendar note can't be deleted\n"));break;\r
- default :fprintf(stdout, _("Message: Calendar note deleting error\n"));break;\r
- }\r
-#endif\r
-\r
- switch (MessageBuffer[4]) {\r
- case 0x01:CurrentCalendarNoteError=GE_NONE;break;\r
- case 0x93:CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;break;\r
- default :CurrentCalendarNoteError=GE_INTERNALERROR;break;\r
- }\r
-}\r
-\r
-GSM_Error N6110_DeleteCalendarNote(GSM_CalendarNote *CalendarNote)\r
-{\r
-\r
- unsigned char req[] = { N6110_FRAME_HEADER,\r
- 0x68, 0x00\r
- };\r
-\r
- req[4]=CalendarNote->Location;\r
-\r
- return NULL_SendMessageSequence (20, &CurrentCalendarNoteError, 5, 0x13, req);\r
-}\r
-\r
-void N6110_ReplyRFBatteryLevel(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Phone status received:\n"));\r
- fprintf(stdout, _(" Mode: "));\r
-\r
- switch (MessageBuffer[4]) {\r
-\r
- case 0x01:\r
-\r
- fprintf(stdout, _("registered within the network\n"));\r
- break;\r
- \r
- /* I was really amazing why is there a hole in the type of 0x02, now I\r
- know... */\r
- case 0x02: fprintf(stdout, _("call in progress\n")); break; /* ringing or already answered call */\r
- case 0x03: fprintf(stdout, _("waiting for security code\n")); break;\r
- case 0x04: fprintf(stdout, _("powered off\n")); break;\r
- default : fprintf(stdout, _("unknown\n"));\r
-\r
- }\r
-\r
- fprintf(stdout, _(" Power source: "));\r
-\r
- switch (MessageBuffer[7]) {\r
-\r
- case 0x01: fprintf(stdout, _("AC/DC\n")); break;\r
- case 0x02: fprintf(stdout, _("battery\n")); break;\r
- default : fprintf(stdout, _("unknown\n"));\r
-\r
- }\r
-\r
- fprintf(stdout, _(" Battery Level: %d\n"), MessageBuffer[8]);\r
- fprintf(stdout, _(" Signal strength: %d\n"), MessageBuffer[5]);\r
-#endif /* DEBUG */\r
-\r
- CurrentRFLevel=MessageBuffer[5];\r
- CurrentBatteryLevel=MessageBuffer[8];\r
- CurrentPowerSource=MessageBuffer[7];\r
-}\r
-\r
-\r
-GSM_Error N6110_GetRFLevel(GSM_RFUnits *units, float *level)\r
-{\r
-\r
- /* FIXME - these values are from 3810 code, may be incorrect. Map from\r
- values returned in status packet to the the values returned by the AT+CSQ\r
- command. */\r
- float csq_map[5] = {0, 8, 16, 24, 31};\r
-\r
- int timeout=10;\r
- int rf_level;\r
- \r
- char screen[NM_MAX_SCREEN_WIDTH];\r
-\r
- CurrentRFLevel=-1;\r
- \r
- if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {\r
-\r
- if (N6110_NetMonitor(1, screen)!=GE_NONE)\r
- return GE_INTERNALERROR;\r
- \r
- rf_level=4;\r
- \r
- if (screen[4]!='-') {\r
- if (screen[5]=='9' && screen[6]>'4') rf_level=1;\r
- if (screen[5]=='9' && screen[6]<'5') rf_level=2;\r
- if (screen[5]=='8' && screen[6]>'4') rf_level=3; \r
- } else rf_level=0;\r
-\r
- /* Arbitrary units. */\r
- if (*units == GRF_Arbitrary) {\r
- *level = rf_level;\r
- return (GE_NONE);\r
- }\r
- \r
- } else {\r
- N6110_SendStatusRequest();\r
-\r
- /* Wait for timeout or other error. */\r
- while (timeout != 0 && CurrentRFLevel == -1 ) {\r
-\r
- if (--timeout == 0)\r
- return (GE_TIMEOUT);\r
-\r
- usleep (100000);\r
- }\r
-\r
- /* Make copy in case it changes. */\r
- rf_level = CurrentRFLevel;\r
-\r
- if (rf_level == -1)\r
- return (GE_NOLINK);\r
-\r
- /* Now convert between the different units we support. */\r
-\r
- /* Arbitrary units. */\r
- if (*units == GRF_Arbitrary) {\r
- *level = rf_level;\r
- return (GE_NONE);\r
- }\r
-\r
- /* CSQ units. */\r
- if (*units == GRF_CSQ) {\r
-\r
- if (rf_level <=4)\r
- *level = csq_map[rf_level];\r
- else\r
- *level = 99; /* Unknown/undefined */\r
-\r
- return (GE_NONE);\r
- }\r
- }\r
-\r
- /* Unit type is one we don't handle so return error */\r
- return (GE_INTERNALERROR);\r
-}\r
-\r
-\r
-GSM_Error N6110_GetBatteryLevel(GSM_BatteryUnits *units, float *level)\r
-{\r
-\r int timeout=10;\r
- int batt_level;\r
-\r
- char screen[NM_MAX_SCREEN_WIDTH];\r
-\r
- CurrentBatteryLevel=-1;\r
-\r
- if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {\r
-\r
- if (N6110_NetMonitor(23, screen)!=GE_NONE)\r
- return GE_NOLINK;\r
- \r
- batt_level=4;\r
- \r
- if (screen[29]=='7') batt_level=3;\r
- if (screen[29]=='5') batt_level=2;\r
- if (screen[29]=='2') batt_level=1;\r
- \r
- /* Only units we handle at present are GBU_Arbitrary */\r
- if (*units == GBU_Arbitrary) {\r
- *level = batt_level;\r
- return (GE_NONE);\r
- }\r
-\r
- return (GE_INTERNALERROR); \r
- \r
- } else {\r
- N6110_SendStatusRequest();\r
-\r
- /* Wait for timeout or other error. */\r
- while (timeout != 0 && CurrentBatteryLevel == -1 ) {\r
-\r
- if (--timeout == 0)\r
- return (GE_TIMEOUT);\r
-\r
- usleep (100000);\r
- }\r
-\r
- /* Take copy in case it changes. */\r
- batt_level = CurrentBatteryLevel;\r
-\r
- if (batt_level != -1) {\r
-\r
- /* Only units we handle at present are GBU_Arbitrary */\r
- if (*units == GBU_Arbitrary) {\r
- *level = batt_level;\r
- return (GE_NONE);\r
- }\r
-\r
- return (GE_INTERNALERROR);\r
- }\r
- else\r
- return (GE_NOLINK);\r
- }\r
-}\r
-\r
-GSM_Error N6110_GetPowerSource(GSM_PowerSource *source)\r
-{\r
-\r
- int timeout=10;\r
-\r
- char screen[NM_MAX_SCREEN_WIDTH];\r
-\r
- CurrentPowerSource=-1;\r
-\r
- if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) { \r
-\r
- if (N6110_NetMonitor(20, screen)!=GE_NONE)\r
- return GE_NOLINK;\r
- \r
- CurrentPowerSource=GPS_ACDC;\r
-\r
- if (screen[6]=='x') CurrentPowerSource=GPS_BATTERY;\r
-\r
- *source=CurrentPowerSource; \r
- \r
- return GE_NONE; \r
- } else {\r
- N6110_SendStatusRequest();\r
-\r
- /* Wait for timeout or other error. */\r
- while (timeout != 0 && CurrentPowerSource == -1 ) {\r
-\r
- if (--timeout == 0)\r
- return (GE_TIMEOUT);\r
-\r
- usleep (100000);\r
- }\r
-\r
- if (CurrentPowerSource != -1) {\r
- *source=CurrentPowerSource;\r
- return (GE_NONE);\r
- }\r
- else\r
- return (GE_NOLINK);\r
- }\r
-}\r
-\r
-void N6110_ReplyGetDisplayStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int i;\r
-\r
- for (i=0; i<MessageBuffer[4];i++)\r
- if (MessageBuffer[2*i+6]==2)\r
- CurrentDisplayStatus|=1<<(MessageBuffer[2*i+5]-1);\r
- else\r
- CurrentDisplayStatus&= (0xff - (1<<(MessageBuffer[2*i+5]-1)));\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Call in progress: %s\n"), CurrentDisplayStatus & (1<<DS_Call_In_Progress)?"on":"off");\r
- fprintf(stdout, _("Unknown: %s\n"), CurrentDisplayStatus & (1<<DS_Unknown)?"on":"off");\r
- fprintf(stdout, _("Unread SMS: %s\n"), CurrentDisplayStatus & (1<<DS_Unread_SMS)?"on":"off");\r
- fprintf(stdout, _("Voice call: %s\n"), CurrentDisplayStatus & (1<<DS_Voice_Call)?"on":"off");\r
- fprintf(stdout, _("Fax call active: %s\n"), CurrentDisplayStatus & (1<<DS_Fax_Call)?"on":"off");\r
- fprintf(stdout, _("Data call active: %s\n"), CurrentDisplayStatus & (1<<DS_Data_Call)?"on":"off");\r
- fprintf(stdout, _("Keyboard lock: %s\n"), CurrentDisplayStatus & (1<<DS_Keyboard_Lock)?"on":"off");\r
- fprintf(stdout, _("SMS storage full: %s\n"), CurrentDisplayStatus & (1<<DS_SMS_Storage_Full)?"on":"off");\r
-#endif /* DEBUG */\r
-\r
- CurrentDisplayStatusError=GE_NONE;\r
-}\r
-\r
-GSM_Error N6110_GetDisplayStatus(int *Status) {\r
-\r
- unsigned char req[4]={ N6110_FRAME_HEADER, 0x51 };\r
-\r
- GSM_Error error;\r
-\r
- error=NULL_SendMessageSequence\r
- (10, &CurrentDisplayStatusError, 4, 0x0d, req);\r
- if (error!=GE_NONE) return error;\r
- \r
- *Status=CurrentDisplayStatus;\r
-\r
- return GE_NONE;\r
-}\r
-\r
-GSM_Error N6110_DialVoice(char *Number) {\r
-/* This commented sequence doesn't work on N3210/3310/6210/7110 */\r
-// unsigned char req[64]={N6110_FRAME_HEADER, 0x01};\r
-// unsigned char req_end[]={0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};\r
-// int i=0;\r
-// req[4]=strlen(Number);\r
-// for(i=0; i < strlen(Number) ; i++)\r
-// req[5+i]=Number[i];\r
-// memcpy(req+5+strlen(Number), req_end, 10);\r
-// return NULL_SendMessageSequence\r
-// (20, &CurrentDialVoiceError, 13+strlen(Number), 0x01, req);\r
-\r
- unsigned char req[64]={0x00,0x01,0x7c,\r
- 0x01}; //call command\r
-\r
- int i=0; \r
- \r
- GSM_Error error;\r
-\r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
-\r
- for(i=0; i < strlen(Number) ; i++) req[4+i]=Number[i];\r
- \r
- req[4+i+1]=0;\r
- \r
- return NULL_SendMessageSequence\r
- (20, &CurrentDialVoiceError, 4+strlen(Number)+1, 0x40, req); \r
-}\r
-\r
-/* Dial a data call - type specifies request to use: \r
- type 0 should normally be used\r
- type 1 should be used when calling a digital line - corresponds to ats35=0\r
- Maybe one day we'll know what they mean!\r
-*/\r
-GSM_Error N6110_DialData(char *Number, char type, void (* callpassup)(char c))
+GSM_Error N6110_GetVoiceMailbox ( GSM_PhonebookEntry *entry)
{
- unsigned char req[100] = { N6110_FRAME_HEADER, 0x01 };
- unsigned char *req_end;
- unsigned char req_end0[] = { 0x01, /* make a data call = type 0x01 */
- 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
- 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00 };
- unsigned char req_end1[] = { 0x01,
- 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
- 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
- 0x88,0x90,0x21,0x48,0x40,0xbb };
- unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
- 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
- 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
- unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
- 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
- 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
- unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
- 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
- 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
- 0x20,0x15,0x63,0x80 };
+ unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
- int i = 0;
- u8 size;
+ GSM_Error error;
+
+ CurrentPhonebookEntry = entry;
- CurrentCallPassup=callpassup;
+ req[4] = N6110_MEMORY_VOICE;
+ req[5] = 0x00; /* Location - isn't important, but... */
- switch (type) {
- case 0:
- req_end = req_end0;
- size = sizeof(req_end0);
- break;
- case 1:
- Protocol->SendMessage(sizeof(req3), 0x01, req3);
- usleep(1000000);\r
- Protocol->SendMessage(sizeof(req4), 0x01, req4);
- usleep(1000000);
- req_end = req_end1;
- size = sizeof(req_end1);
- break;
- case -1: /* Just used to set the call passup */
- return GE_NONE;
- break;
- default:
- req_end = req_end0;
- size = sizeof(req_end0);
- break;
- }
+ error=NULL_SendMessageSequence
+ (20, &CurrentPhonebookError, 7, 0x03, req);
+
+ CurrentPhonebookEntry = NULL;
+
+ return error;
+}
- req[4] = strlen(Number);
+void N6110_ReplyGetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
- for(i = 0; i < strlen(Number) ; i++)
- req[5+i] = Number[i];
+ int i, count;
+
+ GSM_Bitmap NullBitmap;
- memcpy(req + 5 + strlen(Number), req_end, size);
+ DecodeNetworkCode(MessageBuffer+5, NullBitmap.netcode);
+
+ count=8;
- Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);\r
- usleep(1000000);\r
-\r
- if (type != 1) {\r
- Protocol->SendMessage(26, 0x01, req2);
- usleep(1000000);\r
- }
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Info about downloaded operator name received: %s network (for gnokii \"%s\", for phone \""),
+ NullBitmap.netcode,
+ GSM_GetNetworkName(NullBitmap.netcode));
+#endif
+
+ i=count;
+ while (MessageBuffer[count]!=0) {
+#ifdef DEBUG
+ fprintf(stdout,_("%c"),MessageBuffer[count]);
+#endif
+ count++;
+ }
+
+ strcpy(CurrentGetOperatorNameNetwork->Code, NullBitmap.netcode);
+ strncpy(CurrentGetOperatorNameNetwork->Name, MessageBuffer+i,count-i+1);
- return (GE_NONE);
+#ifdef DEBUG
+ fprintf(stdout,_("\")\n"));
+#endif
+
+ CurrentGetOperatorNameError=GE_NONE;
}
-GSM_Error N6110_GetIncomingCallNr(char *Number)\r
-{\r
-\r
- if (*CurrentIncomingCall != ' ') {\r
- strcpy(Number, CurrentIncomingCall);\r
- return GE_NONE;\r
- }\r
- else\r
- return GE_BUSY;\r
-}\r
-
-GSM_Error N6110_CancelCall(void)
+GSM_Error N6110_GetOperatorName (GSM_Network *operator)
{
-// This frame & method works only on 61xx/51xx
-// unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
-// req[4]=CurrentCallSequenceNumber;
-// Protocol->SendMessage(6, 0x01, req);
-// return GE_NONE;
-
+ unsigned char req[] = { 0x00,0x01,0x8c,0x00};
+
GSM_Error error;
- unsigned char req[]={0x00,0x01,0x7c,0x03};
-
- /* Checking */
error=N6110_EnableExtendedCommands(0x01);
if (error!=GE_NONE) return error;
- return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
-}
-\r
-void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
- \r
- switch(MessageBuffer[3]) {\r
-\r
- case 0x0b:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Security code accepted.\n"));\r
-#endif /* DEBUG */\r
- CurrentSecurityCodeError = GE_NONE;\r
- break;\r
-\r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));\r
-#endif /* DEBUG */\r
- CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;\r
- }\r
-}\r
-\r
-GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)\r
-{\r
-\r
- unsigned char req[15] = { N6110_FRAME_HEADER,\r
- 0x0a, /* Enter code request. */\r
- 0x00 /* Type of the entered code. */\r
- };\r
- int i=0;\r
-\r
- req[4]=SecurityCode.Type;\r
-\r
- for (i=0; i<strlen(SecurityCode.Code);i++)\r
- req[5+i]=SecurityCode.Code[i];\r
-\r
- req[5+strlen(SecurityCode.Code)]=0x00;\r
- req[6+strlen(SecurityCode.Code)]=0x00;\r
-\r
- return NULL_SendMessageSequence\r
- (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);\r
-}\r
-\r
-void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
- \r
- *CurrentSecurityCodeStatus = MessageBuffer[4];\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Security Code status received: "));\r
-\r
- switch(*CurrentSecurityCodeStatus) {\r
-\r
- case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;\r
- case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;\r
- case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;\r
- case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;\r
- case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;\r
- case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;\r
- default : fprintf(stdout, _("Unknown!\n"));\r
- }\r
- \r
-#endif /* DEBUG */\r
-\r
- CurrentSecurityCodeError = GE_NONE;\r
-}\r
-\r
-GSM_Error N6110_GetSecurityCodeStatus(int *Status)\r
-{\r
-\r
- unsigned char req[4] = { N6110_FRAME_HEADER,\r
- 0x07\r
- };\r
-\r
- CurrentSecurityCodeStatus=Status;\r
-\r
- return NULL_SendMessageSequence\r
- (20, &CurrentSecurityCodeError, 4, 0x08, req);\r
-}\r
-\r
-void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int i;\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Security code received: "));\r
- switch (MessageBuffer[3]) {\r
- case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;\r
- case GSCT_Pin: fprintf(stdout, _("PIN"));break;\r
- case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;\r
- case GSCT_Puk: fprintf(stdout, _("PUK"));break;\r
- case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;\r
- default: fprintf(stdout, _("unknown !"));break;\r
- }\r
- if (MessageBuffer[4]==1) {\r
- fprintf(stdout, _(" allowed, value \""));\r
- if (MessageBuffer[3]==GSCT_SecurityCode) {\r
- for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}\r
- }\r
- if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||\r
- MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {\r
- for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}\r
- }\r
- fprintf(stdout, _("\""));\r
- } else {\r
- fprintf(stdout, _(" not allowed")); \r
- }\r
- fprintf(stdout, _("\n")); \r
-#endif /* DEBUG */\r
- \r
- if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */\r
- && MessageBuffer[4]==1) { /* It's allowed */\r
- if (MessageBuffer[3]==GSCT_SecurityCode) {\r
- for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}\r
- CurrentSecurityCode->Code[5]=0;\r
- }\r
- if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||\r
- MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {\r
- for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}\r
- CurrentSecurityCode->Code[4]=0;\r
- }\r
- CurrentSecurityCodeError=GE_NONE;\r
- } else\r
- CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;\r
-}\r
-\r
-GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)\r
-{\r
-\r
- unsigned char req[4] = { 0x00,\r
- 0x01,0x6e, /* Get code request. */\r
- 0x00 }; /* Type of the requested code. */\r
-\r
- GSM_Error error;\r
- \r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
- \r
- req[3]=SecurityCode->Type;\r
-\r
- CurrentSecurityCode=SecurityCode;\r
-\r
- return NULL_SendMessageSequence\r
- (20, &CurrentSecurityCodeError, 4, 0x40, req);\r
-}\r
-\r
-void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: answer for PlayTone frame\n")); \r
-#endif\r
- \r
- CurrentPlayToneError=GE_NONE; \r
-}\r
-\r
-GSM_Error N6110_PlayTone(int Herz, u8 Volume)\r
-{\r
- unsigned char req[6] = { 0x00,0x01,0x8f,\r
- 0x00, /* Volume */\r
- 0x00, /* HerzLo */\r
- 0x00 }; /* HerzHi */\r
-\r
- GSM_Error error;\r
-\r
- /* PlayTone wasn't used earlier */\r
- if (CurrentPlayToneError==GE_UNKNOWN) {\r
- if (CurrentConnectionType!=GCT_MBUS)\r
- CurrentDisableKeepAlive=true;\r
-\r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
- }\r
-\r
- /* For Herz==255*255 we have silent */ \r
- if (Herz!=255*255) {\r
- req[3]=Volume;\r
-\r
- req[5]=Herz%256;\r
- req[4]=Herz/256;\r
- } else {\r
- req[3]=0;\r
-\r
- req[5]=0;\r
- req[4]=0;\r
- }\r
-\r
-#ifdef WIN32\r
- /* For Herz==255*255 we have silent and additionaly\r
- we wait for phone answer - it's important for MBUS */\r
- if (Herz==255*255) {\r
- error=NULL_SendMessageSequence\r
- (20, &CurrentPlayToneError, 6, 0x40, req);\r
-\r
- CurrentPlayToneError=GE_UNKNOWN;\r
- CurrentDisableKeepAlive=false;\r
-\r
- if (error!=GE_NONE) return error;\r
- } else {\r
- Protocol->SendMessage(6,0x40,req);\r
- }\r
-#else\r
- error=NULL_SendMessageSequence\r
- (20, &CurrentPlayToneError, 6, 0x40, req);\r
-\r
- /* For Herz==255*255 we wait for phone answer - it's important for MBUS */\r
- if (Herz==255*255) {\r
- CurrentPlayToneError=GE_UNKNOWN;\r
- CurrentDisableKeepAlive=false;\r
- }\r
- \r
- if (error!=GE_NONE) return error;\r
-\r
-#endif\r
- \r
- return(GE_NONE);\r
-}\r
-\r
-void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- if (MessageBuffer[4]==0x01) {\r
- DecodeDateTime(MessageBuffer+8, CurrentDateTime);\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Date and time\n"));\r
- fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);\r
- fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);\r
-#endif /* DEBUG */\r
-\r
- CurrentDateTime->IsSet=true;\r
- } else {\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Date and time not set in phone\n"));\r
-#endif\r
-\r
- CurrentDateTime->IsSet=false;\r
- }\r
- \r
- CurrentDateTimeError=GE_NONE;\r
-}\r
-\r
-GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)\r
-{\r
- return N6110_PrivGetDateTime(date_time,0x11);\r
-}\r
-\r
-GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)\r
-{\r
- unsigned char req[] = {N6110_FRAME_HEADER, 0x62};\r
-\r
- CurrentDateTime=date_time;\r
-\r
- return NULL_SendMessageSequence\r
- (50, &CurrentDateTimeError, 4, msgtype, req);\r
-}\r
-\r
-void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Alarm\n"));\r
- fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);\r
- fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));\r
-#endif /* DEBUG */\r
-\r
- CurrentAlarm->Hour=MessageBuffer[9];\r
- CurrentAlarm->Minute=MessageBuffer[10];\r
- CurrentAlarm->Second=0;\r
-\r
- CurrentAlarm->IsSet=(MessageBuffer[8]==2);\r
-\r
- CurrentAlarmError=GE_NONE;\r
-}\r
-\r
-GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)\r
-{\r
- return N6110_PrivGetAlarm(alarm_number,date_time,0x11);\r
-}\r
-\r
-GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)\r
-{\r
- unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};\r
-\r
- CurrentAlarm=date_time;\r
-\r
- return NULL_SendMessageSequence\r
- (50, &CurrentAlarmError, 4, msgtype, req);\r
-}\r
-\r
-void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
- \r
- switch (MessageBuffer[3]) {\r
-\r
- case 0x34:\r
-\r
- CurrentMessageCenter->No=MessageBuffer[4];\r
- CurrentMessageCenter->Format=MessageBuffer[6];\r
- CurrentMessageCenter->Validity=MessageBuffer[8];\r
- sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);\r
-\r
- sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));\r
-\r
- sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: SMS Center received:\n"));\r
- fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);\r
- fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);\r
- fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);\r
- \r
- fprintf(stdout, _(" SMS Center message format is "));\r
-\r
- switch (CurrentMessageCenter->Format) {\r
-\r
- case GSMF_Text : fprintf(stdout, _("Text")); break;\r
- case GSMF_Paging: fprintf(stdout, _("Paging")); break;\r
- case GSMF_Fax : fprintf(stdout, _("Fax")); break;\r
- case GSMF_Email : fprintf(stdout, _("Email")); break;\r
- default : fprintf(stdout, _("Unknown"));\r
- }\r
-\r
- fprintf(stdout, "\n");\r
-\r
- fprintf(stdout, _(" SMS Center message validity is "));\r
-\r
- switch (CurrentMessageCenter->Validity) {\r
-\r
- case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;\r
- case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;\r
- case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;\r
- case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;\r
- case GSMV_1_Week : fprintf(stdout, _("1 week")); break;\r
- case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;\r
- default : fprintf(stdout, _("Unknown"));\r
- }\r
-\r
- fprintf(stdout, "\n");\r
-\r
-#endif /* DEBUG */\r
-\r
- CurrentMessageCenterError=GE_NONE;\r
-\r
- break;\r
-\r
- case 0x35:\r
-\r
- /* Number of entries depends on SIM card */\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: SMS Center error received:\n"));\r
- fprintf(stdout, _(" The request for SMS Center failed.\n"));\r
-#endif /* DEBUG */\r
-\r
- /* FIXME: appropriate error. */\r
- CurrentMessageCenterError=GE_INTERNALERROR;\r
-\r
- break; \r
-\r
- }\r
-}\r
-\r
-/* This function sends to the mobile phone a request for the SMS Center */\r
-GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)\r
-{\r
- unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,\r
- 0x00 /* SMS Center Number. */\r
- };\r
-\r
- req[5]=MessageCenter->No;\r
-\r
- CurrentMessageCenter=MessageCenter;\r
-\r
- return NULL_SendMessageSequence\r
- (50, &CurrentMessageCenterError, 6, 0x02, req);\r
-}\r
-\r
-void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: SMS Center correctly set.\n"));\r
-#endif\r
- CurrentMessageCenterError=GE_NONE;\r
-}\r
-\r
-/* This function set the SMS Center profile on the phone. */\r
-GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)\r
-{\r
- unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,\r
- 0x00, /* SMS Center Number. */\r
- 0x00, /* Unknown. */\r
- 0x00, /* SMS Message Format. */\r
- 0x00, /* Unknown. */\r
- 0x00, /* Validity. */\r
- 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */\r
- 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */\r
- /* Message Center Name. */\r
- };\r
-\r
- req[5]=MessageCenter->No;\r
- req[7]=MessageCenter->Format;\r
- req[9]=MessageCenter->Validity;\r
-\r
- req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);\r
-\r
- req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);\r
-\r
- sprintf(req+34, "%s", MessageCenter->Name);\r
-\r
- CurrentMessageCenter=MessageCenter;\r
-\r
- return NULL_SendMessageSequence\r
- (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);\r
-}\r
-\r
-void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[3]) {\r
-\r
- case 0x37:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: SMS Status Received\n"));\r
- fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);\r
- fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);\r
-#endif /* DEBUG */\r
-\r
- CurrentSMSStatus->UnRead = MessageBuffer[11];\r
- CurrentSMSStatus->Number = MessageBuffer[10];\r
- \r
- CurrentSMSStatusError = GE_NONE;\r
- break;\r
-\r
- case 0x38:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));\r
-#endif /* DEBUG */\r
-\r
- CurrentSMSStatusError = GE_INTERNALERROR;\r
- break;\r
- \r
- }\r
-}\r
-\r
-GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)\r
-{\r
- unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};\r
-\r
- CurrentSMSStatus = Status;\r
-\r
- return NULL_SendMessageSequence\r
- (10, &CurrentSMSStatusError, 5, 0x14, req);\r
-}\r
+ CurrentGetOperatorNameNetwork = operator;
-GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
-{
- folders->number=2;
+ error=NULL_SendMessageSequence
+ (20, &CurrentGetOperatorNameError, 4, 0x40, req);
- strcpy(folders->Folder[0].Name,"Inbox");
- strcpy(folders->Folder[1].Name,"Outbox");
+ CurrentGetOperatorNameNetwork = NULL;
- return GE_NONE;
+ return error;
}
-\r
-GSM_Error N6110_GetIMEI(char *imei)\r
-{\r
- if (strlen(Current_IMEI)>0) {\r
- strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);\r
- return (GE_NONE);\r
- }\r
- else\r
- return (GE_TRYAGAIN);\r
-}\r
-\r
-GSM_Error N6110_GetRevision(char *revision)\r
-{\r
-\r
- if (strlen(Current_Revision)>0) {\r
- strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);\r
- return (GE_NONE);\r
- }\r
- else\r
- return (GE_TRYAGAIN);\r
-}\r
-\r
-GSM_Error N6110_GetModel(char *model)\r
-{\r
- if (strlen(Current_Model)>0) {\r
- strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);\r
- return (GE_NONE);\r
- }\r
- else\r
- return (GE_TRYAGAIN);\r
-}\r
-\r
-void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[4]) {\r
-\r
- case 0x01:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Date and time set correctly\n"));\r
-#endif /* DEBUG */\r
- CurrentSetDateTimeError=GE_NONE;\r
- break;\r
- \r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Date and time setting error\n"));\r
-#endif /* DEBUG */\r
- CurrentSetDateTimeError=GE_INVALIDDATETIME;\r
-\r
- }\r
-}\r
-\r
-/* Needs SIM card with PIN in phone */\r
-GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)\r
-{\r
- return N6110_PrivSetDateTime(date_time,0x11);\r
-}\r
-\r
-/* Needs SIM card with PIN in phone */\r
-GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)\r
-{\r
-\r
- unsigned char req[] = { N6110_FRAME_HEADER,\r
- 0x60, /* set-time subtype */\r
- 0x01, 0x01, 0x07, /* unknown */\r
- 0x00, 0x00, /* Year (0x07cf = 1999) */\r
- 0x00, 0x00, /* Month Day */\r
- 0x00, 0x00, /* Hours Minutes */\r
- 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */\r
- };\r
-\r
- EncodeDateTime(req+7, date_time);\r
-\r
- return NULL_SendMessageSequence\r
- (20, &CurrentSetDateTimeError, 14, msgtype, req);\r
-}\r
-\r
-void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[4]) {\r
-\r
- case 0x01:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Alarm set correctly\n"));\r
-#endif /* DEBUG */\r
- CurrentSetAlarmError=GE_NONE;\r
- break;\r
- \r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Alarm setting error\n"));\r
-#endif /* DEBUG */\r
- CurrentSetAlarmError=GE_INVALIDDATETIME;\r
-\r
- }\r
-}\r
-\r
-/* FIXME: we should also allow to set the alarm off :-) */\r
-GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)\r
-{\r
- return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);\r
-}\r
-\r
-/* FIXME: we should also allow to set the alarm off :-) */\r
-GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)\r
-{\r
-\r
- unsigned char req[] = { N6110_FRAME_HEADER,\r
- 0x6b, /* set-alarm subtype */\r
- 0x01, 0x20, 0x03, /* unknown */\r
- 0x02, /* should be alarm on/off, but it don't works */\r
- 0x00, 0x00, /* Hours Minutes */\r
- 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */\r
- };\r
-\r
- req[8] = date_time->Hour;\r
- req[9] = date_time->Minute;\r
-\r
- return NULL_SendMessageSequence\r
- (50, &CurrentSetAlarmError, 11, msgtype, req);\r
-}\r
-\r
-void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */\r
- char model[64];\r
-\r
- int i, tmp, count;\r
- \r
- switch (MessageBuffer[3]) {\r
-\r
- case 0x02:\r
-\r
- CurrentPhonebookEntry->Empty = true;\r
-\r
- count=MessageBuffer[5];\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Phonebook entry received:\n"));\r
- fprintf(stdout, _(" Name: "));\r
-\r
- for (tmp=0; tmp <count; tmp++)\r
- {\r
- if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking\r
- if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents\r
- fprintf(stdout, "%c", MessageBuffer[6+tmp]);\r
- }\r
-\r
- fprintf(stdout, "\n");\r
-#endif /* DEBUG */\r
-\r
- while (N6110_GetModel(model) != GE_NONE)\r
- sleep(1);\r
- \r
- if (GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM ||\r
- GetModelFeature (FN_PHONEBOOK)==F_PBK33INT) {//pbk with Unicode\r
- DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);\r
- CurrentPhonebookEntry->Name[count/2] = 0x00;\r
- } else {\r
- memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);\r
- CurrentPhonebookEntry->Name[count] = 0x00;\r
- }\r
-\r
- CurrentPhonebookEntry->Empty = false;\r
-\r
- for (tmp=0; tmp <count; tmp++)\r
- {\r
- if (GetModelFeature (FN_PHONEBOOK)==F_PBK33INT ||\r
- GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM) {//pbk with Unicode\r
- /* We check only 1'st, 3'rd, ... char */\r
- if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking\r
- if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents\r
- } else {\r
- if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking\r
- if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents\r
- }\r
- }\r
-\r
- i=7+count;\r
- count=MessageBuffer[6+count];\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _(" Number: "));\r
-\r
- for (tmp=0; tmp <count; tmp++)\r
- fprintf(stdout, "%c", MessageBuffer[i+tmp]);\r
-\r
- fprintf(stdout, "\n");\r
-#endif /* DEBUG */\r
-\r
- memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);\r
- CurrentPhonebookEntry->Number[count] = 0x00;\r
- CurrentPhonebookEntry->Group = MessageBuffer[i+count];\r
- \r
- /* Phone doesn't have entended phonebook */\r
- CurrentPhonebookEntry->SubEntriesCount = 0;\r
-\r
- /* But for these memories data is saved and we can save it using 7110/6210 style */\r
- if (CurrentPhonebookEntry->MemoryType==GMT_DC ||\r
- CurrentPhonebookEntry->MemoryType==GMT_RC ||\r
- CurrentPhonebookEntry->MemoryType==GMT_MC) {\r
- CurrentPhonebookEntry->SubEntriesCount = 1;\r
- CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;\r
- CurrentPhonebookEntry->SubEntries[0].NumberType=0;\r
- CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;\r
- DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _(" Date: "));\r
- fprintf(stdout, "%02u.%02u.%04u\n",\r
- CurrentPhonebookEntry->SubEntries[0].data.Date.Day,\r
- CurrentPhonebookEntry->SubEntries[0].data.Date.Month,\r
- CurrentPhonebookEntry->SubEntries[0].data.Date.Year);\r
- fprintf(stdout, _(" Time: "));\r
- fprintf(stdout, "%02u:%02u:%02u\n",\r
- CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,\r
- CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,\r
- CurrentPhonebookEntry->SubEntries[0].data.Date.Second);\r
-#endif /* DEBUG */\r
-\r
- /* These values are set, when date and time unavailable in phone.\r
- Values from 3310 - in other can be different */\r
- if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&\r
- CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&\r
- CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&\r
- CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&\r
- CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&\r
- CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)\r
- CurrentPhonebookEntry->SubEntriesCount = 0;\r
- }\r
-\r
- /* Signal no error to calling code. */\r
- CurrentPhonebookError = GE_NONE;\r
-\r
- break;\r
-\r
- case 0x03:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Phonebook read entry error received:\n"));\r
-#endif /* DEBUG */\r
-\r
- switch (MessageBuffer[4]) {\r
-\r
- case 0x7d:\r
-#ifdef DEBUG\r
- fprintf(stdout, _(" Invalid memory type!\n"));\r
-#endif /* DEBUG */\r
- CurrentPhonebookError = GE_INVALIDMEMORYTYPE;\r
- break;\r
-\r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout, _(" Unknown error!\n"));\r
-#endif /* DEBUG */\r
- CurrentPhonebookError = GE_INTERNALERROR;\r
- }\r
-\r
- break;\r
-\r
- }\r
-}\r
-\r
-/* Routine to get specifed phone book location. Designed to be called by\r
- application. Will block until location is retrieved or a timeout/error\r
- occurs. */\r
-GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)\r
-{\r
- unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};\r
-\r
- CurrentPhonebookEntry = entry;\r
-\r
- req[4] = N6110_GetMemoryType(entry->MemoryType);\r
- req[5] = entry->Location;\r
-\r
- return NULL_SendMessageSequence\r
- (50, &CurrentPhonebookError, 7, 0x03, req);\r
-}\r
-\r
-void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[3]) {\r
-\r
- case 0x05:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Phonebook written correctly.\n"));\r
-#endif /* DEBUG */\r
- CurrentPhonebookError = GE_NONE;\r
- break;\r
-\r
- case 0x06:\r
-\r
- switch (MessageBuffer[4]) {\r
- /* FIXME: other errors? When I send the phonebook with index of 350 it\r
- still report error 0x7d :-( */\r
- case 0x7d:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));\r
-#endif /* DEBUG */\r
- CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;\r
- break;\r
-\r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout, _(" Unknown error!\n"));\r
-#endif /* DEBUG */\r
- CurrentPhonebookError = GE_INTERNALERROR;\r
- }\r
- }\r
-}\r
-\r
-/* Routine to write phonebook location in phone. Designed to be called by\r
- application code. Will block until location is written or timeout\r
- occurs. */\r
-GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)\r
-{\r
- unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };\r
- int i=0, current=0;\r
-\r
- req[4] = N6110_GetMemoryType(entry->MemoryType);\r
- req[5] = entry->Location;\r
-\r
- current=7;\r
-\r
- if (GetModelFeature (FN_PHONEBOOK)==F_PBK33INT ||\r
- GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM) {\r
-\r
- req[6] = strlen(entry->Name)*2;\r
-\r
- EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));\r
- \r
- for (i=0; i<strlen(entry->Name); i++)\r
- {\r
- /* here we encode "special" chars */\r
- if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking\r
- if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents\r
- }\r
-\r
- current+=strlen(entry->Name)*2;\r
- } else {\r
-\r
- req[6] = strlen(entry->Name);\r
-\r
- for (i=0; i<strlen(entry->Name); i++)\r
- {\r
- req[current+i] = entry->Name[i];\r
-\r
- /* here we encode "special" chars */\r
- if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking\r
- if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents\r
- }\r
-\r
- current+=strlen(entry->Name);\r
- }\r
-\r
- req[current++]=strlen(entry->Number);\r
-\r
- for (i=0; i<strlen(entry->Number); i++)\r
- req[current+i] = entry->Number[i];\r
-\r
- current+=strlen(entry->Number);\r
-\r
- /* Jano: This allow to save 14 characters name into SIM memory, when\r
- No Group is selected. */\r
- if (entry->Group == 5)\r
- req[current++]=0xff;\r
- else\r
- req[current++]=entry->Group;\r
-\r
- return NULL_SendMessageSequence\r
- (50, &CurrentPhonebookError, current, 0x03, req);\r
-}\r
-\r
-void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch(MessageBuffer[3]) {\r
-\r
- case 0x00:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Netmonitor correctly set.\n"));\r
-#endif /* DEBUG */\r
- CurrentNetmonitorError=GE_NONE; \r
- break;\r
- \r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);\r
- fprintf(stdout, "%s\n", MessageBuffer+4);\r
-#endif /* DEBUG */\r
-\r
- strcpy(CurrentNetmonitor, MessageBuffer+4);\r
-\r
- CurrentNetmonitorError=GE_NONE; \r
- }\r
-}\r
-\r
-GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)\r
-{\r
- unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };\r
- \r
- GSM_Error error;\r
- \r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
-\r
- CurrentNetmonitor=Screen;\r
-\r
- req[3]=mode;\r
-\r
- return NULL_SendMessageSequence\r
- (20, &CurrentNetmonitorError, 4, 0x40, req);\r
-}\r
-\r
-/* Doesn't work in N3210. */\r
-/* In other allow to access phone menu without SIM card (just send any sequence) */\r
-GSM_Error N6110_SendDTMF(char *String)\r
-{\r
- unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,\r
- 0x00 /* Length of DTMF string. */\r
- };\r
- \r
- u8 length=strlen(String);\r
-\r
- if (length>59) length=59;\r
- \r
- req[4] = length;\r
- \r
- memcpy(req+5,String,length);\r
-\r
- return NULL_SendMessageSequence\r
- (20, &CurrentSendDTMFError, 5+length, 0x01, req);\r
-}\r
-\r
-void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[3]) {\r
-\r
- case 0x17:\r
-\r
- switch (MessageBuffer[4]) {\r
- case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;\r
- default : CurrentSpeedDialEntry->MemoryType = GMT_SM;\r
- }\r
- \r
- CurrentSpeedDialEntry->Location = MessageBuffer[5];\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Speed dial entry received:\n"));\r
- fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);\r
- fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);\r
- fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);\r
-#endif /* DEBUG */\r
-\r
- CurrentSpeedDialError=GE_NONE;\r
- break;\r
-\r
- case 0x18:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Speed dial entry error\n"));\r
-#endif /* DEBUG */\r
- CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;\r
- break;\r
-\r
- }\r
-}\r
-\r
-GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)\r
-{\r
-\r
- unsigned char req[] = { N6110_FRAME_HEADER,\r
- 0x16,\r
- 0x00 /* The number of speed dial. */\r
- };\r
-\r
- CurrentSpeedDialEntry = entry;\r
-\r
- req[4] = entry->Number;\r
-\r
- return NULL_SendMessageSequence\r
- (20, &CurrentSpeedDialError, 5, 0x03, req);\r
-}\r
-\r
-void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[3]) {\r
-\r
- case 0x1a:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Speed dial entry set.\n"));\r
-#endif /* DEBUG */\r
- CurrentSpeedDialError=GE_NONE;\r
- break;\r
-\r
- case 0x1b:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Speed dial entry setting error.\n"));\r
-#endif /* DEBUG */\r
- CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;\r
- break;\r
-\r
- }\r
-}\r
-\r
-GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)\r
-{\r
-\r
- unsigned char req[] = { N6110_FRAME_HEADER,\r
- 0x19,\r
- 0x00, /* Number */\r
- 0x00, /* Memory Type */\r
- 0x00 /* Location */\r
- };\r
-\r
- req[4] = entry->Number;\r
-\r
- switch (entry->MemoryType) {\r
- case GMT_ME: req[5] = 0x02;\r
- default : req[5] = 0x03;\r
- }\r
-\r
- req[6] = entry->Location;\r
-\r
- return NULL_SendMessageSequence\r
- (20, &CurrentSpeedDialError, 7, 0x03, req);\r
-}\r
-\r
-/* This function finds parts of SMS in frame used in new Nokia phones\r
- in internal protocols (they're coded according to GSM 03.40), copies them\r
- to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode\r
- GSM_ETSISMSMessage to GSM_SMSMessage structure */\r
-GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)\r
-{\r
- SMS_MessageType PDU=SMS_Deliver;\r
- GSM_ETSISMSMessage ETSI;\r
- int offset=0,i;\r
-\r
- ETSI.firstbyte=req[12];\r
-\r
- /* See GSM 03.40 section 9.2.3.1 */\r
- if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;\r
- if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;\r
-\r
- switch (PDU) {\r
- case SMS_Submit : offset=5;break;\r
- case SMS_Deliver : offset=4;break;\r
- case SMS_Status_Report: offset=3;break;\r
- default: break;\r
- }\r
-\r
- for (i=0;i<req[0]+1;i++)\r
- ETSI.SMSCNumber[i]=req[i];\r
-\r
- for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)\r
- ETSI.Number[i]=req[i+12+offset];\r
-\r
- switch (PDU) {\r
- case SMS_Submit:\r
- ETSI.TPDCS=req[10+offset];\r
- ETSI.TPUDL=req[11+offset];\r
- ETSI.TPVP=0; //no support for now\r
- ETSI.TPPID=0; //no support for now\r
- for(i=31+offset;i<length;i++)\r
- ETSI.MessageText[i-31-offset]=req[i];\r
- break;\r
- case SMS_Deliver:\r
- ETSI.TPDCS=req[10+offset];\r
- ETSI.TPUDL=req[11+offset];\r
- ETSI.TPPID=0; //no support for now\r
- for(i=31+offset;i<length;i++)\r
- ETSI.MessageText[i-31-offset]=req[i];\r
- for(i=0;i<7;i++)\r
- ETSI.DeliveryDateTime[i]=req[i+24+offset];\r
- break;\r
- case SMS_Status_Report:\r
- for(i=0;i<7;i++)\r
- ETSI.DeliveryDateTime[i]=req[i+24+offset];\r
- ETSI.TPStatus=req[14];\r
- for(i=0;i<7;i++)\r
- ETSI.SMSCDateTime[i]=req[i+34];\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- GSM_DecodeETSISMS(SMS, &ETSI);\r
-\r
- SMS->Name[0]=0;\r
-\r
- return GE_NONE;\r
-}\r
-\r
-void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int offset;\r
- \r
- switch (MessageBuffer[3]) {\r
-\r
- case 0x08:\r
-\r
- switch (MessageBuffer[7]) {\r
-\r
- case 0x00:\r
- CurrentSMSMessage->Type = GST_SMS;\r
- CurrentSMSMessage->folder=GST_INBOX;\r
- offset=4;\r
- break;\r
-\r
- case 0x01:\r
- CurrentSMSMessage->Type = GST_DR;\r
- CurrentSMSMessage->folder=GST_INBOX;\r
- offset=3;\r
- break;\r
-\r
- case 0x02:\r
- CurrentSMSMessage->Type = GST_SMS;\r
- CurrentSMSMessage->folder=GST_OUTBOX;\r
- offset=5;\r
- break;\r
-\r
- default:\r
- CurrentSMSMessage->Type = GST_UN;\r
- offset=4;\r
- break;\r
-\r
- }\r
-\r
- /* Field Short Message Status - MessageBuffer[4] seems not to be\r
- compliant with GSM 07.05 spec.\r
- Meaning Nokia protocol GMS spec\r
- ----------------------------------------------------\r
- MO Sent 0x05 0x07 or 0x01\r
- MO Not sent 0x07 0x06 or 0x00\r
- MT Read 0x01 0x05 or 0x01\r
- MT Not read 0x03 0x04 or 0x00\r
- ----------------------------------------------------\r
- See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.\r
- \r
- Pawel Kot */\r
-\r
- if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;\r
- else CurrentSMSMessage->Status = GSS_SENTREAD;\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);\r
-\r
- if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX\r
- fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));\r
- } else {\r
- fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));\r
- }\r
-\r
- if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));\r
- if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));\r
-\r
- if (CurrentSMSMessage->folder==1) { //GST_OUTBOX\r
- if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));\r
- else fprintf(stdout, _(" Not sent\n"));\r
- } else {\r
- if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));\r
- else fprintf(stdout, _(" Not read\n"));\r
- }\r
-#endif\r
-\r
- CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);\r
-\r
- CurrentSMSMessage->MemoryType = MessageBuffer[5];\r
- CurrentSMSMessage->MessageNumber = MessageBuffer[6];\r
- \r
- /* Signal no error to calling code. */\r
- CurrentSMSMessageError = GE_NONE;\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, "\n");\r
-#endif\r
-\r
- break;\r
-\r
- case 0x09:\r
-\r
- /* We have requested invalid or empty location. */\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: SMS reading failed\n"));\r
-\r
- switch (MessageBuffer[4]) {\r
- case 0x02:\r
- fprintf(stdout, _(" Invalid location!\n"));break;\r
- case 0x07:\r
- fprintf(stdout, _(" Empty SMS location.\n"));break;\r
- case 0x0c:\r
- fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;\r
- default: \r
- fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;\r
- }\r
-#endif /* DEBUG */\r
-\r
- switch (MessageBuffer[4]) {\r
- case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;\r
- case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;\r
- case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;\r
- default :CurrentSMSMessageError = GE_UNKNOWN;break;\r
- }\r
-\r
- break;\r
-\r
- }\r
-}\r
-\r
-GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)\r
-{\r
-\r
- unsigned char req[] = { N6110_FRAME_HEADER,\r
- 0x07,\r
- 0x02, /* Unknown */\r
- 0x00, /* Location */\r
- 0x01, 0x64};\r
-\r
- int timeout = 60;\r
-\r
- /* State machine code writes data to these variables when it comes in. */\r
-\r
- CurrentSMSMessage = message;\r
- CurrentSMSMessageError = GE_BUSY;\r
-\r
- req[5] = message->Location;\r
-\r
- /* Send request */\r
- Protocol->SendMessage(8, 0x02, req);\r
-\r
- /* Wait for timeout or other error. */\r
- while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {\r
-\r
- if (--timeout == 0)\r
- return (GE_TIMEOUT);\r
-\r
- usleep (100000);\r
- }\r
-\r
- return (CurrentSMSMessageError);\r
-}\r
-\r
-void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: SMS deleted successfully.\n"));\r
-#endif /* DEBUG */\r
-\r
- CurrentSMSMessageError = GE_NONE; \r
-}\r
-\r
-GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)\r
-{\r
- unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};\r
-\r
- req[5] = message->Location;\r
-\r
- return NULL_SendMessageSequence\r
- (50, &CurrentSMSMessageError, 6, 0x14, req);\r
-}\r
-/* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
-GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
+void N6110_ReplySetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Downloaded operator name changed\n"));
+#endif
+
+ CurrentSetOperatorNameError=GE_NONE;
+}
+
+GSM_Error N6110_SetOperatorName (GSM_Network *operator)
{
- GSM_ETSISMSMessage ETSI;
- int i,offset=0;
+ unsigned char req[256] = { 0x00,0x01,0x8b,0x00,
+ 0x00,0x00, /* MCC */
+ 0x00}; /* MNC */
- GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
+ GSM_Error error;
- /* Cleaning */
- for (i=0;i<36;i++) req[i]=0;
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
- req[12]=ETSI.firstbyte;
+ EncodeNetworkCode(req+4,operator->Code);
- for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
- req[i]=ETSI.SMSCNumber[i];
+ strncpy(req+7,operator->Name,200);
+
+ return NULL_SendMessageSequence
+ (20, &CurrentSetOperatorNameError, 8+strlen(operator->Name), 0x40, req);
+}
+
+void N6110_ReplyGetMemoryStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ case 0x08:
- switch (PDU) {
- case SMS_Submit:
- offset=5;
- for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
- req[i+12+offset]=ETSI.Number[i];
- req[10+offset]=ETSI.TPDCS;
- req[11+offset]=ETSI.TPUDL;
- req[24+offset]=ETSI.TPVP;
#ifdef DEBUG
-// fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
-// fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
-// fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
+ fprintf(stdout, _("Message: Memory status received:\n"));
+
+ fprintf(stdout, _(" Memory Type: %s\n"), N6110_MemoryType_String[MessageBuffer[4]]);
+ fprintf(stdout, _(" Used: %d\n"), MessageBuffer[6]);
+ fprintf(stdout, _(" Free: %d\n"), MessageBuffer[5]);
+#endif /* DEBUG */
+
+ CurrentMemoryStatus->Used = MessageBuffer[6];
+ CurrentMemoryStatus->Free = MessageBuffer[5];
+ CurrentMemoryStatusError = GE_NONE;
+
+ break;
+
+ case 0x09:
+
+#ifdef DEBUG
+ switch (MessageBuffer[4]) {
+ case 0x6f:
+ fprintf(stdout, _("Message: Memory status error, phone is probably powered off.\n"));break;
+ case 0x7d:
+ fprintf(stdout, _("Message: Memory status error, memory type not supported by phone model.\n"));break;
+ case 0x8d:
+ fprintf(stdout, _("Message: Memory status error, waiting for security code.\n"));break;
+ default:
+ fprintf(stdout, _("Message: Unknown Memory status error, subtype (MessageBuffer[4]) = %02x\n"),MessageBuffer[4]);break;
+ }
#endif
-// req[]=ETSI.TPPID;
- for(i=0;i<*length;i++)
- req[i+31+offset]=ETSI.MessageText[i];
- break;
- case SMS_Deliver:
- offset=4;
- for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
- req[i+12+offset]=ETSI.Number[i];
- req[10+offset]=ETSI.TPDCS;
- req[11+offset]=ETSI.TPUDL;
-// req[]=ETSI.TPPID;
- for(i=0;i<*length;i++)
- req[i+31+offset]=ETSI.MessageText[i];
- for (i=0;i<7;i++)
- req[24+offset+i]=ETSI.DeliveryDateTime[i];
- break;
- default:
- break;
+ switch (MessageBuffer[4]) {
+ case 0x6f:CurrentMemoryStatusError = GE_TIMEOUT;break;
+ case 0x7d:CurrentMemoryStatusError = GE_INTERNALERROR;break;
+ case 0x8d:CurrentMemoryStatusError = GE_INVALIDSECURITYCODE;break;
+ default:break;
+ }
+
+ break;
+
}
-
- *length=*length+offset;
-
- return GE_NONE;
}
-\r
-void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
- \r
- switch (MessageBuffer[3]) {\r
-\r
- /* SMS message correctly sent to the network */\r
- case 0x02:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: SMS Message correctly sent.\n"));\r
-#endif /* DEBUG */\r
- CurrentSMSMessageError = GE_SMSSENDOK;\r
- break;\r
-\r
- /* SMS message send to the network failed */\r
- case 0x03:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);\r
- \r
- switch (MessageBuffer[6]) {\r
- case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;\r
- case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;\r
- case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;\r
- case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; \r
- case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break; \r
- case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break; \r
- case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break; \r
- case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break; \r
- case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break; \r
- }\r
-\r
- fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));\r
- fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));\r
-#endif /* DEBUG */\r
-\r
- CurrentSMSMessageError = GE_SMSSENDFAILED;\r
- break;\r
-\r
- }\r
-}\r
-\r
-GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)\r
-{\r
- GSM_Error error;\r
-\r
- unsigned char req[256] = {\r
- N6110_FRAME_HEADER,\r
- 0x01, 0x02, 0x00, /* SMS send request*/\r
- };\r
-\r
- int length;\r
-\r
- error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit); \r
- if (error != GE_NONE) return error;\r
-\r
- return NULL_SendMessageSequence\r
- (200, &CurrentSMSMessageError, 42+length, 0x02, req);\r
-}\r
-\r
-void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[3]) {\r
-\r
- case 0x05:\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);\r
-#endif\r
- \r
- CurrentSMSMessage->MessageNumber=MessageBuffer[5];\r
- \r
- CurrentSMSMessageError = GE_NONE;\r
- break;\r
-\r
- case 0x06:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("SMS saving failed\n"));\r
- switch (MessageBuffer[4]) {\r
- case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;\r
- case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;\r
- default :fprintf(stdout, _(" Unknown error.\n"));break;\r
- }\r
-#endif \r
- \r
- switch (MessageBuffer[4]) {\r
- case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;\r
- case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;\r
- default :CurrentSMSMessageError = GE_UNKNOWN;break;\r
- }\r
- }\r
-}\r
-\r
-/* GST_DR and GST_UN not supported ! */\r
-GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)\r
-{\r
- unsigned char req[256] = {\r
- N6110_FRAME_HEADER, 0x04, /* SMS save request*/\r
- 0x00, /* SMS Status. Different for Inbox and Outbox */\r
- 0x02, /* ?? */\r
- 0x00, /* SMS Location */\r
- 0x02, /* SMS Type */\r
- };\r
-\r
- int length;\r
- SMS_MessageType PDU;\r
- GSM_Error error;\r
-\r
- if (SMS->Location) req[6] = SMS->Location;\r
- \r
- if (SMS->folder==0) { /*Inbox*/\r
- req[4]=1; /* SMS Status */\r
- req[7] = 0x00; /* SMS Type */\r
- PDU=SMS_Deliver;\r
- } else {\r
- req[4]=5; /* SMS Status */\r
- req[7] = 0x02; /* SMS Type */\r
- PDU=SMS_Submit;\r
- }\r
- \r
- if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02; \r
-\r
- error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU); \r
- if (error != GE_NONE) return error;\r
-\r
- CurrentSMSMessage = SMS;\r
-\r
- return NULL_SendMessageSequence\r
- (70, &CurrentSMSMessageError, 39+length, 0x14, req);\r
-}\r
-\r
-void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);\r
-#endif\r
-\r
- CurrentCBError = GE_NONE;\r
-}\r
-\r
-/* Enable and disable Cell Broadcasting */\r
-GSM_Error N6110_EnableCellBroadcast(void)\r
-{\r
- unsigned char req[] = {N6110_FRAME_HEADER, 0x20,\r
- 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};\r
-\r
-#ifdef DEBUG\r
- fprintf (stdout,"Enabling CB\n");\r
-#endif\r
-\r
- CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));\r
- CurrentCBMessage->Channel = 0;\r
- CurrentCBMessage->New = false;\r
- strcpy (CurrentCBMessage->Message,"");\r
-\r
- return NULL_SendMessageSequence\r
- (10, &CurrentCBError, 10, 0x02, req);\r
-}\r
-\r
-\r
-GSM_Error N6110_DisableCellBroadcast(void)\r
-{\r
- /* Should work, but not tested fully */\r
-\r
- unsigned char req[] = {N6110_FRAME_HEADER, 0x20,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/\r
-\r
- return NULL_SendMessageSequence\r
- (10, &CurrentCBError, 10, 0x02, req);\r
-}\r
-\r
-void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int i, tmp;\r
- unsigned char output[160];\r
- \r
- CurrentCBMessage->Channel = MessageBuffer[7];\r
- CurrentCBMessage->New = true;\r
- tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);\r
-\r
- fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);\r
-\r
- fflush (stdout);\r
-\r
- for (i=0; i<tmp;i++) {\r
- fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));\r
- }\r
-\r
- fprintf(stdout, "\n");\r
-#endif\r
- \r
- for (i=0; i<tmp; i++) {\r
- CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);\r
- }\r
- CurrentCBMessage->Message[i]=0;\r
-}\r
-\r
-GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)\r
-{\r
-#ifdef DEBUG\r
- fprintf(stdout,"Reading CB\n");\r
-#endif\r
-\r
- if (CurrentCBMessage != NULL) \r
- {\r
- if (CurrentCBMessage->New == true)\r
- {\r
-#ifdef DEBUG\r
- fprintf(stdout,"New CB received\n");\r
-#endif\r
- Message->Channel = CurrentCBMessage->Channel;\r
- strcpy(Message->Message,CurrentCBMessage->Message);\r
- CurrentCBMessage->New = false;\r
- return (GE_NONE);\r
- }\r
- }\r
- return (GE_NONEWCBRECEIVED);\r
-}\r
-\r
-int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)\r
-{\r
- int count=0;\r
-\r
- req[count++]=Bitmap.number;\r
- req[count++]=strlen(Bitmap.text);\r
- memcpy(req+count,Bitmap.text,req[count-1]);\r
- count+=req[count-1];\r
- req[count++]=Bitmap.ringtone;\r
-\r
- /* Setting for graphic:\r
- 0x00 - Off\r
- 0x01 - On\r
- 0x02 - View Graphics\r
- 0x03 - Send Graphics\r
- 0x04 - Send via IR\r
- You can even set it higher but Nokia phones (my\r
- 6110 at least) will not show you the name of this\r
- item in menu ;-)) Nokia is really joking here. */\r
- if (Bitmap.enabled) req[count++]=0x01;\r
- else req[count++]=0x00;\r
-\r
- req[count++]=(Bitmap.size+4)>>8;\r
- req[count++]=(Bitmap.size+4)%0xff;\r
- req[count++]=0x00; /* Future extensions! */\r
- req[count++]=Bitmap.width;\r
- req[count++]=Bitmap.height;\r
- req[count++]=0x01; /* Just BW */\r
- memcpy(req+count,Bitmap.bitmap,Bitmap.size);\r
-\r
- return count+Bitmap.size;\r
-}\r
-\r
-int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)\r
-{\r
- int count=0;\r
-\r
- EncodeNetworkCode(req+count, Bitmap.netcode);\r
- count=count+3;\r
-\r
- req[count++]=(Bitmap.size+4)>>8;\r
- req[count++]=(Bitmap.size+4)%0xff;\r
- req[count++]=0x00; /* Infofield */\r
- req[count++]=Bitmap.width;\r
- req[count++]=Bitmap.height;\r
- req[count++]=0x01; /* Just BW */ \r
- memcpy(req+count,Bitmap.bitmap,Bitmap.size);\r
-\r
- return count+Bitmap.size;\r
-}\r
-\r
-int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)\r
-{\r
- int count=0;\r
-\r
- req[count++]=0x01;\r
- req[count++]=Bitmap.height;\r
- req[count++]=Bitmap.width;\r
- memcpy(req+count,Bitmap.bitmap,Bitmap.size);\r
-\r
- return count+Bitmap.size;\r
-}\r
-\r
-/* Set a bitmap or welcome-note */\r
-GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {\r
-\r
- unsigned char req[600] = { N6110_FRAME_HEADER };\r
- u16 count=3;\r
- u8 textlen;\r
- \r
- int timeout=50;\r
- /* Direct uploading variables */
- GSM_MultiSMSMessage SMS;
- unsigned char buffer[1000] = {0x0c,0x01};
- GSM_NetworkInfo NetworkInfo;
+/* This function is used to get storage status from the phone. It currently
+ supports two different memory areas - internal and SIM. */
+GSM_Error N6110_GetMemoryStatus(GSM_MemoryStatus *Status)
+{
+ unsigned char req[] = { N6110_FRAME_HEADER,
+ 0x07, /* MemoryStatus request */
+ 0x00 /* MemoryType */
+ };
- GSM_Error error;\r
-
- /* Uploading with preview */
- if (Bitmap->number==255 &&
- (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
- GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
- memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
+ GSM_Error error;
+
+ CurrentMemoryStatus = Status;
- memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
+ req[4] = N6110_GetMemoryType(Status->MemoryType);
- buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
+ error=NULL_SendMessageSequence
+ (20, &CurrentMemoryStatusError, 5, 0x03, req);
- Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
+ CurrentMemoryStatus = NULL;
- GSM->GetNetworkInfo(&NetworkInfo); //need to make something
- return GE_NONE; //no answer from phone
- }
- \r
- CurrentSetBitmapError = GE_BUSY; \r
- \r
- switch (Bitmap->type) {\r
- case GSM_WelcomeNoteText:\r
- case GSM_DealerNoteText:\r
- req[count++]=0x18;\r
- req[count++]=0x01; /* Only one block */\r
-\r
- if (Bitmap->type==GSM_WelcomeNoteText)\r
- req[count++]=0x02; /* Welcome text */\r
- else\r
- req[count++]=0x03; /* Dealer Welcome Note */\r
-\r
- textlen=strlen(Bitmap->text);\r
- req[count++]=textlen;\r
- memcpy(req+count,Bitmap->text,textlen);\r
- \r
- count+=textlen;\r
-\r
- Protocol->SendMessage(count, 0x05, req);\r
- \r
- break;\r
-\r
- case GSM_StartupLogo:\r
- if (Bitmap->number==0) {\r
-\r
- /* For 33xx we first set animated logo to default */\r
- if (GetModelFeature (FN_STARTUP)==F_STANIM) {\r
- error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);\r
- if (error!=GE_NONE) return error;\r
- }\r
-\r
- req[count++]=0x18;\r
- req[count++]=0x01; /* Only one block */\r
- count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap); \r
- Protocol->SendMessage(count, 0x05, req);\r
- } else {\r
- return N6110_SetProfileFeature(0, 0x29, Bitmap->number);\r
- }\r
- break;\r
-\r
- case GSM_OperatorLogo:\r
- req[count++]=0x30; /* Store Op Logo */\r
- req[count++]=0x01; /* Location */\r
- count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
- Protocol->SendMessage(count, 0x05, req);\r
- break;\r
-\r
- case GSM_CallerLogo:\r
- req[count++]=0x13;\r
- count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);\r
- Protocol->SendMessage(count, 0x03, req);\r
- break;\r
-\r
- case GSM_PictureImage:\r
- req[count++]=0x03;\r
- req[count++]=Bitmap->number;\r
- if (strcmp(Bitmap->Sender,"")) {\r
- req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);\r
-\r
- /* Convert number of semioctets to number of chars and add count */\r
- textlen=req[count];\r
- if (textlen % 2) textlen++;\r
- count+=textlen / 2 + 1;\r
-\r
- count++;\r
- } else {\r
- req[count++]=0x00;\r
- req[count++]=0x00;\r
- }\r
- req[count++]=0x00;\r
- req[count++]=strlen(Bitmap->text);\r
- memcpy(req+count,Bitmap->text,strlen(Bitmap->text));\r
- count+=strlen(Bitmap->text);\r
- req[count++]=0x00;\r
- req[count++]=Bitmap->width;\r
- req[count++]=Bitmap->height;\r
- req[count++]=0x01;\r
- memcpy(req+count,Bitmap->bitmap,Bitmap->size);\r
- Protocol->SendMessage(count+Bitmap->size, 0x47, req);\r
- break;\r
-\r
- case GSM_7110OperatorLogo:\r
- case GSM_7110StartupLogo:\r
- case GSM_6210StartupLogo:\r
- return GE_NOTSUPPORTED;\r
-\r
- case GSM_None:\r
- return GE_NONE;\r
- }\r
-\r
- /* Wait for timeout or other error. */\r
- while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {\r
- \r
- if (--timeout == 0)\r
- return (GE_TIMEOUT);\r
- \r
- usleep (100000);\r
- }\r
-\r
- return CurrentSetBitmapError;\r
-}\r
-\r
-/* Get a bitmap from the phone */\r
-GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {\r
-\r
- unsigned char req[10] = { N6110_FRAME_HEADER };\r
- u8 count=3;\r
- \r
- int timeout=100;\r
- \r
- CurrentGetBitmap=Bitmap; \r
- CurrentGetBitmapError = GE_BUSY; \r
- \r
- switch (CurrentGetBitmap->type) {\r
- case GSM_StartupLogo:\r
- case GSM_WelcomeNoteText:\r
- case GSM_DealerNoteText:\r
- req[count++]=0x16;\r
- Protocol->SendMessage(count, 0x05, req);\r
- break;\r
- case GSM_OperatorLogo:\r
- req[count++]=0x33;\r
- req[count++]=0x01; /* Location 1 */\r
- Protocol->SendMessage(count, 0x05, req);\r
- break;\r
- case GSM_CallerLogo:\r
- req[count++]=0x10;\r
- req[count++]=Bitmap->number;\r
- Protocol->SendMessage(count, 0x03, req);\r
- break;\r
- case GSM_PictureImage:\r
- req[count++]=0x01;\r
- req[count++]=Bitmap->number;\r
- Protocol->SendMessage(count, 0x47, req);\r
- break;\r
- case GSM_7110OperatorLogo:\r
- case GSM_7110StartupLogo:\r
- case GSM_6210StartupLogo:\r
- default:\r
- return GE_NOTSUPPORTED;\r
- }\r
-\r
- /* Wait for timeout or other error. */\r
- while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {\r
- \r
- if (--timeout == 0)\r
- return (GE_TIMEOUT);\r
- \r
- usleep (100000);\r
- }\r
-\r
- CurrentGetBitmap=NULL;\r
-\r
- return CurrentGetBitmapError;\r
-}\r
-\r
-void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[3]) {\r
-\r
- /* Set ringtone OK */\r
- case 0x37: \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Ringtone set OK!\n"));\r
-#endif \r
- CurrentRingtoneError=GE_NONE; \r
- break; \r
-\r
- /* Set ringtone error */\r
- case 0x38: \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Ringtone setting error !\n"));\r
-#endif \r
- CurrentRingtoneError=GE_NOTSUPPORTED; \r
- break; \r
- }\r
-}\r
-\r
-GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)\r
-{\r
- \r
- char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =\r
- {N6110_FRAME_HEADER,\r
- 0x36,\r
- 0x00, /* Location */\r
- 0x00,0x78};\r
-\r
- int size=FB61_MAX_RINGTONE_FRAME_LENGTH;\r
-
- /* Variables for preview uploading */
- unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
- unsigned char buffer2[20];
- GSM_NetworkInfo NetworkInfo;
+ return error;
+}
- /* Setting ringtone with preview */
- if (ringtone->location==255) {
- buffer[0]=0x0c;
- buffer[1]=0x01;
- EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
- memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
- *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
- Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
- GSM->GetNetworkInfo(&NetworkInfo); //need to make something
- sleep(1);
- return GE_NONE; //no answer from phone
- }
- \r
- *maxlength=GSM_PackRingtone(ringtone, req+7, &size);\r
-\r
- req[4]=ringtone->location-1;\r
-\r
- return NULL_SendMessageSequence\r
- (50, &CurrentRingtoneError, (size+7), 0x05, req);\r
-}\r
-\r
-void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int i;\r
- \r
- switch (MessageBuffer[4]) {\r
- case 0x00: /* location supported. We have ringtone */\r
-\r
- /* Binary format used in N6150 */\r
- if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Message: ringtone \""));\r
-#endif \r
-\r
- /* Copying name */\r
- i=8;\r
- while (true) {\r
-#ifdef DEBUG\r
- if (MessageBuffer[i]!=0)\r
- fprintf(stdout,_("%c"),MessageBuffer[i]);\r
-#endif\r
- CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];\r
- if (MessageBuffer[i]==0) break;\r
- i++;\r
- }\r
-\r
-#ifdef DEBUG \r
- fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);\r
-#endif\r
- \r
- /* Looking for end */\r
- i=0;\r
- while (true) {\r
- if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {\r
- i=i+2;break;\r
- }\r
- if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {\r
- i=i+2;break;\r
- }\r
- i++;\r
- if (i==MessageLength) break;\r
- }\r
- \r
- /* Copying frame */\r
- memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);\r
- CurrentGetBinRingtone->length=i-3;\r
- \r
- CurrentBinRingtoneError=GE_NONE;\r
- break;\r
- }\r
- \r
- /* Binary format used in N3210 */\r
- if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) { \r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Message: ringtone \""));\r
-#endif \r
-\r
- /* Copying name */\r
- i=8;\r
- while (true) {\r
-#ifdef DEBUG\r
- if (MessageBuffer[i]!=0)\r
- fprintf(stdout,_("%c"),MessageBuffer[i]);\r
-#endif\r
- CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];\r
- if (MessageBuffer[i]==0) break;\r
- i++;\r
- }\r
-\r
-#ifdef DEBUG \r
- fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);\r
-#endif\r
-\r
- /* Here changes to get full compatibility with binary format used in N6150 */\r
- MessageBuffer[3]=0;\r
- MessageBuffer[4]=0;\r
- MessageBuffer[5]=0x0c;\r
- MessageBuffer[6]=0x01;\r
- MessageBuffer[7]=0x2c;\r
-\r
- /* Looking for end */\r
- i=0;\r
- while (true) {\r
- if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {\r
- i=i+2;break;\r
- }\r
- if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {\r
- i=i+2;break;\r
- }\r
- i++;\r
- if (i==MessageLength) break;\r
- }\r
- \r
- /* Copying frame */\r
- memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);\r
-\r
- CurrentGetBinRingtone->length=i-3;\r
- \r
- CurrentBinRingtoneError=GE_NONE; \r
- break;\r
- }\r
-\r
- /* Copying frame */\r
- memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);\r
-\r
- CurrentGetBinRingtone->length=MessageLength;\r
-\r
-#ifdef DEBUG \r
- fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);\r
-#endif\r
- CurrentBinRingtoneError=GE_UNKNOWNMODEL;\r
- break;\r
-\r
- default:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);\r
-#endif\r
-\r
- CurrentBinRingtoneError=GE_INVALIDRINGLOCATION; \r
- }\r
-}\r
-\r
-GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)\r
-{\r
- unsigned char req[] = { 0x00,0x01,0x9e,\r
- 0x00 }; //location\r
-\r
- GSM_Error error;\r
- \r
- CurrentGetBinRingtone=ringtone;\r
- \r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
-\r
- req[3]=ringtone->location-1;\r
- \r
- return NULL_SendMessageSequence\r
- (50, &CurrentBinRingtoneError, 4, 0x40, req);\r
-}\r
-\r
-void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch (MessageBuffer[4]) {\r
- case 0x00: /* location supported. We set ringtone */\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);\r
-#endif\r
- CurrentBinRingtoneError=GE_NONE;\r
- break;\r
-\r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);\r
-#endif\r
- CurrentBinRingtoneError=GE_NOTSUPPORTED; \r
- break;\r
- }\r
-}\r
-\r
-GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)\r
-{\r
- unsigned char req[1000] = { 0x00,0x01,0xa0};\r
-\r
- GSM_Error error;\r
-\r
- GSM_BinRingtone ring;\r
-\r
- /* Must be sure, that can upload ringtone to this phone */\r
- ring.location=ringtone->location;\r
- error=N6110_GetBinRingTone(&ring);\r
- if (error!=GE_NONE) return error;\r
- \r
- error=N6110_EnableExtendedCommands(0x01);\r
- if (error!=GE_NONE) return error;\r
- \r
- memcpy(req+3,ringtone->frame,ringtone->length);\r
-\r
- req[3]=ringtone->location-1;\r
- \r
- return NULL_SendMessageSequence\r
- (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);\r
-}\r
-\r
-GSM_Error N6110_Reset(unsigned char type)\r
-{ \r
- return N6110_EnableExtendedCommands(type);\r
-}\r
-\r
-void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int tmp, count;\r
- \r
- switch (MessageBuffer[3]) {\r
-\r
- /* Unknown message - it has been seen after the 0x07 message (call\r
- answered). Probably it has similar meaning. If you can solve\r
- this - just mail me. Pavel JanÃk ml.\r
-\r
- The message looks like this:\r
-\r
- Msg Destination: PC\r
- Msg Source: Phone\r
- Msg Type: 01\r
- Msg Unknown: 00\r
- Msg Len: 0e\r
-\r
- Phone: [01 ][08 ][00 ] is the header of the frame\r
-\r
- [03 ] is the call message subtype\r
-\r
- [05 ] is the call sequence number\r
-\r
- [05 ] unknown \r
-\r
- [00 ][01 ][03 ][02 ][91][00] are unknown but has been\r
- seen in the Incoming call message (just after the\r
- caller's name from the phonebook). But never change\r
- between phone calls :-(\r
- */\r
-\r
- /* This may mean sequence number of 'just made' call - CK */\r
- case 0x02:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Call message, type 0x02:"));\r
- fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));\r
-#endif /* DEBUG */\r
-\r
- break;\r
-\r
- /* Possibly call OK */\r
- /* JD: I think that this means "call in progress" (incomming or outgoing) */\r
- case 0x03:\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Call message, type 0x03:"));\r
- fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);\r
- fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));\r
-#endif /* DEBUG */\r
- \r
- CurrentCallSequenceNumber=MessageBuffer[4];\r
- CurrentIncomingCall[0]='D';\r
- if (CurrentCallPassup) CurrentCallPassup('D');\r
-\r
- break;\r
-\r
- /* Remote end has gone away before you answer the call. Probably your\r
- mother-in-law or banker (which is worse?) ... */\r
- case 0x04:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Remote end hang up.\n"));\r
- fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);\r
-\r
- switch (MessageBuffer[6]) {\r
- case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;\r
- case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;\r
- case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;\r
- case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;\r
- case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;\r
- case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;\r
- }\r
- \r
- fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));\r
- fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));\r
-#endif /* DEBUG */\r
-\r
- CurrentIncomingCall[0] = ' ';\r
- if (CurrentCallPassup) CurrentCallPassup(' ');\r
-\r
- break;\r
-\r
- /* Incoming call alert */\r
- case 0x05:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Incoming call alert:\n"));\r
-\r
- /* We can have more then one call ringing - we can distinguish between\r
- them */\r
-\r
- fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);\r
- fprintf(stdout, _(" Number: "));\r
-\r
- count=MessageBuffer[6];\r
-\r
- for (tmp=0; tmp <count; tmp++)\r
- fprintf(stdout, "%c", MessageBuffer[7+tmp]);\r
-\r
- fprintf(stdout, "\n");\r
-\r
- fprintf(stdout, _(" Name: "));\r
-\r
- for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)\r
- fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);\r
-\r
- fprintf(stdout, "\n");\r
-#endif /* DEBUG */\r
-\r
- count=MessageBuffer[6];\r
-\r
- CurrentIncomingCall[0] = 0;\r
- for (tmp=0; tmp <count; tmp++)\r
- sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);\r
-\r
- break;\r
-\r
- /* Call answered. Probably your girlfriend...*/\r
- case 0x07:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Call answered.\n"));\r
- fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);\r
-#endif /* DEBUG */\r
-\r
- break;\r
-\r
- /* Call ended. Girlfriend is girlfriend, but time is money :-) */\r
- case 0x09:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Call ended by your phone.\n"));\r
- fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);\r
-#endif /* DEBUG */\r
-\r
- break;\r
-\r
- /* This message has been seen with the message of subtype 0x09\r
- after I hang the call.\r
-\r
- Msg Destination: PC\r
- Msg Source: Phone\r
- Msg Type: 01 \r
- Msg Unknown: 00\r
- Msg Len: 08\r
- Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]\r
-\r
- What is the meaning of 87? Can you spell some magic light into\r
- this issue?\r
-\r
- */\r
-\r
- /* Probably means call over - CK */\r
- case 0x0a:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Call message, type 0x0a:"));\r
- fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);\r
- fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));\r
-#endif /* DEBUG */\r
-\r
- CurrentIncomingCall[0] = ' ';\r
- if (CurrentCallPassup) CurrentCallPassup(' ');\r
-\r
- break;\r
-\r
- case 0x40:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));\r
-#endif\r
-\r
- if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;\r
-\r
- if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;\r
-\r
- break;\r
- \r
- default:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Unknown message of type 0x01\n"));\r
-#endif /* DEBUG */\r
- AppendLogText("Unknown msg\n",false);\r
-\r
- break; /* Visual C Don't like empty cases */\r
- }\r
-}\r
-\r
-void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int tmp, count;\r
- \r
- switch (MessageBuffer[3]) {\r
-\r
- case 0x04:\r
-\r
- /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */\r
- /* If you want see, if it works with your phone make something like that: */\r
-\r
- /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */\r
- /* Protocol->SendMessage(4, 0x04, connect5); */\r
-\r
- /* Marcin-Wiacek@TopNet.PL */\r
- \r
-#ifdef WIN32\r
- sprintf(Current_IMEI, "%s", MessageBuffer+5);\r
- sprintf(Current_Model, "%s", MessageBuffer+21);\r
- sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);\r
-#else\r
- snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);\r
- snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);\r
- snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);\r
-#endif\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Mobile phone identification received:\n"));\r
- fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);\r
- fprintf(stdout, _(" Model: %s\n"), Current_Model);\r
- fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);\r
- fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);\r
- fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);\r
-#endif /* DEBUG */\r
-\r
- break;\r
-\r
- /* Get group data */ \r
- /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */\r
- case 0x11: \r
- \r
- if (CurrentGetBitmap!=NULL) {\r
- if (CurrentGetBitmap->number==MessageBuffer[4]) {\r
- count=MessageBuffer[5];\r
- memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);\r
- CurrentGetBitmap->text[count]=0;\r
-\r
-#ifdef DEBUG \r
- fprintf(stdout, _("Message: Caller group datas\n"));\r
- fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);\r
-#endif /* DEBUG */\r
-\r
- count+=6;\r
-\r
- CurrentGetBitmap->ringtone=MessageBuffer[count++];\r
-#ifdef DEBUG \r
- fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);\r
- if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));\r
- fprintf(stdout,_("\n"));\r
-#endif /* DEBUG */\r
-\r
- CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);\r
-#ifdef DEBUG \r
- fprintf(stdout, _("Caller group logo "));\r
- if (CurrentGetBitmap->enabled)\r
- fprintf(stdout, _("enabled \n"));\r
- else\r
- fprintf(stdout, _("disabled \n"));\r
-#endif /* DEBUG */ \r
-\r
- CurrentGetBitmap->size=MessageBuffer[count++]<<8;\r
- CurrentGetBitmap->size+=MessageBuffer[count++];\r
-#ifdef DEBUG \r
- fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);\r
-#endif /* DEBUG */\r
-\r
- count++;\r
- CurrentGetBitmap->width=MessageBuffer[count++];\r
- CurrentGetBitmap->height=MessageBuffer[count++];\r
- count++;\r
- tmp=GSM_GetBitmapSize(CurrentGetBitmap);\r
- if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;\r
- memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);\r
- CurrentGetBitmapError=GE_NONE;\r
- } else {\r
-#ifdef DEBUG \r
- fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);\r
-#endif\r
- }\r
- } else {\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Caller group data received but not requested!\n"));\r
-#endif\r
- }\r
- break;\r
-\r
- /* Get group data error */\r
- case 0x12: \r
- \r
- CurrentGetBitmapError=GE_UNKNOWN; \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));\r
-#endif \r
- break;\r
-\r
- /* Set group data OK */ \r
- case 0x14: \r
- \r
- CurrentSetBitmapError=GE_NONE; \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Caller group data set correctly.\n"));\r
-#endif\r
- break;\r
-\r
- /* Set group data error */\r
- case 0x15: \r
- \r
- CurrentSetBitmapError=GE_UNKNOWN; \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Error attempting to set caller group data\n"));\r
-#endif\r
- break; \r
- \r
- default:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Unknown message of type 0x03\n"));\r
-#endif /* DEBUG */\r
- AppendLogText("Unknown msg\n",false);\r
-\r
- break; /* Visual C Don't like empty cases */\r
- }\r
-}\r
-\r
-void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int tmp, count, length;\r
- bool issupported;\r
+void N6110_ReplyGetNetworkInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+ GSM_NetworkInfo NullNetworkInfo;
+
+ /* Make sure we are expecting NetworkInfo frame */
+ if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY) {
#ifdef DEBUG
- int i;
+ fprintf(stdout, _("Message: Network informations:\n"));
+#endif
+ } else {
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Network informations not requested, but received:\n"));
#endif
+ }
+
+ sprintf(NullNetworkInfo.NetworkCode, "%x%x%x %x%x", MessageBuffer[14] & 0x0f, MessageBuffer[14] >>4, MessageBuffer[15] & 0x0f, MessageBuffer[16] & 0x0f, MessageBuffer[16] >>4);
- switch (MessageBuffer[3]) {\r
-\r
- /* Startup Logo */\r
- case 0x17: \r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));\r
-#endif\r
-\r
- if (CurrentGetBitmap!=NULL) {\r
- \r
- issupported=false;\r
- \r
- count=5;\r
- \r
- for (tmp=0;tmp<MessageBuffer[4];tmp++){\r
- switch (MessageBuffer[count++]) {\r
- case 0x01:\r
- if (CurrentGetBitmap->type==GSM_StartupLogo) {\r
- CurrentGetBitmap->height=MessageBuffer[count++];\r
- CurrentGetBitmap->width=MessageBuffer[count++];\r
- CurrentGetBitmap->size=GSM_GetBitmapSize(CurrentGetBitmap);\r
- length=CurrentGetBitmap->size;\r
- memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);\r
- } else {\r
- //bitmap size\r
- length=MessageBuffer[count++];\r
- length=length*MessageBuffer[count++]/8;\r
- }\r
- count+=length;\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Startup logo supported - "));\r
- if (length!=0) { fprintf(stdout, _("currently set\n")); }\r
- else { fprintf(stdout, _("currently empty\n")); }\r
-#endif\r
- if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;\r
- break;\r
- case 0x02:\r
- length=MessageBuffer[count];\r
- if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {\r
- memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);\r
- CurrentGetBitmap->text[length]=0;\r
- }\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Startup Text supported - "));\r
- if (length!=0)\r
- {\r
- fprintf(stdout, _("currently set to \""));\r
- for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);\r
- fprintf(stdout, _("\"\n"));\r
- } else {\r
- fprintf(stdout, _("currently empty\n"));\r
- }\r
-#endif\r
- count+=length+1;\r
- if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;\r
- break;\r
- case 0x03:\r
- length=MessageBuffer[count];\r
- if (CurrentGetBitmap->type==GSM_DealerNoteText) {\r
- memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);\r
- CurrentGetBitmap->text[length]=0;\r
- }\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Dealer Welcome supported - "));\r
- if (length!=0)\r
- {\r
- fprintf(stdout, _("currently set to \""));\r
- for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);\r
- fprintf(stdout, _("\"\n"));\r
- } else {\r
- fprintf(stdout, _("currently empty\n"));\r
- }\r
-#endif\r
- count+=length+1;\r
- if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;\r
- break;\r
- }\r
- }\r
- if (issupported) CurrentGetBitmapError=GE_NONE;\r
- else CurrentGetBitmapError=GE_NOTSUPPORTED;\r
- } else {\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Startup logo received but not requested!\n"));\r
-#endif\r
- }\r
- break;\r
-\r
- /* Set startup OK */\r
- case 0x19: \r
- \r
- CurrentSetBitmapError=GE_NONE; \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));\r
-#endif \r
- break; \r
-\r
- /* Set Operator Logo OK */\r
- case 0x31: \r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Operator logo correctly set.\n"));\r
-#endif \r
-\r
- CurrentSetBitmapError=GE_NONE; \r
- break;\r
-\r
- /* Set Operator Logo Error */ \r
- case 0x32: \r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Error setting operator logo!\n"));\r
-#endif\r
-\r
- CurrentSetBitmapError=GE_UNKNOWN; \r
- break;\r
-\r
- /* Operator Logo */\r
- /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */ \r
- case 0x34:\r
- \r
- if (CurrentGetBitmap!=NULL) {\r
-\r
- count=5; /* Location ignored. */\r
-\r
- DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
- count=count+3;
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),\r
- CurrentGetBitmap->netcode,\r
- GSM_GetNetworkName(CurrentGetBitmap->netcode));\r
-#endif \r
-\r
- CurrentGetBitmap->size=MessageBuffer[count++]<<8;\r
- CurrentGetBitmap->size+=MessageBuffer[count++];\r
- count++;\r
- CurrentGetBitmap->width=MessageBuffer[count++];\r
- CurrentGetBitmap->height=MessageBuffer[count++];\r
- count++;\r
- tmp=GSM_GetBitmapSize(CurrentGetBitmap);\r
- if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;\r
- memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);\r
- CurrentGetBitmapError=GE_NONE;\r
- } else {\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Operator logo received but not requested!\n"));\r
-#endif\r
- }\r
- \r
- break;\r
-\r
- /* Get op logo error */ \r
- case 0x35:\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Error getting operator logo!\n"));\r
-#endif \r
- CurrentGetBitmapError=GE_UNKNOWN; \r
- break;\r
-\r
- default:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Unknown message of type 0x05\n"));\r
-#endif /* DEBUG */\r
- AppendLogText("Unknown msg\n",false);\r
-\r
- break;\r
- }\r
-}\r
-\r
-void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int tmp;\r
- unsigned char output[160];\r
+ sprintf(NullNetworkInfo.CellID, "%02x%02x", MessageBuffer[10], MessageBuffer[11]);
+
+ sprintf(NullNetworkInfo.LAC, "%02x%02x", MessageBuffer[12], MessageBuffer[13]);
#ifdef DEBUG
- int i;
-#endif
- \r
- switch (MessageBuffer[3]) {\r
-
- case 0x05:\r
-\r
- /* MessageBuffer[3] = 0x05\r
- MessageBuffer[4] = 0x00\r
- MessageBuffer[5] = 0x0f\r
- MessageBuffer[6] = 0x03\r
- MessageBuffer[7] = length of packed message\r
-\r
- This is all I have seen - Gerry Anderson */\r
-\r
- tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);\r
-\r
-#ifdef DEBUG\r
-\r
- fprintf(stdout, _("Message from Network operator: "));\r
-\r
- for (i=0; i<tmp; i++)\r
- fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));\r
-\r
- fprintf(stdout, "\n");\r
-\r
-#endif /* DEBUG */\r
-\r
- break;\r
-\r
- default:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Unknown message of type 0x06\n"));\r
-#endif /* DEBUG */\r
- AppendLogText("Unknown msg\n",false);\r
-\r
- break;\r
- }\r
-}\r
-\r
-void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
- \r
- switch (MessageBuffer[3]) {\r
- \r
- case 0x80: \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: SIM card login\n"));\r
-#endif\r
- break;\r
-\r
- case 0x81: \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: SIM card logout\n"));\r
-#endif\r
- break;\r
- \r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Unknown message of type 0x09.\n")); \r
-#endif\r
- AppendLogText("Unknown msg\n",false);\r
- break;\r
- }\r
-}\r
-\r
-void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- switch(MessageBuffer[3]) {\r
- \r
- case 0x6a:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Calendar Alarm active\n"));\r
- fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);\r
-#endif /* DEBUG */\r
-\r
- default:\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Unknown message of type 0x13.\n")); \r
-#endif\r
- AppendLogText("Unknown msg\n",false);\r
- break;\r
- }\r
-}\r
-\r
-void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int i;\r
- \r
- switch(MessageBuffer[2]) {\r
-\r
- case 0x02:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));\r
-#endif /* DEBUG */\r
- \r
- CurrentMagicError=GE_NONE;\r
- break;\r
- \r
- case 0x7c:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Answer for call commands.\n"));\r
-#endif\r
- \r
- CurrentDialVoiceError=GE_NONE; \r
- break;\r
- \r
- case 0x81:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));\r
-#endif /* DEBUG */\r
- \r
- CurrentMagicError=GE_NONE;\r
- break;\r
-\r
- case 0x82:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: ACK for simlock closing\n"));\r
-#endif /* DEBUG */\r
- \r
- CurrentMagicError=GE_NONE;\r
- break;\r
-\r
- case 0xd4:\r
-\r
- switch (MessageBuffer[5]) {\r
- case 0xa0:\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Message: EEPROM contest received\n"));\r
-#endif\r
-\r
- if (MessageBuffer[8]!=0x00) {\r
- for (i=9;i<MessageLength;i++) {\r
- fprintf(stdout,_("%c"), MessageBuffer[i]);\r
- }\r
-\r
- CurrentMagicError=GE_NONE;\r
- }\r
- \r
- break;\r
- }\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Unknown message of type 0x40.\n"));\r
-#endif /* DEBUG */\r
- AppendLogText("Unknown msg\n",false); \r
- break;\r
-\r
- case 0xcf:\r
-\r
- N6110_DisplayTestsInfo(MessageBuffer);\r
- break;\r
- \r
- default:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Unknown message of type 0x40.\n"));\r
-#endif /* DEBUG */\r
- AppendLogText("Unknown msg\n",false);\r
- break; /* Visual C Don't like empty cases */\r
- }\r
-}\r
-\r
-void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- int count;\r
- \r
- switch(MessageBuffer[3]) {\r
- \r
- case 0x02:\r
-\r
- count=5;\r
- \r
- if (MessageBuffer[5]!=0) {\r
- strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));\r
-\r
- while (MessageBuffer[count]!=0) {\r
- count++;\r
- }\r
-\r
- count++;\r
- } else {\r
- strcpy(CurrentGetBitmap->Sender,"\0");\r
-\r
- count+=3;\r
- }\r
-\r
- memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);\r
- CurrentGetBitmap->text[MessageBuffer[count]]=0;\r
-\r
- if (MessageBuffer[count]!=0)\r
- count+=MessageBuffer[count];\r
-\r
- count++;\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);\r
-#endif\r
-\r
- CurrentGetBitmap->width=MessageBuffer[count+1];\r
- CurrentGetBitmap->height=MessageBuffer[count+2]; \r
- CurrentGetBitmap->size=GSM_GetBitmapSize(CurrentGetBitmap);\r
- \r
- memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);\r
- \r
- CurrentGetBitmapError=GE_NONE;\r
- break;\r
-\r
- case 0x04:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Getting or setting Picture Image - OK\n"));\r
-#endif\r
- CurrentSetBitmapError=GE_NONE;\r
- CurrentGetBitmapError=GE_NONE;\r
- break; \r
-\r
- case 0x05:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));\r
-#endif\r
- CurrentSetBitmapError=GE_UNKNOWN;\r
- break; \r
-\r
- case 0x06:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));\r
-#endif\r
- CurrentGetBitmapError=GE_UNKNOWN;\r
- break; \r
-\r
- default:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Unknown message of type 0x47.\n"));\r
-#endif /* DEBUG */\r
- AppendLogText("Unknown msg\n",false);\r
- break; /* Visual C Don't like empty cases */\r
- }\r
-}\r
-\r
-void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
- char buffer[50];\r
- \r
- sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);\r
- AppendLog(buffer,strlen(buffer),false);\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],\r
- MessageBuffer[1]);\r
-#endif /* DEBUG */\r
- \r
- CurrentLinkOK = true;\r
-}\r
-\r
-void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
- \r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));\r
-#endif /* DEBUG */\r
-\r
-}\r
-\r
-/* This function is used for parsing the RLP frame into fields. */\r
-void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)\r
-{\r
-\r
- RLP_F96Frame frame;\r
- int count;\r
- int valid = true;\r
-\r
- /* We do not need RLP frame parsing to be done when we do not have callback\r
- specified. */\r
- if (CurrentRLP_RXCallback == NULL)\r
- exit;\r
- \r
- /* Anybody know the official meaning of the first two bytes?\r
- Nokia 6150 sends junk frames starting D9 01, and real frames starting\r
- D9 00. We'd drop the junk frames anyway because the FCS is bad, but\r
- it's tidier to do it here. We still need to call the callback function\r
- to give it a chance to handle timeouts and/or transmit a frame */\r
- if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)\r
- valid = false;\r
-\r
- /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22\r
- specification, so Header consists of 16 bits (2 bytes). See section 4.1\r
- of the specification. */\r
- \r
- frame.Header[0] = MessageBuffer[2];\r
- frame.Header[1] = MessageBuffer[3];\r
-\r
- /* Next 200 bits (25 bytes) contain the Information. We store the\r
- information in the Data array. */\r
-\r
- for (count = 0; count < 25; count ++)\r
- frame.Data[count] = MessageBuffer[4 + count];\r
-\r
- /* The last 24 bits (3 bytes) contain FCS. */\r
-\r
- frame.FCS[0] = MessageBuffer[29];\r
- frame.FCS[1] = MessageBuffer[30];\r
- frame.FCS[2] = MessageBuffer[31];\r
-\r
- /* Here we pass the frame down in the input stream. */\r
- CurrentRLP_RXCallback(valid ? &frame : NULL);\r
-}\r
-\r
-void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));\r
-#endif /* DEBUG */\r
-\r
-}\r
-\r
-void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
-\r
- GSM_SMSMessage NullSMS;\r
-\r
- switch (MessageBuffer[6]) {\r
-\r
- case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;\r
- case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;\r
-\r
- /* Is it possible ? */\r
- case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break; \r
- default: NullSMS.Type = GST_UN; break;\r
- }\r
-\r
-#ifdef DEBUG\r
- if (NullSMS.Type == GST_DR)\r
- fprintf(stdout, _("Message: SMS Message (Report) Received\n"));\r
- else \r
- fprintf(stdout, _("Message: SMS Message Received\n")); \r
-#endif /* DEBUG */\r
-\r
- GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("\n")); \r
-#endif /* DEBUG */\r
-}\r
-\r
-void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {\r
+ fprintf(stdout, _(" CellID: %s\n"), NullNetworkInfo.CellID);
+ fprintf(stdout, _(" LAC: %s\n"), NullNetworkInfo.LAC);
+ fprintf(stdout, _(" Network code: %s\n"), NullNetworkInfo.NetworkCode);
+ fprintf(stdout, _(" Network name: %s (%s)\n"),
+ GSM_GetNetworkName(NullNetworkInfo.NetworkCode),
+ GSM_GetCountryName(NullNetworkInfo.NetworkCode));
+ fprintf(stdout, _(" Status: "));
- bool unknown=false;
+ switch (MessageBuffer[8]) {
+ case 0x01: fprintf(stdout, _("home network selected")); break;
+ case 0x02: fprintf(stdout, _("roaming network")); break;
+ case 0x03: fprintf(stdout, _("requesting network")); break;
+ case 0x04: fprintf(stdout, _("not registered in the network")); break;
+ default: fprintf(stdout, _("unknown"));
+ }
- /* Switch on the basis of the message type byte */\r
- switch (MessageType) {\r
- \r
- /* Call information */\r
- case 0x01:\r
-\r
- N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);\r
- break;\r
-\r
- /* SMS handling */\r
- case 0x02:\r
- switch (MessageBuffer[3]) {\r
- case 0x02:\r
- case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;\r
- case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;\r
- case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x34:\r
- case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;\r
- default :unknown=true;break;\r
- }\r
- break;\r
-\r
- /* Phonebook handling */\r
- case 0x03:\r
- switch (MessageBuffer[3]) {\r
- case 0x02:\r
- case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x05:\r
- case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x08:\r
- case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x17:\r
- case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x1a:\r
- case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;\r
- default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;\r
- }\r
- break;\r
-\r
- /* Phone status */ \r
- case 0x04:\r
- switch (MessageBuffer[3]) {\r
- case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;\r
- default :unknown=true;break;\r
- }\r
- break;\r
- \r
- /* Startup Logo, Operator Logo and Profiles. */\r
- case 0x05:\r
- switch (MessageBuffer[3]) {\r
- case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;\r
- default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;\r
- }\r
- break;\r
-\r
- /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
- /* Call diverts */
- case 0x06:\r
- switch (MessageBuffer[3]) {\r
- case 0x02:\r
- case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;\r
- default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;\r
- }\r
- break;\r
-\r
- /* Security code requests */\r
- case 0x08:\r
- switch (MessageBuffer[3]) {\r
- case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;\r
- default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;\r
- }\r
- break;\r
-\r
- /* SIM login */\r
- case 0x09:\r
-\r
- N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);\r
- break;\r
-\r
- /* Network info */\r
- case 0x0a:\r
- switch (MessageBuffer[3]) {\r
- case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;\r
- default :unknown=true;break;\r
- }\r
- break;\r
-\r
- /* Simulating key pressing */\r
- case 0x0c:\r
- switch (MessageBuffer[3]) {\r
- case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;\r
- default :unknown=true;break;\r
- }\r
- break;\r
-\r
- /* Display */\r
- case 0x0d:\r
- switch (MessageBuffer[3]) {\r
- case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;\r
- default :unknown=true;break;\r
- }\r
- break;\r
-\r
- /* Phone Clock and Alarm */\r
- case 0x11:\r
- switch (MessageBuffer[3]) {\r
- case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;\r
- default :unknown=true;break;\r
- }\r
- break;\r
-\r
- /* Calendar notes handling */\r
- case 0x13:\r
- switch (MessageBuffer[3]) {\r
- case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;\r
- default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;\r
- }\r
- break;\r
-\r
- /* SMS Messages */\r
- case 0x14:\r
- switch (MessageBuffer[3]) {\r
- case 0x05:\r
- case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x08:\r
- case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x37:\r
- case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;\r
- default :unknown=true;break;\r
- }\r
- break;\r
-\r
- /* WAP */\r
- case 0x3f:\r
- switch (MessageBuffer[3]) {\r
- case 0x01:\r
- case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x07:\r
- case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
+ fprintf(stdout, "\n");
+
+ fprintf(stdout, _(" Network selection: %s\n"), MessageBuffer[9]==1?_("manual"):_("automatic"));
+#endif /* DEBUG */
+
+ /* Make sure we are expecting NetworkInfo frame */
+ if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY)
+ *CurrentNetworkInfo=NullNetworkInfo;
+
+ CurrentNetworkInfoError = GE_NONE;
+}
+
+GSM_Error N6110_GetNetworkInfo(GSM_NetworkInfo *NetworkInfo)
+{
+ unsigned char req[] = { N6110_FRAME_HEADER,
+ 0x70
+ };
+
+ GSM_Error error;
+
+ CurrentNetworkInfo = NetworkInfo;
+
+ error=NULL_SendMessageSequence
+ (20, &CurrentNetworkInfoError, 4, 0x0a, req);
+
+ CurrentNetworkInfo = NULL;
+
+ return error;
+}
+
+void N6110_ReplyGetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int i;
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Product Profile Settings received -"));
+ for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),MessageBuffer[3+i]);
+ fprintf(stdout, _("\n"));
+#endif
+
+ for (i=0;i<4;i++) CurrentPPS[i]=MessageBuffer[3+i];
+
+ CurrentProductProfileSettingsError=GE_NONE;
+}
+
+GSM_Error N6110_GetProductProfileSetting (GSM_PPS *PPS)
+{
+ unsigned char req[] = { 0x00, 0x01,0x6a };
+
+ int i,j;
+
+ GSM_Error error;
+
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
+
+ error=NULL_SendMessageSequence
+ (20, &CurrentProductProfileSettingsError, 3, 0x40, req);
+ if (error!=GE_NONE) return error;
+
+ switch (PPS->Name) {
+ case PPS_ALS : PPS->bool_value=(CurrentPPS[1]&32); break;
+ case PPS_GamesMenu: PPS->bool_value=(CurrentPPS[3]&64); break;
+ case PPS_HRData : PPS->bool_value=(CurrentPPS[0]&64); break;
+ case PPS_14400Data: PPS->bool_value=(CurrentPPS[0]&128);break;
+ case PPS_EFR : PPS->int_value =(CurrentPPS[0]&1) +(CurrentPPS[0]&2); break;
+ case PPS_FR : PPS->int_value =(CurrentPPS[0]&16)/16+(CurrentPPS[0]&32)/16;break;
+ case PPS_HR : PPS->int_value =(CurrentPPS[0]&4)/4 +(CurrentPPS[0]&8)/4; break;
+ case PPS_VibraMenu: PPS->bool_value=(CurrentPPS[4]&64); break;
+ case PPS_LCDContrast:
+ PPS->int_value=0;
+ j=1;
+ for (i=0;i<5;i++) {
+ if (CurrentPPS[3]&j) PPS->int_value=PPS->int_value+j;
+ j=j*2;
+ }
+ PPS->int_value=PPS->int_value*100/32;
+ break;
+
+ }
+
+ return (GE_NONE);
+}
+
+void N6110_ReplySetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ int i;
+
+ fprintf(stdout, _("Message: Product Profile Settings set to"));
+ for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),CurrentPPS[i]);
+ fprintf(stdout, _("\n"));
+#endif
+
+ CurrentProductProfileSettingsError=GE_NONE;
+}
+
+GSM_Error N6110_SetProductProfileSetting (GSM_PPS *PPS)
+{
+ unsigned char req[] = { 0x00, 0x01,0x6b,
+ 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */
+ unsigned char settings[32];
+
+ GSM_PPS OldPPS;
+
+ int i,j,z;
+
+ GSM_Error error;
+
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
+
+ OldPPS.Name=PPS_ALS;
+ error=N6110_GetProductProfileSetting(&OldPPS);
+ if (error!=GE_NONE) return error;
+
+ j=128;z=0;
+ for (i=0;i<32;i++) {
+ if (CurrentPPS[z]&j)
+ settings[i]='1';
+ else
+ settings[i]='0';
+ if (j==1) {
+ j=128;
+ z++;
+ } else j=j/2;
+ }
+
+#ifdef DEBUG
+ fprintf(stdout,_("Current settings: "));
+ for (i=0;i<32;i++) {
+ fprintf(stdout,_("%c"),settings[i]);
+ }
+ fprintf(stdout,_("\n"));
+#endif
+
+ switch (PPS->Name) {
+ case PPS_ALS :settings[10]=PPS->bool_value?'1':'0';break;
+ case PPS_HRData :settings[ 5]=PPS->bool_value?'1':'0';break;
+ case PPS_14400Data:settings[ 6]=PPS->bool_value?'1':'0';break;
+ default :break;
+ }
+
+ j=128;z=0;
+ for (i=0;i<32;i++) {
+ if (settings[i]=='1') req[z+3]=req[z+3]+j;
+ if (j==1) {
+ j=128;
+ z++;
+ } else j=j/2;
+ }
+
+#ifdef DEBUG
+ fprintf(stdout,_("Current settings: "));
+ for (i=0;i<4;i++) {
+ fprintf(stdout,_("%i "),req[i+3]);
+ }
+ fprintf(stdout,_("\n"));
+#endif
+
+ for (i=0;i<4;i++) {
+ CurrentPPS[i]=req[i+3];
+ }
+
+ return NULL_SendMessageSequence
+ (20, &CurrentProductProfileSettingsError, 7, 0x40, req);
+}
+
+void N6110_ReplyPressKey(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ if (MessageBuffer[4]==CurrentPressKeyEvent) CurrentPressKeyError=GE_NONE;
+ else CurrentPressKeyError=GE_UNKNOWN; /* MessageBuffer[4] = 0x05 */
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Result of key "));
+ switch (MessageBuffer[4])
+ {
+ case PRESSPHONEKEY: fprintf(stdout, _("press OK\n"));break;
+ case RELEASEPHONEKEY: fprintf(stdout, _("release OK\n"));break;
+ default: fprintf(stdout, _("press or release - error\n"));break;
+ }
+#endif /* DEBUG */
+}
+
+GSM_Error N6110_PressKey(int key, int event)
+{
+ unsigned char req[] = {N6110_FRAME_HEADER, 0x42, 0x01, 0x00, 0x01};
+
+ req[4]=event; /* if we press or release key */
+ req[5]=key;
+
+ CurrentPressKeyEvent=event;
+
+ return NULL_SendMessageSequence
+ (10, &CurrentPressKeyError, 7, 0x0c, req);
+}
+
+void N6110_ReplyDisplayOutput(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
+ char model[64];
+
+ int i, j;
+
+ char uni[100];
+
+ switch(MessageBuffer[3]) {
+
+ /* Phone sends displayed texts */
+ case 0x50:
+ NewX=MessageBuffer[6];
+ NewY=MessageBuffer[5];
+
+ DecodeUnicode (uni, MessageBuffer+8, MessageBuffer[7]);
+
+#ifdef DEBUG
+ fprintf(stdout, _("New displayed text (%i %i): \"%s\"\n"),NewX,NewY,uni);
+#endif /* DEBUG */
+
+ while (N6110_GetModel(model) != GE_NONE)
+ sleep(1);
+
+ /* With these rules it works almost excellent with my N5110 */
+ /* I don't have general rule :-(, that's why you must experiment */
+ /* with your phone. Nokia could make it better. MW */
+ /* It's almost OK for N5110*/
+ /* FIX ME: it will be the same for N5130 and 3210 too*/
+ if (!strcmp(model,"NSE-1"))
+ {
+ /* OldX==1000 means - it's first time */
+ if (OldX==1000) {
+
+ /* Clean table */
+ for (i=0;i<5+1;i++) {
+ for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
+ }
+ OldX=0;
+ }
+
+ if ((OldX==0 && OldY==31 && NewX==29 && NewY==46) ||
+ (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
+ /* Clean the line with current text */
+ for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
+
+ /* Inserts text into table */
+ for (i=0; i<MessageBuffer[7];i++) {
+ PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
+ }
+
+ }
+
+ if ((OldX==0 && OldY==21 && NewX==0 && NewY==10) ||
+ (OldX==0 && OldY==10 && NewX==35 && NewY==46)) {
+ } else {
+ if ((OldX!=0 && NewX==0 && NewY!=6) ||
+ (OldX==0 && NewX!=0 && OldY!=13 && OldY!=22) ||
+ (OldX==0 && NewX==0 && NewY<OldY && (NewY!=13 || OldY!=26)) ||
+ (OldY==5 && NewY!=5) ||
+ (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
+
+ /* Writes "old" screen */
+ for (i=0;i<5+1;i++) {
+ for (j=0;j<27+1;j++) {fprintf(stdout,_("%c"),PhoneScreen[i][j]);}
+ fprintf(stdout,_("\n"));
+ }
+
+ /* Clean table */
+ for (i=0;i<5+1;i++) {
+ for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
+ }
+ }
+ }
+
+ /* Clean the line with current text */
+ for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
+
+ /* Inserts text into table */
+ for (i=0; i<MessageBuffer[7];i++) {
+ PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
+ }
+
+ OldY=NewY;
+ OldX=NewX;
+ } else {
+#ifndef DEBUG
+ fprintf(stdout, _("%s\n"),uni);
+#endif
+ }
+
+ break;
+
+ case 0x54:
+
+ if (MessageBuffer[4]==1)
+ {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Display output successfully disabled/enabled.\n"));
+#endif /* DEBUG */
+
+ CurrentDisplayOutputError=GE_NONE;
+ }
+
+ break;
+ }
+}
+
+GSM_Error SetDisplayOutput(unsigned char state)
+{
+ unsigned char req[] = { N6110_FRAME_HEADER,
+ 0x53, 0x00};
+
+ req[4]=state;
+
+ return NULL_SendMessageSequence
+ (30, &CurrentDisplayOutputError, 5, 0x0d, req);
+}
+
+GSM_Error N6110_EnableDisplayOutput()
+{
+ return SetDisplayOutput(0x01);
+}
+
+GSM_Error N6110_DisableDisplayOutput()
+{
+ return SetDisplayOutput(0x02);
+}
+
+/* If it is interesting for somebody: we can use 0x40 msg for it
+ and it will work for all phones. See n6110.txt for details */
+GSM_Error N6110_AnswerCall(char s)
+{
+ unsigned char req0[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,0x07, 0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
+ 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80};
+ unsigned char req[] = { N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
+
+ req[4]=s;
+
+#ifdef DEBUG
+ fprintf(stdout,_("Answering call %d\n\r"),s);
+#endif
+
+ Protocol->SendMessage(sizeof(req0), 0x01, req0);
+ sleep(1);
+
+ return NULL_SendMessageSequence
+ (20, &CurrentMagicError, sizeof(req) , 0x01, req);
+}
+
+void N6110_ReplyGetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ /* Profile feature */
+ case 0x14:
+
+ switch(GetModelFeature (FN_PROFILES)) {
+ case F_PROF33:
+ switch (MessageBuffer[6]) {
+ case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8]; break;
+ case 0x01: CurrentProfile->CallAlert = MessageBuffer[8]; break;
+ case 0x02: CurrentProfile->Ringtone = MessageBuffer[8]; break;
+ case 0x03: CurrentProfile->Volume = MessageBuffer[8]; break;
+ case 0x04: CurrentProfile->MessageTone = MessageBuffer[8]; break;
+ case 0x05: CurrentProfile->Vibration = MessageBuffer[8]; break;
+ case 0x06: CurrentProfile->WarningTone = MessageBuffer[8]; break;
+ case 0x07: CurrentProfile->ScreenSaver = MessageBuffer[8]; break;
+ default:
+#ifdef DEBUG
+ fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
+#endif
+ break;
+ }
+ break;
+ default:
+ switch (MessageBuffer[6]) {
+ case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8];break;
+ case 0x01: CurrentProfile->Lights = MessageBuffer[8];break;
+ case 0x02: CurrentProfile->CallAlert = MessageBuffer[8];break;
+ case 0x03: CurrentProfile->Ringtone = MessageBuffer[8];break;
+ case 0x04: CurrentProfile->Volume = MessageBuffer[8];break;
+ case 0x05: CurrentProfile->MessageTone = MessageBuffer[8];break;
+ case 0x06: CurrentProfile->Vibration = MessageBuffer[8];break;
+ case 0x07: CurrentProfile->WarningTone = MessageBuffer[8];break;
+ case 0x08: CurrentProfile->CallerGroups = MessageBuffer[8];break;
+ case 0x09: CurrentProfile->AutomaticAnswer = MessageBuffer[8];break;
+ default:
+#ifdef DEBUG
+ fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
+#endif
+ break;
+ }
+ break;
+ }
+
+ CurrentProfileError = GE_NONE;
+ break;
+
+ /* Incoming profile name */
+ case 0x1b:
+
+ if (MessageBuffer[9] == 0x00) {
+ CurrentProfile->DefaultName=MessageBuffer[8];
+ } else {
+ CurrentProfile->DefaultName=-1;
+
+ /* Here name is in Unicode */
+ if (GetModelFeature (FN_PROFILES)==F_PROF33) {
+ DecodeUnicode (CurrentProfile->Name, MessageBuffer+10, MessageBuffer[9]/2);
+ } else {
+ /* ...here not */
+ sprintf(CurrentProfile->Name, MessageBuffer + 10, MessageBuffer[9]);
+ CurrentProfile->Name[MessageBuffer[9]] = '\0';
+ }
+ }
+
+ CurrentProfileError = GE_NONE;
+ break;
+
+ }
+}
+
+/* Needs SIM card with PIN in phone */
+GSM_Error N6110_GetProfile(GSM_Profile *Profile)
+{
+ int i;
+
+ unsigned char name_req[] = { N6110_FRAME_HEADER, 0x1a, 0x00};
+ unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x13, 0x01, 0x00, 0x00};
+
+ GSM_Error error;
+
+ CurrentProfile = Profile;
+
+ /* When after sending all frames feature==253, it means, that it is not
+ supported */
+ CurrentProfile->KeypadTone=253;
+ CurrentProfile->Lights=253;
+ CurrentProfile->CallAlert=253;
+ CurrentProfile->Ringtone=253;
+ CurrentProfile->Volume=253;
+ CurrentProfile->MessageTone=253;
+ CurrentProfile->WarningTone=253;
+ CurrentProfile->Vibration=253;
+ CurrentProfile->CallerGroups=253;
+ CurrentProfile->ScreenSaver=253;
+ CurrentProfile->AutomaticAnswer=253;
+
+ name_req[4] = Profile->Number;
+
+ error=NULL_SendMessageSequence
+ (20, &CurrentProfileError, 5, 0x05, name_req);
+ if (error!=GE_NONE) return error;
+
+ for (i = 0x00; i <= 0x09; i++) {
+
+ feat_req[5] = Profile->Number;
+
+ feat_req[6] = i;
+
+ error=NULL_SendMessageSequence
+ (20, &CurrentProfileError, 7, 0x05, feat_req);
+ if (error!=GE_NONE) return error;
+ }
+
+ if (Profile->DefaultName > -1)
+ {
+ switch(GetModelFeature (FN_PROFILES)) {
+ case F_PROF33:
+ switch (Profile->DefaultName) {
+ case 0x00: sprintf(Profile->Name, "General");break;
+ case 0x01: sprintf(Profile->Name, "Silent");break;
+ case 0x02: sprintf(Profile->Name, "Descreet");break;
+ case 0x03: sprintf(Profile->Name, "Loud");break;
+ case 0x04: sprintf(Profile->Name, "My style");break;
+ case 0x05: Profile->Name[0]=0;break;
+ default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
+ }
+ break;
+ case F_PROF51:
+ switch (Profile->DefaultName) {
+ case 0x00: sprintf(Profile->Name, "Personal");break;
+ case 0x01: sprintf(Profile->Name, "Car");break;
+ case 0x02: sprintf(Profile->Name, "Headset");break;
+ default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
+ }
+ break;
+ case F_PROF61:
+ switch (Profile->DefaultName) {
+ case 0x00: sprintf(Profile->Name, "General");break;
+ case 0x01: sprintf(Profile->Name, "Silent");break;
+ case 0x02: sprintf(Profile->Name, "Meeting");break;
+ case 0x03: sprintf(Profile->Name, "Outdoor");break;
+ case 0x04: sprintf(Profile->Name, "Pager");break;
+ case 0x05: sprintf(Profile->Name, "Car");break;
+ case 0x06: sprintf(Profile->Name, "Headset");break;
+ default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
+ }
+ break;
+ }
+ }
+
+ return (GE_NONE);
+
+}
+
+void N6110_ReplySetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ /* Profile feature change result */
+ case 0x11:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Profile feature change result.\n"));
+#endif /* DEBUG */
+ CurrentProfileError = GE_NONE;
+ break;
+
+ /* Profile name set result */
+ case 0x1d:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Profile name change result.\n"));
+#endif /* DEBUG */
+ CurrentProfileError = GE_NONE;
+ break;
+
+ }
+}
+
+GSM_Error N6110_SetProfileFeature(u8 profile, u8 feature, u8 value)
+{
+ unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x10, 0x01,
+ 0x00, 0x00, 0x00};
+
+ feat_req[5]=profile;
+ feat_req[6]=feature;
+ feat_req[7]=value;
+
+ return NULL_SendMessageSequence
+ (20, &CurrentProfileError, 8, 0x05, feat_req);
+}
+
+GSM_Error N6110_SetProfile(GSM_Profile *Profile)
+{
+ int i,value;
+
+ unsigned char name_req[40] = { N6110_FRAME_HEADER, 0x1c, 0x01, 0x03,
+ 0x00, 0x00, 0x00};
+
+ GSM_Error error;
+
+ name_req[7] = Profile->Number;
+ name_req[8] = strlen(Profile->Name);
+ name_req[6] = name_req[8] + 2;
+
+ for (i = 0; i < name_req[8]; i++)
+ name_req[9 + i] = Profile->Name[i];
+
+ error=NULL_SendMessageSequence
+ (20, &CurrentProfileError, name_req[8] + 9, 0x05, name_req);
+ if (error!=GE_NONE) return error;
+
+ for (i = 0x00; i <= 0x09; i++) {
+
+ switch (i) {
+ case 0x00: value = Profile->KeypadTone; break;
+ case 0x01: value = Profile->Lights; break;
+ case 0x02: value = Profile->CallAlert; break;
+ case 0x03: value = Profile->Ringtone; break;
+ case 0x04: value = Profile->Volume; break;
+ case 0x05: value = Profile->MessageTone; break;
+ case 0x06: value = Profile->Vibration; break;
+ case 0x07: value = Profile->WarningTone; break;
+ case 0x08: value = Profile->CallerGroups; break;
+ case 0x09: value = Profile->AutomaticAnswer; break;
+ default : value = 0; break;
+ }
+
+ error=N6110_SetProfileFeature(Profile->Number,i,value);
+ if (error!=GE_NONE) return error;
+ }
+
+ return (GE_NONE);
+}
+
+bool N6110_SendRLPFrame(RLP_F96Frame *frame, bool out_dtx)
+{
+ u8 req[60] = { 0x00, 0xd9 };
+
+ /* Discontinuos transmission (DTX). See section 5.6 of GSM 04.22 version
+ 7.0.1. */
+
+ if (out_dtx)
+ req[1]=0x01;
+
+ memcpy(req+2, (u8 *) frame, 32);
+
+ return (Protocol->SendFrame(32, 0xf0, req));
+}
+
+void N6110_ReplyGetCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int i, j;
+
+ u8 mychar1;
+
+ wchar_t wc;
+
+ switch (MessageBuffer[4]) {
+
+ case 0x01:
+
+ CurrentCalendarNote->Type=MessageBuffer[8];
+
+ DecodeDateTime(MessageBuffer+9, &CurrentCalendarNote->Time);
+
+ DecodeDateTime(MessageBuffer+16, &CurrentCalendarNote->Alarm);
+
+ CurrentCalendarNote->Text[0]=0;
+
+ if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
+ i=0;
+ if (CurrentCalendarNote->Type == GCN_REMINDER) i=1; //first char is subset
+ switch (MessageBuffer[24]) {
+ case 3:
+#ifdef DEBUG
+ fprintf(stdout,_("Subset 3 in reminder note !\n"));
+#endif
+ while (i!=MessageBuffer[23]) {
+ j=0;
+ if (i!=MessageBuffer[23]-1) {
+ if (MessageBuffer[24+i]>=0xc2) {
+ DecodeWithUTF8Alphabet(MessageBuffer[24+i], MessageBuffer[24+i+1], &mychar1);
+ CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
+ CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=mychar1;
+ j=-1;
+ i++;
+ }
+ }
+ if (j!=-1) {
+ CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
+ CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=MessageBuffer[24+i];
+ }
+ i++;
+ }
+ break;
+ case 2:
+#ifdef DEBUG
+ fprintf(stdout,_("Subset 2 in reminder note !\n"));
+#endif
+ while (i!=MessageBuffer[23]) {
+ wc = MessageBuffer[24+i] | (0x00 << 8);
+ CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
+ CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=
+ DecodeWithUnicodeAlphabet(wc);
+ i++;
+ }
+ break;
+ case 1:
+#ifdef DEBUG
+ fprintf(stdout,_("Subset 1 in reminder note !\n"));
+#endif
+ memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
+ CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
+ break;
+ default:
+#ifdef DEBUG
+ fprintf(stdout,_("Unknown subset in reminder note !\n"));
+#endif
+ memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
+ CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
+ break;
+ }
+ } else {
+ memcpy(CurrentCalendarNote->Text,MessageBuffer+24,MessageBuffer[23]);
+ CurrentCalendarNote->Text[MessageBuffer[23]]=0;
+ }
+
+ if (CurrentCalendarNote->Type == GCN_CALL) {
+ memcpy(CurrentCalendarNote->Phone,MessageBuffer+24+MessageBuffer[23]+1,MessageBuffer[24+MessageBuffer[23]]);
+ CurrentCalendarNote->Phone[MessageBuffer[24+MessageBuffer[23]]]=0;
+ }
+
+ CurrentCalendarNote->Recurrance=0;
+
+ CurrentCalendarNote->AlarmType=0;
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Calendar note received.\n"));
+
+ fprintf(stdout, _(" Date: %d-%02d-%02d\n"), CurrentCalendarNote->Time.Year,
+ CurrentCalendarNote->Time.Month,
+ CurrentCalendarNote->Time.Day);
+
+ fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentCalendarNote->Time.Hour,
+ CurrentCalendarNote->Time.Minute,
+ CurrentCalendarNote->Time.Second);
+
+ /* Some messages do not have alarm set up */
+ if (CurrentCalendarNote->Alarm.Year != 0) {
+ fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"), CurrentCalendarNote->Alarm.Year,
+ CurrentCalendarNote->Alarm.Month,
+ CurrentCalendarNote->Alarm.Day);
+
+ fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"), CurrentCalendarNote->Alarm.Hour,
+ CurrentCalendarNote->Alarm.Minute,
+ CurrentCalendarNote->Alarm.Second);
+ }
+
+ fprintf(stdout, _(" Type: %d\n"), CurrentCalendarNote->Type);
+ fprintf(stdout, _(" Text: %s\n"), CurrentCalendarNote->Text);
+
+ if (CurrentCalendarNote->Type == GCN_CALL)
+ fprintf(stdout, _(" Phone: %s\n"), CurrentCalendarNote->Phone);
+#endif /* DEBUG */
+
+ CurrentCalendarNoteError=GE_NONE;
+ break;
+
+ case 0x93:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Calendar note not available\n"));
+#endif /* DEBUG */
+
+ CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;
+ break;
+
+ default:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Calendar note error\n"));
+#endif /* DEBUG */
+
+ CurrentCalendarNoteError=GE_INTERNALERROR;
+ break;
+
+ }
+}
+
+GSM_Error N6110_GetCalendarNote(GSM_CalendarNote *CalendarNote)
+{
+
+ unsigned char req[] = { N6110_FRAME_HEADER,
+ 0x66, 0x00
+ };
+ GSM_Error error;
+
+ req[4]=CalendarNote->Location;
+
+ CurrentCalendarNote = CalendarNote;
+
+ error=NULL_SendMessageSequence
+ (20, &CurrentCalendarNoteError, 5, 0x13, req);
+
+ CurrentCalendarNote = NULL;
+
+ return error;
+}
+
+void N6110_ReplyWriteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ switch(MessageBuffer[4]) {
+ /* This message is also sent when the user enters the new entry on keypad */
+ case 0x01:
+ fprintf(stdout, _("Message: Calendar note write succesfull!\n"));break;
+ case 0x73:
+ fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
+ case 0x7d:
+ fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
+ default:
+ fprintf(stdout, _("Unknown message of type 0x13 and subtype 0x65\n"));break;
+ }
+#endif
+
+ switch(MessageBuffer[4]) {
+ case 0x01: CurrentCalendarNoteError=GE_NONE; break;
+ case 0x73: CurrentCalendarNoteError=GE_INTERNALERROR; break;
+ case 0x7d: CurrentCalendarNoteError=GE_INTERNALERROR; break;
+ default : AppendLogText("Unknown msg\n",false); break;
+ }
+}
+
+GSM_Error N6110_WriteCalendarNote(GSM_CalendarNote *CalendarNote)
+{
+
+ unsigned char req[200] = { N6110_FRAME_HEADER,
+ 0x64, 0x01, 0x10,
+ 0x00, /* Length of the rest of the frame. */
+ 0x00, /* The type of calendar note */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ typedef struct {
+ char *model;
+ unsigned char call;
+ unsigned char meeting;
+ unsigned char birthday;
+ unsigned char reminder;
+ } calendar_model_length;
+
+ /* Length of entries */
+ calendar_model_length calendar_lengths[] =
+ {
+ /*model,CallTo,Meeting,Birthday,Reminder*/
+ {"NHM-5",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
+ {"NHM-6",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
+ {"NSE-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 [HKEY_LOCAL_MACHINE\Software\Nokia\Data Suite\3.0\Calendar]
+ {"NSM-1",0x1e,0x18,0x18,0x24}, //from NCDS3
+ {"NSK-3",0x1e,0x14,0x14,0x1e}, //from NCDS3
+ {"NSB-3",0x20,0x14,0x14,0x1e}, //from NCDS3
+ {"", 0, 0, 0, 0 } //end of table
+ };
+
+ int i, j, current;
+
+ u8 mychar;
+
+ u8 mychar1,mychar2;
+
+ GSM_Error error;
+
+ /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
+ char model[64];
+
+ req[7]=CalendarNote->Type;
+
+ EncodeDateTime(req+8, &CalendarNote->Time);
+ req[14] = CalendarNote->Time.Timezone;
+
+ if (CalendarNote->Alarm.Year) {
+ EncodeDateTime(req+15, &CalendarNote->Alarm);
+ req[21] = CalendarNote->Alarm.Timezone;
+ }
+
+ req[22]=strlen(CalendarNote->Text);
+
+ current=23;
+
+ if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
+ req[22]++; // one additional char
+ req[current++]=0x01; //we use now subset 1
+ }
+
+ for (i=0; i<strlen(CalendarNote->Text); i++) {
+ j=0;
+ mychar=CalendarNote->Text[i];
+ if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
+ if (EncodeWithUTF8Alphabet(mychar,&mychar1,&mychar2)) {
+ req[current++]=mychar1;
+ req[current++]=mychar2;
+ req[23]=0x03; //use subset 3
+ req[22]++; // one additional char
+ j=-1;
+ }
+ }
+ if (j!=-1) {
+ /* Enables/disables blinking */
+ if (mychar=='~') req[current++]=0x01;
+ else req[current++]=mychar;
+ }
+ }
+
+ req[current++]=strlen(CalendarNote->Phone);
+
+ for (i=0; i<strlen(CalendarNote->Phone); i++)
+ req[current++]=CalendarNote->Phone[i];
+
+ while (N6110_GetModel(model) != GE_NONE)
+ sleep(1);
+
+ /* Checking maximal length */
+ i=0;
+ while (strcmp(calendar_lengths[i].model,"")) {
+ if (!strcmp(calendar_lengths[i].model,model)) {
+ switch (CalendarNote->Type) {
+ case GCN_REMINDER:if (req[22]>calendar_lengths[i].reminder) return GE_TOOLONG;break;
+ case GCN_MEETING :if (req[22]>calendar_lengths[i].meeting) return GE_TOOLONG;break;
+ case GCN_BIRTHDAY:if (req[22]>calendar_lengths[i].birthday) return GE_TOOLONG;break;
+ case GCN_CALL :if (strlen(CalendarNote->Phone)>calendar_lengths[i].call) return GE_TOOLONG;break;
+ }
+ break;
+ }
+ i++;
+ }
+
+ CurrentCalendarNote = CalendarNote;
+
+ error=NULL_SendMessageSequence
+ (20, &CurrentCalendarNoteError, current, 0x13, req);
+
+ CurrentCalendarNote = NULL;
+
+ return error;
+}
+
+void N6110_ReplyDeleteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ switch (MessageBuffer[4]) {
+ /* This message is also sent when the user deletes an old entry on
+ keypad or moves an old entry somewhere (there is also `write'
+ message). */
+ case 0x01:fprintf(stdout, _("Message: Calendar note deleted\n"));break;
+ case 0x93:fprintf(stdout, _("Message: Calendar note can't be deleted\n"));break;
+ default :fprintf(stdout, _("Message: Calendar note deleting error\n"));break;
+ }
+#endif
+
+ switch (MessageBuffer[4]) {
+ case 0x01:CurrentCalendarNoteError=GE_NONE;break;
+ case 0x93:CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;break;
+ default :CurrentCalendarNoteError=GE_INTERNALERROR;break;
+ }
+}
+
+GSM_Error N6110_DeleteCalendarNote(GSM_CalendarNote *CalendarNote)
+{
+
+ unsigned char req[] = { N6110_FRAME_HEADER,
+ 0x68, 0x00
+ };
+
+ req[4]=CalendarNote->Location;
+
+ return NULL_SendMessageSequence (20, &CurrentCalendarNoteError, 5, 0x13, req);
+}
+
+void N6110_ReplyRFBatteryLevel(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Phone status received:\n"));
+ fprintf(stdout, _(" Mode: "));
+
+ switch (MessageBuffer[4]) {
+
+ case 0x01:
+
+ fprintf(stdout, _("registered within the network\n"));
+ break;
+
+ /* I was really amazing why is there a hole in the type of 0x02, now I
+ know... */
+ case 0x02: fprintf(stdout, _("call in progress\n")); break; /* ringing or already answered call */
+ case 0x03: fprintf(stdout, _("waiting for security code\n")); break;
+ case 0x04: fprintf(stdout, _("powered off\n")); break;
+ default : fprintf(stdout, _("unknown\n"));
+
+ }
+
+ fprintf(stdout, _(" Power source: "));
+
+ switch (MessageBuffer[7]) {
+
+ case 0x01: fprintf(stdout, _("AC/DC\n")); break;
+ case 0x02: fprintf(stdout, _("battery\n")); break;
+ default : fprintf(stdout, _("unknown\n"));
+
+ }
+
+ fprintf(stdout, _(" Battery Level: %d\n"), MessageBuffer[8]);
+ fprintf(stdout, _(" Signal strength: %d\n"), MessageBuffer[5]);
+#endif /* DEBUG */
+
+ CurrentRFLevel=MessageBuffer[5];
+ CurrentBatteryLevel=MessageBuffer[8];
+ CurrentPowerSource=MessageBuffer[7];
+}
+
+
+GSM_Error N6110_GetRFLevel(GSM_RFUnits *units, float *level)
+{
+
+ /* FIXME - these values are from 3810 code, may be incorrect. Map from
+ values returned in status packet to the the values returned by the AT+CSQ
+ command. */
+ float csq_map[5] = {0, 8, 16, 24, 31};
+
+ int timeout=10;
+ int rf_level;
+
+ char screen[NM_MAX_SCREEN_WIDTH];
+
+ CurrentRFLevel=-1;
+
+ if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
+
+ if (N6110_NetMonitor(1, screen)!=GE_NONE)
+ return GE_INTERNALERROR;
+
+ rf_level=4;
+
+ if (screen[4]!='-') {
+ if (screen[5]=='9' && screen[6]>'4') rf_level=1;
+ if (screen[5]=='9' && screen[6]<'5') rf_level=2;
+ if (screen[5]=='8' && screen[6]>'4') rf_level=3;
+ } else rf_level=0;
+
+ /* Arbitrary units. */
+ if (*units == GRF_Arbitrary) {
+ *level = rf_level;
+ return (GE_NONE);
+ }
+
+ } else {
+ N6110_SendStatusRequest();
+
+ /* Wait for timeout or other error. */
+ while (timeout != 0 && CurrentRFLevel == -1 ) {
+
+ if (--timeout == 0)
+ return (GE_TIMEOUT);
+
+ usleep (100000);
+ }
+
+ /* Make copy in case it changes. */
+ rf_level = CurrentRFLevel;
+
+ if (rf_level == -1)
+ return (GE_NOLINK);
+
+ /* Now convert between the different units we support. */
+
+ /* Arbitrary units. */
+ if (*units == GRF_Arbitrary) {
+ *level = rf_level;
+ return (GE_NONE);
+ }
+
+ /* CSQ units. */
+ if (*units == GRF_CSQ) {
+
+ if (rf_level <=4)
+ *level = csq_map[rf_level];
+ else
+ *level = 99; /* Unknown/undefined */
+
+ return (GE_NONE);
+ }
+ }
+
+ /* Unit type is one we don't handle so return error */
+ return (GE_INTERNALERROR);
+}
+
+
+GSM_Error N6110_GetBatteryLevel(GSM_BatteryUnits *units, float *level)
+{
+ int timeout=10;
+ int batt_level;
+
+ char screen[NM_MAX_SCREEN_WIDTH];
+
+ CurrentBatteryLevel=-1;
+
+ if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
+
+ if (N6110_NetMonitor(23, screen)!=GE_NONE)
+ return GE_NOLINK;
+
+ batt_level=4;
+
+ if (screen[29]=='7') batt_level=3;
+ if (screen[29]=='5') batt_level=2;
+ if (screen[29]=='2') batt_level=1;
+
+ /* Only units we handle at present are GBU_Arbitrary */
+ if (*units == GBU_Arbitrary) {
+ *level = batt_level;
+ return (GE_NONE);
+ }
+
+ return (GE_INTERNALERROR);
+
+ } else {
+ N6110_SendStatusRequest();
+
+ /* Wait for timeout or other error. */
+ while (timeout != 0 && CurrentBatteryLevel == -1 ) {
+
+ if (--timeout == 0)
+ return (GE_TIMEOUT);
+
+ usleep (100000);
+ }
+
+ /* Take copy in case it changes. */
+ batt_level = CurrentBatteryLevel;
+
+ if (batt_level != -1) {
+
+ /* Only units we handle at present are GBU_Arbitrary */
+ if (*units == GBU_Arbitrary) {
+ *level = batt_level;
+ return (GE_NONE);
+ }
+
+ return (GE_INTERNALERROR);
+ }
+ else
+ return (GE_NOLINK);
+ }
+}
+
+GSM_Error N6110_GetPowerSource(GSM_PowerSource *source)
+{
+
+ int timeout=10;
+
+ char screen[NM_MAX_SCREEN_WIDTH];
+
+ CurrentPowerSource=-1;
+
+ if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
+
+ if (N6110_NetMonitor(20, screen)!=GE_NONE)
+ return GE_NOLINK;
+
+ CurrentPowerSource=GPS_ACDC;
+
+ if (screen[6]=='x') CurrentPowerSource=GPS_BATTERY;
+
+ *source=CurrentPowerSource;
+
+ return GE_NONE;
+ } else {
+ N6110_SendStatusRequest();
+
+ /* Wait for timeout or other error. */
+ while (timeout != 0 && CurrentPowerSource == -1 ) {
+
+ if (--timeout == 0)
+ return (GE_TIMEOUT);
+
+ usleep (100000);
+ }
+
+ if (CurrentPowerSource != -1) {
+ *source=CurrentPowerSource;
+ return (GE_NONE);
+ }
+ else
+ return (GE_NOLINK);
+ }
+}
+
+void N6110_ReplyGetDisplayStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int i;
+
+ for (i=0; i<MessageBuffer[4];i++)
+ if (MessageBuffer[2*i+6]==2)
+ CurrentDisplayStatus|=1<<(MessageBuffer[2*i+5]-1);
+ else
+ CurrentDisplayStatus&= (0xff - (1<<(MessageBuffer[2*i+5]-1)));
+
+#ifdef DEBUG
+ fprintf(stdout, _("Call in progress: %s\n"), CurrentDisplayStatus & (1<<DS_Call_In_Progress)?"on":"off");
+ fprintf(stdout, _("Unknown: %s\n"), CurrentDisplayStatus & (1<<DS_Unknown)?"on":"off");
+ fprintf(stdout, _("Unread SMS: %s\n"), CurrentDisplayStatus & (1<<DS_Unread_SMS)?"on":"off");
+ fprintf(stdout, _("Voice call: %s\n"), CurrentDisplayStatus & (1<<DS_Voice_Call)?"on":"off");
+ fprintf(stdout, _("Fax call active: %s\n"), CurrentDisplayStatus & (1<<DS_Fax_Call)?"on":"off");
+ fprintf(stdout, _("Data call active: %s\n"), CurrentDisplayStatus & (1<<DS_Data_Call)?"on":"off");
+ fprintf(stdout, _("Keyboard lock: %s\n"), CurrentDisplayStatus & (1<<DS_Keyboard_Lock)?"on":"off");
+ fprintf(stdout, _("SMS storage full: %s\n"), CurrentDisplayStatus & (1<<DS_SMS_Storage_Full)?"on":"off");
+#endif /* DEBUG */
+
+ CurrentDisplayStatusError=GE_NONE;
+}
+
+GSM_Error N6110_GetDisplayStatus(int *Status) {
+
+ unsigned char req[4]={ N6110_FRAME_HEADER, 0x51 };
+
+ GSM_Error error;
+
+ error=NULL_SendMessageSequence
+ (10, &CurrentDisplayStatusError, 4, 0x0d, req);
+ if (error!=GE_NONE) return error;
+
+ *Status=CurrentDisplayStatus;
+
+ return GE_NONE;
+}
+
+GSM_Error N6110_DialVoice(char *Number) {
+/* This commented sequence doesn't work on N3210/3310/6210/7110 */
+// unsigned char req[64]={N6110_FRAME_HEADER, 0x01};
+// unsigned char req_end[]={0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};
+// int i=0;
+// req[4]=strlen(Number);
+// for(i=0; i < strlen(Number) ; i++)
+// req[5+i]=Number[i];
+// memcpy(req+5+strlen(Number), req_end, 10);
+// return NULL_SendMessageSequence
+// (20, &CurrentDialVoiceError, 13+strlen(Number), 0x01, req);
+
+ unsigned char req[64]={0x00,0x01,0x7c,
+ 0x01}; //call command
+
+ int i=0;
+
+ GSM_Error error;
+
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
+
+ for(i=0; i < strlen(Number) ; i++) req[4+i]=Number[i];
+
+ req[4+i+1]=0;
+
+ return NULL_SendMessageSequence
+ (20, &CurrentDialVoiceError, 4+strlen(Number)+1, 0x40, req);
+}
+
+/* Dial a data call - type specifies request to use:
+ type 0 should normally be used
+ type 1 should be used when calling a digital line - corresponds to ats35=0
+ Maybe one day we'll know what they mean!
+*/
+GSM_Error N6110_DialData(char *Number, char type, void (* callpassup)(char c))
+{
+ unsigned char req[100] = { N6110_FRAME_HEADER, 0x01 };
+ unsigned char *req_end;
+ unsigned char req_end0[] = { 0x01, /* make a data call = type 0x01 */
+ 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
+ 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00 };
+ unsigned char req_end1[] = { 0x01,
+ 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
+ 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
+ 0x88,0x90,0x21,0x48,0x40,0xbb };
+ unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
+ 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
+ 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
+ unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
+ 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
+ 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
+ unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
+ 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
+ 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
+ 0x20,0x15,0x63,0x80 };
+
+ int i = 0;
+ u8 size;
+
+ CurrentCallPassup=callpassup;
+
+ switch (type) {
+ case 0:
+ req_end = req_end0;
+ size = sizeof(req_end0);
+ break;
+ case 1:
+ Protocol->SendMessage(sizeof(req3), 0x01, req3);
+ usleep(1000000);
+ Protocol->SendMessage(sizeof(req4), 0x01, req4);
+ usleep(1000000);
+ req_end = req_end1;
+ size = sizeof(req_end1);
+ break;
+ case -1: /* Just used to set the call passup */
+ return GE_NONE;
+ break;
+ default:
+ req_end = req_end0;
+ size = sizeof(req_end0);
+ break;
+ }
+
+ req[4] = strlen(Number);
+
+ for(i = 0; i < strlen(Number) ; i++)
+ req[5+i] = Number[i];
+
+ memcpy(req + 5 + strlen(Number), req_end, size);
+
+ Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);
+ usleep(1000000);
+
+ if (type != 1) {
+ Protocol->SendMessage(26, 0x01, req2);
+ usleep(1000000);
+ }
+
+ return (GE_NONE);
+}
+
+GSM_Error N6110_GetIncomingCallNr(char *Number)
+{
+
+ if (*CurrentIncomingCall != ' ') {
+ strcpy(Number, CurrentIncomingCall);
+ return GE_NONE;
+ }
+ else
+ return GE_BUSY;
+}
+
+GSM_Error N6110_CancelCall(void)
+{
+// This frame & method works only on 61xx/51xx
+// unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
+// req[4]=CurrentCallSequenceNumber;
+// Protocol->SendMessage(6, 0x01, req);
+// return GE_NONE;
+
+ GSM_Error error;
+
+ unsigned char req[]={0x00,0x01,0x7c,0x03};
+
+ /* Checking */
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
+
+ return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
+}
+
+void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch(MessageBuffer[3]) {
+
+ case 0x0b:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Security code accepted.\n"));
+#endif /* DEBUG */
+ CurrentSecurityCodeError = GE_NONE;
+ break;
+
+ default:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
+#endif /* DEBUG */
+ CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
+ }
+}
+
+GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
+{
+
+ unsigned char req[15] = { N6110_FRAME_HEADER,
+ 0x0a, /* Enter code request. */
+ 0x00 /* Type of the entered code. */
+ };
+ int i=0;
+
+ req[4]=SecurityCode.Type;
+
+ for (i=0; i<strlen(SecurityCode.Code);i++)
+ req[5+i]=SecurityCode.Code[i];
+
+ req[5+strlen(SecurityCode.Code)]=0x00;
+ req[6+strlen(SecurityCode.Code)]=0x00;
+
+ return NULL_SendMessageSequence
+ (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
+}
+
+void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ *CurrentSecurityCodeStatus = MessageBuffer[4];
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Security Code status received: "));
+
+ switch(*CurrentSecurityCodeStatus) {
+
+ 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"));
+ }
+
+#endif /* DEBUG */
+
+ CurrentSecurityCodeError = GE_NONE;
+}
+
+GSM_Error N6110_GetSecurityCodeStatus(int *Status)
+{
+
+ unsigned char req[4] = { N6110_FRAME_HEADER,
+ 0x07
+ };
+
+ CurrentSecurityCodeStatus=Status;
+
+ return NULL_SendMessageSequence
+ (20, &CurrentSecurityCodeError, 4, 0x08, req);
+}
+
+void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int i;
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Security code received: "));
+ switch (MessageBuffer[3]) {
+ 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: fprintf(stdout, _("unknown !"));break;
+ }
+ if (MessageBuffer[4]==1) {
+ fprintf(stdout, _(" allowed, value \""));
+ if (MessageBuffer[3]==GSCT_SecurityCode) {
+ for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
+ }
+ if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
+ MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
+ for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
+ }
+ fprintf(stdout, _("\""));
+ } else {
+ fprintf(stdout, _(" not allowed"));
+ }
+ fprintf(stdout, _("\n"));
+#endif /* DEBUG */
+
+ if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
+ && MessageBuffer[4]==1) { /* It's allowed */
+ if (MessageBuffer[3]==GSCT_SecurityCode) {
+ for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
+ CurrentSecurityCode->Code[5]=0;
+ }
+ if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
+ MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
+ for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
+ CurrentSecurityCode->Code[4]=0;
+ }
+ CurrentSecurityCodeError=GE_NONE;
+ } else
+ CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
+}
+
+GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
+{
+
+ unsigned char req[4] = { 0x00,
+ 0x01,0x6e, /* Get code request. */
+ 0x00 }; /* Type of the requested code. */
+
+ GSM_Error error;
+
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
+
+ req[3]=SecurityCode->Type;
+
+ CurrentSecurityCode=SecurityCode;
+
+ return NULL_SendMessageSequence
+ (20, &CurrentSecurityCodeError, 4, 0x40, req);
+}
+
+void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: answer for PlayTone frame\n"));
+#endif
+
+ CurrentPlayToneError=GE_NONE;
+}
+
+GSM_Error N6110_PlayTone(int Herz, u8 Volume)
+{
+ unsigned char req[6] = { 0x00,0x01,0x8f,
+ 0x00, /* Volume */
+ 0x00, /* HerzLo */
+ 0x00 }; /* HerzHi */
+
+ GSM_Error error;
+
+ /* PlayTone wasn't used earlier */
+ if (CurrentPlayToneError==GE_UNKNOWN) {
+ if (CurrentConnectionType!=GCT_MBUS)
+ CurrentDisableKeepAlive=true;
+
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
+ }
+
+ /* For Herz==255*255 we have silent */
+ if (Herz!=255*255) {
+ req[3]=Volume;
+
+ req[5]=Herz%256;
+ req[4]=Herz/256;
+ } else {
+ req[3]=0;
+
+ req[5]=0;
+ req[4]=0;
+ }
+
+#ifdef WIN32
+ /* For Herz==255*255 we have silent and additionaly
+ we wait for phone answer - it's important for MBUS */
+ if (Herz==255*255) {
+ error=NULL_SendMessageSequence
+ (20, &CurrentPlayToneError, 6, 0x40, req);
+
+ CurrentPlayToneError=GE_UNKNOWN;
+ CurrentDisableKeepAlive=false;
+
+ if (error!=GE_NONE) return error;
+ } else {
+ Protocol->SendMessage(6,0x40,req);
+ }
+#else
+ error=NULL_SendMessageSequence
+ (20, &CurrentPlayToneError, 6, 0x40, req);
+
+ /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
+ if (Herz==255*255) {
+ CurrentPlayToneError=GE_UNKNOWN;
+ CurrentDisableKeepAlive=false;
+ }
+
+ if (error!=GE_NONE) return error;
+
+#endif
+
+ return(GE_NONE);
+}
+
+void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ if (MessageBuffer[4]==0x01) {
+ DecodeDateTime(MessageBuffer+8, CurrentDateTime);
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Date and time\n"));
+ fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
+ fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
+#endif /* DEBUG */
+
+ CurrentDateTime->IsSet=true;
+ } else {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Date and time not set in phone\n"));
+#endif
+
+ CurrentDateTime->IsSet=false;
+ }
+
+ CurrentDateTimeError=GE_NONE;
+}
+
+GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
+{
+ return N6110_PrivGetDateTime(date_time,0x11);
+}
+
+GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
+{
+ unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
+
+ CurrentDateTime=date_time;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentDateTimeError, 4, msgtype, req);
+}
+
+void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Alarm\n"));
+ fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
+ fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
+#endif /* DEBUG */
+
+ CurrentAlarm->Hour=MessageBuffer[9];
+ CurrentAlarm->Minute=MessageBuffer[10];
+ CurrentAlarm->Second=0;
+
+ CurrentAlarm->IsSet=(MessageBuffer[8]==2);
+
+ CurrentAlarmError=GE_NONE;
+}
+
+GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
+{
+ return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
+}
+
+GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
+{
+ unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
+
+ CurrentAlarm=date_time;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentAlarmError, 4, msgtype, req);
+}
+
+void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ case 0x34:
+
+ CurrentMessageCenter->No=MessageBuffer[4];
+ CurrentMessageCenter->Format=MessageBuffer[6];
+ CurrentMessageCenter->Validity=MessageBuffer[8];
+ sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
+
+ sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
+
+ sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: SMS Center received:\n"));
+ fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
+ fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
+ fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
+
+ fprintf(stdout, _(" SMS Center message format is "));
+
+ switch (CurrentMessageCenter->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 : fprintf(stdout, _("Email")); break;
+ default : fprintf(stdout, _("Unknown"));
+ }
+
+ fprintf(stdout, "\n");
+
+ fprintf(stdout, _(" SMS Center message validity is "));
+
+ switch (CurrentMessageCenter->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"));
+ }
+
+ fprintf(stdout, "\n");
+
+#endif /* DEBUG */
+
+ CurrentMessageCenterError=GE_NONE;
+
+ break;
+
+ case 0x35:
+
+ /* Number of entries depends on SIM card */
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: SMS Center error received:\n"));
+ fprintf(stdout, _(" The request for SMS Center failed.\n"));
+#endif /* DEBUG */
+
+ /* FIXME: appropriate error. */
+ CurrentMessageCenterError=GE_INTERNALERROR;
+
+ break;
+
+ }
+}
+
+/* This function sends to the mobile phone a request for the SMS Center */
+GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
+{
+ unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
+ 0x00 /* SMS Center Number. */
+ };
+
+ req[5]=MessageCenter->No;
+
+ CurrentMessageCenter=MessageCenter;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentMessageCenterError, 6, 0x02, req);
+}
+
+void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: SMS Center correctly set.\n"));
+#endif
+ CurrentMessageCenterError=GE_NONE;
+}
+
+/* This function set the SMS Center profile on the phone. */
+GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
+{
+ unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
+ 0x00, /* SMS Center Number. */
+ 0x00, /* Unknown. */
+ 0x00, /* SMS Message Format. */
+ 0x00, /* Unknown. */
+ 0x00, /* Validity. */
+ 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
+ 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
+ /* Message Center Name. */
+ };
+
+ req[5]=MessageCenter->No;
+ req[7]=MessageCenter->Format;
+ req[9]=MessageCenter->Validity;
+
+ req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
+
+ req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
+
+ sprintf(req+34, "%s", MessageCenter->Name);
+
+ CurrentMessageCenter=MessageCenter;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
+}
+
+void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ case 0x37:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: SMS Status Received\n"));
+ fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
+ fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
+#endif /* DEBUG */
+
+ CurrentSMSStatus->UnRead = MessageBuffer[11];
+ CurrentSMSStatus->Number = MessageBuffer[10];
+
+ CurrentSMSStatusError = GE_NONE;
+ break;
+
+ case 0x38:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
+#endif /* DEBUG */
+
+ CurrentSMSStatusError = GE_INTERNALERROR;
+ break;
+
+ }
+}
+
+GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
+{
+ unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
+
+ CurrentSMSStatus = Status;
+
+ return NULL_SendMessageSequence
+ (10, &CurrentSMSStatusError, 5, 0x14, req);
+}
+
+GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
+{
+ folders->number=2;
+
+ strcpy(folders->Folder[0].Name,"Inbox");
+ strcpy(folders->Folder[1].Name,"Outbox");
+
+ return GE_NONE;
+}
+
+GSM_Error N6110_GetIMEI(char *imei)
+{
+ if (strlen(Current_IMEI)>0) {
+ strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
+ return (GE_NONE);
+ }
+ else
+ return (GE_TRYAGAIN);
+}
+
+GSM_Error N6110_GetRevision(char *revision)
+{
+
+ if (strlen(Current_Revision)>0) {
+ strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
+ return (GE_NONE);
+ }
+ else
+ return (GE_TRYAGAIN);
+}
+
+GSM_Error N6110_GetModel(char *model)
+{
+ if (strlen(Current_Model)>0) {
+ strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
+ return (GE_NONE);
+ }
+ else
+ return (GE_TRYAGAIN);
+}
+
+void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[4]) {
+
+ case 0x01:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Date and time set correctly\n"));
+#endif /* DEBUG */
+ CurrentSetDateTimeError=GE_NONE;
+ break;
+
+ default:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Date and time setting error\n"));
+#endif /* DEBUG */
+ CurrentSetDateTimeError=GE_INVALIDDATETIME;
+
+ }
+}
+
+/* Needs SIM card with PIN in phone */
+GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
+{
+ return N6110_PrivSetDateTime(date_time,0x11);
+}
+
+/* Needs SIM card with PIN in phone */
+GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
+{
+
+ unsigned char req[] = { N6110_FRAME_HEADER,
+ 0x60, /* set-time subtype */
+ 0x01, 0x01, 0x07, /* unknown */
+ 0x00, 0x00, /* Year (0x07cf = 1999) */
+ 0x00, 0x00, /* Month Day */
+ 0x00, 0x00, /* Hours Minutes */
+ 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
+ };
+
+ EncodeDateTime(req+7, date_time);
+
+ return NULL_SendMessageSequence
+ (20, &CurrentSetDateTimeError, 14, msgtype, req);
+}
+
+void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[4]) {
+
+ case 0x01:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Alarm set correctly\n"));
+#endif /* DEBUG */
+ CurrentSetAlarmError=GE_NONE;
+ break;
+
+ default:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Alarm setting error\n"));
+#endif /* DEBUG */
+ CurrentSetAlarmError=GE_INVALIDDATETIME;
+
+ }
+}
+
+/* FIXME: we should also allow to set the alarm off :-) */
+GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
+{
+ return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
+}
+
+/* FIXME: we should also allow to set the alarm off :-) */
+GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
+{
+
+ unsigned char req[] = { N6110_FRAME_HEADER,
+ 0x6b, /* set-alarm subtype */
+ 0x01, 0x20, 0x03, /* unknown */
+ 0x02, /* should be alarm on/off, but it don't works */
+ 0x00, 0x00, /* Hours Minutes */
+ 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
+ };
+
+ req[8] = date_time->Hour;
+ req[9] = date_time->Minute;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentSetAlarmError, 11, msgtype, req);
+}
+
+void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
+ char model[64];
+
+ int i, tmp, count;
+
+ switch (MessageBuffer[3]) {
+
+ case 0x02:
+
+ CurrentPhonebookEntry->Empty = true;
+
+ count=MessageBuffer[5];
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Phonebook entry received:\n"));
+ fprintf(stdout, _(" Name: "));
+
+ for (tmp=0; tmp <count; tmp++)
+ {
+ if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
+ if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
+ fprintf(stdout, "%c", MessageBuffer[6+tmp]);
+ }
+
+ fprintf(stdout, "\n");
+#endif /* DEBUG */
+
+ while (N6110_GetModel(model) != GE_NONE)
+ sleep(1);
+
+ if (GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM ||
+ GetModelFeature (FN_PHONEBOOK)==F_PBK33INT) {//pbk with Unicode
+ DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
+ CurrentPhonebookEntry->Name[count/2] = 0x00;
+ } else {
+ memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);
+ CurrentPhonebookEntry->Name[count] = 0x00;
+ }
+
+ CurrentPhonebookEntry->Empty = false;
+
+ for (tmp=0; tmp <count; tmp++)
+ {
+ if (GetModelFeature (FN_PHONEBOOK)==F_PBK33INT ||
+ GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM) {//pbk with Unicode
+ /* We check only 1'st, 3'rd, ... char */
+ if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking
+ if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents
+ } else {
+ if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking
+ if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents
+ }
+ }
+
+ i=7+count;
+ count=MessageBuffer[6+count];
+
+#ifdef DEBUG
+ fprintf(stdout, _(" Number: "));
+
+ for (tmp=0; tmp <count; tmp++)
+ fprintf(stdout, "%c", MessageBuffer[i+tmp]);
+
+ fprintf(stdout, "\n");
+#endif /* DEBUG */
+
+ memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);
+ CurrentPhonebookEntry->Number[count] = 0x00;
+ CurrentPhonebookEntry->Group = MessageBuffer[i+count];
+
+ /* Phone doesn't have entended phonebook */
+ CurrentPhonebookEntry->SubEntriesCount = 0;
+
+ /* But for these memories data is saved and we can save it using 7110/6210 style */
+ if (CurrentPhonebookEntry->MemoryType==GMT_DC ||
+ CurrentPhonebookEntry->MemoryType==GMT_RC ||
+ CurrentPhonebookEntry->MemoryType==GMT_MC) {
+ CurrentPhonebookEntry->SubEntriesCount = 1;
+ CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;
+ CurrentPhonebookEntry->SubEntries[0].NumberType=0;
+ CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;
+ DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);
+
+#ifdef DEBUG
+ fprintf(stdout, _(" Date: "));
+ fprintf(stdout, "%02u.%02u.%04u\n",
+ CurrentPhonebookEntry->SubEntries[0].data.Date.Day,
+ CurrentPhonebookEntry->SubEntries[0].data.Date.Month,
+ CurrentPhonebookEntry->SubEntries[0].data.Date.Year);
+ fprintf(stdout, _(" Time: "));
+ fprintf(stdout, "%02u:%02u:%02u\n",
+ CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,
+ CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,
+ CurrentPhonebookEntry->SubEntries[0].data.Date.Second);
+#endif /* DEBUG */
+
+ /* These values are set, when date and time unavailable in phone.
+ Values from 3310 - in other can be different */
+ if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&
+ CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&
+ CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&
+ CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&
+ CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&
+ CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)
+ CurrentPhonebookEntry->SubEntriesCount = 0;
+ }
+
+ /* Signal no error to calling code. */
+ CurrentPhonebookError = GE_NONE;
+
+ break;
+
+ case 0x03:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Phonebook read entry error received:\n"));
+#endif /* DEBUG */
+
+ switch (MessageBuffer[4]) {
+
+ case 0x7d:
+#ifdef DEBUG
+ fprintf(stdout, _(" Invalid memory type!\n"));
+#endif /* DEBUG */
+ CurrentPhonebookError = GE_INVALIDMEMORYTYPE;
+ break;
+
+ default:
+#ifdef DEBUG
+ fprintf(stdout, _(" Unknown error!\n"));
+#endif /* DEBUG */
+ CurrentPhonebookError = GE_INTERNALERROR;
+ }
+
+ break;
+
+ }
+}
+
+/* Routine to get specifed phone book location. Designed to be called by
+ application. Will block until location is retrieved or a timeout/error
+ occurs. */
+GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)
+{
+ unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
+
+ CurrentPhonebookEntry = entry;
+
+ req[4] = N6110_GetMemoryType(entry->MemoryType);
+ req[5] = entry->Location;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentPhonebookError, 7, 0x03, req);
+}
+
+void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ case 0x05:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Phonebook written correctly.\n"));
+#endif /* DEBUG */
+ CurrentPhonebookError = GE_NONE;
+ break;
+
+ case 0x06:
+
+ switch (MessageBuffer[4]) {
+ /* FIXME: other errors? When I send the phonebook with index of 350 it
+ still report error 0x7d :-( */
+ case 0x7d:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));
+#endif /* DEBUG */
+ CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;
+ break;
+
+ default:
+#ifdef DEBUG
+ fprintf(stdout, _(" Unknown error!\n"));
+#endif /* DEBUG */
+ CurrentPhonebookError = GE_INTERNALERROR;
+ }
+ }
+}
+
+/* Routine to write phonebook location in phone. Designed to be called by
+ application code. Will block until location is written or timeout
+ occurs. */
+GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)
+{
+ unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };
+ int i=0, current=0;
+
+ req[4] = N6110_GetMemoryType(entry->MemoryType);
+ req[5] = entry->Location;
+
+ current=7;
+
+ if (GetModelFeature (FN_PHONEBOOK)==F_PBK33INT ||
+ GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM) {
+
+ req[6] = strlen(entry->Name)*2;
+
+ EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
+
+ for (i=0; i<strlen(entry->Name); i++)
+ {
+ /* here we encode "special" chars */
+ if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
+ if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
+ }
+
+ current+=strlen(entry->Name)*2;
+ } else {
+
+ req[6] = strlen(entry->Name);
+
+ for (i=0; i<strlen(entry->Name); i++)
+ {
+ req[current+i] = entry->Name[i];
+
+ /* here we encode "special" chars */
+ if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
+ if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
+ }
+
+ current+=strlen(entry->Name);
+ }
+
+ req[current++]=strlen(entry->Number);
+
+ for (i=0; i<strlen(entry->Number); i++)
+ req[current+i] = entry->Number[i];
+
+ current+=strlen(entry->Number);
+
+ /* Jano: This allow to save 14 characters name into SIM memory, when
+ No Group is selected. */
+ if (entry->Group == 5)
+ req[current++]=0xff;
+ else
+ req[current++]=entry->Group;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentPhonebookError, current, 0x03, req);
+}
+
+void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch(MessageBuffer[3]) {
+
+ case 0x00:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
+#endif /* DEBUG */
+ CurrentNetmonitorError=GE_NONE;
+ break;
+
+ default:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
+ fprintf(stdout, "%s\n", MessageBuffer+4);
+#endif /* DEBUG */
+
+ strcpy(CurrentNetmonitor, MessageBuffer+4);
+
+ CurrentNetmonitorError=GE_NONE;
+ }
+}
+
+GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
+{
+ unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
+
+ GSM_Error error;
+
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
+
+ CurrentNetmonitor=Screen;
+
+ req[3]=mode;
+
+ return NULL_SendMessageSequence
+ (20, &CurrentNetmonitorError, 4, 0x40, req);
+}
+
+/* Doesn't work in N3210. */
+/* In other allow to access phone menu without SIM card (just send any sequence) */
+GSM_Error N6110_SendDTMF(char *String)
+{
+ unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
+ 0x00 /* Length of DTMF string. */
+ };
+
+ u8 length=strlen(String);
+
+ if (length>59) length=59;
+
+ req[4] = length;
+
+ memcpy(req+5,String,length);
+
+ return NULL_SendMessageSequence
+ (20, &CurrentSendDTMFError, 5+length, 0x01, req);
+}
+
+void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ case 0x17:
+
+ switch (MessageBuffer[4]) {
+ case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
+ default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
+ }
+
+ CurrentSpeedDialEntry->Location = MessageBuffer[5];
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Speed dial entry received:\n"));
+ fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
+ fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
+ fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
+#endif /* DEBUG */
+
+ CurrentSpeedDialError=GE_NONE;
+ break;
+
+ case 0x18:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Speed dial entry error\n"));
+#endif /* DEBUG */
+ CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
+ break;
+
+ }
+}
+
+GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
+{
+
+ unsigned char req[] = { N6110_FRAME_HEADER,
+ 0x16,
+ 0x00 /* The number of speed dial. */
+ };
+
+ CurrentSpeedDialEntry = entry;
+
+ req[4] = entry->Number;
+
+ return NULL_SendMessageSequence
+ (20, &CurrentSpeedDialError, 5, 0x03, req);
+}
+
+void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ case 0x1a:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Speed dial entry set.\n"));
+#endif /* DEBUG */
+ CurrentSpeedDialError=GE_NONE;
+ break;
+
+ case 0x1b:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
+#endif /* DEBUG */
+ CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
+ break;
+
+ }
+}
+
+GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
+{
+
+ unsigned char req[] = { N6110_FRAME_HEADER,
+ 0x19,
+ 0x00, /* Number */
+ 0x00, /* Memory Type */
+ 0x00 /* Location */
+ };
+
+ req[4] = entry->Number;
+
+ switch (entry->MemoryType) {
+ case GMT_ME: req[5] = 0x02;
+ default : req[5] = 0x03;
+ }
+
+ req[6] = entry->Location;
+
+ return NULL_SendMessageSequence
+ (20, &CurrentSpeedDialError, 7, 0x03, req);
+}
+
+/* This function finds parts of SMS in frame used in new Nokia phones
+ in internal protocols (they're coded according to GSM 03.40), copies them
+ to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
+ GSM_ETSISMSMessage to GSM_SMSMessage structure */
+GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
+{
+ SMS_MessageType PDU=SMS_Deliver;
+ GSM_ETSISMSMessage ETSI;
+ int offset=0,i;
+
+ ETSI.firstbyte=req[12];
+
+ /* See GSM 03.40 section 9.2.3.1 */
+ if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
+ if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
+
+ switch (PDU) {
+ case SMS_Submit : offset=5;break;
+ case SMS_Deliver : offset=4;break;
+ case SMS_Status_Report: offset=3;break;
+ default: break;
+ }
+
+ for (i=0;i<req[0]+1;i++)
+ ETSI.SMSCNumber[i]=req[i];
+
+ for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
+ ETSI.Number[i]=req[i+12+offset];
+
+ switch (PDU) {
+ case SMS_Submit:
+ ETSI.TPDCS=req[10+offset];
+ ETSI.TPUDL=req[11+offset];
+ ETSI.TPVP=0; //no support for now
+ ETSI.TPPID=0; //no support for now
+ for(i=31+offset;i<length;i++)
+ ETSI.MessageText[i-31-offset]=req[i];
+ break;
+ case SMS_Deliver:
+ ETSI.TPDCS=req[10+offset];
+ ETSI.TPUDL=req[11+offset];
+ ETSI.TPPID=0; //no support for now
+ for(i=31+offset;i<length;i++)
+ ETSI.MessageText[i-31-offset]=req[i];
+ for(i=0;i<7;i++)
+ ETSI.DeliveryDateTime[i]=req[i+24+offset];
+ break;
+ case SMS_Status_Report:
+ for(i=0;i<7;i++)
+ ETSI.DeliveryDateTime[i]=req[i+24+offset];
+ ETSI.TPStatus=req[14];
+ for(i=0;i<7;i++)
+ ETSI.SMSCDateTime[i]=req[i+34];
+ break;
+ default:
+ break;
+ }
+
+ GSM_DecodeETSISMS(SMS, &ETSI);
+
+ SMS->Name[0]=0;
+
+ return GE_NONE;
+}
+
+void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int offset;
+
+ switch (MessageBuffer[3]) {
+
+ case 0x08:
+
+ switch (MessageBuffer[7]) {
+
+ case 0x00:
+ CurrentSMSMessage->Type = GST_SMS;
+ CurrentSMSMessage->folder=GST_INBOX;
+ offset=4;
+ break;
+
+ case 0x01:
+ CurrentSMSMessage->Type = GST_DR;
+ CurrentSMSMessage->folder=GST_INBOX;
+ offset=3;
+ break;
+
+ case 0x02:
+ CurrentSMSMessage->Type = GST_SMS;
+ CurrentSMSMessage->folder=GST_OUTBOX;
+ offset=5;
+ break;
+
+ default:
+ CurrentSMSMessage->Type = GST_UN;
+ offset=4;
+ break;
+
+ }
+
+ /* Field Short Message Status - MessageBuffer[4] seems not to be
+ compliant with GSM 07.05 spec.
+ Meaning Nokia protocol GMS spec
+ ----------------------------------------------------
+ MO Sent 0x05 0x07 or 0x01
+ MO Not sent 0x07 0x06 or 0x00
+ MT Read 0x01 0x05 or 0x01
+ MT Not read 0x03 0x04 or 0x00
+ ----------------------------------------------------
+ See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
+
+ Pawel Kot */
+
+ if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
+ else CurrentSMSMessage->Status = GSS_SENTREAD;
+
+#ifdef DEBUG
+ fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
+
+ if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
+ fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
+ } else {
+ fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
+ }
+
+ if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
+ if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
+
+ if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
+ if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
+ else fprintf(stdout, _(" Not sent\n"));
+ } else {
+ if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
+ else fprintf(stdout, _(" Not read\n"));
+ }
+#endif
+
+ CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
+
+ CurrentSMSMessage->MemoryType = MessageBuffer[5];
+ CurrentSMSMessage->MessageNumber = MessageBuffer[6];
+
+ /* Signal no error to calling code. */
+ CurrentSMSMessageError = GE_NONE;
+
+#ifdef DEBUG
+ fprintf(stdout, "\n");
+#endif
+
+ break;
+
+ case 0x09:
+
+ /* We have requested invalid or empty location. */
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: SMS reading failed\n"));
+
+ switch (MessageBuffer[4]) {
+ case 0x02:fprintf(stdout, _(" Invalid location!\n"));break;
+ case 0x07:fprintf(stdout, _(" Empty SMS location.\n"));break;
+ case 0x0c:fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
+ default :fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
+ }
+#endif /* DEBUG */
+
+ switch (MessageBuffer[4]) {
+ case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
+ case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
+ case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
+ default :CurrentSMSMessageError = GE_UNKNOWN;break;
+ }
+
+ break;
+
+ }
+}
+
+GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
+{
+
+ unsigned char req[] = { N6110_FRAME_HEADER,
+ 0x07,
+ 0x02, /* Unknown */
+ 0x00, /* Location */
+ 0x01, 0x64};
+
+ int timeout = 60;
+
+ /* State machine code writes data to these variables when it comes in. */
+
+ CurrentSMSMessage = message;
+ CurrentSMSMessageError = GE_BUSY;
+
+ req[5] = message->Location;
+
+ /* Send request */
+ Protocol->SendMessage(8, 0x02, req);
+
+ /* Wait for timeout or other error. */
+ while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
+
+ if (--timeout == 0)
+ return (GE_TIMEOUT);
+
+ usleep (100000);
+ }
+
+ return (CurrentSMSMessageError);
+}
+
+void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: SMS deleted successfully.\n"));
+#endif /* DEBUG */
+
+ CurrentSMSMessageError = GE_NONE;
+}
+
+GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
+{
+ unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
+
+ req[5] = message->Location;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentSMSMessageError, 6, 0x14, req);
+}
+
+/* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
+GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
+{
+ GSM_ETSISMSMessage ETSI;
+ int i,offset=0;
+
+ GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
+
+ /* Cleaning */
+ for (i=0;i<36;i++) req[i]=0;
+
+ req[12]=ETSI.firstbyte;
+
+ for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
+ req[i]=ETSI.SMSCNumber[i];
+
+ switch (PDU) {
+ case SMS_Submit:
+ offset=5;
+ for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++) req[i+12+offset]=ETSI.Number[i];
+ req[10+offset]=ETSI.TPDCS;
+ req[11+offset]=ETSI.TPUDL;
+ req[24+offset]=ETSI.TPVP;
+#ifdef DEBUG
+// fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
+// fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
+// fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
+#endif
+// req[]=ETSI.TPPID;
+ for(i=0;i<*length;i++) req[i+31+offset]=ETSI.MessageText[i];
+ break;
+
+ case SMS_Deliver:
+ offset=4;
+ for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++) req[i+12+offset]=ETSI.Number[i];
+ req[10+offset]=ETSI.TPDCS;
+ req[11+offset]=ETSI.TPUDL;
+// req[]=ETSI.TPPID;
+ for(i=0;i<*length;i++) req[i+31+offset]=ETSI.MessageText[i];
+ for (i=0;i<7;i++) req[24+offset+i]=ETSI.DeliveryDateTime[i];
+ break;
+ default:
+ break;
+ }
+
+ *length=*length+offset;
+
+ return GE_NONE;
+}
+
+void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ /* SMS message correctly sent to the network */
+ case 0x02:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
+#endif /* DEBUG */
+ CurrentSMSMessageError = GE_SMSSENDOK;
+ break;
+
+ /* SMS message send to the network failed */
+ case 0x03:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
+
+ switch (MessageBuffer[6]) {
+ case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
+ case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
+ case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
+ case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
+ case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
+ case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
+ case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
+ case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
+ case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
+ }
+
+ fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
+ fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
+#endif /* DEBUG */
+
+ CurrentSMSMessageError = GE_SMSSENDFAILED;
+ break;
+
+ }
+}
+
+GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
+{
+ GSM_Error error;
+
+ unsigned char req[256] = {
+ N6110_FRAME_HEADER,
+ 0x01, 0x02, 0x00, /* SMS send request*/
+ };
+
+ int length;
+
+ error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
+ if (error != GE_NONE) return error;
+
+ return NULL_SendMessageSequence
+ (200, &CurrentSMSMessageError, 42+length, 0x02, req);
+}
+
+void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ case 0x05:
+
+#ifdef DEBUG
+ fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
+#endif
+
+ CurrentSMSMessage->MessageNumber=MessageBuffer[5];
+
+ CurrentSMSMessageError = GE_NONE;
+ break;
+
+ case 0x06:
+#ifdef DEBUG
+ fprintf(stdout, _("SMS saving failed\n"));
+ switch (MessageBuffer[4]) {
+ case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
+ case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
+ default :fprintf(stdout, _(" Unknown error.\n"));break;
+ }
+#endif
+
+ switch (MessageBuffer[4]) {
+ case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
+ case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
+ default :CurrentSMSMessageError = GE_UNKNOWN;break;
+ }
+ }
+}
+
+/* GST_DR and GST_UN not supported ! */
+GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
+{
+ unsigned char req[256] = {
+ N6110_FRAME_HEADER, 0x04, /* SMS save request*/
+ 0x00, /* SMS Status. Different for Inbox and Outbox */
+ 0x02, /* ?? */
+ 0x00, /* SMS Location */
+ 0x02, /* SMS Type */
+ };
+
+ int length;
+ SMS_MessageType PDU;
+ GSM_Error error;
+
+ if (SMS->Location) req[6] = SMS->Location;
+
+ if (SMS->folder==0) { /*Inbox*/
+ req[4]=1; /* SMS Status */
+ req[7] = 0x00; /* SMS Type */
+ PDU=SMS_Deliver;
+ } else {
+ req[4]=5; /* SMS Status */
+ req[7] = 0x02; /* SMS Type */
+ PDU=SMS_Submit;
+ }
+
+ if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
+
+ error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
+ if (error != GE_NONE) return error;
+
+ CurrentSMSMessage = SMS;
+
+ return NULL_SendMessageSequence
+ (70, &CurrentSMSMessageError, 39+length, 0x14, req);
+}
+
+void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
+#endif
+
+ CurrentCBError = GE_NONE;
+}
+
+/* Enable and disable Cell Broadcasting */
+GSM_Error N6110_EnableCellBroadcast(void)
+{
+ unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
+
+#ifdef DEBUG
+ fprintf (stdout,"Enabling CB\n");
+#endif
+
+ CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
+ CurrentCBMessage->Channel = 0;
+ CurrentCBMessage->New = false;
+ strcpy (CurrentCBMessage->Message,"");
+
+ return NULL_SendMessageSequence
+ (10, &CurrentCBError, 10, 0x02, req);
+}
+
+
+GSM_Error N6110_DisableCellBroadcast(void)
+{
+ /* Should work, but not tested fully */
+
+ unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
+
+ return NULL_SendMessageSequence
+ (10, &CurrentCBError, 10, 0x02, req);
+}
+
+void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int i, tmp;
+ unsigned char output[160];
+
+ CurrentCBMessage->Channel = MessageBuffer[7];
+ CurrentCBMessage->New = true;
+ tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
+
+ fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
+
+ fflush (stdout);
+
+ for (i=0; i<tmp;i++) {
+ fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
+ }
+
+ fprintf(stdout, "\n");
+#endif
+
+ for (i=0; i<tmp; i++) {
+ CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
+ }
+ CurrentCBMessage->Message[i]=0;
+}
+
+GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
+{
+#ifdef DEBUG
+ fprintf(stdout,"Reading CB\n");
+#endif
+
+ if (CurrentCBMessage != NULL)
+ {
+ if (CurrentCBMessage->New == true)
+ {
+#ifdef DEBUG
+ fprintf(stdout,"New CB received\n");
+#endif
+ Message->Channel = CurrentCBMessage->Channel;
+ strcpy(Message->Message,CurrentCBMessage->Message);
+ CurrentCBMessage->New = false;
+ return (GE_NONE);
+ }
+ }
+ return (GE_NONEWCBRECEIVED);
+}
+
+int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
+{
+ int count=0;
+
+ req[count++]=Bitmap.number;
+ req[count++]=strlen(Bitmap.text);
+ memcpy(req+count,Bitmap.text,req[count-1]);
+ count+=req[count-1];
+ req[count++]=Bitmap.ringtone;
+
+ /* Setting for graphic:
+ 0x00 - Off
+ 0x01 - On
+ 0x02 - View Graphics
+ 0x03 - Send Graphics
+ 0x04 - Send via IR
+ You can even set it higher but Nokia phones (my
+ 6110 at least) will not show you the name of this
+ item in menu ;-)) Nokia is really joking here. */
+ if (Bitmap.enabled) req[count++]=0x01;
+ else req[count++]=0x00;
+
+ req[count++]=(Bitmap.size+4)>>8;
+ req[count++]=(Bitmap.size+4)%0xff;
+ req[count++]=0x00; /* Future extensions! */
+ req[count++]=Bitmap.width;
+ req[count++]=Bitmap.height;
+ req[count++]=0x01; /* Just BW */
+ memcpy(req+count,Bitmap.bitmap,Bitmap.size);
+
+ return count+Bitmap.size;
+}
+
+int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
+{
+ int count=0;
+
+ EncodeNetworkCode(req+count, Bitmap.netcode);
+ count=count+3;
+
+ req[count++]=(Bitmap.size+4)>>8;
+ req[count++]=(Bitmap.size+4)%0xff;
+ req[count++]=0x00; /* Infofield */
+ req[count++]=Bitmap.width;
+ req[count++]=Bitmap.height;
+ req[count++]=0x01; /* Just BW */
+ memcpy(req+count,Bitmap.bitmap,Bitmap.size);
+
+ return count+Bitmap.size;
+}
+
+int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
+{
+ int count=0;
+
+ req[count++]=0x01;
+ req[count++]=Bitmap.height;
+ req[count++]=Bitmap.width;
+ memcpy(req+count,Bitmap.bitmap,Bitmap.size);
+
+ return count+Bitmap.size;
+}
+
+/* Set a bitmap or welcome-note */
+GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
+
+ unsigned char req[600] = { N6110_FRAME_HEADER };
+ u16 count=3;
+ u8 textlen;
+
+ int timeout=50;
+
+ /* Direct uploading variables */
+ GSM_MultiSMSMessage SMS;
+ unsigned char buffer[1000] = {0x0c,0x01};
+ GSM_NetworkInfo NetworkInfo;
+
+ GSM_Error error;
+
+ /* Uploading with preview */
+ if (Bitmap->number==255 &&
+ (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
+ GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
+ memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
+
+ memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
+
+ buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
+
+ Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
+
+ GSM->GetNetworkInfo(&NetworkInfo); //need to make something
+ return GE_NONE; //no answer from phone
+ }
+
+ CurrentSetBitmapError = GE_BUSY;
+
+ switch (Bitmap->type) {
+ case GSM_WelcomeNoteText:
+ case GSM_DealerNoteText:
+ req[count++]=0x18;
+ req[count++]=0x01; /* Only one block */
+
+ if (Bitmap->type==GSM_WelcomeNoteText)
+ req[count++]=0x02; /* Welcome text */
+ else
+ req[count++]=0x03; /* Dealer Welcome Note */
+
+ textlen=strlen(Bitmap->text);
+ req[count++]=textlen;
+ memcpy(req+count,Bitmap->text,textlen);
+
+ count+=textlen;
+
+ Protocol->SendMessage(count, 0x05, req);
+
+ break;
+
+ case GSM_StartupLogo:
+ if (Bitmap->number==0) {
+
+ /* For 33xx we first set animated logo to default */
+ if (GetModelFeature (FN_STARTUP)==F_STANIM) {
+ error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
+ if (error!=GE_NONE) return error;
+ }
+
+ req[count++]=0x18;
+ req[count++]=0x01; /* Only one block */
+ count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
+ Protocol->SendMessage(count, 0x05, req);
+ } else {
+ return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
+ }
+ break;
+
+ case GSM_OperatorLogo:
+ req[count++]=0x30; /* Store Op Logo */
+ req[count++]=0x01; /* Location */
+ count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
+ Protocol->SendMessage(count, 0x05, req);
+ break;
+
+ case GSM_CallerLogo:
+ req[count++]=0x13;
+ count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
+ Protocol->SendMessage(count, 0x03, req);
+ break;
+
+ case GSM_PictureImage:
+ req[count++]=0x03;
+ req[count++]=Bitmap->number;
+ if (strcmp(Bitmap->Sender,"")) {
+ req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
+
+ /* Convert number of semioctets to number of chars and add count */
+ textlen=req[count];
+ if (textlen % 2) textlen++;
+ count+=textlen / 2 + 1;
+
+ count++;
+ } else {
+ req[count++]=0x00;
+ req[count++]=0x00;
+ }
+ req[count++]=0x00;
+ req[count++]=strlen(Bitmap->text);
+ memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
+ count+=strlen(Bitmap->text);
+ req[count++]=0x00;
+ req[count++]=Bitmap->width;
+ req[count++]=Bitmap->height;
+ req[count++]=0x01;
+ memcpy(req+count,Bitmap->bitmap,Bitmap->size);
+ Protocol->SendMessage(count+Bitmap->size, 0x47, req);
+ break;
+
+ case GSM_7110OperatorLogo:
+ case GSM_7110StartupLogo:
+ case GSM_6210StartupLogo:
+ return GE_NOTSUPPORTED;
+
+ case GSM_None:
+ return GE_NONE;
+ }
+
+ /* Wait for timeout or other error. */
+ while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
+
+ if (--timeout == 0)
+ return (GE_TIMEOUT);
+
+ usleep (100000);
+ }
+
+ return CurrentSetBitmapError;
+}
+
+/* Get a bitmap from the phone */
+GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
+
+ unsigned char req[10] = { N6110_FRAME_HEADER };
+ u8 count=3;
+
+ int timeout=100;
+
+ CurrentGetBitmap=Bitmap;
+ CurrentGetBitmapError = GE_BUSY;
+
+ switch (CurrentGetBitmap->type) {
+ case GSM_StartupLogo:
+ case GSM_WelcomeNoteText:
+ case GSM_DealerNoteText:
+ req[count++]=0x16;
+ Protocol->SendMessage(count, 0x05, req);
+ break;
+ case GSM_OperatorLogo:
+ req[count++]=0x33;
+ req[count++]=0x01; /* Location 1 */
+ Protocol->SendMessage(count, 0x05, req);
+ break;
+ case GSM_CallerLogo:
+ req[count++]=0x10;
+ req[count++]=Bitmap->number;
+ Protocol->SendMessage(count, 0x03, req);
+ break;
+ case GSM_PictureImage:
+ req[count++]=0x01;
+ req[count++]=Bitmap->number;
+ Protocol->SendMessage(count, 0x47, req);
+ break;
+ case GSM_7110OperatorLogo:
+ case GSM_7110StartupLogo:
+ case GSM_6210StartupLogo:
+ default:
+ return GE_NOTSUPPORTED;
+ }
+
+ /* Wait for timeout or other error. */
+ while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
+
+ if (--timeout == 0)
+ return (GE_TIMEOUT);
+
+ usleep (100000);
+ }
+
+ CurrentGetBitmap=NULL;
+
+ return CurrentGetBitmapError;
+}
+
+void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ /* Set ringtone OK */
+ case 0x37:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Ringtone set OK!\n"));
+#endif
+ CurrentRingtoneError=GE_NONE;
+ break;
+
+ /* Set ringtone error */
+ case 0x38:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Ringtone setting error !\n"));
+#endif
+ CurrentRingtoneError=GE_NOTSUPPORTED;
+ break;
+ }
+}
+
+GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
+{
+
+ char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
+ {N6110_FRAME_HEADER,
+ 0x36,
+ 0x00, /* Location */
+ 0x00,0x78};
+
+ int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
+
+ /* Variables for preview uploading */
+ unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
+ unsigned char buffer2[20];
+ GSM_NetworkInfo NetworkInfo;
+
+ /* Setting ringtone with preview */
+ if (ringtone->location==255) {
+ buffer[0]=0x0c;
+ buffer[1]=0x01;
+ EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
+ memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
+ *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
+ Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
+ GSM->GetNetworkInfo(&NetworkInfo); //need to make something
+ sleep(1);
+ return GE_NONE; //no answer from phone
+ }
+
+ *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
+
+ req[4]=ringtone->location-1;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentRingtoneError, (size+7), 0x05, req);
+}
+
+void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int i;
+
+ switch (MessageBuffer[4]) {
+ case 0x00: /* location supported. We have ringtone */
+
+ /* Binary format used in N6150 */
+ if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
+#ifdef DEBUG
+ fprintf(stdout,_("Message: ringtone \""));
+#endif
+
+ /* Copying name */
+ i=8;
+ while (true) {
+#ifdef DEBUG
+ if (MessageBuffer[i]!=0)
+ fprintf(stdout,_("%c"),MessageBuffer[i]);
+#endif
+ CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
+ if (MessageBuffer[i]==0) break;
+ i++;
+ }
+
+#ifdef DEBUG
+ fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
+#endif
+
+ /* Looking for end */
+ i=0;
+ while (true) {
+ if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
+ i=i+2;break;
+ }
+ if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
+ i=i+2;break;
+ }
+ i++;
+ if (i==MessageLength) break;
+ }
+
+ /* Copying frame */
+ memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
+ CurrentGetBinRingtone->length=i-3;
+
+ CurrentBinRingtoneError=GE_NONE;
+ break;
+ }
+
+ /* Binary format used in N3210 */
+ if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
+
+#ifdef DEBUG
+ fprintf(stdout,_("Message: ringtone \""));
+#endif
+
+ /* Copying name */
+ i=8;
+ while (true) {
+#ifdef DEBUG
+ if (MessageBuffer[i]!=0)
+ fprintf(stdout,_("%c"),MessageBuffer[i]);
+#endif
+ CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
+ if (MessageBuffer[i]==0) break;
+ i++;
+ }
+
+#ifdef DEBUG
+ fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
+#endif
+
+ /* Here changes to get full compatibility with binary format used in N6150 */
+ MessageBuffer[3]=0;
+ MessageBuffer[4]=0;
+ MessageBuffer[5]=0x0c;
+ MessageBuffer[6]=0x01;
+ MessageBuffer[7]=0x2c;
+
+ /* Looking for end */
+ i=0;
+ while (true) {
+ if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
+ i=i+2;break;
+ }
+ if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
+ i=i+2;break;
+ }
+ i++;
+ if (i==MessageLength) break;
+ }
+
+ /* Copying frame */
+ memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
+
+ CurrentGetBinRingtone->length=i-3;
+
+ CurrentBinRingtoneError=GE_NONE;
+ break;
+ }
+
+ /* Copying frame */
+ memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
+
+ CurrentGetBinRingtone->length=MessageLength;
+
+#ifdef DEBUG
+ fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
+#endif
+ CurrentBinRingtoneError=GE_UNKNOWNMODEL;
+ break;
+
+ default:
+
+#ifdef DEBUG
+ fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
+#endif
+
+ CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
+ }
+}
+
+GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
+{
+ unsigned char req[] = { 0x00,0x01,0x9e,
+ 0x00 }; //location
+
+ GSM_Error error;
+
+ CurrentGetBinRingtone=ringtone;
+
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
+
+ req[3]=ringtone->location-1;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentBinRingtoneError, 4, 0x40, req);
+}
+
+void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[4]) {
+ case 0x00: /* location supported. We set ringtone */
+#ifdef DEBUG
+ fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
+#endif
+ CurrentBinRingtoneError=GE_NONE;
+ break;
+
+ default:
+#ifdef DEBUG
+ fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
+#endif
+ CurrentBinRingtoneError=GE_NOTSUPPORTED;
+ break;
+ }
+}
+
+GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
+{
+ unsigned char req[1000] = { 0x00,0x01,0xa0};
+
+ GSM_Error error;
+
+ GSM_BinRingtone ring;
+
+ /* Must be sure, that can upload ringtone to this phone */
+ ring.location=ringtone->location;
+ error=N6110_GetBinRingTone(&ring);
+ if (error!=GE_NONE) return error;
+
+ error=N6110_EnableExtendedCommands(0x01);
+ if (error!=GE_NONE) return error;
+
+ memcpy(req+3,ringtone->frame,ringtone->length);
+
+ req[3]=ringtone->location-1;
+
+ return NULL_SendMessageSequence
+ (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
+}
+
+GSM_Error N6110_Reset(unsigned char type)
+{
+ return N6110_EnableExtendedCommands(type);
+}
+
+void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int tmp, count;
+
+ switch (MessageBuffer[3]) {
+
+ /* Unknown message - it has been seen after the 0x07 message (call
+ answered). Probably it has similar meaning. If you can solve
+ this - just mail me. Pavel JanÃk ml.
+
+ The message looks like this:
+
+ Msg Destination: PC
+ Msg Source: Phone
+ Msg Type: 01
+ Msg Unknown: 00
+ Msg Len: 0e
+
+ Phone: [01 ][08 ][00 ] is the header of the frame
+
+ [03 ] is the call message subtype
+
+ [05 ] is the call sequence number
+
+ [05 ] unknown
+
+ [00 ][01 ][03 ][02 ][91][00] are unknown but has been
+ seen in the Incoming call message (just after the
+ caller's name from the phonebook). But never change
+ between phone calls :-(
+ */
+
+ /* This may mean sequence number of 'just made' call - CK */
+ case 0x02:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Call message, type 0x02:"));
+ fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
+#endif /* DEBUG */
+
+ break;
+
+ /* Possibly call OK */
+ /* JD: I think that this means "call in progress" (incomming or outgoing) */
+ case 0x03:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Call message, type 0x03:"));
+ fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
+ fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
+#endif /* DEBUG */
+
+ CurrentCallSequenceNumber=MessageBuffer[4];
+ CurrentIncomingCall[0]='D';
+ if (CurrentCallPassup) CurrentCallPassup('D');
+
+ break;
+
+ /* Remote end has gone away before you answer the call. Probably your
+ mother-in-law or banker (which is worse?) ... */
+ case 0x04:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Remote end hang up.\n"));
+ fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
+
+ switch (MessageBuffer[6]) {
+ case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
+ case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
+ case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
+ case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
+ case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
+ case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
+ }
+
+ fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
+ fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
+#endif /* DEBUG */
+
+ CurrentIncomingCall[0] = ' ';
+ if (CurrentCallPassup) CurrentCallPassup(' ');
+
+ break;
+
+ /* Incoming call alert */
+ case 0x05:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Incoming call alert:\n"));
+
+ /* We can have more then one call ringing - we can distinguish between
+ them */
+
+ fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
+ fprintf(stdout, _(" Number: "));
+
+ count=MessageBuffer[6];
+
+ for (tmp=0; tmp <count; tmp++)
+ fprintf(stdout, "%c", MessageBuffer[7+tmp]);
+
+ fprintf(stdout, "\n");
+
+ fprintf(stdout, _(" Name: "));
+
+ for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
+ fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
+
+ fprintf(stdout, "\n");
+#endif /* DEBUG */
+
+ count=MessageBuffer[6];
+
+ CurrentIncomingCall[0] = 0;
+ for (tmp=0; tmp <count; tmp++)
+ sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
+
+ break;
+
+ /* Call answered. Probably your girlfriend...*/
+ case 0x07:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Call answered.\n"));
+ fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
+#endif /* DEBUG */
+
+ break;
+
+ /* Call ended. Girlfriend is girlfriend, but time is money :-) */
+ case 0x09:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Call ended by your phone.\n"));
+ fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
+#endif /* DEBUG */
+
+ break;
+
+ /* This message has been seen with the message of subtype 0x09
+ after I hang the call.
+
+ Msg Destination: PC
+ Msg Source: Phone
+ Msg Type: 01
+ Msg Unknown: 00
+ Msg Len: 08
+ Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
+
+ What is the meaning of 87? Can you spell some magic light into
+ this issue?
+
+ */
+
+ /* Probably means call over - CK */
+ case 0x0a:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Call message, type 0x0a:"));
+ fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
+ fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
+#endif /* DEBUG */
+
+ CurrentIncomingCall[0] = ' ';
+ if (CurrentCallPassup) CurrentCallPassup(' ');
+
+ break;
+
+ case 0x40:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
+#endif
+
+ if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
+
+ if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
+
+ break;
+
+ default:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
+#endif /* DEBUG */
+ AppendLogText("Unknown msg\n",false);
+
+ break; /* Visual C Don't like empty cases */
+ }
+}
+
+void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int tmp, count;
+
+ switch (MessageBuffer[3]) {
+
+ case 0x04:
+
+ /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
+ /* If you want see, if it works with your phone make something like that: */
+
+ /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
+ /* Protocol->SendMessage(4, 0x04, connect5); */
+
+ /* Marcin-Wiacek@TopNet.PL */
+
+#ifdef WIN32
+ sprintf(Current_IMEI, "%s", MessageBuffer+5);
+ sprintf(Current_Model, "%s", MessageBuffer+21);
+ sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
+#else
+ snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
+ snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
+ snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
+#endif
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Mobile phone identification received:\n"));
+ fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
+ fprintf(stdout, _(" Model: %s\n"), Current_Model);
+ fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
+ fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
+ fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
+#endif /* DEBUG */
+
+ break;
+
+ /* Get group data */
+ /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
+ case 0x11:
+
+ if (CurrentGetBitmap!=NULL) {
+ if (CurrentGetBitmap->number==MessageBuffer[4]) {
+ count=MessageBuffer[5];
+ memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
+ CurrentGetBitmap->text[count]=0;
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Caller group datas\n"));
+ fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
+#endif /* DEBUG */
+
+ count+=6;
+
+ CurrentGetBitmap->ringtone=MessageBuffer[count++];
+#ifdef DEBUG
+ fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
+ if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
+ fprintf(stdout,_("\n"));
+#endif /* DEBUG */
+
+ CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
+#ifdef DEBUG
+ fprintf(stdout, _("Caller group logo "));
+ if (CurrentGetBitmap->enabled)
+ fprintf(stdout, _("enabled \n"));
+ else
+ fprintf(stdout, _("disabled \n"));
+#endif /* DEBUG */
+
+ CurrentGetBitmap->size=MessageBuffer[count++]<<8;
+ CurrentGetBitmap->size+=MessageBuffer[count++];
+#ifdef DEBUG
+ fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
+#endif /* DEBUG */
+
+ count++;
+ CurrentGetBitmap->width=MessageBuffer[count++];
+ CurrentGetBitmap->height=MessageBuffer[count++];
+ count++;
+ tmp=GSM_GetBitmapSize(CurrentGetBitmap);
+ if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
+ memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
+ CurrentGetBitmapError=GE_NONE;
+ } else {
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
+#endif
+ }
+ } else {
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
+#endif
+ }
+ break;
+
+ /* Get group data error */
+ case 0x12:
+
+ CurrentGetBitmapError=GE_UNKNOWN;
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
+#endif
+ break;
+
+ /* Set group data OK */
+ case 0x14:
+
+ CurrentSetBitmapError=GE_NONE;
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Caller group data set correctly.\n"));
+#endif
+ break;
+
+ /* Set group data error */
+ case 0x15:
+
+ CurrentSetBitmapError=GE_UNKNOWN;
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
+#endif
+ break;
+
+ default:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
+#endif /* DEBUG */
+ AppendLogText("Unknown msg\n",false);
+
+ break; /* Visual C Don't like empty cases */
+ }
+}
+
+void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int tmp, count, length;
+ bool issupported;
+
+#ifdef DEBUG
+ int i;
+#endif
+
+ switch (MessageBuffer[3]) {
+
+ /* Startup Logo */
+ case 0x17:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
+#endif
+
+ if (CurrentGetBitmap!=NULL) {
+
+ issupported=false;
+
+ count=5;
+
+ for (tmp=0;tmp<MessageBuffer[4];tmp++){
+ switch (MessageBuffer[count++]) {
+ case 0x01:
+ if (CurrentGetBitmap->type==GSM_StartupLogo) {
+ CurrentGetBitmap->height=MessageBuffer[count++];
+ CurrentGetBitmap->width=MessageBuffer[count++];
+ CurrentGetBitmap->size=GSM_GetBitmapSize(CurrentGetBitmap);
+ length=CurrentGetBitmap->size;
+ memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
+ } else {
+ //bitmap size
+ length=MessageBuffer[count++];
+ length=length*MessageBuffer[count++]/8;
+ }
+ count+=length;
+#ifdef DEBUG
+ fprintf(stdout, _("Startup logo supported - "));
+ if (length!=0) { fprintf(stdout, _("currently set\n")); }
+ else { fprintf(stdout, _("currently empty\n")); }
+#endif
+ if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
+ break;
+ case 0x02:
+ length=MessageBuffer[count];
+ if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
+ memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
+ CurrentGetBitmap->text[length]=0;
+ }
+#ifdef DEBUG
+ fprintf(stdout, _("Startup Text supported - "));
+ if (length!=0)
+ {
+ fprintf(stdout, _("currently set to \""));
+ for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
+ fprintf(stdout, _("\"\n"));
+ } else {
+ fprintf(stdout, _("currently empty\n"));
+ }
+#endif
+ count+=length+1;
+ if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
+ break;
+ case 0x03:
+ length=MessageBuffer[count];
+ if (CurrentGetBitmap->type==GSM_DealerNoteText) {
+ memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
+ CurrentGetBitmap->text[length]=0;
+ }
+#ifdef DEBUG
+ fprintf(stdout, _("Dealer Welcome supported - "));
+ if (length!=0)
+ {
+ fprintf(stdout, _("currently set to \""));
+ for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
+ fprintf(stdout, _("\"\n"));
+ } else {
+ fprintf(stdout, _("currently empty\n"));
+ }
+#endif
+ count+=length+1;
+ if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
+ break;
+ }
+ }
+ if (issupported) CurrentGetBitmapError=GE_NONE;
+ else CurrentGetBitmapError=GE_NOTSUPPORTED;
+ } else {
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
+#endif
+ }
+ break;
+
+ /* Set startup OK */
+ case 0x19:
+
+ CurrentSetBitmapError=GE_NONE;
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
+#endif
+ break;
+
+ /* Set Operator Logo OK */
+ case 0x31:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Operator logo correctly set.\n"));
+#endif
+
+ CurrentSetBitmapError=GE_NONE;
+ break;
+
+ /* Set Operator Logo Error */
+ case 0x32:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Error setting operator logo!\n"));
+#endif
+
+ CurrentSetBitmapError=GE_UNKNOWN;
+ break;
+
+ /* Operator Logo */
+ /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
+ case 0x34:
+
+ if (CurrentGetBitmap!=NULL) {
+
+ count=5; /* Location ignored. */
+
+ DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
+ count=count+3;
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
+ CurrentGetBitmap->netcode,
+ GSM_GetNetworkName(CurrentGetBitmap->netcode));
+#endif
+
+ CurrentGetBitmap->size=MessageBuffer[count++]<<8;
+ CurrentGetBitmap->size+=MessageBuffer[count++];
+ count++;
+ CurrentGetBitmap->width=MessageBuffer[count++];
+ CurrentGetBitmap->height=MessageBuffer[count++];
+ count++;
+ tmp=GSM_GetBitmapSize(CurrentGetBitmap);
+ if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
+ memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
+ CurrentGetBitmapError=GE_NONE;
+ } else {
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
+#endif
+ }
+
+ break;
+
+ /* Get op logo error */
+ case 0x35:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Error getting operator logo!\n"));
+#endif
+ CurrentGetBitmapError=GE_UNKNOWN;
+ break;
+
+ default:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
+#endif /* DEBUG */
+ AppendLogText("Unknown msg\n",false);
+
+ break;
+ }
+}
+
+void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int tmp;
+ unsigned char output[160];
+
+#ifdef DEBUG
+ int i;
+#endif
+
+ switch (MessageBuffer[3]) {
+
+ case 0x05:
+
+ /* MessageBuffer[3] = 0x05
+ MessageBuffer[4] = 0x00
+ MessageBuffer[5] = 0x0f
+ MessageBuffer[6] = 0x03
+ MessageBuffer[7] = length of packed message
+
+ This is all I have seen - Gerry Anderson */
+
+ tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
+
+#ifdef DEBUG
+
+ fprintf(stdout, _("Message from Network operator: "));
+
+ for (i=0; i<tmp; i++)
+ fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
+
+ fprintf(stdout, "\n");
+
+#endif /* DEBUG */
+
+ break;
+
+ default:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
+#endif /* DEBUG */
+ AppendLogText("Unknown msg\n",false);
+
+ break;
+ }
+}
+
+void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch (MessageBuffer[3]) {
+
+ case 0x80:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: SIM card login\n"));
+#endif
+ break;
+
+ case 0x81:
+#ifdef DEBUG
+ fprintf(stdout, _("Message: SIM card logout\n"));
+#endif
+ break;
+
+ default:
+#ifdef DEBUG
+ fprintf(stdout, _("Unknown message of type 0x09.\n"));
+#endif
+ AppendLogText("Unknown msg\n",false);
+ break;
+ }
+}
+
+void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ switch(MessageBuffer[3]) {
+
+ case 0x6a:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Calendar Alarm active\n"));
+ fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
+#endif /* DEBUG */
+
+ default:
+#ifdef DEBUG
+ fprintf(stdout, _("Unknown message of type 0x13.\n"));
+#endif
+ AppendLogText("Unknown msg\n",false);
+ break;
+ }
+}
+
+void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int i;
+
+ switch(MessageBuffer[2]) {
+
+ case 0x02:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
+#endif /* DEBUG */
+
+ CurrentMagicError=GE_NONE;
+ break;
+
+ case 0x7c:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Answer for call commands.\n"));
+#endif
+
+ CurrentDialVoiceError=GE_NONE;
+ break;
+
+ case 0x81:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
+#endif /* DEBUG */
+
+ CurrentMagicError=GE_NONE;
+ break;
+
+ case 0x82:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: ACK for simlock closing\n"));
+#endif /* DEBUG */
+
+ CurrentMagicError=GE_NONE;
+ break;
+
+ case 0xd4:
+
+ switch (MessageBuffer[5]) {
+ case 0xa0:
+#ifdef DEBUG
+ fprintf(stdout,_("Message: EEPROM contest received\n"));
+#endif
+
+ if (MessageBuffer[8]!=0x00) {
+ for (i=9;i<MessageLength;i++) {
+ fprintf(stdout,_("%c"), MessageBuffer[i]);
+ }
+
+ CurrentMagicError=GE_NONE;
+ }
+
+ break;
+ }
+
+#ifdef DEBUG
+ fprintf(stdout, _("Unknown message of type 0x40.\n"));
+#endif /* DEBUG */
+ AppendLogText("Unknown msg\n",false);
+ break;
+
+ case 0xcf:
+
+ N6110_DisplayTestsInfo(MessageBuffer);
+ break;
+
+ default:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Unknown message of type 0x40.\n"));
+#endif /* DEBUG */
+ AppendLogText("Unknown msg\n",false);
+ break; /* Visual C Don't like empty cases */
+ }
+}
+
+void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ int count;
+
+ switch(MessageBuffer[3]) {
+
+ case 0x02:
+
+ count=5;
+
+ if (MessageBuffer[5]!=0) {
+ strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
+
+ while (MessageBuffer[count]!=0) {
+ count++;
+ }
+
+ count++;
+ } else {
+ strcpy(CurrentGetBitmap->Sender,"\0");
+
+ count+=3;
+ }
+
+ memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
+ CurrentGetBitmap->text[MessageBuffer[count]]=0;
+
+ if (MessageBuffer[count]!=0)
+ count+=MessageBuffer[count];
+
+ count++;
+
+#ifdef DEBUG
+ fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
+#endif
+
+ CurrentGetBitmap->width=MessageBuffer[count+1];
+ CurrentGetBitmap->height=MessageBuffer[count+2];
+ CurrentGetBitmap->size=GSM_GetBitmapSize(CurrentGetBitmap);
+
+ memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
+
+ CurrentGetBitmapError=GE_NONE;
+ break;
+
+ case 0x04:
+
+#ifdef DEBUG
+ fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
+#endif
+ CurrentSetBitmapError=GE_NONE;
+ CurrentGetBitmapError=GE_NONE;
+ break;
+
+ case 0x05:
+
+#ifdef DEBUG
+ fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
+#endif
+ CurrentSetBitmapError=GE_UNKNOWN;
+ break;
+
+ case 0x06:
+
+#ifdef DEBUG
+ fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
+#endif
+ CurrentGetBitmapError=GE_UNKNOWN;
+ break;
+
+ default:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Unknown message of type 0x47.\n"));
+#endif /* DEBUG */
+ AppendLogText("Unknown msg\n",false);
+ break; /* Visual C Don't like empty cases */
+ }
+}
+
+void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+ char buffer[50];
+
+ sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
+ AppendLog(buffer,strlen(buffer),false);
+
+#ifdef DEBUG
+ fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
+ MessageBuffer[1]);
+#endif /* DEBUG */
+
+ CurrentLinkOK = true;
+}
+
+void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
+#endif /* DEBUG */
+
+}
+
+/* This function is used for parsing the RLP frame into fields. */
+void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
+{
+
+ RLP_F96Frame frame;
+ int count;
+ int valid = true;
+
+ /* We do not need RLP frame parsing to be done when we do not have callback
+ specified. */
+ if (CurrentRLP_RXCallback == NULL)
+ exit;
+
+ /* Anybody know the official meaning of the first two bytes?
+ Nokia 6150 sends junk frames starting D9 01, and real frames starting
+ D9 00. We'd drop the junk frames anyway because the FCS is bad, but
+ it's tidier to do it here. We still need to call the callback function
+ to give it a chance to handle timeouts and/or transmit a frame */
+ if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
+ valid = false;
+
+ /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
+ specification, so Header consists of 16 bits (2 bytes). See section 4.1
+ of the specification. */
+
+ frame.Header[0] = MessageBuffer[2];
+ frame.Header[1] = MessageBuffer[3];
+
+ /* Next 200 bits (25 bytes) contain the Information. We store the
+ information in the Data array. */
+
+ for (count = 0; count < 25; count ++)
+ frame.Data[count] = MessageBuffer[4 + count];
+
+ /* The last 24 bits (3 bytes) contain FCS. */
+
+ frame.FCS[0] = MessageBuffer[29];
+ frame.FCS[1] = MessageBuffer[30];
+ frame.FCS[2] = MessageBuffer[31];
+
+ /* Here we pass the frame down in the input stream. */
+ CurrentRLP_RXCallback(valid ? &frame : NULL);
+}
+
+void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
+#endif /* DEBUG */
+
+}
+
+void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ GSM_SMSMessage NullSMS;
+
+ switch (MessageBuffer[6]) {
+
+ case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
+ case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
+
+ /* Is it possible ? */
+ case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
+ default: NullSMS.Type = GST_UN; break;
+ }
+
+#ifdef DEBUG
+ if (NullSMS.Type == GST_DR)
+ fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
+ else
+ fprintf(stdout, _("Message: SMS Message Received\n"));
+#endif /* DEBUG */
+
+ GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
+
+#ifdef DEBUG
+ fprintf(stdout, _("\n"));
+#endif /* DEBUG */
+}
+
+void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
+
+ bool unknown=false;
+
+ /* Switch on the basis of the message type byte */
+ switch (MessageType) {
+
+ /* Call information */
+ case 0x01:
+
+ N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
+ break;
+
+ /* SMS handling */
+ case 0x02:
+ switch (MessageBuffer[3]) {
+ case 0x02:
+ case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
+ case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
+ case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
+ case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
+ case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
+ case 0x34:
+ case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
+ default :unknown=true;break;
+ }
+ break;
+
+ /* Phonebook handling */
+ case 0x03:
+ switch (MessageBuffer[3]) {
+ case 0x02:
+ case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
+ case 0x05:
+ case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
+ case 0x08:
+ case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
+ case 0x17:
+ case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
+ case 0x1a:
+ case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
+ default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
+ }
+ break;
+
+ /* Phone status */
+ case 0x04:
+ switch (MessageBuffer[3]) {
+ case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
+ default :unknown=true;break;
+ }
+ break;
+
+ /* Startup Logo, Operator Logo and Profiles. */
+ case 0x05:
+ switch (MessageBuffer[3]) {
+ case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
+ case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
+ case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
+ case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
+ case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
+ case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
+ default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
+ }
+ break;
+
+ /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
+ /* Call diverts */
+ case 0x06:
+ switch (MessageBuffer[3]) {
+ case 0x02:
+ case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
+ default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
+ }
+ break;
+
+ /* Security code requests */
+ case 0x08:
+ switch (MessageBuffer[3]) {
+ case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
+ case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
+ default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
+ }
+ break;
+
+ /* SIM login */
+ case 0x09:
+
+ N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
+ break;
+
+ /* Network info */
+ case 0x0a:
+ switch (MessageBuffer[3]) {
+ case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
+ default :unknown=true;break;
+ }
+ break;
+
+ /* Simulating key pressing */
+ case 0x0c:
+ switch (MessageBuffer[3]) {
+ case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
+ default :unknown=true;break;
+ }
+ break;
+
+ /* Display */
+ case 0x0d:
+ switch (MessageBuffer[3]) {
+ case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
+ case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
+ case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
+ default :unknown=true;break;
+ }
+ break;
+
+ /* Phone Clock and Alarm */
+ case 0x11:
+ switch (MessageBuffer[3]) {
+ case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
+ case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
+ case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
+ case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
+ default :unknown=true;break;
+ }
+ break;
+
+ /* Calendar notes handling */
+ case 0x13:
+ switch (MessageBuffer[3]) {
+ case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
+ case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
+ case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
+ default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
+ }
+ break;
+
+ /* SMS Messages */
+ case 0x14:
+ switch (MessageBuffer[3]) {
+ case 0x05:
+ case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
+ case 0x08:
+ case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
+ case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
+ case 0x37:
+ case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
+ default :unknown=true;break;
+ }
+ break;
+
+ /* WAP */
+ case 0x3f:
+ switch (MessageBuffer[3]) {
+ case 0x01:
+ case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
+ case 0x07:
+ case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
case 0x0a:
case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
case 0x16:
case 0x17:
case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
- default :unknown=true;break;\r
- }\r
- break;\r
-\r
- /* Internal phone functions? */\r
- case 0x40:\r
- switch (MessageBuffer[2]) {\r
- case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;\r
- case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;\r
- case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;\r
- case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;\r
- case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;\r
- default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;\r
- }\r
- break;\r
-\r
- /* Picture Images */\r
- case 0x47:\r
-\r
- N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);\r
- break;\r
-\r
- /* Mobile phone identification */\r
- case 0x64:\r
-\r
- N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);\r
- break;\r
-\r
- /***** Acknowlegment of our frames. *****/\r
- case FBUS_FRTYPE_ACK:\r
-\r
- N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);\r
- break;\r
-\r
- /***** Power on message. *****/\r
- case 0xd0:\r
-\r
- N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);\r
- break;\r
-\r
- case 0xd2:\r
-\r
- N6110_ReplyID(MessageLength, MessageBuffer, MessageType);\r
- break;\r
- \r
- /***** RLP frame received. *****/\r
- case 0xf1:\r
-\r
- N6110_RX_HandleRLPMessage(MessageBuffer);\r
- break;\r
-\r
- /***** Power on message. *****/\r
- case 0xf4:\r
-\r
- N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);\r
- break;\r
-\r
- /***** Unknown message *****/\r
- /* If you think that you know the exact meaning of other messages - please\r
- let us know. */\r
- default:\r
-\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Message: Unknown message type.\n"));\r
-#endif /* DEBUG */\r
- AppendLogText("Unknown msg type\n",false);\r
-\r
- unknown=false;\r
- break;\r
-\r
- }\r
-\r
- if (unknown) {\r
-#ifdef DEBUG\r
- fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);\r
-#endif\r
- AppendLogText("Unknown msg\n",false);\r
- }\r
-}\r
+ default :unknown=true;break;
+ }
+ break;
+
+ /* Internal phone functions? */
+ case 0x40:
+ switch (MessageBuffer[2]) {
+ case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
+ case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
+ case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
+ case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
+ case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
+ case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
+ case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
+ case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
+ case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
+ case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
+ case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
+ case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
+ case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
+ case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
+ default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
+ }
+ break;
+
+ /* Picture Images */
+ case 0x47:
+
+ N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
+ break;
+
+ /* Mobile phone identification */
+ case 0x64:
+
+ N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
+ break;
+
+ /***** Acknowlegment of our frames. *****/
+ case FBUS_FRTYPE_ACK:
+
+ N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
+ break;
+
+ /***** Power on message. *****/
+ case 0xd0:
+
+ N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
+ break;
+
+ case 0xd2:
+
+ N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
+ break;
+
+ /***** RLP frame received. *****/
+ case 0xf1:
+
+ N6110_RX_HandleRLPMessage(MessageBuffer);
+ break;
+
+ /***** Power on message. *****/
+ case 0xf4:
+
+ N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
+ break;
+
+ /***** Unknown message *****/
+ /* If you think that you know the exact meaning of other messages - please
+ let us know. */
+ default:
+
+#ifdef DEBUG
+ fprintf(stdout, _("Message: Unknown message type.\n"));
+#endif /* DEBUG */
+ AppendLogText("Unknown msg type\n",false);
+
+ unknown=false;
+ break;
+
+ }
+
+ if (unknown) {
+#ifdef DEBUG
+ fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
+#endif
+ AppendLogText("Unknown msg\n",false);
+ }
+}