5 A Linux/Unix toolset and driver for Nokia mobile phones.
7 Released under the terms of the GNU GPL, see file COPYING for more details.
9 This file provides an API for accessing functions on the 6110 and similar
16 /* "Turn on" prototypes in n-6110.h */
20 /* System header files */
26 #include "misc_win32.h"
29 /* Various header file */
35 #include "gsm-coding.h"
36 #include "newmodules/n6110.h"
37 #include "newmodules/n7110.h"
38 #include "protocol/fbus.h"
39 #include "devices/device.h"
40 /* Global variables used by code in gsm-api.c to expose the functions
41 supported by this model of phone. */
44 /* Here we initialise model specific functions. */
45 GSM_Functions N6110_Functions = {
47 N6110_DispatchMessage,
50 N6110_GetMemoryLocation,
51 N6110_WritePhonebookLocation,
54 N6110_GetMemoryStatus,
60 N6110_DeleteSMSMessage,
73 N6110_GetBatteryLevel,
76 N6110_GetDisplayStatus,
77 N6110_EnterSecurityCode,
78 N6110_GetSecurityCodeStatus,
79 N6110_GetSecurityCode,
104 N6110_GetIncomingCallNr,
105 N6110_GetNetworkInfo,
106 N6110_GetCalendarNote,
107 N6110_WriteCalendarNote,
108 N6110_DeleteCalendarNote,
114 N6110_SetBinRingTone,
115 N6110_GetBinRingTone,
142 N6110_EnableDisplayOutput,
143 N6110_DisableDisplayOutput,
144 N6110_EnableCellBroadcast,
145 N6110_DisableCellBroadcast,
146 N6110_ReadCellBroadcast,
148 N6110_GetProductProfileSetting,
149 N6110_SetProductProfileSetting,
150 N6110_GetOperatorName,
151 N6110_SetOperatorName,
152 N6110_GetVoiceMailbox, N6110_Tests,
154 UNIMPLEMENTED, //GetCalendarNotesInfo
156 N6110_ResetPhoneSettings,
157 N7110_GetWAPBookmark,
158 N7110_SetWAPBookmark,
159 N7110_GetWAPSettings,
176 NULL, //GetCalendarNotesInfo
185 N6110_GetManufacturer
188 /* Mobile phone information */
190 GSM_Information N6110_Information = {
191 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
192 /* Supported models in FBUS */
193 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
194 /* Supported models in MBUS */
195 "6110|6130|6150|8210|8850",
196 /* Supported models in FBUS over infrared */
198 /* Supported models in FBUS over DLR3 */
202 /* infrared sockets */
203 "6110|6130|6150|8210|8850",
204 /* Supported models in FBUS over infrared with Tekram device */
205 4, /* Max RF Level */
206 0, /* Min RF Level */
207 GRF_Arbitrary, /* RF level units */
208 4, /* Max Battery Level */
209 0, /* Min Battery Level */
210 GBU_Arbitrary, /* Battery level units */
211 GDT_DateTime, /* Have date/time support */
212 GDT_TimeOnly, /* Alarm supports time only */
213 1 /* Only one alarm available */
217 static const char *N6110_MemoryType_String [] = {
231 /* Magic bytes from the phone. */
232 static unsigned char MagicBytes[4] = { 0x00, 0x00, 0x00, 0x00 };
234 /* For DisplayOutput */
236 static char PhoneScreen[5+1][27+1];
237 static int OldX=1000,OldY=0,NewX=0,NewY=0;
240 void N6110_ReplyEnableExtendedCommands(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
243 fprintf(stdout, _("Message: Answer for EnableExtendedSecurityCommands frame, meaning not known :-(\n"));
246 CurrentEnableExtendedCommandsError=GE_NONE;
249 /* If you set make some things (for example,
250 change Security Code from phone's menu, disable and enable
251 phone), it won't answer for 0x40 frame - you won't be able
252 to play tones, get netmonitor, etc.
254 This function do thing called "Enabling extended security commands" -
255 it enables 0x40 frame functions.
257 This frame can also some other things - see below */
258 GSM_Error N6110_EnableExtendedCommands (unsigned char status)
260 unsigned char req[4] = { 0x00,
261 0x01,0x64, /* Enable extended commands request */
262 0x01 }; /* 0x01 - on, 0x00 - off,
263 0x03 & 0x04 - soft & hard reset,
264 0x06 - CONTACT SERVICE */
266 /* 0x06 MAKES CONTACT SERVICE! BE CAREFULL! */
267 /* When use 0x03 and had during session changed time & date
268 some phones (like 6150 or 6210) can ask for time & date after reset
269 or disable clock on the screen */
270 if (status!=0x06) req[3] = status;
272 return NULL_SendMessageSequence
273 (50, &CurrentEnableExtendedCommandsError, 4, 0x40, req);
276 void N6110_ReplyIMEI(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
278 #if defined WIN32 || !defined HAVE_SNPRINTF
279 sprintf(Current_IMEI, "%s", MessageBuffer+4);
281 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+4);
285 fprintf(stdout, _("Message: IMEI %s received\n"),Current_IMEI);
288 CurrentGetIMEIError=GE_NONE;
291 GSM_Error N6110_SendIMEIFrame()
293 unsigned char req[4] = {0x00, 0x01, 0x66, 0x00};
297 error=N6110_EnableExtendedCommands(0x01);
298 if (error!=GE_NONE) return error;
300 return NULL_SendMessageSequence (20, &CurrentGetIMEIError, 4, 0x40, req);
303 void N6110_ReplyHW(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
307 if (MessageBuffer[3]==0x05) {
310 fprintf(stdout,_("Message: Hardware version received: "));
313 j=strlen(Current_Revision);
314 Current_Revision[j++]=',';
315 Current_Revision[j++]=' ';
316 Current_Revision[j++]='H';
317 Current_Revision[j++]='W';
321 fprintf(stdout,_("%c"), MessageBuffer[i]);
323 Current_Revision[j++]=MessageBuffer[i];
327 fprintf(stdout,_("\n"));
330 CurrentGetHWError=GE_NONE;
334 GSM_Error N6110_SendHWFrame()
336 unsigned char req[4] = {0x00, 0x01, 0xc8, 0x05};
340 error=N6110_EnableExtendedCommands(0x01);
341 if (error!=GE_NONE) return error;
343 return NULL_SendMessageSequence (20, &CurrentGetHWError, 4, 0x40, req);
346 void N6110_ReplyID(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
351 fprintf(stdout, _("Message: Mobile phone model identification received:\n"));
352 fprintf(stdout, _(" Firmware: "));
355 strcpy(Current_Revision,"SW");
358 while (MessageBuffer[i]!=0x0a) {
359 Current_Revision[j]=MessageBuffer[i];
361 fprintf(stdout, _("%c"),MessageBuffer[i]);
363 if (j==GSM_MAX_REVISION_LENGTH-1) {
365 fprintf(stderr,_("ERROR: increase GSM_MAX_REVISION_LENGTH!\n"));
372 Current_Revision[j+1]=0;
375 fprintf(stdout, _("\n Firmware date: "));
379 while (MessageBuffer[i]!=0x0a) {
381 fprintf(stdout, _("%c"),MessageBuffer[i]);
387 fprintf(stdout, _("\n Model: "));
391 while (MessageBuffer[i]!=0x0a) {
392 Current_Model[j]=MessageBuffer[i];
394 fprintf(stdout, _("%c"),MessageBuffer[i]);
396 if (j==GSM_MAX_MODEL_LENGTH-1) {
398 fprintf(stderr,_("ERROR: increase GSM_MAX_MODEL_LENGTH!\n"));
405 Current_Model[j+1]=0;
408 fprintf(stdout, _("\n"));
411 CurrentMagicError=GE_NONE;
414 GSM_Error N6110_SendIDFrame()
416 unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
418 return NULL_SendMessageSequence (50, &CurrentMagicError, 5, 0xd1, req);
421 /* This function send the status request to the phone. */
422 /* Seems to be ignored in N3210 */
423 GSM_Error N6110_SendStatusRequest(void)
425 unsigned char req[] = {N6110_FRAME_HEADER, 0x01};
427 Protocol->SendMessage(4, 0x04, req);
432 static void N6110_ReplyGetAuthentication(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
434 #if defined WIN32 || !defined HAVE_SNPRINTF
435 sprintf(Current_IMEI, "%s", MessageBuffer+9);
436 sprintf(Current_Model, "%s", MessageBuffer+25);
437 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
439 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+9);
440 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+25);
441 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
445 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
446 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
447 fprintf(stdout, _(" Model: %s\n"), Current_Model);
448 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+31);
449 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+39);
450 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+44);
452 /* These bytes are probably the source of the "Accessory not connected"
453 messages on the phone when trying to emulate NCDS... I hope....
454 UPDATE: of course, now we have the authentication algorithm. */
455 fprintf(stdout, _(" Magic bytes: %02x %02x %02x %02x\n"), MessageBuffer[50], MessageBuffer[51], MessageBuffer[52], MessageBuffer[53]);
458 MagicBytes[0]=MessageBuffer[50];
459 MagicBytes[1]=MessageBuffer[51];
460 MagicBytes[2]=MessageBuffer[52];
461 MagicBytes[3]=MessageBuffer[53];
463 CurrentMagicError=GE_NONE;
466 /* This function provides Nokia authentication protocol.
468 This code is written specially for gnokii project by Odinokov Serge.
469 If you have some special requests for Serge just write him to
470 apskaita@post.omnitel.net or serge@takas.lt
472 Reimplemented in C by Pavel JanÃk ml.
474 Nokia authentication protocol is used in the communication between Nokia
475 mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software,
476 commercially sold by Nokia Corp.
478 The authentication scheme is based on the token send by the phone to the
479 software. The software does it's magic (see the function
480 FB61_GetNokiaAuth()) and returns the result back to the phone. If the
481 result is correct the phone responds with the message "Accessory
482 connected!" displayed on the LCD. Otherwise it will display "Accessory not
483 supported" and some functions will not be available for use.
485 The specification of the protocol is not publicly available, no comment. */
486 static void N6110_GetNokiaAuth(unsigned char *Imei, unsigned char *MagicBytes, unsigned char *MagicResponse)
491 /* This is our temporary working area. */
493 unsigned char Temp[16];
495 /* Here we put FAC (Final Assembly Code) and serial number into our area. */
506 /* And now the TAC (Type Approval Code). */
513 /* And now we pack magic bytes from the phone. */
515 Temp[12] = MagicBytes[0];
516 Temp[13] = MagicBytes[1];
517 Temp[14] = MagicBytes[2];
518 Temp[15] = MagicBytes[3];
520 for (i=0; i<=11; i++)
524 switch (Temp[15] & 0x03) {
531 Temp[i+j] ^= Temp[i+12];
539 Temp[i + j] |= Temp[i + 12];
542 for (i=0; i<=15; i++)
545 for (i=0; i<=15; i++) {
547 switch (Temp[15 - i] & 0x06) {
569 MagicResponse[i] = j;
574 static GSM_Error N6110_Authentication()
576 unsigned char connect1[] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x02};
577 unsigned char connect2[] = {N6110_FRAME_HEADER, 0x20, 0x02};
578 unsigned char connect3[] = {N6110_FRAME_HEADER, 0x0d, 0x01, 0x00, 0x02};
579 unsigned char connect4[] = {N6110_FRAME_HEADER, 0x10};
581 unsigned char magic_connect[] = {N6110_FRAME_HEADER,
584 /* The real magic goes here ... These bytes are filled in with the
585 function N6110_GetNokiaAuth(). */
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 /* NOKIA&GNOKII Accessory */
592 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x26, 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x20,
593 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x79,
595 0x00, 0x00, 0x00, 0x00};
598 fprintf(stdout,_("Making authentication!\n"));
601 usleep(100); Protocol->SendMessage(7, 0x02, connect1);
602 usleep(100); Protocol->SendMessage(5, 0x02, connect2);
603 usleep(100); Protocol->SendMessage(7, 0x02, connect3);
605 CurrentMagicError = GE_BUSY;
607 usleep(100); Protocol->SendMessage(4, 0x64, connect4);
608 if (NULL_WaitUntil(50,&CurrentMagicError)!=GE_NONE) return GE_TIMEOUT;
610 N6110_GetNokiaAuth(Current_IMEI, MagicBytes, magic_connect+4);
612 Protocol->SendMessage(45, 0x64, magic_connect);
615 fprintf(stdout,_("End of authentication!\n"));
621 /* Initialise variables and state machine. */
622 GSM_Error N6110_Initialise(char *port_device, char *initlength,
623 GSM_ConnectionType connection,
624 void (*rlp_callback)(RLP_F96Frame *frame))
626 unsigned char init_char = N6110_SYNC_BYTE;
628 unsigned char end_init_char = N6110_IR_END_SYNC_BYTE;
634 if (Protocol->Initialise(port_device,initlength,connection,rlp_callback)!=GE_NONE)
636 return GE_NOTSUPPORTED;
639 switch (CurrentConnectionType) {
643 /* We don't think about authentication in Irda, because
644 AFAIK there are no phones working over sockets
645 and having authentication. In MBUS it doesn't work */
648 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
650 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
652 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
654 CurrentLinkOK = true;
663 InitLength = atoi(initlength);
665 if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
666 InitLength = 250; /* This is the usual value, lower may work. */
670 if (CurrentConnectionType==GCT_Infrared ||
671 CurrentConnectionType==GCT_Tekram) {
673 fprintf(stdout,_("Setting infrared for FBUS communication...\n"));
675 device_changespeed(9600);
680 fprintf(stdout,_("Writing init chars...."));
683 /* Initialise link with phone or what have you */
684 /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
686 for (count = 0; count < InitLength; count ++) {
688 if (CurrentConnectionType!=GCT_Infrared &&
689 CurrentConnectionType!=GCT_Tekram)
692 Protocol->WritePhone(1,&init_char);
696 if (CurrentConnectionType==GCT_Infrared ||
697 CurrentConnectionType==GCT_Tekram) {
698 Protocol->WritePhone(1,&end_init_char);
704 fprintf(stdout,_("Done\n"));
708 if (CurrentConnectionType==GCT_Infrared ||
709 CurrentConnectionType==GCT_Tekram) {
710 device_changespeed(115200);
714 N6110_SendStatusRequest();
718 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
720 /* N51xx/61xx have something called authentication.
721 After making it phone display "Accessory connected"
722 and probably give access to some function (I'm not too sure about it !)
723 Anyway, I make it now for N51xx/61xx */
724 if (GetModelFeature (FN_AUTHENTICATION)!=0) {
725 if (N6110_Authentication()!=GE_NONE) return GE_TIMEOUT;
726 } else { /* No authentication */
727 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
729 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
735 fprintf(stdout,_("Unknown connection type in n6110.c!\n"));
743 /* This function translates GMT_MemoryType to N6110_MEMORY_xx */
744 int N6110_GetMemoryType(GSM_MemoryType memory_type)
749 switch (memory_type) {
751 case GMT_MT: result = N6110_MEMORY_MT; break;
752 case GMT_ME: result = N6110_MEMORY_ME; break;
753 case GMT_SM: result = N6110_MEMORY_SM; break;
754 case GMT_FD: result = N6110_MEMORY_FD; break;
755 case GMT_ON: result = N6110_MEMORY_ON; break;
756 case GMT_EN: result = N6110_MEMORY_EN; break;
757 case GMT_DC: result = N6110_MEMORY_DC; break;
758 case GMT_RC: result = N6110_MEMORY_RC; break;
759 case GMT_MC: result = N6110_MEMORY_MC; break;
760 default : result = N6110_MEMORY_XX;
769 void N6110_ReplyCallDivert(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
771 switch (MessageBuffer[3]) {
776 fprintf(stdout, _("Message: Call divert status received\n"));
777 fprintf(stdout, _(" Divert type: "));
778 switch (MessageBuffer[6]) {
779 case 0x43: fprintf(stdout, _("when busy"));break;
780 case 0x3d: fprintf(stdout, _("when not answered"));break;
781 case 0x3e: fprintf(stdout, _("when phone off or no coverage"));break;
782 case 0x15: fprintf(stdout, _("all types of diverts"));break; //?
783 case 0x02: fprintf(stdout, _("all types of diverts"));break; //?
784 default: fprintf(stdout, _("unknown %i"),MessageBuffer[6]);break;
786 fprintf(stdout, _("\n Calls type : "));
787 if (MessageBuffer[6]==0x02)
788 fprintf(stdout, _("voice, fax & data")); //?
790 switch (MessageBuffer[8]) {
791 case 0x0b: fprintf(stdout, _("voice"));break;
792 case 0x0d: fprintf(stdout, _("fax"));break;
793 case 0x19: fprintf(stdout, _("data"));break;
794 default: fprintf(stdout, _("unknown %i"),MessageBuffer[8]);break;
797 fprintf(stdout, _("\n"));
798 if (MessageBuffer[10]==0x01) {
799 fprintf(stdout, _(" Status : active\n"));
800 fprintf(stdout, _(" Timeout : %i seconds\n"),MessageBuffer[45]);
801 fprintf(stdout, _(" Number : %s\n"),GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
803 fprintf(stdout, _(" Status : deactivated\n"));
807 switch (MessageBuffer[6]) {
808 case 0x43: CurrentCallDivert->DType=GSM_CDV_Busy;break;
809 case 0x3d: CurrentCallDivert->DType=GSM_CDV_NoAnswer;break;
810 case 0x3e: CurrentCallDivert->DType=GSM_CDV_OutOfReach;break;
811 case 0x15: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
812 case 0x02: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
815 if (MessageBuffer[6]==0x02) //?
816 CurrentCallDivert->CType=GSM_CDV_AllCalls;
818 switch (MessageBuffer[8]) {
819 case 0x0b: CurrentCallDivert->CType=GSM_CDV_VoiceCalls;break;
820 case 0x0d: CurrentCallDivert->CType=GSM_CDV_FaxCalls; break;
821 case 0x19: CurrentCallDivert->CType=GSM_CDV_DataCalls; break;
825 if (MessageBuffer[10]==0x01) {
826 CurrentCallDivert->Enabled=true;
827 CurrentCallDivert->Timeout=MessageBuffer[45];
828 strcpy(CurrentCallDivert->Number,GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
830 CurrentCallDivert->Enabled=false;
833 CurrentCallDivertError=GE_NONE;
838 fprintf(stdout, _("Message: Call divert status receiving error ?\n"));
840 CurrentCallDivertError=GE_UNKNOWN;
845 GSM_Error N6110_CallDivert(GSM_CallDivert *cd)
847 char req[55] = { N6110_FRAME_HEADER, 0x01,
848 0x00, /* operation */
850 0x00, /* divert type */
851 0x00, /* call type */
857 switch (cd->Operation) {
858 case GSM_CDV_Register:
862 req[29]= GSM_PackSemiOctetNumber(cd->Number, req + 9, false);
863 req[52]= cd->Timeout;
866 case GSM_CDV_Erasure:
867 case GSM_CDV_Disable:
874 return GE_NOTIMPLEMENTED;
878 case GSM_CDV_AllTypes : req[6] = 0x15; break;
879 case GSM_CDV_Busy : req[6] = 0x43; break;
880 case GSM_CDV_NoAnswer : req[6] = 0x3d; break;
881 case GSM_CDV_OutOfReach: req[6] = 0x3e; break;
882 default: return GE_NOTIMPLEMENTED;
885 if ((cd->DType == GSM_CDV_AllTypes) &&
886 (cd->CType == GSM_CDV_AllCalls))
890 case GSM_CDV_AllCalls : break;
891 case GSM_CDV_VoiceCalls: req[7] = 0x0b; break;
892 case GSM_CDV_FaxCalls : req[7] = 0x0d; break;
893 case GSM_CDV_DataCalls : req[7] = 0x19; break;
894 default: return GE_NOTIMPLEMENTED;
897 CurrentCallDivert = cd;
899 error=NULL_SendMessageSequence
900 (100, &CurrentCallDivertError, length, 0x06, req);
902 CurrentCallDivert = NULL;
907 GSM_Error N6110_Tests()
909 unsigned char buffer[3]={0x00,0x01,0xcf};
910 unsigned char buffer3[8]={0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00};
914 error=N6110_EnableExtendedCommands(0x01);
915 if (error!=GE_NONE) return error;
917 //make almost all tests
918 Protocol->SendMessage(8, 0x40, buffer3);
920 while (GSM->Initialise(PortDevice, "50", CurrentConnectionType, CurrentRLP_RXCallback)!=GE_NONE) {};
924 return NULL_SendMessageSequence
925 (200, &CurrentNetworkInfoError, 3, 0x40, buffer);
928 void N6110_DisplayTestsInfo(u8 *MessageBuffer) {
932 CurrentNetworkInfoError=GE_NONE;
934 for (i=0;i<MessageBuffer[3];i++) {
936 case 0: fprintf(stdout,_("Unknown(%i) "),i);break;
937 case 1: fprintf(stdout,_("MCU ROM checksum "));break;
938 case 2: fprintf(stdout,_("MCU RAM interface "));break;
939 case 3: fprintf(stdout,_("MCU RAM component "));break;
940 case 4: fprintf(stdout,_("MCU EEPROM interface "));break;
941 case 5: fprintf(stdout,_("MCU EEPROM component "));break;
942 case 6: fprintf(stdout,_("Real Time Clock battery "));break;
943 case 7: fprintf(stdout,_("CCONT interface "));break;
944 case 8: fprintf(stdout,_("AD converter "));break;
945 case 9: fprintf(stdout,_("SW Reset "));break;
946 case 10:fprintf(stdout,_("Power Off "));break;
947 case 11:fprintf(stdout,_("Security Data "));break;
948 case 12:fprintf(stdout,_("EEPROM Tune checksum "));break;
949 case 13:fprintf(stdout,_("PPM checksum "));break;
950 case 14:fprintf(stdout,_("MCU download DSP "));break;
951 case 15:fprintf(stdout,_("DSP alive "));break;
952 case 16:fprintf(stdout,_("COBBA serial "));break;
953 case 17:fprintf(stdout,_("COBBA paraller "));break;
954 case 18:fprintf(stdout,_("EEPROM security checksum"));break;
955 case 19:fprintf(stdout,_("PPM validity "));break;
956 case 20:fprintf(stdout,_("Warranty state "));break;
957 case 21:fprintf(stdout,_("Simlock check "));break;
958 case 22:fprintf(stdout,_("IMEI check? "));break;//from PC-Locals.is OK?
959 default:fprintf(stdout,_("Unknown(%i) "),i);break;
961 switch (MessageBuffer[4+i]) {
962 case 0: fprintf(stdout,_(" : done, result OK"));break;
963 case 0xff:fprintf(stdout,_(" : not done, result unknown"));break;
964 case 254: fprintf(stdout,_(" : done, result NOT OK"));break;
965 default: fprintf(stdout,_(" : result unknown(%i)"),MessageBuffer[4+i]);break;
967 fprintf(stdout,_("\n"));
971 void N6110_ReplySimlockInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
978 fprintf(stdout, _("Message: Simlock info received\n"));
981 for (i=0; i < 12; i++)
984 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] >> 4)));
987 if (j==5 || j==15) fprintf(stdout, _("\n"));
990 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] & 0x0f)));
994 if (j==20 || j==24) fprintf(stdout, _("\n"));
997 if ((MessageBuffer[6] & 1) == 1) fprintf(stdout,_("lock 1 closed\n"));
998 if ((MessageBuffer[6] & 2) == 2) fprintf(stdout,_("lock 2 closed\n"));
999 if ((MessageBuffer[6] & 4) == 4) fprintf(stdout,_("lock 3 closed\n"));
1000 if ((MessageBuffer[6] & 8) == 8) fprintf(stdout,_("lock 4 closed\n"));
1002 /* I'm not sure here at all */
1003 if ((MessageBuffer[5] & 1) == 1) fprintf(stdout,_("lock 1 - user\n"));
1004 if ((MessageBuffer[5] & 2) == 2) fprintf(stdout,_("lock 2 - user\n"));
1005 if ((MessageBuffer[5] & 4) == 4) fprintf(stdout,_("lock 3 - user\n"));
1006 if ((MessageBuffer[5] & 8) == 8) fprintf(stdout,_("lock 4 - user\n"));
1008 fprintf(stdout,_("counter for lock1: %i\n"),MessageBuffer[21]);
1009 fprintf(stdout,_("counter for lock2: %i\n"),MessageBuffer[22]);
1010 fprintf(stdout,_("counter for lock3: %i\n"),MessageBuffer[23]);
1011 fprintf(stdout,_("counter for lock4: %i\n"),MessageBuffer[24]);
1016 for (i=0; i < 12; i++)
1019 uni[j]='0' + (MessageBuffer[9+i] >> 4);
1024 uni[j]='0' + (MessageBuffer[9+i] & 0x0f);
1030 strncpy(CurrentSimLock->simlocks[0].data,uni,5);
1031 CurrentSimLock->simlocks[0].data[5]=0;
1032 strncpy(CurrentSimLock->simlocks[3].data,uni+5,10);
1033 CurrentSimLock->simlocks[3].data[10]=0;
1034 strncpy(CurrentSimLock->simlocks[1].data,uni+16,4);
1035 CurrentSimLock->simlocks[1].data[4]=0;
1036 strncpy(CurrentSimLock->simlocks[2].data,uni+20,4);
1037 CurrentSimLock->simlocks[2].data[4]=0;
1039 CurrentSimLock->simlocks[0].enabled=((MessageBuffer[6] & 1) == 1);
1040 CurrentSimLock->simlocks[1].enabled=((MessageBuffer[6] & 2) == 2);
1041 CurrentSimLock->simlocks[2].enabled=((MessageBuffer[6] & 4) == 4);
1042 CurrentSimLock->simlocks[3].enabled=((MessageBuffer[6] & 8) == 8);
1044 CurrentSimLock->simlocks[0].factory=((MessageBuffer[5] & 1) != 1);
1045 CurrentSimLock->simlocks[1].factory=((MessageBuffer[5] & 2) != 2);
1046 CurrentSimLock->simlocks[2].factory=((MessageBuffer[5] & 4) != 4);
1047 CurrentSimLock->simlocks[3].factory=((MessageBuffer[5] & 8) != 8);
1049 CurrentSimLock->simlocks[0].counter=MessageBuffer[21];
1050 CurrentSimLock->simlocks[1].counter=MessageBuffer[22];
1051 CurrentSimLock->simlocks[2].counter=MessageBuffer[23];
1052 CurrentSimLock->simlocks[3].counter=MessageBuffer[24];
1054 CurrentSimlockInfoError=GE_NONE;
1057 GSM_Error N6110_SimlockInfo(GSM_AllSimlocks *siml)
1060 unsigned char req[] = {0x00,0x01,0x8a,0x00};
1061 error=N6110_EnableExtendedCommands(0x01);
1062 if (error!=GE_NONE) return error;
1064 CurrentSimLock=siml;
1066 return NULL_SendMessageSequence (50, &CurrentSimlockInfoError, 4, 0x40, req);
1069 void N6110_ReplyResetPhoneSettings(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1072 fprintf(stdout, _("Message: Resetting phone settings\n"));
1075 CurrentResetPhoneSettingsError=GE_NONE;
1078 GSM_Error N6110_ResetPhoneSettings()
1081 unsigned char req[] = {0x00,0x01,0x65,0x08,0x00};
1082 error=N6110_EnableExtendedCommands(0x01);
1083 if (error!=GE_NONE) return error;
1085 return NULL_SendMessageSequence
1086 (50, &CurrentResetPhoneSettingsError, 5, 0x40, req);
1089 #endif /* UCLINUX */
1091 GSM_Error N6110_GetManufacturer(char *manufacturer)
1093 strcpy (manufacturer, "Nokia");
1099 GSM_Error N6110_GetVoiceMailbox ( GSM_PhonebookEntry *entry)
1101 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
1105 CurrentPhonebookEntry = entry;
1107 req[4] = N6110_MEMORY_VOICE;
1108 req[5] = 0x00; /* Location - isn't important, but... */
1110 error=NULL_SendMessageSequence
1111 (20, &CurrentPhonebookError, 7, 0x03, req);
1113 CurrentPhonebookEntry = NULL;
1118 void N6110_ReplyGetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1122 GSM_Bitmap NullBitmap;
1124 DecodeNetworkCode(MessageBuffer+5, NullBitmap.netcode);
1129 fprintf(stdout, _("Message: Info about downloaded operator name received: %s network (for gnokii \"%s\", for phone \""),
1131 GSM_GetNetworkName(NullBitmap.netcode));
1135 while (MessageBuffer[count]!=0) {
1137 fprintf(stdout,_("%c"),MessageBuffer[count]);
1142 strcpy(CurrentGetOperatorNameNetwork->Code, NullBitmap.netcode);
1143 strncpy(CurrentGetOperatorNameNetwork->Name, MessageBuffer+i,count-i+1);
1146 fprintf(stdout,_("\")\n"));
1149 CurrentGetOperatorNameError=GE_NONE;
1152 GSM_Error N6110_GetOperatorName (GSM_Network *operator)
1154 unsigned char req[] = { 0x00,0x01,0x8c,0x00};
1158 error=N6110_EnableExtendedCommands(0x01);
1159 if (error!=GE_NONE) return error;
1161 CurrentGetOperatorNameNetwork = operator;
1163 error=NULL_SendMessageSequence
1164 (20, &CurrentGetOperatorNameError, 4, 0x40, req);
1166 CurrentGetOperatorNameNetwork = NULL;
1171 void N6110_ReplySetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1174 fprintf(stdout, _("Message: Downloaded operator name changed\n"));
1177 CurrentSetOperatorNameError=GE_NONE;
1180 GSM_Error N6110_SetOperatorName (GSM_Network *operator)
1182 unsigned char req[256] = { 0x00,0x01,0x8b,0x00,
1183 0x00,0x00, /* MCC */
1188 error=N6110_EnableExtendedCommands(0x01);
1189 if (error!=GE_NONE) return error;
1191 EncodeNetworkCode(req+4,operator->Code);
1193 strncpy(req+7,operator->Name,200);
1195 return NULL_SendMessageSequence
1196 (20, &CurrentSetOperatorNameError, 8+strlen(operator->Name), 0x40, req);
1199 #endif /* UCLINUX */
1201 static void N6110_ReplyGetMemoryStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1203 switch (MessageBuffer[3]) {
1208 fprintf(stdout, _("Message: Memory status received:\n"));
1210 fprintf(stdout, _(" Memory Type: %s\n"), N6110_MemoryType_String[MessageBuffer[4]]);
1211 fprintf(stdout, _(" Used: %d\n"), MessageBuffer[6]);
1212 fprintf(stdout, _(" Free: %d\n"), MessageBuffer[5]);
1215 CurrentMemoryStatus->Used = MessageBuffer[6];
1216 CurrentMemoryStatus->Free = MessageBuffer[5];
1217 CurrentMemoryStatusError = GE_NONE;
1224 switch (MessageBuffer[4]) {
1226 fprintf(stdout, _("Message: Memory status error, phone is probably powered off.\n"));break;
1228 fprintf(stdout, _("Message: Memory status error, memory type not supported by phone model.\n"));break;
1230 fprintf(stdout, _("Message: Memory status error, waiting for security code.\n"));break;
1232 fprintf(stdout, _("Message: Unknown Memory status error, subtype (MessageBuffer[4]) = %02x\n"),MessageBuffer[4]);break;
1236 switch (MessageBuffer[4]) {
1237 case 0x6f:CurrentMemoryStatusError = GE_TIMEOUT;break;
1238 case 0x7d:CurrentMemoryStatusError = GE_INTERNALERROR;break;
1239 case 0x8d:CurrentMemoryStatusError = GE_INVALIDSECURITYCODE;break;
1248 /* This function is used to get storage status from the phone. It currently
1249 supports two different memory areas - internal and SIM. */
1250 GSM_Error N6110_GetMemoryStatus(GSM_MemoryStatus *Status)
1252 unsigned char req[] = { N6110_FRAME_HEADER,
1253 0x07, /* MemoryStatus request */
1254 0x00 /* MemoryType */
1259 CurrentMemoryStatus = Status;
1261 req[4] = N6110_GetMemoryType(Status->MemoryType);
1263 error=NULL_SendMessageSequence
1264 (20, &CurrentMemoryStatusError, 5, 0x03, req);
1266 CurrentMemoryStatus = NULL;
1273 void N6110_ReplyGetNetworkInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1275 GSM_NetworkInfo NullNetworkInfo;
1277 /* Make sure we are expecting NetworkInfo frame */
1278 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY) {
1280 fprintf(stdout, _("Message: Network informations:\n"));
1284 fprintf(stdout, _("Message: Network informations not requested, but received:\n"));
1288 sprintf(NullNetworkInfo.NetworkCode, "%x%x%x %x%x", MessageBuffer[14] & 0x0f, MessageBuffer[14] >>4, MessageBuffer[15] & 0x0f, MessageBuffer[16] & 0x0f, MessageBuffer[16] >>4);
1290 sprintf(NullNetworkInfo.CellID, "%02x%02x", MessageBuffer[10], MessageBuffer[11]);
1292 sprintf(NullNetworkInfo.LAC, "%02x%02x", MessageBuffer[12], MessageBuffer[13]);
1295 fprintf(stdout, _(" CellID: %s\n"), NullNetworkInfo.CellID);
1296 fprintf(stdout, _(" LAC: %s\n"), NullNetworkInfo.LAC);
1297 fprintf(stdout, _(" Network code: %s\n"), NullNetworkInfo.NetworkCode);
1298 fprintf(stdout, _(" Network name: %s (%s)\n"),
1299 GSM_GetNetworkName(NullNetworkInfo.NetworkCode),
1300 GSM_GetCountryName(NullNetworkInfo.NetworkCode));
1301 fprintf(stdout, _(" Status: "));
1303 switch (MessageBuffer[8]) {
1304 case 0x01: fprintf(stdout, _("home network selected")); break;
1305 case 0x02: fprintf(stdout, _("roaming network")); break;
1306 case 0x03: fprintf(stdout, _("requesting network")); break;
1307 case 0x04: fprintf(stdout, _("not registered in the network")); break;
1308 default: fprintf(stdout, _("unknown"));
1311 fprintf(stdout, "\n");
1313 fprintf(stdout, _(" Network selection: %s\n"), MessageBuffer[9]==1?_("manual"):_("automatic"));
1316 /* Make sure we are expecting NetworkInfo frame */
1317 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY)
1318 *CurrentNetworkInfo=NullNetworkInfo;
1320 CurrentNetworkInfoError = GE_NONE;
1323 GSM_Error N6110_GetNetworkInfo(GSM_NetworkInfo *NetworkInfo)
1325 unsigned char req[] = { N6110_FRAME_HEADER,
1331 CurrentNetworkInfo = NetworkInfo;
1333 error=NULL_SendMessageSequence
1334 (20, &CurrentNetworkInfoError, 4, 0x0a, req);
1336 CurrentNetworkInfo = NULL;
1341 void N6110_ReplyGetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1346 fprintf(stdout, _("Message: Product Profile Settings received -"));
1347 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),MessageBuffer[3+i]);
1348 fprintf(stdout, _("\n"));
1351 for (i=0;i<4;i++) CurrentPPS[i]=MessageBuffer[3+i];
1353 CurrentProductProfileSettingsError=GE_NONE;
1356 GSM_Error N6110_GetProductProfileSetting (GSM_PPS *PPS)
1358 unsigned char req[] = { 0x00, 0x01,0x6a };
1364 error=N6110_EnableExtendedCommands(0x01);
1365 if (error!=GE_NONE) return error;
1367 error=NULL_SendMessageSequence
1368 (20, &CurrentProductProfileSettingsError, 3, 0x40, req);
1369 if (error!=GE_NONE) return error;
1371 switch (PPS->Name) {
1372 case PPS_ALS : PPS->bool_value=(CurrentPPS[1]&32); break;
1373 case PPS_GamesMenu: PPS->bool_value=(CurrentPPS[3]&64); break;
1374 case PPS_HRData : PPS->bool_value=(CurrentPPS[0]&64); break;
1375 case PPS_14400Data: PPS->bool_value=(CurrentPPS[0]&128);break;
1376 case PPS_EFR : PPS->int_value =(CurrentPPS[0]&1) +(CurrentPPS[0]&2); break;
1377 case PPS_FR : PPS->int_value =(CurrentPPS[0]&16)/16+(CurrentPPS[0]&32)/16;break;
1378 case PPS_HR : PPS->int_value =(CurrentPPS[0]&4)/4 +(CurrentPPS[0]&8)/4; break;
1379 case PPS_VibraMenu: PPS->bool_value=(CurrentPPS[4]&64); break;
1380 case PPS_LCDContrast:
1384 if (CurrentPPS[3]&j) PPS->int_value=PPS->int_value+j;
1387 PPS->int_value=PPS->int_value*100/32;
1395 void N6110_ReplySetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1400 fprintf(stdout, _("Message: Product Profile Settings set to"));
1401 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),CurrentPPS[i]);
1402 fprintf(stdout, _("\n"));
1405 CurrentProductProfileSettingsError=GE_NONE;
1408 GSM_Error N6110_SetProductProfileSetting (GSM_PPS *PPS)
1410 unsigned char req[] = { 0x00, 0x01,0x6b,
1411 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */
1412 unsigned char settings[32];
1420 error=N6110_EnableExtendedCommands(0x01);
1421 if (error!=GE_NONE) return error;
1423 OldPPS.Name=PPS_ALS;
1424 error=N6110_GetProductProfileSetting(&OldPPS);
1425 if (error!=GE_NONE) return error;
1428 for (i=0;i<32;i++) {
1429 if (CurrentPPS[z]&j)
1440 fprintf(stdout,_("Current settings: "));
1441 for (i=0;i<32;i++) {
1442 fprintf(stdout,_("%c"),settings[i]);
1444 fprintf(stdout,_("\n"));
1447 switch (PPS->Name) {
1448 case PPS_ALS :settings[10]=PPS->bool_value?'1':'0';break;
1449 case PPS_HRData :settings[ 5]=PPS->bool_value?'1':'0';break;
1450 case PPS_14400Data:settings[ 6]=PPS->bool_value?'1':'0';break;
1455 for (i=0;i<32;i++) {
1456 if (settings[i]=='1') req[z+3]=req[z+3]+j;
1464 fprintf(stdout,_("Current settings: "));
1466 fprintf(stdout,_("%i "),req[i+3]);
1468 fprintf(stdout,_("\n"));
1472 CurrentPPS[i]=req[i+3];
1475 return NULL_SendMessageSequence
1476 (20, &CurrentProductProfileSettingsError, 7, 0x40, req);
1479 void N6110_ReplyPressKey(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1481 if (MessageBuffer[4]==CurrentPressKeyEvent) CurrentPressKeyError=GE_NONE;
1482 else CurrentPressKeyError=GE_UNKNOWN; /* MessageBuffer[4] = 0x05 */
1484 fprintf(stdout, _("Message: Result of key "));
1485 switch (MessageBuffer[4])
1487 case PRESSPHONEKEY: fprintf(stdout, _("press OK\n"));break;
1488 case RELEASEPHONEKEY: fprintf(stdout, _("release OK\n"));break;
1489 default: fprintf(stdout, _("press or release - error\n"));break;
1494 GSM_Error N6110_PressKey(int key, int event)
1496 unsigned char req[] = {N6110_FRAME_HEADER, 0x42, 0x01, 0x00, 0x01};
1498 req[4]=event; /* if we press or release key */
1501 CurrentPressKeyEvent=event;
1503 return NULL_SendMessageSequence
1504 (10, &CurrentPressKeyError, 7, 0x0c, req);
1507 void N6110_ReplyDisplayOutput(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1509 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
1516 switch(MessageBuffer[3]) {
1518 /* Phone sends displayed texts */
1520 NewX=MessageBuffer[6];
1521 NewY=MessageBuffer[5];
1523 DecodeUnicode (uni, MessageBuffer+8, MessageBuffer[7]);
1526 fprintf(stdout, _("New displayed text (%i %i): \"%s\"\n"),NewX,NewY,uni);
1529 while (N6110_GetModel(model) != GE_NONE)
1532 /* With these rules it works almost excellent with my N5110 */
1533 /* I don't have general rule :-(, that's why you must experiment */
1534 /* with your phone. Nokia could make it better. MW */
1535 /* It's almost OK for N5110*/
1536 /* FIX ME: it will be the same for N5130 and 3210 too*/
1537 if (!strcmp(model,"NSE-1"))
1539 /* OldX==1000 means - it's first time */
1543 for (i=0;i<5+1;i++) {
1544 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1549 if ((OldX==0 && OldY==31 && NewX==29 && NewY==46) ||
1550 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1551 /* Clean the line with current text */
1552 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1554 /* Inserts text into table */
1555 for (i=0; i<MessageBuffer[7];i++) {
1556 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1561 if ((OldX==0 && OldY==21 && NewX==0 && NewY==10) ||
1562 (OldX==0 && OldY==10 && NewX==35 && NewY==46)) {
1564 if ((OldX!=0 && NewX==0 && NewY!=6) ||
1565 (OldX==0 && NewX!=0 && OldY!=13 && OldY!=22) ||
1566 (OldX==0 && NewX==0 && NewY<OldY && (NewY!=13 || OldY!=26)) ||
1567 (OldY==5 && NewY!=5) ||
1568 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1570 /* Writes "old" screen */
1571 for (i=0;i<5+1;i++) {
1572 for (j=0;j<27+1;j++) {fprintf(stdout,_("%c"),PhoneScreen[i][j]);}
1573 fprintf(stdout,_("\n"));
1577 for (i=0;i<5+1;i++) {
1578 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1583 /* Clean the line with current text */
1584 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1586 /* Inserts text into table */
1587 for (i=0; i<MessageBuffer[7];i++) {
1588 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1595 fprintf(stdout, _("%s\n"),uni);
1603 if (MessageBuffer[4]==1)
1607 fprintf(stdout, _("Display output successfully disabled/enabled.\n"));
1610 CurrentDisplayOutputError=GE_NONE;
1617 GSM_Error SetDisplayOutput(unsigned char state)
1619 unsigned char req[] = { N6110_FRAME_HEADER,
1624 return NULL_SendMessageSequence
1625 (30, &CurrentDisplayOutputError, 5, 0x0d, req);
1628 GSM_Error N6110_EnableDisplayOutput()
1630 return SetDisplayOutput(0x01);
1633 GSM_Error N6110_DisableDisplayOutput()
1635 return SetDisplayOutput(0x02);
1638 /* If it is interesting for somebody: we can use 0x40 msg for it
1639 and it will work for all phones. See n6110.txt for details */
1640 GSM_Error N6110_AnswerCall(char s)
1642 unsigned char req0[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,0x07, 0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
1643 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80};
1644 unsigned char req[] = { N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
1649 fprintf(stdout,_("Answering call %d\n\r"),s);
1652 Protocol->SendMessage(sizeof(req0), 0x01, req0);
1655 return NULL_SendMessageSequence
1656 (20, &CurrentMagicError, sizeof(req) , 0x01, req);
1659 void N6110_ReplyGetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1661 switch (MessageBuffer[3]) {
1663 /* Profile feature */
1666 switch(GetModelFeature (FN_PROFILES)) {
1668 switch (MessageBuffer[6]) {
1669 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8]; break;
1670 case 0x01: CurrentProfile->CallAlert = MessageBuffer[8]; break;
1671 case 0x02: CurrentProfile->Ringtone = MessageBuffer[8]; break;
1672 case 0x03: CurrentProfile->Volume = MessageBuffer[8]; break;
1673 case 0x04: CurrentProfile->MessageTone = MessageBuffer[8]; break;
1674 case 0x05: CurrentProfile->Vibration = MessageBuffer[8]; break;
1675 case 0x06: CurrentProfile->WarningTone = MessageBuffer[8]; break;
1676 case 0x07: CurrentProfile->ScreenSaver = MessageBuffer[8]; break;
1679 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1685 switch (MessageBuffer[6]) {
1686 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8];break;
1687 case 0x01: CurrentProfile->Lights = MessageBuffer[8];break;
1688 case 0x02: CurrentProfile->CallAlert = MessageBuffer[8];break;
1689 case 0x03: CurrentProfile->Ringtone = MessageBuffer[8];break;
1690 case 0x04: CurrentProfile->Volume = MessageBuffer[8];break;
1691 case 0x05: CurrentProfile->MessageTone = MessageBuffer[8];break;
1692 case 0x06: CurrentProfile->Vibration = MessageBuffer[8];break;
1693 case 0x07: CurrentProfile->WarningTone = MessageBuffer[8];break;
1694 case 0x08: CurrentProfile->CallerGroups = MessageBuffer[8];break;
1695 case 0x09: CurrentProfile->AutomaticAnswer = MessageBuffer[8];break;
1698 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1705 CurrentProfileError = GE_NONE;
1708 /* Incoming profile name */
1711 if (MessageBuffer[9] == 0x00) {
1712 CurrentProfile->DefaultName=MessageBuffer[8];
1714 CurrentProfile->DefaultName=-1;
1716 /* Here name is in Unicode */
1717 if (GetModelFeature (FN_PROFILES)==F_PROF33) {
1718 DecodeUnicode (CurrentProfile->Name, MessageBuffer+10, MessageBuffer[9]/2);
1721 sprintf(CurrentProfile->Name, MessageBuffer + 10, MessageBuffer[9]);
1722 CurrentProfile->Name[MessageBuffer[9]] = '\0';
1726 CurrentProfileError = GE_NONE;
1732 /* Needs SIM card with PIN in phone */
1733 GSM_Error N6110_GetProfile(GSM_Profile *Profile)
1737 unsigned char name_req[] = { N6110_FRAME_HEADER, 0x1a, 0x00};
1738 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x13, 0x01, 0x00, 0x00};
1742 CurrentProfile = Profile;
1744 /* When after sending all frames feature==253, it means, that it is not
1746 CurrentProfile->KeypadTone=253;
1747 CurrentProfile->Lights=253;
1748 CurrentProfile->CallAlert=253;
1749 CurrentProfile->Ringtone=253;
1750 CurrentProfile->Volume=253;
1751 CurrentProfile->MessageTone=253;
1752 CurrentProfile->WarningTone=253;
1753 CurrentProfile->Vibration=253;
1754 CurrentProfile->CallerGroups=253;
1755 CurrentProfile->ScreenSaver=253;
1756 CurrentProfile->AutomaticAnswer=253;
1758 name_req[4] = Profile->Number;
1760 error=NULL_SendMessageSequence
1761 (20, &CurrentProfileError, 5, 0x05, name_req);
1762 if (error!=GE_NONE) return error;
1764 for (i = 0x00; i <= 0x09; i++) {
1766 feat_req[5] = Profile->Number;
1770 error=NULL_SendMessageSequence
1771 (20, &CurrentProfileError, 7, 0x05, feat_req);
1772 if (error!=GE_NONE) return error;
1775 if (Profile->DefaultName > -1)
1777 switch(GetModelFeature (FN_PROFILES)) {
1779 switch (Profile->DefaultName) {
1780 case 0x00: sprintf(Profile->Name, "General");break;
1781 case 0x01: sprintf(Profile->Name, "Silent");break;
1782 case 0x02: sprintf(Profile->Name, "Descreet");break;
1783 case 0x03: sprintf(Profile->Name, "Loud");break;
1784 case 0x04: sprintf(Profile->Name, "My style");break;
1785 case 0x05: Profile->Name[0]=0;break;
1786 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1790 switch (Profile->DefaultName) {
1791 case 0x00: sprintf(Profile->Name, "Personal");break;
1792 case 0x01: sprintf(Profile->Name, "Car");break;
1793 case 0x02: sprintf(Profile->Name, "Headset");break;
1794 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1798 switch (Profile->DefaultName) {
1799 case 0x00: sprintf(Profile->Name, "General");break;
1800 case 0x01: sprintf(Profile->Name, "Silent");break;
1801 case 0x02: sprintf(Profile->Name, "Meeting");break;
1802 case 0x03: sprintf(Profile->Name, "Outdoor");break;
1803 case 0x04: sprintf(Profile->Name, "Pager");break;
1804 case 0x05: sprintf(Profile->Name, "Car");break;
1805 case 0x06: sprintf(Profile->Name, "Headset");break;
1806 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1816 void N6110_ReplySetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1818 switch (MessageBuffer[3]) {
1820 /* Profile feature change result */
1823 fprintf(stdout, _("Message: Profile feature change result.\n"));
1825 CurrentProfileError = GE_NONE;
1828 /* Profile name set result */
1831 fprintf(stdout, _("Message: Profile name change result.\n"));
1833 CurrentProfileError = GE_NONE;
1839 GSM_Error N6110_SetProfileFeature(u8 profile, u8 feature, u8 value)
1841 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x10, 0x01,
1844 feat_req[5]=profile;
1845 feat_req[6]=feature;
1848 return NULL_SendMessageSequence
1849 (20, &CurrentProfileError, 8, 0x05, feat_req);
1852 GSM_Error N6110_SetProfile(GSM_Profile *Profile)
1856 unsigned char name_req[40] = { N6110_FRAME_HEADER, 0x1c, 0x01, 0x03,
1861 name_req[7] = Profile->Number;
1862 name_req[8] = strlen(Profile->Name);
1863 name_req[6] = name_req[8] + 2;
1865 for (i = 0; i < name_req[8]; i++)
1866 name_req[9 + i] = Profile->Name[i];
1868 error=NULL_SendMessageSequence
1869 (20, &CurrentProfileError, name_req[8] + 9, 0x05, name_req);
1870 if (error!=GE_NONE) return error;
1872 for (i = 0x00; i <= 0x09; i++) {
1875 case 0x00: value = Profile->KeypadTone; break;
1876 case 0x01: value = Profile->Lights; break;
1877 case 0x02: value = Profile->CallAlert; break;
1878 case 0x03: value = Profile->Ringtone; break;
1879 case 0x04: value = Profile->Volume; break;
1880 case 0x05: value = Profile->MessageTone; break;
1881 case 0x06: value = Profile->Vibration; break;
1882 case 0x07: value = Profile->WarningTone; break;
1883 case 0x08: value = Profile->CallerGroups; break;
1884 case 0x09: value = Profile->AutomaticAnswer; break;
1885 default : value = 0; break;
1888 error=N6110_SetProfileFeature(Profile->Number,i,value);
1889 if (error!=GE_NONE) return error;
1895 #endif /* UCLINUX */
1897 bool N6110_SendRLPFrame(RLP_F96Frame *frame, bool out_dtx)
1899 u8 req[60] = { 0x00, 0xd9 };
1901 /* Discontinuos transmission (DTX). See section 5.6 of GSM 04.22 version
1907 memcpy(req+2, (u8 *) frame, 32);
1909 return (Protocol->SendFrame(32, 0xf0, req));
1914 void N6110_ReplyGetCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1922 switch (MessageBuffer[4]) {
1926 CurrentCalendarNote->Type=MessageBuffer[8];
1928 DecodeDateTime(MessageBuffer+9, &CurrentCalendarNote->Time);
1930 DecodeDateTime(MessageBuffer+16, &CurrentCalendarNote->Alarm);
1932 CurrentCalendarNote->Text[0]=0;
1934 if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
1936 if (CurrentCalendarNote->Type == GCN_REMINDER) i=1; //first char is subset
1937 switch (MessageBuffer[24]) {
1940 fprintf(stdout,_("Subset 3 in reminder note !\n"));
1942 while (i!=MessageBuffer[23]) {
1944 if (i!=MessageBuffer[23]-1) {
1945 if (MessageBuffer[24+i]>=0xc2) {
1946 DecodeWithUTF8Alphabet(MessageBuffer[24+i], MessageBuffer[24+i+1], &mychar1);
1947 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1948 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=mychar1;
1954 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1955 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=MessageBuffer[24+i];
1962 fprintf(stdout,_("Subset 2 in reminder note !\n"));
1964 while (i!=MessageBuffer[23]) {
1965 wc = MessageBuffer[24+i] | (0x00 << 8);
1966 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1967 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=
1968 DecodeWithUnicodeAlphabet(wc);
1974 fprintf(stdout,_("Subset 1 in reminder note !\n"));
1976 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1977 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1981 fprintf(stdout,_("Unknown subset in reminder note !\n"));
1983 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1984 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1988 memcpy(CurrentCalendarNote->Text,MessageBuffer+24,MessageBuffer[23]);
1989 CurrentCalendarNote->Text[MessageBuffer[23]]=0;
1992 if (CurrentCalendarNote->Type == GCN_CALL) {
1993 memcpy(CurrentCalendarNote->Phone,MessageBuffer+24+MessageBuffer[23]+1,MessageBuffer[24+MessageBuffer[23]]);
1994 CurrentCalendarNote->Phone[MessageBuffer[24+MessageBuffer[23]]]=0;
1997 CurrentCalendarNote->Recurrance=0;
1999 CurrentCalendarNote->AlarmType=0;
2002 fprintf(stdout, _("Message: Calendar note received.\n"));
2004 fprintf(stdout, _(" Date: %d-%02d-%02d\n"), CurrentCalendarNote->Time.Year,
2005 CurrentCalendarNote->Time.Month,
2006 CurrentCalendarNote->Time.Day);
2008 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentCalendarNote->Time.Hour,
2009 CurrentCalendarNote->Time.Minute,
2010 CurrentCalendarNote->Time.Second);
2012 /* Some messages do not have alarm set up */
2013 if (CurrentCalendarNote->Alarm.Year != 0) {
2014 fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"), CurrentCalendarNote->Alarm.Year,
2015 CurrentCalendarNote->Alarm.Month,
2016 CurrentCalendarNote->Alarm.Day);
2018 fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"), CurrentCalendarNote->Alarm.Hour,
2019 CurrentCalendarNote->Alarm.Minute,
2020 CurrentCalendarNote->Alarm.Second);
2023 fprintf(stdout, _(" Type: %d\n"), CurrentCalendarNote->Type);
2024 fprintf(stdout, _(" Text: %s\n"), CurrentCalendarNote->Text);
2026 if (CurrentCalendarNote->Type == GCN_CALL)
2027 fprintf(stdout, _(" Phone: %s\n"), CurrentCalendarNote->Phone);
2030 CurrentCalendarNoteError=GE_NONE;
2036 fprintf(stdout, _("Message: Calendar note not available\n"));
2039 CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;
2045 fprintf(stdout, _("Message: Calendar note error\n"));
2048 CurrentCalendarNoteError=GE_INTERNALERROR;
2054 GSM_Error N6110_GetCalendarNote(GSM_CalendarNote *CalendarNote)
2057 unsigned char req[] = { N6110_FRAME_HEADER,
2062 req[4]=CalendarNote->Location;
2064 CurrentCalendarNote = CalendarNote;
2066 error=NULL_SendMessageSequence
2067 (20, &CurrentCalendarNoteError, 5, 0x13, req);
2069 CurrentCalendarNote = NULL;
2074 void N6110_ReplyWriteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2077 switch(MessageBuffer[4]) {
2078 /* This message is also sent when the user enters the new entry on keypad */
2080 fprintf(stdout, _("Message: Calendar note write succesfull!\n"));break;
2082 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2084 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2086 fprintf(stdout, _("Unknown message of type 0x13 and subtype 0x65\n"));break;
2090 switch(MessageBuffer[4]) {
2091 case 0x01: CurrentCalendarNoteError=GE_NONE; break;
2092 case 0x73: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2093 case 0x7d: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2094 default : AppendLogText("Unknown msg\n",false); break;
2098 GSM_Error N6110_WriteCalendarNote(GSM_CalendarNote *CalendarNote)
2101 unsigned char req[200] = { N6110_FRAME_HEADER,
2103 0x00, /* Length of the rest of the frame. */
2104 0x00, /* The type of calendar note */
2105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2112 unsigned char meeting;
2113 unsigned char birthday;
2114 unsigned char reminder;
2115 } calendar_model_length;
2117 /* Length of entries */
2118 calendar_model_length calendar_lengths[] =
2120 /*model,CallTo,Meeting,Birthday,Reminder*/
2121 {"NHM-5",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2122 {"NHM-6",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2123 {"NSE-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 [HKEY_LOCAL_MACHINE\Software\Nokia\Data Suite\3.0\Calendar]
2124 {"NSM-1",0x1e,0x18,0x18,0x24}, //from NCDS3
2125 {"NSK-3",0x1e,0x14,0x14,0x1e}, //from NCDS3
2126 {"NSB-3",0x20,0x14,0x14,0x1e}, //from NCDS3
2127 {"", 0, 0, 0, 0 } //end of table
2138 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
2141 req[7]=CalendarNote->Type;
2143 EncodeDateTime(req+8, &CalendarNote->Time);
2144 req[14] = CalendarNote->Time.Timezone;
2146 if (CalendarNote->Alarm.Year) {
2147 EncodeDateTime(req+15, &CalendarNote->Alarm);
2148 req[21] = CalendarNote->Alarm.Timezone;
2151 req[22]=strlen(CalendarNote->Text);
2155 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2156 req[22]++; // one additional char
2157 req[current++]=0x01; //we use now subset 1
2160 for (i=0; i<strlen(CalendarNote->Text); i++) {
2162 mychar=CalendarNote->Text[i];
2163 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2164 if (EncodeWithUTF8Alphabet(mychar,&mychar1,&mychar2)) {
2165 req[current++]=mychar1;
2166 req[current++]=mychar2;
2167 req[23]=0x03; //use subset 3
2168 req[22]++; // one additional char
2173 /* Enables/disables blinking */
2174 if (mychar=='~') req[current++]=0x01;
2175 else req[current++]=mychar;
2179 req[current++]=strlen(CalendarNote->Phone);
2181 for (i=0; i<strlen(CalendarNote->Phone); i++)
2182 req[current++]=CalendarNote->Phone[i];
2184 while (N6110_GetModel(model) != GE_NONE)
2187 /* Checking maximal length */
2189 while (strcmp(calendar_lengths[i].model,"")) {
2190 if (!strcmp(calendar_lengths[i].model,model)) {
2191 switch (CalendarNote->Type) {
2192 case GCN_REMINDER:if (req[22]>calendar_lengths[i].reminder) return GE_TOOLONG;break;
2193 case GCN_MEETING :if (req[22]>calendar_lengths[i].meeting) return GE_TOOLONG;break;
2194 case GCN_BIRTHDAY:if (req[22]>calendar_lengths[i].birthday) return GE_TOOLONG;break;
2195 case GCN_CALL :if (strlen(CalendarNote->Phone)>calendar_lengths[i].call) return GE_TOOLONG;break;
2202 CurrentCalendarNote = CalendarNote;
2204 error=NULL_SendMessageSequence
2205 (20, &CurrentCalendarNoteError, current, 0x13, req);
2207 CurrentCalendarNote = NULL;
2212 void N6110_ReplyDeleteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2215 switch (MessageBuffer[4]) {
2216 /* This message is also sent when the user deletes an old entry on
2217 keypad or moves an old entry somewhere (there is also `write'
2219 case 0x01:fprintf(stdout, _("Message: Calendar note deleted\n"));break;
2220 case 0x93:fprintf(stdout, _("Message: Calendar note can't be deleted\n"));break;
2221 default :fprintf(stdout, _("Message: Calendar note deleting error\n"));break;
2225 switch (MessageBuffer[4]) {
2226 case 0x01:CurrentCalendarNoteError=GE_NONE;break;
2227 case 0x93:CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;break;
2228 default :CurrentCalendarNoteError=GE_INTERNALERROR;break;
2232 GSM_Error N6110_DeleteCalendarNote(GSM_CalendarNote *CalendarNote)
2235 unsigned char req[] = { N6110_FRAME_HEADER,
2239 req[4]=CalendarNote->Location;
2241 return NULL_SendMessageSequence (20, &CurrentCalendarNoteError, 5, 0x13, req);
2244 #endif /* UCLINUX */
2246 static void N6110_ReplyRFBatteryLevel(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2249 fprintf(stdout, _("Message: Phone status received:\n"));
2250 fprintf(stdout, _(" Mode: "));
2252 switch (MessageBuffer[4]) {
2256 fprintf(stdout, _("registered within the network\n"));
2259 /* I was really amazing why is there a hole in the type of 0x02, now I
2261 case 0x02: fprintf(stdout, _("call in progress\n")); break; /* ringing or already answered call */
2262 case 0x03: fprintf(stdout, _("waiting for security code\n")); break;
2263 case 0x04: fprintf(stdout, _("powered off\n")); break;
2264 default : fprintf(stdout, _("unknown\n"));
2268 fprintf(stdout, _(" Power source: "));
2270 switch (MessageBuffer[7]) {
2272 case 0x01: fprintf(stdout, _("AC/DC\n")); break;
2273 case 0x02: fprintf(stdout, _("battery\n")); break;
2274 default : fprintf(stdout, _("unknown\n"));
2278 fprintf(stdout, _(" Battery Level: %d\n"), MessageBuffer[8]);
2279 fprintf(stdout, _(" Signal strength: %d\n"), MessageBuffer[5]);
2282 CurrentRFLevel=MessageBuffer[5];
2283 CurrentBatteryLevel=MessageBuffer[8];
2284 CurrentPowerSource=MessageBuffer[7];
2288 GSM_Error N6110_GetRFLevel(GSM_RFUnits *units, float *level)
2291 /* FIXME - these values are from 3810 code, may be incorrect. Map from
2292 values returned in status packet to the the values returned by the AT+CSQ
2294 float csq_map[5] = {0, 8, 16, 24, 31};
2299 char screen[NM_MAX_SCREEN_WIDTH];
2303 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2306 if (N6110_NetMonitor(1, screen)!=GE_NONE)
2307 return GE_INTERNALERROR;
2308 #endif /* UCLINUX */
2312 if (screen[4]!='-') {
2313 if (screen[5]=='9' && screen[6]>'4') rf_level=1;
2314 if (screen[5]=='9' && screen[6]<'5') rf_level=2;
2315 if (screen[5]=='8' && screen[6]>'4') rf_level=3;
2318 /* Arbitrary units. */
2319 if (*units == GRF_Arbitrary) {
2325 N6110_SendStatusRequest();
2327 /* Wait for timeout or other error. */
2328 while (timeout != 0 && CurrentRFLevel == -1 ) {
2331 return (GE_TIMEOUT);
2336 /* Make copy in case it changes. */
2337 rf_level = CurrentRFLevel;
2342 /* Now convert between the different units we support. */
2344 /* Arbitrary units. */
2345 if (*units == GRF_Arbitrary) {
2351 if (*units == GRF_CSQ) {
2354 *level = csq_map[rf_level];
2356 *level = 99; /* Unknown/undefined */
2362 /* Unit type is one we don't handle so return error */
2363 return (GE_INTERNALERROR);
2367 GSM_Error N6110_GetBatteryLevel(GSM_BatteryUnits *units, float *level)
2372 char screen[NM_MAX_SCREEN_WIDTH];
2374 CurrentBatteryLevel=-1;
2376 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2379 if (N6110_NetMonitor(23, screen)!=GE_NONE)
2381 #endif /* UCLINUX */
2385 if (screen[29]=='7') batt_level=3;
2386 if (screen[29]=='5') batt_level=2;
2387 if (screen[29]=='2') batt_level=1;
2389 /* Only units we handle at present are GBU_Arbitrary */
2390 if (*units == GBU_Arbitrary) {
2391 *level = batt_level;
2395 return (GE_INTERNALERROR);
2398 N6110_SendStatusRequest();
2400 /* Wait for timeout or other error. */
2401 while (timeout != 0 && CurrentBatteryLevel == -1 ) {
2404 return (GE_TIMEOUT);
2409 /* Take copy in case it changes. */
2410 batt_level = CurrentBatteryLevel;
2412 if (batt_level != -1) {
2414 /* Only units we handle at present are GBU_Arbitrary */
2415 if (*units == GBU_Arbitrary) {
2416 *level = batt_level;
2420 return (GE_INTERNALERROR);
2427 GSM_Error N6110_GetPowerSource(GSM_PowerSource *source)
2432 char screen[NM_MAX_SCREEN_WIDTH];
2434 CurrentPowerSource=-1;
2436 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2439 if (N6110_NetMonitor(20, screen)!=GE_NONE)
2441 #endif /* UCLINUX */
2443 CurrentPowerSource=GPS_ACDC;
2445 if (screen[6]=='x') CurrentPowerSource=GPS_BATTERY;
2447 *source=CurrentPowerSource;
2451 N6110_SendStatusRequest();
2453 /* Wait for timeout or other error. */
2454 while (timeout != 0 && CurrentPowerSource == -1 ) {
2457 return (GE_TIMEOUT);
2462 if (CurrentPowerSource != -1) {
2463 *source=CurrentPowerSource;
2473 static void N6110_ReplyGetDisplayStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2477 for (i=0; i<MessageBuffer[4];i++)
2478 if (MessageBuffer[2*i+6]==2)
2479 CurrentDisplayStatus|=1<<(MessageBuffer[2*i+5]-1);
2481 CurrentDisplayStatus&= (0xff - (1<<(MessageBuffer[2*i+5]-1)));
2484 fprintf(stdout, _("Call in progress: %s\n"), CurrentDisplayStatus & (1<<DS_Call_In_Progress)?"on":"off");
2485 fprintf(stdout, _("Unknown: %s\n"), CurrentDisplayStatus & (1<<DS_Unknown)?"on":"off");
2486 fprintf(stdout, _("Unread SMS: %s\n"), CurrentDisplayStatus & (1<<DS_Unread_SMS)?"on":"off");
2487 fprintf(stdout, _("Voice call: %s\n"), CurrentDisplayStatus & (1<<DS_Voice_Call)?"on":"off");
2488 fprintf(stdout, _("Fax call active: %s\n"), CurrentDisplayStatus & (1<<DS_Fax_Call)?"on":"off");
2489 fprintf(stdout, _("Data call active: %s\n"), CurrentDisplayStatus & (1<<DS_Data_Call)?"on":"off");
2490 fprintf(stdout, _("Keyboard lock: %s\n"), CurrentDisplayStatus & (1<<DS_Keyboard_Lock)?"on":"off");
2491 fprintf(stdout, _("SMS storage full: %s\n"), CurrentDisplayStatus & (1<<DS_SMS_Storage_Full)?"on":"off");
2494 CurrentDisplayStatusError=GE_NONE;
2497 GSM_Error N6110_GetDisplayStatus(int *Status) {
2499 unsigned char req[4]={ N6110_FRAME_HEADER, 0x51 };
2503 error=NULL_SendMessageSequence
2504 (10, &CurrentDisplayStatusError, 4, 0x0d, req);
2505 if (error!=GE_NONE) return error;
2507 *Status=CurrentDisplayStatus;
2512 GSM_Error N6110_DialVoice(char *Number) {
2513 /* This commented sequence doesn't work on N3210/3310/6210/7110 */
2514 // unsigned char req[64]={N6110_FRAME_HEADER, 0x01};
2515 // unsigned char req_end[]={0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};
2517 // req[4]=strlen(Number);
2518 // for(i=0; i < strlen(Number) ; i++)
2519 // req[5+i]=Number[i];
2520 // memcpy(req+5+strlen(Number), req_end, 10);
2521 // return NULL_SendMessageSequence
2522 // (20, &CurrentDialVoiceError, 13+strlen(Number), 0x01, req);
2524 unsigned char req[64]={0x00,0x01,0x7c,
2525 0x01}; //call command
2531 error=N6110_EnableExtendedCommands(0x01);
2532 if (error!=GE_NONE) return error;
2534 for(i=0; i < strlen(Number) ; i++) req[4+i]=Number[i];
2538 return NULL_SendMessageSequence
2539 (20, &CurrentDialVoiceError, 4+strlen(Number)+1, 0x40, req);
2542 #endif /* UCLINUX */
2544 /* Dial a data call - type specifies request to use:
2545 type 0 should normally be used
2546 type 1 should be used when calling a digital line - corresponds to ats35=0
2547 Maybe one day we'll know what they mean!
2549 GSM_Error N6110_DialData(char *Number, char type, void (* callpassup)(char c))
2551 unsigned char req[100] = { N6110_FRAME_HEADER, 0x01 };
2552 unsigned char *req_end;
2553 unsigned char req_end0[] = { 0x01, /* make a data call = type 0x01 */
2554 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2555 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00 };
2556 unsigned char req_end1[] = { 0x01,
2557 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2558 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2559 0x88,0x90,0x21,0x48,0x40,0xbb };
2560 unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2561 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2562 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
2563 unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2564 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2565 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
2566 unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
2567 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2568 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
2569 0x20,0x15,0x63,0x80 };
2574 CurrentCallPassup=callpassup;
2579 size = sizeof(req_end0);
2582 Protocol->SendMessage(sizeof(req3), 0x01, req3);
2584 Protocol->SendMessage(sizeof(req4), 0x01, req4);
2587 size = sizeof(req_end1);
2589 case -1: /* Just used to set the call passup */
2594 size = sizeof(req_end0);
2598 req[4] = strlen(Number);
2600 for(i = 0; i < strlen(Number) ; i++)
2601 req[5+i] = Number[i];
2603 memcpy(req + 5 + strlen(Number), req_end, size);
2605 Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);
2607 if (type != 1) Protocol->SendMessage(26, 0x01, req2);
2614 GSM_Error N6110_GetIncomingCallNr(char *Number)
2617 if (*CurrentIncomingCall != ' ') {
2618 strcpy(Number, CurrentIncomingCall);
2625 #endif /* UCLINUX */
2627 GSM_Error N6110_CancelCall(void)
2629 // This frame & method works only on 61xx/51xx
2630 // unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
2631 // req[4]=CurrentCallSequenceNumber;
2632 // Protocol->SendMessage(6, 0x01, req);
2637 unsigned char req[]={0x00,0x01,0x7c,0x03};
2640 error=N6110_EnableExtendedCommands(0x01);
2641 if (error!=GE_NONE) return error;
2643 return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
2648 void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2650 switch(MessageBuffer[3]) {
2654 fprintf(stdout, _("Message: Security code accepted.\n"));
2656 CurrentSecurityCodeError = GE_NONE;
2661 fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
2663 CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
2667 GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
2670 unsigned char req[15] = { N6110_FRAME_HEADER,
2671 0x0a, /* Enter code request. */
2672 0x00 /* Type of the entered code. */
2676 req[4]=SecurityCode.Type;
2678 for (i=0; i<strlen(SecurityCode.Code);i++)
2679 req[5+i]=SecurityCode.Code[i];
2681 req[5+strlen(SecurityCode.Code)]=0x00;
2682 req[6+strlen(SecurityCode.Code)]=0x00;
2684 return NULL_SendMessageSequence
2685 (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
2688 void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2690 *CurrentSecurityCodeStatus = MessageBuffer[4];
2693 fprintf(stdout, _("Message: Security Code status received: "));
2695 switch(*CurrentSecurityCodeStatus) {
2697 case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;
2698 case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;
2699 case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;
2700 case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;
2701 case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;
2702 case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;
2703 default : fprintf(stdout, _("Unknown!\n"));
2708 CurrentSecurityCodeError = GE_NONE;
2711 GSM_Error N6110_GetSecurityCodeStatus(int *Status)
2714 unsigned char req[4] = { N6110_FRAME_HEADER,
2718 CurrentSecurityCodeStatus=Status;
2720 return NULL_SendMessageSequence
2721 (20, &CurrentSecurityCodeError, 4, 0x08, req);
2724 void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2729 fprintf(stdout, _("Message: Security code received: "));
2730 switch (MessageBuffer[3]) {
2731 case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;
2732 case GSCT_Pin: fprintf(stdout, _("PIN"));break;
2733 case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;
2734 case GSCT_Puk: fprintf(stdout, _("PUK"));break;
2735 case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;
2736 default: fprintf(stdout, _("unknown !"));break;
2738 if (MessageBuffer[4]==1) {
2739 fprintf(stdout, _(" allowed, value \""));
2740 if (MessageBuffer[3]==GSCT_SecurityCode) {
2741 for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2743 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2744 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2745 for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2747 fprintf(stdout, _("\""));
2749 fprintf(stdout, _(" not allowed"));
2751 fprintf(stdout, _("\n"));
2754 if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
2755 && MessageBuffer[4]==1) { /* It's allowed */
2756 if (MessageBuffer[3]==GSCT_SecurityCode) {
2757 for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2758 CurrentSecurityCode->Code[5]=0;
2760 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2761 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2762 for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2763 CurrentSecurityCode->Code[4]=0;
2765 CurrentSecurityCodeError=GE_NONE;
2767 CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
2770 GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
2773 unsigned char req[4] = { 0x00,
2774 0x01,0x6e, /* Get code request. */
2775 0x00 }; /* Type of the requested code. */
2779 error=N6110_EnableExtendedCommands(0x01);
2780 if (error!=GE_NONE) return error;
2782 req[3]=SecurityCode->Type;
2784 CurrentSecurityCode=SecurityCode;
2786 return NULL_SendMessageSequence
2787 (20, &CurrentSecurityCodeError, 4, 0x40, req);
2790 void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2793 fprintf(stdout, _("Message: answer for PlayTone frame\n"));
2796 CurrentPlayToneError=GE_NONE;
2799 GSM_Error N6110_PlayTone(int Herz, u8 Volume)
2801 unsigned char req[6] = { 0x00,0x01,0x8f,
2804 0x00 }; /* HerzHi */
2808 /* PlayTone wasn't used earlier */
2809 if (CurrentPlayToneError==GE_UNKNOWN) {
2810 if (CurrentConnectionType!=GCT_MBUS)
2811 CurrentDisableKeepAlive=true;
2813 error=N6110_EnableExtendedCommands(0x01);
2814 if (error!=GE_NONE) return error;
2817 /* For Herz==255*255 we have silent */
2818 if (Herz!=255*255) {
2831 /* For Herz==255*255 we have silent and additionaly
2832 we wait for phone answer - it's important for MBUS */
2833 if (Herz==255*255) {
2834 error=NULL_SendMessageSequence
2835 (20, &CurrentPlayToneError, 6, 0x40, req);
2837 CurrentPlayToneError=GE_UNKNOWN;
2838 CurrentDisableKeepAlive=false;
2840 if (error!=GE_NONE) return error;
2842 Protocol->SendMessage(6,0x40,req);
2845 error=NULL_SendMessageSequence
2846 (20, &CurrentPlayToneError, 6, 0x40, req);
2848 /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
2849 if (Herz==255*255) {
2850 CurrentPlayToneError=GE_UNKNOWN;
2851 CurrentDisableKeepAlive=false;
2854 if (error!=GE_NONE) return error;
2861 void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2863 if (MessageBuffer[4]==0x01) {
2864 DecodeDateTime(MessageBuffer+8, CurrentDateTime);
2867 fprintf(stdout, _("Message: Date and time\n"));
2868 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
2869 fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
2872 CurrentDateTime->IsSet=true;
2876 fprintf(stdout, _("Message: Date and time not set in phone\n"));
2879 CurrentDateTime->IsSet=false;
2882 CurrentDateTimeError=GE_NONE;
2885 GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
2887 return N6110_PrivGetDateTime(date_time,0x11);
2890 GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
2892 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
2894 CurrentDateTime=date_time;
2896 return NULL_SendMessageSequence
2897 (50, &CurrentDateTimeError, 4, msgtype, req);
2900 void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2903 fprintf(stdout, _("Message: Alarm\n"));
2904 fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
2905 fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
2908 CurrentAlarm->Hour=MessageBuffer[9];
2909 CurrentAlarm->Minute=MessageBuffer[10];
2910 CurrentAlarm->Second=0;
2912 CurrentAlarm->IsSet=(MessageBuffer[8]==2);
2914 CurrentAlarmError=GE_NONE;
2917 GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
2919 return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
2922 GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
2924 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
2926 CurrentAlarm=date_time;
2928 return NULL_SendMessageSequence
2929 (50, &CurrentAlarmError, 4, msgtype, req);
2932 void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2934 switch (MessageBuffer[3]) {
2938 CurrentMessageCenter->No=MessageBuffer[4];
2939 CurrentMessageCenter->Format=MessageBuffer[6];
2940 CurrentMessageCenter->Validity=MessageBuffer[8];
2941 sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
2943 sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
2945 sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
2948 fprintf(stdout, _("Message: SMS Center received:\n"));
2949 fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
2950 fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
2951 fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
2953 fprintf(stdout, _(" SMS Center message format is "));
2955 switch (CurrentMessageCenter->Format) {
2957 case GSMF_Text : fprintf(stdout, _("Text")); break;
2958 case GSMF_Paging: fprintf(stdout, _("Paging")); break;
2959 case GSMF_Fax : fprintf(stdout, _("Fax")); break;
2960 case GSMF_Email : fprintf(stdout, _("Email")); break;
2961 default : fprintf(stdout, _("Unknown"));
2964 fprintf(stdout, "\n");
2966 fprintf(stdout, _(" SMS Center message validity is "));
2968 switch (CurrentMessageCenter->Validity) {
2970 case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;
2971 case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;
2972 case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;
2973 case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;
2974 case GSMV_1_Week : fprintf(stdout, _("1 week")); break;
2975 case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;
2976 default : fprintf(stdout, _("Unknown"));
2979 fprintf(stdout, "\n");
2983 CurrentMessageCenterError=GE_NONE;
2989 /* Number of entries depends on SIM card */
2992 fprintf(stdout, _("Message: SMS Center error received:\n"));
2993 fprintf(stdout, _(" The request for SMS Center failed.\n"));
2996 /* FIXME: appropriate error. */
2997 CurrentMessageCenterError=GE_INTERNALERROR;
3004 /* This function sends to the mobile phone a request for the SMS Center */
3005 GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
3007 unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
3008 0x00 /* SMS Center Number. */
3011 req[5]=MessageCenter->No;
3013 CurrentMessageCenter=MessageCenter;
3015 return NULL_SendMessageSequence
3016 (50, &CurrentMessageCenterError, 6, 0x02, req);
3019 void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3022 fprintf(stdout, _("Message: SMS Center correctly set.\n"));
3024 CurrentMessageCenterError=GE_NONE;
3027 /* This function set the SMS Center profile on the phone. */
3028 GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
3030 unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
3031 0x00, /* SMS Center Number. */
3032 0x00, /* Unknown. */
3033 0x00, /* SMS Message Format. */
3034 0x00, /* Unknown. */
3035 0x00, /* Validity. */
3036 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
3037 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
3038 /* Message Center Name. */
3041 req[5]=MessageCenter->No;
3042 req[7]=MessageCenter->Format;
3043 req[9]=MessageCenter->Validity;
3045 req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
3047 req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
3049 sprintf(req+34, "%s", MessageCenter->Name);
3051 CurrentMessageCenter=MessageCenter;
3053 return NULL_SendMessageSequence
3054 (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
3057 void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3059 switch (MessageBuffer[3]) {
3064 fprintf(stdout, _("Message: SMS Status Received\n"));
3065 fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
3066 fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
3069 CurrentSMSStatus->UnRead = MessageBuffer[11];
3070 CurrentSMSStatus->Number = MessageBuffer[10];
3072 CurrentSMSStatusError = GE_NONE;
3078 fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
3081 CurrentSMSStatusError = GE_INTERNALERROR;
3087 GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
3089 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
3091 CurrentSMSStatus = Status;
3093 return NULL_SendMessageSequence
3094 (10, &CurrentSMSStatusError, 5, 0x14, req);
3097 GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
3101 strcpy(folders->Folder[0].Name,"Inbox");
3102 strcpy(folders->Folder[1].Name,"Outbox");
3107 #endif /* UCLINUX */
3109 GSM_Error N6110_GetIMEI(char *imei)
3111 if (strlen(Current_IMEI)>0) {
3112 strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
3116 return (GE_TRYAGAIN);
3119 GSM_Error N6110_GetRevision(char *revision)
3122 if (strlen(Current_Revision)>0) {
3123 strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
3127 return (GE_TRYAGAIN);
3130 static GSM_Error N6110_GetModel(char *model)
3132 if (strlen(Current_Model)>0) {
3133 strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
3137 return (GE_TRYAGAIN);
3142 void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3144 switch (MessageBuffer[4]) {
3148 fprintf(stdout, _("Message: Date and time set correctly\n"));
3150 CurrentSetDateTimeError=GE_NONE;
3155 fprintf(stdout, _("Message: Date and time setting error\n"));
3157 CurrentSetDateTimeError=GE_INVALIDDATETIME;
3162 /* Needs SIM card with PIN in phone */
3163 GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
3165 return N6110_PrivSetDateTime(date_time,0x11);
3168 /* Needs SIM card with PIN in phone */
3169 GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
3172 unsigned char req[] = { N6110_FRAME_HEADER,
3173 0x60, /* set-time subtype */
3174 0x01, 0x01, 0x07, /* unknown */
3175 0x00, 0x00, /* Year (0x07cf = 1999) */
3176 0x00, 0x00, /* Month Day */
3177 0x00, 0x00, /* Hours Minutes */
3178 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3181 EncodeDateTime(req+7, date_time);
3183 return NULL_SendMessageSequence
3184 (20, &CurrentSetDateTimeError, 14, msgtype, req);
3187 void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3189 switch (MessageBuffer[4]) {
3193 fprintf(stdout, _("Message: Alarm set correctly\n"));
3195 CurrentSetAlarmError=GE_NONE;
3200 fprintf(stdout, _("Message: Alarm setting error\n"));
3202 CurrentSetAlarmError=GE_INVALIDDATETIME;
3207 /* FIXME: we should also allow to set the alarm off :-) */
3208 GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
3210 return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
3213 /* FIXME: we should also allow to set the alarm off :-) */
3214 GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
3217 unsigned char req[] = { N6110_FRAME_HEADER,
3218 0x6b, /* set-alarm subtype */
3219 0x01, 0x20, 0x03, /* unknown */
3220 0x02, /* should be alarm on/off, but it don't works */
3221 0x00, 0x00, /* Hours Minutes */
3222 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3225 req[8] = date_time->Hour;
3226 req[9] = date_time->Minute;
3228 return NULL_SendMessageSequence
3229 (50, &CurrentSetAlarmError, 11, msgtype, req);
3232 #endif /* UCLINUX */
3234 static void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3236 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
3241 switch (MessageBuffer[3]) {
3245 CurrentPhonebookEntry->Empty = true;
3247 count=MessageBuffer[5];
3250 fprintf(stdout, _("Message: Phonebook entry received:\n"));
3251 fprintf(stdout, _(" Name: "));
3253 for (tmp=0; tmp <count; tmp++)
3255 if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
3256 if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
3257 fprintf(stdout, "%c", MessageBuffer[6+tmp]);
3260 fprintf(stdout, "\n");
3263 while (N6110_GetModel(model) != GE_NONE)
3266 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3268 DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
3269 CurrentPhonebookEntry->Name[count/2] = 0x00;
3271 fprintf(stderr,"FATAL ERROR: DecodeUnicode disabled!\n");
3273 #endif /* UCLINUX */
3275 memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);
3276 CurrentPhonebookEntry->Name[count] = 0x00;
3279 CurrentPhonebookEntry->Empty = false;
3281 for (tmp=0; tmp <count; tmp++)
3283 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3284 /* We check only 1'st, 3'rd, ... char */
3285 if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking
3286 if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents
3288 if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking
3289 if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents
3294 count=MessageBuffer[6+count];
3297 fprintf(stdout, _(" Number: "));
3299 for (tmp=0; tmp <count; tmp++)
3300 fprintf(stdout, "%c", MessageBuffer[i+tmp]);
3302 fprintf(stdout, "\n");
3305 memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);
3306 CurrentPhonebookEntry->Number[count] = 0x00;
3307 CurrentPhonebookEntry->Group = MessageBuffer[i+count];
3309 /* Phone doesn't have entended phonebook */
3310 CurrentPhonebookEntry->SubEntriesCount = 0;
3312 /* But for these memories data is saved and we can save it using 7110/6210 style */
3313 if (CurrentPhonebookEntry->MemoryType==GMT_DC ||
3314 CurrentPhonebookEntry->MemoryType==GMT_RC ||
3315 CurrentPhonebookEntry->MemoryType==GMT_MC) {
3316 CurrentPhonebookEntry->SubEntriesCount = 1;
3317 CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;
3318 CurrentPhonebookEntry->SubEntries[0].NumberType=0;
3319 CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;
3320 DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);
3323 fprintf(stdout, _(" Date: "));
3324 fprintf(stdout, "%02u.%02u.%04u\n",
3325 CurrentPhonebookEntry->SubEntries[0].data.Date.Day,
3326 CurrentPhonebookEntry->SubEntries[0].data.Date.Month,
3327 CurrentPhonebookEntry->SubEntries[0].data.Date.Year);
3328 fprintf(stdout, _(" Time: "));
3329 fprintf(stdout, "%02u:%02u:%02u\n",
3330 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,
3331 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,
3332 CurrentPhonebookEntry->SubEntries[0].data.Date.Second);
3335 /* These values are set, when date and time unavailable in phone.
3336 Values from 3310 - in other can be different */
3337 if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&
3338 CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&
3339 CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&
3340 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&
3341 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&
3342 CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)
3343 CurrentPhonebookEntry->SubEntriesCount = 0;
3346 /* Signal no error to calling code. */
3347 CurrentPhonebookError = GE_NONE;
3354 fprintf(stdout, _("Message: Phonebook read entry error received:\n"));
3357 switch (MessageBuffer[4]) {
3361 fprintf(stdout, _(" Invalid memory type!\n"));
3363 CurrentPhonebookError = GE_INVALIDMEMORYTYPE;
3368 fprintf(stdout, _(" Unknown error!\n"));
3370 CurrentPhonebookError = GE_INTERNALERROR;
3378 /* Routine to get specifed phone book location. Designed to be called by
3379 application. Will block until location is retrieved or a timeout/error
3381 GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)
3383 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
3385 CurrentPhonebookEntry = entry;
3387 req[4] = N6110_GetMemoryType(entry->MemoryType);
3388 req[5] = entry->Location;
3390 return NULL_SendMessageSequence
3391 (50, &CurrentPhonebookError, 7, 0x03, req);
3394 static void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3396 switch (MessageBuffer[3]) {
3401 fprintf(stdout, _("Message: Phonebook written correctly.\n"));
3403 CurrentPhonebookError = GE_NONE;
3408 switch (MessageBuffer[4]) {
3409 /* FIXME: other errors? When I send the phonebook with index of 350 it
3410 still report error 0x7d :-( */
3413 fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));
3415 CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;
3420 fprintf(stdout, _(" Unknown error!\n"));
3422 CurrentPhonebookError = GE_INTERNALERROR;
3427 /* Routine to write phonebook location in phone. Designed to be called by
3428 application code. Will block until location is written or timeout
3430 GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)
3432 unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };
3435 req[4] = N6110_GetMemoryType(entry->MemoryType);
3436 req[5] = entry->Location;
3440 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {
3443 req[6] = strlen(entry->Name)*2;
3445 EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
3447 for (i=0; i<strlen(entry->Name); i++)
3449 /* here we encode "special" chars */
3450 if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
3451 if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
3454 current+=strlen(entry->Name)*2;
3458 fprintf(stderr,"FATAL ERROR: EncodeUnicode disabled!\n");
3461 #endif /* UCLINUX */
3464 req[6] = strlen(entry->Name);
3466 for (i=0; i<strlen(entry->Name); i++)
3468 req[current+i] = entry->Name[i];
3470 /* here we encode "special" chars */
3471 if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
3472 if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
3475 current+=strlen(entry->Name);
3478 req[current++]=strlen(entry->Number);
3480 for (i=0; i<strlen(entry->Number); i++)
3481 req[current+i] = entry->Number[i];
3483 current+=strlen(entry->Number);
3485 /* Jano: This allow to save 14 characters name into SIM memory, when
3486 No Group is selected. */
3487 if (entry->Group == 5)
3488 req[current++]=0xff;
3490 req[current++]=entry->Group;
3492 return NULL_SendMessageSequence
3493 (50, &CurrentPhonebookError, current, 0x03, req);
3498 void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3500 switch(MessageBuffer[3]) {
3504 fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
3506 CurrentNetmonitorError=GE_NONE;
3511 fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
3512 fprintf(stdout, "%s\n", MessageBuffer+4);
3515 strcpy(CurrentNetmonitor, MessageBuffer+4);
3517 CurrentNetmonitorError=GE_NONE;
3521 GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
3523 unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
3527 error=N6110_EnableExtendedCommands(0x01);
3528 if (error!=GE_NONE) return error;
3530 CurrentNetmonitor=Screen;
3534 return NULL_SendMessageSequence
3535 (20, &CurrentNetmonitorError, 4, 0x40, req);
3538 /* Doesn't work in N3210. */
3539 /* In other allow to access phone menu without SIM card (just send any sequence) */
3540 GSM_Error N6110_SendDTMF(char *String)
3542 unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
3543 0x00 /* Length of DTMF string. */
3546 u8 length=strlen(String);
3548 if (length>59) length=59;
3552 memcpy(req+5,String,length);
3554 return NULL_SendMessageSequence
3555 (20, &CurrentSendDTMFError, 5+length, 0x01, req);
3558 #endif /* UCLINUX */
3560 static void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3562 switch (MessageBuffer[3]) {
3566 switch (MessageBuffer[4]) {
3567 case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
3568 default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
3571 CurrentSpeedDialEntry->Location = MessageBuffer[5];
3574 fprintf(stdout, _("Message: Speed dial entry received:\n"));
3575 fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
3576 fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
3577 fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
3580 CurrentSpeedDialError=GE_NONE;
3586 fprintf(stdout, _("Message: Speed dial entry error\n"));
3588 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3594 GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
3597 unsigned char req[] = { N6110_FRAME_HEADER,
3599 0x00 /* The number of speed dial. */
3602 CurrentSpeedDialEntry = entry;
3604 req[4] = entry->Number;
3606 return NULL_SendMessageSequence
3607 (20, &CurrentSpeedDialError, 5, 0x03, req);
3610 static void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3612 switch (MessageBuffer[3]) {
3617 fprintf(stdout, _("Message: Speed dial entry set.\n"));
3619 CurrentSpeedDialError=GE_NONE;
3625 fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
3627 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3633 GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
3636 unsigned char req[] = { N6110_FRAME_HEADER,
3639 0x00, /* Memory Type */
3643 req[4] = entry->Number;
3645 switch (entry->MemoryType) {
3646 case GMT_ME: req[5] = 0x02;
3647 default : req[5] = 0x03;
3650 req[6] = entry->Location;
3652 return NULL_SendMessageSequence
3653 (20, &CurrentSpeedDialError, 7, 0x03, req);
3658 /* This function finds parts of SMS in frame used in new Nokia phones
3659 in internal protocols (they're coded according to GSM 03.40), copies them
3660 to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
3661 GSM_ETSISMSMessage to GSM_SMSMessage structure */
3662 GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
3664 SMS_MessageType PDU=SMS_Deliver;
3665 GSM_ETSISMSMessage ETSI;
3668 ETSI.firstbyte=req[12];
3670 /* See GSM 03.40 section 9.2.3.1 */
3671 if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
3672 if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
3675 case SMS_Submit : offset=5;break;
3676 case SMS_Deliver : offset=4;break;
3677 case SMS_Status_Report: offset=3;break;
3681 for (i=0;i<req[0]+1;i++)
3682 ETSI.SMSCNumber[i]=req[i];
3684 for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
3685 ETSI.Number[i]=req[i+12+offset];
3689 ETSI.TPDCS=req[10+offset];
3690 ETSI.TPUDL=req[11+offset];
3691 ETSI.TPVP=0; //no support for now
3692 ETSI.TPPID=0; //no support for now
3693 for(i=31+offset;i<length;i++)
3694 ETSI.MessageText[i-31-offset]=req[i];
3697 ETSI.TPDCS=req[10+offset];
3698 ETSI.TPUDL=req[11+offset];
3699 ETSI.TPPID=0; //no support for now
3700 for(i=31+offset;i<length;i++)
3701 ETSI.MessageText[i-31-offset]=req[i];
3703 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3705 case SMS_Status_Report:
3707 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3708 ETSI.TPStatus=req[14];
3710 ETSI.SMSCDateTime[i]=req[i+34];
3716 GSM_DecodeETSISMS(SMS, &ETSI);
3723 void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3727 switch (MessageBuffer[3]) {
3731 switch (MessageBuffer[7]) {
3734 CurrentSMSMessage->Type = GST_SMS;
3735 CurrentSMSMessage->folder=GST_INBOX;
3740 CurrentSMSMessage->Type = GST_DR;
3741 CurrentSMSMessage->folder=GST_INBOX;
3746 CurrentSMSMessage->Type = GST_SMS;
3747 CurrentSMSMessage->folder=GST_OUTBOX;
3752 CurrentSMSMessage->Type = GST_UN;
3758 /* Field Short Message Status - MessageBuffer[4] seems not to be
3759 compliant with GSM 07.05 spec.
3760 Meaning Nokia protocol GMS spec
3761 ----------------------------------------------------
3762 MO Sent 0x05 0x07 or 0x01
3763 MO Not sent 0x07 0x06 or 0x00
3764 MT Read 0x01 0x05 or 0x01
3765 MT Not read 0x03 0x04 or 0x00
3766 ----------------------------------------------------
3767 See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
3771 if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
3772 else CurrentSMSMessage->Status = GSS_SENTREAD;
3775 fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
3777 if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
3778 fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
3780 fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
3783 if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
3784 if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
3786 if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
3787 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
3788 else fprintf(stdout, _(" Not sent\n"));
3790 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
3791 else fprintf(stdout, _(" Not read\n"));
3795 CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
3797 CurrentSMSMessage->MemoryType = MessageBuffer[5];
3798 CurrentSMSMessage->MessageNumber = MessageBuffer[6];
3800 /* Signal no error to calling code. */
3801 CurrentSMSMessageError = GE_NONE;
3804 fprintf(stdout, "\n");
3811 /* We have requested invalid or empty location. */
3814 fprintf(stdout, _("Message: SMS reading failed\n"));
3816 switch (MessageBuffer[4]) {
3818 fprintf(stdout, _(" Invalid location!\n"));break;
3820 fprintf(stdout, _(" Empty SMS location.\n"));break;
3822 fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
3824 fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
3828 switch (MessageBuffer[4]) {
3829 case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3830 case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
3831 case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
3832 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3840 GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
3843 unsigned char req[] = { N6110_FRAME_HEADER,
3846 0x00, /* Location */
3851 /* State machine code writes data to these variables when it comes in. */
3853 CurrentSMSMessage = message;
3854 CurrentSMSMessageError = GE_BUSY;
3856 req[5] = message->Location;
3859 Protocol->SendMessage(8, 0x02, req);
3861 /* Wait for timeout or other error. */
3862 while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
3865 return (GE_TIMEOUT);
3870 return (CurrentSMSMessageError);
3873 void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3876 fprintf(stdout, _("Message: SMS deleted successfully.\n"));
3879 CurrentSMSMessageError = GE_NONE;
3882 GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
3884 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
3886 req[5] = message->Location;
3888 return NULL_SendMessageSequence
3889 (50, &CurrentSMSMessageError, 6, 0x14, req);
3892 /* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
3893 GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
3895 GSM_ETSISMSMessage ETSI;
3898 GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
3901 for (i=0;i<36;i++) req[i]=0;
3903 req[12]=ETSI.firstbyte;
3905 for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
3906 req[i]=ETSI.SMSCNumber[i];
3911 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3912 req[i+12+offset]=ETSI.Number[i];
3913 req[10+offset]=ETSI.TPDCS;
3914 req[11+offset]=ETSI.TPUDL;
3915 req[24+offset]=ETSI.TPVP;
3917 // fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
3918 // fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
3919 // fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
3921 // req[]=ETSI.TPPID;
3922 for(i=0;i<*length;i++)
3923 req[i+31+offset]=ETSI.MessageText[i];
3928 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3929 req[i+12+offset]=ETSI.Number[i];
3930 req[10+offset]=ETSI.TPDCS;
3931 req[11+offset]=ETSI.TPUDL;
3932 // req[]=ETSI.TPPID;
3933 for(i=0;i<*length;i++)
3934 req[i+31+offset]=ETSI.MessageText[i];
3936 req[24+offset+i]=ETSI.DeliveryDateTime[i];
3942 *length=*length+offset;
3947 void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3949 switch (MessageBuffer[3]) {
3951 /* SMS message correctly sent to the network */
3954 fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
3956 CurrentSMSMessageError = GE_SMSSENDOK;
3959 /* SMS message send to the network failed */
3963 fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
3965 switch (MessageBuffer[6]) {
3966 case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3967 case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
3968 case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3969 case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
3970 case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3971 case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3972 case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3973 case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3974 case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3977 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
3978 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
3981 CurrentSMSMessageError = GE_SMSSENDFAILED;
3987 GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
3991 unsigned char req[256] = {
3993 0x01, 0x02, 0x00, /* SMS send request*/
3998 error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
3999 if (error != GE_NONE) return error;
4001 return NULL_SendMessageSequence
4002 (200, &CurrentSMSMessageError, 42+length, 0x02, req);
4005 void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4007 switch (MessageBuffer[3]) {
4012 fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
4015 CurrentSMSMessage->MessageNumber=MessageBuffer[5];
4017 CurrentSMSMessageError = GE_NONE;
4022 fprintf(stdout, _("SMS saving failed\n"));
4023 switch (MessageBuffer[4]) {
4024 case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
4025 case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
4026 default :fprintf(stdout, _(" Unknown error.\n"));break;
4030 switch (MessageBuffer[4]) {
4031 case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
4032 case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
4033 default :CurrentSMSMessageError = GE_UNKNOWN;break;
4038 /* GST_DR and GST_UN not supported ! */
4039 GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
4041 unsigned char req[256] = {
4042 N6110_FRAME_HEADER, 0x04, /* SMS save request*/
4043 0x00, /* SMS Status. Different for Inbox and Outbox */
4045 0x00, /* SMS Location */
4046 0x02, /* SMS Type */
4050 SMS_MessageType PDU;
4053 if (SMS->Location) req[6] = SMS->Location;
4055 if (SMS->folder==0) { /*Inbox*/
4056 req[4]=1; /* SMS Status */
4057 req[7] = 0x00; /* SMS Type */
4060 req[4]=5; /* SMS Status */
4061 req[7] = 0x02; /* SMS Type */
4065 if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
4067 error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
4068 if (error != GE_NONE) return error;
4070 CurrentSMSMessage = SMS;
4072 return NULL_SendMessageSequence
4073 (70, &CurrentSMSMessageError, 39+length, 0x14, req);
4076 void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4079 fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
4082 CurrentCBError = GE_NONE;
4085 /* Enable and disable Cell Broadcasting */
4086 GSM_Error N6110_EnableCellBroadcast(void)
4088 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4089 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
4092 fprintf (stdout,"Enabling CB\n");
4095 CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
4096 CurrentCBMessage->Channel = 0;
4097 CurrentCBMessage->New = false;
4098 strcpy (CurrentCBMessage->Message,"");
4100 return NULL_SendMessageSequence
4101 (10, &CurrentCBError, 10, 0x02, req);
4105 GSM_Error N6110_DisableCellBroadcast(void)
4107 /* Should work, but not tested fully */
4109 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
4112 return NULL_SendMessageSequence
4113 (10, &CurrentCBError, 10, 0x02, req);
4116 void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4119 unsigned char output[160];
4121 CurrentCBMessage->Channel = MessageBuffer[7];
4122 CurrentCBMessage->New = true;
4123 tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
4126 fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
4128 fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
4132 for (i=0; i<tmp;i++) {
4133 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
4136 fprintf(stdout, "\n");
4139 for (i=0; i<tmp; i++) {
4140 CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
4142 CurrentCBMessage->Message[i]=0;
4145 GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
4148 fprintf(stdout,"Reading CB\n");
4151 if (CurrentCBMessage != NULL)
4153 if (CurrentCBMessage->New == true)
4156 fprintf(stdout,"New CB received\n");
4158 Message->Channel = CurrentCBMessage->Channel;
4159 strcpy(Message->Message,CurrentCBMessage->Message);
4160 CurrentCBMessage->New = false;
4164 return (GE_NONEWCBRECEIVED);
4167 int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
4171 req[count++]=Bitmap.number;
4172 req[count++]=strlen(Bitmap.text);
4173 memcpy(req+count,Bitmap.text,req[count-1]);
4174 count+=req[count-1];
4175 req[count++]=Bitmap.ringtone;
4177 /* Setting for graphic:
4180 0x02 - View Graphics
4181 0x03 - Send Graphics
4183 You can even set it higher but Nokia phones (my
4184 6110 at least) will not show you the name of this
4185 item in menu ;-)) Nokia is really joking here. */
4186 if (Bitmap.enabled) req[count++]=0x01;
4187 else req[count++]=0x00;
4189 req[count++]=(Bitmap.size+4)>>8;
4190 req[count++]=(Bitmap.size+4)%0xff;
4191 req[count++]=0x00; /* Future extensions! */
4192 req[count++]=Bitmap.width;
4193 req[count++]=Bitmap.height;
4194 req[count++]=0x01; /* Just BW */
4195 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4197 return count+Bitmap.size;
4200 int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4204 EncodeNetworkCode(req+count, Bitmap.netcode);
4207 req[count++]=(Bitmap.size+4)>>8;
4208 req[count++]=(Bitmap.size+4)%0xff;
4209 req[count++]=0x00; /* Infofield */
4210 req[count++]=Bitmap.width;
4211 req[count++]=Bitmap.height;
4212 req[count++]=0x01; /* Just BW */
4213 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4215 return count+Bitmap.size;
4218 int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4223 req[count++]=Bitmap.height;
4224 req[count++]=Bitmap.width;
4225 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4227 return count+Bitmap.size;
4230 /* Set a bitmap or welcome-note */
4231 GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
4233 unsigned char req[600] = { N6110_FRAME_HEADER };
4239 /* Direct uploading variables */
4240 GSM_MultiSMSMessage SMS;
4241 unsigned char buffer[1000] = {0x0c,0x01};
4242 GSM_NetworkInfo NetworkInfo;
4246 /* Uploading with preview */
4247 if (Bitmap->number==255 &&
4248 (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
4249 GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
4250 memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
4252 memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
4254 buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
4256 Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
4258 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4259 return GE_NONE; //no answer from phone
4262 CurrentSetBitmapError = GE_BUSY;
4264 switch (Bitmap->type) {
4265 case GSM_WelcomeNoteText:
4266 case GSM_DealerNoteText:
4268 req[count++]=0x01; /* Only one block */
4270 if (Bitmap->type==GSM_WelcomeNoteText)
4271 req[count++]=0x02; /* Welcome text */
4273 req[count++]=0x03; /* Dealer Welcome Note */
4275 textlen=strlen(Bitmap->text);
4276 req[count++]=textlen;
4277 memcpy(req+count,Bitmap->text,textlen);
4281 Protocol->SendMessage(count, 0x05, req);
4285 case GSM_StartupLogo:
4286 if (Bitmap->number==0) {
4288 /* For 33xx we first set animated logo to default */
4289 if (GetModelFeature (FN_STARTUP)==F_STANIM) {
4290 error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4291 if (error!=GE_NONE) return error;
4295 req[count++]=0x01; /* Only one block */
4296 count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
4297 Protocol->SendMessage(count, 0x05, req);
4299 return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4303 case GSM_OperatorLogo:
4304 req[count++]=0x30; /* Store Op Logo */
4305 req[count++]=0x01; /* Location */
4306 count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
4307 Protocol->SendMessage(count, 0x05, req);
4310 case GSM_CallerLogo:
4312 count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
4313 Protocol->SendMessage(count, 0x03, req);
4316 case GSM_PictureImage:
4318 req[count++]=Bitmap->number;
4319 if (strcmp(Bitmap->Sender,"")) {
4320 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
4322 /* Convert number of semioctets to number of chars and add count */
4324 if (textlen % 2) textlen++;
4325 count+=textlen / 2 + 1;
4333 req[count++]=strlen(Bitmap->text);
4334 memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
4335 count+=strlen(Bitmap->text);
4337 req[count++]=Bitmap->width;
4338 req[count++]=Bitmap->height;
4340 memcpy(req+count,Bitmap->bitmap,Bitmap->size);
4341 Protocol->SendMessage(count+Bitmap->size, 0x47, req);
4344 case GSM_7110OperatorLogo:
4345 case GSM_7110StartupLogo:
4346 case GSM_6210StartupLogo:
4347 return GE_NOTSUPPORTED;
4353 /* Wait for timeout or other error. */
4354 while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
4357 return (GE_TIMEOUT);
4362 return CurrentSetBitmapError;
4365 /* Get a bitmap from the phone */
4366 GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
4368 unsigned char req[10] = { N6110_FRAME_HEADER };
4373 CurrentGetBitmap=Bitmap;
4374 CurrentGetBitmapError = GE_BUSY;
4376 switch (CurrentGetBitmap->type) {
4377 case GSM_StartupLogo:
4378 case GSM_WelcomeNoteText:
4379 case GSM_DealerNoteText:
4381 Protocol->SendMessage(count, 0x05, req);
4383 case GSM_OperatorLogo:
4385 req[count++]=0x01; /* Location 1 */
4386 Protocol->SendMessage(count, 0x05, req);
4388 case GSM_CallerLogo:
4390 req[count++]=Bitmap->number;
4391 Protocol->SendMessage(count, 0x03, req);
4393 case GSM_PictureImage:
4395 req[count++]=Bitmap->number;
4396 Protocol->SendMessage(count, 0x47, req);
4398 case GSM_7110OperatorLogo:
4399 case GSM_7110StartupLogo:
4400 case GSM_6210StartupLogo:
4402 return GE_NOTSUPPORTED;
4405 /* Wait for timeout or other error. */
4406 while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
4409 return (GE_TIMEOUT);
4414 CurrentGetBitmap=NULL;
4416 return CurrentGetBitmapError;
4419 void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4421 switch (MessageBuffer[3]) {
4423 /* Set ringtone OK */
4426 fprintf(stdout, _("Message: Ringtone set OK!\n"));
4428 CurrentRingtoneError=GE_NONE;
4431 /* Set ringtone error */
4434 fprintf(stdout, _("Message: Ringtone setting error !\n"));
4436 CurrentRingtoneError=GE_NOTSUPPORTED;
4441 GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
4444 char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
4445 {N6110_FRAME_HEADER,
4447 0x00, /* Location */
4450 int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
4452 /* Variables for preview uploading */
4453 unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
4454 unsigned char buffer2[20];
4455 GSM_NetworkInfo NetworkInfo;
4457 /* Setting ringtone with preview */
4458 if (ringtone->location==255) {
4461 EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
4462 memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
4463 *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
4464 Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
4465 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4467 return GE_NONE; //no answer from phone
4470 *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
4472 req[4]=ringtone->location-1;
4474 return NULL_SendMessageSequence
4475 (50, &CurrentRingtoneError, (size+7), 0x05, req);
4478 void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4482 switch (MessageBuffer[4]) {
4483 case 0x00: /* location supported. We have ringtone */
4485 /* Binary format used in N6150 */
4486 if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4488 fprintf(stdout,_("Message: ringtone \""));
4495 if (MessageBuffer[i]!=0)
4496 fprintf(stdout,_("%c"),MessageBuffer[i]);
4498 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4499 if (MessageBuffer[i]==0) break;
4504 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4507 /* Looking for end */
4510 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4513 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4517 if (i==MessageLength) break;
4521 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4522 CurrentGetBinRingtone->length=i-3;
4524 CurrentBinRingtoneError=GE_NONE;
4528 /* Binary format used in N3210 */
4529 if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4532 fprintf(stdout,_("Message: ringtone \""));
4539 if (MessageBuffer[i]!=0)
4540 fprintf(stdout,_("%c"),MessageBuffer[i]);
4542 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4543 if (MessageBuffer[i]==0) break;
4548 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4551 /* Here changes to get full compatibility with binary format used in N6150 */
4554 MessageBuffer[5]=0x0c;
4555 MessageBuffer[6]=0x01;
4556 MessageBuffer[7]=0x2c;
4558 /* Looking for end */
4561 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4564 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4568 if (i==MessageLength) break;
4572 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4574 CurrentGetBinRingtone->length=i-3;
4576 CurrentBinRingtoneError=GE_NONE;
4581 memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
4583 CurrentGetBinRingtone->length=MessageLength;
4586 fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
4588 CurrentBinRingtoneError=GE_UNKNOWNMODEL;
4594 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4597 CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
4601 GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
4603 unsigned char req[] = { 0x00,0x01,0x9e,
4608 CurrentGetBinRingtone=ringtone;
4610 error=N6110_EnableExtendedCommands(0x01);
4611 if (error!=GE_NONE) return error;
4613 req[3]=ringtone->location-1;
4615 return NULL_SendMessageSequence
4616 (50, &CurrentBinRingtoneError, 4, 0x40, req);
4619 void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4621 switch (MessageBuffer[4]) {
4622 case 0x00: /* location supported. We set ringtone */
4624 fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
4626 CurrentBinRingtoneError=GE_NONE;
4631 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4633 CurrentBinRingtoneError=GE_NOTSUPPORTED;
4638 GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
4640 unsigned char req[1000] = { 0x00,0x01,0xa0};
4644 GSM_BinRingtone ring;
4646 /* Must be sure, that can upload ringtone to this phone */
4647 ring.location=ringtone->location;
4648 error=N6110_GetBinRingTone(&ring);
4649 if (error!=GE_NONE) return error;
4651 error=N6110_EnableExtendedCommands(0x01);
4652 if (error!=GE_NONE) return error;
4654 memcpy(req+3,ringtone->frame,ringtone->length);
4656 req[3]=ringtone->location-1;
4658 return NULL_SendMessageSequence
4659 (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
4662 #endif /* UCLINUX */
4664 GSM_Error N6110_Reset(unsigned char type)
4666 return N6110_EnableExtendedCommands(type);
4669 void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4676 switch (MessageBuffer[3]) {
4678 /* Unknown message - it has been seen after the 0x07 message (call
4679 answered). Probably it has similar meaning. If you can solve
4680 this - just mail me. Pavel JanÃk ml.
4682 The message looks like this:
4690 Phone: [01 ][08 ][00 ] is the header of the frame
4692 [03 ] is the call message subtype
4694 [05 ] is the call sequence number
4698 [00 ][01 ][03 ][02 ][91][00] are unknown but has been
4699 seen in the Incoming call message (just after the
4700 caller's name from the phonebook). But never change
4701 between phone calls :-(
4704 /* This may mean sequence number of 'just made' call - CK */
4708 fprintf(stdout, _("Message: Call message, type 0x02:"));
4709 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4714 /* Possibly call OK */
4715 /* JD: I think that this means "call in progress" (incomming or outgoing) */
4719 fprintf(stdout, _("Message: Call message, type 0x03:"));
4720 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4721 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4724 CurrentCallSequenceNumber=MessageBuffer[4];
4726 CurrentIncomingCall[0]='D';
4727 #endif /* UCLINUX */
4728 if (CurrentCallPassup) CurrentCallPassup('D');
4732 /* Remote end has gone away before you answer the call. Probably your
4733 mother-in-law or banker (which is worse?) ... */
4737 fprintf(stdout, _("Message: Remote end hang up.\n"));
4738 fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
4740 switch (MessageBuffer[6]) {
4741 case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
4742 case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
4743 case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
4744 case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4745 case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
4746 case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4749 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
4750 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4754 CurrentIncomingCall[0] = ' ';
4755 #endif /* UCLINUX */
4756 if (CurrentCallPassup) CurrentCallPassup(' ');
4760 /* Incoming call alert */
4764 fprintf(stdout, _("Message: Incoming call alert:\n"));
4766 /* We can have more then one call ringing - we can distinguish between
4769 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4770 fprintf(stdout, _(" Number: "));
4772 count=MessageBuffer[6];
4774 for (tmp=0; tmp <count; tmp++)
4775 fprintf(stdout, "%c", MessageBuffer[7+tmp]);
4777 fprintf(stdout, "\n");
4779 fprintf(stdout, _(" Name: "));
4781 for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
4782 fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
4784 fprintf(stdout, "\n");
4787 count=MessageBuffer[6];
4790 CurrentIncomingCall[0] = 0;
4791 for (tmp=0; tmp <count; tmp++)
4792 sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
4793 #endif /* UCLINUX */
4797 /* Call answered. Probably your girlfriend...*/
4801 fprintf(stdout, _("Message: Call answered.\n"));
4802 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4807 /* Call ended. Girlfriend is girlfriend, but time is money :-) */
4811 fprintf(stdout, _("Message: Call ended by your phone.\n"));
4812 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4817 /* This message has been seen with the message of subtype 0x09
4818 after I hang the call.
4825 Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
4827 What is the meaning of 87? Can you spell some magic light into
4832 /* Probably means call over - CK */
4836 fprintf(stdout, _("Message: Call message, type 0x0a:"));
4837 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4838 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4842 CurrentIncomingCall[0] = ' ';
4843 #endif /* UCLINUX */
4844 if (CurrentCallPassup) CurrentCallPassup(' ');
4851 fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
4855 if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
4856 #endif /* UCLINUX */
4858 if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
4865 fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
4867 AppendLogText("Unknown msg\n",false);
4869 break; /* Visual C Don't like empty cases */
4875 static void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4879 switch (MessageBuffer[3]) {
4883 /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
4884 /* If you want see, if it works with your phone make something like that: */
4886 /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
4887 /* Protocol->SendMessage(4, 0x04, connect5); */
4889 /* Marcin-Wiacek@TopNet.PL */
4891 #if defined(WIN32) || defined(UCLINUX)
4892 sprintf(Current_IMEI, "%s", MessageBuffer+5);
4893 sprintf(Current_Model, "%s", MessageBuffer+21);
4894 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4896 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
4897 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
4898 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4902 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
4903 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
4904 fprintf(stdout, _(" Model: %s\n"), Current_Model);
4905 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
4906 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
4907 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
4912 /* Get group data */
4913 /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
4916 if (CurrentGetBitmap!=NULL) {
4917 if (CurrentGetBitmap->number==MessageBuffer[4]) {
4918 count=MessageBuffer[5];
4919 memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
4920 CurrentGetBitmap->text[count]=0;
4923 fprintf(stdout, _("Message: Caller group datas\n"));
4924 fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
4929 CurrentGetBitmap->ringtone=MessageBuffer[count++];
4931 fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
4932 if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
4933 fprintf(stdout,_("\n"));
4936 CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
4938 fprintf(stdout, _("Caller group logo "));
4939 if (CurrentGetBitmap->enabled)
4940 fprintf(stdout, _("enabled \n"));
4942 fprintf(stdout, _("disabled \n"));
4945 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4946 CurrentGetBitmap->size+=MessageBuffer[count++];
4948 fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
4952 CurrentGetBitmap->width=MessageBuffer[count++];
4953 CurrentGetBitmap->height=MessageBuffer[count++];
4955 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
4956 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4957 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
4958 CurrentGetBitmapError=GE_NONE;
4961 fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
4966 fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
4971 /* Get group data error */
4974 CurrentGetBitmapError=GE_UNKNOWN;
4976 fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
4980 /* Set group data OK */
4983 CurrentSetBitmapError=GE_NONE;
4985 fprintf(stdout, _("Message: Caller group data set correctly.\n"));
4989 /* Set group data error */
4992 CurrentSetBitmapError=GE_UNKNOWN;
4994 fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
5001 fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
5003 AppendLogText("Unknown msg\n",false);
5005 break; /* Visual C Don't like empty cases */
5009 static void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5011 int tmp, count, length;
5018 switch (MessageBuffer[3]) {
5024 fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
5027 if (CurrentGetBitmap!=NULL) {
5033 for (tmp=0;tmp<MessageBuffer[4];tmp++){
5034 switch (MessageBuffer[count++]) {
5036 if (CurrentGetBitmap->type==GSM_StartupLogo) {
5037 CurrentGetBitmap->height=MessageBuffer[count++];
5038 CurrentGetBitmap->width=MessageBuffer[count++];
5039 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5040 length=CurrentGetBitmap->size;
5041 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
5043 length=MessageBuffer[count++];
5044 length=length*MessageBuffer[count++]/8;
5048 fprintf(stdout, _("Startup logo supported - "));
5049 if (length!=0) { fprintf(stdout, _("currently set\n")); }
5050 else { fprintf(stdout, _("currently empty\n")); }
5052 if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
5055 length=MessageBuffer[count];
5056 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
5057 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5058 CurrentGetBitmap->text[length]=0;
5061 fprintf(stdout, _("Startup Text supported - "));
5064 fprintf(stdout, _("currently set to \""));
5065 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5066 fprintf(stdout, _("\"\n"));
5068 fprintf(stdout, _("currently empty\n"));
5072 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
5075 length=MessageBuffer[count];
5076 if (CurrentGetBitmap->type==GSM_DealerNoteText) {
5077 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5078 CurrentGetBitmap->text[length]=0;
5081 fprintf(stdout, _("Dealer Welcome supported - "));
5084 fprintf(stdout, _("currently set to \""));
5085 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5086 fprintf(stdout, _("\"\n"));
5088 fprintf(stdout, _("currently empty\n"));
5092 if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
5096 if (issupported) CurrentGetBitmapError=GE_NONE;
5097 else CurrentGetBitmapError=GE_NOTSUPPORTED;
5100 fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
5105 /* Set startup OK */
5108 CurrentSetBitmapError=GE_NONE;
5110 fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
5114 /* Set Operator Logo OK */
5118 fprintf(stdout, _("Message: Operator logo correctly set.\n"));
5121 CurrentSetBitmapError=GE_NONE;
5124 /* Set Operator Logo Error */
5128 fprintf(stdout, _("Message: Error setting operator logo!\n"));
5131 CurrentSetBitmapError=GE_UNKNOWN;
5135 /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
5138 if (CurrentGetBitmap!=NULL) {
5140 count=5; /* Location ignored. */
5142 DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
5146 fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
5147 CurrentGetBitmap->netcode,
5148 GSM_GetNetworkName(CurrentGetBitmap->netcode));
5151 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
5152 CurrentGetBitmap->size+=MessageBuffer[count++];
5154 CurrentGetBitmap->width=MessageBuffer[count++];
5155 CurrentGetBitmap->height=MessageBuffer[count++];
5157 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5158 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
5159 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
5160 CurrentGetBitmapError=GE_NONE;
5163 fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
5169 /* Get op logo error */
5173 fprintf(stdout, _("Message: Error getting operator logo!\n"));
5175 CurrentGetBitmapError=GE_UNKNOWN;
5181 fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
5183 AppendLogText("Unknown msg\n",false);
5189 static void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5192 unsigned char output[160];
5198 switch (MessageBuffer[3]) {
5202 /* MessageBuffer[3] = 0x05
5203 MessageBuffer[4] = 0x00
5204 MessageBuffer[5] = 0x0f
5205 MessageBuffer[6] = 0x03
5206 MessageBuffer[7] = length of packed message
5208 This is all I have seen - Gerry Anderson */
5210 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
5214 fprintf(stdout, _("Message from Network operator: "));
5216 for (i=0; i<tmp; i++)
5217 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
5219 fprintf(stdout, "\n");
5228 fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
5230 AppendLogText("Unknown msg\n",false);
5236 static void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5238 switch (MessageBuffer[3]) {
5242 fprintf(stdout, _("Message: SIM card login\n"));
5248 fprintf(stdout, _("Message: SIM card logout\n"));
5254 fprintf(stdout, _("Unknown message of type 0x09.\n"));
5256 AppendLogText("Unknown msg\n",false);
5261 static void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5263 switch(MessageBuffer[3]) {
5268 fprintf(stdout, _("Message: Calendar Alarm active\n"));
5269 fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
5274 fprintf(stdout, _("Unknown message of type 0x13.\n"));
5276 AppendLogText("Unknown msg\n",false);
5281 #endif /* UCLINUX */
5283 void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5287 switch(MessageBuffer[2]) {
5292 fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
5295 CurrentMagicError=GE_NONE;
5301 fprintf(stdout, _("Message: Answer for call commands.\n"));
5304 CurrentDialVoiceError=GE_NONE;
5310 fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
5313 CurrentMagicError=GE_NONE;
5319 fprintf(stdout, _("Message: ACK for simlock closing\n"));
5322 CurrentMagicError=GE_NONE;
5327 switch (MessageBuffer[5]) {
5330 fprintf(stdout,_("Message: EEPROM contest received\n"));
5333 if (MessageBuffer[8]!=0x00) {
5334 for (i=9;i<MessageLength;i++) {
5335 fprintf(stdout,_("%c"), MessageBuffer[i]);
5338 CurrentMagicError=GE_NONE;
5345 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5347 AppendLogText("Unknown msg\n",false);
5353 N6110_DisplayTestsInfo(MessageBuffer);
5355 #endif /* UCLINUX */
5360 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5362 AppendLogText("Unknown msg\n",false);
5363 break; /* Visual C Don't like empty cases */
5369 static void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5373 switch(MessageBuffer[3]) {
5379 if (MessageBuffer[5]!=0) {
5380 strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
5382 while (MessageBuffer[count]!=0) {
5388 strcpy(CurrentGetBitmap->Sender,"\0");
5393 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
5394 CurrentGetBitmap->text[MessageBuffer[count]]=0;
5396 if (MessageBuffer[count]!=0)
5397 count+=MessageBuffer[count];
5402 fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
5405 CurrentGetBitmap->width=MessageBuffer[count+1];
5406 CurrentGetBitmap->height=MessageBuffer[count+2];
5407 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5409 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
5411 CurrentGetBitmapError=GE_NONE;
5417 fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
5419 CurrentSetBitmapError=GE_NONE;
5420 CurrentGetBitmapError=GE_NONE;
5426 fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
5428 CurrentSetBitmapError=GE_UNKNOWN;
5434 fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
5436 CurrentGetBitmapError=GE_UNKNOWN;
5442 fprintf(stdout, _("Unknown message of type 0x47.\n"));
5444 AppendLogText("Unknown msg\n",false);
5445 break; /* Visual C Don't like empty cases */
5449 #endif /* UCLINUX */
5451 void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5454 sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
5455 AppendLog(buffer,strlen(buffer),false);
5458 fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
5462 CurrentLinkOK = true;
5465 static void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5468 fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
5473 /* This function is used for parsing the RLP frame into fields. */
5474 void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
5481 /* We do not need RLP frame parsing to be done when we do not have callback
5483 if (CurrentRLP_RXCallback == NULL)
5486 /* Anybody know the official meaning of the first two bytes?
5487 Nokia 6150 sends junk frames starting D9 01, and real frames starting
5488 D9 00. We'd drop the junk frames anyway because the FCS is bad, but
5489 it's tidier to do it here. We still need to call the callback function
5490 to give it a chance to handle timeouts and/or transmit a frame */
5491 if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
5494 /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
5495 specification, so Header consists of 16 bits (2 bytes). See section 4.1
5496 of the specification. */
5498 frame.Header[0] = MessageBuffer[2];
5499 frame.Header[1] = MessageBuffer[3];
5501 /* Next 200 bits (25 bytes) contain the Information. We store the
5502 information in the Data array. */
5504 for (count = 0; count < 25; count ++)
5505 frame.Data[count] = MessageBuffer[4 + count];
5507 /* The last 24 bits (3 bytes) contain FCS. */
5509 frame.FCS[0] = MessageBuffer[29];
5510 frame.FCS[1] = MessageBuffer[30];
5511 frame.FCS[2] = MessageBuffer[31];
5513 /* Here we pass the frame down in the input stream. */
5514 CurrentRLP_RXCallback(valid ? &frame : NULL);
5517 static void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5520 fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
5527 void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5529 GSM_SMSMessage NullSMS;
5531 switch (MessageBuffer[6]) {
5533 case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
5534 case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
5536 /* Is it possible ? */
5537 case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
5538 default: NullSMS.Type = GST_UN; break;
5542 if (NullSMS.Type == GST_DR)
5543 fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
5545 fprintf(stdout, _("Message: SMS Message Received\n"));
5548 GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
5551 fprintf(stdout, _("\n"));
5555 #endif /* UCLINUX */
5557 void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5561 /* Switch on the basis of the message type byte */
5562 switch (MessageType) {
5564 /* Call information */
5567 N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
5573 switch (MessageBuffer[3]) {
5575 case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5576 case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
5577 case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5578 case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5579 case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5581 case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5582 default :unknown=true;break;
5585 #endif /* UCLINUX */
5587 /* Phonebook handling */
5589 switch (MessageBuffer[3]) {
5591 case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
5593 case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
5595 case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
5597 case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5599 case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5601 default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
5602 #endif /* UCLINUX */
5608 switch (MessageBuffer[3]) {
5609 case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
5610 default :unknown=true;break;
5615 /* Startup Logo, Operator Logo and Profiles. */
5617 switch (MessageBuffer[3]) {
5618 case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5619 case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5620 case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5621 case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5622 case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5623 case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5624 default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
5628 /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
5631 switch (MessageBuffer[3]) {
5633 case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
5634 default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
5638 /* Security code requests */
5640 switch (MessageBuffer[3]) {
5641 case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
5642 case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5643 default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5650 N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
5655 switch (MessageBuffer[3]) {
5656 case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
5657 default :unknown=true;break;
5661 /* Simulating key pressing */
5663 switch (MessageBuffer[3]) {
5664 case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
5665 default :unknown=true;break;
5671 switch (MessageBuffer[3]) {
5672 case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5673 case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
5674 case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5675 default :unknown=true;break;
5679 /* Phone Clock and Alarm */
5681 switch (MessageBuffer[3]) {
5682 case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
5683 case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
5684 case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
5685 case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
5686 default :unknown=true;break;
5690 /* Calendar notes handling */
5692 switch (MessageBuffer[3]) {
5693 case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5694 case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5695 case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
5696 default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
5702 switch (MessageBuffer[3]) {
5704 case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5706 case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5707 case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5709 case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
5710 default :unknown=true;break;
5716 switch (MessageBuffer[3]) {
5718 case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
5720 case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5722 case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5725 case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
5726 default :unknown=true;break;
5729 #endif /* UCLINUX */
5731 /* Internal phone functions? */
5733 switch (MessageBuffer[2]) {
5734 case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
5736 case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
5737 #endif /* UCLINUX */
5738 case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
5740 case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5741 case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5742 case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5743 case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
5744 case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
5745 case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5746 case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5747 case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
5748 case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5749 case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5750 #endif /* UCLINUX */
5751 case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
5752 default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
5757 /* Picture Images */
5760 N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
5762 #endif /* UCLINUX */
5764 /* Mobile phone identification */
5767 N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
5770 /***** Acknowlegment of our frames. *****/
5771 case FBUS_FRTYPE_ACK:
5773 N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
5776 /***** Power on message. *****/
5779 N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
5784 N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
5787 /***** RLP frame received. *****/
5790 N6110_RX_HandleRLPMessage(MessageBuffer);
5793 /***** Power on message. *****/
5796 N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
5799 /***** Unknown message *****/
5800 /* If you think that you know the exact meaning of other messages - please
5805 fprintf(stdout, _("Message: Unknown message type.\n"));
5807 AppendLogText("Unknown msg type\n",false);
5816 fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
5818 AppendLogText("Unknown msg\n",false);