Gammu internals  1.38.0
motorola.c
Go to the documentation of this file.
1 /* © 2007 - 2009 Michal Čihař */
2 
16 #include <gammu-config.h>
17 
18 #ifdef GSM_ENABLE_ATGEN
19 
20 #include "../../gsmcomon.h"
21 #include "../../gsmstate.h"
22 #include "../../service/gsmpbk.h"
23 #include "atgen.h"
24 #include <string.h>
25 #include "../../../helper/string.h"
26 
27 typedef struct {
28  char Command[20];
29  int Mode;
30 } MOTOROLA_CommandInfo;
31 
37 MOTOROLA_CommandInfo Commands[] = {
38  {"+CGMI", 2},
39  {"+CGMM", 2},
40  {"+CGMR", 2},
41  {"+CGSN", 2},
42  {"+CSCS", 2},
43  {"+CIMI", 2},
44  {"+CNUM", 2},
45  {"+CVHU", 2},
46  {"+CHUP", 2},
47  {"+CIND", 2},
48  {"+CLCK", 2},
49  {"D", 2}, /* We want voice call */
50  {"H", 2}, /* We want voice call */
51  {"A", 2}, /* We want voice call */
52  {"+CRING", 2},
53  {"+CLIP", 2},
54  {"+CLIR", 2},
55  {"+CCFC", 2},
56  {"+CHLD", 2},
57  {"+COLP", 2},
58  {"+CCWA", 2},
59  {"+CLCC", 2},
60  {"+CPBS", 2},
61  {"+CPBR", 2},
62  {"+CPBF", 2},
63  {"+CPBW", 2},
64  {"+CCLK", 2},
65  {"+CNMI", 2},
66  {"+CMGD", 2},
67  {"+CMSS", 2},
68  {"+CSMS", 2},
69  {"+CPMS", 2},
70  {"+CMGF", 2},
71  {"+CSDH", 2},
72  {"+CMTI", 2},
73  {"+CMGL", 2},
74  {"+CMGR", 2},
75  {"+CMGW", 2},
76  {"+CSCA", 2},
77  {"+COPS", 2},
78  {"+CBC", 2},
79  {"+CRTT", 2},
80  {"+CMEE", 2},
81  {"+CKPD", 2},
82 
83  {"+CHV", 0},
84  {"+CDV", 0},
85  {"+CPAS", 0},
86  {"+CREG", 0},
87  {"+CSQ", 0},
88  {"+GCAP", 0},
89  {"+CMUT", 0},
90  {"+CIMSI", 0},
91 
92  {"", 0},
93 };
94 
95 GSM_Error MOTOROLA_SetModeReply(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
96 {
97  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
98 
99  switch (s->Phone.Data.Priv.ATGEN.ReplyState) {
100  case AT_Reply_OK:
101  case AT_Reply_Connect:
102  /*
103  * The typo in next line (Unkown) is intentional,
104  * phone returns it this way.
105  */
106  if (strstr(GetLineString(msg->Buffer, &Priv->Lines, 2), "Unkown mode value") != NULL) {
107  return ERR_NOTSUPPORTED;
108  }
109  return ERR_NONE;
110  case AT_Reply_Error:
111  return ERR_UNKNOWN;
112  case AT_Reply_CMSError:
113  return ATGEN_HandleCMSError(s);
114  case AT_Reply_CMEError:
115  return ATGEN_HandleCMEError(s);
116  default:
117  break;
118  }
119  return ERR_UNKNOWNRESPONSE;
120 }
121 
122 GSM_Error MOTOROLA_SetMode(GSM_StateMachine *s, const char *command)
123 {
124  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
125  MOTOROLA_CommandInfo *cmd;
126  const char *realcmd;
127  char buffer[30]={0};
128  GSM_Error error = ERR_NONE;
129  size_t len;
130 
131  /* Do we need any mode switching? */
132  if (!Priv->Mode) {
133  return ERR_NONE;
134  }
135 
136  /* We don't care about non AT commands */
137  if (strncasecmp(command, "AT", 2) != 0) {
138  return ERR_NONE;
139  }
140 
141  /* Skip AT prefix */
142  realcmd = command + 2;
143 
144  /* Do we have it in our list? */
145  for (cmd = Commands; cmd->Command[0] != 0; cmd++) {
146  if (strncasecmp(realcmd, cmd->Command, strlen(cmd->Command)) == 0) {
147  break;
148  }
149  }
150 
151  /* Not found? */
152  if (cmd->Command[0] == 0) {
153  smprintf(s, "Nothing known about %s command, using current mode\n", command);
154  return ERR_NONE;
155  }
156 
157  /* Compare current mode */
158  if (cmd->Mode == Priv->CurrentMode) {
159  smprintf(s, "Already in mode %d\n", cmd->Mode);
160  return ERR_NONE;
161  }
162 
163  /* Switch mode */
164  smprintf(s, "Switching to mode %d\n", cmd->Mode);
165  len = sprintf(buffer, "AT+MODE=%d\r", cmd->Mode);
166  error = GSM_WaitFor(s, buffer, len, 0x00, 100, ID_ModeSwitch);
167 
168  /* On succes we remember it */
169  if (error == ERR_NONE) {
170 
171  /* We might need to restore charset as phone resets it */
172  if (cmd->Mode == 2) {
173  smprintf(s, "Waiting for banner...\n");
174 
175  /* Wait for banner */
176  error = GSM_WaitForOnce(s, NULL, 0x00, 0x00, 40);
177 
178  if (error != ERR_NONE) {
179  return error;
180  }
181 
182  /* Check for banner result */
183  if (Priv->CurrentMode != 2) {
184  smprintf(s, "Failed to set mode 2!\n");
185  return ERR_BUG;
186  }
187 
188  /* Now we can work with phone */
190  } else {
191  Priv->CurrentMode = cmd->Mode;
192  }
193  }
194  return error;
195 }
196 
200 GSM_Error MOTOROLA_Banner(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
201 {
202  s->Phone.Data.Priv.ATGEN.CurrentMode = 2;
203  return ERR_NONE;
204 }
205 
206 
207 GSM_Error MOTOROLA_ReplyGetMemoryInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
208 {
209  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
210  GSM_Error error;
211 
212  Priv->PBK_MPBR = AT_NOTAVAILABLE;
213 
214  switch (Priv->ReplyState) {
215  case AT_Reply_OK:
216  /* Reply string:
217  * +MPBR: 10-18259,40,24,14,0-1,64,(255),(0),(0-1),(1-11),(255),25,(0-1,255),264,(0),62,62,32,32,32,32,50,264
218  */
219  Priv->PBK_MPBR = AT_AVAILABLE;
220  error = ATGEN_ParseReply(s, GetLineString(msg->Buffer, &Priv->Lines, 2),
221  "+MPBR: @i-@i, @0",
223  &Priv->MotorolaMemorySize);
224  if (error != ERR_NONE) {
225  return error;
226  }
227 
229 
230  return ERR_NONE;
231  case AT_Reply_Error:
232  /* The phone returns simply ERROR on empty entry */
233  return ERR_EMPTY;
234  case AT_Reply_CMSError:
235  return ATGEN_HandleCMSError(s);
236  case AT_Reply_CMEError:
237  return ATGEN_HandleCMEError(s);
238  default:
239  return ERR_UNKNOWNRESPONSE;
240  }
241 }
242 
243 GSM_Error MOTOROLA_ReplyGetMemory(GSM_Protocol_Message *msg, GSM_StateMachine *s)
244 {
245  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
246  GSM_MemoryEntry *Memory = s->Phone.Data.Memory;
247  GSM_Error error;
248  const char *str;
249  int number_type, entry_type;
250 
251  switch (Priv->ReplyState) {
252  case AT_Reply_OK:
253  smprintf(s, "Phonebook entry received\n");
254  Memory->EntriesNum = 2;
255  Memory->Entries[0].AddError = ERR_NONE;
256  Memory->Entries[0].VoiceTag = 0;
257  Memory->Entries[0].SMSList[0] = 0;
259  Memory->Entries[1].EntryType = PBK_Text_Name;
261  Memory->Entries[1].AddError = ERR_NONE;
262  Memory->Entries[1].VoiceTag = 0;
263  Memory->Entries[1].SMSList[0] = 0;
264 
265  /* Get line from reply */
266  str = GetLineString(msg->Buffer, &Priv->Lines, 2);
267 
268  /* Detect empty entry */
269  if (strcmp(str, "OK") == 0) return ERR_EMPTY;
270 
271  /*
272  * Parse reply string
273  *
274  * +MPBR: 18,"user@domain.net",128,"Contact Name",6,0,255,0,0,1,255,255,0,"",0,0,"","","","","","","",""
275  */
276  error = ATGEN_ParseReply(s, str,
277  "+MPBR: @i, @p, @i, @s, @i, @0",
278  &Memory->Location,
279  Memory->Entries[0].Text, sizeof(Memory->Entries[0].Text),
280  &number_type,
281  Memory->Entries[1].Text, sizeof(Memory->Entries[1].Text),
282  &entry_type);
283  Memory->Location = Memory->Location + 1 - Priv->MotorolaFirstMemoryEntry;
284  switch (entry_type) {
285  case 0:
286  Memory->Entries[0].EntryType = PBK_Number_General;
287  Memory->Entries[0].Location = PBK_Location_Work;
288  GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type);
289  break;
290  case 1:
291  Memory->Entries[0].EntryType = PBK_Number_General;
292  Memory->Entries[0].Location = PBK_Location_Home;
293  GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type);
294  break;
295  case 2:
296  case 10:
297  case 11:
298  Memory->Entries[0].EntryType = PBK_Number_General;
300  GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type);
301  break;
302  case 3:
303  Memory->Entries[0].EntryType = PBK_Number_Mobile;
305  GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type);
306  break;
307  case 4:
308  Memory->Entries[0].EntryType = PBK_Number_Fax;
310  GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type);
311  break;
312  case 5:
313  Memory->Entries[0].EntryType = PBK_Number_Pager;
315  GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type);
316  break;
317  case 6:
318  Memory->Entries[0].EntryType = PBK_Text_Email;
320  break;
321  case 7:
322  Memory->Entries[0].EntryType = PBK_Text_Email; /* Mailing list */
324  break;
325  default:
326  Memory->Entries[0].EntryType = PBK_Text_Note;
328  }
329 
330  if (error != ERR_NONE) {
331  return error;
332  }
333  return ERR_NONE;
334  case AT_Reply_Error:
335  return ERR_UNKNOWN;
336  case AT_Reply_CMSError:
337  return ATGEN_HandleCMSError(s);
338  case AT_Reply_CMEError:
339  return ATGEN_HandleCMEError(s);
340  default:
341  break;
342  }
343  return ERR_UNKNOWNRESPONSE;
344 }
345 
346 GSM_Error MOTOROLA_LockCalendar(GSM_StateMachine *s)
347 {
348  GSM_Error error;
349 
350  error = ATGEN_WaitForAutoLen(s, "AT+MDBL=1\r", 0x00, 10, ID_SetCalendarNote);
351 
352  return error;
353 }
354 
355 GSM_Error MOTOROLA_UnlockCalendar(GSM_StateMachine *s)
356 {
357  GSM_Error error;
358 
359  error = ATGEN_WaitForAutoLen(s, "AT+MDBL=0\r", 0x00, 10, ID_SetCalendarNote);
360 
361  return error;
362 }
363 
364 GSM_Error MOTOROLA_ReplyGetCalendarStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
365 {
366  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
367  GSM_Error error;
368  int ignore;
369 
370  if (Priv->ReplyState != AT_Reply_OK) {
371  switch (s->Phone.Data.Priv.ATGEN.ReplyState) {
372  case AT_Reply_Error:
373  return ERR_NOTSUPPORTED;
374  case AT_Reply_CMSError:
375  return ATGEN_HandleCMSError(s);
376  case AT_Reply_CMEError:
377  return ATGEN_HandleCMEError(s);
378  default:
379  return ERR_UNKNOWNRESPONSE;
380  }
381  }
382 
383  /*
384  * Reply looks like:
385  * +MDBR: 500,1,64,8,2
386  * (max events that can be stored, number of stored events, ?, ?, ?)
387  */
388 
389  error = ATGEN_ParseReply(s,
390  GetLineString(msg->Buffer, &Priv->Lines, 2),
391  "+MDBR: @i, @i, @i, @i, @i",
392  &s->Phone.Data.CalStatus->Free,
393  &s->Phone.Data.CalStatus->Used,
394  &ignore,
395  &ignore,
396  &ignore);
397  if (error != ERR_NONE) return error;
399  return ERR_NONE;
400 }
401 
402 GSM_Error MOTOROLA_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status)
403 {
404  GSM_Error error;
405 
406  s->Phone.Data.CalStatus = Status;
407 
408  error = ATGEN_WaitForAutoLen(s, "AT+MDBR=?\r", 0x00, 10, ID_GetCalendarNotesInfo);
409 
410  return error;
411 }
412 
413 GSM_Error MOTOROLA_ParseCalendarSimple(GSM_StateMachine *s, const char *line)
414 {
415  GSM_Error error;
416  int ignore;
417  GSM_CalendarEntry *Note = s->Phone.Data.Cal;
418  int duration, repeat, has_time, has_alarm;
419  /*
420  * Parse following format:
421  *
422  * +MDBR: 0,"Meeting",1,0,"17:00","02-24-2006",60,"00:00","00-00-2000",0
423  * +MDBR: 1,"Breakfast",1,1,"10:00","02-25-2006",60,"09:30","02-25-2006",2
424  * event num, description, time flag (if 0, start time is meaningless), alarm enabl
425  * ed flag (if 0, alarm time is meaningless), time, date, duration (mins), alarm ti
426  * me, alarm date, repeat type
427  *
428  * repeat type:
429  * 1 = daily
430  * 2 = weekly
431  * 3 = monthly on date
432  * 4 = monthly on day
433  * 5 = yearly
434  */
435  Note->Type = GSM_CAL_MEMO;
436  Note->Entries[0].EntryType = CAL_TEXT;
438  Note->Entries[1].Date.Timezone = 0;
439  Note->Entries[1].Date.Second = 0;
441  Note->Entries[2].Date.Timezone = 0;
442  Note->Entries[2].Date.Second = 0;
443  Note->EntriesNum = 3;
444  error = ATGEN_ParseReply(s,
445  line,
446  "+MDBR: @i, @s, @i, @i, @d, @i, @d, @i",
447  &ignore,
448  Note->Entries[0].Text, sizeof(Note->Entries[0].Text),
449  &has_time,
450  &has_alarm,
451  &(Note->Entries[1].Date),
452  &duration,
453  &(Note->Entries[2].Date),
454  &repeat);
455 
456  if (!has_time && !has_alarm) {
457  Note->EntriesNum = 1;
458  } else if (!has_alarm) {
459  Note->EntriesNum = 2;
460  } else if (!has_time) {
461  Note->EntriesNum = 2;
462  Note->Entries[1].EntryType = Note->Entries[2].EntryType;
463  Note->Entries[1].Date = Note->Entries[2].Date;
464  }
465  switch (repeat) {
466  case 1:
468  Note->Entries[Note->EntriesNum].Number = 1;
469  Note->EntriesNum++;
470  break;
471  case 2:
473  Note->Entries[Note->EntriesNum].Number = 7;
474  Note->EntriesNum++;
475  break;
476  case 3:
478  Note->Entries[Note->EntriesNum].Number = 1;
479  Note->EntriesNum++;
481  Note->Entries[Note->EntriesNum].Number = Note->Entries[1].Date.Day;
482  Note->EntriesNum++;
483  break;
484  case 4:
486  Note->Entries[Note->EntriesNum].Number = 1;
487  Note->EntriesNum++;
489  Note->Entries[Note->EntriesNum].Number = Note->Entries[1].Date.Day;
490  Note->EntriesNum++;
491  break;
492  case 5:
494  Note->Entries[Note->EntriesNum].Number = 365;
495  Note->EntriesNum++;
496  break;
497  }
498  return error;
499 }
500 
501 GSM_Error MOTOROLA_ReplyGetCalendar(GSM_Protocol_Message *msg, GSM_StateMachine *s)
502 {
503  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
504  GSM_Error error;
505  const char *line;
506 
507  if (Priv->ReplyState != AT_Reply_OK) {
508  switch (s->Phone.Data.Priv.ATGEN.ReplyState) {
509  case AT_Reply_Error:
510  return ERR_NOTSUPPORTED;
511  case AT_Reply_CMSError:
512  return ATGEN_HandleCMSError(s);
513  case AT_Reply_CMEError:
514  return ATGEN_HandleCMEError(s);
515  default:
516  return ERR_UNKNOWNRESPONSE;
517  }
518  }
519 
520  line = GetLineString(msg->Buffer, &Priv->Lines, 2);
521 
522  if (strcmp("OK", line) == 0) {
523  return ERR_EMPTY;
524  }
525 
526  error = MOTOROLA_ParseCalendarSimple(s, line);
527  if (error != ERR_NONE) {
528  /* Fallback to parse complex later */
529  }
530  return error;
531 }
532 
533 GSM_Error MOTOROLA_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, gboolean start)
534 {
535  GSM_Error error;
536  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
537  if (start) {
538  /* One below actual first position */
539  Note->Location = 0;
540  error = MOTOROLA_GetCalendarStatus(s, &Priv->CalendarStatus);
541  if (error != ERR_NONE) {
542  return error;
543  }
544  Priv->CalendarRead = 0;
545  }
546  s->Phone.Data.Cal = Note;
547  Note->EntriesNum = 0;
548  smprintf(s, "Getting calendar entry\n");
549  error = ERR_EMPTY;
550  while (error == ERR_EMPTY) {
551  Note->Location++;
552  if (Note->Location >= Priv->CalendarStatus.Used + Priv->CalendarStatus.Free) {
553  /* We're at the end */
554  return ERR_EMPTY;
555  }
556  if (Priv->CalendarRead >= Priv->CalendarStatus.Used) {
557  /* We've read all entries */
558  return ERR_EMPTY;
559  }
560  error = MOTOROLA_GetCalendar(s, Note);
561  if (error == ERR_NONE) {
562  Priv->CalendarRead++;
563  }
564  }
565  return error;
566 }
567 
568 GSM_Error MOTOROLA_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
569 {
570  char req[50];
571  GSM_Error error;
572  size_t len;
573 
574  error = MOTOROLA_LockCalendar(s);
575  if (error != ERR_NONE) return ERR_NONE;
576 
577  s->Phone.Data.Cal = Note;
578 
579  len = sprintf(req, "AT+MDBR=%d\r", Note->Location - 1);
580 
581  error = ATGEN_WaitFor(s, req, len, 0x00, 10, ID_GetCalendarNote);
582  MOTOROLA_UnlockCalendar(s);
583  return error;
584 }
585 
586 GSM_Error MOTOROLA_ReplySetCalendar(GSM_Protocol_Message *msg, GSM_StateMachine *s)
587 {
588  return ERR_NOTIMPLEMENTED;
589 }
590 
591 GSM_Error MOTOROLA_DelCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
592 {
593  char req[50];
594  GSM_Error error;
595  size_t len;
596 
597  error = MOTOROLA_LockCalendar(s);
598  if (error != ERR_NONE) return ERR_NONE;
599 
600  len = sprintf(req, "AT+MDBWE=%d,0,0\r", Note->Location);
601 
602  error = ATGEN_WaitFor(s, req, len, 0x00, 10, ID_DeleteCalendarNote);
603  MOTOROLA_UnlockCalendar(s);
604  return error;
605 }
606 
607 GSM_Error MOTOROLA_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
608 {
609  GSM_Error error;
610 
611  error = MOTOROLA_LockCalendar(s);
612  if (error != ERR_NONE) return ERR_NONE;
613 
614  MOTOROLA_UnlockCalendar(s);
615  return ERR_NOTIMPLEMENTED;
616 }
617 
618 GSM_Error MOTOROLA_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
619 {
620  GSM_Error error;
621 
622  error = MOTOROLA_LockCalendar(s);
623  if (error != ERR_NONE) return ERR_NONE;
624 
625  MOTOROLA_UnlockCalendar(s);
626  return ERR_NOTIMPLEMENTED;
627 }
628 
629 GSM_Error MOTOROLA_ReplyGetMPBRMemoryStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
630 {
631  GSM_Phone_ATGENData *Priv = &s->Phone.Data.Priv.ATGEN;
632 
633  switch (Priv->ReplyState) {
634  case AT_Reply_OK:
635  smprintf(s, "Memory status received\n");
636  return ERR_NONE;
637  case AT_Reply_Error:
638  return ERR_UNKNOWN;
639  case AT_Reply_CMSError:
640  return ATGEN_HandleCMSError(s);
641  case AT_Reply_CMEError:
642  return ATGEN_HandleCMEError(s);
643  default:
644  return ERR_UNKNOWNRESPONSE;
645  }
646 }
647 
648 #endif
649 
652 
653 /* How should editor hadle tabs in this file? Add editor commands here.
654  * vim: noexpandtab sw=8 ts=8 sts=8:
655  */
void GSM_TweakInternationalNumber(unsigned char *Number, const GSM_NumberType numType)
Definition: gsmpbk.c:620
GSM_Error ATGEN_SetCharset(GSM_StateMachine *s, GSM_AT_Charset_Preference Prefer)
GSM_Error ATGEN_HandleCMEError(GSM_StateMachine *s)
GSM_MemoryEntry * Memory
Definition: gsmstate.h:497
GSM_CutLines Lines
Definition: atgen.h:243
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_Error GSM_WaitForOnce(GSM_StateMachine *s, unsigned const char *buffer, size_t length, int type, int timeout)
Definition: gsmstate.c:986
GSM_AT_Feature PBK_MPBR
Definition: atgen.h:303
GSM_CalendarStatus * CalStatus
Definition: gsmstate.h:553
GSM_EntryType EntryType
Definition: gammu-memory.h:372
unsigned char Text[(GSM_PHONEBOOK_TEXT_LENGTH+1) *2]
Definition: gammu-memory.h:399
int gboolean
Definition: gammu-types.h:23
GSM_CalendarNoteType Type
int MotorolaMemorySize
Definition: atgen.h:308
GSM_Phone Phone
Definition: gsmstate.h:1431
struct GSM_Phone_Data::@2 Priv
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
gboolean Mode
Definition: atgen.h:377
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_Phone_Data Data
Definition: gsmstate.h:1369
GSM_SubCalendarEntry Entries[GSM_CALENDAR_ENTRIES]
GSM_EntryLocation Location
Definition: gammu-memory.h:376
GSM_CalendarStatus CalendarStatus
Definition: atgen.h:315
int MotorolaFirstMemoryEntry
Definition: atgen.h:276
unsigned char * Buffer
Definition: protocol.h:22
#define UNUSED
Definition: gammu-misc.h:105
GSM_AT_Reply_State ReplyState
Definition: atgen.h:247
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