Gammu internals  1.38.0
nfunc.c
Go to the documentation of this file.
1 /* (c) 2002-2005 by Marcin Wiacek */
2 /* based on some work from Ralf Thelen, Gabriele Zappi and MyGnokii */
3 
4 #include <string.h> /* memcpy only */
5 #include <stdio.h>
6 #include <ctype.h>
7 #include <time.h>
8 
9 #include <gammu-nokia.h>
10 
11 #include "../../gsmstate.h"
12 #include "../../gsmphones.h"
13 #include "../../misc/coding/coding.h"
14 #include "../../misc/locales.h"
15 #include "../../service/gsmnet.h"
16 #include "../../service/gsmlogo.h"
17 #include "../../service/gsmcal.h"
18 #include "../pfunc.h"
19 #include "nfunc.h"
20 
21 unsigned char N71_65_MEMORY_TYPES[] = {
22  MEM_DC, 0x01,
23  MEM_MC, 0x02,
24  MEM_RC, 0x03,
25  MEM_ME, 0x05,
26  MEM_SM, 0x06,
27  MEM_VM, 0x09,
28  MEM7110_SP, 0x0e,
29  MEM7110_CG, 0x10,
30  MEM_ON, 0x17,
31  MEM6510_CG2, 0x23,
32  MEM_SL, 0x27,
33  0x00, 0x00
34 };
35 
36 size_t N71_65_PackPBKBlock(GSM_StateMachine *s, int id, size_t size, int no, unsigned char *buf, unsigned char *block)
37 {
38  smprintf(s, "Packing phonebook block with ID = %i, block number = %i, block length = %ld\n",
39  id,
40  no+1,
41  (long)size+6);
42 
43  block[0] = id;
44  block[1] = 0;
45  block[2] = (size + 6) / 256;
46  block[3] = (size + 6) % 256;
47  block[4] = no + 1;
48  memcpy(block+5, buf, size);
49  block[5+size] = 0;
50 
51  return (size + 6);
52 }
53 
54 size_t N71_65_EncodePhonebookFrame(GSM_StateMachine *s, unsigned char *req, GSM_MemoryEntry *entry, size_t *block2, gboolean DCT4, gboolean VoiceTag)
55 {
56  int count=0, len, i, block=0, j;
57  unsigned char string[500];
58  unsigned char type;
59  gboolean found;
60 
61  for (i = 0; i < entry->EntriesNum; i++) {
62  entry->Entries[i].AddError = ERR_NOTSUPPORTED;
63  }
64  memset(string,0,sizeof(string));
65  found = FALSE;
67  for (i = 0; i < entry->EntriesNum; i++) {
68  if (entry->Entries[i].EntryType == PBK_Text_LastName ||
69  entry->Entries[i].EntryType == PBK_Text_FirstName) {
70  if (entry->Entries[i].EntryType==PBK_Text_LastName) {
71  type = S4030_PBK_LASTNAME;
72  } else {
73  type = S4030_PBK_FIRSTNAME;
74  }
75  found = TRUE;
76  entry->Entries[i].AddError = ERR_NONE;
77  len = MIN(UnicodeLength(entry->Entries[i].Text), 126);
78  string[0] = len*2+2;
79  CopyUnicodeString(string+1,entry->Entries[i].Text);
80  string[len*2+1] = 0;
81  count += N71_65_PackPBKBlock(s, type, len * 2 + 2, block++, string, req + count);
82  }
83  }
84  for (i = 0; i < entry->EntriesNum; i++) {
85  if(entry->Entries[i].EntryType==PBK_Text_Name) {
86  if (!found) {
87  entry->Entries[i].AddError = ERR_NONE;
88  type = N7110_PBK_NAME;
89  len = MIN(UnicodeLength(entry->Entries[i].Text), 126);
90  string[0] = len*2+2;
91  CopyUnicodeString(string+1,entry->Entries[i].Text);
92  string[len*2+1] = 0;
93  count += N71_65_PackPBKBlock(s, type, len * 2 + 2, block++, string, req + count);
94  found = TRUE;
95  } else {
96  entry->Entries[i].AddError = ERR_INVALIDDATA;
97  }
98  }
99  }
100  } else {
101  for (i = 0; i < entry->EntriesNum; i++) {
102  if (entry->Entries[i].EntryType == PBK_Text_LastName ||
103  entry->Entries[i].EntryType == PBK_Text_FirstName) {
104  if (UnicodeLength(string+1) > 0) {
105  string[UnicodeLength(string+1)*2+1] = ' ';
106  }
107  CopyUnicodeString(string+UnicodeLength(string+1)*2+1,entry->Entries[i].Text);
108  entry->Entries[i].AddError = ERR_DATACONVERTED;
109  found=TRUE;
110  }
111  }
112  if (UnicodeLength(string+1) != 0) {
113  type = N7110_PBK_NAME;
114  len = MIN(UnicodeLength(string+1), 126);
115  string[0] = len*2+2;
116  string[len*2+1] = 0;
117  count += N71_65_PackPBKBlock(s, type, len * 2 + 2, block++, string, req + count);
118  }
119  for (i = 0; i < entry->EntriesNum; i++) {
120  if (entry->Entries[i].EntryType==PBK_Text_Name) {
121  if (!found) {
122  entry->Entries[i].AddError = ERR_NONE;
123  type = N7110_PBK_NAME;
124  len = MIN(UnicodeLength(entry->Entries[i].Text), 126);
125  string[0] = len*2+2;
126  CopyUnicodeString(string+1,entry->Entries[i].Text);
127  string[len*2+1] = 0;
128  count += N71_65_PackPBKBlock(s, type, len * 2 + 2, block++, string, req + count);
129  found = TRUE;
130  } else {
131  entry->Entries[i].AddError = ERR_INVALIDDATA;
132  }
133  }
134  }
135  }
136  for (i = 0; i < entry->EntriesNum; i++) {
137  type = 0;
139  else if (entry->Entries[i].EntryType == PBK_Number_General && entry->Entries[i].Location == PBK_Location_Home) type = N7110_PBK_NUMBER_HOME;
140  else if (entry->Entries[i].EntryType == PBK_Number_General) type = N7110_PBK_NUMBER_GENERAL;
142  if (entry->Entries[i].EntryType == PBK_Number_Fax) type = N7110_PBK_NUMBER_FAX;
143  if (type != 0) {
144  entry->Entries[i].AddError = ERR_NONE;
145 
146  string[0] = type;
147  len = MIN(UnicodeLength(entry->Entries[i].Text), 126);
148 
149  string[1] = 0;
150  string[2] = 0;
151 
152  /* DCT 3 */
153  if (!DCT4) string[2] = entry->Entries[i].VoiceTag;
154 
155  string[3] = 0;
156  string[4] = len*2+2;
157  CopyUnicodeString(string+5,entry->Entries[i].Text);
158  string[len * 2 + 5] = 0;
159  count += N71_65_PackPBKBlock(s, N7110_PBK_NUMBER, len*2+6, block++, string, req+count);
160 
161  /* DCT 4 */
162  if (DCT4 && VoiceTag) {
163  block++;
164  req[count++] = N6510_PBK_VOICETAG_ID;
165  req[count++] = 0;
166  req[count++] = 0;
167  req[count++] = 8;
168  req[count++] = 0x00;
169  req[count++] = i+1;
170  req[count++] = 0x00;
171  req[count++] = entry->Entries[i].VoiceTag;
172  }
173  if (DCT4) {
174  j = 0;
175  while (entry->Entries[i].SMSList[j] != 0) {
176  string[0] = i+1;
177  string[1] = 0x00;
178  string[2] = 0x02;
179  string[3] = 0x00;
180  string[4] = entry->Entries[i].SMSList[j];
181  string[5] = 0x00;
182  count += N71_65_PackPBKBlock(s, N6510_PBK_SMSLIST_ID, 6, block++, string, req+count);
183 
184  j++;
185  }
186  }
187  continue;
188  }
189  smprintf(s, "entry num %i %i\n",i,entry->EntriesNum);
190  if (entry->Entries[i].EntryType == PBK_Text_Note) type = N7110_PBK_NOTE;
191  if (entry->Entries[i].EntryType == PBK_Text_Postal) {
193  continue;
194  }
195  type = N7110_PBK_POSTAL;
196  }
197  if (entry->Entries[i].EntryType == PBK_Text_Email) type = N7110_PBK_EMAIL;
198  if (entry->Entries[i].EntryType == PBK_Text_Email2) type = N7110_PBK_EMAIL;
199  if (entry->Entries[i].EntryType == PBK_Text_URL) {
200  entry->Entries[i].AddError = ERR_DATACONVERTED;
201  type = N7110_PBK_NOTE;
202  if (DCT4) type = N6510_PBK_URL;
203  }
204  if (type != 0) {
205  if (entry->Entries[i].AddError==ERR_NOTSUPPORTED) entry->Entries[i].AddError = ERR_NONE;
206  len = MIN(UnicodeLength(entry->Entries[i].Text), 126);
207  string[0] = len*2+2;
208  CopyUnicodeString(string+1,entry->Entries[i].Text);
209  string[len*2+1] = 0;
210  count += N71_65_PackPBKBlock(s, type, len * 2 + 2, block++, string, req + count);
211  continue;
212  }
213  if (entry->Entries[i].EntryType == PBK_Caller_Group) {
215  entry->Entries[i].AddError = ERR_NONE;
217  string[0] = 0;
218  string[1] = 0;
219  count += N71_65_PackPBKBlock(s, N6510_PBK_GROUP2_ID, 2, block++, string, req + count);
220  req[count-1] = entry->Entries[i].Number;
221  } else {
222  string[0] = entry->Entries[i].Number;
223  string[1] = 0;
224  count += N71_65_PackPBKBlock(s, N7110_PBK_GROUP, 2, block++, string, req + count);
225  }
226  }
227  continue;
228  }
229  if (entry->Entries[i].EntryType == PBK_RingtoneID) {
231  entry->Entries[i].AddError = ERR_NONE;
232  string[0] = 0x00;
233  string[1] = 0x00;
234  string[2] = entry->Entries[i].Number;
235  count += N71_65_PackPBKBlock(s, N7110_PBK_RINGTONE_ID, 3, block++, string, req + count);
236  count --;
237  req[count-5] = 8;
238  }
239  continue;
240  }
241  if (entry->Entries[i].EntryType == PBK_PictureID) {
243  entry->Entries[i].AddError = ERR_NONE;
244  string[0] = 0x00;
245  string[1] = 0x00;
246  string[2] = 0x00;
247  string[3] = 0x00;
248  string[4] = 0x01;
249  string[5] = entry->Entries[i].Number / 256;
250  string[6] = entry->Entries[i].Number % 256;
251  string[7] = 0x00;
252  string[8] = 0x00;
253  string[9] = 0x00;
254  count += N71_65_PackPBKBlock(s, N6510_PBK_PICTURE_ID, 10, block++, string, req + count);
255  req[count-1] = 0x01;
256  }
257  continue;
258  }
259  /* Maybe we should use separate feature for these new entries... */
261  type = 0;
263  if (entry->Entries[i].EntryType == PBK_Text_JobTitle) type = S4030_PBK_JOBTITLE;
264  if (entry->Entries[i].EntryType == PBK_Text_Company) type = S4030_PBK_COMPANY;
265  if (entry->Entries[i].EntryType == PBK_Text_NickName) type = S4030_PBK_NICKNAME;
266  if (type != 0) {
267  if (entry->Entries[i].AddError==ERR_NOTSUPPORTED) entry->Entries[i].AddError = ERR_NONE;
268  len = MIN(UnicodeLength(entry->Entries[i].Text), 126);
269  string[0] = len*2+2;
270  CopyUnicodeString(string+1,entry->Entries[i].Text);
271  string[len*2+1] = 0;
272  count += N71_65_PackPBKBlock(s, type, len * 2 + 2, block++, string, req + count);
273  continue;
274  }
275  if (entry->Entries[i].EntryType == PBK_Date) {
276  entry->Entries[i].AddError = ERR_NONE;
277 
278  NOKIA_EncodeDateTime(s, string + 1, &(entry->Entries[i].Date));
279  count += N71_65_PackPBKBlock(s, S4030_PBK_BIRTHDAY, 6, block++, string, req + count);
280  continue;
281  }
282  }
283  if (entry->Entries[i].EntryType == PBK_Text_UserID) {
285  entry->Entries[i].AddError = ERR_NONE;
286  string[0] = UnicodeLength(entry->Entries[i].Text)*2;
287  CopyUnicodeString(string+1,entry->Entries[i].Text);
288  count += N71_65_PackPBKBlock(s, N6510_PBK_USER_ID, string[0]+2, block++, string, req+count);
289  req[count-1]--;
290  }
291  continue;
292  }
293  if (entry->Entries[i].EntryType == PBK_PushToTalkID) {
294  entry->Entries[i].AddError = ERR_NONE;
295  string[0] = UnicodeLength(entry->Entries[i].Text)*2;
296  CopyUnicodeString(string+1,entry->Entries[i].Text);
297  count += N71_65_PackPBKBlock(s, N6510_PBK_PUSHTOTALK_ID, string[0]+2, block++, string, req+count);
298  req[count-1]--;
299  continue;
300  }
301  if (entry->Entries[i].EntryType == PBK_Number_Messaging) {
303  entry->Entries[i].AddError = ERR_INVALIDDATA;
304  /* The favorite messaging number is stored as a phone number,
305  * the phone wants an id to a previously supplied entry, so we search for that.
306  * In case there was an error in the previous entries, we stop.
307  * Otherwise we would point past the supplied entries. */
308  for (j = 0; j < i && entry->Entries[j].AddError == ERR_NONE; j++) {
309  if (mywstrncmp(entry->Entries[i].Text, entry->Entries[j].Text, -1)) {
310  string[0] = j + 1;
311  string[1] = 0x00;
312  string[2] = 0x00;
313  count += N71_65_PackPBKBlock(s, N2630_PBK_FAVMESSAGING, 3, block++, string, req + count);
314  count --;
315  req[count-5] = 8;
316  entry->Entries[i].AddError = ERR_NONE;
317  break;
318  }
319 
320  }
321  }
322  continue;
323  }
324  }
325 
326  *block2=block;
327 
328  return count;
329 }
330 
337  GSM_MemoryEntry *entry,
338  const unsigned char *src,
339  unsigned char length)
340 {
341  if ((length & 1) != 0) {
342  smprintf(s, "String length not even\n");
343  return FALSE;
344  }
345  if (length/2 > GSM_PHONEBOOK_TEXT_LENGTH) {
346  smprintf(s, "Too long text\n");
347  return FALSE;
348  }
349  memcpy(entry->Entries[entry->EntriesNum].Text, src, length);
350  /* Zero terminate the string */
351  entry->Entries[entry->EntriesNum].Text[length] = 0;
352  entry->Entries[entry->EntriesNum].Text[length + 1] = 0;
353 
354  smprintf(s, " \"%s\"\n",DecodeUnicodeString(entry->Entries[entry->EntriesNum].Text));
355 
356  return TRUE;
357 }
358 
365  GSM_MemoryEntry *entry,
366  GSM_Bitmap *bitmap,
367  GSM_SpeedDial *speed,
368  unsigned char *MessageBuffer,
369  int MessageLength,
370  gboolean DayMonthReverse)
371 {
372  unsigned char *Block;
373  int length = 0, i, bs = 0;
374  GSM_EntryType Type;
376  gboolean found=FALSE;
377  gboolean foundbb5add=FALSE;
378  gboolean missed_call = FALSE;
379  int favorite_messaging_numbers[10];
380  size_t used_favorite_messaging_numbers = 0;
381 
382  entry->EntriesNum = 0;
383 
384  if ((int)entry->MemoryType==MEM7110_CG) {
385  bitmap->Text[0] = 0x00;
386  bitmap->Text[1] = 0x00;
387  bitmap->DefaultBitmap = TRUE;
388  bitmap->DefaultRingtone = TRUE;
389  bitmap->FileSystemPicture = FALSE;
390  }
392  bitmap->DefaultName = FALSE;
393  bitmap->DefaultBitmap = TRUE;
394  bitmap->DefaultRingtone = TRUE;
395  bitmap->FileSystemPicture = FALSE;
396  }
397 
398  Block = &MessageBuffer[0];
399  while (TRUE) {
400  entry->Entries[entry->EntriesNum].AddError = ERR_NONE;
401  entry->Entries[entry->EntriesNum].SMSList[0] = 0;
402  entry->Entries[entry->EntriesNum].VoiceTag = 0;
403  if (bs != 0) {
404  length = length + bs;
405  /* bb5 */
406  if (length >= MessageLength-1) break;
407  Block = &Block[bs];
408  }
409  bs = 256*Block[2]+Block[3];
410  if (bs == 0) break;
411 #ifdef DEBUG
412  smprintf(s, "Phonebook entry block 0x%02x - length %i\n",
413  Block[0], bs-6);
414  if (GSM_GetDI(s)->dl == DL_TEXTALL || GSM_GetDI(s)->dl == DL_TEXTALLDATE)
415  DumpMessage(&s->di, Block+0, bs-1);
416 #endif
417  if (entry->EntriesNum==GSM_PHONEBOOK_ENTRIES) {
418  smprintf(s, "Too many entries\n");
419  return ERR_UNKNOWNRESPONSE;
420  }
421 
422  Type = 0;
423  if (Block[0] == S4030_PBK_FIRSTNAME) {
424  Type = PBK_Text_FirstName; smprintf(s,"First name ");
425  }
426  if (Block[0] == S4030_PBK_LASTNAME) {
427  Type = PBK_Text_LastName; smprintf(s,"Last name ");
428  }
429  if (Type != 0) {
430  found=TRUE;
431  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
432  return ERR_UNKNOWNRESPONSE;
433  entry->Entries[entry->EntriesNum].EntryType=Type;
435  entry->EntriesNum ++;
436  }
437  }
438 
439  Block = &MessageBuffer[0];
440  bs=0;
441  length=0;
442  while (TRUE) {
443  entry->Entries[entry->EntriesNum].AddError = ERR_NONE;
444  entry->Entries[entry->EntriesNum].SMSList[0] = 0;
445  entry->Entries[entry->EntriesNum].VoiceTag = 0;
446  if (bs != 0) {
447  length = length + bs;
448  if (length >= MessageLength-1) break;
449  Block = &Block[bs];
450  }
451  bs = 256*Block[2]+Block[3];
452  smprintf(s, "Phonebook entry block 0x%02x - length %i\n",
453  Block[0], bs-6);
454  if (s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXTALLDATE) {
455  DumpMessage(&s->di, Block+0, bs-1);
456  }
457  if (entry->EntriesNum >= GSM_PHONEBOOK_ENTRIES) {
458  smprintf(s, "Too many entries\n");
459  return ERR_MOREMEMORY;
460  }
461 
462  Type = 0;
463  if (Block[0] == N7110_PBK_NAME) {
464  if (found) continue;
465  Type = PBK_Text_Name; smprintf(s,"Name ");
466  }
467  if (Block[0] == S4030_PBK_FIRSTNAME) continue;
468  if (Block[0] == S4030_PBK_LASTNAME) continue;
469  if (Block[0] == N7110_PBK_EMAIL) {
470  Type = PBK_Text_Email; smprintf(s,"Email ");
471  }
472  if (Block[0] == N7110_PBK_POSTAL) {
473  Type = PBK_Text_Postal; smprintf(s,"Postal ");
474  }
475  if (Block[0] == N7110_PBK_NOTE) {
476  Type = PBK_Text_Note; smprintf(s,"Text note ");
477  }
478  if (Block[0] == N6510_PBK_URL) {
479  Type = PBK_Text_URL; smprintf(s,"URL ");
480  }
481  if (Block[0] == N6510_PBK_USER_ID) {
482  Type = PBK_Text_UserID; smprintf(s,"User ID:");
483  }
484  if (Type != 0) {
485  if (Block[5]/2>GSM_PHONEBOOK_TEXT_LENGTH) {
486  smprintf(s, "Too long text\n");
487  return ERR_UNKNOWNRESPONSE;
488  }
489  /* No text? */
490  if (Block[5] < 2) {
491  entry->Entries[entry->EntriesNum].Text[0] = 0;
492  entry->Entries[entry->EntriesNum].Text[1] = 0;
493  } else {
494  memcpy(entry->Entries[entry->EntriesNum].Text,Block+6,Block[5]);
495  /* Zero terminate the string */
496  entry->Entries[entry->EntriesNum].Text[Block[5]] = 0;
497  entry->Entries[entry->EntriesNum].Text[Block[5] + 1] = 0;
498  }
499  entry->Entries[entry->EntriesNum].EntryType=Type;
501  smprintf(s, " \"%s\"\n",DecodeUnicodeString(entry->Entries[entry->EntriesNum].Text));
502  if (Block[0] == N7110_PBK_NAME) {
503  if ((int)entry->MemoryType == MEM7110_CG || (int)entry->MemoryType == MEM6510_CG2) {
504  /* No text? */
505  if (Block[5] < 2) {
506  bitmap->Text[0] = 0;
507  bitmap->Text[1] = 0;
508  } else {
509  memcpy(bitmap->Text,Block+6,Block[5]);
510  }
511  }
512  }
513  entry->EntriesNum ++;
514  continue;
515  }
516  if (Block[0] == N7110_PBK_DATETIME) {
517  entry->Entries[entry->EntriesNum].EntryType=PBK_Date;
519  NOKIA_DecodeDateTime(s, Block+6, &entry->Entries[entry->EntriesNum].Date, TRUE, DayMonthReverse);
520  if (CheckDate(&entry->Entries[entry->EntriesNum].Date) &&
521  CheckDate(&entry->Entries[entry->EntriesNum].Date)) {
522  entry->EntriesNum ++;
523  } else {
524  smprintf(s, "Datetime seems to be invalid, ignoring!\n");
525  }
526  continue;
527  }
528  if (Block[0] == N6510_PBK_PICTURE_ID) {
529  if ((int)entry->MemoryType==MEM6510_CG2) {
530  bitmap->FileSystemPicture = TRUE;
531  smprintf(s, "Picture ID \"%i\"\n",Block[10]*256+Block[11]);
532  bitmap->PictureID = Block[10]*256+Block[11];
533  } else {
534  entry->Entries[entry->EntriesNum].EntryType=PBK_PictureID;
536  smprintf(s, "Picture ID \"%i\"\n",Block[10]*256+Block[11]);
537  entry->Entries[entry->EntriesNum].Number=Block[10]*256+Block[11];
538  entry->EntriesNum ++;
539  }
540  continue;
541  }
542  if (Block[0] == N7110_PBK_NUMBER) {
543  if (Block[5] == 0x00) {
544  Type = PBK_Number_General; smprintf(s,"General number ");
545  }
546  /* Not assigned dialed number */
547  if (Block[5] == 0x01) {
548  Type = PBK_Number_General; smprintf(s,"General number ");
549  }
550  if (Block[5] == 0x0B) {
551  Type = PBK_Number_General; smprintf(s,"General number ");
552  }
553  /* In many firmwares 0x55 visible after using
554  * Save from Call Register menu and saving number
555  * to existing phonebook entry */
556  if (Block[5] == 0x55) {
557  Type = PBK_Number_General; smprintf(s,"General number ");
558  }
559  /* Yet another unknown General number */
560  if (Block[5] == 0x08) {
561  Type = PBK_Number_General; smprintf(s,"General number ");
562  }
563  if (Block[5] == N7110_PBK_NUMBER_GENERAL) {
564  Type = PBK_Number_General; smprintf(s,"General number ");
565  }
566  if (Block[5] == N7110_PBK_NUMBER_WORK) {
567  Type = PBK_Number_General; Location = PBK_Location_Work; smprintf(s,"Work number ");
568  }
569  if (Block[5] == N7110_PBK_NUMBER_FAX) {
570  Type = PBK_Number_Fax; smprintf(s,"Fax number ");
571  }
572  if (Block[5] == N7110_PBK_NUMBER_MOBILE) {
573  Type = PBK_Number_Mobile; smprintf(s,"Mobile number ");
574  }
575  if (Block[5] == N7110_PBK_NUMBER_HOME) {
576  Type = PBK_Number_General; Location = PBK_Location_Home; smprintf(s,"Home number ");
577  }
578  if (Type == 0x00) {
579  smprintf(s, "Unknown number type %02x\n",Block[5]);
580  return ERR_UNKNOWNRESPONSE;
581  }
582  entry->Entries[entry->EntriesNum].EntryType=Type;
583  entry->Entries[entry->EntriesNum].Location = Location;
584  if (! N71_65_PB_CopyString(s, entry, Block+10, Block[9]))
585  return ERR_UNKNOWNRESPONSE;
586  /* DCT3 phones like 6210 */
587  entry->Entries[entry->EntriesNum].VoiceTag = Block[7];
588 #ifdef DEBUG
589  if (entry->Entries[entry->EntriesNum].VoiceTag != 0) smprintf(s, "Voice tag %i assigned\n",Block[7]);
590 #endif
591  entry->Entries[entry->EntriesNum].SMSList[0] = 0;
592  entry->EntriesNum ++;
593  continue;
594  }
595  /* to checking */
596  if (Block[0] == S4030_PBK_CALLLENGTH) {
597  entry->Entries[entry->EntriesNum].CallLength = Block[9]*256*256+Block[10]*256+Block[11];
600  entry->EntriesNum ++;
601  continue;
602  }
603  if (Block[0] == S4030_PBK_POSTAL) {
604  if (Block[5] == S4030_PBK_POSTAL_EXTADDRESS) {
605  Type = PBK_Text_Custom1; smprintf(s,"Address extension ? ");
606  }
607  if (Block[5] == S4030_PBK_POSTAL_STREET) {
608  Type = PBK_Text_StreetAddress; smprintf(s,"Street ");
609  }
610  if (Block[5] == S4030_PBK_POSTAL_CITY) {
611  Type = PBK_Text_City; smprintf(s,"City ");
612  }
613  if (Block[5] == S4030_PBK_POSTAL_STATE) {
614  Type = PBK_Text_State; smprintf(s,"State ");
615  }
616  if (Block[5] == S4030_PBK_POSTAL_POSTAL) {
617  Type = PBK_Text_Postal; smprintf(s,"Postal ");
618  }
619  if (Block[5] == S4030_PBK_POSTAL_COUNTRY) {
620  Type = PBK_Text_Country; smprintf(s,"Country ");
621  }
622  if ((Type == 0x00) && (Block[7]>0)) {
623  smprintf(s, "Found new bb5 style address\n");
624  foundbb5add=TRUE;
625  continue;
626  }
627  if (Type == 0x00) {
628  smprintf(s, "Unknown address type %02x\n",Block[5]);
629  return ERR_UNKNOWNRESPONSE;
630  }
631  entry->Entries[entry->EntriesNum].EntryType=Type;
633  if (! N71_65_PB_CopyString(s, entry, Block+10, Block[9]))
634  return ERR_UNKNOWNRESPONSE;
635  entry->EntriesNum ++;
636  continue;
637  }
638 
639 
640  if ((Block[0] == S4030_PBK_POSTAL_EXTADDRESS) && (foundbb5add==TRUE)) {
641  Type = PBK_Text_Custom1; smprintf(s,"Address extension ? ");
642  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
643  return ERR_UNKNOWNRESPONSE;
644  entry->Entries[entry->EntriesNum].EntryType=Type;
646  entry->EntriesNum ++;
647  continue;
648  }
649  if ((Block[0] == S4030_PBK_POSTAL_STREET) && (foundbb5add==TRUE)) {
650  Type = PBK_Text_StreetAddress; smprintf(s,"Street ");
651  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
652  return ERR_UNKNOWNRESPONSE;
653  entry->Entries[entry->EntriesNum].EntryType=Type;
655  entry->EntriesNum ++;
656  continue;
657  }
658  if ((Block[0] == S4030_PBK_POSTAL_CITY) && (foundbb5add==TRUE)) {
659  Type = PBK_Text_City; smprintf(s,"City ");
660  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
661  return ERR_UNKNOWNRESPONSE;
662  entry->Entries[entry->EntriesNum].EntryType=Type;
664  entry->EntriesNum ++;
665  continue;
666  }
667  if ((Block[0] == S4030_PBK_POSTAL_STATE) && (foundbb5add==TRUE)) {
668  Type = PBK_Text_State; smprintf(s,"State ");
669  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
670  return ERR_UNKNOWNRESPONSE;
671  entry->Entries[entry->EntriesNum].EntryType=Type;
673  entry->EntriesNum ++;
674  continue;
675  }
676  if ((Block[0] == S4030_PBK_POSTAL_POSTAL) && (foundbb5add==TRUE)) {
677  Type = PBK_Text_Postal; smprintf(s,"Postal ");
678  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
679  return ERR_UNKNOWNRESPONSE;
680  entry->Entries[entry->EntriesNum].EntryType=Type;
682  entry->EntriesNum ++;
683  continue;
684  }
685  if ((Block[0] == S4030_PBK_POSTAL_COUNTRY) && (foundbb5add==TRUE)) {
686  Type = PBK_Text_Country; smprintf(s,"Country ");
687  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
688  return ERR_UNKNOWNRESPONSE;
689  entry->Entries[entry->EntriesNum].EntryType=Type;
691  entry->EntriesNum ++;
692  continue;
693  }
694  if (Block[0] == S4030_PBK_FORMALNAME) {
695  Type = PBK_Text_FormalName; smprintf(s,"FormalName ");
696  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
697  return ERR_UNKNOWNRESPONSE;
698  entry->Entries[entry->EntriesNum].EntryType=Type;
700  entry->EntriesNum ++;
701  continue;
702  }
703  if (Block[0] == S4030_PBK_JOBTITLE) {
704  Type = PBK_Text_JobTitle; smprintf(s,"JobTitle ");
705  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
706  return ERR_UNKNOWNRESPONSE;
707  entry->Entries[entry->EntriesNum].EntryType=Type;
709  entry->EntriesNum ++;
710  continue;
711  }
712  if (Block[0] == S4030_PBK_COMPANY) {
713  Type = PBK_Text_Company; smprintf(s,"Company ");
714  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
715  return ERR_UNKNOWNRESPONSE;
716  entry->Entries[entry->EntriesNum].EntryType=Type;
718  entry->EntriesNum ++;
719  continue;
720  }
721  if (Block[0] == S4030_PBK_NICKNAME) {
722  Type = PBK_Text_NickName; smprintf(s,"NickName ");
723  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
724  return ERR_UNKNOWNRESPONSE;
725  entry->Entries[entry->EntriesNum].EntryType=Type;
727  entry->EntriesNum ++;
728  continue;
729  }
730  if (Block[0] == S4030_PBK_BIRTHDAY) {
731  entry->Entries[entry->EntriesNum].EntryType=PBK_Date;
733  NOKIA_DecodeDateTime(s, Block+6, &entry->Entries[entry->EntriesNum].Date, FALSE, DayMonthReverse);
734  entry->EntriesNum ++;
735  continue;
736  }
737 
738 
739  if (Block[0] == N7110_PBK_RINGTONE_ID) {
740  if ((int)entry->MemoryType==MEM7110_CG) {
741  bitmap->RingtoneID=Block[5];
742  if (Block[5] == 0x00) bitmap->RingtoneID=Block[7];
743  smprintf(s, "Ringtone ID : %i\n",bitmap->RingtoneID);
744  bitmap->DefaultRingtone = FALSE;
745  bitmap->FileSystemRingtone = FALSE;
746  } else {
749  smprintf(s, "Ringtone ID \"%i\"\n",Block[7]);
750  entry->Entries[entry->EntriesNum].Number=Block[7];
751  entry->EntriesNum ++;
752  }
753  continue;
754  }
755  if (Block[0] == N7110_PBK_LOGOON) {
756  if ((int)entry->MemoryType==MEM7110_CG) {
757  bitmap->BitmapEnabled=(Block[5]==0x00 ? FALSE : TRUE);
758  smprintf(s, "Logo : %s\n", bitmap->BitmapEnabled==TRUE ? "enabled":"disabled");
759  } else {
760  return ERR_UNKNOWNRESPONSE;
761  }
762  continue;
763  }
764  if (Block[0] == N7110_PBK_GROUPLOGO) {
765  if ((int)entry->MemoryType==MEM7110_CG) {
766  smprintf(s, "Caller logo\n");
767  PHONE_DecodeBitmap(GSM_NokiaCallerLogo, Block+10, bitmap);
768  bitmap->DefaultBitmap = FALSE;
769  } else {
770  return ERR_UNKNOWNRESPONSE;
771  }
772  continue;
773  }
774  if (Block[0] == N7110_PBK_GROUP) {
777  smprintf(s, "Caller group \"%i\"\n",Block[5]);
778  entry->Entries[entry->EntriesNum].Number=Block[5];
779  if (Block[5]!=0) entry->EntriesNum ++;
780  continue;
781  }
782  if (Block[0] == N6510_PBK_VOICETAG_ID) {
783  smprintf(s, "Entry %i has voice tag %i\n",Block[5]-1,Block[7]);
784  entry->Entries[entry->EntriesNum].VoiceTag = Block[7];
785  continue;
786  }
787 
788  /* 6210 5.56, SIM speed dials or ME with 1 number */
789  if (Block[0] == N7110_PBK_SIM_SPEEDDIAL) {
790  if ((int)entry->MemoryType==MEM7110_SP) {
791 #ifdef DEBUG
792  smprintf(s, "location %i\n",(Block[6]*256+Block[7]));
793 #endif
794  speed->MemoryType = MEM_ME;
795  if (Block[8] == 0x06) speed->MemoryType = MEM_SM;
796  speed->MemoryLocation = (Block[6]*256+Block[7]);
797  speed->MemoryNumberID = 2;
798  } else {
799  return ERR_UNKNOWNRESPONSE;
800  }
801  continue;
802  }
803 
804  if (Block[0] == N7110_PBK_SPEEDDIAL) {
805  if ((int)entry->MemoryType==MEM7110_SP) {
806 #ifdef DEBUG
807  switch (Block[12]) {
808  case 0x05: smprintf(s, "ME\n"); break;
809  case 0x06: smprintf(s, "SM\n"); break;
810  default : smprintf(s, "%02x\n",Block[12]);
811  }
812  smprintf(s, "location %i, number %i in location\n",
813  (Block[6]*256+Block[7])-1,Block[14]);
814 #endif
815  switch (Block[12]) {
816  case 0x05: speed->MemoryType = MEM_ME; break;
817  case 0x06: speed->MemoryType = MEM_SM; break;
818  }
819  speed->MemoryLocation = (Block[6]*256+Block[7])-1;
820  speed->MemoryNumberID = Block[14];
821  } else {
822  return ERR_UNKNOWNRESPONSE;
823  }
824  continue;
825  }
826  if (Block[0] == N6510_PBK_RINGTONEFILE_ID) {
827  smprintf(s, "Ringtone ID with possibility of using filesystem\n");
828  if ((int)entry->MemoryType==MEM7110_CG) {
829  if (Block[9] == 0x01) {
830  smprintf(s, "Filesystem ringtone ID: %02x\n",Block[10]*256+Block[11]);
831  bitmap->FileSystemRingtone = TRUE;
832  } else {
833  smprintf(s, "Internal ringtone ID: %02x\n",Block[10]*256+Block[11]);
834  bitmap->FileSystemRingtone = FALSE;
835  }
836  bitmap->RingtoneID = Block[10]*256+Block[11];
837  bitmap->DefaultRingtone = FALSE;
838  } else if ((int)entry->MemoryType==MEM6510_CG2) {
839  /* FIXME */
840  smprintf(s, "Internal ringtone ID: %02x\n",Block[10]*256+Block[11]);
841  bitmap->FileSystemRingtone = FALSE;
842  bitmap->RingtoneID = Block[10]*256+Block[11];
843  bitmap->DefaultRingtone = FALSE;
844  } else {
845  /* series 40 3.0 */
846  smprintf(s, "Filesystem ringtone ID: %02x\n",Block[10]*256+Block[11]);
849  entry->Entries[entry->EntriesNum].Number=Block[10]*256+Block[11];
850  entry->EntriesNum ++;
851  }
852  continue;
853  }
854  if (Block[0] == N6510_PBK_SMSLIST_ID) {
855  smprintf(s, "Entry %i is assigned to SMS list %i\n",Block[5]-1,Block[9]);
856  i = 0;
857  while(entry->Entries[Block[5]-1].SMSList[i] != 0) i++;
858  entry->Entries[Block[5]-1].SMSList[i+1] = 0;
859  entry->Entries[Block[5]-1].SMSList[i] = Block[9];
860  continue;
861  }
862  if (Block[0] == N7110_PBK_MISSED) {
863  missed_call = TRUE;
864  smprintf(s,"Unknown entry type 0x%02x data length %d\n", Block[0], bs-6);
865  continue;
866  }
867  if (Block[0] == N7110_PBK_UNKNOWN2
868  || Block[0] == N7110_PBK_UNKNOWN3
869  || Block[0] == N3600_PBK_UNKNOWN1
870  || Block[0] == N6303_PBK_UNKNOWN1
871  || Block[0] == N6303_PBK_UNKNOWN2) {
872  smprintf(s,"Unknown entry type 0x%02x data length %d\n", Block[0], bs-6);
873  continue;
874  }
875  if (Block[0] == N6510_PBK_UNKNOWN2) {
876  smprintf(s,"Unknown entry - probably ID for conversation list\n");
877  continue;
878  }
879  if (Block[0] == N6510_PBK_UNKNOWN3) {
880  smprintf(s,"Unknown entry - probably ID for Instant Messaging service list\n");
881  continue;
882  }
883  if (Block[0] == N6510_PBK_UNKNOWN4) {
884  smprintf(s,"Unknown entry - probably ID for presence list\n");
885  continue;
886  }
887  if (Block[0] == N6510_PBK_PUSHTOTALK_ID) {
888  smprintf(s,"SIP Address (Push to Talk address)\n");
889  if (! N71_65_PB_CopyString(s, entry, Block+6, Block[5]))
890  return ERR_UNKNOWNRESPONSE;
893  entry->EntriesNum ++;
894  continue;
895  }
896  if (Block[0] == N6510_PBK_UNKNOWN5) {
897  smprintf(s,"Unknown entry\n");
898  continue;
899  }
900  if (Block[0] == N6510_PBK_GROUP2_ID) {
901  smprintf(s,"Group ID (6230i or later)\n");
902 
905  smprintf(s, "Caller group \"%i\"\n",Block[7]);
906  entry->Entries[entry->EntriesNum].Number=Block[7];
907  entry->EntriesNum ++;
908  continue;
909  }
910  if (Block[0] == N2630_PBK_FAVMESSAGING) {
911  if (used_favorite_messaging_numbers >= sizeof(favorite_messaging_numbers) / sizeof(int)) {
912  smprintf(s, "Too many favorite messaging numbers!\n");
913  return ERR_MOREMEMORY;
914  }
915  favorite_messaging_numbers[used_favorite_messaging_numbers] = (int)Block[5];
916  used_favorite_messaging_numbers++;
917 
918  continue;
919  }
920  smprintf(s, "ERROR: unknown pbk entry 0x%02x\n",Block[0]);
921  return ERR_UNKNOWNRESPONSE;
922  }
923 
924  if (entry->EntriesNum == 0) {
925  if (missed_call) {
926  smprintf(s, "Empty entry with missed call reference, adding blank number!\n");
929  EncodeUnicode(entry->Entries[entry->EntriesNum].Text, "", 0);
930  } else {
931  return ERR_EMPTY;
932  }
933  }
934 
935  /* Process favorite messaging numbers */
936  for (i = 0; i < (int)used_favorite_messaging_numbers; i++) {
937  if (entry->EntriesNum >= GSM_PHONEBOOK_ENTRIES) {
938  smprintf(s, "Too many entries\n");
939  return ERR_MOREMEMORY;
940  }
941 
942  /* The phone sends an entry id. We store it as phone number because
943  * entry->Entries doesn't retain order. */
944 
947  CopyUnicodeString(entry->Entries[entry->EntriesNum].Text,entry->Entries[favorite_messaging_numbers[i] - 1].Text);
948  smprintf(s,"Marked entry #%i (%s) as favorite messaging number\n",
949  favorite_messaging_numbers[i],
950  DecodeUnicodeString(entry->Entries[entry->EntriesNum].Text));
951  entry->EntriesNum ++;
952  }
953  return ERR_NONE;
954 }
955 
957 {
958  Bitmap->DefaultName = FALSE;
959  if (Bitmap->Text[0]==0x00 && Bitmap->Text[1]==0x00) {
960  Bitmap->DefaultName = TRUE;
961  switch(Bitmap->Location) {
962  case 1: EncodeUnicode(Bitmap->Text,_("Family"),strlen(_("Family")));
963  break;
964  case 2: EncodeUnicode(Bitmap->Text,_("VIP"),strlen(_("VIP")));
965  break;
966  case 3: EncodeUnicode(Bitmap->Text,_("Friends"),strlen(_("Friends")));
967  break;
968  case 4: EncodeUnicode(Bitmap->Text,_("Colleagues"),strlen(_("Colleagues")));
969  break;
970  case 5: EncodeUnicode(Bitmap->Text,_("Other"),strlen(_("Other")));
971  break;
972  }
973  }
974 }
975 
976 void NOKIA_DecodeDateTime(GSM_StateMachine *s, unsigned char* buffer, GSM_DateTime *datetime, gboolean seconds, gboolean DayMonthReverse)
977 {
978  datetime->Year = buffer[0] * 256 + buffer[1];
979  /* Sometimes reversed */
980  if (datetime->Year > 3000) {
981  datetime->Year = buffer[1] * 256 + buffer[0];
982  }
983  if (DayMonthReverse) {
984  datetime->Month = buffer[3];
985  datetime->Day = buffer[2];
986  } else {
987  datetime->Month = buffer[2];
988  datetime->Day = buffer[3];
989  }
990 
991  datetime->Hour = buffer[4];
992  datetime->Minute = buffer[5];
993  if (seconds) {
994  datetime->Second = buffer[6];
995  } else {
996  datetime->Second = 0;
997  }
998  datetime->Timezone = 0;
999 
1000  smprintf(s, "Decoding date and time\n");
1001  smprintf(s, " Time: %02d:%02d:%02d\n",
1002  datetime->Hour, datetime->Minute, datetime->Second);
1003  smprintf(s, " Date: %4d/%02d/%02d\n",
1004  datetime->Year, datetime->Month, datetime->Day);
1005 }
1006 
1007 void NOKIA_EncodeDateTime(GSM_StateMachine *s UNUSED, unsigned char* buffer, GSM_DateTime *datetime)
1008 {
1009  buffer[0] = datetime->Year / 256;
1010  buffer[1] = datetime->Year % 256;
1011  buffer[2] = datetime->Month;
1012  buffer[3] = datetime->Day;
1013 
1014  buffer[4] = datetime->Hour;
1015  buffer[5] = datetime->Minute;
1016 }
1017 
1018 
1019 #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4)
1020 
1021 /* --------------------- Some general Nokia functions ---------------------- */
1022 
1023 void NOKIA_DecodeSMSState(GSM_StateMachine *s, unsigned char state, GSM_SMSMessage *sms)
1024 {
1025  switch (state) {
1026  case 0x01 : sms->State = SMS_Read; break;
1027  case 0x03 : sms->State = SMS_UnRead; break;
1028  case 0x05 : sms->State = SMS_Sent; break;
1029  case 0x07 : sms->State = SMS_UnSent; break;
1030  default :
1031  sms->State = SMS_Read;
1032  smprintf(s, "Unknown SMS state: %02x\n",state);
1033  break;
1034  }
1035 }
1036 
1038 {
1039  strcpy(s->Phone.Data.PhoneString, msg->Buffer+s->Phone.Data.StartPhoneString);
1040  return ERR_NONE;
1041 }
1042 
1043 /* Some strings are very easy. Some header, after it required string and 0x00.
1044  * We can get them using this function. We give frame to send (*string),
1045  * type of message (type), pointer for buffer for response (*value), request
1046  * type (request) and what is start byte in response for our string
1047  */
1048 GSM_Error NOKIA_GetPhoneString(GSM_StateMachine *s, const unsigned char *msgframe, int msglen, unsigned char msgtype, char *retvalue, GSM_Phone_RequestID request, int startresponse)
1049 {
1050  retvalue[0] = 0;
1051  s->Phone.Data.StartPhoneString = startresponse;
1052  s->Phone.Data.PhoneString = retvalue;
1053  return GSM_WaitFor (s, msgframe, msglen,msgtype, 4, request);
1054 }
1055 
1057 {
1058  strcpy(s->Phone.Data.Manufacturer,"Nokia");
1059  return ERR_NONE;
1060 }
1061 
1062 /* Many functions contains such strings:
1063  * (1. length/256) - exist or not
1064  * 2. length%256
1065  * 3. string (unicode, no termination)
1066  * This function read string to output and increases counter
1067  */
1068 void NOKIA_GetUnicodeString(GSM_StateMachine *s UNUSED, int *current, unsigned char *input, unsigned char *output, gboolean FullLength)
1069 {
1070  int length;
1071 
1072  if (FullLength) {
1073  length = (input[*current]*256+input[*current+1])*2;
1074  memcpy(output,input+(*current+2),length);
1075  *current = *current + 2 + length;
1076  } else {
1077  length = (input[*current])*2;
1078  memcpy(output,input+(*current+1),length);
1079  *current = *current + 1 + length;
1080  }
1081 
1082  output[length ] = 0;
1083  output[length+1] = 0;
1084 }
1085 
1086 int NOKIA_SetUnicodeString(GSM_StateMachine *s UNUSED, unsigned char *dest, unsigned char *string, gboolean FullLength)
1087 {
1088  int length;
1089 
1090  length = UnicodeLength(string);
1091  if (FullLength) {
1092  dest[0] = length / 256;
1093  dest[1] = length % 256;
1094  CopyUnicodeString(dest + 2, string);
1095  return 2+length*2;
1096  } else {
1097  dest[0] = length % 256;
1098  CopyUnicodeString(dest + 1, string);
1099  return 1+length*2;
1100  }
1101 }
1102 
1103 /* Returns correct ID for concrete memory type */
1104 GSM_MemoryType NOKIA_GetMemoryType(GSM_StateMachine *s UNUSED, GSM_MemoryType memory_type, unsigned char *ID)
1105 {
1106  int i=0;
1107 
1108  while (ID[i+1]!=0x00) {
1109  if (ID[i]==memory_type) return ID[i+1];
1110  i=i+2;
1111  }
1112  return 0xff;
1113 }
1114 
1116 {
1117  int i,j;
1118 
1119  if (Folder->Number!=0) {
1120  /* Bouble sorting */
1121  i=0;
1122  while (i!=Folder->Number-1) {
1123  if (Folder->Location[i]>Folder->Location[i+1]) {
1124  j=Folder->Location[i];
1125  Folder->Location[i]=Folder->Location[i+1];
1126  Folder->Location[i+1]=j;
1127  i=0;
1128  } else {
1129  i++;
1130  }
1131  }
1132 #ifdef DEBUG
1133  smprintf(s, "Locations: ");
1134  for (i=0;i<Folder->Number;i++) {
1135  smprintf(s, "%i ",Folder->Location[i]);
1136  }
1137  smprintf(s, "\n");
1138 #endif
1139  }
1140 }
1141 
1143 {
1144  if (Profile->DefaultName) {
1145  switch(Profile->Location) {
1146  case 1: EncodeUnicode(Profile->Name,_("General"),strlen(_("General")));
1147  break;
1148  case 2: EncodeUnicode(Profile->Name,_("Silent"),strlen(_("Silent")));
1149  break;
1150  case 3: EncodeUnicode(Profile->Name,_("Meeting"),strlen(_("Meeting")));
1151  break;
1152  case 4: EncodeUnicode(Profile->Name,_("Outdoor"),strlen(_("Outdoor")));
1153  break;
1154  case 5: EncodeUnicode(Profile->Name,_("Pager"),strlen(_("Pager")));
1155  break;
1156  case 6: EncodeUnicode(Profile->Name,_("Car"),strlen(_("Car")));
1157  break;
1158  case 7: EncodeUnicode(Profile->Name,_("Headset"),strlen(_("Headset")));
1159  break;
1160  }
1161  }
1162 }
1163 
1164 /* - Shared for DCT3 (n6110.c, n7110.c, n9110.c) and DCT4 (n6510.c) phones - */
1165 
1167 {
1169  int i,pos = 11,j;
1170  size_t number_pos;
1171  GSM_Error error;
1172 
1173  switch (msg->Buffer[3]) {
1174  case 0x02:
1175  smprintf(s,"Message: Call divert status received\n");
1176  smprintf(s," Divert type: ");
1177  switch (msg->Buffer[6]) {
1178  case 0x43: smprintf(s,"when busy"); break;
1179  case 0x3d: smprintf(s,"when not answered"); break;
1180  case 0x3e: smprintf(s,"when phone off or no coverage"); break;
1181  case 0x15: smprintf(s,"all types of diverts"); break;
1182  default: smprintf(s,"unknown %i",msg->Buffer[6]); break;
1183  }
1184  if (cd == NULL) {
1185  return ERR_NONE;
1186  }
1187  /* 6150 */
1188  if (msg->Length == 0x0b) {
1189  cd->EntriesNum = 0;
1190  return ERR_NONE;
1191  }
1192  cd->EntriesNum = msg->Buffer[10];
1193  for (i=0;i<cd->EntriesNum;i++) {
1194  smprintf(s,"\n Calls type : ");
1195  switch (msg->Buffer[pos]) {
1196  case 0x0b:
1197  smprintf(s,"voice");
1199  break;
1200  case 0x0d:
1201  smprintf(s,"fax");
1203  break;
1204  case 0x19:
1205  smprintf(s,"data");
1207  break;
1208  default:
1209  smprintf(s,"unknown %i",msg->Buffer[pos]);
1210  /* 6310i */
1211  cd->EntriesNum = 0;
1212  return ERR_NONE;
1213  }
1214  smprintf(s,"\n");
1215  j = pos + 2;
1216  while (msg->Buffer[j] != 0x00) j++;
1217  msg->Buffer[pos+1] = j - pos - 2;
1218  number_pos = pos + 1;
1219  error = GSM_UnpackSemiOctetNumber(&(s->di), cd->Entries[i].Number, msg->Buffer, &number_pos, msg->Length, FALSE);
1220  if (error != ERR_NONE) {
1221  return error;
1222  }
1223  smprintf(s," Number : %s\n",DecodeUnicodeString(cd->Entries[i].Number));
1224  cd->Entries[i].Timeout = msg->Buffer[pos+34];
1225  smprintf(s," Timeout : %i seconds\n",msg->Buffer[pos+34]);
1226  pos+=35;
1227  }
1228  return ERR_NONE;
1229  case 0x03:
1230  smprintf(s,"Message: Call divert status receiving error ?\n");
1231  return ERR_UNKNOWN;
1232  }
1233  return ERR_UNKNOWNRESPONSE;
1234 }
1235 
1236 static GSM_Error DCT3DCT4_CallDivert(GSM_StateMachine *s, GSM_CallDivert *request, GSM_MultiCallDivert *response, gboolean get)
1237 {
1238  int length = 0x09;
1239  unsigned char req[55] = {N6110_FRAME_HEADER, 0x01,
1240  0x05, /* operation = Query */
1241  0x00,
1242  0x00, /* divert type */
1243  0x00, /* call type */
1244  0x00};
1245 
1246  if (!get) {
1247  if (UnicodeLength(request->Number) == 0) {
1248  req[4] = 0x04;
1249  } else {
1250  req[4] = 0x03;
1251  req[8] = 0x01;
1252  req[29] = GSM_PackSemiOctetNumber(request->Number, req + 9, FALSE);
1253  req[52] = request->Timeout;
1254  length = 55;
1255  }
1256  }
1257  switch (request->DivertType) {
1258  case GSM_DIVERT_AllTypes : req[6] = 0x15; break;
1259  case GSM_DIVERT_Busy : req[6] = 0x43; break;
1260  case GSM_DIVERT_NoAnswer : req[6] = 0x3d; break;
1261  case GSM_DIVERT_OutOfReach: req[6] = 0x3e; break;
1262  default : return ERR_NOTIMPLEMENTED;
1263  }
1264 
1265  switch (request->CallType) {
1266  case GSM_DIVERT_AllCalls : break;
1267  case GSM_DIVERT_VoiceCalls: req[7] = 0x0b; break;
1268  case GSM_DIVERT_FaxCalls : req[7] = 0x0d; break;
1269  case GSM_DIVERT_DataCalls : req[7] = 0x19; break;
1270  default : return ERR_NOTIMPLEMENTED;
1271  }
1272 
1273  s->Phone.Data.Divert = response;
1274  smprintf(s, "Call divert\n");
1275  return GSM_WaitFor (s, req, length, 0x06, 10, ID_Divert);
1276 }
1277 
1279 {
1280  return DCT3DCT4_CallDivert(s, request, response, TRUE);
1281 }
1282 
1284 {
1285  return DCT3DCT4_CallDivert(s, divert, NULL, FALSE);
1286 }
1287 
1289 {
1290  GSM_MultiCallDivert divert;
1291  unsigned char req[55] = {N6110_FRAME_HEADER, 0x01,
1292  0x04, /* operation = Disable */
1293  0x00,
1294  0x02, /* divert type */
1295  0x00, /* call type */
1296  0x00};
1297 
1298  s->Phone.Data.Divert = &divert;
1299  smprintf(s, "Call divert\n");
1300  return GSM_WaitFor (s, req, 0x09, 0x06, 10, ID_Divert);
1301 }
1302 
1304 {
1305  GSM_Phone_Data *Data = &s->Phone.Data;
1306 
1307  Data->WAPSettings->Active = FALSE;
1308  if (Data->WAPSettings->Location - 1 == msg->Buffer[4]) {
1309  Data->WAPSettings->Active = TRUE;
1310  }
1311  return ERR_NONE;
1312 }
1313 
1315 {
1316  unsigned char GetSetreq[] = {N6110_FRAME_HEADER, 0x0F};
1317 
1318  smprintf(s, "Checking, if connection settings are active\n");
1319  return GSM_WaitFor (s, GetSetreq, 4, 0x3f, 4, ID_GetConnectSet);
1320 }
1321 
1323 {
1324  smprintf(s, "Connection settings activated\n");
1325  return ERR_NONE;
1326 }
1327 
1329 {
1330  unsigned char reqActivate[] = {N6110_FRAME_HEADER, 0x12,
1331  0x00}; /* Location */
1332 
1333  if (settings->Active) {
1334  reqActivate[4] = settings->Location-1;
1335  smprintf(s, "Activating connection settings number %i\n",settings->Location);
1336  return GSM_WaitFor (s, reqActivate, 5, 0x3f, 4, ID_SetConnectSet);
1337  }
1338  return ERR_NONE;
1339 }
1340 
1341 
1342 GSM_Error DCT3DCT4_SendDTMF(GSM_StateMachine *s, char *DTMFSequence)
1343 {
1344  unsigned char req[100] = {N6110_FRAME_HEADER, 0x50,
1345  0x00}; /* Length */
1346 
1348  if (strlen(DTMFSequence) > 100 - 5) return ERR_NOTSUPPORTED;
1349 
1350  req[4] = strlen(DTMFSequence);
1351 
1352  memcpy(req+5,DTMFSequence,strlen(DTMFSequence));
1353 
1354  smprintf(s, "Sending DTMF\n");
1355  return GSM_WaitFor (s, req, 5+strlen(DTMFSequence), 0x01, 4, ID_SendDTMF);
1356 }
1357 
1359 {
1360  int tmp;
1361  GSM_Phone_Data *Data = &s->Phone.Data;
1362 
1363  smprintf(s, "WAP bookmark received\n");
1364  switch (msg->Buffer[3]) {
1365  case 0x07:
1366  tmp = 4;
1367 
1368  Data->WAPBookmark->Location = msg->Buffer[tmp] * 256 + msg->Buffer[tmp+1];
1369  smprintf(s, "Location: %i\n",Data->WAPBookmark->Location);
1370  tmp = tmp + 2;
1371 
1372  NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPBookmark->Title, FullLength);
1373  smprintf(s, "Title : \"%s\"\n",DecodeUnicodeString(Data->WAPBookmark->Title));
1374 
1375  NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPBookmark->Address, FullLength);
1376  smprintf(s, "Address : \"%s\"\n",DecodeUnicodeString(Data->WAPBookmark->Address));
1377 
1378  return ERR_NONE;
1379  case 0x08:
1380  switch (msg->Buffer[4]) {
1381  case 0x01:
1382  smprintf(s, "Security error. Inside WAP bookmarks menu\n");
1383  return ERR_INSIDEPHONEMENU;
1384  case 0x02:
1385  smprintf(s, "Invalid or empty\n");
1386  return ERR_INVALIDLOCATION;
1387  default:
1388  smprintf(s, "ERROR: unknown %i\n",msg->Buffer[4]);
1389  return ERR_UNKNOWNRESPONSE;
1390  }
1391  }
1392  return ERR_UNKNOWNRESPONSE;
1393 }
1394 
1396 {
1397  switch (msg->Buffer[3]) {
1398  case 0x0A:
1399  smprintf(s, "WAP bookmark set OK\n");
1400  return ERR_NONE;
1401  case 0x0B:
1402  smprintf(s, "WAP bookmark setting error\n");
1403  switch (msg->Buffer[4]) {
1404  case 0x01:
1405  smprintf(s, "Security error. Inside WAP bookmarks menu\n");
1406  return ERR_INSIDEPHONEMENU;
1407  case 0x02:
1408  smprintf(s, "Can't write to empty location ?\n");
1409  return ERR_EMPTY;
1410  case 0x04:
1411  smprintf(s, "Full memory\n");
1412  return ERR_FULL;
1413  default:
1414  smprintf(s, "ERROR: unknown %i\n",msg->Buffer[4]);
1415  return ERR_UNKNOWNRESPONSE;
1416  }
1417  }
1418  return ERR_UNKNOWNRESPONSE;
1419 }
1420 
1422 {
1423  smprintf(s, "Connection functions enabled\n");
1424  return ERR_NONE;
1425 }
1426 
1428 {
1429  unsigned char req[] = {N6110_FRAME_HEADER, 0x00};
1430 
1432 
1433  smprintf(s, "Enabling WAP\n");
1434  return GSM_WaitFor (s, req, 4, 0x3f, 4, ID_EnableConnectFunc);
1435 }
1436 
1438 {
1439  smprintf(s, "Connection functions disabled\n");
1440  return ERR_NONE;
1441 }
1442 
1444 {
1445  unsigned char req[] = {N6110_FRAME_HEADER, 0x03};
1446 
1448 
1449  smprintf(s, "Disabling connection settings\n");
1450  return GSM_WaitFor (s, req, 4, 0x3f, 4, ID_DisableConnectFunc);
1451 }
1452 
1454 {
1455  switch (msg->Buffer[3]) {
1456  case 0x0D:
1457  smprintf(s, "WAP bookmark deleted OK\n");
1458  return ERR_NONE;
1459  case 0x0E:
1460  smprintf(s, "WAP bookmark deleting error\n");
1461  switch (msg->Buffer[4]) {
1462  case 0x01:
1463  smprintf(s, "Security error. Inside WAP bookmarks menu\n");
1464  return ERR_SECURITYERROR;
1465  case 0x02:
1466  smprintf(s, "Invalid location\n");
1467  return ERR_INVALIDLOCATION;
1468  default:
1469  smprintf(s, "ERROR: unknown %i\n",msg->Buffer[4]);
1470  return ERR_UNKNOWNRESPONSE;
1471  }
1472  }
1473  return ERR_UNKNOWNRESPONSE;
1474 }
1475 
1477 {
1478  GSM_Error error;
1479  unsigned char req[] = {N6110_FRAME_HEADER, 0x0C,
1480  0x00, 0x00}; /* Location */
1481 
1482  req[5] = bookmark->Location;
1483 
1484  smprintf(s, "Deleting WAP bookmark\n");
1485  error = GSM_WaitFor (s, req, 6, 0x3f, 4, ID_DeleteWAPBookmark);
1486  if (error != ERR_NONE) {
1487  if (error == ERR_INVALIDLOCATION || error == ERR_INSIDEPHONEMENU) {
1489  }
1490  return error;
1491  }
1492 
1494 }
1495 
1497 {
1498  GSM_Error error;
1499  unsigned char req[] = {N6110_FRAME_HEADER, 0x06,
1500  0x00, 0x00}; /* Location */
1501 
1502  req[5]=bookmark->Location-1;
1503 
1504  s->Phone.Data.WAPBookmark=bookmark;
1505  smprintf(s, "Getting WAP bookmark\n");
1506  error = GSM_WaitFor (s, req, 6, 0x3f, 4, ID_GetWAPBookmark);
1507  if (error != ERR_NONE) {
1508  if (error == ERR_INVALIDLOCATION || error == ERR_INSIDEPHONEMENU) {
1510  }
1511  return error;
1512  }
1513 
1515 }
1516 
1518 {
1519  unsigned char req[] = {N6110_FRAME_HEADER, 0x08, 0x00, 0x85};
1520 
1521  req[4] = (unsigned char)ID;
1522  s->Phone.Data.CallID = ID;
1523 
1524  smprintf(s, "Canceling single call\n");
1525  return GSM_WaitFor (s, req, 6, 0x01, 4, ID_CancelCall);
1526 }
1527 
1529 {
1530  unsigned char req[] = {N6110_FRAME_HEADER, 0x06, 0x00, 0x00};
1531 
1532  req[4] = (unsigned char)ID;
1533  s->Phone.Data.CallID = ID;
1534 
1535  smprintf(s, "Answering single call\n");
1536  return GSM_WaitFor (s, req, 6, 0x01, 4, ID_AnswerCall);
1537 }
1538 
1540 {
1541  GSM_CutLines lines;
1542  GSM_Phone_Data *Data = &s->Phone.Data;
1543 
1544  InitLines(&lines);
1545 
1546  SplitLines(msg->Buffer, msg->Length, &lines, "\x20\x0A", 2, "", 0, FALSE);
1547 
1548  strcpy(Data->Model,GetLineString(msg->Buffer, &lines, 4));
1549  smprintf(s, "Received model %s\n",Data->Model);
1550  Data->ModelInfo = GetModelData(s, NULL, Data->Model, NULL);
1551 
1552  strcpy(Data->VerDate,GetLineString(msg->Buffer, &lines, 3));
1553  smprintf(s, "Received firmware date %s\n",Data->VerDate);
1554 
1555  strcpy(Data->Version,GetLineString(msg->Buffer, &lines, 2));
1556  smprintf(s, "Received firmware version %s\n",Data->Version);
1558 
1559  FreeLines(&lines);
1560 
1561  return ERR_NONE;
1562 }
1563 
1565 {
1566  unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
1567  GSM_Error error;
1568 
1569  if (strlen(s->Phone.Data.Model)>0) return ERR_NONE;
1570 
1571  smprintf(s, "Getting model\n");
1572  error=GSM_WaitFor (s, req, 5, 0xd1, 3, ID_GetModel);
1573  if (error == ERR_NONE) {
1574  smprintf_level(s, D_TEXT, "[Connected model - \"%s\"]\n",
1575  s->Phone.Data.Model);
1576  smprintf_level(s, D_TEXT, "[Firmware version - \"%s\"]\n",
1577  s->Phone.Data.Version);
1578  smprintf_level(s, D_TEXT, "[Firmware date - \"%s\"]\n",
1579  s->Phone.Data.VerDate);
1580  }
1581  return error;
1582 }
1583 
1585 {
1586  unsigned char req[5] = {N6110_FRAME_HEADER, 0x03, 0x00};
1587  GSM_Error error;
1588 
1589  if (strlen(s->Phone.Data.Version)>0) return ERR_NONE;
1590 
1591  smprintf(s, "Getting firmware version\n");
1592  error=GSM_WaitFor (s, req, 5, 0xd1, 3, ID_GetFirmware);
1593  if (error == ERR_NONE) {
1594  smprintf_level(s, D_TEXT, "[Connected model - \"%s\"]\n",
1595  s->Phone.Data.Model);
1596  smprintf_level(s, D_TEXT, "[Firmware version - \"%s\"]\n",
1597  s->Phone.Data.Version);
1598  smprintf_level(s, D_TEXT, "[Firmware date - \"%s\"]\n",
1599  s->Phone.Data.VerDate);
1600  }
1601  return error;
1602 }
1603 
1604 /* ---------- Shared for n7110.c and n6510.c ------------------------------- */
1605 
1606 GSM_Error N71_65_ReplyGetMemoryError(unsigned char error, GSM_StateMachine *s)
1607 {
1608  switch (error) {
1609  case 0x21:
1610  smprintf(s, "Wait for synchronisation???\n");
1611  return ERR_WORKINPROGRESS;
1612  case 0x24:
1613  smprintf(s, "No own number???\n");
1614  return ERR_NOTSUPPORTED;
1615  case 0x27:
1616  smprintf(s, "No PIN\n");
1617  return ERR_SECURITYERROR;
1618  case 0x30:
1619  if (s->Phone.Data.Memory->MemoryType == MEM_ME ||
1620  s->Phone.Data.Memory->MemoryType == MEM_SM) {
1621  smprintf(s, "Empty entry\n");
1622  return ERR_EMPTY;
1623  }
1624  smprintf(s, "Invalid memory type\n");
1625  return ERR_NOTSUPPORTED;
1626  case 0x31:
1627  smprintf(s, "Invalid memory type?\n");
1628  s->Phone.Data.Memory->EntriesNum = 0;
1629  return ERR_EMPTY;
1630  case 0x33:
1631  smprintf(s, "Empty location\n");
1632  s->Phone.Data.Memory->EntriesNum = 0;
1633  return ERR_EMPTY;
1634  case 0x34:
1635  smprintf(s, "Too high location ?\n");
1636  return ERR_INVALIDLOCATION;
1637  case 0x3B: /* Tim Dreessen, 6230 */
1638  smprintf(s, "Empty location\n");
1639  s->Phone.Data.Memory->EntriesNum = 0;
1640  /*
1641  * This is really empty, but this entry is calculated to
1642  * entries count, so we must return something.
1643  */
1644  return ERR_NONE;
1645  case 0x3d: /* Seen on RH-105 for own number */
1646  smprintf(s, "Empty location\n");
1647  s->Phone.Data.Memory->EntriesNum = 0;
1648  return ERR_NONE;
1649  default:
1650  smprintf(s, "ERROR: unknown status code 0x%x\n", error);
1651  return ERR_UNKNOWNRESPONSE;
1652  }
1653 }
1654 
1656 {
1657  switch (msg->Buffer[6]) {
1658  case 0x0f:
1659  smprintf(s, "Phonebook entry writing failed\n");
1660  switch (msg->Buffer[10]) {
1661  case 0xf:
1662  smprintf(s, "Invalid block sent\n");
1663  return ERR_BUG;
1664  case 0x21:
1665  smprintf(s, "Still busy processing the last command\n");
1666  return ERR_BUSY;
1667  case 0x23:
1668  smprintf(s, "Block size does not match a definition\n");
1669  return ERR_BUG;
1670  case 0x25:
1671  smprintf(s, "when you try to save into entry with caller group assignment in phone with caller groups standard 2 (like in 6230i)\n");
1672  return ERR_PERMISSION;
1673  case 0x29:
1674  smprintf(s, "no caller group with given number (6230i)\n");
1675  return ERR_MEMORY;
1676  case 0x32:
1677  smprintf(s, "Ignoring ERROR: unknown 50 (probably group contains 50 entries)\n");
1678  return ERR_NONE;
1679  case 0x36:
1680  smprintf(s, "Too long name\n");
1681  return ERR_NOTSUPPORTED;
1682  case 0x3c:
1683  smprintf(s, "Can not add entry with 0 subentries\n");
1684  return ERR_NOTSUPPORTED;
1685  case 0x3d:
1686  smprintf(s, "Wrong entry type\n");
1687  return ERR_NOTSUPPORTED;
1688  case 0x3e:
1689  smprintf(s, "Too many entries\n");
1690  return ERR_NOTSUPPORTED;
1691  case 0x43:
1692  smprintf(s, "Incorrect characters\n");
1693  return ERR_NOTSUPPORTED;
1694  default:
1695  smprintf(s, "ERROR: unknown %i\n",msg->Buffer[10]);
1696  return ERR_UNKNOWNRESPONSE;
1697  }
1698  default:
1699  smprintf(s, "Phonebook entry written\n");
1700  return ERR_NONE;
1701  }
1702 }
1703 
1705  GSM_Profile_PhoneTableValue ProfileTable[],
1706  GSM_Profile_Feat_ID FeatureID,
1707  GSM_Profile_Feat_Value FeatureValue,
1708  unsigned char *PhoneID,
1709  unsigned char *PhoneValue)
1710 {
1711  int i=0;
1712 
1713  smprintf(s, "Trying to find feature %i with value %i\n",FeatureID,FeatureValue);
1714  while (ProfileTable[i].ID != 0x00) {
1715  if (ProfileTable[i].ID == FeatureID &&
1716  ProfileTable[i].Value == FeatureValue) {
1717  *PhoneID = ProfileTable[i].PhoneID;
1718  *PhoneValue = ProfileTable[i].PhoneValue;
1719  return TRUE;
1720  }
1721  i++;
1722  }
1723  return FALSE;
1724 }
1725 
1726 #define PROFILE_CALLERGROUPS_GROUP1 0x01
1727 #define PROFILE_CALLERGROUPS_GROUP2 0x02
1728 #define PROFILE_CALLERGROUPS_GROUP3 0x04
1729 #define PROFILE_CALLERGROUPS_GROUP4 0x08
1730 #define PROFILE_CALLERGROUPS_GROUP5 0x10
1731 
1733  GSM_Profile_PhoneTableValue ProfileTable[],
1734  unsigned char ID,
1735  unsigned char Value,
1736  GSM_Phone_Data *Data,
1737  gboolean CallerGroups)
1738 {
1739  int i;
1740 
1741  if (CallerGroups) {
1742  smprintf(s, "Caller groups: %i\n", Value);
1744  Data->Profile->FeaturesNumber++;
1745  for (i=0;i<5;i++) Data->Profile->CallerGroups[i] = FALSE;
1746  if ((Value & PROFILE_CALLERGROUPS_GROUP1)==PROFILE_CALLERGROUPS_GROUP1) Data->Profile->CallerGroups[0] = TRUE;
1747  if ((Value & PROFILE_CALLERGROUPS_GROUP2)==PROFILE_CALLERGROUPS_GROUP2) Data->Profile->CallerGroups[1] = TRUE;
1748  if ((Value & PROFILE_CALLERGROUPS_GROUP3)==PROFILE_CALLERGROUPS_GROUP3) Data->Profile->CallerGroups[2] = TRUE;
1749  if ((Value & PROFILE_CALLERGROUPS_GROUP4)==PROFILE_CALLERGROUPS_GROUP4) Data->Profile->CallerGroups[3] = TRUE;
1750  if ((Value & PROFILE_CALLERGROUPS_GROUP5)==PROFILE_CALLERGROUPS_GROUP5) Data->Profile->CallerGroups[4] = TRUE;
1751  return;
1752  }
1753 
1754  i = 0;
1755  while (ProfileTable[i].ID != 0x00) {
1756  if (ProfileTable[i].PhoneID == ID &&
1757  ProfileTable[i].PhoneValue == Value) {
1758 #ifdef DEBUG
1759  switch (ProfileTable[i].ID) {
1760  case Profile_KeypadTone : smprintf(s, "Keypad tones\n"); break;
1761  case Profile_CallAlert : smprintf(s, "Call alert\n"); break;
1762  case Profile_RingtoneVolume : smprintf(s, "Ringtone volume\n"); break;
1763  case Profile_MessageTone : smprintf(s, "SMS message tones\n"); break;
1764  case Profile_Vibration : smprintf(s, "Vibration\n"); break;
1765  case Profile_WarningTone : smprintf(s, "Warning (ang games) tones\n"); break;
1766  case Profile_AutoAnswer : smprintf(s, "Automatic answer\n"); break;
1767  case Profile_Lights : smprintf(s, "Lights\n"); break;
1768  case Profile_ScreenSaver : smprintf(s, "Screen Saver\n"); break;
1769  case Profile_ScreenSaverTime : smprintf(s, "Screen Saver timeout\n"); break;
1770  default : break;
1771  }
1772 #endif
1773  Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = ProfileTable[i].ID;
1774  Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = ProfileTable[i].Value;
1775  Data->Profile->FeaturesNumber++;
1776  break;
1777  }
1778  i++;
1779  }
1780 }
1781 
1783  {Profile_KeypadTone, PROFILE_KEYPAD_OFF, 0x00,0x00},
1787  /* Lights ? */
1793 /* {Profile_CallAlert, PROFILE_CALLALERT_CALLERGROUPS,0x02,0x07}, */
1794  /* Ringtone ID */
1809  /* Caller groups */
1812  {0x00, 0x00, 0x00,0x00}
1813 };
1814 
1816 {
1817  s->Phone.Data.EnableIncomingSMS = enable;
1818 #ifdef DEBUG
1819  if (enable) {
1820  smprintf(s, "Enabling incoming SMS\n");
1821  } else {
1822  smprintf(s, "Disabling incoming SMS\n");
1823  }
1824 #endif
1825  return ERR_NONE;
1826 }
1827 
1829 {
1830  unsigned char buffer[2000];
1831  GSM_USSDMessage ussd;
1832 
1833  if (s->Phone.Data.RequestID == ID_Divert) return ERR_NONE;
1834 
1835  memcpy(buffer,msg->Buffer+8,msg->Buffer[7]);
1836  buffer[msg->Buffer[7]] = 0x00;
1837 
1838  smprintf(s, "USSD reply: \"%s\"\n",buffer);
1839 
1840  if (s->Phone.Data.EnableIncomingUSSD && s->User.IncomingUSSD!=NULL) {
1841  EncodeUnicode(ussd.Text,buffer,strlen(buffer));
1845  ussd.Status = USSD_Unknown;
1846  s->User.IncomingUSSD(s, &ussd, s->User.IncomingUSSDUserData);
1847  }
1848 
1849  return ERR_NONE;
1850 }
1851 
1853 {
1854  s->Phone.Data.EnableIncomingUSSD = enable;
1855 #ifdef DEBUG
1856  if (enable) {
1857  smprintf(s, "Enabling incoming USSD\n");
1858  } else {
1859  smprintf(s, "Disabling incoming USSD\n");
1860  }
1861 #endif
1862  return ERR_NONE;
1863 }
1864 
1866 {
1868 
1869  s->Phone.Data.EnableIncomingCall = enable;
1870 #ifdef DEBUG
1871  if (enable) {
1872  smprintf(s, "Enabling incoming Call\n");
1873  } else {
1874  smprintf(s, "Disabling incoming Call\n");
1875  }
1876 #endif
1877  return ERR_NONE;
1878 }
1879 
1881 {
1882  GSM_Call call;
1883  int tmp;
1884  unsigned char buffer[200];
1885 
1886  call.Status = 0;
1887  call.StatusCode = 0;
1888  call.CallIDAvailable = TRUE;
1889  call.PhoneNumber[0] = 0;
1890  call.PhoneNumber[1] = 0;
1891  smprintf(s, "Call info, ");
1892  switch (msg->Buffer[3]) {
1893  case 0x02:
1894  smprintf(s, "Call established, waiting for answer\n");
1896  break;
1897  case 0x03:
1898  case 0x53:
1899  case 0x05:
1900  if (msg->Buffer[3] == 0x03) {
1901  smprintf(s, "Call started\n");
1902  call.Status = GSM_CALL_CallStart;
1903  } else if (msg->Buffer[3] == 0x05) {
1904  smprintf(s, "Incoming call\n");
1906  } else {
1907  smprintf(s, "Outgoing call\n");
1909  }
1910 /* Sample reply:
1911 01 |72r|02 |03 |01 |03 |07 |04 |01 |01 |01 |1C |11 |300|00 | 0B .r...........0..
1912 00 |333|00 |322|00 |344|00 |399|00 |399|00 |355|00 |366|00 |377 .3.2.4.9.9.5.6.7
1913 00 |322|00 |311|00 |311|0E |1C |300|02 |0A |00 |00 |09 |00 |4AJ .2.1.1..0......J
1914 00 |6Fo|00 |72r|00 |69i|00 |73s|00 |20 |00 |41A|00 |63c|00 |63c .o.r.i.s. .A.c.c
1915 00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 |00 ............
1916 */
1917  smprintf(s, "Call mode : %i\n",msg->Buffer[5]);/* such interpretation is in gnokii */
1918  /* This is probably wrong, but I need more sample data to properly parse output */
1919  if (msg->Buffer[6] == 7) {
1920  tmp = 14;
1921  } else {
1922  tmp = 6;
1923  }
1924  NOKIA_GetUnicodeString(s, &tmp, msg->Buffer,call.PhoneNumber,FALSE);
1925  smprintf(s, "Number : \"%s\"\n",DecodeUnicodeString(call.PhoneNumber));
1926  /* FIXME: read name from frame */
1927 
1928  break;
1929  case 0x04:
1930  smprintf(s, "Remote end hang up\n");
1931  smprintf(s, "Cause Type : %i\n",msg->Buffer[5]);/* such interpretation is in gnokii */
1932  smprintf(s, "CC : %i\n",msg->Buffer[6]);
1933  smprintf(s, "MM(?) : %i\n",msg->Buffer[7]);
1934  smprintf(s, "RR(?) : %i\n",msg->Buffer[8]);
1936  call.StatusCode = msg->Buffer[6];
1937  break;
1938  case 0x07:
1939  smprintf(s, "Call answer initiated\n");
1940  break;
1941  case 0x09:
1942  smprintf(s, "Call released\n");
1944  break;
1945  case 0x0a:
1946  smprintf(s, "Call is being released\n");
1947  break;
1948  case 0x0b:
1949  smprintf(s, "Meaning not known\n");
1950  call.CallIDAvailable = FALSE;
1951  break;
1952  case 0x0c:
1953  smprintf(s, "Audio status\n");
1954  if (msg->Buffer[4] == 0x01) smprintf(s, "Audio enabled\n");
1955  else smprintf(s, "Audio disabled\n");
1956  call.CallIDAvailable = FALSE;
1957  break;
1958  case 0x0f: /* 6111 */
1959  if (msg->Buffer[8]==0x01) {
1960  smprintf(s, "Calling from phone keypad ?\n");
1961  if (msg->Buffer[14]==0x03) {
1962  tmp = 19;
1963  } else {
1964  tmp = 21;
1965  NOKIA_GetUnicodeString(s, &tmp, msg->Buffer,buffer,FALSE);
1966  smprintf(s, "Name : \"%s\"\n",DecodeUnicodeString(buffer));
1967  tmp+=7;
1968  }
1969  if (msg->Buffer[tmp-3]==0x11) {
1970  call.PhoneNumber[0]=0;
1971  call.PhoneNumber[1]='+';
1972  NOKIA_GetUnicodeString(s, &tmp, msg->Buffer,call.PhoneNumber+2,FALSE);
1973  } else {
1974  NOKIA_GetUnicodeString(s, &tmp, msg->Buffer,call.PhoneNumber,FALSE);
1975  }
1977  }
1978  if (msg->Buffer[8]==0x00) {
1979  smprintf(s, "Call released\n");
1981  }
1982  break;
1983  case 0x10:
1984  smprintf(s, "Meaning not known\n");
1985  call.CallIDAvailable = FALSE;
1986  break;
1987  case 0x23:
1988  smprintf(s, "Call held\n");
1989  call.Status = GSM_CALL_CallHeld;
1990  break;
1991  case 0x25:
1992  smprintf(s, "Call resumed\n");
1994  break;
1995  case 0x27:
1996  smprintf(s, "Call switched\n");
1998  break;
1999  case 0xA6:
2000  case 0xD2:
2001  case 0xD3:
2002  smprintf(s, "Meaning not known\n");
2003  call.CallIDAvailable = FALSE;
2004  break;
2005  }
2006  if (call.CallIDAvailable) smprintf(s, "Call ID : %d\n",msg->Buffer[4]);
2007  if (s->Phone.Data.EnableIncomingCall && s->User.IncomingCall!=NULL && call.Status != 0) {
2008  if (call.CallIDAvailable) call.CallID = msg->Buffer[4];
2009  s->User.IncomingCall(s, &call, s->User.IncomingCallUserData);
2010  }
2011  if (s->Phone.Data.RequestID == ID_DialVoice) {
2012  if (msg->Buffer[3] == 0x10) return ERR_NOTSUPPORTED;
2013  }
2014  if (s->Phone.Data.RequestID == ID_CancelCall) {
2015  if (msg->Buffer[3] == 0x09) {
2016  if (s->Phone.Data.CallID == msg->Buffer[4]) return ERR_NONE;
2017  /* when we canceled call and see frame about other
2018  * call releasing, we don't give ERR_NONE for "our"
2019  * call release command
2020  */
2021  return ERR_NEEDANOTHERANSWER;
2022  }
2023  }
2024  if (s->Phone.Data.RequestID == ID_AnswerCall) {
2025  if (msg->Buffer[3] == 0x07) {
2026  if (s->Phone.Data.CallID == msg->Buffer[4]) return ERR_NONE;
2027  return ERR_NEEDANOTHERANSWER;
2028  }
2029  }
2030  return ERR_NONE;
2031 }
2032 
2033 /* method 2 */
2035 {
2036  smprintf(s, "Calendar note added\n");
2037  return ERR_NONE;
2038 }
2039 
2040 /* method 2 */
2042 {
2043  GSM_CalendarNoteType NoteType;
2044  time_t t_time1,t_time2;
2045  GSM_DateTime Date,date_time;
2046  GSM_Error error;
2047  long diff;
2048  int Text, Time, Alarm, Phone, EndTime, Location, length=25;
2049  unsigned char req[5000] = {
2051  0x40,
2052  0x00, /* frame length - 7 */
2053  0x00,0x00,0x00,0x00,
2054  0x00,0x00,0x00,0x00, /* start time saved as difference */
2055  0x00,0x00,0xff,0xff, /* alarm saved as difference */
2056  0x00, /* frame length - 7 */
2057  0x00, /* note type */
2058  0x00,0x00, /* recurrance */
2059  0x00,0x00,0x00,0x00,
2060  0x00,0x00,0x00,0x00}; /* rest depends on note type */
2061 
2062  NoteType = N71_65_FindCalendarType(Note->Type, s->Phone.Data.ModelInfo);
2063 
2066  switch(NoteType) {
2067  case GSM_CAL_MEETING : req[18] = 0x01; length = 25; break;
2068  case GSM_CAL_CALL : req[18] = 0x02; length = 27; break;
2069  case GSM_CAL_BIRTHDAY : req[18] = 0x04; length = 28; break;
2070  case GSM_CAL_MEMO : req[18] = 0x08; length = 25; break;
2071  default : return ERR_UNKNOWN;
2072  }
2073  } else {
2074  switch(NoteType) {
2075  case GSM_CAL_REMINDER : req[18] = 0x01; length = 25; break;
2076  case GSM_CAL_CALL : req[18] = 0x02; length = 27; break;
2077  case GSM_CAL_BIRTHDAY : req[18] = 0x04; length = 28; break;
2078  case GSM_CAL_MEMO : req[18] = 0x08; length = 25; break;
2079  default : return ERR_UNKNOWN;
2080  }
2081  }
2082 
2083  GSM_CalendarFindDefaultTextTimeAlarmPhone(Note, &Text, &Time, &Alarm, &Phone, &EndTime, &Location);
2084 
2085  if (Time == -1) {
2086  smprintf(s, "Can not save entry without time!\n");
2087  return ERR_UNKNOWN;
2088  }
2089  if (NoteType != GSM_CAL_BIRTHDAY) {
2090  Date.Year = 2030; Date.Month = 01; Date.Day = 01;
2091  Date.Hour = 00; Date.Minute = 00; Date.Second = 00;
2092  } else {
2093  Date.Year = 2029; Date.Month = 12; Date.Day = 31;
2094  Date.Hour = 22; Date.Minute = 59; Date.Second = 58;
2095  }
2096  t_time1 = Fill_Time_T(Date);
2097  memcpy(&Date,&Note->Entries[Time].Date,sizeof(GSM_DateTime));
2098  if (NoteType != GSM_CAL_BIRTHDAY) {
2099  Date.Year -= 20;
2100  } else {
2101  /* 6230 and probably other new models handle it differently
2102  we don't make difference from 1980 year
2103  */
2107  Date.Year = 1980;
2108  }
2109  Date.Hour = 22; Date.Minute = 58; Date.Second = 58;
2110  }
2111  t_time2 = Fill_Time_T(Date);
2112  diff = t_time1-t_time2;
2113  smprintf(s, " Difference : %li seconds\n", -diff);
2114  req[9] = (unsigned char)(-diff >> 24);
2115  req[10] = (unsigned char)(-diff >> 16);
2116  req[11] = (unsigned char)(-diff >> 8);
2117  req[12] = (unsigned char)(-diff);
2118  if (NoteType == GSM_CAL_BIRTHDAY) {
2119  req[25] = Note->Entries[Time].Date.Year / 256;
2120  req[26] = Note->Entries[Time].Date.Year % 256;
2121  /* Recurrance = 1 year */
2122  req[19] = 0xff;
2123  req[20] = 0xff;
2124  }
2125 
2126  if (NoteType == GSM_CAL_CALL && Phone != -1) {
2127  req[25] = UnicodeLength(Note->Entries[Phone].Text);
2128  CopyUnicodeString(req+length,Note->Entries[Phone].Text);
2129  length += UnicodeLength(Note->Entries[Phone].Text)*2;
2130  }
2131 
2132  if (Alarm != -1) {
2133  if (NoteType == GSM_CAL_BIRTHDAY) {
2134  if (Note->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME) req[27] = 0x01;
2135  error=s->Phone.Functions->GetDateTime(s,&date_time);
2136  switch (error) {
2137  case ERR_EMPTY:
2138  case ERR_NOTIMPLEMENTED:
2139  GSM_GetCurrentDateTime(&date_time);
2140  break;
2141  case ERR_NONE:
2142  break;
2143  default:
2144  return error;
2145  }
2146  Date.Year = date_time.Year;
2147  Date.Hour = 23;
2148  Date.Minute = 59;
2149  } else {
2150  Date.Year += 20;
2151  }
2152  t_time2 = Fill_Time_T(Date);
2153  t_time1 = Fill_Time_T(Note->Entries[Alarm].Date);
2154  diff = t_time1-t_time2;
2155 
2156  /* Sometimes we have difference in minutes */
2157  if (NoteType == GSM_CAL_MEETING) diff = diff / 60;
2159  if (NoteType == GSM_CAL_MEMO || NoteType == GSM_CAL_CALL) {
2160  diff = diff / 60;
2161  }
2162  }
2163 
2164  smprintf(s, " Difference : %li seconds or minutes\n", -diff);
2165  req[13] = (unsigned char)(-diff >> 24);
2166  req[14] = (unsigned char)(-diff >> 16);
2167  req[15] = (unsigned char)(-diff >> 8);
2168  req[16] = (unsigned char)(-diff);
2169  }
2170 
2171  GSM_SetCalendarRecurranceRepeat(&(s->di), req+19, NULL, Note);
2172 
2173  if (Text != -1) {
2174  switch (NoteType) {
2175  case GSM_CAL_CALL:
2176  req[26] = UnicodeLength(Note->Entries[Text].Text);
2177  break;
2178  default:
2179  req[length++] = UnicodeLength(Note->Entries[Text].Text);
2180  if (NoteType == GSM_CAL_MEMO || NoteType == GSM_CAL_MEETING) req[length++] = 0x00;
2181  }
2182  CopyUnicodeString(req+length,Note->Entries[Text].Text);
2183  length += UnicodeLength(Note->Entries[Text].Text)*2;
2184  }
2185 
2186  req[length++] = 0x00;
2187  req[length++] = 0x00;
2188 
2189  req[4] = req[17] = length-7;
2190 
2191  smprintf(s, "Writing calendar note method 2\n");
2192  return GSM_WaitFor (s, req, length, 0x13, 4, ID_SetCalendarNote);
2193 }
2194 
2195 /* method 1*/
2197 {
2198  smprintf(s, "First calendar location: %i\n",msg->Buffer[4]*256+msg->Buffer[5]);
2199  *FirstCalendarPos = msg->Buffer[4]*256+msg->Buffer[5];
2200  return ERR_NONE;
2201 }
2202 
2203 /* method 1*/
2204 static GSM_Error N71_65_GetCalendarNotePos1(GSM_StateMachine *s)
2205 {
2206  unsigned char req[] = {N6110_FRAME_HEADER, 0x31};
2207 
2208  smprintf(s, "Getting first free calendar note location\n");
2209  return GSM_WaitFor (s, req, 4, 0x13, 4, ID_GetCalendarNotePos);
2210 }
2211 
2212 /* method 1 */
2214 {
2215 #ifdef DEBUG
2216  smprintf(s, "Written calendar note type ");
2217  switch ((msg->Buffer[3]/2)-1) {
2218  case 0: smprintf(s, "Meeting"); break;
2219  case 1: smprintf(s, "Call"); break;
2220  case 2: smprintf(s, "Birthday");break;
2221  case 3: smprintf(s, "Reminder");break;
2222  }
2223  smprintf(s, " on location %d\n",msg->Buffer[4]*256+msg->Buffer[5]);
2224 #endif
2225  return ERR_NONE;
2226 }
2227 
2228 /* method 1 */
2229 GSM_Error N71_65_AddCalendar1(GSM_StateMachine *s, GSM_CalendarEntry *Note, int *FirstCalendarPos)
2230 {
2231  long seconds;
2232  GSM_Error error;
2233  GSM_DateTime DT;
2234  int Text, Time, Alarm, Phone, EndTime, Location, count=12;
2235  unsigned char req[5000] = {
2237  0x01, /* note type */
2238  0x00, 0x00, /* location ? */
2239  0x00, /* entry type */
2240  0x00,
2241  0x00, 0x00, /* Year */
2242  0x00, /* Month */
2243  0x00, /* Day */
2244  0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2245 
2246  error=N71_65_GetCalendarNotePos1(s);
2247  if (error!=ERR_NONE) return error;
2248  if (FirstCalendarPos != NULL) {
2249  Note->Location = *FirstCalendarPos;
2250  req[4] = *FirstCalendarPos/256;
2251  req[5] = *FirstCalendarPos%256;
2252  }
2253 
2254  switch(Note->Type) {
2255  case GSM_CAL_CALL : req[3]=0x03; req[6]=0x02; break;
2256  case GSM_CAL_BIRTHDAY: req[3]=0x05; req[6]=0x04; break;
2257  case GSM_CAL_MEMO : req[3]=0x07; req[6]=0x08; break;
2258  case GSM_CAL_MEETING :
2259  default : req[3]=0x01; req[6]=0x01; break;
2260  }
2261 
2262  GSM_CalendarFindDefaultTextTimeAlarmPhone(Note, &Text, &Time, &Alarm, &Phone, &EndTime, &Location);
2263 
2264  if (Time == -1) {
2265  smprintf(s, "Can not save entry without time!\n");
2266  return ERR_UNKNOWN;
2267  }
2268  memcpy(&DT,&Note->Entries[Time].Date,sizeof(GSM_DateTime));
2269  req[8] = DT.Year / 256;
2270  req[9] = DT.Year % 256;
2271  req[10] = DT.Month;
2272  req[11] = DT.Day;
2273 
2274  switch(Note->Type) {
2275  case GSM_CAL_BIRTHDAY:
2276  /* byte 12 and 13 */
2277  req[count++] = 0x00;
2278  req[count++] = 0x00;
2279 
2280  /* Alarm - bytes 14 to 17 */
2281  req[count++] = 0x00;
2282  req[count++] = 0x00;
2283  req[count++] = 0xff;
2284  req[count++] = 0xff;
2285  if (Alarm != -1) {
2286  /* Comment from original source by Gabriele Zappi:
2287  * I try with Time.Year = Alarm.Year. If negative, I increase 1 year,
2288  * but only once ! This thing, because I may have Alarm period across
2289  * a year. (eg. Birthday on 2001-01-10 and Alarm on 2000-12-27)
2290  */
2291  DT.Year = Note->Entries[Alarm].Date.Year;
2292  seconds = Fill_Time_T(DT)-Fill_Time_T(Note->Entries[Alarm].Date);
2293  if (seconds<0L) {
2294  DT.Year++;
2295  seconds = Fill_Time_T(DT)-Fill_Time_T(Note->Entries[Alarm].Date);
2296  }
2297  if (seconds>=0L) {
2298  count -= 4;
2299  /* bytes 14 to 17 */
2300  req[count++] = (unsigned char)(seconds>>24);
2301  req[count++] = (unsigned char)((seconds>>16) & 0xff);
2302  req[count++] = (unsigned char)((seconds>>8) & 0xff);
2303  req[count++] = (unsigned char)(seconds & 0xff);
2304  }
2305  /* byte 18 */
2306  if (Note->Entries[Alarm].EntryType == CAL_SILENT_ALARM_DATETIME) req[count++] = 0x01; else req[count++] = 0x00;
2307  }
2308 
2309  /* byte 19 and next */
2310  if (Text != -1) {
2311  req[count++] = UnicodeLength(Note->Entries[Text].Text);
2312  CopyUnicodeString(req+count,Note->Entries[Text].Text);
2313  count=count+2*UnicodeLength(Note->Entries[Text].Text);
2314  } else {
2315  req[count++] = 0x00;
2316  }
2317  break;
2318  case GSM_CAL_MEMO:
2319  /* byte 12 and 13 */
2320  GSM_SetCalendarRecurranceRepeat(&(s->di), req+count, NULL, Note);
2321  count+=2;
2322 
2323  /* byte 14 and next */
2324  if (Text != -1) {
2325  req[count++] = UnicodeLength(Note->Entries[Text].Text);
2326  req[count++] = 0x00;
2327  CopyUnicodeString(req+count,Note->Entries[Text].Text);
2328  count=count+2*UnicodeLength(Note->Entries[Text].Text);
2329  } else {
2330  req[count++] = 0x00;
2331  req[count++] = 0x00;
2332  }
2333  break;
2334  case GSM_CAL_MEETING:
2335  case GSM_CAL_CALL:
2336  default:
2337  /* byte 12 and 13 */
2338  req[count++] = DT.Hour;
2339  req[count++] = DT.Minute;
2340 
2341  /* Alarm - byte 14 and 15 */
2342  req[count++] = 0xff;
2343  req[count++] = 0xff;
2344  if (Alarm != -1) {
2345  seconds=Fill_Time_T(DT)-Fill_Time_T(Note->Entries[Alarm].Date);
2346  if (seconds>=0L) {
2347  count -= 2;
2348  req[count++] = (unsigned char)((seconds/60L)>>8);
2349  req[count++] = (unsigned char)((seconds/60L)&0xff);
2350  }
2351  }
2352 
2353  /* byte 16 and 17 */
2354  GSM_SetCalendarRecurranceRepeat(&(s->di), req+count, NULL, Note);
2355  count+=2;
2356 
2357  /* byte 18 */
2358  if (Text != -1) {
2359  req[count++] = UnicodeLength(Note->Entries[Text].Text);
2360  } else {
2361  req[count++] = 0x00;
2362  }
2363  /* byte 19 */
2364  if (Note->Type == GSM_CAL_CALL && Phone != -1) {
2365  req[count++] = UnicodeLength(Note->Entries[Phone].Text);
2366  } else {
2367  req[count++] = 0x00;
2368  }
2369  if (Text != -1) {
2370  CopyUnicodeString(req+count,Note->Entries[Text].Text);
2371  count=count+2*UnicodeLength(Note->Entries[Text].Text);
2372  }
2373  if (Note->Type == GSM_CAL_CALL && Phone != -1) {
2374  CopyUnicodeString(req+count,Note->Entries[Phone].Text);
2375  count=count+2*UnicodeLength(Note->Entries[Phone].Text);
2376  }
2377  break;
2378  }
2379  req[count] = 0x00;
2380  smprintf(s, "Writing calendar note method 1\n");
2381  return GSM_WaitFor (s, req, count, 0x13, 4, ID_SetCalendarNote);
2382 }
2383 
2385 {
2386  if (msg->Buffer[3] == 0xf0) return ERR_NOTSUPPORTED;
2387 
2388  smprintf(s, "Deleted calendar note on location %d\n",msg->Buffer[4]*256+msg->Buffer[5]);
2389  return ERR_NONE;
2390 }
2391 
2393 {
2394  unsigned char req[] = {N6110_FRAME_HEADER, 0x0b,
2395  0x00, 0x00}; /* location */
2396 
2397  req[4] = Note->Location / 256;
2398  req[5] = Note->Location % 256;
2399 
2400  smprintf(s, "Deleting calendar note\n");
2401  return GSM_WaitFor (s, req, 6, 0x13, 4, ID_DeleteCalendarNote);
2402 }
2403 
2404 /* method 1 */
2406 {
2407  size_t i,j=0;
2408 
2409  smprintf(s, "Info with calendar notes locations received method 1\n");
2410  while (LastCalendar->Location[j] != 0x00) j++;
2411  if (j >= GSM_MAXCALENDARTODONOTES) {
2412  smprintf(s, "Increase GSM_MAXCALENDARNOTES\n");
2413  return ERR_MOREMEMORY;
2414  }
2415  if (j == 0) {
2416  LastCalendar->Number=msg->Buffer[4]*256+msg->Buffer[5];
2417  smprintf(s, "Number of Entries: %i\n",LastCalendar->Number);
2418  }
2419  smprintf(s, "Locations: ");
2420  i = 0;
2421  while (9+(i*2) <= msg->Length) {
2422  LastCalendar->Location[j++]=msg->Buffer[8+(i*2)]*256+msg->Buffer[9+(i*2)];
2423  smprintf(s, "%i ",LastCalendar->Location[j-1]);
2424  i++;
2425  }
2426  smprintf(s, "\nNumber of Entries in frame: %ld\n", (long)i);
2427  smprintf(s, "\n");
2428  LastCalendar->Location[j] = 0;
2429  if (i == 1 && msg->Buffer[8+(0*2)]*256+msg->Buffer[9+(0*2)] == 0) return ERR_EMPTY;
2430  if (i == 0) return ERR_EMPTY;
2431  return ERR_NONE;
2432 }
2433 
2434 /* method 1 */
2436 {
2437  GSM_Error error;
2438  int i;
2439  unsigned char req[] = {N6110_FRAME_HEADER, 0x3a,
2440  0xFF, 0xFE}; /* First location number */
2441 
2442  LastCalendar->Location[0] = 0x00;
2443  LastCalendar->Number = 0;
2444 
2445  smprintf(s, "Getting locations for calendar method 1\n");
2446  error = GSM_WaitFor (s, req, 6, 0x13, 4, ID_GetCalendarNotesInfo);
2447  if (error != ERR_NONE && error != ERR_EMPTY) return error;
2448 
2449  while (1) {
2450  i=0;
2451  while (LastCalendar->Location[i] != 0x00) i++;
2452  if (i == LastCalendar->Number) break;
2453  if (i != LastCalendar->Number && error == ERR_EMPTY) {
2454  smprintf(s, "Phone doesn't support some notes with this method. Workaround\n");
2455  LastCalendar->Number = i;
2456  break;
2457  }
2458  smprintf(s, "i = %i %i\n",i,LastCalendar->Number);
2459  req[4] = LastCalendar->Location[i-1] / 256;
2460  req[5] = LastCalendar->Location[i-1] % 256;
2461  smprintf(s, "Getting locations for calendar\n");
2462  error = GSM_WaitFor (s, req, 6, 0x13, 4, ID_GetCalendarNotesInfo);
2463  if (error != ERR_NONE && error != ERR_EMPTY) return error;
2464  }
2465  return ERR_NONE;
2466 }
2467 
2468 /* method 1 */
2470 {
2471  int timedelta,i;
2472  GSM_CalendarEntry *entry = s->Phone.Data.Cal;
2473 
2474  smprintf(s, "Calendar note received method 1\n");
2475 
2476  /* Later these values can change */
2477  if (msg->Buffer[6]!=0x04) { /* Here not birthday */
2478  entry->Entries[0].Date.Year = msg->Buffer[8]*256+msg->Buffer[9];
2479  }
2480  entry->Entries[0].Date.Month = msg->Buffer[10];
2481  entry->Entries[0].Date.Day = msg->Buffer[11];
2482  entry->Entries[0].Date.Hour = msg->Buffer[12];
2483  entry->Entries[0].Date.Minute = msg->Buffer[13];
2484  entry->Entries[0].Date.Second = 0;
2485  entry->Entries[0].EntryType = CAL_START_DATETIME;
2486  entry->EntriesNum++;
2487 
2488  switch (msg->Buffer[6]) {
2489  case 0x01:
2490  smprintf(s, "Meeting\n");
2491  entry->Type = GSM_CAL_MEETING;
2492 
2493  timedelta=msg->Buffer[14]*256+msg->Buffer[15];
2494  if (timedelta != 0xffff) {
2495  smprintf(s, " Difference : %i seconds\n", timedelta);
2496  memcpy(&entry->Entries[1].Date,&entry->Entries[0].Date,sizeof(GSM_DateTime));
2497  GetTimeDifference(timedelta, &entry->Entries[1].Date, FALSE, 60);
2499  entry->EntriesNum++;
2500  }
2501  GSM_GetCalendarRecurranceRepeat(&(s->di), msg->Buffer + 16, NULL, entry);
2502 
2503  memcpy(entry->Entries[entry->EntriesNum].Text, msg->Buffer+20, msg->Buffer[18]*2);
2504  entry->Entries[entry->EntriesNum].Text[msg->Buffer[18]*2] = 0;
2505  entry->Entries[entry->EntriesNum].Text[msg->Buffer[18]*2+1] = 0;
2506  entry->Entries[entry->EntriesNum].EntryType = CAL_TEXT;
2507  smprintf(s, "Text : \"%s\"\n", DecodeUnicodeString(entry->Entries[entry->EntriesNum].Text));
2508  entry->EntriesNum++;
2509  return ERR_NONE;
2510  case 0x02:
2511  smprintf(s, "Call\n");
2512  entry->Type = GSM_CAL_CALL;
2513 
2514  timedelta=msg->Buffer[14]*256+msg->Buffer[15];
2515  if (timedelta != 0xffff) {
2516  smprintf(s, " Difference : %i seconds\n", timedelta);
2517  memcpy(&entry->Entries[1].Date,&entry->Entries[0].Date,sizeof(GSM_DateTime));
2518  GetTimeDifference(timedelta, &entry->Entries[1].Date, FALSE, 60);
2520  entry->EntriesNum++;
2521  }
2522  GSM_GetCalendarRecurranceRepeat(&(s->di), msg->Buffer + 16, NULL, entry);
2523 
2524  i = msg->Buffer[18] * 2;
2525  if (i!=0) {
2526  memcpy(entry->Entries[entry->EntriesNum].Text, msg->Buffer+20, i);
2527  entry->Entries[entry->EntriesNum].Text[i] = 0;
2528  entry->Entries[entry->EntriesNum].Text[i+1] = 0;
2529  entry->Entries[entry->EntriesNum].EntryType = CAL_TEXT;
2530  smprintf(s, "Text : \"%s\"\n", DecodeUnicodeString(entry->Entries[entry->EntriesNum].Text));
2531  entry->EntriesNum++;
2532  }
2533 
2534  memcpy(entry->Entries[entry->EntriesNum].Text, msg->Buffer+20+i, msg->Buffer[19]*2);
2535  entry->Entries[entry->EntriesNum].Text[msg->Buffer[19]*2] = 0;
2536  entry->Entries[entry->EntriesNum].Text[msg->Buffer[19]*2+1] = 0;
2537  entry->Entries[entry->EntriesNum].EntryType = CAL_PHONE;
2538  smprintf(s, "Phone : \"%s\"\n", DecodeUnicodeString(entry->Entries[entry->EntriesNum].Text));
2539  entry->EntriesNum++;
2540  return ERR_NONE;
2541  case 0x04:
2542  smprintf(s, "Birthday\n");
2543  entry->Type = GSM_CAL_BIRTHDAY;
2544 
2545  entry->Entries[0].Date.Hour = 23;
2546  entry->Entries[0].Date.Minute = 59;
2547  entry->Entries[0].Date.Second = 58;
2548 
2549  timedelta = ((unsigned int)msg->Buffer[14]) << 24;
2550  timedelta += ((unsigned int)msg->Buffer[15]) << 16;
2551  timedelta += ((unsigned int)msg->Buffer[16]) << 8;
2552  timedelta += msg->Buffer[17];
2553  if (timedelta != 0xffff) {
2554  smprintf(s, " Difference : %i seconds\n", timedelta);
2555  memcpy(&entry->Entries[1].Date,&entry->Entries[0].Date,sizeof(GSM_DateTime));
2556  GetTimeDifference(timedelta, &entry->Entries[1].Date, FALSE, 1);
2558  if (msg->Buffer[20]!=0x00) {
2560  smprintf(s, "Alarm type : Silent\n");
2561  }
2562  entry->EntriesNum++;
2563  }
2564 
2565  entry->Entries[0].Date.Year = msg->Buffer[18]*256 + msg->Buffer[19];
2566  if (entry->Entries[0].Date.Year == 65535) entry->Entries[0].Date.Year = 0;
2567  smprintf(s, "Age : %i\n",entry->Entries[0].Date.Year);
2568 
2569  memcpy(entry->Entries[entry->EntriesNum].Text, msg->Buffer+22, msg->Buffer[21]*2);
2570  entry->Entries[entry->EntriesNum].Text[msg->Buffer[21]*2] = 0;
2571  entry->Entries[entry->EntriesNum].Text[msg->Buffer[21]*2+1] = 0;
2572  entry->Entries[entry->EntriesNum].EntryType = CAL_TEXT;
2573  smprintf(s, "Text : \"%s\"\n", DecodeUnicodeString(entry->Entries[entry->EntriesNum].Text));
2574  entry->EntriesNum++;
2575 
2577  entry->Entries[entry->EntriesNum].Number = 1;
2578  entry->EntriesNum++;
2579  entry->Entries[entry->EntriesNum].EntryType = CAL_REPEAT_DAY;
2580  entry->Entries[entry->EntriesNum].Number = entry->Entries[0].Date.Day;
2581  entry->EntriesNum++;
2582  entry->Entries[entry->EntriesNum].EntryType = CAL_REPEAT_MONTH;
2583  entry->Entries[entry->EntriesNum].Number = entry->Entries[0].Date.Month;
2584  entry->EntriesNum++;
2585 
2586  return ERR_NONE;
2587  case 0x08:
2588  smprintf(s, "Memo\n");
2589  entry->Type = GSM_CAL_MEMO;
2590 
2591  entry->Entries[0].Date.Hour = 0;
2592  entry->Entries[0].Date.Minute = 0;
2593 
2594  GSM_GetCalendarRecurranceRepeat(&(s->di), msg->Buffer + 12, NULL, entry);
2595 
2596  memcpy(entry->Entries[entry->EntriesNum].Text, msg->Buffer+16, msg->Buffer[14]*2);
2597  entry->Entries[entry->EntriesNum].Text[msg->Buffer[14]*2] = 0;
2598  entry->Entries[entry->EntriesNum].Text[msg->Buffer[14]*2+1] = 0;
2599  entry->Entries[entry->EntriesNum].EntryType = CAL_TEXT;
2600  smprintf(s, "Text : \"%s\"\n", DecodeUnicodeString(entry->Entries[entry->EntriesNum].Text));
2601  entry->EntriesNum++;
2602  return ERR_NONE;
2603  default:
2604  smprintf(s, "ERROR: unknown %i\n",msg->Buffer[6]);
2605  return ERR_UNKNOWNRESPONSE;
2606  }
2607 }
2608 
2609 /* method 1 */
2610 GSM_Error N71_65_GetNextCalendar1(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start, GSM_NOKIACalToDoLocations *LastCalendar, int *LastCalendarYear, int *LastCalendarPos)
2611 {
2612  GSM_Error error;
2613  GSM_DateTime date_time;
2614  unsigned char req[] = {N6110_FRAME_HEADER, 0x19,
2615  0x00, 0x00}; /* Location */
2616 
2617  if (start) {
2618  error=N71_65_GetCalendarInfo1(s, LastCalendar);
2619  if (error!=ERR_NONE) return error;
2620  if (LastCalendar->Number == 0) return ERR_EMPTY;
2621 
2622  /* We have to get current year. It's NOT written in frame for
2623  * Birthday
2624  */
2625  error=s->Phone.Functions->GetDateTime(s,&date_time);
2626  switch (error) {
2627  case ERR_EMPTY:
2628  case ERR_NOTIMPLEMENTED:
2629  GSM_GetCurrentDateTime(&date_time);
2630  break;
2631  case ERR_NONE:
2632  break;
2633  default:
2634  return error;
2635  }
2636  *LastCalendarYear = date_time.Year;
2637  *LastCalendarPos = 0;
2638  } else {
2639  (*LastCalendarPos)++;
2640  }
2641 
2642  if (*LastCalendarPos >= LastCalendar->Number) return ERR_EMPTY;
2643 
2644  req[4] = LastCalendar->Location[*LastCalendarPos] / 256;
2645  req[5] = LastCalendar->Location[*LastCalendarPos] % 256;
2646 
2647  Note->EntriesNum = 0;
2648  Note->Entries[0].Date.Year = *LastCalendarYear;
2649  Note->Location = LastCalendar->Location[*LastCalendarPos];
2650 
2651  s->Phone.Data.Cal=Note;
2652  smprintf(s, "Getting calendar note method 1\n");
2653  return GSM_WaitFor (s, req, 6, 0x13, 4, ID_GetCalendarNote);
2654 }
2655 
2656 GSM_Error N71_65_EnableFunctions(GSM_StateMachine *s,const char *buff,int len)
2657 {
2658  unsigned char buffer[50] = {N6110_FRAME_HEADER, 0x10,
2659  0x07}; /* Length */
2660 
2661  buffer[4] = len;
2662  memcpy(buffer+5,buff,len);
2663 
2664  /* Enables various things like incoming SMS, call info, etc. */
2665  return s->Protocol.Functions->WriteMessage(s, buffer, 5+len, 0x10);
2666 }
2667 
2669 {
2670  switch (msg->Buffer[3]) {
2671  case 0xf0:
2672  return ERR_NOTSUPPORTED;
2673  case 0x51:
2674  smprintf(s, "DTMF sent OK\n");
2675  return ERR_NONE;
2676  case 0x59:
2677  case 0x5E:
2678  smprintf(s, "meaning unknown - during sending DTMF\n");
2679  return ERR_NONE;
2680  }
2681  return ERR_UNKNOWNRESPONSE;
2682 }
2683 
2685 {
2686  switch (Type) {
2687  case GSM_CAL_CALL:
2688  return GSM_CAL_CALL;
2689  case GSM_CAL_BIRTHDAY:
2690  return GSM_CAL_BIRTHDAY;
2691  case GSM_CAL_MEETING:
2692  if (GSM_IsPhoneFeatureAvailable(model, F_CAL35)) {
2693  return GSM_CAL_REMINDER;
2694  } else return GSM_CAL_MEETING;
2695  case GSM_CAL_MEMO:
2696  if (GSM_IsPhoneFeatureAvailable(model, F_CAL35)) {
2697  return GSM_CAL_REMINDER;
2698  } else return GSM_CAL_MEMO;
2699  case GSM_CAL_REMINDER:
2700  if (GSM_IsPhoneFeatureAvailable(model, F_CAL62) ||
2702  return GSM_CAL_CALL;
2703  } else return GSM_CAL_REMINDER;
2704  default:
2705  return GSM_CAL_CALL;
2706  }
2707 }
2708 
2709 #endif
2710 
2711 /* How should editor hadle tabs in this file? Add editor commands here.
2712  * vim: noexpandtab sw=8 ts=8 sts=8:
2713  */
GSM_Profile_Feat_Value
gboolean EnableIncomingUSSD
Definition: gsmstate.h:671
GSM_Error DCT3DCT4_ReplyGetActiveConnectSet(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error N71_65_ReplyDelCalendar(GSM_Protocol_Message *msg, GSM_StateMachine *s)
gboolean DefaultRingtone
Definition: gammu-bitmap.h:134
GSM_Profile_Feat_ID FeatureID[15]
IncomingUSSDCallback IncomingUSSD
Definition: gsmstate.h:1384
char * DecodeUnicodeString(const unsigned char *src)
Definition: coding.c:245
void DumpMessage(GSM_Debug_Info *d, const unsigned char *message, const size_t messagesize)
Definition: debug.c:314
GSM_Profile_Feat_Value Value
GSM_Error DCT3DCT4_GetModel(GSM_StateMachine *s)
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_CallStatus Status
Definition: gammu-call.h:86
GSM_Error N71_65_AddCalendar1(GSM_StateMachine *s, GSM_CalendarEntry *Note, int *FirstCalendarPos)
void * IncomingCallUserData
Definition: gsmstate.h:1386
void NOKIA_SortSMSFolderStatus(GSM_StateMachine *s, GSM_NOKIASMSFolder *Folder)
GSM_Error NOKIA_SetIncomingUSSD(GSM_StateMachine *s, gboolean enable)
GSM_SMS_State State
GSM_MemoryType MemoryType
Definition: gammu-memory.h:415
void * IncomingUSSDUserData
Definition: gsmstate.h:1389
#define GSM_PHONEBOOK_TEXT_LENGTH
Definition: gammu-limits.h:91
GSM_EntryLocation
Definition: gammu-memory.h:348
int StartPhoneString
Definition: gsmstate.h:634
gboolean FileSystemRingtone
Definition: gammu-bitmap.h:139
void FreeLines(GSM_CutLines *lines)
Definition: misc.c:392
GSM_Error DCT3DCT4_GetWAPBookmarkPart(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
int GSM_PackSemiOctetNumber(const unsigned char *Number, unsigned char *Output, gboolean semioctet)
Definition: coding.c:1125
void GetTimeDifference(unsigned long diff, GSM_DateTime *DT, gboolean Plus, int multi)
Definition: misc.c:247
GSM_MemoryEntry * Memory
Definition: gsmstate.h:497
#define N6110_FRAME_HEADER
Definition: ncommon.h:8
GSM_MemoryType NOKIA_GetMemoryType(GSM_StateMachine *s, GSM_MemoryType memory_type, unsigned char *ID)
GSM_Debug_Info * GSM_GetDI(GSM_StateMachine *s)
Definition: gsmstate.c:70
#define GSM_PHONEBOOK_ENTRIES
Definition: gammu-limits.h:98
char VerDate[GSM_MAX_VERSION_DATE_LENGTH+1]
Definition: gsmstate.h:458
GSM_Error N71_65_DelCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
GSM_Error N71_65_GetCalendarInfo1(GSM_StateMachine *s, GSM_NOKIACalToDoLocations *LastCalendar)
void NOKIA_EncodeDateTime(GSM_StateMachine *s UNUSED, unsigned char *buffer, GSM_DateTime *datetime)
Definition: nfunc.c:1007
GSM_Error
Definition: gammu-error.h:23
const char * GetLineString(const char *message, GSM_CutLines *lines, int start)
Definition: misc.c:492
GSM_Error DCT3DCT4_ReplyEnableConnectFunc(GSM_Protocol_Message *msg, GSM_StateMachine *s)
gboolean FileSystemPicture
Definition: gammu-bitmap.h:144
void NOKIA_FindFeatureValue(GSM_StateMachine *s, GSM_Profile_PhoneTableValue ProfileTable[], unsigned char ID, unsigned char Value, GSM_Phone_Data *Data, gboolean CallerGroups)
GSM_Debug_Info di
Definition: gsmstate.h:1412
GSM_Error DCT3DCT4_ReplyDisableConnectFunc(GSM_Protocol_Message *msg, GSM_StateMachine *s)
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 N71_65_ReplyGetCalendarNotePos1(GSM_Protocol_Message *msg, GSM_StateMachine *s, int *FirstCalendarPos)
gboolean EnableIncomingCall
Definition: gsmstate.h:659
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 GSM_SetCalendarRecurranceRepeat(GSM_Debug_Info *di, unsigned char *rec, unsigned char *endday, GSM_CalendarEntry *entry)
Definition: gsmcal.c:31
GSM_CalendarNoteType N71_65_FindCalendarType(GSM_CalendarNoteType Type, GSM_PhoneModel *model)
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
char Version[GSM_MAX_VERSION_LENGTH+1]
Definition: gsmstate.h:454
GSM_Error NOKIA_SetIncomingCall(GSM_StateMachine *s, gboolean enable)
unsigned int Timeout
Definition: gammu-call.h:170
int Location[GSM_MAXCALENDARTODONOTES+1]
Definition: ncommon.h:92
char Name[40 *2]
GSM_Profile_PhoneTableValue Profile71_65[]
char Manufacturer[GSM_MAX_MANUFACTURER_LENGTH+1]
Definition: gsmstate.h:441
GSM_PhoneModel * ModelInfo
Definition: gsmstate.h:449
int smprintf_level(GSM_StateMachine *s, GSM_DebugSeverity severity, const char *format,...)
Definition: debug.c:278
GSM_EntryType EntryType
Definition: gammu-memory.h:372
static gboolean N71_65_PB_CopyString(GSM_StateMachine *s, GSM_MemoryEntry *entry, const unsigned char *src, unsigned char length)
Definition: nfunc.c:336
GSM_Error NOKIA_GetPhoneString(GSM_StateMachine *s, const unsigned char *msgframe, int msglen, unsigned char msgtype, char *retvalue, GSM_Phone_RequestID request, int startresponse)
GSM_Error DCT3DCT4_SetActiveConnectSet(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
void GSM_GetCalendarRecurranceRepeat(GSM_Debug_Info *di, unsigned char *rec, unsigned char *endday, GSM_CalendarEntry *entry)
Definition: gsmcal.c:137
unsigned char RingtoneID
Definition: gammu-bitmap.h:138
void GSM_CalendarFindDefaultTextTimeAlarmPhone(GSM_CalendarEntry *entry, int *Text, int *Time, int *Alarm, int *Phone, int *EndTime, int *Location)
Definition: gsmcal.c:279
GSM_Error DCT3DCT4_GetFirmware(GSM_StateMachine *s)
GSM_Error DCT3DCT4_ReplySetActiveConnectSet(GSM_Protocol_Message *msg, GSM_StateMachine *s)
int StatusCode
Definition: gammu-call.h:98
unsigned char Text[(GSM_PHONEBOOK_TEXT_LENGTH+1) *2]
Definition: gammu-memory.h:399
int gboolean
Definition: gammu-types.h:23
GSM_MemoryType
Definition: gammu-memory.h:31
GSM_CalendarNoteType Type
GSM_PhoneModel * GetModelData(GSM_StateMachine *s, const char *model, const char *number, const char *irdamodel)
Definition: gsmphones.c:1002
GSM_Error DCT3DCT4_SetCallDivert(GSM_StateMachine *s, GSM_CallDivert *divert)
void InitLines(GSM_CutLines *lines)
Definition: misc.c:385
void EncodeUnicode(unsigned char *dest, const char *src, size_t len)
Definition: coding.c:301
GSM_Error DCT3DCT4_CancelCall(GSM_StateMachine *s, int ID)
GSM_Phone Phone
Definition: gsmstate.h:1431
#define FALSE
Definition: gammu-types.h:25
GSM_Error DCT3DCT4_DeleteWAPBookmarkPart(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
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
unsigned int Location[GSM_PHONE_MAXSMSINFOLDER+1]
Definition: ncommon.h:87
GSM_Profile_Feat_ID ID
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)
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 DCT3DCT4_DisableConnectionFunctions(GSM_StateMachine *s)
GSM_MultiWAPSettings * WAPSettings
Definition: gsmstate.h:569
void NOKIA_GetDefaultCallerGroupName(GSM_Bitmap *Bitmap)
Definition: nfunc.c:956
unsigned char N71_65_MEMORY_TYPES[]
Definition: nfunc.c:21
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 Number[(GSM_MAX_NUMBER_LENGTH+1) *2]
Definition: gammu-call.h:174
#define GSM_MAXCALENDARTODONOTES
Definition: gammu-limits.h:84
int NOKIA_SetUnicodeString(GSM_StateMachine *s, unsigned char *dest, unsigned char *string, gboolean FullLength)
unsigned char Text[2 *(GSM_MAX_USSD_LENGTH+1)]
GSM_WAPBookmark * WAPBookmark
Definition: gsmstate.h:565
GSM_Divert_CallTypes CallType
Definition: gammu-call.h:166
GSM_Phone_RequestID RequestID
Definition: gsmstate.h:685
GSM_Error N71_65_GetNextCalendar1(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start, GSM_NOKIACalToDoLocations *LastCalendar, int *LastCalendarYear, int *LastCalendarPos)
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)
gboolean BitmapEnabled
Definition: gammu-bitmap.h:122
GSM_Profile_Feat_Value FeatureValue[15]
GSM_CalendarType EntryType
GSM_Error N71_65_ReplyAddCalendar2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
IncomingCallCallback IncomingCall
Definition: gsmstate.h:1381
GSM_MultiCallDivert * Divert
Definition: gsmstate.h:581
GSM_Error DCT3DCT4_ReplyDelWAPBookmark(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Divert_DivertTypes DivertType
Definition: gammu-call.h:162
GSM_MemoryType MemoryType
Definition: gammu-memory.h:447
GSM_Protocol Protocol
Definition: gsmstate.h:1430
GSM_CalendarNoteType
GSM_CallDivert Entries[GSM_MAX_CALL_DIVERTS]
Definition: gammu-call.h:184
unsigned char PhoneNumber[(GSM_MAX_NUMBER_LENGTH+1) *2]
Definition: gammu-call.h:102
gboolean DefaultBitmap
Definition: gammu-bitmap.h:130
GSM_DateTime Date
Definition: gammu-memory.h:380
GSM_Error DCT3DCT4_CancelAllDiverts(GSM_StateMachine *s)
gboolean mywstrncmp(unsigned const char *a, unsigned const char *b, int num)
Definition: coding.c:1457
gboolean CallerGroups[5]
GSM_Error(* GetDateTime)(GSM_StateMachine *s, GSM_DateTime *date_time)
Definition: gsmstate.h:814
int CallID
Definition: gammu-call.h:90
gboolean CallIDAvailable
Definition: gammu-call.h:94
GSM_Error DCT3DCT4_ReplySetWAPBookmark(GSM_Protocol_Message *msg, GSM_StateMachine *s)
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 N71_65_ReplyGetCalendarInfo1(GSM_Protocol_Message *msg, GSM_StateMachine *s, GSM_NOKIACalToDoLocations *LastCalendar)
GSM_Phone_Data Data
Definition: gsmstate.h:1369
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_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
GSM_Error N71_65_EnableFunctions(GSM_StateMachine *s, const char *buff, int len)
GSM_Error DCT3DCT4_ReplyGetModelFirmware(GSM_Protocol_Message *msg, GSM_StateMachine *s)
void GSM_GetCurrentDateTime(GSM_DateTime *Date)
Definition: misc.c:184
GSM_Error N71_65_ReplyUSSDInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
time_t Fill_Time_T(GSM_DateTime DT)
Definition: misc.c:189
gboolean GSM_IsPhoneFeatureAvailable(GSM_PhoneModel *model, GSM_Feature feature)
Definition: gsmphones.c:1026
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
Definition: debug.h:87
gboolean DefaultName
Definition: gammu-bitmap.h:126
GSM_Error NOKIA_ReplyGetPhoneString(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_EntryLocation Location
Definition: gammu-memory.h:376
void GSM_CreateFirmwareNumber(GSM_StateMachine *s)
Definition: pfunc.c:52
#define MIN(a, b)
Definition: gammu-misc.h:70
#define _(x)
Definition: locales.h:21
gboolean DefaultName
GSM_Error N71_65_AddCalendar2(GSM_StateMachine *s, GSM_CalendarEntry *Note)
unsigned char Text[2 *(GSM_BITMAP_TEXT_LENGTH+1)]
Definition: gammu-bitmap.h:118
GSM_Error N71_65_ReplyGetMemoryError(unsigned char error, GSM_StateMachine *s)
GSM_Protocol_Functions * Functions
Definition: gsmstate.h:424
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
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_Profile * Profile
Definition: gsmstate.h:605
GSM_Error DCT3DCT4_ReplyGetWAPBookmark(GSM_Protocol_Message *msg, GSM_StateMachine *s, gboolean FullLength)
gboolean EnableIncomingSMS
Definition: gsmstate.h:663
unsigned char * Buffer
Definition: protocol.h:22
void SplitLines(const char *message, const size_t messagesize, GSM_CutLines *lines, const char *whitespaces, const size_t spaceslen, const char *quotes, const size_t quoteslen, const gboolean eot)
Definition: misc.c:401
#define UNUSED
Definition: gammu-misc.h:105
GSM_Profile_Feat_ID
GSM_EntryType
Definition: gammu-memory.h:144
GSM_Error DCT3DCT4_AnswerCall(GSM_StateMachine *s, int ID)
GSM_Phone_RequestID
Definition: gsmreply.h:25
gboolean CheckDate(GSM_DateTime *date)
Definition: misc.c:349
char Model[GSM_MAX_MODEL_LENGTH+1]
Definition: gsmstate.h:445
Debug_Level dl
Definition: debug.h:35
GSM_Error N71_65_ReplySendDTMF(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_USSDStatus Status
unsigned char * PhoneString
Definition: gsmstate.h:629
unsigned char Text[(GSM_MAX_CALENDAR_TEXT_LENGTH+1) *2]
void NOKIA_GetDefaultProfileName(GSM_Profile *Profile)
GSM_Error DCT3DCT4_SendDTMF(GSM_StateMachine *s, char *sequence)
int smprintf(GSM_StateMachine *s, const char *format,...)
Definition: debug.c:261
GSM_Error N71_65_ReplyWritePhonebook(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_CalendarEntry * Cal
Definition: gsmstate.h:549
GSM_SubMemoryEntry Entries[GSM_PHONEBOOK_ENTRIES]
Definition: gammu-memory.h:427