Imported gammu 0.90.7
[gammu.git] / common / phone / nokia / dct4 / n6510.c
blobb6760d5ea8008dfbb3c4b7bf1bcd5703a36b91c8
1 #include "../../../gsmstate.h"
3 #ifdef GSM_ENABLE_NOKIA6510
5 #include <string.h>
6 #include <time.h>
8 #include "../../../misc/coding/coding.h"
9 #include "../../../gsmcomon.h"
10 #include "../../../service/gsmlogo.h"
11 #include "../nfunc.h"
12 #include "../nfuncold.h"
13 #include "../../pfunc.h"
14 #include "dct4func.h"
15 #include "n6510.h"
17 static GSM_Error N6510_Initialise (GSM_StateMachine *s)
19 s->Phone.Data.Priv.N6510.CalendarIconsNum = 0;
21 /* Enables various things like incoming SMS, call info, etc. */
22 return N71_65_EnableFunctions (s, "\x01\x02\x06\x0A\x14\x17\x39", 7);
25 static GSM_Error N6510_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s)
27 smprintf(s, "Phonebook entry received\n");
28 switch (msg.Buffer[6]) {
29 case 0x0f:
30 return N71_65_ReplyGetMemoryError(msg.Buffer[10], s);
31 default:
32 return N71_65_DecodePhonebook(s, s->Phone.Data.Memory, s->Phone.Data.Bitmap, s->Phone.Data.SpeedDial, msg.Buffer+22, msg.Length-22);
34 return GE_UNKNOWN;
37 static GSM_Error N6510_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry)
39 unsigned char req[] = {
40 N6110_FRAME_HEADER, 0x07, 0x01, 0x01, 0x00, 0x01,
41 0xfe, 0x10, /* memory type */
42 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x01, /* location */
44 0x00, 0x00, 0x01};
46 req[9] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
47 if (req[9]==0xff) return GE_NOTSUPPORTED;
49 if (entry->Location==0x00) return GE_INVALIDLOCATION;
51 req[14] = (entry->Location>>8);
52 req[15] = entry->Location & 0xff;
54 s->Phone.Data.Memory=entry;
55 smprintf(s, "Getting phonebook entry\n");
56 return GSM_WaitFor (s, req, 19, 0x03, 4, ID_GetMemory);
59 static GSM_Error N6510_ReplyGetMemoryStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
61 GSM_Phone_Data *Data = &s->Phone.Data;
63 smprintf(s, "Memory status received\n");
64 /* Quess ;-)) */
65 if (msg.Buffer[14]==0x10) {
66 Data->MemoryStatus->Free = msg.Buffer[18]*256 + msg.Buffer[19];
67 } else {
68 Data->MemoryStatus->Free = msg.Buffer[17];
70 smprintf(s, " Size : %i\n",Data->MemoryStatus->Free);
71 Data->MemoryStatus->Used = msg.Buffer[20]*256 + msg.Buffer[21];
72 smprintf(s, " Used : %i\n",Data->MemoryStatus->Used);
73 Data->MemoryStatus->Free -= Data->MemoryStatus->Used;
74 smprintf(s, " Free : %i\n",Data->MemoryStatus->Free);
75 return GE_NONE;
78 static GSM_Error N6510_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status)
80 unsigned char req[] = {
81 N6110_FRAME_HEADER, 0x03, 0x02,
82 0x00, /* MemoryType */
83 0x55, 0x55, 0x55, 0x00};
85 req[5] = NOKIA_GetMemoryType(s, Status->MemoryType,N71_65_MEMORY_TYPES);
86 if (req[5]==0xff) return GE_NOTSUPPORTED;
88 s->Phone.Data.MemoryStatus=Status;
89 smprintf(s, "Getting memory status\n");
90 return GSM_WaitFor (s, req, 10, 0x03, 4, ID_GetMemoryStatus);
93 static GSM_Error N6510_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s)
95 int i, current, j;
96 GSM_Phone_Data *Data = &s->Phone.Data;
98 switch (msg.Buffer[4]) {
99 case 0x00:
100 smprintf(s, "SMSC received\n");
101 break;
102 case 0x02:
103 smprintf(s, "SMSC empty\n");
104 return GE_INVALIDLOCATION;
105 default:
106 smprintf(s, "Unknown SMSC state: %02x\n",msg.Buffer[4]);
107 return GE_UNKNOWNRESPONSE;
109 memset(Data->SMSC,0,sizeof(GSM_SMSC));
110 Data->SMSC->Location = msg.Buffer[8];
111 Data->SMSC->Format = GSMF_Text;
112 switch (msg.Buffer[10]) {
113 case 0x00: Data->SMSC->Format = GSMF_Text; break;
114 case 0x22: Data->SMSC->Format = GSMF_Fax; break;
115 case 0x26: Data->SMSC->Format = GSMF_Pager; break;
116 case 0x32: Data->SMSC->Format = GSMF_Email; break;
118 Data->SMSC->Validity.VPF = GSM_RelativeFormat;
119 Data->SMSC->Validity.Relative = msg.Buffer[12];
120 current = 14;
121 for (i=0;i<msg.Buffer[13];i++) {
122 switch (msg.Buffer[current]) {
123 case 0x81:
124 j=current+4;
125 while (msg.Buffer[j]!=0) {j++;}
126 j=j-33;
127 if (j>GSM_MAX_SMSC_NAME_LENGTH) {
128 smprintf(s, "Too long name\n");
129 return GE_UNKNOWNRESPONSE;
131 CopyUnicodeString(Data->SMSC->Name,msg.Buffer+current+4);
132 smprintf(s, " Name \"%s\"\n", DecodeUnicodeString(Data->SMSC->Name));
133 break;
134 case 0x82:
135 switch (msg.Buffer[current+2]) {
136 case 0x01:
137 GSM_UnpackSemiOctetNumber(Data->SMSC->DefaultNumber,msg.Buffer+current+4,true);
138 smprintf(s, " Default number \"%s\"\n", DecodeUnicodeString(Data->SMSC->DefaultNumber));
139 break;
140 case 0x02:
141 GSM_UnpackSemiOctetNumber(Data->SMSC->Number,msg.Buffer+current+4,false);
142 smprintf(s, " Number \"%s\"\n", DecodeUnicodeString(Data->SMSC->Number));
143 break;
144 default:
145 smprintf(s, "Unknown SMSC number: %02x\n",msg.Buffer[current+2]);
146 return GE_UNKNOWNRESPONSE;
148 break;
149 default:
150 smprintf(s, "Unknown SMSC block: %02x\n",msg.Buffer[current]);
151 return GE_UNKNOWNRESPONSE;
153 current = current + msg.Buffer[current+1];
155 return GE_NONE;
158 static GSM_Error N6510_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
160 unsigned char req[] = {
161 N6110_FRAME_HEADER, 0x14,
162 0x01, /* SMS Center Number. */
163 0x00};
165 if (smsc->Location==0x00) return GE_INVALIDLOCATION;
167 req[4]=smsc->Location;
169 s->Phone.Data.SMSC=smsc;
170 smprintf(s, "Getting SMSC\n");
171 return GSM_WaitFor (s, req, 6, 0x02, 4, ID_GetSMSC);
174 static GSM_Error N6510_ReplySetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s)
176 switch (msg.Buffer[4]) {
177 case 0x00:
178 smprintf(s, "SMSC set OK\n");
179 return GE_NONE;
180 case 0x02:
181 smprintf(s, "Invalid SMSC location\n");
182 return GE_INVALIDLOCATION;
183 default:
184 smprintf(s, "Unknown SMSC state: %02x\n",msg.Buffer[4]);
185 return GE_UNKNOWNRESPONSE;
187 return GE_UNKNOWNRESPONSE;
190 static GSM_Error N6510_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
192 int count = 13,i;
193 unsigned char req[256] = {
194 N6110_FRAME_HEADER,
195 0x12, 0x55, 0x01, 0x0B, 0x34,
196 0x05, /* Location */
197 0x00,
198 0x00, /* Format */
199 0x00,
200 0xFF}; /* Validity */
202 req[8] = smsc->Location;
203 switch (smsc->Format) {
204 case GSMF_Text: req[10] = 0x00; break;
205 case GSMF_Fax: req[10] = 0x22; break;
206 case GSMF_Pager: req[10] = 0x26; break;
207 case GSMF_Email: req[10] = 0x32; break;
209 req[12] = smsc->Validity.Relative;
211 /* coding data in the sequent blocks */
212 req[count++] = 0x03; /* Number of blocks */
214 /* Block 2. SMSC Number */
215 req[count++] = 0x82; /* type: number */
216 req[count++] = 0x1A; /* offset to next block starting from start of block */
217 req[count++] = 0x02; /* first number field => SMSC number */
218 req[count] = GSM_PackSemiOctetNumber(smsc->Number, req+count+2, false) + 1;
219 if (req[count]>18) {
220 smprintf(s, "Too long SMSC number in frame\n");
221 return GE_UNKNOWN;
223 req[count+1] = req[count] - 1;
224 count += 23;
226 /* Block 1. Default Number */
227 req[count++] = 0x82; /* type: number */
228 req[count++] = 0x14; /* offset to next block starting from start of block */
229 req[count++] = 0x01; /* first number field => default number */
230 req[count] = GSM_PackSemiOctetNumber(smsc->DefaultNumber, req+count+2, true) + 1;
231 if (req[count]*2>12) {
232 smprintf(s, "Too long SMSC number in frame\n");
233 return GE_UNKNOWN;
235 req[count+1] = req[count] - 1;
236 count += 17;
238 /* Block 3. SMSC name */
239 req[count++] = 0x81;
240 req[count++] = UnicodeLength(smsc->Name)*2 + 2 + 4;
241 req[count++] = UnicodeLength(smsc->Name)*2 + 2;
242 req[count++] = 0x00;
243 /* Can't make CopyUnicodeString(req+count,sms->Name) !!!!
244 * with MSVC6 count is changed then
246 i = count;
247 CopyUnicodeString(req+i,smsc->Name);
248 count += UnicodeLength(smsc->Name)*2 + 2;
250 smprintf(s, "Setting SMSC\n");
251 return GSM_WaitFor (s, req, count, 0x02, 4, ID_SetSMSC);
254 static GSM_Error N6510_ReplyGetNetworkInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
256 int current = msg.Buffer[7]+7, tmp;
257 GSM_Phone_Data *Data = &s->Phone.Data;
258 #ifdef DEBUG
259 char name[100];
260 GSM_NetworkInfo NetInfo;
262 switch (msg.Buffer[8]) {
263 case 0x00 : smprintf(s, " Logged into home network.\n"); break;
264 case 0x01 : smprintf(s, " Logged into a roaming network.\n"); break;
265 case 0x04 : smprintf(s, " Not logged in any network!"); break;
266 case 0x06 : smprintf(s, " SIM card rejected\n"); break;
267 case 0x09 : smprintf(s, " Not logged in any network!"); break;
268 default : smprintf(s, " Unknown network status %i!\n",msg.Buffer[8]); break;
270 if (msg.Buffer[8]==0x00 || msg.Buffer[8] == 0x01) {
271 tmp = 10;
272 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer,name,true);
273 smprintf(s, " Network name for phone : %s\n",DecodeUnicodeString(name));
274 NOKIA_DecodeNetworkCode(msg.Buffer + (current + 7),NetInfo.NetworkCode);
275 sprintf(NetInfo.CellID, "%02x%02x", msg.Buffer[current+5], msg.Buffer[current+6]);
276 sprintf(NetInfo.LAC, "%02x%02x", msg.Buffer[current+1], msg.Buffer[current+2]);
277 smprintf(s, " CellID : %s\n", NetInfo.CellID);
278 smprintf(s, " LAC : %s\n", NetInfo.LAC);
279 smprintf(s, " Network code : %s\n", NetInfo.NetworkCode);
280 smprintf(s, " Network name for Gammu : %s ",
281 DecodeUnicodeString(GSM_GetNetworkName(NetInfo.NetworkCode)));
282 smprintf(s, "(%s)\n",DecodeUnicodeString(GSM_GetCountryName(NetInfo.NetworkCode)));
284 #endif
285 if (Data->RequestID==ID_GetNetworkInfo) {
286 Data->NetworkInfo->NetworkName[0] = 0x00;
287 Data->NetworkInfo->NetworkName[1] = 0x00;
288 Data->NetworkInfo->State = 0;
289 switch (msg.Buffer[8]) {
290 case 0x00: Data->NetworkInfo->State = GSM_HomeNetwork; break;
291 case 0x01: Data->NetworkInfo->State = GSM_RoamingNetwork; break;
292 case 0x04:
293 case 0x06:
294 case 0x09: Data->NetworkInfo->State = GSM_NoNetwork; break;
296 if (Data->NetworkInfo->State == GSM_HomeNetwork || Data->NetworkInfo->State == GSM_RoamingNetwork) {
297 tmp = 10;
298 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer,Data->NetworkInfo->NetworkName,true);
299 sprintf(Data->NetworkInfo->CellID, "%02x%02x", msg.Buffer[current+5], msg.Buffer[current+6]);
300 sprintf(Data->NetworkInfo->LAC, "%02x%02x", msg.Buffer[current+1], msg.Buffer[current+2]);
301 NOKIA_DecodeNetworkCode(msg.Buffer + (current+7),Data->NetworkInfo->NetworkCode);
304 return GE_NONE;
307 static GSM_Error N6510_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo)
309 unsigned char req[] = {N6110_FRAME_HEADER, 0x00, 0x00};
311 s->Phone.Data.NetworkInfo=netinfo;
312 smprintf(s, "Getting network info\n");
313 return GSM_WaitFor (s, req, 5, 0x0a, 4, ID_GetNetworkInfo);
316 static GSM_Error N6510_EncodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *req, GSM_SMSMessageLayout *Layout, int *length)
318 int start, count = 0, pos1, pos2, pos3, pos4, pos5;
319 GSM_Error error;
321 memset(Layout,255,sizeof(GSM_SMSMessageLayout));
323 start = *length;
325 req[count++] = 0x01; /* one big block ? */
326 if (sms->PDU != SMS_Deliver) {
327 req[count++] = 0x02;
328 } else {
329 req[count++] = 0x00;
332 pos1 = count; count++;
333 Layout->firstbyte = count; count++; /* firstbyte set in SMS Layout */
334 if (sms->PDU != SMS_Deliver) {
335 Layout->TPMR = count; count++; /* ??? */
336 Layout->TPPID = count; count++;
337 Layout->TPDCS = count; count++; /* TP.DCS set in SMS layout */
338 req[count++] = 0x00;
339 } else {
340 Layout->TPPID = count; count++;
341 Layout->TPDCS = count; count++; /* TP.DCS set in SMS layout */
342 Layout->DateTime = count; count += 7;
343 req[count++] = 0x55;
344 req[count++] = 0x55;
345 req[count++] = 0x55;
348 /* Magic. Nokia new ideas: coding SMS in the sequent blocks */
349 if (sms->PDU != SMS_Deliver) {
350 req[count++] = 0x04; /* Number of blocks */
351 } else {
352 req[count++] = 0x03; /* Number of blocks */
355 /* Block 1. Remote Number */
356 req[count++] = 0x82; /* type: number */
357 req[count++] = 0x10; /* offset to next block starting from start of block (req[18]) */
358 req[count++] = 0x01; /* first number field => phone number */
359 pos4 = count; count++;
360 Layout->Number = count; count+= 12; /* now coded Number in SMS Layout */
362 /* Block 2. SMSC Number */
363 req[count++] = 0x82; /* type: number */
364 req[count++] = 0x10; /* offset to next block starting from start of block (req[18]) */
365 req[count++] = 0x02; /* first number field => SMSC number */
366 pos5 = count; count++;
367 Layout->SMSCNumber = count; count += 12; /* now coded SMSC number in SMS Layout */
369 /* Block 3. Validity Period */
370 if (sms->PDU != SMS_Deliver) {
371 req[count++] = 0x08; /* type: validity */
372 req[count++] = 0x04;
373 req[count++] = 0x01; /* data length */
374 Layout->TPVP = count; count++;
377 /* Block 4. User Data */
378 req[count++] = 0x80; /* type: User Data */
379 pos2 = count; count++; /* same as req[11] but starting from req[42] */
380 pos3 = count; count++;
381 Layout->TPUDL = count; count++; /* FIXME*/
382 Layout->Text = count; /* SMS text and UDH coded in SMS Layout */
384 error = PHONE_EncodeSMSFrame(s,sms,req,*Layout,length,false);
385 if (error != GE_NONE) return error;
387 req[pos1] = *length - 1;
388 req[pos2] = *length - Layout->Text + 6;
389 req[pos3] = *length - Layout->Text;
391 /* Convert number of semioctets to number of chars */
392 req[pos4] = req[Layout->Number] + 4;
393 if (req[pos4] % 2) req[pos4]++;
394 req[pos4] /= 2;
396 req[pos5] = req[Layout->SMSCNumber] + 1;
398 if (req[pos4]>12 || req[pos5]>12) {
399 smprintf(s, "Too long phone number in frame\n");
400 return GE_UNKNOWN;
403 return GE_NONE;
406 static GSM_Error N6510_ReplyGetSMSFolders(GSM_Protocol_Message msg, GSM_StateMachine *s)
408 int j, num = 0, pos;
409 GSM_Phone_Data *Data = &s->Phone.Data;
411 switch (msg.Buffer[3]) {
412 case 0x13:
413 smprintf(s, "SMS folders names received\n");
414 Data->SMSFolders->Number = msg.Buffer[5]+2;
415 pos = 6;
416 for (j=0;j<msg.Buffer[5];j++) {
417 while (true) {
418 if (msg.Buffer[pos] == msg.Buffer[6] &&
419 msg.Buffer[pos+1] == msg.Buffer[7]) break;
420 if (pos+4 > msg.Length) return GE_UNKNOWNRESPONSE;
421 pos++;
423 pos+=4;
424 smprintf(s, "Folder index: %02x",msg.Buffer[pos - 2]);
425 if (msg.Buffer[pos - 1]>GSM_MAX_SMS_FOLDER_NAME_LEN) {
426 smprintf(s, "Too long text\n");
427 return GE_UNKNOWNRESPONSE;
429 CopyUnicodeString(Data->SMSFolders->Folder[num].Name,msg.Buffer + pos);
430 smprintf(s, ", folder name: \"%s\"\n",DecodeUnicodeString(Data->SMSFolders->Folder[num].Name));
431 Data->SMSFolders->Folder[num].InboxFolder = false;
432 Data->SMSFolders->Folder[num].Memory = GMT_ME;
433 if (num == 0x00 || num == 0x02) {
434 if (num == 0x00) {
435 Data->SMSFolders->Folder[num].InboxFolder=true;
437 Data->SMSFolders->Folder[num].Memory = GMT_SM;
438 num++;
439 CopyUnicodeString(Data->SMSFolders->Folder[num].Name,msg.Buffer + pos);
440 Data->SMSFolders->Folder[num].Memory = GMT_ME;
441 Data->SMSFolders->Folder[num].InboxFolder = false;
442 if (num == 0x01) {
443 Data->SMSFolders->Folder[num].InboxFolder=true;
446 num++;
448 return GE_NONE;
450 return GE_UNKNOWNRESPONSE;
453 static GSM_Error N6510_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders)
455 unsigned char req[] = {N6110_FRAME_HEADER, 0x12, 0x00, 0x00};
457 s->Phone.Data.SMSFolders=folders;
458 smprintf(s, "Getting SMS folders\n");
459 return GSM_WaitFor (s, req, 6, 0x14, 4, ID_GetSMSFolders);
462 static GSM_Error N6510_ReplyGetSMSFolderStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
464 int i;
465 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
467 smprintf(s, "SMS folder status received\n");
468 Priv->LastSMSFolder.Number=msg.Buffer[6]*256+msg.Buffer[7];
469 smprintf(s, "Number of Entries: %i\n",Priv->LastSMSFolder.Number);
470 smprintf(s, "Locations: ");
471 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
472 Priv->LastSMSFolder.Location[i]=msg.Buffer[8+(i*2)]*256+msg.Buffer[(i*2)+9];
473 smprintf(s, "%i ",Priv->LastSMSFolder.Location[i]);
475 smprintf(s, "\n");
476 NOKIA_SortSMSFolderStatus(s, &Priv->LastSMSFolder);
477 return GE_NONE;
480 static GSM_Error N6510_GetSMSFolderStatus(GSM_StateMachine *s, int folderid)
482 unsigned char req[] = {
483 N7110_FRAME_HEADER, 0x0C,
484 0x01, /* 0x01 SIM, 0x02 ME */
485 0x00, /* Folder ID */
486 0x0f, 0x55, 0x55, 0x55};
488 switch (folderid) {
489 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
490 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
491 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */
494 smprintf(s, "Getting SMS folder status\n");
495 return GSM_WaitFor (s, req, 10, 0x14, 4, ID_GetSMSFolderStatus);
498 static void N6510_GetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *folderid, int *location)
500 int ifolderid;
502 /* simulate flat SMS memory */
503 if (sms->Folder==0x00) {
504 ifolderid = sms->Location / PHONE_MAXSMSINFOLDER;
505 *folderid = ifolderid + 0x01;
506 *location = sms->Location - ifolderid * PHONE_MAXSMSINFOLDER;
507 } else {
508 *folderid = sms->Folder;
509 *location = sms->Location;
511 smprintf(s, "SMS folder %i & location %i -> 6510 folder %i & location %i\n",
512 sms->Folder,sms->Location,*folderid,*location);
515 static void N6510_SetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char folderid, int location)
517 sms->Folder = 0;
518 sms->Location = (folderid - 0x01) * PHONE_MAXSMSINFOLDER + location;
519 smprintf(s, "6510 folder %i & location %i -> SMS folder %i & location %i\n",
520 folderid,location,sms->Folder,sms->Location);
523 static GSM_Error N6510_DecodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *buffer)
525 int i, current, blocks=0, SMSTemplateDateTime = 0;
526 GSM_SMSMessageLayout Layout;
527 GSM_Error error;
529 memset(&Layout,255,sizeof(GSM_SMSMessageLayout));
530 Layout.firstbyte = 2;
531 switch (buffer[0]) {
532 case 0x00:
533 smprintf(s, "SMS deliver\n");
534 sms->PDU = SMS_Deliver;
535 Layout.TPPID = 3;
536 Layout.TPDCS = 4;
537 Layout.DateTime = 5;
538 blocks = 15;
539 break;
540 case 0x01:
541 smprintf(s, "Delivery report\n");
542 sms->PDU = SMS_Status_Report;
543 Layout.TPStatus = 4;
544 Layout.DateTime = 5;
545 Layout.SMSCTime = 12;
546 blocks = 19;
547 break;
548 case 0x02:
549 smprintf(s, "SMS template\n");
550 sms->PDU = SMS_Submit;
551 Layout.TPMR = 3;
552 Layout.TPPID = 4;
553 Layout.TPDCS = 5;
554 blocks = 7;
555 break;
557 current = blocks + 1;
558 for (i=0;i<buffer[blocks];i++) {
559 switch (buffer[current]) {
560 case 0x80:
561 smprintf(s, "User data\n");
562 if (buffer[current + 2] > buffer[current + 3]) {
563 Layout.TPUDL = current + 2;
564 } else {
565 Layout.TPUDL = current + 3;
567 Layout.Text = current + 4;
568 break;
569 case 0x82:
570 switch (buffer[current+2]) {
571 case 0x01:
572 smprintf(s, "Phone number\n");
573 Layout.Number = current + 4;
574 break;
575 case 0x02:
576 smprintf(s, "SMSC number\n");
577 Layout.SMSCNumber = current + 4;
578 break;
579 default:
580 smprintf(s, "Unknown number\n");
581 break;
583 break;
584 case 0x84:
585 smprintf(s, "Date and time of saving for SMS template\n");
586 SMSTemplateDateTime = current + 2;
587 break;
588 default:
589 smprintf(s, "Unknown block %02x\n",buffer[current]);
591 current = current + buffer[current + 1];
593 error=GSM_DecodeSMSFrame(sms,buffer,Layout);
594 if (SMSTemplateDateTime != 0) {
595 sms->PDU = SMS_Deliver;
596 NOKIA_DecodeDateTime(s, buffer+SMSTemplateDateTime, &sms->DateTime);
597 sms->DateTime.Timezone = 0;
599 return error;
602 static GSM_Error N6510_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
604 int i;
605 int Width, Height;
606 unsigned char output[500]; //output2[500];
607 GSM_Phone_Data *Data = &s->Phone.Data;
609 switch(msg.Buffer[3]) {
610 case 0x03:
611 smprintf(s, "SMS Message received\n");
612 Data->GetSMSMessage->Number=1;
613 NOKIA_DecodeSMSState(s, msg.Buffer[5], &Data->GetSMSMessage->SMS[0]);
614 switch (msg.Buffer[14]) {
615 case 0x00:
616 case 0x01:
617 case 0x02:
618 return N6510_DecodeSMSFrame(s, &Data->GetSMSMessage->SMS[0],msg.Buffer+14);
619 case 0xA0:
620 smprintf(s, "Picture Image\n");
621 Data->GetSMSMessage->Number = 0;
622 i = 0;
623 output[i++] = 0x30; /* Smart Messaging 3.0 */
624 output[i++] = SM30_OTA;
625 output[i++] = 0x01; /* Length */
626 output[i++] = 0x00; /* Length */
627 output[i++] = 0x00;
628 PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height);
629 output[i++] = Width;
630 output[i++] = Height;
631 output[i++] = 0x01;
632 memcpy(output+i,msg.Buffer+30,PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0));
633 i = i + PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0);
634 // if (msg.Length!=282) {
635 // output[i++] = SM30_UNICODETEXT;
636 // output[i++] = 0;
637 // output[i++] = 0; /* Length - later changed */
638 // GSM_UnpackEightBitsToSeven(0, msg.Length-282, msg.Length-304, msg.Buffer+282,output2);
639 // DecodeDefault(output+i, output2, msg.Length - 282, true);
640 // output[i - 1] = UnicodeLength(output+i) * 2;
641 // i = i + output[i-1];
642 // }
643 GSM_MakeMultiPartSMS(Data->GetSMSMessage,output,i,UDH_NokiaProfileLong,GSM_Coding_8bit,1,0);
644 for (i=0;i<3;i++) {
645 Data->GetSMSMessage->SMS[i].Number[0]=0;
646 Data->GetSMSMessage->SMS[i].Number[1]=0;
648 if (Data->Bitmap != NULL) {
649 Data->Bitmap->Location = 0;
650 PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height);
651 Data->Bitmap->Width = Width;
652 Data->Bitmap->Height = Height;
653 PHONE_DecodeBitmap(GSM_NokiaPictureImage, msg.Buffer + 30, Data->Bitmap);
654 Data->Bitmap->Sender[0] = 0x00;
655 Data->Bitmap->Sender[1] = 0x00;
656 Data->Bitmap->Text[0] = 0;
657 Data->Bitmap->Text[1] = 0;
659 return GE_NONE;
660 default:
661 smprintf(s, "Unknown SMS type: %i\n",msg.Buffer[8]);
663 break;
664 case 0x0f:
665 smprintf(s, "SMS message info received\n");
666 CopyUnicodeString(Data->GetSMSMessage->SMS[0].Name,msg.Buffer+52);
667 smprintf(s, "Name: \"%s\"\n",DecodeUnicodeString(Data->GetSMSMessage->SMS[0].Name));
668 return GE_NONE;
670 return GE_UNKNOWNRESPONSE;
673 static GSM_Error N6510_PrivGetSMSMessageBitmap(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, GSM_Bitmap *bitmap)
675 GSM_Error error;
676 unsigned char folderid,namebuffer[200];
677 int location;
678 int i;
679 unsigned char req[] = {
680 N6110_FRAME_HEADER,
681 0x02, /* msg type: 0x02 for getting sms, 0x0e for sms status */
682 0x01, /* 0x01 SIM, 0x02 ME */
683 0x00, /* FolderID */
684 0x00, 0x02, /* Location */
685 0x01, 0x00};
687 N6510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
689 switch (folderid) {
690 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
691 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
692 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */
694 req[6]=location / 256;
695 req[7]=location;
697 s->Phone.Data.GetSMSMessage = sms;
698 s->Phone.Data.Bitmap = bitmap;
699 smprintf(s, "Getting sms message info\n");
700 req[3] = 0x0e; req[8] = 0x55; req[9] = 0x55;
701 error=GSM_WaitFor (s, req, 10, 0x14, 4, ID_GetSMSMessage);
702 if (error!=GE_NONE) return error;
703 CopyUnicodeString(namebuffer,sms->SMS[0].Name);
705 smprintf(s, "Getting sms\n");
706 req[3] = 0x02; req[8] = 0x01; req[9] = 0x00;
707 error=GSM_WaitFor (s, req, 10, 0x14, 4, ID_GetSMSMessage);
708 if (error==GE_NONE) {
709 for (i=0;i<sms->Number;i++) {
710 N6510_SetSMSLocation(s, &sms->SMS[i], folderid, location);
711 sms->SMS[i].Folder = folderid;
712 sms->SMS[i].InboxFolder = true;
713 if (folderid != 0x01 && folderid != 0x02) sms->SMS[i].InboxFolder = false;
714 sms->SMS[i].Memory = GMT_ME;
715 if (folderid == 0x01 || folderid == 0x03) sms->SMS[i].Memory = GMT_SM;
716 CopyUnicodeString(sms->SMS[i].Name,namebuffer);
719 return error;
722 static GSM_Error N6510_GetSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms)
724 GSM_Error error;
725 unsigned char folderid;
726 int location;
727 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
728 int i;
729 bool found = false;
731 N6510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
732 error=N6510_GetSMSFolderStatus(s, folderid);
733 if (error!=GE_NONE) return error;
734 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
735 if (Priv->LastSMSFolder.Location[i]==location) {
736 found = true;
737 break;
740 if (!found) return GE_EMPTY;
741 return N6510_PrivGetSMSMessageBitmap(s,sms,NULL);
744 static GSM_Error N6510_GetNextSMSMessageBitmap(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start, GSM_Bitmap *bitmap)
746 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
747 unsigned char folderid;
748 int location;
749 GSM_Error error;
750 int i;
751 bool findnextfolder = false;
753 if (start) {
754 folderid = 0x00;
755 findnextfolder = true;
756 error=N6510_GetSMSFolders(s,&Priv->LastSMSFolders);
757 if (error!=GE_NONE) return error;
758 } else {
759 N6510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
760 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
761 if (Priv->LastSMSFolder.Location[i]==location) break;
763 /* Is this last location in this folder ? */
764 if (i==Priv->LastSMSFolder.Number-1) {
765 findnextfolder=true;
766 } else {
767 location=Priv->LastSMSFolder.Location[i+1];
770 if (findnextfolder) {
771 Priv->LastSMSFolder.Number=0;
772 while (Priv->LastSMSFolder.Number==0) {
773 folderid++;
774 /* Too high folder number */
775 if ((folderid-1)>Priv->LastSMSFolders.Number) return GE_EMPTY;
776 /* Get next folder status */
777 error=N6510_GetSMSFolderStatus(s, folderid);
778 if (error!=GE_NONE) return error;
779 /* First location from this folder */
780 location=Priv->LastSMSFolder.Location[0];
783 N6510_SetSMSLocation(s, &sms->SMS[0], folderid, location);
785 return N6510_PrivGetSMSMessageBitmap(s, sms, bitmap);
788 static GSM_Error N6510_GetNextSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start)
790 return N6510_GetNextSMSMessageBitmap(s, sms, start, NULL);
793 static GSM_Error N6510_ReplyStartupNoteLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
795 GSM_Phone_Data *Data = &s->Phone.Data;
797 if (Data->RequestID == ID_GetBitmap) {
798 switch (msg.Buffer[4]) {
799 case 0x01:
800 smprintf(s, "Welcome note text received\n");
801 CopyUnicodeString(Data->Bitmap->Text,msg.Buffer+6);
802 smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text));
803 return GE_NONE;
804 case 0x10:
805 smprintf(s, "Dealer note text received\n");
806 CopyUnicodeString(Data->Bitmap->Text,msg.Buffer+6);
807 smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text));
808 return GE_NONE;
809 case 0x0f:
810 smprintf(s, "Startup logo received\n");
811 PHONE_DecodeBitmap(GSM_Nokia7110StartupLogo, msg.Buffer + 22, Data->Bitmap);
812 return GE_NONE;
815 if (Data->RequestID == ID_SetBitmap) {
816 switch (msg.Buffer[4]) {
817 case 0x01:
818 case 0x10:
819 case 0x0f:
820 case 0x25:
821 return GE_NONE;
824 return GE_UNKNOWN;
827 static GSM_Error N6510_GetPictureImage(GSM_StateMachine *s, GSM_Bitmap *Bitmap, int *location)
829 GSM_MultiSMSMessage sms;
830 int Number;
831 GSM_Bitmap bitmap;
832 GSM_Error error;
834 sms.SMS[0].Folder = 0;
835 Number = 0;
836 bitmap.Location = 255;
837 error=N6510_GetNextSMSMessageBitmap(s, &sms, true, &bitmap);
838 while (error == GE_NONE) {
839 if (bitmap.Location != 255) {
840 Number++;
841 if (Number == Bitmap->Location) {
842 bitmap.Location = Bitmap->Location;
843 memcpy(Bitmap,&bitmap,sizeof(GSM_Bitmap));
844 *location = sms.SMS[0].Location;
845 return GE_NONE;
848 bitmap.Location = 255;
849 sms.SMS[0].Folder = 0;
850 error=N6510_GetNextSMSMessageBitmap(s, &sms, false, &bitmap);
852 return GE_INVALIDLOCATION;
855 static GSM_Error N6510_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
857 unsigned char reqOp [] = {N6110_FRAME_HEADER, 0x23, 0x00, 0x00, 0x55, 0x55, 0x55};
858 unsigned char reqStartup[] = {N6110_FRAME_HEADER, 0x02, 0x0f};
859 unsigned char reqNote [] = {N6110_FRAME_HEADER, 0x02, 0x01, 0x00};
860 GSM_MemoryEntry pbk;
861 GSM_Error error;
862 int Location;
864 s->Phone.Data.Bitmap=Bitmap;
865 switch (Bitmap->Type) {
866 case GSM_StartupLogo:
867 Bitmap->Width = 96;
868 Bitmap->Height = 65;
869 GSM_ClearBitmap(Bitmap);
870 smprintf(s, "Getting startup logo\n");
871 return GSM_WaitFor (s, reqStartup, 5, 0x7A, 4, ID_GetBitmap);
872 case GSM_DealerNoteText:
873 reqNote[4] = 0x10;
874 smprintf(s, "Getting dealer note\n");
875 return GSM_WaitFor (s, reqNote, 6, 0x7A, 4, ID_GetBitmap);
876 case GSM_WelcomeNoteText:
877 smprintf(s, "Getting welcome note\n");
878 return GSM_WaitFor (s, reqNote, 6, 0x7A, 4, ID_GetBitmap);
879 case GSM_CallerLogo:
880 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PBK35)) return GE_NOTSUPPORTED;
881 Bitmap->Width = 72;
882 Bitmap->Height = 14;
883 GSM_ClearBitmap(Bitmap);
884 pbk.MemoryType = GMT7110_CG;
885 pbk.Location = Bitmap->Location;
886 smprintf(s, "Getting caller group logo\n");
887 error=N6510_GetMemory(s,&pbk);
888 if (error==GE_NONE) NOKIA_GetDefaultCallerGroupName(s, Bitmap);
889 return error;
890 case GSM_OperatorLogo:
891 smprintf(s, "Getting operator logo\n");
892 return GSM_WaitFor (s, reqOp, 9, 0x0A, 4, ID_GetBitmap);
893 case GSM_PictureImage:
894 return N6510_GetPictureImage(s, Bitmap, &Location);
895 default:
896 break;
898 return GE_NOTSUPPORTED;
901 static GSM_Error N6510_ReplyGetIncSignalQuality(GSM_Protocol_Message msg, GSM_StateMachine *s)
903 smprintf(s, "Network level changed to: %i\n",msg.Buffer[4]);
904 return GE_NONE;
907 static GSM_Error N6510_ReplyGetSignalQuality(GSM_Protocol_Message msg, GSM_StateMachine *s)
909 GSM_Phone_Data *Data = &s->Phone.Data;
911 smprintf(s, "Network level received: %i\n",msg.Buffer[8]);
912 Data->SignalQuality->SignalStrength = -1;
913 Data->SignalQuality->SignalPercent = ((int)msg.Buffer[8]);
914 Data->SignalQuality->BitErrorRate = -1;
915 return GE_NONE;
918 static GSM_Error N6510_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig)
920 unsigned char req[] = {N6110_FRAME_HEADER, 0x0B, 0x00, 0x02, 0x00, 0x00, 0x00};
922 s->Phone.Data.SignalQuality = sig;
923 smprintf(s, "Getting network level\n");
924 return GSM_WaitFor (s, req, 9, 0x0a, 4, ID_GetSignalQuality);
927 static GSM_Error N6510_ReplyGetBatteryCharge(GSM_Protocol_Message msg, GSM_StateMachine *s)
929 GSM_Phone_Data *Data = &s->Phone.Data;
931 smprintf(s, "Battery level received: %i\n",msg.Buffer[9]*100/7);
932 Data->BatteryCharge->BatteryPercent = ((int)(msg.Buffer[9]*100/7));
933 Data->BatteryCharge->ChargeState = 0;
934 return GE_NONE;
937 static GSM_Error N6510_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat)
939 unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x02, 0x00};
941 s->Phone.Data.BatteryCharge = bat;
942 smprintf(s, "Getting battery level\n");
943 return GSM_WaitFor (s, req, 6, 0x17, 4, ID_GetBatteryCharge);
946 static GSM_Error N6510_ReplyGetWAPBookmark(GSM_Protocol_Message msg, GSM_StateMachine *s)
948 return DCT3DCT4_ReplyGetWAPBookmark (msg, s, true);
951 static GSM_Error N6510_ReplyGetOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
953 GSM_Phone_Data *Data = &s->Phone.Data;
955 smprintf(s, "Operator logo received\n");
956 NOKIA_DecodeNetworkCode(msg.Buffer+12,Data->Bitmap->NetworkCode);
957 smprintf(s, "Network code %s\n",Data->Bitmap->NetworkCode);
958 Data->Bitmap->Width = msg.Buffer[20];
959 Data->Bitmap->Height = msg.Buffer[21];
960 if (msg.Length == 18) return GE_EMPTY;
961 PHONE_DecodeBitmap(GSM_Nokia6510OperatorLogo,msg.Buffer+26,Data->Bitmap);
962 return GE_NONE;
965 GSM_Error N6510_ReplyDeleteMemory(GSM_Protocol_Message msg, GSM_StateMachine *s)
967 smprintf(s, "Phonebook entry deleted\n");
968 return GE_NONE;
971 GSM_Error N6510_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
973 unsigned char req[] = {
974 N7110_FRAME_HEADER, 0x0f, 0x55, 0x01,
975 0x04, 0x55, 0x00, 0x10, 0xFF, 0x02,
976 0x00, 0x01, /* location */
977 0x00, 0x00, 0x00, 0x00,
978 0x05, /* memory type */
979 0x55, 0x55, 0x55};
981 req[12] = (entry->Location >> 8);
982 req[13] = entry->Location & 0xff;
984 req[18] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
985 if (req[18]==0xff) return GE_NOTSUPPORTED;
987 smprintf(s, "Deleting phonebook entry\n");
988 return GSM_WaitFor (s, req, 22, 0x03, 4, ID_SetMemory);
991 static GSM_Error N6510_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
993 int count = 22, blocks;
994 unsigned char req[500] = {
995 N7110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x10,
996 0x02, 0x00, /* memory type */
997 0x00, 0x00, /* location */
998 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1000 if (entry->Location == 0) return GE_NOTSUPPORTED;
1002 req[11] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
1003 if (req[11]==0xff) return GE_NOTSUPPORTED;
1005 req[12] = (entry->Location >> 8);
1006 req[13] = entry->Location & 0xff;
1008 count = count + N71_65_EncodePhonebookFrame(s, req+22, *entry, &blocks, true, IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_VOICETAGS));
1009 req[21] = blocks;
1011 smprintf(s, "Writing phonebook entry\n");
1012 return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetMemory);
1015 static GSM_Error N6510_ReplySetOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
1017 smprintf(s, "Operator logo set OK\n");
1018 return GE_NONE;
1021 static GSM_Error N6510_SetCallerLogo(GSM_StateMachine *s, GSM_Bitmap *bitmap)
1023 unsigned char req[500] = {
1024 N6110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x10,
1025 0xfe, 0x10, /* memory type */
1026 0x00, 0x00, /* location */
1027 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1028 char string[500];
1029 int block=0, i;
1030 unsigned int count = 22;
1031 int Width, Height;
1033 req[13] = bitmap->Location;
1035 /* Logo on/off */
1036 string[0] = bitmap->Enabled?1:0;
1037 string[1] = 0;
1038 count += N71_65_PackPBKBlock(s, N7110_ENTRYTYPE_LOGOON, 2, block++, string, req + count);
1040 /* Ringtone */
1041 if (!bitmap->DefaultRingtone) {
1042 string[0] = 0x00;
1043 string[1] = 0x00;
1044 string[2] = bitmap->Ringtone;
1045 count += N71_65_PackPBKBlock(s, N7110_ENTRYTYPE_RINGTONE, 3, block++, string, req + count);
1046 count --;
1047 req[count-5] = 8;
1050 /* Number of group */
1051 string[0] = bitmap->Location;
1052 string[1] = 0;
1053 count += N71_65_PackPBKBlock(s, N7110_ENTRYTYPE_GROUP, 2, block++, string, req + count);
1055 /* Name */
1056 if (!bitmap->DefaultName) {
1057 i = UnicodeLength(bitmap->Text) * 2;
1058 string[0] = i + 2;
1059 memcpy(string + 1, bitmap->Text, i);
1060 string[i + 1] = 0;
1061 count += N71_65_PackPBKBlock(s, N7110_ENTRYTYPE_NAME, i + 2, block++, string, req + count);
1064 /* Logo */
1065 if (!bitmap->DefaultBitmap) {
1066 PHONE_GetBitmapWidthHeight(GSM_NokiaCallerLogo, &Width, &Height);
1067 string[0] = Width;
1068 string[1] = Height;
1069 string[2] = 0;
1070 string[3] = 0;
1071 string[4] = PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0);
1072 PHONE_EncodeBitmap(GSM_NokiaCallerLogo, string + 5, bitmap);
1073 count += N71_65_PackPBKBlock(s, N7110_ENTRYTYPE_GROUPLOGO, PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 5, block++, string, req + count);
1076 req[21] = block;
1078 return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetBitmap);
1081 static GSM_Error N6510_ReplySetPicture(GSM_Protocol_Message msg, GSM_StateMachine *s)
1083 // smprintf(s, "Picture Image written OK, folder %i, location %i\n",msg.Buffer[4],msg.Buffer[5]*256+msg.Buffer[6]);
1084 return GE_NONE;
1087 static GSM_Error N6510_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
1089 GSM_SMSMessage sms;
1090 GSM_Phone_Bitmap_Types Type;
1091 int Width, Height, i, count;
1092 #ifdef DEVELOP
1093 unsigned char folderid;
1094 int location;
1095 #endif
1096 GSM_NetworkInfo NetInfo;
1097 GSM_Error error;
1098 unsigned char reqStartup[1000] = {
1099 N7110_FRAME_HEADER, 0x04, 0x0F,
1100 0x00, 0x00, 0x00,
1101 0x04, 0xC0, 0x02, 0x00,
1102 0x41, 0xC0, 0x03, 0x00,
1103 0x60, 0xC0, 0x04};
1104 unsigned char reqColourWallPaper[200] = {
1105 N6110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0xD5,
1106 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1107 0x00, 0x00, 0x00, 0x01, 0x00,
1108 0x18}; /* Bitmap ID */
1109 unsigned char reqColourStartup[200] = {
1110 N6110_FRAME_HEADER, 0x04, 0x25, 0x00, 0x01, 0x00, 0x18};
1111 unsigned char reqOp[1000] = {
1112 N7110_FRAME_HEADER, 0x25, 0x01,
1113 0x55, 0x00, 0x00, 0x55,
1114 0x01, /* 0x01 - not set, 0x02 - set */
1115 0x0C, 0x08,
1116 0x62, 0xF0, 0x10, /* Network code */
1117 0x03, 0x55, 0x55};
1118 unsigned char reqColourOp[200] = {
1119 N6110_FRAME_HEADER,
1120 0x07, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x00, 0xF9, 0x00,
1121 0x08, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00,
1122 0x18, /* File ID */
1123 0x00,
1124 0x00, 0x00, 0x00}; /* Network code */
1125 unsigned char reqNote[200] = {N6110_FRAME_HEADER, 0x04, 0x01};
1126 unsigned char reqPicture[2000] = {
1127 N6110_FRAME_HEADER, 0x00,
1128 0x02, 0x05, /* SMS folder */
1129 0x00, 0x00, /* location */
1130 0x01, 0x01, 0xa0, 0x02, 0x01, 0x40, 0x00, 0x34,
1131 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1132 0x00, 0x00, 0x55, 0x55, 0x55, 0x03, 0x82, 0x10,
1133 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x10,
1135 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04,
1137 0x00, 0x00, 0xa1, 0x55, 0x01, 0x08, 0x00, 0x00,
1138 0x00, 0x01, 0x48, 0x1c, 0x00, 0xfc, 0x00};
1140 switch (Bitmap->Type) {
1141 case GSM_ColourWallPaper:
1142 reqColourWallPaper[21] = Bitmap->ID;
1143 smprintf(s, "Setting colour wall paper\n");
1144 return GSM_WaitFor (s, reqColourWallPaper, 22, 0x43, 4, ID_SetBitmap);
1145 case GSM_StartupLogo:
1146 Type = GSM_Nokia7110StartupLogo;
1147 switch (Bitmap->Location) {
1148 case 1:
1149 PHONE_EncodeBitmap(Type, reqStartup + 22, Bitmap);
1150 break;
1151 case 2:
1152 memset(reqStartup+5,0x00,15);
1153 PHONE_ClearBitmap(Type, reqStartup + 22,0,0);
1154 break;
1155 default:
1156 return GE_NOTSUPPORTED;
1158 smprintf(s, "Setting startup logo\n");
1159 return GSM_WaitFor (s, reqStartup, 22+PHONE_GetBitmapSize(Type,0,0), 0x7A, 4, ID_SetBitmap);
1160 case GSM_DealerNoteText:
1161 reqNote[4] = 0x10;
1162 CopyUnicodeString(reqNote + 5, Bitmap->Text);
1163 i = 6 + UnicodeLength(Bitmap->Text) * 2;
1164 reqNote[i++] = 0;
1165 reqNote[i] = 0;
1166 return GSM_WaitFor (s, reqNote, i, 0x7A, 4, ID_SetBitmap);
1167 case GSM_WelcomeNoteText:
1168 CopyUnicodeString(reqNote + 5, Bitmap->Text);
1169 i = 6 + UnicodeLength(Bitmap->Text) * 2;
1170 reqNote[i++] = 0;
1171 reqNote[i] = 0;
1172 return GSM_WaitFor (s, reqNote, i, 0x7A, 4, ID_SetBitmap);
1173 case GSM_OperatorLogo:
1174 /* We want to set operator logo, not clear */
1175 if (strcmp(Bitmap->NetworkCode,"000 00")) {
1176 memset(reqOp + 19, 0, 281);
1177 NOKIA_EncodeNetworkCode(reqOp+12, Bitmap->NetworkCode);
1178 Type = GSM_Nokia6510OperatorLogo;
1179 reqOp[9] = 0x02; /* Logo enabled */
1180 reqOp[18] = 0x1a; /* FIXME */
1181 reqOp[19] = PHONE_GetBitmapSize(Type,0,0) + 8 + 29 + 2;
1182 PHONE_GetBitmapWidthHeight(Type, &Width, &Height);
1183 reqOp[20] = Width;
1184 reqOp[21] = Height;
1185 reqOp[22] = 0x00;
1186 reqOp[23] = PHONE_GetBitmapSize(Type,0,0) + 29;
1187 reqOp[24] = 0x00;
1188 reqOp[25] = PHONE_GetBitmapSize(Type,0,0) + 29;
1189 PHONE_EncodeBitmap(Type, reqOp + 26, Bitmap);
1190 smprintf(s, "Setting operator logo\n");
1191 return GSM_WaitFor (s, reqOp, reqOp[19]+reqOp[11]+10, 0x0A, 4, ID_SetBitmap);
1192 } else {
1193 error=N6510_GetNetworkInfo(s,&NetInfo);
1194 if (error != GE_NONE) return error;
1195 NOKIA_EncodeNetworkCode(reqOp+12, NetInfo.NetworkCode);
1196 smprintf(s, "Clearing operator logo\n");
1197 return GSM_WaitFor (s, reqOp, 18, 0x0A, 4, ID_SetBitmap);
1199 case GSM_ColourOperatorLogo:
1200 /* We want to set operator logo, not clear */
1201 if (strcmp(Bitmap->NetworkCode,"000 00")) {
1202 EncodeBCD(reqColourOp+23, Bitmap->NetworkCode, 6, false);
1203 reqColourOp[21] = Bitmap->ID;
1205 smprintf(s, "Setting colour operator logo\n");
1206 return GSM_WaitFor (s, reqColourOp, 26, 0x43, 4, ID_SetBitmap);
1207 case GSM_ColourStartupLogo:
1208 switch (Bitmap->Location) {
1209 case 0:
1210 reqColourStartup[6] = 0x00;
1211 reqColourStartup[8] = 0x00;
1212 smprintf(s, "Setting colour startup logo\n");
1213 return GSM_WaitFor (s, reqColourStartup, 9, 0x7A, 4, ID_SetBitmap);
1214 case 1:
1215 reqColourStartup[8] = Bitmap->ID;
1216 smprintf(s, "Setting colour startup logo\n");
1217 return GSM_WaitFor (s, reqColourStartup, 9, 0x7A, 4, ID_SetBitmap);
1218 default:
1219 return GE_NOTSUPPORTED;
1221 case GSM_CallerLogo:
1222 return N6510_SetCallerLogo(s,Bitmap);
1223 case GSM_PictureImage:
1224 error = N6510_GetPictureImage(s, Bitmap, &sms.Location);
1225 if (error == GE_NONE) {
1226 #ifdef DEVELOP
1227 sms.Folder = 0;
1228 N6510_GetSMSLocation(s, &sms, &folderid, &location);
1229 switch (folderid) {
1230 case 0x01: reqPicture[5] = 0x02; break; /* INBOX SIM */
1231 case 0x02: reqPicture[5] = 0x03; break; /* OUTBOX SIM */
1232 default : reqPicture[5] = folderid - 1; reqPicture[4] = 0x02; break; /* ME folders */
1234 reqPicture[6]=location / 256;
1235 reqPicture[7]=location;
1236 #else
1237 return GE_NOTSUPPORTED;
1238 #endif
1240 Type = GSM_NokiaPictureImage;
1241 count = 78;
1242 PHONE_EncodeBitmap(Type, reqPicture + count, Bitmap);
1243 count += PHONE_GetBitmapSize(Type,0,0);
1244 smprintf(s, "Setting Picture Image\n");
1245 return GSM_WaitFor (s, reqPicture, count, 0x14, 4, ID_SetBitmap);
1246 default:
1247 break;
1249 return GE_NOTSUPPORTED;
1252 static GSM_Error N6510_ReplyGetRingtoneID(GSM_Protocol_Message msg, GSM_StateMachine *s)
1254 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1256 smprintf(s, "Ringtone ID received\n");
1257 Priv->RingtoneID = msg.Buffer[15];
1258 return GE_NONE;
1261 static GSM_Error N6510_ReplySetBinRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
1263 smprintf(s, "Binary ringtone set\n");
1264 return GE_NONE;
1267 static GSM_Error N6510_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
1269 GSM_Error error;
1270 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1271 GSM_NetworkInfo NetInfo;
1272 int size=200, current;
1273 unsigned char GetIDReq[] = {
1274 N7110_FRAME_HEADER, 0x01, 0x00, 0x00,
1275 0x00, 0xFF, 0x06, 0xE1, 0x00,
1276 0xFF, 0x06, 0xE1, 0x01, 0x42};
1277 unsigned char SetPreviewReq[1000] = {
1278 0xAE, /* Ringtone ID */
1279 0x01, 0x00, 0x0D, 0x00,
1280 0x00, 0x00, 0x00, 0x00, 0x00,
1281 0x00}; /*Length*/
1282 unsigned char AddBinaryReq[33000] = {
1283 N7110_FRAME_HEADER, 0x0E, 0x7F, 0xFF, 0xFE};
1285 if (Ringtone->Format == RING_NOTETONE && Ringtone->Location==255)
1287 smprintf(s, "Getting ringtone ID\n");
1288 error=GSM_WaitFor (s, GetIDReq, 14, 0xDB, 4, ID_SetRingtone);
1289 if (error != GE_NONE) return error;
1290 *maxlength=GSM_EncodeNokiaRTTLRingtone(*Ringtone, SetPreviewReq+11, &size);
1291 SetPreviewReq[0] = Priv->RingtoneID;
1292 SetPreviewReq[10] = size;
1293 smprintf(s, "Setting ringtone\n");
1294 error = s->Protocol.Functions->WriteMessage(s, SetPreviewReq, size+11, 0x00);
1295 if (error!=GE_NONE) return error;
1296 my_sleep(1000);
1297 /* We have to make something (not important, what) now */
1298 /* no answer from phone*/
1299 return s->Phone.Functions->GetNetworkInfo(s,&NetInfo);
1301 if (Ringtone->Format == RING_NOKIABINARY) {
1302 AddBinaryReq[7] = UnicodeLength(Ringtone->Name);
1303 CopyUnicodeString(AddBinaryReq+8,Ringtone->Name);
1304 current = 8 + UnicodeLength(Ringtone->Name)*2;
1305 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length/256 + 1;
1306 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length%256 + 1;
1307 AddBinaryReq[current++] = 0x00;
1308 memcpy(AddBinaryReq+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length);
1309 current += Ringtone->NokiaBinary.Length;
1310 smprintf(s, "Adding binary ringtone\n");
1311 return GSM_WaitFor (s, AddBinaryReq, current, 0x1F, 4, ID_SetRingtone);
1313 if (Ringtone->Format == RING_MIDI) {
1314 AddBinaryReq[7] = UnicodeLength(Ringtone->Name);
1315 CopyUnicodeString(AddBinaryReq+8,Ringtone->Name);
1316 current = 8 + UnicodeLength(Ringtone->Name)*2;
1317 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length/256;
1318 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length%256;
1319 memcpy(AddBinaryReq+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length);
1320 current += Ringtone->NokiaBinary.Length;
1321 AddBinaryReq[current++] = 0x00;
1322 AddBinaryReq[current++] = 0x00;
1323 smprintf(s, "Adding binary or MIDI ringtone\n");
1324 return GSM_WaitFor (s, AddBinaryReq, current, 0x1F, 4, ID_SetRingtone);
1326 return GE_NOTSUPPORTED;
1329 static GSM_Error N6510_ReplyDeleteRingtones(GSM_Protocol_Message msg, GSM_StateMachine *s)
1331 smprintf(s, "Ringtones deleted\n");
1332 return GE_NONE;
1335 static GSM_Error N6510_DeleteUserRingtones(GSM_StateMachine *s)
1337 unsigned char DelAllRingtoneReq[] = {
1338 N7110_FRAME_HEADER, 0x10, 0x7F, 0xFE};
1340 smprintf(s, "Deleting all user ringtones\n");
1341 return GSM_WaitFor (s, DelAllRingtoneReq, 6, 0x1F, 4, ID_SetRingtone);
1344 static GSM_Error N6510_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press)
1346 #ifdef DEVELOP
1347 unsigned char req[] = {
1348 N6110_FRAME_HEADER, 0x11, 0x00, 0x01, 0x00, 0x00,
1349 0x00, /* Event */
1350 0x01}; /* Number of presses */
1352 // req[7] = Key;
1353 if (Press) {
1354 req[8] = NOKIA_PRESSPHONEKEY;
1355 s->Phone.Data.PressKey = true;
1356 smprintf(s, "Pressing key\n");
1357 } else {
1358 req[8] = NOKIA_RELEASEPHONEKEY;
1359 s->Phone.Data.PressKey = false;
1360 smprintf(s, "Releasing key\n");
1362 return GSM_WaitFor (s, req, 10, 0x0c, 4, ID_PressKey);
1363 #else
1364 return GE_NOTSUPPORTED;
1365 #endif
1368 static GSM_Error N6510_EnableWAPMMSSettings(GSM_StateMachine *s, bool MMS)
1370 GSM_Error error;
1371 unsigned char req1[] = {N6110_FRAME_HEADER, 0x03};
1372 unsigned char req2[] = {N6110_FRAME_HEADER, 0x00, 0x01};
1374 if (MMS && IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOMMS)) return GE_NOTSUPPORTED;
1376 error=GSM_WaitFor (s, req1, 4, 0x3f, 4, ID_EnableWAP);
1377 if (error != GE_NONE) return error;
1379 if (MMS) {
1380 dbgprintf("Enabling MMS\n");
1381 return GSM_WaitFor (s, req2, 5, 0x3f, 4, ID_EnableWAP);
1382 } else {
1383 return GSM_WaitFor (s, req2, 4, 0x3f, 4, ID_EnableWAP);
1387 static GSM_Error N6510_ReplyGetWAPMMSSettings(GSM_Protocol_Message msg, GSM_StateMachine *s)
1389 int tmp,num=0;
1390 GSM_Phone_Data *Data = &s->Phone.Data;
1392 switch(msg.Buffer[3]) {
1393 case 0x16:
1394 smprintf(s, "WAP settings received OK\n");
1396 if (Data->RequestID == ID_GetMMSSettings) {
1397 Data->WAPSettings->Number = 1;
1398 } else {
1399 Data->WAPSettings->Number = 2;
1402 tmp = 4;
1404 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].Title,true);
1405 CopyUnicodeString(Data->WAPSettings->Settings[1].Title,Data->WAPSettings->Settings[0].Title);
1406 smprintf(s, "Title: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Title));
1408 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].HomePage,true);
1409 CopyUnicodeString(Data->WAPSettings->Settings[1].HomePage,Data->WAPSettings->Settings[0].HomePage);
1410 smprintf(s, "Homepage: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].HomePage));
1412 #ifdef DEBUG
1413 smprintf(s, "Connection type: ");
1414 switch (msg.Buffer[tmp]) {
1415 case 0x00: smprintf(s, "temporary\n"); break;
1416 case 0x01: smprintf(s, "continuous\n"); break;
1417 default: smprintf(s, "unknown\n");
1419 smprintf(s, "Connection security: ");
1420 switch (msg.Buffer[tmp+1]) {
1421 case 0x00: smprintf(s, "off\n"); break;
1422 case 0x01: smprintf(s, "on\n"); break;
1423 default: smprintf(s, "unknown\n");
1425 smprintf(s, "Bearer: ");
1426 switch (msg.Buffer[tmp+2]) {
1427 case 0x01: smprintf(s, "GSM data\n"); break;
1428 case 0x03: smprintf(s, "GPRS\n"); break;
1429 default: smprintf(s, "unknown\n");
1431 #endif
1432 Data->WAPSettings->Settings[0].IsContinuous = false;
1433 if (msg.Buffer[tmp] == 0x01) Data->WAPSettings->Settings[0].IsContinuous = true;
1434 Data->WAPSettings->Settings[1].IsContinuous = Data->WAPSettings->Settings[0].IsContinuous;
1436 Data->WAPSettings->Settings[0].IsSecurity = false;
1437 if (msg.Buffer[tmp+1] == 0x01) Data->WAPSettings->Settings[0].IsSecurity = true;
1438 Data->WAPSettings->Settings[1].IsSecurity = Data->WAPSettings->Settings[0].IsSecurity;
1440 Data->WAPSettings->ActiveBearer = WAPSETTINGS_BEARER_DATA;
1441 if (msg.Buffer[tmp+2] == 0x03) Data->WAPSettings->ActiveBearer = WAPSETTINGS_BEARER_GPRS;
1443 tmp+=3;
1445 if (Data->RequestID == ID_GetWAPSettings) {
1446 /* Here starts settings for data bearer */
1447 Data->WAPSettings->Settings[0].Bearer = WAPSETTINGS_BEARER_DATA;
1448 while ((msg.Buffer[tmp] != 0x01) || (msg.Buffer[tmp + 1] != 0x00)) tmp++;
1449 tmp += 4;
1451 #ifdef DEBUG
1452 smprintf(s, "Authentication type: ");
1453 switch (msg.Buffer[tmp]) {
1454 case 0x00: smprintf(s, "normal\n"); break;
1455 case 0x01: smprintf(s, "secure\n"); break;
1456 default: smprintf(s, "unknown\n"); break;
1458 smprintf(s, "Data call type: ");
1459 switch (msg.Buffer[tmp+1]) {
1460 case 0x00: smprintf(s, "analogue\n"); break;
1461 case 0x01: smprintf(s, "ISDN\n"); break;
1462 default: smprintf(s, "unknown\n"); break;
1464 smprintf(s, "Data call speed: ");
1465 switch (msg.Buffer[tmp+2]) {
1466 case 0x00: smprintf(s, "automatic\n"); break;
1467 case 0x01: smprintf(s, "9600\n"); break;
1468 case 0x02: smprintf(s, "14400\n"); break;
1469 default: smprintf(s, "unknown\n"); break;
1471 smprintf(s, "Login Type: ");
1472 switch (msg.Buffer[tmp+4]) {
1473 case 0x00: smprintf(s, "manual\n"); break;
1474 case 0x01: smprintf(s, "automatic\n"); break;
1475 default: smprintf(s, "unknown\n"); break;
1477 #endif
1478 Data->WAPSettings->Settings[0].IsNormalAuthentication=true;
1479 if (msg.Buffer[tmp]==0x01) Data->WAPSettings->Settings[0].IsNormalAuthentication=false;
1481 Data->WAPSettings->Settings[0].IsISDNCall=false;
1482 if (msg.Buffer[tmp+1]==0x01) Data->WAPSettings->Settings[0].IsISDNCall=true;
1484 switch (msg.Buffer[tmp+2]) {
1485 case 0x00: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_AUTO; break;
1486 case 0x01: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_9600; break;
1487 case 0x02: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_14400; break;
1490 Data->WAPSettings->Settings[0].ManualLogin=false;
1491 if (msg.Buffer[tmp+4]==0x00) Data->WAPSettings->Settings[0].ManualLogin = true;
1493 tmp+=5;
1495 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].IPAddress,false);
1496 smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].IPAddress));
1498 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].DialUp,true);
1499 smprintf(s, "Dial-up number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].DialUp));
1501 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].User,true);
1502 smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].User));
1504 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].Password,true);
1505 smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Password));
1507 num = 1;
1508 } else {
1509 num = 0;
1512 /* Here starts settings for gprs bearer */
1513 Data->WAPSettings->Settings[num].Bearer = WAPSETTINGS_BEARER_GPRS;
1514 while (msg.Buffer[tmp] != 0x03) tmp++;
1515 tmp += 4;
1517 #ifdef DEBUG
1518 smprintf(s, "Authentication type: ");
1519 switch (msg.Buffer[tmp]) {
1520 case 0x00: smprintf(s, "normal\n"); break;
1521 case 0x01: smprintf(s, "secure\n"); break;
1522 default: smprintf(s, "unknown\n"); break;
1524 smprintf(s, "GPRS connection: ");
1525 switch (msg.Buffer[tmp+1]) {
1526 case 0x00: smprintf(s, "ALWAYS online\n"); break;
1527 case 0x01: smprintf(s, "when needed\n"); break;
1528 default: smprintf(s, "unknown\n"); break;
1530 smprintf(s, "Login Type: ");
1531 switch (msg.Buffer[tmp+2]) {
1532 case 0x00: smprintf(s, "manual\n"); break;
1533 case 0x01: smprintf(s, "automatic\n"); break;
1534 default: smprintf(s, "unknown\n"); break;
1536 #endif
1537 Data->WAPSettings->Settings[num].IsNormalAuthentication=true;
1538 if (msg.Buffer[tmp]==0x01) Data->WAPSettings->Settings[num].IsNormalAuthentication=false;
1540 Data->WAPSettings->Settings[num].IsContinuous = true;
1541 if (msg.Buffer[tmp+1] == 0x01) Data->WAPSettings->Settings[num].IsContinuous = false;
1543 Data->WAPSettings->Settings[num].ManualLogin=false;
1544 if (msg.Buffer[tmp+2]==0x00) Data->WAPSettings->Settings[num].ManualLogin = true;
1546 tmp+=3;
1548 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].DialUp,false);
1549 smprintf(s, "Access point: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].DialUp));
1551 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].IPAddress,true);
1552 smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].IPAddress));
1554 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].User,true);
1555 smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].User));
1557 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].Password,true);
1558 smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].Password));
1560 return GE_NONE;
1561 case 0x17:
1562 smprintf(s, "WAP settings receiving error\n");
1563 switch (msg.Buffer[4]) {
1564 case 0x01:
1565 smprintf(s, "Security error. Inside WAP settings menu\n");
1566 return GE_INSIDEPHONEMENU;
1567 case 0x02:
1568 smprintf(s, "Invalid or empty\n");
1569 return GE_INVALIDLOCATION;
1570 default:
1571 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
1572 return GE_UNKNOWNRESPONSE;
1574 break;
1576 return GE_UNKNOWNRESPONSE;
1579 static GSM_Error N6510_GetWAPMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings, bool MMS)
1581 GSM_Error error;
1582 unsigned char req[] = {
1583 N6110_FRAME_HEADER, 0x15,
1584 0x00}; /* Location */
1586 error = N6510_EnableWAPMMSSettings(s, MMS);
1587 if (error!=GE_NONE) return error;
1589 req[4] = settings->Location-1;
1590 s->Phone.Data.WAPSettings = settings;
1591 if (MMS) {
1592 smprintf(s, "Getting MMS settings\n");
1593 error=GSM_WaitFor (s, req, 5, 0x3f, 4, ID_GetMMSSettings);
1594 } else {
1595 smprintf(s, "Getting WAP settings\n");
1596 error=GSM_WaitFor (s, req, 5, 0x3f, 4, ID_GetWAPSettings);
1598 if (error != GE_NONE) return error;
1600 return DCT3DCT4_GetActiveWAPMMSSet(s);
1603 static GSM_Error N6510_GetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
1605 return N6510_GetWAPMMSSettings(s, settings, false);
1608 static GSM_Error N6510_GetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
1610 return N6510_GetWAPMMSSettings(s, settings, true);
1613 static GSM_Error N6510_ReplySetWAPMMSSettings(GSM_Protocol_Message msg, GSM_StateMachine *s)
1615 switch (msg.Buffer[3]) {
1616 case 0x19:
1617 smprintf(s, "WAP settings cleaned\n");
1618 return GE_NONE;
1619 case 0x1a:
1620 smprintf(s, "WAP settings setting status\n");
1621 switch (msg.Buffer[4]) {
1622 case 0x01:
1623 smprintf(s, "Security error. Inside WAP settings menu\n");
1624 return GE_INSIDEPHONEMENU;
1625 case 0x03:
1626 smprintf(s, "Invalid location\n");
1627 return GE_INVALIDLOCATION;
1628 case 0x05:
1629 smprintf(s, "Written OK\n");
1630 return GE_NONE;
1631 default:
1632 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
1633 return GE_UNKNOWNRESPONSE;
1636 return GE_UNKNOWNRESPONSE;
1639 static GSM_Error N6510_SetWAPMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings, bool MMS)
1641 GSM_Error error;
1642 int i, pad = 0, length, pos = 5, loc1=-1,loc2=-1;
1643 unsigned char req[1000] = {
1644 N6110_FRAME_HEADER, 0x18,
1645 0x00}; /* Location */
1647 error = N6510_EnableWAPMMSSettings(s, MMS);
1648 if (error!=GE_NONE) return error;
1650 memset(req + pos, 0, 1000 - pos);
1652 req[4] = settings->Location-1;
1654 for (i=0;i<settings->Number;i++) {
1655 if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_DATA) loc1=i;
1656 if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_GPRS) loc2=i;
1659 if (loc1 != -1) {
1660 /* Name */
1661 length = UnicodeLength(settings->Settings[loc1].Title);
1662 if (!(length % 2)) pad = 1;
1663 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].Title, false);
1665 /* Home */
1666 length = UnicodeLength(settings->Settings[loc1].HomePage);
1667 if (((length + pad) % 2)) pad = 2; else pad = 0;
1668 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].HomePage, true);
1670 if (settings->Settings[loc1].IsContinuous) req[pos] = 0x01; pos++;
1671 if (settings->Settings[loc1].IsSecurity) req[pos] = 0x01; pos++;
1672 } else if (loc2 != -1) {
1673 /* Name */
1674 length = UnicodeLength(settings->Settings[loc2].Title);
1675 if (!(length % 2)) pad = 1;
1676 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].Title, false);
1678 /* Home */
1679 length = UnicodeLength(settings->Settings[loc2].HomePage);
1680 if (((length + pad) % 2)) pad = 2; else pad = 0;
1681 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].HomePage, true);
1683 if (settings->Settings[loc2].IsContinuous) req[pos] = 0x01; pos++;
1684 if (settings->Settings[loc2].IsSecurity) req[pos] = 0x01; pos++;
1685 } else {
1686 /* Name */
1687 length = 0;
1688 if (!(length % 2)) pad = 1;
1689 pos ++;
1691 /* Home */
1692 length = 0;
1693 if (((length + pad) % 2)) pad = 2; else pad = 0;
1694 pos += 2;
1696 pos += 2;
1699 if (MMS) {
1700 req[pos++] = 0x03; //GPRS
1702 /* How many parts do we send? */
1703 req[pos++] = 0x01; pos += pad;
1704 } else {
1705 if (settings->ActiveBearer == WAPSETTINGS_BEARER_GPRS && loc2 != -1) {
1706 req[pos++] = 0x03; //GPRS
1707 } else {
1708 req[pos++] = 0x01; //data set
1710 /* How many parts do we send? */
1711 req[pos++] = 0x02; pos += pad;
1713 /* GSM data */
1714 memcpy(req + pos, "\x01\x00", 2); pos += 2;
1716 if (loc1 != -1) {
1717 length = UnicodeLength(settings->Settings[loc1].IPAddress)*2+1;
1718 length += UnicodeLength(settings->Settings[loc1].DialUp) *2+2;
1719 length += UnicodeLength(settings->Settings[loc1].User) *2+2;
1720 length += UnicodeLength(settings->Settings[loc1].Password) *2+2;
1721 } else {
1722 length = 1 + 2 + 2 + 2;
1724 length += 11;
1725 req[pos++] = length / 256;
1726 req[pos++] = length % 256;
1728 if (loc1 != -1) {
1729 if (!settings->Settings[loc1].IsNormalAuthentication) req[pos]=0x01; pos++;
1730 if (settings->Settings[loc1].IsISDNCall) req[pos]=0x01; pos++;
1731 switch (settings->Settings[loc1].Speed) {
1732 case WAPSETTINGS_SPEED_AUTO : break;
1733 case WAPSETTINGS_SPEED_9600 : req[pos]=0x01; break;
1734 case WAPSETTINGS_SPEED_14400 : req[pos]=0x02; break;
1736 pos++;
1737 req[pos++]=0x01;
1738 if (!settings->Settings[loc1].ManualLogin) req[pos] = 0x01; pos++;
1740 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].IPAddress, false);
1741 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].DialUp, true);
1742 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].User, true);
1743 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].Password, true);
1744 } else {
1745 pos += 3;
1746 req[pos++]=0x01;
1747 pos += 8;
1750 /* Padding */
1751 pos+=2;
1754 /* GPRS block */
1755 memcpy(req + pos, "\x03\x00", 2); pos += 2;
1757 if (loc2 != -1) {
1758 length = UnicodeLength(settings->Settings[loc2].DialUp) *2+1;
1759 length += UnicodeLength(settings->Settings[loc2].IPAddress)*2+2;
1760 length += UnicodeLength(settings->Settings[loc2].User) *2+2;
1761 length += UnicodeLength(settings->Settings[loc2].Password) *2+2;
1762 } else {
1763 length = 7;
1765 length += 7;
1766 req[pos++] = length / 256;
1767 req[pos++] = length % 256;
1769 if (loc2 != -1) {
1770 if (!settings->Settings[loc2].IsNormalAuthentication) req[pos] = 0x01; pos++;
1771 if (!settings->Settings[loc2].IsContinuous) req[pos] = 0x01; pos++;
1772 if (!settings->Settings[loc2].ManualLogin) req[pos] = 0x01; pos++;
1774 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].DialUp, false);
1775 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].IPAddress, true);
1776 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].User, true);
1777 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].Password, true);
1778 } else {
1779 pos += 10;
1782 /* end of blocks ? */
1783 memcpy(req + pos, "\x80\x00\x00\x0c", 4); pos += 4;
1785 if (MMS) {
1786 smprintf(s, "Setting MMS settings\n");
1787 error = GSM_WaitFor (s, req, pos, 0x3f, 4, ID_SetMMSSettings);
1788 } else {
1789 smprintf(s, "Setting WAP settings\n");
1790 error = GSM_WaitFor (s, req, pos, 0x3f, 4, ID_SetWAPSettings);
1792 if (error != GE_NONE) return error;
1793 return DCT3DCT4_SetActiveWAPMMSSet(s, settings, MMS);
1796 static GSM_Error N6510_SetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
1798 return N6510_SetWAPMMSSettings(s, settings, false);
1801 static GSM_Error N6510_SetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
1803 return N6510_SetWAPMMSSettings(s, settings, true);
1806 static GSM_Error N6510_ReplyGetOriginalIMEI(GSM_Protocol_Message msg, GSM_StateMachine *s)
1808 if (msg.Buffer[7] == 0x00) {
1809 smprintf(s, "No SIM card\n");
1810 return GE_SECURITYERROR;
1811 } else {
1812 return NOKIA_ReplyGetPhoneString(msg, s);
1816 static GSM_Error N6510_GetOriginalIMEI(GSM_StateMachine *s, char *value)
1818 return NOKIA_GetPhoneString(s,"\x00\x07\x02\x01\x00\x01",6,0x42,value,ID_GetOriginalIMEI,14);
1821 static GSM_Error N6510_SetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
1823 GSM_Error error;
1824 int count;
1825 int location;
1826 unsigned char req[600] = { N6110_FRAME_HEADER, 0x09 };
1828 /* We have to enable WAP frames in phone */
1829 error=DCT3DCT4_EnableWAP(s);
1830 if (error!=GE_NONE) return error;
1832 if (bookmark->Location == 0) {
1833 location = 0xffff;
1834 } else {
1835 location = bookmark->Location - 1;
1837 count = 4;
1838 req[count++] = (location & 0xff00) >> 8;
1839 req[count++] = (location & 0x00ff);
1841 req[count++] = 0x00;
1842 req[count++] = UnicodeLength(bookmark->Title);
1843 CopyUnicodeString(req+count,bookmark->Title);
1844 count = count + 2*UnicodeLength(bookmark->Title);
1846 req[count++] = 0x00;
1847 req[count++] = UnicodeLength(bookmark->Address);
1848 CopyUnicodeString(req+count,bookmark->Address);
1849 count = count + 2*UnicodeLength(bookmark->Address);
1851 req[count++] = 0x00;
1852 req[count++] = 0x00;
1853 req[count++] = 0x00;
1854 req[count++] = 0x00;
1856 smprintf(s, "Setting WAP bookmark\n");
1857 return GSM_WaitFor (s, req, count, 0x3f, 4, ID_SetWAPBookmark);
1860 static GSM_Error N6510_ReplyGetSMSStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
1862 GSM_Phone_Data *Data = &s->Phone.Data;
1864 switch (msg.Buffer[3]) {
1865 case 0x09:
1866 switch (msg.Buffer[4]) {
1867 case 0x00:
1868 smprintf(s, "Max. in phone memory : %i\n",msg.Buffer[10]*256+msg.Buffer[11]);
1869 smprintf(s, "Used in phone memory : %i\n",msg.Buffer[12]*256+msg.Buffer[13]);
1870 smprintf(s, "Unread in phone memory : %i\n",msg.Buffer[14]*256+msg.Buffer[15]);
1871 smprintf(s, "Max. in SIM : %i\n",msg.Buffer[22]*256+msg.Buffer[23]);
1872 smprintf(s, "Used in SIM : %i\n",msg.Buffer[24]*256+msg.Buffer[25]);
1873 smprintf(s, "Unread in SIM : %i\n",msg.Buffer[26]*256+msg.Buffer[27]);
1874 Data->SMSStatus->PhoneSize = msg.Buffer[10]*256+msg.Buffer[11];
1875 Data->SMSStatus->PhoneUsed = msg.Buffer[12]*256+msg.Buffer[13];
1876 Data->SMSStatus->PhoneUnRead = msg.Buffer[14]*256+msg.Buffer[15];
1877 Data->SMSStatus->SIMSize = msg.Buffer[22]*256+msg.Buffer[23];
1878 Data->SMSStatus->SIMUsed = msg.Buffer[24]*256+msg.Buffer[25];
1879 Data->SMSStatus->SIMUnRead = msg.Buffer[26]*256+msg.Buffer[27];
1880 return GE_NONE;
1881 case 0x0f:
1882 smprintf(s, "No PIN\n");
1883 return GE_SECURITYERROR;
1884 default:
1885 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
1886 return GE_UNKNOWNRESPONSE;
1888 case 0x1a:
1889 smprintf(s, "Wait a moment. Phone is during power on and busy now\n");
1890 return GE_SECURITYERROR;
1892 return GE_UNKNOWNRESPONSE;
1895 static GSM_Error N6510_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status)
1897 GSM_Error error;
1898 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1899 unsigned char req[] = {N6110_FRAME_HEADER, 0x08, 0x00, 0x00};
1901 s->Phone.Data.SMSStatus=status;
1902 smprintf(s, "Getting SMS status\n");
1903 error = GSM_WaitFor (s, req, 6, 0x14, 2, ID_GetSMSStatus);
1904 if (error != GE_NONE) return error;
1906 #ifndef ENABLE_LGPL
1907 /* Nokia 6310 and family does not show not "fixed" messages from the
1908 * Templates folder, ie. when you save a message to the Templates folder,
1909 * SMSStatus does not change! Workaround: get Templates folder status, which
1910 * does show these messages.
1912 #endif
1913 error = N6510_GetSMSFolderStatus(s, 0x06);
1914 if (error != GE_NONE) return error;
1915 status->TemplatesUsed = Priv->LastSMSFolder.Number;
1917 return error;
1920 static GSM_Error N6510_ReplyDeleteSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
1922 switch (msg.Buffer[3]) {
1923 case 0x05:
1924 smprintf(s, "SMS deleted OK\n");
1925 return GE_NONE;
1926 case 0x06:
1927 switch (msg.Buffer[4]) {
1928 case 0x02:
1929 smprintf(s, "Invalid location\n");
1930 return GE_INVALIDLOCATION;
1931 default:
1932 smprintf(s, "Unknown error: %02x\n",msg.Buffer[4]);
1933 return GE_UNKNOWNRESPONSE;
1936 return GE_UNKNOWNRESPONSE;
1939 static GSM_Error N6510_DeleteSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
1941 unsigned char folderid;
1942 int location;
1943 unsigned char req[] = {
1944 N6110_FRAME_HEADER, 0x04,
1945 0x01, /* 0x01 for SM, 0x02 for ME */
1946 0x00, /* FolderID */
1947 0x00, 0x02, /* Location */
1948 0x0F, 0x55};
1950 N6510_GetSMSLocation(s, sms, &folderid, &location);
1952 switch (folderid) {
1953 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
1954 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
1955 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */
1957 req[6]=location / 256;
1958 req[7]=location;
1960 smprintf(s, "Deleting sms\n");
1961 return GSM_WaitFor (s, req, 10, 0x14, 4, ID_DeleteSMSMessage);
1964 static GSM_Error N6510_ReplySendSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
1966 switch (msg.Buffer[8]) {
1967 case 0x00:
1968 smprintf(s, "SMS sent OK\n");
1969 if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,0);
1970 return GE_NONE;
1971 default:
1972 smprintf(s, "SMS not sent OK, error code probably %i\n",msg.Buffer[8]);
1973 if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,msg.Buffer[8]);
1974 return GE_NONE;
1978 static GSM_Error N6510_SendSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
1980 int length = 11;
1981 GSM_Error error;
1982 GSM_SMSMessageLayout Layout;
1983 unsigned char req [300] = {
1984 N6110_FRAME_HEADER, 0x02, 0x00, 0x00, 0x00, 0x55, 0x55};
1986 if (sms->PDU == SMS_Deliver) sms->PDU = SMS_Submit;
1987 memset(req+9,0x00,sizeof(req) - 9);
1988 error=N6510_EncodeSMSFrame(s, sms, req + 9, &Layout, &length);
1989 if (error != GE_NONE) return error;
1991 smprintf(s, "Sending sms\n");
1992 return s->Protocol.Functions->WriteMessage(s, req, length + 9, 0x02);
1995 static GSM_Error N6510_ReplyGetSecurityStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
1997 GSM_Phone_Data *Data = &s->Phone.Data;
1999 smprintf(s, "Security Code status received: ");
2000 switch (msg.Buffer[4]) {
2001 case 0x01 : smprintf(s, "waiting for Security Code.\n"); *Data->SecurityStatus = GSCT_SecurityCode; break;
2002 case 0x07 :
2003 case 0x02 : smprintf(s, "waiting for PIN.\n"); *Data->SecurityStatus = GSCT_Pin; break;
2004 case 0x03 : smprintf(s, "waiting for PUK.\n"); *Data->SecurityStatus = GSCT_Puk; break;
2005 case 0x05 : smprintf(s, "PIN ok, SIM ok\n"); *Data->SecurityStatus = GSCT_None; break;
2006 case 0x06 : smprintf(s, "No input status\n"); *Data->SecurityStatus = GSCT_None; break;
2007 case 0x16 : smprintf(s, "No SIM!\n"); *Data->SecurityStatus = GSCT_None; break;
2008 case 0x1A : smprintf(s, "SIM rejected!\n"); *Data->SecurityStatus = GSCT_None; break;
2009 default : smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
2010 return GE_UNKNOWNRESPONSE;
2012 return GE_NONE;
2015 static GSM_Error N6510_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status)
2017 unsigned char req[5] = {N6110_FRAME_HEADER, 0x11, 0x00};
2019 s->Phone.Data.SecurityStatus=Status;
2020 smprintf(s, "Getting security code status\n");
2021 return GSM_WaitFor (s, req, 5, 0x08, 2, ID_GetSecurityStatus);
2024 static GSM_Error N6510_ReplyEnterSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s)
2026 switch (msg.Buffer[3]) {
2027 case 0x08:
2028 smprintf(s, "Security code OK\n");
2029 return GE_NONE;
2030 case 0x09:
2031 switch (msg.Buffer[4]) {
2032 case 0x06:
2033 smprintf(s, "Wrong PIN\n");
2034 return GE_SECURITYERROR;
2035 case 0x09:
2036 smprintf(s, "Wrong PUK\n");
2037 return GE_SECURITYERROR;
2038 default:
2039 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
2042 return GE_UNKNOWNRESPONSE;
2045 static GSM_Error N6510_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode Code)
2047 int len = 0;
2048 unsigned char req[15] = {
2049 N6110_FRAME_HEADER, 0x07,
2050 0x00}; /* Type of the entered code: 0x02 PIN, 0x03 PUK */
2052 switch (Code.Type) {
2053 case GSCT_Pin : req[4] = 0x02; break;
2054 default : return GE_NOTSUPPORTED;
2057 len = strlen(Code.Code);
2058 memcpy(req+5,Code.Code,len);
2059 req[5+len]=0x00;
2061 smprintf(s, "Entering security code\n");
2062 return GSM_WaitFor (s, req, 6+len, 0x08, 4, ID_EnterSecurityCode);
2065 static GSM_Error N6510_ReplySaveSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
2067 unsigned char folder;
2068 GSM_Phone_Data *Data = &s->Phone.Data;
2070 switch (msg.Buffer[3]) {
2071 case 0x01:
2072 switch (msg.Buffer[4]) {
2073 case 0x00:
2074 smprintf(s, "Done OK\n");
2075 smprintf(s, "Folder info: %i %i\n",msg.Buffer[8],msg.Buffer[5]);
2076 switch (msg.Buffer[8]) {
2077 case 0x02 : if (msg.Buffer[5] == 0x02) {
2078 folder = 0x02; /* INBOX ME */
2079 } else {
2080 folder = 0x01; /* INBOX SIM */
2082 break;
2083 case 0x03 : if (msg.Buffer[5] == 0x02) {
2084 folder = 0x04; /* OUTBOX ME */
2085 } else {
2086 folder = 0x03; /* OUTBOX SIM */
2088 break;
2089 default : folder = msg.Buffer[8] + 1;
2091 N6510_SetSMSLocation(s, Data->SaveSMSMessage,folder,msg.Buffer[6]*256+msg.Buffer[7]);
2092 smprintf(s, "Saved in folder %i at location %i\n",folder, msg.Buffer[6]*256+msg.Buffer[7]);
2093 Data->SaveSMSMessage->Folder = folder;
2094 return GE_NONE;
2095 case 0x02:
2096 printf("Incorrect location\n");
2097 return GE_INVALIDLOCATION;
2098 case 0x05:
2099 printf("Incorrect folder\n");
2100 return GE_INVALIDLOCATION;
2101 default:
2102 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
2103 return GE_UNKNOWNRESPONSE;
2105 case 0x17:
2106 smprintf(s, "SMS name changed\n");
2107 return GE_NONE;
2109 return GE_UNKNOWNRESPONSE;
2112 static GSM_Error N6510_PrivSetSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
2114 int location, length = 11;
2115 unsigned char folderid, folder;
2116 GSM_SMSMessageLayout Layout;
2117 GSM_Error error;
2118 unsigned char req [300] = {
2119 N6110_FRAME_HEADER, 0x00,
2120 0x01, /* 1 = SIM, 2 = ME */
2121 0x02, /* Folder */
2122 0x00, 0x01, /* Location */
2123 0x01}; /* SMS state */
2124 unsigned char NameReq[200] = {
2125 N6110_FRAME_HEADER, 0x16,
2126 0x01, /* 1 = SIM, 2 = ME */
2127 0x02, /* Folder */
2128 0x00, 0x01}; /* Location */
2130 N6510_GetSMSLocation(s, sms, &folderid, &location);
2131 switch (folderid) {
2132 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
2133 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
2134 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */
2136 req[6]=location / 256;
2137 req[7]=location;
2139 switch (sms->PDU) {
2140 case SMS_Submit:
2141 /* Inbox */
2142 if (folderid == 0x01 || folderid == 0x03) sms->PDU = SMS_Deliver;
2143 break;
2144 case SMS_Deliver:
2145 /* SIM Outbox */
2146 if (folderid == 0x02) sms->PDU = SMS_Submit;
2147 break;
2148 default:
2149 return GE_UNKNOWN;
2151 if (sms->PDU == SMS_Deliver) {
2152 switch (sms->State) {
2153 case GSM_Sent : /* We use GSM_Read, because phone return error */
2154 case GSM_Read : req[8] = 0x01; break;
2155 case GSM_UnSent : /* We use GSM_UnRead, because phone return error */
2156 case GSM_UnRead : req[8] = 0x03; break;
2158 } else {
2159 switch (sms->State) {
2160 case GSM_Sent : /* We use GSM_Sent, because phone change folder */
2161 case GSM_Read : req[8] = 0x05; break;
2162 case GSM_UnSent : /* We use GSM_UnSent, because phone change folder */
2163 case GSM_UnRead : req[8] = 0x07; break;
2166 memset(req+9,0x00,sizeof(req) - 9);
2167 error=N6510_EncodeSMSFrame(s, sms, req + 9, &Layout, &length);
2168 if (error != GE_NONE) return error;
2170 s->Phone.Data.SaveSMSMessage=sms;
2171 smprintf(s, "Saving sms\n");
2172 error=GSM_WaitFor (s, req, length+9, 0x14, 4, ID_SaveSMSMessage);
2173 if (error == GE_NONE && UnicodeLength(sms->Name)!=0) {
2174 folder = sms->Folder;
2175 sms->Folder = 0;
2176 N6510_GetSMSLocation(s, sms, &folderid, &location);
2177 switch (folderid) {
2178 case 0x01: NameReq[5] = 0x02; break; /* INBOX SIM */
2179 case 0x02: NameReq[5] = 0x03; break; /* OUTBOX SIM */
2180 default : NameReq[5] = folderid - 1; NameReq[4] = 0x02; break; /* ME folders */
2182 NameReq[6]=location / 256;
2183 NameReq[7]=location;
2184 length = 8;
2185 CopyUnicodeString(NameReq+length, sms->Name);
2186 length = length+UnicodeLength(sms->Name)*2;
2187 NameReq[length++] = 0;
2188 NameReq[length++] = 0;
2189 error=GSM_WaitFor (s, NameReq, length, 0x14, 4, ID_SaveSMSMessage);
2190 sms->Folder = folder;
2192 return error;
2195 static GSM_Error N6510_SetSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2197 int location;
2198 unsigned char folderid;
2200 N6510_GetSMSLocation(s, sms, &folderid, &location);
2201 if (location == 0) return GE_INVALIDLOCATION;
2202 return N6510_PrivSetSMSMessage(s, sms);
2205 static GSM_Error N6510_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2207 int location;
2208 unsigned char folderid;
2210 N6510_GetSMSLocation(s, sms, &folderid, &location);
2211 location = 0;
2212 N6510_SetSMSLocation(s, sms, folderid, location);
2213 return N6510_PrivSetSMSMessage(s, sms);
2216 static GSM_Error N6510_ReplyGetDateTime(GSM_Protocol_Message msg, GSM_StateMachine *s)
2218 smprintf(s, "Date & time received\n");
2219 if (msg.Buffer[4]==0x01) {
2220 NOKIA_DecodeDateTime(s, msg.Buffer+10, s->Phone.Data.DateTime);
2221 return GE_NONE;
2223 smprintf(s, "Not set in phone\n");
2224 return GE_EMPTY;
2227 static GSM_Error N6510_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
2229 unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x00, 0x00};
2231 s->Phone.Data.DateTime=date_time;
2232 smprintf(s, "Getting date & time\n");
2233 return GSM_WaitFor (s, req, 6, 0x19, 4, ID_GetDateTime);
2236 static GSM_Error N6510_ReplySetDateTime(GSM_Protocol_Message msg, GSM_StateMachine *s)
2238 smprintf(s, "Date & time set\n");
2239 return GE_NONE;
2242 static GSM_Error N6510_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
2244 unsigned char req[] = {
2245 N6110_FRAME_HEADER,
2246 0x01, 0x00, 0x01, 0x01, 0x0c, 0x01, 0x03,
2247 0x07, 0xd2, /* Year */
2248 0x08, 0x01, /* Month & Day */
2249 0x15, 0x1f, /* Hours & Minutes */
2250 0x2b, /* Second ? */
2251 0x00};
2253 NOKIA_EncodeDateTime(s, req+10, date_time);
2254 req[16] = date_time->Second;
2255 smprintf(s, "Setting date & time\n");
2256 return GSM_WaitFor (s, req, 18, 0x19, 4, ID_SetDateTime);
2259 static GSM_Error N6510_ReplyGetManufactureMonth(GSM_Protocol_Message msg, GSM_StateMachine *s)
2261 if (msg.Buffer[7] == 0x00) {
2262 smprintf(s, "No SIM card\n");
2263 return GE_SECURITYERROR;
2264 } else {
2265 sprintf(s->Phone.Data.PhoneString,"%02i/%04i",msg.Buffer[13],msg.Buffer[14]*256+msg.Buffer[15]);
2266 return GE_NONE;
2270 static GSM_Error N6510_GetManufactureMonth(GSM_StateMachine *s, char *value)
2272 unsigned char req[6] = {0x00, 0x05, 0x02, 0x01, 0x00, 0x02};
2273 // unsigned char req[6] = {0x00, 0x03, 0x04, 0x0B, 0x01, 0x00};
2275 s->Phone.Data.PhoneString=value;
2276 smprintf(s, "Getting manufacture month\n");
2277 return GSM_WaitFor (s, req, 6, 0x42, 2, ID_GetManufactureMonth);
2278 // return GSM_WaitFor (s, req, 6, 0x1B, 2, ID_GetManufactureMonth);
2281 static GSM_Error N6510_ReplyGetAlarm(GSM_Protocol_Message msg, GSM_StateMachine *s)
2283 GSM_Phone_Data *Data = &s->Phone.Data;
2285 switch(msg.Buffer[3]) {
2286 case 0x1A:
2287 smprintf(s, " Alarm: %02d:%02d\n", msg.Buffer[14], msg.Buffer[15]);
2288 Data->Alarm->Repeating = true;
2289 Data->Alarm->Text[0] = 0;
2290 Data->Alarm->Text[1] = 0;
2291 Data->Alarm->DateTime.Hour = msg.Buffer[14];
2292 Data->Alarm->DateTime.Minute = msg.Buffer[15];
2293 Data->Alarm->DateTime.Second = 0;
2294 return GE_NONE;
2295 case 0x20:
2296 smprintf(s, "Alarm state received\n");
2297 if (msg.Buffer[37] == 0x01) {
2298 smprintf(s, " Not set in phone\n");
2299 return GE_EMPTY;
2301 smprintf(s, "Enabled\n");
2302 return GE_NONE;
2304 return GE_UNKNOWNRESPONSE;
2307 static GSM_Error N6510_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm)
2309 unsigned char StateReq[] = {N6110_FRAME_HEADER, 0x1f, 0x01, 0x00};
2310 unsigned char GetReq [] = {N6110_FRAME_HEADER, 0x19, 0x00, 0x02};
2311 GSM_Error error;
2313 if (alarm->Location != 1) return GE_NOTSUPPORTED;
2315 s->Phone.Data.Alarm=alarm;
2316 smprintf(s, "Getting alarm state\n");
2317 error = GSM_WaitFor (s, StateReq, 6, 0x19, 4, ID_GetAlarm);
2318 if (error != GE_NONE) return error;
2320 smprintf(s, "Getting alarm\n");
2321 return GSM_WaitFor (s, GetReq, 6, 0x19, 4, ID_GetAlarm);
2324 static GSM_Error N6510_ReplySetAlarm(GSM_Protocol_Message msg, GSM_StateMachine *s)
2326 smprintf(s, "Alarm set\n");
2327 return GE_NONE;
2330 static GSM_Error N6510_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm)
2332 unsigned char req[] = {
2333 N6110_FRAME_HEADER,
2334 0x11, 0x00, 0x01, 0x01, 0x0c, 0x02,
2335 0x01, 0x00, 0x00, 0x00, 0x00,
2336 0x00, 0x00, /* Hours, Minutes */
2337 0x00, 0x00, 0x00 };
2339 if (alarm->Location != 1) return GE_NOTSUPPORTED;
2341 req[14] = alarm->DateTime.Hour;
2342 req[15] = alarm->DateTime.Minute;
2344 smprintf(s, "Setting alarm\n");
2345 return GSM_WaitFor (s, req, 19, 0x19, 4, ID_SetAlarm);
2348 static GSM_Error N6510_ReplyGetRingtonesInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
2350 int tmp,i;
2351 GSM_Phone_Data *Data = &s->Phone.Data;
2353 smprintf(s, "Ringtones info received\n");
2354 memset(Data->RingtonesInfo,0,sizeof(GSM_AllRingtonesInfo));
2355 Data->RingtonesInfo->Number = msg.Buffer[4] * 256 + msg.Buffer[5];
2356 tmp = 6;
2357 for (i=0;i<Data->RingtonesInfo->Number;i++) {
2358 Data->RingtonesInfo->Ringtone[i].ID = msg.Buffer[tmp+2] * 256 + msg.Buffer[tmp+3];
2359 memcpy(Data->RingtonesInfo->Ringtone[i].Name,msg.Buffer+tmp+8,(msg.Buffer[tmp+6]*256+msg.Buffer[tmp+7])*2);
2360 smprintf(s, "%i. \"%s\"\n",Data->RingtonesInfo->Ringtone[i].ID,DecodeUnicodeString(Data->RingtonesInfo->Ringtone[i].Name));
2361 tmp = tmp + (msg.Buffer[tmp]*256+msg.Buffer[tmp+1]);
2363 return GE_NONE;
2366 static GSM_Error N6510_PrivGetRingtonesInfo(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info, bool AllRingtones)
2368 GSM_Error error;
2369 unsigned char UserReq[8] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0x02};
2370 unsigned char All_Req[9] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x7D};
2372 s->Phone.Data.RingtonesInfo=Info;
2373 smprintf(s, "Getting binary ringtones ID\n");
2374 if (AllRingtones) {
2375 error = GSM_WaitFor (s, All_Req, 9, 0x1f, 4, ID_GetRingtonesInfo);
2376 if (error == GE_NONE && Info->Number == 0) return GE_NOTSUPPORTED;
2377 return error;
2378 } else {
2379 return GSM_WaitFor (s, UserReq, 8, 0x1f, 4, ID_GetRingtonesInfo);
2383 static GSM_Error N6510_GetRingtonesInfo(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info)
2385 return N6510_PrivGetRingtonesInfo(s, Info, true);
2388 static GSM_Error N6510_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
2390 int tmp,i;
2391 GSM_Phone_Data *Data = &s->Phone.Data;
2393 smprintf(s, "Ringtone received\n");
2394 memcpy(Data->Ringtone->Name,msg.Buffer+8,msg.Buffer[7]*2);
2395 Data->Ringtone->Name[msg.Buffer[7]*2]=0;
2396 Data->Ringtone->Name[msg.Buffer[7]*2+1]=0;
2397 smprintf(s, "Name \"%s\"\n",DecodeUnicodeString(Data->Ringtone->Name));
2398 if (msg.Buffer[msg.Buffer[7]*2+10] == 'M' &&
2399 msg.Buffer[msg.Buffer[7]*2+11] == 'T' &&
2400 msg.Buffer[msg.Buffer[7]*2+12] == 'h' &&
2401 msg.Buffer[msg.Buffer[7]*2+13] == 'd')
2403 smprintf(s,"MIDI\n");
2404 tmp = msg.Buffer[7]*2+10;
2405 i = msg.Length - 2; /* ?????? */
2406 Data->Ringtone->Format = RING_MIDI;
2407 } else {
2408 /* Looking for end */
2409 i=8+msg.Buffer[7]*2+3;
2410 tmp = i;
2411 while (true) {
2412 if (msg.Buffer[i]==0x07 && msg.Buffer[i+1]==0x0b) {
2413 i=i+2; break;
2415 i++;
2416 if (i==msg.Length) return GE_EMPTY;
2419 /* Copying frame */
2420 memcpy(Data->Ringtone->NokiaBinary.Frame,msg.Buffer+tmp,i-tmp);
2421 Data->Ringtone->NokiaBinary.Length=i-tmp;
2422 return GE_NONE;
2425 static GSM_Error N6510_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone)
2427 GSM_AllRingtonesInfo Info;
2428 GSM_Error error;
2429 unsigned char req2[6] = {
2430 N7110_FRAME_HEADER, 0x12,
2431 0x00, 0xe7}; /* Location */
2433 if (Ringtone->Format == 0x00) Ringtone->Format = RING_NOKIABINARY;
2435 switch (Ringtone->Format) {
2436 case RING_NOTETONE:
2437 /* In the future get binary and convert */
2438 return GE_NOTSUPPORTED;
2439 case RING_NOKIABINARY:
2440 s->Phone.Data.Ringtone=Ringtone;
2441 error=N6510_PrivGetRingtonesInfo(s, &Info, PhoneRingtone);
2442 if (error != GE_NONE) return error;
2443 if (Ringtone->Location > Info.Number) return GE_INVALIDLOCATION;
2444 req2[4] = Info.Ringtone[Ringtone->Location-1].ID / 256;
2445 req2[5] = Info.Ringtone[Ringtone->Location-1].ID % 256;
2446 smprintf(s, "Getting binary ringtone\n");
2447 return GSM_WaitFor (s, req2, 6, 0x1f, 4, ID_GetRingtone);
2448 case RING_MIDI:
2449 return GE_NOTSUPPORTED;
2451 return GE_NOTSUPPORTED;
2454 static GSM_Error N6510_PlayTone(GSM_StateMachine *s, int Herz, unsigned char Volume, bool start)
2456 GSM_Error error;
2457 unsigned char reqStart[] = {
2458 0x00,0x06,0x01,0x00,0x07,0x00 };
2459 unsigned char reqPlay[] = {
2460 0x00,0x06,0x01,0x14,0x05,0x04,
2461 0x00,0x00,0x00,0x03,0x03,0x08,
2462 0x00,0x00,0x00,0x01,0x00,0x00,
2463 0x03,0x08,0x01,0x00,
2464 0x07,0xd0, /*Frequency */
2465 0x00,0x00,0x03,0x08,0x02,0x00,0x00,
2466 0x05, /*Volume */
2467 0x00,0x00};
2468 unsigned char reqOff[] = {
2469 0x00,0x06,0x01,0x14,0x05,0x05,
2470 0x00,0x00,0x00,0x01,0x03,0x08,
2471 0x05,0x00,0x00,0x08,0x00,0x00};
2472 // unsigned char reqOff2[] = {
2473 // 0x00,0x06,0x01,0x14,0x05,0x04,
2474 // 0x00,0x00,0x00,0x01,0x03,0x08,
2475 // 0x00,0x00,0x00,0x00,0x00,0x00};
2477 if (start) {
2478 smprintf(s, "Enabling sound - part 1\n");
2479 error=GSM_WaitFor (s, reqStart, 6, 0x0b, 4, ID_PlayTone);
2480 if (error!=GE_NONE) return error;
2481 smprintf(s, "Enabling sound - part 2 (disabling sound command)\n");
2482 error=GSM_WaitFor (s, reqOff, 18, 0x0b, 4, ID_PlayTone);
2483 if (error!=GE_NONE) return error;
2486 /* For Herz==255*255 we have silent */
2487 if (Herz!=255*255) {
2488 reqPlay[23] = Herz%256;
2489 reqPlay[22] = Herz/256;
2490 reqPlay[31] = Volume;
2491 smprintf(s, "Playing sound\n");
2492 return GSM_WaitFor (s, reqPlay, 34, 0x0b, 4, ID_PlayTone);
2493 } else {
2494 reqPlay[23] = 0;
2495 reqPlay[22] = 0;
2496 reqPlay[31] = 0;
2497 smprintf(s, "Playing silent sound\n");
2498 return GSM_WaitFor (s, reqPlay, 34, 0x0b, 4, ID_PlayTone);
2500 // smprintf(s, "Disabling sound - part 1\n");
2501 // error=GSM_WaitFor (s, reqOff, 18, 0x0b, 4, ID_PlayTone);
2502 // if (error!=GE_NONE) return error;
2503 // smprintf(s, "Disabling sound - part 2\n");
2504 // return GSM_WaitFor (s, reqOff2, 18, 0x0b, 4, ID_PlayTone);
2508 static GSM_Error N6510_ReplyGetPPM(GSM_Protocol_Message msg, GSM_StateMachine *s)
2510 GSM_Phone_Data *Data = &s->Phone.Data;
2511 int pos = 6,len;
2513 smprintf(s, "Received phone info\n");
2515 while(pos < msg.Length) {
2516 if (msg.Buffer[pos] == 0x55 && msg.Buffer[pos+1] == 0x55) {
2517 while(1) {
2518 if (msg.Buffer[pos] != 0x55) break;
2519 pos++;
2522 len = pos;
2523 while(1) {
2524 if (msg.Buffer[len] == 0x00 && msg.Buffer[len+1] == 0x00) break;
2525 len++;
2527 while(1) {
2528 if (msg.Buffer[len] != 0x00) break;
2529 len++;
2531 len = len-pos;
2532 smprintf(s, "Block with ID %02x",msg.Buffer[pos]);
2533 #ifdef DEBUG
2534 if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, msg.Buffer+pos, len);
2535 #endif
2536 switch (msg.Buffer[pos]) {
2537 case 0x49:
2538 smprintf(s, "hardware version\n");
2539 break;
2540 case 0x58:
2541 pos += 3;
2542 while (msg.Buffer[pos] != 0x00) pos++;
2543 Data->PhoneString[0] = msg.Buffer[pos - 1];
2544 Data->PhoneString[1] = 0x00;
2545 smprintf(s, "PPM %s\n",Data->PhoneString);
2546 return GE_NONE;
2547 default:
2548 break;
2550 pos += len;
2552 return GE_NOTSUPPORTED;
2555 static GSM_Error N6510_GetPPM(GSM_StateMachine *s,char *value)
2557 // unsigned char req[6] = {N6110_FRAME_HEADER, 0x07, 0x01, 0xff};
2558 unsigned char req[6] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x00};
2560 s->Phone.Data.PhoneString=value;
2561 smprintf(s, "Getting PPM\n");
2562 return GSM_WaitFor (s, req, 6, 0x1b, 3, ID_GetPPM);
2565 static GSM_Error N6510_GetSpeedDial(GSM_StateMachine *s, GSM_SpeedDial *SpeedDial)
2567 GSM_MemoryEntry pbk;
2568 GSM_Error error;
2570 pbk.MemoryType = GMT7110_SP;
2571 pbk.Location = SpeedDial->Location;
2572 SpeedDial->MemoryLocation = 0;
2573 s->Phone.Data.SpeedDial = SpeedDial;
2575 smprintf(s, "Getting speed dial\n");
2576 error=N6510_GetMemory(s,&pbk);
2577 switch (error) {
2578 case GE_NOTSUPPORTED:
2579 smprintf(s, "No speed dials set in phone\n");
2580 return GE_EMPTY;
2581 case GE_NONE:
2582 if (SpeedDial->MemoryLocation == 0) {
2583 smprintf(s, "Speed dial not assigned or error in firmware\n");
2584 return GE_EMPTY;
2586 return GE_NONE;
2587 default:
2588 return error;
2592 static GSM_Error N6510_ReplyGetProfile(GSM_Protocol_Message msg, GSM_StateMachine *s)
2594 unsigned char *blockstart;
2595 int i,j;
2596 GSM_Phone_Data *Data = &s->Phone.Data;
2598 switch (msg.Buffer[3]) {
2599 case 0x02:
2600 blockstart = msg.Buffer + 7;
2601 for (i = 0; i < 11; i++) {
2602 smprintf(s, "Profile feature %02x ",blockstart[1]);
2603 #ifdef DEBUG
2604 if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, blockstart, blockstart[0]);
2605 #endif
2607 switch (blockstart[1]) {
2608 case 0x03:
2609 smprintf(s, "Ringtone ID\n");
2610 Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_RingtoneID;
2611 Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = blockstart[7];
2612 if (blockstart[7] == 0x00) {
2613 Data->Profile->FeatureValue[Data->Profile->FeaturesNumber] = blockstart[10];
2615 Data->Profile->FeaturesNumber++;
2616 break;
2617 case 0x05: /* SMS tone */
2618 j = Data->Profile->FeaturesNumber;
2619 NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,false);
2620 if (j == Data->Profile->FeaturesNumber) {
2621 Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_MessageTone;
2622 Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = PROFILE_MESSAGE_PERSONAL;
2623 Data->Profile->FeaturesNumber++;
2624 Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_MessageToneID;
2625 Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = blockstart[7];
2626 Data->Profile->FeaturesNumber++;
2628 break;
2629 case 0x08: /* Caller groups */
2630 NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,true);
2631 break;
2632 case 0x0c :
2633 CopyUnicodeString(Data->Profile->Name,blockstart + 7);
2634 smprintf(s, "profile Name: \"%s\"\n", DecodeUnicodeString(Data->Profile->Name));
2635 Data->Profile->DefaultName = false;
2636 break;
2637 default:
2638 NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,false);
2640 blockstart = blockstart + blockstart[0];
2642 return GE_NONE;
2643 case 0x06:
2644 Data->Profile->Active = false;
2645 if (Data->Profile->Location == msg.Buffer[5]) Data->Profile->Active = true;
2646 return GE_NONE;
2648 return GE_UNKNOWNRESPONSE;
2651 static GSM_Error N6510_GetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
2653 unsigned char req[150] = {N6110_FRAME_HEADER, 0x01, 0x01, 0x0C, 0x01};
2654 unsigned char reqActive[] = {N6110_FRAME_HEADER, 0x05};
2655 int i, length = 7;
2656 GSM_Error error;
2658 /* For now !!! */
2659 if (!strcmp(s->Phone.Data.ModelInfo->model,"3510")) {
2660 if (s->Phone.Data.VerNum>3.37) return GE_NOTSUPPORTED;
2663 if (Profile->Location>5) return GE_INVALIDLOCATION;
2665 for (i = 0; i < 0x0a; i++) {
2666 req[length++] = 0x04;
2667 req[length++] = Profile->Location;
2668 req[length++] = i;
2669 req[length++] = 0x01;
2672 req[length++] = 0x04;
2673 req[length++] = Profile->Location;
2674 req[length++] = 0x0c;
2675 req[length++] = 0x01;
2677 req[length++] = 0x04;
2679 Profile->CarKitProfile = false;
2680 Profile->HeadSetProfile = false;
2682 Profile->FeaturesNumber = 0;
2684 s->Phone.Data.Profile=Profile;
2685 smprintf(s, "Getting profile\n");
2686 error = GSM_WaitFor (s, req, length, 0x39, 4, ID_GetProfile);
2687 if (error != GE_NONE) return error;
2689 smprintf(s, "Checking, which profile is active\n");
2690 return GSM_WaitFor (s, reqActive, 4, 0x39, 4, ID_GetProfile);
2693 static GSM_Error N6510_ReplySetProfile(GSM_Protocol_Message msg, GSM_StateMachine *s)
2695 unsigned char *blockstart;
2696 int i;
2698 smprintf(s, "Response to profile writing received!\n");
2700 blockstart = msg.Buffer + 6;
2701 for (i = 0; i < msg.Buffer[5]; i++) {
2702 switch (blockstart[2]) {
2703 case 0x00:
2704 if (msg.Buffer[4] == 0x00)
2705 smprintf(s, "keypad tone level successfully set!\n");
2706 else
2707 smprintf(s, "failed to set keypad tone level! error: %i\n", msg.Buffer[4]);
2708 break;
2709 case 0x02:
2710 if (msg.Buffer[4] == 0x00)
2711 smprintf(s, "call alert successfully set!\n");
2712 else
2713 smprintf(s, "failed to set call alert! error: %i\n", msg.Buffer[4]);
2714 break;
2715 case 0x03:
2716 if (msg.Buffer[4] == 0x00)
2717 smprintf(s, "ringtone successfully set!\n");
2718 else
2719 smprintf(s, "failed to set ringtone! error: %i\n", msg.Buffer[4]);
2720 break;
2721 case 0x04:
2722 if (msg.Buffer[4] == 0x00)
2723 smprintf(s, "ringtone volume successfully set!\n");
2724 else
2725 smprintf(s, "failed to set ringtone volume! error: %i\n", msg.Buffer[4]);
2726 break;
2727 case 0x05:
2728 if (msg.Buffer[4] == 0x00)
2729 smprintf(s, "msg.Buffer tone successfully set!\n");
2730 else
2731 smprintf(s, "failed to set msg.Buffer tone! error: %i\n", msg.Buffer[4]);
2732 break;
2733 case 0x06:
2734 if (msg.Buffer[4] == 0x00)
2735 smprintf(s, "vibration successfully set!\n");
2736 else
2737 smprintf(s, "failed to set vibration! error: %i\n", msg.Buffer[4]);
2738 break;
2739 case 0x07:
2740 if (msg.Buffer[4] == 0x00)
2741 smprintf(s, "warning tone level successfully set!\n");
2742 else
2743 smprintf(s, "failed to set warning tone level! error: %i\n", msg.Buffer[4]);
2744 break;
2745 case 0x08:
2746 if (msg.Buffer[4] == 0x00)
2747 smprintf(s, "caller groups successfully set!\n");
2748 else
2749 smprintf(s, "failed to set caller groups! error: %i\n", msg.Buffer[4]);
2750 break;
2751 case 0x09:
2752 if (msg.Buffer[4] == 0x00)
2753 smprintf(s, "automatic answer successfully set!\n");
2754 else
2755 smprintf(s, "failed to set automatic answer! error: %i\n", msg.Buffer[4]);
2756 break;
2757 case 0x0c:
2758 if (msg.Buffer[4] == 0x00)
2759 smprintf(s, "name successfully set!\n");
2760 else
2761 smprintf(s, "failed to set name! error: %i\n", msg.Buffer[4]);
2762 break;
2763 default:
2764 smprintf(s, "Unknown profile subblock type %02x!\n", blockstart[2]);
2765 break;
2767 blockstart = blockstart + blockstart[1];
2769 return GE_NONE;
2772 static GSM_Error N6510_SetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
2774 int i, length = 7, blocks = 0;
2775 bool found;
2776 unsigned char ID,Value;
2777 unsigned char req[150] = {
2778 N6110_FRAME_HEADER, 0x03, 0x01,
2779 0x06, /* Number of blocks */
2780 0x03};
2782 if (Profile->Location>5) return GE_INVALIDLOCATION;
2784 for (i=0;i<Profile->FeaturesNumber;i++) {
2785 found = false;
2786 switch (Profile->FeatureID[i]) {
2787 case Profile_RingtoneID:
2788 ID = 0x03;
2789 Value = Profile->FeatureValue[i];
2790 found = true;
2791 break;
2792 default:
2793 found=NOKIA_FindPhoneFeatureValue(
2795 Profile71_65,
2796 Profile->FeatureID[i],Profile->FeatureValue[i],
2797 &ID,&Value);
2799 if (found) {
2800 req[length] = 0x09;
2801 req[length + 1] = ID;
2802 req[length + 2] = Profile->Location;
2803 memcpy(req + length + 4, "\x00\x00\x01", 3);
2804 req[length + 8] = 0x03;
2805 req[length + 3] = req[length + 7] = Value;
2806 blocks++;
2807 length += 9;
2811 smprintf(s, "Setting profile\n");
2812 return GSM_WaitFor (s, req, length, 0x39, 4, ID_SetProfile);
2815 static GSM_Error N6510_ReplyIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s)
2817 GSM_SMSMessage sms;
2819 #ifdef DEBUG
2820 smprintf(s, "SMS message received\n");
2821 N6510_DecodeSMSFrame(s, &sms, msg.Buffer+10);
2822 #endif
2824 if (s->Phone.Data.EnableIncomingSMS && s->User.IncomingSMS!=NULL) {
2825 sms.State = GSM_UnRead;
2826 sms.InboxFolder = true;
2828 N6510_DecodeSMSFrame(s, &sms, msg.Buffer+10);
2830 s->User.IncomingSMS(s->CurrentConfig->Device,sms);
2832 return GE_NONE;
2835 static GSM_Error N6510_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber)
2837 unsigned int pos = 4;
2838 unsigned char req[100] = {N6110_FRAME_HEADER,0x01,
2839 0x0c}; /* Number length in chars */
2841 req[pos++] = strlen(number);
2842 EncodeUnicode(req+pos,number,strlen(number));
2843 pos += strlen(number)*2;
2844 req[pos++] = 0x05; /* call type: voice - 0x05, data - 0x01 */
2845 req[pos++] = 0x01;
2846 req[pos++] = 0x05;
2847 req[pos++] = 0x00;
2848 req[pos++] = 0x02;
2849 req[pos++] = 0x00;
2850 req[pos++] = 0x00;
2851 switch (ShowNumber) {
2852 case GN_CALL_HideNumber:
2853 req[pos++] = 0x02;
2854 break;
2855 case GN_CALL_ShowNumber:
2856 req[pos++] = 0x03;
2857 break;
2858 case GN_CALL_Default:
2859 req[pos++] = 0x01;
2860 break;
2863 smprintf(s, "Making voice call\n");
2864 return GSM_WaitFor (s, req, pos, 0x01, 4, ID_DialVoice);
2867 /* method 3 */
2868 static GSM_Error N6510_ReplyGetCalendarInfo3(GSM_Protocol_Message msg, GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last)
2870 int i=0,j=0;
2872 while (Last->Location[j] != 0x00) j++;
2873 if (j >= GSM_MAXCALENDARTODONOTES) {
2874 smprintf(s, "Increase GSM_MAXCALENDARTODONOTES\n");
2875 return GE_UNKNOWN;
2877 if (j == 0) {
2878 Last->Number=msg.Buffer[8]*256+msg.Buffer[9];
2879 smprintf(s, "Number of Entries: %i\n",Last->Number);
2881 smprintf(s, "Locations: ");
2882 while (14+(i*4) <= msg.Length) {
2883 Last->Location[j++]=msg.Buffer[12+i*4]*256+msg.Buffer[13+i*4];
2884 smprintf(s, "%i ",Last->Location[j-1]);
2885 i++;
2887 smprintf(s, "\nNumber of Entries in frame: %i\n",i);
2888 Last->Location[j] = 0;
2889 smprintf(s, "\n");
2890 if (i == 1 && msg.Buffer[12+0*4]*256+msg.Buffer[13+0*4] == 0) return GE_EMPTY;
2891 if (i == 0) return GE_EMPTY;
2892 return GE_NONE;
2895 /* method 3 */
2896 static GSM_Error N6510_GetCalendarInfo3(GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last, bool Calendar)
2898 GSM_Error error;
2899 int i;
2900 unsigned char req[] = {N6110_FRAME_HEADER, 0x9E, 0xFF, 0xFF, 0x00, 0x00,
2901 0x00, 0x00, /* First location */
2902 0x00}; /* 0 = calendar, 1 = ToDo in 6610 style */
2904 Last->Location[0] = 0x00;
2905 Last->Number = 0;
2907 if (Calendar) {
2908 smprintf(s, "Getting locations for calendar method 3\n");
2909 error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo);
2910 } else {
2911 req[10] = 0x01;
2912 smprintf(s, "Getting locations for ToDo method 2\n");
2913 error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo);
2915 if (error != GE_NONE && error != GE_EMPTY) return error;
2917 while (1) {
2918 i=0;
2919 while (Last->Location[i] != 0x00) i++;
2920 smprintf(s, "i = %i %i\n",i,Last->Number);
2921 if (i == Last->Number) break;
2922 if (i != Last->Number && error == GE_EMPTY) {
2923 smprintf(s, "Phone doesn't support some notes with this method. Workaround\n");
2924 Last->Number = i;
2925 break;
2927 req[8] = Last->Location[i-1] / 256;
2928 req[9] = Last->Location[i-1] % 256;
2929 if (Calendar) {
2930 smprintf(s, "Getting locations for calendar method 3\n");
2931 error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo);
2932 } else {
2933 smprintf(s, "Getting locations for todo method 2\n");
2934 error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo);
2936 if (error != GE_NONE && error != GE_EMPTY) return error;
2938 return GE_NONE;
2941 /* method 3 */
2942 GSM_Error N6510_ReplyGetCalendar3(GSM_Protocol_Message msg, GSM_StateMachine *s)
2944 GSM_CalendarEntry *entry = s->Phone.Data.Cal;
2945 GSM_DateTime Date;
2946 unsigned long diff;
2947 int i;
2948 bool found = false;
2949 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
2951 smprintf(s, "Calendar note received method 3\n");
2953 smprintf(s,"Note type %02i: ",msg.Buffer[27]);
2954 switch(msg.Buffer[27]) {
2955 case 0x00: smprintf(s,"Reminder\n"); entry->Type = GCN_REMINDER; break;
2956 case 0x01: smprintf(s,"Meeting\n"); entry->Type = GCN_MEETING; break;
2957 case 0x02: smprintf(s,"Call\n"); entry->Type = GCN_CALL; break;
2958 case 0x04: smprintf(s,"Birthday\n"); entry->Type = GCN_BIRTHDAY; break;
2959 case 0x08: smprintf(s,"Memo\n"); entry->Type = GCN_MEMO; break;
2960 default : smprintf(s,"unknown\n");
2963 smprintf(s,"StartTime: %04i-%02i-%02i %02i:%02i\n",
2964 msg.Buffer[28]*256+msg.Buffer[29],
2965 msg.Buffer[30],msg.Buffer[31],msg.Buffer[32],
2966 msg.Buffer[33]);
2967 Date.Year = msg.Buffer[28]*256+msg.Buffer[29];
2968 if (entry->Type == GCN_BIRTHDAY) {
2969 Date.Year = entry->Entries[0].Date.Year;
2970 smprintf(s,"%i\n",Date.Year);
2972 Date.Month = msg.Buffer[30];
2973 Date.Day = msg.Buffer[31];
2974 Date.Hour = msg.Buffer[32];
2975 Date.Minute = msg.Buffer[33];
2976 /* Garbage seen with 3510i 3.51 */
2977 if (Date.Month == 0 && Date.Day == 0 && Date.Hour == 0 && Date.Minute == 0) return GE_EMPTY;
2978 Date.Second = 0;
2979 entry->Entries[0].EntryType = CAL_START_DATETIME;
2980 memcpy(&entry->Entries[0].Date,&Date,sizeof(GSM_DateTime));
2981 entry->EntriesNum++;
2983 if (entry->Type != GCN_BIRTHDAY) {
2984 smprintf(s,"EndTime: %04i-%02i-%02i %02i:%02i\n",
2985 msg.Buffer[34]*256+msg.Buffer[35],
2986 msg.Buffer[36],msg.Buffer[37],msg.Buffer[38],
2987 msg.Buffer[39]);
2988 Date.Year = msg.Buffer[34]*256+msg.Buffer[35];
2989 Date.Month = msg.Buffer[36];
2990 Date.Day = msg.Buffer[37];
2991 Date.Hour = msg.Buffer[38];
2992 Date.Minute = msg.Buffer[39];
2993 Date.Second = 0;
2994 entry->Entries[1].EntryType = CAL_END_DATETIME;
2995 memcpy(&entry->Entries[1].Date,&Date,sizeof(GSM_DateTime));
2996 entry->EntriesNum++;
2999 smprintf(s, "Note icon: %02x\n",msg.Buffer[21]);
3000 for(i=0;i<Priv->CalendarIconsNum;i++) {
3001 if (Priv->CalendarIconsTypes[i] == entry->Type) {
3002 found = true;
3005 if (!found) {
3006 Priv->CalendarIconsTypes[Priv->CalendarIconsNum] = entry->Type;
3007 Priv->CalendarIcons [Priv->CalendarIconsNum] = msg.Buffer[21];
3008 Priv->CalendarIconsNum++;
3011 if (msg.Buffer[14] == 0xFF && msg.Buffer[15] == 0xFF && msg.Buffer[16] == 0xff && msg.Buffer[17] == 0xff)
3013 smprintf(s, "No alarm\n");
3014 } else {
3015 diff = ((unsigned int)msg.Buffer[14]) << 24;
3016 diff += ((unsigned int)msg.Buffer[15]) << 16;
3017 diff += ((unsigned int)msg.Buffer[16]) << 8;
3018 diff += msg.Buffer[17];
3020 memcpy(&entry->Entries[entry->EntriesNum].Date,&entry->Entries[0].Date,sizeof(GSM_DateTime));
3021 GetTimeDifference(diff, &entry->Entries[entry->EntriesNum].Date, false, 60);
3022 smprintf(s, "Alarm date : %02i-%02i-%04i %02i:%02i:%02i\n",
3023 entry->Entries[entry->EntriesNum].Date.Day, entry->Entries[entry->EntriesNum].Date.Month,
3024 entry->Entries[entry->EntriesNum].Date.Year, entry->Entries[entry->EntriesNum].Date.Hour,
3025 entry->Entries[entry->EntriesNum].Date.Minute,entry->Entries[entry->EntriesNum].Date.Second);
3027 entry->Entries[entry->EntriesNum].EntryType = CAL_ALARM_DATETIME;
3028 if (msg.Buffer[22]==0x00 && msg.Buffer[23]==0x00 &&
3029 msg.Buffer[24]==0x00 && msg.Buffer[25]==0x00)
3031 entry->Entries[entry->EntriesNum].EntryType = CAL_SILENT_ALARM_DATETIME;
3032 smprintf(s, "Alarm type : Silent\n");
3034 entry->EntriesNum++;
3037 N71_65_GetCalendarRecurrance(s, msg.Buffer+40, entry);
3039 if (entry->Type == GCN_BIRTHDAY) {
3040 if (msg.Buffer[42] == 0xff && msg.Buffer[43] == 0xff) {
3041 entry->Entries[0].Date.Year = 0;
3042 } else {
3043 entry->Entries[0].Date.Year = msg.Buffer[42]*256+msg.Buffer[43];
3047 memcpy(entry->Entries[entry->EntriesNum].Text, msg.Buffer+54, msg.Buffer[51]*2);
3048 entry->Entries[entry->EntriesNum].Text[msg.Buffer[51]*2] = 0;
3049 entry->Entries[entry->EntriesNum].Text[msg.Buffer[51]*2+1] = 0;
3050 entry->Entries[entry->EntriesNum].EntryType = CAL_TEXT;
3051 entry->EntriesNum++;
3052 smprintf(s, "Note text: \"%s\"\n",DecodeUnicodeString(entry->Entries[entry->EntriesNum-1].Text));
3054 if (entry->Type == GCN_CALL) {
3055 memcpy(entry->Entries[entry->EntriesNum].Text, msg.Buffer+(54+msg.Buffer[51]*2), msg.Buffer[52]*2);
3056 entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2] = 0;
3057 entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2+1] = 0;
3058 entry->Entries[entry->EntriesNum].EntryType = CAL_PHONE;
3059 entry->EntriesNum++;
3061 if (entry->Type == GCN_MEETING) {
3062 memcpy(entry->Entries[entry->EntriesNum].Text, msg.Buffer+(54+msg.Buffer[51]*2), msg.Buffer[52]*2);
3063 entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2] = 0;
3064 entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2+1] = 0;
3065 entry->Entries[entry->EntriesNum].EntryType = CAL_LOCATION;
3066 entry->EntriesNum++;
3069 return GE_NONE;
3072 static GSM_Error N6510_PrivGetCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start, int *LastCalendarYear)
3074 GSM_Error error;
3075 GSM_DateTime date_time;
3076 unsigned char req[] = {
3077 N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00,
3078 0x00,0x99, /* Location */
3079 0xff,0xff,0xff,0xff,0x01};
3081 if (start) {
3082 /* We have to get current year. It's NOT written in frame for
3083 * Birthday
3085 error=s->Phone.Functions->GetDateTime(s,&date_time);
3086 switch (error) {
3087 case GE_EMPTY:
3088 case GE_NOTIMPLEMENTED:
3089 GSM_GetCurrentDateTime(&date_time);
3090 break;
3091 case GE_NONE:
3092 break;
3093 default:
3094 return error;
3096 *LastCalendarYear = date_time.Year;
3099 Note->EntriesNum = 0;
3100 Note->Entries[0].Date.Year = *LastCalendarYear;
3102 req[8] = Note->Location >> 8;
3103 req[9] = Note->Location & 0xff;
3105 s->Phone.Data.Cal=Note;
3106 smprintf(s, "Getting calendar note method 3\n");
3107 return GSM_WaitFor (s, req, 15, 0x13, 4, ID_GetCalendarNote);
3110 /* method 3 */
3111 GSM_Error N6510_GetNextCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start, GSM_NOKIACalToDoLocations *LastCalendar, int *LastCalendarYear, int *LastCalendarPos)
3113 GSM_Error error;
3114 bool start2;
3116 if (start) {
3117 error=N6510_GetCalendarInfo3(s,LastCalendar,true);
3118 if (error!=GE_NONE) return error;
3119 if (LastCalendar->Number == 0) return GE_EMPTY;
3121 *LastCalendarPos = 0;
3122 } else {
3123 (*LastCalendarPos)++;
3126 error = GE_EMPTY;
3127 start2 = start;
3128 while (error == GE_EMPTY) {
3129 if (*LastCalendarPos >= LastCalendar->Number) return GE_EMPTY;
3131 Note->Location = LastCalendar->Location[*LastCalendarPos];
3132 error=N6510_PrivGetCalendar3(s, Note, start2, LastCalendarYear);
3133 if (error == GE_EMPTY) (*LastCalendarPos)++;
3135 start2 = false;
3137 return error;
3140 static GSM_Error N6510_ReplyGetCalendarInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
3142 switch (msg.Buffer[3]) {
3143 case 0x3B:
3144 /* Old method 1 for accessing calendar */
3145 return N71_65_ReplyGetCalendarInfo1(msg, s, &s->Phone.Data.Priv.N6510.LastCalendar);
3146 case 0x9F:
3147 smprintf(s, "Info with calendar notes locations received method 3\n");
3148 return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastCalendar);
3150 return GE_UNKNOWNRESPONSE;
3153 /* method 3 */
3154 GSM_Error N6510_ReplyGetCalendarNotePos3(GSM_Protocol_Message msg, GSM_StateMachine *s,int *FirstCalendarPos)
3156 smprintf(s, "First calendar location: %i\n",msg.Buffer[8]*256+msg.Buffer[9]);
3157 *FirstCalendarPos = msg.Buffer[8]*256+msg.Buffer[9];
3158 return GE_NONE;
3161 /* method 3 */
3162 static GSM_Error N6510_GetCalendarNotePos3(GSM_StateMachine *s)
3164 unsigned char req[] = {N6110_FRAME_HEADER, 0x95, 0x00};
3166 smprintf(s, "Getting first free calendar note location\n");
3167 return GSM_WaitFor (s, req, 5, 0x13, 4, ID_GetCalendarNotePos);
3170 static GSM_Error N6510_ReplyGetCalendarNotePos(GSM_Protocol_Message msg, GSM_StateMachine *s)
3172 switch (msg.Buffer[3]) {
3173 #ifdef DEBUG
3174 case 0x32:
3175 /* Old method 1 for accessing calendar */
3176 return N71_65_ReplyGetCalendarNotePos1(msg, s,&s->Phone.Data.Priv.N6510.FirstCalendarPos);
3177 #endif
3178 case 0x96:
3179 return N6510_ReplyGetCalendarNotePos3(msg, s,&s->Phone.Data.Priv.N6510.FirstCalendarPos);
3181 return GE_UNKNOWNRESPONSE;
3184 static GSM_Error N6510_FindCalendarIconID3(GSM_StateMachine *s, GSM_CalendarEntry *Entry, unsigned char *ID)
3186 int i,j,LastCalendarYear;
3187 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
3188 GSM_CalendarEntry Note;
3189 GSM_NOKIACalToDoLocations LastCalendar1,LastCalendar2;
3190 GSM_Error error;
3191 bool found;
3193 for(i=0;i<Priv->CalendarIconsNum;i++) {
3194 if (Priv->CalendarIconsTypes[i] == Entry->Type) {
3195 *ID = Priv->CalendarIcons[i];
3196 return GE_NONE;
3200 smprintf(s, "Starting finding note ID\n");
3202 error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,true);
3203 memcpy(&LastCalendar1,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations));
3204 if (error != GE_NONE) return error;
3206 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL35) ||
3207 IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL65) ||
3208 IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) {
3209 error=N71_65_AddCalendar2(s,Entry);
3210 } else {
3211 if (Entry->Type == GCN_MEETING) {
3212 error=N71_65_AddCalendar1(s, Entry, &s->Phone.Data.Priv.N6510.FirstCalendarPos);
3213 } else {
3214 error=N71_65_AddCalendar2(s,Entry);
3217 if (error != GE_NONE) return error;
3219 error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,true);
3220 memcpy(&LastCalendar2,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations));
3221 if (error != GE_NONE) return error;
3223 smprintf(s,"Number of entries: %i %i\n",LastCalendar1.Number,LastCalendar2.Number);
3225 for(i=0;i<LastCalendar2.Number;i++) {
3226 found = true;
3227 for(j=0;j<LastCalendar1.Number;j++) {
3228 if (LastCalendar1.Location[j] == LastCalendar2.Location[i]) {
3229 found = false;
3230 break;
3233 if (found) {
3234 Note.Location = LastCalendar2.Location[i];
3235 error=N6510_PrivGetCalendar3(s, &Note, true, &LastCalendarYear);
3236 if (error != GE_NONE) return error;
3238 error=N71_65_DelCalendar(s, &Note);
3239 if (error != GE_NONE) return error;
3241 smprintf(s, "Ending finding note ID\n");
3243 for(j=0;j<Priv->CalendarIconsNum;j++) {
3244 if (Priv->CalendarIconsTypes[j] == Entry->Type) {
3245 *ID = Priv->CalendarIcons[j];
3246 return GE_NONE;
3249 return GE_UNKNOWN;
3253 return GE_UNKNOWN;
3256 /* method 3 */
3257 static GSM_Error N6510_ReplyAddCalendar3(GSM_Protocol_Message msg, GSM_StateMachine *s)
3259 smprintf(s, "Calendar note added\n");
3260 return GE_NONE;
3263 /* method 3 */
3264 GSM_Error N6510_AddCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, int *FirstCalendarPos)
3266 GSM_CalendarNoteType NoteType, OldNoteType;
3267 time_t t_time1,t_time2;
3268 long diff;
3269 GSM_Error error;
3270 GSM_DateTime DT,date_time;
3271 int Text, Time, Alarm, Phone, Recurrance, EndTime, Location, count=54;
3272 unsigned char req[5000] = {
3273 N6110_FRAME_HEADER, 0x65,
3274 0x00, /* 0 = calendar, 1 = todo */
3275 0x00, 0x00, 0x00,
3276 0x00, 0x00, /* location */
3277 0x00, 0x00, 0x00, 0x00,
3278 0xFF, 0xFF, 0xFF, 0xFF, /* alarm */
3279 0x80, 0x00, 0x00,
3280 0x01, /* note icon */
3281 0xFF, 0xFF, 0xFF, 0xFF, /* alarm type */
3282 0x00, /* 0x02 or 0x00 */
3283 0x01, /* note type */
3284 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* start date/time */
3285 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* end date/time */
3286 0x00, 0x00, /* recurrance */
3287 0x00, 0x00, /* birth year */
3288 0x20, /* ToDo priority */
3289 0x00, /* ToDo completed ? */
3290 0x00, 0x00, 0x00,
3291 0x00, /* note text length */
3292 0x00, /* phone length/meeting place */
3293 0x00, 0x00, 0x00};
3295 error=N6510_GetCalendarNotePos3(s);
3296 if (error!=GE_NONE) return error;
3297 req[8] = *FirstCalendarPos/256;
3298 req[9] = *FirstCalendarPos%256;
3300 NoteType = N71_65_FindCalendarType(Note->Type, s->Phone.Data.ModelInfo);
3302 switch(NoteType) {
3303 case GCN_REMINDER : req[27]=0x00; req[26]=0x02; break;
3304 case GCN_MEETING : req[27]=0x01; break;
3305 case GCN_CALL : req[27]=0x02; break;
3306 case GCN_BIRTHDAY : req[27]=0x04; break;
3307 case GCN_MEMO : req[27]=0x08; break;
3308 default : return GE_UNKNOWN;
3311 OldNoteType = Note->Type;
3312 Note->Type = NoteType;
3313 error=N6510_FindCalendarIconID3(s, Note, &req[21]);
3314 Note->Type = OldNoteType;
3315 if (error!=GE_NONE) return error;
3317 GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note, &Text, &Time, &Alarm, &Phone, &Recurrance, &EndTime, &Location);
3319 if (Time == -1) return GE_UNKNOWN;
3320 memcpy(&DT,&Note->Entries[Time].Date,sizeof(GSM_DateTime));
3321 req[28] = DT.Year >> 8;
3322 req[29] = DT.Year & 0xff;
3323 req[30] = DT.Month;
3324 req[31] = DT.Day;
3325 req[32] = DT.Hour;
3326 req[33] = DT.Minute;
3328 if (NoteType == GCN_BIRTHDAY) {
3329 error=s->Phone.Functions->GetDateTime(s,&date_time);
3330 switch (error) {
3331 case GE_EMPTY:
3332 case GE_NOTIMPLEMENTED:
3333 GSM_GetCurrentDateTime(&date_time);
3334 break;
3335 case GE_NONE:
3336 break;
3337 default:
3338 return error;
3340 req[28] = date_time.Year >> 8;
3341 req[29] = date_time.Year & 0xff;
3342 if (DT.Year == 0) {
3343 req[42] = 0xff;
3344 req[43] = 0xff;
3345 } else {
3346 req[42] = DT.Year >> 8;
3347 req[43] = DT.Year & 0xff;
3351 if (EndTime != -1) memcpy(&DT,&Note->Entries[EndTime].Date,sizeof(GSM_DateTime));
3352 req[34] = DT.Year >> 8;
3353 req[35] = DT.Year & 0xff;
3354 req[36] = DT.Month;
3355 req[37] = DT.Day;
3356 req[38] = DT.Hour;
3357 req[39] = DT.Minute;
3358 if (NoteType == GCN_BIRTHDAY) {
3359 req[34] = date_time.Year >> 8;
3360 req[35] = date_time.Year & 0xff;
3363 if (Recurrance != -1) {
3364 /* 0xffff -> 1 Year (8760 hours) */
3365 if (Note->Entries[Recurrance].Number >= 8760) {
3366 req[40] = 0xff;
3367 req[41] = 0xff;
3368 } else {
3369 req[40] = Note->Entries[Recurrance].Number / 256;
3370 req[41] = Note->Entries[Recurrance].Number % 256;
3374 if (Alarm != -1) {
3375 memcpy(&DT,&Note->Entries[Time].Date,sizeof(GSM_DateTime));
3376 if (Note->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME)
3378 req[22] = 0x00; req[23] = 0x00; req[24] = 0x00; req[25] = 0x00;
3380 if (NoteType == GCN_BIRTHDAY) DT.Year = date_time.Year;
3381 t_time2 = Fill_Time_T(DT,8);
3382 t_time1 = Fill_Time_T(Note->Entries[Alarm].Date,8);
3383 diff = (t_time1-t_time2)/60;
3385 smprintf(s, " Difference : %i seconds or minutes\n", -diff);
3386 req[14] = (unsigned char)(-diff >> 24);
3387 req[15] = (unsigned char)(-diff >> 16);
3388 req[16] = (unsigned char)(-diff >> 8);
3389 req[17] = (unsigned char)(-diff);
3392 if (Text != -1) {
3393 req[49] = UnicodeLength(Note->Entries[Text].Text);
3394 CopyUnicodeString(req+54,Note->Entries[Text].Text);
3395 count+= req[49]*2;
3398 if (Phone != -1 && NoteType == GCN_CALL) {
3399 req[50] = UnicodeLength(Note->Entries[Phone].Text);
3400 CopyUnicodeString(req+54+req[49]*2,Note->Entries[Phone].Text);
3401 count+= req[50]*2;
3404 if (Location != -1 && NoteType == GCN_MEETING) {
3405 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62) ||
3406 IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL65) ||
3407 IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL35)) {
3408 } else {
3409 req[50] = UnicodeLength(Note->Entries[Location].Text);
3410 CopyUnicodeString(req+54+req[49]*2,Note->Entries[Location].Text);
3411 count+= req[50]*2;
3415 req[count++] = 0x00;
3417 smprintf(s, "Writing calendar note method 3\n");
3418 return GSM_WaitFor (s, req, count, 0x13, 4, ID_SetCalendarNote);
3421 static GSM_Error N6510_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start)
3423 #ifdef GSM_FORCE_DCT4_CALENDAR_6210
3424 /* Method 1. Some features missed. Not working with some notes in 3510 */
3425 return N71_65_GetNextCalendar1(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendar,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos);
3426 #endif
3428 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) {
3429 /* Method 1. Some features missed. Not working with some notes in 3510 */
3430 return N71_65_GetNextCalendar1(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendar,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos);
3432 /* Method 2. In known phones texts of notes cut to 50 chars. Some features missed */
3433 // return N71_65_GetNextCalendar2(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos);
3434 } else {
3435 /* Method 3. All DCT4 features supported. Not supported by 8910 */
3436 return N6510_GetNextCalendar3(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendar,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos);
3440 static GSM_Error N6510_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status)
3442 GSM_Error error;
3444 #ifdef GSM_FORCE_DCT4_CALENDAR_6210
3445 /* Method 1 */
3446 error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N6510.LastCalendar);
3447 if (error!=GE_NONE) return error;
3448 Status->Used = LastCalendar->Number;
3449 return GE_NONE;
3450 #endif
3452 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) {
3453 /* Method 1 */
3454 error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N6510.LastCalendar);
3455 if (error!=GE_NONE) return error;
3456 Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number;
3457 return GE_NONE;
3459 /* Method 2 */
3460 // return GE_NOTSUPPORTED;
3461 } else {
3462 /* Method 3 */
3463 error=N6510_GetCalendarInfo3(s,&s->Phone.Data.Priv.N6510.LastCalendar,true);
3464 if (error!=GE_NONE) return error;
3465 Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number;
3466 return GE_NONE;
3470 static GSM_Error N6510_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
3472 #ifdef GSM_FORCE_DCT4_CALENDAR_6210
3473 return N71_65_AddCalendar2(s,Note);
3474 #endif
3476 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) {
3477 return N71_65_AddCalendar2(s,Note);
3478 // return N71_65_AddCalendar1(s, Note, &s->Phone.Data.Priv.N6510.FirstCalendarPos);
3479 } else {
3480 /* Method 3. All DCT4 features supported. Not supported by 8910 */
3481 return N6510_AddCalendar3(s, Note, &s->Phone.Data.Priv.N6510.FirstCalendarPos);
3485 static GSM_Error N6510_ReplyLogIntoNetwork(GSM_Protocol_Message msg, GSM_StateMachine *s)
3487 smprintf(s, "Probably phone says: I log into network\n");
3488 return GE_NONE;
3491 void N6510_EncodeFMFrequency(double freq, unsigned char *buff)
3493 double freq0;
3494 unsigned char buffer[20];
3495 unsigned int i,freq2;
3497 sprintf(buffer,"%.3f",freq);
3498 for (i=0;i<strlen(buffer);i++) {
3499 if (buffer[i] == ',' || buffer[i] == '.') buffer[i] = ' ';
3501 StringToDouble(buffer, &freq0);
3502 freq2 = (unsigned int)freq0;
3503 dbgprintf("Frequency: %s %i\n",buffer,freq2);
3504 freq2 = freq2 - 0xffff;
3505 buff[0] = freq2 / 0x100;
3506 buff[1] = freq2 % 0x100;
3509 void N6510_DecodeFMFrequency(double *freq, unsigned char *buff)
3511 unsigned char buffer[20];
3513 sprintf(buffer,"%i.%i",(0xffff + buff[0] * 0x100 + buff[1])/1000,
3514 (0xffff + buff[0] * 0x100 + buff[1])%1000);
3515 dbgprintf("Frequency: %s\n",buffer);
3516 StringToDouble(buffer, freq);
3519 static GSM_Error N6510_ReplyGetFMStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
3521 smprintf(s, "getting FM status OK\n");
3522 memcpy(s->Phone.Data.Priv.N6510.FMStatus,msg.Buffer,msg.Length);
3523 s->Phone.Data.Priv.N6510.FMStatusLength = msg.Length;
3524 return GE_NONE;
3527 static GSM_Error N6510_GetFMStatus(GSM_StateMachine *s)
3529 unsigned char req[7] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x01};
3531 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return GE_NOTSUPPORTED;
3532 return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_GetFMStation);
3535 static GSM_Error N6510_ReplyGetFMStation(GSM_Protocol_Message msg, GSM_StateMachine *s)
3537 unsigned char name[GSM_MAX_FMSTATION_LENGTH*2+2];
3538 int length;
3539 GSM_Phone_Data *Data = &s->Phone.Data;
3541 switch (msg.Buffer[3]) {
3542 case 0x06:
3543 smprintf(s, "Received FM station\n");
3544 length = msg.Buffer[8];
3545 memcpy(name,msg.Buffer+18,length*2);
3546 name[length*2] = 0x00;
3547 name[length*2+1] = 0x00;
3548 CopyUnicodeString(Data->FMStation->StationName,name);
3549 smprintf(s,"Station name: \"%s\"\n",DecodeUnicodeString(Data->FMStation->StationName));
3550 N6510_DecodeFMFrequency(&Data->FMStation->Frequency, msg.Buffer+16);
3551 return GE_NONE;
3552 case 0x16:
3553 smprintf(s, "Received FM station. Empty ?\n");
3554 return GE_EMPTY;
3556 return GE_UNKNOWNRESPONSE;
3559 static GSM_Error N6510_GetFMStation (GSM_StateMachine *s, GSM_FMStation *FMStation)
3561 GSM_Error error;
3562 int location;
3563 unsigned char req[7] = {N6110_FRAME_HEADER, 0x05,
3564 0x00, // location
3565 0x00,0x01};
3567 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return GE_NOTSUPPORTED;
3568 if (FMStation->Location > GSM_MAX_FM_STATION) return GE_INVALIDLOCATION;
3570 s->Phone.Data.FMStation = FMStation;
3572 error = N6510_GetFMStatus(s);
3573 if (error != GE_NONE) return error;
3575 location = FMStation->Location-1;
3576 if (s->Phone.Data.Priv.N6510.FMStatus[14+location] == 0xFF) return GE_EMPTY;
3577 req[4] = s->Phone.Data.Priv.N6510.FMStatus[14+location];
3579 smprintf(s, "Getting FM Station %i\n",FMStation->Location);
3580 return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_GetFMStation);
3583 static GSM_Error N6510_ReplySetFMStation(GSM_Protocol_Message msg, GSM_StateMachine *s)
3585 #ifdef DEBUG
3586 switch (msg.Buffer[4]){
3587 case 0x03: smprintf(s, "FM stations cleaned\n"); break;
3588 case 0x11: smprintf(s, "Setting FM station status OK\n"); break;
3589 case 0x12: smprintf(s, "Setting FM station OK\n"); break;
3591 #endif
3592 return GE_NONE;
3595 static GSM_Error N6510_ClearFMStations (GSM_StateMachine *s)
3597 unsigned char req[7] = {N6110_FRAME_HEADER, 0x03,0x0f,0x00,0x01};
3599 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return GE_NOTSUPPORTED;
3601 smprintf(s, "Cleaning FM Stations\n");
3602 return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_SetFMStation);
3605 static GSM_Error N6510_SetFMStation (GSM_StateMachine *s, GSM_FMStation *FMStation)
3607 unsigned int len, location;
3608 GSM_Error error;
3609 unsigned char setstatus[36] = {N6110_FRAME_HEADER,0x11,0x00,0x01,0x01,
3610 0x00,0x00,0x1c,0x00,0x14,0x00,0x00,
3611 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3612 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3613 0xff,0xff,0xff,0xff,0xff,0x01};
3614 unsigned char req[64] = {N6110_FRAME_HEADER, 0x12,0x00,0x01,0x00,
3615 0x00, // 0x0e + (strlen(name) * 2)
3616 0x00, // strlen(name)
3617 0x14,0x09,0x00,
3618 0x00, // location
3619 0x00,0x00,0x01,
3620 0x00, // freqHi
3621 0x00, // freqLo
3622 0x01};
3624 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return GE_NOTSUPPORTED;
3626 s->Phone.Data.FMStation = FMStation;
3627 location = FMStation->Location-1;
3629 error = N6510_GetFMStatus(s);
3630 if (error != GE_NONE) return error;
3632 memcpy(setstatus+14,s->Phone.Data.Priv.N6510.FMStatus+14,20);
3633 setstatus [14+location] = location;
3635 smprintf(s, "Setting FM status %i\n",FMStation->Location);
3636 error = GSM_WaitFor (s, setstatus, 36 , 0x3E, 2, ID_SetFMStation);
3637 if (error != GE_NONE) return error;
3639 req[12] = location;
3641 /* Name */
3642 len = UnicodeLength(FMStation->StationName);
3643 req[8] = len;
3644 req[7] = 0x0e + len * 2;
3645 memcpy (req+18,FMStation->StationName,len*2);
3647 /* Frequency */
3648 N6510_EncodeFMFrequency(FMStation->Frequency, req+16);
3650 smprintf(s, "Setting FM Station %i\n",FMStation->Location);
3651 return GSM_WaitFor (s, req, 0x13+len*2, 0x3E, 2, ID_SetFMStation);
3654 static GSM_Error N6510_ReplySetLight(GSM_Protocol_Message msg, GSM_StateMachine *s)
3656 smprintf(s, "Light set\n");
3657 return GE_NONE;
3660 GSM_Error N6510_SetLight(GSM_StateMachine *s, N6510_PHONE_LIGHTS light, bool enable)
3662 unsigned char req[14] = {
3663 N6110_FRAME_HEADER, 0x05,
3664 0x01, /* 0x01 = Display, 0x03 = keypad */
3665 0x01, /* 0x01 = Enable, 0x02 = disable */
3666 0x00, 0x00, 0x00, 0x01,
3667 0x05, 0x04, 0x02, 0x00};
3669 req[4] = light;
3670 if (!enable) req[5] = 0x02;
3671 smprintf(s, "Setting light\n");
3672 return GSM_WaitFor (s, req, 14, 0x3A, 4, ID_SetLight);
3675 static GSM_Error N6510_ShowStartInfo(GSM_StateMachine *s, bool enable)
3677 GSM_Error error;
3679 if (enable) {
3680 error=N6510_SetLight(s,N6510_LIGHT_DISPLAY,true);
3681 if (error != GE_NONE) return error;
3683 error=N6510_SetLight(s,N6510_LIGHT_TORCH,true);
3684 if (error != GE_NONE) return error;
3686 return N6510_SetLight(s,N6510_LIGHT_KEYPAD,true);
3687 } else {
3688 error=N6510_SetLight(s,N6510_LIGHT_DISPLAY,false);
3689 if (error != GE_NONE) return error;
3691 error=N6510_SetLight(s,N6510_LIGHT_TORCH,false);
3692 if (error != GE_NONE) return error;
3694 return N6510_SetLight(s,N6510_LIGHT_KEYPAD,false);
3698 static int N6510_FindFileCheckSum(unsigned char *ptr, int len)
3700 int acc, i, accx;
3702 accx = 0;
3703 acc = 0xffff;
3704 while (len--) {
3705 accx = (accx & 0xffff00ff) | (acc & 0xff00);
3706 acc = (acc & 0xffff00ff) | *ptr++ << 8;
3707 for (i = 0; i < 8; i++) {
3708 acc <<= 1;
3709 if (acc & 0x10000) acc ^= 0x1021;
3710 if (accx & 0x80000000) acc ^= 0x1021;
3711 accx <<= 1;
3714 dbgprintf("Checksum from Gammu is %04X\n",(acc & 0xffff));
3715 return (acc & 0xffff);
3718 static GSM_Error N6510_ReplyGetFileFolderInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
3720 GSM_File *File = s->Phone.Data.FileInfo;
3721 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
3722 int i;
3724 switch (msg.Buffer[3]) {
3725 case 0x15:
3726 smprintf(s,"File or folder details received\n");
3727 CopyUnicodeString(File->Name,msg.Buffer+10);
3728 if (!strncmp(DecodeUnicodeString(File->Name),"GMSTemp",7)) return GE_EMPTY;
3729 if (File->Name[0] == 0x00 && File->Name[1] == 0x00) return GE_UNKNOWN;
3731 i = msg.Buffer[8]*256+msg.Buffer[9];
3732 dbgprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
3733 msg.Buffer[i-5],msg.Buffer[i-4],msg.Buffer[i-3],
3734 msg.Buffer[i-2],msg.Buffer[i-1],msg.Buffer[i],
3735 msg.Buffer[i+1],msg.Buffer[i+2],msg.Buffer[i+3]);
3737 File->Folder = false;
3738 if (msg.Buffer[i-5] == 0x00) File->Folder = true;
3740 File->ReadOnly = false;
3741 File->Protected = false;
3742 File->System = false;
3743 File->Hidden = false;
3744 if (msg.Buffer[i+2] == 0x01) File->Protected = true;
3745 if (msg.Buffer[i+4] == 0x01) File->ReadOnly = true;
3746 if (msg.Buffer[i+5] == 0x01) File->Hidden = true;
3747 if (msg.Buffer[i+6] == 0x01) File->System = true;//fixme
3749 File->ModifiedEmpty = false;
3750 NOKIA_DecodeDateTime(s, msg.Buffer+i-22, &File->Modified);
3751 if (File->Modified.Year == 0x00) File->ModifiedEmpty = true;
3752 dbgprintf("%02x %02x %02x %02x\n",msg.Buffer[i-22],msg.Buffer[i-21],msg.Buffer[i-20],msg.Buffer[i-19]);
3754 Priv->FileToken = msg.Buffer[i-10]*256+msg.Buffer[i-9];
3755 Priv->ParentID = msg.Buffer[i]*256+msg.Buffer[i+1];
3756 smprintf(s,"ParentID is %i\n",Priv->ParentID);
3758 File->Type = GSM_File_Other;
3759 if (msg.Length > 240){
3760 i = 227;
3761 if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x01)
3762 File->Type = GSM_File_Image_JPG;
3763 else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x02)
3764 File->Type = GSM_File_Image_BMP;
3765 else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x07)
3766 File->Type = GSM_File_Image_BMP;
3767 else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x03)
3768 File->Type = GSM_File_Image_PNG;
3769 else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x05)
3770 File->Type = GSM_File_Image_GIF;
3771 else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x09)
3772 File->Type = GSM_File_Image_WBMP;
3773 else if (msg.Buffer[i]==0x10 && msg.Buffer[i+2]==0x01)
3774 File->Type = GSM_File_Java_JAR;
3775 else if (msg.Buffer[i]==0x04 && msg.Buffer[i+2]==0x02)
3776 File->Type = GSM_File_Ringtone_MIDI;
3777 #if DEVELOP
3778 else if (msg.Buffer[i]==0x00 && msg.Buffer[i+2]==0x01)
3779 File->Type = GSM_File_MMS;
3780 #endif
3782 return GE_NONE;
3783 case 0x2F:
3784 smprintf(s,"File or folder used bytes received\n");
3785 File->Used = msg.Buffer[6]*256*256*256+
3786 msg.Buffer[7]*256*256+
3787 msg.Buffer[8]*256+
3788 msg.Buffer[9];
3789 return GE_NONE;
3790 case 0x33:
3791 if (s->Phone.Data.RequestID == ID_GetFileInfo) {
3792 i = Priv->FilesLocationsUsed-1;
3793 while (1) {
3794 if (i==Priv->FilesLocationsCurrent-1) break;
3795 dbgprintf("Copying %i to %i, max %i, current %i\n",
3796 i,i+msg.Buffer[9],
3797 Priv->FilesLocationsUsed,Priv->FilesLocationsCurrent);
3798 Priv->FilesLocations[i+msg.Buffer[9]] = Priv->FilesLocations[i];
3799 Priv->FilesLevels[i+msg.Buffer[9]] = Priv->FilesLevels[i];
3800 i--;
3802 Priv->FilesLocationsUsed += msg.Buffer[9];
3803 for (i=0;i<msg.Buffer[9];i++) {
3804 Priv->FilesLocations[Priv->FilesLocationsCurrent+i] = msg.Buffer[13+i*4];
3805 Priv->FilesLevels[Priv->FilesLocationsCurrent+i] = File->Level+1;
3806 dbgprintf("%i ",Priv->FilesLocations[Priv->FilesLocationsCurrent+i]);
3808 dbgprintf("\n");
3810 if (msg.Buffer[9] != 0x00) File->Folder = true;
3811 return GE_NONE;
3812 case 0x43:
3813 Priv->FileCheckSum = msg.Buffer[6] * 256 + msg.Buffer[7];
3814 smprintf(s,"File checksum from phone is %i\n",Priv->FileCheckSum);
3815 return GE_NONE;
3817 return GE_UNKNOWNRESPONSE;
3820 static GSM_Error N6510_GetFileFolderInfo(GSM_StateMachine *s, GSM_File *File, GSM_Phone_RequestID Request)
3822 GSM_Error error;
3823 unsigned char req[10] = {
3824 N7110_FRAME_HEADER,
3825 0x14, /* 0x14 - info, 0x22 - free/total, 0x2E - used, 0x32 - sublocations */
3826 0x01, /* 0x00 for sublocations reverse sorting, 0x01 for free */
3827 0x00, 0x00, 0x01,
3828 0x00, 0x01}; /* Folder or file number */
3829 unsigned char GetCRC[] = {
3830 N7110_FRAME_HEADER, 0x42, 0x00, 0x00, 0x00, 0x01,
3831 0x00, 0x1E}; /* file ID */
3833 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return GE_NOTSUPPORTED;
3835 s->Phone.Data.FileInfo = File;
3836 req[8] = atoi(File->ID_FullName) / 256;
3837 req[9] = atoi(File->ID_FullName) % 256;
3839 req[3] = 0x14;
3840 req[4] = 0x01;
3841 smprintf(s,"Getting info for file in filesystem\n");
3842 error=GSM_WaitFor (s, req, 10, 0x6D, 4, Request);
3843 if (error != GE_NONE) return error;
3845 if (Request != ID_AddFile) {
3846 req[3] = 0x32;
3847 req[4] = 0x00;
3848 smprintf(s,"Getting subfolders for filesystem\n");
3849 error=GSM_WaitFor (s, req, 10, 0x6D, 4, Request);
3850 if (error != GE_NONE) return error;
3852 if (!File->Folder) {
3853 req[3] = 0x2E;
3854 req[4] = 0x01;
3855 smprintf(s,"Getting used memory for file in filesystem\n");
3856 error=GSM_WaitFor (s, req, 10, 0x6D, 4, Request);
3857 if (error != GE_NONE) return error;
3859 GetCRC[8] = atoi(File->ID_FullName) / 256;
3860 GetCRC[9] = atoi(File->ID_FullName) % 256;
3861 smprintf(s,"Getting CRC for file in filesystem\n");
3862 error=GSM_WaitFor (s, GetCRC, 10, 0x6D, 4, Request);
3865 return error;
3868 static GSM_Error N6510_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, bool start)
3870 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
3871 GSM_Error error;
3873 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return GE_NOTSUPPORTED;
3875 if (start) {
3876 Priv->FilesLocationsUsed = 1;
3877 Priv->FilesLocationsCurrent = 0;
3878 Priv->FilesLocations[0] = 0x01;
3879 Priv->FilesLevels[0] = 1;
3882 while (1) {
3883 if (Priv->FilesLocationsCurrent == Priv->FilesLocationsUsed) return GE_EMPTY;
3885 sprintf(File->ID_FullName,"%i",Priv->FilesLocations[Priv->FilesLocationsCurrent]);
3886 File->Level = Priv->FilesLevels[Priv->FilesLocationsCurrent];
3887 Priv->FilesLocationsCurrent++;
3889 error = N6510_GetFileFolderInfo(s, File, ID_GetFileInfo);
3890 if (error == GE_EMPTY) continue;
3891 return error;
3895 static GSM_Error N6510_ReplyGetFileSystemStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
3897 switch (msg.Buffer[3]) {
3898 case 0x23:
3899 if (!strcmp(s->Phone.Data.ModelInfo->model,"6310i")) {
3900 smprintf(s,"File or folder total bytes received\n");
3901 s->Phone.Data.FileSystemStatus->Free =
3902 3*256*256 + msg.Buffer[8]*256 + msg.Buffer[9] -
3903 s->Phone.Data.FileSystemStatus->Used;
3904 } else {
3905 smprintf(s,"File or folder free bytes received\n");
3906 s->Phone.Data.FileSystemStatus->Free =
3907 msg.Buffer[6]*256*256*256+
3908 msg.Buffer[7]*256*256+
3909 msg.Buffer[8]*256+
3910 msg.Buffer[9];
3912 return GE_NONE;
3913 case 0x2F:
3914 smprintf(s,"File or folder used bytes received\n");
3915 s->Phone.Data.FileSystemStatus->Used =
3916 msg.Buffer[6]*256*256*256+
3917 msg.Buffer[7]*256*256+
3918 msg.Buffer[8]*256+
3919 msg.Buffer[9];
3920 return GE_NONE;
3922 return GE_UNKNOWNRESPONSE;
3925 static GSM_Error N6510_GetFileSystemStatus(GSM_StateMachine *s, GSM_FileSystemStatus *status)
3927 GSM_Error error;
3928 unsigned char req[10] = {
3929 N7110_FRAME_HEADER,
3930 0x22, /* 0x14 - info, 0x22 - free/total, 0x2E - used, 0x32 - sublocations */
3931 0x01, /* 0x00 for sublocations reverse sorting, 0x01 for free */
3932 0x00, 0x00, 0x01,
3933 0x00, 0x01}; /* Folder or file number */
3935 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return GE_NOTSUPPORTED;
3937 s->Phone.Data.FileSystemStatus = status;
3939 status->Free = 0;
3941 req[3] = 0x2E;
3942 req[4] = 0x01;
3943 smprintf(s, "Getting used/total memory in filesystem\n");
3944 error = GSM_WaitFor (s, req, 10, 0x6D, 4, ID_FileSystemStatus);
3946 req[3] = 0x22;
3947 req[4] = 0x01;
3948 smprintf(s, "Getting free memory in filesystem\n");
3949 return GSM_WaitFor (s, req, 10, 0x6D, 4, ID_FileSystemStatus);
3952 static GSM_Error N6510_SearchForFileName(GSM_StateMachine *s, GSM_File *File)
3954 GSM_File File2;
3955 GSM_Error error;
3956 int FilesLocations[500],FilesLocations2[500];
3957 int FilesLevels[500];
3958 int FilesLocationsUsed, FilesLocationsCurrent;
3959 int FilesLocationsUsed2, FilesLocationsCurrent2;
3960 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
3962 memcpy(FilesLocations, Priv->FilesLocations, sizeof(FilesLocations));
3963 memcpy(FilesLevels, Priv->FilesLevels, sizeof(FilesLevels));
3964 FilesLocationsUsed = Priv->FilesLocationsUsed;
3965 FilesLocationsCurrent = Priv->FilesLocationsCurrent;
3967 Priv->FilesLocationsUsed = 1;
3968 Priv->FilesLocationsCurrent = 1;
3969 Priv->FilesLocations[0] = atoi(File->ID_FullName);
3970 Priv->FilesLevels[0] = 1;
3972 strcpy(File2.ID_FullName,File->ID_FullName);
3973 error = N6510_GetFileFolderInfo(s, &File2, ID_GetFileInfo);
3974 memcpy(FilesLocations2, Priv->FilesLocations, sizeof(FilesLocations2));
3975 FilesLocationsUsed2 = Priv->FilesLocationsUsed;
3976 FilesLocationsCurrent2 = Priv->FilesLocationsCurrent;
3978 memcpy(Priv->FilesLocations, FilesLocations, sizeof(FilesLocations));
3979 memcpy(Priv->FilesLevels, FilesLevels, sizeof(FilesLevels));
3980 Priv->FilesLocationsUsed = FilesLocationsUsed;
3981 Priv->FilesLocationsCurrent = FilesLocationsCurrent;
3982 if (error != GE_NONE) return error;
3984 while (1) {
3985 if (FilesLocationsCurrent2 == FilesLocationsUsed2) return GE_EMPTY;
3987 sprintf(File2.ID_FullName,"%i",FilesLocations2[FilesLocationsCurrent2]);
3988 dbgprintf("Current is %i\n",FilesLocations2[FilesLocationsCurrent2]);
3989 FilesLocationsCurrent2++;
3991 error = N6510_GetFileFolderInfo(s, &File2, ID_AddFile);
3992 if (error == GE_EMPTY) continue;
3993 if (error != GE_NONE) return error;
3994 dbgprintf("%s %s\n",DecodeUnicodeString(File->Name),DecodeUnicodeString(File2.Name));
3995 if (mywstrncasecmp(File2.Name,File->Name,0)) return GE_NONE;
3997 return GE_EMPTY;
4000 static GSM_Error N6510_ReplyGetFilePart(GSM_Protocol_Message msg, GSM_StateMachine *s)
4002 int old;
4004 smprintf(s,"File part received\n");
4005 old = s->Phone.Data.File->Used;
4006 s->Phone.Data.File->Used += msg.Buffer[6]*256*256*256+
4007 msg.Buffer[7]*256*256+
4008 msg.Buffer[8]*256+
4009 msg.Buffer[9];
4010 smprintf(s,"Length of file part: %i\n",
4011 msg.Buffer[6]*256*256*256+
4012 msg.Buffer[7]*256*256+
4013 msg.Buffer[8]*256+
4014 msg.Buffer[9]);
4015 s->Phone.Data.File->Buffer = (unsigned char *)realloc(s->Phone.Data.File->Buffer,s->Phone.Data.File->Used);
4016 memcpy(s->Phone.Data.File->Buffer+old,msg.Buffer+10,s->Phone.Data.File->Used-old);
4017 return GE_NONE;
4020 static GSM_Error N6510_GetFilePart(GSM_StateMachine *s, GSM_File *File)
4022 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
4023 int old;
4024 GSM_Error error;
4025 unsigned char req[] = {
4026 N7110_FRAME_HEADER, 0x0E, 0x00, 0x00, 0x00, 0x01,
4027 0x00, 0x01, /* Folder or file number */
4028 0x00, 0x00,
4029 0x00, 0x00, /* Start from xxx byte */
4030 0x00, 0x00,
4031 0x03, 0xE8}; /* Read xxx bytes */
4033 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return GE_NOTSUPPORTED;
4035 if (File->Used == 0x00) {
4036 error = N6510_GetFileFolderInfo(s, File, ID_GetFile);
4037 if (error != GE_NONE) return error;
4038 File->Used = 0;
4041 req[8] = atoi(File->ID_FullName) / 256;
4042 req[9] = atoi(File->ID_FullName) % 256;
4043 old = File->Used;
4044 req[12] = old / 256;
4045 req[13] = old % 256;
4047 s->Phone.Data.File = File;
4048 smprintf(s, "Getting file part from filesystem\n");
4049 error=GSM_WaitFor (s, req, 18, 0x6D, 4, ID_GetFile);
4050 if (error != GE_NONE) return error;
4051 if (File->Used - old != (0x03 * 256 + 0xE8)) {
4052 if (N6510_FindFileCheckSum(File->Buffer, File->Used) != Priv->FileCheckSum) {
4053 smprintf(s,"File2 checksum is %i, File checksum is %i\n",N6510_FindFileCheckSum(File->Buffer, File->Used),Priv->FileCheckSum);
4054 return GE_WRONGCRC;
4056 return GE_EMPTY;
4058 return GE_NONE;
4061 static GSM_Error N6510_SetReadOnly(GSM_StateMachine *s, unsigned char *ID, bool enable)
4063 unsigned char SetAttr[] = {
4064 N7110_FRAME_HEADER, 0x18, 0x00, 0x00, 0x00, 0x01,
4065 0x00, 0x20}; /* File ID */
4067 if (!enable) SetAttr[4] = 0x06;
4069 SetAttr[8] = atoi(ID) / 256;
4070 SetAttr[9] = atoi(ID) % 256;
4071 smprintf(s, "Setting readonly attribute\n");
4072 return GSM_WaitFor (s, SetAttr, 10, 0x6D, 4, ID_DeleteFile);
4075 static GSM_Error N6510_ReplyAddFileHeader(GSM_Protocol_Message msg, GSM_StateMachine *s)
4077 switch (msg.Buffer[3]) {
4078 case 0x03:
4079 smprintf(s,"File header added\n");
4080 sprintf(s->Phone.Data.File->ID_FullName,"%i",msg.Buffer[9]);
4081 return GE_NONE;
4082 case 0x13:
4083 return GE_NONE;
4085 return GE_UNKNOWNRESPONSE;
4088 static GSM_Error N6510_ReplyAddFilePart(GSM_Protocol_Message msg, GSM_StateMachine *s)
4090 return GE_NONE;
4093 static GSM_Error N6510_AddFilePart(GSM_StateMachine *s, GSM_File *File, int *Pos)
4095 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
4096 GSM_File File2;
4097 GSM_Error error;
4098 int j;
4099 unsigned char Header[400] = {
4100 N7110_FRAME_HEADER, 0x02, 0x00, 0x00, 0x00, 0x01,
4101 0x00, 0x0C, /* parent folder ID */
4102 0x00, 0x00, 0x00, 0xE8};
4103 unsigned char Add[15000] = {
4104 N7110_FRAME_HEADER, 0x40, 0x00, 0x00, 0x00, 0x01,
4105 0x00, 0x04, /* file ID */
4106 0x00, 0x00,
4107 0x01, 0x28}; /* length */
4108 unsigned char end[30] = {
4109 N7110_FRAME_HEADER, 0x40, 0x00, 0x00, 0x00, 0x01,
4110 0x00, 0x04, /* file ID */
4111 0x00, 0x00, 0x00, 0x00};
4113 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return GE_NOTSUPPORTED;
4115 s->Phone.Data.File = File;
4117 if (*Pos == 0) {
4118 error = N6510_SearchForFileName(s,File);
4119 if (error == GE_NONE) return GE_INVALIDLOCATION;
4120 if (error != GE_EMPTY) return error;
4122 Header[8] = atoi(File->ID_FullName) / 256;
4123 Header[9] = atoi(File->ID_FullName) % 256;
4124 memset(Header+14, 0x00, 300);
4125 CopyUnicodeString(Header+14,File->Name);
4126 Header[224] = File->Used / 256;
4127 Header[225] = File->Used % 256;
4128 switch(File->Type) {
4129 case GSM_File_Image_JPG : Header[231]=0x02; Header[233]=0x01; break;
4130 case GSM_File_Image_BMP : Header[231]=0x02; Header[233]=0x02; break;
4131 case GSM_File_Image_PNG : Header[231]=0x02; Header[233]=0x03; break;
4132 case GSM_File_Image_GIF : Header[231]=0x02; Header[233]=0x05; break;
4133 case GSM_File_Image_WBMP : Header[231]=0x02; Header[233]=0x09; break;
4134 case GSM_File_Ringtone_MIDI: Header[231]=0x04; Header[233]=0x05; break; //Header[238]=0x01;
4135 case GSM_File_Java_JAR : Header[231]=0x10; Header[233]=0x01; break;
4136 #ifdef DEVELOP
4137 case GSM_File_MMS:
4138 Header[214]=0x07;
4139 Header[215]=0xd3;
4140 Header[216]=0x06;
4141 Header[217]=0x01;
4142 Header[218]=0x12;
4143 Header[219]=0x13;
4144 Header[220]=0x29;
4145 Header[233]=0x01;
4146 break;
4147 #endif
4148 default : Header[231]=0x01; Header[233]=0x05;
4150 Header[235] = 0x01;
4151 Header[236] = atoi(File->ID_FullName) / 256;
4152 Header[237] = atoi(File->ID_FullName) % 256;
4153 if (File->Protected) Header[238] = 0x01; //Nokia forward lock
4154 if (File->Hidden) Header[241] = 0x01;
4155 if (File->System) Header[242] = 0x01; //fixme
4156 smprintf(s, "Adding file header\n");
4157 error=GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFile);
4158 if (error != GE_NONE) return error;
4161 j = 1000;
4162 if (File->Used - *Pos < 1000) j = File->Used - *Pos;
4163 Add[ 8] = atoi(File->ID_FullName) / 256;
4164 Add[ 9] = atoi(File->ID_FullName) % 256;
4165 Add[12] = j / 256;
4166 Add[13] = j % 256;
4167 memcpy(Add+14,File->Buffer+(*Pos),j);
4168 smprintf(s, "Adding file part %i %i\n",*Pos,j);
4169 error=GSM_WaitFor (s, Add, 14+j, 0x6D, 4, ID_AddFile);
4170 if (error != GE_NONE) return error;
4171 *Pos = *Pos + j;
4173 if (j < 1000) {
4174 end[8] = atoi(File->ID_FullName) / 256;
4175 end[9] = atoi(File->ID_FullName) % 256;
4176 smprintf(s, "Frame for ending adding file\n");
4177 error = GSM_WaitFor (s, end, 14, 0x6D, 4, ID_AddFile);
4178 if (error != GE_NONE) return error;
4180 strcpy(File2.ID_FullName,File->ID_FullName);
4181 error = N6510_GetFileFolderInfo(s, &File2, ID_GetFileInfo);
4182 if (error != GE_NONE) return error;
4184 if (!File->ModifiedEmpty) {
4185 Header[3] = 0x12;
4186 Header[4] = 0x01;
4187 Header[12] = 0x00;
4188 Header[13] = 0xE8;
4189 Header[8] = atoi(File->ID_FullName) / 256;
4190 Header[9] = atoi(File->ID_FullName) % 256;
4191 memset(Header+14, 0x00, 300);
4192 CopyUnicodeString(Header+14,File->Name);
4193 NOKIA_EncodeDateTime(s,Header+214,&File->Modified);
4194 /* When you save too big file for phone and it changes
4195 * size (some part is cut by firmware), you HAVE to write
4196 * here correct file size. In other case filesystem
4197 * will be damaged
4199 Header[224] = File2.Used / 256;
4200 Header[225] = File2.Used % 256;
4201 Header[226] = Priv->FileToken / 256;
4202 Header[227] = Priv->FileToken % 256;
4203 switch(File->Type) {
4204 case GSM_File_Image_JPG : Header[231]=0x02; Header[233]=0x01; break;
4205 case GSM_File_Image_BMP : Header[231]=0x02; Header[233]=0x02; break;
4206 case GSM_File_Image_PNG : Header[231]=0x02; Header[233]=0x03; break;
4207 case GSM_File_Image_GIF : Header[231]=0x02; Header[233]=0x05; break;
4208 case GSM_File_Image_WBMP : Header[231]=0x02; Header[233]=0x09; break;
4209 case GSM_File_Ringtone_MIDI: Header[231]=0x04; Header[233]=0x05; break; //Header[238]=0x01;
4210 case GSM_File_Java_JAR : Header[231]=0x10; Header[233]=0x01; break;
4211 #ifdef DEVELOP
4212 case GSM_File_MMS:
4213 Header[214]=0x07;
4214 Header[215]=0xd3;
4215 Header[216]=0x06;
4216 Header[217]=0x01;
4217 Header[218]=0x12;
4218 Header[219]=0x13;
4219 Header[220]=0x29;
4220 Header[233]=0x01;
4221 break;
4222 #endif
4223 default : Header[231]=0x01; Header[233]=0x05;
4225 Header[235] = 0x01;
4226 Header[236] = Priv->ParentID / 256;
4227 Header[237] = Priv->ParentID % 256;
4228 smprintf(s, "Adding file header\n");
4229 error=GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFile);
4230 if (error != GE_NONE) return error;
4233 /* Can't delete from phone menu */
4234 if (File->ReadOnly) {
4235 error = N6510_SetReadOnly(s, File->ID_FullName, true);
4236 if (error != GE_NONE) return error;
4239 if (N6510_FindFileCheckSum(File->Buffer, File->Used) != Priv->FileCheckSum) {
4240 smprintf(s,"File2 checksum is %i, File checksum is %i\n",N6510_FindFileCheckSum(File->Buffer, File->Used),Priv->FileCheckSum);
4241 return GE_WRONGCRC;
4244 return GE_EMPTY;
4247 return GE_NONE;
4250 static GSM_Error N6510_ReplyDeleteFile(GSM_Protocol_Message msg, GSM_StateMachine *s)
4252 return GE_NONE;
4255 static GSM_Error N6510_DeleteFile(GSM_StateMachine *s, unsigned char *ID)
4257 GSM_Error error;
4258 unsigned char Delete[40] = {
4259 N7110_FRAME_HEADER, 0x1E, 0x00, 0x00, 0x00, 0x01,
4260 0x00, 0x35}; /* File ID */
4262 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return GE_NOTSUPPORTED;
4264 error = N6510_SetReadOnly(s, ID, false);
4265 if (error != GE_NONE) return error;
4267 Delete[8] = atoi(ID) / 256;
4268 Delete[9] = atoi(ID) % 256;
4269 return GSM_WaitFor (s, Delete, 10, 0x6D, 4, ID_DeleteFile);
4272 static GSM_Error N6510_ReplyAddFolder(GSM_Protocol_Message msg, GSM_StateMachine *s)
4274 sprintf(s->Phone.Data.File->ID_FullName,"%i",msg.Buffer[9]);
4275 return GE_NONE;
4278 static GSM_Error N6510_AddFolder(GSM_StateMachine *s, GSM_File *File)
4280 GSM_Error error;
4281 unsigned char Header[400] = {
4282 N7110_FRAME_HEADER, 0x04, 0x00, 0x00, 0x00, 0x01,
4283 0x00, 0x0C, /* parent folder ID */
4284 0x00, 0x00, 0x00, 0xE8};
4286 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return GE_NOTSUPPORTED;
4288 error = N6510_SearchForFileName(s,File);
4289 if (error == GE_NONE) return GE_INVALIDLOCATION;
4290 if (error != GE_EMPTY) return error;
4292 Header[8] = atoi(File->ID_FullName) / 256;
4293 Header[9] = atoi(File->ID_FullName) % 256;
4294 memset(Header+14, 0x00, 300);
4295 CopyUnicodeString(Header+14,File->Name);
4296 Header[233] = 0x02;
4297 Header[235] = 0x01;
4298 Header[236] = atoi(File->ID_FullName) / 256;
4299 Header[237] = atoi(File->ID_FullName) % 256;
4301 s->Phone.Data.File = File;
4302 smprintf(s, "Adding folder\n");
4303 error = GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFolder);
4304 if (error != GE_NONE) return error;
4306 /* Can't delete from phone menu */
4307 if (File->ReadOnly) {
4308 error = N6510_SetReadOnly(s, File->ID_FullName, true);
4309 if (error != GE_NONE) return error;
4312 return error;
4315 #ifdef DEVELOP
4317 static GSM_Error N6510_ReplyEnableGPRSAccessPoint(GSM_Protocol_Message msg, GSM_StateMachine *s)
4319 if (msg.Buffer[13] == 0x02) return GE_NONE;
4320 return GE_UNKNOWNRESPONSE;
4323 static GSM_Error N6510_EnableGPRSAccessPoint(GSM_StateMachine *s)
4325 GSM_Error error;
4326 int i;
4327 unsigned char req[] = {
4328 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4329 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00};
4331 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return GE_NOTSUPPORTED;
4333 for (i=0;i<3;i++) {
4334 smprintf(s, "Activating full GPRS access point support\n");
4335 error = GSM_WaitFor (s, req, 16, 0x43, 4, ID_EnableGPRSPoint);
4336 if (error != GE_NONE) return error;
4338 return error;
4341 #endif
4343 static GSM_Error N6510_ReplyGetGPRSAccessPoint(GSM_Protocol_Message msg, GSM_StateMachine *s)
4345 GSM_GPRSAccessPoint *point = s->Phone.Data.GPRSPoint;
4347 switch (msg.Buffer[13]) {
4348 case 0x01:
4349 smprintf(s,"Active GPRS point received\n");
4350 point->Active = false;
4351 if (point->Location == msg.Buffer[18]) point->Active = true;
4352 return GE_NONE;
4353 case 0xD2:
4354 smprintf(s,"Names for GPRS points received\n");
4355 CopyUnicodeString(point->Name,msg.Buffer+18+(point->Location-1)*42);
4356 smprintf(s,"\"%s\"\n",DecodeUnicodeString(point->Name));
4357 return GE_NONE;
4358 case 0xF2:
4359 smprintf(s,"URL for GPRS points received\n");
4360 CopyUnicodeString(point->URL,msg.Buffer+18+(point->Location-1)*202);
4361 smprintf(s,"\"%s\"\n",DecodeUnicodeString(point->URL));
4362 return GE_NONE;
4364 return GE_UNKNOWNRESPONSE;
4367 static GSM_Error N6510_GetGPRSAccessPoint(GSM_StateMachine *s, GSM_GPRSAccessPoint *point)
4369 GSM_Error error;
4370 unsigned char URL[] = {
4371 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4372 0x00, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00};
4373 unsigned char Name[] = {
4374 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4375 0x01, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00};
4376 unsigned char Active[] = {
4377 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4378 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
4380 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return GE_NOTSUPPORTED;
4381 if (point->Location < 1) return GE_UNKNOWN;
4382 if (point->Location > 5) return GE_INVALIDLOCATION;
4384 s->Phone.Data.GPRSPoint = point;
4386 #ifdef DEVELOP
4387 error = N6510_EnableGPRSAccessPoint(s);
4388 if (error != GE_NONE) return error;
4389 #endif
4391 smprintf(s, "Getting GPRS access point name\n");
4392 error=GSM_WaitFor (s, Name, 16, 0x43, 4, ID_GetGPRSPoint);
4393 if (error != GE_NONE) return error;
4395 smprintf(s, "Getting GPRS access point URL\n");
4396 error=GSM_WaitFor (s, URL, 16, 0x43, 4, ID_GetGPRSPoint);
4397 if (error != GE_NONE) return error;
4399 smprintf(s, "Getting number of active GPRS access point\n");
4400 error=GSM_WaitFor (s, Active, 16, 0x43, 4, ID_GetGPRSPoint);
4401 if (error != GE_NONE) return error;
4403 if (UnicodeLength(point->URL)==0 && UnicodeLength(point->Name)==0) return GE_EMPTY;
4404 return error;
4407 static GSM_Error N6510_ReplySetGPRSAccessPoint1(GSM_Protocol_Message msg, GSM_StateMachine *s)
4409 switch (msg.Buffer[13]) {
4410 case 0x01:
4411 case 0xD2:
4412 case 0xF2:
4413 memcpy(s->Phone.Data.Priv.N6510.GPRSPoints,msg.Buffer,msg.Length);
4414 s->Phone.Data.Priv.N6510.GPRSPointsLength = msg.Length;
4415 return GE_NONE;
4417 return GE_UNKNOWNRESPONSE;
4420 static GSM_Error N6510_SetGPRSAccessPoint(GSM_StateMachine *s, GSM_GPRSAccessPoint *point)
4422 unsigned char *buff = s->Phone.Data.Priv.N6510.GPRSPoints;
4423 GSM_Error error;
4424 unsigned char URL[] = {
4425 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4426 0x00, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00};
4427 unsigned char Name[] = {
4428 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4429 0x01, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00};
4430 unsigned char Active[] = {
4431 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4432 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
4434 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return GE_NOTSUPPORTED;
4435 if (point->Location < 1) return GE_UNKNOWN;
4436 if (point->Location > 5) return GE_INVALIDLOCATION;
4438 s->Phone.Data.GPRSPoint = point;
4440 #ifdef DEVELOP
4441 error = N6510_EnableGPRSAccessPoint(s);
4442 if (error != GE_NONE) return error;
4443 #endif
4445 smprintf(s, "Getting GPRS access point name\n");
4446 error=GSM_WaitFor (s, Name, 16, 0x43, 4, ID_SetGPRSPoint);
4447 if (error != GE_NONE) return error;
4448 CopyUnicodeString(buff+18+(point->Location-1)*42,point->Name);
4449 buff[0] = 0x00;
4450 buff[1] = 0x01;
4451 buff[2] = 0x01;
4452 buff[3] = 0x07;
4453 smprintf(s, "Setting GPRS access point name\n");
4454 error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, 4, ID_SetGPRSPoint);
4455 if (error != GE_NONE) return error;
4457 smprintf(s, "Getting GPRS access point URL\n");
4458 error=GSM_WaitFor (s, URL, 16, 0x43, 4, ID_SetGPRSPoint);
4459 if (error != GE_NONE) return error;
4460 CopyUnicodeString(buff+18+(point->Location-1)*42,point->URL);
4461 buff[0] = 0x00;
4462 buff[1] = 0x01;
4463 buff[2] = 0x01;
4464 buff[3] = 0x07;
4465 smprintf(s, "Setting GPRS access point URL\n");
4466 error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, 4, ID_SetGPRSPoint);
4467 if (error != GE_NONE) return error;
4469 if (point->Active) {
4470 smprintf(s, "Getting number of active GPRS access point\n");
4471 error=GSM_WaitFor (s, Active, 16, 0x43, 4, ID_SetGPRSPoint);
4472 if (error != GE_NONE) return error;
4473 buff[0] = 0x00;
4474 buff[1] = 0x01;
4475 buff[2] = 0x01;
4476 buff[3] = 0x07;
4477 buff[18]= point->Location;
4478 smprintf(s, "Setting number of active GPRS access point\n");
4479 error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, 4, ID_SetGPRSPoint);
4480 if (error != GE_NONE) return error;
4483 return error;
4486 /* ToDo support - 6310 style */
4487 static GSM_Error N6510_ReplyGetToDoStatus1(GSM_Protocol_Message msg, GSM_StateMachine *s)
4489 int i;
4490 GSM_NOKIACalToDoLocations *Last = &s->Phone.Data.Priv.N6510.LastToDo;
4492 smprintf(s, "TODO locations received\n");
4493 Last->Number=msg.Buffer[6]*256+msg.Buffer[7];
4494 smprintf(s, "Number of Entries: %i\n",Last->Number);
4495 smprintf(s, "Locations: ");
4496 for (i=0;i<Last->Number;i++) {
4497 Last->Location[i]=msg.Buffer[12+(i*4)]*256+msg.Buffer[(i*4)+13];
4498 smprintf(s, "%i ",Last->Location[i]);
4500 smprintf(s, "\n");
4501 return GE_NONE;
4504 /* ToDo support - 6310 style */
4505 static GSM_Error N6510_GetToDoStatus1(GSM_StateMachine *s, GSM_ToDoStatus *status)
4507 GSM_Error error;
4508 GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
4509 unsigned char reqLoc[] = {
4510 N6110_FRAME_HEADER,
4511 0x15, 0x01, 0x00, 0x00,
4512 0x00, 0x00, 0x00};
4514 smprintf(s, "Getting ToDo locations\n");
4515 error = GSM_WaitFor (s, reqLoc, 10, 0x55, 4, ID_GetToDo);
4516 if (error != GE_NONE) return error;
4518 status->Used = LastToDo->Number;
4519 return GE_NONE;
4522 static GSM_Error N6510_GetToDoStatus2(GSM_StateMachine *s, GSM_ToDoStatus *status)
4524 GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
4525 GSM_Error error;
4527 error = N6510_GetCalendarInfo3(s,LastToDo,false);
4528 if (error!=GE_NONE) return error;
4530 status->Used = LastToDo->Number;
4531 return GE_NONE;
4534 static GSM_Error N6510_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status)
4536 status->Used = 0;
4538 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) {
4539 return N6510_GetToDoStatus1(s, status);
4540 } else if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) {
4541 return N6510_GetToDoStatus2(s, status);
4542 } else {
4543 return GE_NOTSUPPORTED;
4547 /* ToDo support - 6310 style */
4548 static GSM_Error N6510_ReplyGetToDo1(GSM_Protocol_Message msg, GSM_StateMachine *s)
4550 GSM_ToDoEntry *Last = s->Phone.Data.ToDo;
4552 smprintf(s, "TODO received method 1\n");
4554 switch (msg.Buffer[4]) {
4555 case 1 : Last->Priority = GSM_Priority_High; break;
4556 case 2 : Last->Priority = GSM_Priority_Medium; break;
4557 case 3 : Last->Priority = GSM_Priority_Low; break;
4558 default : return GE_UNKNOWN;
4560 smprintf(s, "Priority: %i\n",msg.Buffer[4]);
4562 CopyUnicodeString(Last->Entries[0].Text,msg.Buffer+14);
4563 Last->Entries[0].EntryType = TODO_TEXT;
4564 Last->EntriesNum = 1;
4565 smprintf(s, "Text: \"%s\"\n",DecodeUnicodeString(Last->Entries[0].Text));
4567 return GE_NONE;
4570 /* ToDo support - 6310 style */
4571 static GSM_Error N6510_GetNextToDo1(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh)
4573 GSM_Error error;
4574 GSM_ToDoStatus status;
4575 GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
4576 unsigned char reqGet[] = {
4577 N6110_FRAME_HEADER,
4578 0x03, 0x00, 0x00, 0x80, 0x00,
4579 0x00, 0x17}; /* Location */
4581 if (refresh) {
4582 error = N6510_GetToDoStatus(s, &status);
4583 if (error != GE_NONE) return error;
4584 ToDo->Location = 1;
4585 } else {
4586 ToDo->Location++;
4588 if (ToDo->Location > LastToDo->Number) return GE_EMPTY;
4590 reqGet[8] = LastToDo->Location[ToDo->Location-1] / 256;
4591 reqGet[9] = LastToDo->Location[ToDo->Location-1] % 256;
4592 s->Phone.Data.ToDo = ToDo;
4593 smprintf(s, "Getting ToDo\n");
4594 return GSM_WaitFor (s, reqGet, 10, 0x55, 4, ID_GetToDo);
4597 static GSM_Error N6510_ReplyGetToDoStatus2(GSM_Protocol_Message msg, GSM_StateMachine *s)
4599 return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastToDo);
4602 /* Similiar to getting calendar method 3 */
4603 static GSM_Error N6510_ReplyGetToDo2(GSM_Protocol_Message msg, GSM_StateMachine *s)
4605 GSM_ToDoEntry *Last = s->Phone.Data.ToDo;
4606 GSM_DateTime Date;
4607 unsigned long diff;
4609 smprintf(s, "ToDo received method 2\n");
4611 switch (msg.Buffer[44]) {
4612 case 0x10: Last->Priority = GSM_Priority_Low; break;
4613 case 0x20: Last->Priority = GSM_Priority_Medium; break;
4614 case 0x30: Last->Priority = GSM_Priority_High; break;
4615 default : return GE_UNKNOWN;
4618 memcpy(Last->Entries[0].Text,msg.Buffer+54,msg.Buffer[51]*2);
4619 Last->Entries[0].Text[msg.Buffer[51]*2] = 0;
4620 Last->Entries[0].Text[msg.Buffer[51]*2+1] = 0;
4621 Last->Entries[0].EntryType = TODO_TEXT;
4622 smprintf(s, "Text: \"%s\"\n",DecodeUnicodeString(Last->Entries[0].Text));
4624 smprintf(s,"EndTime: %04i-%02i-%02i %02i:%02i\n",
4625 msg.Buffer[34]*256+msg.Buffer[35],
4626 msg.Buffer[36],msg.Buffer[37],msg.Buffer[38],
4627 msg.Buffer[39]);
4628 Date.Year = msg.Buffer[34]*256+msg.Buffer[35];
4629 Date.Month = msg.Buffer[36];
4630 Date.Day = msg.Buffer[37];
4631 Date.Hour = msg.Buffer[38];
4632 Date.Minute = msg.Buffer[39];
4633 Date.Second = 0;
4634 Last->Entries[1].EntryType = TODO_END_DATETIME;
4635 memcpy(&Last->Entries[1].Date,&Date,sizeof(GSM_DateTime));
4637 smprintf(s,"StartTime: %04i-%02i-%02i %02i:%02i\n",
4638 msg.Buffer[28]*256+msg.Buffer[29],
4639 msg.Buffer[30],msg.Buffer[31],msg.Buffer[32],
4640 msg.Buffer[33]);
4641 Date.Year = msg.Buffer[28]*256+msg.Buffer[29];
4642 Date.Month = msg.Buffer[30];
4643 Date.Day = msg.Buffer[31];
4644 Date.Hour = msg.Buffer[32];
4645 Date.Minute = msg.Buffer[33];
4646 Date.Second = 0;
4648 Last->EntriesNum = 2;
4650 if (msg.Buffer[45] == 0x01) {
4651 Last->Entries[2].Number = msg.Buffer[45];
4652 Last->Entries[2].EntryType = TODO_COMPLETED;
4653 Last->EntriesNum++;
4654 smprintf(s,"Completed\n");
4657 if (msg.Buffer[14] == 0xFF && msg.Buffer[15] == 0xFF && msg.Buffer[16] == 0xff && msg.Buffer[17] == 0xff)
4659 smprintf(s, "No alarm\n");
4660 } else {
4661 diff = ((unsigned int)msg.Buffer[14]) << 24;
4662 diff += ((unsigned int)msg.Buffer[15]) << 16;
4663 diff += ((unsigned int)msg.Buffer[16]) << 8;
4664 diff += msg.Buffer[17];
4666 memcpy(&Last->Entries[Last->EntriesNum].Date,&Date,sizeof(GSM_DateTime));
4667 GetTimeDifference(diff, &Last->Entries[Last->EntriesNum].Date, false, 60);
4668 smprintf(s, "Alarm date : %02i-%02i-%04i %02i:%02i:%02i\n",
4669 Last->Entries[Last->EntriesNum].Date.Day, Last->Entries[Last->EntriesNum].Date.Month,
4670 Last->Entries[Last->EntriesNum].Date.Year, Last->Entries[Last->EntriesNum].Date.Hour,
4671 Last->Entries[Last->EntriesNum].Date.Minute,Last->Entries[Last->EntriesNum].Date.Second);
4673 Last->Entries[Last->EntriesNum].EntryType = TODO_ALARM_DATETIME;
4674 if (msg.Buffer[22]==0x00 && msg.Buffer[23]==0x00 &&
4675 msg.Buffer[24]==0x00 && msg.Buffer[25]==0x00)
4677 Last->Entries[Last->EntriesNum].EntryType = TODO_SILENT_ALARM_DATETIME;
4678 smprintf(s, "Alarm type : Silent\n");
4680 Last->EntriesNum++;
4683 return GE_NONE;
4686 /* ToDo support - 6610 style */
4687 static GSM_Error N6510_GetNextToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh)
4689 GSM_Error error;
4690 GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
4691 /* The same to getting calendar method 3 */
4692 unsigned char req[] = {
4693 N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00,
4694 0x00,0x99, /* Location */
4695 0xff,0xff,0xff,0xff,0x01};
4697 if (refresh) {
4698 error=N6510_GetCalendarInfo3(s,LastToDo,false);
4699 if (error!=GE_NONE) return error;
4700 ToDo->Location = 1;
4701 } else {
4702 ToDo->Location++;
4705 if (ToDo->Location > LastToDo->Number) return GE_EMPTY;
4707 req[8] = LastToDo->Location[ToDo->Location-1] >> 8;
4708 req[9] = LastToDo->Location[ToDo->Location-1] & 0xff;
4710 s->Phone.Data.ToDo = ToDo;
4711 smprintf(s, "Getting todo method 2\n");
4712 return GSM_WaitFor (s, req, 15, 0x13, 4, ID_GetToDo);
4715 static GSM_Error N6510_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh)
4717 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) {
4718 return N6510_GetNextToDo1(s, ToDo, refresh);
4719 } else if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) {
4720 return N6510_GetNextToDo2(s, ToDo, refresh);
4721 } else {
4722 return GE_NOTSUPPORTED;
4726 /* ToDo support - 6310 style */
4727 static GSM_Error N6510_ReplyDeleteAllToDo1(GSM_Protocol_Message msg, GSM_StateMachine *s)
4729 smprintf(s, "All TODO deleted\n");
4730 return GE_NONE;
4733 /* ToDo support - 6310 style */
4734 static GSM_Error N6510_DeleteAllToDo1(GSM_StateMachine *s)
4736 unsigned char req[] = {N6110_FRAME_HEADER, 0x11};
4738 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) {
4739 return GE_NOTSUPPORTED;
4742 smprintf(s, "Deleting all ToDo method 1\n");
4743 return GSM_WaitFor (s, req, 4, 0x55, 4, ID_DeleteAllToDo);
4746 static GSM_Error N6510_DeleteToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
4748 GSM_Error error;
4749 GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
4750 GSM_CalendarEntry Note;
4752 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) {
4753 return GE_NOTSUPPORTED;
4756 error=N6510_GetCalendarInfo3(s,LastToDo,false);
4757 if (error!=GE_NONE) return error;
4759 smprintf(s, "Deleting ToDo method 2\n");
4761 if (ToDo->Location > LastToDo->Number || ToDo->Location == 0) return GE_INVALIDLOCATION;
4763 Note.Location = LastToDo->Location[ToDo->Location];
4764 return N71_65_DelCalendar(s,&Note);
4767 /* ToDo support - 6310 style */
4768 static GSM_Error N6510_ReplyGetToDoFirstLoc1(GSM_Protocol_Message msg, GSM_StateMachine *s)
4770 smprintf(s, "TODO first location received method 1: %02x\n",msg.Buffer[9]);
4771 s->Phone.Data.ToDo->Location = msg.Buffer[9];
4772 return GE_NONE;
4775 /* ToDo support - 6310 style */
4776 static GSM_Error N6510_ReplyAddToDo1(GSM_Protocol_Message msg, GSM_StateMachine *s)
4778 smprintf(s, "TODO set OK\n");
4779 return GE_NONE;
4782 /* ToDo support - 6310 style */
4783 static GSM_Error N6510_AddToDo1(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
4785 int Text, Alarm, EndTime, Completed, ulen, Phone;
4786 GSM_Error error;
4787 unsigned char reqLoc[] = {N6110_FRAME_HEADER, 0x0F};
4788 unsigned char reqSet[500] = {
4789 N6110_FRAME_HEADER, 0x01,
4790 0x03, /* Priority */
4791 0x00, /* Length of text */
4792 0x80,0x00,0x00,
4793 0x18}; /* Location */
4795 s->Phone.Data.ToDo = ToDo;
4797 smprintf(s, "Getting first ToDo location\n");
4798 error = GSM_WaitFor (s, reqLoc, 4, 0x55, 4, ID_SetToDo);
4799 if (error != GE_NONE) return error;
4800 reqSet[9] = ToDo->Location;
4802 switch (ToDo->Priority) {
4803 case GSM_Priority_Low : reqSet[4] = 3; break;
4804 case GSM_Priority_Medium: reqSet[4] = 2; break;
4805 case GSM_Priority_High : reqSet[4] = 1; break;
4808 GSM_ToDoFindDefaultTextTimeAlarmCompleted(ToDo, &Text, &Alarm, &Completed, &EndTime, &Phone);
4810 if (Text == -1) return GE_NOTSUPPORTED; /* XXX: shouldn't this be handled different way? */
4811 ulen = UnicodeLength(ToDo->Entries[Text].Text);
4812 reqSet[5] = ulen+1;
4813 CopyUnicodeString(reqSet+10,ToDo->Entries[Text].Text);
4814 reqSet[10+ulen*2] = 0x00;
4815 reqSet[10+ulen*2+1] = 0x00;
4816 smprintf(s, "Adding ToDo method 1\n");
4817 return GSM_WaitFor (s, reqSet, 12+ulen*2, 0x55, 4, ID_SetToDo);
4820 static GSM_Error N6510_ReplyAddToDo2(GSM_Protocol_Message msg, GSM_StateMachine *s)
4822 smprintf(s, "ToDo added method 2\n");
4823 return GE_NONE;
4826 static GSM_Error N6510_ReplyGetToDoFirstLoc2(GSM_Protocol_Message msg, GSM_StateMachine *s)
4828 smprintf(s, "First ToDo location method 2: %i\n",msg.Buffer[8]*256+msg.Buffer[9]);
4829 s->Phone.Data.ToDo->Location = msg.Buffer[9];
4830 return GE_NONE;
4833 static GSM_Error N6510_AddToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
4835 GSM_CalendarEntry Note;
4836 time_t t_time1,t_time2;
4837 long diff;
4838 GSM_Error error;
4839 GSM_DateTime DT;
4840 int Text, Alarm, EndTime, Completed, count=54, Phone;
4841 unsigned char reqLoc[] = {N6110_FRAME_HEADER, 0x95, 0x01};
4842 unsigned char req[5000] = {
4843 N6110_FRAME_HEADER, 0x65,
4844 0x01, /* 0 = calendar, 1 = todo */
4845 0x00, 0x00, 0x00,
4846 0x00, 0x00, /* location */
4847 0x00, 0x00, 0x00, 0x00,
4848 0xFF, 0xFF, 0xFF, 0xFF, /* alarm */
4849 0x80, 0x00, 0x00,
4850 0x01, /* note icon */
4851 0xFF, 0xFF, 0xFF, 0xFF, /* alarm type */
4852 0x00, /* 0x02 or 0x00 */
4853 0x01, /* note type */
4854 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* start date/time */
4855 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* end date/time */
4856 0x00, 0x00, /* recurrance */
4857 0x00, 0x00, /* birth year */
4858 0x20, /* ToDo priority */
4859 0x00, /* ToDo completed ? */
4860 0x00, 0x00, 0x00,
4861 0x00, /* note text length */
4862 0x00, /* phone length/meeting place */
4863 0x00, 0x00, 0x00};
4865 s->Phone.Data.ToDo = ToDo;
4867 smprintf(s, "Getting first free ToDo location method 2\n");
4868 error = GSM_WaitFor (s, reqLoc, 5, 0x13, 4, ID_SetToDo);
4869 if (error!=GE_NONE) return error;
4870 req[8] = ToDo->Location/256;
4871 req[9] = ToDo->Location%256;
4873 Note.Type = GCN_MEETING;
4874 DT.Year = 2004; DT.Month = 1; DT.Day = 1;
4875 DT.Hour = 12; DT.Minute = 12; DT.Second = 0;
4876 memcpy(&Note.Entries[0].Date,&DT,sizeof(GSM_DateTime));
4877 Note.Entries[0].EntryType = CAL_START_DATETIME;
4878 memcpy(&Note.Entries[1].Date,&DT,sizeof(GSM_DateTime));
4879 Note.Entries[1].EntryType = CAL_END_DATETIME;
4880 EncodeUnicode(Note.Entries[2].Text,"ala",3);
4881 Note.Entries[2].EntryType = CAL_TEXT;
4882 Note.EntriesNum = 3;
4883 error=N6510_FindCalendarIconID3(s, &Note, &req[21]);
4884 if (error!=GE_NONE) return error;
4886 switch (ToDo->Priority) {
4887 case GSM_Priority_Low : req[44] = 0x10; break;
4888 case GSM_Priority_Medium: req[44] = 0x20; break;
4889 case GSM_Priority_High : req[44] = 0x30; break;
4892 GSM_ToDoFindDefaultTextTimeAlarmCompleted(ToDo, &Text, &Alarm, &Completed, &EndTime, &Phone);
4894 if (Completed != -1) req[45] = 0x01;
4896 if (EndTime == -1) {
4897 GSM_GetCurrentDateTime(&DT);
4898 } else {
4899 memcpy(&DT,&ToDo->Entries[EndTime].Date,sizeof(GSM_DateTime));
4901 /*Start time*/
4902 req[28] = DT.Year >> 8;
4903 req[29] = DT.Year & 0xff;
4904 req[30] = DT.Month;
4905 req[31] = DT.Day;
4906 req[32] = DT.Hour;
4907 req[33] = DT.Minute;
4908 /*End time*/
4909 req[34] = DT.Year >> 8;
4910 req[35] = DT.Year & 0xff;
4911 req[36] = DT.Month;
4912 req[37] = DT.Day;
4913 req[38] = DT.Hour;
4914 req[39] = DT.Minute;
4916 if (Alarm != -1) {
4917 if (ToDo->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME)
4919 req[22] = 0x00; req[23] = 0x00; req[24] = 0x00; req[25] = 0x00;
4921 t_time2 = Fill_Time_T(DT,8);
4922 t_time1 = Fill_Time_T(ToDo->Entries[Alarm].Date,8);
4923 diff = (t_time1-t_time2)/60;
4925 smprintf(s, " Difference : %i seconds or minutes\n", -diff);
4926 req[14] = (unsigned char)(-diff >> 24);
4927 req[15] = (unsigned char)(-diff >> 16);
4928 req[16] = (unsigned char)(-diff >> 8);
4929 req[17] = (unsigned char)(-diff);
4932 if (Text != -1) {
4933 req[49] = UnicodeLength(ToDo->Entries[Text].Text);
4934 CopyUnicodeString(req+54,ToDo->Entries[Text].Text);
4935 count+= req[49]*2;
4938 req[count++] = 0x00;
4940 smprintf(s, "Adding ToDo method 2\n");
4941 return GSM_WaitFor (s, req, count, 0x13, 4, ID_SetToDo);
4944 static GSM_Error N6510_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
4946 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) {
4947 return N6510_AddToDo1(s, ToDo);
4948 } else if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) {
4949 return N6510_AddToDo2(s, ToDo);
4950 } else {
4951 return GE_NOTSUPPORTED;
4955 static GSM_Error N6510_ReplyGetLocale(GSM_Protocol_Message msg, GSM_StateMachine *s)
4957 GSM_Locale *locale = s->Phone.Data.Locale;
4959 switch (msg.Buffer[3]) {
4960 case 0x8A:
4961 smprintf(s, "Date settings received\n");
4962 switch (msg.Buffer[4]) {
4963 case 0x00:
4964 locale->DateFormat = GSM_Date_DDMMYYYY;
4965 locale->DateSeparator = '.';
4966 break;
4967 case 0x01:
4968 locale->DateFormat = GSM_Date_MMDDYYYY;
4969 locale->DateSeparator = '.';
4970 break;
4971 case 0x02:
4972 locale->DateFormat = GSM_Date_YYYYMMDD;
4973 locale->DateSeparator = '.';
4974 break;
4975 case 0x04:
4976 locale->DateFormat = GSM_Date_DDMMYYYY;
4977 locale->DateSeparator = '/';
4978 break;
4979 case 0x05:
4980 locale->DateFormat = GSM_Date_MMDDYYYY;
4981 locale->DateSeparator = '/';
4982 break;
4983 case 0x06:
4984 locale->DateFormat = GSM_Date_YYYYMMDD;
4985 locale->DateSeparator = '/';
4986 break;
4987 case 0x08:
4988 locale->DateFormat = GSM_Date_DDMMYYYY;
4989 locale->DateSeparator = '-';
4990 break;
4991 case 0x09:
4992 locale->DateFormat = GSM_Date_MMDDYYYY;
4993 locale->DateSeparator = '-';
4994 break;
4995 case 0x0A:
4996 locale->DateFormat = GSM_Date_YYYYMMDD;
4997 locale->DateSeparator = '-';
4998 break;
4999 default:/* FIXME */
5000 locale->DateFormat = GSM_Date_DDMMYYYY;
5001 locale->DateSeparator = '/';
5002 break;
5004 return GE_NONE;
5006 return GE_UNKNOWNRESPONSE;
5009 static GSM_Error N6510_GetLocale(GSM_StateMachine *s, GSM_Locale *locale)
5011 unsigned char req[] = {N6110_FRAME_HEADER, 0x89};
5013 s->Phone.Data.Locale = locale;
5015 smprintf(s, "Getting date format\n");
5016 return GSM_WaitFor (s, req, 4, 0x13, 4, ID_GetLocale);
5019 static GSM_Error N6510_ReplyGetCalendarSettings(GSM_Protocol_Message msg, GSM_StateMachine *s)
5021 GSM_CalendarSettings *sett = s->Phone.Data.CalendarSettings;
5023 switch (msg.Buffer[3]) {
5024 case 0x86:
5025 smprintf(s, "Auto deleting setting received\n");
5026 sett->AutoDelete = msg.Buffer[4];
5027 return GE_NONE;
5028 case 0x8E:
5029 smprintf(s, "Start day for calendar received\n");
5030 switch(msg.Buffer[4]) {
5031 case 0x03:
5032 sett->StartDay = 6;
5033 return GE_NONE;
5034 case 0x02:
5035 sett->StartDay = 7;
5036 return GE_NONE;
5037 case 0x01:
5038 sett->StartDay = 1;
5039 return GE_NONE;
5041 break;
5043 return GE_UNKNOWNRESPONSE;
5046 static GSM_Error N6510_GetCalendarSettings(GSM_StateMachine *s, GSM_CalendarSettings *settings)
5048 GSM_Error error;
5049 unsigned char req1[] = {N6110_FRAME_HEADER, 0x85};
5050 unsigned char req2[] = {N6110_FRAME_HEADER, 0x8D};
5052 s->Phone.Data.CalendarSettings = settings;
5054 smprintf(s, "Getting auto delete\n");
5055 error = GSM_WaitFor (s, req1, 4, 0x13, 4, ID_GetCalendarSettings);
5056 if (error != GE_NONE) return error;
5058 smprintf(s, "Getting start day for week\n");
5059 return GSM_WaitFor (s, req2, 4, 0x13, 4, ID_GetCalendarSettings);
5062 GSM_Error N6510_CancelCall(GSM_StateMachine *s, int ID, bool all)
5064 if (all) return GE_NOTSUPPORTED;
5065 return DCT3DCT4_CancelCall(s,ID);
5068 GSM_Error N6510_AnswerCall(GSM_StateMachine *s, int ID, bool all)
5070 if (all) return GE_NOTSUPPORTED;
5071 return DCT3DCT4_AnswerCall(s,ID);
5074 static GSM_Error N6510_ReplyAddSMSFolder(GSM_Protocol_Message msg, GSM_StateMachine *s)
5076 smprintf(s,"SMS folder \"%s\" has been added\n",DecodeUnicodeString(msg.Buffer+10));
5077 return GE_NONE;
5080 GSM_Error N6510_AddSMSFolder(GSM_StateMachine *s, unsigned char *name)
5082 unsigned char req[200] = {N6110_FRAME_HEADER, 0x10, 0x01, 0x00, 0x01,
5083 0x00, /* Length */
5084 0x00, 0x00};
5087 CopyUnicodeString(req+10,name);
5088 req[7] = UnicodeLength(name)*2 + 6;
5090 smprintf(s, "Adding SMS folder\n");
5091 return GSM_WaitFor (s, req, req[7] + 6, 0x14, 4, ID_AddSMSFolder);
5094 static GSM_Reply_Function N6510ReplyFunctions[] = {
5095 {N71_65_ReplyCallInfo, "\x01",0x03,0x02,ID_IncomingFrame },
5096 {N71_65_ReplyCallInfo, "\x01",0x03,0x03,ID_IncomingFrame },
5097 {N71_65_ReplyCallInfo, "\x01",0x03,0x04,ID_IncomingFrame },
5098 {N71_65_ReplyCallInfo, "\x01",0x03,0x05,ID_IncomingFrame },
5099 {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_AnswerCall },
5100 {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_IncomingFrame },
5101 {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_CancelCall },
5102 {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_IncomingFrame },
5103 {N71_65_ReplyCallInfo, "\x01",0x03,0x0A,ID_IncomingFrame },
5104 {N71_65_ReplyCallInfo, "\x01",0x03,0x0B,ID_IncomingFrame },
5105 {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_DialVoice },
5106 {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_IncomingFrame },
5107 {N71_65_ReplyCallInfo, "\x01",0x03,0x23,ID_IncomingFrame },
5108 {N71_65_ReplyCallInfo, "\x01",0x03,0x25,ID_IncomingFrame },
5109 {N71_65_ReplyCallInfo, "\x01",0x03,0x27,ID_IncomingFrame },
5110 {N71_65_ReplySendDTMF, "\x01",0x03,0x51,ID_SendDTMF },
5111 {N71_65_ReplyCallInfo, "\x01",0x03,0x53,ID_IncomingFrame },
5112 {N71_65_ReplySendDTMF, "\x01",0x03,0x59,ID_SendDTMF },
5113 {N71_65_ReplySendDTMF, "\x01",0x03,0x5E,ID_SendDTMF },
5115 {N6510_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame },
5116 {N6510_ReplyIncomingSMS, "\x02",0x03,0x04,ID_IncomingFrame },
5117 {N6510_ReplySetSMSC, "\x02",0x03,0x13,ID_SetSMSC },
5118 {N6510_ReplyGetSMSC, "\x02",0x03,0x15,ID_GetSMSC },
5120 {N6510_ReplyGetMemoryStatus, "\x03",0x03,0x04,ID_GetMemoryStatus },
5121 {N6510_ReplyGetMemory, "\x03",0x03,0x08,ID_GetMemory },
5122 {N6510_ReplyDeleteMemory, "\x03",0x03,0x10,ID_SetMemory },
5123 {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetBitmap },
5124 {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetMemory },
5126 {DCT3DCT4_ReplyCallDivert, "\x06",0x03,0x02,ID_Divert },
5127 {N71_65_ReplyUSSDInfo, "\x06",0x03,0x03,ID_IncomingFrame },
5128 {NoneReply, "\x06",0x03,0x06,ID_IncomingFrame },
5129 {NoneReply, "\x06",0x03,0x09,ID_IncomingFrame },
5131 {N6510_ReplyEnterSecurityCode, "\x08",0x03,0x08,ID_EnterSecurityCode },
5132 {N6510_ReplyEnterSecurityCode, "\x08",0x03,0x09,ID_EnterSecurityCode },
5133 {N6510_ReplyGetSecurityStatus, "\x08",0x03,0x12,ID_GetSecurityStatus },
5135 {N6510_ReplyGetNetworkInfo, "\x0A",0x03,0x01,ID_GetNetworkInfo },
5136 {N6510_ReplyGetNetworkInfo, "\x0A",0x03,0x01,ID_IncomingFrame },
5137 {N6510_ReplyLogIntoNetwork, "\x0A",0x03,0x02,ID_IncomingFrame },
5138 {N6510_ReplyGetSignalQuality, "\x0A",0x03,0x0C,ID_GetSignalQuality },
5139 {N6510_ReplyGetIncSignalQuality, "\x0A",0x03,0x1E,ID_IncomingFrame },
5140 {NoneReply, "\x0A",0x03,0x20,ID_IncomingFrame },
5141 {N6510_ReplyGetOperatorLogo, "\x0A",0x03,0x24,ID_GetBitmap },
5142 {N6510_ReplySetOperatorLogo, "\x0A",0x03,0x26,ID_SetBitmap },
5144 {NoneReply, "\x0B",0x03,0x01,ID_PlayTone },
5145 {NoneReply, "\x0B",0x03,0x15,ID_PlayTone },
5146 {NoneReply, "\x0B",0x03,0x16,ID_PlayTone },
5148 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x02,ID_SetCalendarNote },
5149 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x04,ID_SetCalendarNote },
5150 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x06,ID_SetCalendarNote },
5151 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x08,ID_SetCalendarNote },
5152 {N71_65_ReplyDelCalendar, "\x13",0x03,0x0C,ID_DeleteCalendarNote },
5153 {N71_65_ReplyGetNextCalendar1, "\x13",0x03,0x1A,ID_GetCalendarNote },/*method 1*/
5154 {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0x32,ID_GetCalendarNotePos },/*method 1*/
5155 {N6510_ReplyGetCalendarInfo, "\x13",0x03,0x3B,ID_GetCalendarNotesInfo},/*method 1*/
5156 #ifdef DEBUG
5157 {N71_65_ReplyGetNextCalendar2, "\x13",0x03,0x3F,ID_GetCalendarNote },
5158 #endif
5159 {N71_65_ReplyAddCalendar2, "\x13",0x03,0x41,ID_SetCalendarNote },/*method 2*/
5160 {N6510_ReplyAddCalendar3, "\x13",0x03,0x66,ID_SetCalendarNote },/*method 3*/
5161 {N6510_ReplyAddToDo2, "\x13",0x03,0x66,ID_SetToDo },
5162 {N6510_ReplyGetCalendar3, "\x13",0x03,0x7E,ID_GetCalendarNote },/*method 3*/
5163 {N6510_ReplyGetToDo2, "\x13",0x03,0x7E,ID_GetToDo },
5164 {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x86,ID_GetCalendarSettings },
5165 {N6510_ReplyGetLocale, "\x13",0x03,0x8A,ID_GetLocale },
5166 {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x8E,ID_GetCalendarSettings },
5167 {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0x96,ID_GetCalendarNotePos },/*method 3*/
5168 {N6510_ReplyGetToDoFirstLoc2, "\x13",0x03,0x96,ID_SetToDo },
5169 {N6510_ReplyGetCalendarInfo, "\x13",0x03,0x9F,ID_GetCalendarNotesInfo},/*method 3*/
5170 {N6510_ReplyGetToDoStatus2, "\x13",0x03,0x9F,ID_GetToDo },
5172 {N6510_ReplySaveSMSMessage, "\x14",0x03,0x01,ID_SaveSMSMessage },
5173 {N6510_ReplySetPicture, "\x14",0x03,0x01,ID_SetBitmap },
5174 {N6510_ReplyGetSMSMessage, "\x14",0x03,0x03,ID_GetSMSMessage },
5175 {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x05,ID_DeleteSMSMessage },
5176 {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x06,ID_DeleteSMSMessage },
5177 {N6510_ReplyGetSMSStatus, "\x14",0x03,0x09,ID_GetSMSStatus },
5178 {N6510_ReplyGetSMSFolderStatus, "\x14",0x03,0x0d,ID_GetSMSFolderStatus },
5179 {N6510_ReplyGetSMSMessage, "\x14",0x03,0x0f,ID_GetSMSMessage },
5180 {N6510_ReplyAddSMSFolder, "\x14",0x03,0x11,ID_AddSMSFolder },
5181 {N6510_ReplyGetSMSFolders, "\x14",0x03,0x13,ID_GetSMSFolders },
5182 {N6510_ReplySaveSMSMessage, "\x14",0x03,0x17,ID_SaveSMSMessage },
5183 {N6510_ReplyGetSMSStatus, "\x14",0x03,0x1a,ID_GetSMSStatus },
5185 {DCT4_ReplySetPhoneMode, "\x15",0x03,0x64,ID_Reset },
5186 {DCT4_ReplyGetPhoneMode, "\x15",0x03,0x65,ID_Reset },
5187 {NoneReply, "\x15",0x03,0x68,ID_Reset },
5189 {N6510_ReplyGetBatteryCharge, "\x17",0x03,0x0B,ID_GetBatteryCharge },
5191 {N6510_ReplySetDateTime, "\x19",0x03,0x02,ID_SetDateTime },
5192 {N6510_ReplyGetDateTime, "\x19",0x03,0x0B,ID_GetDateTime },
5193 {N6510_ReplySetAlarm, "\x19",0x03,0x12,ID_SetAlarm },
5194 {N6510_ReplyGetAlarm, "\x19",0x03,0x1A,ID_GetAlarm },
5195 {N6510_ReplyGetAlarm, "\x19",0x03,0x20,ID_GetAlarm },
5197 {DCT4_ReplyGetIMEI, "\x1B",0x03,0x01,ID_GetIMEI },
5198 {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x08,ID_GetHardware },
5199 {N6510_ReplyGetPPM, "\x1B",0x03,0x08,ID_GetPPM },
5200 {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x0C,ID_GetProductCode },
5202 /* 0x1C - vibra */
5204 {N6510_ReplyGetRingtonesInfo, "\x1f",0x03,0x08,ID_GetRingtonesInfo },
5205 {N6510_ReplyDeleteRingtones, "\x1f",0x03,0x11,ID_SetRingtone },
5206 {N6510_ReplyGetRingtone, "\x1f",0x03,0x13,ID_GetRingtone },
5207 {N6510_ReplySetBinRingtone, "\x1f",0x03,0x0F,ID_SetRingtone },
5209 /* 0x23 - voice records */
5211 {N6510_ReplyGetProfile, "\x39",0x03,0x02,ID_GetProfile },
5212 {N6510_ReplySetProfile, "\x39",0x03,0x04,ID_SetProfile },
5213 {N6510_ReplyGetProfile, "\x39",0x03,0x06,ID_GetProfile },
5215 {N6510_ReplySetLight, "\x3A",0x03,0x06,ID_SetLight },
5217 {N6510_ReplyGetFMStation, "\x3E",0x03,0x06,ID_GetFMStation },
5218 {N6510_ReplyGetFMStatus, "\x3E",0x03,0x0E,ID_GetFMStation },
5219 {N6510_ReplySetFMStation, "\x3E",0x03,0x15,ID_SetFMStation },
5220 {N6510_ReplyGetFMStation, "\x3E",0x03,0x16,ID_GetFMStation },
5222 {DCT3DCT4_ReplyEnableWAP, "\x3f",0x03,0x01,ID_EnableWAP },
5223 {DCT3DCT4_ReplyEnableWAP, "\x3f",0x03,0x02,ID_EnableWAP },
5224 {NoneReply, "\x3f",0x03,0x04,ID_EnableWAP },
5225 {NoneReply, "\x3f",0x03,0x05,ID_EnableWAP },
5226 {N6510_ReplyGetWAPBookmark, "\x3f",0x03,0x07,ID_GetWAPBookmark },
5227 {N6510_ReplyGetWAPBookmark, "\x3f",0x03,0x08,ID_GetWAPBookmark },
5228 {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0A,ID_SetWAPBookmark },
5229 {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0B,ID_SetWAPBookmark },
5230 {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0D,ID_DeleteWAPBookmark },
5231 {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0E,ID_DeleteWAPBookmark },
5232 {DCT3DCT4_ReplyGetActiveWAPMMSSet,"\x3f",0x03,0x10,ID_GetWAPSettings },
5233 {DCT3DCT4_ReplySetActiveWAPMMSSet,"\x3f",0x03,0x13,ID_SetWAPSettings },
5234 {DCT3DCT4_ReplySetActiveWAPMMSSet,"\x3f",0x03,0x13,ID_SetMMSSettings },
5235 {N6510_ReplyGetWAPMMSSettings, "\x3f",0x03,0x16,ID_GetWAPSettings },
5236 {N6510_ReplyGetWAPMMSSettings, "\x3f",0x03,0x16,ID_GetMMSSettings },
5237 {N6510_ReplyGetWAPMMSSettings, "\x3f",0x03,0x17,ID_GetWAPSettings },
5238 {N6510_ReplyGetWAPMMSSettings, "\x3f",0x03,0x17,ID_GetMMSSettings },
5239 {N6510_ReplySetWAPMMSSettings, "\x3f",0x03,0x19,ID_SetWAPSettings },
5240 {N6510_ReplySetWAPMMSSettings, "\x3f",0x03,0x19,ID_SetMMSSettings },
5241 {N6510_ReplySetWAPMMSSettings, "\x3f",0x03,0x1A,ID_SetWAPSettings },
5242 {N6510_ReplySetWAPMMSSettings, "\x3f",0x03,0x1A,ID_SetMMSSettings },
5244 {N6510_ReplyGetOriginalIMEI, "\x42",0x07,0x00,ID_GetOriginalIMEI },
5245 {N6510_ReplyGetManufactureMonth, "\x42",0x07,0x00,ID_GetManufactureMonth },
5246 {N6510_ReplyGetOriginalIMEI, "\x42",0x07,0x01,ID_GetOriginalIMEI },
5247 {N6510_ReplyGetManufactureMonth, "\x42",0x07,0x02,ID_GetManufactureMonth },
5249 {N6510_ReplySetOperatorLogo, "\x43",0x03,0x08,ID_SetBitmap },
5250 {N6510_ReplyGetGPRSAccessPoint, "\x43",0x03,0x06,ID_GetGPRSPoint },
5251 {N6510_ReplySetGPRSAccessPoint1, "\x43",0x03,0x06,ID_SetGPRSPoint },
5252 #ifdef DEVELOP
5253 {N6510_ReplyEnableGPRSAccessPoint,"\x43",0x03,0x06,ID_EnableGPRSPoint },
5254 #endif
5255 {NoneReply, "\x43",0x03,0x08,ID_SetGPRSPoint },
5257 /* 0x4A - voice records */
5259 /* 0x53 - simlock */
5261 {N6510_ReplyAddToDo1, "\x55",0x03,0x02,ID_SetToDo },
5262 {N6510_ReplyGetToDo1, "\x55",0x03,0x04,ID_GetToDo },
5263 {N6510_ReplyGetToDoFirstLoc1, "\x55",0x03,0x10,ID_SetToDo },
5264 {N6510_ReplyDeleteAllToDo1, "\x55",0x03,0x12,ID_DeleteAllToDo },
5265 {N6510_ReplyGetToDoStatus1, "\x55",0x03,0x16,ID_GetToDo },
5267 {N6510_ReplyAddFileHeader, "\x6D",0x03,0x03,ID_AddFile },
5268 {N6510_ReplyAddFolder, "\x6D",0x03,0x05,ID_AddFolder },
5269 {N6510_ReplyGetFilePart, "\x6D",0x03,0x0F,ID_GetFile },
5270 {N6510_ReplyAddFileHeader, "\x6D",0x03,0x13,ID_AddFile },
5271 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x15,ID_GetFileInfo },
5272 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x15,ID_GetFile },
5273 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x15,ID_AddFile },
5274 {N6510_ReplyDeleteFile, "\x6D",0x03,0x19,ID_DeleteFile },
5275 {N6510_ReplyDeleteFile, "\x6D",0x03,0x1F,ID_DeleteFile },
5276 {N6510_ReplyGetFileSystemStatus, "\x6D",0x03,0x23,ID_FileSystemStatus },
5277 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x2F,ID_GetFileInfo },
5278 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x2F,ID_GetFile },
5279 {N6510_ReplyGetFileSystemStatus, "\x6D",0x03,0x2F,ID_FileSystemStatus },
5280 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x33,ID_GetFileInfo },
5281 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x33,ID_GetFile },
5282 {N6510_ReplyAddFilePart, "\x6D",0x03,0x41,ID_AddFile },
5283 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x43,ID_AddFile },
5284 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x43,ID_GetFile },
5285 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x43,ID_GetFileInfo },
5287 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x01,ID_GetBitmap },
5288 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x01,ID_SetBitmap },
5289 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x0F,ID_GetBitmap },
5290 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x0F,ID_SetBitmap },
5291 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x10,ID_GetBitmap },
5292 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x10,ID_SetBitmap },
5293 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x25,ID_SetBitmap },
5295 {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetModel },
5296 {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetFirmware },
5298 /* 0xD7 - Bluetooth */
5300 {N6510_ReplyGetRingtoneID, "\xDB",0x03,0x02,ID_SetRingtone },
5302 {NULL, "\x00",0x00,0x00,ID_None }
5305 GSM_Phone_Functions N6510Phone = {
5306 "1100|1100a|1100b|3100|3100b|3200|3200a|3300|3510|3510i|3530|3590|3595|5100|6100|6200|6220|6310|6310i|6510|6610|6800|7210|7250|7250i|8310|8390|8910|8910i",
5307 N6510ReplyFunctions,
5308 N6510_Initialise,
5309 NONEFUNCTION, /* Terminate */
5310 GSM_DispatchMessage,
5311 N6510_ShowStartInfo,
5312 NOKIA_GetManufacturer,
5313 DCT3DCT4_GetModel,
5314 DCT3DCT4_GetFirmware,
5315 DCT4_GetIMEI,
5316 N6510_GetOriginalIMEI,
5317 N6510_GetManufactureMonth,
5318 DCT4_GetProductCode,
5319 DCT4_GetHardware,
5320 N6510_GetPPM,
5321 NOTSUPPORTED, /* GetSIMIMSI */
5322 N6510_GetDateTime,
5323 N6510_SetDateTime,
5324 N6510_GetAlarm,
5325 N6510_SetAlarm,
5326 N6510_GetLocale,
5327 NOTSUPPORTED, /* SetLocale */
5328 N6510_PressKey,
5329 DCT4_Reset,
5330 NOTIMPLEMENTED, /* ResetPhoneSettings */
5331 N6510_EnterSecurityCode,
5332 N6510_GetSecurityStatus,
5333 NOTSUPPORTED, /* GetDisplayStatus */
5334 NOTIMPLEMENTED, /* SetAutoNetworkLogin */
5335 N6510_GetBatteryCharge,
5336 N6510_GetSignalQuality,
5337 N6510_GetNetworkInfo,
5338 NOTSUPPORTED, /* GetCategory */
5339 NOTSUPPORTED, /* GetCategoryStatus */
5340 N6510_GetMemoryStatus,
5341 N6510_GetMemory,
5342 NOTIMPLEMENTED, /* GetNextMemory */
5343 N6510_SetMemory,
5344 NOTIMPLEMENTED, /* AddMemory */
5345 N6510_DeleteMemory,
5346 NOTIMPLEMENTED, /* DeleteAllMemory */
5347 N6510_GetSpeedDial,
5348 NOTIMPLEMENTED, /* SetSpeedDial */
5349 N6510_GetSMSC,
5350 N6510_SetSMSC,
5351 N6510_GetSMSStatus,
5352 N6510_GetSMSMessage,
5353 N6510_GetNextSMSMessage,
5354 N6510_SetSMS,
5355 N6510_AddSMS,
5356 N6510_DeleteSMSMessage,
5357 N6510_SendSMSMessage,
5358 NOKIA_SetIncomingSMS,
5359 NOTIMPLEMENTED, /* SetIncomingCB */
5360 N6510_GetSMSFolders,
5361 N6510_AddSMSFolder,
5362 NOTIMPLEMENTED, /* DeleteSMSFolder */
5363 N6510_DialVoice,
5364 N6510_AnswerCall,
5365 N6510_CancelCall,
5366 NOTIMPLEMENTED, /* HoldCall */
5367 NOTIMPLEMENTED, /* UnholdCall */
5368 NOTIMPLEMENTED, /* ConferenceCall */
5369 NOTIMPLEMENTED, /* SplitCall */
5370 NOTIMPLEMENTED, /* TransferCall */
5371 NOTIMPLEMENTED, /* SwitchCall */
5372 DCT3DCT4_GetCallDivert,
5373 DCT3DCT4_SetCallDivert,
5374 DCT3DCT4_CancelAllDiverts,
5375 NOKIA_SetIncomingCall,
5376 NOKIA_SetIncomingUSSD,
5377 DCT3DCT4_SendDTMF,
5378 N6510_GetRingtone,
5379 N6510_SetRingtone,
5380 N6510_GetRingtonesInfo,
5381 N6510_DeleteUserRingtones,
5382 N6510_PlayTone,
5383 DCT3DCT4_GetWAPBookmark,
5384 N6510_SetWAPBookmark,
5385 DCT3DCT4_DeleteWAPBookmark,
5386 N6510_GetWAPSettings,
5387 N6510_SetWAPSettings,
5388 N6510_GetMMSSettings,
5389 N6510_SetMMSSettings,
5390 N6510_GetBitmap,
5391 N6510_SetBitmap,
5392 N6510_GetToDoStatus,
5393 NOTIMPLEMENTED, /* GetToDo */
5394 N6510_GetNextToDo,
5395 NOTIMPLEMENTED, /* SetToDo */
5396 N6510_AddToDo,
5397 N6510_DeleteToDo2,
5398 N6510_DeleteAllToDo1,
5399 N6510_GetCalendarStatus,
5400 NOTIMPLEMENTED, /* GetCalendar */
5401 N6510_GetNextCalendar,
5402 NOTIMPLEMENTED, /* SetCalendar */
5403 N6510_AddCalendar,
5404 N71_65_DelCalendar,
5405 NOTIMPLEMENTED, /* DeleteAllCalendar */
5406 N6510_GetCalendarSettings,
5407 NOTSUPPORTED, /* SetCalendarSettings */
5408 NOTIMPLEMENTED, /* GetNote */
5409 N6510_GetProfile,
5410 N6510_SetProfile,
5411 N6510_GetFMStation,
5412 N6510_SetFMStation,
5413 N6510_ClearFMStations,
5414 N6510_GetNextFileFolder,
5415 N6510_GetFilePart,
5416 N6510_AddFilePart,
5417 N6510_GetFileSystemStatus,
5418 N6510_DeleteFile,
5419 N6510_AddFolder,
5420 N6510_GetGPRSAccessPoint,
5421 N6510_SetGPRSAccessPoint
5424 #endif
5426 /* How should editor hadle tabs in this file? Add editor commands here.
5427 * vim: noexpandtab sw=8 ts=8 sts=8: