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. */
44 /* Here we initialise model specific functions. */
45 GSM_Functions N6110_Functions = {
47 N6110_DispatchMessage,
50 N6110_GetMemoryLocation,
51 N6110_WritePhonebookLocation,
54 N6110_GetMemoryStatus,
60 N6110_DeleteSMSMessage,
73 N6110_GetBatteryLevel,
76 N6110_GetDisplayStatus,
77 N6110_EnterSecurityCode,
78 N6110_GetSecurityCodeStatus,
79 N6110_GetSecurityCode,
104 N6110_GetIncomingCallNr,
105 N6110_GetNetworkInfo,
106 N6110_GetCalendarNote,
107 N6110_WriteCalendarNote,
108 N6110_DeleteCalendarNote,
114 N6110_SetBinRingTone,
115 N6110_GetBinRingTone,
142 N6110_EnableDisplayOutput,
143 N6110_DisableDisplayOutput,
144 N6110_EnableCellBroadcast,
145 N6110_DisableCellBroadcast,
146 N6110_ReadCellBroadcast,
148 N6110_GetProductProfileSetting,
149 N6110_SetProductProfileSetting,
150 N6110_GetOperatorName,
151 N6110_SetOperatorName,
152 N6110_GetVoiceMailbox, N6110_Tests,
154 UNIMPLEMENTED, //GetCalendarNotesInfo
156 N6110_ResetPhoneSettings,
157 N7110_GetWAPBookmark,
158 N7110_SetWAPBookmark,
159 N7110_GetWAPSettings,
176 NULL, //GetCalendarNotesInfo
185 N6110_GetManufacturer
188 /* Mobile phone information */
190 GSM_Information N6110_Information = {
191 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
192 /* Supported models in FBUS */
193 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
194 /* Supported models in MBUS */
195 "6110|6130|6150|8210|8850",
196 /* Supported models in FBUS over infrared */
198 /* Supported models in FBUS over DLR3 */
202 /* infrared sockets */
203 "6110|6130|6150|8210|8850",
204 /* Supported models in FBUS over infrared with Tekram device */
205 4, /* Max RF Level */
206 0, /* Min RF Level */
207 GRF_Arbitrary, /* RF level units */
208 4, /* Max Battery Level */
209 0, /* Min Battery Level */
210 GBU_Arbitrary, /* Battery level units */
211 GDT_DateTime, /* Have date/time support */
212 GDT_TimeOnly, /* Alarm supports time only */
213 1 /* Only one alarm available */
217 static const char *N6110_MemoryType_String [] = {
231 /* Magic bytes from the phone. */
232 static unsigned char MagicBytes[4] = { 0x00, 0x00, 0x00, 0x00 };
234 /* For DisplayOutput */
236 static char PhoneScreen[5+1][27+1];
237 static int OldX=1000,OldY=0,NewX=0,NewY=0;
240 void N6110_ReplyEnableExtendedCommands(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
243 fprintf(stdout, _("Message: Answer for EnableExtendedSecurityCommands frame, meaning not known :-(\n"));
246 CurrentEnableExtendedCommandsError=GE_NONE;
249 /* If you set make some things (for example,
250 change Security Code from phone's menu, disable and enable
251 phone), it won't answer for 0x40 frame - you won't be able
252 to play tones, get netmonitor, etc.
254 This function do thing called "Enabling extended security commands" -
255 it enables 0x40 frame functions.
257 This frame can also some other things - see below */
258 GSM_Error N6110_EnableExtendedCommands (unsigned char status)
260 unsigned char req[4] = { 0x00,
261 0x01,0x64, /* Enable extended commands request */
262 0x01 }; /* 0x01 - on, 0x00 - off,
263 0x03 & 0x04 - soft & hard reset,
264 0x06 - CONTACT SERVICE */
266 /* 0x06 MAKES CONTACT SERVICE! BE CAREFULL! */
267 /* When use 0x03 and had during session changed time & date
268 some phones (like 6150 or 6210) can ask for time & date after reset
269 or disable clock on the screen */
270 if (status!=0x06) req[3] = status;
272 return NULL_SendMessageSequence
273 (50, &CurrentEnableExtendedCommandsError, 4, 0x40, req);
276 void N6110_ReplyIMEI(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
278 #if defined WIN32 || !defined HAVE_SNPRINTF
279 sprintf(Current_IMEI, "%s", MessageBuffer+4);
281 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+4);
285 fprintf(stdout, _("Message: IMEI %s received\n"),Current_IMEI);
288 CurrentGetIMEIError=GE_NONE;
291 GSM_Error N6110_SendIMEIFrame()
293 unsigned char req[4] = {0x00, 0x01, 0x66, 0x00};
297 error=N6110_EnableExtendedCommands(0x01);
298 if (error!=GE_NONE) return error;
300 return NULL_SendMessageSequence (20, &CurrentGetIMEIError, 4, 0x40, req);
303 void N6110_ReplyHW(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
307 if (MessageBuffer[3]==0x05) {
310 fprintf(stdout,_("Message: Hardware version received: "));
313 j=strlen(Current_Revision);
314 Current_Revision[j++]=',';
315 Current_Revision[j++]=' ';
316 Current_Revision[j++]='H';
317 Current_Revision[j++]='W';
321 fprintf(stdout,_("%c"), MessageBuffer[i]);
323 Current_Revision[j++]=MessageBuffer[i];
327 fprintf(stdout,_("\n"));
330 CurrentGetHWError=GE_NONE;
334 GSM_Error N6110_SendHWFrame()
336 unsigned char req[4] = {0x00, 0x01, 0xc8, 0x05};
340 error=N6110_EnableExtendedCommands(0x01);
341 if (error!=GE_NONE) return error;
343 return NULL_SendMessageSequence (20, &CurrentGetHWError, 4, 0x40, req);
346 void N6110_ReplyID(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
351 fprintf(stdout, _("Message: Mobile phone model identification received:\n"));
352 fprintf(stdout, _(" Firmware: "));
355 strcpy(Current_Revision,"SW");
358 while (MessageBuffer[i]!=0x0a) {
359 Current_Revision[j]=MessageBuffer[i];
361 fprintf(stdout, _("%c"),MessageBuffer[i]);
363 if (j==GSM_MAX_REVISION_LENGTH-1) {
365 fprintf(stderr,_("ERROR: increase GSM_MAX_REVISION_LENGTH!\n"));
372 Current_Revision[j+1]=0;
375 fprintf(stdout, _("\n Firmware date: "));
379 while (MessageBuffer[i]!=0x0a) {
381 fprintf(stdout, _("%c"),MessageBuffer[i]);
387 fprintf(stdout, _("\n Model: "));
391 while (MessageBuffer[i]!=0x0a) {
392 Current_Model[j]=MessageBuffer[i];
394 fprintf(stdout, _("%c"),MessageBuffer[i]);
396 if (j==GSM_MAX_MODEL_LENGTH-1) {
398 fprintf(stderr,_("ERROR: increase GSM_MAX_MODEL_LENGTH!\n"));
405 Current_Model[j+1]=0;
408 fprintf(stdout, _("\n"));
411 CurrentMagicError=GE_NONE;
414 GSM_Error N6110_SendIDFrame()
416 unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
418 return NULL_SendMessageSequence (50, &CurrentMagicError, 5, 0xd1, req);
421 /* This function send the status request to the phone. */
422 /* Seems to be ignored in N3210 */
423 GSM_Error N6110_SendStatusRequest(void)
425 unsigned char req[] = {N6110_FRAME_HEADER, 0x01};
427 Protocol->SendMessage(4, 0x04, req);
432 static void N6110_ReplyGetAuthentication(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
436 #if defined WIN32 || !defined HAVE_SNPRINTF
437 sprintf(Current_IMEI, "%s", MessageBuffer+9);
438 sprintf(Current_Model, "%s", MessageBuffer+25);
439 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
441 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+9);
442 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+25);
443 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
447 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
448 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
449 fprintf(stdout, _(" Model: %s\n"), Current_Model);
450 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+31);
451 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+39);
452 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+44);
454 /* These bytes are probably the source of the "Accessory not connected"
455 messages on the phone when trying to emulate NCDS... I hope....
456 UPDATE: of course, now we have the authentication algorithm. */
457 fprintf(stdout, _(" Magic bytes: %02x %02x %02x %02x\n"), MessageBuffer[50], MessageBuffer[51], MessageBuffer[52], MessageBuffer[53]);
460 MagicBytes[0]=MessageBuffer[50];
461 MagicBytes[1]=MessageBuffer[51];
462 MagicBytes[2]=MessageBuffer[52];
463 MagicBytes[3]=MessageBuffer[53];
465 CurrentMagicError=GE_NONE;
468 /* This function provides Nokia authentication protocol.
470 This code is written specially for gnokii project by Odinokov Serge.
471 If you have some special requests for Serge just write him to
472 apskaita@post.omnitel.net or serge@takas.lt
474 Reimplemented in C by Pavel JanÃk ml.
476 Nokia authentication protocol is used in the communication between Nokia
477 mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software,
478 commercially sold by Nokia Corp.
480 The authentication scheme is based on the token send by the phone to the
481 software. The software does it's magic (see the function
482 FB61_GetNokiaAuth()) and returns the result back to the phone. If the
483 result is correct the phone responds with the message "Accessory
484 connected!" displayed on the LCD. Otherwise it will display "Accessory not
485 supported" and some functions will not be available for use.
487 The specification of the protocol is not publicly available, no comment. */
488 static void N6110_GetNokiaAuth(unsigned char *Imei, unsigned char *MagicBytes, unsigned char *MagicResponse)
493 /* This is our temporary working area. */
495 unsigned char Temp[16];
497 /* Here we put FAC (Final Assembly Code) and serial number into our area. */
508 /* And now the TAC (Type Approval Code). */
515 /* And now we pack magic bytes from the phone. */
517 Temp[12] = MagicBytes[0];
518 Temp[13] = MagicBytes[1];
519 Temp[14] = MagicBytes[2];
520 Temp[15] = MagicBytes[3];
522 for (i=0; i<=11; i++)
526 switch (Temp[15] & 0x03) {
533 Temp[i+j] ^= Temp[i+12];
541 Temp[i + j] |= Temp[i + 12];
544 for (i=0; i<=15; i++)
547 for (i=0; i<=15; i++) {
549 switch (Temp[15 - i] & 0x06) {
571 MagicResponse[i] = j;
576 static GSM_Error N6110_Authentication()
578 unsigned char connect1[] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x02};
579 unsigned char connect2[] = {N6110_FRAME_HEADER, 0x20, 0x02};
580 unsigned char connect3[] = {N6110_FRAME_HEADER, 0x0d, 0x01, 0x00, 0x02};
581 unsigned char connect4[] = {N6110_FRAME_HEADER, 0x10};
583 unsigned char magic_connect[] = {N6110_FRAME_HEADER,
586 /* The real magic goes here ... These bytes are filled in with the
587 function N6110_GetNokiaAuth(). */
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 /* NOKIA&GNOKII Accessory */
594 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x26, 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x20,
595 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x79,
597 0x00, 0x00, 0x00, 0x00};
599 unsigned char req3_55[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
600 0x07,0xa2,0x88,0x81,0x21,0x55,0x63,0xa8,0x00,0x00,
601 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
602 unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
603 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
604 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
605 unsigned char unknown_05[] = {N6110_FRAME_HEADER, 0x05};
608 fprintf(stdout,_("Making authentication!\n"));
611 usleep(100); Protocol->SendMessage(7, 0x02, connect1);
612 usleep(100); Protocol->SendMessage(5, 0x02, connect2);
613 usleep(100); Protocol->SendMessage(7, 0x02, connect3);
615 usleep(100); Protocol->SendMessage(sizeof(req3_55), 0x01, req3_55); /* Lace */
617 CurrentMagicError = GE_BUSY;
619 usleep(100); Protocol->SendMessage(4, 0x64, connect4);
621 usleep(100); Protocol->SendMessage(sizeof(req3_55), 0x01, req3_55); /* Lace */
622 usleep(100); Protocol->SendMessage(sizeof(req3), 0x01, req3); /* Lace */
624 if (NULL_WaitUntil(50,&CurrentMagicError)!=GE_NONE) return GE_TIMEOUT;
626 N6110_GetNokiaAuth(Current_IMEI, MagicBytes, magic_connect+4);
628 Protocol->SendMessage(45, 0x64, magic_connect);
630 usleep(100); Protocol->SendMessage(4, 0x04, unknown_05); /* Lace */
633 fprintf(stdout,_("End of authentication!\n"));
639 /* Initialise variables and state machine. */
640 GSM_Error N6110_Initialise(char *port_device, char *initlength,
641 GSM_ConnectionType connection,
642 void (*rlp_callback)(RLP_F96Frame *frame))
644 unsigned char init_char = N6110_SYNC_BYTE;
646 unsigned char end_init_char = N6110_IR_END_SYNC_BYTE;
652 if (Protocol->Initialise(port_device,initlength,connection,rlp_callback)!=GE_NONE)
654 return GE_NOTSUPPORTED;
657 switch (CurrentConnectionType) {
661 /* We don't think about authentication in Irda, because
662 AFAIK there are no phones working over sockets
663 and having authentication. In MBUS it doesn't work */
666 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
668 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
670 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
672 CurrentLinkOK = true;
681 InitLength = atoi(initlength);
683 if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
684 InitLength = 250; /* This is the usual value, lower may work. */
688 if (CurrentConnectionType==GCT_Infrared ||
689 CurrentConnectionType==GCT_Tekram) {
691 fprintf(stdout,_("Setting infrared for FBUS communication...\n"));
693 device_changespeed(9600);
698 fprintf(stdout,_("Writing init chars...."));
701 /* Initialise link with phone or what have you */
702 /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
704 for (count = 0; count < InitLength; count ++) {
706 if (CurrentConnectionType!=GCT_Infrared &&
707 CurrentConnectionType!=GCT_Tekram)
710 Protocol->WritePhone(1,&init_char);
714 if (CurrentConnectionType==GCT_Infrared ||
715 CurrentConnectionType==GCT_Tekram) {
716 Protocol->WritePhone(1,&end_init_char);
722 fprintf(stdout,_("Done\n"));
726 if (CurrentConnectionType==GCT_Infrared ||
727 CurrentConnectionType==GCT_Tekram) {
728 device_changespeed(115200);
732 N6110_SendStatusRequest();
736 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
738 /* N51xx/61xx have something called authentication.
739 After making it phone display "Accessory connected"
740 and probably give access to some function (I'm not too sure about it !)
741 Anyway, I make it now for N51xx/61xx */
743 if (GetModelFeature (FN_AUTHENTICATION)!=0)
745 if (0/*Lace-hack:GetModelFeature (FN_AUTHENTICATION)!=0*/)
748 if (N6110_Authentication()!=GE_NONE) return GE_TIMEOUT;
749 } else { /* No authentication */
750 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
752 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
758 fprintf(stdout,_("Unknown connection type in n6110.c!\n"));
766 /* This function translates GMT_MemoryType to N6110_MEMORY_xx */
767 int N6110_GetMemoryType(GSM_MemoryType memory_type)
772 switch (memory_type) {
774 case GMT_MT: result = N6110_MEMORY_MT; break;
775 case GMT_ME: result = N6110_MEMORY_ME; break;
776 case GMT_SM: result = N6110_MEMORY_SM; break;
777 case GMT_FD: result = N6110_MEMORY_FD; break;
778 case GMT_ON: result = N6110_MEMORY_ON; break;
779 case GMT_EN: result = N6110_MEMORY_EN; break;
780 case GMT_DC: result = N6110_MEMORY_DC; break;
781 case GMT_RC: result = N6110_MEMORY_RC; break;
782 case GMT_MC: result = N6110_MEMORY_MC; break;
783 default : result = N6110_MEMORY_XX;
792 void N6110_ReplyCallDivert(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
794 switch (MessageBuffer[3]) {
799 fprintf(stdout, _("Message: Call divert status received\n"));
800 fprintf(stdout, _(" Divert type: "));
801 switch (MessageBuffer[6]) {
802 case 0x43: fprintf(stdout, _("when busy"));break;
803 case 0x3d: fprintf(stdout, _("when not answered"));break;
804 case 0x3e: fprintf(stdout, _("when phone off or no coverage"));break;
805 case 0x15: fprintf(stdout, _("all types of diverts"));break; //?
806 case 0x02: fprintf(stdout, _("all types of diverts"));break; //?
807 default: fprintf(stdout, _("unknown %i"),MessageBuffer[6]);break;
809 fprintf(stdout, _("\n Calls type : "));
810 if (MessageBuffer[6]==0x02)
811 fprintf(stdout, _("voice, fax & data")); //?
813 switch (MessageBuffer[8]) {
814 case 0x0b: fprintf(stdout, _("voice"));break;
815 case 0x0d: fprintf(stdout, _("fax"));break;
816 case 0x19: fprintf(stdout, _("data"));break;
817 default: fprintf(stdout, _("unknown %i"),MessageBuffer[8]);break;
820 fprintf(stdout, _("\n"));
821 if (MessageBuffer[10]==0x01) {
822 fprintf(stdout, _(" Status : active\n"));
823 fprintf(stdout, _(" Timeout : %i seconds\n"),MessageBuffer[45]);
824 fprintf(stdout, _(" Number : %s\n"),GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
826 fprintf(stdout, _(" Status : deactivated\n"));
830 switch (MessageBuffer[6]) {
831 case 0x43: CurrentCallDivert->DType=GSM_CDV_Busy;break;
832 case 0x3d: CurrentCallDivert->DType=GSM_CDV_NoAnswer;break;
833 case 0x3e: CurrentCallDivert->DType=GSM_CDV_OutOfReach;break;
834 case 0x15: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
835 case 0x02: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
838 if (MessageBuffer[6]==0x02) //?
839 CurrentCallDivert->CType=GSM_CDV_AllCalls;
841 switch (MessageBuffer[8]) {
842 case 0x0b: CurrentCallDivert->CType=GSM_CDV_VoiceCalls;break;
843 case 0x0d: CurrentCallDivert->CType=GSM_CDV_FaxCalls; break;
844 case 0x19: CurrentCallDivert->CType=GSM_CDV_DataCalls; break;
848 if (MessageBuffer[10]==0x01) {
849 CurrentCallDivert->Enabled=true;
850 CurrentCallDivert->Timeout=MessageBuffer[45];
851 strcpy(CurrentCallDivert->Number,GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
853 CurrentCallDivert->Enabled=false;
856 CurrentCallDivertError=GE_NONE;
861 fprintf(stdout, _("Message: Call divert status receiving error ?\n"));
863 CurrentCallDivertError=GE_UNKNOWN;
868 GSM_Error N6110_CallDivert(GSM_CallDivert *cd)
870 char req[55] = { N6110_FRAME_HEADER, 0x01,
871 0x00, /* operation */
873 0x00, /* divert type */
874 0x00, /* call type */
880 switch (cd->Operation) {
881 case GSM_CDV_Register:
885 req[29]= GSM_PackSemiOctetNumber(cd->Number, req + 9, false);
886 req[52]= cd->Timeout;
889 case GSM_CDV_Erasure:
890 case GSM_CDV_Disable:
897 return GE_NOTIMPLEMENTED;
901 case GSM_CDV_AllTypes : req[6] = 0x15; break;
902 case GSM_CDV_Busy : req[6] = 0x43; break;
903 case GSM_CDV_NoAnswer : req[6] = 0x3d; break;
904 case GSM_CDV_OutOfReach: req[6] = 0x3e; break;
905 default: return GE_NOTIMPLEMENTED;
908 if ((cd->DType == GSM_CDV_AllTypes) &&
909 (cd->CType == GSM_CDV_AllCalls))
913 case GSM_CDV_AllCalls : break;
914 case GSM_CDV_VoiceCalls: req[7] = 0x0b; break;
915 case GSM_CDV_FaxCalls : req[7] = 0x0d; break;
916 case GSM_CDV_DataCalls : req[7] = 0x19; break;
917 default: return GE_NOTIMPLEMENTED;
920 CurrentCallDivert = cd;
922 error=NULL_SendMessageSequence
923 (100, &CurrentCallDivertError, length, 0x06, req);
925 CurrentCallDivert = NULL;
930 GSM_Error N6110_Tests()
932 unsigned char buffer[3]={0x00,0x01,0xcf};
933 unsigned char buffer3[8]={0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00};
937 error=N6110_EnableExtendedCommands(0x01);
938 if (error!=GE_NONE) return error;
940 //make almost all tests
941 Protocol->SendMessage(8, 0x40, buffer3);
943 while (GSM->Initialise(PortDevice, "50", CurrentConnectionType, CurrentRLP_RXCallback)!=GE_NONE) {};
947 return NULL_SendMessageSequence
948 (200, &CurrentNetworkInfoError, 3, 0x40, buffer);
951 void N6110_DisplayTestsInfo(u8 *MessageBuffer) {
955 CurrentNetworkInfoError=GE_NONE;
957 for (i=0;i<MessageBuffer[3];i++) {
959 case 0: fprintf(stdout,_("Unknown(%i) "),i);break;
960 case 1: fprintf(stdout,_("MCU ROM checksum "));break;
961 case 2: fprintf(stdout,_("MCU RAM interface "));break;
962 case 3: fprintf(stdout,_("MCU RAM component "));break;
963 case 4: fprintf(stdout,_("MCU EEPROM interface "));break;
964 case 5: fprintf(stdout,_("MCU EEPROM component "));break;
965 case 6: fprintf(stdout,_("Real Time Clock battery "));break;
966 case 7: fprintf(stdout,_("CCONT interface "));break;
967 case 8: fprintf(stdout,_("AD converter "));break;
968 case 9: fprintf(stdout,_("SW Reset "));break;
969 case 10:fprintf(stdout,_("Power Off "));break;
970 case 11:fprintf(stdout,_("Security Data "));break;
971 case 12:fprintf(stdout,_("EEPROM Tune checksum "));break;
972 case 13:fprintf(stdout,_("PPM checksum "));break;
973 case 14:fprintf(stdout,_("MCU download DSP "));break;
974 case 15:fprintf(stdout,_("DSP alive "));break;
975 case 16:fprintf(stdout,_("COBBA serial "));break;
976 case 17:fprintf(stdout,_("COBBA paraller "));break;
977 case 18:fprintf(stdout,_("EEPROM security checksum"));break;
978 case 19:fprintf(stdout,_("PPM validity "));break;
979 case 20:fprintf(stdout,_("Warranty state "));break;
980 case 21:fprintf(stdout,_("Simlock check "));break;
981 case 22:fprintf(stdout,_("IMEI check? "));break;//from PC-Locals.is OK?
982 default:fprintf(stdout,_("Unknown(%i) "),i);break;
984 switch (MessageBuffer[4+i]) {
985 case 0: fprintf(stdout,_(" : done, result OK"));break;
986 case 0xff:fprintf(stdout,_(" : not done, result unknown"));break;
987 case 254: fprintf(stdout,_(" : done, result NOT OK"));break;
988 default: fprintf(stdout,_(" : result unknown(%i)"),MessageBuffer[4+i]);break;
990 fprintf(stdout,_("\n"));
994 void N6110_ReplySimlockInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1001 fprintf(stdout, _("Message: Simlock info received\n"));
1004 for (i=0; i < 12; i++)
1007 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] >> 4)));
1010 if (j==5 || j==15) fprintf(stdout, _("\n"));
1013 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] & 0x0f)));
1017 if (j==20 || j==24) fprintf(stdout, _("\n"));
1020 if ((MessageBuffer[6] & 1) == 1) fprintf(stdout,_("lock 1 closed\n"));
1021 if ((MessageBuffer[6] & 2) == 2) fprintf(stdout,_("lock 2 closed\n"));
1022 if ((MessageBuffer[6] & 4) == 4) fprintf(stdout,_("lock 3 closed\n"));
1023 if ((MessageBuffer[6] & 8) == 8) fprintf(stdout,_("lock 4 closed\n"));
1025 /* I'm not sure here at all */
1026 if ((MessageBuffer[5] & 1) == 1) fprintf(stdout,_("lock 1 - user\n"));
1027 if ((MessageBuffer[5] & 2) == 2) fprintf(stdout,_("lock 2 - user\n"));
1028 if ((MessageBuffer[5] & 4) == 4) fprintf(stdout,_("lock 3 - user\n"));
1029 if ((MessageBuffer[5] & 8) == 8) fprintf(stdout,_("lock 4 - user\n"));
1031 fprintf(stdout,_("counter for lock1: %i\n"),MessageBuffer[21]);
1032 fprintf(stdout,_("counter for lock2: %i\n"),MessageBuffer[22]);
1033 fprintf(stdout,_("counter for lock3: %i\n"),MessageBuffer[23]);
1034 fprintf(stdout,_("counter for lock4: %i\n"),MessageBuffer[24]);
1039 for (i=0; i < 12; i++)
1042 uni[j]='0' + (MessageBuffer[9+i] >> 4);
1047 uni[j]='0' + (MessageBuffer[9+i] & 0x0f);
1053 strncpy(CurrentSimLock->simlocks[0].data,uni,5);
1054 CurrentSimLock->simlocks[0].data[5]=0;
1055 strncpy(CurrentSimLock->simlocks[3].data,uni+5,10);
1056 CurrentSimLock->simlocks[3].data[10]=0;
1057 strncpy(CurrentSimLock->simlocks[1].data,uni+16,4);
1058 CurrentSimLock->simlocks[1].data[4]=0;
1059 strncpy(CurrentSimLock->simlocks[2].data,uni+20,4);
1060 CurrentSimLock->simlocks[2].data[4]=0;
1062 CurrentSimLock->simlocks[0].enabled=((MessageBuffer[6] & 1) == 1);
1063 CurrentSimLock->simlocks[1].enabled=((MessageBuffer[6] & 2) == 2);
1064 CurrentSimLock->simlocks[2].enabled=((MessageBuffer[6] & 4) == 4);
1065 CurrentSimLock->simlocks[3].enabled=((MessageBuffer[6] & 8) == 8);
1067 CurrentSimLock->simlocks[0].factory=((MessageBuffer[5] & 1) != 1);
1068 CurrentSimLock->simlocks[1].factory=((MessageBuffer[5] & 2) != 2);
1069 CurrentSimLock->simlocks[2].factory=((MessageBuffer[5] & 4) != 4);
1070 CurrentSimLock->simlocks[3].factory=((MessageBuffer[5] & 8) != 8);
1072 CurrentSimLock->simlocks[0].counter=MessageBuffer[21];
1073 CurrentSimLock->simlocks[1].counter=MessageBuffer[22];
1074 CurrentSimLock->simlocks[2].counter=MessageBuffer[23];
1075 CurrentSimLock->simlocks[3].counter=MessageBuffer[24];
1077 CurrentSimlockInfoError=GE_NONE;
1080 GSM_Error N6110_SimlockInfo(GSM_AllSimlocks *siml)
1083 unsigned char req[] = {0x00,0x01,0x8a,0x00};
1084 error=N6110_EnableExtendedCommands(0x01);
1085 if (error!=GE_NONE) return error;
1087 CurrentSimLock=siml;
1089 return NULL_SendMessageSequence (50, &CurrentSimlockInfoError, 4, 0x40, req);
1092 void N6110_ReplyResetPhoneSettings(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1095 fprintf(stdout, _("Message: Resetting phone settings\n"));
1098 CurrentResetPhoneSettingsError=GE_NONE;
1101 GSM_Error N6110_ResetPhoneSettings()
1104 unsigned char req[] = {0x00,0x01,0x65,0x08,0x00};
1105 error=N6110_EnableExtendedCommands(0x01);
1106 if (error!=GE_NONE) return error;
1108 return NULL_SendMessageSequence
1109 (50, &CurrentResetPhoneSettingsError, 5, 0x40, req);
1112 #endif /* UCLINUX */
1114 GSM_Error N6110_GetManufacturer(char *manufacturer)
1116 strcpy (manufacturer, "Nokia");
1122 GSM_Error N6110_GetVoiceMailbox ( GSM_PhonebookEntry *entry)
1124 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
1128 CurrentPhonebookEntry = entry;
1130 req[4] = N6110_MEMORY_VOICE;
1131 req[5] = 0x00; /* Location - isn't important, but... */
1133 error=NULL_SendMessageSequence
1134 (20, &CurrentPhonebookError, 7, 0x03, req);
1136 CurrentPhonebookEntry = NULL;
1141 void N6110_ReplyGetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1145 GSM_Bitmap NullBitmap;
1147 DecodeNetworkCode(MessageBuffer+5, NullBitmap.netcode);
1152 fprintf(stdout, _("Message: Info about downloaded operator name received: %s network (for gnokii \"%s\", for phone \""),
1154 GSM_GetNetworkName(NullBitmap.netcode));
1158 while (MessageBuffer[count]!=0) {
1160 fprintf(stdout,_("%c"),MessageBuffer[count]);
1165 strcpy(CurrentGetOperatorNameNetwork->Code, NullBitmap.netcode);
1166 strncpy(CurrentGetOperatorNameNetwork->Name, MessageBuffer+i,count-i+1);
1169 fprintf(stdout,_("\")\n"));
1172 CurrentGetOperatorNameError=GE_NONE;
1175 GSM_Error N6110_GetOperatorName (GSM_Network *operator)
1177 unsigned char req[] = { 0x00,0x01,0x8c,0x00};
1181 error=N6110_EnableExtendedCommands(0x01);
1182 if (error!=GE_NONE) return error;
1184 CurrentGetOperatorNameNetwork = operator;
1186 error=NULL_SendMessageSequence
1187 (20, &CurrentGetOperatorNameError, 4, 0x40, req);
1189 CurrentGetOperatorNameNetwork = NULL;
1194 void N6110_ReplySetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1197 fprintf(stdout, _("Message: Downloaded operator name changed\n"));
1200 CurrentSetOperatorNameError=GE_NONE;
1203 GSM_Error N6110_SetOperatorName (GSM_Network *operator)
1205 unsigned char req[256] = { 0x00,0x01,0x8b,0x00,
1206 0x00,0x00, /* MCC */
1211 error=N6110_EnableExtendedCommands(0x01);
1212 if (error!=GE_NONE) return error;
1214 EncodeNetworkCode(req+4,operator->Code);
1216 strncpy(req+7,operator->Name,200);
1218 return NULL_SendMessageSequence
1219 (20, &CurrentSetOperatorNameError, 8+strlen(operator->Name), 0x40, req);
1222 #endif /* UCLINUX */
1224 static void N6110_ReplyGetMemoryStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1226 switch (MessageBuffer[3]) {
1231 fprintf(stdout, _("Message: Memory status received:\n"));
1233 fprintf(stdout, _(" Memory Type: %s\n"), N6110_MemoryType_String[MessageBuffer[4]]);
1234 fprintf(stdout, _(" Used: %d\n"), MessageBuffer[6]);
1235 fprintf(stdout, _(" Free: %d\n"), MessageBuffer[5]);
1238 CurrentMemoryStatus->Used = MessageBuffer[6];
1239 CurrentMemoryStatus->Free = MessageBuffer[5];
1240 CurrentMemoryStatusError = GE_NONE;
1247 switch (MessageBuffer[4]) {
1249 fprintf(stdout, _("Message: Memory status error, phone is probably powered off.\n"));break;
1251 fprintf(stdout, _("Message: Memory status error, memory type not supported by phone model.\n"));break;
1253 fprintf(stdout, _("Message: Memory status error, waiting for security code.\n"));break;
1255 fprintf(stdout, _("Message: Unknown Memory status error, subtype (MessageBuffer[4]) = %02x\n"),MessageBuffer[4]);break;
1259 switch (MessageBuffer[4]) {
1260 case 0x6f:CurrentMemoryStatusError = GE_TIMEOUT;break;
1261 case 0x7d:CurrentMemoryStatusError = GE_INTERNALERROR;break;
1262 case 0x8d:CurrentMemoryStatusError = GE_INVALIDSECURITYCODE;break;
1271 /* This function is used to get storage status from the phone. It currently
1272 supports two different memory areas - internal and SIM. */
1273 GSM_Error N6110_GetMemoryStatus(GSM_MemoryStatus *Status)
1275 unsigned char req[] = { N6110_FRAME_HEADER,
1276 0x07, /* MemoryStatus request */
1277 0x00 /* MemoryType */
1282 CurrentMemoryStatus = Status;
1284 req[4] = N6110_GetMemoryType(Status->MemoryType);
1286 error=NULL_SendMessageSequence
1287 (20, &CurrentMemoryStatusError, 5, 0x03, req);
1289 CurrentMemoryStatus = NULL;
1296 void N6110_ReplyGetNetworkInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1298 GSM_NetworkInfo NullNetworkInfo;
1300 /* Make sure we are expecting NetworkInfo frame */
1301 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY) {
1303 fprintf(stdout, _("Message: Network informations:\n"));
1307 fprintf(stdout, _("Message: Network informations not requested, but received:\n"));
1311 sprintf(NullNetworkInfo.NetworkCode, "%x%x%x %x%x", MessageBuffer[14] & 0x0f, MessageBuffer[14] >>4, MessageBuffer[15] & 0x0f, MessageBuffer[16] & 0x0f, MessageBuffer[16] >>4);
1313 sprintf(NullNetworkInfo.CellID, "%02x%02x", MessageBuffer[10], MessageBuffer[11]);
1315 sprintf(NullNetworkInfo.LAC, "%02x%02x", MessageBuffer[12], MessageBuffer[13]);
1318 fprintf(stdout, _(" CellID: %s\n"), NullNetworkInfo.CellID);
1319 fprintf(stdout, _(" LAC: %s\n"), NullNetworkInfo.LAC);
1320 fprintf(stdout, _(" Network code: %s\n"), NullNetworkInfo.NetworkCode);
1321 fprintf(stdout, _(" Network name: %s (%s)\n"),
1322 GSM_GetNetworkName(NullNetworkInfo.NetworkCode),
1323 GSM_GetCountryName(NullNetworkInfo.NetworkCode));
1324 fprintf(stdout, _(" Status: "));
1326 switch (MessageBuffer[8]) {
1327 case 0x01: fprintf(stdout, _("home network selected")); break;
1328 case 0x02: fprintf(stdout, _("roaming network")); break;
1329 case 0x03: fprintf(stdout, _("requesting network")); break;
1330 case 0x04: fprintf(stdout, _("not registered in the network")); break;
1331 default: fprintf(stdout, _("unknown"));
1334 fprintf(stdout, "\n");
1336 fprintf(stdout, _(" Network selection: %s\n"), MessageBuffer[9]==1?_("manual"):_("automatic"));
1339 /* Make sure we are expecting NetworkInfo frame */
1340 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY)
1341 *CurrentNetworkInfo=NullNetworkInfo;
1343 CurrentNetworkInfoError = GE_NONE;
1346 GSM_Error N6110_GetNetworkInfo(GSM_NetworkInfo *NetworkInfo)
1348 unsigned char req[] = { N6110_FRAME_HEADER,
1354 CurrentNetworkInfo = NetworkInfo;
1356 error=NULL_SendMessageSequence
1357 (20, &CurrentNetworkInfoError, 4, 0x0a, req);
1359 CurrentNetworkInfo = NULL;
1364 void N6110_ReplyGetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1369 fprintf(stdout, _("Message: Product Profile Settings received -"));
1370 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),MessageBuffer[3+i]);
1371 fprintf(stdout, _("\n"));
1374 for (i=0;i<4;i++) CurrentPPS[i]=MessageBuffer[3+i];
1376 CurrentProductProfileSettingsError=GE_NONE;
1379 GSM_Error N6110_GetProductProfileSetting (GSM_PPS *PPS)
1381 unsigned char req[] = { 0x00, 0x01,0x6a };
1387 error=N6110_EnableExtendedCommands(0x01);
1388 if (error!=GE_NONE) return error;
1390 error=NULL_SendMessageSequence
1391 (20, &CurrentProductProfileSettingsError, 3, 0x40, req);
1392 if (error!=GE_NONE) return error;
1394 switch (PPS->Name) {
1395 case PPS_ALS : PPS->bool_value=(CurrentPPS[1]&32); break;
1396 case PPS_GamesMenu: PPS->bool_value=(CurrentPPS[3]&64); break;
1397 case PPS_HRData : PPS->bool_value=(CurrentPPS[0]&64); break;
1398 case PPS_14400Data: PPS->bool_value=(CurrentPPS[0]&128);break;
1399 case PPS_EFR : PPS->int_value =(CurrentPPS[0]&1) +(CurrentPPS[0]&2); break;
1400 case PPS_FR : PPS->int_value =(CurrentPPS[0]&16)/16+(CurrentPPS[0]&32)/16;break;
1401 case PPS_HR : PPS->int_value =(CurrentPPS[0]&4)/4 +(CurrentPPS[0]&8)/4; break;
1402 case PPS_VibraMenu: PPS->bool_value=(CurrentPPS[4]&64); break;
1403 case PPS_LCDContrast:
1407 if (CurrentPPS[3]&j) PPS->int_value=PPS->int_value+j;
1410 PPS->int_value=PPS->int_value*100/32;
1418 void N6110_ReplySetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1423 fprintf(stdout, _("Message: Product Profile Settings set to"));
1424 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),CurrentPPS[i]);
1425 fprintf(stdout, _("\n"));
1428 CurrentProductProfileSettingsError=GE_NONE;
1431 GSM_Error N6110_SetProductProfileSetting (GSM_PPS *PPS)
1433 unsigned char req[] = { 0x00, 0x01,0x6b,
1434 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */
1435 unsigned char settings[32];
1443 error=N6110_EnableExtendedCommands(0x01);
1444 if (error!=GE_NONE) return error;
1446 OldPPS.Name=PPS_ALS;
1447 error=N6110_GetProductProfileSetting(&OldPPS);
1448 if (error!=GE_NONE) return error;
1451 for (i=0;i<32;i++) {
1452 if (CurrentPPS[z]&j)
1463 fprintf(stdout,_("Current settings: "));
1464 for (i=0;i<32;i++) {
1465 fprintf(stdout,_("%c"),settings[i]);
1467 fprintf(stdout,_("\n"));
1470 switch (PPS->Name) {
1471 case PPS_ALS :settings[10]=PPS->bool_value?'1':'0';break;
1472 case PPS_HRData :settings[ 5]=PPS->bool_value?'1':'0';break;
1473 case PPS_14400Data:settings[ 6]=PPS->bool_value?'1':'0';break;
1478 for (i=0;i<32;i++) {
1479 if (settings[i]=='1') req[z+3]=req[z+3]+j;
1487 fprintf(stdout,_("Current settings: "));
1489 fprintf(stdout,_("%i "),req[i+3]);
1491 fprintf(stdout,_("\n"));
1495 CurrentPPS[i]=req[i+3];
1498 return NULL_SendMessageSequence
1499 (20, &CurrentProductProfileSettingsError, 7, 0x40, req);
1502 void N6110_ReplyPressKey(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1504 if (MessageBuffer[4]==CurrentPressKeyEvent) CurrentPressKeyError=GE_NONE;
1505 else CurrentPressKeyError=GE_UNKNOWN; /* MessageBuffer[4] = 0x05 */
1507 fprintf(stdout, _("Message: Result of key "));
1508 switch (MessageBuffer[4])
1510 case PRESSPHONEKEY: fprintf(stdout, _("press OK\n"));break;
1511 case RELEASEPHONEKEY: fprintf(stdout, _("release OK\n"));break;
1512 default: fprintf(stdout, _("press or release - error\n"));break;
1517 GSM_Error N6110_PressKey(int key, int event)
1519 unsigned char req[] = {N6110_FRAME_HEADER, 0x42, 0x01, 0x00, 0x01};
1521 req[4]=event; /* if we press or release key */
1524 CurrentPressKeyEvent=event;
1526 return NULL_SendMessageSequence
1527 (10, &CurrentPressKeyError, 7, 0x0c, req);
1530 void N6110_ReplyDisplayOutput(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1532 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
1539 switch(MessageBuffer[3]) {
1541 /* Phone sends displayed texts */
1543 NewX=MessageBuffer[6];
1544 NewY=MessageBuffer[5];
1546 DecodeUnicode (uni, MessageBuffer+8, MessageBuffer[7]);
1549 fprintf(stdout, _("New displayed text (%i %i): \"%s\"\n"),NewX,NewY,uni);
1552 while (N6110_GetModel(model) != GE_NONE)
1555 /* With these rules it works almost excellent with my N5110 */
1556 /* I don't have general rule :-(, that's why you must experiment */
1557 /* with your phone. Nokia could make it better. MW */
1558 /* It's almost OK for N5110*/
1559 /* FIX ME: it will be the same for N5130 and 3210 too*/
1560 if (!strcmp(model,"NSE-1"))
1562 /* OldX==1000 means - it's first time */
1566 for (i=0;i<5+1;i++) {
1567 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1572 if ((OldX==0 && OldY==31 && NewX==29 && NewY==46) ||
1573 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1574 /* Clean the line with current text */
1575 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1577 /* Inserts text into table */
1578 for (i=0; i<MessageBuffer[7];i++) {
1579 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1584 if ((OldX==0 && OldY==21 && NewX==0 && NewY==10) ||
1585 (OldX==0 && OldY==10 && NewX==35 && NewY==46)) {
1587 if ((OldX!=0 && NewX==0 && NewY!=6) ||
1588 (OldX==0 && NewX!=0 && OldY!=13 && OldY!=22) ||
1589 (OldX==0 && NewX==0 && NewY<OldY && (NewY!=13 || OldY!=26)) ||
1590 (OldY==5 && NewY!=5) ||
1591 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1593 /* Writes "old" screen */
1594 for (i=0;i<5+1;i++) {
1595 for (j=0;j<27+1;j++) {fprintf(stdout,_("%c"),PhoneScreen[i][j]);}
1596 fprintf(stdout,_("\n"));
1600 for (i=0;i<5+1;i++) {
1601 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1606 /* Clean the line with current text */
1607 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1609 /* Inserts text into table */
1610 for (i=0; i<MessageBuffer[7];i++) {
1611 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1618 fprintf(stdout, _("%s\n"),uni);
1626 if (MessageBuffer[4]==1)
1630 fprintf(stdout, _("Display output successfully disabled/enabled.\n"));
1633 CurrentDisplayOutputError=GE_NONE;
1640 GSM_Error SetDisplayOutput(unsigned char state)
1642 unsigned char req[] = { N6110_FRAME_HEADER,
1647 return NULL_SendMessageSequence
1648 (30, &CurrentDisplayOutputError, 5, 0x0d, req);
1651 GSM_Error N6110_EnableDisplayOutput()
1653 return SetDisplayOutput(0x01);
1656 GSM_Error N6110_DisableDisplayOutput()
1658 return SetDisplayOutput(0x02);
1661 /* If it is interesting for somebody: we can use 0x40 msg for it
1662 and it will work for all phones. See n6110.txt for details */
1663 GSM_Error N6110_AnswerCall(char s)
1665 unsigned char req0[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,0x07, 0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
1666 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80};
1667 unsigned char req[] = { N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
1672 fprintf(stdout,_("Answering call %d\n\r"),s);
1675 Protocol->SendMessage(sizeof(req0), 0x01, req0);
1678 return NULL_SendMessageSequence
1679 (20, &CurrentMagicError, sizeof(req) , 0x01, req);
1682 void N6110_ReplyGetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1684 switch (MessageBuffer[3]) {
1686 /* Profile feature */
1689 switch(GetModelFeature (FN_PROFILES)) {
1691 switch (MessageBuffer[6]) {
1692 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8]; break;
1693 case 0x01: CurrentProfile->CallAlert = MessageBuffer[8]; break;
1694 case 0x02: CurrentProfile->Ringtone = MessageBuffer[8]; break;
1695 case 0x03: CurrentProfile->Volume = MessageBuffer[8]; break;
1696 case 0x04: CurrentProfile->MessageTone = MessageBuffer[8]; break;
1697 case 0x05: CurrentProfile->Vibration = MessageBuffer[8]; break;
1698 case 0x06: CurrentProfile->WarningTone = MessageBuffer[8]; break;
1699 case 0x07: CurrentProfile->ScreenSaver = MessageBuffer[8]; break;
1702 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1708 switch (MessageBuffer[6]) {
1709 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8];break;
1710 case 0x01: CurrentProfile->Lights = MessageBuffer[8];break;
1711 case 0x02: CurrentProfile->CallAlert = MessageBuffer[8];break;
1712 case 0x03: CurrentProfile->Ringtone = MessageBuffer[8];break;
1713 case 0x04: CurrentProfile->Volume = MessageBuffer[8];break;
1714 case 0x05: CurrentProfile->MessageTone = MessageBuffer[8];break;
1715 case 0x06: CurrentProfile->Vibration = MessageBuffer[8];break;
1716 case 0x07: CurrentProfile->WarningTone = MessageBuffer[8];break;
1717 case 0x08: CurrentProfile->CallerGroups = MessageBuffer[8];break;
1718 case 0x09: CurrentProfile->AutomaticAnswer = MessageBuffer[8];break;
1721 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1728 CurrentProfileError = GE_NONE;
1731 /* Incoming profile name */
1734 if (MessageBuffer[9] == 0x00) {
1735 CurrentProfile->DefaultName=MessageBuffer[8];
1737 CurrentProfile->DefaultName=-1;
1739 /* Here name is in Unicode */
1740 if (GetModelFeature (FN_PROFILES)==F_PROF33) {
1741 DecodeUnicode (CurrentProfile->Name, MessageBuffer+10, MessageBuffer[9]/2);
1744 sprintf(CurrentProfile->Name, MessageBuffer + 10, MessageBuffer[9]);
1745 CurrentProfile->Name[MessageBuffer[9]] = '\0';
1749 CurrentProfileError = GE_NONE;
1755 /* Needs SIM card with PIN in phone */
1756 GSM_Error N6110_GetProfile(GSM_Profile *Profile)
1760 unsigned char name_req[] = { N6110_FRAME_HEADER, 0x1a, 0x00};
1761 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x13, 0x01, 0x00, 0x00};
1765 CurrentProfile = Profile;
1767 /* When after sending all frames feature==253, it means, that it is not
1769 CurrentProfile->KeypadTone=253;
1770 CurrentProfile->Lights=253;
1771 CurrentProfile->CallAlert=253;
1772 CurrentProfile->Ringtone=253;
1773 CurrentProfile->Volume=253;
1774 CurrentProfile->MessageTone=253;
1775 CurrentProfile->WarningTone=253;
1776 CurrentProfile->Vibration=253;
1777 CurrentProfile->CallerGroups=253;
1778 CurrentProfile->ScreenSaver=253;
1779 CurrentProfile->AutomaticAnswer=253;
1781 name_req[4] = Profile->Number;
1783 error=NULL_SendMessageSequence
1784 (20, &CurrentProfileError, 5, 0x05, name_req);
1785 if (error!=GE_NONE) return error;
1787 for (i = 0x00; i <= 0x09; i++) {
1789 feat_req[5] = Profile->Number;
1793 error=NULL_SendMessageSequence
1794 (20, &CurrentProfileError, 7, 0x05, feat_req);
1795 if (error!=GE_NONE) return error;
1798 if (Profile->DefaultName > -1)
1800 switch(GetModelFeature (FN_PROFILES)) {
1802 switch (Profile->DefaultName) {
1803 case 0x00: sprintf(Profile->Name, "General");break;
1804 case 0x01: sprintf(Profile->Name, "Silent");break;
1805 case 0x02: sprintf(Profile->Name, "Descreet");break;
1806 case 0x03: sprintf(Profile->Name, "Loud");break;
1807 case 0x04: sprintf(Profile->Name, "My style");break;
1808 case 0x05: Profile->Name[0]=0;break;
1809 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1813 switch (Profile->DefaultName) {
1814 case 0x00: sprintf(Profile->Name, "Personal");break;
1815 case 0x01: sprintf(Profile->Name, "Car");break;
1816 case 0x02: sprintf(Profile->Name, "Headset");break;
1817 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1821 switch (Profile->DefaultName) {
1822 case 0x00: sprintf(Profile->Name, "General");break;
1823 case 0x01: sprintf(Profile->Name, "Silent");break;
1824 case 0x02: sprintf(Profile->Name, "Meeting");break;
1825 case 0x03: sprintf(Profile->Name, "Outdoor");break;
1826 case 0x04: sprintf(Profile->Name, "Pager");break;
1827 case 0x05: sprintf(Profile->Name, "Car");break;
1828 case 0x06: sprintf(Profile->Name, "Headset");break;
1829 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1839 void N6110_ReplySetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1841 switch (MessageBuffer[3]) {
1843 /* Profile feature change result */
1846 fprintf(stdout, _("Message: Profile feature change result.\n"));
1848 CurrentProfileError = GE_NONE;
1851 /* Profile name set result */
1854 fprintf(stdout, _("Message: Profile name change result.\n"));
1856 CurrentProfileError = GE_NONE;
1862 GSM_Error N6110_SetProfileFeature(u8 profile, u8 feature, u8 value)
1864 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x10, 0x01,
1867 feat_req[5]=profile;
1868 feat_req[6]=feature;
1871 return NULL_SendMessageSequence
1872 (20, &CurrentProfileError, 8, 0x05, feat_req);
1875 GSM_Error N6110_SetProfile(GSM_Profile *Profile)
1879 unsigned char name_req[40] = { N6110_FRAME_HEADER, 0x1c, 0x01, 0x03,
1884 name_req[7] = Profile->Number;
1885 name_req[8] = strlen(Profile->Name);
1886 name_req[6] = name_req[8] + 2;
1888 for (i = 0; i < name_req[8]; i++)
1889 name_req[9 + i] = Profile->Name[i];
1891 error=NULL_SendMessageSequence
1892 (20, &CurrentProfileError, name_req[8] + 9, 0x05, name_req);
1893 if (error!=GE_NONE) return error;
1895 for (i = 0x00; i <= 0x09; i++) {
1898 case 0x00: value = Profile->KeypadTone; break;
1899 case 0x01: value = Profile->Lights; break;
1900 case 0x02: value = Profile->CallAlert; break;
1901 case 0x03: value = Profile->Ringtone; break;
1902 case 0x04: value = Profile->Volume; break;
1903 case 0x05: value = Profile->MessageTone; break;
1904 case 0x06: value = Profile->Vibration; break;
1905 case 0x07: value = Profile->WarningTone; break;
1906 case 0x08: value = Profile->CallerGroups; break;
1907 case 0x09: value = Profile->AutomaticAnswer; break;
1908 default : value = 0; break;
1911 error=N6110_SetProfileFeature(Profile->Number,i,value);
1912 if (error!=GE_NONE) return error;
1918 #endif /* UCLINUX */
1920 bool N6110_SendRLPFrame(RLP_F96Frame *frame, bool out_dtx)
1922 u8 req[60] = { 0x00, 0xd9 };
1924 /* Discontinuos transmission (DTX). See section 5.6 of GSM 04.22 version
1930 memcpy(req+2, (u8 *) frame, 32);
1932 return (Protocol->SendFrame(32, 0xf0, req));
1937 void N6110_ReplyGetCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1945 switch (MessageBuffer[4]) {
1949 CurrentCalendarNote->Type=MessageBuffer[8];
1951 DecodeDateTime(MessageBuffer+9, &CurrentCalendarNote->Time);
1953 DecodeDateTime(MessageBuffer+16, &CurrentCalendarNote->Alarm);
1955 CurrentCalendarNote->Text[0]=0;
1957 if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
1959 if (CurrentCalendarNote->Type == GCN_REMINDER) i=1; //first char is subset
1960 switch (MessageBuffer[24]) {
1963 fprintf(stdout,_("Subset 3 in reminder note !\n"));
1965 while (i!=MessageBuffer[23]) {
1967 if (i!=MessageBuffer[23]-1) {
1968 if (MessageBuffer[24+i]>=0xc2) {
1969 DecodeWithUTF8Alphabet(MessageBuffer[24+i], MessageBuffer[24+i+1], &mychar1);
1970 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1971 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=mychar1;
1977 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1978 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=MessageBuffer[24+i];
1985 fprintf(stdout,_("Subset 2 in reminder note !\n"));
1987 while (i!=MessageBuffer[23]) {
1988 wc = MessageBuffer[24+i] | (0x00 << 8);
1989 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1990 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=
1991 DecodeWithUnicodeAlphabet(wc);
1997 fprintf(stdout,_("Subset 1 in reminder note !\n"));
1999 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
2000 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
2004 fprintf(stdout,_("Unknown subset in reminder note !\n"));
2006 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
2007 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
2011 memcpy(CurrentCalendarNote->Text,MessageBuffer+24,MessageBuffer[23]);
2012 CurrentCalendarNote->Text[MessageBuffer[23]]=0;
2015 if (CurrentCalendarNote->Type == GCN_CALL) {
2016 memcpy(CurrentCalendarNote->Phone,MessageBuffer+24+MessageBuffer[23]+1,MessageBuffer[24+MessageBuffer[23]]);
2017 CurrentCalendarNote->Phone[MessageBuffer[24+MessageBuffer[23]]]=0;
2020 CurrentCalendarNote->Recurrance=0;
2022 CurrentCalendarNote->AlarmType=0;
2025 fprintf(stdout, _("Message: Calendar note received.\n"));
2027 fprintf(stdout, _(" Date: %d-%02d-%02d\n"), CurrentCalendarNote->Time.Year,
2028 CurrentCalendarNote->Time.Month,
2029 CurrentCalendarNote->Time.Day);
2031 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentCalendarNote->Time.Hour,
2032 CurrentCalendarNote->Time.Minute,
2033 CurrentCalendarNote->Time.Second);
2035 /* Some messages do not have alarm set up */
2036 if (CurrentCalendarNote->Alarm.Year != 0) {
2037 fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"), CurrentCalendarNote->Alarm.Year,
2038 CurrentCalendarNote->Alarm.Month,
2039 CurrentCalendarNote->Alarm.Day);
2041 fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"), CurrentCalendarNote->Alarm.Hour,
2042 CurrentCalendarNote->Alarm.Minute,
2043 CurrentCalendarNote->Alarm.Second);
2046 fprintf(stdout, _(" Type: %d\n"), CurrentCalendarNote->Type);
2047 fprintf(stdout, _(" Text: %s\n"), CurrentCalendarNote->Text);
2049 if (CurrentCalendarNote->Type == GCN_CALL)
2050 fprintf(stdout, _(" Phone: %s\n"), CurrentCalendarNote->Phone);
2053 CurrentCalendarNoteError=GE_NONE;
2059 fprintf(stdout, _("Message: Calendar note not available\n"));
2062 CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;
2068 fprintf(stdout, _("Message: Calendar note error\n"));
2071 CurrentCalendarNoteError=GE_INTERNALERROR;
2077 GSM_Error N6110_GetCalendarNote(GSM_CalendarNote *CalendarNote)
2080 unsigned char req[] = { N6110_FRAME_HEADER,
2085 req[4]=CalendarNote->Location;
2087 CurrentCalendarNote = CalendarNote;
2089 error=NULL_SendMessageSequence
2090 (20, &CurrentCalendarNoteError, 5, 0x13, req);
2092 CurrentCalendarNote = NULL;
2097 void N6110_ReplyWriteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2100 switch(MessageBuffer[4]) {
2101 /* This message is also sent when the user enters the new entry on keypad */
2103 fprintf(stdout, _("Message: Calendar note write succesfull!\n"));break;
2105 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2107 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2109 fprintf(stdout, _("Unknown message of type 0x13 and subtype 0x65\n"));break;
2113 switch(MessageBuffer[4]) {
2114 case 0x01: CurrentCalendarNoteError=GE_NONE; break;
2115 case 0x73: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2116 case 0x7d: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2117 default : AppendLogText("Unknown msg\n",false); break;
2121 GSM_Error N6110_WriteCalendarNote(GSM_CalendarNote *CalendarNote)
2124 unsigned char req[200] = { N6110_FRAME_HEADER,
2126 0x00, /* Length of the rest of the frame. */
2127 0x00, /* The type of calendar note */
2128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2135 unsigned char meeting;
2136 unsigned char birthday;
2137 unsigned char reminder;
2138 } calendar_model_length;
2140 /* Length of entries */
2141 calendar_model_length calendar_lengths[] =
2143 /*model,CallTo,Meeting,Birthday,Reminder*/
2144 {"NHM-5",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2145 {"NHM-6",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2146 {"NSE-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 [HKEY_LOCAL_MACHINE\Software\Nokia\Data Suite\3.0\Calendar]
2147 {"NSM-1",0x1e,0x18,0x18,0x24}, //from NCDS3
2148 {"NSK-3",0x1e,0x14,0x14,0x1e}, //from NCDS3
2149 {"NSB-3",0x20,0x14,0x14,0x1e}, //from NCDS3
2150 {"", 0, 0, 0, 0 } //end of table
2161 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
2164 req[7]=CalendarNote->Type;
2166 EncodeDateTime(req+8, &CalendarNote->Time);
2167 req[14] = CalendarNote->Time.Timezone;
2169 if (CalendarNote->Alarm.Year) {
2170 EncodeDateTime(req+15, &CalendarNote->Alarm);
2171 req[21] = CalendarNote->Alarm.Timezone;
2174 req[22]=strlen(CalendarNote->Text);
2178 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2179 req[22]++; // one additional char
2180 req[current++]=0x01; //we use now subset 1
2183 for (i=0; i<strlen(CalendarNote->Text); i++) {
2185 mychar=CalendarNote->Text[i];
2186 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2187 if (EncodeWithUTF8Alphabet(mychar,&mychar1,&mychar2)) {
2188 req[current++]=mychar1;
2189 req[current++]=mychar2;
2190 req[23]=0x03; //use subset 3
2191 req[22]++; // one additional char
2196 /* Enables/disables blinking */
2197 if (mychar=='~') req[current++]=0x01;
2198 else req[current++]=mychar;
2202 req[current++]=strlen(CalendarNote->Phone);
2204 for (i=0; i<strlen(CalendarNote->Phone); i++)
2205 req[current++]=CalendarNote->Phone[i];
2207 while (N6110_GetModel(model) != GE_NONE)
2210 /* Checking maximal length */
2212 while (strcmp(calendar_lengths[i].model,"")) {
2213 if (!strcmp(calendar_lengths[i].model,model)) {
2214 switch (CalendarNote->Type) {
2215 case GCN_REMINDER:if (req[22]>calendar_lengths[i].reminder) return GE_TOOLONG;break;
2216 case GCN_MEETING :if (req[22]>calendar_lengths[i].meeting) return GE_TOOLONG;break;
2217 case GCN_BIRTHDAY:if (req[22]>calendar_lengths[i].birthday) return GE_TOOLONG;break;
2218 case GCN_CALL :if (strlen(CalendarNote->Phone)>calendar_lengths[i].call) return GE_TOOLONG;break;
2225 CurrentCalendarNote = CalendarNote;
2227 error=NULL_SendMessageSequence
2228 (20, &CurrentCalendarNoteError, current, 0x13, req);
2230 CurrentCalendarNote = NULL;
2235 void N6110_ReplyDeleteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2238 switch (MessageBuffer[4]) {
2239 /* This message is also sent when the user deletes an old entry on
2240 keypad or moves an old entry somewhere (there is also `write'
2242 case 0x01:fprintf(stdout, _("Message: Calendar note deleted\n"));break;
2243 case 0x93:fprintf(stdout, _("Message: Calendar note can't be deleted\n"));break;
2244 default :fprintf(stdout, _("Message: Calendar note deleting error\n"));break;
2248 switch (MessageBuffer[4]) {
2249 case 0x01:CurrentCalendarNoteError=GE_NONE;break;
2250 case 0x93:CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;break;
2251 default :CurrentCalendarNoteError=GE_INTERNALERROR;break;
2255 GSM_Error N6110_DeleteCalendarNote(GSM_CalendarNote *CalendarNote)
2258 unsigned char req[] = { N6110_FRAME_HEADER,
2262 req[4]=CalendarNote->Location;
2264 return NULL_SendMessageSequence (20, &CurrentCalendarNoteError, 5, 0x13, req);
2267 #endif /* UCLINUX */
2269 static void N6110_ReplyRFBatteryLevel(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2272 fprintf(stdout, _("Message: Phone status received:\n"));
2273 fprintf(stdout, _(" Mode: "));
2275 switch (MessageBuffer[4]) {
2279 fprintf(stdout, _("registered within the network\n"));
2282 /* I was really amazing why is there a hole in the type of 0x02, now I
2284 case 0x02: fprintf(stdout, _("call in progress\n")); break; /* ringing or already answered call */
2285 case 0x03: fprintf(stdout, _("waiting for security code\n")); break;
2286 case 0x04: fprintf(stdout, _("powered off\n")); break;
2287 default : fprintf(stdout, _("unknown\n"));
2291 fprintf(stdout, _(" Power source: "));
2293 switch (MessageBuffer[7]) {
2295 case 0x01: fprintf(stdout, _("AC/DC\n")); break;
2296 case 0x02: fprintf(stdout, _("battery\n")); break;
2297 default : fprintf(stdout, _("unknown\n"));
2301 fprintf(stdout, _(" Battery Level: %d\n"), MessageBuffer[8]);
2302 fprintf(stdout, _(" Signal strength: %d\n"), MessageBuffer[5]);
2305 CurrentRFLevel=MessageBuffer[5];
2306 CurrentBatteryLevel=MessageBuffer[8];
2307 CurrentPowerSource=MessageBuffer[7];
2311 GSM_Error N6110_GetRFLevel(GSM_RFUnits *units, float *level)
2314 /* FIXME - these values are from 3810 code, may be incorrect. Map from
2315 values returned in status packet to the the values returned by the AT+CSQ
2317 float csq_map[5] = {0, 8, 16, 24, 31};
2322 char screen[NM_MAX_SCREEN_WIDTH];
2326 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2329 if (N6110_NetMonitor(1, screen)!=GE_NONE)
2330 return GE_INTERNALERROR;
2331 #endif /* UCLINUX */
2335 if (screen[4]!='-') {
2336 if (screen[5]=='9' && screen[6]>'4') rf_level=1;
2337 if (screen[5]=='9' && screen[6]<'5') rf_level=2;
2338 if (screen[5]=='8' && screen[6]>'4') rf_level=3;
2341 /* Arbitrary units. */
2342 if (*units == GRF_Arbitrary) {
2348 N6110_SendStatusRequest();
2350 /* Wait for timeout or other error. */
2351 while (timeout != 0 && CurrentRFLevel == -1 ) {
2354 return (GE_TIMEOUT);
2359 /* Make copy in case it changes. */
2360 rf_level = CurrentRFLevel;
2365 /* Now convert between the different units we support. */
2367 /* Arbitrary units. */
2368 if (*units == GRF_Arbitrary) {
2374 if (*units == GRF_CSQ) {
2377 *level = csq_map[rf_level];
2379 *level = 99; /* Unknown/undefined */
2385 /* Unit type is one we don't handle so return error */
2386 return (GE_INTERNALERROR);
2390 GSM_Error N6110_GetBatteryLevel(GSM_BatteryUnits *units, float *level)
2395 char screen[NM_MAX_SCREEN_WIDTH];
2397 CurrentBatteryLevel=-1;
2399 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2402 if (N6110_NetMonitor(23, screen)!=GE_NONE)
2404 #endif /* UCLINUX */
2408 if (screen[29]=='7') batt_level=3;
2409 if (screen[29]=='5') batt_level=2;
2410 if (screen[29]=='2') batt_level=1;
2412 /* Only units we handle at present are GBU_Arbitrary */
2413 if (*units == GBU_Arbitrary) {
2414 *level = batt_level;
2418 return (GE_INTERNALERROR);
2421 N6110_SendStatusRequest();
2423 /* Wait for timeout or other error. */
2424 while (timeout != 0 && CurrentBatteryLevel == -1 ) {
2427 return (GE_TIMEOUT);
2432 /* Take copy in case it changes. */
2433 batt_level = CurrentBatteryLevel;
2435 if (batt_level != -1) {
2437 /* Only units we handle at present are GBU_Arbitrary */
2438 if (*units == GBU_Arbitrary) {
2439 *level = batt_level;
2443 return (GE_INTERNALERROR);
2450 GSM_Error N6110_GetPowerSource(GSM_PowerSource *source)
2455 char screen[NM_MAX_SCREEN_WIDTH];
2457 CurrentPowerSource=-1;
2459 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2462 if (N6110_NetMonitor(20, screen)!=GE_NONE)
2464 #endif /* UCLINUX */
2466 CurrentPowerSource=GPS_ACDC;
2468 if (screen[6]=='x') CurrentPowerSource=GPS_BATTERY;
2470 *source=CurrentPowerSource;
2474 N6110_SendStatusRequest();
2476 /* Wait for timeout or other error. */
2477 while (timeout != 0 && CurrentPowerSource == -1 ) {
2480 return (GE_TIMEOUT);
2485 if (CurrentPowerSource != -1) {
2486 *source=CurrentPowerSource;
2496 static void N6110_ReplyGetDisplayStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2500 for (i=0; i<MessageBuffer[4];i++)
2501 if (MessageBuffer[2*i+6]==2)
2502 CurrentDisplayStatus|=1<<(MessageBuffer[2*i+5]-1);
2504 CurrentDisplayStatus&= (0xff - (1<<(MessageBuffer[2*i+5]-1)));
2507 fprintf(stdout, _("Call in progress: %s\n"), CurrentDisplayStatus & (1<<DS_Call_In_Progress)?"on":"off");
2508 fprintf(stdout, _("Unknown: %s\n"), CurrentDisplayStatus & (1<<DS_Unknown)?"on":"off");
2509 fprintf(stdout, _("Unread SMS: %s\n"), CurrentDisplayStatus & (1<<DS_Unread_SMS)?"on":"off");
2510 fprintf(stdout, _("Voice call: %s\n"), CurrentDisplayStatus & (1<<DS_Voice_Call)?"on":"off");
2511 fprintf(stdout, _("Fax call active: %s\n"), CurrentDisplayStatus & (1<<DS_Fax_Call)?"on":"off");
2512 fprintf(stdout, _("Data call active: %s\n"), CurrentDisplayStatus & (1<<DS_Data_Call)?"on":"off");
2513 fprintf(stdout, _("Keyboard lock: %s\n"), CurrentDisplayStatus & (1<<DS_Keyboard_Lock)?"on":"off");
2514 fprintf(stdout, _("SMS storage full: %s\n"), CurrentDisplayStatus & (1<<DS_SMS_Storage_Full)?"on":"off");
2517 CurrentDisplayStatusError=GE_NONE;
2520 GSM_Error N6110_GetDisplayStatus(int *Status) {
2522 unsigned char req[4]={ N6110_FRAME_HEADER, 0x51 };
2526 error=NULL_SendMessageSequence
2527 (10, &CurrentDisplayStatusError, 4, 0x0d, req);
2528 if (error!=GE_NONE) return error;
2530 *Status=CurrentDisplayStatus;
2535 GSM_Error N6110_DialVoice(char *Number) {
2536 /* This commented sequence doesn't work on N3210/3310/6210/7110 */
2537 // unsigned char req[64]={N6110_FRAME_HEADER, 0x01};
2538 // unsigned char req_end[]={0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};
2540 // req[4]=strlen(Number);
2541 // for(i=0; i < strlen(Number) ; i++)
2542 // req[5+i]=Number[i];
2543 // memcpy(req+5+strlen(Number), req_end, 10);
2544 // return NULL_SendMessageSequence
2545 // (20, &CurrentDialVoiceError, 13+strlen(Number), 0x01, req);
2547 unsigned char req[64]={0x00,0x01,0x7c,
2548 0x01}; //call command
2554 error=N6110_EnableExtendedCommands(0x01);
2555 if (error!=GE_NONE) return error;
2557 for(i=0; i < strlen(Number) ; i++) req[4+i]=Number[i];
2561 return NULL_SendMessageSequence
2562 (20, &CurrentDialVoiceError, 4+strlen(Number)+1, 0x40, req);
2565 #endif /* UCLINUX */
2567 /* Dial a data call - type specifies request to use:
2568 type 0 should normally be used
2569 type 1 should be used when calling a digital line - corresponds to ats35=0
2570 Maybe one day we'll know what they mean!
2572 GSM_Error N6110_DialData(char *Number, char type, void (* callpassup)(char c))
2574 unsigned char req[100] = { N6110_FRAME_HEADER, 0x01 };
2575 unsigned char *req_end;
2576 unsigned char req_end0[] = { 0x01, /* make a data call = type 0x01 */
2577 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2578 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00 };
2579 unsigned char req_end1[] = { 0x01,
2580 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2581 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2582 0x88,0x90,0x21,0x48,0x40,0xbb };
2583 unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2584 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2585 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
2586 unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2587 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2588 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
2589 unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
2590 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2591 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
2592 0x20,0x15,0x63,0x80 };
2597 CurrentCallPassup=callpassup;
2601 usleep(100); Protocol->SendMessage(sizeof(req3), 0x01, req3); /* Lace */
2604 size = sizeof(req_end0);
2607 Protocol->SendMessage(sizeof(req3), 0x01, req3);
2609 Protocol->SendMessage(sizeof(req4), 0x01, req4);
2612 size = sizeof(req_end1);
2614 case -1: /* Just used to set the call passup */
2619 size = sizeof(req_end0);
2623 req[4] = strlen(Number);
2625 for(i = 0; i < strlen(Number) ; i++)
2626 req[5+i] = Number[i];
2628 memcpy(req + 5 + strlen(Number), req_end, size);
2630 Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);
2634 if (type != 1) Protocol->SendMessage(26, 0x01, req2);
2642 GSM_Error N6110_GetIncomingCallNr(char *Number)
2645 if (*CurrentIncomingCall != ' ') {
2646 strcpy(Number, CurrentIncomingCall);
2653 #endif /* UCLINUX */
2655 GSM_Error N6110_CancelCall(void)
2657 // This frame & method works only on 61xx/51xx
2658 // unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
2659 // req[4]=CurrentCallSequenceNumber;
2660 // Protocol->SendMessage(6, 0x01, req);
2665 unsigned char req[]={0x00,0x01,0x7c,0x03};
2668 error=N6110_EnableExtendedCommands(0x01);
2669 if (error!=GE_NONE) return error;
2671 return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
2676 void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2678 switch(MessageBuffer[3]) {
2682 fprintf(stdout, _("Message: Security code accepted.\n"));
2684 CurrentSecurityCodeError = GE_NONE;
2689 fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
2691 CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
2695 GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
2698 unsigned char req[15] = { N6110_FRAME_HEADER,
2699 0x0a, /* Enter code request. */
2700 0x00 /* Type of the entered code. */
2704 req[4]=SecurityCode.Type;
2706 for (i=0; i<strlen(SecurityCode.Code);i++)
2707 req[5+i]=SecurityCode.Code[i];
2709 req[5+strlen(SecurityCode.Code)]=0x00;
2710 req[6+strlen(SecurityCode.Code)]=0x00;
2712 return NULL_SendMessageSequence
2713 (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
2716 void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2718 *CurrentSecurityCodeStatus = MessageBuffer[4];
2721 fprintf(stdout, _("Message: Security Code status received: "));
2723 switch(*CurrentSecurityCodeStatus) {
2725 case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;
2726 case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;
2727 case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;
2728 case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;
2729 case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;
2730 case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;
2731 default : fprintf(stdout, _("Unknown!\n"));
2736 CurrentSecurityCodeError = GE_NONE;
2739 GSM_Error N6110_GetSecurityCodeStatus(int *Status)
2742 unsigned char req[4] = { N6110_FRAME_HEADER,
2746 CurrentSecurityCodeStatus=Status;
2748 return NULL_SendMessageSequence
2749 (20, &CurrentSecurityCodeError, 4, 0x08, req);
2752 void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2757 fprintf(stdout, _("Message: Security code received: "));
2758 switch (MessageBuffer[3]) {
2759 case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;
2760 case GSCT_Pin: fprintf(stdout, _("PIN"));break;
2761 case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;
2762 case GSCT_Puk: fprintf(stdout, _("PUK"));break;
2763 case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;
2764 default: fprintf(stdout, _("unknown !"));break;
2766 if (MessageBuffer[4]==1) {
2767 fprintf(stdout, _(" allowed, value \""));
2768 if (MessageBuffer[3]==GSCT_SecurityCode) {
2769 for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2771 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2772 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2773 for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2775 fprintf(stdout, _("\""));
2777 fprintf(stdout, _(" not allowed"));
2779 fprintf(stdout, _("\n"));
2782 if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
2783 && MessageBuffer[4]==1) { /* It's allowed */
2784 if (MessageBuffer[3]==GSCT_SecurityCode) {
2785 for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2786 CurrentSecurityCode->Code[5]=0;
2788 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2789 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2790 for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2791 CurrentSecurityCode->Code[4]=0;
2793 CurrentSecurityCodeError=GE_NONE;
2795 CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
2798 GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
2801 unsigned char req[4] = { 0x00,
2802 0x01,0x6e, /* Get code request. */
2803 0x00 }; /* Type of the requested code. */
2807 error=N6110_EnableExtendedCommands(0x01);
2808 if (error!=GE_NONE) return error;
2810 req[3]=SecurityCode->Type;
2812 CurrentSecurityCode=SecurityCode;
2814 return NULL_SendMessageSequence
2815 (20, &CurrentSecurityCodeError, 4, 0x40, req);
2818 void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2821 fprintf(stdout, _("Message: answer for PlayTone frame\n"));
2824 CurrentPlayToneError=GE_NONE;
2827 GSM_Error N6110_PlayTone(int Herz, u8 Volume)
2829 unsigned char req[6] = { 0x00,0x01,0x8f,
2832 0x00 }; /* HerzHi */
2836 /* PlayTone wasn't used earlier */
2837 if (CurrentPlayToneError==GE_UNKNOWN) {
2838 if (CurrentConnectionType!=GCT_MBUS)
2839 CurrentDisableKeepAlive=true;
2841 error=N6110_EnableExtendedCommands(0x01);
2842 if (error!=GE_NONE) return error;
2845 /* For Herz==255*255 we have silent */
2846 if (Herz!=255*255) {
2859 /* For Herz==255*255 we have silent and additionaly
2860 we wait for phone answer - it's important for MBUS */
2861 if (Herz==255*255) {
2862 error=NULL_SendMessageSequence
2863 (20, &CurrentPlayToneError, 6, 0x40, req);
2865 CurrentPlayToneError=GE_UNKNOWN;
2866 CurrentDisableKeepAlive=false;
2868 if (error!=GE_NONE) return error;
2870 Protocol->SendMessage(6,0x40,req);
2873 error=NULL_SendMessageSequence
2874 (20, &CurrentPlayToneError, 6, 0x40, req);
2876 /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
2877 if (Herz==255*255) {
2878 CurrentPlayToneError=GE_UNKNOWN;
2879 CurrentDisableKeepAlive=false;
2882 if (error!=GE_NONE) return error;
2889 void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2891 if (MessageBuffer[4]==0x01) {
2892 DecodeDateTime(MessageBuffer+8, CurrentDateTime);
2895 fprintf(stdout, _("Message: Date and time\n"));
2896 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
2897 fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
2900 CurrentDateTime->IsSet=true;
2904 fprintf(stdout, _("Message: Date and time not set in phone\n"));
2907 CurrentDateTime->IsSet=false;
2910 CurrentDateTimeError=GE_NONE;
2913 GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
2915 return N6110_PrivGetDateTime(date_time,0x11);
2918 GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
2920 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
2922 CurrentDateTime=date_time;
2924 return NULL_SendMessageSequence
2925 (50, &CurrentDateTimeError, 4, msgtype, req);
2928 void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2931 fprintf(stdout, _("Message: Alarm\n"));
2932 fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
2933 fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
2936 CurrentAlarm->Hour=MessageBuffer[9];
2937 CurrentAlarm->Minute=MessageBuffer[10];
2938 CurrentAlarm->Second=0;
2940 CurrentAlarm->IsSet=(MessageBuffer[8]==2);
2942 CurrentAlarmError=GE_NONE;
2945 GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
2947 return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
2950 GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
2952 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
2954 CurrentAlarm=date_time;
2956 return NULL_SendMessageSequence
2957 (50, &CurrentAlarmError, 4, msgtype, req);
2960 void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2962 switch (MessageBuffer[3]) {
2966 CurrentMessageCenter->No=MessageBuffer[4];
2967 CurrentMessageCenter->Format=MessageBuffer[6];
2968 CurrentMessageCenter->Validity=MessageBuffer[8];
2969 sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
2971 sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
2973 sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
2976 fprintf(stdout, _("Message: SMS Center received:\n"));
2977 fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
2978 fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
2979 fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
2981 fprintf(stdout, _(" SMS Center message format is "));
2983 switch (CurrentMessageCenter->Format) {
2985 case GSMF_Text : fprintf(stdout, _("Text")); break;
2986 case GSMF_Paging: fprintf(stdout, _("Paging")); break;
2987 case GSMF_Fax : fprintf(stdout, _("Fax")); break;
2988 case GSMF_Email : fprintf(stdout, _("Email")); break;
2989 default : fprintf(stdout, _("Unknown"));
2992 fprintf(stdout, "\n");
2994 fprintf(stdout, _(" SMS Center message validity is "));
2996 switch (CurrentMessageCenter->Validity) {
2998 case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;
2999 case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;
3000 case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;
3001 case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;
3002 case GSMV_1_Week : fprintf(stdout, _("1 week")); break;
3003 case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;
3004 default : fprintf(stdout, _("Unknown"));
3007 fprintf(stdout, "\n");
3011 CurrentMessageCenterError=GE_NONE;
3017 /* Number of entries depends on SIM card */
3020 fprintf(stdout, _("Message: SMS Center error received:\n"));
3021 fprintf(stdout, _(" The request for SMS Center failed.\n"));
3024 /* FIXME: appropriate error. */
3025 CurrentMessageCenterError=GE_INTERNALERROR;
3032 /* This function sends to the mobile phone a request for the SMS Center */
3033 GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
3035 unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
3036 0x00 /* SMS Center Number. */
3039 req[5]=MessageCenter->No;
3041 CurrentMessageCenter=MessageCenter;
3043 return NULL_SendMessageSequence
3044 (50, &CurrentMessageCenterError, 6, 0x02, req);
3047 void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3050 fprintf(stdout, _("Message: SMS Center correctly set.\n"));
3052 CurrentMessageCenterError=GE_NONE;
3055 /* This function set the SMS Center profile on the phone. */
3056 GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
3058 unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
3059 0x00, /* SMS Center Number. */
3060 0x00, /* Unknown. */
3061 0x00, /* SMS Message Format. */
3062 0x00, /* Unknown. */
3063 0x00, /* Validity. */
3064 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
3065 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
3066 /* Message Center Name. */
3069 req[5]=MessageCenter->No;
3070 req[7]=MessageCenter->Format;
3071 req[9]=MessageCenter->Validity;
3073 req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
3075 req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
3077 sprintf(req+34, "%s", MessageCenter->Name);
3079 CurrentMessageCenter=MessageCenter;
3081 return NULL_SendMessageSequence
3082 (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
3085 void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3087 switch (MessageBuffer[3]) {
3092 fprintf(stdout, _("Message: SMS Status Received\n"));
3093 fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
3094 fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
3097 CurrentSMSStatus->UnRead = MessageBuffer[11];
3098 CurrentSMSStatus->Number = MessageBuffer[10];
3100 CurrentSMSStatusError = GE_NONE;
3106 fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
3109 CurrentSMSStatusError = GE_INTERNALERROR;
3115 GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
3117 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
3119 CurrentSMSStatus = Status;
3121 return NULL_SendMessageSequence
3122 (10, &CurrentSMSStatusError, 5, 0x14, req);
3125 GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
3129 strcpy(folders->Folder[0].Name,"Inbox");
3130 strcpy(folders->Folder[1].Name,"Outbox");
3135 #endif /* UCLINUX */
3137 GSM_Error N6110_GetIMEI(char *imei)
3139 if (strlen(Current_IMEI)>0) {
3140 strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
3144 return (GE_TRYAGAIN);
3147 GSM_Error N6110_GetRevision(char *revision)
3150 if (strlen(Current_Revision)>0) {
3151 strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
3155 return (GE_TRYAGAIN);
3158 static GSM_Error N6110_GetModel(char *model)
3160 if (strlen(Current_Model)>0) {
3161 strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
3165 return (GE_TRYAGAIN);
3170 void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3172 switch (MessageBuffer[4]) {
3176 fprintf(stdout, _("Message: Date and time set correctly\n"));
3178 CurrentSetDateTimeError=GE_NONE;
3183 fprintf(stdout, _("Message: Date and time setting error\n"));
3185 CurrentSetDateTimeError=GE_INVALIDDATETIME;
3190 /* Needs SIM card with PIN in phone */
3191 GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
3193 return N6110_PrivSetDateTime(date_time,0x11);
3196 /* Needs SIM card with PIN in phone */
3197 GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
3200 unsigned char req[] = { N6110_FRAME_HEADER,
3201 0x60, /* set-time subtype */
3202 0x01, 0x01, 0x07, /* unknown */
3203 0x00, 0x00, /* Year (0x07cf = 1999) */
3204 0x00, 0x00, /* Month Day */
3205 0x00, 0x00, /* Hours Minutes */
3206 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3209 EncodeDateTime(req+7, date_time);
3211 return NULL_SendMessageSequence
3212 (20, &CurrentSetDateTimeError, 14, msgtype, req);
3215 void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3217 switch (MessageBuffer[4]) {
3221 fprintf(stdout, _("Message: Alarm set correctly\n"));
3223 CurrentSetAlarmError=GE_NONE;
3228 fprintf(stdout, _("Message: Alarm setting error\n"));
3230 CurrentSetAlarmError=GE_INVALIDDATETIME;
3235 /* FIXME: we should also allow to set the alarm off :-) */
3236 GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
3238 return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
3241 /* FIXME: we should also allow to set the alarm off :-) */
3242 GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
3245 unsigned char req[] = { N6110_FRAME_HEADER,
3246 0x6b, /* set-alarm subtype */
3247 0x01, 0x20, 0x03, /* unknown */
3248 0x02, /* should be alarm on/off, but it don't works */
3249 0x00, 0x00, /* Hours Minutes */
3250 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3253 req[8] = date_time->Hour;
3254 req[9] = date_time->Minute;
3256 return NULL_SendMessageSequence
3257 (50, &CurrentSetAlarmError, 11, msgtype, req);
3260 #endif /* UCLINUX */
3262 static void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3264 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
3269 switch (MessageBuffer[3]) {
3273 CurrentPhonebookEntry->Empty = true;
3275 count=MessageBuffer[5];
3278 fprintf(stdout, _("Message: Phonebook entry received:\n"));
3279 fprintf(stdout, _(" Name: "));
3281 for (tmp=0; tmp <count; tmp++)
3283 if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
3284 if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
3285 fprintf(stdout, "%c", MessageBuffer[6+tmp]);
3288 fprintf(stdout, "\n");
3291 while (N6110_GetModel(model) != GE_NONE)
3294 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3296 DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
3297 CurrentPhonebookEntry->Name[count/2] = 0x00;
3299 fprintf(stderr,"FATAL ERROR: DecodeUnicode disabled!\n");
3301 #endif /* UCLINUX */
3303 memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);
3304 CurrentPhonebookEntry->Name[count] = 0x00;
3307 CurrentPhonebookEntry->Empty = false;
3309 for (tmp=0; tmp <count; tmp++)
3311 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3312 /* We check only 1'st, 3'rd, ... char */
3313 if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking
3314 if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents
3316 if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking
3317 if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents
3322 count=MessageBuffer[6+count];
3325 fprintf(stdout, _(" Number: "));
3327 for (tmp=0; tmp <count; tmp++)
3328 fprintf(stdout, "%c", MessageBuffer[i+tmp]);
3330 fprintf(stdout, "\n");
3333 memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);
3334 CurrentPhonebookEntry->Number[count] = 0x00;
3335 CurrentPhonebookEntry->Group = MessageBuffer[i+count];
3337 /* Phone doesn't have entended phonebook */
3338 CurrentPhonebookEntry->SubEntriesCount = 0;
3340 /* But for these memories data is saved and we can save it using 7110/6210 style */
3341 if (CurrentPhonebookEntry->MemoryType==GMT_DC ||
3342 CurrentPhonebookEntry->MemoryType==GMT_RC ||
3343 CurrentPhonebookEntry->MemoryType==GMT_MC) {
3344 CurrentPhonebookEntry->SubEntriesCount = 1;
3345 CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;
3346 CurrentPhonebookEntry->SubEntries[0].NumberType=0;
3347 CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;
3348 DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);
3351 fprintf(stdout, _(" Date: "));
3352 fprintf(stdout, "%02u.%02u.%04u\n",
3353 CurrentPhonebookEntry->SubEntries[0].data.Date.Day,
3354 CurrentPhonebookEntry->SubEntries[0].data.Date.Month,
3355 CurrentPhonebookEntry->SubEntries[0].data.Date.Year);
3356 fprintf(stdout, _(" Time: "));
3357 fprintf(stdout, "%02u:%02u:%02u\n",
3358 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,
3359 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,
3360 CurrentPhonebookEntry->SubEntries[0].data.Date.Second);
3363 /* These values are set, when date and time unavailable in phone.
3364 Values from 3310 - in other can be different */
3365 if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&
3366 CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&
3367 CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&
3368 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&
3369 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&
3370 CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)
3371 CurrentPhonebookEntry->SubEntriesCount = 0;
3374 /* Signal no error to calling code. */
3375 CurrentPhonebookError = GE_NONE;
3382 fprintf(stdout, _("Message: Phonebook read entry error received:\n"));
3385 switch (MessageBuffer[4]) {
3389 fprintf(stdout, _(" Invalid memory type!\n"));
3391 CurrentPhonebookError = GE_INVALIDMEMORYTYPE;
3396 fprintf(stdout, _(" Unknown error!\n"));
3398 CurrentPhonebookError = GE_INTERNALERROR;
3406 /* Routine to get specifed phone book location. Designed to be called by
3407 application. Will block until location is retrieved or a timeout/error
3409 GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)
3411 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
3413 CurrentPhonebookEntry = entry;
3415 req[4] = N6110_GetMemoryType(entry->MemoryType);
3416 req[5] = entry->Location;
3418 return NULL_SendMessageSequence
3419 (50, &CurrentPhonebookError, 7, 0x03, req);
3422 static void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3424 switch (MessageBuffer[3]) {
3429 fprintf(stdout, _("Message: Phonebook written correctly.\n"));
3431 CurrentPhonebookError = GE_NONE;
3436 switch (MessageBuffer[4]) {
3437 /* FIXME: other errors? When I send the phonebook with index of 350 it
3438 still report error 0x7d :-( */
3441 fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));
3443 CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;
3448 fprintf(stdout, _(" Unknown error!\n"));
3450 CurrentPhonebookError = GE_INTERNALERROR;
3455 /* Routine to write phonebook location in phone. Designed to be called by
3456 application code. Will block until location is written or timeout
3458 GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)
3460 unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };
3463 req[4] = N6110_GetMemoryType(entry->MemoryType);
3464 req[5] = entry->Location;
3468 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {
3471 req[6] = strlen(entry->Name)*2;
3473 EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
3475 for (i=0; i<strlen(entry->Name); i++)
3477 /* here we encode "special" chars */
3478 if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
3479 if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
3482 current+=strlen(entry->Name)*2;
3486 fprintf(stderr,"FATAL ERROR: EncodeUnicode disabled!\n");
3489 #endif /* UCLINUX */
3492 req[6] = strlen(entry->Name);
3494 for (i=0; i<strlen(entry->Name); i++)
3496 req[current+i] = entry->Name[i];
3498 /* here we encode "special" chars */
3499 if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
3500 if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
3503 current+=strlen(entry->Name);
3506 req[current++]=strlen(entry->Number);
3508 for (i=0; i<strlen(entry->Number); i++)
3509 req[current+i] = entry->Number[i];
3511 current+=strlen(entry->Number);
3513 /* Jano: This allow to save 14 characters name into SIM memory, when
3514 No Group is selected. */
3515 if (entry->Group == 5)
3516 req[current++]=0xff;
3518 req[current++]=entry->Group;
3520 return NULL_SendMessageSequence
3521 (50, &CurrentPhonebookError, current, 0x03, req);
3526 void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3528 switch(MessageBuffer[3]) {
3532 fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
3534 CurrentNetmonitorError=GE_NONE;
3539 fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
3540 fprintf(stdout, "%s\n", MessageBuffer+4);
3543 strcpy(CurrentNetmonitor, MessageBuffer+4);
3545 CurrentNetmonitorError=GE_NONE;
3549 GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
3551 unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
3555 error=N6110_EnableExtendedCommands(0x01);
3556 if (error!=GE_NONE) return error;
3558 CurrentNetmonitor=Screen;
3562 return NULL_SendMessageSequence
3563 (20, &CurrentNetmonitorError, 4, 0x40, req);
3566 /* Doesn't work in N3210. */
3567 /* In other allow to access phone menu without SIM card (just send any sequence) */
3568 GSM_Error N6110_SendDTMF(char *String)
3570 unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
3571 0x00 /* Length of DTMF string. */
3574 u8 length=strlen(String);
3576 if (length>59) length=59;
3580 memcpy(req+5,String,length);
3582 return NULL_SendMessageSequence
3583 (20, &CurrentSendDTMFError, 5+length, 0x01, req);
3586 #endif /* UCLINUX */
3588 static void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3590 switch (MessageBuffer[3]) {
3594 switch (MessageBuffer[4]) {
3595 case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
3596 default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
3599 CurrentSpeedDialEntry->Location = MessageBuffer[5];
3602 fprintf(stdout, _("Message: Speed dial entry received:\n"));
3603 fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
3604 fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
3605 fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
3608 CurrentSpeedDialError=GE_NONE;
3614 fprintf(stdout, _("Message: Speed dial entry error\n"));
3616 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3622 GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
3625 unsigned char req[] = { N6110_FRAME_HEADER,
3627 0x00 /* The number of speed dial. */
3630 CurrentSpeedDialEntry = entry;
3632 req[4] = entry->Number;
3634 return NULL_SendMessageSequence
3635 (20, &CurrentSpeedDialError, 5, 0x03, req);
3638 static void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3640 switch (MessageBuffer[3]) {
3645 fprintf(stdout, _("Message: Speed dial entry set.\n"));
3647 CurrentSpeedDialError=GE_NONE;
3653 fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
3655 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3661 GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
3664 unsigned char req[] = { N6110_FRAME_HEADER,
3667 0x00, /* Memory Type */
3671 req[4] = entry->Number;
3673 switch (entry->MemoryType) {
3674 case GMT_ME: req[5] = 0x02;
3675 default : req[5] = 0x03;
3678 req[6] = entry->Location;
3680 return NULL_SendMessageSequence
3681 (20, &CurrentSpeedDialError, 7, 0x03, req);
3686 /* This function finds parts of SMS in frame used in new Nokia phones
3687 in internal protocols (they're coded according to GSM 03.40), copies them
3688 to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
3689 GSM_ETSISMSMessage to GSM_SMSMessage structure */
3690 GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
3692 SMS_MessageType PDU=SMS_Deliver;
3693 GSM_ETSISMSMessage ETSI;
3696 ETSI.firstbyte=req[12];
3698 /* See GSM 03.40 section 9.2.3.1 */
3699 if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
3700 if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
3703 case SMS_Submit : offset=5;break;
3704 case SMS_Deliver : offset=4;break;
3705 case SMS_Status_Report: offset=3;break;
3709 for (i=0;i<req[0]+1;i++)
3710 ETSI.SMSCNumber[i]=req[i];
3712 for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
3713 ETSI.Number[i]=req[i+12+offset];
3717 ETSI.TPDCS=req[10+offset];
3718 ETSI.TPUDL=req[11+offset];
3719 ETSI.TPVP=0; //no support for now
3720 ETSI.TPPID=0; //no support for now
3721 for(i=31+offset;i<length;i++)
3722 ETSI.MessageText[i-31-offset]=req[i];
3725 ETSI.TPDCS=req[10+offset];
3726 ETSI.TPUDL=req[11+offset];
3727 ETSI.TPPID=0; //no support for now
3728 for(i=31+offset;i<length;i++)
3729 ETSI.MessageText[i-31-offset]=req[i];
3731 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3733 case SMS_Status_Report:
3735 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3736 ETSI.TPStatus=req[14];
3738 ETSI.SMSCDateTime[i]=req[i+34];
3744 GSM_DecodeETSISMS(SMS, &ETSI);
3751 void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3755 switch (MessageBuffer[3]) {
3759 switch (MessageBuffer[7]) {
3762 CurrentSMSMessage->Type = GST_SMS;
3763 CurrentSMSMessage->folder=GST_INBOX;
3768 CurrentSMSMessage->Type = GST_DR;
3769 CurrentSMSMessage->folder=GST_INBOX;
3774 CurrentSMSMessage->Type = GST_SMS;
3775 CurrentSMSMessage->folder=GST_OUTBOX;
3780 CurrentSMSMessage->Type = GST_UN;
3786 /* Field Short Message Status - MessageBuffer[4] seems not to be
3787 compliant with GSM 07.05 spec.
3788 Meaning Nokia protocol GMS spec
3789 ----------------------------------------------------
3790 MO Sent 0x05 0x07 or 0x01
3791 MO Not sent 0x07 0x06 or 0x00
3792 MT Read 0x01 0x05 or 0x01
3793 MT Not read 0x03 0x04 or 0x00
3794 ----------------------------------------------------
3795 See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
3799 if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
3800 else CurrentSMSMessage->Status = GSS_SENTREAD;
3803 fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
3805 if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
3806 fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
3808 fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
3811 if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
3812 if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
3814 if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
3815 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
3816 else fprintf(stdout, _(" Not sent\n"));
3818 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
3819 else fprintf(stdout, _(" Not read\n"));
3823 CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
3825 CurrentSMSMessage->MemoryType = MessageBuffer[5];
3826 CurrentSMSMessage->MessageNumber = MessageBuffer[6];
3828 /* Signal no error to calling code. */
3829 CurrentSMSMessageError = GE_NONE;
3832 fprintf(stdout, "\n");
3839 /* We have requested invalid or empty location. */
3842 fprintf(stdout, _("Message: SMS reading failed\n"));
3844 switch (MessageBuffer[4]) {
3846 fprintf(stdout, _(" Invalid location!\n"));break;
3848 fprintf(stdout, _(" Empty SMS location.\n"));break;
3850 fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
3852 fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
3856 switch (MessageBuffer[4]) {
3857 case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3858 case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
3859 case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
3860 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3868 GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
3871 unsigned char req[] = { N6110_FRAME_HEADER,
3874 0x00, /* Location */
3879 /* State machine code writes data to these variables when it comes in. */
3881 CurrentSMSMessage = message;
3882 CurrentSMSMessageError = GE_BUSY;
3884 req[5] = message->Location;
3887 Protocol->SendMessage(8, 0x02, req);
3889 /* Wait for timeout or other error. */
3890 while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
3893 return (GE_TIMEOUT);
3898 return (CurrentSMSMessageError);
3901 void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3904 fprintf(stdout, _("Message: SMS deleted successfully.\n"));
3907 CurrentSMSMessageError = GE_NONE;
3910 GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
3912 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
3914 req[5] = message->Location;
3916 return NULL_SendMessageSequence
3917 (50, &CurrentSMSMessageError, 6, 0x14, req);
3920 /* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
3921 GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
3923 GSM_ETSISMSMessage ETSI;
3926 GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
3929 for (i=0;i<36;i++) req[i]=0;
3931 req[12]=ETSI.firstbyte;
3933 for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
3934 req[i]=ETSI.SMSCNumber[i];
3939 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3940 req[i+12+offset]=ETSI.Number[i];
3941 req[10+offset]=ETSI.TPDCS;
3942 req[11+offset]=ETSI.TPUDL;
3943 req[24+offset]=ETSI.TPVP;
3945 // fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
3946 // fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
3947 // fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
3949 // req[]=ETSI.TPPID;
3950 for(i=0;i<*length;i++)
3951 req[i+31+offset]=ETSI.MessageText[i];
3956 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3957 req[i+12+offset]=ETSI.Number[i];
3958 req[10+offset]=ETSI.TPDCS;
3959 req[11+offset]=ETSI.TPUDL;
3960 // req[]=ETSI.TPPID;
3961 for(i=0;i<*length;i++)
3962 req[i+31+offset]=ETSI.MessageText[i];
3964 req[24+offset+i]=ETSI.DeliveryDateTime[i];
3970 *length=*length+offset;
3975 void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3977 switch (MessageBuffer[3]) {
3979 /* SMS message correctly sent to the network */
3982 fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
3984 CurrentSMSMessageError = GE_SMSSENDOK;
3987 /* SMS message send to the network failed */
3991 fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
3993 switch (MessageBuffer[6]) {
3994 case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3995 case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
3996 case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3997 case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
3998 case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3999 case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4000 case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4001 case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4002 case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4005 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
4006 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4009 CurrentSMSMessageError = GE_SMSSENDFAILED;
4015 GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
4019 unsigned char req[256] = {
4021 0x01, 0x02, 0x00, /* SMS send request*/
4026 error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
4027 if (error != GE_NONE) return error;
4029 return NULL_SendMessageSequence
4030 (200, &CurrentSMSMessageError, 42+length, 0x02, req);
4033 void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4035 switch (MessageBuffer[3]) {
4040 fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
4043 CurrentSMSMessage->MessageNumber=MessageBuffer[5];
4045 CurrentSMSMessageError = GE_NONE;
4050 fprintf(stdout, _("SMS saving failed\n"));
4051 switch (MessageBuffer[4]) {
4052 case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
4053 case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
4054 default :fprintf(stdout, _(" Unknown error.\n"));break;
4058 switch (MessageBuffer[4]) {
4059 case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
4060 case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
4061 default :CurrentSMSMessageError = GE_UNKNOWN;break;
4066 /* GST_DR and GST_UN not supported ! */
4067 GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
4069 unsigned char req[256] = {
4070 N6110_FRAME_HEADER, 0x04, /* SMS save request*/
4071 0x00, /* SMS Status. Different for Inbox and Outbox */
4073 0x00, /* SMS Location */
4074 0x02, /* SMS Type */
4078 SMS_MessageType PDU;
4081 if (SMS->Location) req[6] = SMS->Location;
4083 if (SMS->folder==0) { /*Inbox*/
4084 req[4]=1; /* SMS Status */
4085 req[7] = 0x00; /* SMS Type */
4088 req[4]=5; /* SMS Status */
4089 req[7] = 0x02; /* SMS Type */
4093 if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
4095 error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
4096 if (error != GE_NONE) return error;
4098 CurrentSMSMessage = SMS;
4100 return NULL_SendMessageSequence
4101 (70, &CurrentSMSMessageError, 39+length, 0x14, req);
4104 void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4107 fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
4110 CurrentCBError = GE_NONE;
4113 /* Enable and disable Cell Broadcasting */
4114 GSM_Error N6110_EnableCellBroadcast(void)
4116 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4117 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
4120 fprintf (stdout,"Enabling CB\n");
4123 CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
4124 CurrentCBMessage->Channel = 0;
4125 CurrentCBMessage->New = false;
4126 strcpy (CurrentCBMessage->Message,"");
4128 return NULL_SendMessageSequence
4129 (10, &CurrentCBError, 10, 0x02, req);
4133 GSM_Error N6110_DisableCellBroadcast(void)
4135 /* Should work, but not tested fully */
4137 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
4140 return NULL_SendMessageSequence
4141 (10, &CurrentCBError, 10, 0x02, req);
4144 void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4147 unsigned char output[160];
4149 CurrentCBMessage->Channel = MessageBuffer[7];
4150 CurrentCBMessage->New = true;
4151 tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
4154 fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
4156 fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
4160 for (i=0; i<tmp;i++) {
4161 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
4164 fprintf(stdout, "\n");
4167 for (i=0; i<tmp; i++) {
4168 CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
4170 CurrentCBMessage->Message[i]=0;
4173 GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
4176 fprintf(stdout,"Reading CB\n");
4179 if (CurrentCBMessage != NULL)
4181 if (CurrentCBMessage->New == true)
4184 fprintf(stdout,"New CB received\n");
4186 Message->Channel = CurrentCBMessage->Channel;
4187 strcpy(Message->Message,CurrentCBMessage->Message);
4188 CurrentCBMessage->New = false;
4192 return (GE_NONEWCBRECEIVED);
4195 int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
4199 req[count++]=Bitmap.number;
4200 req[count++]=strlen(Bitmap.text);
4201 memcpy(req+count,Bitmap.text,req[count-1]);
4202 count+=req[count-1];
4203 req[count++]=Bitmap.ringtone;
4205 /* Setting for graphic:
4208 0x02 - View Graphics
4209 0x03 - Send Graphics
4211 You can even set it higher but Nokia phones (my
4212 6110 at least) will not show you the name of this
4213 item in menu ;-)) Nokia is really joking here. */
4214 if (Bitmap.enabled) req[count++]=0x01;
4215 else req[count++]=0x00;
4217 req[count++]=(Bitmap.size+4)>>8;
4218 req[count++]=(Bitmap.size+4)%0xff;
4219 req[count++]=0x00; /* Future extensions! */
4220 req[count++]=Bitmap.width;
4221 req[count++]=Bitmap.height;
4222 req[count++]=0x01; /* Just BW */
4223 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4225 return count+Bitmap.size;
4228 int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4232 EncodeNetworkCode(req+count, Bitmap.netcode);
4235 req[count++]=(Bitmap.size+4)>>8;
4236 req[count++]=(Bitmap.size+4)%0xff;
4237 req[count++]=0x00; /* Infofield */
4238 req[count++]=Bitmap.width;
4239 req[count++]=Bitmap.height;
4240 req[count++]=0x01; /* Just BW */
4241 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4243 return count+Bitmap.size;
4246 int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4251 req[count++]=Bitmap.height;
4252 req[count++]=Bitmap.width;
4253 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4255 return count+Bitmap.size;
4258 /* Set a bitmap or welcome-note */
4259 GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
4261 unsigned char req[600] = { N6110_FRAME_HEADER };
4267 /* Direct uploading variables */
4268 GSM_MultiSMSMessage SMS;
4269 unsigned char buffer[1000] = {0x0c,0x01};
4270 GSM_NetworkInfo NetworkInfo;
4274 /* Uploading with preview */
4275 if (Bitmap->number==255 &&
4276 (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
4277 GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
4278 memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
4280 memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
4282 buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
4284 Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
4286 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4287 return GE_NONE; //no answer from phone
4290 CurrentSetBitmapError = GE_BUSY;
4292 switch (Bitmap->type) {
4293 case GSM_WelcomeNoteText:
4294 case GSM_DealerNoteText:
4296 req[count++]=0x01; /* Only one block */
4298 if (Bitmap->type==GSM_WelcomeNoteText)
4299 req[count++]=0x02; /* Welcome text */
4301 req[count++]=0x03; /* Dealer Welcome Note */
4303 textlen=strlen(Bitmap->text);
4304 req[count++]=textlen;
4305 memcpy(req+count,Bitmap->text,textlen);
4309 Protocol->SendMessage(count, 0x05, req);
4313 case GSM_StartupLogo:
4314 if (Bitmap->number==0) {
4316 /* For 33xx we first set animated logo to default */
4317 if (GetModelFeature (FN_STARTUP)==F_STANIM) {
4318 error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4319 if (error!=GE_NONE) return error;
4323 req[count++]=0x01; /* Only one block */
4324 count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
4325 Protocol->SendMessage(count, 0x05, req);
4327 return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4331 case GSM_OperatorLogo:
4332 req[count++]=0x30; /* Store Op Logo */
4333 req[count++]=0x01; /* Location */
4334 count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
4335 Protocol->SendMessage(count, 0x05, req);
4338 case GSM_CallerLogo:
4340 count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
4341 Protocol->SendMessage(count, 0x03, req);
4344 case GSM_PictureImage:
4346 req[count++]=Bitmap->number;
4347 if (strcmp(Bitmap->Sender,"")) {
4348 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
4350 /* Convert number of semioctets to number of chars and add count */
4352 if (textlen % 2) textlen++;
4353 count+=textlen / 2 + 1;
4361 req[count++]=strlen(Bitmap->text);
4362 memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
4363 count+=strlen(Bitmap->text);
4365 req[count++]=Bitmap->width;
4366 req[count++]=Bitmap->height;
4368 memcpy(req+count,Bitmap->bitmap,Bitmap->size);
4369 Protocol->SendMessage(count+Bitmap->size, 0x47, req);
4372 case GSM_7110OperatorLogo:
4373 case GSM_7110StartupLogo:
4374 case GSM_6210StartupLogo:
4375 return GE_NOTSUPPORTED;
4381 /* Wait for timeout or other error. */
4382 while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
4385 return (GE_TIMEOUT);
4390 return CurrentSetBitmapError;
4393 /* Get a bitmap from the phone */
4394 GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
4396 unsigned char req[10] = { N6110_FRAME_HEADER };
4401 CurrentGetBitmap=Bitmap;
4402 CurrentGetBitmapError = GE_BUSY;
4404 switch (CurrentGetBitmap->type) {
4405 case GSM_StartupLogo:
4406 case GSM_WelcomeNoteText:
4407 case GSM_DealerNoteText:
4409 Protocol->SendMessage(count, 0x05, req);
4411 case GSM_OperatorLogo:
4413 req[count++]=0x01; /* Location 1 */
4414 Protocol->SendMessage(count, 0x05, req);
4416 case GSM_CallerLogo:
4418 req[count++]=Bitmap->number;
4419 Protocol->SendMessage(count, 0x03, req);
4421 case GSM_PictureImage:
4423 req[count++]=Bitmap->number;
4424 Protocol->SendMessage(count, 0x47, req);
4426 case GSM_7110OperatorLogo:
4427 case GSM_7110StartupLogo:
4428 case GSM_6210StartupLogo:
4430 return GE_NOTSUPPORTED;
4433 /* Wait for timeout or other error. */
4434 while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
4437 return (GE_TIMEOUT);
4442 CurrentGetBitmap=NULL;
4444 return CurrentGetBitmapError;
4447 void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4449 switch (MessageBuffer[3]) {
4451 /* Set ringtone OK */
4454 fprintf(stdout, _("Message: Ringtone set OK!\n"));
4456 CurrentRingtoneError=GE_NONE;
4459 /* Set ringtone error */
4462 fprintf(stdout, _("Message: Ringtone setting error !\n"));
4464 CurrentRingtoneError=GE_NOTSUPPORTED;
4469 GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
4472 char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
4473 {N6110_FRAME_HEADER,
4475 0x00, /* Location */
4478 int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
4480 /* Variables for preview uploading */
4481 unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
4482 unsigned char buffer2[20];
4483 GSM_NetworkInfo NetworkInfo;
4485 /* Setting ringtone with preview */
4486 if (ringtone->location==255) {
4489 EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
4490 memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
4491 *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
4492 Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
4493 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4495 return GE_NONE; //no answer from phone
4498 *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
4500 req[4]=ringtone->location-1;
4502 return NULL_SendMessageSequence
4503 (50, &CurrentRingtoneError, (size+7), 0x05, req);
4506 void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4510 switch (MessageBuffer[4]) {
4511 case 0x00: /* location supported. We have ringtone */
4513 /* Binary format used in N6150 */
4514 if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4516 fprintf(stdout,_("Message: ringtone \""));
4523 if (MessageBuffer[i]!=0)
4524 fprintf(stdout,_("%c"),MessageBuffer[i]);
4526 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4527 if (MessageBuffer[i]==0) break;
4532 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4535 /* Looking for end */
4538 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4541 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4545 if (i==MessageLength) break;
4549 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4550 CurrentGetBinRingtone->length=i-3;
4552 CurrentBinRingtoneError=GE_NONE;
4556 /* Binary format used in N3210 */
4557 if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4560 fprintf(stdout,_("Message: ringtone \""));
4567 if (MessageBuffer[i]!=0)
4568 fprintf(stdout,_("%c"),MessageBuffer[i]);
4570 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4571 if (MessageBuffer[i]==0) break;
4576 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4579 /* Here changes to get full compatibility with binary format used in N6150 */
4582 MessageBuffer[5]=0x0c;
4583 MessageBuffer[6]=0x01;
4584 MessageBuffer[7]=0x2c;
4586 /* Looking for end */
4589 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4592 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4596 if (i==MessageLength) break;
4600 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4602 CurrentGetBinRingtone->length=i-3;
4604 CurrentBinRingtoneError=GE_NONE;
4609 memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
4611 CurrentGetBinRingtone->length=MessageLength;
4614 fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
4616 CurrentBinRingtoneError=GE_UNKNOWNMODEL;
4622 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4625 CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
4629 GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
4631 unsigned char req[] = { 0x00,0x01,0x9e,
4636 CurrentGetBinRingtone=ringtone;
4638 error=N6110_EnableExtendedCommands(0x01);
4639 if (error!=GE_NONE) return error;
4641 req[3]=ringtone->location-1;
4643 return NULL_SendMessageSequence
4644 (50, &CurrentBinRingtoneError, 4, 0x40, req);
4647 void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4649 switch (MessageBuffer[4]) {
4650 case 0x00: /* location supported. We set ringtone */
4652 fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
4654 CurrentBinRingtoneError=GE_NONE;
4659 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4661 CurrentBinRingtoneError=GE_NOTSUPPORTED;
4666 GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
4668 unsigned char req[1000] = { 0x00,0x01,0xa0};
4672 GSM_BinRingtone ring;
4674 /* Must be sure, that can upload ringtone to this phone */
4675 ring.location=ringtone->location;
4676 error=N6110_GetBinRingTone(&ring);
4677 if (error!=GE_NONE) return error;
4679 error=N6110_EnableExtendedCommands(0x01);
4680 if (error!=GE_NONE) return error;
4682 memcpy(req+3,ringtone->frame,ringtone->length);
4684 req[3]=ringtone->location-1;
4686 return NULL_SendMessageSequence
4687 (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
4690 #endif /* UCLINUX */
4692 GSM_Error N6110_Reset(unsigned char type)
4694 return N6110_EnableExtendedCommands(type);
4697 void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4704 switch (MessageBuffer[3]) {
4706 /* Unknown message - it has been seen after the 0x07 message (call
4707 answered). Probably it has similar meaning. If you can solve
4708 this - just mail me. Pavel JanÃk ml.
4710 The message looks like this:
4718 Phone: [01 ][08 ][00 ] is the header of the frame
4720 [03 ] is the call message subtype
4722 [05 ] is the call sequence number
4726 [00 ][01 ][03 ][02 ][91][00] are unknown but has been
4727 seen in the Incoming call message (just after the
4728 caller's name from the phonebook). But never change
4729 between phone calls :-(
4732 /* This may mean sequence number of 'just made' call - CK */
4736 fprintf(stdout, _("Message: Call message, type 0x02:"));
4737 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4742 /* Possibly call OK */
4743 /* JD: I think that this means "call in progress" (incomming or outgoing) */
4747 fprintf(stdout, _("Message: Call message, type 0x03:"));
4748 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4749 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4752 CurrentCallSequenceNumber=MessageBuffer[4];
4754 CurrentIncomingCall[0]='D';
4755 #endif /* UCLINUX */
4756 if (CurrentCallPassup) CurrentCallPassup('D');
4760 /* Remote end has gone away before you answer the call. Probably your
4761 mother-in-law or banker (which is worse?) ... */
4765 fprintf(stdout, _("Message: Remote end hang up.\n"));
4766 fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
4768 switch (MessageBuffer[6]) {
4769 case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
4770 case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
4771 case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
4772 case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4773 case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
4774 case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4777 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
4778 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4782 CurrentIncomingCall[0] = ' ';
4783 #endif /* UCLINUX */
4784 if (CurrentCallPassup) CurrentCallPassup(' ');
4788 /* Incoming call alert */
4792 fprintf(stdout, _("Message: Incoming call alert:\n"));
4794 /* We can have more then one call ringing - we can distinguish between
4797 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4798 fprintf(stdout, _(" Number: "));
4800 count=MessageBuffer[6];
4802 for (tmp=0; tmp <count; tmp++)
4803 fprintf(stdout, "%c", MessageBuffer[7+tmp]);
4805 fprintf(stdout, "\n");
4807 fprintf(stdout, _(" Name: "));
4809 for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
4810 fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
4812 fprintf(stdout, "\n");
4815 count=MessageBuffer[6];
4818 CurrentIncomingCall[0] = 0;
4819 for (tmp=0; tmp <count; tmp++)
4820 sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
4821 #endif /* UCLINUX */
4825 /* Call answered. Probably your girlfriend...*/
4829 fprintf(stdout, _("Message: Call answered.\n"));
4830 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4835 /* Call ended. Girlfriend is girlfriend, but time is money :-) */
4839 fprintf(stdout, _("Message: Call ended by your phone.\n"));
4840 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4845 /* This message has been seen with the message of subtype 0x09
4846 after I hang the call.
4853 Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
4855 What is the meaning of 87? Can you spell some magic light into
4860 /* Probably means call over - CK */
4864 fprintf(stdout, _("Message: Call message, type 0x0a:"));
4865 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4866 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4870 CurrentIncomingCall[0] = ' ';
4871 #endif /* UCLINUX */
4872 if (CurrentCallPassup) CurrentCallPassup(' ');
4879 fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
4883 if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
4884 #endif /* UCLINUX */
4886 if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
4893 fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
4895 AppendLogText("Unknown msg\n",false);
4897 break; /* Visual C Don't like empty cases */
4903 static void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4907 switch (MessageBuffer[3]) {
4911 /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
4912 /* If you want see, if it works with your phone make something like that: */
4914 /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
4915 /* Protocol->SendMessage(4, 0x04, connect5); */
4917 /* Marcin-Wiacek@TopNet.PL */
4919 #if defined(WIN32) || defined(UCLINUX)
4920 sprintf(Current_IMEI, "%s", MessageBuffer+5);
4921 sprintf(Current_Model, "%s", MessageBuffer+21);
4922 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4924 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
4925 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
4926 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4930 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
4931 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
4932 fprintf(stdout, _(" Model: %s\n"), Current_Model);
4933 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
4934 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
4935 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
4940 /* Get group data */
4941 /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
4944 if (CurrentGetBitmap!=NULL) {
4945 if (CurrentGetBitmap->number==MessageBuffer[4]) {
4946 count=MessageBuffer[5];
4947 memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
4948 CurrentGetBitmap->text[count]=0;
4951 fprintf(stdout, _("Message: Caller group datas\n"));
4952 fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
4957 CurrentGetBitmap->ringtone=MessageBuffer[count++];
4959 fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
4960 if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
4961 fprintf(stdout,_("\n"));
4964 CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
4966 fprintf(stdout, _("Caller group logo "));
4967 if (CurrentGetBitmap->enabled)
4968 fprintf(stdout, _("enabled \n"));
4970 fprintf(stdout, _("disabled \n"));
4973 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4974 CurrentGetBitmap->size+=MessageBuffer[count++];
4976 fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
4980 CurrentGetBitmap->width=MessageBuffer[count++];
4981 CurrentGetBitmap->height=MessageBuffer[count++];
4983 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
4984 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4985 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
4986 CurrentGetBitmapError=GE_NONE;
4989 fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
4994 fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
4999 /* Get group data error */
5002 CurrentGetBitmapError=GE_UNKNOWN;
5004 fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
5008 /* Set group data OK */
5011 CurrentSetBitmapError=GE_NONE;
5013 fprintf(stdout, _("Message: Caller group data set correctly.\n"));
5017 /* Set group data error */
5020 CurrentSetBitmapError=GE_UNKNOWN;
5022 fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
5029 fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
5031 AppendLogText("Unknown msg\n",false);
5033 break; /* Visual C Don't like empty cases */
5037 static void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5039 int tmp, count, length;
5046 switch (MessageBuffer[3]) {
5052 fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
5055 if (CurrentGetBitmap!=NULL) {
5061 for (tmp=0;tmp<MessageBuffer[4];tmp++){
5062 switch (MessageBuffer[count++]) {
5064 if (CurrentGetBitmap->type==GSM_StartupLogo) {
5065 CurrentGetBitmap->height=MessageBuffer[count++];
5066 CurrentGetBitmap->width=MessageBuffer[count++];
5067 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5068 length=CurrentGetBitmap->size;
5069 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
5071 length=MessageBuffer[count++];
5072 length=length*MessageBuffer[count++]/8;
5076 fprintf(stdout, _("Startup logo supported - "));
5077 if (length!=0) { fprintf(stdout, _("currently set\n")); }
5078 else { fprintf(stdout, _("currently empty\n")); }
5080 if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
5083 length=MessageBuffer[count];
5084 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
5085 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5086 CurrentGetBitmap->text[length]=0;
5089 fprintf(stdout, _("Startup Text supported - "));
5092 fprintf(stdout, _("currently set to \""));
5093 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5094 fprintf(stdout, _("\"\n"));
5096 fprintf(stdout, _("currently empty\n"));
5100 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
5103 length=MessageBuffer[count];
5104 if (CurrentGetBitmap->type==GSM_DealerNoteText) {
5105 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5106 CurrentGetBitmap->text[length]=0;
5109 fprintf(stdout, _("Dealer Welcome supported - "));
5112 fprintf(stdout, _("currently set to \""));
5113 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5114 fprintf(stdout, _("\"\n"));
5116 fprintf(stdout, _("currently empty\n"));
5120 if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
5124 if (issupported) CurrentGetBitmapError=GE_NONE;
5125 else CurrentGetBitmapError=GE_NOTSUPPORTED;
5128 fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
5133 /* Set startup OK */
5136 CurrentSetBitmapError=GE_NONE;
5138 fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
5142 /* Set Operator Logo OK */
5146 fprintf(stdout, _("Message: Operator logo correctly set.\n"));
5149 CurrentSetBitmapError=GE_NONE;
5152 /* Set Operator Logo Error */
5156 fprintf(stdout, _("Message: Error setting operator logo!\n"));
5159 CurrentSetBitmapError=GE_UNKNOWN;
5163 /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
5166 if (CurrentGetBitmap!=NULL) {
5168 count=5; /* Location ignored. */
5170 DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
5174 fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
5175 CurrentGetBitmap->netcode,
5176 GSM_GetNetworkName(CurrentGetBitmap->netcode));
5179 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
5180 CurrentGetBitmap->size+=MessageBuffer[count++];
5182 CurrentGetBitmap->width=MessageBuffer[count++];
5183 CurrentGetBitmap->height=MessageBuffer[count++];
5185 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5186 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
5187 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
5188 CurrentGetBitmapError=GE_NONE;
5191 fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
5197 /* Get op logo error */
5201 fprintf(stdout, _("Message: Error getting operator logo!\n"));
5203 CurrentGetBitmapError=GE_UNKNOWN;
5209 fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
5211 AppendLogText("Unknown msg\n",false);
5217 static void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5220 unsigned char output[160];
5226 switch (MessageBuffer[3]) {
5230 /* MessageBuffer[3] = 0x05
5231 MessageBuffer[4] = 0x00
5232 MessageBuffer[5] = 0x0f
5233 MessageBuffer[6] = 0x03
5234 MessageBuffer[7] = length of packed message
5236 This is all I have seen - Gerry Anderson */
5238 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
5242 fprintf(stdout, _("Message from Network operator: "));
5244 for (i=0; i<tmp; i++)
5245 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
5247 fprintf(stdout, "\n");
5256 fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
5258 AppendLogText("Unknown msg\n",false);
5264 static void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5266 switch (MessageBuffer[3]) {
5270 fprintf(stdout, _("Message: SIM card login\n"));
5276 fprintf(stdout, _("Message: SIM card logout\n"));
5282 fprintf(stdout, _("Unknown message of type 0x09.\n"));
5284 AppendLogText("Unknown msg\n",false);
5289 static void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5291 switch(MessageBuffer[3]) {
5296 fprintf(stdout, _("Message: Calendar Alarm active\n"));
5297 fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
5302 fprintf(stdout, _("Unknown message of type 0x13.\n"));
5304 AppendLogText("Unknown msg\n",false);
5309 #endif /* UCLINUX */
5311 void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5315 switch(MessageBuffer[2]) {
5320 fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
5323 CurrentMagicError=GE_NONE;
5329 fprintf(stdout, _("Message: Answer for call commands.\n"));
5332 CurrentDialVoiceError=GE_NONE;
5338 fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
5341 CurrentMagicError=GE_NONE;
5347 fprintf(stdout, _("Message: ACK for simlock closing\n"));
5350 CurrentMagicError=GE_NONE;
5355 switch (MessageBuffer[5]) {
5358 fprintf(stdout,_("Message: EEPROM contest received\n"));
5361 if (MessageBuffer[8]!=0x00) {
5362 for (i=9;i<MessageLength;i++) {
5363 fprintf(stdout,_("%c"), MessageBuffer[i]);
5366 CurrentMagicError=GE_NONE;
5373 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5375 AppendLogText("Unknown msg\n",false);
5381 N6110_DisplayTestsInfo(MessageBuffer);
5383 #endif /* UCLINUX */
5388 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5390 AppendLogText("Unknown msg\n",false);
5391 break; /* Visual C Don't like empty cases */
5397 static void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5401 switch(MessageBuffer[3]) {
5407 if (MessageBuffer[5]!=0) {
5408 strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
5410 while (MessageBuffer[count]!=0) {
5416 strcpy(CurrentGetBitmap->Sender,"\0");
5421 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
5422 CurrentGetBitmap->text[MessageBuffer[count]]=0;
5424 if (MessageBuffer[count]!=0)
5425 count+=MessageBuffer[count];
5430 fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
5433 CurrentGetBitmap->width=MessageBuffer[count+1];
5434 CurrentGetBitmap->height=MessageBuffer[count+2];
5435 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5437 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
5439 CurrentGetBitmapError=GE_NONE;
5445 fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
5447 CurrentSetBitmapError=GE_NONE;
5448 CurrentGetBitmapError=GE_NONE;
5454 fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
5456 CurrentSetBitmapError=GE_UNKNOWN;
5462 fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
5464 CurrentGetBitmapError=GE_UNKNOWN;
5470 fprintf(stdout, _("Unknown message of type 0x47.\n"));
5472 AppendLogText("Unknown msg\n",false);
5473 break; /* Visual C Don't like empty cases */
5477 #endif /* UCLINUX */
5479 void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5482 sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
5483 AppendLog(buffer,strlen(buffer),false);
5486 fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
5490 CurrentLinkOK = true;
5493 static void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5496 fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
5501 /* This function is used for parsing the RLP frame into fields. */
5502 void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
5509 /* We do not need RLP frame parsing to be done when we do not have callback
5511 if (CurrentRLP_RXCallback == NULL)
5514 /* Anybody know the official meaning of the first two bytes?
5515 Nokia 6150 sends junk frames starting D9 01, and real frames starting
5516 D9 00. We'd drop the junk frames anyway because the FCS is bad, but
5517 it's tidier to do it here. We still need to call the callback function
5518 to give it a chance to handle timeouts and/or transmit a frame */
5519 if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
5522 /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
5523 specification, so Header consists of 16 bits (2 bytes). See section 4.1
5524 of the specification. */
5526 frame.Header[0] = MessageBuffer[2];
5527 frame.Header[1] = MessageBuffer[3];
5529 /* Next 200 bits (25 bytes) contain the Information. We store the
5530 information in the Data array. */
5532 for (count = 0; count < 25; count ++)
5533 frame.Data[count] = MessageBuffer[4 + count];
5535 /* The last 24 bits (3 bytes) contain FCS. */
5537 frame.FCS[0] = MessageBuffer[29];
5538 frame.FCS[1] = MessageBuffer[30];
5539 frame.FCS[2] = MessageBuffer[31];
5541 /* Here we pass the frame down in the input stream. */
5542 CurrentRLP_RXCallback(valid ? &frame : NULL);
5545 static void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5548 fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
5555 void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5557 GSM_SMSMessage NullSMS;
5559 switch (MessageBuffer[6]) {
5561 case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
5562 case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
5564 /* Is it possible ? */
5565 case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
5566 default: NullSMS.Type = GST_UN; break;
5570 if (NullSMS.Type == GST_DR)
5571 fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
5573 fprintf(stdout, _("Message: SMS Message Received\n"));
5576 GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
5579 fprintf(stdout, _("\n"));
5583 #endif /* UCLINUX */
5585 void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5589 /* Switch on the basis of the message type byte */
5590 switch (MessageType) {
5592 /* Call information */
5595 N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
5601 switch (MessageBuffer[3]) {
5603 case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5604 case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
5605 case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5606 case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5607 case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5609 case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5610 default :unknown=true;break;
5613 #endif /* UCLINUX */
5615 /* Phonebook handling */
5617 switch (MessageBuffer[3]) {
5619 case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
5621 case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
5623 case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
5625 case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5627 case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5629 default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
5630 #endif /* UCLINUX */
5636 switch (MessageBuffer[3]) {
5637 case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
5638 default :unknown=true;break;
5643 /* Startup Logo, Operator Logo and Profiles. */
5645 switch (MessageBuffer[3]) {
5646 case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5647 case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5648 case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5649 case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5650 case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5651 case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5652 default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
5656 /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
5659 switch (MessageBuffer[3]) {
5661 case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
5662 default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
5666 /* Security code requests */
5668 switch (MessageBuffer[3]) {
5669 case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
5670 case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5671 default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5678 N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
5683 switch (MessageBuffer[3]) {
5684 case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
5685 default :unknown=true;break;
5689 /* Simulating key pressing */
5691 switch (MessageBuffer[3]) {
5692 case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
5693 default :unknown=true;break;
5699 switch (MessageBuffer[3]) {
5700 case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5701 case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
5702 case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5703 default :unknown=true;break;
5707 /* Phone Clock and Alarm */
5709 switch (MessageBuffer[3]) {
5710 case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
5711 case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
5712 case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
5713 case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
5714 default :unknown=true;break;
5718 /* Calendar notes handling */
5720 switch (MessageBuffer[3]) {
5721 case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5722 case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5723 case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
5724 default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
5730 switch (MessageBuffer[3]) {
5732 case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5734 case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5735 case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5737 case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
5738 default :unknown=true;break;
5744 switch (MessageBuffer[3]) {
5746 case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
5748 case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5750 case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5753 case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
5754 default :unknown=true;break;
5757 #endif /* UCLINUX */
5759 /* Internal phone functions? */
5761 switch (MessageBuffer[2]) {
5762 case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
5764 case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
5765 #endif /* UCLINUX */
5766 case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
5768 case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5769 case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5770 case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5771 case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
5772 case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
5773 case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5774 case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5775 case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
5776 case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5777 case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5778 #endif /* UCLINUX */
5779 case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
5780 default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
5785 /* Picture Images */
5788 N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
5790 #endif /* UCLINUX */
5792 /* Mobile phone identification */
5795 N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
5798 /***** Acknowlegment of our frames. *****/
5799 case FBUS_FRTYPE_ACK:
5801 N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
5804 /***** Power on message. *****/
5807 N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
5812 N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
5815 /***** RLP frame received. *****/
5818 N6110_RX_HandleRLPMessage(MessageBuffer);
5821 /***** Power on message. *****/
5824 N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
5827 /***** Unknown message *****/
5828 /* If you think that you know the exact meaning of other messages - please
5833 fprintf(stdout, _("Message: Unknown message type.\n"));
5835 AppendLogText("Unknown msg type\n",false);
5844 fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
5846 AppendLogText("Unknown msg\n",false);