2 * High level functions for communication with Alcatel One Touch 501 and
3 * compatible mobile phone.
5 * This code implements functions to communicate with Alcatel phones,
6 * currently seem to work:
7 * - BE5 series (501/701)
9 * - BH4 series (535/735)
10 * For some functions it uses normal AT mode (not implemented here, look at
11 * ../at/atgen.[ch]) for others it switches into binary mode and initialises
12 * underlaying protocol (see ../../protocol/alcatel/alcabus.[ch]) and
13 * communicates over it. Don't ask me why Alcatel uses such silly thing...
15 * Notes for future features:
16 * - max phone number length is 61 (BE5)
17 * - max name length is 50 (BE5)
20 #include "../../gsmstate.h"
22 #ifdef GSM_ENABLE_ALCATEL
23 #ifdef GSM_ENABLE_ATGEN
28 #include "../../gsmcomon.h"
29 #include "../../misc/coding/coding.h"
30 #include "../../misc/misc.h"
31 #include "../../service/sms/gsmsms.h"
35 /* Timeout for GSM_WaitFor calls. */
36 #define ALCATEL_TIMEOUT 64
38 /* Some magic numbers for protocol follow */
40 /* synchronisation types (for everything except begin transfer): */
41 #define ALCATEL_SYNC_TYPE_CALENDAR 0x64
42 #define ALCATEL_SYNC_TYPE_TODO 0x68
43 #define ALCATEL_SYNC_TYPE_CONTACTS 0x6C
45 /* synchronisation types (for begin transfer): */
46 #define ALCATEL_BEGIN_SYNC_CALENDAR 0x00
47 #define ALCATEL_BEGIN_SYNC_TODO 0x02
48 #define ALCATEL_BEGIN_SYNC_CONTACTS 0x01
51 #define ALCATEL_LIST_TODO_CAT 0x9B
52 #define ALCATEL_LIST_CONTACTS_CAT 0x96
55 /* We need lot of ATGEN functions, because Alcatel is an AT device. */
57 extern GSM_Reply_Function ALCATELReplyFunctions
[];
58 extern GSM_Reply_Function ATGENReplyFunctions
[];
60 extern GSM_Error
ATGEN_Initialise (GSM_StateMachine
*s
);
61 extern GSM_Error
ATGEN_Terminate (GSM_StateMachine
*s
);
62 extern GSM_Error
ATGEN_GetIMEI (GSM_StateMachine
*s
);
63 extern GSM_Error
ATGEN_GetFirmware (GSM_StateMachine
*s
);
64 extern GSM_Error
ATGEN_GetModel (GSM_StateMachine
*s
);
65 extern GSM_Error
ATGEN_GetDateTime (GSM_StateMachine
*s
, GSM_DateTime
*date_time
);
66 extern GSM_Error
ATGEN_GetMemory (GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
);
67 extern GSM_Error
ATGEN_GetNextMemory (GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
, bool start
);
68 extern GSM_Error
ATGEN_SetMemory (GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
);
69 extern GSM_Error
ATGEN_AddMemory (GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
);
70 extern GSM_Error
ATGEN_DeleteMemory (GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
);
71 extern GSM_Error
ATGEN_GetMemoryStatus (GSM_StateMachine
*s
, GSM_MemoryStatus
*Status
);
72 extern GSM_Error
ATGEN_GetSMSC (GSM_StateMachine
*s
, GSM_SMSC
*smsc
);
73 extern GSM_Error
ATGEN_SetSMSC (GSM_StateMachine
*s
, GSM_SMSC
*smsc
);
74 extern GSM_Error
ATGEN_GetSMSFolders (GSM_StateMachine
*s
, GSM_SMSFolders
*folders
);
75 extern GSM_Error
ATGEN_GetSMSStatus (GSM_StateMachine
*s
, GSM_SMSMemoryStatus
*status
);
76 extern GSM_Error
ATGEN_GetSMS (GSM_StateMachine
*s
, GSM_MultiSMSMessage
*sms
);
77 extern GSM_Error
ATGEN_GetNextSMS (GSM_StateMachine
*s
, GSM_MultiSMSMessage
*sms
, bool start
);
78 extern GSM_Error
ATGEN_SendSMS (GSM_StateMachine
*s
, GSM_SMSMessage
*sms
);
79 extern GSM_Error
ATGEN_DeleteSMS (GSM_StateMachine
*s
, GSM_SMSMessage
*sms
);
80 extern GSM_Error
ATGEN_AddSMS (GSM_StateMachine
*s
, GSM_SMSMessage
*sms
);
81 extern GSM_Error
ATGEN_GetBatteryCharge (GSM_StateMachine
*s
, GSM_BatteryCharge
*bat
);
82 extern GSM_Error
ATGEN_GetSignalQuality (GSM_StateMachine
*s
, GSM_SignalQuality
*sig
);
83 extern GSM_Error
ATGEN_DialVoice (GSM_StateMachine
*s
, char *number
, GSM_CallShowNumber ShowNumber
);
84 extern GSM_Error
ATGEN_AnswerCall (GSM_StateMachine
*s
, int ID
, bool all
);
85 extern GSM_Error
ATGEN_CancelCall (GSM_StateMachine
*s
, int ID
, bool all
);
86 extern GSM_Error
ATGEN_SetDateTime (GSM_StateMachine
*s
, GSM_DateTime
*date_time
);
87 extern GSM_Error
ATGEN_EnterSecurityCode (GSM_StateMachine
*s
, GSM_SecurityCode Code
);
88 extern GSM_Error
ATGEN_GetSecurityStatus (GSM_StateMachine
*s
, GSM_SecurityCodeType
*Status
);
89 extern GSM_Error
ATGEN_ResetPhoneSettings (GSM_StateMachine
*s
, GSM_ResetSettingsType Type
);
90 extern GSM_Error
ATGEN_SendDTMF (GSM_StateMachine
*s
, char *sequence
);
91 extern GSM_Error
ATGEN_GetSIMIMSI (GSM_StateMachine
*s
, char *IMSI
);
92 extern GSM_Error
ATGEN_HandleCMSError (GSM_StateMachine
*s
);
93 extern GSM_Error
ATGEN_GetNetworkInfo (GSM_StateMachine
*s
, GSM_NetworkInfo
*netinfo
);
94 extern GSM_Error
ATGEN_Reset (GSM_StateMachine
*s
, bool hard
);
95 extern GSM_Error
ATGEN_PressKey (GSM_StateMachine
*s
, GSM_KeyCode Key
, bool Press
);
96 extern GSM_Error
ATGEN_GetDisplayStatus (GSM_StateMachine
*s
, GSM_DisplayFeatures
*features
);
97 extern GSM_Error
ATGEN_SetAutoNetworkLogin (GSM_StateMachine
*s
);
98 extern GSM_Error
ATGEN_DeleteAllMemory (GSM_StateMachine
*s
, GSM_MemoryType type
);
100 extern GSM_Error
ATGEN_DispatchMessage (GSM_StateMachine
*s
);
101 extern GSM_Error
ATGEN_SetIncomingCB (GSM_StateMachine
*s
, bool enable
);
102 extern GSM_Error
ATGEN_SetIncomingSMS (GSM_StateMachine
*s
, bool enable
);
105 * Alcatel uses some 8-bit characters in contacts, calendar etc.. This table
106 * attempts to decode it, it is probably not complete, here are just chars
109 unsigned char GSM_AlcatelAlphabet
[] =
111 /* in phone unicode description */
112 0x80, 0x00,0x20, /* empty */
113 0x81, 0x00,0x20, /* empty */
114 0x82, 0x00,0x20, /* empty */
115 0x83, 0x00,0x20, /* empty */
117 0x84, 0x00,0xe7, /* c cedilla */
118 0x85, 0x20,0x26, /* ... */
119 0x86, 0x03,0xc0, /* pi */
120 0x87, 0x01,0x3e, /* l caron */
121 0x88, 0x00,0xc0, /* A grave */
122 0x89, 0x00,0xc1, /* A acute */
123 0x8a, 0x00,0xc2, /* A circumflex */
124 0x8b, 0x00,0xc3, /* A tilde */
125 0x8c, 0x00,0xc8, /* E grave */
126 0x8d, 0x00,0xca, /* E circumflex */
127 0x8e, 0x00,0xcb, /* E diaresis */
128 0x8f, 0x00,0xcc, /* I grave */
129 0x90, 0x00,0xcd, /* I acute */
130 0x91, 0x00,0xd0, /* ETH */
131 0x92, 0x00,0xd2, /* O grave */
132 0x93, 0x00,0xd3, /* O acute */
133 0x94, 0x00,0xd4, /* O circumflex */
134 0x95, 0x00,0xd5, /* O tilde */
135 0x96, 0x00,0xd9, /* U grave */
136 0x97, 0x00,0xda, /* U acute */
137 0x98, 0x00,0xe1, /* a acute */
138 0x99, 0x00,0xe2, /* a circumflex */
139 0x9a, 0x00,0xe3, /* a tilde */
140 0x9b, 0x00,0xea, /* e circumflex */
141 0x9c, 0x00,0xeb, /* e diaresis */
142 0x9d, 0x00,0xed, /* i acute */
143 0x9e, 0x00,0xee, /* i circumflex */
144 0x9f, 0x00,0xef, /* i diaresis */
145 0xa0, 0x00,0xf3, /* o acute */
146 0xa1, 0x00,0xf4, /* o circumflex */
147 0xa2, 0x00,0xf5, /* o tilde */
148 0xa3, 0x00,0xfa, /* u acute */
149 0xa4, 0x00,0xa2, /* cent */
150 0xa5, 0x00,0x5b, /* [ */
151 0xa6, 0x01,0x59, /* r caron */
152 0xa7, 0x01,0x0d, /* c caron */
153 0xa8, 0x01,0x61, /* s caron */
154 0xa9, 0x01,0x1b, /* e caron */
155 0xaa, 0x01,0x6f, /* u ring */
156 0xab, 0x00,0xfd, /* y acute */
157 0xac, 0x00,0xf0, /* eth */
158 0xad, 0x01,0x07, /* c acute */
159 0xae, 0x01,0x19, /* e ogonek */
160 0xaf, 0x01,0x05, /* a ogonek */
161 0xb0, 0x01,0x7c, /* z dot */
162 0xb1, 0x01,0x7a, /* z acute */
163 0xb2, 0x01,0x5b, /* s acute */
164 0xb3, 0x01,0x44, /* n acute */
165 0xb4, 0x01,0x42, /* l stroke */
167 0xb5, 0x00,0x20, /* empty */
169 0xb6, 0x01,0x48, /* n caron */
170 0xb7, 0x01,0x65, /* t caron */
172 0xb8, 0x00,0x20, /* empty */
174 0xb9, 0x01,0x7e, /* z caron */
175 0xba, 0x01,0xe7, /* g caron */
177 0xbb, 0x00,0x20, /* empty */
178 0xbc, 0x00,0x20, /* empty */
180 0xbd, 0x1e,0x20, /* G macron */
181 0xbe, 0x1e,0x21, /* g macron */
182 0xbf, 0x01,0x5e, /* S cedilla */
183 0xc0, 0x01,0x5f, /* s cedilla */
184 0xc1, 0x01,0x2f, /* i ogonek */ /* FIXME: not sure with this, it look like normal i */
185 0xc2, 0x01,0x31, /* i dotless */
186 0xc3, 0x01,0x68, /* U tilde */
187 0xc4, 0x01,0x50, /* O dbl acute */
188 0xc5, 0x01,0x69, /* u tilde */
189 0xc6, 0x01,0x51, /* o dbl acute */
190 0xc7, 0x27,0xa9, /* => */
191 0xc8, 0x27,0xa8, /* filled => */
192 0xc9, 0x00,0xd7, /* x */
193 0xca, 0x00,0x5d, /* ] */
194 0xcb, 0x26,0x0f, /* phone */
195 0xcc, 0x01,0x0f, /* d caron */
197 0xcd, 0x00,0x20, /* empty */
199 0xce, 0x00,0x7e, /* ~ */
200 0xcf, 0x00,0x5c, /* \ */
201 0xd0, 0x00,0x5e, /* ^ */
203 0xd1, 0x00,0x20, /* empty */
205 0xd2, 0x00,0x7b, /* { */
206 0xd3, 0x00,0x7c, /* | */
207 0xd4, 0x00,0x7d, /* } */
209 0xd5, 0x00,0x20, /* empty */
211 0xd6, 0x01,0x63, /* t cedilla */
213 0xd7, 0x00,0x20, /* empty */
214 0xd8, 0x00,0x20, /* empty */
215 0xd9, 0x00,0x20, /* empty */
216 0xda, 0x00,0x20, /* empty */
217 0xdb, 0x00,0x20, /* empty */
218 0xdc, 0x00,0x20, /* empty */
219 0xdd, 0x00,0x20, /* empty */
220 0xde, 0x00,0x20, /* empty */
221 0xdf, 0x00,0x20, /* empty */
222 0xe0, 0x00,0x20, /* empty */
224 0xe1, 0x00,0x20, /* two candles */ /* FIXME */
226 0xe2, 0x00,0x20, /* empty */
227 0xe3, 0x00,0x20, /* empty */
228 0xe4, 0x00,0x20, /* empty */
230 0xe5, 0x01,0xce, /* a caron */
231 0xe6, 0x01,0x01, /* a macron */
232 0xe7, 0x01,0x13, /* e macron */
233 0xe8, 0x01,0x2b, /* i macron */
234 0xe9, 0x01,0x4d, /* o macron */
235 0xea, 0x01,0x6b, /* u macron */
236 0xeb, 0x00,0x41, /* A */
237 0xec, 0x00,0x40, /* @ */
238 0xed, 0x00,0x20, /* some strange char :-) */ /* FIXME */
240 0xee, 0x00,0x20, /* big key stroken */ /* FIXME */
241 0xef, 0x00,0x20, /* big key */ /* FIXME */
243 0xf0, 0x00,0x20, /* empty */
245 0xf1, 0x00,0x31, /* 1 */
246 0xf2, 0x00,0x21, /* bold ! */
247 0xf3, 0x26,0x0e, /* black phone */
248 0xf4, 0x00,0x26, /* & */
249 0xf5, 0x23,0x7e, /* bell */
250 0xf6, 0x26,0x6a, /* note */
252 0xf7, 0x27,0x13, /* okay inv */ /* FIXME */
253 0xf8, 0x27,0x13, /* okay */
255 0xf9, 0x00,0x20, /* empty */
257 0xfa, 0x00,0x20, /* key */ /* FIXME */
259 0xfb, 0x00,0x20, /* empty */
261 0xfc, 0x20,0xac, /* Euro */
262 0xfd, 0x21,0x97, /* NE arrow */
263 0xfe, 0x21,0x98, /* SE arrow */
265 0xff, 0x00,0x20, /* empty */
270 /* This is being called from atgen */
271 GSM_Error
ALCATEL_ProtocolVersionReply (GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
275 * Reply received here looks like:
277 * 2 "+CPROT: 0,"V1.0",1"
278 * 3 "+CPROT: 16,"V1.1",16"
281 switch (s
->Phone
.Data
.Priv
.ATGEN
.ReplyState
) {
283 str
= strstr(msg
.Buffer
, "\"V");
284 if (str
== NULL
) return GE_UNKNOWNRESPONSE
;
286 while((str2
= strstr(str
, "\"V")) != NULL
) str
= str2
+ 2;
287 if (strncmp(str
, "1.0", 3) == 0) {
288 s
->Phone
.Data
.Priv
.ALCATEL
.ProtocolVersion
= V_1_0
;
289 } else if (strncmp(str
, "1.1", 3) == 0) {
290 s
->Phone
.Data
.Priv
.ALCATEL
.ProtocolVersion
= V_1_1
;
292 smprintf(s
, "Unknown protocol version. Please send debug log and phone info to author.\n");
293 return GE_NOTIMPLEMENTED
;
297 case AT_Reply_CMSError
:
298 return ATGEN_HandleCMSError(s
);
300 return GE_UNKNOWNRESPONSE
;
304 static GSM_Error
ALCATEL_SetBinaryMode(GSM_StateMachine
*s
)
306 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
309 if (Priv
->Mode
== ModeBinary
) return GE_NONE
;
311 dbgprintf ("Changing to binary mode\n");
313 error
=GSM_WaitFor (s
, "AT+IFC=2,2\r", 11, 0x02, 4, ID_SetFlowControl
);
314 if (error
!= GE_NONE
) return error
;
316 error
=GSM_WaitFor (s
, "AT+CPROT=?\r", 11, 0x02, 4, ID_AlcatelProtocol
);
317 if (error
!= GE_NONE
) return error
;
319 if (Priv
->ProtocolVersion
== V_1_0
) {
320 error
=GSM_WaitFor (s
, "AT+CPROT=16,\"V1.0\",16\r", 22, 0x00, 4, ID_AlcatelConnect
);
322 error
=GSM_WaitFor (s
, "AT+CPROT=16,\"V1.1\",16\r", 22, 0x00, 4, ID_AlcatelConnect
);
325 if (error
== GE_TIMEOUT
&& s
->Speed
!= 19200) {
326 smprintf(s
, "HINT: Try changing speed to 19200, it is sometimes needed for Alcatel binary mode.\n");
329 if (error
!= GE_NONE
) return error
;
331 dbgprintf ("Changing protocol to Alcabus\n");
333 s
->Protocol
.Functions
= &ALCABUSProtocol
;
334 error
= s
->Protocol
.Functions
->Initialise(s
);
335 if (error
!= GE_NONE
) {
336 s
->Protocol
.Functions
= &ATProtocol
;
339 s
->Phone
.Functions
->ReplyFunctions
= ALCATELReplyFunctions
;
340 Priv
->Mode
= ModeBinary
;
341 Priv
->BinaryItem
= 0;
342 Priv
->BinaryType
= 0;
343 Priv
->BinaryState
= StateAttached
;
347 static GSM_Error
ALCATEL_GoToBinaryState(GSM_StateMachine
*s
, GSM_Alcatel_BinaryState state
, GSM_Alcatel_BinaryType type
, int item
) {
348 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
350 unsigned char attach_buffer
[] = {0x00, 0x00, 0x7C ,0x20};
351 unsigned char detach_buffer
[] = {0x00, 0x01, 0x7C ,0x00};
352 unsigned char start_buffer
[] =
353 {0x00, 0x04, 0x7C, 0x80, /* 4 byte database id follows */
354 0x12, 0x34, 0x56, 0x78};
355 unsigned char end_buffer
[] =
356 {0x00, 0x04, 0x7C, 0x82,
358 0x00, 0x00, 0x00, 0x00}; /* TimeStamp */
359 unsigned char close_buffer
[] =
363 unsigned char select1_buffer
[] =
367 unsigned char select2_buffer
[] =
371 unsigned char begin_buffer
[] =
372 {0x00, 0x04, 0x7C, 0x81,
375 unsigned char commit_buffer
[] =
380 smprintf(s
, "Alcatel state switcher: %d -> %d, %d -> %d, %d -> %d\n", Priv
->BinaryState
, state
, Priv
->BinaryType
, type
, Priv
->BinaryItem
, item
);
381 error
= ALCATEL_SetBinaryMode(s
);
382 if (error
!= GE_NONE
) return error
;
384 /* Do we need to do anything? */
385 if ((state
== Priv
->BinaryState
) && (type
== Priv
->BinaryType
) && (item
== Priv
->BinaryItem
)) return GE_NONE
;
387 /* We're editing, but the next state is not the same. so commit editing */
388 if (Priv
->BinaryState
== StateEdit
) {
389 switch (Priv
->BinaryType
) {
391 commit_buffer
[2] = ALCATEL_SYNC_TYPE_CALENDAR
;
394 commit_buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
397 commit_buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
400 dbgprintf ("Commiting edited record\n");
401 error
=GSM_WaitFor (s
, commit_buffer
, 5, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelCommit
);
402 if (error
!= GE_NONE
) return error
;
403 error
=GSM_WaitFor (s
, 0, 0, 0x00, ALCATEL_TIMEOUT
, ID_AlcatelCommit2
);
404 if (error
!= GE_NONE
) return error
;
405 Priv
->BinaryState
= StateSession
;
406 Priv
->BinaryItem
= 0;
409 /* Do we want to edit something of same type? */
410 if ((state
== StateEdit
) && (type
== Priv
->BinaryType
)) {
411 /* Edit state doesn't need any switching, it is needed only for
412 * indication that e have to commit record before we switch to other
415 Priv
->BinaryState
= StateEdit
;
416 Priv
->BinaryItem
= item
;
420 /* Now we can be only in Attached or Session state, so if states and types matches, just keep them as they are */
421 if ((state
== Priv
->BinaryState
) && (type
== Priv
->BinaryType
)) {
425 /* Do we need to close session? */
426 if (Priv
->BinaryState
== StateSession
) {
427 dbgprintf ("Ending session\n");
428 switch (Priv
->BinaryType
) {
430 end_buffer
[4] = ALCATEL_BEGIN_SYNC_CALENDAR
;
433 end_buffer
[4] = ALCATEL_BEGIN_SYNC_CONTACTS
;
436 end_buffer
[4] = ALCATEL_BEGIN_SYNC_TODO
;
439 error
=GSM_WaitFor (s
, end_buffer
, 9, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelEnd
);
440 if (error
!= GE_NONE
) return error
;
442 switch (Priv
->BinaryType
) {
444 close_buffer
[2] = ALCATEL_SYNC_TYPE_CALENDAR
;
447 close_buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
450 close_buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
453 dbgprintf ("Closing session\n");
454 error
=GSM_WaitFor (s
, close_buffer
, 5, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelClose
);
455 if (error
!= GE_NONE
) return error
;
457 dbgprintf ("Detaching binary mode\n");
458 GSM_WaitFor (s
, detach_buffer
, 4, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelDetach
);
460 Priv
->BinaryState
= StateAttached
;
461 Priv
->BinaryType
= 0;
464 /* Do we need to open session? */
465 if (state
== StateSession
|| state
== StateEdit
) {
466 dbgprintf ("Starting session for %s\n",
467 (type
== TypeCalendar
? "Calendar" :
468 (type
== TypeToDo
? "Todo" :
469 (type
== TypeContacts
? "Contacts" :
471 /* Fill up buffers */
474 select1_buffer
[2] = ALCATEL_SYNC_TYPE_CALENDAR
;
475 select2_buffer
[2] = ALCATEL_SYNC_TYPE_CALENDAR
;
476 begin_buffer
[4] = ALCATEL_BEGIN_SYNC_CALENDAR
;
479 select1_buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
480 select2_buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
481 begin_buffer
[4] = ALCATEL_BEGIN_SYNC_CONTACTS
;
484 select1_buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
485 select2_buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
486 begin_buffer
[4] = ALCATEL_BEGIN_SYNC_TODO
;
489 dbgprintf ("Attaching in binary mode\n");
492 error
=GSM_WaitFor (s
, attach_buffer
, 4, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelAttach
);
493 if (error
!= GE_NONE
) return error
;
495 smprintf(s
,"Start session\n");
496 error
=GSM_WaitFor (s
, start_buffer
, 8, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelStart
);
497 if (error
!= GE_NONE
) return error
;
499 smprintf(s
,"Select type\n");
500 error
=GSM_WaitFor (s
, select1_buffer
, 4, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelSelect1
);
501 if (error
!= GE_NONE
) return error
;
502 error
=GSM_WaitFor (s
, select2_buffer
, 6, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelSelect2
);
503 if (error
!= GE_NONE
) return error
;
504 error
=GSM_WaitFor (s
, 0, 0, 0x00, ALCATEL_TIMEOUT
, ID_AlcatelSelect3
);
505 if (error
!= GE_NONE
) return error
;
507 smprintf(s
,"Begin transfer\n");
508 error
=GSM_WaitFor (s
, begin_buffer
, 8, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelBegin1
);
509 if (error
!= GE_NONE
) return error
;
510 error
=GSM_WaitFor (s
, 0, 0, 0x00, ALCATEL_TIMEOUT
, ID_AlcatelBegin2
);
511 if (error
!= GE_NONE
) return error
;
513 Priv
->BinaryState
= StateSession
;
514 Priv
->BinaryType
= type
;
515 /* Do we want to edit something of same type? */
516 if ((state
== StateEdit
) && (type
== Priv
->BinaryType
)) {
517 Priv
->BinaryState
= StateEdit
;
518 Priv
->BinaryItem
= item
;
525 static GSM_Error
ALCATEL_SetATMode(GSM_StateMachine
*s
)
527 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
530 if (Priv
->Mode
== ModeAT
) return GE_NONE
;
532 error
= ALCATEL_GoToBinaryState(s
, StateAttached
, 0, 0);
533 if (error
!= GE_NONE
) return error
;
535 error
= s
->Protocol
.Functions
->Terminate(s
);
536 if (error
!= GE_NONE
) return error
;
538 dbgprintf ("Changing protocol to AT\n");
539 s
->Protocol
.Functions
= &ATProtocol
;
540 s
->Phone
.Functions
->ReplyFunctions
= ATGENReplyFunctions
;
545 /* In case we don't send AT command short after closing binary mode,
546 * phone takes VERY long to react next time. The error code in
547 * intetionally ignored.
549 GSM_WaitFor (s
, "AT\r", 3, 0x00, 0, ID_IncomingFrame
);
554 static GSM_Error
ALCATEL_Initialise(GSM_StateMachine
*s
)
556 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
561 Priv
->CalendarItems
= NULL
;
562 Priv
->ContactsItems
= NULL
;
563 Priv
->ToDoItems
= NULL
;
564 Priv
->CalendarItemsCount
= 0;
565 Priv
->ToDoItemsCount
= 0;
566 Priv
->ContactsItemsCount
= 0;
567 Priv
->CurrentFields
[0] = 0;
568 Priv
->CurrentFieldsCount
= 0;
569 Priv
->CurrentFieldsItem
= 0;
570 Priv
->CurrentFieldsType
= 0;
571 Priv
->ProtocolVersion
= V_1_0
;
573 Priv
->CurrentCategoriesCount
= 0;
574 Priv
->CurrentCategoriesType
= 0;
576 s
->Protocol
.Functions
= &ATProtocol
;
577 s
->Phone
.Functions
->ReplyFunctions
= ATGENReplyFunctions
;
579 if (ATGEN_Initialise(s
) != GE_NONE
|| GSM_WaitFor (s
, "AT\r", 3, 0x00, 2, ID_IncomingFrame
) != GE_NONE
) {
580 smprintf(s
,"AT initialisation failed, trying to stop binary mode...\n");
581 s
->Protocol
.Functions
= &ALCABUSProtocol
;
582 error
= s
->Protocol
.Functions
->Terminate(s
);
583 s
->Protocol
.Functions
= &ATProtocol
;
585 error
= ATGEN_Initialise(s
);
586 if (error
!= GE_NONE
) return error
;
592 static GSM_Error
ALCATEL_Terminate(GSM_StateMachine
*s
)
595 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
597 free(Priv
->CalendarItems
);
598 free(Priv
->ContactsItems
);
599 free(Priv
->ToDoItems
);
600 error
= ALCATEL_SetATMode(s
);
601 return ATGEN_Terminate(s
);
604 /* finds whether id is set in the phone */
605 static GSM_Error
ALCATEL_IsIdAvailable(GSM_StateMachine
*s
, int id
) {
606 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
609 if (id
> ALCATEL_MAX_LOCATION
) return GE_INVALIDLOCATION
;
611 switch (Priv
->BinaryType
) {
613 Priv
->CurrentList
= &(Priv
->CalendarItems
);
614 Priv
->CurrentCount
= &(Priv
->CalendarItemsCount
);
617 Priv
->CurrentList
= &(Priv
->ContactsItems
);
618 Priv
->CurrentCount
= &(Priv
->ContactsItemsCount
);
621 Priv
->CurrentList
= &(Priv
->ToDoItems
);
622 Priv
->CurrentCount
= &(Priv
->ToDoItemsCount
);
626 for (i
=0; i
<*Priv
->CurrentCount
; i
++) {
627 if ((*Priv
->CurrentList
)[i
] == id
) return GE_NONE
;
633 /* finds next id that is available in the phone */
634 static GSM_Error
ALCATEL_GetNextId(GSM_StateMachine
*s
, int *id
) {
635 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
637 int next
= ALCATEL_MAX_LOCATION
;
639 switch (Priv
->BinaryType
) {
641 Priv
->CurrentList
= &(Priv
->CalendarItems
);
642 Priv
->CurrentCount
= &(Priv
->CalendarItemsCount
);
645 Priv
->CurrentList
= &(Priv
->ContactsItems
);
646 Priv
->CurrentCount
= &(Priv
->ContactsItemsCount
);
649 Priv
->CurrentList
= &(Priv
->ToDoItems
);
650 Priv
->CurrentCount
= &(Priv
->ToDoItemsCount
);
654 for (i
=0; i
<*Priv
->CurrentCount
; i
++) {
655 if (((*Priv
->CurrentList
)[i
] > *id
) && ((*Priv
->CurrentList
)[i
] < next
)) {
656 next
= (*Priv
->CurrentList
)[i
];
659 if (next
== ALCATEL_MAX_LOCATION
) {
667 static GSM_Error
ALCATEL_ReplyGetIds(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
669 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
672 count
= msg
.Buffer
[10];
673 *Priv
->CurrentCount
+= count
;
675 *Priv
->CurrentList
= (int *)realloc(*Priv
->CurrentList
, (*Priv
->CurrentCount
+ 1)* sizeof(int));
676 if (*Priv
->CurrentList
== NULL
) return GE_MOREMEMORY
;
678 for (i
= 0; i
< count
; i
++) {
680 (*Priv
->CurrentList
)[*Priv
->CurrentCount
- count
+ i
] = msg
.Buffer
[pos
+ 3] +
681 (msg
.Buffer
[pos
+ 2] << 8) +
682 (msg
.Buffer
[pos
+ 1] << 16) +
683 (msg
.Buffer
[pos
] << 24);
685 (*Priv
->CurrentList
)[*Priv
->CurrentCount
] = 0;
687 /* If last byte is 0, then we transmitted all items */
688 Priv
->TransferCompleted
= msg
.Buffer
[4 + msg
.Buffer
[4]] == 0;
692 static GSM_Error
ALCATEL_GetAvailableIds(GSM_StateMachine
*s
, bool refresh
)
694 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
697 unsigned char buffer
[] =
702 if (Priv
->BinaryState
!= StateSession
) return GE_UNKNOWN
;
704 switch (Priv
->BinaryType
) {
706 buffer
[2] = ALCATEL_SYNC_TYPE_CALENDAR
;
707 Priv
->CurrentList
= &(Priv
->CalendarItems
);
708 Priv
->CurrentCount
= &(Priv
->CalendarItemsCount
);
711 buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
712 Priv
->CurrentList
= &(Priv
->ContactsItems
);
713 Priv
->CurrentCount
= &(Priv
->ContactsItemsCount
);
716 buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
717 Priv
->CurrentList
= &(Priv
->ToDoItems
);
718 Priv
->CurrentCount
= &(Priv
->ToDoItemsCount
);
722 if (*Priv
->CurrentList
!= NULL
) {
723 if (!refresh
) return GE_NONE
;
724 free(*Priv
->CurrentList
);
725 *Priv
->CurrentList
= NULL
;
727 smprintf(s
,"Reading items list\n");
729 *Priv
->CurrentCount
= 0;
730 Priv
->TransferCompleted
= false;
732 error
=GSM_WaitFor (s
, buffer
, 5, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelGetIds1
);
733 if (error
!= GE_NONE
) return error
;
735 while (!Priv
->TransferCompleted
) {
736 error
=GSM_WaitFor (s
, 0, 0, 0x00, ALCATEL_TIMEOUT
, ID_AlcatelGetIds2
);
737 if (error
!= GE_NONE
) return error
;
741 smprintf(s
,"Received %d ids: ", *Priv
->CurrentCount
);
742 for (i
=0; i
< *Priv
->CurrentCount
; i
++) {
743 smprintf(s
,"%x ", (*Priv
->CurrentList
)[i
]);
750 static GSM_Error
ALCATEL_ReplyGetFields(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
752 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
755 if (msg
.Buffer
[14] > GSM_PHONEBOOK_ENTRIES
) {
756 smprintf(s
, "WARNING: Field list truncated, you should increase GSM_PHONEBOOK_ENTRIES to at least %d\n", msg
.Buffer
[14]);
757 Priv
->CurrentFieldsCount
= GSM_PHONEBOOK_ENTRIES
;
759 Priv
->CurrentFieldsCount
= msg
.Buffer
[14];
762 Priv
->CurrentFields
[Priv
->CurrentFieldsCount
] = 0;
764 for (i
= 0; i
< Priv
->CurrentFieldsCount
; i
++) {
765 Priv
->CurrentFields
[i
] = msg
.Buffer
[15 + i
];
771 static GSM_Error
ALCATEL_GetFields(GSM_StateMachine
*s
, int id
) {
772 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
775 unsigned char buffer
[] =
779 0x00, 0x00, 0x00, 0x00}; /* item */
781 if (Priv
->BinaryState
!= StateSession
) return GE_UNKNOWN
;
782 if ((Priv
->CurrentFieldsItem
== id
) && (Priv
->CurrentFieldsType
== Priv
->BinaryType
)) return GE_NONE
;
784 smprintf(s
,"Reading item fields (%d)\n", id
);
786 buffer
[5] = (id
>> 24);
787 buffer
[6] = ((id
>> 16) & 0xff);
788 buffer
[7] = ((id
>> 8) & 0xff);
789 buffer
[8] = (id
& 0xff);
791 switch (Priv
->BinaryType
) {
793 buffer
[2] = ALCATEL_SYNC_TYPE_CALENDAR
;
796 buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
799 buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
803 Priv
->CurrentFieldsItem
= id
;
804 Priv
->CurrentFieldsType
= Priv
->BinaryType
;
806 error
=GSM_WaitFor (s
, buffer
, 9, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelGetFields1
);
807 if (error
!= GE_NONE
) return error
;
808 error
=GSM_WaitFor (s
, 0, 0, 0x00, ALCATEL_TIMEOUT
, ID_AlcatelGetFields2
);
809 if (error
!= GE_NONE
) return error
;
812 smprintf(s
,"Received %d fields: ", Priv
->CurrentFieldsCount
);
813 for (i
=0; i
< Priv
->CurrentFieldsCount
; i
++) {
814 smprintf(s
,"%x ", Priv
->CurrentFields
[i
]);
821 static GSM_Error
ALCATEL_ReplyGetFieldValue(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
823 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
824 unsigned char *buffer
= &(msg
.Buffer
[16]);
826 if (buffer
[1] == 0x05 && buffer
[2] == 0x67) {
828 Priv
->ReturnType
= Alcatel_date
;
829 Priv
->ReturnDateTime
.Day
= buffer
[4];
830 Priv
->ReturnDateTime
.Month
= buffer
[5];
831 Priv
->ReturnDateTime
.Year
= buffer
[7] + (buffer
[6] << 8);
832 Priv
->ReturnDateTime
.Timezone
= 0; /* FIXME: how to acquire this? */
834 Priv
->ReturnDateTime
.Hour
= 0;
835 Priv
->ReturnDateTime
.Minute
= 0;
836 Priv
->ReturnDateTime
.Second
= 0;
837 } else if (buffer
[1] == 0x06 && buffer
[2] == 0x68) {
839 Priv
->ReturnType
= Alcatel_time
;
840 Priv
->ReturnDateTime
.Hour
= buffer
[4];
841 Priv
->ReturnDateTime
.Minute
= buffer
[5];
842 Priv
->ReturnDateTime
.Second
= buffer
[6];
844 Priv
->ReturnDateTime
.Day
= 0;
845 Priv
->ReturnDateTime
.Month
= 0;
846 Priv
->ReturnDateTime
.Year
= 0;
847 Priv
->ReturnDateTime
.Timezone
= 0;
848 } else if (buffer
[1] == 0x08 && buffer
[2] == 0x3C) {
850 Priv
->ReturnType
= Alcatel_string
;
851 if (GSM_PHONEBOOK_TEXT_LENGTH
< buffer
[3])
852 smprintf(s
, "WARNING: Text truncated, you should increase GSM_PHONEBOOK_TEXT_LENGTH to at least %d\n", buffer
[3] + 1);
853 if (Priv
->ProtocolVersion
== V_1_0
) {
854 DecodeDefault( Priv
->ReturnString
, buffer
+ 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH
, buffer
[3]), false, GSM_AlcatelAlphabet
);
855 } else if(Priv
->ProtocolVersion
== V_1_1
&& (buffer
[4] & 0x80)) {
856 memcpy(Priv
->ReturnString
, buffer
+ 5, buffer
[3]);
857 Priv
->ReturnString
[buffer
[3] + 1] = 0;
858 Priv
->ReturnString
[buffer
[3] + 2] = 0;
859 ReverseUnicodeString(Priv
->ReturnString
);
861 DecodeDefault( Priv
->ReturnString
, buffer
+ 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH
, buffer
[3]), false, GSM_AlcatelAlphabet
);
863 } else if (buffer
[1] == 0x07 && buffer
[2] == 0x3C) {
865 Priv
->ReturnType
= Alcatel_phone
;
866 if (GSM_PHONEBOOK_TEXT_LENGTH
< buffer
[3])
867 smprintf(s
, "WARNING: Text truncated, you should increase GSM_PHONEBOOK_TEXT_LENGTH to at least %d\n", buffer
[3] + 1);
868 if (Priv
->ProtocolVersion
== V_1_0
) {
869 DecodeDefault( Priv
->ReturnString
, buffer
+ 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH
, buffer
[3]), false, GSM_AlcatelAlphabet
);
870 } else if(Priv
->ProtocolVersion
== V_1_1
&& (buffer
[4] & 0x80)) {
871 memcpy(Priv
->ReturnString
, buffer
+ 5, buffer
[3]);
872 Priv
->ReturnString
[buffer
[3] + 1] = 0;
873 Priv
->ReturnString
[buffer
[3] + 2] = 0;
874 ReverseUnicodeString(Priv
->ReturnString
);
876 DecodeDefault( Priv
->ReturnString
, buffer
+ 4, MIN(GSM_PHONEBOOK_TEXT_LENGTH
, buffer
[3]), false, GSM_AlcatelAlphabet
);
878 } else if (buffer
[1] == 0x03 && buffer
[2] == 0x3B) {
880 Priv
->ReturnType
= Alcatel_bool
;
881 Priv
->ReturnInt
= buffer
[3];
882 } else if (buffer
[1] == 0x02 && buffer
[2] == 0x3A) {
884 Priv
->ReturnType
= Alcatel_int
;
885 Priv
->ReturnInt
= buffer
[6] + (buffer
[5] << 8) + (buffer
[4] << 16) + (buffer
[3] << 24);
886 } else if (buffer
[1] == 0x04 && buffer
[2] == 0x38) {
888 Priv
->ReturnType
= Alcatel_enum
;
889 Priv
->ReturnInt
= buffer
[3];
890 } else if (buffer
[1] == 0x00 && buffer
[2] == 0x38) {
892 Priv
->ReturnType
= Alcatel_byte
;
893 Priv
->ReturnInt
= buffer
[3];
895 smprintf(s
, "WARNING: Uknown data type received (%02X,%02X)\n", buffer
[1], buffer
[2]);
896 return GE_UNKNOWNRESPONSE
;
901 static GSM_Error
ALCATEL_GetFieldValue(GSM_StateMachine
*s
, int id
, int field
)
903 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
905 unsigned char buffer
[] =
909 0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */
912 smprintf(s
,"Reading item value (%08x.%02x)\n", id
, field
);
914 switch (Priv
->BinaryType
) {
916 buffer
[2] = ALCATEL_SYNC_TYPE_CALENDAR
;
919 buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
922 buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
926 buffer
[5] = (id
>> 24);
927 buffer
[6] = ((id
>> 16) & 0xff);
928 buffer
[7] = ((id
>> 8) & 0xff);
929 buffer
[8] = (id
& 0xff);
930 buffer
[9] = (field
& 0xff);
932 error
=GSM_WaitFor (s
, buffer
, 10, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelGetFieldValue1
);
933 if (error
!= GE_NONE
) return error
;
934 error
=GSM_WaitFor (s
, 0, 0, 0x00, ALCATEL_TIMEOUT
, ID_AlcatelGetFieldValue2
);
935 if (error
!= GE_NONE
) return error
;
940 static GSM_Error
ALCATEL_ReplyGetCategories(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
942 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
945 /* Did we get any category? */
946 if (msg
.Buffer
[4] == 6) {
947 Priv
->CurrentCategoriesCount
= 0;
950 if (msg
.Buffer
[12] > ALCATEL_MAX_CATEGORIES
) {
951 smprintf(s
, "WARNING: Field list truncated, you should increase ALCATEL_MAX_CATEGORIES to at least %d\n", msg
.Buffer
[12]);
952 Priv
->CurrentCategoriesCount
= ALCATEL_MAX_CATEGORIES
;
954 Priv
->CurrentCategoriesCount
= msg
.Buffer
[12];
957 for (i
= 0; i
< Priv
->CurrentCategoriesCount
; i
++) {
958 Priv
->CurrentCategories
[i
] = msg
.Buffer
[13 + i
];
959 Priv
->CurrentCategoriesCache
[i
][0] = '\000';
960 Priv
->CurrentCategoriesCache
[i
][1] = '\000';
966 static GSM_Error
ALCATEL_GetAvailableCategoryIds(GSM_StateMachine
*s
) {
967 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
970 unsigned char buffer
[] =
976 if (Priv
->BinaryState
!= StateSession
) return GE_UNKNOWN
;
977 if (Priv
->CurrentCategoriesType
== Priv
->BinaryType
) return GE_NONE
;
978 switch (Priv
->BinaryType
) {
980 buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
981 buffer
[4] = ALCATEL_LIST_CONTACTS_CAT
;
984 buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
985 buffer
[4] = ALCATEL_LIST_TODO_CAT
;
988 return GE_NOTSUPPORTED
;
991 Priv
->CurrentCategoriesType
= Priv
->BinaryType
;
993 smprintf(s
,"Reading category list\n");
995 error
=GSM_WaitFor (s
, buffer
, 5, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelGetCategories1
);
996 if (error
!= GE_NONE
) return error
;
998 error
=GSM_WaitFor (s
, 0, 0, 0x00, ALCATEL_TIMEOUT
, ID_AlcatelGetCategories2
);
999 if (error
!= GE_NONE
) return error
;
1002 smprintf(s
,"Received %d ids: ", Priv
->CurrentCategoriesCount
);
1003 for (i
=0; i
< Priv
->CurrentCategoriesCount
; i
++) {
1004 smprintf(s
,"%i ", Priv
->CurrentCategories
[i
]);
1011 static GSM_Error
ALCATEL_IsCategoryIdAvailable(GSM_StateMachine
*s
, int id
) {
1012 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
1015 if (Priv
->CurrentCategoriesType
!= Priv
->BinaryType
) return GE_UNKNOWN
;
1017 for (i
= 0; i
< Priv
->CurrentCategoriesCount
; i
++) {
1018 if (Priv
->CurrentCategories
[i
] == id
) return GE_NONE
;
1023 static GSM_Error
ALCATEL_ReplyGetCategoryText(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1025 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
1028 len
= msg
.Buffer
[14];
1029 if (len
> GSM_MAX_CATEGORY_NAME_LENGTH
) {
1030 smprintf(s
, "WARNING: Category name truncated, you should increase GSM_MAX_CATEGORY_NAME_LENGTH to at least %d\n", len
);
1032 if (Priv
->ProtocolVersion
== V_1_0
) {
1033 DecodeDefault( Priv
->ReturnString
, msg
.Buffer
+ 15, MIN(GSM_MAX_CATEGORY_NAME_LENGTH
, len
), false, GSM_AlcatelAlphabet
);
1034 } else if(Priv
->ProtocolVersion
== V_1_1
&& (msg
.Buffer
[15] & 0x80)) {
1035 memcpy(Priv
->ReturnString
, msg
.Buffer
+ 16, len
);
1036 Priv
->ReturnString
[len
+ 1] = 0;
1037 Priv
->ReturnString
[len
+ 2] = 0;
1038 ReverseUnicodeString(Priv
->ReturnString
);
1040 DecodeDefault( Priv
->ReturnString
, msg
.Buffer
+ 15, MIN(GSM_MAX_CATEGORY_NAME_LENGTH
, len
), false, GSM_AlcatelAlphabet
);
1045 static GSM_Error
ALCATEL_GetCategoryText(GSM_StateMachine
*s
, int id
) {
1046 unsigned char buffer
[] = {0x00, 0x04, 0x00 /*type*/, 0x0c, 0x00 /*list*/, 0x0A, 0x01, 0x00 /*item*/ };
1047 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
1050 if (Priv
->CurrentCategoriesCache
[id
][0] != '\000' || Priv
->CurrentCategoriesCache
[id
][1] != '\000') {
1051 CopyUnicodeString(Priv
->ReturnString
, Priv
->CurrentCategoriesCache
[id
]);
1055 switch (Priv
->BinaryType
) {
1057 buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
1058 buffer
[4] = ALCATEL_LIST_CONTACTS_CAT
;
1061 buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
1062 buffer
[4] = ALCATEL_LIST_TODO_CAT
;
1065 return GE_NOTSUPPORTED
;
1068 buffer
[7] = (id
& 0xff);
1070 error
=GSM_WaitFor (s
, buffer
, 8, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelGetCategoryText1
);
1071 if (error
!= GE_NONE
) return error
;
1072 error
=GSM_WaitFor (s
, 0, 0, 0x00, ALCATEL_TIMEOUT
, ID_AlcatelGetCategoryText2
);
1073 if (error
!= GE_NONE
) return error
;
1075 CopyUnicodeString(Priv
->CurrentCategoriesCache
[id
], Priv
->ReturnString
);
1080 static GSM_Error
ALCATEL_DeleteField(GSM_StateMachine
*s
, int id
, int field
) {
1081 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
1083 unsigned char buffer
[] =
1087 0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */
1092 smprintf(s
,"Deleting field (%08x.%02x)\n", id
, field
);
1094 switch (Priv
->BinaryType
) {
1096 buffer
[2] = ALCATEL_SYNC_TYPE_CALENDAR
;
1099 buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
1102 buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
1106 buffer
[5] = (id
>> 24);
1107 buffer
[6] = ((id
>> 16) & 0xff);
1108 buffer
[7] = ((id
>> 8) & 0xff);
1109 buffer
[8] = (id
& 0xff);
1110 buffer
[11] = (field
& 0xff);
1112 error
=GSM_WaitFor (s
, buffer
, 13, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelDeleteField
);
1113 if (error
!= GE_NONE
) return error
;
1118 static GSM_Error
ALCATEL_DeleteItem(GSM_StateMachine
*s
, int id
) {
1119 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
1121 unsigned char buffer
[] =
1125 0x00, 0x00, 0x00, 0x00, /* here follows 4byte id */
1128 smprintf(s
,"Deleting item (%08x)\n", id
);
1130 switch (Priv
->BinaryType
) {
1132 buffer
[2] = ALCATEL_SYNC_TYPE_CALENDAR
;
1135 buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
1138 buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
1142 buffer
[5] = (id
>> 24);
1143 buffer
[6] = ((id
>> 16) & 0xff);
1144 buffer
[7] = ((id
>> 8) & 0xff);
1145 buffer
[8] = (id
& 0xff);
1147 error
=GSM_WaitFor (s
, buffer
, 10, 0x02, ALCATEL_TIMEOUT
, ID_AlcatelDeleteItem1
);
1148 if (error
!= GE_NONE
) return error
;
1150 error
=GSM_WaitFor (s
, 0, 0, 0x0, ALCATEL_TIMEOUT
, ID_AlcatelDeleteItem2
);
1151 if (error
!= GE_NONE
) return error
;
1156 static GSM_Error
ALCATEL_ReplyDeleteItem(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1158 if (msg
.Buffer
[8] != 0x25) return GE_UNKNOWNRESPONSE
;
1162 static GSM_Error
ALCATEL_BuildWriteBuffer(unsigned char * buffer
, GSM_Alcatel_FieldType type
, int field
, void *data
) {
1165 buffer
[1] = field
& 0xff;
1169 if (!CheckDate((GSM_DateTime
*)data
)) return GE_INVALIDDATETIME
;
1176 buffer
[6] = ((GSM_DateTime
*)data
)->Day
& 0xff;
1177 buffer
[7] = ((GSM_DateTime
*)data
)->Month
& 0xff;
1178 buffer
[8] = ((GSM_DateTime
*)data
)->Year
>> 8;
1179 buffer
[9] = ((GSM_DateTime
*)data
)->Year
& 0xff;
1183 if (!CheckTime((GSM_DateTime
*)data
)) return GE_INVALIDDATETIME
;
1190 buffer
[6] = ((GSM_DateTime
*)data
)->Hour
& 0xff;
1191 buffer
[7] = ((GSM_DateTime
*)data
)->Minute
& 0xff;
1192 buffer
[8] = ((GSM_DateTime
*)data
)->Second
& 0xff;
1195 case Alcatel_string
:
1199 len
= MIN(UnicodeLength((char *)data
),62);
1200 EncodeDefault(buffer
+ 6, (char *)data
, &len
, false, GSM_AlcatelAlphabet
);
1202 buffer
[0] = 5 + len
;
1203 buffer
[6 + len
] = 0x00;
1209 len
= MIN(UnicodeLength((char *)data
),50);
1210 EncodeDefault(buffer
+ 6, (char *)data
, &len
, false, GSM_AlcatelAlphabet
);
1212 buffer
[0] = 5 + len
;
1213 buffer
[6 + len
] = 0x00;
1220 buffer
[5] = *(int *)data
& 0xff;
1228 buffer
[5] = *(int *)data
& 0xff;
1236 buffer
[5] = *(unsigned int *)data
>> 24;
1237 buffer
[6] = (*(unsigned int *)data
>> 16) & 0xff;
1238 buffer
[7] = (*(unsigned int *)data
>> 8) & 0xff;
1239 buffer
[8] = *(unsigned int *)data
& 0xff;
1247 buffer
[5] = *(int *)data
& 0xff;
1254 static GSM_Error
ALCATEL_CreateField(GSM_StateMachine
*s
, GSM_Alcatel_FieldType type
, int field
, void *data
) {
1255 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
1257 unsigned char buffer
[200] =
1261 0x00, /* length of remaining part */
1263 0x37}; /* data follows here */
1265 smprintf(s
,"Creating field (%02x)\n", field
);
1267 switch (Priv
->BinaryType
) {
1269 buffer
[2] = ALCATEL_SYNC_TYPE_CALENDAR
;
1272 buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
1275 buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
1278 error
= ALCATEL_BuildWriteBuffer(buffer
+ 6, type
, field
, data
);
1279 if (error
!= GE_NONE
) return error
;
1281 error
= GSM_WaitFor (s
, buffer
, 8 + buffer
[6], 0x02, ALCATEL_TIMEOUT
, ID_AlcatelCreateField
);
1282 if (error
!= GE_NONE
) return error
;
1287 static GSM_Error
ALCATEL_UpdateField(GSM_StateMachine
*s
, GSM_Alcatel_FieldType type
, int id
, int field
, void *data
) {
1288 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
1290 unsigned char buffer
[200] =
1294 0x00, 0x00, 0x00, 0x00, /* id */
1296 0x00, /* length of remaining part */
1298 0x37}; /* data follows here */
1300 smprintf(s
,"Updating field (%08x.%02x)\n", id
, field
);
1302 buffer
[5] = (id
>> 24);
1303 buffer
[6] = ((id
>> 16) & 0xff);
1304 buffer
[7] = ((id
>> 8) & 0xff);
1305 buffer
[8] = (id
& 0xff);
1307 switch (Priv
->BinaryType
) {
1309 buffer
[2] = ALCATEL_SYNC_TYPE_CALENDAR
;
1312 buffer
[2] = ALCATEL_SYNC_TYPE_CONTACTS
;
1315 buffer
[2] = ALCATEL_SYNC_TYPE_TODO
;
1318 error
= ALCATEL_BuildWriteBuffer(buffer
+ 10, type
, field
, data
);
1319 if (error
!= GE_NONE
) return error
;
1321 error
= GSM_WaitFor (s
, buffer
, 12 + buffer
[10], 0x02, ALCATEL_TIMEOUT
, ID_AlcatelUpdateField
);
1322 if (error
!= GE_NONE
) return error
;
1327 static GSM_Error
ALCATEL_GetManufacturer(GSM_StateMachine
*s
)
1329 strcpy(s
->Phone
.Data
.Manufacturer
, "Alcatel");
1333 static GSM_Error
ALCATEL_GetIMEI (GSM_StateMachine
*s
)
1337 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
1338 return ATGEN_GetIMEI(s
);
1341 static GSM_Error
ALCATEL_GetFirmware(GSM_StateMachine
*s
)
1345 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
1346 return ATGEN_GetFirmware(s
);
1349 static GSM_Error
ALCATEL_GetModel(GSM_StateMachine
*s
)
1353 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
1354 return ATGEN_GetModel(s
);
1357 static GSM_Error
ALCATEL_GetDateTime(GSM_StateMachine
*s
, GSM_DateTime
*date_time
)
1361 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
1362 return ATGEN_GetDateTime(s
, date_time
);
1365 static GSM_Error
ALCATEL_GetMemory(GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
)
1368 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
1372 if (entry
->MemoryType
== GMT_ME
) {
1373 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeContacts
, 0))!= GE_NONE
) return error
;
1374 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
1375 if ((error
= ALCATEL_IsIdAvailable(s
, entry
->Location
))!= GE_NONE
) {
1376 entry
->EntriesNum
= 0;
1379 if ((error
= ALCATEL_GetFields(s
, entry
->Location
))!= GE_NONE
) return error
;
1381 entry
->EntriesNum
= Priv
->CurrentFieldsCount
;
1382 entry
->PreferUnicode
= false;
1384 for (i
=0; i
<Priv
->CurrentFieldsCount
; i
++) {
1385 if ((error
= ALCATEL_GetFieldValue(s
, entry
->Location
, Priv
->CurrentFields
[i
]))!= GE_NONE
) return error
;
1386 entry
->Entries
[i
].VoiceTag
= 0;
1387 switch (Priv
->CurrentFields
[i
]) {
1389 if (Priv
->ReturnType
!= Alcatel_string
) {
1390 smprintf(s
,"WARNING: Received unexpected type %02X for field 0, ignoring\n", Priv
->ReturnType
);
1391 entry
->EntriesNum
--;
1395 entry
->Entries
[i
- j
].EntryType
= PBK_Text_LastName
;
1396 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1399 if (Priv
->ReturnType
!= Alcatel_string
) {
1400 smprintf(s
,"WARNING: Received unexpected type %02X for field 1, ignoring\n", Priv
->ReturnType
);
1401 entry
->EntriesNum
--;
1405 entry
->Entries
[i
- j
].EntryType
= PBK_Text_FirstName
;
1406 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1409 if (Priv
->ReturnType
!= Alcatel_string
) {
1410 smprintf(s
,"WARNING: Received unexpected type %02X for field 2, ignoring\n", Priv
->ReturnType
);
1411 entry
->EntriesNum
--;
1415 entry
->Entries
[i
- j
].EntryType
= PBK_Text_Company
;
1416 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1419 if (Priv
->ReturnType
!= Alcatel_string
) {
1420 smprintf(s
,"WARNING: Received unexpected type %02X for field 3, ignoring\n", Priv
->ReturnType
);
1421 entry
->EntriesNum
--;
1425 entry
->Entries
[i
- j
].EntryType
= PBK_Text_JobTitle
;
1426 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1429 if (Priv
->ReturnType
!= Alcatel_string
) {
1430 smprintf(s
,"WARNING: Received unexpected type %02X for field 4, ignoring\n", Priv
->ReturnType
);
1431 entry
->EntriesNum
--;
1435 entry
->Entries
[i
- j
].EntryType
= PBK_Text_Note
;
1436 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1439 if (Priv
->ReturnType
!= Alcatel_byte
) {
1440 smprintf(s
,"WARNING: Received unexpected type %02X for field 5, ignoring\n", Priv
->ReturnType
);
1441 entry
->EntriesNum
--;
1445 entry
->Entries
[i
- j
].EntryType
= PBK_Category
;
1446 entry
->Entries
[i
- j
].Number
= Priv
->ReturnInt
;
1449 if (Priv
->ReturnType
!= Alcatel_bool
) {
1450 smprintf(s
,"WARNING: Received unexpected type %02X for field 6, ignoring\n", Priv
->ReturnType
);
1451 entry
->EntriesNum
--;
1455 entry
->Entries
[i
- j
].EntryType
= PBK_Private
;
1456 entry
->Entries
[i
- j
].Number
= Priv
->ReturnInt
;
1459 if (Priv
->ReturnType
!= Alcatel_phone
) {
1460 smprintf(s
,"WARNING: Received unexpected type %02X for field 7, ignoring\n", Priv
->ReturnType
);
1461 entry
->EntriesNum
--;
1465 entry
->Entries
[i
- j
].EntryType
= PBK_Number_Work
;
1466 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1469 if (Priv
->ReturnType
!= Alcatel_phone
) {
1470 smprintf(s
,"WARNING: Received unexpected type %02X for field 8, ignoring\n", Priv
->ReturnType
);
1471 entry
->EntriesNum
--;
1475 entry
->Entries
[i
- j
].EntryType
= PBK_Number_General
;
1476 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1479 if (Priv
->ReturnType
!= Alcatel_phone
) {
1480 smprintf(s
,"WARNING: Received unexpected type %02X for field 9, ignoring\n", Priv
->ReturnType
);
1481 entry
->EntriesNum
--;
1485 entry
->Entries
[i
- j
].EntryType
= PBK_Number_Fax
;
1486 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1489 if (Priv
->ReturnType
!= Alcatel_phone
) {
1490 smprintf(s
,"WARNING: Received unexpected type %02X for field 10, ignoring\n", Priv
->ReturnType
);
1491 entry
->EntriesNum
--;
1495 entry
->Entries
[i
- j
].EntryType
= PBK_Number_Other
;
1496 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1499 if (Priv
->ReturnType
!= Alcatel_phone
) {
1500 smprintf(s
,"WARNING: Received unexpected type %02X for field 11, ignoring\n", Priv
->ReturnType
);
1501 entry
->EntriesNum
--;
1505 entry
->Entries
[i
- j
].EntryType
= PBK_Number_Pager
;
1506 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1509 if (Priv
->ReturnType
!= Alcatel_phone
) {
1510 smprintf(s
,"WARNING: Received unexpected type %02X for field 12, ignoring\n", Priv
->ReturnType
);
1511 entry
->EntriesNum
--;
1515 entry
->Entries
[i
- j
].EntryType
= PBK_Number_Mobile
;
1516 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1519 if (Priv
->ReturnType
!= Alcatel_phone
) {
1520 smprintf(s
,"WARNING: Received unexpected type %02X for field 13, ignoring\n", Priv
->ReturnType
);
1521 entry
->EntriesNum
--;
1525 entry
->Entries
[i
- j
].EntryType
= PBK_Number_Home
;
1526 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1529 if (Priv
->ReturnType
!= Alcatel_string
) {
1530 smprintf(s
,"WARNING: Received unexpected type %02X for field 14, ignoring\n", Priv
->ReturnType
);
1531 entry
->EntriesNum
--;
1535 entry
->Entries
[i
- j
].EntryType
= PBK_Text_Email
;
1536 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1539 if (Priv
->ReturnType
!= Alcatel_string
) {
1540 smprintf(s
,"WARNING: Received unexpected type %02X for field 15, ignoring\n", Priv
->ReturnType
);
1541 entry
->EntriesNum
--;
1545 entry
->Entries
[i
- j
].EntryType
= PBK_Text_Email2
;
1546 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1549 if (Priv
->ReturnType
!= Alcatel_string
) {
1550 smprintf(s
,"WARNING: Received unexpected type %02X for field 16, ignoring\n", Priv
->ReturnType
);
1551 entry
->EntriesNum
--;
1555 entry
->Entries
[i
- j
].EntryType
= PBK_Text_StreetAddress
;
1556 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1559 if (Priv
->ReturnType
!= Alcatel_string
) {
1560 smprintf(s
,"WARNING: Received unexpected type %02X for field 17, ignoring\n", Priv
->ReturnType
);
1561 entry
->EntriesNum
--;
1565 entry
->Entries
[i
- j
].EntryType
= PBK_Text_City
;
1566 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1569 if (Priv
->ReturnType
!= Alcatel_string
) {
1570 smprintf(s
,"WARNING: Received unexpected type %02X for field 18, ignoring\n", Priv
->ReturnType
);
1571 entry
->EntriesNum
--;
1575 entry
->Entries
[i
- j
].EntryType
= PBK_Text_State
;
1576 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1579 if (Priv
->ReturnType
!= Alcatel_string
) {
1580 smprintf(s
,"WARNING: Received unexpected type %02X for field 19, ignoring\n", Priv
->ReturnType
);
1581 entry
->EntriesNum
--;
1585 entry
->Entries
[i
- j
].EntryType
= PBK_Text_Zip
;
1586 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1589 if (Priv
->ReturnType
!= Alcatel_string
) {
1590 smprintf(s
,"WARNING: Received unexpected type %02X for field 20, ignoring\n", Priv
->ReturnType
);
1591 entry
->EntriesNum
--;
1595 entry
->Entries
[i
- j
].EntryType
= PBK_Text_Country
;
1596 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1599 if (Priv
->ReturnType
!= Alcatel_string
) {
1600 smprintf(s
,"WARNING: Received unexpected type %02X for field 21, ignoring\n", Priv
->ReturnType
);
1601 entry
->EntriesNum
--;
1605 entry
->Entries
[i
- j
].EntryType
= PBK_Text_Custom1
;
1606 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1609 if (Priv
->ReturnType
!= Alcatel_string
) {
1610 smprintf(s
,"WARNING: Received unexpected type %02X for field 22, ignoring\n", Priv
->ReturnType
);
1611 entry
->EntriesNum
--;
1615 entry
->Entries
[i
- j
].EntryType
= PBK_Text_Custom2
;
1616 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1619 if (Priv
->ReturnType
!= Alcatel_string
) {
1620 smprintf(s
,"WARNING: Received unexpected type %02X for field 23, ignoring\n", Priv
->ReturnType
);
1621 entry
->EntriesNum
--;
1625 entry
->Entries
[i
- j
].EntryType
= PBK_Text_Custom3
;
1626 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1629 if (Priv
->ReturnType
!= Alcatel_string
) {
1630 smprintf(s
,"WARNING: Received unexpected type %02X for field 24, ignoring\n", Priv
->ReturnType
);
1631 entry
->EntriesNum
--;
1635 entry
->Entries
[i
- j
].EntryType
= PBK_Text_Custom4
;
1636 CopyUnicodeString(entry
->Entries
[i
- j
].Text
, Priv
->ReturnString
);
1639 if (Priv
->ReturnType
!= Alcatel_int
) {
1640 smprintf(s
,"WARNING: Received unexpected type %02X for field 25, ignoring\n", Priv
->ReturnType
);
1641 entry
->EntriesNum
--;
1645 if (Priv
->ReturnInt
!= 0) {
1646 entry
->Entries
[i
- j
].EntryType
= PBK_PictureID
;
1647 entry
->Entries
[i
- j
].Number
= Priv
->ReturnInt
;
1649 entry
->EntriesNum
--;
1654 entry
->EntriesNum
--;
1656 smprintf(s
,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv
->CurrentFields
[i
], Priv
->ReturnType
);
1657 switch (Priv
->ReturnType
) {
1659 smprintf(s
, "%d.%d.%d", Priv
->ReturnDateTime
.Day
, Priv
->ReturnDateTime
.Month
, Priv
->ReturnDateTime
.Year
);
1662 smprintf(s
, "%d:%d:%d", Priv
->ReturnDateTime
.Hour
, Priv
->ReturnDateTime
.Minute
, Priv
->ReturnDateTime
.Second
);
1664 case Alcatel_string
:
1666 smprintf(s
, "\"%s\"",DecodeUnicodeString(Priv
->ReturnString
));
1672 smprintf(s
, "%d", Priv
->ReturnInt
);
1680 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
1681 return ATGEN_GetMemory(s
, entry
);
1685 static GSM_Error
ALCATEL_GetNextMemory(GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
, bool start
)
1688 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
1690 if (entry
->MemoryType
== GMT_ME
) {
1691 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeContacts
, 0))!= GE_NONE
) return error
;
1692 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
1693 if (Priv
->ContactsItemsCount
== 0) return GE_EMPTY
;
1695 if (start
) entry
->Location
= Priv
->ContactsItems
[0];
1696 else if ((error
= ALCATEL_GetNextId(s
, &(entry
->Location
))) != GE_NONE
) return error
;
1698 return ALCATEL_GetMemory(s
, entry
);
1700 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
1701 return ATGEN_GetNextMemory(s
, entry
, start
);
1705 static GSM_Error
ALCATEL_AddMemory(GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
)
1708 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
1709 int NamePosition
= -1;
1710 bool NameSet
= false;
1714 if (entry
->MemoryType
== GMT_ME
) {
1715 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeContacts
, 0))!= GE_NONE
) return error
;
1716 if ((error
= ALCATEL_GoToBinaryState(s
, StateEdit
, TypeContacts
, 0))!= GE_NONE
) return error
;
1717 for (i
= 0; i
< entry
->EntriesNum
; i
++) {
1718 switch (entry
->Entries
[i
].EntryType
) {
1719 case PBK_Number_General
:
1720 if ((error
= ALCATEL_CreateField(s
, Alcatel_phone
, 8, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1722 case PBK_Number_Mobile
:
1723 if ((error
= ALCATEL_CreateField(s
, Alcatel_phone
, 12, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1725 case PBK_Number_Work
:
1726 if ((error
= ALCATEL_CreateField(s
, Alcatel_phone
, 7, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1728 case PBK_Number_Fax
:
1729 if ((error
= ALCATEL_CreateField(s
, Alcatel_phone
, 9, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1731 case PBK_Number_Home
:
1732 if ((error
= ALCATEL_CreateField(s
, Alcatel_phone
, 13, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1734 case PBK_Number_Pager
:
1735 if ((error
= ALCATEL_CreateField(s
, Alcatel_phone
, 11, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1737 case PBK_Number_Other
:
1738 if ((error
= ALCATEL_CreateField(s
, Alcatel_phone
, 10, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1741 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 4, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1743 case PBK_Text_Email
:
1744 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 14, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1746 case PBK_Text_Email2
:
1747 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 15, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1749 case PBK_Text_LastName
:
1750 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 0, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1753 case PBK_Text_FirstName
:
1754 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 1, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1757 case PBK_Text_Company
:
1758 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 2, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1760 case PBK_Text_JobTitle
:
1761 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 3, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1764 if ((error
= ALCATEL_CreateField(s
, Alcatel_byte
, 5, &(entry
->Entries
[i
].Number
))) != GE_NONE
) return error
;
1767 if ((error
= ALCATEL_CreateField(s
, Alcatel_bool
, 6, &(entry
->Entries
[i
].Number
))) != GE_NONE
) return error
;
1769 case PBK_Text_StreetAddress
:
1770 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 16, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1773 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 17, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1775 case PBK_Text_State
:
1776 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 18, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1779 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 19, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1781 case PBK_Text_Country
:
1782 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 20, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1784 case PBK_Text_Custom1
:
1785 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 21, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1787 case PBK_Text_Custom2
:
1788 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 22, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1790 case PBK_Text_Custom3
:
1791 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 23, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1793 case PBK_Text_Custom4
:
1794 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 24, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1797 if (s
->Phone
.Data
.Priv
.ALCATEL
.ProtocolVersion
== V_1_1
) {
1798 if ((error
= ALCATEL_CreateField(s
, Alcatel_int
, 25, &(entry
->Entries
[i
].Number
))) != GE_NONE
) return error
;
1800 smprintf(s
,"WARNING: Ignoring entry %d, not supported by phone\n", entry
->Entries
[i
].EntryType
);
1804 case PBK_Text_Name
: NamePosition
= i
; break;
1805 /* Following fields are not supported: */
1807 case PBK_Caller_Group
:
1808 case PBK_RingtoneID
:
1809 case PBK_Text_Postal
:
1811 smprintf(s
,"WARNING: Ignoring entry %d, not supported by phone\n", entry
->Entries
[i
].EntryType
);
1815 if (NamePosition
!= -1) {
1817 smprintf(s
,"WARNING: Ignoring name, not supported by phone\n");
1819 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 1, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1822 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeContacts
, 0))!= GE_NONE
) return error
;
1823 entry
->Location
= Priv
->CommitedRecord
;
1825 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
1828 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
1829 return ATGEN_AddMemory(s
, entry
);
1833 static GSM_Error
ALCATEL_SetMemory(GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
)
1836 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
1837 int NamePosition
= -1;
1838 bool NameSet
= false;
1840 bool UpdatedFields
[26];
1842 if (entry
->Location
== 0) return GE_INVALIDLOCATION
;
1844 if (entry
->MemoryType
== GMT_ME
) {
1845 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeContacts
, 0))!= GE_NONE
) return error
;
1846 /* Save modified entry */
1847 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
1848 if ((error
= ALCATEL_IsIdAvailable(s
, entry
->Location
))!= GE_NONE
) {
1849 /* Entry doesn't exist, we will create new one */
1850 return ALCATEL_AddMemory(s
, entry
);
1852 /* Get fields for current item */
1853 if ((error
= ALCATEL_GetFields(s
, entry
->Location
))!= GE_NONE
) return error
;
1855 for (i
= 0; i
< 26; i
++) { UpdatedFields
[i
] = false; }
1857 if ((error
= ALCATEL_GoToBinaryState(s
, StateEdit
, TypeContacts
, entry
->Location
))!= GE_NONE
) return error
;
1858 for (i
= 0; i
< entry
->EntriesNum
; i
++) {
1859 switch (entry
->Entries
[i
].EntryType
) {
1860 case PBK_Number_General
:
1861 UpdatedFields
[8] = true;
1862 if ((error
= ALCATEL_UpdateField(s
, Alcatel_phone
, entry
->Location
, 8, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1864 case PBK_Number_Mobile
:
1865 UpdatedFields
[12] = true;
1866 if ((error
= ALCATEL_UpdateField(s
, Alcatel_phone
, entry
->Location
, 12, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1868 case PBK_Number_Work
:
1869 UpdatedFields
[7] = true;
1870 if ((error
= ALCATEL_UpdateField(s
, Alcatel_phone
, entry
->Location
, 7, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1872 case PBK_Number_Fax
:
1873 UpdatedFields
[9] = true;
1874 if ((error
= ALCATEL_UpdateField(s
, Alcatel_phone
, entry
->Location
, 9, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1876 case PBK_Number_Home
:
1877 UpdatedFields
[13] = true;
1878 if ((error
= ALCATEL_UpdateField(s
, Alcatel_phone
, entry
->Location
, 13, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1880 case PBK_Number_Pager
:
1881 UpdatedFields
[11] = true;
1882 if ((error
= ALCATEL_UpdateField(s
, Alcatel_phone
, entry
->Location
, 11, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1884 case PBK_Number_Other
:
1885 UpdatedFields
[10] = true;
1886 if ((error
= ALCATEL_UpdateField(s
, Alcatel_phone
, entry
->Location
, 10, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1889 UpdatedFields
[4] = true;
1890 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 4, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1892 case PBK_Text_Email
:
1893 UpdatedFields
[14] = true;
1894 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 14, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1896 case PBK_Text_Email2
:
1897 UpdatedFields
[15] = true;
1898 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 15, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1900 case PBK_Text_LastName
:
1901 UpdatedFields
[0] = true;
1902 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 0, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
; NameSet
= true;
1904 case PBK_Text_FirstName
:
1905 UpdatedFields
[1] = true;
1906 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 1, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
; NameSet
= true;
1908 case PBK_Text_Company
:
1909 UpdatedFields
[2] = true;
1910 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 2, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1912 case PBK_Text_JobTitle
:
1913 UpdatedFields
[3] = true;
1914 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 3, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1917 UpdatedFields
[5] = true;
1918 if ((error
= ALCATEL_UpdateField(s
, Alcatel_byte
, entry
->Location
, 5, &(entry
->Entries
[i
].Number
))) != GE_NONE
) return error
;
1921 UpdatedFields
[6] = true;
1922 if ((error
= ALCATEL_UpdateField(s
, Alcatel_bool
, entry
->Location
, 6, &(entry
->Entries
[i
].Number
))) != GE_NONE
) return error
;
1924 case PBK_Text_StreetAddress
:
1925 UpdatedFields
[16] = true;
1926 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 16, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1929 UpdatedFields
[17] = true;
1930 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 17, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1932 case PBK_Text_State
:
1933 UpdatedFields
[18] = true;
1934 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 18, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1937 UpdatedFields
[19] = true;
1938 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 19, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1940 case PBK_Text_Country
:
1941 UpdatedFields
[20] = true;
1942 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 20, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1944 case PBK_Text_Custom1
:
1945 UpdatedFields
[21] = true;
1946 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 21, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1948 case PBK_Text_Custom2
:
1949 UpdatedFields
[22] = true;
1950 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 22, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1952 case PBK_Text_Custom3
:
1953 UpdatedFields
[23] = true;
1954 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 23, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1956 case PBK_Text_Custom4
:
1957 UpdatedFields
[24] = true;
1958 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 24, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
1961 if (s
->Phone
.Data
.Priv
.ALCATEL
.ProtocolVersion
== V_1_1
) {
1962 UpdatedFields
[25] = true;
1963 if ((error
= ALCATEL_UpdateField(s
, Alcatel_int
, entry
->Location
, 25, &(entry
->Entries
[i
].Number
))) != GE_NONE
) return error
;
1965 smprintf(s
,"WARNING: Ignoring entry %d, not supported by phone\n", entry
->Entries
[i
].EntryType
);
1969 case PBK_Text_Name
: NamePosition
= i
; break;
1970 /* Following fields are not supported: */
1972 case PBK_Caller_Group
:
1973 case PBK_RingtoneID
:
1974 case PBK_Text_Postal
:
1976 smprintf(s
,"WARNING: Ignoring entry %d, not supported by phone\n", entry
->Entries
[i
].EntryType
);
1980 if (NamePosition
!= -1) {
1982 smprintf(s
,"WARNING: Ignoring name, not supported by phone\n");
1984 UpdatedFields
[1] = true; if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, entry
->Location
, 1, entry
->Entries
[i
].Text
)) != GE_NONE
) return error
;
1987 /* If we didn't update some field, we have to delete it... */
1988 for (i
=0; i
<Priv
->CurrentFieldsCount
; i
++) {
1989 if (!UpdatedFields
[Priv
->CurrentFields
[i
]]) if ((error
= ALCATEL_DeleteField(s
, entry
->Location
, Priv
->CurrentFields
[i
])) != GE_NONE
) return error
;
1991 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeContacts
, 0))!= GE_NONE
) return error
;
1992 entry
->Location
= Priv
->CommitedRecord
;
1995 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
1996 return ATGEN_SetMemory(s
, entry
);
2000 static GSM_Error
ALCATEL_DeleteMemory(GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
)
2004 if (entry
->MemoryType
== GMT_ME
) {
2005 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeContacts
, 0))!= GE_NONE
) return error
;
2006 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
2007 if ((error
= ALCATEL_IsIdAvailable(s
, entry
->Location
))!= GE_NONE
) {
2008 /* Entry was empty => no error */
2011 /* Do real delete */
2012 error
= ALCATEL_DeleteItem(s
, entry
->Location
);
2013 if (error
!= GE_NONE
) return error
;
2016 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeContacts
, 0))!= GE_NONE
) return error
;
2017 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
2021 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2022 return ATGEN_DeleteMemory(s
, entry
);
2026 static GSM_Error
ALCATEL_DeleteAllMemory(GSM_StateMachine
*s
, GSM_MemoryType type
)
2029 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
2032 if (type
== GMT_ME
) {
2033 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeContacts
, 0))!= GE_NONE
) return error
;
2034 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
2036 for (i
=0; i
<Priv
->ContactsItemsCount
; i
++) {
2037 error
= ALCATEL_DeleteItem(s
, Priv
->ContactsItems
[i
]);
2038 if (error
!= GE_NONE
) return error
;
2042 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeContacts
, 0))!= GE_NONE
) return error
;
2043 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
2047 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2048 return ATGEN_DeleteAllMemory(s
, type
);
2052 static GSM_Error
ALCATEL_GetSMSC(GSM_StateMachine
*s
, GSM_SMSC
*smsc
)
2056 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2057 return ATGEN_GetSMSC(s
, smsc
);
2061 static GSM_Error
ALCATEL_GetMemoryStatus(GSM_StateMachine
*s
, GSM_MemoryStatus
*Status
)
2063 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
2066 if (Status
->MemoryType
== GMT_ME
) {
2067 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeContacts
, 0))!= GE_NONE
) return error
;
2068 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
2069 Status
->Used
= Priv
->ContactsItemsCount
;
2070 Status
->Free
= ALCATEL_FREE_MEMORY
;
2073 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2074 return ATGEN_GetMemoryStatus(s
, Status
);
2078 static GSM_Error
ALCATEL_GetSMS(GSM_StateMachine
*s
, GSM_MultiSMSMessage
*sms
)
2082 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2083 return ATGEN_GetSMS(s
, sms
);
2086 static GSM_Error
ALCATEL_DeleteSMS(GSM_StateMachine
*s
, GSM_SMSMessage
*sms
)
2090 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2091 return ATGEN_DeleteSMS(s
, sms
);
2094 static GSM_Error
ALCATEL_AddSMS(GSM_StateMachine
*s
, GSM_SMSMessage
*sms
)
2098 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2099 return ATGEN_AddSMS(s
, sms
);
2102 static GSM_Error
ALCATEL_GetBatteryCharge(GSM_StateMachine
*s
, GSM_BatteryCharge
*bat
)
2106 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2107 return ATGEN_GetBatteryCharge(s
, bat
);
2110 static GSM_Error
ALCATEL_GetSignalStrength(GSM_StateMachine
*s
, GSM_SignalQuality
*sig
)
2114 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2115 return ATGEN_GetSignalQuality(s
, sig
);
2118 static GSM_Error
ALCATEL_GetSMSFolders(GSM_StateMachine
*s
, GSM_SMSFolders
*folders
)
2122 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2123 return ATGEN_GetSMSFolders(s
, folders
);
2126 static GSM_Error
ALCATEL_GetNextSMS(GSM_StateMachine
*s
, GSM_MultiSMSMessage
*sms
, bool start
)
2130 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2131 return ATGEN_GetNextSMS(s
, sms
, start
);
2134 static GSM_Error
ALCATEL_GetSMSStatus(GSM_StateMachine
*s
, GSM_SMSMemoryStatus
*status
)
2138 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2139 return ATGEN_GetSMSStatus(s
, status
);
2142 static GSM_Error
ALCATEL_DialVoice(GSM_StateMachine
*s
, char *number
, GSM_CallShowNumber ShowNumber
)
2146 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2147 return ATGEN_DialVoice(s
, number
, ShowNumber
);
2150 static GSM_Error
ALCATEL_AnswerCall(GSM_StateMachine
*s
, int ID
, bool all
)
2154 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2155 return ATGEN_AnswerCall(s
,ID
,all
);
2158 static GSM_Error
ALCATEL_GetNetworkInfo(GSM_StateMachine
*s
, GSM_NetworkInfo
*netinfo
)
2162 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2163 return ATGEN_GetNetworkInfo(s
, netinfo
);
2166 static GSM_Error
ALCATEL_GetDisplayStatus(GSM_StateMachine
*s
, GSM_DisplayFeatures
*features
)
2170 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2171 return ATGEN_GetDisplayStatus(s
, features
);
2174 static GSM_Error
ALCATEL_SetAutoNetworkLogin(GSM_StateMachine
*s
)
2178 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2179 return ATGEN_SetAutoNetworkLogin(s
);
2182 static GSM_Error
ALCATEL_PressKey(GSM_StateMachine
*s
, GSM_KeyCode Key
, bool Press
)
2186 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2187 return ATGEN_PressKey(s
, Key
, Press
);
2190 static GSM_Error
ALCATEL_Reset(GSM_StateMachine
*s
, bool hard
)
2194 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2195 return ATGEN_Reset(s
, hard
);
2198 static GSM_Error
ALCATEL_CancelCall(GSM_StateMachine
*s
, int ID
, bool all
)
2202 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2203 return ATGEN_CancelCall(s
,ID
,all
);
2206 static GSM_Error
ALCATEL_SendSMS(GSM_StateMachine
*s
, GSM_SMSMessage
*sms
)
2210 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2211 return ATGEN_SendSMS(s
, sms
);
2214 static GSM_Error
ALCATEL_SetDateTime(GSM_StateMachine
*s
, GSM_DateTime
*date_time
)
2218 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2219 return ATGEN_SetDateTime(s
, date_time
);
2222 static GSM_Error
ALCATEL_SetSMSC(GSM_StateMachine
*s
, GSM_SMSC
*smsc
)
2226 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2227 return ATGEN_SetSMSC(s
, smsc
);
2230 static GSM_Error
ALCATEL_EnterSecurityCode(GSM_StateMachine
*s
, GSM_SecurityCode Code
)
2234 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2235 return ATGEN_EnterSecurityCode(s
, Code
);
2238 static GSM_Error
ALCATEL_GetSecurityStatus(GSM_StateMachine
*s
, GSM_SecurityCodeType
*Status
)
2242 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2243 return ATGEN_GetSecurityStatus(s
, Status
);
2246 static GSM_Error
ALCATEL_ResetPhoneSettings(GSM_StateMachine
*s
, GSM_ResetSettingsType Type
)
2250 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2251 return ATGEN_ResetPhoneSettings(s
, Type
);
2254 static GSM_Error
ALCATEL_SendDTMF(GSM_StateMachine
*s
, char *sequence
)
2258 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2259 return ATGEN_SendDTMF(s
, sequence
);
2262 static GSM_Error
ALCATEL_GetSIMIMSI(GSM_StateMachine
*s
, char *IMSI
)
2266 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
2267 return ATGEN_GetSIMIMSI(s
, IMSI
);
2270 static GSM_Error
ALCATEL_GetCalendarStatus(GSM_StateMachine
*s
, GSM_CalendarStatus
*status
)
2273 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
2277 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2278 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
2280 status
->Used
= Priv
->CalendarItemsCount
;
2284 static GSM_Error
ALCATEL_GetCalendar(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
)
2287 GSM_DateTime
*dt
= NULL
;
2288 GSM_DateTime evdate
;
2289 bool evdateused
= true;
2290 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
2294 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2295 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
2296 if ((error
= ALCATEL_IsIdAvailable(s
, Note
->Location
))!= GE_NONE
) {
2297 Note
->EntriesNum
= 0;
2300 if ((error
= ALCATEL_GetFields(s
, Note
->Location
))!= GE_NONE
) return error
;
2302 Note
->EntriesNum
= Priv
->CurrentFieldsCount
;
2304 for (i
=0; i
< Priv
->CurrentFieldsCount
; i
++) {
2305 if ((error
= ALCATEL_GetFieldValue(s
, Note
->Location
, Priv
->CurrentFields
[i
]))!= GE_NONE
) return error
;
2306 switch (Priv
->CurrentFields
[i
]) {
2308 if (Priv
->ReturnType
!= Alcatel_date
) {
2309 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2314 if (!CheckDate(&(Priv
->ReturnDateTime
))) {
2315 smprintf(s
,"WARNING: Invalid date in phone, ignoring\n");
2322 evdate
= Priv
->ReturnDateTime
;
2326 if (Priv
->ReturnType
!= Alcatel_time
) {
2327 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2332 if (!CheckTime(&(Priv
->ReturnDateTime
))) {
2333 smprintf(s
,"WARNING: Invalid time in phone, ignoring\n");
2338 Note
->Entries
[i
-j
].EntryType
= CAL_START_DATETIME
;
2339 Note
->Entries
[i
-j
].Date
= Priv
->ReturnDateTime
;
2340 Note
->Entries
[i
-j
].Date
.Day
= evdate
.Day
;
2341 Note
->Entries
[i
-j
].Date
.Month
= evdate
.Month
;
2342 Note
->Entries
[i
-j
].Date
.Year
= evdate
.Year
;
2343 Note
->Entries
[i
-j
].Date
.Timezone
= evdate
.Timezone
;
2347 if (Priv
->ReturnType
!= Alcatel_time
) {
2348 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2353 if (!CheckTime(&(Priv
->ReturnDateTime
))) {
2354 smprintf(s
,"WARNING: Invalid time in phone, ignoring\n");
2359 Note
->Entries
[i
-j
].EntryType
= CAL_END_DATETIME
;
2360 Note
->Entries
[i
-j
].Date
= Priv
->ReturnDateTime
;
2361 Note
->Entries
[i
-j
].Date
.Day
= evdate
.Day
;
2362 Note
->Entries
[i
-j
].Date
.Month
= evdate
.Month
;
2363 Note
->Entries
[i
-j
].Date
.Year
= evdate
.Year
;
2364 Note
->Entries
[i
-j
].Date
.Timezone
= evdate
.Timezone
;
2368 if (Priv
->ReturnType
!= Alcatel_date
) {
2369 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2374 if (!CheckDate(&(Priv
->ReturnDateTime
))) {
2375 smprintf(s
,"WARNING: Invalid date in phone, ignoring\n");
2381 Note
->Entries
[i
-j
].EntryType
= CAL_ALARM_DATETIME
;
2382 Note
->Entries
[i
-j
].Date
= Priv
->ReturnDateTime
;
2383 dt
= &(Note
->Entries
[i
-j
].Date
);
2387 dt
->Day
= Priv
->ReturnDateTime
.Day
;
2388 dt
->Month
= Priv
->ReturnDateTime
.Month
;
2389 dt
->Year
= Priv
->ReturnDateTime
.Year
;
2390 dt
->Timezone
= Priv
->ReturnDateTime
.Timezone
;
2395 if (Priv
->ReturnType
!= Alcatel_time
) {
2396 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2401 if (!CheckTime(&(Priv
->ReturnDateTime
))) {
2402 smprintf(s
,"WARNING: Invalid time in phone, ignoring\n");
2408 Note
->Entries
[i
-j
].EntryType
= CAL_ALARM_DATETIME
;
2409 Note
->Entries
[i
-j
].Date
= Priv
->ReturnDateTime
;
2410 dt
= &(Note
->Entries
[i
-j
].Date
);
2414 dt
->Hour
= Priv
->ReturnDateTime
.Hour
;
2415 dt
->Minute
= Priv
->ReturnDateTime
.Minute
;
2416 dt
->Second
= Priv
->ReturnDateTime
.Second
;
2421 if (Priv
->ReturnType
!= Alcatel_string
) {
2422 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2427 Note
->Entries
[i
-j
].EntryType
= CAL_TEXT
;
2428 CopyUnicodeString(Note
->Entries
[i
-j
].Text
, Priv
->ReturnString
);
2431 if (Priv
->ReturnType
!= Alcatel_bool
) {
2432 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2437 Note
->Entries
[i
-j
].EntryType
= CAL_PRIVATE
;
2438 Note
->Entries
[i
-j
].Number
= Priv
->ReturnInt
;
2441 if (Priv
->ReturnType
!= Alcatel_enum
) {
2442 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2447 switch (Priv
->ReturnInt
) {
2449 Note
->Type
= GCN_MEETING
;
2452 Note
->Type
= GCN_BIRTHDAY
;
2455 Note
->Type
= GCN_CALL
;
2458 Note
->Type
= GCN_ALARM
;
2461 Note
->Type
= GCN_DAILY_ALARM
;
2464 /* I'd call this repeating event, but it makes no sense creating one more type ... */
2465 Note
->Type
= GCN_MEETING
;
2468 smprintf(s
,"WARNING: Received unknown event type %02X!\n", Priv
->ReturnInt
);
2475 if (Priv
->ReturnType
!= Alcatel_int
) {
2476 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2481 /* 0xffffffff indicates that there is phone (BF5), 0 means none (BF5, BE5)*/
2482 if (Priv
->ReturnInt
== 0xffffffff || Priv
->ReturnInt
== 0) {
2486 Note
->Entries
[i
-j
].EntryType
= CAL_CONTACTID
;
2487 Note
->Entries
[i
-j
].Number
= Priv
->ReturnInt
;
2491 if (Priv
->ReturnType
!= Alcatel_phone
) {
2492 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2497 Note
->Entries
[i
-j
].EntryType
= CAL_PHONE
;
2498 CopyUnicodeString(Note
->Entries
[i
-j
].Text
, Priv
->ReturnString
);
2501 if (Priv
->ReturnType
!= Alcatel_byte
) {
2502 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2507 Note
->Entries
[i
-j
].EntryType
= CAL_REPEAT_DAYOFWEEK
;
2508 Note
->Entries
[i
-j
].Number
= Priv
->ReturnInt
;
2511 if (Priv
->ReturnType
!= Alcatel_byte
) {
2512 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2517 Note
->Entries
[i
-j
].EntryType
= CAL_REPEAT_DAY
;
2518 Note
->Entries
[i
-j
].Number
= Priv
->ReturnInt
;
2521 if (Priv
->ReturnType
!= Alcatel_byte
) {
2522 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2527 Note
->Entries
[i
-j
].EntryType
= CAL_REPEAT_WEEKOFMONTH
;
2528 Note
->Entries
[i
-j
].Number
= Priv
->ReturnInt
;
2531 if (Priv
->ReturnType
!= Alcatel_byte
) {
2532 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2537 Note
->Entries
[i
-j
].EntryType
= CAL_REPEAT_MONTH
;
2538 Note
->Entries
[i
-j
].Number
= Priv
->ReturnInt
;
2541 if (Priv
->ReturnType
!= Alcatel_byte
) {
2542 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2547 /* In BF5 birthday has frequency = 1 */
2548 if (Note
->Type
== GCN_BIRTHDAY
) {
2552 Note
->Entries
[i
-j
].EntryType
= CAL_REPEAT_FREQUENCY
;
2553 Note
->Entries
[i
-j
].Number
= Priv
->ReturnInt
;
2557 if (Priv
->ReturnType
!= Alcatel_date
) {
2558 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2563 if (!CheckDate(&(Priv
->ReturnDateTime
))) {
2564 smprintf(s
,"WARNING: Invalid date in phone, ignoring\n");
2569 Note
->Entries
[i
-j
].EntryType
= CAL_REPEAT_STARTDATE
;
2570 Note
->Entries
[i
-j
].Date
= Priv
->ReturnDateTime
;
2573 if (Priv
->ReturnType
!= Alcatel_date
) {
2574 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2579 if (!CheckDate(&(Priv
->ReturnDateTime
))) {
2580 smprintf(s
,"WARNING: Invalid date in phone, ignoring\n");
2585 Note
->Entries
[i
-j
].EntryType
= CAL_REPEAT_STOPDATE
;
2586 Note
->Entries
[i
-j
].Date
= Priv
->ReturnDateTime
;
2589 if (Priv
->ReturnType
!= Alcatel_date
) {
2590 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2595 if (!CheckDate(&(Priv
->ReturnDateTime
))) {
2596 smprintf(s
,"WARNING: Invalid date in phone, ignoring\n");
2601 /* This entry had always same value as the 3rd (alarm date) */
2606 if (Priv
->ReturnType
!= Alcatel_time
) {
2607 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
2612 if (!CheckTime(&(Priv
->ReturnDateTime
))) {
2613 smprintf(s
,"WARNING: Invalid time in phone, ignoring\n");
2618 /* This entry had always same value as the 4th (alarm time) */
2625 smprintf(s
,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv
->CurrentFields
[i
], Priv
->ReturnType
);
2626 switch (Priv
->ReturnType
) {
2628 smprintf(s
, "%d.%d.%d", Priv
->ReturnDateTime
.Day
, Priv
->ReturnDateTime
.Month
, Priv
->ReturnDateTime
.Year
);
2631 smprintf(s
, "%d:%d:%d", Priv
->ReturnDateTime
.Hour
, Priv
->ReturnDateTime
.Minute
, Priv
->ReturnDateTime
.Second
);
2633 case Alcatel_string
:
2635 smprintf(s
, "\"%s\"",DecodeUnicodeString(Priv
->ReturnString
));
2641 smprintf(s
, "%d", Priv
->ReturnInt
);
2647 /* The event didn't have start/stop time -> we need only date */
2650 Note
->Entries
[i
-j
].EntryType
= CAL_START_DATETIME
;
2651 Note
->Entries
[i
-j
].Date
= evdate
;
2656 static GSM_Error
ALCATEL_GetNextCalendar(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
, bool start
)
2659 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
2661 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2662 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
2663 if (Priv
->CalendarItemsCount
== 0) return GE_EMPTY
;
2665 if (start
) Note
->Location
= Priv
->CalendarItems
[0];
2666 else if ((error
= ALCATEL_GetNextId(s
, &(Note
->Location
))) != GE_NONE
) return error
;
2668 return ALCATEL_GetCalendar(s
, Note
);
2672 static GSM_Error
ALCATEL_DeleteCalendar(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
)
2676 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2677 /* Delete Calendar */
2678 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
2679 if ((error
= ALCATEL_IsIdAvailable(s
, Note
->Location
))!= GE_NONE
) {
2680 /* Entry was empty => no error */
2683 error
= ALCATEL_DeleteItem(s
, Note
->Location
);
2684 if (error
!= GE_NONE
) return error
;
2686 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2687 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
2692 static GSM_Error
ALCATEL_AddCalendar(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
)
2696 bool contact_set
= false;
2697 bool phone_set
= false;
2698 bool date_set
= false;
2699 bool repeating
= false;
2701 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
2703 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2704 if ((error
= ALCATEL_GoToBinaryState(s
, StateEdit
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2706 for (i
= 0; i
< Note
->EntriesNum
; i
++) {
2707 switch (Note
->Entries
[i
].EntryType
) {
2708 case CAL_START_DATETIME
:
2710 if ((error
= ALCATEL_CreateField(s
, Alcatel_date
, 0, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2713 if ((error
= ALCATEL_CreateField(s
, Alcatel_time
, 1, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2715 case CAL_END_DATETIME
:
2717 if ((error
= ALCATEL_CreateField(s
, Alcatel_date
, 0, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2720 if ((error
= ALCATEL_CreateField(s
, Alcatel_time
, 2, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2722 case CAL_ALARM_DATETIME
:
2723 if ((error
= ALCATEL_CreateField(s
, Alcatel_date
, 3, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2724 if ((error
= ALCATEL_CreateField(s
, Alcatel_time
, 4, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2725 if (Note
->Type
== GCN_ALARM
|| Note
->Type
== GCN_DAILY_ALARM
) {
2726 if ((error
= ALCATEL_CreateField(s
, Alcatel_date
, 20, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2727 if ((error
= ALCATEL_CreateField(s
, Alcatel_time
, 21, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2731 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 5, Note
->Entries
[i
].Text
)) != GE_NONE
) return error
;
2734 if ((error
= ALCATEL_CreateField(s
, Alcatel_bool
, 6, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2737 if ((error
= ALCATEL_CreateField(s
, Alcatel_int
, 8, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2741 if ((error
= ALCATEL_CreateField(s
, Alcatel_phone
, 9, Note
->Entries
[i
].Text
)) != GE_NONE
) return error
;
2744 case CAL_REPEAT_DAYOFWEEK
:
2745 if ((error
= ALCATEL_CreateField(s
, Alcatel_byte
, 10, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2748 case CAL_REPEAT_DAY
:
2749 if ((error
= ALCATEL_CreateField(s
, Alcatel_byte
, 11, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2752 case CAL_REPEAT_WEEKOFMONTH
:
2753 if ((error
= ALCATEL_CreateField(s
, Alcatel_byte
, 12, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2756 case CAL_REPEAT_MONTH
:
2757 if ((error
= ALCATEL_CreateField(s
, Alcatel_byte
, 13, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2760 case CAL_REPEAT_FREQUENCY
:
2761 if ((error
= ALCATEL_CreateField(s
, Alcatel_byte
, 17, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2764 case CAL_REPEAT_STARTDATE
:
2765 if ((error
= ALCATEL_CreateField(s
, Alcatel_date
, 18, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2768 case CAL_REPEAT_STOPDATE
:
2769 if ((error
= ALCATEL_CreateField(s
, Alcatel_date
, 19, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2772 case CAL_SILENT_ALARM_DATETIME
:
2773 case CAL_RECURRANCE
:
2775 smprintf(s
,"WARNING: Ignoring entry %d, not supported by phone\n", Note
->Entries
[i
].EntryType
);
2780 switch (Note
->Type
) {
2790 case GCN_DAILY_ALARM
:
2800 if ((error
= ALCATEL_CreateField(s
, Alcatel_enum
, 7, &val
)) != GE_NONE
) return error
;
2808 if ((error
= ALCATEL_CreateField(s
, Alcatel_int
, 8, &val
)) != GE_NONE
) return error
;
2810 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2811 Note
->Location
= Priv
->CommitedRecord
;
2813 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
2817 static GSM_Error
ALCATEL_SetCalendar(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
)
2821 bool contact_set
= false;
2822 bool phone_set
= false;
2823 bool date_set
= false;
2824 bool repeating
= false;
2826 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
2827 bool UpdatedFields
[22];
2829 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2830 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
2831 if ((error
= ALCATEL_IsIdAvailable(s
, Note
->Location
))!= GE_NONE
) {
2832 /* Entry doesn't exist, we will create new one */
2833 return ALCATEL_AddCalendar(s
, Note
);
2835 /* Get fields for current item */
2836 if ((error
= ALCATEL_GetFields(s
, Note
->Location
))!= GE_NONE
) return error
;
2838 for (i
= 0; i
< 22; i
++) { UpdatedFields
[i
] = false; }
2840 if ((error
= ALCATEL_GoToBinaryState(s
, StateEdit
, TypeCalendar
, Note
->Location
))!= GE_NONE
) return error
;
2842 for (i
= 0; i
< Note
->EntriesNum
; i
++) {
2843 switch (Note
->Entries
[i
].EntryType
) {
2844 case CAL_START_DATETIME
:
2846 UpdatedFields
[0] = true;
2847 if ((error
= ALCATEL_UpdateField(s
, Alcatel_date
, Note
->Location
, 0, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2850 UpdatedFields
[1] = true;
2851 if ((error
= ALCATEL_UpdateField(s
, Alcatel_time
, Note
->Location
, 1, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2853 case CAL_END_DATETIME
:
2855 UpdatedFields
[0] = true;
2856 if ((error
= ALCATEL_UpdateField(s
, Alcatel_date
, Note
->Location
, 0, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2859 UpdatedFields
[2] = true; if ((error
= ALCATEL_UpdateField(s
, Alcatel_time
, Note
->Location
, 2, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2861 case CAL_ALARM_DATETIME
:
2862 UpdatedFields
[3] = true;
2863 if ((error
= ALCATEL_UpdateField(s
, Alcatel_date
, Note
->Location
, 3, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2864 UpdatedFields
[4] = true;
2865 if ((error
= ALCATEL_UpdateField(s
, Alcatel_time
, Note
->Location
, 4, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2866 if (Note
->Type
== GCN_ALARM
|| Note
->Type
== GCN_DAILY_ALARM
) {
2867 UpdatedFields
[20] = true;
2868 if ((error
= ALCATEL_UpdateField(s
, Alcatel_date
, Note
->Location
, 20, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2869 UpdatedFields
[21] = true;
2870 if ((error
= ALCATEL_UpdateField(s
, Alcatel_time
, Note
->Location
, 21, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2874 UpdatedFields
[5] = true;
2875 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, Note
->Location
, 5, Note
->Entries
[i
].Text
)) != GE_NONE
) return error
;
2878 UpdatedFields
[6] = true;
2879 if ((error
= ALCATEL_UpdateField(s
, Alcatel_bool
, Note
->Location
, 6, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2882 UpdatedFields
[8] = true;
2883 if ((error
= ALCATEL_UpdateField(s
, Alcatel_int
, Note
->Location
, 8, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2887 UpdatedFields
[9] = true;
2888 if ((error
= ALCATEL_UpdateField(s
, Alcatel_phone
, Note
->Location
, 9, Note
->Entries
[i
].Text
)) != GE_NONE
) return error
;
2891 case CAL_REPEAT_DAYOFWEEK
:
2892 UpdatedFields
[10] = true;
2893 if ((error
= ALCATEL_UpdateField(s
, Alcatel_byte
, Note
->Location
, 10, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2896 case CAL_REPEAT_DAY
:
2897 UpdatedFields
[11] = true;
2898 if ((error
= ALCATEL_UpdateField(s
, Alcatel_byte
, Note
->Location
, 11, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2901 case CAL_REPEAT_WEEKOFMONTH
:
2902 UpdatedFields
[12] = true;
2903 if ((error
= ALCATEL_UpdateField(s
, Alcatel_byte
, Note
->Location
, 12, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2906 case CAL_REPEAT_MONTH
:
2907 UpdatedFields
[13] = true;
2908 if ((error
= ALCATEL_UpdateField(s
, Alcatel_byte
, Note
->Location
, 13, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2911 case CAL_REPEAT_FREQUENCY
:
2912 UpdatedFields
[17] = true;
2913 if ((error
= ALCATEL_UpdateField(s
, Alcatel_byte
, Note
->Location
, 17, &(Note
->Entries
[i
].Number
))) != GE_NONE
) return error
;
2916 case CAL_REPEAT_STARTDATE
:
2917 UpdatedFields
[18] = true;
2918 if ((error
= ALCATEL_UpdateField(s
, Alcatel_date
, Note
->Location
, 18, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2921 case CAL_REPEAT_STOPDATE
:
2922 UpdatedFields
[19] = true;
2923 if ((error
= ALCATEL_UpdateField(s
, Alcatel_date
, Note
->Location
, 19, &(Note
->Entries
[i
].Date
))) != GE_NONE
) return error
;
2926 case CAL_SILENT_ALARM_DATETIME
:
2927 case CAL_RECURRANCE
:
2929 smprintf(s
,"WARNING: Ignoring entry %d, not supported by phone\n", Note
->Entries
[i
].EntryType
);
2934 switch (Note
->Type
) {
2944 case GCN_DAILY_ALARM
:
2954 UpdatedFields
[7] = true;
2955 if ((error
= ALCATEL_UpdateField(s
, Alcatel_enum
, Note
->Location
, 7, &val
)) != GE_NONE
) return error
;
2963 UpdatedFields
[8] = true;
2964 if ((error
= ALCATEL_UpdateField(s
, Alcatel_int
, Note
->Location
, 8, &val
)) != GE_NONE
) return error
;
2966 /* If we didn't update some field, we have to delete it... */
2967 for (i
=0; i
<Priv
->CurrentFieldsCount
; i
++) {
2968 if (!UpdatedFields
[Priv
->CurrentFields
[i
]]) if ((error
= ALCATEL_DeleteField(s
, Note
->Location
, Priv
->CurrentFields
[i
])) != GE_NONE
) return error
;
2970 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2974 static GSM_Error
ALCATEL_DeleteAllCalendar (GSM_StateMachine
*s
)
2977 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
2980 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2981 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
2983 for (i
=0; i
<Priv
->CalendarItemsCount
; i
++) {
2984 error
= ALCATEL_DeleteItem(s
, Priv
->CalendarItems
[i
]);
2985 if (error
!= GE_NONE
) return error
;
2989 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
2990 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
2996 static GSM_Error
ALCATEL_GetAlarm(GSM_StateMachine
*s
, GSM_Alarm
*alarm
)
2999 GSM_CalendarEntry Note
;
3000 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
3003 bool DateSet
= false;
3004 int alarm_number
= alarm
->Location
;
3005 static GSM_DateTime nulldt
= {0,0,0,0,0,0,0};
3007 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
3008 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
3010 for (i
=0; i
<Priv
->CalendarItemsCount
; i
++) {
3011 if ((error
= ALCATEL_GetFieldValue(s
, Priv
->CalendarItems
[i
], 7))!= GE_NONE
) return error
;
3012 if (Priv
->ReturnType
!= Alcatel_enum
) {
3013 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3016 if (Priv
->ReturnInt
== 4 || Priv
->ReturnInt
== 5) {
3018 if (alarm_number
== 0) {
3025 if (!Found
) return GE_EMPTY
;
3027 Note
.Location
= Priv
->CalendarItems
[i
];
3029 if ((error
= ALCATEL_GetCalendar(s
, &Note
))!= GE_NONE
) return error
;
3031 if (Note
.Type
== GCN_ALARM
) {
3032 alarm
->Repeating
= false;
3034 alarm
->Repeating
= true;
3037 alarm
->Text
[0] = 0; alarm
->Text
[1] = 0;
3040 for (i
= 0; i
< Note
.EntriesNum
; i
++) {
3041 if (Note
.Entries
[i
].EntryType
== CAL_TEXT
) {
3042 CopyUnicodeString(alarm
->Text
, Note
.Entries
[i
].Text
);
3043 } else if (Note
.Entries
[i
].EntryType
== CAL_ALARM_DATETIME
) {
3044 alarm
->DateTime
= Note
.Entries
[i
].Date
;
3049 alarm
->DateTime
= nulldt
;
3056 static GSM_Error
ALCATEL_SetAlarm (GSM_StateMachine
*s
, GSM_Alarm
*alarm
)
3059 GSM_CalendarEntry Note
;
3060 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
3064 int alarm_number
= alarm
->Location
;
3066 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeCalendar
, 0))!= GE_NONE
) return error
;
3067 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
3069 for (i
=0; i
<Priv
->CalendarItemsCount
; i
++) {
3070 if ((error
= ALCATEL_GetFieldValue(s
, Priv
->CalendarItems
[i
], 7))!= GE_NONE
) return error
;
3071 if (Priv
->ReturnType
!= Alcatel_enum
) {
3072 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3075 if (Priv
->ReturnInt
== 4 || Priv
->ReturnInt
== 5) {
3077 if (alarm_number
== 0) {
3085 Note
.Location
= Priv
->CalendarItems
[i
];
3088 Note
.EntriesNum
= 1;
3090 Note
.Entries
[0].EntryType
= CAL_ALARM_DATETIME
;
3091 Note
.Entries
[0].Date
= alarm
->DateTime
;
3093 if (alarm
->Repeating
) {
3094 Note
.Type
= GCN_DAILY_ALARM
;
3095 GSM_GetCurrentDateTime(&dt
);
3096 Note
.Entries
[0].Date
.Day
= dt
.Day
;
3097 Note
.Entries
[0].Date
.Month
= dt
.Month
;
3098 Note
.Entries
[0].Date
.Year
= dt
.Year
;
3100 Note
.Type
= GCN_ALARM
;
3103 if (alarm
->Text
[0] != 0 || alarm
->Text
[1] != 0) {
3105 Note
.Entries
[1].EntryType
= CAL_TEXT
;
3106 CopyUnicodeString(Note
.Entries
[1].Text
, alarm
->Text
);
3110 return ALCATEL_SetCalendar(s
, &Note
);
3112 return ALCATEL_AddCalendar(s
, &Note
);
3117 static GSM_Error
ALCATEL_GetToDoStatus(GSM_StateMachine
*s
, GSM_ToDoStatus
*status
)
3120 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
3124 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeToDo
, 0))!= GE_NONE
) return error
;
3125 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
3127 status
->Used
= Priv
->ToDoItemsCount
;
3131 static GSM_Error
ALCATEL_GetToDo (GSM_StateMachine
*s
, GSM_ToDoEntry
*ToDo
)
3134 GSM_DateTime
*dt
= NULL
;
3135 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
3139 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeToDo
, 0))!= GE_NONE
) return error
;
3140 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
3141 if ((error
= ALCATEL_IsIdAvailable(s
, ToDo
->Location
))!= GE_NONE
) {
3142 ToDo
->EntriesNum
= 0;
3145 if ((error
= ALCATEL_GetFields(s
, ToDo
->Location
))!= GE_NONE
) return error
;
3147 ToDo
->EntriesNum
= Priv
->CurrentFieldsCount
;
3149 for (i
=0; i
< Priv
->CurrentFieldsCount
; i
++) {
3150 if ((error
= ALCATEL_GetFieldValue(s
, ToDo
->Location
, Priv
->CurrentFields
[i
]))!= GE_NONE
) return error
;
3151 switch (Priv
->CurrentFields
[i
]) {
3153 if (Priv
->ReturnType
!= Alcatel_date
) {
3154 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3159 if (!CheckDate(&(Priv
->ReturnDateTime
))) {
3160 smprintf(s
,"WARNING: Invalid date in phone, ignoring\n");
3165 ToDo
->Entries
[i
-j
].EntryType
= TODO_END_DATETIME
;
3166 ToDo
->Entries
[i
-j
].Date
= Priv
->ReturnDateTime
;
3169 if (Priv
->ReturnType
!= Alcatel_bool
) {
3170 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3175 ToDo
->Entries
[i
-j
].EntryType
= TODO_COMPLETED
;
3176 ToDo
->Entries
[i
-j
].Number
= Priv
->ReturnInt
;
3179 if (Priv
->ReturnType
!= Alcatel_date
) {
3180 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3185 if (!CheckDate(&(Priv
->ReturnDateTime
))) {
3186 smprintf(s
,"WARNING: Invalid date in phone, ignoring\n");
3192 ToDo
->Entries
[i
-j
].EntryType
= TODO_ALARM_DATETIME
;
3193 ToDo
->Entries
[i
-j
].Date
= Priv
->ReturnDateTime
;
3194 dt
= &(ToDo
->Entries
[i
-j
].Date
);
3198 dt
->Day
= Priv
->ReturnDateTime
.Day
;
3199 dt
->Month
= Priv
->ReturnDateTime
.Month
;
3200 dt
->Year
= Priv
->ReturnDateTime
.Year
;
3201 dt
->Timezone
= Priv
->ReturnDateTime
.Timezone
;
3206 if (Priv
->ReturnType
!= Alcatel_time
) {
3207 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3212 if (!CheckTime(&(Priv
->ReturnDateTime
))) {
3213 smprintf(s
,"WARNING: Invalid time in phone, ignoring\n");
3219 ToDo
->Entries
[i
-j
].EntryType
= TODO_ALARM_DATETIME
;
3220 ToDo
->Entries
[i
-j
].Date
= Priv
->ReturnDateTime
;
3221 dt
= &(ToDo
->Entries
[i
-j
].Date
);
3225 dt
->Hour
= Priv
->ReturnDateTime
.Hour
;
3226 dt
->Minute
= Priv
->ReturnDateTime
.Minute
;
3227 dt
->Second
= Priv
->ReturnDateTime
.Second
;
3232 if (Priv
->ReturnType
!= Alcatel_string
) {
3233 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3238 ToDo
->Entries
[i
-j
].EntryType
= TODO_TEXT
;
3239 CopyUnicodeString(ToDo
->Entries
[i
-j
].Text
, Priv
->ReturnString
);
3242 if (Priv
->ReturnType
!= Alcatel_bool
) {
3243 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3248 ToDo
->Entries
[i
-j
].EntryType
= TODO_PRIVATE
;
3249 ToDo
->Entries
[i
-j
].Number
= Priv
->ReturnInt
;
3252 if (Priv
->ReturnType
!= Alcatel_byte
) {
3253 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3258 if (Priv
->ReturnInt
== 255) {
3259 /* 255 means no category */
3263 ToDo
->Entries
[i
-j
].EntryType
= TODO_CATEGORY
;
3264 ToDo
->Entries
[i
-j
].Number
= Priv
->ReturnInt
;
3268 /* This one seems to be byte for BF5 and enum for BE5 */
3269 if (Priv
->ReturnType
!= Alcatel_enum
&& Priv
->ReturnType
!= Alcatel_byte
) {
3270 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3275 switch (Priv
->ReturnInt
) {
3277 ToDo
->Priority
= GSM_Priority_High
;
3280 ToDo
->Priority
= GSM_Priority_Medium
;
3283 ToDo
->Priority
= GSM_Priority_Low
;
3287 smprintf(s
,"WARNING: Received unexpected priority %02X, ignoring\n", Priv
->ReturnInt
);
3293 if (Priv
->ReturnType
!= Alcatel_int
) {
3294 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3299 /* 0xffffffff indicates that there is phone, 0 means none */
3300 if (Priv
->ReturnInt
== 0xffffffff || Priv
->ReturnInt
== 0) {
3304 ToDo
->Entries
[i
-j
].EntryType
= TODO_CONTACTID
;
3305 ToDo
->Entries
[i
-j
].Number
= Priv
->ReturnInt
;
3309 if (Priv
->ReturnType
!= Alcatel_phone
) {
3310 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3315 ToDo
->Entries
[i
-j
].EntryType
= TODO_PHONE
;
3316 CopyUnicodeString(ToDo
->Entries
[i
-j
].Text
, Priv
->ReturnString
);
3319 if (Priv
->ReturnType
!= Alcatel_date
) {
3320 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3325 if (!CheckDate(&(Priv
->ReturnDateTime
))) {
3326 smprintf(s
,"WARNING: Invalid date in phone, ignoring\n");
3331 /* This entry had always same value as the 2nd (alarm date) */
3336 if (Priv
->ReturnType
!= Alcatel_time
) {
3337 smprintf(s
,"WARNING: Received unexpected type %02X, ignoring\n", Priv
->ReturnType
);
3342 if (!CheckTime(&(Priv
->ReturnDateTime
))) {
3343 smprintf(s
,"WARNING: Invalid time in phone, ignoring\n");
3348 /* This entry had always same value as the 3rd (alarm time) */
3355 smprintf(s
,"WARNING: Received unknown field %02X, ignoring. Type = %02X. Value = ", Priv
->CurrentFields
[i
], Priv
->ReturnType
);
3356 switch (Priv
->ReturnType
) {
3358 smprintf(s
, "%d.%d.%d", Priv
->ReturnDateTime
.Day
, Priv
->ReturnDateTime
.Month
, Priv
->ReturnDateTime
.Year
);
3361 smprintf(s
, "%d:%d:%d", Priv
->ReturnDateTime
.Hour
, Priv
->ReturnDateTime
.Minute
, Priv
->ReturnDateTime
.Second
);
3363 case Alcatel_string
:
3365 smprintf(s
, "\"%s\"",DecodeUnicodeString(Priv
->ReturnString
));
3371 smprintf(s
, "%d", Priv
->ReturnInt
);
3380 static GSM_Error
ALCATEL_GetNextToDo(GSM_StateMachine
*s
, GSM_ToDoEntry
*ToDo
, bool start
)
3383 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
3385 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeToDo
, 0))!= GE_NONE
) return error
;
3386 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
3387 if (Priv
->ToDoItemsCount
== 0) return GE_EMPTY
;
3389 if (start
) ToDo
->Location
= Priv
->ToDoItems
[0];
3390 else if ((error
= ALCATEL_GetNextId(s
, &(ToDo
->Location
))) != GE_NONE
) return error
;
3392 return ALCATEL_GetToDo(s
, ToDo
);
3395 static GSM_Error
ALCATEL_DeleteAllToDo (GSM_StateMachine
*s
)
3398 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
3401 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeToDo
, 0))!= GE_NONE
) return error
;
3402 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
3404 for (i
=0; i
<Priv
->ToDoItemsCount
; i
++) {
3405 error
= ALCATEL_DeleteItem(s
, Priv
->ToDoItems
[i
]);
3406 if (error
!= GE_NONE
) return error
;
3410 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeToDo
, 0))!= GE_NONE
) return error
;
3411 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
3416 static GSM_Error
ALCATEL_AddToDo (GSM_StateMachine
*s
, GSM_ToDoEntry
*ToDo
)
3420 bool contact_set
= false;
3421 bool phone_set
= false;
3423 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
3425 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeToDo
, 0))!= GE_NONE
) return error
;
3426 if ((error
= ALCATEL_GoToBinaryState(s
, StateEdit
, TypeToDo
, 0))!= GE_NONE
) return error
;
3428 switch (ToDo
->Priority
) {
3429 case GSM_Priority_High
:
3432 case GSM_Priority_Low
:
3435 case GSM_Priority_Medium
:
3440 /* This one seems to be byte for BF5 and enum for BE5 */
3441 if (s
->Phone
.Data
.Priv
.ALCATEL
.ProtocolVersion
== V_1_1
) {
3442 if ((error
= ALCATEL_CreateField(s
, Alcatel_byte
, 7, &val
)) != GE_NONE
) return error
;
3444 if ((error
= ALCATEL_CreateField(s
, Alcatel_enum
, 7, &val
)) != GE_NONE
) return error
;
3447 for (i
= 0; i
< ToDo
->EntriesNum
; i
++) {
3448 switch (ToDo
->Entries
[i
].EntryType
) {
3449 case TODO_END_DATETIME
:
3450 if ((error
= ALCATEL_CreateField(s
, Alcatel_date
, 0, &(ToDo
->Entries
[i
].Date
))) != GE_NONE
) return error
;
3452 case TODO_COMPLETED
:
3453 if ((error
= ALCATEL_CreateField(s
, Alcatel_bool
, 1, &(ToDo
->Entries
[i
].Number
))) != GE_NONE
) return error
;
3455 case TODO_ALARM_DATETIME
:
3456 if ((error
= ALCATEL_CreateField(s
, Alcatel_date
, 2, &(ToDo
->Entries
[i
].Date
))) != GE_NONE
) return error
;
3457 if ((error
= ALCATEL_CreateField(s
, Alcatel_time
, 3, &(ToDo
->Entries
[i
].Date
))) != GE_NONE
) return error
;
3458 if ((error
= ALCATEL_CreateField(s
, Alcatel_date
, 10, &(ToDo
->Entries
[i
].Date
))) != GE_NONE
) return error
;
3459 if ((error
= ALCATEL_CreateField(s
, Alcatel_time
, 11, &(ToDo
->Entries
[i
].Date
))) != GE_NONE
) return error
;
3462 if ((error
= ALCATEL_CreateField(s
, Alcatel_string
, 4, ToDo
->Entries
[i
].Text
)) != GE_NONE
) return error
;
3465 if ((error
= ALCATEL_CreateField(s
, Alcatel_bool
, 5, &(ToDo
->Entries
[i
].Number
))) != GE_NONE
) return error
;
3468 if ((error
= ALCATEL_CreateField(s
, Alcatel_byte
, 6, &(ToDo
->Entries
[i
].Number
))) != GE_NONE
) return error
;
3470 case TODO_CONTACTID
:
3471 if ((error
= ALCATEL_CreateField(s
, Alcatel_int
, 8, &(ToDo
->Entries
[i
].Number
))) != GE_NONE
) return error
;
3475 if ((error
= ALCATEL_CreateField(s
, Alcatel_phone
, 9, ToDo
->Entries
[i
].Text
)) != GE_NONE
) return error
;
3488 if ((error
= ALCATEL_CreateField(s
, Alcatel_int
, 8, &val
)) != GE_NONE
) return error
;
3490 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeToDo
, 0))!= GE_NONE
) return error
;
3491 ToDo
->Location
= Priv
->CommitedRecord
;
3493 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
3497 static GSM_Error
ALCATEL_SetToDo (GSM_StateMachine
*s
, GSM_ToDoEntry
*ToDo
)
3501 bool contact_set
= false;
3502 bool phone_set
= false;
3503 bool UpdatedFields
[12];
3505 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
3507 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeToDo
, 0))!= GE_NONE
) return error
;
3508 /* Save modified ToDo */
3509 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
3510 if ((error
= ALCATEL_IsIdAvailable(s
, ToDo
->Location
))!= GE_NONE
) {
3511 /* Entry doesn't exist, we will create new one */
3512 return ALCATEL_AddToDo(s
, ToDo
);
3514 /* Get fields for current item */
3515 if ((error
= ALCATEL_GetFields(s
, ToDo
->Location
))!= GE_NONE
) return error
;
3517 for (i
= 0; i
< 12; i
++) { UpdatedFields
[i
] = false; }
3519 if ((error
= ALCATEL_GoToBinaryState(s
, StateEdit
, TypeToDo
, ToDo
->Location
))!= GE_NONE
) return error
;
3521 switch (ToDo
->Priority
) {
3522 case GSM_Priority_High
:
3525 case GSM_Priority_Low
:
3528 case GSM_Priority_Medium
:
3533 /* This one seems to be byte for BF5 and enum for BE5 */
3534 if (s
->Phone
.Data
.Priv
.ALCATEL
.ProtocolVersion
== V_1_1
) {
3535 if ((error
= ALCATEL_UpdateField(s
, Alcatel_byte
, ToDo
->Location
, 7, &val
)) != GE_NONE
) return error
;
3537 if ((error
= ALCATEL_UpdateField(s
, Alcatel_enum
, ToDo
->Location
, 7, &val
)) != GE_NONE
) return error
;
3539 UpdatedFields
[7] = true;
3541 for (i
= 0; i
< ToDo
->EntriesNum
; i
++) {
3542 switch (ToDo
->Entries
[i
].EntryType
) {
3543 case TODO_END_DATETIME
:
3544 if ((error
= ALCATEL_UpdateField(s
, Alcatel_date
, ToDo
->Location
, 0, &(ToDo
->Entries
[i
].Date
))) != GE_NONE
) return error
;
3545 UpdatedFields
[0] = true;
3547 case TODO_COMPLETED
:
3548 if ((error
= ALCATEL_UpdateField(s
, Alcatel_bool
, ToDo
->Location
, 1, &(ToDo
->Entries
[i
].Number
))) != GE_NONE
) return error
;
3549 UpdatedFields
[1] = true;
3551 case TODO_ALARM_DATETIME
:
3552 if ((error
= ALCATEL_UpdateField(s
, Alcatel_date
, ToDo
->Location
, 2, &(ToDo
->Entries
[i
].Date
))) != GE_NONE
) return error
;
3553 UpdatedFields
[2] = true;
3554 if ((error
= ALCATEL_UpdateField(s
, Alcatel_time
, ToDo
->Location
, 3, &(ToDo
->Entries
[i
].Date
))) != GE_NONE
) return error
;
3555 UpdatedFields
[3] = true;
3556 if ((error
= ALCATEL_UpdateField(s
, Alcatel_date
, ToDo
->Location
, 10, &(ToDo
->Entries
[i
].Date
))) != GE_NONE
) return error
;
3557 UpdatedFields
[10] = true;
3558 if ((error
= ALCATEL_UpdateField(s
, Alcatel_time
, ToDo
->Location
, 11, &(ToDo
->Entries
[i
].Date
))) != GE_NONE
) return error
;
3559 UpdatedFields
[11] = true;
3562 if ((error
= ALCATEL_UpdateField(s
, Alcatel_string
, ToDo
->Location
, 4, ToDo
->Entries
[i
].Text
)) != GE_NONE
) return error
;
3563 UpdatedFields
[4] = true;
3566 if ((error
= ALCATEL_UpdateField(s
, Alcatel_bool
, ToDo
->Location
, 5, &(ToDo
->Entries
[i
].Number
))) != GE_NONE
) return error
;
3567 UpdatedFields
[5] = true;
3570 if ((error
= ALCATEL_UpdateField(s
, Alcatel_byte
, ToDo
->Location
, 6, &(ToDo
->Entries
[i
].Number
))) != GE_NONE
) return error
;
3571 UpdatedFields
[6] = true;
3573 case TODO_CONTACTID
:
3574 if ((error
= ALCATEL_UpdateField(s
, Alcatel_int
, ToDo
->Location
, 8, &(ToDo
->Entries
[i
].Number
))) != GE_NONE
) return error
;
3575 UpdatedFields
[8] = true;
3579 if ((error
= ALCATEL_UpdateField(s
, Alcatel_phone
, ToDo
->Location
, 9, ToDo
->Entries
[i
].Text
)) != GE_NONE
) return error
;
3580 UpdatedFields
[9] = true;
3593 if ((error
= ALCATEL_UpdateField(s
, Alcatel_int
, ToDo
->Location
, 8, &val
)) != GE_NONE
) return error
;
3594 UpdatedFields
[8] = true;
3598 /* If we didn't update some field, we have to delete it... */
3599 for (i
=0; i
<Priv
->CurrentFieldsCount
; i
++) {
3600 if (!UpdatedFields
[Priv
->CurrentFields
[i
]]) if ((error
= ALCATEL_DeleteField(s
, ToDo
->Location
, Priv
->CurrentFields
[i
])) != GE_NONE
) return error
;
3602 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeToDo
, 0))!= GE_NONE
) return error
;
3606 static GSM_Error
ALCATEL_DeleteToDo (GSM_StateMachine
*s
, GSM_ToDoEntry
*ToDo
)
3610 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeToDo
, 0))!= GE_NONE
) return error
;
3612 if ((error
= ALCATEL_GetAvailableIds(s
, false))!= GE_NONE
) return error
;
3613 if ((error
= ALCATEL_IsIdAvailable(s
, ToDo
->Location
))!= GE_NONE
) {
3614 /* Entry was empty => no error */
3617 error
= ALCATEL_DeleteItem(s
, ToDo
->Location
);
3618 if (error
!= GE_NONE
) return error
;
3620 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, TypeToDo
, 0))!= GE_NONE
) return error
;
3621 if ((error
= ALCATEL_GetAvailableIds(s
, true))!= GE_NONE
) return error
;
3625 static GSM_Error
ALCATEL_GetCategoryStatus(GSM_StateMachine
*s
, GSM_CategoryStatus
*Status
)
3627 GSM_Alcatel_BinaryType type
;
3629 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
3631 switch (Status
->Type
) {
3632 case Category_ToDo
: type
= TypeToDo
; break;
3633 case Category_Phonebook
: type
= TypeContacts
; break;
3634 default: return GE_NOTSUPPORTED
;
3636 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, type
, 0))!= GE_NONE
) return error
;
3637 if ((error
= ALCATEL_GetAvailableCategoryIds(s
))!= GE_NONE
) return error
;
3639 Status
->Used
= Priv
->CurrentCategoriesCount
;
3644 static GSM_Error
ALCATEL_GetCategory(GSM_StateMachine
*s
, GSM_Category
*Category
)
3646 GSM_Alcatel_BinaryType type
;
3648 GSM_Phone_ALCATELData
*Priv
= &s
->Phone
.Data
.Priv
.ALCATEL
;
3650 switch (Category
->Type
) {
3651 case Category_ToDo
: type
= TypeToDo
; break;
3652 case Category_Phonebook
: type
= TypeContacts
; break;
3653 default: return GE_NOTSUPPORTED
;
3655 if ((error
= ALCATEL_GoToBinaryState(s
, StateSession
, type
, 0))!= GE_NONE
) return error
;
3656 if ((error
= ALCATEL_GetAvailableCategoryIds(s
))!= GE_NONE
) return error
;
3657 if ((error
= ALCATEL_IsCategoryIdAvailable(s
, Category
->Location
))!= GE_NONE
) return error
;
3658 if ((error
= ALCATEL_GetCategoryText(s
, Category
->Location
))!= GE_NONE
) return error
;
3660 CopyUnicodeString(Category
->Name
, Priv
->ReturnString
);
3665 static GSM_Error
ALCATEL_GetProductCode(GSM_StateMachine
*s
, char *value
)
3667 strcpy(value
, s
->Phone
.Data
.ModelInfo
->model
);
3671 static GSM_Error
ALCATEL_DispatchMessage(GSM_StateMachine
*s
)
3673 if (s
->Phone
.Data
.Priv
.ALCATEL
.Mode
== ModeBinary
) {
3674 return GSM_DispatchMessage(s
);
3676 return ATGEN_DispatchMessage(s
);
3680 static GSM_Error
ALCATEL_ReplyGeneric(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
3682 /* All error values are just VERY wild guesses, but these seems to work
3683 * almost as expected ...
3685 switch (msg
.Buffer
[8]) {
3686 case 0x00: /* no error */
3688 case 0x10: /* same thing opened in phone menus */
3689 return GE_INSIDEPHONEMENU
;
3691 /* This appears in more cases:
3692 * - phone needs PIN code
3693 * - we want to close not opened session
3694 * For normal users the second case shouldn't occur...
3696 return GE_SECURITYERROR
;
3697 case 0x14: /* Bad data */
3698 case 0x2f: /* Closing session when not opened */
3699 case 0x1f: /* Bad in/out counter in packet/ack */
3700 case 0x0e: /* Openning session when not closed */
3701 case 0x0C: /* Bad id (item/database) */
3702 case 0x11: /* Bad list id */
3703 case 0x2A: /* Nonexistant field/item id */
3704 case 0x35: /* Too long text */
3706 case 0x23: /* Session opened */
3707 case 0x80: /* Transfer started */
3709 case 0x82: /* Transfer canceled */
3712 smprintf(s
, "WARNING: Packet seems to indicate some status by %02X, ignoring!\n", msg
.Buffer
[8]);
3717 static GSM_Error
ALCATEL_ReplyCommit(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
3719 s
->Phone
.Data
.Priv
.ALCATEL
.CommitedRecord
= msg
.Buffer
[12] + (msg
.Buffer
[11] << 8) + (msg
.Buffer
[10] << 16) + (msg
.Buffer
[9] << 24);
3720 smprintf(s
, "Created record %08x\n", s
->Phone
.Data
.Priv
.ALCATEL
.CommitedRecord
);
3724 static GSM_Error
ALCATEL_SetIncomingCB (GSM_StateMachine
*s
, bool enable
)
3728 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
3729 return ATGEN_SetIncomingCB(s
, enable
);
3732 static GSM_Error
ALCATEL_SetIncomingSMS (GSM_StateMachine
*s
, bool enable
)
3736 if ((error
= ALCATEL_SetATMode(s
))!= GE_NONE
) return error
;
3737 return ATGEN_SetIncomingSMS(s
, enable
);
3740 static GSM_Reply_Function ALCATELReplyFunctions
[] = {
3741 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelAttach
},
3742 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelDetach
},
3743 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelCommit
},
3744 {ALCATEL_ReplyCommit
, "\x02",0x00,0x00, ID_AlcatelCommit2
},
3745 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelEnd
},
3746 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelClose
},
3747 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelStart
},
3748 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelSelect1
},
3749 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelSelect2
},
3750 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelSelect3
},
3751 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelBegin1
},
3752 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelBegin2
},
3753 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelGetIds1
},
3754 {ALCATEL_ReplyGetIds
, "\x02",0x00,0x00, ID_AlcatelGetIds2
},
3755 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelGetCategories1
},
3756 {ALCATEL_ReplyGetCategories
, "\x02",0x00,0x00, ID_AlcatelGetCategories2
},
3757 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelGetCategoryText1
},
3758 {ALCATEL_ReplyGetCategoryText
, "\x02",0x00,0x00, ID_AlcatelGetCategoryText2
},
3759 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelGetFields1
},
3760 {ALCATEL_ReplyGetFields
, "\x02",0x00,0x00, ID_AlcatelGetFields2
},
3761 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelGetFieldValue1
},
3762 {ALCATEL_ReplyGetFieldValue
, "\x02",0x00,0x00, ID_AlcatelGetFieldValue2
},
3763 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelDeleteField
},
3764 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelDeleteItem1
},
3765 {ALCATEL_ReplyDeleteItem
, "\x02",0x00,0x00, ID_AlcatelDeleteItem2
},
3766 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelCreateField
},
3767 {ALCATEL_ReplyGeneric
, "\x02",0x00,0x00, ID_AlcatelUpdateField
},
3768 {NULL
, "\x00",0x00,0x00, ID_None
}
3771 GSM_Phone_Functions ALCATELPhone
= {
3772 /* AFAIK, any 50[0123] phone should work, but I'm not sure whether all
3773 * they were ever really released, if yes add them here also.
3775 "alcatel|OT501|OT701|OT715|OT535|OT735|BE5|BF5|BH4",
3776 ALCATELReplyFunctions
,
3779 ALCATEL_DispatchMessage
,
3780 NOTSUPPORTED
, /* ShowStartInfo */
3781 ALCATEL_GetManufacturer
,
3783 ALCATEL_GetFirmware
,
3785 NOTSUPPORTED
, /* GetOriginalIMEI */
3786 NOTSUPPORTED
, /* GetManufactureMonth */
3787 ALCATEL_GetProductCode
,
3788 NOTSUPPORTED
, /* GetHardware */
3789 NOTSUPPORTED
, /* GetPPM */
3791 ALCATEL_GetDateTime
,
3792 ALCATEL_SetDateTime
,
3795 NOTSUPPORTED
, /* GetLocale */
3796 NOTSUPPORTED
, /* SetLocale */
3799 ALCATEL_ResetPhoneSettings
,
3800 ALCATEL_EnterSecurityCode
,
3801 ALCATEL_GetSecurityStatus
,
3802 ALCATEL_GetDisplayStatus
,
3803 ALCATEL_SetAutoNetworkLogin
,
3804 ALCATEL_GetBatteryCharge
,
3805 ALCATEL_GetSignalStrength
,
3806 ALCATEL_GetNetworkInfo
,
3807 ALCATEL_GetCategory
,
3808 ALCATEL_GetCategoryStatus
,
3809 ALCATEL_GetMemoryStatus
,
3811 ALCATEL_GetNextMemory
,
3814 ALCATEL_DeleteMemory
,
3815 ALCATEL_DeleteAllMemory
,
3816 NOTSUPPORTED
, /* GetSpeedDial */
3817 NOTSUPPORTED
, /* SetSpeedDial */
3820 ALCATEL_GetSMSStatus
,
3823 NOTSUPPORTED
, /* SetSMS */
3827 ALCATEL_SetIncomingSMS
,
3828 ALCATEL_SetIncomingCB
,
3829 ALCATEL_GetSMSFolders
,
3830 NOTSUPPORTED
, /* AddSMSFolder */
3831 NOTSUPPORTED
, /* DeleteSMSFolder */
3835 NOTSUPPORTED
, /* HoldCall */
3836 NOTSUPPORTED
, /* UnholdCall */
3837 NOTSUPPORTED
, /* ConferenceCall */
3838 NOTSUPPORTED
, /* SplitCall */
3839 NOTSUPPORTED
, /* TransferCall */
3840 NOTSUPPORTED
, /* SwitchCall */
3841 NOTSUPPORTED
, /* GetCallDivert */
3842 NOTSUPPORTED
, /* SetCallDivert */
3843 NOTSUPPORTED
, /* CancelAllDiverts */
3844 NONEFUNCTION
, /* SetIncomingCall */
3845 NOTSUPPORTED
, /* SetIncomingUSSD */
3847 NOTSUPPORTED
, /* GetRingtone */
3848 NOTSUPPORTED
, /* SetRingtone */
3849 NOTSUPPORTED
, /* GetRingtonesInfo */
3850 NOTSUPPORTED
, /* DeleteUserRingtones */
3851 NOTSUPPORTED
, /* PlayTone */
3852 NOTSUPPORTED
, /* GetWAPBookmark */
3853 NOTSUPPORTED
, /* SetWAPBookmark */
3854 NOTSUPPORTED
, /* DeleteWAPBookmark */
3855 NOTSUPPORTED
, /* GetWAPSettings */
3856 NOTSUPPORTED
, /* SetWAPSettings */
3857 NOTSUPPORTED
, /* GetMMSSettings */
3858 NOTSUPPORTED
, /* SetMMSSettings */
3859 NOTSUPPORTED
, /* GetBitmap */
3860 NOTSUPPORTED
, /* SetBitmap */
3861 ALCATEL_GetToDoStatus
,
3863 ALCATEL_GetNextToDo
,
3867 ALCATEL_DeleteAllToDo
,
3868 ALCATEL_GetCalendarStatus
,
3869 ALCATEL_GetCalendar
,
3870 ALCATEL_GetNextCalendar
,
3871 ALCATEL_SetCalendar
,
3872 ALCATEL_AddCalendar
,
3873 ALCATEL_DeleteCalendar
,
3874 ALCATEL_DeleteAllCalendar
,
3875 NOTSUPPORTED
, /* GetCalendarSettings */
3876 NOTSUPPORTED
, /* SetCalendarSettings */
3877 NOTSUPPORTED
, /* GetNote */
3878 NOTSUPPORTED
, /* GetProfile */
3879 NOTSUPPORTED
, /* SetProfile */
3880 NOTSUPPORTED
, /* GetFMStation */
3881 NOTSUPPORTED
, /* SetFMStation */
3882 NOTSUPPORTED
, /* ClearFMStations */
3883 NOTSUPPORTED
, /* GetNextFileFolder */
3884 NOTSUPPORTED
, /* GetFilePart */
3885 NOTSUPPORTED
, /* AddFilePart */
3886 NOTSUPPORTED
, /* GetFileSystemStatus */
3887 NOTSUPPORTED
, /* DeleteFile */
3888 NOTSUPPORTED
, /* AddFolder */
3889 NOTSUPPORTED
, /* GetGPRSAccessPoint */
3890 NOTSUPPORTED
/* SetGPRSAccessPoint */
3896 /* How should editor hadle tabs in this file? Add editor commands here.
3897 * vim: noexpandtab sw=8 ts=8 sts=8: