2 #include "../../../gsmstate.h"
4 #ifdef GSM_ENABLE_NOKIA6110
8 #include "../../../../cfg/config.h"
9 #include "../../../misc/coding/coding.h"
10 #include "../../../service/sms/gsmsms.h"
11 #include "../../../gsmcomon.h"
12 #include "../../pfunc.h"
17 static unsigned char N6110_MEMORY_TYPES
[] = {
28 static GSM_Error
N6110_ReplyGetPhoneLanguage(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
30 N6110_Language lang
= N6110_Auto
;
32 if (msg
.Buffer
[3] == 0x15) return GE_NONE
;
34 smprintf(s
, "Phone language is %02x\n",msg
.Buffer
[6]);
35 switch (msg
.Buffer
[6]) {
36 case 0x21: lang
= N6110_Europe
; break; //Polish
38 s
->Phone
.Data
.Priv
.N6110
.PhoneLanguage
= lang
;
42 static GSM_Error
N6110_GetPhoneLanguage(GSM_StateMachine
*s
)
44 unsigned char feat_req
[] = {
45 N6110_FRAME_HEADER
, 0x13, 0x01,
46 0x00, /* Profile location */
47 0x00}; /* Feature number */
49 s
->Phone
.Data
.Priv
.N6110
.PhoneLanguage
= N6110_Auto
;
52 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PROFILES33
)) {
57 smprintf(s
, "Getting profile feature\n");
58 return GSM_WaitFor (s
, feat_req
, 7, 0x05, 4, ID_GetLanguage
);
61 struct N6110_Lang_Char
{
64 unsigned char Unicode1
;
65 unsigned char Unicode2
;
68 static struct N6110_Lang_Char N6110_Lang_Table
[] = {
69 {N6110_Europe
,0x13,0x01,0x04},//Latin capital letter a with ogonek
70 {N6110_Europe
,0x14,0x01,0x05},//Latin small letter a with ogonek
71 {N6110_Europe
,0x15,0x01,0x06},//Latin capital letter c with acute
72 {N6110_Europe
,0x17,0x01,0x07},//Latin small letter c with acute
73 {N6110_Europe
,0x1D,0x01,0x18},//Latin capital letter e with ogonek
74 {N6110_Europe
,0x1E,0x01,0x19},//Latin small letter e with ogonek
75 {N6110_Europe
,0x83,0x00,0xD3},//Latin capital letter o with acute
76 {N6110_Europe
,0x8E,0x01,0x41},//Latin capital letter l with stroke
77 {N6110_Europe
,0x90,0x01,0x42},//Latin small letter l with stroke
78 {N6110_Europe
,0x92,0x01,0x43},//Latin capital letter n with acute
79 {N6110_Europe
,0x93,0x01,0x44},//Latin small letter n with acute
80 {N6110_Europe
,0x9A,0x00,0xF3},//Latin small letter o with acute
81 {N6110_Europe
,0xB2,0x20,0xAC},//euro
82 {N6110_Europe
,0xB5,0x01,0x5A},//Latin capital letter s with acute
83 {N6110_Europe
,0xB6,0x01,0x5B},//Latin small letter s with acute
84 {N6110_Europe
,0xE7,0x01,0x79},//Latin capital letter z with acute
85 {N6110_Europe
,0xEE,0x01,0x7A},//Latin small letter z with acute
86 {N6110_Europe
,0xF4,0x01,0x7C},//Latin small letter z with dot above
87 {N6110_Europe
,0xF0,0x01,0x7B},//Latin capital letter z with dot above
91 static void N6110_EncodeUnicode(GSM_StateMachine
*s
, unsigned char *dest
, const unsigned char *src
, int len
)
93 int i_len
= 0, o_len
, i
;
95 GSM_Phone_N6110Data
*Priv
= &s
->Phone
.Data
.Priv
.N6110
;
98 for (o_len
= 0; i_len
< len
; o_len
++) {
100 if (Priv
->PhoneLanguage
!= N6110_Auto
) {
103 if (N6110_Lang_Table
[i
].Lang
== 0) break;
104 if (N6110_Lang_Table
[i
].Lang
== Priv
->PhoneLanguage
&&
105 N6110_Lang_Table
[i
].Phone
== src
[i_len
]) {
106 dest
[o_len
*2] = N6110_Lang_Table
[i
].Unicode1
;
107 dest
[(o_len
*2)+1] = N6110_Lang_Table
[i
].Unicode2
;
116 i_len
+= EncodeWithUnicodeAlphabet(&src
[i_len
], &wc
);
117 dest
[o_len
*2] = (wc
>> 8) & 0xff;
118 dest
[(o_len
*2)+1] = wc
& 0xff;
122 dest
[(o_len
*2)+1] = 0;
127 /* This function provides Nokia authentication protocol.
128 * Nokia authentication protocol is used in the communication between Nokia
129 * mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software,
130 * commercially sold by Nokia Corp.
131 * The authentication scheme is based on the token send by the phone to the
132 * software. The software does it's magic (see the function
133 * N6110_GetNokiaAuthentication) and returns the result back to the phone.
134 * If the result is correct the phone responds with the message "Accessory
135 * connected!" displayed on the LCD. Otherwise it will display "Accessory not
136 * supported" and some functions will not be available for use (?).
137 * The specification of the protocol is not publicly available, no comment.
139 static void N6110_GetNokiaAuthentication(unsigned char *Imei
, unsigned char *MagicBytes
, unsigned char *MagicResponse
)
142 unsigned char Temp
[16]; /* This is our temporary working area. */
144 /* Here we put FAC (Final Assembly Code) and serial number into our area. */
145 Temp
[0] = Imei
[6]; Temp
[1] = Imei
[7];
146 Temp
[2] = Imei
[8]; Temp
[3] = Imei
[9];
147 Temp
[4] = Imei
[10]; Temp
[5] = Imei
[11];
148 Temp
[6] = Imei
[12]; Temp
[7] = Imei
[13];
150 /* And now the TAC (Type Approval Code). */
151 Temp
[8] = Imei
[2]; Temp
[9] = Imei
[3];
152 Temp
[10] = Imei
[4]; Temp
[11] = Imei
[5];
154 /* And now we pack magic bytes from the phone. */
155 Temp
[12] = MagicBytes
[0]; Temp
[13] = MagicBytes
[1];
156 Temp
[14] = MagicBytes
[2]; Temp
[15] = MagicBytes
[3];
158 for (i
=0; i
<=11; i
++) if (Temp
[i
+ 1]& 1) Temp
[i
]<<=1;
159 switch (Temp
[15] & 0x03) {
161 case 2: j
= Temp
[13] & 0x07;
162 for (i
=0; i
<=3; i
++) Temp
[i
+j
] ^= Temp
[i
+12];
164 default: j
= Temp
[14] & 0x07;
165 for (i
=0; i
<=3; i
++) Temp
[i
+ j
] |= Temp
[i
+ 12];
167 for (i
=0; i
<=15; i
++) CRC
^= Temp
[i
];
168 for (i
=0; i
<=15; i
++) {
169 switch (Temp
[15 - i
] & 0x06) {
170 case 0: j
= Temp
[i
] | CRC
; break;
172 case 4: j
= Temp
[i
] ^ CRC
; break;
173 case 6: j
= Temp
[i
] & CRC
; break;
175 if (j
== CRC
) j
= 0x2c;
176 if (Temp
[i
] == 0) j
= 0;
177 MagicResponse
[i
] = j
;
181 static GSM_Error
N6110_ReplyGetMagicBytes(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
183 GSM_Phone_N6110Data
*Priv
= &s
->Phone
.Data
.Priv
.N6110
;
184 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
186 sprintf(Data
->IMEI
, "%s", msg
.Buffer
+9);
187 sprintf(Data
->HardwareCache
, "%s", msg
.Buffer
+39);
188 sprintf(Data
->ProductCodeCache
, "%s", msg
.Buffer
+31);
190 smprintf(s
, "Message: Mobile phone identification received:\n");
191 smprintf(s
, " IMEI : %s\n", msg
.Buffer
+9);
192 smprintf(s
, " Model : %s\n", msg
.Buffer
+25);
193 smprintf(s
, " Production Code : %s\n", msg
.Buffer
+31);
194 smprintf(s
, " HW : %s\n", msg
.Buffer
+39);
195 smprintf(s
, " Firmware : %s\n", msg
.Buffer
+44);
197 /* These bytes are probably the source of the "Accessory not connected"
198 * messages on the phone when trying to emulate NCDS... I hope....
199 * UPDATE: of course, now we have the authentication algorithm.
201 smprintf(s
, " Magic bytes : %02x %02x %02x %02x\n", msg
.Buffer
[50], msg
.Buffer
[51], msg
.Buffer
[52], msg
.Buffer
[53]);
203 Priv
->MagicBytes
[0]=msg
.Buffer
[50];
204 Priv
->MagicBytes
[1]=msg
.Buffer
[51];
205 Priv
->MagicBytes
[2]=msg
.Buffer
[52];
206 Priv
->MagicBytes
[3]=msg
.Buffer
[53];
211 static GSM_Error
N6110_MakeAuthentication(GSM_StateMachine
*s
)
213 GSM_Phone_N6110Data
*Priv
= &s
->Phone
.Data
.Priv
.N6110
;
215 unsigned char connect4
[] = {N6110_FRAME_HEADER
, 0x10};
216 unsigned char magic_connect
[] = {
217 N6110_FRAME_HEADER
, 0x12,
218 /* The real magic goes here ... These bytes are filled in
219 * with the function N6110_GetNokiaAuthentication. */
220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222 /* NOKIA&GNOKII Accessory */
223 'N', 'O', 'K', 'I', 'A', '&', 'N', 'O', 'K', 'I', 'A',
224 'a', 'c', 'c', 'e', 's', 's', 'o', 'r', 'y',
225 0x00, 0x00, 0x00, 0x00};
227 smprintf(s
, "Getting magic bytes for authentication\n");
228 error
=GSM_WaitFor (s
, connect4
, 4, 0x64, 4, ID_MakeAuthentication
);
229 if (error
!=GE_NONE
) return error
;
231 N6110_GetNokiaAuthentication(s
->Phone
.Data
.IMEI
, Priv
->MagicBytes
, magic_connect
+4);
232 smprintf(s
, "Sending authentication bytes\n");
233 return s
->Protocol
.Functions
->WriteMessage(s
, magic_connect
, 45, 0x64);
238 static GSM_Error
N6110_ShowStartInfo(GSM_StateMachine
*s
, bool enable
)
243 GSM_Error error
=GE_NONE
;
245 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_MAGICBYTES
)) {
246 if (s
->ConnectionType
== GCT_FBUS2
||
247 s
->ConnectionType
== GCT_FBUS2IRDA
) {
248 error
=N6110_MakeAuthentication(s
);
255 static GSM_Error
N6110_Initialise (GSM_StateMachine
*s
)
258 DCT3_SetIncomingCB(s
,true);
260 N6110_GetPhoneLanguage(s
);
264 static GSM_Error
N6110_GetDateTime(GSM_StateMachine
*s
, GSM_DateTime
*date_time
)
266 return DCT3_GetDateTime(s
, date_time
, 0x11);
269 static GSM_Error
N6110_GetAlarm(GSM_StateMachine
*s
, GSM_Alarm
*alarm
)
271 return DCT3_GetAlarm(s
, alarm
, 0x11);
274 static GSM_Error
N6110_SetDateTime(GSM_StateMachine
*s
, GSM_DateTime
*date_time
)
276 return DCT3_SetDateTime(s
, date_time
, 0x11);
279 static GSM_Error
N6110_SetAlarm(GSM_StateMachine
*s
, GSM_Alarm
*alarm
)
281 return DCT3_SetAlarm(s
, alarm
, 0x11);
284 static GSM_Error
N6110_ReplyGetMemory(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
287 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
289 smprintf(s
, "Phonebook entry received\n");
290 switch (msg
.Buffer
[3]) {
292 Data
->Memory
->EntriesNum
= 0;
293 Data
->Memory
->PreferUnicode
= false;
295 /* If name is not empty */
296 if (msg
.Buffer
[count
]!=0x00) {
297 if (msg
.Buffer
[count
]>GSM_PHONEBOOK_TEXT_LENGTH
) {
298 smprintf(s
, "Too long text\n");
299 return GE_UNKNOWNRESPONSE
;
301 Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].EntryType
=PBK_Text_Name
;
302 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_NOPBKUNICODE
)) {
303 if (Data
->Memory
->MemoryType
==GMT_DC
||
304 Data
->Memory
->MemoryType
==GMT_RC
||
305 Data
->Memory
->MemoryType
==GMT_MC
||
306 Data
->Memory
->MemoryType
==GMT_ME
) {
307 N6110_EncodeUnicode(s
,Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].Text
,
308 msg
.Buffer
+count
+1,msg
.Buffer
[count
]);
310 EncodeUnicode(Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].Text
,
311 msg
.Buffer
+count
+1,msg
.Buffer
[count
]);
314 memcpy(Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].Text
,
315 msg
.Buffer
+count
+1,msg
.Buffer
[count
]);
316 Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].Text
[msg
.Buffer
[count
]]=0x00;
317 Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].Text
[msg
.Buffer
[count
]+1]=0x00;
319 smprintf(s
, " Name \"%s\"\n",
320 DecodeUnicodeString(Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].Text
));
321 Data
->Memory
->EntriesNum
++;
323 count
=count
+msg
.Buffer
[count
]+1;
325 /* If number is empty */
326 if (msg
.Buffer
[count
]==0x00) return GE_EMPTY
;
328 if (msg
.Buffer
[count
]>GSM_PHONEBOOK_TEXT_LENGTH
) {
329 smprintf(s
, "Too long text\n");
330 return GE_UNKNOWNRESPONSE
;
332 Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].EntryType
= PBK_Number_General
;
333 Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].VoiceTag
= 0;
334 EncodeUnicode(Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].Text
,
335 msg
.Buffer
+count
+1,msg
.Buffer
[count
]);
336 smprintf(s
, " Number \"%s\"\n",
337 DecodeUnicodeString(Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].Text
));
338 Data
->Memory
->EntriesNum
++;
339 count
=count
+msg
.Buffer
[count
]+1;
341 if (!IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_NOCALLER
)) {
342 if (msg
.Buffer
[count
]<5) {
343 Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].EntryType
=PBK_Caller_Group
;
344 smprintf(s
, "Caller group \"%i\"\n",msg
.Buffer
[count
]);
345 Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].Number
=msg
.Buffer
[count
]+1;
346 Data
->Memory
->EntriesNum
++;
351 if (Data
->Memory
->MemoryType
==GMT_DC
||
352 Data
->Memory
->MemoryType
==GMT_RC
||
353 Data
->Memory
->MemoryType
==GMT_MC
)
355 NOKIA_DecodeDateTime(s
, msg
.Buffer
+count
+1,&Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].Date
);
356 Data
->Memory
->Entries
[Data
->Memory
->EntriesNum
].EntryType
=PBK_Date
;
358 /* These values are set, when date and time unavailable in phone.
359 * Values from 3310 - in other can be different */
360 if (Data
->Memory
->Entries
[2].Date
.Day
!=20 ||
361 Data
->Memory
->Entries
[2].Date
.Month
!=1 ||
362 Data
->Memory
->Entries
[2].Date
.Year
!=2118||
363 Data
->Memory
->Entries
[2].Date
.Hour
!=3 ||
364 Data
->Memory
->Entries
[2].Date
.Minute
!=14 ||
365 Data
->Memory
->Entries
[2].Date
.Second
!=7)
366 Data
->Memory
->EntriesNum
++;
371 switch (msg
.Buffer
[4]) {
373 smprintf(s
, "Phone is OFF\n");
376 /* TODO: check if not too high */
377 smprintf(s
, "ERROR: Empty ????\n");
378 Data
->Memory
->EntriesNum
= 0;
381 smprintf(s
, "ERROR: Invalid memory type\n");
382 return GE_NOTSUPPORTED
;
384 smprintf(s
, "ERROR: no PIN\n");
385 return GE_SECURITYERROR
;
387 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
390 return GE_UNKNOWNRESPONSE
;
393 static GSM_Error
N6110_GetMemory (GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
)
395 unsigned char req
[] = {
396 N6110_FRAME_HEADER
, 0x01,
397 0x00, /* memory type */
401 req
[4] = NOKIA_GetMemoryType(s
, entry
->MemoryType
,N6110_MEMORY_TYPES
);
402 if (req
[4]==0xff) return GE_NOTSUPPORTED
;
404 req
[5] = entry
->Location
;
405 if (entry
->MemoryType
==GMT_DC
|| entry
->MemoryType
==GMT_RC
|| entry
->MemoryType
==GMT_MC
) req
[5]--;
407 s
->Phone
.Data
.Memory
=entry
;
408 smprintf(s
, "Getting phonebook entry\n");
409 return GSM_WaitFor (s
, req
, 7, 0x03, 4, ID_GetMemory
);
412 static GSM_Error
N6110_ReplyGetMemoryStatus(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
414 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
416 smprintf(s
, "Memory status received\n");
417 switch (msg
.Buffer
[3]) {
419 smprintf(s
, " Memory type: %i\n",msg
.Buffer
[4]);
420 smprintf(s
, " Free : %i\n",msg
.Buffer
[5]);
421 Data
->MemoryStatus
->Free
=msg
.Buffer
[5];
422 smprintf(s
, " Used : %i\n",msg
.Buffer
[6]);
423 Data
->MemoryStatus
->Used
=msg
.Buffer
[6];
427 switch (msg
.Buffer
[4]) {
429 smprintf(s
, "Phone is probably powered off.\n");
432 smprintf(s
, "Memory type not supported by phone model.\n");
433 return GE_NOTSUPPORTED
;
435 smprintf(s
, "Waiting for security code.\n");
436 return GE_SECURITYERROR
;
438 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
441 return GE_UNKNOWNRESPONSE
;
445 static GSM_Error
N6110_GetMemoryStatus(GSM_StateMachine
*s
, GSM_MemoryStatus
*Status
)
447 unsigned char req
[] = {
448 N6110_FRAME_HEADER
, 0x07,
449 0x00}; /* MemoryType */
451 req
[4] = NOKIA_GetMemoryType(s
, Status
->MemoryType
,N6110_MEMORY_TYPES
);
452 if (req
[4]==0xff) return GE_NOTSUPPORTED
;
454 s
->Phone
.Data
.MemoryStatus
=Status
;
455 smprintf(s
, "Getting memory status\n");
456 return GSM_WaitFor (s
, req
, 5, 0x03, 4, ID_GetMemoryStatus
);
459 static GSM_Error
N6110_ReplyGetSMSStatus(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
461 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
463 smprintf(s
, "SMS status received\n");
464 switch (msg
.Buffer
[3]) {
466 smprintf(s
, "SIM size : %i\n",msg
.Buffer
[7]);
467 smprintf(s
, "Used in SIM : %i\n",msg
.Buffer
[10]);
468 smprintf(s
, "Unread in SIM : %i\n",msg
.Buffer
[11]);
469 Data
->SMSStatus
->SIMUsed
= msg
.Buffer
[10];
470 Data
->SMSStatus
->SIMUnRead
= msg
.Buffer
[11];
471 Data
->SMSStatus
->SIMSize
= msg
.Buffer
[7];
472 Data
->SMSStatus
->PhoneUsed
= 0;
473 Data
->SMSStatus
->PhoneUnRead
= 0;
474 Data
->SMSStatus
->PhoneSize
= 0;
475 Data
->SMSStatus
->TemplatesUsed
= 0;
478 smprintf(s
, "Error. No PIN ?\n");
479 return GE_SECURITYERROR
;
481 return GE_UNKNOWNRESPONSE
;
484 static GSM_Error
N6110_ReplyGetSMSMessage(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
486 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
488 smprintf(s
, "SMS Message received\n");
489 switch(msg
.Buffer
[3]) {
491 Data
->GetSMSMessage
->Number
= 1;
492 Data
->GetSMSMessage
->SMS
[0].Name
[0] = 0;
493 Data
->GetSMSMessage
->SMS
[0].Name
[1] = 0;
494 NOKIA_DecodeSMSState(s
, msg
.Buffer
[4], &Data
->GetSMSMessage
->SMS
[0]);
495 switch (msg
.Buffer
[7]) {
496 case 0x00: case 0x01: /* Report or SMS_Deliver */
497 Data
->GetSMSMessage
->SMS
[0].Folder
= 0x01;
498 Data
->GetSMSMessage
->SMS
[0].InboxFolder
= true;
500 case 0x02: /* SMS_Submit */
501 Data
->GetSMSMessage
->SMS
[0].Folder
= 0x02;
502 Data
->GetSMSMessage
->SMS
[0].InboxFolder
= false;
505 return GE_UNKNOWNRESPONSE
;
507 DCT3_DecodeSMSFrame(s
, &Data
->GetSMSMessage
->SMS
[0],msg
.Buffer
+8);
510 switch (msg
.Buffer
[4]) {
512 smprintf(s
, "Unknown. Probably phone too busy\n");
515 smprintf(s
, "Too high location ?\n");
516 return GE_INVALIDLOCATION
;
518 smprintf(s
, "Phone is OFF\n");
521 smprintf(s
, "Empty\n");
524 smprintf(s
, "Access error. No PIN ?\n");
525 return GE_SECURITYERROR
;
527 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
530 return GE_UNKNOWNRESPONSE
;
533 static GSM_Error
N6110_GetSMSMessage(GSM_StateMachine
*s
, GSM_MultiSMSMessage
*sms
)
535 unsigned char req
[] = {
536 N6110_FRAME_HEADER
, 0x07, 0x02,
540 if (sms
->SMS
[0].Folder
!=0x00) return GE_NOTSUPPORTED
;
542 req
[5] = sms
->SMS
[0].Location
;
544 s
->Phone
.Data
.GetSMSMessage
=sms
;
545 smprintf(s
, "Getting sms\n");
546 return GSM_WaitFor (s
, req
, 8, 0x02, 4, ID_GetSMSMessage
);
549 static GSM_Error
N6110_GetNextSMSMessage(GSM_StateMachine
*s
, GSM_MultiSMSMessage
*sms
, bool start
)
551 GSM_Phone_N6110Data
*Priv
= &s
->Phone
.Data
.Priv
.N6110
;
555 error
=s
->Phone
.Functions
->GetSMSStatus(s
,&Priv
->LastSMSStatus
);
556 if (error
!=GE_NONE
) return error
;
558 sms
->SMS
[0].Location
=0;
561 sms
->SMS
[0].Location
++;
562 if (Priv
->LastSMSRead
>=(Priv
->LastSMSStatus
.SIMUsed
+Priv
->LastSMSStatus
.PhoneUsed
+Priv
->LastSMSStatus
.TemplatesUsed
)) return GE_EMPTY
;
563 error
=s
->Phone
.Functions
->GetSMS(s
, sms
);
564 if (error
==GE_NONE
) {
568 if (error
!= GE_EMPTY
) return error
;
573 static GSM_Error
N6110_ReplyGetStatus(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
575 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
578 smprintf(s
, "Phone status received :\n");
579 smprintf(s
, "Mode : ");
580 switch (msg
.Buffer
[4]) {
581 case 0x01: smprintf(s
, "registered within the network\n"); break;
582 case 0x02: smprintf(s
, "call in progress\n"); break; /* ringing or already answered call */
583 case 0x03: smprintf(s
, "waiting for security code\n"); break;
584 case 0x04: smprintf(s
, "powered off\n"); break;
585 default : smprintf(s
, "unknown\n");
587 smprintf(s
, "Power source : ");
588 switch (msg
.Buffer
[7]) {
589 case 0x01: smprintf(s
, "AC/DC\n"); break;
590 case 0x02: smprintf(s
, "battery\n"); break;
591 default : smprintf(s
, "unknown\n");
593 smprintf(s
, "Battery Level : %d\n", msg
.Buffer
[8]);
594 smprintf(s
, "Signal strength : %d\n", msg
.Buffer
[5]);
597 switch (Data
->RequestID
) {
598 case ID_GetBatteryCharge
:
599 Data
->BatteryCharge
->BatteryPercent
= ((int)msg
.Buffer
[8])*25;
600 switch (msg
.Buffer
[7]) {
601 case 0x01: Data
->BatteryCharge
->ChargeState
= GSM_BatteryConnected
; break;
602 case 0x02: Data
->BatteryCharge
->ChargeState
= GSM_BatteryPowered
; break;
603 default : Data
->BatteryCharge
->ChargeState
= 0;
606 case ID_GetSignalQuality
:
607 Data
->SignalQuality
->SignalPercent
= ((int)msg
.Buffer
[5])*25;
610 return GE_UNKNOWNRESPONSE
;
614 static GSM_Error
N6110_GetStatus(GSM_StateMachine
*s
, int ID
)
616 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x01};
618 return GSM_WaitFor (s
, req
, 4, 0x04, 4, ID
);
621 static GSM_Error
N6110_GetSignalQuality(GSM_StateMachine
*s
, GSM_SignalQuality
*sig
)
626 sig
->BitErrorRate
= -1;
627 sig
->SignalStrength
= -1; /* TODO for netmon */
629 smprintf(s
, "Getting network level\n");
630 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_POWER_BATT
)) {
631 error
= DCT3_Netmonitor(s
, 1, value
);
632 if (error
!=GE_NONE
) return error
;
633 sig
->SignalPercent
= 100;
635 if (value
[5]=='9' && value
[6]>'4') sig
->SignalPercent
= 25;
636 if (value
[5]=='9' && value
[6]<'5') sig
->SignalPercent
= 50;
637 if (value
[5]=='8' && value
[6]>'4') sig
->SignalPercent
= 75;
638 } else sig
->SignalPercent
= 0;
641 s
->Phone
.Data
.SignalQuality
= sig
;
642 return N6110_GetStatus(s
, ID_GetSignalQuality
);
646 static GSM_Error
N6110_GetBatteryCharge(GSM_StateMachine
*s
, GSM_BatteryCharge
*bat
)
651 smprintf(s
, "Getting battery level\n");
652 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_POWER_BATT
)) {
653 error
= DCT3_Netmonitor(s
, 23, value
);
654 if (error
!=GE_NONE
) return error
;
655 bat
->BatteryPercent
= 100;
656 bat
->ChargeState
= 0;
657 if (value
[29]=='7') bat
->BatteryPercent
= 75;
658 if (value
[29]=='5') bat
->BatteryPercent
= 50;
659 if (value
[29]=='2') bat
->BatteryPercent
= 25;
662 s
->Phone
.Data
.BatteryCharge
= bat
;
663 return N6110_GetStatus(s
, ID_GetBatteryCharge
);
667 static GSM_Error
N6110_ReplySaveSMSMessage(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
669 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
671 smprintf(s
, "SMS message saving status\n");
672 switch (msg
.Buffer
[3]) {
674 smprintf(s
, "Saved at location %i\n",msg
.Buffer
[5]);
675 Data
->SaveSMSMessage
->Location
=msg
.Buffer
[5];
678 switch (msg
.Buffer
[4]) {
680 smprintf(s
, "All locations busy\n");
683 smprintf(s
, "Too high ?\n");
684 return GE_INVALIDLOCATION
;
686 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
689 return GE_UNKNOWNRESPONSE
;
692 static GSM_Error
N6110_PrivSetSMSMessage(GSM_StateMachine
*s
, GSM_SMSMessage
*sms
)
696 unsigned char req
[256] = {
697 N6110_FRAME_HEADER
, 0x04,
698 0x00, /* SMS State */
700 0x00, /* SMS Location */
701 0x02}; /* SMS Type */
703 req
[6] = sms
->Location
;
704 if (sms
->Folder
==1) { /* Inbox */
705 req
[4] = 1; /* SMS State - GSM_Read */
706 req
[7] = 0x00; /* SMS Type */
707 sms
->PDU
= SMS_Deliver
;
708 error
=PHONE_EncodeSMSFrame(s
,sms
,req
+8,PHONE_SMSDeliver
,&length
,true);
709 } else { /* Outbox */
710 req
[4] = 5; /* SMS State - GSM_Sent */
711 req
[7] = 0x02; /* SMS Type */
712 sms
->PDU
= SMS_Submit
;
713 error
=PHONE_EncodeSMSFrame(s
,sms
,req
+8,PHONE_SMSSubmit
,&length
,true);
715 if (error
!= GE_NONE
) return error
;
717 /* SMS State - GSM_Read -> GSM_Unread and GSM_Sent -> GSM_UnSent */
718 if (sms
->State
== GSM_UnSent
|| sms
->State
== GSM_UnRead
) req
[4] |= 0x02;
720 s
->Phone
.Data
.SaveSMSMessage
=sms
;
721 smprintf(s
, "Saving sms\n");
722 return GSM_WaitFor (s
, req
, 8+length
, 0x14, 4, ID_SaveSMSMessage
);
725 static GSM_Error
N6110_SetSMS(GSM_StateMachine
*s
, GSM_SMSMessage
*sms
)
727 if (sms
->Location
== 0) return GE_INVALIDLOCATION
;
728 return N6110_PrivSetSMSMessage(s
, sms
);
731 static GSM_Error
N6110_AddSMS(GSM_StateMachine
*s
, GSM_SMSMessage
*sms
)
734 return N6110_PrivSetSMSMessage(s
, sms
);
737 static GSM_Error
N6110_ReplySetRingtone(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
739 switch (msg
.Buffer
[3]) {
741 smprintf(s
, "Ringtone set OK\n");
745 smprintf(s
, "Error setting ringtone\n");
746 switch (msg
.Buffer
[4]) {
748 smprintf(s
, "Too high location ?\n");
749 return GE_INVALIDLOCATION
;
751 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
754 return GE_UNKNOWNRESPONSE
;
757 static GSM_Error
N6110_ReplySetBinRingtone(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
759 switch (msg
.Buffer
[4]) {
761 smprintf(s
, "Set at location %i\n",msg
.Buffer
[3]+1);
764 smprintf(s
, "Invalid location. Too high ?\n");
765 return GE_INVALIDLOCATION
;
769 static GSM_Error
N6110_SetRingtone(GSM_StateMachine
*s
, GSM_Ringtone
*Ringtone
, int *maxlength
)
771 GSM_NetworkInfo NetInfo
;
773 int size
=200,current
=8;
774 GSM_UDHHeader UDHHeader
;
775 unsigned char req
[1000] = {
776 N6110_FRAME_HEADER
, 0x36,
779 unsigned char reqBin
[1000] = {0x00,0x01,0xa0,0x00,0x00,0x0c,0x01,0x2c};
781 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_NORING
)) return GE_NOTSUPPORTED
;
782 if (Ringtone
->Location
== 0) return GE_INVALIDLOCATION
;
784 switch (Ringtone
->Format
) {
786 if (Ringtone
->Location
==255)
788 /* Only 6110, 6130 and 6150 support it */
789 if (strcmp(s
->Phone
.Data
.Model
,"NSE-3") == 0 || strcmp(s
->Phone
.Data
.Model
,"NSK-3") == 0 ||
790 strcmp(s
->Phone
.Data
.Model
,"NSM-1") == 0)
794 UDHHeader
.Type
= UDH_NokiaRingtone
;
795 GSM_EncodeUDHHeader(&UDHHeader
);
796 /* We copy UDH now */
797 memcpy(req
+2,UDHHeader
.Text
,UDHHeader
.Length
);
798 *maxlength
=GSM_EncodeNokiaRTTLRingtone(*Ringtone
, req
+2+UDHHeader
.Length
, &size
);
799 error
= s
->Protocol
.Functions
->WriteMessage(s
, req
, 2+UDHHeader
.Length
+size
, 0x12);
800 if (error
!=GE_NONE
) return error
;
802 /* We have to make something (not important, what) now */
803 /* no answer from phone*/
804 return DCT3_GetNetworkInfo(s
,&NetInfo
);
806 return GE_NOTSUPPORTED
;
809 *maxlength
=GSM_EncodeNokiaRTTLRingtone(*Ringtone
, req
+7, &size
);
810 req
[4] = Ringtone
->Location
- 1;
811 smprintf(s
, "Setting ringtone\n");
812 return GSM_WaitFor (s
, req
, 7 + size
, 0x05, 4, ID_SetRingtone
);
813 case RING_NOKIABINARY
:
814 error
=DCT3_EnableSecurity (s
, 0x01);
815 if (error
!=GE_NONE
) return error
;
816 memcpy(reqBin
+current
,DecodeUnicodeString(Ringtone
->Name
),UnicodeLength(Ringtone
->Name
));
817 current
+= UnicodeLength(Ringtone
->Name
);
818 reqBin
[current
++] = 0x00;
819 reqBin
[current
++] = 0x00;
820 reqBin
[current
++] = 0x00;/*xxx*/
821 memcpy(reqBin
+current
,Ringtone
->NokiaBinary
.Frame
,Ringtone
->NokiaBinary
.Length
);
822 current
=current
+Ringtone
->NokiaBinary
.Length
;
823 reqBin
[3]=Ringtone
->Location
-1;
824 if (!strcmp(s
->Phone
.Data
.ModelInfo
->model
,"3210")) reqBin
[5]=0x10;
825 smprintf(s
, "Setting binary ringtone\n");
826 return GSM_WaitFor (s
, reqBin
, current
, 0x40, 4, ID_SetRingtone
);
828 return GE_NOTSUPPORTED
;
830 return GE_NOTSUPPORTED
;
833 static GSM_Error
N6110_ReplyGetOpLogo(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
836 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
838 smprintf(s
, "Operator logo received\n");
839 NOKIA_DecodeNetworkCode(msg
.Buffer
+count
,Data
->Bitmap
->NetworkCode
);
841 smprintf(s
, " Network code : %s\n", Data
->Bitmap
->NetworkCode
);
842 smprintf(s
, " Network name for Gammu : %s ",
843 DecodeUnicodeString(GSM_GetNetworkName(Data
->Bitmap
->NetworkCode
)));
844 smprintf(s
, "(%s)\n",DecodeUnicodeString(GSM_GetCountryName(Data
->Bitmap
->NetworkCode
)));
845 count
= count
+ 3; /* We ignore size */
846 Data
->Bitmap
->Width
= msg
.Buffer
[count
++];
847 Data
->Bitmap
->Height
= msg
.Buffer
[count
++];
849 PHONE_DecodeBitmap(GSM_NokiaOperatorLogo
,msg
.Buffer
+count
,Data
->Bitmap
);
853 static GSM_Error
N6110_ReplyGetStartup(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
856 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
858 smprintf(s
, "Startup logo & notes received\n");
859 for (i
=0;i
<msg
.Buffer
[4];i
++) {
860 switch (msg
.Buffer
[count
++]) {
862 smprintf(s
, "Startup logo\n");
863 if (Data
->Bitmap
->Type
== GSM_StartupLogo
) {
864 Data
->Bitmap
->Height
= msg
.Buffer
[count
++];
865 Data
->Bitmap
->Width
= msg
.Buffer
[count
++];
866 PHONE_DecodeBitmap(GSM_NokiaStartupLogo
, msg
.Buffer
+ count
, Data
->Bitmap
);
870 count
= count
+ PHONE_GetBitmapSize(GSM_NokiaStartupLogo
,0,0);
873 smprintf(s
, "Welcome note\n");
874 if (Data
->Bitmap
->Type
== GSM_WelcomeNoteText
) {
875 EncodeUnicode(Data
->Bitmap
->Text
,msg
.Buffer
+count
, msg
.Buffer
[count
]);
876 smprintf(s
, "Text is \"%s\"\n",Data
->Bitmap
->Text
);
878 count
= count
+ msg
.Buffer
[count
] + 1;
881 smprintf(s
, "Dealer welcome note\n");
882 if (Data
->Bitmap
->Type
== GSM_DealerNoteText
) {
883 EncodeUnicode(Data
->Bitmap
->Text
,msg
.Buffer
+count
, msg
.Buffer
[count
]);
884 smprintf(s
, "Text is \"%s\"\n",Data
->Bitmap
->Text
);
886 count
= count
+ msg
.Buffer
[count
] + 1;
889 smprintf(s
, "Unknown block\n");
890 return GE_UNKNOWNRESPONSE
;
897 static GSM_Error
N6110_ReplyGetCallerLogo(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
900 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
902 switch (msg
.Buffer
[3]) {
904 smprintf(s
, "Caller group info received\n");
905 EncodeUnicode(Data
->Bitmap
->Text
,msg
.Buffer
+6,msg
.Buffer
[5]);
906 smprintf(s
, "Name : \"%s\"\n",DecodeUnicodeString(Data
->Bitmap
->Text
));
907 Data
->Bitmap
->DefaultName
= false;
908 if (msg
.Buffer
[5] == 0x00) Data
->Bitmap
->DefaultName
= true;
909 count
= msg
.Buffer
[5] + 6;
910 Data
->Bitmap
->Ringtone
= msg
.Buffer
[count
++];
911 Data
->Bitmap
->DefaultRingtone
= false;
912 if (Data
->Bitmap
->Ringtone
== 16) Data
->Bitmap
->DefaultRingtone
= true;
913 smprintf(s
, "Ringtone ID: %02x\n",Data
->Bitmap
->Ringtone
);
914 Data
->Bitmap
->Enabled
=(msg
.Buffer
[count
++]==1);
916 smprintf(s
, "Caller group logo ");
917 if (Data
->Bitmap
->Enabled
)
918 smprintf(s
, "enabled\n");
920 smprintf(s
, "disabled\n");
922 count
= count
+ 3; /* We ignore size */
923 Data
->Bitmap
->Width
= msg
.Buffer
[count
++];
924 Data
->Bitmap
->Height
= msg
.Buffer
[count
++];
926 PHONE_DecodeBitmap(GSM_NokiaCallerLogo
,msg
.Buffer
+count
,Data
->Bitmap
);
927 Data
->Bitmap
->DefaultBitmap
= false;
930 smprintf(s
, "Error getting caller group info\n");
931 return GE_INVALIDLOCATION
;
933 return GE_UNKNOWNRESPONSE
;
936 static GSM_Error
N6110_ReplyGetSetPicture(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
939 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
941 switch (msg
.Buffer
[3]) {
943 smprintf(s
, "Picture Image received\n");
944 if (msg
.Buffer
[count
]!=0) {
945 GSM_UnpackSemiOctetNumber(Data
->Bitmap
->Sender
, msg
.Buffer
+ 5, true);
946 /* Convert number of semioctets to number of chars */
950 count
= count
+ i
+ 1;
952 Data
->Bitmap
->Sender
[0] = 0x00;
953 Data
->Bitmap
->Sender
[1] = 0x00;
956 smprintf(s
, "Sender : \"%s\"\n",DecodeUnicodeString(Data
->Bitmap
->Sender
));
957 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_NOPICTUREUNI
) ||
958 (!strcmp(Data
->Model
,"NHM-5") && Data
->VerNum
< 5.79)) {
960 EncodeUnicode(Data
->Bitmap
->Text
,msg
.Buffer
+count
+1,msg
.Buffer
[count
]);
961 count
+= UnicodeLength(Data
->Bitmap
->Text
) + 1;
963 if (!strcmp(Data
->Model
,"NHM-5")) {
964 i
= msg
.Buffer
[count
] * 256 + msg
.Buffer
[count
+1];
967 i
= msg
.Buffer
[count
] * 256 + msg
.Buffer
[count
+1] - 2;
970 memcpy(Data
->Bitmap
->Text
,msg
.Buffer
+count
+2,i
);
971 Data
->Bitmap
->Text
[i
] = 0;
972 Data
->Bitmap
->Text
[i
+1] = 0;
975 smprintf(s
, "Text : \"%s\"\n",DecodeUnicodeString(Data
->Bitmap
->Text
));
976 Data
->Bitmap
->Width
= msg
.Buffer
[count
++];
977 Data
->Bitmap
->Height
= msg
.Buffer
[count
++];
978 PHONE_DecodeBitmap(GSM_NokiaPictureImage
, msg
.Buffer
+ count
+ 2, Data
->Bitmap
);
980 if (di
.dl
== DL_TEXTALL
|| di
.dl
== DL_TEXTALLDATE
) GSM_PrintBitmap(di
.df
,Data
->Bitmap
);
985 smprintf(s
, "Picture Image set OK\n");
988 smprintf(s
, "Can't set Picture Image - invalid location ?\n");
989 return GE_INVALIDLOCATION
;
992 smprintf(s
, "Can't get Picture Image - invalid location ?\n");
993 return GE_INVALIDLOCATION
;
996 return GE_UNKNOWNRESPONSE
;
999 static GSM_Error
N6110_GetBitmap(GSM_StateMachine
*s
, GSM_Bitmap
*Bitmap
)
1002 unsigned char req
[10] = { N6110_FRAME_HEADER
};
1004 s
->Phone
.Data
.Bitmap
=Bitmap
;
1005 switch (Bitmap
->Type
) {
1006 case GSM_StartupLogo
:
1007 case GSM_WelcomeNoteText
:
1008 case GSM_DealerNoteText
:
1009 if (Bitmap
->Type
== GSM_StartupLogo
&& IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_NOSTARTUP
)) return GE_NOTSUPPORTED
;
1011 return GSM_WaitFor (s
, req
, 4, 0x05, 4, ID_GetBitmap
);
1012 case GSM_CallerLogo
:
1013 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_NOCALLER
)) return GE_NOTSUPPORTED
;
1015 req
[4] = Bitmap
->Location
- 1;
1016 error
= GSM_WaitFor (s
, req
, 5, 0x03, 4, ID_GetBitmap
);
1017 if (error
==GE_NONE
) NOKIA_GetDefaultCallerGroupName(s
,Bitmap
);
1019 case GSM_OperatorLogo
:
1022 return GSM_WaitFor (s
, req
, 5, 0x05, 4, ID_GetBitmap
);
1023 case GSM_PictureImage
:
1024 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_NOPICTURE
)) return GE_NOTSUPPORTED
;
1026 req
[4] = Bitmap
->Location
- 1;
1027 return GSM_WaitFor (s
, req
, 5, 0x47, 4, ID_GetBitmap
);
1031 return GE_NOTSUPPORTED
;
1034 static GSM_Error
N6110_ReplySetProfileFeature(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1036 switch (msg
.Buffer
[3]) {
1038 smprintf(s
, "Feature of profile set\n");
1041 smprintf(s
, "Error setting profile feature\n");
1042 return GE_NOTSUPPORTED
;
1044 return GE_UNKNOWNRESPONSE
;
1047 static GSM_Error
N6110_SetProfileFeature(GSM_StateMachine
*s
, unsigned char profile
, unsigned char feature
, unsigned char value
)
1049 unsigned char req
[] = {
1050 N6110_FRAME_HEADER
, 0x10, 0x01,
1058 smprintf(s
, "Setting profile feature\n");
1059 return GSM_WaitFor (s
, req
, 8, 0x05, 4, ID_SetProfile
);
1062 static GSM_Error
N6110_ReplySetStartup(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1064 smprintf(s
, "Startup logo set OK\n");
1068 static GSM_Error
N6110_ReplySetCallerLogo(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1070 switch (msg
.Buffer
[3]) {
1072 smprintf(s
, "Caller group set OK\n");
1075 smprintf(s
, "Error setting caller group\n");
1076 return GE_INVALIDLOCATION
;
1078 return GE_UNKNOWNRESPONSE
;
1081 static GSM_Error
N6110_SetBitmap(GSM_StateMachine
*s
, GSM_Bitmap
*Bitmap
)
1083 unsigned char reqPreview
[1000] = {0x0c,0x01};
1084 unsigned char req
[600] = { N6110_FRAME_HEADER
};
1085 GSM_UDH UDHType
= UDH_NokiaOperatorLogo
;
1086 GSM_UDHHeader UDHHeader
;
1087 GSM_NetworkInfo NetInfo
;
1093 switch (Bitmap
->Type
) {
1094 case GSM_CallerLogo
:
1095 case GSM_OperatorLogo
:
1096 if (Bitmap
->Location
== 255) {
1097 /* Only 6110, 6130 and 6150 support it */
1098 if (strcmp(s
->Phone
.Data
.Model
,"NSE-3") == 0 || strcmp(s
->Phone
.Data
.Model
,"NSK-3") == 0 ||
1099 strcmp(s
->Phone
.Data
.Model
,"NSM-1") == 0)
1101 if (Bitmap
->Type
==GSM_CallerLogo
) UDHType
= UDH_NokiaCallerLogo
;
1102 UDHHeader
.Type
= UDHType
;
1103 GSM_EncodeUDHHeader(&UDHHeader
);
1104 /* We copy UDH now */
1105 memcpy(reqPreview
+2,UDHHeader
.Text
,UDHHeader
.Length
);
1106 count
= count
+ UDHHeader
.Length
;
1107 if (Bitmap
->Type
== GSM_OperatorLogo
) {
1108 NOKIA_EncodeNetworkCode(reqPreview
+count
,Bitmap
->NetworkCode
);
1111 if (Bitmap
->DefaultBitmap
) {
1113 Bitmap
->Height
= 14;
1114 GSM_ClearBitmap(Bitmap
);
1117 NOKIA_CopyBitmap(GSM_NokiaOperatorLogo
,Bitmap
,reqPreview
, &count
);
1118 reqPreview
[count
]=0x00;
1119 error
= s
->Protocol
.Functions
->WriteMessage(s
, reqPreview
, count
+ 1, 0x12);
1120 if (error
!=GE_NONE
) return error
;
1122 /* We have to make something (not important, what) now */
1123 /* no answer from phone*/
1124 return DCT3_GetNetworkInfo(s
,&NetInfo
);
1126 smprintf(s
, "%s\n",s
->Phone
.Data
.Model
);
1127 return GE_NOTSUPPORTED
;
1137 switch (Bitmap
->Type
) {
1138 case GSM_StartupLogo
:
1139 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_NOSTARTUP
)) return GE_NOTSUPPORTED
;
1140 if (Bitmap
->Location
!= 1) {
1141 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_NOSTARTANI
)) return GE_NOTSUPPORTED
;
1143 if (!IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_NOSTARTANI
)) {
1144 if (!strcmp(s
->Phone
.Data
.ModelInfo
->model
,"3210")) {
1145 error
= N6110_SetProfileFeature(s
,0,0x2e,((unsigned char)(Bitmap
->Location
-1)));
1147 error
= N6110_SetProfileFeature(s
,0,0x29,((unsigned char)(Bitmap
->Location
-1)));
1149 if (error
== GE_NOTSUPPORTED
) error
= GE_SECURITYERROR
;
1150 if (error
!= GE_NONE
) return error
;
1151 if (Bitmap
->Location
!= 1) return GE_NONE
;
1153 req
[count
++] = 0x18;
1154 req
[count
++] = 0x01; /* One block */
1155 req
[count
++] = 0x01;
1156 PHONE_GetBitmapWidthHeight(GSM_NokiaStartupLogo
, &Width
, &Height
);
1157 req
[count
++] = Height
;
1158 req
[count
++] = Width
;
1159 PHONE_EncodeBitmap(GSM_NokiaStartupLogo
, req
+ count
, Bitmap
);
1160 count
= count
+ PHONE_GetBitmapSize(GSM_NokiaStartupLogo
,0,0);
1161 return GSM_WaitFor (s
, req
, count
, 0x05, 4, ID_SetBitmap
);
1162 case GSM_WelcomeNoteText
:
1163 case GSM_DealerNoteText
:
1164 req
[count
++] = 0x18;
1165 req
[count
++] = 0x01; /* One block */
1166 if (Bitmap
->Type
== GSM_WelcomeNoteText
) {
1167 req
[count
++] = 0x02;
1169 req
[count
++] = 0x03;
1171 textlen
= UnicodeLength(Bitmap
->Text
);
1172 req
[count
++] = textlen
;
1173 memcpy(req
+ count
,DecodeUnicodeString(Bitmap
->Text
),textlen
);
1175 return GSM_WaitFor (s
, req
, count
, 0x05, 4, ID_SetBitmap
);
1176 case GSM_CallerLogo
:
1177 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_NOCALLER
)) return GE_NOTSUPPORTED
;
1178 req
[count
++] = 0x13;
1179 req
[count
++] = Bitmap
->Location
- 1;
1180 if (Bitmap
->DefaultName
) {
1183 textlen
= UnicodeLength(Bitmap
->Text
);
1184 req
[count
++] = textlen
;
1185 memcpy(req
+count
,DecodeUnicodeString(Bitmap
->Text
),textlen
);
1188 if (Bitmap
->DefaultRingtone
) {
1191 req
[count
++] = Bitmap
->Ringtone
;
1193 /* Setting for graphic:
1196 * 0x02 - View Graphics
1197 * 0x03 - Send Graphics
1198 * 0x04 - Send via IR
1199 * When set to higher, some phones (like 6110) will not show
1200 * the name of this item in menu
1202 if (Bitmap
->DefaultBitmap
) {
1204 Bitmap
->Height
= 14;
1205 GSM_ClearBitmap(Bitmap
);
1208 if (Bitmap
->Enabled
) req
[count
++] = 0x01; else req
[count
++] = 0x00;
1210 req
[count
++] = (PHONE_GetBitmapSize(GSM_NokiaCallerLogo
,0,0) + 4) >> 8;
1211 req
[count
++] = (PHONE_GetBitmapSize(GSM_NokiaCallerLogo
,0,0) + 4) % 0xff;
1212 NOKIA_CopyBitmap(GSM_NokiaCallerLogo
, Bitmap
, req
, &count
);
1213 return GSM_WaitFor (s
, req
, count
, 0x03, 4, ID_SetBitmap
);
1214 case GSM_OperatorLogo
:
1215 req
[count
++] = 0x30;
1216 req
[count
++] = 0x01;
1217 NOKIA_EncodeNetworkCode(req
+count
, Bitmap
->NetworkCode
);
1219 req
[count
++] = (PHONE_GetBitmapSize(GSM_NokiaOperatorLogo
,0,0) + 4) >> 8;
1220 req
[count
++] = (PHONE_GetBitmapSize(GSM_NokiaOperatorLogo
,0,0) + 4) % 0xff;
1221 NOKIA_CopyBitmap(GSM_NokiaOperatorLogo
, Bitmap
, req
, &count
);
1222 return GSM_WaitFor (s
, req
, count
, 0x05, 4, ID_SetBitmap
);
1223 case GSM_PictureImage
:
1224 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_NOPICTURE
)) return GE_NOTSUPPORTED
;
1225 req
[count
++] = 0x03;
1226 req
[count
++] = Bitmap
->Location
- 1;
1227 if (Bitmap
->Sender
[0]!=0 || Bitmap
->Sender
[1]!=0)
1229 req
[count
]=GSM_PackSemiOctetNumber(Bitmap
->Sender
, req
+count
+1,true);
1230 /* Convert number of semioctets to number of chars and add count */
1231 textlen
= req
[count
];
1232 if (textlen
% 2) textlen
++;
1233 count
+= textlen
/ 2 + 1;
1236 req
[count
++] = 0x00;
1237 req
[count
++] = 0x00;
1239 req
[count
++] = 0x00;
1240 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_NOPICTUREUNI
) ||
1241 (!strcmp(s
->Phone
.Data
.Model
,"NHM-5") && s
->Phone
.Data
.VerNum
< 5.79)) {
1242 textlen
= UnicodeLength(Bitmap
->Text
);
1243 req
[count
++] = textlen
;
1244 memcpy(req
+count
,DecodeUnicodeString(Bitmap
->Text
),textlen
);
1247 textlen
= UnicodeLength(Bitmap
->Text
)*2;
1248 if (!strcmp(s
->Phone
.Data
.Model
,"NHM-5")) {
1249 req
[count
++] = textlen
;
1252 req
[count
++] = textlen
+2;
1253 req
[count
++] = 0x00;
1254 req
[count
++] = 0x1e;
1256 memcpy(req
+count
,Bitmap
->Text
,textlen
);
1259 NOKIA_CopyBitmap(GSM_NokiaPictureImage
, Bitmap
, req
, &count
);
1260 return GSM_WaitFor (s
, req
, count
, 0x47, 4, ID_SetBitmap
);
1264 return GE_NOTSUPPORTED
;
1267 static GSM_Error
N6110_ReplyCallInfo(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1269 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
1273 call
.CallIDAvailable
= true;
1275 smprintf(s
, "Call info, ");
1276 switch (msg
.Buffer
[3]) {
1278 smprintf(s
, "Call established, waiting for answer\n");
1279 call
.Status
= GN_CALL_CallEstablished
;
1282 smprintf(s
, "Call started\n");
1283 /* no phone number in frame */
1284 call
.Status
= GN_CALL_CallStart
;
1287 smprintf(s
, "Remote end hang up\n");
1288 smprintf(s
, "CC : %i\n",msg
.Buffer
[6]);
1289 call
.Status
= GN_CALL_CallRemoteEnd
;
1290 call
.StatusCode
= msg
.Buffer
[6];
1293 smprintf(s
, "Incoming call\n");
1294 smprintf(s
, "Number : \"");
1295 count
=msg
.Buffer
[6];
1296 for (tmp
=0; tmp
<count
; tmp
++) smprintf(s
, "%c", msg
.Buffer
[7+tmp
]);
1297 smprintf(s
, "\"\nName : \"");
1298 for (tmp
=0; tmp
<msg
.Buffer
[7+count
]; tmp
++) smprintf(s
, "%c", msg
.Buffer
[8+count
+tmp
]);
1299 smprintf(s
, "\"\n");
1301 call
.Status
= GN_CALL_IncomingCall
;
1302 EncodeUnicode(call
.PhoneNumber
, msg
.Buffer
+7, msg
.Buffer
[6]);
1305 smprintf(s
, "Call answer initiated\n");
1308 smprintf(s
, "Call released\n");
1309 call
.Status
= GN_CALL_CallLocalEnd
;
1312 smprintf(s
, "Call is being released\n");
1315 smprintf(s
, "Call held\n");
1316 call
.Status
= GN_CALL_CallHeld
;
1319 smprintf(s
, "Call resumed\n");
1320 call
.Status
= GN_CALL_CallResumed
;
1323 smprintf(s
, "Call switched\n");
1324 /* incorrect call id in frame - 6150 5.22 */
1325 call
.CallIDAvailable
= false;
1326 call
.Status
= GN_CALL_CallSwitched
;
1329 smprintf(s
, "Joining call to the conference (conference)\n");
1332 smprintf(s
, "Removing call from the conference (split)\n");
1335 if (call
.CallIDAvailable
) smprintf(s
, "Call ID : %d\n",msg
.Buffer
[4]);
1336 if (Data
->EnableIncomingCall
&& s
->User
.IncomingCall
!=NULL
&& call
.Status
!= 0) {
1337 if (call
.CallIDAvailable
) call
.CallID
= msg
.Buffer
[4];
1338 s
->User
.IncomingCall(s
->CurrentConfig
->Device
, call
);
1340 if (s
->Phone
.Data
.RequestID
== ID_CancelCall
) {
1341 if (msg
.Buffer
[3] == 0x09) {
1342 if (s
->Phone
.Data
.CallID
== msg
.Buffer
[4]) return GE_NONE
;
1343 /* when we canceled call and see frame about other
1344 * call releasing, we don't give GE_NONE for "our"
1345 * call release command
1347 return GE_NEEDANOTHERANSWER
;
1350 if (s
->Phone
.Data
.RequestID
== ID_AnswerCall
) {
1351 if (msg
.Buffer
[3] == 0x07) {
1352 if (s
->Phone
.Data
.CallID
== msg
.Buffer
[4]) return GE_NONE
;
1353 return GE_NEEDANOTHERANSWER
;
1356 if (s
->Phone
.Data
.RequestID
== ID_UnholdCall
) {
1357 if (msg
.Buffer
[3] == 0x25) {
1358 if (s
->Phone
.Data
.CallID
== msg
.Buffer
[4]) return GE_NONE
;
1359 return GE_NEEDANOTHERANSWER
;
1362 if (s
->Phone
.Data
.RequestID
== ID_HoldCall
) {
1363 if (msg
.Buffer
[3] == 0x23) {
1364 if (s
->Phone
.Data
.CallID
== msg
.Buffer
[4]) return GE_NONE
;
1365 return GE_NEEDANOTHERANSWER
;
1368 if (s
->Phone
.Data
.RequestID
== ID_ConferenceCall
) {
1369 if (msg
.Buffer
[3] == 0x29) {
1370 if (s
->Phone
.Data
.CallID
== msg
.Buffer
[4]) return GE_NONE
;
1371 return GE_NEEDANOTHERANSWER
;
1374 if (s
->Phone
.Data
.RequestID
== ID_SplitCall
) {
1375 if (msg
.Buffer
[3] == 0x2B) {
1376 if (s
->Phone
.Data
.CallID
== msg
.Buffer
[4]) return GE_NONE
;
1377 return GE_NEEDANOTHERANSWER
;
1383 static GSM_Error
N6110_DeleteSMSMessage(GSM_StateMachine
*s
, GSM_SMSMessage
*sms
)
1385 unsigned char req
[] = {
1386 N6110_FRAME_HEADER
, 0x0a, 0x02,
1387 0x00}; /* Location */
1389 if (sms
->Folder
!=0x00) return GE_NOTSUPPORTED
;
1391 req
[5]=sms
->Location
;
1393 smprintf(s
, "Deleting sms\n");
1394 return GSM_WaitFor (s
, req
, 6, 0x14, 4, ID_DeleteSMSMessage
);
1397 static GSM_Error
N6110_ReplySetMemory(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1399 smprintf(s
, "Reply for writing memory\n");
1400 switch (msg
.Buffer
[3]) {
1402 smprintf(s
, "Done OK\n");
1405 smprintf(s
, "Error\n");
1406 switch (msg
.Buffer
[4]) {
1408 smprintf(s
, "Too high location ?\n");
1409 return GE_INVALIDLOCATION
;
1411 smprintf(s
, "Too long name...or other error\n");
1412 return GE_NOTSUPPORTED
;
1414 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
1417 return GE_UNKNOWNRESPONSE
;
1420 static GSM_Error
N6110_SetMemory(GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
)
1422 int current
, Group
, Name
, Number
;
1423 unsigned char req
[128] = {
1424 N6110_FRAME_HEADER
, 0x04,
1425 0x00, /* memory type */
1426 0x00}; /* location */
1428 if (entry
->Location
== 0) return GE_NOTSUPPORTED
;
1430 GSM_PhonebookFindDefaultNameNumberGroup(entry
, &Name
, &Number
, &Group
);
1432 req
[4] = NOKIA_GetMemoryType(s
, entry
->MemoryType
,N6110_MEMORY_TYPES
);
1433 req
[5] = entry
->Location
;
1437 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_NOPBKUNICODE
)) {
1439 req
[6] = UnicodeLength(entry
->Entries
[Name
].Text
);
1440 memcpy(req
+current
,DecodeUnicodeString(entry
->Entries
[Name
].Text
),UnicodeLength(entry
->Entries
[Name
].Text
));
1441 current
+= UnicodeLength(entry
->Entries
[Name
].Text
);
1445 req
[6] = UnicodeLength(entry
->Entries
[Name
].Text
)*2+2;
1446 memcpy(req
+current
,entry
->Entries
[Name
].Text
,UnicodeLength(entry
->Entries
[Name
].Text
)*2);
1447 current
+= UnicodeLength(entry
->Entries
[Name
].Text
)*2;
1449 req
[current
++]=0x00;
1450 req
[current
++]=0x00;
1454 req
[current
++]=UnicodeLength(entry
->Entries
[Number
].Text
);
1455 memcpy(req
+current
,DecodeUnicodeString(entry
->Entries
[Number
].Text
),UnicodeLength(entry
->Entries
[Number
].Text
));
1456 current
+= UnicodeLength(entry
->Entries
[Number
].Text
);
1457 } else req
[current
++] = 0;
1459 /* This allow to save 14 characters name into SIM memory, when
1460 * no caller group is selected. */
1462 req
[current
++] = 0xff;
1464 req
[current
++] = entry
->Entries
[Group
].Number
-1;
1467 smprintf(s
, "Writing phonebook entry\n");
1468 return GSM_WaitFor (s
, req
, current
, 0x03, 4, ID_SetMemory
);
1471 static GSM_Error
N6110_DeleteMemory(GSM_StateMachine
*s
, GSM_MemoryEntry
*entry
)
1473 GSM_MemoryEntry dwa
;
1475 dwa
.Location
= entry
->Location
;
1476 dwa
.MemoryType
= entry
->MemoryType
;
1479 return N6110_SetMemory(s
, &dwa
);
1482 static GSM_Error
N6110_ReplyGetRingtone(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1484 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
1489 smprintf(s
, "Ringtone received\n");
1490 switch (msg
.Buffer
[4]) {
1492 switch (Data
->Ringtone
->Format
) {
1494 memcpy(buffer
,msg
.Buffer
,msg
.Length
);
1496 if (buffer
[9]==0x4a && buffer
[10]==0x3a) i
=8;
1498 error
=GSM_DecodeNokiaRTTLRingtone(Data
->Ringtone
, buffer
+i
, msg
.Length
-i
);
1499 if (error
!=GE_NONE
) return GE_EMPTY
;
1501 case RING_NOKIABINARY
:
1503 while (msg
.Buffer
[i
]!=0) {
1505 if (i
>msg
.Length
) return GE_EMPTY
;
1507 EncodeUnicode(Data
->Ringtone
->Name
,msg
.Buffer
+8,i
-8);
1508 smprintf(s
, "Name \"%s\"\n",DecodeUnicodeString(Data
->Ringtone
->Name
));
1509 /* Looking for start && end */
1513 if (msg
.Buffer
[i
]==0x07 && msg
.Buffer
[i
+1]==0x0b) {
1516 if (msg
.Buffer
[i
]==0x0e && msg
.Buffer
[i
+1]==0x0b) {
1520 if (msg
.Buffer
[i
]==0x02 && msg
.Buffer
[i
+1]==0xfc && msg
.Buffer
[i
+2]==0x09) {
1525 if (i
==msg
.Length
-3) return GE_EMPTY
;
1528 memcpy(Data
->Ringtone
->NokiaBinary
.Frame
,msg
.Buffer
+start
,end
-start
);
1529 Data
->Ringtone
->NokiaBinary
.Length
=end
-start
;
1531 if (di
.dl
== DL_TEXTALL
|| di
.dl
== DL_TEXTALLDATE
) DumpMessage(di
.df
, Data
->Ringtone
->NokiaBinary
.Frame
, Data
->Ringtone
->NokiaBinary
.Length
);
1535 return GE_NOTSUPPORTED
;
1537 smprintf(s
, "Ringtone format is %i\n",Data
->Ringtone
->Format
);
1540 smprintf(s
, "Invalid location. Too high ?\n");
1541 return GE_INVALIDLOCATION
;
1543 return GE_UNKNOWNRESPONSE
;
1546 static GSM_Error
N6110_GetRingtone(GSM_StateMachine
*s
, GSM_Ringtone
*Ringtone
, bool PhoneRingtone
)
1549 unsigned char req
[] = {
1551 0x00 }; /* location */
1553 if (PhoneRingtone
) return GE_NOTSUPPORTED
;
1554 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_NORING
)) return GE_NOTSUPPORTED
;
1555 if (Ringtone
->Location
== 0) return GE_INVALIDLOCATION
;
1557 if (Ringtone
->Format
== 0x00) {
1558 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_RING_SM
)) {
1559 Ringtone
->Format
= RING_NOTETONE
;
1561 Ringtone
->Format
= RING_NOKIABINARY
;
1565 switch (Ringtone
->Format
) {
1567 if (!IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_RING_SM
)) return GE_NOTSUPPORTED
;
1569 case RING_NOKIABINARY
:
1570 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_RING_SM
)) return GE_NOTSUPPORTED
;
1573 return GE_NOTSUPPORTED
;
1576 error
=DCT3_EnableSecurity (s
, 0x01);
1577 if (error
!=GE_NONE
) return error
;
1579 req
[3]=Ringtone
->Location
-1;
1580 s
->Phone
.Data
.Ringtone
=Ringtone
;
1581 smprintf(s
, "Getting (binary) ringtone\n");
1582 return GSM_WaitFor (s
, req
, 4, 0x40, 4, ID_GetRingtone
);
1585 static GSM_Error
N6110_ReplyGetSecurityStatus(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1587 *s
->Phone
.Data
.SecurityStatus
= msg
.Buffer
[4];
1590 smprintf(s
, "Security code status\n");
1591 switch(msg
.Buffer
[4]) {
1592 case GSCT_SecurityCode
: smprintf(s
, "waiting for Security Code.\n"); break;
1593 case GSCT_Pin
: smprintf(s
, "waiting for PIN.\n"); break;
1594 case GSCT_Pin2
: smprintf(s
, "waiting for PIN2.\n"); break;
1595 case GSCT_Puk
: smprintf(s
, "waiting for PUK.\n"); break;
1596 case GSCT_Puk2
: smprintf(s
, "waiting for PUK2.\n"); break;
1597 case GSCT_None
: smprintf(s
, "nothing to enter.\n"); break;
1598 default : smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
1599 return GE_UNKNOWNRESPONSE
;
1605 static GSM_Error
N6110_GetSecurityStatus(GSM_StateMachine
*s
, GSM_SecurityCodeType
*Status
)
1607 unsigned char req
[4] = {N6110_FRAME_HEADER
, 0x07};
1609 s
->Phone
.Data
.SecurityStatus
=Status
;
1610 smprintf(s
, "Getting security code status\n");
1611 return GSM_WaitFor (s
, req
, 4, 0x08, 2, ID_GetSecurityStatus
);
1614 static GSM_Error
N6110_ReplyEnterSecurityCode(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1616 switch (msg
.Buffer
[3]) {
1618 smprintf(s
, "Security code OK\n");
1621 switch (msg
.Buffer
[4]) {
1623 smprintf(s
, "Wrong code\n");
1624 return GE_SECURITYERROR
;
1626 smprintf(s
, "Not required\n");
1629 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
1632 return GE_UNKNOWNRESPONSE
;
1635 static GSM_Error
N6110_EnterSecurityCode(GSM_StateMachine
*s
, GSM_SecurityCode Code
)
1638 unsigned char req
[15] = {
1639 N6110_FRAME_HEADER
, 0x0a,
1640 0x00}; /* Type of the entered code. */
1644 len
= strlen(Code
.Code
);
1645 memcpy(req
+5,Code
.Code
,len
);
1649 smprintf(s
, "Entering security code\n");
1650 return GSM_WaitFor (s
, req
, 7+len
, 0x08, 4, ID_EnterSecurityCode
);
1653 static GSM_Error
N6110_ReplyGetSpeedDial(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1655 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
1657 switch (msg
.Buffer
[3]) {
1659 smprintf(s
, "Speed dial received\n");
1660 switch (msg
.Buffer
[4]) {
1662 Data
->SpeedDial
->MemoryType
= GMT_ME
;
1666 Data
->SpeedDial
->MemoryType
= GMT_SM
;
1667 smprintf(s
, "SIM ");
1670 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
1671 return GE_UNKNOWNRESPONSE
;
1673 Data
->SpeedDial
->MemoryLocation
= msg
.Buffer
[5];
1674 if (msg
.Buffer
[5] == 0x00) Data
->SpeedDial
->MemoryLocation
= Data
->SpeedDial
->Location
;
1675 Data
->SpeedDial
->MemoryNumberID
= 2;
1676 smprintf(s
, "location %i\n",Data
->SpeedDial
->MemoryLocation
);
1679 smprintf(s
, "Error getting speed dial. Invalid location\n");
1680 return GE_INVALIDLOCATION
;
1682 return GE_UNKNOWNRESPONSE
;
1685 static GSM_Error
N6110_GetSpeedDial(GSM_StateMachine
*s
, GSM_SpeedDial
*SpeedDial
)
1687 unsigned char req
[] = {
1688 N6110_FRAME_HEADER
, 0x16,
1689 0x01}; /* Speed dial number */
1691 req
[4] = SpeedDial
->Location
;
1693 s
->Phone
.Data
.SpeedDial
=SpeedDial
;
1694 smprintf(s
, "Getting speed dial\n");
1695 return GSM_WaitFor (s
, req
, 5, 0x03, 4, ID_GetSpeedDial
);
1698 static GSM_Error
N6110_ReplySendDTMF(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1700 switch (msg
.Buffer
[3]) {
1702 smprintf(s
, "During sending DTMF\n");
1705 smprintf(s
, "DTMF sent OK\n");
1708 return GE_UNKNOWNRESPONSE
;
1711 static GSM_Error
N6110_ReplyGetDisplayStatus(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1714 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
1716 smprintf(s
, "Display status received\n");
1717 if (Data
->RequestID
== ID_GetDisplayStatus
) Data
->DisplayFeatures
->Number
=0;
1718 for (i
=0;i
<msg
.Buffer
[4];i
++) {
1719 if (msg
.Buffer
[2*i
+6] == 0x02) {
1721 switch (msg
.Buffer
[2*i
+5]) {
1722 case 0x01: smprintf(s
, "Call in progress\n"); break;
1723 case 0x02: smprintf(s
, "Unknown\n"); break;
1724 case 0x03: smprintf(s
, "Unread SMS\n"); break;
1725 case 0x04: smprintf(s
, "Voice call\n"); break;
1726 case 0x05: smprintf(s
, "Fax call active\n"); break;
1727 case 0x06: smprintf(s
, "Data call active\n"); break;
1728 case 0x07: smprintf(s
, "Keyboard lock\n"); break;
1729 case 0x08: smprintf(s
, "SMS storage full\n"); break;
1732 if (Data
->RequestID
== ID_GetDisplayStatus
) {
1733 switch (msg
.Buffer
[2*i
+5]) {
1734 case 0x01: Data
->DisplayFeatures
->Feature
[Data
->DisplayFeatures
->Number
] = GSM_CallActive
;
1736 case 0x03: Data
->DisplayFeatures
->Feature
[Data
->DisplayFeatures
->Number
] = GSM_UnreadSMS
;
1738 case 0x04: Data
->DisplayFeatures
->Feature
[Data
->DisplayFeatures
->Number
] = GSM_VoiceCall
;
1740 case 0x05: Data
->DisplayFeatures
->Feature
[Data
->DisplayFeatures
->Number
] = GSM_FaxCall
;
1742 case 0x06: Data
->DisplayFeatures
->Feature
[Data
->DisplayFeatures
->Number
] = GSM_DataCall
;
1744 case 0x07: Data
->DisplayFeatures
->Feature
[Data
->DisplayFeatures
->Number
] = GSM_KeypadLocked
;
1746 case 0x08: Data
->DisplayFeatures
->Feature
[Data
->DisplayFeatures
->Number
] = GSM_SMSMemoryFull
;
1749 if (msg
.Buffer
[2*i
+5]!=0x02) Data
->DisplayFeatures
->Number
++;
1756 static GSM_Error
N6110_GetDisplayStatus(GSM_StateMachine
*s
, GSM_DisplayFeatures
*features
)
1758 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x51};
1760 if (!IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_DISPSTATUS
)) return GE_NOTSUPPORTED
;
1762 s
->Phone
.Data
.DisplayFeatures
= features
;
1763 smprintf(s
, "Getting display status\n");
1764 return GSM_WaitFor (s
, req
, 4, 0x0d, 4, ID_GetDisplayStatus
);
1767 static GSM_Profile_PhoneTableValue Profile6110
[] = {
1768 {Profile_KeypadTone
, PROFILE_KEYPAD_LEVEL1
, 0x00,0x00},
1769 {Profile_KeypadTone
, PROFILE_KEYPAD_LEVEL2
, 0x00,0x01},
1770 {Profile_KeypadTone
, PROFILE_KEYPAD_LEVEL3
, 0x00,0x02},
1771 {Profile_KeypadTone
, PROFILE_KEYPAD_OFF
, 0x00,0xff},
1772 {Profile_Lights
, PROFILE_LIGHTS_OFF
, 0x01,0x00},
1773 {Profile_Lights
, PROFILE_LIGHTS_AUTO
, 0x01,0x01},
1774 {Profile_CallAlert
, PROFILE_CALLALERT_RINGING
, 0x02,0x01},
1775 {Profile_CallAlert
, PROFILE_CALLALERT_BEEPONCE
, 0x02,0x02},
1776 {Profile_CallAlert
, PROFILE_CALLALERT_OFF
, 0x02,0x04},
1777 {Profile_CallAlert
, PROFILE_CALLALERT_RINGONCE
, 0x02,0x05},
1778 {Profile_CallAlert
, PROFILE_CALLALERT_ASCENDING
, 0x02,0x06},
1779 {Profile_CallAlert
, PROFILE_CALLALERT_CALLERGROUPS
,0x02,0x07},
1781 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL1
, 0x04,0x06},
1782 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL2
, 0x04,0x07},
1783 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL3
, 0x04,0x08},
1784 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL4
, 0x04,0x09},
1785 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL5
, 0x04,0x0a},
1786 {Profile_MessageTone
, PROFILE_MESSAGE_NOTONE
, 0x05,0x00},
1787 {Profile_MessageTone
, PROFILE_MESSAGE_STANDARD
, 0x05,0x01},
1788 {Profile_MessageTone
, PROFILE_MESSAGE_SPECIAL
, 0x05,0x02},
1789 {Profile_MessageTone
, PROFILE_MESSAGE_BEEPONCE
, 0x05,0x03},
1790 {Profile_MessageTone
, PROFILE_MESSAGE_ASCENDING
, 0x05,0x04},
1791 {Profile_Vibration
, PROFILE_VIBRATION_OFF
, 0x06,0x00},
1792 {Profile_Vibration
, PROFILE_VIBRATION_ON
, 0x06,0x01},
1793 {Profile_WarningTone
, PROFILE_WARNING_OFF
, 0x07,0xff},
1794 {Profile_WarningTone
, PROFILE_WARNING_ON
, 0x07,0x04},
1796 {Profile_AutoAnswer
, PROFILE_AUTOANSWER_OFF
, 0x09,0x00},
1797 {Profile_AutoAnswer
, PROFILE_AUTOANSWER_ON
, 0x09,0x01},
1798 {0x00, 0x00, 0x00,0x00}
1801 static GSM_Profile_PhoneTableValue Profile3310
[] = {
1802 {Profile_KeypadTone
, PROFILE_KEYPAD_LEVEL1
, 0x00,0x00},
1803 {Profile_KeypadTone
, PROFILE_KEYPAD_LEVEL2
, 0x00,0x01},
1804 {Profile_KeypadTone
, PROFILE_KEYPAD_LEVEL3
, 0x00,0x02},
1805 {Profile_KeypadTone
, PROFILE_KEYPAD_OFF
, 0x00,0xff},
1806 {Profile_CallAlert
, PROFILE_CALLALERT_RINGING
, 0x01,0x01},
1807 {Profile_CallAlert
, PROFILE_CALLALERT_BEEPONCE
, 0x01,0x02},
1808 {Profile_CallAlert
, PROFILE_CALLALERT_OFF
, 0x01,0x04},
1809 {Profile_CallAlert
, PROFILE_CALLALERT_RINGONCE
, 0x01,0x05},
1810 {Profile_CallAlert
, PROFILE_CALLALERT_ASCENDING
, 0x01,0x06},
1812 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL1
, 0x03,0x06},
1813 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL2
, 0x03,0x07},
1814 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL3
, 0x03,0x08},
1815 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL4
, 0x03,0x09},
1816 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL5
, 0x03,0x0a},
1817 {Profile_MessageTone
, PROFILE_MESSAGE_NOTONE
, 0x04,0x00},
1818 {Profile_MessageTone
, PROFILE_MESSAGE_STANDARD
, 0x04,0x01},
1819 {Profile_MessageTone
, PROFILE_MESSAGE_SPECIAL
, 0x04,0x02},
1820 {Profile_MessageTone
, PROFILE_MESSAGE_BEEPONCE
, 0x04,0x03},
1821 {Profile_MessageTone
, PROFILE_MESSAGE_ASCENDING
, 0x04,0x04},
1822 {Profile_MessageTone
, PROFILE_MESSAGE_PERSONAL
, 0x04,0x05},
1823 {Profile_Vibration
, PROFILE_VIBRATION_OFF
, 0x05,0x00},
1824 {Profile_Vibration
, PROFILE_VIBRATION_ON
, 0x05,0x01},
1825 {Profile_Vibration
, PROFILE_VIBRATION_FIRST
, 0x05,0x02},
1826 {Profile_WarningTone
, PROFILE_WARNING_OFF
, 0x06,0xff},
1827 {Profile_WarningTone
, PROFILE_WARNING_ON
, 0x06,0x04},
1828 {Profile_ScreenSaver
, PROFILE_SAVER_OFF
, 0x07,0x00},
1829 {Profile_ScreenSaver
, PROFILE_SAVER_ON
, 0x07,0x01},
1830 {Profile_ScreenSaverTime
,PROFILE_SAVER_TIMEOUT_5SEC
, 0x08,0x00},
1831 {Profile_ScreenSaverTime
,PROFILE_SAVER_TIMEOUT_20SEC
, 0x08,0x01},
1832 {Profile_ScreenSaverTime
,PROFILE_SAVER_TIMEOUT_1MIN
, 0x08,0x02},
1833 {Profile_ScreenSaverTime
,PROFILE_SAVER_TIMEOUT_2MIN
, 0x08,0x03},
1834 {Profile_ScreenSaverTime
,PROFILE_SAVER_TIMEOUT_5MIN
, 0x08,0x04},
1835 {Profile_ScreenSaverTime
,PROFILE_SAVER_TIMEOUT_10MIN
, 0x08,0x05},
1836 {0x00, 0x00, 0x00,0x00}
1839 static GSM_Error
N6110_ReplyGetProfileFeature(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1841 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
1843 switch (msg
.Buffer
[3]) {
1845 smprintf(s
, "Profile feature %02x with value %02x\n",msg
.Buffer
[6],msg
.Buffer
[8]);
1846 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PROFILES33
)) {
1847 switch (msg
.Buffer
[6]) {
1849 smprintf(s
, "Ringtone ID\n");
1850 Data
->Profile
->FeatureID
[Data
->Profile
->FeaturesNumber
] = Profile_RingtoneID
;
1851 Data
->Profile
->FeatureValue
[Data
->Profile
->FeaturesNumber
] = msg
.Buffer
[8];
1852 Data
->Profile
->FeaturesNumber
++;
1855 smprintf(s
, "screen saver number\n");
1856 Data
->Profile
->FeatureID
[Data
->Profile
->FeaturesNumber
] = Profile_ScreenSaverNumber
;
1857 Data
->Profile
->FeatureValue
[Data
->Profile
->FeaturesNumber
] = msg
.Buffer
[8] + 1;
1858 Data
->Profile
->FeaturesNumber
++;
1861 smprintf(s
, "selected profile\n");
1862 if (msg
.Buffer
[8] + 1 == Data
->Profile
->Location
) Data
->Profile
->Active
= true;
1865 NOKIA_FindFeatureValue(s
, Profile3310
,msg
.Buffer
[6],msg
.Buffer
[8],Data
,false);
1869 switch (msg
.Buffer
[6]) {
1870 case 0x01: /* Lights */
1871 if (Data
->Profile
->CarKitProfile
) {
1872 NOKIA_FindFeatureValue(s
, Profile6110
,msg
.Buffer
[6],msg
.Buffer
[8],Data
,false);
1876 smprintf(s
, "Ringtone ID\n");
1877 Data
->Profile
->FeatureID
[Data
->Profile
->FeaturesNumber
] = Profile_RingtoneID
;
1878 Data
->Profile
->FeatureValue
[Data
->Profile
->FeaturesNumber
] = msg
.Buffer
[8];
1879 Data
->Profile
->FeaturesNumber
++;
1881 case 0x08: /* Caller groups */
1882 if (!IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PROFILES51
)) {
1883 NOKIA_FindFeatureValue(s
, Profile6110
,msg
.Buffer
[6],msg
.Buffer
[8],Data
,true);
1886 case 0x09: /* Autoanswer */
1887 if (Data
->Profile
->CarKitProfile
|| Data
->Profile
->HeadSetProfile
) {
1888 NOKIA_FindFeatureValue(s
, Profile6110
,msg
.Buffer
[6],msg
.Buffer
[8],Data
,false);
1892 smprintf(s
, "selected profile\n");
1893 if (msg
.Buffer
[8] + 1 == Data
->Profile
->Location
) Data
->Profile
->Active
= true;
1896 NOKIA_FindFeatureValue(s
, Profile6110
,msg
.Buffer
[6],msg
.Buffer
[8],Data
,false);
1900 smprintf(s
, "Invalid profile location\n");
1901 return GE_INVALIDLOCATION
;
1903 Data
->Profile
->Name
[0] = 0;
1904 Data
->Profile
->Name
[1] = 0;
1905 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PROFILES33
)) {
1906 EncodeUnicode(Data
->Profile
->Name
,msg
.Buffer
+10,msg
.Buffer
[9]);
1908 if (msg
.Length
> 0x0A) {
1909 CopyUnicodeString(Data
->Profile
->Name
,msg
.Buffer
+10);
1912 smprintf(s
, "Profile name: \"%s\"\n",Data
->Profile
->Name
);
1913 Data
->Profile
->DefaultName
= false;
1914 if (msg
.Buffer
[9]==0x00) Data
->Profile
->DefaultName
= true;
1917 return GE_UNKNOWNRESPONSE
;
1920 static GSM_Error
N6110_GetProfile(GSM_StateMachine
*s
, GSM_Profile
*Profile
)
1924 unsigned char name_req
[] = {N6110_FRAME_HEADER
, 0x1a, 0x00};
1925 unsigned char feat_req
[] = {
1926 N6110_FRAME_HEADER
, 0x13, 0x01,
1927 0x00, /* Profile location */
1928 0x00}; /* Feature number */
1930 s
->Phone
.Data
.Profile
=Profile
;
1932 smprintf(s
, "Getting profile name\n");
1933 error
= GSM_WaitFor (s
, name_req
, 5, 0x05, 4, ID_GetProfile
);
1934 if (error
!=GE_NONE
) return error
;
1935 if (Profile
->DefaultName
) {
1936 NOKIA_GetDefaultProfileName(s
, Profile
);
1937 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PROFILES51
)) {
1938 switch(Profile
->Location
) {
1939 case 1: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Personal"),strlen(GetMsg(s
->msg
,"Personal")));
1941 case 2: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Car"),strlen(GetMsg(s
->msg
,"Car")));
1943 case 3: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Headset"),strlen(GetMsg(s
->msg
,"Headset")));
1947 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PROFILES33
)) {
1948 switch(Profile
->Location
) {
1949 case 1: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"General"),strlen(GetMsg(s
->msg
,"General")));
1951 case 2: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Silent"),strlen(GetMsg(s
->msg
,"Silent")));
1953 case 3: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Discreet"),strlen(GetMsg(s
->msg
,"Discreet")));
1955 case 4: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Loud"),strlen(GetMsg(s
->msg
,"Loud")));
1957 case 5: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"My style"),strlen(GetMsg(s
->msg
,"My style")));
1959 case 6: Profile
->Name
[0] = 0; Profile
->Name
[1] = 0;
1965 Profile
->FeaturesNumber
= 0;
1967 Profile
->CarKitProfile
= false;
1968 Profile
->HeadSetProfile
= false;
1969 if (Profile
->Location
== 6) Profile
->CarKitProfile
= true;
1970 if (Profile
->Location
== 7) Profile
->HeadSetProfile
= true;
1971 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PROFILES51
)) {
1972 if (Profile
->Location
== 2) Profile
->CarKitProfile
= true;
1973 if (Profile
->Location
== 3) Profile
->HeadSetProfile
= true;
1975 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PROFILES33
)) {
1976 Profile
->HeadSetProfile
= false; //fixme
1977 Profile
->CarKitProfile
= false;
1980 for (i
= 0x00; i
<= 0x09; i
++) {
1981 feat_req
[5] = Profile
->Location
- 1;
1983 smprintf(s
, "Getting profile feature\n");
1984 error
= GSM_WaitFor (s
, feat_req
, 7, 0x05, 4, ID_GetProfile
);
1985 if (error
!=GE_NONE
) return error
;
1988 for (i
=0;i
<Profile
->FeaturesNumber
;i
++) {
1989 if (Profile
->FeatureID
[i
] == Profile_CallAlert
&&
1990 Profile
->FeatureValue
[i
] != PROFILE_CALLALERT_CALLERGROUPS
) {
1991 for (j
=0;j
<5;j
++) Profile
->CallerGroups
[j
] = true;
1995 Profile
->Active
= false;
1997 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PROFILES33
)) {
2002 smprintf(s
, "Getting profile feature\n");
2003 error
= GSM_WaitFor (s
, feat_req
, 7, 0x05, 4, ID_GetProfile
);
2008 static GSM_Error
N6110_SetProfile(GSM_StateMachine
*s
, GSM_Profile
*Profile
)
2012 unsigned char ID
,Value
;
2014 GSM_Profile_PhoneTableValue
*ProfilePhone
= Profile6110
;
2016 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PROFILES33
)) ProfilePhone
= Profile3310
;
2018 for (i
=0;i
<Profile
->FeaturesNumber
;i
++) {
2020 if (ProfilePhone
== Profile3310
) {
2021 switch (Profile
->FeatureID
[i
]) {
2022 case Profile_RingtoneID
:
2024 Value
= Profile
->FeatureValue
[i
];
2027 case Profile_ScreenSaverNumber
:
2029 Value
= Profile
->FeatureValue
[i
];
2033 found
=NOKIA_FindPhoneFeatureValue(
2036 Profile
->FeatureID
[i
],Profile
->FeatureValue
[i
],
2040 if (ProfilePhone
== Profile6110
) {
2041 switch (Profile
->FeatureID
[i
]) {
2042 case Profile_RingtoneID
:
2044 Value
= Profile
->FeatureValue
[i
];
2048 found
=NOKIA_FindPhoneFeatureValue(
2051 Profile
->FeatureID
[i
],Profile
->FeatureValue
[i
],
2056 error
=N6110_SetProfileFeature (s
,((unsigned char)(Profile
->Location
-1)),ID
,Value
);
2057 if (error
!=GE_NONE
) return error
;
2063 static GSM_Error
N6110_ReplyIncomingSMS(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
2065 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
2069 smprintf(s
, "SMS message received\n");
2070 sms
.State
= GSM_UnRead
;
2071 sms
.InboxFolder
= true;
2072 DCT3_DecodeSMSFrame(s
, &sms
,msg
.Buffer
+7);
2074 if (Data
->EnableIncomingSMS
&& s
->User
.IncomingSMS
!=NULL
) {
2075 sms
.State
= GSM_UnRead
;
2076 sms
.InboxFolder
= true;
2077 DCT3_DecodeSMSFrame(s
, &sms
,msg
.Buffer
+7);
2079 s
->User
.IncomingSMS(s
->CurrentConfig
->Device
,sms
);
2084 static GSM_Error
N6110_ReplyAddCalendar(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
2086 smprintf(s
, "Written Calendar Note ");
2087 switch (msg
.Buffer
[4]) {
2089 smprintf(s
, "- OK\n");
2093 smprintf(s
, "- error\n");
2096 smprintf(s
,"- during editing notes in phone menu\n");
2097 return GE_INSIDEPHONEMENU
;
2099 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
2101 return GE_UNKNOWNRESPONSE
;
2104 static GSM_Error
N6110_AddCalendarNote(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
)
2106 bool Reminder3310
= false;
2107 int Text
, Time
, Alarm
, Phone
, Recurrance
, EndTime
, Location
, i
, current
;
2108 unsigned char mychar1
,mychar2
;
2109 unsigned char req
[200] = {
2110 N6110_FRAME_HEADER
, 0x64, 0x01, 0x10,
2111 0x00, /* Length of the rest of the frame. */
2112 0x00, /* The type of calendar note */
2113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2114 0x00, 0x00, 0x00, 0x01, 0x00, 0x66, 0x01};
2116 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_NOCALENDAR
)) return GE_NOTSUPPORTED
;
2118 GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note
, &Text
, &Time
, &Alarm
, &Phone
, &Recurrance
, &EndTime
, &Location
);
2120 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_CAL52
)) {
2121 switch(Note
->Type
) {
2122 case GCN_REMINDER
: req
[7]=0x01; break;
2123 case GCN_CALL
: req
[7]=0x02; break;
2124 case GCN_MEETING
: req
[7]=0x03; break;
2125 case GCN_BIRTHDAY
: req
[7]=0x04; break;
2126 case GCN_T_ATHL
: req
[7]=0x05; break;
2127 case GCN_T_BALL
: req
[7]=0x06; break;
2128 case GCN_T_CYCL
: req
[7]=0x07; break;
2129 case GCN_T_BUDO
: req
[7]=0x08; break;
2130 case GCN_T_DANC
: req
[7]=0x09; break;
2131 case GCN_T_EXTR
: req
[7]=0x0a; break;
2132 case GCN_T_FOOT
: req
[7]=0x0b; break;
2133 case GCN_T_GOLF
: req
[7]=0x0c; break;
2134 case GCN_T_GYM
: req
[7]=0x0d; break;
2135 case GCN_T_HORS
: req
[7]=0x0e; break;
2136 case GCN_T_HOCK
: req
[7]=0x0f; break;
2137 case GCN_T_RACE
: req
[7]=0x10; break;
2138 case GCN_T_RUGB
: req
[7]=0x11; break;
2139 case GCN_T_SAIL
: req
[7]=0x12; break;
2140 case GCN_T_STRE
: req
[7]=0x13; break;
2141 case GCN_T_SWIM
: req
[7]=0x14; break;
2142 case GCN_T_TENN
: req
[7]=0x15; break;
2143 case GCN_T_TRAV
: req
[7]=0x16; break;
2144 case GCN_T_WINT
: req
[7]=0x17; break;
2145 default : req
[7]=0x01; break;
2148 switch(Note
->Type
) {
2149 case GCN_CALL
: req
[7]=0x02; break;
2150 case GCN_MEETING
: req
[7]=0x03; break;
2151 case GCN_BIRTHDAY
: req
[7]=0x04; break;
2153 default : req
[7]=0x01; break;
2157 if (Time
== -1) return GE_UNKNOWN
;
2158 NOKIA_EncodeDateTime(s
, req
+8, &Note
->Entries
[Time
].Date
);
2159 req
[14] = Note
->Entries
[Time
].Date
.Second
;
2162 NOKIA_EncodeDateTime(s
, req
+15, &Note
->Entries
[Alarm
].Date
);
2163 req
[21] = Note
->Entries
[Alarm
].Date
.Second
;
2169 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_CAL52
) ||
2170 IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_CAL82
)) {
2171 req
[22] = UnicodeLength(Note
->Entries
[Text
].Text
)*2;
2172 memcpy(req
+current
,Note
->Entries
[Text
].Text
,UnicodeLength(Note
->Entries
[Text
].Text
)*2);
2173 current
+= UnicodeLength(Note
->Entries
[Text
].Text
)*2;
2175 req
[22] = UnicodeLength(Note
->Entries
[Text
].Text
);
2176 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_CAL33
))
2178 Reminder3310
= true;
2179 if (!strcmp(s
->Phone
.Data
.ModelInfo
->model
,"3310") && s
->Phone
.Data
.VerNum
<5.11)
2181 if (Note
->Type
!=GCN_REMINDER
) Reminder3310
= false;
2183 if (!strcmp(s
->Phone
.Data
.ModelInfo
->model
,"3330") && s
->Phone
.Data
.VerNum
<=4.50)
2185 if (Note
->Type
!=GCN_REMINDER
) Reminder3310
= false;
2188 req
[22]++; /* one additional char */
2189 req
[current
++] = 0x01; /* we use now subset 1 */
2190 for (i
=0;i
<((int)UnicodeLength(Note
->Entries
[Text
].Text
));i
++)
2193 if (Note
->Entries
[Text
].Text
[i
*2]==0x20 && Note
->Entries
[Text
].Text
[i
*2+1]==0xAC) {
2194 req
[current
++] = 0xe2;
2195 req
[current
++] = 0x82;
2196 req
[current
++] = 0xac;
2197 req
[23] = 0x03; /* use subset 3 */
2198 req
[22]+=2; /* two additional chars */
2199 } else if (EncodeWithUTF8Alphabet(Note
->Entries
[Text
].Text
[i
*2],Note
->Entries
[Text
].Text
[i
*2+1],&mychar1
,&mychar2
))
2201 req
[current
++] = mychar1
;
2202 req
[current
++] = mychar2
;
2203 req
[23] = 0x03; /* use subset 3 */
2204 req
[22]++; /* one additional char */
2206 current
+=DecodeWithUnicodeAlphabet(((wchar_t)(Note
->Entries
[Text
].Text
[i
*2]*256+Note
->Entries
[Text
].Text
[i
*2+1])),req
+current
);
2211 if (!Reminder3310
) {
2212 memcpy(req
+current
,DecodeUnicodeString(Note
->Entries
[Text
].Text
),UnicodeLength(Note
->Entries
[Text
].Text
));
2213 current
+= UnicodeLength(Note
->Entries
[Text
].Text
);
2216 } else req
[22] = 0x00;
2218 if (Note
->Type
== GCN_CALL
) {
2220 req
[current
++] = UnicodeLength(Note
->Entries
[Phone
].Text
);
2221 memcpy(req
+current
,DecodeUnicodeString(Note
->Entries
[Phone
].Text
),UnicodeLength(Note
->Entries
[Phone
].Text
));
2222 current
+= UnicodeLength(Note
->Entries
[Phone
].Text
);
2223 } else req
[current
++] = 0x00;
2226 req
[6] = current
- 8;
2228 smprintf(s
, "Writing calendar note\n");
2229 return GSM_WaitFor (s
, req
, current
, 0x13, 4, ID_SetCalendarNote
);
2232 static GSM_Error
N6110_ReplyDeleteCalendar(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
2234 smprintf(s
, "Calendar note deleted\n");
2235 switch (msg
.Buffer
[4]) {
2237 smprintf(s
, "Done OK\n");
2240 smprintf(s
,"- during editing notes in phone menu\n");
2241 return GE_INSIDEPHONEMENU
;
2243 smprintf(s
, "Can't be done - too high location ?\n");
2244 return GE_INVALIDLOCATION
;
2246 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
2247 return GE_UNKNOWNRESPONSE
;
2251 static GSM_Error
N6110_DeleteCalendarNote(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
)
2253 unsigned char req
[] = {
2254 N6110_FRAME_HEADER
, 0x68,
2255 0x00}; /* Location */
2257 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_NOCALENDAR
)) return GE_NOTSUPPORTED
;
2259 req
[4] = Note
->Location
;
2261 smprintf(s
, "Deleting calendar note\n");
2262 return GSM_WaitFor (s
, req
, 5, 0x13, 5, ID_DeleteCalendarNote
);
2265 /* for example: "Euro_char" text */
2266 static void Decode3310Subset3(int j
, GSM_Protocol_Message msg
, GSM_Phone_Data
*Data
)
2272 GSM_CalendarEntry
*Entry
= Data
->Cal
;
2275 while (i
!=msg
.Buffer
[23]) {
2276 EncodeWithUnicodeAlphabet(msg
.Buffer
+24+i
,&wc
);
2278 if (i
!=msg
.Buffer
[23]-2) {
2279 if (msg
.Buffer
[24+i
] ==0xe2 && msg
.Buffer
[24+i
+1]==0x82 &&
2280 msg
.Buffer
[24+i
+2]==0xac) {
2281 wc
= 0x20 * 256 + 0xac;
2286 if (i
!=msg
.Buffer
[23]-1 && !charfound
) {
2287 if (msg
.Buffer
[24+i
]>=0xc2) {
2288 wc
= DecodeWithUTF8Alphabet(msg
.Buffer
[24+i
],msg
.Buffer
[24+i
+1]);
2292 Entry
->Entries
[Entry
->EntriesNum
].Text
[len
++] = (wc
>> 8) & 0xff;
2293 Entry
->Entries
[Entry
->EntriesNum
].Text
[len
++] = wc
& 0xff;
2296 Entry
->Entries
[Entry
->EntriesNum
].Text
[len
++] = 0;
2297 Entry
->Entries
[Entry
->EntriesNum
].Text
[len
++] = 0;
2300 /* For example: "a with : above" char */
2301 static void Decode3310Subset2(int j
, GSM_Protocol_Message msg
, GSM_Phone_Data
*Data
)
2305 GSM_CalendarEntry
*Entry
= Data
->Cal
;
2308 while (i
!=msg
.Buffer
[23]) {
2309 Entry
->Entries
[Entry
->EntriesNum
].Text
[len
++] = 0x00;
2310 Entry
->Entries
[Entry
->EntriesNum
].Text
[len
++] = msg
.Buffer
[24+i
];
2313 Entry
->Entries
[Entry
->EntriesNum
].Text
[len
++] = 0;
2314 Entry
->Entries
[Entry
->EntriesNum
].Text
[len
++] = 0;
2317 static GSM_Error
N6110_ReplyGetNextCalendar(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
2320 bool SpecialSubSet
= false;
2321 GSM_CalendarEntry
*Entry
= s
->Phone
.Data
.Cal
;
2323 switch (msg
.Buffer
[4]) {
2325 smprintf(s
, "Calendar note received\n");
2326 switch (msg
.Buffer
[8]) {
2327 case 0x01: Entry
->Type
= GCN_REMINDER
; break;
2328 case 0x02: Entry
->Type
= GCN_CALL
; break;
2329 case 0x03: Entry
->Type
= GCN_MEETING
; break;
2330 case 0x04: Entry
->Type
= GCN_BIRTHDAY
; break;
2331 case 0x05: Entry
->Type
= GCN_T_ATHL
; break;
2332 case 0x06: Entry
->Type
= GCN_T_BALL
; break;
2333 case 0x07: Entry
->Type
= GCN_T_CYCL
; break;
2334 case 0x08: Entry
->Type
= GCN_T_BUDO
; break;
2335 case 0x09: Entry
->Type
= GCN_T_DANC
; break;
2336 case 0x0a: Entry
->Type
= GCN_T_EXTR
; break;
2337 case 0x0b: Entry
->Type
= GCN_T_FOOT
; break;
2338 case 0x0c: Entry
->Type
= GCN_T_GOLF
; break;
2339 case 0x0d: Entry
->Type
= GCN_T_GYM
; break;
2340 case 0x0e: Entry
->Type
= GCN_T_HORS
; break;
2341 case 0x0f: Entry
->Type
= GCN_T_HOCK
; break;
2342 case 0x10: Entry
->Type
= GCN_T_RACE
; break;
2343 case 0x11: Entry
->Type
= GCN_T_RUGB
; break;
2344 case 0x12: Entry
->Type
= GCN_T_SAIL
; break;
2345 case 0x13: Entry
->Type
= GCN_T_STRE
; break;
2346 case 0x14: Entry
->Type
= GCN_T_SWIM
; break;
2347 case 0x15: Entry
->Type
= GCN_T_TENN
; break;
2348 case 0x16: Entry
->Type
= GCN_T_TRAV
; break;
2349 case 0x17: Entry
->Type
= GCN_T_WINT
; break;
2351 smprintf(s
, "Unknown note type %i\n",msg
.Buffer
[8]);
2352 return GE_UNKNOWNRESPONSE
;
2355 switch (msg
.Buffer
[8]) {
2356 case 0x01: smprintf(s
, "Reminder\n"); break;
2357 case 0x02: smprintf(s
, "Call\n"); break;
2358 case 0x03: smprintf(s
, "Meeting\n"); break;
2359 case 0x04: smprintf(s
, "Birthday\n"); break;
2362 Entry
->EntriesNum
= 0;
2364 NOKIA_DecodeDateTime(s
, msg
.Buffer
+9, &Entry
->Entries
[0].Date
);
2365 smprintf(s
, "Time : %02i-%02i-%04i %02i:%02i:%02i\n",
2366 Entry
->Entries
[0].Date
.Day
,Entry
->Entries
[0].Date
.Month
,Entry
->Entries
[0].Date
.Year
,
2367 Entry
->Entries
[0].Date
.Hour
,Entry
->Entries
[0].Date
.Minute
,Entry
->Entries
[0].Date
.Second
);
2368 Entry
->Entries
[0].EntryType
= CAL_START_DATETIME
;
2369 Entry
->EntriesNum
++;
2371 NOKIA_DecodeDateTime(s
, msg
.Buffer
+16, &Entry
->Entries
[1].Date
);
2372 if (Entry
->Entries
[1].Date
.Year
!=0) {
2373 smprintf(s
, "Alarm : %02i-%02i-%04i %02i:%02i:%02i\n",
2374 Entry
->Entries
[1].Date
.Day
,Entry
->Entries
[1].Date
.Month
,Entry
->Entries
[1].Date
.Year
,
2375 Entry
->Entries
[1].Date
.Hour
,Entry
->Entries
[1].Date
.Minute
,Entry
->Entries
[1].Date
.Second
);
2376 Entry
->Entries
[1].EntryType
= CAL_ALARM_DATETIME
;
2377 Entry
->EntriesNum
++;
2379 smprintf(s
, "No alarm\n");
2382 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_CAL52
) ||
2383 IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_CAL82
)) {
2384 memcpy(Entry
->Entries
[Entry
->EntriesNum
].Text
,msg
.Buffer
+24,msg
.Buffer
[23]);
2385 Entry
->Entries
[Entry
->EntriesNum
].Text
[msg
.Buffer
[23] ]=0;
2386 Entry
->Entries
[Entry
->EntriesNum
].Text
[msg
.Buffer
[23]+1]=0;
2388 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_CAL33
))
2390 /* first char is subset for 33xx and reminders */
2391 if (Entry
->Type
== GCN_REMINDER
) {
2393 smprintf(s
, "Subset %i in reminder note !\n",msg
.Buffer
[24]);
2395 SpecialSubSet
= true;
2396 switch (msg
.Buffer
[24]) {
2397 case 2 : Decode3310Subset2(i
,msg
,&s
->Phone
.Data
); break;
2398 case 3 : Decode3310Subset3(i
,msg
,&s
->Phone
.Data
); break;
2399 default : SpecialSubSet
= false; break;
2402 if (!SpecialSubSet
) {
2403 N6110_EncodeUnicode(s
,Entry
->Entries
[Entry
->EntriesNum
].Text
,msg
.Buffer
+24+i
,msg
.Buffer
[23]-i
);
2406 smprintf(s
, "Text \"%s\"\n",DecodeUnicodeString(Entry
->Entries
[Entry
->EntriesNum
].Text
));
2407 if (msg
.Buffer
[23] != 0x00) {
2408 Entry
->Entries
[Entry
->EntriesNum
].EntryType
= CAL_TEXT
;
2409 Entry
->EntriesNum
++;
2412 if (Entry
->Type
== GCN_CALL
)
2414 EncodeUnicode(Entry
->Entries
[Entry
->EntriesNum
].Text
,msg
.Buffer
+24+msg
.Buffer
[23]+1,msg
.Buffer
[24+msg
.Buffer
[23]]);
2415 smprintf(s
, "Phone : \"%s\"\n",DecodeUnicodeString(Entry
->Entries
[Entry
->EntriesNum
].Text
));
2416 if (msg
.Buffer
[24+msg
.Buffer
[23]] != 0x00) {
2417 Entry
->Entries
[Entry
->EntriesNum
].EntryType
= CAL_PHONE
;
2418 Entry
->EntriesNum
++;
2423 smprintf(s
, "Can't get calendar note - too high location?\n");
2424 return GE_INVALIDLOCATION
;
2426 return GE_UNKNOWNRESPONSE
;
2429 static GSM_Error
N6110_GetNextCalendarNote(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
, bool start
)
2431 int Text
, Time
, Alarm
, Phone
, Recurrance
, EndTime
, Location
;
2433 GSM_DateTime date_time
;
2434 GSM_Phone_N6110Data
*Priv
= &s
->Phone
.Data
.Priv
.N6110
;
2435 unsigned char req
[] = {
2436 N6110_FRAME_HEADER
, 0x66,
2437 0x00}; /* Location */
2439 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_NOCALENDAR
)) return GE_NOTSUPPORTED
;
2442 Priv
->LastCalendarPos
= 1;
2444 Priv
->LastCalendarPos
++;
2447 Note
->Location
= Priv
->LastCalendarPos
;
2448 req
[4] = Priv
->LastCalendarPos
;
2450 s
->Phone
.Data
.Cal
=Note
;
2451 smprintf(s
, "Getting calendar note\n");
2452 error
=GSM_WaitFor (s
, req
, 5, 0x13, 4, ID_GetCalendarNote
);
2454 GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note
, &Text
, &Time
, &Alarm
, &Phone
, &Recurrance
, &EndTime
, &Location
);
2455 /* 2090 year is set for example in 3310 */
2456 if (error
== GE_NONE
&& Note
->Entries
[Time
].Date
.Year
== 2090) {
2457 error
=N6110_GetDateTime(s
, &date_time
);
2458 if (error
== GE_NONE
) Note
->Entries
[Time
].Date
.Year
= date_time
.Year
;
2463 GSM_Error
N6110_ReplyUSSDInfo(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
2465 unsigned char buffer
[2000],buffer2
[4000];
2468 tmp
=GSM_UnpackEightBitsToSeven(0, 82, 82, msg
.Buffer
+8, buffer
);
2469 msg
.Buffer
[tmp
] = 0;
2471 smprintf(s
, "USSD reply: \"%s\"\n",buffer
);
2473 if (s
->Phone
.Data
.EnableIncomingUSSD
&& s
->User
.IncomingUSSD
!=NULL
) {
2474 EncodeUnicode(buffer2
,buffer
,strlen(buffer
));
2475 s
->User
.IncomingUSSD(s
->CurrentConfig
->Device
, buffer2
);
2481 GSM_Error
N6110_AnswerCall(GSM_StateMachine
*s
, int ID
, bool all
)
2484 unsigned char req1
[] = {N6110_FRAME_HEADER
, 0x42, 0x05, 0x01,
2485 0x07, 0xa2, 0x88, 0x81, 0x21, 0x15, 0x63, 0xa8,
2487 0x07, 0xa3, 0xb8, 0x81, 0x20, 0x15, 0x63, 0x80};
2490 smprintf(s
, "Answering call part 1\n");
2491 error
= GSM_WaitFor (s
, req1
, 24, 0x01, 5, ID_AnswerCall
);
2492 if (error
!= GE_NONE
) return error
;
2493 return DCT3DCT4_AnswerCall(s
,ID
);
2496 return DCT3_AnswerAllCalls(s
);
2499 static GSM_Error
N6110_DialVoice(GSM_StateMachine
*s
, char *number
, GSM_CallShowNumber ShowNumber
)
2501 unsigned int pos
= 4;
2502 unsigned char req
[100] = {N6110_FRAME_HEADER
,0x01,
2503 0x0c}; /* Number length in chars */
2505 if (ShowNumber
== GN_CALL_Default
) return DCT3_DialVoice(s
,number
,ShowNumber
);
2507 req
[pos
++] = strlen(number
);
2508 memcpy(req
+pos
,number
,strlen(number
));
2509 pos
+= strlen(number
);
2510 req
[pos
++] = 0x05; /* call type: voice - 0x05, data - 0x01 */
2515 switch (ShowNumber
) {
2516 case GN_CALL_HideNumber
:
2519 case GN_CALL_ShowNumber
:
2522 case GN_CALL_Default
:
2529 smprintf(s
, "Making voice call\n");
2530 return GSM_WaitFor (s
, req
, pos
, 0x01, 4, ID_DialVoice
);
2533 GSM_Error
N6110_UnholdCall(GSM_StateMachine
*s
, int ID
)
2535 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x24, 0x00, 0x02};
2537 req
[4] = (unsigned char)ID
;
2538 s
->Phone
.Data
.CallID
= ID
;
2540 smprintf(s
, "Unholding call\n");
2541 return GSM_WaitFor (s
, req
, 6, 0x01, 4, ID_UnholdCall
);
2544 GSM_Error
N6110_HoldCall(GSM_StateMachine
*s
, int ID
)
2546 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x22, 0x00, 0x00};
2548 req
[4] = (unsigned char)ID
;
2549 s
->Phone
.Data
.CallID
= ID
;
2551 smprintf(s
, "Unholding call\n");
2552 return GSM_WaitFor (s
, req
, 6, 0x01, 4, ID_HoldCall
);
2555 /* Joining selected call to current (and making conference) */
2556 GSM_Error
N6110_ConferenceCall(GSM_StateMachine
*s
, int ID
)
2558 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x28, 0x00, 0x01};
2560 req
[4] = (unsigned char)ID
;
2561 s
->Phone
.Data
.CallID
= ID
;
2563 smprintf(s
, "Conference call\n");
2564 return GSM_WaitFor (s
, req
, 6, 0x01, 4, ID_ConferenceCall
);
2567 /* Removing selected call from conference and making private call with it
2568 * (conference call is on hold) */
2569 GSM_Error
N6110_SplitCall(GSM_StateMachine
*s
, int ID
)
2571 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x2A, 0x00, 0x01};
2573 req
[4] = (unsigned char)ID
;
2574 s
->Phone
.Data
.CallID
= ID
;
2576 smprintf(s
, "Split call\n");
2577 return GSM_WaitFor (s
, req
, 6, 0x01, 4, ID_SplitCall
);
2580 /* This probably need more investigation */
2581 GSM_Error
N6110_SwitchCall(GSM_StateMachine
*s
, int ID
, bool next
)
2583 // unsigned char req[] = {N6110_FRAME_HEADER, 0x20}; calls info
2584 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x26, 0x00};
2586 s
->Phone
.Data
.CallID
= ID
;
2589 smprintf(s
, "Switch call\n");
2590 return GSM_WaitFor (s
, req
, 4, 0x01, 4, ID_SwitchCall
);
2592 req
[4] = (unsigned char)ID
;
2594 smprintf(s
, "Switch call\n");
2595 return GSM_WaitFor (s
, req
, 5, 0x01, 4, ID_SwitchCall
);
2599 /* This probably need more investigation */
2600 GSM_Error
N6110_TransferCall(GSM_StateMachine
*s
, int ID
, bool next
)
2602 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x2C, 0x00};
2604 s
->Phone
.Data
.CallID
= ID
;
2607 smprintf(s
, "Transfer call\n");
2608 return GSM_WaitFor (s
, req
, 4, 0x01, 4, ID_TransferCall
);
2610 req
[4] = (unsigned char)ID
;
2612 smprintf(s
, "Transfer call\n");
2613 return GSM_WaitFor (s
, req
, 5, 0x01, 4, ID_TransferCall
);
2617 static GSM_Reply_Function N6110ReplyFunctions
[] = {
2618 {N6110_ReplyCallInfo
, "\x01",0x03,0x02,ID_IncomingFrame
},
2619 {N6110_ReplyCallInfo
, "\x01",0x03,0x03,ID_IncomingFrame
},
2620 {N6110_ReplyCallInfo
, "\x01",0x03,0x04,ID_IncomingFrame
},
2621 {N6110_ReplyCallInfo
, "\x01",0x03,0x05,ID_IncomingFrame
},
2622 {N6110_ReplyCallInfo
, "\x01",0x03,0x07,ID_AnswerCall
},
2623 {N6110_ReplyCallInfo
, "\x01",0x03,0x07,ID_IncomingFrame
},
2624 {N6110_ReplyCallInfo
, "\x01",0x03,0x09,ID_CancelCall
},
2625 {N6110_ReplyCallInfo
, "\x01",0x03,0x09,ID_IncomingFrame
},
2626 {N6110_ReplyCallInfo
, "\x01",0x03,0x0A,ID_IncomingFrame
},
2627 {N6110_ReplyCallInfo
, "\x01",0x03,0x23,ID_HoldCall
},
2628 {N6110_ReplyCallInfo
, "\x01",0x03,0x23,ID_IncomingFrame
},
2629 {N6110_ReplyCallInfo
, "\x01",0x03,0x25,ID_UnholdCall
},
2630 {N6110_ReplyCallInfo
, "\x01",0x03,0x25,ID_IncomingFrame
},
2631 {N6110_ReplyCallInfo
, "\x01",0x03,0x27,ID_IncomingFrame
},
2632 {N6110_ReplyCallInfo
, "\x01",0x03,0x29,ID_ConferenceCall
},
2633 {N6110_ReplyCallInfo
, "\x01",0x03,0x29,ID_IncomingFrame
},
2634 {N6110_ReplyCallInfo
, "\x01",0x03,0x2B,ID_SplitCall
},
2635 {N6110_ReplyCallInfo
, "\x01",0x03,0x2B,ID_IncomingFrame
},
2636 {N6110_ReplySendDTMF
, "\x01",0x03,0x40,ID_SendDTMF
},
2637 {NoneReply
, "\x01",0x03,0x40,ID_DialVoice
},
2638 {NoneReply
, "\x01",0x03,0x40,ID_IncomingFrame
},
2639 {NoneReply
, "\x01",0x03,0x43,ID_AnswerCall
},
2640 {N6110_ReplySendDTMF
, "\x01",0x03,0x51,ID_SendDTMF
},
2642 {DCT3_ReplySendSMSMessage
, "\x02",0x03,0x02,ID_IncomingFrame
},
2643 {DCT3_ReplySendSMSMessage
, "\x02",0x03,0x03,ID_IncomingFrame
},
2644 {N6110_ReplyIncomingSMS
, "\x02",0x03,0x10,ID_IncomingFrame
},
2645 #ifdef GSM_ENABLE_CELLBROADCAST
2646 {DCT3_ReplySetIncomingCB
, "\x02",0x03,0x21,ID_SetIncomingCB
},
2647 {DCT3_ReplySetIncomingCB
, "\x02",0x03,0x22,ID_SetIncomingCB
},
2648 {DCT3_ReplyIncomingCB
, "\x02",0x03,0x23,ID_IncomingFrame
},
2650 {DCT3_ReplySetSMSC
, "\x02",0x03,0x31,ID_SetSMSC
},
2651 {DCT3_ReplyGetSMSC
, "\x02",0x03,0x34,ID_GetSMSC
},
2652 {DCT3_ReplyGetSMSC
, "\x02",0x03,0x35,ID_GetSMSC
},
2654 {N6110_ReplyGetMemory
, "\x03",0x03,0x02,ID_GetMemory
},
2655 {N6110_ReplyGetMemory
, "\x03",0x03,0x03,ID_GetMemory
},
2656 {N6110_ReplySetMemory
, "\x03",0x03,0x05,ID_SetMemory
},
2657 {N6110_ReplySetMemory
, "\x03",0x03,0x06,ID_SetMemory
},
2658 {N6110_ReplyGetMemoryStatus
, "\x03",0x03,0x08,ID_GetMemoryStatus
},
2659 {N6110_ReplyGetMemoryStatus
, "\x03",0x03,0x09,ID_GetMemoryStatus
},
2660 {N6110_ReplyGetCallerLogo
, "\x03",0x03,0x11,ID_GetBitmap
},
2661 {N6110_ReplyGetCallerLogo
, "\x03",0x03,0x12,ID_GetBitmap
},
2662 {N6110_ReplySetCallerLogo
, "\x03",0x03,0x14,ID_SetBitmap
},
2663 {N6110_ReplySetCallerLogo
, "\x03",0x03,0x15,ID_SetBitmap
},
2664 {N6110_ReplyGetSpeedDial
, "\x03",0x03,0x17,ID_GetSpeedDial
},
2665 {N6110_ReplyGetSpeedDial
, "\x03",0x03,0x18,ID_GetSpeedDial
},
2666 /* 0x1A, 0x1B - reply set speed dial */
2668 {N6110_ReplyGetStatus
, "\x04",0x03,0x02,ID_GetSignalQuality
},
2669 {N6110_ReplyGetStatus
, "\x04",0x03,0x02,ID_GetBatteryCharge
},
2671 {N6110_ReplySetProfileFeature
, "\x05",0x03,0x11,ID_SetProfile
},
2672 {N6110_ReplySetProfileFeature
, "\x05",0x03,0x12,ID_SetProfile
},
2673 {N6110_ReplyGetProfileFeature
, "\x05",0x03,0x14,ID_GetProfile
},
2674 {N6110_ReplyGetPhoneLanguage
, "\x05",0x03,0x14,ID_GetLanguage
},
2675 {N6110_ReplyGetProfileFeature
, "\x05",0x03,0x15,ID_GetProfile
},
2676 {N6110_ReplyGetPhoneLanguage
, "\x05",0x03,0x15,ID_GetLanguage
},
2677 {N6110_ReplyGetStartup
, "\x05",0x03,0x17,ID_GetBitmap
},
2678 {N6110_ReplySetStartup
, "\x05",0x03,0x19,ID_SetBitmap
},
2679 {N6110_ReplyGetProfileFeature
, "\x05",0x03,0x1b,ID_GetProfile
},
2680 {N61_91_ReplySetOpLogo
, "\x05",0x03,0x31,ID_SetBitmap
},
2681 {N61_91_ReplySetOpLogo
, "\x05",0x03,0x32,ID_SetBitmap
},
2682 {N6110_ReplyGetOpLogo
, "\x05",0x03,0x34,ID_GetBitmap
},
2683 {N6110_ReplySetRingtone
, "\x05",0x03,0x37,ID_SetRingtone
},
2684 {N6110_ReplySetRingtone
, "\x05",0x03,0x38,ID_SetRingtone
},
2686 {DCT3DCT4_ReplyCallDivert
, "\x06",0x03,0x02,ID_Divert
},
2687 {DCT3DCT4_ReplyCallDivert
, "\x06",0x03,0x03,ID_Divert
},
2688 {N6110_ReplyUSSDInfo
, "\x06",0x03,0x05,ID_IncomingFrame
},
2690 {N6110_ReplyGetSecurityStatus
, "\x08",0x03,0x08,ID_GetSecurityStatus
},
2691 {N6110_ReplyEnterSecurityCode
, "\x08",0x03,0x0b,ID_EnterSecurityCode
},
2692 {N6110_ReplyEnterSecurityCode
, "\x08",0x03,0x0c,ID_EnterSecurityCode
},
2694 {DCT3_ReplySIMLogin
, "\x09",0x03,0x80,ID_IncomingFrame
},
2695 {DCT3_ReplySIMLogout
, "\x09",0x03,0x81,ID_IncomingFrame
},
2697 {DCT3_ReplyGetNetworkInfo
, "\x0A",0x03,0x71,ID_GetNetworkInfo
},
2698 {DCT3_ReplyGetNetworkInfo
, "\x0A",0x03,0x71,ID_IncomingFrame
},
2700 {N6110_ReplyGetDisplayStatus
, "\x0D",0x03,0x52,ID_GetDisplayStatus
},
2701 {N6110_ReplyGetDisplayStatus
, "\x0D",0x03,0x52,ID_IncomingFrame
},
2703 {DCT3_ReplySetDateTime
, "\x11",0x03,0x61,ID_SetDateTime
},
2704 {DCT3_ReplyGetDateTime
, "\x11",0x03,0x63,ID_GetDateTime
},
2705 {DCT3_ReplySetAlarm
, "\x11",0x03,0x6C,ID_SetAlarm
},
2706 {DCT3_ReplyGetAlarm
, "\x11",0x03,0x6E,ID_GetAlarm
},
2708 {N6110_ReplyAddCalendar
, "\x13",0x03,0x65,ID_SetCalendarNote
},
2709 {N6110_ReplyAddCalendar
, "\x13",0x03,0x65,ID_IncomingFrame
},
2710 {N6110_ReplyGetNextCalendar
, "\x13",0x03,0x67,ID_GetCalendarNote
},
2711 {N6110_ReplyDeleteCalendar
, "\x13",0x03,0x69,ID_DeleteCalendarNote
},
2712 {N6110_ReplyDeleteCalendar
, "\x13",0x03,0x69,ID_IncomingFrame
},
2714 {N6110_ReplySaveSMSMessage
, "\x14",0x03,0x05,ID_SaveSMSMessage
},
2715 {N6110_ReplySaveSMSMessage
, "\x14",0x03,0x06,ID_SaveSMSMessage
},
2716 {N6110_ReplyGetSMSMessage
, "\x14",0x03,0x08,ID_GetSMSMessage
},
2717 {N6110_ReplyGetSMSMessage
, "\x14",0x03,0x09,ID_GetSMSMessage
},
2718 {DCT3_ReplyDeleteSMSMessage
, "\x14",0x03,0x0B,ID_DeleteSMSMessage
},
2719 {DCT3_ReplyDeleteSMSMessage
, "\x14",0x03,0x0C,ID_DeleteSMSMessage
},
2720 {N6110_ReplyGetSMSStatus
, "\x14",0x03,0x37,ID_GetSMSStatus
},
2721 {N6110_ReplyGetSMSStatus
, "\x14",0x03,0x38,ID_GetSMSStatus
},
2723 {DCT3DCT4_ReplyEnableWAP
, "\x3f",0x03,0x01,ID_EnableWAP
},
2724 {DCT3DCT4_ReplyEnableWAP
, "\x3f",0x03,0x02,ID_EnableWAP
},
2725 {DCT3_ReplyGetWAPBookmark
, "\x3f",0x03,0x07,ID_GetWAPBookmark
},
2726 {DCT3_ReplyGetWAPBookmark
, "\x3f",0x03,0x08,ID_GetWAPBookmark
},
2727 {DCT3DCT4_ReplySetWAPBookmark
, "\x3f",0x03,0x0A,ID_SetWAPBookmark
},
2728 {DCT3DCT4_ReplySetWAPBookmark
, "\x3f",0x03,0x0B,ID_SetWAPBookmark
},
2729 {DCT3DCT4_ReplyDelWAPBookmark
, "\x3f",0x03,0x0D,ID_DeleteWAPBookmark
},
2730 {DCT3DCT4_ReplyDelWAPBookmark
, "\x3f",0x03,0x0E,ID_DeleteWAPBookmark
},
2731 {DCT3DCT4_ReplyGetActiveWAPMMSSet
,"\x3f",0x03,0x10,ID_GetWAPSettings
},
2732 {DCT3DCT4_ReplySetActiveWAPMMSSet
,"\x3f",0x03,0x13,ID_SetWAPSettings
},
2733 {DCT3_ReplyGetWAPSettings
, "\x3f",0x03,0x16,ID_GetWAPSettings
},
2734 {DCT3_ReplyGetWAPSettings
, "\x3f",0x03,0x17,ID_GetWAPSettings
},
2735 {DCT3_ReplySetWAPSettings
, "\x3f",0x03,0x19,ID_SetWAPSettings
},
2736 {DCT3_ReplySetWAPSettings
, "\x3f",0x03,0x1A,ID_SetWAPSettings
},
2737 {DCT3_ReplyGetWAPSettings
, "\x3f",0x03,0x1C,ID_GetWAPSettings
},
2738 {DCT3_ReplyGetWAPSettings
, "\x3f",0x03,0x1D,ID_GetWAPSettings
},
2739 {DCT3_ReplySetWAPSettings
, "\x3f",0x03,0x1F,ID_SetWAPSettings
},
2741 {DCT3_ReplyEnableSecurity
, "\x40",0x02,0x64,ID_EnableSecurity
},
2742 {N61_71_ReplyResetPhoneSettings
, "\x40",0x02,0x65,ID_ResetPhoneSettings
},
2743 {DCT3_ReplyGetIMEI
, "\x40",0x02,0x66,ID_GetIMEI
},
2744 {DCT3_ReplyDialCommand
, "\x40",0x02,0x7C,ID_DialVoice
},
2745 {DCT3_ReplyDialCommand
, "\x40",0x02,0x7C,ID_CancelCall
},
2746 {DCT3_ReplyDialCommand
, "\x40",0x02,0x7C,ID_AnswerCall
},
2747 {DCT3_ReplyNetmonitor
, "\x40",0x02,0x7E,ID_Netmonitor
},
2748 {DCT3_ReplyPlayTone
, "\x40",0x02,0x8F,ID_PlayTone
},
2749 {N6110_ReplyGetRingtone
, "\x40",0x02,0x9E,ID_GetRingtone
},
2750 {N6110_ReplySetBinRingtone
, "\x40",0x02,0xA0,ID_SetRingtone
},
2751 {NOKIA_ReplyGetPhoneString
, "\x40",0x02,0xC8,ID_GetHardware
},
2752 {NOKIA_ReplyGetPhoneString
, "\x40",0x02,0xC8,ID_GetPPM
},
2753 {NOKIA_ReplyGetPhoneString
, "\x40",0x02,0xCA,ID_GetProductCode
},
2754 {NOKIA_ReplyGetPhoneString
, "\x40",0x02,0xCC,ID_GetManufactureMonth
},
2755 {NOKIA_ReplyGetPhoneString
, "\x40",0x02,0xCC,ID_GetOriginalIMEI
},
2757 {N6110_ReplyGetSetPicture
, "\x47",0x03,0x02,ID_GetBitmap
},
2758 {N6110_ReplyGetSetPicture
, "\x47",0x03,0x04,ID_SetBitmap
},
2759 {N6110_ReplyGetSetPicture
, "\x47",0x03,0x05,ID_SetBitmap
},
2760 {N6110_ReplyGetSetPicture
, "\x47",0x03,0x06,ID_GetBitmap
},
2763 {N6110_ReplyGetMagicBytes
, "\x64",0x00,0x00,ID_MakeAuthentication
},
2766 {DCT3DCT4_ReplyGetModelFirmware
, "\xD2",0x02,0x00,ID_GetModel
},
2767 {DCT3DCT4_ReplyGetModelFirmware
, "\xD2",0x02,0x00,ID_GetFirmware
},
2768 {DCT3_ReplyPressKey
, "\xD2",0x02,0x46,ID_PressKey
},
2769 {DCT3_ReplyPressKey
, "\xD2",0x02,0x47,ID_PressKey
},
2771 {NULL
, "\x00",0x00,0x00,ID_None
}
2774 GSM_Phone_Functions N6110Phone
= {
2775 "2100|3210|3310|3330|3390|3410|3610|5110|5110i|5130|5190|5210|5510|6110|6130|6150|6190|8210|8250|8290|8850|8855|8890",
2776 N6110ReplyFunctions
,
2779 GSM_DispatchMessage
,
2780 N6110_ShowStartInfo
,
2781 NOKIA_GetManufacturer
,
2783 DCT3DCT4_GetFirmware
,
2785 DCT3_GetOriginalIMEI
,
2786 DCT3_GetManufactureMonth
,
2787 DCT3_GetProductCode
,
2790 NOTSUPPORTED
, /* GetSIMIMSI */
2795 NOTSUPPORTED
, /* GetLocale */
2796 NOTSUPPORTED
, /* SetLocale */
2799 N61_71_ResetPhoneSettings
,
2800 N6110_EnterSecurityCode
,
2801 N6110_GetSecurityStatus
,
2802 N6110_GetDisplayStatus
,
2803 NOTIMPLEMENTED
, /* SetAutoNetworkLogin */
2804 N6110_GetBatteryCharge
,
2805 N6110_GetSignalQuality
,
2806 DCT3_GetNetworkInfo
,
2807 NOTSUPPORTED
, /* GetCategory */
2808 NOTSUPPORTED
, /* GetCategoryStatus */
2809 N6110_GetMemoryStatus
,
2811 NOTIMPLEMENTED
, /* GetNextMemory */
2813 NOTIMPLEMENTED
, /* AddMemory */
2815 NOTIMPLEMENTED
, /* DeleteAllMemory */
2817 NOTIMPLEMENTED
, /* SetSpeedDial */
2821 N6110_GetSMSMessage
,
2822 N6110_GetNextSMSMessage
,
2825 N6110_DeleteSMSMessage
,
2826 DCT3_SendSMSMessage
,
2827 NOKIA_SetIncomingSMS
,
2829 PHONE_GetSMSFolders
,
2830 NOTSUPPORTED
, /* AddSMSFolder */
2831 NOTSUPPORTED
, /* DeleteSMSFolder */
2837 N6110_ConferenceCall
,
2841 DCT3DCT4_GetCallDivert
,
2842 DCT3DCT4_SetCallDivert
,
2843 DCT3DCT4_CancelAllDiverts
,
2844 NOKIA_SetIncomingCall
,
2845 NOKIA_SetIncomingUSSD
,
2849 NOTSUPPORTED
, /* GetRingtonesInfo */
2850 NOTSUPPORTED
, /* DeleteUserRingtones */
2852 DCT3DCT4_GetWAPBookmark
,
2853 DCT3_SetWAPBookmark
,
2854 DCT3DCT4_DeleteWAPBookmark
,
2855 DCT3_GetWAPSettings
,
2856 DCT3_SetWAPSettings
,
2857 NOTSUPPORTED
, /* GetMMSSettings */
2858 NOTSUPPORTED
, /* SetMMSSettings */
2861 NOTSUPPORTED
, /* GetToDoStatus */
2862 NOTSUPPORTED
, /* GetToDo */
2863 NOTSUPPORTED
, /* GetNextToDo */
2864 NOTSUPPORTED
, /* SetToDo */
2865 NOTSUPPORTED
, /* AddToDo */
2866 NOTSUPPORTED
, /* DeleteToDo */
2867 NOTSUPPORTED
, /* DeleteAllToDo */
2868 NOTIMPLEMENTED
, /* GetCalendarStatus */
2869 NOTIMPLEMENTED
, /* GetCalendar */
2870 N6110_GetNextCalendarNote
,
2871 NOTIMPLEMENTED
, /* SetCalendar */
2872 N6110_AddCalendarNote
,
2873 N6110_DeleteCalendarNote
,
2874 NOTIMPLEMENTED
, /* DeleteAllCalendar */
2875 NOTSUPPORTED
, /* GetCalendarSettings */
2876 NOTSUPPORTED
, /* SetCalendarSettings */
2877 NOTSUPPORTED
, /* GetNote */
2880 NOTSUPPORTED
, /* GetFMStation */
2881 NOTSUPPORTED
, /* SetFMStation */
2882 NOTSUPPORTED
, /* ClearFMStations */
2883 NOTSUPPORTED
, /* GetNextFileFolder */
2884 NOTSUPPORTED
, /* GetFilePart */
2885 NOTSUPPORTED
, /* AddFile */
2886 NOTSUPPORTED
, /* GetFileSystemStatus */
2887 NOTSUPPORTED
, /* DeleteFile */
2888 NOTSUPPORTED
, /* AddFolder */
2889 NOTSUPPORTED
, /* GetGPRSAccessPoint */
2890 NOTSUPPORTED
/* SetGPRSAccessPoint */
2895 /* How should editor hadle tabs in this file? Add editor commands here.
2896 * vim: noexpandtab sw=8 ts=8 sts=8: