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 };
2584 unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2585 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2586 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
2588 unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2589 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2590 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
2591 unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
2592 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2593 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
2594 0x20,0x15,0x63,0x80 };
2599 CurrentCallPassup=callpassup;
2603 usleep(100); Protocol->SendMessage(sizeof(req3), 0x01, req3); /* Lace */
2606 size = sizeof(req_end0);
2609 Protocol->SendMessage(sizeof(req3), 0x01, req3);
2611 Protocol->SendMessage(sizeof(req4), 0x01, req4);
2614 size = sizeof(req_end1);
2616 case -1: /* Just used to set the call passup */
2621 size = sizeof(req_end0);
2625 req[4] = strlen(Number);
2627 for(i = 0; i < strlen(Number) ; i++)
2628 req[5+i] = Number[i];
2630 memcpy(req + 5 + strlen(Number), req_end, size);
2632 Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);
2636 if (type != 1) Protocol->SendMessage(26, 0x01, req2);
2644 GSM_Error N6110_GetIncomingCallNr(char *Number)
2647 if (*CurrentIncomingCall != ' ') {
2648 strcpy(Number, CurrentIncomingCall);
2655 #endif /* UCLINUX */
2657 GSM_Error N6110_CancelCall(void)
2659 // This frame & method works only on 61xx/51xx
2660 // unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
2661 // req[4]=CurrentCallSequenceNumber;
2662 // Protocol->SendMessage(6, 0x01, req);
2667 unsigned char req[]={0x00,0x01,0x7c,0x03};
2670 error=N6110_EnableExtendedCommands(0x01);
2671 if (error!=GE_NONE) return error;
2673 return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
2678 void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2680 switch(MessageBuffer[3]) {
2684 fprintf(stdout, _("Message: Security code accepted.\n"));
2686 CurrentSecurityCodeError = GE_NONE;
2691 fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
2693 CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
2697 GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
2700 unsigned char req[15] = { N6110_FRAME_HEADER,
2701 0x0a, /* Enter code request. */
2702 0x00 /* Type of the entered code. */
2706 req[4]=SecurityCode.Type;
2708 for (i=0; i<strlen(SecurityCode.Code);i++)
2709 req[5+i]=SecurityCode.Code[i];
2711 req[5+strlen(SecurityCode.Code)]=0x00;
2712 req[6+strlen(SecurityCode.Code)]=0x00;
2714 return NULL_SendMessageSequence
2715 (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
2718 void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2720 *CurrentSecurityCodeStatus = MessageBuffer[4];
2723 fprintf(stdout, _("Message: Security Code status received: "));
2725 switch(*CurrentSecurityCodeStatus) {
2727 case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;
2728 case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;
2729 case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;
2730 case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;
2731 case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;
2732 case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;
2733 default : fprintf(stdout, _("Unknown!\n"));
2738 CurrentSecurityCodeError = GE_NONE;
2741 GSM_Error N6110_GetSecurityCodeStatus(int *Status)
2744 unsigned char req[4] = { N6110_FRAME_HEADER,
2748 CurrentSecurityCodeStatus=Status;
2750 return NULL_SendMessageSequence
2751 (20, &CurrentSecurityCodeError, 4, 0x08, req);
2754 void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2759 fprintf(stdout, _("Message: Security code received: "));
2760 switch (MessageBuffer[3]) {
2761 case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;
2762 case GSCT_Pin: fprintf(stdout, _("PIN"));break;
2763 case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;
2764 case GSCT_Puk: fprintf(stdout, _("PUK"));break;
2765 case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;
2766 default: fprintf(stdout, _("unknown !"));break;
2768 if (MessageBuffer[4]==1) {
2769 fprintf(stdout, _(" allowed, value \""));
2770 if (MessageBuffer[3]==GSCT_SecurityCode) {
2771 for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2773 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2774 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2775 for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2777 fprintf(stdout, _("\""));
2779 fprintf(stdout, _(" not allowed"));
2781 fprintf(stdout, _("\n"));
2784 if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
2785 && MessageBuffer[4]==1) { /* It's allowed */
2786 if (MessageBuffer[3]==GSCT_SecurityCode) {
2787 for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2788 CurrentSecurityCode->Code[5]=0;
2790 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2791 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2792 for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2793 CurrentSecurityCode->Code[4]=0;
2795 CurrentSecurityCodeError=GE_NONE;
2797 CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
2800 GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
2803 unsigned char req[4] = { 0x00,
2804 0x01,0x6e, /* Get code request. */
2805 0x00 }; /* Type of the requested code. */
2809 error=N6110_EnableExtendedCommands(0x01);
2810 if (error!=GE_NONE) return error;
2812 req[3]=SecurityCode->Type;
2814 CurrentSecurityCode=SecurityCode;
2816 return NULL_SendMessageSequence
2817 (20, &CurrentSecurityCodeError, 4, 0x40, req);
2820 void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2823 fprintf(stdout, _("Message: answer for PlayTone frame\n"));
2826 CurrentPlayToneError=GE_NONE;
2829 GSM_Error N6110_PlayTone(int Herz, u8 Volume)
2831 unsigned char req[6] = { 0x00,0x01,0x8f,
2834 0x00 }; /* HerzHi */
2838 /* PlayTone wasn't used earlier */
2839 if (CurrentPlayToneError==GE_UNKNOWN) {
2840 if (CurrentConnectionType!=GCT_MBUS)
2841 CurrentDisableKeepAlive=true;
2843 error=N6110_EnableExtendedCommands(0x01);
2844 if (error!=GE_NONE) return error;
2847 /* For Herz==255*255 we have silent */
2848 if (Herz!=255*255) {
2861 /* For Herz==255*255 we have silent and additionaly
2862 we wait for phone answer - it's important for MBUS */
2863 if (Herz==255*255) {
2864 error=NULL_SendMessageSequence
2865 (20, &CurrentPlayToneError, 6, 0x40, req);
2867 CurrentPlayToneError=GE_UNKNOWN;
2868 CurrentDisableKeepAlive=false;
2870 if (error!=GE_NONE) return error;
2872 Protocol->SendMessage(6,0x40,req);
2875 error=NULL_SendMessageSequence
2876 (20, &CurrentPlayToneError, 6, 0x40, req);
2878 /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
2879 if (Herz==255*255) {
2880 CurrentPlayToneError=GE_UNKNOWN;
2881 CurrentDisableKeepAlive=false;
2884 if (error!=GE_NONE) return error;
2891 void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2893 if (MessageBuffer[4]==0x01) {
2894 DecodeDateTime(MessageBuffer+8, CurrentDateTime);
2897 fprintf(stdout, _("Message: Date and time\n"));
2898 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
2899 fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
2902 CurrentDateTime->IsSet=true;
2906 fprintf(stdout, _("Message: Date and time not set in phone\n"));
2909 CurrentDateTime->IsSet=false;
2912 CurrentDateTimeError=GE_NONE;
2915 GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
2917 return N6110_PrivGetDateTime(date_time,0x11);
2920 GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
2922 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
2924 CurrentDateTime=date_time;
2926 return NULL_SendMessageSequence
2927 (50, &CurrentDateTimeError, 4, msgtype, req);
2930 void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2933 fprintf(stdout, _("Message: Alarm\n"));
2934 fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
2935 fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
2938 CurrentAlarm->Hour=MessageBuffer[9];
2939 CurrentAlarm->Minute=MessageBuffer[10];
2940 CurrentAlarm->Second=0;
2942 CurrentAlarm->IsSet=(MessageBuffer[8]==2);
2944 CurrentAlarmError=GE_NONE;
2947 GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
2949 return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
2952 GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
2954 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
2956 CurrentAlarm=date_time;
2958 return NULL_SendMessageSequence
2959 (50, &CurrentAlarmError, 4, msgtype, req);
2962 void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2964 switch (MessageBuffer[3]) {
2968 CurrentMessageCenter->No=MessageBuffer[4];
2969 CurrentMessageCenter->Format=MessageBuffer[6];
2970 CurrentMessageCenter->Validity=MessageBuffer[8];
2971 sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
2973 sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
2975 sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
2978 fprintf(stdout, _("Message: SMS Center received:\n"));
2979 fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
2980 fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
2981 fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
2983 fprintf(stdout, _(" SMS Center message format is "));
2985 switch (CurrentMessageCenter->Format) {
2987 case GSMF_Text : fprintf(stdout, _("Text")); break;
2988 case GSMF_Paging: fprintf(stdout, _("Paging")); break;
2989 case GSMF_Fax : fprintf(stdout, _("Fax")); break;
2990 case GSMF_Email : fprintf(stdout, _("Email")); break;
2991 default : fprintf(stdout, _("Unknown"));
2994 fprintf(stdout, "\n");
2996 fprintf(stdout, _(" SMS Center message validity is "));
2998 switch (CurrentMessageCenter->Validity) {
3000 case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;
3001 case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;
3002 case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;
3003 case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;
3004 case GSMV_1_Week : fprintf(stdout, _("1 week")); break;
3005 case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;
3006 default : fprintf(stdout, _("Unknown"));
3009 fprintf(stdout, "\n");
3013 CurrentMessageCenterError=GE_NONE;
3019 /* Number of entries depends on SIM card */
3022 fprintf(stdout, _("Message: SMS Center error received:\n"));
3023 fprintf(stdout, _(" The request for SMS Center failed.\n"));
3026 /* FIXME: appropriate error. */
3027 CurrentMessageCenterError=GE_INTERNALERROR;
3034 /* This function sends to the mobile phone a request for the SMS Center */
3035 GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
3037 unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
3038 0x00 /* SMS Center Number. */
3041 req[5]=MessageCenter->No;
3043 CurrentMessageCenter=MessageCenter;
3045 return NULL_SendMessageSequence
3046 (50, &CurrentMessageCenterError, 6, 0x02, req);
3049 void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3052 fprintf(stdout, _("Message: SMS Center correctly set.\n"));
3054 CurrentMessageCenterError=GE_NONE;
3057 /* This function set the SMS Center profile on the phone. */
3058 GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
3060 unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
3061 0x00, /* SMS Center Number. */
3062 0x00, /* Unknown. */
3063 0x00, /* SMS Message Format. */
3064 0x00, /* Unknown. */
3065 0x00, /* Validity. */
3066 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
3067 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
3068 /* Message Center Name. */
3071 req[5]=MessageCenter->No;
3072 req[7]=MessageCenter->Format;
3073 req[9]=MessageCenter->Validity;
3075 req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
3077 req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
3079 sprintf(req+34, "%s", MessageCenter->Name);
3081 CurrentMessageCenter=MessageCenter;
3083 return NULL_SendMessageSequence
3084 (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
3087 void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3089 switch (MessageBuffer[3]) {
3094 fprintf(stdout, _("Message: SMS Status Received\n"));
3095 fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
3096 fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
3099 CurrentSMSStatus->UnRead = MessageBuffer[11];
3100 CurrentSMSStatus->Number = MessageBuffer[10];
3102 CurrentSMSStatusError = GE_NONE;
3108 fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
3111 CurrentSMSStatusError = GE_INTERNALERROR;
3117 GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
3119 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
3121 CurrentSMSStatus = Status;
3123 return NULL_SendMessageSequence
3124 (10, &CurrentSMSStatusError, 5, 0x14, req);
3127 GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
3131 strcpy(folders->Folder[0].Name,"Inbox");
3132 strcpy(folders->Folder[1].Name,"Outbox");
3137 #endif /* UCLINUX */
3139 GSM_Error N6110_GetIMEI(char *imei)
3141 if (strlen(Current_IMEI)>0) {
3142 strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
3146 return (GE_TRYAGAIN);
3149 GSM_Error N6110_GetRevision(char *revision)
3152 if (strlen(Current_Revision)>0) {
3153 strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
3157 return (GE_TRYAGAIN);
3160 static GSM_Error N6110_GetModel(char *model)
3162 if (strlen(Current_Model)>0) {
3163 strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
3167 return (GE_TRYAGAIN);
3172 void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3174 switch (MessageBuffer[4]) {
3178 fprintf(stdout, _("Message: Date and time set correctly\n"));
3180 CurrentSetDateTimeError=GE_NONE;
3185 fprintf(stdout, _("Message: Date and time setting error\n"));
3187 CurrentSetDateTimeError=GE_INVALIDDATETIME;
3192 /* Needs SIM card with PIN in phone */
3193 GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
3195 return N6110_PrivSetDateTime(date_time,0x11);
3198 /* Needs SIM card with PIN in phone */
3199 GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
3202 unsigned char req[] = { N6110_FRAME_HEADER,
3203 0x60, /* set-time subtype */
3204 0x01, 0x01, 0x07, /* unknown */
3205 0x00, 0x00, /* Year (0x07cf = 1999) */
3206 0x00, 0x00, /* Month Day */
3207 0x00, 0x00, /* Hours Minutes */
3208 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3211 EncodeDateTime(req+7, date_time);
3213 return NULL_SendMessageSequence
3214 (20, &CurrentSetDateTimeError, 14, msgtype, req);
3217 void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3219 switch (MessageBuffer[4]) {
3223 fprintf(stdout, _("Message: Alarm set correctly\n"));
3225 CurrentSetAlarmError=GE_NONE;
3230 fprintf(stdout, _("Message: Alarm setting error\n"));
3232 CurrentSetAlarmError=GE_INVALIDDATETIME;
3237 /* FIXME: we should also allow to set the alarm off :-) */
3238 GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
3240 return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
3243 /* FIXME: we should also allow to set the alarm off :-) */
3244 GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
3247 unsigned char req[] = { N6110_FRAME_HEADER,
3248 0x6b, /* set-alarm subtype */
3249 0x01, 0x20, 0x03, /* unknown */
3250 0x02, /* should be alarm on/off, but it don't works */
3251 0x00, 0x00, /* Hours Minutes */
3252 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3255 req[8] = date_time->Hour;
3256 req[9] = date_time->Minute;
3258 return NULL_SendMessageSequence
3259 (50, &CurrentSetAlarmError, 11, msgtype, req);
3262 #endif /* UCLINUX */
3264 static void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3266 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
3271 switch (MessageBuffer[3]) {
3275 CurrentPhonebookEntry->Empty = true;
3277 count=MessageBuffer[5];
3280 fprintf(stdout, _("Message: Phonebook entry received:\n"));
3281 fprintf(stdout, _(" Name: "));
3283 for (tmp=0; tmp <count; tmp++)
3285 if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
3286 if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
3287 fprintf(stdout, "%c", MessageBuffer[6+tmp]);
3290 fprintf(stdout, "\n");
3293 while (N6110_GetModel(model) != GE_NONE)
3296 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3298 DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
3299 CurrentPhonebookEntry->Name[count/2] = 0x00;
3301 fprintf(stderr,"FATAL ERROR: DecodeUnicode disabled!\n");
3303 #endif /* UCLINUX */
3305 memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);
3306 CurrentPhonebookEntry->Name[count] = 0x00;
3309 CurrentPhonebookEntry->Empty = false;
3311 for (tmp=0; tmp <count; tmp++)
3313 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3314 /* We check only 1'st, 3'rd, ... char */
3315 if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking
3316 if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents
3318 if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking
3319 if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents
3324 count=MessageBuffer[6+count];
3327 fprintf(stdout, _(" Number: "));
3329 for (tmp=0; tmp <count; tmp++)
3330 fprintf(stdout, "%c", MessageBuffer[i+tmp]);
3332 fprintf(stdout, "\n");
3335 memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);
3336 CurrentPhonebookEntry->Number[count] = 0x00;
3337 CurrentPhonebookEntry->Group = MessageBuffer[i+count];
3339 /* Phone doesn't have entended phonebook */
3340 CurrentPhonebookEntry->SubEntriesCount = 0;
3342 /* But for these memories data is saved and we can save it using 7110/6210 style */
3343 if (CurrentPhonebookEntry->MemoryType==GMT_DC ||
3344 CurrentPhonebookEntry->MemoryType==GMT_RC ||
3345 CurrentPhonebookEntry->MemoryType==GMT_MC) {
3346 CurrentPhonebookEntry->SubEntriesCount = 1;
3347 CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;
3348 CurrentPhonebookEntry->SubEntries[0].NumberType=0;
3349 CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;
3350 DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);
3353 fprintf(stdout, _(" Date: "));
3354 fprintf(stdout, "%02u.%02u.%04u\n",
3355 CurrentPhonebookEntry->SubEntries[0].data.Date.Day,
3356 CurrentPhonebookEntry->SubEntries[0].data.Date.Month,
3357 CurrentPhonebookEntry->SubEntries[0].data.Date.Year);
3358 fprintf(stdout, _(" Time: "));
3359 fprintf(stdout, "%02u:%02u:%02u\n",
3360 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,
3361 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,
3362 CurrentPhonebookEntry->SubEntries[0].data.Date.Second);
3365 /* These values are set, when date and time unavailable in phone.
3366 Values from 3310 - in other can be different */
3367 if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&
3368 CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&
3369 CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&
3370 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&
3371 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&
3372 CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)
3373 CurrentPhonebookEntry->SubEntriesCount = 0;
3376 /* Signal no error to calling code. */
3377 CurrentPhonebookError = GE_NONE;
3384 fprintf(stdout, _("Message: Phonebook read entry error received:\n"));
3387 switch (MessageBuffer[4]) {
3391 fprintf(stdout, _(" Invalid memory type!\n"));
3393 CurrentPhonebookError = GE_INVALIDMEMORYTYPE;
3398 fprintf(stdout, _(" Unknown error!\n"));
3400 CurrentPhonebookError = GE_INTERNALERROR;
3408 /* Routine to get specifed phone book location. Designed to be called by
3409 application. Will block until location is retrieved or a timeout/error
3411 GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)
3413 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
3415 CurrentPhonebookEntry = entry;
3417 req[4] = N6110_GetMemoryType(entry->MemoryType);
3418 req[5] = entry->Location;
3420 return NULL_SendMessageSequence
3421 (50, &CurrentPhonebookError, 7, 0x03, req);
3424 static void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3426 switch (MessageBuffer[3]) {
3431 fprintf(stdout, _("Message: Phonebook written correctly.\n"));
3433 CurrentPhonebookError = GE_NONE;
3438 switch (MessageBuffer[4]) {
3439 /* FIXME: other errors? When I send the phonebook with index of 350 it
3440 still report error 0x7d :-( */
3443 fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));
3445 CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;
3450 fprintf(stdout, _(" Unknown error!\n"));
3452 CurrentPhonebookError = GE_INTERNALERROR;
3457 /* Routine to write phonebook location in phone. Designed to be called by
3458 application code. Will block until location is written or timeout
3460 GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)
3462 unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };
3465 req[4] = N6110_GetMemoryType(entry->MemoryType);
3466 req[5] = entry->Location;
3470 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {
3473 req[6] = strlen(entry->Name)*2;
3475 EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
3477 for (i=0; i<strlen(entry->Name); i++)
3479 /* here we encode "special" chars */
3480 if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
3481 if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
3484 current+=strlen(entry->Name)*2;
3488 fprintf(stderr,"FATAL ERROR: EncodeUnicode disabled!\n");
3491 #endif /* UCLINUX */
3494 req[6] = strlen(entry->Name);
3496 for (i=0; i<strlen(entry->Name); i++)
3498 req[current+i] = entry->Name[i];
3500 /* here we encode "special" chars */
3501 if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
3502 if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
3505 current+=strlen(entry->Name);
3508 req[current++]=strlen(entry->Number);
3510 for (i=0; i<strlen(entry->Number); i++)
3511 req[current+i] = entry->Number[i];
3513 current+=strlen(entry->Number);
3515 /* Jano: This allow to save 14 characters name into SIM memory, when
3516 No Group is selected. */
3517 if (entry->Group == 5)
3518 req[current++]=0xff;
3520 req[current++]=entry->Group;
3522 return NULL_SendMessageSequence
3523 (50, &CurrentPhonebookError, current, 0x03, req);
3528 void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3530 switch(MessageBuffer[3]) {
3534 fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
3536 CurrentNetmonitorError=GE_NONE;
3541 fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
3542 fprintf(stdout, "%s\n", MessageBuffer+4);
3545 strcpy(CurrentNetmonitor, MessageBuffer+4);
3547 CurrentNetmonitorError=GE_NONE;
3551 GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
3553 unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
3557 error=N6110_EnableExtendedCommands(0x01);
3558 if (error!=GE_NONE) return error;
3560 CurrentNetmonitor=Screen;
3564 return NULL_SendMessageSequence
3565 (20, &CurrentNetmonitorError, 4, 0x40, req);
3568 /* Doesn't work in N3210. */
3569 /* In other allow to access phone menu without SIM card (just send any sequence) */
3570 GSM_Error N6110_SendDTMF(char *String)
3572 unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
3573 0x00 /* Length of DTMF string. */
3576 u8 length=strlen(String);
3578 if (length>59) length=59;
3582 memcpy(req+5,String,length);
3584 return NULL_SendMessageSequence
3585 (20, &CurrentSendDTMFError, 5+length, 0x01, req);
3588 #endif /* UCLINUX */
3590 static void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3592 switch (MessageBuffer[3]) {
3596 switch (MessageBuffer[4]) {
3597 case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
3598 default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
3601 CurrentSpeedDialEntry->Location = MessageBuffer[5];
3604 fprintf(stdout, _("Message: Speed dial entry received:\n"));
3605 fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
3606 fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
3607 fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
3610 CurrentSpeedDialError=GE_NONE;
3616 fprintf(stdout, _("Message: Speed dial entry error\n"));
3618 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3624 GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
3627 unsigned char req[] = { N6110_FRAME_HEADER,
3629 0x00 /* The number of speed dial. */
3632 CurrentSpeedDialEntry = entry;
3634 req[4] = entry->Number;
3636 return NULL_SendMessageSequence
3637 (20, &CurrentSpeedDialError, 5, 0x03, req);
3640 static void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3642 switch (MessageBuffer[3]) {
3647 fprintf(stdout, _("Message: Speed dial entry set.\n"));
3649 CurrentSpeedDialError=GE_NONE;
3655 fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
3657 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3663 GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
3666 unsigned char req[] = { N6110_FRAME_HEADER,
3669 0x00, /* Memory Type */
3673 req[4] = entry->Number;
3675 switch (entry->MemoryType) {
3676 case GMT_ME: req[5] = 0x02;
3677 default : req[5] = 0x03;
3680 req[6] = entry->Location;
3682 return NULL_SendMessageSequence
3683 (20, &CurrentSpeedDialError, 7, 0x03, req);
3688 /* This function finds parts of SMS in frame used in new Nokia phones
3689 in internal protocols (they're coded according to GSM 03.40), copies them
3690 to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
3691 GSM_ETSISMSMessage to GSM_SMSMessage structure */
3692 GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
3694 SMS_MessageType PDU=SMS_Deliver;
3695 GSM_ETSISMSMessage ETSI;
3698 ETSI.firstbyte=req[12];
3700 /* See GSM 03.40 section 9.2.3.1 */
3701 if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
3702 if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
3705 case SMS_Submit : offset=5;break;
3706 case SMS_Deliver : offset=4;break;
3707 case SMS_Status_Report: offset=3;break;
3711 for (i=0;i<req[0]+1;i++)
3712 ETSI.SMSCNumber[i]=req[i];
3714 for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
3715 ETSI.Number[i]=req[i+12+offset];
3719 ETSI.TPDCS=req[10+offset];
3720 ETSI.TPUDL=req[11+offset];
3721 ETSI.TPVP=0; //no support for now
3722 ETSI.TPPID=0; //no support for now
3723 for(i=31+offset;i<length;i++)
3724 ETSI.MessageText[i-31-offset]=req[i];
3727 ETSI.TPDCS=req[10+offset];
3728 ETSI.TPUDL=req[11+offset];
3729 ETSI.TPPID=0; //no support for now
3730 for(i=31+offset;i<length;i++)
3731 ETSI.MessageText[i-31-offset]=req[i];
3733 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3735 case SMS_Status_Report:
3737 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3738 ETSI.TPStatus=req[14];
3740 ETSI.SMSCDateTime[i]=req[i+34];
3746 GSM_DecodeETSISMS(SMS, &ETSI);
3753 void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3757 switch (MessageBuffer[3]) {
3761 switch (MessageBuffer[7]) {
3764 CurrentSMSMessage->Type = GST_SMS;
3765 CurrentSMSMessage->folder=GST_INBOX;
3770 CurrentSMSMessage->Type = GST_DR;
3771 CurrentSMSMessage->folder=GST_INBOX;
3776 CurrentSMSMessage->Type = GST_SMS;
3777 CurrentSMSMessage->folder=GST_OUTBOX;
3782 CurrentSMSMessage->Type = GST_UN;
3788 /* Field Short Message Status - MessageBuffer[4] seems not to be
3789 compliant with GSM 07.05 spec.
3790 Meaning Nokia protocol GMS spec
3791 ----------------------------------------------------
3792 MO Sent 0x05 0x07 or 0x01
3793 MO Not sent 0x07 0x06 or 0x00
3794 MT Read 0x01 0x05 or 0x01
3795 MT Not read 0x03 0x04 or 0x00
3796 ----------------------------------------------------
3797 See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
3801 if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
3802 else CurrentSMSMessage->Status = GSS_SENTREAD;
3805 fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
3807 if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
3808 fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
3810 fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
3813 if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
3814 if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
3816 if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
3817 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
3818 else fprintf(stdout, _(" Not sent\n"));
3820 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
3821 else fprintf(stdout, _(" Not read\n"));
3825 CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
3827 CurrentSMSMessage->MemoryType = MessageBuffer[5];
3828 CurrentSMSMessage->MessageNumber = MessageBuffer[6];
3830 /* Signal no error to calling code. */
3831 CurrentSMSMessageError = GE_NONE;
3834 fprintf(stdout, "\n");
3841 /* We have requested invalid or empty location. */
3844 fprintf(stdout, _("Message: SMS reading failed\n"));
3846 switch (MessageBuffer[4]) {
3848 fprintf(stdout, _(" Invalid location!\n"));break;
3850 fprintf(stdout, _(" Empty SMS location.\n"));break;
3852 fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
3854 fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
3858 switch (MessageBuffer[4]) {
3859 case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3860 case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
3861 case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
3862 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3870 GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
3873 unsigned char req[] = { N6110_FRAME_HEADER,
3876 0x00, /* Location */
3881 /* State machine code writes data to these variables when it comes in. */
3883 CurrentSMSMessage = message;
3884 CurrentSMSMessageError = GE_BUSY;
3886 req[5] = message->Location;
3889 Protocol->SendMessage(8, 0x02, req);
3891 /* Wait for timeout or other error. */
3892 while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
3895 return (GE_TIMEOUT);
3900 return (CurrentSMSMessageError);
3903 void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3906 fprintf(stdout, _("Message: SMS deleted successfully.\n"));
3909 CurrentSMSMessageError = GE_NONE;
3912 GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
3914 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
3916 req[5] = message->Location;
3918 return NULL_SendMessageSequence
3919 (50, &CurrentSMSMessageError, 6, 0x14, req);
3922 /* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
3923 GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
3925 GSM_ETSISMSMessage ETSI;
3928 GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
3931 for (i=0;i<36;i++) req[i]=0;
3933 req[12]=ETSI.firstbyte;
3935 for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
3936 req[i]=ETSI.SMSCNumber[i];
3941 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3942 req[i+12+offset]=ETSI.Number[i];
3943 req[10+offset]=ETSI.TPDCS;
3944 req[11+offset]=ETSI.TPUDL;
3945 req[24+offset]=ETSI.TPVP;
3947 // fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
3948 // fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
3949 // fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
3951 // req[]=ETSI.TPPID;
3952 for(i=0;i<*length;i++)
3953 req[i+31+offset]=ETSI.MessageText[i];
3958 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3959 req[i+12+offset]=ETSI.Number[i];
3960 req[10+offset]=ETSI.TPDCS;
3961 req[11+offset]=ETSI.TPUDL;
3962 // req[]=ETSI.TPPID;
3963 for(i=0;i<*length;i++)
3964 req[i+31+offset]=ETSI.MessageText[i];
3966 req[24+offset+i]=ETSI.DeliveryDateTime[i];
3972 *length=*length+offset;
3977 void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3979 switch (MessageBuffer[3]) {
3981 /* SMS message correctly sent to the network */
3984 fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
3986 CurrentSMSMessageError = GE_SMSSENDOK;
3989 /* SMS message send to the network failed */
3993 fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
3995 switch (MessageBuffer[6]) {
3996 case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3997 case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
3998 case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3999 case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
4000 case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4001 case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4002 case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4003 case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4004 case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4007 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
4008 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4011 CurrentSMSMessageError = GE_SMSSENDFAILED;
4017 GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
4021 unsigned char req[256] = {
4023 0x01, 0x02, 0x00, /* SMS send request*/
4028 error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
4029 if (error != GE_NONE) return error;
4031 return NULL_SendMessageSequence
4032 (200, &CurrentSMSMessageError, 42+length, 0x02, req);
4035 void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4037 switch (MessageBuffer[3]) {
4042 fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
4045 CurrentSMSMessage->MessageNumber=MessageBuffer[5];
4047 CurrentSMSMessageError = GE_NONE;
4052 fprintf(stdout, _("SMS saving failed\n"));
4053 switch (MessageBuffer[4]) {
4054 case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
4055 case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
4056 default :fprintf(stdout, _(" Unknown error.\n"));break;
4060 switch (MessageBuffer[4]) {
4061 case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
4062 case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
4063 default :CurrentSMSMessageError = GE_UNKNOWN;break;
4068 /* GST_DR and GST_UN not supported ! */
4069 GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
4071 unsigned char req[256] = {
4072 N6110_FRAME_HEADER, 0x04, /* SMS save request*/
4073 0x00, /* SMS Status. Different for Inbox and Outbox */
4075 0x00, /* SMS Location */
4076 0x02, /* SMS Type */
4080 SMS_MessageType PDU;
4083 if (SMS->Location) req[6] = SMS->Location;
4085 if (SMS->folder==0) { /*Inbox*/
4086 req[4]=1; /* SMS Status */
4087 req[7] = 0x00; /* SMS Type */
4090 req[4]=5; /* SMS Status */
4091 req[7] = 0x02; /* SMS Type */
4095 if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
4097 error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
4098 if (error != GE_NONE) return error;
4100 CurrentSMSMessage = SMS;
4102 return NULL_SendMessageSequence
4103 (70, &CurrentSMSMessageError, 39+length, 0x14, req);
4106 void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4109 fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
4112 CurrentCBError = GE_NONE;
4115 /* Enable and disable Cell Broadcasting */
4116 GSM_Error N6110_EnableCellBroadcast(void)
4118 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4119 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
4122 fprintf (stdout,"Enabling CB\n");
4125 CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
4126 CurrentCBMessage->Channel = 0;
4127 CurrentCBMessage->New = false;
4128 strcpy (CurrentCBMessage->Message,"");
4130 return NULL_SendMessageSequence
4131 (10, &CurrentCBError, 10, 0x02, req);
4135 GSM_Error N6110_DisableCellBroadcast(void)
4137 /* Should work, but not tested fully */
4139 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
4142 return NULL_SendMessageSequence
4143 (10, &CurrentCBError, 10, 0x02, req);
4146 void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4149 unsigned char output[160];
4151 CurrentCBMessage->Channel = MessageBuffer[7];
4152 CurrentCBMessage->New = true;
4153 tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
4156 fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
4158 fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
4162 for (i=0; i<tmp;i++) {
4163 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
4166 fprintf(stdout, "\n");
4169 for (i=0; i<tmp; i++) {
4170 CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
4172 CurrentCBMessage->Message[i]=0;
4175 GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
4178 fprintf(stdout,"Reading CB\n");
4181 if (CurrentCBMessage != NULL)
4183 if (CurrentCBMessage->New == true)
4186 fprintf(stdout,"New CB received\n");
4188 Message->Channel = CurrentCBMessage->Channel;
4189 strcpy(Message->Message,CurrentCBMessage->Message);
4190 CurrentCBMessage->New = false;
4194 return (GE_NONEWCBRECEIVED);
4197 int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
4201 req[count++]=Bitmap.number;
4202 req[count++]=strlen(Bitmap.text);
4203 memcpy(req+count,Bitmap.text,req[count-1]);
4204 count+=req[count-1];
4205 req[count++]=Bitmap.ringtone;
4207 /* Setting for graphic:
4210 0x02 - View Graphics
4211 0x03 - Send Graphics
4213 You can even set it higher but Nokia phones (my
4214 6110 at least) will not show you the name of this
4215 item in menu ;-)) Nokia is really joking here. */
4216 if (Bitmap.enabled) req[count++]=0x01;
4217 else req[count++]=0x00;
4219 req[count++]=(Bitmap.size+4)>>8;
4220 req[count++]=(Bitmap.size+4)%0xff;
4221 req[count++]=0x00; /* Future extensions! */
4222 req[count++]=Bitmap.width;
4223 req[count++]=Bitmap.height;
4224 req[count++]=0x01; /* Just BW */
4225 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4227 return count+Bitmap.size;
4230 int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4234 EncodeNetworkCode(req+count, Bitmap.netcode);
4237 req[count++]=(Bitmap.size+4)>>8;
4238 req[count++]=(Bitmap.size+4)%0xff;
4239 req[count++]=0x00; /* Infofield */
4240 req[count++]=Bitmap.width;
4241 req[count++]=Bitmap.height;
4242 req[count++]=0x01; /* Just BW */
4243 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4245 return count+Bitmap.size;
4248 int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4253 req[count++]=Bitmap.height;
4254 req[count++]=Bitmap.width;
4255 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4257 return count+Bitmap.size;
4260 /* Set a bitmap or welcome-note */
4261 GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
4263 unsigned char req[600] = { N6110_FRAME_HEADER };
4269 /* Direct uploading variables */
4270 GSM_MultiSMSMessage SMS;
4271 unsigned char buffer[1000] = {0x0c,0x01};
4272 GSM_NetworkInfo NetworkInfo;
4276 /* Uploading with preview */
4277 if (Bitmap->number==255 &&
4278 (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
4279 GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
4280 memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
4282 memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
4284 buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
4286 Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
4288 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4289 return GE_NONE; //no answer from phone
4292 CurrentSetBitmapError = GE_BUSY;
4294 switch (Bitmap->type) {
4295 case GSM_WelcomeNoteText:
4296 case GSM_DealerNoteText:
4298 req[count++]=0x01; /* Only one block */
4300 if (Bitmap->type==GSM_WelcomeNoteText)
4301 req[count++]=0x02; /* Welcome text */
4303 req[count++]=0x03; /* Dealer Welcome Note */
4305 textlen=strlen(Bitmap->text);
4306 req[count++]=textlen;
4307 memcpy(req+count,Bitmap->text,textlen);
4311 Protocol->SendMessage(count, 0x05, req);
4315 case GSM_StartupLogo:
4316 if (Bitmap->number==0) {
4318 /* For 33xx we first set animated logo to default */
4319 if (GetModelFeature (FN_STARTUP)==F_STANIM) {
4320 error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4321 if (error!=GE_NONE) return error;
4325 req[count++]=0x01; /* Only one block */
4326 count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
4327 Protocol->SendMessage(count, 0x05, req);
4329 return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4333 case GSM_OperatorLogo:
4334 req[count++]=0x30; /* Store Op Logo */
4335 req[count++]=0x01; /* Location */
4336 count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
4337 Protocol->SendMessage(count, 0x05, req);
4340 case GSM_CallerLogo:
4342 count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
4343 Protocol->SendMessage(count, 0x03, req);
4346 case GSM_PictureImage:
4348 req[count++]=Bitmap->number;
4349 if (strcmp(Bitmap->Sender,"")) {
4350 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
4352 /* Convert number of semioctets to number of chars and add count */
4354 if (textlen % 2) textlen++;
4355 count+=textlen / 2 + 1;
4363 req[count++]=strlen(Bitmap->text);
4364 memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
4365 count+=strlen(Bitmap->text);
4367 req[count++]=Bitmap->width;
4368 req[count++]=Bitmap->height;
4370 memcpy(req+count,Bitmap->bitmap,Bitmap->size);
4371 Protocol->SendMessage(count+Bitmap->size, 0x47, req);
4374 case GSM_7110OperatorLogo:
4375 case GSM_7110StartupLogo:
4376 case GSM_6210StartupLogo:
4377 return GE_NOTSUPPORTED;
4383 /* Wait for timeout or other error. */
4384 while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
4387 return (GE_TIMEOUT);
4392 return CurrentSetBitmapError;
4395 /* Get a bitmap from the phone */
4396 GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
4398 unsigned char req[10] = { N6110_FRAME_HEADER };
4403 CurrentGetBitmap=Bitmap;
4404 CurrentGetBitmapError = GE_BUSY;
4406 switch (CurrentGetBitmap->type) {
4407 case GSM_StartupLogo:
4408 case GSM_WelcomeNoteText:
4409 case GSM_DealerNoteText:
4411 Protocol->SendMessage(count, 0x05, req);
4413 case GSM_OperatorLogo:
4415 req[count++]=0x01; /* Location 1 */
4416 Protocol->SendMessage(count, 0x05, req);
4418 case GSM_CallerLogo:
4420 req[count++]=Bitmap->number;
4421 Protocol->SendMessage(count, 0x03, req);
4423 case GSM_PictureImage:
4425 req[count++]=Bitmap->number;
4426 Protocol->SendMessage(count, 0x47, req);
4428 case GSM_7110OperatorLogo:
4429 case GSM_7110StartupLogo:
4430 case GSM_6210StartupLogo:
4432 return GE_NOTSUPPORTED;
4435 /* Wait for timeout or other error. */
4436 while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
4439 return (GE_TIMEOUT);
4444 CurrentGetBitmap=NULL;
4446 return CurrentGetBitmapError;
4449 void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4451 switch (MessageBuffer[3]) {
4453 /* Set ringtone OK */
4456 fprintf(stdout, _("Message: Ringtone set OK!\n"));
4458 CurrentRingtoneError=GE_NONE;
4461 /* Set ringtone error */
4464 fprintf(stdout, _("Message: Ringtone setting error !\n"));
4466 CurrentRingtoneError=GE_NOTSUPPORTED;
4471 GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
4474 char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
4475 {N6110_FRAME_HEADER,
4477 0x00, /* Location */
4480 int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
4482 /* Variables for preview uploading */
4483 unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
4484 unsigned char buffer2[20];
4485 GSM_NetworkInfo NetworkInfo;
4487 /* Setting ringtone with preview */
4488 if (ringtone->location==255) {
4491 EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
4492 memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
4493 *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
4494 Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
4495 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4497 return GE_NONE; //no answer from phone
4500 *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
4502 req[4]=ringtone->location-1;
4504 return NULL_SendMessageSequence
4505 (50, &CurrentRingtoneError, (size+7), 0x05, req);
4508 void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4512 switch (MessageBuffer[4]) {
4513 case 0x00: /* location supported. We have ringtone */
4515 /* Binary format used in N6150 */
4516 if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4518 fprintf(stdout,_("Message: ringtone \""));
4525 if (MessageBuffer[i]!=0)
4526 fprintf(stdout,_("%c"),MessageBuffer[i]);
4528 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4529 if (MessageBuffer[i]==0) break;
4534 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4537 /* Looking for end */
4540 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4543 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4547 if (i==MessageLength) break;
4551 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4552 CurrentGetBinRingtone->length=i-3;
4554 CurrentBinRingtoneError=GE_NONE;
4558 /* Binary format used in N3210 */
4559 if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4562 fprintf(stdout,_("Message: ringtone \""));
4569 if (MessageBuffer[i]!=0)
4570 fprintf(stdout,_("%c"),MessageBuffer[i]);
4572 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4573 if (MessageBuffer[i]==0) break;
4578 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4581 /* Here changes to get full compatibility with binary format used in N6150 */
4584 MessageBuffer[5]=0x0c;
4585 MessageBuffer[6]=0x01;
4586 MessageBuffer[7]=0x2c;
4588 /* Looking for end */
4591 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4594 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4598 if (i==MessageLength) break;
4602 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4604 CurrentGetBinRingtone->length=i-3;
4606 CurrentBinRingtoneError=GE_NONE;
4611 memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
4613 CurrentGetBinRingtone->length=MessageLength;
4616 fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
4618 CurrentBinRingtoneError=GE_UNKNOWNMODEL;
4624 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4627 CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
4631 GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
4633 unsigned char req[] = { 0x00,0x01,0x9e,
4638 CurrentGetBinRingtone=ringtone;
4640 error=N6110_EnableExtendedCommands(0x01);
4641 if (error!=GE_NONE) return error;
4643 req[3]=ringtone->location-1;
4645 return NULL_SendMessageSequence
4646 (50, &CurrentBinRingtoneError, 4, 0x40, req);
4649 void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4651 switch (MessageBuffer[4]) {
4652 case 0x00: /* location supported. We set ringtone */
4654 fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
4656 CurrentBinRingtoneError=GE_NONE;
4661 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4663 CurrentBinRingtoneError=GE_NOTSUPPORTED;
4668 GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
4670 unsigned char req[1000] = { 0x00,0x01,0xa0};
4674 GSM_BinRingtone ring;
4676 /* Must be sure, that can upload ringtone to this phone */
4677 ring.location=ringtone->location;
4678 error=N6110_GetBinRingTone(&ring);
4679 if (error!=GE_NONE) return error;
4681 error=N6110_EnableExtendedCommands(0x01);
4682 if (error!=GE_NONE) return error;
4684 memcpy(req+3,ringtone->frame,ringtone->length);
4686 req[3]=ringtone->location-1;
4688 return NULL_SendMessageSequence
4689 (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
4692 #endif /* UCLINUX */
4694 GSM_Error N6110_Reset(unsigned char type)
4696 return N6110_EnableExtendedCommands(type);
4699 void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4706 switch (MessageBuffer[3]) {
4708 /* Unknown message - it has been seen after the 0x07 message (call
4709 answered). Probably it has similar meaning. If you can solve
4710 this - just mail me. Pavel JanÃk ml.
4712 The message looks like this:
4720 Phone: [01 ][08 ][00 ] is the header of the frame
4722 [03 ] is the call message subtype
4724 [05 ] is the call sequence number
4728 [00 ][01 ][03 ][02 ][91][00] are unknown but has been
4729 seen in the Incoming call message (just after the
4730 caller's name from the phonebook). But never change
4731 between phone calls :-(
4734 /* This may mean sequence number of 'just made' call - CK */
4738 fprintf(stdout, _("Message: Call message, type 0x02:"));
4739 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4744 /* Possibly call OK */
4745 /* JD: I think that this means "call in progress" (incomming or outgoing) */
4749 fprintf(stdout, _("Message: Call message, type 0x03:"));
4750 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4751 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4754 CurrentCallSequenceNumber=MessageBuffer[4];
4756 CurrentIncomingCall[0]='D';
4757 #endif /* UCLINUX */
4758 if (CurrentCallPassup) CurrentCallPassup('D');
4762 /* Remote end has gone away before you answer the call. Probably your
4763 mother-in-law or banker (which is worse?) ... */
4767 fprintf(stdout, _("Message: Remote end hang up.\n"));
4768 fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
4770 switch (MessageBuffer[6]) {
4771 case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
4772 case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
4773 case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
4774 case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4775 case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
4776 case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4779 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
4780 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4784 CurrentIncomingCall[0] = ' ';
4785 #endif /* UCLINUX */
4786 if (CurrentCallPassup) CurrentCallPassup(' ');
4790 /* Incoming call alert */
4794 fprintf(stdout, _("Message: Incoming call alert:\n"));
4796 /* We can have more then one call ringing - we can distinguish between
4799 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4800 fprintf(stdout, _(" Number: "));
4802 count=MessageBuffer[6];
4804 for (tmp=0; tmp <count; tmp++)
4805 fprintf(stdout, "%c", MessageBuffer[7+tmp]);
4807 fprintf(stdout, "\n");
4809 fprintf(stdout, _(" Name: "));
4811 for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
4812 fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
4814 fprintf(stdout, "\n");
4817 count=MessageBuffer[6];
4820 CurrentIncomingCall[0] = 0;
4821 for (tmp=0; tmp <count; tmp++)
4822 sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
4823 #endif /* UCLINUX */
4827 /* Call answered. Probably your girlfriend...*/
4831 fprintf(stdout, _("Message: Call answered.\n"));
4832 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4837 /* Call ended. Girlfriend is girlfriend, but time is money :-) */
4841 fprintf(stdout, _("Message: Call ended by your phone.\n"));
4842 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4847 /* This message has been seen with the message of subtype 0x09
4848 after I hang the call.
4855 Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
4857 What is the meaning of 87? Can you spell some magic light into
4862 /* Probably means call over - CK */
4866 fprintf(stdout, _("Message: Call message, type 0x0a:"));
4867 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4868 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4872 CurrentIncomingCall[0] = ' ';
4873 #endif /* UCLINUX */
4874 if (CurrentCallPassup) CurrentCallPassup(' ');
4881 fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
4885 if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
4886 #endif /* UCLINUX */
4888 if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
4895 fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
4897 AppendLogText("Unknown msg\n",false);
4899 break; /* Visual C Don't like empty cases */
4905 static void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4909 switch (MessageBuffer[3]) {
4913 /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
4914 /* If you want see, if it works with your phone make something like that: */
4916 /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
4917 /* Protocol->SendMessage(4, 0x04, connect5); */
4919 /* Marcin-Wiacek@TopNet.PL */
4921 #if defined(WIN32) || defined(UCLINUX)
4922 sprintf(Current_IMEI, "%s", MessageBuffer+5);
4923 sprintf(Current_Model, "%s", MessageBuffer+21);
4924 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4926 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
4927 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
4928 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4932 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
4933 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
4934 fprintf(stdout, _(" Model: %s\n"), Current_Model);
4935 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
4936 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
4937 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
4942 /* Get group data */
4943 /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
4946 if (CurrentGetBitmap!=NULL) {
4947 if (CurrentGetBitmap->number==MessageBuffer[4]) {
4948 count=MessageBuffer[5];
4949 memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
4950 CurrentGetBitmap->text[count]=0;
4953 fprintf(stdout, _("Message: Caller group datas\n"));
4954 fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
4959 CurrentGetBitmap->ringtone=MessageBuffer[count++];
4961 fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
4962 if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
4963 fprintf(stdout,_("\n"));
4966 CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
4968 fprintf(stdout, _("Caller group logo "));
4969 if (CurrentGetBitmap->enabled)
4970 fprintf(stdout, _("enabled \n"));
4972 fprintf(stdout, _("disabled \n"));
4975 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4976 CurrentGetBitmap->size+=MessageBuffer[count++];
4978 fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
4982 CurrentGetBitmap->width=MessageBuffer[count++];
4983 CurrentGetBitmap->height=MessageBuffer[count++];
4985 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
4986 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4987 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
4988 CurrentGetBitmapError=GE_NONE;
4991 fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
4996 fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
5001 /* Get group data error */
5004 CurrentGetBitmapError=GE_UNKNOWN;
5006 fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
5010 /* Set group data OK */
5013 CurrentSetBitmapError=GE_NONE;
5015 fprintf(stdout, _("Message: Caller group data set correctly.\n"));
5019 /* Set group data error */
5022 CurrentSetBitmapError=GE_UNKNOWN;
5024 fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
5031 fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
5033 AppendLogText("Unknown msg\n",false);
5035 break; /* Visual C Don't like empty cases */
5039 static void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5041 int tmp, count, length;
5048 switch (MessageBuffer[3]) {
5054 fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
5057 if (CurrentGetBitmap!=NULL) {
5063 for (tmp=0;tmp<MessageBuffer[4];tmp++){
5064 switch (MessageBuffer[count++]) {
5066 if (CurrentGetBitmap->type==GSM_StartupLogo) {
5067 CurrentGetBitmap->height=MessageBuffer[count++];
5068 CurrentGetBitmap->width=MessageBuffer[count++];
5069 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5070 length=CurrentGetBitmap->size;
5071 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
5073 length=MessageBuffer[count++];
5074 length=length*MessageBuffer[count++]/8;
5078 fprintf(stdout, _("Startup logo supported - "));
5079 if (length!=0) { fprintf(stdout, _("currently set\n")); }
5080 else { fprintf(stdout, _("currently empty\n")); }
5082 if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
5085 length=MessageBuffer[count];
5086 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
5087 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5088 CurrentGetBitmap->text[length]=0;
5091 fprintf(stdout, _("Startup Text supported - "));
5094 fprintf(stdout, _("currently set to \""));
5095 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5096 fprintf(stdout, _("\"\n"));
5098 fprintf(stdout, _("currently empty\n"));
5102 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
5105 length=MessageBuffer[count];
5106 if (CurrentGetBitmap->type==GSM_DealerNoteText) {
5107 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5108 CurrentGetBitmap->text[length]=0;
5111 fprintf(stdout, _("Dealer Welcome supported - "));
5114 fprintf(stdout, _("currently set to \""));
5115 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5116 fprintf(stdout, _("\"\n"));
5118 fprintf(stdout, _("currently empty\n"));
5122 if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
5126 if (issupported) CurrentGetBitmapError=GE_NONE;
5127 else CurrentGetBitmapError=GE_NOTSUPPORTED;
5130 fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
5135 /* Set startup OK */
5138 CurrentSetBitmapError=GE_NONE;
5140 fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
5144 /* Set Operator Logo OK */
5148 fprintf(stdout, _("Message: Operator logo correctly set.\n"));
5151 CurrentSetBitmapError=GE_NONE;
5154 /* Set Operator Logo Error */
5158 fprintf(stdout, _("Message: Error setting operator logo!\n"));
5161 CurrentSetBitmapError=GE_UNKNOWN;
5165 /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
5168 if (CurrentGetBitmap!=NULL) {
5170 count=5; /* Location ignored. */
5172 DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
5176 fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
5177 CurrentGetBitmap->netcode,
5178 GSM_GetNetworkName(CurrentGetBitmap->netcode));
5181 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
5182 CurrentGetBitmap->size+=MessageBuffer[count++];
5184 CurrentGetBitmap->width=MessageBuffer[count++];
5185 CurrentGetBitmap->height=MessageBuffer[count++];
5187 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5188 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
5189 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
5190 CurrentGetBitmapError=GE_NONE;
5193 fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
5199 /* Get op logo error */
5203 fprintf(stdout, _("Message: Error getting operator logo!\n"));
5205 CurrentGetBitmapError=GE_UNKNOWN;
5211 fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
5213 AppendLogText("Unknown msg\n",false);
5219 static void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5222 unsigned char output[160];
5228 switch (MessageBuffer[3]) {
5232 /* MessageBuffer[3] = 0x05
5233 MessageBuffer[4] = 0x00
5234 MessageBuffer[5] = 0x0f
5235 MessageBuffer[6] = 0x03
5236 MessageBuffer[7] = length of packed message
5238 This is all I have seen - Gerry Anderson */
5240 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
5244 fprintf(stdout, _("Message from Network operator: "));
5246 for (i=0; i<tmp; i++)
5247 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
5249 fprintf(stdout, "\n");
5258 fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
5260 AppendLogText("Unknown msg\n",false);
5266 static void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5268 switch (MessageBuffer[3]) {
5272 fprintf(stdout, _("Message: SIM card login\n"));
5278 fprintf(stdout, _("Message: SIM card logout\n"));
5284 fprintf(stdout, _("Unknown message of type 0x09.\n"));
5286 AppendLogText("Unknown msg\n",false);
5291 static void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5293 switch(MessageBuffer[3]) {
5298 fprintf(stdout, _("Message: Calendar Alarm active\n"));
5299 fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
5304 fprintf(stdout, _("Unknown message of type 0x13.\n"));
5306 AppendLogText("Unknown msg\n",false);
5311 #endif /* UCLINUX */
5313 void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5317 switch(MessageBuffer[2]) {
5322 fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
5325 CurrentMagicError=GE_NONE;
5331 fprintf(stdout, _("Message: Answer for call commands.\n"));
5334 CurrentDialVoiceError=GE_NONE;
5340 fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
5343 CurrentMagicError=GE_NONE;
5349 fprintf(stdout, _("Message: ACK for simlock closing\n"));
5352 CurrentMagicError=GE_NONE;
5357 switch (MessageBuffer[5]) {
5360 fprintf(stdout,_("Message: EEPROM contest received\n"));
5363 if (MessageBuffer[8]!=0x00) {
5364 for (i=9;i<MessageLength;i++) {
5365 fprintf(stdout,_("%c"), MessageBuffer[i]);
5368 CurrentMagicError=GE_NONE;
5375 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5377 AppendLogText("Unknown msg\n",false);
5383 N6110_DisplayTestsInfo(MessageBuffer);
5385 #endif /* UCLINUX */
5390 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5392 AppendLogText("Unknown msg\n",false);
5393 break; /* Visual C Don't like empty cases */
5399 static void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5403 switch(MessageBuffer[3]) {
5409 if (MessageBuffer[5]!=0) {
5410 strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
5412 while (MessageBuffer[count]!=0) {
5418 strcpy(CurrentGetBitmap->Sender,"\0");
5423 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
5424 CurrentGetBitmap->text[MessageBuffer[count]]=0;
5426 if (MessageBuffer[count]!=0)
5427 count+=MessageBuffer[count];
5432 fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
5435 CurrentGetBitmap->width=MessageBuffer[count+1];
5436 CurrentGetBitmap->height=MessageBuffer[count+2];
5437 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5439 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
5441 CurrentGetBitmapError=GE_NONE;
5447 fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
5449 CurrentSetBitmapError=GE_NONE;
5450 CurrentGetBitmapError=GE_NONE;
5456 fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
5458 CurrentSetBitmapError=GE_UNKNOWN;
5464 fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
5466 CurrentGetBitmapError=GE_UNKNOWN;
5472 fprintf(stdout, _("Unknown message of type 0x47.\n"));
5474 AppendLogText("Unknown msg\n",false);
5475 break; /* Visual C Don't like empty cases */
5479 #endif /* UCLINUX */
5481 void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5484 sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
5485 AppendLog(buffer,strlen(buffer),false);
5488 fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
5492 CurrentLinkOK = true;
5495 static void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5498 fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
5503 /* This function is used for parsing the RLP frame into fields. */
5504 void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
5511 /* We do not need RLP frame parsing to be done when we do not have callback
5513 if (CurrentRLP_RXCallback == NULL)
5516 /* Anybody know the official meaning of the first two bytes?
5517 Nokia 6150 sends junk frames starting D9 01, and real frames starting
5518 D9 00. We'd drop the junk frames anyway because the FCS is bad, but
5519 it's tidier to do it here. We still need to call the callback function
5520 to give it a chance to handle timeouts and/or transmit a frame */
5521 if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
5524 /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
5525 specification, so Header consists of 16 bits (2 bytes). See section 4.1
5526 of the specification. */
5528 frame.Header[0] = MessageBuffer[2];
5529 frame.Header[1] = MessageBuffer[3];
5531 /* Next 200 bits (25 bytes) contain the Information. We store the
5532 information in the Data array. */
5534 for (count = 0; count < 25; count ++)
5535 frame.Data[count] = MessageBuffer[4 + count];
5537 /* The last 24 bits (3 bytes) contain FCS. */
5539 frame.FCS[0] = MessageBuffer[29];
5540 frame.FCS[1] = MessageBuffer[30];
5541 frame.FCS[2] = MessageBuffer[31];
5543 /* Here we pass the frame down in the input stream. */
5544 CurrentRLP_RXCallback(valid ? &frame : NULL);
5547 static void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5550 fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
5557 void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5559 GSM_SMSMessage NullSMS;
5561 switch (MessageBuffer[6]) {
5563 case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
5564 case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
5566 /* Is it possible ? */
5567 case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
5568 default: NullSMS.Type = GST_UN; break;
5572 if (NullSMS.Type == GST_DR)
5573 fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
5575 fprintf(stdout, _("Message: SMS Message Received\n"));
5578 GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
5581 fprintf(stdout, _("\n"));
5585 #endif /* UCLINUX */
5587 void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5591 /* Switch on the basis of the message type byte */
5592 switch (MessageType) {
5594 /* Call information */
5597 N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
5603 switch (MessageBuffer[3]) {
5605 case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5606 case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
5607 case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5608 case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5609 case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5611 case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5612 default :unknown=true;break;
5615 #endif /* UCLINUX */
5617 /* Phonebook handling */
5619 switch (MessageBuffer[3]) {
5621 case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
5623 case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
5625 case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
5627 case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5629 case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5631 default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
5632 #endif /* UCLINUX */
5638 switch (MessageBuffer[3]) {
5639 case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
5640 default :unknown=true;break;
5645 /* Startup Logo, Operator Logo and Profiles. */
5647 switch (MessageBuffer[3]) {
5648 case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5649 case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5650 case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5651 case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5652 case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5653 case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5654 default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
5658 /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
5661 switch (MessageBuffer[3]) {
5663 case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
5664 default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
5668 /* Security code requests */
5670 switch (MessageBuffer[3]) {
5671 case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
5672 case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5673 default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5680 N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
5685 switch (MessageBuffer[3]) {
5686 case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
5687 default :unknown=true;break;
5691 /* Simulating key pressing */
5693 switch (MessageBuffer[3]) {
5694 case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
5695 default :unknown=true;break;
5701 switch (MessageBuffer[3]) {
5702 case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5703 case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
5704 case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5705 default :unknown=true;break;
5709 /* Phone Clock and Alarm */
5711 switch (MessageBuffer[3]) {
5712 case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
5713 case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
5714 case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
5715 case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
5716 default :unknown=true;break;
5720 /* Calendar notes handling */
5722 switch (MessageBuffer[3]) {
5723 case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5724 case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5725 case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
5726 default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
5732 switch (MessageBuffer[3]) {
5734 case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5736 case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5737 case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5739 case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
5740 default :unknown=true;break;
5746 switch (MessageBuffer[3]) {
5748 case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
5750 case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5752 case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5755 case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
5756 default :unknown=true;break;
5759 #endif /* UCLINUX */
5761 /* Internal phone functions? */
5763 switch (MessageBuffer[2]) {
5764 case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
5766 case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
5767 #endif /* UCLINUX */
5768 case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
5770 case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5771 case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5772 case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5773 case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
5774 case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
5775 case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5776 case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5777 case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
5778 case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5779 case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5780 #endif /* UCLINUX */
5781 case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
5782 default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
5787 /* Picture Images */
5790 N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
5792 #endif /* UCLINUX */
5794 /* Mobile phone identification */
5797 N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
5800 /***** Acknowlegment of our frames. *****/
5801 case FBUS_FRTYPE_ACK:
5803 N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
5806 /***** Power on message. *****/
5809 N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
5814 N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
5817 /***** RLP frame received. *****/
5820 N6110_RX_HandleRLPMessage(MessageBuffer);
5823 /***** Power on message. *****/
5826 N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
5829 /***** Unknown message *****/
5830 /* If you think that you know the exact meaning of other messages - please
5835 fprintf(stdout, _("Message: Unknown message type.\n"));
5837 AppendLogText("Unknown msg type\n",false);
5846 fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
5848 AppendLogText("Unknown msg\n",false);