5 A Linux/Unix toolset and driver for Nokia mobile phones.
7 Released under the terms of the GNU GPL, see file COPYING for more details.
9 This file provides an API for accessing functions on the 6110 and similar
16 /* "Turn on" prototypes in n-6110.h */
20 /* System header files */
26 #include "misc_win32.h"
29 /* Various header file */
35 #include "gsm-coding.h"
36 #include "newmodules/n6110.h"
37 #include "newmodules/n7110.h"
38 #include "protocol/fbus.h"
39 #include "devices/device.h"
40 /* Global variables used by code in gsm-api.c to expose the functions
41 supported by this model of phone. */
49 /* Here we initialise model specific functions. */
50 GSM_Functions N6110_Functions = {
52 N6110_DispatchMessage,
55 N6110_GetMemoryLocation,
56 N6110_WritePhonebookLocation,
64 N6110_GetMemoryStatus,
70 N6110_DeleteSMSMessage,
83 N6110_GetBatteryLevel,
86 N6110_GetDisplayStatus,
87 N6110_EnterSecurityCode,
88 N6110_GetSecurityCodeStatus,
89 N6110_GetSecurityCode,
114 N6110_GetIncomingCallNr,
115 N6110_GetNetworkInfo,
116 N6110_GetCalendarNote,
117 N6110_WriteCalendarNote,
118 N6110_DeleteCalendarNote,
124 N6110_SetBinRingTone,
125 N6110_GetBinRingTone,
153 N6110_EnableDisplayOutput,
154 N6110_DisableDisplayOutput,
155 N6110_EnableCellBroadcast,
156 N6110_DisableCellBroadcast,
157 N6110_ReadCellBroadcast,
159 N6110_GetProductProfileSetting,
160 N6110_SetProductProfileSetting,
161 N6110_GetOperatorName,
162 N6110_SetOperatorName,
163 N6110_GetVoiceMailbox, N6110_Tests,
165 UNIMPLEMENTED, //GetCalendarNotesInfo
167 N6110_ResetPhoneSettings,
168 N7110_GetWAPBookmark,
169 N7110_SetWAPBookmark,
170 N7110_GetWAPSettings,
187 NULL, //GetCalendarNotesInfo
196 N6110_GetManufacturer
199 /* Mobile phone information */
201 GSM_Information N6110_Information = {
202 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
203 /* Supported models in FBUS */
204 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
205 /* Supported models in MBUS */
206 "6110|6130|6150|8210|8850",
207 /* Supported models in FBUS over infrared */
209 /* Supported models in FBUS over DLR3 */
213 /* infrared sockets */
214 "6110|6130|6150|8210|8850",
215 /* Supported models in FBUS over infrared with Tekram device */
216 4, /* Max RF Level */
217 0, /* Min RF Level */
218 GRF_Arbitrary, /* RF level units */
219 4, /* Max Battery Level */
220 0, /* Min Battery Level */
221 GBU_Arbitrary, /* Battery level units */
222 GDT_DateTime, /* Have date/time support */
223 GDT_TimeOnly, /* Alarm supports time only */
224 1 /* Only one alarm available */
228 static const char *N6110_MemoryType_String [] = {
242 /* Magic bytes from the phone. */
243 static unsigned char MagicBytes[4] = { 0x00, 0x00, 0x00, 0x00 };
245 /* For DisplayOutput */
247 static char PhoneScreen[5+1][27+1];
248 static int OldX=1000,OldY=0,NewX=0,NewY=0;
251 void N6110_ReplyEnableExtendedCommands(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
254 fprintf(stdout, _("Message: Answer for EnableExtendedSecurityCommands frame, meaning not known :-(\n"));
257 CurrentEnableExtendedCommandsError=GE_NONE;
260 /* If you set make some things (for example,
261 change Security Code from phone's menu, disable and enable
262 phone), it won't answer for 0x40 frame - you won't be able
263 to play tones, get netmonitor, etc.
265 This function do thing called "Enabling extended security commands" -
266 it enables 0x40 frame functions.
268 This frame can also some other things - see below */
269 GSM_Error N6110_EnableExtendedCommands (unsigned char status)
271 unsigned char req[4] = { 0x00,
272 0x01,0x64, /* Enable extended commands request */
273 0x01 }; /* 0x01 - on, 0x00 - off,
274 0x03 & 0x04 - soft & hard reset,
275 0x06 - CONTACT SERVICE */
277 /* 0x06 MAKES CONTACT SERVICE! BE CAREFULL! */
278 /* When use 0x03 and had during session changed time & date
279 some phones (like 6150 or 6210) can ask for time & date after reset
280 or disable clock on the screen */
281 if (status!=0x06) req[3] = status;
283 return NULL_SendMessageSequence
284 (50, &CurrentEnableExtendedCommandsError, 4, 0x40, req);
287 void N6110_ReplyIMEI(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
289 #if defined WIN32 || !defined HAVE_SNPRINTF
290 sprintf(Current_IMEI, "%s", MessageBuffer+4);
292 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+4);
296 fprintf(stdout, _("Message: IMEI %s received\n"),Current_IMEI);
299 CurrentGetIMEIError=GE_NONE;
302 GSM_Error N6110_SendIMEIFrame()
304 unsigned char req[4] = {0x00, 0x01, 0x66, 0x00};
308 error=N6110_EnableExtendedCommands(0x01);
309 if (error!=GE_NONE) return error;
311 return NULL_SendMessageSequence (20, &CurrentGetIMEIError, 4, 0x40, req);
314 void N6110_ReplyHW(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
318 if (MessageBuffer[3]==0x05) {
321 fprintf(stdout,_("Message: Hardware version received: "));
324 j=strlen(Current_Revision);
325 Current_Revision[j++]=',';
326 Current_Revision[j++]=' ';
327 Current_Revision[j++]='H';
328 Current_Revision[j++]='W';
332 fprintf(stdout,_("%c"), MessageBuffer[i]);
334 Current_Revision[j++]=MessageBuffer[i];
338 fprintf(stdout,_("\n"));
341 CurrentGetHWError=GE_NONE;
345 GSM_Error N6110_SendHWFrame()
347 unsigned char req[4] = {0x00, 0x01, 0xc8, 0x05};
351 error=N6110_EnableExtendedCommands(0x01);
352 if (error!=GE_NONE) return error;
354 return NULL_SendMessageSequence (20, &CurrentGetHWError, 4, 0x40, req);
357 void N6110_ReplyID(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
362 fprintf(stdout, _("Message: Mobile phone model identification received:\n"));
363 fprintf(stdout, _(" Firmware: "));
366 strcpy(Current_Revision,"SW");
369 while (MessageBuffer[i]!=0x0a) {
370 Current_Revision[j]=MessageBuffer[i];
372 fprintf(stdout, _("%c"),MessageBuffer[i]);
374 if (j==GSM_MAX_REVISION_LENGTH-1) {
376 fprintf(stderr,_("ERROR: increase GSM_MAX_REVISION_LENGTH!\n"));
383 Current_Revision[j+1]=0;
386 fprintf(stdout, _("\n Firmware date: "));
390 while (MessageBuffer[i]!=0x0a) {
392 fprintf(stdout, _("%c"),MessageBuffer[i]);
398 fprintf(stdout, _("\n Model: "));
402 while (MessageBuffer[i]!=0x0a) {
403 Current_Model[j]=MessageBuffer[i];
405 fprintf(stdout, _("%c"),MessageBuffer[i]);
407 if (j==GSM_MAX_MODEL_LENGTH-1) {
409 fprintf(stderr,_("ERROR: increase GSM_MAX_MODEL_LENGTH!\n"));
416 Current_Model[j+1]=0;
419 fprintf(stdout, _("\n"));
422 CurrentMagicError=GE_NONE;
425 GSM_Error N6110_SendIDFrame()
427 unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
429 return NULL_SendMessageSequence (50, &CurrentMagicError, 5, 0xd1, req);
432 /* This function send the status request to the phone. */
433 /* Seems to be ignored in N3210 */
434 GSM_Error N6110_SendStatusRequest(void)
436 unsigned char req[] = {N6110_FRAME_HEADER, 0x01};
438 Protocol->SendMessage(4, 0x04, req);
443 static void N6110_ReplyGetAuthentication(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
445 #if defined WIN32 || !defined HAVE_SNPRINTF
446 sprintf(Current_IMEI, "%s", MessageBuffer+9);
447 sprintf(Current_Model, "%s", MessageBuffer+25);
448 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
450 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+9);
451 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+25);
452 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
456 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
457 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
458 fprintf(stdout, _(" Model: %s\n"), Current_Model);
459 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+31);
460 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+39);
461 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+44);
463 /* These bytes are probably the source of the "Accessory not connected"
464 messages on the phone when trying to emulate NCDS... I hope....
465 UPDATE: of course, now we have the authentication algorithm. */
466 fprintf(stdout, _(" Magic bytes: %02x %02x %02x %02x\n"), MessageBuffer[50], MessageBuffer[51], MessageBuffer[52], MessageBuffer[53]);
469 MagicBytes[0]=MessageBuffer[50];
470 MagicBytes[1]=MessageBuffer[51];
471 MagicBytes[2]=MessageBuffer[52];
472 MagicBytes[3]=MessageBuffer[53];
474 CurrentMagicError=GE_NONE;
477 /* This function provides Nokia authentication protocol.
479 This code is written specially for gnokii project by Odinokov Serge.
480 If you have some special requests for Serge just write him to
481 apskaita@post.omnitel.net or serge@takas.lt
483 Reimplemented in C by Pavel JanÃk ml.
485 Nokia authentication protocol is used in the communication between Nokia
486 mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software,
487 commercially sold by Nokia Corp.
489 The authentication scheme is based on the token send by the phone to the
490 software. The software does it's magic (see the function
491 FB61_GetNokiaAuth()) and returns the result back to the phone. If the
492 result is correct the phone responds with the message "Accessory
493 connected!" displayed on the LCD. Otherwise it will display "Accessory not
494 supported" and some functions will not be available for use.
496 The specification of the protocol is not publicly available, no comment. */
497 static void N6110_GetNokiaAuth(unsigned char *Imei, unsigned char *MagicBytes, unsigned char *MagicResponse)
502 /* This is our temporary working area. */
504 unsigned char Temp[16];
506 /* Here we put FAC (Final Assembly Code) and serial number into our area. */
517 /* And now the TAC (Type Approval Code). */
524 /* And now we pack magic bytes from the phone. */
526 Temp[12] = MagicBytes[0];
527 Temp[13] = MagicBytes[1];
528 Temp[14] = MagicBytes[2];
529 Temp[15] = MagicBytes[3];
531 for (i=0; i<=11; i++)
535 switch (Temp[15] & 0x03) {
542 Temp[i+j] ^= Temp[i+12];
550 Temp[i + j] |= Temp[i + 12];
553 for (i=0; i<=15; i++)
556 for (i=0; i<=15; i++) {
558 switch (Temp[15 - i] & 0x06) {
580 MagicResponse[i] = j;
585 static GSM_Error N6110_Authentication()
587 unsigned char connect1[] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x02};
588 unsigned char connect2[] = {N6110_FRAME_HEADER, 0x20, 0x02};
589 unsigned char connect3[] = {N6110_FRAME_HEADER, 0x0d, 0x01, 0x00, 0x02};
590 unsigned char connect4[] = {N6110_FRAME_HEADER, 0x10};
592 unsigned char magic_connect[] = {N6110_FRAME_HEADER,
595 /* The real magic goes here ... These bytes are filled in with the
596 function N6110_GetNokiaAuth(). */
598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 /* NOKIA&GNOKII Accessory */
603 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x26, 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x20,
604 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x79,
606 0x00, 0x00, 0x00, 0x00};
609 fprintf(stdout,_("Making authentication!\n"));
612 usleep(100); Protocol->SendMessage(7, 0x02, connect1);
613 usleep(100); Protocol->SendMessage(5, 0x02, connect2);
614 usleep(100); Protocol->SendMessage(7, 0x02, connect3);
616 CurrentMagicError = GE_BUSY;
618 usleep(100); Protocol->SendMessage(4, 0x64, connect4);
619 if (NULL_WaitUntil(50,&CurrentMagicError)!=GE_NONE) return GE_TIMEOUT;
621 N6110_GetNokiaAuth(Current_IMEI, MagicBytes, magic_connect+4);
623 Protocol->SendMessage(45, 0x64, magic_connect);
626 fprintf(stdout,_("End of authentication!\n"));
632 /* Initialise variables and state machine. */
633 GSM_Error N6110_Initialise(char *port_device, char *initlength,
634 GSM_ConnectionType connection,
635 void (*rlp_callback)(RLP_F96Frame *frame))
637 unsigned char init_char = N6110_SYNC_BYTE;
639 unsigned char end_init_char = N6110_IR_END_SYNC_BYTE;
645 if (Protocol->Initialise(port_device,initlength,connection,rlp_callback)!=GE_NONE)
647 return GE_NOTSUPPORTED;
650 switch (CurrentConnectionType) {
654 /* We don't think about authentication in Irda, because
655 AFAIK there are no phones working over sockets
656 and having authentication. In MBUS it doesn't work */
659 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
661 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
663 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
665 CurrentLinkOK = true;
674 InitLength = atoi(initlength);
676 if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
677 InitLength = 250; /* This is the usual value, lower may work. */
681 if (CurrentConnectionType==GCT_Infrared ||
682 CurrentConnectionType==GCT_Tekram) {
684 fprintf(stdout,_("Setting infrared for FBUS communication...\n"));
686 device_changespeed(9600);
691 fprintf(stdout,_("Writing init chars...."));
694 /* Initialise link with phone or what have you */
695 /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
697 for (count = 0; count < InitLength; count ++) {
699 if (CurrentConnectionType!=GCT_Infrared &&
700 CurrentConnectionType!=GCT_Tekram)
703 Protocol->WritePhone(1,&init_char);
707 if (CurrentConnectionType==GCT_Infrared ||
708 CurrentConnectionType==GCT_Tekram) {
709 Protocol->WritePhone(1,&end_init_char);
715 fprintf(stdout,_("Done\n"));
719 if (CurrentConnectionType==GCT_Infrared ||
720 CurrentConnectionType==GCT_Tekram) {
721 device_changespeed(115200);
725 N6110_SendStatusRequest();
729 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
731 /* N51xx/61xx have something called authentication.
732 After making it phone display "Accessory connected"
733 and probably give access to some function (I'm not too sure about it !)
734 Anyway, I make it now for N51xx/61xx */
735 if (GetModelFeature (FN_AUTHENTICATION)!=0) {
736 if (N6110_Authentication()!=GE_NONE) return GE_TIMEOUT;
737 } else { /* No authentication */
738 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
740 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
746 fprintf(stdout,_("Unknown connection type in n6110.c!\n"));
754 /* This function translates GMT_MemoryType to N6110_MEMORY_xx */
755 int N6110_GetMemoryType(GSM_MemoryType memory_type)
760 switch (memory_type) {
762 case GMT_MT: result = N6110_MEMORY_MT; break;
763 case GMT_ME: result = N6110_MEMORY_ME; break;
764 case GMT_SM: result = N6110_MEMORY_SM; break;
765 case GMT_FD: result = N6110_MEMORY_FD; break;
766 case GMT_ON: result = N6110_MEMORY_ON; break;
767 case GMT_EN: result = N6110_MEMORY_EN; break;
768 case GMT_DC: result = N6110_MEMORY_DC; break;
769 case GMT_RC: result = N6110_MEMORY_RC; break;
770 case GMT_MC: result = N6110_MEMORY_MC; break;
771 default : result = N6110_MEMORY_XX;
780 void N6110_ReplyCallDivert(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
782 switch (MessageBuffer[3]) {
787 fprintf(stdout, _("Message: Call divert status received\n"));
788 fprintf(stdout, _(" Divert type: "));
789 switch (MessageBuffer[6]) {
790 case 0x43: fprintf(stdout, _("when busy"));break;
791 case 0x3d: fprintf(stdout, _("when not answered"));break;
792 case 0x3e: fprintf(stdout, _("when phone off or no coverage"));break;
793 case 0x15: fprintf(stdout, _("all types of diverts"));break; //?
794 case 0x02: fprintf(stdout, _("all types of diverts"));break; //?
795 default: fprintf(stdout, _("unknown %i"),MessageBuffer[6]);break;
797 fprintf(stdout, _("\n Calls type : "));
798 if (MessageBuffer[6]==0x02)
799 fprintf(stdout, _("voice, fax & data")); //?
801 switch (MessageBuffer[8]) {
802 case 0x0b: fprintf(stdout, _("voice"));break;
803 case 0x0d: fprintf(stdout, _("fax"));break;
804 case 0x19: fprintf(stdout, _("data"));break;
805 default: fprintf(stdout, _("unknown %i"),MessageBuffer[8]);break;
808 fprintf(stdout, _("\n"));
809 if (MessageBuffer[10]==0x01) {
810 fprintf(stdout, _(" Status : active\n"));
811 fprintf(stdout, _(" Timeout : %i seconds\n"),MessageBuffer[45]);
812 fprintf(stdout, _(" Number : %s\n"),GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
814 fprintf(stdout, _(" Status : deactivated\n"));
818 switch (MessageBuffer[6]) {
819 case 0x43: CurrentCallDivert->DType=GSM_CDV_Busy;break;
820 case 0x3d: CurrentCallDivert->DType=GSM_CDV_NoAnswer;break;
821 case 0x3e: CurrentCallDivert->DType=GSM_CDV_OutOfReach;break;
822 case 0x15: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
823 case 0x02: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
826 if (MessageBuffer[6]==0x02) //?
827 CurrentCallDivert->CType=GSM_CDV_AllCalls;
829 switch (MessageBuffer[8]) {
830 case 0x0b: CurrentCallDivert->CType=GSM_CDV_VoiceCalls;break;
831 case 0x0d: CurrentCallDivert->CType=GSM_CDV_FaxCalls; break;
832 case 0x19: CurrentCallDivert->CType=GSM_CDV_DataCalls; break;
836 if (MessageBuffer[10]==0x01) {
837 CurrentCallDivert->Enabled=true;
838 CurrentCallDivert->Timeout=MessageBuffer[45];
839 strcpy(CurrentCallDivert->Number,GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
841 CurrentCallDivert->Enabled=false;
844 CurrentCallDivertError=GE_NONE;
849 fprintf(stdout, _("Message: Call divert status receiving error ?\n"));
851 CurrentCallDivertError=GE_UNKNOWN;
856 GSM_Error N6110_CallDivert(GSM_CallDivert *cd)
858 char req[55] = { N6110_FRAME_HEADER, 0x01,
859 0x00, /* operation */
861 0x00, /* divert type */
862 0x00, /* call type */
868 switch (cd->Operation) {
869 case GSM_CDV_Register:
873 req[29]= GSM_PackSemiOctetNumber(cd->Number, req + 9, false);
874 req[52]= cd->Timeout;
877 case GSM_CDV_Erasure:
878 case GSM_CDV_Disable:
885 return GE_NOTIMPLEMENTED;
889 case GSM_CDV_AllTypes : req[6] = 0x15; break;
890 case GSM_CDV_Busy : req[6] = 0x43; break;
891 case GSM_CDV_NoAnswer : req[6] = 0x3d; break;
892 case GSM_CDV_OutOfReach: req[6] = 0x3e; break;
893 default: return GE_NOTIMPLEMENTED;
896 if ((cd->DType == GSM_CDV_AllTypes) &&
897 (cd->CType == GSM_CDV_AllCalls))
901 case GSM_CDV_AllCalls : break;
902 case GSM_CDV_VoiceCalls: req[7] = 0x0b; break;
903 case GSM_CDV_FaxCalls : req[7] = 0x0d; break;
904 case GSM_CDV_DataCalls : req[7] = 0x19; break;
905 default: return GE_NOTIMPLEMENTED;
908 CurrentCallDivert = cd;
910 error=NULL_SendMessageSequence
911 (100, &CurrentCallDivertError, length, 0x06, req);
913 CurrentCallDivert = NULL;
918 GSM_Error N6110_Tests()
920 unsigned char buffer[3]={0x00,0x01,0xcf};
921 unsigned char buffer3[8]={0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00};
925 error=N6110_EnableExtendedCommands(0x01);
926 if (error!=GE_NONE) return error;
928 //make almost all tests
929 Protocol->SendMessage(8, 0x40, buffer3);
931 while (GSM->Initialise(PortDevice, "50", CurrentConnectionType, CurrentRLP_RXCallback)!=GE_NONE) {};
935 return NULL_SendMessageSequence
936 (200, &CurrentNetworkInfoError, 3, 0x40, buffer);
939 void N6110_DisplayTestsInfo(u8 *MessageBuffer) {
943 CurrentNetworkInfoError=GE_NONE;
945 for (i=0;i<MessageBuffer[3];i++) {
947 case 0: fprintf(stdout,_("Unknown(%i) "),i);break;
948 case 1: fprintf(stdout,_("MCU ROM checksum "));break;
949 case 2: fprintf(stdout,_("MCU RAM interface "));break;
950 case 3: fprintf(stdout,_("MCU RAM component "));break;
951 case 4: fprintf(stdout,_("MCU EEPROM interface "));break;
952 case 5: fprintf(stdout,_("MCU EEPROM component "));break;
953 case 6: fprintf(stdout,_("Real Time Clock battery "));break;
954 case 7: fprintf(stdout,_("CCONT interface "));break;
955 case 8: fprintf(stdout,_("AD converter "));break;
956 case 9: fprintf(stdout,_("SW Reset "));break;
957 case 10:fprintf(stdout,_("Power Off "));break;
958 case 11:fprintf(stdout,_("Security Data "));break;
959 case 12:fprintf(stdout,_("EEPROM Tune checksum "));break;
960 case 13:fprintf(stdout,_("PPM checksum "));break;
961 case 14:fprintf(stdout,_("MCU download DSP "));break;
962 case 15:fprintf(stdout,_("DSP alive "));break;
963 case 16:fprintf(stdout,_("COBBA serial "));break;
964 case 17:fprintf(stdout,_("COBBA paraller "));break;
965 case 18:fprintf(stdout,_("EEPROM security checksum"));break;
966 case 19:fprintf(stdout,_("PPM validity "));break;
967 case 20:fprintf(stdout,_("Warranty state "));break;
968 case 21:fprintf(stdout,_("Simlock check "));break;
969 case 22:fprintf(stdout,_("IMEI check? "));break;//from PC-Locals.is OK?
970 default:fprintf(stdout,_("Unknown(%i) "),i);break;
972 switch (MessageBuffer[4+i]) {
973 case 0: fprintf(stdout,_(" : done, result OK"));break;
974 case 0xff:fprintf(stdout,_(" : not done, result unknown"));break;
975 case 254: fprintf(stdout,_(" : done, result NOT OK"));break;
976 default: fprintf(stdout,_(" : result unknown(%i)"),MessageBuffer[4+i]);break;
978 fprintf(stdout,_("\n"));
982 void N6110_ReplySimlockInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
989 fprintf(stdout, _("Message: Simlock info received\n"));
992 for (i=0; i < 12; i++)
995 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] >> 4)));
998 if (j==5 || j==15) fprintf(stdout, _("\n"));
1001 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] & 0x0f)));
1005 if (j==20 || j==24) fprintf(stdout, _("\n"));
1008 if ((MessageBuffer[6] & 1) == 1) fprintf(stdout,_("lock 1 closed\n"));
1009 if ((MessageBuffer[6] & 2) == 2) fprintf(stdout,_("lock 2 closed\n"));
1010 if ((MessageBuffer[6] & 4) == 4) fprintf(stdout,_("lock 3 closed\n"));
1011 if ((MessageBuffer[6] & 8) == 8) fprintf(stdout,_("lock 4 closed\n"));
1013 /* I'm not sure here at all */
1014 if ((MessageBuffer[5] & 1) == 1) fprintf(stdout,_("lock 1 - user\n"));
1015 if ((MessageBuffer[5] & 2) == 2) fprintf(stdout,_("lock 2 - user\n"));
1016 if ((MessageBuffer[5] & 4) == 4) fprintf(stdout,_("lock 3 - user\n"));
1017 if ((MessageBuffer[5] & 8) == 8) fprintf(stdout,_("lock 4 - user\n"));
1019 fprintf(stdout,_("counter for lock1: %i\n"),MessageBuffer[21]);
1020 fprintf(stdout,_("counter for lock2: %i\n"),MessageBuffer[22]);
1021 fprintf(stdout,_("counter for lock3: %i\n"),MessageBuffer[23]);
1022 fprintf(stdout,_("counter for lock4: %i\n"),MessageBuffer[24]);
1027 for (i=0; i < 12; i++)
1030 uni[j]='0' + (MessageBuffer[9+i] >> 4);
1035 uni[j]='0' + (MessageBuffer[9+i] & 0x0f);
1041 strncpy(CurrentSimLock->simlocks[0].data,uni,5);
1042 CurrentSimLock->simlocks[0].data[5]=0;
1043 strncpy(CurrentSimLock->simlocks[3].data,uni+5,10);
1044 CurrentSimLock->simlocks[3].data[10]=0;
1045 strncpy(CurrentSimLock->simlocks[1].data,uni+16,4);
1046 CurrentSimLock->simlocks[1].data[4]=0;
1047 strncpy(CurrentSimLock->simlocks[2].data,uni+20,4);
1048 CurrentSimLock->simlocks[2].data[4]=0;
1050 CurrentSimLock->simlocks[0].enabled=((MessageBuffer[6] & 1) == 1);
1051 CurrentSimLock->simlocks[1].enabled=((MessageBuffer[6] & 2) == 2);
1052 CurrentSimLock->simlocks[2].enabled=((MessageBuffer[6] & 4) == 4);
1053 CurrentSimLock->simlocks[3].enabled=((MessageBuffer[6] & 8) == 8);
1055 CurrentSimLock->simlocks[0].factory=((MessageBuffer[5] & 1) != 1);
1056 CurrentSimLock->simlocks[1].factory=((MessageBuffer[5] & 2) != 2);
1057 CurrentSimLock->simlocks[2].factory=((MessageBuffer[5] & 4) != 4);
1058 CurrentSimLock->simlocks[3].factory=((MessageBuffer[5] & 8) != 8);
1060 CurrentSimLock->simlocks[0].counter=MessageBuffer[21];
1061 CurrentSimLock->simlocks[1].counter=MessageBuffer[22];
1062 CurrentSimLock->simlocks[2].counter=MessageBuffer[23];
1063 CurrentSimLock->simlocks[3].counter=MessageBuffer[24];
1065 CurrentSimlockInfoError=GE_NONE;
1068 GSM_Error N6110_SimlockInfo(GSM_AllSimlocks *siml)
1071 unsigned char req[] = {0x00,0x01,0x8a,0x00};
1072 error=N6110_EnableExtendedCommands(0x01);
1073 if (error!=GE_NONE) return error;
1075 CurrentSimLock=siml;
1077 return NULL_SendMessageSequence (50, &CurrentSimlockInfoError, 4, 0x40, req);
1080 void N6110_ReplyResetPhoneSettings(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1083 fprintf(stdout, _("Message: Resetting phone settings\n"));
1086 CurrentResetPhoneSettingsError=GE_NONE;
1089 GSM_Error N6110_ResetPhoneSettings()
1092 unsigned char req[] = {0x00,0x01,0x65,0x08,0x00};
1093 error=N6110_EnableExtendedCommands(0x01);
1094 if (error!=GE_NONE) return error;
1096 return NULL_SendMessageSequence
1097 (50, &CurrentResetPhoneSettingsError, 5, 0x40, req);
1100 #endif /* UCLINUX */
1102 GSM_Error N6110_GetManufacturer(char *manufacturer)
1104 strcpy (manufacturer, "Nokia");
1110 GSM_Error N6110_GetVoiceMailbox ( GSM_PhonebookEntry *entry)
1112 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
1116 CurrentPhonebookEntry = entry;
1118 req[4] = N6110_MEMORY_VOICE;
1119 req[5] = 0x00; /* Location - isn't important, but... */
1121 error=NULL_SendMessageSequence
1122 (20, &CurrentPhonebookError, 7, 0x03, req);
1124 CurrentPhonebookEntry = NULL;
1129 void N6110_ReplyGetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1133 GSM_Bitmap NullBitmap;
1135 DecodeNetworkCode(MessageBuffer+5, NullBitmap.netcode);
1140 fprintf(stdout, _("Message: Info about downloaded operator name received: %s network (for gnokii \"%s\", for phone \""),
1142 GSM_GetNetworkName(NullBitmap.netcode));
1146 while (MessageBuffer[count]!=0) {
1148 fprintf(stdout,_("%c"),MessageBuffer[count]);
1153 strcpy(CurrentGetOperatorNameNetwork->Code, NullBitmap.netcode);
1154 strncpy(CurrentGetOperatorNameNetwork->Name, MessageBuffer+i,count-i+1);
1157 fprintf(stdout,_("\")\n"));
1160 CurrentGetOperatorNameError=GE_NONE;
1163 GSM_Error N6110_GetOperatorName (GSM_Network *operator)
1165 unsigned char req[] = { 0x00,0x01,0x8c,0x00};
1169 error=N6110_EnableExtendedCommands(0x01);
1170 if (error!=GE_NONE) return error;
1172 CurrentGetOperatorNameNetwork = operator;
1174 error=NULL_SendMessageSequence
1175 (20, &CurrentGetOperatorNameError, 4, 0x40, req);
1177 CurrentGetOperatorNameNetwork = NULL;
1182 void N6110_ReplySetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1185 fprintf(stdout, _("Message: Downloaded operator name changed\n"));
1188 CurrentSetOperatorNameError=GE_NONE;
1191 GSM_Error N6110_SetOperatorName (GSM_Network *operator)
1193 unsigned char req[256] = { 0x00,0x01,0x8b,0x00,
1194 0x00,0x00, /* MCC */
1199 error=N6110_EnableExtendedCommands(0x01);
1200 if (error!=GE_NONE) return error;
1202 EncodeNetworkCode(req+4,operator->Code);
1204 strncpy(req+7,operator->Name,200);
1206 return NULL_SendMessageSequence
1207 (20, &CurrentSetOperatorNameError, 8+strlen(operator->Name), 0x40, req);
1210 #endif /* UCLINUX */
1212 static void N6110_ReplyGetMemoryStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1214 switch (MessageBuffer[3]) {
1219 fprintf(stdout, _("Message: Memory status received:\n"));
1221 fprintf(stdout, _(" Memory Type: %s\n"), N6110_MemoryType_String[MessageBuffer[4]]);
1222 fprintf(stdout, _(" Used: %d\n"), MessageBuffer[6]);
1223 fprintf(stdout, _(" Free: %d\n"), MessageBuffer[5]);
1226 CurrentMemoryStatus->Used = MessageBuffer[6];
1227 CurrentMemoryStatus->Free = MessageBuffer[5];
1228 CurrentMemoryStatusError = GE_NONE;
1235 switch (MessageBuffer[4]) {
1237 fprintf(stdout, _("Message: Memory status error, phone is probably powered off.\n"));break;
1239 fprintf(stdout, _("Message: Memory status error, memory type not supported by phone model.\n"));break;
1241 fprintf(stdout, _("Message: Memory status error, waiting for security code.\n"));break;
1243 fprintf(stdout, _("Message: Unknown Memory status error, subtype (MessageBuffer[4]) = %02x\n"),MessageBuffer[4]);break;
1247 switch (MessageBuffer[4]) {
1248 case 0x6f:CurrentMemoryStatusError = GE_TIMEOUT;break;
1249 case 0x7d:CurrentMemoryStatusError = GE_INTERNALERROR;break;
1250 case 0x8d:CurrentMemoryStatusError = GE_INVALIDSECURITYCODE;break;
1259 /* This function is used to get storage status from the phone. It currently
1260 supports two different memory areas - internal and SIM. */
1261 GSM_Error N6110_GetMemoryStatus(GSM_MemoryStatus *Status)
1263 unsigned char req[] = { N6110_FRAME_HEADER,
1264 0x07, /* MemoryStatus request */
1265 0x00 /* MemoryType */
1270 CurrentMemoryStatus = Status;
1272 req[4] = N6110_GetMemoryType(Status->MemoryType);
1274 error=NULL_SendMessageSequence
1275 (20, &CurrentMemoryStatusError, 5, 0x03, req);
1277 CurrentMemoryStatus = NULL;
1284 void N6110_ReplyGetNetworkInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1286 GSM_NetworkInfo NullNetworkInfo;
1288 /* Make sure we are expecting NetworkInfo frame */
1289 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY) {
1291 fprintf(stdout, _("Message: Network informations:\n"));
1295 fprintf(stdout, _("Message: Network informations not requested, but received:\n"));
1299 sprintf(NullNetworkInfo.NetworkCode, "%x%x%x %x%x", MessageBuffer[14] & 0x0f, MessageBuffer[14] >>4, MessageBuffer[15] & 0x0f, MessageBuffer[16] & 0x0f, MessageBuffer[16] >>4);
1301 sprintf(NullNetworkInfo.CellID, "%02x%02x", MessageBuffer[10], MessageBuffer[11]);
1303 sprintf(NullNetworkInfo.LAC, "%02x%02x", MessageBuffer[12], MessageBuffer[13]);
1306 fprintf(stdout, _(" CellID: %s\n"), NullNetworkInfo.CellID);
1307 fprintf(stdout, _(" LAC: %s\n"), NullNetworkInfo.LAC);
1308 fprintf(stdout, _(" Network code: %s\n"), NullNetworkInfo.NetworkCode);
1309 fprintf(stdout, _(" Network name: %s (%s)\n"),
1310 GSM_GetNetworkName(NullNetworkInfo.NetworkCode),
1311 GSM_GetCountryName(NullNetworkInfo.NetworkCode));
1312 fprintf(stdout, _(" Status: "));
1314 switch (MessageBuffer[8]) {
1315 case 0x01: fprintf(stdout, _("home network selected")); break;
1316 case 0x02: fprintf(stdout, _("roaming network")); break;
1317 case 0x03: fprintf(stdout, _("requesting network")); break;
1318 case 0x04: fprintf(stdout, _("not registered in the network")); break;
1319 default: fprintf(stdout, _("unknown"));
1322 fprintf(stdout, "\n");
1324 fprintf(stdout, _(" Network selection: %s\n"), MessageBuffer[9]==1?_("manual"):_("automatic"));
1327 /* Make sure we are expecting NetworkInfo frame */
1328 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY)
1329 *CurrentNetworkInfo=NullNetworkInfo;
1331 CurrentNetworkInfoError = GE_NONE;
1334 GSM_Error N6110_GetNetworkInfo(GSM_NetworkInfo *NetworkInfo)
1336 unsigned char req[] = { N6110_FRAME_HEADER,
1342 CurrentNetworkInfo = NetworkInfo;
1344 error=NULL_SendMessageSequence
1345 (20, &CurrentNetworkInfoError, 4, 0x0a, req);
1347 CurrentNetworkInfo = NULL;
1352 void N6110_ReplyGetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1357 fprintf(stdout, _("Message: Product Profile Settings received -"));
1358 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),MessageBuffer[3+i]);
1359 fprintf(stdout, _("\n"));
1362 for (i=0;i<4;i++) CurrentPPS[i]=MessageBuffer[3+i];
1364 CurrentProductProfileSettingsError=GE_NONE;
1367 GSM_Error N6110_GetProductProfileSetting (GSM_PPS *PPS)
1369 unsigned char req[] = { 0x00, 0x01,0x6a };
1375 error=N6110_EnableExtendedCommands(0x01);
1376 if (error!=GE_NONE) return error;
1378 error=NULL_SendMessageSequence
1379 (20, &CurrentProductProfileSettingsError, 3, 0x40, req);
1380 if (error!=GE_NONE) return error;
1382 switch (PPS->Name) {
1383 case PPS_ALS : PPS->bool_value=(CurrentPPS[1]&32); break;
1384 case PPS_GamesMenu: PPS->bool_value=(CurrentPPS[3]&64); break;
1385 case PPS_HRData : PPS->bool_value=(CurrentPPS[0]&64); break;
1386 case PPS_14400Data: PPS->bool_value=(CurrentPPS[0]&128);break;
1387 case PPS_EFR : PPS->int_value =(CurrentPPS[0]&1) +(CurrentPPS[0]&2); break;
1388 case PPS_FR : PPS->int_value =(CurrentPPS[0]&16)/16+(CurrentPPS[0]&32)/16;break;
1389 case PPS_HR : PPS->int_value =(CurrentPPS[0]&4)/4 +(CurrentPPS[0]&8)/4; break;
1390 case PPS_VibraMenu: PPS->bool_value=(CurrentPPS[4]&64); break;
1391 case PPS_LCDContrast:
1395 if (CurrentPPS[3]&j) PPS->int_value=PPS->int_value+j;
1398 PPS->int_value=PPS->int_value*100/32;
1406 void N6110_ReplySetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1411 fprintf(stdout, _("Message: Product Profile Settings set to"));
1412 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),CurrentPPS[i]);
1413 fprintf(stdout, _("\n"));
1416 CurrentProductProfileSettingsError=GE_NONE;
1419 GSM_Error N6110_SetProductProfileSetting (GSM_PPS *PPS)
1421 unsigned char req[] = { 0x00, 0x01,0x6b,
1422 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */
1423 unsigned char settings[32];
1431 error=N6110_EnableExtendedCommands(0x01);
1432 if (error!=GE_NONE) return error;
1434 OldPPS.Name=PPS_ALS;
1435 error=N6110_GetProductProfileSetting(&OldPPS);
1436 if (error!=GE_NONE) return error;
1439 for (i=0;i<32;i++) {
1440 if (CurrentPPS[z]&j)
1451 fprintf(stdout,_("Current settings: "));
1452 for (i=0;i<32;i++) {
1453 fprintf(stdout,_("%c"),settings[i]);
1455 fprintf(stdout,_("\n"));
1458 switch (PPS->Name) {
1459 case PPS_ALS :settings[10]=PPS->bool_value?'1':'0';break;
1460 case PPS_HRData :settings[ 5]=PPS->bool_value?'1':'0';break;
1461 case PPS_14400Data:settings[ 6]=PPS->bool_value?'1':'0';break;
1466 for (i=0;i<32;i++) {
1467 if (settings[i]=='1') req[z+3]=req[z+3]+j;
1475 fprintf(stdout,_("Current settings: "));
1477 fprintf(stdout,_("%i "),req[i+3]);
1479 fprintf(stdout,_("\n"));
1483 CurrentPPS[i]=req[i+3];
1486 return NULL_SendMessageSequence
1487 (20, &CurrentProductProfileSettingsError, 7, 0x40, req);
1490 void N6110_ReplyPressKey(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1492 if (MessageBuffer[4]==CurrentPressKeyEvent) CurrentPressKeyError=GE_NONE;
1493 else CurrentPressKeyError=GE_UNKNOWN; /* MessageBuffer[4] = 0x05 */
1495 fprintf(stdout, _("Message: Result of key "));
1496 switch (MessageBuffer[4])
1498 case PRESSPHONEKEY: fprintf(stdout, _("press OK\n"));break;
1499 case RELEASEPHONEKEY: fprintf(stdout, _("release OK\n"));break;
1500 default: fprintf(stdout, _("press or release - error\n"));break;
1505 GSM_Error N6110_PressKey(int key, int event)
1507 unsigned char req[] = {N6110_FRAME_HEADER, 0x42, 0x01, 0x00, 0x01};
1509 req[4]=event; /* if we press or release key */
1512 CurrentPressKeyEvent=event;
1514 return NULL_SendMessageSequence
1515 (10, &CurrentPressKeyError, 7, 0x0c, req);
1518 void N6110_ReplyDisplayOutput(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1520 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
1527 switch(MessageBuffer[3]) {
1529 /* Phone sends displayed texts */
1531 NewX=MessageBuffer[6];
1532 NewY=MessageBuffer[5];
1534 DecodeUnicode (uni, MessageBuffer+8, MessageBuffer[7]);
1537 fprintf(stdout, _("New displayed text (%i %i): \"%s\"\n"),NewX,NewY,uni);
1540 while (N6110_GetModel(model) != GE_NONE)
1543 /* With these rules it works almost excellent with my N5110 */
1544 /* I don't have general rule :-(, that's why you must experiment */
1545 /* with your phone. Nokia could make it better. MW */
1546 /* It's almost OK for N5110*/
1547 /* FIX ME: it will be the same for N5130 and 3210 too*/
1548 if (!strcmp(model,"NSE-1"))
1550 /* OldX==1000 means - it's first time */
1554 for (i=0;i<5+1;i++) {
1555 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1560 if ((OldX==0 && OldY==31 && NewX==29 && NewY==46) ||
1561 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1562 /* Clean the line with current text */
1563 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1565 /* Inserts text into table */
1566 for (i=0; i<MessageBuffer[7];i++) {
1567 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1572 if ((OldX==0 && OldY==21 && NewX==0 && NewY==10) ||
1573 (OldX==0 && OldY==10 && NewX==35 && NewY==46)) {
1575 if ((OldX!=0 && NewX==0 && NewY!=6) ||
1576 (OldX==0 && NewX!=0 && OldY!=13 && OldY!=22) ||
1577 (OldX==0 && NewX==0 && NewY<OldY && (NewY!=13 || OldY!=26)) ||
1578 (OldY==5 && NewY!=5) ||
1579 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1581 /* Writes "old" screen */
1582 for (i=0;i<5+1;i++) {
1583 for (j=0;j<27+1;j++) {fprintf(stdout,_("%c"),PhoneScreen[i][j]);}
1584 fprintf(stdout,_("\n"));
1588 for (i=0;i<5+1;i++) {
1589 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1594 /* Clean the line with current text */
1595 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1597 /* Inserts text into table */
1598 for (i=0; i<MessageBuffer[7];i++) {
1599 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1606 fprintf(stdout, _("%s\n"),uni);
1614 if (MessageBuffer[4]==1)
1618 fprintf(stdout, _("Display output successfully disabled/enabled.\n"));
1621 CurrentDisplayOutputError=GE_NONE;
1628 GSM_Error SetDisplayOutput(unsigned char state)
1630 unsigned char req[] = { N6110_FRAME_HEADER,
1635 return NULL_SendMessageSequence
1636 (30, &CurrentDisplayOutputError, 5, 0x0d, req);
1639 GSM_Error N6110_EnableDisplayOutput()
1641 return SetDisplayOutput(0x01);
1644 GSM_Error N6110_DisableDisplayOutput()
1646 return SetDisplayOutput(0x02);
1649 /* If it is interesting for somebody: we can use 0x40 msg for it
1650 and it will work for all phones. See n6110.txt for details */
1651 GSM_Error N6110_AnswerCall(char s)
1653 unsigned char req0[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,0x07, 0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
1654 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80};
1655 unsigned char req[] = { N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
1660 fprintf(stdout,_("Answering call %d\n\r"),s);
1663 Protocol->SendMessage(sizeof(req0), 0x01, req0);
1666 return NULL_SendMessageSequence
1667 (20, &CurrentMagicError, sizeof(req) , 0x01, req);
1670 void N6110_ReplyGetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1672 switch (MessageBuffer[3]) {
1674 /* Profile feature */
1677 switch(GetModelFeature (FN_PROFILES)) {
1679 switch (MessageBuffer[6]) {
1680 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8]; break;
1681 case 0x01: CurrentProfile->CallAlert = MessageBuffer[8]; break;
1682 case 0x02: CurrentProfile->Ringtone = MessageBuffer[8]; break;
1683 case 0x03: CurrentProfile->Volume = MessageBuffer[8]; break;
1684 case 0x04: CurrentProfile->MessageTone = MessageBuffer[8]; break;
1685 case 0x05: CurrentProfile->Vibration = MessageBuffer[8]; break;
1686 case 0x06: CurrentProfile->WarningTone = MessageBuffer[8]; break;
1687 case 0x07: CurrentProfile->ScreenSaver = MessageBuffer[8]; break;
1690 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1696 switch (MessageBuffer[6]) {
1697 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8];break;
1698 case 0x01: CurrentProfile->Lights = MessageBuffer[8];break;
1699 case 0x02: CurrentProfile->CallAlert = MessageBuffer[8];break;
1700 case 0x03: CurrentProfile->Ringtone = MessageBuffer[8];break;
1701 case 0x04: CurrentProfile->Volume = MessageBuffer[8];break;
1702 case 0x05: CurrentProfile->MessageTone = MessageBuffer[8];break;
1703 case 0x06: CurrentProfile->Vibration = MessageBuffer[8];break;
1704 case 0x07: CurrentProfile->WarningTone = MessageBuffer[8];break;
1705 case 0x08: CurrentProfile->CallerGroups = MessageBuffer[8];break;
1706 case 0x09: CurrentProfile->AutomaticAnswer = MessageBuffer[8];break;
1709 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1716 CurrentProfileError = GE_NONE;
1719 /* Incoming profile name */
1722 if (MessageBuffer[9] == 0x00) {
1723 CurrentProfile->DefaultName=MessageBuffer[8];
1725 CurrentProfile->DefaultName=-1;
1727 /* Here name is in Unicode */
1728 if (GetModelFeature (FN_PROFILES)==F_PROF33) {
1729 DecodeUnicode (CurrentProfile->Name, MessageBuffer+10, MessageBuffer[9]/2);
1732 sprintf(CurrentProfile->Name, MessageBuffer + 10, MessageBuffer[9]);
1733 CurrentProfile->Name[MessageBuffer[9]] = '\0';
1737 CurrentProfileError = GE_NONE;
1743 /* Needs SIM card with PIN in phone */
1744 GSM_Error N6110_GetProfile(GSM_Profile *Profile)
1748 unsigned char name_req[] = { N6110_FRAME_HEADER, 0x1a, 0x00};
1749 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x13, 0x01, 0x00, 0x00};
1753 CurrentProfile = Profile;
1755 /* When after sending all frames feature==253, it means, that it is not
1757 CurrentProfile->KeypadTone=253;
1758 CurrentProfile->Lights=253;
1759 CurrentProfile->CallAlert=253;
1760 CurrentProfile->Ringtone=253;
1761 CurrentProfile->Volume=253;
1762 CurrentProfile->MessageTone=253;
1763 CurrentProfile->WarningTone=253;
1764 CurrentProfile->Vibration=253;
1765 CurrentProfile->CallerGroups=253;
1766 CurrentProfile->ScreenSaver=253;
1767 CurrentProfile->AutomaticAnswer=253;
1769 name_req[4] = Profile->Number;
1771 error=NULL_SendMessageSequence
1772 (20, &CurrentProfileError, 5, 0x05, name_req);
1773 if (error!=GE_NONE) return error;
1775 for (i = 0x00; i <= 0x09; i++) {
1777 feat_req[5] = Profile->Number;
1781 error=NULL_SendMessageSequence
1782 (20, &CurrentProfileError, 7, 0x05, feat_req);
1783 if (error!=GE_NONE) return error;
1786 if (Profile->DefaultName > -1)
1788 switch(GetModelFeature (FN_PROFILES)) {
1790 switch (Profile->DefaultName) {
1791 case 0x00: sprintf(Profile->Name, "General");break;
1792 case 0x01: sprintf(Profile->Name, "Silent");break;
1793 case 0x02: sprintf(Profile->Name, "Descreet");break;
1794 case 0x03: sprintf(Profile->Name, "Loud");break;
1795 case 0x04: sprintf(Profile->Name, "My style");break;
1796 case 0x05: Profile->Name[0]=0;break;
1797 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1801 switch (Profile->DefaultName) {
1802 case 0x00: sprintf(Profile->Name, "Personal");break;
1803 case 0x01: sprintf(Profile->Name, "Car");break;
1804 case 0x02: sprintf(Profile->Name, "Headset");break;
1805 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1809 switch (Profile->DefaultName) {
1810 case 0x00: sprintf(Profile->Name, "General");break;
1811 case 0x01: sprintf(Profile->Name, "Silent");break;
1812 case 0x02: sprintf(Profile->Name, "Meeting");break;
1813 case 0x03: sprintf(Profile->Name, "Outdoor");break;
1814 case 0x04: sprintf(Profile->Name, "Pager");break;
1815 case 0x05: sprintf(Profile->Name, "Car");break;
1816 case 0x06: sprintf(Profile->Name, "Headset");break;
1817 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1827 void N6110_ReplySetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1829 switch (MessageBuffer[3]) {
1831 /* Profile feature change result */
1834 fprintf(stdout, _("Message: Profile feature change result.\n"));
1836 CurrentProfileError = GE_NONE;
1839 /* Profile name set result */
1842 fprintf(stdout, _("Message: Profile name change result.\n"));
1844 CurrentProfileError = GE_NONE;
1850 GSM_Error N6110_SetProfileFeature(u8 profile, u8 feature, u8 value)
1852 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x10, 0x01,
1855 feat_req[5]=profile;
1856 feat_req[6]=feature;
1859 return NULL_SendMessageSequence
1860 (20, &CurrentProfileError, 8, 0x05, feat_req);
1863 GSM_Error N6110_SetProfile(GSM_Profile *Profile)
1867 unsigned char name_req[40] = { N6110_FRAME_HEADER, 0x1c, 0x01, 0x03,
1872 name_req[7] = Profile->Number;
1873 name_req[8] = strlen(Profile->Name);
1874 name_req[6] = name_req[8] + 2;
1876 for (i = 0; i < name_req[8]; i++)
1877 name_req[9 + i] = Profile->Name[i];
1879 error=NULL_SendMessageSequence
1880 (20, &CurrentProfileError, name_req[8] + 9, 0x05, name_req);
1881 if (error!=GE_NONE) return error;
1883 for (i = 0x00; i <= 0x09; i++) {
1886 case 0x00: value = Profile->KeypadTone; break;
1887 case 0x01: value = Profile->Lights; break;
1888 case 0x02: value = Profile->CallAlert; break;
1889 case 0x03: value = Profile->Ringtone; break;
1890 case 0x04: value = Profile->Volume; break;
1891 case 0x05: value = Profile->MessageTone; break;
1892 case 0x06: value = Profile->Vibration; break;
1893 case 0x07: value = Profile->WarningTone; break;
1894 case 0x08: value = Profile->CallerGroups; break;
1895 case 0x09: value = Profile->AutomaticAnswer; break;
1896 default : value = 0; break;
1899 error=N6110_SetProfileFeature(Profile->Number,i,value);
1900 if (error!=GE_NONE) return error;
1906 bool N6110_SendRLPFrame(RLP_F96Frame *frame, bool out_dtx)
1908 u8 req[60] = { 0x00, 0xd9 };
1910 /* Discontinuos transmission (DTX). See section 5.6 of GSM 04.22 version
1916 memcpy(req+2, (u8 *) frame, 32);
1918 return (Protocol->SendFrame(32, 0xf0, req));
1921 void N6110_ReplyGetCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1929 switch (MessageBuffer[4]) {
1933 CurrentCalendarNote->Type=MessageBuffer[8];
1935 DecodeDateTime(MessageBuffer+9, &CurrentCalendarNote->Time);
1937 DecodeDateTime(MessageBuffer+16, &CurrentCalendarNote->Alarm);
1939 CurrentCalendarNote->Text[0]=0;
1941 if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
1943 if (CurrentCalendarNote->Type == GCN_REMINDER) i=1; //first char is subset
1944 switch (MessageBuffer[24]) {
1947 fprintf(stdout,_("Subset 3 in reminder note !\n"));
1949 while (i!=MessageBuffer[23]) {
1951 if (i!=MessageBuffer[23]-1) {
1952 if (MessageBuffer[24+i]>=0xc2) {
1953 DecodeWithUTF8Alphabet(MessageBuffer[24+i], MessageBuffer[24+i+1], &mychar1);
1954 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1955 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=mychar1;
1961 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1962 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=MessageBuffer[24+i];
1969 fprintf(stdout,_("Subset 2 in reminder note !\n"));
1971 while (i!=MessageBuffer[23]) {
1972 wc = MessageBuffer[24+i] | (0x00 << 8);
1973 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1974 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=
1975 DecodeWithUnicodeAlphabet(wc);
1981 fprintf(stdout,_("Subset 1 in reminder note !\n"));
1983 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1984 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1988 fprintf(stdout,_("Unknown subset in reminder note !\n"));
1990 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1991 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1995 memcpy(CurrentCalendarNote->Text,MessageBuffer+24,MessageBuffer[23]);
1996 CurrentCalendarNote->Text[MessageBuffer[23]]=0;
1999 if (CurrentCalendarNote->Type == GCN_CALL) {
2000 memcpy(CurrentCalendarNote->Phone,MessageBuffer+24+MessageBuffer[23]+1,MessageBuffer[24+MessageBuffer[23]]);
2001 CurrentCalendarNote->Phone[MessageBuffer[24+MessageBuffer[23]]]=0;
2004 CurrentCalendarNote->Recurrance=0;
2006 CurrentCalendarNote->AlarmType=0;
2009 fprintf(stdout, _("Message: Calendar note received.\n"));
2011 fprintf(stdout, _(" Date: %d-%02d-%02d\n"), CurrentCalendarNote->Time.Year,
2012 CurrentCalendarNote->Time.Month,
2013 CurrentCalendarNote->Time.Day);
2015 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentCalendarNote->Time.Hour,
2016 CurrentCalendarNote->Time.Minute,
2017 CurrentCalendarNote->Time.Second);
2019 /* Some messages do not have alarm set up */
2020 if (CurrentCalendarNote->Alarm.Year != 0) {
2021 fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"), CurrentCalendarNote->Alarm.Year,
2022 CurrentCalendarNote->Alarm.Month,
2023 CurrentCalendarNote->Alarm.Day);
2025 fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"), CurrentCalendarNote->Alarm.Hour,
2026 CurrentCalendarNote->Alarm.Minute,
2027 CurrentCalendarNote->Alarm.Second);
2030 fprintf(stdout, _(" Type: %d\n"), CurrentCalendarNote->Type);
2031 fprintf(stdout, _(" Text: %s\n"), CurrentCalendarNote->Text);
2033 if (CurrentCalendarNote->Type == GCN_CALL)
2034 fprintf(stdout, _(" Phone: %s\n"), CurrentCalendarNote->Phone);
2037 CurrentCalendarNoteError=GE_NONE;
2043 fprintf(stdout, _("Message: Calendar note not available\n"));
2046 CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;
2052 fprintf(stdout, _("Message: Calendar note error\n"));
2055 CurrentCalendarNoteError=GE_INTERNALERROR;
2061 GSM_Error N6110_GetCalendarNote(GSM_CalendarNote *CalendarNote)
2064 unsigned char req[] = { N6110_FRAME_HEADER,
2069 req[4]=CalendarNote->Location;
2071 CurrentCalendarNote = CalendarNote;
2073 error=NULL_SendMessageSequence
2074 (20, &CurrentCalendarNoteError, 5, 0x13, req);
2076 CurrentCalendarNote = NULL;
2081 void N6110_ReplyWriteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2084 switch(MessageBuffer[4]) {
2085 /* This message is also sent when the user enters the new entry on keypad */
2087 fprintf(stdout, _("Message: Calendar note write succesfull!\n"));break;
2089 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2091 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2093 fprintf(stdout, _("Unknown message of type 0x13 and subtype 0x65\n"));break;
2097 switch(MessageBuffer[4]) {
2098 case 0x01: CurrentCalendarNoteError=GE_NONE; break;
2099 case 0x73: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2100 case 0x7d: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2101 default : AppendLogText("Unknown msg\n",false); break;
2105 GSM_Error N6110_WriteCalendarNote(GSM_CalendarNote *CalendarNote)
2108 unsigned char req[200] = { N6110_FRAME_HEADER,
2110 0x00, /* Length of the rest of the frame. */
2111 0x00, /* The type of calendar note */
2112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2119 unsigned char meeting;
2120 unsigned char birthday;
2121 unsigned char reminder;
2122 } calendar_model_length;
2124 /* Length of entries */
2125 calendar_model_length calendar_lengths[] =
2127 /*model,CallTo,Meeting,Birthday,Reminder*/
2128 {"NHM-5",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2129 {"NHM-6",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2130 {"NSE-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 [HKEY_LOCAL_MACHINE\Software\Nokia\Data Suite\3.0\Calendar]
2131 {"NSM-1",0x1e,0x18,0x18,0x24}, //from NCDS3
2132 {"NSK-3",0x1e,0x14,0x14,0x1e}, //from NCDS3
2133 {"NSB-3",0x20,0x14,0x14,0x1e}, //from NCDS3
2134 {"", 0, 0, 0, 0 } //end of table
2145 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
2148 req[7]=CalendarNote->Type;
2150 EncodeDateTime(req+8, &CalendarNote->Time);
2151 req[14] = CalendarNote->Time.Timezone;
2153 if (CalendarNote->Alarm.Year) {
2154 EncodeDateTime(req+15, &CalendarNote->Alarm);
2155 req[21] = CalendarNote->Alarm.Timezone;
2158 req[22]=strlen(CalendarNote->Text);
2162 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2163 req[22]++; // one additional char
2164 req[current++]=0x01; //we use now subset 1
2167 for (i=0; i<strlen(CalendarNote->Text); i++) {
2169 mychar=CalendarNote->Text[i];
2170 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2171 if (EncodeWithUTF8Alphabet(mychar,&mychar1,&mychar2)) {
2172 req[current++]=mychar1;
2173 req[current++]=mychar2;
2174 req[23]=0x03; //use subset 3
2175 req[22]++; // one additional char
2180 /* Enables/disables blinking */
2181 if (mychar=='~') req[current++]=0x01;
2182 else req[current++]=mychar;
2186 req[current++]=strlen(CalendarNote->Phone);
2188 for (i=0; i<strlen(CalendarNote->Phone); i++)
2189 req[current++]=CalendarNote->Phone[i];
2191 while (N6110_GetModel(model) != GE_NONE)
2194 /* Checking maximal length */
2196 while (strcmp(calendar_lengths[i].model,"")) {
2197 if (!strcmp(calendar_lengths[i].model,model)) {
2198 switch (CalendarNote->Type) {
2199 case GCN_REMINDER:if (req[22]>calendar_lengths[i].reminder) return GE_TOOLONG;break;
2200 case GCN_MEETING :if (req[22]>calendar_lengths[i].meeting) return GE_TOOLONG;break;
2201 case GCN_BIRTHDAY:if (req[22]>calendar_lengths[i].birthday) return GE_TOOLONG;break;
2202 case GCN_CALL :if (strlen(CalendarNote->Phone)>calendar_lengths[i].call) return GE_TOOLONG;break;
2209 CurrentCalendarNote = CalendarNote;
2211 error=NULL_SendMessageSequence
2212 (20, &CurrentCalendarNoteError, current, 0x13, req);
2214 CurrentCalendarNote = NULL;
2219 void N6110_ReplyDeleteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2222 switch (MessageBuffer[4]) {
2223 /* This message is also sent when the user deletes an old entry on
2224 keypad or moves an old entry somewhere (there is also `write'
2226 case 0x01:fprintf(stdout, _("Message: Calendar note deleted\n"));break;
2227 case 0x93:fprintf(stdout, _("Message: Calendar note can't be deleted\n"));break;
2228 default :fprintf(stdout, _("Message: Calendar note deleting error\n"));break;
2232 switch (MessageBuffer[4]) {
2233 case 0x01:CurrentCalendarNoteError=GE_NONE;break;
2234 case 0x93:CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;break;
2235 default :CurrentCalendarNoteError=GE_INTERNALERROR;break;
2239 GSM_Error N6110_DeleteCalendarNote(GSM_CalendarNote *CalendarNote)
2242 unsigned char req[] = { N6110_FRAME_HEADER,
2246 req[4]=CalendarNote->Location;
2248 return NULL_SendMessageSequence (20, &CurrentCalendarNoteError, 5, 0x13, req);
2251 #endif /* UCLINUX */
2253 static void N6110_ReplyRFBatteryLevel(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2256 fprintf(stdout, _("Message: Phone status received:\n"));
2257 fprintf(stdout, _(" Mode: "));
2259 switch (MessageBuffer[4]) {
2263 fprintf(stdout, _("registered within the network\n"));
2266 /* I was really amazing why is there a hole in the type of 0x02, now I
2268 case 0x02: fprintf(stdout, _("call in progress\n")); break; /* ringing or already answered call */
2269 case 0x03: fprintf(stdout, _("waiting for security code\n")); break;
2270 case 0x04: fprintf(stdout, _("powered off\n")); break;
2271 default : fprintf(stdout, _("unknown\n"));
2275 fprintf(stdout, _(" Power source: "));
2277 switch (MessageBuffer[7]) {
2279 case 0x01: fprintf(stdout, _("AC/DC\n")); break;
2280 case 0x02: fprintf(stdout, _("battery\n")); break;
2281 default : fprintf(stdout, _("unknown\n"));
2285 fprintf(stdout, _(" Battery Level: %d\n"), MessageBuffer[8]);
2286 fprintf(stdout, _(" Signal strength: %d\n"), MessageBuffer[5]);
2289 CurrentRFLevel=MessageBuffer[5];
2290 CurrentBatteryLevel=MessageBuffer[8];
2291 CurrentPowerSource=MessageBuffer[7];
2295 GSM_Error N6110_GetRFLevel(GSM_RFUnits *units, float *level)
2298 /* FIXME - these values are from 3810 code, may be incorrect. Map from
2299 values returned in status packet to the the values returned by the AT+CSQ
2301 float csq_map[5] = {0, 8, 16, 24, 31};
2306 char screen[NM_MAX_SCREEN_WIDTH];
2310 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2313 if (N6110_NetMonitor(1, screen)!=GE_NONE)
2314 return GE_INTERNALERROR;
2315 #endif /* UCLINUX */
2319 if (screen[4]!='-') {
2320 if (screen[5]=='9' && screen[6]>'4') rf_level=1;
2321 if (screen[5]=='9' && screen[6]<'5') rf_level=2;
2322 if (screen[5]=='8' && screen[6]>'4') rf_level=3;
2325 /* Arbitrary units. */
2326 if (*units == GRF_Arbitrary) {
2332 N6110_SendStatusRequest();
2334 /* Wait for timeout or other error. */
2335 while (timeout != 0 && CurrentRFLevel == -1 ) {
2338 return (GE_TIMEOUT);
2343 /* Make copy in case it changes. */
2344 rf_level = CurrentRFLevel;
2349 /* Now convert between the different units we support. */
2351 /* Arbitrary units. */
2352 if (*units == GRF_Arbitrary) {
2358 if (*units == GRF_CSQ) {
2361 *level = csq_map[rf_level];
2363 *level = 99; /* Unknown/undefined */
2369 /* Unit type is one we don't handle so return error */
2370 return (GE_INTERNALERROR);
2374 GSM_Error N6110_GetBatteryLevel(GSM_BatteryUnits *units, float *level)
2379 char screen[NM_MAX_SCREEN_WIDTH];
2381 CurrentBatteryLevel=-1;
2383 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2386 if (N6110_NetMonitor(23, screen)!=GE_NONE)
2388 #endif /* UCLINUX */
2392 if (screen[29]=='7') batt_level=3;
2393 if (screen[29]=='5') batt_level=2;
2394 if (screen[29]=='2') batt_level=1;
2396 /* Only units we handle at present are GBU_Arbitrary */
2397 if (*units == GBU_Arbitrary) {
2398 *level = batt_level;
2402 return (GE_INTERNALERROR);
2405 N6110_SendStatusRequest();
2407 /* Wait for timeout or other error. */
2408 while (timeout != 0 && CurrentBatteryLevel == -1 ) {
2411 return (GE_TIMEOUT);
2416 /* Take copy in case it changes. */
2417 batt_level = CurrentBatteryLevel;
2419 if (batt_level != -1) {
2421 /* Only units we handle at present are GBU_Arbitrary */
2422 if (*units == GBU_Arbitrary) {
2423 *level = batt_level;
2427 return (GE_INTERNALERROR);
2434 GSM_Error N6110_GetPowerSource(GSM_PowerSource *source)
2439 char screen[NM_MAX_SCREEN_WIDTH];
2441 CurrentPowerSource=-1;
2443 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2446 if (N6110_NetMonitor(20, screen)!=GE_NONE)
2448 #endif /* UCLINUX */
2450 CurrentPowerSource=GPS_ACDC;
2452 if (screen[6]=='x') CurrentPowerSource=GPS_BATTERY;
2454 *source=CurrentPowerSource;
2458 N6110_SendStatusRequest();
2460 /* Wait for timeout or other error. */
2461 while (timeout != 0 && CurrentPowerSource == -1 ) {
2464 return (GE_TIMEOUT);
2469 if (CurrentPowerSource != -1) {
2470 *source=CurrentPowerSource;
2480 static void N6110_ReplyGetDisplayStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2484 for (i=0; i<MessageBuffer[4];i++)
2485 if (MessageBuffer[2*i+6]==2)
2486 CurrentDisplayStatus|=1<<(MessageBuffer[2*i+5]-1);
2488 CurrentDisplayStatus&= (0xff - (1<<(MessageBuffer[2*i+5]-1)));
2491 fprintf(stdout, _("Call in progress: %s\n"), CurrentDisplayStatus & (1<<DS_Call_In_Progress)?"on":"off");
2492 fprintf(stdout, _("Unknown: %s\n"), CurrentDisplayStatus & (1<<DS_Unknown)?"on":"off");
2493 fprintf(stdout, _("Unread SMS: %s\n"), CurrentDisplayStatus & (1<<DS_Unread_SMS)?"on":"off");
2494 fprintf(stdout, _("Voice call: %s\n"), CurrentDisplayStatus & (1<<DS_Voice_Call)?"on":"off");
2495 fprintf(stdout, _("Fax call active: %s\n"), CurrentDisplayStatus & (1<<DS_Fax_Call)?"on":"off");
2496 fprintf(stdout, _("Data call active: %s\n"), CurrentDisplayStatus & (1<<DS_Data_Call)?"on":"off");
2497 fprintf(stdout, _("Keyboard lock: %s\n"), CurrentDisplayStatus & (1<<DS_Keyboard_Lock)?"on":"off");
2498 fprintf(stdout, _("SMS storage full: %s\n"), CurrentDisplayStatus & (1<<DS_SMS_Storage_Full)?"on":"off");
2501 CurrentDisplayStatusError=GE_NONE;
2504 GSM_Error N6110_GetDisplayStatus(int *Status) {
2506 unsigned char req[4]={ N6110_FRAME_HEADER, 0x51 };
2510 error=NULL_SendMessageSequence
2511 (10, &CurrentDisplayStatusError, 4, 0x0d, req);
2512 if (error!=GE_NONE) return error;
2514 *Status=CurrentDisplayStatus;
2519 GSM_Error N6110_DialVoice(char *Number) {
2520 /* This commented sequence doesn't work on N3210/3310/6210/7110 */
2521 // unsigned char req[64]={N6110_FRAME_HEADER, 0x01};
2522 // unsigned char req_end[]={0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};
2524 // req[4]=strlen(Number);
2525 // for(i=0; i < strlen(Number) ; i++)
2526 // req[5+i]=Number[i];
2527 // memcpy(req+5+strlen(Number), req_end, 10);
2528 // return NULL_SendMessageSequence
2529 // (20, &CurrentDialVoiceError, 13+strlen(Number), 0x01, req);
2531 unsigned char req[64]={0x00,0x01,0x7c,
2532 0x01}; //call command
2538 error=N6110_EnableExtendedCommands(0x01);
2539 if (error!=GE_NONE) return error;
2541 for(i=0; i < strlen(Number) ; i++) req[4+i]=Number[i];
2545 return NULL_SendMessageSequence
2546 (20, &CurrentDialVoiceError, 4+strlen(Number)+1, 0x40, req);
2549 #endif /* UCLINUX */
2551 /* Dial a data call - type specifies request to use:
2552 type 0 should normally be used
2553 type 1 should be used when calling a digital line - corresponds to ats35=0
2554 Maybe one day we'll know what they mean!
2556 GSM_Error N6110_DialData(char *Number, char type, void (* callpassup)(char c))
2558 unsigned char req[100] = { N6110_FRAME_HEADER, 0x01 };
2559 unsigned char *req_end;
2560 unsigned char req_end0[] = { 0x01, /* make a data call = type 0x01 */
2561 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2562 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00 };
2563 unsigned char req_end1[] = { 0x01,
2564 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2565 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2566 0x88,0x90,0x21,0x48,0x40,0xbb };
2567 unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2568 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2569 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
2570 unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2571 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2572 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
2573 unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
2574 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2575 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
2576 0x20,0x15,0x63,0x80 };
2581 CurrentCallPassup=callpassup;
2586 size = sizeof(req_end0);
2589 Protocol->SendMessage(sizeof(req3), 0x01, req3);
2590 Protocol->SendMessage(sizeof(req4), 0x01, req4);
2592 size = sizeof(req_end1);
2594 case -1: /* Just used to set the call passup */
2599 size = sizeof(req_end0);
2603 req[4] = strlen(Number);
2605 for(i = 0; i < strlen(Number) ; i++)
2606 req[5+i] = Number[i];
2608 memcpy(req + 5 + strlen(Number), req_end, size);
2610 Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);
2611 if (type != 1) Protocol->SendMessage(26, 0x01, req2);
2618 GSM_Error N6110_GetIncomingCallNr(char *Number)
2621 if (*CurrentIncomingCall != ' ') {
2622 strcpy(Number, CurrentIncomingCall);
2629 #endif /* UCLINUX */
2631 GSM_Error N6110_CancelCall(void)
2633 // This frame & method works only on 61xx/51xx
2634 // unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
2635 // req[4]=CurrentCallSequenceNumber;
2636 // Protocol->SendMessage(6, 0x01, req);
2641 unsigned char req[]={0x00,0x01,0x7c,0x03};
2644 error=N6110_EnableExtendedCommands(0x01);
2645 if (error!=GE_NONE) return error;
2647 return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
2652 void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2654 switch(MessageBuffer[3]) {
2658 fprintf(stdout, _("Message: Security code accepted.\n"));
2660 CurrentSecurityCodeError = GE_NONE;
2665 fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
2667 CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
2671 GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
2674 unsigned char req[15] = { N6110_FRAME_HEADER,
2675 0x0a, /* Enter code request. */
2676 0x00 /* Type of the entered code. */
2680 req[4]=SecurityCode.Type;
2682 for (i=0; i<strlen(SecurityCode.Code);i++)
2683 req[5+i]=SecurityCode.Code[i];
2685 req[5+strlen(SecurityCode.Code)]=0x00;
2686 req[6+strlen(SecurityCode.Code)]=0x00;
2688 return NULL_SendMessageSequence
2689 (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
2692 void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2694 *CurrentSecurityCodeStatus = MessageBuffer[4];
2697 fprintf(stdout, _("Message: Security Code status received: "));
2699 switch(*CurrentSecurityCodeStatus) {
2701 case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;
2702 case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;
2703 case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;
2704 case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;
2705 case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;
2706 case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;
2707 default : fprintf(stdout, _("Unknown!\n"));
2712 CurrentSecurityCodeError = GE_NONE;
2715 GSM_Error N6110_GetSecurityCodeStatus(int *Status)
2718 unsigned char req[4] = { N6110_FRAME_HEADER,
2722 CurrentSecurityCodeStatus=Status;
2724 return NULL_SendMessageSequence
2725 (20, &CurrentSecurityCodeError, 4, 0x08, req);
2728 void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2733 fprintf(stdout, _("Message: Security code received: "));
2734 switch (MessageBuffer[3]) {
2735 case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;
2736 case GSCT_Pin: fprintf(stdout, _("PIN"));break;
2737 case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;
2738 case GSCT_Puk: fprintf(stdout, _("PUK"));break;
2739 case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;
2740 default: fprintf(stdout, _("unknown !"));break;
2742 if (MessageBuffer[4]==1) {
2743 fprintf(stdout, _(" allowed, value \""));
2744 if (MessageBuffer[3]==GSCT_SecurityCode) {
2745 for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2747 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2748 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2749 for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2751 fprintf(stdout, _("\""));
2753 fprintf(stdout, _(" not allowed"));
2755 fprintf(stdout, _("\n"));
2758 if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
2759 && MessageBuffer[4]==1) { /* It's allowed */
2760 if (MessageBuffer[3]==GSCT_SecurityCode) {
2761 for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2762 CurrentSecurityCode->Code[5]=0;
2764 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2765 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2766 for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2767 CurrentSecurityCode->Code[4]=0;
2769 CurrentSecurityCodeError=GE_NONE;
2771 CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
2774 GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
2777 unsigned char req[4] = { 0x00,
2778 0x01,0x6e, /* Get code request. */
2779 0x00 }; /* Type of the requested code. */
2783 error=N6110_EnableExtendedCommands(0x01);
2784 if (error!=GE_NONE) return error;
2786 req[3]=SecurityCode->Type;
2788 CurrentSecurityCode=SecurityCode;
2790 return NULL_SendMessageSequence
2791 (20, &CurrentSecurityCodeError, 4, 0x40, req);
2794 void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2797 fprintf(stdout, _("Message: answer for PlayTone frame\n"));
2800 CurrentPlayToneError=GE_NONE;
2803 GSM_Error N6110_PlayTone(int Herz, u8 Volume)
2805 unsigned char req[6] = { 0x00,0x01,0x8f,
2808 0x00 }; /* HerzHi */
2812 /* PlayTone wasn't used earlier */
2813 if (CurrentPlayToneError==GE_UNKNOWN) {
2814 if (CurrentConnectionType!=GCT_MBUS)
2815 CurrentDisableKeepAlive=true;
2817 error=N6110_EnableExtendedCommands(0x01);
2818 if (error!=GE_NONE) return error;
2821 /* For Herz==255*255 we have silent */
2822 if (Herz!=255*255) {
2835 /* For Herz==255*255 we have silent and additionaly
2836 we wait for phone answer - it's important for MBUS */
2837 if (Herz==255*255) {
2838 error=NULL_SendMessageSequence
2839 (20, &CurrentPlayToneError, 6, 0x40, req);
2841 CurrentPlayToneError=GE_UNKNOWN;
2842 CurrentDisableKeepAlive=false;
2844 if (error!=GE_NONE) return error;
2846 Protocol->SendMessage(6,0x40,req);
2849 error=NULL_SendMessageSequence
2850 (20, &CurrentPlayToneError, 6, 0x40, req);
2852 /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
2853 if (Herz==255*255) {
2854 CurrentPlayToneError=GE_UNKNOWN;
2855 CurrentDisableKeepAlive=false;
2858 if (error!=GE_NONE) return error;
2865 void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2867 if (MessageBuffer[4]==0x01) {
2868 DecodeDateTime(MessageBuffer+8, CurrentDateTime);
2871 fprintf(stdout, _("Message: Date and time\n"));
2872 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
2873 fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
2876 CurrentDateTime->IsSet=true;
2880 fprintf(stdout, _("Message: Date and time not set in phone\n"));
2883 CurrentDateTime->IsSet=false;
2886 CurrentDateTimeError=GE_NONE;
2889 GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
2891 return N6110_PrivGetDateTime(date_time,0x11);
2894 GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
2896 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
2898 CurrentDateTime=date_time;
2900 return NULL_SendMessageSequence
2901 (50, &CurrentDateTimeError, 4, msgtype, req);
2904 void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2907 fprintf(stdout, _("Message: Alarm\n"));
2908 fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
2909 fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
2912 CurrentAlarm->Hour=MessageBuffer[9];
2913 CurrentAlarm->Minute=MessageBuffer[10];
2914 CurrentAlarm->Second=0;
2916 CurrentAlarm->IsSet=(MessageBuffer[8]==2);
2918 CurrentAlarmError=GE_NONE;
2921 GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
2923 return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
2926 GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
2928 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
2930 CurrentAlarm=date_time;
2932 return NULL_SendMessageSequence
2933 (50, &CurrentAlarmError, 4, msgtype, req);
2936 void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2938 switch (MessageBuffer[3]) {
2942 CurrentMessageCenter->No=MessageBuffer[4];
2943 CurrentMessageCenter->Format=MessageBuffer[6];
2944 CurrentMessageCenter->Validity=MessageBuffer[8];
2945 sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
2947 sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
2949 sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
2952 fprintf(stdout, _("Message: SMS Center received:\n"));
2953 fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
2954 fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
2955 fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
2957 fprintf(stdout, _(" SMS Center message format is "));
2959 switch (CurrentMessageCenter->Format) {
2961 case GSMF_Text : fprintf(stdout, _("Text")); break;
2962 case GSMF_Paging: fprintf(stdout, _("Paging")); break;
2963 case GSMF_Fax : fprintf(stdout, _("Fax")); break;
2964 case GSMF_Email : fprintf(stdout, _("Email")); break;
2965 default : fprintf(stdout, _("Unknown"));
2968 fprintf(stdout, "\n");
2970 fprintf(stdout, _(" SMS Center message validity is "));
2972 switch (CurrentMessageCenter->Validity) {
2974 case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;
2975 case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;
2976 case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;
2977 case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;
2978 case GSMV_1_Week : fprintf(stdout, _("1 week")); break;
2979 case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;
2980 default : fprintf(stdout, _("Unknown"));
2983 fprintf(stdout, "\n");
2987 CurrentMessageCenterError=GE_NONE;
2993 /* Number of entries depends on SIM card */
2996 fprintf(stdout, _("Message: SMS Center error received:\n"));
2997 fprintf(stdout, _(" The request for SMS Center failed.\n"));
3000 /* FIXME: appropriate error. */
3001 CurrentMessageCenterError=GE_INTERNALERROR;
3008 /* This function sends to the mobile phone a request for the SMS Center */
3009 GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
3011 unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
3012 0x00 /* SMS Center Number. */
3015 req[5]=MessageCenter->No;
3017 CurrentMessageCenter=MessageCenter;
3019 return NULL_SendMessageSequence
3020 (50, &CurrentMessageCenterError, 6, 0x02, req);
3023 void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3026 fprintf(stdout, _("Message: SMS Center correctly set.\n"));
3028 CurrentMessageCenterError=GE_NONE;
3031 /* This function set the SMS Center profile on the phone. */
3032 GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
3034 unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
3035 0x00, /* SMS Center Number. */
3036 0x00, /* Unknown. */
3037 0x00, /* SMS Message Format. */
3038 0x00, /* Unknown. */
3039 0x00, /* Validity. */
3040 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
3041 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
3042 /* Message Center Name. */
3045 req[5]=MessageCenter->No;
3046 req[7]=MessageCenter->Format;
3047 req[9]=MessageCenter->Validity;
3049 req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
3051 req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
3053 sprintf(req+34, "%s", MessageCenter->Name);
3055 CurrentMessageCenter=MessageCenter;
3057 return NULL_SendMessageSequence
3058 (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
3061 void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3063 switch (MessageBuffer[3]) {
3068 fprintf(stdout, _("Message: SMS Status Received\n"));
3069 fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
3070 fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
3073 CurrentSMSStatus->UnRead = MessageBuffer[11];
3074 CurrentSMSStatus->Number = MessageBuffer[10];
3076 CurrentSMSStatusError = GE_NONE;
3082 fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
3085 CurrentSMSStatusError = GE_INTERNALERROR;
3091 GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
3093 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
3095 CurrentSMSStatus = Status;
3097 return NULL_SendMessageSequence
3098 (10, &CurrentSMSStatusError, 5, 0x14, req);
3101 GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
3105 strcpy(folders->Folder[0].Name,"Inbox");
3106 strcpy(folders->Folder[1].Name,"Outbox");
3111 GSM_Error N6110_GetIMEI(char *imei)
3113 if (strlen(Current_IMEI)>0) {
3114 strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
3118 return (GE_TRYAGAIN);
3121 GSM_Error N6110_GetRevision(char *revision)
3124 if (strlen(Current_Revision)>0) {
3125 strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
3129 return (GE_TRYAGAIN);
3132 #endif /* UCLINUX */
3134 static GSM_Error N6110_GetModel(char *model)
3136 if (strlen(Current_Model)>0) {
3137 strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
3141 return (GE_TRYAGAIN);
3146 void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3148 switch (MessageBuffer[4]) {
3152 fprintf(stdout, _("Message: Date and time set correctly\n"));
3154 CurrentSetDateTimeError=GE_NONE;
3159 fprintf(stdout, _("Message: Date and time setting error\n"));
3161 CurrentSetDateTimeError=GE_INVALIDDATETIME;
3166 /* Needs SIM card with PIN in phone */
3167 GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
3169 return N6110_PrivSetDateTime(date_time,0x11);
3172 /* Needs SIM card with PIN in phone */
3173 GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
3176 unsigned char req[] = { N6110_FRAME_HEADER,
3177 0x60, /* set-time subtype */
3178 0x01, 0x01, 0x07, /* unknown */
3179 0x00, 0x00, /* Year (0x07cf = 1999) */
3180 0x00, 0x00, /* Month Day */
3181 0x00, 0x00, /* Hours Minutes */
3182 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3185 EncodeDateTime(req+7, date_time);
3187 return NULL_SendMessageSequence
3188 (20, &CurrentSetDateTimeError, 14, msgtype, req);
3191 void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3193 switch (MessageBuffer[4]) {
3197 fprintf(stdout, _("Message: Alarm set correctly\n"));
3199 CurrentSetAlarmError=GE_NONE;
3204 fprintf(stdout, _("Message: Alarm setting error\n"));
3206 CurrentSetAlarmError=GE_INVALIDDATETIME;
3211 /* FIXME: we should also allow to set the alarm off :-) */
3212 GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
3214 return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
3217 /* FIXME: we should also allow to set the alarm off :-) */
3218 GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
3221 unsigned char req[] = { N6110_FRAME_HEADER,
3222 0x6b, /* set-alarm subtype */
3223 0x01, 0x20, 0x03, /* unknown */
3224 0x02, /* should be alarm on/off, but it don't works */
3225 0x00, 0x00, /* Hours Minutes */
3226 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3229 req[8] = date_time->Hour;
3230 req[9] = date_time->Minute;
3232 return NULL_SendMessageSequence
3233 (50, &CurrentSetAlarmError, 11, msgtype, req);
3236 #endif /* UCLINUX */
3238 static void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3240 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
3245 switch (MessageBuffer[3]) {
3249 CurrentPhonebookEntry->Empty = true;
3251 count=MessageBuffer[5];
3254 fprintf(stdout, _("Message: Phonebook entry received:\n"));
3255 fprintf(stdout, _(" Name: "));
3257 for (tmp=0; tmp <count; tmp++)
3259 if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
3260 if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
3261 fprintf(stdout, "%c", MessageBuffer[6+tmp]);
3264 fprintf(stdout, "\n");
3267 while (N6110_GetModel(model) != GE_NONE)
3270 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3271 DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
3272 CurrentPhonebookEntry->Name[count/2] = 0x00;
3274 memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);
3275 CurrentPhonebookEntry->Name[count] = 0x00;
3278 CurrentPhonebookEntry->Empty = false;
3280 for (tmp=0; tmp <count; tmp++)
3282 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3283 /* We check only 1'st, 3'rd, ... char */
3284 if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking
3285 if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents
3287 if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking
3288 if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents
3293 count=MessageBuffer[6+count];
3296 fprintf(stdout, _(" Number: "));
3298 for (tmp=0; tmp <count; tmp++)
3299 fprintf(stdout, "%c", MessageBuffer[i+tmp]);
3301 fprintf(stdout, "\n");
3304 memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);
3305 CurrentPhonebookEntry->Number[count] = 0x00;
3306 CurrentPhonebookEntry->Group = MessageBuffer[i+count];
3308 /* Phone doesn't have entended phonebook */
3309 CurrentPhonebookEntry->SubEntriesCount = 0;
3311 /* But for these memories data is saved and we can save it using 7110/6210 style */
3312 if (CurrentPhonebookEntry->MemoryType==GMT_DC ||
3313 CurrentPhonebookEntry->MemoryType==GMT_RC ||
3314 CurrentPhonebookEntry->MemoryType==GMT_MC) {
3315 CurrentPhonebookEntry->SubEntriesCount = 1;
3316 CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;
3317 CurrentPhonebookEntry->SubEntries[0].NumberType=0;
3318 CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;
3319 DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);
3322 fprintf(stdout, _(" Date: "));
3323 fprintf(stdout, "%02u.%02u.%04u\n",
3324 CurrentPhonebookEntry->SubEntries[0].data.Date.Day,
3325 CurrentPhonebookEntry->SubEntries[0].data.Date.Month,
3326 CurrentPhonebookEntry->SubEntries[0].data.Date.Year);
3327 fprintf(stdout, _(" Time: "));
3328 fprintf(stdout, "%02u:%02u:%02u\n",
3329 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,
3330 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,
3331 CurrentPhonebookEntry->SubEntries[0].data.Date.Second);
3334 /* These values are set, when date and time unavailable in phone.
3335 Values from 3310 - in other can be different */
3336 if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&
3337 CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&
3338 CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&
3339 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&
3340 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&
3341 CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)
3342 CurrentPhonebookEntry->SubEntriesCount = 0;
3345 /* Signal no error to calling code. */
3346 CurrentPhonebookError = GE_NONE;
3353 fprintf(stdout, _("Message: Phonebook read entry error received:\n"));
3356 switch (MessageBuffer[4]) {
3360 fprintf(stdout, _(" Invalid memory type!\n"));
3362 CurrentPhonebookError = GE_INVALIDMEMORYTYPE;
3367 fprintf(stdout, _(" Unknown error!\n"));
3369 CurrentPhonebookError = GE_INTERNALERROR;
3377 /* Routine to get specifed phone book location. Designed to be called by
3378 application. Will block until location is retrieved or a timeout/error
3380 GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)
3382 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
3384 CurrentPhonebookEntry = entry;
3386 req[4] = N6110_GetMemoryType(entry->MemoryType);
3387 req[5] = entry->Location;
3389 return NULL_SendMessageSequence
3390 (50, &CurrentPhonebookError, 7, 0x03, req);
3393 static void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3395 switch (MessageBuffer[3]) {
3400 fprintf(stdout, _("Message: Phonebook written correctly.\n"));
3402 CurrentPhonebookError = GE_NONE;
3407 switch (MessageBuffer[4]) {
3408 /* FIXME: other errors? When I send the phonebook with index of 350 it
3409 still report error 0x7d :-( */
3412 fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));
3414 CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;
3419 fprintf(stdout, _(" Unknown error!\n"));
3421 CurrentPhonebookError = GE_INTERNALERROR;
3426 /* Routine to write phonebook location in phone. Designed to be called by
3427 application code. Will block until location is written or timeout
3429 GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)
3431 unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };
3434 req[4] = N6110_GetMemoryType(entry->MemoryType);
3435 req[5] = entry->Location;
3439 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {
3441 req[6] = strlen(entry->Name)*2;
3443 EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
3445 for (i=0; i<strlen(entry->Name); i++)
3447 /* here we encode "special" chars */
3448 if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
3449 if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
3452 current+=strlen(entry->Name)*2;
3455 req[6] = strlen(entry->Name);
3457 for (i=0; i<strlen(entry->Name); i++)
3459 req[current+i] = entry->Name[i];
3461 /* here we encode "special" chars */
3462 if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
3463 if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
3466 current+=strlen(entry->Name);
3469 req[current++]=strlen(entry->Number);
3471 for (i=0; i<strlen(entry->Number); i++)
3472 req[current+i] = entry->Number[i];
3474 current+=strlen(entry->Number);
3476 /* Jano: This allow to save 14 characters name into SIM memory, when
3477 No Group is selected. */
3478 if (entry->Group == 5)
3479 req[current++]=0xff;
3481 req[current++]=entry->Group;
3483 return NULL_SendMessageSequence
3484 (50, &CurrentPhonebookError, current, 0x03, req);
3489 void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3491 switch(MessageBuffer[3]) {
3495 fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
3497 CurrentNetmonitorError=GE_NONE;
3502 fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
3503 fprintf(stdout, "%s\n", MessageBuffer+4);
3506 strcpy(CurrentNetmonitor, MessageBuffer+4);
3508 CurrentNetmonitorError=GE_NONE;
3512 GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
3514 unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
3518 error=N6110_EnableExtendedCommands(0x01);
3519 if (error!=GE_NONE) return error;
3521 CurrentNetmonitor=Screen;
3525 return NULL_SendMessageSequence
3526 (20, &CurrentNetmonitorError, 4, 0x40, req);
3529 /* Doesn't work in N3210. */
3530 /* In other allow to access phone menu without SIM card (just send any sequence) */
3531 GSM_Error N6110_SendDTMF(char *String)
3533 unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
3534 0x00 /* Length of DTMF string. */
3537 u8 length=strlen(String);
3539 if (length>59) length=59;
3543 memcpy(req+5,String,length);
3545 return NULL_SendMessageSequence
3546 (20, &CurrentSendDTMFError, 5+length, 0x01, req);
3549 void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3551 switch (MessageBuffer[3]) {
3555 switch (MessageBuffer[4]) {
3556 case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
3557 default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
3560 CurrentSpeedDialEntry->Location = MessageBuffer[5];
3563 fprintf(stdout, _("Message: Speed dial entry received:\n"));
3564 fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
3565 fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
3566 fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
3569 CurrentSpeedDialError=GE_NONE;
3575 fprintf(stdout, _("Message: Speed dial entry error\n"));
3577 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3583 GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
3586 unsigned char req[] = { N6110_FRAME_HEADER,
3588 0x00 /* The number of speed dial. */
3591 CurrentSpeedDialEntry = entry;
3593 req[4] = entry->Number;
3595 return NULL_SendMessageSequence
3596 (20, &CurrentSpeedDialError, 5, 0x03, req);
3599 void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3601 switch (MessageBuffer[3]) {
3606 fprintf(stdout, _("Message: Speed dial entry set.\n"));
3608 CurrentSpeedDialError=GE_NONE;
3614 fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
3616 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3622 GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
3625 unsigned char req[] = { N6110_FRAME_HEADER,
3628 0x00, /* Memory Type */
3632 req[4] = entry->Number;
3634 switch (entry->MemoryType) {
3635 case GMT_ME: req[5] = 0x02;
3636 default : req[5] = 0x03;
3639 req[6] = entry->Location;
3641 return NULL_SendMessageSequence
3642 (20, &CurrentSpeedDialError, 7, 0x03, req);
3645 /* This function finds parts of SMS in frame used in new Nokia phones
3646 in internal protocols (they're coded according to GSM 03.40), copies them
3647 to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
3648 GSM_ETSISMSMessage to GSM_SMSMessage structure */
3649 GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
3651 SMS_MessageType PDU=SMS_Deliver;
3652 GSM_ETSISMSMessage ETSI;
3655 ETSI.firstbyte=req[12];
3657 /* See GSM 03.40 section 9.2.3.1 */
3658 if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
3659 if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
3662 case SMS_Submit : offset=5;break;
3663 case SMS_Deliver : offset=4;break;
3664 case SMS_Status_Report: offset=3;break;
3668 for (i=0;i<req[0]+1;i++)
3669 ETSI.SMSCNumber[i]=req[i];
3671 for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
3672 ETSI.Number[i]=req[i+12+offset];
3676 ETSI.TPDCS=req[10+offset];
3677 ETSI.TPUDL=req[11+offset];
3678 ETSI.TPVP=0; //no support for now
3679 ETSI.TPPID=0; //no support for now
3680 for(i=31+offset;i<length;i++)
3681 ETSI.MessageText[i-31-offset]=req[i];
3684 ETSI.TPDCS=req[10+offset];
3685 ETSI.TPUDL=req[11+offset];
3686 ETSI.TPPID=0; //no support for now
3687 for(i=31+offset;i<length;i++)
3688 ETSI.MessageText[i-31-offset]=req[i];
3690 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3692 case SMS_Status_Report:
3694 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3695 ETSI.TPStatus=req[14];
3697 ETSI.SMSCDateTime[i]=req[i+34];
3703 GSM_DecodeETSISMS(SMS, &ETSI);
3710 void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3714 switch (MessageBuffer[3]) {
3718 switch (MessageBuffer[7]) {
3721 CurrentSMSMessage->Type = GST_SMS;
3722 CurrentSMSMessage->folder=GST_INBOX;
3727 CurrentSMSMessage->Type = GST_DR;
3728 CurrentSMSMessage->folder=GST_INBOX;
3733 CurrentSMSMessage->Type = GST_SMS;
3734 CurrentSMSMessage->folder=GST_OUTBOX;
3739 CurrentSMSMessage->Type = GST_UN;
3745 /* Field Short Message Status - MessageBuffer[4] seems not to be
3746 compliant with GSM 07.05 spec.
3747 Meaning Nokia protocol GMS spec
3748 ----------------------------------------------------
3749 MO Sent 0x05 0x07 or 0x01
3750 MO Not sent 0x07 0x06 or 0x00
3751 MT Read 0x01 0x05 or 0x01
3752 MT Not read 0x03 0x04 or 0x00
3753 ----------------------------------------------------
3754 See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
3758 if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
3759 else CurrentSMSMessage->Status = GSS_SENTREAD;
3762 fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
3764 if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
3765 fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
3767 fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
3770 if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
3771 if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
3773 if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
3774 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
3775 else fprintf(stdout, _(" Not sent\n"));
3777 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
3778 else fprintf(stdout, _(" Not read\n"));
3782 CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
3784 CurrentSMSMessage->MemoryType = MessageBuffer[5];
3785 CurrentSMSMessage->MessageNumber = MessageBuffer[6];
3787 /* Signal no error to calling code. */
3788 CurrentSMSMessageError = GE_NONE;
3791 fprintf(stdout, "\n");
3798 /* We have requested invalid or empty location. */
3801 fprintf(stdout, _("Message: SMS reading failed\n"));
3803 switch (MessageBuffer[4]) {
3805 fprintf(stdout, _(" Invalid location!\n"));break;
3807 fprintf(stdout, _(" Empty SMS location.\n"));break;
3809 fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
3811 fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
3815 switch (MessageBuffer[4]) {
3816 case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3817 case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
3818 case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
3819 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3827 GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
3830 unsigned char req[] = { N6110_FRAME_HEADER,
3833 0x00, /* Location */
3838 /* State machine code writes data to these variables when it comes in. */
3840 CurrentSMSMessage = message;
3841 CurrentSMSMessageError = GE_BUSY;
3843 req[5] = message->Location;
3846 Protocol->SendMessage(8, 0x02, req);
3848 /* Wait for timeout or other error. */
3849 while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
3852 return (GE_TIMEOUT);
3857 return (CurrentSMSMessageError);
3860 void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3863 fprintf(stdout, _("Message: SMS deleted successfully.\n"));
3866 CurrentSMSMessageError = GE_NONE;
3869 GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
3871 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
3873 req[5] = message->Location;
3875 return NULL_SendMessageSequence
3876 (50, &CurrentSMSMessageError, 6, 0x14, req);
3879 /* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
3880 GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
3882 GSM_ETSISMSMessage ETSI;
3885 GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
3888 for (i=0;i<36;i++) req[i]=0;
3890 req[12]=ETSI.firstbyte;
3892 for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
3893 req[i]=ETSI.SMSCNumber[i];
3898 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3899 req[i+12+offset]=ETSI.Number[i];
3900 req[10+offset]=ETSI.TPDCS;
3901 req[11+offset]=ETSI.TPUDL;
3902 req[24+offset]=ETSI.TPVP;
3904 // fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
3905 // fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
3906 // fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
3908 // req[]=ETSI.TPPID;
3909 for(i=0;i<*length;i++)
3910 req[i+31+offset]=ETSI.MessageText[i];
3915 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3916 req[i+12+offset]=ETSI.Number[i];
3917 req[10+offset]=ETSI.TPDCS;
3918 req[11+offset]=ETSI.TPUDL;
3919 // req[]=ETSI.TPPID;
3920 for(i=0;i<*length;i++)
3921 req[i+31+offset]=ETSI.MessageText[i];
3923 req[24+offset+i]=ETSI.DeliveryDateTime[i];
3929 *length=*length+offset;
3934 void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3936 switch (MessageBuffer[3]) {
3938 /* SMS message correctly sent to the network */
3941 fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
3943 CurrentSMSMessageError = GE_SMSSENDOK;
3946 /* SMS message send to the network failed */
3950 fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
3952 switch (MessageBuffer[6]) {
3953 case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3954 case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
3955 case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3956 case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
3957 case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3958 case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3959 case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3960 case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3961 case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3964 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
3965 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
3968 CurrentSMSMessageError = GE_SMSSENDFAILED;
3974 GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
3978 unsigned char req[256] = {
3980 0x01, 0x02, 0x00, /* SMS send request*/
3985 error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
3986 if (error != GE_NONE) return error;
3988 return NULL_SendMessageSequence
3989 (200, &CurrentSMSMessageError, 42+length, 0x02, req);
3992 void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3994 switch (MessageBuffer[3]) {
3999 fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
4002 CurrentSMSMessage->MessageNumber=MessageBuffer[5];
4004 CurrentSMSMessageError = GE_NONE;
4009 fprintf(stdout, _("SMS saving failed\n"));
4010 switch (MessageBuffer[4]) {
4011 case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
4012 case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
4013 default :fprintf(stdout, _(" Unknown error.\n"));break;
4017 switch (MessageBuffer[4]) {
4018 case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
4019 case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
4020 default :CurrentSMSMessageError = GE_UNKNOWN;break;
4025 /* GST_DR and GST_UN not supported ! */
4026 GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
4028 unsigned char req[256] = {
4029 N6110_FRAME_HEADER, 0x04, /* SMS save request*/
4030 0x00, /* SMS Status. Different for Inbox and Outbox */
4032 0x00, /* SMS Location */
4033 0x02, /* SMS Type */
4037 SMS_MessageType PDU;
4040 if (SMS->Location) req[6] = SMS->Location;
4042 if (SMS->folder==0) { /*Inbox*/
4043 req[4]=1; /* SMS Status */
4044 req[7] = 0x00; /* SMS Type */
4047 req[4]=5; /* SMS Status */
4048 req[7] = 0x02; /* SMS Type */
4052 if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
4054 error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
4055 if (error != GE_NONE) return error;
4057 CurrentSMSMessage = SMS;
4059 return NULL_SendMessageSequence
4060 (70, &CurrentSMSMessageError, 39+length, 0x14, req);
4063 void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4066 fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
4069 CurrentCBError = GE_NONE;
4072 /* Enable and disable Cell Broadcasting */
4073 GSM_Error N6110_EnableCellBroadcast(void)
4075 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4076 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
4079 fprintf (stdout,"Enabling CB\n");
4082 CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
4083 CurrentCBMessage->Channel = 0;
4084 CurrentCBMessage->New = false;
4085 strcpy (CurrentCBMessage->Message,"");
4087 return NULL_SendMessageSequence
4088 (10, &CurrentCBError, 10, 0x02, req);
4092 GSM_Error N6110_DisableCellBroadcast(void)
4094 /* Should work, but not tested fully */
4096 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4097 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
4099 return NULL_SendMessageSequence
4100 (10, &CurrentCBError, 10, 0x02, req);
4103 void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4106 unsigned char output[160];
4108 CurrentCBMessage->Channel = MessageBuffer[7];
4109 CurrentCBMessage->New = true;
4110 tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
4113 fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
4115 fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
4119 for (i=0; i<tmp;i++) {
4120 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
4123 fprintf(stdout, "\n");
4126 for (i=0; i<tmp; i++) {
4127 CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
4129 CurrentCBMessage->Message[i]=0;
4132 GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
4135 fprintf(stdout,"Reading CB\n");
4138 if (CurrentCBMessage != NULL)
4140 if (CurrentCBMessage->New == true)
4143 fprintf(stdout,"New CB received\n");
4145 Message->Channel = CurrentCBMessage->Channel;
4146 strcpy(Message->Message,CurrentCBMessage->Message);
4147 CurrentCBMessage->New = false;
4151 return (GE_NONEWCBRECEIVED);
4154 int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
4158 req[count++]=Bitmap.number;
4159 req[count++]=strlen(Bitmap.text);
4160 memcpy(req+count,Bitmap.text,req[count-1]);
4161 count+=req[count-1];
4162 req[count++]=Bitmap.ringtone;
4164 /* Setting for graphic:
4167 0x02 - View Graphics
4168 0x03 - Send Graphics
4170 You can even set it higher but Nokia phones (my
4171 6110 at least) will not show you the name of this
4172 item in menu ;-)) Nokia is really joking here. */
4173 if (Bitmap.enabled) req[count++]=0x01;
4174 else req[count++]=0x00;
4176 req[count++]=(Bitmap.size+4)>>8;
4177 req[count++]=(Bitmap.size+4)%0xff;
4178 req[count++]=0x00; /* Future extensions! */
4179 req[count++]=Bitmap.width;
4180 req[count++]=Bitmap.height;
4181 req[count++]=0x01; /* Just BW */
4182 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4184 return count+Bitmap.size;
4187 int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4191 EncodeNetworkCode(req+count, Bitmap.netcode);
4194 req[count++]=(Bitmap.size+4)>>8;
4195 req[count++]=(Bitmap.size+4)%0xff;
4196 req[count++]=0x00; /* Infofield */
4197 req[count++]=Bitmap.width;
4198 req[count++]=Bitmap.height;
4199 req[count++]=0x01; /* Just BW */
4200 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4202 return count+Bitmap.size;
4205 int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4210 req[count++]=Bitmap.height;
4211 req[count++]=Bitmap.width;
4212 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4214 return count+Bitmap.size;
4217 /* Set a bitmap or welcome-note */
4218 GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
4220 unsigned char req[600] = { N6110_FRAME_HEADER };
4226 /* Direct uploading variables */
4227 GSM_MultiSMSMessage SMS;
4228 unsigned char buffer[1000] = {0x0c,0x01};
4229 GSM_NetworkInfo NetworkInfo;
4233 /* Uploading with preview */
4234 if (Bitmap->number==255 &&
4235 (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
4236 GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
4237 memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
4239 memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
4241 buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
4243 Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
4245 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4246 return GE_NONE; //no answer from phone
4249 CurrentSetBitmapError = GE_BUSY;
4251 switch (Bitmap->type) {
4252 case GSM_WelcomeNoteText:
4253 case GSM_DealerNoteText:
4255 req[count++]=0x01; /* Only one block */
4257 if (Bitmap->type==GSM_WelcomeNoteText)
4258 req[count++]=0x02; /* Welcome text */
4260 req[count++]=0x03; /* Dealer Welcome Note */
4262 textlen=strlen(Bitmap->text);
4263 req[count++]=textlen;
4264 memcpy(req+count,Bitmap->text,textlen);
4268 Protocol->SendMessage(count, 0x05, req);
4272 case GSM_StartupLogo:
4273 if (Bitmap->number==0) {
4275 /* For 33xx we first set animated logo to default */
4276 if (GetModelFeature (FN_STARTUP)==F_STANIM) {
4277 error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4278 if (error!=GE_NONE) return error;
4282 req[count++]=0x01; /* Only one block */
4283 count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
4284 Protocol->SendMessage(count, 0x05, req);
4286 return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4290 case GSM_OperatorLogo:
4291 req[count++]=0x30; /* Store Op Logo */
4292 req[count++]=0x01; /* Location */
4293 count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
4294 Protocol->SendMessage(count, 0x05, req);
4297 case GSM_CallerLogo:
4299 count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
4300 Protocol->SendMessage(count, 0x03, req);
4303 case GSM_PictureImage:
4305 req[count++]=Bitmap->number;
4306 if (strcmp(Bitmap->Sender,"")) {
4307 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
4309 /* Convert number of semioctets to number of chars and add count */
4311 if (textlen % 2) textlen++;
4312 count+=textlen / 2 + 1;
4320 req[count++]=strlen(Bitmap->text);
4321 memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
4322 count+=strlen(Bitmap->text);
4324 req[count++]=Bitmap->width;
4325 req[count++]=Bitmap->height;
4327 memcpy(req+count,Bitmap->bitmap,Bitmap->size);
4328 Protocol->SendMessage(count+Bitmap->size, 0x47, req);
4331 case GSM_7110OperatorLogo:
4332 case GSM_7110StartupLogo:
4333 case GSM_6210StartupLogo:
4334 return GE_NOTSUPPORTED;
4340 /* Wait for timeout or other error. */
4341 while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
4344 return (GE_TIMEOUT);
4349 return CurrentSetBitmapError;
4352 /* Get a bitmap from the phone */
4353 GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
4355 unsigned char req[10] = { N6110_FRAME_HEADER };
4360 CurrentGetBitmap=Bitmap;
4361 CurrentGetBitmapError = GE_BUSY;
4363 switch (CurrentGetBitmap->type) {
4364 case GSM_StartupLogo:
4365 case GSM_WelcomeNoteText:
4366 case GSM_DealerNoteText:
4368 Protocol->SendMessage(count, 0x05, req);
4370 case GSM_OperatorLogo:
4372 req[count++]=0x01; /* Location 1 */
4373 Protocol->SendMessage(count, 0x05, req);
4375 case GSM_CallerLogo:
4377 req[count++]=Bitmap->number;
4378 Protocol->SendMessage(count, 0x03, req);
4380 case GSM_PictureImage:
4382 req[count++]=Bitmap->number;
4383 Protocol->SendMessage(count, 0x47, req);
4385 case GSM_7110OperatorLogo:
4386 case GSM_7110StartupLogo:
4387 case GSM_6210StartupLogo:
4389 return GE_NOTSUPPORTED;
4392 /* Wait for timeout or other error. */
4393 while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
4396 return (GE_TIMEOUT);
4401 CurrentGetBitmap=NULL;
4403 return CurrentGetBitmapError;
4406 void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4408 switch (MessageBuffer[3]) {
4410 /* Set ringtone OK */
4413 fprintf(stdout, _("Message: Ringtone set OK!\n"));
4415 CurrentRingtoneError=GE_NONE;
4418 /* Set ringtone error */
4421 fprintf(stdout, _("Message: Ringtone setting error !\n"));
4423 CurrentRingtoneError=GE_NOTSUPPORTED;
4428 GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
4431 char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
4432 {N6110_FRAME_HEADER,
4434 0x00, /* Location */
4437 int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
4439 /* Variables for preview uploading */
4440 unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
4441 unsigned char buffer2[20];
4442 GSM_NetworkInfo NetworkInfo;
4444 /* Setting ringtone with preview */
4445 if (ringtone->location==255) {
4448 EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
4449 memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
4450 *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
4451 Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
4452 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4454 return GE_NONE; //no answer from phone
4457 *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
4459 req[4]=ringtone->location-1;
4461 return NULL_SendMessageSequence
4462 (50, &CurrentRingtoneError, (size+7), 0x05, req);
4465 void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4469 switch (MessageBuffer[4]) {
4470 case 0x00: /* location supported. We have ringtone */
4472 /* Binary format used in N6150 */
4473 if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4475 fprintf(stdout,_("Message: ringtone \""));
4482 if (MessageBuffer[i]!=0)
4483 fprintf(stdout,_("%c"),MessageBuffer[i]);
4485 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4486 if (MessageBuffer[i]==0) break;
4491 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4494 /* Looking for end */
4497 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4500 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4504 if (i==MessageLength) break;
4508 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4509 CurrentGetBinRingtone->length=i-3;
4511 CurrentBinRingtoneError=GE_NONE;
4515 /* Binary format used in N3210 */
4516 if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4519 fprintf(stdout,_("Message: ringtone \""));
4526 if (MessageBuffer[i]!=0)
4527 fprintf(stdout,_("%c"),MessageBuffer[i]);
4529 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4530 if (MessageBuffer[i]==0) break;
4535 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4538 /* Here changes to get full compatibility with binary format used in N6150 */
4541 MessageBuffer[5]=0x0c;
4542 MessageBuffer[6]=0x01;
4543 MessageBuffer[7]=0x2c;
4545 /* Looking for end */
4548 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4551 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4555 if (i==MessageLength) break;
4559 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4561 CurrentGetBinRingtone->length=i-3;
4563 CurrentBinRingtoneError=GE_NONE;
4568 memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
4570 CurrentGetBinRingtone->length=MessageLength;
4573 fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
4575 CurrentBinRingtoneError=GE_UNKNOWNMODEL;
4581 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4584 CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
4588 GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
4590 unsigned char req[] = { 0x00,0x01,0x9e,
4595 CurrentGetBinRingtone=ringtone;
4597 error=N6110_EnableExtendedCommands(0x01);
4598 if (error!=GE_NONE) return error;
4600 req[3]=ringtone->location-1;
4602 return NULL_SendMessageSequence
4603 (50, &CurrentBinRingtoneError, 4, 0x40, req);
4606 void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4608 switch (MessageBuffer[4]) {
4609 case 0x00: /* location supported. We set ringtone */
4611 fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
4613 CurrentBinRingtoneError=GE_NONE;
4618 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4620 CurrentBinRingtoneError=GE_NOTSUPPORTED;
4625 GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
4627 unsigned char req[1000] = { 0x00,0x01,0xa0};
4631 GSM_BinRingtone ring;
4633 /* Must be sure, that can upload ringtone to this phone */
4634 ring.location=ringtone->location;
4635 error=N6110_GetBinRingTone(&ring);
4636 if (error!=GE_NONE) return error;
4638 error=N6110_EnableExtendedCommands(0x01);
4639 if (error!=GE_NONE) return error;
4641 memcpy(req+3,ringtone->frame,ringtone->length);
4643 req[3]=ringtone->location-1;
4645 return NULL_SendMessageSequence
4646 (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
4649 #endif /* UCLINUX */
4651 GSM_Error N6110_Reset(unsigned char type)
4653 return N6110_EnableExtendedCommands(type);
4656 void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4663 switch (MessageBuffer[3]) {
4665 /* Unknown message - it has been seen after the 0x07 message (call
4666 answered). Probably it has similar meaning. If you can solve
4667 this - just mail me. Pavel JanÃk ml.
4669 The message looks like this:
4677 Phone: [01 ][08 ][00 ] is the header of the frame
4679 [03 ] is the call message subtype
4681 [05 ] is the call sequence number
4685 [00 ][01 ][03 ][02 ][91][00] are unknown but has been
4686 seen in the Incoming call message (just after the
4687 caller's name from the phonebook). But never change
4688 between phone calls :-(
4691 /* This may mean sequence number of 'just made' call - CK */
4695 fprintf(stdout, _("Message: Call message, type 0x02:"));
4696 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4701 /* Possibly call OK */
4702 /* JD: I think that this means "call in progress" (incomming or outgoing) */
4706 fprintf(stdout, _("Message: Call message, type 0x03:"));
4707 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4708 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4711 CurrentCallSequenceNumber=MessageBuffer[4];
4713 CurrentIncomingCall[0]='D';
4714 #endif /* UCLINUX */
4715 if (CurrentCallPassup) CurrentCallPassup('D');
4719 /* Remote end has gone away before you answer the call. Probably your
4720 mother-in-law or banker (which is worse?) ... */
4724 fprintf(stdout, _("Message: Remote end hang up.\n"));
4725 fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
4727 switch (MessageBuffer[6]) {
4728 case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
4729 case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
4730 case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
4731 case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4732 case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
4733 case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4736 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
4737 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4741 CurrentIncomingCall[0] = ' ';
4742 #endif /* UCLINUX */
4743 if (CurrentCallPassup) CurrentCallPassup(' ');
4747 /* Incoming call alert */
4751 fprintf(stdout, _("Message: Incoming call alert:\n"));
4753 /* We can have more then one call ringing - we can distinguish between
4756 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4757 fprintf(stdout, _(" Number: "));
4759 count=MessageBuffer[6];
4761 for (tmp=0; tmp <count; tmp++)
4762 fprintf(stdout, "%c", MessageBuffer[7+tmp]);
4764 fprintf(stdout, "\n");
4766 fprintf(stdout, _(" Name: "));
4768 for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
4769 fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
4771 fprintf(stdout, "\n");
4774 count=MessageBuffer[6];
4777 CurrentIncomingCall[0] = 0;
4778 for (tmp=0; tmp <count; tmp++)
4779 sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
4780 #endif /* UCLINUX */
4784 /* Call answered. Probably your girlfriend...*/
4788 fprintf(stdout, _("Message: Call answered.\n"));
4789 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4794 /* Call ended. Girlfriend is girlfriend, but time is money :-) */
4798 fprintf(stdout, _("Message: Call ended by your phone.\n"));
4799 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4804 /* This message has been seen with the message of subtype 0x09
4805 after I hang the call.
4812 Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
4814 What is the meaning of 87? Can you spell some magic light into
4819 /* Probably means call over - CK */
4823 fprintf(stdout, _("Message: Call message, type 0x0a:"));
4824 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4825 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4829 CurrentIncomingCall[0] = ' ';
4830 #endif /* UCLINUX */
4831 if (CurrentCallPassup) CurrentCallPassup(' ');
4838 fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
4842 if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
4843 #endif /* UCLINUX */
4845 if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
4852 fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
4854 AppendLogText("Unknown msg\n",false);
4856 break; /* Visual C Don't like empty cases */
4862 static void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4866 switch (MessageBuffer[3]) {
4870 /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
4871 /* If you want see, if it works with your phone make something like that: */
4873 /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
4874 /* Protocol->SendMessage(4, 0x04, connect5); */
4876 /* Marcin-Wiacek@TopNet.PL */
4878 #if defined(WIN32) || defined(UCLINUX)
4879 sprintf(Current_IMEI, "%s", MessageBuffer+5);
4880 sprintf(Current_Model, "%s", MessageBuffer+21);
4881 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4883 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
4884 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
4885 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4889 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
4890 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
4891 fprintf(stdout, _(" Model: %s\n"), Current_Model);
4892 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
4893 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
4894 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
4899 /* Get group data */
4900 /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
4903 if (CurrentGetBitmap!=NULL) {
4904 if (CurrentGetBitmap->number==MessageBuffer[4]) {
4905 count=MessageBuffer[5];
4906 memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
4907 CurrentGetBitmap->text[count]=0;
4910 fprintf(stdout, _("Message: Caller group datas\n"));
4911 fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
4916 CurrentGetBitmap->ringtone=MessageBuffer[count++];
4918 fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
4919 if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
4920 fprintf(stdout,_("\n"));
4923 CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
4925 fprintf(stdout, _("Caller group logo "));
4926 if (CurrentGetBitmap->enabled)
4927 fprintf(stdout, _("enabled \n"));
4929 fprintf(stdout, _("disabled \n"));
4932 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4933 CurrentGetBitmap->size+=MessageBuffer[count++];
4935 fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
4939 CurrentGetBitmap->width=MessageBuffer[count++];
4940 CurrentGetBitmap->height=MessageBuffer[count++];
4942 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
4943 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4944 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
4945 CurrentGetBitmapError=GE_NONE;
4948 fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
4953 fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
4958 /* Get group data error */
4961 CurrentGetBitmapError=GE_UNKNOWN;
4963 fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
4967 /* Set group data OK */
4970 CurrentSetBitmapError=GE_NONE;
4972 fprintf(stdout, _("Message: Caller group data set correctly.\n"));
4976 /* Set group data error */
4979 CurrentSetBitmapError=GE_UNKNOWN;
4981 fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
4988 fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
4990 AppendLogText("Unknown msg\n",false);
4992 break; /* Visual C Don't like empty cases */
4996 static void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4998 int tmp, count, length;
5005 switch (MessageBuffer[3]) {
5011 fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
5014 if (CurrentGetBitmap!=NULL) {
5020 for (tmp=0;tmp<MessageBuffer[4];tmp++){
5021 switch (MessageBuffer[count++]) {
5023 if (CurrentGetBitmap->type==GSM_StartupLogo) {
5024 CurrentGetBitmap->height=MessageBuffer[count++];
5025 CurrentGetBitmap->width=MessageBuffer[count++];
5026 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5027 length=CurrentGetBitmap->size;
5028 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
5030 length=MessageBuffer[count++];
5031 length=length*MessageBuffer[count++]/8;
5035 fprintf(stdout, _("Startup logo supported - "));
5036 if (length!=0) { fprintf(stdout, _("currently set\n")); }
5037 else { fprintf(stdout, _("currently empty\n")); }
5039 if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
5042 length=MessageBuffer[count];
5043 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
5044 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5045 CurrentGetBitmap->text[length]=0;
5048 fprintf(stdout, _("Startup Text supported - "));
5051 fprintf(stdout, _("currently set to \""));
5052 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5053 fprintf(stdout, _("\"\n"));
5055 fprintf(stdout, _("currently empty\n"));
5059 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
5062 length=MessageBuffer[count];
5063 if (CurrentGetBitmap->type==GSM_DealerNoteText) {
5064 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5065 CurrentGetBitmap->text[length]=0;
5068 fprintf(stdout, _("Dealer Welcome supported - "));
5071 fprintf(stdout, _("currently set to \""));
5072 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5073 fprintf(stdout, _("\"\n"));
5075 fprintf(stdout, _("currently empty\n"));
5079 if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
5083 if (issupported) CurrentGetBitmapError=GE_NONE;
5084 else CurrentGetBitmapError=GE_NOTSUPPORTED;
5087 fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
5092 /* Set startup OK */
5095 CurrentSetBitmapError=GE_NONE;
5097 fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
5101 /* Set Operator Logo OK */
5105 fprintf(stdout, _("Message: Operator logo correctly set.\n"));
5108 CurrentSetBitmapError=GE_NONE;
5111 /* Set Operator Logo Error */
5115 fprintf(stdout, _("Message: Error setting operator logo!\n"));
5118 CurrentSetBitmapError=GE_UNKNOWN;
5122 /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
5125 if (CurrentGetBitmap!=NULL) {
5127 count=5; /* Location ignored. */
5129 DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
5133 fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
5134 CurrentGetBitmap->netcode,
5135 GSM_GetNetworkName(CurrentGetBitmap->netcode));
5138 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
5139 CurrentGetBitmap->size+=MessageBuffer[count++];
5141 CurrentGetBitmap->width=MessageBuffer[count++];
5142 CurrentGetBitmap->height=MessageBuffer[count++];
5144 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5145 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
5146 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
5147 CurrentGetBitmapError=GE_NONE;
5150 fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
5156 /* Get op logo error */
5160 fprintf(stdout, _("Message: Error getting operator logo!\n"));
5162 CurrentGetBitmapError=GE_UNKNOWN;
5168 fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
5170 AppendLogText("Unknown msg\n",false);
5176 static void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5179 unsigned char output[160];
5185 switch (MessageBuffer[3]) {
5189 /* MessageBuffer[3] = 0x05
5190 MessageBuffer[4] = 0x00
5191 MessageBuffer[5] = 0x0f
5192 MessageBuffer[6] = 0x03
5193 MessageBuffer[7] = length of packed message
5195 This is all I have seen - Gerry Anderson */
5197 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
5201 fprintf(stdout, _("Message from Network operator: "));
5203 for (i=0; i<tmp; i++)
5204 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
5206 fprintf(stdout, "\n");
5215 fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
5217 AppendLogText("Unknown msg\n",false);
5223 #endif /* UCLINUX */
5225 static void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5227 switch (MessageBuffer[3]) {
5231 fprintf(stdout, _("Message: SIM card login\n"));
5237 fprintf(stdout, _("Message: SIM card logout\n"));
5243 fprintf(stdout, _("Unknown message of type 0x09.\n"));
5245 AppendLogText("Unknown msg\n",false);
5252 static void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5254 switch(MessageBuffer[3]) {
5259 fprintf(stdout, _("Message: Calendar Alarm active\n"));
5260 fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
5265 fprintf(stdout, _("Unknown message of type 0x13.\n"));
5267 AppendLogText("Unknown msg\n",false);
5272 #endif /* UCLINUX */
5274 void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5278 switch(MessageBuffer[2]) {
5283 fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
5286 CurrentMagicError=GE_NONE;
5292 fprintf(stdout, _("Message: Answer for call commands.\n"));
5295 CurrentDialVoiceError=GE_NONE;
5301 fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
5304 CurrentMagicError=GE_NONE;
5310 fprintf(stdout, _("Message: ACK for simlock closing\n"));
5313 CurrentMagicError=GE_NONE;
5318 switch (MessageBuffer[5]) {
5321 fprintf(stdout,_("Message: EEPROM contest received\n"));
5324 if (MessageBuffer[8]!=0x00) {
5325 for (i=9;i<MessageLength;i++) {
5326 fprintf(stdout,_("%c"), MessageBuffer[i]);
5329 CurrentMagicError=GE_NONE;
5336 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5338 AppendLogText("Unknown msg\n",false);
5344 N6110_DisplayTestsInfo(MessageBuffer);
5346 #endif /* UCLINUX */
5351 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5353 AppendLogText("Unknown msg\n",false);
5354 break; /* Visual C Don't like empty cases */
5360 static void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5364 switch(MessageBuffer[3]) {
5370 if (MessageBuffer[5]!=0) {
5371 strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
5373 while (MessageBuffer[count]!=0) {
5379 strcpy(CurrentGetBitmap->Sender,"\0");
5384 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
5385 CurrentGetBitmap->text[MessageBuffer[count]]=0;
5387 if (MessageBuffer[count]!=0)
5388 count+=MessageBuffer[count];
5393 fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
5396 CurrentGetBitmap->width=MessageBuffer[count+1];
5397 CurrentGetBitmap->height=MessageBuffer[count+2];
5398 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5400 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
5402 CurrentGetBitmapError=GE_NONE;
5408 fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
5410 CurrentSetBitmapError=GE_NONE;
5411 CurrentGetBitmapError=GE_NONE;
5417 fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
5419 CurrentSetBitmapError=GE_UNKNOWN;
5425 fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
5427 CurrentGetBitmapError=GE_UNKNOWN;
5433 fprintf(stdout, _("Unknown message of type 0x47.\n"));
5435 AppendLogText("Unknown msg\n",false);
5436 break; /* Visual C Don't like empty cases */
5440 #endif /* UCLINUX */
5442 void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5445 sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
5446 AppendLog(buffer,strlen(buffer),false);
5449 fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
5453 CurrentLinkOK = true;
5456 static void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5459 fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
5464 /* This function is used for parsing the RLP frame into fields. */
5465 void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
5472 /* We do not need RLP frame parsing to be done when we do not have callback
5474 if (CurrentRLP_RXCallback == NULL)
5477 /* Anybody know the official meaning of the first two bytes?
5478 Nokia 6150 sends junk frames starting D9 01, and real frames starting
5479 D9 00. We'd drop the junk frames anyway because the FCS is bad, but
5480 it's tidier to do it here. We still need to call the callback function
5481 to give it a chance to handle timeouts and/or transmit a frame */
5482 if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
5485 /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
5486 specification, so Header consists of 16 bits (2 bytes). See section 4.1
5487 of the specification. */
5489 frame.Header[0] = MessageBuffer[2];
5490 frame.Header[1] = MessageBuffer[3];
5492 /* Next 200 bits (25 bytes) contain the Information. We store the
5493 information in the Data array. */
5495 for (count = 0; count < 25; count ++)
5496 frame.Data[count] = MessageBuffer[4 + count];
5498 /* The last 24 bits (3 bytes) contain FCS. */
5500 frame.FCS[0] = MessageBuffer[29];
5501 frame.FCS[1] = MessageBuffer[30];
5502 frame.FCS[2] = MessageBuffer[31];
5504 /* Here we pass the frame down in the input stream. */
5505 CurrentRLP_RXCallback(valid ? &frame : NULL);
5508 static void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5511 fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
5518 void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5520 GSM_SMSMessage NullSMS;
5522 switch (MessageBuffer[6]) {
5524 case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
5525 case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
5527 /* Is it possible ? */
5528 case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
5529 default: NullSMS.Type = GST_UN; break;
5533 if (NullSMS.Type == GST_DR)
5534 fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
5536 fprintf(stdout, _("Message: SMS Message Received\n"));
5539 GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
5542 fprintf(stdout, _("\n"));
5546 #endif /* UCLINUX */
5548 void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5552 /* Switch on the basis of the message type byte */
5553 switch (MessageType) {
5555 /* Call information */
5558 N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
5564 switch (MessageBuffer[3]) {
5566 case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5567 case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
5568 case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5569 case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5570 case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5572 case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5573 default :unknown=true;break;
5576 #endif /* UCLINUX */
5578 /* Phonebook handling */
5580 switch (MessageBuffer[3]) {
5582 case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
5584 case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
5586 case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
5589 case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5591 case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5592 default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
5593 #endif /* UCLINUX */
5599 switch (MessageBuffer[3]) {
5600 case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
5601 default :unknown=true;break;
5606 /* Startup Logo, Operator Logo and Profiles. */
5608 switch (MessageBuffer[3]) {
5609 case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5610 case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5611 case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5612 case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5613 case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5614 case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5615 default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
5619 /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
5622 switch (MessageBuffer[3]) {
5624 case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
5625 default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
5629 /* Security code requests */
5631 switch (MessageBuffer[3]) {
5632 case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
5633 case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5634 default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5637 #endif /* UCLINUX */
5642 N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
5648 switch (MessageBuffer[3]) {
5649 case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
5650 default :unknown=true;break;
5654 /* Simulating key pressing */
5656 switch (MessageBuffer[3]) {
5657 case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
5658 default :unknown=true;break;
5664 switch (MessageBuffer[3]) {
5665 case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5666 case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
5667 case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5668 default :unknown=true;break;
5672 /* Phone Clock and Alarm */
5674 switch (MessageBuffer[3]) {
5675 case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
5676 case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
5677 case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
5678 case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
5679 default :unknown=true;break;
5683 /* Calendar notes handling */
5685 switch (MessageBuffer[3]) {
5686 case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5687 case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5688 case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
5689 default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
5695 switch (MessageBuffer[3]) {
5697 case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5699 case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5700 case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5702 case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
5703 default :unknown=true;break;
5709 switch (MessageBuffer[3]) {
5711 case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
5713 case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5715 case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5718 case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
5719 default :unknown=true;break;
5722 #endif /* UCLINUX */
5724 /* Internal phone functions? */
5726 switch (MessageBuffer[2]) {
5727 case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
5729 case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
5730 #endif /* UCLINUX */
5731 case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
5733 case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5734 case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5735 case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5736 case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
5737 case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
5738 case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5739 case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5740 case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
5741 case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5742 case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5743 #endif /* UCLINUX */
5744 case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
5745 default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
5750 /* Picture Images */
5753 N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
5755 #endif /* UCLINUX */
5757 /* Mobile phone identification */
5760 N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
5763 /***** Acknowlegment of our frames. *****/
5764 case FBUS_FRTYPE_ACK:
5766 N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
5769 /***** Power on message. *****/
5772 N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
5777 N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
5780 /***** RLP frame received. *****/
5783 N6110_RX_HandleRLPMessage(MessageBuffer);
5786 /***** Power on message. *****/
5789 N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
5792 /***** Unknown message *****/
5793 /* If you think that you know the exact meaning of other messages - please
5798 fprintf(stdout, _("Message: Unknown message type.\n"));
5800 AppendLogText("Unknown msg type\n",false);
5809 fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
5811 AppendLogText("Unknown msg\n",false);