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
14 /* "Turn on" prototypes in n-6110.h */
18 /* System header files */
24 #include "misc_win32.h"
27 /* Various header file */
33 #include "gsm-coding.h"
34 #include "newmodules/n6110.h"
35 #include "newmodules/n7110.h"
36 #include "protocol/fbus.h"
37 #include "devices/device.h"
38 /* Global variables used by code in gsm-api.c to expose the functions
39 supported by this model of phone. */
47 /* Here we initialise model specific functions. */
48 GSM_Functions N6110_Functions = {
50 N6110_DispatchMessage,
53 N6110_GetMemoryLocation,
54 N6110_WritePhonebookLocation,
57 N6110_GetMemoryStatus,
62 N6110_DeleteSMSMessage,
66 N6110_GetBatteryLevel,
68 N6110_GetDisplayStatus,
69 N6110_EnterSecurityCode,
70 N6110_GetSecurityCodeStatus,
71 N6110_GetSecurityCode,
81 N6110_GetIncomingCallNr,
83 N6110_GetCalendarNote,
84 N6110_WriteCalendarNote,
85 N6110_DeleteCalendarNote,
99 N6110_EnableDisplayOutput,
100 N6110_DisableDisplayOutput,
101 N6110_EnableCellBroadcast,
102 N6110_DisableCellBroadcast,
103 N6110_ReadCellBroadcast,
105 N6110_GetProductProfileSetting,
106 N6110_SetProductProfileSetting,
107 N6110_GetOperatorName,
108 N6110_SetOperatorName,
109 N6110_GetVoiceMailbox, N6110_Tests,
111 UNIMPLEMENTED, //GetCalendarNotesInfo
113 N6110_ResetPhoneSettings,
114 N7110_GetWAPBookmark,
115 N7110_SetWAPBookmark,
116 N7110_GetWAPSettings,
119 N6110_GetManufacturer
122 /* Mobile phone information */
124 GSM_Information N6110_Information = {
125 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
126 /* Supported models in FBUS */
127 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850|9210",
128 /* Supported models in MBUS */
129 "6110|6130|6150|8210|8850",
130 /* Supported models in FBUS over infrared */
132 /* Supported models in FBUS over DLR3 */
136 /* infrared sockets */
137 "6110|6130|6150|8210|8850",
138 /* Supported models in FBUS over infrared with Tekram device */ "",
139 4, /* Max RF Level */
140 0, /* Min RF Level */
141 GRF_Arbitrary, /* RF level units */
142 4, /* Max Battery Level */
143 0, /* Min Battery Level */
144 GBU_Arbitrary, /* Battery level units */
145 GDT_DateTime, /* Have date/time support */
146 GDT_TimeOnly, /* Alarm supports time only */
147 1 /* Only one alarm available */
150 const char *N6110_MemoryType_String [] = {
163 /* Magic bytes from the phone. */
164 unsigned char MagicBytes[4] = { 0x00, 0x00, 0x00, 0x00 };
166 /* For DisplayOutput */
167 char PhoneScreen[5+1][27+1];
168 int OldX=1000,OldY=0,NewX=0,NewY=0;
170 void N6110_ReplyEnableExtendedCommands(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
173 fprintf(stdout, _("Message: Answer for EnableExtendedSecurityCommands frame, meaning not known :-(\n"));
176 CurrentEnableExtendedCommandsError=GE_NONE;
179 /* If you set make some things (for example,
180 change Security Code from phone's menu, disable and enable
181 phone), it won't answer for 0x40 frame - you won't be able
182 to play tones, get netmonitor, etc.
184 This function do thing called "Enabling extended security commands" -
185 it enables 0x40 frame functions.
187 This frame can also some other things - see below */
188 GSM_Error N6110_EnableExtendedCommands (unsigned char status)
190 unsigned char req[4] = { 0x00,
191 0x01,0x64, /* Enable extended commands request */
192 0x01 }; /* 0x01 - on, 0x00 - off,
193 0x03 & 0x04 - soft & hard reset,
194 0x06 - CONTACT SERVICE */
196 /* 0x06 MAKES CONTACT SERVICE! BE CAREFULL! */
197 /* When use 0x03 and had during session changed time & date
198 some phones (like 6150 or 6210) can ask for time & date after reset
199 or disable clock on the screen */
200 if (status!=0x06) req[3] = status;
202 return NULL_SendMessageSequence
203 (50, &CurrentEnableExtendedCommandsError, 4, 0x40, req);
206 void N6110_ReplyIMEI(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
208 #if defined WIN32 || !defined HAVE_SNPRINTF
209 sprintf(Current_IMEI, "%s", MessageBuffer+4);
211 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+4);
215 fprintf(stdout, _("Message: IMEI %s received\n"),Current_IMEI);
218 CurrentGetIMEIError=GE_NONE;
221 GSM_Error N6110_SendIMEIFrame()
223 unsigned char req[4] = {0x00, 0x01, 0x66, 0x00};
227 error=N6110_EnableExtendedCommands(0x01);
228 if (error!=GE_NONE) return error;
230 return NULL_SendMessageSequence (20, &CurrentGetIMEIError, 4, 0x40, req);
233 void N6110_ReplyHW(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
237 if (MessageBuffer[3]==0x05) {
240 fprintf(stdout,_("Message: Hardware version received: "));
243 j=strlen(Current_Revision);
244 Current_Revision[j++]=',';
245 Current_Revision[j++]=' ';
246 Current_Revision[j++]='H';
247 Current_Revision[j++]='W';
251 fprintf(stdout,_("%c"), MessageBuffer[i]);
253 Current_Revision[j++]=MessageBuffer[i];
257 fprintf(stdout,_("\n"));
260 CurrentGetHWError=GE_NONE;
264 GSM_Error N6110_SendHWFrame()
266 unsigned char req[4] = {0x00, 0x01, 0xc8, 0x05};
270 error=N6110_EnableExtendedCommands(0x01);
271 if (error!=GE_NONE) return error;
273 return NULL_SendMessageSequence (20, &CurrentGetHWError, 4, 0x40, req);
276 void N6110_ReplyID(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
281 fprintf(stdout, _("Message: Mobile phone model identification received:\n"));
282 fprintf(stdout, _(" Firmware: "));
285 strcpy(Current_Revision,"SW");
288 while (MessageBuffer[i]!=0x0a) {
289 Current_Revision[j]=MessageBuffer[i];
291 fprintf(stdout, _("%c"),MessageBuffer[i]);
293 if (j==GSM_MAX_REVISION_LENGTH-1) {
295 fprintf(stderr,_("ERROR: increase GSM_MAX_REVISION_LENGTH!\n"));
302 Current_Revision[j+1]=0;
305 fprintf(stdout, _("\n Firmware date: "));
309 while (MessageBuffer[i]!=0x0a) {
311 fprintf(stdout, _("%c"),MessageBuffer[i]);
317 fprintf(stdout, _("\n Model: "));
321 while (MessageBuffer[i]!=0x0a) {
322 Current_Model[j]=MessageBuffer[i];
324 fprintf(stdout, _("%c"),MessageBuffer[i]);
326 if (j==GSM_MAX_MODEL_LENGTH-1) {
328 fprintf(stderr,_("ERROR: increase GSM_MAX_MODEL_LENGTH!\n"));
335 Current_Model[j+1]=0;
338 fprintf(stdout, _("\n"));
341 CurrentMagicError=GE_NONE;
344 GSM_Error N6110_SendIDFrame()
346 unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
348 return NULL_SendMessageSequence (50, &CurrentMagicError, 5, 0xd1, req);
351 /* This function send the status request to the phone. */
352 /* Seems to be ignored in N3210 */
353 GSM_Error N6110_SendStatusRequest(void)
355 unsigned char req[] = {N6110_FRAME_HEADER, 0x01};
357 Protocol->SendMessage(4, 0x04, req);
362 void N6110_ReplyGetAuthentication(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
364 #if defined WIN32 || !defined HAVE_SNPRINTF
365 sprintf(Current_IMEI, "%s", MessageBuffer+9);
366 sprintf(Current_Model, "%s", MessageBuffer+25);
367 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
369 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+9);
370 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+25);
371 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
375 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
376 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
377 fprintf(stdout, _(" Model: %s\n"), Current_Model);
378 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+31);
379 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+39);
380 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+44);
382 /* These bytes are probably the source of the "Accessory not connected"
383 messages on the phone when trying to emulate NCDS... I hope....
384 UPDATE: of course, now we have the authentication algorithm. */
385 fprintf(stdout, _(" Magic bytes: %02x %02x %02x %02x\n"), MessageBuffer[50], MessageBuffer[51], MessageBuffer[52], MessageBuffer[53]);
388 MagicBytes[0]=MessageBuffer[50];
389 MagicBytes[1]=MessageBuffer[51];
390 MagicBytes[2]=MessageBuffer[52];
391 MagicBytes[3]=MessageBuffer[53];
393 CurrentMagicError=GE_NONE;
396 /* This function provides Nokia authentication protocol.
398 This code is written specially for gnokii project by Odinokov Serge.
399 If you have some special requests for Serge just write him to
400 apskaita@post.omnitel.net or serge@takas.lt
402 Reimplemented in C by Pavel JanÃk ml.
404 Nokia authentication protocol is used in the communication between Nokia
405 mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software,
406 commercially sold by Nokia Corp.
408 The authentication scheme is based on the token send by the phone to the
409 software. The software does it's magic (see the function
410 FB61_GetNokiaAuth()) and returns the result back to the phone. If the
411 result is correct the phone responds with the message "Accessory
412 connected!" displayed on the LCD. Otherwise it will display "Accessory not
413 supported" and some functions will not be available for use.
415 The specification of the protocol is not publicly available, no comment. */
416 void N6110_GetNokiaAuth(unsigned char *Imei, unsigned char *MagicBytes, unsigned char *MagicResponse)
421 /* This is our temporary working area. */
423 unsigned char Temp[16];
425 /* Here we put FAC (Final Assembly Code) and serial number into our area. */
436 /* And now the TAC (Type Approval Code). */
443 /* And now we pack magic bytes from the phone. */
445 Temp[12] = MagicBytes[0];
446 Temp[13] = MagicBytes[1];
447 Temp[14] = MagicBytes[2];
448 Temp[15] = MagicBytes[3];
450 for (i=0; i<=11; i++)
454 switch (Temp[15] & 0x03) {
461 Temp[i+j] ^= Temp[i+12];
469 Temp[i + j] |= Temp[i + 12];
472 for (i=0; i<=15; i++)
475 for (i=0; i<=15; i++) {
477 switch (Temp[15 - i] & 0x06) {
499 MagicResponse[i] = j;
504 GSM_Error N6110_Authentication()
506 unsigned char connect1[] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x02};
507 unsigned char connect2[] = {N6110_FRAME_HEADER, 0x20, 0x02};
508 unsigned char connect3[] = {N6110_FRAME_HEADER, 0x0d, 0x01, 0x00, 0x02};
509 unsigned char connect4[] = {N6110_FRAME_HEADER, 0x10};
511 unsigned char magic_connect[] = {N6110_FRAME_HEADER,
514 /* The real magic goes here ... These bytes are filled in with the
515 function N6110_GetNokiaAuth(). */
517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520 /* NOKIA&GNOKII Accessory */
522 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x26, 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x20,
523 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x79,
525 0x00, 0x00, 0x00, 0x00};
528 fprintf(stdout,_("Making authentication!\n"));
531 usleep(100); Protocol->SendMessage(7, 0x02, connect1);
532 usleep(100); Protocol->SendMessage(5, 0x02, connect2);
533 usleep(100); Protocol->SendMessage(7, 0x02, connect3);
535 CurrentMagicError = GE_BUSY;
537 usleep(100); Protocol->SendMessage(4, 0x64, connect4);
538 if (NULL_WaitUntil(50,&CurrentMagicError)!=GE_NONE) return GE_TIMEOUT;
540 N6110_GetNokiaAuth(Current_IMEI, MagicBytes, magic_connect+4);
542 Protocol->SendMessage(45, 0x64, magic_connect);
545 fprintf(stdout,_("End of authentication!\n"));
551 /* Initialise variables and state machine. */
552 GSM_Error N6110_Initialise(char *port_device, char *initlength,
553 GSM_ConnectionType connection,
554 void (*rlp_callback)(RLP_F96Frame *frame))
556 unsigned char init_char = N6110_SYNC_BYTE;
557 unsigned char end_init_char = N6110_IR_END_SYNC_BYTE;
562 if (Protocol->Initialise(port_device,initlength,connection,rlp_callback)!=GE_NONE)
564 return GE_NOTSUPPORTED;
567 switch (CurrentConnectionType) {
570 /* We don't think about authentication in Irda, because
571 AFAIK there are no phones working over sockets
572 and having authentication. In MBUS it doesn't work */
575 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
577 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
579 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
581 CurrentLinkOK = true;
587 InitLength = atoi(initlength);
589 if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
590 InitLength = 250; /* This is the usual value, lower may work. */
593 if (CurrentConnectionType==GCT_Infrared ||
594 CurrentConnectionType==GCT_Tekram) {
596 fprintf(stdout,_("Setting infrared for FBUS communication...\n"));
598 device_changespeed(9600);
602 fprintf(stdout,_("Writing init chars...."));
605 /* Initialise link with phone or what have you */
606 /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
608 for (count = 0; count < InitLength; count ++) {
609 if (CurrentConnectionType!=GCT_Infrared &&
610 CurrentConnectionType!=GCT_Tekram) usleep(100);
611 Protocol->WritePhone(1,&init_char);
614 if (CurrentConnectionType==GCT_Infrared ||
615 CurrentConnectionType==GCT_Tekram) {
616 Protocol->WritePhone(1,&end_init_char);
621 fprintf(stdout,_("Done\n"));
624 if (CurrentConnectionType==GCT_Infrared ||
625 CurrentConnectionType==GCT_Tekram) {
626 device_changespeed(115200);
629 N6110_SendStatusRequest();
633 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
635 /* N51xx/61xx have something called authentication.
636 After making it phone display "Accessory connected"
637 and probably give access to some function (I'm not too sure about it !)
638 Anyway, I make it now for N51xx/61xx */
639 if (GetModelFeature (FN_AUTHENTICATION)!=0) {
640 if (N6110_Authentication()!=GE_NONE) return GE_TIMEOUT;
641 } else { /* No authentication */
642 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
644 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
650 fprintf(stdout,_("Unknown connection type in n6110.c!\n"));
658 /* This function translates GMT_MemoryType to N6110_MEMORY_xx */
659 int N6110_GetMemoryType(GSM_MemoryType memory_type)
664 switch (memory_type) {
666 case GMT_MT: result = N6110_MEMORY_MT; break;
667 case GMT_ME: result = N6110_MEMORY_ME; break;
668 case GMT_SM: result = N6110_MEMORY_SM; break;
669 case GMT_FD: result = N6110_MEMORY_FD; break;
670 case GMT_ON: result = N6110_MEMORY_ON; break;
671 case GMT_EN: result = N6110_MEMORY_EN; break;
672 case GMT_DC: result = N6110_MEMORY_DC; break;
673 case GMT_RC: result = N6110_MEMORY_RC; break;
674 case GMT_MC: result = N6110_MEMORY_MC; break;
675 default : result = N6110_MEMORY_XX;
682 void N6110_ReplyCallDivert(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
684 switch (MessageBuffer[3]) {
689 fprintf(stdout, _("Message: Call divert status received\n"));
690 fprintf(stdout, _(" Divert type: "));
691 switch (MessageBuffer[6]) {
692 case 0x43: fprintf(stdout, _("when busy"));break;
693 case 0x3d: fprintf(stdout, _("when not answered"));break;
694 case 0x3e: fprintf(stdout, _("when phone off or no coverage"));break;
695 case 0x15: fprintf(stdout, _("all types of diverts"));break; //?
696 case 0x02: fprintf(stdout, _("all types of diverts"));break; //?
697 default: fprintf(stdout, _("unknown %i"),MessageBuffer[6]);break;
699 fprintf(stdout, _("\n Calls type : "));
700 if (MessageBuffer[6]==0x02)
701 fprintf(stdout, _("voice, fax & data")); //?
703 switch (MessageBuffer[8]) {
704 case 0x0b: fprintf(stdout, _("voice"));break;
705 case 0x0d: fprintf(stdout, _("fax"));break;
706 case 0x19: fprintf(stdout, _("data"));break;
707 default: fprintf(stdout, _("unknown %i"),MessageBuffer[8]);break;
710 fprintf(stdout, _("\n"));
711 if (MessageBuffer[10]==0x01) {
712 fprintf(stdout, _(" Status : active\n"));
713 fprintf(stdout, _(" Timeout : %i seconds\n"),MessageBuffer[45]);
714 fprintf(stdout, _(" Number : %s\n"),GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
716 fprintf(stdout, _(" Status : deactivated\n"));
720 if (CurrentCallDivert!=NULL) {
721 switch (MessageBuffer[6]) {
722 case 0x43: CurrentCallDivert->DType=GSM_CDV_Busy;break;
723 case 0x3d: CurrentCallDivert->DType=GSM_CDV_NoAnswer;break;
724 case 0x3e: CurrentCallDivert->DType=GSM_CDV_OutOfReach;break;
725 case 0x15: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
726 case 0x02: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
729 if (MessageBuffer[6]==0x02) //?
730 CurrentCallDivert->CType=GSM_CDV_AllCalls;
732 switch (MessageBuffer[8]) {
733 case 0x0b: CurrentCallDivert->CType=GSM_CDV_VoiceCalls;break;
734 case 0x0d: CurrentCallDivert->CType=GSM_CDV_FaxCalls; break;
735 case 0x19: CurrentCallDivert->CType=GSM_CDV_DataCalls; break;
739 if (MessageBuffer[10]==0x01) {
740 CurrentCallDivert->Enabled=true;
741 CurrentCallDivert->Timeout=MessageBuffer[45];
742 strcpy(CurrentCallDivert->Number,GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
744 CurrentCallDivert->Enabled=false;
746 CurrentCallDivertError=GE_NONE;
752 fprintf(stdout, _("Message: Call divert status receiving error ?\n"));
754 CurrentCallDivertError=GE_UNKNOWN;
759 GSM_Error N6110_CallDivert(GSM_CallDivert *cd)
761 char req[55] = { N6110_FRAME_HEADER, 0x01,
762 0x00, /* operation */
764 0x00, /* divert type */
765 0x00, /* call type */
771 switch (cd->Operation) {
772 case GSM_CDV_Register:
776 req[29]= GSM_PackSemiOctetNumber(cd->Number, req + 9, false);
777 req[52]= cd->Timeout;
780 case GSM_CDV_Erasure:
781 case GSM_CDV_Disable:
788 return GE_NOTIMPLEMENTED;
792 case GSM_CDV_AllTypes : req[6] = 0x15; break;
793 case GSM_CDV_Busy : req[6] = 0x43; break;
794 case GSM_CDV_NoAnswer : req[6] = 0x3d; break;
795 case GSM_CDV_OutOfReach: req[6] = 0x3e; break;
796 default: return GE_NOTIMPLEMENTED;
799 if ((cd->DType == GSM_CDV_AllTypes) &&
800 (cd->CType == GSM_CDV_AllCalls))
804 case GSM_CDV_AllCalls : break;
805 case GSM_CDV_VoiceCalls: req[7] = 0x0b; break;
806 case GSM_CDV_FaxCalls : req[7] = 0x0d; break;
807 case GSM_CDV_DataCalls : req[7] = 0x19; break;
808 default: return GE_NOTIMPLEMENTED;
811 CurrentCallDivert = cd;
813 error=NULL_SendMessageSequence
814 (100, &CurrentCallDivertError, length, 0x06, req);
816 CurrentCallDivert = NULL;
821 GSM_Error N6110_Tests()
823 unsigned char buffer[3]={0x00,0x01,0xcf};
824 unsigned char buffer3[8]={0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00};
828 error=N6110_EnableExtendedCommands(0x01);
829 if (error!=GE_NONE) return error;
831 //make almost all tests
832 Protocol->SendMessage(8, 0x40, buffer3);
834 while (GSM->Initialise(PortDevice, "50", CurrentConnectionType, CurrentRLP_RXCallback)!=GE_NONE) {};
838 return NULL_SendMessageSequence
839 (200, &CurrentNetworkInfoError, 3, 0x40, buffer);
842 void N6110_DisplayTestsInfo(u8 *MessageBuffer) {
846 CurrentNetworkInfoError=GE_NONE;
848 for (i=0;i<MessageBuffer[3];i++) {
850 case 0: fprintf(stdout,_("Unknown(%i) "),i);break;
851 case 1: fprintf(stdout,_("MCU ROM checksum "));break;
852 case 2: fprintf(stdout,_("MCU RAM interface "));break;
853 case 3: fprintf(stdout,_("MCU RAM component "));break;
854 case 4: fprintf(stdout,_("MCU EEPROM interface "));break;
855 case 5: fprintf(stdout,_("MCU EEPROM component "));break;
856 case 6: fprintf(stdout,_("Real Time Clock battery "));break;
857 case 7: fprintf(stdout,_("CCONT interface "));break;
858 case 8: fprintf(stdout,_("AD converter "));break;
859 case 9: fprintf(stdout,_("SW Reset "));break;
860 case 10:fprintf(stdout,_("Power Off "));break;
861 case 11:fprintf(stdout,_("Security Data "));break;
862 case 12:fprintf(stdout,_("EEPROM Tune checksum "));break;
863 case 13:fprintf(stdout,_("PPM checksum "));break;
864 case 14:fprintf(stdout,_("MCU download DSP "));break;
865 case 15:fprintf(stdout,_("DSP alive "));break;
866 case 16:fprintf(stdout,_("COBBA serial "));break;
867 case 17:fprintf(stdout,_("COBBA paraller "));break;
868 case 18:fprintf(stdout,_("EEPROM security checksum"));break;
869 case 19:fprintf(stdout,_("PPM validity "));break;
870 case 20:fprintf(stdout,_("Warranty state "));break;
871 case 21:fprintf(stdout,_("Simlock check "));break;
872 case 22:fprintf(stdout,_("IMEI check? "));break;//from PC-Locals.is OK?
873 default:fprintf(stdout,_("Unknown(%i) "),i);break;
875 switch (MessageBuffer[4+i]) {
876 case 0: fprintf(stdout,_(" : done, result OK"));break;
877 case 0xff:fprintf(stdout,_(" : not done, result unknown"));break;
878 case 254: fprintf(stdout,_(" : done, result NOT OK"));break;
879 default: fprintf(stdout,_(" : result unknown(%i)"),MessageBuffer[4+i]);break;
881 fprintf(stdout,_("\n"));
885 void N6110_ReplySimlockInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
892 fprintf(stdout, _("Message: Simlock info received\n"));
895 for (i=0; i < 12; i++)
898 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] >> 4)));
901 if (j==5 || j==15) fprintf(stdout, _("\n"));
904 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] & 0x0f)));
908 if (j==20 || j==24) fprintf(stdout, _("\n"));
911 if ((MessageBuffer[6] & 1) == 1) fprintf(stdout,_("lock 1 closed\n"));
912 if ((MessageBuffer[6] & 2) == 2) fprintf(stdout,_("lock 2 closed\n"));
913 if ((MessageBuffer[6] & 4) == 4) fprintf(stdout,_("lock 3 closed\n"));
914 if ((MessageBuffer[6] & 8) == 8) fprintf(stdout,_("lock 4 closed\n"));
916 /* I'm not sure here at all */
917 if ((MessageBuffer[5] & 1) == 1) fprintf(stdout,_("lock 1 - user\n"));
918 if ((MessageBuffer[5] & 2) == 2) fprintf(stdout,_("lock 2 - user\n"));
919 if ((MessageBuffer[5] & 4) == 4) fprintf(stdout,_("lock 3 - user\n"));
920 if ((MessageBuffer[5] & 8) == 8) fprintf(stdout,_("lock 4 - user\n"));
922 fprintf(stdout,_("counter for lock1: %i\n"),MessageBuffer[21]);
923 fprintf(stdout,_("counter for lock2: %i\n"),MessageBuffer[22]);
924 fprintf(stdout,_("counter for lock3: %i\n"),MessageBuffer[23]);
925 fprintf(stdout,_("counter for lock4: %i\n"),MessageBuffer[24]);
930 for (i=0; i < 12; i++)
933 uni[j]='0' + (MessageBuffer[9+i] >> 4);
938 uni[j]='0' + (MessageBuffer[9+i] & 0x0f);
944 strncpy(CurrentSimLock->simlocks[0].data,uni,5);
945 CurrentSimLock->simlocks[0].data[5]=0;
946 strncpy(CurrentSimLock->simlocks[3].data,uni+5,10);
947 CurrentSimLock->simlocks[3].data[10]=0;
948 strncpy(CurrentSimLock->simlocks[1].data,uni+16,4);
949 CurrentSimLock->simlocks[1].data[4]=0;
950 strncpy(CurrentSimLock->simlocks[2].data,uni+20,4);
951 CurrentSimLock->simlocks[2].data[4]=0;
953 CurrentSimLock->simlocks[0].enabled=((MessageBuffer[6] & 1) == 1);
954 CurrentSimLock->simlocks[1].enabled=((MessageBuffer[6] & 2) == 2);
955 CurrentSimLock->simlocks[2].enabled=((MessageBuffer[6] & 4) == 4);
956 CurrentSimLock->simlocks[3].enabled=((MessageBuffer[6] & 8) == 8);
958 CurrentSimLock->simlocks[0].factory=((MessageBuffer[5] & 1) != 1);
959 CurrentSimLock->simlocks[1].factory=((MessageBuffer[5] & 2) != 2);
960 CurrentSimLock->simlocks[2].factory=((MessageBuffer[5] & 4) != 4);
961 CurrentSimLock->simlocks[3].factory=((MessageBuffer[5] & 8) != 8);
963 CurrentSimLock->simlocks[0].counter=MessageBuffer[21];
964 CurrentSimLock->simlocks[1].counter=MessageBuffer[22];
965 CurrentSimLock->simlocks[2].counter=MessageBuffer[23];
966 CurrentSimLock->simlocks[3].counter=MessageBuffer[24];
968 CurrentSimlockInfoError=GE_NONE;
971 GSM_Error N6110_SimlockInfo(GSM_AllSimlocks *siml)
974 unsigned char req[] = {0x00,0x01,0x8a,0x00};
975 error=N6110_EnableExtendedCommands(0x01);
976 if (error!=GE_NONE) return error;
980 return NULL_SendMessageSequence (50, &CurrentSimlockInfoError, 4, 0x40, req);
983 void N6110_ReplyResetPhoneSettings(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
986 fprintf(stdout, _("Message: Resetting phone settings\n"));
989 CurrentResetPhoneSettingsError=GE_NONE;
992 GSM_Error N6110_ResetPhoneSettings()
995 unsigned char req[] = {0x00,0x01,0x65,0x08,0x00};
996 error=N6110_EnableExtendedCommands(0x01);
997 if (error!=GE_NONE) return error;
999 return NULL_SendMessageSequence
1000 (50, &CurrentResetPhoneSettingsError, 5, 0x40, req);
1002 GSM_Error N6110_GetManufacturer(char *manufacturer)
1004 strcpy (manufacturer, "Nokia");
1008 GSM_Error N6110_GetVoiceMailbox ( GSM_PhonebookEntry *entry)
1010 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
1014 CurrentPhonebookEntry = entry;
1016 req[4] = N6110_MEMORY_VOICE;
1017 req[5] = 0x00; /* Location - isn't important, but... */
1019 error=NULL_SendMessageSequence
1020 (20, &CurrentPhonebookError, 7, 0x03, req);
1022 CurrentPhonebookEntry = NULL;
1027 void N6110_ReplyGetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1031 GSM_Bitmap NullBitmap;
1033 DecodeNetworkCode(MessageBuffer+5, NullBitmap.netcode);
1038 fprintf(stdout, _("Message: Info about downloaded operator name received: %s network (for gnokii \"%s\", for phone \""),
1040 GSM_GetNetworkName(NullBitmap.netcode));
1044 while (MessageBuffer[count]!=0) {
1046 fprintf(stdout,_("%c"),MessageBuffer[count]);
1051 strcpy(CurrentGetOperatorNameNetwork->Code, NullBitmap.netcode);
1052 strncpy(CurrentGetOperatorNameNetwork->Name, MessageBuffer+i,count-i+1);
1055 fprintf(stdout,_("\")\n"));
1058 CurrentGetOperatorNameError=GE_NONE;
1061 GSM_Error N6110_GetOperatorName (GSM_Network *operator)
1063 unsigned char req[] = { 0x00,0x01,0x8c,0x00};
1067 error=N6110_EnableExtendedCommands(0x01);
1068 if (error!=GE_NONE) return error;
1070 CurrentGetOperatorNameNetwork = operator;
1072 error=NULL_SendMessageSequence
1073 (20, &CurrentGetOperatorNameError, 4, 0x40, req);
1075 CurrentGetOperatorNameNetwork = NULL;
1080 void N6110_ReplySetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1083 fprintf(stdout, _("Message: Downloaded operator name changed\n"));
1086 CurrentSetOperatorNameError=GE_NONE;
1089 GSM_Error N6110_SetOperatorName (GSM_Network *operator)
1091 unsigned char req[256] = { 0x00,0x01,0x8b,0x00,
1092 0x00,0x00, /* MCC */
1097 error=N6110_EnableExtendedCommands(0x01);
1098 if (error!=GE_NONE) return error;
1100 EncodeNetworkCode(req+4,operator->Code);
1102 strncpy(req+7,operator->Name,200);
1104 return NULL_SendMessageSequence
1105 (20, &CurrentSetOperatorNameError, 8+strlen(operator->Name), 0x40, req);
1108 void N6110_ReplyGetMemoryStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1110 switch (MessageBuffer[3]) {
1115 fprintf(stdout, _("Message: Memory status received:\n"));
1117 fprintf(stdout, _(" Memory Type: %s\n"), N6110_MemoryType_String[MessageBuffer[4]]);
1118 fprintf(stdout, _(" Used: %d\n"), MessageBuffer[6]);
1119 fprintf(stdout, _(" Free: %d\n"), MessageBuffer[5]);
1122 CurrentMemoryStatus->Used = MessageBuffer[6];
1123 CurrentMemoryStatus->Free = MessageBuffer[5];
1124 CurrentMemoryStatusError = GE_NONE;
1131 switch (MessageBuffer[4]) {
1133 fprintf(stdout, _("Message: Memory status error, phone is probably powered off.\n"));break;
1135 fprintf(stdout, _("Message: Memory status error, memory type not supported by phone model.\n"));break;
1137 fprintf(stdout, _("Message: Memory status error, waiting for security code.\n"));break;
1139 fprintf(stdout, _("Message: Unknown Memory status error, subtype (MessageBuffer[4]) = %02x\n"),MessageBuffer[4]);break;
1143 switch (MessageBuffer[4]) {
1144 case 0x6f:CurrentMemoryStatusError = GE_TIMEOUT;break;
1145 case 0x7d:CurrentMemoryStatusError = GE_INTERNALERROR;break;
1146 case 0x8d:CurrentMemoryStatusError = GE_INVALIDSECURITYCODE;break;
1155 /* This function is used to get storage status from the phone. It currently
1156 supports two different memory areas - internal and SIM. */
1157 GSM_Error N6110_GetMemoryStatus(GSM_MemoryStatus *Status)
1159 unsigned char req[] = { N6110_FRAME_HEADER,
1160 0x07, /* MemoryStatus request */
1161 0x00 /* MemoryType */
1166 CurrentMemoryStatus = Status;
1168 req[4] = N6110_GetMemoryType(Status->MemoryType);
1170 error=NULL_SendMessageSequence
1171 (20, &CurrentMemoryStatusError, 5, 0x03, req);
1173 CurrentMemoryStatus = NULL;
1178 void N6110_ReplyGetNetworkInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1180 GSM_NetworkInfo NullNetworkInfo;
1182 /* Make sure we are expecting NetworkInfo frame */
1183 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY) {
1185 fprintf(stdout, _("Message: Network informations:\n"));
1189 fprintf(stdout, _("Message: Network informations not requested, but received:\n"));
1193 sprintf(NullNetworkInfo.NetworkCode, "%x%x%x %x%x", MessageBuffer[14] & 0x0f, MessageBuffer[14] >>4, MessageBuffer[15] & 0x0f, MessageBuffer[16] & 0x0f, MessageBuffer[16] >>4);
1195 sprintf(NullNetworkInfo.CellID, "%02x%02x", MessageBuffer[10], MessageBuffer[11]);
1197 sprintf(NullNetworkInfo.LAC, "%02x%02x", MessageBuffer[12], MessageBuffer[13]);
1200 fprintf(stdout, _(" CellID: %s\n"), NullNetworkInfo.CellID);
1201 fprintf(stdout, _(" LAC: %s\n"), NullNetworkInfo.LAC);
1202 fprintf(stdout, _(" Network code: %s\n"), NullNetworkInfo.NetworkCode);
1203 fprintf(stdout, _(" Network name: %s (%s)\n"),
1204 GSM_GetNetworkName(NullNetworkInfo.NetworkCode),
1205 GSM_GetCountryName(NullNetworkInfo.NetworkCode));
1206 fprintf(stdout, _(" Status: "));
1208 switch (MessageBuffer[8]) {
1209 case 0x01: fprintf(stdout, _("home network selected")); break;
1210 case 0x02: fprintf(stdout, _("roaming network")); break;
1211 case 0x03: fprintf(stdout, _("requesting network")); break;
1212 case 0x04: fprintf(stdout, _("not registered in the network")); break;
1213 default: fprintf(stdout, _("unknown"));
1216 fprintf(stdout, "\n");
1218 fprintf(stdout, _(" Network selection: %s\n"), MessageBuffer[9]==1?_("manual"):_("automatic"));
1221 /* Make sure we are expecting NetworkInfo frame */
1222 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY)
1223 *CurrentNetworkInfo=NullNetworkInfo;
1225 CurrentNetworkInfoError = GE_NONE;
1228 GSM_Error N6110_GetNetworkInfo(GSM_NetworkInfo *NetworkInfo)
1230 unsigned char req[] = { N6110_FRAME_HEADER,
1236 CurrentNetworkInfo = NetworkInfo;
1238 error=NULL_SendMessageSequence
1239 (20, &CurrentNetworkInfoError, 4, 0x0a, req);
1241 CurrentNetworkInfo = NULL;
1246 void N6110_ReplyGetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1251 fprintf(stdout, _("Message: Product Profile Settings received -"));
1252 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),MessageBuffer[3+i]);
1253 fprintf(stdout, _("\n"));
1256 for (i=0;i<4;i++) CurrentPPS[i]=MessageBuffer[3+i];
1258 CurrentProductProfileSettingsError=GE_NONE;
1261 GSM_Error N6110_GetProductProfileSetting (GSM_PPS *PPS)
1263 unsigned char req[] = { 0x00, 0x01,0x6a };
1269 error=N6110_EnableExtendedCommands(0x01);
1270 if (error!=GE_NONE) return error;
1272 error=NULL_SendMessageSequence
1273 (20, &CurrentProductProfileSettingsError, 3, 0x40, req);
1274 if (error!=GE_NONE) return error;
1276 switch (PPS->Name) {
1277 case PPS_ALS : PPS->bool_value=(CurrentPPS[1]&32); break;
1278 case PPS_GamesMenu: PPS->bool_value=(CurrentPPS[3]&64); break;
1279 case PPS_HRData : PPS->bool_value=(CurrentPPS[0]&64); break;
1280 case PPS_14400Data: PPS->bool_value=(CurrentPPS[0]&128);break;
1281 case PPS_EFR : PPS->int_value =(CurrentPPS[0]&1) +(CurrentPPS[0]&2); break;
1282 case PPS_FR : PPS->int_value =(CurrentPPS[0]&16)/16+(CurrentPPS[0]&32)/16;break;
1283 case PPS_HR : PPS->int_value =(CurrentPPS[0]&4)/4 +(CurrentPPS[0]&8)/4; break;
1284 case PPS_VibraMenu: PPS->bool_value=(CurrentPPS[4]&64); break;
1285 case PPS_LCDContrast:
1289 if (CurrentPPS[3]&j) PPS->int_value=PPS->int_value+j;
1292 PPS->int_value=PPS->int_value*100/32;
1300 void N6110_ReplySetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1305 fprintf(stdout, _("Message: Product Profile Settings set to"));
1306 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),CurrentPPS[i]);
1307 fprintf(stdout, _("\n"));
1310 CurrentProductProfileSettingsError=GE_NONE;
1313 GSM_Error N6110_SetProductProfileSetting (GSM_PPS *PPS)
1315 unsigned char req[] = { 0x00, 0x01,0x6b,
1316 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */
1317 unsigned char settings[32];
1325 error=N6110_EnableExtendedCommands(0x01);
1326 if (error!=GE_NONE) return error;
1328 OldPPS.Name=PPS_ALS;
1329 error=N6110_GetProductProfileSetting(&OldPPS);
1330 if (error!=GE_NONE) return error;
1333 for (i=0;i<32;i++) {
1334 if (CurrentPPS[z]&j)
1345 fprintf(stdout,_("Current settings: "));
1346 for (i=0;i<32;i++) {
1347 fprintf(stdout,_("%c"),settings[i]);
1349 fprintf(stdout,_("\n"));
1352 switch (PPS->Name) {
1353 case PPS_ALS :settings[10]=PPS->bool_value?'1':'0';break;
1354 case PPS_HRData :settings[ 5]=PPS->bool_value?'1':'0';break;
1355 case PPS_14400Data:settings[ 6]=PPS->bool_value?'1':'0';break;
1360 for (i=0;i<32;i++) {
1361 if (settings[i]=='1') req[z+3]=req[z+3]+j;
1369 fprintf(stdout,_("Current settings: "));
1371 fprintf(stdout,_("%i "),req[i+3]);
1373 fprintf(stdout,_("\n"));
1377 CurrentPPS[i]=req[i+3];
1380 return NULL_SendMessageSequence
1381 (20, &CurrentProductProfileSettingsError, 7, 0x40, req);
1384 void N6110_ReplyPressKey(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1386 if (MessageBuffer[4]==CurrentPressKeyEvent) CurrentPressKeyError=GE_NONE;
1387 else CurrentPressKeyError=GE_UNKNOWN; /* MessageBuffer[4] = 0x05 */
1389 fprintf(stdout, _("Message: Result of key "));
1390 switch (MessageBuffer[4])
1392 case PRESSPHONEKEY: fprintf(stdout, _("press OK\n"));break;
1393 case RELEASEPHONEKEY: fprintf(stdout, _("release OK\n"));break;
1394 default: fprintf(stdout, _("press or release - error\n"));break;
1399 GSM_Error N6110_PressKey(int key, int event)
1401 unsigned char req[] = {N6110_FRAME_HEADER, 0x42, 0x01, 0x00, 0x01};
1403 req[4]=event; /* if we press or release key */
1406 CurrentPressKeyEvent=event;
1408 return NULL_SendMessageSequence
1409 (10, &CurrentPressKeyError, 7, 0x0c, req);
1412 void N6110_ReplyDisplayOutput(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1414 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
1421 switch(MessageBuffer[3]) {
1423 /* Phone sends displayed texts */
1425 NewX=MessageBuffer[6];
1426 NewY=MessageBuffer[5];
1428 DecodeUnicode (uni, MessageBuffer+8, MessageBuffer[7]);
1431 fprintf(stdout, _("New displayed text (%i %i): \"%s\"\n"),NewX,NewY,uni);
1434 while (N6110_GetModel(model) != GE_NONE)
1437 /* With these rules it works almost excellent with my N5110 */
1438 /* I don't have general rule :-(, that's why you must experiment */
1439 /* with your phone. Nokia could make it better. MW */
1440 /* It's almost OK for N5110*/
1441 /* FIX ME: it will be the same for N5130 and 3210 too*/
1442 if (!strcmp(model,"NSE-1"))
1444 /* OldX==1000 means - it's first time */
1448 for (i=0;i<5+1;i++) {
1449 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1454 if ((OldX==0 && OldY==31 && NewX==29 && NewY==46) ||
1455 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1456 /* Clean the line with current text */
1457 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1459 /* Inserts text into table */
1460 for (i=0; i<MessageBuffer[7];i++) {
1461 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1466 if ((OldX==0 && OldY==21 && NewX==0 && NewY==10) ||
1467 (OldX==0 && OldY==10 && NewX==35 && NewY==46)) {
1469 if ((OldX!=0 && NewX==0 && NewY!=6) ||
1470 (OldX==0 && NewX!=0 && OldY!=13 && OldY!=22) ||
1471 (OldX==0 && NewX==0 && NewY<OldY && (NewY!=13 || OldY!=26)) ||
1472 (OldY==5 && NewY!=5) ||
1473 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1475 /* Writes "old" screen */
1476 for (i=0;i<5+1;i++) {
1477 for (j=0;j<27+1;j++) {fprintf(stdout,_("%c"),PhoneScreen[i][j]);}
1478 fprintf(stdout,_("\n"));
1482 for (i=0;i<5+1;i++) {
1483 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1488 /* Clean the line with current text */
1489 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1491 /* Inserts text into table */
1492 for (i=0; i<MessageBuffer[7];i++) {
1493 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1500 fprintf(stdout, _("%s\n"),uni);
1508 if (MessageBuffer[4]==1)
1512 fprintf(stdout, _("Display output successfully disabled/enabled.\n"));
1515 CurrentDisplayOutputError=GE_NONE;
1522 GSM_Error SetDisplayOutput(unsigned char state)
1524 unsigned char req[] = { N6110_FRAME_HEADER,
1529 return NULL_SendMessageSequence
1530 (30, &CurrentDisplayOutputError, 5, 0x0d, req);
1533 GSM_Error N6110_EnableDisplayOutput()
1535 return SetDisplayOutput(0x01);
1538 GSM_Error N6110_DisableDisplayOutput()
1540 return SetDisplayOutput(0x02);
1543 /* If it is interesting for somebody: we can use 0x40 msg for it
1544 and it will work for all phones. See n6110.txt for details */
1545 GSM_Error N6110_AnswerCall(char s)
1547 unsigned char req0[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,0x07, 0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
1548 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80};
1549 unsigned char req[] = { N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
1554 fprintf(stdout,_("Answering call %d\n\r"),s);
1557 Protocol->SendMessage(sizeof(req0), 0x01, req0);
1560 return NULL_SendMessageSequence
1561 (20, &CurrentMagicError, sizeof(req) , 0x01, req);
1564 void N6110_ReplyGetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1566 switch (MessageBuffer[3]) {
1568 /* Profile feature */
1571 switch(GetModelFeature (FN_PROFILES)) {
1573 switch (MessageBuffer[6]) {
1574 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8]; break;
1575 case 0x01: CurrentProfile->CallAlert = MessageBuffer[8]; break;
1576 case 0x02: CurrentProfile->Ringtone = MessageBuffer[8]; break;
1577 case 0x03: CurrentProfile->Volume = MessageBuffer[8]; break;
1578 case 0x04: CurrentProfile->MessageTone = MessageBuffer[8]; break;
1579 case 0x05: CurrentProfile->Vibration = MessageBuffer[8]; break;
1580 case 0x06: CurrentProfile->WarningTone = MessageBuffer[8]; break;
1581 case 0x07: CurrentProfile->ScreenSaver = MessageBuffer[8]; break;
1584 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1590 switch (MessageBuffer[6]) {
1591 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8];break;
1592 case 0x01: CurrentProfile->Lights = MessageBuffer[8];break;
1593 case 0x02: CurrentProfile->CallAlert = MessageBuffer[8];break;
1594 case 0x03: CurrentProfile->Ringtone = MessageBuffer[8];break;
1595 case 0x04: CurrentProfile->Volume = MessageBuffer[8];break;
1596 case 0x05: CurrentProfile->MessageTone = MessageBuffer[8];break;
1597 case 0x06: CurrentProfile->Vibration = MessageBuffer[8];break;
1598 case 0x07: CurrentProfile->WarningTone = MessageBuffer[8];break;
1599 case 0x08: CurrentProfile->CallerGroups = MessageBuffer[8];break;
1600 case 0x09: CurrentProfile->AutomaticAnswer = MessageBuffer[8];break;
1603 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1610 CurrentProfileError = GE_NONE;
1613 /* Incoming profile name */
1616 if (MessageBuffer[9] == 0x00) {
1617 CurrentProfile->DefaultName=MessageBuffer[8];
1619 CurrentProfile->DefaultName=-1;
1621 /* Here name is in Unicode */
1622 if (GetModelFeature (FN_PROFILES)==F_PROF33) {
1623 DecodeUnicode (CurrentProfile->Name, MessageBuffer+10, MessageBuffer[9]/2);
1626 sprintf(CurrentProfile->Name, MessageBuffer + 10, MessageBuffer[9]);
1627 CurrentProfile->Name[MessageBuffer[9]] = '\0';
1631 CurrentProfileError = GE_NONE;
1637 /* Needs SIM card with PIN in phone */
1638 GSM_Error N6110_GetProfile(GSM_Profile *Profile)
1642 unsigned char name_req[] = { N6110_FRAME_HEADER, 0x1a, 0x00};
1643 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x13, 0x01, 0x00, 0x00};
1647 CurrentProfile = Profile;
1649 /* When after sending all frames feature==253, it means, that it is not
1651 CurrentProfile->KeypadTone=253;
1652 CurrentProfile->Lights=253;
1653 CurrentProfile->CallAlert=253;
1654 CurrentProfile->Ringtone=253;
1655 CurrentProfile->Volume=253;
1656 CurrentProfile->MessageTone=253;
1657 CurrentProfile->WarningTone=253;
1658 CurrentProfile->Vibration=253;
1659 CurrentProfile->CallerGroups=253;
1660 CurrentProfile->ScreenSaver=253;
1661 CurrentProfile->AutomaticAnswer=253;
1663 name_req[4] = Profile->Number;
1665 error=NULL_SendMessageSequence
1666 (20, &CurrentProfileError, 5, 0x05, name_req);
1667 if (error!=GE_NONE) return error;
1669 for (i = 0x00; i <= 0x09; i++) {
1671 feat_req[5] = Profile->Number;
1675 error=NULL_SendMessageSequence
1676 (20, &CurrentProfileError, 7, 0x05, feat_req);
1677 if (error!=GE_NONE) return error;
1680 if (Profile->DefaultName > -1)
1682 switch(GetModelFeature (FN_PROFILES)) {
1684 switch (Profile->DefaultName) {
1685 case 0x00: sprintf(Profile->Name, "General");break;
1686 case 0x01: sprintf(Profile->Name, "Silent");break;
1687 case 0x02: sprintf(Profile->Name, "Descreet");break;
1688 case 0x03: sprintf(Profile->Name, "Loud");break;
1689 case 0x04: sprintf(Profile->Name, "My style");break;
1690 case 0x05: Profile->Name[0]=0;break;
1691 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1695 switch (Profile->DefaultName) {
1696 case 0x00: sprintf(Profile->Name, "Personal");break;
1697 case 0x01: sprintf(Profile->Name, "Car");break;
1698 case 0x02: sprintf(Profile->Name, "Headset");break;
1699 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1703 switch (Profile->DefaultName) {
1704 case 0x00: sprintf(Profile->Name, "General");break;
1705 case 0x01: sprintf(Profile->Name, "Silent");break;
1706 case 0x02: sprintf(Profile->Name, "Meeting");break;
1707 case 0x03: sprintf(Profile->Name, "Outdoor");break;
1708 case 0x04: sprintf(Profile->Name, "Pager");break;
1709 case 0x05: sprintf(Profile->Name, "Car");break;
1710 case 0x06: sprintf(Profile->Name, "Headset");break;
1711 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1721 void N6110_ReplySetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1723 switch (MessageBuffer[3]) {
1725 /* Profile feature change result */
1728 fprintf(stdout, _("Message: Profile feature change result.\n"));
1730 CurrentProfileError = GE_NONE;
1733 /* Profile name set result */
1736 fprintf(stdout, _("Message: Profile name change result.\n"));
1738 CurrentProfileError = GE_NONE;
1744 GSM_Error N6110_SetProfileFeature(u8 profile, u8 feature, u8 value)
1746 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x10, 0x01,
1749 feat_req[5]=profile;
1750 feat_req[6]=feature;
1753 return NULL_SendMessageSequence
1754 (20, &CurrentProfileError, 8, 0x05, feat_req);
1757 GSM_Error N6110_SetProfile(GSM_Profile *Profile)
1761 unsigned char name_req[40] = { N6110_FRAME_HEADER, 0x1c, 0x01, 0x03,
1766 name_req[7] = Profile->Number;
1767 name_req[8] = strlen(Profile->Name);
1768 name_req[6] = name_req[8] + 2;
1770 for (i = 0; i < name_req[8]; i++)
1771 name_req[9 + i] = Profile->Name[i];
1773 error=NULL_SendMessageSequence
1774 (20, &CurrentProfileError, name_req[8] + 9, 0x05, name_req);
1775 if (error!=GE_NONE) return error;
1777 for (i = 0x00; i <= 0x09; i++) {
1780 case 0x00: value = Profile->KeypadTone; break;
1781 case 0x01: value = Profile->Lights; break;
1782 case 0x02: value = Profile->CallAlert; break;
1783 case 0x03: value = Profile->Ringtone; break;
1784 case 0x04: value = Profile->Volume; break;
1785 case 0x05: value = Profile->MessageTone; break;
1786 case 0x06: value = Profile->Vibration; break;
1787 case 0x07: value = Profile->WarningTone; break;
1788 case 0x08: value = Profile->CallerGroups; break;
1789 case 0x09: value = Profile->AutomaticAnswer; break;
1790 default : value = 0; break;
1793 error=N6110_SetProfileFeature(Profile->Number,i,value);
1794 if (error!=GE_NONE) return error;
1800 bool N6110_SendRLPFrame(RLP_F96Frame *frame, bool out_dtx)
1802 u8 req[60] = { 0x00, 0xd9 };
1804 /* Discontinuos transmission (DTX). See section 5.6 of GSM 04.22 version
1810 memcpy(req+2, (u8 *) frame, 32);
1812 return (Protocol->SendFrame(32, 0xf0, req));
1815 void N6110_ReplyGetCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1823 switch (MessageBuffer[4]) {
1827 CurrentCalendarNote->Type=MessageBuffer[8];
1829 DecodeDateTime(MessageBuffer+9, &CurrentCalendarNote->Time);
1831 DecodeDateTime(MessageBuffer+16, &CurrentCalendarNote->Alarm);
1833 CurrentCalendarNote->Text[0]=0;
1835 if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
1837 if (CurrentCalendarNote->Type == GCN_REMINDER) i=1; //first char is subset
1838 switch (MessageBuffer[24]) {
1841 fprintf(stdout,_("Subset 3 in reminder note !\n"));
1843 while (i!=MessageBuffer[23]) {
1845 if (i!=MessageBuffer[23]-1) {
1846 if (MessageBuffer[24+i]>=0xc2) {
1847 DecodeWithUTF8Alphabet(MessageBuffer[24+i], MessageBuffer[24+i+1], &mychar1);
1848 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1849 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=mychar1;
1855 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1856 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=MessageBuffer[24+i];
1863 fprintf(stdout,_("Subset 2 in reminder note !\n"));
1865 while (i!=MessageBuffer[23]) {
1866 wc = MessageBuffer[24+i] | (0x00 << 8);
1867 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1868 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=
1869 DecodeWithUnicodeAlphabet(wc);
1875 fprintf(stdout,_("Subset 1 in reminder note !\n"));
1877 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1878 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1882 fprintf(stdout,_("Unknown subset in reminder note !\n"));
1884 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1885 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1889 memcpy(CurrentCalendarNote->Text,MessageBuffer+24,MessageBuffer[23]);
1890 CurrentCalendarNote->Text[MessageBuffer[23]]=0;
1893 if (CurrentCalendarNote->Type == GCN_CALL) {
1894 memcpy(CurrentCalendarNote->Phone,MessageBuffer+24+MessageBuffer[23]+1,MessageBuffer[24+MessageBuffer[23]]);
1895 CurrentCalendarNote->Phone[MessageBuffer[24+MessageBuffer[23]]]=0;
1898 CurrentCalendarNote->Recurrance=0;
1900 CurrentCalendarNote->AlarmType=0;
1903 fprintf(stdout, _("Message: Calendar note received.\n"));
1905 fprintf(stdout, _(" Date: %d-%02d-%02d\n"), CurrentCalendarNote->Time.Year,
1906 CurrentCalendarNote->Time.Month,
1907 CurrentCalendarNote->Time.Day);
1909 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentCalendarNote->Time.Hour,
1910 CurrentCalendarNote->Time.Minute,
1911 CurrentCalendarNote->Time.Second);
1913 /* Some messages do not have alarm set up */
1914 if (CurrentCalendarNote->Alarm.Year != 0) {
1915 fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"), CurrentCalendarNote->Alarm.Year,
1916 CurrentCalendarNote->Alarm.Month,
1917 CurrentCalendarNote->Alarm.Day);
1919 fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"), CurrentCalendarNote->Alarm.Hour,
1920 CurrentCalendarNote->Alarm.Minute,
1921 CurrentCalendarNote->Alarm.Second);
1924 fprintf(stdout, _(" Type: %d\n"), CurrentCalendarNote->Type);
1925 fprintf(stdout, _(" Text: %s\n"), CurrentCalendarNote->Text);
1927 if (CurrentCalendarNote->Type == GCN_CALL)
1928 fprintf(stdout, _(" Phone: %s\n"), CurrentCalendarNote->Phone);
1931 CurrentCalendarNoteError=GE_NONE;
1937 fprintf(stdout, _("Message: Calendar note not available\n"));
1940 CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;
1946 fprintf(stdout, _("Message: Calendar note error\n"));
1949 CurrentCalendarNoteError=GE_INTERNALERROR;
1955 GSM_Error N6110_GetCalendarNote(GSM_CalendarNote *CalendarNote)
1958 unsigned char req[] = { N6110_FRAME_HEADER,
1963 req[4]=CalendarNote->Location;
1965 CurrentCalendarNote = CalendarNote;
1967 error=NULL_SendMessageSequence
1968 (20, &CurrentCalendarNoteError, 5, 0x13, req);
1970 CurrentCalendarNote = NULL;
1975 void N6110_ReplyWriteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1978 switch(MessageBuffer[4]) {
1979 /* This message is also sent when the user enters the new entry on keypad */
1981 fprintf(stdout, _("Message: Calendar note write succesfull!\n"));break;
1983 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
1985 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
1987 fprintf(stdout, _("Unknown message of type 0x13 and subtype 0x65\n"));break;
1991 switch(MessageBuffer[4]) {
1992 case 0x01: CurrentCalendarNoteError=GE_NONE; break;
1993 case 0x73: CurrentCalendarNoteError=GE_INTERNALERROR; break;
1994 case 0x7d: CurrentCalendarNoteError=GE_INTERNALERROR; break;
1995 default : AppendLogText("Unknown msg\n",false); break;
1999 GSM_Error N6110_WriteCalendarNote(GSM_CalendarNote *CalendarNote)
2002 unsigned char req[200] = { N6110_FRAME_HEADER,
2004 0x00, /* Length of the rest of the frame. */
2005 0x00, /* The type of calendar note */
2006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2007 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2013 unsigned char meeting;
2014 unsigned char birthday;
2015 unsigned char reminder;
2016 } calendar_model_length;
2018 /* Length of entries */
2019 calendar_model_length calendar_lengths[] =
2021 /*model,CallTo,Meeting,Birthday,Reminder*/
2022 {"NHM-5",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2023 {"NHM-6",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2024 {"NSE-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 [HKEY_LOCAL_MACHINE\Software\Nokia\Data Suite\3.0\Calendar]
2025 {"NSM-1",0x1e,0x18,0x18,0x24}, //from NCDS3
2026 {"NSK-3",0x1e,0x14,0x14,0x1e}, //from NCDS3
2027 {"NSB-3",0x20,0x14,0x14,0x1e}, //from NCDS3
2028 {"", 0, 0, 0, 0 } //end of table
2039 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
2042 req[7]=CalendarNote->Type;
2044 EncodeDateTime(req+8, &CalendarNote->Time);
2045 req[14] = CalendarNote->Time.Timezone;
2047 if (CalendarNote->Alarm.Year) {
2048 EncodeDateTime(req+15, &CalendarNote->Alarm);
2049 req[21] = CalendarNote->Alarm.Timezone;
2052 req[22]=strlen(CalendarNote->Text);
2056 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2057 req[22]++; // one additional char
2058 req[current++]=0x01; //we use now subset 1
2061 for (i=0; i<strlen(CalendarNote->Text); i++) {
2063 mychar=CalendarNote->Text[i];
2064 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2065 if (EncodeWithUTF8Alphabet(mychar,&mychar1,&mychar2)) {
2066 req[current++]=mychar1;
2067 req[current++]=mychar2;
2068 req[23]=0x03; //use subset 3
2069 req[22]++; // one additional char
2074 /* Enables/disables blinking */
2075 if (mychar=='~') req[current++]=0x01;
2076 else req[current++]=mychar;
2080 req[current++]=strlen(CalendarNote->Phone);
2082 for (i=0; i<strlen(CalendarNote->Phone); i++)
2083 req[current++]=CalendarNote->Phone[i];
2085 while (N6110_GetModel(model) != GE_NONE)
2088 /* Checking maximal length */
2090 while (strcmp(calendar_lengths[i].model,"")) {
2091 if (!strcmp(calendar_lengths[i].model,model)) {
2092 switch (CalendarNote->Type) {
2093 case GCN_REMINDER:if (req[22]>calendar_lengths[i].reminder) return GE_TOOLONG;break;
2094 case GCN_MEETING :if (req[22]>calendar_lengths[i].meeting) return GE_TOOLONG;break;
2095 case GCN_BIRTHDAY:if (req[22]>calendar_lengths[i].birthday) return GE_TOOLONG;break;
2096 case GCN_CALL :if (strlen(CalendarNote->Phone)>calendar_lengths[i].call) return GE_TOOLONG;break;
2103 CurrentCalendarNote = CalendarNote;
2105 error=NULL_SendMessageSequence
2106 (20, &CurrentCalendarNoteError, current, 0x13, req);
2108 CurrentCalendarNote = NULL;
2113 void N6110_ReplyDeleteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2116 switch (MessageBuffer[4]) {
2117 /* This message is also sent when the user deletes an old entry on
2118 keypad or moves an old entry somewhere (there is also `write'
2120 case 0x01:fprintf(stdout, _("Message: Calendar note deleted\n"));break;
2121 case 0x93:fprintf(stdout, _("Message: Calendar note can't be deleted\n"));break;
2122 default :fprintf(stdout, _("Message: Calendar note deleting error\n"));break;
2126 switch (MessageBuffer[4]) {
2127 case 0x01:CurrentCalendarNoteError=GE_NONE;break;
2128 case 0x93:CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;break;
2129 default :CurrentCalendarNoteError=GE_INTERNALERROR;break;
2133 GSM_Error N6110_DeleteCalendarNote(GSM_CalendarNote *CalendarNote)
2136 unsigned char req[] = { N6110_FRAME_HEADER,
2140 req[4]=CalendarNote->Location;
2142 return NULL_SendMessageSequence (20, &CurrentCalendarNoteError, 5, 0x13, req);
2145 void N6110_ReplyRFBatteryLevel(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2148 fprintf(stdout, _("Message: Phone status received:\n"));
2149 fprintf(stdout, _(" Mode: "));
2151 switch (MessageBuffer[4]) {
2155 fprintf(stdout, _("registered within the network\n"));
2158 /* I was really amazing why is there a hole in the type of 0x02, now I
2160 case 0x02: fprintf(stdout, _("call in progress\n")); break; /* ringing or already answered call */
2161 case 0x03: fprintf(stdout, _("waiting for security code\n")); break;
2162 case 0x04: fprintf(stdout, _("powered off\n")); break;
2163 default : fprintf(stdout, _("unknown\n"));
2167 fprintf(stdout, _(" Power source: "));
2169 switch (MessageBuffer[7]) {
2171 case 0x01: fprintf(stdout, _("AC/DC\n")); break;
2172 case 0x02: fprintf(stdout, _("battery\n")); break;
2173 default : fprintf(stdout, _("unknown\n"));
2177 fprintf(stdout, _(" Battery Level: %d\n"), MessageBuffer[8]);
2178 fprintf(stdout, _(" Signal strength: %d\n"), MessageBuffer[5]);
2181 CurrentRFLevel=MessageBuffer[5];
2182 CurrentBatteryLevel=MessageBuffer[8];
2183 CurrentPowerSource=MessageBuffer[7];
2187 GSM_Error N6110_GetRFLevel(GSM_RFUnits *units, float *level)
2190 /* FIXME - these values are from 3810 code, may be incorrect. Map from
2191 values returned in status packet to the the values returned by the AT+CSQ
2193 float csq_map[5] = {0, 8, 16, 24, 31};
2198 char screen[NM_MAX_SCREEN_WIDTH];
2202 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2204 if (N6110_NetMonitor(1, screen)!=GE_NONE)
2205 return GE_INTERNALERROR;
2209 if (screen[4]!='-') {
2210 if (screen[5]=='9' && screen[6]>'4') rf_level=1;
2211 if (screen[5]=='9' && screen[6]<'5') rf_level=2;
2212 if (screen[5]=='8' && screen[6]>'4') rf_level=3;
2215 /* Arbitrary units. */
2216 if (*units == GRF_Arbitrary) {
2222 N6110_SendStatusRequest();
2224 /* Wait for timeout or other error. */
2225 while (timeout != 0 && CurrentRFLevel == -1 ) {
2228 return (GE_TIMEOUT);
2233 /* Make copy in case it changes. */
2234 rf_level = CurrentRFLevel;
2239 /* Now convert between the different units we support. */
2241 /* Arbitrary units. */
2242 if (*units == GRF_Arbitrary) {
2248 if (*units == GRF_CSQ) {
2251 *level = csq_map[rf_level];
2253 *level = 99; /* Unknown/undefined */
2259 /* Unit type is one we don't handle so return error */
2260 return (GE_INTERNALERROR);
2264 GSM_Error N6110_GetBatteryLevel(GSM_BatteryUnits *units, float *level)
2269 char screen[NM_MAX_SCREEN_WIDTH];
2271 CurrentBatteryLevel=-1;
2273 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2275 if (N6110_NetMonitor(23, screen)!=GE_NONE)
2280 if (screen[29]=='7') batt_level=3;
2281 if (screen[29]=='5') batt_level=2;
2282 if (screen[29]=='2') batt_level=1;
2284 /* Only units we handle at present are GBU_Arbitrary */
2285 if (*units == GBU_Arbitrary) {
2286 *level = batt_level;
2290 return (GE_INTERNALERROR);
2293 N6110_SendStatusRequest();
2295 /* Wait for timeout or other error. */
2296 while (timeout != 0 && CurrentBatteryLevel == -1 ) {
2299 return (GE_TIMEOUT);
2304 /* Take copy in case it changes. */
2305 batt_level = CurrentBatteryLevel;
2307 if (batt_level != -1) {
2309 /* Only units we handle at present are GBU_Arbitrary */
2310 if (*units == GBU_Arbitrary) {
2311 *level = batt_level;
2315 return (GE_INTERNALERROR);
2322 GSM_Error N6110_GetPowerSource(GSM_PowerSource *source)
2327 char screen[NM_MAX_SCREEN_WIDTH];
2329 CurrentPowerSource=-1;
2331 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2333 if (N6110_NetMonitor(20, screen)!=GE_NONE)
2336 CurrentPowerSource=GPS_ACDC;
2338 if (screen[6]=='x') CurrentPowerSource=GPS_BATTERY;
2340 *source=CurrentPowerSource;
2344 N6110_SendStatusRequest();
2346 /* Wait for timeout or other error. */
2347 while (timeout != 0 && CurrentPowerSource == -1 ) {
2350 return (GE_TIMEOUT);
2355 if (CurrentPowerSource != -1) {
2356 *source=CurrentPowerSource;
2364 void N6110_ReplyGetDisplayStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2368 for (i=0; i<MessageBuffer[4];i++)
2369 if (MessageBuffer[2*i+6]==2)
2370 CurrentDisplayStatus|=1<<(MessageBuffer[2*i+5]-1);
2372 CurrentDisplayStatus&= (0xff - (1<<(MessageBuffer[2*i+5]-1)));
2375 fprintf(stdout, _("Call in progress: %s\n"), CurrentDisplayStatus & (1<<DS_Call_In_Progress)?"on":"off");
2376 fprintf(stdout, _("Unknown: %s\n"), CurrentDisplayStatus & (1<<DS_Unknown)?"on":"off");
2377 fprintf(stdout, _("Unread SMS: %s\n"), CurrentDisplayStatus & (1<<DS_Unread_SMS)?"on":"off");
2378 fprintf(stdout, _("Voice call: %s\n"), CurrentDisplayStatus & (1<<DS_Voice_Call)?"on":"off");
2379 fprintf(stdout, _("Fax call active: %s\n"), CurrentDisplayStatus & (1<<DS_Fax_Call)?"on":"off");
2380 fprintf(stdout, _("Data call active: %s\n"), CurrentDisplayStatus & (1<<DS_Data_Call)?"on":"off");
2381 fprintf(stdout, _("Keyboard lock: %s\n"), CurrentDisplayStatus & (1<<DS_Keyboard_Lock)?"on":"off");
2382 fprintf(stdout, _("SMS storage full: %s\n"), CurrentDisplayStatus & (1<<DS_SMS_Storage_Full)?"on":"off");
2385 CurrentDisplayStatusError=GE_NONE;
2388 GSM_Error N6110_GetDisplayStatus(int *Status) {
2390 unsigned char req[4]={ N6110_FRAME_HEADER, 0x51 };
2394 error=NULL_SendMessageSequence
2395 (10, &CurrentDisplayStatusError, 4, 0x0d, req);
2396 if (error!=GE_NONE) return error;
2398 *Status=CurrentDisplayStatus;
2403 GSM_Error N6110_DialVoice(char *Number) {
2404 /* This commented sequence doesn't work on N3210/3310/6210/7110 */
2405 // unsigned char req[64]={N6110_FRAME_HEADER, 0x01};
2406 // unsigned char req_end[]={0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};
2408 // req[4]=strlen(Number);
2409 // for(i=0; i < strlen(Number) ; i++)
2410 // req[5+i]=Number[i];
2411 // memcpy(req+5+strlen(Number), req_end, 10);
2412 // return NULL_SendMessageSequence
2413 // (20, &CurrentDialVoiceError, 13+strlen(Number), 0x01, req);
2415 unsigned char req[64]={0x00,0x01,0x7c,
2416 0x01}; //call command
2422 error=N6110_EnableExtendedCommands(0x01);
2423 if (error!=GE_NONE) return error;
2425 for(i=0; i < strlen(Number) ; i++) req[4+i]=Number[i];
2429 return NULL_SendMessageSequence
2430 (20, &CurrentDialVoiceError, 4+strlen(Number)+1, 0x40, req);
2433 /* Dial a data call - type specifies request to use:
2434 type 0 should normally be used
2435 type 1 should be used when calling a digital line - corresponds to ats35=0
2436 Maybe one day we'll know what they mean!
2438 GSM_Error N6110_DialData(char *Number, char type, void (* callpassup)(char c))
2440 unsigned char req[100] = { N6110_FRAME_HEADER, 0x01 };
2441 unsigned char *req_end;
2442 unsigned char req_end0[] = { 0x01, /* make a data call = type 0x01 */
2443 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2444 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00 };
2445 unsigned char req_end1[] = { 0x01,
2446 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2447 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2448 0x88,0x90,0x21,0x48,0x40,0xbb };
2449 unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2450 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2451 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
2452 unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2453 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2454 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
2455 unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
2456 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2457 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
2458 0x20,0x15,0x63,0x80 };
2463 CurrentCallPassup=callpassup;
2468 size = sizeof(req_end0);
2471 Protocol->SendMessage(sizeof(req3), 0x01, req3);
2473 Protocol->SendMessage(sizeof(req4), 0x01, req4);
2476 size = sizeof(req_end1);
2478 case -1: /* Just used to set the call passup */
2483 size = sizeof(req_end0);
2487 req[4] = strlen(Number);
2489 for(i = 0; i < strlen(Number) ; i++)
2490 req[5+i] = Number[i];
2492 memcpy(req + 5 + strlen(Number), req_end, size);
2494 Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);
2498 Protocol->SendMessage(26, 0x01, req2);
2505 GSM_Error N6110_GetIncomingCallNr(char *Number)
2508 if (*CurrentIncomingCall != ' ') {
2509 strcpy(Number, CurrentIncomingCall);
2516 GSM_Error N6110_CancelCall(void)
2518 // This frame & method works only on 61xx/51xx
2519 // unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
2520 // req[4]=CurrentCallSequenceNumber;
2521 // Protocol->SendMessage(6, 0x01, req);
2526 unsigned char req[]={0x00,0x01,0x7c,0x03};
2529 error=N6110_EnableExtendedCommands(0x01);
2530 if (error!=GE_NONE) return error;
2532 return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
2535 void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2537 switch(MessageBuffer[3]) {
2541 fprintf(stdout, _("Message: Security code accepted.\n"));
2543 CurrentSecurityCodeError = GE_NONE;
2548 fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
2550 CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
2554 GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
2557 unsigned char req[15] = { N6110_FRAME_HEADER,
2558 0x0a, /* Enter code request. */
2559 0x00 /* Type of the entered code. */
2563 req[4]=SecurityCode.Type;
2565 for (i=0; i<strlen(SecurityCode.Code);i++)
2566 req[5+i]=SecurityCode.Code[i];
2568 req[5+strlen(SecurityCode.Code)]=0x00;
2569 req[6+strlen(SecurityCode.Code)]=0x00;
2571 return NULL_SendMessageSequence
2572 (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
2575 void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2577 *CurrentSecurityCodeStatus = MessageBuffer[4];
2580 fprintf(stdout, _("Message: Security Code status received: "));
2582 switch(*CurrentSecurityCodeStatus) {
2584 case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;
2585 case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;
2586 case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;
2587 case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;
2588 case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;
2589 case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;
2590 default : fprintf(stdout, _("Unknown!\n"));
2595 CurrentSecurityCodeError = GE_NONE;
2598 GSM_Error N6110_GetSecurityCodeStatus(int *Status)
2601 unsigned char req[4] = { N6110_FRAME_HEADER,
2605 CurrentSecurityCodeStatus=Status;
2607 return NULL_SendMessageSequence
2608 (20, &CurrentSecurityCodeError, 4, 0x08, req);
2611 void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2616 fprintf(stdout, _("Message: Security code received: "));
2617 switch (MessageBuffer[3]) {
2618 case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;
2619 case GSCT_Pin: fprintf(stdout, _("PIN"));break;
2620 case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;
2621 case GSCT_Puk: fprintf(stdout, _("PUK"));break;
2622 case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;
2623 default: fprintf(stdout, _("unknown !"));break;
2625 if (MessageBuffer[4]==1) {
2626 fprintf(stdout, _(" allowed, value \""));
2627 if (MessageBuffer[3]==GSCT_SecurityCode) {
2628 for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2630 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2631 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2632 for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2634 fprintf(stdout, _("\""));
2636 fprintf(stdout, _(" not allowed"));
2638 fprintf(stdout, _("\n"));
2641 if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
2642 && MessageBuffer[4]==1) { /* It's allowed */
2643 if (MessageBuffer[3]==GSCT_SecurityCode) {
2644 for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2645 CurrentSecurityCode->Code[5]=0;
2647 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2648 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2649 for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2650 CurrentSecurityCode->Code[4]=0;
2652 CurrentSecurityCodeError=GE_NONE;
2654 CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
2657 GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
2660 unsigned char req[4] = { 0x00,
2661 0x01,0x6e, /* Get code request. */
2662 0x00 }; /* Type of the requested code. */
2666 error=N6110_EnableExtendedCommands(0x01);
2667 if (error!=GE_NONE) return error;
2669 req[3]=SecurityCode->Type;
2671 CurrentSecurityCode=SecurityCode;
2673 return NULL_SendMessageSequence
2674 (20, &CurrentSecurityCodeError, 4, 0x40, req);
2677 void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2680 fprintf(stdout, _("Message: answer for PlayTone frame\n"));
2683 CurrentPlayToneError=GE_NONE;
2686 GSM_Error N6110_PlayTone(int Herz, u8 Volume)
2688 unsigned char req[6] = { 0x00,0x01,0x8f,
2691 0x00 }; /* HerzHi */
2695 /* PlayTone wasn't used earlier */
2696 if (CurrentPlayToneError==GE_UNKNOWN) {
2697 if (CurrentConnectionType!=GCT_MBUS)
2698 CurrentDisableKeepAlive=true;
2700 error=N6110_EnableExtendedCommands(0x01);
2701 if (error!=GE_NONE) return error;
2704 /* For Herz==255*255 we have silent */
2705 if (Herz!=255*255) {
2718 /* For Herz==255*255 we have silent and additionaly
2719 we wait for phone answer - it's important for MBUS */
2720 if (Herz==255*255) {
2721 error=NULL_SendMessageSequence
2722 (20, &CurrentPlayToneError, 6, 0x40, req);
2724 CurrentPlayToneError=GE_UNKNOWN;
2725 CurrentDisableKeepAlive=false;
2727 if (error!=GE_NONE) return error;
2729 Protocol->SendMessage(6,0x40,req);
2732 error=NULL_SendMessageSequence
2733 (20, &CurrentPlayToneError, 6, 0x40, req);
2735 /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
2736 if (Herz==255*255) {
2737 CurrentPlayToneError=GE_UNKNOWN;
2738 CurrentDisableKeepAlive=false;
2741 if (error!=GE_NONE) return error;
2748 void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2750 if (MessageBuffer[4]==0x01) {
2751 DecodeDateTime(MessageBuffer+8, CurrentDateTime);
2754 fprintf(stdout, _("Message: Date and time\n"));
2755 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
2756 fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
2759 CurrentDateTime->IsSet=true;
2763 fprintf(stdout, _("Message: Date and time not set in phone\n"));
2766 CurrentDateTime->IsSet=false;
2769 CurrentDateTimeError=GE_NONE;
2772 GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
2774 return N6110_PrivGetDateTime(date_time,0x11);
2777 GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
2779 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
2781 CurrentDateTime=date_time;
2783 return NULL_SendMessageSequence
2784 (50, &CurrentDateTimeError, 4, msgtype, req);
2787 void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2790 fprintf(stdout, _("Message: Alarm\n"));
2791 fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
2792 fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
2795 CurrentAlarm->Hour=MessageBuffer[9];
2796 CurrentAlarm->Minute=MessageBuffer[10];
2797 CurrentAlarm->Second=0;
2799 CurrentAlarm->IsSet=(MessageBuffer[8]==2);
2801 CurrentAlarmError=GE_NONE;
2804 GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
2806 return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
2809 GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
2811 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
2813 CurrentAlarm=date_time;
2815 return NULL_SendMessageSequence
2816 (50, &CurrentAlarmError, 4, msgtype, req);
2819 void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2821 switch (MessageBuffer[3]) {
2825 CurrentMessageCenter->No=MessageBuffer[4];
2826 CurrentMessageCenter->Format=MessageBuffer[6];
2827 CurrentMessageCenter->Validity=MessageBuffer[8];
2828 sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
2830 sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
2832 sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
2835 fprintf(stdout, _("Message: SMS Center received:\n"));
2836 fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
2837 fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
2838 fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
2840 fprintf(stdout, _(" SMS Center message format is "));
2842 switch (CurrentMessageCenter->Format) {
2844 case GSMF_Text : fprintf(stdout, _("Text")); break;
2845 case GSMF_Paging: fprintf(stdout, _("Paging")); break;
2846 case GSMF_Fax : fprintf(stdout, _("Fax")); break;
2847 case GSMF_Email : fprintf(stdout, _("Email")); break;
2848 default : fprintf(stdout, _("Unknown"));
2851 fprintf(stdout, "\n");
2853 fprintf(stdout, _(" SMS Center message validity is "));
2855 switch (CurrentMessageCenter->Validity) {
2857 case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;
2858 case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;
2859 case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;
2860 case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;
2861 case GSMV_1_Week : fprintf(stdout, _("1 week")); break;
2862 case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;
2863 default : fprintf(stdout, _("Unknown"));
2866 fprintf(stdout, "\n");
2870 CurrentMessageCenterError=GE_NONE;
2876 /* Number of entries depends on SIM card */
2879 fprintf(stdout, _("Message: SMS Center error received:\n"));
2880 fprintf(stdout, _(" The request for SMS Center failed.\n"));
2883 /* FIXME: appropriate error. */
2884 CurrentMessageCenterError=GE_INTERNALERROR;
2891 /* This function sends to the mobile phone a request for the SMS Center */
2892 GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
2894 unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
2895 0x00 /* SMS Center Number. */
2898 req[5]=MessageCenter->No;
2900 CurrentMessageCenter=MessageCenter;
2902 return NULL_SendMessageSequence
2903 (50, &CurrentMessageCenterError, 6, 0x02, req);
2906 void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2909 fprintf(stdout, _("Message: SMS Center correctly set.\n"));
2911 CurrentMessageCenterError=GE_NONE;
2914 /* This function set the SMS Center profile on the phone. */
2915 GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
2917 unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
2918 0x00, /* SMS Center Number. */
2919 0x00, /* Unknown. */
2920 0x00, /* SMS Message Format. */
2921 0x00, /* Unknown. */
2922 0x00, /* Validity. */
2923 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
2924 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
2925 /* Message Center Name. */
2928 req[5]=MessageCenter->No;
2929 req[7]=MessageCenter->Format;
2930 req[9]=MessageCenter->Validity;
2932 req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
2934 req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
2936 sprintf(req+34, "%s", MessageCenter->Name);
2938 CurrentMessageCenter=MessageCenter;
2940 return NULL_SendMessageSequence
2941 (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
2944 void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2946 switch (MessageBuffer[3]) {
2951 fprintf(stdout, _("Message: SMS Status Received\n"));
2952 fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
2953 fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
2956 CurrentSMSStatus->UnRead = MessageBuffer[11];
2957 CurrentSMSStatus->Number = MessageBuffer[10];
2959 CurrentSMSStatusError = GE_NONE;
2965 fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
2968 CurrentSMSStatusError = GE_INTERNALERROR;
2974 GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
2976 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
2978 CurrentSMSStatus = Status;
2980 return NULL_SendMessageSequence
2981 (10, &CurrentSMSStatusError, 5, 0x14, req);
2984 GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
2988 strcpy(folders->Folder[0].Name,"Inbox");
2989 strcpy(folders->Folder[1].Name,"Outbox");
2994 GSM_Error N6110_GetIMEI(char *imei)
2996 if (strlen(Current_IMEI)>0) {
2997 strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
3001 return (GE_TRYAGAIN);
3004 GSM_Error N6110_GetRevision(char *revision)
3007 if (strlen(Current_Revision)>0) {
3008 strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
3012 return (GE_TRYAGAIN);
3015 GSM_Error N6110_GetModel(char *model)
3017 if (strlen(Current_Model)>0) {
3018 strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
3022 return (GE_TRYAGAIN);
3025 void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3027 switch (MessageBuffer[4]) {
3031 fprintf(stdout, _("Message: Date and time set correctly\n"));
3033 CurrentSetDateTimeError=GE_NONE;
3038 fprintf(stdout, _("Message: Date and time setting error\n"));
3040 CurrentSetDateTimeError=GE_INVALIDDATETIME;
3045 /* Needs SIM card with PIN in phone */
3046 GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
3048 return N6110_PrivSetDateTime(date_time,0x11);
3051 /* Needs SIM card with PIN in phone */
3052 GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
3055 unsigned char req[] = { N6110_FRAME_HEADER,
3056 0x60, /* set-time subtype */
3057 0x01, 0x01, 0x07, /* unknown */
3058 0x00, 0x00, /* Year (0x07cf = 1999) */
3059 0x00, 0x00, /* Month Day */
3060 0x00, 0x00, /* Hours Minutes */
3061 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3064 EncodeDateTime(req+7, date_time);
3066 return NULL_SendMessageSequence
3067 (20, &CurrentSetDateTimeError, 14, msgtype, req);
3070 void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3072 switch (MessageBuffer[4]) {
3076 fprintf(stdout, _("Message: Alarm set correctly\n"));
3078 CurrentSetAlarmError=GE_NONE;
3083 fprintf(stdout, _("Message: Alarm setting error\n"));
3085 CurrentSetAlarmError=GE_INVALIDDATETIME;
3090 /* FIXME: we should also allow to set the alarm off :-) */
3091 GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
3093 return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
3096 /* FIXME: we should also allow to set the alarm off :-) */
3097 GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
3100 unsigned char req[] = { N6110_FRAME_HEADER,
3101 0x6b, /* set-alarm subtype */
3102 0x01, 0x20, 0x03, /* unknown */
3103 0x02, /* should be alarm on/off, but it don't works */
3104 0x00, 0x00, /* Hours Minutes */
3105 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3108 req[8] = date_time->Hour;
3109 req[9] = date_time->Minute;
3111 return NULL_SendMessageSequence
3112 (50, &CurrentSetAlarmError, 11, msgtype, req);
3115 void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3117 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
3122 switch (MessageBuffer[3]) {
3126 CurrentPhonebookEntry->Empty = true;
3128 count=MessageBuffer[5];
3131 fprintf(stdout, _("Message: Phonebook entry received:\n"));
3132 fprintf(stdout, _(" Name: "));
3134 for (tmp=0; tmp <count; tmp++)
3136 if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
3137 if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
3138 fprintf(stdout, "%c", MessageBuffer[6+tmp]);
3141 fprintf(stdout, "\n");
3144 while (N6110_GetModel(model) != GE_NONE)
3147 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM ||
3148 GetModelFeature (FN_PHONEBOOK)==F_PBK33INT) {//pbk with Unicode
3149 DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
3150 CurrentPhonebookEntry->Name[count/2] = 0x00;
3152 memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);
3153 CurrentPhonebookEntry->Name[count] = 0x00;
3156 CurrentPhonebookEntry->Empty = false;
3158 for (tmp=0; tmp <count; tmp++)
3160 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33INT ||
3161 GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM) {//pbk with Unicode
3162 /* We check only 1'st, 3'rd, ... char */
3163 if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking
3164 if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents
3166 if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking
3167 if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents
3172 count=MessageBuffer[6+count];
3175 fprintf(stdout, _(" Number: "));
3177 for (tmp=0; tmp <count; tmp++)
3178 fprintf(stdout, "%c", MessageBuffer[i+tmp]);
3180 fprintf(stdout, "\n");
3183 memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);
3184 CurrentPhonebookEntry->Number[count] = 0x00;
3185 CurrentPhonebookEntry->Group = MessageBuffer[i+count];
3187 /* Phone doesn't have entended phonebook */
3188 CurrentPhonebookEntry->SubEntriesCount = 0;
3190 /* But for these memories data is saved and we can save it using 7110/6210 style */
3191 if (CurrentPhonebookEntry->MemoryType==GMT_DC ||
3192 CurrentPhonebookEntry->MemoryType==GMT_RC ||
3193 CurrentPhonebookEntry->MemoryType==GMT_MC) {
3194 CurrentPhonebookEntry->SubEntriesCount = 1;
3195 CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;
3196 CurrentPhonebookEntry->SubEntries[0].NumberType=0;
3197 CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;
3198 DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);
3201 fprintf(stdout, _(" Date: "));
3202 fprintf(stdout, "%02u.%02u.%04u\n",
3203 CurrentPhonebookEntry->SubEntries[0].data.Date.Day,
3204 CurrentPhonebookEntry->SubEntries[0].data.Date.Month,
3205 CurrentPhonebookEntry->SubEntries[0].data.Date.Year);
3206 fprintf(stdout, _(" Time: "));
3207 fprintf(stdout, "%02u:%02u:%02u\n",
3208 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,
3209 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,
3210 CurrentPhonebookEntry->SubEntries[0].data.Date.Second);
3213 /* These values are set, when date and time unavailable in phone.
3214 Values from 3310 - in other can be different */
3215 if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&
3216 CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&
3217 CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&
3218 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&
3219 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&
3220 CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)
3221 CurrentPhonebookEntry->SubEntriesCount = 0;
3224 /* Signal no error to calling code. */
3225 CurrentPhonebookError = GE_NONE;
3232 fprintf(stdout, _("Message: Phonebook read entry error received:\n"));
3235 switch (MessageBuffer[4]) {
3239 fprintf(stdout, _(" Invalid memory type!\n"));
3241 CurrentPhonebookError = GE_INVALIDMEMORYTYPE;
3246 fprintf(stdout, _(" Unknown error!\n"));
3248 CurrentPhonebookError = GE_INTERNALERROR;
3256 /* Routine to get specifed phone book location. Designed to be called by
3257 application. Will block until location is retrieved or a timeout/error
3259 GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)
3261 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
3263 CurrentPhonebookEntry = entry;
3265 req[4] = N6110_GetMemoryType(entry->MemoryType);
3266 req[5] = entry->Location;
3268 return NULL_SendMessageSequence
3269 (50, &CurrentPhonebookError, 7, 0x03, req);
3272 void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3274 switch (MessageBuffer[3]) {
3279 fprintf(stdout, _("Message: Phonebook written correctly.\n"));
3281 CurrentPhonebookError = GE_NONE;
3286 switch (MessageBuffer[4]) {
3287 /* FIXME: other errors? When I send the phonebook with index of 350 it
3288 still report error 0x7d :-( */
3291 fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));
3293 CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;
3298 fprintf(stdout, _(" Unknown error!\n"));
3300 CurrentPhonebookError = GE_INTERNALERROR;
3305 /* Routine to write phonebook location in phone. Designed to be called by
3306 application code. Will block until location is written or timeout
3308 GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)
3310 unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };
3313 req[4] = N6110_GetMemoryType(entry->MemoryType);
3314 req[5] = entry->Location;
3318 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33INT ||
3319 GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM) {
3321 req[6] = strlen(entry->Name)*2;
3323 EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
3325 for (i=0; i<strlen(entry->Name); i++)
3327 /* here we encode "special" chars */
3328 if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
3329 if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
3332 current+=strlen(entry->Name)*2;
3335 req[6] = strlen(entry->Name);
3337 for (i=0; i<strlen(entry->Name); i++)
3339 req[current+i] = entry->Name[i];
3341 /* here we encode "special" chars */
3342 if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
3343 if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
3346 current+=strlen(entry->Name);
3349 req[current++]=strlen(entry->Number);
3351 for (i=0; i<strlen(entry->Number); i++)
3352 req[current+i] = entry->Number[i];
3354 current+=strlen(entry->Number);
3356 /* Jano: This allow to save 14 characters name into SIM memory, when
3357 No Group is selected. */
3358 if (entry->Group == 5)
3359 req[current++]=0xff;
3361 req[current++]=entry->Group;
3363 return NULL_SendMessageSequence
3364 (50, &CurrentPhonebookError, current, 0x03, req);
3367 void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3369 switch(MessageBuffer[3]) {
3373 fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
3375 CurrentNetmonitorError=GE_NONE;
3380 fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
3381 fprintf(stdout, "%s\n", MessageBuffer+4);
3384 strcpy(CurrentNetmonitor, MessageBuffer+4);
3386 CurrentNetmonitorError=GE_NONE;
3390 GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
3392 unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
3396 error=N6110_EnableExtendedCommands(0x01);
3397 if (error!=GE_NONE) return error;
3399 CurrentNetmonitor=Screen;
3403 return NULL_SendMessageSequence
3404 (20, &CurrentNetmonitorError, 4, 0x40, req);
3407 /* Doesn't work in N3210. */
3408 /* In other allow to access phone menu without SIM card (just send any sequence) */
3409 GSM_Error N6110_SendDTMF(char *String)
3411 unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
3412 0x00 /* Length of DTMF string. */
3415 u8 length=strlen(String);
3417 if (length>59) length=59;
3421 memcpy(req+5,String,length);
3423 return NULL_SendMessageSequence
3424 (20, &CurrentSendDTMFError, 5+length, 0x01, req);
3427 void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3429 switch (MessageBuffer[3]) {
3433 switch (MessageBuffer[4]) {
3434 case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
3435 default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
3438 CurrentSpeedDialEntry->Location = MessageBuffer[5];
3441 fprintf(stdout, _("Message: Speed dial entry received:\n"));
3442 fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
3443 fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
3444 fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
3447 CurrentSpeedDialError=GE_NONE;
3453 fprintf(stdout, _("Message: Speed dial entry error\n"));
3455 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3461 GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
3464 unsigned char req[] = { N6110_FRAME_HEADER,
3466 0x00 /* The number of speed dial. */
3469 CurrentSpeedDialEntry = entry;
3471 req[4] = entry->Number;
3473 return NULL_SendMessageSequence
3474 (20, &CurrentSpeedDialError, 5, 0x03, req);
3477 void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3479 switch (MessageBuffer[3]) {
3484 fprintf(stdout, _("Message: Speed dial entry set.\n"));
3486 CurrentSpeedDialError=GE_NONE;
3492 fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
3494 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3500 GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
3503 unsigned char req[] = { N6110_FRAME_HEADER,
3506 0x00, /* Memory Type */
3510 req[4] = entry->Number;
3512 switch (entry->MemoryType) {
3513 case GMT_ME: req[5] = 0x02;
3514 default : req[5] = 0x03;
3517 req[6] = entry->Location;
3519 return NULL_SendMessageSequence
3520 (20, &CurrentSpeedDialError, 7, 0x03, req);
3523 /* This function finds parts of SMS in frame used in new Nokia phones
3524 in internal protocols (they're coded according to GSM 03.40), copies them
3525 to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
3526 GSM_ETSISMSMessage to GSM_SMSMessage structure */
3527 GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
3529 SMS_MessageType PDU=SMS_Deliver;
3530 GSM_ETSISMSMessage ETSI;
3533 ETSI.firstbyte=req[12];
3535 /* See GSM 03.40 section 9.2.3.1 */
3536 if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
3537 if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
3540 case SMS_Submit : offset=5;break;
3541 case SMS_Deliver : offset=4;break;
3542 case SMS_Status_Report: offset=3;break;
3546 for (i=0;i<req[0]+1;i++)
3547 ETSI.SMSCNumber[i]=req[i];
3549 for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
3550 ETSI.Number[i]=req[i+12+offset];
3554 ETSI.TPDCS=req[10+offset];
3555 ETSI.TPUDL=req[11+offset];
3556 ETSI.TPVP=0; //no support for now
3557 ETSI.TPPID=0; //no support for now
3558 for(i=31+offset;i<length;i++)
3559 ETSI.MessageText[i-31-offset]=req[i];
3562 ETSI.TPDCS=req[10+offset];
3563 ETSI.TPUDL=req[11+offset];
3564 ETSI.TPPID=0; //no support for now
3565 for(i=31+offset;i<length;i++)
3566 ETSI.MessageText[i-31-offset]=req[i];
3568 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3570 case SMS_Status_Report:
3572 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3573 ETSI.TPStatus=req[14];
3575 ETSI.SMSCDateTime[i]=req[i+34];
3581 GSM_DecodeETSISMS(SMS, &ETSI);
3588 void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3592 switch (MessageBuffer[3]) {
3596 switch (MessageBuffer[7]) {
3599 CurrentSMSMessage->Type = GST_SMS;
3600 CurrentSMSMessage->folder=GST_INBOX;
3605 CurrentSMSMessage->Type = GST_DR;
3606 CurrentSMSMessage->folder=GST_INBOX;
3611 CurrentSMSMessage->Type = GST_SMS;
3612 CurrentSMSMessage->folder=GST_OUTBOX;
3617 CurrentSMSMessage->Type = GST_UN;
3623 /* Field Short Message Status - MessageBuffer[4] seems not to be
3624 compliant with GSM 07.05 spec.
3625 Meaning Nokia protocol GMS spec
3626 ----------------------------------------------------
3627 MO Sent 0x05 0x07 or 0x01
3628 MO Not sent 0x07 0x06 or 0x00
3629 MT Read 0x01 0x05 or 0x01
3630 MT Not read 0x03 0x04 or 0x00
3631 ----------------------------------------------------
3632 See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
3636 if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
3637 else CurrentSMSMessage->Status = GSS_SENTREAD;
3640 fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
3642 if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
3643 fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
3645 fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
3648 if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
3649 if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
3651 if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
3652 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
3653 else fprintf(stdout, _(" Not sent\n"));
3655 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
3656 else fprintf(stdout, _(" Not read\n"));
3660 CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
3662 CurrentSMSMessage->MemoryType = MessageBuffer[5];
3663 CurrentSMSMessage->MessageNumber = MessageBuffer[6];
3665 /* Signal no error to calling code. */
3666 CurrentSMSMessageError = GE_NONE;
3669 fprintf(stdout, "\n");
3676 /* We have requested invalid or empty location. */
3679 fprintf(stdout, _("Message: SMS reading failed\n"));
3681 switch (MessageBuffer[4]) {
3682 case 0x02:fprintf(stdout, _(" Invalid location!\n"));break;
3683 case 0x07:fprintf(stdout, _(" Empty SMS location.\n"));break;
3684 case 0x0c:fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
3685 default :fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
3689 switch (MessageBuffer[4]) {
3690 case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3691 case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
3692 case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
3693 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3701 GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
3704 unsigned char req[] = { N6110_FRAME_HEADER,
3707 0x00, /* Location */
3712 /* State machine code writes data to these variables when it comes in. */
3714 CurrentSMSMessage = message;
3715 CurrentSMSMessageError = GE_BUSY;
3717 req[5] = message->Location;
3720 Protocol->SendMessage(8, 0x02, req);
3722 /* Wait for timeout or other error. */
3723 while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
3726 return (GE_TIMEOUT);
3731 return (CurrentSMSMessageError);
3734 void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3737 fprintf(stdout, _("Message: SMS deleted successfully.\n"));
3740 CurrentSMSMessageError = GE_NONE;
3743 GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
3745 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
3747 req[5] = message->Location;
3749 return NULL_SendMessageSequence
3750 (50, &CurrentSMSMessageError, 6, 0x14, req);
3753 /* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
3754 GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
3756 GSM_ETSISMSMessage ETSI;
3759 GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
3762 for (i=0;i<36;i++) req[i]=0;
3764 req[12]=ETSI.firstbyte;
3766 for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
3767 req[i]=ETSI.SMSCNumber[i];
3772 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++) req[i+12+offset]=ETSI.Number[i];
3773 req[10+offset]=ETSI.TPDCS;
3774 req[11+offset]=ETSI.TPUDL;
3775 req[24+offset]=ETSI.TPVP;
3777 // fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
3778 // fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
3779 // fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
3781 // req[]=ETSI.TPPID;
3782 for(i=0;i<*length;i++) req[i+31+offset]=ETSI.MessageText[i];
3787 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++) req[i+12+offset]=ETSI.Number[i];
3788 req[10+offset]=ETSI.TPDCS;
3789 req[11+offset]=ETSI.TPUDL;
3790 // req[]=ETSI.TPPID;
3791 for(i=0;i<*length;i++) req[i+31+offset]=ETSI.MessageText[i];
3792 for (i=0;i<7;i++) req[24+offset+i]=ETSI.DeliveryDateTime[i];
3798 *length=*length+offset;
3803 void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3805 switch (MessageBuffer[3]) {
3807 /* SMS message correctly sent to the network */
3810 fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
3812 CurrentSMSMessageError = GE_SMSSENDOK;
3815 /* SMS message send to the network failed */
3819 fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
3821 switch (MessageBuffer[6]) {
3822 case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3823 case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
3824 case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3825 case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
3826 case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3827 case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3828 case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3829 case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3830 case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3833 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
3834 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
3837 CurrentSMSMessageError = GE_SMSSENDFAILED;
3843 GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
3847 unsigned char req[256] = {
3849 0x01, 0x02, 0x00, /* SMS send request*/
3854 error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
3855 if (error != GE_NONE) return error;
3857 return NULL_SendMessageSequence
3858 (200, &CurrentSMSMessageError, 42+length, 0x02, req);
3861 void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3863 switch (MessageBuffer[3]) {
3868 fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
3871 CurrentSMSMessage->MessageNumber=MessageBuffer[5];
3873 CurrentSMSMessageError = GE_NONE;
3878 fprintf(stdout, _("SMS saving failed\n"));
3879 switch (MessageBuffer[4]) {
3880 case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
3881 case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
3882 default :fprintf(stdout, _(" Unknown error.\n"));break;
3886 switch (MessageBuffer[4]) {
3887 case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
3888 case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3889 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3894 /* GST_DR and GST_UN not supported ! */
3895 GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
3897 unsigned char req[256] = {
3898 N6110_FRAME_HEADER, 0x04, /* SMS save request*/
3899 0x00, /* SMS Status. Different for Inbox and Outbox */
3901 0x00, /* SMS Location */
3902 0x02, /* SMS Type */
3906 SMS_MessageType PDU;
3909 if (SMS->Location) req[6] = SMS->Location;
3911 if (SMS->folder==0) { /*Inbox*/
3912 req[4]=1; /* SMS Status */
3913 req[7] = 0x00; /* SMS Type */
3916 req[4]=5; /* SMS Status */
3917 req[7] = 0x02; /* SMS Type */
3921 if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
3923 error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
3924 if (error != GE_NONE) return error;
3926 CurrentSMSMessage = SMS;
3928 return NULL_SendMessageSequence
3929 (70, &CurrentSMSMessageError, 39+length, 0x14, req);
3932 void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3935 fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
3938 CurrentCBError = GE_NONE;
3941 /* Enable and disable Cell Broadcasting */
3942 GSM_Error N6110_EnableCellBroadcast(void)
3944 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
3945 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
3948 fprintf (stdout,"Enabling CB\n");
3951 CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
3952 CurrentCBMessage->Channel = 0;
3953 CurrentCBMessage->New = false;
3954 strcpy (CurrentCBMessage->Message,"");
3956 return NULL_SendMessageSequence
3957 (10, &CurrentCBError, 10, 0x02, req);
3961 GSM_Error N6110_DisableCellBroadcast(void)
3963 /* Should work, but not tested fully */
3965 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
3966 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
3968 return NULL_SendMessageSequence
3969 (10, &CurrentCBError, 10, 0x02, req);
3972 void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3975 unsigned char output[160];
3977 CurrentCBMessage->Channel = MessageBuffer[7];
3978 CurrentCBMessage->New = true;
3979 tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
3982 fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
3984 fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
3988 for (i=0; i<tmp;i++) {
3989 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
3992 fprintf(stdout, "\n");
3995 for (i=0; i<tmp; i++) {
3996 CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
3998 CurrentCBMessage->Message[i]=0;
4001 GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
4004 fprintf(stdout,"Reading CB\n");
4007 if (CurrentCBMessage != NULL)
4009 if (CurrentCBMessage->New == true)
4012 fprintf(stdout,"New CB received\n");
4014 Message->Channel = CurrentCBMessage->Channel;
4015 strcpy(Message->Message,CurrentCBMessage->Message);
4016 CurrentCBMessage->New = false;
4020 return (GE_NONEWCBRECEIVED);
4023 int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
4027 req[count++]=Bitmap.number;
4028 req[count++]=strlen(Bitmap.text);
4029 memcpy(req+count,Bitmap.text,req[count-1]);
4030 count+=req[count-1];
4031 req[count++]=Bitmap.ringtone;
4033 /* Setting for graphic:
4036 0x02 - View Graphics
4037 0x03 - Send Graphics
4039 You can even set it higher but Nokia phones (my
4040 6110 at least) will not show you the name of this
4041 item in menu ;-)) Nokia is really joking here. */
4042 if (Bitmap.enabled) req[count++]=0x01;
4043 else req[count++]=0x00;
4045 req[count++]=(Bitmap.size+4)>>8;
4046 req[count++]=(Bitmap.size+4)%0xff;
4047 req[count++]=0x00; /* Future extensions! */
4048 req[count++]=Bitmap.width;
4049 req[count++]=Bitmap.height;
4050 req[count++]=0x01; /* Just BW */
4051 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4053 return count+Bitmap.size;
4056 int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4060 EncodeNetworkCode(req+count, Bitmap.netcode);
4063 req[count++]=(Bitmap.size+4)>>8;
4064 req[count++]=(Bitmap.size+4)%0xff;
4065 req[count++]=0x00; /* Infofield */
4066 req[count++]=Bitmap.width;
4067 req[count++]=Bitmap.height;
4068 req[count++]=0x01; /* Just BW */
4069 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4071 return count+Bitmap.size;
4074 int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4079 req[count++]=Bitmap.height;
4080 req[count++]=Bitmap.width;
4081 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4083 return count+Bitmap.size;
4086 /* Set a bitmap or welcome-note */
4087 GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
4089 unsigned char req[600] = { N6110_FRAME_HEADER };
4095 /* Direct uploading variables */
4096 GSM_MultiSMSMessage SMS;
4097 unsigned char buffer[1000] = {0x0c,0x01};
4098 GSM_NetworkInfo NetworkInfo;
4102 /* Uploading with preview */
4103 if (Bitmap->number==255 &&
4104 (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
4105 GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
4106 memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
4108 memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
4110 buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
4112 Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
4114 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4115 return GE_NONE; //no answer from phone
4118 CurrentSetBitmapError = GE_BUSY;
4120 switch (Bitmap->type) {
4121 case GSM_WelcomeNoteText:
4122 case GSM_DealerNoteText:
4124 req[count++]=0x01; /* Only one block */
4126 if (Bitmap->type==GSM_WelcomeNoteText)
4127 req[count++]=0x02; /* Welcome text */
4129 req[count++]=0x03; /* Dealer Welcome Note */
4131 textlen=strlen(Bitmap->text);
4132 req[count++]=textlen;
4133 memcpy(req+count,Bitmap->text,textlen);
4137 Protocol->SendMessage(count, 0x05, req);
4141 case GSM_StartupLogo:
4142 if (Bitmap->number==0) {
4144 /* For 33xx we first set animated logo to default */
4145 if (GetModelFeature (FN_STARTUP)==F_STANIM) {
4146 error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4147 if (error!=GE_NONE) return error;
4151 req[count++]=0x01; /* Only one block */
4152 count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
4153 Protocol->SendMessage(count, 0x05, req);
4155 return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4159 case GSM_OperatorLogo:
4160 req[count++]=0x30; /* Store Op Logo */
4161 req[count++]=0x01; /* Location */
4162 count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
4163 Protocol->SendMessage(count, 0x05, req);
4166 case GSM_CallerLogo:
4168 count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
4169 Protocol->SendMessage(count, 0x03, req);
4172 case GSM_PictureImage:
4174 req[count++]=Bitmap->number;
4175 if (strcmp(Bitmap->Sender,"")) {
4176 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
4178 /* Convert number of semioctets to number of chars and add count */
4180 if (textlen % 2) textlen++;
4181 count+=textlen / 2 + 1;
4189 req[count++]=strlen(Bitmap->text);
4190 memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
4191 count+=strlen(Bitmap->text);
4193 req[count++]=Bitmap->width;
4194 req[count++]=Bitmap->height;
4196 memcpy(req+count,Bitmap->bitmap,Bitmap->size);
4197 Protocol->SendMessage(count+Bitmap->size, 0x47, req);
4200 case GSM_7110OperatorLogo:
4201 case GSM_7110StartupLogo:
4202 case GSM_6210StartupLogo:
4203 return GE_NOTSUPPORTED;
4209 /* Wait for timeout or other error. */
4210 while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
4213 return (GE_TIMEOUT);
4218 return CurrentSetBitmapError;
4221 /* Get a bitmap from the phone */
4222 GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
4224 unsigned char req[10] = { N6110_FRAME_HEADER };
4229 CurrentGetBitmap=Bitmap;
4230 CurrentGetBitmapError = GE_BUSY;
4232 switch (CurrentGetBitmap->type) {
4233 case GSM_StartupLogo:
4234 case GSM_WelcomeNoteText:
4235 case GSM_DealerNoteText:
4237 Protocol->SendMessage(count, 0x05, req);
4239 case GSM_OperatorLogo:
4241 req[count++]=0x01; /* Location 1 */
4242 Protocol->SendMessage(count, 0x05, req);
4244 case GSM_CallerLogo:
4246 req[count++]=Bitmap->number;
4247 Protocol->SendMessage(count, 0x03, req);
4249 case GSM_PictureImage:
4251 req[count++]=Bitmap->number;
4252 Protocol->SendMessage(count, 0x47, req);
4254 case GSM_7110OperatorLogo:
4255 case GSM_7110StartupLogo:
4256 case GSM_6210StartupLogo:
4258 return GE_NOTSUPPORTED;
4261 /* Wait for timeout or other error. */
4262 while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
4265 return (GE_TIMEOUT);
4270 CurrentGetBitmap=NULL;
4272 return CurrentGetBitmapError;
4275 void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4277 switch (MessageBuffer[3]) {
4279 /* Set ringtone OK */
4282 fprintf(stdout, _("Message: Ringtone set OK!\n"));
4284 CurrentRingtoneError=GE_NONE;
4287 /* Set ringtone error */
4290 fprintf(stdout, _("Message: Ringtone setting error !\n"));
4292 CurrentRingtoneError=GE_NOTSUPPORTED;
4297 GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
4300 char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
4301 {N6110_FRAME_HEADER,
4303 0x00, /* Location */
4306 int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
4308 /* Variables for preview uploading */
4309 unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
4310 unsigned char buffer2[20];
4311 GSM_NetworkInfo NetworkInfo;
4313 /* Setting ringtone with preview */
4314 if (ringtone->location==255) {
4317 EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
4318 memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
4319 *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
4320 Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
4321 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4323 return GE_NONE; //no answer from phone
4326 *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
4328 req[4]=ringtone->location-1;
4330 return NULL_SendMessageSequence
4331 (50, &CurrentRingtoneError, (size+7), 0x05, req);
4334 void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4338 switch (MessageBuffer[4]) {
4339 case 0x00: /* location supported. We have ringtone */
4341 /* Binary format used in N6150 */
4342 if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4344 fprintf(stdout,_("Message: ringtone \""));
4351 if (MessageBuffer[i]!=0)
4352 fprintf(stdout,_("%c"),MessageBuffer[i]);
4354 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4355 if (MessageBuffer[i]==0) break;
4360 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4363 /* Looking for end */
4366 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4369 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4373 if (i==MessageLength) break;
4377 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4378 CurrentGetBinRingtone->length=i-3;
4380 CurrentBinRingtoneError=GE_NONE;
4384 /* Binary format used in N3210 */
4385 if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4388 fprintf(stdout,_("Message: ringtone \""));
4395 if (MessageBuffer[i]!=0)
4396 fprintf(stdout,_("%c"),MessageBuffer[i]);
4398 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4399 if (MessageBuffer[i]==0) break;
4404 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4407 /* Here changes to get full compatibility with binary format used in N6150 */
4410 MessageBuffer[5]=0x0c;
4411 MessageBuffer[6]=0x01;
4412 MessageBuffer[7]=0x2c;
4414 /* Looking for end */
4417 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4420 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4424 if (i==MessageLength) break;
4428 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4430 CurrentGetBinRingtone->length=i-3;
4432 CurrentBinRingtoneError=GE_NONE;
4437 memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
4439 CurrentGetBinRingtone->length=MessageLength;
4442 fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
4444 CurrentBinRingtoneError=GE_UNKNOWNMODEL;
4450 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4453 CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
4457 GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
4459 unsigned char req[] = { 0x00,0x01,0x9e,
4464 CurrentGetBinRingtone=ringtone;
4466 error=N6110_EnableExtendedCommands(0x01);
4467 if (error!=GE_NONE) return error;
4469 req[3]=ringtone->location-1;
4471 return NULL_SendMessageSequence
4472 (50, &CurrentBinRingtoneError, 4, 0x40, req);
4475 void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4477 switch (MessageBuffer[4]) {
4478 case 0x00: /* location supported. We set ringtone */
4480 fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
4482 CurrentBinRingtoneError=GE_NONE;
4487 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4489 CurrentBinRingtoneError=GE_NOTSUPPORTED;
4494 GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
4496 unsigned char req[1000] = { 0x00,0x01,0xa0};
4500 GSM_BinRingtone ring;
4502 /* Must be sure, that can upload ringtone to this phone */
4503 ring.location=ringtone->location;
4504 error=N6110_GetBinRingTone(&ring);
4505 if (error!=GE_NONE) return error;
4507 error=N6110_EnableExtendedCommands(0x01);
4508 if (error!=GE_NONE) return error;
4510 memcpy(req+3,ringtone->frame,ringtone->length);
4512 req[3]=ringtone->location-1;
4514 return NULL_SendMessageSequence
4515 (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
4518 GSM_Error N6110_Reset(unsigned char type)
4520 return N6110_EnableExtendedCommands(type);
4523 void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4527 switch (MessageBuffer[3]) {
4529 /* Unknown message - it has been seen after the 0x07 message (call
4530 answered). Probably it has similar meaning. If you can solve
4531 this - just mail me. Pavel JanÃk ml.
4533 The message looks like this:
4541 Phone: [01 ][08 ][00 ] is the header of the frame
4543 [03 ] is the call message subtype
4545 [05 ] is the call sequence number
4549 [00 ][01 ][03 ][02 ][91][00] are unknown but has been
4550 seen in the Incoming call message (just after the
4551 caller's name from the phonebook). But never change
4552 between phone calls :-(
4555 /* This may mean sequence number of 'just made' call - CK */
4559 fprintf(stdout, _("Message: Call message, type 0x02:"));
4560 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4565 /* Possibly call OK */
4566 /* JD: I think that this means "call in progress" (incomming or outgoing) */
4570 fprintf(stdout, _("Message: Call message, type 0x03:"));
4571 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4572 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4575 CurrentCallSequenceNumber=MessageBuffer[4];
4576 CurrentIncomingCall[0]='D';
4577 if (CurrentCallPassup) CurrentCallPassup('D');
4581 /* Remote end has gone away before you answer the call. Probably your
4582 mother-in-law or banker (which is worse?) ... */
4586 fprintf(stdout, _("Message: Remote end hang up.\n"));
4587 fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
4589 switch (MessageBuffer[6]) {
4590 case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
4591 case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
4592 case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
4593 case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4594 case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
4595 case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4598 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
4599 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4602 CurrentIncomingCall[0] = ' ';
4603 if (CurrentCallPassup) CurrentCallPassup(' ');
4607 /* Incoming call alert */
4611 fprintf(stdout, _("Message: Incoming call alert:\n"));
4613 /* We can have more then one call ringing - we can distinguish between
4616 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4617 fprintf(stdout, _(" Number: "));
4619 count=MessageBuffer[6];
4621 for (tmp=0; tmp <count; tmp++)
4622 fprintf(stdout, "%c", MessageBuffer[7+tmp]);
4624 fprintf(stdout, "\n");
4626 fprintf(stdout, _(" Name: "));
4628 for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
4629 fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
4631 fprintf(stdout, "\n");
4634 count=MessageBuffer[6];
4636 CurrentIncomingCall[0] = 0;
4637 for (tmp=0; tmp <count; tmp++)
4638 sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
4642 /* Call answered. Probably your girlfriend...*/
4646 fprintf(stdout, _("Message: Call answered.\n"));
4647 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4652 /* Call ended. Girlfriend is girlfriend, but time is money :-) */
4656 fprintf(stdout, _("Message: Call ended by your phone.\n"));
4657 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4662 /* This message has been seen with the message of subtype 0x09
4663 after I hang the call.
4670 Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
4672 What is the meaning of 87? Can you spell some magic light into
4677 /* Probably means call over - CK */
4681 fprintf(stdout, _("Message: Call message, type 0x0a:"));
4682 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4683 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4686 CurrentIncomingCall[0] = ' ';
4687 if (CurrentCallPassup) CurrentCallPassup(' ');
4694 fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
4697 if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
4699 if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
4706 fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
4708 AppendLogText("Unknown msg\n",false);
4710 break; /* Visual C Don't like empty cases */
4714 void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4718 switch (MessageBuffer[3]) {
4722 /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
4723 /* If you want see, if it works with your phone make something like that: */
4725 /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
4726 /* Protocol->SendMessage(4, 0x04, connect5); */
4728 /* Marcin-Wiacek@TopNet.PL */
4731 sprintf(Current_IMEI, "%s", MessageBuffer+5);
4732 sprintf(Current_Model, "%s", MessageBuffer+21);
4733 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4735 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
4736 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
4737 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4741 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
4742 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
4743 fprintf(stdout, _(" Model: %s\n"), Current_Model);
4744 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
4745 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
4746 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
4751 /* Get group data */
4752 /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
4755 if (CurrentGetBitmap!=NULL) {
4756 if (CurrentGetBitmap->number==MessageBuffer[4]) {
4757 count=MessageBuffer[5];
4758 memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
4759 CurrentGetBitmap->text[count]=0;
4762 fprintf(stdout, _("Message: Caller group datas\n"));
4763 fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
4768 CurrentGetBitmap->ringtone=MessageBuffer[count++];
4770 fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
4771 if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
4772 fprintf(stdout,_("\n"));
4775 CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
4777 fprintf(stdout, _("Caller group logo "));
4778 if (CurrentGetBitmap->enabled)
4779 fprintf(stdout, _("enabled \n"));
4781 fprintf(stdout, _("disabled \n"));
4784 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4785 CurrentGetBitmap->size+=MessageBuffer[count++];
4787 fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
4791 CurrentGetBitmap->width=MessageBuffer[count++];
4792 CurrentGetBitmap->height=MessageBuffer[count++];
4794 tmp=GSM_GetBitmapSize(CurrentGetBitmap);
4795 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4796 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
4797 CurrentGetBitmapError=GE_NONE;
4800 fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
4805 fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
4810 /* Get group data error */
4813 CurrentGetBitmapError=GE_UNKNOWN;
4815 fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
4819 /* Set group data OK */
4822 CurrentSetBitmapError=GE_NONE;
4824 fprintf(stdout, _("Message: Caller group data set correctly.\n"));
4828 /* Set group data error */
4831 CurrentSetBitmapError=GE_UNKNOWN;
4833 fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
4840 fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
4842 AppendLogText("Unknown msg\n",false);
4844 break; /* Visual C Don't like empty cases */
4848 void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4850 int tmp, count, length;
4857 switch (MessageBuffer[3]) {
4863 fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
4866 if (CurrentGetBitmap!=NULL) {
4872 for (tmp=0;tmp<MessageBuffer[4];tmp++){
4873 switch (MessageBuffer[count++]) {
4875 if (CurrentGetBitmap->type==GSM_StartupLogo) {
4876 CurrentGetBitmap->height=MessageBuffer[count++];
4877 CurrentGetBitmap->width=MessageBuffer[count++];
4878 CurrentGetBitmap->size=GSM_GetBitmapSize(CurrentGetBitmap);
4879 length=CurrentGetBitmap->size;
4880 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
4883 length=MessageBuffer[count++];
4884 length=length*MessageBuffer[count++]/8;
4888 fprintf(stdout, _("Startup logo supported - "));
4889 if (length!=0) { fprintf(stdout, _("currently set\n")); }
4890 else { fprintf(stdout, _("currently empty\n")); }
4892 if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
4895 length=MessageBuffer[count];
4896 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
4897 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
4898 CurrentGetBitmap->text[length]=0;
4901 fprintf(stdout, _("Startup Text supported - "));
4904 fprintf(stdout, _("currently set to \""));
4905 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
4906 fprintf(stdout, _("\"\n"));
4908 fprintf(stdout, _("currently empty\n"));
4912 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
4915 length=MessageBuffer[count];
4916 if (CurrentGetBitmap->type==GSM_DealerNoteText) {
4917 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
4918 CurrentGetBitmap->text[length]=0;
4921 fprintf(stdout, _("Dealer Welcome supported - "));
4924 fprintf(stdout, _("currently set to \""));
4925 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
4926 fprintf(stdout, _("\"\n"));
4928 fprintf(stdout, _("currently empty\n"));
4932 if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
4936 if (issupported) CurrentGetBitmapError=GE_NONE;
4937 else CurrentGetBitmapError=GE_NOTSUPPORTED;
4940 fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
4945 /* Set startup OK */
4948 CurrentSetBitmapError=GE_NONE;
4950 fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
4954 /* Set Operator Logo OK */
4958 fprintf(stdout, _("Message: Operator logo correctly set.\n"));
4961 CurrentSetBitmapError=GE_NONE;
4964 /* Set Operator Logo Error */
4968 fprintf(stdout, _("Message: Error setting operator logo!\n"));
4971 CurrentSetBitmapError=GE_UNKNOWN;
4975 /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
4978 if (CurrentGetBitmap!=NULL) {
4980 count=5; /* Location ignored. */
4982 DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
4986 fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
4987 CurrentGetBitmap->netcode,
4988 GSM_GetNetworkName(CurrentGetBitmap->netcode));
4991 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4992 CurrentGetBitmap->size+=MessageBuffer[count++];
4994 CurrentGetBitmap->width=MessageBuffer[count++];
4995 CurrentGetBitmap->height=MessageBuffer[count++];
4997 tmp=GSM_GetBitmapSize(CurrentGetBitmap);
4998 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4999 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
5000 CurrentGetBitmapError=GE_NONE;
5003 fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
5009 /* Get op logo error */
5013 fprintf(stdout, _("Message: Error getting operator logo!\n"));
5015 CurrentGetBitmapError=GE_UNKNOWN;
5021 fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
5023 AppendLogText("Unknown msg\n",false);
5029 void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5032 unsigned char output[160];
5038 switch (MessageBuffer[3]) {
5042 /* MessageBuffer[3] = 0x05
5043 MessageBuffer[4] = 0x00
5044 MessageBuffer[5] = 0x0f
5045 MessageBuffer[6] = 0x03
5046 MessageBuffer[7] = length of packed message
5048 This is all I have seen - Gerry Anderson */
5050 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
5054 fprintf(stdout, _("Message from Network operator: "));
5056 for (i=0; i<tmp; i++)
5057 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
5059 fprintf(stdout, "\n");
5068 fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
5070 AppendLogText("Unknown msg\n",false);
5076 void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5078 switch (MessageBuffer[3]) {
5082 fprintf(stdout, _("Message: SIM card login\n"));
5088 fprintf(stdout, _("Message: SIM card logout\n"));
5094 fprintf(stdout, _("Unknown message of type 0x09.\n"));
5096 AppendLogText("Unknown msg\n",false);
5101 void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5103 switch(MessageBuffer[3]) {
5108 fprintf(stdout, _("Message: Calendar Alarm active\n"));
5109 fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
5114 fprintf(stdout, _("Unknown message of type 0x13.\n"));
5116 AppendLogText("Unknown msg\n",false);
5121 void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5125 switch(MessageBuffer[2]) {
5130 fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
5133 CurrentMagicError=GE_NONE;
5139 fprintf(stdout, _("Message: Answer for call commands.\n"));
5142 CurrentDialVoiceError=GE_NONE;
5148 fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
5151 CurrentMagicError=GE_NONE;
5157 fprintf(stdout, _("Message: ACK for simlock closing\n"));
5160 CurrentMagicError=GE_NONE;
5165 switch (MessageBuffer[5]) {
5168 fprintf(stdout,_("Message: EEPROM contest received\n"));
5171 if (MessageBuffer[8]!=0x00) {
5172 for (i=9;i<MessageLength;i++) {
5173 fprintf(stdout,_("%c"), MessageBuffer[i]);
5176 CurrentMagicError=GE_NONE;
5183 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5185 AppendLogText("Unknown msg\n",false);
5190 N6110_DisplayTestsInfo(MessageBuffer);
5196 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5198 AppendLogText("Unknown msg\n",false);
5199 break; /* Visual C Don't like empty cases */
5203 void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5207 switch(MessageBuffer[3]) {
5213 if (MessageBuffer[5]!=0) {
5214 strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
5216 while (MessageBuffer[count]!=0) {
5222 strcpy(CurrentGetBitmap->Sender,"\0");
5227 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
5228 CurrentGetBitmap->text[MessageBuffer[count]]=0;
5230 if (MessageBuffer[count]!=0)
5231 count+=MessageBuffer[count];
5236 fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
5239 CurrentGetBitmap->width=MessageBuffer[count+1];
5240 CurrentGetBitmap->height=MessageBuffer[count+2];
5241 CurrentGetBitmap->size=GSM_GetBitmapSize(CurrentGetBitmap);
5243 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
5245 CurrentGetBitmapError=GE_NONE;
5251 fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
5253 CurrentSetBitmapError=GE_NONE;
5254 CurrentGetBitmapError=GE_NONE;
5260 fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
5262 CurrentSetBitmapError=GE_UNKNOWN;
5268 fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
5270 CurrentGetBitmapError=GE_UNKNOWN;
5276 fprintf(stdout, _("Unknown message of type 0x47.\n"));
5278 AppendLogText("Unknown msg\n",false);
5279 break; /* Visual C Don't like empty cases */
5283 void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5286 sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
5287 AppendLog(buffer,strlen(buffer),false);
5290 fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
5294 CurrentLinkOK = true;
5297 void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5300 fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
5305 /* This function is used for parsing the RLP frame into fields. */
5306 void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
5313 /* We do not need RLP frame parsing to be done when we do not have callback
5315 if (CurrentRLP_RXCallback == NULL)
5318 /* Anybody know the official meaning of the first two bytes?
5319 Nokia 6150 sends junk frames starting D9 01, and real frames starting
5320 D9 00. We'd drop the junk frames anyway because the FCS is bad, but
5321 it's tidier to do it here. We still need to call the callback function
5322 to give it a chance to handle timeouts and/or transmit a frame */
5323 if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
5326 /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
5327 specification, so Header consists of 16 bits (2 bytes). See section 4.1
5328 of the specification. */
5330 frame.Header[0] = MessageBuffer[2];
5331 frame.Header[1] = MessageBuffer[3];
5333 /* Next 200 bits (25 bytes) contain the Information. We store the
5334 information in the Data array. */
5336 for (count = 0; count < 25; count ++)
5337 frame.Data[count] = MessageBuffer[4 + count];
5339 /* The last 24 bits (3 bytes) contain FCS. */
5341 frame.FCS[0] = MessageBuffer[29];
5342 frame.FCS[1] = MessageBuffer[30];
5343 frame.FCS[2] = MessageBuffer[31];
5345 /* Here we pass the frame down in the input stream. */
5346 CurrentRLP_RXCallback(valid ? &frame : NULL);
5349 void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5352 fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
5357 void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5359 GSM_SMSMessage NullSMS;
5361 switch (MessageBuffer[6]) {
5363 case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
5364 case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
5366 /* Is it possible ? */
5367 case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
5368 default: NullSMS.Type = GST_UN; break;
5372 if (NullSMS.Type == GST_DR)
5373 fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
5375 fprintf(stdout, _("Message: SMS Message Received\n"));
5378 GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
5381 fprintf(stdout, _("\n"));
5385 void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5389 /* Switch on the basis of the message type byte */
5390 switch (MessageType) {
5392 /* Call information */
5395 N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
5400 switch (MessageBuffer[3]) {
5402 case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5403 case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
5404 case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5405 case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5406 case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5408 case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5409 default :unknown=true;break;
5413 /* Phonebook handling */
5415 switch (MessageBuffer[3]) {
5417 case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
5419 case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
5421 case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
5423 case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5425 case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5426 default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
5432 switch (MessageBuffer[3]) {
5433 case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
5434 default :unknown=true;break;
5438 /* Startup Logo, Operator Logo and Profiles. */
5440 switch (MessageBuffer[3]) {
5441 case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5442 case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5443 case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5444 case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5445 case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5446 case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5447 default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
5451 /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
5454 switch (MessageBuffer[3]) {
5456 case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
5457 default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
5461 /* Security code requests */
5463 switch (MessageBuffer[3]) {
5464 case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
5465 case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5466 default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5473 N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
5478 switch (MessageBuffer[3]) {
5479 case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
5480 default :unknown=true;break;
5484 /* Simulating key pressing */
5486 switch (MessageBuffer[3]) {
5487 case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
5488 default :unknown=true;break;
5494 switch (MessageBuffer[3]) {
5495 case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5496 case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
5497 case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5498 default :unknown=true;break;
5502 /* Phone Clock and Alarm */
5504 switch (MessageBuffer[3]) {
5505 case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
5506 case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
5507 case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
5508 case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
5509 default :unknown=true;break;
5513 /* Calendar notes handling */
5515 switch (MessageBuffer[3]) {
5516 case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5517 case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5518 case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
5519 default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
5525 switch (MessageBuffer[3]) {
5527 case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5529 case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5530 case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5532 case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
5533 default :unknown=true;break;
5539 switch (MessageBuffer[3]) {
5541 case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
5543 case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5545 case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5548 case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
5549 default :unknown=true;break;
5553 /* Internal phone functions? */
5555 switch (MessageBuffer[2]) {
5556 case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
5557 case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
5558 case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
5559 case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5560 case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5561 case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5562 case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
5563 case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
5564 case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5565 case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5566 case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
5567 case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5568 case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5569 case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
5570 default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
5574 /* Picture Images */
5577 N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
5580 /* Mobile phone identification */
5583 N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
5586 /***** Acknowlegment of our frames. *****/
5587 case FBUS_FRTYPE_ACK:
5589 N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
5592 /***** Power on message. *****/
5595 N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
5600 N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
5603 /***** RLP frame received. *****/
5606 N6110_RX_HandleRLPMessage(MessageBuffer);
5609 /***** Power on message. *****/
5612 N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
5615 /***** Unknown message *****/
5616 /* If you think that you know the exact meaning of other messages - please
5621 fprintf(stdout, _("Message: Unknown message type.\n"));
5623 AppendLogText("Unknown msg type\n",false);
5632 fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
5634 AppendLogText("Unknown msg\n",false);