1 /* (c) 2002-2005 by Marcin Wiacek */
2 /* based on some Markus Plail, Pawel Kot work from Gnokii (www.gnokii.org)
3 * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot
4 * GNU GPL version 2 or later
5 */
6 /* Due to a problem in the source code management, the names of some of
7 * the authors have unfortunately been lost. We do not mean to belittle
8 * their efforts and hope they will contact us to see their names
9 * properly added to the Copyright notice above.
10 * Having published their contributions under the terms of the GNU
11 * General Public License (GPL) [version 2], the Copyright of these
12 * authors will remain respected by adhering to the license they chose
13 * to publish their code under.
14 */
15
16 #include <gammu-config.h>
17
18 #ifdef GSM_ENABLE_NOKIA6510
19
20 #include <string.h>
21 #include <time.h>
22 #ifdef HAVE_STDINT_H
23 #include <stdint.h>
24 #endif
25
26 #include <gammu-nokia.h>
27
28 #include "../../../../misc/coding/coding.h"
29 #include "../../../../misc/locales.h"
30 #include "../../../../gsmcomon.h"
31 #include "../../../../service/gsmlogo.h"
32 #include "../../../../service/gsmnet.h"
33 #include "../../../../service/gsmring.h"
34 #include "../../../../service/sms/gsmmulti.h"
35 #include "../../nfunc.h"
36 #include "../../nfuncold.h"
37 #include "../../../pfunc.h"
38 #include "../dct4func.h"
39 #include "n6510.h"
40 #include "6510cal.h"
41 #include "6510file.h"
42
N6510_Initialise(GSM_StateMachine * s)43 static GSM_Error N6510_Initialise (GSM_StateMachine *s)
44 {
45 s->Phone.Data.Priv.N6510.CalendarIconsNum = 0;
46 s->Phone.Data.Priv.N6510.LastFreeMemoryLocation = 0;
47 s->Phone.Data.Priv.N6510.LastFreeMemoryType = 0;
48 s->Phone.Data.Priv.N6510.FilesLocationsAvail = 0;
49 s->Phone.Data.Priv.N6510.FilesLocationsUsed = 0;
50 s->Phone.Data.Priv.N6510.FilesCache = NULL;
51 s->Phone.Data.Priv.N6510.ScreenWidth = 0;
52 s->Phone.Data.Priv.N6510.ScreenHeight = 0;
53
54 /* Default timeout for cables */
55 s->Phone.Data.Priv.N6510.Timeout = 8;
56 if (s->ConnectionType == GCT_IRDAPHONET || s->ConnectionType == GCT_FBUS2IRDA) {
57 s->Phone.Data.Priv.N6510.Timeout = 40;
58 }
59 if (s->ConnectionType == GCT_BLUEPHONET || s->ConnectionType == GCT_BLUEFBUS2) {
60 s->Phone.Data.Priv.N6510.Timeout = 20;
61 }
62
63 /* Enables various things like incoming SMS, call info, etc. */
64 return N71_65_EnableFunctions (s, "\x01\x02\x06\x0A\x14\x17\x39", 7);
65 }
66
N6510_Terminate(GSM_StateMachine * s)67 static GSM_Error N6510_Terminate (GSM_StateMachine *s)
68 {
69 free(s->Phone.Data.Priv.N6510.FilesCache);
70 s->Phone.Data.Priv.N6510.FilesCache = NULL;
71 return ERR_NONE;
72 }
73
N6510_ReplyGetMemory(GSM_Protocol_Message * msg,GSM_StateMachine * s)74 static GSM_Error N6510_ReplyGetMemory(GSM_Protocol_Message *msg, GSM_StateMachine *s)
75 {
76 smprintf(s, "Phonebook entry received\n");
77 if (msg->Buffer[6] == 0x0f)
78 return N71_65_ReplyGetMemoryError(msg->Buffer[10], s);
79
80 if (msg->Length < 22) {
81 return ERR_UNKNOWN;
82 }
83 return N71_65_DecodePhonebook(s,
84 s->Phone.Data.Memory,
85 s->Phone.Data.Bitmap,
86 s->Phone.Data.SpeedDial,
87 msg->Buffer + 22,
88 msg->Length - 22,
89 FALSE);
90 }
91
N6510_GetMemory(GSM_StateMachine * s,GSM_MemoryEntry * entry)92 static GSM_Error N6510_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry)
93 {
94 GSM_Error error;
95 unsigned char req[] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x01, 0x00, 0x01,
96 0xfe, 0x10, /* memory type */
97 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x01, /* location */
99 0x00, 0x00, 0x01};
100
101 req[9] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
102 if (req[9]==0xff) return ERR_NOTSUPPORTED;
103
104 if (entry->Location==0x00) return ERR_INVALIDLOCATION;
105
106 req[14] = entry->Location / 256;
107 req[15] = entry->Location % 256;
108
109 s->Phone.Data.Memory=entry;
110 smprintf(s, "Getting phonebook entry\n");
111 error = GSM_WaitFor (s, req, 19, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_GetMemory);
112 if (error == ERR_WORKINPROGRESS) {
113 sleep(2);
114 smprintf(s, "Retrying to get phonebook entry\n");
115 error = GSM_WaitFor (s, req, 19, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_GetMemory);
116 }
117 if (entry->MemoryType == MEM_DC || entry->MemoryType == MEM_RC || entry->MemoryType == MEM_MC) {
118 /* 6111 */
119 if (error == ERR_NOTSUPPORTED) return ERR_EMPTY;
120 }
121 return error;
122 }
123
N6510_ReplyGetMemoryStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)124 static GSM_Error N6510_ReplyGetMemoryStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
125 {
126 GSM_Phone_Data *Data = &s->Phone.Data;
127
128 smprintf(s, "Memory status received\n");
129 /* Quess ;-)) */
130 if (msg->Buffer[14]==0x10) {
131 Data->MemoryStatus->MemoryFree = msg->Buffer[18]*256 + msg->Buffer[19];
132 Data->MemoryStatus->MemoryUsed = msg->Buffer[20]*256 + msg->Buffer[21];
133 } else if (msg->Buffer[14]==0x02) {
134 Data->MemoryStatus->MemoryFree = msg->Buffer[22];
135 Data->MemoryStatus->MemoryUsed = msg->Buffer[21];
136 } else {
137 Data->MemoryStatus->MemoryFree = msg->Buffer[17];
138 Data->MemoryStatus->MemoryUsed = msg->Buffer[20]*256 + msg->Buffer[21];
139 }
140 smprintf(s, "Size : %i\n",Data->MemoryStatus->MemoryFree);
141 smprintf(s, "Used : %i\n",Data->MemoryStatus->MemoryUsed);
142 Data->MemoryStatus->MemoryFree -= Data->MemoryStatus->MemoryUsed;
143 smprintf(s, "Free : %i\n",Data->MemoryStatus->MemoryFree);
144 return ERR_NONE;
145 }
146
N6510_GetMemoryStatus(GSM_StateMachine * s,GSM_MemoryStatus * Status)147 static GSM_Error N6510_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status)
148 {
149 unsigned char req[] = {N6110_FRAME_HEADER, 0x03, 0x02,
150 0x00, /* memory type */
151 0x55, 0x55, 0x55, 0x00};
152
153 req[5] = NOKIA_GetMemoryType(s, Status->MemoryType,N71_65_MEMORY_TYPES);
154 if (req[5]==0xff) return ERR_NOTSUPPORTED;
155
156 s->Phone.Data.MemoryStatus=Status;
157 smprintf(s, "Getting memory status\n");
158 return GSM_WaitFor (s, req, 10, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_GetMemoryStatus);
159 }
160
N6510_ReplyGetSMSC(GSM_Protocol_Message * msg,GSM_StateMachine * s)161 static GSM_Error N6510_ReplyGetSMSC(GSM_Protocol_Message *msg, GSM_StateMachine *s)
162 {
163 int i, current, j;
164 GSM_Phone_Data *Data = &s->Phone.Data;
165 size_t pos;
166 GSM_Error error;
167
168 switch (msg->Buffer[4]) {
169 case 0x00:
170 smprintf(s, "SMSC received\n");
171 break;
172 case 0x02:
173 smprintf(s, "SMSC empty\n");
174 return ERR_INVALIDLOCATION;
175 case 0x09:
176 smprintf(s, "SMSC empty???\n");
177 return ERR_INVALIDLOCATION;
178 default:
179 smprintf(s, "Unknown SMSC state: %02x\n",msg->Buffer[4]);
180 return ERR_UNKNOWNRESPONSE;
181 }
182 memset(Data->SMSC,0,sizeof(GSM_SMSC));
183 Data->SMSC->Location = msg->Buffer[8];
184 Data->SMSC->Format = SMS_FORMAT_Text;
185 switch (msg->Buffer[10]) {
186 case 0x00: Data->SMSC->Format = SMS_FORMAT_Text; break;
187 case 0x22: Data->SMSC->Format = SMS_FORMAT_Fax; break;
188 case 0x26: Data->SMSC->Format = SMS_FORMAT_Pager; break;
189 case 0x32: Data->SMSC->Format = SMS_FORMAT_Email; break;
190 }
191 Data->SMSC->Validity.Format = SMS_Validity_RelativeFormat;
192 Data->SMSC->Validity.Relative = msg->Buffer[12];
193 if (msg->Buffer[12] == 0x00) Data->SMSC->Validity.Relative = SMS_VALID_Max_Time;
194
195 current = 14;
196 for (i=0;i<msg->Buffer[13];i++) {
197 switch (msg->Buffer[current]) {
198 case 0x81:
199 j=current+4;
200 while (msg->Buffer[j]!=0) {j++;}
201 j=j-33;
202 if (j>GSM_MAX_SMSC_NAME_LENGTH) {
203 smprintf(s, "Too long name\n");
204 return ERR_UNKNOWNRESPONSE;
205 }
206 CopyUnicodeString(Data->SMSC->Name,msg->Buffer+current+4);
207 smprintf(s, " Name \"%s\"\n", DecodeUnicodeString(Data->SMSC->Name));
208 break;
209 case 0x82:
210 switch (msg->Buffer[current+2]) {
211 case 0x01:
212 pos = current + 4;
213 error = GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->DefaultNumber, msg->Buffer, &pos, msg->Length, TRUE);
214 if (error != ERR_NONE) {
215 return error;
216 }
217 smprintf(s, " Default number \"%s\"\n", DecodeUnicodeString(Data->SMSC->DefaultNumber));
218 break;
219 case 0x02:
220 pos = current + 4;
221 error = GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->Number, msg->Buffer, &pos, msg->Length, FALSE);
222 if (error != ERR_NONE) {
223 return error;
224 }
225 smprintf(s, " Number \"%s\"\n", DecodeUnicodeString(Data->SMSC->Number));
226 break;
227 default:
228 smprintf(s, "Unknown SMSC number: %02x\n",msg->Buffer[current+2]);
229 return ERR_UNKNOWNRESPONSE;
230 }
231 break;
232 default:
233 smprintf(s, "Unknown SMSC block: %02x\n",msg->Buffer[current]);
234 return ERR_UNKNOWNRESPONSE;
235 }
236 current = current + msg->Buffer[current+1];
237 }
238 return ERR_NONE;
239 }
240
N6510_GetSMSC(GSM_StateMachine * s,GSM_SMSC * smsc)241 static GSM_Error N6510_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
242 {
243 unsigned char req[] = {N6110_FRAME_HEADER, 0x14,
244 0x01, /* location */
245 0x00};
246
247 if (smsc->Location==0x00) return ERR_INVALIDLOCATION;
248
249 req[4]=smsc->Location;
250
251 s->Phone.Data.SMSC=smsc;
252 smprintf(s, "Getting SMSC\n");
253 return GSM_WaitFor (s, req, 6, 0x02, s->Phone.Data.Priv.N6510.Timeout, ID_GetSMSC);
254 }
255
N6510_ReplySetSMSC(GSM_Protocol_Message * msg,GSM_StateMachine * s)256 static GSM_Error N6510_ReplySetSMSC(GSM_Protocol_Message *msg, GSM_StateMachine *s)
257 {
258 switch (msg->Buffer[4]) {
259 case 0x00:
260 smprintf(s, "SMSC set OK\n");
261 return ERR_NONE;
262 case 0x02:
263 smprintf(s, "Invalid SMSC location\n");
264 return ERR_INVALIDLOCATION;
265 default:
266 smprintf(s, "Unknown SMSC state: %02x\n",msg->Buffer[4]);
267 return ERR_UNKNOWNRESPONSE;
268 }
269 }
270
N6510_SetSMSC(GSM_StateMachine * s,GSM_SMSC * smsc)271 static GSM_Error N6510_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
272 {
273 int count = 13,i;
274 unsigned char req[256] = {N6110_FRAME_HEADER,
275 0x12, 0x55, 0x01, 0x0B, 0x34,
276 0x05, /* Location */
277 0x00,
278 0x00, /* Format */
279 0x00,
280 0xFF}; /* Validity */
281
282 req[8] = smsc->Location;
283 switch (smsc->Format) {
284 case SMS_FORMAT_Text: req[10] = 0x00; break;
285 case SMS_FORMAT_Fax: req[10] = 0x22; break;
286 case SMS_FORMAT_Pager: req[10] = 0x26; break;
287 case SMS_FORMAT_Email: req[10] = 0x32; break;
288 }
289 req[12] = smsc->Validity.Relative;
290
291 /* We have now blocks. Number of blocks = 3 */
292 req[count++] = 0x03;
293
294 /* -------------- SMSC number ----------------- */
295 /* Block type: number */
296 req[count++] = 0x82;
297 /* Offset to next block */
298 req[count++] = 0x1A;
299 /* Type of number: SMSC number */
300 req[count++] = 0x02;
301 req[count] = GSM_PackSemiOctetNumber(smsc->Number, req+count+2, FALSE) + 1;
302 if (req[count]>18) {
303 smprintf(s, "Too long SMSC number in frame\n");
304 return ERR_UNKNOWN;
305 }
306 req[count+1] = req[count] - 1;
307 count += 23;
308
309 /* --------------- Default number ------------- */
310 /* Block type: number */
311 req[count++] = 0x82;
312 /* Offset to next block */
313 req[count++] = 0x14;
314 /* Type of number: default number */
315 req[count++] = 0x01;
316 req[count] = GSM_PackSemiOctetNumber(smsc->DefaultNumber, req+count+2, TRUE) + 1;
317 if (req[count]*2>12) {
318 smprintf(s, "Too long SMSC number in frame\n");
319 return ERR_UNKNOWN;
320 }
321 req[count+1] = req[count] - 1;
322 count += 17;
323
324 /* -------------- SMSC name ------------------- */
325 req[count++] = 0x81;
326 req[count++] = UnicodeLength(smsc->Name)*2 + 2 + 4;
327 req[count++] = UnicodeLength(smsc->Name)*2 + 2;
328 req[count++] = 0x00;
329 /* Can't make CopyUnicodeString(req+count,sms->Name) !!!!
330 * with MSVC6 count is changed then
331 */
332 i = count;
333 CopyUnicodeString(req+i,smsc->Name);
334 count += UnicodeLength(smsc->Name)*2 + 2;
335
336 smprintf(s, "Setting SMSC\n");
337 return GSM_WaitFor (s, req, count, 0x02, s->Phone.Data.Priv.N6510.Timeout, ID_SetSMSC);
338 }
339
N6510_ReplyGetNetworkInfo(GSM_Protocol_Message * msg,GSM_StateMachine * s)340 static GSM_Error N6510_ReplyGetNetworkInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
341 {
342 int current = msg->Buffer[7]+7, pos;
343 GSM_Phone_Data *Data = &s->Phone.Data;
344 GSM_NetworkInfo network_info_local, *network_info;
345
346 if (msg->Buffer[3] == 0xf0) {
347 return ERR_NOTSUPPORTED;
348 }
349
350 if (Data->RequestID == ID_GetNetworkInfo) {
351 network_info = Data->NetworkInfo;
352 } else {
353 network_info = &network_info_local;
354 }
355
356 network_info->NetworkName[0] = 0x00;
357 network_info->NetworkName[1] = 0x00;
358
359 switch (msg->Buffer[8]) {
360 case 0x00:
361 smprintf(s, "home network\n");
362 network_info->State = GSM_HomeNetwork;
363 break;
364 case 0x01:
365 smprintf(s, "roaming network\n");
366 network_info->State = GSM_RoamingNetwork;
367 break;
368 case 0x04:
369 smprintf(s, "not logged");
370 network_info->State = GSM_NoNetwork;
371 break;
372 case 0x06:
373 smprintf(s, "SIM card rejected\n");
374 network_info->State = GSM_RegistrationDenied;
375 break;
376 case 0x09:
377 smprintf(s, "not logged");
378 network_info->State = GSM_NoNetwork;
379 break;
380 default:
381 smprintf(s, "unknown %i!\n",msg->Buffer[8]);
382 network_info->State = GSM_NetworkStatusUnknown;
383 }
384 if (network_info->State == GSM_HomeNetwork || network_info->State == GSM_RoamingNetwork) {
385 pos = 10;
386 NOKIA_GetUnicodeString(s, &pos, msg->Buffer, network_info->NetworkName, TRUE);
387 smprintf(s, "Network name: %s ", DecodeUnicodeString(network_info->NetworkName));
388 NOKIA_DecodeNetworkCode(msg->Buffer + (current + 7), network_info->NetworkCode);
389 smprintf(s, "Network code: %s\n", network_info->NetworkCode);
390 smprintf(s, "Network name in libGammu: %s ", DecodeUnicodeString(GSM_GetNetworkName(network_info->NetworkCode)));
391 sprintf(network_info->LAC, "%02X%02X", msg->Buffer[current+1], msg->Buffer[current+2]);
392 smprintf(s, "LAC: %s\n", network_info->LAC);
393 sprintf(network_info->CID, "%02X%02X", msg->Buffer[current+5], msg->Buffer[current+6]);
394 smprintf(s, "CID: %s\n", network_info->CID);
395 }
396 return ERR_NONE;
397 }
398
N6510_GetNetworkInfo(GSM_StateMachine * s,GSM_NetworkInfo * netinfo)399 static GSM_Error N6510_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo)
400 {
401 unsigned char req[] = {N6110_FRAME_HEADER, 0x00, 0x00};
402
403 netinfo->GPRS = 0;
404 s->Phone.Data.NetworkInfo=netinfo;
405 smprintf(s, "Getting network info\n");
406 return GSM_WaitFor (s, req, 5, 0x0a, s->Phone.Data.Priv.N6510.Timeout, ID_GetNetworkInfo);
407 }
408
N6510_EncodeSMSFrame(GSM_StateMachine * s,GSM_SMSMessage * sms,unsigned char * req,GSM_SMSMessageLayout * Layout,int * length)409 static GSM_Error N6510_EncodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *req, GSM_SMSMessageLayout *Layout, int *length)
410 {
411 int count = 0, pos1, pos2, pos3, pos4, pos5;
412 GSM_Error error;
413
414 memset(Layout,255,sizeof(GSM_SMSMessageLayout));
415
416 req[count++] = 0x01;
417 if (sms->PDU != SMS_Deliver) {
418 req[count++] = 0x02;
419 } else {
420 req[count++] = 0x00;
421 }
422
423 pos1 = count; count++;
424 /* firstbyte set in SMS Layout */
425 Layout->firstbyte = count; count++;
426 if (sms->PDU != SMS_Deliver) {
427 Layout->TPMR = count; count++;
428
429 Layout->TPPID = count; count++;
430
431 /* TP.DCS set in SMS layout */
432 Layout->TPDCS = count; count++;
433 req[count++] = 0x00;
434 } else {
435 Layout->TPPID = count; count++;
436 /* TP.DCS set in SMS layout */
437 Layout->TPDCS = count; count++;
438 Layout->DateTime = count; count += 7;
439 req[count++] = 0x55;
440 req[count++] = 0x55;
441 req[count++] = 0x55;
442 }
443
444 /* We have now blocks. Number of blocks = 3 or 4 */
445 if (sms->PDU != SMS_Deliver) {
446 req[count++] = 0x04;
447 } else {
448 req[count++] = 0x03;
449 }
450
451 /* -------------- Phone number ------------- */
452 /* Block type: number */
453 req[count++] = 0x82;
454 /* Offset to next block */
455 req[count++] = 0x10;
456 /* Type of number: default number */
457 req[count++] = 0x01;
458 pos4 = count; count++;
459 /* now coded Number in SMS Layout */
460 Layout->Number = count; count+= 12;
461
462 /* -------------- SMSC number -------------- */
463 /* Block type: number */
464 req[count++] = 0x82;
465 /* Offset to next block */
466 req[count++] = 0x10;
467 /* Type of number: SMSC number */
468 req[count++] = 0x02;
469 pos5 = count; count++;
470 /* now coded SMSC number in SMS Layout */
471 Layout->SMSCNumber = count; count += 12;
472
473 /* -------------- SMS validity ------------- */
474 if (sms->PDU != SMS_Deliver) {
475 /* Block type: validity */
476 req[count++] = 0x08;
477 req[count++] = 0x04;
478 /* data length */
479 req[count++] = 0x01;
480 Layout->TPVP = count; count++;
481 }
482
483 /* --------------- SMS text ---------------- */
484 /* Block type: SMS text */
485 req[count++] = 0x80;
486 /* this the same as req[11] but starting from req[42] */
487 pos2 = count; count++;
488 pos3 = count; count++;
489 /* FIXME*/
490 Layout->TPUDL = count; count++;
491 /* SMS text and UDH coded in SMS Layout */
492 Layout->Text = count;
493
494 error = PHONE_EncodeSMSFrame(s,sms,req,*Layout,length,FALSE);
495 if (error != ERR_NONE) return error;
496
497 req[pos1] = *length - 1;
498 req[pos2] = *length - Layout->Text + 6;
499 req[pos3] = *length - Layout->Text;
500
501 /* Convert number of semioctets to number of chars */
502 req[pos4] = req[Layout->Number] + 4;
503 if (req[pos4] % 2) req[pos4]++;
504 req[pos4] /= 2;
505
506 req[pos5] = req[Layout->SMSCNumber] + 1;
507
508 if (req[pos4]>12 || req[pos5]>12) {
509 smprintf(s, "Too long phone number in frame\n");
510 return ERR_UNKNOWN;
511 }
512
513 return ERR_NONE;
514 }
515
N6510_ReplyGetSMSFolders(GSM_Protocol_Message * msg,GSM_StateMachine * s)516 static GSM_Error N6510_ReplyGetSMSFolders(GSM_Protocol_Message *msg, GSM_StateMachine *s)
517 {
518 int j, num = 0;
519 size_t pos;
520 GSM_Phone_Data *Data = &s->Phone.Data;
521
522 switch (msg->Buffer[3]) {
523 case 0x13:
524 smprintf(s, "SMS folders names received\n");
525 Data->SMSFolders->Number = msg->Buffer[5]+2;
526 pos = 6;
527 for (j=0;j<msg->Buffer[5];j++) {
528 while (TRUE) {
529 if (msg->Buffer[pos] == msg->Buffer[6] &&
530 msg->Buffer[pos+1] == msg->Buffer[7]) break;
531 if (pos+4 > msg->Length) return ERR_UNKNOWNRESPONSE;
532 pos++;
533 }
534 pos+=4;
535 smprintf(s, "Folder index: %02x",msg->Buffer[pos - 2]);
536 if (msg->Buffer[pos - 1]>GSM_MAX_SMS_FOLDER_NAME_LEN) {
537 smprintf(s, "Too long text\n");
538 return ERR_UNKNOWNRESPONSE;
539 }
540 CopyUnicodeString(Data->SMSFolders->Folder[num].Name,msg->Buffer + pos);
541 smprintf(s, ", folder name: \"%s\"\n",DecodeUnicodeString(Data->SMSFolders->Folder[num].Name));
542 Data->SMSFolders->Folder[num].InboxFolder = FALSE;
543 Data->SMSFolders->Folder[num].Memory = MEM_ME;
544 if (num == 0x01) { /* OUTBOX SIM */
545 Data->SMSFolders->Folder[0].Memory = MEM_SM;
546 Data->SMSFolders->Folder[0].InboxFolder = TRUE;
547 Data->SMSFolders->Folder[0].OutboxFolder = FALSE;
548
549 Data->SMSFolders->Folder[1].Memory = MEM_SM;
550 Data->SMSFolders->Folder[1].InboxFolder = FALSE;
551 Data->SMSFolders->Folder[1].OutboxFolder = TRUE;
552
553 CopyUnicodeString(Data->SMSFolders->Folder[2].Name,Data->SMSFolders->Folder[0].Name);
554 Data->SMSFolders->Folder[2].Memory = MEM_ME;
555 Data->SMSFolders->Folder[2].InboxFolder = TRUE;
556 Data->SMSFolders->Folder[2].OutboxFolder = FALSE;
557
558 CopyUnicodeString(Data->SMSFolders->Folder[3].Name,Data->SMSFolders->Folder[1].Name);
559 Data->SMSFolders->Folder[3].Memory = MEM_ME;
560 Data->SMSFolders->Folder[3].InboxFolder = FALSE;
561 Data->SMSFolders->Folder[3].OutboxFolder = TRUE;
562
563 num+=2;
564 }
565 num++;
566 }
567 return ERR_NONE;
568 case 0xf0:
569 smprintf(s, "HINT: Maybe phone needs F_SMS_FILES?\n");
570 break;
571 }
572 return ERR_UNKNOWNRESPONSE;
573 }
574
N6510_GetSMSFoldersS40_30(GSM_StateMachine * s UNUSED,GSM_SMSFolders * folders)575 GSM_Error N6510_GetSMSFoldersS40_30(GSM_StateMachine *s UNUSED, GSM_SMSFolders *folders)
576 {
577 folders->Number=4;
578 EncodeUnicode(folders->Folder[0].Name,_("SIM"),strlen(_("SIM")));
579 EncodeUnicode(folders->Folder[1].Name,_("Inbox"),strlen(_("Inbox")));
580 EncodeUnicode(folders->Folder[2].Name,_("Sent items"),strlen(_("Sent items")));
581 EncodeUnicode(folders->Folder[3].Name,_("Saved items"),strlen(_("Saved items")));
582 folders->Folder[0].InboxFolder = TRUE;
583 folders->Folder[1].InboxFolder = TRUE;
584 folders->Folder[2].InboxFolder = FALSE;
585 folders->Folder[3].InboxFolder = FALSE;
586 folders->Folder[0].OutboxFolder = TRUE;
587 folders->Folder[1].OutboxFolder = FALSE;
588 folders->Folder[2].OutboxFolder = TRUE;
589 folders->Folder[3].OutboxFolder = FALSE;
590 folders->Folder[0].Memory = MEM_SM;
591 folders->Folder[1].Memory = MEM_ME;
592 folders->Folder[2].Memory = MEM_ME;
593 folders->Folder[3].Memory = MEM_ME;
594 return ERR_NONE;
595 }
596
N6510_GetSMSFolders(GSM_StateMachine * s,GSM_SMSFolders * folders)597 static GSM_Error N6510_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders)
598 {
599 unsigned char req[] = {N6110_FRAME_HEADER, 0x12, 0x00, 0x00};
600
601 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
602 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMS_FILES)) return N6510_GetFilesystemSMSFolders(s,folders);
603 return N6510_GetSMSFoldersS40_30(s,folders);
604 }
605
606 s->Phone.Data.SMSFolders=folders;
607 smprintf(s, "Getting SMS folders\n");
608 return GSM_WaitFor (s, req, 6, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_GetSMSFolders);
609 }
610
N6510_ReplyGetSMSFolderStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)611 static GSM_Error N6510_ReplyGetSMSFolderStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
612 {
613 int i;
614 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
615
616 smprintf(s, "SMS folder status received\n");
617 Priv->LastSMSFolder.Number=msg->Buffer[6]*256+msg->Buffer[7];
618 smprintf(s, "Number of Entries: %i\n",Priv->LastSMSFolder.Number);
619 smprintf(s, "Locations: ");
620 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
621 Priv->LastSMSFolder.Location[i]=msg->Buffer[8+(i*2)]*256+msg->Buffer[(i*2)+9];
622 smprintf(s, "%i ",Priv->LastSMSFolder.Location[i]);
623 }
624 smprintf(s, "\n");
625 NOKIA_SortSMSFolderStatus(s, &Priv->LastSMSFolder);
626 return ERR_NONE;
627 }
628
N6510_GetSMSFolderStatus(GSM_StateMachine * s,int folderid)629 static GSM_Error N6510_GetSMSFolderStatus(GSM_StateMachine *s, int folderid)
630 {
631 unsigned char req[] = {N7110_FRAME_HEADER, 0x0C,
632 0x01, /* 0x01=SIM, 0x02=ME */
633 0x00, /* Folder ID */
634 0x0f, 0x55, 0x55, 0x55};
635
636 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
637 switch (folderid) {
638 case 0x01: req[5] = 0x01; break; /* SIM */
639 default : req[5] = folderid; req[4] = 0x02; break; /* ME folders */
640 }
641 } else {
642 switch (folderid) {
643 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
644 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
645 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */
646 }
647 }
648
649 smprintf(s, "Getting SMS folder status\n");
650 return GSM_WaitFor (s, req, 10, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_GetSMSFolderStatus);
651 }
652
N6510_GetSMSLocation(GSM_StateMachine * s,GSM_SMSMessage * sms,unsigned char * folderid,unsigned int * location)653 static void N6510_GetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *folderid, unsigned int *location)
654 {
655 int ifolderid;
656
657 /* simulate flat SMS memory */
658 if (sms->Folder==0x00) {
659 ifolderid = sms->Location / GSM_PHONE_MAXSMSINFOLDER;
660 *folderid = ifolderid + 0x01;
661 *location = sms->Location - ifolderid * GSM_PHONE_MAXSMSINFOLDER;
662 if (*folderid == 0x1B) (*folderid)=0x99; /* 0x1A is Outbox in 6230i */
663 } else {
664 *folderid = sms->Folder;
665 *location = sms->Location;
666 if (*folderid == 0x1A) (*folderid)=0x99; /* 0x1A is Outbox in 6230i */
667 }
668 smprintf(s, "SMS folder %i & location %i -> 6510 folder %i & location %i\n",
669 sms->Folder,sms->Location,*folderid,*location);
670 }
671
N6510_SetSMSLocation(GSM_StateMachine * s,GSM_SMSMessage * sms,unsigned char folderid,int location)672 static void N6510_SetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char folderid, int location)
673 {
674 sms->Folder = 0;
675 sms->Location = (folderid - 0x01) * GSM_PHONE_MAXSMSINFOLDER + location;
676 smprintf(s, "6510 folder %i & location %i -> SMS folder %i & location %i\n",
677 folderid,location,sms->Folder,sms->Location);
678 }
679
N6510_DecodeSMSFrame(GSM_StateMachine * s,GSM_SMSMessage * sms,unsigned char * buffer,size_t * current2)680 static GSM_Error N6510_DecodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *buffer, size_t *current2)
681 {
682 int i, current, blocks=0, SMSTemplateDateTime = 0;
683 GSM_SMSMessageLayout Layout;
684 GSM_Error error;
685
686 memset(&Layout,255,sizeof(GSM_SMSMessageLayout));
687 Layout.firstbyte = 2;
688 switch (buffer[0]) {
689 case 0x00:
690 smprintf(s, "SMS deliver\n");
691 sms->PDU = SMS_Deliver;
692 Layout.TPPID = 3;
693 Layout.TPDCS = 4;
694 Layout.DateTime = 5;
695 blocks = 15;
696 break;
697 case 0x01:
698 smprintf(s, "Delivery report\n");
699 sms->PDU = SMS_Status_Report;
700 Layout.TPMR = 3;
701 Layout.TPStatus = 4;
702 Layout.DateTime = 5;
703 Layout.SMSCTime = 12;
704 blocks = 19;
705 break;
706 case 0x02:
707 smprintf(s, "SMS template\n");
708 sms->PDU = SMS_Submit;
709 Layout.TPMR = 3;
710 Layout.TPPID = 4;
711 Layout.TPDCS = 5;
712 blocks = 7;
713 break;
714 }
715 current = blocks + 1;
716 for (i=0;i<buffer[blocks];i++) {
717 switch (buffer[current]) {
718 case 0x08:
719 smprintf(s, "SMSC timestamp (ignored)\n");
720 break;
721 case 0x80:
722 smprintf(s, "SMS text\n");
723 if (buffer[current + 2] > buffer[current + 3]) {
724 Layout.TPUDL = current + 2;
725 } else {
726 Layout.TPUDL = current + 3;
727 }
728 Layout.Text = current + 4;
729 break;
730 case 0x82:
731 switch (buffer[current+2]) {
732 case 0x01:
733 smprintf(s, "Phone number\n");
734 Layout.Number = current + 4;
735 break;
736 case 0x02:
737 smprintf(s, "SMSC number\n");
738 Layout.SMSCNumber = current + 4;
739 break;
740 default:
741 smprintf(s, "Unknown number\n");
742 break;
743 }
744 break;
745 case 0x84:
746 smprintf(s, "Date and time of saving for SMS template\n");
747 SMSTemplateDateTime = current + 2;
748 break;
749 default:
750 smprintf(s, "Unknown block %02x\n",buffer[current]);
751 }
752 current = current + buffer[current + 1];
753 }
754 error = GSM_DecodeSMSFrame(&(s->di), sms,buffer,Layout);
755 if (SMSTemplateDateTime != 0) {
756 sms->PDU = SMS_Deliver;
757 NOKIA_DecodeDateTime(s, buffer+SMSTemplateDateTime, &sms->DateTime, TRUE, FALSE);
758 }
759 (*current2) = current;
760 return error;
761 }
762
N6510_ReplyGetSMSMessage(GSM_Protocol_Message * msg,GSM_StateMachine * s)763 GSM_Error N6510_ReplyGetSMSMessage(GSM_Protocol_Message *msg, GSM_StateMachine *s)
764 {
765 size_t i,j;
766 size_t Width, Height;
767 unsigned char output[500]; /* output2[500]; */
768 GSM_Phone_Data *Data = &s->Phone.Data;
769 GSM_Error error;
770
771 switch(msg->Buffer[3]) {
772 case 0x03:
773 smprintf(s, "SMS Message received\n");
774 GSM_SetDefaultReceivedSMSData(Data->GetSMSMessage->SMS);
775 Data->GetSMSMessage->Number=1;
776 NOKIA_DecodeSMSState(s, msg->Buffer[5], &(Data->GetSMSMessage->SMS[0]));
777 if (msg->Length < 15) {
778 smprintf(s, "No message data!\n");
779 Data->GetSMSMessage->SMS[0].PDU = SMS_Deliver;
780 return ERR_NONE;
781 }
782 switch (msg->Buffer[14]) {
783 case 0x00:
784 case 0x01:
785 case 0x02:
786 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
787 Data->GetSMSMessage->Number=0;
788 i = 14;
789 while (TRUE) {
790 error = N6510_DecodeSMSFrame(s, &Data->GetSMSMessage->SMS[Data->GetSMSMessage->Number],msg->Buffer+i,&j);
791 if (error != ERR_NONE) return error;
792 NOKIA_DecodeSMSState(s, msg->Buffer[5], &Data->GetSMSMessage->SMS[Data->GetSMSMessage->Number]);
793 i+=j;
794 Data->GetSMSMessage->Number++;
795 if (i>=msg->Length) break;
796 }
797 return error;
798 } else {
799 return N6510_DecodeSMSFrame(s, &Data->GetSMSMessage->SMS[0],msg->Buffer+14,&j);
800 }
801 case 0xA0:
802 smprintf(s, "Picture Image\n");
803 Data->GetSMSMessage->Number = 0;
804 i = 0;
805 output[i++] = 0x30; /* Smart Messaging 3.0 */
806 output[i++] = SM30_OTA;
807 output[i++] = 0x01; /* Length */
808 output[i++] = 0x00; /* Length */
809 output[i++] = 0x00;
810 PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height);
811 output[i++] = Width;
812 output[i++] = Height;
813 output[i++] = 0x01;
814 memcpy(output+i,msg->Buffer+30,PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0));
815 i = i + PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0);
816 #if 0
817 if (msg->Length!=282) {
818 output[i++] = SM30_UNICODETEXT;
819 output[i++] = 0;
820 output[i++] = 0; /* Length - later changed */
821 GSM_UnpackEightBitsToSeven(0, msg->Length-282, msg->Length-304, msg->Buffer+282,output2);
822 DecodeDefault(output+i, output2, msg->Length - 282, TRUE, NULL);
823 output[i - 1] = UnicodeLength(output+i) * 2;
824 i = i + output[i-1];
825 }
826 #endif
827 GSM_MakeMultiPartSMS(&(s->di), Data->GetSMSMessage,output,i,UDH_NokiaProfileLong,SMS_Coding_8bit,1,0);
828 for (i=0;i<3;i++) {
829 Data->GetSMSMessage->SMS[i].Number[0]=0;
830 Data->GetSMSMessage->SMS[i].Number[1]=0;
831 }
832 if (Data->Bitmap != NULL) {
833 Data->Bitmap->Location = 0;
834 PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height);
835 Data->Bitmap->BitmapWidth = Width;
836 Data->Bitmap->BitmapHeight = Height;
837 PHONE_DecodeBitmap(GSM_NokiaPictureImage, msg->Buffer + 30, Data->Bitmap);
838 Data->Bitmap->Sender[0] = 0x00;
839 Data->Bitmap->Sender[1] = 0x00;
840 Data->Bitmap->Text[0] = 0;
841 Data->Bitmap->Text[1] = 0;
842 }
843 return ERR_NONE;
844 default:
845 smprintf(s, "Unknown SMS type: %i\n",msg->Buffer[8]);
846 }
847 break;
848 case 0x0f:
849 smprintf(s, "SMS message info received\n");
850 CopyUnicodeString(Data->GetSMSMessage->SMS[0].Name,msg->Buffer+52);
851 smprintf(s, "Name: \"%s\"\n",DecodeUnicodeString(Data->GetSMSMessage->SMS[0].Name));
852 return ERR_NONE;
853 }
854 return ERR_UNKNOWNRESPONSE;
855 }
856
N6510_PrivGetSMSMessageBitmap(GSM_StateMachine * s,GSM_MultiSMSMessage * sms,GSM_Bitmap * bitmap)857 static GSM_Error N6510_PrivGetSMSMessageBitmap(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, GSM_Bitmap *bitmap)
858 {
859 GSM_Error error;
860 unsigned char folderid,namebuffer[200];
861 unsigned int location;
862 int i;
863 unsigned char req[] = {
864 N6110_FRAME_HEADER,
865 0x02, /* msg type: 0x02 for getting sms, 0x0e for sms status */
866 0x01, /* 0x01=SIM, 0x02=ME */
867 0x00, /* FolderID */
868 0x00, 0x02, /* Location */
869 0x01, 0x00};
870
871 N6510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
872
873 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
874 switch (folderid) {
875 case 0x01: req[5] = 0x01; break; /* SIM */
876 default : req[5] = folderid; req[4] = 0x02; break; /* ME folders */
877 }
878 } else {
879 switch (folderid) {
880 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
881 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
882 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */
883 }
884 }
885
886 req[6]=location / 256;
887 req[7]=location % 256;
888
889 s->Phone.Data.GetSMSMessage = sms;
890 s->Phone.Data.Bitmap = bitmap;
891 smprintf(s, "Getting sms message info\n");
892 req[3] = 0x0e; req[8] = 0x55; req[9] = 0x55;
893 error=GSM_WaitFor (s, req, 10, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_GetSMSMessage);
894 if (error!=ERR_NONE) return error;
895 CopyUnicodeString(namebuffer,sms->SMS[0].Name);
896
897 smprintf(s, "Getting sms\n");
898 req[3] = 0x02; req[8] = 0x01; req[9] = 0x00;
899 error = GSM_WaitFor (s, req, 10, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_GetSMSMessage);
900 if (error == ERR_NONE) {
901 if (sms->Number == 0) {
902 return ERR_EMPTY;
903 }
904 for (i=0;i<sms->Number;i++) {
905 N6510_SetSMSLocation(s, &sms->SMS[i], folderid, location);
906 sms->SMS[i].Folder = folderid;
907
908 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
909 sms->SMS[i].InboxFolder = TRUE;
910 if (folderid > 2) sms->SMS[i].InboxFolder = FALSE;
911 sms->SMS[i].Memory = MEM_ME;
912 if (folderid == 0x01) sms->SMS[i].Memory = MEM_SM;
913 } else {
914 sms->SMS[i].InboxFolder = TRUE;
915 if (folderid != 0x01 && folderid != 0x03) sms->SMS[i].InboxFolder = FALSE;
916 sms->SMS[i].Memory = MEM_ME;
917 if (folderid == 0x01 || folderid == 0x02) sms->SMS[i].Memory = MEM_SM;
918 }
919
920 CopyUnicodeString(sms->SMS[i].Name,namebuffer);
921 }
922 }
923 return error;
924 }
925
N6510_GetSMSMessage(GSM_StateMachine * s,GSM_MultiSMSMessage * sms)926 static GSM_Error N6510_GetSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms)
927 {
928 GSM_Error error;
929 unsigned char folderid;
930 unsigned int location;
931 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
932 int i;
933 gboolean found = FALSE;
934
935 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
936 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMS_FILES)) return ERR_NOTSUPPORTED;
937 }
938
939 /* Clear SMS structure of any possible junk */
940 GSM_SetDefaultReceivedSMSData(&(sms->SMS[0]));
941
942 N6510_GetSMSLocation(s, &(sms->SMS[0]), &folderid, &location);
943 error=N6510_GetSMSFolderStatus(s, folderid);
944 if (error!=ERR_NONE) return error;
945 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
946 if (Priv->LastSMSFolder.Location[i]==location) {
947 found = TRUE;
948 break;
949 }
950 }
951 if (!found) return ERR_EMPTY;
952 return N6510_PrivGetSMSMessageBitmap(s,sms,NULL);
953 }
954
N6510_GetNextSMSMessageBitmap(GSM_StateMachine * s,GSM_MultiSMSMessage * sms,gboolean start,GSM_Bitmap * bitmap)955 static GSM_Error N6510_GetNextSMSMessageBitmap(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboolean start, GSM_Bitmap *bitmap)
956 {
957 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
958 unsigned char folderid;
959 unsigned int location;
960 GSM_Error error;
961 int i;
962 gboolean findnextfolder = FALSE;
963
964 if (start) {
965 folderid = 0x00;
966 findnextfolder = TRUE;
967 error=N6510_GetSMSFolders(s,&Priv->LastSMSFolders);
968 if (error!=ERR_NONE) return error;
969 } else {
970 N6510_GetSMSLocation(s, &(sms->SMS[0]), &folderid, &location);
971 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
972 if (Priv->LastSMSFolder.Location[i]==location) break;
973 }
974 /* Is this last location in this folder ? */
975 if (i==Priv->LastSMSFolder.Number-1) {
976 findnextfolder=TRUE;
977 } else {
978 location=Priv->LastSMSFolder.Location[i+1];
979 }
980 }
981 if (findnextfolder) {
982 Priv->LastSMSFolder.Number=0;
983 while (Priv->LastSMSFolder.Number==0) {
984 folderid++;
985 /* Too high folder number */
986 if ((folderid-1)>=Priv->LastSMSFolders.Number) return ERR_EMPTY;
987 /* Get next folder status */
988 error=N6510_GetSMSFolderStatus(s, folderid);
989 if (error!=ERR_NONE) return error;
990 /* First location from this folder */
991 location=Priv->LastSMSFolder.Location[0];
992 }
993 }
994 N6510_SetSMSLocation(s, &sms->SMS[0], folderid, location);
995
996 return N6510_PrivGetSMSMessageBitmap(s, sms, bitmap);
997 }
998
N6510_GetNextSMSMessage(GSM_StateMachine * s,GSM_MultiSMSMessage * sms,gboolean start)999 static GSM_Error N6510_GetNextSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboolean start)
1000 {
1001 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30) &&
1002 GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMS_FILES)) {
1003 return N6510_GetNextFilesystemSMS(s,sms,start);
1004 }
1005
1006 return N6510_GetNextSMSMessageBitmap(s, sms, start, NULL);
1007 }
1008
N6510_ReplyStartupNoteLogo(GSM_Protocol_Message * msg,GSM_StateMachine * s)1009 static GSM_Error N6510_ReplyStartupNoteLogo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1010 {
1011 GSM_Phone_Data *Data = &s->Phone.Data;
1012
1013 if (Data->RequestID == ID_GetBitmap) {
1014 switch (msg->Buffer[4]) {
1015 case 0x01:
1016 smprintf(s, "Welcome note text received\n");
1017 CopyUnicodeString(Data->Bitmap->Text,msg->Buffer+6);
1018 smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text));
1019 return ERR_NONE;
1020 case 0x10:
1021 smprintf(s, "Dealer note text received\n");
1022 CopyUnicodeString(Data->Bitmap->Text,msg->Buffer+6);
1023 smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text));
1024 return ERR_NONE;
1025 case 0x0f:
1026 smprintf(s, "Startup logo received\n");
1027 PHONE_DecodeBitmap(GSM_Nokia7110StartupLogo, msg->Buffer + 22, Data->Bitmap);
1028 return ERR_NONE;
1029 }
1030 }
1031 if (Data->RequestID == ID_SetBitmap) {
1032 switch (msg->Buffer[4]) {
1033 case 0x01:
1034 case 0x10:
1035 case 0x0f:
1036 case 0x25:
1037 return ERR_NONE;
1038 }
1039 }
1040 return ERR_UNKNOWN;
1041 }
1042
N6510_GetPictureImage(GSM_StateMachine * s,GSM_Bitmap * Bitmap,int * location)1043 static GSM_Error N6510_GetPictureImage(GSM_StateMachine *s, GSM_Bitmap *Bitmap, int *location)
1044 {
1045 GSM_MultiSMSMessage sms;
1046 int Number;
1047 GSM_Bitmap bitmap;
1048 GSM_Error error;
1049
1050 sms.SMS[0].Folder = 0;
1051 Number = 0;
1052 bitmap.Location = 255;
1053 error=N6510_GetNextSMSMessageBitmap(s, &sms, TRUE, &bitmap);
1054 while (error == ERR_NONE) {
1055 if (bitmap.Location != 255) {
1056 Number++;
1057 if (Number == Bitmap->Location) {
1058 bitmap.Location = Bitmap->Location;
1059 memcpy(Bitmap,&bitmap,sizeof(GSM_Bitmap));
1060 *location = sms.SMS[0].Location;
1061 return ERR_NONE;
1062 }
1063 }
1064 bitmap.Location = 255;
1065 sms.SMS[0].Folder = 0;
1066 error=N6510_GetNextSMSMessageBitmap(s, &sms, FALSE, &bitmap);
1067 }
1068 return ERR_INVALIDLOCATION;
1069 }
1070
N6510_GetBitmap(GSM_StateMachine * s,GSM_Bitmap * Bitmap)1071 static GSM_Error N6510_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
1072 {
1073 unsigned char reqOp [] = {N6110_FRAME_HEADER, 0x23, 0x00, 0x00, 0x55, 0x55, 0x55};
1074 unsigned char reqStartup[] = {N6110_FRAME_HEADER, 0x02, 0x0f};
1075 unsigned char reqNote [] = {N6110_FRAME_HEADER, 0x02, 0x01, 0x00};
1076 GSM_MemoryEntry pbk;
1077 GSM_Error error;
1078 int Location;
1079
1080 s->Phone.Data.Bitmap=Bitmap;
1081 switch (Bitmap->Type) {
1082 case GSM_StartupLogo:
1083 Bitmap->BitmapWidth = 96;
1084 Bitmap->BitmapHeight = 65;
1085 GSM_ClearBitmap(Bitmap);
1086 smprintf(s, "Getting startup logo\n");
1087 return GSM_WaitFor (s, reqStartup, 5, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_GetBitmap);
1088 case GSM_DealerNote_Text:
1089 reqNote[4] = 0x10;
1090 smprintf(s, "Getting dealer note\n");
1091 return GSM_WaitFor (s, reqNote, 6, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_GetBitmap);
1092 case GSM_WelcomeNote_Text:
1093 smprintf(s, "Getting welcome note\n");
1094 return GSM_WaitFor (s, reqNote, 6, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_GetBitmap);
1095 case GSM_CallerGroupLogo:
1096 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PBK35)) return ERR_NOTSUPPORTED;
1097 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1098 pbk.MemoryType = (GSM_MemoryType)MEM6510_CG2;
1099 pbk.Location = Bitmap->Location;
1100 smprintf(s, "Getting caller group logo method 2\n");
1101 return N6510_GetMemory(s,&pbk);
1102 }
1103 Bitmap->BitmapWidth = 72;
1104 Bitmap->BitmapHeight = 14;
1105 GSM_ClearBitmap(Bitmap);
1106 pbk.MemoryType = (GSM_MemoryType)MEM7110_CG;
1107 pbk.Location = Bitmap->Location;
1108 smprintf(s, "Getting caller group logo\n");
1109 error=N6510_GetMemory(s,&pbk);
1110 if (error==ERR_NONE) NOKIA_GetDefaultCallerGroupName(Bitmap);
1111 return error;
1112 case GSM_OperatorLogo:
1113 smprintf(s, "Getting operator logo\n");
1114 return GSM_WaitFor (s, reqOp, 9, 0x0A, s->Phone.Data.Priv.N6510.Timeout, ID_GetBitmap);
1115 case GSM_PictureImage:
1116 return N6510_GetPictureImage(s, Bitmap, &Location);
1117 default:
1118 break;
1119 }
1120 return ERR_NOTSUPPORTED;
1121 }
1122
N6510_ReplyGetIncSignalQuality(GSM_Protocol_Message * msg,GSM_StateMachine * s)1123 static GSM_Error N6510_ReplyGetIncSignalQuality(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1124 {
1125 smprintf(s, "Network level changed to: %i\n",msg->Buffer[4]);
1126 return ERR_NONE;
1127 }
1128
N6510_ReplyGetSignalQuality(GSM_Protocol_Message * msg,GSM_StateMachine * s)1129 static GSM_Error N6510_ReplyGetSignalQuality(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1130 {
1131 GSM_Phone_Data *Data = &s->Phone.Data;
1132
1133 smprintf(s, "Network level received: %i\n",msg->Buffer[8]);
1134 Data->SignalQuality->SignalStrength = -1;
1135 Data->SignalQuality->SignalPercent = ((int)msg->Buffer[8]);
1136 Data->SignalQuality->BitErrorRate = -1;
1137 return ERR_NONE;
1138 }
1139
N6510_GetSignalQuality(GSM_StateMachine * s,GSM_SignalQuality * sig)1140 static GSM_Error N6510_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig)
1141 {
1142 unsigned char req[] = {N6110_FRAME_HEADER, 0x0B, 0x00, 0x02, 0x00, 0x00, 0x00};
1143
1144 s->Phone.Data.SignalQuality = sig;
1145 smprintf(s, "Getting network level\n");
1146 return GSM_WaitFor (s, req, 9, 0x0a, s->Phone.Data.Priv.N6510.Timeout * 3, ID_GetSignalQuality);
1147 }
1148
N6510_IncomingBatteryCharge(GSM_Protocol_Message * msg,GSM_StateMachine * s)1149 static GSM_Error N6510_IncomingBatteryCharge(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1150 {
1151 smprintf(s, "Incoming battery level received???: %i\n",
1152 msg->Buffer[9]*100/7);
1153 return ERR_NONE;
1154 }
1155
N6510_ReplyGetBatteryCharge(GSM_Protocol_Message * msg,GSM_StateMachine * s)1156 static GSM_Error N6510_ReplyGetBatteryCharge(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1157 {
1158 GSM_Phone_Data *Data = &s->Phone.Data;
1159
1160 Data->BatteryCharge->BatteryPercent = ((int)(msg->Buffer[9]*100/msg->Buffer[8]));
1161 Data->BatteryCharge->ChargeState = 0;
1162
1163 smprintf(s, "Battery level received: %i\n",
1164 Data->BatteryCharge->BatteryPercent);
1165
1166 return ERR_NONE;
1167 }
1168
N6510_GetBatteryCharge(GSM_StateMachine * s,GSM_BatteryCharge * bat)1169 static GSM_Error N6510_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat)
1170 {
1171 unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x02, 0x00};
1172
1173 GSM_ClearBatteryCharge(bat);
1174 s->Phone.Data.BatteryCharge = bat;
1175 smprintf(s, "Getting battery level\n");
1176 return GSM_WaitFor (s, req, 6, 0x17, s->Phone.Data.Priv.N6510.Timeout, ID_GetBatteryCharge);
1177 }
1178
N6510_ReplyGetWAPBookmark(GSM_Protocol_Message * msg,GSM_StateMachine * s)1179 static GSM_Error N6510_ReplyGetWAPBookmark(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1180 {
1181 return DCT3DCT4_ReplyGetWAPBookmark (msg, s, TRUE);
1182 }
1183
N6510_ReplyGetOperatorLogo(GSM_Protocol_Message * msg,GSM_StateMachine * s)1184 static GSM_Error N6510_ReplyGetOperatorLogo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1185 {
1186 GSM_Phone_Data *Data = &s->Phone.Data;
1187
1188 if (msg->Buffer[3] == 0xf0) return ERR_NOTSUPPORTED;
1189
1190 smprintf(s, "Operator logo received\n");
1191 if (msg->Length <= 18) {
1192 smprintf(s, "Packet too short to contain operator logo\n");
1193 return ERR_EMPTY;
1194 }
1195 NOKIA_DecodeNetworkCode(msg->Buffer+12,Data->Bitmap->NetworkCode);
1196 smprintf(s, "Network code %s\n",Data->Bitmap->NetworkCode);
1197 Data->Bitmap->BitmapWidth = msg->Buffer[20];
1198 Data->Bitmap->BitmapHeight = msg->Buffer[21];
1199 PHONE_DecodeBitmap(GSM_Nokia6510OperatorLogo,msg->Buffer+26,Data->Bitmap);
1200 return ERR_NONE;
1201 }
1202
N6510_ReplyDeleteMemory(GSM_Protocol_Message * msg,GSM_StateMachine * s)1203 GSM_Error N6510_ReplyDeleteMemory(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1204 {
1205 if (msg->Buffer[5] == 0x1) {
1206 switch (msg->Buffer[6]) {
1207 case 0x0f:
1208 switch (msg->Buffer[10]) {
1209 case 0x21:
1210 smprintf(s, "Still busy processing the last command\n");
1211 return ERR_BUSY;
1212 case 0x3B:
1213 smprintf(s, "Nothing to delete\n");
1214 return ERR_NONE;
1215 case 0x33:
1216 smprintf(s, "Entry is read only\n");
1217 return ERR_READ_ONLY;
1218 default:
1219 smprintf(s, "ERROR: unknown 0x%x\n", msg->Buffer[10]);
1220 return ERR_UNKNOWNRESPONSE;
1221 }
1222 }
1223 }
1224 smprintf(s, "Phonebook entry deleted\n");
1225 return ERR_NONE;
1226 }
1227
N6510_DeleteMemory(GSM_StateMachine * s,GSM_MemoryEntry * entry)1228 GSM_Error N6510_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1229 {
1230 unsigned char req[] = {N7110_FRAME_HEADER, 0x0f, 0x55, 0x01,
1231 0x04, 0x55, 0x00, 0x10, 0xFF, 0x02,
1232 0x00, 0x01, /* location */
1233 0x00, 0x00, 0x00, 0x00,
1234 0x05, /* memory type */
1235 0x55, 0x55, 0x55};
1236
1237 req[12] = entry->Location / 256;
1238 req[13] = entry->Location % 256;
1239
1240 req[18] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
1241 if (req[18]==0xff) return ERR_NOTSUPPORTED;
1242
1243 smprintf(s, "Deleting phonebook entry\n");
1244 return GSM_WaitFor (s, req, 22, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_SetMemory);
1245 }
1246
N6510_SetMemory(GSM_StateMachine * s,GSM_MemoryEntry * entry)1247 static GSM_Error N6510_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1248 {
1249 int count = 22;
1250 size_t blocks;
1251 unsigned char req[5000] = {
1252 N7110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x10, 0x02,
1253 0x00, /* memory type */
1254 0x00, 0x00, /* location */
1255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1256 0x00}; /* Number of blocks */
1257 GSM_Error error;
1258 GSM_MemoryEntry tmp;
1259 GSM_MemoryStatus status;
1260 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1261
1262 if (entry->Location == 0) {
1263 /*
1264 * We want to remember last location so that we don't check the
1265 * same place again and again.
1266 */
1267 if (Priv->LastFreeMemoryType != entry->MemoryType) {
1268 Priv->LastFreeMemoryLocation = 0;
1269 Priv->LastFreeMemoryType = entry->MemoryType;
1270 status.MemoryType = entry->MemoryType;
1271 error = N6510_GetMemoryStatus(s, &status);
1272 if (error != ERR_NONE) return error;
1273 Priv->LastFreeMemorySize = status.MemoryUsed + status.MemoryFree;
1274 }
1275
1276 /* Advance beyond last used location */
1277 tmp.MemoryType = entry->MemoryType;
1278 error = ERR_NONE;
1279 for (tmp.Location = Priv->LastFreeMemoryLocation + 1;
1280 tmp.Location < Priv->LastFreeMemorySize;
1281 tmp.Location++) {
1282 error = N6510_GetMemory(s, &tmp);
1283 if (error != ERR_NONE) break;
1284 }
1285 if (error == ERR_NONE) {
1286 /* Memory full */
1287 return ERR_FULL;
1288 } else if (error != ERR_EMPTY) {
1289 /* Other failure */
1290 return error;
1291 }
1292 /* We've got the location */
1293 entry->Location = tmp.Location;
1294 smprintf(s, "Found empty location: %d\n", entry->Location);
1295 }
1296
1297 req[11] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
1298 if (req[11]==0xff) return ERR_NOTSUPPORTED;
1299
1300 req[12] = entry->Location / 256;
1301 req[13] = entry->Location % 256;
1302
1303 count = count + N71_65_EncodePhonebookFrame(s, req+22, entry, &blocks, TRUE, GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_VOICETAGS));
1304 req[21] = blocks;
1305
1306 smprintf(s, "Writing phonebook entry\n");
1307 return GSM_WaitFor (s, req, count, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_SetMemory);
1308 }
1309
N6510_AddMemory(GSM_StateMachine * s,GSM_MemoryEntry * entry)1310 static GSM_Error N6510_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1311 {
1312 entry->Location = 0;
1313 return N6510_SetMemory(s, entry);
1314 }
1315
N6510_ReplySetOperatorLogo(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)1316 static GSM_Error N6510_ReplySetOperatorLogo(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
1317 {
1318 smprintf(s, "Operator logo set OK\n");
1319 return ERR_NONE;
1320 }
1321
N6510_SetCallerLogo(GSM_StateMachine * s,GSM_Bitmap * bitmap)1322 static GSM_Error N6510_SetCallerLogo(GSM_StateMachine *s, GSM_Bitmap *bitmap)
1323 {
1324 char string[500];
1325 int block=0, i;
1326 size_t Width, Height;
1327 unsigned int count = 22;
1328 unsigned char req[500] = {
1329 N6110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x10,
1330 0xfe, 0x00, /* memory type */
1331 0x00, 0x00, /* location */
1332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1333
1334 /* Set memory type */
1335 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1336 req[11] = MEM6510_CG2;
1337 } else {
1338 req[11] = MEM7110_CG;
1339 }
1340
1341 req[13] = bitmap->Location;
1342
1343 /* Enabling/disabling logo */
1344 if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1345 string[0] = bitmap->BitmapEnabled?1:0;
1346 string[1] = 0;
1347 count += N71_65_PackPBKBlock(s, N7110_PBK_LOGOON, 2, block++, string, req + count);
1348 }
1349
1350 /* Ringtone */
1351 if (!bitmap->DefaultRingtone) {
1352 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1353 string[0] = 0x00;
1354 string[1] = 0x00;
1355 string[2] = 0x00;
1356 string[3] = 0x10;
1357 string[4] = 0x00;
1358 string[5] = 0x00;
1359 string[6] = bitmap->RingtoneID;
1360 string[7] = 0x00;
1361 string[8] = 0x00;
1362 string[9] = 0x00;
1363 count += N71_65_PackPBKBlock(s, N6510_PBK_RINGTONEFILE_ID, 10, block++, string, req + count);
1364 req[count - 1] = 0x01;
1365 } else if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PBKTONEGAL)) {
1366 /* do nothing ? */
1367 } else {
1368 string[0] = 0x00;
1369 string[1] = 0x00;
1370 string[2] = bitmap->RingtoneID;
1371 count += N71_65_PackPBKBlock(s, N7110_PBK_RINGTONE_ID, 3, block++, string, req + count);
1372 count --;
1373 req[count-5] = 8;
1374 }
1375 }
1376
1377 /* Number of group */
1378 if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1379 string[0] = bitmap->Location;
1380 string[1] = 0;
1381 count += N71_65_PackPBKBlock(s, N7110_PBK_GROUP, 2, block++, string, req + count);
1382 }
1383
1384 /* Name */
1385 if (!bitmap->DefaultName) {
1386 i = UnicodeLength(bitmap->Text) * 2;
1387 string[0] = i + 2;
1388 memcpy(string + 1, bitmap->Text, i);
1389 string[i + 1] = 0;
1390 count += N71_65_PackPBKBlock(s, N7110_PBK_NAME, i + 2, block++, string, req + count);
1391 }
1392
1393 /* Logo */
1394 if (!bitmap->DefaultBitmap) {
1395 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1396 /* write N6510_PBK_PICTURE_ID ? */
1397 } else {
1398 PHONE_GetBitmapWidthHeight(GSM_NokiaCallerLogo, &Width, &Height);
1399 string[0] = Width;
1400 string[1] = Height;
1401 string[2] = 0;
1402 string[3] = 0;
1403 string[4] = PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0);
1404 PHONE_EncodeBitmap(GSM_NokiaCallerLogo, string + 5, bitmap);
1405 count += N71_65_PackPBKBlock(s, N7110_PBK_GROUPLOGO, PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 5, block++, string, req + count);
1406 }
1407 }
1408
1409 req[21] = block;
1410
1411 return GSM_WaitFor (s, req, count, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1412 }
1413
N6510_ReplySetPicture(GSM_Protocol_Message * msg,GSM_StateMachine * s)1414 static GSM_Error N6510_ReplySetPicture(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1415 {
1416 smprintf(s, "Picture Image written OK, folder %i, location %i\n",msg->Buffer[4],msg->Buffer[5]*256+msg->Buffer[6]);
1417 return ERR_NONE;
1418 }
1419
N6510_SetBitmap(GSM_StateMachine * s,GSM_Bitmap * Bitmap)1420 static GSM_Error N6510_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
1421 {
1422 GSM_SMSMessage sms;
1423 GSM_Phone_Bitmap_Types Type;
1424 size_t Width, Height, i, count;
1425 unsigned char folderid;
1426 unsigned int location;
1427 GSM_NetworkInfo NetInfo;
1428 GSM_Error error;
1429 unsigned char reqStartup[1000] = {
1430 N7110_FRAME_HEADER, 0x04, 0x0F,
1431 0x00, 0x00, 0x00,
1432 0x04, 0xC0, 0x02, 0x00,
1433 0x41, 0xC0, 0x03, 0x00,
1434 0x60, 0xC0, 0x04};
1435 unsigned char reqColourWallPaper[200] = {
1436 N6110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0xD5,
1437 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1438 0x00, 0x00, 0x00, 0x01, 0x00,
1439 0x18}; /* Bitmap ID */
1440 unsigned char reqColourStartup[200] = {
1441 N6110_FRAME_HEADER, 0x04, 0x25, 0x00, 0x01, 0x00, 0x18};
1442 unsigned char reqOp[1000] = {
1443 N7110_FRAME_HEADER, 0x25, 0x01,
1444 0x55, 0x00, 0x00, 0x55,
1445 0x01, /* 0x01 - not set, 0x02 - set */
1446 0x0C, 0x08,
1447 0x62, 0xF0, 0x10, /* Network code */
1448 0x03, 0x55, 0x55};
1449 unsigned char reqColourOp[200] = {
1450 N6110_FRAME_HEADER,
1451 0x07, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x00, 0xF9, 0x00,
1452 0x08, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00,
1453 0x18, /* File ID */
1454 0x00,
1455 0x00, 0x00, 0x00}; /* Network code */
1456 unsigned char reqNote[200] = {N6110_FRAME_HEADER, 0x04, 0x01};
1457 unsigned char reqPicture[2000] = {
1458 N6110_FRAME_HEADER, 0x00,
1459 0x02, 0x05, /* SMS folder */
1460 0x00, 0x00, /* location */
1461 0x01, 0x01, 0xa0, 0x02, 0x01, 0x40, 0x00, 0x34,
1462 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1463 0x00, 0x00, 0x55, 0x55, 0x55, 0x03, 0x82, 0x10,
1464 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x10,
1466 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04,
1468 0x00, 0x00, 0xa1, 0x55, 0x01, 0x08, 0x00, 0x00,
1469 0x00, 0x01, 0x48, 0x1c, 0x00, 0xfc, 0x00};
1470
1471 switch (Bitmap->Type) {
1472 case GSM_ColourWallPaper_ID:
1473 reqColourWallPaper[21] = Bitmap->ID;
1474 smprintf(s, "Setting colour wall paper\n");
1475 return GSM_WaitFor (s, reqColourWallPaper, 22, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1476 case GSM_StartupLogo:
1477 Type = GSM_Nokia7110StartupLogo;
1478 switch (Bitmap->Location) {
1479 case 1: PHONE_EncodeBitmap(Type, reqStartup + 22, Bitmap);
1480 break;
1481 case 2: memset(reqStartup+5,0x00,15);
1482 PHONE_ClearBitmap(Type, reqStartup + 22,0,0);
1483 break;
1484 default: return ERR_NOTSUPPORTED;
1485 }
1486 smprintf(s, "Setting startup logo\n");
1487 return GSM_WaitFor (s, reqStartup, 22+PHONE_GetBitmapSize(Type,0,0), 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1488 case GSM_DealerNote_Text:
1489 reqNote[4] = 0x10;
1490 CopyUnicodeString(reqNote + 5, Bitmap->Text);
1491 i = 6 + UnicodeLength(Bitmap->Text) * 2;
1492 reqNote[i++] = 0;
1493 reqNote[i] = 0;
1494 return GSM_WaitFor (s, reqNote, i, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1495 case GSM_WelcomeNote_Text:
1496 CopyUnicodeString(reqNote + 5, Bitmap->Text);
1497 i = 6 + UnicodeLength(Bitmap->Text) * 2;
1498 reqNote[i++] = 0;
1499 reqNote[i] = 0;
1500 return GSM_WaitFor (s, reqNote, i, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1501 case GSM_OperatorLogo:
1502 /* We want to set operator logo, not clear */
1503 if (strcmp(Bitmap->NetworkCode,"000 00")) {
1504 memset(reqOp + 19, 0, 281);
1505 NOKIA_EncodeNetworkCode(reqOp+12, Bitmap->NetworkCode);
1506 Type = GSM_Nokia6510OperatorLogo;
1507 reqOp[9] = 0x02; /* Logo enabled */
1508 reqOp[18] = 0x1a; /* FIXME */
1509 reqOp[19] = PHONE_GetBitmapSize(Type,0,0) + 8 + 29 + 2;
1510 PHONE_GetBitmapWidthHeight(Type, &Width, &Height);
1511 reqOp[20] = Width;
1512 reqOp[21] = Height;
1513 reqOp[22] = 0x00;
1514 reqOp[23] = PHONE_GetBitmapSize(Type,0,0) + 29;
1515 reqOp[24] = 0x00;
1516 reqOp[25] = PHONE_GetBitmapSize(Type,0,0) + 29;
1517 PHONE_EncodeBitmap(Type, reqOp + 26, Bitmap);
1518 smprintf(s, "Setting operator logo\n");
1519 return GSM_WaitFor (s, reqOp, reqOp[19]+reqOp[11]+10, 0x0A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1520 } else {
1521 error=N6510_GetNetworkInfo(s,&NetInfo);
1522 if (error != ERR_NONE) return error;
1523 NOKIA_EncodeNetworkCode(reqOp+12, NetInfo.NetworkCode);
1524 smprintf(s, "Clearing operator logo\n");
1525 return GSM_WaitFor (s, reqOp, 18, 0x0A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1526 }
1527 case GSM_ColourOperatorLogo_ID:
1528 /* We want to set operator logo, not clear */
1529 if (strcmp(Bitmap->NetworkCode,"000 00")) {
1530 EncodeBCD(reqColourOp+23, Bitmap->NetworkCode, 6, FALSE);
1531 reqColourOp[21] = Bitmap->ID;
1532 }
1533 smprintf(s, "Setting colour operator logo\n");
1534 return GSM_WaitFor (s, reqColourOp, 26, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1535 case GSM_ColourStartupLogo_ID:
1536 switch (Bitmap->Location) {
1537 case 0: reqColourStartup[6] = 0x00;
1538 reqColourStartup[8] = 0x00;
1539 smprintf(s, "Setting colour startup logo\n");
1540 return GSM_WaitFor (s, reqColourStartup, 9, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1541 case 1: reqColourStartup[8] = Bitmap->ID;
1542 smprintf(s, "Setting colour startup logo\n");
1543 return GSM_WaitFor (s, reqColourStartup, 9, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1544 default:return ERR_NOTSUPPORTED;
1545 }
1546 case GSM_CallerGroupLogo:
1547 return N6510_SetCallerLogo(s,Bitmap);
1548 case GSM_PictureImage:
1549 error = N6510_GetPictureImage(s, Bitmap, &sms.Location);
1550 if (error == ERR_NONE) {
1551 sms.Folder = 0;
1552 N6510_GetSMSLocation(s, &sms, &folderid, &location);
1553 switch (folderid) {
1554 case 0x01: reqPicture[5] = 0x02; break; /* INBOX SIM */
1555 case 0x02: reqPicture[5] = 0x03; break; /* OUTBOX SIM */
1556 default : reqPicture[5] = folderid - 1; reqPicture[4] = 0x02; break; /* ME folders */
1557 }
1558 reqPicture[6]=location / 256;
1559 reqPicture[7]=location;
1560 }
1561 Type = GSM_NokiaPictureImage;
1562 count = 78;
1563 PHONE_EncodeBitmap(Type, reqPicture + count, Bitmap);
1564 count += PHONE_GetBitmapSize(Type,0,0);
1565 smprintf(s, "Setting Picture Image\n");
1566 return GSM_WaitFor (s, reqPicture, count, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1567 default:
1568 break;
1569 }
1570 return ERR_NOTSUPPORTED;
1571 }
1572
N6510_ReplyGetRingtoneID(GSM_Protocol_Message * msg,GSM_StateMachine * s)1573 static GSM_Error N6510_ReplyGetRingtoneID(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1574 {
1575 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1576
1577 smprintf(s, "Ringtone ID received\n");
1578 Priv->RingtoneID = msg->Buffer[15];
1579 return ERR_NONE;
1580 }
1581
N6510_ReplySetBinRingtone(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)1582 static GSM_Error N6510_ReplySetBinRingtone(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
1583 {
1584 smprintf(s, "Binary ringtone set\n");
1585 return ERR_NONE;
1586 }
1587
N6510_SetRingtone(GSM_StateMachine * s,GSM_Ringtone * Ringtone,int * maxlength)1588 static GSM_Error N6510_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
1589 {
1590 GSM_Error error;
1591 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1592 GSM_NetworkInfo NetInfo;
1593 size_t size=200, current;
1594 unsigned char GetIDReq[] = {
1595 N7110_FRAME_HEADER, 0x01, 0x00, 0x00,
1596 0x00, 0xFF, 0x06, 0xE1, 0x00,
1597 0xFF, 0x06, 0xE1, 0x01, 0x42};
1598 unsigned char SetPreviewReq[1000] = {
1599 0xAE, /* Ringtone ID */
1600 0x01, 0x00, 0x0D, 0x00,
1601 0x00, 0x00, 0x00, 0x00, 0x00,
1602 0x00}; /*Length*/
1603 unsigned char AddBinaryReq[33000] = {
1604 N7110_FRAME_HEADER, 0x0E, 0x7F, 0xFF, 0xFE};
1605
1606 if (Ringtone->Format == RING_NOTETONE && Ringtone->Location==255)
1607 {
1608 smprintf(s, "Getting ringtone ID\n");
1609 error=GSM_WaitFor (s, GetIDReq, 14, 0xDB, s->Phone.Data.Priv.N6510.Timeout, ID_SetRingtone);
1610 if (error != ERR_NONE) return error;
1611 *maxlength=GSM_EncodeNokiaRTTLRingtone(Ringtone, SetPreviewReq+11, &size);
1612 SetPreviewReq[0] = Priv->RingtoneID;
1613 SetPreviewReq[10] = size;
1614 smprintf(s, "Setting ringtone\n");
1615 error = s->Protocol.Functions->WriteMessage(s, SetPreviewReq, size+11, 0x00);
1616 if (error!=ERR_NONE) return error;
1617 sleep(1);
1618 /* We have to make something (not important, what) now */
1619 /* no answer from phone*/
1620 return s->Phone.Functions->GetNetworkInfo(s,&NetInfo);
1621 }
1622 if (Ringtone->Format == RING_NOKIABINARY) {
1623 AddBinaryReq[7] = UnicodeLength(Ringtone->Name);
1624 CopyUnicodeString(AddBinaryReq+8,Ringtone->Name);
1625 current = 8 + UnicodeLength(Ringtone->Name)*2;
1626 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length/256 + 1;
1627 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length%256 + 1;
1628 AddBinaryReq[current++] = 0x00;
1629 memcpy(AddBinaryReq+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length);
1630 current += Ringtone->NokiaBinary.Length;
1631 smprintf(s, "Adding binary ringtone\n");
1632 return GSM_WaitFor (s, AddBinaryReq, current, 0x1F, s->Phone.Data.Priv.N6510.Timeout, ID_SetRingtone);
1633 }
1634 if (Ringtone->Format == RING_MIDI) {
1635 AddBinaryReq[7] = UnicodeLength(Ringtone->Name);
1636 CopyUnicodeString(AddBinaryReq+8,Ringtone->Name);
1637 current = 8 + UnicodeLength(Ringtone->Name)*2;
1638 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length/256;
1639 AddBinaryReq[current++] = Ringtone->NokiaBinary.Length%256;
1640 memcpy(AddBinaryReq+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length);
1641 current += Ringtone->NokiaBinary.Length;
1642 AddBinaryReq[current++] = 0x00;
1643 AddBinaryReq[current++] = 0x00;
1644 smprintf(s, "Adding binary or MIDI ringtone\n");
1645 return GSM_WaitFor (s, AddBinaryReq, current, 0x1F, s->Phone.Data.Priv.N6510.Timeout, ID_SetRingtone);
1646 }
1647 return ERR_NOTSUPPORTED;
1648 }
1649
N6510_ReplyDeleteRingtones(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)1650 static GSM_Error N6510_ReplyDeleteRingtones(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
1651 {
1652 smprintf(s, "Ringtones deleted\n");
1653 return ERR_NONE;
1654 }
1655
N6510_DeleteUserRingtones(GSM_StateMachine * s)1656 static GSM_Error N6510_DeleteUserRingtones(GSM_StateMachine *s)
1657 {
1658 unsigned char DelAllRingtoneReq[] = {N7110_FRAME_HEADER, 0x10, 0x7F, 0xFE};
1659
1660 smprintf(s, "Deleting all user ringtones\n");
1661 return GSM_WaitFor (s, DelAllRingtoneReq, 6, 0x1F, s->Phone.Data.Priv.N6510.Timeout, ID_SetRingtone);
1662 }
1663
N6510_ReplyPressKey(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)1664 static GSM_Error N6510_ReplyPressKey(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
1665 {
1666 if (msg->Buffer[3] == 0x33) {
1667 smprintf(s, "Key auto released\n");
1668 } else if (msg->Buffer[3] == 0x12) {
1669 smprintf(s, "Key pressed\n");
1670 } else {
1671 return ERR_UNKNOWN;
1672 }
1673 return ERR_NONE;
1674 }
1675
N6510_PressKey(GSM_StateMachine * s,GSM_KeyCode Key,gboolean Press)1676 static GSM_Error N6510_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, gboolean Press)
1677 {
1678 unsigned char req[] = {N6110_FRAME_HEADER, 0x11, 0x00, 0x01, 0x00, 0x00,
1679 0x00, /* Event */
1680 0x01}; /* Number of presses */
1681
1682 if (Key != GSM_KEY_GREEN) {
1683 smprintf(s, "Mapping for key code %d missing!\n", Key);
1684 return ERR_NOTIMPLEMENTED;
1685 }
1686
1687 req[7] = Key;
1688 if (Press) {
1689 req[8] = NOKIA_PRESSPHONEKEY;
1690 s->Phone.Data.PressKey = TRUE;
1691 smprintf(s, "Pressing key\n");
1692 } else {
1693 req[8] = NOKIA_RELEASEPHONEKEY;
1694 s->Phone.Data.PressKey = FALSE;
1695 smprintf(s, "Releasing key\n");
1696 }
1697 return GSM_WaitFor (s, req, 10, 0x0c, s->Phone.Data.Priv.N6510.Timeout, ID_PressKey);
1698 }
1699
N6510_EnableConnectionFunctions(GSM_StateMachine * s,N6510_Connection_Settings Type)1700 static GSM_Error N6510_EnableConnectionFunctions(GSM_StateMachine *s, N6510_Connection_Settings Type)
1701 {
1702 GSM_Error error;
1703 unsigned char req2[] = {N6110_FRAME_HEADER, 0x00, 0x01};
1704 unsigned char req3[] = {N6110_FRAME_HEADER, 0x00, 0x03};
1705 unsigned char req4[] = {N6110_FRAME_HEADER, 0x00, 0x04};
1706
1707 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iWAP)) return ERR_NOTSUPPORTED;
1708
1709 if (Type == N6510_MMS_SETTINGS && GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOMMS)) return ERR_NOTSUPPORTED;
1710 if (Type == N6510_CHAT_SETTINGS && !GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CHAT)) return ERR_NOTSUPPORTED;
1711 if (Type == N6510_SYNCML_SETTINGS && !GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SYNCML)) return ERR_NOTSUPPORTED;
1712
1713 error=DCT3DCT4_DisableConnectionFunctions(s);
1714 if (error!=ERR_NONE) return error;
1715
1716 switch (Type) {
1717 case N6510_WAP_SETTINGS:
1718 return DCT3DCT4_EnableWAPFunctions(s);
1719 case N6510_MMS_SETTINGS:
1720 smprintf(s, "Enabling MMS\n");
1721 return GSM_WaitFor (s, req2, 5, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_EnableConnectFunc);
1722 case N6510_SYNCML_SETTINGS:
1723 smprintf(s, "Enabling SyncML\n");
1724 return GSM_WaitFor (s, req3, 5, 0x3f, 5, ID_EnableConnectFunc);
1725 case N6510_CHAT_SETTINGS:
1726 smprintf(s, "Enabling Chat\n");
1727 return GSM_WaitFor (s, req4, 5, 0x3f, 5, ID_EnableConnectFunc);
1728 default:
1729 return ERR_UNKNOWN;
1730 }
1731 }
1732
N6510_ReplyGetConnectionSettings(GSM_Protocol_Message * msg,GSM_StateMachine * s)1733 static GSM_Error N6510_ReplyGetConnectionSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1734 {
1735 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1736 int tmp,num=0,i;
1737 GSM_Phone_Data *Data = &s->Phone.Data;
1738 unsigned char buff[2000];
1739
1740 switch(msg->Buffer[3]) {
1741 case 0x16:
1742 smprintf(s, "Connection settings received OK\n");
1743
1744 Data->WAPSettings->Number = Priv->BearerNumber;
1745
1746 Data->WAPSettings->Proxy[0] = 0x00;
1747 Data->WAPSettings->Proxy[1] = 0x00;
1748 Data->WAPSettings->ProxyPort = 8080;
1749
1750 Data->WAPSettings->Proxy2[0] = 0x00;
1751 Data->WAPSettings->Proxy2[1] = 0x00;
1752 Data->WAPSettings->Proxy2Port = 8080;
1753
1754 tmp = 4;
1755
1756 NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].Title,TRUE);
1757 CopyUnicodeString(Data->WAPSettings->Settings[1].Title,Data->WAPSettings->Settings[0].Title);
1758 smprintf(s, "Title: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Title));
1759
1760 NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].HomePage,TRUE);
1761 CopyUnicodeString(Data->WAPSettings->Settings[1].HomePage,Data->WAPSettings->Settings[0].HomePage);
1762 smprintf(s, "Homepage: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].HomePage));
1763
1764 #ifdef DEBUG
1765 smprintf(s, "Connection type: ");
1766 switch (msg->Buffer[tmp]) {
1767 case 0x00: smprintf(s, "temporary\n"); break;
1768 case 0x01: smprintf(s, "continuous\n"); break;
1769 default: smprintf(s, "unknown\n");
1770 }
1771 smprintf(s, "Connection security: ");
1772 switch (msg->Buffer[tmp+1]) {
1773 case 0x00: smprintf(s, "off\n"); break;
1774 case 0x01: smprintf(s, "on\n"); break;
1775 default: smprintf(s, "unknown\n");
1776 }
1777 smprintf(s, "Bearer: ");
1778 switch (msg->Buffer[tmp+2]) {
1779 case 0x01: smprintf(s, "GSM data\n"); break;
1780 case 0x03: smprintf(s, "GPRS\n"); break;
1781 default: smprintf(s, "unknown\n");
1782 }
1783 if (msg->Buffer[tmp+3] == 0x01) smprintf(s, "locked\n");
1784 #endif
1785 Data->WAPSettings->Settings[0].IsContinuous = FALSE;
1786 if (msg->Buffer[tmp] == 0x01) Data->WAPSettings->Settings[0].IsContinuous = TRUE;
1787 Data->WAPSettings->Settings[1].IsContinuous = Data->WAPSettings->Settings[0].IsContinuous;
1788
1789 Data->WAPSettings->Settings[0].IsSecurity = FALSE;
1790 if (msg->Buffer[tmp+1] == 0x01) Data->WAPSettings->Settings[0].IsSecurity = TRUE;
1791 Data->WAPSettings->Settings[1].IsSecurity = Data->WAPSettings->Settings[0].IsSecurity;
1792
1793 Data->WAPSettings->ActiveBearer = WAPSETTINGS_BEARER_DATA;
1794 if (msg->Buffer[tmp+2] == 0x03) Data->WAPSettings->ActiveBearer = WAPSETTINGS_BEARER_GPRS;
1795
1796 Data->WAPSettings->ReadOnly = FALSE;
1797 if (msg->Buffer[tmp+3] == 0x01) Data->WAPSettings->ReadOnly = TRUE;
1798
1799 tmp+=3;
1800
1801 if (Priv->BearerNumber == 2) {
1802 /* Here starts settings for data bearer */
1803 Data->WAPSettings->Settings[0].Bearer = WAPSETTINGS_BEARER_DATA;
1804 while ((msg->Buffer[tmp] != 0x01) || (msg->Buffer[tmp + 1] != 0x00)) tmp++;
1805 tmp += 4;
1806
1807 #ifdef DEBUG
1808 smprintf(s, "Authentication type: ");
1809 switch (msg->Buffer[tmp]) {
1810 case 0x00: smprintf(s, "normal\n"); break;
1811 case 0x01: smprintf(s, "secure\n"); break;
1812 default: smprintf(s, "unknown\n"); break;
1813 }
1814 smprintf(s, "Data call type: ");
1815 switch (msg->Buffer[tmp+1]) {
1816 case 0x00: smprintf(s, "analogue\n"); break;
1817 case 0x01: smprintf(s, "ISDN\n"); break;
1818 default: smprintf(s, "unknown\n"); break;
1819 }
1820 smprintf(s, "Data call speed: ");
1821 switch (msg->Buffer[tmp+2]) {
1822 case 0x00: smprintf(s, "automatic\n"); break;
1823 case 0x01: smprintf(s, "9600\n"); break;
1824 case 0x02: smprintf(s, "14400\n"); break;
1825 default: smprintf(s, "unknown\n"); break;
1826 }
1827 smprintf(s, "Login Type: ");
1828 switch (msg->Buffer[tmp+4]) {
1829 case 0x00: smprintf(s, "manual\n"); break;
1830 case 0x01: smprintf(s, "automatic\n"); break;
1831 default: smprintf(s, "unknown\n"); break;
1832 }
1833 #endif
1834 Data->WAPSettings->Settings[0].IsNormalAuthentication=TRUE;
1835 if (msg->Buffer[tmp]==0x01) Data->WAPSettings->Settings[0].IsNormalAuthentication=FALSE;
1836
1837 Data->WAPSettings->Settings[0].IsISDNCall=FALSE;
1838 if (msg->Buffer[tmp+1]==0x01) Data->WAPSettings->Settings[0].IsISDNCall=TRUE;
1839
1840 switch (msg->Buffer[tmp+2]) {
1841 case 0x00: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_AUTO; break;
1842 case 0x01: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_9600; break;
1843 case 0x02: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_14400; break;
1844 default:
1845 smprintf(s, "Unknown speed settings: 0x%0x\n", msg->Buffer[tmp+2]);
1846 Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_AUTO;
1847 break;
1848 }
1849
1850 Data->WAPSettings->Settings[0].ManualLogin=FALSE;
1851 if (msg->Buffer[tmp+4]==0x00) Data->WAPSettings->Settings[0].ManualLogin = TRUE;
1852
1853 tmp+=5;
1854
1855 NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].IPAddress,FALSE);
1856 smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].IPAddress));
1857
1858 NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].DialUp,TRUE);
1859 smprintf(s, "Dial-up number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].DialUp));
1860
1861 NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].User,TRUE);
1862 smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].User));
1863
1864 NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].Password,TRUE);
1865 smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Password));
1866
1867 num = 1;
1868 } else {
1869 num = 0;
1870 }
1871
1872 /* Here starts settings for gprs bearer */
1873 Data->WAPSettings->Settings[num].Bearer = WAPSETTINGS_BEARER_GPRS;
1874 while (msg->Buffer[tmp] != 0x03) tmp++;
1875 tmp += 4;
1876
1877 #ifdef DEBUG
1878 smprintf(s, "Authentication type: ");
1879 switch (msg->Buffer[tmp]) {
1880 case 0x00: smprintf(s, "normal\n"); break;
1881 case 0x01: smprintf(s, "secure\n"); break;
1882 default: smprintf(s, "unknown\n"); break;
1883 }
1884 smprintf(s, "GPRS connection: ");
1885 switch (msg->Buffer[tmp+1]) {
1886 case 0x00: smprintf(s, "ALWAYS online\n"); break;
1887 case 0x01: smprintf(s, "when needed\n"); break;
1888 default: smprintf(s, "unknown\n"); break;
1889 }
1890 smprintf(s, "Login Type: ");
1891 switch (msg->Buffer[tmp+2]) {
1892 case 0x00: smprintf(s, "manual\n"); break;
1893 case 0x01: smprintf(s, "automatic\n"); break;
1894 default: smprintf(s, "unknown\n"); break;
1895 }
1896 #endif
1897 Data->WAPSettings->Settings[num].IsNormalAuthentication=TRUE;
1898 if (msg->Buffer[tmp]==0x01) Data->WAPSettings->Settings[num].IsNormalAuthentication=FALSE;
1899
1900 Data->WAPSettings->Settings[num].IsISDNCall=FALSE;
1901 Data->WAPSettings->Settings[num].Speed = WAPSETTINGS_SPEED_AUTO;
1902
1903 Data->WAPSettings->Settings[num].IsContinuous = TRUE;
1904 if (msg->Buffer[tmp+1] == 0x01) Data->WAPSettings->Settings[num].IsContinuous = FALSE;
1905
1906 Data->WAPSettings->Settings[num].ManualLogin=FALSE;
1907 if (msg->Buffer[tmp+2]==0x00) Data->WAPSettings->Settings[num].ManualLogin = TRUE;
1908
1909 tmp+=3;
1910
1911 NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[num].DialUp,FALSE);
1912 smprintf(s, "Access point: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].DialUp));
1913
1914 NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[num].IPAddress,TRUE);
1915 smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].IPAddress));
1916
1917 NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[num].User,TRUE);
1918 smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].User));
1919
1920 NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[num].Password,TRUE);
1921 smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].Password));
1922
1923 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) {
1924 if (msg->Buffer[tmp] == 0x00 && msg->Buffer[tmp+1] == 0x00) tmp = tmp+2;
1925
1926 memcpy(buff,msg->Buffer+tmp+10,msg->Buffer[tmp+4]);
1927 buff[msg->Buffer[tmp+4]] = 0x00;
1928 smprintf(s, "Proxy 1: \"%s\", port %i\n",buff,msg->Buffer[tmp+6]*256+msg->Buffer[tmp+7]);
1929 EncodeUnicode(Data->WAPSettings->Proxy,buff,strlen(buff));
1930 Data->WAPSettings->ProxyPort = msg->Buffer[tmp+6]*256+msg->Buffer[tmp+7];
1931
1932 memcpy(buff,msg->Buffer+tmp+10+msg->Buffer[tmp+4],msg->Buffer[tmp+5]);
1933 buff[msg->Buffer[tmp+5]] = 0x00;
1934 smprintf(s, "Proxy 2: \"%s\", port %i\n",buff,msg->Buffer[tmp+8]*256+msg->Buffer[tmp+9]);
1935 EncodeUnicode(Data->WAPSettings->Proxy2,buff,strlen(buff));
1936 Data->WAPSettings->Proxy2Port = msg->Buffer[tmp+8]*256+msg->Buffer[tmp+9];
1937
1938 tmp = tmp + msg->Buffer[tmp+3] + 19;
1939
1940 for (i=0;i<4;i++) {
1941 #ifdef DEBUG
1942 smprintf(s, "Proxy data %i\n",i+1);
1943 if (msg->Buffer[tmp+2]!=0) memcpy(buff,msg->Buffer+tmp+9,msg->Buffer[tmp+2]*2);
1944 buff[msg->Buffer[tmp+2]*2] =0;
1945 buff[msg->Buffer[tmp+2]*2+1]=0;
1946 smprintf(s, "IP: \"%s\"",DecodeUnicodeString(buff));
1947 smprintf(s, ", port %i\n",msg->Buffer[tmp+3]*256+msg->Buffer[tmp+4]);
1948 #endif
1949 tmp = tmp + msg->Buffer[tmp];
1950 }
1951
1952 #ifdef DEBUG
1953 smprintf(s, "%02x %02x\n",msg->Buffer[tmp],msg->Buffer[tmp+1]);
1954 smprintf(s, "Port %i\n",msg->Buffer[tmp+3]*256+msg->Buffer[tmp+4]);
1955 tmp = tmp + msg->Buffer[tmp];
1956 #endif
1957 }
1958
1959 return ERR_NONE;
1960 case 0xf0:
1961 /*
1962 * Don't know exactly what 0x0f means, but the message is too short
1963 * to contain information:
1964 *
1965 * 01 |58X|00 |F0 |01 |15 |00 |00 |00 |00
1966 */
1967 smprintf(s, "Connection settings receiving error, assuming empty\n");
1968 return ERR_EMPTY;
1969 case 0x11:
1970 case 0x17:
1971 smprintf(s, "Connection settings receiving error\n");
1972 switch (msg->Buffer[4]) {
1973 case 0x01:
1974 smprintf(s, "Security error. Inside phone settings menu\n");
1975 return ERR_INSIDEPHONEMENU;
1976 case 0x02:
1977 case 0x03: /* Guess */
1978 smprintf(s, "Invalid or empty\n");
1979 return ERR_INVALIDLOCATION;
1980 default:
1981 smprintf(s, "ERROR: unknown %i\n",msg->Buffer[4]);
1982 return ERR_UNKNOWNRESPONSE;
1983 }
1984 }
1985 return ERR_UNKNOWNRESPONSE;
1986 }
1987
N6510_GetConnectionSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings,N6510_Connection_Settings Type)1988 static GSM_Error N6510_GetConnectionSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings, N6510_Connection_Settings Type)
1989 {
1990 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1991 GSM_Error error;
1992 unsigned char req[] = {N6110_FRAME_HEADER, 0x15,
1993 0x00}; /* Location */
1994
1995 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) return ERR_NOTSUPPORTED;
1996 if (!strcmp(s->Phone.Data.ModelInfo->model,"6020")) return ERR_NOTSUPPORTED;
1997
1998 error = N6510_EnableConnectionFunctions(s, Type);
1999 if (error!=ERR_NONE) return error;
2000
2001 req[4] = settings->Location-1;
2002 s->Phone.Data.WAPSettings = settings;
2003
2004 switch (Type) {
2005 case N6510_MMS_SETTINGS:
2006 smprintf(s, "Getting MMS settings\n");
2007 Priv->BearerNumber = 1;
2008 break;
2009 case N6510_WAP_SETTINGS:
2010 smprintf(s, "Getting WAP settings\n");
2011 Priv->BearerNumber = 2;
2012 break;
2013 case N6510_SYNCML_SETTINGS:
2014 smprintf(s, "Getting SyncML settings\n");
2015 Priv->BearerNumber = 2;
2016 break;
2017 case N6510_CHAT_SETTINGS:
2018 smprintf(s, "Getting Chat settings\n");
2019 Priv->BearerNumber = 1;
2020 break;
2021 }
2022
2023 error=GSM_WaitFor (s, req, 5, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_GetConnectSet);
2024 if (error != ERR_NONE) {
2025 if (error == ERR_INVALIDLOCATION || error == ERR_INSIDEPHONEMENU) {
2026 DCT3DCT4_DisableConnectionFunctions(s);
2027 }
2028 return error;
2029 }
2030
2031 error=DCT3DCT4_GetActiveConnectSet(s);
2032 if (error != ERR_NONE) return error;
2033
2034 return DCT3DCT4_DisableConnectionFunctions(s);
2035 }
2036
N6510_GetWAPSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings)2037 static GSM_Error N6510_GetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2038 {
2039 return N6510_GetConnectionSettings(s, settings, N6510_WAP_SETTINGS);
2040 }
2041
N6510_GetMMSSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings)2042 static GSM_Error N6510_GetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2043 {
2044 return N6510_GetConnectionSettings(s, settings, N6510_MMS_SETTINGS);
2045 }
2046
N6510_ReplyGetSyncMLSettings(GSM_Protocol_Message * msg,GSM_StateMachine * s)2047 static GSM_Error N6510_ReplyGetSyncMLSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2048 {
2049 GSM_SyncMLSettings *Sett = s->Phone.Data.SyncMLSettings;
2050
2051 smprintf(s, "SyncML settings received OK\n");
2052 CopyUnicodeString(Sett->User,msg->Buffer+18);
2053 CopyUnicodeString(Sett->Password,msg->Buffer+86);
2054 CopyUnicodeString(Sett->PhonebookDataBase,msg->Buffer+130);
2055 CopyUnicodeString(Sett->CalendarDataBase,msg->Buffer+234);
2056 CopyUnicodeString(Sett->Server,msg->Buffer+338);
2057
2058 Sett->SyncPhonebook = FALSE;
2059 Sett->SyncCalendar = FALSE;
2060 if ((msg->Buffer[598] & 0x02)==0x02) Sett->SyncCalendar = TRUE;
2061 if ((msg->Buffer[598] & 0x01)==0x01) Sett->SyncPhonebook = TRUE;
2062
2063 return ERR_NONE;
2064 }
2065
N6510_ReplyGetSyncMLName(GSM_Protocol_Message * msg,GSM_StateMachine * s)2066 static GSM_Error N6510_ReplyGetSyncMLName(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2067 {
2068 GSM_SyncMLSettings *Sett = s->Phone.Data.SyncMLSettings;
2069
2070 smprintf(s, "SyncML names received OK\n");
2071
2072 CopyUnicodeString(Sett->Name,msg->Buffer+18);
2073
2074 return ERR_NONE;
2075 }
2076
N6510_GetSyncMLSettings(GSM_StateMachine * s,GSM_SyncMLSettings * settings)2077 static GSM_Error N6510_GetSyncMLSettings(GSM_StateMachine *s, GSM_SyncMLSettings *settings)
2078 {
2079 GSM_Error error;
2080 /* unsigned char NameReq[] = {N6110_FRAME_HEADER, 0x05, */
2081 /* 0x00, 0x00, 0x00, 0x31, 0x00, */
2082 /* 0x06, 0x00, 0x00, 0x00, 0xDE, 0x00, 0x00}; */
2083 /* unsigned char GetActive[] = {N6110_FRAME_HEADER, 0x05, */
2084 /* 0x00, 0x00, 0x00, 0x31, 0x00, */
2085 /* 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; */
2086 unsigned char req[] = {N6110_FRAME_HEADER, 0x05,
2087 0x00, 0x00, 0x00, 0x31, 0x00,
2088 0x01, /* location */
2089 0x00, 0x00, 0x02, 0x46, 0x00, 0x00};
2090
2091 settings->Connection.Location = settings->Location;
2092 error = N6510_GetConnectionSettings(s, &settings->Connection, N6510_SYNCML_SETTINGS);
2093 if (error != ERR_NONE) return error;
2094
2095 settings->Active = settings->Connection.Active;
2096
2097 settings->Name[0] = 0;
2098 settings->Name[1] = 0;
2099 s->Phone.Data.SyncMLSettings = settings;
2100
2101 /* smprintf(s, "Getting SyncML settings name\n"); */
2102 /* error = GSM_WaitFor (s, NameReq, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_GetSyncMLName); */
2103 /* if (error != ERR_NONE) return error; */
2104
2105 req[9] = settings->Location - 1;
2106 smprintf(s, "Getting additional SyncML settings\n");
2107 return GSM_WaitFor (s, req, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_GetSyncMLSettings);
2108 }
2109
N6510_ReplyGetChatSettings(GSM_Protocol_Message * msg,GSM_StateMachine * s)2110 static GSM_Error N6510_ReplyGetChatSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2111 {
2112 GSM_ChatSettings *Sett = s->Phone.Data.ChatSettings;
2113 int i;
2114
2115 Sett->Name[0] = 0;
2116 Sett->Name[1] = 0;
2117 Sett->HomePage[0] = 0;
2118 Sett->HomePage[1] = 0;
2119 Sett->User[0] = 0;
2120 Sett->User[1] = 0;
2121 Sett->Password[0] = 0;
2122 Sett->Password[1] = 0;
2123
2124 switch(msg->Buffer[3]) {
2125 case 0x3B:
2126 smprintf(s, "Chat settings received OK\n");
2127 memcpy(Sett->Name,msg->Buffer+20,msg->Buffer[12]*2);
2128 Sett->Name[msg->Buffer[12]*2] = 0;
2129 Sett->Name[msg->Buffer[12]*2+1] = 0;
2130 memcpy(Sett->HomePage,msg->Buffer+20+msg->Buffer[12]*2,msg->Buffer[15]*2);
2131 Sett->HomePage[msg->Buffer[15]*2] = 0;
2132 Sett->HomePage[msg->Buffer[15]*2+1] = 0;
2133 i = msg->Buffer[12]*2 + msg->Buffer[15]*2 + 29;
2134 memcpy(Sett->User,msg->Buffer+i+3,msg->Buffer[i]*2);
2135 Sett->User[msg->Buffer[i]*2] = 0;
2136 Sett->User[msg->Buffer[i]*2+1] = 0;
2137 memcpy(Sett->Password,msg->Buffer+i+3+msg->Buffer[i]*2,msg->Buffer[i+1]*2);
2138 Sett->Password[msg->Buffer[i+1]*2] = 0;
2139 Sett->Password[msg->Buffer[i+1]*2+1] = 0;
2140 return ERR_NONE;
2141 case 0x3C:
2142 smprintf(s, "Empty chat settings received\n");
2143 return ERR_NONE;
2144 }
2145 return ERR_UNKNOWNRESPONSE;
2146 }
2147
N6510_GetChatSettings(GSM_StateMachine * s,GSM_ChatSettings * settings)2148 static GSM_Error N6510_GetChatSettings(GSM_StateMachine *s, GSM_ChatSettings *settings)
2149 {
2150 GSM_Error error;
2151 unsigned char req[] = {N6110_FRAME_HEADER, 0x3a,
2152 0x09, /* location */
2153 0x01, 0x0e};
2154
2155 settings->Connection.Location = settings->Location;
2156 error = N6510_GetConnectionSettings(s, &settings->Connection, N6510_CHAT_SETTINGS);
2157 if (error != ERR_NONE) return error;
2158
2159 settings->Active = settings->Connection.Active;
2160
2161 s->Phone.Data.ChatSettings = settings;
2162 req[4] = settings->Location - 1;
2163 smprintf(s, "Getting additional Chat settings\n");
2164 return GSM_WaitFor (s, req, 7, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_GetChatSettings);
2165 }
2166
N6510_ReplySetConnectionSettings(GSM_Protocol_Message * msg,GSM_StateMachine * s)2167 static GSM_Error N6510_ReplySetConnectionSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2168 {
2169 switch (msg->Buffer[3]) {
2170 case 0x19:
2171 smprintf(s, "Connection settings cleaned\n");
2172 return ERR_NONE;
2173 case 0x1a:
2174 smprintf(s, "Connection settings setting status\n");
2175 switch (msg->Buffer[4]) {
2176 case 0x01:
2177 smprintf(s, "Security error. Inside phone settings menu\n");
2178 return ERR_INSIDEPHONEMENU;
2179 case 0x03:
2180 smprintf(s, "Invalid location\n");
2181 return ERR_INVALIDLOCATION;
2182 case 0x05:
2183 smprintf(s, "Written OK\n");
2184 return ERR_NONE;
2185 default:
2186 smprintf(s, "ERROR: unknown %i\n",msg->Buffer[4]);
2187 return ERR_UNKNOWNRESPONSE;
2188 }
2189 case 0x28:
2190 case 0x2B:
2191 smprintf(s, "Set OK\n");
2192 return ERR_NONE;
2193 }
2194 return ERR_UNKNOWNRESPONSE;
2195 }
2196
N6510_SetConnectionSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings,N6510_Connection_Settings Type)2197 static GSM_Error N6510_SetConnectionSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings, N6510_Connection_Settings Type)
2198 {
2199 GSM_Error error;
2200 int i, pad = 0, length, pos = 5, loc1=-1,loc2=-1,port;
2201 unsigned char *Proxy;
2202 unsigned char req[2000] = {N6110_FRAME_HEADER, 0x18,
2203 0x00}; /* Location */
2204 unsigned char Lock[5] = {N6110_FRAME_HEADER, 0x27,
2205 0x00}; /* Location */
2206 unsigned char UnLock[5] = {N6110_FRAME_HEADER, 0x2A,
2207 0x00}; /* Location */
2208
2209 error = N6510_EnableConnectionFunctions(s, Type);
2210 if (error!=ERR_NONE) return error;
2211
2212 memset(req + pos, 0, 1000 - pos);
2213
2214 req[4] = settings->Location-1;
2215
2216 for (i=0;i<settings->Number;i++) {
2217 if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_DATA) loc1=i;
2218 if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_GPRS) loc2=i;
2219 }
2220
2221 if (loc1 != -1) {
2222 /* Name */
2223 length = UnicodeLength(settings->Settings[loc1].Title);
2224 if (!(length % 2)) pad = 1;
2225 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].Title, FALSE);
2226
2227 /* Home */
2228 length = UnicodeLength(settings->Settings[loc1].HomePage);
2229 if (((length + pad) % 2)) pad = 2; else pad = 0;
2230 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].HomePage, TRUE);
2231
2232 if (settings->Settings[loc1].IsContinuous) {
2233 req[pos] = 0x01;
2234 }
2235 pos++;
2236 if (settings->Settings[loc1].IsSecurity) {
2237 req[pos] = 0x01;
2238 }
2239 pos++;
2240 } else if (loc2 != -1) {
2241 /* Name */
2242 length = UnicodeLength(settings->Settings[loc2].Title);
2243 if (!(length % 2)) pad = 1;
2244 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].Title, FALSE);
2245
2246 /* Home */
2247 length = UnicodeLength(settings->Settings[loc2].HomePage);
2248 if (((length + pad) % 2)) pad = 2; else pad = 0;
2249 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].HomePage, TRUE);
2250
2251 if (settings->Settings[loc2].IsContinuous) {
2252 req[pos] = 0x01;
2253 }
2254 pos++;
2255 if (settings->Settings[loc2].IsSecurity) {
2256 req[pos] = 0x01;
2257 }
2258 pos++;
2259 } else {
2260 /* Name */
2261 length = 0;
2262 if (!(length % 2)) pad = 1;
2263 pos ++;
2264
2265 /* Home */
2266 length = 0;
2267 if (((length + pad) % 2)) pad = 2; else pad = 0;
2268 pos += 2;
2269
2270 pos += 2;
2271 }
2272
2273 if (Type == N6510_MMS_SETTINGS || Type == N6510_CHAT_SETTINGS) {
2274 req[pos++] = 0x03; /* active bearer: GPRS */
2275 } else {
2276 if (settings->ActiveBearer == WAPSETTINGS_BEARER_GPRS && loc2 != -1) {
2277 req[pos++] = 0x03; /* active bearer: GPRS */
2278 } else {
2279 req[pos++] = 0x01; /* active bearer: data set */
2280 }
2281 }
2282
2283 /* Number of sent bearers */
2284 if (Type == N6510_MMS_SETTINGS || Type == N6510_CHAT_SETTINGS) {
2285 req[pos] = 0x01;
2286 } else {
2287 req[pos] = 0x02;
2288 }
2289 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) req[pos] += 2;
2290 pos++;
2291 pos += pad;
2292
2293 if (Type != N6510_MMS_SETTINGS && Type != N6510_CHAT_SETTINGS) {
2294 /* GSM data block */
2295 memcpy(req + pos, "\x01\x00", 2); pos += 2;
2296
2297 if (loc1 != -1) {
2298 length = UnicodeLength(settings->Settings[loc1].IPAddress)*2+1;
2299 length += UnicodeLength(settings->Settings[loc1].DialUp) *2+2;
2300 length += UnicodeLength(settings->Settings[loc1].User) *2+2;
2301 length += UnicodeLength(settings->Settings[loc1].Password) *2+2;
2302 } else {
2303 length = 1 + 2 + 2 + 2;
2304 }
2305 length += 11;
2306 req[pos++] = length / 256;
2307 req[pos++] = length % 256;
2308
2309 if (loc1 != -1) {
2310 if (!settings->Settings[loc1].IsNormalAuthentication) {
2311 req[pos]=0x01;
2312 }
2313 pos++;
2314 if (settings->Settings[loc1].IsISDNCall) {
2315 req[pos]=0x01;
2316 }
2317 pos++;
2318 switch (settings->Settings[loc1].Speed) {
2319 case WAPSETTINGS_SPEED_AUTO : break;
2320 case WAPSETTINGS_SPEED_9600 : req[pos]=0x01; break;
2321 case WAPSETTINGS_SPEED_14400 : req[pos]=0x02; break;
2322 }
2323 pos++;
2324 req[pos++]=0x01;
2325 if (!settings->Settings[loc1].ManualLogin) {
2326 req[pos] = 0x01;
2327 }pos++;
2328
2329 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].IPAddress, FALSE);
2330 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].DialUp, TRUE);
2331 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].User, TRUE);
2332 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].Password, TRUE);
2333 } else {
2334 pos += 3;
2335 req[pos++]=0x01;
2336 pos += 8;
2337 }
2338
2339 /* Padding */
2340 pos+=2;
2341 }
2342
2343 /* GPRS block */
2344 memcpy(req + pos, "\x03\x00", 2); pos += 2;
2345
2346 if (loc2 != -1) {
2347 length = UnicodeLength(settings->Settings[loc2].DialUp) *2+1;
2348 length += UnicodeLength(settings->Settings[loc2].IPAddress)*2+2;
2349 length += UnicodeLength(settings->Settings[loc2].User) *2+2;
2350 length += UnicodeLength(settings->Settings[loc2].Password) *2+2;
2351 } else {
2352 length = 7;
2353 }
2354 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) length+=2;
2355 length += 7;
2356 req[pos++] = length / 256;
2357 req[pos++] = length % 256;
2358
2359 if (loc2 != -1) {
2360 if (!settings->Settings[loc2].IsNormalAuthentication) {
2361 req[pos] = 0x01;
2362 }
2363 pos++;
2364 if (!settings->Settings[loc2].IsContinuous) {
2365 req[pos] = 0x01;
2366 }
2367 pos++;
2368 if (!settings->Settings[loc2].ManualLogin) {
2369 req[pos] = 0x01;
2370 }
2371 pos++;
2372
2373 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].DialUp, FALSE);
2374 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].IPAddress, TRUE);
2375 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].User, TRUE);
2376 pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].Password, TRUE);
2377 } else {
2378 pos += 10;
2379 }
2380
2381 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) {
2382 req[pos++] = 0x00;
2383 req[pos++] = 0x00;
2384
2385 /* Proxy block */
2386 req[pos++] = 0x06;
2387 req[pos++] = 0x01;
2388 if (UnicodeLength(settings->Proxy)!=0 ||
2389 UnicodeLength(settings->Proxy2)!=0) {
2390 req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+13)/256;
2391 req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+13)%256;
2392 } else {
2393 req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+12)/256;
2394 req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+12)%256;
2395 }
2396 req[pos++] = UnicodeLength(settings->Proxy);
2397 req[pos++] = UnicodeLength(settings->Proxy2);
2398 req[pos++] = settings->ProxyPort/256;
2399 req[pos++] = settings->ProxyPort%256;
2400 req[pos++] = settings->Proxy2Port/256;
2401 req[pos++] = settings->Proxy2Port%256;
2402 if (UnicodeLength(settings->Proxy)!=0) {
2403 sprintf(req+pos,"%s",DecodeUnicodeString(settings->Proxy));
2404 pos+=UnicodeLength(settings->Proxy);
2405 }
2406 if (UnicodeLength(settings->Proxy2)!=0) {
2407 sprintf(req+pos,"%s",DecodeUnicodeString(settings->Proxy2));
2408 pos+=UnicodeLength(settings->Proxy2);
2409 }
2410 if (UnicodeLength(settings->Proxy)!=0 ||
2411 UnicodeLength(settings->Proxy2)!=0) {
2412 req[pos++] = 0x00;
2413 }
2414 req[pos++] = 0x00; req[pos++] = 0x00;
2415 req[pos++] = 0x07; /* unknown */
2416 req[pos++] = 0x00; req[pos++] = 0x00;
2417 req[pos++] = 0x80; /* unknown */
2418 req[pos++] = 0x01; /* unknown */
2419 req[pos++] = 0x05; /* unknown */
2420 req[pos++] = 0x00; req[pos++] = 0x00;
2421
2422 /* Proxy data blocks */
2423 for (i=0;i<4;i++) {
2424 port = 8080;
2425 Proxy = NULL;
2426 if (i==0) {
2427 port = settings->ProxyPort;
2428 Proxy = settings->Proxy;
2429 } else if (i==1) {
2430 port = settings->Proxy2Port;
2431 Proxy = settings->Proxy2;
2432 }
2433 req[pos++] = 0x08; req[pos++] = 0x00;
2434 if (Proxy != NULL && UnicodeLength(Proxy)!=0) {
2435 if (UnicodeLength(Proxy)%2 != 0) {
2436 req[pos++] = (12 + (UnicodeLength(Proxy)+1)*2)/256;
2437 req[pos++] = (12 + (UnicodeLength(Proxy)+1)*2)%256;
2438 } else {
2439 req[pos++] = (12 + UnicodeLength(Proxy)*2)/256;
2440 req[pos++] = (12 + UnicodeLength(Proxy)*2)%256;
2441 }
2442 } else {
2443 req[pos++] = 12/256;
2444 req[pos++] = 12%256;
2445 }
2446 req[pos++] = i+1;
2447 if (Proxy != NULL) {
2448 req[pos++] = UnicodeLength(Proxy);
2449 } else {
2450 req[pos++] = 0;
2451 }
2452 req[pos++] = port/256;
2453 req[pos++] = port%256;
2454 req[pos++] = 0x00;
2455
2456 req[pos++] = 0x00;
2457 req[pos++] = 0x01;
2458
2459 req[pos++] = 0x00;
2460 if (Proxy != NULL && UnicodeLength(Proxy)!=0) {
2461 CopyUnicodeString(req+pos,Proxy);
2462 pos+=UnicodeLength(Proxy)*2;
2463 if (UnicodeLength(Proxy)%2 != 0) {
2464 req[pos++] = 0x00;
2465 req[pos++] = 0x00;
2466 }
2467 }
2468 }
2469
2470 req[pos++] = 0x09; req[pos++] = 0x00; req[pos++] = 0x00;
2471 req[pos++] = 0x0C; req[pos++] = 0x02; req[pos++] = 0x00;
2472 req[pos++] = 0x00; req[pos++] = 0x02; req[pos++] = 0x00;
2473 req[pos++] = 0x00; req[pos++] = 0x00; req[pos++] = 0x00;
2474 } else {
2475 /* end of blocks ? */
2476 memcpy(req + pos, "\x80\x00\x00\x0c", 4); pos += 4;
2477 }
2478
2479 UnLock[4] = settings->Location-1;
2480 smprintf(s, "Making Connection settings read-write\n");
2481 error = GSM_WaitFor (s, UnLock, 5, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_SetConnectSet);
2482 if (error != ERR_NONE) return error;
2483
2484 switch (Type) {
2485 case N6510_MMS_SETTINGS:
2486 smprintf(s, "Setting MMS settings\n");
2487 break;
2488 case N6510_CHAT_SETTINGS:
2489 smprintf(s, "Setting Chat settings\n");
2490 break;
2491 case N6510_WAP_SETTINGS:
2492 smprintf(s, "Setting WAP settings\n");
2493 break;
2494 case N6510_SYNCML_SETTINGS:
2495 smprintf(s, "Setting SyncML settings\n");
2496 break;
2497 }
2498 error = GSM_WaitFor (s, req, pos, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_SetConnectSet);
2499 if (error != ERR_NONE) {
2500 if (error == ERR_INSIDEPHONEMENU || error == ERR_INVALIDLOCATION) {
2501 DCT3DCT4_DisableConnectionFunctions(s);
2502 }
2503 return error;
2504 }
2505
2506 if (settings->ReadOnly) {
2507 Lock[4] = settings->Location-1;
2508 smprintf(s, "Making Connection settings readonly\n");
2509 error = GSM_WaitFor (s, Lock, 5, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_SetConnectSet);
2510 if (error != ERR_NONE) return error;
2511 }
2512
2513 error = DCT3DCT4_SetActiveConnectSet(s, settings);
2514 if (error != ERR_NONE) return error;
2515
2516 return DCT3DCT4_DisableConnectionFunctions(s);
2517 }
2518
N6510_SetWAPSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings)2519 static GSM_Error N6510_SetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2520 {
2521 return N6510_SetConnectionSettings(s, settings, N6510_WAP_SETTINGS);
2522 }
2523
N6510_SetMMSSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings)2524 static GSM_Error N6510_SetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2525 {
2526 return N6510_SetConnectionSettings(s, settings, N6510_MMS_SETTINGS);
2527 }
2528
N6510_ReplyGetOriginalIMEI(GSM_Protocol_Message * msg,GSM_StateMachine * s)2529 static GSM_Error N6510_ReplyGetOriginalIMEI(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2530 {
2531 if (msg->Buffer[7] == 0x00) {
2532 smprintf(s, "No SIM card\n");
2533 return ERR_NOSIM;
2534 } else {
2535 return NOKIA_ReplyGetPhoneString(msg, s);
2536 }
2537 }
2538
N6510_GetOriginalIMEI(GSM_StateMachine * s,char * value)2539 static GSM_Error N6510_GetOriginalIMEI(GSM_StateMachine *s, char *value)
2540 {
2541 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) return ERR_NOTSUPPORTED;
2542
2543 return NOKIA_GetPhoneString(s,"\x00\x07\x02\x01\x00\x01",6,0x42,value,ID_GetOriginalIMEI,14);
2544 }
2545
N6510_ReplyGetSMSStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)2546 static GSM_Error N6510_ReplyGetSMSStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2547 {
2548 GSM_Phone_Data *Data = &s->Phone.Data;
2549
2550 switch (msg->Buffer[3]) {
2551 case 0x09:
2552 switch (msg->Buffer[4]) {
2553 case 0x00:
2554 smprintf(s, "Max. in phone memory : %i\n",msg->Buffer[10]*256+msg->Buffer[11]);
2555 smprintf(s, "Used in phone memory : %i\n",msg->Buffer[12]*256+msg->Buffer[13]);
2556 smprintf(s, "Unread in phone memory : %i\n",msg->Buffer[14]*256+msg->Buffer[15]);
2557 smprintf(s, "Max. in SIM : %i\n",msg->Buffer[22]*256+msg->Buffer[23]);
2558 smprintf(s, "Used in SIM : %i\n",msg->Buffer[24]*256+msg->Buffer[25]);
2559 smprintf(s, "Unread in SIM : %i\n",msg->Buffer[26]*256+msg->Buffer[27]);
2560 Data->SMSStatus->PhoneSize = msg->Buffer[10]*256+msg->Buffer[11];
2561 Data->SMSStatus->PhoneUsed = msg->Buffer[12]*256+msg->Buffer[13];
2562 Data->SMSStatus->PhoneUnRead = msg->Buffer[14]*256+msg->Buffer[15];
2563 Data->SMSStatus->SIMSize = msg->Buffer[22]*256+msg->Buffer[23];
2564 Data->SMSStatus->SIMUsed = msg->Buffer[24]*256+msg->Buffer[25];
2565 Data->SMSStatus->SIMUnRead = msg->Buffer[26]*256+msg->Buffer[27];
2566 return ERR_NONE;
2567 case 0x0f:
2568 smprintf(s, "No PIN\n");
2569 return ERR_SECURITYERROR;
2570 default:
2571 smprintf(s, "ERROR: unknown SMS status %i\n",msg->Buffer[4]);
2572 return ERR_UNKNOWNRESPONSE;
2573 }
2574 case 0x1a:
2575 smprintf(s, "Wait a moment. Phone is during power on and busy now\n");
2576 return ERR_SECURITYERROR;
2577 case 0xf0:
2578 /* 01 |00 |00 |F0ð|01 |12 |00 |00 |00 */
2579 smprintf(s, "Handling of this reply is not known, please help!\n");
2580 return ERR_NOTIMPLEMENTED;
2581 }
2582 return ERR_UNKNOWNRESPONSE;
2583 }
2584
N6510_GetSMSStatus(GSM_StateMachine * s,GSM_SMSMemoryStatus * status)2585 static GSM_Error N6510_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status)
2586 {
2587 GSM_Error error;
2588 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
2589 unsigned char req[] = {N6110_FRAME_HEADER, 0x08, 0x00, 0x00};
2590
2591 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) return ERR_NOTSUPPORTED;
2592
2593 s->Phone.Data.SMSStatus=status;
2594 smprintf(s, "Getting SMS status\n");
2595 error = GSM_WaitFor (s, req, 6, 0x14, 20, ID_GetSMSStatus);
2596 if (error != ERR_NONE) return error;
2597
2598 /* DCT4 family doesn't show in frame with SMS status info
2599 * about Templates. We get separately info about this SMS folder.
2600 */
2601 error = N6510_GetSMSFolderStatus(s, 0x06);
2602 if (error != ERR_NONE) return error;
2603 status->TemplatesUsed = Priv->LastSMSFolder.Number;
2604
2605 return error;
2606 }
2607
N6510_ReplyDeleteSMSMessage(GSM_Protocol_Message * msg,GSM_StateMachine * s)2608 static GSM_Error N6510_ReplyDeleteSMSMessage(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2609 {
2610 switch (msg->Buffer[3]) {
2611 case 0x05:
2612 smprintf(s, "SMS deleted OK\n");
2613 return ERR_NONE;
2614 case 0x06:
2615 switch (msg->Buffer[4]) {
2616 case 0x02:
2617 smprintf(s, "Invalid location\n");
2618 return ERR_INVALIDLOCATION;
2619 default:
2620 smprintf(s, "Unknown error: %02x\n",msg->Buffer[4]);
2621 return ERR_UNKNOWNRESPONSE;
2622 }
2623 }
2624 return ERR_UNKNOWNRESPONSE;
2625 }
2626
N6510_DeleteSMSMessage(GSM_StateMachine * s,GSM_SMSMessage * sms)2627 static GSM_Error N6510_DeleteSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
2628 {
2629 unsigned char folderid;
2630 unsigned int location;
2631 unsigned char req[] = {N6110_FRAME_HEADER, 0x04,
2632 0x01, /* 0x01=SM, 0x02=ME */
2633 0x00, /* FolderID */
2634 0x00, 0x02, /* Location */
2635 0x0F, 0x55};
2636
2637 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2638 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMS_FILES)) return ERR_NOTSUPPORTED;
2639 }
2640
2641 N6510_GetSMSLocation(s, sms, &folderid, &location);
2642
2643 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2644 switch (folderid) {
2645 case 0x01: req[5] = 0x01; break; /* SIM */
2646 default : req[5] = folderid; req[4] = 0x02; break; /* ME folders */
2647 }
2648 } else {
2649 switch (folderid) {
2650 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
2651 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
2652 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */
2653 }
2654 }
2655 req[6]=location / 256;
2656 req[7]=location % 256;
2657
2658 smprintf(s, "Deleting sms\n");
2659 return GSM_WaitFor (s, req, 10, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_DeleteSMSMessage);
2660 }
2661
N6510_ReplySendSMSMessage(GSM_Protocol_Message * msg,GSM_StateMachine * s)2662 static GSM_Error N6510_ReplySendSMSMessage(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2663 {
2664 switch (msg->Buffer[8]) {
2665 case 0x00:
2666 smprintf(s, "SMS sent OK, TPMR for sent sms is %d\n",msg->Buffer[10]);
2667 if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s,0,msg->Buffer[10], s->User.SendSMSStatusUserData);
2668 return ERR_NONE;
2669 default:
2670 smprintf(s, "SMS not sent OK, error code probably %i\n",msg->Buffer[8]);
2671 if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s,msg->Buffer[8],msg->Buffer[10], s->User.SendSMSStatusUserData);
2672 return ERR_NONE;
2673 }
2674 }
2675
N6510_SendSMSMessage(GSM_StateMachine * s,GSM_SMSMessage * sms)2676 static GSM_Error N6510_SendSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
2677 {
2678 int length = 11;
2679 GSM_Error error;
2680 GSM_SMSMessageLayout Layout;
2681 unsigned char req [300] = {
2682 N6110_FRAME_HEADER, 0x02, 0x00, 0x00, 0x00, 0x55, 0x55};
2683
2684 if (sms->PDU == SMS_Deliver) sms->PDU = SMS_Submit;
2685 memset(req+9,0x00,sizeof(req) - 9);
2686 error=N6510_EncodeSMSFrame(s, sms, req + 9, &Layout, &length);
2687 if (error != ERR_NONE) return error;
2688
2689 smprintf(s, "Sending sms\n");
2690 return s->Protocol.Functions->WriteMessage(s, req, length + 9, 0x02);
2691 }
2692
N6510_ReplyGetSecurityStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)2693 static GSM_Error N6510_ReplyGetSecurityStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2694 {
2695 GSM_Phone_Data *Data = &s->Phone.Data;
2696
2697 if (msg->Buffer[3] == 0xf0) {
2698 return ERR_NOTSUPPORTED;
2699 }
2700
2701 smprintf(s, "Security Code status received: ");
2702 switch (msg->Buffer[4]) {
2703 case 0x01 : smprintf(s, "waiting for Security Code.\n"); *Data->SecurityStatus = SEC_SecurityCode; break;
2704 case 0x07 :
2705 case 0x02 : smprintf(s, "waiting for PIN.\n"); *Data->SecurityStatus = SEC_Pin; break;
2706 case 0x03 : smprintf(s, "waiting for PUK.\n"); *Data->SecurityStatus = SEC_Puk; break;
2707 case 0x05 : smprintf(s, "PIN ok, SIM ok\n"); *Data->SecurityStatus = SEC_None; break;
2708 case 0x06 : smprintf(s, "No input status\n"); *Data->SecurityStatus = SEC_None; break;
2709 case 0x16 : smprintf(s, "No SIM card\n"); return ERR_NOSIM;
2710 case 0x1A : smprintf(s, "SIM card rejected!\n"); *Data->SecurityStatus = SEC_None; break;
2711 default : smprintf(s, "ERROR: unknown %i\n",msg->Buffer[4]);
2712 return ERR_UNKNOWNRESPONSE;
2713 }
2714 return ERR_NONE;
2715 }
2716
N6510_GetSecurityStatus(GSM_StateMachine * s,GSM_SecurityCodeType * Status)2717 static GSM_Error N6510_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status)
2718 {
2719 unsigned char req[5] = {N6110_FRAME_HEADER, 0x11, 0x00};
2720
2721 s->Phone.Data.SecurityStatus=Status;
2722 smprintf(s, "Getting security code status\n");
2723 return GSM_WaitFor (s, req, 5, 0x08, 2, ID_GetSecurityStatus);
2724 }
2725
N6510_ReplyEnterSecurityCode(GSM_Protocol_Message * msg,GSM_StateMachine * s)2726 static GSM_Error N6510_ReplyEnterSecurityCode(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2727 {
2728 switch (msg->Buffer[3]) {
2729 case 0x08:
2730 smprintf(s, "Security code OK\n");
2731 return ERR_NONE;
2732 case 0x09:
2733 switch (msg->Buffer[4]) {
2734 case 0x06:
2735 smprintf(s, "Wrong PIN\n");
2736 return ERR_SECURITYERROR;
2737 case 0x09:
2738 smprintf(s, "Wrong PUK\n");
2739 return ERR_SECURITYERROR;
2740 default:
2741 smprintf(s, "ERROR: unknown security code status %i\n",msg->Buffer[4]);
2742 }
2743 }
2744 return ERR_UNKNOWNRESPONSE;
2745 }
2746
N6510_EnterSecurityCode(GSM_StateMachine * s,GSM_SecurityCode * Code)2747 static GSM_Error N6510_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode *Code)
2748 {
2749 int len = 0;
2750 unsigned char req[15] = {N6110_FRAME_HEADER, 0x07,
2751 0x00}; /* Code type */
2752
2753 switch (Code->Type) {
2754 case SEC_Pin : req[4] = 0x02; break;
2755 case SEC_Puk : req[4] = 0x03; break;/* FIXME */
2756 default : return ERR_NOTSUPPORTED;
2757 }
2758
2759 len = strlen(Code->Code);
2760 memcpy(req+5,Code->Code,len);
2761 req[5+len]=0x00;
2762
2763 smprintf(s, "Entering security code\n");
2764 return GSM_WaitFor (s, req, 6+len, 0x08, s->Phone.Data.Priv.N6510.Timeout, ID_EnterSecurityCode);
2765 }
2766
N6510_ReplySaveSMSMessage(GSM_Protocol_Message * msg,GSM_StateMachine * s)2767 static GSM_Error N6510_ReplySaveSMSMessage(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2768 {
2769 unsigned char folder;
2770 GSM_Phone_Data *Data = &s->Phone.Data;
2771
2772 switch (msg->Buffer[3]) {
2773 case 0x01:
2774 switch (msg->Buffer[4]) {
2775 case 0x00:
2776 smprintf(s, "Done OK\n");
2777 break;
2778 case 0x02:
2779 smprintf(s, "Incorrect location\n");
2780 return ERR_INVALIDLOCATION;
2781 case 0x03:
2782 smprintf(s, "Memory full (for example no empty space in SIM)\n");
2783 return ERR_FULL;
2784 case 0x05:
2785 smprintf(s, "Incorrect folder\n");
2786 return ERR_INVALIDLOCATION;
2787 default:
2788 smprintf(s, "ERROR: unknown reply on saving message %i\n",msg->Buffer[4]);
2789 return ERR_UNKNOWNRESPONSE;
2790 }
2791
2792 smprintf(s, "Folder info: %i %i\n",msg->Buffer[5],msg->Buffer[8]);
2793 Data->SaveSMSMessage->Memory = MEM_ME;
2794 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2795 folder = msg->Buffer[8];
2796 } else {
2797 folder = msg->Buffer[8] + 1;
2798 /* inbox,outbox */
2799 if (msg->Buffer[8] == 0x02 || msg->Buffer[8] == 0x03) {
2800 if (msg->Buffer[5] == 0x01) {
2801 folder = msg->Buffer[8] - 1;
2802 Data->SaveSMSMessage->Memory = MEM_SM;
2803 }
2804 }
2805 }
2806 N6510_SetSMSLocation(s, Data->SaveSMSMessage,folder,msg->Buffer[6]*256+msg->Buffer[7]);
2807 smprintf(s, "Saved in folder %i at location %i\n",folder, msg->Buffer[6]*256+msg->Buffer[7]);
2808 Data->SaveSMSMessage->Folder = folder;
2809 return ERR_NONE;
2810 case 0x17:
2811 smprintf(s, "SMS name changed\n");
2812 return ERR_NONE;
2813 }
2814 return ERR_UNKNOWNRESPONSE;
2815 }
2816
N6510_PrivSetSMSMessage(GSM_StateMachine * s,GSM_SMSMessage * sms)2817 static GSM_Error N6510_PrivSetSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
2818 {
2819 int length = 11;
2820 unsigned int location;
2821 unsigned char folderid, folder;
2822 GSM_SMSMessageLayout Layout;
2823 GSM_Error error;
2824 unsigned char req [300] = {
2825 N6110_FRAME_HEADER, 0x00,
2826 0x01, /* 1 = SIM, 2 = ME */
2827 0x02, /* Folder */
2828 0x00, 0x01, /* Location */
2829 0x01}; /* SMS state */
2830 unsigned char NameReq[200] = {
2831 N6110_FRAME_HEADER, 0x16,
2832 0x01, /* 1 = SIM, 2 = ME */
2833 0x02, /* Folder */
2834 0x00, 0x01}; /* Location */
2835
2836 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2837 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMS_FILES)) return ERR_NOTSUPPORTED;
2838 }
2839
2840 N6510_GetSMSLocation(s, sms, &folderid, &location);
2841 if (folderid == 0x99) return ERR_INVALIDLOCATION;
2842 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2843 switch (folderid) {
2844 case 0x02: req[4] = 0x02; req[5] = 0x02; break; /* inbox */
2845 /* sms saved to sent items make problems later during reading */
2846 /* case 0x03: req[4] = 0x02; req[5] = 0x03; break; //sent items */
2847 default : return ERR_NOTSUPPORTED; /* at least 6111 doesn't support saving to other */
2848 }
2849 } else {
2850 switch (folderid) {
2851 case 0x01: req[5] = 0x02; break; /* INBOX SIM */
2852 case 0x02: req[5] = 0x03; break; /* OUTBOX SIM */
2853 default : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders */
2854 }
2855 }
2856 req[6]=location / 256;
2857 req[7]=location % 256;
2858
2859 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2860 switch (sms->PDU) {
2861 case SMS_Status_Report: /* this is SMS submit with delivery report request */
2862 case SMS_Submit:
2863 break;
2864 case SMS_Deliver:
2865 /* Sent items */
2866 if (folderid == 0x03) sms->PDU = SMS_Submit;
2867 break;
2868 default:
2869 return ERR_UNKNOWN;
2870 }
2871 } else {
2872 switch (sms->PDU) {
2873 case SMS_Status_Report: /* this is SMS submit with delivery report request */
2874 case SMS_Submit:
2875 /* Inbox */
2876 if (folderid == 0x01 || folderid == 0x03) sms->PDU = SMS_Deliver;
2877 break;
2878 case SMS_Deliver:
2879 /* SIM Outbox */
2880 if (folderid == 0x02) sms->PDU = SMS_Submit;
2881 break;
2882 default:
2883 return ERR_UNKNOWN;
2884 }
2885 if (sms->PDU == SMS_Deliver) {
2886 switch (sms->State) {
2887 case SMS_Sent : /* We use GSM_Read, because phone return error */
2888 case SMS_Read : req[8] = 0x01; break;
2889 case SMS_UnSent : /* We use GSM_UnRead, because phone return error */
2890 case SMS_UnRead : req[8] = 0x03; break;
2891 }
2892 } else {
2893 switch (sms->State) {
2894 case SMS_Sent : /* We use GSM_Sent, because phone change folder */
2895 case SMS_Read : req[8] = 0x05; break;
2896 case SMS_UnSent : /* We use GSM_UnSent, because phone change folder */
2897 case SMS_UnRead : req[8] = 0x07; break;
2898 }
2899 }
2900 }
2901 memset(req+9,0x00,sizeof(req) - 9);
2902 error=N6510_EncodeSMSFrame(s, sms, req + 9, &Layout, &length);
2903 if (error != ERR_NONE) return error;
2904
2905 s->Phone.Data.SaveSMSMessage=sms;
2906 smprintf(s, "Saving sms\n");
2907 error=GSM_WaitFor (s, req, length+9, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_SaveSMSMessage);
2908 if (error != ERR_NONE) return error;
2909
2910 /* no adding to SIM SMS */
2911 if (UnicodeLength(sms->Name)==0 || sms->Folder < 3) return ERR_NONE;
2912
2913 folder = sms->Folder;
2914 sms->Folder = 0;
2915 N6510_GetSMSLocation(s, sms, &folderid, &location);
2916
2917 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2918 switch (folderid) {
2919 case 0x03: NameReq[4] = 0x02; NameReq[5] = 0x02; break; /* sent items */
2920 case 0x02: NameReq[4] = 0x02; NameReq[5] = 0x03; break; /* inbox */
2921 default : return ERR_NOTSUPPORTED; /* at least 6111 doesn't support saving to other */
2922 }
2923 } else {
2924 switch (folderid) {
2925 case 0x01: NameReq[5] = 0x02; break; /* INBOX SIM */
2926 case 0x02: NameReq[5] = 0x03; break; /* OUTBOX SIM */
2927 default : NameReq[5] = folderid - 1; NameReq[4] = 0x02; break; /* ME folders */
2928 }
2929 }
2930 NameReq[6]=location / 256;
2931 NameReq[7]=location % 256;
2932 length = 8;
2933 CopyUnicodeString(NameReq+length, sms->Name);
2934 length = length+UnicodeLength(sms->Name)*2;
2935 NameReq[length++] = 0;
2936 NameReq[length++] = 0;
2937 error=GSM_WaitFor (s, NameReq, length, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_SaveSMSMessage);
2938 sms->Folder = folder;
2939 return error;
2940 }
2941
N6510_SetSMS(GSM_StateMachine * s,GSM_SMSMessage * sms)2942 static GSM_Error N6510_SetSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2943 {
2944 unsigned int location;
2945 unsigned char folderid;
2946
2947 N6510_GetSMSLocation(s, sms, &folderid, &location);
2948 if (location == 0) return ERR_INVALIDLOCATION;
2949 return N6510_PrivSetSMSMessage(s, sms);
2950 }
2951
N6510_AddSMS(GSM_StateMachine * s,GSM_SMSMessage * sms)2952 static GSM_Error N6510_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2953 {
2954 unsigned int location;
2955 unsigned char folderid;
2956
2957 N6510_GetSMSLocation(s, sms, &folderid, &location);
2958 location = 0;
2959 N6510_SetSMSLocation(s, sms, folderid, location);
2960 return N6510_PrivSetSMSMessage(s, sms);
2961 }
2962
N6510_ReplyGetDateTime(GSM_Protocol_Message * msg,GSM_StateMachine * s)2963 static GSM_Error N6510_ReplyGetDateTime(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2964 {
2965 smprintf(s, "Date & time received\n");
2966 if (msg->Buffer[4]==0x01) {
2967 NOKIA_DecodeDateTime(s, msg->Buffer+10, s->Phone.Data.DateTime, TRUE, FALSE);
2968 return ERR_NONE;
2969 }
2970 smprintf(s, "Not set in phone\n");
2971 return ERR_EMPTY;
2972 }
2973
N6510_GetDateTime(GSM_StateMachine * s,GSM_DateTime * date_time)2974 static GSM_Error N6510_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
2975 {
2976 unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x00, 0x00};
2977
2978 s->Phone.Data.DateTime=date_time;
2979 smprintf(s, "Getting date & time\n");
2980 return GSM_WaitFor (s, req, 6, 0x19, s->Phone.Data.Priv.N6510.Timeout, ID_GetDateTime);
2981 }
2982
N6510_ReplySetDateTime(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)2983 static GSM_Error N6510_ReplySetDateTime(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
2984 {
2985 smprintf(s, "Date & time set\n");
2986 return ERR_NONE;
2987 }
2988
N6510_SetDateTime(GSM_StateMachine * s,GSM_DateTime * date_time)2989 static GSM_Error N6510_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
2990 {
2991 unsigned char req[] = {N6110_FRAME_HEADER,
2992 0x01, 0x00, 0x01, 0x01, 0x0c, 0x01, 0x03,
2993 0x00, 0x00, /* Year */
2994 0x08, 0x01, /* Month & Day */
2995 0x15, 0x1f, /* Hours & Minutes */
2996 0x2b, /* Second ? */
2997 0x00};
2998
2999 NOKIA_EncodeDateTime(s, req+10, date_time);
3000 req[16] = date_time->Second;
3001 smprintf(s, "Setting date & time\n");
3002 return GSM_WaitFor (s, req, 18, 0x19, s->Phone.Data.Priv.N6510.Timeout, ID_SetDateTime);
3003 }
3004
N6510_ReplyGetManufactureMonth(GSM_Protocol_Message * msg,GSM_StateMachine * s)3005 static GSM_Error N6510_ReplyGetManufactureMonth(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3006 {
3007 if (msg->Buffer[7] == 0x00) {
3008 smprintf(s, "No SIM card\n");
3009 return ERR_NOSIM;
3010 } else {
3011 sprintf(s->Phone.Data.PhoneString,"%02i/%04i",msg->Buffer[13],msg->Buffer[14]*256+msg->Buffer[15]);
3012 return ERR_NONE;
3013 }
3014 }
3015
N6510_GetManufactureMonth(GSM_StateMachine * s,char * value)3016 static GSM_Error N6510_GetManufactureMonth(GSM_StateMachine *s, char *value)
3017 {
3018 unsigned char req[6] = {0x00, 0x05, 0x02, 0x01, 0x00, 0x02};
3019 /* unsigned char req[6] = {0x00, 0x03, 0x04, 0x0B, 0x01, 0x00}; */
3020
3021 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) return ERR_NOTSUPPORTED;
3022
3023 s->Phone.Data.PhoneString=value;
3024 smprintf(s, "Getting manufacture month\n");
3025 return GSM_WaitFor (s, req, 6, 0x42, 2, ID_GetManufactureMonth);
3026 /* return GSM_WaitFor (s, req, 6, 0x1B, 2, ID_GetManufactureMonth); */
3027 }
3028
N6510_ReplyGetAlarm(GSM_Protocol_Message * msg,GSM_StateMachine * s)3029 static GSM_Error N6510_ReplyGetAlarm(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3030 {
3031 GSM_Phone_Data *Data = &s->Phone.Data;
3032
3033 switch(msg->Buffer[3]) {
3034 case 0x1A:
3035 smprintf(s, " Alarm: %02d:%02d\n", msg->Buffer[14], msg->Buffer[15]);
3036 Data->Alarm->Repeating = TRUE;
3037 Data->Alarm->Text[0] = 0;
3038 Data->Alarm->Text[1] = 0;
3039 Data->Alarm->DateTime.Hour = msg->Buffer[14];
3040 Data->Alarm->DateTime.Minute = msg->Buffer[15];
3041 Data->Alarm->DateTime.Second = 0;
3042 return ERR_NONE;
3043 case 0x20:
3044 smprintf(s, "Alarm state received\n");
3045 if (msg->Buffer[37] == 0x01) {
3046 smprintf(s, " Not set in phone\n");
3047 return ERR_EMPTY;
3048 }
3049 smprintf(s, "Enabled\n");
3050 return ERR_NONE;
3051 }
3052 return ERR_UNKNOWNRESPONSE;
3053 }
3054
N6510_GetAlarm(GSM_StateMachine * s,GSM_Alarm * Alarm)3055 static GSM_Error N6510_GetAlarm(GSM_StateMachine *s, GSM_Alarm *Alarm)
3056 {
3057 unsigned char StateReq[] = {N6110_FRAME_HEADER, 0x1f, 0x01, 0x00};
3058 unsigned char GetReq [] = {N6110_FRAME_HEADER, 0x19, 0x00, 0x02};
3059 GSM_Error error;
3060
3061 if (Alarm->Location != 1) return ERR_NOTSUPPORTED;
3062
3063 s->Phone.Data.Alarm=Alarm;
3064 smprintf(s, "Getting alarm state\n");
3065 error = GSM_WaitFor (s, StateReq, 6, 0x19, s->Phone.Data.Priv.N6510.Timeout, ID_GetAlarm);
3066 if (error != ERR_NONE) return error;
3067
3068 smprintf(s, "Getting alarm\n");
3069 return GSM_WaitFor (s, GetReq, 6, 0x19, s->Phone.Data.Priv.N6510.Timeout, ID_GetAlarm);
3070 }
3071
N6510_ReplySetAlarm(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)3072 static GSM_Error N6510_ReplySetAlarm(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
3073 {
3074 smprintf(s, "Alarm set\n");
3075 return ERR_NONE;
3076 }
3077
N6510_SetAlarm(GSM_StateMachine * s,GSM_Alarm * Alarm)3078 static GSM_Error N6510_SetAlarm(GSM_StateMachine *s, GSM_Alarm *Alarm)
3079 {
3080 unsigned char req[] = {N6110_FRAME_HEADER,
3081 0x11, 0x00, 0x01, 0x01, 0x0c, 0x02,
3082 0x01, 0x00, 0x00, 0x00, 0x00,
3083 0x00, 0x00, /* Hours, Minutes */
3084 0x00, 0x00, 0x00 };
3085
3086 if (Alarm->Location != 1) return ERR_NOTSUPPORTED;
3087
3088 req[14] = Alarm->DateTime.Hour;
3089 req[15] = Alarm->DateTime.Minute;
3090
3091 smprintf(s, "Setting alarm\n");
3092 return GSM_WaitFor (s, req, 19, 0x19, s->Phone.Data.Priv.N6510.Timeout, ID_SetAlarm);
3093 }
3094
N6510_ReplyGetRingtonesInfo(GSM_Protocol_Message * msg,GSM_StateMachine * s)3095 static GSM_Error N6510_ReplyGetRingtonesInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3096 {
3097 int tmp,i;
3098 GSM_Phone_Data *Data = &s->Phone.Data;
3099
3100 smprintf(s, "Ringtones info received\n");
3101 memset(Data->RingtonesInfo,0,sizeof(GSM_AllRingtonesInfo));
3102 if (msg->Buffer[4] * 256 + msg->Buffer[5] == 0x00) return ERR_EMPTY;
3103 Data->RingtonesInfo->Number = msg->Buffer[4] * 256 + msg->Buffer[5];
3104 /* allocate array of ringtones based on number */
3105 Data->RingtonesInfo->Ringtone = calloc(Data->RingtonesInfo->Number, sizeof(GSM_RingtoneInfo));
3106 tmp = 6;
3107 for (i=0;i<Data->RingtonesInfo->Number;i++) {
3108 Data->RingtonesInfo->Ringtone[i].Group = msg->Buffer[tmp+4];
3109 Data->RingtonesInfo->Ringtone[i].ID = msg->Buffer[tmp+2] * 256 + msg->Buffer[tmp+3];
3110 memcpy(Data->RingtonesInfo->Ringtone[i].Name,msg->Buffer+tmp+8,(msg->Buffer[tmp+6]*256+msg->Buffer[tmp+7])*2);
3111 smprintf(s, "%5i (%5i). \"%s\"\n",
3112 Data->RingtonesInfo->Ringtone[i].ID,
3113 Data->RingtonesInfo->Ringtone[i].Group,
3114 DecodeUnicodeString(Data->RingtonesInfo->Ringtone[i].Name));
3115 tmp = tmp + (msg->Buffer[tmp]*256+msg->Buffer[tmp+1]);
3116 }
3117 return ERR_NONE;
3118 }
3119
N6510_PrivGetRingtonesInfo(GSM_StateMachine * s,GSM_AllRingtonesInfo * Info,gboolean AllRingtones)3120 static GSM_Error N6510_PrivGetRingtonesInfo(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info, gboolean AllRingtones)
3121 {
3122 GSM_Error error;
3123 unsigned char UserReq[8] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0x02};
3124 /* unsigned char All_Req[9] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x7D}; */
3125 unsigned char All_Req[8] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0x00};
3126
3127 s->Phone.Data.RingtonesInfo=Info;
3128 smprintf(s, "Getting binary ringtones ID\n");
3129 if (AllRingtones) {
3130 /* error = GSM_WaitFor (s, All_Req, 9, 0x1f, s->Phone.Data.Priv.N6510.Timeout, ID_GetRingtonesInfo); */
3131 error = GSM_WaitFor (s, All_Req, 8, 0x1f, s->Phone.Data.Priv.N6510.Timeout, ID_GetRingtonesInfo);
3132 if (error == ERR_EMPTY && Info->Number == 0) return ERR_NOTSUPPORTED;
3133 return error;
3134 } else {
3135 error = GSM_WaitFor (s, UserReq, 8, 0x1f, s->Phone.Data.Priv.N6510.Timeout, ID_GetRingtonesInfo);
3136 if (error == ERR_EMPTY && Info->Number == 0) return ERR_NOTSUPPORTED;
3137 return error;
3138 }
3139 }
3140
N6510_GetRingtonesInfo(GSM_StateMachine * s,GSM_AllRingtonesInfo * Info)3141 static GSM_Error N6510_GetRingtonesInfo(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info)
3142 {
3143 return N6510_PrivGetRingtonesInfo(s, Info, TRUE);
3144 }
3145
N6510_ReplyGetRingtone(GSM_Protocol_Message * msg,GSM_StateMachine * s)3146 static GSM_Error N6510_ReplyGetRingtone(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3147 {
3148 size_t tmp,i;
3149 GSM_Phone_Data *Data = &s->Phone.Data;
3150
3151 smprintf(s, "Ringtone received\n");
3152 memcpy(Data->Ringtone->Name,msg->Buffer+8,msg->Buffer[7]*2);
3153 Data->Ringtone->Name[msg->Buffer[7]*2]=0;
3154 Data->Ringtone->Name[msg->Buffer[7]*2+1]=0;
3155 smprintf(s, "Name \"%s\"\n",DecodeUnicodeString(Data->Ringtone->Name));
3156 if (msg->Buffer[msg->Buffer[7]*2+10] == 'M' &&
3157 msg->Buffer[msg->Buffer[7]*2+11] == 'T' &&
3158 msg->Buffer[msg->Buffer[7]*2+12] == 'h' &&
3159 msg->Buffer[msg->Buffer[7]*2+13] == 'd') {
3160 smprintf(s,"MIDI\n");
3161 tmp = msg->Buffer[7]*2+10;
3162 i = msg->Length - 2; /* ?????? */
3163 Data->Ringtone->Format = RING_MIDI;
3164 } else {
3165 /* Looking for end */
3166 i=8+msg->Buffer[7]*2+3;
3167 tmp = i;
3168 while (TRUE) {
3169 if (msg->Buffer[i]==0x07 && msg->Buffer[i+1]==0x0b) {
3170 i=i+2; break;
3171 }
3172 i++;
3173 if (i==msg->Length) return ERR_EMPTY;
3174 }
3175 }
3176 /* Copying frame */
3177 memcpy(Data->Ringtone->NokiaBinary.Frame,msg->Buffer+tmp,i-tmp);
3178 Data->Ringtone->NokiaBinary.Length=i-tmp;
3179 return ERR_NONE;
3180 }
3181
N6510_GetRingtone(GSM_StateMachine * s,GSM_Ringtone * Ringtone,gboolean PhoneRingtone)3182 static GSM_Error N6510_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, gboolean PhoneRingtone)
3183 {
3184 GSM_AllRingtonesInfo Info = {0, NULL};
3185 GSM_Error error;
3186 unsigned char req2[6] = {N7110_FRAME_HEADER, 0x12,
3187 0x00, 0xe7}; /* Location */
3188
3189 if (Ringtone->Format == 0x00) Ringtone->Format = RING_NOKIABINARY;
3190
3191 switch (Ringtone->Format) {
3192 case RING_NOTETONE:
3193 /* In the future get binary and convert */
3194 return ERR_NOTSUPPORTED;
3195 case RING_NOKIABINARY:
3196 s->Phone.Data.Ringtone = Ringtone;
3197 Info.Number = 0;
3198 error=N6510_PrivGetRingtonesInfo(s, &Info, PhoneRingtone);
3199 if (error != ERR_NONE) return error;
3200 if (Ringtone->Location > Info.Number) return ERR_INVALIDLOCATION;
3201 req2[4] = Info.Ringtone[Ringtone->Location-1].ID / 256;
3202 req2[5] = Info.Ringtone[Ringtone->Location-1].ID % 256;
3203 smprintf(s, "Getting binary ringtone\n");
3204 error = GSM_WaitFor (s, req2, 6, 0x1f, s->Phone.Data.Priv.N6510.Timeout, ID_GetRingtone);
3205 if (Info.Ringtone) {
3206 free(Info.Ringtone);
3207 Info.Ringtone=NULL;
3208 }
3209 return error;
3210 case RING_MIDI:
3211 case RING_MMF:
3212 return ERR_NOTSUPPORTED;
3213 }
3214 return ERR_NOTSUPPORTED;
3215 }
3216
N6510_PlayTone(GSM_StateMachine * s,int Herz,unsigned char Volume,gboolean start)3217 static GSM_Error N6510_PlayTone(GSM_StateMachine *s, int Herz, unsigned char Volume, gboolean start)
3218 {
3219 GSM_Error error;
3220 unsigned char reqStart[] = {
3221 0x00,0x06,0x01,0x00,0x07,0x00 };
3222 unsigned char reqPlay[] = {
3223 0x00,0x06,0x01,0x14,0x05,0x04,
3224 0x00,0x00,0x00,0x03,0x03,0x08,
3225 0x00,0x00,0x00,0x01,0x00,0x00,
3226 0x03,0x08,0x01,0x00,
3227 0x07,0xd0, /*Frequency */
3228 0x00,0x00,0x03,0x08,0x02,0x00,0x00,
3229 0x05, /*Volume */
3230 0x00,0x00};
3231 unsigned char reqOff[] = {
3232 0x00,0x06,0x01,0x14,0x05,0x05,
3233 0x00,0x00,0x00,0x01,0x03,0x08,
3234 0x05,0x00,0x00,0x08,0x00,0x00};
3235 /* unsigned char reqOff2[] = { */
3236 /* 0x00,0x06,0x01,0x14,0x05,0x04, */
3237 /* 0x00,0x00,0x00,0x01,0x03,0x08, */
3238 /* 0x00,0x00,0x00,0x00,0x00,0x00}; */
3239
3240 if (start) {
3241 smprintf(s, "Enabling sound - part 1\n");
3242 error=GSM_WaitFor (s, reqStart, 6, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone);
3243 if (error!=ERR_NONE) return error;
3244 smprintf(s, "Enabling sound - part 2 (disabling sound command)\n");
3245 error=GSM_WaitFor (s, reqOff, 18, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone);
3246 if (error!=ERR_NONE) return error;
3247 }
3248
3249 /* For Herz==255*255 we have silent */
3250 if (Herz!=255*255) {
3251 reqPlay[23] = Herz%256;
3252 reqPlay[22] = Herz/256;
3253 reqPlay[31] = Volume;
3254 smprintf(s, "Playing sound\n");
3255 return GSM_WaitFor (s, reqPlay, 34, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone);
3256 } else {
3257 reqPlay[23] = 0;
3258 reqPlay[22] = 0;
3259 reqPlay[31] = 0;
3260 smprintf(s, "Playing silent sound\n");
3261 return GSM_WaitFor (s, reqPlay, 34, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone);
3262
3263 /* smprintf(s, "Disabling sound - part 1\n"); */
3264 /* error=GSM_WaitFor (s, reqOff, 18, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone); */
3265 /* if (error!=ERR_NONE) return error; */
3266 /* smprintf(s, "Disabling sound - part 2\n"); */
3267 /* return GSM_WaitFor (s, reqOff2, 18, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone); */
3268 }
3269 }
3270
N6510_ReplyGetPPM(GSM_Protocol_Message * msg,GSM_StateMachine * s)3271 static GSM_Error N6510_ReplyGetPPM(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3272 {
3273 GSM_Phone_Data *Data = &s->Phone.Data;
3274 size_t pos = 6,len;
3275
3276 smprintf(s, "Received phone info\n");
3277
3278 while(pos < msg->Length) {
3279 if (msg->Buffer[pos] == 0x55 && msg->Buffer[pos+1] == 0x55) {
3280 while(1) {
3281 if (msg->Buffer[pos] != 0x55) break;
3282 pos++;
3283 }
3284 }
3285 len = pos;
3286 while(len < msg->Length) {
3287 if (msg->Buffer[len] == 0x00 && msg->Buffer[len+1] == 0x00) break;
3288 len++;
3289 }
3290 while(len < msg->Length) {
3291 if (msg->Buffer[len] != 0x00) break;
3292 len++;
3293 }
3294 len = len-pos;
3295 smprintf(s, "Block with ID %02x",msg->Buffer[pos]);
3296 #ifdef DEBUG
3297 if (s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXTALLDATE) DumpMessage(&s->di, msg->Buffer+pos, len);
3298 #endif
3299 switch (msg->Buffer[pos]) {
3300 case 0x49:
3301 smprintf(s, "hardware version\n");
3302 break;
3303 case 0x58:
3304 pos += 3;
3305 while (msg->Buffer[pos] != 0x00) pos++;
3306 Data->PhoneString[0] = msg->Buffer[pos - 1];
3307 Data->PhoneString[1] = 0x00;
3308 smprintf(s, "PPM %s\n",Data->PhoneString);
3309 return ERR_NONE;
3310 default:
3311 break;
3312 }
3313 pos += len;
3314 }
3315 return ERR_NOTSUPPORTED;
3316 }
3317
N6510_GetPPM(GSM_StateMachine * s,char * value)3318 static GSM_Error N6510_GetPPM(GSM_StateMachine *s,char *value)
3319 {
3320 /* unsigned char req[6] = {N6110_FRAME_HEADER, 0x07, 0x01, 0xff}; */
3321 unsigned char req[6] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x00};
3322
3323 s->Phone.Data.PhoneString=value;
3324 smprintf(s, "Getting PPM\n");
3325 return GSM_WaitFor (s, req, 6, 0x1b, 3, ID_GetPPM);
3326 }
3327
N6510_GetSpeedDial(GSM_StateMachine * s,GSM_SpeedDial * SpeedDial)3328 static GSM_Error N6510_GetSpeedDial(GSM_StateMachine *s, GSM_SpeedDial *SpeedDial)
3329 {
3330 GSM_MemoryEntry pbk;
3331 GSM_Error error;
3332
3333 pbk.MemoryType = (GSM_MemoryType)MEM7110_SP;
3334 pbk.Location = SpeedDial->Location;
3335 SpeedDial->MemoryLocation = 0;
3336 s->Phone.Data.SpeedDial = SpeedDial;
3337
3338 smprintf(s, "Getting speed dial\n");
3339 error=N6510_GetMemory(s,&pbk);
3340 switch (error) {
3341 case ERR_NOTSUPPORTED:
3342 smprintf(s, "No speed dials set in phone\n");
3343 return ERR_EMPTY;
3344 case ERR_NONE:
3345 if (SpeedDial->MemoryLocation == 0) {
3346 smprintf(s, "Speed dial not assigned or error in firmware\n");
3347 return ERR_EMPTY;
3348 }
3349 return ERR_NONE;
3350 default:
3351 return error;
3352 }
3353 }
3354
N6510_ReplyGetProfile(GSM_Protocol_Message * msg,GSM_StateMachine * s)3355 static GSM_Error N6510_ReplyGetProfile(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3356 {
3357 unsigned char *blockstart;
3358 int i,j;
3359 GSM_Phone_Data *Data = &s->Phone.Data;
3360
3361 switch (msg->Buffer[3]) {
3362 case 0x02:
3363 blockstart = msg->Buffer + 7;
3364 for (i = 0; i < 11; i++) {
3365 smprintf(s, "Profile feature %02x ",blockstart[1]);
3366 #ifdef DEBUG
3367 if (s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXTALLDATE) DumpMessage(&s->di, blockstart, blockstart[0]);
3368 #endif
3369
3370 switch (blockstart[1]) {
3371 case 0x03:
3372 smprintf(s, "Ringtone ID\n");
3373 Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_RingtoneID;
3374 Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = blockstart[7];
3375 if (blockstart[7] == 0x00) {
3376 Data->Profile->FeatureValue[Data->Profile->FeaturesNumber] = blockstart[10];
3377 }
3378 Data->Profile->FeaturesNumber++;
3379 break;
3380 case 0x05: /* SMS tone */
3381 j = Data->Profile->FeaturesNumber;
3382 NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,FALSE);
3383 if (j == Data->Profile->FeaturesNumber) {
3384 Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_MessageTone;
3385 Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = PROFILE_MESSAGE_PERSONAL;
3386 Data->Profile->FeaturesNumber++;
3387 Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_MessageToneID;
3388 Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = blockstart[7];
3389 Data->Profile->FeaturesNumber++;
3390 }
3391 break;
3392 case 0x08: /* Caller groups */
3393 NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,TRUE);
3394 break;
3395 case 0x0c :
3396 CopyUnicodeString(Data->Profile->Name,blockstart + 7);
3397 smprintf(s, "profile Name: \"%s\"\n", DecodeUnicodeString(Data->Profile->Name));
3398 Data->Profile->DefaultName = FALSE;
3399 break;
3400 default:
3401 NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,FALSE);
3402 }
3403 blockstart = blockstart + blockstart[0];
3404 }
3405 return ERR_NONE;
3406 case 0x06:
3407 Data->Profile->Active = FALSE;
3408 if (Data->Profile->Location == msg->Buffer[5]) Data->Profile->Active = TRUE;
3409 return ERR_NONE;
3410 }
3411 return ERR_UNKNOWNRESPONSE;
3412 }
3413
N6510_GetProfile(GSM_StateMachine * s,GSM_Profile * Profile)3414 static GSM_Error N6510_GetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
3415 {
3416 unsigned char req[150] = {N6110_FRAME_HEADER, 0x01, 0x01, 0x0C, 0x01};
3417 unsigned char reqActive[] = {N6110_FRAME_HEADER, 0x05};
3418 int i, length = 7;
3419 GSM_Error error;
3420
3421 if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES)) return ERR_NOTSUPPORTED;
3422
3423 /* if (!strcmp(s->Phone.Data.ModelInfo->model,"3510")) { */
3424 /* if (s->Phone.Data.VerNum>3.37) return ERR_NOTSUPPORTED; */
3425 /* if (!strcmp(s->Phone.Data.ModelInfo->model,"6230")) { */
3426 /* if (!strcmp(s->Phone.Data.ModelInfo->model,"6220")) { */
3427 /* if (!strcmp(s->Phone.Data.ModelInfo->model,"5140")) { */
3428 /* if (!strcmp(s->Phone.Data.ModelInfo->model,"6230i")) { */
3429 /* if (!strcmp(s->Phone.Data.ModelInfo->model,"6020")) { */
3430
3431 if (Profile->Location>5) return ERR_INVALIDLOCATION;
3432
3433 for (i = 0; i < 0x0a; i++) {
3434 req[length++] = 0x04;
3435 req[length++] = Profile->Location;
3436 req[length++] = i;
3437 req[length++] = 0x01;
3438 }
3439
3440 req[length++] = 0x04;
3441 req[length++] = Profile->Location;
3442 req[length++] = 0x0c;
3443 req[length++] = 0x01;
3444
3445 req[length++] = 0x04;
3446
3447 Profile->CarKitProfile = FALSE;
3448 Profile->HeadSetProfile = FALSE;
3449
3450 Profile->FeaturesNumber = 0;
3451
3452 s->Phone.Data.Profile=Profile;
3453 smprintf(s, "Getting profile\n");
3454 error = GSM_WaitFor (s, req, length, 0x39, s->Phone.Data.Priv.N6510.Timeout, ID_GetProfile);
3455 if (error != ERR_NONE) return error;
3456
3457 smprintf(s, "Checking, which profile is active\n");
3458 return GSM_WaitFor (s, reqActive, 4, 0x39, s->Phone.Data.Priv.N6510.Timeout, ID_GetProfile);
3459 }
3460
N6510_ReplySetProfile(GSM_Protocol_Message * msg,GSM_StateMachine * s)3461 static GSM_Error N6510_ReplySetProfile(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3462 {
3463 unsigned char *blockstart;
3464 int i;
3465
3466 smprintf(s, "Response to profile writing received!\n");
3467
3468 blockstart = msg->Buffer + 6;
3469 for (i = 0; i < msg->Buffer[5]; i++) {
3470 switch (blockstart[2]) {
3471 case 0x00: smprintf(s, "keypad tone level"); break;
3472 case 0x02: smprintf(s, "call alert"); break;
3473 case 0x03: smprintf(s, "ringtone"); break;
3474 case 0x04: smprintf(s, "ringtone volume"); break;
3475 case 0x05: smprintf(s, "SMS tone"); break;
3476 case 0x06: smprintf(s, "vibration"); break;
3477 case 0x07: smprintf(s, "warning tone level"); break;
3478 case 0x08: smprintf(s, "caller groups"); break;
3479 case 0x09: smprintf(s, "automatic answer"); break;
3480 case 0x0c: smprintf(s, "name"); break;
3481 default:
3482 smprintf(s, "Unknown block type %02x", blockstart[2]);
3483 break;
3484 }
3485 if (msg->Buffer[4] == 0x00) {
3486 smprintf(s, ": set OK\n");
3487 } else {
3488 smprintf(s, ": setting error %i\n", msg->Buffer[4]);
3489 }
3490 blockstart = blockstart + blockstart[1];
3491 }
3492 return ERR_NONE;
3493 }
3494
N6510_SetProfile(GSM_StateMachine * s,GSM_Profile * Profile)3495 static GSM_Error N6510_SetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
3496 {
3497 int i, length = 7, blocks = 0;
3498 gboolean found;
3499 unsigned char ID,Value;
3500 unsigned char req[150] = {N6110_FRAME_HEADER, 0x03, 0x01,
3501 0x06, /* Number of blocks */
3502 0x03};
3503
3504 if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES)) return ERR_NOTSUPPORTED;
3505
3506 if (Profile->Location>5) return ERR_INVALIDLOCATION;
3507
3508 for (i=0;i<Profile->FeaturesNumber;i++) {
3509 found = FALSE;
3510 switch (Profile->FeatureID[i]) {
3511 case Profile_RingtoneID:
3512 ID = 0x03;
3513 Value = Profile->FeatureValue[i];
3514 found = TRUE;
3515 break;
3516 default:
3517 found=NOKIA_FindPhoneFeatureValue(
3518 s,
3519 Profile71_65,
3520 Profile->FeatureID[i],Profile->FeatureValue[i],
3521 &ID,&Value);
3522 }
3523 if (found) {
3524 req[length] = 0x09;
3525 req[length + 1] = ID;
3526 req[length + 2] = Profile->Location;
3527 memcpy(req + length + 4, "\x00\x00\x01", 3);
3528 req[length + 8] = 0x03;
3529 req[length + 3] = req[length + 7] = Value;
3530 blocks++;
3531 length += 9;
3532 }
3533 }
3534
3535 smprintf(s, "Setting profile\n");
3536 return GSM_WaitFor (s, req, length, 0x39, s->Phone.Data.Priv.N6510.Timeout, ID_SetProfile);
3537 }
3538
N6510_ReplyIncomingCB(GSM_Protocol_Message * msg,GSM_StateMachine * s)3539 static GSM_Error N6510_ReplyIncomingCB(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3540 {
3541 switch (msg->Buffer[3]) {
3542 case 0x21:
3543 smprintf(s, "Ignoring cell broadcast ok event\n");
3544 break;
3545 case 0x22:
3546 smprintf(s, "Ignoring cell broadcast fail event\n");
3547 break;
3548 case 0x23:
3549 smprintf(s, "Ignoring cell broadcast read event\n");
3550 break;
3551 default:
3552 smprintf(s, "Ignoring cell broadcast event 0x%02x\n", msg->Buffer[3]);
3553 break;
3554 }
3555 return ERR_NONE;
3556 }
N6510_ReplyIncomingSMS(GSM_Protocol_Message * msg,GSM_StateMachine * s)3557 static GSM_Error N6510_ReplyIncomingSMS(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3558 {
3559 GSM_SMSMessage sms;
3560 size_t i;
3561
3562 #ifdef DEBUG
3563 smprintf(s, "SMS message received\n");
3564 N6510_DecodeSMSFrame(s, &sms, msg->Buffer+10,&i);
3565 #endif
3566
3567 if (s->Phone.Data.EnableIncomingSMS && s->User.IncomingSMS!=NULL) {
3568 GSM_SetDefaultSMSData(&sms);
3569
3570 sms.State = SMS_UnRead;
3571 sms.InboxFolder = TRUE;
3572
3573 N6510_DecodeSMSFrame(s, &sms, msg->Buffer+10,&i);
3574
3575 s->User.IncomingSMS(s, &sms, s->User.IncomingSMSUserData);
3576 }
3577 return ERR_NONE;
3578 }
3579
N6510_DialVoice(GSM_StateMachine * s,char * number,GSM_CallShowNumber ShowNumber)3580 static GSM_Error N6510_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber)
3581 {
3582 unsigned int pos2 = 15;
3583 unsigned int pos = 4;
3584 unsigned char req2[100] = {N6110_FRAME_HEADER,0x01,
3585 0x00,0x02,0x07,0x04,
3586 0x01, /* 1 - voice, 2 - data */
3587 0x00,0x03,
3588 0x18, /* length of rest + 1 */
3589 0x00,0x00,0x00};
3590 unsigned char req[100] = {N6110_FRAME_HEADER,0x01,
3591 0x0c}; /* Number length */
3592 GSM_Error error;
3593
3594 /* USSD not supported */
3595 if (number[0] == '*') return ERR_NOTSUPPORTED;
3596 if (number[0] == '#') return ERR_NOTSUPPORTED;
3597
3598 req[pos++] = strlen(number);
3599 EncodeUnicode(req+pos,number,strlen(number));
3600 pos += strlen(number)*2;
3601 req[pos++] = 0x05; /* call type: voice - 0x05, data - 0x01 */
3602 req[pos++] = 0x01;
3603 req[pos++] = 0x05;
3604 req[pos++] = 0x00;
3605 req[pos++] = 0x02;
3606 req[pos++] = 0x00;
3607 req[pos++] = 0x00;
3608 switch (ShowNumber) {
3609 case GSM_CALL_HideNumber:
3610 req[pos++] = 0x02;
3611 break;
3612 case GSM_CALL_ShowNumber:
3613 req[pos++] = 0x03;
3614 break;
3615 case GSM_CALL_DefaultNumberPresence:
3616 req[pos++] = 0x01;
3617 break;
3618 }
3619 smprintf(s, "Making voice call\n");
3620 error = GSM_WaitFor (s, req, pos, 0x01, s->Phone.Data.Priv.N6510.Timeout, ID_DialVoice);
3621 if (error != ERR_NOTSUPPORTED) return error;
3622
3623 if (ShowNumber != GSM_CALL_DefaultNumberPresence) return ERR_NOTSUPPORTED;
3624
3625 req2[11] = strlen(number)*2+6;
3626 req2[pos2++] = strlen(number);
3627 EncodeUnicode(req2+pos2,number,strlen(number));
3628 pos2 += strlen(number)*2;
3629
3630 smprintf(s, "Making voice call\n");
3631 error = GSM_WaitFor (s, req2, pos2, 0x01, s->Phone.Data.Priv.N6510.Timeout, ID_DialVoice);
3632 if (error == ERR_NOTSUPPORTED) return ERR_NONE;
3633 return error;
3634 }
3635
N6510_ReplyLogIntoNetwork(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)3636 static GSM_Error N6510_ReplyLogIntoNetwork(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
3637 {
3638 smprintf(s, "Probably phone says: I log into network\n");
3639 return ERR_NONE;
3640 }
3641
N6510_EncodeFMFrequency(double freq,unsigned char * buff)3642 void N6510_EncodeFMFrequency(double freq, unsigned char *buff)
3643 {
3644 unsigned int freq2;
3645
3646 freq2 = (unsigned int)(freq * 100);
3647 freq2 = freq2 - 0xffff;
3648 buff[0] = freq2 / 0x100;
3649 buff[1] = freq2 % 0x100;
3650 }
3651
N6510_DecodeFMFrequency(double * freq,unsigned char * buff)3652 void N6510_DecodeFMFrequency(double *freq, unsigned char *buff)
3653 {
3654 *freq = (double)(0xffff + buff[0] * 0x100 + buff[1])/1000.0;
3655 }
3656
N6510_ReplyGetFMStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)3657 static GSM_Error N6510_ReplyGetFMStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3658 {
3659 smprintf(s, "getting FM status OK\n");
3660 memcpy(s->Phone.Data.Priv.N6510.FMStatus,msg->Buffer,msg->Length);
3661 s->Phone.Data.Priv.N6510.FMStatusLength = msg->Length;
3662 return ERR_NONE;
3663 }
3664
N6510_GetFMStatus(GSM_StateMachine * s)3665 static GSM_Error N6510_GetFMStatus(GSM_StateMachine *s)
3666 {
3667 unsigned char req[7] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x01};
3668
3669 if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3670 return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_GetFMStation);
3671 }
3672
N6510_ReplyGetFMStation(GSM_Protocol_Message * msg,GSM_StateMachine * s)3673 static GSM_Error N6510_ReplyGetFMStation(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3674 {
3675 unsigned char name[GSM_MAX_FMSTATION_LENGTH*2+2];
3676 int length;
3677 GSM_Phone_Data *Data = &s->Phone.Data;
3678
3679 switch (msg->Buffer[3]) {
3680 case 0x06:
3681 smprintf(s, "Received FM station\n");
3682 length = msg->Buffer[8];
3683 if (length > GSM_MAX_FMSTATION_LENGTH) {
3684 smprintf(s, "FM station name too long (%d), truncating!\n", length);
3685 length = GSM_MAX_FMSTATION_LENGTH;
3686 }
3687 memcpy(name,msg->Buffer+18,length*2);
3688 name[length*2] = 0x00;
3689 name[length*2+1] = 0x00;
3690 CopyUnicodeString(Data->FMStation->StationName,name);
3691 smprintf(s,"Station name: \"%s\"\n",DecodeUnicodeString(Data->FMStation->StationName));
3692 N6510_DecodeFMFrequency(&Data->FMStation->Frequency, msg->Buffer+16);
3693 return ERR_NONE;
3694 case 0x16:
3695 smprintf(s, "Received FM station. Empty ?\n");
3696 return ERR_EMPTY;
3697 case 0xf0:
3698 smprintf(s, "FM radio not supported\n");
3699 return ERR_NOTSUPPORTED;
3700 }
3701 return ERR_UNKNOWNRESPONSE;
3702 }
3703
N6510_GetFMStation(GSM_StateMachine * s,GSM_FMStation * FMStation)3704 static GSM_Error N6510_GetFMStation (GSM_StateMachine *s, GSM_FMStation *FMStation)
3705 {
3706 GSM_Error error;
3707 int location;
3708 unsigned char req[7] = {N6110_FRAME_HEADER, 0x05,
3709 0x00, /* location */
3710 0x00,0x01};
3711
3712 if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3713 if (FMStation->Location > GSM_MAX_FM_STATION) return ERR_INVALIDLOCATION;
3714
3715 s->Phone.Data.FMStation = FMStation;
3716
3717 error = N6510_GetFMStatus(s);
3718 if (error != ERR_NONE) return error;
3719
3720 location = FMStation->Location-1;
3721 if (s->Phone.Data.Priv.N6510.FMStatus[14+location] == 0xFF) return ERR_EMPTY;
3722 req[4] = s->Phone.Data.Priv.N6510.FMStatus[14+location];
3723
3724 smprintf(s, "Getting FM Station %i\n",FMStation->Location);
3725 return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_GetFMStation);
3726 }
3727
N6510_ReplySetFMStation(GSM_Protocol_Message * msg,GSM_StateMachine * s)3728 static GSM_Error N6510_ReplySetFMStation(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3729 {
3730 #ifdef DEBUG
3731 switch (msg->Buffer[4]){
3732 case 0x03: smprintf(s, "FM stations cleaned\n"); break;
3733 case 0x11: smprintf(s, "Setting FM station status OK\n"); break;
3734 case 0x12: smprintf(s, "Setting FM station OK\n"); break;
3735 }
3736 #endif
3737 return ERR_NONE;
3738 }
3739
N6510_ClearFMStations(GSM_StateMachine * s)3740 static GSM_Error N6510_ClearFMStations (GSM_StateMachine *s)
3741 {
3742 unsigned char req[7] = {N6110_FRAME_HEADER, 0x03,0x0f,0x00,0x01};
3743
3744 if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3745
3746 smprintf(s, "Cleaning FM Stations\n");
3747 return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_SetFMStation);
3748 }
3749
N6510_SetFMStation(GSM_StateMachine * s,GSM_FMStation * FMStation)3750 static GSM_Error N6510_SetFMStation (GSM_StateMachine *s, GSM_FMStation *FMStation)
3751 {
3752 unsigned int len, location;
3753 GSM_Error error;
3754 unsigned char setstatus[36] = {N6110_FRAME_HEADER,0x11,0x00,0x01,0x01,
3755 0x00,0x00,0x1c,0x00,0x14,0x00,0x00,
3756 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3757 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3758 0xff,0xff,0xff,0xff,0xff,0x01};
3759 unsigned char req[64] = {N6110_FRAME_HEADER, 0x12,0x00,0x01,0x00,
3760 0x00, /* 0x0e + (strlen(name) * 2) */
3761 0x00, /* strlen(name) */
3762 0x14,0x09,0x00,
3763 0x00, /* location */
3764 0x00,0x00,0x01,
3765 0x00, /* freqHi */
3766 0x00, /* freqLo */
3767 0x01};
3768
3769 if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3770
3771 s->Phone.Data.FMStation = FMStation;
3772 location = FMStation->Location-1;
3773
3774 error = N6510_GetFMStatus(s);
3775 if (error != ERR_NONE) return error;
3776
3777 memcpy(setstatus+14,s->Phone.Data.Priv.N6510.FMStatus+14,20);
3778 setstatus [14+location] = location;
3779
3780 smprintf(s, "Setting FM status %i\n",FMStation->Location);
3781 error = GSM_WaitFor (s, setstatus, 36 , 0x3E, 2, ID_SetFMStation);
3782 if (error != ERR_NONE) return error;
3783
3784 req[12] = location;
3785
3786 /* Name */
3787 len = UnicodeLength(FMStation->StationName);
3788 req[8] = len;
3789 req[7] = 0x0e + len * 2;
3790 memcpy (req+18,FMStation->StationName,len*2);
3791
3792 /* Frequency */
3793 N6510_EncodeFMFrequency(FMStation->Frequency, req+16);
3794
3795 smprintf(s, "Setting FM Station %i\n",FMStation->Location);
3796 return GSM_WaitFor (s, req, 0x13+len*2, 0x3E, 2, ID_SetFMStation);
3797 }
3798
N6510_ReplySetLight(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)3799 static GSM_Error N6510_ReplySetLight(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
3800 {
3801 smprintf(s, "Light set\n");
3802 return ERR_NONE;
3803 }
3804
N6510_SetLight(GSM_StateMachine * s,N6510_PHONE_LIGHTS light,gboolean enable)3805 GSM_Error N6510_SetLight(GSM_StateMachine *s, N6510_PHONE_LIGHTS light, gboolean enable)
3806 {
3807 unsigned char req[14] = {
3808 N6110_FRAME_HEADER, 0x05,
3809 0x01, /* 0x01 = Display, 0x03 = keypad */
3810 0x01, /* 0x01 = Enable, 0x02 = disable */
3811 0x00, 0x00, 0x00, 0x01,
3812 0x05, 0x04, 0x02, 0x00};
3813
3814 req[4] = light;
3815 if (!enable) req[5] = 0x02;
3816 smprintf(s, "Setting light\n");
3817 return GSM_WaitFor (s, req, 14, 0x3A, s->Phone.Data.Priv.N6510.Timeout, ID_SetLight);
3818 }
3819
N6510_ShowStartInfo(GSM_StateMachine * s,gboolean enable)3820 static GSM_Error N6510_ShowStartInfo(GSM_StateMachine *s, gboolean enable)
3821 {
3822 GSM_Error error;
3823
3824 if (enable) {
3825 error=N6510_SetLight(s,N6510_LIGHT_DISPLAY,TRUE);
3826 if (error != ERR_NONE) return error;
3827
3828 error=N6510_SetLight(s,N6510_LIGHT_TORCH,TRUE);
3829 if (error != ERR_NONE) return error;
3830
3831 return N6510_SetLight(s,N6510_LIGHT_KEYPAD,TRUE);
3832 } else {
3833 error=N6510_SetLight(s,N6510_LIGHT_DISPLAY,FALSE);
3834 if (error != ERR_NONE) return error;
3835
3836 error=N6510_SetLight(s,N6510_LIGHT_TORCH,FALSE);
3837 if (error != ERR_NONE) return error;
3838
3839 return N6510_SetLight(s,N6510_LIGHT_KEYPAD,FALSE);
3840 }
3841 }
3842
N6510_ReplyGetGPRSAccessPoint(GSM_Protocol_Message * msg,GSM_StateMachine * s)3843 static GSM_Error N6510_ReplyGetGPRSAccessPoint(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3844 {
3845 GSM_GPRSAccessPoint *point = s->Phone.Data.GPRSPoint;
3846
3847 switch (msg->Buffer[13]) {
3848 case 0x01:
3849 smprintf(s,"Active GPRS point received\n");
3850 point->Active = FALSE;
3851 if (point->Location == msg->Buffer[18]) point->Active = TRUE;
3852 return ERR_NONE;
3853 case 0xD2:
3854 smprintf(s,"Names for GPRS points received\n");
3855 CopyUnicodeString(point->Name,msg->Buffer+18+(point->Location-1)*42);
3856 smprintf(s,"\"%s\"\n",DecodeUnicodeString(point->Name));
3857 return ERR_NONE;
3858 case 0xF2:
3859 smprintf(s,"URL for GPRS points received\n");
3860 CopyUnicodeString(point->URL,msg->Buffer+18+(point->Location-1)*202);
3861 smprintf(s,"\"%s\"\n",DecodeUnicodeString(point->URL));
3862 return ERR_NONE;
3863 }
3864 return ERR_UNKNOWNRESPONSE;
3865 }
3866
N6510_GetGPRSAccessPoint(GSM_StateMachine * s,GSM_GPRSAccessPoint * point)3867 static GSM_Error N6510_GetGPRSAccessPoint(GSM_StateMachine *s, GSM_GPRSAccessPoint *point)
3868 {
3869 GSM_Error error;
3870 unsigned char URL[] = {
3871 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3872 0x00, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00};
3873 unsigned char Name[] = {
3874 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3875 0x01, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00};
3876 unsigned char Active[] = {
3877 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3878 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
3879
3880 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return ERR_NOTSUPPORTED;
3881 if (point->Location < 1) return ERR_UNKNOWN;
3882 if (point->Location > 5) return ERR_INVALIDLOCATION;
3883
3884 s->Phone.Data.GPRSPoint = point;
3885
3886 smprintf(s, "Getting GPRS access point name\n");
3887 error=GSM_WaitFor (s, Name, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_GetGPRSPoint);
3888 if (error != ERR_NONE) return error;
3889
3890 smprintf(s, "Getting GPRS access point URL\n");
3891 error=GSM_WaitFor (s, URL, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_GetGPRSPoint);
3892 if (error != ERR_NONE) return error;
3893
3894 smprintf(s, "Getting number of active GPRS access point\n");
3895 error=GSM_WaitFor (s, Active, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_GetGPRSPoint);
3896 if (error != ERR_NONE) return error;
3897
3898 if (UnicodeLength(point->URL)==0 && UnicodeLength(point->Name)==0) return ERR_EMPTY;
3899 return error;
3900 }
3901
N6510_ReplySetGPRSAccessPoint1(GSM_Protocol_Message * msg,GSM_StateMachine * s)3902 static GSM_Error N6510_ReplySetGPRSAccessPoint1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3903 {
3904 switch (msg->Buffer[13]) {
3905 case 0x01:
3906 case 0xD2:
3907 case 0xF2:
3908 memcpy(s->Phone.Data.Priv.N6510.GPRSPoints,msg->Buffer,msg->Length);
3909 s->Phone.Data.Priv.N6510.GPRSPointsLength = msg->Length;
3910 return ERR_NONE;
3911 }
3912 return ERR_UNKNOWNRESPONSE;
3913 }
3914
N6510_SetGPRSAccessPoint(GSM_StateMachine * s,GSM_GPRSAccessPoint * point)3915 static GSM_Error N6510_SetGPRSAccessPoint(GSM_StateMachine *s, GSM_GPRSAccessPoint *point)
3916 {
3917 unsigned char *buff = s->Phone.Data.Priv.N6510.GPRSPoints;
3918 GSM_Error error;
3919 unsigned char URL[] = {
3920 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3921 0x00, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00};
3922 unsigned char Name[] = {
3923 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3924 0x01, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00};
3925 unsigned char Active[] = {
3926 N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3927 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
3928
3929 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return ERR_NOTSUPPORTED;
3930 if (point->Location < 1) return ERR_UNKNOWN;
3931 if (point->Location > 5) return ERR_INVALIDLOCATION;
3932
3933 s->Phone.Data.GPRSPoint = point;
3934
3935 smprintf(s, "Getting GPRS access point name\n");
3936 error=GSM_WaitFor (s, Name, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3937 if (error != ERR_NONE) return error;
3938 CopyUnicodeString(buff+18+(point->Location-1)*42,point->Name);
3939 buff[0] = 0x00;
3940 buff[1] = 0x01;
3941 buff[2] = 0x01;
3942 buff[3] = 0x07;
3943 smprintf(s, "Setting GPRS access point name\n");
3944 error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3945 if (error != ERR_NONE) return error;
3946
3947 smprintf(s, "Getting GPRS access point URL\n");
3948 error=GSM_WaitFor (s, URL, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3949 if (error != ERR_NONE) return error;
3950 CopyUnicodeString(buff+18+(point->Location-1)*42,point->URL);
3951 buff[0] = 0x00;
3952 buff[1] = 0x01;
3953 buff[2] = 0x01;
3954 buff[3] = 0x07;
3955 smprintf(s, "Setting GPRS access point URL\n");
3956 error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3957 if (error != ERR_NONE) return error;
3958
3959 if (point->Active) {
3960 smprintf(s, "Getting number of active GPRS access point\n");
3961 error=GSM_WaitFor (s, Active, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3962 if (error != ERR_NONE) return error;
3963 buff[0] = 0x00;
3964 buff[1] = 0x01;
3965 buff[2] = 0x01;
3966 buff[3] = 0x07;
3967 buff[18]= point->Location;
3968 smprintf(s, "Setting number of active GPRS access point\n");
3969 error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3970 if (error != ERR_NONE) return error;
3971 }
3972
3973 return error;
3974 }
3975
N6510_ReplyGetLocale(GSM_Protocol_Message * msg,GSM_StateMachine * s)3976 static GSM_Error N6510_ReplyGetLocale(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3977 {
3978 GSM_Locale *locale = s->Phone.Data.Locale;
3979
3980 switch (msg->Buffer[3]) {
3981 case 0x8A:
3982 smprintf(s, "Date settings received\n");
3983 switch (msg->Buffer[4]) {
3984 case 0x00:
3985 locale->DateFormat = GSM_Date_DDMMYYYY;
3986 locale->DateSeparator = '.';
3987 break;
3988 case 0x01:
3989 locale->DateFormat = GSM_Date_MMDDYYYY;
3990 locale->DateSeparator = '.';
3991 break;
3992 case 0x02:
3993 locale->DateFormat = GSM_Date_YYYYMMDD;
3994 locale->DateSeparator = '.';
3995 break;
3996 case 0x04:
3997 locale->DateFormat = GSM_Date_DDMMYYYY;
3998 locale->DateSeparator = '/';
3999 break;
4000 case 0x05:
4001 locale->DateFormat = GSM_Date_MMDDYYYY;
4002 locale->DateSeparator = '/';
4003 break;
4004 case 0x06:
4005 locale->DateFormat = GSM_Date_YYYYMMDD;
4006 locale->DateSeparator = '/';
4007 break;
4008 case 0x08:
4009 locale->DateFormat = GSM_Date_DDMMYYYY;
4010 locale->DateSeparator = '-';
4011 break;
4012 case 0x09:
4013 locale->DateFormat = GSM_Date_MMDDYYYY;
4014 locale->DateSeparator = '-';
4015 break;
4016 case 0x0A:
4017 locale->DateFormat = GSM_Date_YYYYMMDD;
4018 locale->DateSeparator = '-';
4019 break;
4020 default:/* FIXME */
4021 locale->DateFormat = GSM_Date_DDMMYYYY;
4022 locale->DateSeparator = '/';
4023 break;
4024 }
4025 return ERR_NONE;
4026 }
4027 return ERR_UNKNOWNRESPONSE;
4028 }
4029
N6510_GetLocale(GSM_StateMachine * s,GSM_Locale * locale)4030 static GSM_Error N6510_GetLocale(GSM_StateMachine *s, GSM_Locale *locale)
4031 {
4032 unsigned char req[] = {N6110_FRAME_HEADER, 0x89};
4033
4034 s->Phone.Data.Locale = locale;
4035
4036 smprintf(s, "Getting date format\n");
4037 return GSM_WaitFor (s, req, 4, 0x13, s->Phone.Data.Priv.N6510.Timeout, ID_GetLocale);
4038 }
4039
N6510_CancelCall(GSM_StateMachine * s,int ID,gboolean all)4040 GSM_Error N6510_CancelCall(GSM_StateMachine *s, int ID, gboolean all)
4041 {
4042 if (all) return ERR_NOTSUPPORTED;
4043 return DCT3DCT4_CancelCall(s,ID);
4044 }
4045
N6510_AnswerCall(GSM_StateMachine * s,int ID,gboolean all)4046 GSM_Error N6510_AnswerCall(GSM_StateMachine *s, int ID, gboolean all)
4047 {
4048 if (all) return ERR_NOTSUPPORTED;
4049 return DCT3DCT4_AnswerCall(s,ID);
4050 }
4051
N6510_ReplyAddSMSFolder(GSM_Protocol_Message * msg,GSM_StateMachine * s)4052 static GSM_Error N6510_ReplyAddSMSFolder(GSM_Protocol_Message *msg, GSM_StateMachine *s)
4053 {
4054 smprintf(s,"SMS folder \"%s\" has been added\n",DecodeUnicodeString(msg->Buffer+10));
4055 return ERR_NONE;
4056 }
4057
N6510_AddSMSFolder(GSM_StateMachine * s,unsigned char * name)4058 GSM_Error N6510_AddSMSFolder(GSM_StateMachine *s, unsigned char *name)
4059 {
4060 unsigned char req[200] = {N6110_FRAME_HEADER, 0x10, 0x01, 0x00, 0x01,
4061 0x00, /* Length */
4062 0x00, 0x00};
4063
4064 CopyUnicodeString(req+10,name);
4065 req[7] = UnicodeLength(name)*2 + 6;
4066
4067 smprintf(s, "Adding SMS folder\n");
4068 return GSM_WaitFor (s, req, req[7] + 6, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_AddSMSFolder);
4069 }
4070
N6510_SetWAPBookmark(GSM_StateMachine * s,GSM_WAPBookmark * bookmark)4071 static GSM_Error N6510_SetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
4072 {
4073 GSM_Error error;
4074 int count=4, location;
4075 unsigned char req[600] = {N6110_FRAME_HEADER, 0x09};
4076
4077 /* We have to enable WAP frames in phone */
4078 error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS);
4079 if (error!=ERR_NONE) return error;
4080
4081 location = bookmark->Location - 1;
4082 if (bookmark->Location == 0) location = 0xffff;
4083 req[count++] = (location & 0xff00) >> 8;
4084 req[count++] = location & 0x00ff;
4085
4086 count += NOKIA_SetUnicodeString(s, req+count, bookmark->Title, TRUE);
4087 count += NOKIA_SetUnicodeString(s, req+count, bookmark->Address, TRUE);
4088
4089 req[count++] = 0x00;
4090 req[count++] = 0x00;
4091 req[count++] = 0x00;
4092 req[count++] = 0x00;
4093
4094 smprintf(s, "Setting WAP bookmark\n");
4095 error = GSM_WaitFor (s, req, count, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_SetWAPBookmark);
4096 if (error != ERR_NONE) {
4097 if (error == ERR_INSIDEPHONEMENU || error == ERR_EMPTY || error == ERR_FULL) {
4098 DCT3DCT4_DisableConnectionFunctions(s);
4099 }
4100 return error;
4101 }
4102
4103 return DCT3DCT4_DisableConnectionFunctions(s);
4104 }
4105
N6510_DeleteWAPBookmark(GSM_StateMachine * s,GSM_WAPBookmark * bookmark)4106 GSM_Error N6510_DeleteWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
4107 {
4108 GSM_Error error;
4109
4110 /* We have to enable WAP frames in phone */
4111 error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS);
4112 if (error!=ERR_NONE) return error;
4113
4114 return DCT3DCT4_DeleteWAPBookmarkPart(s,bookmark);
4115 }
4116
N6510_GetWAPBookmark(GSM_StateMachine * s,GSM_WAPBookmark * bookmark)4117 GSM_Error N6510_GetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
4118 {
4119 GSM_Error error;
4120
4121 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) return ERR_NOTSUPPORTED;
4122
4123 /* We have to enable WAP frames in phone */
4124 error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS);
4125 if (error!=ERR_NONE) return error;
4126
4127 return DCT3DCT4_GetWAPBookmarkPart(s,bookmark);
4128 }
4129
DCT4_ReplyGetScreenDump(GSM_Protocol_Message * msg,GSM_StateMachine * s)4130 static GSM_Error DCT4_ReplyGetScreenDump(GSM_Protocol_Message *msg, GSM_StateMachine *s)
4131 {
4132 int len;
4133
4134 /* Data is at offset 10 */
4135
4136 len = msg->Buffer[7] | (msg->Buffer[6] << 8);
4137 smprintf(s, "Received screenshot part, length %d\n", len);
4138 s->Phone.Data.Picture->Buffer = realloc(s->Phone.Data.Picture->Buffer, s->Phone.Data.Picture->Length + len);
4139 if (s->Phone.Data.Picture->Buffer == NULL) {
4140 return ERR_MOREMEMORY;
4141 }
4142 memcpy(s->Phone.Data.Picture->Buffer + s->Phone.Data.Picture->Length, msg->Buffer + 10, len);
4143 s->Phone.Data.Picture->Length += len;
4144 if (len < 500) {
4145 return ERR_NONE;
4146 }
4147 return ERR_NEEDANOTHERANSWER;
4148 }
4149
DCT4_ReplyGetScreenInfo(GSM_Protocol_Message * msg,GSM_StateMachine * s)4150 static GSM_Error DCT4_ReplyGetScreenInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
4151 {
4152 s->Phone.Data.Priv.N6510.ScreenWidth = msg->Buffer[5] | (msg->Buffer[4] << 8);
4153 s->Phone.Data.Priv.N6510.ScreenHeight = msg->Buffer[7] | (msg->Buffer[6] << 8);
4154 smprintf(s, "Screen size %dx%d\n", s->Phone.Data.Priv.N6510.ScreenWidth, s->Phone.Data.Priv.N6510.ScreenHeight);
4155
4156 return ERR_NONE;
4157 }
4158
DCT4_Screenshot(GSM_StateMachine * s,GSM_BinaryPicture * picture)4159 GSM_Error DCT4_Screenshot(GSM_StateMachine *s, GSM_BinaryPicture *picture)
4160 {
4161 unsigned char req_data[] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x00};
4162 unsigned char req_screen[] = {N6110_FRAME_HEADER, 0x06, 0x01, 0x00};
4163 unsigned char bmp_header[] = {0x42, 0x4D, /* BMP magic "BM" */
4164 0, 0, 0, 0, /* Size of BMP in bytes */
4165 0, 0, 0, 0, /* reserved */
4166 0x7a, 0, 0, 0 , /* Offset of data */
4167 0x6c, 0, 0, 0, /* Size of header */
4168 0, 0, 0, 0, /* width */
4169 0, 0, 0, 0, /* height */
4170 1, 0, /* color planes */
4171 32, 0, /* bpp */
4172 3, 0, 0, 0, /* compression, BI_BITFIELDS */
4173 32, 0, 0, 0, /* Size of image pixel */
4174 0x13,0x0b,0x00,0x00, /* XPelsPerMeter */
4175 0x13,0x0b,0x00,0x00, /* YPelsPerMeter */
4176 0, 0, 0, 0, /* palette */
4177 0, 0, 0, 0, /* important colors */
4178 0, 0xFF, 0, 0, /* red mask */
4179 0, 0, 0xFF, 0, /* green mask */
4180 0, 0, 0, 0xFF, /* blue mask */
4181 0xFF, 0, 0, 0, /* alpha mask */
4182 0x20, 0x6E, 0x69, 0x57, /* LCS_WINDOWS_COLOR_SPACE */
4183 0, 0, 0, 0, /* CIEXYZTRIPLE */
4184 0, 0, 0, 0,
4185 0, 0, 0, 0,
4186 0, 0, 0, 0,
4187 0, 0, 0, 0,
4188 0, 0, 0, 0,
4189 0, 0, 0, 0,
4190 0, 0, 0, 0,
4191 0, 0, 0, 0,
4192 0, 0, 0, 0, /* red gamma */
4193 0, 0, 0, 0, /* green gamma */
4194 0, 0, 0, 0, /* blue gamma */
4195 };
4196 GSM_Error error;
4197 int tmp;
4198
4199 /* Get screen size */
4200 error = GSM_WaitFor(s, req_screen, 6, 0x0E, 4, ID_GetScreenSize);
4201 if (error != ERR_NONE) {
4202 return error;
4203 }
4204
4205 /* Allocate buffer */
4206 s->Phone.Data.Picture = picture;
4207 picture->Type = PICTURE_BMP;
4208 picture->Buffer = malloc(sizeof(bmp_header));
4209 if (picture->Buffer == NULL) {
4210 return ERR_MOREMEMORY;
4211 }
4212 memcpy(picture->Buffer, bmp_header, sizeof(bmp_header));
4213 picture->Length = sizeof(bmp_header);
4214
4215 /* Fill BMP header */
4216 #define STORE_INT(data, pos) picture->Buffer[pos] = data & 0xff; picture->Buffer[pos + 1] = (data >> 8) & 0xff; picture->Buffer[pos + 2] = (data >> 16) & 0xff; picture->Buffer[pos + 3] = (data >> 24) & 0xff;
4217 /* Size */
4218 tmp = 0x7a + (s->Phone.Data.Priv.N6510.ScreenWidth * s->Phone.Data.Priv.N6510.ScreenHeight * 4);
4219 STORE_INT(tmp, 2);
4220 tmp = s->Phone.Data.Priv.N6510.ScreenWidth;
4221 STORE_INT(tmp, 18);
4222 tmp = -s->Phone.Data.Priv.N6510.ScreenHeight;
4223 STORE_INT(tmp, 22);
4224
4225 /* And fill in bitmap */
4226 return GSM_WaitFor(s, req_data, 6, 0x0E, 4, ID_Screenshot);
4227 }
4228
4229
4230 static GSM_Reply_Function N6510ReplyFunctions[] = {
4231 {N71_65_ReplyCallInfo, "\x01",0x03,0x02,ID_IncomingFrame },
4232 {N71_65_ReplyCallInfo, "\x01",0x03,0x03,ID_IncomingFrame },
4233 {N71_65_ReplyCallInfo, "\x01",0x03,0x04,ID_IncomingFrame },
4234 {N71_65_ReplyCallInfo, "\x01",0x03,0x05,ID_IncomingFrame },
4235 {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_AnswerCall },
4236 {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_IncomingFrame },
4237 {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_CancelCall },
4238 {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_IncomingFrame },
4239 {N71_65_ReplyCallInfo, "\x01",0x03,0x0A,ID_IncomingFrame },
4240 {N71_65_ReplyCallInfo, "\x01",0x03,0x0B,ID_IncomingFrame },
4241 {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_DialVoice },
4242 {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_IncomingFrame },
4243 {N71_65_ReplyCallInfo, "\x01",0x03,0x0F,ID_IncomingFrame },
4244 {N71_65_ReplyCallInfo, "\x01",0x03,0x10,ID_DialVoice },
4245 {N71_65_ReplyCallInfo, "\x01",0x03,0x10,ID_IncomingFrame },
4246 {N71_65_ReplyCallInfo, "\x01",0x03,0x23,ID_IncomingFrame },
4247 {N71_65_ReplyCallInfo, "\x01",0x03,0x25,ID_IncomingFrame },
4248 {N71_65_ReplyCallInfo, "\x01",0x03,0x27,ID_IncomingFrame },
4249 {N71_65_ReplySendDTMF, "\x01",0x03,0x51,ID_SendDTMF },
4250 {N71_65_ReplySendDTMF, "\x01",0x03,0xf0,ID_SendDTMF },
4251 {N71_65_ReplyCallInfo, "\x01",0x03,0x53,ID_IncomingFrame },
4252 {N71_65_ReplySendDTMF, "\x01",0x03,0x59,ID_SendDTMF },
4253 {N71_65_ReplySendDTMF, "\x01",0x03,0x5E,ID_SendDTMF },
4254 {N71_65_ReplyCallInfo, "\x01",0x03,0xA6,ID_IncomingFrame },
4255 {N71_65_ReplyCallInfo, "\x01",0x03,0xD2,ID_IncomingFrame },
4256 {N71_65_ReplyCallInfo, "\x01",0x03,0xD3,ID_IncomingFrame },
4257 {N6510_ReplyPressKey, "\x01",0x03,0x33,ID_PressKey },
4258 {N6510_ReplyPressKey, "\x01",0x03,0x12,ID_PressKey },
4259
4260 {N6510_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame },
4261 {N6510_ReplyIncomingSMS, "\x02",0x03,0x04,ID_IncomingFrame },
4262 {N6510_ReplySetSMSC, "\x02",0x03,0x13,ID_SetSMSC },
4263 {N6510_ReplyGetSMSC, "\x02",0x03,0x15,ID_GetSMSC },
4264 {N6510_ReplyIncomingCB, "\x02",0x03,0x21,ID_IncomingFrame },
4265 {N6510_ReplyIncomingCB, "\x02",0x03,0x22,ID_IncomingFrame },
4266 {N6510_ReplyIncomingCB, "\x02",0x03,0x23,ID_IncomingFrame },
4267
4268 {N6510_ReplyGetMemoryStatus, "\x03",0x03,0x04,ID_GetMemoryStatus },
4269 {N6510_ReplyGetMemory, "\x03",0x03,0x08,ID_GetMemory },
4270 {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetBitmap },
4271 {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetMemory },
4272 {N6510_ReplyDeleteMemory, "\x03",0x03,0x10,ID_SetMemory },
4273
4274 {DCT3DCT4_ReplyCallDivert, "\x06",0x03,0x02,ID_Divert },
4275 {N71_65_ReplyUSSDInfo, "\x06",0x03,0x03,ID_IncomingFrame },
4276 {NoneReply, "\x06",0x03,0x06,ID_IncomingFrame },
4277 {NoneReply, "\x06",0x03,0x09,ID_IncomingFrame },
4278
4279 {N6510_ReplyEnterSecurityCode, "\x08",0x03,0x08,ID_EnterSecurityCode },
4280 {N6510_ReplyEnterSecurityCode, "\x08",0x03,0x09,ID_EnterSecurityCode },
4281 {N6510_ReplyGetSecurityStatus, "\x08",0x03,0x12,ID_GetSecurityStatus },
4282 {N6510_ReplyGetSecurityStatus, "\x08",0x03,0xf0,ID_GetSecurityStatus },
4283
4284 {N6510_ReplyGetNetworkInfo, "\x0A",0x03,0x01,ID_GetNetworkInfo },
4285 {N6510_ReplyGetNetworkInfo, "\x0A",0x03,0xf0,ID_GetNetworkInfo },
4286 {N6510_ReplyGetSignalQuality, "\x0A",0x03,0x0C,ID_GetSignalQuality },
4287 {N6510_ReplyGetOperatorLogo, "\x0A",0x03,0x24,ID_GetBitmap },
4288 {N6510_ReplyGetOperatorLogo, "\x0A",0x03,0xf0,ID_GetBitmap },
4289 {N6510_ReplySetOperatorLogo, "\x0A",0x03,0x26,ID_SetBitmap },
4290 /* This needs to be last of type */
4291 {N6510_ReplyGetNetworkInfo, "\x0A",0x03,0x01,ID_IncomingFrame },
4292 {N6510_ReplyLogIntoNetwork, "\x0A",0x03,0x02,ID_IncomingFrame },
4293 {NoneReply, "\x0A",0x03,0x16,ID_IncomingFrame },
4294 {N6510_ReplyGetIncSignalQuality, "\x0A",0x03,0x1E,ID_IncomingFrame },
4295 {NoneReply, "\x0A",0x03,0x20,ID_IncomingFrame },
4296 {N6510_ReplyGetNetworkInfo, "\x0A",0x03,0xf0,ID_IncomingFrame },
4297
4298 {NoneReply, "\x0B",0x03,0x01,ID_PlayTone },
4299 {NoneReply, "\x0B",0x03,0x15,ID_PlayTone },
4300 {NoneReply, "\x0B",0x03,0x16,ID_PlayTone },
4301
4302 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x02,ID_SetCalendarNote },
4303 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x04,ID_SetCalendarNote },
4304 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x06,ID_SetCalendarNote },
4305 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x08,ID_SetCalendarNote },
4306 {N71_65_ReplyDelCalendar, "\x13",0x03,0x0C,ID_DeleteCalendarNote },
4307 {N71_65_ReplyDelCalendar, "\x13",0x03,0xF0,ID_DeleteCalendarNote },
4308 {N71_65_ReplyGetNextCalendar1, "\x13",0x03,0x1A,ID_GetCalendarNote },/*method 1*/
4309 {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0x32,ID_GetCalendarNotePos },/*method 1*/
4310 {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0xF0,ID_GetCalendarNotePos },/*method 1*/
4311 {N6510_ReplyGetCalendarInfo, "\x13",0x03,0x3B,ID_GetCalendarNotesInfo},/*method 1*/
4312 #ifdef DEBUG
4313 {N71_65_ReplyGetNextCalendar2, "\x13",0x03,0x3F,ID_GetCalendarNote },
4314 #endif
4315 {N71_65_ReplyAddCalendar2, "\x13",0x03,0x41,ID_SetCalendarNote },/*method 2*/
4316 {N6510_ReplyAddCalendar3, "\x13",0x03,0x66,ID_SetCalendarNote },/*method 3*/
4317 {N6510_ReplyAddToDo2, "\x13",0x03,0x66,ID_SetToDo },
4318 {N6510_ReplyAddNote, "\x13",0x03,0x66,ID_SetNote },
4319 {N6510_ReplyGetCalendar3, "\x13",0x03,0x7E,ID_GetCalendarNote },/*method 3*/
4320 {N6510_ReplyGetToDo2, "\x13",0x03,0x7E,ID_GetToDo },
4321 {N6510_ReplyGetNote, "\x13",0x03,0x7E,ID_GetNote },
4322 {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x86,ID_GetCalendarSettings },
4323 {N6510_ReplyGetLocale, "\x13",0x03,0x8A,ID_GetLocale },
4324 {N6510_ReplyGetCalendarSettings, "\x13",0x03,0x8E,ID_GetCalendarSettings },
4325 {N6510_ReplyGetCalendarNotePos, "\x13",0x03,0x96,ID_GetCalendarNotePos },/*method 3*/
4326 {N6510_ReplyGetToDoFirstLoc2, "\x13",0x03,0x96,ID_SetToDo },
4327 {N6510_ReplyGetNoteFirstLoc, "\x13",0x03,0x96,ID_SetNote },
4328 {N6510_ReplyGetCalendarInfo, "\x13",0x03,0x9F,ID_GetCalendarNotesInfo},/*method 3*/
4329 {N6510_ReplyGetToDoStatus2, "\x13",0x03,0x9F,ID_GetToDo },
4330 {N6510_ReplyGetNoteInfo, "\x13",0x03,0x9F,ID_GetNote },
4331
4332 {N6510_ReplySaveSMSMessage, "\x14",0x03,0x01,ID_SaveSMSMessage },
4333 {N6510_ReplySetPicture, "\x14",0x03,0x01,ID_SetBitmap },
4334 {N6510_ReplyGetSMSMessage, "\x14",0x03,0x03,ID_GetSMSMessage },
4335 {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x05,ID_DeleteSMSMessage },
4336 {N6510_ReplyDeleteSMSMessage, "\x14",0x03,0x06,ID_DeleteSMSMessage },
4337 {N6510_ReplyGetSMSStatus, "\x14",0x03,0x09,ID_GetSMSStatus },
4338 {N6510_ReplyGetSMSFolderStatus, "\x14",0x03,0x0d,ID_GetSMSFolderStatus },
4339 {N6510_ReplyGetSMSMessage, "\x14",0x03,0x0f,ID_GetSMSMessage },
4340 {N6510_ReplyAddSMSFolder, "\x14",0x03,0x11,ID_AddSMSFolder },
4341 {N6510_ReplyGetSMSFolders, "\x14",0x03,0x13,ID_GetSMSFolders },
4342 {N6510_ReplySaveSMSMessage, "\x14",0x03,0x17,ID_SaveSMSMessage },
4343 {N6510_ReplyGetSMSStatus, "\x14",0x03,0x1a,ID_GetSMSStatus },
4344 {N6510_ReplyGetSMSStatus, "\x14",0x03,0xf0,ID_GetSMSStatus },
4345
4346 {DCT4_ReplySetPhoneMode, "\x15",0x03,0x64,ID_Reset },
4347 {DCT4_ReplyGetPhoneMode, "\x15",0x03,0x65,ID_Reset },
4348 {NoneReply, "\x15",0x03,0x68,ID_Reset },
4349
4350 {N6510_ReplyGetBatteryCharge, "\x17",0x03,0x0B,ID_GetBatteryCharge },
4351 {N6510_IncomingBatteryCharge, "\x17",0x03,0x2c,ID_IncomingFrame },
4352
4353 {N6510_ReplySetDateTime, "\x19",0x03,0x02,ID_SetDateTime },
4354 {N6510_ReplyGetDateTime, "\x19",0x03,0x0B,ID_GetDateTime },
4355 {N6510_ReplySetAlarm, "\x19",0x03,0x12,ID_SetAlarm },
4356 {N6510_ReplyGetAlarm, "\x19",0x03,0x1A,ID_GetAlarm },
4357 {N6510_ReplyGetAlarm, "\x19",0x03,0x20,ID_GetAlarm },
4358
4359 {DCT4_ReplyGetIMEI, "\x1B",0x03,0x01,ID_GetIMEI },
4360 {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x08,ID_GetHardware },
4361 {N6510_ReplyGetPPM, "\x1B",0x03,0x08,ID_GetPPM },
4362 {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x0C,ID_GetProductCode },
4363
4364 /* 0x1C - vibra */
4365
4366 {N6510_ReplyGetRingtonesInfo, "\x1f",0x03,0x08,ID_GetRingtonesInfo },
4367 {N6510_ReplyDeleteRingtones, "\x1f",0x03,0x11,ID_SetRingtone },
4368 {N6510_ReplyGetRingtone, "\x1f",0x03,0x13,ID_GetRingtone },
4369 {N6510_ReplySetBinRingtone, "\x1f",0x03,0x0F,ID_SetRingtone },
4370
4371 /* 0x23 - voice records */
4372
4373 {N6510_ReplyGetProfile, "\x39",0x03,0x02,ID_GetProfile },
4374 {N6510_ReplySetProfile, "\x39",0x03,0x04,ID_SetProfile },
4375 {N6510_ReplyGetProfile, "\x39",0x03,0x06,ID_GetProfile },
4376
4377 {N6510_ReplySetLight, "\x3A",0x03,0x06,ID_SetLight },
4378
4379 {N6510_ReplyGetFMStation, "\x3E",0x03,0x06,ID_GetFMStation },
4380 {N6510_ReplyGetFMStatus, "\x3E",0x03,0x0E,ID_GetFMStation },
4381 {N6510_ReplySetFMStation, "\x3E",0x03,0x15,ID_SetFMStation },
4382 {N6510_ReplyGetFMStation, "\x3E",0x03,0x16,ID_GetFMStation },
4383 {N6510_ReplyGetFMStation, "\x3E",0x03,0xF0,ID_GetFMStation },
4384
4385 {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x01,ID_EnableConnectFunc },
4386 {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x02,ID_EnableConnectFunc },
4387 {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x04,ID_DisableConnectFunc },
4388 {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x05,ID_DisableConnectFunc },
4389 {N6510_ReplyGetWAPBookmark, "\x3f",0x03,0x07,ID_GetWAPBookmark },
4390 {N6510_ReplyGetWAPBookmark, "\x3f",0x03,0x08,ID_GetWAPBookmark },
4391 {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0A,ID_SetWAPBookmark },
4392 {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0B,ID_SetWAPBookmark },
4393 {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0D,ID_DeleteWAPBookmark },
4394 {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0E,ID_DeleteWAPBookmark },
4395 {DCT3DCT4_ReplyGetActiveConnectSet,"\x3f",0x03,0x10,ID_GetConnectSet },
4396 {DCT3DCT4_ReplySetActiveConnectSet,"\x3f",0x03,0x13,ID_SetConnectSet },
4397 {N6510_ReplyGetConnectionSettings,"\x3f",0x03,0x11,ID_GetConnectSet },
4398 {N6510_ReplyGetConnectionSettings,"\x3f",0x03,0x16,ID_GetConnectSet },
4399 {N6510_ReplyGetConnectionSettings,"\x3f",0x03,0x17,ID_GetConnectSet },
4400 {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x19,ID_SetConnectSet },
4401 {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x1A,ID_SetConnectSet },
4402 {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x28,ID_SetConnectSet },
4403 {N6510_ReplySetConnectionSettings,"\x3f",0x03,0x2B,ID_SetConnectSet },
4404 {N6510_ReplyGetChatSettings, "\x3f",0x03,0x3B,ID_GetChatSettings },
4405 {N6510_ReplyGetChatSettings, "\x3f",0x03,0x3C,ID_GetChatSettings },
4406 {N6510_ReplyGetConnectionSettings,"\x3f",0x03,0xf0,ID_GetConnectSet },
4407
4408 {N6510_ReplyGetOriginalIMEI, "\x42",0x07,0x00,ID_GetOriginalIMEI },
4409 {N6510_ReplyGetManufactureMonth, "\x42",0x07,0x00,ID_GetManufactureMonth },
4410 {N6510_ReplyGetOriginalIMEI, "\x42",0x07,0x01,ID_GetOriginalIMEI },
4411 {N6510_ReplyGetManufactureMonth, "\x42",0x07,0x02,ID_GetManufactureMonth },
4412
4413 {N6510_ReplySetOperatorLogo, "\x43",0x03,0x08,ID_SetBitmap },
4414 {N6510_ReplyGetGPRSAccessPoint, "\x43",0x03,0x06,ID_GetGPRSPoint },
4415 {N6510_ReplySetGPRSAccessPoint1, "\x43",0x03,0x06,ID_SetGPRSPoint },
4416 {N6510_ReplyGetSyncMLSettings, "\x43",0x03,0x06,ID_GetSyncMLSettings },
4417 {N6510_ReplyGetSyncMLName, "\x43",0x03,0x06,ID_GetSyncMLName },
4418 {NoneReply, "\x43",0x03,0x08,ID_SetGPRSPoint },
4419
4420 /* 0x4A - voice records */
4421
4422 /* 0x53 - simlock */
4423
4424 {N6510_ReplyAddToDo1, "\x55",0x03,0x02,ID_SetToDo },
4425 {N6510_ReplyGetToDo1, "\x55",0x03,0x04,ID_GetToDo },
4426 {N6510_ReplyGetToDoFirstLoc1, "\x55",0x03,0x10,ID_SetToDo },
4427 {N6510_ReplyDeleteAllToDo1, "\x55",0x03,0x12,ID_DeleteAllToDo },
4428 {N6510_ReplyGetToDoStatus1, "\x55",0x03,0x16,ID_GetToDo },
4429
4430 {N6510_ReplyAddFileHeader1, "\x6D",0x03,0x03,ID_AddFile },
4431 {N6510_ReplyAddFolder1, "\x6D",0x03,0x05,ID_AddFolder },
4432 {N6510_ReplyGetFilePart12, "\x6D",0x03,0x0F,ID_GetFile },/* filesystem1&2 */
4433 {N6510_ReplyAddFileHeader1, "\x6D",0x03,0x13,ID_AddFile },
4434 {N6510_ReplyGetFileFolderInfo1, "\x6D",0x03,0x15,ID_GetFileInfo },
4435 {NoneReply, "\x6D",0x03,0x19,ID_SetAttrib },
4436 {N6510_ReplyDeleteFileFolder1, "\x6D",0x03,0x1F,ID_DeleteFile },
4437 {N6510_ReplyGetFileSystemStatus1, "\x6D",0x03,0x23,ID_FileSystemStatus },
4438 {N6510_ReplyGetFileFolderInfo1, "\x6D",0x03,0x2F,ID_GetFileInfo },
4439 {N6510_ReplyGetFileSystemStatus1, "\x6D",0x03,0x2F,ID_FileSystemStatus },
4440 {N6510_ReplyGetFileFolderInfo1, "\x6D",0x03,0x33,ID_GetFileInfo },
4441 {N6510_ReplyGetFileFolderInfo1, "\x6D",0x03,0xF0,ID_GetFileInfo },
4442 {N6510_ReplyAddFilePart1, "\x6D",0x03,0x41,ID_AddFile },
4443 {N6510_ReplyGetFileCRC12, "\x6D",0x03,0x43,ID_GetCRC },
4444 {NoneReply, "\x6D",0x03,0x59,ID_AddFile },/* filesystem2 */
4445 {N6510_ReplyGetFilePart12, "\x6D",0x03,0x5F,ID_GetFile },/* filesystem2 */
4446 {N6510_ReplyDeleteFile2, "\x6D",0x03,0x63,ID_DeleteFile },/* filesystem2 */
4447 {N6510_ReplyAddFolder2, "\x6D",0x03,0x65,ID_AddFolder },/* filesystem2 */
4448 {N6510_ReplyGetFileCRC12, "\x6D",0x03,0x67,ID_GetCRC },/* filesystem2 */
4449 {N6510_ReplyGetFileFolderInfo2, "\x6D",0x03,0x69,ID_IncomingFrame },/* filesystem2 */
4450 {N6510_ReplyDeleteFolder2, "\x6D",0x03,0x6B,ID_DeleteFolder },/* filesystem2 */
4451 {N6510_ReplyGetFileFolderInfo2, "\x6D",0x03,0x6D,ID_GetFileInfo },/* filesystem2 */
4452 {N6510_ReplySetAttrib2, "\x6D",0x03,0x6F,ID_SetAttrib },/* filesystem2 */
4453 {N6510_ReplyOpenFile2, "\x6D",0x03,0x73,ID_OpenFile },/* filesystem2 */
4454 {NoneReply, "\x6D",0x03,0x75,ID_CloseFile },/* filesystem2 */
4455 {N6510_ReplySetFileDate2, "\x6D",0x03,0x87,ID_AddFile },/* filesystem2 */
4456
4457 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x01,ID_GetBitmap },
4458 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x01,ID_SetBitmap },
4459 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x0F,ID_GetBitmap },
4460 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x0F,ID_SetBitmap },
4461 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x10,ID_GetBitmap },
4462 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x10,ID_SetBitmap },
4463 {N6510_ReplyStartupNoteLogo, "\x7A",0x04,0x25,ID_SetBitmap },
4464
4465 {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetModel },
4466 {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetFirmware },
4467
4468 /* 0xD7 - Bluetooth */
4469
4470 {N6510_ReplyGetRingtoneID, "\xDB",0x03,0x02,ID_SetRingtone },
4471
4472 {DCT4_ReplyGetScreenDump, "\x0E",0x00,0x00,ID_Screenshot },
4473 {DCT4_ReplyGetScreenInfo, "\x0E",0x00,0x00,ID_GetScreenSize },
4474
4475 {NULL, "\x00",0x00,0x00,ID_None }
4476 };
4477
4478 GSM_Phone_Functions N6510Phone = {
4479 "1100|1100a|1100b|1112|1200|1209|1600|1650|1680|2600|2610|2630|2650|2660|2680|2760|3100|3100b|3105|3108|3109c|3200|3200a|3205|3220|3300|3510|3510i|3530|3589i|3590|3595|5000|5100|5140|5140i|5200|5220|5300|5310|6020|6020b|6021|6030|6060|6070|6085|6086|6100|6101|6103|6111|6125|6131|6151|6170|6200|6220|6220c|6225|6230|6230i|6233|6234|6270|6275i|6280|6300|6303c|6310|6310i|6340i|6385|6500c|6500s|6510|6600|6610|6610i|6800|6810|6820|6822|7200|7210|7210s|7230|7250|7250i|7260|7270|7360|7370|7500|7600|7900|8310|8390|8800|8910|8910i",
4480 N6510ReplyFunctions,
4481 NOTSUPPORTED, /* Install */
4482 N6510_Initialise,
4483 N6510_Terminate,
4484 GSM_DispatchMessage,
4485 N6510_ShowStartInfo,
4486 NOKIA_GetManufacturer,
4487 DCT3DCT4_GetModel,
4488 DCT3DCT4_GetFirmware,
4489 DCT4_GetIMEI,
4490 N6510_GetOriginalIMEI,
4491 N6510_GetManufactureMonth,
4492 DCT4_GetProductCode,
4493 DCT4_GetHardware,
4494 N6510_GetPPM,
4495 NOTSUPPORTED, /* GetSIMIMSI */
4496 N6510_GetDateTime,
4497 N6510_SetDateTime,
4498 N6510_GetAlarm,
4499 N6510_SetAlarm,
4500 N6510_GetLocale,
4501 NOTSUPPORTED, /* SetLocale */
4502 N6510_PressKey,
4503 DCT4_Reset,
4504 NOTIMPLEMENTED, /* ResetPhoneSettings */
4505 N6510_EnterSecurityCode,
4506 N6510_GetSecurityStatus,
4507 NOTSUPPORTED, /* GetDisplayStatus */
4508 NOTIMPLEMENTED, /* SetAutoNetworkLogin */
4509 N6510_GetBatteryCharge,
4510 N6510_GetSignalQuality,
4511 N6510_GetNetworkInfo,
4512 NOTSUPPORTED, /* GetCategory */
4513 NOTSUPPORTED, /* AddCategory */
4514 NOTSUPPORTED, /* GetCategoryStatus */
4515 N6510_GetMemoryStatus,
4516 N6510_GetMemory,
4517 NOTIMPLEMENTED, /* GetNextMemory */
4518 N6510_SetMemory,
4519 N6510_AddMemory,
4520 N6510_DeleteMemory,
4521 NOTIMPLEMENTED, /* DeleteAllMemory */
4522 N6510_GetSpeedDial,
4523 NOTIMPLEMENTED, /* SetSpeedDial */
4524 N6510_GetSMSC,
4525 N6510_SetSMSC,
4526 N6510_GetSMSStatus,
4527 N6510_GetSMSMessage,
4528 N6510_GetNextSMSMessage,
4529 N6510_SetSMS,
4530 N6510_AddSMS,
4531 N6510_DeleteSMSMessage,
4532 N6510_SendSMSMessage,
4533 NOTSUPPORTED, /* SendSavedSMS */
4534 NOTSUPPORTED, /* SetFastSMSSending */
4535 NOKIA_SetIncomingSMS,
4536 NOTIMPLEMENTED, /* SetIncomingCB */
4537 N6510_GetSMSFolders,
4538 N6510_AddSMSFolder,
4539 NOTIMPLEMENTED, /* DeleteSMSFolder */
4540 N6510_DialVoice,
4541 NOTIMPLEMENTED, /* DialService */
4542 N6510_AnswerCall,
4543 N6510_CancelCall,
4544 NOTIMPLEMENTED, /* HoldCall */
4545 NOTIMPLEMENTED, /* UnholdCall */
4546 NOTIMPLEMENTED, /* ConferenceCall */
4547 NOTIMPLEMENTED, /* SplitCall */
4548 NOTIMPLEMENTED, /* TransferCall */
4549 NOTIMPLEMENTED, /* SwitchCall */
4550 DCT3DCT4_GetCallDivert,
4551 DCT3DCT4_SetCallDivert,
4552 DCT3DCT4_CancelAllDiverts,
4553 NOKIA_SetIncomingCall,
4554 NOKIA_SetIncomingUSSD,
4555 DCT3DCT4_SendDTMF,
4556 N6510_GetRingtone,
4557 N6510_SetRingtone,
4558 N6510_GetRingtonesInfo,
4559 N6510_DeleteUserRingtones,
4560 N6510_PlayTone,
4561 N6510_GetWAPBookmark,
4562 N6510_SetWAPBookmark,
4563 N6510_DeleteWAPBookmark,
4564 N6510_GetWAPSettings,
4565 N6510_SetWAPSettings,
4566 N6510_GetSyncMLSettings,
4567 NOTSUPPORTED, /* SetSyncMLSettings */
4568 N6510_GetChatSettings,
4569 NOTSUPPORTED, /* SetChatSettings */
4570 N6510_GetMMSSettings,
4571 N6510_SetMMSSettings,
4572 N6510_GetMMSFolders,
4573 N6510_GetNextMMSFileInfo,
4574 N6510_GetBitmap,
4575 N6510_SetBitmap,
4576 N6510_GetToDoStatus,
4577 NOTIMPLEMENTED, /* GetToDo */
4578 N6510_GetNextToDo,
4579 NOTIMPLEMENTED, /* SetToDo */
4580 N6510_AddToDo,
4581 N6510_DeleteToDo2,
4582 N6510_DeleteAllToDo1,
4583 N6510_GetCalendarStatus,
4584 NOTIMPLEMENTED, /* GetCalendar */
4585 N6510_GetNextCalendar,
4586 NOTIMPLEMENTED, /* SetCalendar */
4587 N6510_AddCalendar,
4588 N71_65_DelCalendar,
4589 NOTIMPLEMENTED, /* DeleteAllCalendar */
4590 N6510_GetCalendarSettings,
4591 NOTSUPPORTED, /* SetCalendarSettings */
4592 N6510_GetNoteStatus,
4593 NOTIMPLEMENTED, /* GetNote */
4594 N6510_GetNextNote,
4595 NOTIMPLEMENTED, /* SetNote */
4596 N6510_AddNote,
4597 N6510_DeleteNote,
4598 NOTSUPPORTED, /* DeleteAllNotes */
4599 N6510_GetProfile,
4600 N6510_SetProfile,
4601 N6510_GetFMStation,
4602 N6510_SetFMStation,
4603 N6510_ClearFMStations,
4604 N6510_GetNextFileFolder,
4605 N6510_GetFolderListing,
4606 N6510_GetNextRootFolder,
4607 N6510_SetFileAttributes,
4608 N6510_GetFilePart,
4609 N6510_AddFilePart,
4610 NOTSUPPORTED, /* SendFilePart */
4611 N6510_GetFileSystemStatus,
4612 N6510_DeleteFile,
4613 N6510_AddFolder,
4614 N6510_DeleteFolder,
4615 N6510_GetGPRSAccessPoint,
4616 N6510_SetGPRSAccessPoint,
4617 DCT4_Screenshot,
4618 NOTSUPPORTED, /* SetPower */
4619 NOTSUPPORTED, /* PostConnect */
4620 NONEFUNCTION /* PreAPICall */
4621 };
4622
4623 #endif
4624
4625 /* How should editor hadle tabs in this file? Add editor commands here.
4626 * vim: noexpandtab sw=8 ts=8 sts=8:
4627 */
4628