5 A Linux/Unix toolset and driver for Nokia mobile phones.
7 Released under the terms of the GNU GPL, see file COPYING for more details.
9 This file provides an API for accessing functions on the 6110 and similar
16 /* "Turn on" prototypes in n-6110.h */
20 /* System header files */
26 #include "misc_win32.h"
29 /* Various header file */
35 #include "gsm-coding.h"
36 #include "newmodules/n6110.h"
37 #include "newmodules/n7110.h"
38 #include "protocol/fbus.h"
39 #include "devices/device.h"
40 /* Global variables used by code in gsm-api.c to expose the functions
41 supported by this model of phone. */
44 /* Here we initialise model specific functions. */
45 GSM_Functions N6110_Functions = {
47 N6110_DispatchMessage,
50 N6110_GetMemoryLocation,
51 N6110_WritePhonebookLocation,
54 N6110_GetMemoryStatus,
60 N6110_DeleteSMSMessage,
73 N6110_GetBatteryLevel,
76 N6110_GetDisplayStatus,
77 N6110_EnterSecurityCode,
78 N6110_GetSecurityCodeStatus,
79 N6110_GetSecurityCode,
104 N6110_GetIncomingCallNr,
105 N6110_GetNetworkInfo,
106 N6110_GetCalendarNote,
107 N6110_WriteCalendarNote,
108 N6110_DeleteCalendarNote,
114 N6110_SetBinRingTone,
115 N6110_GetBinRingTone,
142 N6110_EnableDisplayOutput,
143 N6110_DisableDisplayOutput,
144 N6110_EnableCellBroadcast,
145 N6110_DisableCellBroadcast,
146 N6110_ReadCellBroadcast,
148 N6110_GetProductProfileSetting,
149 N6110_SetProductProfileSetting,
150 N6110_GetOperatorName,
151 N6110_SetOperatorName,
152 N6110_GetVoiceMailbox, N6110_Tests,
154 UNIMPLEMENTED, //GetCalendarNotesInfo
156 N6110_ResetPhoneSettings,
157 N7110_GetWAPBookmark,
158 N7110_SetWAPBookmark,
159 N7110_GetWAPSettings,
176 NULL, //GetCalendarNotesInfo
185 N6110_GetManufacturer
188 /* Mobile phone information */
190 GSM_Information N6110_Information = {
191 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
192 /* Supported models in FBUS */
193 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
194 /* Supported models in MBUS */
195 "6110|6130|6150|8210|8850",
196 /* Supported models in FBUS over infrared */
198 /* Supported models in FBUS over DLR3 */
202 /* infrared sockets */
203 "6110|6130|6150|8210|8850",
204 /* Supported models in FBUS over infrared with Tekram device */
205 4, /* Max RF Level */
206 0, /* Min RF Level */
207 GRF_Arbitrary, /* RF level units */
208 4, /* Max Battery Level */
209 0, /* Min Battery Level */
210 GBU_Arbitrary, /* Battery level units */
211 GDT_DateTime, /* Have date/time support */
212 GDT_TimeOnly, /* Alarm supports time only */
213 1 /* Only one alarm available */
217 static const char *N6110_MemoryType_String [] = {
231 /* Magic bytes from the phone. */
232 static unsigned char MagicBytes[4] = { 0x00, 0x00, 0x00, 0x00 };
234 /* For DisplayOutput */
236 static char PhoneScreen[5+1][27+1];
237 static int OldX=1000,OldY=0,NewX=0,NewY=0;
240 void N6110_ReplyEnableExtendedCommands(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
243 fprintf(stdout, _("Message: Answer for EnableExtendedSecurityCommands frame, meaning not known :-(\n"));
246 CurrentEnableExtendedCommandsError=GE_NONE;
249 /* If you set make some things (for example,
250 change Security Code from phone's menu, disable and enable
251 phone), it won't answer for 0x40 frame - you won't be able
252 to play tones, get netmonitor, etc.
254 This function do thing called "Enabling extended security commands" -
255 it enables 0x40 frame functions.
257 This frame can also some other things - see below */
258 GSM_Error N6110_EnableExtendedCommands (unsigned char status)
260 unsigned char req[4] = { 0x00,
261 0x01,0x64, /* Enable extended commands request */
262 0x01 }; /* 0x01 - on, 0x00 - off,
263 0x03 & 0x04 - soft & hard reset,
264 0x06 - CONTACT SERVICE */
266 /* 0x06 MAKES CONTACT SERVICE! BE CAREFULL! */
267 /* When use 0x03 and had during session changed time & date
268 some phones (like 6150 or 6210) can ask for time & date after reset
269 or disable clock on the screen */
270 if (status!=0x06) req[3] = status;
272 return NULL_SendMessageSequence
273 (50, &CurrentEnableExtendedCommandsError, 4, 0x40, req);
276 void N6110_ReplyIMEI(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
278 #if defined WIN32 || !defined HAVE_SNPRINTF
279 sprintf(Current_IMEI, "%s", MessageBuffer+4);
281 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+4);
285 fprintf(stdout, _("Message: IMEI %s received\n"),Current_IMEI);
288 CurrentGetIMEIError=GE_NONE;
291 GSM_Error N6110_SendIMEIFrame()
293 unsigned char req[4] = {0x00, 0x01, 0x66, 0x00};
297 error=N6110_EnableExtendedCommands(0x01);
298 if (error!=GE_NONE) return error;
300 return NULL_SendMessageSequence (20, &CurrentGetIMEIError, 4, 0x40, req);
303 void N6110_ReplyHW(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
307 if (MessageBuffer[3]==0x05) {
310 fprintf(stdout,_("Message: Hardware version received: "));
313 j=strlen(Current_Revision);
314 Current_Revision[j++]=',';
315 Current_Revision[j++]=' ';
316 Current_Revision[j++]='H';
317 Current_Revision[j++]='W';
321 fprintf(stdout,_("%c"), MessageBuffer[i]);
323 Current_Revision[j++]=MessageBuffer[i];
327 fprintf(stdout,_("\n"));
330 CurrentGetHWError=GE_NONE;
334 GSM_Error N6110_SendHWFrame()
336 unsigned char req[4] = {0x00, 0x01, 0xc8, 0x05};
340 error=N6110_EnableExtendedCommands(0x01);
341 if (error!=GE_NONE) return error;
343 return NULL_SendMessageSequence (20, &CurrentGetHWError, 4, 0x40, req);
346 void N6110_ReplyID(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
351 fprintf(stdout, _("Message: Mobile phone model identification received:\n"));
352 fprintf(stdout, _(" Firmware: "));
355 strcpy(Current_Revision,"SW");
358 while (MessageBuffer[i]!=0x0a) {
359 Current_Revision[j]=MessageBuffer[i];
361 fprintf(stdout, _("%c"),MessageBuffer[i]);
363 if (j==GSM_MAX_REVISION_LENGTH-1) {
365 fprintf(stderr,_("ERROR: increase GSM_MAX_REVISION_LENGTH!\n"));
372 Current_Revision[j+1]=0;
375 fprintf(stdout, _("\n Firmware date: "));
379 while (MessageBuffer[i]!=0x0a) {
381 fprintf(stdout, _("%c"),MessageBuffer[i]);
387 fprintf(stdout, _("\n Model: "));
391 while (MessageBuffer[i]!=0x0a) {
392 Current_Model[j]=MessageBuffer[i];
394 fprintf(stdout, _("%c"),MessageBuffer[i]);
396 if (j==GSM_MAX_MODEL_LENGTH-1) {
398 fprintf(stderr,_("ERROR: increase GSM_MAX_MODEL_LENGTH!\n"));
405 Current_Model[j+1]=0;
408 fprintf(stdout, _("\n"));
411 CurrentMagicError=GE_NONE;
414 GSM_Error N6110_SendIDFrame()
416 unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
418 return NULL_SendMessageSequence (50, &CurrentMagicError, 5, 0xd1, req);
421 /* This function send the status request to the phone. */
422 /* Seems to be ignored in N3210 */
423 GSM_Error N6110_SendStatusRequest(void)
425 unsigned char req[] = {N6110_FRAME_HEADER, 0x01};
427 Protocol->SendMessage(4, 0x04, req);
432 static void N6110_ReplyGetAuthentication(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
436 #if defined WIN32 || !defined HAVE_SNPRINTF
437 sprintf(Current_IMEI, "%s", MessageBuffer+9);
438 sprintf(Current_Model, "%s", MessageBuffer+25);
439 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
441 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+9);
442 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+25);
443 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
447 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
448 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
449 fprintf(stdout, _(" Model: %s\n"), Current_Model);
450 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+31);
451 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+39);
452 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+44);
454 /* These bytes are probably the source of the "Accessory not connected"
455 messages on the phone when trying to emulate NCDS... I hope....
456 UPDATE: of course, now we have the authentication algorithm. */
457 fprintf(stdout, _(" Magic bytes: %02x %02x %02x %02x\n"), MessageBuffer[50], MessageBuffer[51], MessageBuffer[52], MessageBuffer[53]);
460 MagicBytes[0]=MessageBuffer[50];
461 MagicBytes[1]=MessageBuffer[51];
462 MagicBytes[2]=MessageBuffer[52];
463 MagicBytes[3]=MessageBuffer[53];
465 CurrentMagicError=GE_NONE;
468 /* This function provides Nokia authentication protocol.
470 This code is written specially for gnokii project by Odinokov Serge.
471 If you have some special requests for Serge just write him to
472 apskaita@post.omnitel.net or serge@takas.lt
474 Reimplemented in C by Pavel JanÃk ml.
476 Nokia authentication protocol is used in the communication between Nokia
477 mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software,
478 commercially sold by Nokia Corp.
480 The authentication scheme is based on the token send by the phone to the
481 software. The software does it's magic (see the function
482 FB61_GetNokiaAuth()) and returns the result back to the phone. If the
483 result is correct the phone responds with the message "Accessory
484 connected!" displayed on the LCD. Otherwise it will display "Accessory not
485 supported" and some functions will not be available for use.
487 The specification of the protocol is not publicly available, no comment. */
488 static void N6110_GetNokiaAuth(unsigned char *Imei, unsigned char *MagicBytes, unsigned char *MagicResponse)
493 /* This is our temporary working area. */
495 unsigned char Temp[16];
497 /* Here we put FAC (Final Assembly Code) and serial number into our area. */
508 /* And now the TAC (Type Approval Code). */
515 /* And now we pack magic bytes from the phone. */
517 Temp[12] = MagicBytes[0];
518 Temp[13] = MagicBytes[1];
519 Temp[14] = MagicBytes[2];
520 Temp[15] = MagicBytes[3];
522 for (i=0; i<=11; i++)
526 switch (Temp[15] & 0x03) {
533 Temp[i+j] ^= Temp[i+12];
541 Temp[i + j] |= Temp[i + 12];
544 for (i=0; i<=15; i++)
547 for (i=0; i<=15; i++) {
549 switch (Temp[15 - i] & 0x06) {
571 MagicResponse[i] = j;
576 static GSM_Error N6110_Authentication()
578 unsigned char connect1[] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x02};
579 unsigned char connect2[] = {N6110_FRAME_HEADER, 0x20, 0x02};
580 unsigned char connect3[] = {N6110_FRAME_HEADER, 0x0d, 0x01, 0x00, 0x02};
581 unsigned char connect4[] = {N6110_FRAME_HEADER, 0x10};
583 unsigned char magic_connect[] = {N6110_FRAME_HEADER,
586 /* The real magic goes here ... These bytes are filled in with the
587 function N6110_GetNokiaAuth(). */
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 /* NOKIA&GNOKII Accessory */
594 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x26, 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x20,
595 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x79,
597 0x00, 0x00, 0x00, 0x00};
600 fprintf(stdout,_("Making authentication!\n"));
603 usleep(100); Protocol->SendMessage(7, 0x02, connect1);
604 usleep(100); Protocol->SendMessage(5, 0x02, connect2);
605 usleep(100); Protocol->SendMessage(7, 0x02, connect3);
607 CurrentMagicError = GE_BUSY;
609 usleep(100); Protocol->SendMessage(4, 0x64, connect4);
610 if (NULL_WaitUntil(50,&CurrentMagicError)!=GE_NONE) return GE_TIMEOUT;
612 N6110_GetNokiaAuth(Current_IMEI, MagicBytes, magic_connect+4);
614 Protocol->SendMessage(45, 0x64, magic_connect);
617 fprintf(stdout,_("End of authentication!\n"));
623 /* Initialise variables and state machine. */
624 GSM_Error N6110_Initialise(char *port_device, char *initlength,
625 GSM_ConnectionType connection,
626 void (*rlp_callback)(RLP_F96Frame *frame))
628 unsigned char init_char = N6110_SYNC_BYTE;
630 unsigned char end_init_char = N6110_IR_END_SYNC_BYTE;
636 if (Protocol->Initialise(port_device,initlength,connection,rlp_callback)!=GE_NONE)
638 return GE_NOTSUPPORTED;
641 switch (CurrentConnectionType) {
645 /* We don't think about authentication in Irda, because
646 AFAIK there are no phones working over sockets
647 and having authentication. In MBUS it doesn't work */
650 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
652 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
654 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
656 CurrentLinkOK = true;
665 InitLength = atoi(initlength);
667 if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
668 InitLength = 250; /* This is the usual value, lower may work. */
672 if (CurrentConnectionType==GCT_Infrared ||
673 CurrentConnectionType==GCT_Tekram) {
675 fprintf(stdout,_("Setting infrared for FBUS communication...\n"));
677 device_changespeed(9600);
682 fprintf(stdout,_("Writing init chars...."));
685 /* Initialise link with phone or what have you */
686 /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
688 for (count = 0; count < InitLength; count ++) {
690 if (CurrentConnectionType!=GCT_Infrared &&
691 CurrentConnectionType!=GCT_Tekram)
694 Protocol->WritePhone(1,&init_char);
698 if (CurrentConnectionType==GCT_Infrared ||
699 CurrentConnectionType==GCT_Tekram) {
700 Protocol->WritePhone(1,&end_init_char);
706 fprintf(stdout,_("Done\n"));
710 if (CurrentConnectionType==GCT_Infrared ||
711 CurrentConnectionType==GCT_Tekram) {
712 device_changespeed(115200);
716 N6110_SendStatusRequest();
720 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
722 /* N51xx/61xx have something called authentication.
723 After making it phone display "Accessory connected"
724 and probably give access to some function (I'm not too sure about it !)
725 Anyway, I make it now for N51xx/61xx */
727 if (GetModelFeature (FN_AUTHENTICATION)!=0)
729 if (0/*Lace-hack:GetModelFeature (FN_AUTHENTICATION)!=0*/)
732 if (N6110_Authentication()!=GE_NONE) return GE_TIMEOUT;
733 } else { /* No authentication */
734 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
736 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
742 fprintf(stdout,_("Unknown connection type in n6110.c!\n"));
750 /* This function translates GMT_MemoryType to N6110_MEMORY_xx */
751 int N6110_GetMemoryType(GSM_MemoryType memory_type)
756 switch (memory_type) {
758 case GMT_MT: result = N6110_MEMORY_MT; break;
759 case GMT_ME: result = N6110_MEMORY_ME; break;
760 case GMT_SM: result = N6110_MEMORY_SM; break;
761 case GMT_FD: result = N6110_MEMORY_FD; break;
762 case GMT_ON: result = N6110_MEMORY_ON; break;
763 case GMT_EN: result = N6110_MEMORY_EN; break;
764 case GMT_DC: result = N6110_MEMORY_DC; break;
765 case GMT_RC: result = N6110_MEMORY_RC; break;
766 case GMT_MC: result = N6110_MEMORY_MC; break;
767 default : result = N6110_MEMORY_XX;
776 void N6110_ReplyCallDivert(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
778 switch (MessageBuffer[3]) {
783 fprintf(stdout, _("Message: Call divert status received\n"));
784 fprintf(stdout, _(" Divert type: "));
785 switch (MessageBuffer[6]) {
786 case 0x43: fprintf(stdout, _("when busy"));break;
787 case 0x3d: fprintf(stdout, _("when not answered"));break;
788 case 0x3e: fprintf(stdout, _("when phone off or no coverage"));break;
789 case 0x15: fprintf(stdout, _("all types of diverts"));break; //?
790 case 0x02: fprintf(stdout, _("all types of diverts"));break; //?
791 default: fprintf(stdout, _("unknown %i"),MessageBuffer[6]);break;
793 fprintf(stdout, _("\n Calls type : "));
794 if (MessageBuffer[6]==0x02)
795 fprintf(stdout, _("voice, fax & data")); //?
797 switch (MessageBuffer[8]) {
798 case 0x0b: fprintf(stdout, _("voice"));break;
799 case 0x0d: fprintf(stdout, _("fax"));break;
800 case 0x19: fprintf(stdout, _("data"));break;
801 default: fprintf(stdout, _("unknown %i"),MessageBuffer[8]);break;
804 fprintf(stdout, _("\n"));
805 if (MessageBuffer[10]==0x01) {
806 fprintf(stdout, _(" Status : active\n"));
807 fprintf(stdout, _(" Timeout : %i seconds\n"),MessageBuffer[45]);
808 fprintf(stdout, _(" Number : %s\n"),GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
810 fprintf(stdout, _(" Status : deactivated\n"));
814 switch (MessageBuffer[6]) {
815 case 0x43: CurrentCallDivert->DType=GSM_CDV_Busy;break;
816 case 0x3d: CurrentCallDivert->DType=GSM_CDV_NoAnswer;break;
817 case 0x3e: CurrentCallDivert->DType=GSM_CDV_OutOfReach;break;
818 case 0x15: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
819 case 0x02: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
822 if (MessageBuffer[6]==0x02) //?
823 CurrentCallDivert->CType=GSM_CDV_AllCalls;
825 switch (MessageBuffer[8]) {
826 case 0x0b: CurrentCallDivert->CType=GSM_CDV_VoiceCalls;break;
827 case 0x0d: CurrentCallDivert->CType=GSM_CDV_FaxCalls; break;
828 case 0x19: CurrentCallDivert->CType=GSM_CDV_DataCalls; break;
832 if (MessageBuffer[10]==0x01) {
833 CurrentCallDivert->Enabled=true;
834 CurrentCallDivert->Timeout=MessageBuffer[45];
835 strcpy(CurrentCallDivert->Number,GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
837 CurrentCallDivert->Enabled=false;
840 CurrentCallDivertError=GE_NONE;
845 fprintf(stdout, _("Message: Call divert status receiving error ?\n"));
847 CurrentCallDivertError=GE_UNKNOWN;
852 GSM_Error N6110_CallDivert(GSM_CallDivert *cd)
854 char req[55] = { N6110_FRAME_HEADER, 0x01,
855 0x00, /* operation */
857 0x00, /* divert type */
858 0x00, /* call type */
864 switch (cd->Operation) {
865 case GSM_CDV_Register:
869 req[29]= GSM_PackSemiOctetNumber(cd->Number, req + 9, false);
870 req[52]= cd->Timeout;
873 case GSM_CDV_Erasure:
874 case GSM_CDV_Disable:
881 return GE_NOTIMPLEMENTED;
885 case GSM_CDV_AllTypes : req[6] = 0x15; break;
886 case GSM_CDV_Busy : req[6] = 0x43; break;
887 case GSM_CDV_NoAnswer : req[6] = 0x3d; break;
888 case GSM_CDV_OutOfReach: req[6] = 0x3e; break;
889 default: return GE_NOTIMPLEMENTED;
892 if ((cd->DType == GSM_CDV_AllTypes) &&
893 (cd->CType == GSM_CDV_AllCalls))
897 case GSM_CDV_AllCalls : break;
898 case GSM_CDV_VoiceCalls: req[7] = 0x0b; break;
899 case GSM_CDV_FaxCalls : req[7] = 0x0d; break;
900 case GSM_CDV_DataCalls : req[7] = 0x19; break;
901 default: return GE_NOTIMPLEMENTED;
904 CurrentCallDivert = cd;
906 error=NULL_SendMessageSequence
907 (100, &CurrentCallDivertError, length, 0x06, req);
909 CurrentCallDivert = NULL;
914 GSM_Error N6110_Tests()
916 unsigned char buffer[3]={0x00,0x01,0xcf};
917 unsigned char buffer3[8]={0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00};
921 error=N6110_EnableExtendedCommands(0x01);
922 if (error!=GE_NONE) return error;
924 //make almost all tests
925 Protocol->SendMessage(8, 0x40, buffer3);
927 while (GSM->Initialise(PortDevice, "50", CurrentConnectionType, CurrentRLP_RXCallback)!=GE_NONE) {};
931 return NULL_SendMessageSequence
932 (200, &CurrentNetworkInfoError, 3, 0x40, buffer);
935 void N6110_DisplayTestsInfo(u8 *MessageBuffer) {
939 CurrentNetworkInfoError=GE_NONE;
941 for (i=0;i<MessageBuffer[3];i++) {
943 case 0: fprintf(stdout,_("Unknown(%i) "),i);break;
944 case 1: fprintf(stdout,_("MCU ROM checksum "));break;
945 case 2: fprintf(stdout,_("MCU RAM interface "));break;
946 case 3: fprintf(stdout,_("MCU RAM component "));break;
947 case 4: fprintf(stdout,_("MCU EEPROM interface "));break;
948 case 5: fprintf(stdout,_("MCU EEPROM component "));break;
949 case 6: fprintf(stdout,_("Real Time Clock battery "));break;
950 case 7: fprintf(stdout,_("CCONT interface "));break;
951 case 8: fprintf(stdout,_("AD converter "));break;
952 case 9: fprintf(stdout,_("SW Reset "));break;
953 case 10:fprintf(stdout,_("Power Off "));break;
954 case 11:fprintf(stdout,_("Security Data "));break;
955 case 12:fprintf(stdout,_("EEPROM Tune checksum "));break;
956 case 13:fprintf(stdout,_("PPM checksum "));break;
957 case 14:fprintf(stdout,_("MCU download DSP "));break;
958 case 15:fprintf(stdout,_("DSP alive "));break;
959 case 16:fprintf(stdout,_("COBBA serial "));break;
960 case 17:fprintf(stdout,_("COBBA paraller "));break;
961 case 18:fprintf(stdout,_("EEPROM security checksum"));break;
962 case 19:fprintf(stdout,_("PPM validity "));break;
963 case 20:fprintf(stdout,_("Warranty state "));break;
964 case 21:fprintf(stdout,_("Simlock check "));break;
965 case 22:fprintf(stdout,_("IMEI check? "));break;//from PC-Locals.is OK?
966 default:fprintf(stdout,_("Unknown(%i) "),i);break;
968 switch (MessageBuffer[4+i]) {
969 case 0: fprintf(stdout,_(" : done, result OK"));break;
970 case 0xff:fprintf(stdout,_(" : not done, result unknown"));break;
971 case 254: fprintf(stdout,_(" : done, result NOT OK"));break;
972 default: fprintf(stdout,_(" : result unknown(%i)"),MessageBuffer[4+i]);break;
974 fprintf(stdout,_("\n"));
978 void N6110_ReplySimlockInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
985 fprintf(stdout, _("Message: Simlock info received\n"));
988 for (i=0; i < 12; i++)
991 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] >> 4)));
994 if (j==5 || j==15) fprintf(stdout, _("\n"));
997 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] & 0x0f)));
1001 if (j==20 || j==24) fprintf(stdout, _("\n"));
1004 if ((MessageBuffer[6] & 1) == 1) fprintf(stdout,_("lock 1 closed\n"));
1005 if ((MessageBuffer[6] & 2) == 2) fprintf(stdout,_("lock 2 closed\n"));
1006 if ((MessageBuffer[6] & 4) == 4) fprintf(stdout,_("lock 3 closed\n"));
1007 if ((MessageBuffer[6] & 8) == 8) fprintf(stdout,_("lock 4 closed\n"));
1009 /* I'm not sure here at all */
1010 if ((MessageBuffer[5] & 1) == 1) fprintf(stdout,_("lock 1 - user\n"));
1011 if ((MessageBuffer[5] & 2) == 2) fprintf(stdout,_("lock 2 - user\n"));
1012 if ((MessageBuffer[5] & 4) == 4) fprintf(stdout,_("lock 3 - user\n"));
1013 if ((MessageBuffer[5] & 8) == 8) fprintf(stdout,_("lock 4 - user\n"));
1015 fprintf(stdout,_("counter for lock1: %i\n"),MessageBuffer[21]);
1016 fprintf(stdout,_("counter for lock2: %i\n"),MessageBuffer[22]);
1017 fprintf(stdout,_("counter for lock3: %i\n"),MessageBuffer[23]);
1018 fprintf(stdout,_("counter for lock4: %i\n"),MessageBuffer[24]);
1023 for (i=0; i < 12; i++)
1026 uni[j]='0' + (MessageBuffer[9+i] >> 4);
1031 uni[j]='0' + (MessageBuffer[9+i] & 0x0f);
1037 strncpy(CurrentSimLock->simlocks[0].data,uni,5);
1038 CurrentSimLock->simlocks[0].data[5]=0;
1039 strncpy(CurrentSimLock->simlocks[3].data,uni+5,10);
1040 CurrentSimLock->simlocks[3].data[10]=0;
1041 strncpy(CurrentSimLock->simlocks[1].data,uni+16,4);
1042 CurrentSimLock->simlocks[1].data[4]=0;
1043 strncpy(CurrentSimLock->simlocks[2].data,uni+20,4);
1044 CurrentSimLock->simlocks[2].data[4]=0;
1046 CurrentSimLock->simlocks[0].enabled=((MessageBuffer[6] & 1) == 1);
1047 CurrentSimLock->simlocks[1].enabled=((MessageBuffer[6] & 2) == 2);
1048 CurrentSimLock->simlocks[2].enabled=((MessageBuffer[6] & 4) == 4);
1049 CurrentSimLock->simlocks[3].enabled=((MessageBuffer[6] & 8) == 8);
1051 CurrentSimLock->simlocks[0].factory=((MessageBuffer[5] & 1) != 1);
1052 CurrentSimLock->simlocks[1].factory=((MessageBuffer[5] & 2) != 2);
1053 CurrentSimLock->simlocks[2].factory=((MessageBuffer[5] & 4) != 4);
1054 CurrentSimLock->simlocks[3].factory=((MessageBuffer[5] & 8) != 8);
1056 CurrentSimLock->simlocks[0].counter=MessageBuffer[21];
1057 CurrentSimLock->simlocks[1].counter=MessageBuffer[22];
1058 CurrentSimLock->simlocks[2].counter=MessageBuffer[23];
1059 CurrentSimLock->simlocks[3].counter=MessageBuffer[24];
1061 CurrentSimlockInfoError=GE_NONE;
1064 GSM_Error N6110_SimlockInfo(GSM_AllSimlocks *siml)
1067 unsigned char req[] = {0x00,0x01,0x8a,0x00};
1068 error=N6110_EnableExtendedCommands(0x01);
1069 if (error!=GE_NONE) return error;
1071 CurrentSimLock=siml;
1073 return NULL_SendMessageSequence (50, &CurrentSimlockInfoError, 4, 0x40, req);
1076 void N6110_ReplyResetPhoneSettings(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1079 fprintf(stdout, _("Message: Resetting phone settings\n"));
1082 CurrentResetPhoneSettingsError=GE_NONE;
1085 GSM_Error N6110_ResetPhoneSettings()
1088 unsigned char req[] = {0x00,0x01,0x65,0x08,0x00};
1089 error=N6110_EnableExtendedCommands(0x01);
1090 if (error!=GE_NONE) return error;
1092 return NULL_SendMessageSequence
1093 (50, &CurrentResetPhoneSettingsError, 5, 0x40, req);
1096 #endif /* UCLINUX */
1098 GSM_Error N6110_GetManufacturer(char *manufacturer)
1100 strcpy (manufacturer, "Nokia");
1106 GSM_Error N6110_GetVoiceMailbox ( GSM_PhonebookEntry *entry)
1108 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
1112 CurrentPhonebookEntry = entry;
1114 req[4] = N6110_MEMORY_VOICE;
1115 req[5] = 0x00; /* Location - isn't important, but... */
1117 error=NULL_SendMessageSequence
1118 (20, &CurrentPhonebookError, 7, 0x03, req);
1120 CurrentPhonebookEntry = NULL;
1125 void N6110_ReplyGetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1129 GSM_Bitmap NullBitmap;
1131 DecodeNetworkCode(MessageBuffer+5, NullBitmap.netcode);
1136 fprintf(stdout, _("Message: Info about downloaded operator name received: %s network (for gnokii \"%s\", for phone \""),
1138 GSM_GetNetworkName(NullBitmap.netcode));
1142 while (MessageBuffer[count]!=0) {
1144 fprintf(stdout,_("%c"),MessageBuffer[count]);
1149 strcpy(CurrentGetOperatorNameNetwork->Code, NullBitmap.netcode);
1150 strncpy(CurrentGetOperatorNameNetwork->Name, MessageBuffer+i,count-i+1);
1153 fprintf(stdout,_("\")\n"));
1156 CurrentGetOperatorNameError=GE_NONE;
1159 GSM_Error N6110_GetOperatorName (GSM_Network *operator)
1161 unsigned char req[] = { 0x00,0x01,0x8c,0x00};
1165 error=N6110_EnableExtendedCommands(0x01);
1166 if (error!=GE_NONE) return error;
1168 CurrentGetOperatorNameNetwork = operator;
1170 error=NULL_SendMessageSequence
1171 (20, &CurrentGetOperatorNameError, 4, 0x40, req);
1173 CurrentGetOperatorNameNetwork = NULL;
1178 void N6110_ReplySetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1181 fprintf(stdout, _("Message: Downloaded operator name changed\n"));
1184 CurrentSetOperatorNameError=GE_NONE;
1187 GSM_Error N6110_SetOperatorName (GSM_Network *operator)
1189 unsigned char req[256] = { 0x00,0x01,0x8b,0x00,
1190 0x00,0x00, /* MCC */
1195 error=N6110_EnableExtendedCommands(0x01);
1196 if (error!=GE_NONE) return error;
1198 EncodeNetworkCode(req+4,operator->Code);
1200 strncpy(req+7,operator->Name,200);
1202 return NULL_SendMessageSequence
1203 (20, &CurrentSetOperatorNameError, 8+strlen(operator->Name), 0x40, req);
1206 #endif /* UCLINUX */
1208 static void N6110_ReplyGetMemoryStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1210 switch (MessageBuffer[3]) {
1215 fprintf(stdout, _("Message: Memory status received:\n"));
1217 fprintf(stdout, _(" Memory Type: %s\n"), N6110_MemoryType_String[MessageBuffer[4]]);
1218 fprintf(stdout, _(" Used: %d\n"), MessageBuffer[6]);
1219 fprintf(stdout, _(" Free: %d\n"), MessageBuffer[5]);
1222 CurrentMemoryStatus->Used = MessageBuffer[6];
1223 CurrentMemoryStatus->Free = MessageBuffer[5];
1224 CurrentMemoryStatusError = GE_NONE;
1231 switch (MessageBuffer[4]) {
1233 fprintf(stdout, _("Message: Memory status error, phone is probably powered off.\n"));break;
1235 fprintf(stdout, _("Message: Memory status error, memory type not supported by phone model.\n"));break;
1237 fprintf(stdout, _("Message: Memory status error, waiting for security code.\n"));break;
1239 fprintf(stdout, _("Message: Unknown Memory status error, subtype (MessageBuffer[4]) = %02x\n"),MessageBuffer[4]);break;
1243 switch (MessageBuffer[4]) {
1244 case 0x6f:CurrentMemoryStatusError = GE_TIMEOUT;break;
1245 case 0x7d:CurrentMemoryStatusError = GE_INTERNALERROR;break;
1246 case 0x8d:CurrentMemoryStatusError = GE_INVALIDSECURITYCODE;break;
1255 /* This function is used to get storage status from the phone. It currently
1256 supports two different memory areas - internal and SIM. */
1257 GSM_Error N6110_GetMemoryStatus(GSM_MemoryStatus *Status)
1259 unsigned char req[] = { N6110_FRAME_HEADER,
1260 0x07, /* MemoryStatus request */
1261 0x00 /* MemoryType */
1266 CurrentMemoryStatus = Status;
1268 req[4] = N6110_GetMemoryType(Status->MemoryType);
1270 error=NULL_SendMessageSequence
1271 (20, &CurrentMemoryStatusError, 5, 0x03, req);
1273 CurrentMemoryStatus = NULL;
1280 void N6110_ReplyGetNetworkInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1282 GSM_NetworkInfo NullNetworkInfo;
1284 /* Make sure we are expecting NetworkInfo frame */
1285 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY) {
1287 fprintf(stdout, _("Message: Network informations:\n"));
1291 fprintf(stdout, _("Message: Network informations not requested, but received:\n"));
1295 sprintf(NullNetworkInfo.NetworkCode, "%x%x%x %x%x", MessageBuffer[14] & 0x0f, MessageBuffer[14] >>4, MessageBuffer[15] & 0x0f, MessageBuffer[16] & 0x0f, MessageBuffer[16] >>4);
1297 sprintf(NullNetworkInfo.CellID, "%02x%02x", MessageBuffer[10], MessageBuffer[11]);
1299 sprintf(NullNetworkInfo.LAC, "%02x%02x", MessageBuffer[12], MessageBuffer[13]);
1302 fprintf(stdout, _(" CellID: %s\n"), NullNetworkInfo.CellID);
1303 fprintf(stdout, _(" LAC: %s\n"), NullNetworkInfo.LAC);
1304 fprintf(stdout, _(" Network code: %s\n"), NullNetworkInfo.NetworkCode);
1305 fprintf(stdout, _(" Network name: %s (%s)\n"),
1306 GSM_GetNetworkName(NullNetworkInfo.NetworkCode),
1307 GSM_GetCountryName(NullNetworkInfo.NetworkCode));
1308 fprintf(stdout, _(" Status: "));
1310 switch (MessageBuffer[8]) {
1311 case 0x01: fprintf(stdout, _("home network selected")); break;
1312 case 0x02: fprintf(stdout, _("roaming network")); break;
1313 case 0x03: fprintf(stdout, _("requesting network")); break;
1314 case 0x04: fprintf(stdout, _("not registered in the network")); break;
1315 default: fprintf(stdout, _("unknown"));
1318 fprintf(stdout, "\n");
1320 fprintf(stdout, _(" Network selection: %s\n"), MessageBuffer[9]==1?_("manual"):_("automatic"));
1323 /* Make sure we are expecting NetworkInfo frame */
1324 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY)
1325 *CurrentNetworkInfo=NullNetworkInfo;
1327 CurrentNetworkInfoError = GE_NONE;
1330 GSM_Error N6110_GetNetworkInfo(GSM_NetworkInfo *NetworkInfo)
1332 unsigned char req[] = { N6110_FRAME_HEADER,
1338 CurrentNetworkInfo = NetworkInfo;
1340 error=NULL_SendMessageSequence
1341 (20, &CurrentNetworkInfoError, 4, 0x0a, req);
1343 CurrentNetworkInfo = NULL;
1348 void N6110_ReplyGetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1353 fprintf(stdout, _("Message: Product Profile Settings received -"));
1354 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),MessageBuffer[3+i]);
1355 fprintf(stdout, _("\n"));
1358 for (i=0;i<4;i++) CurrentPPS[i]=MessageBuffer[3+i];
1360 CurrentProductProfileSettingsError=GE_NONE;
1363 GSM_Error N6110_GetProductProfileSetting (GSM_PPS *PPS)
1365 unsigned char req[] = { 0x00, 0x01,0x6a };
1371 error=N6110_EnableExtendedCommands(0x01);
1372 if (error!=GE_NONE) return error;
1374 error=NULL_SendMessageSequence
1375 (20, &CurrentProductProfileSettingsError, 3, 0x40, req);
1376 if (error!=GE_NONE) return error;
1378 switch (PPS->Name) {
1379 case PPS_ALS : PPS->bool_value=(CurrentPPS[1]&32); break;
1380 case PPS_GamesMenu: PPS->bool_value=(CurrentPPS[3]&64); break;
1381 case PPS_HRData : PPS->bool_value=(CurrentPPS[0]&64); break;
1382 case PPS_14400Data: PPS->bool_value=(CurrentPPS[0]&128);break;
1383 case PPS_EFR : PPS->int_value =(CurrentPPS[0]&1) +(CurrentPPS[0]&2); break;
1384 case PPS_FR : PPS->int_value =(CurrentPPS[0]&16)/16+(CurrentPPS[0]&32)/16;break;
1385 case PPS_HR : PPS->int_value =(CurrentPPS[0]&4)/4 +(CurrentPPS[0]&8)/4; break;
1386 case PPS_VibraMenu: PPS->bool_value=(CurrentPPS[4]&64); break;
1387 case PPS_LCDContrast:
1391 if (CurrentPPS[3]&j) PPS->int_value=PPS->int_value+j;
1394 PPS->int_value=PPS->int_value*100/32;
1402 void N6110_ReplySetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1407 fprintf(stdout, _("Message: Product Profile Settings set to"));
1408 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),CurrentPPS[i]);
1409 fprintf(stdout, _("\n"));
1412 CurrentProductProfileSettingsError=GE_NONE;
1415 GSM_Error N6110_SetProductProfileSetting (GSM_PPS *PPS)
1417 unsigned char req[] = { 0x00, 0x01,0x6b,
1418 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */
1419 unsigned char settings[32];
1427 error=N6110_EnableExtendedCommands(0x01);
1428 if (error!=GE_NONE) return error;
1430 OldPPS.Name=PPS_ALS;
1431 error=N6110_GetProductProfileSetting(&OldPPS);
1432 if (error!=GE_NONE) return error;
1435 for (i=0;i<32;i++) {
1436 if (CurrentPPS[z]&j)
1447 fprintf(stdout,_("Current settings: "));
1448 for (i=0;i<32;i++) {
1449 fprintf(stdout,_("%c"),settings[i]);
1451 fprintf(stdout,_("\n"));
1454 switch (PPS->Name) {
1455 case PPS_ALS :settings[10]=PPS->bool_value?'1':'0';break;
1456 case PPS_HRData :settings[ 5]=PPS->bool_value?'1':'0';break;
1457 case PPS_14400Data:settings[ 6]=PPS->bool_value?'1':'0';break;
1462 for (i=0;i<32;i++) {
1463 if (settings[i]=='1') req[z+3]=req[z+3]+j;
1471 fprintf(stdout,_("Current settings: "));
1473 fprintf(stdout,_("%i "),req[i+3]);
1475 fprintf(stdout,_("\n"));
1479 CurrentPPS[i]=req[i+3];
1482 return NULL_SendMessageSequence
1483 (20, &CurrentProductProfileSettingsError, 7, 0x40, req);
1486 void N6110_ReplyPressKey(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1488 if (MessageBuffer[4]==CurrentPressKeyEvent) CurrentPressKeyError=GE_NONE;
1489 else CurrentPressKeyError=GE_UNKNOWN; /* MessageBuffer[4] = 0x05 */
1491 fprintf(stdout, _("Message: Result of key "));
1492 switch (MessageBuffer[4])
1494 case PRESSPHONEKEY: fprintf(stdout, _("press OK\n"));break;
1495 case RELEASEPHONEKEY: fprintf(stdout, _("release OK\n"));break;
1496 default: fprintf(stdout, _("press or release - error\n"));break;
1501 GSM_Error N6110_PressKey(int key, int event)
1503 unsigned char req[] = {N6110_FRAME_HEADER, 0x42, 0x01, 0x00, 0x01};
1505 req[4]=event; /* if we press or release key */
1508 CurrentPressKeyEvent=event;
1510 return NULL_SendMessageSequence
1511 (10, &CurrentPressKeyError, 7, 0x0c, req);
1514 void N6110_ReplyDisplayOutput(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1516 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
1523 switch(MessageBuffer[3]) {
1525 /* Phone sends displayed texts */
1527 NewX=MessageBuffer[6];
1528 NewY=MessageBuffer[5];
1530 DecodeUnicode (uni, MessageBuffer+8, MessageBuffer[7]);
1533 fprintf(stdout, _("New displayed text (%i %i): \"%s\"\n"),NewX,NewY,uni);
1536 while (N6110_GetModel(model) != GE_NONE)
1539 /* With these rules it works almost excellent with my N5110 */
1540 /* I don't have general rule :-(, that's why you must experiment */
1541 /* with your phone. Nokia could make it better. MW */
1542 /* It's almost OK for N5110*/
1543 /* FIX ME: it will be the same for N5130 and 3210 too*/
1544 if (!strcmp(model,"NSE-1"))
1546 /* OldX==1000 means - it's first time */
1550 for (i=0;i<5+1;i++) {
1551 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1556 if ((OldX==0 && OldY==31 && NewX==29 && NewY==46) ||
1557 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1558 /* Clean the line with current text */
1559 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1561 /* Inserts text into table */
1562 for (i=0; i<MessageBuffer[7];i++) {
1563 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1568 if ((OldX==0 && OldY==21 && NewX==0 && NewY==10) ||
1569 (OldX==0 && OldY==10 && NewX==35 && NewY==46)) {
1571 if ((OldX!=0 && NewX==0 && NewY!=6) ||
1572 (OldX==0 && NewX!=0 && OldY!=13 && OldY!=22) ||
1573 (OldX==0 && NewX==0 && NewY<OldY && (NewY!=13 || OldY!=26)) ||
1574 (OldY==5 && NewY!=5) ||
1575 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
1577 /* Writes "old" screen */
1578 for (i=0;i<5+1;i++) {
1579 for (j=0;j<27+1;j++) {fprintf(stdout,_("%c"),PhoneScreen[i][j]);}
1580 fprintf(stdout,_("\n"));
1584 for (i=0;i<5+1;i++) {
1585 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
1590 /* Clean the line with current text */
1591 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
1593 /* Inserts text into table */
1594 for (i=0; i<MessageBuffer[7];i++) {
1595 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
1602 fprintf(stdout, _("%s\n"),uni);
1610 if (MessageBuffer[4]==1)
1614 fprintf(stdout, _("Display output successfully disabled/enabled.\n"));
1617 CurrentDisplayOutputError=GE_NONE;
1624 GSM_Error SetDisplayOutput(unsigned char state)
1626 unsigned char req[] = { N6110_FRAME_HEADER,
1631 return NULL_SendMessageSequence
1632 (30, &CurrentDisplayOutputError, 5, 0x0d, req);
1635 GSM_Error N6110_EnableDisplayOutput()
1637 return SetDisplayOutput(0x01);
1640 GSM_Error N6110_DisableDisplayOutput()
1642 return SetDisplayOutput(0x02);
1645 /* If it is interesting for somebody: we can use 0x40 msg for it
1646 and it will work for all phones. See n6110.txt for details */
1647 GSM_Error N6110_AnswerCall(char s)
1649 unsigned char req0[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,0x07, 0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
1650 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80};
1651 unsigned char req[] = { N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
1656 fprintf(stdout,_("Answering call %d\n\r"),s);
1659 Protocol->SendMessage(sizeof(req0), 0x01, req0);
1662 return NULL_SendMessageSequence
1663 (20, &CurrentMagicError, sizeof(req) , 0x01, req);
1666 void N6110_ReplyGetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1668 switch (MessageBuffer[3]) {
1670 /* Profile feature */
1673 switch(GetModelFeature (FN_PROFILES)) {
1675 switch (MessageBuffer[6]) {
1676 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8]; break;
1677 case 0x01: CurrentProfile->CallAlert = MessageBuffer[8]; break;
1678 case 0x02: CurrentProfile->Ringtone = MessageBuffer[8]; break;
1679 case 0x03: CurrentProfile->Volume = MessageBuffer[8]; break;
1680 case 0x04: CurrentProfile->MessageTone = MessageBuffer[8]; break;
1681 case 0x05: CurrentProfile->Vibration = MessageBuffer[8]; break;
1682 case 0x06: CurrentProfile->WarningTone = MessageBuffer[8]; break;
1683 case 0x07: CurrentProfile->ScreenSaver = MessageBuffer[8]; break;
1686 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1692 switch (MessageBuffer[6]) {
1693 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8];break;
1694 case 0x01: CurrentProfile->Lights = MessageBuffer[8];break;
1695 case 0x02: CurrentProfile->CallAlert = MessageBuffer[8];break;
1696 case 0x03: CurrentProfile->Ringtone = MessageBuffer[8];break;
1697 case 0x04: CurrentProfile->Volume = MessageBuffer[8];break;
1698 case 0x05: CurrentProfile->MessageTone = MessageBuffer[8];break;
1699 case 0x06: CurrentProfile->Vibration = MessageBuffer[8];break;
1700 case 0x07: CurrentProfile->WarningTone = MessageBuffer[8];break;
1701 case 0x08: CurrentProfile->CallerGroups = MessageBuffer[8];break;
1702 case 0x09: CurrentProfile->AutomaticAnswer = MessageBuffer[8];break;
1705 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
1712 CurrentProfileError = GE_NONE;
1715 /* Incoming profile name */
1718 if (MessageBuffer[9] == 0x00) {
1719 CurrentProfile->DefaultName=MessageBuffer[8];
1721 CurrentProfile->DefaultName=-1;
1723 /* Here name is in Unicode */
1724 if (GetModelFeature (FN_PROFILES)==F_PROF33) {
1725 DecodeUnicode (CurrentProfile->Name, MessageBuffer+10, MessageBuffer[9]/2);
1728 sprintf(CurrentProfile->Name, MessageBuffer + 10, MessageBuffer[9]);
1729 CurrentProfile->Name[MessageBuffer[9]] = '\0';
1733 CurrentProfileError = GE_NONE;
1739 /* Needs SIM card with PIN in phone */
1740 GSM_Error N6110_GetProfile(GSM_Profile *Profile)
1744 unsigned char name_req[] = { N6110_FRAME_HEADER, 0x1a, 0x00};
1745 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x13, 0x01, 0x00, 0x00};
1749 CurrentProfile = Profile;
1751 /* When after sending all frames feature==253, it means, that it is not
1753 CurrentProfile->KeypadTone=253;
1754 CurrentProfile->Lights=253;
1755 CurrentProfile->CallAlert=253;
1756 CurrentProfile->Ringtone=253;
1757 CurrentProfile->Volume=253;
1758 CurrentProfile->MessageTone=253;
1759 CurrentProfile->WarningTone=253;
1760 CurrentProfile->Vibration=253;
1761 CurrentProfile->CallerGroups=253;
1762 CurrentProfile->ScreenSaver=253;
1763 CurrentProfile->AutomaticAnswer=253;
1765 name_req[4] = Profile->Number;
1767 error=NULL_SendMessageSequence
1768 (20, &CurrentProfileError, 5, 0x05, name_req);
1769 if (error!=GE_NONE) return error;
1771 for (i = 0x00; i <= 0x09; i++) {
1773 feat_req[5] = Profile->Number;
1777 error=NULL_SendMessageSequence
1778 (20, &CurrentProfileError, 7, 0x05, feat_req);
1779 if (error!=GE_NONE) return error;
1782 if (Profile->DefaultName > -1)
1784 switch(GetModelFeature (FN_PROFILES)) {
1786 switch (Profile->DefaultName) {
1787 case 0x00: sprintf(Profile->Name, "General");break;
1788 case 0x01: sprintf(Profile->Name, "Silent");break;
1789 case 0x02: sprintf(Profile->Name, "Descreet");break;
1790 case 0x03: sprintf(Profile->Name, "Loud");break;
1791 case 0x04: sprintf(Profile->Name, "My style");break;
1792 case 0x05: Profile->Name[0]=0;break;
1793 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1797 switch (Profile->DefaultName) {
1798 case 0x00: sprintf(Profile->Name, "Personal");break;
1799 case 0x01: sprintf(Profile->Name, "Car");break;
1800 case 0x02: sprintf(Profile->Name, "Headset");break;
1801 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1805 switch (Profile->DefaultName) {
1806 case 0x00: sprintf(Profile->Name, "General");break;
1807 case 0x01: sprintf(Profile->Name, "Silent");break;
1808 case 0x02: sprintf(Profile->Name, "Meeting");break;
1809 case 0x03: sprintf(Profile->Name, "Outdoor");break;
1810 case 0x04: sprintf(Profile->Name, "Pager");break;
1811 case 0x05: sprintf(Profile->Name, "Car");break;
1812 case 0x06: sprintf(Profile->Name, "Headset");break;
1813 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
1823 void N6110_ReplySetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1825 switch (MessageBuffer[3]) {
1827 /* Profile feature change result */
1830 fprintf(stdout, _("Message: Profile feature change result.\n"));
1832 CurrentProfileError = GE_NONE;
1835 /* Profile name set result */
1838 fprintf(stdout, _("Message: Profile name change result.\n"));
1840 CurrentProfileError = GE_NONE;
1846 GSM_Error N6110_SetProfileFeature(u8 profile, u8 feature, u8 value)
1848 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x10, 0x01,
1851 feat_req[5]=profile;
1852 feat_req[6]=feature;
1855 return NULL_SendMessageSequence
1856 (20, &CurrentProfileError, 8, 0x05, feat_req);
1859 GSM_Error N6110_SetProfile(GSM_Profile *Profile)
1863 unsigned char name_req[40] = { N6110_FRAME_HEADER, 0x1c, 0x01, 0x03,
1868 name_req[7] = Profile->Number;
1869 name_req[8] = strlen(Profile->Name);
1870 name_req[6] = name_req[8] + 2;
1872 for (i = 0; i < name_req[8]; i++)
1873 name_req[9 + i] = Profile->Name[i];
1875 error=NULL_SendMessageSequence
1876 (20, &CurrentProfileError, name_req[8] + 9, 0x05, name_req);
1877 if (error!=GE_NONE) return error;
1879 for (i = 0x00; i <= 0x09; i++) {
1882 case 0x00: value = Profile->KeypadTone; break;
1883 case 0x01: value = Profile->Lights; break;
1884 case 0x02: value = Profile->CallAlert; break;
1885 case 0x03: value = Profile->Ringtone; break;
1886 case 0x04: value = Profile->Volume; break;
1887 case 0x05: value = Profile->MessageTone; break;
1888 case 0x06: value = Profile->Vibration; break;
1889 case 0x07: value = Profile->WarningTone; break;
1890 case 0x08: value = Profile->CallerGroups; break;
1891 case 0x09: value = Profile->AutomaticAnswer; break;
1892 default : value = 0; break;
1895 error=N6110_SetProfileFeature(Profile->Number,i,value);
1896 if (error!=GE_NONE) return error;
1902 #endif /* UCLINUX */
1904 bool N6110_SendRLPFrame(RLP_F96Frame *frame, bool out_dtx)
1906 u8 req[60] = { 0x00, 0xd9 };
1908 /* Discontinuos transmission (DTX). See section 5.6 of GSM 04.22 version
1914 memcpy(req+2, (u8 *) frame, 32);
1916 return (Protocol->SendFrame(32, 0xf0, req));
1921 void N6110_ReplyGetCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
1929 switch (MessageBuffer[4]) {
1933 CurrentCalendarNote->Type=MessageBuffer[8];
1935 DecodeDateTime(MessageBuffer+9, &CurrentCalendarNote->Time);
1937 DecodeDateTime(MessageBuffer+16, &CurrentCalendarNote->Alarm);
1939 CurrentCalendarNote->Text[0]=0;
1941 if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
1943 if (CurrentCalendarNote->Type == GCN_REMINDER) i=1; //first char is subset
1944 switch (MessageBuffer[24]) {
1947 fprintf(stdout,_("Subset 3 in reminder note !\n"));
1949 while (i!=MessageBuffer[23]) {
1951 if (i!=MessageBuffer[23]-1) {
1952 if (MessageBuffer[24+i]>=0xc2) {
1953 DecodeWithUTF8Alphabet(MessageBuffer[24+i], MessageBuffer[24+i+1], &mychar1);
1954 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1955 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=mychar1;
1961 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1962 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=MessageBuffer[24+i];
1969 fprintf(stdout,_("Subset 2 in reminder note !\n"));
1971 while (i!=MessageBuffer[23]) {
1972 wc = MessageBuffer[24+i] | (0x00 << 8);
1973 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
1974 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=
1975 DecodeWithUnicodeAlphabet(wc);
1981 fprintf(stdout,_("Subset 1 in reminder note !\n"));
1983 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1984 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1988 fprintf(stdout,_("Unknown subset in reminder note !\n"));
1990 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
1991 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
1995 memcpy(CurrentCalendarNote->Text,MessageBuffer+24,MessageBuffer[23]);
1996 CurrentCalendarNote->Text[MessageBuffer[23]]=0;
1999 if (CurrentCalendarNote->Type == GCN_CALL) {
2000 memcpy(CurrentCalendarNote->Phone,MessageBuffer+24+MessageBuffer[23]+1,MessageBuffer[24+MessageBuffer[23]]);
2001 CurrentCalendarNote->Phone[MessageBuffer[24+MessageBuffer[23]]]=0;
2004 CurrentCalendarNote->Recurrance=0;
2006 CurrentCalendarNote->AlarmType=0;
2009 fprintf(stdout, _("Message: Calendar note received.\n"));
2011 fprintf(stdout, _(" Date: %d-%02d-%02d\n"), CurrentCalendarNote->Time.Year,
2012 CurrentCalendarNote->Time.Month,
2013 CurrentCalendarNote->Time.Day);
2015 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentCalendarNote->Time.Hour,
2016 CurrentCalendarNote->Time.Minute,
2017 CurrentCalendarNote->Time.Second);
2019 /* Some messages do not have alarm set up */
2020 if (CurrentCalendarNote->Alarm.Year != 0) {
2021 fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"), CurrentCalendarNote->Alarm.Year,
2022 CurrentCalendarNote->Alarm.Month,
2023 CurrentCalendarNote->Alarm.Day);
2025 fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"), CurrentCalendarNote->Alarm.Hour,
2026 CurrentCalendarNote->Alarm.Minute,
2027 CurrentCalendarNote->Alarm.Second);
2030 fprintf(stdout, _(" Type: %d\n"), CurrentCalendarNote->Type);
2031 fprintf(stdout, _(" Text: %s\n"), CurrentCalendarNote->Text);
2033 if (CurrentCalendarNote->Type == GCN_CALL)
2034 fprintf(stdout, _(" Phone: %s\n"), CurrentCalendarNote->Phone);
2037 CurrentCalendarNoteError=GE_NONE;
2043 fprintf(stdout, _("Message: Calendar note not available\n"));
2046 CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;
2052 fprintf(stdout, _("Message: Calendar note error\n"));
2055 CurrentCalendarNoteError=GE_INTERNALERROR;
2061 GSM_Error N6110_GetCalendarNote(GSM_CalendarNote *CalendarNote)
2064 unsigned char req[] = { N6110_FRAME_HEADER,
2069 req[4]=CalendarNote->Location;
2071 CurrentCalendarNote = CalendarNote;
2073 error=NULL_SendMessageSequence
2074 (20, &CurrentCalendarNoteError, 5, 0x13, req);
2076 CurrentCalendarNote = NULL;
2081 void N6110_ReplyWriteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2084 switch(MessageBuffer[4]) {
2085 /* This message is also sent when the user enters the new entry on keypad */
2087 fprintf(stdout, _("Message: Calendar note write succesfull!\n"));break;
2089 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2091 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
2093 fprintf(stdout, _("Unknown message of type 0x13 and subtype 0x65\n"));break;
2097 switch(MessageBuffer[4]) {
2098 case 0x01: CurrentCalendarNoteError=GE_NONE; break;
2099 case 0x73: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2100 case 0x7d: CurrentCalendarNoteError=GE_INTERNALERROR; break;
2101 default : AppendLogText("Unknown msg\n",false); break;
2105 GSM_Error N6110_WriteCalendarNote(GSM_CalendarNote *CalendarNote)
2108 unsigned char req[200] = { N6110_FRAME_HEADER,
2110 0x00, /* Length of the rest of the frame. */
2111 0x00, /* The type of calendar note */
2112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2119 unsigned char meeting;
2120 unsigned char birthday;
2121 unsigned char reminder;
2122 } calendar_model_length;
2124 /* Length of entries */
2125 calendar_model_length calendar_lengths[] =
2127 /*model,CallTo,Meeting,Birthday,Reminder*/
2128 {"NHM-5",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2129 {"NHM-6",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
2130 {"NSE-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 [HKEY_LOCAL_MACHINE\Software\Nokia\Data Suite\3.0\Calendar]
2131 {"NSM-1",0x1e,0x18,0x18,0x24}, //from NCDS3
2132 {"NSK-3",0x1e,0x14,0x14,0x1e}, //from NCDS3
2133 {"NSB-3",0x20,0x14,0x14,0x1e}, //from NCDS3
2134 {"", 0, 0, 0, 0 } //end of table
2145 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
2148 req[7]=CalendarNote->Type;
2150 EncodeDateTime(req+8, &CalendarNote->Time);
2151 req[14] = CalendarNote->Time.Timezone;
2153 if (CalendarNote->Alarm.Year) {
2154 EncodeDateTime(req+15, &CalendarNote->Alarm);
2155 req[21] = CalendarNote->Alarm.Timezone;
2158 req[22]=strlen(CalendarNote->Text);
2162 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2163 req[22]++; // one additional char
2164 req[current++]=0x01; //we use now subset 1
2167 for (i=0; i<strlen(CalendarNote->Text); i++) {
2169 mychar=CalendarNote->Text[i];
2170 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
2171 if (EncodeWithUTF8Alphabet(mychar,&mychar1,&mychar2)) {
2172 req[current++]=mychar1;
2173 req[current++]=mychar2;
2174 req[23]=0x03; //use subset 3
2175 req[22]++; // one additional char
2180 /* Enables/disables blinking */
2181 if (mychar=='~') req[current++]=0x01;
2182 else req[current++]=mychar;
2186 req[current++]=strlen(CalendarNote->Phone);
2188 for (i=0; i<strlen(CalendarNote->Phone); i++)
2189 req[current++]=CalendarNote->Phone[i];
2191 while (N6110_GetModel(model) != GE_NONE)
2194 /* Checking maximal length */
2196 while (strcmp(calendar_lengths[i].model,"")) {
2197 if (!strcmp(calendar_lengths[i].model,model)) {
2198 switch (CalendarNote->Type) {
2199 case GCN_REMINDER:if (req[22]>calendar_lengths[i].reminder) return GE_TOOLONG;break;
2200 case GCN_MEETING :if (req[22]>calendar_lengths[i].meeting) return GE_TOOLONG;break;
2201 case GCN_BIRTHDAY:if (req[22]>calendar_lengths[i].birthday) return GE_TOOLONG;break;
2202 case GCN_CALL :if (strlen(CalendarNote->Phone)>calendar_lengths[i].call) return GE_TOOLONG;break;
2209 CurrentCalendarNote = CalendarNote;
2211 error=NULL_SendMessageSequence
2212 (20, &CurrentCalendarNoteError, current, 0x13, req);
2214 CurrentCalendarNote = NULL;
2219 void N6110_ReplyDeleteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2222 switch (MessageBuffer[4]) {
2223 /* This message is also sent when the user deletes an old entry on
2224 keypad or moves an old entry somewhere (there is also `write'
2226 case 0x01:fprintf(stdout, _("Message: Calendar note deleted\n"));break;
2227 case 0x93:fprintf(stdout, _("Message: Calendar note can't be deleted\n"));break;
2228 default :fprintf(stdout, _("Message: Calendar note deleting error\n"));break;
2232 switch (MessageBuffer[4]) {
2233 case 0x01:CurrentCalendarNoteError=GE_NONE;break;
2234 case 0x93:CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;break;
2235 default :CurrentCalendarNoteError=GE_INTERNALERROR;break;
2239 GSM_Error N6110_DeleteCalendarNote(GSM_CalendarNote *CalendarNote)
2242 unsigned char req[] = { N6110_FRAME_HEADER,
2246 req[4]=CalendarNote->Location;
2248 return NULL_SendMessageSequence (20, &CurrentCalendarNoteError, 5, 0x13, req);
2251 #endif /* UCLINUX */
2253 static void N6110_ReplyRFBatteryLevel(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2256 fprintf(stdout, _("Message: Phone status received:\n"));
2257 fprintf(stdout, _(" Mode: "));
2259 switch (MessageBuffer[4]) {
2263 fprintf(stdout, _("registered within the network\n"));
2266 /* I was really amazing why is there a hole in the type of 0x02, now I
2268 case 0x02: fprintf(stdout, _("call in progress\n")); break; /* ringing or already answered call */
2269 case 0x03: fprintf(stdout, _("waiting for security code\n")); break;
2270 case 0x04: fprintf(stdout, _("powered off\n")); break;
2271 default : fprintf(stdout, _("unknown\n"));
2275 fprintf(stdout, _(" Power source: "));
2277 switch (MessageBuffer[7]) {
2279 case 0x01: fprintf(stdout, _("AC/DC\n")); break;
2280 case 0x02: fprintf(stdout, _("battery\n")); break;
2281 default : fprintf(stdout, _("unknown\n"));
2285 fprintf(stdout, _(" Battery Level: %d\n"), MessageBuffer[8]);
2286 fprintf(stdout, _(" Signal strength: %d\n"), MessageBuffer[5]);
2289 CurrentRFLevel=MessageBuffer[5];
2290 CurrentBatteryLevel=MessageBuffer[8];
2291 CurrentPowerSource=MessageBuffer[7];
2295 GSM_Error N6110_GetRFLevel(GSM_RFUnits *units, float *level)
2298 /* FIXME - these values are from 3810 code, may be incorrect. Map from
2299 values returned in status packet to the the values returned by the AT+CSQ
2301 float csq_map[5] = {0, 8, 16, 24, 31};
2306 char screen[NM_MAX_SCREEN_WIDTH];
2310 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2313 if (N6110_NetMonitor(1, screen)!=GE_NONE)
2314 return GE_INTERNALERROR;
2315 #endif /* UCLINUX */
2319 if (screen[4]!='-') {
2320 if (screen[5]=='9' && screen[6]>'4') rf_level=1;
2321 if (screen[5]=='9' && screen[6]<'5') rf_level=2;
2322 if (screen[5]=='8' && screen[6]>'4') rf_level=3;
2325 /* Arbitrary units. */
2326 if (*units == GRF_Arbitrary) {
2332 N6110_SendStatusRequest();
2334 /* Wait for timeout or other error. */
2335 while (timeout != 0 && CurrentRFLevel == -1 ) {
2338 return (GE_TIMEOUT);
2343 /* Make copy in case it changes. */
2344 rf_level = CurrentRFLevel;
2349 /* Now convert between the different units we support. */
2351 /* Arbitrary units. */
2352 if (*units == GRF_Arbitrary) {
2358 if (*units == GRF_CSQ) {
2361 *level = csq_map[rf_level];
2363 *level = 99; /* Unknown/undefined */
2369 /* Unit type is one we don't handle so return error */
2370 return (GE_INTERNALERROR);
2374 GSM_Error N6110_GetBatteryLevel(GSM_BatteryUnits *units, float *level)
2379 char screen[NM_MAX_SCREEN_WIDTH];
2381 CurrentBatteryLevel=-1;
2383 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2386 if (N6110_NetMonitor(23, screen)!=GE_NONE)
2388 #endif /* UCLINUX */
2392 if (screen[29]=='7') batt_level=3;
2393 if (screen[29]=='5') batt_level=2;
2394 if (screen[29]=='2') batt_level=1;
2396 /* Only units we handle at present are GBU_Arbitrary */
2397 if (*units == GBU_Arbitrary) {
2398 *level = batt_level;
2402 return (GE_INTERNALERROR);
2405 N6110_SendStatusRequest();
2407 /* Wait for timeout or other error. */
2408 while (timeout != 0 && CurrentBatteryLevel == -1 ) {
2411 return (GE_TIMEOUT);
2416 /* Take copy in case it changes. */
2417 batt_level = CurrentBatteryLevel;
2419 if (batt_level != -1) {
2421 /* Only units we handle at present are GBU_Arbitrary */
2422 if (*units == GBU_Arbitrary) {
2423 *level = batt_level;
2427 return (GE_INTERNALERROR);
2434 GSM_Error N6110_GetPowerSource(GSM_PowerSource *source)
2439 char screen[NM_MAX_SCREEN_WIDTH];
2441 CurrentPowerSource=-1;
2443 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
2446 if (N6110_NetMonitor(20, screen)!=GE_NONE)
2448 #endif /* UCLINUX */
2450 CurrentPowerSource=GPS_ACDC;
2452 if (screen[6]=='x') CurrentPowerSource=GPS_BATTERY;
2454 *source=CurrentPowerSource;
2458 N6110_SendStatusRequest();
2460 /* Wait for timeout or other error. */
2461 while (timeout != 0 && CurrentPowerSource == -1 ) {
2464 return (GE_TIMEOUT);
2469 if (CurrentPowerSource != -1) {
2470 *source=CurrentPowerSource;
2480 static void N6110_ReplyGetDisplayStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2484 for (i=0; i<MessageBuffer[4];i++)
2485 if (MessageBuffer[2*i+6]==2)
2486 CurrentDisplayStatus|=1<<(MessageBuffer[2*i+5]-1);
2488 CurrentDisplayStatus&= (0xff - (1<<(MessageBuffer[2*i+5]-1)));
2491 fprintf(stdout, _("Call in progress: %s\n"), CurrentDisplayStatus & (1<<DS_Call_In_Progress)?"on":"off");
2492 fprintf(stdout, _("Unknown: %s\n"), CurrentDisplayStatus & (1<<DS_Unknown)?"on":"off");
2493 fprintf(stdout, _("Unread SMS: %s\n"), CurrentDisplayStatus & (1<<DS_Unread_SMS)?"on":"off");
2494 fprintf(stdout, _("Voice call: %s\n"), CurrentDisplayStatus & (1<<DS_Voice_Call)?"on":"off");
2495 fprintf(stdout, _("Fax call active: %s\n"), CurrentDisplayStatus & (1<<DS_Fax_Call)?"on":"off");
2496 fprintf(stdout, _("Data call active: %s\n"), CurrentDisplayStatus & (1<<DS_Data_Call)?"on":"off");
2497 fprintf(stdout, _("Keyboard lock: %s\n"), CurrentDisplayStatus & (1<<DS_Keyboard_Lock)?"on":"off");
2498 fprintf(stdout, _("SMS storage full: %s\n"), CurrentDisplayStatus & (1<<DS_SMS_Storage_Full)?"on":"off");
2501 CurrentDisplayStatusError=GE_NONE;
2504 GSM_Error N6110_GetDisplayStatus(int *Status) {
2506 unsigned char req[4]={ N6110_FRAME_HEADER, 0x51 };
2510 error=NULL_SendMessageSequence
2511 (10, &CurrentDisplayStatusError, 4, 0x0d, req);
2512 if (error!=GE_NONE) return error;
2514 *Status=CurrentDisplayStatus;
2519 GSM_Error N6110_DialVoice(char *Number) {
2520 /* This commented sequence doesn't work on N3210/3310/6210/7110 */
2521 // unsigned char req[64]={N6110_FRAME_HEADER, 0x01};
2522 // unsigned char req_end[]={0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};
2524 // req[4]=strlen(Number);
2525 // for(i=0; i < strlen(Number) ; i++)
2526 // req[5+i]=Number[i];
2527 // memcpy(req+5+strlen(Number), req_end, 10);
2528 // return NULL_SendMessageSequence
2529 // (20, &CurrentDialVoiceError, 13+strlen(Number), 0x01, req);
2531 unsigned char req[64]={0x00,0x01,0x7c,
2532 0x01}; //call command
2538 error=N6110_EnableExtendedCommands(0x01);
2539 if (error!=GE_NONE) return error;
2541 for(i=0; i < strlen(Number) ; i++) req[4+i]=Number[i];
2545 return NULL_SendMessageSequence
2546 (20, &CurrentDialVoiceError, 4+strlen(Number)+1, 0x40, req);
2549 #endif /* UCLINUX */
2551 /* Dial a data call - type specifies request to use:
2552 type 0 should normally be used
2553 type 1 should be used when calling a digital line - corresponds to ats35=0
2554 Maybe one day we'll know what they mean!
2556 GSM_Error N6110_DialData(char *Number, char type, void (* callpassup)(char c))
2558 unsigned char req[100] = { N6110_FRAME_HEADER, 0x01 };
2559 unsigned char *req_end;
2560 unsigned char req_end0[] = { 0x01, /* make a data call = type 0x01 */
2561 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2562 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00 };
2563 unsigned char req_end1[] = { 0x01,
2564 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2565 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2566 0x88,0x90,0x21,0x48,0x40,0xbb };
2567 unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2568 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2569 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
2570 unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2571 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2572 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
2573 unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
2574 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2575 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
2576 0x20,0x15,0x63,0x80 };
2581 CurrentCallPassup=callpassup;
2586 size = sizeof(req_end0);
2589 Protocol->SendMessage(sizeof(req3), 0x01, req3);
2591 Protocol->SendMessage(sizeof(req4), 0x01, req4);
2594 size = sizeof(req_end1);
2596 case -1: /* Just used to set the call passup */
2601 size = sizeof(req_end0);
2605 req[4] = strlen(Number);
2607 for(i = 0; i < strlen(Number) ; i++)
2608 req[5+i] = Number[i];
2610 memcpy(req + 5 + strlen(Number), req_end, size);
2612 Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);
2614 if (type != 1) Protocol->SendMessage(26, 0x01, req2);
2621 GSM_Error N6110_GetIncomingCallNr(char *Number)
2624 if (*CurrentIncomingCall != ' ') {
2625 strcpy(Number, CurrentIncomingCall);
2632 #endif /* UCLINUX */
2634 GSM_Error N6110_CancelCall(void)
2636 // This frame & method works only on 61xx/51xx
2637 // unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
2638 // req[4]=CurrentCallSequenceNumber;
2639 // Protocol->SendMessage(6, 0x01, req);
2644 unsigned char req[]={0x00,0x01,0x7c,0x03};
2647 error=N6110_EnableExtendedCommands(0x01);
2648 if (error!=GE_NONE) return error;
2650 return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
2655 void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2657 switch(MessageBuffer[3]) {
2661 fprintf(stdout, _("Message: Security code accepted.\n"));
2663 CurrentSecurityCodeError = GE_NONE;
2668 fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
2670 CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
2674 GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
2677 unsigned char req[15] = { N6110_FRAME_HEADER,
2678 0x0a, /* Enter code request. */
2679 0x00 /* Type of the entered code. */
2683 req[4]=SecurityCode.Type;
2685 for (i=0; i<strlen(SecurityCode.Code);i++)
2686 req[5+i]=SecurityCode.Code[i];
2688 req[5+strlen(SecurityCode.Code)]=0x00;
2689 req[6+strlen(SecurityCode.Code)]=0x00;
2691 return NULL_SendMessageSequence
2692 (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
2695 void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2697 *CurrentSecurityCodeStatus = MessageBuffer[4];
2700 fprintf(stdout, _("Message: Security Code status received: "));
2702 switch(*CurrentSecurityCodeStatus) {
2704 case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;
2705 case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;
2706 case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;
2707 case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;
2708 case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;
2709 case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;
2710 default : fprintf(stdout, _("Unknown!\n"));
2715 CurrentSecurityCodeError = GE_NONE;
2718 GSM_Error N6110_GetSecurityCodeStatus(int *Status)
2721 unsigned char req[4] = { N6110_FRAME_HEADER,
2725 CurrentSecurityCodeStatus=Status;
2727 return NULL_SendMessageSequence
2728 (20, &CurrentSecurityCodeError, 4, 0x08, req);
2731 void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2736 fprintf(stdout, _("Message: Security code received: "));
2737 switch (MessageBuffer[3]) {
2738 case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;
2739 case GSCT_Pin: fprintf(stdout, _("PIN"));break;
2740 case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;
2741 case GSCT_Puk: fprintf(stdout, _("PUK"));break;
2742 case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;
2743 default: fprintf(stdout, _("unknown !"));break;
2745 if (MessageBuffer[4]==1) {
2746 fprintf(stdout, _(" allowed, value \""));
2747 if (MessageBuffer[3]==GSCT_SecurityCode) {
2748 for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2750 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2751 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2752 for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2754 fprintf(stdout, _("\""));
2756 fprintf(stdout, _(" not allowed"));
2758 fprintf(stdout, _("\n"));
2761 if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
2762 && MessageBuffer[4]==1) { /* It's allowed */
2763 if (MessageBuffer[3]==GSCT_SecurityCode) {
2764 for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2765 CurrentSecurityCode->Code[5]=0;
2767 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2768 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2769 for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2770 CurrentSecurityCode->Code[4]=0;
2772 CurrentSecurityCodeError=GE_NONE;
2774 CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
2777 GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
2780 unsigned char req[4] = { 0x00,
2781 0x01,0x6e, /* Get code request. */
2782 0x00 }; /* Type of the requested code. */
2786 error=N6110_EnableExtendedCommands(0x01);
2787 if (error!=GE_NONE) return error;
2789 req[3]=SecurityCode->Type;
2791 CurrentSecurityCode=SecurityCode;
2793 return NULL_SendMessageSequence
2794 (20, &CurrentSecurityCodeError, 4, 0x40, req);
2797 void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2800 fprintf(stdout, _("Message: answer for PlayTone frame\n"));
2803 CurrentPlayToneError=GE_NONE;
2806 GSM_Error N6110_PlayTone(int Herz, u8 Volume)
2808 unsigned char req[6] = { 0x00,0x01,0x8f,
2811 0x00 }; /* HerzHi */
2815 /* PlayTone wasn't used earlier */
2816 if (CurrentPlayToneError==GE_UNKNOWN) {
2817 if (CurrentConnectionType!=GCT_MBUS)
2818 CurrentDisableKeepAlive=true;
2820 error=N6110_EnableExtendedCommands(0x01);
2821 if (error!=GE_NONE) return error;
2824 /* For Herz==255*255 we have silent */
2825 if (Herz!=255*255) {
2838 /* For Herz==255*255 we have silent and additionaly
2839 we wait for phone answer - it's important for MBUS */
2840 if (Herz==255*255) {
2841 error=NULL_SendMessageSequence
2842 (20, &CurrentPlayToneError, 6, 0x40, req);
2844 CurrentPlayToneError=GE_UNKNOWN;
2845 CurrentDisableKeepAlive=false;
2847 if (error!=GE_NONE) return error;
2849 Protocol->SendMessage(6,0x40,req);
2852 error=NULL_SendMessageSequence
2853 (20, &CurrentPlayToneError, 6, 0x40, req);
2855 /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
2856 if (Herz==255*255) {
2857 CurrentPlayToneError=GE_UNKNOWN;
2858 CurrentDisableKeepAlive=false;
2861 if (error!=GE_NONE) return error;
2868 void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2870 if (MessageBuffer[4]==0x01) {
2871 DecodeDateTime(MessageBuffer+8, CurrentDateTime);
2874 fprintf(stdout, _("Message: Date and time\n"));
2875 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
2876 fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
2879 CurrentDateTime->IsSet=true;
2883 fprintf(stdout, _("Message: Date and time not set in phone\n"));
2886 CurrentDateTime->IsSet=false;
2889 CurrentDateTimeError=GE_NONE;
2892 GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
2894 return N6110_PrivGetDateTime(date_time,0x11);
2897 GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
2899 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
2901 CurrentDateTime=date_time;
2903 return NULL_SendMessageSequence
2904 (50, &CurrentDateTimeError, 4, msgtype, req);
2907 void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2910 fprintf(stdout, _("Message: Alarm\n"));
2911 fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
2912 fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
2915 CurrentAlarm->Hour=MessageBuffer[9];
2916 CurrentAlarm->Minute=MessageBuffer[10];
2917 CurrentAlarm->Second=0;
2919 CurrentAlarm->IsSet=(MessageBuffer[8]==2);
2921 CurrentAlarmError=GE_NONE;
2924 GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
2926 return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
2929 GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
2931 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
2933 CurrentAlarm=date_time;
2935 return NULL_SendMessageSequence
2936 (50, &CurrentAlarmError, 4, msgtype, req);
2939 void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2941 switch (MessageBuffer[3]) {
2945 CurrentMessageCenter->No=MessageBuffer[4];
2946 CurrentMessageCenter->Format=MessageBuffer[6];
2947 CurrentMessageCenter->Validity=MessageBuffer[8];
2948 sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
2950 sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
2952 sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
2955 fprintf(stdout, _("Message: SMS Center received:\n"));
2956 fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
2957 fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
2958 fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
2960 fprintf(stdout, _(" SMS Center message format is "));
2962 switch (CurrentMessageCenter->Format) {
2964 case GSMF_Text : fprintf(stdout, _("Text")); break;
2965 case GSMF_Paging: fprintf(stdout, _("Paging")); break;
2966 case GSMF_Fax : fprintf(stdout, _("Fax")); break;
2967 case GSMF_Email : fprintf(stdout, _("Email")); break;
2968 default : fprintf(stdout, _("Unknown"));
2971 fprintf(stdout, "\n");
2973 fprintf(stdout, _(" SMS Center message validity is "));
2975 switch (CurrentMessageCenter->Validity) {
2977 case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;
2978 case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;
2979 case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;
2980 case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;
2981 case GSMV_1_Week : fprintf(stdout, _("1 week")); break;
2982 case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;
2983 default : fprintf(stdout, _("Unknown"));
2986 fprintf(stdout, "\n");
2990 CurrentMessageCenterError=GE_NONE;
2996 /* Number of entries depends on SIM card */
2999 fprintf(stdout, _("Message: SMS Center error received:\n"));
3000 fprintf(stdout, _(" The request for SMS Center failed.\n"));
3003 /* FIXME: appropriate error. */
3004 CurrentMessageCenterError=GE_INTERNALERROR;
3011 /* This function sends to the mobile phone a request for the SMS Center */
3012 GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
3014 unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
3015 0x00 /* SMS Center Number. */
3018 req[5]=MessageCenter->No;
3020 CurrentMessageCenter=MessageCenter;
3022 return NULL_SendMessageSequence
3023 (50, &CurrentMessageCenterError, 6, 0x02, req);
3026 void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3029 fprintf(stdout, _("Message: SMS Center correctly set.\n"));
3031 CurrentMessageCenterError=GE_NONE;
3034 /* This function set the SMS Center profile on the phone. */
3035 GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
3037 unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
3038 0x00, /* SMS Center Number. */
3039 0x00, /* Unknown. */
3040 0x00, /* SMS Message Format. */
3041 0x00, /* Unknown. */
3042 0x00, /* Validity. */
3043 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
3044 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
3045 /* Message Center Name. */
3048 req[5]=MessageCenter->No;
3049 req[7]=MessageCenter->Format;
3050 req[9]=MessageCenter->Validity;
3052 req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
3054 req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
3056 sprintf(req+34, "%s", MessageCenter->Name);
3058 CurrentMessageCenter=MessageCenter;
3060 return NULL_SendMessageSequence
3061 (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
3064 void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3066 switch (MessageBuffer[3]) {
3071 fprintf(stdout, _("Message: SMS Status Received\n"));
3072 fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
3073 fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
3076 CurrentSMSStatus->UnRead = MessageBuffer[11];
3077 CurrentSMSStatus->Number = MessageBuffer[10];
3079 CurrentSMSStatusError = GE_NONE;
3085 fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
3088 CurrentSMSStatusError = GE_INTERNALERROR;
3094 GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
3096 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
3098 CurrentSMSStatus = Status;
3100 return NULL_SendMessageSequence
3101 (10, &CurrentSMSStatusError, 5, 0x14, req);
3104 GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
3108 strcpy(folders->Folder[0].Name,"Inbox");
3109 strcpy(folders->Folder[1].Name,"Outbox");
3114 #endif /* UCLINUX */
3116 GSM_Error N6110_GetIMEI(char *imei)
3118 if (strlen(Current_IMEI)>0) {
3119 strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
3123 return (GE_TRYAGAIN);
3126 GSM_Error N6110_GetRevision(char *revision)
3129 if (strlen(Current_Revision)>0) {
3130 strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
3134 return (GE_TRYAGAIN);
3137 static GSM_Error N6110_GetModel(char *model)
3139 if (strlen(Current_Model)>0) {
3140 strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
3144 return (GE_TRYAGAIN);
3149 void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3151 switch (MessageBuffer[4]) {
3155 fprintf(stdout, _("Message: Date and time set correctly\n"));
3157 CurrentSetDateTimeError=GE_NONE;
3162 fprintf(stdout, _("Message: Date and time setting error\n"));
3164 CurrentSetDateTimeError=GE_INVALIDDATETIME;
3169 /* Needs SIM card with PIN in phone */
3170 GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
3172 return N6110_PrivSetDateTime(date_time,0x11);
3175 /* Needs SIM card with PIN in phone */
3176 GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
3179 unsigned char req[] = { N6110_FRAME_HEADER,
3180 0x60, /* set-time subtype */
3181 0x01, 0x01, 0x07, /* unknown */
3182 0x00, 0x00, /* Year (0x07cf = 1999) */
3183 0x00, 0x00, /* Month Day */
3184 0x00, 0x00, /* Hours Minutes */
3185 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3188 EncodeDateTime(req+7, date_time);
3190 return NULL_SendMessageSequence
3191 (20, &CurrentSetDateTimeError, 14, msgtype, req);
3194 void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3196 switch (MessageBuffer[4]) {
3200 fprintf(stdout, _("Message: Alarm set correctly\n"));
3202 CurrentSetAlarmError=GE_NONE;
3207 fprintf(stdout, _("Message: Alarm setting error\n"));
3209 CurrentSetAlarmError=GE_INVALIDDATETIME;
3214 /* FIXME: we should also allow to set the alarm off :-) */
3215 GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
3217 return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
3220 /* FIXME: we should also allow to set the alarm off :-) */
3221 GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
3224 unsigned char req[] = { N6110_FRAME_HEADER,
3225 0x6b, /* set-alarm subtype */
3226 0x01, 0x20, 0x03, /* unknown */
3227 0x02, /* should be alarm on/off, but it don't works */
3228 0x00, 0x00, /* Hours Minutes */
3229 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3232 req[8] = date_time->Hour;
3233 req[9] = date_time->Minute;
3235 return NULL_SendMessageSequence
3236 (50, &CurrentSetAlarmError, 11, msgtype, req);
3239 #endif /* UCLINUX */
3241 static void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3243 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
3248 switch (MessageBuffer[3]) {
3252 CurrentPhonebookEntry->Empty = true;
3254 count=MessageBuffer[5];
3257 fprintf(stdout, _("Message: Phonebook entry received:\n"));
3258 fprintf(stdout, _(" Name: "));
3260 for (tmp=0; tmp <count; tmp++)
3262 if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
3263 if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
3264 fprintf(stdout, "%c", MessageBuffer[6+tmp]);
3267 fprintf(stdout, "\n");
3270 while (N6110_GetModel(model) != GE_NONE)
3273 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3275 DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
3276 CurrentPhonebookEntry->Name[count/2] = 0x00;
3278 fprintf(stderr,"FATAL ERROR: DecodeUnicode disabled!\n");
3280 #endif /* UCLINUX */
3282 memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);
3283 CurrentPhonebookEntry->Name[count] = 0x00;
3286 CurrentPhonebookEntry->Empty = false;
3288 for (tmp=0; tmp <count; tmp++)
3290 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3291 /* We check only 1'st, 3'rd, ... char */
3292 if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking
3293 if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents
3295 if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking
3296 if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents
3301 count=MessageBuffer[6+count];
3304 fprintf(stdout, _(" Number: "));
3306 for (tmp=0; tmp <count; tmp++)
3307 fprintf(stdout, "%c", MessageBuffer[i+tmp]);
3309 fprintf(stdout, "\n");
3312 memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);
3313 CurrentPhonebookEntry->Number[count] = 0x00;
3314 CurrentPhonebookEntry->Group = MessageBuffer[i+count];
3316 /* Phone doesn't have entended phonebook */
3317 CurrentPhonebookEntry->SubEntriesCount = 0;
3319 /* But for these memories data is saved and we can save it using 7110/6210 style */
3320 if (CurrentPhonebookEntry->MemoryType==GMT_DC ||
3321 CurrentPhonebookEntry->MemoryType==GMT_RC ||
3322 CurrentPhonebookEntry->MemoryType==GMT_MC) {
3323 CurrentPhonebookEntry->SubEntriesCount = 1;
3324 CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;
3325 CurrentPhonebookEntry->SubEntries[0].NumberType=0;
3326 CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;
3327 DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);
3330 fprintf(stdout, _(" Date: "));
3331 fprintf(stdout, "%02u.%02u.%04u\n",
3332 CurrentPhonebookEntry->SubEntries[0].data.Date.Day,
3333 CurrentPhonebookEntry->SubEntries[0].data.Date.Month,
3334 CurrentPhonebookEntry->SubEntries[0].data.Date.Year);
3335 fprintf(stdout, _(" Time: "));
3336 fprintf(stdout, "%02u:%02u:%02u\n",
3337 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,
3338 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,
3339 CurrentPhonebookEntry->SubEntries[0].data.Date.Second);
3342 /* These values are set, when date and time unavailable in phone.
3343 Values from 3310 - in other can be different */
3344 if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&
3345 CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&
3346 CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&
3347 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&
3348 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&
3349 CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)
3350 CurrentPhonebookEntry->SubEntriesCount = 0;
3353 /* Signal no error to calling code. */
3354 CurrentPhonebookError = GE_NONE;
3361 fprintf(stdout, _("Message: Phonebook read entry error received:\n"));
3364 switch (MessageBuffer[4]) {
3368 fprintf(stdout, _(" Invalid memory type!\n"));
3370 CurrentPhonebookError = GE_INVALIDMEMORYTYPE;
3375 fprintf(stdout, _(" Unknown error!\n"));
3377 CurrentPhonebookError = GE_INTERNALERROR;
3385 /* Routine to get specifed phone book location. Designed to be called by
3386 application. Will block until location is retrieved or a timeout/error
3388 GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)
3390 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
3392 CurrentPhonebookEntry = entry;
3394 req[4] = N6110_GetMemoryType(entry->MemoryType);
3395 req[5] = entry->Location;
3397 return NULL_SendMessageSequence
3398 (50, &CurrentPhonebookError, 7, 0x03, req);
3401 static void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3403 switch (MessageBuffer[3]) {
3408 fprintf(stdout, _("Message: Phonebook written correctly.\n"));
3410 CurrentPhonebookError = GE_NONE;
3415 switch (MessageBuffer[4]) {
3416 /* FIXME: other errors? When I send the phonebook with index of 350 it
3417 still report error 0x7d :-( */
3420 fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));
3422 CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;
3427 fprintf(stdout, _(" Unknown error!\n"));
3429 CurrentPhonebookError = GE_INTERNALERROR;
3434 /* Routine to write phonebook location in phone. Designed to be called by
3435 application code. Will block until location is written or timeout
3437 GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)
3439 unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };
3442 req[4] = N6110_GetMemoryType(entry->MemoryType);
3443 req[5] = entry->Location;
3447 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {
3450 req[6] = strlen(entry->Name)*2;
3452 EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
3454 for (i=0; i<strlen(entry->Name); i++)
3456 /* here we encode "special" chars */
3457 if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
3458 if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
3461 current+=strlen(entry->Name)*2;
3465 fprintf(stderr,"FATAL ERROR: EncodeUnicode disabled!\n");
3468 #endif /* UCLINUX */
3471 req[6] = strlen(entry->Name);
3473 for (i=0; i<strlen(entry->Name); i++)
3475 req[current+i] = entry->Name[i];
3477 /* here we encode "special" chars */
3478 if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
3479 if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
3482 current+=strlen(entry->Name);
3485 req[current++]=strlen(entry->Number);
3487 for (i=0; i<strlen(entry->Number); i++)
3488 req[current+i] = entry->Number[i];
3490 current+=strlen(entry->Number);
3492 /* Jano: This allow to save 14 characters name into SIM memory, when
3493 No Group is selected. */
3494 if (entry->Group == 5)
3495 req[current++]=0xff;
3497 req[current++]=entry->Group;
3499 return NULL_SendMessageSequence
3500 (50, &CurrentPhonebookError, current, 0x03, req);
3505 void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3507 switch(MessageBuffer[3]) {
3511 fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
3513 CurrentNetmonitorError=GE_NONE;
3518 fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
3519 fprintf(stdout, "%s\n", MessageBuffer+4);
3522 strcpy(CurrentNetmonitor, MessageBuffer+4);
3524 CurrentNetmonitorError=GE_NONE;
3528 GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
3530 unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
3534 error=N6110_EnableExtendedCommands(0x01);
3535 if (error!=GE_NONE) return error;
3537 CurrentNetmonitor=Screen;
3541 return NULL_SendMessageSequence
3542 (20, &CurrentNetmonitorError, 4, 0x40, req);
3545 /* Doesn't work in N3210. */
3546 /* In other allow to access phone menu without SIM card (just send any sequence) */
3547 GSM_Error N6110_SendDTMF(char *String)
3549 unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
3550 0x00 /* Length of DTMF string. */
3553 u8 length=strlen(String);
3555 if (length>59) length=59;
3559 memcpy(req+5,String,length);
3561 return NULL_SendMessageSequence
3562 (20, &CurrentSendDTMFError, 5+length, 0x01, req);
3565 #endif /* UCLINUX */
3567 static void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3569 switch (MessageBuffer[3]) {
3573 switch (MessageBuffer[4]) {
3574 case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
3575 default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
3578 CurrentSpeedDialEntry->Location = MessageBuffer[5];
3581 fprintf(stdout, _("Message: Speed dial entry received:\n"));
3582 fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
3583 fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
3584 fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
3587 CurrentSpeedDialError=GE_NONE;
3593 fprintf(stdout, _("Message: Speed dial entry error\n"));
3595 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3601 GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
3604 unsigned char req[] = { N6110_FRAME_HEADER,
3606 0x00 /* The number of speed dial. */
3609 CurrentSpeedDialEntry = entry;
3611 req[4] = entry->Number;
3613 return NULL_SendMessageSequence
3614 (20, &CurrentSpeedDialError, 5, 0x03, req);
3617 static void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3619 switch (MessageBuffer[3]) {
3624 fprintf(stdout, _("Message: Speed dial entry set.\n"));
3626 CurrentSpeedDialError=GE_NONE;
3632 fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
3634 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3640 GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
3643 unsigned char req[] = { N6110_FRAME_HEADER,
3646 0x00, /* Memory Type */
3650 req[4] = entry->Number;
3652 switch (entry->MemoryType) {
3653 case GMT_ME: req[5] = 0x02;
3654 default : req[5] = 0x03;
3657 req[6] = entry->Location;
3659 return NULL_SendMessageSequence
3660 (20, &CurrentSpeedDialError, 7, 0x03, req);
3665 /* This function finds parts of SMS in frame used in new Nokia phones
3666 in internal protocols (they're coded according to GSM 03.40), copies them
3667 to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
3668 GSM_ETSISMSMessage to GSM_SMSMessage structure */
3669 GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
3671 SMS_MessageType PDU=SMS_Deliver;
3672 GSM_ETSISMSMessage ETSI;
3675 ETSI.firstbyte=req[12];
3677 /* See GSM 03.40 section 9.2.3.1 */
3678 if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
3679 if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
3682 case SMS_Submit : offset=5;break;
3683 case SMS_Deliver : offset=4;break;
3684 case SMS_Status_Report: offset=3;break;
3688 for (i=0;i<req[0]+1;i++)
3689 ETSI.SMSCNumber[i]=req[i];
3691 for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
3692 ETSI.Number[i]=req[i+12+offset];
3696 ETSI.TPDCS=req[10+offset];
3697 ETSI.TPUDL=req[11+offset];
3698 ETSI.TPVP=0; //no support for now
3699 ETSI.TPPID=0; //no support for now
3700 for(i=31+offset;i<length;i++)
3701 ETSI.MessageText[i-31-offset]=req[i];
3704 ETSI.TPDCS=req[10+offset];
3705 ETSI.TPUDL=req[11+offset];
3706 ETSI.TPPID=0; //no support for now
3707 for(i=31+offset;i<length;i++)
3708 ETSI.MessageText[i-31-offset]=req[i];
3710 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3712 case SMS_Status_Report:
3714 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3715 ETSI.TPStatus=req[14];
3717 ETSI.SMSCDateTime[i]=req[i+34];
3723 GSM_DecodeETSISMS(SMS, &ETSI);
3730 void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3734 switch (MessageBuffer[3]) {
3738 switch (MessageBuffer[7]) {
3741 CurrentSMSMessage->Type = GST_SMS;
3742 CurrentSMSMessage->folder=GST_INBOX;
3747 CurrentSMSMessage->Type = GST_DR;
3748 CurrentSMSMessage->folder=GST_INBOX;
3753 CurrentSMSMessage->Type = GST_SMS;
3754 CurrentSMSMessage->folder=GST_OUTBOX;
3759 CurrentSMSMessage->Type = GST_UN;
3765 /* Field Short Message Status - MessageBuffer[4] seems not to be
3766 compliant with GSM 07.05 spec.
3767 Meaning Nokia protocol GMS spec
3768 ----------------------------------------------------
3769 MO Sent 0x05 0x07 or 0x01
3770 MO Not sent 0x07 0x06 or 0x00
3771 MT Read 0x01 0x05 or 0x01
3772 MT Not read 0x03 0x04 or 0x00
3773 ----------------------------------------------------
3774 See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
3778 if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
3779 else CurrentSMSMessage->Status = GSS_SENTREAD;
3782 fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
3784 if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
3785 fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
3787 fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
3790 if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
3791 if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
3793 if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
3794 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
3795 else fprintf(stdout, _(" Not sent\n"));
3797 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
3798 else fprintf(stdout, _(" Not read\n"));
3802 CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
3804 CurrentSMSMessage->MemoryType = MessageBuffer[5];
3805 CurrentSMSMessage->MessageNumber = MessageBuffer[6];
3807 /* Signal no error to calling code. */
3808 CurrentSMSMessageError = GE_NONE;
3811 fprintf(stdout, "\n");
3818 /* We have requested invalid or empty location. */
3821 fprintf(stdout, _("Message: SMS reading failed\n"));
3823 switch (MessageBuffer[4]) {
3825 fprintf(stdout, _(" Invalid location!\n"));break;
3827 fprintf(stdout, _(" Empty SMS location.\n"));break;
3829 fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
3831 fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
3835 switch (MessageBuffer[4]) {
3836 case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3837 case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
3838 case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
3839 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3847 GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
3850 unsigned char req[] = { N6110_FRAME_HEADER,
3853 0x00, /* Location */
3858 /* State machine code writes data to these variables when it comes in. */
3860 CurrentSMSMessage = message;
3861 CurrentSMSMessageError = GE_BUSY;
3863 req[5] = message->Location;
3866 Protocol->SendMessage(8, 0x02, req);
3868 /* Wait for timeout or other error. */
3869 while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
3872 return (GE_TIMEOUT);
3877 return (CurrentSMSMessageError);
3880 void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3883 fprintf(stdout, _("Message: SMS deleted successfully.\n"));
3886 CurrentSMSMessageError = GE_NONE;
3889 GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
3891 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
3893 req[5] = message->Location;
3895 return NULL_SendMessageSequence
3896 (50, &CurrentSMSMessageError, 6, 0x14, req);
3899 /* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
3900 GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
3902 GSM_ETSISMSMessage ETSI;
3905 GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
3908 for (i=0;i<36;i++) req[i]=0;
3910 req[12]=ETSI.firstbyte;
3912 for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
3913 req[i]=ETSI.SMSCNumber[i];
3918 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3919 req[i+12+offset]=ETSI.Number[i];
3920 req[10+offset]=ETSI.TPDCS;
3921 req[11+offset]=ETSI.TPUDL;
3922 req[24+offset]=ETSI.TPVP;
3924 // fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
3925 // fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
3926 // fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
3928 // req[]=ETSI.TPPID;
3929 for(i=0;i<*length;i++)
3930 req[i+31+offset]=ETSI.MessageText[i];
3935 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3936 req[i+12+offset]=ETSI.Number[i];
3937 req[10+offset]=ETSI.TPDCS;
3938 req[11+offset]=ETSI.TPUDL;
3939 // req[]=ETSI.TPPID;
3940 for(i=0;i<*length;i++)
3941 req[i+31+offset]=ETSI.MessageText[i];
3943 req[24+offset+i]=ETSI.DeliveryDateTime[i];
3949 *length=*length+offset;
3954 void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3956 switch (MessageBuffer[3]) {
3958 /* SMS message correctly sent to the network */
3961 fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
3963 CurrentSMSMessageError = GE_SMSSENDOK;
3966 /* SMS message send to the network failed */
3970 fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
3972 switch (MessageBuffer[6]) {
3973 case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3974 case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
3975 case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3976 case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
3977 case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3978 case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3979 case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3980 case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3981 case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3984 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
3985 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
3988 CurrentSMSMessageError = GE_SMSSENDFAILED;
3994 GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
3998 unsigned char req[256] = {
4000 0x01, 0x02, 0x00, /* SMS send request*/
4005 error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
4006 if (error != GE_NONE) return error;
4008 return NULL_SendMessageSequence
4009 (200, &CurrentSMSMessageError, 42+length, 0x02, req);
4012 void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4014 switch (MessageBuffer[3]) {
4019 fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
4022 CurrentSMSMessage->MessageNumber=MessageBuffer[5];
4024 CurrentSMSMessageError = GE_NONE;
4029 fprintf(stdout, _("SMS saving failed\n"));
4030 switch (MessageBuffer[4]) {
4031 case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
4032 case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
4033 default :fprintf(stdout, _(" Unknown error.\n"));break;
4037 switch (MessageBuffer[4]) {
4038 case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
4039 case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
4040 default :CurrentSMSMessageError = GE_UNKNOWN;break;
4045 /* GST_DR and GST_UN not supported ! */
4046 GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
4048 unsigned char req[256] = {
4049 N6110_FRAME_HEADER, 0x04, /* SMS save request*/
4050 0x00, /* SMS Status. Different for Inbox and Outbox */
4052 0x00, /* SMS Location */
4053 0x02, /* SMS Type */
4057 SMS_MessageType PDU;
4060 if (SMS->Location) req[6] = SMS->Location;
4062 if (SMS->folder==0) { /*Inbox*/
4063 req[4]=1; /* SMS Status */
4064 req[7] = 0x00; /* SMS Type */
4067 req[4]=5; /* SMS Status */
4068 req[7] = 0x02; /* SMS Type */
4072 if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
4074 error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
4075 if (error != GE_NONE) return error;
4077 CurrentSMSMessage = SMS;
4079 return NULL_SendMessageSequence
4080 (70, &CurrentSMSMessageError, 39+length, 0x14, req);
4083 void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4086 fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
4089 CurrentCBError = GE_NONE;
4092 /* Enable and disable Cell Broadcasting */
4093 GSM_Error N6110_EnableCellBroadcast(void)
4095 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4096 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
4099 fprintf (stdout,"Enabling CB\n");
4102 CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
4103 CurrentCBMessage->Channel = 0;
4104 CurrentCBMessage->New = false;
4105 strcpy (CurrentCBMessage->Message,"");
4107 return NULL_SendMessageSequence
4108 (10, &CurrentCBError, 10, 0x02, req);
4112 GSM_Error N6110_DisableCellBroadcast(void)
4114 /* Should work, but not tested fully */
4116 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
4119 return NULL_SendMessageSequence
4120 (10, &CurrentCBError, 10, 0x02, req);
4123 void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4126 unsigned char output[160];
4128 CurrentCBMessage->Channel = MessageBuffer[7];
4129 CurrentCBMessage->New = true;
4130 tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
4133 fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
4135 fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
4139 for (i=0; i<tmp;i++) {
4140 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
4143 fprintf(stdout, "\n");
4146 for (i=0; i<tmp; i++) {
4147 CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
4149 CurrentCBMessage->Message[i]=0;
4152 GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
4155 fprintf(stdout,"Reading CB\n");
4158 if (CurrentCBMessage != NULL)
4160 if (CurrentCBMessage->New == true)
4163 fprintf(stdout,"New CB received\n");
4165 Message->Channel = CurrentCBMessage->Channel;
4166 strcpy(Message->Message,CurrentCBMessage->Message);
4167 CurrentCBMessage->New = false;
4171 return (GE_NONEWCBRECEIVED);
4174 int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
4178 req[count++]=Bitmap.number;
4179 req[count++]=strlen(Bitmap.text);
4180 memcpy(req+count,Bitmap.text,req[count-1]);
4181 count+=req[count-1];
4182 req[count++]=Bitmap.ringtone;
4184 /* Setting for graphic:
4187 0x02 - View Graphics
4188 0x03 - Send Graphics
4190 You can even set it higher but Nokia phones (my
4191 6110 at least) will not show you the name of this
4192 item in menu ;-)) Nokia is really joking here. */
4193 if (Bitmap.enabled) req[count++]=0x01;
4194 else req[count++]=0x00;
4196 req[count++]=(Bitmap.size+4)>>8;
4197 req[count++]=(Bitmap.size+4)%0xff;
4198 req[count++]=0x00; /* Future extensions! */
4199 req[count++]=Bitmap.width;
4200 req[count++]=Bitmap.height;
4201 req[count++]=0x01; /* Just BW */
4202 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4204 return count+Bitmap.size;
4207 int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4211 EncodeNetworkCode(req+count, Bitmap.netcode);
4214 req[count++]=(Bitmap.size+4)>>8;
4215 req[count++]=(Bitmap.size+4)%0xff;
4216 req[count++]=0x00; /* Infofield */
4217 req[count++]=Bitmap.width;
4218 req[count++]=Bitmap.height;
4219 req[count++]=0x01; /* Just BW */
4220 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4222 return count+Bitmap.size;
4225 int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4230 req[count++]=Bitmap.height;
4231 req[count++]=Bitmap.width;
4232 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4234 return count+Bitmap.size;
4237 /* Set a bitmap or welcome-note */
4238 GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
4240 unsigned char req[600] = { N6110_FRAME_HEADER };
4246 /* Direct uploading variables */
4247 GSM_MultiSMSMessage SMS;
4248 unsigned char buffer[1000] = {0x0c,0x01};
4249 GSM_NetworkInfo NetworkInfo;
4253 /* Uploading with preview */
4254 if (Bitmap->number==255 &&
4255 (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
4256 GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
4257 memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
4259 memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
4261 buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
4263 Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
4265 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4266 return GE_NONE; //no answer from phone
4269 CurrentSetBitmapError = GE_BUSY;
4271 switch (Bitmap->type) {
4272 case GSM_WelcomeNoteText:
4273 case GSM_DealerNoteText:
4275 req[count++]=0x01; /* Only one block */
4277 if (Bitmap->type==GSM_WelcomeNoteText)
4278 req[count++]=0x02; /* Welcome text */
4280 req[count++]=0x03; /* Dealer Welcome Note */
4282 textlen=strlen(Bitmap->text);
4283 req[count++]=textlen;
4284 memcpy(req+count,Bitmap->text,textlen);
4288 Protocol->SendMessage(count, 0x05, req);
4292 case GSM_StartupLogo:
4293 if (Bitmap->number==0) {
4295 /* For 33xx we first set animated logo to default */
4296 if (GetModelFeature (FN_STARTUP)==F_STANIM) {
4297 error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4298 if (error!=GE_NONE) return error;
4302 req[count++]=0x01; /* Only one block */
4303 count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
4304 Protocol->SendMessage(count, 0x05, req);
4306 return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4310 case GSM_OperatorLogo:
4311 req[count++]=0x30; /* Store Op Logo */
4312 req[count++]=0x01; /* Location */
4313 count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
4314 Protocol->SendMessage(count, 0x05, req);
4317 case GSM_CallerLogo:
4319 count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
4320 Protocol->SendMessage(count, 0x03, req);
4323 case GSM_PictureImage:
4325 req[count++]=Bitmap->number;
4326 if (strcmp(Bitmap->Sender,"")) {
4327 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
4329 /* Convert number of semioctets to number of chars and add count */
4331 if (textlen % 2) textlen++;
4332 count+=textlen / 2 + 1;
4340 req[count++]=strlen(Bitmap->text);
4341 memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
4342 count+=strlen(Bitmap->text);
4344 req[count++]=Bitmap->width;
4345 req[count++]=Bitmap->height;
4347 memcpy(req+count,Bitmap->bitmap,Bitmap->size);
4348 Protocol->SendMessage(count+Bitmap->size, 0x47, req);
4351 case GSM_7110OperatorLogo:
4352 case GSM_7110StartupLogo:
4353 case GSM_6210StartupLogo:
4354 return GE_NOTSUPPORTED;
4360 /* Wait for timeout or other error. */
4361 while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
4364 return (GE_TIMEOUT);
4369 return CurrentSetBitmapError;
4372 /* Get a bitmap from the phone */
4373 GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
4375 unsigned char req[10] = { N6110_FRAME_HEADER };
4380 CurrentGetBitmap=Bitmap;
4381 CurrentGetBitmapError = GE_BUSY;
4383 switch (CurrentGetBitmap->type) {
4384 case GSM_StartupLogo:
4385 case GSM_WelcomeNoteText:
4386 case GSM_DealerNoteText:
4388 Protocol->SendMessage(count, 0x05, req);
4390 case GSM_OperatorLogo:
4392 req[count++]=0x01; /* Location 1 */
4393 Protocol->SendMessage(count, 0x05, req);
4395 case GSM_CallerLogo:
4397 req[count++]=Bitmap->number;
4398 Protocol->SendMessage(count, 0x03, req);
4400 case GSM_PictureImage:
4402 req[count++]=Bitmap->number;
4403 Protocol->SendMessage(count, 0x47, req);
4405 case GSM_7110OperatorLogo:
4406 case GSM_7110StartupLogo:
4407 case GSM_6210StartupLogo:
4409 return GE_NOTSUPPORTED;
4412 /* Wait for timeout or other error. */
4413 while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
4416 return (GE_TIMEOUT);
4421 CurrentGetBitmap=NULL;
4423 return CurrentGetBitmapError;
4426 void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4428 switch (MessageBuffer[3]) {
4430 /* Set ringtone OK */
4433 fprintf(stdout, _("Message: Ringtone set OK!\n"));
4435 CurrentRingtoneError=GE_NONE;
4438 /* Set ringtone error */
4441 fprintf(stdout, _("Message: Ringtone setting error !\n"));
4443 CurrentRingtoneError=GE_NOTSUPPORTED;
4448 GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
4451 char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
4452 {N6110_FRAME_HEADER,
4454 0x00, /* Location */
4457 int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
4459 /* Variables for preview uploading */
4460 unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
4461 unsigned char buffer2[20];
4462 GSM_NetworkInfo NetworkInfo;
4464 /* Setting ringtone with preview */
4465 if (ringtone->location==255) {
4468 EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
4469 memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
4470 *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
4471 Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
4472 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4474 return GE_NONE; //no answer from phone
4477 *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
4479 req[4]=ringtone->location-1;
4481 return NULL_SendMessageSequence
4482 (50, &CurrentRingtoneError, (size+7), 0x05, req);
4485 void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4489 switch (MessageBuffer[4]) {
4490 case 0x00: /* location supported. We have ringtone */
4492 /* Binary format used in N6150 */
4493 if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4495 fprintf(stdout,_("Message: ringtone \""));
4502 if (MessageBuffer[i]!=0)
4503 fprintf(stdout,_("%c"),MessageBuffer[i]);
4505 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4506 if (MessageBuffer[i]==0) break;
4511 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4514 /* Looking for end */
4517 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4520 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4524 if (i==MessageLength) break;
4528 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4529 CurrentGetBinRingtone->length=i-3;
4531 CurrentBinRingtoneError=GE_NONE;
4535 /* Binary format used in N3210 */
4536 if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4539 fprintf(stdout,_("Message: ringtone \""));
4546 if (MessageBuffer[i]!=0)
4547 fprintf(stdout,_("%c"),MessageBuffer[i]);
4549 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4550 if (MessageBuffer[i]==0) break;
4555 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4558 /* Here changes to get full compatibility with binary format used in N6150 */
4561 MessageBuffer[5]=0x0c;
4562 MessageBuffer[6]=0x01;
4563 MessageBuffer[7]=0x2c;
4565 /* Looking for end */
4568 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4571 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4575 if (i==MessageLength) break;
4579 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4581 CurrentGetBinRingtone->length=i-3;
4583 CurrentBinRingtoneError=GE_NONE;
4588 memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
4590 CurrentGetBinRingtone->length=MessageLength;
4593 fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
4595 CurrentBinRingtoneError=GE_UNKNOWNMODEL;
4601 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4604 CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
4608 GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
4610 unsigned char req[] = { 0x00,0x01,0x9e,
4615 CurrentGetBinRingtone=ringtone;
4617 error=N6110_EnableExtendedCommands(0x01);
4618 if (error!=GE_NONE) return error;
4620 req[3]=ringtone->location-1;
4622 return NULL_SendMessageSequence
4623 (50, &CurrentBinRingtoneError, 4, 0x40, req);
4626 void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4628 switch (MessageBuffer[4]) {
4629 case 0x00: /* location supported. We set ringtone */
4631 fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
4633 CurrentBinRingtoneError=GE_NONE;
4638 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4640 CurrentBinRingtoneError=GE_NOTSUPPORTED;
4645 GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
4647 unsigned char req[1000] = { 0x00,0x01,0xa0};
4651 GSM_BinRingtone ring;
4653 /* Must be sure, that can upload ringtone to this phone */
4654 ring.location=ringtone->location;
4655 error=N6110_GetBinRingTone(&ring);
4656 if (error!=GE_NONE) return error;
4658 error=N6110_EnableExtendedCommands(0x01);
4659 if (error!=GE_NONE) return error;
4661 memcpy(req+3,ringtone->frame,ringtone->length);
4663 req[3]=ringtone->location-1;
4665 return NULL_SendMessageSequence
4666 (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
4669 #endif /* UCLINUX */
4671 GSM_Error N6110_Reset(unsigned char type)
4673 return N6110_EnableExtendedCommands(type);
4676 void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4683 switch (MessageBuffer[3]) {
4685 /* Unknown message - it has been seen after the 0x07 message (call
4686 answered). Probably it has similar meaning. If you can solve
4687 this - just mail me. Pavel JanÃk ml.
4689 The message looks like this:
4697 Phone: [01 ][08 ][00 ] is the header of the frame
4699 [03 ] is the call message subtype
4701 [05 ] is the call sequence number
4705 [00 ][01 ][03 ][02 ][91][00] are unknown but has been
4706 seen in the Incoming call message (just after the
4707 caller's name from the phonebook). But never change
4708 between phone calls :-(
4711 /* This may mean sequence number of 'just made' call - CK */
4715 fprintf(stdout, _("Message: Call message, type 0x02:"));
4716 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4721 /* Possibly call OK */
4722 /* JD: I think that this means "call in progress" (incomming or outgoing) */
4726 fprintf(stdout, _("Message: Call message, type 0x03:"));
4727 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4728 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4731 CurrentCallSequenceNumber=MessageBuffer[4];
4733 CurrentIncomingCall[0]='D';
4734 #endif /* UCLINUX */
4735 if (CurrentCallPassup) CurrentCallPassup('D');
4739 /* Remote end has gone away before you answer the call. Probably your
4740 mother-in-law or banker (which is worse?) ... */
4744 fprintf(stdout, _("Message: Remote end hang up.\n"));
4745 fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
4747 switch (MessageBuffer[6]) {
4748 case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
4749 case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
4750 case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
4751 case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4752 case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
4753 case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4756 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
4757 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4761 CurrentIncomingCall[0] = ' ';
4762 #endif /* UCLINUX */
4763 if (CurrentCallPassup) CurrentCallPassup(' ');
4767 /* Incoming call alert */
4771 fprintf(stdout, _("Message: Incoming call alert:\n"));
4773 /* We can have more then one call ringing - we can distinguish between
4776 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4777 fprintf(stdout, _(" Number: "));
4779 count=MessageBuffer[6];
4781 for (tmp=0; tmp <count; tmp++)
4782 fprintf(stdout, "%c", MessageBuffer[7+tmp]);
4784 fprintf(stdout, "\n");
4786 fprintf(stdout, _(" Name: "));
4788 for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
4789 fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
4791 fprintf(stdout, "\n");
4794 count=MessageBuffer[6];
4797 CurrentIncomingCall[0] = 0;
4798 for (tmp=0; tmp <count; tmp++)
4799 sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
4800 #endif /* UCLINUX */
4804 /* Call answered. Probably your girlfriend...*/
4808 fprintf(stdout, _("Message: Call answered.\n"));
4809 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4814 /* Call ended. Girlfriend is girlfriend, but time is money :-) */
4818 fprintf(stdout, _("Message: Call ended by your phone.\n"));
4819 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4824 /* This message has been seen with the message of subtype 0x09
4825 after I hang the call.
4832 Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
4834 What is the meaning of 87? Can you spell some magic light into
4839 /* Probably means call over - CK */
4843 fprintf(stdout, _("Message: Call message, type 0x0a:"));
4844 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4845 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4849 CurrentIncomingCall[0] = ' ';
4850 #endif /* UCLINUX */
4851 if (CurrentCallPassup) CurrentCallPassup(' ');
4858 fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
4862 if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
4863 #endif /* UCLINUX */
4865 if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
4872 fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
4874 AppendLogText("Unknown msg\n",false);
4876 break; /* Visual C Don't like empty cases */
4882 static void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4886 switch (MessageBuffer[3]) {
4890 /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
4891 /* If you want see, if it works with your phone make something like that: */
4893 /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
4894 /* Protocol->SendMessage(4, 0x04, connect5); */
4896 /* Marcin-Wiacek@TopNet.PL */
4898 #if defined(WIN32) || defined(UCLINUX)
4899 sprintf(Current_IMEI, "%s", MessageBuffer+5);
4900 sprintf(Current_Model, "%s", MessageBuffer+21);
4901 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4903 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
4904 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
4905 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4909 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
4910 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
4911 fprintf(stdout, _(" Model: %s\n"), Current_Model);
4912 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
4913 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
4914 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
4919 /* Get group data */
4920 /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
4923 if (CurrentGetBitmap!=NULL) {
4924 if (CurrentGetBitmap->number==MessageBuffer[4]) {
4925 count=MessageBuffer[5];
4926 memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
4927 CurrentGetBitmap->text[count]=0;
4930 fprintf(stdout, _("Message: Caller group datas\n"));
4931 fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
4936 CurrentGetBitmap->ringtone=MessageBuffer[count++];
4938 fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
4939 if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
4940 fprintf(stdout,_("\n"));
4943 CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
4945 fprintf(stdout, _("Caller group logo "));
4946 if (CurrentGetBitmap->enabled)
4947 fprintf(stdout, _("enabled \n"));
4949 fprintf(stdout, _("disabled \n"));
4952 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4953 CurrentGetBitmap->size+=MessageBuffer[count++];
4955 fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
4959 CurrentGetBitmap->width=MessageBuffer[count++];
4960 CurrentGetBitmap->height=MessageBuffer[count++];
4962 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
4963 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4964 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
4965 CurrentGetBitmapError=GE_NONE;
4968 fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
4973 fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
4978 /* Get group data error */
4981 CurrentGetBitmapError=GE_UNKNOWN;
4983 fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
4987 /* Set group data OK */
4990 CurrentSetBitmapError=GE_NONE;
4992 fprintf(stdout, _("Message: Caller group data set correctly.\n"));
4996 /* Set group data error */
4999 CurrentSetBitmapError=GE_UNKNOWN;
5001 fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
5008 fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
5010 AppendLogText("Unknown msg\n",false);
5012 break; /* Visual C Don't like empty cases */
5016 static void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5018 int tmp, count, length;
5025 switch (MessageBuffer[3]) {
5031 fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
5034 if (CurrentGetBitmap!=NULL) {
5040 for (tmp=0;tmp<MessageBuffer[4];tmp++){
5041 switch (MessageBuffer[count++]) {
5043 if (CurrentGetBitmap->type==GSM_StartupLogo) {
5044 CurrentGetBitmap->height=MessageBuffer[count++];
5045 CurrentGetBitmap->width=MessageBuffer[count++];
5046 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5047 length=CurrentGetBitmap->size;
5048 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
5050 length=MessageBuffer[count++];
5051 length=length*MessageBuffer[count++]/8;
5055 fprintf(stdout, _("Startup logo supported - "));
5056 if (length!=0) { fprintf(stdout, _("currently set\n")); }
5057 else { fprintf(stdout, _("currently empty\n")); }
5059 if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
5062 length=MessageBuffer[count];
5063 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
5064 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5065 CurrentGetBitmap->text[length]=0;
5068 fprintf(stdout, _("Startup Text supported - "));
5071 fprintf(stdout, _("currently set to \""));
5072 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5073 fprintf(stdout, _("\"\n"));
5075 fprintf(stdout, _("currently empty\n"));
5079 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
5082 length=MessageBuffer[count];
5083 if (CurrentGetBitmap->type==GSM_DealerNoteText) {
5084 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5085 CurrentGetBitmap->text[length]=0;
5088 fprintf(stdout, _("Dealer Welcome supported - "));
5091 fprintf(stdout, _("currently set to \""));
5092 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5093 fprintf(stdout, _("\"\n"));
5095 fprintf(stdout, _("currently empty\n"));
5099 if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
5103 if (issupported) CurrentGetBitmapError=GE_NONE;
5104 else CurrentGetBitmapError=GE_NOTSUPPORTED;
5107 fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
5112 /* Set startup OK */
5115 CurrentSetBitmapError=GE_NONE;
5117 fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
5121 /* Set Operator Logo OK */
5125 fprintf(stdout, _("Message: Operator logo correctly set.\n"));
5128 CurrentSetBitmapError=GE_NONE;
5131 /* Set Operator Logo Error */
5135 fprintf(stdout, _("Message: Error setting operator logo!\n"));
5138 CurrentSetBitmapError=GE_UNKNOWN;
5142 /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
5145 if (CurrentGetBitmap!=NULL) {
5147 count=5; /* Location ignored. */
5149 DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
5153 fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
5154 CurrentGetBitmap->netcode,
5155 GSM_GetNetworkName(CurrentGetBitmap->netcode));
5158 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
5159 CurrentGetBitmap->size+=MessageBuffer[count++];
5161 CurrentGetBitmap->width=MessageBuffer[count++];
5162 CurrentGetBitmap->height=MessageBuffer[count++];
5164 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5165 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
5166 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
5167 CurrentGetBitmapError=GE_NONE;
5170 fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
5176 /* Get op logo error */
5180 fprintf(stdout, _("Message: Error getting operator logo!\n"));
5182 CurrentGetBitmapError=GE_UNKNOWN;
5188 fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
5190 AppendLogText("Unknown msg\n",false);
5196 static void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5199 unsigned char output[160];
5205 switch (MessageBuffer[3]) {
5209 /* MessageBuffer[3] = 0x05
5210 MessageBuffer[4] = 0x00
5211 MessageBuffer[5] = 0x0f
5212 MessageBuffer[6] = 0x03
5213 MessageBuffer[7] = length of packed message
5215 This is all I have seen - Gerry Anderson */
5217 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
5221 fprintf(stdout, _("Message from Network operator: "));
5223 for (i=0; i<tmp; i++)
5224 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
5226 fprintf(stdout, "\n");
5235 fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
5237 AppendLogText("Unknown msg\n",false);
5243 static void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5245 switch (MessageBuffer[3]) {
5249 fprintf(stdout, _("Message: SIM card login\n"));
5255 fprintf(stdout, _("Message: SIM card logout\n"));
5261 fprintf(stdout, _("Unknown message of type 0x09.\n"));
5263 AppendLogText("Unknown msg\n",false);
5268 static void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5270 switch(MessageBuffer[3]) {
5275 fprintf(stdout, _("Message: Calendar Alarm active\n"));
5276 fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
5281 fprintf(stdout, _("Unknown message of type 0x13.\n"));
5283 AppendLogText("Unknown msg\n",false);
5288 #endif /* UCLINUX */
5290 void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5294 switch(MessageBuffer[2]) {
5299 fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
5302 CurrentMagicError=GE_NONE;
5308 fprintf(stdout, _("Message: Answer for call commands.\n"));
5311 CurrentDialVoiceError=GE_NONE;
5317 fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
5320 CurrentMagicError=GE_NONE;
5326 fprintf(stdout, _("Message: ACK for simlock closing\n"));
5329 CurrentMagicError=GE_NONE;
5334 switch (MessageBuffer[5]) {
5337 fprintf(stdout,_("Message: EEPROM contest received\n"));
5340 if (MessageBuffer[8]!=0x00) {
5341 for (i=9;i<MessageLength;i++) {
5342 fprintf(stdout,_("%c"), MessageBuffer[i]);
5345 CurrentMagicError=GE_NONE;
5352 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5354 AppendLogText("Unknown msg\n",false);
5360 N6110_DisplayTestsInfo(MessageBuffer);
5362 #endif /* UCLINUX */
5367 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5369 AppendLogText("Unknown msg\n",false);
5370 break; /* Visual C Don't like empty cases */
5376 static void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5380 switch(MessageBuffer[3]) {
5386 if (MessageBuffer[5]!=0) {
5387 strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
5389 while (MessageBuffer[count]!=0) {
5395 strcpy(CurrentGetBitmap->Sender,"\0");
5400 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
5401 CurrentGetBitmap->text[MessageBuffer[count]]=0;
5403 if (MessageBuffer[count]!=0)
5404 count+=MessageBuffer[count];
5409 fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
5412 CurrentGetBitmap->width=MessageBuffer[count+1];
5413 CurrentGetBitmap->height=MessageBuffer[count+2];
5414 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5416 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
5418 CurrentGetBitmapError=GE_NONE;
5424 fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
5426 CurrentSetBitmapError=GE_NONE;
5427 CurrentGetBitmapError=GE_NONE;
5433 fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
5435 CurrentSetBitmapError=GE_UNKNOWN;
5441 fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
5443 CurrentGetBitmapError=GE_UNKNOWN;
5449 fprintf(stdout, _("Unknown message of type 0x47.\n"));
5451 AppendLogText("Unknown msg\n",false);
5452 break; /* Visual C Don't like empty cases */
5456 #endif /* UCLINUX */
5458 void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5461 sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
5462 AppendLog(buffer,strlen(buffer),false);
5465 fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
5469 CurrentLinkOK = true;
5472 static void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5475 fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
5480 /* This function is used for parsing the RLP frame into fields. */
5481 void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
5488 /* We do not need RLP frame parsing to be done when we do not have callback
5490 if (CurrentRLP_RXCallback == NULL)
5493 /* Anybody know the official meaning of the first two bytes?
5494 Nokia 6150 sends junk frames starting D9 01, and real frames starting
5495 D9 00. We'd drop the junk frames anyway because the FCS is bad, but
5496 it's tidier to do it here. We still need to call the callback function
5497 to give it a chance to handle timeouts and/or transmit a frame */
5498 if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
5501 /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
5502 specification, so Header consists of 16 bits (2 bytes). See section 4.1
5503 of the specification. */
5505 frame.Header[0] = MessageBuffer[2];
5506 frame.Header[1] = MessageBuffer[3];
5508 /* Next 200 bits (25 bytes) contain the Information. We store the
5509 information in the Data array. */
5511 for (count = 0; count < 25; count ++)
5512 frame.Data[count] = MessageBuffer[4 + count];
5514 /* The last 24 bits (3 bytes) contain FCS. */
5516 frame.FCS[0] = MessageBuffer[29];
5517 frame.FCS[1] = MessageBuffer[30];
5518 frame.FCS[2] = MessageBuffer[31];
5520 /* Here we pass the frame down in the input stream. */
5521 CurrentRLP_RXCallback(valid ? &frame : NULL);
5524 static void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5527 fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
5534 void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5536 GSM_SMSMessage NullSMS;
5538 switch (MessageBuffer[6]) {
5540 case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
5541 case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
5543 /* Is it possible ? */
5544 case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
5545 default: NullSMS.Type = GST_UN; break;
5549 if (NullSMS.Type == GST_DR)
5550 fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
5552 fprintf(stdout, _("Message: SMS Message Received\n"));
5555 GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
5558 fprintf(stdout, _("\n"));
5562 #endif /* UCLINUX */
5564 void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5568 /* Switch on the basis of the message type byte */
5569 switch (MessageType) {
5571 /* Call information */
5574 N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
5580 switch (MessageBuffer[3]) {
5582 case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5583 case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
5584 case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5585 case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5586 case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5588 case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5589 default :unknown=true;break;
5592 #endif /* UCLINUX */
5594 /* Phonebook handling */
5596 switch (MessageBuffer[3]) {
5598 case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
5600 case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
5602 case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
5604 case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5606 case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5608 default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
5609 #endif /* UCLINUX */
5615 switch (MessageBuffer[3]) {
5616 case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
5617 default :unknown=true;break;
5622 /* Startup Logo, Operator Logo and Profiles. */
5624 switch (MessageBuffer[3]) {
5625 case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5626 case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5627 case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5628 case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5629 case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5630 case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5631 default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
5635 /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
5638 switch (MessageBuffer[3]) {
5640 case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
5641 default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
5645 /* Security code requests */
5647 switch (MessageBuffer[3]) {
5648 case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
5649 case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5650 default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5657 N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
5662 switch (MessageBuffer[3]) {
5663 case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
5664 default :unknown=true;break;
5668 /* Simulating key pressing */
5670 switch (MessageBuffer[3]) {
5671 case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
5672 default :unknown=true;break;
5678 switch (MessageBuffer[3]) {
5679 case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5680 case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
5681 case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5682 default :unknown=true;break;
5686 /* Phone Clock and Alarm */
5688 switch (MessageBuffer[3]) {
5689 case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
5690 case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
5691 case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
5692 case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
5693 default :unknown=true;break;
5697 /* Calendar notes handling */
5699 switch (MessageBuffer[3]) {
5700 case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5701 case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5702 case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
5703 default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
5709 switch (MessageBuffer[3]) {
5711 case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5713 case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5714 case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5716 case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
5717 default :unknown=true;break;
5723 switch (MessageBuffer[3]) {
5725 case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
5727 case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5729 case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5732 case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
5733 default :unknown=true;break;
5736 #endif /* UCLINUX */
5738 /* Internal phone functions? */
5740 switch (MessageBuffer[2]) {
5741 case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
5743 case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
5744 #endif /* UCLINUX */
5745 case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
5747 case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5748 case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5749 case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5750 case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
5751 case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
5752 case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5753 case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5754 case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
5755 case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5756 case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5757 #endif /* UCLINUX */
5758 case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
5759 default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
5764 /* Picture Images */
5767 N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
5769 #endif /* UCLINUX */
5771 /* Mobile phone identification */
5774 N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
5777 /***** Acknowlegment of our frames. *****/
5778 case FBUS_FRTYPE_ACK:
5780 N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
5783 /***** Power on message. *****/
5786 N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
5791 N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
5794 /***** RLP frame received. *****/
5797 N6110_RX_HandleRLPMessage(MessageBuffer);
5800 /***** Power on message. *****/
5803 N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
5806 /***** Unknown message *****/
5807 /* If you think that you know the exact meaning of other messages - please
5812 fprintf(stdout, _("Message: Unknown message type.\n"));
5814 AppendLogText("Unknown msg type\n",false);
5823 fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
5825 AppendLogText("Unknown msg\n",false);