Gammu internals  1.38.0
samsung.c
Go to the documentation of this file.
1 /* Samsung-specific functions
2  * Copyright (C) 2004 Claudio Matsuoka <cmatsuoka@gmail.com>
3  * Copyright (c) 2009 Michal Cihar <michal@cihar.com>
4  */
5 
6 #include <gammu-config.h>
7 
8 #ifdef GSM_ENABLE_ATGEN
9 
10 #include <string.h>
11 #include <time.h>
12 #include <ctype.h>
13 
14 #include "../../misc/coding/coding.h"
15 #include "../../gsmcomon.h"
16 #include "../pfunc.h"
17 
18 #include "atgen.h"
19 #include "samsung.h"
20 
21 /* Binary frame size */
22 #define BLKSZ 1024
23 
24 struct ModelRes {
25  const char *model;
26  const size_t width;
27  const size_t height;
28 };
29 
30 static struct ModelRes modres[] = {
31  { "S100", 128, 128 },
32  { "S200", 128, 113 },
33  { "S300", 128, 97 },
34  { "S500", 128, 128 },
35  { "T100", 128, 128 },
36  { "E700", 128, 128 },
37  { NULL, 0, 0 }
38 };
39 
40 /*
41  * CRC functions from the Granch SBNI12 Linux driver by
42  * Denis I. Timofeev <timofeev@granch.ru>
43  */
44 static unsigned int crc32tab[] = {
45  0xD202EF8D, 0xA505DF1B, 0x3C0C8EA1, 0x4B0BBE37,
46  0xD56F2B94, 0xA2681B02, 0x3B614AB8, 0x4C667A2E,
47  0xDCD967BF, 0xABDE5729, 0x32D70693, 0x45D03605,
48  0xDBB4A3A6, 0xACB39330, 0x35BAC28A, 0x42BDF21C,
49  0xCFB5FFE9, 0xB8B2CF7F, 0x21BB9EC5, 0x56BCAE53,
50  0xC8D83BF0, 0xBFDF0B66, 0x26D65ADC, 0x51D16A4A,
51  0xC16E77DB, 0xB669474D, 0x2F6016F7, 0x58672661,
52  0xC603B3C2, 0xB1048354, 0x280DD2EE, 0x5F0AE278,
53  0xE96CCF45, 0x9E6BFFD3, 0x0762AE69, 0x70659EFF,
54  0xEE010B5C, 0x99063BCA, 0x000F6A70, 0x77085AE6,
55  0xE7B74777, 0x90B077E1, 0x09B9265B, 0x7EBE16CD,
56  0xE0DA836E, 0x97DDB3F8, 0x0ED4E242, 0x79D3D2D4,
57  0xF4DBDF21, 0x83DCEFB7, 0x1AD5BE0D, 0x6DD28E9B,
58  0xF3B61B38, 0x84B12BAE, 0x1DB87A14, 0x6ABF4A82,
59  0xFA005713, 0x8D076785, 0x140E363F, 0x630906A9,
60  0xFD6D930A, 0x8A6AA39C, 0x1363F226, 0x6464C2B0,
61  0xA4DEAE1D, 0xD3D99E8B, 0x4AD0CF31, 0x3DD7FFA7,
62  0xA3B36A04, 0xD4B45A92, 0x4DBD0B28, 0x3ABA3BBE,
63  0xAA05262F, 0xDD0216B9, 0x440B4703, 0x330C7795,
64  0xAD68E236, 0xDA6FD2A0, 0x4366831A, 0x3461B38C,
65  0xB969BE79, 0xCE6E8EEF, 0x5767DF55, 0x2060EFC3,
66  0xBE047A60, 0xC9034AF6, 0x500A1B4C, 0x270D2BDA,
67  0xB7B2364B, 0xC0B506DD, 0x59BC5767, 0x2EBB67F1,
68  0xB0DFF252, 0xC7D8C2C4, 0x5ED1937E, 0x29D6A3E8,
69  0x9FB08ED5, 0xE8B7BE43, 0x71BEEFF9, 0x06B9DF6F,
70  0x98DD4ACC, 0xEFDA7A5A, 0x76D32BE0, 0x01D41B76,
71  0x916B06E7, 0xE66C3671, 0x7F6567CB, 0x0862575D,
72  0x9606C2FE, 0xE101F268, 0x7808A3D2, 0x0F0F9344,
73  0x82079EB1, 0xF500AE27, 0x6C09FF9D, 0x1B0ECF0B,
74  0x856A5AA8, 0xF26D6A3E, 0x6B643B84, 0x1C630B12,
75  0x8CDC1683, 0xFBDB2615, 0x62D277AF, 0x15D54739,
76  0x8BB1D29A, 0xFCB6E20C, 0x65BFB3B6, 0x12B88320,
77  0x3FBA6CAD, 0x48BD5C3B, 0xD1B40D81, 0xA6B33D17,
78  0x38D7A8B4, 0x4FD09822, 0xD6D9C998, 0xA1DEF90E,
79  0x3161E49F, 0x4666D409, 0xDF6F85B3, 0xA868B525,
80  0x360C2086, 0x410B1010, 0xD80241AA, 0xAF05713C,
81  0x220D7CC9, 0x550A4C5F, 0xCC031DE5, 0xBB042D73,
82  0x2560B8D0, 0x52678846, 0xCB6ED9FC, 0xBC69E96A,
83  0x2CD6F4FB, 0x5BD1C46D, 0xC2D895D7, 0xB5DFA541,
84  0x2BBB30E2, 0x5CBC0074, 0xC5B551CE, 0xB2B26158,
85  0x04D44C65, 0x73D37CF3, 0xEADA2D49, 0x9DDD1DDF,
86  0x03B9887C, 0x74BEB8EA, 0xEDB7E950, 0x9AB0D9C6,
87  0x0A0FC457, 0x7D08F4C1, 0xE401A57B, 0x930695ED,
88  0x0D62004E, 0x7A6530D8, 0xE36C6162, 0x946B51F4,
89  0x19635C01, 0x6E646C97, 0xF76D3D2D, 0x806A0DBB,
90  0x1E0E9818, 0x6909A88E, 0xF000F934, 0x8707C9A2,
91  0x17B8D433, 0x60BFE4A5, 0xF9B6B51F, 0x8EB18589,
92  0x10D5102A, 0x67D220BC, 0xFEDB7106, 0x89DC4190,
93  0x49662D3D, 0x3E611DAB, 0xA7684C11, 0xD06F7C87,
94  0x4E0BE924, 0x390CD9B2, 0xA0058808, 0xD702B89E,
95  0x47BDA50F, 0x30BA9599, 0xA9B3C423, 0xDEB4F4B5,
96  0x40D06116, 0x37D75180, 0xAEDE003A, 0xD9D930AC,
97  0x54D13D59, 0x23D60DCF, 0xBADF5C75, 0xCDD86CE3,
98  0x53BCF940, 0x24BBC9D6, 0xBDB2986C, 0xCAB5A8FA,
99  0x5A0AB56B, 0x2D0D85FD, 0xB404D447, 0xC303E4D1,
100  0x5D677172, 0x2A6041E4, 0xB369105E, 0xC46E20C8,
101  0x72080DF5, 0x050F3D63, 0x9C066CD9, 0xEB015C4F,
102  0x7565C9EC, 0x0262F97A, 0x9B6BA8C0, 0xEC6C9856,
103  0x7CD385C7, 0x0BD4B551, 0x92DDE4EB, 0xE5DAD47D,
104  0x7BBE41DE, 0x0CB97148, 0x95B020F2, 0xE2B71064,
105  0x6FBF1D91, 0x18B82D07, 0x81B17CBD, 0xF6B64C2B,
106  0x68D2D988, 0x1FD5E91E, 0x86DCB8A4, 0xF1DB8832,
107  0x616495A3, 0x1663A535, 0x8F6AF48F, 0xF86DC419,
108  0x660951BA, 0x110E612C, 0x88073096, 0xFF000000
109 };
110 
111 static unsigned int GetCRC(char *data, int size)
112 {
113  unsigned int crc = 0;
114 
115  while (size--)
116  crc = crc32tab[(crc ^ *data++) & 0xff] ^ ((crc >> 8) & 0x00FFFFFF);
117 
118  return crc;
119 }
120 
121 /*
122  * Frame transfer
123  */
124 
125 static GSM_Error WaitFor(GSM_StateMachine *s, const char *t, int ttl)
126 {
127  char readbuf[100]={0};
128  int n=0,sec=0;
129  GSM_DateTime Date;
130 
131  GSM_GetCurrentDateTime (&Date);
132  sec = Date.Second;
133 
134  n = s->Device.Functions->ReadDevice(s, readbuf, sizeof(readbuf) - 1);
135  readbuf[n] = '\0';
136 
137  while (strstr(readbuf, t) == NULL && (sec + ttl) >= Date.Second) {
138  usleep(500000);
139  n = s->Device.Functions->ReadDevice(s, readbuf, sizeof(readbuf) - 1);
140  readbuf[n] = '\0';
141  GSM_GetCurrentDateTime (&Date);
142  }
143 
144  return (sec + ttl) >= Date.Second ? ERR_NONE : ERR_TIMEOUT;
145 }
146 
147 static GSM_Error SetSamsungFrame(GSM_StateMachine *s, unsigned char *buff, int size, GSM_Phone_RequestID id)
148 {
149  GSM_Phone_Data *Phone = &s->Phone.Data;
150  GSM_Error error;
151  int i, count;
152 
153  count = size / BLKSZ;
154 
155  for (i = 0; i < count; i++) {
156  error = WaitFor(s, ">", 4);
157  if (error!=ERR_NONE) return error;
158 
159  error = s->Protocol.Functions->WriteMessage(s,
160  buff + i * BLKSZ, BLKSZ, 0x00);
161  if (error!=ERR_NONE) return error;
162  }
163 
164  error = WaitFor(s, ">", 4);
165  if (error!=ERR_NONE) return error;
166  error = s->Protocol.Functions->WriteMessage(s,
167  buff + i * BLKSZ, size%BLKSZ, 0x00);
168  if (error!=ERR_NONE) return error;
169 
170  error = GSM_WaitFor(s, "", 0, 0x00, 4, id);
171  if (error!=ERR_NONE) return error;
172 
173  return Phone->DispatchError;
174 }
175 
176 /* Answer format for binary data transfer
177  *
178  * SDNDCRC = 0xa : RECEIVECRC = 0xcbf53a1c : BINSIZE = 5
179  * CRCERR
180  */
181 static GSM_Error ReplySetSamsungFrame(GSM_Protocol_Message *msg, GSM_StateMachine *s)
182 {
183  unsigned long txcrc, rxcrc;
184  int binsize;
185  char *pos;
186 
187  /* Parse SDNDCRC */
188  pos = strchr(msg->Buffer, '=');
189  if (!pos) return ERR_UNKNOWN;
190  pos++;
191  txcrc = strtoul(pos, NULL, 0);
192  smprintf(s, "Sent CRC : 0x%lx\n", txcrc);
193 
194  /* Parse RECEIVECRC */
195  pos = strchr(pos, '=');
196  if (!pos) return ERR_UNKNOWN;
197  pos++;
198  rxcrc = strtoul(pos, NULL, 0);
199  smprintf(s, "Reveived CRC : 0x%lx\n", rxcrc);
200 
201  /* Parse BINSIZE */
202  pos = strchr(pos, '=');
203  if (!pos) return ERR_UNKNOWN;
204  pos++;
205  binsize = strtoul(pos, NULL, 0);
206  smprintf(s, "Binary size : %d\n", binsize);
207 
208  return txcrc == rxcrc ? ERR_NONE : ERR_WRONGCRC;
209 }
210 
211 /*
212  * Bitmaps
213  */
214 
216 {
217  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
218  char buffer[32];
219  char *pos;
220  int location, count;
221 
222  switch (Priv->ReplyState) {
223  case AT_Reply_OK:
224  smprintf(s, "Bitmap info received\n");
225  /* Parse +IMGR:location,name,0,0,0,0 */
226 
227  /* Parse location */
228  pos = strchr(msg->Buffer, ':');
229  if (!pos) return ERR_UNKNOWN;
230  pos++;
231  location = atoi(pos);
232  smprintf(s, "Location : %d\n", location);
233 
234  /* Parse name */
235  pos = strchr(pos, '"');
236  if (!pos) return ERR_UNKNOWN;
237  pos++;
238  for (count = 0; count < 31; count++) {
239  if (pos[count] == '"')
240  break;
241  buffer[count] = pos[count];
242  }
243  buffer[count] = 0;
244  smprintf(s, "Name : %s\n", buffer);
245  EncodeUnicode(s->Phone.Data.Bitmap->Name, buffer, strlen(buffer));
246 
247  s->Phone.Data.Bitmap->Location = location;
248 
249  return ERR_NONE;
250  case AT_Reply_Error:
251  return ERR_NOTSUPPORTED;
252  case AT_Reply_CMSError:
253  return ATGEN_HandleCMSError(s);
254  case AT_Reply_CMEError:
255  return ATGEN_HandleCMEError(s);
256  default:
257  return ERR_UNKNOWNRESPONSE;
258  }
259 }
260 
262 {
263  smprintf(s, "Bitmap sent\n");
264  return ReplySetSamsungFrame(msg, s);
265 }
266 
268 {
269  unsigned char req[100];
270  size_t len;
271 
272  s->Phone.Data.Bitmap=Bitmap;
273  smprintf(s, "Getting bitmap\n");
274  len = sprintf(req, "AT+IMGR=%d\r", Bitmap->Location-1);
275  return GSM_WaitFor (s, req, len, 0x00, 4, ID_GetBitmap);
276 }
277 
279 {
280  unsigned char req[100];
281  unsigned long crc;
282  GSM_Error error;
283  char name[50], *dot;
284  const char *model;
285  GSM_Phone_Data *Data = &s->Phone.Data;
286  int i;
287  size_t len;
288 
289  s->Phone.Data.Bitmap = Bitmap;
290  smprintf(s, "Setting bitmap\n");
291 
292  if (Bitmap->Type != GSM_PictureBinary) {
293  smprintf(s, "Invalid picture type\n");
294  return ERR_INVALIDDATA;
295  }
296 
297  if (Bitmap->BinaryPic.Type != PICTURE_GIF) {
298  smprintf(s, "Invalid binary picture type\n");
299  return ERR_INVALIDDATA;
300  }
301 
302  /* Check if picture size matches phone model */
303  model = Data->ModelInfo->model;
304  smprintf(s, "Checking picture size for %s\n", model);
305  for (i = 0; modres[i].model; i++) {
306  if (!strcmp(model, modres[i].model)) {
307  if (Bitmap->BitmapWidth != modres[i].width ||
308  Bitmap->BitmapHeight != modres[i].height) {
309  smprintf(s, "Model %s must use %ld x %ld picture size\n",
310  modres[i].model,
311  (long)modres[i].width,
312  (long)modres[i].height);
313  return ERR_INVALIDDATA;
314  }
315  break;
316  }
317  }
318  if (modres[i].model == NULL) {
319  smprintf(s, "Model \"%s\" is not supported.\n", Data->Model);
320  return ERR_NOTSUPPORTED;
321  }
322 
323  crc = GetCRC(Bitmap->BinaryPic.Buffer, Bitmap->BinaryPic.Length);
324 
325  /* Remove extension from file name */
326  strncpy(name, DecodeUnicodeString(Bitmap->Name), 50);
327  name[49] = '\0';
328  if ((dot = strrchr(name, '.')) != NULL)
329  *dot = 0;
330 
331  len = sprintf(req, "AT+IMGW=0,\"%s\",2,0,0,0,0,100,%ld,%u\r", name,
332  (long int)Bitmap->BinaryPic.Length, (unsigned int)crc);
333 
334  error = s->Protocol.Functions->WriteMessage(s, req, len, 0x00);
335  if (error!=ERR_NONE) return error;
336 
337  return SetSamsungFrame(s, Bitmap->BinaryPic.Buffer,
338  Bitmap->BinaryPic.Length, ID_SetBitmap);
339 }
340 
341 /*
342  * Ringtones
343  */
344 
346 {
347  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
348  unsigned char buffer[32];
349  char *pos;
350  int location, length, count;
351 
352  switch (Priv->ReplyState) {
353  case AT_Reply_OK:
354  smprintf(s, "Ringtone info received\n");
355  /* Parse +MELR:location,name,size */
356 
357  /* Parse location */
358  pos = strchr(msg->Buffer, ':');
359  if (!pos) return ERR_UNKNOWN;
360  pos++;
361  location = atoi(pos);
362  smprintf(s, "Location : %d\n", location);
363 
364  /* Parse name */
365  pos = strchr(pos, '"');
366  if (!pos) return ERR_UNKNOWN;
367  pos++;
368  /* Ringtone.Name size is 20 chars */
369  for (count = 0; count < 19; count++) {
370  if (pos[count] == '"')
371  break;
372  buffer[count] = pos[count];
373  }
374  buffer[count] = 0;
375  smprintf(s, "Name : %s\n", buffer);
376  EncodeUnicode(s->Phone.Data.Ringtone->Name,buffer,strlen(buffer));
377 
378  /* Parse ringtone length */
379  pos = strchr(pos, ',');
380  if (!pos) return ERR_UNKNOWN;
381  pos++;
382  length = atoi(pos);
383  smprintf(s, "Length : %d\n", length);
384 
385  /* S300 ringtones are always MMF */
387  s->Phone.Data.Ringtone->Location = location;
388  s->Phone.Data.Ringtone->BinaryTone.Length = length;
389 
390  return ERR_NONE;
391  case AT_Reply_Error:
392  return ERR_UNKNOWN;
393  case AT_Reply_CMSError:
394  return ATGEN_HandleCMSError(s);
395  case AT_Reply_CMEError:
396  return ATGEN_HandleCMEError(s);
397  default:
398  return ERR_UNKNOWNRESPONSE;
399  }
400 }
401 
403 {
404  unsigned char req[100];
405  size_t len;
406 
407  s->Phone.Data.Ringtone = Ringtone;
408  smprintf(s, "Getting ringtone\n");
409  len = sprintf(req, "AT+MELR=%d\r", Ringtone->Location-1);
410  return GSM_WaitFor (s, req, len, 0x00, 4, ID_GetRingtone);
411 }
412 
414 {
415  smprintf(s, "Ringtone sent\n");
416  return ReplySetSamsungFrame(msg, s);
417 }
418 
420 {
421  unsigned char req[100];
422  unsigned long crc;
423  GSM_Error error;
424  char name[50], *dot;
425  size_t len;
426 
427  s->Phone.Data.Ringtone = Ringtone;
428  smprintf(s, "Setting ringtone\n");
429 
430  if (Ringtone->Format != RING_MMF) {
431  smprintf(s, "Not MMF ringtone\n");
432  return ERR_INVALIDDATA;
433  }
434 
435  /* Remove extension from file name */
436  strncpy(name, DecodeUnicodeString(Ringtone->Name), 50);
437  name[49] = '\0';
438  if ((dot = strrchr(name, '.')) != NULL) *dot = 0;
439 
440  crc = GetCRC(Ringtone->BinaryTone.Buffer, Ringtone->BinaryTone.Length);
441  len = sprintf(req, "AT+MELW=0,\"%s\",4,%ld,%u\r", name,
442  (long)Ringtone->BinaryTone.Length, (unsigned int)crc);
443 
444  error = s->Protocol.Functions->WriteMessage(s, req, len, 0x00);
445  if (error!=ERR_NONE) return error;
446 
447  return SetSamsungFrame(s, Ringtone->BinaryTone.Buffer,
448  Ringtone->BinaryTone.Length, ID_SetRingtone);
449 }
450 
454 GSM_Error SAMSUNG_CheckCalendar(GSM_StateMachine *s)
455 {
456  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
457  GSM_Error error;
458 
459  if (Priv->SamsungCalendar != 0) {
460  return ERR_NONE;
461  }
462 
463  smprintf(s, "Checking for supported calendar commands\n");
464 
465  error = ATGEN_WaitForAutoLen(s, "AT+SSHT?\r", 0x00, 10, ID_GetProtocol);
466  if (error == ERR_NONE) {
468  return ERR_NONE;
469  }
470 
471  error = ATGEN_WaitForAutoLen(s, "AT+ORGI?\r", 0x00, 10, ID_GetProtocol);
472  if (error == ERR_NONE) {
474  return ERR_NONE;
475  }
476 
478  return ERR_NONE;
479 
480 }
481 
483 {
484  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
485 
486  Priv->PBK_SPBR = AT_NOTAVAILABLE;
487 
488  switch (Priv->ReplyState) {
489  case AT_Reply_OK:
490  /* FIXME: does phone give also some useful infromation here? */
491  Priv->PBK_SPBR = AT_AVAILABLE;
492 
493  return ERR_NONE;
494  case AT_Reply_Error:
495  return ERR_UNKNOWN;
496  case AT_Reply_CMSError:
497  return ATGEN_HandleCMSError(s);
498  case AT_Reply_CMEError:
499  return ATGEN_HandleCMEError(s);
500  default:
501  return ERR_UNKNOWNRESPONSE;
502  }
503 }
504 
506 {
507  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
508  GSM_MemoryEntry *Memory = s->Phone.Data.Memory;
509  GSM_Error error;
510  const char *str;
511  int i, j, year = 1900, month = 0, day = 0;
512 
513  switch (Priv->ReplyState) {
514  case AT_Reply_OK:
515  smprintf(s, "Phonebook entry received\n");
516  Memory->EntriesNum = 12;
517  Memory->Entries[0].EntryType = PBK_Number_Mobile;
519  Memory->Entries[0].AddError = ERR_NONE;
520  Memory->Entries[0].VoiceTag = 0;
521  Memory->Entries[0].SMSList[0] = 0;
522  Memory->Entries[1].EntryType = PBK_Number_General;
523  Memory->Entries[1].Location = PBK_Location_Home;
524  Memory->Entries[1].AddError = ERR_NONE;
525  Memory->Entries[1].VoiceTag = 0;
526  Memory->Entries[1].SMSList[0] = 0;
527  Memory->Entries[2].EntryType = PBK_Number_General;
528  Memory->Entries[2].Location = PBK_Location_Work;
529  Memory->Entries[2].AddError = ERR_NONE;
530  Memory->Entries[2].VoiceTag = 0;
531  Memory->Entries[2].SMSList[0] = 0;
532  Memory->Entries[3].EntryType = PBK_Number_Fax;
534  Memory->Entries[3].AddError = ERR_NONE;
535  Memory->Entries[3].VoiceTag = 0;
536  Memory->Entries[3].SMSList[0] = 0;
537  Memory->Entries[4].EntryType = PBK_Number_General;
539  Memory->Entries[4].AddError = ERR_NONE;
540  Memory->Entries[4].VoiceTag = 0;
541  Memory->Entries[4].SMSList[0] = 0;
542  Memory->Entries[5].EntryType = PBK_Text_Email;
544  Memory->Entries[5].AddError = ERR_NONE;
545  Memory->Entries[5].VoiceTag = 0;
546  Memory->Entries[5].SMSList[0] = 0;
547  Memory->Entries[6].EntryType = PBK_Text_FirstName;
549  Memory->Entries[6].AddError = ERR_NONE;
550  Memory->Entries[6].VoiceTag = 0;
551  Memory->Entries[6].SMSList[0] = 0;
552  Memory->Entries[7].EntryType = PBK_Text_LastName;
554  Memory->Entries[7].AddError = ERR_NONE;
555  Memory->Entries[7].VoiceTag = 0;
556  Memory->Entries[7].SMSList[0] = 0;
557  Memory->Entries[8].EntryType = PBK_Text_Note;
559  Memory->Entries[8].AddError = ERR_NONE;
560  Memory->Entries[8].VoiceTag = 0;
561  Memory->Entries[8].SMSList[0] = 0;
562  Memory->Entries[9].EntryType = PBK_Text_Note;
564  Memory->Entries[9].AddError = ERR_NONE;
565  Memory->Entries[9].VoiceTag = 0;
566  Memory->Entries[9].SMSList[0] = 0;
567  EncodeUnicode(Memory->Entries[9].Text, "", 0);
568  Memory->Entries[10].EntryType = PBK_Text_Note;
569  Memory->Entries[10].Location = PBK_Location_Unknown;
570  Memory->Entries[10].AddError = ERR_NONE;
571  Memory->Entries[10].VoiceTag = 0;
572  Memory->Entries[10].SMSList[0] = 0;
573  EncodeUnicode(Memory->Entries[10].Text, "", 0);
574  Memory->Entries[11].EntryType = PBK_Text_Note;
575  Memory->Entries[11].Location = PBK_Location_Unknown;
576  Memory->Entries[11].AddError = ERR_NONE;
577  Memory->Entries[11].VoiceTag = 0;
578  Memory->Entries[11].SMSList[0] = 0;
579  EncodeUnicode(Memory->Entries[11].Text, "", 0);
580 
581  /* Get line from reply */
582  str = GetLineString(msg->Buffer, &Priv->Lines, 2);
583 
584  /* Empty entry */
585  if (strcmp(str, "OK") == 0) return ERR_EMPTY;
586 
587  /* Philips has it's SPBR as well, but different reply */
588  if ( Priv->Manufacturer == AT_Philips) {
589  error = ATGEN_ParseReply(s,
590  GetLineString(msg->Buffer, &Priv->Lines, 2),
591  "+SPBR: @n, @u, @p",
592  &Memory->Location,
593  Memory->Entries[0].Text, sizeof(Memory->Entries[0].Text),
594  Memory->Entries[1].Text, sizeof(Memory->Entries[1].Text));
595  if (error == ERR_NONE) {
596  /* Set name type */
597  Memory->Entries[0].EntryType = PBK_Text_Name;
599 
600  /* Set number type */
601  Memory->Entries[1].EntryType = PBK_Number_General;
603  Memory->Entries[1].VoiceTag = 0;
604  Memory->Entries[1].SMSList[0] = 0;
605 
606  return ERR_NONE;
607  }
608  }
609 
610  /*
611  * Parse reply string
612  *
613  * The last string seems to be always empty, so it is
614  * not handled in rest of the code.
615  */
616  error = ATGEN_ParseReply(s, str,
617  "+SPBR: @i, @p, @p, @p, @p, @p, @s, @T, @T, @T, @T",
618  &Memory->Location,
619  Memory->Entries[0].Text, sizeof(Memory->Entries[0].Text),
620  Memory->Entries[1].Text, sizeof(Memory->Entries[1].Text),
621  Memory->Entries[2].Text, sizeof(Memory->Entries[2].Text),
622  Memory->Entries[3].Text, sizeof(Memory->Entries[3].Text),
623  Memory->Entries[4].Text, sizeof(Memory->Entries[4].Text),
624  Memory->Entries[5].Text, sizeof(Memory->Entries[5].Text),
625  Memory->Entries[6].Text, sizeof(Memory->Entries[6].Text),
626  Memory->Entries[7].Text, sizeof(Memory->Entries[7].Text),
627  Memory->Entries[8].Text, sizeof(Memory->Entries[8].Text),
628  Memory->Entries[9].Text, sizeof(Memory->Entries[9].Text));
629  if (error != ERR_NONE) {
630  /*
631  * Some phones have different string:
632  * +SPBR: 1,"+999999999999","","","","","aaaaaaaaaa@gmail.com","6,Aaaaaa","8,Ssssssss",1999,1,31,"2,Me","0,"
633  */
634  error = ATGEN_ParseReply(s, str,
635  "+SPBR: @i, @p, @p, @p, @p, @p, @s, @T, @T, @i, @i, @i, @T, @T",
636  &Memory->Location,
637  Memory->Entries[0].Text, sizeof(Memory->Entries[0].Text),
638  Memory->Entries[1].Text, sizeof(Memory->Entries[1].Text),
639  Memory->Entries[2].Text, sizeof(Memory->Entries[2].Text),
640  Memory->Entries[3].Text, sizeof(Memory->Entries[3].Text),
641  Memory->Entries[4].Text, sizeof(Memory->Entries[4].Text),
642  Memory->Entries[5].Text, sizeof(Memory->Entries[5].Text),
643  Memory->Entries[6].Text, sizeof(Memory->Entries[6].Text),
644  Memory->Entries[7].Text, sizeof(Memory->Entries[7].Text),
645  &year, &month, &day,
646  Memory->Entries[8].Text, sizeof(Memory->Entries[8].Text),
647  Memory->Entries[9].Text, sizeof(Memory->Entries[9].Text));
648  }
649  if (error != ERR_NONE) {
650  /*
651  * Some phones have different string:
652  * +SPBR:1,"5,37217201","0,","0,","0,","0,","14,admrede@inf.ufsc.br","0,","11,Admrede Inf","4,Ufsc","0,","0,",1900,1,1,"0,"
653  */
654  error = ATGEN_ParseReply(s, str,
655  "+SPBR: @i, @T, @T, @T, @T, @T, @T, @T, @T, @T, @T, @T, @i, @i, @i, @T",
656  &Memory->Location,
657  Memory->Entries[0].Text, sizeof(Memory->Entries[0].Text),
658  Memory->Entries[1].Text, sizeof(Memory->Entries[1].Text),
659  Memory->Entries[2].Text, sizeof(Memory->Entries[2].Text),
660  Memory->Entries[3].Text, sizeof(Memory->Entries[3].Text),
661  Memory->Entries[4].Text, sizeof(Memory->Entries[4].Text),
662  Memory->Entries[5].Text, sizeof(Memory->Entries[5].Text),
663  Memory->Entries[6].Text, sizeof(Memory->Entries[6].Text),
664  Memory->Entries[7].Text, sizeof(Memory->Entries[7].Text),
665  Memory->Entries[9].Text, sizeof(Memory->Entries[9].Text),
666  Memory->Entries[10].Text, sizeof(Memory->Entries[10].Text),
667  Memory->Entries[11].Text, sizeof(Memory->Entries[11].Text),
668  &year, &month, &day,
669  Memory->Entries[8].Text, sizeof(Memory->Entries[8].Text));
670  }
671  if (error != ERR_NONE) {
672  return error;
673  }
674  /* Remove empty entries */
675  for (i = 0; i < Memory->EntriesNum; i++) {
676  if (UnicodeLength(Memory->Entries[i].Text) == 0) {
677  for (j = i + 1; j < Memory->EntriesNum; j++) {
678  CopyUnicodeString(Memory->Entries[j - 1].Text, Memory->Entries[j].Text);
679  Memory->Entries[j - 1].EntryType = Memory->Entries[j].EntryType;
680  Memory->Entries[j - 1].Location = Memory->Entries[j].Location;
681  }
682  Memory->EntriesNum--;
683  }
684  }
685  /* Was there stored birthday? */
686  if (year > 1900) {
687  Memory->Entries[Memory->EntriesNum].EntryType = PBK_Date;
688  Memory->Entries[Memory->EntriesNum].Location = PBK_Location_Unknown;
689  Memory->Entries[Memory->EntriesNum].Date.Year = year;
690  Memory->Entries[Memory->EntriesNum].Date.Month = month;
691  Memory->Entries[Memory->EntriesNum].Date.Day = day;
692  Memory->Entries[Memory->EntriesNum].Date.Hour = 0;
693  Memory->Entries[Memory->EntriesNum].Date.Minute = 0;
694  Memory->Entries[Memory->EntriesNum].Date.Second = 0;
695  Memory->Entries[Memory->EntriesNum].Date.Timezone = 0;
696  Memory->EntriesNum++;
697  }
698  if (Memory->EntriesNum == 0) {
699  return ERR_EMPTY;
700  }
701  return ERR_NONE;
702  case AT_Reply_Error:
703  return ERR_UNKNOWN;
704  case AT_Reply_CMSError:
705  return ATGEN_HandleCMSError(s);
706  case AT_Reply_CMEError:
707  /* Empty location */
708  if (Priv->ErrorCode == 28) {
709  return ERR_EMPTY;
710  }
711  return ATGEN_HandleCMEError(s);
712  default:
713  break;
714  }
715  return ERR_UNKNOWNRESPONSE;
716 }
717 
719 {
720  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
721 
722  SAMSUNG_CheckCalendar(s);
723 
724  if (Priv->SamsungCalendar == SAMSUNG_NONE) {
725  return ERR_NOTSUPPORTED;
726  } else if (Priv->SamsungCalendar == SAMSUNG_SSH) {
727  return ERR_NOTIMPLEMENTED;
728  }
729 
730  /* FIXME: Here you have to implement conversion of GSM_MemoryEntry to AT command */
731  smprintf(s, "Setting memory for Samsung not implemented yet!\n");
732  return ERR_NOTIMPLEMENTED;
733 }
734 
736 {
737  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
738  GSM_Error error;
739  int ignore;
740 
741  if (Priv->ReplyState != AT_Reply_OK) {
742  switch (s->Phone.Data.Priv.ATGEN.ReplyState) {
743  case AT_Reply_Error:
744  return ERR_NOTSUPPORTED;
745  case AT_Reply_CMSError:
746  return ATGEN_HandleCMSError(s);
747  case AT_Reply_CMEError:
748  return ATGEN_HandleCMEError(s);
749  default:
750  return ERR_UNKNOWNRESPONSE;
751  }
752  }
753 
754  if (strcmp(GetLineString(msg->Buffer, &Priv->Lines, 2), "OK") == 0) {
755  return ERR_NOTSUPPORTED;
756  }
757 
758  error = ATGEN_ParseReply(s,
759  GetLineString(msg->Buffer, &Priv->Lines, 2),
760  "+ORGI: @i, @i, @i, @i, @i",
761  &s->Phone.Data.CalStatus->Used,
762  &s->Phone.Data.CalStatus->Free,
763  &ignore,
764  &ignore,
765  &ignore);
766  if (error != ERR_NONE) return error;
768  return ERR_NONE;
769 }
770 
772 {
773  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
774  GSM_Error error;
775  int ignore;
776 
777  if (Priv->ReplyState != AT_Reply_OK) {
778  switch (s->Phone.Data.Priv.ATGEN.ReplyState) {
779  case AT_Reply_Error:
780  return ERR_NOTSUPPORTED;
781  case AT_Reply_CMSError:
782  return ATGEN_HandleCMSError(s);
783  case AT_Reply_CMEError:
784  return ATGEN_HandleCMEError(s);
785  default:
786  return ERR_UNKNOWNRESPONSE;
787  }
788  }
789 
790  error = ATGEN_ParseReply(s,
791  GetLineString(msg->Buffer, &Priv->Lines, 2),
792  "+SSHI: @i, @i, @i",
793  &s->Phone.Data.CalStatus->Used,
794  &s->Phone.Data.CalStatus->Free,
795  &ignore);
796  if (error != ERR_NONE) return error;
798  return ERR_NONE;
799 }
800 
802 {
803  GSM_Error error;
804  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
805 
806  s->Phone.Data.CalStatus = Status;
807 
808  SAMSUNG_CheckCalendar(s);
809 
810  if (Priv->SamsungCalendar == SAMSUNG_NONE) {
811  return ERR_NOTSUPPORTED;
812  } else if (Priv->SamsungCalendar == SAMSUNG_SSH) {
813  error = ATGEN_WaitForAutoLen(s, "AT+SSHI?\r", 0x00, 10, ID_GetCalendarNotesInfo);
814  return error;
815  } else if (Priv->SamsungCalendar == SAMSUNG_ORG) {
816  error = ATGEN_WaitForAutoLen(s, "AT+ORGI?\r", 0x00, 10, ID_GetCalendarNotesInfo);
817  return error;
818  }
819 
820  return ERR_BUG;
821 }
822 
824 {
825  GSM_Error error;
826  int ignore, alarm_flag, alarm_time, alarm_quantity, alarm_repeat;
827  char ignorestring[10];
828  GSM_CalendarEntry *Note = s->Phone.Data.Cal;
829  /*
830 par03: Organizer entry short name
831 par04: Organizer entry detailed description
832 par05: Start day
833 par06: Start month
834 par07: Start year
835 par08: Start hour
836 par09: Start minute
837 par10: End day
838 par11: End month
839 par12: End year
840 par13: End hour
841 par14: End minute
842 par15: Location
843 par16: Alarm flag (0=no, 1=yes)
844 par17: Alarm time unit (1=minutes, 2=hours, days, 4=weeks)
845 par18: Alarm items quantity
846 par19: Alarm repeat flag (0 or empty=no, 2=yes)
847 par20: Empty
848 par21: Empty
849 par22: Repeat until day
850 par23: Repeat until month
851 par24: Repeat until year
852 */
853  Note->Entries[0].EntryType = CAL_TEXT;
854  Note->Entries[1].EntryType = CAL_DESCRIPTION;
856  Note->Entries[2].Date.Timezone = 0;
857  Note->Entries[2].Date.Second = 0;
859  Note->Entries[3].Date.Timezone = 0;
860  Note->Entries[3].Date.Second = 0;
861  Note->Entries[4].EntryType = CAL_LOCATION;
862  Note->EntriesNum = 4;
863  error = ATGEN_ParseReply(s,
864  line,
865  "+ORGR: @i, @i, @S, @S, @i, @i, @i, @i, @i, @i, @i, @i, @i, @i, @s, @I, @I, @I, @I, @s, @s, @I, @I, @I",
866  &ignore,
867  &ignore,
868  Note->Entries[0].Text, sizeof(Note->Entries[0].Text),
869  Note->Entries[1].Text, sizeof(Note->Entries[1].Text),
870  &(Note->Entries[2].Date.Day),
871  &(Note->Entries[2].Date.Month),
872  &(Note->Entries[2].Date.Year),
873  &(Note->Entries[2].Date.Hour),
874  &(Note->Entries[2].Date.Minute),
875  &(Note->Entries[3].Date.Day),
876  &(Note->Entries[3].Date.Month),
877  &(Note->Entries[3].Date.Year),
878  &(Note->Entries[3].Date.Hour),
879  &(Note->Entries[3].Date.Minute),
880  Note->Entries[4].Text, sizeof(Note->Entries[4].Text),
881  &alarm_flag,
882  &alarm_time,
883  &alarm_quantity,
884  &alarm_repeat,
885  ignorestring, sizeof(ignorestring),
886  ignorestring, sizeof(ignorestring),
887  &(Note->Entries[5].Date.Day),
888  &(Note->Entries[5].Date.Month),
889  &(Note->Entries[5].Date.Year)
890  );
891  if (error != ERR_NONE) return error;
892  return ERR_NONE;
893 }
894 
896 {
897  GSM_Error error;
898  int ignore, alarm_flag, alarm_time, alarm_quantity, alarm_repeat;
899  char ignorestring[10];
900  GSM_CalendarEntry *Note = s->Phone.Data.Cal;
901  /*
902 par03: Empty
903 par04: Ocassion name
904 par05: Alarm day
905 par06: Alarm month
906 par07: Alarm year
907 par08: Alarm hour
908 par09: Alarm minutes
909 par10: Empty
910 par11: Empty
911 par12: Empty
912 par13: Empty
913 par14: Empty
914 par15: Empty
915 par16: Alarm flag (0=no, 1=yes)
916 par17: Alarm time unit (1=minutes, 2=hours, days, 4=weeks)
917 par18: Alarm items quantity
918 par19: Repeat each year (0=no, 4=yes)
919 par20: Empty
920 par21: Empty
921 par22: Empty
922 par23: Empty
923 par24: Empty
924 */
925  Note->Entries[0].EntryType = CAL_TEXT;
927  Note->Entries[1].Date.Timezone = 0;
928  Note->Entries[1].Date.Second = 0;
929  Note->EntriesNum = 2;
930  error = ATGEN_ParseReply(s,
931  line,
932  "+ORGR: @i, @i, @S, @S, @i, @i, @i, @i, @i, @s, @s, @s, @s, @s, @s, @i, @i, @i, @i, @0",
933  &ignore,
934  &ignore,
935  ignorestring, sizeof(ignorestring),
936  Note->Entries[0].Text, sizeof(Note->Entries[0].Text),
937  &(Note->Entries[1].Date.Day),
938  &(Note->Entries[1].Date.Month),
939  &(Note->Entries[1].Date.Year),
940  &(Note->Entries[1].Date.Hour),
941  &(Note->Entries[1].Date.Minute),
942  ignorestring, sizeof(ignorestring),
943  ignorestring, sizeof(ignorestring),
944  ignorestring, sizeof(ignorestring),
945  ignorestring, sizeof(ignorestring),
946  ignorestring, sizeof(ignorestring),
947  ignorestring, sizeof(ignorestring),
948  &alarm_flag,
949  &alarm_time,
950  &alarm_quantity,
951  &alarm_repeat
952  );
953  if (error != ERR_NONE) return error;
954  return ERR_NONE;
955 }
956 
957 GSM_Error SAMSUNG_ParseTask(GSM_StateMachine *s, const char *line)
958 {
959  GSM_Error error;
960  int ignore, alarm_flag, alarm_time, alarm_quantity, priority, status;
961  char ignorestring[10];
962  GSM_CalendarEntry *Note = s->Phone.Data.Cal;
963  /*
964 par03: Empty
965 par04: Task name
966 par05: Start day
967 par06: Start month
968 par07: Start year
969 par08: Alarm hour
970 par09: Alarm minute
971 par10: Due day
972 par11: Due month
973 par12: Due year
974 par13: Empty
975 par14: Empty
976 par15: Empty
977 par16: Alarm flag (0=no, 1=yes)
978 par17: Alarm time unit (1=minutes, 2=hours, days, 4=weeks)
979 par18: Alarm items quantity
980 par19: Empty
981 par20: Task priority (1=high, 2=normal, 3=low)
982 par21: Task status (0=undone, 1=done)
983 par22: Empty
984 par23: Empty
985 par24: Empty
986 */
987  Note->Entries[0].EntryType = CAL_TEXT;
989  Note->Entries[1].Date.Timezone = 0;
990  Note->Entries[1].Date.Second = 0;
992  Note->Entries[2].Date.Timezone = 0;
993  Note->Entries[2].Date.Second = 0;
994  Note->Entries[2].Date.Hour = 0;
995  Note->Entries[2].Date.Minute = 0;
996  Note->EntriesNum = 3;
997  error = ATGEN_ParseReply(s,
998  line,
999  "+ORGR: @i, @i, @S, @S, @i, @i, @i, @i, @i, @i, @i, @i, @s, @s, @s, @i, @i, @i, @s, @i, @i, @0",
1000  &ignore,
1001  &ignore,
1002  ignorestring, sizeof(ignorestring),
1003  Note->Entries[0].Text, sizeof(Note->Entries[0].Text),
1004  &(Note->Entries[1].Date.Day),
1005  &(Note->Entries[1].Date.Month),
1006  &(Note->Entries[1].Date.Year),
1007  &(Note->Entries[1].Date.Hour),
1008  &(Note->Entries[1].Date.Minute),
1009  &(Note->Entries[2].Date.Day),
1010  &(Note->Entries[2].Date.Month),
1011  &(Note->Entries[2].Date.Year),
1012  ignorestring, sizeof(ignorestring),
1013  ignorestring, sizeof(ignorestring),
1014  ignorestring, sizeof(ignorestring),
1015  &alarm_flag,
1016  &alarm_time,
1017  &alarm_quantity,
1018  ignorestring, sizeof(ignorestring),
1019  &priority,
1020  &status
1021  );
1022  if (error != ERR_NONE) return error;
1023  return ERR_NONE;
1024 }
1025 
1027 {
1028  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
1029  GSM_Error error;
1030  int ignore, type;
1031  const char *line;
1032 
1033  if (Priv->ReplyState != AT_Reply_OK) {
1034  switch (s->Phone.Data.Priv.ATGEN.ReplyState) {
1035  case AT_Reply_Error:
1036  return ERR_NOTSUPPORTED;
1037  case AT_Reply_CMSError:
1038  return ATGEN_HandleCMSError(s);
1039  case AT_Reply_CMEError:
1040  return ATGEN_HandleCMEError(s);
1041  default:
1042  return ERR_UNKNOWNRESPONSE;
1043  }
1044  }
1045 
1046  line = GetLineString(msg->Buffer, &Priv->Lines, 2);
1047 
1048  if (strcmp("OK", line) == 0) {
1049  return ERR_EMPTY;
1050  }
1051 
1052  error = ATGEN_ParseReply(s,
1053  line,
1054  "+ORGR: @i, @i, @0",
1055  &ignore,
1056  &type);
1057  if (error != ERR_NONE) return error;
1058 
1059  switch (type) {
1060  case 1:
1062  return SAMSUNG_ParseAppointment(s, line);
1063  case 2:
1065  return SAMSUNG_ParseAniversary(s, line);
1066  case 3:
1067  /* TODO: This should be rather turned into todo entry */
1069  return SAMSUNG_ParseTask(s, line);
1070  case 4:
1071  s->Phone.Data.Cal->Type = GSM_CAL_MEMO;
1072  return SAMSUNG_ParseAppointment(s, line);
1073  default:
1074  smprintf(s, "WARNING: Unknown entry type %d, treating as memo!\n", type);
1075  s->Phone.Data.Cal->Type = GSM_CAL_MEMO;
1076  return SAMSUNG_ParseAppointment(s, line);
1077  }
1078 }
1079 
1081 {
1082  return ERR_NOTIMPLEMENTED;
1083 }
1084 
1086 {
1087  GSM_Error error;
1088  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
1089 
1090  SAMSUNG_CheckCalendar(s);
1091 
1092  if (Priv->SamsungCalendar == SAMSUNG_NONE) {
1093  return ERR_NOTSUPPORTED;
1094  }
1095 
1096  if (start) {
1097  /* One below actual first position */
1098  Note->Location = 0;
1099  error = SAMSUNG_GetCalendarStatus(s, &Priv->CalendarStatus);
1100  if (error != ERR_NONE) {
1101  return error;
1102  }
1103  Priv->CalendarRead = 0;
1104  }
1105  s->Phone.Data.Cal = Note;
1106  Note->EntriesNum = 0;
1107  smprintf(s, "Getting calendar entry\n");
1108  error = ERR_EMPTY;
1109  while (error == ERR_EMPTY) {
1110  Note->Location++;
1111  if (Note->Location >= Priv->CalendarStatus.Used + Priv->CalendarStatus.Free) {
1112  /* We're at the end */
1113  return ERR_EMPTY;
1114  }
1115  if (Priv->CalendarRead >= Priv->CalendarStatus.Used) {
1116  /* We've read all entries */
1117  return ERR_EMPTY;
1118  }
1119  error = SAMSUNG_GetCalendar(s, Note);
1120  if (error == ERR_NONE) {
1121  Priv->CalendarRead++;
1122  }
1123  }
1124  return error;
1125 }
1126 
1128 {
1129  char req[50];
1130  GSM_Error error;
1131  size_t len;
1132  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
1133 
1134  s->Phone.Data.Cal = Note;
1135 
1136  SAMSUNG_CheckCalendar(s);
1137 
1138  if (Priv->SamsungCalendar == SAMSUNG_NONE) {
1139  return ERR_NOTSUPPORTED;
1140  } else if (Priv->SamsungCalendar == SAMSUNG_ORG) {
1141  len = sprintf(req, "AT+ORGR=%d\r", Note->Location - 1);
1142  } else if (Priv->SamsungCalendar == SAMSUNG_SSH) {
1143  len = sprintf(req, "AT+SSHR=%d\r", Note->Location);
1144  } else {
1145  return ERR_BUG;
1146  }
1147 
1148  error = ATGEN_WaitFor(s, req, len, 0x00, 10, ID_GetCalendarNote);
1149  return error;
1150 }
1151 
1153 {
1154  return ERR_NOTIMPLEMENTED;
1155 }
1156 
1158 {
1159  char req[50];
1160  GSM_Error error;
1161  size_t len;
1162  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
1163 
1164  SAMSUNG_CheckCalendar(s);
1165 
1166  if (Priv->SamsungCalendar == SAMSUNG_NONE) {
1167  return ERR_NOTSUPPORTED;
1168  } else if (Priv->SamsungCalendar == SAMSUNG_ORG) {
1169  len = sprintf(req, "AT+ORGD=%d\r", Note->Location - 1);
1170  } else if (Priv->SamsungCalendar == SAMSUNG_SSH) {
1171  len = sprintf(req, "AT+SSHD=%d\r", Note->Location);
1172  } else {
1173  return ERR_BUG;
1174  }
1175 
1176  error = ATGEN_WaitFor(s, req, len, 0x00, 10, ID_DeleteCalendarNote);
1177  return error;
1178 }
1179 
1181 {
1182  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
1183 
1184  SAMSUNG_CheckCalendar(s);
1185 
1186  if (Priv->SamsungCalendar == SAMSUNG_NONE) {
1187  return ERR_NOTSUPPORTED;
1188  } else if (Priv->SamsungCalendar == SAMSUNG_ORG) {
1189  return ERR_NOTIMPLEMENTED;
1190  } else {
1191  return ERR_NOTIMPLEMENTED;
1192  }
1193 }
1194 
1196 {
1197  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
1198 
1199  SAMSUNG_CheckCalendar(s);
1200 
1201  if (Priv->SamsungCalendar == SAMSUNG_NONE) {
1202  return ERR_NOTSUPPORTED;
1203  } else if (Priv->SamsungCalendar == SAMSUNG_ORG) {
1204  return ERR_NOTIMPLEMENTED;
1205  } else {
1206  return ERR_NOTIMPLEMENTED;
1207  }
1208 }
1209 #endif
1210 
1211 /* How should editor hadle tabs in this file? Add editor commands here.
1212  * vim: noexpandtab sw=8 ts=8 sts=8:
1213  */
unsigned char Name[(GSM_MAX_RINGTONE_NAME_LENGTH+1) *2]
GSM_Error SAMSUNG_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
GSM_Error SAMSUNG_ORG_ReplySetCalendar(GSM_Protocol_Message *msg, GSM_StateMachine *s)
char * DecodeUnicodeString(const unsigned char *src)
Definition: coding.c:245
GSM_RingtoneFormat Format
void CopyUnicodeString(unsigned char *Dest, const unsigned char *Source)
Definition: coding.c:1192
GSM_Error SAMSUNG_SSH_ReplyGetCalendar(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error ATGEN_HandleCMEError(GSM_StateMachine *s)
GSM_Bitmap_Types Type
Definition: gammu-bitmap.h:107
GSM_Error SAMSUNG_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status)
GSM_MemoryEntry * Memory
Definition: gsmstate.h:497
GSM_Error SAMSUNG_ParseTask(GSM_StateMachine *s, const char *line)
GSM_CutLines Lines
Definition: atgen.h:243
GSM_Error SAMSUNG_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
GSM_Error SAMSUNG_GetBitmap(GSM_StateMachine *, GSM_Bitmap *)
GSM_Error ATGEN_HandleCMSError(GSM_StateMachine *s)
GSM_Error
Definition: gammu-error.h:23
const char * GetLineString(const char *message, GSM_CutLines *lines, int start)
Definition: misc.c:492
#define ATGEN_WaitForAutoLen(s, cmd, type, time, request)
Definition: atgen.h:437
GSM_BinaryPicture_Types Type
Definition: gammu-bitmap.h:44
GSM_Error DispatchError
Definition: gsmstate.h:689
const char * model
Definition: gammu-info.h:764
unsigned char * Buffer
Definition: gammu-bitmap.h:45
GSM_Error SAMSUNG_ORG_ReplyGetCalendarStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
size_t UnicodeLength(const unsigned char *str)
Definition: coding.c:186
GSM_Bitmap * Bitmap
Definition: gsmstate.h:573
unsigned char Location
Definition: gammu-bitmap.h:112
GSM_Error(* WriteMessage)(GSM_StateMachine *s, unsigned const char *buffer, int length, int type)
Definition: gsmstate.h:347
GSM_CalendarStatus * CalStatus
Definition: gsmstate.h:553
GSM_PhoneModel * ModelInfo
Definition: gsmstate.h:449
GSM_EntryType EntryType
Definition: gammu-memory.h:372
GSM_Error SAMSUNG_ReplySetRingtone(GSM_Protocol_Message *, GSM_StateMachine *)
unsigned char Text[(GSM_PHONEBOOK_TEXT_LENGTH+1) *2]
Definition: gammu-memory.h:399
int gboolean
Definition: gammu-types.h:23
GSM_Error SAMSUNG_ReplyGetBitmap(GSM_Protocol_Message *, GSM_StateMachine *)
GSM_Error SAMSUNG_ParseAppointment(GSM_StateMachine *s, const char *line)
GSM_Error SAMSUNG_ReplyGetMemoryInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_CalendarNoteType Type
GSM_Error SAMSUNG_ReplyGetMemory(GSM_Protocol_Message *msg, GSM_StateMachine *s)
void EncodeUnicode(unsigned char *dest, const char *src, size_t len)
Definition: coding.c:301
GSM_Phone Phone
Definition: gsmstate.h:1431
GSM_Error SAMSUNG_SetBitmap(GSM_StateMachine *, GSM_Bitmap *)
struct GSM_Phone_Data::@2 Priv
GSM_Error SAMSUNG_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start)
GSM_Error SAMSUNG_ReplyGetRingtone(GSM_Protocol_Message *, GSM_StateMachine *)
GSM_Error ATGEN_ParseReply(GSM_StateMachine *s, const unsigned char *input, const char *format,...)
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
GSM_Error SAMSUNG_ORG_ReplyGetCalendar(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Ringtone * Ringtone
Definition: gsmstate.h:545
GSM_Error SAMSUNG_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
unsigned char * Buffer
int(* ReadDevice)(GSM_StateMachine *s, void *buf, size_t nbytes)
Definition: gsmstate.h:252
GSM_Error ATGEN_WaitFor(GSM_StateMachine *s, const char *cmd, size_t len, int type, int time, GSM_Phone_RequestID request)
GSM_CalendarType EntryType
GSM_Device_Functions * Functions
Definition: gsmstate.h:335
GSM_Protocol Protocol
Definition: gsmstate.h:1430
GSM_DateTime Date
Definition: gammu-memory.h:380
unsigned char Name[2 *(GSM_BITMAP_TEXT_LENGTH+1)]
Definition: gammu-bitmap.h:176
GSM_BinaryPicture BinaryPic
Definition: gammu-bitmap.h:172
GSM_BinaryTone BinaryTone
GSM_Phone_Data Data
Definition: gsmstate.h:1369
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
void GSM_GetCurrentDateTime(GSM_DateTime *Date)
Definition: misc.c:184
GSM_SamsungCalendar SamsungCalendar
Definition: atgen.h:304
GSM_EntryLocation Location
Definition: gammu-memory.h:376
size_t BitmapHeight
Definition: gammu-bitmap.h:152
GSM_AT_Feature PBK_SPBR
Definition: atgen.h:302
size_t BitmapWidth
Definition: gammu-bitmap.h:156
GSM_Error SAMSUNG_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
GSM_Error SAMSUNG_DelCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
GSM_CalendarStatus CalendarStatus
Definition: atgen.h:315
GSM_Protocol_Functions * Functions
Definition: gsmstate.h:424
GSM_Error SAMSUNG_SetRingtone(GSM_StateMachine *, GSM_Ringtone *, int *)
unsigned char * Buffer
Definition: protocol.h:22
#define UNUSED
Definition: gammu-misc.h:105
GSM_Error SAMSUNG_ParseAniversary(GSM_StateMachine *s, const char *line)
GSM_AT_Reply_State ReplyState
Definition: atgen.h:247
GSM_Error SAMSUNG_GetRingtone(GSM_StateMachine *, GSM_Ringtone *, gboolean)
GSM_Error SAMSUNG_SSH_ReplyGetCalendarStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
GSM_Error SAMSUNG_ReplySetBitmap(GSM_Protocol_Message *, GSM_StateMachine *)
GSM_AT_Manufacturer Manufacturer
Definition: atgen.h:239
GSM_Phone_RequestID
Definition: gsmreply.h:25
char Model[GSM_MAX_MODEL_LENGTH+1]
Definition: gsmstate.h:445
GSM_Device Device
Definition: gsmstate.h:1429
unsigned char Text[(GSM_MAX_CALENDAR_TEXT_LENGTH+1) *2]
int smprintf(GSM_StateMachine *s, const char *format,...)
Definition: debug.c:261
GSM_CalendarEntry * Cal
Definition: gsmstate.h:549
GSM_SubMemoryEntry Entries[GSM_PHONEBOOK_ENTRIES]
Definition: gammu-memory.h:427