Gammu internals  1.38.0
alcatel.c
Go to the documentation of this file.
1 /* (c) 2002-2005 by Michal Cihar */
32 #include "../../gsmstate.h"
33 
34 #ifdef GSM_ENABLE_ALCATEL
35 #ifdef GSM_ENABLE_ATGEN
36 
37 #include <string.h>
38 #include <time.h>
39 
40 #include "../../gsmcomon.h"
41 #include "../../misc/coding/coding.h"
42 #include "../../misc/misc.h"
43 #include "../pfunc.h"
44 #include "../at/atfunc.h"
45 #include "alcatel.h"
46 
50 #define ALCATEL_TIMEOUT 64
51 
57 /* synchronisation types (for everything except begin transfer): */
58 #define ALCATEL_SYNC_TYPE_CALENDAR 0x64
59 #define ALCATEL_SYNC_TYPE_TODO 0x68
60 #define ALCATEL_SYNC_TYPE_CONTACTS 0x6C
61 
62 /* synchronisation types (for begin transfer): */
63 #define ALCATEL_BEGIN_SYNC_CALENDAR 0x00
64 #define ALCATEL_BEGIN_SYNC_TODO 0x02
65 #define ALCATEL_BEGIN_SYNC_CONTACTS 0x01
66 
67 /* category types */
68 #define ALCATEL_LIST_TODO_CAT 0x9B
69 #define ALCATEL_LIST_CONTACTS_CAT 0x96
70 
71 /* Various flags */
72 #define ALCATEL_UNICODE_FLAG 0x80
73 
76 extern GSM_Reply_Function ALCATELReplyFunctions[];
77 
85 unsigned char GSM_AlcatelAlphabet[] =
86 {
87 /* in phone unicode description */
88  0x80, 0x00,0x20, /* empty - probably control char */
89  0x81, 0x00,0x20, /* empty */
90  0x82, 0x00,0x20, /* empty */
91  0x83, 0x00,0x20, /* empty */
92 
93  0x84, 0x00,0xe7, /* c cedilla */
94  0x85, 0x20,0x26, /* ... */
95  0x86, 0x03,0xc0, /* pi */
96  0x87, 0x01,0x3e, /* l caron */
97  0x88, 0x00,0xc0, /* A grave */
98  0x89, 0x00,0xc1, /* A acute */
99  0x8a, 0x00,0xc2, /* A circumflex */
100  0x8b, 0x00,0xc3, /* A tilde */
101  0x8c, 0x00,0xc8, /* E grave */
102  0x8d, 0x00,0xca, /* E circumflex */
103  0x8e, 0x00,0xcb, /* E diaresis */
104  0x8f, 0x00,0xcc, /* I grave */
105  0x90, 0x00,0xcd, /* I acute */
106  0x91, 0x00,0xd0, /* ETH */
107  0x92, 0x00,0xd2, /* O grave */
108  0x93, 0x00,0xd3, /* O acute */
109  0x94, 0x00,0xd4, /* O circumflex */
110  0x95, 0x00,0xd5, /* O tilde */
111  0x96, 0x00,0xd9, /* U grave */
112  0x97, 0x00,0xda, /* U acute */
113  0x98, 0x00,0xe1, /* a acute */
114  0x99, 0x00,0xe2, /* a circumflex */
115  0x9a, 0x00,0xe3, /* a tilde */
116  0x9b, 0x00,0xea, /* e circumflex */
117  0x9c, 0x00,0xeb, /* e diaresis */
118  0x9d, 0x00,0xed, /* i acute */
119  0x9e, 0x00,0xee, /* i circumflex */
120  0x9f, 0x00,0xef, /* i diaresis */
121  0xa0, 0x00,0xf3, /* o acute */
122  0xa1, 0x00,0xf4, /* o circumflex */
123  0xa2, 0x00,0xf5, /* o tilde */
124  0xa3, 0x00,0xfa, /* u acute */
125  0xa4, 0x00,0xa2, /* cent */
126  0xa5, 0x00,0x5b, /* [ */
127  0xa6, 0x01,0x59, /* r caron */
128  0xa7, 0x01,0x0d, /* c caron */
129  0xa8, 0x01,0x61, /* s caron */
130  0xa9, 0x01,0x1b, /* e caron */
131  0xaa, 0x01,0x6f, /* u ring */
132  0xab, 0x00,0xfd, /* y acute */
133  0xac, 0x00,0xf0, /* eth */
134  0xad, 0x01,0x07, /* c acute */
135  0xae, 0x01,0x19, /* e ogonek */
136  0xaf, 0x01,0x05, /* a ogonek */
137  0xb0, 0x01,0x7c, /* z dot */
138  0xb1, 0x01,0x7a, /* z acute */
139  0xb2, 0x01,0x5b, /* s acute */
140  0xb3, 0x01,0x44, /* n acute */
141  0xb4, 0x01,0x42, /* l stroke */
142 
143  0xb5, 0x00,0x20, /* empty */
144 
145  0xb6, 0x01,0x48, /* n caron */
146  0xb7, 0x01,0x65, /* t caron */
147 
148  0xb8, 0x00,0x20, /* empty */
149 
150  0xb9, 0x01,0x7e, /* z caron */
151  0xba, 0x01,0xe7, /* g caron */
152 
153  0xbb, 0x00,0x20, /* empty */
154  0xbc, 0x00,0x20, /* empty */
155 
156  0xbd, 0x1e,0x20, /* G macron */
157  0xbe, 0x1e,0x21, /* g macron */
158  0xbf, 0x01,0x5e, /* S cedilla */
159  0xc0, 0x01,0x5f, /* s cedilla */
160  0xc1, 0x01,0x2f, /* i ogonek */ /* Not sure with this, it look like normal i */
161  0xc2, 0x01,0x31, /* i dotless */
162  0xc3, 0x01,0x68, /* U tilde */
163  0xc4, 0x01,0x50, /* O dbl acute */
164  0xc5, 0x01,0x69, /* u tilde */
165  0xc6, 0x01,0x51, /* o dbl acute */
166  0xc7, 0x27,0xa9, /* => */
167  0xc8, 0x27,0xa8, /* filled => */
168  0xc9, 0x00,0xd7, /* x */
169  0xca, 0x00,0x5d, /* ] */
170  0xcb, 0x26,0x0f, /* phone */
171  0xcc, 0x01,0x0f, /* d caron */
172 
173  0xcd, 0x00,0x20, /* empty */
174 
175  0xce, 0x00,0x7e, /* ~ */
176  0xcf, 0x00,0x5c, /* \ */
177  0xd0, 0x00,0x5e, /* ^ */
178 
179  0xd1, 0x00,0x20, /* empty */
180 
181  0xd2, 0x00,0x7b, /* { */
182  0xd3, 0x00,0x7c, /* | */
183  0xd4, 0x00,0x7d, /* } */
184 
185  0xd5, 0x00,0x20, /* empty */
186 
187  0xd6, 0x01,0x63, /* t cedilla */
188 
189  0xd7, 0x00,0x20, /* empty */
190  0xd8, 0x00,0x20, /* empty */
191  0xd9, 0x00,0x20, /* empty */
192  0xda, 0x00,0x20, /* empty */
193  0xdb, 0x00,0x20, /* empty */
194  0xdc, 0x00,0x20, /* empty */
195  0xdd, 0x00,0x20, /* empty */
196  0xde, 0x00,0x20, /* empty */
197  0xdf, 0x00,0x20, /* empty */
198  0xe0, 0x00,0x20, /* empty */
199 
200  0xe1, 0x00,0x20, /* two candles */ /* Does this have unicode representation? */
201 
202  0xe2, 0x00,0x20, /* empty */
203  0xe3, 0x00,0x20, /* empty */
204  0xe4, 0x00,0x20, /* empty */
205 
206  0xe5, 0x01,0xce, /* a caron */
207  0xe6, 0x01,0x01, /* a macron */
208  0xe7, 0x01,0x13, /* e macron */
209  0xe8, 0x01,0x2b, /* i macron */
210  0xe9, 0x01,0x4d, /* o macron */
211  0xea, 0x01,0x6b, /* u macron */
212  0xeb, 0x00,0x41, /* A */
213  0xec, 0x00,0x40, /* @ */
214  0xed, 0x00,0x20, /* some strange char :-) */ /* Does this have unicode representation? */
215 
216  0xee, 0x00,0x20, /* big key stroken */ /* Does this have unicode representation? */
217  0xef, 0x00,0x20, /* big key */ /* Does this have unicode representation? */
218 
219  0xf0, 0x00,0x20, /* empty */
220 
221  0xf1, 0x00,0x31, /* 1 */
222  0xf2, 0x00,0x21, /* bold ! */
223  0xf3, 0x26,0x0e, /* black phone */
224  0xf4, 0x00,0x26, /* & */
225  0xf5, 0x23,0x7e, /* bell */
226  0xf6, 0x26,0x6a, /* note */
227 
228  0xf7, 0x27,0x13, /* okay inv */ /* Does this have unicode representation? */
229  0xf8, 0x27,0x13, /* okay */
230 
231  0xf9, 0x00,0x20, /* empty */
232 
233  0xfa, 0x00,0x20, /* key */ /* Does this have unicode representation? */
234 
235  0xfb, 0x00,0x20, /* empty */
236 
237  0xfc, 0x20,0xac, /* Euro */
238  0xfd, 0x21,0x97, /* NE arrow */
239  0xfe, 0x21,0x98, /* SE arrow */
240 
241  0xff, 0x00,0x20, /* empty */
242 
243  0x00, 0x00,0x00
244 };
245 
255 GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message *msg, GSM_StateMachine *s)
256 {
257  char *str, *str2;
258 /*
259  * Reply received here looks like:
260  * 1 "AT+CPROT=?"
261  * 2 "+CPROT: 0,"V1.0",1"
262  * 3 "+CPROT: 16,"V1.1",16"
263  * 4 "OK"
264  */
265  switch (s->Phone.Data.Priv.ATGEN.ReplyState) {
266  case AT_Reply_OK:
267  str = strstr(msg->Buffer, "\"V");
268  if (str == NULL) return ERR_UNKNOWNRESPONSE;
269  str += 2;
270  while((str2 = strstr(str, "\"V")) != NULL) str = str2 + 2;
271  if (strncmp(str, "1.0", 3) == 0) {
272  s->Phone.Data.Priv.ALCATEL.ProtocolVersion = V_1_0;
273  } else if (strncmp(str, "1.1", 3) == 0) {
274  s->Phone.Data.Priv.ALCATEL.ProtocolVersion = V_1_1;
275  } else {
276  smprintf(s, "Unknown protocol version. Please send debug log and phone info to author.\n");
277  return ERR_NOTIMPLEMENTED;
278  }
279  return ERR_NONE;
280  case AT_Reply_Error:
281  return ERR_NOTSUPPORTED;
282  case AT_Reply_CMSError:
283  return ATGEN_HandleCMSError(s);
284  case AT_Reply_CMEError:
285  return ATGEN_HandleCMEError(s);
286  default:
287  return ERR_UNKNOWNRESPONSE;
288  }
289 }
290 
294 static GSM_Error ALCATEL_SetBinaryMode(GSM_StateMachine *s)
295 {
296  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
297  GSM_Error error;
298 
299  if (Priv->Mode == ModeBinary) return ERR_NONE;
300 
301  smprintf(s, "Changing to binary mode\n");
302 
303  error=GSM_WaitFor (s, "AT+IFC=2,2\r", 11, 0x02, 4, ID_SetFlowControl);
304  if (error != ERR_NONE) return error;
305 
306  error=GSM_WaitFor (s, "AT+CPROT=?\r", 11, 0x02, 4, ID_AlcatelProtocol);
307  if (error != ERR_NONE) return error;
308 
309  if (Priv->ProtocolVersion == V_1_0) {
310  error=GSM_WaitFor (s, "AT+CPROT=16,\"V1.0\",16\r", 22, 0x00, 4, ID_AlcatelConnect);
311  } else {
312  error=GSM_WaitFor (s, "AT+CPROT=16,\"V1.1\",16\r", 22, 0x00, 4, ID_AlcatelConnect);
313  }
314 
315  if (error == ERR_TIMEOUT && s->Speed != 19200) {
316  smprintf(s, "HINT: Try changing speed to 19200, it is sometimes needed for Alcatel binary mode.\n");
317  }
318 
319  if (error != ERR_NONE) return error;
320 
321  smprintf(s, "Changing protocol to Alcabus\n");
322 
323  s->Protocol.Functions = &ALCABUSProtocol;
324  error = s->Protocol.Functions->Initialise(s);
325  if (error != ERR_NONE) {
326  s->Protocol.Functions = &ATProtocol;
327  return error;
328  }
329  s->Phone.Functions->ReplyFunctions = ALCATELReplyFunctions;
330  Priv->Mode = ModeBinary;
331  Priv->BinaryItem = 0;
332  Priv->BinaryType = 0;
333  Priv->BinaryState = StateAttached;
334  return ERR_NONE;
335 }
336 
340 static GSM_Error ALCATEL_GoToBinaryState(GSM_StateMachine *s, GSM_Alcatel_BinaryState state, GSM_Alcatel_BinaryType type, int item) {
341  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
342  GSM_Error error;
343  unsigned char attach_buffer[] = {0x00, 0x00, 0x7C ,0x20};
344  unsigned char detach_buffer[] = {0x00, 0x01, 0x7C ,0x00};
345  unsigned char start_buffer[] =
346  {0x00, 0x04, 0x7C, 0x80, /* 4 byte database id follows */
347  0x12, 0x34, 0x56, 0x78};
348  unsigned char end_buffer[] =
349  {0x00, 0x04, 0x7C, 0x82,
350  0x00, /* type */
351  0x00, 0x00, 0x00, 0x00}; /* TimeStamp */
352  unsigned char close_buffer[] =
353  {0x00, 0x04,
354  0x00, /*type */
355  0x23, 0x01};
356  unsigned char select1_buffer[] =
357  {0x00, 0x00,
358  0x00, /*type */
359  0x20};
360  unsigned char select2_buffer[] =
361  {0x00, 0x04,
362  0x00, /*type */
363  0x22, 0x01, 0x00};
364  unsigned char begin_buffer[] =
365  {0x00, 0x04, 0x7C, 0x81,
366  0x00, /*type */
367  0x00, 0x85, 0x00};
368  unsigned char commit_buffer[] =
369  {0x00, 0x04,
370  0x00, /*type */
371  0x20, 0x01};
372 
373  smprintf(s, "Alcatel state switcher: %d -> %d, %d -> %d, %d -> %d\n", Priv->BinaryState, state, Priv->BinaryType, type, Priv->BinaryItem, item);
374  error = ALCATEL_SetBinaryMode(s);
375  if (error != ERR_NONE) return error;
376 
377  /* Do we need to do anything? */
378  if ((state == Priv->BinaryState) && (type == Priv->BinaryType) && (item == Priv->BinaryItem)) return ERR_NONE;
379 
380  /* We're editing, but the next state is not the same. so commit editing */
381  if (Priv->BinaryState == StateEdit) {
382  /* Something has changed, we will have to reread fields! */
383  Priv->CurrentFieldsItem = -1;
384  switch (Priv->BinaryType) {
385  case TypeCalendar:
386  commit_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
387  break;
388  case TypeContacts:
389  commit_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
390  break;
391  case TypeToDo:
392  commit_buffer[2] = ALCATEL_SYNC_TYPE_TODO;
393  break;
394  }
395  smprintf(s, "Committing edited record\n");
396  error=GSM_WaitFor (s, commit_buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelCommit);
397  if (error != ERR_NONE) return error;
398  error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelCommit2);
399  if (error != ERR_NONE) return error;
400  Priv->BinaryState = StateSession;
401  Priv->BinaryItem = 0;
402  }
403 
404  /* Do we want to edit something of same type? */
405  if ((state == StateEdit) && (type == Priv->BinaryType)) {
406  /* Edit state doesn't need any switching, it is needed only for
407  * indication that e have to commit record before we switch to other
408  * mode.
409  */
410  Priv->BinaryState = StateEdit;
411  Priv->BinaryItem = item;
412  return ERR_NONE;
413  }
414 
415  /* Now we can be only in Attached or Session state, so if states and types matches, just keep them as they are */
416  if ((state == Priv->BinaryState) && (type == Priv->BinaryType)) {
417  return ERR_NONE;
418  }
419 
420  /* Do we need to close session? */
421  if (Priv->BinaryState == StateSession) {
422  smprintf(s, "Ending session\n");
423  switch (Priv->BinaryType) {
424  case TypeCalendar:
425  end_buffer[4] = ALCATEL_BEGIN_SYNC_CALENDAR;
426  break;
427  case TypeContacts:
428  end_buffer[4] = ALCATEL_BEGIN_SYNC_CONTACTS;
429  break;
430  case TypeToDo:
431  end_buffer[4] = ALCATEL_BEGIN_SYNC_TODO;
432  break;
433  }
434  error=GSM_WaitFor (s, end_buffer, 9, 0x02, ALCATEL_TIMEOUT, ID_AlcatelEnd);
435  if (error != ERR_NONE) return error;
436 
437  switch (Priv->BinaryType) {
438  case TypeCalendar:
439  close_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
440  break;
441  case TypeContacts:
442  close_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
443  break;
444  case TypeToDo:
445  close_buffer[2] = ALCATEL_SYNC_TYPE_TODO;
446  break;
447  }
448  smprintf(s, "Closing session\n");
449  error=GSM_WaitFor (s, close_buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelClose);
450  if (error != ERR_NONE) return error;
451 
452  smprintf(s, "Detaching binary mode\n");
453  error = GSM_WaitFor (s, detach_buffer, 4, 0x02, ALCATEL_TIMEOUT, ID_AlcatelDetach);
454  if (error != ERR_NONE) return error;
455 
456  Priv->BinaryState = StateAttached;
457  Priv->BinaryType = 0;
458  }
459 
460  /* Do we need to open session? */
461  if (state == StateSession || state == StateEdit) {
462  smprintf(s, "Starting session for %s\n",
463  (type == TypeCalendar ? "Calendar" :
464  (type == TypeToDo ? "Todo" :
465  (type == TypeContacts ? "Contacts" :
466  "Unknown!"))));
467  /* Fill up buffers */
468  switch (type) {
469  case TypeCalendar:
470  select1_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
471  select2_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
472  begin_buffer[4] = ALCATEL_BEGIN_SYNC_CALENDAR;
473  break;
474  case TypeContacts:
475  select1_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
476  select2_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
477  begin_buffer[4] = ALCATEL_BEGIN_SYNC_CONTACTS;
478  break;
479  case TypeToDo:
480  select1_buffer[2] = ALCATEL_SYNC_TYPE_TODO;
481  select2_buffer[2] = ALCATEL_SYNC_TYPE_TODO;
482  begin_buffer[4] = ALCATEL_BEGIN_SYNC_TODO;
483  break;
484  }
485  smprintf(s, "Attaching in binary mode\n");
486 
487  /* Communicate */
488  error=GSM_WaitFor (s, attach_buffer, 4, 0x02, ALCATEL_TIMEOUT, ID_AlcatelAttach);
489  if (error != ERR_NONE) return error;
490 
491  smprintf(s,"Start session\n");
492  error=GSM_WaitFor (s, start_buffer, 8, 0x02, ALCATEL_TIMEOUT, ID_AlcatelStart);
493  if (error != ERR_NONE) return error;
494 
495  smprintf(s,"Select type\n");
496  error=GSM_WaitFor (s, select1_buffer, 4, 0x02, ALCATEL_TIMEOUT, ID_AlcatelSelect1);
497  if (error != ERR_NONE) return error;
498  error=GSM_WaitFor (s, select2_buffer, 6, 0x02, ALCATEL_TIMEOUT, ID_AlcatelSelect2);
499  if (error != ERR_NONE) return error;
500  error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelSelect3);
501  if (error != ERR_NONE) return error;
502 
503  smprintf(s,"Begin transfer\n");
504  error=GSM_WaitFor (s, begin_buffer, 8, 0x02, ALCATEL_TIMEOUT, ID_AlcatelBegin1);
505  if (error != ERR_NONE) return error;
506  error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelBegin2);
507  if (error != ERR_NONE) return error;
508 
509  Priv->BinaryState = StateSession;
510  Priv->BinaryType = type;
511  /* Do we want to edit something of same type? */
512  if ((state == StateEdit) && (type == Priv->BinaryType)) {
513  Priv->BinaryState = StateEdit;
514  Priv->BinaryItem = item;
515  return ERR_NONE;
516  }
517  }
518  return ERR_NONE;
519 }
520 
524 static GSM_Error ALCATEL_SetATMode(GSM_StateMachine *s)
525 {
526  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
527  GSM_Error error;
528 
529  if (Priv->Mode == ModeAT) return ERR_NONE;
530 
531  error = ALCATEL_GoToBinaryState(s, StateAttached, 0, 0);
532  if (error != ERR_NONE) return error;
533 
534  error = s->Protocol.Functions->Terminate(s);
535  if (error != ERR_NONE) return error;
536 
537  smprintf(s, "Changing protocol to AT\n");
538  s->Protocol.Functions = &ATProtocol;
540  Priv->Mode = ModeAT;
541  s->Phone.Data.Priv.ATGEN.Charset = 0;
542  s->Phone.Data.Priv.ATGEN.PBKMemory = 0;
543 
544  usleep(100000);
545 
546  /* In case we don't send AT command short after closing binary mode,
547  * phone takes VERY long to react next time. The error code in
548  * intetionally ignored.
549  */
550  error = GSM_WaitFor (s, "AT\r", 3, 0x00, 0, ID_IncomingFrame);
551 
552  return ERR_NONE;
553 }
554 
560 static GSM_Error ALCATEL_Initialise(GSM_StateMachine *s)
561 {
562  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
563  GSM_Error error;
564 
565  Priv->Mode = ModeAT;
566 
567  Priv->CalendarItems = NULL;
568  Priv->ContactsItems = NULL;
569  Priv->ToDoItems = NULL;
570  Priv->CalendarItemsCount = 0;
571  Priv->ToDoItemsCount = 0;
572  Priv->ContactsItemsCount = 0;
573  Priv->CurrentFields[0] = 0;
574  Priv->CurrentFieldsCount = 0;
575  Priv->CurrentFieldsItem = 0;
576  Priv->CurrentFieldsType = 0;
577  Priv->ProtocolVersion = V_1_0;
578  Priv->CurrentFieldsItem = -1;
579 
580  Priv->CurrentCategoriesCount = 0;
581  Priv->CurrentCategoriesType = 0;
582 
583  s->Protocol.Functions = &ATProtocol;
585 
586  if (ATGEN_Initialise(s) != ERR_NONE || GSM_WaitFor (s, "AT\r", 3, 0x00, 2, ID_IncomingFrame) != ERR_NONE) {
587  smprintf(s,"AT initialisation failed, trying to stop binary mode...\n");
588  s->Protocol.Functions = &ALCABUSProtocol;
589  error = s->Protocol.Functions->Terminate(s);
590  s->Protocol.Functions = &ATProtocol;
591 
592  error = ATGEN_Initialise(s);
593  if (error != ERR_NONE) return error;
594  }
595 
596  return ERR_NONE;
597 }
598 
599 static GSM_Error ALCATEL_Terminate(GSM_StateMachine *s)
600 {
601  GSM_Error error;
602  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
603 
604  free(Priv->CalendarItems);
605  Priv->CalendarItems=NULL;
606  free(Priv->ContactsItems);
607  Priv->ContactsItems=NULL;
608  free(Priv->ToDoItems);
609  Priv->ToDoItems=NULL;
610  error = ALCATEL_SetATMode(s);
611 
612  if (error != ERR_NONE) {
613  return error;
614  }
615  return ATGEN_Terminate(s);
616 }
617 
621 static GSM_Error ALCATEL_IsIdAvailable(GSM_StateMachine *s, int id) {
622  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
623  int i;
624 
625  if (id > ALCATEL_MAX_LOCATION) return ERR_INVALIDLOCATION;
626 
627  switch (Priv->BinaryType) {
628  case TypeCalendar:
629  Priv->CurrentList = &(Priv->CalendarItems);
630  Priv->CurrentCount = &(Priv->CalendarItemsCount);
631  break;
632  case TypeContacts:
633  Priv->CurrentList = &(Priv->ContactsItems);
634  Priv->CurrentCount = &(Priv->ContactsItemsCount);
635  break;
636  case TypeToDo:
637  Priv->CurrentList = &(Priv->ToDoItems);
638  Priv->CurrentCount = &(Priv->ToDoItemsCount);
639  break;
640  }
641 
642  for (i=0; i<*Priv->CurrentCount; i++) {
643  if ((*Priv->CurrentList)[i] == id) return ERR_NONE;
644  }
645 
646  return ERR_EMPTY;
647 }
648 
652 static GSM_Error ALCATEL_GetNextId(GSM_StateMachine *s, int *id) {
653  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
654  int i = 0;
655  int next = ALCATEL_MAX_LOCATION;
656 
657  switch (Priv->BinaryType) {
658  case TypeCalendar:
659  Priv->CurrentList = &(Priv->CalendarItems);
660  Priv->CurrentCount = &(Priv->CalendarItemsCount);
661  break;
662  case TypeContacts:
663  Priv->CurrentList = &(Priv->ContactsItems);
664  Priv->CurrentCount = &(Priv->ContactsItemsCount);
665  break;
666  case TypeToDo:
667  Priv->CurrentList = &(Priv->ToDoItems);
668  Priv->CurrentCount = &(Priv->ToDoItemsCount);
669  break;
670  }
671 
672  for (i=0; i<*Priv->CurrentCount; i++) {
673  if (((*Priv->CurrentList)[i] > *id) && ((*Priv->CurrentList)[i] < next )) {
674  next = (*Priv->CurrentList)[i];
675  }
676  }
677  if (next == ALCATEL_MAX_LOCATION) {
678  return ERR_EMPTY;
679  } else {
680  *id = next;
681  return ERR_NONE;
682  }
683 }
684 
685 static GSM_Error ALCATEL_ReplyGetIds(GSM_Protocol_Message *msg, GSM_StateMachine *s)
686 {
687  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
688  int count,i,pos;
689 
690  count = msg->Buffer[10];
691  *Priv->CurrentCount += count;
692 
693  *Priv->CurrentList = (int *)realloc(*Priv->CurrentList, (*Priv->CurrentCount + 1)* sizeof(int));
694  if (*Priv->CurrentList == NULL) return ERR_MOREMEMORY;
695 
696  for (i = 0; i < count; i++) {
697  pos = 11 + (4 * i);
698  (*Priv->CurrentList)[*Priv->CurrentCount - count + i] = msg->Buffer[pos + 3] +
699  (msg->Buffer[pos + 2] << 8) +
700  (msg->Buffer[pos + 1] << 16) +
701  (msg->Buffer[pos] << 24);
702  }
703  (*Priv->CurrentList)[*Priv->CurrentCount] = 0;
704 
705  /* If last byte is 0, then we transmitted all items */
706  Priv->TransferCompleted = msg->Buffer[4 + msg->Buffer[4]] == 0;
707  return ERR_NONE;
708 }
709 
713 static GSM_Error ALCATEL_GetAvailableIds(GSM_StateMachine *s, gboolean refresh)
714 {
715  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
716  GSM_Error error;
717  int i;
718  unsigned char buffer[] =
719  {0x00, 0x04,
720  0x00, /*type */
721  0x2F, 0x01};
722 
723  if (Priv->BinaryState != StateSession) return ERR_UNKNOWN;
724 
725  switch (Priv->BinaryType) {
726  case TypeCalendar:
727  buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
728  Priv->CurrentList = &(Priv->CalendarItems);
729  Priv->CurrentCount = &(Priv->CalendarItemsCount);
730  break;
731  case TypeContacts:
732  buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
733  Priv->CurrentList = &(Priv->ContactsItems);
734  Priv->CurrentCount = &(Priv->ContactsItemsCount);
735  break;
736  case TypeToDo:
737  buffer[2] = ALCATEL_SYNC_TYPE_TODO;
738  Priv->CurrentList = &(Priv->ToDoItems);
739  Priv->CurrentCount = &(Priv->ToDoItemsCount);
740  break;
741  }
742 
743  if (*Priv->CurrentList != NULL) {
744  if (!refresh) {
745  return ERR_NONE;
746  }
747  free(*Priv->CurrentList);
748  *Priv->CurrentList = NULL;
749  }
750  smprintf(s,"Reading items list\n");
751 
752  *Priv->CurrentCount = 0;
753  Priv->TransferCompleted = FALSE;
754 
755  error=GSM_WaitFor (s, buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetIds1);
756  if (error != ERR_NONE) return error;
757 
758  while (!Priv->TransferCompleted) {
759  error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetIds2);
760  if (error != ERR_NONE) return error;
761  }
762 
763  smprintf(s,"Received %d ids: ", *Priv->CurrentCount);
764  for (i=0; i < *Priv->CurrentCount; i++) {
765  smprintf(s,"%x ", (*Priv->CurrentList)[i]);
766  }
767  smprintf(s,"\n");
768 
769  return ERR_NONE;
770 }
771 
772 static GSM_Error ALCATEL_ReplyGetFields(GSM_Protocol_Message *msg, GSM_StateMachine *s)
773 {
774  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
775  int i;
776 
777  if (msg->Buffer[14] > GSM_PHONEBOOK_ENTRIES) {
778  smprintf(s, "WARNING: Field list truncated, you should increase GSM_PHONEBOOK_ENTRIES to at least %d\n", msg->Buffer[14]);
780  } else {
781  Priv->CurrentFieldsCount = msg->Buffer[14];
782  }
783 
784  Priv->CurrentFields[Priv->CurrentFieldsCount] = 0;
785 
786  for (i = 0; i < Priv->CurrentFieldsCount; i++) {
787  Priv->CurrentFields[i] = msg->Buffer[15 + i];
788  }
789 
790  return ERR_NONE;
791 }
792 
793 static GSM_Error ALCATEL_GetFields(GSM_StateMachine *s, int id) {
794  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
795  GSM_Error error;
796  int i;
797  unsigned char buffer[] =
798  {0x00, 0x04,
799  0x00, /* type */
800  0x30, 0x01,
801  0x00, 0x00, 0x00, 0x00}; /* item */
802 
803  if (Priv->BinaryState != StateSession) return ERR_UNKNOWN;
804  if ((Priv->CurrentFieldsItem == id) && (Priv->CurrentFieldsType == Priv->BinaryType)) return ERR_NONE;
805 
806  smprintf(s,"Reading item fields (%d)\n", id);
807 
808  buffer[5] = (id >> 24);
809  buffer[6] = ((id >> 16) & 0xff);
810  buffer[7] = ((id >> 8) & 0xff);
811  buffer[8] = (id & 0xff);
812 
813  switch (Priv->BinaryType) {
814  case TypeCalendar:
815  buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
816  break;
817  case TypeContacts:
818  buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
819  break;
820  case TypeToDo:
821  buffer[2] = ALCATEL_SYNC_TYPE_TODO;
822  break;
823  }
824 
825  Priv->CurrentFieldsItem = id;
826  Priv->CurrentFieldsType = Priv->BinaryType;
827 
828  error=GSM_WaitFor (s, buffer, 9, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetFields1);
829  if (error != ERR_NONE) return error;
830  error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetFields2);
831  if (error != ERR_NONE) return error;
832 
833  smprintf(s,"Received %d fields: ", Priv->CurrentFieldsCount);
834  for (i=0; i < Priv->CurrentFieldsCount; i++) {
835  smprintf(s,"%x ", Priv->CurrentFields[i]);
836  }
837  smprintf(s,"\n");
838 
839  return ERR_NONE;
840 }
841 
842 static void ALCATEL_DecodeString(GSM_StateMachine *s, unsigned const char *buffer, unsigned char *target, int maxlen)
843 {
844  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
845  int len;
846 
847  len = buffer[0];
848  if (Priv->ProtocolVersion == V_1_1 && (buffer[1] == ALCATEL_UNICODE_FLAG)) {
849  /* UCS-2-BE string */
850  if (GSM_PHONEBOOK_TEXT_LENGTH <= len / 2) {
851  smprintf(s, "WARNING: Text truncated, to %d from %d\n", maxlen, len/2 + 1);
852  len = GSM_PHONEBOOK_TEXT_LENGTH * 2;
853  }
854  memcpy(target, buffer + 2, len);
855  Priv->ReturnString[len + 1] = 0;
856  Priv->ReturnString[len + 2] = 0;
857  } else {
858  /* Alcatel alphabet string */
859  if (GSM_PHONEBOOK_TEXT_LENGTH <= len) {
860  smprintf(s, "WARNING: Text truncated, to %d from %d\n", maxlen, len + 1);
862  }
863  DecodeDefault(target, buffer + 1, len, FALSE, GSM_AlcatelAlphabet);
864  }
865 }
866 
867 static GSM_Error ALCATEL_EncodeString(GSM_StateMachine *s, unsigned const char *buffer, unsigned char *target, GSM_Alcatel_FieldType type)
868 {
869  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
870  size_t len;
871  size_t maxlen = 0;
872  gboolean unicode = FALSE;
873  unsigned char text[2*(GSM_PHONEBOOK_TEXT_LENGTH + 1)];
874  unsigned char utext[2*(GSM_PHONEBOOK_TEXT_LENGTH + 1)];
875 
876  len = UnicodeLength(buffer);
877  /* Maximal length is item and phone dependant, we use it only for guessing as phone will report too big entry correctly. */
878  if (type == Alcatel_string) {
879  if (Priv->ProtocolVersion == V_1_1) {
880  maxlen = 151;
881  } else {
882  maxlen = 62;
883  }
884  } else if (type == Alcatel_phone) {
885  if (Priv->ProtocolVersion == V_1_1) {
886  maxlen = 61;
887  } else {
888  maxlen = 50;
889  }
890  } else if (type == 0) {
891  /* We're creating category */
892  maxlen = 60;
893  }
894 
895  if (Priv->ProtocolVersion == V_1_1) {
896 
897  /* Compare if we would loose some information when not using
898  * unicode */
899  EncodeDefault(text, buffer, &len, TRUE, GSM_AlcatelAlphabet);
900  DecodeDefault(utext, text, len, TRUE, GSM_AlcatelAlphabet);
901  if (!mywstrncmp(utext, buffer, len)) {
902  /* Use unicode only when we have enough space */
903  unicode = ((len * 2) < maxlen);
904  }
905  }
906 
907  if (unicode) {
908  /* UCS-2-BE string */
909  target[0] = len * 2 + 3;
910  target[1] = ALCATEL_UNICODE_FLAG;
911  memcpy(target + 2, buffer, len * 2 + 2);
912  } else {
913  /* Alcatel alphabet string */
914  EncodeDefault(target + 1, buffer, &len, TRUE, GSM_AlcatelAlphabet);
915  target[0] = len;
916  target[len + 1] = 0;
917  }
918 
919  return ERR_NONE;
920 }
921 
927 static GSM_Error ALCATEL_ReplyGetFieldValue(GSM_Protocol_Message *msg, GSM_StateMachine *s)
928 {
929  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
930  unsigned char *buffer = &(msg->Buffer[16]);
931 
932  if (buffer[1] == 0x05 && buffer[2] == 0x67) {
933  /* date */
934  Priv->ReturnType = Alcatel_date;
935  Priv->ReturnDateTime.Day = buffer[4];
936  Priv->ReturnDateTime.Month = buffer[5];
937  Priv->ReturnDateTime.Year = buffer[7] + (buffer[6] << 8);
938  Priv->ReturnDateTime.Timezone = 0; /* how to acquire this? */
939 
940  Priv->ReturnDateTime.Hour = 0;
941  Priv->ReturnDateTime.Minute = 0;
942  Priv->ReturnDateTime.Second = 0;
943  } else if (buffer[1] == 0x06 && buffer[2] == 0x68) {
944  /* time */
945  Priv->ReturnType = Alcatel_time;
946  Priv->ReturnDateTime.Hour = buffer[4];
947  Priv->ReturnDateTime.Minute = buffer[5];
948  Priv->ReturnDateTime.Second = buffer[6];
949 
950  Priv->ReturnDateTime.Day = 0;
951  Priv->ReturnDateTime.Month = 0;
952  Priv->ReturnDateTime.Year = 0;
953  Priv->ReturnDateTime.Timezone = 0;
954  } else if (buffer[1] == 0x08 && buffer[2] == 0x3C) {
955  /* string */
956  Priv->ReturnType = Alcatel_string;
957  ALCATEL_DecodeString(s, buffer + 3, Priv->ReturnString, GSM_PHONEBOOK_TEXT_LENGTH);
958  } else if (buffer[1] == 0x07 && buffer[2] == 0x3C) {
959  /* phone */
960  Priv->ReturnType = Alcatel_phone;
961  ALCATEL_DecodeString(s, buffer + 3, Priv->ReturnString, GSM_PHONEBOOK_TEXT_LENGTH);
962  } else if (buffer[1] == 0x03 && buffer[2] == 0x3B) {
963  /* boolean */
964  Priv->ReturnType = Alcatel_bool;
965  Priv->ReturnInt = buffer[3];
966  } else if (buffer[1] == 0x02 && buffer[2] == 0x3A) {
967  /* integer */
968  Priv->ReturnType = Alcatel_int;
969  Priv->ReturnInt = buffer[6] + (buffer[5] << 8) + (buffer[4] << 16) + (buffer[3] << 24);
970  } else if (buffer[1] == 0x04 && buffer[2] == 0x38) {
971  /* enumeration */
972  Priv->ReturnType = Alcatel_enum;
973  Priv->ReturnInt = buffer[3];
974  } else if (buffer[1] == 0x00 && buffer[2] == 0x38) {
975  /* byte */
976  Priv->ReturnType = Alcatel_byte;
977  Priv->ReturnInt = buffer[3];
978  } else {
979  smprintf(s, "WARNING: Uknown data type received (%02X,%02X)\n", buffer[1], buffer[2]);
980  return ERR_UNKNOWNRESPONSE;
981  }
982  return ERR_NONE;
983 }
984 
985 static GSM_Error ALCATEL_GetFieldValue(GSM_StateMachine *s, int id, int field)
986 {
987  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
988  GSM_Error error;
989  unsigned char buffer[] =
990  {0x00, 0x04,
991  0x00, /* type */
992  0x1f, 0x01,
993  0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */
994  0x00}; /* field */
995 
996  smprintf(s,"Reading item value (%08x.%02x)\n", id, field);
997 
998  switch (Priv->BinaryType) {
999  case TypeCalendar:
1000  buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
1001  break;
1002  case TypeContacts:
1003  buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1004  break;
1005  case TypeToDo:
1006  buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1007  break;
1008  }
1009 
1010  buffer[5] = (id >> 24);
1011  buffer[6] = ((id >> 16) & 0xff);
1012  buffer[7] = ((id >> 8) & 0xff);
1013  buffer[8] = (id & 0xff);
1014  buffer[9] = (field & 0xff);
1015 
1016  error=GSM_WaitFor (s, buffer, 10, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetFieldValue1);
1017  if (error != ERR_NONE) return error;
1018  error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetFieldValue2);
1019  if (error != ERR_NONE) return error;
1020 
1021  return ERR_NONE;
1022 }
1023 
1024 static GSM_Error ALCATEL_ReplyGetCategories(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1025 {
1026  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1027  int i;
1028 
1029  /* Did we get any category? */
1030  if (msg->Buffer[4] == 6) {
1031  Priv->CurrentCategoriesCount = 0;
1032  return ERR_NONE;
1033  }
1034  if (msg->Buffer[12] > ALCATEL_MAX_CATEGORIES) {
1035  smprintf(s, "WARNING: Field list truncated, you should increase ALCATEL_MAX_CATEGORIES to at least %d\n", msg->Buffer[12]);
1037  } else {
1038  Priv->CurrentCategoriesCount = msg->Buffer[12];
1039  }
1040 
1041  for (i = 0; i < Priv->CurrentCategoriesCount; i++) {
1042  Priv->CurrentCategories[i] = msg->Buffer[13 + i];
1043  Priv->CurrentCategoriesCache[i][0] = '\000';
1044  Priv->CurrentCategoriesCache[i][1] = '\000';
1045  }
1046 
1047  return ERR_NONE;
1048 }
1049 
1050 static GSM_Error ALCATEL_GetAvailableCategoryIds(GSM_StateMachine *s) {
1051  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1052  GSM_Error error;
1053  int i;
1054  unsigned char buffer[] =
1055  {0x00, 0x04,
1056  0x00 /*type */,
1057  0x0b,
1058  0x00 /* list */};
1059 
1060  if (Priv->BinaryState != StateSession) return ERR_UNKNOWN;
1061  if (Priv->CurrentCategoriesType == Priv->BinaryType) return ERR_NONE;
1062  switch (Priv->BinaryType) {
1063  case TypeContacts:
1064  buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1065  buffer[4] = ALCATEL_LIST_CONTACTS_CAT;
1066  break;
1067  case TypeToDo:
1068  buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1069  buffer[4] = ALCATEL_LIST_TODO_CAT;
1070  break;
1071  default:
1072  return ERR_NOTSUPPORTED;
1073  }
1074 
1075  Priv->CurrentCategoriesType = Priv->BinaryType;
1076 
1077  smprintf(s,"Reading category list\n");
1078 
1079  error=GSM_WaitFor (s, buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetCategories1);
1080  if (error != ERR_NONE) return error;
1081 
1082  error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetCategories2);
1083  if (error != ERR_NONE) return error;
1084 
1085  smprintf(s,"Received %d ids: ", Priv->CurrentCategoriesCount);
1086  for (i=0; i < Priv->CurrentCategoriesCount; i++) {
1087  smprintf(s,"%i ", Priv->CurrentCategories[i]);
1088  }
1089  smprintf(s,"\n");
1090 
1091  return ERR_NONE;
1092 }
1093 
1094 static GSM_Error ALCATEL_IsCategoryIdAvailable(GSM_StateMachine *s, int id) {
1095  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1096  int i = 0;
1097 
1098  if (Priv->CurrentCategoriesType != Priv->BinaryType) return ERR_UNKNOWN;
1099 
1100  for (i = 0; i< Priv->CurrentCategoriesCount; i++) {
1101  if (Priv->CurrentCategories[i] == id) return ERR_NONE;
1102  }
1103  return ERR_EMPTY;
1104 }
1105 
1106 static GSM_Error ALCATEL_ReplyAddCategoryText(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1107 {
1108  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1109 
1110  Priv->ReturnInt = msg->Buffer[12];
1111 
1112  return ERR_NONE;
1113 }
1114 
1115 static GSM_Error ALCATEL_AddCategoryText(GSM_StateMachine *s, const unsigned char *str) {
1116  unsigned char buffer[200] = {0x00, 0x04, 0x00 /*type*/, 0x0d, 0x00 /*list*/, 0x0b };
1117  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1118  GSM_Error error;
1119 
1120 
1121  smprintf(s,"Creating category\n");
1122  ALCATEL_EncodeString(s, str, buffer + 7, 0);
1123  buffer[6] = buffer[7] + 1;
1124 
1125  switch (Priv->BinaryType) {
1126  case TypeContacts:
1127  buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1128  buffer[4] = ALCATEL_LIST_CONTACTS_CAT;
1129  break;
1130  case TypeToDo:
1131  buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1132  buffer[4] = ALCATEL_LIST_TODO_CAT;
1133  break;
1134  default:
1135  return ERR_NOTSUPPORTED;
1136  }
1137 
1138  error=GSM_WaitFor (s, buffer, 8 + buffer[7], 0x02, ALCATEL_TIMEOUT, ID_AlcatelAddCategoryText1);
1139  if (error != ERR_NONE) return error;
1140  error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelAddCategoryText2);
1141  if (error != ERR_NONE) return error;
1142 
1143  /* Refresh list */
1144  Priv->CurrentCategoriesType = 0;
1145  return ALCATEL_GetAvailableCategoryIds(s);
1146 }
1147 
1148 static GSM_Error ALCATEL_ReplyGetCategoryText(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1149 {
1150  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1151 
1152  ALCATEL_DecodeString(s,msg->Buffer + 14, Priv->ReturnString, GSM_MAX_CATEGORY_NAME_LENGTH);
1153 
1154  return ERR_NONE;
1155 }
1156 
1157 static GSM_Error ALCATEL_GetCategoryText(GSM_StateMachine *s, int id) {
1158  unsigned char buffer[] = {0x00, 0x04, 0x00 /*type*/, 0x0c, 0x00 /*list*/, 0x0A, 0x01, 0x00 /*item*/ };
1159  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1160  GSM_Error error;
1161 
1162  if (Priv->CurrentCategoriesCache[id][0] != '\000' || Priv->CurrentCategoriesCache[id][1] != '\000') {
1164  return ERR_NONE;
1165  }
1166 
1167  smprintf(s,"Reading category %d\n", id);
1168 
1169  switch (Priv->BinaryType) {
1170  case TypeContacts:
1171  buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1172  buffer[4] = ALCATEL_LIST_CONTACTS_CAT;
1173  break;
1174  case TypeToDo:
1175  buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1176  buffer[4] = ALCATEL_LIST_TODO_CAT;
1177  break;
1178  default:
1179  return ERR_NOTSUPPORTED;
1180  }
1181 
1182  buffer[7] = (id & 0xff);
1183 
1184  error=GSM_WaitFor (s, buffer, 8, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetCategoryText1);
1185  if (error != ERR_NONE) return error;
1186  error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetCategoryText2);
1187  if (error != ERR_NONE) return error;
1188 
1190 
1191  return ERR_NONE;
1192 }
1193 
1194 static GSM_Error ALCATEL_DeleteField(GSM_StateMachine *s, int id, int field) {
1195  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1196  GSM_Error error;
1197  unsigned char buffer[] =
1198  {0x00, 0x04,
1199  0x00, /* type */
1200  0x26, 0x01,
1201  0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */
1202  0x65, 0x01,
1203  0x00, /* field */
1204  0x01};
1205 
1206  smprintf(s,"Deleting field (%08x.%02x)\n", id, field);
1207 
1208  switch (Priv->BinaryType) {
1209  case TypeCalendar:
1210  buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
1211  break;
1212  case TypeContacts:
1213  buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1214  break;
1215  case TypeToDo:
1216  buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1217  break;
1218  }
1219 
1220  buffer[5] = (id >> 24);
1221  buffer[6] = ((id >> 16) & 0xff);
1222  buffer[7] = ((id >> 8) & 0xff);
1223  buffer[8] = (id & 0xff);
1224  buffer[11] = (field & 0xff);
1225 
1226  error=GSM_WaitFor (s, buffer, 13, 0x02, ALCATEL_TIMEOUT, ID_AlcatelDeleteField);
1227  if (error != ERR_NONE) return error;
1228 
1229  return ERR_NONE;
1230 }
1231 
1232 static GSM_Error ALCATEL_DeleteItem(GSM_StateMachine *s, int id) {
1233  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1234  GSM_Error error;
1235  unsigned char buffer[] =
1236  {0x00, 0x04,
1237  0x00, /* type */
1238  0x27, 0x01,
1239  0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */
1240  0x42};
1241 
1242  smprintf(s,"Deleting item (%08x)\n", id);
1243 
1244  switch (Priv->BinaryType) {
1245  case TypeCalendar:
1246  buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
1247  break;
1248  case TypeContacts:
1249  buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1250  break;
1251  case TypeToDo:
1252  buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1253  break;
1254  }
1255 
1256  buffer[5] = (id >> 24);
1257  buffer[6] = ((id >> 16) & 0xff);
1258  buffer[7] = ((id >> 8) & 0xff);
1259  buffer[8] = (id & 0xff);
1260 
1261  error=GSM_WaitFor (s, buffer, 10, 0x02, ALCATEL_TIMEOUT, ID_AlcatelDeleteItem1);
1262  if (error != ERR_NONE) return error;
1263 
1264  error=GSM_WaitFor (s, 0, 0, 0x0, ALCATEL_TIMEOUT, ID_AlcatelDeleteItem2);
1265  if (error != ERR_NONE) return error;
1266 
1267  return ERR_NONE;
1268 }
1269 
1270 static GSM_Error ALCATEL_ReplyDeleteItem(GSM_Protocol_Message *msg, GSM_StateMachine *s UNUSED)
1271 {
1272  if (msg->Buffer[8] != 0x25) return ERR_UNKNOWNRESPONSE;
1273  return ERR_NONE;
1274 }
1275 
1276 static GSM_Error ALCATEL_BuildWriteBuffer(GSM_StateMachine *s, unsigned char * buffer, GSM_Alcatel_FieldType type, int field, void *data) {
1277  GSM_Error error;
1278 
1279  buffer[1] = field & 0xff;
1280 
1281  switch(type) {
1282  case Alcatel_date:
1283  if (!CheckDate((GSM_DateTime *)data)) return ERR_INVALIDDATETIME;
1284 
1285  buffer[3] = 0x05;
1286  buffer[4] = 0x67;
1287 
1288  buffer[0] = 0x09;
1289  buffer[5] = 0x04;
1290  buffer[6] = ((GSM_DateTime *)data)->Day & 0xff;
1291  buffer[7] = ((GSM_DateTime *)data)->Month & 0xff;
1292  buffer[8] = ((GSM_DateTime *)data)->Year >> 8;
1293  buffer[9] = ((GSM_DateTime *)data)->Year & 0xff;
1294  buffer[10] = 0x00;
1295  break;
1296  case Alcatel_time:
1297  if (!CheckTime((GSM_DateTime *)data)) return ERR_INVALIDDATETIME;
1298 
1299  buffer[3] = 0x06;
1300  buffer[4] = 0x68;
1301 
1302  buffer[0] = 0x08;
1303  buffer[5] = 0x03;
1304  buffer[6] = ((GSM_DateTime *)data)->Hour & 0xff;
1305  buffer[7] = ((GSM_DateTime *)data)->Minute & 0xff;
1306  buffer[8] = ((GSM_DateTime *)data)->Second & 0xff;
1307  buffer[9] = 0x00;
1308  break;
1309  case Alcatel_string:
1310  buffer[3] = 0x08;
1311  buffer[4] = 0x3c;
1312 
1313  error = ALCATEL_EncodeString(s, (char *)data, buffer + 5, Alcatel_string);
1314  if (error != ERR_NONE) return error;
1315  buffer[0] = 5 + buffer[5];
1316  break;
1317  case Alcatel_phone:
1318  buffer[3] = 0x07;
1319  buffer[4] = 0x3c;
1320 
1321  error = ALCATEL_EncodeString(s, (char *)data, buffer + 5, Alcatel_phone);
1322  if (error != ERR_NONE) return error;
1323  buffer[0] = 5 + buffer[5];
1324  break;
1325  case Alcatel_enum:
1326  buffer[3] = 0x04;
1327  buffer[4] = 0x38;
1328 
1329  buffer[0] = 0x05;
1330  buffer[5] = *(int *)data & 0xff;
1331  buffer[6] = 0x00;
1332  break;
1333  case Alcatel_bool:
1334  buffer[3] = 0x03;
1335  buffer[4] = 0x3b;
1336 
1337  buffer[0] = 0x05;
1338  buffer[5] = *(int *)data & 0xff;
1339  buffer[6] = 0x00;
1340  break;
1341  case Alcatel_int:
1342  buffer[3] = 0x02;
1343  buffer[4] = 0x3a;
1344 
1345  buffer[0] = 0x08;
1346  buffer[5] = *(unsigned int *)data >> 24;
1347  buffer[6] = (*(unsigned int *)data >> 16) & 0xff;
1348  buffer[7] = (*(unsigned int *)data >> 8) & 0xff;
1349  buffer[8] = *(unsigned int *)data & 0xff;
1350  buffer[9] = 0x00;
1351  break;
1352  case Alcatel_byte:
1353  buffer[3] = 0x00;
1354  buffer[4] = 0x38;
1355 
1356  buffer[0] = 0x05;
1357  buffer[5] = *(int *)data & 0xff;
1358  buffer[6] = 0x00;
1359  break;
1360  }
1361  return ERR_NONE;
1362 }
1363 
1364 static GSM_Error ALCATEL_CreateField(GSM_StateMachine *s, GSM_Alcatel_FieldType type, int field, void *data) {
1365  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1366  GSM_Error error;
1367  unsigned char buffer[200] =
1368  {0x00, 0x04,
1369  0x00, /* type */
1370  0x25, 0x01, 0x65,
1371  0x00, /* length of remaining part */
1372  0x00, /* field */
1373  0x37}; /* data follows here */
1374 
1375  smprintf(s,"Creating field (%02x)\n", field);
1376 
1377  switch (Priv->BinaryType) {
1378  case TypeCalendar:
1379  buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
1380  break;
1381  case TypeContacts:
1382  buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1383  break;
1384  case TypeToDo:
1385  buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1386  break;
1387  }
1388  error = ALCATEL_BuildWriteBuffer(s, buffer + 6, type, field, data);
1389  if (error != ERR_NONE) return error;
1390 
1391  error = GSM_WaitFor (s, buffer, 8 + buffer[6], 0x02, ALCATEL_TIMEOUT, ID_AlcatelCreateField);
1392  if (error != ERR_NONE) return error;
1393 
1394  return ERR_NONE;
1395 }
1396 
1397 static GSM_Error ALCATEL_UpdateField(GSM_StateMachine *s, GSM_Alcatel_FieldType type, int id, int field, void *data) {
1398  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1399  GSM_Error error;
1400  unsigned char buffer[50 + GSM_PHONEBOOK_TEXT_LENGTH] =
1401  {0x00, 0x04,
1402  0x00, /* type */
1403  0x26, 0x01,
1404  0x00, 0x00, 0x00, 0x00, /* id */
1405  0x65,
1406  0x00, /* length of remaining part */
1407  0x00, /* field */
1408  0x37}; /* data follows here */
1409 
1410  smprintf(s,"Updating field (%08x.%02x)\n", id, field);
1411 
1412  buffer[5] = (id >> 24);
1413  buffer[6] = ((id >> 16) & 0xff);
1414  buffer[7] = ((id >> 8) & 0xff);
1415  buffer[8] = (id & 0xff);
1416 
1417  switch (Priv->BinaryType) {
1418  case TypeCalendar:
1419  buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
1420  break;
1421  case TypeContacts:
1422  buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1423  break;
1424  case TypeToDo:
1425  buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1426  break;
1427  }
1428  error = ALCATEL_BuildWriteBuffer(s, buffer + 10, type, field, data);
1429  if (error != ERR_NONE) return error;
1430 
1431  error = GSM_WaitFor (s, buffer, 12 + buffer[10], 0x02, ALCATEL_TIMEOUT, ID_AlcatelUpdateField);
1432  if (error != ERR_NONE) return error;
1433 
1434  return ERR_NONE;
1435 }
1436 
1437 static GSM_Error ALCATEL_GetManufacturer(GSM_StateMachine *s)
1438 {
1439  strcpy(s->Phone.Data.Manufacturer, "Alcatel");
1440  return ERR_NONE;
1441 }
1442 
1443 static GSM_Error ALCATEL_GetIMEI (GSM_StateMachine *s)
1444 {
1445  GSM_Error error;
1446 
1447  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
1448  return ATGEN_GetIMEI(s);
1449 }
1450 
1451 static GSM_Error ALCATEL_GetFirmware(GSM_StateMachine *s)
1452 {
1453  GSM_Error error;
1454 
1455  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
1456  return ATGEN_GetFirmware(s);
1457 }
1458 
1459 static GSM_Error ALCATEL_GetModel(GSM_StateMachine *s)
1460 {
1461  GSM_Error error;
1462 
1463  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
1464  return ATGEN_GetModel(s);
1465 }
1466 
1467 static GSM_Error ALCATEL_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
1468 {
1469  GSM_Error error;
1470 
1471  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
1472  return ATGEN_GetDateTime(s, date_time);
1473 }
1474 
1475 static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1476 {
1477  GSM_Error error;
1478  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1479  int i;
1480  int j = 0;
1481 
1482  if (entry->MemoryType == MEM_ME) {
1483  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error;
1484  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
1485  if ((error = ALCATEL_IsIdAvailable(s, entry->Location))!= ERR_NONE) {
1486  entry->EntriesNum = 0;
1487  return error;
1488  }
1489  if ((error = ALCATEL_GetFields(s, entry->Location))!= ERR_NONE) return error;
1490 
1491  entry->EntriesNum = Priv->CurrentFieldsCount;
1492 
1493  for (i=0; i<Priv->CurrentFieldsCount; i++) {
1494  if ((error = ALCATEL_GetFieldValue(s, entry->Location, Priv->CurrentFields[i]))!= ERR_NONE) return error;
1495  entry->Entries[i].VoiceTag = 0;
1496  entry->Entries[i].SMSList[0] = 0;
1497  switch (Priv->CurrentFields[i]) {
1498  case 0:
1499  if (Priv->ReturnType != Alcatel_string) {
1500  smprintf(s,"WARNING: Received unexpected type %02X for field 0, ignoring\n", Priv->ReturnType);
1501  entry->EntriesNum--;
1502  j++;
1503  break;
1504  }
1505  entry->Entries[i - j].EntryType = PBK_Text_LastName;
1506  entry->Entries[i - j].Location = PBK_Location_Unknown;
1507  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1508  break;
1509  case 1:
1510  if (Priv->ReturnType != Alcatel_string) {
1511  smprintf(s,"WARNING: Received unexpected type %02X for field 1, ignoring\n", Priv->ReturnType);
1512  entry->EntriesNum--;
1513  j++;
1514  break;
1515  }
1516  entry->Entries[i - j].EntryType = PBK_Text_FirstName;
1517  entry->Entries[i - j].Location = PBK_Location_Unknown;
1518  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1519  break;
1520  case 2:
1521  if (Priv->ReturnType != Alcatel_string) {
1522  smprintf(s,"WARNING: Received unexpected type %02X for field 2, ignoring\n", Priv->ReturnType);
1523  entry->EntriesNum--;
1524  j++;
1525  break;
1526  }
1527  entry->Entries[i - j].EntryType = PBK_Text_Company;
1528  entry->Entries[i - j].Location = PBK_Location_Unknown;
1529  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1530  break;
1531  case 3:
1532  if (Priv->ReturnType != Alcatel_string) {
1533  smprintf(s,"WARNING: Received unexpected type %02X for field 3, ignoring\n", Priv->ReturnType);
1534  entry->EntriesNum--;
1535  j++;
1536  break;
1537  }
1538  entry->Entries[i - j].EntryType = PBK_Text_JobTitle;
1539  entry->Entries[i - j].Location = PBK_Location_Unknown;
1540  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1541  break;
1542  case 4:
1543  if (Priv->ReturnType != Alcatel_string) {
1544  smprintf(s,"WARNING: Received unexpected type %02X for field 4, ignoring\n", Priv->ReturnType);
1545  entry->EntriesNum--;
1546  j++;
1547  break;
1548  }
1549  entry->Entries[i - j].EntryType = PBK_Text_Note;
1550  entry->Entries[i - j].Location = PBK_Location_Unknown;
1551  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1552  break;
1553  case 5:
1554  if (Priv->ReturnType != Alcatel_byte) {
1555  smprintf(s,"WARNING: Received unexpected type %02X for field 5, ignoring\n", Priv->ReturnType);
1556  entry->EntriesNum--;
1557  j++;
1558  break;
1559  }
1560  entry->Entries[i - j].EntryType = PBK_Category;
1561  entry->Entries[i - j].Location = PBK_Location_Unknown;
1562  entry->Entries[i - j].Number = Priv->ReturnInt;
1563  break;
1564  case 6:
1565  if (Priv->ReturnType != Alcatel_bool) {
1566  smprintf(s,"WARNING: Received unexpected type %02X for field 6, ignoring\n", Priv->ReturnType);
1567  entry->EntriesNum--;
1568  j++;
1569  break;
1570  }
1571  entry->Entries[i - j].EntryType = PBK_Private;
1572  entry->Entries[i - j].Location = PBK_Location_Unknown;
1573  entry->Entries[i - j].Number = Priv->ReturnInt;
1574  break;
1575  case 7:
1576  if (Priv->ReturnType != Alcatel_phone) {
1577  smprintf(s,"WARNING: Received unexpected type %02X for field 7, ignoring\n", Priv->ReturnType);
1578  entry->EntriesNum--;
1579  j++;
1580  break;
1581  }
1582  entry->Entries[i - j].EntryType = PBK_Number_General;
1583  entry->Entries[i - j].Location = PBK_Location_Work;
1584  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1585  break;
1586  case 8:
1587  if (Priv->ReturnType != Alcatel_phone) {
1588  smprintf(s,"WARNING: Received unexpected type %02X for field 8, ignoring\n", Priv->ReturnType);
1589  entry->EntriesNum--;
1590  j++;
1591  break;
1592  }
1593  entry->Entries[i - j].EntryType = PBK_Number_General;
1594  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1595  break;
1596  case 9:
1597  if (Priv->ReturnType != Alcatel_phone) {
1598  smprintf(s,"WARNING: Received unexpected type %02X for field 9, ignoring\n", Priv->ReturnType);
1599  entry->EntriesNum--;
1600  j++;
1601  break;
1602  }
1603  entry->Entries[i - j].EntryType = PBK_Number_Fax;
1604  entry->Entries[i - j].Location = PBK_Location_Unknown;
1605  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1606  break;
1607  case 10:
1608  if (Priv->ReturnType != Alcatel_phone) {
1609  smprintf(s,"WARNING: Received unexpected type %02X for field 10, ignoring\n", Priv->ReturnType);
1610  entry->EntriesNum--;
1611  j++;
1612  break;
1613  }
1614  entry->Entries[i - j].EntryType = PBK_Number_Other;
1615  entry->Entries[i - j].Location = PBK_Location_Unknown;
1616  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1617  break;
1618  case 11:
1619  if (Priv->ReturnType != Alcatel_phone) {
1620  smprintf(s,"WARNING: Received unexpected type %02X for field 11, ignoring\n", Priv->ReturnType);
1621  entry->EntriesNum--;
1622  j++;
1623  break;
1624  }
1625  entry->Entries[i - j].EntryType = PBK_Number_Pager;
1626  entry->Entries[i - j].Location = PBK_Location_Unknown;
1627  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1628  break;
1629  case 12:
1630  if (Priv->ReturnType != Alcatel_phone) {
1631  smprintf(s,"WARNING: Received unexpected type %02X for field 12, ignoring\n", Priv->ReturnType);
1632  entry->EntriesNum--;
1633  j++;
1634  break;
1635  }
1636  entry->Entries[i - j].EntryType = PBK_Number_Mobile;
1637  entry->Entries[i - j].Location = PBK_Location_Unknown;
1638  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1639  break;
1640  case 13:
1641  if (Priv->ReturnType != Alcatel_phone) {
1642  smprintf(s,"WARNING: Received unexpected type %02X for field 13, ignoring\n", Priv->ReturnType);
1643  entry->EntriesNum--;
1644  j++;
1645  break;
1646  }
1647  entry->Entries[i - j].EntryType = PBK_Number_General;
1648  entry->Entries[i - j].Location = PBK_Location_Home;
1649  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1650  break;
1651  case 14:
1652  if (Priv->ReturnType != Alcatel_string) {
1653  smprintf(s,"WARNING: Received unexpected type %02X for field 14, ignoring\n", Priv->ReturnType);
1654  entry->EntriesNum--;
1655  j++;
1656  break;
1657  }
1658  entry->Entries[i - j].EntryType = PBK_Text_Email;
1659  entry->Entries[i - j].Location = PBK_Location_Unknown;
1660  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1661  break;
1662  case 15:
1663  if (Priv->ReturnType != Alcatel_string) {
1664  smprintf(s,"WARNING: Received unexpected type %02X for field 15, ignoring\n", Priv->ReturnType);
1665  entry->EntriesNum--;
1666  j++;
1667  break;
1668  }
1669  entry->Entries[i - j].EntryType = PBK_Text_Email2;
1670  entry->Entries[i - j].Location = PBK_Location_Unknown;
1671  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1672  break;
1673  case 16:
1674  if (Priv->ReturnType != Alcatel_string) {
1675  smprintf(s,"WARNING: Received unexpected type %02X for field 16, ignoring\n", Priv->ReturnType);
1676  entry->EntriesNum--;
1677  j++;
1678  break;
1679  }
1680  entry->Entries[i - j].EntryType = PBK_Text_StreetAddress;
1681  entry->Entries[i - j].Location = PBK_Location_Unknown;
1682  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1683  break;
1684  case 17:
1685  if (Priv->ReturnType != Alcatel_string) {
1686  smprintf(s,"WARNING: Received unexpected type %02X for field 17, ignoring\n", Priv->ReturnType);
1687  entry->EntriesNum--;
1688  j++;
1689  break;
1690  }
1691  entry->Entries[i - j].EntryType = PBK_Text_City;
1692  entry->Entries[i - j].Location = PBK_Location_Unknown;
1693  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1694  break;
1695  case 18:
1696  if (Priv->ReturnType != Alcatel_string) {
1697  smprintf(s,"WARNING: Received unexpected type %02X for field 18, ignoring\n", Priv->ReturnType);
1698  entry->EntriesNum--;
1699  j++;
1700  break;
1701  }
1702  entry->Entries[i - j].EntryType = PBK_Text_State;
1703  entry->Entries[i - j].Location = PBK_Location_Unknown;
1704  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1705  break;
1706  case 19:
1707  if (Priv->ReturnType != Alcatel_string) {
1708  smprintf(s,"WARNING: Received unexpected type %02X for field 19, ignoring\n", Priv->ReturnType);
1709  entry->EntriesNum--;
1710  j++;
1711  break;
1712  }
1713  entry->Entries[i - j].EntryType = PBK_Text_Zip;
1714  entry->Entries[i - j].Location = PBK_Location_Unknown;
1715  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1716  break;
1717  case 20:
1718  if (Priv->ReturnType != Alcatel_string) {
1719  smprintf(s,"WARNING: Received unexpected type %02X for field 20, ignoring\n", Priv->ReturnType);
1720  entry->EntriesNum--;
1721  j++;
1722  break;
1723  }
1724  entry->Entries[i - j].EntryType = PBK_Text_Country;
1725  entry->Entries[i - j].Location = PBK_Location_Unknown;
1726  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1727  break;
1728  case 21:
1729  if (Priv->ReturnType != Alcatel_string) {
1730  smprintf(s,"WARNING: Received unexpected type %02X for field 21, ignoring\n", Priv->ReturnType);
1731  entry->EntriesNum--;
1732  j++;
1733  break;
1734  }
1735  entry->Entries[i - j].EntryType = PBK_Text_Custom1;
1736  entry->Entries[i - j].Location = PBK_Location_Unknown;
1737  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1738  break;
1739  case 22:
1740  if (Priv->ReturnType != Alcatel_string) {
1741  smprintf(s,"WARNING: Received unexpected type %02X for field 22, ignoring\n", Priv->ReturnType);
1742  entry->EntriesNum--;
1743  j++;
1744  break;
1745  }
1746  entry->Entries[i - j].EntryType = PBK_Text_Custom2;
1747  entry->Entries[i - j].Location = PBK_Location_Unknown;
1748  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1749  break;
1750  case 23:
1751  if (Priv->ReturnType != Alcatel_string) {
1752  smprintf(s,"WARNING: Received unexpected type %02X for field 23, ignoring\n", Priv->ReturnType);
1753  entry->EntriesNum--;
1754  j++;
1755  break;
1756  }
1757  entry->Entries[i - j].EntryType = PBK_Text_Custom3;
1758  entry->Entries[i - j].Location = PBK_Location_Unknown;
1759  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1760  break;
1761  case 24:
1762  if (Priv->ReturnType != Alcatel_string) {
1763  smprintf(s,"WARNING: Received unexpected type %02X for field 24, ignoring\n", Priv->ReturnType);
1764  entry->EntriesNum--;
1765  j++;
1766  break;
1767  }
1768  entry->Entries[i - j].EntryType = PBK_Text_Custom4;
1769  entry->Entries[i - j].Location = PBK_Location_Unknown;
1770  CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1771  break;
1772  case 25:
1773  if (Priv->ReturnType != Alcatel_int) {
1774  smprintf(s,"WARNING: Received unexpected type %02X for field 25, ignoring\n", Priv->ReturnType);
1775  entry->EntriesNum--;
1776  j++;
1777  break;
1778  }
1779  if (Priv->ReturnInt != 0) {
1780  entry->Entries[i - j].EntryType = PBK_PictureID;
1781  entry->Entries[i - j].Location = PBK_Location_Unknown;
1782  entry->Entries[i - j].Number = Priv->ReturnInt;
1783  } else {
1784  entry->EntriesNum--;
1785  j++;
1786  }
1787  break;
1788  default:
1789  entry->EntriesNum--;
1790  j++;
1791  smprintf(s,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv->CurrentFields[i], Priv->ReturnType);
1792  switch (Priv->ReturnType) {
1793  case Alcatel_date:
1794  smprintf(s, "%d.%d.%d", Priv->ReturnDateTime.Day, Priv->ReturnDateTime.Month, Priv->ReturnDateTime.Year);
1795  break;
1796  case Alcatel_time:
1797  smprintf(s, "%d:%d:%d", Priv->ReturnDateTime.Hour, Priv->ReturnDateTime.Minute, Priv->ReturnDateTime.Second);
1798  break;
1799  case Alcatel_string:
1800  case Alcatel_phone:
1801  smprintf(s, "\"%s\"",DecodeUnicodeString(Priv->ReturnString));
1802  break;
1803  case Alcatel_enum:
1804  case Alcatel_bool:
1805  case Alcatel_int:
1806  case Alcatel_byte:
1807  smprintf(s, "%d", Priv->ReturnInt);
1808  break;
1809  }
1810  smprintf(s,"\n");
1811  }
1812  }
1813  return ERR_NONE;
1814  } else {
1815  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
1816  return ATGEN_GetMemory(s, entry);
1817  }
1818 }
1819 
1820 static GSM_Error ALCATEL_GetNextMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry, gboolean start)
1821 {
1822  GSM_Error error;
1823  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1824 
1825  if (entry->MemoryType == MEM_ME) {
1826  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error;
1827  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
1828  if (Priv->ContactsItemsCount == 0) return ERR_EMPTY;
1829 
1830  if (start) entry->Location = 0;
1831  if ((error = ALCATEL_GetNextId(s, &(entry->Location))) != ERR_NONE) return error;
1832 
1833  return ALCATEL_GetMemory(s, entry);
1834  } else {
1835  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
1836  return ATGEN_GetNextMemory(s, entry, start);
1837  }
1838 }
1839 
1840 static GSM_Error ALCATEL_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1841 {
1842  GSM_Error error;
1843  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1844  int NamePosition = -1;
1845  gboolean NameSet = FALSE;
1846  int i;
1847 
1848 
1849  if (entry->MemoryType == MEM_ME) {
1850  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error;
1851  if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeContacts, 0))!= ERR_NONE) return error;
1852  for (i = 0; i < entry->EntriesNum; i++) {
1853  entry->Entries[i].AddError = ERR_NONE;
1854  switch (entry->Entries[i].EntryType) {
1855  case PBK_Number_General:
1856  switch (entry->Entries[i].Location) {
1857  case PBK_Location_Unknown:
1858  if ((error = ALCATEL_CreateField(s, Alcatel_phone, 8, entry->Entries[i].Text)) != ERR_NONE) return error;
1859  break;
1860  case PBK_Location_Work:
1861  if ((error = ALCATEL_CreateField(s, Alcatel_phone, 7, entry->Entries[i].Text)) != ERR_NONE) return error;
1862  break;
1863  case PBK_Location_Home:
1864  if ((error = ALCATEL_CreateField(s, Alcatel_phone, 13, entry->Entries[i].Text)) != ERR_NONE) return error;
1865  break;
1866  }
1867  break;
1868  case PBK_Number_Mobile:
1869  if ((error = ALCATEL_CreateField(s, Alcatel_phone, 12, entry->Entries[i].Text)) != ERR_NONE) return error;
1870  break;
1871  case PBK_Number_Fax:
1872  if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, entry->Entries[i].Text)) != ERR_NONE) return error;
1873  break;
1874  case PBK_Number_Pager:
1875  if ((error = ALCATEL_CreateField(s, Alcatel_phone, 11, entry->Entries[i].Text)) != ERR_NONE) return error;
1876  break;
1877  case PBK_Number_Other:
1878  if ((error = ALCATEL_CreateField(s, Alcatel_phone, 10, entry->Entries[i].Text)) != ERR_NONE) return error;
1879  break;
1880  case PBK_Text_Note:
1881  if ((error = ALCATEL_CreateField(s, Alcatel_string, 4, entry->Entries[i].Text)) != ERR_NONE) return error;
1882  break;
1883  case PBK_Text_Email:
1884  if ((error = ALCATEL_CreateField(s, Alcatel_string, 14, entry->Entries[i].Text)) != ERR_NONE) return error;
1885  break;
1886  case PBK_Text_Email2:
1887  if ((error = ALCATEL_CreateField(s, Alcatel_string, 15, entry->Entries[i].Text)) != ERR_NONE) return error;
1888  break;
1889  case PBK_Text_LastName:
1890  if ((error = ALCATEL_CreateField(s, Alcatel_string, 0, entry->Entries[i].Text)) != ERR_NONE) return error;
1891  NameSet = TRUE;
1892  break;
1893  case PBK_Text_FirstName:
1894  if ((error = ALCATEL_CreateField(s, Alcatel_string, 1, entry->Entries[i].Text)) != ERR_NONE) return error;
1895  NameSet = TRUE;
1896  break;
1897  case PBK_Text_Company:
1898  if ((error = ALCATEL_CreateField(s, Alcatel_string, 2, entry->Entries[i].Text)) != ERR_NONE) return error;
1899  break;
1900  case PBK_Text_JobTitle:
1901  if ((error = ALCATEL_CreateField(s, Alcatel_string, 3, entry->Entries[i].Text)) != ERR_NONE) return error;
1902  break;
1903  case PBK_Category:
1904  if ((error = ALCATEL_CreateField(s, Alcatel_byte, 5, &(entry->Entries[i].Number))) != ERR_NONE) return error;
1905  break;
1906  case PBK_Private:
1907  if ((error = ALCATEL_CreateField(s, Alcatel_bool, 6, &(entry->Entries[i].Number))) != ERR_NONE) return error;
1908  break;
1910  if ((error = ALCATEL_CreateField(s, Alcatel_string, 16, entry->Entries[i].Text)) != ERR_NONE) return error;
1911  break;
1912  case PBK_Text_City:
1913  if ((error = ALCATEL_CreateField(s, Alcatel_string, 17, entry->Entries[i].Text)) != ERR_NONE) return error;
1914  break;
1915  case PBK_Text_State:
1916  if ((error = ALCATEL_CreateField(s, Alcatel_string, 18, entry->Entries[i].Text)) != ERR_NONE) return error;
1917  break;
1918  case PBK_Text_Zip:
1919  if ((error = ALCATEL_CreateField(s, Alcatel_string, 19, entry->Entries[i].Text)) != ERR_NONE) return error;
1920  break;
1921  case PBK_Text_Country:
1922  if ((error = ALCATEL_CreateField(s, Alcatel_string, 20, entry->Entries[i].Text)) != ERR_NONE) return error;
1923  break;
1924  case PBK_Text_Custom1:
1925  if ((error = ALCATEL_CreateField(s, Alcatel_string, 21, entry->Entries[i].Text)) != ERR_NONE) return error;
1926  break;
1927  case PBK_Text_Custom2:
1928  if ((error = ALCATEL_CreateField(s, Alcatel_string, 22, entry->Entries[i].Text)) != ERR_NONE) return error;
1929  break;
1930  case PBK_Text_Custom3:
1931  if ((error = ALCATEL_CreateField(s, Alcatel_string, 23, entry->Entries[i].Text)) != ERR_NONE) return error;
1932  break;
1933  case PBK_Text_Custom4:
1934  if ((error = ALCATEL_CreateField(s, Alcatel_string, 24, entry->Entries[i].Text)) != ERR_NONE) return error;
1935  break;
1936  case PBK_PictureID:
1937  if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) {
1938  if ((error = ALCATEL_CreateField(s, Alcatel_int, 25, &(entry->Entries[i].Number))) != ERR_NONE) return error;
1939  } else {
1940  entry->Entries[i].AddError = ERR_NOTSUPPORTED;
1941  smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType);
1942  }
1943  break;
1944 
1945  case PBK_Text_Name: NamePosition = i; break;
1946  /* Following fields are not supported: */
1947  case PBK_Text_UserID:
1948  case PBK_Date:
1949  case PBK_LastModified:
1950  case PBK_Caller_Group:
1951  case PBK_RingtoneID:
1952  case PBK_Text_Postal:
1953  case PBK_Text_URL:
1954  case PBK_Text_LUID:
1955  case PBK_Text_VOIP:
1956  case PBK_Text_SWIS:
1957  case PBK_Text_WVID:
1958  case PBK_Text_SIP:
1959  case PBK_Text_DTMF:
1960  case PBK_CallLength:
1961  case PBK_Text_NickName:
1962  case PBK_Text_FormalName:
1963  case PBK_Text_NameSuffix:
1964  case PBK_Text_NamePrefix:
1965  case PBK_Text_PictureName:
1966  case PBK_PushToTalkID:
1967  case PBK_Number_Messaging:
1968  case PBK_Number_Video:
1969  case PBK_Photo:
1970  case PBK_Text_SecondName:
1971  entry->Entries[i].AddError = ERR_NOTSUPPORTED;
1972  smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType);
1973  break;
1974  }
1975  }
1976  if (NamePosition != -1) {
1977  if (NameSet) {
1978  entry->Entries[NamePosition].AddError = ERR_NOTSUPPORTED;
1979  smprintf(s,"WARNING: Ignoring name, not supported by phone\n");
1980  } else {
1981  if ((error = ALCATEL_CreateField(s, Alcatel_string, 1, entry->Entries[i].Text)) != ERR_NONE) return error;
1982  }
1983  }
1984  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error;
1985  entry->Location = Priv->CommitedRecord;
1986  /* Refresh list */
1987  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
1988  return ERR_NONE;
1989  } else {
1990  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
1991  return ATGEN_AddMemory(s, entry);
1992  }
1993 }
1994 
1995 static GSM_Error ALCATEL_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1996 {
1997  GSM_Error error;
1998  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1999  int NamePosition = -1;
2000  gboolean NameSet = FALSE;
2001  int i;
2002  gboolean UpdatedFields[26];
2003 
2004  if (entry->Location == 0) return ERR_INVALIDLOCATION;
2005 
2006  if (entry->MemoryType == MEM_ME) {
2007  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error;
2008  /* Save modified entry */
2009  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
2010  if ((error = ALCATEL_IsIdAvailable(s, entry->Location))!= ERR_NONE) {
2011  /* Entry doesn't exist, we will create new one */
2012  return ALCATEL_AddMemory(s, entry);
2013  }
2014  /* Get fields for current item */
2015  if ((error = ALCATEL_GetFields(s, entry->Location))!= ERR_NONE) return error;
2016 
2017  for (i = 0; i < 26; i++) { UpdatedFields[i] = FALSE; }
2018 
2019  if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeContacts, entry->Location))!= ERR_NONE) return error;
2020  for (i = 0; i < entry->EntriesNum; i++) {
2021  entry->Entries[i].AddError = ERR_NONE;
2022  switch (entry->Entries[i].EntryType) {
2023  case PBK_Number_General:
2024  switch (entry->Entries[i].Location) {
2025  case PBK_Location_Unknown:
2026  UpdatedFields[8] = TRUE;
2027  if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 8, entry->Entries[i].Text)) != ERR_NONE) return error;
2028  break;
2029  case PBK_Location_Work:
2030  UpdatedFields[7] = TRUE;
2031  if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 7, entry->Entries[i].Text)) != ERR_NONE) return error;
2032  break;
2033  case PBK_Location_Home:
2034  UpdatedFields[13] = TRUE;
2035  if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 13, entry->Entries[i].Text)) != ERR_NONE) return error;
2036  break;
2037  }
2038  break;
2039  case PBK_Number_Mobile:
2040  UpdatedFields[12] = TRUE;
2041  if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 12, entry->Entries[i].Text)) != ERR_NONE) return error;
2042  break;
2043  case PBK_Number_Fax:
2044  UpdatedFields[9] = TRUE;
2045  if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 9, entry->Entries[i].Text)) != ERR_NONE) return error;
2046  break;
2047  case PBK_Number_Pager:
2048  UpdatedFields[11] = TRUE;
2049  if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 11, entry->Entries[i].Text)) != ERR_NONE) return error;
2050  break;
2051  case PBK_Number_Other:
2052  UpdatedFields[10] = TRUE;
2053  if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 10, entry->Entries[i].Text)) != ERR_NONE) return error;
2054  break;
2055  case PBK_Text_Note:
2056  UpdatedFields[4] = TRUE;
2057  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 4, entry->Entries[i].Text)) != ERR_NONE) return error;
2058  break;
2059  case PBK_Text_Email:
2060  UpdatedFields[14] = TRUE;
2061  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 14, entry->Entries[i].Text)) != ERR_NONE) return error;
2062  break;
2063  case PBK_Text_Email2:
2064  UpdatedFields[15] = TRUE;
2065  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 15, entry->Entries[i].Text)) != ERR_NONE) return error;
2066  break;
2067  case PBK_Text_LastName:
2068  UpdatedFields[0] = TRUE;
2069  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 0, entry->Entries[i].Text)) != ERR_NONE) return error;
2070  NameSet = TRUE;
2071  break;
2072  case PBK_Text_FirstName:
2073  UpdatedFields[1] = TRUE;
2074  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 1, entry->Entries[i].Text)) != ERR_NONE) return error;
2075  NameSet = TRUE;
2076  break;
2077  case PBK_Text_Company:
2078  UpdatedFields[2] = TRUE;
2079  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 2, entry->Entries[i].Text)) != ERR_NONE) return error;
2080  break;
2081  case PBK_Text_JobTitle:
2082  UpdatedFields[3] = TRUE;
2083  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 3, entry->Entries[i].Text)) != ERR_NONE) return error;
2084  break;
2085  case PBK_Category:
2086  UpdatedFields[5] = TRUE;
2087  if ((error = ALCATEL_UpdateField(s, Alcatel_byte, entry->Location, 5, &(entry->Entries[i].Number))) != ERR_NONE) return error;
2088  break;
2089  case PBK_Private:
2090  UpdatedFields[6] = TRUE;
2091  if ((error = ALCATEL_UpdateField(s, Alcatel_bool, entry->Location, 6, &(entry->Entries[i].Number))) != ERR_NONE) return error;
2092  break;
2094  UpdatedFields[16] = TRUE;
2095  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 16, entry->Entries[i].Text)) != ERR_NONE) return error;
2096  break;
2097  case PBK_Text_City:
2098  UpdatedFields[17] = TRUE;
2099  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 17, entry->Entries[i].Text)) != ERR_NONE) return error;
2100  break;
2101  case PBK_Text_State:
2102  UpdatedFields[18] = TRUE;
2103  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 18, entry->Entries[i].Text)) != ERR_NONE) return error;
2104  break;
2105  case PBK_Text_Zip:
2106  UpdatedFields[19] = TRUE;
2107  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 19, entry->Entries[i].Text)) != ERR_NONE) return error;
2108  break;
2109  case PBK_Text_Country:
2110  UpdatedFields[20] = TRUE;
2111  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 20, entry->Entries[i].Text)) != ERR_NONE) return error;
2112  break;
2113  case PBK_Text_Custom1:
2114  UpdatedFields[21] = TRUE;
2115  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 21, entry->Entries[i].Text)) != ERR_NONE) return error;
2116  break;
2117  case PBK_Text_Custom2:
2118  UpdatedFields[22] = TRUE;
2119  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 22, entry->Entries[i].Text)) != ERR_NONE) return error;
2120  break;
2121  case PBK_Text_Custom3:
2122  UpdatedFields[23] = TRUE;
2123  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 23, entry->Entries[i].Text)) != ERR_NONE) return error;
2124  break;
2125  case PBK_Text_Custom4:
2126  UpdatedFields[24] = TRUE;
2127  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 24, entry->Entries[i].Text)) != ERR_NONE) return error;
2128  break;
2129  case PBK_PictureID:
2130  if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) {
2131  UpdatedFields[25] = TRUE;
2132  if ((error = ALCATEL_UpdateField(s, Alcatel_int, entry->Location, 25, &(entry->Entries[i].Number))) != ERR_NONE) return error;
2133  } else {
2134  smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType);
2135  entry->Entries[i].AddError = ERR_NOTSUPPORTED;
2136  }
2137  break;
2138  case PBK_Text_Name: NamePosition = i; break;
2139  /* Following fields are not supported: */
2140  case PBK_Text_UserID:
2141  case PBK_Date:
2142  case PBK_LastModified:
2143  case PBK_Caller_Group:
2144  case PBK_RingtoneID:
2145  case PBK_Text_Postal:
2146  case PBK_Text_URL:
2147  case PBK_Text_LUID:
2148  case PBK_Text_VOIP:
2149  case PBK_Text_SWIS:
2150  case PBK_Text_WVID:
2151  case PBK_Text_SIP:
2152  case PBK_Text_DTMF:
2153  case PBK_CallLength:
2154  case PBK_Text_NickName:
2155  case PBK_Text_FormalName:
2156  case PBK_Text_NameSuffix:
2157  case PBK_Text_NamePrefix:
2158  case PBK_Text_PictureName:
2159  case PBK_PushToTalkID:
2160  case PBK_Number_Messaging:
2161  case PBK_Number_Video:
2162  case PBK_Photo:
2163  case PBK_Text_SecondName:
2164  entry->Entries[i].AddError = ERR_NOTSUPPORTED;
2165  smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType);
2166  break;
2167  }
2168  }
2169  if (NamePosition != -1) {
2170  if (NameSet) {
2171  entry->Entries[NamePosition].AddError = ERR_NOTSUPPORTED;
2172  smprintf(s,"WARNING: Ignoring name, not supported by phone\n");
2173  } else {
2174  /* mw: fixme ? */
2175  UpdatedFields[1] = TRUE;
2176  if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 1, entry->Entries[i].Text)) != ERR_NONE) return error;
2177  }
2178  }
2179  /* If we didn't update some field, we have to delete it... */
2180  for (i=0; i<Priv->CurrentFieldsCount; i++) {
2181  if (!UpdatedFields[Priv->CurrentFields[i]]) if ((error = ALCATEL_DeleteField(s, entry->Location, Priv->CurrentFields[i])) != ERR_NONE) return error;
2182  }
2183  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error;
2184  entry->Location = Priv->CommitedRecord;
2185  return ERR_NONE;
2186  } else {
2187  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2188  return ATGEN_SetMemory(s, entry);
2189  }
2190 }
2191 
2192 static GSM_Error ALCATEL_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
2193 {
2194  GSM_Error error;
2195 
2196  if (entry->MemoryType == MEM_ME) {
2197  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error;
2198  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
2199  if ((error = ALCATEL_IsIdAvailable(s, entry->Location))!= ERR_NONE) {
2200  /* Entry was empty => no error */
2201  return ERR_NONE;
2202  }
2203  /* Do real delete */
2204  error = ALCATEL_DeleteItem(s, entry->Location);
2205  if (error != ERR_NONE) return error;
2206 
2207  /* Refresh list */
2208  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error;
2209  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
2210 
2211  return ERR_NONE;
2212  } else {
2213  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2214  return ATGEN_DeleteMemory(s, entry);
2215  }
2216 }
2217 
2218 static GSM_Error ALCATEL_DeleteAllMemory(GSM_StateMachine *s, GSM_MemoryType type)
2219 {
2220  GSM_Error error;
2221  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2222  int i;
2223 
2224  if (type == MEM_ME) {
2225  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error;
2226  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
2227 
2228  for (i=0; i<Priv->ContactsItemsCount; i++) {
2229  error = ALCATEL_DeleteItem(s, Priv->ContactsItems[i]);
2230  if (error != ERR_NONE) return error;
2231  }
2232 
2233  /* Refresh list */
2234  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error;
2235  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
2236 
2237  return ERR_NONE;
2238  } else {
2239  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2240  return ATGEN_DeleteAllMemory(s, type);
2241  }
2242 }
2243 
2244 static GSM_Error ALCATEL_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
2245 {
2246  GSM_Error error;
2247 
2248  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2249  return ATGEN_GetSMSC(s, smsc);
2250 }
2251 
2252 
2253 static GSM_Error ALCATEL_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status)
2254 {
2255  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2256  GSM_Error error;
2257 
2258  if (Status->MemoryType == MEM_ME) {
2259  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= ERR_NONE) return error;
2260  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
2261  Status->MemoryUsed = Priv->ContactsItemsCount;
2262  Status->MemoryFree = ALCATEL_FREE_MEMORY;
2263  return ERR_NONE;
2264  } else {
2265  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2266  return ATGEN_GetMemoryStatus(s, Status);
2267  }
2268 }
2269 
2270 static GSM_Error ALCATEL_GetSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms)
2271 {
2272  GSM_Error error;
2273 
2274  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2275  return ATGEN_GetSMS(s, sms);
2276 }
2277 
2278 static GSM_Error ALCATEL_DeleteSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2279 {
2280  GSM_Error error;
2281 
2282  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2283  return ATGEN_DeleteSMS(s, sms);
2284 }
2285 
2286 static GSM_Error ALCATEL_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2287 {
2288  GSM_Error error;
2289 
2290  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2291  return ATGEN_AddSMS(s, sms);
2292 }
2293 
2294 static GSM_Error ALCATEL_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat)
2295 {
2296  GSM_Error error;
2297 
2298  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2299  return ATGEN_GetBatteryCharge(s, bat);
2300 }
2301 
2302 static GSM_Error ALCATEL_GetSignalStrength(GSM_StateMachine *s, GSM_SignalQuality *sig)
2303 {
2304  GSM_Error error;
2305 
2306  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2307  return ATGEN_GetSignalQuality(s, sig);
2308 }
2309 
2310 static GSM_Error ALCATEL_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders)
2311 {
2312  GSM_Error error;
2313 
2314  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2315  return ATGEN_GetSMSFolders(s, folders);
2316 }
2317 
2318 static GSM_Error ALCATEL_GetNextSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboolean start)
2319 {
2320  GSM_Error error;
2321 
2322  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2323  return ATGEN_GetNextSMS(s, sms, start);
2324 }
2325 
2326 static GSM_Error ALCATEL_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status)
2327 {
2328  GSM_Error error;
2329 
2330  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2331  return ATGEN_GetSMSStatus(s, status);
2332 }
2333 
2334 static GSM_Error ALCATEL_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber)
2335 {
2336  GSM_Error error;
2337 
2338  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2339  return ATGEN_DialVoice(s, number, ShowNumber);
2340 }
2341 
2342 static GSM_Error ALCATEL_DialService(GSM_StateMachine *s, char *number)
2343 {
2344  GSM_Error error;
2345 
2346  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2347  return ATGEN_DialService(s, number);
2348 }
2349 
2350 static GSM_Error ALCATEL_AnswerCall(GSM_StateMachine *s, int ID, gboolean all)
2351 {
2352  GSM_Error error;
2353 
2354  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2355  return ATGEN_AnswerCall(s,ID,all);
2356 }
2357 
2358 static GSM_Error ALCATEL_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo)
2359 {
2360  GSM_Error error;
2361 
2362  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2363  return ATGEN_GetNetworkInfo(s, netinfo);
2364 }
2365 
2366 static GSM_Error ALCATEL_GetDisplayStatus(GSM_StateMachine *s, GSM_DisplayFeatures *features)
2367 {
2368  GSM_Error error;
2369 
2370  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2371  return ATGEN_GetDisplayStatus(s, features);
2372 }
2373 
2374 static GSM_Error ALCATEL_SetAutoNetworkLogin(GSM_StateMachine *s)
2375 {
2376  GSM_Error error;
2377 
2378  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2379  return ATGEN_SetAutoNetworkLogin(s);
2380 }
2381 
2382 static GSM_Error ALCATEL_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, gboolean Press)
2383 {
2384  GSM_Error error;
2385 
2386  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2387  return ATGEN_PressKey(s, Key, Press);
2388 }
2389 
2390 static GSM_Error ALCATEL_Reset(GSM_StateMachine *s, gboolean hard)
2391 {
2392  GSM_Error error;
2393 
2394  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2395  return ATGEN_Reset(s, hard);
2396 }
2397 
2398 static GSM_Error ALCATEL_CancelCall(GSM_StateMachine *s, int ID, gboolean all)
2399 {
2400  GSM_Error error;
2401 
2402  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2403  return ATGEN_CancelCall(s,ID,all);
2404 }
2405 
2406 static GSM_Error ALCATEL_SendSavedSMS(GSM_StateMachine *s, int Folder, int Location)
2407 {
2408  GSM_Error error;
2409 
2410  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2411  return ATGEN_SendSavedSMS(s, Folder, Location);
2412 }
2413 
2414 static GSM_Error ALCATEL_SendSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2415 {
2416  GSM_Error error;
2417 
2418  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2419  return ATGEN_SendSMS(s, sms);
2420 }
2421 
2422 static GSM_Error ALCATEL_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
2423 {
2424  GSM_Error error;
2425 
2426  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2427  return ATGEN_SetDateTime(s, date_time);
2428 }
2429 
2430 static GSM_Error ALCATEL_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
2431 {
2432  GSM_Error error;
2433 
2434  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2435  return ATGEN_SetSMSC(s, smsc);
2436 }
2437 
2438 static GSM_Error ALCATEL_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode *Code)
2439 {
2440  GSM_Error error;
2441 
2442  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2443  return ATGEN_EnterSecurityCode(s, Code);
2444 }
2445 
2446 static GSM_Error ALCATEL_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status)
2447 {
2448  GSM_Error error;
2449 
2450  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2451  return ATGEN_GetSecurityStatus(s, Status);
2452 }
2453 
2454 static GSM_Error ALCATEL_ResetPhoneSettings(GSM_StateMachine *s, GSM_ResetSettingsType Type)
2455 {
2456  GSM_Error error;
2457 
2458  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2459  return ATGEN_ResetPhoneSettings(s, Type);
2460 }
2461 
2462 static GSM_Error ALCATEL_SendDTMF(GSM_StateMachine *s, char *sequence)
2463 {
2464  GSM_Error error;
2465 
2466  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2467  return ATGEN_SendDTMF(s, sequence);
2468 }
2469 
2470 static GSM_Error ALCATEL_GetSIMIMSI(GSM_StateMachine *s, char *IMSI)
2471 {
2472  GSM_Error error;
2473 
2474  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
2475  return ATGEN_GetSIMIMSI(s, IMSI);
2476 }
2477 
2478 static GSM_Error ALCATEL_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *status)
2479 {
2480  GSM_Error error;
2481  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2482 
2483  status->Used = 0;
2484  status->Free = ALCATEL_FREE_MEMORY;
2485 
2486  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
2487  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
2488 
2489  status->Used = Priv->CalendarItemsCount;
2490  return ERR_NONE;
2491 }
2492 
2493 static GSM_Error ALCATEL_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
2494 {
2495  GSM_Error error;
2496  GSM_DateTime *dt = NULL;
2497  GSM_DateTime EventDate = {0,0,0,0,0,0,0};
2498  GSM_DateTime EventStart = {0,0,0,0,0,0,0};
2499  GSM_DateTime EventEnd = {0,0,0,0,0,0,0};
2500  gboolean EventDateSet = FALSE;
2501  gboolean EventStartSet = FALSE;
2502  gboolean EventEndSet = FALSE;
2503  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2504  int i;
2505  int j=0;
2506 
2507  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
2508  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
2509  if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= ERR_NONE) {
2510  Note->EntriesNum = 0;
2511  return error;
2512  }
2513  if ((error = ALCATEL_GetFields(s, Note->Location))!= ERR_NONE) return error;
2514 
2515  Note->EntriesNum = Priv->CurrentFieldsCount;
2516 
2517  for (i=0; i < Priv->CurrentFieldsCount; i++) {
2518  if ((error = ALCATEL_GetFieldValue(s, Note->Location, Priv->CurrentFields[i]))!= ERR_NONE) return error;
2519  switch (Priv->CurrentFields[i]) {
2520  case 0:
2521  if (Priv->ReturnType != Alcatel_date) {
2522  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2523  Note->EntriesNum--;
2524  j++;
2525  break;
2526  }
2527  if (!CheckDate(&(Priv->ReturnDateTime))) {
2528  smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
2529  Note->EntriesNum--;
2530  j++;
2531  break;
2532  }
2533  /* Date and time is composed at the end, when we have all needed data */
2534  j++;
2535  Note->EntriesNum--;
2536  EventDate = Priv->ReturnDateTime;
2537  EventDateSet = TRUE;
2538  break;
2539  case 1:
2540  if (Priv->ReturnType != Alcatel_time) {
2541  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2542  Note->EntriesNum--;
2543  j++;
2544  break;
2545  }
2546  if (!CheckTime(&(Priv->ReturnDateTime))) {
2547  smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
2548  Note->EntriesNum--;
2549  j++;
2550  break;
2551  }
2552  /* Date and time is composed at the end, when we have all needed data */
2553  j++;
2554  Note->EntriesNum--;
2555  EventStart = Priv->ReturnDateTime;
2556  EventStartSet = TRUE;
2557  break;
2558  case 2:
2559  if (Priv->ReturnType != Alcatel_time) {
2560  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2561  Note->EntriesNum--;
2562  j++;
2563  break;
2564  }
2565  if (!CheckTime(&(Priv->ReturnDateTime))) {
2566  smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
2567  Note->EntriesNum--;
2568  j++;
2569  break;
2570  }
2571  /* Date and time is composed at the end, when we have all needed data */
2572  j++;
2573  Note->EntriesNum--;
2574  EventEnd = Priv->ReturnDateTime;
2575  EventEndSet = TRUE;
2576  break;
2577  case 3:
2578  if (Priv->ReturnType != Alcatel_date) {
2579  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2580  Note->EntriesNum--;
2581  j++;
2582  break;
2583  }
2584  if (!CheckDate(&(Priv->ReturnDateTime))) {
2585  smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
2586  Note->EntriesNum--;
2587  j++;
2588  break;
2589  }
2590  if (dt == NULL) {
2592  Note->Entries[i-j].Date = Priv->ReturnDateTime;
2593  dt = &(Note->Entries[i-j].Date);
2594  } else {
2595  j++;
2596  Note->EntriesNum--;
2597  dt->Day = Priv->ReturnDateTime.Day;
2598  dt->Month = Priv->ReturnDateTime.Month;
2599  dt->Year = Priv->ReturnDateTime.Year;
2600  dt->Timezone = Priv->ReturnDateTime.Timezone;
2601  dt = NULL;
2602  }
2603  break;
2604  case 4:
2605  if (Priv->ReturnType != Alcatel_time) {
2606  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2607  Note->EntriesNum--;
2608  j++;
2609  break;
2610  }
2611  if (!CheckTime(&(Priv->ReturnDateTime))) {
2612  smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
2613  Note->EntriesNum--;
2614  j++;
2615  break;
2616  }
2617  if (dt == NULL) {
2619  Note->Entries[i-j].Date = Priv->ReturnDateTime;
2620  dt = &(Note->Entries[i-j].Date);
2621  } else {
2622  j++;
2623  Note->EntriesNum--;
2624  dt->Hour = Priv->ReturnDateTime.Hour;
2625  dt->Minute = Priv->ReturnDateTime.Minute;
2626  dt->Second = Priv->ReturnDateTime.Second;
2627  dt = NULL;
2628  }
2629  break;
2630  case 5:
2631  if (Priv->ReturnType != Alcatel_string) {
2632  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2633  Note->EntriesNum--;
2634  j++;
2635  break;
2636  }
2637  Note->Entries[i-j].EntryType = CAL_TEXT;
2638  CopyUnicodeString(Note->Entries[i-j].Text, Priv->ReturnString);
2639  break;
2640  case 6:
2641  if (Priv->ReturnType != Alcatel_bool) {
2642  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2643  Note->EntriesNum--;
2644  j++;
2645  break;
2646  }
2647  Note->Entries[i-j].EntryType = CAL_PRIVATE;
2648  Note->Entries[i-j].Number = Priv->ReturnInt;
2649  break;
2650  case 7:
2651  if (Priv->ReturnType != Alcatel_enum) {
2652  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2653  Note->EntriesNum--;
2654  j++;
2655  break;
2656  }
2657  switch (Priv->ReturnInt) {
2658  case 0:
2659  Note->Type = GSM_CAL_MEETING;
2660  break;
2661  case 2:
2662  Note->Type = GSM_CAL_BIRTHDAY;
2663  break;
2664  case 3:
2665  Note->Type = GSM_CAL_CALL;
2666  break;
2667  case 4:
2668  Note->Type = GSM_CAL_ALARM;
2669  break;
2670  case 5:
2671  Note->Type = GSM_CAL_DAILY_ALARM;
2672  break;
2673  case 9:
2674  /* I'd call this repeating event, but it makes no sense creating one more type ... */
2675  Note->Type = GSM_CAL_MEETING;
2676  break;
2677  default:
2678  smprintf(s,"WARNING: Received unknown event type %02X!\n", Priv->ReturnInt);
2679  break;
2680  }
2681  j++;
2682  Note->EntriesNum--;
2683  break;
2684  case 8:
2685  if (Priv->ReturnType != Alcatel_int) {
2686  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2687  Note->EntriesNum--;
2688  j++;
2689  break;
2690  }
2691  /* 0xffffffff indicates that there is phone (BF5), 0 means none (BF5, BE5)*/
2692  if (Priv->ReturnInt == 0xffffffff || Priv->ReturnInt == 0) {
2693  j++;
2694  Note->EntriesNum--;
2695  } else {
2696  Note->Entries[i-j].EntryType = CAL_CONTACTID;
2697  Note->Entries[i-j].Number = Priv->ReturnInt;
2698  }
2699  break;
2700  case 9:
2701  if (Priv->ReturnType != Alcatel_phone) {
2702  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2703  Note->EntriesNum--;
2704  j++;
2705  break;
2706  }
2707  Note->Entries[i-j].EntryType = CAL_PHONE;
2708  CopyUnicodeString(Note->Entries[i-j].Text, Priv->ReturnString);
2709  break;
2710  case 10:
2711  if (Priv->ReturnType != Alcatel_byte) {
2712  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2713  Note->EntriesNum--;
2714  j++;
2715  break;
2716  }
2717  Note->Entries[i-j].EntryType = CAL_REPEAT_DAYOFWEEK;
2718  Note->Entries[i-j].Number = Priv->ReturnInt;
2719  break;
2720  case 11:
2721  if (Priv->ReturnType != Alcatel_byte) {
2722  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2723  Note->EntriesNum--;
2724  j++;
2725  break;
2726  }
2727  Note->Entries[i-j].EntryType = CAL_REPEAT_DAY;
2728  Note->Entries[i-j].Number = Priv->ReturnInt;
2729  break;
2730  case 12:
2731  if (Priv->ReturnType != Alcatel_byte) {
2732  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2733  Note->EntriesNum--;
2734  j++;
2735  break;
2736  }
2738  Note->Entries[i-j].Number = Priv->ReturnInt;
2739  break;
2740  case 13:
2741  if (Priv->ReturnType != Alcatel_byte) {
2742  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2743  Note->EntriesNum--;
2744  j++;
2745  break;
2746  }
2747  Note->Entries[i-j].EntryType = CAL_REPEAT_MONTH;
2748  Note->Entries[i-j].Number = Priv->ReturnInt;
2749  break;
2750  case 17:
2751  if (Priv->ReturnType != Alcatel_byte) {
2752  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2753  Note->EntriesNum--;
2754  j++;
2755  break;
2756  }
2757  /* In BF5 birthday has frequency = 1 */
2758  if (Note->Type == GSM_CAL_BIRTHDAY) {
2759  Note->EntriesNum--;
2760  j++;
2761  } else {
2762  Note->Entries[i-j].EntryType = CAL_REPEAT_FREQUENCY;
2763  Note->Entries[i-j].Number = Priv->ReturnInt;
2764  }
2765  break;
2766  case 18:
2767  if (Priv->ReturnType != Alcatel_date) {
2768  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2769  Note->EntriesNum--;
2770  j++;
2771  break;
2772  }
2773  if (!CheckDate(&(Priv->ReturnDateTime))) {
2774  smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
2775  Note->EntriesNum--;
2776  j++;
2777  break;
2778  }
2779  Note->Entries[i-j].EntryType = CAL_REPEAT_STARTDATE;
2780  Note->Entries[i-j].Date = Priv->ReturnDateTime;
2781  break;
2782  case 19:
2783  if (Priv->ReturnType != Alcatel_date) {
2784  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2785  Note->EntriesNum--;
2786  j++;
2787  break;
2788  }
2789  if (!CheckDate(&(Priv->ReturnDateTime))) {
2790  smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
2791  Note->EntriesNum--;
2792  j++;
2793  break;
2794  }
2795  Note->Entries[i-j].EntryType = CAL_REPEAT_STOPDATE;
2796  Note->Entries[i-j].Date = Priv->ReturnDateTime;
2797  break;
2798  case 20:
2799  if (Priv->ReturnType != Alcatel_date) {
2800  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2801  Note->EntriesNum--;
2802  j++;
2803  break;
2804  }
2805  if (!CheckDate(&(Priv->ReturnDateTime))) {
2806  smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
2807  Note->EntriesNum--;
2808  j++;
2809  break;
2810  }
2811  /* This entry had always same value as the 3rd (alarm date) */
2812  j++;
2813  Note->EntriesNum--;
2814  break;
2815  case 21:
2816  if (Priv->ReturnType != Alcatel_time) {
2817  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2818  Note->EntriesNum--;
2819  j++;
2820  break;
2821  }
2822  if (!CheckTime(&(Priv->ReturnDateTime))) {
2823  smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
2824  Note->EntriesNum--;
2825  j++;
2826  break;
2827  }
2828  /* This entry had always same value as the 4th (alarm time) */
2829  j++;
2830  Note->EntriesNum--;
2831  break;
2832  default:
2833  Note->EntriesNum--;
2834  j++;
2835  smprintf(s,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv->CurrentFields[i], Priv->ReturnType);
2836  switch (Priv->ReturnType) {
2837  case Alcatel_date:
2838  smprintf(s, "%d.%d.%d", Priv->ReturnDateTime.Day, Priv->ReturnDateTime.Month, Priv->ReturnDateTime.Year);
2839  break;
2840  case Alcatel_time:
2841  smprintf(s, "%d:%d:%d", Priv->ReturnDateTime.Hour, Priv->ReturnDateTime.Minute, Priv->ReturnDateTime.Second);
2842  break;
2843  case Alcatel_string:
2844  case Alcatel_phone:
2845  smprintf(s, "\"%s\"",DecodeUnicodeString(Priv->ReturnString));
2846  break;
2847  case Alcatel_enum:
2848  case Alcatel_bool:
2849  case Alcatel_int:
2850  case Alcatel_byte:
2851  smprintf(s, "%d", Priv->ReturnInt);
2852  break;
2853  }
2854  smprintf(s,"\n");
2855  }
2856  }
2857  /* Fill start/stop datetime */
2858  if (EventDateSet) {
2859  if (EventStartSet) {
2860  Note->Entries[i-j].EntryType = CAL_START_DATETIME;
2861  Note->Entries[i-j].Date = EventDate;
2862  Note->Entries[i-j].Date.Timezone = EventStart.Timezone;
2863  Note->Entries[i-j].Date.Hour = EventStart.Hour;
2864  Note->Entries[i-j].Date.Minute = EventStart.Minute;
2865  Note->Entries[i-j].Date.Second = EventStart.Second;
2866  Note->EntriesNum++;
2867  i++;
2868  }
2869  if (EventEndSet) {
2870  Note->Entries[i-j].EntryType = CAL_END_DATETIME;
2871  Note->Entries[i-j].Date = EventDate;
2872  Note->Entries[i-j].Date.Timezone = EventEnd.Timezone;
2873  Note->Entries[i-j].Date.Hour = EventEnd.Hour;
2874  Note->Entries[i-j].Date.Minute = EventEnd.Minute;
2875  Note->Entries[i-j].Date.Second = EventEnd.Second;
2876  Note->EntriesNum++;
2877  i++;
2878  }
2879  if (!EventStartSet && !EventEndSet) {
2880  Note->Entries[i-j].EntryType = CAL_START_DATETIME;
2881  Note->Entries[i-j].Date = EventDate;
2882  Note->EntriesNum++;
2883  i++;
2884  }
2885  }
2886  return ERR_NONE;
2887 }
2888 
2889 static GSM_Error ALCATEL_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start)
2890 {
2891  GSM_Error error;
2892  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2893 
2894  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
2895  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
2896  if (Priv->CalendarItemsCount == 0) return ERR_EMPTY;
2897 
2898  if (start) Note->Location = 0;
2899  if ((error = ALCATEL_GetNextId(s, &(Note->Location))) != ERR_NONE) return error;
2900 
2901  return ALCATEL_GetCalendar(s, Note);
2902 }
2903 
2904 
2905 static GSM_Error ALCATEL_DeleteCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
2906 {
2907  GSM_Error error;
2908 
2909  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
2910  /* Delete Calendar */
2911  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
2912  if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= ERR_NONE) {
2913  /* Entry was empty => no error */
2914  return ERR_NONE;
2915  }
2916  error = ALCATEL_DeleteItem(s, Note->Location);
2917  if (error != ERR_NONE) return error;
2918  /* Refresh list */
2919  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
2920  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
2921  return ERR_NONE;
2922 }
2923 
2924 
2925 static GSM_Error ALCATEL_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
2926 {
2927  GSM_Error error;
2928  unsigned int val;
2929  gboolean contact_set = FALSE;
2930  gboolean phone_set = FALSE;
2931  gboolean date_set = FALSE;
2932  gboolean repeating = FALSE;
2933  int i;
2934  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2935 
2936  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
2937  if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeCalendar, 0))!= ERR_NONE) return error;
2938 
2939  for (i = 0; i < Note->EntriesNum; i++) {
2940  switch (Note->Entries[i].EntryType) {
2941  case CAL_START_DATETIME:
2942  if (!date_set) {
2943  if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error;
2944  date_set = TRUE;
2945  }
2946  if ((error = ALCATEL_CreateField(s, Alcatel_time, 1, &(Note->Entries[i].Date))) != ERR_NONE) return error;
2947  break;
2948  case CAL_END_DATETIME:
2949  if (!date_set) {
2950  if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error;
2951  date_set = TRUE;
2952  }
2953  if ((error = ALCATEL_CreateField(s, Alcatel_time, 2, &(Note->Entries[i].Date))) != ERR_NONE) return error;
2954  break;
2956  if ((error = ALCATEL_CreateField(s, Alcatel_date, 3, &(Note->Entries[i].Date))) != ERR_NONE) return error;
2957  if ((error = ALCATEL_CreateField(s, Alcatel_time, 4, &(Note->Entries[i].Date))) != ERR_NONE) return error;
2958  if (Note->Type == GSM_CAL_ALARM || Note->Type == GSM_CAL_DAILY_ALARM) {
2959  if ((error = ALCATEL_CreateField(s, Alcatel_date, 20, &(Note->Entries[i].Date))) != ERR_NONE) return error;
2960  if ((error = ALCATEL_CreateField(s, Alcatel_time, 21, &(Note->Entries[i].Date))) != ERR_NONE) return error;
2961  }
2962  break;
2963  case CAL_TEXT:
2964  if ((error = ALCATEL_CreateField(s, Alcatel_string, 5, Note->Entries[i].Text)) != ERR_NONE) return error;
2965  break;
2966  case CAL_PRIVATE:
2967  if ((error = ALCATEL_CreateField(s, Alcatel_bool, 6, &(Note->Entries[i].Number))) != ERR_NONE) return error;
2968  break;
2969  case CAL_CONTACTID:
2970  if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &(Note->Entries[i].Number))) != ERR_NONE) return error;
2971  contact_set = TRUE;
2972  break;
2973  case CAL_PHONE:
2974  if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, Note->Entries[i].Text)) != ERR_NONE) return error;
2975  phone_set = TRUE;
2976  break;
2977  case CAL_REPEAT_DAYOFWEEK:
2978  if ((error = ALCATEL_CreateField(s, Alcatel_byte, 10, &(Note->Entries[i].Number))) != ERR_NONE) return error;
2979  repeating = TRUE;
2980  break;
2981  case CAL_REPEAT_DAY:
2982  if ((error = ALCATEL_CreateField(s, Alcatel_byte, 11, &(Note->Entries[i].Number))) != ERR_NONE) return error;
2983  repeating = TRUE;
2984  break;
2986  if ((error = ALCATEL_CreateField(s, Alcatel_byte, 12, &(Note->Entries[i].Number))) != ERR_NONE) return error;
2987  repeating = TRUE;
2988  break;
2989  case CAL_REPEAT_MONTH:
2990  if ((error = ALCATEL_CreateField(s, Alcatel_byte, 13, &(Note->Entries[i].Number))) != ERR_NONE) return error;
2991  repeating = TRUE;
2992  break;
2993  case CAL_REPEAT_FREQUENCY:
2994  if ((error = ALCATEL_CreateField(s, Alcatel_byte, 17, &(Note->Entries[i].Number))) != ERR_NONE) return error;
2995  repeating = TRUE;
2996  break;
2997  case CAL_REPEAT_STARTDATE:
2998  if ((error = ALCATEL_CreateField(s, Alcatel_date, 18, &(Note->Entries[i].Date))) != ERR_NONE) return error;
2999  repeating = TRUE;
3000  break;
3001  case CAL_REPEAT_STOPDATE:
3002  if ((error = ALCATEL_CreateField(s, Alcatel_date, 19, &(Note->Entries[i].Date))) != ERR_NONE) return error;
3003  repeating = TRUE;
3004  break;
3005  case CAL_REPEAT_COUNT:
3006  case CAL_REPEAT_DAYOFYEAR:
3008  case CAL_LOCATION:
3009  case CAL_DESCRIPTION:
3010  case CAL_LUID:
3011  case CAL_LAST_MODIFIED:
3012  smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", Note->Entries[i].EntryType);
3013  break;
3014  }
3015  }
3016 
3017  switch (Note->Type) {
3018  case GSM_CAL_CALL:
3019  val = 3;
3020  break;
3021  case GSM_CAL_BIRTHDAY:
3022  val = 2;
3023  break;
3024  case GSM_CAL_ALARM:
3025  val = 4;
3026  break;
3027  case GSM_CAL_DAILY_ALARM:
3028  val = 5;
3029  break;
3030  default:
3031  if (repeating) {
3032  val = 9;
3033  } else {
3034  val = 0;
3035  }
3036  }
3037  if ((error = ALCATEL_CreateField(s, Alcatel_enum, 7, &val)) != ERR_NONE) return error;
3038 
3039  if (!contact_set) {
3040  if (phone_set) {
3041  val = 0xffffffff;
3042  } else {
3043  val = 0;
3044  }
3045  if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &val)) != ERR_NONE) return error;
3046  }
3047  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
3048  Note->Location = Priv->CommitedRecord;
3049  /* Refresh list */
3050  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
3051  return ERR_NONE;
3052 }
3053 
3054 static GSM_Error ALCATEL_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
3055 {
3056  GSM_Error error;
3057  unsigned int val;
3058  gboolean contact_set = FALSE;
3059  gboolean phone_set = FALSE;
3060  gboolean date_set = FALSE;
3061  gboolean repeating = FALSE;
3062  int i;
3063  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3064  gboolean UpdatedFields[22];
3065 
3066  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
3067  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
3068  if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= ERR_NONE) {
3069  /* Entry doesn't exist, we will create new one */
3070  return ALCATEL_AddCalendar(s, Note);
3071  }
3072  /* Get fields for current item */
3073  if ((error = ALCATEL_GetFields(s, Note->Location))!= ERR_NONE) return error;
3074 
3075  for (i = 0; i < 22; i++) { UpdatedFields[i] = FALSE; }
3076 
3077  if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeCalendar, Note->Location))!= ERR_NONE) return error;
3078 
3079  for (i = 0; i < Note->EntriesNum; i++) {
3080  switch (Note->Entries[i].EntryType) {
3081  case CAL_START_DATETIME:
3082  if (!date_set) {
3083  UpdatedFields[0] = TRUE;
3084  if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error;
3085  date_set = TRUE;
3086  }
3087  UpdatedFields[1] = TRUE;
3088  if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 1, &(Note->Entries[i].Date))) != ERR_NONE) return error;
3089  break;
3090  case CAL_END_DATETIME:
3091  if (!date_set) {
3092  UpdatedFields[0] = TRUE;
3093  if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 0, &(Note->Entries[i].Date))) != ERR_NONE) return error;
3094  date_set = TRUE;
3095  }
3096  UpdatedFields[2] = TRUE; if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 2, &(Note->Entries[i].Date))) != ERR_NONE) return error;
3097  break;
3099  UpdatedFields[3] = TRUE;
3100  if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 3, &(Note->Entries[i].Date))) != ERR_NONE) return error;
3101  UpdatedFields[4] = TRUE;
3102  if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 4, &(Note->Entries[i].Date))) != ERR_NONE) return error;
3103  if (Note->Type == GSM_CAL_ALARM || Note->Type == GSM_CAL_DAILY_ALARM) {
3104  UpdatedFields[20] = TRUE;
3105  if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 20, &(Note->Entries[i].Date))) != ERR_NONE) return error;
3106  UpdatedFields[21] = TRUE;
3107  if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 21, &(Note->Entries[i].Date))) != ERR_NONE) return error;
3108  }
3109  break;
3110  case CAL_TEXT:
3111  UpdatedFields[5] = TRUE;
3112  if ((error = ALCATEL_UpdateField(s, Alcatel_string, Note->Location, 5, Note->Entries[i].Text)) != ERR_NONE) return error;
3113  break;
3114  case CAL_PRIVATE:
3115  UpdatedFields[6] = TRUE;
3116  if ((error = ALCATEL_UpdateField(s, Alcatel_bool, Note->Location, 6, &(Note->Entries[i].Number))) != ERR_NONE) return error;
3117  break;
3118  case CAL_CONTACTID:
3119  UpdatedFields[8] = TRUE;
3120  if ((error = ALCATEL_UpdateField(s, Alcatel_int, Note->Location, 8, &(Note->Entries[i].Number))) != ERR_NONE) return error;
3121  contact_set = TRUE;
3122  break;
3123  case CAL_PHONE:
3124  UpdatedFields[9] = TRUE;
3125  if ((error = ALCATEL_UpdateField(s, Alcatel_phone, Note->Location, 9, Note->Entries[i].Text)) != ERR_NONE) return error;
3126  phone_set = TRUE;
3127  break;
3128  case CAL_REPEAT_DAYOFWEEK:
3129  UpdatedFields[10] = TRUE;
3130  if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 10, &(Note->Entries[i].Number))) != ERR_NONE) return error;
3131  repeating = TRUE;
3132  break;
3133  case CAL_REPEAT_DAY:
3134  UpdatedFields[11] = TRUE;
3135  if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 11, &(Note->Entries[i].Number))) != ERR_NONE) return error;
3136  repeating = TRUE;
3137  break;
3139  UpdatedFields[12] = TRUE;
3140  if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 12, &(Note->Entries[i].Number))) != ERR_NONE) return error;
3141  repeating = TRUE;
3142  break;
3143  case CAL_REPEAT_MONTH:
3144  UpdatedFields[13] = TRUE;
3145  if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 13, &(Note->Entries[i].Number))) != ERR_NONE) return error;
3146  repeating = TRUE;
3147  break;
3148  case CAL_REPEAT_FREQUENCY:
3149  UpdatedFields[17] = TRUE;
3150  if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 17, &(Note->Entries[i].Number))) != ERR_NONE) return error;
3151  repeating = TRUE;
3152  break;
3153  case CAL_REPEAT_STARTDATE:
3154  UpdatedFields[18] = TRUE;
3155  if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 18, &(Note->Entries[i].Date))) != ERR_NONE) return error;
3156  repeating = TRUE;
3157  break;
3158  case CAL_REPEAT_STOPDATE:
3159  UpdatedFields[19] = TRUE;
3160  if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 19, &(Note->Entries[i].Date))) != ERR_NONE) return error;
3161  repeating = TRUE;
3162  break;
3163  case CAL_REPEAT_COUNT:
3164  case CAL_REPEAT_DAYOFYEAR:
3166  case CAL_LOCATION:
3167  case CAL_DESCRIPTION:
3168  case CAL_LUID:
3169  case CAL_LAST_MODIFIED:
3170  smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", Note->Entries[i].EntryType);
3171  break;
3172  }
3173  }
3174 
3175  switch (Note->Type) {
3176  case GSM_CAL_CALL:
3177  val = 3;
3178  break;
3179  case GSM_CAL_BIRTHDAY:
3180  val = 2;
3181  break;
3182  case GSM_CAL_ALARM:
3183  val = 4;
3184  break;
3185  case GSM_CAL_DAILY_ALARM:
3186  val = 5;
3187  break;
3188  default:
3189  if (repeating) {
3190  val = 9;
3191  } else {
3192  val = 0;
3193  }
3194  }
3195  UpdatedFields[7] = TRUE;
3196  if ((error = ALCATEL_UpdateField(s, Alcatel_enum, Note->Location, 7, &val)) != ERR_NONE) return error;
3197 
3198  if (!contact_set) {
3199  if (phone_set) {
3200  val = 0xffffffff;
3201  } else {
3202  val = 0;
3203  }
3204  UpdatedFields[8] = TRUE;
3205  if ((error = ALCATEL_UpdateField(s, Alcatel_int, Note->Location, 8, &val)) != ERR_NONE) return error;
3206  }
3207  /* If we didn't update some field, we have to delete it... */
3208  for (i=0; i<Priv->CurrentFieldsCount; i++) {
3209  if (!UpdatedFields[Priv->CurrentFields[i]]) if ((error = ALCATEL_DeleteField(s, Note->Location, Priv->CurrentFields[i])) != ERR_NONE) return error;
3210  }
3211  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
3212  return ERR_NONE;
3213 }
3214 
3215 static GSM_Error ALCATEL_DeleteAllCalendar (GSM_StateMachine *s)
3216 {
3217  GSM_Error error;
3218  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3219  int i;
3220 
3221  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
3222  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
3223 
3224  for (i=0; i<Priv->CalendarItemsCount; i++) {
3225  error = ALCATEL_DeleteItem(s, Priv->CalendarItems[i]);
3226  if (error != ERR_NONE) return error;
3227  }
3228 
3229  /* Refresh list */
3230  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
3231  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
3232 
3233  return ERR_NONE;
3234 }
3235 
3236 
3237 static GSM_Error ALCATEL_GetAlarm(GSM_StateMachine *s, GSM_Alarm *Alarm)
3238 {
3239  GSM_Error error;
3240  GSM_CalendarEntry Note;
3241  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3242  int i;
3243  gboolean Found = FALSE;
3244  gboolean DateSet = FALSE;
3245  int alarm_number = Alarm->Location;
3246  static GSM_DateTime nulldt = {0,0,0,0,0,0,0};
3247 
3248  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
3249  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
3250 
3251  for (i=0; i<Priv->CalendarItemsCount; i++) {
3252  if ((error = ALCATEL_GetFieldValue(s, Priv->CalendarItems[i], 7))!= ERR_NONE) return error;
3253  if (Priv->ReturnType != Alcatel_enum) {
3254  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3255  continue;
3256  }
3257  if (Priv->ReturnInt == 4 || Priv->ReturnInt == 5) {
3258  alarm_number--;
3259  if (alarm_number == 0) {
3260  Found = TRUE;
3261  break;
3262  }
3263  }
3264  }
3265 
3266  if (!Found) return ERR_EMPTY;
3267 
3268  Note.Location = Priv->CalendarItems[i];
3269  Note.Type = 0;
3270 
3271  if ((error = ALCATEL_GetCalendar(s, &Note))!= ERR_NONE) return error;
3272 
3273  if (Note.Type == GSM_CAL_ALARM) {
3274  Alarm->Repeating = FALSE;
3275  } else {
3276  Alarm->Repeating = TRUE;
3277  }
3278 
3279  Alarm->Text[0] = 0; Alarm->Text[1] = 0;
3280 
3281 
3282  for (i = 0; i < Note.EntriesNum; i++) {
3283  if (Note.Entries[i].EntryType == CAL_TEXT) {
3284  CopyUnicodeString(Alarm->Text, Note.Entries[i].Text);
3285  } else if (Note.Entries[i].EntryType == CAL_TONE_ALARM_DATETIME) {
3286  Alarm->DateTime = Note.Entries[i].Date;
3287  DateSet = FALSE;
3288  }
3289  }
3290  if (!DateSet) {
3291  Alarm->DateTime = nulldt;
3292  }
3293 
3294  return ERR_NONE;
3295 }
3296 
3297 
3298 static GSM_Error ALCATEL_SetAlarm (GSM_StateMachine *s, GSM_Alarm *Alarm)
3299 {
3300  GSM_Error error;
3301  GSM_CalendarEntry Note;
3302  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3303  GSM_DateTime dt;
3304  int i;
3305  gboolean Found = FALSE;
3306  int alarm_number = Alarm->Location;
3307 
3308  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= ERR_NONE) return error;
3309  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
3310 
3311  for (i=0; i<Priv->CalendarItemsCount; i++) {
3312  if ((error = ALCATEL_GetFieldValue(s, Priv->CalendarItems[i], 7))!= ERR_NONE) return error;
3313  if (Priv->ReturnType != Alcatel_enum) {
3314  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3315  continue;
3316  }
3317  if (Priv->ReturnInt == 4 || Priv->ReturnInt == 5) {
3318  alarm_number--;
3319  if (alarm_number == 0) {
3320  Found = TRUE;
3321  break;
3322  }
3323  }
3324  }
3325 
3326  if (Found) {
3327  Note.Location = Priv->CalendarItems[i];
3328  }
3329 
3330  Note.EntriesNum = 1;
3331 
3333  Note.Entries[0].Date = Alarm->DateTime;
3334 
3335  if (Alarm->Repeating) {
3336  Note.Type = GSM_CAL_DAILY_ALARM;
3338  Note.Entries[0].Date.Day = dt.Day;
3339  Note.Entries[0].Date.Month = dt.Month;
3340  Note.Entries[0].Date.Year = dt.Year;
3341  } else {
3342  Note.Type = GSM_CAL_ALARM;
3343  }
3344 
3345  if (Alarm->Text[0] != 0 || Alarm->Text[1] != 0) {
3346  Note.EntriesNum++;
3347  Note.Entries[1].EntryType = CAL_TEXT;
3348  CopyUnicodeString(Note.Entries[1].Text, Alarm->Text);
3349  }
3350 
3351  if (Found) {
3352  return ALCATEL_SetCalendar(s, &Note);
3353  } else {
3354  return ALCATEL_AddCalendar(s, &Note);
3355  }
3356 }
3357 
3358 
3359 static GSM_Error ALCATEL_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status)
3360 {
3361  GSM_Error error;
3362  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3363 
3364  status->Used = 0;
3365  status->Free = ALCATEL_FREE_MEMORY;
3366 
3367  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error;
3368  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
3369 
3370  status->Used = Priv->ToDoItemsCount;
3371  return ERR_NONE;
3372 }
3373 
3374 static GSM_Error ALCATEL_GetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
3375 {
3376  GSM_Error error;
3377  GSM_DateTime *dt = NULL;
3378  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3379  int i;
3380  int j=0;
3381 
3382  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error;
3383  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
3384  if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= ERR_NONE) {
3385  ToDo->EntriesNum = 0;
3386  return error;
3387  }
3388  if ((error = ALCATEL_GetFields(s, ToDo->Location))!= ERR_NONE) return error;
3389 
3390  ToDo->EntriesNum = Priv->CurrentFieldsCount;
3391  ToDo->Priority = GSM_Priority_None;
3392  ToDo->Type = GSM_CAL_MEMO;
3393 
3394  for (i=0; i < Priv->CurrentFieldsCount; i++) {
3395  if ((error = ALCATEL_GetFieldValue(s, ToDo->Location, Priv->CurrentFields[i]))!= ERR_NONE) return error;
3396  switch (Priv->CurrentFields[i]) {
3397  case 0:
3398  if (Priv->ReturnType != Alcatel_date) {
3399  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3400  ToDo->EntriesNum--;
3401  j++;
3402  break;
3403  }
3404  if (!CheckDate(&(Priv->ReturnDateTime))) {
3405  smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
3406  ToDo->EntriesNum--;
3407  j++;
3408  break;
3409  }
3410  ToDo->Entries[i-j].EntryType = TODO_END_DATETIME;
3411  ToDo->Entries[i-j].Date = Priv->ReturnDateTime;
3412  break;
3413  case 1:
3414  if (Priv->ReturnType != Alcatel_bool) {
3415  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3416  ToDo->EntriesNum--;
3417  j++;
3418  break;
3419  }
3420  ToDo->Entries[i-j].EntryType = TODO_COMPLETED;
3421  ToDo->Entries[i-j].Number = Priv->ReturnInt;
3422  break;
3423  case 2:
3424  if (Priv->ReturnType != Alcatel_date) {
3425  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3426  ToDo->EntriesNum--;
3427  j++;
3428  break;
3429  }
3430  if (!CheckDate(&(Priv->ReturnDateTime))) {
3431  smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
3432  ToDo->EntriesNum--;
3433  j++;
3434  break;
3435  }
3436  if (dt == NULL) {
3437  ToDo->Entries[i-j].EntryType = TODO_ALARM_DATETIME;
3438  ToDo->Entries[i-j].Date = Priv->ReturnDateTime;
3439  dt = &(ToDo->Entries[i-j].Date);
3440  } else {
3441  j++;
3442  ToDo->EntriesNum--;
3443  dt->Day = Priv->ReturnDateTime.Day;
3444  dt->Month = Priv->ReturnDateTime.Month;
3445  dt->Year = Priv->ReturnDateTime.Year;
3446  dt->Timezone = Priv->ReturnDateTime.Timezone;
3447  dt = NULL;
3448  }
3449  break;
3450  case 3:
3451  if (Priv->ReturnType != Alcatel_time) {
3452  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3453  ToDo->EntriesNum--;
3454  j++;
3455  break;
3456  }
3457  if (!CheckTime(&(Priv->ReturnDateTime))) {
3458  smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
3459  ToDo->EntriesNum--;
3460  j++;
3461  break;
3462  }
3463  if (dt == NULL) {
3464  ToDo->Entries[i-j].EntryType = TODO_ALARM_DATETIME;
3465  ToDo->Entries[i-j].Date = Priv->ReturnDateTime;
3466  dt = &(ToDo->Entries[i-j].Date);
3467  } else {
3468  j++;
3469  ToDo->EntriesNum--;
3470  dt->Hour = Priv->ReturnDateTime.Hour;
3471  dt->Minute = Priv->ReturnDateTime.Minute;
3472  dt->Second = Priv->ReturnDateTime.Second;
3473  dt = NULL;
3474  }
3475  break;
3476  case 4:
3477  if (Priv->ReturnType != Alcatel_string) {
3478  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3479  ToDo->EntriesNum--;
3480  j++;
3481  break;
3482  }
3483  ToDo->Entries[i-j].EntryType = TODO_TEXT;
3484  CopyUnicodeString(ToDo->Entries[i-j].Text, Priv->ReturnString);
3485  break;
3486  case 5:
3487  if (Priv->ReturnType != Alcatel_bool) {
3488  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3489  ToDo->EntriesNum--;
3490  j++;
3491  break;
3492  }
3493  ToDo->Entries[i-j].EntryType = TODO_PRIVATE;
3494  ToDo->Entries[i-j].Number = Priv->ReturnInt;
3495  break;
3496  case 6:
3497  if (Priv->ReturnType != Alcatel_byte) {
3498  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3499  ToDo->EntriesNum--;
3500  j++;
3501  break;
3502  }
3503  if (Priv->ReturnInt == 255) {
3504  /* 255 means no category */
3505  j++;
3506  ToDo->EntriesNum--;
3507  } else {
3508  ToDo->Entries[i-j].EntryType = TODO_CATEGORY;
3509  ToDo->Entries[i-j].Number = Priv->ReturnInt;
3510  }
3511  break;
3512  case 7:
3513  /* This one seems to be byte for BF5 and enum for BE5 */
3514  if (Priv->ReturnType != Alcatel_enum && Priv->ReturnType != Alcatel_byte) {
3515  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3516  ToDo->EntriesNum--;
3517  j++;
3518  break;
3519  }
3520  switch (Priv->ReturnInt) {
3521  case 0:
3522  ToDo->Priority = GSM_Priority_High;
3523  break;
3524  case 1:
3525  ToDo->Priority = GSM_Priority_Medium;
3526  break;
3527  case 2:
3528  ToDo->Priority = GSM_Priority_Low;
3529  break;
3530  default:
3531  smprintf(s,"WARNING: Received unexpected priority %02X, ignoring\n", Priv->ReturnInt);
3532  }
3533  j++;
3534  ToDo->EntriesNum--;
3535  break;
3536  case 8:
3537  if (Priv->ReturnType != Alcatel_int) {
3538  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3539  ToDo->EntriesNum--;
3540  j++;
3541  break;
3542  }
3543  /* 0xffffffff indicates that there is phone, 0 means none */
3544  if (Priv->ReturnInt == 0xffffffff || Priv->ReturnInt == 0) {
3545  j++;
3546  ToDo->EntriesNum--;
3547  } else {
3548  ToDo->Entries[i-j].EntryType = TODO_CONTACTID;
3549  ToDo->Entries[i-j].Number = Priv->ReturnInt;
3550  ToDo->Type = GSM_CAL_CALL;
3551  }
3552  break;
3553  case 9:
3554  if (Priv->ReturnType != Alcatel_phone) {
3555  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3556  ToDo->EntriesNum--;
3557  j++;
3558  break;
3559  }
3560  ToDo->Entries[i-j].EntryType = TODO_PHONE;
3561  ToDo->Type = GSM_CAL_CALL;
3562  CopyUnicodeString(ToDo->Entries[i-j].Text, Priv->ReturnString);
3563  break;
3564  case 10:
3565  if (Priv->ReturnType != Alcatel_date) {
3566  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3567  ToDo->EntriesNum--;
3568  j++;
3569  break;
3570  }
3571  if (!CheckDate(&(Priv->ReturnDateTime))) {
3572  smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
3573  ToDo->EntriesNum--;
3574  j++;
3575  break;
3576  }
3577  /* This entry had always same value as the 2nd (alarm date) */
3578  j++;
3579  ToDo->EntriesNum--;
3580  break;
3581  case 11:
3582  if (Priv->ReturnType != Alcatel_time) {
3583  smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3584  ToDo->EntriesNum--;
3585  j++;
3586  break;
3587  }
3588  if (!CheckTime(&(Priv->ReturnDateTime))) {
3589  smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
3590  ToDo->EntriesNum--;
3591  j++;
3592  break;
3593  }
3594  /* This entry had always same value as the 3rd (alarm time) */
3595  j++;
3596  ToDo->EntriesNum--;
3597  break;
3598  default:
3599  ToDo->EntriesNum--;
3600  j++;
3601  smprintf(s,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv->CurrentFields[i], Priv->ReturnType);
3602  switch (Priv->ReturnType) {
3603  case Alcatel_date:
3604  smprintf(s, "%d.%d.%d", Priv->ReturnDateTime.Day, Priv->ReturnDateTime.Month, Priv->ReturnDateTime.Year);
3605  break;
3606  case Alcatel_time:
3607  smprintf(s, "%d:%d:%d", Priv->ReturnDateTime.Hour, Priv->ReturnDateTime.Minute, Priv->ReturnDateTime.Second);
3608  break;
3609  case Alcatel_string:
3610  case Alcatel_phone:
3611  smprintf(s, "\"%s\"",DecodeUnicodeString(Priv->ReturnString));
3612  break;
3613  case Alcatel_enum:
3614  case Alcatel_bool:
3615  case Alcatel_int:
3616  case Alcatel_byte:
3617  smprintf(s, "%d", Priv->ReturnInt);
3618  break;
3619  }
3620  smprintf(s,"\n");
3621  }
3622  }
3623  return ERR_NONE;
3624 }
3625 
3626 static GSM_Error ALCATEL_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, gboolean start)
3627 {
3628  GSM_Error error;
3629  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3630 
3631  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error;
3632  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
3633  if (Priv->ToDoItemsCount == 0) return ERR_EMPTY;
3634 
3635  if (start) ToDo->Location = 0;
3636  if ((error = ALCATEL_GetNextId(s, &(ToDo->Location))) != ERR_NONE) return error;
3637 
3638  return ALCATEL_GetToDo(s, ToDo);
3639 }
3640 
3641 static GSM_Error ALCATEL_DeleteAllToDo (GSM_StateMachine *s)
3642 {
3643  GSM_Error error;
3644  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3645  int i;
3646 
3647  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error;
3648  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
3649 
3650  for (i=0; i<Priv->ToDoItemsCount; i++) {
3651  error = ALCATEL_DeleteItem(s, Priv->ToDoItems[i]);
3652  if (error != ERR_NONE) return error;
3653  }
3654 
3655  /* Refresh list */
3656  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error;
3657  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
3658 
3659  return ERR_NONE;
3660 }
3661 
3662 static GSM_Error ALCATEL_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
3663 {
3664  GSM_Error error;
3665  unsigned int val;
3666  gboolean contact_set = FALSE;
3667  gboolean phone_set = FALSE;
3668  int i;
3669  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3670 
3671  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error;
3672  if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeToDo, 0))!= ERR_NONE) return error;
3673 
3674  /* Set priority if wanted */
3675  switch (ToDo->Priority) {
3676  case GSM_Priority_High:
3677  val = 0;
3678  break;
3679  case GSM_Priority_Low:
3680  val = 2;
3681  break;
3682  case GSM_Priority_Medium:
3683  val = 1;
3684  break;
3685  case GSM_Priority_None:
3686  default:
3687  val = 0xff;
3688  break;
3689  }
3690 
3691  if (val != 0xff) {
3692  /* This one seems to be byte for BF5 and enum for BE5 */
3693  if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) {
3694  if ((error = ALCATEL_CreateField(s, Alcatel_byte, 7, &val)) != ERR_NONE) return error;
3695  } else {
3696  if ((error = ALCATEL_CreateField(s, Alcatel_enum, 7, &val)) != ERR_NONE) return error;
3697  }
3698  }
3699 
3700  for (i = 0; i < ToDo->EntriesNum; i++) {
3701  switch (ToDo->Entries[i].EntryType) {
3702  case TODO_END_DATETIME:
3703  if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(ToDo->Entries[i].Date))) != ERR_NONE) return error;
3704  break;
3705  case TODO_COMPLETED:
3706  if ((error = ALCATEL_CreateField(s, Alcatel_bool, 1, &(ToDo->Entries[i].Number))) != ERR_NONE) return error;
3707  break;
3708  case TODO_ALARM_DATETIME:
3709  if ((error = ALCATEL_CreateField(s, Alcatel_date, 2, &(ToDo->Entries[i].Date))) != ERR_NONE) return error;
3710  if ((error = ALCATEL_CreateField(s, Alcatel_time, 3, &(ToDo->Entries[i].Date))) != ERR_NONE) return error;
3711  if ((error = ALCATEL_CreateField(s, Alcatel_date, 10, &(ToDo->Entries[i].Date))) != ERR_NONE) return error;
3712  if ((error = ALCATEL_CreateField(s, Alcatel_time, 11, &(ToDo->Entries[i].Date))) != ERR_NONE) return error;
3713  break;
3714  case TODO_TEXT:
3715  if ((error = ALCATEL_CreateField(s, Alcatel_string, 4, ToDo->Entries[i].Text)) != ERR_NONE) return error;
3716  break;
3717  case TODO_PRIVATE:
3718  if ((error = ALCATEL_CreateField(s, Alcatel_bool, 5, &(ToDo->Entries[i].Number))) != ERR_NONE) return error;
3719  break;
3720  case TODO_CATEGORY:
3721  if ((error = ALCATEL_CreateField(s, Alcatel_byte, 6, &(ToDo->Entries[i].Number))) != ERR_NONE) return error;
3722  break;
3723  case TODO_CONTACTID:
3724  if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &(ToDo->Entries[i].Number))) != ERR_NONE) return error;
3725  contact_set = TRUE;
3726  break;
3727  case TODO_PHONE:
3728  if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, ToDo->Entries[i].Text)) != ERR_NONE) return error;
3729  phone_set = TRUE;
3730  break;
3731  default:
3732  break;
3733  }
3734  }
3735  if (!contact_set) {
3736  if (phone_set) {
3737  val = 0xffffffff;
3738  } else {
3739  val = 0;
3740  }
3741  if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &val)) != ERR_NONE) return error;
3742  }
3743  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error;
3744  ToDo->Location = Priv->CommitedRecord;
3745  /* Refresh list */
3746  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
3747  return ERR_NONE;
3748 }
3749 
3750 static GSM_Error ALCATEL_SetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
3751 {
3752  GSM_Error error;
3753  unsigned int val;
3754  gboolean contact_set = FALSE;
3755  gboolean phone_set = FALSE;
3756  gboolean UpdatedFields[12];
3757  int i;
3758  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3759 
3760  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error;
3761  /* Save modified ToDo */
3762  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
3763  if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= ERR_NONE) {
3764  /* Entry doesn't exist, we will create new one */
3765  return ALCATEL_AddToDo(s, ToDo);
3766  }
3767  /* Get fields for current item */
3768  if ((error = ALCATEL_GetFields(s, ToDo->Location))!= ERR_NONE) return error;
3769 
3770  for (i = 0; i < 12; i++) { UpdatedFields[i] = FALSE; }
3771 
3772  if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeToDo, ToDo->Location))!= ERR_NONE) return error;
3773 
3774  /* Set priority if wanted */
3775  switch (ToDo->Priority) {
3776  case GSM_Priority_High:
3777  val = 0;
3778  break;
3779  case GSM_Priority_Low:
3780  val = 2;
3781  break;
3782  case GSM_Priority_Medium:
3783  val = 1;
3784  break;
3785  case GSM_Priority_None:
3786  default:
3787  val = 0xff;
3788  break;
3789  }
3790 
3791  if (val != 0xff) {
3792  /* This one seems to be byte for BF5 and enum for BE5 */
3793  if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) {
3794  if ((error = ALCATEL_UpdateField(s, Alcatel_byte, ToDo->Location, 7, &val)) != ERR_NONE) return error;
3795  } else {
3796  if ((error = ALCATEL_UpdateField(s, Alcatel_enum, ToDo->Location, 7, &val)) != ERR_NONE) return error;
3797  }
3798  UpdatedFields[7] = TRUE;
3799  }
3800 
3801  for (i = 0; i < ToDo->EntriesNum; i++) {
3802  switch (ToDo->Entries[i].EntryType) {
3803  case TODO_END_DATETIME:
3804  if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 0, &(ToDo->Entries[i].Date))) != ERR_NONE) return error;
3805  UpdatedFields[0] = TRUE;
3806  break;
3807  case TODO_COMPLETED:
3808  if ((error = ALCATEL_UpdateField(s, Alcatel_bool, ToDo->Location, 1, &(ToDo->Entries[i].Number))) != ERR_NONE) return error;
3809  UpdatedFields[1] = TRUE;
3810  break;
3811  case TODO_ALARM_DATETIME:
3812  if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 2, &(ToDo->Entries[i].Date))) != ERR_NONE) return error;
3813  UpdatedFields[2] = TRUE;
3814  if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 3, &(ToDo->Entries[i].Date))) != ERR_NONE) return error;
3815  UpdatedFields[3] = TRUE;
3816  if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 10, &(ToDo->Entries[i].Date))) != ERR_NONE) return error;
3817  UpdatedFields[10] = TRUE;
3818  if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 11, &(ToDo->Entries[i].Date))) != ERR_NONE) return error;
3819  UpdatedFields[11] = TRUE;
3820  break;
3821  case TODO_TEXT:
3822  if ((error = ALCATEL_UpdateField(s, Alcatel_string, ToDo->Location, 4, ToDo->Entries[i].Text)) != ERR_NONE) return error;
3823  UpdatedFields[4] = TRUE;
3824  break;
3825  case TODO_PRIVATE:
3826  if ((error = ALCATEL_UpdateField(s, Alcatel_bool, ToDo->Location, 5, &(ToDo->Entries[i].Number))) != ERR_NONE) return error;
3827  UpdatedFields[5] = TRUE;
3828  break;
3829  case TODO_CATEGORY:
3830  if ((error = ALCATEL_UpdateField(s, Alcatel_byte, ToDo->Location, 6, &(ToDo->Entries[i].Number))) != ERR_NONE) return error;
3831  UpdatedFields[6] = TRUE;
3832  break;
3833  case TODO_CONTACTID:
3834  if ((error = ALCATEL_UpdateField(s, Alcatel_int, ToDo->Location, 8, &(ToDo->Entries[i].Number))) != ERR_NONE) return error;
3835  UpdatedFields[8] = TRUE;
3836  contact_set = TRUE;
3837  break;
3838  case TODO_PHONE:
3839  if ((error = ALCATEL_UpdateField(s, Alcatel_phone, ToDo->Location, 9, ToDo->Entries[i].Text)) != ERR_NONE) return error;
3840  UpdatedFields[9] = TRUE;
3841  phone_set = TRUE;
3842  break;
3843  default:
3844  break;
3845  }
3846  }
3847  if (!contact_set) {
3848  if (phone_set) {
3849  val = 0xffffffff;
3850  } else {
3851  val = 0;
3852  }
3853  if ((error = ALCATEL_UpdateField(s, Alcatel_int, ToDo->Location, 8, &val)) != ERR_NONE) return error;
3854  UpdatedFields[8] = TRUE;
3855  }
3856 
3857 
3858  /* If we didn't update some field, we have to delete it... */
3859  for (i=0; i<Priv->CurrentFieldsCount; i++) {
3860  if (!UpdatedFields[Priv->CurrentFields[i]]) if ((error = ALCATEL_DeleteField(s, ToDo->Location, Priv->CurrentFields[i])) != ERR_NONE) return error;
3861  }
3862  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error;
3863  return ERR_NONE;
3864 }
3865 
3866 static GSM_Error ALCATEL_DeleteToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
3867 {
3868  GSM_Error error;
3869 
3870  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error;
3871  /* Delete ToDo */
3872  if ((error = ALCATEL_GetAvailableIds(s, FALSE))!= ERR_NONE) return error;
3873  if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= ERR_NONE) {
3874  /* Entry was empty => no error */
3875  return ERR_NONE;
3876  }
3877  error = ALCATEL_DeleteItem(s, ToDo->Location);
3878  if (error != ERR_NONE) return error;
3879  /* Refresh list */
3880  if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= ERR_NONE) return error;
3881  if ((error = ALCATEL_GetAvailableIds(s, TRUE))!= ERR_NONE) return error;
3882  return ERR_NONE;
3883 }
3884 
3885 static GSM_Error ALCATEL_GetCategoryStatus(GSM_StateMachine *s, GSM_CategoryStatus *Status)
3886 {
3888  GSM_Error error;
3889  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3890 
3891  switch (Status->Type) {
3892  case Category_ToDo: type = TypeToDo; break;
3893  case Category_Phonebook: type = TypeContacts; break;
3894  default: return ERR_NOTSUPPORTED;
3895  }
3896  if ((error = ALCATEL_GoToBinaryState(s, StateSession, type, 0))!= ERR_NONE) return error;
3897  if ((error = ALCATEL_GetAvailableCategoryIds(s))!= ERR_NONE) return error;
3898 
3899  Status->Used = Priv->CurrentCategoriesCount;
3900 
3901  return ERR_NONE;
3902 }
3903 
3904 static GSM_Error ALCATEL_GetCategory(GSM_StateMachine *s, GSM_Category *Category)
3905 {
3907  GSM_Error error;
3908  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3909 
3910  switch (Category->Type) {
3911  case Category_ToDo: type = TypeToDo; break;
3912  case Category_Phonebook: type = TypeContacts; break;
3913  default: return ERR_NOTSUPPORTED;
3914  }
3915  if ((error = ALCATEL_GoToBinaryState(s, StateSession, type, 0))!= ERR_NONE) return error;
3916  if ((error = ALCATEL_GetAvailableCategoryIds(s))!= ERR_NONE) return error;
3917  if ((error = ALCATEL_IsCategoryIdAvailable(s, Category->Location))!= ERR_NONE) return error;
3918  if ((error = ALCATEL_GetCategoryText(s, Category->Location))!= ERR_NONE) return error;
3919 
3920  CopyUnicodeString(Category->Name, Priv->ReturnString);
3921 
3922  return ERR_NONE;
3923 }
3924 
3925 static GSM_Error ALCATEL_AddCategory(GSM_StateMachine *s, GSM_Category *Category)
3926 {
3928  GSM_Error error;
3929  GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3930 
3931  switch (Category->Type) {
3932  case Category_ToDo: type = TypeToDo; break;
3933  case Category_Phonebook: type = TypeContacts; break;
3934  default: return ERR_NOTSUPPORTED;
3935  }
3936  if ((error = ALCATEL_GoToBinaryState(s, StateSession, type, 0))!= ERR_NONE) return error;
3937  if ((error = ALCATEL_AddCategoryText(s, Category->Name))!= ERR_NONE) return error;
3938 
3939  Category->Location = Priv->ReturnInt;
3940 
3941  return ERR_NONE;
3942 }
3943 
3944 static GSM_Error ALCATEL_GetProductCode(GSM_StateMachine *s, char *value)
3945 {
3946  strcpy(value, s->Phone.Data.ModelInfo->model);
3947  return ERR_NONE;
3948 }
3949 
3950 static GSM_Error ALCATEL_DispatchMessage(GSM_StateMachine *s)
3951 {
3952  if (s->Phone.Data.Priv.ALCATEL.Mode == ModeBinary) {
3953  return GSM_DispatchMessage(s);
3954  } else {
3955  return ATGEN_DispatchMessage(s);
3956  }
3957 }
3958 
3959 static GSM_Error ALCATEL_ReplyGeneric(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3960 {
3961  /* All error values are just VERY wild guesses, but these seems to work
3962  * almost as expected ...
3963  */
3964  switch (msg->Buffer[8]) {
3965  case 0x00: /* no error */
3966  return ERR_NONE;
3967  case 0x0e: /* Opening session when not closed (might be also opened somewhere else) */
3968  case 0x10: /* Some thing opened in phone menus */
3969  return ERR_INSIDEPHONEMENU;
3970  case 0x13:
3971  /* This appears in more cases:
3972  * - phone needs PIN code
3973  * - we want to close not opened session
3974  * For normal users the second case shouldn't occur...
3975  */
3976  return ERR_SECURITYERROR;
3977  case 0x14: /* Bad data */
3978  return ERR_INVALIDDATA;
3979  case 0x2f: /* Closing session when not opened */
3980  case 0x1f: /* Bad in/out counter in packet/ack */
3981  case 0x0C: /* Bad id (item/database) */
3982  case 0x11: /* Bad list id */
3983  case 0x2A: /* Nonexistant field/item id */
3984  smprintf(s, "WARNING: Bug reply %02X\n", msg->Buffer[8]);
3985  return ERR_BUG;
3986  case 0x35: /* Too long text */
3987  return ERR_INVALIDDATA;
3988  case 0x23: /* Session opened */
3989  case 0x80: /* Transfer started */
3990  return ERR_NONE;
3991  case 0x82: /* Transfer canceled */
3992  return ERR_CANCELED;
3993  default:
3994  smprintf(s, "WARNING: Packet seems to indicate some status by %02X, ignoring!\n", msg->Buffer[8]);
3995  return ERR_NONE;
3996  }
3997 }
3998 
3999 static GSM_Error ALCATEL_ReplyCommit(GSM_Protocol_Message *msg, GSM_StateMachine *s)
4000 {
4001  s->Phone.Data.Priv.ALCATEL.CommitedRecord = msg->Buffer[12] + (msg->Buffer[11] << 8) + (msg->Buffer[10] << 16) + (msg->Buffer[9] << 24);
4002  smprintf(s, "Created record %08x\n", s->Phone.Data.Priv.ALCATEL.CommitedRecord);
4003  return ERR_NONE;
4004 }
4005 
4006 static GSM_Error ALCATEL_SetIncomingCB (GSM_StateMachine *s, gboolean enable)
4007 {
4008  GSM_Error error;
4009 
4010  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
4011  return ATGEN_SetIncomingCB(s, enable);
4012 }
4013 
4014 static GSM_Error ALCATEL_SetIncomingSMS (GSM_StateMachine *s, gboolean enable)
4015 {
4016  GSM_Error error;
4017 
4018  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
4019  return ATGEN_SetIncomingSMS(s, enable);
4020 }
4021 
4022 static GSM_Error ALCATEL_SetFastSMSSending(GSM_StateMachine *s, gboolean enable)
4023 {
4024  GSM_Error error;
4025 
4026  if ((error = ALCATEL_SetATMode(s))!= ERR_NONE) return error;
4027  return ATGEN_SetFastSMSSending(s, enable);
4028 }
4029 
4030 GSM_Reply_Function ALCATELReplyFunctions[] = {
4031 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelAttach },
4032 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDetach },
4033 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelCommit },
4034 {ALCATEL_ReplyCommit, "\x02",0x00,0x00, ID_AlcatelCommit2 },
4035 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelEnd },
4036 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelClose },
4037 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelStart },
4038 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect1 },
4039 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect2 },
4040 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect3 },
4041 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelBegin1 },
4042 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelBegin2 },
4043 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetIds1 },
4044 {ALCATEL_ReplyGetIds, "\x02",0x00,0x00, ID_AlcatelGetIds2 },
4045 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetCategories1 },
4046 {ALCATEL_ReplyGetCategories, "\x02",0x00,0x00, ID_AlcatelGetCategories2 },
4047 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetCategoryText1 },
4048 {ALCATEL_ReplyGetCategoryText, "\x02",0x00,0x00, ID_AlcatelGetCategoryText2 },
4049 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelAddCategoryText1 },
4050 {ALCATEL_ReplyAddCategoryText, "\x02",0x00,0x00, ID_AlcatelAddCategoryText2 },
4051 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetFields1 },
4052 {ALCATEL_ReplyGetFields, "\x02",0x00,0x00, ID_AlcatelGetFields2 },
4053 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetFieldValue1 },
4054 {ALCATEL_ReplyGetFieldValue, "\x02",0x00,0x00, ID_AlcatelGetFieldValue2 },
4055 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDeleteField },
4056 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDeleteItem1 },
4057 {ALCATEL_ReplyDeleteItem, "\x02",0x00,0x00, ID_AlcatelDeleteItem2 },
4058 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelCreateField },
4059 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelUpdateField },
4060 {NULL, "\x00",0x00,0x00, ID_None }
4061 };
4062 
4063 GSM_Phone_Functions ALCATELPhone = {
4064  /* AFAIK, any 50[0123] phone should work, but I'm not sure whether all
4065  * they were ever really released, if yes add them here also.
4066  */
4067  "alcatel|OT501|OT701|OT715|OT535|OT735|BE5|BF5|BH4",
4068  ALCATELReplyFunctions,
4069  NOTSUPPORTED, /* Install */
4070  ALCATEL_Initialise,
4071  ALCATEL_Terminate,
4072  ALCATEL_DispatchMessage,
4073  NOTSUPPORTED, /* ShowStartInfo */
4074  ALCATEL_GetManufacturer,
4075  ALCATEL_GetModel,
4076  ALCATEL_GetFirmware,
4077  ALCATEL_GetIMEI,
4078  NOTSUPPORTED, /* GetOriginalIMEI */
4079  NOTSUPPORTED, /* GetManufactureMonth */
4080  ALCATEL_GetProductCode,
4081  NOTSUPPORTED, /* GetHardware */
4082  NOTSUPPORTED, /* GetPPM */
4083  ALCATEL_GetSIMIMSI,
4084  ALCATEL_GetDateTime,
4085  ALCATEL_SetDateTime,
4086  ALCATEL_GetAlarm,
4087  ALCATEL_SetAlarm,
4088  NOTSUPPORTED, /* GetLocale */
4089  NOTSUPPORTED, /* SetLocale */
4090  ALCATEL_PressKey,
4091  ALCATEL_Reset,
4092  ALCATEL_ResetPhoneSettings,
4093  ALCATEL_EnterSecurityCode,
4094  ALCATEL_GetSecurityStatus,
4095  ALCATEL_GetDisplayStatus,
4096  ALCATEL_SetAutoNetworkLogin,
4097  ALCATEL_GetBatteryCharge,
4098  ALCATEL_GetSignalStrength,
4099  ALCATEL_GetNetworkInfo,
4100  ALCATEL_GetCategory,
4101  ALCATEL_AddCategory,
4102  ALCATEL_GetCategoryStatus,
4103  ALCATEL_GetMemoryStatus,
4104  ALCATEL_GetMemory,
4105  ALCATEL_GetNextMemory,
4106  ALCATEL_SetMemory,
4107  ALCATEL_AddMemory,
4108  ALCATEL_DeleteMemory,
4109  ALCATEL_DeleteAllMemory,
4110  NOTSUPPORTED, /* GetSpeedDial */
4111  NOTSUPPORTED, /* SetSpeedDial */
4112  ALCATEL_GetSMSC,
4113  ALCATEL_SetSMSC,
4114  ALCATEL_GetSMSStatus,
4115  ALCATEL_GetSMS,
4116  ALCATEL_GetNextSMS,
4117  NOTSUPPORTED, /* SetSMS */
4118  ALCATEL_AddSMS,
4119  ALCATEL_DeleteSMS,
4120  ALCATEL_SendSMS,
4121  ALCATEL_SendSavedSMS,
4122  ALCATEL_SetFastSMSSending,
4123  ALCATEL_SetIncomingSMS,
4124  ALCATEL_SetIncomingCB,
4125  ALCATEL_GetSMSFolders,
4126  NOTSUPPORTED, /* AddSMSFolder */
4127  NOTSUPPORTED, /* DeleteSMSFolder */
4128  ALCATEL_DialVoice,
4129  ALCATEL_DialService,
4130  ALCATEL_AnswerCall,
4131  ALCATEL_CancelCall,
4132  NOTSUPPORTED, /* HoldCall */
4133  NOTSUPPORTED, /* UnholdCall */
4134  NOTSUPPORTED, /* ConferenceCall */
4135  NOTSUPPORTED, /* SplitCall */
4136  NOTSUPPORTED, /* TransferCall */
4137  NOTSUPPORTED, /* SwitchCall */
4138  NOTSUPPORTED, /* GetCallDivert */
4139  NOTSUPPORTED, /* SetCallDivert */
4140  NOTSUPPORTED, /* CancelAllDiverts */
4141  NONEFUNCTION, /* SetIncomingCall */
4142  NOTSUPPORTED, /* SetIncomingUSSD */
4143  ALCATEL_SendDTMF,
4144  NOTSUPPORTED, /* GetRingtone */
4145  NOTSUPPORTED, /* SetRingtone */
4146  NOTSUPPORTED, /* GetRingtonesInfo */
4147  NOTSUPPORTED, /* DeleteUserRingtones */
4148  NOTSUPPORTED, /* PlayTone */
4149  NOTSUPPORTED, /* GetWAPBookmark */
4150  NOTSUPPORTED, /* SetWAPBookmark */
4151  NOTSUPPORTED, /* DeleteWAPBookmark */
4152  NOTSUPPORTED, /* GetWAPSettings */
4153  NOTSUPPORTED, /* SetWAPSettings */
4154  NOTSUPPORTED, /* GetSyncMLSettings */
4155  NOTSUPPORTED, /* SetSyncMLSettings */
4156  NOTSUPPORTED, /* GetChatSettings */
4157  NOTSUPPORTED, /* SetChatSettings */
4158  NOTSUPPORTED, /* GetMMSSettings */
4159  NOTSUPPORTED, /* SetMMSSettings */
4160  NOTSUPPORTED, /* GetMMSFolders */
4161  NOTSUPPORTED, /* GetNextMMSFileInfo */
4162  NOTSUPPORTED, /* GetBitmap */
4163  NOTSUPPORTED, /* SetBitmap */
4164  ALCATEL_GetToDoStatus,
4165  ALCATEL_GetToDo,
4166  ALCATEL_GetNextToDo,
4167  ALCATEL_SetToDo,
4168  ALCATEL_AddToDo,
4169  ALCATEL_DeleteToDo,
4170  ALCATEL_DeleteAllToDo,
4171  ALCATEL_GetCalendarStatus,
4172  ALCATEL_GetCalendar,
4173  ALCATEL_GetNextCalendar,
4174  ALCATEL_SetCalendar,
4175  ALCATEL_AddCalendar,
4176  ALCATEL_DeleteCalendar,
4177  ALCATEL_DeleteAllCalendar,
4178  NOTSUPPORTED, /* GetCalendarSettings */
4179  NOTSUPPORTED, /* SetCalendarSettings */
4180  NOTSUPPORTED, /* GetNoteStatus */
4181  NOTSUPPORTED, /* GetNote */
4182  NOTSUPPORTED, /* GetNextNote */
4183  NOTSUPPORTED, /* SetNote */
4184  NOTSUPPORTED, /* AddNote */
4185  NOTSUPPORTED, /* DeleteNote */
4186  NOTSUPPORTED, /* DeleteAllNotes */
4187  NOTSUPPORTED, /* GetProfile */
4188  NOTSUPPORTED, /* SetProfile */
4189  NOTSUPPORTED, /* GetFMStation */
4190  NOTSUPPORTED, /* SetFMStation */
4191  NOTSUPPORTED, /* ClearFMStations */
4192  NOTSUPPORTED, /* GetNextFileFolder */
4193  NOTSUPPORTED, /* GetFolderListing */
4194  NOTSUPPORTED, /* GetNextRootFolder */
4195  NOTSUPPORTED, /* SetFileAttributes */
4196  NOTSUPPORTED, /* GetFilePart */
4197  NOTSUPPORTED, /* AddFilePart */
4198  NOTSUPPORTED, /* SendFilePart */
4199  NOTSUPPORTED, /* GetFileSystemStatus */
4200  NOTSUPPORTED, /* DeleteFile */
4201  NOTSUPPORTED, /* AddFolder */
4202  NOTSUPPORTED, /* DeleteFolder */
4203  NOTSUPPORTED, /* GetGPRSAccessPoint */
4204  NOTSUPPORTED, /* SetGPRSAccessPoint */
4205  NOTSUPPORTED, /* GetScreenshot */
4206  NOTSUPPORTED, /* SetPower */
4207  NOTSUPPORTED, /* PostConnect */
4208  NONEFUNCTION /* PreAPICall */
4209 };
4210 
4211 #endif
4212 #endif
4213 
4216 
4217 /* How should editor hadle tabs in this file? Add editor commands here.
4218  * vim: noexpandtab sw=8 ts=8 sts=8:
4219  */
#define ALCATEL_FREE_MEMORY
Definition: alcatel.h:151
Definition: alcatel.h:68
GSM_Error ATGEN_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
GSM_Error ATGEN_AnswerCall(GSM_StateMachine *s, int ID, gboolean all)
GSM_Error ATGEN_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat)
char * DecodeUnicodeString(const unsigned char *src)
Definition: coding.c:245
GSM_Alcatel_BinaryType BinaryType
Definition: alcatel.h:182
void CopyUnicodeString(unsigned char *Dest, const unsigned char *Source)
Definition: coding.c:1192
void DecodeDefault(unsigned char *dest, const unsigned char *src, size_t len, gboolean UseExtensions, unsigned char *ExtraAlphabet)
Definition: coding.c:498
GSM_ToDo_Priority Priority
GSM_Error ATGEN_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
GSM_Error ATGEN_HandleCMEError(GSM_StateMachine *s)
GSM_Error ATGEN_DialService(GSM_StateMachine *s, char *number)
GSM_MemoryType MemoryType
Definition: gammu-memory.h:415
#define GSM_PHONEBOOK_TEXT_LENGTH
Definition: gammu-limits.h:91
GSM_Alcatel_BinaryState BinaryState
Definition: alcatel.h:177
unsigned int Number
GSM_Error ATGEN_ResetPhoneSettings(GSM_StateMachine *s, GSM_ResetSettingsType Type)
GSM_CalendarNoteType Type
int CurrentFields[GSM_PHONEBOOK_ENTRIES+1]
Definition: alcatel.h:260
GSM_Alcatel_BinaryType
Definition: alcatel.h:92
#define NOTSUPPORTED
Definition: gsmcomon.h:14
#define GSM_MAX_CATEGORY_NAME_LENGTH
Definition: gammu-limits.h:260
GSM_Error ATGEN_Reset(GSM_StateMachine *s, gboolean hard)
#define GSM_PHONEBOOK_ENTRIES
Definition: gammu-limits.h:98
int CurrentCategories[ALCATEL_MAX_CATEGORIES+1]
Definition: alcatel.h:279
GSM_Error ATGEN_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders)
GSM_DateTime DateTime
unsigned char ReturnString[(GSM_PHONEBOOK_TEXT_LENGTH+1) *2]
Definition: alcatel.h:219
GSM_Error ATGEN_SendDTMF(GSM_StateMachine *s, char *sequence)
GSM_Error ATGEN_GetModel(GSM_StateMachine *s)
GSM_Error ATGEN_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
GSM_Error ATGEN_DeleteSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
GSM_CategoryType Type
GSM_Error ATGEN_Terminate(GSM_StateMachine *s)
GSM_Error ATGEN_HandleCMSError(GSM_StateMachine *s)
GSM_DateTime ReturnDateTime
Definition: alcatel.h:211
GSM_Error GSM_DispatchMessage(GSM_StateMachine *s)
Definition: gsmstate.c:1131
#define NONEFUNCTION
Definition: gsmcomon.h:12
GSM_Error
Definition: gammu-error.h:23
GSM_Error ATGEN_GetDisplayStatus(GSM_StateMachine *s, GSM_DisplayFeatures *features)
#define ALCATEL_MAX_LOCATION
Definition: alcatel.h:157
GSM_Error ATGEN_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status)
GSM_Error ATGEN_Initialise(GSM_StateMachine *s)
GSM_Alcatel_BinaryType CurrentFieldsType
Definition: alcatel.h:274
const char * model
Definition: gammu-info.h:764
GSM_CallShowNumber
Definition: gammu-call.h:192
size_t UnicodeLength(const unsigned char *str)
Definition: coding.c:186
unsigned char Name[(GSM_MAX_CATEGORY_NAME_LENGTH+1) *2]
const char features[]
Definition: feature_tests.c:2
GSM_Error ATGEN_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
GSM_Error ATGEN_CancelCall(GSM_StateMachine *s, int ID, gboolean all)
GSM_Error ATGEN_SetFastSMSSending(GSM_StateMachine *s, gboolean enable)
GSM_Error ATGEN_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
GSM_Error ATGEN_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status)
GSM_Error ATGEN_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo)
GSM_Error ATGEN_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber)
char Manufacturer[GSM_MAX_MANUFACTURER_LENGTH+1]
Definition: gsmstate.h:441
GSM_PhoneModel * ModelInfo
Definition: gsmstate.h:449
GSM_Alcatel_ProtocolVersion ProtocolVersion
Definition: alcatel.h:190
unsigned char Text[(GSM_MAX_CALENDAR_TEXT_LENGTH+1) *2]
unsigned int ReturnInt
Definition: alcatel.h:215
GSM_EntryType EntryType
Definition: gammu-memory.h:372
gboolean TransferCompleted
Definition: alcatel.h:203
GSM_ToDoType EntryType
GSM_Error(* Initialise)(GSM_StateMachine *s)
Definition: gsmstate.h:356
GSM_Error ATGEN_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
unsigned char Text[(GSM_PHONEBOOK_TEXT_LENGTH+1) *2]
Definition: gammu-memory.h:399
int gboolean
Definition: gammu-types.h:23
GSM_Alcatel_Mode Mode
Definition: alcatel.h:173
GSM_MemoryType
Definition: gammu-memory.h:31
GSM_Error ATGEN_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
GSM_Error ATGEN_GetSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms)
GSM_CalendarNoteType Type
GSM_Phone Phone
Definition: gsmstate.h:1431
#define FALSE
Definition: gammu-types.h:25
struct GSM_Phone_Data::@2 Priv
GSM_SubToDoEntry Entries[GSM_TODO_ENTRIES]
GSM_Reply_Function ATGENReplyFunctions[]
GSM_Alcatel_BinaryState
Definition: alcatel.h:74
GSM_SecurityCodeType
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
Definition: alcatel.h:50
GSM_Error ATGEN_DeleteAllMemory(GSM_StateMachine *s, GSM_MemoryType type)
GSM_Error ATGEN_SendSavedSMS(GSM_StateMachine *s, int Folder, int Location)
GSM_Error ATGEN_SendSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
GSM_Alcatel_FieldType
Definition: alcatel.h:110
gboolean CheckTime(GSM_DateTime *date)
Definition: misc.c:363
GSM_Error ATGEN_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, gboolean Press)
GSM_Error ATGEN_GetNextSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboolean start)
GSM_CalendarType EntryType
GSM_Protocol Protocol
Definition: gsmstate.h:1430
GSM_Error ATGEN_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status)
gboolean mywstrncmp(unsigned const char *a, unsigned const char *b, int num)
Definition: coding.c:1457
GSM_Error ATGEN_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
GSM_Error ATGEN_SetAutoNetworkLogin(GSM_StateMachine *s)
GSM_CategoryType Type
GSM_Phone_Data Data
Definition: gsmstate.h:1369
GSM_KeyCode
Definition: gammu-keys.h:30
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
GSM_MemoryType MemoryType
Definition: gammu-memory.h:131
void GSM_GetCurrentDateTime(GSM_DateTime *Date)
Definition: misc.c:184
GSM_Error(* Terminate)(GSM_StateMachine *s)
Definition: gsmstate.h:360
GSM_Phone_Functions * Functions
Definition: gsmstate.h:1373
GSM_Alcatel_FieldType ReturnType
Definition: alcatel.h:207
GSM_EntryLocation Location
Definition: gammu-memory.h:376
GSM_Error ATGEN_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
GSM_Error ATGEN_GetNextMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry, gboolean start)
char CurrentCategoriesCache[ALCATEL_MAX_CATEGORIES+1][(GSM_MAX_CATEGORY_NAME_LENGTH+1) *2]
Definition: alcatel.h:284
GSM_Error ATGEN_GetIMEI(GSM_StateMachine *s)
GSM_Alcatel_BinaryType CurrentCategoriesType
Definition: alcatel.h:292
GSM_Reply_Function * ReplyFunctions
Definition: gsmstate.h:748
GSM_Protocol_Functions * Functions
Definition: gsmstate.h:424
#define TRUE
Definition: gammu-types.h:28
GSM_Error ATGEN_DispatchMessage(GSM_StateMachine *s)
unsigned char * Buffer
Definition: protocol.h:22
unsigned char Text[(GSM_MAX_TODO_TEXT_LENGTH+1) *2]
#define UNUSED
Definition: gammu-misc.h:105
void EncodeDefault(unsigned char *dest, const unsigned char *src, size_t *len, gboolean UseExtensions, unsigned char *ExtraAlphabet)
Definition: coding.c:831
gboolean CheckDate(GSM_DateTime *date)
Definition: misc.c:349
GSM_Error ATGEN_SetIncomingCB(GSM_StateMachine *s, gboolean enable)
gboolean Repeating
GSM_DateTime Date
GSM_Error ATGEN_GetSIMIMSI(GSM_StateMachine *s, char *IMSI)
GSM_Error ATGEN_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig)
unsigned char Text[(GSM_MAX_CALENDAR_TEXT_LENGTH+1) *2]
GSM_Error ATGEN_SetIncomingSMS(GSM_StateMachine *s, gboolean enable)
GSM_Error ATGEN_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode *Code)
GSM_ResetSettingsType
#define ALCATEL_MAX_CATEGORIES
Definition: alcatel.h:161
GSM_Error ATGEN_GetFirmware(GSM_StateMachine *s)
int smprintf(GSM_StateMachine *s, const char *format,...)
Definition: debug.c:261
Definition: alcatel.h:64
GSM_SubMemoryEntry Entries[GSM_PHONEBOOK_ENTRIES]
Definition: gammu-memory.h:427