1 /* © 2007 - 2009 Michal Čihař */
2
3 /**
4 * @file motorola.c
5 * @author Michal Čihař
6 */
7 /**
8 * @ingroup Phone
9 * @{
10 */
11 /**
12 * @addtogroup ATPhone
13 * @{
14 */
15
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 "../../../libgammu/misc/string.h"
26
27 typedef struct {
28 char Command[20];
29 int Mode;
30 } MOTOROLA_CommandInfo;
31
32 /**
33 * AT Commands which can be issued only in one mode.
34 *
35 * List is based on c18 AT Commands document revision C.
36 */
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
MOTOROLA_SetModeReply(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)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
MOTOROLA_SetMode(GSM_StateMachine * s,const char * command)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 */
189 error = ATGEN_SetCharset(s, AT_PREF_CHARSET_RESET);
190 } else {
191 Priv->CurrentMode = cmd->Mode;
192 }
193 }
194 return error;
195 }
196
197 /**
198 * Catches +MBAN: reply.
199 */
MOTOROLA_Banner(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)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
MOTOROLA_ReplyGetMemoryInfo(GSM_Protocol_Message * msg,GSM_StateMachine * s)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",
222 &Priv->MotorolaFirstMemoryEntry,
223 &Priv->MotorolaMemorySize);
224 if (error != ERR_NONE) {
225 return error;
226 }
227
228 Priv->MotorolaMemorySize -= Priv->MotorolaFirstMemoryEntry;
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
MOTOROLA_ReplyGetMemory(GSM_Protocol_Message * msg,GSM_StateMachine * s)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;
258 Memory->Entries[0].Location = PBK_Location_Unknown;
259 Memory->Entries[1].EntryType = PBK_Text_Name;
260 Memory->Entries[1].Location = PBK_Location_Unknown;
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;
299 Memory->Entries[0].Location = PBK_Location_Unknown;
300 GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type);
301 break;
302 case 3:
303 Memory->Entries[0].EntryType = PBK_Number_Mobile;
304 Memory->Entries[0].Location = PBK_Location_Unknown;
305 GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type);
306 break;
307 case 4:
308 Memory->Entries[0].EntryType = PBK_Number_Fax;
309 Memory->Entries[0].Location = PBK_Location_Unknown;
310 GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type);
311 break;
312 case 5:
313 Memory->Entries[0].EntryType = PBK_Number_Pager;
314 Memory->Entries[0].Location = PBK_Location_Unknown;
315 GSM_TweakInternationalNumber(Memory->Entries[0].Text, number_type);
316 break;
317 case 6:
318 Memory->Entries[0].EntryType = PBK_Text_Email;
319 Memory->Entries[0].Location = PBK_Location_Unknown;
320 break;
321 case 7:
322 Memory->Entries[0].EntryType = PBK_Text_Email; /* Mailing list */
323 Memory->Entries[0].Location = PBK_Location_Unknown;
324 break;
325 default:
326 Memory->Entries[0].EntryType = PBK_Text_Note;
327 Memory->Entries[0].Location = PBK_Location_Unknown;
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
MOTOROLA_LockCalendar(GSM_StateMachine * s)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
MOTOROLA_UnlockCalendar(GSM_StateMachine * s)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
MOTOROLA_ReplyGetCalendarStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)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;
398 s->Phone.Data.CalStatus->Free += s->Phone.Data.CalStatus->Used;
399 return ERR_NONE;
400 }
401
MOTOROLA_GetCalendarStatus(GSM_StateMachine * s,GSM_CalendarStatus * Status)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
MOTOROLA_ParseCalendarSimple(GSM_StateMachine * s,const char * line)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;
437 Note->Entries[1].EntryType = CAL_START_DATETIME;
438 Note->Entries[1].Date.Timezone = 0;
439 Note->Entries[1].Date.Second = 0;
440 Note->Entries[2].EntryType = CAL_TONE_ALARM_DATETIME;
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:
467 Note->Entries[Note->EntriesNum].EntryType = CAL_REPEAT_FREQUENCY;
468 Note->Entries[Note->EntriesNum].Number = 1;
469 Note->EntriesNum++;
470 break;
471 case 2:
472 Note->Entries[Note->EntriesNum].EntryType = CAL_REPEAT_FREQUENCY;
473 Note->Entries[Note->EntriesNum].Number = 7;
474 Note->EntriesNum++;
475 break;
476 case 3:
477 Note->Entries[Note->EntriesNum].EntryType = CAL_REPEAT_FREQUENCY;
478 Note->Entries[Note->EntriesNum].Number = 1;
479 Note->EntriesNum++;
480 Note->Entries[Note->EntriesNum].EntryType = CAL_REPEAT_DAY;
481 Note->Entries[Note->EntriesNum].Number = Note->Entries[1].Date.Day;
482 Note->EntriesNum++;
483 break;
484 case 4:
485 Note->Entries[Note->EntriesNum].EntryType = CAL_REPEAT_FREQUENCY;
486 Note->Entries[Note->EntriesNum].Number = 1;
487 Note->EntriesNum++;
488 Note->Entries[Note->EntriesNum].EntryType = CAL_REPEAT_DAY;
489 Note->Entries[Note->EntriesNum].Number = Note->Entries[1].Date.Day;
490 Note->EntriesNum++;
491 break;
492 case 5:
493 Note->Entries[Note->EntriesNum].EntryType = CAL_REPEAT_FREQUENCY;
494 Note->Entries[Note->EntriesNum].Number = 365;
495 Note->EntriesNum++;
496 break;
497 }
498 return error;
499 }
500
MOTOROLA_ReplyGetCalendar(GSM_Protocol_Message * msg,GSM_StateMachine * s)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
MOTOROLA_GetNextCalendar(GSM_StateMachine * s,GSM_CalendarEntry * Note,gboolean start)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
MOTOROLA_GetCalendar(GSM_StateMachine * s,GSM_CalendarEntry * Note)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
MOTOROLA_ReplySetCalendar(GSM_Protocol_Message * msg,GSM_StateMachine * s)586 GSM_Error MOTOROLA_ReplySetCalendar(GSM_Protocol_Message *msg, GSM_StateMachine *s)
587 {
588 return ERR_NOTIMPLEMENTED;
589 }
590
MOTOROLA_DelCalendar(GSM_StateMachine * s,GSM_CalendarEntry * Note)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
MOTOROLA_SetCalendar(GSM_StateMachine * s,GSM_CalendarEntry * Note)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
MOTOROLA_AddCalendar(GSM_StateMachine * s,GSM_CalendarEntry * Note)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
MOTOROLA_ReplyGetMPBRMemoryStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)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
650 /*@}*/
651 /*@}*/
652
653 /* How should editor hadle tabs in this file? Add editor commands here.
654 * vim: noexpandtab sw=8 ts=8 sts=8:
655 */
656