Gammu internals  1.38.0
n6510.c
Go to the documentation of this file.
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 
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;
57  s->Phone.Data.Priv.N6510.Timeout = 40;
58  }
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 
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 
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 
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 
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 
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);
143  smprintf(s, "Free : %i\n",Data->MemoryStatus->MemoryFree);
144  return ERR_NONE;
145 }
146 
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 
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 
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  }
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 
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 
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 
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 
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 
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 
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 
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 
554  Data->SMSFolders->Folder[2].Memory = MEM_ME;
555  Data->SMSFolders->Folder[2].InboxFolder = TRUE;
556  Data->SMSFolders->Folder[2].OutboxFolder = FALSE;
557 
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 
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 
597 static GSM_Error N6510_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders)
598 {
599  unsigned char req[] = {N6110_FRAME_HEADER, 0x12, 0x00, 0x00};
600 
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 
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");
626  return ERR_NONE;
627 }
628 
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 
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 
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 
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 
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 
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");
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:
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;
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));
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
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;
835  Data->Bitmap->BitmapWidth = Width;
836  Data->Bitmap->BitmapHeight = Height;
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 
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[] = {
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 
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 
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 
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 
937  }
938 
939  /* Clear SMS structure of any possible junk */
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 
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 
999 static GSM_Error N6510_GetNextSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboolean start)
1000 {
1003  return N6510_GetNextFilesystemSMS(s,sms,start);
1004  }
1005 
1006  return N6510_GetNextSMSMessageBitmap(s, sms, start, NULL);
1007 }
1008 
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");
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 
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 
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:
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);
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 
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 
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 
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 
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 
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 
1169 static GSM_Error N6510_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat)
1170 {
1171  unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x02, 0x00};
1172 
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 
1179 static GSM_Error N6510_ReplyGetWAPBookmark(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1180 {
1181  return DCT3DCT4_ReplyGetWAPBookmark (msg, s, TRUE);
1182 }
1183 
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  }
1196  smprintf(s, "Network code %s\n",Data->Bitmap->NetworkCode);
1197  Data->Bitmap->BitmapWidth = msg->Buffer[20];
1198  Data->Bitmap->BitmapHeight = msg->Buffer[21];
1200  return ERR_NONE;
1201 }
1202 
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 
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 
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 
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 
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 
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 */
1336  req[11] = MEM6510_CG2;
1337  } else {
1338  req[11] = MEM7110_CG;
1339  }
1340 
1341  req[13] = bitmap->Location;
1342 
1343  /* Enabling/disabling logo */
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) {
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;
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 */
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) {
1396  /* write N6510_PBK_PICTURE_ID ? */
1397  } else {
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 
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 
1420 static GSM_Error N6510_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
1421 {
1422  GSM_SMSMessage sms;
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] = {
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) {
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);
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  }
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);
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 
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 
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 
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 
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 
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 
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 
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 
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 
1708 
1712 
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 
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);
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);
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;
1788 
1789  Data->WAPSettings->Settings[0].IsSecurity = FALSE;
1790  if (msg->Buffer[tmp+1] == 0x01) Data->WAPSettings->Settings[0].IsSecurity = TRUE;
1792 
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 */
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
1835  if (msg->Buffer[tmp]==0x01) Data->WAPSettings->Settings[0].IsNormalAuthentication=FALSE;
1836 
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]);
1847  break;
1848  }
1849 
1851  if (msg->Buffer[tmp+4]==0x00) Data->WAPSettings->Settings[0].ManualLogin = TRUE;
1852 
1853  tmp+=5;
1854 
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 */
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
1898  if (msg->Buffer[tmp]==0x01) Data->WAPSettings->Settings[num].IsNormalAuthentication=FALSE;
1899 
1900  Data->WAPSettings->Settings[num].IsISDNCall=FALSE;
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 
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 
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 
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) {
2027  }
2028  return error;
2029  }
2030 
2032  if (error != ERR_NONE) return error;
2033 
2035 }
2036 
2037 static GSM_Error N6510_GetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2038 {
2039  return N6510_GetConnectionSettings(s, settings, N6510_WAP_SETTINGS);
2040 }
2041 
2042 static GSM_Error N6510_GetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2043 {
2044  return N6510_GetConnectionSettings(s, settings, N6510_MMS_SETTINGS);
2045 }
2046 
2047 static GSM_Error N6510_ReplyGetSyncMLSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2048 {
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 
2066 static GSM_Error N6510_ReplyGetSyncMLName(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2067 {
2069 
2070  smprintf(s, "SyncML names received OK\n");
2071 
2072  CopyUnicodeString(Sett->Name,msg->Buffer+18);
2073 
2074  return ERR_NONE;
2075 }
2076 
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 
2110 static GSM_Error N6510_ReplyGetChatSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2111 {
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 
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 
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 
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  }
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  }
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 
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) {
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 
2517 }
2518 
2519 static GSM_Error N6510_SetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2520 {
2521  return N6510_SetConnectionSettings(s, settings, N6510_WAP_SETTINGS);
2522 }
2523 
2524 static GSM_Error N6510_SetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2525 {
2526  return N6510_SetConnectionSettings(s, settings, N6510_MMS_SETTINGS);
2527 }
2528 
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 
2539 static GSM_Error N6510_GetOriginalIMEI(GSM_StateMachine *s, char *value)
2540 {
2542 
2543  return NOKIA_GetPhoneString(s,"\x00\x07\x02\x01\x00\x01",6,0x42,value,ID_GetOriginalIMEI,14);
2544 }
2545 
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 
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 
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 
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 
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 
2639  }
2640 
2641  N6510_GetSMSLocation(s, sms, &folderid, &location);
2642 
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 
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 
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 
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 
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 
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 
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 
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;
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 
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 
2838  }
2839 
2840  N6510_GetSMSLocation(s, sms, &folderid, &location);
2841  if (folderid == 0x99) return ERR_INVALIDLOCATION;
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 
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 
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 
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 
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 
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) {
2968  return ERR_NONE;
2969  }
2970  smprintf(s, "Not set in phone\n");
2971  return ERR_EMPTY;
2972 }
2973 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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,
3115  tmp = tmp + (msg->Buffer[tmp]*256+msg->Buffer[tmp+1]);
3116  }
3117  return ERR_NONE;
3118 }
3119 
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 
3141 static GSM_Error N6510_GetRingtonesInfo(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info)
3142 {
3143  return N6510_PrivGetRingtonesInfo(s, Info, TRUE);
3144 }
3145 
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 
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 
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 
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 
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 
3328 static GSM_Error N6510_GetSpeedDial(GSM_StateMachine *s, GSM_SpeedDial *SpeedDial)
3329 {
3330  GSM_MemoryEntry pbk;
3331  GSM_Error error;
3332 
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 
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");
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) {
3386  Data->Profile->FeaturesNumber++;
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 
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 
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 
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 
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 
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:
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 
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 }
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 
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;
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 
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 
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 
3652 void N6510_DecodeFMFrequency(double *freq, unsigned char *buff)
3653 {
3654  *freq = (double)(0xffff + buff[0] * 0x100 + buff[1])/1000.0;
3655 }
3656 
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 
3665 static GSM_Error N6510_GetFMStatus(GSM_StateMachine *s)
3666 {
3667  unsigned char req[7] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x01};
3668 
3670  return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_GetFMStation);
3671 }
3672 
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;
3691  smprintf(s,"Station name: \"%s\"\n",DecodeUnicodeString(Data->FMStation->StationName));
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 
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 
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 
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 
3740 static GSM_Error N6510_ClearFMStations (GSM_StateMachine *s)
3741 {
3742  unsigned char req[7] = {N6110_FRAME_HEADER, 0x03,0x0f,0x00,0x01};
3743 
3745 
3746  smprintf(s, "Cleaning FM Stations\n");
3747  return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_SetFMStation);
3748 }
3749 
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 
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 
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 
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 
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 
3843 static GSM_Error N6510_ReplyGetGPRSAccessPoint(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3844 {
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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) {
4099  }
4100  return error;
4101  }
4102 
4104 }
4105 
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 
4117 GSM_Error N6510_GetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
4118 {
4119  GSM_Error error;
4120 
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 
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 
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 
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 },
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 
4386  {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x02,ID_EnableConnectFunc },
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 },
4394  {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0E,ID_DeleteWAPBookmark },
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 },
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,
4485  N6510_ShowStartInfo,
4489  DCT4_GetIMEI,
4490  N6510_GetOriginalIMEI,
4491  N6510_GetManufactureMonth,
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 */
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 */
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,
4574  N6510_GetBitmap,
4575  N6510_SetBitmap,
4577  NOTIMPLEMENTED, /* GetToDo */
4579  NOTIMPLEMENTED, /* SetToDo */
4580  N6510_AddToDo,
4584  NOTIMPLEMENTED, /* GetCalendar */
4586  NOTIMPLEMENTED, /* SetCalendar */
4589  NOTIMPLEMENTED, /* DeleteAllCalendar */
4591  NOTSUPPORTED, /* SetCalendarSettings */
4593  NOTIMPLEMENTED, /* GetNote */
4595  NOTIMPLEMENTED, /* SetNote */
4596  N6510_AddNote,
4598  NOTSUPPORTED, /* DeleteAllNotes */
4599  N6510_GetProfile,
4600  N6510_SetProfile,
4601  N6510_GetFMStation,
4602  N6510_SetFMStation,
4603  N6510_ClearFMStations,
4610  NOTSUPPORTED, /* SendFilePart */
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  */
unsigned char Text
GSM_SMSMessageType PDU
#define NOKIA_RELEASEPHONEKEY
Definition: ncommon.h:97
GSM_Error N6510_GetNextNote(GSM_StateMachine *s, GSM_NoteEntry *Note, gboolean start)
GSM_DateTime DateTime
GSM_SecurityCodeType * SecurityStatus
Definition: gsmstate.h:601
GSM_Error DCT3DCT4_ReplyGetActiveConnectSet(GSM_Protocol_Message *msg, GSM_StateMachine *s)
WAPSettings_Bearer ActiveBearer
Definition: gammu-wap.h:200
unsigned char TPUDL
char Server[(128+1) *2]
GSM_Error N71_65_ReplyDelCalendar(GSM_Protocol_Message *msg, GSM_StateMachine *s)
char IPAddress[(20+1) *2]
Definition: gammu-wap.h:128
unsigned char Name[(GSM_MAX_RINGTONE_NAME_LENGTH+1) *2]
GSM_Error N6510_ReplyDeleteFileFolder1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
void GSM_SetDefaultReceivedSMSData(GSM_SMSMessage *SMS)
Definition: gsmsms.c:1092
gboolean IsNormalAuthentication
Definition: gammu-wap.h:104
gboolean DefaultRingtone
Definition: gammu-bitmap.h:134
GSM_Profile_Feat_ID FeatureID[15]
char Name[(20+1) *2]
unsigned char ID
Definition: gammu-bitmap.h:168
GSM_Error N6510_ReplyGetFileFolderInfo1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_ChargeState ChargeState
Definition: gammu-info.h:244
GSM_Error N6510_ReplyGetCalendarInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
const unsigned char * GSM_GetNetworkName(const char *NetworkCode)
Definition: gsmnet.c:2420
GSM_Error DCT4_ReplySetPhoneMode(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_ReplyGetFileCRC12(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_ReplyGetToDoFirstLoc1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
char * DecodeUnicodeString(const unsigned char *src)
Definition: coding.c:245
int LastFreeMemoryLocation
Definition: n6510.h:71
void DumpMessage(GSM_Debug_Info *d, const unsigned char *message, const size_t messagesize)
Definition: debug.c:314
size_t PHONE_GetBitmapSize(GSM_Phone_Bitmap_Types Type, size_t Width, size_t Height)
Definition: gsmlogo.c:44
GSM_RingtoneFormat Format
GSM_Error DCT3DCT4_GetModel(GSM_StateMachine *s)
unsigned char Number[(GSM_MAX_NUMBER_LENGTH+1) *2]
char Title[(20+1) *2]
Definition: gammu-wap.h:79
void EncodeBCD(unsigned char *dest, const unsigned char *src, size_t len, gboolean fill)
Definition: coding.c:342
void CopyUnicodeString(unsigned char *Dest, const unsigned char *Source)
Definition: coding.c:1192
void NOKIA_DecodeSMSState(GSM_StateMachine *s, unsigned char state, GSM_SMSMessage *sms)
GSM_BinaryPicture * Picture
Definition: gsmstate.h:593
unsigned char TPDCS
GSM_Alarm * Alarm
Definition: gsmstate.h:493
GSM_WAPSettings Settings[4]
Definition: gammu-wap.h:172
void DecodeDefault(unsigned char *dest, const unsigned char *src, size_t len, gboolean UseExtensions, unsigned char *ExtraAlphabet)
Definition: coding.c:498
GSM_Error N6510_SetFileAttributes(GSM_StateMachine *s, GSM_File *File)
GSM_Error N6510_AddFilePart(GSM_StateMachine *s, GSM_File *File, size_t *Pos, int *Handle)
gboolean IsSecurity
Definition: gammu-wap.h:91
GSM_Error N6510_ReplyGetToDo2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
void NOKIA_SortSMSFolderStatus(GSM_StateMachine *s, GSM_NOKIASMSFolder *Folder)
GSM_Error NOKIA_SetIncomingUSSD(GSM_StateMachine *s, gboolean enable)
GSM_Error N6510_ReplyGetCalendarSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_SMS_State State
GSM_MemoryType LastFreeMemoryType
Definition: n6510.h:75
GSM_Error N6510_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
GSM_MemoryType MemoryType
Definition: gammu-memory.h:415
GSM_Error N6510_ReplySetFileDate2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error DCT3DCT4_GetWAPBookmarkPart(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
GSM_Error N6510_ReplyDeleteFolder2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Bitmap_Types Type
Definition: gammu-bitmap.h:107
int GSM_PackSemiOctetNumber(const unsigned char *Number, unsigned char *Output, gboolean semioctet)
Definition: coding.c:1125
char Code[GSM_SECURITY_CODE_LEN+1]
GSM_ConnectionType ConnectionType
Definition: gsmstate.h:1402
unsigned char SMSCTime
#define GSM_PHONE_MAXSMSINFOLDER
Definition: gammu-limits.h:70
#define NOTSUPPORTED
Definition: gsmcomon.h:14
GSM_MemoryEntry * Memory
Definition: gsmstate.h:497
GSM_Error N6510_ReplyGetFileSystemStatus1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
#define N6110_FRAME_HEADER
Definition: ncommon.h:8
unsigned char NetworkName[15 *2]
Definition: gammu-info.h:135
GSM_Error N6510_DeleteAllToDo1(GSM_StateMachine *s)
char Password[(50+1) *2]
GSM_MemoryType NOKIA_GetMemoryType(GSM_StateMachine *s, GSM_MemoryType memory_type, unsigned char *ID)
GSM_SMSMemoryStatus * SMSStatus
Definition: gsmstate.h:517
GSM_Error N71_65_DelCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
GSM_DateTime DateTime
GSM_MultiSMSMessage * GetSMSMessage
Definition: gsmstate.h:509
unsigned char Sender[2 *(GSM_MAX_NUMBER_LENGTH+1)]
Definition: gammu-bitmap.h:164
GSM_Error N6510_ReplyGetFilePart12(GSM_Protocol_Message *msg, GSM_StateMachine *s)
gboolean HeadSetProfile
GSM_Error N6510_ReplyAddFilePart1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status)
void NOKIA_EncodeDateTime(GSM_StateMachine *s UNUSED, unsigned char *buffer, GSM_DateTime *datetime)
Definition: nfunc.c:1007
GSM_Error N6510_ReplyAddFileHeader1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
N6510_Connection_Settings
Definition: n6510.h:8
GSM_Error DCT4_Reset(GSM_StateMachine *s, gboolean hard)
SendSMSStatusCallback SendSMSStatus
Definition: gsmstate.h:1385
GSM_Error GSM_DispatchMessage(GSM_StateMachine *s)
Definition: gsmstate.c:1131
GSM_Error N6510_AddToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
#define NONEFUNCTION
Definition: gsmcomon.h:12
GSM_Error GSM_DecodeSMSFrame(GSM_Debug_Info *di, GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout)
Definition: gsmsms.c:807
GSM_Error
Definition: gammu-error.h:23
GSM_Error N6510_ReplyGetNoteInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
void PHONE_EncodeBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, GSM_Bitmap *Bitmap)
Definition: gsmlogo.c:197
GSM_Error DCT3DCT4_ReplyEnableConnectFunc(GSM_Protocol_Message *msg, GSM_StateMachine *s)
void NOKIA_FindFeatureValue(GSM_StateMachine *s, GSM_Profile_PhoneTableValue ProfileTable[], unsigned char ID, unsigned char Value, GSM_Phone_Data *Data, gboolean CallerGroups)
GSM_BinaryPicture_Types Type
Definition: gammu-bitmap.h:44
GSM_Debug_Info di
Definition: gsmstate.h:1412
const char * model
Definition: gammu-info.h:764
GSM_CallShowNumber
Definition: gammu-call.h:192
GSM_NetworkInfo * NetworkInfo
Definition: gsmstate.h:541
unsigned char * Buffer
Definition: gammu-bitmap.h:45
GSM_OneSMSFolder Folder[GSM_MAX_SMS_FOLDERS]
GSM_Error N6510_ReplyAddFolder2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error NoneReply(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
Definition: pfunc.c:188
GSM_Error DCT3DCT4_ReplyDisableConnectFunc(GSM_Protocol_Message *msg, GSM_StateMachine *s)
char LAC[10]
Definition: gammu-info.h:131
GSM_Error N6510_ReplyGetFileFolderInfo2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
void * SendSMSStatusUserData
Definition: gsmstate.h:1390
void GSM_SetDefaultSMSData(GSM_SMSMessage *SMS)
Definition: gsmsms.c:1129
GSM_Error N71_65_ReplyCallInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
size_t UnicodeLength(const unsigned char *str)
Definition: coding.c:186
GSM_Error DCT3DCT4_EnableWAPFunctions(GSM_StateMachine *s)
GSM_Error N6510_AddFolder(GSM_StateMachine *s, GSM_File *File)
GSM_DateFormat DateFormat
GSM_MultiWAPSettings Connection
GSM_Error N71_65_ReplyAddCalendar1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
void PHONE_DecodeBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, GSM_Bitmap *Bitmap)
Definition: gsmlogo.c:141
void N6510_EncodeFMFrequency(double freq, unsigned char *buff)
GSM_Error N6510_ReplyOpenFile2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error DCT4_GetHardware(GSM_StateMachine *s, char *value)
GSM_Bitmap * Bitmap
Definition: gsmstate.h:573
unsigned char Location
Definition: gammu-bitmap.h:112
GSM_Error(* WriteMessage)(GSM_StateMachine *s, unsigned const char *buffer, int length, int type)
Definition: gsmstate.h:347
#define NOKIA_PRESSPHONEKEY
Definition: ncommon.h:96
unsigned char Number
Definition: gammu-wap.h:168
char PhonebookDataBase[(50+1) *2]
GSM_Phone_Bitmap_Types
Definition: gsmlogo.h:9
GSM_Error NOKIA_SetIncomingCall(GSM_StateMachine *s, gboolean enable)
GSM_Error N6510_ReplyDeleteAllToDo1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_SMSFolders LastSMSFolders
Definition: n6510.h:32
GSM_Error DCT4_GetIMEI(GSM_StateMachine *s)
GSM_ChatSettings * ChatSettings
Definition: gsmstate.h:650
char Name[40 *2]
GSM_Locale * Locale
Definition: gsmstate.h:621
GSM_Profile_PhoneTableValue Profile71_65[]
GSM_Error N6510_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start)
unsigned char SMSCNumber
GSM_SMSFormat Format
GSM_Error N6510_ReplyDeleteFile2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
unsigned char GSM_EncodeNokiaRTTLRingtone(GSM_Ringtone *ringtone, unsigned char *package, size_t *maxlength)
Definition: gsmring.c:992
GSM_PhoneModel * ModelInfo
Definition: gsmstate.h:449
char NetworkCode[10]
Definition: gammu-info.h:122
WAPSettings_Bearer Bearer
Definition: gammu-wap.h:87
char CID[10]
Definition: gammu-info.h:118
GSM_Error N6510_GetMMSFolders(GSM_StateMachine *s, GSM_MMSFolders *folders)
unsigned char Text[(GSM_MAX_CALENDAR_TEXT_LENGTH+1) *2]
GSM_SignalQuality * SignalQuality
Definition: gsmstate.h:533
GSM_Error N6510_AddNote(GSM_StateMachine *s, GSM_NoteEntry *Not)
GSM_Error DCT4_ReplyGetIMEI(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, gboolean start)
char HomePage[(200+1) *2]
GSM_Error NOKIA_GetPhoneString(GSM_StateMachine *s, const unsigned char *msgframe, int msglen, unsigned char msgtype, char *retvalue, GSM_Phone_RequestID request, int startresponse)
char NetworkCode[10]
Definition: gammu-bitmap.h:160
GSM_Error DCT3DCT4_SetActiveConnectSet(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
unsigned char RingtoneID
Definition: gammu-bitmap.h:138
GSM_Error DCT3DCT4_GetFirmware(GSM_StateMachine *s)
GSM_Error DCT3DCT4_ReplySetActiveConnectSet(GSM_Protocol_Message *msg, GSM_StateMachine *s)
void GSM_ClearBatteryCharge(GSM_BatteryCharge *bat)
Definition: gsmmisc.c:784
GSM_Error N6510_ReplyAddFolder1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_GetNextMMSFileInfo(GSM_StateMachine *s, unsigned char *FileID, int *MMSFolder, gboolean start)
unsigned char DefaultNumber[(GSM_MAX_NUMBER_LENGTH+1) *2]
GSM_Error(* GetNetworkInfo)(GSM_StateMachine *s, GSM_NetworkInfo *netinfo)
Definition: gsmstate.h:874
void NOKIA_DecodeNetworkCode(const unsigned char *buffer, char *output)
Definition: gsmnet.c:2473
gboolean PressKey
Definition: gsmstate.h:597
int gboolean
Definition: gammu-types.h:23
void GSM_MakeMultiPartSMS(GSM_Debug_Info *di, GSM_MultiSMSMessage *SMS, unsigned char *MessageBuffer, size_t MessageLength, GSM_UDH UDHType, GSM_Coding_Type Coding, int Class, unsigned char ReplaceMessage)
Definition: gsmmulti.c:305
char Password[(20+1) *2]
GSM_ValidityPeriodFormat Format
GSM_MemoryType
Definition: gammu-memory.h:31
GSM_DateTime * DateTime
Definition: gsmstate.h:489
char User[(50+1) *2]
Definition: gammu-wap.h:142
gboolean ManualLogin
Definition: gammu-wap.h:132
#define GSM_MAX_SMS_FOLDER_NAME_LEN
Definition: gammu-limits.h:155
GSM_Error DCT3DCT4_SetCallDivert(GSM_StateMachine *s, GSM_CallDivert *divert)
void EncodeUnicode(unsigned char *dest, const char *src, size_t len)
Definition: coding.c:301
unsigned char Name[(GSM_MAX_SMS_NAME_LENGTH+1) *2]
GSM_Error DCT3DCT4_CancelCall(GSM_StateMachine *s, int ID)
gboolean InboxFolder
GSM_Phone Phone
Definition: gsmstate.h:1431
#define FALSE
Definition: gammu-types.h:25
GSM_Error N6510_ReplyGetCalendarNotePos(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error DCT3DCT4_DeleteWAPBookmarkPart(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
GSM_Error N6510_GetFileSystemStatus(GSM_StateMachine *s, GSM_FileSystemStatus *status)
GSM_SMSValidity Validity
size_t N71_65_PackPBKBlock(GSM_StateMachine *s, int id, size_t size, int no, unsigned char *buf, unsigned char *block)
Definition: nfunc.c:36
char Proxy[(100+1) *2]
Definition: gammu-wap.h:184
unsigned int Location[GSM_PHONE_MAXSMSINFOLDER+1]
Definition: ncommon.h:87
struct GSM_Phone_Data::@2 Priv
#define SM30_UNICODETEXT
Definition: gsmmulti.h:17
GSM_Error N6510_GetFolderListing(GSM_StateMachine *s, GSM_File *File, gboolean start)
#define GSM_MAX_FM_STATION
Definition: gammu-limits.h:246
GSM_Error N6510_ReplyGetNote(GSM_Protocol_Message *msg, GSM_StateMachine *s)
void NOKIA_GetUnicodeString(GSM_StateMachine *s, int *current, unsigned char *input, unsigned char *output, gboolean FullLength)
GSM_Error N71_65_ReplyGetNextCalendar1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
int LastFreeMemorySize
Definition: n6510.h:79
GSM_SecurityCodeType
gboolean NOKIA_FindPhoneFeatureValue(GSM_StateMachine *s, GSM_Profile_PhoneTableValue ProfileTable[], GSM_Profile_Feat_ID FeatureID, GSM_Profile_Feat_Value FeatureValue, unsigned char *PhoneID, unsigned char *PhoneValue)
GSM_Error N6510_DeleteFolder(GSM_StateMachine *s, unsigned char *ID)
GSM_FMStation * FMStation
Definition: gsmstate.h:617
GSM_NokiaBinaryRingtone NokiaBinary
GSM_Error DCT3DCT4_DisableConnectionFunctions(GSM_StateMachine *s)
GSM_MultiWAPSettings * WAPSettings
Definition: gsmstate.h:569
GSM_Error N6510_GetFilesystemSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders)
void NOKIA_GetDefaultCallerGroupName(GSM_Bitmap *Bitmap)
Definition: nfunc.c:956
unsigned char N71_65_MEMORY_TYPES[]
Definition: nfunc.c:21
WAPSettings_Speed Speed
Definition: gammu-wap.h:152
GSM_Error GSM_WaitFor(GSM_StateMachine *s, unsigned const char *buffer, size_t length, int type, int timeout, GSM_Phone_RequestID request)
Definition: gsmstate.c:1029
unsigned char Frame[50000]
GSM_Error N6510_GetNextFilesystemSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboolean start)
GSM_GPRS_State GPRS
Definition: gammu-info.h:139
int NOKIA_SetUnicodeString(GSM_StateMachine *s, unsigned char *dest, unsigned char *string, gboolean FullLength)
GSM_Ringtone * Ringtone
Definition: gsmstate.h:545
GSM_SyncMLSettings * SyncMLSettings
Definition: gsmstate.h:654
unsigned char TPVP
GSM_Error N6510_ReplyGetToDoFirstLoc2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_ReplyAddCalendar3(GSM_Protocol_Message *msg, GSM_StateMachine *s)
char CalendarDataBase[(50+1) *2]
GSM_MultiWAPSettings Connection
GSM_Error N6510_ReplyGetToDoStatus1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_RingtoneInfo * Ringtone
GSM_Phone_RequestID RequestID
Definition: gsmstate.h:685
unsigned char Name[(GSM_MAX_SMS_FOLDER_NAME_LEN+1) *2]
GSM_Error N71_65_DecodePhonebook(GSM_StateMachine *s, GSM_MemoryEntry *entry, GSM_Bitmap *bitmap, GSM_SpeedDial *speed, unsigned char *MessageBuffer, int MessageLength, gboolean DayMonthReverse)
Definition: nfunc.c:364
GSM_Error DCT3DCT4_ReplyCallDivert(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_MemoryType Memory
gboolean OutboxFolder
gboolean BitmapEnabled
Definition: gammu-bitmap.h:122
GSM_Error N6510_GetFilePart(GSM_StateMachine *s, GSM_File *File, int *Handle, size_t *Size)
GSM_Profile_Feat_Value FeatureValue[15]
GSM_SMSMessage SMS[GSM_MAX_MULTI_SMS]
GSM_Error N71_65_ReplyAddCalendar2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
unsigned char Name[(GSM_MAX_GPRS_AP_NAME_LENGTH+1) *2]
#define N7110_FRAME_HEADER
Definition: ncommon.h:9
GSM_Error DCT3DCT4_ReplyDelWAPBookmark(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_AllRingtonesInfo * RingtonesInfo
Definition: gsmstate.h:609
gboolean IsISDNCall
Definition: gammu-wap.h:100
#define NOTIMPLEMENTED
Definition: gsmcomon.h:13
gboolean CarKitProfile
unsigned char URL[(GSM_MAX_GPRS_AP_URL_LENGTH+1) *2]
GSM_Protocol Protocol
Definition: gsmstate.h:1430
gboolean InboxFolder
char Name[(50+1) *2]
GSM_BatteryCharge * BatteryCharge
Definition: gsmstate.h:537
gboolean DefaultBitmap
Definition: gammu-bitmap.h:130
GSM_NetworkInfo_State State
Definition: gammu-info.h:127
GSM_NOKIASMSFolder LastSMSFolder
Definition: n6510.h:31
char Password[(50+1) *2]
Definition: gammu-wap.h:148
unsigned char Number[(GSM_MAX_NUMBER_LENGTH+1) *2]
GSM_Error DCT3DCT4_CancelAllDiverts(GSM_StateMachine *s)
unsigned char firstbyte
void NOKIA_EncodeNetworkCode(unsigned char *buffer, const char *input)
Definition: gsmnet.c:2467
GSM_Error DCT3DCT4_ReplySetWAPBookmark(GSM_Protocol_Message *msg, GSM_StateMachine *s)
unsigned char RingtoneID
Definition: n6510.h:41
GSM_Error DCT3DCT4_GetCallDivert(GSM_StateMachine *s, GSM_CallDivert *reqest, GSM_MultiCallDivert *response)
unsigned char Title[(50+1) *2]
Definition: gammu-wap.h:42
GSM_Error DCT3DCT4_GetActiveConnectSet(GSM_StateMachine *s)
GSM_Error N6510_ReplyGetToDoStatus2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N6510_ReplyAddNote(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Phone_Data Data
Definition: gsmstate.h:1369
GSM_KeyCode
Definition: gammu-keys.h:30
char Proxy2[(100+1) *2]
Definition: gammu-wap.h:192
GSM_Error GSM_UnpackSemiOctetNumber(GSM_Debug_Info *di, unsigned char *retval, const unsigned char *Number, size_t *pos, size_t bufferlength, gboolean semioctet)
Definition: coding.c:1028
GSM_Error N71_65_EnableFunctions(GSM_StateMachine *s, const char *buff, int len)
GSM_Error N6510_GetNoteStatus(GSM_StateMachine *s, GSM_ToDoStatus *status)
int GSM_UnpackEightBitsToSeven(size_t offset, size_t in_length, size_t out_length, const unsigned char *input, unsigned char *output)
Definition: coding.c:953
GSM_Error DCT3DCT4_ReplyGetModelFirmware(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_MemoryType MemoryType
Definition: gammu-memory.h:131
GSM_Error N71_65_ReplyUSSDInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
unsigned char TPStatus
void GSM_ClearBitmap(GSM_Bitmap *bmp)
Definition: gsmlogo.c:247
GSM_SMSFolders * SMSFolders
Definition: gsmstate.h:521
char DialUp[(20+1) *2]
Definition: gammu-wap.h:136
GSM_Error N6510_ReplyGetNoteFirstLoc(GSM_Protocol_Message *msg, GSM_StateMachine *s)
#define GSM_MAX_FMSTATION_LENGTH
Definition: gammu-limits.h:239
gboolean IsContinuous
Definition: gammu-wap.h:95
gboolean GSM_IsPhoneFeatureAvailable(GSM_PhoneModel *model, GSM_Feature feature)
Definition: gsmphones.c:1026
GSM_Error N6510_DeleteToDo2(GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
unsigned char Name[30 *2]
size_t N71_65_EncodePhonebookFrame(GSM_StateMachine *s, unsigned char *req, GSM_MemoryEntry *entry, size_t *block2, gboolean DCT4, gboolean VoiceTag)
Definition: nfunc.c:54
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
gboolean DefaultName
Definition: gammu-bitmap.h:126
GSM_Error NOKIA_ReplyGetPhoneString(GSM_Protocol_Message *msg, GSM_StateMachine *s)
void PHONE_GetBitmapWidthHeight(GSM_Phone_Bitmap_Types Type, size_t *width, size_t *height)
Definition: gsmlogo.c:23
GSM_Error N6510_ReplyAddToDo2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error DCT4_ReplyGetPhoneMode(GSM_Protocol_Message *msg, GSM_StateMachine *s)
size_t BitmapHeight
Definition: gammu-bitmap.h:152
GSM_Error N6510_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status)
void N6510_DecodeFMFrequency(double *freq, unsigned char *buff)
void * IncomingSMSUserData
Definition: gsmstate.h:1387
#define _(x)
Definition: locales.h:21
gboolean DefaultName
GSM_SMSC * SMSC
Definition: gsmstate.h:505
size_t BitmapWidth
Definition: gammu-bitmap.h:156
GSM_Error N6510_ReplySetAttrib2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
N6510_PHONE_LIGHTS
Definition: n6510.h:16
unsigned char Text[2 *(GSM_BITMAP_TEXT_LENGTH+1)]
Definition: gammu-bitmap.h:118
GSM_Error N6510_ReplyAddToDo1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N71_65_ReplyGetMemoryError(unsigned char error, GSM_StateMachine *s)
GSM_Error N6510_DeleteFile(GSM_StateMachine *s, unsigned char *ID)
void PHONE_ClearBitmap(GSM_Phone_Bitmap_Types Type, char *buffer, size_t width, size_t height)
Definition: gsmlogo.c:192
char DateSeparator
GSM_Protocol_Functions * Functions
Definition: gsmstate.h:424
GSM_GPRSAccessPoint * GPRSPoint
Definition: gsmstate.h:481
char User[(30+1) *2]
char HomePage[(100+1) *2]
Definition: gammu-wap.h:83
GSM_Error NOKIA_GetManufacturer(GSM_StateMachine *s)
unsigned char Address[(255+1) *2]
Definition: gammu-wap.h:38
#define TRUE
Definition: gammu-types.h:28
GSM_Error N6510_ReplyGetCalendar3(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_MemoryStatus * MemoryStatus
Definition: gsmstate.h:501
GSM_SecurityCodeType Type
GSM_SMSMessage * SaveSMSMessage
Definition: gsmstate.h:513
void NOKIA_DecodeDateTime(GSM_StateMachine *s, unsigned char *buffer, GSM_DateTime *datetime, gboolean seconds, gboolean DayMonthReverse)
Definition: nfunc.c:976
GSM_Error NOKIA_SetIncomingSMS(GSM_StateMachine *s, gboolean enable)
GSM_Error N6510_GetNextRootFolder(GSM_StateMachine *s, GSM_File *File)
GSM_Error N6510_DeleteNote(GSM_StateMachine *s, GSM_NoteEntry *Not)
GSM_Profile * Profile
Definition: gsmstate.h:605
char StationName[(GSM_MAX_FMSTATION_LENGTH+1) *2]
GSM_Error DCT3DCT4_ReplyGetWAPBookmark(GSM_Protocol_Message *msg, GSM_StateMachine *s, gboolean FullLength)
char User[(50+1) *2]
gboolean EnableIncomingSMS
Definition: gsmstate.h:663
GSM_Error PHONE_EncodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *SMS, unsigned char *buffer, GSM_SMSMessageLayout Layout, int *length, gboolean clear)
Definition: pfunc.c:58
unsigned char * Buffer
Definition: protocol.h:22
unsigned char DateTime
GSM_Error N6510_GetCalendarSettings(GSM_StateMachine *s, GSM_CalendarSettings *settings)
#define UNUSED
Definition: gammu-misc.h:105
unsigned char Number
GSM_Error N6510_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, gboolean refresh)
unsigned char TPMR
GSM_Error DCT3DCT4_AnswerCall(GSM_StateMachine *s, int ID)
GSM_ValidityPeriod Relative
GSM_SpeedDial * SpeedDial
Definition: gsmstate.h:485
Debug_Level dl
Definition: debug.h:35
gboolean Repeating
GSM_MemoryType Memory
IncomingSMSCallback IncomingSMS
Definition: gsmstate.h:1382
GSM_Error N71_65_ReplySendDTMF(GSM_Protocol_Message *msg, GSM_StateMachine *s)
unsigned char * PhoneString
Definition: gsmstate.h:629
GSM_Error N6510_ReplyGetToDo1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error DCT4_GetProductCode(GSM_StateMachine *s, char *value)
GSM_Error DCT3DCT4_SendDTMF(GSM_StateMachine *s, char *sequence)
int smprintf(GSM_StateMachine *s, const char *format,...)
Definition: debug.c:261
#define GSM_MAX_SMSC_NAME_LENGTH
Definition: gammu-limits.h:218
gboolean Active
#define SM30_OTA
Definition: gsmmulti.h:18
GSM_Error N71_65_ReplyWritePhonebook(GSM_Protocol_Message *msg, GSM_StateMachine *s)
unsigned char TPPID
unsigned char Name[(GSM_MAX_SMSC_NAME_LENGTH+1) *2]