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