5 A Linux/Unix toolset and driver for Nokia mobile phones.
\r
7 Released under the terms of the GNU GPL, see file COPYING for more details.
\r
9 This file provides an API for accessing functions on the 6110 and similar
\r
14 /* "Turn on" prototypes in n-6110.h */
\r
18 /* System header files */
\r
24 #include "misc_win32.h"
\r
27 /* Various header file */
\r
32 #include "gsm-api.h"
\r
33 #include "gsm-coding.h"
\r
34 #include "newmodules/n6110.h"
\r
35 #include "newmodules/n7110.h"
\r
36 #include "protocol/fbus.h"
\r
37 #include "devices/device.h"
\r
38 \r\r/* Global variables used by code in gsm-api.c to expose the functions
\r
39 supported by this model of phone. */
\r
47 /* Here we initialise model specific functions. */
\r
48 GSM_Functions N6110_Functions = {
\r
50 N6110_DispatchMessage,
\r
53 N6110_GetMemoryLocation,
\r
54 N6110_WritePhonebookLocation,
\r
57 N6110_GetMemoryStatus,
\r
61 N6110_GetSMSMessage,
\r
62 N6110_DeleteSMSMessage,
\r
63 N6110_SendSMSMessage,
\r
64 N6110_SaveSMSMessage,
\r
66 N6110_GetBatteryLevel,
\r
67 N6110_GetPowerSource,
\r
68 N6110_GetDisplayStatus,
\r
69 N6110_EnterSecurityCode,
\r
70 N6110_GetSecurityCodeStatus,
\r
71 N6110_GetSecurityCode,
\r
81 N6110_GetIncomingCallNr,
\r
82 N6110_GetNetworkInfo,
\r
83 N6110_GetCalendarNote,
\r
84 N6110_WriteCalendarNote,
\r
85 N6110_DeleteCalendarNote,
\r
91 N6110_SetBinRingTone,
\r
92 N6110_GetBinRingTone,
\r
99 N6110_EnableDisplayOutput,
\r
100 N6110_DisableDisplayOutput,
\r
101 N6110_EnableCellBroadcast,
\r
102 N6110_DisableCellBroadcast,
\r
103 N6110_ReadCellBroadcast,
\r
105 N6110_GetProductProfileSetting,
\r
106 N6110_SetProductProfileSetting,
\r
107 N6110_GetOperatorName,
\r
108 N6110_SetOperatorName,
\r
109 N6110_GetVoiceMailbox,
\r N6110_Tests,
111 UNIMPLEMENTED, //GetCalendarNotesInfo
113 N6110_ResetPhoneSettings,
114 N7110_GetWAPBookmark,
115 N7110_SetWAPBookmark,
116 N7110_GetWAPSettings,
119 N6110_GetManufacturer
122 /* Mobile phone information */
\r
124 GSM_Information N6110_Information = {
\r
125 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
\r
126 /* Supported models in FBUS */
\r
127 "3210|3310|3330|5110|5130|5190|6110|6130|6150|6190|8210|8850",
\r
128 /* Supported models in MBUS */
\r
129 "6110|6130|6150|8210|8850",
\r
130 /* Supported models in FBUS over infrared */
\r
132 /* Supported models in FBUS over DLR3 */
\r
136 /* infrared sockets */
137 "6110|6130|6150|8210|8850",
138 /* Supported models in FBUS over infrared with Tekram device */
\r
139 4, /* Max RF Level */
\r
140 0, /* Min RF Level */
\r
141 GRF_Arbitrary, /* RF level units */
\r
142 4, /* Max Battery Level */
\r
143 0, /* Min Battery Level */
\r
144 GBU_Arbitrary, /* Battery level units */
\r
145 GDT_DateTime, /* Have date/time support */
\r
146 GDT_TimeOnly, /* Alarm supports time only */
\r
147 1 /* Only one alarm available */
\r
150 const char *N6110_MemoryType_String [] = {
\r
163 /* Magic bytes from the phone. */
\r
164 unsigned char MagicBytes[4] = { 0x00, 0x00, 0x00, 0x00 };
\r
166 /* For DisplayOutput */
\r
167 char PhoneScreen[5+1][27+1];
\r
168 int OldX=1000,OldY=0,NewX=0,NewY=0;
\r
170 void N6110_ReplyEnableExtendedCommands(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
173 fprintf(stdout, _("Message: Answer for EnableExtendedSecurityCommands frame, meaning not known :-(\n"));
\r
176 CurrentEnableExtendedCommandsError=GE_NONE;
\r
179 /* If you set make some things (for example,
\r
180 change Security Code from phone's menu, disable and enable
\r
181 phone), it won't answer for 0x40 frame - you won't be able
\r
182 to play tones, get netmonitor, etc.
\r
184 This function do thing called "Enabling extended security commands" -
\r
185 it enables 0x40 frame functions.
\r
187 This frame can also some other things - see below */
\r
188 GSM_Error N6110_EnableExtendedCommands (unsigned char status)
\r
190 unsigned char req[4] = { 0x00,
\r
191 0x01,0x64, /* Enable extended commands request */
\r
192 0x01 }; /* 0x01 - on, 0x00 - off,
\r
193 0x03 & 0x04 - soft & hard reset,
\r
194 0x06 - CONTACT SERVICE */
\r
196 /* 0x06 MAKES CONTACT SERVICE! BE CAREFULL! */
\r
197 /* When use 0x03 and had during session changed time & date
198 some phones (like 6150 or 6210) can ask for time & date after reset
199 or disable clock on the screen */
200 if (status!=0x06) req[3] = status;
\r
202 return NULL_SendMessageSequence
\r
203 (50, &CurrentEnableExtendedCommandsError, 4, 0x40, req);
\r
206 void N6110_ReplyIMEI(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
208 #if defined WIN32 || !defined HAVE_SNPRINTF
\r
209 sprintf(Current_IMEI, "%s", MessageBuffer+4);
\r
211 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+4);
\r
215 fprintf(stdout, _("Message: IMEI %s received\n"),Current_IMEI);
\r
218 CurrentGetIMEIError=GE_NONE;
\r
221 GSM_Error N6110_SendIMEIFrame()
\r
223 unsigned char req[4] = {0x00, 0x01, 0x66, 0x00};
\r
227 error=N6110_EnableExtendedCommands(0x01);
\r
228 if (error!=GE_NONE) return error;
\r
230 return NULL_SendMessageSequence (20, &CurrentGetIMEIError, 4, 0x40, req);
\r
233 void N6110_ReplyHW(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
237 if (MessageBuffer[3]==0x05) {
\r
240 fprintf(stdout,_("Message: Hardware version received: "));
\r
243 j=strlen(Current_Revision);
\r
244 Current_Revision[j++]=',';
\r
245 Current_Revision[j++]=' ';
\r
246 Current_Revision[j++]='H';
\r
247 Current_Revision[j++]='W';
\r
249 for (i=5;i<9;i++) {
\r
251 fprintf(stdout,_("%c"), MessageBuffer[i]);
\r
253 Current_Revision[j++]=MessageBuffer[i];
\r
257 fprintf(stdout,_("\n"));
\r
260 CurrentGetHWError=GE_NONE;
\r
264 GSM_Error N6110_SendHWFrame()
\r
266 unsigned char req[4] = {0x00, 0x01, 0xc8, 0x05};
\r
270 error=N6110_EnableExtendedCommands(0x01);
\r
271 if (error!=GE_NONE) return error;
\r
273 return NULL_SendMessageSequence (20, &CurrentGetHWError, 4, 0x40, req);
\r
276 void N6110_ReplyID(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
281 fprintf(stdout, _("Message: Mobile phone model identification received:\n"));
\r
282 fprintf(stdout, _(" Firmware: "));
\r
285 strcpy(Current_Revision,"SW");
\r
288 while (MessageBuffer[i]!=0x0a) {
\r
289 Current_Revision[j]=MessageBuffer[i];
\r
291 fprintf(stdout, _("%c"),MessageBuffer[i]);
\r
293 if (j==GSM_MAX_REVISION_LENGTH-1) {
\r
295 fprintf(stderr,_("ERROR: increase GSM_MAX_REVISION_LENGTH!\n"));
\r
302 Current_Revision[j+1]=0;
\r
305 fprintf(stdout, _("\n Firmware date: "));
\r
309 while (MessageBuffer[i]!=0x0a) {
\r
311 fprintf(stdout, _("%c"),MessageBuffer[i]);
\r
317 fprintf(stdout, _("\n Model: "));
\r
321 while (MessageBuffer[i]!=0x0a) {
\r
322 Current_Model[j]=MessageBuffer[i];
\r
324 fprintf(stdout, _("%c"),MessageBuffer[i]);
\r
326 if (j==GSM_MAX_MODEL_LENGTH-1) {
\r
328 fprintf(stderr,_("ERROR: increase GSM_MAX_MODEL_LENGTH!\n"));
\r
335 Current_Model[j+1]=0;
\r
338 fprintf(stdout, _("\n"));
\r
341 CurrentMagicError=GE_NONE;
\r
344 GSM_Error N6110_SendIDFrame()
\r
346 unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
\r
348 return NULL_SendMessageSequence (50, &CurrentMagicError, 5, 0xd1, req);
\r
351 /* This function send the status request to the phone. */
\r
352 /* Seems to be ignored in N3210 */
\r
353 GSM_Error N6110_SendStatusRequest(void)
\r
355 unsigned char req[] = {N6110_FRAME_HEADER, 0x01};
\r
357 Protocol->SendMessage(4, 0x04, req);
\r
362 void N6110_ReplyGetAuthentication(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
364 #if defined WIN32 || !defined HAVE_SNPRINTF
\r
365 sprintf(Current_IMEI, "%s", MessageBuffer+9);
\r
366 sprintf(Current_Model, "%s", MessageBuffer+25);
\r
367 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
\r
369 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+9);
\r
370 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+25);
\r
371 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+44, MessageBuffer+39);
\r
375 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
\r
376 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
\r
377 fprintf(stdout, _(" Model: %s\n"), Current_Model);
\r
378 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+31);
\r
379 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+39);
\r
380 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+44);
\r
382 /* These bytes are probably the source of the "Accessory not connected"
\r
383 messages on the phone when trying to emulate NCDS... I hope....
\r
384 UPDATE: of course, now we have the authentication algorithm. */
\r
385 fprintf(stdout, _(" Magic bytes: %02x %02x %02x %02x\n"), MessageBuffer[50], MessageBuffer[51], MessageBuffer[52], MessageBuffer[53]);
\r
388 MagicBytes[0]=MessageBuffer[50];
\r
389 MagicBytes[1]=MessageBuffer[51];
\r
390 MagicBytes[2]=MessageBuffer[52];
\r
391 MagicBytes[3]=MessageBuffer[53];
\r
393 CurrentMagicError=GE_NONE;
\r
396 /* This function provides Nokia authentication protocol.
\r
398 This code is written specially for gnokii project by Odinokov Serge.
\r
399 If you have some special requests for Serge just write him to
\r
400 apskaita@post.omnitel.net or serge@takas.lt
\r
402 Reimplemented in C by Pavel JanÃk ml.
\r
404 Nokia authentication protocol is used in the communication between Nokia
\r
405 mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software,
\r
406 commercially sold by Nokia Corp.
\r
408 The authentication scheme is based on the token send by the phone to the
\r
409 software. The software does it's magic (see the function
\r
410 FB61_GetNokiaAuth()) and returns the result back to the phone. If the
\r
411 result is correct the phone responds with the message "Accessory
\r
412 connected!" displayed on the LCD. Otherwise it will display "Accessory not
\r
413 supported" and some functions will not be available for use.
\r
415 The specification of the protocol is not publicly available, no comment. */
\r
416 void N6110_GetNokiaAuth(unsigned char *Imei, unsigned char *MagicBytes, unsigned char *MagicResponse)
\r
421 /* This is our temporary working area. */
\r
423 unsigned char Temp[16];
\r
425 /* Here we put FAC (Final Assembly Code) and serial number into our area. */
\r
431 Temp[4] = Imei[10];
\r
432 Temp[5] = Imei[11];
\r
433 Temp[6] = Imei[12];
\r
434 Temp[7] = Imei[13];
\r
436 /* And now the TAC (Type Approval Code). */
\r
440 Temp[10] = Imei[4];
\r
441 Temp[11] = Imei[5];
\r
443 /* And now we pack magic bytes from the phone. */
\r
445 Temp[12] = MagicBytes[0];
\r
446 Temp[13] = MagicBytes[1];
\r
447 Temp[14] = MagicBytes[2];
\r
448 Temp[15] = MagicBytes[3];
\r
450 for (i=0; i<=11; i++)
\r
451 if (Temp[i + 1]& 1)
\r
454 switch (Temp[15] & 0x03) {
\r
458 j = Temp[13] & 0x07;
\r
460 for (i=0; i<=3; i++)
\r
461 Temp[i+j] ^= Temp[i+12];
\r
466 j = Temp[14] & 0x07;
\r
468 for (i=0; i<=3; i++)
\r
469 Temp[i + j] |= Temp[i + 12];
\r
472 for (i=0; i<=15; i++)
\r
475 for (i=0; i<=15; i++) {
\r
477 switch (Temp[15 - i] & 0x06) {
\r
499 MagicResponse[i] = j;
\r
504 GSM_Error N6110_Authentication()
\r
506 unsigned char connect1[] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x02};
\r
507 unsigned char connect2[] = {N6110_FRAME_HEADER, 0x20, 0x02};
\r
508 unsigned char connect3[] = {N6110_FRAME_HEADER, 0x0d, 0x01, 0x00, 0x02};
\r
509 unsigned char connect4[] = {N6110_FRAME_HEADER, 0x10};
\r
511 unsigned char magic_connect[] = {N6110_FRAME_HEADER,
\r
514 /* The real magic goes here ... These bytes are filled in with the
\r
515 function N6110_GetNokiaAuth(). */
\r
517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
\r
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
\r
520 /* NOKIA&GNOKII Accessory */
\r
522 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x26, 0x4e, 0x4f, 0x4b, 0x49, 0x41, 0x20,
\r
523 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x79,
\r
525 0x00, 0x00, 0x00, 0x00};
\r
528 fprintf(stdout,_("Making authentication!\n"));
\r
531 usleep(100); Protocol->SendMessage(7, 0x02, connect1);
\r
532 usleep(100); Protocol->SendMessage(5, 0x02, connect2);
\r
533 usleep(100); Protocol->SendMessage(7, 0x02, connect3);
\r
535 CurrentMagicError = GE_BUSY;
\r
537 usleep(100); Protocol->SendMessage(4, 0x64, connect4);
\r
538 if (NULL_WaitUntil(50,&CurrentMagicError)!=GE_NONE) return GE_TIMEOUT;
\r
540 N6110_GetNokiaAuth(Current_IMEI, MagicBytes, magic_connect+4);
\r
542 Protocol->SendMessage(45, 0x64, magic_connect);
\r
545 fprintf(stdout,_("End of authentication!\n"));
\r
551 /* Initialise variables and state machine. */
\r
552 GSM_Error N6110_Initialise(char *port_device, char *initlength,
\r
553 GSM_ConnectionType connection,
\r
554 void (*rlp_callback)(RLP_F96Frame *frame))
\r
556 unsigned char init_char = N6110_SYNC_BYTE;
\r
557 unsigned char end_init_char = N6110_IR_END_SYNC_BYTE;
\r
562 if (Protocol->Initialise(port_device,initlength,connection,rlp_callback)!=GE_NONE)
\r
564 return GE_NOTSUPPORTED;
\r
567 switch (CurrentConnectionType) {
570 /* We don't think about authentication in Irda, because
571 AFAIK there are no phones working over sockets
572 and having authentication. In MBUS it doesn't work */
575 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
\r
577 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
\r
579 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
\r
581 CurrentLinkOK = true;
\r \r
587 InitLength = atoi(initlength);
\r
589 if ((strcmp(initlength, "default") == 0) || (InitLength == 0)) {
\r
590 InitLength = 250; /* This is the usual value, lower may work. */
\r
593 if (CurrentConnectionType==GCT_Infrared ||
594 CurrentConnectionType==GCT_Tekram) {
\r
596 fprintf(stdout,_("Setting infrared for FBUS communication...\n"));
\r
598 device_changespeed(9600);
\r
602 fprintf(stdout,_("Writing init chars...."));
\r
605 /* Initialise link with phone or what have you */
\r
606 /* Send init string to phone, this is a bunch of 0x55 characters. Timing is
\r
608 for (count = 0; count < InitLength; count ++) {
\r
609 if (CurrentConnectionType!=GCT_Infrared &&
610 CurrentConnectionType!=GCT_Tekram)
\r usleep(100);
\r
611 Protocol->WritePhone(1,&init_char);
\r
614 if (CurrentConnectionType==GCT_Infrared ||
615 CurrentConnectionType==GCT_Tekram)
\r {
616 Protocol->WritePhone(1,&end_init_char);
\r
621 fprintf(stdout,_("Done\n"));
\r
624 if (CurrentConnectionType==GCT_Infrared ||
625 CurrentConnectionType==GCT_Tekram)
\r {
626 device_changespeed(115200);
\r
629 N6110_SendStatusRequest();
\r
633 if (N6110_SendIDFrame()!=GE_NONE) return GE_TIMEOUT;
\r
635 /* N51xx/61xx have something called authentication.
\r
636 After making it phone display "Accessory connected"
\r
637 and probably give access to some function (I'm not too sure about it !)
\r
638 Anyway, I make it now for N51xx/61xx */
\r
639 if (GetModelFeature (FN_AUTHENTICATION)!=0) {
\r
640 if (N6110_Authentication()!=GE_NONE) return GE_TIMEOUT;
\r
641 } else {
\r /* No authentication */
642 if (N6110_SendIMEIFrame()!=GE_NONE) return GE_TIMEOUT;
\r
644 if (N6110_SendHWFrame()!=GE_NONE) return GE_TIMEOUT;
\r
650 fprintf(stdout,_("Unknown connection type in n6110.c!\n"));
\r
658 /* This function translates GMT_MemoryType to N6110_MEMORY_xx */
\r
659 int N6110_GetMemoryType(GSM_MemoryType memory_type)
\r
664 switch (memory_type) {
\r
666 case GMT_MT: result = N6110_MEMORY_MT; break;
\r
667 case GMT_ME: result = N6110_MEMORY_ME; break;
\r
668 case GMT_SM: result = N6110_MEMORY_SM; break;
\r
669 case GMT_FD: result = N6110_MEMORY_FD; break;
\r
670 case GMT_ON: result = N6110_MEMORY_ON; break;
\r
671 case GMT_EN: result = N6110_MEMORY_EN; break;
\r
672 case GMT_DC: result = N6110_MEMORY_DC; break;
\r
673 case GMT_RC: result = N6110_MEMORY_RC; break;
\r
674 case GMT_MC: result = N6110_MEMORY_MC; break;
\r
675 default : result = N6110_MEMORY_XX;
\r
682 void N6110_ReplyCallDivert(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
684 switch (MessageBuffer[3]) {
689 fprintf(stdout, _("Message: Call divert status received\n"));
\r
690 fprintf(stdout, _(" Divert type: "));
691 switch (MessageBuffer[6]) {
692 case 0x43: fprintf(stdout, _("when busy"));break;
693 case 0x3d: fprintf(stdout, _("when not answered"));break;
694 case 0x3e: fprintf(stdout, _("when phone off or no coverage"));break;
695 case 0x15: fprintf(stdout, _("all types of diverts"));break; //?
696 case 0x02: fprintf(stdout, _("all types of diverts"));break; //?
697 default: fprintf(stdout, _("unknown %i"),MessageBuffer[6]);break;
699 fprintf(stdout, _("\n Calls type : "));
700 if (MessageBuffer[6]==0x02)
701 fprintf(stdout, _("voice, fax & data")); //?
703 switch (MessageBuffer[8]) {
704 case 0x0b: fprintf(stdout, _("voice"));break;
705 case 0x0d: fprintf(stdout, _("fax"));break;
706 case 0x19: fprintf(stdout, _("data"));break;
707 default: fprintf(stdout, _("unknown %i"),MessageBuffer[8]);break;
710 fprintf(stdout, _("\n"));
711 if (MessageBuffer[10]==0x01) {
712 fprintf(stdout, _(" Status : active\n"));
713 fprintf(stdout, _(" Timeout : %i seconds\n"),MessageBuffer[45]);
714 fprintf(stdout, _(" Number : %s\n"),GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
716 fprintf(stdout, _(" Status : deactivated\n"));
720 if (CurrentCallDivert!=NULL) {
721 switch (MessageBuffer[6]) {
722 case 0x43: CurrentCallDivert->DType=GSM_CDV_Busy;break;
723 case 0x3d: CurrentCallDivert->DType=GSM_CDV_NoAnswer;break;
724 case 0x3e: CurrentCallDivert->DType=GSM_CDV_OutOfReach;break;
725 case 0x15: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
726 case 0x02: CurrentCallDivert->DType=GSM_CDV_AllTypes;break; //?
729 if (MessageBuffer[6]==0x02) //?
730 CurrentCallDivert->CType=GSM_CDV_AllCalls;
732 switch (MessageBuffer[8]) {
733 case 0x0b: CurrentCallDivert->CType=GSM_CDV_VoiceCalls;break;
734 case 0x0d: CurrentCallDivert->CType=GSM_CDV_FaxCalls; break;
735 case 0x19: CurrentCallDivert->CType=GSM_CDV_DataCalls; break;
739 if (MessageBuffer[10]==0x01) {
740 CurrentCallDivert->Enabled=true;
741 CurrentCallDivert->Timeout=MessageBuffer[45];
742 strcpy(CurrentCallDivert->Number,GSM_UnpackSemiOctetNumber(MessageBuffer+12,true));
744 CurrentCallDivert->Enabled=false;
746 CurrentCallDivertError=GE_NONE;
\r
752 fprintf(stdout, _("Message: Call divert status receiving error ?\n"));
754 CurrentCallDivertError=GE_UNKNOWN;
\r
759 GSM_Error N6110_CallDivert(GSM_CallDivert *cd)
761 char req[55] = { N6110_FRAME_HEADER, 0x01,
762 0x00, /* operation */
764 0x00, /* divert type */
765 0x00, /* call type */
771 switch (cd->Operation) {
772 case GSM_CDV_Register:
\r
773 case GSM_CDV_Enable:
\r
776 req[29]= GSM_PackSemiOctetNumber(cd->Number, req + 9, false);
777 req[52]= cd->Timeout;
780 case GSM_CDV_Erasure:
781 case GSM_CDV_Disable:
788 return GE_NOTIMPLEMENTED;
792 case GSM_CDV_AllTypes : req[6] = 0x15; break;
793 case GSM_CDV_Busy : req[6] = 0x43; break;
794 case GSM_CDV_NoAnswer : req[6] = 0x3d; break;
795 case GSM_CDV_OutOfReach: req[6] = 0x3e; break;
796 default: return GE_NOTIMPLEMENTED;
799 if ((cd->DType == GSM_CDV_AllTypes) &&
800 (cd->CType == GSM_CDV_AllCalls))
804 case GSM_CDV_AllCalls : break;
805 case GSM_CDV_VoiceCalls: req[7] = 0x0b; break;
806 case GSM_CDV_FaxCalls : req[7] = 0x0d; break;
807 case GSM_CDV_DataCalls : req[7] = 0x19; break;
808 default: return GE_NOTIMPLEMENTED;
811 CurrentCallDivert = cd;
813 error=NULL_SendMessageSequence
814 (100, &CurrentCallDivertError, length, 0x06, req);
816 CurrentCallDivert = NULL;
821 GSM_Error N6110_Tests()
\r
823 unsigned char buffer[3]={0x00,0x01,0xcf};
\r
824 unsigned char buffer3[8]={0x00,0x01,0xce,0x1d,0xfe,0x23,0x00,0x00};
\r
828 error=N6110_EnableExtendedCommands(0x01);
\r
829 if (error!=GE_NONE) return error;
831 //make almost all tests
\r
832 Protocol->SendMessage(8, 0x40, buffer3);
\r
834 while (GSM->Initialise(PortDevice, "50", CurrentConnectionType, CurrentRLP_RXCallback)!=GE_NONE) {};
\r
838 return NULL_SendMessageSequence
\r
839 (200, &CurrentNetworkInfoError, 3, 0x40, buffer);
\r
842 void N6110_DisplayTestsInfo(u8 *MessageBuffer) {
\r
846 CurrentNetworkInfoError=GE_NONE;
\r
848 for (i=0;i<MessageBuffer[3];i++) {
\r
850 case 0: fprintf(stdout,_("Unknown(%i) "),i);break;
\r
851 case 1: fprintf(stdout,_("MCU ROM checksum "));break;
\r
852 case 2: fprintf(stdout,_("MCU RAM interface "));break;
\r
853 case 3: fprintf(stdout,_("MCU RAM component "));break;
\r
854 case 4: fprintf(stdout,_("MCU EEPROM interface "));break;
\r
855 case 5: fprintf(stdout,_("MCU EEPROM component "));break;
\r
856 case 6: fprintf(stdout,_("Real Time Clock battery "));break;
\r
857 case 7: fprintf(stdout,_("CCONT interface "));break;
\r
858 case 8: fprintf(stdout,_("AD converter "));break;
\r
859 case 9: fprintf(stdout,_("SW Reset "));break;
\r
860 case 10:fprintf(stdout,_("Power Off "));break;
\r
861 case 11:fprintf(stdout,_("Security Data "));break;
\r
862 case 12:fprintf(stdout,_("EEPROM Tune checksum "));break;
\r
863 case 13:fprintf(stdout,_("PPM checksum "));break;
\r
864 case 14:fprintf(stdout,_("MCU download DSP "));break;
\r
865 case 15:fprintf(stdout,_("DSP alive "));break;
\r
866 case 16:fprintf(stdout,_("COBBA serial "));break;
\r
867 case 17:fprintf(stdout,_("COBBA paraller "));break;
\r
868 case 18:fprintf(stdout,_("EEPROM security checksum"));break;
\r
869 case 19:fprintf(stdout,_("PPM validity "));break;
\r
870 case 20:fprintf(stdout,_("Warranty state "));break;
\r
871 case 21:fprintf(stdout,_("Simlock check "));break;
\r
872 case 22:fprintf(stdout,_("IMEI check? "));break;//from PC-Locals.is OK?
\r
873 default:fprintf(stdout,_("Unknown(%i) "),i);break;
\r
875 switch (MessageBuffer[4+i]) {
\r
876 case 0: fprintf(stdout,_(" : done, result OK"));break;
\r
877 case 0xff:fprintf(stdout,_(" : not done, result unknown"));break;
\r
878 case 254: fprintf(stdout,_(" : done, result NOT OK"));break;
\r
879 default: fprintf(stdout,_(" : result unknown(%i)"),MessageBuffer[4+i]);break;
\r
881 fprintf(stdout,_("\n"));
\r
885 void N6110_ReplySimlockInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
892 fprintf(stdout, _("Message: Simlock info received\n"));
895 for (i=0; i < 12; i++)
\r
898 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] >> 4)));
\r
901 if (j==5 || j==15) fprintf(stdout, _("\n"));
\r
904 fprintf(stdout,_("%c"), ('0' + (MessageBuffer[9+i] & 0x0f)));
\r
908 if (j==20 || j==24) fprintf(stdout, _("\n"));
\r
911 if ((MessageBuffer[6] & 1) == 1) fprintf(stdout,_("lock 1 closed\n"));
912 if ((MessageBuffer[6] & 2) == 2) fprintf(stdout,_("lock 2 closed\n"));
913 if ((MessageBuffer[6] & 4) == 4) fprintf(stdout,_("lock 3 closed\n"));
914 if ((MessageBuffer[6] & 8) == 8) fprintf(stdout,_("lock 4 closed\n"));
916 /* I'm not sure here at all */
917 if ((MessageBuffer[5] & 1) == 1) fprintf(stdout,_("lock 1 - user\n"));
918 if ((MessageBuffer[5] & 2) == 2) fprintf(stdout,_("lock 2 - user\n"));
919 if ((MessageBuffer[5] & 4) == 4) fprintf(stdout,_("lock 3 - user\n"));
920 if ((MessageBuffer[5] & 8) == 8) fprintf(stdout,_("lock 4 - user\n"));
922 fprintf(stdout,_("counter for lock1: %i\n"),MessageBuffer[21]);
923 fprintf(stdout,_("counter for lock2: %i\n"),MessageBuffer[22]);
924 fprintf(stdout,_("counter for lock3: %i\n"),MessageBuffer[23]);
925 fprintf(stdout,_("counter for lock4: %i\n"),MessageBuffer[24]);
930 for (i=0; i < 12; i++)
933 uni[j]='0' + (MessageBuffer[9+i] >> 4);
938 uni[j]='0' + (MessageBuffer[9+i] & 0x0f);
944 strncpy(CurrentSimLock->simlocks[0].data,uni,5);
945 CurrentSimLock->simlocks[0].data[5]=0;
946 strncpy(CurrentSimLock->simlocks[3].data,uni+5,10);
947 CurrentSimLock->simlocks[3].data[10]=0;
948 strncpy(CurrentSimLock->simlocks[1].data,uni+16,4);
949 CurrentSimLock->simlocks[1].data[4]=0;
950 strncpy(CurrentSimLock->simlocks[2].data,uni+20,4);
951 CurrentSimLock->simlocks[2].data[4]=0;
953 CurrentSimLock->simlocks[0].enabled=((MessageBuffer[6] & 1) == 1);
954 CurrentSimLock->simlocks[1].enabled=((MessageBuffer[6] & 2) == 2);
955 CurrentSimLock->simlocks[2].enabled=((MessageBuffer[6] & 4) == 4);
956 CurrentSimLock->simlocks[3].enabled=((MessageBuffer[6] & 8) == 8);
958 CurrentSimLock->simlocks[0].factory=((MessageBuffer[5] & 1) != 1);
959 CurrentSimLock->simlocks[1].factory=((MessageBuffer[5] & 2) != 2);
960 CurrentSimLock->simlocks[2].factory=((MessageBuffer[5] & 4) != 4);
961 CurrentSimLock->simlocks[3].factory=((MessageBuffer[5] & 8) != 8);
963 CurrentSimLock->simlocks[0].counter=MessageBuffer[21];
964 CurrentSimLock->simlocks[1].counter=MessageBuffer[22];
965 CurrentSimLock->simlocks[2].counter=MessageBuffer[23];
966 CurrentSimLock->simlocks[3].counter=MessageBuffer[24];
968 CurrentSimlockInfoError=GE_NONE;
971 GSM_Error N6110_SimlockInfo(GSM_AllSimlocks *siml)
\r
974 unsigned char req[] = {0x00,0x01,0x8a,0x00};
\r\r
975 error=N6110_EnableExtendedCommands(0x01);
\r
976 if (error!=GE_NONE) return error;
980 return NULL_SendMessageSequence (50, &CurrentSimlockInfoError, 4, 0x40, req);
\r
983 void N6110_ReplyResetPhoneSettings(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
986 fprintf(stdout, _("Message: Resetting phone settings\n"));
989 CurrentResetPhoneSettingsError=GE_NONE;
992 GSM_Error N6110_ResetPhoneSettings()
\r
995 unsigned char req[] = {0x00,0x01,0x65,0x08,0x00};
\r \r
996 error=N6110_EnableExtendedCommands(0x01);
\r
997 if (error!=GE_NONE) return error;
999 return NULL_SendMessageSequence
\r
1000 (50, &CurrentResetPhoneSettingsError, 5, 0x40, req);
\r
1002 GSM_Error N6110_GetManufacturer(char *manufacturer)
1004 strcpy (manufacturer, "Nokia");
1008 GSM_Error N6110_GetVoiceMailbox ( GSM_PhonebookEntry *entry)
\r
1010 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
\r
1014 CurrentPhonebookEntry = entry;
\r
1016 req[4] = N6110_MEMORY_VOICE;
\r
1017 req[5] = 0x00; /* Location - isn't important, but... */
\r
1019 error=NULL_SendMessageSequence
\r
1020 (20, &CurrentPhonebookError, 7, 0x03, req);
\r
1022 CurrentPhonebookEntry = NULL;
\r
1027 void N6110_ReplyGetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1031 GSM_Bitmap NullBitmap;
\r
1033 DecodeNetworkCode(MessageBuffer+5, NullBitmap.netcode);
\r
1038 fprintf(stdout, _("Message: Info about downloaded operator name received: %s network (for gnokii \"%s\", for phone \""),
\r
1039 NullBitmap.netcode,
\r
1040 GSM_GetNetworkName(NullBitmap.netcode));
\r
1044 while (MessageBuffer[count]!=0) {
\r
1046 fprintf(stdout,_("%c"),MessageBuffer[count]);
\r
1051 strcpy(CurrentGetOperatorNameNetwork->Code, NullBitmap.netcode);
\r
1052 strncpy(CurrentGetOperatorNameNetwork->Name, MessageBuffer+i,count-i+1);
\r
1055 fprintf(stdout,_("\")\n"));
\r
1058 CurrentGetOperatorNameError=GE_NONE;
\r
1061 GSM_Error N6110_GetOperatorName (GSM_Network *operator)
\r
1063 unsigned char req[] = { 0x00,0x01,0x8c,0x00};
\r
1067 error=N6110_EnableExtendedCommands(0x01);
\r
1068 if (error!=GE_NONE) return error;
\r
1070 CurrentGetOperatorNameNetwork = operator;
\r
1072 error=NULL_SendMessageSequence
\r
1073 (20, &CurrentGetOperatorNameError, 4, 0x40, req);
\r
1075 CurrentGetOperatorNameNetwork = NULL;
\r
1080 void N6110_ReplySetOperatorName(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1083 fprintf(stdout, _("Message: Downloaded operator name changed\n"));
\r
1086 CurrentSetOperatorNameError=GE_NONE;
\r
1089 GSM_Error N6110_SetOperatorName (GSM_Network *operator)
\r
1091 unsigned char req[256] = { 0x00,0x01,0x8b,0x00,
\r
1092 0x00,0x00, /* MCC */
\r
1097 error=N6110_EnableExtendedCommands(0x01);
\r
1098 if (error!=GE_NONE) return error;
\r
1100 EncodeNetworkCode(req+4,operator->Code);
\r
1102 strncpy(req+7,operator->Name,200);
\r
1104 return NULL_SendMessageSequence
\r
1105 (20, &CurrentSetOperatorNameError, 8+strlen(operator->Name), 0x40, req);
\r
1108 void N6110_ReplyGetMemoryStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1110 switch (MessageBuffer[3]) {
\r
1115 fprintf(stdout, _("Message: Memory status received:\n"));
\r
1117 fprintf(stdout, _(" Memory Type: %s\n"), N6110_MemoryType_String[MessageBuffer[4]]);
\r
1118 fprintf(stdout, _(" Used: %d\n"), MessageBuffer[6]);
\r
1119 fprintf(stdout, _(" Free: %d\n"), MessageBuffer[5]);
\r
1120 #endif /* DEBUG */
\r
1122 CurrentMemoryStatus->Used = MessageBuffer[6];
\r
1123 CurrentMemoryStatus->Free = MessageBuffer[5];
\r
1124 CurrentMemoryStatusError = GE_NONE;
\r
1131 switch (MessageBuffer[4]) {
\r
1133 fprintf(stdout, _("Message: Memory status error, phone is probably powered off.\n"));break;
\r
1135 fprintf(stdout, _("Message: Memory status error, memory type not supported by phone model.\n"));break;
\r
1137 fprintf(stdout, _("Message: Memory status error, waiting for security code.\n"));break;
\r
1139 fprintf(stdout, _("Message: Unknown Memory status error, subtype (MessageBuffer[4]) = %02x\n"),MessageBuffer[4]);break;
\r
1143 switch (MessageBuffer[4]) {
\r
1144 case 0x6f:CurrentMemoryStatusError = GE_TIMEOUT;break;
\r
1145 case 0x7d:CurrentMemoryStatusError = GE_INTERNALERROR;break;
\r
1146 case 0x8d:CurrentMemoryStatusError = GE_INVALIDSECURITYCODE;break;
\r
1155 /* This function is used to get storage status from the phone. It currently
\r
1156 supports two different memory areas - internal and SIM. */
\r
1157 GSM_Error N6110_GetMemoryStatus(GSM_MemoryStatus *Status)
\r
1159 unsigned char req[] = { N6110_FRAME_HEADER,
\r
1160 0x07, /* MemoryStatus request */
\r
1161 0x00 /* MemoryType */
\r
1166 CurrentMemoryStatus = Status;
\r
1168 req[4] = N6110_GetMemoryType(Status->MemoryType);
\r
1170 error=NULL_SendMessageSequence
\r
1171 (20, &CurrentMemoryStatusError, 5, 0x03, req);
\r
1173 CurrentMemoryStatus = NULL;
\r
1178 void N6110_ReplyGetNetworkInfo(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1180 GSM_NetworkInfo NullNetworkInfo;
\r
1182 /* Make sure we are expecting NetworkInfo frame */
\r
1183 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY) {
\r
1185 fprintf(stdout, _("Message: Network informations:\n"));
\r
1189 fprintf(stdout, _("Message: Network informations not requested, but received:\n"));
\r
1193 sprintf(NullNetworkInfo.NetworkCode, "%x%x%x %x%x", MessageBuffer[14] & 0x0f, MessageBuffer[14] >>4, MessageBuffer[15] & 0x0f, MessageBuffer[16] & 0x0f, MessageBuffer[16] >>4);
\r
1195 sprintf(NullNetworkInfo.CellID, "%02x%02x", MessageBuffer[10], MessageBuffer[11]);
\r
1197 sprintf(NullNetworkInfo.LAC, "%02x%02x", MessageBuffer[12], MessageBuffer[13]);
\r
1200 fprintf(stdout, _(" CellID: %s\n"), NullNetworkInfo.CellID);
\r
1201 fprintf(stdout, _(" LAC: %s\n"), NullNetworkInfo.LAC);
\r
1202 fprintf(stdout, _(" Network code: %s\n"), NullNetworkInfo.NetworkCode);
\r
1203 fprintf(stdout, _(" Network name: %s (%s)\n"),
\r
1204 GSM_GetNetworkName(NullNetworkInfo.NetworkCode),
\r
1205 GSM_GetCountryName(NullNetworkInfo.NetworkCode));
\r
1206 fprintf(stdout, _(" Status: "));
\r
1208 switch (MessageBuffer[8]) {
\r
1209 case 0x01: fprintf(stdout, _("home network selected")); break;
\r
1210 case 0x02: fprintf(stdout, _("roaming network")); break;
\r
1211 case 0x03: fprintf(stdout, _("requesting network")); break;
\r
1212 case 0x04: fprintf(stdout, _("not registered in the network")); break;
\r
1213 default: fprintf(stdout, _("unknown"));
\r
1216 fprintf(stdout, "\n");
\r
1218 fprintf(stdout, _(" Network selection: %s\n"), MessageBuffer[9]==1?_("manual"):_("automatic"));
\r
1219 #endif /* DEBUG */
\r
1221 /* Make sure we are expecting NetworkInfo frame */
\r
1222 if (CurrentNetworkInfo && CurrentNetworkInfoError == GE_BUSY)
\r
1223 *CurrentNetworkInfo=NullNetworkInfo;
\r
1225 CurrentNetworkInfoError = GE_NONE;
\r
1228 GSM_Error N6110_GetNetworkInfo(GSM_NetworkInfo *NetworkInfo)
\r
1230 unsigned char req[] = { N6110_FRAME_HEADER,
\r
1236 CurrentNetworkInfo = NetworkInfo;
\r
1238 error=NULL_SendMessageSequence
\r
1239 (20, &CurrentNetworkInfoError, 4, 0x0a, req);
\r
1241 CurrentNetworkInfo = NULL;
\r
1246 void N6110_ReplyGetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1251 fprintf(stdout, _("Message: Product Profile Settings received -"));
\r
1252 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),MessageBuffer[3+i]);
\r
1253 fprintf(stdout, _("\n"));
\r
1256 for (i=0;i<4;i++) CurrentPPS[i]=MessageBuffer[3+i];
\r
1258 CurrentProductProfileSettingsError=GE_NONE;
\r
1261 GSM_Error N6110_GetProductProfileSetting (GSM_PPS *PPS)
\r
1263 unsigned char req[] = { 0x00, 0x01,0x6a };
\r
1269 error=N6110_EnableExtendedCommands(0x01);
\r
1270 if (error!=GE_NONE) return error;
\r
1272 error=NULL_SendMessageSequence
\r
1273 (20, &CurrentProductProfileSettingsError, 3, 0x40, req);
\r
1274 if (error!=GE_NONE) return error;
\r
1276 switch (PPS->Name) {
\r
1277 case PPS_ALS : PPS->bool_value=(CurrentPPS[1]&32); break;
\r
1278 case PPS_GamesMenu: PPS->bool_value=(CurrentPPS[3]&64); break;
\r
1279 case PPS_HRData : PPS->bool_value=(CurrentPPS[0]&64); break;
\r
1280 case PPS_14400Data: PPS->bool_value=(CurrentPPS[0]&128);break;
\r
1281 case PPS_EFR : PPS->int_value =(CurrentPPS[0]&1) +(CurrentPPS[0]&2); break;
\r
1282 case PPS_FR : PPS->int_value =(CurrentPPS[0]&16)/16+(CurrentPPS[0]&32)/16;break;
\r
1283 case PPS_HR : PPS->int_value =(CurrentPPS[0]&4)/4 +(CurrentPPS[0]&8)/4; break;
\r
1284 case PPS_VibraMenu: PPS->bool_value=(CurrentPPS[4]&64); break;
\r
1285 case PPS_LCDContrast:
\r
1288 for (i=0;i<5;i++) {
\r
1289 if (CurrentPPS[3]&j) PPS->int_value=PPS->int_value+j;
\r
1292 PPS->int_value=PPS->int_value*100/32;
\r
1300 void N6110_ReplySetProductProfileSetting(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1305 fprintf(stdout, _("Message: Product Profile Settings set to"));
\r
1306 for (i=0;i<4;i++) fprintf(stdout, _(" %02x"),CurrentPPS[i]);
\r
1307 fprintf(stdout, _("\n"));
\r
1310 CurrentProductProfileSettingsError=GE_NONE;
\r
1313 GSM_Error N6110_SetProductProfileSetting (GSM_PPS *PPS)
\r
1315 unsigned char req[] = { 0x00, 0x01,0x6b,
\r
1316 0x00, 0x00, 0x00, 0x00 }; /* bytes with Product Profile Setings */
\r
1317 unsigned char settings[32];
\r
1325 error=N6110_EnableExtendedCommands(0x01);
\r
1326 if (error!=GE_NONE) return error;
\r
1328 OldPPS.Name=PPS_ALS;
\r
1329 error=N6110_GetProductProfileSetting(&OldPPS);
\r
1330 if (error!=GE_NONE) return error;
\r
1333 for (i=0;i<32;i++) {
\r
1334 if (CurrentPPS[z]&j)
\r
1345 fprintf(stdout,_("Current settings: "));
\r
1346 for (i=0;i<32;i++) {
\r
1347 fprintf(stdout,_("%c"),settings[i]);
\r
1349 fprintf(stdout,_("\n"));
\r
1352 switch (PPS->Name) {
\r
1353 case PPS_ALS :settings[10]=PPS->bool_value?'1':'0';break;
\r
1354 case PPS_HRData :settings[ 5]=PPS->bool_value?'1':'0';break;
\r
1355 case PPS_14400Data:settings[ 6]=PPS->bool_value?'1':'0';break;
\r
1360 for (i=0;i<32;i++) {
\r
1361 if (settings[i]=='1') req[z+3]=req[z+3]+j;
\r
1369 fprintf(stdout,_("Current settings: "));
\r
1370 for (i=0;i<4;i++) {
\r
1371 fprintf(stdout,_("%i "),req[i+3]);
\r
1373 fprintf(stdout,_("\n"));
\r
1376 for (i=0;i<4;i++) {
\r
1377 CurrentPPS[i]=req[i+3];
\r
1380 return NULL_SendMessageSequence
\r
1381 (20, &CurrentProductProfileSettingsError, 7, 0x40, req);
\r
1384 void N6110_ReplyPressKey(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1386 if (MessageBuffer[4]==CurrentPressKeyEvent) CurrentPressKeyError=GE_NONE;
\r
1387 else CurrentPressKeyError=GE_UNKNOWN; /* MessageBuffer[4] = 0x05 */
\r
1389 fprintf(stdout, _("Message: Result of key "));
\r
1390 switch (MessageBuffer[4])
\r
1392 case PRESSPHONEKEY: fprintf(stdout, _("press OK\n"));break;
\r
1393 case RELEASEPHONEKEY: fprintf(stdout, _("release OK\n"));break;
\r
1394 default: fprintf(stdout, _("press or release - error\n"));break;
\r
1396 #endif /* DEBUG */
\r
1399 GSM_Error N6110_PressKey(int key, int event)
\r
1401 unsigned char req[] = {N6110_FRAME_HEADER, 0x42, 0x01, 0x00, 0x01};
\r
1403 req[4]=event; /* if we press or release key */
\r
1406 CurrentPressKeyEvent=event;
\r
1408 return NULL_SendMessageSequence
\r
1409 (10, &CurrentPressKeyError, 7, 0x0c, req);
\r
1412 void N6110_ReplyDisplayOutput(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1414 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
\r
1421 switch(MessageBuffer[3]) {
\r
1423 /* Phone sends displayed texts */
\r
1425 NewX=MessageBuffer[6];
\r
1426 NewY=MessageBuffer[5];
\r
1428 DecodeUnicode (uni, MessageBuffer+8, MessageBuffer[7]);
\r
1431 fprintf(stdout, _("New displayed text (%i %i): \"%s\"\n"),NewX,NewY,uni);
\r
1432 #endif /* DEBUG */
\r
1434 while (N6110_GetModel(model) != GE_NONE)
\r
1437 /* With these rules it works almost excellent with my N5110 */
\r
1438 /* I don't have general rule :-(, that's why you must experiment */
\r
1439 /* with your phone. Nokia could make it better. MW */
\r
1440 /* It's almost OK for N5110*/
\r
1441 /* FIX ME: it will be the same for N5130 and 3210 too*/
\r
1442 if (!strcmp(model,"NSE-1"))
\r
1444 /* OldX==1000 means - it's first time */
\r
1448 for (i=0;i<5+1;i++) {
\r
1449 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
\r
1454 if ((OldX==0 && OldY==31 && NewX==29 && NewY==46) ||
\r
1455 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
\r
1456 /* Clean the line with current text */
\r
1457 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
\r
1459 /* Inserts text into table */
\r
1460 for (i=0; i<MessageBuffer[7];i++) {
\r
1461 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
\r
1466 if ((OldX==0 && OldY==21 && NewX==0 && NewY==10) ||
\r
1467 (OldX==0 && OldY==10 && NewX==35 && NewY==46)) {
\r
1469 if ((OldX!=0 && NewX==0 && NewY!=6) ||
\r
1470 (OldX==0 && NewX!=0 && OldY!=13 && OldY!=22) ||
\r
1471 (OldX==0 && NewX==0 && NewY<OldY && (NewY!=13 || OldY!=26)) ||
\r
1472 (OldY==5 && NewY!=5) ||
\r
1473 (OldX==0 && OldY==13 && NewX==23 && NewY==46)) {
\r
1475 /* Writes "old" screen */
\r
1476 for (i=0;i<5+1;i++) {
\r
1477 for (j=0;j<27+1;j++) {fprintf(stdout,_("%c"),PhoneScreen[i][j]);}
\r
1478 fprintf(stdout,_("\n"));
\r
1482 for (i=0;i<5+1;i++) {
\r
1483 for (j=0;j<27+1;j++) {PhoneScreen[i][j]=' ';}
\r
1488 /* Clean the line with current text */
\r
1489 for (j=0;j<27+1;j++) {PhoneScreen[NewY/(47/5)][j]=' ';}
\r
1491 /* Inserts text into table */
\r
1492 for (i=0; i<MessageBuffer[7];i++) {
\r
1493 PhoneScreen[NewY/(47/5)][NewX/(84/27)+i]=uni[i];
\r
1500 fprintf(stdout, _("%s\n"),uni);
\r
1508 if (MessageBuffer[4]==1)
\r
1512 fprintf(stdout, _("Display output successfully disabled/enabled.\n"));
\r
1513 #endif /* DEBUG */
\r
1515 CurrentDisplayOutputError=GE_NONE;
\r
1522 GSM_Error SetDisplayOutput(unsigned char state)
\r
1524 unsigned char req[] = { N6110_FRAME_HEADER,
\r
1529 return NULL_SendMessageSequence
\r
1530 (30, &CurrentDisplayOutputError, 5, 0x0d, req);
\r
1533 GSM_Error N6110_EnableDisplayOutput()
\r
1535 return SetDisplayOutput(0x01);
\r
1538 GSM_Error N6110_DisableDisplayOutput()
\r
1540 return SetDisplayOutput(0x02);
\r
1543 /* If it is interesting for somebody: we can use 0x40 msg for it
\r
1544 and it will work for all phones. See n6110.txt for details */
\r
1545 GSM_Error N6110_AnswerCall(char s)
\r
1547 unsigned char req0[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,0x07, 0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
\r
1548 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80};
\r
1549 unsigned char req[] = { N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
\r
1554 fprintf(stdout,_("Answering call %d\n\r"),s);
\r
1557 Protocol->SendMessage(sizeof(req0), 0x01, req0);
\r
1560 return NULL_SendMessageSequence
\r
1561 (20, &CurrentMagicError, sizeof(req) , 0x01, req);
\r
1564 void N6110_ReplyGetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1566 switch (MessageBuffer[3]) {
\r
1568 /* Profile feature */
\r
1571 switch(GetModelFeature (FN_PROFILES)) {
\r
1573 switch (MessageBuffer[6]) {
\r
1574 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8]; break;
\r
1575 case 0x01: CurrentProfile->CallAlert = MessageBuffer[8]; break;
\r
1576 case 0x02: CurrentProfile->Ringtone = MessageBuffer[8]; break;
\r
1577 case 0x03: CurrentProfile->Volume = MessageBuffer[8]; break;
\r
1578 case 0x04: CurrentProfile->MessageTone = MessageBuffer[8]; break;
\r
1579 case 0x05: CurrentProfile->Vibration = MessageBuffer[8]; break;
\r
1580 case 0x06: CurrentProfile->WarningTone = MessageBuffer[8]; break;
\r
1581 case 0x07: CurrentProfile->ScreenSaver = MessageBuffer[8]; break;
\r
1584 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
\r
1590 switch (MessageBuffer[6]) {
\r
1591 case 0x00: CurrentProfile->KeypadTone = MessageBuffer[8];break;
\r
1592 case 0x01: CurrentProfile->Lights = MessageBuffer[8];break;
\r
1593 case 0x02: CurrentProfile->CallAlert = MessageBuffer[8];break;
\r
1594 case 0x03: CurrentProfile->Ringtone = MessageBuffer[8];break;
\r
1595 case 0x04: CurrentProfile->Volume = MessageBuffer[8];break;
\r
1596 case 0x05: CurrentProfile->MessageTone = MessageBuffer[8];break;
\r
1597 case 0x06: CurrentProfile->Vibration = MessageBuffer[8];break;
\r
1598 case 0x07: CurrentProfile->WarningTone = MessageBuffer[8];break;
\r
1599 case 0x08: CurrentProfile->CallerGroups = MessageBuffer[8];break;
\r
1600 case 0x09: CurrentProfile->AutomaticAnswer = MessageBuffer[8];break;
\r
1603 fprintf(stdout,_("feature %i = value %i\n\n"),MessageBuffer[6],MessageBuffer[8]);
\r
1610 CurrentProfileError = GE_NONE;
\r
1613 /* Incoming profile name */
\r
1616 if (MessageBuffer[9] == 0x00) {
\r
1617 CurrentProfile->DefaultName=MessageBuffer[8];
\r
1619 CurrentProfile->DefaultName=-1;
\r
1621 /* Here name is in Unicode */
\r
1622 if (GetModelFeature (FN_PROFILES)==F_PROF33) {
\r
1623 DecodeUnicode (CurrentProfile->Name, MessageBuffer+10, MessageBuffer[9]/2);
\r
1626 sprintf(CurrentProfile->Name, MessageBuffer + 10, MessageBuffer[9]);
\r
1627 CurrentProfile->Name[MessageBuffer[9]] = '\0';
\r
1631 CurrentProfileError = GE_NONE;
\r
1637 /* Needs SIM card with PIN in phone */
\r
1638 GSM_Error N6110_GetProfile(GSM_Profile *Profile)
\r
1642 unsigned char name_req[] = { N6110_FRAME_HEADER, 0x1a, 0x00};
\r
1643 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x13, 0x01, 0x00, 0x00};
\r
1647 CurrentProfile = Profile;
\r
1649 /* When after sending all frames feature==253, it means, that it is not
\r
1651 CurrentProfile->KeypadTone=253;
\r
1652 CurrentProfile->Lights=253;
\r
1653 CurrentProfile->CallAlert=253;
\r
1654 CurrentProfile->Ringtone=253;
\r
1655 CurrentProfile->Volume=253;
\r
1656 CurrentProfile->MessageTone=253;
\r
1657 CurrentProfile->WarningTone=253;
\r
1658 CurrentProfile->Vibration=253;
\r
1659 CurrentProfile->CallerGroups=253;
\r
1660 CurrentProfile->ScreenSaver=253;
\r
1661 CurrentProfile->AutomaticAnswer=253;
\r
1663 name_req[4] = Profile->Number;
\r
1665 error=NULL_SendMessageSequence
\r
1666 (20, &CurrentProfileError, 5, 0x05, name_req);
\r
1667 if (error!=GE_NONE) return error;
\r
1669 for (i = 0x00; i <= 0x09; i++) {
\r
1671 feat_req[5] = Profile->Number;
\r
1675 error=NULL_SendMessageSequence
\r
1676 (20, &CurrentProfileError, 7, 0x05, feat_req);
\r
1677 if (error!=GE_NONE) return error;
\r
1680 if (Profile->DefaultName > -1)
\r
1682 switch(GetModelFeature (FN_PROFILES)) {
\r
1684 switch (Profile->DefaultName) {
\r
1685 case 0x00: sprintf(Profile->Name, "General");break;
\r
1686 case 0x01: sprintf(Profile->Name, "Silent");break;
\r
1687 case 0x02: sprintf(Profile->Name, "Descreet");break;
\r
1688 case 0x03: sprintf(Profile->Name, "Loud");break;
\r
1689 case 0x04: sprintf(Profile->Name, "My style");break;
\r
1690 case 0x05: Profile->Name[0]=0;break;
\r
1691 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
\r
1695 switch (Profile->DefaultName) {
\r
1696 case 0x00: sprintf(Profile->Name, "Personal");break;
\r
1697 case 0x01: sprintf(Profile->Name, "Car");break;
\r
1698 case 0x02: sprintf(Profile->Name, "Headset");break;
\r
1699 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
\r
1703 switch (Profile->DefaultName) {
\r
1704 case 0x00: sprintf(Profile->Name, "General");break;
\r
1705 case 0x01: sprintf(Profile->Name, "Silent");break;
\r
1706 case 0x02: sprintf(Profile->Name, "Meeting");break;
\r
1707 case 0x03: sprintf(Profile->Name, "Outdoor");break;
\r
1708 case 0x04: sprintf(Profile->Name, "Pager");break;
\r
1709 case 0x05: sprintf(Profile->Name, "Car");break;
\r
1710 case 0x06: sprintf(Profile->Name, "Headset");break;
\r
1711 default : sprintf(Profile->Name, "Unknown (%i)", Profile->DefaultName);break;
\r
1721 void N6110_ReplySetProfile(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1723 switch (MessageBuffer[3]) {
\r
1725 /* Profile feature change result */
\r
1728 fprintf(stdout, _("Message: Profile feature change result.\n"));
\r
1729 #endif /* DEBUG */
\r
1730 CurrentProfileError = GE_NONE;
\r
1733 /* Profile name set result */
\r
1736 fprintf(stdout, _("Message: Profile name change result.\n"));
\r
1737 #endif /* DEBUG */
\r
1738 CurrentProfileError = GE_NONE;
\r
1744 GSM_Error N6110_SetProfileFeature(u8 profile, u8 feature, u8 value)
\r
1746 unsigned char feat_req[] = { N6110_FRAME_HEADER, 0x10, 0x01,
\r
1747 0x00, 0x00, 0x00};
\r
1749 feat_req[5]=profile;
\r
1750 feat_req[6]=feature;
\r
1751 feat_req[7]=value;
\r
1753 return NULL_SendMessageSequence
\r
1754 (20, &CurrentProfileError, 8, 0x05, feat_req);
\r
1757 GSM_Error N6110_SetProfile(GSM_Profile *Profile)
\r
1761 unsigned char name_req[40] = { N6110_FRAME_HEADER, 0x1c, 0x01, 0x03,
\r
1762 0x00, 0x00, 0x00};
\r
1766 name_req[7] = Profile->Number;
\r
1767 name_req[8] = strlen(Profile->Name);
\r
1768 name_req[6] = name_req[8] + 2;
\r
1770 for (i = 0; i < name_req[8]; i++)
\r
1771 name_req[9 + i] = Profile->Name[i];
\r
1773 error=NULL_SendMessageSequence
\r
1774 (20, &CurrentProfileError, name_req[8] + 9, 0x05, name_req);
\r
1775 if (error!=GE_NONE) return error;
\r
1777 for (i = 0x00; i <= 0x09; i++) {
\r
1780 case 0x00: value = Profile->KeypadTone; break;
\r
1781 case 0x01: value = Profile->Lights; break;
\r
1782 case 0x02: value = Profile->CallAlert; break;
\r
1783 case 0x03: value = Profile->Ringtone; break;
\r
1784 case 0x04: value = Profile->Volume; break;
\r
1785 case 0x05: value = Profile->MessageTone; break;
\r
1786 case 0x06: value = Profile->Vibration; break;
\r
1787 case 0x07: value = Profile->WarningTone; break;
\r
1788 case 0x08: value = Profile->CallerGroups; break;
\r
1789 case 0x09: value = Profile->AutomaticAnswer; break;
\r
1790 default : value = 0; break;
1793 error=N6110_SetProfileFeature(Profile->Number,i,value);
\r
1794 if (error!=GE_NONE) return error;
\r
1800 bool N6110_SendRLPFrame(RLP_F96Frame *frame, bool out_dtx)
\r
1802 u8 req[60] = { 0x00, 0xd9 };
\r
1804 /* Discontinuos transmission (DTX). See section 5.6 of GSM 04.22 version
\r
1810 memcpy(req+2, (u8 *) frame, 32);
\r
1812 return (Protocol->SendFrame(32, 0xf0, req));
\r
1815 void N6110_ReplyGetCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1823 switch (MessageBuffer[4]) {
\r
1827 CurrentCalendarNote->Type=MessageBuffer[8];
\r
1829 DecodeDateTime(MessageBuffer+9, &CurrentCalendarNote->Time);
\r
1831 DecodeDateTime(MessageBuffer+16, &CurrentCalendarNote->Alarm);
\r
1833 CurrentCalendarNote->Text[0]=0;
\r
1835 if (GetModelFeature (FN_CALENDAR)==F_CAL33) {
\r
1837 if (CurrentCalendarNote->Type == GCN_REMINDER) i=1; //first char is subset
\r
1838 switch (MessageBuffer[24]) {
\r
1841 fprintf(stdout,_("Subset 3 in reminder note !\n"));
\r
1843 while (i!=MessageBuffer[23]) {
\r
1845 if (i!=MessageBuffer[23]-1) {
\r
1846 if (MessageBuffer[24+i]>=0xc2) {
\r
1847 DecodeWithUTF8Alphabet(MessageBuffer[24+i], MessageBuffer[24+i+1], &mychar1);
\r
1848 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
\r
1849 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=mychar1;
\r
1855 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
\r
1856 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=MessageBuffer[24+i];
\r
1863 fprintf(stdout,_("Subset 2 in reminder note !\n"));
\r
1865 while (i!=MessageBuffer[23]) {
\r
1866 wc = MessageBuffer[24+i] | (0x00 << 8);
\r
1867 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)+1]=0;
\r
1868 CurrentCalendarNote->Text[strlen(CurrentCalendarNote->Text)]=
\r
1869 DecodeWithUnicodeAlphabet(wc);
\r
1875 fprintf(stdout,_("Subset 1 in reminder note !\n"));
\r
1877 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
\r
1878 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
\r
1882 fprintf(stdout,_("Unknown subset in reminder note !\n"));
\r
1884 memcpy(CurrentCalendarNote->Text,MessageBuffer+24+i,MessageBuffer[23]-i);
\r
1885 CurrentCalendarNote->Text[MessageBuffer[23]-i]=0;
\r
1889 memcpy(CurrentCalendarNote->Text,MessageBuffer+24,MessageBuffer[23]);
\r
1890 CurrentCalendarNote->Text[MessageBuffer[23]]=0;
\r
1893 if (CurrentCalendarNote->Type == GCN_CALL) {
\r
1894 memcpy(CurrentCalendarNote->Phone,MessageBuffer+24+MessageBuffer[23]+1,MessageBuffer[24+MessageBuffer[23]]);
\r
1895 CurrentCalendarNote->Phone[MessageBuffer[24+MessageBuffer[23]]]=0;
\r
1898 CurrentCalendarNote->Recurrance=0;
\r
1900 CurrentCalendarNote->AlarmType=0;
\r
1903 fprintf(stdout, _("Message: Calendar note received.\n"));
\r
1905 fprintf(stdout, _(" Date: %d-%02d-%02d\n"), CurrentCalendarNote->Time.Year,
\r
1906 CurrentCalendarNote->Time.Month,
\r
1907 CurrentCalendarNote->Time.Day);
\r
1909 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentCalendarNote->Time.Hour,
\r
1910 CurrentCalendarNote->Time.Minute,
\r
1911 CurrentCalendarNote->Time.Second);
\r
1913 /* Some messages do not have alarm set up */
\r
1914 if (CurrentCalendarNote->Alarm.Year != 0) {
\r
1915 fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"), CurrentCalendarNote->Alarm.Year,
\r
1916 CurrentCalendarNote->Alarm.Month,
\r
1917 CurrentCalendarNote->Alarm.Day);
\r
1919 fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"), CurrentCalendarNote->Alarm.Hour,
\r
1920 CurrentCalendarNote->Alarm.Minute,
\r
1921 CurrentCalendarNote->Alarm.Second);
\r
1924 fprintf(stdout, _(" Type: %d\n"), CurrentCalendarNote->Type);
\r
1925 fprintf(stdout, _(" Text: %s\n"), CurrentCalendarNote->Text);
\r
1927 if (CurrentCalendarNote->Type == GCN_CALL)
\r
1928 fprintf(stdout, _(" Phone: %s\n"), CurrentCalendarNote->Phone);
\r
1929 #endif /* DEBUG */
\r
1931 CurrentCalendarNoteError=GE_NONE;
\r
1937 fprintf(stdout, _("Message: Calendar note not available\n"));
\r
1938 #endif /* DEBUG */
\r
1940 CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;
\r
1946 fprintf(stdout, _("Message: Calendar note error\n"));
\r
1947 #endif /* DEBUG */
\r
1949 CurrentCalendarNoteError=GE_INTERNALERROR;
\r
1955 GSM_Error N6110_GetCalendarNote(GSM_CalendarNote *CalendarNote)
\r
1958 unsigned char req[] = { N6110_FRAME_HEADER,
\r
1963 req[4]=CalendarNote->Location;
\r
1965 CurrentCalendarNote = CalendarNote;
\r
1967 error=NULL_SendMessageSequence
\r
1968 (20, &CurrentCalendarNoteError, 5, 0x13, req);
\r
1970 CurrentCalendarNote = NULL;
\r
1975 void N6110_ReplyWriteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
1978 switch(MessageBuffer[4]) {
\r
1979 /* This message is also sent when the user enters the new entry on keypad */
\r
1981 fprintf(stdout, _("Message: Calendar note write succesfull!\n"));break;
\r
1983 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
\r
1985 fprintf(stdout, _("Message: Calendar note write failed!\n"));break;
\r
1987 fprintf(stdout, _("Unknown message of type 0x13 and subtype 0x65\n"));break;
\r
1991 switch(MessageBuffer[4]) {
\r
1992 case 0x01: CurrentCalendarNoteError=GE_NONE; break;
\r
1993 case 0x73: CurrentCalendarNoteError=GE_INTERNALERROR; break;
\r
1994 case 0x7d: CurrentCalendarNoteError=GE_INTERNALERROR; break;
\r
1995 default : AppendLogText("Unknown msg\n",false); break;
\r
1999 GSM_Error N6110_WriteCalendarNote(GSM_CalendarNote *CalendarNote)
\r
2002 unsigned char req[200] = { N6110_FRAME_HEADER,
\r
2004 0x00, /* Length of the rest of the frame. */
\r
2005 0x00, /* The type of calendar note */
\r
2006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
\r
2007 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
\r
2012 unsigned char call;
\r
2013 unsigned char meeting;
\r
2014 unsigned char birthday;
\r
2015 unsigned char reminder;
\r
2016 } calendar_model_length;
\r
2018 /* Length of entries */
\r
2019 calendar_model_length calendar_lengths[] =
\r
2021 /*model,CallTo,Meeting,Birthday,Reminder*/
\r
2022 {"NHM-5",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
\r
2023 {"NHM-6",0x24,0x24,0x24,0x24}, //Reminder from phone, other quesses
\r
2024 {"NSE-3",0x1e,0x14,0x14,0x1e}, //from NCDS3 [HKEY_LOCAL_MACHINE\Software\Nokia\Data Suite\3.0\Calendar]
\r
2025 {"NSM-1",0x1e,0x18,0x18,0x24}, //from NCDS3
\r
2026 {"NSK-3",0x1e,0x14,0x14,0x1e}, //from NCDS3
\r
2027 {"NSB-3",0x20,0x14,0x14,0x1e}, //from NCDS3
\r
2028 {"", 0, 0, 0, 0 } //end of table
\r
2031 int i, j, current;
\r
2039 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
\r
2042 req[7]=CalendarNote->Type;
\r
2044 EncodeDateTime(req+8, &CalendarNote->Time);
\r
2045 req[14] = CalendarNote->Time.Timezone;
\r
2047 if (CalendarNote->Alarm.Year) {
\r
2048 EncodeDateTime(req+15, &CalendarNote->Alarm);
\r
2049 req[21] = CalendarNote->Alarm.Timezone;
\r
2052 req[22]=strlen(CalendarNote->Text);
\r
2056 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
\r
2057 req[22]++; // one additional char
\r
2058 req[current++]=0x01; //we use now subset 1
\r
2061 for (i=0; i<strlen(CalendarNote->Text); i++) {
\r
2063 mychar=CalendarNote->Text[i];
\r
2064 if (GetModelFeature (FN_CALENDAR)==F_CAL33 && CalendarNote->Type==GCN_REMINDER) {
\r
2065 if (EncodeWithUTF8Alphabet(mychar,&mychar1,&mychar2)) {
2066 req[current++]=mychar1;
\r
2067 req[current++]=mychar2;
\r
2068 req[23]=0x03; //use subset 3
\r
2069 req[22]++; // one additional char
\r
2074 /* Enables/disables blinking */
\r
2075 if (mychar=='~') req[current++]=0x01;
\r
2076 else req[current++]=mychar;
\r
2080 req[current++]=strlen(CalendarNote->Phone);
\r
2082 for (i=0; i<strlen(CalendarNote->Phone); i++)
\r
2083 req[current++]=CalendarNote->Phone[i];
\r
2085 while (N6110_GetModel(model) != GE_NONE)
\r
2088 /* Checking maximal length */
\r
2090 while (strcmp(calendar_lengths[i].model,"")) {
\r
2091 if (!strcmp(calendar_lengths[i].model,model)) {
\r
2092 switch (CalendarNote->Type) {
\r
2093 case GCN_REMINDER:if (req[22]>calendar_lengths[i].reminder) return GE_TOOLONG;break;
\r
2094 case GCN_MEETING :if (req[22]>calendar_lengths[i].meeting) return GE_TOOLONG;break;
\r
2095 case GCN_BIRTHDAY:if (req[22]>calendar_lengths[i].birthday) return GE_TOOLONG;break;
\r
2096 case GCN_CALL :if (strlen(CalendarNote->Phone)>calendar_lengths[i].call) return GE_TOOLONG;break;
\r
2103 CurrentCalendarNote = CalendarNote;
\r
2105 error=NULL_SendMessageSequence
\r
2106 (20, &CurrentCalendarNoteError, current, 0x13, req);
\r
2108 CurrentCalendarNote = NULL;
\r
2113 void N6110_ReplyDeleteCalendarNote(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2116 switch (MessageBuffer[4]) {
\r
2117 /* This message is also sent when the user deletes an old entry on
\r
2118 keypad or moves an old entry somewhere (there is also `write'
\r
2120 case 0x01:fprintf(stdout, _("Message: Calendar note deleted\n"));break;
\r
2121 case 0x93:fprintf(stdout, _("Message: Calendar note can't be deleted\n"));break;
\r
2122 default :fprintf(stdout, _("Message: Calendar note deleting error\n"));break;
\r
2126 switch (MessageBuffer[4]) {
\r
2127 case 0x01:CurrentCalendarNoteError=GE_NONE;break;
\r
2128 case 0x93:CurrentCalendarNoteError=GE_INVALIDCALNOTELOCATION;break;
\r
2129 default :CurrentCalendarNoteError=GE_INTERNALERROR;break;
\r
2133 GSM_Error N6110_DeleteCalendarNote(GSM_CalendarNote *CalendarNote)
\r
2136 unsigned char req[] = { N6110_FRAME_HEADER,
\r
2140 req[4]=CalendarNote->Location;
\r
2142 return NULL_SendMessageSequence (20, &CurrentCalendarNoteError, 5, 0x13, req);
\r
2145 void N6110_ReplyRFBatteryLevel(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2148 fprintf(stdout, _("Message: Phone status received:\n"));
\r
2149 fprintf(stdout, _(" Mode: "));
\r
2151 switch (MessageBuffer[4]) {
\r
2155 fprintf(stdout, _("registered within the network\n"));
\r
2158 /* I was really amazing why is there a hole in the type of 0x02, now I
\r
2160 case 0x02: fprintf(stdout, _("call in progress\n")); break; /* ringing or already answered call */
\r
2161 case 0x03: fprintf(stdout, _("waiting for security code\n")); break;
\r
2162 case 0x04: fprintf(stdout, _("powered off\n")); break;
\r
2163 default : fprintf(stdout, _("unknown\n"));
\r
2167 fprintf(stdout, _(" Power source: "));
\r
2169 switch (MessageBuffer[7]) {
\r
2171 case 0x01: fprintf(stdout, _("AC/DC\n")); break;
\r
2172 case 0x02: fprintf(stdout, _("battery\n")); break;
\r
2173 default : fprintf(stdout, _("unknown\n"));
\r
2177 fprintf(stdout, _(" Battery Level: %d\n"), MessageBuffer[8]);
\r
2178 fprintf(stdout, _(" Signal strength: %d\n"), MessageBuffer[5]);
\r
2179 #endif /* DEBUG */
\r
2181 CurrentRFLevel=MessageBuffer[5];
\r
2182 CurrentBatteryLevel=MessageBuffer[8];
\r
2183 CurrentPowerSource=MessageBuffer[7];
\r
2187 GSM_Error N6110_GetRFLevel(GSM_RFUnits *units, float *level)
\r
2190 /* FIXME - these values are from 3810 code, may be incorrect. Map from
\r
2191 values returned in status packet to the the values returned by the AT+CSQ
\r
2193 float csq_map[5] = {0, 8, 16, 24, 31};
\r
2198 char screen[NM_MAX_SCREEN_WIDTH];
\r
2200 CurrentRFLevel=-1;
\r
2202 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
\r
2204 if (N6110_NetMonitor(1, screen)!=GE_NONE)
\r
2205 return GE_INTERNALERROR;
\r
2209 if (screen[4]!='-') {
\r
2210 if (screen[5]=='9' && screen[6]>'4') rf_level=1;
\r
2211 if (screen[5]=='9' && screen[6]<'5') rf_level=2;
\r
2212 if (screen[5]=='8' && screen[6]>'4') rf_level=3;
\r
2213 } else rf_level=0;
\r
2215 /* Arbitrary units. */
\r
2216 if (*units == GRF_Arbitrary) {
\r
2217 *level = rf_level;
\r
2222 N6110_SendStatusRequest();
\r
2224 /* Wait for timeout or other error. */
\r
2225 while (timeout != 0 && CurrentRFLevel == -1 ) {
\r
2227 if (--timeout == 0)
\r
2228 return (GE_TIMEOUT);
\r
2233 /* Make copy in case it changes. */
\r
2234 rf_level = CurrentRFLevel;
\r
2236 if (rf_level == -1)
\r
2237 return (GE_NOLINK);
\r
2239 /* Now convert between the different units we support. */
\r
2241 /* Arbitrary units. */
\r
2242 if (*units == GRF_Arbitrary) {
\r
2243 *level = rf_level;
\r
2248 if (*units == GRF_CSQ) {
\r
2251 *level = csq_map[rf_level];
\r
2253 *level = 99; /* Unknown/undefined */
\r
2259 /* Unit type is one we don't handle so return error */
\r
2260 return (GE_INTERNALERROR);
\r
2264 GSM_Error N6110_GetBatteryLevel(GSM_BatteryUnits *units, float *level)
\r
2266 \r int timeout=10;
\r
2269 char screen[NM_MAX_SCREEN_WIDTH];
\r
2271 CurrentBatteryLevel=-1;
\r
2273 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
\r
2275 if (N6110_NetMonitor(23, screen)!=GE_NONE)
\r
2280 if (screen[29]=='7') batt_level=3;
\r
2281 if (screen[29]=='5') batt_level=2;
\r
2282 if (screen[29]=='2') batt_level=1;
\r
2284 /* Only units we handle at present are GBU_Arbitrary */
\r
2285 if (*units == GBU_Arbitrary) {
\r
2286 *level = batt_level;
\r
2290 return (GE_INTERNALERROR);
\r
2293 N6110_SendStatusRequest();
\r
2295 /* Wait for timeout or other error. */
\r
2296 while (timeout != 0 && CurrentBatteryLevel == -1 ) {
\r
2298 if (--timeout == 0)
\r
2299 return (GE_TIMEOUT);
\r
2304 /* Take copy in case it changes. */
\r
2305 batt_level = CurrentBatteryLevel;
\r
2307 if (batt_level != -1) {
\r
2309 /* Only units we handle at present are GBU_Arbitrary */
\r
2310 if (*units == GBU_Arbitrary) {
\r
2311 *level = batt_level;
\r
2315 return (GE_INTERNALERROR);
\r
2318 return (GE_NOLINK);
\r
2322 GSM_Error N6110_GetPowerSource(GSM_PowerSource *source)
\r
2327 char screen[NM_MAX_SCREEN_WIDTH];
\r
2329 CurrentPowerSource=-1;
\r
2331 if (GetModelFeature (FN_NOPOWERFRAME)==F_NOPOWER) {
\r
2333 if (N6110_NetMonitor(20, screen)!=GE_NONE)
\r
2336 CurrentPowerSource=GPS_ACDC;
\r
2338 if (screen[6]=='x') CurrentPowerSource=GPS_BATTERY;
\r
2340 *source=CurrentPowerSource;
\r
2344 N6110_SendStatusRequest();
\r
2346 /* Wait for timeout or other error. */
\r
2347 while (timeout != 0 && CurrentPowerSource == -1 ) {
\r
2349 if (--timeout == 0)
\r
2350 return (GE_TIMEOUT);
\r
2355 if (CurrentPowerSource != -1) {
\r
2356 *source=CurrentPowerSource;
\r
2360 return (GE_NOLINK);
\r
2364 void N6110_ReplyGetDisplayStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2368 for (i=0; i<MessageBuffer[4];i++)
\r
2369 if (MessageBuffer[2*i+6]==2)
\r
2370 CurrentDisplayStatus|=1<<(MessageBuffer[2*i+5]-1);
\r
2372 CurrentDisplayStatus&= (0xff - (1<<(MessageBuffer[2*i+5]-1)));
\r
2375 fprintf(stdout, _("Call in progress: %s\n"), CurrentDisplayStatus & (1<<DS_Call_In_Progress)?"on":"off");
\r
2376 fprintf(stdout, _("Unknown: %s\n"), CurrentDisplayStatus & (1<<DS_Unknown)?"on":"off");
\r
2377 fprintf(stdout, _("Unread SMS: %s\n"), CurrentDisplayStatus & (1<<DS_Unread_SMS)?"on":"off");
\r
2378 fprintf(stdout, _("Voice call: %s\n"), CurrentDisplayStatus & (1<<DS_Voice_Call)?"on":"off");
\r
2379 fprintf(stdout, _("Fax call active: %s\n"), CurrentDisplayStatus & (1<<DS_Fax_Call)?"on":"off");
\r
2380 fprintf(stdout, _("Data call active: %s\n"), CurrentDisplayStatus & (1<<DS_Data_Call)?"on":"off");
\r
2381 fprintf(stdout, _("Keyboard lock: %s\n"), CurrentDisplayStatus & (1<<DS_Keyboard_Lock)?"on":"off");
\r
2382 fprintf(stdout, _("SMS storage full: %s\n"), CurrentDisplayStatus & (1<<DS_SMS_Storage_Full)?"on":"off");
\r
2383 #endif /* DEBUG */
\r
2385 CurrentDisplayStatusError=GE_NONE;
\r
2388 GSM_Error N6110_GetDisplayStatus(int *Status) {
\r
2390 unsigned char req[4]={ N6110_FRAME_HEADER, 0x51 };
\r
2394 error=NULL_SendMessageSequence
\r
2395 (10, &CurrentDisplayStatusError, 4, 0x0d, req);
\r
2396 if (error!=GE_NONE) return error;
\r
2398 *Status=CurrentDisplayStatus;
\r
2403 GSM_Error N6110_DialVoice(char *Number) {
\r
2404 /* This commented sequence doesn't work on N3210/3310/6210/7110 */
\r
2405 // unsigned char req[64]={N6110_FRAME_HEADER, 0x01};
\r
2406 // unsigned char req_end[]={0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};
\r
2408 // req[4]=strlen(Number);
\r
2409 // for(i=0; i < strlen(Number) ; i++)
\r
2410 // req[5+i]=Number[i];
\r
2411 // memcpy(req+5+strlen(Number), req_end, 10);
\r
2412 // return NULL_SendMessageSequence
\r
2413 // (20, &CurrentDialVoiceError, 13+strlen(Number), 0x01, req);
\r
2415 unsigned char req[64]={0x00,0x01,0x7c,
\r
2416 0x01}; //call command
\r
2422 error=N6110_EnableExtendedCommands(0x01);
\r
2423 if (error!=GE_NONE) return error;
\r
2425 for(i=0; i < strlen(Number) ; i++) req[4+i]=Number[i];
\r
2429 return NULL_SendMessageSequence
\r
2430 (20, &CurrentDialVoiceError, 4+strlen(Number)+1, 0x40, req);
\r
2433 /* Dial a data call - type specifies request to use:
\r
2434 type 0 should normally be used
\r
2435 type 1 should be used when calling a digital line - corresponds to ats35=0
\r
2436 Maybe one day we'll know what they mean!
\r
2438 GSM_Error N6110_DialData(char *Number, char type, void (* callpassup)(char c))
2440 unsigned char req[100] = { N6110_FRAME_HEADER, 0x01 };
2441 unsigned char *req_end;
2442 unsigned char req_end0[] = { 0x01, /* make a data call = type 0x01 */
2443 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2444 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00 };
2445 unsigned char req_end1[] = { 0x01,
2446 0x02,0x01,0x05,0x81,0x01,0x00,0x00,0x01,0x02,0x0a,
2447 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2448 0x88,0x90,0x21,0x48,0x40,0xbb };
2449 unsigned char req2[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2450 0x07,0xa2,0xc8,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2451 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80,0x01,0x60 };
2452 unsigned char req3[] = { N6110_FRAME_HEADER, 0x42,0x05,0x01,
2453 0x07,0xa2,0x88,0x81,0x21,0x15,0x63,0xa8,0x00,0x00,
2454 0x07,0xa3,0xb8,0x81,0x20,0x15,0x63,0x80 };
2455 unsigned char req4[] = { N6110_FRAME_HEADER, 0x42,0x05,0x81,
2456 0x07,0xa1,0x88,0x89,0x21,0x15,0x63,0xa0,0x00,0x06,
2457 0x88,0x90,0x21,0x48,0x40,0xbb,0x07,0xa3,0xb8,0x81,
2458 0x20,0x15,0x63,0x80 };
2463 CurrentCallPassup=callpassup;
2468 size = sizeof(req_end0);
2471 Protocol->SendMessage(sizeof(req3), 0x01, req3);
2473 Protocol->SendMessage(sizeof(req4), 0x01, req4);
2476 size = sizeof(req_end1);
2478 case -1: /* Just used to set the call passup */
2483 size = sizeof(req_end0);
2487 req[4] = strlen(Number);
2489 for(i = 0; i < strlen(Number) ; i++)
2490 req[5+i] = Number[i];
2492 memcpy(req + 5 + strlen(Number), req_end, size);
2494 Protocol->SendMessage(5 + size + strlen(Number), 0x01, req);
\r
2498 Protocol->SendMessage(26, 0x01, req2);
2505 GSM_Error N6110_GetIncomingCallNr(char *Number)
\r
2508 if (*CurrentIncomingCall != ' ') {
\r
2509 strcpy(Number, CurrentIncomingCall);
\r
2516 GSM_Error N6110_CancelCall(void)
2518 // This frame & method works only on 61xx/51xx
2519 // unsigned char req[] = { N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
2520 // req[4]=CurrentCallSequenceNumber;
2521 // Protocol->SendMessage(6, 0x01, req);
2526 unsigned char req[]={0x00,0x01,0x7c,0x03};
2529 error=N6110_EnableExtendedCommands(0x01);
2530 if (error!=GE_NONE) return error;
2532 return NULL_SendMessageSequence (20, &CurrentDialVoiceError, 4, 0x40, req);
2535 void N6110_ReplyEnterSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2537 switch(MessageBuffer[3]) {
\r
2541 fprintf(stdout, _("Message: Security code accepted.\n"));
\r
2542 #endif /* DEBUG */
\r
2543 CurrentSecurityCodeError = GE_NONE;
\r
2548 fprintf(stdout, _("Message: Security code is wrong. You're not my big owner :-)\n"));
\r
2549 #endif /* DEBUG */
\r
2550 CurrentSecurityCodeError = GE_INVALIDSECURITYCODE;
\r
2554 GSM_Error N6110_EnterSecurityCode(GSM_SecurityCode SecurityCode)
\r
2557 unsigned char req[15] = { N6110_FRAME_HEADER,
\r
2558 0x0a, /* Enter code request. */
\r
2559 0x00 /* Type of the entered code. */
\r
2563 req[4]=SecurityCode.Type;
\r
2565 for (i=0; i<strlen(SecurityCode.Code);i++)
\r
2566 req[5+i]=SecurityCode.Code[i];
\r
2568 req[5+strlen(SecurityCode.Code)]=0x00;
\r
2569 req[6+strlen(SecurityCode.Code)]=0x00;
\r
2571 return NULL_SendMessageSequence
\r
2572 (20, &CurrentSecurityCodeError, 7+strlen(SecurityCode.Code), 0x08, req);
\r
2575 void N6110_ReplyGetSecurityCodeStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2577 *CurrentSecurityCodeStatus = MessageBuffer[4];
\r
2580 fprintf(stdout, _("Message: Security Code status received: "));
\r
2582 switch(*CurrentSecurityCodeStatus) {
\r
2584 case GSCT_SecurityCode: fprintf(stdout, _("waiting for Security Code.\n")); break;
\r
2585 case GSCT_Pin : fprintf(stdout, _("waiting for PIN.\n")); break;
\r
2586 case GSCT_Pin2 : fprintf(stdout, _("waiting for PIN2.\n")); break;
\r
2587 case GSCT_Puk : fprintf(stdout, _("waiting for PUK.\n")); break;
\r
2588 case GSCT_Puk2 : fprintf(stdout, _("waiting for PUK2.\n")); break;
\r
2589 case GSCT_None : fprintf(stdout, _("nothing to enter.\n")); break;
\r
2590 default : fprintf(stdout, _("Unknown!\n"));
\r
2593 #endif /* DEBUG */
\r
2595 CurrentSecurityCodeError = GE_NONE;
\r
2598 GSM_Error N6110_GetSecurityCodeStatus(int *Status)
\r
2601 unsigned char req[4] = { N6110_FRAME_HEADER,
\r
2605 CurrentSecurityCodeStatus=Status;
\r
2607 return NULL_SendMessageSequence
\r
2608 (20, &CurrentSecurityCodeError, 4, 0x08, req);
\r
2611 void N6110_ReplyGetSecurityCode(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2616 fprintf(stdout, _("Message: Security code received: "));
\r
2617 switch (MessageBuffer[3]) {
\r
2618 case GSCT_SecurityCode: fprintf(stdout, _("Security code"));break;
\r
2619 case GSCT_Pin: fprintf(stdout, _("PIN"));break;
\r
2620 case GSCT_Pin2: fprintf(stdout, _("PIN2"));break;
\r
2621 case GSCT_Puk: fprintf(stdout, _("PUK"));break;
\r
2622 case GSCT_Puk2: fprintf(stdout, _("PUK2"));break;
\r
2623 default: fprintf(stdout, _("unknown !"));break;
\r
2625 if (MessageBuffer[4]==1) {
\r
2626 fprintf(stdout, _(" allowed, value \""));
\r
2627 if (MessageBuffer[3]==GSCT_SecurityCode) {
\r
2628 for (i=0;i<5;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
\r
2630 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
\r
2631 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
\r
2632 for (i=0;i<4;i++) {fprintf(stdout, _("%c"), MessageBuffer[5+i]);}
\r
2634 fprintf(stdout, _("\""));
\r
2636 fprintf(stdout, _(" not allowed"));
\r
2638 fprintf(stdout, _("\n"));
\r
2639 #endif /* DEBUG */
\r
2641 if (CurrentSecurityCode->Type==MessageBuffer[3] /* We wanted this code */
\r
2642 && MessageBuffer[4]==1) { /* It's allowed */
\r
2643 if (MessageBuffer[3]==GSCT_SecurityCode) {
\r
2644 for (i=0;i<5;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
\r
2645 CurrentSecurityCode->Code[5]=0;
\r
2647 if (MessageBuffer[3]==GSCT_Pin || MessageBuffer[3]==GSCT_Pin2 ||
\r
2648 MessageBuffer[3]==GSCT_Puk || MessageBuffer[3]==GSCT_Puk2) {
\r
2649 for (i=0;i<4;i++) {CurrentSecurityCode->Code[i]=MessageBuffer[5+i];}
\r
2650 CurrentSecurityCode->Code[4]=0;
\r
2652 CurrentSecurityCodeError=GE_NONE;
\r
2654 CurrentSecurityCodeError=GE_INVALIDSECURITYCODE;
\r
2657 GSM_Error N6110_GetSecurityCode(GSM_SecurityCode *SecurityCode)
\r
2660 unsigned char req[4] = { 0x00,
\r
2661 0x01,0x6e, /* Get code request. */
\r
2662 0x00 }; /* Type of the requested code. */
\r
2666 error=N6110_EnableExtendedCommands(0x01);
\r
2667 if (error!=GE_NONE) return error;
\r
2669 req[3]=SecurityCode->Type;
\r
2671 CurrentSecurityCode=SecurityCode;
\r
2673 return NULL_SendMessageSequence
\r
2674 (20, &CurrentSecurityCodeError, 4, 0x40, req);
\r
2677 void N6110_ReplyPlayTone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2680 fprintf(stdout, _("Message: answer for PlayTone frame\n"));
\r
2683 CurrentPlayToneError=GE_NONE;
\r
2686 GSM_Error N6110_PlayTone(int Herz, u8 Volume)
\r
2688 unsigned char req[6] = { 0x00,0x01,0x8f,
\r
2689 0x00, /* Volume */
\r
2690 0x00, /* HerzLo */
\r
2691 0x00 }; /* HerzHi */
\r
2695 /* PlayTone wasn't used earlier */
\r
2696 if (CurrentPlayToneError==GE_UNKNOWN) {
\r
2697 if (CurrentConnectionType!=GCT_MBUS)
\r
2698 CurrentDisableKeepAlive=true;
\r
2700 error=N6110_EnableExtendedCommands(0x01);
\r
2701 if (error!=GE_NONE) return error;
\r
2704 /* For Herz==255*255 we have silent */
\r
2705 if (Herz!=255*255) {
\r
2718 /* For Herz==255*255 we have silent and additionaly
\r
2719 we wait for phone answer - it's important for MBUS */
\r
2720 if (Herz==255*255) {
\r
2721 error=NULL_SendMessageSequence
\r
2722 (20, &CurrentPlayToneError, 6, 0x40, req);
\r
2724 CurrentPlayToneError=GE_UNKNOWN;
\r
2725 CurrentDisableKeepAlive=false;
\r
2727 if (error!=GE_NONE) return error;
\r
2729 Protocol->SendMessage(6,0x40,req);
\r
2732 error=NULL_SendMessageSequence
\r
2733 (20, &CurrentPlayToneError, 6, 0x40, req);
\r
2735 /* For Herz==255*255 we wait for phone answer - it's important for MBUS */
\r
2736 if (Herz==255*255) {
\r
2737 CurrentPlayToneError=GE_UNKNOWN;
\r
2738 CurrentDisableKeepAlive=false;
\r
2741 if (error!=GE_NONE) return error;
\r
2748 void N6110_ReplyGetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2750 if (MessageBuffer[4]==0x01) {
\r
2751 DecodeDateTime(MessageBuffer+8, CurrentDateTime);
\r
2754 fprintf(stdout, _("Message: Date and time\n"));
\r
2755 fprintf(stdout, _(" Time: %02d:%02d:%02d\n"), CurrentDateTime->Hour, CurrentDateTime->Minute, CurrentDateTime->Second);
\r
2756 fprintf(stdout, _(" Date: %4d/%02d/%02d\n"), CurrentDateTime->Year, CurrentDateTime->Month, CurrentDateTime->Day);
\r
2757 #endif /* DEBUG */
\r
2759 CurrentDateTime->IsSet=true;
\r
2763 fprintf(stdout, _("Message: Date and time not set in phone\n"));
\r
2766 CurrentDateTime->IsSet=false;
\r
2769 CurrentDateTimeError=GE_NONE;
\r
2772 GSM_Error N6110_GetDateTime(GSM_DateTime *date_time)
\r
2774 return N6110_PrivGetDateTime(date_time,0x11);
\r
2777 GSM_Error N6110_PrivGetDateTime(GSM_DateTime *date_time, int msgtype)
\r
2779 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
\r
2781 CurrentDateTime=date_time;
\r
2783 return NULL_SendMessageSequence
\r
2784 (50, &CurrentDateTimeError, 4, msgtype, req);
\r
2787 void N6110_ReplyGetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2790 fprintf(stdout, _("Message: Alarm\n"));
\r
2791 fprintf(stdout, _(" Alarm: %02d:%02d\n"), MessageBuffer[9], MessageBuffer[10]);
\r
2792 fprintf(stdout, _(" Alarm is %s\n"), (MessageBuffer[8]==2) ? _("on"):_("off"));
\r
2793 #endif /* DEBUG */
\r
2795 CurrentAlarm->Hour=MessageBuffer[9];
\r
2796 CurrentAlarm->Minute=MessageBuffer[10];
\r
2797 CurrentAlarm->Second=0;
\r
2799 CurrentAlarm->IsSet=(MessageBuffer[8]==2);
\r
2801 CurrentAlarmError=GE_NONE;
\r
2804 GSM_Error N6110_GetAlarm(int alarm_number, GSM_DateTime *date_time)
\r
2806 return N6110_PrivGetAlarm(alarm_number,date_time,0x11);
\r
2809 GSM_Error N6110_PrivGetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
\r
2811 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
\r
2813 CurrentAlarm=date_time;
\r
2815 return NULL_SendMessageSequence
\r
2816 (50, &CurrentAlarmError, 4, msgtype, req);
\r
2819 void N6110_ReplyGetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2821 switch (MessageBuffer[3]) {
\r
2825 CurrentMessageCenter->No=MessageBuffer[4];
\r
2826 CurrentMessageCenter->Format=MessageBuffer[6];
\r
2827 CurrentMessageCenter->Validity=MessageBuffer[8];
\r
2828 sprintf(CurrentMessageCenter->Name, "%s", MessageBuffer+33);
\r
2830 sprintf(CurrentMessageCenter->DefaultRecipient, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+9,false));
\r
2832 sprintf(CurrentMessageCenter->Number, "%s", GSM_UnpackSemiOctetNumber(MessageBuffer+21,false));
\r
2835 fprintf(stdout, _("Message: SMS Center received:\n"));
\r
2836 fprintf(stdout, _(" %d. SMS Center name is %s\n"), CurrentMessageCenter->No, CurrentMessageCenter->Name);
\r
2837 fprintf(stdout, _(" SMS Center number is %s\n"), CurrentMessageCenter->Number);
\r
2838 fprintf(stdout, _(" Default recipient number is %s\n"), CurrentMessageCenter->DefaultRecipient);
\r
2840 fprintf(stdout, _(" SMS Center message format is "));
\r
2842 switch (CurrentMessageCenter->Format) {
\r
2844 case GSMF_Text : fprintf(stdout, _("Text")); break;
\r
2845 case GSMF_Paging: fprintf(stdout, _("Paging")); break;
\r
2846 case GSMF_Fax : fprintf(stdout, _("Fax")); break;
\r
2847 case GSMF_Email : fprintf(stdout, _("Email")); break;
\r
2848 default : fprintf(stdout, _("Unknown"));
\r
2851 fprintf(stdout, "\n");
\r
2853 fprintf(stdout, _(" SMS Center message validity is "));
\r
2855 switch (CurrentMessageCenter->Validity) {
\r
2857 case GSMV_1_Hour : fprintf(stdout, _("1 hour")); break;
\r
2858 case GSMV_6_Hours : fprintf(stdout, _("6 hours")); break;
\r
2859 case GSMV_24_Hours: fprintf(stdout, _("24 hours")); break;
\r
2860 case GSMV_72_Hours: fprintf(stdout, _("72 hours")); break;
\r
2861 case GSMV_1_Week : fprintf(stdout, _("1 week")); break;
\r
2862 case GSMV_Max_Time: fprintf(stdout, _("Maximum time"));break;
\r
2863 default : fprintf(stdout, _("Unknown"));
\r
2866 fprintf(stdout, "\n");
\r
2868 #endif /* DEBUG */
\r
2870 CurrentMessageCenterError=GE_NONE;
\r
2876 /* Number of entries depends on SIM card */
\r
2879 fprintf(stdout, _("Message: SMS Center error received:\n"));
\r
2880 fprintf(stdout, _(" The request for SMS Center failed.\n"));
\r
2881 #endif /* DEBUG */
\r
2883 /* FIXME: appropriate error. */
\r
2884 CurrentMessageCenterError=GE_INTERNALERROR;
\r
2891 /* This function sends to the mobile phone a request for the SMS Center */
\r
2892 GSM_Error N6110_GetSMSCenter(GSM_MessageCenter *MessageCenter)
\r
2894 unsigned char req[] = { N6110_FRAME_HEADER, 0x33, 0x64,
\r
2895 0x00 /* SMS Center Number. */
\r
2898 req[5]=MessageCenter->No;
\r
2900 CurrentMessageCenter=MessageCenter;
\r
2902 return NULL_SendMessageSequence
\r
2903 (50, &CurrentMessageCenterError, 6, 0x02, req);
\r
2906 void N6110_ReplySetSMSCenter(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2909 fprintf(stdout, _("Message: SMS Center correctly set.\n"));
\r
2911 CurrentMessageCenterError=GE_NONE;
\r
2914 /* This function set the SMS Center profile on the phone. */
\r
2915 GSM_Error N6110_SetSMSCenter(GSM_MessageCenter *MessageCenter)
\r
2917 unsigned char req[64] = { N6110_FRAME_HEADER, 0x30, 0x64,
\r
2918 0x00, /* SMS Center Number. */
\r
2919 0x00, /* Unknown. */
\r
2920 0x00, /* SMS Message Format. */
\r
2921 0x00, /* Unknown. */
\r
2922 0x00, /* Validity. */
\r
2923 0,0,0,0,0,0,0,0,0,0,0,0, /* Default recipient number */
\r
2924 0,0,0,0,0,0,0,0,0,0,0,0 /* Message Center Number. */
\r
2925 /* Message Center Name. */
\r
2928 req[5]=MessageCenter->No;
\r
2929 req[7]=MessageCenter->Format;
\r
2930 req[9]=MessageCenter->Validity;
\r
2932 req[10]=GSM_PackSemiOctetNumber(MessageCenter->DefaultRecipient, req+11, false);
\r
2934 req[22]=GSM_PackSemiOctetNumber(MessageCenter->Number, req+23, false);
\r
2936 sprintf(req+34, "%s", MessageCenter->Name);
\r
2938 CurrentMessageCenter=MessageCenter;
\r
2940 return NULL_SendMessageSequence
\r
2941 (50, &CurrentMessageCenterError, 35+strlen(MessageCenter->Name), 0x02, req);
\r
2944 void N6110_ReplyGetSMSStatus(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
2946 switch (MessageBuffer[3]) {
\r
2951 fprintf(stdout, _("Message: SMS Status Received\n"));
\r
2952 fprintf(stdout, _(" The number of messages: %d\n"), MessageBuffer[10]);
\r
2953 fprintf(stdout, _(" Unread messages: %d\n"), MessageBuffer[11]);
\r
2954 #endif /* DEBUG */
\r
2956 CurrentSMSStatus->UnRead = MessageBuffer[11];
\r
2957 CurrentSMSStatus->Number = MessageBuffer[10];
\r
2959 CurrentSMSStatusError = GE_NONE;
\r
2965 fprintf(stdout, _("Message: SMS Status error, probably not authorized by PIN\n"));
\r
2966 #endif /* DEBUG */
\r
2968 CurrentSMSStatusError = GE_INTERNALERROR;
\r
2974 GSM_Error N6110_GetSMSStatus(GSM_SMSStatus *Status)
\r
2976 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
\r
2978 CurrentSMSStatus = Status;
\r
2980 return NULL_SendMessageSequence
\r
2981 (10, &CurrentSMSStatusError, 5, 0x14, req);
\r
2984 GSM_Error N6110_GetSMSFolders ( GSM_SMSFolders *folders)
2988 strcpy(folders->Folder[0].Name,"Inbox");
2989 strcpy(folders->Folder[1].Name,"Outbox");
2994 GSM_Error N6110_GetIMEI(char *imei)
\r
2996 if (strlen(Current_IMEI)>0) {
\r
2997 strncpy (imei, Current_IMEI, GSM_MAX_IMEI_LENGTH);
\r
3001 return (GE_TRYAGAIN);
\r
3004 GSM_Error N6110_GetRevision(char *revision)
\r
3007 if (strlen(Current_Revision)>0) {
\r
3008 strncpy (revision, Current_Revision, GSM_MAX_REVISION_LENGTH);
\r
3012 return (GE_TRYAGAIN);
\r
3015 GSM_Error N6110_GetModel(char *model)
\r
3017 if (strlen(Current_Model)>0) {
\r
3018 strncpy (model, Current_Model, GSM_MAX_MODEL_LENGTH);
\r
3022 return (GE_TRYAGAIN);
\r
3025 void N6110_ReplySetDateTime(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3027 switch (MessageBuffer[4]) {
\r
3031 fprintf(stdout, _("Message: Date and time set correctly\n"));
\r
3032 #endif /* DEBUG */
\r
3033 CurrentSetDateTimeError=GE_NONE;
\r
3038 fprintf(stdout, _("Message: Date and time setting error\n"));
\r
3039 #endif /* DEBUG */
\r
3040 CurrentSetDateTimeError=GE_INVALIDDATETIME;
\r
3045 /* Needs SIM card with PIN in phone */
\r
3046 GSM_Error N6110_SetDateTime(GSM_DateTime *date_time)
\r
3048 return N6110_PrivSetDateTime(date_time,0x11);
\r
3051 /* Needs SIM card with PIN in phone */
\r
3052 GSM_Error N6110_PrivSetDateTime(GSM_DateTime *date_time, int msgtype)
\r
3055 unsigned char req[] = { N6110_FRAME_HEADER,
\r
3056 0x60, /* set-time subtype */
\r
3057 0x01, 0x01, 0x07, /* unknown */
\r
3058 0x00, 0x00, /* Year (0x07cf = 1999) */
\r
3059 0x00, 0x00, /* Month Day */
\r
3060 0x00, 0x00, /* Hours Minutes */
\r
3061 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
\r
3064 EncodeDateTime(req+7, date_time);
\r
3066 return NULL_SendMessageSequence
\r
3067 (20, &CurrentSetDateTimeError, 14, msgtype, req);
\r
3070 void N6110_ReplySetAlarm(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3072 switch (MessageBuffer[4]) {
\r
3076 fprintf(stdout, _("Message: Alarm set correctly\n"));
\r
3077 #endif /* DEBUG */
\r
3078 CurrentSetAlarmError=GE_NONE;
\r
3083 fprintf(stdout, _("Message: Alarm setting error\n"));
\r
3084 #endif /* DEBUG */
\r
3085 CurrentSetAlarmError=GE_INVALIDDATETIME;
\r
3090 /* FIXME: we should also allow to set the alarm off :-) */
\r
3091 GSM_Error N6110_SetAlarm(int alarm_number, GSM_DateTime *date_time)
\r
3093 return N6110_PrivSetAlarm(alarm_number,date_time, 0x11);
\r
3096 /* FIXME: we should also allow to set the alarm off :-) */
\r
3097 GSM_Error N6110_PrivSetAlarm(int alarm_number, GSM_DateTime *date_time, int msgtype)
\r
3100 unsigned char req[] = { N6110_FRAME_HEADER,
\r
3101 0x6b, /* set-alarm subtype */
\r
3102 0x01, 0x20, 0x03, /* unknown */
\r
3103 0x02, /* should be alarm on/off, but it don't works */
\r
3104 0x00, 0x00, /* Hours Minutes */
\r
3105 0x00 /* Unknown, but not seconds - try 59 and wait 1 sec. */
\r
3108 req[8] = date_time->Hour;
\r
3109 req[9] = date_time->Minute;
\r
3111 return NULL_SendMessageSequence
\r
3112 (50, &CurrentSetAlarmError, 11, msgtype, req);
\r
3115 void N6110_ReplyGetMemoryLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3117 /* Hopefully is 64 larger as FB38_MAX* / N6110_MAX* */
\r
3120 int i, tmp, count;
\r
3122 switch (MessageBuffer[3]) {
\r
3126 CurrentPhonebookEntry->Empty = true;
\r
3128 count=MessageBuffer[5];
\r
3131 fprintf(stdout, _("Message: Phonebook entry received:\n"));
\r
3132 fprintf(stdout, _(" Name: "));
\r
3134 for (tmp=0; tmp <count; tmp++)
\r
3136 if (MessageBuffer[6+tmp]==1) fprintf(stdout, "%c", '~'); else //enables/disables blinking
\r
3137 if (MessageBuffer[6+tmp]==0) fprintf(stdout, "%c", '`'); else //hides rest ot contents
\r
3138 fprintf(stdout, "%c", MessageBuffer[6+tmp]);
\r
3141 fprintf(stdout, "\n");
\r
3142 #endif /* DEBUG */
\r
3144 while (N6110_GetModel(model) != GE_NONE)
\r
3147 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM ||
\r
3148 GetModelFeature (FN_PHONEBOOK)==F_PBK33INT) {//pbk with Unicode
\r
3149 DecodeUnicode (CurrentPhonebookEntry->Name, MessageBuffer+6, count/2);
\r
3150 CurrentPhonebookEntry->Name[count/2] = 0x00;
\r
3152 memcpy(CurrentPhonebookEntry->Name, MessageBuffer + 6, count);
\r
3153 CurrentPhonebookEntry->Name[count] = 0x00;
\r
3156 CurrentPhonebookEntry->Empty = false;
\r
3158 for (tmp=0; tmp <count; tmp++)
\r
3160 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33INT ||
\r
3161 GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM) {//pbk with Unicode
\r
3162 /* We check only 1'st, 3'rd, ... char */
\r
3163 if (tmp%2!=0 && MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp/2]='~'; //enables/disables blinking
\r
3164 if (tmp%2!=0 && MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp/2]='`'; //hides rest ot contents
\r
3166 if (MessageBuffer[6+tmp]==1) CurrentPhonebookEntry->Name[tmp]='~'; //enables/disables blinking
\r
3167 if (MessageBuffer[6+tmp]==0) CurrentPhonebookEntry->Name[tmp]='`'; //hides rest ot contents
\r
3172 count=MessageBuffer[6+count];
\r
3175 fprintf(stdout, _(" Number: "));
\r
3177 for (tmp=0; tmp <count; tmp++)
\r
3178 fprintf(stdout, "%c", MessageBuffer[i+tmp]);
\r
3180 fprintf(stdout, "\n");
\r
3181 #endif /* DEBUG */
\r
3183 memcpy(CurrentPhonebookEntry->Number, MessageBuffer + i, count);
\r
3184 CurrentPhonebookEntry->Number[count] = 0x00;
\r
3185 CurrentPhonebookEntry->Group = MessageBuffer[i+count];
\r
3187 /* Phone doesn't have entended phonebook */
\r
3188 CurrentPhonebookEntry->SubEntriesCount = 0;
\r
3190 /* But for these memories data is saved and we can save it using 7110/6210 style */
\r
3191 if (CurrentPhonebookEntry->MemoryType==GMT_DC ||
\r
3192 CurrentPhonebookEntry->MemoryType==GMT_RC ||
\r
3193 CurrentPhonebookEntry->MemoryType==GMT_MC) {
\r
3194 CurrentPhonebookEntry->SubEntriesCount = 1;
\r
3195 CurrentPhonebookEntry->SubEntries[0].EntryType=N7110_ENTRYTYPE_DATE;
\r
3196 CurrentPhonebookEntry->SubEntries[0].NumberType=0;
\r
3197 CurrentPhonebookEntry->SubEntries[0].BlockNumber=1;
\r
3198 DecodeDateTime(MessageBuffer+(i+count+2),&CurrentPhonebookEntry->SubEntries[0].data.Date);
\r
3201 fprintf(stdout, _(" Date: "));
\r
3202 fprintf(stdout, "%02u.%02u.%04u\n",
\r
3203 CurrentPhonebookEntry->SubEntries[0].data.Date.Day,
\r
3204 CurrentPhonebookEntry->SubEntries[0].data.Date.Month,
\r
3205 CurrentPhonebookEntry->SubEntries[0].data.Date.Year);
\r
3206 fprintf(stdout, _(" Time: "));
\r
3207 fprintf(stdout, "%02u:%02u:%02u\n",
\r
3208 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour,
\r
3209 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute,
\r
3210 CurrentPhonebookEntry->SubEntries[0].data.Date.Second);
\r
3211 #endif /* DEBUG */
\r
3213 /* These values are set, when date and time unavailable in phone.
\r
3214 Values from 3310 - in other can be different */
\r
3215 if (CurrentPhonebookEntry->SubEntries[0].data.Date.Day==20 &&
\r
3216 CurrentPhonebookEntry->SubEntries[0].data.Date.Month==1 &&
\r
3217 CurrentPhonebookEntry->SubEntries[0].data.Date.Year==2118 &&
\r
3218 CurrentPhonebookEntry->SubEntries[0].data.Date.Hour==3 &&
\r
3219 CurrentPhonebookEntry->SubEntries[0].data.Date.Minute==14 &&
\r
3220 CurrentPhonebookEntry->SubEntries[0].data.Date.Second==7)
\r
3221 CurrentPhonebookEntry->SubEntriesCount = 0;
\r
3224 /* Signal no error to calling code. */
\r
3225 CurrentPhonebookError = GE_NONE;
\r
3232 fprintf(stdout, _("Message: Phonebook read entry error received:\n"));
\r
3233 #endif /* DEBUG */
\r
3235 switch (MessageBuffer[4]) {
\r
3239 fprintf(stdout, _(" Invalid memory type!\n"));
\r
3240 #endif /* DEBUG */
\r
3241 CurrentPhonebookError = GE_INVALIDMEMORYTYPE;
\r
3246 fprintf(stdout, _(" Unknown error!\n"));
\r
3247 #endif /* DEBUG */
\r
3248 CurrentPhonebookError = GE_INTERNALERROR;
\r
3256 /* Routine to get specifed phone book location. Designed to be called by
\r
3257 application. Will block until location is retrieved or a timeout/error
\r
3259 GSM_Error N6110_GetMemoryLocation(GSM_PhonebookEntry *entry)
\r
3261 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x00, 0x00, 0x00};
\r
3263 CurrentPhonebookEntry = entry;
\r
3265 req[4] = N6110_GetMemoryType(entry->MemoryType);
\r
3266 req[5] = entry->Location;
\r
3268 return NULL_SendMessageSequence
\r
3269 (50, &CurrentPhonebookError, 7, 0x03, req);
\r
3272 void N6110_ReplyWritePhonebookLocation(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3274 switch (MessageBuffer[3]) {
\r
3279 fprintf(stdout, _("Message: Phonebook written correctly.\n"));
\r
3280 #endif /* DEBUG */
\r
3281 CurrentPhonebookError = GE_NONE;
\r
3286 switch (MessageBuffer[4]) {
\r
3287 /* FIXME: other errors? When I send the phonebook with index of 350 it
\r
3288 still report error 0x7d :-( */
\r
3291 fprintf(stdout, _("Message: Phonebook not written - name is too long.\n"));
\r
3292 #endif /* DEBUG */
\r
3293 CurrentPhonebookError = GE_PHBOOKNAMETOOLONG;
\r
3298 fprintf(stdout, _(" Unknown error!\n"));
\r
3299 #endif /* DEBUG */
\r
3300 CurrentPhonebookError = GE_INTERNALERROR;
\r
3305 /* Routine to write phonebook location in phone. Designed to be called by
\r
3306 application code. Will block until location is written or timeout
\r
3308 GSM_Error N6110_WritePhonebookLocation(GSM_PhonebookEntry *entry)
\r
3310 unsigned char req[128] = { N6110_FRAME_HEADER, 0x04, 0x00, 0x00 };
\r
3311 int i=0, current=0;
\r
3313 req[4] = N6110_GetMemoryType(entry->MemoryType);
\r
3314 req[5] = entry->Location;
\r
3318 if (GetModelFeature (FN_PHONEBOOK)==F_PBK33INT ||
\r
3319 GetModelFeature (FN_PHONEBOOK)==F_PBK33SIM) {
\r
3321 req[6] = strlen(entry->Name)*2;
\r
3323 EncodeUnicode (req+current,entry->Name ,strlen(entry->Name));
\r
3325 for (i=0; i<strlen(entry->Name); i++)
\r
3327 /* here we encode "special" chars */
\r
3328 if (entry->Name[i]=='~') req[current+i*2]=1; //enables/disables blinking
\r
3329 if (entry->Name[i]=='`') req[current+i*2]=0; //hides rest ot contents
\r
3332 current+=strlen(entry->Name)*2;
\r
3335 req[6] = strlen(entry->Name);
\r
3337 for (i=0; i<strlen(entry->Name); i++)
\r
3339 req[current+i] = entry->Name[i];
\r
3341 /* here we encode "special" chars */
\r
3342 if (entry->Name[i]=='~') req[current+i]=1; //enables/disables blinking
\r
3343 if (entry->Name[i]=='`') req[current+i]=0; //hides rest ot contents
\r
3346 current+=strlen(entry->Name);
\r
3349 req[current++]=strlen(entry->Number);
\r
3351 for (i=0; i<strlen(entry->Number); i++)
\r
3352 req[current+i] = entry->Number[i];
\r
3354 current+=strlen(entry->Number);
\r
3356 /* Jano: This allow to save 14 characters name into SIM memory, when
\r
3357 No Group is selected. */
\r
3358 if (entry->Group == 5)
\r
3359 req[current++]=0xff;
\r
3361 req[current++]=entry->Group;
\r
3363 return NULL_SendMessageSequence
\r
3364 (50, &CurrentPhonebookError, current, 0x03, req);
\r
3367 void N6110_ReplyNetmonitor(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3369 switch(MessageBuffer[3]) {
\r
3373 fprintf(stdout, _("Message: Netmonitor correctly set.\n"));
\r
3374 #endif /* DEBUG */
\r
3375 CurrentNetmonitorError=GE_NONE;
\r
3380 fprintf(stdout, _("Message: Netmonitor menu %d received:\n"), MessageBuffer[3]);
\r
3381 fprintf(stdout, "%s\n", MessageBuffer+4);
\r
3382 #endif /* DEBUG */
\r
3384 strcpy(CurrentNetmonitor, MessageBuffer+4);
\r
3386 CurrentNetmonitorError=GE_NONE;
\r
3390 GSM_Error N6110_NetMonitor(unsigned char mode, char *Screen)
\r
3392 unsigned char req[] = { 0x00, 0x01, 0x7e, 0x00 };
\r
3396 error=N6110_EnableExtendedCommands(0x01);
\r
3397 if (error!=GE_NONE) return error;
\r
3399 CurrentNetmonitor=Screen;
\r
3403 return NULL_SendMessageSequence
\r
3404 (20, &CurrentNetmonitorError, 4, 0x40, req);
\r
3407 /* Doesn't work in N3210. */
\r
3408 /* In other allow to access phone menu without SIM card (just send any sequence) */
\r
3409 GSM_Error N6110_SendDTMF(char *String)
\r
3411 unsigned char req[64] = { N6110_FRAME_HEADER, 0x50,
\r
3412 0x00 /* Length of DTMF string. */
\r
3415 u8 length=strlen(String);
\r
3417 if (length>59) length=59;
\r
3421 memcpy(req+5,String,length);
\r
3423 return NULL_SendMessageSequence
\r
3424 (20, &CurrentSendDTMFError, 5+length, 0x01, req);
\r
3427 void N6110_ReplyGetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3429 switch (MessageBuffer[3]) {
\r
3433 switch (MessageBuffer[4]) {
\r
3434 case 0x02: CurrentSpeedDialEntry->MemoryType = GMT_ME;
\r
3435 default : CurrentSpeedDialEntry->MemoryType = GMT_SM;
\r
3438 CurrentSpeedDialEntry->Location = MessageBuffer[5];
\r
3441 fprintf(stdout, _("Message: Speed dial entry received:\n"));
\r
3442 fprintf(stdout, _(" Location: %d\n"), CurrentSpeedDialEntry->Location);
\r
3443 fprintf(stdout, _(" MemoryType: %s\n"), N6110_MemoryType_String[CurrentSpeedDialEntry->MemoryType]);
\r
3444 fprintf(stdout, _(" Number: %d\n"), CurrentSpeedDialEntry->Number);
\r
3445 #endif /* DEBUG */
\r
3447 CurrentSpeedDialError=GE_NONE;
\r
3453 fprintf(stdout, _("Message: Speed dial entry error\n"));
\r
3454 #endif /* DEBUG */
\r
3455 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
\r
3461 GSM_Error N6110_GetSpeedDial(GSM_SpeedDial *entry)
\r
3464 unsigned char req[] = { N6110_FRAME_HEADER,
\r
3466 0x00 /* The number of speed dial. */
\r
3469 CurrentSpeedDialEntry = entry;
\r
3471 req[4] = entry->Number;
\r
3473 return NULL_SendMessageSequence
\r
3474 (20, &CurrentSpeedDialError, 5, 0x03, req);
\r
3477 void N6110_ReplySetSpeedDial(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3479 switch (MessageBuffer[3]) {
\r
3484 fprintf(stdout, _("Message: Speed dial entry set.\n"));
\r
3485 #endif /* DEBUG */
\r
3486 CurrentSpeedDialError=GE_NONE;
\r
3492 fprintf(stdout, _("Message: Speed dial entry setting error.\n"));
\r
3493 #endif /* DEBUG */
\r
3494 CurrentSpeedDialError=GE_INVALIDSPEEDDIALLOCATION;
\r
3500 GSM_Error N6110_SetSpeedDial(GSM_SpeedDial *entry)
\r
3503 unsigned char req[] = { N6110_FRAME_HEADER,
\r
3505 0x00, /* Number */
\r
3506 0x00, /* Memory Type */
\r
3507 0x00 /* Location */
\r
3510 req[4] = entry->Number;
\r
3512 switch (entry->MemoryType) {
\r
3513 case GMT_ME: req[5] = 0x02;
\r
3514 default : req[5] = 0x03;
\r
3517 req[6] = entry->Location;
\r
3519 return NULL_SendMessageSequence
\r
3520 (20, &CurrentSpeedDialError, 7, 0x03, req);
\r
3523 /* This function finds parts of SMS in frame used in new Nokia phones
\r
3524 in internal protocols (they're coded according to GSM 03.40), copies them
\r
3525 to GSM_ETSISMSMessage and calls GSM_DecodeETSISMS to decode
\r
3526 GSM_ETSISMSMessage to GSM_SMSMessage structure */
\r
3527 GSM_Error GSM_DecodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int length)
\r
3529 SMS_MessageType PDU=SMS_Deliver;
\r
3530 GSM_ETSISMSMessage ETSI;
\r
3533 ETSI.firstbyte=req[12];
\r
3535 /* See GSM 03.40 section 9.2.3.1 */
\r
3536 if ((ETSI.firstbyte & 0x03) == 0x01) PDU=SMS_Submit;
\r
3537 if ((ETSI.firstbyte & 0x03) == 0x02) PDU=SMS_Status_Report;
\r
3540 case SMS_Submit : offset=5;break;
\r
3541 case SMS_Deliver : offset=4;break;
\r
3542 case SMS_Status_Report: offset=3;break;
\r
3546 for (i=0;i<req[0]+1;i++)
\r
3547 ETSI.SMSCNumber[i]=req[i];
\r
3549 for (i=0;i<((req[12+offset]+1)/2+1)+1;i++)
\r
3550 ETSI.Number[i]=req[i+12+offset];
\r
3554 ETSI.TPDCS=req[10+offset];
\r
3555 ETSI.TPUDL=req[11+offset];
\r
3556 ETSI.TPVP=0; //no support for now
\r
3557 ETSI.TPPID=0; //no support for now
\r
3558 for(i=31+offset;i<length;i++)
\r
3559 ETSI.MessageText[i-31-offset]=req[i];
\r
3562 ETSI.TPDCS=req[10+offset];
\r
3563 ETSI.TPUDL=req[11+offset];
\r
3564 ETSI.TPPID=0; //no support for now
\r
3565 for(i=31+offset;i<length;i++)
\r
3566 ETSI.MessageText[i-31-offset]=req[i];
\r
3568 ETSI.DeliveryDateTime[i]=req[i+24+offset];
\r
3570 case SMS_Status_Report:
\r
3572 ETSI.DeliveryDateTime[i]=req[i+24+offset];
\r
3573 ETSI.TPStatus=req[14];
\r
3575 ETSI.SMSCDateTime[i]=req[i+34];
\r
3581 GSM_DecodeETSISMS(SMS, &ETSI);
\r
3588 void N6110_ReplyGetSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3592 switch (MessageBuffer[3]) {
\r
3596 switch (MessageBuffer[7]) {
\r
3599 CurrentSMSMessage->Type = GST_SMS;
\r
3600 CurrentSMSMessage->folder=GST_INBOX;
\r
3605 CurrentSMSMessage->Type = GST_DR;
\r
3606 CurrentSMSMessage->folder=GST_INBOX;
\r
3611 CurrentSMSMessage->Type = GST_SMS;
\r
3612 CurrentSMSMessage->folder=GST_OUTBOX;
\r
3617 CurrentSMSMessage->Type = GST_UN;
\r
3623 /* Field Short Message Status - MessageBuffer[4] seems not to be
\r
3624 compliant with GSM 07.05 spec.
\r
3625 Meaning Nokia protocol GMS spec
\r
3626 ----------------------------------------------------
\r
3627 MO Sent 0x05 0x07 or 0x01
\r
3628 MO Not sent 0x07 0x06 or 0x00
\r
3629 MT Read 0x01 0x05 or 0x01
\r
3630 MT Not read 0x03 0x04 or 0x00
\r
3631 ----------------------------------------------------
\r
3632 See GSM 07.05 section 2.5.2.6 and correct me if I'm wrong.
\r
3636 if (MessageBuffer[4] & 0x02) CurrentSMSMessage->Status = GSS_NOTSENTREAD;
\r
3637 else CurrentSMSMessage->Status = GSS_SENTREAD;
\r
3640 fprintf(stdout, _("Number: %d\n"), MessageBuffer[6]);
\r
3642 if (CurrentSMSMessage->folder!=1) { //GST_OUTBOX
\r
3643 fprintf(stdout, _("Message: Received SMS (mobile terminated)\n"));
\r
3645 fprintf(stdout, _("Message: Outbox message (mobile originated)\n"));
\r
3648 if (CurrentSMSMessage->Type == GST_DR) fprintf(stdout, _(" Delivery Report\n"));
\r
3649 if (CurrentSMSMessage->Type == GST_UN) fprintf(stdout, _(" Unknown type\n"));
\r
3651 if (CurrentSMSMessage->folder==1) { //GST_OUTBOX
\r
3652 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Sent\n"));
\r
3653 else fprintf(stdout, _(" Not sent\n"));
\r
3655 if (CurrentSMSMessage->Status) fprintf(stdout, _(" Read\n"));
\r
3656 else fprintf(stdout, _(" Not read\n"));
\r
3660 CurrentSMSPointer=GSM_DecodeNokiaSMSFrame(CurrentSMSMessage, MessageBuffer+8, MessageLength-8);
\r
3662 CurrentSMSMessage->MemoryType = MessageBuffer[5];
\r
3663 CurrentSMSMessage->MessageNumber = MessageBuffer[6];
\r
3665 /* Signal no error to calling code. */
\r
3666 CurrentSMSMessageError = GE_NONE;
\r
3669 fprintf(stdout, "\n");
\r
3676 /* We have requested invalid or empty location. */
\r
3679 fprintf(stdout, _("Message: SMS reading failed\n"));
\r
3681 switch (MessageBuffer[4]) {
\r
3683 fprintf(stdout, _(" Invalid location!\n"));break;
\r
3685 fprintf(stdout, _(" Empty SMS location.\n"));break;
\r
3687 fprintf(stdout, _(" No access to memory (no PIN on card ?)\n"));break;
\r
3689 fprintf(stdout, _(" Error code %i - please report it \n"),MessageBuffer[4]);break;
\r
3691 #endif /* DEBUG */
\r
3693 switch (MessageBuffer[4]) {
\r
3694 case 0x02:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
\r
3695 case 0x07:CurrentSMSMessageError = GE_EMPTYSMSLOCATION;break;
\r
3696 case 0x0c:CurrentSMSMessageError = GE_NOACCESS;break;
\r
3697 default :CurrentSMSMessageError = GE_UNKNOWN;break;
\r
3705 GSM_Error N6110_GetSMSMessage(GSM_SMSMessage *message)
\r
3708 unsigned char req[] = { N6110_FRAME_HEADER,
\r
3710 0x02, /* Unknown */
\r
3711 0x00, /* Location */
\r
3716 /* State machine code writes data to these variables when it comes in. */
\r
3718 CurrentSMSMessage = message;
\r
3719 CurrentSMSMessageError = GE_BUSY;
\r
3721 req[5] = message->Location;
\r
3723 /* Send request */
\r
3724 Protocol->SendMessage(8, 0x02, req);
\r
3726 /* Wait for timeout or other error. */
\r
3727 while (timeout != 0 && (CurrentSMSMessageError == GE_BUSY || CurrentSMSMessageError == GE_SMSWAITING)) {
\r
3729 if (--timeout == 0)
\r
3730 return (GE_TIMEOUT);
\r
3735 return (CurrentSMSMessageError);
\r
3738 void N6110_ReplyDeleteSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3741 fprintf(stdout, _("Message: SMS deleted successfully.\n"));
\r
3742 #endif /* DEBUG */
\r
3744 CurrentSMSMessageError = GE_NONE;
\r
3747 GSM_Error N6110_DeleteSMSMessage(GSM_SMSMessage *message)
\r
3749 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02, 0x00};
\r
3751 req[5] = message->Location;
\r
3753 return NULL_SendMessageSequence
\r
3754 (50, &CurrentSMSMessageError, 6, 0x14, req);
\r
3757 /* FIXME: do we need more than SMS_Submit and SMS_Deliver ? */
3758 GSM_Error GSM_EncodeNokiaSMSFrame(GSM_SMSMessage *SMS, unsigned char *req, int *length, SMS_MessageType PDU)
3760 GSM_ETSISMSMessage ETSI;
3763 GSM_EncodeETSISMS(SMS, &ETSI, PDU, length);
3766 for (i=0;i<36;i++) req[i]=0;
3768 req[12]=ETSI.firstbyte;
3770 for (i=0;i<ETSI.SMSCNumber[0]+1;i++)
3771 req[i]=ETSI.SMSCNumber[i];
3776 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3777 req[i+12+offset]=ETSI.Number[i];
3778 req[10+offset]=ETSI.TPDCS;
3779 req[11+offset]=ETSI.TPUDL;
3780 req[24+offset]=ETSI.TPVP;
3782 // fprintf(stdout,_(" First byte: %02x\n"),ETSI.firstbyte);
3783 // fprintf(stdout,_(" TP-VP: %02x\n"),ETSI.TPVP);
3784 // fprintf(stdout,_(" TP-DCS: %02x\n"),ETSI.TPDCS);
3786 // req[]=ETSI.TPPID;
3787 for(i=0;i<*length;i++)
3788 req[i+31+offset]=ETSI.MessageText[i];
3793 for (i=0;i<((ETSI.Number[0]+1)/2+1)+1;i++)
3794 req[i+12+offset]=ETSI.Number[i];
3795 req[10+offset]=ETSI.TPDCS;
3796 req[11+offset]=ETSI.TPUDL;
3797 // req[]=ETSI.TPPID;
3798 for(i=0;i<*length;i++)
3799 req[i+31+offset]=ETSI.MessageText[i];
3801 req[24+offset+i]=ETSI.DeliveryDateTime[i];
3807 *length=*length+offset;
3812 void N6110_ReplySendSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3814 switch (MessageBuffer[3]) {
\r
3816 /* SMS message correctly sent to the network */
\r
3819 fprintf(stdout, _("Message: SMS Message correctly sent.\n"));
\r
3820 #endif /* DEBUG */
\r
3821 CurrentSMSMessageError = GE_SMSSENDOK;
\r
3824 /* SMS message send to the network failed */
\r
3828 fprintf(stdout, _("Message: Sending SMS Message failed, error: %i"),MessageBuffer[6]);
\r
3830 switch (MessageBuffer[6]) {
\r
3831 case 1: fprintf(stdout,_(" (info \"Number not in use\")"));break;
\r
3832 case 21: fprintf(stdout,_(" (info \"Message not sent this time\")"));break;
\r
3833 case 28: fprintf(stdout,_(" (info \"Number not in use\")"));break;
\r
3834 case 38: fprintf(stdout,_(" (info \"Message not sent this time\")"));break; case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break;
\r
3835 case 96: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
\r
3836 case 111: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
\r
3837 case 166: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
\r
3838 case 178: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
\r
3839 case 252: fprintf(stdout,_(" (info \"Message sending failed\")"));break; case 253: fprintf(stdout,_(" (info \"Message sending failed\")"));break;
\r
3842 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 65) on www.marcin-wiacek.topnet.pl"));
\r
3843 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
\r
3844 #endif /* DEBUG */
\r
3846 CurrentSMSMessageError = GE_SMSSENDFAILED;
\r
3852 GSM_Error N6110_SendSMSMessage(GSM_SMSMessage *SMS)
\r
3856 unsigned char req[256] = {
\r
3857 N6110_FRAME_HEADER,
\r
3858 0x01, 0x02, 0x00, /* SMS send request*/
\r
3863 error=GSM_EncodeNokiaSMSFrame(SMS, req+6, &length, SMS_Submit);
\r
3864 if (error != GE_NONE) return error;
\r
3866 return NULL_SendMessageSequence
\r
3867 (200, &CurrentSMSMessageError, 42+length, 0x02, req);
\r
3870 void N6110_ReplySaveSMSMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3872 switch (MessageBuffer[3]) {
\r
3877 fprintf(stdout, _("SMS Message stored at %d\n"), MessageBuffer[5]);
\r
3880 CurrentSMSMessage->MessageNumber=MessageBuffer[5];
\r
3882 CurrentSMSMessageError = GE_NONE;
\r
3887 fprintf(stdout, _("SMS saving failed\n"));
\r
3888 switch (MessageBuffer[4]) {
\r
3889 case 0x02:fprintf(stdout, _(" All locations busy.\n"));break;
\r
3890 case 0x03:fprintf(stdout, _(" Invalid location!\n"));break;
\r
3891 default :fprintf(stdout, _(" Unknown error.\n"));break;
\r
3895 switch (MessageBuffer[4]) {
\r
3896 case 0x02:CurrentSMSMessageError = GE_MEMORYFULL;break;
\r
3897 case 0x03:CurrentSMSMessageError = GE_INVALIDSMSLOCATION;break;
\r
3898 default :CurrentSMSMessageError = GE_UNKNOWN;break;
\r
3903 /* GST_DR and GST_UN not supported ! */
\r
3904 GSM_Error N6110_SaveSMSMessage(GSM_SMSMessage *SMS)
\r
3906 unsigned char req[256] = {
\r
3907 N6110_FRAME_HEADER, 0x04, /* SMS save request*/
\r
3908 0x00, /* SMS Status. Different for Inbox and Outbox */
\r
3910 0x00, /* SMS Location */
\r
3911 0x02, /* SMS Type */
\r
3915 SMS_MessageType PDU;
\r
3918 if (SMS->Location) req[6] = SMS->Location;
\r
3920 if (SMS->folder==0) { /*Inbox*/
\r
3921 req[4]=1; /* SMS Status */
\r
3922 req[7] = 0x00; /* SMS Type */
\r
3925 req[4]=5; /* SMS Status */
\r
3926 req[7] = 0x02; /* SMS Type */
\r
3930 if (SMS->Status == GSS_NOTSENTREAD) req[4] |= 0x02;
\r
3932 error=GSM_EncodeNokiaSMSFrame(SMS, req+8, &length, PDU);
\r
3933 if (error != GE_NONE) return error;
\r
3935 CurrentSMSMessage = SMS;
\r
3937 return NULL_SendMessageSequence
\r
3938 (70, &CurrentSMSMessageError, 39+length, 0x14, req);
\r
3941 void N6110_ReplySetCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3944 fprintf(stdout, _("Message: Cell Broadcast enabled/disabled successfully.\n")); fflush (stdout);
\r
3947 CurrentCBError = GE_NONE;
\r
3950 /* Enable and disable Cell Broadcasting */
\r
3951 GSM_Error N6110_EnableCellBroadcast(void)
\r
3953 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
\r
3954 0x01, 0x01, 0x00, 0x00, 0x01, 0x01};
\r
3957 fprintf (stdout,"Enabling CB\n");
\r
3960 CurrentCBMessage = (GSM_CBMessage *)malloc(sizeof (GSM_CBMessage));
\r
3961 CurrentCBMessage->Channel = 0;
\r
3962 CurrentCBMessage->New = false;
\r
3963 strcpy (CurrentCBMessage->Message,"");
\r
3965 return NULL_SendMessageSequence
\r
3966 (10, &CurrentCBError, 10, 0x02, req);
\r
3970 GSM_Error N6110_DisableCellBroadcast(void)
\r
3972 /* Should work, but not tested fully */
\r
3974 unsigned char req[] = {N6110_FRAME_HEADER, 0x20,
\r
3975 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /*VERIFY*/
\r
3977 return NULL_SendMessageSequence
\r
3978 (10, &CurrentCBError, 10, 0x02, req);
\r
3981 void N6110_ReplyReadCellBroadcast(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
3984 unsigned char output[160];
\r
3986 CurrentCBMessage->Channel = MessageBuffer[7];
\r
3987 CurrentCBMessage->New = true;
\r
3988 tmp=GSM_UnpackEightBitsToSeven(0, MessageBuffer[9], MessageBuffer[9], MessageBuffer+10, output);
\r
3991 fprintf(stdout, _("Message: CB received.\n")); fflush (stdout);
\r
3993 fprintf(stdout, _("Message: channel number %i\n"),MessageBuffer[7]);
\r
3997 for (i=0; i<tmp;i++) {
\r
3998 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
\r
4001 fprintf(stdout, "\n");
\r
4004 for (i=0; i<tmp; i++) {
\r
4005 CurrentCBMessage->Message[i] = DecodeWithDefaultAlphabet(output[i]);
\r
4007 CurrentCBMessage->Message[i]=0;
\r
4010 GSM_Error N6110_ReadCellBroadcast(GSM_CBMessage *Message)
\r
4013 fprintf(stdout,"Reading CB\n");
\r
4016 if (CurrentCBMessage != NULL)
\r
4018 if (CurrentCBMessage->New == true)
\r
4021 fprintf(stdout,"New CB received\n");
\r
4023 Message->Channel = CurrentCBMessage->Channel;
\r
4024 strcpy(Message->Message,CurrentCBMessage->Message);
\r
4025 CurrentCBMessage->New = false;
\r
4029 return (GE_NONEWCBRECEIVED);
\r
4032 int N6110_MakeCallerGroupFrame(unsigned char *req,GSM_Bitmap Bitmap)
\r
4036 req[count++]=Bitmap.number;
\r
4037 req[count++]=strlen(Bitmap.text);
\r
4038 memcpy(req+count,Bitmap.text,req[count-1]);
\r
4039 count+=req[count-1];
\r
4040 req[count++]=Bitmap.ringtone;
\r
4042 /* Setting for graphic:
\r
4045 0x02 - View Graphics
\r
4046 0x03 - Send Graphics
\r
4047 0x04 - Send via IR
\r
4048 You can even set it higher but Nokia phones (my
\r
4049 6110 at least) will not show you the name of this
\r
4050 item in menu ;-)) Nokia is really joking here. */
\r
4051 if (Bitmap.enabled) req[count++]=0x01;
\r
4052 else req[count++]=0x00;
\r
4054 req[count++]=(Bitmap.size+4)>>8;
\r
4055 req[count++]=(Bitmap.size+4)%0xff;
\r
4056 req[count++]=0x00; /* Future extensions! */
\r
4057 req[count++]=Bitmap.width;
\r
4058 req[count++]=Bitmap.height;
\r
4059 req[count++]=0x01; /* Just BW */
\r
4060 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
\r
4062 return count+Bitmap.size;
\r
4065 int N6110_MakeOperatorLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
\r
4069 EncodeNetworkCode(req+count, Bitmap.netcode);
\r
4072 req[count++]=(Bitmap.size+4)>>8;
\r
4073 req[count++]=(Bitmap.size+4)%0xff;
\r
4074 req[count++]=0x00; /* Infofield */
\r
4075 req[count++]=Bitmap.width;
\r
4076 req[count++]=Bitmap.height;
\r
4077 req[count++]=0x01; /* Just BW */
\r
4078 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
\r
4080 return count+Bitmap.size;
\r
4083 int N6110_MakeStartupLogoFrame(unsigned char *req,GSM_Bitmap Bitmap)
\r
4087 req[count++]=0x01;
\r
4088 req[count++]=Bitmap.height;
\r
4089 req[count++]=Bitmap.width;
\r
4090 memcpy(req+count,Bitmap.bitmap,Bitmap.size);
\r
4092 return count+Bitmap.size;
\r
4095 /* Set a bitmap or welcome-note */
\r
4096 GSM_Error N6110_SetBitmap(GSM_Bitmap *Bitmap) {
\r
4098 unsigned char req[600] = { N6110_FRAME_HEADER };
\r
4104 /* Direct uploading variables */
4105 GSM_MultiSMSMessage SMS;
4106 unsigned char buffer[1000] = {0x0c,0x01};
4107 GSM_NetworkInfo NetworkInfo;
4111 /* Uploading with preview */
4112 if (Bitmap->number==255 &&
4113 (Bitmap->type==GSM_OperatorLogo || Bitmap->type==GSM_CallerLogo)) {
4114 GSM_SaveBitmapToSMS(&SMS,Bitmap,false,false);
4115 memcpy(buffer+2,SMS.SMS[0].UDH,SMS.SMS[0].UDH[0]+1);
4117 memcpy(buffer+2+SMS.SMS[0].UDH[0]+1,SMS.SMS[0].MessageText,SMS.SMS[0].Length);
4119 buffer[2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length]=0x00;
4121 Protocol->SendMessage(2+SMS.SMS[0].UDH[0]+1+SMS.SMS[0].Length+1, 0x12, buffer);
4123 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4124 return GE_NONE; //no answer from phone
4127 CurrentSetBitmapError = GE_BUSY;
\r
4129 switch (Bitmap->type) {
\r
4130 case GSM_WelcomeNoteText:
\r
4131 case GSM_DealerNoteText:
\r
4132 req[count++]=0x18;
\r
4133 req[count++]=0x01; /* Only one block */
\r
4135 if (Bitmap->type==GSM_WelcomeNoteText)
\r
4136 req[count++]=0x02; /* Welcome text */
\r
4138 req[count++]=0x03; /* Dealer Welcome Note */
\r
4140 textlen=strlen(Bitmap->text);
\r
4141 req[count++]=textlen;
\r
4142 memcpy(req+count,Bitmap->text,textlen);
\r
4146 Protocol->SendMessage(count, 0x05, req);
\r
4150 case GSM_StartupLogo:
\r
4151 if (Bitmap->number==0) {
\r
4153 /* For 33xx we first set animated logo to default */
\r
4154 if (GetModelFeature (FN_STARTUP)==F_STANIM) {
\r
4155 error=N6110_SetProfileFeature(0, 0x29, Bitmap->number);
\r
4156 if (error!=GE_NONE) return error;
\r
4159 req[count++]=0x18;
\r
4160 req[count++]=0x01; /* Only one block */
\r
4161 count=count+N6110_MakeStartupLogoFrame(req+5,*Bitmap);
\r
4162 Protocol->SendMessage(count, 0x05, req);
\r
4164 return N6110_SetProfileFeature(0, 0x29, Bitmap->number);
\r
4168 case GSM_OperatorLogo:
\r
4169 req[count++]=0x30; /* Store Op Logo */
\r
4170 req[count++]=0x01; /* Location */
\r
4171 count=count+N6110_MakeOperatorLogoFrame(req+5,*Bitmap);
4172 Protocol->SendMessage(count, 0x05, req);
\r
4175 case GSM_CallerLogo:
\r
4176 req[count++]=0x13;
\r
4177 count=count+N6110_MakeCallerGroupFrame(req+4,*Bitmap);
\r
4178 Protocol->SendMessage(count, 0x03, req);
\r
4181 case GSM_PictureImage:
\r
4182 req[count++]=0x03;
\r
4183 req[count++]=Bitmap->number;
\r
4184 if (strcmp(Bitmap->Sender,"")) {
\r
4185 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
\r
4187 /* Convert number of semioctets to number of chars and add count */
\r
4188 textlen=req[count];
\r
4189 if (textlen % 2) textlen++;
\r
4190 count+=textlen / 2 + 1;
\r
4194 req[count++]=0x00;
\r
4195 req[count++]=0x00;
\r
4197 req[count++]=0x00;
\r
4198 req[count++]=strlen(Bitmap->text);
\r
4199 memcpy(req+count,Bitmap->text,strlen(Bitmap->text));
\r
4200 count+=strlen(Bitmap->text);
\r
4201 req[count++]=0x00;
\r
4202 req[count++]=Bitmap->width;
\r
4203 req[count++]=Bitmap->height;
\r
4204 req[count++]=0x01;
\r
4205 memcpy(req+count,Bitmap->bitmap,Bitmap->size);
\r
4206 Protocol->SendMessage(count+Bitmap->size, 0x47, req);
\r
4209 case GSM_7110OperatorLogo:
\r
4210 case GSM_7110StartupLogo:
\r
4211 case GSM_6210StartupLogo:
\r
4212 return GE_NOTSUPPORTED;
\r
4218 /* Wait for timeout or other error. */
\r
4219 while (timeout != 0 && CurrentSetBitmapError == GE_BUSY ) {
\r
4221 if (--timeout == 0)
\r
4222 return (GE_TIMEOUT);
\r
4227 return CurrentSetBitmapError;
\r
4230 /* Get a bitmap from the phone */
\r
4231 GSM_Error N6110_GetBitmap(GSM_Bitmap *Bitmap) {
\r
4233 unsigned char req[10] = { N6110_FRAME_HEADER };
\r
4238 CurrentGetBitmap=Bitmap;
\r
4239 CurrentGetBitmapError = GE_BUSY;
\r
4241 switch (CurrentGetBitmap->type) {
\r
4242 case GSM_StartupLogo:
\r
4243 case GSM_WelcomeNoteText:
\r
4244 case GSM_DealerNoteText:
\r
4245 req[count++]=0x16;
\r
4246 Protocol->SendMessage(count, 0x05, req);
\r
4248 case GSM_OperatorLogo:
\r
4249 req[count++]=0x33;
\r
4250 req[count++]=0x01; /* Location 1 */
\r
4251 Protocol->SendMessage(count, 0x05, req);
\r
4253 case GSM_CallerLogo:
\r
4254 req[count++]=0x10;
\r
4255 req[count++]=Bitmap->number;
\r
4256 Protocol->SendMessage(count, 0x03, req);
\r
4258 case GSM_PictureImage:
\r
4259 req[count++]=0x01;
\r
4260 req[count++]=Bitmap->number;
\r
4261 Protocol->SendMessage(count, 0x47, req);
\r
4263 case GSM_7110OperatorLogo:
\r
4264 case GSM_7110StartupLogo:
\r
4265 case GSM_6210StartupLogo:
\r
4267 return GE_NOTSUPPORTED;
\r
4270 /* Wait for timeout or other error. */
\r
4271 while (timeout != 0 && CurrentGetBitmapError == GE_BUSY ) {
\r
4273 if (--timeout == 0)
\r
4274 return (GE_TIMEOUT);
\r
4279 CurrentGetBitmap=NULL;
\r
4281 return CurrentGetBitmapError;
\r
4284 void N6110_ReplySetRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
4286 switch (MessageBuffer[3]) {
\r
4288 /* Set ringtone OK */
\r
4291 fprintf(stdout, _("Message: Ringtone set OK!\n"));
\r
4293 CurrentRingtoneError=GE_NONE;
\r
4296 /* Set ringtone error */
\r
4299 fprintf(stdout, _("Message: Ringtone setting error !\n"));
\r
4301 CurrentRingtoneError=GE_NOTSUPPORTED;
\r
4306 GSM_Error N6110_SetRingTone(GSM_Ringtone *ringtone, int *maxlength)
\r
4309 char req[FB61_MAX_RINGTONE_FRAME_LENGTH+10] =
\r
4310 {N6110_FRAME_HEADER,
\r
4312 0x00, /* Location */
\r
4315 int size=FB61_MAX_RINGTONE_FRAME_LENGTH;
\r
4317 /* Variables for preview uploading */
4318 unsigned char buffer[FB61_MAX_RINGTONE_FRAME_LENGTH+50];
4319 unsigned char buffer2[20];
4320 GSM_NetworkInfo NetworkInfo;
4322 /* Setting ringtone with preview */
4323 if (ringtone->location==255) {
4326 EncodeUDHHeader(buffer2, GSM_RingtoneUDH);
4327 memcpy(buffer+2,buffer2,buffer2[0]+1); //copying UDH
4328 *maxlength=GSM_PackRingtone(ringtone, buffer+2+buffer2[0]+1, &size); //packing ringtone
4329 Protocol->SendMessage(2+buffer2[0]+1+size, 0x12, buffer); //sending frame
4330 GSM->GetNetworkInfo(&NetworkInfo); //need to make something
4332 return GE_NONE; //no answer from phone
4335 *maxlength=GSM_PackRingtone(ringtone, req+7, &size);
\r
4337 req[4]=ringtone->location-1;
\r
4339 return NULL_SendMessageSequence
\r
4340 (50, &CurrentRingtoneError, (size+7), 0x05, req);
\r
4343 void N6110_ReplyGetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
4347 switch (MessageBuffer[4]) {
\r
4348 case 0x00: /* location supported. We have ringtone */
\r
4350 /* Binary format used in N6150 */
\r
4351 if (MessageBuffer[5]==0x0c && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
\r
4353 fprintf(stdout,_("Message: ringtone \""));
\r
4356 /* Copying name */
\r
4360 if (MessageBuffer[i]!=0)
\r
4361 fprintf(stdout,_("%c"),MessageBuffer[i]);
\r
4363 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
\r
4364 if (MessageBuffer[i]==0) break;
\r
4369 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
\r
4372 /* Looking for end */
\r
4375 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
\r
4378 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
\r
4382 if (i==MessageLength) break;
\r
4385 /* Copying frame */
\r
4386 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
\r
4387 CurrentGetBinRingtone->length=i-3;
\r
4389 CurrentBinRingtoneError=GE_NONE;
\r
4393 /* Binary format used in N3210 */
\r
4394 if (MessageBuffer[5]==0x10 && MessageBuffer[6]==0x01 && MessageBuffer[7]==0x2c) {
\r
4397 fprintf(stdout,_("Message: ringtone \""));
\r
4400 /* Copying name */
\r
4404 if (MessageBuffer[i]!=0)
\r
4405 fprintf(stdout,_("%c"),MessageBuffer[i]);
\r
4407 CurrentGetBinRingtone->name[i-8]=MessageBuffer[i];
\r
4408 if (MessageBuffer[i]==0) break;
\r
4413 fprintf(stdout,_("\" received from location %i\n"),MessageBuffer[3]+1);
\r
4416 /* Here changes to get full compatibility with binary format used in N6150 */
\r
4417 MessageBuffer[3]=0;
\r
4418 MessageBuffer[4]=0;
\r
4419 MessageBuffer[5]=0x0c;
\r
4420 MessageBuffer[6]=0x01;
\r
4421 MessageBuffer[7]=0x2c;
\r
4423 /* Looking for end */
\r
4426 if (MessageBuffer[i]==0x07 && MessageBuffer[i+1]==0x0b) {
\r
4429 if (MessageBuffer[i]==0x0e && MessageBuffer[i+1]==0x0b) {
\r
4433 if (i==MessageLength) break;
\r
4436 /* Copying frame */
\r
4437 memcpy(CurrentGetBinRingtone->frame,MessageBuffer+3,i-3);
\r
4439 CurrentGetBinRingtone->length=i-3;
\r
4441 CurrentBinRingtoneError=GE_NONE;
\r
4445 /* Copying frame */
\r
4446 memcpy(CurrentGetBinRingtone->frame,MessageBuffer,MessageLength);
\r
4448 CurrentGetBinRingtone->length=MessageLength;
\r
4451 fprintf(stdout,_("Message: unknown binary format for ringtone received from location %i\n"),MessageBuffer[3]+1);
\r
4453 CurrentBinRingtoneError=GE_UNKNOWNMODEL;
\r
4459 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
\r
4462 CurrentBinRingtoneError=GE_INVALIDRINGLOCATION;
\r
4466 GSM_Error N6110_GetBinRingTone(GSM_BinRingtone *ringtone)
\r
4468 unsigned char req[] = { 0x00,0x01,0x9e,
\r
4469 0x00 }; //location
\r
4473 CurrentGetBinRingtone=ringtone;
\r
4475 error=N6110_EnableExtendedCommands(0x01);
\r
4476 if (error!=GE_NONE) return error;
\r
4478 req[3]=ringtone->location-1;
\r
4480 return NULL_SendMessageSequence
\r
4481 (50, &CurrentBinRingtoneError, 4, 0x40, req);
\r
4484 void N6110_ReplySetBinRingtone(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
4486 switch (MessageBuffer[4]) {
\r
4487 case 0x00: /* location supported. We set ringtone */
\r
4489 fprintf(stdout,_("Message: downloaded ringtone set at location %i\n"),MessageBuffer[3]+1);
\r
4491 CurrentBinRingtoneError=GE_NONE;
\r
4496 fprintf(stdout,_("Message: Phone doesn't support downloaded ringtones at location %i\n"),MessageBuffer[3]+1);
\r
4498 CurrentBinRingtoneError=GE_NOTSUPPORTED;
\r
4503 GSM_Error N6110_SetBinRingTone(GSM_BinRingtone *ringtone)
\r
4505 unsigned char req[1000] = { 0x00,0x01,0xa0};
\r
4509 GSM_BinRingtone ring;
\r
4511 /* Must be sure, that can upload ringtone to this phone */
\r
4512 ring.location=ringtone->location;
\r
4513 error=N6110_GetBinRingTone(&ring);
\r
4514 if (error!=GE_NONE) return error;
\r
4516 error=N6110_EnableExtendedCommands(0x01);
\r
4517 if (error!=GE_NONE) return error;
\r
4519 memcpy(req+3,ringtone->frame,ringtone->length);
\r
4521 req[3]=ringtone->location-1;
\r
4523 return NULL_SendMessageSequence
\r
4524 (50, &CurrentBinRingtoneError, ringtone->length+3, 0x40, req);
\r
4527 GSM_Error N6110_Reset(unsigned char type)
\r
4529 return N6110_EnableExtendedCommands(type);
\r
4532 void N6110_Dispatch0x01Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
4536 switch (MessageBuffer[3]) {
\r
4538 /* Unknown message - it has been seen after the 0x07 message (call
\r
4539 answered). Probably it has similar meaning. If you can solve
\r
4540 this - just mail me. Pavel JanÃk ml.
\r
4542 The message looks like this:
\r
4544 Msg Destination: PC
\r
4550 Phone: [01 ][08 ][00 ] is the header of the frame
\r
4552 [03 ] is the call message subtype
\r
4554 [05 ] is the call sequence number
\r
4558 [00 ][01 ][03 ][02 ][91][00] are unknown but has been
\r
4559 seen in the Incoming call message (just after the
\r
4560 caller's name from the phonebook). But never change
\r
4561 between phone calls :-(
\r
4564 /* This may mean sequence number of 'just made' call - CK */
\r
4568 fprintf(stdout, _("Message: Call message, type 0x02:"));
\r
4569 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
\r
4570 #endif /* DEBUG */
\r
4574 /* Possibly call OK */
\r
4575 /* JD: I think that this means "call in progress" (incomming or outgoing) */
\r
4579 fprintf(stdout, _("Message: Call message, type 0x03:"));
\r
4580 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
\r
4581 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
\r
4582 #endif /* DEBUG */
\r
4584 CurrentCallSequenceNumber=MessageBuffer[4];
\r
4585 CurrentIncomingCall[0]='D';
\r
4586 if (CurrentCallPassup) CurrentCallPassup('D');
\r
4590 /* Remote end has gone away before you answer the call. Probably your
\r
4591 mother-in-law or banker (which is worse?) ... */
\r
4595 fprintf(stdout, _("Message: Remote end hang up.\n"));
\r
4596 fprintf(stdout, _(" Sequence nr. of the call: %d, error: %i"), MessageBuffer[4],MessageBuffer[6]);
\r
4598 switch (MessageBuffer[6]) {
\r
4599 case 28: fprintf(stdout,_(" (info \"Invalid phone number\")"));break;
\r
4600 case 34: fprintf(stdout,_(" (info \"Network busy\")"));break;
\r
4601 case 42: fprintf(stdout,_(" (info \"Network busy\")"));break;
\r
4602 case 47: fprintf(stdout,_(" (info \"Error in connection\")"));break;
\r
4603 case 50: fprintf(stdout,_(" (info \"Check operator services\")"));break; case 76: fprintf(stdout,_(" (info \"Check operator services\")"));break;
\r
4604 case 111: fprintf(stdout,_(" (info \"Error in connection\")"));break;
\r
4607 fprintf(stdout,_("\n For more details with errors see netmonitor manual (test 39) on www.marcin-wiacek.topnet.pl"));
\r
4608 fprintf(stdout,_("\n If know their meaning, GSM specs decribing them, contact with me on marcin-wiacek@topnet.pl. THX\n"));
\r
4609 #endif /* DEBUG */
\r
4611 CurrentIncomingCall[0] = ' ';
\r
4612 if (CurrentCallPassup) CurrentCallPassup(' ');
\r
4616 /* Incoming call alert */
\r
4620 fprintf(stdout, _("Message: Incoming call alert:\n"));
\r
4622 /* We can have more then one call ringing - we can distinguish between
\r
4625 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
\r
4626 fprintf(stdout, _(" Number: "));
\r
4628 count=MessageBuffer[6];
\r
4630 for (tmp=0; tmp <count; tmp++)
\r
4631 fprintf(stdout, "%c", MessageBuffer[7+tmp]);
\r
4633 fprintf(stdout, "\n");
\r
4635 fprintf(stdout, _(" Name: "));
\r
4637 for (tmp=0; tmp <MessageBuffer[7+count]; tmp++)
\r
4638 fprintf(stdout, "%c", MessageBuffer[8+count+tmp]);
\r
4640 fprintf(stdout, "\n");
\r
4641 #endif /* DEBUG */
\r
4643 count=MessageBuffer[6];
\r
4645 CurrentIncomingCall[0] = 0;
\r
4646 for (tmp=0; tmp <count; tmp++)
\r
4647 sprintf(CurrentIncomingCall, "%s%c", CurrentIncomingCall, MessageBuffer[7+tmp]);
\r
4651 /* Call answered. Probably your girlfriend...*/
\r
4655 fprintf(stdout, _("Message: Call answered.\n"));
\r
4656 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
\r
4657 #endif /* DEBUG */
\r
4661 /* Call ended. Girlfriend is girlfriend, but time is money :-) */
\r
4665 fprintf(stdout, _("Message: Call ended by your phone.\n"));
\r
4666 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
\r
4667 #endif /* DEBUG */
\r
4671 /* This message has been seen with the message of subtype 0x09
\r
4672 after I hang the call.
\r
4674 Msg Destination: PC
\r
4679 Phone: [01 ][08 ][00 ][0a ][04 ][87 ][01 ][42B][1a ][c2 ]
\r
4681 What is the meaning of 87? Can you spell some magic light into
\r
4686 /* Probably means call over - CK */
\r
4690 fprintf(stdout, _("Message: Call message, type 0x0a:"));
\r
4691 fprintf(stdout, _(" Sequence nr. of the call: %d\n"), MessageBuffer[4]);
\r
4692 fprintf(stdout, _(" Exact meaning not known yet, sorry :-(\n"));
\r
4693 #endif /* DEBUG */
\r
4695 CurrentIncomingCall[0] = ' ';
\r
4696 if (CurrentCallPassup) CurrentCallPassup(' ');
\r
4703 fprintf(stdout, _("Message: Answer for send DTMF or dial voice command\n"));
\r
4706 if (CurrentSendDTMFError!=GE_NONE) CurrentSendDTMFError=GE_NONE;
\r
4708 if (CurrentDialVoiceError!=GE_NONE) CurrentDialVoiceError=GE_NONE;
\r
4715 fprintf(stdout, _("Message: Unknown message of type 0x01\n"));
\r
4716 #endif /* DEBUG */
\r
4717 AppendLogText("Unknown msg\n",false);
\r
4719 break; /* Visual C Don't like empty cases */
\r
4723 void N6110_Dispatch0x03Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
4727 switch (MessageBuffer[3]) {
\r
4731 /* AFAIK, this frame isn't used anywhere - it's rather for testing :-) */
\r
4732 /* If you want see, if it works with your phone make something like that: */
\r
4734 /* unsigned char connect5[] = {N6110_FRAME_HEADER, 0x03}; */
\r
4735 /* Protocol->SendMessage(4, 0x04, connect5); */
\r
4737 /* Marcin-Wiacek@TopNet.PL */
\r
4740 sprintf(Current_IMEI, "%s", MessageBuffer+5);
\r
4741 sprintf(Current_Model, "%s", MessageBuffer+21);
\r
4742 sprintf(Current_Revision, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
\r
4744 snprintf(Current_IMEI, GSM_MAX_IMEI_LENGTH, "%s", MessageBuffer+5);
\r
4745 snprintf(Current_Model, GSM_MAX_MODEL_LENGTH, "%s", MessageBuffer+21);
\r
4746 snprintf(Current_Revision, GSM_MAX_REVISION_LENGTH, "SW%s, HW%s", MessageBuffer+41, MessageBuffer+35);
\r
4750 fprintf(stdout, _("Message: Mobile phone identification received:\n"));
\r
4751 fprintf(stdout, _(" IMEI: %s\n"), Current_IMEI);
\r
4752 fprintf(stdout, _(" Model: %s\n"), Current_Model);
\r
4753 fprintf(stdout, _(" Production Code: %s\n"), MessageBuffer+27);
\r
4754 fprintf(stdout, _(" HW: %s\n"), MessageBuffer+35);
\r
4755 fprintf(stdout, _(" Firmware: %s\n"), MessageBuffer+41);
\r
4756 #endif /* DEBUG */
\r
4760 /* Get group data */
\r
4761 /* [ID],[name_len],[name].,[ringtone],[graphicon],[lenhi],[lenlo],[bitmap] */
\r
4764 if (CurrentGetBitmap!=NULL) {
\r
4765 if (CurrentGetBitmap->number==MessageBuffer[4]) {
\r
4766 count=MessageBuffer[5];
\r
4767 memcpy(CurrentGetBitmap->text,MessageBuffer+6,count);
\r
4768 CurrentGetBitmap->text[count]=0;
\r
4771 fprintf(stdout, _("Message: Caller group datas\n"));
\r
4772 fprintf(stdout, _("Caller group name: %s\n"),CurrentGetBitmap->text);
\r
4773 #endif /* DEBUG */
\r
4777 CurrentGetBitmap->ringtone=MessageBuffer[count++];
\r
4779 fprintf(stdout, _("Caller group ringtone ID: %i"),CurrentGetBitmap->ringtone);
\r
4780 if (CurrentGetBitmap->ringtone==16) fprintf(stdout,_(" (default)"));
\r
4781 fprintf(stdout,_("\n"));
\r
4782 #endif /* DEBUG */
\r
4784 CurrentGetBitmap->enabled=(MessageBuffer[count++]==1);
\r
4786 fprintf(stdout, _("Caller group logo "));
\r
4787 if (CurrentGetBitmap->enabled)
\r
4788 fprintf(stdout, _("enabled \n"));
\r
4790 fprintf(stdout, _("disabled \n"));
\r
4791 #endif /* DEBUG */
\r
4793 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
\r
4794 CurrentGetBitmap->size+=MessageBuffer[count++];
\r
4796 fprintf(stdout, _("Bitmap size=%i\n"),CurrentGetBitmap->size);
\r
4797 #endif /* DEBUG */
\r
4800 CurrentGetBitmap->width=MessageBuffer[count++];
\r
4801 CurrentGetBitmap->height=MessageBuffer[count++];
\r
4803 tmp=GSM_GetBitmapSize(CurrentGetBitmap);
\r
4804 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
\r
4805 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
\r
4806 CurrentGetBitmapError=GE_NONE;
\r
4809 fprintf(stdout, _("Message: Caller group datas received, but group number does not match (%i is not %i)\n"),MessageBuffer[4],CurrentGetBitmap->number);
\r
4814 fprintf(stdout, _("Message: Caller group data received but not requested!\n"));
\r
4819 /* Get group data error */
\r
4822 CurrentGetBitmapError=GE_UNKNOWN;
\r
4824 fprintf(stdout, _("Message: Error attempting to get caller group data.\n"));
\r
4828 /* Set group data OK */
\r
4831 CurrentSetBitmapError=GE_NONE;
\r
4833 fprintf(stdout, _("Message: Caller group data set correctly.\n"));
\r
4837 /* Set group data error */
\r
4840 CurrentSetBitmapError=GE_UNKNOWN;
\r
4842 fprintf(stdout, _("Message: Error attempting to set caller group data\n"));
\r
4849 fprintf(stdout, _("Message: Unknown message of type 0x03\n"));
\r
4850 #endif /* DEBUG */
\r
4851 AppendLogText("Unknown msg\n",false);
\r
4853 break; /* Visual C Don't like empty cases */
\r
4857 void N6110_Dispatch0x05Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
4859 int tmp, count, length;
\r
4866 switch (MessageBuffer[3]) {
\r
4868 /* Startup Logo */
\r
4872 fprintf(stdout, _("Message: Startup Logo, welcome note and dealer welcome note received.\n"));
\r
4875 if (CurrentGetBitmap!=NULL) {
\r
4877 issupported=false;
\r
4881 for (tmp=0;tmp<MessageBuffer[4];tmp++){
\r
4882 switch (MessageBuffer[count++]) {
\r
4884 if (CurrentGetBitmap->type==GSM_StartupLogo) {
\r
4885 CurrentGetBitmap->height=MessageBuffer[count++];
\r
4886 CurrentGetBitmap->width=MessageBuffer[count++];
\r
4887 CurrentGetBitmap->size=GSM_GetBitmapSize(CurrentGetBitmap);
\r
4888 length=CurrentGetBitmap->size;
\r
4889 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,length);
\r
4892 length=MessageBuffer[count++];
\r
4893 length=length*MessageBuffer[count++]/8;
\r
4897 fprintf(stdout, _("Startup logo supported - "));
\r
4898 if (length!=0) { fprintf(stdout, _("currently set\n")); }
\r
4899 else { fprintf(stdout, _("currently empty\n")); }
\r
4901 if (CurrentGetBitmap->type==GSM_StartupLogo) issupported=true;
\r
4904 length=MessageBuffer[count];
\r
4905 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) {
\r
4906 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
\r
4907 CurrentGetBitmap->text[length]=0;
\r
4910 fprintf(stdout, _("Startup Text supported - "));
\r
4913 fprintf(stdout, _("currently set to \""));
\r
4914 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
\r
4915 fprintf(stdout, _("\"\n"));
\r
4917 fprintf(stdout, _("currently empty\n"));
\r
4921 if (CurrentGetBitmap->type==GSM_WelcomeNoteText) issupported=true;
\r
4924 length=MessageBuffer[count];
\r
4925 if (CurrentGetBitmap->type==GSM_DealerNoteText) {
\r
4926 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,length);
\r
4927 CurrentGetBitmap->text[length]=0;
\r
4930 fprintf(stdout, _("Dealer Welcome supported - "));
\r
4933 fprintf(stdout, _("currently set to \""));
\r
4934 for (i=0;i<length;i++) fprintf(stdout, _("%c"),MessageBuffer[count+1+i]);
\r
4935 fprintf(stdout, _("\"\n"));
\r
4937 fprintf(stdout, _("currently empty\n"));
\r
4941 if (CurrentGetBitmap->type==GSM_DealerNoteText) issupported=true;
\r
4945 if (issupported) CurrentGetBitmapError=GE_NONE;
\r
4946 else CurrentGetBitmapError=GE_NOTSUPPORTED;
\r
4949 fprintf(stdout, _("Message: Startup logo received but not requested!\n"));
\r
4954 /* Set startup OK */
\r
4957 CurrentSetBitmapError=GE_NONE;
\r
4959 fprintf(stdout, _("Message: Startup logo, welcome note or dealer welcome note correctly set.\n"));
\r
4963 /* Set Operator Logo OK */
\r
4967 fprintf(stdout, _("Message: Operator logo correctly set.\n"));
\r
4970 CurrentSetBitmapError=GE_NONE;
\r
4973 /* Set Operator Logo Error */
\r
4977 fprintf(stdout, _("Message: Error setting operator logo!\n"));
\r
4980 CurrentSetBitmapError=GE_UNKNOWN;
\r
4983 /* Operator Logo */
\r
4984 /* [location],[netcode x 3],[lenhi],[lenlo],[bitmap] */
\r
4987 if (CurrentGetBitmap!=NULL) {
\r
4989 count=5; /* Location ignored. */
\r
4991 DecodeNetworkCode(MessageBuffer+count, CurrentGetBitmap->netcode);
4995 fprintf(stdout, _("Message: Operator Logo for %s (%s) network received.\n"),
\r
4996 CurrentGetBitmap->netcode,
\r
4997 GSM_GetNetworkName(CurrentGetBitmap->netcode));
\r
5000 CurrentGetBitmap->size=MessageBuffer[count++]<<8;
\r
5001 CurrentGetBitmap->size+=MessageBuffer[count++];
\r
5003 CurrentGetBitmap->width=MessageBuffer[count++];
\r
5004 CurrentGetBitmap->height=MessageBuffer[count++];
\r
5006 tmp=GSM_GetBitmapSize(CurrentGetBitmap);
\r
5007 if (CurrentGetBitmap->size>tmp) CurrentGetBitmap->size=tmp;
\r
5008 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count,CurrentGetBitmap->size);
\r
5009 CurrentGetBitmapError=GE_NONE;
\r
5012 fprintf(stdout, _("Message: Operator logo received but not requested!\n"));
\r
5018 /* Get op logo error */
\r
5022 fprintf(stdout, _("Message: Error getting operator logo!\n"));
\r
5024 CurrentGetBitmapError=GE_UNKNOWN;
\r
5030 fprintf(stdout, _("Message: Unknown message of type 0x05\n"));
\r
5031 #endif /* DEBUG */
\r
5032 AppendLogText("Unknown msg\n",false);
\r
5038 void N6110_Dispatch0x06Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
5041 unsigned char output[160];
\r
5047 switch (MessageBuffer[3]) {
\r
5051 /* MessageBuffer[3] = 0x05
\r
5052 MessageBuffer[4] = 0x00
\r
5053 MessageBuffer[5] = 0x0f
\r
5054 MessageBuffer[6] = 0x03
\r
5055 MessageBuffer[7] = length of packed message
\r
5057 This is all I have seen - Gerry Anderson */
\r
5059 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, MessageBuffer+8, output);
\r
5063 fprintf(stdout, _("Message from Network operator: "));
\r
5065 for (i=0; i<tmp; i++)
\r
5066 fprintf(stdout, "%c", DecodeWithDefaultAlphabet(output[i]));
\r
5068 fprintf(stdout, "\n");
\r
5070 #endif /* DEBUG */
\r
5077 fprintf(stdout, _("Message: Unknown message of type 0x06\n"));
\r
5078 #endif /* DEBUG */
\r
5079 AppendLogText("Unknown msg\n",false);
\r
5085 void N6110_Dispatch0x09Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
5087 switch (MessageBuffer[3]) {
\r
5091 fprintf(stdout, _("Message: SIM card login\n"));
\r
5097 fprintf(stdout, _("Message: SIM card logout\n"));
\r
5103 fprintf(stdout, _("Unknown message of type 0x09.\n"));
\r
5105 AppendLogText("Unknown msg\n",false);
\r
5110 void N6110_Dispatch0x13Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
5112 switch(MessageBuffer[3]) {
\r
5117 fprintf(stdout, _("Message: Calendar Alarm active\n"));
\r
5118 fprintf(stdout, _(" Item number: %d\n"), MessageBuffer[4]);
\r
5119 #endif /* DEBUG */
\r
5123 fprintf(stdout, _("Unknown message of type 0x13.\n"));
\r
5125 AppendLogText("Unknown msg\n",false);
\r
5130 void N6110_Dispatch0x40Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
5134 switch(MessageBuffer[2]) {
\r
5139 fprintf(stdout, _("Message: ACK for simlock opening part 1\n"));
\r
5140 #endif /* DEBUG */
\r
5142 CurrentMagicError=GE_NONE;
\r
5148 fprintf(stdout, _("Message: Answer for call commands.\n"));
\r
5151 CurrentDialVoiceError=GE_NONE;
\r
5157 fprintf(stdout, _("Message: ACK for simlock opening part 2\n"));
\r
5158 #endif /* DEBUG */
\r
5160 CurrentMagicError=GE_NONE;
\r
5166 fprintf(stdout, _("Message: ACK for simlock closing\n"));
\r
5167 #endif /* DEBUG */
\r
5169 CurrentMagicError=GE_NONE;
\r
5174 switch (MessageBuffer[5]) {
\r
5177 fprintf(stdout,_("Message: EEPROM contest received\n"));
\r
5180 if (MessageBuffer[8]!=0x00) {
\r
5181 for (i=9;i<MessageLength;i++) {
\r
5182 fprintf(stdout,_("%c"), MessageBuffer[i]);
\r
5185 CurrentMagicError=GE_NONE;
\r
5192 fprintf(stdout, _("Unknown message of type 0x40.\n"));
\r
5193 #endif /* DEBUG */
\r
5194 AppendLogText("Unknown msg\n",false);
\r
5199 N6110_DisplayTestsInfo(MessageBuffer);
\r
5205 fprintf(stdout, _("Unknown message of type 0x40.\n"));
\r
5206 #endif /* DEBUG */
\r
5207 AppendLogText("Unknown msg\n",false);
\r
5208 break; /* Visual C Don't like empty cases */
\r
5212 void N6110_Dispatch0x47Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
5216 switch(MessageBuffer[3]) {
\r
5222 if (MessageBuffer[5]!=0) {
\r
5223 strcpy(CurrentGetBitmap->Sender,GSM_UnpackSemiOctetNumber(MessageBuffer+5,true));
\r
5225 while (MessageBuffer[count]!=0) {
\r
5231 strcpy(CurrentGetBitmap->Sender,"\0");
\r
5236 memcpy(CurrentGetBitmap->text,MessageBuffer+count+1,MessageBuffer[count]);
\r
5237 CurrentGetBitmap->text[MessageBuffer[count]]=0;
\r
5239 if (MessageBuffer[count]!=0)
\r
5240 count+=MessageBuffer[count];
\r
5245 fprintf(stdout,_("Picture Image received, text \"%s\", sender %s\n"),CurrentGetBitmap->text,CurrentGetBitmap->Sender);
\r
5248 CurrentGetBitmap->width=MessageBuffer[count+1];
\r
5249 CurrentGetBitmap->height=MessageBuffer[count+2];
\r
5250 CurrentGetBitmap->size=GSM_GetBitmapSize(CurrentGetBitmap);
\r
5252 memcpy(CurrentGetBitmap->bitmap,MessageBuffer+count+4,CurrentGetBitmap->size);
\r
5254 CurrentGetBitmapError=GE_NONE;
\r
5260 fprintf(stdout,_("Getting or setting Picture Image - OK\n"));
\r
5262 CurrentSetBitmapError=GE_NONE;
\r
5263 CurrentGetBitmapError=GE_NONE;
\r
5269 fprintf(stdout,_("Setting Picture Image - invalid location or other error\n"));
\r
5271 CurrentSetBitmapError=GE_UNKNOWN;
\r
5277 fprintf(stdout,_("Getting Picture Image - invalid location or other error\n"));
\r
5279 CurrentGetBitmapError=GE_UNKNOWN;
\r
5285 fprintf(stdout, _("Unknown message of type 0x47.\n"));
\r
5286 #endif /* DEBUG */
\r
5287 AppendLogText("Unknown msg\n",false);
\r
5288 break; /* Visual C Don't like empty cases */
\r
5292 void N6110_DispatchACKMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
5295 sprintf(buffer,"Received ACK %02x %02x\n",MessageBuffer[0],MessageBuffer[1]);
\r
5296 AppendLog(buffer,strlen(buffer),false);
\r
5299 fprintf(stdout, _("[Received Ack of type %02x, seq: %2x]\n"), MessageBuffer[0],
\r
5300 MessageBuffer[1]);
\r
5301 #endif /* DEBUG */
\r
5303 CurrentLinkOK = true;
\r
5306 void N6110_Dispatch0xD0Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
5309 fprintf(stdout, _("Message: The phone is powered on - seq 1.\n"));
\r
5310 #endif /* DEBUG */
\r
5314 /* This function is used for parsing the RLP frame into fields. */
\r
5315 void N6110_RX_HandleRLPMessage(u8 *MessageBuffer)
\r
5318 RLP_F96Frame frame;
\r
5322 /* We do not need RLP frame parsing to be done when we do not have callback
\r
5324 if (CurrentRLP_RXCallback == NULL)
\r
5327 /* Anybody know the official meaning of the first two bytes?
\r
5328 Nokia 6150 sends junk frames starting D9 01, and real frames starting
\r
5329 D9 00. We'd drop the junk frames anyway because the FCS is bad, but
\r
5330 it's tidier to do it here. We still need to call the callback function
\r
5331 to give it a chance to handle timeouts and/or transmit a frame */
\r
5332 if (MessageBuffer[0] == 0xd9 && MessageBuffer[1] == 0x01)
\r
5335 /* Nokia uses 240 bit frame size of RLP frames as per GSM 04.22
\r
5336 specification, so Header consists of 16 bits (2 bytes). See section 4.1
\r
5337 of the specification. */
\r
5339 frame.Header[0] = MessageBuffer[2];
\r
5340 frame.Header[1] = MessageBuffer[3];
\r
5342 /* Next 200 bits (25 bytes) contain the Information. We store the
\r
5343 information in the Data array. */
\r
5345 for (count = 0; count < 25; count ++)
\r
5346 frame.Data[count] = MessageBuffer[4 + count];
\r
5348 /* The last 24 bits (3 bytes) contain FCS. */
\r
5350 frame.FCS[0] = MessageBuffer[29];
\r
5351 frame.FCS[1] = MessageBuffer[30];
\r
5352 frame.FCS[2] = MessageBuffer[31];
\r
5354 /* Here we pass the frame down in the input stream. */
\r
5355 CurrentRLP_RXCallback(valid ? &frame : NULL);
\r
5358 void N6110_Dispatch0xF4Message(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
5361 fprintf(stdout, _("Message: The phone is powered on - seq 2.\n"));
\r
5362 #endif /* DEBUG */
\r
5366 void N6110_ReplyIncomingSMS(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
5368 GSM_SMSMessage NullSMS;
\r
5370 switch (MessageBuffer[6]) {
\r
5372 case 0x00: NullSMS.Type = GST_SMS; NullSMS.folder = GST_INBOX; break;
\r
5373 case 0x01: NullSMS.Type = GST_DR; NullSMS.folder = GST_INBOX; break;
\r
5375 /* Is it possible ? */
\r
5376 case 0x02: NullSMS.Type = GST_SMS; NullSMS.folder = GST_OUTBOX; break;
\r
5377 default: NullSMS.Type = GST_UN; break;
\r
5381 if (NullSMS.Type == GST_DR)
\r
5382 fprintf(stdout, _("Message: SMS Message (Report) Received\n"));
\r
5384 fprintf(stdout, _("Message: SMS Message Received\n"));
\r
5385 #endif /* DEBUG */
\r
5387 GSM_DecodeNokiaSMSFrame(&NullSMS, MessageBuffer+7, MessageLength-7);
\r
5390 fprintf(stdout, _("\n"));
\r
5391 #endif /* DEBUG */
\r
5394 void N6110_DispatchMessage(u16 MessageLength, u8 *MessageBuffer, u8 MessageType) {
\r
5398 /* Switch on the basis of the message type byte */
\r
5399 switch (MessageType) {
\r
5401 /* Call information */
\r
5404 N6110_Dispatch0x01Message(MessageLength, MessageBuffer, MessageType);
\r
5407 /* SMS handling */
\r
5409 switch (MessageBuffer[3]) {
\r
5411 case 0x03:N6110_ReplySendSMSMessage(MessageLength,MessageBuffer,MessageType);break;
\r
5412 case 0x10:N6110_ReplyIncomingSMS(MessageLength,MessageBuffer,MessageType);break;
\r
5413 case 0x21:N6110_ReplySetCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
\r
5414 case 0x23:N6110_ReplyReadCellBroadcast(MessageLength, MessageBuffer, MessageType);break;
\r
5415 case 0x31:N6110_ReplySetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
\r
5417 case 0x35:N6110_ReplyGetSMSCenter(MessageLength,MessageBuffer,MessageType);break;
\r
5418 default :unknown=true;break;
\r
5422 /* Phonebook handling */
\r
5424 switch (MessageBuffer[3]) {
\r
5426 case 0x03:N6110_ReplyGetMemoryLocation(MessageLength,MessageBuffer,MessageType);break;
\r
5428 case 0x06:N6110_ReplyWritePhonebookLocation(MessageLength,MessageBuffer,MessageType);break;
\r
5430 case 0x09:N6110_ReplyGetMemoryStatus(MessageLength,MessageBuffer,MessageType);break;
\r
5432 case 0x18:N6110_ReplyGetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
\r
5434 case 0x1b:N6110_ReplySetSpeedDial(MessageLength,MessageBuffer,MessageType);break;
\r
5435 default :N6110_Dispatch0x03Message(MessageLength,MessageBuffer,MessageType);break;
\r
5439 /* Phone status */
\r
5441 switch (MessageBuffer[3]) {
\r
5442 case 0x02:N6110_ReplyRFBatteryLevel(MessageLength,MessageBuffer,MessageType);break;
\r
5443 default :unknown=true;break;
\r
5447 /* Startup Logo, Operator Logo and Profiles. */
\r
5449 switch (MessageBuffer[3]) {
\r
5450 case 0x11:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
\r
5451 case 0x14:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
\r
5452 case 0x1b:N6110_ReplyGetProfile (MessageLength,MessageBuffer,MessageType);break;
\r
5453 case 0x1d:N6110_ReplySetProfile (MessageLength,MessageBuffer,MessageType);break;
\r
5454 case 0x37:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
\r
5455 case 0x38:N6110_ReplySetRingtone (MessageLength,MessageBuffer,MessageType);break;
\r
5456 default :N6110_Dispatch0x05Message(MessageLength,MessageBuffer,MessageType);break;
\r
5460 /* Network Operator Message to handset -> Gerry Anderson & prepaid info */
5463 switch (MessageBuffer[3]) {
\r
5465 case 0x03:N6110_ReplyCallDivert (MessageLength,MessageBuffer,MessageType);break;
\r
5466 default :N6110_Dispatch0x06Message(MessageLength,MessageBuffer,MessageType);break;
\r
5470 /* Security code requests */
\r
5472 switch (MessageBuffer[3]) {
\r
5473 case 0x08:N6110_ReplyGetSecurityCodeStatus(MessageLength,MessageBuffer,MessageType);break;
\r
5474 case 0x0b:N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
\r
5475 default :N6110_ReplyEnterSecurityCode (MessageLength,MessageBuffer,MessageType);break;
\r
5482 N6110_Dispatch0x09Message(MessageLength, MessageBuffer, MessageType);
\r
5485 /* Network info */
\r
5487 switch (MessageBuffer[3]) {
\r
5488 case 0x71:N6110_ReplyGetNetworkInfo(MessageLength,MessageBuffer,MessageType);break;
\r
5489 default :unknown=true;break;
\r
5493 /* Simulating key pressing */
\r
5495 switch (MessageBuffer[3]) {
\r
5496 case 0x43:N6110_ReplyPressKey(MessageLength,MessageBuffer,MessageType);break;
\r
5497 default :unknown=true;break;
\r
5503 switch (MessageBuffer[3]) {
\r
5504 case 0x50:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
\r
5505 case 0x52:N6110_ReplyGetDisplayStatus(MessageLength,MessageBuffer,MessageType);break;
\r
5506 case 0x54:N6110_ReplyDisplayOutput (MessageLength,MessageBuffer,MessageType);break;
\r
5507 default :unknown=true;break;
\r
5511 /* Phone Clock and Alarm */
\r
5513 switch (MessageBuffer[3]) {
\r
5514 case 0x61:N6110_ReplySetDateTime(MessageLength,MessageBuffer,MessageType);break;
\r
5515 case 0x63:N6110_ReplyGetDateTime(MessageLength,MessageBuffer,MessageType);break;
\r
5516 case 0x6c:N6110_ReplySetAlarm (MessageLength,MessageBuffer,MessageType);break;
\r
5517 case 0x6e:N6110_ReplyGetAlarm (MessageLength,MessageBuffer,MessageType);break;
\r
5518 default :unknown=true;break;
\r
5522 /* Calendar notes handling */
\r
5524 switch (MessageBuffer[3]) {
\r
5525 case 0x65:N6110_ReplyWriteCalendarNote (MessageLength,MessageBuffer,MessageType);break;
\r
5526 case 0x67:N6110_ReplyGetCalendarNote (MessageLength,MessageBuffer,MessageType);break;
\r
5527 case 0x69:N6110_ReplyDeleteCalendarNote(MessageLength,MessageBuffer,MessageType);break;
\r
5528 default :N6110_Dispatch0x13Message (MessageLength,MessageBuffer,MessageType);break;
\r
5532 /* SMS Messages */
\r
5534 switch (MessageBuffer[3]) {
\r
5536 case 0x06:N6110_ReplySaveSMSMessage (MessageLength,MessageBuffer,MessageType);break;
\r
5538 case 0x09:N6110_ReplyGetSMSMessage (MessageLength,MessageBuffer,MessageType);break;
\r
5539 case 0x0b:N6110_ReplyDeleteSMSMessage(MessageLength,MessageBuffer,MessageType);break;
\r
5541 case 0x38:N6110_ReplyGetSMSStatus (MessageLength,MessageBuffer,MessageType);break;
\r
5542 default :unknown=true;break;
\r
5548 switch (MessageBuffer[3]) {
\r
5550 case 0x02:N7110_ReplyEnableWAPCommands(MessageLength,MessageBuffer,MessageType);break;
\r
5552 case 0x08:N7110_ReplyGetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5554 case 0x0b:N7110_ReplySetWAPBookmark (MessageLength,MessageBuffer,MessageType);break;
5557 case 0x1c:N7110_ReplyGetWAPSettings (MessageLength,MessageBuffer,MessageType);break;
5558 default :unknown=true;break;
\r
5562 /* Internal phone functions? */
\r
5564 switch (MessageBuffer[2]) {
\r
5565 case 0x64:N6110_ReplyEnableExtendedCommands (MessageLength,MessageBuffer,MessageType);break;
\r
5566 case 0x65:N6110_ReplyResetPhoneSettings (MessageLength,MessageBuffer,MessageType);break;
\r
5567 case 0x66:N6110_ReplyIMEI (MessageLength,MessageBuffer,MessageType);break;
\r
5568 case 0x6a:N6110_ReplyGetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
\r
5569 case 0x6b:N6110_ReplySetProductProfileSetting(MessageLength,MessageBuffer,MessageType);break;
\r
5570 case 0x6e:N6110_ReplyGetSecurityCode (MessageLength,MessageBuffer,MessageType);break;
\r
5571 case 0x7e:N6110_ReplyNetmonitor (MessageLength,MessageBuffer,MessageType);break;
\r
5572 case 0x8a:N6110_ReplySimlockInfo (MessageLength,MessageBuffer,MessageType);break;
\r
5573 case 0x8b:N6110_ReplySetOperatorName (MessageLength,MessageBuffer,MessageType);break;
\r
5574 case 0x8c:N6110_ReplyGetOperatorName (MessageLength,MessageBuffer,MessageType);break;
\r
5575 case 0x8f:N6110_ReplyPlayTone (MessageLength,MessageBuffer,MessageType);break;
\r
5576 case 0x9e:N6110_ReplyGetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
\r
5577 case 0xa0:N6110_ReplySetBinRingtone (MessageLength,MessageBuffer,MessageType);break;
\r
5578 case 0xc8:N6110_ReplyHW (MessageLength,MessageBuffer,MessageType);break;
\r
5579 default :N6110_Dispatch0x40Message (MessageLength,MessageBuffer,MessageType);break;
\r
5583 /* Picture Images */
\r
5586 N6110_Dispatch0x47Message(MessageLength, MessageBuffer, MessageType);
\r
5589 /* Mobile phone identification */
\r
5592 N6110_ReplyGetAuthentication(MessageLength, MessageBuffer, MessageType);
\r
5595 /***** Acknowlegment of our frames. *****/
\r
5596 case FBUS_FRTYPE_ACK:
\r
5598 N6110_DispatchACKMessage(MessageLength, MessageBuffer, MessageType);
\r
5601 /***** Power on message. *****/
\r
5604 N6110_Dispatch0xD0Message(MessageLength, MessageBuffer, MessageType);
\r
5609 N6110_ReplyID(MessageLength, MessageBuffer, MessageType);
\r
5612 /***** RLP frame received. *****/
\r
5615 N6110_RX_HandleRLPMessage(MessageBuffer);
\r
5618 /***** Power on message. *****/
\r
5621 N6110_Dispatch0xF4Message(MessageLength, MessageBuffer, MessageType);
\r
5624 /***** Unknown message *****/
\r
5625 /* If you think that you know the exact meaning of other messages - please
\r
5630 fprintf(stdout, _("Message: Unknown message type.\n"));
\r
5631 #endif /* DEBUG */
\r
5632 AppendLogText("Unknown msg type\n",false);
\r
5641 fprintf(stdout, _("Unknown message of type %02x.\n"),MessageType);
\r
5643 AppendLogText("Unknown msg\n",false);
\r