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);
2615 if (type != 1) Protocol->SendMessage(26, 0x01, req2);
2623 GSM_Error N6110_GetIncomingCallNr(char *Number)
2626 if (*CurrentIncomingCall != ' ') {
2627 strcpy(Number, CurrentIncomingCall);
2634 #endif /* UCLINUX */
2636 GSM_Error N6110_CancelCall(void)
2638 // This frame & method works only on 61xx/51xx
2639 // unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
2640 // req[4]=CurrentCallSequenceNumber;
2641 // Protocol->SendMessage(6, 0x01, req);
2646 unsigned char req[]={0x00,0x01,0x7c,0x03};
2649 error=N6110_EnableExtendedCommands(0x01);
2650 if (error!=GE_NONE) return error;
2652 return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
2657 void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2659 switch(MessageBuffer[3]) {
2663 fprintf(stdout, _("Message: Security code accepted.\n"));
2665 CurrentSecurityCodeError = GE_NONE;
2670 fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
2672 CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
2676 GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
2679 unsigned char req[15] = { N6110_FRAME_HEADER,
2680 0x0a, /* Enter code request. */
2681 0x00 /* Type of the entered code. */
2685 req[4]=SecurityCode.Type;
2687 for (i=0; i<strlen(SecurityCode.Code);i++)
2688 req[5+i]=SecurityCode.Code[i];
2690 req[5+strlen(SecurityCode.Code)]=0x00;
2691 req[6+strlen(SecurityCode.Code)]=0x00;
2693 return NULL_SendMessageSequence
2694 (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
2697 void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2699 *CurrentSecurityCodeStatus = MessageBuffer[4];
2702 fprintf(stdout, _("Message: Security Code status received: "));
2704 switch(*CurrentSecurityCodeStatus) {
2706 case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;
2707 case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;
2708 case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;
2709 case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;
2710 case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;
2711 case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;
2712 default : fprintf(stdout, _("Unknown!\n"));
2717 CurrentSecurityCodeError = GE_NONE;
2720 GSM_Error N6110_GetSecurityCodeStatus(int *Status)
2723 unsigned char req[4] = { N6110_FRAME_HEADER,
2727 CurrentSecurityCodeStatus=Status;
2729 return NULL_SendMessageSequence
2730 (20, &CurrentSecurityCodeError, 4, 0x08, req);
2733 void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2738 fprintf(stdout, _("Message: Security code received: "));
2739 switch (MessageBuffer[3]) {
2740 case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;
2741 case GSCT_Pin: fprintf(stdout, _("PIN"));break;
2742 case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;
2743 case GSCT_Puk: fprintf(stdout, _("PUK"));break;
2744 case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;
2745 default: fprintf(stdout, _("unknown !"));break;
2747 if (MessageBuffer[4]==1) {
2748 fprintf(stdout, _(" allowed, value \""));
2749 if (MessageBuffer[3]==GSCT_SecurityCode) {
2750 for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2752 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2753 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2754 for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
2756 fprintf(stdout, _("\""));
2758 fprintf(stdout, _(" not allowed"));
2760 fprintf(stdout, _("\n"));
2763 if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
2764 && MessageBuffer[4]==1) { /* It's allowed */
2765 if (MessageBuffer[3]==GSCT_SecurityCode) {
2766 for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2767 CurrentSecurityCode->Code[5]=0;
2769 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
2770 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
2771 for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
2772 CurrentSecurityCode->Code[4]=0;
2774 CurrentSecurityCodeError=GE_NONE;
2776 CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
2779 GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
2782 unsigned char req[4] = { 0x00,
2783 0x01,0x6e, /* Get code request. */
2784 0x00 }; /* Type of the requested code. */
2788 error=N6110_EnableExtendedCommands(0x01);
2789 if (error!=GE_NONE) return error;
2791 req[3]=SecurityCode->Type;
2793 CurrentSecurityCode=SecurityCode;
2795 return NULL_SendMessageSequence
2796 (20, &CurrentSecurityCodeError, 4, 0x40, req);
2799 void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2802 fprintf(stdout, _("Message: answer for PlayTone frame\n"));
2805 CurrentPlayToneError=GE_NONE;
2808 GSM_Error N6110_PlayTone(int Herz, u8 Volume)
2810 unsigned char req[6] = { 0x00,0x01,0x8f,
2813 0x00 }; /* HerzHi */
2817 /* PlayTone wasn't used earlier */
2818 if (CurrentPlayToneError==GE_UNKNOWN) {
2819 if (CurrentConnectionType!=GCT_MBUS)
2820 CurrentDisableKeepAlive=true;
2822 error=N6110_EnableExtendedCommands(0x01);
2823 if (error!=GE_NONE) return error;
2826 /* For Herz==255*255 we have silent */
2827 if (Herz!=255*255) {
2840 /* For Herz==255*255 we have silent and additionaly
2841 we wait for phone answer - it's important for MBUS */
2842 if (Herz==255*255) {
2843 error=NULL_SendMessageSequence
2844 (20, &CurrentPlayToneError, 6, 0x40, req);
2846 CurrentPlayToneError=GE_UNKNOWN;
2847 CurrentDisableKeepAlive=false;
2849 if (error!=GE_NONE) return error;
2851 Protocol->SendMessage(6,0x40,req);
2854 error=NULL_SendMessageSequence
2855 (20, &CurrentPlayToneError, 6, 0x40, req);
2857 /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
2858 if (Herz==255*255) {
2859 CurrentPlayToneError=GE_UNKNOWN;
2860 CurrentDisableKeepAlive=false;
2863 if (error!=GE_NONE) return error;
2870 void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2872 if (MessageBuffer[4]==0x01) {
2873 DecodeDateTime(MessageBuffer+8, CurrentDateTime);
2876 fprintf(stdout, _("Message: Date and time\n"));
2877 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
2878 fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
2881 CurrentDateTime->IsSet=true;
2885 fprintf(stdout, _("Message: Date and time not set in phone\n"));
2888 CurrentDateTime->IsSet=false;
2891 CurrentDateTimeError=GE_NONE;
2894 GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
2896 return N6110_PrivGetDateTime(date_time,0x11);
2899 GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
2901 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
2903 CurrentDateTime=date_time;
2905 return NULL_SendMessageSequence
2906 (50, &CurrentDateTimeError, 4, msgtype, req);
2909 void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2912 fprintf(stdout, _("Message: Alarm\n"));
2913 fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
2914 fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
2917 CurrentAlarm->Hour=MessageBuffer[9];
2918 CurrentAlarm->Minute=MessageBuffer[10];
2919 CurrentAlarm->Second=0;
2921 CurrentAlarm->IsSet=(MessageBuffer[8]==2);
2923 CurrentAlarmError=GE_NONE;
2926 GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
2928 return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
2931 GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
2933 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
2935 CurrentAlarm=date_time;
2937 return NULL_SendMessageSequence
2938 (50, &CurrentAlarmError, 4, msgtype, req);
2941 void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
2943 switch (MessageBuffer[3]) {
2947 CurrentMessageCenter->No=MessageBuffer[4];
2948 CurrentMessageCenter->Format=MessageBuffer[6];
2949 CurrentMessageCenter->Validity=MessageBuffer[8];
2950 sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
2952 sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
2954 sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
2957 fprintf(stdout, _("Message: SMS Center received:\n"));
2958 fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
2959 fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
2960 fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
2962 fprintf(stdout, _(" SMS Center message format is "));
2964 switch (CurrentMessageCenter->Format) {
2966 case GSMF_Text : fprintf(stdout, _("Text")); break;
2967 case GSMF_Paging: fprintf(stdout, _("Paging")); break;
2968 case GSMF_Fax : fprintf(stdout, _("Fax")); break;
2969 case GSMF_Email : fprintf(stdout, _("Email")); break;
2970 default : fprintf(stdout, _("Unknown"));
2973 fprintf(stdout, "\n");
2975 fprintf(stdout, _(" SMS Center message validity is "));
2977 switch (CurrentMessageCenter->Validity) {
2979 case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;
2980 case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;
2981 case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;
2982 case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;
2983 case GSMV_1_Week : fprintf(stdout, _("1 week")); break;
2984 case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;
2985 default : fprintf(stdout, _("Unknown"));
2988 fprintf(stdout, "\n");
2992 CurrentMessageCenterError=GE_NONE;
2998 /* Number of entries depends on SIM card */
3001 fprintf(stdout, _("Message: SMS Center error received:\n"));
3002 fprintf(stdout, _(" The request for SMS Center failed.\n"));
3005 /* FIXME: appropriate error. */
3006 CurrentMessageCenterError=GE_INTERNALERROR;
3013 /* This function sends to the mobile phone a request for the SMS Center */
3014 GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
3016 unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
3017 0x00 /* SMS Center Number. */
3020 req[5]=MessageCenter->No;
3022 CurrentMessageCenter=MessageCenter;
3024 return NULL_SendMessageSequence
3025 (50, &CurrentMessageCenterError, 6, 0x02, req);
3028 void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3031 fprintf(stdout, _("Message: SMS Center correctly set.\n"));
3033 CurrentMessageCenterError=GE_NONE;
3036 /* This function set the SMS Center profile on the phone. */
3037 GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
3039 unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
3040 0x00, /* SMS Center Number. */
3041 0x00, /* Unknown. */
3042 0x00, /* SMS Message Format. */
3043 0x00, /* Unknown. */
3044 0x00, /* Validity. */
3045 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
3046 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
3047 /* Message Center Name. */
3050 req[5]=MessageCenter->No;
3051 req[7]=MessageCenter->Format;
3052 req[9]=MessageCenter->Validity;
3054 req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
3056 req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
3058 sprintf(req+34, "%s", MessageCenter->Name);
3060 CurrentMessageCenter=MessageCenter;
3062 return NULL_SendMessageSequence
3063 (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
3066 void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3068 switch (MessageBuffer[3]) {
3073 fprintf(stdout, _("Message: SMS Status Received\n"));
3074 fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
3075 fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
3078 CurrentSMSStatus->UnRead = MessageBuffer[11];
3079 CurrentSMSStatus->Number = MessageBuffer[10];
3081 CurrentSMSStatusError = GE_NONE;
3087 fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
3090 CurrentSMSStatusError = GE_INTERNALERROR;
3096 GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
3098 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
3100 CurrentSMSStatus = Status;
3102 return NULL_SendMessageSequence
3103 (10, &CurrentSMSStatusError, 5, 0x14, req);
3106 GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
3110 strcpy(folders->Folder[0].Name,"Inbox");
3111 strcpy(folders->Folder[1].Name,"Outbox");
3116 #endif /* UCLINUX */
3118 GSM_Error N6110_GetIMEI(char *imei)
3120 if (strlen(Current_IMEI)>0) {
3121 strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
3125 return (GE_TRYAGAIN);
3128 GSM_Error N6110_GetRevision(char *revision)
3131 if (strlen(Current_Revision)>0) {
3132 strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
3136 return (GE_TRYAGAIN);
3139 static GSM_Error N6110_GetModel(char *model)
3141 if (strlen(Current_Model)>0) {
3142 strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
3146 return (GE_TRYAGAIN);
3151 void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3153 switch (MessageBuffer[4]) {
3157 fprintf(stdout, _("Message: Date and time set correctly\n"));
3159 CurrentSetDateTimeError=GE_NONE;
3164 fprintf(stdout, _("Message: Date and time setting error\n"));
3166 CurrentSetDateTimeError=GE_INVALIDDATETIME;
3171 /* Needs SIM card with PIN in phone */
3172 GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
3174 return N6110_PrivSetDateTime(date_time,0x11);
3177 /* Needs SIM card with PIN in phone */
3178 GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
3181 unsigned char req[] = { N6110_FRAME_HEADER,
3182 0x60, /* set-time subtype */
3183 0x01, 0x01, 0x07, /* unknown */
3184 0x00, 0x00, /* Year (0x07cf = 1999) */
3185 0x00, 0x00, /* Month Day */
3186 0x00, 0x00, /* Hours Minutes */
3187 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3190 EncodeDateTime(req+7, date_time);
3192 return NULL_SendMessageSequence
3193 (20, &CurrentSetDateTimeError, 14, msgtype, req);
3196 void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3198 switch (MessageBuffer[4]) {
3202 fprintf(stdout, _("Message: Alarm set correctly\n"));
3204 CurrentSetAlarmError=GE_NONE;
3209 fprintf(stdout, _("Message: Alarm setting error\n"));
3211 CurrentSetAlarmError=GE_INVALIDDATETIME;
3216 /* FIXME: we should also allow to set the alarm off :-) */
3217 GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
3219 return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
3222 /* FIXME: we should also allow to set the alarm off :-) */
3223 GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
3226 unsigned char req[] = { N6110_FRAME_HEADER,
3227 0x6b, /* set-alarm subtype */
3228 0x01, 0x20, 0x03, /* unknown */
3229 0x02, /* should be alarm on/off, but it don't works */
3230 0x00, 0x00, /* Hours Minutes */
3231 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
3234 req[8] = date_time->Hour;
3235 req[9] = date_time->Minute;
3237 return NULL_SendMessageSequence
3238 (50, &CurrentSetAlarmError, 11, msgtype, req);
3241 #endif /* UCLINUX */
3243 static void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3245 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
3250 switch (MessageBuffer[3]) {
3254 CurrentPhonebookEntry->Empty = true;
3256 count=MessageBuffer[5];
3259 fprintf(stdout, _("Message: Phonebook entry received:\n"));
3260 fprintf(stdout, _(" Name: "));
3262 for (tmp=0; tmp <count; tmp++)
3264 if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
3265 if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
3266 fprintf(stdout, "%c", MessageBuffer[6+tmp]);
3269 fprintf(stdout, "\n");
3272 while (N6110_GetModel(model) != GE_NONE)
3275 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3277 DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
3278 CurrentPhonebookEntry->Name[count/2] = 0x00;
3280 fprintf(stderr,"FATAL ERROR: DecodeUnicode disabled!\n");
3282 #endif /* UCLINUX */
3284 memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);
3285 CurrentPhonebookEntry->Name[count] = 0x00;
3288 CurrentPhonebookEntry->Empty = false;
3290 for (tmp=0; tmp <count; tmp++)
3292 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {//pbk with Unicode
3293 /* We check only 1'st, 3'rd, ... char */
3294 if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking
3295 if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents
3297 if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking
3298 if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents
3303 count=MessageBuffer[6+count];
3306 fprintf(stdout, _(" Number: "));
3308 for (tmp=0; tmp <count; tmp++)
3309 fprintf(stdout, "%c", MessageBuffer[i+tmp]);
3311 fprintf(stdout, "\n");
3314 memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);
3315 CurrentPhonebookEntry->Number[count] = 0x00;
3316 CurrentPhonebookEntry->Group = MessageBuffer[i+count];
3318 /* Phone doesn't have entended phonebook */
3319 CurrentPhonebookEntry->SubEntriesCount = 0;
3321 /* But for these memories data is saved and we can save it using 7110/6210 style */
3322 if (CurrentPhonebookEntry->MemoryType==GMT_DC ||
3323 CurrentPhonebookEntry->MemoryType==GMT_RC ||
3324 CurrentPhonebookEntry->MemoryType==GMT_MC) {
3325 CurrentPhonebookEntry->SubEntriesCount = 1;
3326 CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;
3327 CurrentPhonebookEntry->SubEntries[0].NumberType=0;
3328 CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;
3329 DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);
3332 fprintf(stdout, _(" Date: "));
3333 fprintf(stdout, "%02u.%02u.%04u\n",
3334 CurrentPhonebookEntry->SubEntries[0].data.Date.Day,
3335 CurrentPhonebookEntry->SubEntries[0].data.Date.Month,
3336 CurrentPhonebookEntry->SubEntries[0].data.Date.Year);
3337 fprintf(stdout, _(" Time: "));
3338 fprintf(stdout, "%02u:%02u:%02u\n",
3339 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,
3340 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,
3341 CurrentPhonebookEntry->SubEntries[0].data.Date.Second);
3344 /* These values are set, when date and time unavailable in phone.
3345 Values from 3310 - in other can be different */
3346 if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&
3347 CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&
3348 CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&
3349 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&
3350 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&
3351 CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)
3352 CurrentPhonebookEntry->SubEntriesCount = 0;
3355 /* Signal no error to calling code. */
3356 CurrentPhonebookError = GE_NONE;
3363 fprintf(stdout, _("Message: Phonebook read entry error received:\n"));
3366 switch (MessageBuffer[4]) {
3370 fprintf(stdout, _(" Invalid memory type!\n"));
3372 CurrentPhonebookError = GE_INVALIDMEMORYTYPE;
3377 fprintf(stdout, _(" Unknown error!\n"));
3379 CurrentPhonebookError = GE_INTERNALERROR;
3387 /* Routine to get specifed phone book location. Designed to be called by
3388 application. Will block until location is retrieved or a timeout/error
3390 GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)
3392 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
3394 CurrentPhonebookEntry = entry;
3396 req[4] = N6110_GetMemoryType(entry->MemoryType);
3397 req[5] = entry->Location;
3399 return NULL_SendMessageSequence
3400 (50, &CurrentPhonebookError, 7, 0x03, req);
3403 static void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3405 switch (MessageBuffer[3]) {
3410 fprintf(stdout, _("Message: Phonebook written correctly.\n"));
3412 CurrentPhonebookError = GE_NONE;
3417 switch (MessageBuffer[4]) {
3418 /* FIXME: other errors? When I send the phonebook with index of 350 it
3419 still report error 0x7d :-( */
3422 fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));
3424 CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;
3429 fprintf(stdout, _(" Unknown error!\n"));
3431 CurrentPhonebookError = GE_INTERNALERROR;
3436 /* Routine to write phonebook location in phone. Designed to be called by
3437 application code. Will block until location is written or timeout
3439 GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)
3441 unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };
3444 req[4] = N6110_GetMemoryType(entry->MemoryType);
3445 req[5] = entry->Location;
3449 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33) {
3452 req[6] = strlen(entry->Name)*2;
3454 EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
3456 for (i=0; i<strlen(entry->Name); i++)
3458 /* here we encode "special" chars */
3459 if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
3460 if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
3463 current+=strlen(entry->Name)*2;
3467 fprintf(stderr,"FATAL ERROR: EncodeUnicode disabled!\n");
3470 #endif /* UCLINUX */
3473 req[6] = strlen(entry->Name);
3475 for (i=0; i<strlen(entry->Name); i++)
3477 req[current+i] = entry->Name[i];
3479 /* here we encode "special" chars */
3480 if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
3481 if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
3484 current+=strlen(entry->Name);
3487 req[current++]=strlen(entry->Number);
3489 for (i=0; i<strlen(entry->Number); i++)
3490 req[current+i] = entry->Number[i];
3492 current+=strlen(entry->Number);
3494 /* Jano: This allow to save 14 characters name into SIM memory, when
3495 No Group is selected. */
3496 if (entry->Group == 5)
3497 req[current++]=0xff;
3499 req[current++]=entry->Group;
3501 return NULL_SendMessageSequence
3502 (50, &CurrentPhonebookError, current, 0x03, req);
3507 void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3509 switch(MessageBuffer[3]) {
3513 fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
3515 CurrentNetmonitorError=GE_NONE;
3520 fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
3521 fprintf(stdout, "%s\n", MessageBuffer+4);
3524 strcpy(CurrentNetmonitor, MessageBuffer+4);
3526 CurrentNetmonitorError=GE_NONE;
3530 GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
3532 unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
3536 error=N6110_EnableExtendedCommands(0x01);
3537 if (error!=GE_NONE) return error;
3539 CurrentNetmonitor=Screen;
3543 return NULL_SendMessageSequence
3544 (20, &CurrentNetmonitorError, 4, 0x40, req);
3547 /* Doesn't work in N3210. */
3548 /* In other allow to access phone menu without SIM card (just send any sequence) */
3549 GSM_Error N6110_SendDTMF(char *String)
3551 unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
3552 0x00 /* Length of DTMF string. */
3555 u8 length=strlen(String);
3557 if (length>59) length=59;
3561 memcpy(req+5,String,length);
3563 return NULL_SendMessageSequence
3564 (20, &CurrentSendDTMFError, 5+length, 0x01, req);
3567 #endif /* UCLINUX */
3569 static void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3571 switch (MessageBuffer[3]) {
3575 switch (MessageBuffer[4]) {
3576 case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
3577 default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
3580 CurrentSpeedDialEntry->Location = MessageBuffer[5];
3583 fprintf(stdout, _("Message: Speed dial entry received:\n"));
3584 fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
3585 fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
3586 fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
3589 CurrentSpeedDialError=GE_NONE;
3595 fprintf(stdout, _("Message: Speed dial entry error\n"));
3597 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3603 GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
3606 unsigned char req[] = { N6110_FRAME_HEADER,
3608 0x00 /* The number of speed dial. */
3611 CurrentSpeedDialEntry = entry;
3613 req[4] = entry->Number;
3615 return NULL_SendMessageSequence
3616 (20, &CurrentSpeedDialError, 5, 0x03, req);
3619 static void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3621 switch (MessageBuffer[3]) {
3626 fprintf(stdout, _("Message: Speed dial entry set.\n"));
3628 CurrentSpeedDialError=GE_NONE;
3634 fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
3636 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
3642 GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
3645 unsigned char req[] = { N6110_FRAME_HEADER,
3648 0x00, /* Memory Type */
3652 req[4] = entry->Number;
3654 switch (entry->MemoryType) {
3655 case GMT_ME: req[5] = 0x02;
3656 default : req[5] = 0x03;
3659 req[6] = entry->Location;
3661 return NULL_SendMessageSequence
3662 (20, &CurrentSpeedDialError, 7, 0x03, req);
3667 /* This function finds parts of SMS in frame used in new Nokia phones
3668 in internal protocols (they're coded according to GSM 03.40), copies them
3669 to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
3670 GSM_ETSISMSMessage to GSM_SMSMessage structure */
3671 GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
3673 SMS_MessageType PDU=SMS_Deliver;
3674 GSM_ETSISMSMessage ETSI;
3677 ETSI.firstbyte=req[12];
3679 /* See GSM 03.40 section 9.2.3.1 */
3680 if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
3681 if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
3684 case SMS_Submit : offset=5;break;
3685 case SMS_Deliver : offset=4;break;
3686 case SMS_Status_Report: offset=3;break;
3690 for (i=0;i<req[0]+1;i++)
3691 ETSI.SMSCNumber[i]=req[i];
3693 for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
3694 ETSI.Number[i]=req[i+12+offset];
3698 ETSI.TPDCS=req[10+offset];
3699 ETSI.TPUDL=req[11+offset];
3700 ETSI.TPVP=0; //no support for now
3701 ETSI.TPPID=0; //no support for now
3702 for(i=31+offset;i<length;i++)
3703 ETSI.MessageText[i-31-offset]=req[i];
3706 ETSI.TPDCS=req[10+offset];
3707 ETSI.TPUDL=req[11+offset];
3708 ETSI.TPPID=0; //no support for now
3709 for(i=31+offset;i<length;i++)
3710 ETSI.MessageText[i-31-offset]=req[i];
3712 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3714 case SMS_Status_Report:
3716 ETSI.DeliveryDateTime[i]=req[i+24+offset];
3717 ETSI.TPStatus=req[14];
3719 ETSI.SMSCDateTime[i]=req[i+34];
3725 GSM_DecodeETSISMS(SMS, &ETSI);
3732 void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3736 switch (MessageBuffer[3]) {
3740 switch (MessageBuffer[7]) {
3743 CurrentSMSMessage->Type = GST_SMS;
3744 CurrentSMSMessage->folder=GST_INBOX;
3749 CurrentSMSMessage->Type = GST_DR;
3750 CurrentSMSMessage->folder=GST_INBOX;
3755 CurrentSMSMessage->Type = GST_SMS;
3756 CurrentSMSMessage->folder=GST_OUTBOX;
3761 CurrentSMSMessage->Type = GST_UN;
3767 /* Field Short Message Status - MessageBuffer[4] seems not to be
3768 compliant with GSM 07.05 spec.
3769 Meaning Nokia protocol GMS spec
3770 ----------------------------------------------------
3771 MO Sent 0x05 0x07 or 0x01
3772 MO Not sent 0x07 0x06 or 0x00
3773 MT Read 0x01 0x05 or 0x01
3774 MT Not read 0x03 0x04 or 0x00
3775 ----------------------------------------------------
3776 See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
3780 if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
3781 else CurrentSMSMessage->Status = GSS_SENTREAD;
3784 fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
3786 if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
3787 fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
3789 fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
3792 if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
3793 if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
3795 if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
3796 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
3797 else fprintf(stdout, _(" Not sent\n"));
3799 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
3800 else fprintf(stdout, _(" Not read\n"));
3804 CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
3806 CurrentSMSMessage->MemoryType = MessageBuffer[5];
3807 CurrentSMSMessage->MessageNumber = MessageBuffer[6];
3809 /* Signal no error to calling code. */
3810 CurrentSMSMessageError = GE_NONE;
3813 fprintf(stdout, "\n");
3820 /* We have requested invalid or empty location. */
3823 fprintf(stdout, _("Message: SMS reading failed\n"));
3825 switch (MessageBuffer[4]) {
3827 fprintf(stdout, _(" Invalid location!\n"));break;
3829 fprintf(stdout, _(" Empty SMS location.\n"));break;
3831 fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
3833 fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
3837 switch (MessageBuffer[4]) {
3838 case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
3839 case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
3840 case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
3841 default :CurrentSMSMessageError = GE_UNKNOWN;break;
3849 GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
3852 unsigned char req[] = { N6110_FRAME_HEADER,
3855 0x00, /* Location */
3860 /* State machine code writes data to these variables when it comes in. */
3862 CurrentSMSMessage = message;
3863 CurrentSMSMessageError = GE_BUSY;
3865 req[5] = message->Location;
3868 Protocol->SendMessage(8, 0x02, req);
3870 /* Wait for timeout or other error. */
3871 while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
3874 return (GE_TIMEOUT);
3879 return (CurrentSMSMessageError);
3882 void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3885 fprintf(stdout, _("Message: SMS deleted successfully.\n"));
3888 CurrentSMSMessageError = GE_NONE;
3891 GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
3893 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
3895 req[5] = message->Location;
3897 return NULL_SendMessageSequence
3898 (50, &CurrentSMSMessageError, 6, 0x14, req);
3901 /* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
3902 GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
3904 GSM_ETSISMSMessage ETSI;
3907 GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
3910 for (i=0;i<36;i++) req[i]=0;
3912 req[12]=ETSI.firstbyte;
3914 for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
3915 req[i]=ETSI.SMSCNumber[i];
3920 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3921 req[i+12+offset]=ETSI.Number[i];
3922 req[10+offset]=ETSI.TPDCS;
3923 req[11+offset]=ETSI.TPUDL;
3924 req[24+offset]=ETSI.TPVP;
3926 // fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
3927 // fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
3928 // fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
3930 // req[]=ETSI.TPPID;
3931 for(i=0;i<*length;i++)
3932 req[i+31+offset]=ETSI.MessageText[i];
3937 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3938 req[i+12+offset]=ETSI.Number[i];
3939 req[10+offset]=ETSI.TPDCS;
3940 req[11+offset]=ETSI.TPUDL;
3941 // req[]=ETSI.TPPID;
3942 for(i=0;i<*length;i++)
3943 req[i+31+offset]=ETSI.MessageText[i];
3945 req[24+offset+i]=ETSI.DeliveryDateTime[i];
3951 *length=*length+offset;
3956 void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
3958 switch (MessageBuffer[3]) {
3960 /* SMS message correctly sent to the network */
3963 fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
3965 CurrentSMSMessageError = GE_SMSSENDOK;
3968 /* SMS message send to the network failed */
3972 fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
3974 switch (MessageBuffer[6]) {
3975 case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3976 case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
3977 case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
3978 case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
3979 case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3980 case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3981 case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3982 case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3983 case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
3986 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
3987 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
3990 CurrentSMSMessageError = GE_SMSSENDFAILED;
3996 GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
4000 unsigned char req[256] = {
4002 0x01, 0x02, 0x00, /* SMS send request*/
4007 error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
4008 if (error != GE_NONE) return error;
4010 return NULL_SendMessageSequence
4011 (200, &CurrentSMSMessageError, 42+length, 0x02, req);
4014 void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4016 switch (MessageBuffer[3]) {
4021 fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
4024 CurrentSMSMessage->MessageNumber=MessageBuffer[5];
4026 CurrentSMSMessageError = GE_NONE;
4031 fprintf(stdout, _("SMS saving failed\n"));
4032 switch (MessageBuffer[4]) {
4033 case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
4034 case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
4035 default :fprintf(stdout, _(" Unknown error.\n"));break;
4039 switch (MessageBuffer[4]) {
4040 case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
4041 case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
4042 default :CurrentSMSMessageError = GE_UNKNOWN;break;
4047 /* GST_DR and GST_UN not supported ! */
4048 GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
4050 unsigned char req[256] = {
4051 N6110_FRAME_HEADER, 0x04, /* SMS save request*/
4052 0x00, /* SMS Status. Different for Inbox and Outbox */
4054 0x00, /* SMS Location */
4055 0x02, /* SMS Type */
4059 SMS_MessageType PDU;
4062 if (SMS->Location) req[6] = SMS->Location;
4064 if (SMS->folder==0) { /*Inbox*/
4065 req[4]=1; /* SMS Status */
4066 req[7] = 0x00; /* SMS Type */
4069 req[4]=5; /* SMS Status */
4070 req[7] = 0x02; /* SMS Type */
4074 if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
4076 error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
4077 if (error != GE_NONE) return error;
4079 CurrentSMSMessage = SMS;
4081 return NULL_SendMessageSequence
4082 (70, &CurrentSMSMessageError, 39+length, 0x14, req);
4085 void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4088 fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
4091 CurrentCBError = GE_NONE;
4094 /* Enable and disable Cell Broadcasting */
4095 GSM_Error N6110_EnableCellBroadcast(void)
4097 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4098 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
4101 fprintf (stdout,"Enabling CB\n");
4104 CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
4105 CurrentCBMessage->Channel = 0;
4106 CurrentCBMessage->New = false;
4107 strcpy (CurrentCBMessage->Message,"");
4109 return NULL_SendMessageSequence
4110 (10, &CurrentCBError, 10, 0x02, req);
4114 GSM_Error N6110_DisableCellBroadcast(void)
4116 /* Should work, but not tested fully */
4118 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
4119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
4121 return NULL_SendMessageSequence
4122 (10, &CurrentCBError, 10, 0x02, req);
4125 void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4128 unsigned char output[160];
4130 CurrentCBMessage->Channel = MessageBuffer[7];
4131 CurrentCBMessage->New = true;
4132 tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
4135 fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
4137 fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
4141 for (i=0; i<tmp;i++) {
4142 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
4145 fprintf(stdout, "\n");
4148 for (i=0; i<tmp; i++) {
4149 CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
4151 CurrentCBMessage->Message[i]=0;
4154 GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
4157 fprintf(stdout,"Reading CB\n");
4160 if (CurrentCBMessage != NULL)
4162 if (CurrentCBMessage->New == true)
4165 fprintf(stdout,"New CB received\n");
4167 Message->Channel = CurrentCBMessage->Channel;
4168 strcpy(Message->Message,CurrentCBMessage->Message);
4169 CurrentCBMessage->New = false;
4173 return (GE_NONEWCBRECEIVED);
4176 int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
4180 req[count++]=Bitmap.number;
4181 req[count++]=strlen(Bitmap.text);
4182 memcpy(req+count,Bitmap.text,req[count-1]);
4183 count+=req[count-1];
4184 req[count++]=Bitmap.ringtone;
4186 /* Setting for graphic:
4189 0x02 - View Graphics
4190 0x03 - Send Graphics
4192 You can even set it higher but Nokia phones (my
4193 6110 at least) will not show you the name of this
4194 item in menu ;-)) Nokia is really joking here. */
4195 if (Bitmap.enabled) req[count++]=0x01;
4196 else req[count++]=0x00;
4198 req[count++]=(Bitmap.size+4)>>8;
4199 req[count++]=(Bitmap.size+4)%0xff;
4200 req[count++]=0x00; /* Future extensions! */
4201 req[count++]=Bitmap.width;
4202 req[count++]=Bitmap.height;
4203 req[count++]=0x01; /* Just BW */
4204 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4206 return count+Bitmap.size;
4209 int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4213 EncodeNetworkCode(req+count, Bitmap.netcode);
4216 req[count++]=(Bitmap.size+4)>>8;
4217 req[count++]=(Bitmap.size+4)%0xff;
4218 req[count++]=0x00; /* Infofield */
4219 req[count++]=Bitmap.width;
4220 req[count++]=Bitmap.height;
4221 req[count++]=0x01; /* Just BW */
4222 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4224 return count+Bitmap.size;
4227 int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
4232 req[count++]=Bitmap.height;
4233 req[count++]=Bitmap.width;
4234 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
4236 return count+Bitmap.size;
4239 /* Set a bitmap or welcome-note */
4240 GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
4242 unsigned char req[600] = { N6110_FRAME_HEADER };
4248 /* Direct uploading variables */
4249 GSM_MultiSMSMessage SMS;
4250 unsigned char buffer[1000] = {0x0c,0x01};
4251 GSM_NetworkInfo NetworkInfo;
4255 /* Uploading with preview */
4256 if (Bitmap->number==255 &&
4257 (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
4258 GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
4259 memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
4261 memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
4263 buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
4265 Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
4267 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4268 return GE_NONE; //no answer from phone
4271 CurrentSetBitmapError = GE_BUSY;
4273 switch (Bitmap->type) {
4274 case GSM_WelcomeNoteText:
4275 case GSM_DealerNoteText:
4277 req[count++]=0x01; /* Only one block */
4279 if (Bitmap->type==GSM_WelcomeNoteText)
4280 req[count++]=0x02; /* Welcome text */
4282 req[count++]=0x03; /* Dealer Welcome Note */
4284 textlen=strlen(Bitmap->text);
4285 req[count++]=textlen;
4286 memcpy(req+count,Bitmap->text,textlen);
4290 Protocol->SendMessage(count, 0x05, req);
4294 case GSM_StartupLogo:
4295 if (Bitmap->number==0) {
4297 /* For 33xx we first set animated logo to default */
4298 if (GetModelFeature (FN_STARTUP)==F_STANIM) {
4299 error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4300 if (error!=GE_NONE) return error;
4304 req[count++]=0x01; /* Only one block */
4305 count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
4306 Protocol->SendMessage(count, 0x05, req);
4308 return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
4312 case GSM_OperatorLogo:
4313 req[count++]=0x30; /* Store Op Logo */
4314 req[count++]=0x01; /* Location */
4315 count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
4316 Protocol->SendMessage(count, 0x05, req);
4319 case GSM_CallerLogo:
4321 count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
4322 Protocol->SendMessage(count, 0x03, req);
4325 case GSM_PictureImage:
4327 req[count++]=Bitmap->number;
4328 if (strcmp(Bitmap->Sender,"")) {
4329 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
4331 /* Convert number of semioctets to number of chars and add count */
4333 if (textlen % 2) textlen++;
4334 count+=textlen / 2 + 1;
4342 req[count++]=strlen(Bitmap->text);
4343 memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
4344 count+=strlen(Bitmap->text);
4346 req[count++]=Bitmap->width;
4347 req[count++]=Bitmap->height;
4349 memcpy(req+count,Bitmap->bitmap,Bitmap->size);
4350 Protocol->SendMessage(count+Bitmap->size, 0x47, req);
4353 case GSM_7110OperatorLogo:
4354 case GSM_7110StartupLogo:
4355 case GSM_6210StartupLogo:
4356 return GE_NOTSUPPORTED;
4362 /* Wait for timeout or other error. */
4363 while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
4366 return (GE_TIMEOUT);
4371 return CurrentSetBitmapError;
4374 /* Get a bitmap from the phone */
4375 GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
4377 unsigned char req[10] = { N6110_FRAME_HEADER };
4382 CurrentGetBitmap=Bitmap;
4383 CurrentGetBitmapError = GE_BUSY;
4385 switch (CurrentGetBitmap->type) {
4386 case GSM_StartupLogo:
4387 case GSM_WelcomeNoteText:
4388 case GSM_DealerNoteText:
4390 Protocol->SendMessage(count, 0x05, req);
4392 case GSM_OperatorLogo:
4394 req[count++]=0x01; /* Location 1 */
4395 Protocol->SendMessage(count, 0x05, req);
4397 case GSM_CallerLogo:
4399 req[count++]=Bitmap->number;
4400 Protocol->SendMessage(count, 0x03, req);
4402 case GSM_PictureImage:
4404 req[count++]=Bitmap->number;
4405 Protocol->SendMessage(count, 0x47, req);
4407 case GSM_7110OperatorLogo:
4408 case GSM_7110StartupLogo:
4409 case GSM_6210StartupLogo:
4411 return GE_NOTSUPPORTED;
4414 /* Wait for timeout or other error. */
4415 while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
4418 return (GE_TIMEOUT);
4423 CurrentGetBitmap=NULL;
4425 return CurrentGetBitmapError;
4428 void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4430 switch (MessageBuffer[3]) {
4432 /* Set ringtone OK */
4435 fprintf(stdout, _("Message: Ringtone set OK!\n"));
4437 CurrentRingtoneError=GE_NONE;
4440 /* Set ringtone error */
4443 fprintf(stdout, _("Message: Ringtone setting error !\n"));
4445 CurrentRingtoneError=GE_NOTSUPPORTED;
4450 GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
4453 char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
4454 {N6110_FRAME_HEADER,
4456 0x00, /* Location */
4459 int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
4461 /* Variables for preview uploading */
4462 unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
4463 unsigned char buffer2[20];
4464 GSM_NetworkInfo NetworkInfo;
4466 /* Setting ringtone with preview */
4467 if (ringtone->location==255) {
4470 EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
4471 memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
4472 *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
4473 Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
4474 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4476 return GE_NONE; //no answer from phone
4479 *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
4481 req[4]=ringtone->location-1;
4483 return NULL_SendMessageSequence
4484 (50, &CurrentRingtoneError, (size+7), 0x05, req);
4487 void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4491 switch (MessageBuffer[4]) {
4492 case 0x00: /* location supported. We have ringtone */
4494 /* Binary format used in N6150 */
4495 if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4497 fprintf(stdout,_("Message: ringtone \""));
4504 if (MessageBuffer[i]!=0)
4505 fprintf(stdout,_("%c"),MessageBuffer[i]);
4507 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4508 if (MessageBuffer[i]==0) break;
4513 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4516 /* Looking for end */
4519 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4522 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4526 if (i==MessageLength) break;
4530 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4531 CurrentGetBinRingtone->length=i-3;
4533 CurrentBinRingtoneError=GE_NONE;
4537 /* Binary format used in N3210 */
4538 if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
4541 fprintf(stdout,_("Message: ringtone \""));
4548 if (MessageBuffer[i]!=0)
4549 fprintf(stdout,_("%c"),MessageBuffer[i]);
4551 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
4552 if (MessageBuffer[i]==0) break;
4557 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
4560 /* Here changes to get full compatibility with binary format used in N6150 */
4563 MessageBuffer[5]=0x0c;
4564 MessageBuffer[6]=0x01;
4565 MessageBuffer[7]=0x2c;
4567 /* Looking for end */
4570 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
4573 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
4577 if (i==MessageLength) break;
4581 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
4583 CurrentGetBinRingtone->length=i-3;
4585 CurrentBinRingtoneError=GE_NONE;
4590 memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
4592 CurrentGetBinRingtone->length=MessageLength;
4595 fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
4597 CurrentBinRingtoneError=GE_UNKNOWNMODEL;
4603 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4606 CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
4610 GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
4612 unsigned char req[] = { 0x00,0x01,0x9e,
4617 CurrentGetBinRingtone=ringtone;
4619 error=N6110_EnableExtendedCommands(0x01);
4620 if (error!=GE_NONE) return error;
4622 req[3]=ringtone->location-1;
4624 return NULL_SendMessageSequence
4625 (50, &CurrentBinRingtoneError, 4, 0x40, req);
4628 void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4630 switch (MessageBuffer[4]) {
4631 case 0x00: /* location supported. We set ringtone */
4633 fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
4635 CurrentBinRingtoneError=GE_NONE;
4640 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
4642 CurrentBinRingtoneError=GE_NOTSUPPORTED;
4647 GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
4649 unsigned char req[1000] = { 0x00,0x01,0xa0};
4653 GSM_BinRingtone ring;
4655 /* Must be sure, that can upload ringtone to this phone */
4656 ring.location=ringtone->location;
4657 error=N6110_GetBinRingTone(&ring);
4658 if (error!=GE_NONE) return error;
4660 error=N6110_EnableExtendedCommands(0x01);
4661 if (error!=GE_NONE) return error;
4663 memcpy(req+3,ringtone->frame,ringtone->length);
4665 req[3]=ringtone->location-1;
4667 return NULL_SendMessageSequence
4668 (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
4671 #endif /* UCLINUX */
4673 GSM_Error N6110_Reset(unsigned char type)
4675 return N6110_EnableExtendedCommands(type);
4678 void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4685 switch (MessageBuffer[3]) {
4687 /* Unknown message - it has been seen after the 0x07 message (call
4688 answered). Probably it has similar meaning. If you can solve
4689 this - just mail me. Pavel JanÃk ml.
4691 The message looks like this:
4699 Phone: [01 ][08 ][00 ] is the header of the frame
4701 [03 ] is the call message subtype
4703 [05 ] is the call sequence number
4707 [00 ][01 ][03 ][02 ][91][00] are unknown but has been
4708 seen in the Incoming call message (just after the
4709 caller's name from the phonebook). But never change
4710 between phone calls :-(
4713 /* This may mean sequence number of 'just made' call - CK */
4717 fprintf(stdout, _("Message: Call message, type 0x02:"));
4718 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4723 /* Possibly call OK */
4724 /* JD: I think that this means "call in progress" (incomming or outgoing) */
4728 fprintf(stdout, _("Message: Call message, type 0x03:"));
4729 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4730 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4733 CurrentCallSequenceNumber=MessageBuffer[4];
4735 CurrentIncomingCall[0]='D';
4736 #endif /* UCLINUX */
4737 if (CurrentCallPassup) CurrentCallPassup('D');
4741 /* Remote end has gone away before you answer the call. Probably your
4742 mother-in-law or banker (which is worse?) ... */
4746 fprintf(stdout, _("Message: Remote end hang up.\n"));
4747 fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
4749 switch (MessageBuffer[6]) {
4750 case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
4751 case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
4752 case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
4753 case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4754 case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
4755 case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
4758 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
4759 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
4763 CurrentIncomingCall[0] = ' ';
4764 #endif /* UCLINUX */
4765 if (CurrentCallPassup) CurrentCallPassup(' ');
4769 /* Incoming call alert */
4773 fprintf(stdout, _("Message: Incoming call alert:\n"));
4775 /* We can have more then one call ringing - we can distinguish between
4778 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4779 fprintf(stdout, _(" Number: "));
4781 count=MessageBuffer[6];
4783 for (tmp=0; tmp <count; tmp++)
4784 fprintf(stdout, "%c", MessageBuffer[7+tmp]);
4786 fprintf(stdout, "\n");
4788 fprintf(stdout, _(" Name: "));
4790 for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
4791 fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
4793 fprintf(stdout, "\n");
4796 count=MessageBuffer[6];
4799 CurrentIncomingCall[0] = 0;
4800 for (tmp=0; tmp <count; tmp++)
4801 sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
4802 #endif /* UCLINUX */
4806 /* Call answered. Probably your girlfriend...*/
4810 fprintf(stdout, _("Message: Call answered.\n"));
4811 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4816 /* Call ended. Girlfriend is girlfriend, but time is money :-) */
4820 fprintf(stdout, _("Message: Call ended by your phone.\n"));
4821 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4826 /* This message has been seen with the message of subtype 0x09
4827 after I hang the call.
4834 Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
4836 What is the meaning of 87? Can you spell some magic light into
4841 /* Probably means call over - CK */
4845 fprintf(stdout, _("Message: Call message, type 0x0a:"));
4846 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
4847 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
4851 CurrentIncomingCall[0] = ' ';
4852 #endif /* UCLINUX */
4853 if (CurrentCallPassup) CurrentCallPassup(' ');
4860 fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
4864 if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
4865 #endif /* UCLINUX */
4867 if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
4874 fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
4876 AppendLogText("Unknown msg\n",false);
4878 break; /* Visual C Don't like empty cases */
4884 static void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
4888 switch (MessageBuffer[3]) {
4892 /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
4893 /* If you want see, if it works with your phone make something like that: */
4895 /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
4896 /* Protocol->SendMessage(4, 0x04, connect5); */
4898 /* Marcin-Wiacek@TopNet.PL */
4900 #if defined(WIN32) || defined(UCLINUX)
4901 sprintf(Current_IMEI, "%s", MessageBuffer+5);
4902 sprintf(Current_Model, "%s", MessageBuffer+21);
4903 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4905 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
4906 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
4907 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
4911 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
4912 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
4913 fprintf(stdout, _(" Model: %s\n"), Current_Model);
4914 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
4915 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
4916 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
4921 /* Get group data */
4922 /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
4925 if (CurrentGetBitmap!=NULL) {
4926 if (CurrentGetBitmap->number==MessageBuffer[4]) {
4927 count=MessageBuffer[5];
4928 memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
4929 CurrentGetBitmap->text[count]=0;
4932 fprintf(stdout, _("Message: Caller group datas\n"));
4933 fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
4938 CurrentGetBitmap->ringtone=MessageBuffer[count++];
4940 fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
4941 if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
4942 fprintf(stdout,_("\n"));
4945 CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
4947 fprintf(stdout, _("Caller group logo "));
4948 if (CurrentGetBitmap->enabled)
4949 fprintf(stdout, _("enabled \n"));
4951 fprintf(stdout, _("disabled \n"));
4954 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
4955 CurrentGetBitmap->size+=MessageBuffer[count++];
4957 fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
4961 CurrentGetBitmap->width=MessageBuffer[count++];
4962 CurrentGetBitmap->height=MessageBuffer[count++];
4964 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
4965 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
4966 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
4967 CurrentGetBitmapError=GE_NONE;
4970 fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
4975 fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
4980 /* Get group data error */
4983 CurrentGetBitmapError=GE_UNKNOWN;
4985 fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
4989 /* Set group data OK */
4992 CurrentSetBitmapError=GE_NONE;
4994 fprintf(stdout, _("Message: Caller group data set correctly.\n"));
4998 /* Set group data error */
5001 CurrentSetBitmapError=GE_UNKNOWN;
5003 fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
5010 fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
5012 AppendLogText("Unknown msg\n",false);
5014 break; /* Visual C Don't like empty cases */
5018 static void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5020 int tmp, count, length;
5027 switch (MessageBuffer[3]) {
5033 fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
5036 if (CurrentGetBitmap!=NULL) {
5042 for (tmp=0;tmp<MessageBuffer[4];tmp++){
5043 switch (MessageBuffer[count++]) {
5045 if (CurrentGetBitmap->type==GSM_StartupLogo) {
5046 CurrentGetBitmap->height=MessageBuffer[count++];
5047 CurrentGetBitmap->width=MessageBuffer[count++];
5048 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5049 length=CurrentGetBitmap->size;
5050 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
5052 length=MessageBuffer[count++];
5053 length=length*MessageBuffer[count++]/8;
5057 fprintf(stdout, _("Startup logo supported - "));
5058 if (length!=0) { fprintf(stdout, _("currently set\n")); }
5059 else { fprintf(stdout, _("currently empty\n")); }
5061 if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
5064 length=MessageBuffer[count];
5065 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
5066 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5067 CurrentGetBitmap->text[length]=0;
5070 fprintf(stdout, _("Startup Text supported - "));
5073 fprintf(stdout, _("currently set to \""));
5074 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5075 fprintf(stdout, _("\"\n"));
5077 fprintf(stdout, _("currently empty\n"));
5081 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
5084 length=MessageBuffer[count];
5085 if (CurrentGetBitmap->type==GSM_DealerNoteText) {
5086 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
5087 CurrentGetBitmap->text[length]=0;
5090 fprintf(stdout, _("Dealer Welcome supported - "));
5093 fprintf(stdout, _("currently set to \""));
5094 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
5095 fprintf(stdout, _("\"\n"));
5097 fprintf(stdout, _("currently empty\n"));
5101 if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
5105 if (issupported) CurrentGetBitmapError=GE_NONE;
5106 else CurrentGetBitmapError=GE_NOTSUPPORTED;
5109 fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
5114 /* Set startup OK */
5117 CurrentSetBitmapError=GE_NONE;
5119 fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
5123 /* Set Operator Logo OK */
5127 fprintf(stdout, _("Message: Operator logo correctly set.\n"));
5130 CurrentSetBitmapError=GE_NONE;
5133 /* Set Operator Logo Error */
5137 fprintf(stdout, _("Message: Error setting operator logo!\n"));
5140 CurrentSetBitmapError=GE_UNKNOWN;
5144 /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
5147 if (CurrentGetBitmap!=NULL) {
5149 count=5; /* Location ignored. */
5151 DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
5155 fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
5156 CurrentGetBitmap->netcode,
5157 GSM_GetNetworkName(CurrentGetBitmap->netcode));
5160 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
5161 CurrentGetBitmap->size+=MessageBuffer[count++];
5163 CurrentGetBitmap->width=MessageBuffer[count++];
5164 CurrentGetBitmap->height=MessageBuffer[count++];
5166 tmp=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5167 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
5168 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
5169 CurrentGetBitmapError=GE_NONE;
5172 fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
5178 /* Get op logo error */
5182 fprintf(stdout, _("Message: Error getting operator logo!\n"));
5184 CurrentGetBitmapError=GE_UNKNOWN;
5190 fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
5192 AppendLogText("Unknown msg\n",false);
5198 static void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5201 unsigned char output[160];
5207 switch (MessageBuffer[3]) {
5211 /* MessageBuffer[3] = 0x05
5212 MessageBuffer[4] = 0x00
5213 MessageBuffer[5] = 0x0f
5214 MessageBuffer[6] = 0x03
5215 MessageBuffer[7] = length of packed message
5217 This is all I have seen - Gerry Anderson */
5219 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
5223 fprintf(stdout, _("Message from Network operator: "));
5225 for (i=0; i<tmp; i++)
5226 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
5228 fprintf(stdout, "\n");
5237 fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
5239 AppendLogText("Unknown msg\n",false);
5245 static void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5247 switch (MessageBuffer[3]) {
5251 fprintf(stdout, _("Message: SIM card login\n"));
5257 fprintf(stdout, _("Message: SIM card logout\n"));
5263 fprintf(stdout, _("Unknown message of type 0x09.\n"));
5265 AppendLogText("Unknown msg\n",false);
5270 static void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5272 switch(MessageBuffer[3]) {
5277 fprintf(stdout, _("Message: Calendar Alarm active\n"));
5278 fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
5283 fprintf(stdout, _("Unknown message of type 0x13.\n"));
5285 AppendLogText("Unknown msg\n",false);
5290 #endif /* UCLINUX */
5292 void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5296 switch(MessageBuffer[2]) {
5301 fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
5304 CurrentMagicError=GE_NONE;
5310 fprintf(stdout, _("Message: Answer for call commands.\n"));
5313 CurrentDialVoiceError=GE_NONE;
5319 fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
5322 CurrentMagicError=GE_NONE;
5328 fprintf(stdout, _("Message: ACK for simlock closing\n"));
5331 CurrentMagicError=GE_NONE;
5336 switch (MessageBuffer[5]) {
5339 fprintf(stdout,_("Message: EEPROM contest received\n"));
5342 if (MessageBuffer[8]!=0x00) {
5343 for (i=9;i<MessageLength;i++) {
5344 fprintf(stdout,_("%c"), MessageBuffer[i]);
5347 CurrentMagicError=GE_NONE;
5354 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5356 AppendLogText("Unknown msg\n",false);
5362 N6110_DisplayTestsInfo(MessageBuffer);
5364 #endif /* UCLINUX */
5369 fprintf(stdout, _("Unknown message of type 0x40.\n"));
5371 AppendLogText("Unknown msg\n",false);
5372 break; /* Visual C Don't like empty cases */
5378 static void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5382 switch(MessageBuffer[3]) {
5388 if (MessageBuffer[5]!=0) {
5389 strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
5391 while (MessageBuffer[count]!=0) {
5397 strcpy(CurrentGetBitmap->Sender,"\0");
5402 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
5403 CurrentGetBitmap->text[MessageBuffer[count]]=0;
5405 if (MessageBuffer[count]!=0)
5406 count+=MessageBuffer[count];
5411 fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
5414 CurrentGetBitmap->width=MessageBuffer[count+1];
5415 CurrentGetBitmap->height=MessageBuffer[count+2];
5416 CurrentGetBitmap->size=CurrentGetBitmap->height*CurrentGetBitmap->width/8;
5418 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
5420 CurrentGetBitmapError=GE_NONE;
5426 fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
5428 CurrentSetBitmapError=GE_NONE;
5429 CurrentGetBitmapError=GE_NONE;
5435 fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
5437 CurrentSetBitmapError=GE_UNKNOWN;
5443 fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
5445 CurrentGetBitmapError=GE_UNKNOWN;
5451 fprintf(stdout, _("Unknown message of type 0x47.\n"));
5453 AppendLogText("Unknown msg\n",false);
5454 break; /* Visual C Don't like empty cases */
5458 #endif /* UCLINUX */
5460 void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5463 sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
5464 AppendLog(buffer,strlen(buffer),false);
5467 fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
5471 CurrentLinkOK = true;
5474 static void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5477 fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
5482 /* This function is used for parsing the RLP frame into fields. */
5483 void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
5490 /* We do not need RLP frame parsing to be done when we do not have callback
5492 if (CurrentRLP_RXCallback == NULL)
5495 /* Anybody know the official meaning of the first two bytes?
5496 Nokia 6150 sends junk frames starting D9 01, and real frames starting
5497 D9 00. We'd drop the junk frames anyway because the FCS is bad, but
5498 it's tidier to do it here. We still need to call the callback function
5499 to give it a chance to handle timeouts and/or transmit a frame */
5500 if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
5503 /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
5504 specification, so Header consists of 16 bits (2 bytes). See section 4.1
5505 of the specification. */
5507 frame.Header[0] = MessageBuffer[2];
5508 frame.Header[1] = MessageBuffer[3];
5510 /* Next 200 bits (25 bytes) contain the Information. We store the
5511 information in the Data array. */
5513 for (count = 0; count < 25; count ++)
5514 frame.Data[count] = MessageBuffer[4 + count];
5516 /* The last 24 bits (3 bytes) contain FCS. */
5518 frame.FCS[0] = MessageBuffer[29];
5519 frame.FCS[1] = MessageBuffer[30];
5520 frame.FCS[2] = MessageBuffer[31];
5522 /* Here we pass the frame down in the input stream. */
5523 CurrentRLP_RXCallback(valid ? &frame : NULL);
5526 static void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5529 fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
5536 void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5538 GSM_SMSMessage NullSMS;
5540 switch (MessageBuffer[6]) {
5542 case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
5543 case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
5545 /* Is it possible ? */
5546 case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
5547 default: NullSMS.Type = GST_UN; break;
5551 if (NullSMS.Type == GST_DR)
5552 fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
5554 fprintf(stdout, _("Message: SMS Message Received\n"));
5557 GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
5560 fprintf(stdout, _("\n"));
5564 #endif /* UCLINUX */
5566 void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
5570 /* Switch on the basis of the message type byte */
5571 switch (MessageType) {
5573 /* Call information */
5576 N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
5582 switch (MessageBuffer[3]) {
5584 case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5585 case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
5586 case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5587 case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
5588 case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5590 case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
5591 default :unknown=true;break;
5594 #endif /* UCLINUX */
5596 /* Phonebook handling */
5598 switch (MessageBuffer[3]) {
5600 case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
5602 case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
5604 case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
5606 case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5608 case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
5610 default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
5611 #endif /* UCLINUX */
5617 switch (MessageBuffer[3]) {
5618 case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
5619 default :unknown=true;break;
5624 /* Startup Logo, Operator Logo and Profiles. */
5626 switch (MessageBuffer[3]) {
5627 case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5628 case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5629 case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
5630 case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
5631 case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5632 case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
5633 default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
5637 /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
5640 switch (MessageBuffer[3]) {
5642 case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
5643 default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
5647 /* Security code requests */
5649 switch (MessageBuffer[3]) {
5650 case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
5651 case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5652 default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5659 N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
5664 switch (MessageBuffer[3]) {
5665 case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
5666 default :unknown=true;break;
5670 /* Simulating key pressing */
5672 switch (MessageBuffer[3]) {
5673 case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
5674 default :unknown=true;break;
5680 switch (MessageBuffer[3]) {
5681 case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5682 case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
5683 case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
5684 default :unknown=true;break;
5688 /* Phone Clock and Alarm */
5690 switch (MessageBuffer[3]) {
5691 case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
5692 case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
5693 case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
5694 case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
5695 default :unknown=true;break;
5699 /* Calendar notes handling */
5701 switch (MessageBuffer[3]) {
5702 case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5703 case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
5704 case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
5705 default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
5711 switch (MessageBuffer[3]) {
5713 case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5715 case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
5716 case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
5718 case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
5719 default :unknown=true;break;
5725 switch (MessageBuffer[3]) {
5727 case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
5729 case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5731 case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5734 case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
5735 default :unknown=true;break;
5738 #endif /* UCLINUX */
5740 /* Internal phone functions? */
5742 switch (MessageBuffer[2]) {
5743 case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
5745 case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
5746 #endif /* UCLINUX */
5747 case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
5749 case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5750 case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
5751 case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
5752 case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
5753 case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
5754 case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5755 case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
5756 case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
5757 case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5758 case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
5759 #endif /* UCLINUX */
5760 case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
5761 default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
5766 /* Picture Images */
5769 N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
5771 #endif /* UCLINUX */
5773 /* Mobile phone identification */
5776 N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
5779 /***** Acknowlegment of our frames. *****/
5780 case FBUS_FRTYPE_ACK:
5782 N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
5785 /***** Power on message. *****/
5788 N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
5793 N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
5796 /***** RLP frame received. *****/
5799 N6110_RX_HandleRLPMessage(MessageBuffer);
5802 /***** Power on message. *****/
5805 N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
5808 /***** Unknown message *****/
5809 /* If you think that you know the exact meaning of other messages - please
5814 fprintf(stdout, _("Message: Unknown message type.\n"));
5816 AppendLogText("Unknown msg type\n",false);
5825 fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
5827 AppendLogText("Unknown msg\n",false);