2 #include <string.h> /* memcpy only */
7 #include "../../gsmstate.h"
8 #include "../../misc/coding/coding.h"
9 #include "../../service/sms/gsmsms.h"
13 unsigned char N71_65_MEMORY_TYPES
[] = {
26 int N71_65_PackPBKBlock(GSM_StateMachine
*s
, int id
, int size
, int no
, unsigned char *buf
, unsigned char *block
)
28 smprintf(s
, "Adding block id:%i,number:%i,length:%i\n",id
,no
+1,size
+6);
33 *(block
++) = size
+ 6;
35 memcpy(block
, buf
, size
);
42 int N71_65_EncodePhonebookFrame(GSM_StateMachine
*s
, unsigned char *req
, GSM_MemoryEntry entry
, int *block2
, bool DCT4
, bool VoiceTag
)
44 int count
=0, len
, i
, block
=0;
48 for (i
= 0; i
< entry
.EntriesNum
; i
++)
50 switch (entry
.Entries
[i
].EntryType
) {
51 case PBK_Number_General
:
52 case PBK_Number_Mobile
:
56 switch (entry
.Entries
[i
].EntryType
) {
57 case PBK_Number_General
:
58 string
[0] = N7110_NUMBER_GENERAL
; break;
59 case PBK_Number_Mobile
:
60 string
[0] = N7110_NUMBER_MOBILE
; break;
62 string
[0] = N7110_NUMBER_WORK
; break;
64 string
[0] = N7110_NUMBER_FAX
; break;
66 string
[0] = N7110_NUMBER_HOME
; break;
69 len
= UnicodeLength(entry
.Entries
[i
].Text
);
72 if (!DCT4
) string
[2] = entry
.Entries
[i
].VoiceTag
;
74 string
[4] = len
* 2 + 2; /* length (with Termination) */
75 CopyUnicodeString(string
+5,entry
.Entries
[i
].Text
);
76 string
[len
* 2 + 5] = 0; /* Terminating 0 */
77 count
+= N71_65_PackPBKBlock(s
, N7110_ENTRYTYPE_NUMBER
, len
* 2 + 6, block
++, string
, req
+ count
);
79 if (DCT4
&& VoiceTag
) {
81 req
[count
++] = N6510_ENTRYTYPE_VOICETAG
;
88 req
[count
++] = entry
.Entries
[i
].VoiceTag
;
97 len
= UnicodeLength(entry
.Entries
[i
].Text
);
98 string
[0] = len
* 2 + 2; /* length (with Termination) */
99 CopyUnicodeString(string
+1,entry
.Entries
[i
].Text
);
100 string
[len
* 2 + 1] = 0; /* Terminating 0 */
101 switch (entry
.Entries
[i
].EntryType
) {
103 type
= N7110_ENTRYTYPE_NOTE
; break;
104 case PBK_Text_Postal
:
105 type
= N7110_ENTRYTYPE_POSTAL
; break;
107 case PBK_Text_Email2
:
108 type
= N7110_ENTRYTYPE_EMAIL
; break;
110 type
= N7110_ENTRYTYPE_NOTE
;
111 if (DCT4
) type
= N6510_ENTRYTYPE_URL
;
114 type
= N7110_ENTRYTYPE_NAME
; break;
117 count
+= N71_65_PackPBKBlock(s
, type
, len
* 2 + 2, block
++, string
, req
+ count
);
119 case PBK_Caller_Group
:
120 if (!IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PBK35
)) {
121 string
[0] = entry
.Entries
[i
].Number
;
123 count
+= N71_65_PackPBKBlock(s
, N7110_ENTRYTYPE_GROUP
, 2, block
++, string
, req
+ count
);
127 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_PBK35
)) {
130 string
[2] = entry
.Entries
[i
].Number
;
131 count
+= N71_65_PackPBKBlock(s
, N7110_ENTRYTYPE_RINGTONE
, 3, block
++, string
, req
+ count
);
148 GSM_Error
N71_65_DecodePhonebook(GSM_StateMachine
*s
,
149 GSM_MemoryEntry
*entry
,
151 GSM_SpeedDial
*speed
,
152 unsigned char *MessageBuffer
,
155 unsigned char *Block
;
158 entry
->EntriesNum
= 0;
159 entry
->PreferUnicode
= false;
161 if (entry
->MemoryType
==GMT7110_CG
) {
162 bitmap
->Text
[0] = 0x00;
163 bitmap
->Text
[1] = 0x00;
164 bitmap
->DefaultBitmap
= true;
165 bitmap
->DefaultRingtone
= true;
168 Block
= &MessageBuffer
[0];
169 while (length
!= MessageLength
) {
171 smprintf(s
, "Phonebook entry block - length %i", Block
[3]-6);
172 if (di
.dl
== DL_TEXTALL
|| di
.dl
== DL_TEXTALLDATE
) DumpMessage(di
.df
, Block
+5, Block
[3]-6);
174 if (entry
->EntriesNum
==GSM_PHONEBOOK_ENTRIES
) {
175 smprintf(s
, "Too many entries\n");
176 return GE_UNKNOWNRESPONSE
;
180 case N7110_ENTRYTYPE_NAME
:
181 case N7110_ENTRYTYPE_EMAIL
:
182 case N7110_ENTRYTYPE_POSTAL
:
183 case N7110_ENTRYTYPE_NOTE
:
184 case N6510_ENTRYTYPE_URL
:
185 if (Block
[5]/2>GSM_PHONEBOOK_TEXT_LENGTH
) {
186 smprintf(s
, "Too long text\n");
187 return GE_UNKNOWNRESPONSE
;
189 memcpy(entry
->Entries
[entry
->EntriesNum
].Text
,Block
+6,Block
[5]);
191 case N7110_ENTRYTYPE_NAME
:
192 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Text_Name
;
193 if (entry
->MemoryType
==GMT7110_CG
) {
194 memcpy(bitmap
->Text
,Block
+6,Block
[5]);
196 smprintf(s
, " Name \"%s\"\n",DecodeUnicodeString(entry
->Entries
[entry
->EntriesNum
].Text
));
198 case N7110_ENTRYTYPE_EMAIL
:
199 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Text_Email
;
200 smprintf(s
, " Email \"%s\"\n",DecodeUnicodeString(entry
->Entries
[entry
->EntriesNum
].Text
));
202 case N7110_ENTRYTYPE_POSTAL
:
203 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Text_Postal
;
204 smprintf(s
, " Postal \"%s\"\n",DecodeUnicodeString(entry
->Entries
[entry
->EntriesNum
].Text
));
206 case N7110_ENTRYTYPE_NOTE
:
207 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Text_Note
;
208 smprintf(s
, " Note \"%s\"\n",DecodeUnicodeString(entry
->Entries
[entry
->EntriesNum
].Text
));
210 case N6510_ENTRYTYPE_URL
:
211 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Text_URL
;
212 smprintf(s
, " URL \"%s\"\n",DecodeUnicodeString(entry
->Entries
[entry
->EntriesNum
].Text
));
215 entry
->EntriesNum
++;
217 case N7110_ENTRYTYPE_DATE
:
218 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Date
;
219 NOKIA_DecodeDateTime(s
, Block
+6, &entry
->Entries
[entry
->EntriesNum
].Date
);
220 entry
->EntriesNum
++;
222 case N7110_ENTRYTYPE_NUMBER
:
225 case 0x01: /* Not assigned dialed number */
227 case 0x55: /* In many firmwares 0x55 visible after using
228 * Save from Call Register menu and saving number
229 * to existing phonebook entry */
230 case N7110_NUMBER_GENERAL
:
231 smprintf(s
, " General number");
232 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Number_General
;
234 case N7110_NUMBER_WORK
:
235 smprintf(s
, " Work number");
236 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Number_Work
;
238 case N7110_NUMBER_FAX
:
239 smprintf(s
, " Fax number");
240 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Number_Fax
;
242 case N7110_NUMBER_MOBILE
:
243 smprintf(s
, " Mobile number");
244 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Number_Mobile
;
246 case N7110_NUMBER_HOME
:
247 smprintf(s
, " Home number");
248 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Number_Home
;
251 smprintf(s
, "Unknown number type %02x\n",Block
[5]);
252 return GE_UNKNOWNRESPONSE
;
254 if (Block
[9]/2>GSM_PHONEBOOK_TEXT_LENGTH
) {
255 smprintf(s
, "Too long text\n");
256 return GE_UNKNOWNRESPONSE
;
258 memcpy(entry
->Entries
[entry
->EntriesNum
].Text
,Block
+10,Block
[9]);
259 smprintf(s
, " \"%s\"\n",DecodeUnicodeString(entry
->Entries
[entry
->EntriesNum
].Text
));
260 /* DCT3 phones like 6210 */
261 entry
->Entries
[entry
->EntriesNum
].VoiceTag
= Block
[7];
263 if (entry
->Entries
[entry
->EntriesNum
].VoiceTag
!= 0) smprintf(s
, "Voice tag %i assigned\n",Block
[7]);
265 entry
->EntriesNum
++;
267 case N7110_ENTRYTYPE_RINGTONE
:
268 if (entry
->MemoryType
==GMT7110_CG
) {
269 bitmap
->Ringtone
=Block
[5];
270 if (Block
[5] == 0x00) bitmap
->Ringtone
=Block
[7];
271 smprintf(s
, "Ringtone ID : %i\n",bitmap
->Ringtone
);
272 bitmap
->DefaultRingtone
= false;
274 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_RingtoneID
;
275 smprintf(s
, "Ringtone ID \"%i\"\n",Block
[7]);
276 entry
->Entries
[entry
->EntriesNum
].Number
=Block
[7];
277 entry
->EntriesNum
++;
280 case N7110_ENTRYTYPE_LOGOON
:
281 if (entry
->MemoryType
==GMT7110_CG
) {
282 bitmap
->Enabled
=(Block
[5]==0x00 ? false : true);
283 smprintf(s
, "Logo : %s\n", bitmap
->Enabled
==true ? "enabled":"disabled");
284 } else return GE_UNKNOWNRESPONSE
;
286 case N7110_ENTRYTYPE_GROUPLOGO
:
287 if (entry
->MemoryType
==GMT7110_CG
) {
288 smprintf(s
, "Caller logo\n");
289 PHONE_DecodeBitmap(GSM_NokiaCallerLogo
, Block
+10, bitmap
);
290 bitmap
->DefaultBitmap
= false;
291 } else return GE_UNKNOWNRESPONSE
;
293 case N7110_ENTRYTYPE_GROUP
:
294 entry
->Entries
[entry
->EntriesNum
].EntryType
=PBK_Caller_Group
;
295 smprintf(s
, "Caller group \"%i\"\n",Block
[5]);
296 entry
->Entries
[entry
->EntriesNum
].Number
=Block
[5];
297 if (Block
[5]!=0) entry
->EntriesNum
++;
299 case N6510_ENTRYTYPE_VOICETAG
:
300 smprintf(s
, "Entry %i has voice tag %i\n",Block
[5]-1,Block
[7]);
301 entry
->Entries
[Block
[5]-1].VoiceTag
= Block
[7];
303 /* 6210 5.56, SIM speed dials or ME with 1 number */
304 case N7110_ENTRYTYPE_SIM_SPEEDDIAL
:
305 if (entry
->MemoryType
==GMT7110_SP
) {
307 smprintf(s
, "location %i\n",(Block
[6]*256+Block
[7]));
309 speed
->MemoryType
= GMT_ME
;
310 if (Block
[8] == 0x06) speed
->MemoryType
= GMT_SM
;
311 speed
->MemoryLocation
= (Block
[6]*256+Block
[7]);
312 speed
->MemoryNumberID
= 2;
313 } else return GE_UNKNOWNRESPONSE
;
315 case N7110_ENTRYTYPE_SPEEDDIAL
:
316 if (entry
->MemoryType
==GMT7110_SP
) {
319 case 0x05: smprintf(s
, "ME\n"); break;
320 case 0x06: smprintf(s
, "SM\n"); break;
321 default : smprintf(s
, "%02x\n",Block
[12]);
323 smprintf(s
, "location %i, number %i in location\n",
324 (Block
[6]*256+Block
[7])-1,Block
[14]);
327 case 0x05: speed
->MemoryType
= GMT_ME
; break;
328 case 0x06: speed
->MemoryType
= GMT_SM
; break;
330 speed
->MemoryLocation
= (Block
[6]*256+Block
[7])-1;
331 speed
->MemoryNumberID
= Block
[14];
332 } else return GE_UNKNOWNRESPONSE
;
334 case N7110_ENTRYTYPE_UNKNOWN1
:
335 smprintf(s
,"Unknown entry\n");
338 smprintf(s
, "ERROR: unknown pbk entry %i\n",Block
[0]);
339 return GE_UNKNOWNRESPONSE
;
341 length
=length
+ Block
[3];
342 Block
= &Block
[(int) Block
[3]];
345 if (entry
->EntriesNum
== 0) return GE_EMPTY
;
350 void NOKIA_GetDefaultCallerGroupName(GSM_StateMachine
*s
, GSM_Bitmap
*Bitmap
)
352 Bitmap
->DefaultName
= false;
353 if (Bitmap
->Text
[0]==0x00 && Bitmap
->Text
[1]==0x00) {
354 Bitmap
->DefaultName
= true;
355 switch(Bitmap
->Location
) {
357 EncodeUnicode(Bitmap
->Text
,GetMsg(s
->msg
,"Family"),strlen(GetMsg(s
->msg
,"Family")));
360 EncodeUnicode(Bitmap
->Text
,GetMsg(s
->msg
,"VIP"),strlen(GetMsg(s
->msg
,"VIP")));
363 EncodeUnicode(Bitmap
->Text
,GetMsg(s
->msg
,"Friends"),strlen(GetMsg(s
->msg
,"Friends")));
366 EncodeUnicode(Bitmap
->Text
,GetMsg(s
->msg
,"Colleagues"),strlen(GetMsg(s
->msg
,"Colleagues")));
369 EncodeUnicode(Bitmap
->Text
,GetMsg(s
->msg
,"Other"),strlen(GetMsg(s
->msg
,"Other")));
375 void NOKIA_DecodeDateTime(GSM_StateMachine
*s
, unsigned char* buffer
, GSM_DateTime
*datetime
)
377 datetime
->Year
= buffer
[0] * 256 + buffer
[1];
378 datetime
->Month
= buffer
[2];
379 datetime
->Day
= buffer
[3];
381 datetime
->Hour
= buffer
[4];
382 datetime
->Minute
= buffer
[5];
383 datetime
->Second
= buffer
[6];
385 smprintf(s
, "Decoding date and time\n");
386 smprintf(s
, " Time: %02d:%02d:%02d\n",
387 datetime
->Hour
, datetime
->Minute
, datetime
->Second
);
388 smprintf(s
, " Date: %4d/%02d/%02d\n",
389 datetime
->Year
, datetime
->Month
, datetime
->Day
);
392 #if defined(GSM_ENABLE_NOKIA_DCT3) || defined(GSM_ENABLE_NOKIA_DCT4)
394 /* --------------------- Some general Nokia functions ---------------------- */
396 void NOKIA_DecodeSMSState(GSM_StateMachine
*s
, unsigned char state
, GSM_SMSMessage
*sms
)
399 case 0x01 : sms
->State
= GSM_Read
; break;
400 case 0x03 : sms
->State
= GSM_UnRead
; break;
401 case 0x05 : sms
->State
= GSM_Sent
; break;
402 case 0x07 : sms
->State
= GSM_UnSent
; break;
403 default : smprintf(s
, "Unknown SMS state: %02x\n",state
);
407 GSM_Error
NOKIA_ReplyGetPhoneString(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
409 strcpy(s
->Phone
.Data
.PhoneString
, msg
.Buffer
+s
->Phone
.Data
.StartPhoneString
);
413 /* Some strings are very easy. Some header, after it required string and 0x00.
414 * We can get them using this function. We give frame to send (*string),
415 * type of message (type), pointer for buffer for response (*value), request
416 * type (request) and what is start byte in response for our string
418 GSM_Error
NOKIA_GetPhoneString(GSM_StateMachine
*s
, unsigned char *msgframe
, int msglen
, unsigned char msgtype
, char *retvalue
, GSM_Phone_RequestID request
, int startresponse
)
421 s
->Phone
.Data
.StartPhoneString
= startresponse
;
422 s
->Phone
.Data
.PhoneString
= retvalue
;
423 return GSM_WaitFor (s
, msgframe
, msglen
,msgtype
, 4, request
);
426 GSM_Error
NOKIA_GetManufacturer(GSM_StateMachine
*s
)
428 strcpy(s
->Phone
.Data
.Manufacturer
,"Nokia");
432 /* Many functions contains such strings:
433 * (1. length/256) - exist or not
435 * 3. string (unicode, no termination)
436 * This function read string to output and increases counter
438 void NOKIA_GetUnicodeString(GSM_StateMachine
*s
, int *current
, unsigned char *input
, unsigned char *output
, bool FullLength
)
443 length
= (input
[*current
]*256+input
[*current
+1])*2;
444 memcpy(output
,input
+(*current
+2),length
);
445 *current
= *current
+ 2 + length
;
447 length
= (input
[*current
])*2;
448 memcpy(output
,input
+(*current
+1),length
);
449 *current
= *current
+ 1 + length
;
453 output
[length
+1] = 0;
456 int NOKIA_SetUnicodeString(GSM_StateMachine
*s
, unsigned char *dest
, unsigned char *string
, bool FullLength
)
460 length
= UnicodeLength(string
);
462 dest
[0] = length
/ 256;
463 dest
[1] = length
% 256;
464 CopyUnicodeString(dest
+ 2, string
);
467 dest
[0] = length
% 256;
468 CopyUnicodeString(dest
+ 1, string
);
473 /* Returns correct ID for concrete memory type */
474 GSM_MemoryType
NOKIA_GetMemoryType(GSM_StateMachine
*s
, GSM_MemoryType memory_type
, unsigned char *ID
)
478 while (ID
[i
+1]!=0x00) {
479 if (ID
[i
]==memory_type
) return ID
[i
+1];
485 void NOKIA_EncodeDateTime(GSM_StateMachine
*s
, unsigned char* buffer
, GSM_DateTime
*datetime
)
487 buffer
[0] = datetime
->Year
/ 256;
488 buffer
[1] = datetime
->Year
% 256;
489 buffer
[2] = datetime
->Month
;
490 buffer
[3] = datetime
->Day
;
492 buffer
[4] = datetime
->Hour
;
493 buffer
[5] = datetime
->Minute
;
496 void NOKIA_SortSMSFolderStatus(GSM_StateMachine
*s
, GSM_NOKIASMSFolder
*Folder
)
500 if (Folder
->Number
!=0) {
503 while (i
!=Folder
->Number
-1) {
504 if (Folder
->Location
[i
]>Folder
->Location
[i
+1]) {
505 j
=Folder
->Location
[i
];
506 Folder
->Location
[i
]=Folder
->Location
[i
+1];
507 Folder
->Location
[i
+1]=j
;
514 smprintf(s
, "Locations: ");
515 for (i
=0;i
<Folder
->Number
;i
++) {
516 smprintf(s
, "%i ",Folder
->Location
[i
]);
523 void NOKIA_GetDefaultProfileName(GSM_StateMachine
*s
, GSM_Profile
*Profile
)
525 if (Profile
->DefaultName
) {
526 switch(Profile
->Location
) {
527 case 1: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"General"),strlen(GetMsg(s
->msg
,"General")));
529 case 2: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Silent"),strlen(GetMsg(s
->msg
,"Silent")));
531 case 3: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Meeting"),strlen(GetMsg(s
->msg
,"Meeting")));
533 case 4: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Outdoor"),strlen(GetMsg(s
->msg
,"Outdoor")));
535 case 5: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Pager"),strlen(GetMsg(s
->msg
,"Pager")));
537 case 6: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Car"),strlen(GetMsg(s
->msg
,"Car")));
539 case 7: EncodeUnicode(Profile
->Name
,GetMsg(s
->msg
,"Headset"),strlen(GetMsg(s
->msg
,"Headset")));
545 /* - Shared for DCT3 (n6110.c, n7110.c, n9110.c) and DCT4 (n6510.c) phones - */
547 GSM_Error
DCT3DCT4_ReplyCallDivert(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
549 GSM_MultiCallDivert
*cd
= s
->Phone
.Data
.Divert
;
552 switch (msg
.Buffer
[3]) {
554 smprintf(s
,"Message: Call divert status received\n");
555 smprintf(s
," Divert type: ");
556 switch (msg
.Buffer
[6]) {
557 case 0x43: smprintf(s
,"when busy"); break;
558 case 0x3d: smprintf(s
,"when not answered"); break;
559 case 0x3e: smprintf(s
,"when phone off or no coverage"); break;
560 case 0x15: smprintf(s
,"all types of diverts"); break;
561 default: smprintf(s
,"unknown %i",msg
.Buffer
[6]); break;
564 if (msg
.Length
== 0x0b) {
565 cd
->Response
.EntriesNum
= 0;
568 cd
->Response
.EntriesNum
= msg
.Buffer
[10];
569 for (i
=0;i
<cd
->Response
.EntriesNum
;i
++) {
570 smprintf(s
,"\n Calls type : ");
571 switch (msg
.Buffer
[pos
]) {
574 cd
->Response
.Entries
[i
].CType
= GSM_CDV_VoiceCalls
;
578 cd
->Response
.Entries
[i
].CType
= GSM_CDV_FaxCalls
;
582 cd
->Response
.Entries
[i
].CType
= GSM_CDV_DataCalls
;
585 smprintf(s
,"unknown %i",msg
.Buffer
[pos
]);
587 cd
->Response
.EntriesNum
= 0;
593 while (msg
.Buffer
[j
] != 0x00) j
++;
594 msg
.Buffer
[pos
+1] = j
- pos
- 2;
595 GSM_UnpackSemiOctetNumber(cd
->Response
.Entries
[i
].Number
,msg
.Buffer
+(pos
+1),false);
596 smprintf(s
," Number : %s\n",DecodeUnicodeString(cd
->Response
.Entries
[i
].Number
));
597 cd
->Response
.Entries
[i
].Timeout
= msg
.Buffer
[pos
+34];
598 smprintf(s
," Timeout : %i seconds\n",msg
.Buffer
[pos
+34]);
603 smprintf(s
,"Message: Call divert status receiving error ?\n");
606 return GE_UNKNOWNRESPONSE
;
609 static GSM_Error
DCT3DCT4_CallDivert(GSM_StateMachine
*s
, GSM_MultiCallDivert
*divert
, bool get
)
612 unsigned char req
[55] = {N6110_FRAME_HEADER
, 0x01,
613 0x05, /* operation = Query */
615 0x00, /* divert type */
616 0x00, /* call type */
620 if (UnicodeLength(divert
->Request
.Number
) == 0) {
625 req
[29] = GSM_PackSemiOctetNumber(divert
->Request
.Number
, req
+ 9, false);
626 req
[52] = divert
->Request
.Timeout
;
630 switch (divert
->Request
.DType
) {
631 case GSM_CDV_AllTypes
: req
[6] = 0x15; break;
632 case GSM_CDV_Busy
: req
[6] = 0x43; break;
633 case GSM_CDV_NoAnswer
: req
[6] = 0x3d; break;
634 case GSM_CDV_OutOfReach
: req
[6] = 0x3e; break;
635 default : return GE_NOTIMPLEMENTED
;
638 switch (divert
->Request
.CType
) {
639 case GSM_CDV_AllCalls
: break;
640 case GSM_CDV_VoiceCalls
: req
[7] = 0x0b; break;
641 case GSM_CDV_FaxCalls
: req
[7] = 0x0d; break;
642 case GSM_CDV_DataCalls
: req
[7] = 0x19; break;
643 default : return GE_NOTIMPLEMENTED
;
646 s
->Phone
.Data
.Divert
= divert
;
647 smprintf(s
, "Call divert\n");
648 return GSM_WaitFor (s
, req
, length
, 0x06, 10, ID_Divert
);
651 GSM_Error
DCT3DCT4_GetCallDivert(GSM_StateMachine
*s
, GSM_MultiCallDivert
*divert
)
653 return DCT3DCT4_CallDivert(s
,divert
,true);
656 GSM_Error
DCT3DCT4_SetCallDivert(GSM_StateMachine
*s
, GSM_MultiCallDivert
*divert
)
658 return DCT3DCT4_CallDivert(s
,divert
,false);
661 GSM_Error
DCT3DCT4_CancelAllDiverts(GSM_StateMachine
*s
)
663 GSM_MultiCallDivert divert
;
664 unsigned char req
[55] = {N6110_FRAME_HEADER
, 0x01,
665 0x04, /* operation = Disable */
667 0x02, /* divert type */
668 0x00, /* call type */
671 s
->Phone
.Data
.Divert
= &divert
;
672 smprintf(s
, "Call divert\n");
673 return GSM_WaitFor (s
, req
, 0x09, 0x06, 10, ID_Divert
);
676 GSM_Error
DCT3DCT4_ReplyGetActiveWAPMMSSet(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
678 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
680 Data
->WAPSettings
->Active
= false;
681 if (Data
->WAPSettings
->Location
- 1 == msg
.Buffer
[4]) {
682 Data
->WAPSettings
->Active
= true;
687 GSM_Error
DCT3DCT4_GetActiveWAPMMSSet(GSM_StateMachine
*s
)
689 unsigned char GetSetreq
[] = {N6110_FRAME_HEADER
, 0x0F};
691 smprintf(s
, "Checking, if WAP/MMS settings are active\n");
692 return GSM_WaitFor (s
, GetSetreq
, 4, 0x3f, 4, ID_GetWAPSettings
);
695 GSM_Error
DCT3DCT4_ReplySetActiveWAPMMSSet(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
697 smprintf(s
, "WAP settings activated\n");
701 GSM_Error
DCT3DCT4_SetActiveWAPMMSSet(GSM_StateMachine
*s
, GSM_MultiWAPSettings
*settings
, bool MMS
)
703 unsigned char reqActivate
[] = {
704 N6110_FRAME_HEADER
, 0x12,
705 0x00}; /* Location */
707 if (settings
->Active
) {
708 reqActivate
[4] = settings
->Location
-1;
710 smprintf(s
, "Activating MMS settings\n");
711 return GSM_WaitFor (s
, reqActivate
, 5, 0x3f, 4, ID_SetMMSSettings
);
713 smprintf(s
, "Activating WAP settings\n");
714 return GSM_WaitFor (s
, reqActivate
, 5, 0x3f, 4, ID_SetWAPSettings
);
721 GSM_Error
DCT3DCT4_SendDTMF(GSM_StateMachine
*s
, char *sequence
)
723 unsigned char length
= strlen(sequence
);
724 unsigned char req
[64] = {
725 N6110_FRAME_HEADER
, 0x50,
726 0x00}; /* Length of DTMF string. */
728 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_NODTMF
)) return GE_NOTSUPPORTED
;
730 if (length
>59) length
=59;
733 memcpy(req
+5,sequence
,length
);
735 smprintf(s
, "Sending DTMF\n");
736 return GSM_WaitFor (s
, req
, 5+length
, 0x01, 4, ID_SendDTMF
);
739 GSM_Error
DCT3DCT4_ReplyGetWAPBookmark(GSM_Protocol_Message msg
, GSM_StateMachine
*s
, bool FullLength
)
742 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
744 smprintf(s
, "WAP bookmark received\n");
745 switch (msg
.Buffer
[3]) {
749 Data
->WAPBookmark
->Location
= msg
.Buffer
[tmp
] * 256 + msg
.Buffer
[tmp
+1];
750 smprintf(s
, "Location: %i\n",Data
->WAPBookmark
->Location
);
753 NOKIA_GetUnicodeString(s
, &tmp
, msg
.Buffer
, Data
->WAPBookmark
->Title
, FullLength
);
754 smprintf(s
, "Title : \"%s\"\n",DecodeUnicodeString(Data
->WAPBookmark
->Title
));
756 NOKIA_GetUnicodeString(s
, &tmp
, msg
.Buffer
, Data
->WAPBookmark
->Address
, FullLength
);
757 smprintf(s
, "Address : \"%s\"\n",DecodeUnicodeString(Data
->WAPBookmark
->Address
));
761 switch (msg
.Buffer
[4]) {
763 smprintf(s
, "Security error. Inside WAP bookmarks menu\n");
764 return GE_INSIDEPHONEMENU
;
766 smprintf(s
, "Invalid or empty\n");
767 return GE_INVALIDLOCATION
;
769 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
770 return GE_UNKNOWNRESPONSE
;
774 return GE_UNKNOWNRESPONSE
;
777 GSM_Error
DCT3DCT4_ReplySetWAPBookmark(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
779 switch (msg
.Buffer
[3]) {
781 smprintf(s
, "WAP bookmark set OK\n");
784 smprintf(s
, "WAP bookmark setting error\n");
785 switch (msg
.Buffer
[4]) {
787 smprintf(s
, "Security error. Inside WAP bookmarks menu\n");
788 return GE_INSIDEPHONEMENU
;
790 smprintf(s
, "Can't write to empty location ?\n");
793 smprintf(s
, "Full memory\n");
796 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
797 return GE_UNKNOWNRESPONSE
;
800 return GE_UNKNOWNRESPONSE
;
803 GSM_Error
DCT3DCT4_ReplyEnableWAP(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
805 smprintf(s
, "WAP functions enabled\n");
809 GSM_Error
DCT3DCT4_EnableWAP(GSM_StateMachine
*s
)
811 unsigned char req
[] = { N6110_FRAME_HEADER
, 0x00 };
813 /* Check if have WAP in phone */
814 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_NOWAP
)) return GE_NOTSUPPORTED
;
816 smprintf(s
, "Enabling WAP\n");
817 return GSM_WaitFor (s
, req
, 4, 0x3f, 4, ID_EnableWAP
);
820 GSM_Error
DCT3DCT4_ReplyDelWAPBookmark(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
822 switch (msg
.Buffer
[3]) {
824 smprintf(s
, "WAP bookmark deleted OK\n");
827 smprintf(s
, "WAP bookmark deleting error\n");
828 switch (msg
.Buffer
[4]) {
830 smprintf(s
, "Security error. Inside WAP bookmarks menu\n");
831 return GE_SECURITYERROR
;
833 smprintf(s
, "Invalid location\n");
834 return GE_INVALIDLOCATION
;
836 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[4]);
837 return GE_UNKNOWNRESPONSE
;
840 return GE_UNKNOWNRESPONSE
;
843 GSM_Error
DCT3DCT4_DeleteWAPBookmark(GSM_StateMachine
*s
, GSM_WAPBookmark
*bookmark
)
846 unsigned char req
[] = {
847 N6110_FRAME_HEADER
, 0x0C,
848 0x00, 0x00}; /* Location */
850 /* We have to enable WAP frames in phone */
851 error
=DCT3DCT4_EnableWAP(s
);
852 if (error
!=GE_NONE
) return error
;
854 req
[5] = bookmark
->Location
;
856 smprintf(s
, "Deleting WAP bookmark\n");
857 return GSM_WaitFor (s
, req
, 6, 0x3f, 4, ID_DeleteWAPBookmark
);
860 GSM_Error
DCT3DCT4_GetWAPBookmark(GSM_StateMachine
*s
, GSM_WAPBookmark
*bookmark
)
863 unsigned char req
[] = {
864 N6110_FRAME_HEADER
, 0x06,
865 0x00, 0x00}; /* Location */
867 /* We have to enable WAP frames in phone */
868 error
=DCT3DCT4_EnableWAP(s
);
869 if (error
!=GE_NONE
) return error
;
871 req
[5]=bookmark
->Location
-1;
873 s
->Phone
.Data
.WAPBookmark
=bookmark
;
874 smprintf(s
, "Getting WAP bookmark\n");
875 return GSM_WaitFor (s
, req
, 6, 0x3f, 4, ID_GetWAPBookmark
);
878 GSM_Error
DCT3DCT4_CancelCall(GSM_StateMachine
*s
, int ID
)
880 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x08, 0x00, 0x85};
882 req
[4] = (unsigned char)ID
;
883 s
->Phone
.Data
.CallID
= ID
;
885 smprintf(s
, "Canceling single call\n");
886 return GSM_WaitFor (s
, req
, 6, 0x01, 4, ID_CancelCall
);
889 GSM_Error
DCT3DCT4_AnswerCall(GSM_StateMachine
*s
, int ID
)
891 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x06, 0x00, 0x00};
893 req
[4] = (unsigned char)ID
;
894 s
->Phone
.Data
.CallID
= ID
;
896 smprintf(s
, "Answering single call\n");
897 return GSM_WaitFor (s
, req
, 6, 0x01, 4, ID_AnswerCall
);
900 GSM_Error
DCT3DCT4_ReplyGetModelFirmware(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
903 GSM_Phone_Data
*Data
= &s
->Phone
.Data
;
905 SplitLines(msg
.Buffer
, msg
.Length
, &lines
, "\x20\x0A", 2, false);
907 strcpy(Data
->Model
,GetLineString(msg
.Buffer
, lines
, 4));
908 smprintf(s
, "Received model %s\n",Data
->Model
);
909 Data
->ModelInfo
= GetModelData(NULL
,Data
->Model
,NULL
);
911 strcpy(Data
->VerDate
,GetLineString(msg
.Buffer
, lines
, 3));
912 smprintf(s
, "Received firmware date %s\n",Data
->VerDate
);
914 strcpy(Data
->Version
,GetLineString(msg
.Buffer
, lines
, 2));
915 smprintf(s
, "Received firmware version %s\n",Data
->Version
);
916 GSM_CreateFirmwareNumber(s
);
921 GSM_Error
DCT3DCT4_GetModel (GSM_StateMachine
*s
)
923 unsigned char req
[5] = {N6110_FRAME_HEADER
, 0x03, 0x00};
926 if (strlen(s
->Phone
.Data
.Model
)>0) return GE_NONE
;
928 smprintf(s
, "Getting model\n");
929 error
=GSM_WaitFor (s
, req
, 5, 0xd1, 3, ID_GetModel
);
930 if (error
==GE_NONE
) {
931 if (s
->di
.dl
==DL_TEXT
|| s
->di
.dl
==DL_TEXTALL
||
932 s
->di
.dl
==DL_TEXTDATE
|| s
->di
.dl
==DL_TEXTALLDATE
) {
933 smprintf(s
, "[Connected model - \"%s\"]\n",s
->Phone
.Data
.Model
);
934 smprintf(s
, "[Firmware version - \"%s\"]\n",s
->Phone
.Data
.Version
);
935 smprintf(s
, "[Firmware date - \"%s\"]\n",s
->Phone
.Data
.VerDate
);
941 GSM_Error
DCT3DCT4_GetFirmware (GSM_StateMachine
*s
)
943 unsigned char req
[5] = {N6110_FRAME_HEADER
, 0x03, 0x00};
946 if (strlen(s
->Phone
.Data
.Version
)>0) return GE_NONE
;
948 smprintf(s
, "Getting firmware version\n");
949 error
=GSM_WaitFor (s
, req
, 5, 0xd1, 3, ID_GetFirmware
);
950 if (error
==GE_NONE
) {
951 if (s
->di
.dl
==DL_TEXT
|| s
->di
.dl
==DL_TEXTALL
||
952 s
->di
.dl
==DL_TEXTDATE
|| s
->di
.dl
==DL_TEXTALLDATE
) {
953 smprintf(s
, "[Connected model - \"%s\"]\n",s
->Phone
.Data
.Model
);
954 smprintf(s
, "[Firmware version - \"%s\"]\n",s
->Phone
.Data
.Version
);
955 smprintf(s
, "[Firmware date - \"%s\"]\n",s
->Phone
.Data
.VerDate
);
961 /* ---------- Shared for n7110.c and n6510.c ------------------------------- */
963 GSM_Error
N71_65_ReplyGetMemoryError(unsigned char error
, GSM_StateMachine
*s
)
967 smprintf(s
, "No PIN\n");
968 return GE_SECURITYERROR
;
970 smprintf(s
, "Invalid memory type\n");
971 if (s
->Phone
.Data
.Memory
->MemoryType
== GMT_ME
) return GE_EMPTY
;
972 if (s
->Phone
.Data
.Memory
->MemoryType
== GMT_SM
) return GE_EMPTY
;
973 return GE_NOTSUPPORTED
;
975 smprintf(s
, "Empty location\n");
976 s
->Phone
.Data
.Memory
->EntriesNum
= 0;
979 smprintf(s
, "Too high location ?\n");
980 return GE_INVALIDLOCATION
;
982 smprintf(s
, "ERROR: unknown %i\n",error
);
983 return GE_UNKNOWNRESPONSE
;
987 GSM_Error
N71_65_ReplyWritePhonebook(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
989 smprintf(s
, "Phonebook entry written ");
990 switch (msg
.Buffer
[6]) {
992 smprintf(s
, " - error\n");
993 switch (msg
.Buffer
[10]) {
995 smprintf(s
, "Too long name\n");
996 return GE_NOTSUPPORTED
;
998 smprintf(s
, "Can not add entry with 0 subentries\n");
999 return GE_NOTSUPPORTED
;
1001 smprintf(s
, "Wrong entry type\n");
1002 return GE_NOTSUPPORTED
;
1004 smprintf(s
, "Too much entries\n");
1005 return GE_NOTSUPPORTED
;
1007 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[10]);
1008 return GE_UNKNOWNRESPONSE
;
1011 smprintf(s
, " - OK\n");
1016 bool NOKIA_FindPhoneFeatureValue(GSM_StateMachine
*s
,
1017 GSM_Profile_PhoneTableValue ProfileTable
[],
1018 GSM_Profile_Feat_ID FeatureID
,
1019 GSM_Profile_Feat_Value FeatureValue
,
1020 unsigned char *PhoneID
,
1021 unsigned char *PhoneValue
)
1025 smprintf(s
, "Trying to find feature %i with value %i\n",FeatureID
,FeatureValue
);
1026 while (ProfileTable
[i
].ID
!= 0x00) {
1027 if (ProfileTable
[i
].ID
== FeatureID
&&
1028 ProfileTable
[i
].Value
== FeatureValue
) {
1029 *PhoneID
= ProfileTable
[i
].PhoneID
;
1030 *PhoneValue
= ProfileTable
[i
].PhoneValue
;
1038 #define PROFILE_CALLERGROUPS_GROUP1 0x01
1039 #define PROFILE_CALLERGROUPS_GROUP2 0x02
1040 #define PROFILE_CALLERGROUPS_GROUP3 0x04
1041 #define PROFILE_CALLERGROUPS_GROUP4 0x08
1042 #define PROFILE_CALLERGROUPS_GROUP5 0x10
1044 void NOKIA_FindFeatureValue(GSM_StateMachine
*s
,
1045 GSM_Profile_PhoneTableValue ProfileTable
[],
1047 unsigned char Value
,
1048 GSM_Phone_Data
*Data
,
1054 smprintf(s
, "Caller groups: %i\n", Value
);
1055 Data
->Profile
->FeatureID
[Data
->Profile
->FeaturesNumber
] = Profile_CallerGroups
;
1056 Data
->Profile
->FeaturesNumber
++;
1057 for (i
=0;i
<5;i
++) Data
->Profile
->CallerGroups
[i
] = false;
1058 if ((Value
& PROFILE_CALLERGROUPS_GROUP1
)==PROFILE_CALLERGROUPS_GROUP1
) Data
->Profile
->CallerGroups
[0] = true;
1059 if ((Value
& PROFILE_CALLERGROUPS_GROUP2
)==PROFILE_CALLERGROUPS_GROUP2
) Data
->Profile
->CallerGroups
[1] = true;
1060 if ((Value
& PROFILE_CALLERGROUPS_GROUP3
)==PROFILE_CALLERGROUPS_GROUP3
) Data
->Profile
->CallerGroups
[2] = true;
1061 if ((Value
& PROFILE_CALLERGROUPS_GROUP4
)==PROFILE_CALLERGROUPS_GROUP4
) Data
->Profile
->CallerGroups
[3] = true;
1062 if ((Value
& PROFILE_CALLERGROUPS_GROUP5
)==PROFILE_CALLERGROUPS_GROUP5
) Data
->Profile
->CallerGroups
[4] = true;
1067 while (ProfileTable
[i
].ID
!= 0x00) {
1068 if (ProfileTable
[i
].PhoneID
== ID
&&
1069 ProfileTable
[i
].PhoneValue
== Value
) {
1071 switch (ProfileTable
[i
].ID
) {
1072 case Profile_KeypadTone
: smprintf(s
, "Keypad tones\n"); break;
1073 case Profile_CallAlert
: smprintf(s
, "Call alert\n"); break;
1074 case Profile_RingtoneVolume
: smprintf(s
, "Ringtone volume\n"); break;
1075 case Profile_MessageTone
: smprintf(s
, "SMS message tones\n"); break;
1076 case Profile_Vibration
: smprintf(s
, "Vibration\n"); break;
1077 case Profile_WarningTone
: smprintf(s
, "Warning (ang games) tones\n"); break;
1078 case Profile_AutoAnswer
: smprintf(s
, "Automatic answer\n"); break;
1079 case Profile_Lights
: smprintf(s
, "Lights\n"); break;
1080 case Profile_ScreenSaver
: smprintf(s
, "Screen Saver\n"); break;
1081 case Profile_ScreenSaverTime
: smprintf(s
, "Screen Saver timeout\n"); break;
1085 Data
->Profile
->FeatureID
[Data
->Profile
->FeaturesNumber
] = ProfileTable
[i
].ID
;
1086 Data
->Profile
->FeatureValue
[Data
->Profile
->FeaturesNumber
] = ProfileTable
[i
].Value
;
1087 Data
->Profile
->FeaturesNumber
++;
1094 GSM_Profile_PhoneTableValue Profile71_65
[] = {
1095 {Profile_KeypadTone
, PROFILE_KEYPAD_OFF
, 0x00,0x00},
1096 {Profile_KeypadTone
, PROFILE_KEYPAD_LEVEL1
, 0x00,0x01},
1097 {Profile_KeypadTone
, PROFILE_KEYPAD_LEVEL2
, 0x00,0x02},
1098 {Profile_KeypadTone
, PROFILE_KEYPAD_LEVEL3
, 0x00,0x03},
1100 {Profile_CallAlert
, PROFILE_CALLALERT_RINGING
, 0x02,0x00},
1101 {Profile_CallAlert
, PROFILE_CALLALERT_ASCENDING
, 0x02,0x01},
1102 {Profile_CallAlert
, PROFILE_CALLALERT_RINGONCE
, 0x02,0x02},
1103 {Profile_CallAlert
, PROFILE_CALLALERT_BEEPONCE
, 0x02,0x03},
1104 {Profile_CallAlert
, PROFILE_CALLALERT_OFF
, 0x02,0x05},
1105 /* {Profile_CallAlert, PROFILE_CALLALERT_CALLERGROUPS,0x02,0x07}, */
1107 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL1
, 0x04,0x00},
1108 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL2
, 0x04,0x01},
1109 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL3
, 0x04,0x02},
1110 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL4
, 0x04,0x03},
1111 {Profile_RingtoneVolume
, PROFILE_VOLUME_LEVEL5
, 0x04,0x04},
1112 {Profile_MessageTone
, PROFILE_MESSAGE_NOTONE
, 0x05,0x00},
1113 {Profile_MessageTone
, PROFILE_MESSAGE_STANDARD
, 0x05,0x01},
1114 {Profile_MessageTone
, PROFILE_MESSAGE_SPECIAL
, 0x05,0x02},
1115 {Profile_MessageTone
, PROFILE_MESSAGE_BEEPONCE
, 0x05,0x03},
1116 {Profile_MessageTone
, PROFILE_MESSAGE_ASCENDING
, 0x05,0x04},
1117 {Profile_Vibration
, PROFILE_VIBRATION_OFF
, 0x06,0x00},
1118 {Profile_Vibration
, PROFILE_VIBRATION_ON
, 0x06,0x01},
1119 {Profile_WarningTone
, PROFILE_WARNING_OFF
, 0x07,0x00},
1120 {Profile_WarningTone
, PROFILE_WARNING_ON
, 0x07,0x01},
1122 {Profile_AutoAnswer
, PROFILE_AUTOANSWER_OFF
, 0x09,0x00},
1123 {Profile_AutoAnswer
, PROFILE_AUTOANSWER_ON
, 0x09,0x01},
1124 {0x00, 0x00, 0x00,0x00}
1127 GSM_Error
NOKIA_SetIncomingSMS(GSM_StateMachine
*s
, bool enable
)
1129 s
->Phone
.Data
.EnableIncomingSMS
= enable
;
1132 smprintf(s
, "Enabling incoming SMS\n");
1134 smprintf(s
, "Disabling incoming SMS\n");
1140 GSM_Error
N71_65_ReplyUSSDInfo(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1142 unsigned char buffer
[2000],buffer2
[4000];
1144 if (s
->Phone
.Data
.RequestID
== ID_Divert
) return GE_NONE
;
1146 memcpy(buffer
,msg
.Buffer
+8,msg
.Buffer
[7]);
1147 buffer
[msg
.Buffer
[7]] = 0x00;
1149 smprintf(s
, "USSD reply: \"%s\"\n",buffer
);
1151 if (s
->Phone
.Data
.EnableIncomingUSSD
&& s
->User
.IncomingUSSD
!=NULL
) {
1152 EncodeUnicode(buffer2
,buffer
,strlen(buffer
));
1153 s
->User
.IncomingUSSD(s
->CurrentConfig
->Device
, buffer2
);
1159 GSM_Error
NOKIA_SetIncomingUSSD(GSM_StateMachine
*s
, bool enable
)
1161 s
->Phone
.Data
.EnableIncomingUSSD
= enable
;
1164 smprintf(s
, "Enabling incoming USSD\n");
1166 smprintf(s
, "Disabling incoming USSD\n");
1172 GSM_Error
NOKIA_SetIncomingCall(GSM_StateMachine
*s
, bool enable
)
1174 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
,F_NOCALLINFO
)) return GE_NOTSUPPORTED
;
1176 s
->Phone
.Data
.EnableIncomingCall
= enable
;
1179 smprintf(s
, "Enabling incoming Call\n");
1181 smprintf(s
, "Disabling incoming Call\n");
1187 GSM_Error
N71_65_ReplyCallInfo(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1191 unsigned char buffer
[200];
1194 call
.CallIDAvailable
= true;
1195 smprintf(s
, "Call info, ");
1196 switch (msg
.Buffer
[3]) {
1198 smprintf(s
, "Call established, waiting for answer\n");
1199 call
.Status
= GN_CALL_CallEstablished
;
1202 smprintf(s
, "Call started\n");
1203 smprintf(s
, "Call mode : %i\n",msg
.Buffer
[5]);//after gnokii
1205 NOKIA_GetUnicodeString(s
, &tmp
, msg
.Buffer
,buffer
,false);
1206 smprintf(s
, "Number : \"%s\"\n",DecodeUnicodeString(buffer
));
1207 /* FIXME: read name from frame */
1209 call
.Status
= GN_CALL_CallStart
;
1212 smprintf(s
, "Remote end hang up\n");
1213 smprintf(s
, "Cause Type : %i\n",msg
.Buffer
[5]);//after gnokii
1214 smprintf(s
, "CC : %i\n",msg
.Buffer
[6]);
1215 smprintf(s
, "MM(?) : %i\n",msg
.Buffer
[7]);
1216 smprintf(s
, "RR(?) : %i\n",msg
.Buffer
[8]);
1217 call
.Status
= GN_CALL_CallRemoteEnd
;
1218 call
.StatusCode
= msg
.Buffer
[6];
1221 smprintf(s
, "Incoming call\n");
1222 smprintf(s
, "Call mode : %i\n",msg
.Buffer
[5]);//after gnokii
1224 NOKIA_GetUnicodeString(s
, &tmp
, msg
.Buffer
,buffer
,false);
1225 smprintf(s
, "Number : \"%s\"\n",DecodeUnicodeString(buffer
));
1226 /* FIXME: read name from frame */
1227 call
.Status
= GN_CALL_IncomingCall
;
1229 NOKIA_GetUnicodeString(s
, &tmp
, msg
.Buffer
,call
.PhoneNumber
,false);
1232 smprintf(s
, "Call answer initiated\n");
1235 smprintf(s
, "Call released\n");
1236 call
.Status
= GN_CALL_CallLocalEnd
;
1239 smprintf(s
, "Call is being released\n");
1242 smprintf(s
, "Meaning not known\n");
1243 call
.CallIDAvailable
= false;
1246 smprintf(s
, "Audio status\n");
1247 if (msg
.Buffer
[4] == 0x01) smprintf(s
, "Audio enabled\n");
1248 else smprintf(s
, "Audio disabled\n");
1249 call
.CallIDAvailable
= false;
1252 smprintf(s
, "Call held\n");
1253 call
.Status
= GN_CALL_CallHeld
;
1256 smprintf(s
, "Call resumed\n");
1257 call
.Status
= GN_CALL_CallResumed
;
1260 smprintf(s
, "Call switched\n");
1261 call
.Status
= GN_CALL_CallSwitched
;
1264 smprintf(s
, "Outgoing call\n");
1265 smprintf(s
, "Call mode : %i\n",msg
.Buffer
[5]);//after gnokii
1267 NOKIA_GetUnicodeString(s
, &tmp
, msg
.Buffer
,buffer
,false);
1268 smprintf(s
, "Number : \"%s\"\n",DecodeUnicodeString(buffer
));
1269 /* FIXME: read name from frame */
1270 call
.Status
= GN_CALL_OutgoingCall
;
1272 NOKIA_GetUnicodeString(s
, &tmp
, msg
.Buffer
,call
.PhoneNumber
,false);
1275 if (call
.CallIDAvailable
) smprintf(s
, "Call ID : %d\n",msg
.Buffer
[4]);
1276 if (s
->Phone
.Data
.EnableIncomingCall
&& s
->User
.IncomingCall
!=NULL
&& call
.Status
!= 0) {
1277 if (call
.CallIDAvailable
) call
.CallID
= msg
.Buffer
[4];
1278 s
->User
.IncomingCall(s
->CurrentConfig
->Device
, call
);
1280 if (s
->Phone
.Data
.RequestID
== ID_CancelCall
) {
1281 if (msg
.Buffer
[3] == 0x09) {
1282 if (s
->Phone
.Data
.CallID
== msg
.Buffer
[4]) return GE_NONE
;
1283 /* when we canceled call and see frame about other
1284 * call releasing, we don't give GE_NONE for "our"
1285 * call release command
1287 return GE_NEEDANOTHERANSWER
;
1290 if (s
->Phone
.Data
.RequestID
== ID_AnswerCall
) {
1291 if (msg
.Buffer
[3] == 0x07) {
1292 if (s
->Phone
.Data
.CallID
== msg
.Buffer
[4]) return GE_NONE
;
1293 return GE_NEEDANOTHERANSWER
;
1299 void N71_65_GetCalendarRecurrance(GSM_StateMachine
*s
, unsigned char *buffer
, GSM_CalendarEntry
*entry
)
1303 Recurrance
= buffer
[0]*256 + buffer
[1];
1304 if (Recurrance
== 0xffff) Recurrance
=8760; /* 0xffff -> 1 Year (8760 hours) */
1305 if (Recurrance
!= 0) {
1306 smprintf(s
, "Recurrance : %i hours\n",Recurrance
);
1307 entry
->Entries
[entry
->EntriesNum
].EntryType
= CAL_RECURRANCE
;
1308 entry
->Entries
[entry
->EntriesNum
].Number
= Recurrance
;
1309 entry
->EntriesNum
++;
1314 GSM_Error
N71_65_ReplyAddCalendar2(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1316 smprintf(s
, "Calendar note added\n");
1321 GSM_Error
N71_65_AddCalendar2(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
)
1323 GSM_CalendarNoteType NoteType
;
1324 time_t t_time1
,t_time2
;
1325 GSM_DateTime Date
,date_time
;
1328 int Text
, Time
, Alarm
, Phone
, Recurrance
, EndTime
, Location
, length
=25;
1329 unsigned char req
[5000] = {
1332 0x00, /* frame length - 7 */
1333 0x00,0x00,0x00,0x00,
1334 0x00,0x00,0x00,0x00, /* start time saved as difference */
1335 0x00,0x00,0xff,0xff, /* alarm saved as difference */
1336 0x00, /* frame length - 7 */
1337 0x00, /* note type */
1338 0x00,0x00, /* recurrance */
1339 0x00,0x00,0x00,0x00,
1340 0x00,0x00,0x00,0x00}; /* rest depends on note type */
1342 NoteType
= N71_65_FindCalendarType(Note
->Type
, s
->Phone
.Data
.ModelInfo
);
1344 if (IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_CAL62
) ||
1345 IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_CAL65
))
1348 case GCN_MEETING
: req
[18] = 0x01; length
= 25; break;
1349 case GCN_CALL
: req
[18] = 0x02; length
= 27; break;
1350 case GCN_BIRTHDAY
: req
[18] = 0x04; length
= 28; break;
1351 case GCN_MEMO
: req
[18] = 0x08; length
= 25; break;
1352 default : return GE_UNKNOWN
;
1356 case GCN_REMINDER
: req
[18] = 0x01; length
= 25; break;
1357 case GCN_CALL
: req
[18] = 0x02; length
= 27; break;
1358 case GCN_BIRTHDAY
: req
[18] = 0x04; length
= 28; break;
1359 case GCN_MEMO
: req
[18] = 0x08; length
= 25; break;
1360 default : return GE_UNKNOWN
;
1364 GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note
, &Text
, &Time
, &Alarm
, &Phone
, &Recurrance
, &EndTime
, &Location
);
1366 if (Time
== -1) return GE_UNKNOWN
;
1367 if (NoteType
!= GCN_BIRTHDAY
) {
1368 Date
.Year
= 2030; Date
.Month
= 01; Date
.Day
= 01;
1369 Date
.Hour
= 00; Date
.Minute
= 00; Date
.Second
= 00;
1371 Date
.Year
= 2029; Date
.Month
= 12; Date
.Day
= 31;
1372 Date
.Hour
= 22; Date
.Minute
= 59; Date
.Second
= 58;
1374 t_time1
= Fill_Time_T(Date
,8);
1375 memcpy(&Date
,&Note
->Entries
[Time
].Date
,sizeof(GSM_DateTime
));
1376 if (NoteType
!= GCN_BIRTHDAY
) {
1380 Date
.Hour
= 22; Date
.Minute
= 58; Date
.Second
= 58;
1382 t_time2
= Fill_Time_T(Date
,8);
1383 diff
= t_time1
-t_time2
;
1384 smprintf(s
, " Difference : %i seconds\n", -diff
);
1385 req
[9] = (unsigned char)(-diff
>> 24);
1386 req
[10] = (unsigned char)(-diff
>> 16);
1387 req
[11] = (unsigned char)(-diff
>> 8);
1388 req
[12] = (unsigned char)(-diff
);
1389 if (NoteType
== GCN_BIRTHDAY
) {
1390 req
[25] = Note
->Entries
[Time
].Date
.Year
/ 256;
1391 req
[26] = Note
->Entries
[Time
].Date
.Year
% 256;
1392 /* Recurrance = 1 year */
1397 if (NoteType
== GCN_CALL
&& Phone
!= -1) {
1398 req
[25] = UnicodeLength(Note
->Entries
[Phone
].Text
);
1399 CopyUnicodeString(req
+length
,Note
->Entries
[Phone
].Text
);
1400 length
+= UnicodeLength(Note
->Entries
[Phone
].Text
)*2;
1404 if (NoteType
== GCN_BIRTHDAY
) {
1405 if (Note
->Entries
[Alarm
].EntryType
== CAL_SILENT_ALARM_DATETIME
) req
[27] = 0x01;
1406 error
=s
->Phone
.Functions
->GetDateTime(s
,&date_time
);
1409 case GE_NOTIMPLEMENTED
:
1410 GSM_GetCurrentDateTime(&date_time
);
1417 Date
.Year
= date_time
.Year
;
1423 t_time2
= Fill_Time_T(Date
,8);
1424 t_time1
= Fill_Time_T(Note
->Entries
[Alarm
].Date
,8);
1425 diff
= t_time1
-t_time2
;
1427 /* Sometimes we have difference in minutes */
1428 if (NoteType
== GCN_MEETING
) diff
= diff
/ 60;
1429 if (!IsPhoneFeatureAvailable(s
->Phone
.Data
.ModelInfo
, F_CAL35
)) {
1430 if (NoteType
== GCN_MEMO
|| NoteType
== GCN_CALL
) {
1435 smprintf(s
, " Difference : %i seconds or minutes\n", -diff
);
1436 req
[13] = (unsigned char)(-diff
>> 24);
1437 req
[14] = (unsigned char)(-diff
>> 16);
1438 req
[15] = (unsigned char)(-diff
>> 8);
1439 req
[16] = (unsigned char)(-diff
);
1442 if (Recurrance
!= -1) {
1443 /* 0xffff -> 1 Year (8760 hours) */
1444 if (Note
->Entries
[Recurrance
].Number
>= 8760) {
1448 req
[19] = Note
->Entries
[Recurrance
].Number
/ 256;
1449 req
[20] = Note
->Entries
[Recurrance
].Number
% 256;
1456 req
[26] = UnicodeLength(Note
->Entries
[Text
].Text
);
1459 req
[length
++] = UnicodeLength(Note
->Entries
[Text
].Text
);
1460 if (NoteType
== GCN_MEMO
|| NoteType
== GCN_MEETING
) req
[length
++] = 0x00;
1462 CopyUnicodeString(req
+length
,Note
->Entries
[Text
].Text
);
1463 length
+= UnicodeLength(Note
->Entries
[Text
].Text
)*2;
1466 req
[length
++] = 0x00;
1467 req
[length
++] = 0x00;
1469 req
[4] = req
[17] = length
-7;
1471 smprintf(s
, "Writing calendar note method 2\n");
1472 return GSM_WaitFor (s
, req
, length
, 0x13, 4, ID_SetCalendarNote
);
1476 GSM_Error
N71_65_ReplyGetCalendarNotePos1(GSM_Protocol_Message msg
, GSM_StateMachine
*s
,int *FirstCalendarPos
)
1478 smprintf(s
, "First calendar location: %i\n",msg
.Buffer
[4]*256+msg
.Buffer
[5]);
1479 *FirstCalendarPos
= msg
.Buffer
[4]*256+msg
.Buffer
[5];
1484 static GSM_Error
N71_65_GetCalendarNotePos1(GSM_StateMachine
*s
)
1486 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x31};
1488 smprintf(s
, "Getting first free calendar note location\n");
1489 return GSM_WaitFor (s
, req
, 4, 0x13, 4, ID_GetCalendarNotePos
);
1493 GSM_Error
N71_65_ReplyAddCalendar1(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1496 smprintf(s
, "Written Calendar Note type ");
1497 switch ((msg
.Buffer
[3]/2)-1) {
1498 case 0: smprintf(s
, "Meeting"); break;
1499 case 1: smprintf(s
, "Call"); break;
1500 case 2: smprintf(s
, "Birthday");break;
1501 case 3: smprintf(s
, "Reminder");break;
1503 smprintf(s
, " on location %d\n",msg
.Buffer
[4]*256+msg
.Buffer
[5]);
1509 GSM_Error
N71_65_AddCalendar1(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
, int *FirstCalendarPos
)
1514 int Text
, Time
, Alarm
, Phone
, Recurrance
, EndTime
, Location
, count
=12;
1515 unsigned char req
[5000] = {
1517 0x01, /* note type */
1518 0x00, 0x00, /* location ? */
1519 0x00, /* entry type */
1521 0x00, 0x00, 0x00, 0x00, /* Year(2bytes), Month, Day */
1522 /* here starts block ... depends on note type */
1523 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1525 error
=N71_65_GetCalendarNotePos1(s
);
1526 if (error
!=GE_NONE
) return error
;
1527 if (FirstCalendarPos
!= NULL
) {
1528 req
[4] = *FirstCalendarPos
/256;
1529 req
[5] = *FirstCalendarPos
%256;
1532 switch(Note
->Type
) {
1533 case GCN_CALL
: req
[3]=0x03; req
[6]=0x02; break;
1534 case GCN_BIRTHDAY
: req
[3]=0x05; req
[6]=0x04; break;
1535 case GCN_MEMO
: req
[3]=0x07; req
[6]=0x08; break;
1537 default : req
[3]=0x01; req
[6]=0x01; break;
1540 GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note
, &Text
, &Time
, &Alarm
, &Phone
, &Recurrance
, &EndTime
, &Location
);
1542 if (Time
== -1) return GE_UNKNOWN
;
1543 memcpy(&DT
,&Note
->Entries
[Time
].Date
,sizeof(GSM_DateTime
));
1544 req
[8] = DT
.Year
>> 8;
1545 req
[9] = DT
.Year
& 0xff;
1549 switch(Note
->Type
) {
1551 req
[count
++] = 0x00; /* 12 */
1552 req
[count
++] = 0x00; /* 13 */
1555 req
[count
++] = 0x00; /* 14 */
1556 req
[count
++] = 0x00; /* 15 */
1557 req
[count
++] = 0xff; /* 16 */
1558 req
[count
++] = 0xff; /* 17 */
1560 /* I try with Time.Year = Alarm.Year. If negative, I increase 1 year,
1561 * but only once ! This thing, because I may have Alarm period across
1562 * a year. (eg. Birthday on 2001-01-10 and Alarm on 2000-12-27)
1564 DT
.Year
= Note
->Entries
[Alarm
].Date
.Year
;
1565 if((seconds
= Fill_Time_T(DT
,8)-Fill_Time_T(Note
->Entries
[Alarm
].Date
,8))<0L)
1568 seconds
= Fill_Time_T(DT
,8)-Fill_Time_T(Note
->Entries
[Alarm
].Date
,8);
1573 req
[count
++] = (unsigned char)(seconds
>>24); /* 14 */
1574 req
[count
++] = (unsigned char)((seconds
>>16) & 0xff); /* 15 */
1575 req
[count
++] = (unsigned char)((seconds
>>8) & 0xff); /* 16 */
1576 req
[count
++] = (unsigned char)(seconds
& 0xff); /* 17 */
1578 if (Note
->Entries
[Alarm
].EntryType
== CAL_SILENT_ALARM_DATETIME
) req
[count
++] = 0x01; else req
[count
++] = 0x00;
1582 req
[count
++] = UnicodeLength(Note
->Entries
[Text
].Text
); /* 19 */
1583 CopyUnicodeString(req
+count
,Note
->Entries
[Text
].Text
);
1584 count
=count
+2*UnicodeLength(Note
->Entries
[Text
].Text
); /* 22->N */
1586 req
[count
++] = 0x00;
1590 if (Recurrance
!= -1) {
1591 /* 0xffff -> 1 Year (8760 hours) */
1592 if (Note
->Entries
[Recurrance
].Number
>= 8760) {
1593 req
[count
++] = 0xff;
1594 req
[count
++] = 0xff;
1596 req
[count
++] = Note
->Entries
[Recurrance
].Number
>> 8; /* 12 */
1597 req
[count
++] = Note
->Entries
[Recurrance
].Number
& 0xff; /* 13 */
1600 req
[count
++] = 0x00; /* 12 */
1601 req
[count
++] = 0x00; /* 13 */
1605 req
[count
++] = UnicodeLength(Note
->Entries
[Text
].Text
); /* 14 */
1606 req
[count
++] = 0x00; /* 15 */
1607 CopyUnicodeString(req
+count
,Note
->Entries
[Text
].Text
);
1608 count
=count
+2*UnicodeLength(Note
->Entries
[Text
].Text
); /* 16->N */
1610 req
[count
++] = 0x00;
1611 req
[count
++] = 0x00;
1617 req
[count
++] = DT
.Hour
; /* 12 */
1618 req
[count
++] = DT
.Minute
; /* 13 */
1621 req
[count
++] = 0xff; /* 14 */
1622 req
[count
++] = 0xff; /* 15 */
1624 seconds
=Fill_Time_T(DT
,8)-Fill_Time_T(Note
->Entries
[Alarm
].Date
,8);
1628 req
[count
++] = ((unsigned char)(seconds
/60L)>>8);
1629 req
[count
++] = (unsigned char)((seconds
/60L)&0xff);
1633 if (Recurrance
!= -1) {
1634 /* 0xffff -> 1 Year (8760 hours) */
1635 if (Note
->Entries
[Recurrance
].Number
>= 8760) {
1636 req
[count
++] = 0xff;
1637 req
[count
++] = 0xff;
1639 req
[count
++] = Note
->Entries
[Recurrance
].Number
>> 8; /* 12 */
1640 req
[count
++] = Note
->Entries
[Recurrance
].Number
& 0xff; /* 13 */
1643 req
[count
++] = 0x00; /* 16 */
1644 req
[count
++] = 0x00; /* 17 */
1648 req
[count
++] = UnicodeLength(Note
->Entries
[Text
].Text
);
1650 req
[count
++] = 0x00; /* 18 */
1652 if (Note
->Type
== GCN_CALL
&& Phone
!= -1) {
1653 req
[count
++] = UnicodeLength(Note
->Entries
[Phone
].Text
);
1655 req
[count
++] = 0x00; /* 19 */
1658 CopyUnicodeString(req
+count
,Note
->Entries
[Text
].Text
);
1659 count
=count
+2*UnicodeLength(Note
->Entries
[Text
].Text
);/* 20->N */
1661 if (Note
->Type
== GCN_CALL
&& Phone
!= -1) {
1662 CopyUnicodeString(req
+count
,Note
->Entries
[Phone
].Text
);
1663 count
=count
+2*UnicodeLength(Note
->Entries
[Phone
].Text
);/* (N+1)->n */
1668 smprintf(s
, "Writing calendar note method 1\n");
1669 return GSM_WaitFor (s
, req
, count
, 0x13, 4, ID_SetCalendarNote
);
1672 GSM_Error
N71_65_ReplyDelCalendar(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1674 smprintf(s
, "Deleted calendar note on location %d\n",msg
.Buffer
[4]*256+msg
.Buffer
[5]);
1678 GSM_Error
N71_65_DelCalendar(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
)
1680 unsigned char req
[] = {
1681 N6110_FRAME_HEADER
, 0x0b,
1682 0x00, 0x00}; /* location */
1684 req
[4] = Note
->Location
>> 8;
1685 req
[5] = Note
->Location
& 0xff;
1687 smprintf(s
, "Deleting calendar note\n");
1688 return GSM_WaitFor (s
, req
, 6, 0x13, 4, ID_DeleteCalendarNote
);
1692 GSM_Error
N71_65_ReplyGetCalendarInfo1(GSM_Protocol_Message msg
, GSM_StateMachine
*s
, GSM_NOKIACalToDoLocations
*LastCalendar
)
1696 smprintf(s
, "Info with calendar notes locations received method 1\n");
1697 while (LastCalendar
->Location
[j
] != 0x00) j
++;
1698 if (j
>= GSM_MAXCALENDARTODONOTES
) {
1699 smprintf(s
, "Increase GSM_MAXCALENDARNOTES\n");
1703 LastCalendar
->Number
=msg
.Buffer
[4]*256+msg
.Buffer
[5];
1704 smprintf(s
, "Number of Entries: %i\n",LastCalendar
->Number
);
1706 smprintf(s
, "Locations: ");
1708 while (9+(i
*2) <= msg
.Length
) {
1709 LastCalendar
->Location
[j
++]=msg
.Buffer
[8+(i
*2)]*256+msg
.Buffer
[9+(i
*2)];
1710 smprintf(s
, "%i ",LastCalendar
->Location
[j
-1]);
1713 smprintf(s
, "\nNumber of Entries in frame: %i\n",i
);
1715 LastCalendar
->Location
[j
] = 0;
1716 if (i
== 1 && msg
.Buffer
[8+(0*2)]*256+msg
.Buffer
[9+(0*2)] == 0) return GE_EMPTY
;
1717 if (i
== 0) return GE_EMPTY
;
1722 GSM_Error
N71_65_GetCalendarInfo1(GSM_StateMachine
*s
, GSM_NOKIACalToDoLocations
*LastCalendar
)
1726 unsigned char req
[] = {N6110_FRAME_HEADER
, 0x3a,
1727 0xFF, 0xFE}; /* First location number */
1729 LastCalendar
->Location
[0] = 0x00;
1730 LastCalendar
->Number
= 0;
1732 smprintf(s
, "Getting locations for calendar method 1\n");
1733 error
= GSM_WaitFor (s
, req
, 6, 0x13, 4, ID_GetCalendarNotesInfo
);
1734 if (error
!= GE_NONE
&& error
!= GE_EMPTY
) return error
;
1738 while (LastCalendar
->Location
[i
] != 0x00) i
++;
1739 if (i
== LastCalendar
->Number
) break;
1740 if (i
!= LastCalendar
->Number
&& error
== GE_EMPTY
) {
1741 smprintf(s
, "Phone doesn't support some notes with this method. Workaround\n");
1742 LastCalendar
->Number
= i
;
1745 smprintf(s
, "i = %i %i\n",i
,LastCalendar
->Number
);
1746 req
[4] = LastCalendar
->Location
[i
-1] / 256;
1747 req
[5] = LastCalendar
->Location
[i
-1] % 256;
1748 smprintf(s
, "Getting locations for calendar\n");
1749 error
= GSM_WaitFor (s
, req
, 6, 0x13, 4, ID_GetCalendarNotesInfo
);
1750 if (error
!= GE_NONE
&& error
!= GE_EMPTY
) return error
;
1756 GSM_Error
N71_65_ReplyGetNextCalendar1(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1759 GSM_CalendarEntry
*entry
= s
->Phone
.Data
.Cal
;
1761 smprintf(s
, "Calendar note received method 1\n");
1763 /* Later these values can change */
1764 if (msg
.Buffer
[6]!=0x04) { /* Here not birthday */
1765 entry
->Entries
[0].Date
.Year
= msg
.Buffer
[8]*256+msg
.Buffer
[9];
1767 entry
->Entries
[0].Date
.Month
= msg
.Buffer
[10];
1768 entry
->Entries
[0].Date
.Day
= msg
.Buffer
[11];
1769 entry
->Entries
[0].Date
.Hour
= msg
.Buffer
[12];
1770 entry
->Entries
[0].Date
.Minute
= msg
.Buffer
[13];
1771 entry
->Entries
[0].Date
.Second
= 0;
1772 entry
->Entries
[0].EntryType
= CAL_START_DATETIME
;
1773 entry
->EntriesNum
++;
1775 switch (msg
.Buffer
[6]) {
1777 smprintf(s
, "Meeting\n");
1778 entry
->Type
= GCN_MEETING
;
1780 alarm
=msg
.Buffer
[14]*256+msg
.Buffer
[15];
1781 if (alarm
!= 0xffff) {
1782 smprintf(s
, " Difference : %i seconds\n", alarm
);
1783 memcpy(&entry
->Entries
[1].Date
,&entry
->Entries
[0].Date
,sizeof(GSM_DateTime
));
1784 GetTimeDifference(alarm
, &entry
->Entries
[1].Date
, false, 60);
1785 entry
->Entries
[1].EntryType
= CAL_ALARM_DATETIME
;
1786 entry
->EntriesNum
++;
1788 N71_65_GetCalendarRecurrance(s
, msg
.Buffer
+ 16, entry
);
1790 memcpy(entry
->Entries
[entry
->EntriesNum
].Text
, msg
.Buffer
+20, msg
.Buffer
[18]*2);
1791 entry
->Entries
[entry
->EntriesNum
].Text
[msg
.Buffer
[18]*2] = 0;
1792 entry
->Entries
[entry
->EntriesNum
].Text
[msg
.Buffer
[18]*2+1] = 0;
1793 entry
->Entries
[entry
->EntriesNum
].EntryType
= CAL_TEXT
;
1794 smprintf(s
, "Text : \"%s\"\n", DecodeUnicodeString(entry
->Entries
[entry
->EntriesNum
].Text
));
1795 entry
->EntriesNum
++;
1798 smprintf(s
, "Call\n");
1799 entry
->Type
= GCN_CALL
;
1801 alarm
=msg
.Buffer
[14]*256+msg
.Buffer
[15];
1802 if (alarm
!= 0xffff) {
1803 smprintf(s
, " Difference : %i seconds\n", alarm
);
1804 memcpy(&entry
->Entries
[1].Date
,&entry
->Entries
[0].Date
,sizeof(GSM_DateTime
));
1805 GetTimeDifference(alarm
, &entry
->Entries
[1].Date
, false, 60);
1806 entry
->Entries
[1].EntryType
= CAL_ALARM_DATETIME
;
1807 entry
->EntriesNum
++;
1809 N71_65_GetCalendarRecurrance(s
, msg
.Buffer
+ 16, entry
);
1811 i
= msg
.Buffer
[18] * 2;
1813 memcpy(entry
->Entries
[entry
->EntriesNum
].Text
, msg
.Buffer
+20, i
);
1814 entry
->Entries
[entry
->EntriesNum
].Text
[i
] = 0;
1815 entry
->Entries
[entry
->EntriesNum
].Text
[i
+1] = 0;
1816 entry
->Entries
[entry
->EntriesNum
].EntryType
= CAL_TEXT
;
1817 smprintf(s
, "Text : \"%s\"\n", DecodeUnicodeString(entry
->Entries
[entry
->EntriesNum
].Text
));
1818 entry
->EntriesNum
++;
1821 memcpy(entry
->Entries
[entry
->EntriesNum
].Text
, msg
.Buffer
+20+i
, msg
.Buffer
[19]*2);
1822 entry
->Entries
[entry
->EntriesNum
].Text
[msg
.Buffer
[19]*2] = 0;
1823 entry
->Entries
[entry
->EntriesNum
].Text
[msg
.Buffer
[19]*2+1] = 0;
1824 entry
->Entries
[entry
->EntriesNum
].EntryType
= CAL_PHONE
;
1825 smprintf(s
, "Phone : \"%s\"\n", DecodeUnicodeString(entry
->Entries
[entry
->EntriesNum
].Text
));
1826 entry
->EntriesNum
++;
1829 smprintf(s
, "Birthday\n");
1830 entry
->Type
= GCN_BIRTHDAY
;
1832 entry
->Entries
[0].Date
.Hour
= 23;
1833 entry
->Entries
[0].Date
.Minute
= 59;
1834 entry
->Entries
[0].Date
.Second
= 58;
1836 alarm
= ((unsigned int)msg
.Buffer
[14]) << 24;
1837 alarm
+= ((unsigned int)msg
.Buffer
[15]) << 16;
1838 alarm
+= ((unsigned int)msg
.Buffer
[16]) << 8;
1839 alarm
+= msg
.Buffer
[17];
1840 if (alarm
!= 0xffff) {
1841 smprintf(s
, " Difference : %i seconds\n", alarm
);
1842 memcpy(&entry
->Entries
[1].Date
,&entry
->Entries
[0].Date
,sizeof(GSM_DateTime
));
1843 GetTimeDifference(alarm
, &entry
->Entries
[1].Date
, false, 1);
1844 entry
->Entries
[1].EntryType
= CAL_ALARM_DATETIME
;
1845 if (msg
.Buffer
[20]!=0x00) {
1846 entry
->Entries
[1].EntryType
= CAL_SILENT_ALARM_DATETIME
;
1847 smprintf(s
, "Alarm type : Silent\n");
1849 entry
->EntriesNum
++;
1852 entry
->Entries
[0].Date
.Year
= msg
.Buffer
[18]*256 + msg
.Buffer
[19];
1853 if (entry
->Entries
[0].Date
.Year
== 65535) entry
->Entries
[0].Date
.Year
= 0;
1854 smprintf(s
, "Age : %i\n",entry
->Entries
[0].Date
.Year
);
1856 memcpy(entry
->Entries
[entry
->EntriesNum
].Text
, msg
.Buffer
+22, msg
.Buffer
[21]*2);
1857 entry
->Entries
[entry
->EntriesNum
].Text
[msg
.Buffer
[21]*2] = 0;
1858 entry
->Entries
[entry
->EntriesNum
].Text
[msg
.Buffer
[21]*2+1] = 0;
1859 entry
->Entries
[entry
->EntriesNum
].EntryType
= CAL_TEXT
;
1860 smprintf(s
, "Text : \"%s\"\n", DecodeUnicodeString(entry
->Entries
[entry
->EntriesNum
].Text
));
1861 entry
->EntriesNum
++;
1864 smprintf(s
, "Memo\n");
1865 entry
->Type
= GCN_MEMO
;
1867 entry
->Entries
[0].Date
.Hour
= 0;
1868 entry
->Entries
[0].Date
.Minute
= 0;
1870 N71_65_GetCalendarRecurrance(s
, msg
.Buffer
+ 12, entry
);
1872 memcpy(entry
->Entries
[entry
->EntriesNum
].Text
, msg
.Buffer
+16, msg
.Buffer
[14]*2);
1873 entry
->Entries
[entry
->EntriesNum
].Text
[msg
.Buffer
[14]*2] = 0;
1874 entry
->Entries
[entry
->EntriesNum
].Text
[msg
.Buffer
[14]*2+1] = 0;
1875 entry
->Entries
[entry
->EntriesNum
].EntryType
= CAL_TEXT
;
1876 smprintf(s
, "Text : \"%s\"\n", DecodeUnicodeString(entry
->Entries
[entry
->EntriesNum
].Text
));
1877 entry
->EntriesNum
++;
1880 smprintf(s
, "ERROR: unknown %i\n",msg
.Buffer
[6]);
1881 return GE_UNKNOWNRESPONSE
;
1886 GSM_Error
N71_65_GetNextCalendar1(GSM_StateMachine
*s
, GSM_CalendarEntry
*Note
, bool start
, GSM_NOKIACalToDoLocations
*LastCalendar
, int *LastCalendarYear
, int *LastCalendarPos
)
1889 GSM_DateTime date_time
;
1890 unsigned char req
[] = {
1891 N6110_FRAME_HEADER
, 0x19,
1892 0x00, 0x00}; /* Location */
1895 error
=N71_65_GetCalendarInfo1(s
, LastCalendar
);
1896 if (error
!=GE_NONE
) return error
;
1897 if (LastCalendar
->Number
== 0) return GE_EMPTY
;
1899 /* We have to get current year. It's NOT written in frame for
1902 error
=s
->Phone
.Functions
->GetDateTime(s
,&date_time
);
1905 case GE_NOTIMPLEMENTED
:
1906 GSM_GetCurrentDateTime(&date_time
);
1913 *LastCalendarYear
= date_time
.Year
;
1914 *LastCalendarPos
= 0;
1916 (*LastCalendarPos
)++;
1919 if (*LastCalendarPos
>= LastCalendar
->Number
) return GE_EMPTY
;
1921 req
[4] = LastCalendar
->Location
[*LastCalendarPos
] >> 8;
1922 req
[5] = LastCalendar
->Location
[*LastCalendarPos
] & 0xff;
1924 Note
->EntriesNum
= 0;
1925 Note
->Entries
[0].Date
.Year
= *LastCalendarYear
;
1926 Note
->Location
= LastCalendar
->Location
[*LastCalendarPos
];
1928 s
->Phone
.Data
.Cal
=Note
;
1929 smprintf(s
, "Getting calendar note method 1\n");
1930 return GSM_WaitFor (s
, req
, 6, 0x13, 4, ID_GetCalendarNote
);
1933 GSM_Error
N71_65_EnableFunctions(GSM_StateMachine
*s
,char *buff
,int len
)
1935 unsigned char buffer
[50] =
1936 {N6110_FRAME_HEADER
,0x10,
1940 memcpy(buffer
+5,buff
,len
);
1942 /* Enables various things like incoming SMS, call info, etc. */
1943 return s
->Protocol
.Functions
->WriteMessage(s
, buffer
, 5+len
, 0x10);
1946 GSM_Error
N71_65_ReplySendDTMF(GSM_Protocol_Message msg
, GSM_StateMachine
*s
)
1948 switch (msg
.Buffer
[3]) {
1950 smprintf(s
, "DTMF sent OK\n");
1954 smprintf(s
, "meaning unknown - during sending DTMF\n");
1957 return GE_UNKNOWNRESPONSE
;
1960 GSM_CalendarNoteType
N71_65_FindCalendarType(GSM_CalendarNoteType Type
, OnePhoneModel
*model
)
1966 return GCN_BIRTHDAY
;
1968 if (IsPhoneFeatureAvailable(model
, F_CAL35
)) {
1969 return GCN_REMINDER
;
1970 } else return GCN_MEETING
;
1972 if (IsPhoneFeatureAvailable(model
, F_CAL35
)) {
1973 return GCN_REMINDER
;
1974 } else return GCN_MEMO
;
1976 if (IsPhoneFeatureAvailable(model
, F_CAL62
) ||
1977 IsPhoneFeatureAvailable(model
, F_CAL65
)) {
1979 } else return GCN_REMINDER
;
1987 /* How should editor hadle tabs in this file? Add editor commands here.
1988 * vim: noexpandtab sw=8 ts=8 sts=8: