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",
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 switch (MessageBuffer[6]) {
721 case 0x43: CurrentCallDivert->DType=GSM_CDV_Busy;break;
722 case 0x3d: CurrentCallDivert->DType=GSM_CDV_NoAnswer;break;
723 case 0x3e: CurrentCallDivert->DType=GSM_CDV_OutOfReach;break;
724 case 0x15: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
725 case 0x02: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
728 if (MessageBuffer[6]==0x02) //?
729 CurrentCallDivert->CType=GSM_CDV_AllCalls;
731 switch (MessageBuffer[8]) {
732 case 0x0b: CurrentCallDivert->CType=GSM_CDV_VoiceCalls;break;
733 case 0x0d: CurrentCallDivert->CType=GSM_CDV_FaxCalls; break;
734 case 0x19: CurrentCallDivert->CType=GSM_CDV_DataCalls; break;
738 if (MessageBuffer[10]==0x01) {
739 CurrentCallDivert->Enabled=true;
740 CurrentCallDivert->Timeout=MessageBuffer[45];
741 strcpy(CurrentCallDivert->Number,GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
743 CurrentCallDivert->Enabled=false;
746 CurrentCallDivertError=GE_NONE;
751 fprintf(stdout, _("Message: Call divert status receiving error ?\n"));
753 CurrentCallDivertError=GE_UNKNOWN;
758 GSM_Error N6110_CallDivert(GSM_CallDivert *cd)
760 char req[55] = { N6110_FRAME_HEADER, 0x01,
761 0x00, /* operation */
763 0x00, /* divert type */
764 0x00, /* call type */
770 switch (cd->Operation) {
771 case GSM_CDV_Register:
775 req[29]= GSM_PackSemiOctetNumber(cd->Number, req + 9, false);
776 req[52]= cd->Timeout;
779 case GSM_CDV_Erasure:
780 case GSM_CDV_Disable:
787 return GE_NOTIMPLEMENTED;
791 case GSM_CDV_AllTypes : req[6] = 0x15; break;
792 case GSM_CDV_Busy : req[6] = 0x43; break;
793 case GSM_CDV_NoAnswer : req[6] = 0x3d; break;
794 case GSM_CDV_OutOfReach: req[6] = 0x3e; break;
795 default: return GE_NOTIMPLEMENTED;
798 if ((cd->DType == GSM_CDV_AllTypes) &&
799 (cd->CType == GSM_CDV_AllCalls))
803 case GSM_CDV_AllCalls : break;
804 case GSM_CDV_VoiceCalls: req[7] = 0x0b; break;
805 case GSM_CDV_FaxCalls : req[7] = 0x0d; break;
806 case GSM_CDV_DataCalls : req[7] = 0x19; break;
807 default: return GE_NOTIMPLEMENTED;
810 CurrentCallDivert = cd;
812 error=NULL_SendMessageSequence
813 (100, &CurrentCallDivertError, length, 0x06, req);
815 CurrentCallDivert = NULL;
820 GSM_Error N6110_Tests()
822 unsigned char buffer[3]={0x00,0x01,0xcf};
823 unsigned char buffer3[8]={0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00};
827 error=N6110_EnableExtendedCommands(0x01);
828 if (error!=GE_NONE) return error;
830 //make almost all tests
831 Protocol->SendMessage(8, 0x40, buffer3);
833 while (GSM->Initialise(PortDevice, "50", CurrentConnectionType, CurrentRLP_RXCallback)!=GE_NONE) {};
837 return NULL_SendMessageSequence
838 (200, &CurrentNetworkInfoError, 3, 0x40, buffer);
841 void N6110_DisplayTestsInfo(u8 *MessageBuffer) {
845 CurrentNetworkInfoError=GE_NONE;
847 for (i=0;i<MessageBuffer[3];i++) {
849 case 0: fprintf(stdout,_("Unknown(%i) "),i);break;
850 case 1: fprintf(stdout,_("MCU ROM checksum "));break;
851 case 2: fprintf(stdout,_("MCU RAM interface "));break;
852 case 3: fprintf(stdout,_("MCU RAM component "));break;
853 case 4: fprintf(stdout,_("MCU EEPROM interface "));break;
854 case 5: fprintf(stdout,_("MCU EEPROM component "));break;
855 case 6: fprintf(stdout,_("Real Time Clock battery "));break;
856 case 7: fprintf(stdout,_("CCONT interface "));break;
857 case 8: fprintf(stdout,_("AD converter "));break;
858 case 9: fprintf(stdout,_("SW Reset "));break;
859 case 10:fprintf(stdout,_("Power Off "));break;
860 case 11:fprintf(stdout,_("Security Data "));break;
861 case 12:fprintf(stdout,_("EEPROM Tune checksum "));break;
862 case 13:fprintf(stdout,_("PPM checksum "));break;
863 case 14:fprintf(stdout,_("MCU download DSP "));break;
864 case 15:fprintf(stdout,_("DSP alive "));break;
865 case 16:fprintf(stdout,_("COBBA serial "));break;
866 case 17:fprintf(stdout,_("COBBA paraller "));break;
867 case 18:fprintf(stdout,_("EEPROM security checksum"));break;
868 case 19:fprintf(stdout,_("PPM validity "));break;
869 case 20:fprintf(stdout,_("Warranty state "));break;
870 case 21:fprintf(stdout,_("Simlock check "));break;
871 case 22:fprintf(stdout,_("IMEI check? "));break;//from PC-Locals.is OK?
872 default:fprintf(stdout,_("Unknown(%i) "),i);break;
874 switch (MessageBuffer[4+i]) {
875 case 0: fprintf(stdout,_(" : done, result OK"));break;
876 case 0xff:fprintf(stdout,_(" : not done, result unknown"));break;
877 case 254: fprintf(stdout,_(" : done, result NOT OK"));break;
878 default: fprintf(stdout,_(" : result unknown(%i)"),MessageBuffer[4+i]);break;
880 fprintf(stdout,_("\n"));
884 void N6110_ReplySimlockInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
891 fprintf(stdout, _("Message: Simlock info received\n"));
894 for (i=0; i < 12; i++)
897 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] >> 4)));
900 if (j==5 || j==15) fprintf(stdout, _("\n"));
903 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] & 0x0f)));
907 if (j==20 || j==24) fprintf(stdout, _("\n"));
910 if ((MessageBuffer[6] & 1) == 1) fprintf(stdout,_("lock 1 closed\n"));
911 if ((MessageBuffer[6] & 2) == 2) fprintf(stdout,_("lock 2 closed\n"));
912 if ((MessageBuffer[6] & 4) == 4) fprintf(stdout,_("lock 3 closed\n"));
913 if ((MessageBuffer[6] & 8) == 8) fprintf(stdout,_("lock 4 closed\n"));
915 /* I'm not sure here at all */
916 if ((MessageBuffer[5] & 1) == 1) fprintf(stdout,_("lock 1 - user\n"));
917 if ((MessageBuffer[5] & 2) == 2) fprintf(stdout,_("lock 2 - user\n"));
918 if ((MessageBuffer[5] & 4) == 4) fprintf(stdout,_("lock 3 - user\n"));
919 if ((MessageBuffer[5] & 8) == 8) fprintf(stdout,_("lock 4 - user\n"));
921 fprintf(stdout,_("counter for lock1: %i\n"),MessageBuffer[21]);
922 fprintf(stdout,_("counter for lock2: %i\n"),MessageBuffer[22]);
923 fprintf(stdout,_("counter for lock3: %i\n"),MessageBuffer[23]);
924 fprintf(stdout,_("counter for lock4: %i\n"),MessageBuffer[24]);
929 for (i=0; i < 12; i++)
932 uni[j]='0' + (MessageBuffer[9+i] >> 4);
937 uni[j]='0' + (MessageBuffer[9+i] & 0x0f);
943 strncpy(CurrentSimLock->simlocks[0].data,uni,5);
944 CurrentSimLock->simlocks[0].data[5]=0;
945 strncpy(CurrentSimLock->simlocks[3].data,uni+5,10);
946 CurrentSimLock->simlocks[3].data[10]=0;
947 strncpy(CurrentSimLock->simlocks[1].data,uni+16,4);
948 CurrentSimLock->simlocks[1].data[4]=0;
949 strncpy(CurrentSimLock->simlocks[2].data,uni+20,4);
950 CurrentSimLock->simlocks[2].data[4]=0;
952 CurrentSimLock->simlocks[0].enabled=((MessageBuffer[6] & 1) == 1);
953 CurrentSimLock->simlocks[1].enabled=((MessageBuffer[6] & 2) == 2);
954 CurrentSimLock->simlocks[2].enabled=((MessageBuffer[6] & 4) == 4);
955 CurrentSimLock->simlocks[3].enabled=((MessageBuffer[6] & 8) == 8);
957 CurrentSimLock->simlocks[0].factory=((MessageBuffer[5] & 1) != 1);
958 CurrentSimLock->simlocks[1].factory=((MessageBuffer[5] & 2) != 2);
959 CurrentSimLock->simlocks[2].factory=((MessageBuffer[5] & 4) != 4);
960 CurrentSimLock->simlocks[3].factory=((MessageBuffer[5] & 8) != 8);
962 CurrentSimLock->simlocks[0].counter=MessageBuffer[21];
963 CurrentSimLock->simlocks[1].counter=MessageBuffer[22];
964 CurrentSimLock->simlocks[2].counter=MessageBuffer[23];
965 CurrentSimLock->simlocks[3].counter=MessageBuffer[24];
967 CurrentSimlockInfoError=GE_NONE;
970 GSM_Error N6110_SimlockInfo(GSM_AllSimlocks *siml)
973 unsigned char req[] = {0x00,0x01,0x8a,0x00};
974 error=N6110_EnableExtendedCommands(0x01);
975 if (error!=GE_NONE) return error;
979 return NULL_SendMessageSequence (50, &CurrentSimlockInfoError, 4, 0x40, req);
982 void N6110_ReplyResetPhoneSettings(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
985 fprintf(stdout, _("Message: Resetting phone settings\n"));
988 CurrentResetPhoneSettingsError=GE_NONE;
991 GSM_Error N6110_ResetPhoneSettings()
994 unsigned char req[] = {0x00,0x01,0x65,0x08,0x00};
995 error=N6110_EnableExtendedCommands(0x01);
996 if (error!=GE_NONE) return error;
998 return NULL_SendMessageSequence
999 (50, &CurrentResetPhoneSettingsError, 5, 0x40, req);
1001 GSM_Error N6110_GetManufacturer(char *manufacturer)
1003 strcpy (manufacturer, "Nokia");
1007 GSM_Error N6110_GetVoiceMailbox ( GSM_PhonebookEntry *entry)
1009 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
1013 CurrentPhonebookEntry = entry;
1015 req[4] = N6110_MEMORY_VOICE;
1016 req[5] = 0x00; /* Location - isn't important, but... */
1018 error=NULL_SendMessageSequence
1019 (20, &CurrentPhonebookError, 7, 0x03, req);
1021 CurrentPhonebookEntry = NULL;
1026 void N6110_ReplyGetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1030 GSM_Bitmap NullBitmap;
1032 DecodeNetworkCode(MessageBuffer+5, NullBitmap.netcode);
1037 fprintf(stdout, _("Message: Info about downloaded operator name received: %s network (for gnokii \"%s\", for phone \""),
1039 GSM_GetNetworkName(NullBitmap.netcode));
1043 while (MessageBuffer[count]!=0) {
1045 fprintf(stdout,_("%c"),MessageBuffer[count]);
1050 strcpy(CurrentGetOperatorNameNetwork->Code, NullBitmap.netcode);
1051 strncpy(CurrentGetOperatorNameNetwork->Name, MessageBuffer+i,count-i+1);
1054 fprintf(stdout,_("\")\n"));
1057 CurrentGetOperatorNameError=GE_NONE;
1060 GSM_Error N6110_GetOperatorName (GSM_Network *operator)
1062 unsigned char req[] = { 0x00,0x01,0x8c,0x00};
1066 error=N6110_EnableExtendedCommands(0x01);
1067 if (error!=GE_NONE) return error;
1069 CurrentGetOperatorNameNetwork = operator;
1071 error=NULL_SendMessageSequence
1072 (20, &CurrentGetOperatorNameError, 4, 0x40, req);
1074 CurrentGetOperatorNameNetwork = NULL;
1079 void N6110_ReplySetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1082 fprintf(stdout, _("Message: Downloaded operator name changed\n"));
1085 CurrentSetOperatorNameError=GE_NONE;
1088 GSM_Error N6110_SetOperatorName (GSM_Network *operator)
1090 unsigned char req[256] = { 0x00,0x01,0x8b,0x00,
1091 0x00,0x00, /* MCC */
1096 error=N6110_EnableExtendedCommands(0x01);
1097 if (error!=GE_NONE) return error;
1099 EncodeNetworkCode(req+4,operator->Code);
1101 strncpy(req+7,operator->Name,200);
1103 return NULL_SendMessageSequence
1104 (20, &CurrentSetOperatorNameError, 8+strlen(operator->Name), 0x40, req);
1107 void N6110_ReplyGetMemoryStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1109 switch (MessageBuffer[3]) {
1114 fprintf(stdout, _("Message: Memory status received:\n"));
1116 fprintf(stdout, _(" Memory Type: %s\n"), N6110_MemoryType_String[MessageBuffer[4]]);
1117 fprintf(stdout, _(" Used: %d\n"), MessageBuffer[6]);
1118 fprintf(stdout, _(" Free: %d\n"), MessageBuffer[5]);
1121 CurrentMemoryStatus->Used = MessageBuffer[6];
1122 CurrentMemoryStatus->Free = MessageBuffer[5];
1123 CurrentMemoryStatusError = GE_NONE;
1130 switch (MessageBuffer[4]) {
1132 fprintf(stdout, _("Message: Memory status error, phone is probably powered off.\n"));break;
1134 fprintf(stdout, _("Message: Memory status error, memory type not supported by phone model.\n"));break;
1136 fprintf(stdout, _("Message: Memory status error, waiting for security code.\n"));break;
1138 fprintf(stdout, _("Message: Unknown Memory status error, subtype (MessageBuffer[4]) = %02x\n"),MessageBuffer[4]);break;
1142 switch (MessageBuffer[4]) {
1143 case 0x6f:CurrentMemoryStatusError = GE_TIMEOUT;break;
1144 case 0x7d:CurrentMemoryStatusError = GE_INTERNALERROR;break;
1145 case 0x8d:CurrentMemoryStatusError = GE_INVALIDSECURITYCODE;break;
1154 /* This function is used to get storage status from the phone. It currently
1155 supports two different memory areas - internal and SIM. */
1156 GSM_Error N6110_GetMemoryStatus(GSM_MemoryStatus *Status)
1158 unsigned char req[] = { N6110_FRAME_HEADER,
1159 0x07, /* MemoryStatus request */
1160 0x00 /* MemoryType */
1165 CurrentMemoryStatus = Status;
1167 req[4] = N6110_GetMemoryType(Status->MemoryType);
1169 error=NULL_SendMessageSequence
1170 (20, &CurrentMemoryStatusError, 5, 0x03, req);
1172 CurrentMemoryStatus = NULL;
1177 void N6110_ReplyGetNetworkInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1179 GSM_NetworkInfo NullNetworkInfo;
1181 /* Make sure we are expecting NetworkInfo frame */
1182 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY) {
1184 fprintf(stdout, _("Message: Network informations:\n"));
1188 fprintf(stdout, _("Message: Network informations not requested, but received:\n"));
1192 sprintf(NullNetworkInfo.NetworkCode, "%x%x%x %x%x", MessageBuffer[14] & 0x0f, MessageBuffer[14] >>4, MessageBuffer[15] & 0x0f, MessageBuffer[16] & 0x0f, MessageBuffer[16] >>4);
1194 sprintf(NullNetworkInfo.CellID, "%02x%02x", MessageBuffer[10], MessageBuffer[11]);
1196 sprintf(NullNetworkInfo.LAC, "%02x%02x", MessageBuffer[12], MessageBuffer[13]);
1199 fprintf(stdout, _(" CellID: %s\n"), NullNetworkInfo.CellID);
1200 fprintf(stdout, _(" LAC: %s\n"), NullNetworkInfo.LAC);
1201 fprintf(stdout, _(" Network code: %s\n"), NullNetworkInfo.NetworkCode);
1202 fprintf(stdout, _(" Network name: %s (%s)\n"),
1203 GSM_GetNetworkName(NullNetworkInfo.NetworkCode),
1204 GSM_GetCountryName(NullNetworkInfo.NetworkCode));
1205 fprintf(stdout, _(" Status: "));
1207 switch (MessageBuffer[8]) {
1208 case 0x01: fprintf(stdout, _("home network selected")); break;
1209 case 0x02: fprintf(stdout, _("roaming network")); break;
1210 case 0x03: fprintf(stdout, _("requesting network")); break;
1211 case 0x04: fprintf(stdout, _("not registered in the network")); break;
1212 default: fprintf(stdout, _("unknown"));
1215 fprintf(stdout, "\n");
1217 fprintf(stdout, _(" Network selection: %s\n"), MessageBuffer[9]==1?_("manual"):_("automatic"));
1220 /* Make sure we are expecting NetworkInfo frame */
1221 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY)
1222 *CurrentNetworkInfo=NullNetworkInfo;
1224 CurrentNetworkInfoError = GE_NONE;
1227 GSM_Error N6110_GetNetworkInfo(GSM_NetworkInfo *NetworkInfo)
1229 unsigned char req[] = { N6110_FRAME_HEADER,
1235 CurrentNetworkInfo = NetworkInfo;
1237 error=NULL_SendMessageSequence
1238 (20, &CurrentNetworkInfoError, 4, 0x0a, req);
1240 CurrentNetworkInfo = NULL;
1245 void N6110_ReplyGetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1250 fprintf(stdout, _("Message: Product Profile Settings received -"));
1251 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),MessageBuffer[3+i]);
1252 fprintf(stdout, _("\n"));
1255 for (i=0;i<4;i++) CurrentPPS[i]=MessageBuffer[3+i];
1257 CurrentProductProfileSettingsError=GE_NONE;
1260 GSM_Error N6110_GetProductProfileSetting (GSM_PPS *PPS)
1262 unsigned char req[] = { 0x00, 0x01,0x6a };
1268 error=N6110_EnableExtendedCommands(0x01);
1269 if (error!=GE_NONE) return error;
1271 error=NULL_SendMessageSequence
1272 (20, &CurrentProductProfileSettingsError, 3, 0x40, req);
1273 if (error!=GE_NONE) return error;
1275 switch (PPS->Name) {
1276 case PPS_ALS : PPS->bool_value=(CurrentPPS[1]&32); break;
1277 case PPS_GamesMenu: PPS->bool_value=(CurrentPPS[3]&64); break;
1278 case PPS_HRData : PPS->bool_value=(CurrentPPS[0]&64); break;
1279 case PPS_14400Data: PPS->bool_value=(CurrentPPS[0]&128);break;
1280 case PPS_EFR : PPS->int_value =(CurrentPPS[0]&1) +(CurrentPPS[0]&2); break;
1281 case PPS_FR : PPS->int_value =(CurrentPPS[0]&16)/16+(CurrentPPS[0]&32)/16;break;
1282 case PPS_HR : PPS->int_value =(CurrentPPS[0]&4)/4 +(CurrentPPS[0]&8)/4; break;
1283 case PPS_VibraMenu: PPS->bool_value=(CurrentPPS[4]&64); break;
1284 case PPS_LCDContrast:
1288 if (CurrentPPS[3]&j) PPS->int_value=PPS->int_value+j;
1291 PPS->int_value=PPS->int_value*100/32;
1299 void N6110_ReplySetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1304 fprintf(stdout, _("Message: Product Profile Settings set to"));
1305 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),CurrentPPS[i]);
1306 fprintf(stdout, _("\n"));
1309 CurrentProductProfileSettingsError=GE_NONE;
1312 GSM_Error N6110_SetProductProfileSetting (GSM_PPS *PPS)
1314 unsigned char req[] = { 0x00, 0x01,0x6b,
1315 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */
1316 unsigned char settings[32];
1324 error=N6110_EnableExtendedCommands(0x01);
1325 if (error!=GE_NONE) return error;
1327 OldPPS.Name=PPS_ALS;
1328 error=N6110_GetProductProfileSetting(&OldPPS);
1329 if (error!=GE_NONE) return error;
1332 for (i=0;i<32;i++) {
1333 if (CurrentPPS[z]&j)
1344 fprintf(stdout,_("Current settings: "));
1345 for (i=0;i<32;i++) {
1346 fprintf(stdout,_("%c"),settings[i]);
1348 fprintf(stdout,_("\n"));
1351 switch (PPS->Name) {
1352 case PPS_ALS :settings[10]=PPS->bool_value?'1':'0';break;
1353 case PPS_HRData :settings[ 5]=PPS->bool_value?'1':'0';break;
1354 case PPS_14400Data:settings[ 6]=PPS->bool_value?'1':'0';break;
1359 for (i=0;i<32;i++) {
1360 if (settings[i]=='1') req[z+3]=req[z+3]+j;
1368 fprintf(stdout,_("Current settings: "));
1370 fprintf(stdout,_("%i "),req[i+3]);
1372 fprintf(stdout,_("\n"));
1376 CurrentPPS[i]=req[i+3];
1379 return NULL_SendMessageSequence
1380 (20, &CurrentProductProfileSettingsError, 7, 0x40, req);
1383 void N6110_ReplyPressKey(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1385 if (MessageBuffer[4]==CurrentPressKeyEvent) CurrentPressKeyError=GE_NONE;
1386 else CurrentPressKeyError=GE_UNKNOWN; /* MessageBuffer[4] = 0x05 */
1388 fprintf(stdout, _("Message: Result of key "));
1389 switch (MessageBuffer[4])
1391 case PRESSPHONEKEY: fprintf(stdout, _("press OK\n"));break;
1392 case RELEASEPHONEKEY: fprintf(stdout, _("release OK\n"));break;
1393 default: fprintf(stdout, _("press or release - error\n"));break;
1398 GSM_Error N6110_PressKey(int key, int event)
1400 unsigned char req[] = {N6110_FRAME_HEADER, 0x42, 0x01, 0x00, 0x01};
1402 req[4]=event; /* if we press or release key */
1405 CurrentPressKeyEvent=event;
1407 return NULL_SendMessageSequence
1408 (10, &CurrentPressKeyError, 7, 0x0c, req);
1411 void N6110_ReplyDisplayOutput(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1413 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
1420 switch(MessageBuffer[3]) {
1422 /* Phone sends displayed texts */
1424 NewX=MessageBuffer[6];
1425 NewY=MessageBuffer[5];
1427 DecodeUnicode (uni, MessageBuffer+8, MessageBuffer[7]);
1430 fprintf(stdout, _("New displayed text (%i %i): \"%s\"\n"),NewX,NewY,uni);
1433 while (N6110_GetModel(model) != GE_NONE)
1436 /* With these rules it works almost excellent with my N5110 */
1437 /* I don't have general rule :-(, that's why you must experiment */
1438 /* with your phone. Nokia could make it better. MW */
1439 /* It's almost OK for N5110*/
1440 /* FIX ME: it will be the same for N5130 and 3210 too*/
1441 if (!strcmp(model,"NSE-1"))
1443 /* OldX==1000 means - it's first time */
1447 for (i=0;i<5+1;i++) {
1448 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1453 if ((OldX==0 && OldY==31 && NewX==29 && NewY==46) ||
1454 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1455 /* Clean the line with current text */
1456 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1458 /* Inserts text into table */
1459 for (i=0; i<MessageBuffer[7];i++) {
1460 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1465 if ((OldX==0 && OldY==21 && NewX==0 && NewY==10) ||
1466 (OldX==0 && OldY==10 && NewX==35 && NewY==46)) {
1468 if ((OldX!=0 && NewX==0 && NewY!=6) ||
1469 (OldX==0 && NewX!=0 && OldY!=13 && OldY!=22) ||
1470 (OldX==0 && NewX==0 && NewY<OldY && (NewY!=13 || OldY!=26)) ||
1471 (OldY==5 && NewY!=5) ||
1472 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1474 /* Writes "old" screen */
1475 for (i=0;i<5+1;i++) {
1476 for (j=0;j<27+1;j++) {fprintf(stdout,_("%c"),PhoneScreen[i][j]);}
1477 fprintf(stdout,_("\n"));
1481 for (i=0;i<5+1;i++) {
1482 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1487 /* Clean the line with current text */
1488 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1490 /* Inserts text into table */
1491 for (i=0; i<MessageBuffer[7];i++) {
1492 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1499 fprintf(stdout, _("%s\n"),uni);
1507 if (MessageBuffer[4]==1)
1511 fprintf(stdout, _("Display output successfully disabled/enabled.\n"));
1514 CurrentDisplayOutputError=GE_NONE;
1521 GSM_Error SetDisplayOutput(unsigned char state)
1523 unsigned char req[] = { N6110_FRAME_HEADER,
1528 return NULL_SendMessageSequence
1529 (30, &CurrentDisplayOutputError, 5, 0x0d, req);
1532 GSM_Error N6110_EnableDisplayOutput()
1534 return SetDisplayOutput(0x01);
1537 GSM_Error N6110_DisableDisplayOutput()
1539 return SetDisplayOutput(0x02);
1542 /* If it is interesting for somebody: we can use 0x40 msg for it
1543 and it will work for all phones. See n6110.txt for details */
1544 GSM_Error N6110_AnswerCall(char s)
1546 unsigned char req0[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,0x07, 0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
1547 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80};
1548 unsigned char req[] = { N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
1553 fprintf(stdout,_("Answering call %d\n\r"),s);
1556 Protocol->SendMessage(sizeof(req0), 0x01, req0);
1559 return NULL_SendMessageSequence
1560 (20, &CurrentMagicError, sizeof(req) , 0x01, req);
1563 void N6110_ReplyGetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1565 switch (MessageBuffer[3]) {
1567 /* Profile feature */
1570 switch(GetModelFeature (FN_PROFILES)) {
1572 switch (MessageBuffer[6]) {
1573 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8]; break;
1574 case 0x01: CurrentProfile->CallAlert = MessageBuffer[8]; break;
1575 case 0x02: CurrentProfile->Ringtone = MessageBuffer[8]; break;
1576 case 0x03: CurrentProfile->Volume = MessageBuffer[8]; break;
1577 case 0x04: CurrentProfile->MessageTone = MessageBuffer[8]; break;
1578 case 0x05: CurrentProfile->Vibration = MessageBuffer[8]; break;
1579 case 0x06: CurrentProfile->WarningTone = MessageBuffer[8]; break;
1580 case 0x07: CurrentProfile->ScreenSaver = MessageBuffer[8]; break;
1583 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1589 switch (MessageBuffer[6]) {
1590 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8];break;
1591 case 0x01: CurrentProfile->Lights = MessageBuffer[8];break;
1592 case 0x02: CurrentProfile->CallAlert = MessageBuffer[8];break;
1593 case 0x03: CurrentProfile->Ringtone = MessageBuffer[8];break;
1594 case 0x04: CurrentProfile->Volume = MessageBuffer[8];break;
1595 case 0x05: CurrentProfile->MessageTone = MessageBuffer[8];break;
1596 case 0x06: CurrentProfile->Vibration = MessageBuffer[8];break;
1597 case 0x07: CurrentProfile->WarningTone = MessageBuffer[8];break;
1598 case 0x08: CurrentProfile->CallerGroups = MessageBuffer[8];break;
1599 case 0x09: CurrentProfile->AutomaticAnswer = MessageBuffer[8];break;
1602 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1609 CurrentProfileError = GE_NONE;
1612 /* Incoming profile name */
1615 if (MessageBuffer[9] == 0x00) {
1616 CurrentProfile->DefaultName=MessageBuffer[8];
1618 CurrentProfile->DefaultName=-1;
1620 /* Here name is in Unicode */
1621 if (GetModelFeature (FN_PROFILES)==F_PROF33) {
1622 DecodeUnicode (CurrentProfile->Name, MessageBuffer+10, MessageBuffer[9]/2);
1625 sprintf(CurrentProfile->Name, MessageBuffer + 10, MessageBuffer[9]);
1626 CurrentProfile->Name[MessageBuffer[9]] = '\0';
1630 CurrentProfileError = GE_NONE;
1636 /* Needs SIM card with PIN in phone */
1637 GSM_Error N6110_GetProfile(GSM_Profile *Profile)
1641 unsigned char name_req[] = { N6110_FRAME_HEADER, 0x1a, 0x00};
1642 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x13, 0x01, 0x00, 0x00};
1646 CurrentProfile = Profile;
1648 /* When after sending all frames feature==253, it means, that it is not
1650 CurrentProfile->KeypadTone=253;
1651 CurrentProfile->Lights=253;
1652 CurrentProfile->CallAlert=253;
1653 CurrentProfile->Ringtone=253;
1654 CurrentProfile->Volume=253;
1655 CurrentProfile->MessageTone=253;
1656 CurrentProfile->WarningTone=253;
1657 CurrentProfile->Vibration=253;
1658 CurrentProfile->CallerGroups=253;
1659 CurrentProfile->ScreenSaver=253;
1660 CurrentProfile->AutomaticAnswer=253;
1662 name_req[4] = Profile->Number;
1664 error=NULL_SendMessageSequence
1665 (20, &CurrentProfileError, 5, 0x05, name_req);
1666 if (error!=GE_NONE) return error;
1668 for (i = 0x00; i <= 0x09; i++) {
1670 feat_req[5] = Profile->Number;
1674 error=NULL_SendMessageSequence
1675 (20, &CurrentProfileError, 7, 0x05, feat_req);
1676 if (error!=GE_NONE) return error;
1679 if (Profile->DefaultName > -1)
1681 switch(GetModelFeature (FN_PROFILES)) {
1683 switch (Profile->DefaultName) {
1684 case 0x00: sprintf(Profile->Name, "General");break;
1685 case 0x01: sprintf(Profile->Name, "Silent");break;
1686 case 0x02: sprintf(Profile->Name, "Descreet");break;
1687 case 0x03: sprintf(Profile->Name, "Loud");break;
1688 case 0x04: sprintf(Profile->Name, "My style");break;
1689 case 0x05: Profile->Name[0]=0;break;
1690 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1694 switch (Profile->DefaultName) {
1695 case 0x00: sprintf(Profile->Name, "Personal");break;
1696 case 0x01: sprintf(Profile->Name, "Car");break;
1697 case 0x02: sprintf(Profile->Name, "Headset");break;
1698 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1702 switch (Profile->DefaultName) {
1703 case 0x00: sprintf(Profile->Name, "General");break;
1704 case 0x01: sprintf(Profile->Name, "Silent");break;
1705 case 0x02: sprintf(Profile->Name, "Meeting");break;
1706 case 0x03: sprintf(Profile->Name, "Outdoor");break;
1707 case 0x04: sprintf(Profile->Name, "Pager");break;
1708 case 0x05: sprintf(Profile->Name, "Car");break;
1709 case 0x06: sprintf(Profile->Name, "Headset");break;
1710 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1720 void N6110_ReplySetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1722 switch (MessageBuffer[3]) {
1724 /* Profile feature change result */
1727 fprintf(stdout, _("Message: Profile feature change result.\n"));
1729 CurrentProfileError = GE_NONE;
1732 /* Profile name set result */
1735 fprintf(stdout, _("Message: Profile name change result.\n"));
1737 CurrentProfileError = GE_NONE;
1743 GSM_Error N6110_SetProfileFeature(u8 profile, u8 feature, u8 value)
1745 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x10, 0x01,
1748 feat_req[5]=profile;
1749 feat_req[6]=feature;
1752 return NULL_SendMessageSequence
1753 (20, &CurrentProfileError, 8, 0x05, feat_req);
1756 GSM_Error N6110_SetProfile(GSM_Profile *Profile)
1760 unsigned char name_req[40] = { N6110_FRAME_HEADER, 0x1c, 0x01, 0x03,
1765 name_req[7] = Profile->Number;
1766 name_req[8] = strlen(Profile->Name);
1767 name_req[6] = name_req[8] + 2;
1769 for (i = 0; i < name_req[8]; i++)
1770 name_req[9 + i] = Profile->Name[i];
1772 error=NULL_SendMessageSequence
1773 (20, &CurrentProfileError, name_req[8] + 9, 0x05, name_req);
1774 if (error!=GE_NONE) return error;
1776 for (i = 0x00; i <= 0x09; i++) {
1779 case 0x00: value = Profile->KeypadTone; break;
1780 case 0x01: value = Profile->Lights; break;
1781 case 0x02: value = Profile->CallAlert; break;
1782 case 0x03: value = Profile->Ringtone; break;
1783 case 0x04: value = Profile->Volume; break;
1784 case 0x05: value = Profile->MessageTone; break;
1785 case 0x06: value = Profile->Vibration; break;
1786 case 0x07: value = Profile->WarningTone; break;
1787 case 0x08: value = Profile->CallerGroups; break;
1788 case 0x09: value = Profile->AutomaticAnswer; break;
1789 default : value = 0; break;
1792 error=N6110_SetProfileFeature(Profile->Number,i,value);
1793 if (error!=GE_NONE) return error;
1799 bool N6110_SendRLPFrame(RLP_F96Frame *frame, bool out_dtx)
1801 u8 req[60] = { 0x00, 0xd9 };
1803 /* Discontinuos transmission (DTX). See section 5.6 of GSM 04.22 version
1809 memcpy(req+2, (u8 *) frame, 32);
1811 return (Protocol->SendFrame(32, 0xf0, req));
1814 void N6110_ReplyGetCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1822 switch (MessageBuffer[4]) {
1826 CurrentCalendarNote->Type=MessageBuffer[8];
1828 DecodeDateTime(MessageBuffer+9, &CurrentCalendarNote->Time);
1830 DecodeDateTime(MessageBuffer+16, &CurrentCalendarNote->Alarm);
1832 CurrentCalendarNote->Text[0]=0;
1834 if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
1836 if (CurrentCalendarNote->Type == GCN_REMINDER) i=1; //first char is subset
1837 switch (MessageBuffer[24]) {
1840 fprintf(stdout,_("Subset 3 in reminder note !\n"));
1842 while (i!=MessageBuffer[23]) {
1844 if (i!=MessageBuffer[23]-1) {
1845 if (MessageBuffer[24+i]>=0xc2) {
1846 DecodeWithUTF8Alphabet(MessageBuffer[24+i], MessageBuffer[24+i+1], &mychar1);
1847 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1848 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=mychar1;
1854 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1855 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=MessageBuffer[24+i];
1862 fprintf(stdout,_("Subset 2 in reminder note !\n"));
1864 while (i!=MessageBuffer[23]) {
1865 wc = MessageBuffer[24+i] | (0x00 << 8);
1866 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1867 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=
1868 DecodeWithUnicodeAlphabet(wc);
1874 fprintf(stdout,_("Subset 1 in reminder note !\n"));
1876 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1877 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1881 fprintf(stdout,_("Unknown subset in reminder note !\n"));
1883 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1884 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1888 memcpy(CurrentCalendarNote->Text,MessageBuffer+24,MessageBuffer[23]);
1889 CurrentCalendarNote->Text[MessageBuffer[23]]=0;
1892 if (CurrentCalendarNote->Type == GCN_CALL) {
1893 memcpy(CurrentCalendarNote->Phone,MessageBuffer+24+MessageBuffer[23]+1,MessageBuffer[24+MessageBuffer[23]]);
1894 CurrentCalendarNote->Phone[MessageBuffer[24+MessageBuffer[23]]]=0;
1897 CurrentCalendarNote->Recurrance=0;
1899 CurrentCalendarNote->AlarmType=0;
1902 fprintf(stdout, _("Message: Calendar note received.\n"));
1904 fprintf(stdout, _(" Date: %d-%02d-%02d\n"), CurrentCalendarNote->Time.Year,
1905 CurrentCalendarNote->Time.Month,
1906 CurrentCalendarNote->Time.Day);
1908 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentCalendarNote->Time.Hour,
1909 CurrentCalendarNote->Time.Minute,
1910 CurrentCalendarNote->Time.Second);
1912 /* Some messages do not have alarm set up */
1913 if (CurrentCalendarNote->Alarm.Year != 0) {
1914 fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"), CurrentCalendarNote->Alarm.Year,
1915 CurrentCalendarNote->Alarm.Month,
1916 CurrentCalendarNote->Alarm.Day);
1918 fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"), CurrentCalendarNote->Alarm.Hour,
1919 CurrentCalendarNote->Alarm.Minute,
1920 CurrentCalendarNote->Alarm.Second);
1923 fprintf(stdout, _(" Type: %d\n"), CurrentCalendarNote->Type);
1924 fprintf(stdout, _(" Text: %s\n"), CurrentCalendarNote->Text);
1926 if (CurrentCalendarNote->Type == GCN_CALL)
1927 fprintf(stdout, _(" Phone: %s\n"), CurrentCalendarNote->Phone);
1930 CurrentCalendarNoteError=GE_NONE;
1936 fprintf(stdout, _("Message: Calendar note not available\n"));
1939 CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;
1945 fprintf(stdout, _("Message: Calendar note error\n"));
1948 CurrentCalendarNoteError=GE_INTERNALERROR;
1954 GSM_Error N6110_GetCalendarNote(GSM_CalendarNote *CalendarNote)
1957 unsigned char req[] = { N6110_FRAME_HEADER,
1962 req[4]=CalendarNote->Location;
1964 CurrentCalendarNote = CalendarNote;
1966 error=NULL_SendMessageSequence
1967 (20, &CurrentCalendarNoteError, 5, 0x13, req);
1969 CurrentCalendarNote = NULL;
1974 void N6110_ReplyWriteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1977 switch(MessageBuffer[4]) {
1978 /* This message is also sent when the user enters the new entry on keypad */
1980 fprintf(stdout, _("Message: Calendar note write succesfull!\n"));break;
1982 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
1984 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
1986 fprintf(stdout, _("Unknown message of type 0x13 and subtype 0x65\n"));break;
1990 switch(MessageBuffer[4]) {
1991 case 0x01: CurrentCalendarNoteError=GE_NONE; break;
1992 case 0x73: CurrentCalendarNoteError=GE_INTERNALERROR; break;
1993 case 0x7d: CurrentCalendarNoteError=GE_INTERNALERROR; break;
1994 default : AppendLogText("Unknown msg\n",false); break;
1998 GSM_Error N6110_WriteCalendarNote(GSM_CalendarNote *CalendarNote)
2001 unsigned char req[200] = { N6110_FRAME_HEADER,
2003 0x00, /* Length of the rest of the frame. */
2004 0x00, /* The type of calendar note */
2005 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2012 unsigned char meeting;
2013 unsigned char birthday;
2014 unsigned char reminder;
2015 } calendar_model_length;
2017 /* Length of entries */
2018 calendar_model_length calendar_lengths[] =
2020 /*model,CallTo,Meeting,Birthday,Reminder*/
2021 {"NHM-5",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2022 {"NHM-6",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2023 {"NSE-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 [HKEY_LOCAL_MACHINE\Software\Nokia\Data Suite\3.0\Calendar]
2024 {"NSM-1",0x1e,0x18,0x18,0x24}, //from NCDS3
2025 {"NSK-3",0x1e,0x14,0x14,0x1e}, //from NCDS3
2026 {"NSB-3",0x20,0x14,0x14,0x1e}, //from NCDS3
2027 {"", 0, 0, 0, 0 } //end of table
2038 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
2041 req[7]=CalendarNote->Type;
2043 EncodeDateTime(req+8, &CalendarNote->Time);
2044 req[14] = CalendarNote->Time.Timezone;
2046 if (CalendarNote->Alarm.Year) {
2047 EncodeDateTime(req+15, &CalendarNote->Alarm);
2048 req[21] = CalendarNote->Alarm.Timezone;
2051 req[22]=strlen(CalendarNote->Text);
2055 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2056 req[22]++; // one additional char
2057 req[current++]=0x01; //we use now subset 1
2060 for (i=0; i<strlen(CalendarNote->Text); i++) {
2062 mychar=CalendarNote->Text[i];
2063 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2064 if (EncodeWithUTF8Alphabet(mychar,&mychar1,&mychar2)) {
2065 req[current++]=mychar1;
2066 req[current++]=mychar2;
2067 req[23]=0x03; //use subset 3
2068 req[22]++; // one additional char
2073 /* Enables/disables blinking */
2074 if (mychar=='~') req[current++]=0x01;
2075 else req[current++]=mychar;
2079 req[current++]=strlen(CalendarNote->Phone);
2081 for (i=0; i<strlen(CalendarNote->Phone); i++)
2082 req[current++]=CalendarNote->Phone[i];
2084 while (N6110_GetModel(model) != GE_NONE)
2087 /* Checking maximal length */
2089 while (strcmp(calendar_lengths[i].model,"")) {
2090 if (!strcmp(calendar_lengths[i].model,model)) {
2091 switch (CalendarNote->Type) {
2092 case GCN_REMINDER:if (req[22]>calendar_lengths[i].reminder) return GE_TOOLONG;break;
2093 case GCN_MEETING :if (req[22]>calendar_lengths[i].meeting) return GE_TOOLONG;break;
2094 case GCN_BIRTHDAY:if (req[22]>calendar_lengths[i].birthday) return GE_TOOLONG;break;
2095 case GCN_CALL :if (strlen(CalendarNote->Phone)>calendar_lengths[i].call) return GE_TOOLONG;break;
2102 CurrentCalendarNote = CalendarNote;
2104 error=NULL_SendMessageSequence
2105 (20, &CurrentCalendarNoteError, current, 0x13, req);
2107 CurrentCalendarNote = NULL;
2112 void N6110_ReplyDeleteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2115 switch (MessageBuffer[4]) {
2116 /* This message is also sent when the user deletes an old entry on
2117 keypad or moves an old entry somewhere (there is also `write'
2119 case 0x01:fprintf(stdout, _("Message: Calendar note deleted\n"));break;
2120 case 0x93:fprintf(stdout, _("Message: Calendar note can't be deleted\n"));break;
2121 default :fprintf(stdout, _("Message: Calendar note deleting error\n"));break;
2125 switch (MessageBuffer[4]) {
2126 case 0x01:CurrentCalendarNoteError=GE_NONE;break;
2127 case 0x93:CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;break;
2128 default :CurrentCalendarNoteError=GE_INTERNALERROR;break;
2132 GSM_Error N6110_DeleteCalendarNote(GSM_CalendarNote *CalendarNote)
2135 unsigned char req[] = { N6110_FRAME_HEADER,
2139 req[4]=CalendarNote->Location;
2141 return NULL_SendMessageSequence (20, &CurrentCalendarNoteError, 5, 0x13, req);
2144 void N6110_ReplyRFBatteryLevel(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2147 fprintf(stdout, _("Message: Phone status received:\n"));
2148 fprintf(stdout, _(" Mode: "));
2150 switch (MessageBuffer[4]) {
2154 fprintf(stdout, _("registered within the network\n"));
2157 /* I was really amazing why is there a hole in the type of 0x02, now I
2159 case 0x02: fprintf(stdout, _("call in progress\n")); break; /* ringing or already answered call */
2160 case 0x03: fprintf(stdout, _("waiting for security code\n")); break;
2161 case 0x04: fprintf(stdout, _("powered off\n")); break;
2162 default : fprintf(stdout, _("unknown\n"));
2166 fprintf(stdout, _(" Power source: "));
2168 switch (MessageBuffer[7]) {
2170 case 0x01: fprintf(stdout, _("AC/DC\n")); break;
2171 case 0x02: fprintf(stdout, _("battery\n")); break;
2172 default : fprintf(stdout, _("unknown\n"));
2176 fprintf(stdout, _(" Battery Level: %d\n"), MessageBuffer[8]);
2177 fprintf(stdout, _(" Signal strength: %d\n"), MessageBuffer[5]);
2180 CurrentRFLevel=MessageBuffer[5];
2181 CurrentBatteryLevel=MessageBuffer[8];
2182 CurrentPowerSource=MessageBuffer[7];
2186 GSM_Error N6110_GetRFLevel(GSM_RFUnits *units, float *level)
2189 /* FIXME - these values are from 3810 code, may be incorrect. Map from
2190 values returned in status packet to the the values returned by the AT+CSQ
2192 float csq_map[5] = {0, 8, 16, 24, 31};
2197 char screen[NM_MAX_SCREEN_WIDTH];
2201 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2203 if (N6110_NetMonitor(1, screen)!=GE_NONE)
2204 return GE_INTERNALERROR;
2208 if (screen[4]!='-') {
2209 if (screen[5]=='9' && screen[6]>'4') rf_level=1;
2210 if (screen[5]=='9' && screen[6]<'5') rf_level=2;
2211 if (screen[5]=='8' && screen[6]>'4') rf_level=3;
2214 /* Arbitrary units. */
2215 if (*units == GRF_Arbitrary) {
2221 N6110_SendStatusRequest();
2223 /* Wait for timeout or other error. */
2224 while (timeout != 0 && CurrentRFLevel == -1 ) {
2227 return (GE_TIMEOUT);
2232 /* Make copy in case it changes. */
2233 rf_level = CurrentRFLevel;
2238 /* Now convert between the different units we support. */
2240 /* Arbitrary units. */
2241 if (*units == GRF_Arbitrary) {
2247 if (*units == GRF_CSQ) {
2250 *level = csq_map[rf_level];
2252 *level = 99; /* Unknown/undefined */
2258 /* Unit type is one we don't handle so return error */
2259 return (GE_INTERNALERROR);
2263 GSM_Error N6110_GetBatteryLevel(GSM_BatteryUnits *units, float *level)
2268 char screen[NM_MAX_SCREEN_WIDTH];
2270 CurrentBatteryLevel=-1;
2272 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2274 if (N6110_NetMonitor(23, screen)!=GE_NONE)
2279 if (screen[29]=='7') batt_level=3;
2280 if (screen[29]=='5') batt_level=2;
2281 if (screen[29]=='2') batt_level=1;
2283 /* Only units we handle at present are GBU_Arbitrary */
2284 if (*units == GBU_Arbitrary) {
2285 *level = batt_level;
2289 return (GE_INTERNALERROR);
2292 N6110_SendStatusRequest();
2294 /* Wait for timeout or other error. */
2295 while (timeout != 0 && CurrentBatteryLevel == -1 ) {
2298 return (GE_TIMEOUT);
2303 /* Take copy in case it changes. */
2304 batt_level = CurrentBatteryLevel;
2306 if (batt_level != -1) {
2308 /* Only units we handle at present are GBU_Arbitrary */
2309 if (*units == GBU_Arbitrary) {
2310 *level = batt_level;
2314 return (GE_INTERNALERROR);
2321 GSM_Error N6110_GetPowerSource(GSM_PowerSource *source)
2326 char screen[NM_MAX_SCREEN_WIDTH];
2328 CurrentPowerSource=-1;
2330 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2332 if (N6110_NetMonitor(20, screen)!=GE_NONE)
2335 CurrentPowerSource=GPS_ACDC;
2337 if (screen[6]=='x') CurrentPowerSource=GPS_BATTERY;
2339 *source=CurrentPowerSource;
2343 N6110_SendStatusRequest();
2345 /* Wait for timeout or other error. */
2346 while (timeout != 0 && CurrentPowerSource == -1 ) {
2349 return (GE_TIMEOUT);
2354 if (CurrentPowerSource != -1) {
2355 *source=CurrentPowerSource;
2363 void N6110_ReplyGetDisplayStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2367 for (i=0; i<MessageBuffer[4];i++)
2368 if (MessageBuffer[2*i+6]==2)
2369 CurrentDisplayStatus|=1<<(MessageBuffer[2*i+5]-1);
2371 CurrentDisplayStatus&= (0xff - (1<<(MessageBuffer[2*i+5]-1)));
2374 fprintf(stdout, _("Call in progress: %s\n"), CurrentDisplayStatus & (1<<DS_Call_In_Progress)?"on":"off");
2375 fprintf(stdout, _("Unknown: %s\n"), CurrentDisplayStatus & (1<<DS_Unknown)?"on":"off");
2376 fprintf(stdout, _("Unread SMS: %s\n"), CurrentDisplayStatus & (1<<DS_Unread_SMS)?"on":"off");
2377 fprintf(stdout, _("Voice call: %s\n"), CurrentDisplayStatus & (1<<DS_Voice_Call)?"on":"off");
2378 fprintf(stdout, _("Fax call active: %s\n"), CurrentDisplayStatus & (1<<DS_Fax_Call)?"on":"off");
2379 fprintf(stdout, _("Data call active: %s\n"), CurrentDisplayStatus & (1<<DS_Data_Call)?"on":"off");
2380 fprintf(stdout, _("Keyboard lock: %s\n"), CurrentDisplayStatus & (1<<DS_Keyboard_Lock)?"on":"off");
2381 fprintf(stdout, _("SMS storage full: %s\n"), CurrentDisplayStatus & (1<<DS_SMS_Storage_Full)?"on":"off");
2384 CurrentDisplayStatusError=GE_NONE;
2387 GSM_Error N6110_GetDisplayStatus(int *Status) {
2389 unsigned char req[4]={ N6110_FRAME_HEADER, 0x51 };
2393 error=NULL_SendMessageSequence
2394 (10, &CurrentDisplayStatusError, 4, 0x0d, req);
2395 if (error!=GE_NONE) return error;
2397 *Status=CurrentDisplayStatus;
2402 GSM_Error N6110_DialVoice(char *Number) {
2403 /* This commented sequence doesn't work on N3210/3310/6210/7110 */
2404 // unsigned char req[64]={N6110_FRAME_HEADER, 0x01};
2405 // unsigned char req_end[]={0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};
2407 // req[4]=strlen(Number);
2408 // for(i=0; i < strlen(Number) ; i++)
2409 // req[5+i]=Number[i];
2410 // memcpy(req+5+strlen(Number), req_end, 10);
2411 // return NULL_SendMessageSequence
2412 // (20, &CurrentDialVoiceError, 13+strlen(Number), 0x01, req);
2414 unsigned char req[64]={0x00,0x01,0x7c,
2415 0x01}; //call command
2421 error=N6110_EnableExtendedCommands(0x01);
2422 if (error!=GE_NONE) return error;
2424 for(i=0; i < strlen(Number) ; i++) req[4+i]=Number[i];
2428 return NULL_SendMessageSequence
2429 (20, &CurrentDialVoiceError, 4+strlen(Number)+1, 0x40, req);
2432 /* Dial a data call - type specifies request to use:
2433 type 0 should normally be used
2434 type 1 should be used when calling a digital line - corresponds to ats35=0
2435 Maybe one day we'll know what they mean!
2437 GSM_Error N6110_DialData(char *Number, char type, void (* callpassup)(char c))
2439 unsigned char req[100] = { N6110_FRAME_HEADER, 0x01 };
2440 unsigned char *req_end;
2441 unsigned char req_end0[] = { 0x01, /* make a data call = type 0x01 */
2442 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2443 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00 };
2444 unsigned char req_end1[] = { 0x01,
2445 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2446 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2447 0x88,0x90,0x21,0x48,0x40,0xbb };
2448 unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2449 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2450 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
2451 unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2452 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2453 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
2454 unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
2455 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2456 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
2457 0x20,0x15,0x63,0x80 };
2462 CurrentCallPassup=callpassup;
2467 size = sizeof(req_end0);
2470 Protocol->SendMessage(sizeof(req3), 0x01, req3);
2471 Protocol->SendMessage(sizeof(req4), 0x01, req4);
2473 size = sizeof(req_end1);
2475 case -1: /* Just used to set the call passup */
2480 size = sizeof(req_end0);
2484 req[4] = strlen(Number);
2486 for(i = 0; i < strlen(Number) ; i++)
2487 req[5+i] = Number[i];
2489 memcpy(req + 5 + strlen(Number), req_end, size);
2491 Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);
2492 if (type != 1) Protocol->SendMessage(26, 0x01, req2);
2497 GSM_Error N6110_GetIncomingCallNr(char *Number)
2500 if (*CurrentIncomingCall != ' ') {
2501 strcpy(Number, CurrentIncomingCall);
2508 GSM_Error N6110_CancelCall(void)
2510 // This frame & method works only on 61xx/51xx
2511 // unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
2512 // req[4]=CurrentCallSequenceNumber;
2513 // Protocol->SendMessage(6, 0x01, req);
2518 unsigned char req[]={0x00,0x01,0x7c,0x03};
2521 error=N6110_EnableExtendedCommands(0x01);
2522 if (error!=GE_NONE) return error;
2524 return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
2527 void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2529 switch(MessageBuffer[3]) {
2533 fprintf(stdout, _("Message: Security code accepted.\n"));
2535 CurrentSecurityCodeError = GE_NONE;
2540 fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
2542 CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
2546 GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
2549 unsigned char req[15] = { N6110_FRAME_HEADER,
2550 0x0a, /* Enter code request. */
2551 0x00 /* Type of the entered code. */
2555 req[4]=SecurityCode.Type;
2557 for (i=0; i<strlen(SecurityCode.Code);i++)
2558 req[5+i]=SecurityCode.Code[i];
2560 req[5+strlen(SecurityCode.Code)]=0x00;
2561 req[6+strlen(SecurityCode.Code)]=0x00;
2563 return NULL_SendMessageSequence
2564 (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
2567 void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2569 *CurrentSecurityCodeStatus = MessageBuffer[4];
2572 fprintf(stdout, _("Message: Security Code status received: "));
2574 switch(*CurrentSecurityCodeStatus) {
2576 case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;
2577 case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;
2578 case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;
2579 case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;
2580 case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;
2581 case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;
2582 default : fprintf(stdout, _("Unknown!\n"));
2587 CurrentSecurityCodeError = GE_NONE;
2590 GSM_Error N6110_GetSecurityCodeStatus(int *Status)
2593 unsigned char req[4] = { N6110_FRAME_HEADER,
2597 CurrentSecurityCodeStatus=Status;
2599 return NULL_SendMessageSequence
2600 (20, &CurrentSecurityCodeError, 4, 0x08, req);
2603 void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2608 fprintf(stdout, _("Message: Security code received: "));
2609 switch (MessageBuffer[3]) {
2610 case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;
2611 case GSCT_Pin: fprintf(stdout, _("PIN"));break;
2612 case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;
2613 case GSCT_Puk: fprintf(stdout, _("PUK"));break;
2614 case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;
2615 default: fprintf(stdout, _("unknown !"));break;
2617 if (MessageBuffer[4]==1) {
2618 fprintf(stdout, _(" allowed, value \""));
2619 if (MessageBuffer[3]==GSCT_SecurityCode) {
2620 for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2622 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2623 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2624 for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2626 fprintf(stdout, _("\""));
2628 fprintf(stdout, _(" not allowed"));
2630 fprintf(stdout, _("\n"));
2633 if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
2634 && MessageBuffer[4]==1) { /* It's allowed */
2635 if (MessageBuffer[3]==GSCT_SecurityCode) {
2636 for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2637 CurrentSecurityCode->Code[5]=0;
2639 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2640 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2641 for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2642 CurrentSecurityCode->Code[4]=0;
2644 CurrentSecurityCodeError=GE_NONE;
2646 CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
2649 GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
2652 unsigned char req[4] = { 0x00,
2653 0x01,0x6e, /* Get code request. */
2654 0x00 }; /* Type of the requested code. */
2658 error=N6110_EnableExtendedCommands(0x01);
2659 if (error!=GE_NONE) return error;
2661 req[3]=SecurityCode->Type;
2663 CurrentSecurityCode=SecurityCode;
2665 return NULL_SendMessageSequence
2666 (20, &CurrentSecurityCodeError, 4, 0x40, req);
2669 void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2672 fprintf(stdout, _("Message: answer for PlayTone frame\n"));
2675 CurrentPlayToneError=GE_NONE;
2678 GSM_Error N6110_PlayTone(int Herz, u8 Volume)
2680 unsigned char req[6] = { 0x00,0x01,0x8f,
2683 0x00 }; /* HerzHi */
2687 /* PlayTone wasn't used earlier */
2688 if (CurrentPlayToneError==GE_UNKNOWN) {
2689 if (CurrentConnectionType!=GCT_MBUS)
2690 CurrentDisableKeepAlive=true;
2692 error=N6110_EnableExtendedCommands(0x01);
2693 if (error!=GE_NONE) return error;
2696 /* For Herz==255*255 we have silent */
2697 if (Herz!=255*255) {
2710 /* For Herz==255*255 we have silent and additionaly
2711 we wait for phone answer - it's important for MBUS */
2712 if (Herz==255*255) {
2713 error=NULL_SendMessageSequence
2714 (20, &CurrentPlayToneError, 6, 0x40, req);
2716 CurrentPlayToneError=GE_UNKNOWN;
2717 CurrentDisableKeepAlive=false;
2719 if (error!=GE_NONE) return error;
2721 Protocol->SendMessage(6,0x40,req);
2724 error=NULL_SendMessageSequence
2725 (20, &CurrentPlayToneError, 6, 0x40, req);
2727 /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
2728 if (Herz==255*255) {
2729 CurrentPlayToneError=GE_UNKNOWN;
2730 CurrentDisableKeepAlive=false;
2733 if (error!=GE_NONE) return error;
2740 void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2742 if (MessageBuffer[4]==0x01) {
2743 DecodeDateTime(MessageBuffer+8, CurrentDateTime);
2746 fprintf(stdout, _("Message: Date and time\n"));
2747 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
2748 fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
2751 CurrentDateTime->IsSet=true;
2755 fprintf(stdout, _("Message: Date and time not set in phone\n"));
2758 CurrentDateTime->IsSet=false;
2761 CurrentDateTimeError=GE_NONE;
2764 GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
2766 return N6110_PrivGetDateTime(date_time,0x11);
2769 GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
2771 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
2773 CurrentDateTime=date_time;
2775 return NULL_SendMessageSequence
2776 (50, &CurrentDateTimeError, 4, msgtype, req);
2779 void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2782 fprintf(stdout, _("Message: Alarm\n"));
2783 fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
2784 fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
2787 CurrentAlarm->Hour=MessageBuffer[9];
2788 CurrentAlarm->Minute=MessageBuffer[10];
2789 CurrentAlarm->Second=0;
2791 CurrentAlarm->IsSet=(MessageBuffer[8]==2);
2793 CurrentAlarmError=GE_NONE;
2796 GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
2798 return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
2801 GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
2803 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
2805 CurrentAlarm=date_time;
2807 return NULL_SendMessageSequence
2808 (50, &CurrentAlarmError, 4, msgtype, req);
2811 void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2813 switch (MessageBuffer[3]) {
2817 CurrentMessageCenter->No=MessageBuffer[4];
2818 CurrentMessageCenter->Format=MessageBuffer[6];
2819 CurrentMessageCenter->Validity=MessageBuffer[8];
2820 sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
2822 sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
2824 sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
2827 fprintf(stdout, _("Message: SMS Center received:\n"));
2828 fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
2829 fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
2830 fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
2832 fprintf(stdout, _(" SMS Center message format is "));
2834 switch (CurrentMessageCenter->Format) {
2836 case GSMF_Text : fprintf(stdout, _("Text")); break;
2837 case GSMF_Paging: fprintf(stdout, _("Paging")); break;
2838 case GSMF_Fax : fprintf(stdout, _("Fax")); break;
2839 case GSMF_Email : fprintf(stdout, _("Email")); break;
2840 default : fprintf(stdout, _("Unknown"));
2843 fprintf(stdout, "\n");
2845 fprintf(stdout, _(" SMS Center message validity is "));
2847 switch (CurrentMessageCenter->Validity) {
2849 case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;
2850 case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;
2851 case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;
2852 case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;
2853 case GSMV_1_Week : fprintf(stdout, _("1 week")); break;
2854 case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;
2855 default : fprintf(stdout, _("Unknown"));
2858 fprintf(stdout, "\n");
2862 CurrentMessageCenterError=GE_NONE;
2868 /* Number of entries depends on SIM card */
2871 fprintf(stdout, _("Message: SMS Center error received:\n"));
2872 fprintf(stdout, _(" The request for SMS Center failed.\n"));
2875 /* FIXME: appropriate error. */
2876 CurrentMessageCenterError=GE_INTERNALERROR;
2883 /* This function sends to the mobile phone a request for the SMS Center */
2884 GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
2886 unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
2887 0x00 /* SMS Center Number. */
2890 req[5]=MessageCenter->No;
2892 CurrentMessageCenter=MessageCenter;
2894 return NULL_SendMessageSequence
2895 (50, &CurrentMessageCenterError, 6, 0x02, req);
2898 void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2901 fprintf(stdout, _("Message: SMS Center correctly set.\n"));
2903 CurrentMessageCenterError=GE_NONE;
2906 /* This function set the SMS Center profile on the phone. */
2907 GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
2909 unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
2910 0x00, /* SMS Center Number. */
2911 0x00, /* Unknown. */
2912 0x00, /* SMS Message Format. */
2913 0x00, /* Unknown. */
2914 0x00, /* Validity. */
2915 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
2916 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
2917 /* Message Center Name. */
2920 req[5]=MessageCenter->No;
2921 req[7]=MessageCenter->Format;
2922 req[9]=MessageCenter->Validity;
2924 req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
2926 req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
2928 sprintf(req+34, "%s", MessageCenter->Name);
2930 CurrentMessageCenter=MessageCenter;
2932 return NULL_SendMessageSequence
2933 (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
2936 void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2938 switch (MessageBuffer[3]) {
2943 fprintf(stdout, _("Message: SMS Status Received\n"));
2944 fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
2945 fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
2948 CurrentSMSStatus->UnRead = MessageBuffer[11];
2949 CurrentSMSStatus->Number = MessageBuffer[10];
2951 CurrentSMSStatusError = GE_NONE;
2957 fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
2960 CurrentSMSStatusError = GE_INTERNALERROR;
2966 GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
2968 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
2970 CurrentSMSStatus = Status;
2972 return NULL_SendMessageSequence
2973 (10, &CurrentSMSStatusError, 5, 0x14, req);
2976 GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
2980 strcpy(folders->Folder[0].Name,"Inbox");
2981 strcpy(folders->Folder[1].Name,"Outbox");
2986 GSM_Error N6110_GetIMEI(char *imei)
2988 if (strlen(Current_IMEI)>0) {
2989 strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
2993 return (GE_TRYAGAIN);
2996 GSM_Error N6110_GetRevision(char *revision)
2999 if (strlen(Current_Revision)>0) {
3000 strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
3004 return (GE_TRYAGAIN);
3007 GSM_Error N6110_GetModel(char *model)
3009 if (strlen(Current_Model)>0) {
3010 strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
3014 return (GE_TRYAGAIN);
3017 void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3019 switch (MessageBuffer[4]) {
3023 fprintf(stdout, _("Message: Date and time set correctly\n"));
3025 CurrentSetDateTimeError=GE_NONE;
3030 fprintf(stdout, _("Message: Date and time setting error\n"));
3032 CurrentSetDateTimeError=GE_INVALIDDATETIME;
3037 /* Needs SIM card with PIN in phone */
3038 GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
3040 return N6110_PrivSetDateTime(date_time,0x11);
3043 /* Needs SIM card with PIN in phone */
3044 GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
3047 unsigned char req[] = { N6110_FRAME_HEADER,
3048 0x60, /* set-time subtype */
3049 0x01, 0x01, 0x07, /* unknown */
3050 0x00, 0x00, /* Year (0x07cf = 1999) */
3051 0x00, 0x00, /* Month Day */
3052 0x00, 0x00, /* Hours Minutes */
3053 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3056 EncodeDateTime(req+7, date_time);
3058 return NULL_SendMessageSequence
3059 (20, &CurrentSetDateTimeError, 14, msgtype, req);
3062 void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3064 switch (MessageBuffer[4]) {
3068 fprintf(stdout, _("Message: Alarm set correctly\n"));
3070 CurrentSetAlarmError=GE_NONE;
3075 fprintf(stdout, _("Message: Alarm setting error\n"));
3077 CurrentSetAlarmError=GE_INVALIDDATETIME;
3082 /* FIXME: we should also allow to set the alarm off :-) */
3083 GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
3085 return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
3088 /* FIXME: we should also allow to set the alarm off :-) */
3089 GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
3092 unsigned char req[] = { N6110_FRAME_HEADER,
3093 0x6b, /* set-alarm subtype */
3094 0x01, 0x20, 0x03, /* unknown */
3095 0x02, /* should be alarm on/off, but it don't works */
3096 0x00, 0x00, /* Hours Minutes */
3097 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3100 req[8] = date_time->Hour;
3101 req[9] = date_time->Minute;
3103 return NULL_SendMessageSequence
3104 (50, &CurrentSetAlarmError, 11, msgtype, req);
3107 void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3109 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
3114 switch (MessageBuffer[3]) {
3118 CurrentPhonebookEntry->Empty = true;
3120 count=MessageBuffer[5];
3123 fprintf(stdout, _("Message: Phonebook entry received:\n"));
3124 fprintf(stdout, _(" Name: "));
3126 for (tmp=0; tmp <count; tmp++)
3128 if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
3129 if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
3130 fprintf(stdout, "%c", MessageBuffer[6+tmp]);
3133 fprintf(stdout, "\n");
3136 while (N6110_GetModel(model) != GE_NONE)
3139 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3140 DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
3141 CurrentPhonebookEntry->Name[count/2] = 0x00;
3143 memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);
3144 CurrentPhonebookEntry->Name[count] = 0x00;
3147 CurrentPhonebookEntry->Empty = false;
3149 for (tmp=0; tmp <count; tmp++)
3151 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3152 /* We check only 1'st, 3'rd, ... char */
3153 if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking
3154 if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents
3156 if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking
3157 if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents
3162 count=MessageBuffer[6+count];
3165 fprintf(stdout, _(" Number: "));
3167 for (tmp=0; tmp <count; tmp++)
3168 fprintf(stdout, "%c", MessageBuffer[i+tmp]);
3170 fprintf(stdout, "\n");
3173 memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);
3174 CurrentPhonebookEntry->Number[count] = 0x00;
3175 CurrentPhonebookEntry->Group = MessageBuffer[i+count];
3177 /* Phone doesn't have entended phonebook */
3178 CurrentPhonebookEntry->SubEntriesCount = 0;
3180 /* But for these memories data is saved and we can save it using 7110/6210 style */
3181 if (CurrentPhonebookEntry->MemoryType==GMT_DC ||
3182 CurrentPhonebookEntry->MemoryType==GMT_RC ||
3183 CurrentPhonebookEntry->MemoryType==GMT_MC) {
3184 CurrentPhonebookEntry->SubEntriesCount = 1;
3185 CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;
3186 CurrentPhonebookEntry->SubEntries[0].NumberType=0;
3187 CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;
3188 DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);
3191 fprintf(stdout, _(" Date: "));
3192 fprintf(stdout, "%02u.%02u.%04u\n",
3193 CurrentPhonebookEntry->SubEntries[0].data.Date.Day,
3194 CurrentPhonebookEntry->SubEntries[0].data.Date.Month,
3195 CurrentPhonebookEntry->SubEntries[0].data.Date.Year);
3196 fprintf(stdout, _(" Time: "));
3197 fprintf(stdout, "%02u:%02u:%02u\n",
3198 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,
3199 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,
3200 CurrentPhonebookEntry->SubEntries[0].data.Date.Second);
3203 /* These values are set, when date and time unavailable in phone.
3204 Values from 3310 - in other can be different */
3205 if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&
3206 CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&
3207 CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&
3208 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&
3209 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&
3210 CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)
3211 CurrentPhonebookEntry->SubEntriesCount = 0;
3214 /* Signal no error to calling code. */
3215 CurrentPhonebookError = GE_NONE;
3222 fprintf(stdout, _("Message: Phonebook read entry error received:\n"));
3225 switch (MessageBuffer[4]) {
3229 fprintf(stdout, _(" Invalid memory type!\n"));
3231 CurrentPhonebookError = GE_INVALIDMEMORYTYPE;
3236 fprintf(stdout, _(" Unknown error!\n"));
3238 CurrentPhonebookError = GE_INTERNALERROR;
3246 /* Routine to get specifed phone book location. Designed to be called by
3247 application. Will block until location is retrieved or a timeout/error
3249 GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)
3251 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
3253 CurrentPhonebookEntry = entry;
3255 req[4] = N6110_GetMemoryType(entry->MemoryType);
3256 req[5] = entry->Location;
3258 return NULL_SendMessageSequence
3259 (50, &CurrentPhonebookError, 7, 0x03, req);
3262 void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3264 switch (MessageBuffer[3]) {
3269 fprintf(stdout, _("Message: Phonebook written correctly.\n"));
3271 CurrentPhonebookError = GE_NONE;
3276 switch (MessageBuffer[4]) {
3277 /* FIXME: other errors? When I send the phonebook with index of 350 it
3278 still report error 0x7d :-( */
3281 fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));
3283 CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;
3288 fprintf(stdout, _(" Unknown error!\n"));
3290 CurrentPhonebookError = GE_INTERNALERROR;
3295 /* Routine to write phonebook location in phone. Designed to be called by
3296 application code. Will block until location is written or timeout
3298 GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)
3300 unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };
3303 req[4] = N6110_GetMemoryType(entry->MemoryType);
3304 req[5] = entry->Location;
3308 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {
3310 req[6] = strlen(entry->Name)*2;
3312 EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
3314 for (i=0; i<strlen(entry->Name); i++)
3316 /* here we encode "special" chars */
3317 if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
3318 if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
3321 current+=strlen(entry->Name)*2;
3324 req[6] = strlen(entry->Name);
3326 for (i=0; i<strlen(entry->Name); i++)
3328 req[current+i] = entry->Name[i];
3330 /* here we encode "special" chars */
3331 if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
3332 if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
3335 current+=strlen(entry->Name);
3338 req[current++]=strlen(entry->Number);
3340 for (i=0; i<strlen(entry->Number); i++)
3341 req[current+i] = entry->Number[i];
3343 current+=strlen(entry->Number);
3345 /* Jano: This allow to save 14 characters name into SIM memory, when
3346 No Group is selected. */
3347 if (entry->Group == 5)
3348 req[current++]=0xff;
3350 req[current++]=entry->Group;
3352 return NULL_SendMessageSequence
3353 (50, &CurrentPhonebookError, current, 0x03, req);
3356 void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3358 switch(MessageBuffer[3]) {
3362 fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
3364 CurrentNetmonitorError=GE_NONE;
3369 fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
3370 fprintf(stdout, "%s\n", MessageBuffer+4);
3373 strcpy(CurrentNetmonitor, MessageBuffer+4);
3375 CurrentNetmonitorError=GE_NONE;
3379 GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
3381 unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
3385 error=N6110_EnableExtendedCommands(0x01);
3386 if (error!=GE_NONE) return error;
3388 CurrentNetmonitor=Screen;
3392 return NULL_SendMessageSequence
3393 (20, &CurrentNetmonitorError, 4, 0x40, req);
3396 /* Doesn't work in N3210. */
3397 /* In other allow to access phone menu without SIM card (just send any sequence) */
3398 GSM_Error N6110_SendDTMF(char *String)
3400 unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
3401 0x00 /* Length of DTMF string. */
3404 u8 length=strlen(String);
3406 if (length>59) length=59;
3410 memcpy(req+5,String,length);
3412 return NULL_SendMessageSequence
3413 (20, &CurrentSendDTMFError, 5+length, 0x01, req);
3416 void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3418 switch (MessageBuffer[3]) {
3422 switch (MessageBuffer[4]) {
3423 case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
3424 default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
3427 CurrentSpeedDialEntry->Location = MessageBuffer[5];
3430 fprintf(stdout, _("Message: Speed dial entry received:\n"));
3431 fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
3432 fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
3433 fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
3436 CurrentSpeedDialError=GE_NONE;
3442 fprintf(stdout, _("Message: Speed dial entry error\n"));
3444 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3450 GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
3453 unsigned char req[] = { N6110_FRAME_HEADER,
3455 0x00 /* The number of speed dial. */
3458 CurrentSpeedDialEntry = entry;
3460 req[4] = entry->Number;
3462 return NULL_SendMessageSequence
3463 (20, &CurrentSpeedDialError, 5, 0x03, req);
3466 void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3468 switch (MessageBuffer[3]) {
3473 fprintf(stdout, _("Message: Speed dial entry set.\n"));
3475 CurrentSpeedDialError=GE_NONE;
3481 fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
3483 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3489 GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
3492 unsigned char req[] = { N6110_FRAME_HEADER,
3495 0x00, /* Memory Type */
3499 req[4] = entry->Number;
3501 switch (entry->MemoryType) {
3502 case GMT_ME: req[5] = 0x02;
3503 default : req[5] = 0x03;
3506 req[6] = entry->Location;
3508 return NULL_SendMessageSequence
3509 (20, &CurrentSpeedDialError, 7, 0x03, req);
3512 /* This function finds parts of SMS in frame used in new Nokia phones
3513 in internal protocols (they're coded according to GSM 03.40), copies them
3514 to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
3515 GSM_ETSISMSMessage to GSM_SMSMessage structure */
3516 GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
3518 SMS_MessageType PDU=SMS_Deliver;
3519 GSM_ETSISMSMessage ETSI;
3522 ETSI.firstbyte=req[12];
3524 /* See GSM 03.40 section 9.2.3.1 */
3525 if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
3526 if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
3529 case SMS_Submit : offset=5;break;
3530 case SMS_Deliver : offset=4;break;
3531 case SMS_Status_Report: offset=3;break;
3535 for (i=0;i<req[0]+1;i++)
3536 ETSI.SMSCNumber[i]=req[i];
3538 for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
3539 ETSI.Number[i]=req[i+12+offset];
3543 ETSI.TPDCS=req[10+offset];
3544 ETSI.TPUDL=req[11+offset];
3545 ETSI.TPVP=0; //no support for now
3546 ETSI.TPPID=0; //no support for now
3547 for(i=31+offset;i<length;i++)
3548 ETSI.MessageText[i-31-offset]=req[i];
3551 ETSI.TPDCS=req[10+offset];
3552 ETSI.TPUDL=req[11+offset];
3553 ETSI.TPPID=0; //no support for now
3554 for(i=31+offset;i<length;i++)
3555 ETSI.MessageText[i-31-offset]=req[i];
3557 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3559 case SMS_Status_Report:
3561 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3562 ETSI.TPStatus=req[14];
3564 ETSI.SMSCDateTime[i]=req[i+34];
3570 GSM_DecodeETSISMS(SMS, &ETSI);
3577 void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3581 switch (MessageBuffer[3]) {
3585 switch (MessageBuffer[7]) {
3588 CurrentSMSMessage->Type = GST_SMS;
3589 CurrentSMSMessage->folder=GST_INBOX;
3594 CurrentSMSMessage->Type = GST_DR;
3595 CurrentSMSMessage->folder=GST_INBOX;
3600 CurrentSMSMessage->Type = GST_SMS;
3601 CurrentSMSMessage->folder=GST_OUTBOX;
3606 CurrentSMSMessage->Type = GST_UN;
3612 /* Field Short Message Status - MessageBuffer[4] seems not to be
3613 compliant with GSM 07.05 spec.
3614 Meaning Nokia protocol GMS spec
3615 ----------------------------------------------------
3616 MO Sent 0x05 0x07 or 0x01
3617 MO Not sent 0x07 0x06 or 0x00
3618 MT Read 0x01 0x05 or 0x01
3619 MT Not read 0x03 0x04 or 0x00
3620 ----------------------------------------------------
3621 See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
3625 if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
3626 else CurrentSMSMessage->Status = GSS_SENTREAD;
3629 fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
3631 if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
3632 fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
3634 fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
3637 if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
3638 if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
3640 if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
3641 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
3642 else fprintf(stdout, _(" Not sent\n"));
3644 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
3645 else fprintf(stdout, _(" Not read\n"));
3649 CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
3651 CurrentSMSMessage->MemoryType = MessageBuffer[5];
3652 CurrentSMSMessage->MessageNumber = MessageBuffer[6];
3654 /* Signal no error to calling code. */
3655 CurrentSMSMessageError = GE_NONE;
3658 fprintf(stdout, "\n");
3665 /* We have requested invalid or empty location. */
3668 fprintf(stdout, _("Message: SMS reading failed\n"));
3670 switch (MessageBuffer[4]) {
3672 fprintf(stdout, _(" Invalid location!\n"));break;
3674 fprintf(stdout, _(" Empty SMS location.\n"));break;
3676 fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
3678 fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
3682 switch (MessageBuffer[4]) {
3683 case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3684 case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
3685 case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
3686 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3694 GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
3697 unsigned char req[] = { N6110_FRAME_HEADER,
3700 0x00, /* Location */
3705 /* State machine code writes data to these variables when it comes in. */
3707 CurrentSMSMessage = message;
3708 CurrentSMSMessageError = GE_BUSY;
3710 req[5] = message->Location;
3713 Protocol->SendMessage(8, 0x02, req);
3715 /* Wait for timeout or other error. */
3716 while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
3719 return (GE_TIMEOUT);
3724 return (CurrentSMSMessageError);
3727 void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3730 fprintf(stdout, _("Message: SMS deleted successfully.\n"));
3733 CurrentSMSMessageError = GE_NONE;
3736 GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
3738 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
3740 req[5] = message->Location;
3742 return NULL_SendMessageSequence
3743 (50, &CurrentSMSMessageError, 6, 0x14, req);
3746 /* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
3747 GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
3749 GSM_ETSISMSMessage ETSI;
3752 GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
3755 for (i=0;i<36;i++) req[i]=0;
3757 req[12]=ETSI.firstbyte;
3759 for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
3760 req[i]=ETSI.SMSCNumber[i];
3765 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3766 req[i+12+offset]=ETSI.Number[i];
3767 req[10+offset]=ETSI.TPDCS;
3768 req[11+offset]=ETSI.TPUDL;
3769 req[24+offset]=ETSI.TPVP;
3771 // fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
3772 // fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
3773 // fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
3775 // req[]=ETSI.TPPID;
3776 for(i=0;i<*length;i++)
3777 req[i+31+offset]=ETSI.MessageText[i];
3782 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3783 req[i+12+offset]=ETSI.Number[i];
3784 req[10+offset]=ETSI.TPDCS;
3785 req[11+offset]=ETSI.TPUDL;
3786 // req[]=ETSI.TPPID;
3787 for(i=0;i<*length;i++)
3788 req[i+31+offset]=ETSI.MessageText[i];
3790 req[24+offset+i]=ETSI.DeliveryDateTime[i];
3796 *length=*length+offset;
3801 void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3803 switch (MessageBuffer[3]) {
3805 /* SMS message correctly sent to the network */
3808 fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
3810 CurrentSMSMessageError = GE_SMSSENDOK;
3813 /* SMS message send to the network failed */
3817 fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
3819 switch (MessageBuffer[6]) {
3820 case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3821 case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
3822 case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3823 case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
3824 case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3825 case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3826 case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3827 case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3828 case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3831 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
3832 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
3835 CurrentSMSMessageError = GE_SMSSENDFAILED;
3841 GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
3845 unsigned char req[256] = {
3847 0x01, 0x02, 0x00, /* SMS send request*/
3852 error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
3853 if (error != GE_NONE) return error;
3855 return NULL_SendMessageSequence
3856 (200, &CurrentSMSMessageError, 42+length, 0x02, req);
3859 void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3861 switch (MessageBuffer[3]) {
3866 fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
3869 CurrentSMSMessage->MessageNumber=MessageBuffer[5];
3871 CurrentSMSMessageError = GE_NONE;
3876 fprintf(stdout, _("SMS saving failed\n"));
3877 switch (MessageBuffer[4]) {
3878 case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
3879 case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
3880 default :fprintf(stdout, _(" Unknown error.\n"));break;
3884 switch (MessageBuffer[4]) {
3885 case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
3886 case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3887 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3892 /* GST_DR and GST_UN not supported ! */
3893 GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
3895 unsigned char req[256] = {
3896 N6110_FRAME_HEADER, 0x04, /* SMS save request*/
3897 0x00, /* SMS Status. Different for Inbox and Outbox */
3899 0x00, /* SMS Location */
3900 0x02, /* SMS Type */
3904 SMS_MessageType PDU;
3907 if (SMS->Location) req[6] = SMS->Location;
3909 if (SMS->folder==0) { /*Inbox*/
3910 req[4]=1; /* SMS Status */
3911 req[7] = 0x00; /* SMS Type */
3914 req[4]=5; /* SMS Status */
3915 req[7] = 0x02; /* SMS Type */
3919 if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
3921 error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
3922 if (error != GE_NONE) return error;
3924 CurrentSMSMessage = SMS;
3926 return NULL_SendMessageSequence
3927 (70, &CurrentSMSMessageError, 39+length, 0x14, req);
3930 void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3933 fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
3936 CurrentCBError = GE_NONE;
3939 /* Enable and disable Cell Broadcasting */
3940 GSM_Error N6110_EnableCellBroadcast(void)
3942 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
3943 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
3946 fprintf (stdout,"Enabling CB\n");
3949 CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
3950 CurrentCBMessage->Channel = 0;
3951 CurrentCBMessage->New = false;
3952 strcpy (CurrentCBMessage->Message,"");
3954 return NULL_SendMessageSequence
3955 (10, &CurrentCBError, 10, 0x02, req);
3959 GSM_Error N6110_DisableCellBroadcast(void)
3961 /* Should work, but not tested fully */
3963 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
3964 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
3966 return NULL_SendMessageSequence
3967 (10, &CurrentCBError, 10, 0x02, req);
3970 void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3973 unsigned char output[160];
3975 CurrentCBMessage->Channel = MessageBuffer[7];
3976 CurrentCBMessage->New = true;
3977 tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
3980 fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
3982 fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
3986 for (i=0; i<tmp;i++) {
3987 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
3990 fprintf(stdout, "\n");
3993 for (i=0; i<tmp; i++) {
3994 CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
3996 CurrentCBMessage->Message[i]=0;
3999 GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
4002 fprintf(stdout,"Reading CB\n");
4005 if (CurrentCBMessage != NULL)
4007 if (CurrentCBMessage->New == true)
4010 fprintf(stdout,"New CB received\n");
4012 Message->Channel = CurrentCBMessage->Channel;
4013 strcpy(Message->Message,CurrentCBMessage->Message);
4014 CurrentCBMessage->New = false;
4018 return (GE_NONEWCBRECEIVED);
4021 int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
4025 req[count++]=Bitmap.number;
4026 req[count++]=strlen(Bitmap.text);
4027 memcpy(req+count,Bitmap.text,req[count-1]);
4028 count+=req[count-1];
4029 req[count++]=Bitmap.ringtone;
4031 /* Setting for graphic:
4034 0x02 - View Graphics
4035 0x03 - Send Graphics
4037 You can even set it higher but Nokia phones (my
4038 6110 at least) will not show you the name of this
4039 item in menu ;-)) Nokia is really joking here. */
4040 if (Bitmap.enabled) req[count++]=0x01;
4041 else req[count++]=0x00;
4043 req[count++]=(Bitmap.size+4)>>8;
4044 req[count++]=(Bitmap.size+4)%0xff;
4045 req[count++]=0x00; /* Future extensions! */
4046 req[count++]=Bitmap.width;
4047 req[count++]=Bitmap.height;
4048 req[count++]=0x01; /* Just BW */
4049 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4051 return count+Bitmap.size;
4054 int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4058 EncodeNetworkCode(req+count, Bitmap.netcode);
4061 req[count++]=(Bitmap.size+4)>>8;
4062 req[count++]=(Bitmap.size+4)%0xff;
4063 req[count++]=0x00; /* Infofield */
4064 req[count++]=Bitmap.width;
4065 req[count++]=Bitmap.height;
4066 req[count++]=0x01; /* Just BW */
4067 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4069 return count+Bitmap.size;
4072 int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4077 req[count++]=Bitmap.height;
4078 req[count++]=Bitmap.width;
4079 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4081 return count+Bitmap.size;
4084 /* Set a bitmap or welcome-note */
4085 GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
4087 unsigned char req[600] = { N6110_FRAME_HEADER };
4093 /* Direct uploading variables */
4094 GSM_MultiSMSMessage SMS;
4095 unsigned char buffer[1000] = {0x0c,0x01};
4096 GSM_NetworkInfo NetworkInfo;
4100 /* Uploading with preview */
4101 if (Bitmap->number==255 &&
4102 (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
4103 GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
4104 memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
4106 memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
4108 buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
4110 Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
4112 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4113 return GE_NONE; //no answer from phone
4116 CurrentSetBitmapError = GE_BUSY;
4118 switch (Bitmap->type) {
4119 case GSM_WelcomeNoteText:
4120 case GSM_DealerNoteText:
4122 req[count++]=0x01; /* Only one block */
4124 if (Bitmap->type==GSM_WelcomeNoteText)
4125 req[count++]=0x02; /* Welcome text */
4127 req[count++]=0x03; /* Dealer Welcome Note */
4129 textlen=strlen(Bitmap->text);
4130 req[count++]=textlen;
4131 memcpy(req+count,Bitmap->text,textlen);
4135 Protocol->SendMessage(count, 0x05, req);
4139 case GSM_StartupLogo:
4140 if (Bitmap->number==0) {
4142 /* For 33xx we first set animated logo to default */
4143 if (GetModelFeature (FN_STARTUP)==F_STANIM) {
4144 error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4145 if (error!=GE_NONE) return error;
4149 req[count++]=0x01; /* Only one block */
4150 count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
4151 Protocol->SendMessage(count, 0x05, req);
4153 return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4157 case GSM_OperatorLogo:
4158 req[count++]=0x30; /* Store Op Logo */
4159 req[count++]=0x01; /* Location */
4160 count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
4161 Protocol->SendMessage(count, 0x05, req);
4164 case GSM_CallerLogo:
4166 count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
4167 Protocol->SendMessage(count, 0x03, req);
4170 case GSM_PictureImage:
4172 req[count++]=Bitmap->number;
4173 if (strcmp(Bitmap->Sender,"")) {
4174 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
4176 /* Convert number of semioctets to number of chars and add count */
4178 if (textlen % 2) textlen++;
4179 count+=textlen / 2 + 1;
4187 req[count++]=strlen(Bitmap->text);
4188 memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
4189 count+=strlen(Bitmap->text);
4191 req[count++]=Bitmap->width;
4192 req[count++]=Bitmap->height;
4194 memcpy(req+count,Bitmap->bitmap,Bitmap->size);
4195 Protocol->SendMessage(count+Bitmap->size, 0x47, req);
4198 case GSM_7110OperatorLogo:
4199 case GSM_7110StartupLogo:
4200 case GSM_6210StartupLogo:
4201 return GE_NOTSUPPORTED;
4207 /* Wait for timeout or other error. */
4208 while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
4211 return (GE_TIMEOUT);
4216 return CurrentSetBitmapError;
4219 /* Get a bitmap from the phone */
4220 GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
4222 unsigned char req[10] = { N6110_FRAME_HEADER };
4227 CurrentGetBitmap=Bitmap;
4228 CurrentGetBitmapError = GE_BUSY;
4230 switch (CurrentGetBitmap->type) {
4231 case GSM_StartupLogo:
4232 case GSM_WelcomeNoteText:
4233 case GSM_DealerNoteText:
4235 Protocol->SendMessage(count, 0x05, req);
4237 case GSM_OperatorLogo:
4239 req[count++]=0x01; /* Location 1 */
4240 Protocol->SendMessage(count, 0x05, req);
4242 case GSM_CallerLogo:
4244 req[count++]=Bitmap->number;
4245 Protocol->SendMessage(count, 0x03, req);
4247 case GSM_PictureImage:
4249 req[count++]=Bitmap->number;
4250 Protocol->SendMessage(count, 0x47, req);
4252 case GSM_7110OperatorLogo:
4253 case GSM_7110StartupLogo:
4254 case GSM_6210StartupLogo:
4256 return GE_NOTSUPPORTED;
4259 /* Wait for timeout or other error. */
4260 while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
4263 return (GE_TIMEOUT);
4268 CurrentGetBitmap=NULL;
4270 return CurrentGetBitmapError;
4273 void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4275 switch (MessageBuffer[3]) {
4277 /* Set ringtone OK */
4280 fprintf(stdout, _("Message: Ringtone set OK!\n"));
4282 CurrentRingtoneError=GE_NONE;
4285 /* Set ringtone error */
4288 fprintf(stdout, _("Message: Ringtone setting error !\n"));
4290 CurrentRingtoneError=GE_NOTSUPPORTED;
4295 GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
4298 char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
4299 {N6110_FRAME_HEADER,
4301 0x00, /* Location */
4304 int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
4306 /* Variables for preview uploading */
4307 unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
4308 unsigned char buffer2[20];
4309 GSM_NetworkInfo NetworkInfo;
4311 /* Setting ringtone with preview */
4312 if (ringtone->location==255) {
4315 EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
4316 memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
4317 *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
4318 Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
4319 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4321 return GE_NONE; //no answer from phone
4324 *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
4326 req[4]=ringtone->location-1;
4328 return NULL_SendMessageSequence
4329 (50, &CurrentRingtoneError, (size+7), 0x05, req);
4332 void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4336 switch (MessageBuffer[4]) {
4337 case 0x00: /* location supported. We have ringtone */
4339 /* Binary format used in N6150 */
4340 if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4342 fprintf(stdout,_("Message: ringtone \""));
4349 if (MessageBuffer[i]!=0)
4350 fprintf(stdout,_("%c"),MessageBuffer[i]);
4352 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4353 if (MessageBuffer[i]==0) break;
4358 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4361 /* Looking for end */
4364 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4367 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4371 if (i==MessageLength) break;
4375 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4376 CurrentGetBinRingtone->length=i-3;
4378 CurrentBinRingtoneError=GE_NONE;
4382 /* Binary format used in N3210 */
4383 if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4386 fprintf(stdout,_("Message: ringtone \""));
4393 if (MessageBuffer[i]!=0)
4394 fprintf(stdout,_("%c"),MessageBuffer[i]);
4396 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4397 if (MessageBuffer[i]==0) break;
4402 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4405 /* Here changes to get full compatibility with binary format used in N6150 */
4408 MessageBuffer[5]=0x0c;
4409 MessageBuffer[6]=0x01;
4410 MessageBuffer[7]=0x2c;
4412 /* Looking for end */
4415 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4418 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4422 if (i==MessageLength) break;
4426 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4428 CurrentGetBinRingtone->length=i-3;
4430 CurrentBinRingtoneError=GE_NONE;
4435 memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
4437 CurrentGetBinRingtone->length=MessageLength;
4440 fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
4442 CurrentBinRingtoneError=GE_UNKNOWNMODEL;
4448 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4451 CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
4455 GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
4457 unsigned char req[] = { 0x00,0x01,0x9e,
4462 CurrentGetBinRingtone=ringtone;
4464 error=N6110_EnableExtendedCommands(0x01);
4465 if (error!=GE_NONE) return error;
4467 req[3]=ringtone->location-1;
4469 return NULL_SendMessageSequence
4470 (50, &CurrentBinRingtoneError, 4, 0x40, req);
4473 void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4475 switch (MessageBuffer[4]) {
4476 case 0x00: /* location supported. We set ringtone */
4478 fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
4480 CurrentBinRingtoneError=GE_NONE;
4485 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4487 CurrentBinRingtoneError=GE_NOTSUPPORTED;
4492 GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
4494 unsigned char req[1000] = { 0x00,0x01,0xa0};
4498 GSM_BinRingtone ring;
4500 /* Must be sure, that can upload ringtone to this phone */
4501 ring.location=ringtone->location;
4502 error=N6110_GetBinRingTone(&ring);
4503 if (error!=GE_NONE) return error;
4505 error=N6110_EnableExtendedCommands(0x01);
4506 if (error!=GE_NONE) return error;
4508 memcpy(req+3,ringtone->frame,ringtone->length);
4510 req[3]=ringtone->location-1;
4512 return NULL_SendMessageSequence
4513 (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
4516 GSM_Error N6110_Reset(unsigned char type)
4518 return N6110_EnableExtendedCommands(type);
4521 void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4525 switch (MessageBuffer[3]) {
4527 /* Unknown message - it has been seen after the 0x07 message (call
4528 answered). Probably it has similar meaning. If you can solve
4529 this - just mail me. Pavel JanÃk ml.
4531 The message looks like this:
4539 Phone: [01 ][08 ][00 ] is the header of the frame
4541 [03 ] is the call message subtype
4543 [05 ] is the call sequence number
4547 [00 ][01 ][03 ][02 ][91][00] are unknown but has been
4548 seen in the Incoming call message (just after the
4549 caller's name from the phonebook). But never change
4550 between phone calls :-(
4553 /* This may mean sequence number of 'just made' call - CK */
4557 fprintf(stdout, _("Message: Call message, type 0x02:"));
4558 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4563 /* Possibly call OK */
4564 /* JD: I think that this means "call in progress" (incomming or outgoing) */
4568 fprintf(stdout, _("Message: Call message, type 0x03:"));
4569 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4570 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4573 CurrentCallSequenceNumber=MessageBuffer[4];
4574 CurrentIncomingCall[0]='D';
4575 if (CurrentCallPassup) CurrentCallPassup('D');
4579 /* Remote end has gone away before you answer the call. Probably your
4580 mother-in-law or banker (which is worse?) ... */
4584 fprintf(stdout, _("Message: Remote end hang up.\n"));
4585 fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
4587 switch (MessageBuffer[6]) {
4588 case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
4589 case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
4590 case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
4591 case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4592 case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
4593 case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4596 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
4597 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4600 CurrentIncomingCall[0] = ' ';
4601 if (CurrentCallPassup) CurrentCallPassup(' ');
4605 /* Incoming call alert */
4609 fprintf(stdout, _("Message: Incoming call alert:\n"));
4611 /* We can have more then one call ringing - we can distinguish between
4614 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4615 fprintf(stdout, _(" Number: "));
4617 count=MessageBuffer[6];
4619 for (tmp=0; tmp <count; tmp++)
4620 fprintf(stdout, "%c", MessageBuffer[7+tmp]);
4622 fprintf(stdout, "\n");
4624 fprintf(stdout, _(" Name: "));
4626 for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
4627 fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
4629 fprintf(stdout, "\n");
4632 count=MessageBuffer[6];
4634 CurrentIncomingCall[0] = 0;
4635 for (tmp=0; tmp <count; tmp++)
4636 sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
4640 /* Call answered. Probably your girlfriend...*/
4644 fprintf(stdout, _("Message: Call answered.\n"));
4645 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4650 /* Call ended. Girlfriend is girlfriend, but time is money :-) */
4654 fprintf(stdout, _("Message: Call ended by your phone.\n"));
4655 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4660 /* This message has been seen with the message of subtype 0x09
4661 after I hang the call.
4668 Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
4670 What is the meaning of 87? Can you spell some magic light into
4675 /* Probably means call over - CK */
4679 fprintf(stdout, _("Message: Call message, type 0x0a:"));
4680 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4681 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4684 CurrentIncomingCall[0] = ' ';
4685 if (CurrentCallPassup) CurrentCallPassup(' ');
4692 fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
4695 if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
4697 if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
4704 fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
4706 AppendLogText("Unknown msg\n",false);
4708 break; /* Visual C Don't like empty cases */
4712 void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4716 switch (MessageBuffer[3]) {
4720 /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
4721 /* If you want see, if it works with your phone make something like that: */
4723 /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
4724 /* Protocol->SendMessage(4, 0x04, connect5); */
4726 /* Marcin-Wiacek@TopNet.PL */
4729 sprintf(Current_IMEI, "%s", MessageBuffer+5);
4730 sprintf(Current_Model, "%s", MessageBuffer+21);
4731 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4733 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
4734 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
4735 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4739 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
4740 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
4741 fprintf(stdout, _(" Model: %s\n"), Current_Model);
4742 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
4743 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
4744 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
4749 /* Get group data */
4750 /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
4753 if (CurrentGetBitmap!=NULL) {
4754 if (CurrentGetBitmap->number==MessageBuffer[4]) {
4755 count=MessageBuffer[5];
4756 memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
4757 CurrentGetBitmap->text[count]=0;
4760 fprintf(stdout, _("Message: Caller group datas\n"));
4761 fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
4766 CurrentGetBitmap->ringtone=MessageBuffer[count++];
4768 fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
4769 if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
4770 fprintf(stdout,_("\n"));
4773 CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
4775 fprintf(stdout, _("Caller group logo "));
4776 if (CurrentGetBitmap->enabled)
4777 fprintf(stdout, _("enabled \n"));
4779 fprintf(stdout, _("disabled \n"));
4782 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4783 CurrentGetBitmap->size+=MessageBuffer[count++];
4785 fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
4789 CurrentGetBitmap->width=MessageBuffer[count++];
4790 CurrentGetBitmap->height=MessageBuffer[count++];
4792 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
4793 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4794 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
4795 CurrentGetBitmapError=GE_NONE;
4798 fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
4803 fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
4808 /* Get group data error */
4811 CurrentGetBitmapError=GE_UNKNOWN;
4813 fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
4817 /* Set group data OK */
4820 CurrentSetBitmapError=GE_NONE;
4822 fprintf(stdout, _("Message: Caller group data set correctly.\n"));
4826 /* Set group data error */
4829 CurrentSetBitmapError=GE_UNKNOWN;
4831 fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
4838 fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
4840 AppendLogText("Unknown msg\n",false);
4842 break; /* Visual C Don't like empty cases */
4846 void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4848 int tmp, count, length;
4855 switch (MessageBuffer[3]) {
4861 fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
4864 if (CurrentGetBitmap!=NULL) {
4870 for (tmp=0;tmp<MessageBuffer[4];tmp++){
4871 switch (MessageBuffer[count++]) {
4873 if (CurrentGetBitmap->type==GSM_StartupLogo) {
4874 CurrentGetBitmap->height=MessageBuffer[count++];
4875 CurrentGetBitmap->width=MessageBuffer[count++];
4876 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
4877 length=CurrentGetBitmap->size;
4878 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
4880 length=MessageBuffer[count++];
4881 length=length*MessageBuffer[count++]/8;
4885 fprintf(stdout, _("Startup logo supported - "));
4886 if (length!=0) { fprintf(stdout, _("currently set\n")); }
4887 else { fprintf(stdout, _("currently empty\n")); }
4889 if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
4892 length=MessageBuffer[count];
4893 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
4894 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
4895 CurrentGetBitmap->text[length]=0;
4898 fprintf(stdout, _("Startup Text supported - "));
4901 fprintf(stdout, _("currently set to \""));
4902 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
4903 fprintf(stdout, _("\"\n"));
4905 fprintf(stdout, _("currently empty\n"));
4909 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
4912 length=MessageBuffer[count];
4913 if (CurrentGetBitmap->type==GSM_DealerNoteText) {
4914 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
4915 CurrentGetBitmap->text[length]=0;
4918 fprintf(stdout, _("Dealer Welcome supported - "));
4921 fprintf(stdout, _("currently set to \""));
4922 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
4923 fprintf(stdout, _("\"\n"));
4925 fprintf(stdout, _("currently empty\n"));
4929 if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
4933 if (issupported) CurrentGetBitmapError=GE_NONE;
4934 else CurrentGetBitmapError=GE_NOTSUPPORTED;
4937 fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
4942 /* Set startup OK */
4945 CurrentSetBitmapError=GE_NONE;
4947 fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
4951 /* Set Operator Logo OK */
4955 fprintf(stdout, _("Message: Operator logo correctly set.\n"));
4958 CurrentSetBitmapError=GE_NONE;
4961 /* Set Operator Logo Error */
4965 fprintf(stdout, _("Message: Error setting operator logo!\n"));
4968 CurrentSetBitmapError=GE_UNKNOWN;
4972 /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
4975 if (CurrentGetBitmap!=NULL) {
4977 count=5; /* Location ignored. */
4979 DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
4983 fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
4984 CurrentGetBitmap->netcode,
4985 GSM_GetNetworkName(CurrentGetBitmap->netcode));
4988 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4989 CurrentGetBitmap->size+=MessageBuffer[count++];
4991 CurrentGetBitmap->width=MessageBuffer[count++];
4992 CurrentGetBitmap->height=MessageBuffer[count++];
4994 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
4995 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4996 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
4997 CurrentGetBitmapError=GE_NONE;
5000 fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
5006 /* Get op logo error */
5010 fprintf(stdout, _("Message: Error getting operator logo!\n"));
5012 CurrentGetBitmapError=GE_UNKNOWN;
5018 fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
5020 AppendLogText("Unknown msg\n",false);
5026 void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5029 unsigned char output[160];
5035 switch (MessageBuffer[3]) {
5039 /* MessageBuffer[3] = 0x05
5040 MessageBuffer[4] = 0x00
5041 MessageBuffer[5] = 0x0f
5042 MessageBuffer[6] = 0x03
5043 MessageBuffer[7] = length of packed message
5045 This is all I have seen - Gerry Anderson */
5047 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
5051 fprintf(stdout, _("Message from Network operator: "));
5053 for (i=0; i<tmp; i++)
5054 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
5056 fprintf(stdout, "\n");
5065 fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
5067 AppendLogText("Unknown msg\n",false);
5073 void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5075 switch (MessageBuffer[3]) {
5079 fprintf(stdout, _("Message: SIM card login\n"));
5085 fprintf(stdout, _("Message: SIM card logout\n"));
5091 fprintf(stdout, _("Unknown message of type 0x09.\n"));
5093 AppendLogText("Unknown msg\n",false);
5098 void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5100 switch(MessageBuffer[3]) {
5105 fprintf(stdout, _("Message: Calendar Alarm active\n"));
5106 fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
5111 fprintf(stdout, _("Unknown message of type 0x13.\n"));
5113 AppendLogText("Unknown msg\n",false);
5118 void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5122 switch(MessageBuffer[2]) {
5127 fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
5130 CurrentMagicError=GE_NONE;
5136 fprintf(stdout, _("Message: Answer for call commands.\n"));
5139 CurrentDialVoiceError=GE_NONE;
5145 fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
5148 CurrentMagicError=GE_NONE;
5154 fprintf(stdout, _("Message: ACK for simlock closing\n"));
5157 CurrentMagicError=GE_NONE;
5162 switch (MessageBuffer[5]) {
5165 fprintf(stdout,_("Message: EEPROM contest received\n"));
5168 if (MessageBuffer[8]!=0x00) {
5169 for (i=9;i<MessageLength;i++) {
5170 fprintf(stdout,_("%c"), MessageBuffer[i]);
5173 CurrentMagicError=GE_NONE;
5180 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5182 AppendLogText("Unknown msg\n",false);
5187 N6110_DisplayTestsInfo(MessageBuffer);
5193 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5195 AppendLogText("Unknown msg\n",false);
5196 break; /* Visual C Don't like empty cases */
5200 void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5204 switch(MessageBuffer[3]) {
5210 if (MessageBuffer[5]!=0) {
5211 strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
5213 while (MessageBuffer[count]!=0) {
5219 strcpy(CurrentGetBitmap->Sender,"\0");
5224 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
5225 CurrentGetBitmap->text[MessageBuffer[count]]=0;
5227 if (MessageBuffer[count]!=0)
5228 count+=MessageBuffer[count];
5233 fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
5236 CurrentGetBitmap->width=MessageBuffer[count+1];
5237 CurrentGetBitmap->height=MessageBuffer[count+2];
5238 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5240 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
5242 CurrentGetBitmapError=GE_NONE;
5248 fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
5250 CurrentSetBitmapError=GE_NONE;
5251 CurrentGetBitmapError=GE_NONE;
5257 fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
5259 CurrentSetBitmapError=GE_UNKNOWN;
5265 fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
5267 CurrentGetBitmapError=GE_UNKNOWN;
5273 fprintf(stdout, _("Unknown message of type 0x47.\n"));
5275 AppendLogText("Unknown msg\n",false);
5276 break; /* Visual C Don't like empty cases */
5280 void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5283 sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
5284 AppendLog(buffer,strlen(buffer),false);
5287 fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
5291 CurrentLinkOK = true;
5294 void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5297 fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
5302 /* This function is used for parsing the RLP frame into fields. */
5303 void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
5310 /* We do not need RLP frame parsing to be done when we do not have callback
5312 if (CurrentRLP_RXCallback == NULL)
5315 /* Anybody know the official meaning of the first two bytes?
5316 Nokia 6150 sends junk frames starting D9 01, and real frames starting
5317 D9 00. We'd drop the junk frames anyway because the FCS is bad, but
5318 it's tidier to do it here. We still need to call the callback function
5319 to give it a chance to handle timeouts and/or transmit a frame */
5320 if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
5323 /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
5324 specification, so Header consists of 16 bits (2 bytes). See section 4.1
5325 of the specification. */
5327 frame.Header[0] = MessageBuffer[2];
5328 frame.Header[1] = MessageBuffer[3];
5330 /* Next 200 bits (25 bytes) contain the Information. We store the
5331 information in the Data array. */
5333 for (count = 0; count < 25; count ++)
5334 frame.Data[count] = MessageBuffer[4 + count];
5336 /* The last 24 bits (3 bytes) contain FCS. */
5338 frame.FCS[0] = MessageBuffer[29];
5339 frame.FCS[1] = MessageBuffer[30];
5340 frame.FCS[2] = MessageBuffer[31];
5342 /* Here we pass the frame down in the input stream. */
5343 CurrentRLP_RXCallback(valid ? &frame : NULL);
5346 void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5349 fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
5354 void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5356 GSM_SMSMessage NullSMS;
5358 switch (MessageBuffer[6]) {
5360 case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
5361 case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
5363 /* Is it possible ? */
5364 case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
5365 default: NullSMS.Type = GST_UN; break;
5369 if (NullSMS.Type == GST_DR)
5370 fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
5372 fprintf(stdout, _("Message: SMS Message Received\n"));
5375 GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
5378 fprintf(stdout, _("\n"));
5382 void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5386 /* Switch on the basis of the message type byte */
5387 switch (MessageType) {
5389 /* Call information */
5392 N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
5397 switch (MessageBuffer[3]) {
5399 case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5400 case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
5401 case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5402 case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5403 case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5405 case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5406 default :unknown=true;break;
5410 /* Phonebook handling */
5412 switch (MessageBuffer[3]) {
5414 case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
5416 case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
5418 case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
5420 case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5422 case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5423 default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
5429 switch (MessageBuffer[3]) {
5430 case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
5431 default :unknown=true;break;
5435 /* Startup Logo, Operator Logo and Profiles. */
5437 switch (MessageBuffer[3]) {
5438 case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5439 case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5440 case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5441 case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5442 case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5443 case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5444 default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
5448 /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
5451 switch (MessageBuffer[3]) {
5453 case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
5454 default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
5458 /* Security code requests */
5460 switch (MessageBuffer[3]) {
5461 case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
5462 case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5463 default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5470 N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
5475 switch (MessageBuffer[3]) {
5476 case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
5477 default :unknown=true;break;
5481 /* Simulating key pressing */
5483 switch (MessageBuffer[3]) {
5484 case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
5485 default :unknown=true;break;
5491 switch (MessageBuffer[3]) {
5492 case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5493 case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
5494 case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5495 default :unknown=true;break;
5499 /* Phone Clock and Alarm */
5501 switch (MessageBuffer[3]) {
5502 case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
5503 case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
5504 case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
5505 case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
5506 default :unknown=true;break;
5510 /* Calendar notes handling */
5512 switch (MessageBuffer[3]) {
5513 case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5514 case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5515 case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
5516 default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
5522 switch (MessageBuffer[3]) {
5524 case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5526 case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5527 case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5529 case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
5530 default :unknown=true;break;
5536 switch (MessageBuffer[3]) {
5538 case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
5540 case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5542 case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5545 case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
5546 default :unknown=true;break;
5550 /* Internal phone functions? */
5552 switch (MessageBuffer[2]) {
5553 case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
5554 case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
5555 case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
5556 case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5557 case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5558 case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5559 case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
5560 case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
5561 case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5562 case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5563 case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
5564 case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5565 case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5566 case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
5567 default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
5571 /* Picture Images */
5574 N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
5577 /* Mobile phone identification */
5580 N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
5583 /***** Acknowlegment of our frames. *****/
5584 case FBUS_FRTYPE_ACK:
5586 N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
5589 /***** Power on message. *****/
5592 N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
5597 N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
5600 /***** RLP frame received. *****/
5603 N6110_RX_HandleRLPMessage(MessageBuffer);
5606 /***** Power on message. *****/
5609 N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
5612 /***** Unknown message *****/
5613 /* If you think that you know the exact meaning of other messages - please
5618 fprintf(stdout, _("Message: Unknown message type.\n"));
5620 AppendLogText("Unknown msg type\n",false);
5629 fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
5631 AppendLogText("Unknown msg\n",false);