7 A Linux/Unix toolset and driver for Nokia mobile phones.
9 Copyright (C) 2000 Hugh Blemings & Pavel JanÃk ml.
10 Copytight (C) 2000 Chris Kemp
12 Released under the terms of the GNU GPL, see file COPYING for more details.
14 This file provides functions specific to the 7110 series.
15 See README for more details on supported mobile phones.
17 The various routines are called P7110_(whatever).
20 Revision 1.1.1.5 2002/04/03 00:08:10 short
21 Found in "gnokii-working" directory, some November-patches version
23 Revision 1.15 2001/11/08 16:47:48 pkot
24 Start fiddling with 7110 and SMS
26 Revision 1.14 2001/09/09 21:45:49 machek
27 Cleanups from Ladislav Michl <ladis@psi.cz>:
29 *) do *not* internationalize debug messages
31 *) some whitespace fixes, do not use //
33 *) break is unneccessary after return
35 Revision 1.13 2001/08/16 23:59:32 pkot
36 Fixed (hopefully) timezone mismash (Sheldon Hearn)
38 Revision 1.12 2001/08/09 12:34:34 pkot
39 3330 and 6250 support - I have no idea if it does work (mygnokii)
41 Revision 1.11 2001/07/05 10:54:53 pkot
42 Solaris 2.7 fixes - should be harmless for other OSes (Michael Wiedmann)
44 Revision 1.10 2001/06/27 23:52:49 pkot
45 7110/6210 updates (Marian Jancar)
47 Revision 1.9 2001/06/10 23:49:49 pkot
48 Small fixes to hide compilation warnings and allow gnokii.c to compile
50 Revision 1.8 2001/05/24 20:47:30 chris
51 More updating of 7110 code and some of xgnokii_lowlevel changed over.
53 Revision 1.7 2001/05/07 16:24:04 pkot
54 DLR-3P temporary fix. How should I do it better?
56 Revision 1.6 2001/03/23 13:40:24 chris
57 Pavel's patch and a few fixes.
59 Revision 1.5 2001/03/22 16:17:06 chris
60 Tidy-ups and fixed gnokii/Makefile and gnokii/ChangeLog which I somehow corrupted.
62 Revision 1.4 2001/03/21 23:36:06 chris
63 Added the statemachine
64 This will break gnokii --identify and --monitor except for 6210/7110
66 Revision 1.3 2001/03/13 01:24:03 pkot
67 Code cleanup - no warnings during compilation
69 Revision 1.2 2001/03/13 01:23:18 pkot
70 Windows updates (Manfred Jonsson)
72 Revision 1.1 2001/02/21 19:57:07 chris
73 More fiddling with the directory layout
75 Revision 1.1 2001/02/16 14:29:53 chris
76 Restructure of common/. Fixed a problem in fbus-phonet.c
77 Lots of dprintfs for Marcin
78 Any size xpm can now be loaded (eg for 7110 startup logos)
79 nk7110 code detects 7110/6210 and alters startup logo size to suit
80 Moved Marcin's extended phonebook code into gnokii.c
82 Revision 1.7 2001/02/06 21:15:35 chris
83 Preliminary irda support for 7110 etc. Not well tested!
85 Revision 1.6 2001/02/03 23:56:15 chris
86 Start of work on irda support (now we just need fbus-irda.c!)
87 Proper unicode support in 7110 code (from pkot)
89 Revision 1.5 2001/02/01 15:17:31 pkot
90 Fixed --identify and added Manfred's manufacturer patch
92 Revision 1.4 2001/01/29 17:14:42 chris
93 dprintf now in misc.h (and fiddling with 7110 code)
95 Revision 1.3 2001/01/23 15:32:41 chris
96 Pavel's 'break' and 'static' corrections.
97 Work on logos for 7110.
99 Revision 1.2 2001/01/17 02:54:54 chris
100 More 7110 work. Use with care! (eg it is not possible to delete phonebook entries)
101 I can now edit my phonebook in xgnokii but it is 'work in progress'.
103 Revision 1.1 2001/01/14 22:46:59 chris
104 Preliminary 7110 support (dlr9 only) and the beginnings of a new structure
113 #define __phones_nk7110_c /* Turn on prototypes in phones/nk7110.h */
115 #include "gsm-common.h"
116 #include "phones/generic.h"
117 #include "phones/nk7110.h"
118 #include "links/fbus.h"
119 #include "links/fbus-phonet.h"
120 #include "phones/nokia.h"
121 #include "gsm-encoding.h"
124 #define snprintf _snprintf
129 static GSM_IncomingFunctionType P7110_IncomingFunctions[] = {
130 { P7110_MSG_FOLDER, P7110_IncomingFolder },
131 { P7110_MSG_SMS, P7110_IncomingSMS },
132 { P7110_MSG_PHONEBOOK, P7110_IncomingPhonebook },
133 { P7110_MSG_NETSTATUS, P7110_IncomingNetwork },
134 { P7110_MSG_CALENDAR, P7110_IncomingCalendar },
135 { P7110_MSG_BATTERY, P7110_IncomingBattLevel },
136 { P7110_MSG_CLOCK, P7110_IncomingClock },
137 { P7110_MSG_IDENTITY, P7110_Incoming0x1b },
138 { P7110_MSG_STLOGO, P7110_IncomingStartup },
142 GSM_Phone phone_nokia_7110 = {
143 P7110_IncomingFunctions,
144 PGEN_IncomingDefault,
145 /* Mobile phone information */
147 "7110|6210|6250", /* Supported models */
148 7, /* Max RF Level */
149 0, /* Min RF Level */
150 GRF_Percentage, /* RF level units */
151 7, /* Max Battery Level */
152 0, /* Min Battery Level */
153 GBU_Percentage, /* Battery level units */
154 GDT_DateTime, /* Have date/time support */
155 GDT_TimeOnly, /* Alarm supports time only */
156 1, /* Alarms available - FIXME */
157 60, 96, /* Startup logo size - 7110 is fixed at init*/
158 21, 78, /* Op logo size */
159 14, 72 /* Caller logo size */
164 /* FIXME - a little macro would help here... */
166 static GSM_Error P7110_Functions(GSM_Operation op, GSM_Data *data, GSM_Statemachine *state)
170 return P7110_Initialise(state);
172 return P7110_GetModel(data, state);
173 case GOP_GetRevision:
174 return P7110_GetRevision(data, state);
176 return P7110_GetIMEI(data, state);
178 return P7110_Identify(data, state);
179 case GOP_GetBatteryLevel:
180 return P7110_GetBatteryLevel(data, state);
182 return P7110_GetRFLevel(data, state);
183 case GOP_GetMemoryStatus:
184 return P7110_GetMemoryStatus(data, state);
186 return P7110_GetBitmap(data, state);
188 return P7110_SetBitmap(data, state);
189 case GOP_ReadPhonebook:
190 return P7110_ReadPhonebook(data, state);
191 case GOP_WritePhonebook:
192 return P7110_WritePhonebookLocation(data, state);
193 case GOP_GetNetworkInfo:
194 return P7110_GetNetworkInfo(data, state);
195 case GOP_GetSpeedDial:
196 return P7110_GetSpeedDial(data, state);
197 case GOP_GetSMSCenter:
198 return P7110_GetSMSCenter(data, state);
199 case GOP_GetDateTime:
200 return P7110_GetClock(P7110_SUBCLO_GET_DATE, data, state);
202 return P7110_GetClock(P7110_SUBCLO_GET_ALARM, data, state);
203 case GOP_GetCalendarNote:
204 return P7110_GetCalendarNote(data, state);
206 return P7110_GetSMS(data, state);
207 /* I'm not suer yet if folder functions will be shared or local
208 case GOP_GetSMSFolders:
209 return P7110_GetSMSFolders(data, state);
210 case GOP_GetSMSFolderStatus:
211 return P7110_GetSMSFolderStatus(data, state);*/
213 return GE_NOTIMPLEMENTED;
217 /* LinkOK is always true for now... */
218 bool P7110_LinkOK = true;
220 /* Initialise is the only function allowed to 'use' state */
221 static GSM_Error P7110_Initialise(GSM_Statemachine *state)
226 int try = 0, connected = 0;
228 /* Copy in the phone info */
229 memcpy(&(state->Phone), &phone_nokia_7110, sizeof(GSM_Phone));
232 switch (state->Link.ConnectionType) {
234 if (try > 1) return GE_NOTSUPPORTED;
235 err = FBUS_Initialise(&(state->Link), state);
239 if (try > 0) return GE_NOTSUPPORTED;
240 err = PHONET_Initialise(&(state->Link), state);
243 return GE_NOTSUPPORTED;
247 if (err != GE_NONE) {
248 dprintf("Error in link initialisation\n");
253 SM_Initialise(state);
255 /* Now test the link and get the model */
256 GSM_DataClear(&data);
258 if (state->Phone.Functions(GOP_GetModel, &data, state) != GE_NONE) try++;
261 /* Check for 7110 and alter the startup logo size */
262 if (strcmp(model, "NSE-5") == 0) {
263 state->Phone.Info.StartupLogoH = 65;
264 dprintf("7110 detected - startup logo height set to 65\n");
269 static GSM_Error P7110_GetModel(GSM_Data *data, GSM_Statemachine *state)
271 unsigned char req[] = {FBUS_FRAME_HEADER, 0x03, 0x01, 0x32};
273 dprintf("Getting model...\n");
274 if (SM_SendMessage(state, 6, 0x1b, req)!=GE_NONE) return GE_NOTREADY;
275 return SM_Block(state, data, 0x1b);
278 static GSM_Error P7110_GetRevision(GSM_Data *data, GSM_Statemachine *state)
280 unsigned char req[] = {FBUS_FRAME_HEADER, 0x03, 0x01, 0x32};
282 dprintf("Getting revision...\n");
283 if (SM_SendMessage(state, 6, 0x1b, req)!=GE_NONE) return GE_NOTREADY;
284 return SM_Block(state, data, 0x1b);
287 static GSM_Error P7110_GetIMEI(GSM_Data *data, GSM_Statemachine *state)
289 unsigned char req[] = {FBUS_FRAME_HEADER, 0x01};
291 dprintf("Getting imei...\n");
292 if (SM_SendMessage(state, 4, 0x1b, req)!=GE_NONE) return GE_NOTREADY;
293 return SM_Block(state, data, 0x1b);
296 static GSM_Error P7110_GetBatteryLevel(GSM_Data *data, GSM_Statemachine *state)
298 unsigned char req[] = {FBUS_FRAME_HEADER, 0x02};
300 dprintf("Getting battery level...\n");
301 if (SM_SendMessage(state, 4, 0x17, req) != GE_NONE) return GE_NOTREADY;
302 return SM_Block(state, data, 0x17);
305 static GSM_Error P7110_IncomingBattLevel(int messagetype, unsigned char *message, int length, GSM_Data *data)
307 switch (message[3]) {
309 if (data->BatteryLevel) {
310 *(data->BatteryUnits) = GBU_Percentage;
311 *(data->BatteryLevel) = message[5];
312 dprintf("Battery level %f\n",*(data->BatteryLevel));
317 dprintf("Unknown subtype of type 0x17 (%d)\n", message[3]);
323 static GSM_Error P7110_GetRFLevel(GSM_Data *data, GSM_Statemachine *state)
325 unsigned char req[] = {FBUS_FRAME_HEADER, 0x81};
327 dprintf("Getting rf level...\n");
328 if (SM_SendMessage(state, 4, 0x0a, req) != GE_NONE) return GE_NOTREADY;
329 return SM_Block(state, data, 0x0a);
332 static GSM_Error P7110_GetNetworkInfo(GSM_Data *data, GSM_Statemachine *state)
334 unsigned char req[] = {FBUS_FRAME_HEADER, 0x70};
336 dprintf("Getting Network Info...\n");
337 if (SM_SendMessage(state, 4, 0x0a, req) != GE_NONE) return GE_NOTREADY;
338 return SM_Block(state, data, 0x0a);
341 static GSM_Error P7110_IncomingNetwork(int messagetype, unsigned char *message, int length, GSM_Data *data)
343 unsigned char *blockstart;
346 switch (message[3]) {
348 blockstart = message + 6;
349 for (i = 0; i < message[4]; i++) {
350 switch (blockstart[0]) {
351 case 0x01: /* Operator details */
352 /* Network code is stored as 0xBA 0xXC 0xED ("ABC DE"). */
353 if (data->NetworkInfo) {
354 /* Is this correct? */
355 data->NetworkInfo->CellID[0]=blockstart[4];
356 data->NetworkInfo->CellID[1]=blockstart[5];
357 data->NetworkInfo->LAC[0]=blockstart[6];
358 data->NetworkInfo->LAC[1]=blockstart[7];
359 data->NetworkInfo->NetworkCode[0] = '0' + (blockstart[8] & 0x0f);
360 data->NetworkInfo->NetworkCode[1] = '0' + (blockstart[8] >> 4);
361 data->NetworkInfo->NetworkCode[2] = '0' + (blockstart[9] & 0x0f);
362 data->NetworkInfo->NetworkCode[3] = ' ';
363 data->NetworkInfo->NetworkCode[4] = '0' + (blockstart[10] & 0x0f);
364 data->NetworkInfo->NetworkCode[5] = '0' + (blockstart[10] >> 4);
365 data->NetworkInfo->NetworkCode[6] = 0;
368 data->Bitmap->netcode[0] = '0' + (blockstart[8] & 0x0f);
369 data->Bitmap->netcode[1] = '0' + (blockstart[8] >> 4);
370 data->Bitmap->netcode[2] = '0' + (blockstart[9] & 0x0f);
371 data->Bitmap->netcode[3] = ' ';
372 data->Bitmap->netcode[4] = '0' + (blockstart[10] & 0x0f);
373 data->Bitmap->netcode[5] = '0' + (blockstart[10] >> 4);
374 data->Bitmap->netcode[6] = 0;
375 dprintf("Operator %s ",data->Bitmap->netcode);
378 case 0x04: /* Logo */
380 dprintf("Op logo received ok ");
381 data->Bitmap->type = GSM_OperatorLogo;
382 data->Bitmap->size = blockstart[5]; /* Probably + [4]<<8 */
383 data->Bitmap->height = blockstart[3];
384 data->Bitmap->width = blockstart[2];
385 memcpy(data->Bitmap->bitmap, blockstart + 8, data->Bitmap->size);
386 dprintf("Logo (%dx%d) ", data->Bitmap->height, data->Bitmap->width);
390 dprintf("Unknown operator block %d\n", blockstart[0]);
393 blockstart += blockstart[1];
399 *(data->RFUnits) = GRF_Percentage;
400 *(data->RFLevel) = message[4];
401 dprintf("RF level %f\n",*(data->RFLevel));
406 dprintf("Op Logo Set OK\n");
409 dprintf("Unknown subtype of type 0x0a (%d)\n", message[3]);
415 static GSM_Error P7110_GetMemoryStatus(GSM_Data *data, GSM_Statemachine *state)
417 unsigned char req[] = {FBUS_FRAME_HEADER, 0x03, 0x00, 0x00};
419 dprintf("Getting memory status...\n");
420 req[5] = GetMemoryType(data->MemoryStatus->MemoryType);
421 if (SM_SendMessage(state, 6, 0x03, req) != GE_NONE) return GE_NOTREADY;
422 return SM_Block(state, data, 0x03);
425 static GSM_Error P7110_IncomingPhonebook(int messagetype, unsigned char *message, int length, GSM_Data *data)
427 unsigned char *blockstart;
428 unsigned char blocks;
429 unsigned char subblockcount;
432 GSM_SubPhonebookEntry* subEntry = NULL;
434 PGEN_DebugMessage(messagetype, message, length);
436 switch (message[3]) {
437 case 0x04: /* Get status response */
438 if (data->MemoryStatus) {
439 if (message[5] != 0xff) {
440 data->MemoryStatus->Used = (message[16] << 8) + message[17];
441 data->MemoryStatus->Free = ((message[14] << 8) + message[15]) - data->MemoryStatus->Used;
442 dprintf("Memory status - location = %d\n", (message[8] << 8) + message[9]);
445 dprintf("Unknown error getting mem status\n");
446 return GE_NOTIMPLEMENTED;
452 case 0x08: /* Read Memory response */
453 if (data->PhonebookEntry) {
454 data->PhonebookEntry->Empty = true;
455 data->PhonebookEntry->Group = 0;
456 data->PhonebookEntry->Name[0] = '\0';
457 data->PhonebookEntry->Number[0] = '\0';
458 data->PhonebookEntry->SubEntriesCount = 0;
459 data->PhonebookEntry->Date.Year = 0;
460 data->PhonebookEntry->Date.Month = 0;
461 data->PhonebookEntry->Date.Day = 0;
462 data->PhonebookEntry->Date.Hour = 0;
463 data->PhonebookEntry->Date.Minute = 0;
464 data->PhonebookEntry->Date.Second = 0;
466 if (message[6] == 0x0f) { // not found
467 if (message[10] == 0x34 || message[10] == 0x33 || message[10] == 0x30) {
468 dprintf("Invalid caller location\n");
469 return GE_INVALIDPHBOOKLOCATION;
471 dprintf("Unknown error getting phonebook\n");
472 return GE_NOTIMPLEMENTED;
475 dprintf("Received phonebook info\n");
476 blocks = message[17];
477 blockstart = message + 18;
480 for (i = 0; i < blocks; i++) {
481 if (data->PhonebookEntry)
482 subEntry = &data->PhonebookEntry->SubEntries[subblockcount];
483 switch(blockstart[0]) {
484 case P7110_ENTRYTYPE_POINTER: /* Pointer */
485 switch (message[11]) { /* Memory type */
486 case P7110_MEMORY_SPEEDDIALS: /* Speed dial numbers */
487 if ((data != NULL) && (data->SpeedDial != NULL)) {
488 data->SpeedDial->Location = (((unsigned int)blockstart[6]) << 8) + blockstart[7];
489 switch(blockstart[8]) {
491 data->SpeedDial->MemoryType = GMT_ME;
496 data->SpeedDial->MemoryType = GMT_SM;
500 data->SpeedDial->MemoryType = GMT_XX;
505 dprintf("Speed dial pointer: %i in %s\n", data->SpeedDial->Location, str);
509 /* FIXME: is it possible? */
510 dprintf("Wrong memory type(?)\n");
515 case P7110_ENTRYTYPE_NAME: /* Name */
517 DecodeUnicode(data->Bitmap->text, (blockstart + 6), blockstart[5] / 2);
518 dprintf("Name: %s\n", data->Bitmap->text);
519 } else if (data->PhonebookEntry) {
520 DecodeUnicode(data->PhonebookEntry->Name, (blockstart + 6), blockstart[5] / 2);
521 data->PhonebookEntry->Empty = false;
522 dprintf(" Name: %s\n", data->PhonebookEntry->Name);
525 case P7110_ENTRYTYPE_EMAIL:
526 case P7110_ENTRYTYPE_POSTAL:
527 case P7110_ENTRYTYPE_NOTE:
528 if (data->PhonebookEntry) {
529 subEntry->EntryType = blockstart[0];
530 subEntry->NumberType = 0;
531 subEntry->BlockNumber = blockstart[4];
532 DecodeUnicode(subEntry->data.Number, (blockstart + 6), blockstart[5] / 2);
533 dprintf(" Type: %d (%02x)\n", subEntry->EntryType, subEntry->EntryType);
534 dprintf(" Text: %s\n", subEntry->data.Number);
536 data->PhonebookEntry->SubEntriesCount++;
539 case P7110_ENTRYTYPE_NUMBER:
540 if (data->PhonebookEntry) {
541 subEntry->EntryType = blockstart[0];
542 subEntry->NumberType = blockstart[5];
543 subEntry->BlockNumber = blockstart[4];
544 DecodeUnicode(subEntry->data.Number, (blockstart + 10), blockstart[9] / 2);
545 if (!subblockcount) strcpy(data->PhonebookEntry->Number, subEntry->data.Number);
546 dprintf(" Type: %d (%02x)\n", subEntry->NumberType, subEntry->NumberType);
547 dprintf(" Number: %s\n", subEntry->data.Number);
549 data->PhonebookEntry->SubEntriesCount++;
552 case P7110_ENTRYTYPE_RINGTONE: /* Ringtone */
554 data->Bitmap->ringtone = blockstart[5];
555 dprintf("Ringtone no. %d\n", data->Bitmap->ringtone);
558 case P7110_ENTRYTYPE_DATE:
559 if (data->PhonebookEntry) {
560 subEntry->EntryType=blockstart[0];
561 subEntry->NumberType=blockstart[5];
562 subEntry->BlockNumber=blockstart[4];
563 subEntry->data.Date.Year=(blockstart[6] << 8) + blockstart[7];
564 subEntry->data.Date.Month = blockstart[8];
565 subEntry->data.Date.Day = blockstart[9];
566 subEntry->data.Date.Hour = blockstart[10];
567 subEntry->data.Date.Minute = blockstart[11];
568 subEntry->data.Date.Second = blockstart[12];
569 dprintf(" Date: %02u.%02u.%04u\n", subEntry->data.Date.Day,
570 subEntry->data.Date.Month, subEntry->data.Date.Year);
571 dprintf(" Time: %02u:%02u:%02u\n", subEntry->data.Date.Hour,
572 subEntry->data.Date.Minute, subEntry->data.Date.Second);
576 case P7110_ENTRYTYPE_LOGO: /* Caller group logo */
578 data->Bitmap->width = blockstart[5];
579 data->Bitmap->height = blockstart[6];
580 data->Bitmap->size = (data->Bitmap->width * data->Bitmap->height) / 8;
581 memcpy(data->Bitmap->bitmap, blockstart + 10, data->Bitmap->size);
585 case P7110_ENTRYTYPE_LOGOSWITCH:/* Logo on/off */
587 case P7110_ENTRYTYPE_GROUP: /* Caller group number */
588 if (data->PhonebookEntry) {
589 data->PhonebookEntry->Group = blockstart[5] - 1;
590 dprintf(" Group: %d\n", data->PhonebookEntry->Group);
594 dprintf("Unknown phonebook block %02x\n", blockstart[0]);
597 blockstart += blockstart[3];
602 switch (message[6]) {
603 case 0x3d: return GE_PHBOOKWRITEFAILED; break;
604 case 0x3e: return GE_PHBOOKWRITEFAILED; break;
605 default: return GE_NONE; break;
609 dprintf("Unknown subtype of type 0x03 (%d)\n", message[3]);
615 /* Just as an example.... */
616 /* But note that both requests are the same type which isn't very 'proper' */
617 static GSM_Error P7110_Identify(GSM_Data *data, GSM_Statemachine *state)
619 unsigned char req[] = {FBUS_FRAME_HEADER, 0x01};
620 unsigned char req2[] = {FBUS_FRAME_HEADER, 0x03, 0x01, 0x32};
622 dprintf("Identifying...\n");
623 if (SM_SendMessage(state, 4, 0x1b, req) != GE_NONE) return GE_NOTREADY;
624 if (SM_SendMessage(state, 6, 0x1b, req2) != GE_NONE) return GE_NOTREADY;
625 SM_WaitFor(state, data, 0x1b);
626 SM_Block(state, data, 0x1b); /* waits for all requests - returns req2 error */
627 SM_GetError(state, 0x1b);
629 /* Check that we are back at state Initialised */
630 if (SM_Loop(state,0)!=Initialised) return GE_UNKNOWN;
634 static GSM_Error P7110_Incoming0x1b(int messagetype, unsigned char *message, int length, GSM_Data *data)
636 switch (message[3]) {
639 snprintf(data->Imei, GSM_MAX_IMEI_LENGTH, "%s", message + 4);
640 dprintf("Received imei %s\n",data->Imei);
646 snprintf(data->Model, GSM_MAX_MODEL_LENGTH, "%s", message + 22);
647 dprintf("Received model %s\n",data->Model);
649 if (data->Revision) {
650 snprintf(data->Revision, GSM_MAX_REVISION_LENGTH, "%s", message + 7);
651 dprintf("Received revision %s\n",data->Revision);
656 dprintf("Unknown subtype of type 0x1b (%d)\n", message[3]);
663 /* handle messages of type 0x14 (SMS Handling, Folders, Logos.. */
664 static GSM_Error P7110_IncomingFolder(int messagetype, unsigned char *message, int length, GSM_Data *data)
669 switch (message[3]) {
673 data->SMSFolders->number = message[4];
674 dprintf("Message: %d SMS Folders received:\n", data->SMSFolders->number);
676 for (j = 0; j < message[4]; j++) {
677 strcpy(data->SMSFolders->Folder[j].Name, " ");
678 data->SMSFolders->FoldersID[j] = message[i];
679 dprintf("Folder Index: %d", data->SMSFolders->FoldersID[j]);
681 dprintf(" Folder name: ");
683 while ((message[i] != 0x00) & (message[i+1] == 0x00)) {
684 wc = message[i] | (message[i+1] << 8);
685 data->SMSFolders->Folder[j].Name[tmp] = DecodeWithUnicodeAlphabet(wc);
686 dprintf("%c", data->SMSFolders->Folder[j].Name[tmp]);
696 /* getfolderstatus */
698 dprintf("Message: SMS Folder status received: \n" );
699 data->OneSMSFolder->number = (message[5] * 256) + message[5];
700 dprintf("Message: Number of Entries: %i\n" , data->OneSMSFolder->number);
701 dprintf("Message: IDs of Entries : ");
702 for (i=0;i<message[4]*256+message[5];i++) {
703 data->OneSMSFolder->locations[i]=message[6+(i*2)]*256+message[(i*2)+7];
704 dprintf("%d, ", data->OneSMSFolder->locations[i]);
711 for (i = 0; i < length-2; i ++)
712 if (isprint(message[i]))
713 dprintf("[%02x%c]", message[i], message[i]);
715 dprintf("[%02x ]", message[i]);
718 dprintf("Message: Getting SMS %i " , data->SMSMessage->Location);
719 dprintf("in Folder %i\n", data->SMSMessage->Destination);
720 if (message[5] != data->SMSMessage->Destination) {
721 dprintf("Invalid SMS location (Folder)\n");
722 return GE_INVALIDSMSLOCATION;
724 if ((message[6] * 256 + message[7]) != data->SMSMessage->Location) {
725 dprintf("Invalid SMS location (ID)\n");
726 return GE_INVALIDSMSLOCATION;
729 /* Status see nk7110.txt */
730 data->SMSMessage->Status = message[4];
732 if (message[8]==0x01) data->SMSMessage->Type = SMS_Deliver_Report;
734 if (data->SMSMessage->Status == SMS_MO_SENT) offset=5;
736 if (message[9+12] & 0x40) { /* UDH header available */
738 off = (message[9+31+offset] + 1); /* Length of UDH header */
740 dprintf(" UDH header available (length %i)\n",off);
743 DecodeSMSHeader(message, length, data->SMSMessage, 9, offset);
744 DecodeTextSMS(message, length, data->SMSMessage, 9, offset, off);
750 for (i = 0; i < length-2; i ++)
751 if (isprint(message[i]))
752 dprintf("[%02x%c]", message[i], message[i]);
754 dprintf("[%02x ]", message[i]);
756 dprintf("Message: Unknown message of type 14 : %d length: %d\n", message[3], length);
763 static GSM_Error P7110_GetSMS(GSM_Data *data, GSM_Statemachine *state)
765 unsigned char req[] = {FBUS_FRAME_HEADER, 0x07,
771 dprintf("Getting SMS...\n");
772 req[4] = data->SMSMessage->MemoryType;
773 req[6] = data->SMSMessage->Location;
774 if (SM_SendMessage(state, 10, 0x14, req) != GE_NONE) return GE_NOTREADY;
775 return SM_Block(state, data, 0x14);
779 static GSM_Error P7110_GetSMSFolders(GSM_Data *data, GSM_Statemachine *state)
781 unsigned char req[] = {FBUS_FRAME_HEADER, 0x7A, 0x00, 0x00};
783 dprintf("Getting SMS Folders...\n");
784 if (SM_SendMessage(state, 6, 0x14, req) != GE_NONE) return GE_NOTREADY;
785 return SM_Block(state, data, 0x14);
788 static GSM_Error P7110_GetSMSFolderStatus(GSM_Data *data, GSM_Statemachine *state)
791 unsigned char req[] = {FBUS_FRAME_HEADER, 0x6B,
795 req[4] = data->OneSMSFolder->FolderID;
796 dprintf("Getting SMS Folder Status...\n");
797 if (SM_SendMessage(state, 7, 0x14, req) != GE_NONE) return GE_NOTREADY;
798 return SM_Block(state, data, 0x14);
803 static GSM_Error P7110_IncomingSMS(int messagetype, unsigned char *message, int length, GSM_Data *data)
805 GSM_Error e = GE_NONE;
808 if (!data || !data->MessageCenter) return GE_INTERNALERROR;
810 switch (message[3]) {
811 case P7110_SUBSMS_SMSC_RCVD:
812 /* FIXME: Implement all these in gsm-sms.c */
813 data->MessageCenter->No = message[4];
814 data->MessageCenter->Format = message[6];
815 data->MessageCenter->Validity = message[8]; /* due to changes in format */
818 bytes = message[21] - 1;
821 sprintf(data->MessageCenter->Name, "%s", message + 33);
823 if (strlen(data->MessageCenter->Recipient) == 0) {
824 sprintf(data->MessageCenter->Recipient, "(none)");
826 if (strlen(data->MessageCenter->Number) == 0) {
827 sprintf(data->MessageCenter->Number, "(none)");
829 if(strlen(data->MessageCenter->Name) == 0) {
830 sprintf(data->MessageCenter->Name, "(none)");
834 case P7110_SUBSMS_SMS_SENT:
835 case P7110_SUBSMS_SEND_FAIL:
836 case P7110_SUBSMS_SMS_RCVD:
837 case P7110_SUBSMS_CELLBRD_OK:
838 case P7110_SUBSMS_CELLBRD_FAIL:
839 case P7110_SUBSMS_READ_CELLBRD:
840 case P7110_SUBSMS_SMSC_OK:
841 case P7110_SUBSMS_SMSC_FAIL:
842 case P7110_SUBSMS_SMSC_RCVFAIL:
843 dprintf("Subtype 0x%02x of type 0x%02x (SMS handling) not implemented\n", message[3], P7110_MSG_SMS);
844 e = GE_NOTIMPLEMENTED;
847 dprintf("Unknown subtype of type 0x%02x (SMS handling): 0x%02x\n", P7110_MSG_SMS, message[3]);
854 static GSM_Error P7110_IncomingClock(int messagetype, unsigned char *message, int length, GSM_Data *data)
856 GSM_Error e = GE_NONE;
858 if (!data || !data->DateTime) return GE_INTERNALERROR;
859 switch (message[3]) {
860 case P7110_SUBCLO_DATE_RCVD:
861 data->DateTime->Year = (((unsigned int)message[8]) << 8) + message[9];
862 data->DateTime->Month = message[10];
863 data->DateTime->Day = message[11];
864 data->DateTime->Hour = message[12];
865 data->DateTime->Minute = message[13];
866 data->DateTime->Second = message[14];
869 case P7110_SUBCLO_ALARM_RCVD:
871 case P7110_ALARM_ENABLED:
872 data->DateTime->AlarmEnabled = 1;
874 case P7110_ALARM_DISABLED:
875 data->DateTime->AlarmEnabled = 0;
878 data->DateTime->AlarmEnabled = -1;
879 dprintf("Unknown value of alarm enable byte: 0x%02x\n", message[8]);
884 data->DateTime->Hour = message[9];
885 data->DateTime->Minute = message[10];
889 dprintf("Unknown subtype of type 0x%02x (clock handling): 0x%02x\n", P7110_MSG_CLOCK, message[3]);
896 GSM_Error P7110_GetNoteAlarm(int alarmdiff, GSM_DateTime *time, GSM_DateTime *alarm)
901 GSM_Error e = GE_NONE;
903 if (!time || !alarm) return GE_INTERNALERROR;
905 memset(&tm_time, 0, sizeof(tm_time));
906 tm_time.tm_year = time->Year - 1900;
907 tm_time.tm_mon = time->Month - 1;
908 tm_time.tm_mday = time->Day;
909 tm_time.tm_hour = time->Hour;
910 tm_time.tm_min = time->Minute;
913 t_alarm = mktime(&tm_time);
914 t_alarm -= alarmdiff;
917 tm_alarm = localtime(&t_alarm);
919 alarm->Year = tm_alarm->tm_year + 1900;
920 alarm->Month = tm_alarm->tm_mon + 1;
921 alarm->Day = tm_alarm->tm_mday;
922 alarm->Hour = tm_alarm->tm_hour;
923 alarm->Minute = tm_alarm->tm_min;
924 alarm->Second = tm_alarm->tm_sec;
930 GSM_Error P7110_GetNoteTimes(unsigned char *block, GSM_CalendarNote *c)
933 GSM_Error e = GE_NONE;
935 if (!c) return GE_INTERNALERROR;
937 c->Time.Hour = block[0];
938 c->Time.Minute = block[1];
939 c->Recurance = ((((unsigned int)block[4]) << 8) + block[5]) * 60;
940 alarmdiff = (((unsigned int)block[2]) << 8) + block[3];
942 if (alarmdiff != 0xffff) {
943 P7110_GetNoteAlarm(alarmdiff * 60, &(c->Time), &(c->Alarm));
944 c->Alarm.AlarmEnabled = 1;
946 c->Alarm.AlarmEnabled = 0;
952 static GSM_Error P7110_IncomingCalendar(int messagetype, unsigned char *message, int length, GSM_Data *data)
954 GSM_Error e = GE_NONE;
955 unsigned char *block;
958 if (!data || !data->CalendarNote) return GE_INTERNALERROR;
960 year = data->CalendarNote->Time.Year;
961 dprintf("Year: %i\n", data->CalendarNote->Time.Year);
962 switch (message[3]) {
963 case P7110_SUBCAL_NOTE_RCVD:
964 block = message + 12;
966 data->CalendarNote->Location = (((unsigned int)message[4]) << 8) + message[5];
967 data->CalendarNote->Time.Year = (((unsigned int)message[8]) << 8) + message[9];
968 data->CalendarNote->Time.Month = message[10];
969 data->CalendarNote->Time.Day = message[11];
970 data->CalendarNote->Time.Second = 0;
972 dprintf("Year: %i\n", data->CalendarNote->Time.Year);
974 switch (message[6]) {
975 case P7110_NOTE_MEETING:
976 data->CalendarNote->Type = GCN_MEETING;
977 P7110_GetNoteTimes(block, data->CalendarNote);
978 DecodeUnicode(data->CalendarNote->Text, (block + 8), block[6]);
980 case P7110_NOTE_CALL:
981 data->CalendarNote->Type = GCN_CALL;
982 P7110_GetNoteTimes(block, data->CalendarNote);
983 DecodeUnicode(data->CalendarNote->Text, (block + 8), block[6]);
984 DecodeUnicode(data->CalendarNote->Phone, (block + 8 + block[6] * 2), block[7]);
986 case P7110_NOTE_REMINDER:
987 data->CalendarNote->Type = GCN_REMINDER;
988 data->CalendarNote->Recurance = ((((unsigned int)block[0]) << 8) + block[1]) * 60;
989 DecodeUnicode(data->CalendarNote->Text, (block + 4), block[2]);
991 case P7110_NOTE_BIRTHDAY:
993 for (i = 0; i < 10; i++) {
994 dprintf("(%i:0x%02x)", i, block[i]);
998 data->CalendarNote->Type = GCN_BIRTHDAY;
999 data->CalendarNote->Time.Year = year;
1000 data->CalendarNote->Time.Hour = 23;
1001 data->CalendarNote->Time.Minute = 59;
1002 data->CalendarNote->Time.Second = 58;
1004 alarm = ((unsigned int)block[2]) << 24;
1005 alarm += ((unsigned int)block[3]) << 16;
1006 alarm += ((unsigned int)block[4]) << 8;
1009 dprintf("alarm: %i\n", alarm);
1011 if (alarm == 0xffff) {
1012 data->CalendarNote->Alarm.AlarmEnabled = 0;
1014 data->CalendarNote->Alarm.AlarmEnabled = 1;
1017 P7110_GetNoteAlarm(alarm, &(data->CalendarNote->Time), &(data->CalendarNote->Alarm));
1019 data->CalendarNote->Time.Hour = 0;
1020 data->CalendarNote->Time.Minute = 0;
1021 data->CalendarNote->Time.Second = 0;
1022 data->CalendarNote->Time.Year = (((unsigned int)block[6]) << 8) + block[7];
1024 DecodeUnicode(data->CalendarNote->Text, (block + 10), block[9]);
1028 data->CalendarNote->Type = -1;
1034 case P7110_SUBCAL_ADD_MEETING_RESP:
1035 case P7110_SUBCAL_ADD_CALL_RESP:
1036 case P7110_SUBCAL_ADD_BIRTHDAY_RESP:
1037 case P7110_SUBCAL_ADD_REMINDER_RESP:
1038 case P7110_SUBCAL_DEL_NOTE_RESP:
1039 case P7110_SUBCAL_FREEPOS_RCVD:
1040 case P7110_SUBCAL_INFO_RCVD:
1041 dprintf("Subtype 0x%02x of type 0x%02x (calendar handling) not implemented\n", message[3], P7110_MSG_CALENDAR);
1042 e = GE_NOTIMPLEMENTED;
1045 dprintf("Unknown subtype of type 0x%02x (calendar handling): 0x%02x\n", P7110_MSG_CALENDAR, message[3]);
1052 static int GetMemoryType(GSM_MemoryType memory_type)
1056 switch (memory_type) {
1058 result = P7110_MEMORY_MT;
1061 result = P7110_MEMORY_ME;
1064 result = P7110_MEMORY_SM;
1067 result = P7110_MEMORY_FD;
1070 result = P7110_MEMORY_ON;
1073 result = P7110_MEMORY_EN;
1076 result = P7110_MEMORY_DC;
1079 result = P7110_MEMORY_RC;
1082 result = P7110_MEMORY_MC;
1085 result = P7110_MEMORY_XX;
1093 static GSM_Error P7110_DialVoice(char *Number)
1096 /* Doesn't work (yet) */ /* 3 2 1 5 2 30 35 */
1098 // unsigned char req0[100] = { 0x00, 0x01, 0x64, 0x01 };
1100 unsigned char req[] = {FBUS_FRAME_HEADER, 0x01, 0x01, 0x01, 0x01, 0x05, 0x00, 0x01, 0x03, 0x02, 0x91, 0x00, 0x031, 0x32, 0x00};
1101 // unsigned char req[100]={0x00, 0x01, 0x7c, 0x01, 0x31, 0x37, 0x30, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01};
1102 // unsigned char req[100] = {FBUS_FRAME_HEADER, 0x01, 0x00, 0x20, 0x01, 0x46};
1103 // unsigned char req_end[] = {0x05, 0x01, 0x01, 0x05, 0x81, 0x01, 0x00, 0x00, 0x01};
1106 //req[4]=strlen(Number);
1108 //for(i=0; i < strlen(Number) ; i++)
1109 // req[5+i]=Number[i];
1111 //memcpy(req+5+strlen(Number), req_end, 10);
1113 //len=6+strlen(Number);
1118 //PGEN_CommandResponse(&link, req0, &len, 0x40, 0x40, 100);
1122 if (PGEN_CommandResponse(&link, req, &len, 0x01, 0x01, 100)==GE_NONE) {
1123 PGEN_DebugMessage(1, req, len);
1127 // } else return GE_NOTIMPLEMENTED;
1134 return GE_NOTIMPLEMENTED;
1139 static GSM_Error GetCallerBitmap(GSM_Data *data, GSM_Statemachine *state)
1141 unsigned char req[] = {FBUS_FRAME_HEADER, 0x07, 0x01, 0x01, 0x00, 0x01,
1142 0x00, 0x10 , /* memory type */
1143 0x00, 0x00, /* location */
1146 req[11] = data->Bitmap->number + 1;
1147 dprintf("Getting caller(%d) logo...\n",data->Bitmap->number);
1148 if (SM_SendMessage(state, 14, 0x03, req)!=GE_NONE) return GE_NOTREADY;
1149 return SM_Block(state, data, 0x03);
1152 inline unsigned char PackBlock(u8 id, u8 size, u8 no, u8 *buf, u8 *block)
1157 *(block++) = size + 6;
1159 memcpy(block, buf, size);
1165 static GSM_Error SetCallerBitmap(GSM_Data *data, GSM_Statemachine *state)
1167 unsigned char req[500] = {FBUS_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x0c,
1168 0x00, 0x10, /* memory type */
1169 0x00, 0x00, /* location */
1173 unsigned int count = 18;
1175 if ((data->Bitmap->width!=state->Phone.Info.CallerLogoW) ||
1176 (data->Bitmap->height!=state->Phone.Info.CallerLogoH )) {
1177 dprintf("Invalid image size - expecting (%dx%d) got (%dx%d)\n",state->Phone.Info.CallerLogoH, state->Phone.Info.CallerLogoW, data->Bitmap->height, data->Bitmap->width);
1178 return GE_INVALIDIMAGESIZE;
1181 req[13] = data->Bitmap->number + 1;
1182 dprintf("Setting caller(%d) bitmap...\n",data->Bitmap->number);
1185 i = strlen(data->Bitmap->text);
1186 EncodeUnicode((string + 1), data->Bitmap->text, i);
1188 count += PackBlock(0x07, i * 2 + 1, block++, string, req + count);
1190 string[0] = data->Bitmap->ringtone;
1192 count += PackBlock(0x0c, 2, block++, string, req + count);
1194 string[0] = data->Bitmap->number+1;
1196 count += PackBlock(0x1e, 2, block++, string, req + count);
1197 /* Logo on/off - assume on for now */
1200 count += PackBlock(0x1c, 2, block++, string, req + count);
1202 string[0] = data->Bitmap->width;
1203 string[1] = data->Bitmap->height;
1206 string[4] = 0x7e; /* Size */
1207 memcpy(string + 5, data->Bitmap->bitmap, data->Bitmap->size);
1208 count += PackBlock(0x1b, data->Bitmap->size + 5, block++, string, req + count);
1209 req[17] = block - 1;
1211 if (SM_SendMessage(state, count, 0x03, req)!=GE_NONE) return GE_NOTREADY;
1212 return SM_Block(state, data, 0x03);
1215 static GSM_Error GetStartupBitmap(GSM_Data *data, GSM_Statemachine *state)
1217 unsigned char req[] = {FBUS_FRAME_HEADER, 0xee, 0x15};
1219 dprintf("Getting startup logo...\n");
1220 if (SM_SendMessage(state, 5, 0x7a, req)!=GE_NONE) return GE_NOTREADY;
1221 return SM_Block(state, data, 0x7a);
1224 static GSM_Error P7110_IncomingStartup(int messagetype, unsigned char *message, int length, GSM_Data *data)
1226 switch (message[3]) {
1228 dprintf("Startup logo set ok\n");
1233 /* I'm sure there are blocks here but never mind! */
1234 data->Bitmap->type = GSM_StartupLogo;
1235 data->Bitmap->height = message[13];
1236 data->Bitmap->width = message[17];
1237 data->Bitmap->size=((data->Bitmap->height/8)+(data->Bitmap->height%8>0))*data->Bitmap->width; /* Can't see this coded anywhere */
1238 memcpy(data->Bitmap->bitmap, message+22, data->Bitmap->size);
1239 dprintf("Startup logo got ok - height(%d) width(%d)\n", data->Bitmap->height, data->Bitmap->width);
1244 dprintf("Unknown subtype of type 0x7a (%d)\n", message[3]);
1250 static GSM_Error GetOperatorBitmap(GSM_Data *data, GSM_Statemachine *state)
1252 unsigned char req[] = {FBUS_FRAME_HEADER, 0x70};
1254 dprintf("Getting op logo...\n");
1255 if (SM_SendMessage(state, 4, 0x0a, req) != GE_NONE) return GE_NOTREADY;
1256 return SM_Block(state, data, 0x0a);
1259 static GSM_Error SetStartupBitmap(GSM_Data *data, GSM_Statemachine *state)
1261 unsigned char req[1000] = {FBUS_FRAME_HEADER, 0xec, 0x15, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x02, 0x00,
1265 0xc0, 0x04, 0x03, 0x00 };
1269 if ((data->Bitmap->width!=state->Phone.Info.StartupLogoW) ||
1270 (data->Bitmap->height!=state->Phone.Info.StartupLogoH )) {
1271 dprintf("Invalid image size - expecting (%dx%d) got (%dx%d)\n",state->Phone.Info.StartupLogoH, state->Phone.Info.StartupLogoW, data->Bitmap->height, data->Bitmap->width);
1272 return GE_INVALIDIMAGESIZE;
1275 req[12] = data->Bitmap->height;
1276 req[16] = data->Bitmap->width;
1277 memcpy(req + count, data->Bitmap->bitmap, data->Bitmap->size);
1278 count += data->Bitmap->size;
1279 dprintf("Setting startup logo...\n");
1281 if (SM_SendMessage(state, count, 0x7a, req) != GE_NONE) return GE_NOTREADY;
1282 return SM_Block(state, data, 0x7a);
1285 static GSM_Error SetOperatorBitmap(GSM_Data *data, GSM_Statemachine *state)
1287 unsigned char req[500] = { FBUS_FRAME_HEADER, 0xa3, 0x01,
1288 0x00, /* logo enabled */
1289 0x00, 0xf0, 0x00, /* network code (000 00) */
1291 0x08, /* length of rest */
1292 0x00, 0x00, /* Bitmap width / height */
1294 0x00, /* Bitmap size */
1299 if ((data->Bitmap->width!=state->Phone.Info.OpLogoW) ||
1300 (data->Bitmap->height!=state->Phone.Info.OpLogoH )) {
1301 dprintf("Invalid image size - expecting (%dx%d) got (%dx%d)\n",state->Phone.Info.OpLogoH, state->Phone.Info.OpLogoW, data->Bitmap->height, data->Bitmap->width);
1302 return GE_INVALIDIMAGESIZE;
1305 if (strcmp(data->Bitmap->netcode,"000 00")) { /* set logo */
1306 req[5] = 0x01; // Logo enabled
1307 req[6] = ((data->Bitmap->netcode[1] & 0x0f) << 4) | (data->Bitmap->netcode[0] & 0x0f);
1308 req[7] = 0xf0 | (data->Bitmap->netcode[2] & 0x0f);
1309 req[8] = ((data->Bitmap->netcode[5] & 0x0f) << 4) | (data->Bitmap->netcode[4] & 0x0f);
1310 req[11] = 8 + data->Bitmap->size;
1311 req[12] = data->Bitmap->width;
1312 req[13] = data->Bitmap->height;
1313 req[15] = data->Bitmap->size;
1314 memcpy(req + count, data->Bitmap->bitmap, data->Bitmap->size);
1315 count += data->Bitmap->size;
1317 dprintf("Setting op logo...\n");
1318 if (SM_SendMessage(state, count, 0x0a, req) != GE_NONE) return GE_NOTREADY;
1319 return SM_Block(state, data, 0x0a);
1322 static GSM_Error P7110_GetBitmap(GSM_Data *data, GSM_Statemachine *state)
1324 switch(data->Bitmap->type) {
1325 case GSM_CallerLogo:
1326 return GetCallerBitmap(data, state);
1327 case GSM_StartupLogo:
1328 return GetStartupBitmap(data, state);
1329 case GSM_OperatorLogo:
1330 return GetOperatorBitmap(data, state);
1332 return GE_NOTIMPLEMENTED;
1336 static GSM_Error P7110_SetBitmap(GSM_Data *data, GSM_Statemachine *state)
1338 switch(data->Bitmap->type) {
1339 case GSM_CallerLogo:
1340 return SetCallerBitmap(data, state);
1341 case GSM_StartupLogo:
1342 return SetStartupBitmap(data, state);
1343 case GSM_OperatorLogo:
1344 return SetOperatorBitmap(data, state);
1346 return GE_NOTIMPLEMENTED;
1350 static GSM_Error P7110_WritePhonebookLocation(GSM_Data *data, GSM_Statemachine *state)
1352 unsigned char req[500] = {FBUS_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x0c,
1353 0x00, 0x00, /* memory type */
1354 0x00, 0x00, /* location */
1357 int block, i, j, defaultn;
1358 unsigned int count = 18;
1359 GSM_PhonebookEntry *entry;
1361 if (data->PhonebookEntry) entry=data->PhonebookEntry;
1362 else return GE_TRYAGAIN;
1364 req[11] = GetMemoryType(entry->MemoryType);
1365 req[12] = (entry->Location >> 8);
1366 req[13] = entry->Location & 0xff;
1368 if (*(entry->Name)) {
1370 i = strlen(entry->Name);
1371 EncodeUnicode((string + 1), entry->Name, i);
1373 count += PackBlock(0x07, i * 2 + 1, block++, string, req + count);
1375 string[0] = entry->Group + 1;
1377 count += PackBlock(0x1e, 2, block++, string, req + count);
1378 /* Default Number */
1380 for (i = 0; i < entry->SubEntriesCount; i++)
1381 if (entry->SubEntries[i].EntryType == GSM_Number)
1382 if (!strcmp(entry->Number, entry->SubEntries[i].data.Number))
1385 string[0] = entry->SubEntries[defaultn].NumberType;
1389 i = strlen(entry->SubEntries[defaultn].data.Number);
1390 EncodeUnicode((string + 5), entry->SubEntries[defaultn].data.Number, i);
1392 count += PackBlock(0x0b, i * 2 + 5, block++, string, req + count);
1394 /* Rest of the numbers */
1395 for (i = 0; i < entry->SubEntriesCount; i++)
1396 if (entry->SubEntries[i].EntryType == GSM_Number)
1397 if (i != defaultn) {
1398 string[0] = entry->SubEntries[i].NumberType;
1402 j = strlen(entry->SubEntries[i].data.Number);
1403 EncodeUnicode((string + 5), entry->SubEntries[i].data.Number, j);
1405 count += PackBlock(0x0b, j * 2 + 5, block++, string, req + count);
1407 req[17] = block - 1;
1408 dprintf("Writing phonebook entry %s...\n",entry->Name);
1410 if (SM_SendMessage(state, count, 0x03, req) != GE_NONE) return GE_NOTREADY;
1411 return SM_Block(state, data, 0x03);
1414 static GSM_Error P7110_ReadPhonebookLL(GSM_Data *data, GSM_Statemachine *state, int memtype, int location)
1417 unsigned char req[2000] = {FBUS_FRAME_HEADER, 0x07, 0x01, 0x01, 0x00, 0x01,
1418 0x00, 0x00, /* memory type */ //02,05
1419 0x00, 0x00, /* location */
1422 dprintf("Reading phonebook location (%d)\n", location);
1425 req[10] = location >> 8;
1426 req[11] = location & 0xff;
1428 if (SM_SendMessage(state, 14, P7110_MSG_PHONEBOOK, req) != GE_NONE) return GE_NOTREADY;
1429 error = SM_Block(state, data, P7110_MSG_PHONEBOOK);
1434 static GSM_Error P7110_ReadPhonebook(GSM_Data *data, GSM_Statemachine *state)
1436 int memtype, location;
1438 memtype = GetMemoryType(data->PhonebookEntry->MemoryType);
1439 location = data->PhonebookEntry->Location;
1441 return P7110_ReadPhonebookLL(data, state, memtype, location);
1444 static GSM_Error P7110_GetSpeedDial(GSM_Data *data, GSM_Statemachine *state)
1446 int memtype, location;
1448 memtype = P7110_MEMORY_SPEEDDIALS;
1449 location = data->SpeedDial->Number;
1451 return P7110_ReadPhonebookLL(data, state, memtype, location);
1454 static GSM_Error P7110_GetSMSCenter(GSM_Data *data, GSM_Statemachine *state)
1457 unsigned char req[2000] = {FBUS_FRAME_HEADER, P7110_SUBSMS_GET_SMSC, 0x64, 0x00};
1459 req[5] = data->MessageCenter->No;
1461 if (SM_SendMessage(state, 6, P7110_MSG_SMS, req) != GE_NONE) return GE_NOTREADY;
1462 error = SM_Block(state, data, P7110_MSG_SMS);
1467 static GSM_Error P7110_GetClock(char req_type, GSM_Data *data, GSM_Statemachine *state)
1470 unsigned char req[2000] = {FBUS_FRAME_HEADER, req_type};
1472 if (SM_SendMessage(state, 4, P7110_MSG_CLOCK, req) != GE_NONE) return GE_NOTREADY;
1473 error = SM_Block(state, data, P7110_MSG_CLOCK);
1478 static GSM_Error P7110_GetCalendarNote(GSM_Data *data, GSM_Statemachine *state)
1480 GSM_Error error = GE_NOTREADY;
1481 unsigned char req[2000] = {FBUS_FRAME_HEADER, P7110_SUBCAL_GET_NOTE, 0x00, 0x00};
1482 unsigned char date[2000] = {FBUS_FRAME_HEADER, P7110_SUBCLO_GET_DATE};
1484 GSM_DateTime tmptime;
1486 tmpdata.DateTime = &tmptime;
1487 if (SM_SendMessage(state, 4, P7110_MSG_CLOCK, date) == GE_NONE) {
1488 SM_Block(state, &tmpdata, P7110_MSG_CLOCK);
1489 req[4] = data->CalendarNote->Location >> 8;
1490 req[5] = data->CalendarNote->Location & 0xff;
1491 data->CalendarNote->Time.Year = tmptime.Year;
1493 if(SM_SendMessage(state, 6, P7110_MSG_CALENDAR, req) == GE_NONE) {
1494 error = SM_Block(state, data, P7110_MSG_CALENDAR);