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,
59 N6110_GetMemoryStatus,
65 N6110_DeleteSMSMessage,
78 N6110_GetBatteryLevel,
81 N6110_GetDisplayStatus,
82 N6110_EnterSecurityCode,
83 N6110_GetSecurityCodeStatus,
84 N6110_GetSecurityCode,
109 N6110_GetIncomingCallNr,
110 N6110_GetNetworkInfo,
111 N6110_GetCalendarNote,
112 N6110_WriteCalendarNote,
113 N6110_DeleteCalendarNote,
119 N6110_SetBinRingTone,
120 N6110_GetBinRingTone,
148 N6110_EnableDisplayOutput,
149 N6110_DisableDisplayOutput,
150 N6110_EnableCellBroadcast,
151 N6110_DisableCellBroadcast,
152 N6110_ReadCellBroadcast,
154 N6110_GetProductProfileSetting,
155 N6110_SetProductProfileSetting,
156 N6110_GetOperatorName,
157 N6110_SetOperatorName,
158 N6110_GetVoiceMailbox, N6110_Tests,
160 UNIMPLEMENTED, //GetCalendarNotesInfo
162 N6110_ResetPhoneSettings,
163 N7110_GetWAPBookmark,
164 N7110_SetWAPBookmark,
165 N7110_GetWAPSettings,
182 NULL, //GetCalendarNotesInfo
191 N6110_GetManufacturer
194 /* Mobile phone information */
196 GSM_Information N6110_Information = {
197 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
198 /* Supported models in FBUS */
199 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
200 /* Supported models in MBUS */
201 "6110|6130|6150|8210|8850",
202 /* Supported models in FBUS over infrared */
204 /* Supported models in FBUS over DLR3 */
208 /* infrared sockets */
209 "6110|6130|6150|8210|8850",
210 /* Supported models in FBUS over infrared with Tekram device */
211 4, /* Max RF Level */
212 0, /* Min RF Level */
213 GRF_Arbitrary, /* RF level units */
214 4, /* Max Battery Level */
215 0, /* Min Battery Level */
216 GBU_Arbitrary, /* Battery level units */
217 GDT_DateTime, /* Have date/time support */
218 GDT_TimeOnly, /* Alarm supports time only */
219 1 /* Only one alarm available */
223 static const char *N6110_MemoryType_String [] = {
237 /* Magic bytes from the phone. */
238 static unsigned char MagicBytes[4] = { 0x00, 0x00, 0x00, 0x00 };
240 /* For DisplayOutput */
242 static char PhoneScreen[5+1][27+1];
243 static int OldX=1000,OldY=0,NewX=0,NewY=0;
246 void N6110_ReplyEnableExtendedCommands(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
249 fprintf(stdout, _("Message: Answer for EnableExtendedSecurityCommands frame, meaning not known :-(\n"));
252 CurrentEnableExtendedCommandsError=GE_NONE;
255 /* If you set make some things (for example,
256 change Security Code from phone's menu, disable and enable
257 phone), it won't answer for 0x40 frame - you won't be able
258 to play tones, get netmonitor, etc.
260 This function do thing called "Enabling extended security commands" -
261 it enables 0x40 frame functions.
263 This frame can also some other things - see below */
264 GSM_Error N6110_EnableExtendedCommands (unsigned char status)
266 unsigned char req[4] = { 0x00,
267 0x01,0x64, /* Enable extended commands request */
268 0x01 }; /* 0x01 - on, 0x00 - off,
269 0x03 & 0x04 - soft & hard reset,
270 0x06 - CONTACT SERVICE */
272 /* 0x06 MAKES CONTACT SERVICE! BE CAREFULL! */
273 /* When use 0x03 and had during session changed time & date
274 some phones (like 6150 or 6210) can ask for time & date after reset
275 or disable clock on the screen */
276 if (status!=0x06) req[3] = status;
278 return NULL_SendMessageSequence
279 (50, &CurrentEnableExtendedCommandsError, 4, 0x40, req);
282 void N6110_ReplyIMEI(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
284 #if defined WIN32 || !defined HAVE_SNPRINTF
285 sprintf(Current_IMEI, "%s", MessageBuffer+4);
287 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+4);
291 fprintf(stdout, _("Message: IMEI %s received\n"),Current_IMEI);
294 CurrentGetIMEIError=GE_NONE;
297 GSM_Error N6110_SendIMEIFrame()
299 unsigned char req[4] = {0x00, 0x01, 0x66, 0x00};
303 error=N6110_EnableExtendedCommands(0x01);
304 if (error!=GE_NONE) return error;
306 return NULL_SendMessageSequence (20, &CurrentGetIMEIError, 4, 0x40, req);
309 void N6110_ReplyHW(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
313 if (MessageBuffer[3]==0x05) {
316 fprintf(stdout,_("Message: Hardware version received: "));
319 j=strlen(Current_Revision);
320 Current_Revision[j++]=',';
321 Current_Revision[j++]=' ';
322 Current_Revision[j++]='H';
323 Current_Revision[j++]='W';
327 fprintf(stdout,_("%c"), MessageBuffer[i]);
329 Current_Revision[j++]=MessageBuffer[i];
333 fprintf(stdout,_("\n"));
336 CurrentGetHWError=GE_NONE;
340 GSM_Error N6110_SendHWFrame()
342 unsigned char req[4] = {0x00, 0x01, 0xc8, 0x05};
346 error=N6110_EnableExtendedCommands(0x01);
347 if (error!=GE_NONE) return error;
349 return NULL_SendMessageSequence (20, &CurrentGetHWError, 4, 0x40, req);
352 void N6110_ReplyID(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
357 fprintf(stdout, _("Message: Mobile phone model identification received:\n"));
358 fprintf(stdout, _(" Firmware: "));
361 strcpy(Current_Revision,"SW");
364 while (MessageBuffer[i]!=0x0a) {
365 Current_Revision[j]=MessageBuffer[i];
367 fprintf(stdout, _("%c"),MessageBuffer[i]);
369 if (j==GSM_MAX_REVISION_LENGTH-1) {
371 fprintf(stderr,_("ERROR: increase GSM_MAX_REVISION_LENGTH!\n"));
378 Current_Revision[j+1]=0;
381 fprintf(stdout, _("\n Firmware date: "));
385 while (MessageBuffer[i]!=0x0a) {
387 fprintf(stdout, _("%c"),MessageBuffer[i]);
393 fprintf(stdout, _("\n Model: "));
397 while (MessageBuffer[i]!=0x0a) {
398 Current_Model[j]=MessageBuffer[i];
400 fprintf(stdout, _("%c"),MessageBuffer[i]);
402 if (j==GSM_MAX_MODEL_LENGTH-1) {
404 fprintf(stderr,_("ERROR: increase GSM_MAX_MODEL_LENGTH!\n"));
411 Current_Model[j+1]=0;
414 fprintf(stdout, _("\n"));
417 CurrentMagicError=GE_NONE;
420 GSM_Error N6110_SendIDFrame()
422 unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
424 return NULL_SendMessageSequence (50, &CurrentMagicError, 5, 0xd1, req);
427 /* This function send the status request to the phone. */
428 /* Seems to be ignored in N3210 */
429 GSM_Error N6110_SendStatusRequest(void)
431 unsigned char req[] = {N6110_FRAME_HEADER, 0x01};
433 Protocol->SendMessage(4, 0x04, req);
438 static void N6110_ReplyGetAuthentication(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
440 #if defined WIN32 || !defined HAVE_SNPRINTF
441 sprintf(Current_IMEI, "%s", MessageBuffer+9);
442 sprintf(Current_Model, "%s", MessageBuffer+25);
443 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
445 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+9);
446 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+25);
447 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
451 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
452 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
453 fprintf(stdout, _(" Model: %s\n"), Current_Model);
454 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+31);
455 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+39);
456 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+44);
458 /* These bytes are probably the source of the "Accessory not connected"
459 messages on the phone when trying to emulate NCDS... I hope....
460 UPDATE: of course, now we have the authentication algorithm. */
461 fprintf(stdout, _(" Magic bytes: %02x %02x %02x %02x\n"), MessageBuffer[50], MessageBuffer[51], MessageBuffer[52], MessageBuffer[53]);
464 MagicBytes[0]=MessageBuffer[50];
465 MagicBytes[1]=MessageBuffer[51];
466 MagicBytes[2]=MessageBuffer[52];
467 MagicBytes[3]=MessageBuffer[53];
469 CurrentMagicError=GE_NONE;
472 /* This function provides Nokia authentication protocol.
474 This code is written specially for gnokii project by Odinokov Serge.
475 If you have some special requests for Serge just write him to
476 apskaita@post.omnitel.net or serge@takas.lt
478 Reimplemented in C by Pavel JanÃk ml.
480 Nokia authentication protocol is used in the communication between Nokia
481 mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software,
482 commercially sold by Nokia Corp.
484 The authentication scheme is based on the token send by the phone to the
485 software. The software does it's magic (see the function
486 FB61_GetNokiaAuth()) and returns the result back to the phone. If the
487 result is correct the phone responds with the message "Accessory
488 connected!" displayed on the LCD. Otherwise it will display "Accessory not
489 supported" and some functions will not be available for use.
491 The specification of the protocol is not publicly available, no comment. */
492 static void N6110_GetNokiaAuth(unsigned char *Imei, unsigned char *MagicBytes, unsigned char *MagicResponse)
497 /* This is our temporary working area. */
499 unsigned char Temp[16];
501 /* Here we put FAC (Final Assembly Code) and serial number into our area. */
512 /* And now the TAC (Type Approval Code). */
519 /* And now we pack magic bytes from the phone. */
521 Temp[12] = MagicBytes[0];
522 Temp[13] = MagicBytes[1];
523 Temp[14] = MagicBytes[2];
524 Temp[15] = MagicBytes[3];
526 for (i=0; i<=11; i++)
530 switch (Temp[15] & 0x03) {
537 Temp[i+j] ^= Temp[i+12];
545 Temp[i + j] |= Temp[i + 12];
548 for (i=0; i<=15; i++)
551 for (i=0; i<=15; i++) {
553 switch (Temp[15 - i] & 0x06) {
575 MagicResponse[i] = j;
580 static GSM_Error N6110_Authentication()
582 unsigned char connect1[] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x02};
583 unsigned char connect2[] = {N6110_FRAME_HEADER, 0x20, 0x02};
584 unsigned char connect3[] = {N6110_FRAME_HEADER, 0x0d, 0x01, 0x00, 0x02};
585 unsigned char connect4[] = {N6110_FRAME_HEADER, 0x10};
587 unsigned char magic_connect[] = {N6110_FRAME_HEADER,
590 /* The real magic goes here ... These bytes are filled in with the
591 function N6110_GetNokiaAuth(). */
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596 /* NOKIA&GNOKII Accessory */
598 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x26, 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x20,
599 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x79,
601 0x00, 0x00, 0x00, 0x00};
604 fprintf(stdout,_("Making authentication!\n"));
607 usleep(100); Protocol->SendMessage(7, 0x02, connect1);
608 usleep(100); Protocol->SendMessage(5, 0x02, connect2);
609 usleep(100); Protocol->SendMessage(7, 0x02, connect3);
611 CurrentMagicError = GE_BUSY;
613 usleep(100); Protocol->SendMessage(4, 0x64, connect4);
614 if (NULL_WaitUntil(50,&CurrentMagicError)!=GE_NONE) return GE_TIMEOUT;
616 N6110_GetNokiaAuth(Current_IMEI, MagicBytes, magic_connect+4);
618 Protocol->SendMessage(45, 0x64, magic_connect);
621 fprintf(stdout,_("End of authentication!\n"));
627 /* Initialise variables and state machine. */
628 GSM_Error N6110_Initialise(char *port_device, char *initlength,
629 GSM_ConnectionType connection,
630 void (*rlp_callback)(RLP_F96Frame *frame))
632 unsigned char init_char = N6110_SYNC_BYTE;
634 unsigned char end_init_char = N6110_IR_END_SYNC_BYTE;
640 if (Protocol->Initialise(port_device,initlength,connection,rlp_callback)!=GE_NONE)
642 return GE_NOTSUPPORTED;
645 switch (CurrentConnectionType) {
649 /* We don't think about authentication in Irda, because
650 AFAIK there are no phones working over sockets
651 and having authentication. In MBUS it doesn't work */
654 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
656 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
658 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
660 CurrentLinkOK = true;
669 InitLength = atoi(initlength);
671 if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
672 InitLength = 250; /* This is the usual value, lower may work. */
676 if (CurrentConnectionType==GCT_Infrared ||
677 CurrentConnectionType==GCT_Tekram) {
679 fprintf(stdout,_("Setting infrared for FBUS communication...\n"));
681 device_changespeed(9600);
686 fprintf(stdout,_("Writing init chars...."));
689 /* Initialise link with phone or what have you */
690 /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
692 for (count = 0; count < InitLength; count ++) {
694 if (CurrentConnectionType!=GCT_Infrared &&
695 CurrentConnectionType!=GCT_Tekram)
698 Protocol->WritePhone(1,&init_char);
702 if (CurrentConnectionType==GCT_Infrared ||
703 CurrentConnectionType==GCT_Tekram) {
704 Protocol->WritePhone(1,&end_init_char);
710 fprintf(stdout,_("Done\n"));
714 if (CurrentConnectionType==GCT_Infrared ||
715 CurrentConnectionType==GCT_Tekram) {
716 device_changespeed(115200);
720 N6110_SendStatusRequest();
724 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
726 /* N51xx/61xx have something called authentication.
727 After making it phone display "Accessory connected"
728 and probably give access to some function (I'm not too sure about it !)
729 Anyway, I make it now for N51xx/61xx */
730 if (GetModelFeature (FN_AUTHENTICATION)!=0) {
731 if (N6110_Authentication()!=GE_NONE) return GE_TIMEOUT;
732 } else { /* No authentication */
733 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
735 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
741 fprintf(stdout,_("Unknown connection type in n6110.c!\n"));
749 /* This function translates GMT_MemoryType to N6110_MEMORY_xx */
750 int N6110_GetMemoryType(GSM_MemoryType memory_type)
755 switch (memory_type) {
757 case GMT_MT: result = N6110_MEMORY_MT; break;
758 case GMT_ME: result = N6110_MEMORY_ME; break;
759 case GMT_SM: result = N6110_MEMORY_SM; break;
760 case GMT_FD: result = N6110_MEMORY_FD; break;
761 case GMT_ON: result = N6110_MEMORY_ON; break;
762 case GMT_EN: result = N6110_MEMORY_EN; break;
763 case GMT_DC: result = N6110_MEMORY_DC; break;
764 case GMT_RC: result = N6110_MEMORY_RC; break;
765 case GMT_MC: result = N6110_MEMORY_MC; break;
766 default : result = N6110_MEMORY_XX;
775 void N6110_ReplyCallDivert(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
777 switch (MessageBuffer[3]) {
782 fprintf(stdout, _("Message: Call divert status received\n"));
783 fprintf(stdout, _(" Divert type: "));
784 switch (MessageBuffer[6]) {
785 case 0x43: fprintf(stdout, _("when busy"));break;
786 case 0x3d: fprintf(stdout, _("when not answered"));break;
787 case 0x3e: fprintf(stdout, _("when phone off or no coverage"));break;
788 case 0x15: fprintf(stdout, _("all types of diverts"));break; //?
789 case 0x02: fprintf(stdout, _("all types of diverts"));break; //?
790 default: fprintf(stdout, _("unknown %i"),MessageBuffer[6]);break;
792 fprintf(stdout, _("\n Calls type : "));
793 if (MessageBuffer[6]==0x02)
794 fprintf(stdout, _("voice, fax & data")); //?
796 switch (MessageBuffer[8]) {
797 case 0x0b: fprintf(stdout, _("voice"));break;
798 case 0x0d: fprintf(stdout, _("fax"));break;
799 case 0x19: fprintf(stdout, _("data"));break;
800 default: fprintf(stdout, _("unknown %i"),MessageBuffer[8]);break;
803 fprintf(stdout, _("\n"));
804 if (MessageBuffer[10]==0x01) {
805 fprintf(stdout, _(" Status : active\n"));
806 fprintf(stdout, _(" Timeout : %i seconds\n"),MessageBuffer[45]);
807 fprintf(stdout, _(" Number : %s\n"),GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
809 fprintf(stdout, _(" Status : deactivated\n"));
813 switch (MessageBuffer[6]) {
814 case 0x43: CurrentCallDivert->DType=GSM_CDV_Busy;break;
815 case 0x3d: CurrentCallDivert->DType=GSM_CDV_NoAnswer;break;
816 case 0x3e: CurrentCallDivert->DType=GSM_CDV_OutOfReach;break;
817 case 0x15: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
818 case 0x02: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
821 if (MessageBuffer[6]==0x02) //?
822 CurrentCallDivert->CType=GSM_CDV_AllCalls;
824 switch (MessageBuffer[8]) {
825 case 0x0b: CurrentCallDivert->CType=GSM_CDV_VoiceCalls;break;
826 case 0x0d: CurrentCallDivert->CType=GSM_CDV_FaxCalls; break;
827 case 0x19: CurrentCallDivert->CType=GSM_CDV_DataCalls; break;
831 if (MessageBuffer[10]==0x01) {
832 CurrentCallDivert->Enabled=true;
833 CurrentCallDivert->Timeout=MessageBuffer[45];
834 strcpy(CurrentCallDivert->Number,GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
836 CurrentCallDivert->Enabled=false;
839 CurrentCallDivertError=GE_NONE;
844 fprintf(stdout, _("Message: Call divert status receiving error ?\n"));
846 CurrentCallDivertError=GE_UNKNOWN;
851 GSM_Error N6110_CallDivert(GSM_CallDivert *cd)
853 char req[55] = { N6110_FRAME_HEADER, 0x01,
854 0x00, /* operation */
856 0x00, /* divert type */
857 0x00, /* call type */
863 switch (cd->Operation) {
864 case GSM_CDV_Register:
868 req[29]= GSM_PackSemiOctetNumber(cd->Number, req + 9, false);
869 req[52]= cd->Timeout;
872 case GSM_CDV_Erasure:
873 case GSM_CDV_Disable:
880 return GE_NOTIMPLEMENTED;
884 case GSM_CDV_AllTypes : req[6] = 0x15; break;
885 case GSM_CDV_Busy : req[6] = 0x43; break;
886 case GSM_CDV_NoAnswer : req[6] = 0x3d; break;
887 case GSM_CDV_OutOfReach: req[6] = 0x3e; break;
888 default: return GE_NOTIMPLEMENTED;
891 if ((cd->DType == GSM_CDV_AllTypes) &&
892 (cd->CType == GSM_CDV_AllCalls))
896 case GSM_CDV_AllCalls : break;
897 case GSM_CDV_VoiceCalls: req[7] = 0x0b; break;
898 case GSM_CDV_FaxCalls : req[7] = 0x0d; break;
899 case GSM_CDV_DataCalls : req[7] = 0x19; break;
900 default: return GE_NOTIMPLEMENTED;
903 CurrentCallDivert = cd;
905 error=NULL_SendMessageSequence
906 (100, &CurrentCallDivertError, length, 0x06, req);
908 CurrentCallDivert = NULL;
913 GSM_Error N6110_Tests()
915 unsigned char buffer[3]={0x00,0x01,0xcf};
916 unsigned char buffer3[8]={0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00};
920 error=N6110_EnableExtendedCommands(0x01);
921 if (error!=GE_NONE) return error;
923 //make almost all tests
924 Protocol->SendMessage(8, 0x40, buffer3);
926 while (GSM->Initialise(PortDevice, "50", CurrentConnectionType, CurrentRLP_RXCallback)!=GE_NONE) {};
930 return NULL_SendMessageSequence
931 (200, &CurrentNetworkInfoError, 3, 0x40, buffer);
934 void N6110_DisplayTestsInfo(u8 *MessageBuffer) {
938 CurrentNetworkInfoError=GE_NONE;
940 for (i=0;i<MessageBuffer[3];i++) {
942 case 0: fprintf(stdout,_("Unknown(%i) "),i);break;
943 case 1: fprintf(stdout,_("MCU ROM checksum "));break;
944 case 2: fprintf(stdout,_("MCU RAM interface "));break;
945 case 3: fprintf(stdout,_("MCU RAM component "));break;
946 case 4: fprintf(stdout,_("MCU EEPROM interface "));break;
947 case 5: fprintf(stdout,_("MCU EEPROM component "));break;
948 case 6: fprintf(stdout,_("Real Time Clock battery "));break;
949 case 7: fprintf(stdout,_("CCONT interface "));break;
950 case 8: fprintf(stdout,_("AD converter "));break;
951 case 9: fprintf(stdout,_("SW Reset "));break;
952 case 10:fprintf(stdout,_("Power Off "));break;
953 case 11:fprintf(stdout,_("Security Data "));break;
954 case 12:fprintf(stdout,_("EEPROM Tune checksum "));break;
955 case 13:fprintf(stdout,_("PPM checksum "));break;
956 case 14:fprintf(stdout,_("MCU download DSP "));break;
957 case 15:fprintf(stdout,_("DSP alive "));break;
958 case 16:fprintf(stdout,_("COBBA serial "));break;
959 case 17:fprintf(stdout,_("COBBA paraller "));break;
960 case 18:fprintf(stdout,_("EEPROM security checksum"));break;
961 case 19:fprintf(stdout,_("PPM validity "));break;
962 case 20:fprintf(stdout,_("Warranty state "));break;
963 case 21:fprintf(stdout,_("Simlock check "));break;
964 case 22:fprintf(stdout,_("IMEI check? "));break;//from PC-Locals.is OK?
965 default:fprintf(stdout,_("Unknown(%i) "),i);break;
967 switch (MessageBuffer[4+i]) {
968 case 0: fprintf(stdout,_(" : done, result OK"));break;
969 case 0xff:fprintf(stdout,_(" : not done, result unknown"));break;
970 case 254: fprintf(stdout,_(" : done, result NOT OK"));break;
971 default: fprintf(stdout,_(" : result unknown(%i)"),MessageBuffer[4+i]);break;
973 fprintf(stdout,_("\n"));
977 void N6110_ReplySimlockInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
984 fprintf(stdout, _("Message: Simlock info received\n"));
987 for (i=0; i < 12; i++)
990 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] >> 4)));
993 if (j==5 || j==15) fprintf(stdout, _("\n"));
996 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] & 0x0f)));
1000 if (j==20 || j==24) fprintf(stdout, _("\n"));
1003 if ((MessageBuffer[6] & 1) == 1) fprintf(stdout,_("lock 1 closed\n"));
1004 if ((MessageBuffer[6] & 2) == 2) fprintf(stdout,_("lock 2 closed\n"));
1005 if ((MessageBuffer[6] & 4) == 4) fprintf(stdout,_("lock 3 closed\n"));
1006 if ((MessageBuffer[6] & 8) == 8) fprintf(stdout,_("lock 4 closed\n"));
1008 /* I'm not sure here at all */
1009 if ((MessageBuffer[5] & 1) == 1) fprintf(stdout,_("lock 1 - user\n"));
1010 if ((MessageBuffer[5] & 2) == 2) fprintf(stdout,_("lock 2 - user\n"));
1011 if ((MessageBuffer[5] & 4) == 4) fprintf(stdout,_("lock 3 - user\n"));
1012 if ((MessageBuffer[5] & 8) == 8) fprintf(stdout,_("lock 4 - user\n"));
1014 fprintf(stdout,_("counter for lock1: %i\n"),MessageBuffer[21]);
1015 fprintf(stdout,_("counter for lock2: %i\n"),MessageBuffer[22]);
1016 fprintf(stdout,_("counter for lock3: %i\n"),MessageBuffer[23]);
1017 fprintf(stdout,_("counter for lock4: %i\n"),MessageBuffer[24]);
1022 for (i=0; i < 12; i++)
1025 uni[j]='0' + (MessageBuffer[9+i] >> 4);
1030 uni[j]='0' + (MessageBuffer[9+i] & 0x0f);
1036 strncpy(CurrentSimLock->simlocks[0].data,uni,5);
1037 CurrentSimLock->simlocks[0].data[5]=0;
1038 strncpy(CurrentSimLock->simlocks[3].data,uni+5,10);
1039 CurrentSimLock->simlocks[3].data[10]=0;
1040 strncpy(CurrentSimLock->simlocks[1].data,uni+16,4);
1041 CurrentSimLock->simlocks[1].data[4]=0;
1042 strncpy(CurrentSimLock->simlocks[2].data,uni+20,4);
1043 CurrentSimLock->simlocks[2].data[4]=0;
1045 CurrentSimLock->simlocks[0].enabled=((MessageBuffer[6] & 1) == 1);
1046 CurrentSimLock->simlocks[1].enabled=((MessageBuffer[6] & 2) == 2);
1047 CurrentSimLock->simlocks[2].enabled=((MessageBuffer[6] & 4) == 4);
1048 CurrentSimLock->simlocks[3].enabled=((MessageBuffer[6] & 8) == 8);
1050 CurrentSimLock->simlocks[0].factory=((MessageBuffer[5] & 1) != 1);
1051 CurrentSimLock->simlocks[1].factory=((MessageBuffer[5] & 2) != 2);
1052 CurrentSimLock->simlocks[2].factory=((MessageBuffer[5] & 4) != 4);
1053 CurrentSimLock->simlocks[3].factory=((MessageBuffer[5] & 8) != 8);
1055 CurrentSimLock->simlocks[0].counter=MessageBuffer[21];
1056 CurrentSimLock->simlocks[1].counter=MessageBuffer[22];
1057 CurrentSimLock->simlocks[2].counter=MessageBuffer[23];
1058 CurrentSimLock->simlocks[3].counter=MessageBuffer[24];
1060 CurrentSimlockInfoError=GE_NONE;
1063 GSM_Error N6110_SimlockInfo(GSM_AllSimlocks *siml)
1066 unsigned char req[] = {0x00,0x01,0x8a,0x00};
1067 error=N6110_EnableExtendedCommands(0x01);
1068 if (error!=GE_NONE) return error;
1070 CurrentSimLock=siml;
1072 return NULL_SendMessageSequence (50, &CurrentSimlockInfoError, 4, 0x40, req);
1075 void N6110_ReplyResetPhoneSettings(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1078 fprintf(stdout, _("Message: Resetting phone settings\n"));
1081 CurrentResetPhoneSettingsError=GE_NONE;
1084 GSM_Error N6110_ResetPhoneSettings()
1087 unsigned char req[] = {0x00,0x01,0x65,0x08,0x00};
1088 error=N6110_EnableExtendedCommands(0x01);
1089 if (error!=GE_NONE) return error;
1091 return NULL_SendMessageSequence
1092 (50, &CurrentResetPhoneSettingsError, 5, 0x40, req);
1095 #endif /* UCLINUX */
1097 GSM_Error N6110_GetManufacturer(char *manufacturer)
1099 strcpy (manufacturer, "Nokia");
1105 GSM_Error N6110_GetVoiceMailbox ( GSM_PhonebookEntry *entry)
1107 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
1111 CurrentPhonebookEntry = entry;
1113 req[4] = N6110_MEMORY_VOICE;
1114 req[5] = 0x00; /* Location - isn't important, but... */
1116 error=NULL_SendMessageSequence
1117 (20, &CurrentPhonebookError, 7, 0x03, req);
1119 CurrentPhonebookEntry = NULL;
1124 void N6110_ReplyGetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1128 GSM_Bitmap NullBitmap;
1130 DecodeNetworkCode(MessageBuffer+5, NullBitmap.netcode);
1135 fprintf(stdout, _("Message: Info about downloaded operator name received: %s network (for gnokii \"%s\", for phone \""),
1137 GSM_GetNetworkName(NullBitmap.netcode));
1141 while (MessageBuffer[count]!=0) {
1143 fprintf(stdout,_("%c"),MessageBuffer[count]);
1148 strcpy(CurrentGetOperatorNameNetwork->Code, NullBitmap.netcode);
1149 strncpy(CurrentGetOperatorNameNetwork->Name, MessageBuffer+i,count-i+1);
1152 fprintf(stdout,_("\")\n"));
1155 CurrentGetOperatorNameError=GE_NONE;
1158 GSM_Error N6110_GetOperatorName (GSM_Network *operator)
1160 unsigned char req[] = { 0x00,0x01,0x8c,0x00};
1164 error=N6110_EnableExtendedCommands(0x01);
1165 if (error!=GE_NONE) return error;
1167 CurrentGetOperatorNameNetwork = operator;
1169 error=NULL_SendMessageSequence
1170 (20, &CurrentGetOperatorNameError, 4, 0x40, req);
1172 CurrentGetOperatorNameNetwork = NULL;
1177 void N6110_ReplySetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1180 fprintf(stdout, _("Message: Downloaded operator name changed\n"));
1183 CurrentSetOperatorNameError=GE_NONE;
1186 GSM_Error N6110_SetOperatorName (GSM_Network *operator)
1188 unsigned char req[256] = { 0x00,0x01,0x8b,0x00,
1189 0x00,0x00, /* MCC */
1194 error=N6110_EnableExtendedCommands(0x01);
1195 if (error!=GE_NONE) return error;
1197 EncodeNetworkCode(req+4,operator->Code);
1199 strncpy(req+7,operator->Name,200);
1201 return NULL_SendMessageSequence
1202 (20, &CurrentSetOperatorNameError, 8+strlen(operator->Name), 0x40, req);
1205 #endif /* UCLINUX */
1207 static void N6110_ReplyGetMemoryStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1209 switch (MessageBuffer[3]) {
1214 fprintf(stdout, _("Message: Memory status received:\n"));
1216 fprintf(stdout, _(" Memory Type: %s\n"), N6110_MemoryType_String[MessageBuffer[4]]);
1217 fprintf(stdout, _(" Used: %d\n"), MessageBuffer[6]);
1218 fprintf(stdout, _(" Free: %d\n"), MessageBuffer[5]);
1221 CurrentMemoryStatus->Used = MessageBuffer[6];
1222 CurrentMemoryStatus->Free = MessageBuffer[5];
1223 CurrentMemoryStatusError = GE_NONE;
1230 switch (MessageBuffer[4]) {
1232 fprintf(stdout, _("Message: Memory status error, phone is probably powered off.\n"));break;
1234 fprintf(stdout, _("Message: Memory status error, memory type not supported by phone model.\n"));break;
1236 fprintf(stdout, _("Message: Memory status error, waiting for security code.\n"));break;
1238 fprintf(stdout, _("Message: Unknown Memory status error, subtype (MessageBuffer[4]) = %02x\n"),MessageBuffer[4]);break;
1242 switch (MessageBuffer[4]) {
1243 case 0x6f:CurrentMemoryStatusError = GE_TIMEOUT;break;
1244 case 0x7d:CurrentMemoryStatusError = GE_INTERNALERROR;break;
1245 case 0x8d:CurrentMemoryStatusError = GE_INVALIDSECURITYCODE;break;
1254 /* This function is used to get storage status from the phone. It currently
1255 supports two different memory areas - internal and SIM. */
1256 GSM_Error N6110_GetMemoryStatus(GSM_MemoryStatus *Status)
1258 unsigned char req[] = { N6110_FRAME_HEADER,
1259 0x07, /* MemoryStatus request */
1260 0x00 /* MemoryType */
1265 CurrentMemoryStatus = Status;
1267 req[4] = N6110_GetMemoryType(Status->MemoryType);
1269 error=NULL_SendMessageSequence
1270 (20, &CurrentMemoryStatusError, 5, 0x03, req);
1272 CurrentMemoryStatus = NULL;
1279 void N6110_ReplyGetNetworkInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1281 GSM_NetworkInfo NullNetworkInfo;
1283 /* Make sure we are expecting NetworkInfo frame */
1284 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY) {
1286 fprintf(stdout, _("Message: Network informations:\n"));
1290 fprintf(stdout, _("Message: Network informations not requested, but received:\n"));
1294 sprintf(NullNetworkInfo.NetworkCode, "%x%x%x %x%x", MessageBuffer[14] & 0x0f, MessageBuffer[14] >>4, MessageBuffer[15] & 0x0f, MessageBuffer[16] & 0x0f, MessageBuffer[16] >>4);
1296 sprintf(NullNetworkInfo.CellID, "%02x%02x", MessageBuffer[10], MessageBuffer[11]);
1298 sprintf(NullNetworkInfo.LAC, "%02x%02x", MessageBuffer[12], MessageBuffer[13]);
1301 fprintf(stdout, _(" CellID: %s\n"), NullNetworkInfo.CellID);
1302 fprintf(stdout, _(" LAC: %s\n"), NullNetworkInfo.LAC);
1303 fprintf(stdout, _(" Network code: %s\n"), NullNetworkInfo.NetworkCode);
1304 fprintf(stdout, _(" Network name: %s (%s)\n"),
1305 GSM_GetNetworkName(NullNetworkInfo.NetworkCode),
1306 GSM_GetCountryName(NullNetworkInfo.NetworkCode));
1307 fprintf(stdout, _(" Status: "));
1309 switch (MessageBuffer[8]) {
1310 case 0x01: fprintf(stdout, _("home network selected")); break;
1311 case 0x02: fprintf(stdout, _("roaming network")); break;
1312 case 0x03: fprintf(stdout, _("requesting network")); break;
1313 case 0x04: fprintf(stdout, _("not registered in the network")); break;
1314 default: fprintf(stdout, _("unknown"));
1317 fprintf(stdout, "\n");
1319 fprintf(stdout, _(" Network selection: %s\n"), MessageBuffer[9]==1?_("manual"):_("automatic"));
1322 /* Make sure we are expecting NetworkInfo frame */
1323 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY)
1324 *CurrentNetworkInfo=NullNetworkInfo;
1326 CurrentNetworkInfoError = GE_NONE;
1329 GSM_Error N6110_GetNetworkInfo(GSM_NetworkInfo *NetworkInfo)
1331 unsigned char req[] = { N6110_FRAME_HEADER,
1337 CurrentNetworkInfo = NetworkInfo;
1339 error=NULL_SendMessageSequence
1340 (20, &CurrentNetworkInfoError, 4, 0x0a, req);
1342 CurrentNetworkInfo = NULL;
1347 void N6110_ReplyGetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1352 fprintf(stdout, _("Message: Product Profile Settings received -"));
1353 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),MessageBuffer[3+i]);
1354 fprintf(stdout, _("\n"));
1357 for (i=0;i<4;i++) CurrentPPS[i]=MessageBuffer[3+i];
1359 CurrentProductProfileSettingsError=GE_NONE;
1362 GSM_Error N6110_GetProductProfileSetting (GSM_PPS *PPS)
1364 unsigned char req[] = { 0x00, 0x01,0x6a };
1370 error=N6110_EnableExtendedCommands(0x01);
1371 if (error!=GE_NONE) return error;
1373 error=NULL_SendMessageSequence
1374 (20, &CurrentProductProfileSettingsError, 3, 0x40, req);
1375 if (error!=GE_NONE) return error;
1377 switch (PPS->Name) {
1378 case PPS_ALS : PPS->bool_value=(CurrentPPS[1]&32); break;
1379 case PPS_GamesMenu: PPS->bool_value=(CurrentPPS[3]&64); break;
1380 case PPS_HRData : PPS->bool_value=(CurrentPPS[0]&64); break;
1381 case PPS_14400Data: PPS->bool_value=(CurrentPPS[0]&128);break;
1382 case PPS_EFR : PPS->int_value =(CurrentPPS[0]&1) +(CurrentPPS[0]&2); break;
1383 case PPS_FR : PPS->int_value =(CurrentPPS[0]&16)/16+(CurrentPPS[0]&32)/16;break;
1384 case PPS_HR : PPS->int_value =(CurrentPPS[0]&4)/4 +(CurrentPPS[0]&8)/4; break;
1385 case PPS_VibraMenu: PPS->bool_value=(CurrentPPS[4]&64); break;
1386 case PPS_LCDContrast:
1390 if (CurrentPPS[3]&j) PPS->int_value=PPS->int_value+j;
1393 PPS->int_value=PPS->int_value*100/32;
1401 void N6110_ReplySetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1406 fprintf(stdout, _("Message: Product Profile Settings set to"));
1407 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),CurrentPPS[i]);
1408 fprintf(stdout, _("\n"));
1411 CurrentProductProfileSettingsError=GE_NONE;
1414 GSM_Error N6110_SetProductProfileSetting (GSM_PPS *PPS)
1416 unsigned char req[] = { 0x00, 0x01,0x6b,
1417 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */
1418 unsigned char settings[32];
1426 error=N6110_EnableExtendedCommands(0x01);
1427 if (error!=GE_NONE) return error;
1429 OldPPS.Name=PPS_ALS;
1430 error=N6110_GetProductProfileSetting(&OldPPS);
1431 if (error!=GE_NONE) return error;
1434 for (i=0;i<32;i++) {
1435 if (CurrentPPS[z]&j)
1446 fprintf(stdout,_("Current settings: "));
1447 for (i=0;i<32;i++) {
1448 fprintf(stdout,_("%c"),settings[i]);
1450 fprintf(stdout,_("\n"));
1453 switch (PPS->Name) {
1454 case PPS_ALS :settings[10]=PPS->bool_value?'1':'0';break;
1455 case PPS_HRData :settings[ 5]=PPS->bool_value?'1':'0';break;
1456 case PPS_14400Data:settings[ 6]=PPS->bool_value?'1':'0';break;
1461 for (i=0;i<32;i++) {
1462 if (settings[i]=='1') req[z+3]=req[z+3]+j;
1470 fprintf(stdout,_("Current settings: "));
1472 fprintf(stdout,_("%i "),req[i+3]);
1474 fprintf(stdout,_("\n"));
1478 CurrentPPS[i]=req[i+3];
1481 return NULL_SendMessageSequence
1482 (20, &CurrentProductProfileSettingsError, 7, 0x40, req);
1485 void N6110_ReplyPressKey(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1487 if (MessageBuffer[4]==CurrentPressKeyEvent) CurrentPressKeyError=GE_NONE;
1488 else CurrentPressKeyError=GE_UNKNOWN; /* MessageBuffer[4] = 0x05 */
1490 fprintf(stdout, _("Message: Result of key "));
1491 switch (MessageBuffer[4])
1493 case PRESSPHONEKEY: fprintf(stdout, _("press OK\n"));break;
1494 case RELEASEPHONEKEY: fprintf(stdout, _("release OK\n"));break;
1495 default: fprintf(stdout, _("press or release - error\n"));break;
1500 GSM_Error N6110_PressKey(int key, int event)
1502 unsigned char req[] = {N6110_FRAME_HEADER, 0x42, 0x01, 0x00, 0x01};
1504 req[4]=event; /* if we press or release key */
1507 CurrentPressKeyEvent=event;
1509 return NULL_SendMessageSequence
1510 (10, &CurrentPressKeyError, 7, 0x0c, req);
1513 void N6110_ReplyDisplayOutput(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1515 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
1522 switch(MessageBuffer[3]) {
1524 /* Phone sends displayed texts */
1526 NewX=MessageBuffer[6];
1527 NewY=MessageBuffer[5];
1529 DecodeUnicode (uni, MessageBuffer+8, MessageBuffer[7]);
1532 fprintf(stdout, _("New displayed text (%i %i): \"%s\"\n"),NewX,NewY,uni);
1535 while (N6110_GetModel(model) != GE_NONE)
1538 /* With these rules it works almost excellent with my N5110 */
1539 /* I don't have general rule :-(, that's why you must experiment */
1540 /* with your phone. Nokia could make it better. MW */
1541 /* It's almost OK for N5110*/
1542 /* FIX ME: it will be the same for N5130 and 3210 too*/
1543 if (!strcmp(model,"NSE-1"))
1545 /* OldX==1000 means - it's first time */
1549 for (i=0;i<5+1;i++) {
1550 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1555 if ((OldX==0 && OldY==31 && NewX==29 && NewY==46) ||
1556 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1557 /* Clean the line with current text */
1558 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1560 /* Inserts text into table */
1561 for (i=0; i<MessageBuffer[7];i++) {
1562 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1567 if ((OldX==0 && OldY==21 && NewX==0 && NewY==10) ||
1568 (OldX==0 && OldY==10 && NewX==35 && NewY==46)) {
1570 if ((OldX!=0 && NewX==0 && NewY!=6) ||
1571 (OldX==0 && NewX!=0 && OldY!=13 && OldY!=22) ||
1572 (OldX==0 && NewX==0 && NewY<OldY && (NewY!=13 || OldY!=26)) ||
1573 (OldY==5 && NewY!=5) ||
1574 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1576 /* Writes "old" screen */
1577 for (i=0;i<5+1;i++) {
1578 for (j=0;j<27+1;j++) {fprintf(stdout,_("%c"),PhoneScreen[i][j]);}
1579 fprintf(stdout,_("\n"));
1583 for (i=0;i<5+1;i++) {
1584 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1589 /* Clean the line with current text */
1590 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1592 /* Inserts text into table */
1593 for (i=0; i<MessageBuffer[7];i++) {
1594 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1601 fprintf(stdout, _("%s\n"),uni);
1609 if (MessageBuffer[4]==1)
1613 fprintf(stdout, _("Display output successfully disabled/enabled.\n"));
1616 CurrentDisplayOutputError=GE_NONE;
1623 GSM_Error SetDisplayOutput(unsigned char state)
1625 unsigned char req[] = { N6110_FRAME_HEADER,
1630 return NULL_SendMessageSequence
1631 (30, &CurrentDisplayOutputError, 5, 0x0d, req);
1634 GSM_Error N6110_EnableDisplayOutput()
1636 return SetDisplayOutput(0x01);
1639 GSM_Error N6110_DisableDisplayOutput()
1641 return SetDisplayOutput(0x02);
1644 /* If it is interesting for somebody: we can use 0x40 msg for it
1645 and it will work for all phones. See n6110.txt for details */
1646 GSM_Error N6110_AnswerCall(char s)
1648 unsigned char req0[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,0x07, 0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
1649 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80};
1650 unsigned char req[] = { N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
1655 fprintf(stdout,_("Answering call %d\n\r"),s);
1658 Protocol->SendMessage(sizeof(req0), 0x01, req0);
1661 return NULL_SendMessageSequence
1662 (20, &CurrentMagicError, sizeof(req) , 0x01, req);
1665 void N6110_ReplyGetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1667 switch (MessageBuffer[3]) {
1669 /* Profile feature */
1672 switch(GetModelFeature (FN_PROFILES)) {
1674 switch (MessageBuffer[6]) {
1675 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8]; break;
1676 case 0x01: CurrentProfile->CallAlert = MessageBuffer[8]; break;
1677 case 0x02: CurrentProfile->Ringtone = MessageBuffer[8]; break;
1678 case 0x03: CurrentProfile->Volume = MessageBuffer[8]; break;
1679 case 0x04: CurrentProfile->MessageTone = MessageBuffer[8]; break;
1680 case 0x05: CurrentProfile->Vibration = MessageBuffer[8]; break;
1681 case 0x06: CurrentProfile->WarningTone = MessageBuffer[8]; break;
1682 case 0x07: CurrentProfile->ScreenSaver = MessageBuffer[8]; break;
1685 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1691 switch (MessageBuffer[6]) {
1692 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8];break;
1693 case 0x01: CurrentProfile->Lights = MessageBuffer[8];break;
1694 case 0x02: CurrentProfile->CallAlert = MessageBuffer[8];break;
1695 case 0x03: CurrentProfile->Ringtone = MessageBuffer[8];break;
1696 case 0x04: CurrentProfile->Volume = MessageBuffer[8];break;
1697 case 0x05: CurrentProfile->MessageTone = MessageBuffer[8];break;
1698 case 0x06: CurrentProfile->Vibration = MessageBuffer[8];break;
1699 case 0x07: CurrentProfile->WarningTone = MessageBuffer[8];break;
1700 case 0x08: CurrentProfile->CallerGroups = MessageBuffer[8];break;
1701 case 0x09: CurrentProfile->AutomaticAnswer = MessageBuffer[8];break;
1704 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1711 CurrentProfileError = GE_NONE;
1714 /* Incoming profile name */
1717 if (MessageBuffer[9] == 0x00) {
1718 CurrentProfile->DefaultName=MessageBuffer[8];
1720 CurrentProfile->DefaultName=-1;
1722 /* Here name is in Unicode */
1723 if (GetModelFeature (FN_PROFILES)==F_PROF33) {
1724 DecodeUnicode (CurrentProfile->Name, MessageBuffer+10, MessageBuffer[9]/2);
1727 sprintf(CurrentProfile->Name, MessageBuffer + 10, MessageBuffer[9]);
1728 CurrentProfile->Name[MessageBuffer[9]] = '\0';
1732 CurrentProfileError = GE_NONE;
1738 /* Needs SIM card with PIN in phone */
1739 GSM_Error N6110_GetProfile(GSM_Profile *Profile)
1743 unsigned char name_req[] = { N6110_FRAME_HEADER, 0x1a, 0x00};
1744 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x13, 0x01, 0x00, 0x00};
1748 CurrentProfile = Profile;
1750 /* When after sending all frames feature==253, it means, that it is not
1752 CurrentProfile->KeypadTone=253;
1753 CurrentProfile->Lights=253;
1754 CurrentProfile->CallAlert=253;
1755 CurrentProfile->Ringtone=253;
1756 CurrentProfile->Volume=253;
1757 CurrentProfile->MessageTone=253;
1758 CurrentProfile->WarningTone=253;
1759 CurrentProfile->Vibration=253;
1760 CurrentProfile->CallerGroups=253;
1761 CurrentProfile->ScreenSaver=253;
1762 CurrentProfile->AutomaticAnswer=253;
1764 name_req[4] = Profile->Number;
1766 error=NULL_SendMessageSequence
1767 (20, &CurrentProfileError, 5, 0x05, name_req);
1768 if (error!=GE_NONE) return error;
1770 for (i = 0x00; i <= 0x09; i++) {
1772 feat_req[5] = Profile->Number;
1776 error=NULL_SendMessageSequence
1777 (20, &CurrentProfileError, 7, 0x05, feat_req);
1778 if (error!=GE_NONE) return error;
1781 if (Profile->DefaultName > -1)
1783 switch(GetModelFeature (FN_PROFILES)) {
1785 switch (Profile->DefaultName) {
1786 case 0x00: sprintf(Profile->Name, "General");break;
1787 case 0x01: sprintf(Profile->Name, "Silent");break;
1788 case 0x02: sprintf(Profile->Name, "Descreet");break;
1789 case 0x03: sprintf(Profile->Name, "Loud");break;
1790 case 0x04: sprintf(Profile->Name, "My style");break;
1791 case 0x05: Profile->Name[0]=0;break;
1792 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1796 switch (Profile->DefaultName) {
1797 case 0x00: sprintf(Profile->Name, "Personal");break;
1798 case 0x01: sprintf(Profile->Name, "Car");break;
1799 case 0x02: sprintf(Profile->Name, "Headset");break;
1800 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1804 switch (Profile->DefaultName) {
1805 case 0x00: sprintf(Profile->Name, "General");break;
1806 case 0x01: sprintf(Profile->Name, "Silent");break;
1807 case 0x02: sprintf(Profile->Name, "Meeting");break;
1808 case 0x03: sprintf(Profile->Name, "Outdoor");break;
1809 case 0x04: sprintf(Profile->Name, "Pager");break;
1810 case 0x05: sprintf(Profile->Name, "Car");break;
1811 case 0x06: sprintf(Profile->Name, "Headset");break;
1812 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1822 void N6110_ReplySetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1824 switch (MessageBuffer[3]) {
1826 /* Profile feature change result */
1829 fprintf(stdout, _("Message: Profile feature change result.\n"));
1831 CurrentProfileError = GE_NONE;
1834 /* Profile name set result */
1837 fprintf(stdout, _("Message: Profile name change result.\n"));
1839 CurrentProfileError = GE_NONE;
1845 GSM_Error N6110_SetProfileFeature(u8 profile, u8 feature, u8 value)
1847 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x10, 0x01,
1850 feat_req[5]=profile;
1851 feat_req[6]=feature;
1854 return NULL_SendMessageSequence
1855 (20, &CurrentProfileError, 8, 0x05, feat_req);
1858 GSM_Error N6110_SetProfile(GSM_Profile *Profile)
1862 unsigned char name_req[40] = { N6110_FRAME_HEADER, 0x1c, 0x01, 0x03,
1867 name_req[7] = Profile->Number;
1868 name_req[8] = strlen(Profile->Name);
1869 name_req[6] = name_req[8] + 2;
1871 for (i = 0; i < name_req[8]; i++)
1872 name_req[9 + i] = Profile->Name[i];
1874 error=NULL_SendMessageSequence
1875 (20, &CurrentProfileError, name_req[8] + 9, 0x05, name_req);
1876 if (error!=GE_NONE) return error;
1878 for (i = 0x00; i <= 0x09; i++) {
1881 case 0x00: value = Profile->KeypadTone; break;
1882 case 0x01: value = Profile->Lights; break;
1883 case 0x02: value = Profile->CallAlert; break;
1884 case 0x03: value = Profile->Ringtone; break;
1885 case 0x04: value = Profile->Volume; break;
1886 case 0x05: value = Profile->MessageTone; break;
1887 case 0x06: value = Profile->Vibration; break;
1888 case 0x07: value = Profile->WarningTone; break;
1889 case 0x08: value = Profile->CallerGroups; break;
1890 case 0x09: value = Profile->AutomaticAnswer; break;
1891 default : value = 0; break;
1894 error=N6110_SetProfileFeature(Profile->Number,i,value);
1895 if (error!=GE_NONE) return error;
1901 bool N6110_SendRLPFrame(RLP_F96Frame *frame, bool out_dtx)
1903 u8 req[60] = { 0x00, 0xd9 };
1905 /* Discontinuos transmission (DTX). See section 5.6 of GSM 04.22 version
1911 memcpy(req+2, (u8 *) frame, 32);
1913 return (Protocol->SendFrame(32, 0xf0, req));
1916 void N6110_ReplyGetCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1924 switch (MessageBuffer[4]) {
1928 CurrentCalendarNote->Type=MessageBuffer[8];
1930 DecodeDateTime(MessageBuffer+9, &CurrentCalendarNote->Time);
1932 DecodeDateTime(MessageBuffer+16, &CurrentCalendarNote->Alarm);
1934 CurrentCalendarNote->Text[0]=0;
1936 if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
1938 if (CurrentCalendarNote->Type == GCN_REMINDER) i=1; //first char is subset
1939 switch (MessageBuffer[24]) {
1942 fprintf(stdout,_("Subset 3 in reminder note !\n"));
1944 while (i!=MessageBuffer[23]) {
1946 if (i!=MessageBuffer[23]-1) {
1947 if (MessageBuffer[24+i]>=0xc2) {
1948 DecodeWithUTF8Alphabet(MessageBuffer[24+i], MessageBuffer[24+i+1], &mychar1);
1949 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1950 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=mychar1;
1956 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1957 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=MessageBuffer[24+i];
1964 fprintf(stdout,_("Subset 2 in reminder note !\n"));
1966 while (i!=MessageBuffer[23]) {
1967 wc = MessageBuffer[24+i] | (0x00 << 8);
1968 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1969 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=
1970 DecodeWithUnicodeAlphabet(wc);
1976 fprintf(stdout,_("Subset 1 in reminder note !\n"));
1978 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1979 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1983 fprintf(stdout,_("Unknown subset in reminder note !\n"));
1985 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1986 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1990 memcpy(CurrentCalendarNote->Text,MessageBuffer+24,MessageBuffer[23]);
1991 CurrentCalendarNote->Text[MessageBuffer[23]]=0;
1994 if (CurrentCalendarNote->Type == GCN_CALL) {
1995 memcpy(CurrentCalendarNote->Phone,MessageBuffer+24+MessageBuffer[23]+1,MessageBuffer[24+MessageBuffer[23]]);
1996 CurrentCalendarNote->Phone[MessageBuffer[24+MessageBuffer[23]]]=0;
1999 CurrentCalendarNote->Recurrance=0;
2001 CurrentCalendarNote->AlarmType=0;
2004 fprintf(stdout, _("Message: Calendar note received.\n"));
2006 fprintf(stdout, _(" Date: %d-%02d-%02d\n"), CurrentCalendarNote->Time.Year,
2007 CurrentCalendarNote->Time.Month,
2008 CurrentCalendarNote->Time.Day);
2010 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentCalendarNote->Time.Hour,
2011 CurrentCalendarNote->Time.Minute,
2012 CurrentCalendarNote->Time.Second);
2014 /* Some messages do not have alarm set up */
2015 if (CurrentCalendarNote->Alarm.Year != 0) {
2016 fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"), CurrentCalendarNote->Alarm.Year,
2017 CurrentCalendarNote->Alarm.Month,
2018 CurrentCalendarNote->Alarm.Day);
2020 fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"), CurrentCalendarNote->Alarm.Hour,
2021 CurrentCalendarNote->Alarm.Minute,
2022 CurrentCalendarNote->Alarm.Second);
2025 fprintf(stdout, _(" Type: %d\n"), CurrentCalendarNote->Type);
2026 fprintf(stdout, _(" Text: %s\n"), CurrentCalendarNote->Text);
2028 if (CurrentCalendarNote->Type == GCN_CALL)
2029 fprintf(stdout, _(" Phone: %s\n"), CurrentCalendarNote->Phone);
2032 CurrentCalendarNoteError=GE_NONE;
2038 fprintf(stdout, _("Message: Calendar note not available\n"));
2041 CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;
2047 fprintf(stdout, _("Message: Calendar note error\n"));
2050 CurrentCalendarNoteError=GE_INTERNALERROR;
2056 GSM_Error N6110_GetCalendarNote(GSM_CalendarNote *CalendarNote)
2059 unsigned char req[] = { N6110_FRAME_HEADER,
2064 req[4]=CalendarNote->Location;
2066 CurrentCalendarNote = CalendarNote;
2068 error=NULL_SendMessageSequence
2069 (20, &CurrentCalendarNoteError, 5, 0x13, req);
2071 CurrentCalendarNote = NULL;
2076 void N6110_ReplyWriteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2079 switch(MessageBuffer[4]) {
2080 /* This message is also sent when the user enters the new entry on keypad */
2082 fprintf(stdout, _("Message: Calendar note write succesfull!\n"));break;
2084 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2086 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2088 fprintf(stdout, _("Unknown message of type 0x13 and subtype 0x65\n"));break;
2092 switch(MessageBuffer[4]) {
2093 case 0x01: CurrentCalendarNoteError=GE_NONE; break;
2094 case 0x73: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2095 case 0x7d: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2096 default : AppendLogText("Unknown msg\n",false); break;
2100 GSM_Error N6110_WriteCalendarNote(GSM_CalendarNote *CalendarNote)
2103 unsigned char req[200] = { N6110_FRAME_HEADER,
2105 0x00, /* Length of the rest of the frame. */
2106 0x00, /* The type of calendar note */
2107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2114 unsigned char meeting;
2115 unsigned char birthday;
2116 unsigned char reminder;
2117 } calendar_model_length;
2119 /* Length of entries */
2120 calendar_model_length calendar_lengths[] =
2122 /*model,CallTo,Meeting,Birthday,Reminder*/
2123 {"NHM-5",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2124 {"NHM-6",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2125 {"NSE-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 [HKEY_LOCAL_MACHINE\Software\Nokia\Data Suite\3.0\Calendar]
2126 {"NSM-1",0x1e,0x18,0x18,0x24}, //from NCDS3
2127 {"NSK-3",0x1e,0x14,0x14,0x1e}, //from NCDS3
2128 {"NSB-3",0x20,0x14,0x14,0x1e}, //from NCDS3
2129 {"", 0, 0, 0, 0 } //end of table
2140 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
2143 req[7]=CalendarNote->Type;
2145 EncodeDateTime(req+8, &CalendarNote->Time);
2146 req[14] = CalendarNote->Time.Timezone;
2148 if (CalendarNote->Alarm.Year) {
2149 EncodeDateTime(req+15, &CalendarNote->Alarm);
2150 req[21] = CalendarNote->Alarm.Timezone;
2153 req[22]=strlen(CalendarNote->Text);
2157 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2158 req[22]++; // one additional char
2159 req[current++]=0x01; //we use now subset 1
2162 for (i=0; i<strlen(CalendarNote->Text); i++) {
2164 mychar=CalendarNote->Text[i];
2165 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2166 if (EncodeWithUTF8Alphabet(mychar,&mychar1,&mychar2)) {
2167 req[current++]=mychar1;
2168 req[current++]=mychar2;
2169 req[23]=0x03; //use subset 3
2170 req[22]++; // one additional char
2175 /* Enables/disables blinking */
2176 if (mychar=='~') req[current++]=0x01;
2177 else req[current++]=mychar;
2181 req[current++]=strlen(CalendarNote->Phone);
2183 for (i=0; i<strlen(CalendarNote->Phone); i++)
2184 req[current++]=CalendarNote->Phone[i];
2186 while (N6110_GetModel(model) != GE_NONE)
2189 /* Checking maximal length */
2191 while (strcmp(calendar_lengths[i].model,"")) {
2192 if (!strcmp(calendar_lengths[i].model,model)) {
2193 switch (CalendarNote->Type) {
2194 case GCN_REMINDER:if (req[22]>calendar_lengths[i].reminder) return GE_TOOLONG;break;
2195 case GCN_MEETING :if (req[22]>calendar_lengths[i].meeting) return GE_TOOLONG;break;
2196 case GCN_BIRTHDAY:if (req[22]>calendar_lengths[i].birthday) return GE_TOOLONG;break;
2197 case GCN_CALL :if (strlen(CalendarNote->Phone)>calendar_lengths[i].call) return GE_TOOLONG;break;
2204 CurrentCalendarNote = CalendarNote;
2206 error=NULL_SendMessageSequence
2207 (20, &CurrentCalendarNoteError, current, 0x13, req);
2209 CurrentCalendarNote = NULL;
2214 void N6110_ReplyDeleteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2217 switch (MessageBuffer[4]) {
2218 /* This message is also sent when the user deletes an old entry on
2219 keypad or moves an old entry somewhere (there is also `write'
2221 case 0x01:fprintf(stdout, _("Message: Calendar note deleted\n"));break;
2222 case 0x93:fprintf(stdout, _("Message: Calendar note can't be deleted\n"));break;
2223 default :fprintf(stdout, _("Message: Calendar note deleting error\n"));break;
2227 switch (MessageBuffer[4]) {
2228 case 0x01:CurrentCalendarNoteError=GE_NONE;break;
2229 case 0x93:CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;break;
2230 default :CurrentCalendarNoteError=GE_INTERNALERROR;break;
2234 GSM_Error N6110_DeleteCalendarNote(GSM_CalendarNote *CalendarNote)
2237 unsigned char req[] = { N6110_FRAME_HEADER,
2241 req[4]=CalendarNote->Location;
2243 return NULL_SendMessageSequence (20, &CurrentCalendarNoteError, 5, 0x13, req);
2246 #endif /* UCLINUX */
2248 static void N6110_ReplyRFBatteryLevel(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2251 fprintf(stdout, _("Message: Phone status received:\n"));
2252 fprintf(stdout, _(" Mode: "));
2254 switch (MessageBuffer[4]) {
2258 fprintf(stdout, _("registered within the network\n"));
2261 /* I was really amazing why is there a hole in the type of 0x02, now I
2263 case 0x02: fprintf(stdout, _("call in progress\n")); break; /* ringing or already answered call */
2264 case 0x03: fprintf(stdout, _("waiting for security code\n")); break;
2265 case 0x04: fprintf(stdout, _("powered off\n")); break;
2266 default : fprintf(stdout, _("unknown\n"));
2270 fprintf(stdout, _(" Power source: "));
2272 switch (MessageBuffer[7]) {
2274 case 0x01: fprintf(stdout, _("AC/DC\n")); break;
2275 case 0x02: fprintf(stdout, _("battery\n")); break;
2276 default : fprintf(stdout, _("unknown\n"));
2280 fprintf(stdout, _(" Battery Level: %d\n"), MessageBuffer[8]);
2281 fprintf(stdout, _(" Signal strength: %d\n"), MessageBuffer[5]);
2284 CurrentRFLevel=MessageBuffer[5];
2285 CurrentBatteryLevel=MessageBuffer[8];
2286 CurrentPowerSource=MessageBuffer[7];
2290 GSM_Error N6110_GetRFLevel(GSM_RFUnits *units, float *level)
2293 /* FIXME - these values are from 3810 code, may be incorrect. Map from
2294 values returned in status packet to the the values returned by the AT+CSQ
2296 float csq_map[5] = {0, 8, 16, 24, 31};
2301 char screen[NM_MAX_SCREEN_WIDTH];
2305 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2308 if (N6110_NetMonitor(1, screen)!=GE_NONE)
2309 return GE_INTERNALERROR;
2310 #endif /* UCLINUX */
2314 if (screen[4]!='-') {
2315 if (screen[5]=='9' && screen[6]>'4') rf_level=1;
2316 if (screen[5]=='9' && screen[6]<'5') rf_level=2;
2317 if (screen[5]=='8' && screen[6]>'4') rf_level=3;
2320 /* Arbitrary units. */
2321 if (*units == GRF_Arbitrary) {
2327 N6110_SendStatusRequest();
2329 /* Wait for timeout or other error. */
2330 while (timeout != 0 && CurrentRFLevel == -1 ) {
2333 return (GE_TIMEOUT);
2338 /* Make copy in case it changes. */
2339 rf_level = CurrentRFLevel;
2344 /* Now convert between the different units we support. */
2346 /* Arbitrary units. */
2347 if (*units == GRF_Arbitrary) {
2353 if (*units == GRF_CSQ) {
2356 *level = csq_map[rf_level];
2358 *level = 99; /* Unknown/undefined */
2364 /* Unit type is one we don't handle so return error */
2365 return (GE_INTERNALERROR);
2369 GSM_Error N6110_GetBatteryLevel(GSM_BatteryUnits *units, float *level)
2374 char screen[NM_MAX_SCREEN_WIDTH];
2376 CurrentBatteryLevel=-1;
2378 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2381 if (N6110_NetMonitor(23, screen)!=GE_NONE)
2383 #endif /* UCLINUX */
2387 if (screen[29]=='7') batt_level=3;
2388 if (screen[29]=='5') batt_level=2;
2389 if (screen[29]=='2') batt_level=1;
2391 /* Only units we handle at present are GBU_Arbitrary */
2392 if (*units == GBU_Arbitrary) {
2393 *level = batt_level;
2397 return (GE_INTERNALERROR);
2400 N6110_SendStatusRequest();
2402 /* Wait for timeout or other error. */
2403 while (timeout != 0 && CurrentBatteryLevel == -1 ) {
2406 return (GE_TIMEOUT);
2411 /* Take copy in case it changes. */
2412 batt_level = CurrentBatteryLevel;
2414 if (batt_level != -1) {
2416 /* Only units we handle at present are GBU_Arbitrary */
2417 if (*units == GBU_Arbitrary) {
2418 *level = batt_level;
2422 return (GE_INTERNALERROR);
2429 GSM_Error N6110_GetPowerSource(GSM_PowerSource *source)
2434 char screen[NM_MAX_SCREEN_WIDTH];
2436 CurrentPowerSource=-1;
2438 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2441 if (N6110_NetMonitor(20, screen)!=GE_NONE)
2443 #endif /* UCLINUX */
2445 CurrentPowerSource=GPS_ACDC;
2447 if (screen[6]=='x') CurrentPowerSource=GPS_BATTERY;
2449 *source=CurrentPowerSource;
2453 N6110_SendStatusRequest();
2455 /* Wait for timeout or other error. */
2456 while (timeout != 0 && CurrentPowerSource == -1 ) {
2459 return (GE_TIMEOUT);
2464 if (CurrentPowerSource != -1) {
2465 *source=CurrentPowerSource;
2475 static void N6110_ReplyGetDisplayStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2479 for (i=0; i<MessageBuffer[4];i++)
2480 if (MessageBuffer[2*i+6]==2)
2481 CurrentDisplayStatus|=1<<(MessageBuffer[2*i+5]-1);
2483 CurrentDisplayStatus&= (0xff - (1<<(MessageBuffer[2*i+5]-1)));
2486 fprintf(stdout, _("Call in progress: %s\n"), CurrentDisplayStatus & (1<<DS_Call_In_Progress)?"on":"off");
2487 fprintf(stdout, _("Unknown: %s\n"), CurrentDisplayStatus & (1<<DS_Unknown)?"on":"off");
2488 fprintf(stdout, _("Unread SMS: %s\n"), CurrentDisplayStatus & (1<<DS_Unread_SMS)?"on":"off");
2489 fprintf(stdout, _("Voice call: %s\n"), CurrentDisplayStatus & (1<<DS_Voice_Call)?"on":"off");
2490 fprintf(stdout, _("Fax call active: %s\n"), CurrentDisplayStatus & (1<<DS_Fax_Call)?"on":"off");
2491 fprintf(stdout, _("Data call active: %s\n"), CurrentDisplayStatus & (1<<DS_Data_Call)?"on":"off");
2492 fprintf(stdout, _("Keyboard lock: %s\n"), CurrentDisplayStatus & (1<<DS_Keyboard_Lock)?"on":"off");
2493 fprintf(stdout, _("SMS storage full: %s\n"), CurrentDisplayStatus & (1<<DS_SMS_Storage_Full)?"on":"off");
2496 CurrentDisplayStatusError=GE_NONE;
2499 GSM_Error N6110_GetDisplayStatus(int *Status) {
2501 unsigned char req[4]={ N6110_FRAME_HEADER, 0x51 };
2505 error=NULL_SendMessageSequence
2506 (10, &CurrentDisplayStatusError, 4, 0x0d, req);
2507 if (error!=GE_NONE) return error;
2509 *Status=CurrentDisplayStatus;
2514 GSM_Error N6110_DialVoice(char *Number) {
2515 /* This commented sequence doesn't work on N3210/3310/6210/7110 */
2516 // unsigned char req[64]={N6110_FRAME_HEADER, 0x01};
2517 // unsigned char req_end[]={0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};
2519 // req[4]=strlen(Number);
2520 // for(i=0; i < strlen(Number) ; i++)
2521 // req[5+i]=Number[i];
2522 // memcpy(req+5+strlen(Number), req_end, 10);
2523 // return NULL_SendMessageSequence
2524 // (20, &CurrentDialVoiceError, 13+strlen(Number), 0x01, req);
2526 unsigned char req[64]={0x00,0x01,0x7c,
2527 0x01}; //call command
2533 error=N6110_EnableExtendedCommands(0x01);
2534 if (error!=GE_NONE) return error;
2536 for(i=0; i < strlen(Number) ; i++) req[4+i]=Number[i];
2540 return NULL_SendMessageSequence
2541 (20, &CurrentDialVoiceError, 4+strlen(Number)+1, 0x40, req);
2544 #endif /* UCLINUX */
2546 /* Dial a data call - type specifies request to use:
2547 type 0 should normally be used
2548 type 1 should be used when calling a digital line - corresponds to ats35=0
2549 Maybe one day we'll know what they mean!
2551 GSM_Error N6110_DialData(char *Number, char type, void (* callpassup)(char c))
2553 unsigned char req[100] = { N6110_FRAME_HEADER, 0x01 };
2554 unsigned char *req_end;
2555 unsigned char req_end0[] = { 0x01, /* make a data call = type 0x01 */
2556 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2557 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00 };
2558 unsigned char req_end1[] = { 0x01,
2559 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2560 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2561 0x88,0x90,0x21,0x48,0x40,0xbb };
2562 unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2563 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2564 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
2565 unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2566 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2567 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
2568 unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
2569 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2570 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
2571 0x20,0x15,0x63,0x80 };
2576 CurrentCallPassup=callpassup;
2581 size = sizeof(req_end0);
2584 Protocol->SendMessage(sizeof(req3), 0x01, req3);
2585 Protocol->SendMessage(sizeof(req4), 0x01, req4);
2587 size = sizeof(req_end1);
2589 case -1: /* Just used to set the call passup */
2594 size = sizeof(req_end0);
2598 req[4] = strlen(Number);
2600 for(i = 0; i < strlen(Number) ; i++)
2601 req[5+i] = Number[i];
2603 memcpy(req + 5 + strlen(Number), req_end, size);
2605 Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);
2606 if (type != 1) Protocol->SendMessage(26, 0x01, req2);
2613 GSM_Error N6110_GetIncomingCallNr(char *Number)
2616 if (*CurrentIncomingCall != ' ') {
2617 strcpy(Number, CurrentIncomingCall);
2624 #endif /* UCLINUX */
2626 GSM_Error N6110_CancelCall(void)
2628 // This frame & method works only on 61xx/51xx
2629 // unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
2630 // req[4]=CurrentCallSequenceNumber;
2631 // Protocol->SendMessage(6, 0x01, req);
2636 unsigned char req[]={0x00,0x01,0x7c,0x03};
2639 error=N6110_EnableExtendedCommands(0x01);
2640 if (error!=GE_NONE) return error;
2642 return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
2647 void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2649 switch(MessageBuffer[3]) {
2653 fprintf(stdout, _("Message: Security code accepted.\n"));
2655 CurrentSecurityCodeError = GE_NONE;
2660 fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
2662 CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
2666 GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
2669 unsigned char req[15] = { N6110_FRAME_HEADER,
2670 0x0a, /* Enter code request. */
2671 0x00 /* Type of the entered code. */
2675 req[4]=SecurityCode.Type;
2677 for (i=0; i<strlen(SecurityCode.Code);i++)
2678 req[5+i]=SecurityCode.Code[i];
2680 req[5+strlen(SecurityCode.Code)]=0x00;
2681 req[6+strlen(SecurityCode.Code)]=0x00;
2683 return NULL_SendMessageSequence
2684 (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
2687 void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2689 *CurrentSecurityCodeStatus = MessageBuffer[4];
2692 fprintf(stdout, _("Message: Security Code status received: "));
2694 switch(*CurrentSecurityCodeStatus) {
2696 case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;
2697 case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;
2698 case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;
2699 case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;
2700 case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;
2701 case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;
2702 default : fprintf(stdout, _("Unknown!\n"));
2707 CurrentSecurityCodeError = GE_NONE;
2710 GSM_Error N6110_GetSecurityCodeStatus(int *Status)
2713 unsigned char req[4] = { N6110_FRAME_HEADER,
2717 CurrentSecurityCodeStatus=Status;
2719 return NULL_SendMessageSequence
2720 (20, &CurrentSecurityCodeError, 4, 0x08, req);
2723 void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2728 fprintf(stdout, _("Message: Security code received: "));
2729 switch (MessageBuffer[3]) {
2730 case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;
2731 case GSCT_Pin: fprintf(stdout, _("PIN"));break;
2732 case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;
2733 case GSCT_Puk: fprintf(stdout, _("PUK"));break;
2734 case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;
2735 default: fprintf(stdout, _("unknown !"));break;
2737 if (MessageBuffer[4]==1) {
2738 fprintf(stdout, _(" allowed, value \""));
2739 if (MessageBuffer[3]==GSCT_SecurityCode) {
2740 for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2742 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2743 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2744 for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2746 fprintf(stdout, _("\""));
2748 fprintf(stdout, _(" not allowed"));
2750 fprintf(stdout, _("\n"));
2753 if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
2754 && MessageBuffer[4]==1) { /* It's allowed */
2755 if (MessageBuffer[3]==GSCT_SecurityCode) {
2756 for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2757 CurrentSecurityCode->Code[5]=0;
2759 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2760 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2761 for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2762 CurrentSecurityCode->Code[4]=0;
2764 CurrentSecurityCodeError=GE_NONE;
2766 CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
2769 GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
2772 unsigned char req[4] = { 0x00,
2773 0x01,0x6e, /* Get code request. */
2774 0x00 }; /* Type of the requested code. */
2778 error=N6110_EnableExtendedCommands(0x01);
2779 if (error!=GE_NONE) return error;
2781 req[3]=SecurityCode->Type;
2783 CurrentSecurityCode=SecurityCode;
2785 return NULL_SendMessageSequence
2786 (20, &CurrentSecurityCodeError, 4, 0x40, req);
2789 void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2792 fprintf(stdout, _("Message: answer for PlayTone frame\n"));
2795 CurrentPlayToneError=GE_NONE;
2798 GSM_Error N6110_PlayTone(int Herz, u8 Volume)
2800 unsigned char req[6] = { 0x00,0x01,0x8f,
2803 0x00 }; /* HerzHi */
2807 /* PlayTone wasn't used earlier */
2808 if (CurrentPlayToneError==GE_UNKNOWN) {
2809 if (CurrentConnectionType!=GCT_MBUS)
2810 CurrentDisableKeepAlive=true;
2812 error=N6110_EnableExtendedCommands(0x01);
2813 if (error!=GE_NONE) return error;
2816 /* For Herz==255*255 we have silent */
2817 if (Herz!=255*255) {
2830 /* For Herz==255*255 we have silent and additionaly
2831 we wait for phone answer - it's important for MBUS */
2832 if (Herz==255*255) {
2833 error=NULL_SendMessageSequence
2834 (20, &CurrentPlayToneError, 6, 0x40, req);
2836 CurrentPlayToneError=GE_UNKNOWN;
2837 CurrentDisableKeepAlive=false;
2839 if (error!=GE_NONE) return error;
2841 Protocol->SendMessage(6,0x40,req);
2844 error=NULL_SendMessageSequence
2845 (20, &CurrentPlayToneError, 6, 0x40, req);
2847 /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
2848 if (Herz==255*255) {
2849 CurrentPlayToneError=GE_UNKNOWN;
2850 CurrentDisableKeepAlive=false;
2853 if (error!=GE_NONE) return error;
2860 void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2862 if (MessageBuffer[4]==0x01) {
2863 DecodeDateTime(MessageBuffer+8, CurrentDateTime);
2866 fprintf(stdout, _("Message: Date and time\n"));
2867 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
2868 fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
2871 CurrentDateTime->IsSet=true;
2875 fprintf(stdout, _("Message: Date and time not set in phone\n"));
2878 CurrentDateTime->IsSet=false;
2881 CurrentDateTimeError=GE_NONE;
2884 GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
2886 return N6110_PrivGetDateTime(date_time,0x11);
2889 GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
2891 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
2893 CurrentDateTime=date_time;
2895 return NULL_SendMessageSequence
2896 (50, &CurrentDateTimeError, 4, msgtype, req);
2899 void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2902 fprintf(stdout, _("Message: Alarm\n"));
2903 fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
2904 fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
2907 CurrentAlarm->Hour=MessageBuffer[9];
2908 CurrentAlarm->Minute=MessageBuffer[10];
2909 CurrentAlarm->Second=0;
2911 CurrentAlarm->IsSet=(MessageBuffer[8]==2);
2913 CurrentAlarmError=GE_NONE;
2916 GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
2918 return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
2921 GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
2923 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
2925 CurrentAlarm=date_time;
2927 return NULL_SendMessageSequence
2928 (50, &CurrentAlarmError, 4, msgtype, req);
2931 void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2933 switch (MessageBuffer[3]) {
2937 CurrentMessageCenter->No=MessageBuffer[4];
2938 CurrentMessageCenter->Format=MessageBuffer[6];
2939 CurrentMessageCenter->Validity=MessageBuffer[8];
2940 sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
2942 sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
2944 sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
2947 fprintf(stdout, _("Message: SMS Center received:\n"));
2948 fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
2949 fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
2950 fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
2952 fprintf(stdout, _(" SMS Center message format is "));
2954 switch (CurrentMessageCenter->Format) {
2956 case GSMF_Text : fprintf(stdout, _("Text")); break;
2957 case GSMF_Paging: fprintf(stdout, _("Paging")); break;
2958 case GSMF_Fax : fprintf(stdout, _("Fax")); break;
2959 case GSMF_Email : fprintf(stdout, _("Email")); break;
2960 default : fprintf(stdout, _("Unknown"));
2963 fprintf(stdout, "\n");
2965 fprintf(stdout, _(" SMS Center message validity is "));
2967 switch (CurrentMessageCenter->Validity) {
2969 case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;
2970 case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;
2971 case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;
2972 case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;
2973 case GSMV_1_Week : fprintf(stdout, _("1 week")); break;
2974 case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;
2975 default : fprintf(stdout, _("Unknown"));
2978 fprintf(stdout, "\n");
2982 CurrentMessageCenterError=GE_NONE;
2988 /* Number of entries depends on SIM card */
2991 fprintf(stdout, _("Message: SMS Center error received:\n"));
2992 fprintf(stdout, _(" The request for SMS Center failed.\n"));
2995 /* FIXME: appropriate error. */
2996 CurrentMessageCenterError=GE_INTERNALERROR;
3003 /* This function sends to the mobile phone a request for the SMS Center */
3004 GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
3006 unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
3007 0x00 /* SMS Center Number. */
3010 req[5]=MessageCenter->No;
3012 CurrentMessageCenter=MessageCenter;
3014 return NULL_SendMessageSequence
3015 (50, &CurrentMessageCenterError, 6, 0x02, req);
3018 void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3021 fprintf(stdout, _("Message: SMS Center correctly set.\n"));
3023 CurrentMessageCenterError=GE_NONE;
3026 /* This function set the SMS Center profile on the phone. */
3027 GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
3029 unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
3030 0x00, /* SMS Center Number. */
3031 0x00, /* Unknown. */
3032 0x00, /* SMS Message Format. */
3033 0x00, /* Unknown. */
3034 0x00, /* Validity. */
3035 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
3036 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
3037 /* Message Center Name. */
3040 req[5]=MessageCenter->No;
3041 req[7]=MessageCenter->Format;
3042 req[9]=MessageCenter->Validity;
3044 req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
3046 req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
3048 sprintf(req+34, "%s", MessageCenter->Name);
3050 CurrentMessageCenter=MessageCenter;
3052 return NULL_SendMessageSequence
3053 (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
3056 void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3058 switch (MessageBuffer[3]) {
3063 fprintf(stdout, _("Message: SMS Status Received\n"));
3064 fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
3065 fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
3068 CurrentSMSStatus->UnRead = MessageBuffer[11];
3069 CurrentSMSStatus->Number = MessageBuffer[10];
3071 CurrentSMSStatusError = GE_NONE;
3077 fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
3080 CurrentSMSStatusError = GE_INTERNALERROR;
3086 GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
3088 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
3090 CurrentSMSStatus = Status;
3092 return NULL_SendMessageSequence
3093 (10, &CurrentSMSStatusError, 5, 0x14, req);
3096 GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
3100 strcpy(folders->Folder[0].Name,"Inbox");
3101 strcpy(folders->Folder[1].Name,"Outbox");
3106 #endif /* UCLINUX */
3108 GSM_Error N6110_GetIMEI(char *imei)
3110 if (strlen(Current_IMEI)>0) {
3111 strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
3115 return (GE_TRYAGAIN);
3118 GSM_Error N6110_GetRevision(char *revision)
3121 if (strlen(Current_Revision)>0) {
3122 strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
3126 return (GE_TRYAGAIN);
3129 static GSM_Error N6110_GetModel(char *model)
3131 if (strlen(Current_Model)>0) {
3132 strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
3136 return (GE_TRYAGAIN);
3141 void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3143 switch (MessageBuffer[4]) {
3147 fprintf(stdout, _("Message: Date and time set correctly\n"));
3149 CurrentSetDateTimeError=GE_NONE;
3154 fprintf(stdout, _("Message: Date and time setting error\n"));
3156 CurrentSetDateTimeError=GE_INVALIDDATETIME;
3161 /* Needs SIM card with PIN in phone */
3162 GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
3164 return N6110_PrivSetDateTime(date_time,0x11);
3167 /* Needs SIM card with PIN in phone */
3168 GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
3171 unsigned char req[] = { N6110_FRAME_HEADER,
3172 0x60, /* set-time subtype */
3173 0x01, 0x01, 0x07, /* unknown */
3174 0x00, 0x00, /* Year (0x07cf = 1999) */
3175 0x00, 0x00, /* Month Day */
3176 0x00, 0x00, /* Hours Minutes */
3177 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3180 EncodeDateTime(req+7, date_time);
3182 return NULL_SendMessageSequence
3183 (20, &CurrentSetDateTimeError, 14, msgtype, req);
3186 void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3188 switch (MessageBuffer[4]) {
3192 fprintf(stdout, _("Message: Alarm set correctly\n"));
3194 CurrentSetAlarmError=GE_NONE;
3199 fprintf(stdout, _("Message: Alarm setting error\n"));
3201 CurrentSetAlarmError=GE_INVALIDDATETIME;
3206 /* FIXME: we should also allow to set the alarm off :-) */
3207 GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
3209 return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
3212 /* FIXME: we should also allow to set the alarm off :-) */
3213 GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
3216 unsigned char req[] = { N6110_FRAME_HEADER,
3217 0x6b, /* set-alarm subtype */
3218 0x01, 0x20, 0x03, /* unknown */
3219 0x02, /* should be alarm on/off, but it don't works */
3220 0x00, 0x00, /* Hours Minutes */
3221 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3224 req[8] = date_time->Hour;
3225 req[9] = date_time->Minute;
3227 return NULL_SendMessageSequence
3228 (50, &CurrentSetAlarmError, 11, msgtype, req);
3231 #endif /* UCLINUX */
3233 static void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3235 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
3240 switch (MessageBuffer[3]) {
3244 CurrentPhonebookEntry->Empty = true;
3246 count=MessageBuffer[5];
3249 fprintf(stdout, _("Message: Phonebook entry received:\n"));
3250 fprintf(stdout, _(" Name: "));
3252 for (tmp=0; tmp <count; tmp++)
3254 if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
3255 if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
3256 fprintf(stdout, "%c", MessageBuffer[6+tmp]);
3259 fprintf(stdout, "\n");
3262 while (N6110_GetModel(model) != GE_NONE)
3265 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3267 DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
3268 CurrentPhonebookEntry->Name[count/2] = 0x00;
3270 fprintf(stderr,"FATAL ERROR: DecodeUnicode disabled!\n");
3272 #endif /* UCLINUX */
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) {
3442 req[6] = strlen(entry->Name)*2;
3444 EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
3446 for (i=0; i<strlen(entry->Name); i++)
3448 /* here we encode "special" chars */
3449 if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
3450 if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
3453 current+=strlen(entry->Name)*2;
3457 fprintf(stderr,"FATAL ERROR: EncodeUnicode disabled!\n");
3460 #endif /* UCLINUX */
3463 req[6] = strlen(entry->Name);
3465 for (i=0; i<strlen(entry->Name); i++)
3467 req[current+i] = entry->Name[i];
3469 /* here we encode "special" chars */
3470 if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
3471 if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
3474 current+=strlen(entry->Name);
3477 req[current++]=strlen(entry->Number);
3479 for (i=0; i<strlen(entry->Number); i++)
3480 req[current+i] = entry->Number[i];
3482 current+=strlen(entry->Number);
3484 /* Jano: This allow to save 14 characters name into SIM memory, when
3485 No Group is selected. */
3486 if (entry->Group == 5)
3487 req[current++]=0xff;
3489 req[current++]=entry->Group;
3491 return NULL_SendMessageSequence
3492 (50, &CurrentPhonebookError, current, 0x03, req);
3497 void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3499 switch(MessageBuffer[3]) {
3503 fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
3505 CurrentNetmonitorError=GE_NONE;
3510 fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
3511 fprintf(stdout, "%s\n", MessageBuffer+4);
3514 strcpy(CurrentNetmonitor, MessageBuffer+4);
3516 CurrentNetmonitorError=GE_NONE;
3520 GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
3522 unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
3526 error=N6110_EnableExtendedCommands(0x01);
3527 if (error!=GE_NONE) return error;
3529 CurrentNetmonitor=Screen;
3533 return NULL_SendMessageSequence
3534 (20, &CurrentNetmonitorError, 4, 0x40, req);
3537 /* Doesn't work in N3210. */
3538 /* In other allow to access phone menu without SIM card (just send any sequence) */
3539 GSM_Error N6110_SendDTMF(char *String)
3541 unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
3542 0x00 /* Length of DTMF string. */
3545 u8 length=strlen(String);
3547 if (length>59) length=59;
3551 memcpy(req+5,String,length);
3553 return NULL_SendMessageSequence
3554 (20, &CurrentSendDTMFError, 5+length, 0x01, req);
3557 #endif /* UCLINUX */
3559 static void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3561 switch (MessageBuffer[3]) {
3565 switch (MessageBuffer[4]) {
3566 case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
3567 default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
3570 CurrentSpeedDialEntry->Location = MessageBuffer[5];
3573 fprintf(stdout, _("Message: Speed dial entry received:\n"));
3574 fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
3575 fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
3576 fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
3579 CurrentSpeedDialError=GE_NONE;
3585 fprintf(stdout, _("Message: Speed dial entry error\n"));
3587 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3593 GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
3596 unsigned char req[] = { N6110_FRAME_HEADER,
3598 0x00 /* The number of speed dial. */
3601 CurrentSpeedDialEntry = entry;
3603 req[4] = entry->Number;
3605 return NULL_SendMessageSequence
3606 (20, &CurrentSpeedDialError, 5, 0x03, req);
3609 static void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3611 switch (MessageBuffer[3]) {
3616 fprintf(stdout, _("Message: Speed dial entry set.\n"));
3618 CurrentSpeedDialError=GE_NONE;
3624 fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
3626 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3632 GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
3635 unsigned char req[] = { N6110_FRAME_HEADER,
3638 0x00, /* Memory Type */
3642 req[4] = entry->Number;
3644 switch (entry->MemoryType) {
3645 case GMT_ME: req[5] = 0x02;
3646 default : req[5] = 0x03;
3649 req[6] = entry->Location;
3651 return NULL_SendMessageSequence
3652 (20, &CurrentSpeedDialError, 7, 0x03, req);
3657 /* This function finds parts of SMS in frame used in new Nokia phones
3658 in internal protocols (they're coded according to GSM 03.40), copies them
3659 to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
3660 GSM_ETSISMSMessage to GSM_SMSMessage structure */
3661 GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
3663 SMS_MessageType PDU=SMS_Deliver;
3664 GSM_ETSISMSMessage ETSI;
3667 ETSI.firstbyte=req[12];
3669 /* See GSM 03.40 section 9.2.3.1 */
3670 if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
3671 if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
3674 case SMS_Submit : offset=5;break;
3675 case SMS_Deliver : offset=4;break;
3676 case SMS_Status_Report: offset=3;break;
3680 for (i=0;i<req[0]+1;i++)
3681 ETSI.SMSCNumber[i]=req[i];
3683 for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
3684 ETSI.Number[i]=req[i+12+offset];
3688 ETSI.TPDCS=req[10+offset];
3689 ETSI.TPUDL=req[11+offset];
3690 ETSI.TPVP=0; //no support for now
3691 ETSI.TPPID=0; //no support for now
3692 for(i=31+offset;i<length;i++)
3693 ETSI.MessageText[i-31-offset]=req[i];
3696 ETSI.TPDCS=req[10+offset];
3697 ETSI.TPUDL=req[11+offset];
3698 ETSI.TPPID=0; //no support for now
3699 for(i=31+offset;i<length;i++)
3700 ETSI.MessageText[i-31-offset]=req[i];
3702 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3704 case SMS_Status_Report:
3706 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3707 ETSI.TPStatus=req[14];
3709 ETSI.SMSCDateTime[i]=req[i+34];
3715 GSM_DecodeETSISMS(SMS, &ETSI);
3722 void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3726 switch (MessageBuffer[3]) {
3730 switch (MessageBuffer[7]) {
3733 CurrentSMSMessage->Type = GST_SMS;
3734 CurrentSMSMessage->folder=GST_INBOX;
3739 CurrentSMSMessage->Type = GST_DR;
3740 CurrentSMSMessage->folder=GST_INBOX;
3745 CurrentSMSMessage->Type = GST_SMS;
3746 CurrentSMSMessage->folder=GST_OUTBOX;
3751 CurrentSMSMessage->Type = GST_UN;
3757 /* Field Short Message Status - MessageBuffer[4] seems not to be
3758 compliant with GSM 07.05 spec.
3759 Meaning Nokia protocol GMS spec
3760 ----------------------------------------------------
3761 MO Sent 0x05 0x07 or 0x01
3762 MO Not sent 0x07 0x06 or 0x00
3763 MT Read 0x01 0x05 or 0x01
3764 MT Not read 0x03 0x04 or 0x00
3765 ----------------------------------------------------
3766 See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
3770 if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
3771 else CurrentSMSMessage->Status = GSS_SENTREAD;
3774 fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
3776 if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
3777 fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
3779 fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
3782 if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
3783 if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
3785 if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
3786 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
3787 else fprintf(stdout, _(" Not sent\n"));
3789 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
3790 else fprintf(stdout, _(" Not read\n"));
3794 CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
3796 CurrentSMSMessage->MemoryType = MessageBuffer[5];
3797 CurrentSMSMessage->MessageNumber = MessageBuffer[6];
3799 /* Signal no error to calling code. */
3800 CurrentSMSMessageError = GE_NONE;
3803 fprintf(stdout, "\n");
3810 /* We have requested invalid or empty location. */
3813 fprintf(stdout, _("Message: SMS reading failed\n"));
3815 switch (MessageBuffer[4]) {
3817 fprintf(stdout, _(" Invalid location!\n"));break;
3819 fprintf(stdout, _(" Empty SMS location.\n"));break;
3821 fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
3823 fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
3827 switch (MessageBuffer[4]) {
3828 case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3829 case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
3830 case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
3831 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3839 GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
3842 unsigned char req[] = { N6110_FRAME_HEADER,
3845 0x00, /* Location */
3850 /* State machine code writes data to these variables when it comes in. */
3852 CurrentSMSMessage = message;
3853 CurrentSMSMessageError = GE_BUSY;
3855 req[5] = message->Location;
3858 Protocol->SendMessage(8, 0x02, req);
3860 /* Wait for timeout or other error. */
3861 while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
3864 return (GE_TIMEOUT);
3869 return (CurrentSMSMessageError);
3872 void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3875 fprintf(stdout, _("Message: SMS deleted successfully.\n"));
3878 CurrentSMSMessageError = GE_NONE;
3881 GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
3883 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
3885 req[5] = message->Location;
3887 return NULL_SendMessageSequence
3888 (50, &CurrentSMSMessageError, 6, 0x14, req);
3891 /* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
3892 GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
3894 GSM_ETSISMSMessage ETSI;
3897 GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
3900 for (i=0;i<36;i++) req[i]=0;
3902 req[12]=ETSI.firstbyte;
3904 for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
3905 req[i]=ETSI.SMSCNumber[i];
3910 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3911 req[i+12+offset]=ETSI.Number[i];
3912 req[10+offset]=ETSI.TPDCS;
3913 req[11+offset]=ETSI.TPUDL;
3914 req[24+offset]=ETSI.TPVP;
3916 // fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
3917 // fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
3918 // fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
3920 // req[]=ETSI.TPPID;
3921 for(i=0;i<*length;i++)
3922 req[i+31+offset]=ETSI.MessageText[i];
3927 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3928 req[i+12+offset]=ETSI.Number[i];
3929 req[10+offset]=ETSI.TPDCS;
3930 req[11+offset]=ETSI.TPUDL;
3931 // req[]=ETSI.TPPID;
3932 for(i=0;i<*length;i++)
3933 req[i+31+offset]=ETSI.MessageText[i];
3935 req[24+offset+i]=ETSI.DeliveryDateTime[i];
3941 *length=*length+offset;
3946 void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3948 switch (MessageBuffer[3]) {
3950 /* SMS message correctly sent to the network */
3953 fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
3955 CurrentSMSMessageError = GE_SMSSENDOK;
3958 /* SMS message send to the network failed */
3962 fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
3964 switch (MessageBuffer[6]) {
3965 case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3966 case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
3967 case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3968 case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
3969 case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3970 case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3971 case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3972 case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3973 case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3976 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
3977 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
3980 CurrentSMSMessageError = GE_SMSSENDFAILED;
3986 GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
3990 unsigned char req[256] = {
3992 0x01, 0x02, 0x00, /* SMS send request*/
3997 error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
3998 if (error != GE_NONE) return error;
4000 return NULL_SendMessageSequence
4001 (200, &CurrentSMSMessageError, 42+length, 0x02, req);
4004 void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4006 switch (MessageBuffer[3]) {
4011 fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
4014 CurrentSMSMessage->MessageNumber=MessageBuffer[5];
4016 CurrentSMSMessageError = GE_NONE;
4021 fprintf(stdout, _("SMS saving failed\n"));
4022 switch (MessageBuffer[4]) {
4023 case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
4024 case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
4025 default :fprintf(stdout, _(" Unknown error.\n"));break;
4029 switch (MessageBuffer[4]) {
4030 case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
4031 case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
4032 default :CurrentSMSMessageError = GE_UNKNOWN;break;
4037 /* GST_DR and GST_UN not supported ! */
4038 GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
4040 unsigned char req[256] = {
4041 N6110_FRAME_HEADER, 0x04, /* SMS save request*/
4042 0x00, /* SMS Status. Different for Inbox and Outbox */
4044 0x00, /* SMS Location */
4045 0x02, /* SMS Type */
4049 SMS_MessageType PDU;
4052 if (SMS->Location) req[6] = SMS->Location;
4054 if (SMS->folder==0) { /*Inbox*/
4055 req[4]=1; /* SMS Status */
4056 req[7] = 0x00; /* SMS Type */
4059 req[4]=5; /* SMS Status */
4060 req[7] = 0x02; /* SMS Type */
4064 if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
4066 error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
4067 if (error != GE_NONE) return error;
4069 CurrentSMSMessage = SMS;
4071 return NULL_SendMessageSequence
4072 (70, &CurrentSMSMessageError, 39+length, 0x14, req);
4075 void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4078 fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
4081 CurrentCBError = GE_NONE;
4084 /* Enable and disable Cell Broadcasting */
4085 GSM_Error N6110_EnableCellBroadcast(void)
4087 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4088 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
4091 fprintf (stdout,"Enabling CB\n");
4094 CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
4095 CurrentCBMessage->Channel = 0;
4096 CurrentCBMessage->New = false;
4097 strcpy (CurrentCBMessage->Message,"");
4099 return NULL_SendMessageSequence
4100 (10, &CurrentCBError, 10, 0x02, req);
4104 GSM_Error N6110_DisableCellBroadcast(void)
4106 /* Should work, but not tested fully */
4108 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
4111 return NULL_SendMessageSequence
4112 (10, &CurrentCBError, 10, 0x02, req);
4115 void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4118 unsigned char output[160];
4120 CurrentCBMessage->Channel = MessageBuffer[7];
4121 CurrentCBMessage->New = true;
4122 tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
4125 fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
4127 fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
4131 for (i=0; i<tmp;i++) {
4132 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
4135 fprintf(stdout, "\n");
4138 for (i=0; i<tmp; i++) {
4139 CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
4141 CurrentCBMessage->Message[i]=0;
4144 GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
4147 fprintf(stdout,"Reading CB\n");
4150 if (CurrentCBMessage != NULL)
4152 if (CurrentCBMessage->New == true)
4155 fprintf(stdout,"New CB received\n");
4157 Message->Channel = CurrentCBMessage->Channel;
4158 strcpy(Message->Message,CurrentCBMessage->Message);
4159 CurrentCBMessage->New = false;
4163 return (GE_NONEWCBRECEIVED);
4166 int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
4170 req[count++]=Bitmap.number;
4171 req[count++]=strlen(Bitmap.text);
4172 memcpy(req+count,Bitmap.text,req[count-1]);
4173 count+=req[count-1];
4174 req[count++]=Bitmap.ringtone;
4176 /* Setting for graphic:
4179 0x02 - View Graphics
4180 0x03 - Send Graphics
4182 You can even set it higher but Nokia phones (my
4183 6110 at least) will not show you the name of this
4184 item in menu ;-)) Nokia is really joking here. */
4185 if (Bitmap.enabled) req[count++]=0x01;
4186 else req[count++]=0x00;
4188 req[count++]=(Bitmap.size+4)>>8;
4189 req[count++]=(Bitmap.size+4)%0xff;
4190 req[count++]=0x00; /* Future extensions! */
4191 req[count++]=Bitmap.width;
4192 req[count++]=Bitmap.height;
4193 req[count++]=0x01; /* Just BW */
4194 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4196 return count+Bitmap.size;
4199 int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4203 EncodeNetworkCode(req+count, Bitmap.netcode);
4206 req[count++]=(Bitmap.size+4)>>8;
4207 req[count++]=(Bitmap.size+4)%0xff;
4208 req[count++]=0x00; /* Infofield */
4209 req[count++]=Bitmap.width;
4210 req[count++]=Bitmap.height;
4211 req[count++]=0x01; /* Just BW */
4212 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4214 return count+Bitmap.size;
4217 int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4222 req[count++]=Bitmap.height;
4223 req[count++]=Bitmap.width;
4224 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4226 return count+Bitmap.size;
4229 /* Set a bitmap or welcome-note */
4230 GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
4232 unsigned char req[600] = { N6110_FRAME_HEADER };
4238 /* Direct uploading variables */
4239 GSM_MultiSMSMessage SMS;
4240 unsigned char buffer[1000] = {0x0c,0x01};
4241 GSM_NetworkInfo NetworkInfo;
4245 /* Uploading with preview */
4246 if (Bitmap->number==255 &&
4247 (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
4248 GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
4249 memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
4251 memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
4253 buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
4255 Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
4257 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4258 return GE_NONE; //no answer from phone
4261 CurrentSetBitmapError = GE_BUSY;
4263 switch (Bitmap->type) {
4264 case GSM_WelcomeNoteText:
4265 case GSM_DealerNoteText:
4267 req[count++]=0x01; /* Only one block */
4269 if (Bitmap->type==GSM_WelcomeNoteText)
4270 req[count++]=0x02; /* Welcome text */
4272 req[count++]=0x03; /* Dealer Welcome Note */
4274 textlen=strlen(Bitmap->text);
4275 req[count++]=textlen;
4276 memcpy(req+count,Bitmap->text,textlen);
4280 Protocol->SendMessage(count, 0x05, req);
4284 case GSM_StartupLogo:
4285 if (Bitmap->number==0) {
4287 /* For 33xx we first set animated logo to default */
4288 if (GetModelFeature (FN_STARTUP)==F_STANIM) {
4289 error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4290 if (error!=GE_NONE) return error;
4294 req[count++]=0x01; /* Only one block */
4295 count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
4296 Protocol->SendMessage(count, 0x05, req);
4298 return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4302 case GSM_OperatorLogo:
4303 req[count++]=0x30; /* Store Op Logo */
4304 req[count++]=0x01; /* Location */
4305 count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
4306 Protocol->SendMessage(count, 0x05, req);
4309 case GSM_CallerLogo:
4311 count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
4312 Protocol->SendMessage(count, 0x03, req);
4315 case GSM_PictureImage:
4317 req[count++]=Bitmap->number;
4318 if (strcmp(Bitmap->Sender,"")) {
4319 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
4321 /* Convert number of semioctets to number of chars and add count */
4323 if (textlen % 2) textlen++;
4324 count+=textlen / 2 + 1;
4332 req[count++]=strlen(Bitmap->text);
4333 memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
4334 count+=strlen(Bitmap->text);
4336 req[count++]=Bitmap->width;
4337 req[count++]=Bitmap->height;
4339 memcpy(req+count,Bitmap->bitmap,Bitmap->size);
4340 Protocol->SendMessage(count+Bitmap->size, 0x47, req);
4343 case GSM_7110OperatorLogo:
4344 case GSM_7110StartupLogo:
4345 case GSM_6210StartupLogo:
4346 return GE_NOTSUPPORTED;
4352 /* Wait for timeout or other error. */
4353 while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
4356 return (GE_TIMEOUT);
4361 return CurrentSetBitmapError;
4364 /* Get a bitmap from the phone */
4365 GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
4367 unsigned char req[10] = { N6110_FRAME_HEADER };
4372 CurrentGetBitmap=Bitmap;
4373 CurrentGetBitmapError = GE_BUSY;
4375 switch (CurrentGetBitmap->type) {
4376 case GSM_StartupLogo:
4377 case GSM_WelcomeNoteText:
4378 case GSM_DealerNoteText:
4380 Protocol->SendMessage(count, 0x05, req);
4382 case GSM_OperatorLogo:
4384 req[count++]=0x01; /* Location 1 */
4385 Protocol->SendMessage(count, 0x05, req);
4387 case GSM_CallerLogo:
4389 req[count++]=Bitmap->number;
4390 Protocol->SendMessage(count, 0x03, req);
4392 case GSM_PictureImage:
4394 req[count++]=Bitmap->number;
4395 Protocol->SendMessage(count, 0x47, req);
4397 case GSM_7110OperatorLogo:
4398 case GSM_7110StartupLogo:
4399 case GSM_6210StartupLogo:
4401 return GE_NOTSUPPORTED;
4404 /* Wait for timeout or other error. */
4405 while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
4408 return (GE_TIMEOUT);
4413 CurrentGetBitmap=NULL;
4415 return CurrentGetBitmapError;
4418 void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4420 switch (MessageBuffer[3]) {
4422 /* Set ringtone OK */
4425 fprintf(stdout, _("Message: Ringtone set OK!\n"));
4427 CurrentRingtoneError=GE_NONE;
4430 /* Set ringtone error */
4433 fprintf(stdout, _("Message: Ringtone setting error !\n"));
4435 CurrentRingtoneError=GE_NOTSUPPORTED;
4440 GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
4443 char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
4444 {N6110_FRAME_HEADER,
4446 0x00, /* Location */
4449 int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
4451 /* Variables for preview uploading */
4452 unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
4453 unsigned char buffer2[20];
4454 GSM_NetworkInfo NetworkInfo;
4456 /* Setting ringtone with preview */
4457 if (ringtone->location==255) {
4460 EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
4461 memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
4462 *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
4463 Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
4464 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4466 return GE_NONE; //no answer from phone
4469 *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
4471 req[4]=ringtone->location-1;
4473 return NULL_SendMessageSequence
4474 (50, &CurrentRingtoneError, (size+7), 0x05, req);
4477 void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4481 switch (MessageBuffer[4]) {
4482 case 0x00: /* location supported. We have ringtone */
4484 /* Binary format used in N6150 */
4485 if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4487 fprintf(stdout,_("Message: ringtone \""));
4494 if (MessageBuffer[i]!=0)
4495 fprintf(stdout,_("%c"),MessageBuffer[i]);
4497 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4498 if (MessageBuffer[i]==0) break;
4503 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4506 /* Looking for end */
4509 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4512 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4516 if (i==MessageLength) break;
4520 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4521 CurrentGetBinRingtone->length=i-3;
4523 CurrentBinRingtoneError=GE_NONE;
4527 /* Binary format used in N3210 */
4528 if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4531 fprintf(stdout,_("Message: ringtone \""));
4538 if (MessageBuffer[i]!=0)
4539 fprintf(stdout,_("%c"),MessageBuffer[i]);
4541 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4542 if (MessageBuffer[i]==0) break;
4547 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4550 /* Here changes to get full compatibility with binary format used in N6150 */
4553 MessageBuffer[5]=0x0c;
4554 MessageBuffer[6]=0x01;
4555 MessageBuffer[7]=0x2c;
4557 /* Looking for end */
4560 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4563 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4567 if (i==MessageLength) break;
4571 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4573 CurrentGetBinRingtone->length=i-3;
4575 CurrentBinRingtoneError=GE_NONE;
4580 memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
4582 CurrentGetBinRingtone->length=MessageLength;
4585 fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
4587 CurrentBinRingtoneError=GE_UNKNOWNMODEL;
4593 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4596 CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
4600 GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
4602 unsigned char req[] = { 0x00,0x01,0x9e,
4607 CurrentGetBinRingtone=ringtone;
4609 error=N6110_EnableExtendedCommands(0x01);
4610 if (error!=GE_NONE) return error;
4612 req[3]=ringtone->location-1;
4614 return NULL_SendMessageSequence
4615 (50, &CurrentBinRingtoneError, 4, 0x40, req);
4618 void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4620 switch (MessageBuffer[4]) {
4621 case 0x00: /* location supported. We set ringtone */
4623 fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
4625 CurrentBinRingtoneError=GE_NONE;
4630 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4632 CurrentBinRingtoneError=GE_NOTSUPPORTED;
4637 GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
4639 unsigned char req[1000] = { 0x00,0x01,0xa0};
4643 GSM_BinRingtone ring;
4645 /* Must be sure, that can upload ringtone to this phone */
4646 ring.location=ringtone->location;
4647 error=N6110_GetBinRingTone(&ring);
4648 if (error!=GE_NONE) return error;
4650 error=N6110_EnableExtendedCommands(0x01);
4651 if (error!=GE_NONE) return error;
4653 memcpy(req+3,ringtone->frame,ringtone->length);
4655 req[3]=ringtone->location-1;
4657 return NULL_SendMessageSequence
4658 (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
4661 #endif /* UCLINUX */
4663 GSM_Error N6110_Reset(unsigned char type)
4665 return N6110_EnableExtendedCommands(type);
4668 void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4675 switch (MessageBuffer[3]) {
4677 /* Unknown message - it has been seen after the 0x07 message (call
4678 answered). Probably it has similar meaning. If you can solve
4679 this - just mail me. Pavel JanÃk ml.
4681 The message looks like this:
4689 Phone: [01 ][08 ][00 ] is the header of the frame
4691 [03 ] is the call message subtype
4693 [05 ] is the call sequence number
4697 [00 ][01 ][03 ][02 ][91][00] are unknown but has been
4698 seen in the Incoming call message (just after the
4699 caller's name from the phonebook). But never change
4700 between phone calls :-(
4703 /* This may mean sequence number of 'just made' call - CK */
4707 fprintf(stdout, _("Message: Call message, type 0x02:"));
4708 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4713 /* Possibly call OK */
4714 /* JD: I think that this means "call in progress" (incomming or outgoing) */
4718 fprintf(stdout, _("Message: Call message, type 0x03:"));
4719 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4720 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4723 CurrentCallSequenceNumber=MessageBuffer[4];
4725 CurrentIncomingCall[0]='D';
4726 #endif /* UCLINUX */
4727 if (CurrentCallPassup) CurrentCallPassup('D');
4731 /* Remote end has gone away before you answer the call. Probably your
4732 mother-in-law or banker (which is worse?) ... */
4736 fprintf(stdout, _("Message: Remote end hang up.\n"));
4737 fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
4739 switch (MessageBuffer[6]) {
4740 case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
4741 case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
4742 case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
4743 case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4744 case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
4745 case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4748 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
4749 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4753 CurrentIncomingCall[0] = ' ';
4754 #endif /* UCLINUX */
4755 if (CurrentCallPassup) CurrentCallPassup(' ');
4759 /* Incoming call alert */
4763 fprintf(stdout, _("Message: Incoming call alert:\n"));
4765 /* We can have more then one call ringing - we can distinguish between
4768 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4769 fprintf(stdout, _(" Number: "));
4771 count=MessageBuffer[6];
4773 for (tmp=0; tmp <count; tmp++)
4774 fprintf(stdout, "%c", MessageBuffer[7+tmp]);
4776 fprintf(stdout, "\n");
4778 fprintf(stdout, _(" Name: "));
4780 for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
4781 fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
4783 fprintf(stdout, "\n");
4786 count=MessageBuffer[6];
4789 CurrentIncomingCall[0] = 0;
4790 for (tmp=0; tmp <count; tmp++)
4791 sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
4792 #endif /* UCLINUX */
4796 /* Call answered. Probably your girlfriend...*/
4800 fprintf(stdout, _("Message: Call answered.\n"));
4801 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4806 /* Call ended. Girlfriend is girlfriend, but time is money :-) */
4810 fprintf(stdout, _("Message: Call ended by your phone.\n"));
4811 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4816 /* This message has been seen with the message of subtype 0x09
4817 after I hang the call.
4824 Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
4826 What is the meaning of 87? Can you spell some magic light into
4831 /* Probably means call over - CK */
4835 fprintf(stdout, _("Message: Call message, type 0x0a:"));
4836 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4837 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4841 CurrentIncomingCall[0] = ' ';
4842 #endif /* UCLINUX */
4843 if (CurrentCallPassup) CurrentCallPassup(' ');
4850 fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
4854 if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
4855 #endif /* UCLINUX */
4857 if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
4864 fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
4866 AppendLogText("Unknown msg\n",false);
4868 break; /* Visual C Don't like empty cases */
4874 static void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4878 switch (MessageBuffer[3]) {
4882 /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
4883 /* If you want see, if it works with your phone make something like that: */
4885 /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
4886 /* Protocol->SendMessage(4, 0x04, connect5); */
4888 /* Marcin-Wiacek@TopNet.PL */
4890 #if defined(WIN32) || defined(UCLINUX)
4891 sprintf(Current_IMEI, "%s", MessageBuffer+5);
4892 sprintf(Current_Model, "%s", MessageBuffer+21);
4893 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4895 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
4896 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
4897 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4901 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
4902 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
4903 fprintf(stdout, _(" Model: %s\n"), Current_Model);
4904 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
4905 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
4906 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
4911 /* Get group data */
4912 /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
4915 if (CurrentGetBitmap!=NULL) {
4916 if (CurrentGetBitmap->number==MessageBuffer[4]) {
4917 count=MessageBuffer[5];
4918 memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
4919 CurrentGetBitmap->text[count]=0;
4922 fprintf(stdout, _("Message: Caller group datas\n"));
4923 fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
4928 CurrentGetBitmap->ringtone=MessageBuffer[count++];
4930 fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
4931 if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
4932 fprintf(stdout,_("\n"));
4935 CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
4937 fprintf(stdout, _("Caller group logo "));
4938 if (CurrentGetBitmap->enabled)
4939 fprintf(stdout, _("enabled \n"));
4941 fprintf(stdout, _("disabled \n"));
4944 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4945 CurrentGetBitmap->size+=MessageBuffer[count++];
4947 fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
4951 CurrentGetBitmap->width=MessageBuffer[count++];
4952 CurrentGetBitmap->height=MessageBuffer[count++];
4954 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
4955 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4956 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
4957 CurrentGetBitmapError=GE_NONE;
4960 fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
4965 fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
4970 /* Get group data error */
4973 CurrentGetBitmapError=GE_UNKNOWN;
4975 fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
4979 /* Set group data OK */
4982 CurrentSetBitmapError=GE_NONE;
4984 fprintf(stdout, _("Message: Caller group data set correctly.\n"));
4988 /* Set group data error */
4991 CurrentSetBitmapError=GE_UNKNOWN;
4993 fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
5000 fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
5002 AppendLogText("Unknown msg\n",false);
5004 break; /* Visual C Don't like empty cases */
5008 static void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5010 int tmp, count, length;
5017 switch (MessageBuffer[3]) {
5023 fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
5026 if (CurrentGetBitmap!=NULL) {
5032 for (tmp=0;tmp<MessageBuffer[4];tmp++){
5033 switch (MessageBuffer[count++]) {
5035 if (CurrentGetBitmap->type==GSM_StartupLogo) {
5036 CurrentGetBitmap->height=MessageBuffer[count++];
5037 CurrentGetBitmap->width=MessageBuffer[count++];
5038 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5039 length=CurrentGetBitmap->size;
5040 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
5042 length=MessageBuffer[count++];
5043 length=length*MessageBuffer[count++]/8;
5047 fprintf(stdout, _("Startup logo supported - "));
5048 if (length!=0) { fprintf(stdout, _("currently set\n")); }
5049 else { fprintf(stdout, _("currently empty\n")); }
5051 if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
5054 length=MessageBuffer[count];
5055 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
5056 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5057 CurrentGetBitmap->text[length]=0;
5060 fprintf(stdout, _("Startup Text supported - "));
5063 fprintf(stdout, _("currently set to \""));
5064 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5065 fprintf(stdout, _("\"\n"));
5067 fprintf(stdout, _("currently empty\n"));
5071 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
5074 length=MessageBuffer[count];
5075 if (CurrentGetBitmap->type==GSM_DealerNoteText) {
5076 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5077 CurrentGetBitmap->text[length]=0;
5080 fprintf(stdout, _("Dealer Welcome supported - "));
5083 fprintf(stdout, _("currently set to \""));
5084 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5085 fprintf(stdout, _("\"\n"));
5087 fprintf(stdout, _("currently empty\n"));
5091 if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
5095 if (issupported) CurrentGetBitmapError=GE_NONE;
5096 else CurrentGetBitmapError=GE_NOTSUPPORTED;
5099 fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
5104 /* Set startup OK */
5107 CurrentSetBitmapError=GE_NONE;
5109 fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
5113 /* Set Operator Logo OK */
5117 fprintf(stdout, _("Message: Operator logo correctly set.\n"));
5120 CurrentSetBitmapError=GE_NONE;
5123 /* Set Operator Logo Error */
5127 fprintf(stdout, _("Message: Error setting operator logo!\n"));
5130 CurrentSetBitmapError=GE_UNKNOWN;
5134 /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
5137 if (CurrentGetBitmap!=NULL) {
5139 count=5; /* Location ignored. */
5141 DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
5145 fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
5146 CurrentGetBitmap->netcode,
5147 GSM_GetNetworkName(CurrentGetBitmap->netcode));
5150 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
5151 CurrentGetBitmap->size+=MessageBuffer[count++];
5153 CurrentGetBitmap->width=MessageBuffer[count++];
5154 CurrentGetBitmap->height=MessageBuffer[count++];
5156 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5157 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
5158 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
5159 CurrentGetBitmapError=GE_NONE;
5162 fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
5168 /* Get op logo error */
5172 fprintf(stdout, _("Message: Error getting operator logo!\n"));
5174 CurrentGetBitmapError=GE_UNKNOWN;
5180 fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
5182 AppendLogText("Unknown msg\n",false);
5188 static void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5191 unsigned char output[160];
5197 switch (MessageBuffer[3]) {
5201 /* MessageBuffer[3] = 0x05
5202 MessageBuffer[4] = 0x00
5203 MessageBuffer[5] = 0x0f
5204 MessageBuffer[6] = 0x03
5205 MessageBuffer[7] = length of packed message
5207 This is all I have seen - Gerry Anderson */
5209 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
5213 fprintf(stdout, _("Message from Network operator: "));
5215 for (i=0; i<tmp; i++)
5216 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
5218 fprintf(stdout, "\n");
5227 fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
5229 AppendLogText("Unknown msg\n",false);
5235 #endif /* UCLINUX */
5237 static void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5239 switch (MessageBuffer[3]) {
5243 fprintf(stdout, _("Message: SIM card login\n"));
5249 fprintf(stdout, _("Message: SIM card logout\n"));
5255 fprintf(stdout, _("Unknown message of type 0x09.\n"));
5257 AppendLogText("Unknown msg\n",false);
5264 static void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5266 switch(MessageBuffer[3]) {
5271 fprintf(stdout, _("Message: Calendar Alarm active\n"));
5272 fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
5277 fprintf(stdout, _("Unknown message of type 0x13.\n"));
5279 AppendLogText("Unknown msg\n",false);
5284 #endif /* UCLINUX */
5286 void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5290 switch(MessageBuffer[2]) {
5295 fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
5298 CurrentMagicError=GE_NONE;
5304 fprintf(stdout, _("Message: Answer for call commands.\n"));
5307 CurrentDialVoiceError=GE_NONE;
5313 fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
5316 CurrentMagicError=GE_NONE;
5322 fprintf(stdout, _("Message: ACK for simlock closing\n"));
5325 CurrentMagicError=GE_NONE;
5330 switch (MessageBuffer[5]) {
5333 fprintf(stdout,_("Message: EEPROM contest received\n"));
5336 if (MessageBuffer[8]!=0x00) {
5337 for (i=9;i<MessageLength;i++) {
5338 fprintf(stdout,_("%c"), MessageBuffer[i]);
5341 CurrentMagicError=GE_NONE;
5348 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5350 AppendLogText("Unknown msg\n",false);
5356 N6110_DisplayTestsInfo(MessageBuffer);
5358 #endif /* UCLINUX */
5363 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5365 AppendLogText("Unknown msg\n",false);
5366 break; /* Visual C Don't like empty cases */
5372 static void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5376 switch(MessageBuffer[3]) {
5382 if (MessageBuffer[5]!=0) {
5383 strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
5385 while (MessageBuffer[count]!=0) {
5391 strcpy(CurrentGetBitmap->Sender,"\0");
5396 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
5397 CurrentGetBitmap->text[MessageBuffer[count]]=0;
5399 if (MessageBuffer[count]!=0)
5400 count+=MessageBuffer[count];
5405 fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
5408 CurrentGetBitmap->width=MessageBuffer[count+1];
5409 CurrentGetBitmap->height=MessageBuffer[count+2];
5410 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5412 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
5414 CurrentGetBitmapError=GE_NONE;
5420 fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
5422 CurrentSetBitmapError=GE_NONE;
5423 CurrentGetBitmapError=GE_NONE;
5429 fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
5431 CurrentSetBitmapError=GE_UNKNOWN;
5437 fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
5439 CurrentGetBitmapError=GE_UNKNOWN;
5445 fprintf(stdout, _("Unknown message of type 0x47.\n"));
5447 AppendLogText("Unknown msg\n",false);
5448 break; /* Visual C Don't like empty cases */
5452 #endif /* UCLINUX */
5454 void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5457 sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
5458 AppendLog(buffer,strlen(buffer),false);
5461 fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
5465 CurrentLinkOK = true;
5468 static void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5471 fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
5476 /* This function is used for parsing the RLP frame into fields. */
5477 void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
5484 /* We do not need RLP frame parsing to be done when we do not have callback
5486 if (CurrentRLP_RXCallback == NULL)
5489 /* Anybody know the official meaning of the first two bytes?
5490 Nokia 6150 sends junk frames starting D9 01, and real frames starting
5491 D9 00. We'd drop the junk frames anyway because the FCS is bad, but
5492 it's tidier to do it here. We still need to call the callback function
5493 to give it a chance to handle timeouts and/or transmit a frame */
5494 if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
5497 /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
5498 specification, so Header consists of 16 bits (2 bytes). See section 4.1
5499 of the specification. */
5501 frame.Header[0] = MessageBuffer[2];
5502 frame.Header[1] = MessageBuffer[3];
5504 /* Next 200 bits (25 bytes) contain the Information. We store the
5505 information in the Data array. */
5507 for (count = 0; count < 25; count ++)
5508 frame.Data[count] = MessageBuffer[4 + count];
5510 /* The last 24 bits (3 bytes) contain FCS. */
5512 frame.FCS[0] = MessageBuffer[29];
5513 frame.FCS[1] = MessageBuffer[30];
5514 frame.FCS[2] = MessageBuffer[31];
5516 /* Here we pass the frame down in the input stream. */
5517 CurrentRLP_RXCallback(valid ? &frame : NULL);
5520 static void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5523 fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
5530 void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5532 GSM_SMSMessage NullSMS;
5534 switch (MessageBuffer[6]) {
5536 case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
5537 case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
5539 /* Is it possible ? */
5540 case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
5541 default: NullSMS.Type = GST_UN; break;
5545 if (NullSMS.Type == GST_DR)
5546 fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
5548 fprintf(stdout, _("Message: SMS Message Received\n"));
5551 GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
5554 fprintf(stdout, _("\n"));
5558 #endif /* UCLINUX */
5560 void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5564 /* Switch on the basis of the message type byte */
5565 switch (MessageType) {
5567 /* Call information */
5570 N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
5576 switch (MessageBuffer[3]) {
5578 case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5579 case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
5580 case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5581 case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5582 case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5584 case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5585 default :unknown=true;break;
5588 #endif /* UCLINUX */
5590 /* Phonebook handling */
5592 switch (MessageBuffer[3]) {
5594 case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
5596 case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
5598 case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
5600 case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5602 case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5604 default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
5605 #endif /* UCLINUX */
5611 switch (MessageBuffer[3]) {
5612 case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
5613 default :unknown=true;break;
5618 /* Startup Logo, Operator Logo and Profiles. */
5620 switch (MessageBuffer[3]) {
5621 case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5622 case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5623 case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5624 case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5625 case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5626 case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5627 default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
5631 /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
5634 switch (MessageBuffer[3]) {
5636 case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
5637 default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
5641 /* Security code requests */
5643 switch (MessageBuffer[3]) {
5644 case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
5645 case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5646 default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5649 #endif /* UCLINUX */
5654 N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
5660 switch (MessageBuffer[3]) {
5661 case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
5662 default :unknown=true;break;
5666 /* Simulating key pressing */
5668 switch (MessageBuffer[3]) {
5669 case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
5670 default :unknown=true;break;
5676 switch (MessageBuffer[3]) {
5677 case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5678 case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
5679 case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5680 default :unknown=true;break;
5684 /* Phone Clock and Alarm */
5686 switch (MessageBuffer[3]) {
5687 case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
5688 case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
5689 case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
5690 case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
5691 default :unknown=true;break;
5695 /* Calendar notes handling */
5697 switch (MessageBuffer[3]) {
5698 case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5699 case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5700 case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
5701 default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
5707 switch (MessageBuffer[3]) {
5709 case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5711 case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5712 case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5714 case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
5715 default :unknown=true;break;
5721 switch (MessageBuffer[3]) {
5723 case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
5725 case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5727 case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5730 case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
5731 default :unknown=true;break;
5734 #endif /* UCLINUX */
5736 /* Internal phone functions? */
5738 switch (MessageBuffer[2]) {
5739 case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
5741 case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
5742 #endif /* UCLINUX */
5743 case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
5745 case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5746 case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5747 case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5748 case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
5749 case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
5750 case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5751 case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5752 case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
5753 case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5754 case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5755 #endif /* UCLINUX */
5756 case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
5757 default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
5762 /* Picture Images */
5765 N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
5767 #endif /* UCLINUX */
5769 /* Mobile phone identification */
5772 N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
5775 /***** Acknowlegment of our frames. *****/
5776 case FBUS_FRTYPE_ACK:
5778 N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
5781 /***** Power on message. *****/
5784 N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
5789 N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
5792 /***** RLP frame received. *****/
5795 N6110_RX_HandleRLPMessage(MessageBuffer);
5798 /***** Power on message. *****/
5801 N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
5804 /***** Unknown message *****/
5805 /* If you think that you know the exact meaning of other messages - please
5810 fprintf(stdout, _("Message: Unknown message type.\n"));
5812 AppendLogText("Unknown msg type\n",false);
5821 fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
5823 AppendLogText("Unknown msg\n",false);