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|9210",
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 if (CurrentCallDivert!=NULL) {
831 switch (MessageBuffer[6]) {
832 case 0x43: CurrentCallDivert->DType=GSM_CDV_Busy;break;
833 case 0x3d: CurrentCallDivert->DType=GSM_CDV_NoAnswer;break;
834 case 0x3e: CurrentCallDivert->DType=GSM_CDV_OutOfReach;break;
835 case 0x15: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
836 case 0x02: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
839 if (MessageBuffer[6]==0x02) //?
840 CurrentCallDivert->CType=GSM_CDV_AllCalls;
842 switch (MessageBuffer[8]) {
843 case 0x0b: CurrentCallDivert->CType=GSM_CDV_VoiceCalls;break;
844 case 0x0d: CurrentCallDivert->CType=GSM_CDV_FaxCalls; break;
845 case 0x19: CurrentCallDivert->CType=GSM_CDV_DataCalls; break;
849 if (MessageBuffer[10]==0x01) {
850 CurrentCallDivert->Enabled=true;
851 CurrentCallDivert->Timeout=MessageBuffer[45];
852 strcpy(CurrentCallDivert->Number,GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
854 CurrentCallDivert->Enabled=false;
856 CurrentCallDivertError=GE_NONE;
862 fprintf(stdout, _("Message: Call divert status receiving error ?\n"));
864 CurrentCallDivertError=GE_UNKNOWN;
869 GSM_Error N6110_CallDivert(GSM_CallDivert *cd)
871 char req[55] = { N6110_FRAME_HEADER, 0x01,
872 0x00, /* operation */
874 0x00, /* divert type */
875 0x00, /* call type */
881 switch (cd->Operation) {
882 case GSM_CDV_Register:
886 req[29]= GSM_PackSemiOctetNumber(cd->Number, req + 9, false);
887 req[52]= cd->Timeout;
890 case GSM_CDV_Erasure:
891 case GSM_CDV_Disable:
898 return GE_NOTIMPLEMENTED;
902 case GSM_CDV_AllTypes : req[6] = 0x15; break;
903 case GSM_CDV_Busy : req[6] = 0x43; break;
904 case GSM_CDV_NoAnswer : req[6] = 0x3d; break;
905 case GSM_CDV_OutOfReach: req[6] = 0x3e; break;
906 default: return GE_NOTIMPLEMENTED;
909 if ((cd->DType == GSM_CDV_AllTypes) &&
910 (cd->CType == GSM_CDV_AllCalls))
914 case GSM_CDV_AllCalls : break;
915 case GSM_CDV_VoiceCalls: req[7] = 0x0b; break;
916 case GSM_CDV_FaxCalls : req[7] = 0x0d; break;
917 case GSM_CDV_DataCalls : req[7] = 0x19; break;
918 default: return GE_NOTIMPLEMENTED;
921 CurrentCallDivert = cd;
923 error=NULL_SendMessageSequence
924 (100, &CurrentCallDivertError, length, 0x06, req);
926 CurrentCallDivert = NULL;
931 GSM_Error N6110_Tests()
933 unsigned char buffer[3]={0x00,0x01,0xcf};
934 unsigned char buffer3[8]={0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00};
938 error=N6110_EnableExtendedCommands(0x01);
939 if (error!=GE_NONE) return error;
941 //make almost all tests
942 Protocol->SendMessage(8, 0x40, buffer3);
944 while (GSM->Initialise(PortDevice, "50", CurrentConnectionType, CurrentRLP_RXCallback)!=GE_NONE) {};
948 return NULL_SendMessageSequence
949 (200, &CurrentNetworkInfoError, 3, 0x40, buffer);
952 void N6110_DisplayTestsInfo(u8 *MessageBuffer) {
956 CurrentNetworkInfoError=GE_NONE;
958 for (i=0;i<MessageBuffer[3];i++) {
960 case 0: fprintf(stdout,_("Unknown(%i) "),i);break;
961 case 1: fprintf(stdout,_("MCU ROM checksum "));break;
962 case 2: fprintf(stdout,_("MCU RAM interface "));break;
963 case 3: fprintf(stdout,_("MCU RAM component "));break;
964 case 4: fprintf(stdout,_("MCU EEPROM interface "));break;
965 case 5: fprintf(stdout,_("MCU EEPROM component "));break;
966 case 6: fprintf(stdout,_("Real Time Clock battery "));break;
967 case 7: fprintf(stdout,_("CCONT interface "));break;
968 case 8: fprintf(stdout,_("AD converter "));break;
969 case 9: fprintf(stdout,_("SW Reset "));break;
970 case 10:fprintf(stdout,_("Power Off "));break;
971 case 11:fprintf(stdout,_("Security Data "));break;
972 case 12:fprintf(stdout,_("EEPROM Tune checksum "));break;
973 case 13:fprintf(stdout,_("PPM checksum "));break;
974 case 14:fprintf(stdout,_("MCU download DSP "));break;
975 case 15:fprintf(stdout,_("DSP alive "));break;
976 case 16:fprintf(stdout,_("COBBA serial "));break;
977 case 17:fprintf(stdout,_("COBBA paraller "));break;
978 case 18:fprintf(stdout,_("EEPROM security checksum"));break;
979 case 19:fprintf(stdout,_("PPM validity "));break;
980 case 20:fprintf(stdout,_("Warranty state "));break;
981 case 21:fprintf(stdout,_("Simlock check "));break;
982 case 22:fprintf(stdout,_("IMEI check? "));break;//from PC-Locals.is OK?
983 default:fprintf(stdout,_("Unknown(%i) "),i);break;
985 switch (MessageBuffer[4+i]) {
986 case 0: fprintf(stdout,_(" : done, result OK"));break;
987 case 0xff:fprintf(stdout,_(" : not done, result unknown"));break;
988 case 254: fprintf(stdout,_(" : done, result NOT OK"));break;
989 default: fprintf(stdout,_(" : result unknown(%i)"),MessageBuffer[4+i]);break;
991 fprintf(stdout,_("\n"));
995 void N6110_ReplySimlockInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1002 fprintf(stdout, _("Message: Simlock info received\n"));
1005 for (i=0; i < 12; i++)
1008 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] >> 4)));
1011 if (j==5 || j==15) fprintf(stdout, _("\n"));
1014 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] & 0x0f)));
1018 if (j==20 || j==24) fprintf(stdout, _("\n"));
1021 if ((MessageBuffer[6] & 1) == 1) fprintf(stdout,_("lock 1 closed\n"));
1022 if ((MessageBuffer[6] & 2) == 2) fprintf(stdout,_("lock 2 closed\n"));
1023 if ((MessageBuffer[6] & 4) == 4) fprintf(stdout,_("lock 3 closed\n"));
1024 if ((MessageBuffer[6] & 8) == 8) fprintf(stdout,_("lock 4 closed\n"));
1026 /* I'm not sure here at all */
1027 if ((MessageBuffer[5] & 1) == 1) fprintf(stdout,_("lock 1 - user\n"));
1028 if ((MessageBuffer[5] & 2) == 2) fprintf(stdout,_("lock 2 - user\n"));
1029 if ((MessageBuffer[5] & 4) == 4) fprintf(stdout,_("lock 3 - user\n"));
1030 if ((MessageBuffer[5] & 8) == 8) fprintf(stdout,_("lock 4 - user\n"));
1032 fprintf(stdout,_("counter for lock1: %i\n"),MessageBuffer[21]);
1033 fprintf(stdout,_("counter for lock2: %i\n"),MessageBuffer[22]);
1034 fprintf(stdout,_("counter for lock3: %i\n"),MessageBuffer[23]);
1035 fprintf(stdout,_("counter for lock4: %i\n"),MessageBuffer[24]);
1040 for (i=0; i < 12; i++)
1043 uni[j]='0' + (MessageBuffer[9+i] >> 4);
1048 uni[j]='0' + (MessageBuffer[9+i] & 0x0f);
1054 strncpy(CurrentSimLock->simlocks[0].data,uni,5);
1055 CurrentSimLock->simlocks[0].data[5]=0;
1056 strncpy(CurrentSimLock->simlocks[3].data,uni+5,10);
1057 CurrentSimLock->simlocks[3].data[10]=0;
1058 strncpy(CurrentSimLock->simlocks[1].data,uni+16,4);
1059 CurrentSimLock->simlocks[1].data[4]=0;
1060 strncpy(CurrentSimLock->simlocks[2].data,uni+20,4);
1061 CurrentSimLock->simlocks[2].data[4]=0;
1063 CurrentSimLock->simlocks[0].enabled=((MessageBuffer[6] & 1) == 1);
1064 CurrentSimLock->simlocks[1].enabled=((MessageBuffer[6] & 2) == 2);
1065 CurrentSimLock->simlocks[2].enabled=((MessageBuffer[6] & 4) == 4);
1066 CurrentSimLock->simlocks[3].enabled=((MessageBuffer[6] & 8) == 8);
1068 CurrentSimLock->simlocks[0].factory=((MessageBuffer[5] & 1) != 1);
1069 CurrentSimLock->simlocks[1].factory=((MessageBuffer[5] & 2) != 2);
1070 CurrentSimLock->simlocks[2].factory=((MessageBuffer[5] & 4) != 4);
1071 CurrentSimLock->simlocks[3].factory=((MessageBuffer[5] & 8) != 8);
1073 CurrentSimLock->simlocks[0].counter=MessageBuffer[21];
1074 CurrentSimLock->simlocks[1].counter=MessageBuffer[22];
1075 CurrentSimLock->simlocks[2].counter=MessageBuffer[23];
1076 CurrentSimLock->simlocks[3].counter=MessageBuffer[24];
1078 CurrentSimlockInfoError=GE_NONE;
1081 GSM_Error N6110_SimlockInfo(GSM_AllSimlocks *siml)
1084 unsigned char req[] = {0x00,0x01,0x8a,0x00};
1085 error=N6110_EnableExtendedCommands(0x01);
1086 if (error!=GE_NONE) return error;
1088 CurrentSimLock=siml;
1090 return NULL_SendMessageSequence (50, &CurrentSimlockInfoError, 4, 0x40, req);
1093 void N6110_ReplyResetPhoneSettings(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1096 fprintf(stdout, _("Message: Resetting phone settings\n"));
1099 CurrentResetPhoneSettingsError=GE_NONE;
1102 GSM_Error N6110_ResetPhoneSettings()
1105 unsigned char req[] = {0x00,0x01,0x65,0x08,0x00};
1106 error=N6110_EnableExtendedCommands(0x01);
1107 if (error!=GE_NONE) return error;
1109 return NULL_SendMessageSequence
1110 (50, &CurrentResetPhoneSettingsError, 5, 0x40, req);
1113 #endif /* UCLINUX */
1115 GSM_Error N6110_GetManufacturer(char *manufacturer)
1117 strcpy (manufacturer, "Nokia");
1123 GSM_Error N6110_GetVoiceMailbox ( GSM_PhonebookEntry *entry)
1125 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
1129 CurrentPhonebookEntry = entry;
1131 req[4] = N6110_MEMORY_VOICE;
1132 req[5] = 0x00; /* Location - isn't important, but... */
1134 error=NULL_SendMessageSequence
1135 (20, &CurrentPhonebookError, 7, 0x03, req);
1137 CurrentPhonebookEntry = NULL;
1142 void N6110_ReplyGetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1146 GSM_Bitmap NullBitmap;
1148 DecodeNetworkCode(MessageBuffer+5, NullBitmap.netcode);
1153 fprintf(stdout, _("Message: Info about downloaded operator name received: %s network (for gnokii \"%s\", for phone \""),
1155 GSM_GetNetworkName(NullBitmap.netcode));
1159 while (MessageBuffer[count]!=0) {
1161 fprintf(stdout,_("%c"),MessageBuffer[count]);
1166 strcpy(CurrentGetOperatorNameNetwork->Code, NullBitmap.netcode);
1167 strncpy(CurrentGetOperatorNameNetwork->Name, MessageBuffer+i,count-i+1);
1170 fprintf(stdout,_("\")\n"));
1173 CurrentGetOperatorNameError=GE_NONE;
1176 GSM_Error N6110_GetOperatorName (GSM_Network *operator)
1178 unsigned char req[] = { 0x00,0x01,0x8c,0x00};
1182 error=N6110_EnableExtendedCommands(0x01);
1183 if (error!=GE_NONE) return error;
1185 CurrentGetOperatorNameNetwork = operator;
1187 error=NULL_SendMessageSequence
1188 (20, &CurrentGetOperatorNameError, 4, 0x40, req);
1190 CurrentGetOperatorNameNetwork = NULL;
1195 void N6110_ReplySetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1198 fprintf(stdout, _("Message: Downloaded operator name changed\n"));
1201 CurrentSetOperatorNameError=GE_NONE;
1204 GSM_Error N6110_SetOperatorName (GSM_Network *operator)
1206 unsigned char req[256] = { 0x00,0x01,0x8b,0x00,
1207 0x00,0x00, /* MCC */
1212 error=N6110_EnableExtendedCommands(0x01);
1213 if (error!=GE_NONE) return error;
1215 EncodeNetworkCode(req+4,operator->Code);
1217 strncpy(req+7,operator->Name,200);
1219 return NULL_SendMessageSequence
1220 (20, &CurrentSetOperatorNameError, 8+strlen(operator->Name), 0x40, req);
1223 #endif /* UCLINUX */
1225 static void N6110_ReplyGetMemoryStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1227 switch (MessageBuffer[3]) {
1232 fprintf(stdout, _("Message: Memory status received:\n"));
1234 fprintf(stdout, _(" Memory Type: %s\n"), N6110_MemoryType_String[MessageBuffer[4]]);
1235 fprintf(stdout, _(" Used: %d\n"), MessageBuffer[6]);
1236 fprintf(stdout, _(" Free: %d\n"), MessageBuffer[5]);
1239 CurrentMemoryStatus->Used = MessageBuffer[6];
1240 CurrentMemoryStatus->Free = MessageBuffer[5];
1241 CurrentMemoryStatusError = GE_NONE;
1248 switch (MessageBuffer[4]) {
1250 fprintf(stdout, _("Message: Memory status error, phone is probably powered off.\n"));break;
1252 fprintf(stdout, _("Message: Memory status error, memory type not supported by phone model.\n"));break;
1254 fprintf(stdout, _("Message: Memory status error, waiting for security code.\n"));break;
1256 fprintf(stdout, _("Message: Unknown Memory status error, subtype (MessageBuffer[4]) = %02x\n"),MessageBuffer[4]);break;
1260 switch (MessageBuffer[4]) {
1261 case 0x6f:CurrentMemoryStatusError = GE_TIMEOUT;break;
1262 case 0x7d:CurrentMemoryStatusError = GE_INTERNALERROR;break;
1263 case 0x8d:CurrentMemoryStatusError = GE_INVALIDSECURITYCODE;break;
1272 /* This function is used to get storage status from the phone. It currently
1273 supports two different memory areas - internal and SIM. */
1274 GSM_Error N6110_GetMemoryStatus(GSM_MemoryStatus *Status)
1276 unsigned char req[] = { N6110_FRAME_HEADER,
1277 0x07, /* MemoryStatus request */
1278 0x00 /* MemoryType */
1283 CurrentMemoryStatus = Status;
1285 req[4] = N6110_GetMemoryType(Status->MemoryType);
1287 error=NULL_SendMessageSequence
1288 (20, &CurrentMemoryStatusError, 5, 0x03, req);
1290 CurrentMemoryStatus = NULL;
1297 void N6110_ReplyGetNetworkInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1299 GSM_NetworkInfo NullNetworkInfo;
1301 /* Make sure we are expecting NetworkInfo frame */
1302 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY) {
1304 fprintf(stdout, _("Message: Network informations:\n"));
1308 fprintf(stdout, _("Message: Network informations not requested, but received:\n"));
1312 sprintf(NullNetworkInfo.NetworkCode, "%x%x%x %x%x", MessageBuffer[14] & 0x0f, MessageBuffer[14] >>4, MessageBuffer[15] & 0x0f, MessageBuffer[16] & 0x0f, MessageBuffer[16] >>4);
1314 sprintf(NullNetworkInfo.CellID, "%02x%02x", MessageBuffer[10], MessageBuffer[11]);
1316 sprintf(NullNetworkInfo.LAC, "%02x%02x", MessageBuffer[12], MessageBuffer[13]);
1319 fprintf(stdout, _(" CellID: %s\n"), NullNetworkInfo.CellID);
1320 fprintf(stdout, _(" LAC: %s\n"), NullNetworkInfo.LAC);
1321 fprintf(stdout, _(" Network code: %s\n"), NullNetworkInfo.NetworkCode);
1322 fprintf(stdout, _(" Network name: %s (%s)\n"),
1323 GSM_GetNetworkName(NullNetworkInfo.NetworkCode),
1324 GSM_GetCountryName(NullNetworkInfo.NetworkCode));
1325 fprintf(stdout, _(" Status: "));
1327 switch (MessageBuffer[8]) {
1328 case 0x01: fprintf(stdout, _("home network selected")); break;
1329 case 0x02: fprintf(stdout, _("roaming network")); break;
1330 case 0x03: fprintf(stdout, _("requesting network")); break;
1331 case 0x04: fprintf(stdout, _("not registered in the network")); break;
1332 default: fprintf(stdout, _("unknown"));
1335 fprintf(stdout, "\n");
1337 fprintf(stdout, _(" Network selection: %s\n"), MessageBuffer[9]==1?_("manual"):_("automatic"));
1340 /* Make sure we are expecting NetworkInfo frame */
1341 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY)
1342 *CurrentNetworkInfo=NullNetworkInfo;
1344 CurrentNetworkInfoError = GE_NONE;
1347 GSM_Error N6110_GetNetworkInfo(GSM_NetworkInfo *NetworkInfo)
1349 unsigned char req[] = { N6110_FRAME_HEADER,
1355 CurrentNetworkInfo = NetworkInfo;
1357 error=NULL_SendMessageSequence
1358 (20, &CurrentNetworkInfoError, 4, 0x0a, req);
1360 CurrentNetworkInfo = NULL;
1365 void N6110_ReplyGetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1370 fprintf(stdout, _("Message: Product Profile Settings received -"));
1371 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),MessageBuffer[3+i]);
1372 fprintf(stdout, _("\n"));
1375 for (i=0;i<4;i++) CurrentPPS[i]=MessageBuffer[3+i];
1377 CurrentProductProfileSettingsError=GE_NONE;
1380 GSM_Error N6110_GetProductProfileSetting (GSM_PPS *PPS)
1382 unsigned char req[] = { 0x00, 0x01,0x6a };
1388 error=N6110_EnableExtendedCommands(0x01);
1389 if (error!=GE_NONE) return error;
1391 error=NULL_SendMessageSequence
1392 (20, &CurrentProductProfileSettingsError, 3, 0x40, req);
1393 if (error!=GE_NONE) return error;
1395 switch (PPS->Name) {
1396 case PPS_ALS : PPS->bool_value=(CurrentPPS[1]&32); break;
1397 case PPS_GamesMenu: PPS->bool_value=(CurrentPPS[3]&64); break;
1398 case PPS_HRData : PPS->bool_value=(CurrentPPS[0]&64); break;
1399 case PPS_14400Data: PPS->bool_value=(CurrentPPS[0]&128);break;
1400 case PPS_EFR : PPS->int_value =(CurrentPPS[0]&1) +(CurrentPPS[0]&2); break;
1401 case PPS_FR : PPS->int_value =(CurrentPPS[0]&16)/16+(CurrentPPS[0]&32)/16;break;
1402 case PPS_HR : PPS->int_value =(CurrentPPS[0]&4)/4 +(CurrentPPS[0]&8)/4; break;
1403 case PPS_VibraMenu: PPS->bool_value=(CurrentPPS[4]&64); break;
1404 case PPS_LCDContrast:
1408 if (CurrentPPS[3]&j) PPS->int_value=PPS->int_value+j;
1411 PPS->int_value=PPS->int_value*100/32;
1419 void N6110_ReplySetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1424 fprintf(stdout, _("Message: Product Profile Settings set to"));
1425 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),CurrentPPS[i]);
1426 fprintf(stdout, _("\n"));
1429 CurrentProductProfileSettingsError=GE_NONE;
1432 GSM_Error N6110_SetProductProfileSetting (GSM_PPS *PPS)
1434 unsigned char req[] = { 0x00, 0x01,0x6b,
1435 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */
1436 unsigned char settings[32];
1444 error=N6110_EnableExtendedCommands(0x01);
1445 if (error!=GE_NONE) return error;
1447 OldPPS.Name=PPS_ALS;
1448 error=N6110_GetProductProfileSetting(&OldPPS);
1449 if (error!=GE_NONE) return error;
1452 for (i=0;i<32;i++) {
1453 if (CurrentPPS[z]&j)
1464 fprintf(stdout,_("Current settings: "));
1465 for (i=0;i<32;i++) {
1466 fprintf(stdout,_("%c"),settings[i]);
1468 fprintf(stdout,_("\n"));
1471 switch (PPS->Name) {
1472 case PPS_ALS :settings[10]=PPS->bool_value?'1':'0';break;
1473 case PPS_HRData :settings[ 5]=PPS->bool_value?'1':'0';break;
1474 case PPS_14400Data:settings[ 6]=PPS->bool_value?'1':'0';break;
1479 for (i=0;i<32;i++) {
1480 if (settings[i]=='1') req[z+3]=req[z+3]+j;
1488 fprintf(stdout,_("Current settings: "));
1490 fprintf(stdout,_("%i "),req[i+3]);
1492 fprintf(stdout,_("\n"));
1496 CurrentPPS[i]=req[i+3];
1499 return NULL_SendMessageSequence
1500 (20, &CurrentProductProfileSettingsError, 7, 0x40, req);
1503 void N6110_ReplyPressKey(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1505 if (MessageBuffer[4]==CurrentPressKeyEvent) CurrentPressKeyError=GE_NONE;
1506 else CurrentPressKeyError=GE_UNKNOWN; /* MessageBuffer[4] = 0x05 */
1508 fprintf(stdout, _("Message: Result of key "));
1509 switch (MessageBuffer[4])
1511 case PRESSPHONEKEY: fprintf(stdout, _("press OK\n"));break;
1512 case RELEASEPHONEKEY: fprintf(stdout, _("release OK\n"));break;
1513 default: fprintf(stdout, _("press or release - error\n"));break;
1518 GSM_Error N6110_PressKey(int key, int event)
1520 unsigned char req[] = {N6110_FRAME_HEADER, 0x42, 0x01, 0x00, 0x01};
1522 req[4]=event; /* if we press or release key */
1525 CurrentPressKeyEvent=event;
1527 return NULL_SendMessageSequence
1528 (10, &CurrentPressKeyError, 7, 0x0c, req);
1531 void N6110_ReplyDisplayOutput(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1533 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
1540 switch(MessageBuffer[3]) {
1542 /* Phone sends displayed texts */
1544 NewX=MessageBuffer[6];
1545 NewY=MessageBuffer[5];
1547 DecodeUnicode (uni, MessageBuffer+8, MessageBuffer[7]);
1550 fprintf(stdout, _("New displayed text (%i %i): \"%s\"\n"),NewX,NewY,uni);
1553 while (N6110_GetModel(model) != GE_NONE)
1556 /* With these rules it works almost excellent with my N5110 */
1557 /* I don't have general rule :-(, that's why you must experiment */
1558 /* with your phone. Nokia could make it better. MW */
1559 /* It's almost OK for N5110*/
1560 /* FIX ME: it will be the same for N5130 and 3210 too*/
1561 if (!strcmp(model,"NSE-1"))
1563 /* OldX==1000 means - it's first time */
1567 for (i=0;i<5+1;i++) {
1568 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1573 if ((OldX==0 && OldY==31 && NewX==29 && NewY==46) ||
1574 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1575 /* Clean the line with current text */
1576 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1578 /* Inserts text into table */
1579 for (i=0; i<MessageBuffer[7];i++) {
1580 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1585 if ((OldX==0 && OldY==21 && NewX==0 && NewY==10) ||
1586 (OldX==0 && OldY==10 && NewX==35 && NewY==46)) {
1588 if ((OldX!=0 && NewX==0 && NewY!=6) ||
1589 (OldX==0 && NewX!=0 && OldY!=13 && OldY!=22) ||
1590 (OldX==0 && NewX==0 && NewY<OldY && (NewY!=13 || OldY!=26)) ||
1591 (OldY==5 && NewY!=5) ||
1592 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1594 /* Writes "old" screen */
1595 for (i=0;i<5+1;i++) {
1596 for (j=0;j<27+1;j++) {fprintf(stdout,_("%c"),PhoneScreen[i][j]);}
1597 fprintf(stdout,_("\n"));
1601 for (i=0;i<5+1;i++) {
1602 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1607 /* Clean the line with current text */
1608 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1610 /* Inserts text into table */
1611 for (i=0; i<MessageBuffer[7];i++) {
1612 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1619 fprintf(stdout, _("%s\n"),uni);
1627 if (MessageBuffer[4]==1)
1631 fprintf(stdout, _("Display output successfully disabled/enabled.\n"));
1634 CurrentDisplayOutputError=GE_NONE;
1641 GSM_Error SetDisplayOutput(unsigned char state)
1643 unsigned char req[] = { N6110_FRAME_HEADER,
1648 return NULL_SendMessageSequence
1649 (30, &CurrentDisplayOutputError, 5, 0x0d, req);
1652 GSM_Error N6110_EnableDisplayOutput()
1654 return SetDisplayOutput(0x01);
1657 GSM_Error N6110_DisableDisplayOutput()
1659 return SetDisplayOutput(0x02);
1662 /* If it is interesting for somebody: we can use 0x40 msg for it
1663 and it will work for all phones. See n6110.txt for details */
1664 GSM_Error N6110_AnswerCall(char s)
1666 unsigned char req0[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,0x07, 0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
1667 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80};
1668 unsigned char req[] = { N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
1673 fprintf(stdout,_("Answering call %d\n\r"),s);
1676 Protocol->SendMessage(sizeof(req0), 0x01, req0);
1679 return NULL_SendMessageSequence
1680 (20, &CurrentMagicError, sizeof(req) , 0x01, req);
1683 void N6110_ReplyGetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1685 switch (MessageBuffer[3]) {
1687 /* Profile feature */
1690 switch(GetModelFeature (FN_PROFILES)) {
1692 switch (MessageBuffer[6]) {
1693 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8]; break;
1694 case 0x01: CurrentProfile->CallAlert = MessageBuffer[8]; break;
1695 case 0x02: CurrentProfile->Ringtone = MessageBuffer[8]; break;
1696 case 0x03: CurrentProfile->Volume = MessageBuffer[8]; break;
1697 case 0x04: CurrentProfile->MessageTone = MessageBuffer[8]; break;
1698 case 0x05: CurrentProfile->Vibration = MessageBuffer[8]; break;
1699 case 0x06: CurrentProfile->WarningTone = MessageBuffer[8]; break;
1700 case 0x07: CurrentProfile->ScreenSaver = MessageBuffer[8]; break;
1703 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1709 switch (MessageBuffer[6]) {
1710 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8];break;
1711 case 0x01: CurrentProfile->Lights = MessageBuffer[8];break;
1712 case 0x02: CurrentProfile->CallAlert = MessageBuffer[8];break;
1713 case 0x03: CurrentProfile->Ringtone = MessageBuffer[8];break;
1714 case 0x04: CurrentProfile->Volume = MessageBuffer[8];break;
1715 case 0x05: CurrentProfile->MessageTone = MessageBuffer[8];break;
1716 case 0x06: CurrentProfile->Vibration = MessageBuffer[8];break;
1717 case 0x07: CurrentProfile->WarningTone = MessageBuffer[8];break;
1718 case 0x08: CurrentProfile->CallerGroups = MessageBuffer[8];break;
1719 case 0x09: CurrentProfile->AutomaticAnswer = MessageBuffer[8];break;
1722 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1729 CurrentProfileError = GE_NONE;
1732 /* Incoming profile name */
1735 if (MessageBuffer[9] == 0x00) {
1736 CurrentProfile->DefaultName=MessageBuffer[8];
1738 CurrentProfile->DefaultName=-1;
1740 /* Here name is in Unicode */
1741 if (GetModelFeature (FN_PROFILES)==F_PROF33) {
1742 DecodeUnicode (CurrentProfile->Name, MessageBuffer+10, MessageBuffer[9]/2);
1745 sprintf(CurrentProfile->Name, MessageBuffer + 10, MessageBuffer[9]);
1746 CurrentProfile->Name[MessageBuffer[9]] = '\0';
1750 CurrentProfileError = GE_NONE;
1756 /* Needs SIM card with PIN in phone */
1757 GSM_Error N6110_GetProfile(GSM_Profile *Profile)
1761 unsigned char name_req[] = { N6110_FRAME_HEADER, 0x1a, 0x00};
1762 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x13, 0x01, 0x00, 0x00};
1766 CurrentProfile = Profile;
1768 /* When after sending all frames feature==253, it means, that it is not
1770 CurrentProfile->KeypadTone=253;
1771 CurrentProfile->Lights=253;
1772 CurrentProfile->CallAlert=253;
1773 CurrentProfile->Ringtone=253;
1774 CurrentProfile->Volume=253;
1775 CurrentProfile->MessageTone=253;
1776 CurrentProfile->WarningTone=253;
1777 CurrentProfile->Vibration=253;
1778 CurrentProfile->CallerGroups=253;
1779 CurrentProfile->ScreenSaver=253;
1780 CurrentProfile->AutomaticAnswer=253;
1782 name_req[4] = Profile->Number;
1784 error=NULL_SendMessageSequence
1785 (20, &CurrentProfileError, 5, 0x05, name_req);
1786 if (error!=GE_NONE) return error;
1788 for (i = 0x00; i <= 0x09; i++) {
1790 feat_req[5] = Profile->Number;
1794 error=NULL_SendMessageSequence
1795 (20, &CurrentProfileError, 7, 0x05, feat_req);
1796 if (error!=GE_NONE) return error;
1799 if (Profile->DefaultName > -1)
1801 switch(GetModelFeature (FN_PROFILES)) {
1803 switch (Profile->DefaultName) {
1804 case 0x00: sprintf(Profile->Name, "General");break;
1805 case 0x01: sprintf(Profile->Name, "Silent");break;
1806 case 0x02: sprintf(Profile->Name, "Descreet");break;
1807 case 0x03: sprintf(Profile->Name, "Loud");break;
1808 case 0x04: sprintf(Profile->Name, "My style");break;
1809 case 0x05: Profile->Name[0]=0;break;
1810 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1814 switch (Profile->DefaultName) {
1815 case 0x00: sprintf(Profile->Name, "Personal");break;
1816 case 0x01: sprintf(Profile->Name, "Car");break;
1817 case 0x02: sprintf(Profile->Name, "Headset");break;
1818 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1822 switch (Profile->DefaultName) {
1823 case 0x00: sprintf(Profile->Name, "General");break;
1824 case 0x01: sprintf(Profile->Name, "Silent");break;
1825 case 0x02: sprintf(Profile->Name, "Meeting");break;
1826 case 0x03: sprintf(Profile->Name, "Outdoor");break;
1827 case 0x04: sprintf(Profile->Name, "Pager");break;
1828 case 0x05: sprintf(Profile->Name, "Car");break;
1829 case 0x06: sprintf(Profile->Name, "Headset");break;
1830 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1840 void N6110_ReplySetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1842 switch (MessageBuffer[3]) {
1844 /* Profile feature change result */
1847 fprintf(stdout, _("Message: Profile feature change result.\n"));
1849 CurrentProfileError = GE_NONE;
1852 /* Profile name set result */
1855 fprintf(stdout, _("Message: Profile name change result.\n"));
1857 CurrentProfileError = GE_NONE;
1863 GSM_Error N6110_SetProfileFeature(u8 profile, u8 feature, u8 value)
1865 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x10, 0x01,
1868 feat_req[5]=profile;
1869 feat_req[6]=feature;
1872 return NULL_SendMessageSequence
1873 (20, &CurrentProfileError, 8, 0x05, feat_req);
1876 GSM_Error N6110_SetProfile(GSM_Profile *Profile)
1880 unsigned char name_req[40] = { N6110_FRAME_HEADER, 0x1c, 0x01, 0x03,
1885 name_req[7] = Profile->Number;
1886 name_req[8] = strlen(Profile->Name);
1887 name_req[6] = name_req[8] + 2;
1889 for (i = 0; i < name_req[8]; i++)
1890 name_req[9 + i] = Profile->Name[i];
1892 error=NULL_SendMessageSequence
1893 (20, &CurrentProfileError, name_req[8] + 9, 0x05, name_req);
1894 if (error!=GE_NONE) return error;
1896 for (i = 0x00; i <= 0x09; i++) {
1899 case 0x00: value = Profile->KeypadTone; break;
1900 case 0x01: value = Profile->Lights; break;
1901 case 0x02: value = Profile->CallAlert; break;
1902 case 0x03: value = Profile->Ringtone; break;
1903 case 0x04: value = Profile->Volume; break;
1904 case 0x05: value = Profile->MessageTone; break;
1905 case 0x06: value = Profile->Vibration; break;
1906 case 0x07: value = Profile->WarningTone; break;
1907 case 0x08: value = Profile->CallerGroups; break;
1908 case 0x09: value = Profile->AutomaticAnswer; break;
1909 default : value = 0; break;
1912 error=N6110_SetProfileFeature(Profile->Number,i,value);
1913 if (error!=GE_NONE) return error;
1919 #endif /* UCLINUX */
1921 bool N6110_SendRLPFrame(RLP_F96Frame *frame, bool out_dtx)
1923 u8 req[60] = { 0x00, 0xd9 };
1925 /* Discontinuos transmission (DTX). See section 5.6 of GSM 04.22 version
1931 memcpy(req+2, (u8 *) frame, 32);
1933 return (Protocol->SendFrame(32, 0xf0, req));
1938 void N6110_ReplyGetCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1946 switch (MessageBuffer[4]) {
1950 CurrentCalendarNote->Type=MessageBuffer[8];
1952 DecodeDateTime(MessageBuffer+9, &CurrentCalendarNote->Time);
1954 DecodeDateTime(MessageBuffer+16, &CurrentCalendarNote->Alarm);
1956 CurrentCalendarNote->Text[0]=0;
1958 if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
1960 if (CurrentCalendarNote->Type == GCN_REMINDER) i=1; //first char is subset
1961 switch (MessageBuffer[24]) {
1964 fprintf(stdout,_("Subset 3 in reminder note !\n"));
1966 while (i!=MessageBuffer[23]) {
1968 if (i!=MessageBuffer[23]-1) {
1969 if (MessageBuffer[24+i]>=0xc2) {
1970 DecodeWithUTF8Alphabet(MessageBuffer[24+i], MessageBuffer[24+i+1], &mychar1);
1971 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1972 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=mychar1;
1978 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1979 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=MessageBuffer[24+i];
1986 fprintf(stdout,_("Subset 2 in reminder note !\n"));
1988 while (i!=MessageBuffer[23]) {
1989 wc = MessageBuffer[24+i] | (0x00 << 8);
1990 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1991 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=
1992 DecodeWithUnicodeAlphabet(wc);
1998 fprintf(stdout,_("Subset 1 in reminder note !\n"));
2000 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
2001 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
2005 fprintf(stdout,_("Unknown subset in reminder note !\n"));
2007 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
2008 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
2012 memcpy(CurrentCalendarNote->Text,MessageBuffer+24,MessageBuffer[23]);
2013 CurrentCalendarNote->Text[MessageBuffer[23]]=0;
2016 if (CurrentCalendarNote->Type == GCN_CALL) {
2017 memcpy(CurrentCalendarNote->Phone,MessageBuffer+24+MessageBuffer[23]+1,MessageBuffer[24+MessageBuffer[23]]);
2018 CurrentCalendarNote->Phone[MessageBuffer[24+MessageBuffer[23]]]=0;
2021 CurrentCalendarNote->Recurrance=0;
2023 CurrentCalendarNote->AlarmType=0;
2026 fprintf(stdout, _("Message: Calendar note received.\n"));
2028 fprintf(stdout, _(" Date: %d-%02d-%02d\n"), CurrentCalendarNote->Time.Year,
2029 CurrentCalendarNote->Time.Month,
2030 CurrentCalendarNote->Time.Day);
2032 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentCalendarNote->Time.Hour,
2033 CurrentCalendarNote->Time.Minute,
2034 CurrentCalendarNote->Time.Second);
2036 /* Some messages do not have alarm set up */
2037 if (CurrentCalendarNote->Alarm.Year != 0) {
2038 fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"), CurrentCalendarNote->Alarm.Year,
2039 CurrentCalendarNote->Alarm.Month,
2040 CurrentCalendarNote->Alarm.Day);
2042 fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"), CurrentCalendarNote->Alarm.Hour,
2043 CurrentCalendarNote->Alarm.Minute,
2044 CurrentCalendarNote->Alarm.Second);
2047 fprintf(stdout, _(" Type: %d\n"), CurrentCalendarNote->Type);
2048 fprintf(stdout, _(" Text: %s\n"), CurrentCalendarNote->Text);
2050 if (CurrentCalendarNote->Type == GCN_CALL)
2051 fprintf(stdout, _(" Phone: %s\n"), CurrentCalendarNote->Phone);
2054 CurrentCalendarNoteError=GE_NONE;
2060 fprintf(stdout, _("Message: Calendar note not available\n"));
2063 CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;
2069 fprintf(stdout, _("Message: Calendar note error\n"));
2072 CurrentCalendarNoteError=GE_INTERNALERROR;
2078 GSM_Error N6110_GetCalendarNote(GSM_CalendarNote *CalendarNote)
2081 unsigned char req[] = { N6110_FRAME_HEADER,
2086 req[4]=CalendarNote->Location;
2088 CurrentCalendarNote = CalendarNote;
2090 error=NULL_SendMessageSequence
2091 (20, &CurrentCalendarNoteError, 5, 0x13, req);
2093 CurrentCalendarNote = NULL;
2098 void N6110_ReplyWriteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2101 switch(MessageBuffer[4]) {
2102 /* This message is also sent when the user enters the new entry on keypad */
2104 fprintf(stdout, _("Message: Calendar note write succesfull!\n"));break;
2106 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2108 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2110 fprintf(stdout, _("Unknown message of type 0x13 and subtype 0x65\n"));break;
2114 switch(MessageBuffer[4]) {
2115 case 0x01: CurrentCalendarNoteError=GE_NONE; break;
2116 case 0x73: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2117 case 0x7d: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2118 default : AppendLogText("Unknown msg\n",false); break;
2122 GSM_Error N6110_WriteCalendarNote(GSM_CalendarNote *CalendarNote)
2125 unsigned char req[200] = { N6110_FRAME_HEADER,
2127 0x00, /* Length of the rest of the frame. */
2128 0x00, /* The type of calendar note */
2129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2136 unsigned char meeting;
2137 unsigned char birthday;
2138 unsigned char reminder;
2139 } calendar_model_length;
2141 /* Length of entries */
2142 calendar_model_length calendar_lengths[] =
2144 /*model,CallTo,Meeting,Birthday,Reminder*/
2145 {"NHM-5",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2146 {"NHM-6",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2147 {"NSE-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 [HKEY_LOCAL_MACHINE\Software\Nokia\Data Suite\3.0\Calendar]
2148 {"NSM-1",0x1e,0x18,0x18,0x24}, //from NCDS3
2149 {"NSK-3",0x1e,0x14,0x14,0x1e}, //from NCDS3
2150 {"NSB-3",0x20,0x14,0x14,0x1e}, //from NCDS3
2151 {"", 0, 0, 0, 0 } //end of table
2162 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
2165 req[7]=CalendarNote->Type;
2167 EncodeDateTime(req+8, &CalendarNote->Time);
2168 req[14] = CalendarNote->Time.Timezone;
2170 if (CalendarNote->Alarm.Year) {
2171 EncodeDateTime(req+15, &CalendarNote->Alarm);
2172 req[21] = CalendarNote->Alarm.Timezone;
2175 req[22]=strlen(CalendarNote->Text);
2179 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2180 req[22]++; // one additional char
2181 req[current++]=0x01; //we use now subset 1
2184 for (i=0; i<strlen(CalendarNote->Text); i++) {
2186 mychar=CalendarNote->Text[i];
2187 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2188 if (EncodeWithUTF8Alphabet(mychar,&mychar1,&mychar2)) {
2189 req[current++]=mychar1;
2190 req[current++]=mychar2;
2191 req[23]=0x03; //use subset 3
2192 req[22]++; // one additional char
2197 /* Enables/disables blinking */
2198 if (mychar=='~') req[current++]=0x01;
2199 else req[current++]=mychar;
2203 req[current++]=strlen(CalendarNote->Phone);
2205 for (i=0; i<strlen(CalendarNote->Phone); i++)
2206 req[current++]=CalendarNote->Phone[i];
2208 while (N6110_GetModel(model) != GE_NONE)
2211 /* Checking maximal length */
2213 while (strcmp(calendar_lengths[i].model,"")) {
2214 if (!strcmp(calendar_lengths[i].model,model)) {
2215 switch (CalendarNote->Type) {
2216 case GCN_REMINDER:if (req[22]>calendar_lengths[i].reminder) return GE_TOOLONG;break;
2217 case GCN_MEETING :if (req[22]>calendar_lengths[i].meeting) return GE_TOOLONG;break;
2218 case GCN_BIRTHDAY:if (req[22]>calendar_lengths[i].birthday) return GE_TOOLONG;break;
2219 case GCN_CALL :if (strlen(CalendarNote->Phone)>calendar_lengths[i].call) return GE_TOOLONG;break;
2226 CurrentCalendarNote = CalendarNote;
2228 error=NULL_SendMessageSequence
2229 (20, &CurrentCalendarNoteError, current, 0x13, req);
2231 CurrentCalendarNote = NULL;
2236 void N6110_ReplyDeleteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2239 switch (MessageBuffer[4]) {
2240 /* This message is also sent when the user deletes an old entry on
2241 keypad or moves an old entry somewhere (there is also `write'
2243 case 0x01:fprintf(stdout, _("Message: Calendar note deleted\n"));break;
2244 case 0x93:fprintf(stdout, _("Message: Calendar note can't be deleted\n"));break;
2245 default :fprintf(stdout, _("Message: Calendar note deleting error\n"));break;
2249 switch (MessageBuffer[4]) {
2250 case 0x01:CurrentCalendarNoteError=GE_NONE;break;
2251 case 0x93:CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;break;
2252 default :CurrentCalendarNoteError=GE_INTERNALERROR;break;
2256 GSM_Error N6110_DeleteCalendarNote(GSM_CalendarNote *CalendarNote)
2259 unsigned char req[] = { N6110_FRAME_HEADER,
2263 req[4]=CalendarNote->Location;
2265 return NULL_SendMessageSequence (20, &CurrentCalendarNoteError, 5, 0x13, req);
2268 #endif /* UCLINUX */
2270 static void N6110_ReplyRFBatteryLevel(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2273 fprintf(stdout, _("Message: Phone status received:\n"));
2274 fprintf(stdout, _(" Mode: "));
2276 switch (MessageBuffer[4]) {
2280 fprintf(stdout, _("registered within the network\n"));
2283 /* I was really amazing why is there a hole in the type of 0x02, now I
2285 case 0x02: fprintf(stdout, _("call in progress\n")); break; /* ringing or already answered call */
2286 case 0x03: fprintf(stdout, _("waiting for security code\n")); break;
2287 case 0x04: fprintf(stdout, _("powered off\n")); break;
2288 default : fprintf(stdout, _("unknown\n"));
2292 fprintf(stdout, _(" Power source: "));
2294 switch (MessageBuffer[7]) {
2296 case 0x01: fprintf(stdout, _("AC/DC\n")); break;
2297 case 0x02: fprintf(stdout, _("battery\n")); break;
2298 default : fprintf(stdout, _("unknown\n"));
2302 fprintf(stdout, _(" Battery Level: %d\n"), MessageBuffer[8]);
2303 fprintf(stdout, _(" Signal strength: %d\n"), MessageBuffer[5]);
2306 CurrentRFLevel=MessageBuffer[5];
2307 CurrentBatteryLevel=MessageBuffer[8];
2308 CurrentPowerSource=MessageBuffer[7];
2312 GSM_Error N6110_GetRFLevel(GSM_RFUnits *units, float *level)
2315 /* FIXME - these values are from 3810 code, may be incorrect. Map from
2316 values returned in status packet to the the values returned by the AT+CSQ
2318 float csq_map[5] = {0, 8, 16, 24, 31};
2323 char screen[NM_MAX_SCREEN_WIDTH];
2327 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2330 if (N6110_NetMonitor(1, screen)!=GE_NONE)
2331 return GE_INTERNALERROR;
2332 #endif /* UCLINUX */
2336 if (screen[4]!='-') {
2337 if (screen[5]=='9' && screen[6]>'4') rf_level=1;
2338 if (screen[5]=='9' && screen[6]<'5') rf_level=2;
2339 if (screen[5]=='8' && screen[6]>'4') rf_level=3;
2342 /* Arbitrary units. */
2343 if (*units == GRF_Arbitrary) {
2349 N6110_SendStatusRequest();
2351 /* Wait for timeout or other error. */
2352 while (timeout != 0 && CurrentRFLevel == -1 ) {
2355 return (GE_TIMEOUT);
2360 /* Make copy in case it changes. */
2361 rf_level = CurrentRFLevel;
2366 /* Now convert between the different units we support. */
2368 /* Arbitrary units. */
2369 if (*units == GRF_Arbitrary) {
2375 if (*units == GRF_CSQ) {
2378 *level = csq_map[rf_level];
2380 *level = 99; /* Unknown/undefined */
2386 /* Unit type is one we don't handle so return error */
2387 return (GE_INTERNALERROR);
2391 GSM_Error N6110_GetBatteryLevel(GSM_BatteryUnits *units, float *level)
2396 char screen[NM_MAX_SCREEN_WIDTH];
2398 CurrentBatteryLevel=-1;
2400 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2403 if (N6110_NetMonitor(23, screen)!=GE_NONE)
2405 #endif /* UCLINUX */
2409 if (screen[29]=='7') batt_level=3;
2410 if (screen[29]=='5') batt_level=2;
2411 if (screen[29]=='2') batt_level=1;
2413 /* Only units we handle at present are GBU_Arbitrary */
2414 if (*units == GBU_Arbitrary) {
2415 *level = batt_level;
2419 return (GE_INTERNALERROR);
2422 N6110_SendStatusRequest();
2424 /* Wait for timeout or other error. */
2425 while (timeout != 0 && CurrentBatteryLevel == -1 ) {
2428 return (GE_TIMEOUT);
2433 /* Take copy in case it changes. */
2434 batt_level = CurrentBatteryLevel;
2436 if (batt_level != -1) {
2438 /* Only units we handle at present are GBU_Arbitrary */
2439 if (*units == GBU_Arbitrary) {
2440 *level = batt_level;
2444 return (GE_INTERNALERROR);
2451 GSM_Error N6110_GetPowerSource(GSM_PowerSource *source)
2456 char screen[NM_MAX_SCREEN_WIDTH];
2458 CurrentPowerSource=-1;
2460 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2463 if (N6110_NetMonitor(20, screen)!=GE_NONE)
2465 #endif /* UCLINUX */
2467 CurrentPowerSource=GPS_ACDC;
2469 if (screen[6]=='x') CurrentPowerSource=GPS_BATTERY;
2471 *source=CurrentPowerSource;
2475 N6110_SendStatusRequest();
2477 /* Wait for timeout or other error. */
2478 while (timeout != 0 && CurrentPowerSource == -1 ) {
2481 return (GE_TIMEOUT);
2486 if (CurrentPowerSource != -1) {
2487 *source=CurrentPowerSource;
2497 static void N6110_ReplyGetDisplayStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2501 for (i=0; i<MessageBuffer[4];i++)
2502 if (MessageBuffer[2*i+6]==2)
2503 CurrentDisplayStatus|=1<<(MessageBuffer[2*i+5]-1);
2505 CurrentDisplayStatus&= (0xff - (1<<(MessageBuffer[2*i+5]-1)));
2508 fprintf(stdout, _("Call in progress: %s\n"), CurrentDisplayStatus & (1<<DS_Call_In_Progress)?"on":"off");
2509 fprintf(stdout, _("Unknown: %s\n"), CurrentDisplayStatus & (1<<DS_Unknown)?"on":"off");
2510 fprintf(stdout, _("Unread SMS: %s\n"), CurrentDisplayStatus & (1<<DS_Unread_SMS)?"on":"off");
2511 fprintf(stdout, _("Voice call: %s\n"), CurrentDisplayStatus & (1<<DS_Voice_Call)?"on":"off");
2512 fprintf(stdout, _("Fax call active: %s\n"), CurrentDisplayStatus & (1<<DS_Fax_Call)?"on":"off");
2513 fprintf(stdout, _("Data call active: %s\n"), CurrentDisplayStatus & (1<<DS_Data_Call)?"on":"off");
2514 fprintf(stdout, _("Keyboard lock: %s\n"), CurrentDisplayStatus & (1<<DS_Keyboard_Lock)?"on":"off");
2515 fprintf(stdout, _("SMS storage full: %s\n"), CurrentDisplayStatus & (1<<DS_SMS_Storage_Full)?"on":"off");
2518 CurrentDisplayStatusError=GE_NONE;
2521 GSM_Error N6110_GetDisplayStatus(int *Status) {
2523 unsigned char req[4]={ N6110_FRAME_HEADER, 0x51 };
2527 error=NULL_SendMessageSequence
2528 (10, &CurrentDisplayStatusError, 4, 0x0d, req);
2529 if (error!=GE_NONE) return error;
2531 *Status=CurrentDisplayStatus;
2536 GSM_Error N6110_DialVoice(char *Number) {
2537 /* This commented sequence doesn't work on N3210/3310/6210/7110 */
2538 // unsigned char req[64]={N6110_FRAME_HEADER, 0x01};
2539 // unsigned char req_end[]={0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};
2541 // req[4]=strlen(Number);
2542 // for(i=0; i < strlen(Number) ; i++)
2543 // req[5+i]=Number[i];
2544 // memcpy(req+5+strlen(Number), req_end, 10);
2545 // return NULL_SendMessageSequence
2546 // (20, &CurrentDialVoiceError, 13+strlen(Number), 0x01, req);
2548 unsigned char req[64]={0x00,0x01,0x7c,
2549 0x01}; //call command
2555 error=N6110_EnableExtendedCommands(0x01);
2556 if (error!=GE_NONE) return error;
2558 for(i=0; i < strlen(Number) ; i++) req[4+i]=Number[i];
2562 return NULL_SendMessageSequence
2563 (20, &CurrentDialVoiceError, 4+strlen(Number)+1, 0x40, req);
2566 #endif /* UCLINUX */
2568 /* Dial a data call - type specifies request to use:
2569 type 0 should normally be used
2570 type 1 should be used when calling a digital line - corresponds to ats35=0
2571 Maybe one day we'll know what they mean!
2573 GSM_Error N6110_DialData(char *Number, char type, void (* callpassup)(char c))
2575 unsigned char req[100] = { N6110_FRAME_HEADER, 0x01 };
2576 unsigned char *req_end;
2577 unsigned char req_end0[] = { 0x01, /* make a data call = type 0x01 */
2578 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2579 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00 };
2580 unsigned char req_end1[] = { 0x01,
2581 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2582 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2583 0x88,0x90,0x21,0x48,0x40,0xbb };
2585 unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2586 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2587 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
2589 unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2590 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2591 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
2592 unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
2593 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2594 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
2595 0x20,0x15,0x63,0x80 };
2600 CurrentCallPassup=callpassup;
2604 usleep(100); Protocol->SendMessage(sizeof(req3), 0x01, req3); /* Lace */
2607 size = sizeof(req_end0);
2610 Protocol->SendMessage(sizeof(req3), 0x01, req3);
2612 Protocol->SendMessage(sizeof(req4), 0x01, req4);
2615 size = sizeof(req_end1);
2617 case -1: /* Just used to set the call passup */
2622 size = sizeof(req_end0);
2626 req[4] = strlen(Number);
2628 for(i = 0; i < strlen(Number) ; i++)
2629 req[5+i] = Number[i];
2631 memcpy(req + 5 + strlen(Number), req_end, size);
2633 Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);
2638 Protocol->SendMessage(26, 0x01, req2);
2648 GSM_Error N6110_GetIncomingCallNr(char *Number)
2651 if (*CurrentIncomingCall != ' ') {
2652 strcpy(Number, CurrentIncomingCall);
2659 #endif /* UCLINUX */
2661 GSM_Error N6110_CancelCall(void)
2663 // This frame & method works only on 61xx/51xx
2664 // unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
2665 // req[4]=CurrentCallSequenceNumber;
2666 // Protocol->SendMessage(6, 0x01, req);
2671 unsigned char req[]={0x00,0x01,0x7c,0x03};
2674 error=N6110_EnableExtendedCommands(0x01);
2675 if (error!=GE_NONE) return error;
2677 return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
2682 void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2684 switch(MessageBuffer[3]) {
2688 fprintf(stdout, _("Message: Security code accepted.\n"));
2690 CurrentSecurityCodeError = GE_NONE;
2695 fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
2697 CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
2701 GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
2704 unsigned char req[15] = { N6110_FRAME_HEADER,
2705 0x0a, /* Enter code request. */
2706 0x00 /* Type of the entered code. */
2710 req[4]=SecurityCode.Type;
2712 for (i=0; i<strlen(SecurityCode.Code);i++)
2713 req[5+i]=SecurityCode.Code[i];
2715 req[5+strlen(SecurityCode.Code)]=0x00;
2716 req[6+strlen(SecurityCode.Code)]=0x00;
2718 return NULL_SendMessageSequence
2719 (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
2722 void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2724 *CurrentSecurityCodeStatus = MessageBuffer[4];
2727 fprintf(stdout, _("Message: Security Code status received: "));
2729 switch(*CurrentSecurityCodeStatus) {
2731 case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;
2732 case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;
2733 case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;
2734 case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;
2735 case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;
2736 case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;
2737 default : fprintf(stdout, _("Unknown!\n"));
2742 CurrentSecurityCodeError = GE_NONE;
2745 GSM_Error N6110_GetSecurityCodeStatus(int *Status)
2748 unsigned char req[4] = { N6110_FRAME_HEADER,
2752 CurrentSecurityCodeStatus=Status;
2754 return NULL_SendMessageSequence
2755 (20, &CurrentSecurityCodeError, 4, 0x08, req);
2758 void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2763 fprintf(stdout, _("Message: Security code received: "));
2764 switch (MessageBuffer[3]) {
2765 case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;
2766 case GSCT_Pin: fprintf(stdout, _("PIN"));break;
2767 case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;
2768 case GSCT_Puk: fprintf(stdout, _("PUK"));break;
2769 case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;
2770 default: fprintf(stdout, _("unknown !"));break;
2772 if (MessageBuffer[4]==1) {
2773 fprintf(stdout, _(" allowed, value \""));
2774 if (MessageBuffer[3]==GSCT_SecurityCode) {
2775 for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2777 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2778 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2779 for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2781 fprintf(stdout, _("\""));
2783 fprintf(stdout, _(" not allowed"));
2785 fprintf(stdout, _("\n"));
2788 if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
2789 && MessageBuffer[4]==1) { /* It's allowed */
2790 if (MessageBuffer[3]==GSCT_SecurityCode) {
2791 for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2792 CurrentSecurityCode->Code[5]=0;
2794 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2795 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2796 for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2797 CurrentSecurityCode->Code[4]=0;
2799 CurrentSecurityCodeError=GE_NONE;
2801 CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
2804 GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
2807 unsigned char req[4] = { 0x00,
2808 0x01,0x6e, /* Get code request. */
2809 0x00 }; /* Type of the requested code. */
2813 error=N6110_EnableExtendedCommands(0x01);
2814 if (error!=GE_NONE) return error;
2816 req[3]=SecurityCode->Type;
2818 CurrentSecurityCode=SecurityCode;
2820 return NULL_SendMessageSequence
2821 (20, &CurrentSecurityCodeError, 4, 0x40, req);
2824 void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2827 fprintf(stdout, _("Message: answer for PlayTone frame\n"));
2830 CurrentPlayToneError=GE_NONE;
2833 GSM_Error N6110_PlayTone(int Herz, u8 Volume)
2835 unsigned char req[6] = { 0x00,0x01,0x8f,
2838 0x00 }; /* HerzHi */
2842 /* PlayTone wasn't used earlier */
2843 if (CurrentPlayToneError==GE_UNKNOWN) {
2844 if (CurrentConnectionType!=GCT_MBUS)
2845 CurrentDisableKeepAlive=true;
2847 error=N6110_EnableExtendedCommands(0x01);
2848 if (error!=GE_NONE) return error;
2851 /* For Herz==255*255 we have silent */
2852 if (Herz!=255*255) {
2865 /* For Herz==255*255 we have silent and additionaly
2866 we wait for phone answer - it's important for MBUS */
2867 if (Herz==255*255) {
2868 error=NULL_SendMessageSequence
2869 (20, &CurrentPlayToneError, 6, 0x40, req);
2871 CurrentPlayToneError=GE_UNKNOWN;
2872 CurrentDisableKeepAlive=false;
2874 if (error!=GE_NONE) return error;
2876 Protocol->SendMessage(6,0x40,req);
2879 error=NULL_SendMessageSequence
2880 (20, &CurrentPlayToneError, 6, 0x40, req);
2882 /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
2883 if (Herz==255*255) {
2884 CurrentPlayToneError=GE_UNKNOWN;
2885 CurrentDisableKeepAlive=false;
2888 if (error!=GE_NONE) return error;
2895 void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2897 if (MessageBuffer[4]==0x01) {
2898 DecodeDateTime(MessageBuffer+8, CurrentDateTime);
2901 fprintf(stdout, _("Message: Date and time\n"));
2902 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
2903 fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
2906 CurrentDateTime->IsSet=true;
2910 fprintf(stdout, _("Message: Date and time not set in phone\n"));
2913 CurrentDateTime->IsSet=false;
2916 CurrentDateTimeError=GE_NONE;
2919 GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
2921 return N6110_PrivGetDateTime(date_time,0x11);
2924 GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
2926 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
2928 CurrentDateTime=date_time;
2930 return NULL_SendMessageSequence
2931 (50, &CurrentDateTimeError, 4, msgtype, req);
2934 void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2937 fprintf(stdout, _("Message: Alarm\n"));
2938 fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
2939 fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
2942 CurrentAlarm->Hour=MessageBuffer[9];
2943 CurrentAlarm->Minute=MessageBuffer[10];
2944 CurrentAlarm->Second=0;
2946 CurrentAlarm->IsSet=(MessageBuffer[8]==2);
2948 CurrentAlarmError=GE_NONE;
2951 GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
2953 return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
2956 GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
2958 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
2960 CurrentAlarm=date_time;
2962 return NULL_SendMessageSequence
2963 (50, &CurrentAlarmError, 4, msgtype, req);
2966 void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2968 switch (MessageBuffer[3]) {
2972 CurrentMessageCenter->No=MessageBuffer[4];
2973 CurrentMessageCenter->Format=MessageBuffer[6];
2974 CurrentMessageCenter->Validity=MessageBuffer[8];
2975 sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
2977 sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
2979 sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
2982 fprintf(stdout, _("Message: SMS Center received:\n"));
2983 fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
2984 fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
2985 fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
2987 fprintf(stdout, _(" SMS Center message format is "));
2989 switch (CurrentMessageCenter->Format) {
2991 case GSMF_Text : fprintf(stdout, _("Text")); break;
2992 case GSMF_Paging: fprintf(stdout, _("Paging")); break;
2993 case GSMF_Fax : fprintf(stdout, _("Fax")); break;
2994 case GSMF_Email : fprintf(stdout, _("Email")); break;
2995 default : fprintf(stdout, _("Unknown"));
2998 fprintf(stdout, "\n");
3000 fprintf(stdout, _(" SMS Center message validity is "));
3002 switch (CurrentMessageCenter->Validity) {
3004 case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;
3005 case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;
3006 case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;
3007 case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;
3008 case GSMV_1_Week : fprintf(stdout, _("1 week")); break;
3009 case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;
3010 default : fprintf(stdout, _("Unknown"));
3013 fprintf(stdout, "\n");
3017 CurrentMessageCenterError=GE_NONE;
3023 /* Number of entries depends on SIM card */
3026 fprintf(stdout, _("Message: SMS Center error received:\n"));
3027 fprintf(stdout, _(" The request for SMS Center failed.\n"));
3030 /* FIXME: appropriate error. */
3031 CurrentMessageCenterError=GE_INTERNALERROR;
3038 /* This function sends to the mobile phone a request for the SMS Center */
3039 GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
3041 unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
3042 0x00 /* SMS Center Number. */
3045 req[5]=MessageCenter->No;
3047 CurrentMessageCenter=MessageCenter;
3049 return NULL_SendMessageSequence
3050 (50, &CurrentMessageCenterError, 6, 0x02, req);
3053 void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3056 fprintf(stdout, _("Message: SMS Center correctly set.\n"));
3058 CurrentMessageCenterError=GE_NONE;
3061 /* This function set the SMS Center profile on the phone. */
3062 GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
3064 unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
3065 0x00, /* SMS Center Number. */
3066 0x00, /* Unknown. */
3067 0x00, /* SMS Message Format. */
3068 0x00, /* Unknown. */
3069 0x00, /* Validity. */
3070 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
3071 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
3072 /* Message Center Name. */
3075 req[5]=MessageCenter->No;
3076 req[7]=MessageCenter->Format;
3077 req[9]=MessageCenter->Validity;
3079 req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
3081 req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
3083 sprintf(req+34, "%s", MessageCenter->Name);
3085 CurrentMessageCenter=MessageCenter;
3087 return NULL_SendMessageSequence
3088 (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
3091 void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3093 switch (MessageBuffer[3]) {
3098 fprintf(stdout, _("Message: SMS Status Received\n"));
3099 fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
3100 fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
3103 CurrentSMSStatus->UnRead = MessageBuffer[11];
3104 CurrentSMSStatus->Number = MessageBuffer[10];
3106 CurrentSMSStatusError = GE_NONE;
3112 fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
3115 CurrentSMSStatusError = GE_INTERNALERROR;
3121 GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
3123 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
3125 CurrentSMSStatus = Status;
3127 return NULL_SendMessageSequence
3128 (10, &CurrentSMSStatusError, 5, 0x14, req);
3131 GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
3135 strcpy(folders->Folder[0].Name,"Inbox");
3136 strcpy(folders->Folder[1].Name,"Outbox");
3141 #endif /* UCLINUX */
3143 GSM_Error N6110_GetIMEI(char *imei)
3145 if (strlen(Current_IMEI)>0) {
3146 strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
3150 return (GE_TRYAGAIN);
3153 GSM_Error N6110_GetRevision(char *revision)
3156 if (strlen(Current_Revision)>0) {
3157 strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
3161 return (GE_TRYAGAIN);
3164 static GSM_Error N6110_GetModel(char *model)
3166 if (strlen(Current_Model)>0) {
3167 strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
3171 return (GE_TRYAGAIN);
3176 void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3178 switch (MessageBuffer[4]) {
3182 fprintf(stdout, _("Message: Date and time set correctly\n"));
3184 CurrentSetDateTimeError=GE_NONE;
3189 fprintf(stdout, _("Message: Date and time setting error\n"));
3191 CurrentSetDateTimeError=GE_INVALIDDATETIME;
3196 /* Needs SIM card with PIN in phone */
3197 GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
3199 return N6110_PrivSetDateTime(date_time,0x11);
3202 /* Needs SIM card with PIN in phone */
3203 GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
3206 unsigned char req[] = { N6110_FRAME_HEADER,
3207 0x60, /* set-time subtype */
3208 0x01, 0x01, 0x07, /* unknown */
3209 0x00, 0x00, /* Year (0x07cf = 1999) */
3210 0x00, 0x00, /* Month Day */
3211 0x00, 0x00, /* Hours Minutes */
3212 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3215 EncodeDateTime(req+7, date_time);
3217 return NULL_SendMessageSequence
3218 (20, &CurrentSetDateTimeError, 14, msgtype, req);
3221 void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3223 switch (MessageBuffer[4]) {
3227 fprintf(stdout, _("Message: Alarm set correctly\n"));
3229 CurrentSetAlarmError=GE_NONE;
3234 fprintf(stdout, _("Message: Alarm setting error\n"));
3236 CurrentSetAlarmError=GE_INVALIDDATETIME;
3241 /* FIXME: we should also allow to set the alarm off :-) */
3242 GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
3244 return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
3247 /* FIXME: we should also allow to set the alarm off :-) */
3248 GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
3251 unsigned char req[] = { N6110_FRAME_HEADER,
3252 0x6b, /* set-alarm subtype */
3253 0x01, 0x20, 0x03, /* unknown */
3254 0x02, /* should be alarm on/off, but it don't works */
3255 0x00, 0x00, /* Hours Minutes */
3256 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3259 req[8] = date_time->Hour;
3260 req[9] = date_time->Minute;
3262 return NULL_SendMessageSequence
3263 (50, &CurrentSetAlarmError, 11, msgtype, req);
3266 #endif /* UCLINUX */
3268 static void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3270 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
3275 switch (MessageBuffer[3]) {
3279 CurrentPhonebookEntry->Empty = true;
3281 count=MessageBuffer[5];
3284 fprintf(stdout, _("Message: Phonebook entry received:\n"));
3285 fprintf(stdout, _(" Name: "));
3287 for (tmp=0; tmp <count; tmp++)
3289 if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
3290 if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
3291 fprintf(stdout, "%c", MessageBuffer[6+tmp]);
3294 fprintf(stdout, "\n");
3297 while (N6110_GetModel(model) != GE_NONE)
3300 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM ||
3301 GetModelFeature (FN_PHONEBOOK)==F_PBK33INT) {//pbk with Unicode
3303 DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
3304 CurrentPhonebookEntry->Name[count/2] = 0x00;
3306 fprintf(stderr,"FATAL ERROR: DecodeUnicode disabled!\n");
3308 #endif /* UCLINUX */
3310 memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);
3311 CurrentPhonebookEntry->Name[count] = 0x00;
3314 CurrentPhonebookEntry->Empty = false;
3316 for (tmp=0; tmp <count; tmp++)
3318 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33INT ||
3319 GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM) {//pbk with Unicode
3320 /* We check only 1'st, 3'rd, ... char */
3321 if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking
3322 if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents
3324 if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking
3325 if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents
3330 count=MessageBuffer[6+count];
3333 fprintf(stdout, _(" Number: "));
3335 for (tmp=0; tmp <count; tmp++)
3336 fprintf(stdout, "%c", MessageBuffer[i+tmp]);
3338 fprintf(stdout, "\n");
3341 memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);
3342 CurrentPhonebookEntry->Number[count] = 0x00;
3343 CurrentPhonebookEntry->Group = MessageBuffer[i+count];
3345 /* Phone doesn't have entended phonebook */
3346 CurrentPhonebookEntry->SubEntriesCount = 0;
3348 /* But for these memories data is saved and we can save it using 7110/6210 style */
3349 if (CurrentPhonebookEntry->MemoryType==GMT_DC ||
3350 CurrentPhonebookEntry->MemoryType==GMT_RC ||
3351 CurrentPhonebookEntry->MemoryType==GMT_MC) {
3352 CurrentPhonebookEntry->SubEntriesCount = 1;
3353 CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;
3354 CurrentPhonebookEntry->SubEntries[0].NumberType=0;
3355 CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;
3356 DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);
3359 fprintf(stdout, _(" Date: "));
3360 fprintf(stdout, "%02u.%02u.%04u\n",
3361 CurrentPhonebookEntry->SubEntries[0].data.Date.Day,
3362 CurrentPhonebookEntry->SubEntries[0].data.Date.Month,
3363 CurrentPhonebookEntry->SubEntries[0].data.Date.Year);
3364 fprintf(stdout, _(" Time: "));
3365 fprintf(stdout, "%02u:%02u:%02u\n",
3366 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,
3367 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,
3368 CurrentPhonebookEntry->SubEntries[0].data.Date.Second);
3371 /* These values are set, when date and time unavailable in phone.
3372 Values from 3310 - in other can be different */
3373 if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&
3374 CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&
3375 CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&
3376 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&
3377 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&
3378 CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)
3379 CurrentPhonebookEntry->SubEntriesCount = 0;
3382 /* Signal no error to calling code. */
3383 CurrentPhonebookError = GE_NONE;
3390 fprintf(stdout, _("Message: Phonebook read entry error received:\n"));
3393 switch (MessageBuffer[4]) {
3397 fprintf(stdout, _(" Invalid memory type!\n"));
3399 CurrentPhonebookError = GE_INVALIDMEMORYTYPE;
3404 fprintf(stdout, _(" Unknown error!\n"));
3406 CurrentPhonebookError = GE_INTERNALERROR;
3414 /* Routine to get specifed phone book location. Designed to be called by
3415 application. Will block until location is retrieved or a timeout/error
3417 GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)
3419 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
3421 CurrentPhonebookEntry = entry;
3423 req[4] = N6110_GetMemoryType(entry->MemoryType);
3424 req[5] = entry->Location;
3426 return NULL_SendMessageSequence
3427 (50, &CurrentPhonebookError, 7, 0x03, req);
3430 static void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3432 switch (MessageBuffer[3]) {
3437 fprintf(stdout, _("Message: Phonebook written correctly.\n"));
3439 CurrentPhonebookError = GE_NONE;
3444 switch (MessageBuffer[4]) {
3445 /* FIXME: other errors? When I send the phonebook with index of 350 it
3446 still report error 0x7d :-( */
3449 fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));
3451 CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;
3456 fprintf(stdout, _(" Unknown error!\n"));
3458 CurrentPhonebookError = GE_INTERNALERROR;
3463 /* Routine to write phonebook location in phone. Designed to be called by
3464 application code. Will block until location is written or timeout
3466 GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)
3468 unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };
3471 req[4] = N6110_GetMemoryType(entry->MemoryType);
3472 req[5] = entry->Location;
3476 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33INT ||
3477 GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM) {
3480 req[6] = strlen(entry->Name)*2;
3482 EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
3484 for (i=0; i<strlen(entry->Name); i++)
3486 /* here we encode "special" chars */
3487 if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
3488 if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
3491 current+=strlen(entry->Name)*2;
3495 fprintf(stderr,"FATAL ERROR: EncodeUnicode disabled!\n");
3498 #endif /* UCLINUX */
3501 req[6] = strlen(entry->Name);
3503 for (i=0; i<strlen(entry->Name); i++)
3505 req[current+i] = entry->Name[i];
3507 /* here we encode "special" chars */
3508 if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
3509 if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
3512 current+=strlen(entry->Name);
3515 req[current++]=strlen(entry->Number);
3517 for (i=0; i<strlen(entry->Number); i++)
3518 req[current+i] = entry->Number[i];
3520 current+=strlen(entry->Number);
3522 /* Jano: This allow to save 14 characters name into SIM memory, when
3523 No Group is selected. */
3524 if (entry->Group == 5)
3525 req[current++]=0xff;
3527 req[current++]=entry->Group;
3529 return NULL_SendMessageSequence
3530 (50, &CurrentPhonebookError, current, 0x03, req);
3535 void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3537 switch(MessageBuffer[3]) {
3541 fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
3543 CurrentNetmonitorError=GE_NONE;
3548 fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
3549 fprintf(stdout, "%s\n", MessageBuffer+4);
3552 strcpy(CurrentNetmonitor, MessageBuffer+4);
3554 CurrentNetmonitorError=GE_NONE;
3558 GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
3560 unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
3564 error=N6110_EnableExtendedCommands(0x01);
3565 if (error!=GE_NONE) return error;
3567 CurrentNetmonitor=Screen;
3571 return NULL_SendMessageSequence
3572 (20, &CurrentNetmonitorError, 4, 0x40, req);
3575 /* Doesn't work in N3210. */
3576 /* In other allow to access phone menu without SIM card (just send any sequence) */
3577 GSM_Error N6110_SendDTMF(char *String)
3579 unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
3580 0x00 /* Length of DTMF string. */
3583 u8 length=strlen(String);
3585 if (length>59) length=59;
3589 memcpy(req+5,String,length);
3591 return NULL_SendMessageSequence
3592 (20, &CurrentSendDTMFError, 5+length, 0x01, req);
3595 #endif /* UCLINUX */
3597 static void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3599 switch (MessageBuffer[3]) {
3603 switch (MessageBuffer[4]) {
3604 case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
3605 default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
3608 CurrentSpeedDialEntry->Location = MessageBuffer[5];
3611 fprintf(stdout, _("Message: Speed dial entry received:\n"));
3612 fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
3613 fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
3614 fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
3617 CurrentSpeedDialError=GE_NONE;
3623 fprintf(stdout, _("Message: Speed dial entry error\n"));
3625 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3631 GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
3634 unsigned char req[] = { N6110_FRAME_HEADER,
3636 0x00 /* The number of speed dial. */
3639 CurrentSpeedDialEntry = entry;
3641 req[4] = entry->Number;
3643 return NULL_SendMessageSequence
3644 (20, &CurrentSpeedDialError, 5, 0x03, req);
3647 static void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3649 switch (MessageBuffer[3]) {
3654 fprintf(stdout, _("Message: Speed dial entry set.\n"));
3656 CurrentSpeedDialError=GE_NONE;
3662 fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
3664 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3670 GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
3673 unsigned char req[] = { N6110_FRAME_HEADER,
3676 0x00, /* Memory Type */
3680 req[4] = entry->Number;
3682 switch (entry->MemoryType) {
3683 case GMT_ME: req[5] = 0x02;
3684 default : req[5] = 0x03;
3687 req[6] = entry->Location;
3689 return NULL_SendMessageSequence
3690 (20, &CurrentSpeedDialError, 7, 0x03, req);
3695 /* This function finds parts of SMS in frame used in new Nokia phones
3696 in internal protocols (they're coded according to GSM 03.40), copies them
3697 to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
3698 GSM_ETSISMSMessage to GSM_SMSMessage structure */
3699 GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
3701 SMS_MessageType PDU=SMS_Deliver;
3702 GSM_ETSISMSMessage ETSI;
3705 ETSI.firstbyte=req[12];
3707 /* See GSM 03.40 section 9.2.3.1 */
3708 if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
3709 if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
3712 case SMS_Submit : offset=5;break;
3713 case SMS_Deliver : offset=4;break;
3714 case SMS_Status_Report: offset=3;break;
3718 for (i=0;i<req[0]+1;i++)
3719 ETSI.SMSCNumber[i]=req[i];
3721 for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
3722 ETSI.Number[i]=req[i+12+offset];
3726 ETSI.TPDCS=req[10+offset];
3727 ETSI.TPUDL=req[11+offset];
3728 ETSI.TPVP=0; //no support for now
3729 ETSI.TPPID=0; //no support for now
3730 for(i=31+offset;i<length;i++)
3731 ETSI.MessageText[i-31-offset]=req[i];
3734 ETSI.TPDCS=req[10+offset];
3735 ETSI.TPUDL=req[11+offset];
3736 ETSI.TPPID=0; //no support for now
3737 for(i=31+offset;i<length;i++)
3738 ETSI.MessageText[i-31-offset]=req[i];
3740 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3742 case SMS_Status_Report:
3744 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3745 ETSI.TPStatus=req[14];
3747 ETSI.SMSCDateTime[i]=req[i+34];
3753 GSM_DecodeETSISMS(SMS, &ETSI);
3760 void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3764 switch (MessageBuffer[3]) {
3768 switch (MessageBuffer[7]) {
3771 CurrentSMSMessage->Type = GST_SMS;
3772 CurrentSMSMessage->folder=GST_INBOX;
3777 CurrentSMSMessage->Type = GST_DR;
3778 CurrentSMSMessage->folder=GST_INBOX;
3783 CurrentSMSMessage->Type = GST_SMS;
3784 CurrentSMSMessage->folder=GST_OUTBOX;
3789 CurrentSMSMessage->Type = GST_UN;
3795 /* Field Short Message Status - MessageBuffer[4] seems not to be
3796 compliant with GSM 07.05 spec.
3797 Meaning Nokia protocol GMS spec
3798 ----------------------------------------------------
3799 MO Sent 0x05 0x07 or 0x01
3800 MO Not sent 0x07 0x06 or 0x00
3801 MT Read 0x01 0x05 or 0x01
3802 MT Not read 0x03 0x04 or 0x00
3803 ----------------------------------------------------
3804 See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
3808 if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
3809 else CurrentSMSMessage->Status = GSS_SENTREAD;
3812 fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
3814 if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
3815 fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
3817 fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
3820 if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
3821 if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
3823 if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
3824 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
3825 else fprintf(stdout, _(" Not sent\n"));
3827 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
3828 else fprintf(stdout, _(" Not read\n"));
3832 CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
3834 CurrentSMSMessage->MemoryType = MessageBuffer[5];
3835 CurrentSMSMessage->MessageNumber = MessageBuffer[6];
3837 /* Signal no error to calling code. */
3838 CurrentSMSMessageError = GE_NONE;
3841 fprintf(stdout, "\n");
3848 /* We have requested invalid or empty location. */
3851 fprintf(stdout, _("Message: SMS reading failed\n"));
3853 switch (MessageBuffer[4]) {
3854 case 0x02:fprintf(stdout, _(" Invalid location!\n"));break;
3855 case 0x07:fprintf(stdout, _(" Empty SMS location.\n"));break;
3856 case 0x0c:fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
3857 default :fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
3861 switch (MessageBuffer[4]) {
3862 case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3863 case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
3864 case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
3865 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3873 GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
3876 unsigned char req[] = { N6110_FRAME_HEADER,
3879 0x00, /* Location */
3884 /* State machine code writes data to these variables when it comes in. */
3886 CurrentSMSMessage = message;
3887 CurrentSMSMessageError = GE_BUSY;
3889 req[5] = message->Location;
3892 Protocol->SendMessage(8, 0x02, req);
3894 /* Wait for timeout or other error. */
3895 while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
3898 return (GE_TIMEOUT);
3903 return (CurrentSMSMessageError);
3906 void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3909 fprintf(stdout, _("Message: SMS deleted successfully.\n"));
3912 CurrentSMSMessageError = GE_NONE;
3915 GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
3917 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
3919 req[5] = message->Location;
3921 return NULL_SendMessageSequence
3922 (50, &CurrentSMSMessageError, 6, 0x14, req);
3925 /* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
3926 GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
3928 GSM_ETSISMSMessage ETSI;
3931 GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
3934 for (i=0;i<36;i++) req[i]=0;
3936 req[12]=ETSI.firstbyte;
3938 for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
3939 req[i]=ETSI.SMSCNumber[i];
3944 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++) req[i+12+offset]=ETSI.Number[i];
3945 req[10+offset]=ETSI.TPDCS;
3946 req[11+offset]=ETSI.TPUDL;
3947 req[24+offset]=ETSI.TPVP;
3949 // fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
3950 // fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
3951 // fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
3953 // req[]=ETSI.TPPID;
3954 for(i=0;i<*length;i++) req[i+31+offset]=ETSI.MessageText[i];
3959 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++) 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++) req[i+31+offset]=ETSI.MessageText[i];
3964 for (i=0;i<7;i++) req[24+offset+i]=ETSI.DeliveryDateTime[i];
3970 *length=*length+offset;
3975 void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3977 switch (MessageBuffer[3]) {
3979 /* SMS message correctly sent to the network */
3982 fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
3984 CurrentSMSMessageError = GE_SMSSENDOK;
3987 /* SMS message send to the network failed */
3991 fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
3993 switch (MessageBuffer[6]) {
3994 case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3995 case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
3996 case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3997 case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
3998 case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3999 case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4000 case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4001 case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4002 case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
4005 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
4006 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4009 CurrentSMSMessageError = GE_SMSSENDFAILED;
4015 GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
4019 unsigned char req[256] = {
4021 0x01, 0x02, 0x00, /* SMS send request*/
4026 error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
4027 if (error != GE_NONE) return error;
4029 return NULL_SendMessageSequence
4030 (200, &CurrentSMSMessageError, 42+length, 0x02, req);
4033 void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4035 switch (MessageBuffer[3]) {
4040 fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
4043 CurrentSMSMessage->MessageNumber=MessageBuffer[5];
4045 CurrentSMSMessageError = GE_NONE;
4050 fprintf(stdout, _("SMS saving failed\n"));
4051 switch (MessageBuffer[4]) {
4052 case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
4053 case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
4054 default :fprintf(stdout, _(" Unknown error.\n"));break;
4058 switch (MessageBuffer[4]) {
4059 case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
4060 case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
4061 default :CurrentSMSMessageError = GE_UNKNOWN;break;
4066 /* GST_DR and GST_UN not supported ! */
4067 GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
4069 unsigned char req[256] = {
4070 N6110_FRAME_HEADER, 0x04, /* SMS save request*/
4071 0x00, /* SMS Status. Different for Inbox and Outbox */
4073 0x00, /* SMS Location */
4074 0x02, /* SMS Type */
4078 SMS_MessageType PDU;
4081 if (SMS->Location) req[6] = SMS->Location;
4083 if (SMS->folder==0) { /*Inbox*/
4084 req[4]=1; /* SMS Status */
4085 req[7] = 0x00; /* SMS Type */
4088 req[4]=5; /* SMS Status */
4089 req[7] = 0x02; /* SMS Type */
4093 if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
4095 error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
4096 if (error != GE_NONE) return error;
4098 CurrentSMSMessage = SMS;
4100 return NULL_SendMessageSequence
4101 (70, &CurrentSMSMessageError, 39+length, 0x14, req);
4104 void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4107 fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
4110 CurrentCBError = GE_NONE;
4113 /* Enable and disable Cell Broadcasting */
4114 GSM_Error N6110_EnableCellBroadcast(void)
4116 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4117 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
4120 fprintf (stdout,"Enabling CB\n");
4123 CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
4124 CurrentCBMessage->Channel = 0;
4125 CurrentCBMessage->New = false;
4126 strcpy (CurrentCBMessage->Message,"");
4128 return NULL_SendMessageSequence
4129 (10, &CurrentCBError, 10, 0x02, req);
4133 GSM_Error N6110_DisableCellBroadcast(void)
4135 /* Should work, but not tested fully */
4137 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
4140 return NULL_SendMessageSequence
4141 (10, &CurrentCBError, 10, 0x02, req);
4144 void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4147 unsigned char output[160];
4149 CurrentCBMessage->Channel = MessageBuffer[7];
4150 CurrentCBMessage->New = true;
4151 tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
4154 fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
4156 fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
4160 for (i=0; i<tmp;i++) {
4161 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
4164 fprintf(stdout, "\n");
4167 for (i=0; i<tmp; i++) {
4168 CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
4170 CurrentCBMessage->Message[i]=0;
4173 GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
4176 fprintf(stdout,"Reading CB\n");
4179 if (CurrentCBMessage != NULL)
4181 if (CurrentCBMessage->New == true)
4184 fprintf(stdout,"New CB received\n");
4186 Message->Channel = CurrentCBMessage->Channel;
4187 strcpy(Message->Message,CurrentCBMessage->Message);
4188 CurrentCBMessage->New = false;
4192 return (GE_NONEWCBRECEIVED);
4195 int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
4199 req[count++]=Bitmap.number;
4200 req[count++]=strlen(Bitmap.text);
4201 memcpy(req+count,Bitmap.text,req[count-1]);
4202 count+=req[count-1];
4203 req[count++]=Bitmap.ringtone;
4205 /* Setting for graphic:
4208 0x02 - View Graphics
4209 0x03 - Send Graphics
4211 You can even set it higher but Nokia phones (my
4212 6110 at least) will not show you the name of this
4213 item in menu ;-)) Nokia is really joking here. */
4214 if (Bitmap.enabled) req[count++]=0x01;
4215 else req[count++]=0x00;
4217 req[count++]=(Bitmap.size+4)>>8;
4218 req[count++]=(Bitmap.size+4)%0xff;
4219 req[count++]=0x00; /* Future extensions! */
4220 req[count++]=Bitmap.width;
4221 req[count++]=Bitmap.height;
4222 req[count++]=0x01; /* Just BW */
4223 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4225 return count+Bitmap.size;
4228 int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4232 EncodeNetworkCode(req+count, Bitmap.netcode);
4235 req[count++]=(Bitmap.size+4)>>8;
4236 req[count++]=(Bitmap.size+4)%0xff;
4237 req[count++]=0x00; /* Infofield */
4238 req[count++]=Bitmap.width;
4239 req[count++]=Bitmap.height;
4240 req[count++]=0x01; /* Just BW */
4241 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4243 return count+Bitmap.size;
4246 int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4251 req[count++]=Bitmap.height;
4252 req[count++]=Bitmap.width;
4253 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4255 return count+Bitmap.size;
4258 /* Set a bitmap or welcome-note */
4259 GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
4261 unsigned char req[600] = { N6110_FRAME_HEADER };
4267 /* Direct uploading variables */
4268 GSM_MultiSMSMessage SMS;
4269 unsigned char buffer[1000] = {0x0c,0x01};
4270 GSM_NetworkInfo NetworkInfo;
4274 /* Uploading with preview */
4275 if (Bitmap->number==255 &&
4276 (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
4277 GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
4278 memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
4280 memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
4282 buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
4284 Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
4286 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4287 return GE_NONE; //no answer from phone
4290 CurrentSetBitmapError = GE_BUSY;
4292 switch (Bitmap->type) {
4293 case GSM_WelcomeNoteText:
4294 case GSM_DealerNoteText:
4296 req[count++]=0x01; /* Only one block */
4298 if (Bitmap->type==GSM_WelcomeNoteText)
4299 req[count++]=0x02; /* Welcome text */
4301 req[count++]=0x03; /* Dealer Welcome Note */
4303 textlen=strlen(Bitmap->text);
4304 req[count++]=textlen;
4305 memcpy(req+count,Bitmap->text,textlen);
4309 Protocol->SendMessage(count, 0x05, req);
4313 case GSM_StartupLogo:
4314 if (Bitmap->number==0) {
4316 /* For 33xx we first set animated logo to default */
4317 if (GetModelFeature (FN_STARTUP)==F_STANIM) {
4318 error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4319 if (error!=GE_NONE) return error;
4323 req[count++]=0x01; /* Only one block */
4324 count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
4325 Protocol->SendMessage(count, 0x05, req);
4327 return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4331 case GSM_OperatorLogo:
4332 req[count++]=0x30; /* Store Op Logo */
4333 req[count++]=0x01; /* Location */
4334 count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
4335 Protocol->SendMessage(count, 0x05, req);
4338 case GSM_CallerLogo:
4340 count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
4341 Protocol->SendMessage(count, 0x03, req);
4344 case GSM_PictureImage:
4346 req[count++]=Bitmap->number;
4347 if (strcmp(Bitmap->Sender,"")) {
4348 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
4350 /* Convert number of semioctets to number of chars and add count */
4352 if (textlen % 2) textlen++;
4353 count+=textlen / 2 + 1;
4361 req[count++]=strlen(Bitmap->text);
4362 memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
4363 count+=strlen(Bitmap->text);
4365 req[count++]=Bitmap->width;
4366 req[count++]=Bitmap->height;
4368 memcpy(req+count,Bitmap->bitmap,Bitmap->size);
4369 Protocol->SendMessage(count+Bitmap->size, 0x47, req);
4372 case GSM_7110OperatorLogo:
4373 case GSM_7110StartupLogo:
4374 case GSM_6210StartupLogo:
4375 return GE_NOTSUPPORTED;
4381 /* Wait for timeout or other error. */
4382 while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
4385 return (GE_TIMEOUT);
4390 return CurrentSetBitmapError;
4393 /* Get a bitmap from the phone */
4394 GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
4396 unsigned char req[10] = { N6110_FRAME_HEADER };
4401 CurrentGetBitmap=Bitmap;
4402 CurrentGetBitmapError = GE_BUSY;
4404 switch (CurrentGetBitmap->type) {
4405 case GSM_StartupLogo:
4406 case GSM_WelcomeNoteText:
4407 case GSM_DealerNoteText:
4409 Protocol->SendMessage(count, 0x05, req);
4411 case GSM_OperatorLogo:
4413 req[count++]=0x01; /* Location 1 */
4414 Protocol->SendMessage(count, 0x05, req);
4416 case GSM_CallerLogo:
4418 req[count++]=Bitmap->number;
4419 Protocol->SendMessage(count, 0x03, req);
4421 case GSM_PictureImage:
4423 req[count++]=Bitmap->number;
4424 Protocol->SendMessage(count, 0x47, req);
4426 case GSM_7110OperatorLogo:
4427 case GSM_7110StartupLogo:
4428 case GSM_6210StartupLogo:
4430 return GE_NOTSUPPORTED;
4433 /* Wait for timeout or other error. */
4434 while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
4437 return (GE_TIMEOUT);
4442 CurrentGetBitmap=NULL;
4444 return CurrentGetBitmapError;
4447 void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4449 switch (MessageBuffer[3]) {
4451 /* Set ringtone OK */
4454 fprintf(stdout, _("Message: Ringtone set OK!\n"));
4456 CurrentRingtoneError=GE_NONE;
4459 /* Set ringtone error */
4462 fprintf(stdout, _("Message: Ringtone setting error !\n"));
4464 CurrentRingtoneError=GE_NOTSUPPORTED;
4469 GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
4472 char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
4473 {N6110_FRAME_HEADER,
4475 0x00, /* Location */
4478 int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
4480 /* Variables for preview uploading */
4481 unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
4482 unsigned char buffer2[20];
4483 GSM_NetworkInfo NetworkInfo;
4485 /* Setting ringtone with preview */
4486 if (ringtone->location==255) {
4489 EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
4490 memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
4491 *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
4492 Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
4493 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4495 return GE_NONE; //no answer from phone
4498 *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
4500 req[4]=ringtone->location-1;
4502 return NULL_SendMessageSequence
4503 (50, &CurrentRingtoneError, (size+7), 0x05, req);
4506 void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4510 switch (MessageBuffer[4]) {
4511 case 0x00: /* location supported. We have ringtone */
4513 /* Binary format used in N6150 */
4514 if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4516 fprintf(stdout,_("Message: ringtone \""));
4523 if (MessageBuffer[i]!=0)
4524 fprintf(stdout,_("%c"),MessageBuffer[i]);
4526 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4527 if (MessageBuffer[i]==0) break;
4532 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4535 /* Looking for end */
4538 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4541 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4545 if (i==MessageLength) break;
4549 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4550 CurrentGetBinRingtone->length=i-3;
4552 CurrentBinRingtoneError=GE_NONE;
4556 /* Binary format used in N3210 */
4557 if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4560 fprintf(stdout,_("Message: ringtone \""));
4567 if (MessageBuffer[i]!=0)
4568 fprintf(stdout,_("%c"),MessageBuffer[i]);
4570 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4571 if (MessageBuffer[i]==0) break;
4576 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4579 /* Here changes to get full compatibility with binary format used in N6150 */
4582 MessageBuffer[5]=0x0c;
4583 MessageBuffer[6]=0x01;
4584 MessageBuffer[7]=0x2c;
4586 /* Looking for end */
4589 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4592 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4596 if (i==MessageLength) break;
4600 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4602 CurrentGetBinRingtone->length=i-3;
4604 CurrentBinRingtoneError=GE_NONE;
4609 memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
4611 CurrentGetBinRingtone->length=MessageLength;
4614 fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
4616 CurrentBinRingtoneError=GE_UNKNOWNMODEL;
4622 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4625 CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
4629 GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
4631 unsigned char req[] = { 0x00,0x01,0x9e,
4636 CurrentGetBinRingtone=ringtone;
4638 error=N6110_EnableExtendedCommands(0x01);
4639 if (error!=GE_NONE) return error;
4641 req[3]=ringtone->location-1;
4643 return NULL_SendMessageSequence
4644 (50, &CurrentBinRingtoneError, 4, 0x40, req);
4647 void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4649 switch (MessageBuffer[4]) {
4650 case 0x00: /* location supported. We set ringtone */
4652 fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
4654 CurrentBinRingtoneError=GE_NONE;
4659 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4661 CurrentBinRingtoneError=GE_NOTSUPPORTED;
4666 GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
4668 unsigned char req[1000] = { 0x00,0x01,0xa0};
4672 GSM_BinRingtone ring;
4674 /* Must be sure, that can upload ringtone to this phone */
4675 ring.location=ringtone->location;
4676 error=N6110_GetBinRingTone(&ring);
4677 if (error!=GE_NONE) return error;
4679 error=N6110_EnableExtendedCommands(0x01);
4680 if (error!=GE_NONE) return error;
4682 memcpy(req+3,ringtone->frame,ringtone->length);
4684 req[3]=ringtone->location-1;
4686 return NULL_SendMessageSequence
4687 (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
4690 #endif /* UCLINUX */
4692 GSM_Error N6110_Reset(unsigned char type)
4694 return N6110_EnableExtendedCommands(type);
4697 void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4704 switch (MessageBuffer[3]) {
4706 /* Unknown message - it has been seen after the 0x07 message (call
4707 answered). Probably it has similar meaning. If you can solve
4708 this - just mail me. Pavel JanÃk ml.
4710 The message looks like this:
4718 Phone: [01 ][08 ][00 ] is the header of the frame
4720 [03 ] is the call message subtype
4722 [05 ] is the call sequence number
4726 [00 ][01 ][03 ][02 ][91][00] are unknown but has been
4727 seen in the Incoming call message (just after the
4728 caller's name from the phonebook). But never change
4729 between phone calls :-(
4732 /* This may mean sequence number of 'just made' call - CK */
4736 fprintf(stdout, _("Message: Call message, type 0x02:"));
4737 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4742 /* Possibly call OK */
4743 /* JD: I think that this means "call in progress" (incomming or outgoing) */
4747 fprintf(stdout, _("Message: Call message, type 0x03:"));
4748 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4749 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4752 CurrentCallSequenceNumber=MessageBuffer[4];
4754 CurrentIncomingCall[0]='D';
4755 #endif /* UCLINUX */
4756 if (CurrentCallPassup) CurrentCallPassup('D');
4760 /* Remote end has gone away before you answer the call. Probably your
4761 mother-in-law or banker (which is worse?) ... */
4765 fprintf(stdout, _("Message: Remote end hang up.\n"));
4766 fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
4768 switch (MessageBuffer[6]) {
4769 case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
4770 case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
4771 case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
4772 case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4773 case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
4774 case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4777 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
4778 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4782 CurrentIncomingCall[0] = ' ';
4783 #endif /* UCLINUX */
4784 if (CurrentCallPassup) CurrentCallPassup(' ');
4788 /* Incoming call alert */
4792 fprintf(stdout, _("Message: Incoming call alert:\n"));
4794 /* We can have more then one call ringing - we can distinguish between
4797 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4798 fprintf(stdout, _(" Number: "));
4800 count=MessageBuffer[6];
4802 for (tmp=0; tmp <count; tmp++)
4803 fprintf(stdout, "%c", MessageBuffer[7+tmp]);
4805 fprintf(stdout, "\n");
4807 fprintf(stdout, _(" Name: "));
4809 for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
4810 fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
4812 fprintf(stdout, "\n");
4815 count=MessageBuffer[6];
4818 CurrentIncomingCall[0] = 0;
4819 for (tmp=0; tmp <count; tmp++)
4820 sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
4821 #endif /* UCLINUX */
4825 /* Call answered. Probably your girlfriend...*/
4829 fprintf(stdout, _("Message: Call answered.\n"));
4830 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4835 /* Call ended. Girlfriend is girlfriend, but time is money :-) */
4839 fprintf(stdout, _("Message: Call ended by your phone.\n"));
4840 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4845 /* This message has been seen with the message of subtype 0x09
4846 after I hang the call.
4853 Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
4855 What is the meaning of 87? Can you spell some magic light into
4860 /* Probably means call over - CK */
4864 fprintf(stdout, _("Message: Call message, type 0x0a:"));
4865 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4866 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4870 CurrentIncomingCall[0] = ' ';
4871 #endif /* UCLINUX */
4872 if (CurrentCallPassup) CurrentCallPassup(' ');
4879 fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
4883 if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
4884 #endif /* UCLINUX */
4886 if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
4893 fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
4895 AppendLogText("Unknown msg\n",false);
4897 break; /* Visual C Don't like empty cases */
4903 static void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4907 switch (MessageBuffer[3]) {
4911 /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
4912 /* If you want see, if it works with your phone make something like that: */
4914 /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
4915 /* Protocol->SendMessage(4, 0x04, connect5); */
4917 /* Marcin-Wiacek@TopNet.PL */
4919 #if defined(WIN32) || defined(UCLINUX)
4920 sprintf(Current_IMEI, "%s", MessageBuffer+5);
4921 sprintf(Current_Model, "%s", MessageBuffer+21);
4922 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4924 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
4925 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
4926 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4930 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
4931 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
4932 fprintf(stdout, _(" Model: %s\n"), Current_Model);
4933 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
4934 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
4935 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
4940 /* Get group data */
4941 /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
4944 if (CurrentGetBitmap!=NULL) {
4945 if (CurrentGetBitmap->number==MessageBuffer[4]) {
4946 count=MessageBuffer[5];
4947 memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
4948 CurrentGetBitmap->text[count]=0;
4951 fprintf(stdout, _("Message: Caller group datas\n"));
4952 fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
4957 CurrentGetBitmap->ringtone=MessageBuffer[count++];
4959 fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
4960 if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
4961 fprintf(stdout,_("\n"));
4964 CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
4966 fprintf(stdout, _("Caller group logo "));
4967 if (CurrentGetBitmap->enabled)
4968 fprintf(stdout, _("enabled \n"));
4970 fprintf(stdout, _("disabled \n"));
4973 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4974 CurrentGetBitmap->size+=MessageBuffer[count++];
4976 fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
4980 CurrentGetBitmap->width=MessageBuffer[count++];
4981 CurrentGetBitmap->height=MessageBuffer[count++];
4983 tmp=GSM_GetBitmapSize(CurrentGetBitmap);
4984 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4985 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
4986 CurrentGetBitmapError=GE_NONE;
4989 fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
4994 fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
4999 /* Get group data error */
5002 CurrentGetBitmapError=GE_UNKNOWN;
5004 fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
5008 /* Set group data OK */
5011 CurrentSetBitmapError=GE_NONE;
5013 fprintf(stdout, _("Message: Caller group data set correctly.\n"));
5017 /* Set group data error */
5020 CurrentSetBitmapError=GE_UNKNOWN;
5022 fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
5029 fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
5031 AppendLogText("Unknown msg\n",false);
5033 break; /* Visual C Don't like empty cases */
5037 static void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5039 int tmp, count, length;
5046 switch (MessageBuffer[3]) {
5052 fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
5055 if (CurrentGetBitmap!=NULL) {
5061 for (tmp=0;tmp<MessageBuffer[4];tmp++){
5062 switch (MessageBuffer[count++]) {
5064 if (CurrentGetBitmap->type==GSM_StartupLogo) {
5065 CurrentGetBitmap->height=MessageBuffer[count++];
5066 CurrentGetBitmap->width=MessageBuffer[count++];
5067 CurrentGetBitmap->size=GSM_GetBitmapSize(CurrentGetBitmap);
5068 length=CurrentGetBitmap->size;
5069 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
5072 length=MessageBuffer[count++];
5073 length=length*MessageBuffer[count++]/8;
5077 fprintf(stdout, _("Startup logo supported - "));
5078 if (length!=0) { fprintf(stdout, _("currently set\n")); }
5079 else { fprintf(stdout, _("currently empty\n")); }
5081 if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
5084 length=MessageBuffer[count];
5085 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
5086 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5087 CurrentGetBitmap->text[length]=0;
5090 fprintf(stdout, _("Startup Text supported - "));
5093 fprintf(stdout, _("currently set to \""));
5094 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5095 fprintf(stdout, _("\"\n"));
5097 fprintf(stdout, _("currently empty\n"));
5101 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
5104 length=MessageBuffer[count];
5105 if (CurrentGetBitmap->type==GSM_DealerNoteText) {
5106 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5107 CurrentGetBitmap->text[length]=0;
5110 fprintf(stdout, _("Dealer Welcome supported - "));
5113 fprintf(stdout, _("currently set to \""));
5114 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5115 fprintf(stdout, _("\"\n"));
5117 fprintf(stdout, _("currently empty\n"));
5121 if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
5125 if (issupported) CurrentGetBitmapError=GE_NONE;
5126 else CurrentGetBitmapError=GE_NOTSUPPORTED;
5129 fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
5134 /* Set startup OK */
5137 CurrentSetBitmapError=GE_NONE;
5139 fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
5143 /* Set Operator Logo OK */
5147 fprintf(stdout, _("Message: Operator logo correctly set.\n"));
5150 CurrentSetBitmapError=GE_NONE;
5153 /* Set Operator Logo Error */
5157 fprintf(stdout, _("Message: Error setting operator logo!\n"));
5160 CurrentSetBitmapError=GE_UNKNOWN;
5164 /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
5167 if (CurrentGetBitmap!=NULL) {
5169 count=5; /* Location ignored. */
5171 DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
5175 fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
5176 CurrentGetBitmap->netcode,
5177 GSM_GetNetworkName(CurrentGetBitmap->netcode));
5180 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
5181 CurrentGetBitmap->size+=MessageBuffer[count++];
5183 CurrentGetBitmap->width=MessageBuffer[count++];
5184 CurrentGetBitmap->height=MessageBuffer[count++];
5186 tmp=GSM_GetBitmapSize(CurrentGetBitmap);
5187 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
5188 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
5189 CurrentGetBitmapError=GE_NONE;
5192 fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
5198 /* Get op logo error */
5202 fprintf(stdout, _("Message: Error getting operator logo!\n"));
5204 CurrentGetBitmapError=GE_UNKNOWN;
5210 fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
5212 AppendLogText("Unknown msg\n",false);
5218 static void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5221 unsigned char output[160];
5227 switch (MessageBuffer[3]) {
5231 /* MessageBuffer[3] = 0x05
5232 MessageBuffer[4] = 0x00
5233 MessageBuffer[5] = 0x0f
5234 MessageBuffer[6] = 0x03
5235 MessageBuffer[7] = length of packed message
5237 This is all I have seen - Gerry Anderson */
5239 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
5243 fprintf(stdout, _("Message from Network operator: "));
5245 for (i=0; i<tmp; i++)
5246 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
5248 fprintf(stdout, "\n");
5257 fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
5259 AppendLogText("Unknown msg\n",false);
5265 static void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5267 switch (MessageBuffer[3]) {
5271 fprintf(stdout, _("Message: SIM card login\n"));
5277 fprintf(stdout, _("Message: SIM card logout\n"));
5283 fprintf(stdout, _("Unknown message of type 0x09.\n"));
5285 AppendLogText("Unknown msg\n",false);
5290 static void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5292 switch(MessageBuffer[3]) {
5297 fprintf(stdout, _("Message: Calendar Alarm active\n"));
5298 fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
5303 fprintf(stdout, _("Unknown message of type 0x13.\n"));
5305 AppendLogText("Unknown msg\n",false);
5310 #endif /* UCLINUX */
5312 void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5316 switch(MessageBuffer[2]) {
5321 fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
5324 CurrentMagicError=GE_NONE;
5330 fprintf(stdout, _("Message: Answer for call commands.\n"));
5333 CurrentDialVoiceError=GE_NONE;
5339 fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
5342 CurrentMagicError=GE_NONE;
5348 fprintf(stdout, _("Message: ACK for simlock closing\n"));
5351 CurrentMagicError=GE_NONE;
5356 switch (MessageBuffer[5]) {
5359 fprintf(stdout,_("Message: EEPROM contest received\n"));
5362 if (MessageBuffer[8]!=0x00) {
5363 for (i=9;i<MessageLength;i++) {
5364 fprintf(stdout,_("%c"), MessageBuffer[i]);
5367 CurrentMagicError=GE_NONE;
5374 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5376 AppendLogText("Unknown msg\n",false);
5382 N6110_DisplayTestsInfo(MessageBuffer);
5384 #endif /* UCLINUX */
5389 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5391 AppendLogText("Unknown msg\n",false);
5392 break; /* Visual C Don't like empty cases */
5398 static void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5402 switch(MessageBuffer[3]) {
5408 if (MessageBuffer[5]!=0) {
5409 strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
5411 while (MessageBuffer[count]!=0) {
5417 strcpy(CurrentGetBitmap->Sender,"\0");
5422 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
5423 CurrentGetBitmap->text[MessageBuffer[count]]=0;
5425 if (MessageBuffer[count]!=0)
5426 count+=MessageBuffer[count];
5431 fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
5434 CurrentGetBitmap->width=MessageBuffer[count+1];
5435 CurrentGetBitmap->height=MessageBuffer[count+2];
5436 CurrentGetBitmap->size=GSM_GetBitmapSize(CurrentGetBitmap);
5438 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
5440 CurrentGetBitmapError=GE_NONE;
5446 fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
5448 CurrentSetBitmapError=GE_NONE;
5449 CurrentGetBitmapError=GE_NONE;
5455 fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
5457 CurrentSetBitmapError=GE_UNKNOWN;
5463 fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
5465 CurrentGetBitmapError=GE_UNKNOWN;
5471 fprintf(stdout, _("Unknown message of type 0x47.\n"));
5473 AppendLogText("Unknown msg\n",false);
5474 break; /* Visual C Don't like empty cases */
5478 #endif /* UCLINUX */
5480 void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5483 sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
5484 AppendLog(buffer,strlen(buffer),false);
5487 fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
5491 CurrentLinkOK = true;
5494 static void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5497 fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
5502 /* This function is used for parsing the RLP frame into fields. */
5503 void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
5510 /* We do not need RLP frame parsing to be done when we do not have callback
5512 if (CurrentRLP_RXCallback == NULL)
5515 /* Anybody know the official meaning of the first two bytes?
5516 Nokia 6150 sends junk frames starting D9 01, and real frames starting
5517 D9 00. We'd drop the junk frames anyway because the FCS is bad, but
5518 it's tidier to do it here. We still need to call the callback function
5519 to give it a chance to handle timeouts and/or transmit a frame */
5520 if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
5523 /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
5524 specification, so Header consists of 16 bits (2 bytes). See section 4.1
5525 of the specification. */
5527 frame.Header[0] = MessageBuffer[2];
5528 frame.Header[1] = MessageBuffer[3];
5530 /* Next 200 bits (25 bytes) contain the Information. We store the
5531 information in the Data array. */
5533 for (count = 0; count < 25; count ++)
5534 frame.Data[count] = MessageBuffer[4 + count];
5536 /* The last 24 bits (3 bytes) contain FCS. */
5538 frame.FCS[0] = MessageBuffer[29];
5539 frame.FCS[1] = MessageBuffer[30];
5540 frame.FCS[2] = MessageBuffer[31];
5542 /* Here we pass the frame down in the input stream. */
5543 CurrentRLP_RXCallback(valid ? &frame : NULL);
5546 static void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5549 fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
5556 void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5558 GSM_SMSMessage NullSMS;
5560 switch (MessageBuffer[6]) {
5562 case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
5563 case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
5565 /* Is it possible ? */
5566 case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
5567 default: NullSMS.Type = GST_UN; break;
5571 if (NullSMS.Type == GST_DR)
5572 fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
5574 fprintf(stdout, _("Message: SMS Message Received\n"));
5577 GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
5580 fprintf(stdout, _("\n"));
5584 #endif /* UCLINUX */
5586 void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5590 /* Switch on the basis of the message type byte */
5591 switch (MessageType) {
5593 /* Call information */
5596 N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
5602 switch (MessageBuffer[3]) {
5604 case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5605 case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
5606 case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5607 case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5608 case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5610 case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5611 default :unknown=true;break;
5614 #endif /* UCLINUX */
5616 /* Phonebook handling */
5618 switch (MessageBuffer[3]) {
5620 case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
5622 case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
5624 case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
5626 case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5628 case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5630 default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
5631 #endif /* UCLINUX */
5637 switch (MessageBuffer[3]) {
5638 case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
5639 default :unknown=true;break;
5644 /* Startup Logo, Operator Logo and Profiles. */
5646 switch (MessageBuffer[3]) {
5647 case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5648 case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5649 case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5650 case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5651 case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5652 case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5653 default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
5657 /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
5660 switch (MessageBuffer[3]) {
5662 case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
5663 default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
5667 /* Security code requests */
5669 switch (MessageBuffer[3]) {
5670 case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
5671 case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5672 default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5679 N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
5684 switch (MessageBuffer[3]) {
5685 case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
5686 default :unknown=true;break;
5690 /* Simulating key pressing */
5692 switch (MessageBuffer[3]) {
5693 case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
5694 default :unknown=true;break;
5700 switch (MessageBuffer[3]) {
5701 case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5702 case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
5703 case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5704 default :unknown=true;break;
5708 /* Phone Clock and Alarm */
5710 switch (MessageBuffer[3]) {
5711 case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
5712 case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
5713 case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
5714 case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
5715 default :unknown=true;break;
5719 /* Calendar notes handling */
5721 switch (MessageBuffer[3]) {
5722 case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5723 case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5724 case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
5725 default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
5731 switch (MessageBuffer[3]) {
5733 case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5735 case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5736 case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5738 case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
5739 default :unknown=true;break;
5745 switch (MessageBuffer[3]) {
5747 case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
5749 case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5751 case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5754 case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
5755 default :unknown=true;break;
5758 #endif /* UCLINUX */
5760 /* Internal phone functions? */
5762 switch (MessageBuffer[2]) {
5763 case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
5765 case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
5766 #endif /* UCLINUX */
5767 case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
5769 case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5770 case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5771 case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5772 case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
5773 case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
5774 case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5775 case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5776 case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
5777 case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5778 case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5779 #endif /* UCLINUX */
5780 case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
5781 default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
5786 /* Picture Images */
5789 N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
5791 #endif /* UCLINUX */
5793 /* Mobile phone identification */
5796 N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
5799 /***** Acknowlegment of our frames. *****/
5800 case FBUS_FRTYPE_ACK:
5802 N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
5805 /***** Power on message. *****/
5808 N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
5813 N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
5816 /***** RLP frame received. *****/
5819 N6110_RX_HandleRLPMessage(MessageBuffer);
5822 /***** Power on message. *****/
5825 N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
5828 /***** Unknown message *****/
5829 /* If you think that you know the exact meaning of other messages - please
5834 fprintf(stdout, _("Message: Unknown message type.\n"));
5836 AppendLogText("Unknown msg type\n",false);
5845 fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
5847 AppendLogText("Unknown msg\n",false);