Imported gammu 0.90.7
[gammu.git] / common / phone / alcatel / alcatel.c
blobaaee39141784fe7e56d95742acd5ba9b8c397e79
1 /*
2 * High level functions for communication with Alcatel One Touch 501 and
3 * compatible mobile phone.
5 * This code implements functions to communicate with Alcatel phones,
6 * currently seem to work:
7 * - BE5 series (501/701)
8 * - BF5 series (715)
9 * - BH4 series (535/735)
10 * For some functions it uses normal AT mode (not implemented here, look at
11 * ../at/atgen.[ch]) for others it switches into binary mode and initialises
12 * underlaying protocol (see ../../protocol/alcatel/alcabus.[ch]) and
13 * communicates over it. Don't ask me why Alcatel uses such silly thing...
15 * Notes for future features:
16 * - max phone number length is 61 (BE5)
17 * - max name length is 50 (BE5)
20 #include "../../gsmstate.h"
22 #ifdef GSM_ENABLE_ALCATEL
23 #ifdef GSM_ENABLE_ATGEN
25 #include <string.h>
26 #include <time.h>
28 #include "../../gsmcomon.h"
29 #include "../../misc/coding/coding.h"
30 #include "../../misc/misc.h"
31 #include "../../service/sms/gsmsms.h"
32 #include "../pfunc.h"
33 #include "alcatel.h"
35 /* Timeout for GSM_WaitFor calls. */
36 #define ALCATEL_TIMEOUT 64
38 /* Some magic numbers for protocol follow */
40 /* synchronisation types (for everything except begin transfer): */
41 #define ALCATEL_SYNC_TYPE_CALENDAR 0x64
42 #define ALCATEL_SYNC_TYPE_TODO 0x68
43 #define ALCATEL_SYNC_TYPE_CONTACTS 0x6C
45 /* synchronisation types (for begin transfer): */
46 #define ALCATEL_BEGIN_SYNC_CALENDAR 0x00
47 #define ALCATEL_BEGIN_SYNC_TODO 0x02
48 #define ALCATEL_BEGIN_SYNC_CONTACTS 0x01
50 /* category types */
51 #define ALCATEL_LIST_TODO_CAT 0x9B
52 #define ALCATEL_LIST_CONTACTS_CAT 0x96
55 /* We need lot of ATGEN functions, because Alcatel is an AT device. */
57 extern GSM_Reply_Function ALCATELReplyFunctions[];
58 extern GSM_Reply_Function ATGENReplyFunctions[];
60 extern GSM_Error ATGEN_Initialise (GSM_StateMachine *s);
61 extern GSM_Error ATGEN_Terminate (GSM_StateMachine *s);
62 extern GSM_Error ATGEN_GetIMEI (GSM_StateMachine *s);
63 extern GSM_Error ATGEN_GetFirmware (GSM_StateMachine *s);
64 extern GSM_Error ATGEN_GetModel (GSM_StateMachine *s);
65 extern GSM_Error ATGEN_GetDateTime (GSM_StateMachine *s, GSM_DateTime *date_time);
66 extern GSM_Error ATGEN_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry);
67 extern GSM_Error ATGEN_GetNextMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry, bool start);
68 extern GSM_Error ATGEN_SetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry);
69 extern GSM_Error ATGEN_AddMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry);
70 extern GSM_Error ATGEN_DeleteMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry);
71 extern GSM_Error ATGEN_GetMemoryStatus (GSM_StateMachine *s, GSM_MemoryStatus *Status);
72 extern GSM_Error ATGEN_GetSMSC (GSM_StateMachine *s, GSM_SMSC *smsc);
73 extern GSM_Error ATGEN_SetSMSC (GSM_StateMachine *s, GSM_SMSC *smsc);
74 extern GSM_Error ATGEN_GetSMSFolders (GSM_StateMachine *s, GSM_SMSFolders *folders);
75 extern GSM_Error ATGEN_GetSMSStatus (GSM_StateMachine *s, GSM_SMSMemoryStatus *status);
76 extern GSM_Error ATGEN_GetSMS (GSM_StateMachine *s, GSM_MultiSMSMessage *sms);
77 extern GSM_Error ATGEN_GetNextSMS (GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start);
78 extern GSM_Error ATGEN_SendSMS (GSM_StateMachine *s, GSM_SMSMessage *sms);
79 extern GSM_Error ATGEN_DeleteSMS (GSM_StateMachine *s, GSM_SMSMessage *sms);
80 extern GSM_Error ATGEN_AddSMS (GSM_StateMachine *s, GSM_SMSMessage *sms);
81 extern GSM_Error ATGEN_GetBatteryCharge (GSM_StateMachine *s, GSM_BatteryCharge *bat);
82 extern GSM_Error ATGEN_GetSignalQuality (GSM_StateMachine *s, GSM_SignalQuality *sig);
83 extern GSM_Error ATGEN_DialVoice (GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber);
84 extern GSM_Error ATGEN_AnswerCall (GSM_StateMachine *s, int ID, bool all);
85 extern GSM_Error ATGEN_CancelCall (GSM_StateMachine *s, int ID, bool all);
86 extern GSM_Error ATGEN_SetDateTime (GSM_StateMachine *s, GSM_DateTime *date_time);
87 extern GSM_Error ATGEN_EnterSecurityCode (GSM_StateMachine *s, GSM_SecurityCode Code);
88 extern GSM_Error ATGEN_GetSecurityStatus (GSM_StateMachine *s, GSM_SecurityCodeType *Status);
89 extern GSM_Error ATGEN_ResetPhoneSettings (GSM_StateMachine *s, GSM_ResetSettingsType Type);
90 extern GSM_Error ATGEN_SendDTMF (GSM_StateMachine *s, char *sequence);
91 extern GSM_Error ATGEN_GetSIMIMSI (GSM_StateMachine *s, char *IMSI);
92 extern GSM_Error ATGEN_HandleCMSError (GSM_StateMachine *s);
93 extern GSM_Error ATGEN_GetNetworkInfo (GSM_StateMachine *s, GSM_NetworkInfo *netinfo);
94 extern GSM_Error ATGEN_Reset (GSM_StateMachine *s, bool hard);
95 extern GSM_Error ATGEN_PressKey (GSM_StateMachine *s, GSM_KeyCode Key, bool Press);
96 extern GSM_Error ATGEN_GetDisplayStatus (GSM_StateMachine *s, GSM_DisplayFeatures *features);
97 extern GSM_Error ATGEN_SetAutoNetworkLogin (GSM_StateMachine *s);
98 extern GSM_Error ATGEN_DeleteAllMemory (GSM_StateMachine *s, GSM_MemoryType type);
100 extern GSM_Error ATGEN_DispatchMessage (GSM_StateMachine *s);
101 extern GSM_Error ATGEN_SetIncomingCB (GSM_StateMachine *s, bool enable);
102 extern GSM_Error ATGEN_SetIncomingSMS (GSM_StateMachine *s, bool enable);
105 * Alcatel uses some 8-bit characters in contacts, calendar etc.. This table
106 * attempts to decode it, it is probably not complete, here are just chars
107 * that I found...
109 unsigned char GSM_AlcatelAlphabet[] =
111 /* in phone unicode description */
112 0x80, 0x00,0x20, /* empty */
113 0x81, 0x00,0x20, /* empty */
114 0x82, 0x00,0x20, /* empty */
115 0x83, 0x00,0x20, /* empty */
117 0x84, 0x00,0xe7, /* c cedilla */
118 0x85, 0x20,0x26, /* ... */
119 0x86, 0x03,0xc0, /* pi */
120 0x87, 0x01,0x3e, /* l caron */
121 0x88, 0x00,0xc0, /* A grave */
122 0x89, 0x00,0xc1, /* A acute */
123 0x8a, 0x00,0xc2, /* A circumflex */
124 0x8b, 0x00,0xc3, /* A tilde */
125 0x8c, 0x00,0xc8, /* E grave */
126 0x8d, 0x00,0xca, /* E circumflex */
127 0x8e, 0x00,0xcb, /* E diaresis */
128 0x8f, 0x00,0xcc, /* I grave */
129 0x90, 0x00,0xcd, /* I acute */
130 0x91, 0x00,0xd0, /* ETH */
131 0x92, 0x00,0xd2, /* O grave */
132 0x93, 0x00,0xd3, /* O acute */
133 0x94, 0x00,0xd4, /* O circumflex */
134 0x95, 0x00,0xd5, /* O tilde */
135 0x96, 0x00,0xd9, /* U grave */
136 0x97, 0x00,0xda, /* U acute */
137 0x98, 0x00,0xe1, /* a acute */
138 0x99, 0x00,0xe2, /* a circumflex */
139 0x9a, 0x00,0xe3, /* a tilde */
140 0x9b, 0x00,0xea, /* e circumflex */
141 0x9c, 0x00,0xeb, /* e diaresis */
142 0x9d, 0x00,0xed, /* i acute */
143 0x9e, 0x00,0xee, /* i circumflex */
144 0x9f, 0x00,0xef, /* i diaresis */
145 0xa0, 0x00,0xf3, /* o acute */
146 0xa1, 0x00,0xf4, /* o circumflex */
147 0xa2, 0x00,0xf5, /* o tilde */
148 0xa3, 0x00,0xfa, /* u acute */
149 0xa4, 0x00,0xa2, /* cent */
150 0xa5, 0x00,0x5b, /* [ */
151 0xa6, 0x01,0x59, /* r caron */
152 0xa7, 0x01,0x0d, /* c caron */
153 0xa8, 0x01,0x61, /* s caron */
154 0xa9, 0x01,0x1b, /* e caron */
155 0xaa, 0x01,0x6f, /* u ring */
156 0xab, 0x00,0xfd, /* y acute */
157 0xac, 0x00,0xf0, /* eth */
158 0xad, 0x01,0x07, /* c acute */
159 0xae, 0x01,0x19, /* e ogonek */
160 0xaf, 0x01,0x05, /* a ogonek */
161 0xb0, 0x01,0x7c, /* z dot */
162 0xb1, 0x01,0x7a, /* z acute */
163 0xb2, 0x01,0x5b, /* s acute */
164 0xb3, 0x01,0x44, /* n acute */
165 0xb4, 0x01,0x42, /* l stroke */
167 0xb5, 0x00,0x20, /* empty */
169 0xb6, 0x01,0x48, /* n caron */
170 0xb7, 0x01,0x65, /* t caron */
172 0xb8, 0x00,0x20, /* empty */
174 0xb9, 0x01,0x7e, /* z caron */
175 0xba, 0x01,0xe7, /* g caron */
177 0xbb, 0x00,0x20, /* empty */
178 0xbc, 0x00,0x20, /* empty */
180 0xbd, 0x1e,0x20, /* G macron */
181 0xbe, 0x1e,0x21, /* g macron */
182 0xbf, 0x01,0x5e, /* S cedilla */
183 0xc0, 0x01,0x5f, /* s cedilla */
184 0xc1, 0x01,0x2f, /* i ogonek */ /* FIXME: not sure with this, it look like normal i */
185 0xc2, 0x01,0x31, /* i dotless */
186 0xc3, 0x01,0x68, /* U tilde */
187 0xc4, 0x01,0x50, /* O dbl acute */
188 0xc5, 0x01,0x69, /* u tilde */
189 0xc6, 0x01,0x51, /* o dbl acute */
190 0xc7, 0x27,0xa9, /* => */
191 0xc8, 0x27,0xa8, /* filled => */
192 0xc9, 0x00,0xd7, /* x */
193 0xca, 0x00,0x5d, /* ] */
194 0xcb, 0x26,0x0f, /* phone */
195 0xcc, 0x01,0x0f, /* d caron */
197 0xcd, 0x00,0x20, /* empty */
199 0xce, 0x00,0x7e, /* ~ */
200 0xcf, 0x00,0x5c, /* \ */
201 0xd0, 0x00,0x5e, /* ^ */
203 0xd1, 0x00,0x20, /* empty */
205 0xd2, 0x00,0x7b, /* { */
206 0xd3, 0x00,0x7c, /* | */
207 0xd4, 0x00,0x7d, /* } */
209 0xd5, 0x00,0x20, /* empty */
211 0xd6, 0x01,0x63, /* t cedilla */
213 0xd7, 0x00,0x20, /* empty */
214 0xd8, 0x00,0x20, /* empty */
215 0xd9, 0x00,0x20, /* empty */
216 0xda, 0x00,0x20, /* empty */
217 0xdb, 0x00,0x20, /* empty */
218 0xdc, 0x00,0x20, /* empty */
219 0xdd, 0x00,0x20, /* empty */
220 0xde, 0x00,0x20, /* empty */
221 0xdf, 0x00,0x20, /* empty */
222 0xe0, 0x00,0x20, /* empty */
224 0xe1, 0x00,0x20, /* two candles */ /* FIXME */
226 0xe2, 0x00,0x20, /* empty */
227 0xe3, 0x00,0x20, /* empty */
228 0xe4, 0x00,0x20, /* empty */
230 0xe5, 0x01,0xce, /* a caron */
231 0xe6, 0x01,0x01, /* a macron */
232 0xe7, 0x01,0x13, /* e macron */
233 0xe8, 0x01,0x2b, /* i macron */
234 0xe9, 0x01,0x4d, /* o macron */
235 0xea, 0x01,0x6b, /* u macron */
236 0xeb, 0x00,0x41, /* A */
237 0xec, 0x00,0x40, /* @ */
238 0xed, 0x00,0x20, /* some strange char :-) */ /* FIXME */
240 0xee, 0x00,0x20, /* big key stroken */ /* FIXME */
241 0xef, 0x00,0x20, /* big key */ /* FIXME */
243 0xf0, 0x00,0x20, /* empty */
245 0xf1, 0x00,0x31, /* 1 */
246 0xf2, 0x00,0x21, /* bold ! */
247 0xf3, 0x26,0x0e, /* black phone */
248 0xf4, 0x00,0x26, /* & */
249 0xf5, 0x23,0x7e, /* bell */
250 0xf6, 0x26,0x6a, /* note */
252 0xf7, 0x27,0x13, /* okay inv */ /* FIXME */
253 0xf8, 0x27,0x13, /* okay */
255 0xf9, 0x00,0x20, /* empty */
257 0xfa, 0x00,0x20, /* key */ /* FIXME */
259 0xfb, 0x00,0x20, /* empty */
261 0xfc, 0x20,0xac, /* Euro */
262 0xfd, 0x21,0x97, /* NE arrow */
263 0xfe, 0x21,0x98, /* SE arrow */
265 0xff, 0x00,0x20, /* empty */
267 0x00, 0x00,0x00
270 /* This is being called from atgen */
271 GSM_Error ALCATEL_ProtocolVersionReply (GSM_Protocol_Message msg, GSM_StateMachine *s)
273 char *str, *str2;
275 * Reply received here looks like:
276 * 1 "AT+CPROT=?"
277 * 2 "+CPROT: 0,"V1.0",1"
278 * 3 "+CPROT: 16,"V1.1",16"
279 * 4 "OK"
281 switch (s->Phone.Data.Priv.ATGEN.ReplyState) {
282 case AT_Reply_OK:
283 str = strstr(msg.Buffer, "\"V");
284 if (str == NULL) return GE_UNKNOWNRESPONSE;
285 str += 2;
286 while((str2 = strstr(str, "\"V")) != NULL) str = str2 + 2;
287 if (strncmp(str, "1.0", 3) == 0) {
288 s->Phone.Data.Priv.ALCATEL.ProtocolVersion = V_1_0;
289 } else if (strncmp(str, "1.1", 3) == 0) {
290 s->Phone.Data.Priv.ALCATEL.ProtocolVersion = V_1_1;
291 } else {
292 smprintf(s, "Unknown protocol version. Please send debug log and phone info to author.\n");
293 return GE_NOTIMPLEMENTED;
295 return GE_NONE;
296 case AT_Reply_Error:
297 case AT_Reply_CMSError:
298 return ATGEN_HandleCMSError(s);
299 default:
300 return GE_UNKNOWNRESPONSE;
304 static GSM_Error ALCATEL_SetBinaryMode(GSM_StateMachine *s)
306 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
307 GSM_Error error;
309 if (Priv->Mode == ModeBinary) return GE_NONE;
311 dbgprintf ("Changing to binary mode\n");
313 error=GSM_WaitFor (s, "AT+IFC=2,2\r", 11, 0x02, 4, ID_SetFlowControl);
314 if (error != GE_NONE) return error;
316 error=GSM_WaitFor (s, "AT+CPROT=?\r", 11, 0x02, 4, ID_AlcatelProtocol);
317 if (error != GE_NONE) return error;
319 if (Priv->ProtocolVersion == V_1_0) {
320 error=GSM_WaitFor (s, "AT+CPROT=16,\"V1.0\",16\r", 22, 0x00, 4, ID_AlcatelConnect);
321 } else {
322 error=GSM_WaitFor (s, "AT+CPROT=16,\"V1.1\",16\r", 22, 0x00, 4, ID_AlcatelConnect);
325 if (error == GE_TIMEOUT && s->Speed != 19200) {
326 smprintf(s, "HINT: Try changing speed to 19200, it is sometimes needed for Alcatel binary mode.\n");
329 if (error != GE_NONE) return error;
331 dbgprintf ("Changing protocol to Alcabus\n");
333 s->Protocol.Functions = &ALCABUSProtocol;
334 error = s->Protocol.Functions->Initialise(s);
335 if (error != GE_NONE) {
336 s->Protocol.Functions = &ATProtocol;
337 return error;
339 s->Phone.Functions->ReplyFunctions = ALCATELReplyFunctions;
340 Priv->Mode = ModeBinary;
341 Priv->BinaryItem = 0;
342 Priv->BinaryType = 0;
343 Priv->BinaryState = StateAttached;
344 return GE_NONE;
347 static GSM_Error ALCATEL_GoToBinaryState(GSM_StateMachine *s, GSM_Alcatel_BinaryState state, GSM_Alcatel_BinaryType type, int item) {
348 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
349 GSM_Error error;
350 unsigned char attach_buffer[] = {0x00, 0x00, 0x7C ,0x20};
351 unsigned char detach_buffer[] = {0x00, 0x01, 0x7C ,0x00};
352 unsigned char start_buffer[] =
353 {0x00, 0x04, 0x7C, 0x80, /* 4 byte database id follows */
354 0x12, 0x34, 0x56, 0x78};
355 unsigned char end_buffer[] =
356 {0x00, 0x04, 0x7C, 0x82,
357 0x00, /* type */
358 0x00, 0x00, 0x00, 0x00}; /* TimeStamp */
359 unsigned char close_buffer[] =
360 {0x00, 0x04,
361 0x00, /*type */
362 0x23, 0x01};
363 unsigned char select1_buffer[] =
364 {0x00, 0x00,
365 0x00, /*type */
366 0x20};
367 unsigned char select2_buffer[] =
368 {0x00, 0x04,
369 0x00, /*type */
370 0x22, 0x01, 0x00};
371 unsigned char begin_buffer[] =
372 {0x00, 0x04, 0x7C, 0x81,
373 0x00, /*type */
374 0x00, 0x85, 0x00};
375 unsigned char commit_buffer[] =
376 {0x00, 0x04,
377 0x00, /*type */
378 0x20, 0x01};
380 smprintf(s, "Alcatel state switcher: %d -> %d, %d -> %d, %d -> %d\n", Priv->BinaryState, state, Priv->BinaryType, type, Priv->BinaryItem, item);
381 error = ALCATEL_SetBinaryMode(s);
382 if (error != GE_NONE) return error;
384 /* Do we need to do anything? */
385 if ((state == Priv->BinaryState) && (type == Priv->BinaryType) && (item == Priv->BinaryItem)) return GE_NONE;
387 /* We're editing, but the next state is not the same. so commit editing */
388 if (Priv->BinaryState == StateEdit) {
389 switch (Priv->BinaryType) {
390 case TypeCalendar:
391 commit_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
392 break;
393 case TypeContacts:
394 commit_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
395 break;
396 case TypeToDo:
397 commit_buffer[2] = ALCATEL_SYNC_TYPE_TODO;
398 break;
400 dbgprintf ("Commiting edited record\n");
401 error=GSM_WaitFor (s, commit_buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelCommit);
402 if (error != GE_NONE) return error;
403 error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelCommit2);
404 if (error != GE_NONE) return error;
405 Priv->BinaryState = StateSession;
406 Priv->BinaryItem = 0;
409 /* Do we want to edit something of same type? */
410 if ((state == StateEdit) && (type == Priv->BinaryType)) {
411 /* Edit state doesn't need any switching, it is needed only for
412 * indication that e have to commit record before we switch to other
413 * mode.
415 Priv->BinaryState = StateEdit;
416 Priv->BinaryItem = item;
417 return GE_NONE;
420 /* Now we can be only in Attached or Session state, so if states and types matches, just keep them as they are */
421 if ((state == Priv->BinaryState) && (type == Priv->BinaryType)) {
422 return GE_NONE;
425 /* Do we need to close session? */
426 if (Priv->BinaryState == StateSession) {
427 dbgprintf ("Ending session\n");
428 switch (Priv->BinaryType) {
429 case TypeCalendar:
430 end_buffer[4] = ALCATEL_BEGIN_SYNC_CALENDAR;
431 break;
432 case TypeContacts:
433 end_buffer[4] = ALCATEL_BEGIN_SYNC_CONTACTS;
434 break;
435 case TypeToDo:
436 end_buffer[4] = ALCATEL_BEGIN_SYNC_TODO;
437 break;
439 error=GSM_WaitFor (s, end_buffer, 9, 0x02, ALCATEL_TIMEOUT, ID_AlcatelEnd);
440 if (error != GE_NONE) return error;
442 switch (Priv->BinaryType) {
443 case TypeCalendar:
444 close_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
445 break;
446 case TypeContacts:
447 close_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
448 break;
449 case TypeToDo:
450 close_buffer[2] = ALCATEL_SYNC_TYPE_TODO;
451 break;
453 dbgprintf ("Closing session\n");
454 error=GSM_WaitFor (s, close_buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelClose);
455 if (error != GE_NONE) return error;
457 dbgprintf ("Detaching binary mode\n");
458 GSM_WaitFor (s, detach_buffer, 4, 0x02, ALCATEL_TIMEOUT, ID_AlcatelDetach);
460 Priv->BinaryState = StateAttached;
461 Priv->BinaryType = 0;
464 /* Do we need to open session? */
465 if (state == StateSession || state == StateEdit) {
466 dbgprintf ("Starting session for %s\n",
467 (type == TypeCalendar ? "Calendar" :
468 (type == TypeToDo ? "Todo" :
469 (type == TypeContacts ? "Contacts" :
470 "Unknown!"))));
471 /* Fill up buffers */
472 switch (type) {
473 case TypeCalendar:
474 select1_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
475 select2_buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
476 begin_buffer[4] = ALCATEL_BEGIN_SYNC_CALENDAR;
477 break;
478 case TypeContacts:
479 select1_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
480 select2_buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
481 begin_buffer[4] = ALCATEL_BEGIN_SYNC_CONTACTS;
482 break;
483 case TypeToDo:
484 select1_buffer[2] = ALCATEL_SYNC_TYPE_TODO;
485 select2_buffer[2] = ALCATEL_SYNC_TYPE_TODO;
486 begin_buffer[4] = ALCATEL_BEGIN_SYNC_TODO;
487 break;
489 dbgprintf ("Attaching in binary mode\n");
491 /* Communicate */
492 error=GSM_WaitFor (s, attach_buffer, 4, 0x02, ALCATEL_TIMEOUT, ID_AlcatelAttach);
493 if (error != GE_NONE) return error;
495 smprintf(s,"Start session\n");
496 error=GSM_WaitFor (s, start_buffer, 8, 0x02, ALCATEL_TIMEOUT, ID_AlcatelStart);
497 if (error != GE_NONE) return error;
499 smprintf(s,"Select type\n");
500 error=GSM_WaitFor (s, select1_buffer, 4, 0x02, ALCATEL_TIMEOUT, ID_AlcatelSelect1);
501 if (error != GE_NONE) return error;
502 error=GSM_WaitFor (s, select2_buffer, 6, 0x02, ALCATEL_TIMEOUT, ID_AlcatelSelect2);
503 if (error != GE_NONE) return error;
504 error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelSelect3);
505 if (error != GE_NONE) return error;
507 smprintf(s,"Begin transfer\n");
508 error=GSM_WaitFor (s, begin_buffer, 8, 0x02, ALCATEL_TIMEOUT, ID_AlcatelBegin1);
509 if (error != GE_NONE) return error;
510 error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelBegin2);
511 if (error != GE_NONE) return error;
513 Priv->BinaryState = StateSession;
514 Priv->BinaryType = type;
515 /* Do we want to edit something of same type? */
516 if ((state == StateEdit) && (type == Priv->BinaryType)) {
517 Priv->BinaryState = StateEdit;
518 Priv->BinaryItem = item;
519 return GE_NONE;
522 return GE_NONE;
525 static GSM_Error ALCATEL_SetATMode(GSM_StateMachine *s)
527 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
528 GSM_Error error;
530 if (Priv->Mode == ModeAT) return GE_NONE;
532 error = ALCATEL_GoToBinaryState(s, StateAttached, 0, 0);
533 if (error != GE_NONE) return error;
535 error = s->Protocol.Functions->Terminate(s);
536 if (error != GE_NONE) return error;
538 dbgprintf ("Changing protocol to AT\n");
539 s->Protocol.Functions = &ATProtocol;
540 s->Phone.Functions->ReplyFunctions = ATGENReplyFunctions;
541 Priv->Mode = ModeAT;
543 my_sleep(100);
545 /* In case we don't send AT command short after closing binary mode,
546 * phone takes VERY long to react next time. The error code in
547 * intetionally ignored.
549 GSM_WaitFor (s, "AT\r", 3, 0x00, 0, ID_IncomingFrame);
551 return GE_NONE;
554 static GSM_Error ALCATEL_Initialise(GSM_StateMachine *s)
556 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
557 GSM_Error error;
559 Priv->Mode = ModeAT;
561 Priv->CalendarItems = NULL;
562 Priv->ContactsItems = NULL;
563 Priv->ToDoItems = NULL;
564 Priv->CalendarItemsCount = 0;
565 Priv->ToDoItemsCount = 0;
566 Priv->ContactsItemsCount = 0;
567 Priv->CurrentFields[0] = 0;
568 Priv->CurrentFieldsCount = 0;
569 Priv->CurrentFieldsItem = 0;
570 Priv->CurrentFieldsType = 0;
571 Priv->ProtocolVersion = V_1_0;
573 Priv->CurrentCategoriesCount = 0;
574 Priv->CurrentCategoriesType = 0;
576 s->Protocol.Functions = &ATProtocol;
577 s->Phone.Functions->ReplyFunctions = ATGENReplyFunctions;
579 if (ATGEN_Initialise(s) != GE_NONE || GSM_WaitFor (s, "AT\r", 3, 0x00, 2, ID_IncomingFrame) != GE_NONE) {
580 smprintf(s,"AT initialisation failed, trying to stop binary mode...\n");
581 s->Protocol.Functions = &ALCABUSProtocol;
582 error = s->Protocol.Functions->Terminate(s);
583 s->Protocol.Functions = &ATProtocol;
585 error = ATGEN_Initialise(s);
586 if (error != GE_NONE) return error;
589 return GE_NONE;
592 static GSM_Error ALCATEL_Terminate(GSM_StateMachine *s)
594 GSM_Error error;
595 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
597 free(Priv->CalendarItems);
598 free(Priv->ContactsItems);
599 free(Priv->ToDoItems);
600 error = ALCATEL_SetATMode(s);
601 return ATGEN_Terminate(s);
604 /* finds whether id is set in the phone */
605 static GSM_Error ALCATEL_IsIdAvailable(GSM_StateMachine *s, int id) {
606 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
607 int i;
609 if (id > ALCATEL_MAX_LOCATION) return GE_INVALIDLOCATION;
611 switch (Priv->BinaryType) {
612 case TypeCalendar:
613 Priv->CurrentList = &(Priv->CalendarItems);
614 Priv->CurrentCount = &(Priv->CalendarItemsCount);
615 break;
616 case TypeContacts:
617 Priv->CurrentList = &(Priv->ContactsItems);
618 Priv->CurrentCount = &(Priv->ContactsItemsCount);
619 break;
620 case TypeToDo:
621 Priv->CurrentList = &(Priv->ToDoItems);
622 Priv->CurrentCount = &(Priv->ToDoItemsCount);
623 break;
626 for (i=0; i<*Priv->CurrentCount; i++) {
627 if ((*Priv->CurrentList)[i] == id) return GE_NONE;
630 return GE_EMPTY;
633 /* finds next id that is available in the phone */
634 static GSM_Error ALCATEL_GetNextId(GSM_StateMachine *s, int *id) {
635 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
636 int i = 0;
637 int next = ALCATEL_MAX_LOCATION;
639 switch (Priv->BinaryType) {
640 case TypeCalendar:
641 Priv->CurrentList = &(Priv->CalendarItems);
642 Priv->CurrentCount = &(Priv->CalendarItemsCount);
643 break;
644 case TypeContacts:
645 Priv->CurrentList = &(Priv->ContactsItems);
646 Priv->CurrentCount = &(Priv->ContactsItemsCount);
647 break;
648 case TypeToDo:
649 Priv->CurrentList = &(Priv->ToDoItems);
650 Priv->CurrentCount = &(Priv->ToDoItemsCount);
651 break;
654 for (i=0; i<*Priv->CurrentCount; i++) {
655 if (((*Priv->CurrentList)[i] > *id) && ((*Priv->CurrentList)[i] < next )) {
656 next = (*Priv->CurrentList)[i];
659 if (next == ALCATEL_MAX_LOCATION) {
660 return GE_EMPTY;
661 } else {
662 *id = next;
663 return GE_NONE;
667 static GSM_Error ALCATEL_ReplyGetIds(GSM_Protocol_Message msg, GSM_StateMachine *s)
669 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
670 int count,i,pos;
672 count = msg.Buffer[10];
673 *Priv->CurrentCount += count;
675 *Priv->CurrentList = (int *)realloc(*Priv->CurrentList, (*Priv->CurrentCount + 1)* sizeof(int));
676 if (*Priv->CurrentList == NULL) return GE_MOREMEMORY;
678 for (i = 0; i < count; i++) {
679 pos = 11 + (4 * i);
680 (*Priv->CurrentList)[*Priv->CurrentCount - count + i] = msg.Buffer[pos + 3] +
681 (msg.Buffer[pos + 2] << 8) +
682 (msg.Buffer[pos + 1] << 16) +
683 (msg.Buffer[pos] << 24);
685 (*Priv->CurrentList)[*Priv->CurrentCount] = 0;
687 /* If last byte is 0, then we transmitted all items */
688 Priv->TransferCompleted = msg.Buffer[4 + msg.Buffer[4]] == 0;
689 return GE_NONE;
692 static GSM_Error ALCATEL_GetAvailableIds(GSM_StateMachine *s, bool refresh)
694 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
695 GSM_Error error;
696 int i;
697 unsigned char buffer[] =
698 {0x00, 0x04,
699 0x00, /*type */
700 0x2F, 0x01};
702 if (Priv->BinaryState != StateSession) return GE_UNKNOWN;
704 switch (Priv->BinaryType) {
705 case TypeCalendar:
706 buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
707 Priv->CurrentList = &(Priv->CalendarItems);
708 Priv->CurrentCount = &(Priv->CalendarItemsCount);
709 break;
710 case TypeContacts:
711 buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
712 Priv->CurrentList = &(Priv->ContactsItems);
713 Priv->CurrentCount = &(Priv->ContactsItemsCount);
714 break;
715 case TypeToDo:
716 buffer[2] = ALCATEL_SYNC_TYPE_TODO;
717 Priv->CurrentList = &(Priv->ToDoItems);
718 Priv->CurrentCount = &(Priv->ToDoItemsCount);
719 break;
722 if (*Priv->CurrentList != NULL) {
723 if (!refresh) return GE_NONE;
724 free(*Priv->CurrentList);
725 *Priv->CurrentList = NULL;
727 smprintf(s,"Reading items list\n");
729 *Priv->CurrentCount = 0;
730 Priv->TransferCompleted = false;
732 error=GSM_WaitFor (s, buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetIds1);
733 if (error != GE_NONE) return error;
735 while (!Priv->TransferCompleted) {
736 error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetIds2);
737 if (error != GE_NONE) return error;
740 i = 0;
741 smprintf(s,"Received %d ids: ", *Priv->CurrentCount);
742 for (i=0; i < *Priv->CurrentCount; i++) {
743 smprintf(s,"%x ", (*Priv->CurrentList)[i]);
745 smprintf(s,"\n");
747 return GE_NONE;
750 static GSM_Error ALCATEL_ReplyGetFields(GSM_Protocol_Message msg, GSM_StateMachine *s)
752 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
753 int i;
755 if (msg.Buffer[14] > GSM_PHONEBOOK_ENTRIES) {
756 smprintf(s, "WARNING: Field list truncated, you should increase GSM_PHONEBOOK_ENTRIES to at least %d\n", msg.Buffer[14]);
757 Priv->CurrentFieldsCount = GSM_PHONEBOOK_ENTRIES;
758 } else {
759 Priv->CurrentFieldsCount = msg.Buffer[14];
762 Priv->CurrentFields[Priv->CurrentFieldsCount] = 0;
764 for (i = 0; i < Priv->CurrentFieldsCount; i++) {
765 Priv->CurrentFields[i] = msg.Buffer[15 + i];
768 return GE_NONE;
771 static GSM_Error ALCATEL_GetFields(GSM_StateMachine *s, int id) {
772 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
773 GSM_Error error;
774 int i;
775 unsigned char buffer[] =
776 {0x00, 0x04,
777 0x00, /* type */
778 0x30, 0x01,
779 0x00, 0x00, 0x00, 0x00}; /* item */
781 if (Priv->BinaryState != StateSession) return GE_UNKNOWN;
782 if ((Priv->CurrentFieldsItem == id) && (Priv->CurrentFieldsType == Priv->BinaryType)) return GE_NONE;
784 smprintf(s,"Reading item fields (%d)\n", id);
786 buffer[5] = (id >> 24);
787 buffer[6] = ((id >> 16) & 0xff);
788 buffer[7] = ((id >> 8) & 0xff);
789 buffer[8] = (id & 0xff);
791 switch (Priv->BinaryType) {
792 case TypeCalendar:
793 buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
794 break;
795 case TypeContacts:
796 buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
797 break;
798 case TypeToDo:
799 buffer[2] = ALCATEL_SYNC_TYPE_TODO;
800 break;
803 Priv->CurrentFieldsItem = id;
804 Priv->CurrentFieldsType = Priv->BinaryType;
806 error=GSM_WaitFor (s, buffer, 9, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetFields1);
807 if (error != GE_NONE) return error;
808 error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetFields2);
809 if (error != GE_NONE) return error;
811 i = 0;
812 smprintf(s,"Received %d fields: ", Priv->CurrentFieldsCount);
813 for (i=0; i < Priv->CurrentFieldsCount; i++) {
814 smprintf(s,"%x ", Priv->CurrentFields[i]);
816 smprintf(s,"\n");
818 return GE_NONE;
821 static GSM_Error ALCATEL_ReplyGetFieldValue(GSM_Protocol_Message msg, GSM_StateMachine *s)
823 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
824 unsigned char *buffer = &(msg.Buffer[16]);
826 if (buffer[1] == 0x05 && buffer[2] == 0x67) {
827 /* date */
828 Priv->ReturnType = Alcatel_date;
829 Priv->ReturnDateTime.Day = buffer[4];
830 Priv->ReturnDateTime.Month = buffer[5];
831 Priv->ReturnDateTime.Year = buffer[7] + (buffer[6] << 8);
832 Priv->ReturnDateTime.Timezone = 0; /* FIXME: how to acquire this? */
834 Priv->ReturnDateTime.Hour = 0;
835 Priv->ReturnDateTime.Minute = 0;
836 Priv->ReturnDateTime.Second = 0;
837 } else if (buffer[1] == 0x06 && buffer[2] == 0x68) {
838 /* time */
839 Priv->ReturnType = Alcatel_time;
840 Priv->ReturnDateTime.Hour = buffer[4];
841 Priv->ReturnDateTime.Minute = buffer[5];
842 Priv->ReturnDateTime.Second = buffer[6];
844 Priv->ReturnDateTime.Day = 0;
845 Priv->ReturnDateTime.Month = 0;
846 Priv->ReturnDateTime.Year = 0;
847 Priv->ReturnDateTime.Timezone = 0;
848 } else if (buffer[1] == 0x08 && buffer[2] == 0x3C) {
849 /* string */
850 Priv->ReturnType = Alcatel_string;
851 if (GSM_PHONEBOOK_TEXT_LENGTH < buffer[3])
852 smprintf(s, "WARNING: Text truncated, you should increase GSM_PHONEBOOK_TEXT_LENGTH to at least %d\n", buffer[3] + 1);
853 if (Priv->ProtocolVersion == V_1_0) {
854 DecodeDefault( Priv->ReturnString, buffer + 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH, buffer[3]), false, GSM_AlcatelAlphabet);
855 } else if(Priv->ProtocolVersion == V_1_1 && (buffer[4] & 0x80)) {
856 memcpy(Priv->ReturnString, buffer + 5, buffer[3]);
857 Priv->ReturnString[buffer[3] + 1] = 0;
858 Priv->ReturnString[buffer[3] + 2] = 0;
859 ReverseUnicodeString(Priv->ReturnString);
860 } else {
861 DecodeDefault( Priv->ReturnString, buffer + 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH, buffer[3]), false, GSM_AlcatelAlphabet);
863 } else if (buffer[1] == 0x07 && buffer[2] == 0x3C) {
864 /* phone */
865 Priv->ReturnType = Alcatel_phone;
866 if (GSM_PHONEBOOK_TEXT_LENGTH < buffer[3])
867 smprintf(s, "WARNING: Text truncated, you should increase GSM_PHONEBOOK_TEXT_LENGTH to at least %d\n", buffer[3] + 1);
868 if (Priv->ProtocolVersion == V_1_0) {
869 DecodeDefault( Priv->ReturnString, buffer + 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH, buffer[3]), false, GSM_AlcatelAlphabet);
870 } else if(Priv->ProtocolVersion == V_1_1 && (buffer[4] & 0x80)) {
871 memcpy(Priv->ReturnString, buffer + 5, buffer[3]);
872 Priv->ReturnString[buffer[3] + 1] = 0;
873 Priv->ReturnString[buffer[3] + 2] = 0;
874 ReverseUnicodeString(Priv->ReturnString);
875 } else {
876 DecodeDefault( Priv->ReturnString, buffer + 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH, buffer[3]), false, GSM_AlcatelAlphabet);
878 } else if (buffer[1] == 0x03 && buffer[2] == 0x3B) {
879 /* boolean */
880 Priv->ReturnType = Alcatel_bool;
881 Priv->ReturnInt = buffer[3];
882 } else if (buffer[1] == 0x02 && buffer[2] == 0x3A) {
883 /* integer */
884 Priv->ReturnType = Alcatel_int;
885 Priv->ReturnInt = buffer[6] + (buffer[5] << 8) + (buffer[4] << 16) + (buffer[3] << 24);
886 } else if (buffer[1] == 0x04 && buffer[2] == 0x38) {
887 /* enumeration */
888 Priv->ReturnType = Alcatel_enum;
889 Priv->ReturnInt = buffer[3];
890 } else if (buffer[1] == 0x00 && buffer[2] == 0x38) {
891 /* byte */
892 Priv->ReturnType = Alcatel_byte;
893 Priv->ReturnInt = buffer[3];
894 } else {
895 smprintf(s, "WARNING: Uknown data type received (%02X,%02X)\n", buffer[1], buffer[2]);
896 return GE_UNKNOWNRESPONSE;
898 return GE_NONE;
901 static GSM_Error ALCATEL_GetFieldValue(GSM_StateMachine *s, int id, int field)
903 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
904 GSM_Error error;
905 unsigned char buffer[] =
906 {0x00, 0x04,
907 0x00, /* type */
908 0x1f, 0x01,
909 0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */
910 0x00}; /* field */
912 smprintf(s,"Reading item value (%08x.%02x)\n", id, field);
914 switch (Priv->BinaryType) {
915 case TypeCalendar:
916 buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
917 break;
918 case TypeContacts:
919 buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
920 break;
921 case TypeToDo:
922 buffer[2] = ALCATEL_SYNC_TYPE_TODO;
923 break;
926 buffer[5] = (id >> 24);
927 buffer[6] = ((id >> 16) & 0xff);
928 buffer[7] = ((id >> 8) & 0xff);
929 buffer[8] = (id & 0xff);
930 buffer[9] = (field & 0xff);
932 error=GSM_WaitFor (s, buffer, 10, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetFieldValue1);
933 if (error != GE_NONE) return error;
934 error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetFieldValue2);
935 if (error != GE_NONE) return error;
937 return GE_NONE;
940 static GSM_Error ALCATEL_ReplyGetCategories(GSM_Protocol_Message msg, GSM_StateMachine *s)
942 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
943 int i;
945 /* Did we get any category? */
946 if (msg.Buffer[4] == 6) {
947 Priv->CurrentCategoriesCount = 0;
948 return GE_NONE;
950 if (msg.Buffer[12] > ALCATEL_MAX_CATEGORIES) {
951 smprintf(s, "WARNING: Field list truncated, you should increase ALCATEL_MAX_CATEGORIES to at least %d\n", msg.Buffer[12]);
952 Priv->CurrentCategoriesCount = ALCATEL_MAX_CATEGORIES;
953 } else {
954 Priv->CurrentCategoriesCount = msg.Buffer[12];
957 for (i = 0; i < Priv->CurrentCategoriesCount; i++) {
958 Priv->CurrentCategories[i] = msg.Buffer[13 + i];
959 Priv->CurrentCategoriesCache[i][0] = '\000';
960 Priv->CurrentCategoriesCache[i][1] = '\000';
963 return GE_NONE;
966 static GSM_Error ALCATEL_GetAvailableCategoryIds(GSM_StateMachine *s) {
967 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
968 GSM_Error error;
969 int i;
970 unsigned char buffer[] =
971 {0x00, 0x04,
972 0x00 /*type */,
973 0x0b,
974 0x00 /* list */};
976 if (Priv->BinaryState != StateSession) return GE_UNKNOWN;
977 if (Priv->CurrentCategoriesType == Priv->BinaryType) return GE_NONE;
978 switch (Priv->BinaryType) {
979 case TypeContacts:
980 buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
981 buffer[4] = ALCATEL_LIST_CONTACTS_CAT;
982 break;
983 case TypeToDo:
984 buffer[2] = ALCATEL_SYNC_TYPE_TODO;
985 buffer[4] = ALCATEL_LIST_TODO_CAT;
986 break;
987 default:
988 return GE_NOTSUPPORTED;
991 Priv->CurrentCategoriesType = Priv->BinaryType;
993 smprintf(s,"Reading category list\n");
995 error=GSM_WaitFor (s, buffer, 5, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetCategories1);
996 if (error != GE_NONE) return error;
998 error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetCategories2);
999 if (error != GE_NONE) return error;
1001 i = 0;
1002 smprintf(s,"Received %d ids: ", Priv->CurrentCategoriesCount);
1003 for (i=0; i < Priv->CurrentCategoriesCount; i++) {
1004 smprintf(s,"%i ", Priv->CurrentCategories[i]);
1006 smprintf(s,"\n");
1008 return GE_NONE;
1011 static GSM_Error ALCATEL_IsCategoryIdAvailable(GSM_StateMachine *s, int id) {
1012 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1013 int i = 0;
1015 if (Priv->CurrentCategoriesType != Priv->BinaryType) return GE_UNKNOWN;
1017 for (i = 0; i< Priv->CurrentCategoriesCount; i++) {
1018 if (Priv->CurrentCategories[i] == id) return GE_NONE;
1020 return GE_EMPTY;
1023 static GSM_Error ALCATEL_ReplyGetCategoryText(GSM_Protocol_Message msg, GSM_StateMachine *s)
1025 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1026 int len;
1028 len = msg.Buffer[14];
1029 if (len > GSM_MAX_CATEGORY_NAME_LENGTH) {
1030 smprintf(s, "WARNING: Category name truncated, you should increase GSM_MAX_CATEGORY_NAME_LENGTH to at least %d\n", len);
1032 if (Priv->ProtocolVersion == V_1_0) {
1033 DecodeDefault( Priv->ReturnString, msg.Buffer + 15, MIN(GSM_MAX_CATEGORY_NAME_LENGTH, len), false, GSM_AlcatelAlphabet);
1034 } else if(Priv->ProtocolVersion == V_1_1 && (msg.Buffer[15] & 0x80)) {
1035 memcpy(Priv->ReturnString, msg.Buffer + 16, len);
1036 Priv->ReturnString[len + 1] = 0;
1037 Priv->ReturnString[len + 2] = 0;
1038 ReverseUnicodeString(Priv->ReturnString);
1039 } else {
1040 DecodeDefault( Priv->ReturnString, msg.Buffer + 15, MIN(GSM_MAX_CATEGORY_NAME_LENGTH, len), false, GSM_AlcatelAlphabet);
1042 return GE_NONE;
1045 static GSM_Error ALCATEL_GetCategoryText(GSM_StateMachine *s, int id) {
1046 unsigned char buffer[] = {0x00, 0x04, 0x00 /*type*/, 0x0c, 0x00 /*list*/, 0x0A, 0x01, 0x00 /*item*/ };
1047 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1048 GSM_Error error;
1050 if (Priv->CurrentCategoriesCache[id][0] != '\000' || Priv->CurrentCategoriesCache[id][1] != '\000') {
1051 CopyUnicodeString(Priv->ReturnString, Priv->CurrentCategoriesCache[id]);
1052 return GE_NONE;
1055 switch (Priv->BinaryType) {
1056 case TypeContacts:
1057 buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1058 buffer[4] = ALCATEL_LIST_CONTACTS_CAT;
1059 break;
1060 case TypeToDo:
1061 buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1062 buffer[4] = ALCATEL_LIST_TODO_CAT;
1063 break;
1064 default:
1065 return GE_NOTSUPPORTED;
1068 buffer[7] = (id & 0xff);
1070 error=GSM_WaitFor (s, buffer, 8, 0x02, ALCATEL_TIMEOUT, ID_AlcatelGetCategoryText1);
1071 if (error != GE_NONE) return error;
1072 error=GSM_WaitFor (s, 0, 0, 0x00, ALCATEL_TIMEOUT, ID_AlcatelGetCategoryText2);
1073 if (error != GE_NONE) return error;
1075 CopyUnicodeString(Priv->CurrentCategoriesCache[id], Priv->ReturnString);
1077 return GE_NONE;
1080 static GSM_Error ALCATEL_DeleteField(GSM_StateMachine *s, int id, int field) {
1081 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1082 GSM_Error error;
1083 unsigned char buffer[] =
1084 {0x00, 0x04,
1085 0x00, /* type */
1086 0x26, 0x01,
1087 0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */
1088 0x65, 0x01,
1089 0x00, /* field */
1090 0x01};
1092 smprintf(s,"Deleting field (%08x.%02x)\n", id, field);
1094 switch (Priv->BinaryType) {
1095 case TypeCalendar:
1096 buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
1097 break;
1098 case TypeContacts:
1099 buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1100 break;
1101 case TypeToDo:
1102 buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1103 break;
1106 buffer[5] = (id >> 24);
1107 buffer[6] = ((id >> 16) & 0xff);
1108 buffer[7] = ((id >> 8) & 0xff);
1109 buffer[8] = (id & 0xff);
1110 buffer[11] = (field & 0xff);
1112 error=GSM_WaitFor (s, buffer, 13, 0x02, ALCATEL_TIMEOUT, ID_AlcatelDeleteField);
1113 if (error != GE_NONE) return error;
1115 return GE_NONE;
1118 static GSM_Error ALCATEL_DeleteItem(GSM_StateMachine *s, int id) {
1119 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1120 GSM_Error error;
1121 unsigned char buffer[] =
1122 {0x00, 0x04,
1123 0x00, /* type */
1124 0x27, 0x01,
1125 0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */
1126 0x42};
1128 smprintf(s,"Deleting item (%08x)\n", id);
1130 switch (Priv->BinaryType) {
1131 case TypeCalendar:
1132 buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
1133 break;
1134 case TypeContacts:
1135 buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1136 break;
1137 case TypeToDo:
1138 buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1139 break;
1142 buffer[5] = (id >> 24);
1143 buffer[6] = ((id >> 16) & 0xff);
1144 buffer[7] = ((id >> 8) & 0xff);
1145 buffer[8] = (id & 0xff);
1147 error=GSM_WaitFor (s, buffer, 10, 0x02, ALCATEL_TIMEOUT, ID_AlcatelDeleteItem1);
1148 if (error != GE_NONE) return error;
1150 error=GSM_WaitFor (s, 0, 0, 0x0, ALCATEL_TIMEOUT, ID_AlcatelDeleteItem2);
1151 if (error != GE_NONE) return error;
1153 return GE_NONE;
1156 static GSM_Error ALCATEL_ReplyDeleteItem(GSM_Protocol_Message msg, GSM_StateMachine *s)
1158 if (msg.Buffer[8] != 0x25) return GE_UNKNOWNRESPONSE;
1159 return GE_NONE;
1162 static GSM_Error ALCATEL_BuildWriteBuffer(unsigned char * buffer, GSM_Alcatel_FieldType type, int field, void *data) {
1163 int len;
1165 buffer[1] = field & 0xff;
1167 switch(type) {
1168 case Alcatel_date:
1169 if (!CheckDate((GSM_DateTime *)data)) return GE_INVALIDDATETIME;
1171 buffer[3] = 0x05;
1172 buffer[4] = 0x67;
1174 buffer[0] = 0x09;
1175 buffer[5] = 0x04;
1176 buffer[6] = ((GSM_DateTime *)data)->Day & 0xff;
1177 buffer[7] = ((GSM_DateTime *)data)->Month & 0xff;
1178 buffer[8] = ((GSM_DateTime *)data)->Year >> 8;
1179 buffer[9] = ((GSM_DateTime *)data)->Year & 0xff;
1180 buffer[10] = 0x00;
1181 break;
1182 case Alcatel_time:
1183 if (!CheckTime((GSM_DateTime *)data)) return GE_INVALIDDATETIME;
1185 buffer[3] = 0x06;
1186 buffer[4] = 0x68;
1188 buffer[0] = 0x08;
1189 buffer[5] = 0x03;
1190 buffer[6] = ((GSM_DateTime *)data)->Hour & 0xff;
1191 buffer[7] = ((GSM_DateTime *)data)->Minute & 0xff;
1192 buffer[8] = ((GSM_DateTime *)data)->Second & 0xff;
1193 buffer[9] = 0x00;
1194 break;
1195 case Alcatel_string:
1196 buffer[3] = 0x08;
1197 buffer[4] = 0x3c;
1199 len = MIN(UnicodeLength((char *)data),62);
1200 EncodeDefault(buffer + 6, (char *)data, &len, false, GSM_AlcatelAlphabet);
1201 buffer[5] = len;
1202 buffer[0] = 5 + len;
1203 buffer[6 + len] = 0x00;
1204 break;
1205 case Alcatel_phone:
1206 buffer[3] = 0x07;
1207 buffer[4] = 0x3c;
1209 len = MIN(UnicodeLength((char *)data),50);
1210 EncodeDefault(buffer + 6, (char *)data, &len, false, GSM_AlcatelAlphabet);
1211 buffer[5] = len;
1212 buffer[0] = 5 + len;
1213 buffer[6 + len] = 0x00;
1214 break;
1215 case Alcatel_enum:
1216 buffer[3] = 0x04;
1217 buffer[4] = 0x38;
1219 buffer[0] = 0x05;
1220 buffer[5] = *(int *)data & 0xff;
1221 buffer[6] = 0x00;
1222 break;
1223 case Alcatel_bool:
1224 buffer[3] = 0x03;
1225 buffer[4] = 0x3b;
1227 buffer[0] = 0x05;
1228 buffer[5] = *(int *)data & 0xff;
1229 buffer[6] = 0x00;
1230 break;
1231 case Alcatel_int:
1232 buffer[3] = 0x02;
1233 buffer[4] = 0x3a;
1235 buffer[0] = 0x08;
1236 buffer[5] = *(unsigned int *)data >> 24;
1237 buffer[6] = (*(unsigned int *)data >> 16) & 0xff;
1238 buffer[7] = (*(unsigned int *)data >> 8) & 0xff;
1239 buffer[8] = *(unsigned int *)data & 0xff;
1240 buffer[9] = 0x00;
1241 break;
1242 case Alcatel_byte:
1243 buffer[3] = 0x00;
1244 buffer[4] = 0x38;
1246 buffer[0] = 0x05;
1247 buffer[5] = *(int *)data & 0xff;
1248 buffer[6] = 0x00;
1249 break;
1251 return GE_NONE;
1254 static GSM_Error ALCATEL_CreateField(GSM_StateMachine *s, GSM_Alcatel_FieldType type, int field, void *data) {
1255 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1256 GSM_Error error;
1257 unsigned char buffer[200] =
1258 {0x00, 0x04,
1259 0x00, /* type */
1260 0x25, 0x01, 0x65,
1261 0x00, /* length of remaining part */
1262 0x00, /* field */
1263 0x37}; /* data follows here */
1265 smprintf(s,"Creating field (%02x)\n", field);
1267 switch (Priv->BinaryType) {
1268 case TypeCalendar:
1269 buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
1270 break;
1271 case TypeContacts:
1272 buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1273 break;
1274 case TypeToDo:
1275 buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1276 break;
1278 error = ALCATEL_BuildWriteBuffer(buffer + 6, type, field, data);
1279 if (error != GE_NONE) return error;
1281 error = GSM_WaitFor (s, buffer, 8 + buffer[6], 0x02, ALCATEL_TIMEOUT, ID_AlcatelCreateField);
1282 if (error != GE_NONE) return error;
1284 return GE_NONE;
1287 static GSM_Error ALCATEL_UpdateField(GSM_StateMachine *s, GSM_Alcatel_FieldType type, int id, int field, void *data) {
1288 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1289 GSM_Error error;
1290 unsigned char buffer[200] =
1291 {0x00, 0x04,
1292 0x00, /* type */
1293 0x26, 0x01,
1294 0x00, 0x00, 0x00, 0x00, /* id */
1295 0x65,
1296 0x00, /* length of remaining part */
1297 0x00, /* field */
1298 0x37}; /* data follows here */
1300 smprintf(s,"Updating field (%08x.%02x)\n", id, field);
1302 buffer[5] = (id >> 24);
1303 buffer[6] = ((id >> 16) & 0xff);
1304 buffer[7] = ((id >> 8) & 0xff);
1305 buffer[8] = (id & 0xff);
1307 switch (Priv->BinaryType) {
1308 case TypeCalendar:
1309 buffer[2] = ALCATEL_SYNC_TYPE_CALENDAR;
1310 break;
1311 case TypeContacts:
1312 buffer[2] = ALCATEL_SYNC_TYPE_CONTACTS;
1313 break;
1314 case TypeToDo:
1315 buffer[2] = ALCATEL_SYNC_TYPE_TODO;
1316 break;
1318 error = ALCATEL_BuildWriteBuffer(buffer + 10, type, field, data);
1319 if (error != GE_NONE) return error;
1321 error = GSM_WaitFor (s, buffer, 12 + buffer[10], 0x02, ALCATEL_TIMEOUT, ID_AlcatelUpdateField);
1322 if (error != GE_NONE) return error;
1324 return GE_NONE;
1327 static GSM_Error ALCATEL_GetManufacturer(GSM_StateMachine *s)
1329 strcpy(s->Phone.Data.Manufacturer, "Alcatel");
1330 return GE_NONE;
1333 static GSM_Error ALCATEL_GetIMEI (GSM_StateMachine *s)
1335 GSM_Error error;
1337 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
1338 return ATGEN_GetIMEI(s);
1341 static GSM_Error ALCATEL_GetFirmware(GSM_StateMachine *s)
1343 GSM_Error error;
1345 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
1346 return ATGEN_GetFirmware(s);
1349 static GSM_Error ALCATEL_GetModel(GSM_StateMachine *s)
1351 GSM_Error error;
1353 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
1354 return ATGEN_GetModel(s);
1357 static GSM_Error ALCATEL_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
1359 GSM_Error error;
1361 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
1362 return ATGEN_GetDateTime(s, date_time);
1365 static GSM_Error ALCATEL_GetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1367 GSM_Error error;
1368 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1369 int i;
1370 int j = 0;
1372 if (entry->MemoryType == GMT_ME) {
1373 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= GE_NONE) return error;
1374 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
1375 if ((error = ALCATEL_IsIdAvailable(s, entry->Location))!= GE_NONE) {
1376 entry->EntriesNum = 0;
1377 return error;
1379 if ((error = ALCATEL_GetFields(s, entry->Location))!= GE_NONE) return error;
1381 entry->EntriesNum = Priv->CurrentFieldsCount;
1382 entry->PreferUnicode = false;
1384 for (i=0; i<Priv->CurrentFieldsCount; i++) {
1385 if ((error = ALCATEL_GetFieldValue(s, entry->Location, Priv->CurrentFields[i]))!= GE_NONE) return error;
1386 entry->Entries[i].VoiceTag = 0;
1387 switch (Priv->CurrentFields[i]) {
1388 case 0:
1389 if (Priv->ReturnType != Alcatel_string) {
1390 smprintf(s,"WARNING: Received unexpected type %02X for field 0, ignoring\n", Priv->ReturnType);
1391 entry->EntriesNum--;
1392 j++;
1393 break;
1395 entry->Entries[i - j].EntryType = PBK_Text_LastName;
1396 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1397 break;
1398 case 1:
1399 if (Priv->ReturnType != Alcatel_string) {
1400 smprintf(s,"WARNING: Received unexpected type %02X for field 1, ignoring\n", Priv->ReturnType);
1401 entry->EntriesNum--;
1402 j++;
1403 break;
1405 entry->Entries[i - j].EntryType = PBK_Text_FirstName;
1406 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1407 break;
1408 case 2:
1409 if (Priv->ReturnType != Alcatel_string) {
1410 smprintf(s,"WARNING: Received unexpected type %02X for field 2, ignoring\n", Priv->ReturnType);
1411 entry->EntriesNum--;
1412 j++;
1413 break;
1415 entry->Entries[i - j].EntryType = PBK_Text_Company;
1416 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1417 break;
1418 case 3:
1419 if (Priv->ReturnType != Alcatel_string) {
1420 smprintf(s,"WARNING: Received unexpected type %02X for field 3, ignoring\n", Priv->ReturnType);
1421 entry->EntriesNum--;
1422 j++;
1423 break;
1425 entry->Entries[i - j].EntryType = PBK_Text_JobTitle;
1426 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1427 break;
1428 case 4:
1429 if (Priv->ReturnType != Alcatel_string) {
1430 smprintf(s,"WARNING: Received unexpected type %02X for field 4, ignoring\n", Priv->ReturnType);
1431 entry->EntriesNum--;
1432 j++;
1433 break;
1435 entry->Entries[i - j].EntryType = PBK_Text_Note;
1436 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1437 break;
1438 case 5:
1439 if (Priv->ReturnType != Alcatel_byte) {
1440 smprintf(s,"WARNING: Received unexpected type %02X for field 5, ignoring\n", Priv->ReturnType);
1441 entry->EntriesNum--;
1442 j++;
1443 break;
1445 entry->Entries[i - j].EntryType = PBK_Category;
1446 entry->Entries[i - j].Number = Priv->ReturnInt;
1447 break;
1448 case 6:
1449 if (Priv->ReturnType != Alcatel_bool) {
1450 smprintf(s,"WARNING: Received unexpected type %02X for field 6, ignoring\n", Priv->ReturnType);
1451 entry->EntriesNum--;
1452 j++;
1453 break;
1455 entry->Entries[i - j].EntryType = PBK_Private;
1456 entry->Entries[i - j].Number = Priv->ReturnInt;
1457 break;
1458 case 7:
1459 if (Priv->ReturnType != Alcatel_phone) {
1460 smprintf(s,"WARNING: Received unexpected type %02X for field 7, ignoring\n", Priv->ReturnType);
1461 entry->EntriesNum--;
1462 j++;
1463 break;
1465 entry->Entries[i - j].EntryType = PBK_Number_Work;
1466 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1467 break;
1468 case 8:
1469 if (Priv->ReturnType != Alcatel_phone) {
1470 smprintf(s,"WARNING: Received unexpected type %02X for field 8, ignoring\n", Priv->ReturnType);
1471 entry->EntriesNum--;
1472 j++;
1473 break;
1475 entry->Entries[i - j].EntryType = PBK_Number_General;
1476 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1477 break;
1478 case 9:
1479 if (Priv->ReturnType != Alcatel_phone) {
1480 smprintf(s,"WARNING: Received unexpected type %02X for field 9, ignoring\n", Priv->ReturnType);
1481 entry->EntriesNum--;
1482 j++;
1483 break;
1485 entry->Entries[i - j].EntryType = PBK_Number_Fax;
1486 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1487 break;
1488 case 10:
1489 if (Priv->ReturnType != Alcatel_phone) {
1490 smprintf(s,"WARNING: Received unexpected type %02X for field 10, ignoring\n", Priv->ReturnType);
1491 entry->EntriesNum--;
1492 j++;
1493 break;
1495 entry->Entries[i - j].EntryType = PBK_Number_Other;
1496 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1497 break;
1498 case 11:
1499 if (Priv->ReturnType != Alcatel_phone) {
1500 smprintf(s,"WARNING: Received unexpected type %02X for field 11, ignoring\n", Priv->ReturnType);
1501 entry->EntriesNum--;
1502 j++;
1503 break;
1505 entry->Entries[i - j].EntryType = PBK_Number_Pager;
1506 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1507 break;
1508 case 12:
1509 if (Priv->ReturnType != Alcatel_phone) {
1510 smprintf(s,"WARNING: Received unexpected type %02X for field 12, ignoring\n", Priv->ReturnType);
1511 entry->EntriesNum--;
1512 j++;
1513 break;
1515 entry->Entries[i - j].EntryType = PBK_Number_Mobile;
1516 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1517 break;
1518 case 13:
1519 if (Priv->ReturnType != Alcatel_phone) {
1520 smprintf(s,"WARNING: Received unexpected type %02X for field 13, ignoring\n", Priv->ReturnType);
1521 entry->EntriesNum--;
1522 j++;
1523 break;
1525 entry->Entries[i - j].EntryType = PBK_Number_Home;
1526 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1527 break;
1528 case 14:
1529 if (Priv->ReturnType != Alcatel_string) {
1530 smprintf(s,"WARNING: Received unexpected type %02X for field 14, ignoring\n", Priv->ReturnType);
1531 entry->EntriesNum--;
1532 j++;
1533 break;
1535 entry->Entries[i - j].EntryType = PBK_Text_Email;
1536 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1537 break;
1538 case 15:
1539 if (Priv->ReturnType != Alcatel_string) {
1540 smprintf(s,"WARNING: Received unexpected type %02X for field 15, ignoring\n", Priv->ReturnType);
1541 entry->EntriesNum--;
1542 j++;
1543 break;
1545 entry->Entries[i - j].EntryType = PBK_Text_Email2;
1546 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1547 break;
1548 case 16:
1549 if (Priv->ReturnType != Alcatel_string) {
1550 smprintf(s,"WARNING: Received unexpected type %02X for field 16, ignoring\n", Priv->ReturnType);
1551 entry->EntriesNum--;
1552 j++;
1553 break;
1555 entry->Entries[i - j].EntryType = PBK_Text_StreetAddress;
1556 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1557 break;
1558 case 17:
1559 if (Priv->ReturnType != Alcatel_string) {
1560 smprintf(s,"WARNING: Received unexpected type %02X for field 17, ignoring\n", Priv->ReturnType);
1561 entry->EntriesNum--;
1562 j++;
1563 break;
1565 entry->Entries[i - j].EntryType = PBK_Text_City;
1566 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1567 break;
1568 case 18:
1569 if (Priv->ReturnType != Alcatel_string) {
1570 smprintf(s,"WARNING: Received unexpected type %02X for field 18, ignoring\n", Priv->ReturnType);
1571 entry->EntriesNum--;
1572 j++;
1573 break;
1575 entry->Entries[i - j].EntryType = PBK_Text_State;
1576 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1577 break;
1578 case 19:
1579 if (Priv->ReturnType != Alcatel_string) {
1580 smprintf(s,"WARNING: Received unexpected type %02X for field 19, ignoring\n", Priv->ReturnType);
1581 entry->EntriesNum--;
1582 j++;
1583 break;
1585 entry->Entries[i - j].EntryType = PBK_Text_Zip;
1586 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1587 break;
1588 case 20:
1589 if (Priv->ReturnType != Alcatel_string) {
1590 smprintf(s,"WARNING: Received unexpected type %02X for field 20, ignoring\n", Priv->ReturnType);
1591 entry->EntriesNum--;
1592 j++;
1593 break;
1595 entry->Entries[i - j].EntryType = PBK_Text_Country;
1596 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1597 break;
1598 case 21:
1599 if (Priv->ReturnType != Alcatel_string) {
1600 smprintf(s,"WARNING: Received unexpected type %02X for field 21, ignoring\n", Priv->ReturnType);
1601 entry->EntriesNum--;
1602 j++;
1603 break;
1605 entry->Entries[i - j].EntryType = PBK_Text_Custom1;
1606 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1607 break;
1608 case 22:
1609 if (Priv->ReturnType != Alcatel_string) {
1610 smprintf(s,"WARNING: Received unexpected type %02X for field 22, ignoring\n", Priv->ReturnType);
1611 entry->EntriesNum--;
1612 j++;
1613 break;
1615 entry->Entries[i - j].EntryType = PBK_Text_Custom2;
1616 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1617 break;
1618 case 23:
1619 if (Priv->ReturnType != Alcatel_string) {
1620 smprintf(s,"WARNING: Received unexpected type %02X for field 23, ignoring\n", Priv->ReturnType);
1621 entry->EntriesNum--;
1622 j++;
1623 break;
1625 entry->Entries[i - j].EntryType = PBK_Text_Custom3;
1626 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1627 break;
1628 case 24:
1629 if (Priv->ReturnType != Alcatel_string) {
1630 smprintf(s,"WARNING: Received unexpected type %02X for field 24, ignoring\n", Priv->ReturnType);
1631 entry->EntriesNum--;
1632 j++;
1633 break;
1635 entry->Entries[i - j].EntryType = PBK_Text_Custom4;
1636 CopyUnicodeString(entry->Entries[i - j].Text, Priv->ReturnString);
1637 break;
1638 case 25:
1639 if (Priv->ReturnType != Alcatel_int) {
1640 smprintf(s,"WARNING: Received unexpected type %02X for field 25, ignoring\n", Priv->ReturnType);
1641 entry->EntriesNum--;
1642 j++;
1643 break;
1645 if (Priv->ReturnInt != 0) {
1646 entry->Entries[i - j].EntryType = PBK_PictureID;
1647 entry->Entries[i - j].Number = Priv->ReturnInt;
1648 } else {
1649 entry->EntriesNum--;
1650 j++;
1652 break;
1653 default:
1654 entry->EntriesNum--;
1655 j++;
1656 smprintf(s,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv->CurrentFields[i], Priv->ReturnType);
1657 switch (Priv->ReturnType) {
1658 case Alcatel_date:
1659 smprintf(s, "%d.%d.%d", Priv->ReturnDateTime.Day, Priv->ReturnDateTime.Month, Priv->ReturnDateTime.Year);
1660 break;
1661 case Alcatel_time:
1662 smprintf(s, "%d:%d:%d", Priv->ReturnDateTime.Hour, Priv->ReturnDateTime.Minute, Priv->ReturnDateTime.Second);
1663 break;
1664 case Alcatel_string:
1665 case Alcatel_phone:
1666 smprintf(s, "\"%s\"",DecodeUnicodeString(Priv->ReturnString));
1667 break;
1668 case Alcatel_enum:
1669 case Alcatel_bool:
1670 case Alcatel_int:
1671 case Alcatel_byte:
1672 smprintf(s, "%d", Priv->ReturnInt);
1673 break;
1675 smprintf(s,"\n");
1678 return GE_NONE;
1679 } else {
1680 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
1681 return ATGEN_GetMemory(s, entry);
1685 static GSM_Error ALCATEL_GetNextMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry, bool start)
1687 GSM_Error error;
1688 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1690 if (entry->MemoryType == GMT_ME) {
1691 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= GE_NONE) return error;
1692 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
1693 if (Priv->ContactsItemsCount == 0) return GE_EMPTY;
1695 if (start) entry->Location = Priv->ContactsItems[0];
1696 else if ((error = ALCATEL_GetNextId(s, &(entry->Location))) != GE_NONE) return error;
1698 return ALCATEL_GetMemory(s, entry);
1699 } else {
1700 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
1701 return ATGEN_GetNextMemory(s, entry, start);
1705 static GSM_Error ALCATEL_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1707 GSM_Error error;
1708 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1709 int NamePosition = -1;
1710 bool NameSet = false;
1711 int i;
1714 if (entry->MemoryType == GMT_ME) {
1715 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= GE_NONE) return error;
1716 if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeContacts, 0))!= GE_NONE) return error;
1717 for (i = 0; i < entry->EntriesNum; i++) {
1718 switch (entry->Entries[i].EntryType) {
1719 case PBK_Number_General:
1720 if ((error = ALCATEL_CreateField(s, Alcatel_phone, 8, entry->Entries[i].Text)) != GE_NONE) return error;
1721 break;
1722 case PBK_Number_Mobile:
1723 if ((error = ALCATEL_CreateField(s, Alcatel_phone, 12, entry->Entries[i].Text)) != GE_NONE) return error;
1724 break;
1725 case PBK_Number_Work:
1726 if ((error = ALCATEL_CreateField(s, Alcatel_phone, 7, entry->Entries[i].Text)) != GE_NONE) return error;
1727 break;
1728 case PBK_Number_Fax:
1729 if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, entry->Entries[i].Text)) != GE_NONE) return error;
1730 break;
1731 case PBK_Number_Home:
1732 if ((error = ALCATEL_CreateField(s, Alcatel_phone, 13, entry->Entries[i].Text)) != GE_NONE) return error;
1733 break;
1734 case PBK_Number_Pager:
1735 if ((error = ALCATEL_CreateField(s, Alcatel_phone, 11, entry->Entries[i].Text)) != GE_NONE) return error;
1736 break;
1737 case PBK_Number_Other:
1738 if ((error = ALCATEL_CreateField(s, Alcatel_phone, 10, entry->Entries[i].Text)) != GE_NONE) return error;
1739 break;
1740 case PBK_Text_Note:
1741 if ((error = ALCATEL_CreateField(s, Alcatel_string, 4, entry->Entries[i].Text)) != GE_NONE) return error;
1742 break;
1743 case PBK_Text_Email:
1744 if ((error = ALCATEL_CreateField(s, Alcatel_string, 14, entry->Entries[i].Text)) != GE_NONE) return error;
1745 break;
1746 case PBK_Text_Email2:
1747 if ((error = ALCATEL_CreateField(s, Alcatel_string, 15, entry->Entries[i].Text)) != GE_NONE) return error;
1748 break;
1749 case PBK_Text_LastName:
1750 if ((error = ALCATEL_CreateField(s, Alcatel_string, 0, entry->Entries[i].Text)) != GE_NONE) return error;
1751 NameSet = true;
1752 break;
1753 case PBK_Text_FirstName:
1754 if ((error = ALCATEL_CreateField(s, Alcatel_string, 1, entry->Entries[i].Text)) != GE_NONE) return error;
1755 NameSet = true;
1756 break;
1757 case PBK_Text_Company:
1758 if ((error = ALCATEL_CreateField(s, Alcatel_string, 2, entry->Entries[i].Text)) != GE_NONE) return error;
1759 break;
1760 case PBK_Text_JobTitle:
1761 if ((error = ALCATEL_CreateField(s, Alcatel_string, 3, entry->Entries[i].Text)) != GE_NONE) return error;
1762 break;
1763 case PBK_Category:
1764 if ((error = ALCATEL_CreateField(s, Alcatel_byte, 5, &(entry->Entries[i].Number))) != GE_NONE) return error;
1765 break;
1766 case PBK_Private:
1767 if ((error = ALCATEL_CreateField(s, Alcatel_bool, 6, &(entry->Entries[i].Number))) != GE_NONE) return error;
1768 break;
1769 case PBK_Text_StreetAddress:
1770 if ((error = ALCATEL_CreateField(s, Alcatel_string, 16, entry->Entries[i].Text)) != GE_NONE) return error;
1771 break;
1772 case PBK_Text_City:
1773 if ((error = ALCATEL_CreateField(s, Alcatel_string, 17, entry->Entries[i].Text)) != GE_NONE) return error;
1774 break;
1775 case PBK_Text_State:
1776 if ((error = ALCATEL_CreateField(s, Alcatel_string, 18, entry->Entries[i].Text)) != GE_NONE) return error;
1777 break;
1778 case PBK_Text_Zip:
1779 if ((error = ALCATEL_CreateField(s, Alcatel_string, 19, entry->Entries[i].Text)) != GE_NONE) return error;
1780 break;
1781 case PBK_Text_Country:
1782 if ((error = ALCATEL_CreateField(s, Alcatel_string, 20, entry->Entries[i].Text)) != GE_NONE) return error;
1783 break;
1784 case PBK_Text_Custom1:
1785 if ((error = ALCATEL_CreateField(s, Alcatel_string, 21, entry->Entries[i].Text)) != GE_NONE) return error;
1786 break;
1787 case PBK_Text_Custom2:
1788 if ((error = ALCATEL_CreateField(s, Alcatel_string, 22, entry->Entries[i].Text)) != GE_NONE) return error;
1789 break;
1790 case PBK_Text_Custom3:
1791 if ((error = ALCATEL_CreateField(s, Alcatel_string, 23, entry->Entries[i].Text)) != GE_NONE) return error;
1792 break;
1793 case PBK_Text_Custom4:
1794 if ((error = ALCATEL_CreateField(s, Alcatel_string, 24, entry->Entries[i].Text)) != GE_NONE) return error;
1795 break;
1796 case PBK_PictureID:
1797 if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) {
1798 if ((error = ALCATEL_CreateField(s, Alcatel_int, 25, &(entry->Entries[i].Number))) != GE_NONE) return error;
1799 } else {
1800 smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType);
1802 break;
1804 case PBK_Text_Name: NamePosition = i; break;
1805 /* Following fields are not supported: */
1806 case PBK_Date:
1807 case PBK_Caller_Group:
1808 case PBK_RingtoneID:
1809 case PBK_Text_Postal:
1810 case PBK_Text_URL:
1811 smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType);
1812 break;
1815 if (NamePosition != -1) {
1816 if (NameSet) {
1817 smprintf(s,"WARNING: Ignoring name, not supported by phone\n");
1818 } else {
1819 if ((error = ALCATEL_CreateField(s, Alcatel_string, 1, entry->Entries[i].Text)) != GE_NONE) return error;
1822 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= GE_NONE) return error;
1823 entry->Location = Priv->CommitedRecord;
1824 /* Refresh list */
1825 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
1826 return GE_NONE;
1827 } else {
1828 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
1829 return ATGEN_AddMemory(s, entry);
1833 static GSM_Error ALCATEL_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1835 GSM_Error error;
1836 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
1837 int NamePosition = -1;
1838 bool NameSet = false;
1839 int i;
1840 bool UpdatedFields[26];
1842 if (entry->Location == 0) return GE_INVALIDLOCATION;
1844 if (entry->MemoryType == GMT_ME) {
1845 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= GE_NONE) return error;
1846 /* Save modified entry */
1847 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
1848 if ((error = ALCATEL_IsIdAvailable(s, entry->Location))!= GE_NONE) {
1849 /* Entry doesn't exist, we will create new one */
1850 return ALCATEL_AddMemory(s, entry);
1852 /* Get fields for current item */
1853 if ((error = ALCATEL_GetFields(s, entry->Location))!= GE_NONE) return error;
1855 for (i = 0; i < 26; i++) { UpdatedFields[i] = false; }
1857 if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeContacts, entry->Location))!= GE_NONE) return error;
1858 for (i = 0; i < entry->EntriesNum; i++) {
1859 switch (entry->Entries[i].EntryType) {
1860 case PBK_Number_General:
1861 UpdatedFields[8] = true;
1862 if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 8, entry->Entries[i].Text)) != GE_NONE) return error;
1863 break;
1864 case PBK_Number_Mobile:
1865 UpdatedFields[12] = true;
1866 if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 12, entry->Entries[i].Text)) != GE_NONE) return error;
1867 break;
1868 case PBK_Number_Work:
1869 UpdatedFields[7] = true;
1870 if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 7, entry->Entries[i].Text)) != GE_NONE) return error;
1871 break;
1872 case PBK_Number_Fax:
1873 UpdatedFields[9] = true;
1874 if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 9, entry->Entries[i].Text)) != GE_NONE) return error;
1875 break;
1876 case PBK_Number_Home:
1877 UpdatedFields[13] = true;
1878 if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 13, entry->Entries[i].Text)) != GE_NONE) return error;
1879 break;
1880 case PBK_Number_Pager:
1881 UpdatedFields[11] = true;
1882 if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 11, entry->Entries[i].Text)) != GE_NONE) return error;
1883 break;
1884 case PBK_Number_Other:
1885 UpdatedFields[10] = true;
1886 if ((error = ALCATEL_UpdateField(s, Alcatel_phone, entry->Location, 10, entry->Entries[i].Text)) != GE_NONE) return error;
1887 break;
1888 case PBK_Text_Note:
1889 UpdatedFields[4] = true;
1890 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 4, entry->Entries[i].Text)) != GE_NONE) return error;
1891 break;
1892 case PBK_Text_Email:
1893 UpdatedFields[14] = true;
1894 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 14, entry->Entries[i].Text)) != GE_NONE) return error;
1895 break;
1896 case PBK_Text_Email2:
1897 UpdatedFields[15] = true;
1898 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 15, entry->Entries[i].Text)) != GE_NONE) return error;
1899 break;
1900 case PBK_Text_LastName:
1901 UpdatedFields[0] = true;
1902 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 0, entry->Entries[i].Text)) != GE_NONE) return error; NameSet = true;
1903 break;
1904 case PBK_Text_FirstName:
1905 UpdatedFields[1] = true;
1906 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 1, entry->Entries[i].Text)) != GE_NONE) return error; NameSet = true;
1907 break;
1908 case PBK_Text_Company:
1909 UpdatedFields[2] = true;
1910 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 2, entry->Entries[i].Text)) != GE_NONE) return error;
1911 break;
1912 case PBK_Text_JobTitle:
1913 UpdatedFields[3] = true;
1914 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 3, entry->Entries[i].Text)) != GE_NONE) return error;
1915 break;
1916 case PBK_Category:
1917 UpdatedFields[5] = true;
1918 if ((error = ALCATEL_UpdateField(s, Alcatel_byte, entry->Location, 5, &(entry->Entries[i].Number))) != GE_NONE) return error;
1919 break;
1920 case PBK_Private:
1921 UpdatedFields[6] = true;
1922 if ((error = ALCATEL_UpdateField(s, Alcatel_bool, entry->Location, 6, &(entry->Entries[i].Number))) != GE_NONE) return error;
1923 break;
1924 case PBK_Text_StreetAddress:
1925 UpdatedFields[16] = true;
1926 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 16, entry->Entries[i].Text)) != GE_NONE) return error;
1927 break;
1928 case PBK_Text_City:
1929 UpdatedFields[17] = true;
1930 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 17, entry->Entries[i].Text)) != GE_NONE) return error;
1931 break;
1932 case PBK_Text_State:
1933 UpdatedFields[18] = true;
1934 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 18, entry->Entries[i].Text)) != GE_NONE) return error;
1935 break;
1936 case PBK_Text_Zip:
1937 UpdatedFields[19] = true;
1938 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 19, entry->Entries[i].Text)) != GE_NONE) return error;
1939 break;
1940 case PBK_Text_Country:
1941 UpdatedFields[20] = true;
1942 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 20, entry->Entries[i].Text)) != GE_NONE) return error;
1943 break;
1944 case PBK_Text_Custom1:
1945 UpdatedFields[21] = true;
1946 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 21, entry->Entries[i].Text)) != GE_NONE) return error;
1947 break;
1948 case PBK_Text_Custom2:
1949 UpdatedFields[22] = true;
1950 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 22, entry->Entries[i].Text)) != GE_NONE) return error;
1951 break;
1952 case PBK_Text_Custom3:
1953 UpdatedFields[23] = true;
1954 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 23, entry->Entries[i].Text)) != GE_NONE) return error;
1955 break;
1956 case PBK_Text_Custom4:
1957 UpdatedFields[24] = true;
1958 if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 24, entry->Entries[i].Text)) != GE_NONE) return error
1959 ; break;
1960 case PBK_PictureID:
1961 if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) {
1962 UpdatedFields[25] = true;
1963 if ((error = ALCATEL_UpdateField(s, Alcatel_int, entry->Location, 25, &(entry->Entries[i].Number))) != GE_NONE) return error;
1964 } else {
1965 smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType);
1967 break;
1969 case PBK_Text_Name: NamePosition = i; break;
1970 /* Following fields are not supported: */
1971 case PBK_Date:
1972 case PBK_Caller_Group:
1973 case PBK_RingtoneID:
1974 case PBK_Text_Postal:
1975 case PBK_Text_URL:
1976 smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", entry->Entries[i].EntryType);
1977 break;
1980 if (NamePosition != -1) {
1981 if (NameSet) {
1982 smprintf(s,"WARNING: Ignoring name, not supported by phone\n");
1983 } else {
1984 UpdatedFields[1] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_string, entry->Location, 1, entry->Entries[i].Text)) != GE_NONE) return error;
1987 /* If we didn't update some field, we have to delete it... */
1988 for (i=0; i<Priv->CurrentFieldsCount; i++) {
1989 if (!UpdatedFields[Priv->CurrentFields[i]]) if ((error = ALCATEL_DeleteField(s, entry->Location, Priv->CurrentFields[i])) != GE_NONE) return error;
1991 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= GE_NONE) return error;
1992 entry->Location = Priv->CommitedRecord;
1993 return GE_NONE;
1994 } else {
1995 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
1996 return ATGEN_SetMemory(s, entry);
2000 static GSM_Error ALCATEL_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
2002 GSM_Error error;
2004 if (entry->MemoryType == GMT_ME) {
2005 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= GE_NONE) return error;
2006 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
2007 if ((error = ALCATEL_IsIdAvailable(s, entry->Location))!= GE_NONE) {
2008 /* Entry was empty => no error */
2009 return GE_NONE;
2011 /* Do real delete */
2012 error = ALCATEL_DeleteItem(s, entry->Location);
2013 if (error != GE_NONE) return error;
2015 /* Refresh list */
2016 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= GE_NONE) return error;
2017 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
2019 return GE_NONE;
2020 } else {
2021 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2022 return ATGEN_DeleteMemory(s, entry);
2026 static GSM_Error ALCATEL_DeleteAllMemory(GSM_StateMachine *s, GSM_MemoryType type)
2028 GSM_Error error;
2029 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2030 int i;
2032 if (type == GMT_ME) {
2033 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= GE_NONE) return error;
2034 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
2036 for (i=0; i<Priv->ContactsItemsCount; i++) {
2037 error = ALCATEL_DeleteItem(s, Priv->ContactsItems[i]);
2038 if (error != GE_NONE) return error;
2041 /* Refresh list */
2042 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= GE_NONE) return error;
2043 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
2045 return GE_NONE;
2046 } else {
2047 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2048 return ATGEN_DeleteAllMemory(s, type);
2052 static GSM_Error ALCATEL_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
2054 GSM_Error error;
2056 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2057 return ATGEN_GetSMSC(s, smsc);
2061 static GSM_Error ALCATEL_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status)
2063 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2064 GSM_Error error;
2066 if (Status->MemoryType == GMT_ME) {
2067 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeContacts, 0))!= GE_NONE) return error;
2068 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
2069 Status->Used = Priv->ContactsItemsCount;
2070 Status->Free = ALCATEL_FREE_MEMORY;
2071 return GE_NONE;
2072 } else {
2073 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2074 return ATGEN_GetMemoryStatus(s, Status);
2078 static GSM_Error ALCATEL_GetSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms)
2080 GSM_Error error;
2082 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2083 return ATGEN_GetSMS(s, sms);
2086 static GSM_Error ALCATEL_DeleteSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2088 GSM_Error error;
2090 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2091 return ATGEN_DeleteSMS(s, sms);
2094 static GSM_Error ALCATEL_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2096 GSM_Error error;
2098 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2099 return ATGEN_AddSMS(s, sms);
2102 static GSM_Error ALCATEL_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat)
2104 GSM_Error error;
2106 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2107 return ATGEN_GetBatteryCharge(s, bat);
2110 static GSM_Error ALCATEL_GetSignalStrength(GSM_StateMachine *s, GSM_SignalQuality *sig)
2112 GSM_Error error;
2114 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2115 return ATGEN_GetSignalQuality(s, sig);
2118 static GSM_Error ALCATEL_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders)
2120 GSM_Error error;
2122 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2123 return ATGEN_GetSMSFolders(s, folders);
2126 static GSM_Error ALCATEL_GetNextSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start)
2128 GSM_Error error;
2130 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2131 return ATGEN_GetNextSMS(s, sms, start);
2134 static GSM_Error ALCATEL_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status)
2136 GSM_Error error;
2138 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2139 return ATGEN_GetSMSStatus(s, status);
2142 static GSM_Error ALCATEL_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber)
2144 GSM_Error error;
2146 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2147 return ATGEN_DialVoice(s, number, ShowNumber);
2150 static GSM_Error ALCATEL_AnswerCall(GSM_StateMachine *s, int ID, bool all)
2152 GSM_Error error;
2154 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2155 return ATGEN_AnswerCall(s,ID,all);
2158 static GSM_Error ALCATEL_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo)
2160 GSM_Error error;
2162 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2163 return ATGEN_GetNetworkInfo(s, netinfo);
2166 static GSM_Error ALCATEL_GetDisplayStatus(GSM_StateMachine *s, GSM_DisplayFeatures *features)
2168 GSM_Error error;
2170 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2171 return ATGEN_GetDisplayStatus(s, features);
2174 static GSM_Error ALCATEL_SetAutoNetworkLogin(GSM_StateMachine *s)
2176 GSM_Error error;
2178 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2179 return ATGEN_SetAutoNetworkLogin(s);
2182 static GSM_Error ALCATEL_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press)
2184 GSM_Error error;
2186 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2187 return ATGEN_PressKey(s, Key, Press);
2190 static GSM_Error ALCATEL_Reset(GSM_StateMachine *s, bool hard)
2192 GSM_Error error;
2194 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2195 return ATGEN_Reset(s, hard);
2198 static GSM_Error ALCATEL_CancelCall(GSM_StateMachine *s, int ID, bool all)
2200 GSM_Error error;
2202 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2203 return ATGEN_CancelCall(s,ID,all);
2206 static GSM_Error ALCATEL_SendSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2208 GSM_Error error;
2210 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2211 return ATGEN_SendSMS(s, sms);
2214 static GSM_Error ALCATEL_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
2216 GSM_Error error;
2218 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2219 return ATGEN_SetDateTime(s, date_time);
2222 static GSM_Error ALCATEL_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
2224 GSM_Error error;
2226 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2227 return ATGEN_SetSMSC(s, smsc);
2230 static GSM_Error ALCATEL_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode Code)
2232 GSM_Error error;
2234 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2235 return ATGEN_EnterSecurityCode(s, Code);
2238 static GSM_Error ALCATEL_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status)
2240 GSM_Error error;
2242 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2243 return ATGEN_GetSecurityStatus(s, Status);
2246 static GSM_Error ALCATEL_ResetPhoneSettings(GSM_StateMachine *s, GSM_ResetSettingsType Type)
2248 GSM_Error error;
2250 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2251 return ATGEN_ResetPhoneSettings(s, Type);
2254 static GSM_Error ALCATEL_SendDTMF(GSM_StateMachine *s, char *sequence)
2256 GSM_Error error;
2258 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2259 return ATGEN_SendDTMF(s, sequence);
2262 static GSM_Error ALCATEL_GetSIMIMSI(GSM_StateMachine *s, char *IMSI)
2264 GSM_Error error;
2266 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
2267 return ATGEN_GetSIMIMSI(s, IMSI);
2270 static GSM_Error ALCATEL_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *status)
2272 GSM_Error error;
2273 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2275 status->Used = 0;
2277 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
2278 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
2280 status->Used = Priv->CalendarItemsCount;
2281 return GE_NONE;
2284 static GSM_Error ALCATEL_GetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
2286 GSM_Error error;
2287 GSM_DateTime *dt = NULL;
2288 GSM_DateTime evdate;
2289 bool evdateused = true;
2290 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2291 int i;
2292 int j=0;
2294 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
2295 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
2296 if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= GE_NONE) {
2297 Note->EntriesNum = 0;
2298 return error;
2300 if ((error = ALCATEL_GetFields(s, Note->Location))!= GE_NONE) return error;
2302 Note->EntriesNum = Priv->CurrentFieldsCount;
2304 for (i=0; i < Priv->CurrentFieldsCount; i++) {
2305 if ((error = ALCATEL_GetFieldValue(s, Note->Location, Priv->CurrentFields[i]))!= GE_NONE) return error;
2306 switch (Priv->CurrentFields[i]) {
2307 case 0:
2308 if (Priv->ReturnType != Alcatel_date) {
2309 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2310 Note->EntriesNum--;
2311 j++;
2312 break;
2314 if (!CheckDate(&(Priv->ReturnDateTime))) {
2315 smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
2316 Note->EntriesNum--;
2317 j++;
2318 break;
2320 j++;
2321 Note->EntriesNum--;
2322 evdate = Priv->ReturnDateTime;
2323 evdateused = false;
2324 break;
2325 case 1:
2326 if (Priv->ReturnType != Alcatel_time) {
2327 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2328 Note->EntriesNum--;
2329 j++;
2330 break;
2332 if (!CheckTime(&(Priv->ReturnDateTime))) {
2333 smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
2334 Note->EntriesNum--;
2335 j++;
2336 break;
2338 Note->Entries[i-j].EntryType = CAL_START_DATETIME;
2339 Note->Entries[i-j].Date = Priv->ReturnDateTime;
2340 Note->Entries[i-j].Date.Day = evdate.Day;
2341 Note->Entries[i-j].Date.Month = evdate.Month;
2342 Note->Entries[i-j].Date.Year = evdate.Year;
2343 Note->Entries[i-j].Date.Timezone = evdate.Timezone;
2344 evdateused = true;
2345 break;
2346 case 2:
2347 if (Priv->ReturnType != Alcatel_time) {
2348 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2349 Note->EntriesNum--;
2350 j++;
2351 break;
2353 if (!CheckTime(&(Priv->ReturnDateTime))) {
2354 smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
2355 Note->EntriesNum--;
2356 j++;
2357 break;
2359 Note->Entries[i-j].EntryType = CAL_END_DATETIME;
2360 Note->Entries[i-j].Date = Priv->ReturnDateTime;
2361 Note->Entries[i-j].Date.Day = evdate.Day;
2362 Note->Entries[i-j].Date.Month = evdate.Month;
2363 Note->Entries[i-j].Date.Year = evdate.Year;
2364 Note->Entries[i-j].Date.Timezone = evdate.Timezone;
2365 evdateused = true;
2366 break;
2367 case 3:
2368 if (Priv->ReturnType != Alcatel_date) {
2369 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2370 Note->EntriesNum--;
2371 j++;
2372 break;
2374 if (!CheckDate(&(Priv->ReturnDateTime))) {
2375 smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
2376 Note->EntriesNum--;
2377 j++;
2378 break;
2380 if (dt == NULL) {
2381 Note->Entries[i-j].EntryType = CAL_ALARM_DATETIME;
2382 Note->Entries[i-j].Date = Priv->ReturnDateTime;
2383 dt = &(Note->Entries[i-j].Date);
2384 } else {
2385 j++;
2386 Note->EntriesNum--;
2387 dt->Day = Priv->ReturnDateTime.Day;
2388 dt->Month = Priv->ReturnDateTime.Month;
2389 dt->Year = Priv->ReturnDateTime.Year;
2390 dt->Timezone = Priv->ReturnDateTime.Timezone;
2391 dt = NULL;
2393 break;
2394 case 4:
2395 if (Priv->ReturnType != Alcatel_time) {
2396 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2397 Note->EntriesNum--;
2398 j++;
2399 break;
2401 if (!CheckTime(&(Priv->ReturnDateTime))) {
2402 smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
2403 Note->EntriesNum--;
2404 j++;
2405 break;
2407 if (dt == NULL) {
2408 Note->Entries[i-j].EntryType = CAL_ALARM_DATETIME;
2409 Note->Entries[i-j].Date = Priv->ReturnDateTime;
2410 dt = &(Note->Entries[i-j].Date);
2411 } else {
2412 j++;
2413 Note->EntriesNum--;
2414 dt->Hour = Priv->ReturnDateTime.Hour;
2415 dt->Minute = Priv->ReturnDateTime.Minute;
2416 dt->Second = Priv->ReturnDateTime.Second;
2417 dt = NULL;
2419 break;
2420 case 5:
2421 if (Priv->ReturnType != Alcatel_string) {
2422 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2423 Note->EntriesNum--;
2424 j++;
2425 break;
2427 Note->Entries[i-j].EntryType = CAL_TEXT;
2428 CopyUnicodeString(Note->Entries[i-j].Text, Priv->ReturnString);
2429 break;
2430 case 6:
2431 if (Priv->ReturnType != Alcatel_bool) {
2432 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2433 Note->EntriesNum--;
2434 j++;
2435 break;
2437 Note->Entries[i-j].EntryType = CAL_PRIVATE;
2438 Note->Entries[i-j].Number = Priv->ReturnInt;
2439 break;
2440 case 7:
2441 if (Priv->ReturnType != Alcatel_enum) {
2442 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2443 Note->EntriesNum--;
2444 j++;
2445 break;
2447 switch (Priv->ReturnInt) {
2448 case 0:
2449 Note->Type = GCN_MEETING;
2450 break;
2451 case 2:
2452 Note->Type = GCN_BIRTHDAY;
2453 break;
2454 case 3:
2455 Note->Type = GCN_CALL;
2456 break;
2457 case 4:
2458 Note->Type = GCN_ALARM;
2459 break;
2460 case 5:
2461 Note->Type = GCN_DAILY_ALARM;
2462 break;
2463 case 9:
2464 /* I'd call this repeating event, but it makes no sense creating one more type ... */
2465 Note->Type = GCN_MEETING;
2466 break;
2467 default:
2468 smprintf(s,"WARNING: Received unknown event type %02X!\n", Priv->ReturnInt);
2469 break;
2471 j++;
2472 Note->EntriesNum--;
2473 break;
2474 case 8:
2475 if (Priv->ReturnType != Alcatel_int) {
2476 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2477 Note->EntriesNum--;
2478 j++;
2479 break;
2481 /* 0xffffffff indicates that there is phone (BF5), 0 means none (BF5, BE5)*/
2482 if (Priv->ReturnInt == 0xffffffff || Priv->ReturnInt == 0) {
2483 j++;
2484 Note->EntriesNum--;
2485 } else {
2486 Note->Entries[i-j].EntryType = CAL_CONTACTID;
2487 Note->Entries[i-j].Number = Priv->ReturnInt;
2489 break;
2490 case 9:
2491 if (Priv->ReturnType != Alcatel_phone) {
2492 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2493 Note->EntriesNum--;
2494 j++;
2495 break;
2497 Note->Entries[i-j].EntryType = CAL_PHONE;
2498 CopyUnicodeString(Note->Entries[i-j].Text, Priv->ReturnString);
2499 break;
2500 case 10:
2501 if (Priv->ReturnType != Alcatel_byte) {
2502 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2503 Note->EntriesNum--;
2504 j++;
2505 break;
2507 Note->Entries[i-j].EntryType = CAL_REPEAT_DAYOFWEEK;
2508 Note->Entries[i-j].Number = Priv->ReturnInt;
2509 break;
2510 case 11:
2511 if (Priv->ReturnType != Alcatel_byte) {
2512 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2513 Note->EntriesNum--;
2514 j++;
2515 break;
2517 Note->Entries[i-j].EntryType = CAL_REPEAT_DAY;
2518 Note->Entries[i-j].Number = Priv->ReturnInt;
2519 break;
2520 case 12:
2521 if (Priv->ReturnType != Alcatel_byte) {
2522 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2523 Note->EntriesNum--;
2524 j++;
2525 break;
2527 Note->Entries[i-j].EntryType = CAL_REPEAT_WEEKOFMONTH;
2528 Note->Entries[i-j].Number = Priv->ReturnInt;
2529 break;
2530 case 13:
2531 if (Priv->ReturnType != Alcatel_byte) {
2532 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2533 Note->EntriesNum--;
2534 j++;
2535 break;
2537 Note->Entries[i-j].EntryType = CAL_REPEAT_MONTH;
2538 Note->Entries[i-j].Number = Priv->ReturnInt;
2539 break;
2540 case 17:
2541 if (Priv->ReturnType != Alcatel_byte) {
2542 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2543 Note->EntriesNum--;
2544 j++;
2545 break;
2547 /* In BF5 birthday has frequency = 1 */
2548 if (Note->Type == GCN_BIRTHDAY) {
2549 Note->EntriesNum--;
2550 j++;
2551 } else {
2552 Note->Entries[i-j].EntryType = CAL_REPEAT_FREQUENCY;
2553 Note->Entries[i-j].Number = Priv->ReturnInt;
2555 break;
2556 case 18:
2557 if (Priv->ReturnType != Alcatel_date) {
2558 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2559 Note->EntriesNum--;
2560 j++;
2561 break;
2563 if (!CheckDate(&(Priv->ReturnDateTime))) {
2564 smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
2565 Note->EntriesNum--;
2566 j++;
2567 break;
2569 Note->Entries[i-j].EntryType = CAL_REPEAT_STARTDATE;
2570 Note->Entries[i-j].Date = Priv->ReturnDateTime;
2571 break;
2572 case 19:
2573 if (Priv->ReturnType != Alcatel_date) {
2574 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2575 Note->EntriesNum--;
2576 j++;
2577 break;
2579 if (!CheckDate(&(Priv->ReturnDateTime))) {
2580 smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
2581 Note->EntriesNum--;
2582 j++;
2583 break;
2585 Note->Entries[i-j].EntryType = CAL_REPEAT_STOPDATE;
2586 Note->Entries[i-j].Date = Priv->ReturnDateTime;
2587 break;
2588 case 20:
2589 if (Priv->ReturnType != Alcatel_date) {
2590 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2591 Note->EntriesNum--;
2592 j++;
2593 break;
2595 if (!CheckDate(&(Priv->ReturnDateTime))) {
2596 smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
2597 Note->EntriesNum--;
2598 j++;
2599 break;
2601 /* This entry had always same value as the 3rd (alarm date) */
2602 j++;
2603 Note->EntriesNum--;
2604 break;
2605 case 21:
2606 if (Priv->ReturnType != Alcatel_time) {
2607 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
2608 Note->EntriesNum--;
2609 j++;
2610 break;
2612 if (!CheckTime(&(Priv->ReturnDateTime))) {
2613 smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
2614 Note->EntriesNum--;
2615 j++;
2616 break;
2618 /* This entry had always same value as the 4th (alarm time) */
2619 j++;
2620 Note->EntriesNum--;
2621 break;
2622 default:
2623 Note->EntriesNum--;
2624 j++;
2625 smprintf(s,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv->CurrentFields[i], Priv->ReturnType);
2626 switch (Priv->ReturnType) {
2627 case Alcatel_date:
2628 smprintf(s, "%d.%d.%d", Priv->ReturnDateTime.Day, Priv->ReturnDateTime.Month, Priv->ReturnDateTime.Year);
2629 break;
2630 case Alcatel_time:
2631 smprintf(s, "%d:%d:%d", Priv->ReturnDateTime.Hour, Priv->ReturnDateTime.Minute, Priv->ReturnDateTime.Second);
2632 break;
2633 case Alcatel_string:
2634 case Alcatel_phone:
2635 smprintf(s, "\"%s\"",DecodeUnicodeString(Priv->ReturnString));
2636 break;
2637 case Alcatel_enum:
2638 case Alcatel_bool:
2639 case Alcatel_int:
2640 case Alcatel_byte:
2641 smprintf(s, "%d", Priv->ReturnInt);
2642 break;
2644 smprintf(s,"\n");
2647 /* The event didn't have start/stop time -> we need only date */
2648 if (!evdateused) {
2649 Note->EntriesNum++;
2650 Note->Entries[i-j].EntryType = CAL_START_DATETIME;
2651 Note->Entries[i-j].Date = evdate;
2653 return GE_NONE;
2656 static GSM_Error ALCATEL_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start)
2658 GSM_Error error;
2659 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2661 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
2662 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
2663 if (Priv->CalendarItemsCount == 0) return GE_EMPTY;
2665 if (start) Note->Location = Priv->CalendarItems[0];
2666 else if ((error = ALCATEL_GetNextId(s, &(Note->Location))) != GE_NONE) return error;
2668 return ALCATEL_GetCalendar(s, Note);
2672 static GSM_Error ALCATEL_DeleteCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
2674 GSM_Error error;
2676 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
2677 /* Delete Calendar */
2678 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
2679 if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= GE_NONE) {
2680 /* Entry was empty => no error */
2681 return GE_NONE;
2683 error = ALCATEL_DeleteItem(s, Note->Location);
2684 if (error != GE_NONE) return error;
2685 /* Refresh list */
2686 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
2687 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
2688 return GE_NONE;
2692 static GSM_Error ALCATEL_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
2694 GSM_Error error;
2695 unsigned int val;
2696 bool contact_set = false;
2697 bool phone_set = false;
2698 bool date_set = false;
2699 bool repeating = false;
2700 int i;
2701 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2703 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
2704 if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeCalendar, 0))!= GE_NONE) return error;
2706 for (i = 0; i < Note->EntriesNum; i++) {
2707 switch (Note->Entries[i].EntryType) {
2708 case CAL_START_DATETIME:
2709 if (!date_set) {
2710 if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(Note->Entries[i].Date))) != GE_NONE) return error;
2711 date_set = true;
2713 if ((error = ALCATEL_CreateField(s, Alcatel_time, 1, &(Note->Entries[i].Date))) != GE_NONE) return error;
2714 break;
2715 case CAL_END_DATETIME:
2716 if (!date_set) {
2717 if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(Note->Entries[i].Date))) != GE_NONE) return error;
2718 date_set = true;
2720 if ((error = ALCATEL_CreateField(s, Alcatel_time, 2, &(Note->Entries[i].Date))) != GE_NONE) return error;
2721 break;
2722 case CAL_ALARM_DATETIME:
2723 if ((error = ALCATEL_CreateField(s, Alcatel_date, 3, &(Note->Entries[i].Date))) != GE_NONE) return error;
2724 if ((error = ALCATEL_CreateField(s, Alcatel_time, 4, &(Note->Entries[i].Date))) != GE_NONE) return error;
2725 if (Note->Type == GCN_ALARM || Note->Type == GCN_DAILY_ALARM) {
2726 if ((error = ALCATEL_CreateField(s, Alcatel_date, 20, &(Note->Entries[i].Date))) != GE_NONE) return error;
2727 if ((error = ALCATEL_CreateField(s, Alcatel_time, 21, &(Note->Entries[i].Date))) != GE_NONE) return error;
2729 break;
2730 case CAL_TEXT:
2731 if ((error = ALCATEL_CreateField(s, Alcatel_string, 5, Note->Entries[i].Text)) != GE_NONE) return error;
2732 break;
2733 case CAL_PRIVATE:
2734 if ((error = ALCATEL_CreateField(s, Alcatel_bool, 6, &(Note->Entries[i].Number))) != GE_NONE) return error;
2735 break;
2736 case CAL_CONTACTID:
2737 if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &(Note->Entries[i].Number))) != GE_NONE) return error;
2738 contact_set = true;
2739 break;
2740 case CAL_PHONE:
2741 if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, Note->Entries[i].Text)) != GE_NONE) return error;
2742 phone_set = true;
2743 break;
2744 case CAL_REPEAT_DAYOFWEEK:
2745 if ((error = ALCATEL_CreateField(s, Alcatel_byte, 10, &(Note->Entries[i].Number))) != GE_NONE) return error;
2746 repeating = true;
2747 break;
2748 case CAL_REPEAT_DAY:
2749 if ((error = ALCATEL_CreateField(s, Alcatel_byte, 11, &(Note->Entries[i].Number))) != GE_NONE) return error;
2750 repeating = true;
2751 break;
2752 case CAL_REPEAT_WEEKOFMONTH:
2753 if ((error = ALCATEL_CreateField(s, Alcatel_byte, 12, &(Note->Entries[i].Number))) != GE_NONE) return error;
2754 repeating = true;
2755 break;
2756 case CAL_REPEAT_MONTH:
2757 if ((error = ALCATEL_CreateField(s, Alcatel_byte, 13, &(Note->Entries[i].Number))) != GE_NONE) return error;
2758 repeating = true;
2759 break;
2760 case CAL_REPEAT_FREQUENCY:
2761 if ((error = ALCATEL_CreateField(s, Alcatel_byte, 17, &(Note->Entries[i].Number))) != GE_NONE) return error;
2762 repeating = true;
2763 break;
2764 case CAL_REPEAT_STARTDATE:
2765 if ((error = ALCATEL_CreateField(s, Alcatel_date, 18, &(Note->Entries[i].Date))) != GE_NONE) return error;
2766 repeating = true;
2767 break;
2768 case CAL_REPEAT_STOPDATE:
2769 if ((error = ALCATEL_CreateField(s, Alcatel_date, 19, &(Note->Entries[i].Date))) != GE_NONE) return error;
2770 repeating = true;
2771 break;
2772 case CAL_SILENT_ALARM_DATETIME:
2773 case CAL_RECURRANCE:
2774 case CAL_LOCATION:
2775 smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", Note->Entries[i].EntryType);
2776 break;
2780 switch (Note->Type) {
2781 case GCN_CALL:
2782 val = 3;
2783 break;
2784 case GCN_BIRTHDAY:
2785 val = 2;
2786 break;
2787 case GCN_ALARM:
2788 val = 4;
2789 break;
2790 case GCN_DAILY_ALARM:
2791 val = 5;
2792 break;
2793 default:
2794 if (repeating) {
2795 val = 9;
2796 } else {
2797 val = 0;
2800 if ((error = ALCATEL_CreateField(s, Alcatel_enum, 7, &val)) != GE_NONE) return error;
2802 if (!contact_set) {
2803 if (phone_set) {
2804 val = 0xffffffff;
2805 } else {
2806 val = 0;
2808 if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &val)) != GE_NONE) return error;
2810 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
2811 Note->Location = Priv->CommitedRecord;
2812 /* Refresh list */
2813 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
2814 return GE_NONE;
2817 static GSM_Error ALCATEL_SetCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
2819 GSM_Error error;
2820 unsigned int val;
2821 bool contact_set = false;
2822 bool phone_set = false;
2823 bool date_set = false;
2824 bool repeating = false;
2825 int i;
2826 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2827 bool UpdatedFields[22];
2829 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
2830 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
2831 if ((error = ALCATEL_IsIdAvailable(s, Note->Location))!= GE_NONE) {
2832 /* Entry doesn't exist, we will create new one */
2833 return ALCATEL_AddCalendar(s, Note);
2835 /* Get fields for current item */
2836 if ((error = ALCATEL_GetFields(s, Note->Location))!= GE_NONE) return error;
2838 for (i = 0; i < 22; i++) { UpdatedFields[i] = false; }
2840 if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeCalendar, Note->Location))!= GE_NONE) return error;
2842 for (i = 0; i < Note->EntriesNum; i++) {
2843 switch (Note->Entries[i].EntryType) {
2844 case CAL_START_DATETIME:
2845 if (!date_set) {
2846 UpdatedFields[0] = true;
2847 if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 0, &(Note->Entries[i].Date))) != GE_NONE) return error;
2848 date_set = true;
2850 UpdatedFields[1] = true;
2851 if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 1, &(Note->Entries[i].Date))) != GE_NONE) return error;
2852 break;
2853 case CAL_END_DATETIME:
2854 if (!date_set) {
2855 UpdatedFields[0] = true;
2856 if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 0, &(Note->Entries[i].Date))) != GE_NONE) return error;
2857 date_set = true;
2859 UpdatedFields[2] = true; if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 2, &(Note->Entries[i].Date))) != GE_NONE) return error;
2860 break;
2861 case CAL_ALARM_DATETIME:
2862 UpdatedFields[3] = true;
2863 if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 3, &(Note->Entries[i].Date))) != GE_NONE) return error;
2864 UpdatedFields[4] = true;
2865 if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 4, &(Note->Entries[i].Date))) != GE_NONE) return error;
2866 if (Note->Type == GCN_ALARM || Note->Type == GCN_DAILY_ALARM) {
2867 UpdatedFields[20] = true;
2868 if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 20, &(Note->Entries[i].Date))) != GE_NONE) return error;
2869 UpdatedFields[21] = true;
2870 if ((error = ALCATEL_UpdateField(s, Alcatel_time, Note->Location, 21, &(Note->Entries[i].Date))) != GE_NONE) return error;
2872 break;
2873 case CAL_TEXT:
2874 UpdatedFields[5] = true;
2875 if ((error = ALCATEL_UpdateField(s, Alcatel_string, Note->Location, 5, Note->Entries[i].Text)) != GE_NONE) return error;
2876 break;
2877 case CAL_PRIVATE:
2878 UpdatedFields[6] = true;
2879 if ((error = ALCATEL_UpdateField(s, Alcatel_bool, Note->Location, 6, &(Note->Entries[i].Number))) != GE_NONE) return error;
2880 break;
2881 case CAL_CONTACTID:
2882 UpdatedFields[8] = true;
2883 if ((error = ALCATEL_UpdateField(s, Alcatel_int, Note->Location, 8, &(Note->Entries[i].Number))) != GE_NONE) return error;
2884 contact_set = true;
2885 break;
2886 case CAL_PHONE:
2887 UpdatedFields[9] = true;
2888 if ((error = ALCATEL_UpdateField(s, Alcatel_phone, Note->Location, 9, Note->Entries[i].Text)) != GE_NONE) return error;
2889 phone_set = true;
2890 break;
2891 case CAL_REPEAT_DAYOFWEEK:
2892 UpdatedFields[10] = true;
2893 if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 10, &(Note->Entries[i].Number))) != GE_NONE) return error;
2894 repeating = true;
2895 break;
2896 case CAL_REPEAT_DAY:
2897 UpdatedFields[11] = true;
2898 if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 11, &(Note->Entries[i].Number))) != GE_NONE) return error;
2899 repeating = true;
2900 break;
2901 case CAL_REPEAT_WEEKOFMONTH:
2902 UpdatedFields[12] = true;
2903 if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 12, &(Note->Entries[i].Number))) != GE_NONE) return error;
2904 repeating = true;
2905 break;
2906 case CAL_REPEAT_MONTH:
2907 UpdatedFields[13] = true;
2908 if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 13, &(Note->Entries[i].Number))) != GE_NONE) return error;
2909 repeating = true;
2910 break;
2911 case CAL_REPEAT_FREQUENCY:
2912 UpdatedFields[17] = true;
2913 if ((error = ALCATEL_UpdateField(s, Alcatel_byte, Note->Location, 17, &(Note->Entries[i].Number))) != GE_NONE) return error;
2914 repeating = true;
2915 break;
2916 case CAL_REPEAT_STARTDATE:
2917 UpdatedFields[18] = true;
2918 if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 18, &(Note->Entries[i].Date))) != GE_NONE) return error;
2919 repeating = true;
2920 break;
2921 case CAL_REPEAT_STOPDATE:
2922 UpdatedFields[19] = true;
2923 if ((error = ALCATEL_UpdateField(s, Alcatel_date, Note->Location, 19, &(Note->Entries[i].Date))) != GE_NONE) return error;
2924 repeating = true;
2925 break;
2926 case CAL_SILENT_ALARM_DATETIME:
2927 case CAL_RECURRANCE:
2928 case CAL_LOCATION:
2929 smprintf(s,"WARNING: Ignoring entry %d, not supported by phone\n", Note->Entries[i].EntryType);
2930 break;
2934 switch (Note->Type) {
2935 case GCN_CALL:
2936 val = 3;
2937 break;
2938 case GCN_BIRTHDAY:
2939 val = 2;
2940 break;
2941 case GCN_ALARM:
2942 val = 4;
2943 break;
2944 case GCN_DAILY_ALARM:
2945 val = 5;
2946 break;
2947 default:
2948 if (repeating) {
2949 val = 9;
2950 } else {
2951 val = 0;
2954 UpdatedFields[7] = true;
2955 if ((error = ALCATEL_UpdateField(s, Alcatel_enum, Note->Location, 7, &val)) != GE_NONE) return error;
2957 if (!contact_set) {
2958 if (phone_set) {
2959 val = 0xffffffff;
2960 } else {
2961 val = 0;
2963 UpdatedFields[8] = true;
2964 if ((error = ALCATEL_UpdateField(s, Alcatel_int, Note->Location, 8, &val)) != GE_NONE) return error;
2966 /* If we didn't update some field, we have to delete it... */
2967 for (i=0; i<Priv->CurrentFieldsCount; i++) {
2968 if (!UpdatedFields[Priv->CurrentFields[i]]) if ((error = ALCATEL_DeleteField(s, Note->Location, Priv->CurrentFields[i])) != GE_NONE) return error;
2970 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
2971 return GE_NONE;
2974 static GSM_Error ALCATEL_DeleteAllCalendar (GSM_StateMachine *s)
2976 GSM_Error error;
2977 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
2978 int i;
2980 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
2981 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
2983 for (i=0; i<Priv->CalendarItemsCount; i++) {
2984 error = ALCATEL_DeleteItem(s, Priv->CalendarItems[i]);
2985 if (error != GE_NONE) return error;
2988 /* Refresh list */
2989 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
2990 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
2992 return GE_NONE;
2996 static GSM_Error ALCATEL_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm)
2998 GSM_Error error;
2999 GSM_CalendarEntry Note;
3000 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3001 int i;
3002 bool Found = false;
3003 bool DateSet = false;
3004 int alarm_number = alarm->Location;
3005 static GSM_DateTime nulldt = {0,0,0,0,0,0,0};
3007 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
3008 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
3010 for (i=0; i<Priv->CalendarItemsCount; i++) {
3011 if ((error = ALCATEL_GetFieldValue(s, Priv->CalendarItems[i], 7))!= GE_NONE) return error;
3012 if (Priv->ReturnType != Alcatel_enum) {
3013 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3014 continue;
3016 if (Priv->ReturnInt == 4 || Priv->ReturnInt == 5) {
3017 alarm_number--;
3018 if (alarm_number == 0) {
3019 Found = true;
3020 break;
3025 if (!Found) return GE_EMPTY;
3027 Note.Location = Priv->CalendarItems[i];
3029 if ((error = ALCATEL_GetCalendar(s, &Note))!= GE_NONE) return error;
3031 if (Note.Type == GCN_ALARM) {
3032 alarm->Repeating = false;
3033 } else {
3034 alarm->Repeating = true;
3037 alarm->Text[0] = 0; alarm->Text[1] = 0;
3040 for (i = 0; i < Note.EntriesNum; i++) {
3041 if (Note.Entries[i].EntryType == CAL_TEXT) {
3042 CopyUnicodeString(alarm->Text, Note.Entries[i].Text);
3043 } else if (Note.Entries[i].EntryType == CAL_ALARM_DATETIME) {
3044 alarm->DateTime = Note.Entries[i].Date;
3045 DateSet = false;
3048 if (!DateSet) {
3049 alarm->DateTime = nulldt;
3052 return GE_NONE;
3056 static GSM_Error ALCATEL_SetAlarm (GSM_StateMachine *s, GSM_Alarm *alarm)
3058 GSM_Error error;
3059 GSM_CalendarEntry Note;
3060 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3061 GSM_DateTime dt;
3062 int i;
3063 bool Found = false;
3064 int alarm_number = alarm->Location;
3066 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeCalendar, 0))!= GE_NONE) return error;
3067 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
3069 for (i=0; i<Priv->CalendarItemsCount; i++) {
3070 if ((error = ALCATEL_GetFieldValue(s, Priv->CalendarItems[i], 7))!= GE_NONE) return error;
3071 if (Priv->ReturnType != Alcatel_enum) {
3072 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3073 continue;
3075 if (Priv->ReturnInt == 4 || Priv->ReturnInt == 5) {
3076 alarm_number--;
3077 if (alarm_number == 0) {
3078 Found = true;
3079 break;
3084 if (Found) {
3085 Note.Location = Priv->CalendarItems[i];
3088 Note.EntriesNum = 1;
3090 Note.Entries[0].EntryType = CAL_ALARM_DATETIME;
3091 Note.Entries[0].Date = alarm->DateTime;
3093 if (alarm->Repeating) {
3094 Note.Type = GCN_DAILY_ALARM;
3095 GSM_GetCurrentDateTime(&dt);
3096 Note.Entries[0].Date.Day = dt.Day;
3097 Note.Entries[0].Date.Month = dt.Month;
3098 Note.Entries[0].Date.Year = dt.Year;
3099 } else {
3100 Note.Type = GCN_ALARM;
3103 if (alarm->Text[0] != 0 || alarm->Text[1] != 0) {
3104 Note.EntriesNum++;
3105 Note.Entries[1].EntryType = CAL_TEXT;
3106 CopyUnicodeString(Note.Entries[1].Text, alarm->Text);
3109 if (Found) {
3110 return ALCATEL_SetCalendar(s, &Note);
3111 } else {
3112 return ALCATEL_AddCalendar(s, &Note);
3117 static GSM_Error ALCATEL_GetToDoStatus(GSM_StateMachine *s, GSM_ToDoStatus *status)
3119 GSM_Error error;
3120 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3122 status->Used = 0;
3124 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= GE_NONE) return error;
3125 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
3127 status->Used = Priv->ToDoItemsCount;
3128 return GE_NONE;
3131 static GSM_Error ALCATEL_GetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
3133 GSM_Error error;
3134 GSM_DateTime *dt = NULL;
3135 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3136 int i;
3137 int j=0;
3139 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= GE_NONE) return error;
3140 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
3141 if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= GE_NONE) {
3142 ToDo->EntriesNum = 0;
3143 return error;
3145 if ((error = ALCATEL_GetFields(s, ToDo->Location))!= GE_NONE) return error;
3147 ToDo->EntriesNum = Priv->CurrentFieldsCount;
3149 for (i=0; i < Priv->CurrentFieldsCount; i++) {
3150 if ((error = ALCATEL_GetFieldValue(s, ToDo->Location, Priv->CurrentFields[i]))!= GE_NONE) return error;
3151 switch (Priv->CurrentFields[i]) {
3152 case 0:
3153 if (Priv->ReturnType != Alcatel_date) {
3154 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3155 ToDo->EntriesNum--;
3156 j++;
3157 break;
3159 if (!CheckDate(&(Priv->ReturnDateTime))) {
3160 smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
3161 ToDo->EntriesNum--;
3162 j++;
3163 break;
3165 ToDo->Entries[i-j].EntryType = TODO_END_DATETIME;
3166 ToDo->Entries[i-j].Date = Priv->ReturnDateTime;
3167 break;
3168 case 1:
3169 if (Priv->ReturnType != Alcatel_bool) {
3170 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3171 ToDo->EntriesNum--;
3172 j++;
3173 break;
3175 ToDo->Entries[i-j].EntryType = TODO_COMPLETED;
3176 ToDo->Entries[i-j].Number = Priv->ReturnInt;
3177 break;
3178 case 2:
3179 if (Priv->ReturnType != Alcatel_date) {
3180 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3181 ToDo->EntriesNum--;
3182 j++;
3183 break;
3185 if (!CheckDate(&(Priv->ReturnDateTime))) {
3186 smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
3187 ToDo->EntriesNum--;
3188 j++;
3189 break;
3191 if (dt == NULL) {
3192 ToDo->Entries[i-j].EntryType = TODO_ALARM_DATETIME;
3193 ToDo->Entries[i-j].Date = Priv->ReturnDateTime;
3194 dt = &(ToDo->Entries[i-j].Date);
3195 } else {
3196 j++;
3197 ToDo->EntriesNum--;
3198 dt->Day = Priv->ReturnDateTime.Day;
3199 dt->Month = Priv->ReturnDateTime.Month;
3200 dt->Year = Priv->ReturnDateTime.Year;
3201 dt->Timezone = Priv->ReturnDateTime.Timezone;
3202 dt = NULL;
3204 break;
3205 case 3:
3206 if (Priv->ReturnType != Alcatel_time) {
3207 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3208 ToDo->EntriesNum--;
3209 j++;
3210 break;
3212 if (!CheckTime(&(Priv->ReturnDateTime))) {
3213 smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
3214 ToDo->EntriesNum--;
3215 j++;
3216 break;
3218 if (dt == NULL) {
3219 ToDo->Entries[i-j].EntryType = TODO_ALARM_DATETIME;
3220 ToDo->Entries[i-j].Date = Priv->ReturnDateTime;
3221 dt = &(ToDo->Entries[i-j].Date);
3222 } else {
3223 j++;
3224 ToDo->EntriesNum--;
3225 dt->Hour = Priv->ReturnDateTime.Hour;
3226 dt->Minute = Priv->ReturnDateTime.Minute;
3227 dt->Second = Priv->ReturnDateTime.Second;
3228 dt = NULL;
3230 break;
3231 case 4:
3232 if (Priv->ReturnType != Alcatel_string) {
3233 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3234 ToDo->EntriesNum--;
3235 j++;
3236 break;
3238 ToDo->Entries[i-j].EntryType = TODO_TEXT;
3239 CopyUnicodeString(ToDo->Entries[i-j].Text, Priv->ReturnString);
3240 break;
3241 case 5:
3242 if (Priv->ReturnType != Alcatel_bool) {
3243 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3244 ToDo->EntriesNum--;
3245 j++;
3246 break;
3248 ToDo->Entries[i-j].EntryType = TODO_PRIVATE;
3249 ToDo->Entries[i-j].Number = Priv->ReturnInt;
3250 break;
3251 case 6:
3252 if (Priv->ReturnType != Alcatel_byte) {
3253 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3254 ToDo->EntriesNum--;
3255 j++;
3256 break;
3258 if (Priv->ReturnInt == 255) {
3259 /* 255 means no category */
3260 j++;
3261 ToDo->EntriesNum--;
3262 } else {
3263 ToDo->Entries[i-j].EntryType = TODO_CATEGORY;
3264 ToDo->Entries[i-j].Number = Priv->ReturnInt;
3266 break;
3267 case 7:
3268 /* This one seems to be byte for BF5 and enum for BE5 */
3269 if (Priv->ReturnType != Alcatel_enum && Priv->ReturnType != Alcatel_byte) {
3270 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3271 ToDo->EntriesNum--;
3272 j++;
3273 break;
3275 switch (Priv->ReturnInt) {
3276 case 0:
3277 ToDo->Priority = GSM_Priority_High;
3278 break;
3279 case 1:
3280 ToDo->Priority = GSM_Priority_Medium;
3281 break;
3282 case 2:
3283 ToDo->Priority = GSM_Priority_Low;
3284 break;
3285 default:
3286 ToDo->Priority = 0;
3287 smprintf(s,"WARNING: Received unexpected priority %02X, ignoring\n", Priv->ReturnInt);
3289 j++;
3290 ToDo->EntriesNum--;
3291 break;
3292 case 8:
3293 if (Priv->ReturnType != Alcatel_int) {
3294 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3295 ToDo->EntriesNum--;
3296 j++;
3297 break;
3299 /* 0xffffffff indicates that there is phone, 0 means none */
3300 if (Priv->ReturnInt == 0xffffffff || Priv->ReturnInt == 0) {
3301 j++;
3302 ToDo->EntriesNum--;
3303 } else {
3304 ToDo->Entries[i-j].EntryType = TODO_CONTACTID;
3305 ToDo->Entries[i-j].Number = Priv->ReturnInt;
3307 break;
3308 case 9:
3309 if (Priv->ReturnType != Alcatel_phone) {
3310 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3311 ToDo->EntriesNum--;
3312 j++;
3313 break;
3315 ToDo->Entries[i-j].EntryType = TODO_PHONE;
3316 CopyUnicodeString(ToDo->Entries[i-j].Text, Priv->ReturnString);
3317 break;
3318 case 10:
3319 if (Priv->ReturnType != Alcatel_date) {
3320 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3321 ToDo->EntriesNum--;
3322 j++;
3323 break;
3325 if (!CheckDate(&(Priv->ReturnDateTime))) {
3326 smprintf(s,"WARNING: Invalid date in phone, ignoring\n");
3327 ToDo->EntriesNum--;
3328 j++;
3329 break;
3331 /* This entry had always same value as the 2nd (alarm date) */
3332 j++;
3333 ToDo->EntriesNum--;
3334 break;
3335 case 11:
3336 if (Priv->ReturnType != Alcatel_time) {
3337 smprintf(s,"WARNING: Received unexpected type %02X, ignoring\n", Priv->ReturnType);
3338 ToDo->EntriesNum--;
3339 j++;
3340 break;
3342 if (!CheckTime(&(Priv->ReturnDateTime))) {
3343 smprintf(s,"WARNING: Invalid time in phone, ignoring\n");
3344 ToDo->EntriesNum--;
3345 j++;
3346 break;
3348 /* This entry had always same value as the 3rd (alarm time) */
3349 j++;
3350 ToDo->EntriesNum--;
3351 break;
3352 default:
3353 ToDo->EntriesNum--;
3354 j++;
3355 smprintf(s,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv->CurrentFields[i], Priv->ReturnType);
3356 switch (Priv->ReturnType) {
3357 case Alcatel_date:
3358 smprintf(s, "%d.%d.%d", Priv->ReturnDateTime.Day, Priv->ReturnDateTime.Month, Priv->ReturnDateTime.Year);
3359 break;
3360 case Alcatel_time:
3361 smprintf(s, "%d:%d:%d", Priv->ReturnDateTime.Hour, Priv->ReturnDateTime.Minute, Priv->ReturnDateTime.Second);
3362 break;
3363 case Alcatel_string:
3364 case Alcatel_phone:
3365 smprintf(s, "\"%s\"",DecodeUnicodeString(Priv->ReturnString));
3366 break;
3367 case Alcatel_enum:
3368 case Alcatel_bool:
3369 case Alcatel_int:
3370 case Alcatel_byte:
3371 smprintf(s, "%d", Priv->ReturnInt);
3372 break;
3374 smprintf(s,"\n");
3377 return GE_NONE;
3380 static GSM_Error ALCATEL_GetNextToDo(GSM_StateMachine *s, GSM_ToDoEntry *ToDo, bool start)
3382 GSM_Error error;
3383 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3385 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= GE_NONE) return error;
3386 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
3387 if (Priv->ToDoItemsCount == 0) return GE_EMPTY;
3389 if (start) ToDo->Location = Priv->ToDoItems[0];
3390 else if ((error = ALCATEL_GetNextId(s, &(ToDo->Location))) != GE_NONE) return error;
3392 return ALCATEL_GetToDo(s, ToDo);
3395 static GSM_Error ALCATEL_DeleteAllToDo (GSM_StateMachine *s)
3397 GSM_Error error;
3398 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3399 int i;
3401 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= GE_NONE) return error;
3402 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
3404 for (i=0; i<Priv->ToDoItemsCount; i++) {
3405 error = ALCATEL_DeleteItem(s, Priv->ToDoItems[i]);
3406 if (error != GE_NONE) return error;
3409 /* Refresh list */
3410 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= GE_NONE) return error;
3411 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
3413 return GE_NONE;
3416 static GSM_Error ALCATEL_AddToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
3418 GSM_Error error;
3419 unsigned int val;
3420 bool contact_set = false;
3421 bool phone_set = false;
3422 int i;
3423 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3425 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= GE_NONE) return error;
3426 if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeToDo, 0))!= GE_NONE) return error;
3428 switch (ToDo->Priority) {
3429 case GSM_Priority_High:
3430 val = 0;
3431 break;
3432 case GSM_Priority_Low:
3433 val = 2;
3434 break;
3435 case GSM_Priority_Medium:
3436 default:
3437 val = 1;
3438 break;
3440 /* This one seems to be byte for BF5 and enum for BE5 */
3441 if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) {
3442 if ((error = ALCATEL_CreateField(s, Alcatel_byte, 7, &val)) != GE_NONE) return error;
3443 } else {
3444 if ((error = ALCATEL_CreateField(s, Alcatel_enum, 7, &val)) != GE_NONE) return error;
3447 for (i = 0; i < ToDo->EntriesNum; i++) {
3448 switch (ToDo->Entries[i].EntryType) {
3449 case TODO_END_DATETIME:
3450 if ((error = ALCATEL_CreateField(s, Alcatel_date, 0, &(ToDo->Entries[i].Date))) != GE_NONE) return error;
3451 break;
3452 case TODO_COMPLETED:
3453 if ((error = ALCATEL_CreateField(s, Alcatel_bool, 1, &(ToDo->Entries[i].Number))) != GE_NONE) return error;
3454 break;
3455 case TODO_ALARM_DATETIME:
3456 if ((error = ALCATEL_CreateField(s, Alcatel_date, 2, &(ToDo->Entries[i].Date))) != GE_NONE) return error;
3457 if ((error = ALCATEL_CreateField(s, Alcatel_time, 3, &(ToDo->Entries[i].Date))) != GE_NONE) return error;
3458 if ((error = ALCATEL_CreateField(s, Alcatel_date, 10, &(ToDo->Entries[i].Date))) != GE_NONE) return error;
3459 if ((error = ALCATEL_CreateField(s, Alcatel_time, 11, &(ToDo->Entries[i].Date))) != GE_NONE) return error;
3460 break;
3461 case TODO_TEXT:
3462 if ((error = ALCATEL_CreateField(s, Alcatel_string, 4, ToDo->Entries[i].Text)) != GE_NONE) return error;
3463 break;
3464 case TODO_PRIVATE:
3465 if ((error = ALCATEL_CreateField(s, Alcatel_bool, 5, &(ToDo->Entries[i].Number))) != GE_NONE) return error;
3466 break;
3467 case TODO_CATEGORY:
3468 if ((error = ALCATEL_CreateField(s, Alcatel_byte, 6, &(ToDo->Entries[i].Number))) != GE_NONE) return error;
3469 break;
3470 case TODO_CONTACTID:
3471 if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &(ToDo->Entries[i].Number))) != GE_NONE) return error;
3472 contact_set = true;
3473 break;
3474 case TODO_PHONE:
3475 if ((error = ALCATEL_CreateField(s, Alcatel_phone, 9, ToDo->Entries[i].Text)) != GE_NONE) return error;
3476 phone_set = true;
3477 break;
3478 default:
3479 break;
3482 if (!contact_set) {
3483 if (phone_set) {
3484 val = 0xffffffff;
3485 } else {
3486 val = 0;
3488 if ((error = ALCATEL_CreateField(s, Alcatel_int, 8, &val)) != GE_NONE) return error;
3490 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= GE_NONE) return error;
3491 ToDo->Location = Priv->CommitedRecord;
3492 /* Refresh list */
3493 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
3494 return GE_NONE;
3497 static GSM_Error ALCATEL_SetToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
3499 GSM_Error error;
3500 unsigned int val;
3501 bool contact_set = false;
3502 bool phone_set = false;
3503 bool UpdatedFields[12];
3504 int i;
3505 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3507 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= GE_NONE) return error;
3508 /* Save modified ToDo */
3509 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
3510 if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= GE_NONE) {
3511 /* Entry doesn't exist, we will create new one */
3512 return ALCATEL_AddToDo(s, ToDo);
3514 /* Get fields for current item */
3515 if ((error = ALCATEL_GetFields(s, ToDo->Location))!= GE_NONE) return error;
3517 for (i = 0; i < 12; i++) { UpdatedFields[i] = false; }
3519 if ((error = ALCATEL_GoToBinaryState(s, StateEdit, TypeToDo, ToDo->Location))!= GE_NONE) return error;
3521 switch (ToDo->Priority) {
3522 case GSM_Priority_High:
3523 val = 0;
3524 break;
3525 case GSM_Priority_Low:
3526 val = 2;
3527 break;
3528 case GSM_Priority_Medium:
3529 default:
3530 val = 1;
3531 break;
3533 /* This one seems to be byte for BF5 and enum for BE5 */
3534 if (s->Phone.Data.Priv.ALCATEL.ProtocolVersion == V_1_1) {
3535 if ((error = ALCATEL_UpdateField(s, Alcatel_byte, ToDo->Location, 7, &val)) != GE_NONE) return error;
3536 } else {
3537 if ((error = ALCATEL_UpdateField(s, Alcatel_enum, ToDo->Location, 7, &val)) != GE_NONE) return error;
3539 UpdatedFields[7] = true;
3541 for (i = 0; i < ToDo->EntriesNum; i++) {
3542 switch (ToDo->Entries[i].EntryType) {
3543 case TODO_END_DATETIME:
3544 if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 0, &(ToDo->Entries[i].Date))) != GE_NONE) return error;
3545 UpdatedFields[0] = true;
3546 break;
3547 case TODO_COMPLETED:
3548 if ((error = ALCATEL_UpdateField(s, Alcatel_bool, ToDo->Location, 1, &(ToDo->Entries[i].Number))) != GE_NONE) return error;
3549 UpdatedFields[1] = true;
3550 break;
3551 case TODO_ALARM_DATETIME:
3552 if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 2, &(ToDo->Entries[i].Date))) != GE_NONE) return error;
3553 UpdatedFields[2] = true;
3554 if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 3, &(ToDo->Entries[i].Date))) != GE_NONE) return error;
3555 UpdatedFields[3] = true;
3556 if ((error = ALCATEL_UpdateField(s, Alcatel_date, ToDo->Location, 10, &(ToDo->Entries[i].Date))) != GE_NONE) return error;
3557 UpdatedFields[10] = true;
3558 if ((error = ALCATEL_UpdateField(s, Alcatel_time, ToDo->Location, 11, &(ToDo->Entries[i].Date))) != GE_NONE) return error;
3559 UpdatedFields[11] = true;
3560 break;
3561 case TODO_TEXT:
3562 if ((error = ALCATEL_UpdateField(s, Alcatel_string, ToDo->Location, 4, ToDo->Entries[i].Text)) != GE_NONE) return error;
3563 UpdatedFields[4] = true;
3564 break;
3565 case TODO_PRIVATE:
3566 if ((error = ALCATEL_UpdateField(s, Alcatel_bool, ToDo->Location, 5, &(ToDo->Entries[i].Number))) != GE_NONE) return error;
3567 UpdatedFields[5] = true;
3568 break;
3569 case TODO_CATEGORY:
3570 if ((error = ALCATEL_UpdateField(s, Alcatel_byte, ToDo->Location, 6, &(ToDo->Entries[i].Number))) != GE_NONE) return error;
3571 UpdatedFields[6] = true;
3572 break;
3573 case TODO_CONTACTID:
3574 if ((error = ALCATEL_UpdateField(s, Alcatel_int, ToDo->Location, 8, &(ToDo->Entries[i].Number))) != GE_NONE) return error;
3575 UpdatedFields[8] = true;
3576 contact_set = true;
3577 break;
3578 case TODO_PHONE:
3579 if ((error = ALCATEL_UpdateField(s, Alcatel_phone, ToDo->Location, 9, ToDo->Entries[i].Text)) != GE_NONE) return error;
3580 UpdatedFields[9] = true;
3581 phone_set = true;
3582 break;
3583 default:
3584 break;
3587 if (!contact_set) {
3588 if (phone_set) {
3589 val = 0xffffffff;
3590 } else {
3591 val = 0;
3593 if ((error = ALCATEL_UpdateField(s, Alcatel_int, ToDo->Location, 8, &val)) != GE_NONE) return error;
3594 UpdatedFields[8] = true;
3598 /* If we didn't update some field, we have to delete it... */
3599 for (i=0; i<Priv->CurrentFieldsCount; i++) {
3600 if (!UpdatedFields[Priv->CurrentFields[i]]) if ((error = ALCATEL_DeleteField(s, ToDo->Location, Priv->CurrentFields[i])) != GE_NONE) return error;
3602 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= GE_NONE) return error;
3603 return GE_NONE;
3606 static GSM_Error ALCATEL_DeleteToDo (GSM_StateMachine *s, GSM_ToDoEntry *ToDo)
3608 GSM_Error error;
3610 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= GE_NONE) return error;
3611 /* Delete ToDo */
3612 if ((error = ALCATEL_GetAvailableIds(s, false))!= GE_NONE) return error;
3613 if ((error = ALCATEL_IsIdAvailable(s, ToDo->Location))!= GE_NONE) {
3614 /* Entry was empty => no error */
3615 return GE_NONE;
3617 error = ALCATEL_DeleteItem(s, ToDo->Location);
3618 if (error != GE_NONE) return error;
3619 /* Refresh list */
3620 if ((error = ALCATEL_GoToBinaryState(s, StateSession, TypeToDo, 0))!= GE_NONE) return error;
3621 if ((error = ALCATEL_GetAvailableIds(s, true))!= GE_NONE) return error;
3622 return GE_NONE;
3625 static GSM_Error ALCATEL_GetCategoryStatus(GSM_StateMachine *s, GSM_CategoryStatus *Status)
3627 GSM_Alcatel_BinaryType type;
3628 GSM_Error error;
3629 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3631 switch (Status->Type) {
3632 case Category_ToDo: type = TypeToDo; break;
3633 case Category_Phonebook: type = TypeContacts; break;
3634 default: return GE_NOTSUPPORTED;
3636 if ((error = ALCATEL_GoToBinaryState(s, StateSession, type, 0))!= GE_NONE) return error;
3637 if ((error = ALCATEL_GetAvailableCategoryIds(s))!= GE_NONE) return error;
3639 Status->Used = Priv->CurrentCategoriesCount;
3641 return GE_NONE;
3644 static GSM_Error ALCATEL_GetCategory(GSM_StateMachine *s, GSM_Category *Category)
3646 GSM_Alcatel_BinaryType type;
3647 GSM_Error error;
3648 GSM_Phone_ALCATELData *Priv = &s->Phone.Data.Priv.ALCATEL;
3650 switch (Category->Type) {
3651 case Category_ToDo: type = TypeToDo; break;
3652 case Category_Phonebook: type = TypeContacts; break;
3653 default: return GE_NOTSUPPORTED;
3655 if ((error = ALCATEL_GoToBinaryState(s, StateSession, type, 0))!= GE_NONE) return error;
3656 if ((error = ALCATEL_GetAvailableCategoryIds(s))!= GE_NONE) return error;
3657 if ((error = ALCATEL_IsCategoryIdAvailable(s, Category->Location))!= GE_NONE) return error;
3658 if ((error = ALCATEL_GetCategoryText(s, Category->Location))!= GE_NONE) return error;
3660 CopyUnicodeString(Category->Name, Priv->ReturnString);
3662 return GE_NONE;
3665 static GSM_Error ALCATEL_GetProductCode(GSM_StateMachine *s, char *value)
3667 strcpy(value, s->Phone.Data.ModelInfo->model);
3668 return GE_NONE;
3671 static GSM_Error ALCATEL_DispatchMessage(GSM_StateMachine *s)
3673 if (s->Phone.Data.Priv.ALCATEL.Mode == ModeBinary) {
3674 return GSM_DispatchMessage(s);
3675 } else {
3676 return ATGEN_DispatchMessage(s);
3680 static GSM_Error ALCATEL_ReplyGeneric(GSM_Protocol_Message msg, GSM_StateMachine *s)
3682 /* All error values are just VERY wild guesses, but these seems to work
3683 * almost as expected ...
3685 switch (msg.Buffer[8]) {
3686 case 0x00: /* no error */
3687 return GE_NONE;
3688 case 0x10: /* same thing opened in phone menus */
3689 return GE_INSIDEPHONEMENU;
3690 case 0x13:
3691 /* This appears in more cases:
3692 * - phone needs PIN code
3693 * - we want to close not opened session
3694 * For normal users the second case shouldn't occur...
3696 return GE_SECURITYERROR;
3697 case 0x14: /* Bad data */
3698 case 0x2f: /* Closing session when not opened */
3699 case 0x1f: /* Bad in/out counter in packet/ack */
3700 case 0x0e: /* Openning session when not closed */
3701 case 0x0C: /* Bad id (item/database) */
3702 case 0x11: /* Bad list id */
3703 case 0x2A: /* Nonexistant field/item id */
3704 case 0x35: /* Too long text */
3705 return GE_BUG;
3706 case 0x23: /* Session opened */
3707 case 0x80: /* Transfer started */
3708 return GE_NONE;
3709 case 0x82: /* Transfer canceled */
3710 return GE_CANCELED;
3711 default:
3712 smprintf(s, "WARNING: Packet seems to indicate some status by %02X, ignoring!\n", msg.Buffer[8]);
3713 return GE_NONE;
3717 static GSM_Error ALCATEL_ReplyCommit(GSM_Protocol_Message msg, GSM_StateMachine *s)
3719 s->Phone.Data.Priv.ALCATEL.CommitedRecord = msg.Buffer[12] + (msg.Buffer[11] << 8) + (msg.Buffer[10] << 16) + (msg.Buffer[9] << 24);
3720 smprintf(s, "Created record %08x\n", s->Phone.Data.Priv.ALCATEL.CommitedRecord);
3721 return GE_NONE;
3724 static GSM_Error ALCATEL_SetIncomingCB (GSM_StateMachine *s, bool enable)
3726 GSM_Error error;
3728 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
3729 return ATGEN_SetIncomingCB(s, enable);
3732 static GSM_Error ALCATEL_SetIncomingSMS (GSM_StateMachine *s, bool enable)
3734 GSM_Error error;
3736 if ((error = ALCATEL_SetATMode(s))!= GE_NONE) return error;
3737 return ATGEN_SetIncomingSMS(s, enable);
3740 static GSM_Reply_Function ALCATELReplyFunctions[] = {
3741 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelAttach },
3742 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDetach },
3743 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelCommit },
3744 {ALCATEL_ReplyCommit, "\x02",0x00,0x00, ID_AlcatelCommit2 },
3745 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelEnd },
3746 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelClose },
3747 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelStart },
3748 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect1 },
3749 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect2 },
3750 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelSelect3 },
3751 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelBegin1 },
3752 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelBegin2 },
3753 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetIds1 },
3754 {ALCATEL_ReplyGetIds, "\x02",0x00,0x00, ID_AlcatelGetIds2 },
3755 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetCategories1 },
3756 {ALCATEL_ReplyGetCategories, "\x02",0x00,0x00, ID_AlcatelGetCategories2 },
3757 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetCategoryText1 },
3758 {ALCATEL_ReplyGetCategoryText, "\x02",0x00,0x00, ID_AlcatelGetCategoryText2 },
3759 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetFields1 },
3760 {ALCATEL_ReplyGetFields, "\x02",0x00,0x00, ID_AlcatelGetFields2 },
3761 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelGetFieldValue1 },
3762 {ALCATEL_ReplyGetFieldValue, "\x02",0x00,0x00, ID_AlcatelGetFieldValue2 },
3763 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDeleteField },
3764 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelDeleteItem1 },
3765 {ALCATEL_ReplyDeleteItem, "\x02",0x00,0x00, ID_AlcatelDeleteItem2 },
3766 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelCreateField },
3767 {ALCATEL_ReplyGeneric, "\x02",0x00,0x00, ID_AlcatelUpdateField },
3768 {NULL, "\x00",0x00,0x00, ID_None }
3771 GSM_Phone_Functions ALCATELPhone = {
3772 /* AFAIK, any 50[0123] phone should work, but I'm not sure whether all
3773 * they were ever really released, if yes add them here also.
3775 "alcatel|OT501|OT701|OT715|OT535|OT735|BE5|BF5|BH4",
3776 ALCATELReplyFunctions,
3777 ALCATEL_Initialise,
3778 ALCATEL_Terminate,
3779 ALCATEL_DispatchMessage,
3780 NOTSUPPORTED, /* ShowStartInfo */
3781 ALCATEL_GetManufacturer,
3782 ALCATEL_GetModel,
3783 ALCATEL_GetFirmware,
3784 ALCATEL_GetIMEI,
3785 NOTSUPPORTED, /* GetOriginalIMEI */
3786 NOTSUPPORTED, /* GetManufactureMonth */
3787 ALCATEL_GetProductCode,
3788 NOTSUPPORTED, /* GetHardware */
3789 NOTSUPPORTED, /* GetPPM */
3790 ALCATEL_GetSIMIMSI,
3791 ALCATEL_GetDateTime,
3792 ALCATEL_SetDateTime,
3793 ALCATEL_GetAlarm,
3794 ALCATEL_SetAlarm,
3795 NOTSUPPORTED, /* GetLocale */
3796 NOTSUPPORTED, /* SetLocale */
3797 ALCATEL_PressKey,
3798 ALCATEL_Reset,
3799 ALCATEL_ResetPhoneSettings,
3800 ALCATEL_EnterSecurityCode,
3801 ALCATEL_GetSecurityStatus,
3802 ALCATEL_GetDisplayStatus,
3803 ALCATEL_SetAutoNetworkLogin,
3804 ALCATEL_GetBatteryCharge,
3805 ALCATEL_GetSignalStrength,
3806 ALCATEL_GetNetworkInfo,
3807 ALCATEL_GetCategory,
3808 ALCATEL_GetCategoryStatus,
3809 ALCATEL_GetMemoryStatus,
3810 ALCATEL_GetMemory,
3811 ALCATEL_GetNextMemory,
3812 ALCATEL_SetMemory,
3813 ALCATEL_AddMemory,
3814 ALCATEL_DeleteMemory,
3815 ALCATEL_DeleteAllMemory,
3816 NOTSUPPORTED, /* GetSpeedDial */
3817 NOTSUPPORTED, /* SetSpeedDial */
3818 ALCATEL_GetSMSC,
3819 ALCATEL_SetSMSC,
3820 ALCATEL_GetSMSStatus,
3821 ALCATEL_GetSMS,
3822 ALCATEL_GetNextSMS,
3823 NOTSUPPORTED, /* SetSMS */
3824 ALCATEL_AddSMS,
3825 ALCATEL_DeleteSMS,
3826 ALCATEL_SendSMS,
3827 ALCATEL_SetIncomingSMS,
3828 ALCATEL_SetIncomingCB,
3829 ALCATEL_GetSMSFolders,
3830 NOTSUPPORTED, /* AddSMSFolder */
3831 NOTSUPPORTED, /* DeleteSMSFolder */
3832 ALCATEL_DialVoice,
3833 ALCATEL_AnswerCall,
3834 ALCATEL_CancelCall,
3835 NOTSUPPORTED, /* HoldCall */
3836 NOTSUPPORTED, /* UnholdCall */
3837 NOTSUPPORTED, /* ConferenceCall */
3838 NOTSUPPORTED, /* SplitCall */
3839 NOTSUPPORTED, /* TransferCall */
3840 NOTSUPPORTED, /* SwitchCall */
3841 NOTSUPPORTED, /* GetCallDivert */
3842 NOTSUPPORTED, /* SetCallDivert */
3843 NOTSUPPORTED, /* CancelAllDiverts */
3844 NONEFUNCTION, /* SetIncomingCall */
3845 NOTSUPPORTED, /* SetIncomingUSSD */
3846 ALCATEL_SendDTMF,
3847 NOTSUPPORTED, /* GetRingtone */
3848 NOTSUPPORTED, /* SetRingtone */
3849 NOTSUPPORTED, /* GetRingtonesInfo */
3850 NOTSUPPORTED, /* DeleteUserRingtones */
3851 NOTSUPPORTED, /* PlayTone */
3852 NOTSUPPORTED, /* GetWAPBookmark */
3853 NOTSUPPORTED, /* SetWAPBookmark */
3854 NOTSUPPORTED, /* DeleteWAPBookmark */
3855 NOTSUPPORTED, /* GetWAPSettings */
3856 NOTSUPPORTED, /* SetWAPSettings */
3857 NOTSUPPORTED, /* GetMMSSettings */
3858 NOTSUPPORTED, /* SetMMSSettings */
3859 NOTSUPPORTED, /* GetBitmap */
3860 NOTSUPPORTED, /* SetBitmap */
3861 ALCATEL_GetToDoStatus,
3862 ALCATEL_GetToDo,
3863 ALCATEL_GetNextToDo,
3864 ALCATEL_SetToDo,
3865 ALCATEL_AddToDo,
3866 ALCATEL_DeleteToDo,
3867 ALCATEL_DeleteAllToDo,
3868 ALCATEL_GetCalendarStatus,
3869 ALCATEL_GetCalendar,
3870 ALCATEL_GetNextCalendar,
3871 ALCATEL_SetCalendar,
3872 ALCATEL_AddCalendar,
3873 ALCATEL_DeleteCalendar,
3874 ALCATEL_DeleteAllCalendar,
3875 NOTSUPPORTED, /* GetCalendarSettings */
3876 NOTSUPPORTED, /* SetCalendarSettings */
3877 NOTSUPPORTED, /* GetNote */
3878 NOTSUPPORTED, /* GetProfile */
3879 NOTSUPPORTED, /* SetProfile */
3880 NOTSUPPORTED, /* GetFMStation */
3881 NOTSUPPORTED, /* SetFMStation */
3882 NOTSUPPORTED, /* ClearFMStations */
3883 NOTSUPPORTED, /* GetNextFileFolder */
3884 NOTSUPPORTED, /* GetFilePart */
3885 NOTSUPPORTED, /* AddFilePart */
3886 NOTSUPPORTED, /* GetFileSystemStatus */
3887 NOTSUPPORTED, /* DeleteFile */
3888 NOTSUPPORTED, /* AddFolder */
3889 NOTSUPPORTED, /* GetGPRSAccessPoint */
3890 NOTSUPPORTED /* SetGPRSAccessPoint */
3893 #endif
3894 #endif
3896 /* How should editor hadle tabs in this file? Add editor commands here.
3897 * vim: noexpandtab sw=8 ts=8 sts=8: