summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/phone/nokia/dct4/n6510.c
authorzautrix <zautrix>2004-08-07 17:24:40 (UTC)
committer zautrix <zautrix>2004-08-07 17:24:40 (UTC)
commit88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22 (patch) (unidiff)
tree6331418973714243beb674abc87692277b83869d /gammu/emb/common/phone/nokia/dct4/n6510.c
parentef8a09ce74ad3f0a51484d03fdf009bd5b3677bf (diff)
downloadkdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.zip
kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.gz
kdepimpi-88b0d33b8b0b1f6ae320cfc863ca6a47fa8fec22.tar.bz2
Initial revision
Diffstat (limited to 'gammu/emb/common/phone/nokia/dct4/n6510.c') (more/less context) (show whitespace changes)
-rw-r--r--gammu/emb/common/phone/nokia/dct4/n6510.c5782
1 files changed, 5782 insertions, 0 deletions
diff --git a/gammu/emb/common/phone/nokia/dct4/n6510.c b/gammu/emb/common/phone/nokia/dct4/n6510.c
new file mode 100644
index 0000000..67fe492
--- a/dev/null
+++ b/gammu/emb/common/phone/nokia/dct4/n6510.c
@@ -0,0 +1,5782 @@
1/* (c) 2002-2004 by Marcin Wiacek */
2/* based on some work from Markus Plail, Pawel Kot and Gnokii */
3/* function for making CRC for filesystem (c) 2003 by Michael Schroeder */
4
5#include "../../../gsmstate.h"
6
7#ifdef GSM_ENABLE_NOKIA6510
8
9#include <string.h>
10#include <time.h>
11
12#include "../../../misc/coding/coding.h"
13#include "../../../gsmcomon.h"
14#include "../../../service/gsmlogo.h"
15#include "../nfunc.h"
16#include "../nfuncold.h"
17#include "../../pfunc.h"
18#include "dct4func.h"
19#include "n6510.h"
20
21static GSM_Error N6510_Initialise (GSM_StateMachine *s)
22{
23 s->Phone.Data.Priv.N6510.CalendarIconsNum = 0;
24
25 /* Enables various things like incoming SMS, call info, etc. */
26 return N71_65_EnableFunctions (s, "\x01\x02\x06\x0A\x14\x17\x39", 7);
27}
28
29static GSM_Error N6510_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s)
30{
31 smprintf(s, "Phonebook entry received\n");
32 switch (msg.Buffer[6]) {
33 case 0x0f:
34 return N71_65_ReplyGetMemoryError(msg.Buffer[10], s);
35 default:
36 return N71_65_DecodePhonebook(s, s->Phone.Data.Memory, s->Phone.Data.Bitmap, s->Phone.Data.SpeedDial, msg.Buffer+22, msg.Length-22,false);
37 }
38 return ERR_UNKNOWN;
39}
40
41static GSM_Error N6510_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry)
42{
43 unsigned char req[] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x01, 0x00, 0x01,
44 0xfe, 0x10, /* memory type */
45 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x01, /* location */
47 0x00, 0x00, 0x01};
48
49 req[9] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
50 if (req[9]==0xff) return ERR_NOTSUPPORTED;
51
52 if (entry->Location==0x00) return ERR_INVALIDLOCATION;
53
54 req[14] = entry->Location / 256;
55 req[15] = entry->Location % 256;
56
57 s->Phone.Data.Memory=entry;
58 smprintf(s, "Getting phonebook entry\n");
59 return GSM_WaitFor (s, req, 19, 0x03, 4, ID_GetMemory);
60}
61
62static GSM_Error N6510_ReplyGetMemoryStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
63{
64 GSM_Phone_Data *Data = &s->Phone.Data;
65
66 smprintf(s, "Memory status received\n");
67 /* Quess ;-)) */
68 if (msg.Buffer[14]==0x10) {
69 Data->MemoryStatus->MemoryFree = msg.Buffer[18]*256 + msg.Buffer[19];
70 } else {
71 Data->MemoryStatus->MemoryFree = msg.Buffer[17];
72 }
73 smprintf(s, "Size : %i\n",Data->MemoryStatus->MemoryFree);
74 Data->MemoryStatus->MemoryUsed = msg.Buffer[20]*256 + msg.Buffer[21];
75 smprintf(s, "Used : %i\n",Data->MemoryStatus->MemoryUsed);
76 Data->MemoryStatus->MemoryFree -= Data->MemoryStatus->MemoryUsed;
77 smprintf(s, "Free : %i\n",Data->MemoryStatus->MemoryFree);
78 return ERR_NONE;
79}
80
81static GSM_Error N6510_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status)
82{
83 unsigned char req[] = {N6110_FRAME_HEADER, 0x03, 0x02,
84 0x00, /* memory type */
85 0x55, 0x55, 0x55, 0x00};
86
87 req[5] = NOKIA_GetMemoryType(s, Status->MemoryType,N71_65_MEMORY_TYPES);
88 if (req[5]==0xff) return ERR_NOTSUPPORTED;
89
90 s->Phone.Data.MemoryStatus=Status;
91 smprintf(s, "Getting memory status\n");
92 return GSM_WaitFor (s, req, 10, 0x03, 4, ID_GetMemoryStatus);
93}
94
95static GSM_Error N6510_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s)
96{
97 int i, current, j;
98 GSM_Phone_Data *Data = &s->Phone.Data;
99
100 switch (msg.Buffer[4]) {
101 case 0x00:
102 smprintf(s, "SMSC received\n");
103 break;
104 case 0x02:
105 smprintf(s, "SMSC empty\n");
106 return ERR_INVALIDLOCATION;
107 default:
108 smprintf(s, "Unknown SMSC state: %02x\n",msg.Buffer[4]);
109 return ERR_UNKNOWNRESPONSE;
110 }
111 memset(Data->SMSC,0,sizeof(GSM_SMSC));
112 Data->SMSC->Location = msg.Buffer[8];
113 Data->SMSC->Format = SMS_FORMAT_Text;
114 switch (msg.Buffer[10]) {
115 case 0x00: Data->SMSC->Format = SMS_FORMAT_Text; break;
116 case 0x22: Data->SMSC->Format = SMS_FORMAT_Fax; break;
117 case 0x26: Data->SMSC->Format = SMS_FORMAT_Pager;break;
118 case 0x32: Data->SMSC->Format = SMS_FORMAT_Email;break;
119 }
120 Data->SMSC->Validity.Format= SMS_Validity_RelativeFormat;
121 Data->SMSC->Validity.Relative= msg.Buffer[12];
122 current = 14;
123 for (i=0;i<msg.Buffer[13];i++) {
124 switch (msg.Buffer[current]) {
125 case 0x81:
126 j=current+4;
127 while (msg.Buffer[j]!=0) {j++;}
128 j=j-33;
129 if (j>GSM_MAX_SMSC_NAME_LENGTH) {
130 smprintf(s, "Too long name\n");
131 return ERR_UNKNOWNRESPONSE;
132 }
133 CopyUnicodeString(Data->SMSC->Name,msg.Buffer+current+4);
134 smprintf(s, " Name \"%s\"\n", DecodeUnicodeString(Data->SMSC->Name));
135 break;
136 case 0x82:
137 switch (msg.Buffer[current+2]) {
138 case 0x01:
139 GSM_UnpackSemiOctetNumber(Data->SMSC->DefaultNumber,msg.Buffer+current+4,true);
140 smprintf(s, " Default number \"%s\"\n", DecodeUnicodeString(Data->SMSC->DefaultNumber));
141 break;
142 case 0x02:
143 GSM_UnpackSemiOctetNumber(Data->SMSC->Number,msg.Buffer+current+4,false);
144 smprintf(s, " Number \"%s\"\n", DecodeUnicodeString(Data->SMSC->Number));
145 break;
146 default:
147 smprintf(s, "Unknown SMSC number: %02x\n",msg.Buffer[current+2]);
148 return ERR_UNKNOWNRESPONSE;
149 }
150 break;
151 default:
152 smprintf(s, "Unknown SMSC block: %02x\n",msg.Buffer[current]);
153 return ERR_UNKNOWNRESPONSE;
154 }
155 current = current + msg.Buffer[current+1];
156 }
157 return ERR_NONE;
158}
159
160static GSM_Error N6510_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
161{
162 unsigned char req[] = {N6110_FRAME_HEADER, 0x14,
163 0x01, /* location */
164 0x00};
165
166 if (smsc->Location==0x00) return ERR_INVALIDLOCATION;
167
168 req[4]=smsc->Location;
169
170 s->Phone.Data.SMSC=smsc;
171 smprintf(s, "Getting SMSC\n");
172 return GSM_WaitFor (s, req, 6, 0x02, 4, ID_GetSMSC);
173}
174
175static GSM_Error N6510_ReplySetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s)
176{
177 switch (msg.Buffer[4]) {
178 case 0x00:
179 smprintf(s, "SMSC set OK\n");
180 return ERR_NONE;
181 case 0x02:
182 smprintf(s, "Invalid SMSC location\n");
183 return ERR_INVALIDLOCATION;
184 default:
185 smprintf(s, "Unknown SMSC state: %02x\n",msg.Buffer[4]);
186 return ERR_UNKNOWNRESPONSE;
187 }
188 return ERR_UNKNOWNRESPONSE;
189}
190
191static GSM_Error N6510_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
192{
193 int count = 13,i;
194 unsigned char req[256] = {N6110_FRAME_HEADER,
195 0x12, 0x55, 0x01, 0x0B, 0x34,
196 0x05, /* Location */
197 0x00,
198 0x00, /* Format */
199 0x00,
200 0xFF}; /* Validity*/
201
202 req[8] = smsc->Location;
203 switch (smsc->Format) {
204 case SMS_FORMAT_Text: req[10] = 0x00;break;
205 case SMS_FORMAT_Fax: req[10] = 0x22;break;
206 case SMS_FORMAT_Pager: req[10] = 0x26;break;
207 case SMS_FORMAT_Email: req[10] = 0x32;break;
208 }
209 req[12] = smsc->Validity.Relative;
210
211 /* We have now blocks. Number of blocks = 3 */
212 req[count++] = 0x03;
213
214 /* -------------- SMSC number ----------------- */
215 /* Block type: number */
216 req[count++] = 0x82;
217 /* Offset to next block */
218 req[count++] = 0x1A;
219 /* Type of number: SMSC number */
220 req[count++] = 0x02;
221 req[count] = GSM_PackSemiOctetNumber(smsc->Number, req+count+2, false) + 1;
222 if (req[count]>18) {
223 smprintf(s, "Too long SMSC number in frame\n");
224 return ERR_UNKNOWN;
225 }
226 req[count+1] = req[count] - 1;
227 count += 23;
228
229 /* --------------- Default number ------------- */
230 /* Block type: number */
231 req[count++] = 0x82;
232 /* Offset to next block */
233 req[count++] = 0x14;
234 /* Type of number: default number */
235 req[count++] = 0x01;
236 req[count] = GSM_PackSemiOctetNumber(smsc->DefaultNumber, req+count+2, true) + 1;
237 if (req[count]*2>12) {
238 smprintf(s, "Too long SMSC number in frame\n");
239 return ERR_UNKNOWN;
240 }
241 req[count+1] = req[count] - 1;
242 count += 17;
243
244 /* -------------- SMSC name ------------------- */
245 req[count++] = 0x81;
246 req[count++] = UnicodeLength(smsc->Name)*2 + 2 + 4;
247 req[count++] = UnicodeLength(smsc->Name)*2 + 2;
248 req[count++] = 0x00;
249 /* Can't make CopyUnicodeString(req+count,sms->Name) !!!!
250 * with MSVC6 count is changed then
251 */
252 i = count;
253 CopyUnicodeString(req+i,smsc->Name);
254 count += UnicodeLength(smsc->Name)*2 + 2;
255
256 smprintf(s, "Setting SMSC\n");
257 return GSM_WaitFor (s, req, count, 0x02, 4, ID_SetSMSC);
258}
259
260static GSM_Error N6510_ReplyGetNetworkInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
261{
262 int current = msg.Buffer[7]+7, tmp;
263 GSM_Phone_Data*Data = &s->Phone.Data;
264#ifdef DEBUG
265 char name[100];
266 GSM_NetworkInfo NetInfo;
267
268 smprintf(s, "Network status: ");
269 switch (msg.Buffer[8]) {
270 case 0x00 : smprintf(s, "home network\n"); break;
271 case 0x01 : smprintf(s, "roaming network\n"); break;
272 case 0x04 : smprintf(s, "not logged"); break;
273 case 0x06 : smprintf(s, "SIM card rejected\n"); break;
274 case 0x09 : smprintf(s, "not logged"); break;
275 default : smprintf(s, "unknown %i!\n",msg.Buffer[8]); break;
276 }
277 if (msg.Buffer[8]==0x00 || msg.Buffer[8] == 0x01) {
278 NOKIA_DecodeNetworkCode(msg.Buffer + (current + 7),NetInfo.NetworkCode);
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)));
283
284 sprintf(NetInfo.LAC,"%02x%02x", msg.Buffer[current+1], msg.Buffer[current+2]);
285 smprintf(s, "LAC : %s\n", NetInfo.LAC);
286
287 sprintf(NetInfo.CID, "%02x%02x", msg.Buffer[current+5], msg.Buffer[current+6]);
288 smprintf(s, "CID : %s\n", NetInfo.CID);
289
290 tmp = 10;
291 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer,name,true);
292 smprintf(s, "Network name for phone : %s\n",DecodeUnicodeString(name));
293 }
294#endif
295 if (Data->RequestID==ID_GetNetworkInfo) {
296 Data->NetworkInfo->NetworkName[0] = 0x00;
297 Data->NetworkInfo->NetworkName[1] = 0x00;
298 Data->NetworkInfo->State = 0;
299 switch (msg.Buffer[8]) {
300 case 0x00: Data->NetworkInfo->State = GSM_HomeNetwork; break;
301 case 0x01: Data->NetworkInfo->State = GSM_RoamingNetwork;break;
302 case 0x04:
303 case 0x06:
304 case 0x09: Data->NetworkInfo->State = GSM_NoNetwork; break;
305 }
306 if (Data->NetworkInfo->State == GSM_HomeNetwork || Data->NetworkInfo->State == GSM_RoamingNetwork) {
307 tmp = 10;
308 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer,Data->NetworkInfo->NetworkName,true);
309 sprintf(Data->NetworkInfo->LAC, "%02x%02x", msg.Buffer[current+1], msg.Buffer[current+2]);
310 sprintf(Data->NetworkInfo->CID, "%02x%02x", msg.Buffer[current+5], msg.Buffer[current+6]);
311 NOKIA_DecodeNetworkCode(msg.Buffer + (current+7),Data->NetworkInfo->NetworkCode);
312 }
313 }
314 return ERR_NONE;
315}
316
317static GSM_Error N6510_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo)
318{
319 unsigned char req[] = {N6110_FRAME_HEADER, 0x00, 0x00};
320
321 s->Phone.Data.NetworkInfo=netinfo;
322 smprintf(s, "Getting network info\n");
323 return GSM_WaitFor (s, req, 5, 0x0a, 4, ID_GetNetworkInfo);
324}
325
326static GSM_Error N6510_EncodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *req, GSM_SMSMessageLayout *Layout, int *length)
327{
328 int start, count = 0, pos1, pos2, pos3, pos4, pos5;
329 GSM_Error error;
330
331 memset(Layout,255,sizeof(GSM_SMSMessageLayout));
332
333 start = *length;
334
335 req[count++] = 0x01;
336 if (sms->PDU != SMS_Deliver) {
337 req[count++] = 0x02;
338 } else {
339 req[count++] = 0x00;
340 }
341
342 pos1 = count; count++;
343 /* firstbyte set in SMS Layout */
344 Layout->firstbyte = count; count++;
345 if (sms->PDU != SMS_Deliver) {
346 Layout->TPMR = count; count++;
347
348 Layout->TPPID = count; count++;
349
350 /* TP.DCS set in SMS layout */
351 Layout->TPDCS = count; count++;
352 req[count++] = 0x00;
353 } else {
354 Layout->TPPID = count; count++;
355 /* TP.DCS set in SMS layout */
356 Layout->TPDCS = count; count++;
357 Layout->DateTime = count; count += 7;
358 req[count++] = 0x55;
359 req[count++] = 0x55;
360 req[count++] = 0x55;
361 }
362
363 /* We have now blocks. Number of blocks = 3 or 4 */
364 if (sms->PDU != SMS_Deliver) {
365 req[count++] = 0x04;
366 } else {
367 req[count++] = 0x03;
368 }
369
370 /* -------------- Phone number ------------- */
371 /* Block type: number */
372 req[count++] = 0x82;
373 /* Offset to next block */
374 req[count++] = 0x10;
375 /* Type of number: default number */
376 req[count++] = 0x01;
377 pos4 = count; count++;
378 /* now coded Number in SMS Layout */
379 Layout->Number = count; count+= 12;
380
381 /* -------------- SMSC number -------------- */
382 /* Block type: number */
383 req[count++] = 0x82;
384 /* Offset to next block */
385 req[count++] = 0x10;
386 /* Type of number: SMSC number */
387 req[count++] = 0x02;
388 pos5 = count; count++;
389 /* now coded SMSC number in SMS Layout */
390 Layout->SMSCNumber = count; count += 12;
391
392 /* -------------- SMS validity ------------- */
393 if (sms->PDU != SMS_Deliver) {
394 /* Block type: validity */
395 req[count++] = 0x08;
396 req[count++] = 0x04;
397 /* data length */
398 req[count++] = 0x01;
399 Layout->TPVP = count; count++;
400 }
401
402 /* --------------- SMS text ---------------- */
403 /* Block type: SMS text */
404 req[count++] = 0x80;
405 /* this the same as req[11] but starting from req[42] */
406 pos2 = count; count++;
407 pos3 = count; count++;
408 /* FIXME*/
409 Layout->TPUDL = count; count++;
410 /* SMS text and UDH coded in SMS Layout */
411 Layout->Text = count;
412
413 error = PHONE_EncodeSMSFrame(s,sms,req,*Layout,length,false);
414 if (error != ERR_NONE) return error;
415
416 req[pos1] = *length - 1;
417 req[pos2] = *length - Layout->Text + 6;
418 req[pos3] = *length - Layout->Text;
419
420 /* Convert number of semioctets to number of chars */
421 req[pos4] = req[Layout->Number] + 4;
422 if (req[pos4] % 2) req[pos4]++;
423 req[pos4] /= 2;
424
425 req[pos5] = req[Layout->SMSCNumber] + 1;
426
427 if (req[pos4]>12 || req[pos5]>12) {
428 smprintf(s, "Too long phone number in frame\n");
429 return ERR_UNKNOWN;
430 }
431
432 return ERR_NONE;
433}
434
435static GSM_Error N6510_ReplyGetSMSFolders(GSM_Protocol_Message msg, GSM_StateMachine *s)
436{
437 int j, num = 0, pos;
438 GSM_Phone_Data *Data = &s->Phone.Data;
439
440 switch (msg.Buffer[3]) {
441 case 0x13:
442 smprintf(s, "SMS folders names received\n");
443 Data->SMSFolders->Number = msg.Buffer[5]+2;
444 pos = 6;
445 for (j=0;j<msg.Buffer[5];j++) {
446 while (true) {
447 if (msg.Buffer[pos] == msg.Buffer[6] &&
448 msg.Buffer[pos+1] == msg.Buffer[7]) break;
449 if (pos+4 > msg.Length) return ERR_UNKNOWNRESPONSE;
450 pos++;
451 }
452 pos+=4;
453 smprintf(s, "Folder index: %02x",msg.Buffer[pos - 2]);
454 if (msg.Buffer[pos - 1]>GSM_MAX_SMS_FOLDER_NAME_LEN) {
455 smprintf(s, "Too long text\n");
456 return ERR_UNKNOWNRESPONSE;
457 }
458 CopyUnicodeString(Data->SMSFolders->Folder[num].Name,msg.Buffer + pos);
459 smprintf(s, ", folder name: \"%s\"\n",DecodeUnicodeString(Data->SMSFolders->Folder[num].Name));
460 Data->SMSFolders->Folder[num].InboxFolder = false;
461 Data->SMSFolders->Folder[num].Memory = MEM_ME;
462 if (num == 0x01) { /* OUTBOX SIM */
463 Data->SMSFolders->Folder[0].Memory = MEM_SM;
464 Data->SMSFolders->Folder[0].InboxFolder = true;
465
466 Data->SMSFolders->Folder[1].Memory = MEM_SM;
467
468 CopyUnicodeString(Data->SMSFolders->Folder[2].Name,Data->SMSFolders->Folder[0].Name);
469 Data->SMSFolders->Folder[2].Memory = MEM_ME;
470 Data->SMSFolders->Folder[2].InboxFolder = true;
471
472 CopyUnicodeString(Data->SMSFolders->Folder[3].Name,Data->SMSFolders->Folder[1].Name);
473 Data->SMSFolders->Folder[3].Memory = MEM_ME;
474 Data->SMSFolders->Folder[3].InboxFolder = false;
475
476 num+=2;
477 }
478 num++;
479 }
480 return ERR_NONE;
481 }
482 return ERR_UNKNOWNRESPONSE;
483}
484
485static GSM_Error N6510_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders)
486{
487 unsigned char req[] = {N6110_FRAME_HEADER, 0x12, 0x00, 0x00};
488
489 s->Phone.Data.SMSFolders=folders;
490 smprintf(s, "Getting SMS folders\n");
491 return GSM_WaitFor (s, req, 6, 0x14, 4, ID_GetSMSFolders);
492}
493
494static GSM_Error N6510_ReplyGetSMSFolderStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
495{
496 int i;
497 GSM_Phone_N6510Data*Priv = &s->Phone.Data.Priv.N6510;
498
499 smprintf(s, "SMS folder status received\n");
500 Priv->LastSMSFolder.Number=msg.Buffer[6]*256+msg.Buffer[7];
501 smprintf(s, "Number of Entries: %i\n",Priv->LastSMSFolder.Number);
502 smprintf(s, "Locations: ");
503 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
504 Priv->LastSMSFolder.Location[i]=msg.Buffer[8+(i*2)]*256+msg.Buffer[(i*2)+9];
505 smprintf(s, "%i ",Priv->LastSMSFolder.Location[i]);
506 }
507 smprintf(s, "\n");
508 NOKIA_SortSMSFolderStatus(s, &Priv->LastSMSFolder);
509 return ERR_NONE;
510}
511
512static GSM_Error N6510_GetSMSFolderStatus(GSM_StateMachine *s, int folderid)
513{
514 unsigned char req[] = {N7110_FRAME_HEADER, 0x0C,
515 0x01, /* 0x01=SIM, 0x02=ME */
516 0x00, /* Folder ID */
517 0x0f, 0x55, 0x55, 0x55};
518
519 switch (folderid) {
520 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
521 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
522 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders*/
523 }
524
525 smprintf(s, "Getting SMS folder status\n");
526 return GSM_WaitFor (s, req, 10, 0x14, 4, ID_GetSMSFolderStatus);
527}
528
529static void N6510_GetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *folderid, int *location)
530{
531 int ifolderid;
532
533 /* simulate flat SMS memory */
534 if (sms->Folder==0x00) {
535 ifolderid = sms->Location / PHONE_MAXSMSINFOLDER;
536 *folderid = ifolderid + 0x01;
537 *location = sms->Location - ifolderid * PHONE_MAXSMSINFOLDER;
538 } else {
539 *folderid = sms->Folder;
540 *location = sms->Location;
541 }
542 smprintf(s, "SMS folder %i & location %i -> 6510 folder %i & location %i\n",
543 sms->Folder,sms->Location,*folderid,*location);
544}
545
546static void N6510_SetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char folderid, int location)
547{
548 sms->Folder= 0;
549 sms->Location= (folderid - 0x01) * PHONE_MAXSMSINFOLDER + location;
550 smprintf(s, "6510 folder %i & location %i -> SMS folder %i & location %i\n",
551 folderid,location,sms->Folder,sms->Location);
552}
553
554static GSM_Error N6510_DecodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *buffer)
555{
556 int i, current, blocks=0, SMSTemplateDateTime = 0;
557 GSM_SMSMessageLayout Layout;
558 GSM_Error error;
559
560 memset(&Layout,255,sizeof(GSM_SMSMessageLayout));
561 Layout.firstbyte = 2;
562 switch (buffer[0]) {
563 case 0x00:
564 smprintf(s, "SMS deliver\n");
565 sms->PDU = SMS_Deliver;
566 Layout.TPPID = 3;
567 Layout.TPDCS = 4;
568 Layout.DateTime = 5;
569 blocks = 15;
570 break;
571 case 0x01:
572 smprintf(s, "Delivery report\n");
573 sms->PDU = SMS_Status_Report;
574 Layout.TPMR= 3;
575 Layout.TPStatus= 4;
576 Layout.DateTime = 5;
577 Layout.SMSCTime = 12;
578 blocks = 19;
579 break;
580 case 0x02:
581 smprintf(s, "SMS template\n");
582 sms->PDU = SMS_Submit;
583 Layout.TPMR= 3;
584 Layout.TPPID = 4;
585 Layout.TPDCS = 5;
586 blocks = 7;
587 break;
588 }
589 current = blocks + 1;
590 for (i=0;i<buffer[blocks];i++) {
591 switch (buffer[current]) {
592 case 0x80:
593 smprintf(s, "SMS text\n");
594 if (buffer[current + 2] > buffer[current + 3]) {
595 Layout.TPUDL = current + 2;
596 } else {
597 Layout.TPUDL = current + 3;
598 }
599 Layout.Text = current + 4;
600 break;
601 case 0x82:
602 switch (buffer[current+2]) {
603 case 0x01:
604 smprintf(s, "Phone number\n");
605 Layout.Number = current + 4;
606 break;
607 case 0x02:
608 smprintf(s, "SMSC number\n");
609 Layout.SMSCNumber = current + 4;
610 break;
611 default:
612 smprintf(s, "Unknown number\n");
613 break;
614 }
615 break;
616 case 0x84:
617 smprintf(s, "Date and time of saving for SMS template\n");
618 SMSTemplateDateTime = current + 2;
619 break;
620 default:
621 smprintf(s, "Unknown block %02x\n",buffer[current]);
622 }
623 current = current + buffer[current + 1];
624 }
625 error=GSM_DecodeSMSFrame(sms,buffer,Layout);
626 if (SMSTemplateDateTime != 0) {
627 sms->PDU = SMS_Deliver;
628 NOKIA_DecodeDateTime(s, buffer+SMSTemplateDateTime, &sms->DateTime);
629 sms->DateTime.Timezone = 0;
630 }
631 return error;
632}
633
634static GSM_Error N6510_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
635{
636 int i;
637 int Width, Height;
638 unsigned char output[500]; //output2[500];
639 GSM_Phone_Data *Data = &s->Phone.Data;
640
641 switch(msg.Buffer[3]) {
642 case 0x03:
643 smprintf(s, "SMS Message received\n");
644 Data->GetSMSMessage->Number=1;
645 NOKIA_DecodeSMSState(s, msg.Buffer[5], &Data->GetSMSMessage->SMS[0]);
646 switch (msg.Buffer[14]) {
647 case 0x00:
648 case 0x01:
649 case 0x02:
650 return N6510_DecodeSMSFrame(s, &Data->GetSMSMessage->SMS[0],msg.Buffer+14);
651 case 0xA0:
652 smprintf(s, "Picture Image\n");
653 Data->GetSMSMessage->Number = 0;
654 i = 0;
655 output[i++] = 0x30; /* Smart Messaging 3.0 */
656 output[i++] = SM30_OTA;
657 output[i++] = 0x01; /* Length */
658 output[i++] = 0x00; /* Length */
659 output[i++] = 0x00;
660 PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height);
661 output[i++] = Width;
662 output[i++] = Height;
663 output[i++] = 0x01;
664 memcpy(output+i,msg.Buffer+30,PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0));
665 i = i + PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0);
666 // if (msg.Length!=282) {
667 // output[i++] = SM30_UNICODETEXT;
668 // output[i++] = 0;
669 // output[i++] = 0; /* Length - later changed */
670 // GSM_UnpackEightBitsToSeven(0, msg.Length-282, msg.Length-304, msg.Buffer+282,output2);
671 // DecodeDefault(output+i, output2, msg.Length - 282, true);
672 // output[i - 1] = UnicodeLength(output+i) * 2;
673 // i = i + output[i-1];
674 // }
675 GSM_MakeMultiPartSMS(Data->GetSMSMessage,output,i,UDH_NokiaProfileLong,SMS_Coding_8bit,1,0);
676 for (i=0;i<3;i++) {
677 Data->GetSMSMessage->SMS[i].Number[0]=0;
678 Data->GetSMSMessage->SMS[i].Number[1]=0;
679 }
680 if (Data->Bitmap != NULL) {
681 Data->Bitmap->Location= 0;
682 PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height);
683 Data->Bitmap->BitmapWidth= Width;
684 Data->Bitmap->BitmapHeight= Height;
685 PHONE_DecodeBitmap(GSM_NokiaPictureImage, msg.Buffer + 30, Data->Bitmap);
686 Data->Bitmap->Sender[0] = 0x00;
687 Data->Bitmap->Sender[1] = 0x00;
688 Data->Bitmap->Text[0] = 0;
689 Data->Bitmap->Text[1] = 0;
690 }
691 return ERR_NONE;
692 default:
693 smprintf(s, "Unknown SMS type: %i\n",msg.Buffer[8]);
694 }
695 break;
696 case 0x0f:
697 smprintf(s, "SMS message info received\n");
698 CopyUnicodeString(Data->GetSMSMessage->SMS[0].Name,msg.Buffer+52);
699 smprintf(s, "Name: \"%s\"\n",DecodeUnicodeString(Data->GetSMSMessage->SMS[0].Name));
700 return ERR_NONE;
701 }
702 return ERR_UNKNOWNRESPONSE;
703}
704
705static GSM_Error N6510_PrivGetSMSMessageBitmap(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, GSM_Bitmap *bitmap)
706{
707 GSM_Error error;
708 unsigned char folderid,namebuffer[200];
709 int location;
710 int i;
711 unsigned char req[] = {
712 N6110_FRAME_HEADER,
713 0x02, /* msg type: 0x02 for getting sms, 0x0e for sms status */
714 0x01, /* 0x01=SIM, 0x02=ME */
715 0x00, /* FolderID */
716 0x00, 0x02,/* Location */
717 0x01, 0x00};
718
719 N6510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
720
721 switch (folderid) {
722 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
723 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
724 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders*/
725 }
726 req[6]=location / 256;
727 req[7]=location;
728
729 s->Phone.Data.GetSMSMessage = sms;
730 s->Phone.Data.Bitmap = bitmap;
731 smprintf(s, "Getting sms message info\n");
732 req[3] = 0x0e; req[8] = 0x55; req[9] = 0x55;
733 error=GSM_WaitFor (s, req, 10, 0x14, 4, ID_GetSMSMessage);
734 if (error!=ERR_NONE) return error;
735 CopyUnicodeString(namebuffer,sms->SMS[0].Name);
736
737 smprintf(s, "Getting sms\n");
738 req[3] = 0x02; req[8] = 0x01; req[9] = 0x00;
739 error=GSM_WaitFor (s, req, 10, 0x14, 4, ID_GetSMSMessage);
740 if (error==ERR_NONE) {
741 for (i=0;i<sms->Number;i++) {
742 N6510_SetSMSLocation(s, &sms->SMS[i], folderid, location);
743 sms->SMS[i].Folder = folderid;
744 sms->SMS[i].InboxFolder = true;
745 if (folderid != 0x01 && folderid != 0x03) sms->SMS[i].InboxFolder = false;
746 sms->SMS[i].Memory= MEM_ME;
747 if (folderid == 0x01 || folderid == 0x02) sms->SMS[i].Memory = MEM_SM;
748 CopyUnicodeString(sms->SMS[i].Name,namebuffer);
749 }
750 }
751 return error;
752}
753
754static GSM_Error N6510_GetSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms)
755{
756 GSM_Error error;
757 unsigned char folderid;
758 int location;
759 GSM_Phone_N6510Data*Priv = &s->Phone.Data.Priv.N6510;
760 int i;
761 bool found = false;
762
763 N6510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
764 error=N6510_GetSMSFolderStatus(s, folderid);
765 if (error!=ERR_NONE) return error;
766 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
767 if (Priv->LastSMSFolder.Location[i]==location) {
768 found = true;
769 break;
770 }
771 }
772 if (!found) return ERR_EMPTY;
773 return N6510_PrivGetSMSMessageBitmap(s,sms,NULL);
774}
775
776static GSM_Error N6510_GetNextSMSMessageBitmap(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start, GSM_Bitmap *bitmap)
777{
778 GSM_Phone_N6510Data*Priv = &s->Phone.Data.Priv.N6510;
779 unsigned char folderid;
780 int location;
781 GSM_Error error;
782 int i;
783 bool findnextfolder = false;
784
785 if (start) {
786 folderid= 0x00;
787 findnextfolder= true;
788 error=N6510_GetSMSFolders(s,&Priv->LastSMSFolders);
789 if (error!=ERR_NONE) return error;
790 } else {
791 N6510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
792 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
793 if (Priv->LastSMSFolder.Location[i]==location) break;
794 }
795 /* Is this last location in this folder ? */
796 if (i==Priv->LastSMSFolder.Number-1) {
797 findnextfolder=true;
798 } else {
799 location=Priv->LastSMSFolder.Location[i+1];
800 }
801 }
802 if (findnextfolder) {
803 Priv->LastSMSFolder.Number=0;
804 while (Priv->LastSMSFolder.Number==0) {
805 folderid++;
806 /* Too high folder number */
807 if ((folderid-1)>Priv->LastSMSFolders.Number) return ERR_EMPTY;
808 /* Get next folder status */
809 error=N6510_GetSMSFolderStatus(s, folderid);
810 if (error!=ERR_NONE) return error;
811 /* First location from this folder */
812 location=Priv->LastSMSFolder.Location[0];
813 }
814 }
815 N6510_SetSMSLocation(s, &sms->SMS[0], folderid, location);
816
817 return N6510_PrivGetSMSMessageBitmap(s, sms, bitmap);
818}
819
820static GSM_Error N6510_GetNextSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start)
821{
822 return N6510_GetNextSMSMessageBitmap(s, sms, start, NULL);
823}
824
825static GSM_Error N6510_ReplyStartupNoteLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
826{
827 GSM_Phone_Data *Data = &s->Phone.Data;
828
829 if (Data->RequestID == ID_GetBitmap) {
830 switch (msg.Buffer[4]) {
831 case 0x01:
832 smprintf(s, "Welcome note text received\n");
833 CopyUnicodeString(Data->Bitmap->Text,msg.Buffer+6);
834 smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text));
835 return ERR_NONE;
836 case 0x10:
837 smprintf(s, "Dealer note text received\n");
838 CopyUnicodeString(Data->Bitmap->Text,msg.Buffer+6);
839 smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text));
840 return ERR_NONE;
841 case 0x0f:
842 smprintf(s, "Startup logo received\n");
843 PHONE_DecodeBitmap(GSM_Nokia7110StartupLogo, msg.Buffer + 22, Data->Bitmap);
844 return ERR_NONE;
845 }
846 }
847 if (Data->RequestID == ID_SetBitmap) {
848 switch (msg.Buffer[4]) {
849 case 0x01:
850 case 0x10:
851 case 0x0f:
852 case 0x25:
853 return ERR_NONE;
854 }
855 }
856 return ERR_UNKNOWN;
857}
858
859static GSM_Error N6510_GetPictureImage(GSM_StateMachine *s, GSM_Bitmap *Bitmap, int *location)
860{
861 GSM_MultiSMSMessage sms;
862 int Number;
863 GSM_Bitmap bitmap;
864 GSM_Error error;
865
866 sms.SMS[0].Folder= 0;
867 Number = 0;
868 bitmap.Location = 255;
869 error=N6510_GetNextSMSMessageBitmap(s, &sms, true, &bitmap);
870 while (error == ERR_NONE) {
871 if (bitmap.Location != 255) {
872 Number++;
873 if (Number == Bitmap->Location) {
874 bitmap.Location = Bitmap->Location;
875 memcpy(Bitmap,&bitmap,sizeof(GSM_Bitmap));
876 *location = sms.SMS[0].Location;
877 return ERR_NONE;
878 }
879 }
880 bitmap.Location = 255;
881 sms.SMS[0].Folder = 0;
882 error=N6510_GetNextSMSMessageBitmap(s, &sms, false, &bitmap);
883 }
884 return ERR_INVALIDLOCATION;
885}
886
887static GSM_Error N6510_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
888{
889 unsigned char reqOp[] = {N6110_FRAME_HEADER, 0x23, 0x00, 0x00, 0x55, 0x55, 0x55};
890 unsigned char reqStartup[] = {N6110_FRAME_HEADER, 0x02, 0x0f};
891 unsigned char reqNote[] = {N6110_FRAME_HEADER, 0x02, 0x01, 0x00};
892 GSM_MemoryEntrypbk;
893 GSM_Error error;
894 int Location;
895
896 s->Phone.Data.Bitmap=Bitmap;
897 switch (Bitmap->Type) {
898 case GSM_StartupLogo:
899 Bitmap->BitmapWidth = 96;
900 Bitmap->BitmapHeight = 65;
901 GSM_ClearBitmap(Bitmap);
902 smprintf(s, "Getting startup logo\n");
903 return GSM_WaitFor (s, reqStartup, 5, 0x7A, 4, ID_GetBitmap);
904 case GSM_DealerNote_Text:
905 reqNote[4] = 0x10;
906 smprintf(s, "Getting dealer note\n");
907 return GSM_WaitFor (s, reqNote, 6, 0x7A, 4, ID_GetBitmap);
908 case GSM_WelcomeNote_Text:
909 smprintf(s, "Getting welcome note\n");
910 return GSM_WaitFor (s, reqNote, 6, 0x7A, 4, ID_GetBitmap);
911 case GSM_CallerGroupLogo:
912 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PBK35)) return ERR_NOTSUPPORTED;
913 Bitmap->BitmapWidth = 72;
914 Bitmap->BitmapHeight = 14;
915 GSM_ClearBitmap(Bitmap);
916 pbk.MemoryType= MEM7110_CG;
917 pbk.Location= Bitmap->Location;
918 smprintf(s, "Getting caller group logo\n");
919 error=N6510_GetMemory(s,&pbk);
920 if (error==ERR_NONE) NOKIA_GetDefaultCallerGroupName(s, Bitmap);
921 return error;
922 case GSM_OperatorLogo:
923 smprintf(s, "Getting operator logo\n");
924 return GSM_WaitFor (s, reqOp, 9, 0x0A, 4, ID_GetBitmap);
925 case GSM_PictureImage:
926 return N6510_GetPictureImage(s, Bitmap, &Location);
927 default:
928 break;
929 }
930 return ERR_NOTSUPPORTED;
931}
932
933static GSM_Error N6510_ReplyGetIncSignalQuality(GSM_Protocol_Message msg, GSM_StateMachine *s)
934{
935 smprintf(s, "Network level changed to: %i\n",msg.Buffer[4]);
936 return ERR_NONE;
937}
938
939static GSM_Error N6510_ReplyGetSignalQuality(GSM_Protocol_Message msg, GSM_StateMachine *s)
940{
941 GSM_Phone_Data *Data = &s->Phone.Data;
942
943 smprintf(s, "Network level received: %i\n",msg.Buffer[8]);
944 Data->SignalQuality->SignalStrength = -1;
945 Data->SignalQuality->SignalPercent = ((int)msg.Buffer[8]);
946 Data->SignalQuality->BitErrorRate = -1;
947 return ERR_NONE;
948}
949
950static GSM_Error N6510_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig)
951{
952 unsigned char req[] = {N6110_FRAME_HEADER, 0x0B, 0x00, 0x02, 0x00, 0x00, 0x00};
953
954 s->Phone.Data.SignalQuality = sig;
955 smprintf(s, "Getting network level\n");
956 return GSM_WaitFor (s, req, 9, 0x0a, 4, ID_GetSignalQuality);
957}
958
959static GSM_Error N6510_ReplyGetBatteryCharge(GSM_Protocol_Message msg, GSM_StateMachine *s)
960{
961 GSM_Phone_Data *Data = &s->Phone.Data;
962
963 smprintf(s, "Battery level received: %i\n",msg.Buffer[9]*100/7);
964 Data->BatteryCharge->BatteryPercent = ((int)(msg.Buffer[9]*100/7));
965 Data->BatteryCharge->ChargeState = 0;
966 return ERR_NONE;
967}
968
969static GSM_Error N6510_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat)
970{
971 unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x02, 0x00};
972
973 s->Phone.Data.BatteryCharge = bat;
974 smprintf(s, "Getting battery level\n");
975 return GSM_WaitFor (s, req, 6, 0x17, 4, ID_GetBatteryCharge);
976}
977
978static GSM_Error N6510_ReplyGetWAPBookmark(GSM_Protocol_Message msg, GSM_StateMachine *s)
979{
980 return DCT3DCT4_ReplyGetWAPBookmark (msg, s, true);
981}
982
983static GSM_Error N6510_ReplyGetOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
984{
985 GSM_Phone_Data *Data = &s->Phone.Data;
986
987 smprintf(s, "Operator logo received\n");
988 NOKIA_DecodeNetworkCode(msg.Buffer+12,Data->Bitmap->NetworkCode);
989 smprintf(s, "Network code %s\n",Data->Bitmap->NetworkCode);
990 Data->Bitmap->BitmapWidth= msg.Buffer[20];
991 Data->Bitmap->BitmapHeight= msg.Buffer[21];
992 if (msg.Length == 18) return ERR_EMPTY;
993 PHONE_DecodeBitmap(GSM_Nokia6510OperatorLogo,msg.Buffer+26,Data->Bitmap);
994 return ERR_NONE;
995}
996
997GSM_Error N6510_ReplyDeleteMemory(GSM_Protocol_Message msg, GSM_StateMachine *s)
998{
999 smprintf(s, "Phonebook entry deleted\n");
1000 return ERR_NONE;
1001}
1002
1003GSM_Error N6510_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1004{
1005 unsigned char req[] = {N7110_FRAME_HEADER, 0x0f, 0x55, 0x01,
1006 0x04, 0x55, 0x00, 0x10, 0xFF, 0x02,
1007 0x00, 0x01, /* location*/
1008 0x00, 0x00, 0x00, 0x00,
1009 0x05, /* memory type*/
1010 0x55, 0x55, 0x55};
1011
1012 req[12] = entry->Location / 256;
1013 req[13] = entry->Location % 256;
1014
1015 req[18] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
1016 if (req[18]==0xff) return ERR_NOTSUPPORTED;
1017
1018 smprintf(s, "Deleting phonebook entry\n");
1019 return GSM_WaitFor (s, req, 22, 0x03, 4, ID_SetMemory);
1020}
1021
1022static GSM_Error N6510_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1023{
1024 int count = 22, blocks;
1025 unsigned char req[500] = {
1026 N7110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x10,
1027 0x02, 0x00, /* memory type */
1028 0x00, 0x00, /* location */
1029 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1030
1031 if (entry->Location == 0) return ERR_NOTSUPPORTED;
1032
1033 req[11] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
1034 if (req[11]==0xff) return ERR_NOTSUPPORTED;
1035
1036 req[12] = entry->Location / 256;
1037 req[13] = entry->Location % 256;
1038
1039 count = count + N71_65_EncodePhonebookFrame(s, req+22, *entry, &blocks, true, IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_VOICETAGS));
1040 req[21] = blocks;
1041
1042 smprintf(s, "Writing phonebook entry\n");
1043 return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetMemory);
1044}
1045
1046static GSM_Error N6510_ReplySetOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
1047{
1048 smprintf(s, "Operator logo set OK\n");
1049 return ERR_NONE;
1050}
1051
1052static GSM_Error N6510_SetCallerLogo(GSM_StateMachine *s, GSM_Bitmap *bitmap)
1053{
1054 char string[500];
1055 int block=0, i, Width, Height;
1056 unsigned int count = 22;
1057 unsigned char req[500] = {
1058 N6110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x10,
1059 0xfe, 0x10, /* memory type */
1060 0x00, 0x00, /* location */
1061 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1062
1063 req[13] = bitmap->Location;
1064
1065 /* Enabling/disabling logo */
1066 string[0] = bitmap->BitmapEnabled?1:0;
1067 string[1] = 0;
1068 count += N71_65_PackPBKBlock(s, N7110_PBK_LOGOON, 2, block++, string, req + count);
1069
1070 /* Ringtone */
1071 if (!bitmap->DefaultRingtone) {
1072 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PBKTONEGAL)) {
1073 } else {
1074 string[0] = 0x00;
1075 string[1] = 0x00;
1076 string[2] = bitmap->RingtoneID;
1077 count += N71_65_PackPBKBlock(s, N7110_PBK_RINGTONE_ID, 3, block++, string, req + count);
1078 count --;
1079 req[count-5] = 8;
1080 }
1081 }
1082
1083 /* Number of group */
1084 string[0] = bitmap->Location;
1085 string[1] = 0;
1086 count += N71_65_PackPBKBlock(s, N7110_PBK_GROUP, 2, block++, string, req + count);
1087
1088 /* Name */
1089 if (!bitmap->DefaultName) {
1090 i = UnicodeLength(bitmap->Text) * 2;
1091 string[0] = i + 2;
1092 memcpy(string + 1, bitmap->Text, i);
1093 string[i + 1] = 0;
1094 count += N71_65_PackPBKBlock(s, N7110_PBK_NAME, i + 2, block++, string, req + count);
1095 }
1096
1097 /* Logo */
1098 if (!bitmap->DefaultBitmap) {
1099 PHONE_GetBitmapWidthHeight(GSM_NokiaCallerLogo, &Width, &Height);
1100 string[0] = Width;
1101 string[1] = Height;
1102 string[2] = 0;
1103 string[3] = 0;
1104 string[4] = PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0);
1105 PHONE_EncodeBitmap(GSM_NokiaCallerLogo, string + 5, bitmap);
1106 count += N71_65_PackPBKBlock(s, N7110_PBK_GROUPLOGO, PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 5, block++, string, req + count);
1107 }
1108
1109 req[21] = block;
1110
1111 return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetBitmap);
1112}
1113
1114static GSM_Error N6510_ReplySetPicture(GSM_Protocol_Message msg, GSM_StateMachine *s)
1115{
1116 //smprintf(s, "Picture Image written OK, folder %i, location %i\n",msg.Buffer[4],msg.Buffer[5]*256+msg.Buffer[6]);
1117 return ERR_NONE;
1118}
1119
1120static GSM_Error N6510_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
1121{
1122 GSM_SMSMessage sms;
1123 GSM_Phone_Bitmap_TypesType;
1124 int Width, Height, i, count;
1125#ifdef DEVELOP
1126 unsigned char folderid;
1127 int location;
1128#endif
1129 GSM_NetworkInfo NetInfo;
1130 GSM_Error error;
1131 unsigned char reqStartup[1000] = {
1132 N7110_FRAME_HEADER, 0x04, 0x0F,
1133 0x00, 0x00, 0x00,
1134 0x04, 0xC0, 0x02, 0x00,
1135 0x41, 0xC0, 0x03, 0x00,
1136 0x60, 0xC0, 0x04};
1137 unsigned char reqColourWallPaper[200] = {
1138 N6110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0xD5,
1139 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1140 0x00, 0x00, 0x00, 0x01, 0x00,
1141 0x18}; /* Bitmap ID */
1142 unsigned char reqColourStartup[200] = {
1143 N6110_FRAME_HEADER, 0x04, 0x25, 0x00, 0x01, 0x00, 0x18};
1144 unsigned char reqOp[1000] = {
1145 N7110_FRAME_HEADER, 0x25, 0x01,
1146 0x55, 0x00, 0x00, 0x55,
1147 0x01, /* 0x01 - not set, 0x02 - set */
1148 0x0C, 0x08,
1149 0x62, 0xF0, 0x10,/* Network code */
1150 0x03, 0x55, 0x55};
1151 unsigned char reqColourOp[200] = {
1152 N6110_FRAME_HEADER,
1153 0x07, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x00, 0xF9, 0x00,
1154 0x08, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00,
1155 0x18, /* File ID */
1156 0x00,
1157 0x00, 0x00, 0x00};/* Network code */
1158 unsigned char reqNote[200] = {N6110_FRAME_HEADER, 0x04, 0x01};
1159 unsigned char reqPicture[2000] = {
1160 N6110_FRAME_HEADER, 0x00,
1161 0x02, 0x05, /* SMS folder */
1162 0x00, 0x00, /* location */
1163 0x01, 0x01, 0xa0, 0x02, 0x01, 0x40, 0x00, 0x34,
1164 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1165 0x00, 0x00, 0x55, 0x55, 0x55, 0x03, 0x82, 0x10,
1166 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x10,
1168 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04,
1170 0x00, 0x00, 0xa1, 0x55, 0x01, 0x08, 0x00, 0x00,
1171 0x00, 0x01, 0x48, 0x1c, 0x00, 0xfc, 0x00};
1172
1173 switch (Bitmap->Type) {
1174 case GSM_ColourWallPaper_ID:
1175 reqColourWallPaper[21] = Bitmap->ID;
1176 smprintf(s, "Setting colour wall paper\n");
1177 return GSM_WaitFor (s, reqColourWallPaper, 22, 0x43, 4, ID_SetBitmap);
1178 case GSM_StartupLogo:
1179 Type = GSM_Nokia7110StartupLogo;
1180 switch (Bitmap->Location) {
1181 case 1: PHONE_EncodeBitmap(Type, reqStartup + 22, Bitmap);
1182 break;
1183 case 2: memset(reqStartup+5,0x00,15);
1184 PHONE_ClearBitmap(Type, reqStartup + 22,0,0);
1185 break;
1186 default: return ERR_NOTSUPPORTED;
1187 }
1188 smprintf(s, "Setting startup logo\n");
1189 return GSM_WaitFor (s, reqStartup, 22+PHONE_GetBitmapSize(Type,0,0), 0x7A, 4, ID_SetBitmap);
1190 case GSM_DealerNote_Text:
1191 reqNote[4] = 0x10;
1192 CopyUnicodeString(reqNote + 5, Bitmap->Text);
1193 i = 6 + UnicodeLength(Bitmap->Text) * 2;
1194 reqNote[i++] = 0;
1195 reqNote[i] = 0;
1196 return GSM_WaitFor (s, reqNote, i, 0x7A, 4, ID_SetBitmap);
1197 case GSM_WelcomeNote_Text:
1198 CopyUnicodeString(reqNote + 5, Bitmap->Text);
1199 i = 6 + UnicodeLength(Bitmap->Text) * 2;
1200 reqNote[i++] = 0;
1201 reqNote[i] = 0;
1202 return GSM_WaitFor (s, reqNote, i, 0x7A, 4, ID_SetBitmap);
1203 case GSM_OperatorLogo:
1204 /* We want to set operator logo, not clear */
1205 if (strcmp(Bitmap->NetworkCode,"000 00")) {
1206 memset(reqOp + 19, 0, 281);
1207 NOKIA_EncodeNetworkCode(reqOp+12, Bitmap->NetworkCode);
1208 Type = GSM_Nokia6510OperatorLogo;
1209 reqOp[9] = 0x02;/* Logo enabled */
1210 reqOp[18] = 0x1a;/* FIXME */
1211 reqOp[19] = PHONE_GetBitmapSize(Type,0,0) + 8 + 29 + 2;
1212 PHONE_GetBitmapWidthHeight(Type, &Width, &Height);
1213 reqOp[20] = Width;
1214 reqOp[21] = Height;
1215 reqOp[22] = 0x00;
1216 reqOp[23] = PHONE_GetBitmapSize(Type,0,0) + 29;
1217 reqOp[24] = 0x00;
1218 reqOp[25] = PHONE_GetBitmapSize(Type,0,0) + 29;
1219 PHONE_EncodeBitmap(Type, reqOp + 26, Bitmap);
1220 smprintf(s, "Setting operator logo\n");
1221 return GSM_WaitFor (s, reqOp, reqOp[19]+reqOp[11]+10, 0x0A, 4, ID_SetBitmap);
1222 } else {
1223 error=N6510_GetNetworkInfo(s,&NetInfo);
1224 if (error != ERR_NONE) return error;
1225 NOKIA_EncodeNetworkCode(reqOp+12, NetInfo.NetworkCode);
1226 smprintf(s, "Clearing operator logo\n");
1227 return GSM_WaitFor (s, reqOp, 18, 0x0A, 4, ID_SetBitmap);
1228 }
1229 case GSM_ColourOperatorLogo_ID:
1230 /* We want to set operator logo, not clear */
1231 if (strcmp(Bitmap->NetworkCode,"000 00")) {
1232 EncodeBCD(reqColourOp+23, Bitmap->NetworkCode, 6, false);
1233 reqColourOp[21] = Bitmap->ID;
1234 }
1235 smprintf(s, "Setting colour operator logo\n");
1236 return GSM_WaitFor (s, reqColourOp, 26, 0x43, 4, ID_SetBitmap);
1237 case GSM_ColourStartupLogo_ID:
1238 switch (Bitmap->Location) {
1239 case 0: reqColourStartup[6] = 0x00;
1240 reqColourStartup[8] = 0x00;
1241 smprintf(s, "Setting colour startup logo\n");
1242 return GSM_WaitFor (s, reqColourStartup, 9, 0x7A, 4, ID_SetBitmap);
1243 case 1: reqColourStartup[8] = Bitmap->ID;
1244 smprintf(s, "Setting colour startup logo\n");
1245 return GSM_WaitFor (s, reqColourStartup, 9, 0x7A, 4, ID_SetBitmap);
1246 default:return ERR_NOTSUPPORTED;
1247 }
1248 case GSM_CallerGroupLogo:
1249 return N6510_SetCallerLogo(s,Bitmap);
1250 case GSM_PictureImage:
1251 error = N6510_GetPictureImage(s, Bitmap, &sms.Location);
1252 if (error == ERR_NONE) {
1253#ifdef DEVELOP
1254 sms.Folder = 0;
1255 N6510_GetSMSLocation(s, &sms, &folderid, &location);
1256 switch (folderid) {
1257 case 0x01: reqPicture[5] = 0x02; break; /* INBOX SIM */
1258 case 0x02: reqPicture[5] = 0x03; break; /* OUTBOX SIM */
1259 default : reqPicture[5] = folderid - 1; reqPicture[4] = 0x02; break; /* ME folders*/
1260 }
1261 reqPicture[6]=location / 256;
1262 reqPicture[7]=location;
1263#else
1264 return ERR_NOTSUPPORTED;
1265#endif
1266 }
1267 Type = GSM_NokiaPictureImage;
1268 count = 78;
1269 PHONE_EncodeBitmap(Type, reqPicture + count, Bitmap);
1270 count += PHONE_GetBitmapSize(Type,0,0);
1271 smprintf(s, "Setting Picture Image\n");
1272 return GSM_WaitFor (s, reqPicture, count, 0x14, 4, ID_SetBitmap);
1273 default:
1274 break;
1275 }
1276 return ERR_NOTSUPPORTED;
1277}
1278
1279static GSM_Error N6510_ReplyGetRingtoneID(GSM_Protocol_Message msg, GSM_StateMachine *s)
1280{
1281 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1282
1283 smprintf(s, "Ringtone ID received\n");
1284 Priv->RingtoneID = msg.Buffer[15];
1285 return ERR_NONE;
1286}
1287
1288static GSM_Error N6510_ReplySetBinRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
1289{
1290 smprintf(s, "Binary ringtone set\n");
1291 return ERR_NONE;
1292}
1293
1294static GSM_Error N6510_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
1295{
1296 GSM_Error error;
1297 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1298 GSM_NetworkInfo NetInfo;
1299 int size=200, current;
1300 unsigned char GetIDReq[] = {
1301 N7110_FRAME_HEADER, 0x01, 0x00, 0x00,
1302 0x00, 0xFF, 0x06, 0xE1, 0x00,
1303 0xFF, 0x06, 0xE1, 0x01, 0x42};
1304 unsigned char SetPreviewReq[1000] = {
1305 0xAE, /* Ringtone ID */
1306 0x01, 0x00, 0x0D, 0x00,
1307 0x00, 0x00, 0x00, 0x00, 0x00,
1308 0x00}; /*Length*/
1309 unsigned char AddBinaryReq[33000] = {
1310 N7110_FRAME_HEADER, 0x0E, 0x7F, 0xFF, 0xFE};
1311
1312 if (Ringtone->Format == RING_NOTETONE && Ringtone->Location==255)
1313 {
1314 smprintf(s, "Getting ringtone ID\n");
1315 error=GSM_WaitFor (s, GetIDReq, 14, 0xDB, 4, ID_SetRingtone);
1316 if (error != ERR_NONE) return error;
1317 *maxlength=GSM_EncodeNokiaRTTLRingtone(*Ringtone, SetPreviewReq+11, &size);
1318 SetPreviewReq[0] = Priv->RingtoneID;
1319 SetPreviewReq[10] = size;
1320 smprintf(s, "Setting ringtone\n");
1321 error = s->Protocol.Functions->WriteMessage(s, SetPreviewReq, size+11, 0x00);
1322 if (error!=ERR_NONE) return error;
1323 my_sleep(1000);
1324 /* We have to make something (not important, what) now */
1325 /* no answer from phone*/
1326 return s->Phone.Functions->GetNetworkInfo(s,&NetInfo);
1327 }
1328 if (Ringtone->Format == RING_NOKIABINARY) {
1329 AddBinaryReq[7] = UnicodeLength(Ringtone->Name);
1330 CopyUnicodeString(AddBinaryReq+8,Ringtone->Name);
1331 current = 8 + UnicodeLength(Ringtone->Name)*2;
1332 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length/256 + 1;
1333 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length%256 + 1;
1334 AddBinaryReq[current++] = 0x00;
1335 memcpy(AddBinaryReq+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length);
1336 current += Ringtone->NokiaBinary.Length;
1337 smprintf(s, "Adding binary ringtone\n");
1338 return GSM_WaitFor (s, AddBinaryReq, current, 0x1F, 4, ID_SetRingtone);
1339 }
1340 if (Ringtone->Format == RING_MIDI) {
1341 AddBinaryReq[7] = UnicodeLength(Ringtone->Name);
1342 CopyUnicodeString(AddBinaryReq+8,Ringtone->Name);
1343 current = 8 + UnicodeLength(Ringtone->Name)*2;
1344 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length/256;
1345 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length%256;
1346 memcpy(AddBinaryReq+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length);
1347 current += Ringtone->NokiaBinary.Length;
1348 AddBinaryReq[current++] = 0x00;
1349 AddBinaryReq[current++] = 0x00;
1350 smprintf(s, "Adding binary or MIDI ringtone\n");
1351 return GSM_WaitFor (s, AddBinaryReq, current, 0x1F, 4, ID_SetRingtone);
1352 }
1353 return ERR_NOTSUPPORTED;
1354}
1355
1356static GSM_Error N6510_ReplyDeleteRingtones(GSM_Protocol_Message msg, GSM_StateMachine *s)
1357{
1358 smprintf(s, "Ringtones deleted\n");
1359 return ERR_NONE;
1360}
1361
1362static GSM_Error N6510_DeleteUserRingtones(GSM_StateMachine *s)
1363{
1364 unsigned char DelAllRingtoneReq[] = {N7110_FRAME_HEADER, 0x10, 0x7F, 0xFE};
1365
1366 smprintf(s, "Deleting all user ringtones\n");
1367 return GSM_WaitFor (s, DelAllRingtoneReq, 6, 0x1F, 4, ID_SetRingtone);
1368}
1369
1370static GSM_Error N6510_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press)
1371{
1372#ifdef DEVELOP
1373 unsigned char req[] = {N6110_FRAME_HEADER, 0x11, 0x00, 0x01, 0x00, 0x00,
1374 0x00, /* Event */
1375 0x01}; /* Number of presses */
1376
1377 //req[7] = Key;
1378 if (Press) {
1379 req[8] = NOKIA_PRESSPHONEKEY;
1380 s->Phone.Data.PressKey = true;
1381 smprintf(s, "Pressing key\n");
1382 } else {
1383 req[8] = NOKIA_RELEASEPHONEKEY;
1384 s->Phone.Data.PressKey = false;
1385 smprintf(s, "Releasing key\n");
1386 }
1387 return GSM_WaitFor (s, req, 10, 0x0c, 4, ID_PressKey);
1388#else
1389 return ERR_NOTSUPPORTED;
1390#endif
1391}
1392
1393static GSM_Error N6510_EnableConnectionFunctions(GSM_StateMachine *s, N6510_Connection_Settings Type)
1394{
1395 GSM_Errorerror;
1396 unsigned char req2[] = {N6110_FRAME_HEADER, 0x00, 0x01};
1397 unsigned char req3[] = {N6110_FRAME_HEADER, 0x00, 0x03};
1398 unsigned char req4[] = {N6110_FRAME_HEADER, 0x00, 0x04};
1399
1400 if (Type == N6510_MMS_SETTINGS && IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOMMS)) return ERR_NOTSUPPORTED;
1401
1402 error=DCT3DCT4_DisableConnectionFunctions(s);
1403 if (error!=ERR_NONE) return error;
1404
1405 switch (Type) {
1406 case N6510_WAP_SETTINGS:
1407 return DCT3DCT4_EnableWAPFunctions(s);
1408 case N6510_MMS_SETTINGS:
1409 dbgprintf("Enabling MMS\n");
1410 return GSM_WaitFor (s, req2, 5, 0x3f, 4, ID_EnableConnectFunc);
1411 case N6510_SYNCML_SETTINGS:
1412 dbgprintf("Enabling SyncML\n");
1413 return GSM_WaitFor (s, req3, 5, 0x3f, 5, ID_EnableConnectFunc);
1414 case N6510_CHAT_SETTINGS:
1415 dbgprintf("Enabling Chat\n");
1416 return GSM_WaitFor (s, req4, 5, 0x3f, 5, ID_EnableConnectFunc);
1417 default:
1418 return ERR_UNKNOWN;
1419 }
1420}
1421
1422static GSM_Error N6510_ReplyGetConnectionSettings(GSM_Protocol_Message msg, GSM_StateMachine *s)
1423{
1424 GSM_Phone_N6510Data*Priv = &s->Phone.Data.Priv.N6510;
1425 int tmp,num=0,i;
1426 GSM_Phone_Data *Data = &s->Phone.Data;
1427 unsigned char buff[2000];
1428
1429 switch(msg.Buffer[3]) {
1430 case 0x16:
1431 smprintf(s, "Connection settings received OK\n");
1432
1433 Data->WAPSettings->Number = Priv->BearerNumber;
1434
1435 Data->WAPSettings->Proxy[0] = 0x00;
1436 Data->WAPSettings->Proxy[1] = 0x00;
1437 Data->WAPSettings->ProxyPort = 8080;
1438
1439 Data->WAPSettings->Proxy2[0] = 0x00;
1440 Data->WAPSettings->Proxy2[1] = 0x00;
1441 Data->WAPSettings->Proxy2Port = 8080;
1442
1443 tmp = 4;
1444
1445 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].Title,true);
1446 CopyUnicodeString(Data->WAPSettings->Settings[1].Title,Data->WAPSettings->Settings[0].Title);
1447 smprintf(s, "Title: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Title));
1448
1449 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].HomePage,true);
1450 CopyUnicodeString(Data->WAPSettings->Settings[1].HomePage,Data->WAPSettings->Settings[0].HomePage);
1451 smprintf(s, "Homepage: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].HomePage));
1452
1453#ifdef DEBUG
1454 smprintf(s, "Connection type: ");
1455 switch (msg.Buffer[tmp]) {
1456 case 0x00: smprintf(s, "temporary\n"); break;
1457 case 0x01: smprintf(s, "continuous\n"); break;
1458 default: smprintf(s, "unknown\n");
1459 }
1460 smprintf(s, "Connection security: ");
1461 switch (msg.Buffer[tmp+1]) {
1462 case 0x00: smprintf(s, "off\n");break;
1463 case 0x01: smprintf(s, "on\n"); break;
1464 default: smprintf(s, "unknown\n");
1465 }
1466 smprintf(s, "Bearer: ");
1467 switch (msg.Buffer[tmp+2]) {
1468 case 0x01: smprintf(s, "GSM data\n");break;
1469 case 0x03: smprintf(s, "GPRS\n");break;
1470 default: smprintf(s, "unknown\n");
1471 }
1472 if (msg.Buffer[tmp+3] == 0x01) smprintf(s, "locked\n");
1473#endif
1474 Data->WAPSettings->Settings[0].IsContinuous = false;
1475 if (msg.Buffer[tmp] == 0x01) Data->WAPSettings->Settings[0].IsContinuous = true;
1476 Data->WAPSettings->Settings[1].IsContinuous = Data->WAPSettings->Settings[0].IsContinuous;
1477
1478 Data->WAPSettings->Settings[0].IsSecurity = false;
1479 if (msg.Buffer[tmp+1] == 0x01) Data->WAPSettings->Settings[0].IsSecurity = true;
1480 Data->WAPSettings->Settings[1].IsSecurity = Data->WAPSettings->Settings[0].IsSecurity;
1481
1482 Data->WAPSettings->ActiveBearer = WAPSETTINGS_BEARER_DATA;
1483 if (msg.Buffer[tmp+2] == 0x03) Data->WAPSettings->ActiveBearer = WAPSETTINGS_BEARER_GPRS;
1484
1485 Data->WAPSettings->ReadOnly = false;
1486 if (msg.Buffer[tmp+3] == 0x01) Data->WAPSettings->ReadOnly = true;
1487
1488 tmp+=3;
1489
1490 if (Priv->BearerNumber == 2) {
1491 /* Here starts settings for data bearer */
1492 Data->WAPSettings->Settings[0].Bearer = WAPSETTINGS_BEARER_DATA;
1493 while ((msg.Buffer[tmp] != 0x01) || (msg.Buffer[tmp + 1] != 0x00)) tmp++;
1494 tmp += 4;
1495
1496#ifdef DEBUG
1497 smprintf(s, "Authentication type: ");
1498 switch (msg.Buffer[tmp]) {
1499 case 0x00: smprintf(s, "normal\n");break;
1500 case 0x01: smprintf(s, "secure\n");break;
1501 default: smprintf(s, "unknown\n");break;
1502 }
1503 smprintf(s, "Data call type: ");
1504 switch (msg.Buffer[tmp+1]) {
1505 case 0x00: smprintf(s, "analogue\n");break;
1506 case 0x01: smprintf(s, "ISDN\n");break;
1507 default: smprintf(s, "unknown\n");break;
1508 }
1509 smprintf(s, "Data call speed: ");
1510 switch (msg.Buffer[tmp+2]) {
1511 case 0x00: smprintf(s, "automatic\n"); break;
1512 case 0x01: smprintf(s, "9600\n");break;
1513 case 0x02: smprintf(s, "14400\n");break;
1514 default: smprintf(s, "unknown\n");break;
1515 }
1516 smprintf(s, "Login Type: ");
1517 switch (msg.Buffer[tmp+4]) {
1518 case 0x00: smprintf(s, "manual\n");break;
1519 case 0x01: smprintf(s, "automatic\n");break;
1520 default: smprintf(s, "unknown\n");break;
1521 }
1522#endif
1523 Data->WAPSettings->Settings[0].IsNormalAuthentication=true;
1524 if (msg.Buffer[tmp]==0x01) Data->WAPSettings->Settings[0].IsNormalAuthentication=false;
1525
1526 Data->WAPSettings->Settings[0].IsISDNCall=false;
1527 if (msg.Buffer[tmp+1]==0x01) Data->WAPSettings->Settings[0].IsISDNCall=true;
1528
1529 switch (msg.Buffer[tmp+2]) {
1530 case 0x00: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_AUTO; break;
1531 case 0x01: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_9600; break;
1532 case 0x02: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_14400; break;
1533 }
1534
1535 Data->WAPSettings->Settings[0].ManualLogin=false;
1536 if (msg.Buffer[tmp+4]==0x00) Data->WAPSettings->Settings[0].ManualLogin = true;
1537
1538 tmp+=5;
1539
1540 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].IPAddress,false);
1541 smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].IPAddress));
1542
1543 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].DialUp,true);
1544 smprintf(s, "Dial-up number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].DialUp));
1545
1546 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].User,true);
1547 smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].User));
1548
1549 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].Password,true);
1550 smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Password));
1551
1552 num = 1;
1553 } else {
1554 num = 0;
1555 }
1556
1557 /* Here starts settings for gprs bearer */
1558 Data->WAPSettings->Settings[num].Bearer = WAPSETTINGS_BEARER_GPRS;
1559 while (msg.Buffer[tmp] != 0x03) tmp++;
1560 tmp += 4;
1561
1562#ifdef DEBUG
1563 smprintf(s, "Authentication type: ");
1564 switch (msg.Buffer[tmp]) {
1565 case 0x00: smprintf(s, "normal\n");break;
1566 case 0x01: smprintf(s, "secure\n");break;
1567 default: smprintf(s, "unknown\n");break;
1568 }
1569 smprintf(s, "GPRS connection: ");
1570 switch (msg.Buffer[tmp+1]) {
1571 case 0x00: smprintf(s, "ALWAYS online\n"); break;
1572 case 0x01: smprintf(s, "when needed\n"); break;
1573 default: smprintf(s, "unknown\n"); break;
1574 }
1575 smprintf(s, "Login Type: ");
1576 switch (msg.Buffer[tmp+2]) {
1577 case 0x00: smprintf(s, "manual\n");break;
1578 case 0x01: smprintf(s, "automatic\n");break;
1579 default: smprintf(s, "unknown\n");break;
1580 }
1581#endif
1582 Data->WAPSettings->Settings[num].IsNormalAuthentication=true;
1583 if (msg.Buffer[tmp]==0x01) Data->WAPSettings->Settings[num].IsNormalAuthentication=false;
1584
1585 Data->WAPSettings->Settings[num].IsContinuous = true;
1586 if (msg.Buffer[tmp+1] == 0x01) Data->WAPSettings->Settings[num].IsContinuous = false;
1587
1588 Data->WAPSettings->Settings[num].ManualLogin=false;
1589 if (msg.Buffer[tmp+2]==0x00) Data->WAPSettings->Settings[num].ManualLogin = true;
1590
1591 tmp+=3;
1592
1593 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].DialUp,false);
1594 smprintf(s, "Access point: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].DialUp));
1595
1596 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].IPAddress,true);
1597 smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].IPAddress));
1598
1599 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].User,true);
1600 smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].User));
1601
1602 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[num].Password,true);
1603 smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].Password));
1604
1605 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) {
1606 if (msg.Buffer[tmp] == 0x00 && msg.Buffer[tmp+1] == 0x00) tmp = tmp+2;
1607
1608 memcpy(buff,msg.Buffer+tmp+10,msg.Buffer[tmp+4]);
1609 buff[msg.Buffer[tmp+4]] = 0x00;
1610 smprintf(s, "Proxy 1: \"%s\", port %i\n",buff,msg.Buffer[tmp+6]*256+msg.Buffer[tmp+7]);
1611 EncodeUnicode(Data->WAPSettings->Proxy,buff,strlen(buff));
1612 Data->WAPSettings->ProxyPort = msg.Buffer[tmp+6]*256+msg.Buffer[tmp+7];
1613
1614 memcpy(buff,msg.Buffer+tmp+10+msg.Buffer[tmp+4],msg.Buffer[tmp+5]);
1615 buff[msg.Buffer[tmp+5]] = 0x00;
1616 smprintf(s, "Proxy 2: \"%s\", port %i\n",buff,msg.Buffer[tmp+8]*256+msg.Buffer[tmp+9]);
1617 EncodeUnicode(Data->WAPSettings->Proxy2,buff,strlen(buff));
1618 Data->WAPSettings->Proxy2Port = msg.Buffer[tmp+8]*256+msg.Buffer[tmp+9];
1619
1620 tmp = tmp + msg.Buffer[tmp+3] + 19;
1621
1622 for (i=0;i<4;i++) {
1623#ifdef DEBUG
1624 smprintf(s, "Proxy data %i\n",i+1);
1625 if (msg.Buffer[tmp+2]!=0) memcpy(buff,msg.Buffer+tmp+9,msg.Buffer[tmp+2]*2);
1626 buff[msg.Buffer[tmp+2]*2] =0;
1627 buff[msg.Buffer[tmp+2]*2+1]=0;
1628 smprintf(s, "IP: \"%s\"",DecodeUnicodeString(buff));
1629 smprintf(s, ", port %i\n",msg.Buffer[tmp+3]*256+msg.Buffer[tmp+4]);
1630#endif
1631 tmp = tmp + msg.Buffer[tmp];
1632 }
1633
1634#ifdef DEBUG
1635 smprintf(s, "%02x %02x\n",msg.Buffer[tmp],msg.Buffer[tmp+1]);
1636 smprintf(s, "Port %i\n",msg.Buffer[tmp+3]*256+msg.Buffer[tmp+4]);
1637 tmp = tmp + msg.Buffer[tmp];
1638#endif
1639 }
1640
1641 return ERR_NONE;
1642 case 0x17:
1643 smprintf(s, "Connection settings receiving error\n");
1644 switch (msg.Buffer[4]) {
1645 case 0x01:
1646 smprintf(s, "Security error. Inside phone settings menu\n");
1647 return ERR_INSIDEPHONEMENU;
1648 case 0x02:
1649 smprintf(s, "Invalid or empty\n");
1650 return ERR_INVALIDLOCATION;
1651 default:
1652 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
1653 return ERR_UNKNOWNRESPONSE;
1654 }
1655 break;
1656 }
1657 return ERR_UNKNOWNRESPONSE;
1658}
1659
1660static GSM_Error N6510_GetConnectionSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings, N6510_Connection_Settings Type)
1661{
1662 GSM_Phone_N6510Data*Priv = &s->Phone.Data.Priv.N6510;
1663 GSM_Error error;
1664 unsigned char req[] = {N6110_FRAME_HEADER, 0x15,
1665 0x00}; /* Location */
1666
1667 error = N6510_EnableConnectionFunctions(s, Type);
1668 if (error!=ERR_NONE) return error;
1669
1670 req[4] = settings->Location-1;
1671 s->Phone.Data.WAPSettings = settings;
1672
1673 switch (Type) {
1674 case N6510_MMS_SETTINGS:
1675 smprintf(s, "Getting MMS settings\n");
1676 Priv->BearerNumber = 1;
1677 break;
1678 case N6510_WAP_SETTINGS:
1679 smprintf(s, "Getting WAP settings\n");
1680 Priv->BearerNumber = 2;
1681 break;
1682 case N6510_SYNCML_SETTINGS:
1683 smprintf(s, "Getting SyncML settings\n");
1684 Priv->BearerNumber = 2;
1685 break;
1686 case N6510_CHAT_SETTINGS:
1687 smprintf(s, "Getting Chat settings\n");
1688 Priv->BearerNumber = 1;
1689 break;
1690 }
1691
1692 error=GSM_WaitFor (s, req, 5, 0x3f, 4, ID_GetConnectSet);
1693 if (error != ERR_NONE) {
1694 if (error == ERR_INVALIDLOCATION || error == ERR_INSIDEPHONEMENU) {
1695 DCT3DCT4_DisableConnectionFunctions(s);
1696 }
1697 return error;
1698 }
1699
1700 error=DCT3DCT4_GetActiveConnectSet(s);
1701 if (error != ERR_NONE) return error;
1702
1703 return DCT3DCT4_DisableConnectionFunctions(s);
1704}
1705
1706static GSM_Error N6510_GetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
1707{
1708 return N6510_GetConnectionSettings(s, settings, N6510_WAP_SETTINGS);
1709}
1710
1711static GSM_Error N6510_GetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
1712{
1713 return N6510_GetConnectionSettings(s, settings, N6510_MMS_SETTINGS);
1714}
1715
1716static GSM_Error N6510_ReplyGetSyncMLSettings(GSM_Protocol_Message msg, GSM_StateMachine *s)
1717{
1718 GSM_SyncMLSettings *Sett = s->Phone.Data.SyncMLSettings;
1719
1720 smprintf(s, "SyncML settings received OK\n");
1721 CopyUnicodeString(Sett->User,msg.Buffer+18);
1722 CopyUnicodeString(Sett->Password,msg.Buffer+86);
1723 CopyUnicodeString(Sett->PhonebookDataBase,msg.Buffer+130);
1724 CopyUnicodeString(Sett->CalendarDataBase,msg.Buffer+234);
1725 CopyUnicodeString(Sett->Server,msg.Buffer+338);
1726
1727 Sett->SyncPhonebook = false;
1728 Sett->SyncCalendar = false;
1729 if ((msg.Buffer[598] & 0x02)==0x02) Sett->SyncCalendar = true;
1730 if ((msg.Buffer[598] & 0x01)==0x01) Sett->SyncPhonebook = true;
1731
1732 return ERR_NONE;
1733}
1734
1735static GSM_Error N6510_ReplyGetSyncMLName(GSM_Protocol_Message msg, GSM_StateMachine *s)
1736{
1737 GSM_SyncMLSettings *Sett = s->Phone.Data.SyncMLSettings;
1738
1739 smprintf(s, "SyncML names received OK\n");
1740
1741 CopyUnicodeString(Sett->Name,msg.Buffer+18);
1742
1743 return ERR_NONE;
1744}
1745
1746static GSM_Error N6510_GetSyncMLSettings(GSM_StateMachine *s, GSM_SyncMLSettings *settings)
1747{
1748 GSM_Error error;
1749 // unsigned char NameReq[] = {N6110_FRAME_HEADER, 0x05,
1750 // 0x00, 0x00, 0x00, 0x31, 0x00,
1751 // 0x06, 0x00, 0x00, 0x00, 0xDE, 0x00, 0x00};
1752 // unsigned char GetActive[] = {N6110_FRAME_HEADER, 0x05,
1753 // 0x00, 0x00, 0x00, 0x31, 0x00,
1754 // 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
1755 unsigned char req[] = {N6110_FRAME_HEADER, 0x05,
1756 0x00, 0x00, 0x00, 0x31, 0x00,
1757 0x01, //location
1758 0x00, 0x00, 0x02, 0x46, 0x00, 0x00};
1759
1760 settings->Connection.Location = settings->Location;
1761 error = N6510_GetConnectionSettings(s, &settings->Connection, N6510_SYNCML_SETTINGS);
1762 if (error != ERR_NONE) return error;
1763
1764 settings->Active = settings->Connection.Active;
1765
1766 settings->Name[0] = 0;
1767 settings->Name[1] = 0;
1768 //s->Phone.Data.SyncMLSettings = settings;
1769 //smprintf(s, "Getting SyncML settings name\n");
1770 //error = GSM_WaitFor (s, NameReq, 16, 0x43, 4, ID_GetSyncMLName);
1771 //if (error != ERR_NONE) return error;
1772
1773 req[9] = settings->Location - 1;
1774 smprintf(s, "Getting additional SyncML settings\n");
1775 return GSM_WaitFor (s, req, 16, 0x43, 4, ID_GetSyncMLSettings);
1776}
1777
1778static GSM_Error N6510_ReplyGetChatSettings(GSM_Protocol_Message msg, GSM_StateMachine *s)
1779{
1780 GSM_ChatSettings *Sett = s->Phone.Data.ChatSettings;
1781 int i;
1782
1783 Sett->Name[0] = 0;
1784 Sett->Name[1] = 0;
1785 Sett->HomePage[0] = 0;
1786 Sett->HomePage[1] = 0;
1787 Sett->User[0] = 0;
1788 Sett->User[1] = 0;
1789 Sett->Password[0] = 0;
1790 Sett->Password[1] = 0;
1791
1792 switch(msg.Buffer[3]) {
1793 case 0x3B:
1794 smprintf(s, "Chat settings received OK\n");
1795 memcpy(Sett->Name,msg.Buffer+20,msg.Buffer[12]*2);
1796 Sett->Name[msg.Buffer[12]*2] = 0;
1797 Sett->Name[msg.Buffer[12]*2+1] = 0;
1798 memcpy(Sett->HomePage,msg.Buffer+20+msg.Buffer[12]*2,msg.Buffer[15]*2);
1799 Sett->HomePage[msg.Buffer[15]*2] = 0;
1800 Sett->HomePage[msg.Buffer[15]*2+1] = 0;
1801 i = msg.Buffer[12]*2 + msg.Buffer[15]*2 + 29;
1802 memcpy(Sett->User,msg.Buffer+i+3,msg.Buffer[i]*2);
1803 Sett->User[msg.Buffer[i]*2] = 0;
1804 Sett->User[msg.Buffer[i]*2+1] = 0;
1805 memcpy(Sett->Password,msg.Buffer+i+3+msg.Buffer[i]*2,msg.Buffer[i+1]*2);
1806 Sett->Password[msg.Buffer[i+1]*2] = 0;
1807 Sett->Password[msg.Buffer[i+1]*2+1] = 0;
1808 return ERR_NONE;
1809 case 0x3C:
1810 smprintf(s, "Empty chat settings received\n");
1811 return ERR_NONE;
1812 }
1813 return ERR_UNKNOWNRESPONSE;
1814}
1815
1816static GSM_Error N6510_GetChatSettings(GSM_StateMachine *s, GSM_ChatSettings *settings)
1817{
1818 GSM_Error error;
1819 unsigned char req[] = {N6110_FRAME_HEADER, 0x3a,
1820 0x09, // location
1821 0x01, 0x0e};
1822
1823 settings->Connection.Location = settings->Location;
1824 error = N6510_GetConnectionSettings(s, &settings->Connection, N6510_CHAT_SETTINGS);
1825 if (error != ERR_NONE) return error;
1826
1827 settings->Active = settings->Connection.Active;
1828
1829 s->Phone.Data.ChatSettings = settings;
1830 req[4] = settings->Location - 1;
1831 smprintf(s, "Getting additional Chat settings\n");
1832 return GSM_WaitFor (s, req, 7, 0x3f, 4, ID_GetChatSettings);
1833}
1834
1835static GSM_Error N6510_ReplySetConnectionSettings(GSM_Protocol_Message msg, GSM_StateMachine *s)
1836{
1837 switch (msg.Buffer[3]) {
1838 case 0x19:
1839 smprintf(s, "Connection settings cleaned\n");
1840 return ERR_NONE;
1841 case 0x1a:
1842 smprintf(s, "Connection settings setting status\n");
1843 switch (msg.Buffer[4]) {
1844 case 0x01:
1845 smprintf(s, "Security error. Inside phone settings menu\n");
1846 return ERR_INSIDEPHONEMENU;
1847 case 0x03:
1848 smprintf(s, "Invalid location\n");
1849 return ERR_INVALIDLOCATION;
1850 case 0x05:
1851 smprintf(s, "Written OK\n");
1852 return ERR_NONE;
1853 default:
1854 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
1855 return ERR_UNKNOWNRESPONSE;
1856 }
1857 case 0x28:
1858 case 0x2B:
1859 smprintf(s, "Set OK\n");
1860 return ERR_NONE;
1861 }
1862 return ERR_UNKNOWNRESPONSE;
1863}
1864
1865static GSM_Error N6510_SetConnectionSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings, N6510_Connection_Settings Type)
1866{
1867 GSM_Error error;
1868 int i, pad = 0, length, pos = 5, loc1=-1,loc2=-1,port;
1869 unsigned char*Proxy;
1870 unsigned char req[2000] = {N6110_FRAME_HEADER, 0x18,
1871 0x00}; /* Location */
1872 unsigned char Lock[5] = {N6110_FRAME_HEADER, 0x27,
1873 0x00}; /* Location */
1874 unsigned char UnLock[5] = {N6110_FRAME_HEADER, 0x2A,
1875 0x00}; /* Location */
1876
1877 error = N6510_EnableConnectionFunctions(s, Type);
1878 if (error!=ERR_NONE) return error;
1879
1880 memset(req + pos, 0, 1000 - pos);
1881
1882 req[4] = settings->Location-1;
1883
1884 for (i=0;i<settings->Number;i++) {
1885 if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_DATA) loc1=i;
1886 if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_GPRS) loc2=i;
1887 }
1888
1889 if (loc1 != -1) {
1890 /* Name */
1891 length = UnicodeLength(settings->Settings[loc1].Title);
1892 if (!(length % 2)) pad = 1;
1893 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].Title, false);
1894
1895 /* Home */
1896 length = UnicodeLength(settings->Settings[loc1].HomePage);
1897 if (((length + pad) % 2)) pad = 2; else pad = 0;
1898 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].HomePage, true);
1899
1900 if (settings->Settings[loc1].IsContinuous) req[pos] = 0x01; pos++;
1901 if (settings->Settings[loc1].IsSecurity) req[pos] = 0x01; pos++;
1902 } else if (loc2 != -1) {
1903 /* Name */
1904 length = UnicodeLength(settings->Settings[loc2].Title);
1905 if (!(length % 2)) pad = 1;
1906 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].Title, false);
1907
1908 /* Home */
1909 length = UnicodeLength(settings->Settings[loc2].HomePage);
1910 if (((length + pad) % 2)) pad = 2; else pad = 0;
1911 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].HomePage, true);
1912
1913 if (settings->Settings[loc2].IsContinuous) req[pos] = 0x01; pos++;
1914 if (settings->Settings[loc2].IsSecurity) req[pos] = 0x01; pos++;
1915 } else {
1916 /* Name */
1917 length = 0;
1918 if (!(length % 2)) pad = 1;
1919 pos ++;
1920
1921 /* Home */
1922 length = 0;
1923 if (((length + pad) % 2)) pad = 2; else pad = 0;
1924 pos += 2;
1925
1926 pos += 2;
1927 }
1928
1929 if (Type == N6510_MMS_SETTINGS || Type == N6510_CHAT_SETTINGS) {
1930 req[pos++] = 0x03; //active bearer: GPRS
1931 } else {
1932 if (settings->ActiveBearer == WAPSETTINGS_BEARER_GPRS && loc2 != -1) {
1933 req[pos++] = 0x03; //active bearer: GPRS
1934 } else {
1935 req[pos++] = 0x01; //active bearer: data set
1936 }
1937 }
1938
1939 /* Number of sent bearers */
1940 if (Type == N6510_MMS_SETTINGS || Type == N6510_CHAT_SETTINGS) {
1941 req[pos] = 0x01;
1942 } else {
1943 req[pos] = 0x02;
1944 }
1945 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) req[pos] += 2;
1946 pos++;
1947 pos += pad;
1948
1949 if (Type != N6510_MMS_SETTINGS && Type != N6510_CHAT_SETTINGS) {
1950 /* GSM data block */
1951 memcpy(req + pos, "\x01\x00", 2);pos += 2;
1952
1953 if (loc1 != -1) {
1954 length = UnicodeLength(settings->Settings[loc1].IPAddress)*2+1;
1955 length += UnicodeLength(settings->Settings[loc1].DialUp) *2+2;
1956 length += UnicodeLength(settings->Settings[loc1].User) *2+2;
1957 length += UnicodeLength(settings->Settings[loc1].Password) *2+2;
1958 } else {
1959 length = 1 + 2 + 2 + 2;
1960 }
1961 length += 11;
1962 req[pos++] = length / 256;
1963 req[pos++] = length % 256;
1964
1965 if (loc1 != -1) {
1966 if (!settings->Settings[loc1].IsNormalAuthentication) req[pos]=0x01; pos++;
1967 if (settings->Settings[loc1].IsISDNCall) req[pos]=0x01;pos++;
1968 switch (settings->Settings[loc1].Speed) {
1969 case WAPSETTINGS_SPEED_AUTO : break;
1970 case WAPSETTINGS_SPEED_9600: req[pos]=0x01; break;
1971 case WAPSETTINGS_SPEED_14400: req[pos]=0x02; break;
1972 }
1973 pos++;
1974 req[pos++]=0x01;
1975 if (!settings->Settings[loc1].ManualLogin) req[pos] = 0x01; pos++;
1976
1977 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].IPAddress, false);
1978 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].DialUp, true);
1979 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].User, true);
1980 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].Password, true);
1981 } else {
1982 pos += 3;
1983 req[pos++]=0x01;
1984 pos += 8;
1985 }
1986
1987 /* Padding */
1988 pos+=2;
1989 }
1990
1991 /* GPRS block */
1992 memcpy(req + pos, "\x03\x00", 2);pos += 2;
1993
1994 if (loc2 != -1) {
1995 length = UnicodeLength(settings->Settings[loc2].DialUp) *2+1;
1996 length += UnicodeLength(settings->Settings[loc2].IPAddress)*2+2;
1997 length += UnicodeLength(settings->Settings[loc2].User) *2+2;
1998 length += UnicodeLength(settings->Settings[loc2].Password) *2+2;
1999 } else {
2000 length = 7;
2001 }
2002 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) length+=2;
2003 length += 7;
2004 req[pos++] = length / 256;
2005 req[pos++] = length % 256;
2006
2007 if (loc2 != -1) {
2008 if (!settings->Settings[loc2].IsNormalAuthentication) req[pos] = 0x01; pos++;
2009 if (!settings->Settings[loc2].IsContinuous) req[pos] = 0x01; pos++;
2010 if (!settings->Settings[loc2].ManualLogin) req[pos] = 0x01; pos++;
2011
2012 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].DialUp, false);
2013 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].IPAddress, true);
2014 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].User, true);
2015 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].Password, true);
2016 } else {
2017 pos += 10;
2018 }
2019
2020 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) {
2021 req[pos++] = 0x00;
2022 req[pos++] = 0x00;
2023
2024 /* Proxy block */
2025 req[pos++] = 0x06;
2026 req[pos++] = 0x01;
2027 if (UnicodeLength(settings->Proxy)!=0 ||
2028 UnicodeLength(settings->Proxy2)!=0) {
2029 req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+13)/256;
2030 req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+13)%256;
2031 } else {
2032 req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+12)/256;
2033 req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+12)%256;
2034 }
2035 req[pos++] = UnicodeLength(settings->Proxy);
2036 req[pos++] = UnicodeLength(settings->Proxy2);
2037 req[pos++] = settings->ProxyPort/256;
2038 req[pos++] = settings->ProxyPort%256;
2039 req[pos++] = settings->Proxy2Port/256;
2040 req[pos++] = settings->Proxy2Port%256;
2041 if (UnicodeLength(settings->Proxy)!=0) {
2042 sprintf(req+pos,"%s",DecodeUnicodeString(settings->Proxy));
2043 pos+=UnicodeLength(settings->Proxy);
2044 }
2045 if (UnicodeLength(settings->Proxy2)!=0) {
2046 sprintf(req+pos,"%s",DecodeUnicodeString(settings->Proxy2));
2047 pos+=UnicodeLength(settings->Proxy2);
2048 }
2049 if (UnicodeLength(settings->Proxy)!=0 ||
2050 UnicodeLength(settings->Proxy2)!=0) {
2051 req[pos++] = 0x00;
2052 }
2053 req[pos++] = 0x00; req[pos++] = 0x00;
2054 req[pos++] = 0x07; //unknown
2055 req[pos++] = 0x00; req[pos++] = 0x00;
2056 req[pos++] = 0x80; //unknown
2057 req[pos++] = 0x01; //unknown
2058 req[pos++] = 0x05; //unknown
2059 req[pos++] = 0x00; req[pos++] = 0x00;
2060
2061 /* Proxy data blocks */
2062 for (i=0;i<4;i++) {
2063 port = 8080;
2064 Proxy = NULL;
2065 if (i==0) {
2066 port = settings->ProxyPort;
2067 Proxy = settings->Proxy;
2068 } else if (i==1) {
2069 port = settings->Proxy2Port;
2070 Proxy = settings->Proxy2;
2071 }
2072 req[pos++] = 0x08; req[pos++] = 0x00;
2073 if (Proxy != NULL && UnicodeLength(Proxy)!=0) {
2074 if (UnicodeLength(Proxy)%2 != 0) {
2075 req[pos++] = (12 + (UnicodeLength(Proxy)+1)*2)/256;
2076 req[pos++] = (12 + (UnicodeLength(Proxy)+1)*2)%256;
2077 } else {
2078 req[pos++] = (12 + UnicodeLength(Proxy)*2)/256;
2079 req[pos++] = (12 + UnicodeLength(Proxy)*2)%256;
2080 }
2081 } else {
2082 req[pos++] = 12/256;
2083 req[pos++] = 12%256;
2084 }
2085 req[pos++] = i+1;
2086 if (Proxy != NULL) {
2087 req[pos++] = UnicodeLength(Proxy);
2088 } else {
2089 req[pos++] = 0;
2090 }
2091 req[pos++] = port/256;
2092 req[pos++] = port%256;
2093 req[pos++] = 0x00;
2094
2095 req[pos++] = 0x00;
2096 req[pos++] = 0x01;
2097
2098 req[pos++] = 0x00;
2099 if (Proxy != NULL && UnicodeLength(Proxy)!=0) {
2100 CopyUnicodeString(req+pos,Proxy);
2101 pos+=UnicodeLength(Proxy)*2;
2102 if (UnicodeLength(Proxy)%2 != 0) {
2103 req[pos++] = 0x00;
2104 req[pos++] = 0x00;
2105 }
2106 }
2107 }
2108
2109 req[pos++] = 0x09; req[pos++] = 0x00; req[pos++] = 0x00;
2110 req[pos++] = 0x0C; req[pos++] = 0x02; req[pos++] = 0x00;
2111 req[pos++] = 0x00; req[pos++] = 0x02; req[pos++] = 0x00;
2112 req[pos++] = 0x00; req[pos++] = 0x00; req[pos++] = 0x00;
2113 } else {
2114 /* end of blocks ? */
2115 memcpy(req + pos, "\x80\x00\x00\x0c", 4);pos += 4;
2116 }
2117
2118 UnLock[4] = settings->Location-1;
2119 smprintf(s, "Making Connection settings read-write\n");
2120 error = GSM_WaitFor (s, UnLock, 5, 0x3f, 4, ID_SetConnectSet);
2121 if (error != ERR_NONE) return error;
2122
2123 switch (Type) {
2124 case N6510_MMS_SETTINGS:
2125 smprintf(s, "Setting MMS settings\n");
2126 break;
2127 case N6510_CHAT_SETTINGS:
2128 smprintf(s, "Setting Chat settings\n");
2129 break;
2130 case N6510_WAP_SETTINGS:
2131 smprintf(s, "Setting WAP settings\n");
2132 break;
2133 case N6510_SYNCML_SETTINGS:
2134 smprintf(s, "Setting SyncML settings\n");
2135 break;
2136 }
2137 error = GSM_WaitFor (s, req, pos, 0x3f, 4, ID_SetConnectSet);
2138 if (error != ERR_NONE) {
2139 if (error == ERR_INSIDEPHONEMENU || error == ERR_INVALIDLOCATION) {
2140 DCT3DCT4_DisableConnectionFunctions(s);
2141 }
2142 return error;
2143 }
2144
2145 if (settings->ReadOnly) {
2146 Lock[4] = settings->Location-1;
2147 smprintf(s, "Making Connection settings readonly\n");
2148 error = GSM_WaitFor (s, Lock, 5, 0x3f, 4, ID_SetConnectSet);
2149 if (error != ERR_NONE) return error;
2150 }
2151
2152 error = DCT3DCT4_SetActiveConnectSet(s, settings);
2153 if (error != ERR_NONE) return error;
2154
2155 return DCT3DCT4_DisableConnectionFunctions(s);
2156}
2157
2158static GSM_Error N6510_SetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2159{
2160 return N6510_SetConnectionSettings(s, settings, N6510_WAP_SETTINGS);
2161}
2162
2163static GSM_Error N6510_SetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2164{
2165 return N6510_SetConnectionSettings(s, settings, N6510_MMS_SETTINGS);
2166}
2167
2168static GSM_Error N6510_ReplyGetOriginalIMEI(GSM_Protocol_Message msg, GSM_StateMachine *s)
2169{
2170 if (msg.Buffer[7] == 0x00) {
2171 smprintf(s, "No SIM card\n");
2172 return ERR_SECURITYERROR;
2173 } else {
2174 return NOKIA_ReplyGetPhoneString(msg, s);
2175 }
2176}
2177
2178static GSM_Error N6510_GetOriginalIMEI(GSM_StateMachine *s, char *value)
2179{
2180 return NOKIA_GetPhoneString(s,"\x00\x07\x02\x01\x00\x01",6,0x42,value,ID_GetOriginalIMEI,14);
2181}
2182
2183static GSM_Error N6510_ReplyGetSMSStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
2184{
2185 GSM_Phone_Data *Data = &s->Phone.Data;
2186
2187 switch (msg.Buffer[3]) {
2188 case 0x09:
2189 switch (msg.Buffer[4]) {
2190 case 0x00:
2191 smprintf(s, "Max. in phone memory : %i\n",msg.Buffer[10]*256+msg.Buffer[11]);
2192 smprintf(s, "Used in phone memory : %i\n",msg.Buffer[12]*256+msg.Buffer[13]);
2193 smprintf(s, "Unread in phone memory : %i\n",msg.Buffer[14]*256+msg.Buffer[15]);
2194 smprintf(s, "Max. in SIM : %i\n",msg.Buffer[22]*256+msg.Buffer[23]);
2195 smprintf(s, "Used in SIM : %i\n",msg.Buffer[24]*256+msg.Buffer[25]);
2196 smprintf(s, "Unread in SIM : %i\n",msg.Buffer[26]*256+msg.Buffer[27]);
2197 Data->SMSStatus->PhoneSize= msg.Buffer[10]*256+msg.Buffer[11];
2198 Data->SMSStatus->PhoneUsed= msg.Buffer[12]*256+msg.Buffer[13];
2199 Data->SMSStatus->PhoneUnRead = msg.Buffer[14]*256+msg.Buffer[15];
2200 Data->SMSStatus->SIMSize= msg.Buffer[22]*256+msg.Buffer[23];
2201 Data->SMSStatus->SIMUsed = msg.Buffer[24]*256+msg.Buffer[25];
2202 Data->SMSStatus->SIMUnRead = msg.Buffer[26]*256+msg.Buffer[27];
2203 return ERR_NONE;
2204 case 0x0f:
2205 smprintf(s, "No PIN\n");
2206 return ERR_SECURITYERROR;
2207 default:
2208 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
2209 return ERR_UNKNOWNRESPONSE;
2210 }
2211 case 0x1a:
2212 smprintf(s, "Wait a moment. Phone is during power on and busy now\n");
2213 return ERR_SECURITYERROR;
2214 }
2215 return ERR_UNKNOWNRESPONSE;
2216}
2217
2218static GSM_Error N6510_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status)
2219{
2220 GSM_Error error;
2221 GSM_Phone_N6510Data*Priv = &s->Phone.Data.Priv.N6510;
2222 unsigned char req[] = {N6110_FRAME_HEADER, 0x08, 0x00, 0x00};
2223
2224 s->Phone.Data.SMSStatus=status;
2225 smprintf(s, "Getting SMS status\n");
2226 error = GSM_WaitFor (s, req, 6, 0x14, 2, ID_GetSMSStatus);
2227 if (error != ERR_NONE) return error;
2228
2229 /* DCT4 family doesn't show in frame with SMS status info
2230 * about Templates. We get separately info about this SMS folder.
2231 */
2232 error = N6510_GetSMSFolderStatus(s, 0x06);
2233 if (error != ERR_NONE) return error;
2234 status->TemplatesUsed = Priv->LastSMSFolder.Number;
2235
2236 return error;
2237}
2238
2239static GSM_Error N6510_ReplyDeleteSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
2240{
2241 switch (msg.Buffer[3]) {
2242 case 0x05:
2243 smprintf(s, "SMS deleted OK\n");
2244 return ERR_NONE;
2245 case 0x06:
2246 switch (msg.Buffer[4]) {
2247 case 0x02:
2248 smprintf(s, "Invalid location\n");
2249 return ERR_INVALIDLOCATION;
2250 default:
2251 smprintf(s, "Unknown error: %02x\n",msg.Buffer[4]);
2252 return ERR_UNKNOWNRESPONSE;
2253 }
2254 }
2255 return ERR_UNKNOWNRESPONSE;
2256}
2257
2258static GSM_Error N6510_DeleteSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
2259{
2260 unsigned char folderid;
2261 int location;
2262 unsigned char req[] = {N6110_FRAME_HEADER, 0x04,
2263 0x01, /* 0x01=SM, 0x02=ME */
2264 0x00, /* FolderID */
2265 0x00, 0x02, /* Location */
2266 0x0F, 0x55};
2267
2268 N6510_GetSMSLocation(s, sms, &folderid, &location);
2269
2270 switch (folderid) {
2271 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
2272 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
2273 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders*/
2274 }
2275 req[6]=location / 256;
2276 req[7]=location;
2277
2278 smprintf(s, "Deleting sms\n");
2279 return GSM_WaitFor (s, req, 10, 0x14, 4, ID_DeleteSMSMessage);
2280}
2281
2282static GSM_Error N6510_ReplySendSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
2283{
2284 switch (msg.Buffer[8]) {
2285 case 0x00:
2286 smprintf(s, "SMS sent OK, TPMR for sent sms is %02x\n",msg.Buffer[10]);
2287 if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,0,msg.Buffer[10]);
2288 return ERR_NONE;
2289 default:
2290 smprintf(s, "SMS not sent OK, error code probably %i\n",msg.Buffer[8]);
2291 if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,msg.Buffer[8],msg.Buffer[10]);
2292 return ERR_NONE;
2293 }
2294}
2295
2296static GSM_Error N6510_SendSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
2297{
2298 int length = 11;
2299 GSM_Error error;
2300 GSM_SMSMessageLayout Layout;
2301 unsigned char req [300] = {
2302 N6110_FRAME_HEADER, 0x02, 0x00, 0x00, 0x00, 0x55, 0x55};
2303
2304 if (sms->PDU == SMS_Deliver) sms->PDU = SMS_Submit;
2305 memset(req+9,0x00,sizeof(req) - 9);
2306 error=N6510_EncodeSMSFrame(s, sms, req + 9, &Layout, &length);
2307 if (error != ERR_NONE) return error;
2308
2309 smprintf(s, "Sending sms\n");
2310 return s->Protocol.Functions->WriteMessage(s, req, length + 9, 0x02);
2311}
2312
2313static GSM_Error N6510_ReplyGetSecurityStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
2314{
2315 GSM_Phone_Data *Data = &s->Phone.Data;
2316
2317 smprintf(s, "Security Code status received: ");
2318 switch (msg.Buffer[4]) {
2319 case 0x01 : smprintf(s, "waiting for Security Code.\n"); *Data->SecurityStatus = SEC_SecurityCode;break;
2320 case 0x07 :
2321 case 0x02 : smprintf(s, "waiting for PIN.\n"); *Data->SecurityStatus = SEC_Pin; break;
2322 case 0x03 : smprintf(s, "waiting for PUK.\n"); *Data->SecurityStatus = SEC_Puk; break;
2323 case 0x05 : smprintf(s, "PIN ok, SIM ok\n"); *Data->SecurityStatus = SEC_None; break;
2324 case 0x06 : smprintf(s, "No input status\n"); *Data->SecurityStatus = SEC_None; break;
2325 case 0x16 : smprintf(s, "No SIM card\n"); *Data->SecurityStatus = SEC_None; break;
2326 case 0x1A : smprintf(s, "SIM card rejected!\n"); *Data->SecurityStatus = SEC_None; break;
2327 default : smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
2328 return ERR_UNKNOWNRESPONSE;
2329 }
2330 return ERR_NONE;
2331}
2332
2333static GSM_Error N6510_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status)
2334{
2335 unsigned char req[5] = {N6110_FRAME_HEADER, 0x11, 0x00};
2336
2337 s->Phone.Data.SecurityStatus=Status;
2338 smprintf(s, "Getting security code status\n");
2339 return GSM_WaitFor (s, req, 5, 0x08, 2, ID_GetSecurityStatus);
2340}
2341
2342static GSM_Error N6510_ReplyEnterSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s)
2343{
2344 switch (msg.Buffer[3]) {
2345 case 0x08:
2346 smprintf(s, "Security code OK\n");
2347 return ERR_NONE;
2348 case 0x09:
2349 switch (msg.Buffer[4]) {
2350 case 0x06:
2351 smprintf(s, "Wrong PIN\n");
2352 return ERR_SECURITYERROR;
2353 case 0x09:
2354 smprintf(s, "Wrong PUK\n");
2355 return ERR_SECURITYERROR;
2356 default:
2357 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
2358 }
2359 }
2360 return ERR_UNKNOWNRESPONSE;
2361}
2362
2363static GSM_Error N6510_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode Code)
2364{
2365 int len = 0;
2366 unsigned char req[15] = {N6110_FRAME_HEADER, 0x07,
2367 0x00};/* Code type */
2368
2369 switch (Code.Type) {
2370 case SEC_Pin: req[4] = 0x02; break;
2371 case SEC_Puk: req[4] = 0x03; break;/* FIXME */
2372 default : return ERR_NOTSUPPORTED;
2373 }
2374
2375 len = strlen(Code.Code);
2376 memcpy(req+5,Code.Code,len);
2377 req[5+len]=0x00;
2378
2379 smprintf(s, "Entering security code\n");
2380 return GSM_WaitFor (s, req, 6+len, 0x08, 4, ID_EnterSecurityCode);
2381}
2382
2383static GSM_Error N6510_ReplySaveSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
2384{
2385 unsigned char folder;
2386 GSM_Phone_Data *Data = &s->Phone.Data;
2387
2388 switch (msg.Buffer[3]) {
2389 case 0x01:
2390 switch (msg.Buffer[4]) {
2391 case 0x00:
2392 smprintf(s, "Done OK\n");
2393 smprintf(s, "Folder info: %i %i\n",msg.Buffer[5],msg.Buffer[8]);
2394 switch (msg.Buffer[8]) {
2395 case 0x02 : if (msg.Buffer[5] == 0x02) {
2396 folder = 0x03; /* INBOX ME */
2397 } else {
2398 folder = 0x01; /* INBOX SIM */
2399 }
2400 break;
2401 case 0x03 : if (msg.Buffer[5] == 0x02) {
2402 folder = 0x04; /* OUTBOX ME */
2403 } else {
2404 folder = 0x02; /* OUTBOX SIM */
2405 }
2406 break;
2407 default : folder = msg.Buffer[8] + 1;
2408 }
2409 N6510_SetSMSLocation(s, Data->SaveSMSMessage,folder,msg.Buffer[6]*256+msg.Buffer[7]);
2410 smprintf(s, "Saved in folder %i at location %i\n",folder, msg.Buffer[6]*256+msg.Buffer[7]);
2411 Data->SaveSMSMessage->Folder = folder;
2412 return ERR_NONE;
2413 case 0x02:
2414 printf("Incorrect location\n");
2415 return ERR_INVALIDLOCATION;
2416 case 0x05:
2417 printf("Incorrect folder\n");
2418 return ERR_INVALIDLOCATION;
2419 default:
2420 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
2421 return ERR_UNKNOWNRESPONSE;
2422 }
2423 case 0x17:
2424 smprintf(s, "SMS name changed\n");
2425 return ERR_NONE;
2426 }
2427 return ERR_UNKNOWNRESPONSE;
2428}
2429
2430static GSM_Error N6510_PrivSetSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
2431{
2432 int location, length = 11;
2433 unsigned char folderid, folder;
2434 GSM_SMSMessageLayout Layout;
2435 GSM_Error error;
2436 unsigned char req [300] = {
2437 N6110_FRAME_HEADER, 0x00,
2438 0x01, /* 1 = SIM, 2 = ME */
2439 0x02, /* Folder */
2440 0x00, 0x01, /* Location */
2441 0x01}; /* SMS state */
2442 unsigned char NameReq[200] = {
2443 N6110_FRAME_HEADER, 0x16,
2444 0x01, /* 1 = SIM, 2 = ME */
2445 0x02, /* Folder */
2446 0x00, 0x01}; /* Location */
2447
2448 N6510_GetSMSLocation(s, sms, &folderid, &location);
2449 switch (folderid) {
2450 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
2451 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
2452 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders*/
2453 }
2454 req[6]=location / 256;
2455 req[7]=location;
2456
2457 switch (sms->PDU) {
2458 case SMS_Submit:
2459 /* Inbox */
2460 if (folderid == 0x01 || folderid == 0x03) sms->PDU = SMS_Deliver;
2461 break;
2462 case SMS_Deliver:
2463 /* SIM Outbox */
2464 if (folderid == 0x02) sms->PDU = SMS_Submit;
2465 break;
2466 default:
2467 return ERR_UNKNOWN;
2468 }
2469 if (sms->PDU == SMS_Deliver) {
2470 switch (sms->State) {
2471 case SMS_Sent: /* We use GSM_Read, because phone return error */
2472 case SMS_Read: req[8] = 0x01; break;
2473 case SMS_UnSent: /* We use GSM_UnRead, because phone return error */
2474 case SMS_UnRead: req[8] = 0x03; break;
2475 }
2476 } else {
2477 switch (sms->State) {
2478 case SMS_Sent: /* We use GSM_Sent, because phone change folder */
2479 case SMS_Read: req[8] = 0x05; break;
2480 case SMS_UnSent: /* We use GSM_UnSent, because phone change folder */
2481 case SMS_UnRead: req[8] = 0x07; break;
2482 }
2483 }
2484 memset(req+9,0x00,sizeof(req) - 9);
2485 error=N6510_EncodeSMSFrame(s, sms, req + 9, &Layout, &length);
2486 if (error != ERR_NONE) return error;
2487
2488 s->Phone.Data.SaveSMSMessage=sms;
2489 smprintf(s, "Saving sms\n");
2490 error=GSM_WaitFor (s, req, length+9, 0x14, 4, ID_SaveSMSMessage);
2491 if (error == ERR_NONE && UnicodeLength(sms->Name)!=0) {
2492 folder = sms->Folder;
2493 sms->Folder = 0;
2494 N6510_GetSMSLocation(s, sms, &folderid, &location);
2495 switch (folderid) {
2496 case 0x01: NameReq[5] = 0x02; break; /* INBOX SIM */
2497 case 0x02: NameReq[5] = 0x03; break; /* OUTBOX SIM */
2498 default : NameReq[5] = folderid - 1; NameReq[4] = 0x02; break; /* ME folders*/
2499 }
2500 NameReq[6]=location / 256;
2501 NameReq[7]=location;
2502 length = 8;
2503 CopyUnicodeString(NameReq+length, sms->Name);
2504 length = length+UnicodeLength(sms->Name)*2;
2505 NameReq[length++] = 0;
2506 NameReq[length++] = 0;
2507 error=GSM_WaitFor (s, NameReq, length, 0x14, 4, ID_SaveSMSMessage);
2508 sms->Folder = folder;
2509 }
2510 return error;
2511}
2512
2513static GSM_Error N6510_SetSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2514{
2515 int location;
2516 unsigned char folderid;
2517
2518 N6510_GetSMSLocation(s, sms, &folderid, &location);
2519 if (location == 0) return ERR_INVALIDLOCATION;
2520 return N6510_PrivSetSMSMessage(s, sms);
2521}
2522
2523static GSM_Error N6510_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2524{
2525 int location;
2526 unsigned char folderid;
2527
2528 N6510_GetSMSLocation(s, sms, &folderid, &location);
2529 location = 0;
2530 N6510_SetSMSLocation(s, sms, folderid, location);
2531 return N6510_PrivSetSMSMessage(s, sms);
2532}
2533
2534static GSM_Error N6510_ReplyGetDateTime(GSM_Protocol_Message msg, GSM_StateMachine *s)
2535{
2536 smprintf(s, "Date & time received\n");
2537 if (msg.Buffer[4]==0x01) {
2538 NOKIA_DecodeDateTime(s, msg.Buffer+10, s->Phone.Data.DateTime);
2539 return ERR_NONE;
2540 }
2541 smprintf(s, "Not set in phone\n");
2542 return ERR_EMPTY;
2543}
2544
2545static GSM_Error N6510_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
2546{
2547 unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x00, 0x00};
2548
2549 s->Phone.Data.DateTime=date_time;
2550 smprintf(s, "Getting date & time\n");
2551 return GSM_WaitFor (s, req, 6, 0x19, 4, ID_GetDateTime);
2552}
2553
2554static GSM_Error N6510_ReplySetDateTime(GSM_Protocol_Message msg, GSM_StateMachine *s)
2555{
2556 smprintf(s, "Date & time set\n");
2557 return ERR_NONE;
2558}
2559
2560static GSM_Error N6510_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
2561{
2562 unsigned char req[] = {N6110_FRAME_HEADER,
2563 0x01, 0x00, 0x01, 0x01, 0x0c, 0x01, 0x03,
2564 0x00, 0x00,/* Year */
2565 0x08, 0x01, /* Month & Day */
2566 0x15, 0x1f,/* Hours & Minutes */
2567 0x2b, /* Second ? */
2568 0x00};
2569
2570 NOKIA_EncodeDateTime(s, req+10, date_time);
2571 req[16] = date_time->Second;
2572 smprintf(s, "Setting date & time\n");
2573 return GSM_WaitFor (s, req, 18, 0x19, 4, ID_SetDateTime);
2574}
2575
2576static GSM_Error N6510_ReplyGetManufactureMonth(GSM_Protocol_Message msg, GSM_StateMachine *s)
2577{
2578 if (msg.Buffer[7] == 0x00) {
2579 smprintf(s, "No SIM card\n");
2580 return ERR_SECURITYERROR;
2581 } else {
2582 sprintf(s->Phone.Data.PhoneString,"%02i/%04i",msg.Buffer[13],msg.Buffer[14]*256+msg.Buffer[15]);
2583 return ERR_NONE;
2584 }
2585}
2586
2587static GSM_Error N6510_GetManufactureMonth(GSM_StateMachine *s, char *value)
2588{
2589 unsigned char req[6] = {0x00, 0x05, 0x02, 0x01, 0x00, 0x02};
2590 //unsigned char req[6] = {0x00, 0x03, 0x04, 0x0B, 0x01, 0x00};
2591
2592 s->Phone.Data.PhoneString=value;
2593 smprintf(s, "Getting manufacture month\n");
2594 return GSM_WaitFor (s, req, 6, 0x42, 2, ID_GetManufactureMonth);
2595 //return GSM_WaitFor (s, req, 6, 0x1B, 2, ID_GetManufactureMonth);
2596}
2597
2598static GSM_Error N6510_ReplyGetAlarm(GSM_Protocol_Message msg, GSM_StateMachine *s)
2599{
2600 GSM_Phone_Data *Data = &s->Phone.Data;
2601
2602 switch(msg.Buffer[3]) {
2603 case 0x1A:
2604 smprintf(s, " Alarm: %02d:%02d\n", msg.Buffer[14], msg.Buffer[15]);
2605 Data->Alarm->Repeating = true;
2606 Data->Alarm->Text[0] = 0;
2607 Data->Alarm->Text[1] = 0;
2608 Data->Alarm->DateTime.Hour= msg.Buffer[14];
2609 Data->Alarm->DateTime.Minute= msg.Buffer[15];
2610 Data->Alarm->DateTime.Second= 0;
2611 return ERR_NONE;
2612 case 0x20:
2613 smprintf(s, "Alarm state received\n");
2614 if (msg.Buffer[37] == 0x01) {
2615 smprintf(s, " Not set in phone\n");
2616 return ERR_EMPTY;
2617 }
2618 smprintf(s, "Enabled\n");
2619 return ERR_NONE;
2620 }
2621 return ERR_UNKNOWNRESPONSE;
2622}
2623
2624static GSM_Error N6510_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm)
2625{
2626 unsigned char StateReq[] = {N6110_FRAME_HEADER, 0x1f, 0x01, 0x00};
2627 unsigned char GetReq [] = {N6110_FRAME_HEADER, 0x19, 0x00, 0x02};
2628 GSM_Errorerror;
2629
2630 if (alarm->Location != 1) return ERR_NOTSUPPORTED;
2631
2632 s->Phone.Data.Alarm=alarm;
2633 smprintf(s, "Getting alarm state\n");
2634 error = GSM_WaitFor (s, StateReq, 6, 0x19, 4, ID_GetAlarm);
2635 if (error != ERR_NONE) return error;
2636
2637 smprintf(s, "Getting alarm\n");
2638 return GSM_WaitFor (s, GetReq, 6, 0x19, 4, ID_GetAlarm);
2639}
2640
2641static GSM_Error N6510_ReplySetAlarm(GSM_Protocol_Message msg, GSM_StateMachine *s)
2642{
2643 smprintf(s, "Alarm set\n");
2644 return ERR_NONE;
2645}
2646
2647static GSM_Error N6510_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm)
2648{
2649 unsigned char req[] = {N6110_FRAME_HEADER,
2650 0x11, 0x00, 0x01, 0x01, 0x0c, 0x02,
2651 0x01, 0x00, 0x00, 0x00, 0x00,
2652 0x00, 0x00, /* Hours, Minutes */
2653 0x00, 0x00, 0x00 };
2654
2655 if (alarm->Location != 1) return ERR_NOTSUPPORTED;
2656
2657 req[14] = alarm->DateTime.Hour;
2658 req[15] = alarm->DateTime.Minute;
2659
2660 smprintf(s, "Setting alarm\n");
2661 return GSM_WaitFor (s, req, 19, 0x19, 4, ID_SetAlarm);
2662}
2663
2664static GSM_Error N6510_ReplyGetRingtonesInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
2665{
2666 int tmp,i;
2667 GSM_Phone_Data *Data = &s->Phone.Data;
2668
2669 smprintf(s, "Ringtones info received\n");
2670 memset(Data->RingtonesInfo,0,sizeof(GSM_AllRingtonesInfo));
2671 if (msg.Buffer[4] * 256 + msg.Buffer[5] == 0x00) return ERR_EMPTY;
2672 Data->RingtonesInfo->Number = msg.Buffer[4] * 256 + msg.Buffer[5];
2673 tmp = 6;
2674 for (i=0;i<Data->RingtonesInfo->Number;i++) {
2675 Data->RingtonesInfo->Ringtone[i].Group = msg.Buffer[tmp+4];
2676 Data->RingtonesInfo->Ringtone[i].ID = msg.Buffer[tmp+2] * 256 + msg.Buffer[tmp+3];
2677 memcpy(Data->RingtonesInfo->Ringtone[i].Name,msg.Buffer+tmp+8,(msg.Buffer[tmp+6]*256+msg.Buffer[tmp+7])*2);
2678 smprintf(s, "%5i (%5i). \"%s\"\n",
2679 Data->RingtonesInfo->Ringtone[i].ID,
2680 Data->RingtonesInfo->Ringtone[i].Group,
2681 DecodeUnicodeString(Data->RingtonesInfo->Ringtone[i].Name));
2682 tmp = tmp + (msg.Buffer[tmp]*256+msg.Buffer[tmp+1]);
2683 }
2684 return ERR_NONE;
2685}
2686
2687static GSM_Error N6510_PrivGetRingtonesInfo(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info, bool AllRingtones)
2688{
2689 GSM_Errorerror;
2690 unsigned char UserReq[8] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0x02};
2691 // unsigned char All_Req[9] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x7D};
2692 unsigned char All_Req[8] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0x00};
2693
2694 s->Phone.Data.RingtonesInfo=Info;
2695 smprintf(s, "Getting binary ringtones ID\n");
2696 if (AllRingtones) {
2697 // error = GSM_WaitFor (s, All_Req, 9, 0x1f, 4, ID_GetRingtonesInfo);
2698 error = GSM_WaitFor (s, All_Req, 8, 0x1f, 4, ID_GetRingtonesInfo);
2699 if (error == ERR_EMPTY && Info->Number == 0) return ERR_NOTSUPPORTED;
2700 return error;
2701 } else {
2702 error = GSM_WaitFor (s, UserReq, 8, 0x1f, 4, ID_GetRingtonesInfo);
2703 if (error == ERR_EMPTY && Info->Number == 0) return ERR_NOTSUPPORTED;
2704 return error;
2705 }
2706}
2707
2708static GSM_Error N6510_GetRingtonesInfo(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info)
2709{
2710 return N6510_PrivGetRingtonesInfo(s, Info, true);
2711}
2712
2713static GSM_Error N6510_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
2714{
2715 int tmp,i;
2716 GSM_Phone_Data *Data = &s->Phone.Data;
2717
2718 smprintf(s, "Ringtone received\n");
2719 memcpy(Data->Ringtone->Name,msg.Buffer+8,msg.Buffer[7]*2);
2720 Data->Ringtone->Name[msg.Buffer[7]*2]=0;
2721 Data->Ringtone->Name[msg.Buffer[7]*2+1]=0;
2722 smprintf(s, "Name \"%s\"\n",DecodeUnicodeString(Data->Ringtone->Name));
2723 if (msg.Buffer[msg.Buffer[7]*2+10] == 'M' &&
2724 msg.Buffer[msg.Buffer[7]*2+11] == 'T' &&
2725 msg.Buffer[msg.Buffer[7]*2+12] == 'h' &&
2726 msg.Buffer[msg.Buffer[7]*2+13] == 'd') {
2727 smprintf(s,"MIDI\n");
2728 tmp = msg.Buffer[7]*2+10;
2729 i = msg.Length - 2; /* ?????? */
2730 Data->Ringtone->Format = RING_MIDI;
2731 } else {
2732 /* Looking for end */
2733 i=8+msg.Buffer[7]*2+3;
2734 tmp = i;
2735 while (true) {
2736 if (msg.Buffer[i]==0x07 && msg.Buffer[i+1]==0x0b) {
2737 i=i+2; break;
2738 }
2739 i++;
2740 if (i==msg.Length) return ERR_EMPTY;
2741 }
2742 }
2743 /* Copying frame */
2744 memcpy(Data->Ringtone->NokiaBinary.Frame,msg.Buffer+tmp,i-tmp);
2745 Data->Ringtone->NokiaBinary.Length=i-tmp;
2746 return ERR_NONE;
2747}
2748
2749static GSM_Error N6510_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone)
2750{
2751 GSM_AllRingtonesInfo Info;
2752 GSM_Error error;
2753 unsigned char req2[6] = {N7110_FRAME_HEADER, 0x12,
2754 0x00, 0xe7}; /* Location */
2755
2756 if (Ringtone->Format == 0x00) Ringtone->Format = RING_NOKIABINARY;
2757
2758 switch (Ringtone->Format) {
2759 case RING_NOTETONE:
2760 /* In the future get binary and convert */
2761 return ERR_NOTSUPPORTED;
2762 case RING_NOKIABINARY:
2763 s->Phone.Data.Ringtone= Ringtone;
2764 Info.Number = 0;
2765 error=N6510_PrivGetRingtonesInfo(s, &Info, PhoneRingtone);
2766 if (error != ERR_NONE) return error;
2767 if (Ringtone->Location > Info.Number) return ERR_INVALIDLOCATION;
2768 req2[4] = Info.Ringtone[Ringtone->Location-1].ID / 256;
2769 req2[5] = Info.Ringtone[Ringtone->Location-1].ID % 256;
2770 smprintf(s, "Getting binary ringtone\n");
2771 return GSM_WaitFor (s, req2, 6, 0x1f, 4, ID_GetRingtone);
2772 case RING_MIDI:
2773 return ERR_NOTSUPPORTED;
2774 }
2775 return ERR_NOTSUPPORTED;
2776}
2777
2778static GSM_Error N6510_PlayTone(GSM_StateMachine *s, int Herz, unsigned char Volume, bool start)
2779{
2780 GSM_Error error;
2781 unsigned char reqStart[] = {
2782 0x00,0x06,0x01,0x00,0x07,0x00 };
2783 unsigned char reqPlay[] = {
2784 0x00,0x06,0x01,0x14,0x05,0x04,
2785 0x00,0x00,0x00,0x03,0x03,0x08,
2786 0x00,0x00,0x00,0x01,0x00,0x00,
2787 0x03,0x08,0x01,0x00,
2788 0x07,0xd0,/*Frequency */
2789 0x00,0x00,0x03,0x08,0x02,0x00,0x00,
2790 0x05, /*Volume */
2791 0x00,0x00};
2792 unsigned char reqOff[] = {
2793 0x00,0x06,0x01,0x14,0x05,0x05,
2794 0x00,0x00,0x00,0x01,0x03,0x08,
2795 0x05,0x00,0x00,0x08,0x00,0x00};
2796 // unsigned char reqOff2[] = {
2797 // 0x00,0x06,0x01,0x14,0x05,0x04,
2798 // 0x00,0x00,0x00,0x01,0x03,0x08,
2799 // 0x00,0x00,0x00,0x00,0x00,0x00};
2800
2801 if (start) {
2802 smprintf(s, "Enabling sound - part 1\n");
2803 error=GSM_WaitFor (s, reqStart, 6, 0x0b, 4, ID_PlayTone);
2804 if (error!=ERR_NONE) return error;
2805 smprintf(s, "Enabling sound - part 2 (disabling sound command)\n");
2806 error=GSM_WaitFor (s, reqOff, 18, 0x0b, 4, ID_PlayTone);
2807 if (error!=ERR_NONE) return error;
2808 }
2809
2810 /* For Herz==255*255 we have silent */
2811 if (Herz!=255*255) {
2812 reqPlay[23] = Herz%256;
2813 reqPlay[22] = Herz/256;
2814 reqPlay[31] = Volume;
2815 smprintf(s, "Playing sound\n");
2816 return GSM_WaitFor (s, reqPlay, 34, 0x0b, 4, ID_PlayTone);
2817 } else {
2818 reqPlay[23] = 0;
2819 reqPlay[22] = 0;
2820 reqPlay[31] = 0;
2821 smprintf(s, "Playing silent sound\n");
2822 return GSM_WaitFor (s, reqPlay, 34, 0x0b, 4, ID_PlayTone);
2823
2824 // smprintf(s, "Disabling sound - part 1\n");
2825 // error=GSM_WaitFor (s, reqOff, 18, 0x0b, 4, ID_PlayTone);
2826 // if (error!=ERR_NONE) return error;
2827 // smprintf(s, "Disabling sound - part 2\n");
2828 // return GSM_WaitFor (s, reqOff2, 18, 0x0b, 4, ID_PlayTone);
2829 }
2830}
2831
2832static GSM_Error N6510_ReplyGetPPM(GSM_Protocol_Message msg, GSM_StateMachine *s)
2833{
2834 GSM_Phone_Data *Data = &s->Phone.Data;
2835 int pos = 6,len;
2836
2837 smprintf(s, "Received phone info\n");
2838
2839 while(pos < msg.Length) {
2840 if (msg.Buffer[pos] == 0x55 && msg.Buffer[pos+1] == 0x55) {
2841 while(1) {
2842 if (msg.Buffer[pos] != 0x55) break;
2843 pos++;
2844 }
2845 }
2846 len = pos;
2847 while(1) {
2848 if (msg.Buffer[len] == 0x00 && msg.Buffer[len+1] == 0x00) break;
2849 len++;
2850 }
2851 while(1) {
2852 if (msg.Buffer[len] != 0x00) break;
2853 len++;
2854 }
2855 len = len-pos;
2856 smprintf(s, "Block with ID %02x",msg.Buffer[pos]);
2857#ifdef DEBUG
2858 if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, di.dl, msg.Buffer+pos, len);
2859#endif
2860 switch (msg.Buffer[pos]) {
2861 case 0x49:
2862 smprintf(s, "hardware version\n");
2863 break;
2864 case 0x58:
2865 pos += 3;
2866 while (msg.Buffer[pos] != 0x00) pos++;
2867 Data->PhoneString[0] = msg.Buffer[pos - 1];
2868 Data->PhoneString[1] = 0x00;
2869 smprintf(s, "PPM %s\n",Data->PhoneString);
2870 return ERR_NONE;
2871 default:
2872 break;
2873 }
2874 pos += len;
2875 }
2876 return ERR_NOTSUPPORTED;
2877}
2878
2879static GSM_Error N6510_GetPPM(GSM_StateMachine *s,char *value)
2880{
2881 //unsigned char req[6] = {N6110_FRAME_HEADER, 0x07, 0x01, 0xff};
2882 unsigned char req[6] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x00};
2883
2884 s->Phone.Data.PhoneString=value;
2885 smprintf(s, "Getting PPM\n");
2886 return GSM_WaitFor (s, req, 6, 0x1b, 3, ID_GetPPM);
2887}
2888
2889static GSM_Error N6510_GetSpeedDial(GSM_StateMachine *s, GSM_SpeedDial *SpeedDial)
2890{
2891 GSM_MemoryEntry pbk;
2892 GSM_Error error;
2893
2894 pbk.MemoryType = MEM7110_SP;
2895 pbk.Location = SpeedDial->Location;
2896 SpeedDial->MemoryLocation = 0;
2897 s->Phone.Data.SpeedDial = SpeedDial;
2898
2899 smprintf(s, "Getting speed dial\n");
2900 error=N6510_GetMemory(s,&pbk);
2901 switch (error) {
2902 case ERR_NOTSUPPORTED:
2903 smprintf(s, "No speed dials set in phone\n");
2904 return ERR_EMPTY;
2905 case ERR_NONE:
2906 if (SpeedDial->MemoryLocation == 0) {
2907 smprintf(s, "Speed dial not assigned or error in firmware\n");
2908 return ERR_EMPTY;
2909 }
2910 return ERR_NONE;
2911 default:
2912 return error;
2913 }
2914}
2915
2916static GSM_Error N6510_ReplyGetProfile(GSM_Protocol_Message msg, GSM_StateMachine *s)
2917{
2918 unsigned char *blockstart;
2919 int i,j;
2920 GSM_Phone_Data*Data = &s->Phone.Data;
2921
2922 switch (msg.Buffer[3]) {
2923 case 0x02:
2924 blockstart = msg.Buffer + 7;
2925 for (i = 0; i < 11; i++) {
2926 smprintf(s, "Profile feature %02x ",blockstart[1]);
2927#ifdef DEBUG
2928 if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, di.dl, blockstart, blockstart[0]);
2929#endif
2930
2931 switch (blockstart[1]) {
2932 case 0x03:
2933 smprintf(s, "Ringtone ID\n");
2934 Data->Profile->FeatureID[Data->Profile->FeaturesNumber] = Profile_RingtoneID;
2935 Data->Profile->FeatureValue[Data->Profile->FeaturesNumber] = blockstart[7];
2936 if (blockstart[7] == 0x00) {
2937 Data->Profile->FeatureValue[Data->Profile->FeaturesNumber] = blockstart[10];
2938 }
2939 Data->Profile->FeaturesNumber++;
2940 break;
2941 case 0x05:/* SMS tone */
2942 j = Data->Profile->FeaturesNumber;
2943 NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,false);
2944 if (j == Data->Profile->FeaturesNumber) {
2945 Data->Profile->FeatureID[Data->Profile->FeaturesNumber] = Profile_MessageTone;
2946 Data->Profile->FeatureValue[Data->Profile->FeaturesNumber] = PROFILE_MESSAGE_PERSONAL;
2947 Data->Profile->FeaturesNumber++;
2948 Data->Profile->FeatureID[Data->Profile->FeaturesNumber] = Profile_MessageToneID;
2949 Data->Profile->FeatureValue[Data->Profile->FeaturesNumber] = blockstart[7];
2950 Data->Profile->FeaturesNumber++;
2951 }
2952 break;
2953 case 0x08:/* Caller groups */
2954 NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,true);
2955 break;
2956 case 0x0c :
2957 CopyUnicodeString(Data->Profile->Name,blockstart + 7);
2958 smprintf(s, "profile Name: \"%s\"\n", DecodeUnicodeString(Data->Profile->Name));
2959 Data->Profile->DefaultName = false;
2960 break;
2961 default:
2962 NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,false);
2963 }
2964 blockstart = blockstart + blockstart[0];
2965 }
2966 return ERR_NONE;
2967 case 0x06:
2968 Data->Profile->Active = false;
2969 if (Data->Profile->Location == msg.Buffer[5]) Data->Profile->Active = true;
2970 return ERR_NONE;
2971 }
2972 return ERR_UNKNOWNRESPONSE;
2973}
2974
2975static GSM_Error N6510_GetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
2976{
2977 unsigned char req[150] = {N6110_FRAME_HEADER, 0x01, 0x01, 0x0C, 0x01};
2978 unsigned charreqActive[] = {N6110_FRAME_HEADER, 0x05};
2979 int i, length = 7;
2980 GSM_Errorerror;
2981
2982 /* For now !!! */
2983 if (!strcmp(s->Phone.Data.ModelInfo->model,"3510")) {
2984 if (s->Phone.Data.VerNum>3.37) return ERR_NOTSUPPORTED;
2985 }
2986 if (!strcmp(s->Phone.Data.ModelInfo->model,"6230")) {
2987 return ERR_NOTSUPPORTED;
2988 }
2989
2990 if (Profile->Location>5) return ERR_INVALIDLOCATION;
2991
2992 for (i = 0; i < 0x0a; i++) {
2993 req[length++] = 0x04;
2994 req[length++] = Profile->Location;
2995 req[length++] = i;
2996 req[length++] = 0x01;
2997 }
2998
2999 req[length++] = 0x04;
3000 req[length++] = Profile->Location;
3001 req[length++] = 0x0c;
3002 req[length++] = 0x01;
3003
3004 req[length++] = 0x04;
3005
3006 Profile->CarKitProfile= false;
3007 Profile->HeadSetProfile= false;
3008
3009 Profile->FeaturesNumber = 0;
3010
3011 s->Phone.Data.Profile=Profile;
3012 smprintf(s, "Getting profile\n");
3013 error = GSM_WaitFor (s, req, length, 0x39, 4, ID_GetProfile);
3014 if (error != ERR_NONE) return error;
3015
3016 smprintf(s, "Checking, which profile is active\n");
3017 return GSM_WaitFor (s, reqActive, 4, 0x39, 4, ID_GetProfile);
3018}
3019
3020static GSM_Error N6510_ReplySetProfile(GSM_Protocol_Message msg, GSM_StateMachine *s)
3021{
3022 unsigned char *blockstart;
3023 int i;
3024
3025 smprintf(s, "Response to profile writing received!\n");
3026
3027 blockstart = msg.Buffer + 6;
3028 for (i = 0; i < msg.Buffer[5]; i++) {
3029 switch (blockstart[2]) {
3030 case 0x00: smprintf(s, "keypad tone level"); break;
3031 case 0x02: smprintf(s, "call alert"); break;
3032 case 0x03: smprintf(s, "ringtone"); break;
3033 case 0x04: smprintf(s, "ringtone volume"); break;
3034 case 0x05: smprintf(s, "SMS tone"); break;
3035 case 0x06: smprintf(s, "vibration"); break;
3036 case 0x07: smprintf(s, "warning tone level"); break;
3037 case 0x08: smprintf(s, "caller groups"); break;
3038 case 0x09: smprintf(s, "automatic answer"); break;
3039 case 0x0c: smprintf(s, "name"); break;
3040 default:
3041 smprintf(s, "Unknown block type %02x", blockstart[2]);
3042 break;
3043 }
3044 if (msg.Buffer[4] == 0x00) {
3045 smprintf(s, ": set OK\n");
3046 } else {
3047 smprintf(s, ": setting error %i\n", msg.Buffer[4]);
3048 }
3049 blockstart = blockstart + blockstart[1];
3050 }
3051 return ERR_NONE;
3052}
3053
3054static GSM_Error N6510_SetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
3055{
3056 int i, length = 7, blocks = 0;
3057 bool found;
3058 unsigned charID,Value;
3059 unsigned char req[150] = {N6110_FRAME_HEADER, 0x03, 0x01,
3060 0x06, /* Number of blocks */
3061 0x03};
3062
3063 if (Profile->Location>5) return ERR_INVALIDLOCATION;
3064
3065 for (i=0;i<Profile->FeaturesNumber;i++) {
3066 found = false;
3067 switch (Profile->FeatureID[i]) {
3068 case Profile_RingtoneID:
3069 ID = 0x03;
3070 Value = Profile->FeatureValue[i];
3071 found = true;
3072 break;
3073 default:
3074 found=NOKIA_FindPhoneFeatureValue(
3075 s,
3076 Profile71_65,
3077 Profile->FeatureID[i],Profile->FeatureValue[i],
3078 &ID,&Value);
3079 }
3080 if (found) {
3081 req[length] = 0x09;
3082 req[length + 1] = ID;
3083 req[length + 2] = Profile->Location;
3084 memcpy(req + length + 4, "\x00\x00\x01", 3);
3085 req[length + 8] = 0x03;
3086 req[length + 3] = req[length + 7] = Value;
3087 blocks++;
3088 length += 9;
3089 }
3090 }
3091
3092 smprintf(s, "Setting profile\n");
3093 return GSM_WaitFor (s, req, length, 0x39, 4, ID_SetProfile);
3094}
3095
3096static GSM_Error N6510_ReplyIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s)
3097{
3098 GSM_SMSMessage sms;
3099
3100#ifdef DEBUG
3101 smprintf(s, "SMS message received\n");
3102 N6510_DecodeSMSFrame(s, &sms, msg.Buffer+10);
3103#endif
3104
3105 if (s->Phone.Data.EnableIncomingSMS && s->User.IncomingSMS!=NULL) {
3106 sms.State = SMS_UnRead;
3107 sms.InboxFolder = true;
3108
3109 N6510_DecodeSMSFrame(s, &sms, msg.Buffer+10);
3110
3111 s->User.IncomingSMS(s->CurrentConfig->Device,sms);
3112 }
3113 return ERR_NONE;
3114}
3115
3116static GSM_Error N6510_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber)
3117{
3118 unsigned intpos = 4;
3119 unsigned char req[100] = {N6110_FRAME_HEADER,0x01,
3120 0x0c};/* Number length */
3121
3122 req[pos++] = strlen(number);
3123 EncodeUnicode(req+pos,number,strlen(number));
3124 pos += strlen(number)*2;
3125 req[pos++] = 0x05; /* call type: voice - 0x05, data - 0x01 */
3126 req[pos++] = 0x01;
3127 req[pos++] = 0x05;
3128 req[pos++] = 0x00;
3129 req[pos++] = 0x02;
3130 req[pos++] = 0x00;
3131 req[pos++] = 0x00;
3132 switch (ShowNumber) {
3133 case GSM_CALL_HideNumber:
3134 req[pos++] = 0x02;
3135 break;
3136 case GSM_CALL_ShowNumber:
3137 req[pos++] = 0x03;
3138 break;
3139 case GSM_CALL_DefaultNumberPresence:
3140 req[pos++] = 0x01;
3141 break;
3142 }
3143
3144 smprintf(s, "Making voice call\n");
3145 return GSM_WaitFor (s, req, pos, 0x01, 4, ID_DialVoice);
3146}
3147
3148/* method 3 */
3149static GSM_Error N6510_ReplyGetCalendarInfo3(GSM_Protocol_Message msg, GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last)
3150{
3151 int i=0,j=0;
3152
3153 while (Last->Location[j] != 0x00) j++;
3154 if (j >= GSM_MAXCALENDARTODONOTES) {
3155 smprintf(s, "Increase GSM_MAXCALENDARTODONOTES\n");
3156 return ERR_UNKNOWN;
3157 }
3158 if (j == 0) {
3159 Last->Number=msg.Buffer[8]*256+msg.Buffer[9];
3160 smprintf(s, "Number of Entries: %i\n",Last->Number);
3161 }
3162 smprintf(s, "Locations: ");
3163 while (14+(i*4) <= msg.Length) {
3164 Last->Location[j++]=msg.Buffer[12+i*4]*256+msg.Buffer[13+i*4];
3165 smprintf(s, "%i ",Last->Location[j-1]);
3166 i++;
3167 }
3168 smprintf(s, "\nNumber of Entries in frame: %i\n",i);
3169 Last->Location[j] = 0;
3170 smprintf(s, "\n");
3171 if (i == 1 && msg.Buffer[12+0*4]*256+msg.Buffer[13+0*4] == 0) return ERR_EMPTY;
3172 if (i == 0) return ERR_EMPTY;
3173 return ERR_NONE;
3174}
3175
3176/* method 3 */
3177static GSM_Error N6510_GetCalendarInfo3(GSM_StateMachine *s, GSM_NOKIACalToDoLocations *Last, bool Calendar)
3178{
3179 GSM_Error error;
3180 int i;
3181 unsigned char req[] = {N6110_FRAME_HEADER, 0x9E, 0xFF, 0xFF, 0x00, 0x00,
3182 0x00, 0x00,/* First location */
3183 0x00}; /* 0 = calendar, 1 = ToDo in 6610 style */
3184
3185 Last->Location[0] = 0x00;
3186 Last->Number = 0;
3187
3188 if (Calendar) {
3189 smprintf(s, "Getting locations for calendar method 3\n");
3190 error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo);
3191 } else {
3192 req[10] = 0x01;
3193 smprintf(s, "Getting locations for ToDo method 2\n");
3194 error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo);
3195 }
3196 if (error != ERR_NONE && error != ERR_EMPTY) return error;
3197
3198 while (1) {
3199 i=0;
3200 while (Last->Location[i] != 0x00) i++;
3201 smprintf(s, "i = %i %i\n",i,Last->Number);
3202 if (i == Last->Number) break;
3203 if (i != Last->Number && error == ERR_EMPTY) {
3204 smprintf(s, "Phone doesn't support some notes with this method. Workaround\n");
3205 Last->Number = i;
3206 break;
3207 }
3208 req[8] = Last->Location[i-1] / 256;
3209 req[9] = Last->Location[i-1] % 256;
3210 if (Calendar) {
3211 smprintf(s, "Getting locations for calendar method 3\n");
3212 error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetCalendarNotesInfo);
3213 } else {
3214 smprintf(s, "Getting locations for todo method 2\n");
3215 error = GSM_WaitFor (s, req, 11, 0x13, 4, ID_GetToDo);
3216 }
3217 if (error != ERR_NONE && error != ERR_EMPTY) return error;
3218 }
3219 return ERR_NONE;
3220}
3221
3222/* method 3 */
3223GSM_Error N6510_ReplyGetCalendar3(GSM_Protocol_Message msg, GSM_StateMachine *s)
3224{
3225 GSM_CalendarEntry *entry = s->Phone.Data.Cal;
3226 GSM_DateTime Date;
3227 unsigned long diff;
3228 int i;
3229 bool found = false;
3230 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
3231
3232 smprintf(s, "Calendar note received method 3\n");
3233
3234 smprintf(s,"Note type %02i: ",msg.Buffer[27]);
3235 switch(msg.Buffer[27]) {
3236 case 0x00: smprintf(s,"Reminder\n"); entry->Type = GSM_CAL_REMINDER; break;
3237 case 0x01: smprintf(s,"Meeting\n"); entry->Type = GSM_CAL_MEETING; break;
3238 case 0x02: smprintf(s,"Call\n"); entry->Type = GSM_CAL_CALL; break;
3239 case 0x04: smprintf(s,"Birthday\n"); entry->Type = GSM_CAL_BIRTHDAY; break;
3240 case 0x08: smprintf(s,"Memo\n"); entry->Type = GSM_CAL_MEMO; break;
3241 default : smprintf(s,"unknown\n");
3242 }
3243
3244 smprintf(s,"StartTime: %04i-%02i-%02i %02i:%02i\n",
3245 msg.Buffer[28]*256+msg.Buffer[29],
3246 msg.Buffer[30],msg.Buffer[31],msg.Buffer[32],
3247 msg.Buffer[33]);
3248 Date.Year = msg.Buffer[28]*256+msg.Buffer[29];
3249 if (entry->Type == GSM_CAL_BIRTHDAY) {
3250 Date.Year = entry->Entries[0].Date.Year;
3251 smprintf(s,"%i\n",Date.Year);
3252 }
3253 Date.Month = msg.Buffer[30];
3254 Date.Day = msg.Buffer[31];
3255 Date.Hour = msg.Buffer[32];
3256 Date.Minute = msg.Buffer[33];
3257 /* Garbage seen with 3510i 3.51 */
3258 if (Date.Month == 0 && Date.Day == 0 && Date.Hour == 0 && Date.Minute == 0) return ERR_EMPTY;
3259 Date.Second= 0;
3260 entry->Entries[0].EntryType = CAL_START_DATETIME;
3261 memcpy(&entry->Entries[0].Date,&Date,sizeof(GSM_DateTime));
3262 entry->EntriesNum++;
3263
3264 if (entry->Type != GSM_CAL_BIRTHDAY) {
3265 smprintf(s,"EndTime: %04i-%02i-%02i %02i:%02i\n",
3266 msg.Buffer[34]*256+msg.Buffer[35],
3267 msg.Buffer[36],msg.Buffer[37],msg.Buffer[38],
3268 msg.Buffer[39]);
3269 Date.Year = msg.Buffer[34]*256+msg.Buffer[35];
3270 Date.Month = msg.Buffer[36];
3271 Date.Day = msg.Buffer[37];
3272 Date.Hour = msg.Buffer[38];
3273 Date.Minute = msg.Buffer[39];
3274 Date.Second= 0;
3275 entry->Entries[1].EntryType = CAL_END_DATETIME;
3276 memcpy(&entry->Entries[1].Date,&Date,sizeof(GSM_DateTime));
3277 entry->EntriesNum++;
3278 }
3279
3280 smprintf(s, "Note icon: %02x\n",msg.Buffer[21]);
3281 for(i=0;i<Priv->CalendarIconsNum;i++) {
3282 if (Priv->CalendarIconsTypes[i] == entry->Type) {
3283 found = true;
3284 }
3285 }
3286 if (!found) {
3287 Priv->CalendarIconsTypes[Priv->CalendarIconsNum] = entry->Type;
3288 Priv->CalendarIcons[Priv->CalendarIconsNum] = msg.Buffer[21];
3289 Priv->CalendarIconsNum++;
3290 }
3291
3292 if (msg.Buffer[14] == 0xFF && msg.Buffer[15] == 0xFF && msg.Buffer[16] == 0xff && msg.Buffer[17] == 0xff)
3293 {
3294 smprintf(s, "No alarm\n");
3295 } else {
3296 diff = ((unsigned int)msg.Buffer[14]) << 24;
3297 diff += ((unsigned int)msg.Buffer[15]) << 16;
3298 diff += ((unsigned int)msg.Buffer[16]) << 8;
3299 diff += msg.Buffer[17];
3300
3301 memcpy(&entry->Entries[entry->EntriesNum].Date,&entry->Entries[0].Date,sizeof(GSM_DateTime));
3302 GetTimeDifference(diff, &entry->Entries[entry->EntriesNum].Date, false, 60);
3303 smprintf(s, "Alarm date : %02i-%02i-%04i %02i:%02i:%02i\n",
3304 entry->Entries[entry->EntriesNum].Date.Day, entry->Entries[entry->EntriesNum].Date.Month,
3305 entry->Entries[entry->EntriesNum].Date.Year, entry->Entries[entry->EntriesNum].Date.Hour,
3306 entry->Entries[entry->EntriesNum].Date.Minute,entry->Entries[entry->EntriesNum].Date.Second);
3307
3308 entry->Entries[entry->EntriesNum].EntryType = CAL_ALARM_DATETIME;
3309 if (msg.Buffer[22]==0x00 && msg.Buffer[23]==0x00 &&
3310 msg.Buffer[24]==0x00 && msg.Buffer[25]==0x00)
3311 {
3312 entry->Entries[entry->EntriesNum].EntryType = CAL_SILENT_ALARM_DATETIME;
3313 smprintf(s, "Alarm type : Silent\n");
3314 }
3315 entry->EntriesNum++;
3316 }
3317
3318 N71_65_GetCalendarRecurrance(s, msg.Buffer+40, entry);
3319
3320 if (entry->Type == GSM_CAL_BIRTHDAY) {
3321 if (msg.Buffer[42] == 0xff && msg.Buffer[43] == 0xff) {
3322 entry->Entries[0].Date.Year = 0;
3323 } else {
3324 entry->Entries[0].Date.Year = msg.Buffer[42]*256+msg.Buffer[43];
3325 }
3326 }
3327
3328 memcpy(entry->Entries[entry->EntriesNum].Text, msg.Buffer+54, msg.Buffer[51]*2);
3329 entry->Entries[entry->EntriesNum].Text[msg.Buffer[51]*2] = 0;
3330 entry->Entries[entry->EntriesNum].Text[msg.Buffer[51]*2+1] = 0;
3331 entry->Entries[entry->EntriesNum].EntryType = CAL_TEXT;
3332 entry->EntriesNum++;
3333 smprintf(s, "Note text: \"%s\"\n",DecodeUnicodeString(entry->Entries[entry->EntriesNum-1].Text));
3334
3335 if (entry->Type == GSM_CAL_CALL) {
3336 memcpy(entry->Entries[entry->EntriesNum].Text, msg.Buffer+(54+msg.Buffer[51]*2), msg.Buffer[52]*2);
3337 entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2] = 0;
3338 entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2+1] = 0;
3339 entry->Entries[entry->EntriesNum].EntryType = CAL_PHONE;
3340 entry->EntriesNum++;
3341 }
3342 if (entry->Type == GSM_CAL_MEETING) {
3343 memcpy(entry->Entries[entry->EntriesNum].Text, msg.Buffer+(54+msg.Buffer[51]*2), msg.Buffer[52]*2);
3344 entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2] = 0;
3345 entry->Entries[entry->EntriesNum].Text[msg.Buffer[52]*2+1] = 0;
3346 entry->Entries[entry->EntriesNum].EntryType = CAL_LOCATION;
3347 entry->EntriesNum++;
3348 }
3349
3350 return ERR_NONE;
3351}
3352
3353static GSM_Error N6510_PrivGetCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start, int *LastCalendarYear)
3354{
3355 GSM_Error error;
3356 GSM_DateTime date_time;
3357 unsigned char req[] = {N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00,
3358 0x00,0x99,/* Location */
3359 0xff,0xff,0xff,0xff,0x01};
3360
3361 if (start) {
3362 /* We have to get current year. It's NOT written in frame for
3363 * Birthday
3364 */
3365 error=s->Phone.Functions->GetDateTime(s,&date_time);
3366 switch (error) {
3367 case ERR_EMPTY:
3368 case ERR_NOTIMPLEMENTED:
3369 GSM_GetCurrentDateTime(&date_time);
3370 break;
3371 case ERR_NONE:
3372 break;
3373 default:
3374 return error;
3375 }
3376 *LastCalendarYear = date_time.Year;
3377 }
3378
3379 Note->EntriesNum = 0;
3380 Note->Entries[0].Date.Year = *LastCalendarYear;
3381
3382 req[8] = Note->Location / 256;
3383 req[9] = Note->Location % 256;
3384
3385 s->Phone.Data.Cal=Note;
3386 smprintf(s, "Getting calendar note method 3\n");
3387 return GSM_WaitFor (s, req, 15, 0x13, 4, ID_GetCalendarNote);
3388}
3389
3390/* method 3 */
3391GSM_Error N6510_GetNextCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start, GSM_NOKIACalToDoLocations *LastCalendar, int *LastCalendarYear, int *LastCalendarPos)
3392{
3393 GSM_Error error;
3394 bool start2;
3395
3396 if (start) {
3397 error=N6510_GetCalendarInfo3(s,LastCalendar,true);
3398 if (error!=ERR_NONE) return error;
3399 if (LastCalendar->Number == 0) return ERR_EMPTY;
3400
3401 *LastCalendarPos = 0;
3402 } else {
3403 (*LastCalendarPos)++;
3404 }
3405
3406 error = ERR_EMPTY;
3407 start2 = start;
3408 while (error == ERR_EMPTY) {
3409 if (*LastCalendarPos >= LastCalendar->Number) return ERR_EMPTY;
3410
3411 Note->Location = LastCalendar->Location[*LastCalendarPos];
3412 error=N6510_PrivGetCalendar3(s, Note, start2, LastCalendarYear);
3413 if (error == ERR_EMPTY) (*LastCalendarPos)++;
3414
3415 start2 = false;
3416 }
3417 return error;
3418}
3419
3420static GSM_Error N6510_ReplyGetCalendarInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
3421{
3422 switch (msg.Buffer[3]) {
3423 case 0x3B:
3424 /* Old method 1 for accessing calendar */
3425 return N71_65_ReplyGetCalendarInfo1(msg, s, &s->Phone.Data.Priv.N6510.LastCalendar);
3426 case 0x9F:
3427 smprintf(s, "Info with calendar notes locations received method 3\n");
3428 return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastCalendar);
3429 }
3430 return ERR_UNKNOWNRESPONSE;
3431}
3432
3433/* method 3 */
3434GSM_Error N6510_ReplyGetCalendarNotePos3(GSM_Protocol_Message msg, GSM_StateMachine *s,int *FirstCalendarPos)
3435{
3436 smprintf(s, "First calendar location: %i\n",msg.Buffer[8]*256+msg.Buffer[9]);
3437 *FirstCalendarPos = msg.Buffer[8]*256+msg.Buffer[9];
3438 return ERR_NONE;
3439}
3440
3441/* method 3 */
3442static GSM_Error N6510_GetCalendarNotePos3(GSM_StateMachine *s)
3443{
3444 unsigned char req[] = {N6110_FRAME_HEADER, 0x95, 0x00};
3445
3446 smprintf(s, "Getting first free calendar note location\n");
3447 return GSM_WaitFor (s, req, 5, 0x13, 4, ID_GetCalendarNotePos);
3448}
3449
3450static GSM_Error N6510_ReplyGetCalendarNotePos(GSM_Protocol_Message msg, GSM_StateMachine *s)
3451{
3452 switch (msg.Buffer[3]) {
3453 case 0x32:
3454 /* Old method 1 for accessing calendar */
3455 return N71_65_ReplyGetCalendarNotePos1(msg, s,&s->Phone.Data.Priv.N6510.FirstCalendarPos);
3456 case 0x96:
3457 return N6510_ReplyGetCalendarNotePos3(msg, s,&s->Phone.Data.Priv.N6510.FirstCalendarPos);
3458 }
3459 return ERR_UNKNOWNRESPONSE;
3460}
3461
3462static GSM_Error N6510_FindCalendarIconID3(GSM_StateMachine *s, GSM_CalendarEntry *Entry, unsigned char *ID)
3463{
3464 int i,j,LastCalendarYear;
3465 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
3466 GSM_CalendarEntry Note;
3467 GSM_NOKIACalToDoLocationsLastCalendar1,LastCalendar2;
3468 GSM_Error error;
3469 bool found;
3470
3471 for(i=0;i<Priv->CalendarIconsNum;i++) {
3472 if (Priv->CalendarIconsTypes[i] == Entry->Type) {
3473 *ID = Priv->CalendarIcons[i];
3474 return ERR_NONE;
3475 }
3476 }
3477
3478 smprintf(s, "Starting finding note ID\n");
3479
3480 error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,true);
3481 memcpy(&LastCalendar1,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations));
3482 if (error != ERR_NONE) return error;
3483
3484 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL35) ||
3485 IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL65) ||
3486 IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) {
3487 error=N71_65_AddCalendar2(s,Entry);
3488 } else {
3489 if (Entry->Type == GSM_CAL_MEETING) {
3490 error=N71_65_AddCalendar1(s, Entry, &s->Phone.Data.Priv.N6510.FirstCalendarPos);
3491 } else {
3492 error=N71_65_AddCalendar2(s,Entry);
3493 }
3494 }
3495 if (error != ERR_NONE) return error;
3496
3497 error=N6510_GetCalendarInfo3(s, &Priv->LastCalendar,true);
3498 memcpy(&LastCalendar2,&Priv->LastCalendar,sizeof(GSM_NOKIACalToDoLocations));
3499 if (error != ERR_NONE) return error;
3500
3501 smprintf(s,"Number of entries: %i %i\n",LastCalendar1.Number,LastCalendar2.Number);
3502
3503 for(i=0;i<LastCalendar2.Number;i++) {
3504 found = true;
3505 for(j=0;j<LastCalendar1.Number;j++) {
3506 if (LastCalendar1.Location[j] == LastCalendar2.Location[i]) {
3507 found = false;
3508 break;
3509 }
3510 }
3511 if (found) {
3512 Note.Location = LastCalendar2.Location[i];
3513 error=N6510_PrivGetCalendar3(s, &Note, true, &LastCalendarYear);
3514 if (error != ERR_NONE) return error;
3515
3516 error=N71_65_DelCalendar(s, &Note);
3517 if (error != ERR_NONE) return error;
3518
3519 smprintf(s, "Ending finding note ID\n");
3520
3521 for(j=0;j<Priv->CalendarIconsNum;j++) {
3522 if (Priv->CalendarIconsTypes[j] == Entry->Type) {
3523 *ID = Priv->CalendarIcons[j];
3524 return ERR_NONE;
3525 }
3526 }
3527 return ERR_UNKNOWN;
3528 }
3529 }
3530
3531 return ERR_UNKNOWN;
3532}
3533
3534/* method 3 */
3535static GSM_Error N6510_ReplyAddCalendar3(GSM_Protocol_Message msg, GSM_StateMachine *s)
3536{
3537 smprintf(s, "Calendar note added\n");
3538 return ERR_NONE;
3539}
3540
3541/* method 3 */
3542GSM_Error N6510_AddCalendar3(GSM_StateMachine *s, GSM_CalendarEntry *Note, int *FirstCalendarPos)
3543{
3544 GSM_CalendarNoteTypeNoteType, OldNoteType;
3545 time_t t_time1,t_time2;
3546 long diff;
3547 GSM_Error error;
3548 GSM_DateTime DT,date_time;
3549 int Text, Time, Alarm, Phone, Recurrance, EndTime, Location, count=54;
3550 unsigned char req[5000] = {
3551 N6110_FRAME_HEADER, 0x65,
3552 0x00, /* 0 = calendar, 1 = todo */
3553 0x00, 0x00, 0x00,
3554 0x00, 0x00, /* location */
3555 0x00, 0x00, 0x00, 0x00,
3556 0xFF, 0xFF, 0xFF, 0xFF, /* alarm */
3557 0x80, 0x00, 0x00,
3558 0x01, /* note icon */
3559 0xFF, 0xFF, 0xFF, 0xFF, /* alarm type */
3560 0x00, /* 0x02 or 0x00 */
3561 0x01, /* note type */
3562 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* start date/time */
3563 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* end date/time */
3564 0x00, 0x00, /* recurrance */
3565 0x00, 0x00, /* birth year */
3566 0x20, /* ToDo priority */
3567 0x00, /* ToDo completed ? */
3568 0x00, 0x00, 0x00,
3569 0x00, /* note text length */
3570 0x00, /* phone length/meeting place*/
3571 0x00, 0x00, 0x00};
3572
3573 error=N6510_GetCalendarNotePos3(s);
3574 if (error!=ERR_NONE) return error;
3575 req[8] = *FirstCalendarPos/256;
3576 req[9] = *FirstCalendarPos%256;
3577
3578 NoteType = N71_65_FindCalendarType(Note->Type, s->Phone.Data.ModelInfo);
3579
3580 switch(NoteType) {
3581 case GSM_CAL_REMINDER : req[27]=0x00; req[26]=0x02; break;
3582 case GSM_CAL_MEETING : req[27]=0x01; break;
3583 case GSM_CAL_CALL : req[27]=0x02; break;
3584 case GSM_CAL_BIRTHDAY : req[27]=0x04; break;
3585 case GSM_CAL_MEMO : req[27]=0x08; break;
3586 default : return ERR_UNKNOWN;
3587 }
3588
3589 OldNoteType = Note->Type;
3590 Note->Type = NoteType;
3591 error=N6510_FindCalendarIconID3(s, Note, &req[21]);
3592 Note->Type = OldNoteType;
3593 if (error!=ERR_NONE) return error;
3594
3595 GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note, &Text, &Time, &Alarm, &Phone, &Recurrance, &EndTime, &Location);
3596
3597 if (Time == -1) return ERR_UNKNOWN;
3598 memcpy(&DT,&Note->Entries[Time].Date,sizeof(GSM_DateTime));
3599 req[28]= DT.Year / 256;
3600 req[29]= DT.Year % 256;
3601 req[30]= DT.Month;
3602 req[31]= DT.Day;
3603 req[32]= DT.Hour;
3604 req[33]= DT.Minute;
3605
3606 if (NoteType == GSM_CAL_BIRTHDAY) {
3607 error=s->Phone.Functions->GetDateTime(s,&date_time);
3608 switch (error) {
3609 case ERR_EMPTY:
3610 case ERR_NOTIMPLEMENTED:
3611 GSM_GetCurrentDateTime(&date_time);
3612 break;
3613 case ERR_NONE:
3614 break;
3615 default:
3616 return error;
3617 }
3618 req[28]= date_time.Year / 256;
3619 req[29] = date_time.Year % 256;
3620 if (DT.Year == 0) {
3621 req[42]= 0xff;
3622 req[43]= 0xff;
3623 } else {
3624 req[42]= DT.Year / 256;
3625 req[43]= DT.Year % 256;
3626 }
3627 }
3628
3629 if (EndTime != -1) memcpy(&DT,&Note->Entries[EndTime].Date,sizeof(GSM_DateTime));
3630 req[34]= DT.Year / 256;
3631 req[35]= DT.Year % 256;
3632 req[36]= DT.Month;
3633 req[37]= DT.Day;
3634 req[38]= DT.Hour;
3635 req[39]= DT.Minute;
3636 if (NoteType == GSM_CAL_BIRTHDAY) {
3637 req[34]= date_time.Year / 256;
3638 req[35] = date_time.Year % 256;
3639 }
3640
3641 if (Recurrance != -1) {
3642 /* max. 1 Year = 8760 hours */
3643 if (Note->Entries[Recurrance].Number >= 8760) {
3644 req[40] = 0xff;
3645 req[41] = 0xff;
3646 } else {
3647 req[40] = Note->Entries[Recurrance].Number / 256;
3648 req[41] = Note->Entries[Recurrance].Number % 256;
3649 }
3650 }
3651
3652 if (Alarm != -1) {
3653 memcpy(&DT,&Note->Entries[Time].Date,sizeof(GSM_DateTime));
3654 if (Note->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME) {
3655 req[22] = 0x00; req[23] = 0x00; req[24] = 0x00; req[25] = 0x00;
3656 }
3657 if (NoteType == GSM_CAL_BIRTHDAY) DT.Year = date_time.Year;
3658 t_time2 = Fill_Time_T(DT,8);
3659 t_time1 = Fill_Time_T(Note->Entries[Alarm].Date,8);
3660 diff = (t_time1-t_time2)/60;
3661
3662 smprintf(s, " Difference : %li seconds or minutes\n", -diff);
3663 req[14] = (unsigned char)(-diff >> 24);
3664 req[15] = (unsigned char)(-diff >> 16);
3665 req[16] = (unsigned char)(-diff >> 8);
3666 req[17] = (unsigned char)(-diff);
3667 }
3668
3669 if (Text != -1) {
3670 req[49] = UnicodeLength(Note->Entries[Text].Text);
3671 CopyUnicodeString(req+54,Note->Entries[Text].Text);
3672 count+= req[49]*2;
3673 }
3674
3675 if (Phone != -1 && NoteType == GSM_CAL_CALL) {
3676 req[50] = UnicodeLength(Note->Entries[Phone].Text);
3677 CopyUnicodeString(req+54+req[49]*2,Note->Entries[Phone].Text);
3678 count+= req[50]*2;
3679 }
3680
3681 if (Location != -1 && NoteType == GSM_CAL_MEETING) {
3682 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62) ||
3683 IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL65) ||
3684 IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL35)) {
3685 } else {
3686 req[50] = UnicodeLength(Note->Entries[Location].Text);
3687 CopyUnicodeString(req+54+req[49]*2,Note->Entries[Location].Text);
3688 count+= req[50]*2;
3689 }
3690 }
3691
3692 req[count++] = 0x00;
3693
3694 smprintf(s, "Writing calendar note method 3\n");
3695 return GSM_WaitFor (s, req, count, 0x13, 4, ID_SetCalendarNote);
3696}
3697
3698static GSM_Error N6510_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start)
3699{
3700#ifdef GSM_FORCE_DCT4_CALENDAR_6210
3701 /* Method 1. Some features missed. Not working with some notes in 3510 */
3702 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);
3703#endif
3704
3705 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) {
3706 /* Method 1. Some features missed. Not working with some notes in 3510 */
3707 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);
3708
3709 /* Method 2. In known phones texts of notes cut to 50 chars. Some features missed */
3710 // return N71_65_GetNextCalendar2(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos);
3711 } else {
3712 /* Method 3. All DCT4 features supported. Not supported by 8910 */
3713 return N6510_GetNextCalendar3(s,Note,start,&s->Phone.Data.Priv.N6510.LastCalendar,&s->Phone.Data.Priv.N6510.LastCalendarYear,&s->Phone.Data.Priv.N6510.LastCalendarPos);
3714 }
3715}
3716
3717static GSM_Error N6510_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status)
3718{
3719 GSM_Error error;
3720
3721#ifdef GSM_FORCE_DCT4_CALENDAR_6210
3722 /* Method 1 */
3723 error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N6510.LastCalendar);
3724 if (error!=ERR_NONE) return error;
3725 Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number;
3726 return ERR_NONE;
3727#endif
3728
3729 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) {
3730 /* Method 1 */
3731 error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N6510.LastCalendar);
3732 if (error!=ERR_NONE) return error;
3733 Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number;
3734 return ERR_NONE;
3735
3736 /* Method 2 */
3737 // return ERR_NOTSUPPORTED;
3738 } else {
3739 /* Method 3 */
3740 error=N6510_GetCalendarInfo3(s,&s->Phone.Data.Priv.N6510.LastCalendar,true);
3741 if (error!=ERR_NONE) return error;
3742 Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number;
3743 return ERR_NONE;
3744 }
3745}
3746
3747static GSM_Error N6510_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
3748{
3749#ifdef GSM_FORCE_DCT4_CALENDAR_6210
3750 return N71_65_AddCalendar2(s,Note);
3751#endif
3752
3753 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CAL62)) {
3754 return N71_65_AddCalendar2(s,Note);
3755 // return N71_65_AddCalendar1(s, Note, &s->Phone.Data.Priv.N6510.FirstCalendarPos);
3756 } else {
3757 /* Method 3. All DCT4 features supported. Not supported by 8910 */
3758 return N6510_AddCalendar3(s, Note, &s->Phone.Data.Priv.N6510.FirstCalendarPos);
3759 }
3760}
3761
3762static GSM_Error N6510_ReplyLogIntoNetwork(GSM_Protocol_Message msg, GSM_StateMachine *s)
3763{
3764 smprintf(s, "Probably phone says: I log into network\n");
3765 return ERR_NONE;
3766}
3767
3768void N6510_EncodeFMFrequency(double freq, unsigned char *buff)
3769{
3770 double freq0;
3771 unsigned char buffer[20];
3772 unsigned int i,freq2;
3773
3774 sprintf(buffer,"%.3f",freq);
3775 for (i=0;i<strlen(buffer);i++) {
3776 if (buffer[i] == ',' || buffer[i] == '.') buffer[i] = ' ';
3777 }
3778 StringToDouble(buffer, &freq0);
3779 freq2 = (unsigned int)freq0;
3780 dbgprintf("Frequency: %s %i\n",buffer,freq2);
3781 freq2= freq2 - 0xffff;
3782 buff[0] = freq2 / 0x100;
3783 buff[1] = freq2 % 0x100;
3784}
3785
3786void N6510_DecodeFMFrequency(double *freq, unsigned char *buff)
3787{
3788 unsigned char buffer[20];
3789
3790 sprintf(buffer,"%i.%i",(0xffff + buff[0] * 0x100 + buff[1])/1000,
3791 (0xffff + buff[0] * 0x100 + buff[1])%1000);
3792 dbgprintf("Frequency: %s\n",buffer);
3793 StringToDouble(buffer, freq);
3794}
3795
3796static GSM_Error N6510_ReplyGetFMStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
3797{
3798 smprintf(s, "getting FM status OK\n");
3799 memcpy(s->Phone.Data.Priv.N6510.FMStatus,msg.Buffer,msg.Length);
3800 s->Phone.Data.Priv.N6510.FMStatusLength = msg.Length;
3801 return ERR_NONE;
3802}
3803
3804static GSM_Error N6510_GetFMStatus(GSM_StateMachine *s)
3805{
3806 unsigned char req[7] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x01};
3807
3808 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3809 return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_GetFMStation);
3810}
3811
3812static GSM_Error N6510_ReplyGetFMStation(GSM_Protocol_Message msg, GSM_StateMachine *s)
3813{
3814 unsigned char name[GSM_MAX_FMSTATION_LENGTH*2+2];
3815 int length;
3816 GSM_Phone_Data*Data = &s->Phone.Data;
3817
3818 switch (msg.Buffer[3]) {
3819 case 0x06:
3820 smprintf(s, "Received FM station\n");
3821 length = msg.Buffer[8];
3822 memcpy(name,msg.Buffer+18,length*2);
3823 name[length*2] = 0x00;
3824 name[length*2+1] = 0x00;
3825 CopyUnicodeString(Data->FMStation->StationName,name);
3826 smprintf(s,"Station name: \"%s\"\n",DecodeUnicodeString(Data->FMStation->StationName));
3827 N6510_DecodeFMFrequency(&Data->FMStation->Frequency, msg.Buffer+16);
3828 return ERR_NONE;
3829 case 0x16:
3830 smprintf(s, "Received FM station. Empty ?\n");
3831 return ERR_EMPTY;
3832 }
3833 return ERR_UNKNOWNRESPONSE;
3834}
3835
3836static GSM_Error N6510_GetFMStation (GSM_StateMachine *s, GSM_FMStation *FMStation)
3837{
3838 GSM_Error error;
3839 int location;
3840 unsigned char req[7] = {N6110_FRAME_HEADER, 0x05,
3841 0x00, // location
3842 0x00,0x01};
3843
3844 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3845 if (FMStation->Location > GSM_MAX_FM_STATION) return ERR_INVALIDLOCATION;
3846
3847 s->Phone.Data.FMStation = FMStation;
3848
3849 error = N6510_GetFMStatus(s);
3850 if (error != ERR_NONE) return error;
3851
3852 location = FMStation->Location-1;
3853 if (s->Phone.Data.Priv.N6510.FMStatus[14+location] == 0xFF) return ERR_EMPTY;
3854 req[4] = s->Phone.Data.Priv.N6510.FMStatus[14+location];
3855
3856 smprintf(s, "Getting FM Station %i\n",FMStation->Location);
3857 return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_GetFMStation);
3858}
3859
3860static GSM_Error N6510_ReplySetFMStation(GSM_Protocol_Message msg, GSM_StateMachine *s)
3861{
3862#ifdef DEBUG
3863 switch (msg.Buffer[4]){
3864 case 0x03: smprintf(s, "FM stations cleaned\n"); break;
3865 case 0x11: smprintf(s, "Setting FM station status OK\n"); break;
3866 case 0x12: smprintf(s, "Setting FM station OK\n"); break;
3867 }
3868#endif
3869 return ERR_NONE;
3870}
3871
3872static GSM_Error N6510_ClearFMStations (GSM_StateMachine *s)
3873{
3874 unsigned char req[7] = {N6110_FRAME_HEADER, 0x03,0x0f,0x00,0x01};
3875
3876 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3877
3878 smprintf(s, "Cleaning FM Stations\n");
3879 return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_SetFMStation);
3880}
3881
3882static GSM_Error N6510_SetFMStation (GSM_StateMachine *s, GSM_FMStation *FMStation)
3883{
3884 unsigned int len, location;
3885 GSM_Error error;
3886 unsigned char setstatus[36] = {N6110_FRAME_HEADER,0x11,0x00,0x01,0x01,
3887 0x00,0x00,0x1c,0x00,0x14,0x00,0x00,
3888 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3889 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3890 0xff,0xff,0xff,0xff,0xff,0x01};
3891 unsigned char req[64] = {N6110_FRAME_HEADER, 0x12,0x00,0x01,0x00,
3892 0x00, // 0x0e + (strlen(name) * 2)
3893 0x00, // strlen(name)
3894 0x14,0x09,0x00,
3895 0x00, // location
3896 0x00,0x00,0x01,
3897 0x00, // freqHi
3898 0x00, // freqLo
3899 0x01};
3900
3901 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3902
3903 s->Phone.Data.FMStation = FMStation;
3904 location = FMStation->Location-1;
3905
3906 error = N6510_GetFMStatus(s);
3907 if (error != ERR_NONE) return error;
3908
3909 memcpy(setstatus+14,s->Phone.Data.Priv.N6510.FMStatus+14,20);
3910 setstatus [14+location] = location;
3911
3912 smprintf(s, "Setting FM status %i\n",FMStation->Location);
3913 error = GSM_WaitFor (s, setstatus, 36 , 0x3E, 2, ID_SetFMStation);
3914 if (error != ERR_NONE) return error;
3915
3916 req[12] = location;
3917
3918 /* Name */
3919 len = UnicodeLength(FMStation->StationName);
3920 req[8] = len;
3921 req[7] = 0x0e + len * 2;
3922 memcpy (req+18,FMStation->StationName,len*2);
3923
3924 /* Frequency */
3925 N6510_EncodeFMFrequency(FMStation->Frequency, req+16);
3926
3927 smprintf(s, "Setting FM Station %i\n",FMStation->Location);
3928 return GSM_WaitFor (s, req, 0x13+len*2, 0x3E, 2, ID_SetFMStation);
3929}
3930
3931static GSM_Error N6510_ReplySetLight(GSM_Protocol_Message msg, GSM_StateMachine *s)
3932{
3933 smprintf(s, "Light set\n");
3934 return ERR_NONE;
3935}
3936
3937GSM_Error N6510_SetLight(GSM_StateMachine *s, N6510_PHONE_LIGHTS light, bool enable)
3938{
3939 unsigned char req[14] = {
3940 N6110_FRAME_HEADER, 0x05,
3941 0x01, /* 0x01 = Display, 0x03 = keypad */
3942 0x01, /* 0x01 = Enable, 0x02 = disable */
3943 0x00, 0x00, 0x00, 0x01,
3944 0x05, 0x04, 0x02, 0x00};
3945
3946 req[4] = light;
3947 if (!enable) req[5] = 0x02;
3948 smprintf(s, "Setting light\n");
3949 return GSM_WaitFor (s, req, 14, 0x3A, 4, ID_SetLight);
3950}
3951
3952static GSM_Error N6510_ShowStartInfo(GSM_StateMachine *s, bool enable)
3953{
3954 GSM_Error error;
3955
3956 if (enable) {
3957 error=N6510_SetLight(s,N6510_LIGHT_DISPLAY,true);
3958 if (error != ERR_NONE) return error;
3959
3960 error=N6510_SetLight(s,N6510_LIGHT_TORCH,true);
3961 if (error != ERR_NONE) return error;
3962
3963 return N6510_SetLight(s,N6510_LIGHT_KEYPAD,true);
3964 } else {
3965 error=N6510_SetLight(s,N6510_LIGHT_DISPLAY,false);
3966 if (error != ERR_NONE) return error;
3967
3968 error=N6510_SetLight(s,N6510_LIGHT_TORCH,false);
3969 if (error != ERR_NONE) return error;
3970
3971 return N6510_SetLight(s,N6510_LIGHT_KEYPAD,false);
3972 }
3973}
3974
3975static int N6510_FindFileCheckSum(unsigned char *ptr, int len)
3976{
3977 int acc, i, accx;
3978
3979 accx = 0;
3980 acc = 0xffff;
3981 while (len--) {
3982 accx = (accx & 0xffff00ff) | (acc & 0xff00);
3983 acc = (acc & 0xffff00ff) | *ptr++ << 8;
3984 for (i = 0; i < 8; i++) {
3985 acc <<= 1;
3986 if (acc & 0x10000) acc ^= 0x1021;
3987 if (accx & 0x80000000) acc ^= 0x1021;
3988 accx <<= 1;
3989 }
3990 }
3991 dbgprintf("Checksum from Gammu is %04X\n",(acc & 0xffff));
3992 return (acc & 0xffff);
3993}
3994
3995static GSM_Error N6510_ReplyGetFileFolderInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
3996{
3997 GSM_File *File = s->Phone.Data.FileInfo;
3998 GSM_Phone_N6510Data*Priv = &s->Phone.Data.Priv.N6510;
3999 int i;
4000
4001 switch (msg.Buffer[3]) {
4002 case 0x15:
4003 smprintf(s,"File or folder details received\n");
4004 CopyUnicodeString(File->Name,msg.Buffer+10);
4005 if (!strncmp(DecodeUnicodeString(File->Name),"GMSTemp",7)) return ERR_EMPTY;
4006 if (File->Name[0] == 0x00 && File->Name[1] == 0x00) return ERR_UNKNOWN;
4007
4008 i = msg.Buffer[8]*256+msg.Buffer[9];
4009 dbgprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
4010 msg.Buffer[i-5],msg.Buffer[i-4],msg.Buffer[i-3],
4011 msg.Buffer[i-2],msg.Buffer[i-1],msg.Buffer[i],
4012 msg.Buffer[i+1],msg.Buffer[i+2],msg.Buffer[i+3]);
4013
4014 File->Folder = false;
4015 if (msg.Buffer[i-5] == 0x00) File->Folder = true;
4016
4017 File->ReadOnly = false;
4018 File->Protected = false;
4019 File->System= false;
4020 File->Hidden= false;
4021 if (msg.Buffer[i+2] == 0x01) File->Protected = true;
4022 if (msg.Buffer[i+4] == 0x01) File->ReadOnly = true;
4023 if (msg.Buffer[i+5] == 0x01) File->Hidden= true;
4024 if (msg.Buffer[i+6] == 0x01) File->System= true;//fixme
4025
4026 File->ModifiedEmpty = false;
4027 NOKIA_DecodeDateTime(s, msg.Buffer+i-22, &File->Modified);
4028 if (File->Modified.Year == 0x00) File->ModifiedEmpty = true;
4029 dbgprintf("%02x %02x %02x %02x\n",msg.Buffer[i-22],msg.Buffer[i-21],msg.Buffer[i-20],msg.Buffer[i-19]);
4030
4031 Priv->FileToken = msg.Buffer[i-10]*256+msg.Buffer[i-9];
4032 Priv->ParentID = msg.Buffer[i]*256+msg.Buffer[i+1];
4033 smprintf(s,"ParentID is %i\n",Priv->ParentID);
4034
4035 File->Type = GSM_File_Other;
4036 if (msg.Length > 240){
4037 i = 227;
4038 if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x01)
4039 File->Type = GSM_File_Image_JPG;
4040 else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x02)
4041 File->Type = GSM_File_Image_BMP;
4042 else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x07)
4043 File->Type = GSM_File_Image_BMP;
4044 else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x03)
4045 File->Type = GSM_File_Image_PNG;
4046 else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x05)
4047 File->Type = GSM_File_Image_GIF;
4048 else if (msg.Buffer[i]==0x02 && msg.Buffer[i+2]==0x09)
4049 File->Type = GSM_File_Image_WBMP;
4050 else if (msg.Buffer[i]==0x04 && msg.Buffer[i+2]==0x01)
4051 File->Type = GSM_File_Sound_AMR;
4052 else if (msg.Buffer[i]==0x04 && msg.Buffer[i+2]==0x02)
4053 File->Type = GSM_File_Sound_MIDI;
4054 else if (msg.Buffer[i]==0x08 && msg.Buffer[i+2]==0x05)
4055 File->Type = GSM_File_Video_3GP;
4056 else if (msg.Buffer[i]==0x10 && msg.Buffer[i+2]==0x01)
4057 File->Type = GSM_File_Java_JAR;
4058#if DEVELOP
4059 else if (msg.Buffer[i]==0x00 && msg.Buffer[i+2]==0x01)
4060 File->Type = GSM_File_MMS;
4061#endif
4062 }
4063 return ERR_NONE;
4064 case 0x2F:
4065 smprintf(s,"File or folder used bytes received\n");
4066 File->Used = msg.Buffer[6]*256*256*256+
4067 msg.Buffer[7]*256*256+
4068 msg.Buffer[8]*256+
4069 msg.Buffer[9];
4070 return ERR_NONE;
4071 case 0x33:
4072 if (s->Phone.Data.RequestID == ID_GetFileInfo) {
4073 i = Priv->FilesLocationsUsed-1;
4074 while (1) {
4075 if (i==Priv->FilesLocationsCurrent-1) break;
4076 dbgprintf("Copying %i to %i, max %i, current %i\n",
4077 i,i+msg.Buffer[9],
4078 Priv->FilesLocationsUsed,Priv->FilesLocationsCurrent);
4079 Priv->FilesLocations[i+msg.Buffer[9]] = Priv->FilesLocations[i];
4080 Priv->FilesLevels[i+msg.Buffer[9]]= Priv->FilesLevels[i];
4081 i--;
4082 }
4083 Priv->FilesLocationsUsed += msg.Buffer[9];
4084 for (i=0;i<msg.Buffer[9];i++) {
4085 Priv->FilesLocations[Priv->FilesLocationsCurrent+i] = msg.Buffer[13+i*4-1]*256 + msg.Buffer[13+i*4];
4086 Priv->FilesLevels[Priv->FilesLocationsCurrent+i] = File->Level+1;
4087 dbgprintf("%i ",Priv->FilesLocations[Priv->FilesLocationsCurrent+i]);
4088 }
4089 dbgprintf("\n");
4090 }
4091 if (msg.Buffer[9] != 0x00) File->Folder = true;
4092 return ERR_NONE;
4093 case 0x43:
4094 Priv->FileCheckSum = msg.Buffer[6] * 256 + msg.Buffer[7];
4095 smprintf(s,"File checksum from phone is %04X\n",Priv->FileCheckSum);
4096 return ERR_NONE;
4097 }
4098 return ERR_UNKNOWNRESPONSE;
4099}
4100
4101static GSM_Error N6510_GetFileFolderInfo(GSM_StateMachine *s, GSM_File *File, GSM_Phone_RequestID Request)
4102{
4103 GSM_Error error;
4104 unsigned char req[10] = {
4105 N7110_FRAME_HEADER,
4106 0x14, /* 0x14 - info, 0x22 - free/total, 0x2E - used, 0x32 - sublocations */
4107 0x01, /* 0x00 for sublocations reverse sorting, 0x01 for free */
4108 0x00, 0x00, 0x01,
4109 0x00, 0x01};/* Folder or file number */
4110 unsigned char GetCRC[] = {
4111 N7110_FRAME_HEADER, 0x42, 0x00, 0x00, 0x00, 0x01,
4112 0x00, 0x1E}; /* file ID */
4113
4114 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
4115
4116 s->Phone.Data.FileInfo = File;
4117 req[8] = atoi(File->ID_FullName) / 256;
4118 req[9] = atoi(File->ID_FullName) % 256;
4119
4120 req[3] = 0x14;
4121 req[4] = 0x01;
4122 smprintf(s,"Getting info for file in filesystem\n");
4123 error=GSM_WaitFor (s, req, 10, 0x6D, 4, Request);
4124 if (error != ERR_NONE) return error;
4125
4126 if (Request != ID_AddFile) {
4127 req[3] = 0x32;
4128 req[4] = 0x00;
4129 smprintf(s,"Getting subfolders for filesystem\n");
4130 error=GSM_WaitFor (s, req, 10, 0x6D, 4, Request);
4131 if (error != ERR_NONE) return error;
4132
4133 if (!File->Folder) {
4134 req[3] = 0x2E;
4135 req[4] = 0x01;
4136 smprintf(s,"Getting used memory for file in filesystem\n");
4137 error=GSM_WaitFor (s, req, 10, 0x6D, 4, Request);
4138 if (error != ERR_NONE) return error;
4139
4140 GetCRC[8] = atoi(File->ID_FullName) / 256;
4141 GetCRC[9] = atoi(File->ID_FullName) % 256;
4142 smprintf(s,"Getting CRC for file in filesystem\n");
4143 error=GSM_WaitFor (s, GetCRC, 10, 0x6D, 4, Request);
4144 }
4145 }
4146 return error;
4147}
4148
4149static GSM_Error N6510_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, bool start)
4150{
4151 GSM_Phone_N6510Data*Priv = &s->Phone.Data.Priv.N6510;
4152 GSM_Error error;
4153
4154 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
4155
4156 if (start) {
4157 Priv->FilesLocationsUsed = 1;
4158 Priv->FilesLocationsCurrent = 0;
4159 Priv->FilesLocations[0] = 0x01;
4160 Priv->FilesLevels[0] = 1;
4161 }
4162
4163 while (1) {
4164 if (Priv->FilesLocationsCurrent == Priv->FilesLocationsUsed) return ERR_EMPTY;
4165
4166 sprintf(File->ID_FullName,"%i",Priv->FilesLocations[Priv->FilesLocationsCurrent]);
4167 File->Level= Priv->FilesLevels[Priv->FilesLocationsCurrent];
4168 Priv->FilesLocationsCurrent++;
4169
4170 error = N6510_GetFileFolderInfo(s, File, ID_GetFileInfo);
4171 if (error == ERR_EMPTY) continue;
4172 return error;
4173 }
4174}
4175
4176static GSM_Error N6510_ReplyGetFileSystemStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
4177{
4178 switch (msg.Buffer[3]) {
4179 case 0x23:
4180 if (!strcmp(s->Phone.Data.ModelInfo->model,"6310i")) {
4181 smprintf(s,"File or folder total bytes received\n");
4182 s->Phone.Data.FileSystemStatus->Free =
4183 3*256*256 + msg.Buffer[8]*256 + msg.Buffer[9] -
4184 s->Phone.Data.FileSystemStatus->Used;
4185 } else {
4186 smprintf(s,"File or folder free bytes received\n");
4187 s->Phone.Data.FileSystemStatus->Free =
4188 msg.Buffer[6]*256*256*256+
4189 msg.Buffer[7]*256*256+
4190 msg.Buffer[8]*256+
4191 msg.Buffer[9];
4192 }
4193 return ERR_NONE;
4194 case 0x2F:
4195 smprintf(s,"File or folder used bytes received\n");
4196 s->Phone.Data.FileSystemStatus->Used =
4197 msg.Buffer[6]*256*256*256+
4198 msg.Buffer[7]*256*256+
4199 msg.Buffer[8]*256+
4200 msg.Buffer[9];
4201 return ERR_NONE;
4202 }
4203 return ERR_UNKNOWNRESPONSE;
4204}
4205
4206static GSM_Error N6510_GetFileSystemStatus(GSM_StateMachine *s, GSM_FileSystemStatus *status)
4207{
4208 GSM_Error error;
4209 unsigned char req[10] = {
4210 N7110_FRAME_HEADER,
4211 0x22, /* 0x14 - info, 0x22 - free/total, 0x2E - used, 0x32 - sublocations */
4212 0x01, /* 0x00 for sublocations reverse sorting, 0x01 for free */
4213 0x00, 0x00, 0x01,
4214 0x00, 0x01};/* Folder or file number */
4215
4216 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
4217
4218 s->Phone.Data.FileSystemStatus = status;
4219
4220 status->Free = 0;
4221
4222 req[3] = 0x2E;
4223 req[4] = 0x01;
4224 smprintf(s, "Getting used/total memory in filesystem\n");
4225 error = GSM_WaitFor (s, req, 10, 0x6D, 4, ID_FileSystemStatus);
4226
4227 req[3] = 0x22;
4228 req[4] = 0x01;
4229 smprintf(s, "Getting free memory in filesystem\n");
4230 return GSM_WaitFor (s, req, 10, 0x6D, 4, ID_FileSystemStatus);
4231}
4232
4233static GSM_Error N6510_SearchForFileName(GSM_StateMachine *s, GSM_File *File)
4234{
4235 GSM_File File2;
4236 GSM_Error error;
4237 int FilesLocations[1000],FilesLocations2[1000];
4238 int FilesLevels[1000];
4239 int FilesLocationsUsed, FilesLocationsCurrent;
4240 int FilesLocationsUsed2, FilesLocationsCurrent2;
4241 GSM_Phone_N6510Data*Priv = &s->Phone.Data.Priv.N6510;
4242
4243 memcpy(FilesLocations, Priv->FilesLocations,sizeof(FilesLocations));
4244 memcpy(FilesLevels, Priv->FilesLevels,sizeof(FilesLevels));
4245 FilesLocationsUsed = Priv->FilesLocationsUsed;
4246 FilesLocationsCurrent = Priv->FilesLocationsCurrent;
4247
4248 Priv->FilesLocationsUsed = 1;
4249 Priv->FilesLocationsCurrent = 1;
4250 Priv->FilesLocations[0] = atoi(File->ID_FullName);
4251 Priv->FilesLevels[0] = 1;
4252
4253 strcpy(File2.ID_FullName,File->ID_FullName);
4254 error = N6510_GetFileFolderInfo(s, &File2, ID_GetFileInfo);
4255 memcpy(FilesLocations2, Priv->FilesLocations,sizeof(FilesLocations2));
4256 FilesLocationsUsed2 = Priv->FilesLocationsUsed;
4257 FilesLocationsCurrent2 = Priv->FilesLocationsCurrent;
4258
4259 memcpy(Priv->FilesLocations, FilesLocations, sizeof(FilesLocations));
4260 memcpy(Priv->FilesLevels, FilesLevels, sizeof(FilesLevels));
4261 Priv->FilesLocationsUsed = FilesLocationsUsed;
4262 Priv->FilesLocationsCurrent = FilesLocationsCurrent;
4263 if (error != ERR_NONE) return error;
4264
4265 while (1) {
4266 if (FilesLocationsCurrent2 == FilesLocationsUsed2) return ERR_EMPTY;
4267
4268 sprintf(File2.ID_FullName,"%i",FilesLocations2[FilesLocationsCurrent2]);
4269 dbgprintf("Current is %i\n",FilesLocations2[FilesLocationsCurrent2]);
4270 FilesLocationsCurrent2++;
4271
4272 error = N6510_GetFileFolderInfo(s, &File2, ID_AddFile);
4273 if (error == ERR_EMPTY) continue;
4274 if (error != ERR_NONE) return error;
4275 dbgprintf("%s %s\n",DecodeUnicodeString(File->Name),DecodeUnicodeString(File2.Name));
4276 if (mywstrncasecmp(File2.Name,File->Name,0)) return ERR_NONE;
4277 }
4278 return ERR_EMPTY;
4279}
4280
4281static GSM_Error N6510_ReplyGetFilePart(GSM_Protocol_Message msg, GSM_StateMachine *s)
4282{
4283 int old;
4284
4285 smprintf(s,"File part received\n");
4286 old = s->Phone.Data.File->Used;
4287 s->Phone.Data.File->Used += msg.Buffer[6]*256*256*256+
4288 msg.Buffer[7]*256*256+
4289 msg.Buffer[8]*256+
4290 msg.Buffer[9];
4291 smprintf(s,"Length of file part: %i\n",
4292 msg.Buffer[6]*256*256*256+
4293 msg.Buffer[7]*256*256+
4294 msg.Buffer[8]*256+
4295 msg.Buffer[9]);
4296 s->Phone.Data.File->Buffer = (unsigned char *)realloc(s->Phone.Data.File->Buffer,s->Phone.Data.File->Used);
4297 memcpy(s->Phone.Data.File->Buffer+old,msg.Buffer+10,s->Phone.Data.File->Used-old);
4298 return ERR_NONE;
4299}
4300
4301static GSM_Error N6510_GetFilePart(GSM_StateMachine *s, GSM_File *File)
4302{
4303 GSM_Phone_N6510Data*Priv = &s->Phone.Data.Priv.N6510;
4304 int old;
4305 GSM_Error error;
4306 unsigned char req[] = {
4307 N7110_FRAME_HEADER, 0x0E, 0x00, 0x00, 0x00, 0x01,
4308 0x00, 0x01, /* Folder or file number */
4309 0x00, 0x00, 0x00, 0x00,/* Start from xxx byte */
4310 0x00, 0x00,
4311 0x03, 0xE8}; /* Read xxx bytes */
4312
4313 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
4314
4315 if (File->Used == 0x00) {
4316 error = N6510_GetFileFolderInfo(s, File, ID_GetFile);
4317 if (error != ERR_NONE) return error;
4318 File->Used = 0;
4319 }
4320
4321 old = File->Used;
4322 req[8] = atoi(File->ID_FullName) / 256;
4323 req[9] = atoi(File->ID_FullName) % 256;
4324 req[10] = old / (256*256*256);
4325 req[11] = old / (256*256);
4326 req[12] = old / 256;
4327 req[13] = old % 256;
4328
4329 s->Phone.Data.File = File;
4330 smprintf(s, "Getting file part from filesystem\n");
4331 error=GSM_WaitFor (s, req, 18, 0x6D, 4, ID_GetFile);
4332 if (error != ERR_NONE) return error;
4333 if (File->Used - old != (0x03 * 256 + 0xE8)) {
4334 if (N6510_FindFileCheckSum(File->Buffer, File->Used) != Priv->FileCheckSum) {
4335 smprintf(s,"File2 checksum is %i, File checksum is %i\n",N6510_FindFileCheckSum(File->Buffer, File->Used),Priv->FileCheckSum);
4336 return ERR_WRONGCRC;
4337 }
4338 return ERR_EMPTY;
4339 }
4340 return ERR_NONE;
4341}
4342
4343static GSM_Error N6510_SetReadOnly(GSM_StateMachine *s, unsigned char *ID, bool enable)
4344{
4345 unsigned char SetAttr[] = {
4346 N7110_FRAME_HEADER, 0x18, 0x00, 0x00, 0x00, 0x01,
4347 0x00, 0x20}; /* File ID */
4348
4349 if (!enable) SetAttr[4] = 0x06;
4350
4351 SetAttr[8] = atoi(ID) / 256;
4352 SetAttr[9] = atoi(ID) % 256;
4353 smprintf(s, "Setting readonly attribute\n");
4354 return GSM_WaitFor (s, SetAttr, 10, 0x6D, 4, ID_DeleteFile);
4355}
4356
4357static GSM_Error N6510_ReplyAddFileHeader(GSM_Protocol_Message msg, GSM_StateMachine *s)
4358{
4359 switch (msg.Buffer[3]) {
4360 case 0x03:
4361 smprintf(s,"File header added\n");
4362 sprintf(s->Phone.Data.File->ID_FullName,"%i",msg.Buffer[9]);
4363 return ERR_NONE;
4364 case 0x13:
4365 return ERR_NONE;
4366 }
4367 return ERR_UNKNOWNRESPONSE;
4368}
4369
4370static GSM_Error N6510_ReplyAddFilePart(GSM_Protocol_Message msg, GSM_StateMachine *s)
4371{
4372 return ERR_NONE;
4373}
4374
4375static GSM_Error N6510_AddFilePart(GSM_StateMachine *s, GSM_File *File, int *Pos)
4376{
4377 GSM_Phone_N6510Data*Priv = &s->Phone.Data.Priv.N6510;
4378 GSM_File File2;
4379 GSM_Error error;
4380 int j;
4381 unsigned char Header[400] = {
4382 N7110_FRAME_HEADER, 0x02, 0x00, 0x00, 0x00, 0x01,
4383 0x00, 0x0C, /* parent folder ID */
4384 0x00, 0x00, 0x00, 0xE8};
4385 unsigned char Add[15000] = {
4386 N7110_FRAME_HEADER, 0x40, 0x00, 0x00, 0x00, 0x01,
4387 0x00, 0x04, /* file ID */
4388 0x00, 0x00,
4389 0x01, 0x28}; /* length */
4390 unsigned char end[30] = {
4391 N7110_FRAME_HEADER, 0x40, 0x00, 0x00, 0x00, 0x01,
4392 0x00, 0x04, /* file ID */
4393 0x00, 0x00, 0x00, 0x00};
4394
4395 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
4396
4397 s->Phone.Data.File = File;
4398
4399 if (*Pos == 0) {
4400 error = N6510_SearchForFileName(s,File);
4401 if (error == ERR_NONE) return ERR_INVALIDLOCATION;
4402 if (error != ERR_EMPTY) return error;
4403
4404 Header[8] = atoi(File->ID_FullName) / 256;
4405 Header[9] = atoi(File->ID_FullName) % 256;
4406 memset(Header+14, 0x00, 300);
4407 CopyUnicodeString(Header+14,File->Name);
4408 Header[222] = File->Used / (256*256*256);
4409 Header[223] = File->Used / (256*256);
4410 Header[224] = File->Used / 256;
4411 Header[225] = File->Used % 256;
4412 switch(File->Type) {
4413 case GSM_File_Image_JPG : Header[231]=0x02; Header[233]=0x01; break;
4414 case GSM_File_Image_BMP : Header[231]=0x02; Header[233]=0x02; break;
4415 case GSM_File_Image_PNG : Header[231]=0x02; Header[233]=0x03; break;
4416 case GSM_File_Image_GIF : Header[231]=0x02; Header[233]=0x05; break;
4417 case GSM_File_Image_WBMP : Header[231]=0x02; Header[233]=0x09; break;
4418 case GSM_File_Sound_AMR : Header[231]=0x04; Header[233]=0x01; break;
4419 case GSM_File_Sound_MIDI : Header[231]=0x04; Header[233]=0x05; break; //Header[238]=0x01;
4420 case GSM_File_Sound_NRT : Header[231]=0x04; Header[233]=0x06; break;
4421 case GSM_File_Video_3GP : Header[231]=0x08; Header[233]=0x05; break;
4422 case GSM_File_Java_JAR : Header[231]=0x10; Header[233]=0x01; break;
4423#ifdef DEVELOP
4424 case GSM_File_MMS:
4425 Header[214]=0x07;
4426 Header[215]=0xd3;
4427 Header[216]=0x06;
4428 Header[217]=0x01;
4429 Header[218]=0x12;
4430 Header[219]=0x13;
4431 Header[220]=0x29;
4432 Header[233]=0x01;
4433 break;
4434#endif
4435 default : Header[231]=0x01; Header[233]=0x05;
4436 }
4437 Header[235] = 0x01;
4438 Header[236] = atoi(File->ID_FullName) / 256;
4439 Header[237] = atoi(File->ID_FullName) % 256;
4440 if (File->Protected) Header[238] = 0x01; //Nokia forward lock
4441 if (File->Hidden) Header[241] = 0x01;
4442 if (File->System) Header[242] = 0x01; //fixme
4443 smprintf(s, "Adding file header\n");
4444 error=GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFile);
4445 if (error != ERR_NONE) return error;
4446 }
4447
4448 j = 1000;
4449 if (File->Used - *Pos < 1000) j = File->Used - *Pos;
4450 Add[ 8] = atoi(File->ID_FullName) / 256;
4451 Add[ 9] = atoi(File->ID_FullName) % 256;
4452 Add[12] = j / 256;
4453 Add[13] = j % 256;
4454 memcpy(Add+14,File->Buffer+(*Pos),j);
4455 smprintf(s, "Adding file part %i %i\n",*Pos,j);
4456 error=GSM_WaitFor (s, Add, 14+j, 0x6D, 4, ID_AddFile);
4457 if (error != ERR_NONE) return error;
4458 *Pos = *Pos + j;
4459
4460 if (j < 1000) {
4461 end[8] = atoi(File->ID_FullName) / 256;
4462 end[9] = atoi(File->ID_FullName) % 256;
4463 smprintf(s, "Frame for ending adding file\n");
4464 error = GSM_WaitFor (s, end, 14, 0x6D, 4, ID_AddFile);
4465 if (error != ERR_NONE) return error;
4466
4467 strcpy(File2.ID_FullName,File->ID_FullName);
4468 error = N6510_GetFileFolderInfo(s, &File2, ID_GetFileInfo);
4469 if (error != ERR_NONE) return error;
4470
4471 if (!File->ModifiedEmpty) {
4472 Header[3] = 0x12;
4473 Header[4] = 0x01;
4474 Header[12] = 0x00;
4475 Header[13] = 0xE8;
4476 Header[8] = atoi(File->ID_FullName) / 256;
4477 Header[9] = atoi(File->ID_FullName) % 256;
4478 memset(Header+14, 0x00, 300);
4479 CopyUnicodeString(Header+14,File->Name);
4480 NOKIA_EncodeDateTime(s,Header+214,&File->Modified);
4481 /* When you save too big file for phone and it changes
4482 * size (some part is cut by firmware), you HAVE to write
4483 * here correct file size. In other case filesystem
4484 * will be damaged
4485 */
4486 Header[224] = File2.Used / 256;
4487 Header[225] = File2.Used % 256;
4488 Header[226] = Priv->FileToken / 256;
4489 Header[227] = Priv->FileToken % 256;
4490 switch(File->Type) {
4491 case GSM_File_Image_JPG : Header[231]=0x02; Header[233]=0x01; break;
4492 case GSM_File_Image_BMP : Header[231]=0x02; Header[233]=0x02; break;
4493 case GSM_File_Image_PNG : Header[231]=0x02; Header[233]=0x03; break;
4494 case GSM_File_Image_GIF : Header[231]=0x02; Header[233]=0x05; break;
4495 case GSM_File_Image_WBMP : Header[231]=0x02; Header[233]=0x09; break;
4496 case GSM_File_Sound_AMR : Header[231]=0x04; Header[233]=0x01; break;
4497 case GSM_File_Sound_MIDI : Header[231]=0x04; Header[233]=0x05; break; //Header[238]=0x01;
4498 case GSM_File_Sound_NRT : Header[231]=0x04; Header[233]=0x06; break;
4499 case GSM_File_Video_3GP : Header[231]=0x08; Header[233]=0x05; break;
4500 case GSM_File_Java_JAR : Header[231]=0x10; Header[233]=0x01; break;
4501#ifdef DEVELOP
4502 case GSM_File_MMS:
4503 Header[214]=0x07;
4504 Header[215]=0xd3;
4505 Header[216]=0x06;
4506 Header[217]=0x01;
4507 Header[218]=0x12;
4508 Header[219]=0x13;
4509 Header[220]=0x29;
4510 Header[233]=0x01;
4511 break;
4512#endif
4513 default : Header[231]=0x01; Header[233]=0x05;
4514 }
4515 Header[235] = 0x01;
4516 Header[236] = Priv->ParentID / 256;
4517 Header[237] = Priv->ParentID % 256;
4518 smprintf(s, "Adding file header\n");
4519 error=GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFile);
4520 if (error != ERR_NONE) return error;
4521 }
4522
4523 /* Can't delete from phone menu */
4524 if (File->ReadOnly) {
4525 error = N6510_SetReadOnly(s, File->ID_FullName, true);
4526 if (error != ERR_NONE) return error;
4527 }
4528
4529 if (N6510_FindFileCheckSum(File->Buffer, File->Used) != Priv->FileCheckSum) {
4530 smprintf(s,"File2 checksum is %i, File checksum is %i\n",N6510_FindFileCheckSum(File->Buffer, File->Used),Priv->FileCheckSum);
4531 return ERR_WRONGCRC;
4532 }
4533
4534 return ERR_EMPTY;
4535 }
4536
4537 return ERR_NONE;
4538}
4539
4540static GSM_Error N6510_ReplyDeleteFile(GSM_Protocol_Message msg, GSM_StateMachine *s)
4541{
4542 return ERR_NONE;
4543}
4544
4545static GSM_Error N6510_DeleteFile(GSM_StateMachine *s, unsigned char *ID)
4546{
4547 GSM_Errorerror;
4548 unsigned char Delete[40] = {
4549 N7110_FRAME_HEADER, 0x1E, 0x00, 0x00, 0x00, 0x01,
4550 0x00, 0x35}; /* File ID */
4551
4552 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
4553
4554 error = N6510_SetReadOnly(s, ID, false);
4555 if (error != ERR_NONE) return error;
4556
4557 Delete[8] = atoi(ID) / 256;
4558 Delete[9] = atoi(ID) % 256;
4559 return GSM_WaitFor (s, Delete, 10, 0x6D, 4, ID_DeleteFile);
4560}
4561
4562static GSM_Error N6510_ReplyAddFolder(GSM_Protocol_Message msg, GSM_StateMachine *s)
4563{
4564 sprintf(s->Phone.Data.File->ID_FullName,"%i",msg.Buffer[9]);
4565 return ERR_NONE;
4566}
4567
4568static GSM_Error N6510_AddFolder(GSM_StateMachine *s, GSM_File *File)
4569{
4570 GSM_Errorerror;
4571 unsigned char Header[400] = {
4572 N7110_FRAME_HEADER, 0x04, 0x00, 0x00, 0x00, 0x01,
4573 0x00, 0x0C, /* parent folder ID */
4574 0x00, 0x00, 0x00, 0xE8};
4575
4576 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
4577
4578 error = N6510_SearchForFileName(s,File);
4579 if (error == ERR_NONE) return ERR_INVALIDLOCATION;
4580 if (error != ERR_EMPTY) return error;
4581
4582 Header[8] = atoi(File->ID_FullName) / 256;
4583 Header[9] = atoi(File->ID_FullName) % 256;
4584 memset(Header+14, 0x00, 300);
4585 CopyUnicodeString(Header+14,File->Name);
4586 Header[233] = 0x02;
4587 Header[235] = 0x01;
4588 Header[236] = atoi(File->ID_FullName) / 256;
4589 Header[237] = atoi(File->ID_FullName) % 256;
4590
4591 s->Phone.Data.File = File;
4592 smprintf(s, "Adding folder\n");
4593 error = GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFolder);
4594 if (error != ERR_NONE) return error;
4595
4596 /* Can't delete from phone menu */
4597 if (File->ReadOnly) {
4598 error = N6510_SetReadOnly(s, File->ID_FullName, true);
4599 if (error != ERR_NONE) return error;
4600 }
4601
4602 return error;
4603}
4604
4605#ifdef DEVELOP
4606
4607static GSM_Error N6510_ReplyEnableGPRSAccessPoint(GSM_Protocol_Message msg, GSM_StateMachine *s)
4608{
4609 if (msg.Buffer[13] == 0x02) return ERR_NONE;
4610 return ERR_UNKNOWNRESPONSE;
4611}
4612
4613static GSM_Error N6510_EnableGPRSAccessPoint(GSM_StateMachine *s)
4614{
4615 GSM_Errorerror;
4616 int i;
4617 unsigned char req[] = {
4618 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4619 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00};
4620
4621 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return ERR_NOTSUPPORTED;
4622
4623 for (i=0;i<3;i++) {
4624 smprintf(s, "Activating full GPRS access point support\n");
4625 error = GSM_WaitFor (s, req, 16, 0x43, 4, ID_EnableGPRSPoint);
4626 if (error != ERR_NONE) return error;
4627 }
4628 return error;
4629}
4630
4631#endif
4632
4633static GSM_Error N6510_ReplyGetGPRSAccessPoint(GSM_Protocol_Message msg, GSM_StateMachine *s)
4634{
4635 GSM_GPRSAccessPoint *point = s->Phone.Data.GPRSPoint;
4636
4637 switch (msg.Buffer[13]) {
4638 case 0x01:
4639 smprintf(s,"Active GPRS point received\n");
4640 point->Active = false;
4641 if (point->Location == msg.Buffer[18]) point->Active = true;
4642 return ERR_NONE;
4643 case 0xD2:
4644 smprintf(s,"Names for GPRS points received\n");
4645 CopyUnicodeString(point->Name,msg.Buffer+18+(point->Location-1)*42);
4646 smprintf(s,"\"%s\"\n",DecodeUnicodeString(point->Name));
4647 return ERR_NONE;
4648 case 0xF2:
4649 smprintf(s,"URL for GPRS points received\n");
4650 CopyUnicodeString(point->URL,msg.Buffer+18+(point->Location-1)*202);
4651 smprintf(s,"\"%s\"\n",DecodeUnicodeString(point->URL));
4652 return ERR_NONE;
4653 }
4654 return ERR_UNKNOWNRESPONSE;
4655}
4656
4657static GSM_Error N6510_GetGPRSAccessPoint(GSM_StateMachine *s, GSM_GPRSAccessPoint *point)
4658{
4659 GSM_Errorerror;
4660 unsigned char URL[] = {
4661 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4662 0x00, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00};
4663 unsigned char Name[] = {
4664 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4665 0x01, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00};
4666 unsigned char Active[] = {
4667 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4668 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
4669
4670 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return ERR_NOTSUPPORTED;
4671 if (point->Location < 1) return ERR_UNKNOWN;
4672 if (point->Location > 5) return ERR_INVALIDLOCATION;
4673
4674 s->Phone.Data.GPRSPoint = point;
4675
4676#ifdef DEVELOP
4677 error = N6510_EnableGPRSAccessPoint(s);
4678 if (error != ERR_NONE) return error;
4679#endif
4680
4681 smprintf(s, "Getting GPRS access point name\n");
4682 error=GSM_WaitFor (s, Name, 16, 0x43, 4, ID_GetGPRSPoint);
4683 if (error != ERR_NONE) return error;
4684
4685 smprintf(s, "Getting GPRS access point URL\n");
4686 error=GSM_WaitFor (s, URL, 16, 0x43, 4, ID_GetGPRSPoint);
4687 if (error != ERR_NONE) return error;
4688
4689 smprintf(s, "Getting number of active GPRS access point\n");
4690 error=GSM_WaitFor (s, Active, 16, 0x43, 4, ID_GetGPRSPoint);
4691 if (error != ERR_NONE) return error;
4692
4693 if (UnicodeLength(point->URL)==0 && UnicodeLength(point->Name)==0) return ERR_EMPTY;
4694 return error;
4695}
4696
4697static GSM_Error N6510_ReplySetGPRSAccessPoint1(GSM_Protocol_Message msg, GSM_StateMachine *s)
4698{
4699 switch (msg.Buffer[13]) {
4700 case 0x01:
4701 case 0xD2:
4702 case 0xF2:
4703 memcpy(s->Phone.Data.Priv.N6510.GPRSPoints,msg.Buffer,msg.Length);
4704 s->Phone.Data.Priv.N6510.GPRSPointsLength = msg.Length;
4705 return ERR_NONE;
4706 }
4707 return ERR_UNKNOWNRESPONSE;
4708}
4709
4710static GSM_Error N6510_SetGPRSAccessPoint(GSM_StateMachine *s, GSM_GPRSAccessPoint *point)
4711{
4712 unsigned char*buff = s->Phone.Data.Priv.N6510.GPRSPoints;
4713 GSM_Errorerror;
4714 unsigned char URL[] = {
4715 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4716 0x00, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00};
4717 unsigned char Name[] = {
4718 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4719 0x01, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00};
4720 unsigned char Active[] = {
4721 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
4722 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
4723
4724 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return ERR_NOTSUPPORTED;
4725 if (point->Location < 1) return ERR_UNKNOWN;
4726 if (point->Location > 5) return ERR_INVALIDLOCATION;
4727
4728 s->Phone.Data.GPRSPoint = point;
4729
4730#ifdef DEVELOP
4731 error = N6510_EnableGPRSAccessPoint(s);
4732 if (error != ERR_NONE) return error;
4733#endif
4734
4735 smprintf(s, "Getting GPRS access point name\n");
4736 error=GSM_WaitFor (s, Name, 16, 0x43, 4, ID_SetGPRSPoint);
4737 if (error != ERR_NONE) return error;
4738 CopyUnicodeString(buff+18+(point->Location-1)*42,point->Name);
4739 buff[0] = 0x00;
4740 buff[1] = 0x01;
4741 buff[2] = 0x01;
4742 buff[3] = 0x07;
4743 smprintf(s, "Setting GPRS access point name\n");
4744 error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, 4, ID_SetGPRSPoint);
4745 if (error != ERR_NONE) return error;
4746
4747 smprintf(s, "Getting GPRS access point URL\n");
4748 error=GSM_WaitFor (s, URL, 16, 0x43, 4, ID_SetGPRSPoint);
4749 if (error != ERR_NONE) return error;
4750 CopyUnicodeString(buff+18+(point->Location-1)*42,point->URL);
4751 buff[0] = 0x00;
4752 buff[1] = 0x01;
4753 buff[2] = 0x01;
4754 buff[3] = 0x07;
4755 smprintf(s, "Setting GPRS access point URL\n");
4756 error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, 4, ID_SetGPRSPoint);
4757 if (error != ERR_NONE) return error;
4758
4759 if (point->Active) {
4760 smprintf(s, "Getting number of active GPRS access point\n");
4761 error=GSM_WaitFor (s, Active, 16, 0x43, 4, ID_SetGPRSPoint);
4762 if (error != ERR_NONE) return error;
4763 buff[0] = 0x00;
4764 buff[1] = 0x01;
4765 buff[2] = 0x01;
4766 buff[3] = 0x07;
4767 buff[18]= point->Location;
4768 smprintf(s, "Setting number of active GPRS access point\n");
4769 error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, 4, ID_SetGPRSPoint);
4770 if (error != ERR_NONE) return error;
4771 }
4772
4773 return error;
4774}
4775
4776/* ToDo support - 6310 style */
4777static GSM_Error N6510_ReplyGetToDoStatus1(GSM_Protocol_Message msg, GSM_StateMachine *s)
4778{
4779 int i;
4780 GSM_NOKIACalToDoLocations*Last = &s->Phone.Data.Priv.N6510.LastToDo;
4781
4782 smprintf(s, "TODO locations received\n");
4783 Last->Number=msg.Buffer[6]*256+msg.Buffer[7];
4784 smprintf(s, "Number of Entries: %i\n",Last->Number);
4785 smprintf(s, "Locations: ");
4786 for (i=0;i<Last->Number;i++) {
4787 Last->Location[i]=msg.Buffer[12+(i*4)]*256+msg.Buffer[(i*4)+13];
4788 smprintf(s, "%i ",Last->Location[i]);
4789 }
4790 smprintf(s, "\n");
4791 return ERR_NONE;
4792}
4793
4794/* ToDo support - 6310 style */
4795static GSM_Error N6510_GetToDoStatus1(GSM_StateMachine *s, GSM_ToDoStatus *status)
4796{
4797 GSM_Error error;
4798 GSM_NOKIACalToDoLocations*LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
4799 unsigned char reqLoc[] = {
4800 N6110_FRAME_HEADER,
4801 0x15, 0x01, 0x00, 0x00,
4802 0x00, 0x00, 0x00};
4803
4804 smprintf(s, "Getting ToDo locations\n");
4805 error = GSM_WaitFor (s, reqLoc, 10, 0x55, 4, ID_GetToDo);
4806 if (error != ERR_NONE) return error;
4807
4808 status->Used = LastToDo->Number;
4809 return ERR_NONE;
4810}
4811
4812static GSM_Error N6510_GetToDoStatus2(GSM_StateMachine *s, GSM_ToDoStatus *status)
4813{
4814 GSM_NOKIACalToDoLocations*LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
4815 GSM_Error error;
4816
4817 error = N6510_GetCalendarInfo3(s,LastToDo,false);
4818 if (error!=ERR_NONE) return error;
4819
4820 status->Used = LastToDo->Number;
4821 return ERR_NONE;
4822}
4823
4824static GSM_Error N6510_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status)
4825{
4826 status->Used = 0;
4827
4828 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) {
4829 return N6510_GetToDoStatus1(s, status);
4830 } else if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) {
4831 return N6510_GetToDoStatus2(s, status);
4832 } else {
4833 return ERR_NOTSUPPORTED;
4834 }
4835}
4836
4837/* ToDo support - 6310 style */
4838static GSM_Error N6510_ReplyGetToDo1(GSM_Protocol_Message msg, GSM_StateMachine *s)
4839{
4840 GSM_ToDoEntry *Last = s->Phone.Data.ToDo;
4841
4842 smprintf(s, "TODO received method 1\n");
4843
4844 switch (msg.Buffer[4]) {
4845 case 1 : Last->Priority = GSM_Priority_High; break;
4846 case 2 : Last->Priority = GSM_Priority_Medium; break;
4847 case 3 : Last->Priority = GSM_Priority_Low; break;
4848 default: return ERR_UNKNOWN;
4849 }
4850 smprintf(s, "Priority: %i\n",msg.Buffer[4]);
4851
4852 CopyUnicodeString(Last->Entries[0].Text,msg.Buffer+14);
4853 Last->Entries[0].EntryType = TODO_TEXT;
4854 Last->EntriesNum = 1;
4855 smprintf(s, "Text: \"%s\"\n",DecodeUnicodeString(Last->Entries[0].Text));
4856
4857 return ERR_NONE;
4858}
4859
4860/* ToDo support - 6310 style */
4861static GSM_Error N6510_GetNextToDo1(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh)
4862{
4863 GSM_Error error;
4864 GSM_ToDoStatus status;
4865 GSM_NOKIACalToDoLocations*LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
4866 unsigned char reqGet[] = {
4867 N6110_FRAME_HEADER,
4868 0x03, 0x00, 0x00, 0x80, 0x00,
4869 0x00, 0x17}; /* Location */
4870
4871 if (refresh) {
4872 error = N6510_GetToDoStatus(s, &status);
4873 if (error != ERR_NONE) return error;
4874 ToDo->Location = 1;
4875 } else {
4876 ToDo->Location++;
4877 }
4878 if (ToDo->Location > LastToDo->Number) return ERR_EMPTY;
4879
4880 reqGet[8] = LastToDo->Location[ToDo->Location-1] / 256;
4881 reqGet[9] = LastToDo->Location[ToDo->Location-1] % 256;
4882 s->Phone.Data.ToDo = ToDo;
4883 smprintf(s, "Getting ToDo\n");
4884 return GSM_WaitFor (s, reqGet, 10, 0x55, 4, ID_GetToDo);
4885}
4886
4887static GSM_Error N6510_ReplyGetToDoStatus2(GSM_Protocol_Message msg, GSM_StateMachine *s)
4888{
4889 return N6510_ReplyGetCalendarInfo3(msg, s, &s->Phone.Data.Priv.N6510.LastToDo);
4890}
4891
4892/* Similiar to getting calendar method 3 */
4893static GSM_Error N6510_ReplyGetToDo2(GSM_Protocol_Message msg, GSM_StateMachine *s)
4894{
4895 GSM_ToDoEntry *Last = s->Phone.Data.ToDo;
4896 GSM_DateTime Date;
4897 unsigned long diff;
4898
4899 smprintf(s, "ToDo received method 2\n");
4900
4901 switch (msg.Buffer[44]) {
4902 case 0x10: Last->Priority = GSM_Priority_Low; break;
4903 case 0x20: Last->Priority = GSM_Priority_Medium; break;
4904 case 0x30: Last->Priority = GSM_Priority_High; break;
4905 default : return ERR_UNKNOWN;
4906 }
4907
4908 memcpy(Last->Entries[0].Text,msg.Buffer+54,msg.Buffer[51]*2);
4909 Last->Entries[0].Text[msg.Buffer[51]*2] = 0;
4910 Last->Entries[0].Text[msg.Buffer[51]*2+1] = 0;
4911 Last->Entries[0].EntryType = TODO_TEXT;
4912 smprintf(s, "Text: \"%s\"\n",DecodeUnicodeString(Last->Entries[0].Text));
4913
4914 smprintf(s,"EndTime: %04i-%02i-%02i %02i:%02i\n",
4915 msg.Buffer[34]*256+msg.Buffer[35],
4916 msg.Buffer[36],msg.Buffer[37],msg.Buffer[38],
4917 msg.Buffer[39]);
4918 Date.Year = msg.Buffer[34]*256+msg.Buffer[35];
4919 Date.Month = msg.Buffer[36];
4920 Date.Day = msg.Buffer[37];
4921 Date.Hour = msg.Buffer[38];
4922 Date.Minute = msg.Buffer[39];
4923 Date.Second= 0;
4924 Last->Entries[1].EntryType = TODO_END_DATETIME;
4925 memcpy(&Last->Entries[1].Date,&Date,sizeof(GSM_DateTime));
4926
4927 smprintf(s,"StartTime: %04i-%02i-%02i %02i:%02i\n",
4928 msg.Buffer[28]*256+msg.Buffer[29],
4929 msg.Buffer[30],msg.Buffer[31],msg.Buffer[32],
4930 msg.Buffer[33]);
4931 Date.Year = msg.Buffer[28]*256+msg.Buffer[29];
4932 Date.Month = msg.Buffer[30];
4933 Date.Day = msg.Buffer[31];
4934 Date.Hour = msg.Buffer[32];
4935 Date.Minute = msg.Buffer[33];
4936 Date.Second= 0;
4937
4938 Last->EntriesNum = 2;
4939
4940 if (msg.Buffer[45] == 0x01) {
4941 Last->Entries[2].Number = msg.Buffer[45];
4942 Last->Entries[2].EntryType = TODO_COMPLETED;
4943 Last->EntriesNum++;
4944 smprintf(s,"Completed\n");
4945 }
4946
4947 if (msg.Buffer[14] == 0xFF && msg.Buffer[15] == 0xFF && msg.Buffer[16] == 0xff && msg.Buffer[17] == 0xff)
4948 {
4949 smprintf(s, "No alarm\n");
4950 } else {
4951 diff = ((unsigned int)msg.Buffer[14]) << 24;
4952 diff += ((unsigned int)msg.Buffer[15]) << 16;
4953 diff += ((unsigned int)msg.Buffer[16]) << 8;
4954 diff += msg.Buffer[17];
4955
4956 memcpy(&Last->Entries[Last->EntriesNum].Date,&Date,sizeof(GSM_DateTime));
4957 GetTimeDifference(diff, &Last->Entries[Last->EntriesNum].Date, false, 60);
4958 smprintf(s, "Alarm date : %02i-%02i-%04i %02i:%02i:%02i\n",
4959 Last->Entries[Last->EntriesNum].Date.Day, Last->Entries[Last->EntriesNum].Date.Month,
4960 Last->Entries[Last->EntriesNum].Date.Year, Last->Entries[Last->EntriesNum].Date.Hour,
4961 Last->Entries[Last->EntriesNum].Date.Minute,Last->Entries[Last->EntriesNum].Date.Second);
4962
4963 Last->Entries[Last->EntriesNum].EntryType = TODO_ALARM_DATETIME;
4964 if (msg.Buffer[22]==0x00 && msg.Buffer[23]==0x00 &&
4965 msg.Buffer[24]==0x00 && msg.Buffer[25]==0x00)
4966 {
4967 Last->Entries[Last->EntriesNum].EntryType = TODO_SILENT_ALARM_DATETIME;
4968 smprintf(s, "Alarm type : Silent\n");
4969 }
4970 Last->EntriesNum++;
4971 }
4972
4973 return ERR_NONE;
4974}
4975
4976/* ToDo support - 6610 style */
4977static GSM_Error N6510_GetNextToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh)
4978{
4979 GSM_Error error;
4980 GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
4981 /* The same to getting calendar method 3 */
4982 unsigned char req[] = {
4983 N6110_FRAME_HEADER,0x7D,0x00,0x00,0x00,0x00,
4984 0x00,0x99, /* Location */
4985 0xff,0xff,0xff,0xff,0x01};
4986
4987 if (refresh) {
4988 error=N6510_GetCalendarInfo3(s,LastToDo,false);
4989 if (error!=ERR_NONE) return error;
4990 ToDo->Location = 1;
4991 } else {
4992 ToDo->Location++;
4993 }
4994
4995 if (ToDo->Location > LastToDo->Number) return ERR_EMPTY;
4996
4997 req[8] = LastToDo->Location[ToDo->Location-1] / 256;
4998 req[9] = LastToDo->Location[ToDo->Location-1] % 256;
4999
5000 s->Phone.Data.ToDo = ToDo;
5001 smprintf(s, "Getting todo method 2\n");
5002 return GSM_WaitFor (s, req, 15, 0x13, 4, ID_GetToDo);
5003}
5004
5005static GSM_Error N6510_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool refresh)
5006{
5007 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) {
5008 return N6510_GetNextToDo1(s, ToDo, refresh);
5009 } else if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) {
5010 return N6510_GetNextToDo2(s, ToDo, refresh);
5011 } else {
5012 return ERR_NOTSUPPORTED;
5013 }
5014}
5015
5016/* ToDo support - 6310 style */
5017static GSM_Error N6510_ReplyDeleteAllToDo1(GSM_Protocol_Message msg, GSM_StateMachine *s)
5018{
5019 smprintf(s, "All TODO deleted\n");
5020 return ERR_NONE;
5021}
5022
5023/* ToDo support - 6310 style */
5024static GSM_Error N6510_DeleteAllToDo1(GSM_StateMachine *s)
5025{
5026 unsigned char req[] = {N6110_FRAME_HEADER, 0x11};
5027
5028 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) {
5029 return ERR_NOTSUPPORTED;
5030 }
5031
5032 smprintf(s, "Deleting all ToDo method 1\n");
5033 return GSM_WaitFor (s, req, 4, 0x55, 4, ID_DeleteAllToDo);
5034}
5035
5036static GSM_Error N6510_DeleteToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
5037{
5038 GSM_Error error;
5039 GSM_NOKIACalToDoLocations *LastToDo = &s->Phone.Data.Priv.N6510.LastToDo;
5040 GSM_CalendarEntry Note;
5041
5042 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) {
5043 return ERR_NOTSUPPORTED;
5044 }
5045
5046 error=N6510_GetCalendarInfo3(s,LastToDo,false);
5047 if (error!=ERR_NONE) return error;
5048
5049 smprintf(s, "Deleting ToDo method 2\n");
5050
5051 if (ToDo->Location > LastToDo->Number || ToDo->Location == 0) return ERR_INVALIDLOCATION;
5052
5053 Note.Location = LastToDo->Location[ToDo->Location-1];
5054 return N71_65_DelCalendar(s,&Note);
5055}
5056
5057/* ToDo support - 6310 style */
5058static GSM_Error N6510_ReplyGetToDoFirstLoc1(GSM_Protocol_Message msg, GSM_StateMachine *s)
5059{
5060 smprintf(s, "TODO first location received method 1: %02x\n",msg.Buffer[9]);
5061 s->Phone.Data.ToDo->Location = msg.Buffer[9];
5062 return ERR_NONE;
5063}
5064
5065/* ToDo support - 6310 style */
5066static GSM_Error N6510_ReplyAddToDo1(GSM_Protocol_Message msg, GSM_StateMachine *s)
5067{
5068 smprintf(s, "TODO set OK\n");
5069 return ERR_NONE;
5070}
5071
5072/* ToDo support - 6310 style */
5073static GSM_Error N6510_AddToDo1(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
5074{
5075 int Text, Alarm, EndTime, Completed, ulen, Phone;
5076 GSM_Error error;
5077 unsigned char reqLoc[] = {N6110_FRAME_HEADER, 0x0F};
5078 unsigned char reqSet[500] = {
5079 N6110_FRAME_HEADER, 0x01,
5080 0x03, /* Priority */
5081 0x00, /* Length of text */
5082 0x80,0x00,0x00,
5083 0x18}; /* Location */
5084
5085 s->Phone.Data.ToDo = ToDo;
5086
5087 smprintf(s, "Getting first ToDo location\n");
5088 error = GSM_WaitFor (s, reqLoc, 4, 0x55, 4, ID_SetToDo);
5089 if (error != ERR_NONE) return error;
5090 reqSet[9] = ToDo->Location;
5091
5092 switch (ToDo->Priority) {
5093 case GSM_Priority_Low: reqSet[4] = 3; break;
5094 case GSM_Priority_Medium: reqSet[4] = 2; break;
5095 case GSM_Priority_High: reqSet[4] = 1; break;
5096 }
5097
5098 GSM_ToDoFindDefaultTextTimeAlarmCompleted(ToDo, &Text, &Alarm, &Completed, &EndTime, &Phone);
5099
5100 if (Text == -1) return ERR_NOTSUPPORTED; /* XXX: shouldn't this be handled different way? */
5101 ulen = UnicodeLength(ToDo->Entries[Text].Text);
5102 reqSet[5] = ulen+1;
5103 CopyUnicodeString(reqSet+10,ToDo->Entries[Text].Text);
5104 reqSet[10+ulen*2] = 0x00;
5105 reqSet[10+ulen*2+1] = 0x00;
5106 smprintf(s, "Adding ToDo method 1\n");
5107 return GSM_WaitFor (s, reqSet, 12+ulen*2, 0x55, 4, ID_SetToDo);
5108}
5109
5110static GSM_Error N6510_ReplyAddToDo2(GSM_Protocol_Message msg, GSM_StateMachine *s)
5111{
5112 smprintf(s, "ToDo added method 2\n");
5113 return ERR_NONE;
5114}
5115
5116static GSM_Error N6510_ReplyGetToDoFirstLoc2(GSM_Protocol_Message msg, GSM_StateMachine *s)
5117{
5118 smprintf(s, "First ToDo location method 2: %i\n",msg.Buffer[8]*256+msg.Buffer[9]);
5119 s->Phone.Data.ToDo->Location = msg.Buffer[9];
5120 return ERR_NONE;
5121}
5122
5123static GSM_Error N6510_AddToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
5124{
5125 GSM_CalendarEntryNote;
5126 time_t t_time1,t_time2;
5127 long diff;
5128 GSM_Error error;
5129 GSM_DateTime DT;
5130 int Text, Alarm, EndTime, Completed, count=54, Phone;
5131 unsigned char reqLoc[] = {N6110_FRAME_HEADER, 0x95, 0x01};
5132 unsigned char req[5000] = {
5133 N6110_FRAME_HEADER, 0x65,
5134 0x01, /* 0 = calendar, 1 = todo */
5135 0x00, 0x00, 0x00,
5136 0x00, 0x00, /* location */
5137 0x00, 0x00, 0x00, 0x00,
5138 0xFF, 0xFF, 0xFF, 0xFF, /* alarm */
5139 0x80, 0x00, 0x00,
5140 0x01, /* note icon */
5141 0xFF, 0xFF, 0xFF, 0xFF, /* alarm type */
5142 0x00, /* 0x02 or 0x00 */
5143 0x01, /* note type */
5144 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* start date/time */
5145 0x07, 0xD0, 0x01, 0x12, 0x0C, 0x00, /* end date/time */
5146 0x00, 0x00, /* recurrance */
5147 0x00, 0x00, /* birth year */
5148 0x20, /* ToDo priority */
5149 0x00, /* ToDo completed ? */
5150 0x00, 0x00, 0x00,
5151 0x00, /* note text length */
5152 0x00, /* phone length/meeting place*/
5153 0x00, 0x00, 0x00};
5154
5155 s->Phone.Data.ToDo = ToDo;
5156
5157 smprintf(s, "Getting first free ToDo location method 2\n");
5158 error = GSM_WaitFor (s, reqLoc, 5, 0x13, 4, ID_SetToDo);
5159 if (error!=ERR_NONE) return error;
5160 req[8] = ToDo->Location/256;
5161 req[9] = ToDo->Location%256;
5162
5163 Note.Type = GSM_CAL_MEETING;
5164 DT.Year = 2004; DT.Month = 1; DT.Day = 1;
5165 DT.Hour = 12; DT.Minute = 12; DT.Second = 0;
5166 memcpy(&Note.Entries[0].Date,&DT,sizeof(GSM_DateTime));
5167 Note.Entries[0].EntryType = CAL_START_DATETIME;
5168 memcpy(&Note.Entries[1].Date,&DT,sizeof(GSM_DateTime));
5169 Note.Entries[1].EntryType = CAL_END_DATETIME;
5170 EncodeUnicode(Note.Entries[2].Text,"ala",3);
5171 Note.Entries[2].EntryType = CAL_TEXT;
5172 Note.EntriesNum = 3;
5173 error=N6510_FindCalendarIconID3(s, &Note, &req[21]);
5174 if (error!=ERR_NONE) return error;
5175
5176 switch (ToDo->Priority) {
5177 case GSM_Priority_Low: req[44] = 0x10; break;
5178 case GSM_Priority_Medium: req[44] = 0x20; break;
5179 case GSM_Priority_High: req[44] = 0x30; break;
5180 }
5181
5182 GSM_ToDoFindDefaultTextTimeAlarmCompleted(ToDo, &Text, &Alarm, &Completed, &EndTime, &Phone);
5183
5184 if (Completed != -1) req[45] = 0x01;
5185
5186 if (EndTime == -1) {
5187 GSM_GetCurrentDateTime(&DT);
5188 } else {
5189 memcpy(&DT,&ToDo->Entries[EndTime].Date,sizeof(GSM_DateTime));
5190 }
5191 /*Start time*/
5192 req[28]= DT.Year / 256;
5193 req[29]= DT.Year % 256;
5194 req[30]= DT.Month;
5195 req[31]= DT.Day;
5196 req[32]= DT.Hour;
5197 req[33]= DT.Minute;
5198 /*End time*/
5199 req[34]= DT.Year / 256;
5200 req[35]= DT.Year % 256;
5201 req[36]= DT.Month;
5202 req[37]= DT.Day;
5203 req[38]= DT.Hour;
5204 req[39]= DT.Minute;
5205
5206 if (Alarm != -1) {
5207 if (ToDo->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME)
5208 {
5209 req[22] = 0x00; req[23] = 0x00; req[24] = 0x00; req[25] = 0x00;
5210 }
5211 t_time2 = Fill_Time_T(DT,8);
5212 t_time1 = Fill_Time_T(ToDo->Entries[Alarm].Date,8);
5213 diff = (t_time1-t_time2)/60;
5214
5215 smprintf(s, " Difference : %li seconds or minutes\n", -diff);
5216 req[14] = (unsigned char)(-diff >> 24);
5217 req[15] = (unsigned char)(-diff >> 16);
5218 req[16] = (unsigned char)(-diff >> 8);
5219 req[17] = (unsigned char)(-diff);
5220 }
5221
5222 if (Text != -1) {
5223 req[49] = UnicodeLength(ToDo->Entries[Text].Text);
5224 CopyUnicodeString(req+54,ToDo->Entries[Text].Text);
5225 count+= req[49]*2;
5226 }
5227
5228 req[count++] = 0x00;
5229
5230 smprintf(s, "Adding ToDo method 2\n");
5231 return GSM_WaitFor (s, req, count, 0x13, 4, ID_SetToDo);
5232}
5233
5234static GSM_Error N6510_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
5235{
5236 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO63)) {
5237 return N6510_AddToDo1(s, ToDo);
5238 } else if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_TODO66)) {
5239 return N6510_AddToDo2(s, ToDo);
5240 } else {
5241 return ERR_NOTSUPPORTED;
5242 }
5243}
5244
5245static GSM_Error N6510_ReplyGetLocale(GSM_Protocol_Message msg, GSM_StateMachine *s)
5246{
5247 GSM_Locale *locale = s->Phone.Data.Locale;
5248
5249 switch (msg.Buffer[3]) {
5250 case 0x8A:
5251 smprintf(s, "Date settings received\n");
5252 switch (msg.Buffer[4]) {
5253 case 0x00:
5254 locale->DateFormat = GSM_Date_DDMMYYYY;
5255 locale->DateSeparator = '.';
5256 break;
5257 case 0x01:
5258 locale->DateFormat = GSM_Date_MMDDYYYY;
5259 locale->DateSeparator = '.';
5260 break;
5261 case 0x02:
5262 locale->DateFormat = GSM_Date_YYYYMMDD;
5263 locale->DateSeparator = '.';
5264 break;
5265 case 0x04:
5266 locale->DateFormat = GSM_Date_DDMMYYYY;
5267 locale->DateSeparator = '/';
5268 break;
5269 case 0x05:
5270 locale->DateFormat = GSM_Date_MMDDYYYY;
5271 locale->DateSeparator = '/';
5272 break;
5273 case 0x06:
5274 locale->DateFormat = GSM_Date_YYYYMMDD;
5275 locale->DateSeparator = '/';
5276 break;
5277 case 0x08:
5278 locale->DateFormat = GSM_Date_DDMMYYYY;
5279 locale->DateSeparator = '-';
5280 break;
5281 case 0x09:
5282 locale->DateFormat = GSM_Date_MMDDYYYY;
5283 locale->DateSeparator = '-';
5284 break;
5285 case 0x0A:
5286 locale->DateFormat = GSM_Date_YYYYMMDD;
5287 locale->DateSeparator = '-';
5288 break;
5289 default:/* FIXME */
5290 locale->DateFormat = GSM_Date_DDMMYYYY;
5291 locale->DateSeparator = '/';
5292 break;
5293 }
5294 return ERR_NONE;
5295 }
5296 return ERR_UNKNOWNRESPONSE;
5297}
5298
5299static GSM_Error N6510_GetLocale(GSM_StateMachine *s, GSM_Locale *locale)
5300{
5301 unsigned char req[] = {N6110_FRAME_HEADER, 0x89};
5302
5303 s->Phone.Data.Locale = locale;
5304
5305 smprintf(s, "Getting date format\n");
5306 return GSM_WaitFor (s, req, 4, 0x13, 4, ID_GetLocale);
5307}
5308
5309static GSM_Error N6510_ReplyGetCalendarSettings(GSM_Protocol_Message msg, GSM_StateMachine *s)
5310{
5311 GSM_CalendarSettings *sett = s->Phone.Data.CalendarSettings;
5312
5313 switch (msg.Buffer[3]) {
5314 case 0x86:
5315 smprintf(s, "Auto deleting setting received\n");
5316 sett->AutoDelete = msg.Buffer[4];
5317 return ERR_NONE;
5318 case 0x8E:
5319 smprintf(s, "Start day for calendar received\n");
5320 switch(msg.Buffer[4]) {
5321 case 0x03:
5322 sett->StartDay = 6;
5323 return ERR_NONE;
5324 case 0x02:
5325 sett->StartDay = 7;
5326 return ERR_NONE;
5327 case 0x01:
5328 sett->StartDay = 1;
5329 return ERR_NONE;
5330 }
5331 break;
5332 }
5333 return ERR_UNKNOWNRESPONSE;
5334}
5335
5336static GSM_Error N6510_GetCalendarSettings(GSM_StateMachine *s, GSM_CalendarSettings *settings)
5337{
5338 GSM_Errorerror;
5339 unsigned char req1[] = {N6110_FRAME_HEADER, 0x85};
5340 unsigned char req2[] = {N6110_FRAME_HEADER, 0x8D};
5341
5342 s->Phone.Data.CalendarSettings = settings;
5343
5344 smprintf(s, "Getting auto delete\n");
5345 error = GSM_WaitFor (s, req1, 4, 0x13, 4, ID_GetCalendarSettings);
5346 if (error != ERR_NONE) return error;
5347
5348 smprintf(s, "Getting start day for week\n");
5349 return GSM_WaitFor (s, req2, 4, 0x13, 4, ID_GetCalendarSettings);
5350}
5351
5352GSM_Error N6510_CancelCall(GSM_StateMachine *s, int ID, bool all)
5353{
5354 if (all) return ERR_NOTSUPPORTED;
5355 return DCT3DCT4_CancelCall(s,ID);
5356}
5357
5358GSM_Error N6510_AnswerCall(GSM_StateMachine *s, int ID, bool all)
5359{
5360 if (all) return ERR_NOTSUPPORTED;
5361 return DCT3DCT4_AnswerCall(s,ID);
5362}
5363
5364static GSM_Error N6510_ReplyAddSMSFolder(GSM_Protocol_Message msg, GSM_StateMachine *s)
5365{
5366 smprintf(s,"SMS folder \"%s\" has been added\n",DecodeUnicodeString(msg.Buffer+10));
5367 return ERR_NONE;
5368}
5369
5370GSM_Error N6510_AddSMSFolder(GSM_StateMachine *s, unsigned char *name)
5371{
5372 unsigned char req[200] = {N6110_FRAME_HEADER, 0x10, 0x01, 0x00, 0x01,
5373 0x00, /* Length */
5374 0x00, 0x00};
5375
5376
5377 CopyUnicodeString(req+10,name);
5378 req[7] = UnicodeLength(name)*2 + 6;
5379
5380 smprintf(s, "Adding SMS folder\n");
5381 return GSM_WaitFor (s, req, req[7] + 6, 0x14, 4, ID_AddSMSFolder);
5382}
5383
5384static GSM_Error N6510_SetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
5385{
5386 GSM_Error error;
5387 int count=4, location;
5388 unsigned char req[600] = {N6110_FRAME_HEADER, 0x09};
5389
5390 /* We have to enable WAP frames in phone */
5391 error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS);
5392 if (error!=ERR_NONE) return error;
5393
5394 location = bookmark->Location - 1;
5395 if (bookmark->Location == 0) location = 0xffff;
5396 req[count++] = (location & 0xff00) >> 8;
5397 req[count++] = location & 0x00ff;
5398
5399 count += NOKIA_SetUnicodeString(s, req+count, bookmark->Title, true);
5400 count += NOKIA_SetUnicodeString(s, req+count, bookmark->Address, true);
5401
5402 req[count++] = 0x00;
5403 req[count++] = 0x00;
5404 req[count++] = 0x00;
5405 req[count++] = 0x00;
5406
5407 smprintf(s, "Setting WAP bookmark\n");
5408 error = GSM_WaitFor (s, req, count, 0x3f, 4, ID_SetWAPBookmark);
5409 if (error != ERR_NONE) {
5410 if (error == ERR_INSIDEPHONEMENU || error == ERR_EMPTY || error == ERR_FULL) {
5411 DCT3DCT4_DisableConnectionFunctions(s);
5412 }
5413 return error;
5414 }
5415
5416 return DCT3DCT4_DisableConnectionFunctions(s);
5417}
5418
5419GSM_Error N6510_DeleteWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
5420{
5421 GSM_Error error;
5422
5423 /* We have to enable WAP frames in phone */
5424 error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS);
5425 if (error!=ERR_NONE) return error;
5426
5427 return DCT3DCT4_DeleteWAPBookmarkPart(s,bookmark);
5428}
5429
5430GSM_Error N6510_GetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
5431{
5432 GSM_Error error;
5433
5434 /* We have to enable WAP frames in phone */
5435 error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS);
5436 if (error!=ERR_NONE) return error;
5437
5438 return DCT3DCT4_GetWAPBookmarkPart(s,bookmark);
5439}
5440
5441static GSM_Reply_Function N6510ReplyFunctions[] = {
5442 {N71_65_ReplyCallInfo, "\x01",0x03,0x02,ID_IncomingFrame },
5443 {N71_65_ReplyCallInfo, "\x01",0x03,0x03,ID_IncomingFrame },
5444 {N71_65_ReplyCallInfo, "\x01",0x03,0x04,ID_IncomingFrame },
5445 {N71_65_ReplyCallInfo, "\x01",0x03,0x05,ID_IncomingFrame },
5446 {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_AnswerCall },
5447 {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_IncomingFrame },
5448 {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_CancelCall },
5449 {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_IncomingFrame },
5450 {N71_65_ReplyCallInfo, "\x01",0x03,0x0A,ID_IncomingFrame },
5451 {N71_65_ReplyCallInfo, "\x01",0x03,0x0B,ID_IncomingFrame },
5452 {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_DialVoice },
5453 {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_IncomingFrame },
5454 {N71_65_ReplyCallInfo, "\x01",0x03,0x23,ID_IncomingFrame },
5455 {N71_65_ReplyCallInfo, "\x01",0x03,0x25,ID_IncomingFrame },
5456 {N71_65_ReplyCallInfo, "\x01",0x03,0x27,ID_IncomingFrame },
5457 {N71_65_ReplySendDTMF, "\x01",0x03,0x51,ID_SendDTMF },
5458 {N71_65_ReplyCallInfo, "\x01",0x03,0x53,ID_IncomingFrame },
5459 {N71_65_ReplySendDTMF, "\x01",0x03,0x59,ID_SendDTMF },
5460 {N71_65_ReplySendDTMF, "\x01",0x03,0x5E,ID_SendDTMF },
5461
5462 {N6510_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame },
5463 {N6510_ReplyIncomingSMS, "\x02",0x03,0x04,ID_IncomingFrame },
5464 {N6510_ReplySetSMSC, "\x02",0x03,0x13,ID_SetSMSC },
5465 {N6510_ReplyGetSMSC, "\x02",0x03,0x15,ID_GetSMSC },
5466
5467 {N6510_ReplyGetMemoryStatus, "\x03",0x03,0x04,ID_GetMemoryStatus },
5468 {N6510_ReplyGetMemory, "\x03",0x03,0x08,ID_GetMemory },
5469 {N6510_ReplyDeleteMemory, "\x03",0x03,0x10,ID_SetMemory },
5470 {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetBitmap },
5471 {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetMemory },
5472
5473 {DCT3DCT4_ReplyCallDivert, "\x06",0x03,0x02,ID_Divert },
5474 {N71_65_ReplyUSSDInfo, "\x06",0x03,0x03,ID_IncomingFrame },
5475 {NoneReply, "\x06",0x03,0x06,ID_IncomingFrame },
5476 {NoneReply, "\x06",0x03,0x09,ID_IncomingFrame },
5477
5478 {N6510_ReplyEnterSecurityCode, "\x08",0x03,0x08,ID_EnterSecurityCode },
5479 {N6510_ReplyEnterSecurityCode, "\x08",0x03,0x09,ID_EnterSecurityCode },
5480 {N6510_ReplyGetSecurityStatus, "\x08",0x03,0x12,ID_GetSecurityStatus },
5481
5482 {N6510_ReplyGetNetworkInfo, "\x0A",0x03,0x01,ID_GetNetworkInfo },
5483 {N6510_ReplyGetNetworkInfo, "\x0A",0x03,0x01,ID_IncomingFrame },
5484 {N6510_ReplyLogIntoNetwork, "\x0A",0x03,0x02,ID_IncomingFrame },
5485 {N6510_ReplyGetSignalQuality, "\x0A",0x03,0x0C,ID_GetSignalQuality },
5486 {N6510_ReplyGetIncSignalQuality, "\x0A",0x03,0x1E,ID_IncomingFrame },
5487 {NoneReply, "\x0A",0x03,0x20,ID_IncomingFrame },
5488 {N6510_ReplyGetOperatorLogo, "\x0A",0x03,0x24,ID_GetBitmap },
5489 {N6510_ReplySetOperatorLogo, "\x0A",0x03,0x26,ID_SetBitmap },
5490
5491 {NoneReply, "\x0B",0x03,0x01,ID_PlayTone },
5492 {NoneReply, "\x0B",0x03,0x15,ID_PlayTone },
5493 {NoneReply, "\x0B",0x03,0x16,ID_PlayTone },
5494
5495 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x02,ID_SetCalendarNote },
5496 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x04,ID_SetCalendarNote },
5497 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x06,ID_SetCalendarNote },
5498 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x08,ID_SetCalendarNote },
5499 {N71_65_ReplyDelCalendar, "\x13",0x03,0x0C,ID_DeleteCalendarNote },
5500 {N71_65_ReplyGetNextCalendar1, "\x13",0x03,0x1A,ID_GetCalendarNote },/*method 1*/
5501 {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0x32,ID_GetCalendarNotePos },/*method 1*/
5502 {N6510_ReplyGetCalendarInfo, "\x13",0x03,0x3B,ID_GetCalendarNotesInfo},/*method 1*/
5503#ifdef DEBUG
5504 {N71_65_ReplyGetNextCalendar2, "\x13",0x03,0x3F,ID_GetCalendarNote },
5505#endif
5506 {N71_65_ReplyAddCalendar2, "\x13",0x03,0x41,ID_SetCalendarNote },/*method 2*/
5507 {N6510_ReplyAddCalendar3, "\x13",0x03,0x66,ID_SetCalendarNote },/*method 3*/
5508 {N6510_ReplyAddToDo2, "\x13",0x03,0x66,ID_SetToDo },
5509 {N6510_ReplyGetCalendar3, "\x13",0x03,0x7E,ID_GetCalendarNote },/*method 3*/
5510 {N6510_ReplyGetToDo2, "\x13",0x03,0x7E,ID_GetToDo },
5511 {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x86,ID_GetCalendarSettings },
5512 {N6510_ReplyGetLocale, "\x13",0x03,0x8A,ID_GetLocale },
5513 {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x8E,ID_GetCalendarSettings },
5514 {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0x96,ID_GetCalendarNotePos },/*method 3*/
5515 {N6510_ReplyGetToDoFirstLoc2, "\x13",0x03,0x96,ID_SetToDo },
5516 {N6510_ReplyGetCalendarInfo, "\x13",0x03,0x9F,ID_GetCalendarNotesInfo},/*method 3*/
5517 {N6510_ReplyGetToDoStatus2, "\x13",0x03,0x9F,ID_GetToDo },
5518
5519 {N6510_ReplySaveSMSMessage, "\x14",0x03,0x01,ID_SaveSMSMessage },
5520 {N6510_ReplySetPicture, "\x14",0x03,0x01,ID_SetBitmap },
5521 {N6510_ReplyGetSMSMessage, "\x14",0x03,0x03,ID_GetSMSMessage },
5522 {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x05,ID_DeleteSMSMessage },
5523 {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x06,ID_DeleteSMSMessage },
5524 {N6510_ReplyGetSMSStatus, "\x14",0x03,0x09,ID_GetSMSStatus },
5525 {N6510_ReplyGetSMSFolderStatus, "\x14",0x03,0x0d,ID_GetSMSFolderStatus },
5526 {N6510_ReplyGetSMSMessage, "\x14",0x03,0x0f,ID_GetSMSMessage },
5527 {N6510_ReplyAddSMSFolder, "\x14",0x03,0x11,ID_AddSMSFolder },
5528 {N6510_ReplyGetSMSFolders, "\x14",0x03,0x13,ID_GetSMSFolders },
5529 {N6510_ReplySaveSMSMessage, "\x14",0x03,0x17,ID_SaveSMSMessage },
5530 {N6510_ReplyGetSMSStatus, "\x14",0x03,0x1a,ID_GetSMSStatus },
5531
5532 {DCT4_ReplySetPhoneMode, "\x15",0x03,0x64,ID_Reset },
5533 {DCT4_ReplyGetPhoneMode, "\x15",0x03,0x65,ID_Reset },
5534 {NoneReply, "\x15",0x03,0x68,ID_Reset },
5535
5536 {N6510_ReplyGetBatteryCharge, "\x17",0x03,0x0B,ID_GetBatteryCharge },
5537
5538 {N6510_ReplySetDateTime, "\x19",0x03,0x02,ID_SetDateTime },
5539 {N6510_ReplyGetDateTime, "\x19",0x03,0x0B,ID_GetDateTime },
5540 {N6510_ReplySetAlarm, "\x19",0x03,0x12,ID_SetAlarm },
5541 {N6510_ReplyGetAlarm, "\x19",0x03,0x1A,ID_GetAlarm },
5542 {N6510_ReplyGetAlarm, "\x19",0x03,0x20,ID_GetAlarm },
5543
5544 {DCT4_ReplyGetIMEI, "\x1B",0x03,0x01,ID_GetIMEI },
5545 {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x08,ID_GetHardware },
5546 {N6510_ReplyGetPPM, "\x1B",0x03,0x08,ID_GetPPM },
5547 {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x0C,ID_GetProductCode },
5548
5549 /* 0x1C - vibra */
5550
5551 {N6510_ReplyGetRingtonesInfo, "\x1f",0x03,0x08,ID_GetRingtonesInfo },
5552 {N6510_ReplyDeleteRingtones, "\x1f",0x03,0x11,ID_SetRingtone },
5553 {N6510_ReplyGetRingtone, "\x1f",0x03,0x13,ID_GetRingtone },
5554 {N6510_ReplySetBinRingtone, "\x1f",0x03,0x0F,ID_SetRingtone },
5555
5556 /* 0x23 - voice records */
5557
5558 {N6510_ReplyGetProfile, "\x39",0x03,0x02,ID_GetProfile },
5559 {N6510_ReplySetProfile, "\x39",0x03,0x04,ID_SetProfile },
5560 {N6510_ReplyGetProfile, "\x39",0x03,0x06,ID_GetProfile },
5561
5562 {N6510_ReplySetLight, "\x3A",0x03,0x06,ID_SetLight },
5563
5564 {N6510_ReplyGetFMStation, "\x3E",0x03,0x06,ID_GetFMStation },
5565 {N6510_ReplyGetFMStatus, "\x3E",0x03,0x0E,ID_GetFMStation },
5566 {N6510_ReplySetFMStation, "\x3E",0x03,0x15,ID_SetFMStation },
5567 {N6510_ReplyGetFMStation, "\x3E",0x03,0x16,ID_GetFMStation },
5568
5569 {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x01,ID_EnableConnectFunc },
5570 {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x02,ID_EnableConnectFunc },
5571 {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x04,ID_DisableConnectFunc },
5572 {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x05,ID_DisableConnectFunc },
5573 {N6510_ReplyGetWAPBookmark, "\x3f",0x03,0x07,ID_GetWAPBookmark },
5574 {N6510_ReplyGetWAPBookmark, "\x3f",0x03,0x08,ID_GetWAPBookmark },
5575 {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0A,ID_SetWAPBookmark },
5576 {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0B,ID_SetWAPBookmark },
5577 {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0D,ID_DeleteWAPBookmark },
5578 {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0E,ID_DeleteWAPBookmark },
5579 {DCT3DCT4_ReplyGetActiveConnectSet,"\x3f",0x03,0x10,ID_GetConnectSet },
5580 {DCT3DCT4_ReplySetActiveConnectSet,"\x3f",0x03,0x13,ID_SetConnectSet },
5581 {N6510_ReplyGetConnectionSettings,"\x3f",0x03,0x16,ID_GetConnectSet },
5582 {N6510_ReplyGetConnectionSettings,"\x3f",0x03,0x17,ID_GetConnectSet },
5583 {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x19,ID_SetConnectSet },
5584 {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x1A,ID_SetConnectSet },
5585 {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x28,ID_SetConnectSet },
5586 {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x2B,ID_SetConnectSet },
5587 {N6510_ReplyGetChatSettings, "\x3f",0x03,0x3B,ID_GetChatSettings },
5588 {N6510_ReplyGetChatSettings, "\x3f",0x03,0x3C,ID_GetChatSettings },
5589
5590 {N6510_ReplyGetOriginalIMEI, "\x42",0x07,0x00,ID_GetOriginalIMEI },
5591 {N6510_ReplyGetManufactureMonth, "\x42",0x07,0x00,ID_GetManufactureMonth },
5592 {N6510_ReplyGetOriginalIMEI, "\x42",0x07,0x01,ID_GetOriginalIMEI },
5593 {N6510_ReplyGetManufactureMonth, "\x42",0x07,0x02,ID_GetManufactureMonth },
5594
5595 {N6510_ReplySetOperatorLogo, "\x43",0x03,0x08,ID_SetBitmap },
5596 {N6510_ReplyGetGPRSAccessPoint, "\x43",0x03,0x06,ID_GetGPRSPoint },
5597 {N6510_ReplySetGPRSAccessPoint1, "\x43",0x03,0x06,ID_SetGPRSPoint },
5598#ifdef DEVELOP
5599 {N6510_ReplyEnableGPRSAccessPoint,"\x43",0x03,0x06,ID_EnableGPRSPoint },
5600#endif
5601 {N6510_ReplyGetSyncMLSettings, "\x43",0x03,0x06,ID_GetSyncMLSettings },
5602 {N6510_ReplyGetSyncMLName, "\x43",0x03,0x06,ID_GetSyncMLName },
5603 {NoneReply, "\x43",0x03,0x08,ID_SetGPRSPoint },
5604
5605 /* 0x4A - voice records */
5606
5607 /* 0x53 - simlock */
5608
5609 {N6510_ReplyAddToDo1, "\x55",0x03,0x02,ID_SetToDo },
5610 {N6510_ReplyGetToDo1, "\x55",0x03,0x04,ID_GetToDo },
5611 {N6510_ReplyGetToDoFirstLoc1, "\x55",0x03,0x10,ID_SetToDo },
5612 {N6510_ReplyDeleteAllToDo1, "\x55",0x03,0x12,ID_DeleteAllToDo },
5613 {N6510_ReplyGetToDoStatus1, "\x55",0x03,0x16,ID_GetToDo },
5614
5615 {N6510_ReplyAddFileHeader, "\x6D",0x03,0x03,ID_AddFile },
5616 {N6510_ReplyAddFolder, "\x6D",0x03,0x05,ID_AddFolder },
5617 {N6510_ReplyGetFilePart, "\x6D",0x03,0x0F,ID_GetFile },
5618 {N6510_ReplyAddFileHeader, "\x6D",0x03,0x13,ID_AddFile },
5619 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x15,ID_GetFileInfo },
5620 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x15,ID_GetFile },
5621 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x15,ID_AddFile },
5622 {N6510_ReplyDeleteFile, "\x6D",0x03,0x19,ID_DeleteFile },
5623 {N6510_ReplyDeleteFile, "\x6D",0x03,0x1F,ID_DeleteFile },
5624 {N6510_ReplyGetFileSystemStatus, "\x6D",0x03,0x23,ID_FileSystemStatus },
5625 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x2F,ID_GetFileInfo },
5626 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x2F,ID_GetFile },
5627 {N6510_ReplyGetFileSystemStatus, "\x6D",0x03,0x2F,ID_FileSystemStatus },
5628 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x33,ID_GetFileInfo },
5629 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x33,ID_GetFile },
5630 {N6510_ReplyAddFilePart, "\x6D",0x03,0x41,ID_AddFile },
5631 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x43,ID_AddFile },
5632 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x43,ID_GetFile },
5633 {N6510_ReplyGetFileFolderInfo, "\x6D",0x03,0x43,ID_GetFileInfo },
5634
5635 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x01,ID_GetBitmap },
5636 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x01,ID_SetBitmap },
5637 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x0F,ID_GetBitmap },
5638 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x0F,ID_SetBitmap },
5639 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x10,ID_GetBitmap },
5640 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x10,ID_SetBitmap },
5641 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x25,ID_SetBitmap },
5642
5643 {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetModel },
5644 {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetFirmware },
5645
5646 /* 0xD7 - Bluetooth */
5647
5648 {N6510_ReplyGetRingtoneID, "\xDB",0x03,0x02,ID_SetRingtone },
5649
5650 {NULL, "\x00",0x00,0x00,ID_None }
5651};
5652
5653GSM_Phone_Functions N6510Phone = {
5654 "1100|1100a|1100b|3100|3100b|3108|3200|3200a|3300|3510|3510i|3530|3589i|3590|3595|5100|6100|6200|6220|6230|6310|6310i|6385|6510|6610|6800|7210|7250|7250i|7600|8310|8390|8910|8910i",
5655 N6510ReplyFunctions,
5656 N6510_Initialise,
5657 NONEFUNCTION, /* Terminate */
5658 GSM_DispatchMessage,
5659 N6510_ShowStartInfo,
5660 NOKIA_GetManufacturer,
5661 DCT3DCT4_GetModel,
5662 DCT3DCT4_GetFirmware,
5663 DCT4_GetIMEI,
5664 N6510_GetOriginalIMEI,
5665 N6510_GetManufactureMonth,
5666 DCT4_GetProductCode,
5667 DCT4_GetHardware,
5668 N6510_GetPPM,
5669 NOTSUPPORTED, /* GetSIMIMSI */
5670 N6510_GetDateTime,
5671 N6510_SetDateTime,
5672 N6510_GetAlarm,
5673 N6510_SetAlarm,
5674 N6510_GetLocale,
5675 NOTSUPPORTED, /* SetLocale */
5676 N6510_PressKey,
5677 DCT4_Reset,
5678 NOTIMPLEMENTED, /* ResetPhoneSettings*/
5679 N6510_EnterSecurityCode,
5680 N6510_GetSecurityStatus,
5681 NOTSUPPORTED, /* GetDisplayStatus*/
5682 NOTIMPLEMENTED, /* SetAutoNetworkLogin*/
5683 N6510_GetBatteryCharge,
5684 N6510_GetSignalQuality,
5685 N6510_GetNetworkInfo,
5686 NOTSUPPORTED, /* GetCategory */
5687 NOTSUPPORTED, /* AddCategory */
5688 NOTSUPPORTED, /* GetCategoryStatus */
5689 N6510_GetMemoryStatus,
5690 N6510_GetMemory,
5691 NOTIMPLEMENTED, /* GetNextMemory */
5692 N6510_SetMemory,
5693 NOTIMPLEMENTED, /* AddMemory */
5694 N6510_DeleteMemory,
5695 NOTIMPLEMENTED, /* DeleteAllMemory */
5696 N6510_GetSpeedDial,
5697 NOTIMPLEMENTED, /* SetSpeedDial */
5698 N6510_GetSMSC,
5699 N6510_SetSMSC,
5700 N6510_GetSMSStatus,
5701 N6510_GetSMSMessage,
5702 N6510_GetNextSMSMessage,
5703 N6510_SetSMS,
5704 N6510_AddSMS,
5705 N6510_DeleteSMSMessage,
5706 N6510_SendSMSMessage,
5707 NOTSUPPORTED, /* SendSavedSMS */
5708 NOKIA_SetIncomingSMS,
5709 NOTIMPLEMENTED, /* SetIncomingCB */
5710 N6510_GetSMSFolders,
5711 N6510_AddSMSFolder,
5712 NOTIMPLEMENTED, /* DeleteSMSFolder */
5713 N6510_DialVoice,
5714 N6510_AnswerCall,
5715 N6510_CancelCall,
5716 NOTIMPLEMENTED, /* HoldCall */
5717 NOTIMPLEMENTED, /* UnholdCall */
5718 NOTIMPLEMENTED, /* ConferenceCall */
5719 NOTIMPLEMENTED, /* SplitCall */
5720 NOTIMPLEMENTED, /* TransferCall */
5721 NOTIMPLEMENTED, /* SwitchCall */
5722 DCT3DCT4_GetCallDivert,
5723 DCT3DCT4_SetCallDivert,
5724 DCT3DCT4_CancelAllDiverts,
5725 NOKIA_SetIncomingCall,
5726 NOKIA_SetIncomingUSSD,
5727 DCT3DCT4_SendDTMF,
5728 N6510_GetRingtone,
5729 N6510_SetRingtone,
5730 N6510_GetRingtonesInfo,
5731 N6510_DeleteUserRingtones,
5732 N6510_PlayTone,
5733 N6510_GetWAPBookmark,
5734 N6510_SetWAPBookmark,
5735 N6510_DeleteWAPBookmark,
5736 N6510_GetWAPSettings,
5737 N6510_SetWAPSettings,
5738 N6510_GetMMSSettings,
5739 N6510_SetMMSSettings,
5740 N6510_GetSyncMLSettings,
5741 NOTSUPPORTED, /* SetSyncMLSettings*/
5742 N6510_GetChatSettings,
5743 NOTSUPPORTED, /* SetChatSettings */
5744 N6510_GetBitmap,
5745 N6510_SetBitmap,
5746 N6510_GetToDoStatus,
5747 NOTIMPLEMENTED, /* GetToDo */
5748 N6510_GetNextToDo,
5749 NOTIMPLEMENTED, /* SetToDo */
5750 N6510_AddToDo,
5751 N6510_DeleteToDo2,
5752 N6510_DeleteAllToDo1,
5753 N6510_GetCalendarStatus,
5754 NOTIMPLEMENTED, /* GetCalendar */
5755 N6510_GetNextCalendar,
5756 NOTIMPLEMENTED, /* SetCalendar */
5757 N6510_AddCalendar,
5758 N71_65_DelCalendar,
5759 NOTIMPLEMENTED, /* DeleteAllCalendar*/
5760 N6510_GetCalendarSettings,
5761 NOTSUPPORTED, /* SetCalendarSettings*/
5762 NOTIMPLEMENTED, /* GetNote */
5763 N6510_GetProfile,
5764 N6510_SetProfile,
5765 N6510_GetFMStation,
5766 N6510_SetFMStation,
5767 N6510_ClearFMStations,
5768 N6510_GetNextFileFolder,
5769 N6510_GetFilePart,
5770 N6510_AddFilePart,
5771 N6510_GetFileSystemStatus,
5772 N6510_DeleteFile,
5773 N6510_AddFolder,
5774 N6510_GetGPRSAccessPoint,
5775 N6510_SetGPRSAccessPoint
5776};
5777
5778#endif
5779
5780/* How should editor hadle tabs in this file? Add editor commands here.
5781 * vim: noexpandtab sw=8 ts=8 sts=8:
5782 */