summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/phone/nokia/dct3
Unidiff
Diffstat (limited to 'gammu/emb/common/phone/nokia/dct3') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/phone/nokia/dct3/dct3comm.h16
-rw-r--r--gammu/emb/common/phone/nokia/dct3/dct3func.c1535
-rw-r--r--gammu/emb/common/phone/nokia/dct3/dct3func.h78
-rw-r--r--gammu/emb/common/phone/nokia/dct3/n6110.c2884
-rw-r--r--gammu/emb/common/phone/nokia/dct3/n6110.h45
-rw-r--r--gammu/emb/common/phone/nokia/dct3/n7110.c1724
-rw-r--r--gammu/emb/common/phone/nokia/dct3/n7110.h45
-rw-r--r--gammu/emb/common/phone/nokia/dct3/n9210.c396
-rw-r--r--gammu/emb/common/phone/nokia/dct3/n9210.h17
9 files changed, 6740 insertions, 0 deletions
diff --git a/gammu/emb/common/phone/nokia/dct3/dct3comm.h b/gammu/emb/common/phone/nokia/dct3/dct3comm.h
new file mode 100644
index 0000000..0b3e42e
--- a/dev/null
+++ b/gammu/emb/common/phone/nokia/dct3/dct3comm.h
@@ -0,0 +1,16 @@
1/* (c) 2002-2003 by Marcin Wiacek */
2
3#ifndef phone_nokia_dct3common_h
4#define phone_nokia_dct3common_h
5
6typedef struct {
7 int Locations[4];
8 intCurrentLocation;
9 intID;
10} DCT3_WAPSettings_Locations;
11
12#endif
13
14/* How should editor hadle tabs in this file? Add editor commands here.
15 * vim: noexpandtab sw=8 ts=8 sts=8:
16 */
diff --git a/gammu/emb/common/phone/nokia/dct3/dct3func.c b/gammu/emb/common/phone/nokia/dct3/dct3func.c
new file mode 100644
index 0000000..beef33c
--- a/dev/null
+++ b/gammu/emb/common/phone/nokia/dct3/dct3func.c
@@ -0,0 +1,1535 @@
1/* (c) 2001-2004 by Marcin Wiacek */
2/* based on some work from Markus Plail, Pavel Janik, others and Gnokii */
3/* resetting DCT4 phones settings (c) by Walek */
4
5#include <string.h> /* memcpy only */
6#include <stdio.h>
7#include <ctype.h>
8
9#include "../../../gsmstate.h"
10#include "../../../misc/coding/coding.h"
11#include "../../../service/sms/gsmsms.h"
12#include "../../pfunc.h"
13#include "../nfunc.h"
14#include "dct3func.h"
15
16#ifdef GSM_ENABLE_NOKIA_DCT3
17
18GSM_Error DCT3_DeleteWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
19{
20 GSM_Error error;
21
22 /* We have to enable WAP frames in phone */
23 error=DCT3DCT4_EnableWAPFunctions(s);
24 if (error!=ERR_NONE) return error;
25
26 return DCT3DCT4_DeleteWAPBookmarkPart(s,bookmark);
27}
28
29GSM_Error DCT3_GetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
30{
31 GSM_Error error;
32
33 /* We have to enable WAP frames in phone */
34 error=DCT3DCT4_EnableWAPFunctions(s);
35 if (error!=ERR_NONE) return error;
36
37 return DCT3DCT4_GetWAPBookmarkPart(s,bookmark);
38}
39
40GSM_Error DCT3_ReplyPressKey(GSM_Protocol_Message msg, GSM_StateMachine *s)
41{
42 GSM_Phone_Data *Data = &s->Phone.Data;
43
44 switch (msg.Buffer[2]) {
45 case 0x46:
46 smprintf(s, "Pressing key OK\n");
47 if (Data->PressKey) return ERR_NONE;
48 break;
49 case 0x47:
50 smprintf(s, "Releasing key OK\n");
51 if (!Data->PressKey) return ERR_NONE;
52 break;
53 }
54 return ERR_UNKNOWNRESPONSE;
55}
56
57GSM_Error DCT3_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, bool Press)
58{
59 unsigned char PressReq[] = {0x00, 0x01, 0x46, 0x00, 0x01,
60 0x0a}; /* Key code */
61 unsigned char ReleaseReq[] = {0x00, 0x01, 0x47, 0x00, 0x01, 0x0c};
62
63 if (Press) {
64 PressReq[5] = Key;
65 s->Phone.Data.PressKey = true;
66 smprintf(s, "Pressing key\n");
67 return GSM_WaitFor (s, PressReq, 6, 0xd1, 4, ID_PressKey);
68 } else {
69 s->Phone.Data.PressKey = false;
70 smprintf(s, "Releasing key\n");
71 return GSM_WaitFor (s, ReleaseReq, 6, 0xd1, 4, ID_PressKey);
72 }
73}
74
75GSM_Error DCT3_ReplyPlayTone(GSM_Protocol_Message msg, GSM_StateMachine *s)
76{
77 smprintf(s, "Tone played\n");
78 return ERR_NONE;
79}
80
81GSM_Error DCT3_PlayTone(GSM_StateMachine *s, int Herz, unsigned char Volume, bool start)
82{
83 GSM_Error error;
84 unsigned char req[] = {0x00,0x01,0x8f,
85 0x00, /* Volume */
86 0x00, /* HerzLo */
87 0x00}; /* HerzHi */
88
89 if (start) {
90 error=DCT3_EnableSecurity (s, 0x01);
91 if (error!=ERR_NONE) return error;
92 }
93
94 /* For Herz==255*255 we have silent */
95 if (Herz!=255*255) {
96 req[3]=Volume;
97 req[5]=Herz%256;
98 req[4]=Herz/256;
99 } else {
100 req[3]=0;
101 req[5]=0;
102 req[4]=0;
103 }
104
105 return GSM_WaitFor (s, req, 6, 0x40, 4, ID_PlayTone);
106}
107
108#ifdef GSM_ENABLE_CELLBROADCAST
109
110GSM_Error DCT3_ReplyIncomingCB(GSM_Protocol_Message msg, GSM_StateMachine *s)
111{
112 GSM_CBMessage CB;
113 int i;
114 char Buffer[300];
115
116 smprintf(s, "CB received\n");
117 CB.Channel = msg.Buffer[7];
118 i = GSM_UnpackEightBitsToSeven(0, msg.Buffer[9], msg.Buffer[9], msg.Buffer+10, Buffer);
119 i = msg.Buffer[9] - 1;
120 while (i!=0) {
121 if (Buffer[i] == 13) i = i - 1; else break;
122 }
123 DecodeDefault(CB.Text, Buffer, i + 1, false, NULL);
124 smprintf(s, "Channel %i, text \"%s\"\n",CB.Channel,DecodeUnicodeString(CB.Text));
125 if (s->Phone.Data.EnableIncomingCB && s->User.IncomingCB!=NULL) {
126 s->User.IncomingCB(s->CurrentConfig->Device,CB);
127 }
128 return ERR_NONE;
129}
130
131GSM_Error DCT3_ReplySetIncomingCB(GSM_Protocol_Message msg, GSM_StateMachine *s)
132{
133 switch (msg.Buffer[3]) {
134 case 0x21:
135 smprintf(s, "CB set\n");
136 return ERR_NONE;
137 case 0x22:
138 smprintf(s, "CB not set\n");
139 return ERR_UNKNOWN;
140 case 0xCA:
141 smprintf(s, "No network and no CB\n");
142 return ERR_SECURITYERROR;
143 }
144 return ERR_UNKNOWNRESPONSE;
145}
146
147#endif
148
149GSM_Error DCT3_SetIncomingCB(GSM_StateMachine *s, bool enable)
150{
151#ifdef GSM_ENABLE_CELLBROADCAST
152 unsigned char reqOn[] = {N6110_FRAME_HEADER, 0x20, 0x01,
153 0x01, 0x00, 0x00, 0x01, 0x01};
154 unsigned char reqOff[] = {N6110_FRAME_HEADER, 0x20, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00};
156
157 if (s->Phone.Data.EnableIncomingCB!=enable) {
158 s->Phone.Data.EnableIncomingCB = enable;
159 if (enable) {
160 smprintf(s, "Enabling incoming CB\n");
161 return GSM_WaitFor(s, reqOn, 10, 0x02, 4, ID_SetIncomingCB);
162 } else {
163 smprintf(s, "Disabling incoming CB\n");
164 return GSM_WaitFor(s, reqOff, 10, 0x02, 4, ID_SetIncomingCB);
165 }
166 }
167 return ERR_NONE;
168#else
169 return ERR_SOURCENOTAVAILABLE;
170#endif
171}
172
173GSM_Error DCT3_ReplySetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s)
174{
175 smprintf(s, "SMSC set\n");
176 return ERR_NONE;
177}
178
179GSM_Error DCT3_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
180{
181 unsigned char req[100] = {N6110_FRAME_HEADER, 0x30, 0x64};
182
183 memset(req+6,100-6,0);
184
185 /* SMSC location */
186 req[5] = smsc->Location;
187
188 /* SMSC format */
189 switch (smsc->Format) {
190 case SMS_FORMAT_Text : req[7] = 0x00; break;
191 case SMS_FORMAT_Fax : req[7] = 0x22; break;
192 case SMS_FORMAT_Pager : req[7] = 0x26; break;
193 case SMS_FORMAT_Email : req[7] = 0x32; break;
194 }
195
196 /* SMS validity */
197 req[9] = smsc->Validity.Relative;
198
199 /* Default number for SMS messages */
200 req[10] = GSM_PackSemiOctetNumber(smsc->DefaultNumber, req+11, true);
201
202 /* SMSC number */
203 req[22] = GSM_PackSemiOctetNumber(smsc->Number, req+23, false);
204
205 /* SMSC name */
206 memcpy(req + 34, DecodeUnicodeString(smsc->Name),UnicodeLength(smsc->Name));
207
208 smprintf(s, "Setting SMSC\n");
209 return GSM_WaitFor (s, req, 35+UnicodeLength(smsc->Name), 0x02, 4, ID_SetSMSC);
210}
211
212GSM_Error DCT3_ReplyEnableSecurity(GSM_Protocol_Message msg, GSM_StateMachine *s)
213{
214 smprintf(s, "State of security commands set\n");
215 return ERR_NONE;
216}
217
218/* If you set make some things (for example, change Security Code from
219 * phone's menu, disable and enable phone), it won't answer for 0x40 frames
220 * and you won't be able to play tones, get netmonitor, etc.
221 * This function do thing called "Enabling extended security commands"
222 * and it enables 0x40 frame functions.
223 * This frame can also some other things - see below
224 */
225GSM_Error DCT3_EnableSecurity (GSM_StateMachine *s, unsigned char status)
226{
227 unsigned char req[] = {0x00, 0x01, 0x64,
228 0x01};/* 0x00/0x01 - off/on,
229 * 0x03/0x04 - soft/hard reset,
230 * 0x06 - CONTACT SERVICE
231 */
232
233 /* 0x06 MAKES CONTACT SERVICE! BE CAREFULL! */
234 /* When use 0x03 and had during session changed time & date
235 * some phones (like 6150 or 6210) can ask for time & date after reset
236 * or disable clock on the screen
237 */
238 if (status!=0x06) req[3] = status;
239 smprintf(s, "Setting state of security commands\n");
240 return GSM_WaitFor (s, req, 4, 0x40, 4, ID_EnableSecurity);
241}
242
243GSM_Error DCT3_ReplyGetIMEI(GSM_Protocol_Message msg, GSM_StateMachine *s)
244{
245 memcpy(s->Phone.Data.IMEI,msg.Buffer + 4, 16);
246 smprintf(s, "Received IMEI %s\n",s->Phone.Data.IMEI);
247 return ERR_NONE;
248}
249
250GSM_Error DCT3_GetIMEI (GSM_StateMachine *s)
251{
252 unsigned char req[] = {0x00, 0x01, 0x66, 0x00};
253 GSM_Error error;
254
255 if (strlen(s->Phone.Data.IMEI)!=0) return ERR_NONE;
256
257 error=DCT3_EnableSecurity (s, 0x01);
258 if (error!=ERR_NONE) return error;
259
260 smprintf(s, "Getting IMEI\n");
261 return GSM_WaitFor (s, req, 4, 0x40, 2, ID_GetIMEI);
262}
263
264GSM_Error DCT3_ReplySIMLogin(GSM_Protocol_Message msg, GSM_StateMachine *s)
265{
266 smprintf(s, "Login for SIM card\n");
267 return ERR_NONE;
268}
269
270GSM_Error DCT3_ReplySIMLogout(GSM_Protocol_Message msg, GSM_StateMachine *s)
271{
272 smprintf(s, "Logout for SIM card\n");
273 return ERR_NONE;
274}
275
276GSM_Error DCT3_ReplyGetDateTime(GSM_Protocol_Message msg, GSM_StateMachine *s)
277{
278 smprintf(s, "Date & time received\n");
279 if (msg.Buffer[4]==0x01) {
280 NOKIA_DecodeDateTime(s, msg.Buffer+8, s->Phone.Data.DateTime);
281 return ERR_NONE;
282 }
283 smprintf(s, "Not set in phone\n");
284 return ERR_EMPTY;
285}
286
287GSM_Error DCT3_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time, unsigned char msgtype)
288{
289 unsigned char req[] = {N6110_FRAME_HEADER, 0x62};
290
291 s->Phone.Data.DateTime=date_time;
292 smprintf(s, "Getting date & time\n");
293 return GSM_WaitFor (s, req, 4, msgtype, 4, ID_GetDateTime);
294}
295
296GSM_Error DCT3_ReplyGetAlarm(GSM_Protocol_Message msg, GSM_StateMachine *s)
297{
298 GSM_Phone_Data*Data = &s->Phone.Data;
299
300 smprintf(s, "Alarm: ");
301 if (msg.Buffer[8]==0x02) {
302 smprintf(s, "set to %02i:%02i\n", msg.Buffer[9], msg.Buffer[10]);
303 Data->Alarm->Repeating = true;
304 Data->Alarm->Text[0] = 0;
305 Data->Alarm->Text[1] = 0;
306 Data->Alarm->DateTime.Hour= msg.Buffer[9];
307 Data->Alarm->DateTime.Minute= msg.Buffer[10];
308 Data->Alarm->DateTime.Second= 0;
309 return ERR_NONE;
310 }
311 smprintf(s, "not set\n");
312 return ERR_EMPTY;
313}
314
315GSM_Error DCT3_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm, unsigned char msgtype)
316{
317 unsigned char req[] = {N6110_FRAME_HEADER, 0x6d};
318
319 if (alarm->Location!=1) return ERR_NOTSUPPORTED;
320
321 s->Phone.Data.Alarm=alarm;
322 smprintf(s, "Getting alarm\n");
323 return GSM_WaitFor (s, req, 4, msgtype, 4, ID_GetAlarm);
324}
325
326GSM_Error DCT3_ReplySetDateTime(GSM_Protocol_Message msg, GSM_StateMachine *s)
327{
328 smprintf(s, "Date & time: ");
329 if (msg.Buffer[4]==0x01) {
330 smprintf(s, "set OK\n");
331 return ERR_NONE;
332 }
333 smprintf(s, "error setting\n");
334 return ERR_UNKNOWN;
335}
336
337GSM_Error DCT3_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time, unsigned char msgtype)
338{
339 unsigned char req[] = {N6110_FRAME_HEADER, 0x60, 0x01, 0x01, 0x07,
340 0x00, 0x00, /* Year */
341 0x00, /* Month */
342 0x00, /* Day */
343 0x00, /* Hour */
344 0x00, /* Minute */
345 0x00}; /* Unknown. Not seconds */
346
347 NOKIA_EncodeDateTime(s, req+7, date_time);
348 smprintf(s, "Setting date & time\n");
349 return GSM_WaitFor (s, req, 14, msgtype, 4, ID_SetDateTime);
350}
351
352GSM_Error DCT3_ReplySetAlarm(GSM_Protocol_Message msg, GSM_StateMachine *s)
353{
354 smprintf(s, "Alarm: ");
355 if (msg.Buffer[4]==0x01) {
356 smprintf(s, "set OK\n");
357 return ERR_NONE;
358 }
359 smprintf(s, "error setting\n");
360 return ERR_UNKNOWN;
361}
362
363GSM_Error DCT3_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm, unsigned char msgtype)
364{
365 unsigned char req[] = {N6110_FRAME_HEADER, 0x6b, 0x01, 0x20, 0x03,
366 0x02, /* Unknown. Not for enabling/disabling */
367 0x00, /* Hour */
368 0x00, /* Minute */
369 0x00}; /* Unknown. Not seconds */
370
371 if (alarm->Location != 1) return ERR_NOTSUPPORTED;
372
373 req[8] = alarm->DateTime.Hour;
374 req[9] = alarm->DateTime.Minute;
375
376 smprintf(s, "Setting alarm\n");
377 return GSM_WaitFor (s, req, 11, msgtype, 4, ID_SetAlarm);
378}
379
380GSM_Error DCT3_ReplyGetSMSC(GSM_Protocol_Message msg, GSM_StateMachine *s)
381{
382 int i;
383 GSM_Phone_Data*Data = &s->Phone.Data;
384
385 switch (msg.Buffer[3]) {
386 case 0x34:
387 smprintf(s, "SMSC received\n");
388 Data->SMSC->Format = SMS_FORMAT_Text;
389 switch (msg.Buffer[6]) {
390 case 0x00: Data->SMSC->Format = SMS_FORMAT_Text; break;
391 case 0x22: Data->SMSC->Format = SMS_FORMAT_Fax; break;
392 case 0x26: Data->SMSC->Format = SMS_FORMAT_Pager;break;
393 case 0x32: Data->SMSC->Format = SMS_FORMAT_Email;break;
394 }
395 Data->SMSC->Validity.Format = SMS_Validity_RelativeFormat;
396 Data->SMSC->Validity.Relative= msg.Buffer[8];
397
398 i=33;
399 while (msg.Buffer[i]!=0) {i++;}
400 i=i-33;
401 if (i>GSM_MAX_SMSC_NAME_LENGTH) {
402 smprintf(s, "Too long name\n");
403 return ERR_UNKNOWNRESPONSE;
404 }
405 EncodeUnicode(Data->SMSC->Name,msg.Buffer+33,i);
406 smprintf(s, "Name \"%s\"\n", DecodeUnicodeString(Data->SMSC->Name));
407
408 GSM_UnpackSemiOctetNumber(Data->SMSC->DefaultNumber,msg.Buffer+9,true);
409 smprintf(s, "Default number \"%s\"\n", DecodeUnicodeString(Data->SMSC->DefaultNumber));
410
411 GSM_UnpackSemiOctetNumber(Data->SMSC->Number,msg.Buffer+21,false);
412 smprintf(s, "Number \"%s\"\n", DecodeUnicodeString(Data->SMSC->Number));
413
414 return ERR_NONE;
415 case 0x35:
416 smprintf(s, "Getting SMSC failed\n");
417 return ERR_INVALIDLOCATION;
418 }
419 return ERR_UNKNOWNRESPONSE;
420}
421
422GSM_Error DCT3_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
423{
424 unsigned char req[] = {N6110_FRAME_HEADER, 0x33, 0x64,
425 0x00}; /* Location */
426
427 if (smsc->Location==0x00) return ERR_INVALIDLOCATION;
428
429 req[5]=smsc->Location;
430
431 s->Phone.Data.SMSC=smsc;
432 smprintf(s, "Getting SMSC\n");
433 return GSM_WaitFor (s, req, 6, 0x02, 4, ID_GetSMSC);
434}
435
436GSM_Error DCT3_ReplyGetNetworkInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
437{
438 int count;
439 GSM_Phone_Data*Data = &s->Phone.Data;
440#ifdef DEBUG
441 GSM_NetworkInfo NetInfo;
442 char name[100];
443
444 smprintf(s, "Network info received\n");
445 smprintf(s, " Status : ");
446 switch (msg.Buffer[8]) {
447 case 0x01: smprintf(s, "home network"); break;
448 case 0x02: smprintf(s, "roaming network"); break;
449 case 0x03: smprintf(s, "requesting network"); break;
450 case 0x04: smprintf(s, "not registered in the network");break;
451 default : smprintf(s, "unknown");
452 }
453 smprintf(s, "\n");
454 smprintf(s, "Network selection : %s\n", msg.Buffer[9]==1?"manual":"automatic");
455 if (msg.Buffer[8]<0x03) {
456 sprintf(NetInfo.CID, "%02x%02x", msg.Buffer[10], msg.Buffer[11]);
457 smprintf(s, "CID : %s\n", NetInfo.CID);
458
459 sprintf(NetInfo.LAC, "%02x%02x", msg.Buffer[12], msg.Buffer[13]);
460 smprintf(s, "LAC : %s\n", NetInfo.LAC);
461
462 smprintf(s, "Network code : %s\n", NetInfo.NetworkCode);
463 NOKIA_DecodeNetworkCode(msg.Buffer+14,NetInfo.NetworkCode);
464 smprintf(s, "Network name for Gammu : %s ",
465 DecodeUnicodeString(GSM_GetNetworkName(NetInfo.NetworkCode)));
466 smprintf(s, "(%s)\n",DecodeUnicodeString(GSM_GetCountryName(NetInfo.NetworkCode)));
467
468 if (msg.Length>18) {
469 if (msg.Buffer[18]==0x00) {
470 /* In 6210 name is in "normal" Unicode */
471 memcpy(name,msg.Buffer+18,msg.Buffer[17]*2);
472 name[msg.Buffer[17]*2]=0x00;
473 name[msg.Buffer[17]*2+1]=0x00;
474 smprintf(s, "Network name for phone : %s\n",DecodeUnicodeString(name));
475 } else {
476 /* In 9210 first 0x00 is cut from Unicode string */
477 name[0] = 0;
478 memcpy(name+1,msg.Buffer+18,msg.Buffer[17]*2);
479 name[msg.Buffer[17]*2+1]=0x00;
480 name[msg.Buffer[17]*2+2]=0x00;
481 smprintf(s, "Network name for phone : %s\n",DecodeUnicodeString(name));
482 }
483 }
484 }
485#endif
486 if (Data->RequestID==ID_GetNetworkInfo) {
487 Data->NetworkInfo->NetworkName[0] = 0x00;
488 Data->NetworkInfo->NetworkName[1] = 0x00;
489 Data->NetworkInfo->State = 0;
490 switch (msg.Buffer[8]) {
491 case 0x01: Data->NetworkInfo->State = GSM_HomeNetwork; break;
492 case 0x02: Data->NetworkInfo->State = GSM_RoamingNetwork;break;
493 case 0x03: Data->NetworkInfo->State = GSM_RequestingNetwork;break;
494 case 0x04: Data->NetworkInfo->State = GSM_NoNetwork; break;
495 }
496 if (Data->NetworkInfo->State == GSM_HomeNetwork || Data->NetworkInfo->State == GSM_RoamingNetwork) {
497 if (msg.Buffer[18]==0x00) {
498 /* In 6210 name is in "normal" Unicode */
499 memcpy(Data->NetworkInfo->NetworkName,msg.Buffer+18,msg.Buffer[17]*2);
500 Data->NetworkInfo->NetworkName[msg.Buffer[17]*2] = 0x00;
501 Data->NetworkInfo->NetworkName[msg.Buffer[17]*2+1] = 0x00;
502 } else {
503 /* In 9210 first 0x00 is cut from Unicode string */
504 Data->NetworkInfo->NetworkName[0] = 0;
505 memcpy(Data->NetworkInfo->NetworkName+1,msg.Buffer+18,msg.Buffer[17]*2);
506 Data->NetworkInfo->NetworkName[msg.Buffer[17]*2+1]=0x00;
507 Data->NetworkInfo->NetworkName[msg.Buffer[17]*2+2]=0x00;
508 }
509 NOKIA_DecodeNetworkCode(msg.Buffer+14,Data->NetworkInfo->NetworkCode);
510 sprintf(Data->NetworkInfo->CID, "%02x%02x", msg.Buffer[10], msg.Buffer[11]);
511 sprintf(Data->NetworkInfo->LAC, "%02x%02x", msg.Buffer[12], msg.Buffer[13]);
512 }
513 }
514 /* 6210/6250/7110 */
515 if (Data->RequestID==ID_GetBitmap) {
516 if (msg.Buffer[4]==0x02) {
517 smprintf(s, "Operator logo available\n");
518 count = 7;
519 /* skip network info */
520 count += msg.Buffer[count];
521 count ++;
522 Data->Bitmap->BitmapWidth= msg.Buffer[count++];
523 Data->Bitmap->BitmapHeight= msg.Buffer[count++];
524 count+=4;
525 PHONE_DecodeBitmap(GSM_Nokia7110OperatorLogo,msg.Buffer+count,Data->Bitmap);
526 NOKIA_DecodeNetworkCode(msg.Buffer+14,Data->Bitmap->NetworkCode);
527 } else {
528 Data->Bitmap->BitmapWidth= 78;
529 Data->Bitmap->BitmapHeight= 21;
530 GSM_ClearBitmap(Data->Bitmap);
531 strcpy(Data->Bitmap->NetworkCode,"000 00");
532 }
533 }
534 return ERR_NONE;
535}
536
537GSM_Error DCT3_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo)
538{
539 unsigned char req[] = {N6110_FRAME_HEADER, 0x70};
540
541 s->Phone.Data.NetworkInfo=netinfo;
542 smprintf(s, "Getting network info\n");
543 return GSM_WaitFor (s, req, 4, 0x0a, 4, ID_GetNetworkInfo);
544}
545
546GSM_Error DCT3_ReplyDialCommand(GSM_Protocol_Message msg, GSM_StateMachine *s)
547{
548 smprintf(s, "Answer for call commands\n");
549 return ERR_NONE;
550}
551
552GSM_Error DCT3_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber)
553{
554 unsigned inti = 0;
555 GSM_Errorerror;
556 unsigned char req[100] = {0x00, 0x01, 0x7c,
557 0x01}; /* call command */
558
559 if (ShowNumber != GSM_CALL_DefaultNumberPresence) return ERR_NOTSUPPORTED;
560
561 error=DCT3_EnableSecurity (s, 0x01);
562 if (error!=ERR_NONE) return error;
563
564 for (i=0; i < strlen(number); i++) req[4+i]=number[i];
565 req[4+i+1]=0;
566
567 smprintf(s, "Making voice call\n");
568 return GSM_WaitFor (s, req, 4+strlen(number)+1, 0x40, 4, ID_DialVoice);
569}
570
571static GSM_Error DCT3_CancelAllCalls(GSM_StateMachine *s)
572{
573 GSM_Errorerror;
574 unsigned char req[] = {0x00, 0x01, 0x7c,
575 0x03}; /* call command */
576
577 error=DCT3_EnableSecurity (s, 0x01);
578 if (error!=ERR_NONE) return error;
579
580 smprintf(s, "Canceling calls\n");
581 return GSM_WaitFor (s, req, 4, 0x40, 4, ID_CancelCall);
582}
583
584GSM_Error DCT3_CancelCall(GSM_StateMachine *s, int ID, bool all)
585{
586 if (!all) return DCT3DCT4_CancelCall(s,ID);
587 return DCT3_CancelAllCalls(s);
588}
589
590GSM_Error DCT3_AnswerAllCalls(GSM_StateMachine *s)
591{
592 GSM_Errorerror;
593 unsigned char req[] = {0x00, 0x01, 0x7c,
594 0x02}; /* call command */
595
596 error=DCT3_EnableSecurity (s, 0x01);
597 if (error!=ERR_NONE) return error;
598
599 smprintf(s, "Answering calls\n");
600 return GSM_WaitFor (s, req, 4, 0x40, 4, ID_AnswerCall);
601}
602
603GSM_Error DCT3_Reset(GSM_StateMachine *s, bool hard)
604{
605 GSM_Error error;
606
607 if (hard) {
608 error=DCT3_EnableSecurity(s, 0x04);
609 } else {
610 error=DCT3_EnableSecurity(s, 0x03);
611 }
612 if (error == ERR_NONE) {
613 s->Phone.Data.EnableIncomingSMS = false;
614 s->Phone.Data.EnableIncomingCB = false;
615 }
616 return error;
617}
618
619GSM_Error DCT3_ReplyGetWAPBookmark(GSM_Protocol_Message msg, GSM_StateMachine *s)
620{
621 return DCT3DCT4_ReplyGetWAPBookmark (msg,s,false);
622}
623
624GSM_Error DCT3_SetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
625{
626 GSM_Error error;
627 int count = 4, location;
628 unsigned char req[600] = {N6110_FRAME_HEADER, 0x09};
629
630 /* We have to enable WAP frames in phone */
631 error=DCT3DCT4_EnableWAPFunctions(s);
632 if (error!=ERR_NONE) return error;
633
634 location = bookmark->Location - 1;
635 if (bookmark->Location == 0) location = 0xffff;
636 req[count++] = (location & 0xff00) >> 8;
637 req[count++] = location & 0x00ff;
638
639 count += NOKIA_SetUnicodeString(s, req+count, bookmark->Title, false);
640 count += NOKIA_SetUnicodeString(s, req+count, bookmark->Address, false);
641
642 /* unknown */
643 req[count++] = 0x01; req[count++] = 0x80; req[count++] = 0x00;
644 req[count++] = 0x00; req[count++] = 0x00; req[count++] = 0x00;
645 req[count++] = 0x00; req[count++] = 0x00; req[count++] = 0x00;
646
647 smprintf(s, "Setting WAP bookmark\n");
648 error = GSM_WaitFor (s, req, count, 0x3f, 4, ID_SetWAPBookmark);
649 if (error != ERR_NONE) {
650 if (error == ERR_INSIDEPHONEMENU || error == ERR_EMPTY || error == ERR_FULL) {
651 DCT3DCT4_DisableConnectionFunctions(s);
652 }
653 return error;
654 }
655
656 return DCT3DCT4_DisableConnectionFunctions(s);
657}
658
659GSM_Error DCT3_ReplyGetWAPSettings(GSM_Protocol_Message msg, GSM_StateMachine *s)
660{
661 int tmp,Number;
662 // int tmp2;
663 GSM_Phone_Data *Data = &s->Phone.Data;
664#ifdef GSM_ENABLE_NOKIA6110
665 GSM_Phone_N6110Data *Priv6110 = &s->Phone.Data.Priv.N6110;
666#endif
667#ifdef GSM_ENABLE_NOKIA7110
668 GSM_Phone_N7110Data *Priv7110 = &s->Phone.Data.Priv.N7110;
669#endif
670
671 switch(msg.Buffer[3]) {
672 case 0x16:
673 smprintf(s, "WAP settings part 1 received OK\n");
674
675 tmp = 4;
676
677 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].Title,false);
678 smprintf(s, "Title: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Title));
679
680 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[0].HomePage,false);
681 smprintf(s, "Homepage: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].HomePage));
682#ifdef DEBUG
683 smprintf(s, "Connection type: ");
684 switch (msg.Buffer[tmp]) {
685 case 0x00: smprintf(s, "temporary\n"); break;
686 case 0x01: smprintf(s, "continuous\n"); break;
687 default: smprintf(s, "unknown\n");
688 }
689 smprintf(s, "Connection security: ");
690 switch (msg.Buffer[tmp+13]) {
691 case 0x00: smprintf(s, "off\n");break;
692 case 0x01: smprintf(s, "on\n"); break;
693 default: smprintf(s, "unknown\n");
694 }
695#endif
696 Data->WAPSettings->Settings[0].IsContinuous = false;
697 if (msg.Buffer[tmp] == 0x01) Data->WAPSettings->Settings[0].IsContinuous = true;
698 Data->WAPSettings->Settings[0].IsSecurity = false;
699 if (msg.Buffer[tmp+13] == 0x01) Data->WAPSettings->Settings[0].IsSecurity = true;
700
701 /* I'm not sure here. Experimental values from 6210 5.56 */
702 // tmp2 = DecodeUnicodeLength(Data->WAPSettings->Settings[0].Title);
703 // if (tmp2 != 0) tmp2 --;
704 // tmp2 += tmp;
705 if (!(UnicodeLength(Data->WAPSettings->Settings[0].Title)) % 2) tmp++;
706 if (UnicodeLength(Data->WAPSettings->Settings[0].HomePage)!=0) tmp++;
707
708 smprintf(s, "ID for writing %i\n",msg.Buffer[tmp+5]);
709
710 smprintf(s, "Current set location in phone %i\n",msg.Buffer[tmp+6]);
711
712 smprintf(s, "1 location %i\n",msg.Buffer[tmp+8]);
713 smprintf(s, "2 location %i\n",msg.Buffer[tmp+9]);
714 smprintf(s, "3 location %i\n",msg.Buffer[tmp+10]);
715 smprintf(s, "4 location %i\n",msg.Buffer[tmp+11]);
716#ifdef GSM_ENABLE_NOKIA7110
717 if (strstr(N7110Phone.models, Data->ModelInfo->model) != NULL) {
718 Priv7110->WAPLocations.ID = msg.Buffer[tmp+5];
719 Priv7110->WAPLocations.CurrentLocation= msg.Buffer[tmp+6];
720 Priv7110->WAPLocations.Locations[0] = msg.Buffer[tmp+8];
721 Priv7110->WAPLocations.Locations[1] = msg.Buffer[tmp+9];
722 Priv7110->WAPLocations.Locations[2] = msg.Buffer[tmp+10];
723 Priv7110->WAPLocations.Locations[3] = msg.Buffer[tmp+11];
724
725 // Priv7110->WAPLocations.CurrentLocation= msg.Buffer[tmp2+1];
726 // Priv7110->WAPLocations.Locations[0] = msg.Buffer[tmp2+3];
727 // Priv7110->WAPLocations.Locations[1] = msg.Buffer[tmp2+4];
728 // Priv7110->WAPLocations.Locations[2] = msg.Buffer[tmp2+5];
729 // Priv7110->WAPLocations.Locations[3] = msg.Buffer[tmp2+6];
730 }
731#endif
732#ifdef GSM_ENABLE_NOKIA6110
733 if (strstr(N6110Phone.models, Data->ModelInfo->model) != NULL) {
734 Priv6110->WAPLocations.ID = msg.Buffer[tmp+5];
735 Priv6110->WAPLocations.CurrentLocation= msg.Buffer[tmp+6];
736 Priv6110->WAPLocations.Locations[0] = msg.Buffer[tmp+8];
737 Priv6110->WAPLocations.Locations[1] = msg.Buffer[tmp+9];
738 Priv6110->WAPLocations.Locations[2] = msg.Buffer[tmp+10];
739 Priv6110->WAPLocations.Locations[3] = msg.Buffer[tmp+11];
740 }
741#endif
742 return ERR_NONE;
743 case 0x17:
744 smprintf(s, "WAP settings part 1 receiving error\n");
745 switch (msg.Buffer[4]) {
746 case 0x01:
747 smprintf(s, "Security error. Inside WAP settings menu\n");
748 return ERR_INSIDEPHONEMENU;
749 case 0x02:
750 smprintf(s, "Invalid or empty\n");
751 return ERR_INVALIDLOCATION;
752 default:
753 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
754 return ERR_UNKNOWNRESPONSE;
755 }
756 break;
757 case 0x1c:
758 smprintf(s, "WAP settings part 2 received OK\n");
759 Number = Data->WAPSettings->Number;
760 switch (msg.Buffer[5]) {
761 case 0x00:
762 Data->WAPSettings->Settings[Number].Bearer = WAPSETTINGS_BEARER_SMS;
763 smprintf(s, "Settings for SMS bearer:\n");
764 tmp = 6;
765
766 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].Service,false);
767 smprintf(s, "Service number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Service));
768
769 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].Server,false);
770 smprintf(s, "Server number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Server));
771 break;
772 case 0x01:
773 Data->WAPSettings->Settings[Number].Bearer = WAPSETTINGS_BEARER_DATA;
774 smprintf(s, "Settings for data bearer:\n");
775 Data->WAPSettings->Settings[Number].ManualLogin = false;
776 tmp = 10;
777
778 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].IPAddress,false);
779 smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].IPAddress));
780
781 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].DialUp,false);
782 smprintf(s, "Dial-up number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].DialUp));
783
784 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].User,false);
785 smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].User));
786
787 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].Password,false);
788 smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Password));
789#ifdef DEBUG
790 smprintf(s, "Authentication type: ");
791 switch (msg.Buffer[6]) {
792 case 0x00: smprintf(s, "normal\n"); break;
793 case 0x01: smprintf(s, "secure\n"); break;
794 default: smprintf(s, "unknown\n"); break;
795 }
796 smprintf(s, "Data call type: ");
797 switch (msg.Buffer[7]) {
798 case 0x00: smprintf(s, "analogue\n"); break;
799 case 0x01: smprintf(s, "ISDN\n"); break;
800 default: smprintf(s, "unknown\n"); break;
801 }
802 smprintf(s, "Data call speed: ");
803 switch (msg.Buffer[9]) {
804 case 0x01: smprintf(s, "9600\n"); break;
805 case 0x02: smprintf(s, "14400\n"); break;
806 default: smprintf(s, "unknown\n"); break;
807 }
808#endif
809 Data->WAPSettings->Settings[Number].IsNormalAuthentication=true;
810 if (msg.Buffer[6]==0x01) Data->WAPSettings->Settings[Number].IsNormalAuthentication=false;
811 Data->WAPSettings->Settings[Number].IsISDNCall=false;
812 if (msg.Buffer[7]==0x01) Data->WAPSettings->Settings[Number].IsISDNCall=true;
813 Data->WAPSettings->Settings[Number].Speed = WAPSETTINGS_SPEED_9600;
814 if (msg.Buffer[9]==0x02) Data->WAPSettings->Settings[Number].Speed = WAPSETTINGS_SPEED_14400;
815 break;
816 case 0x02:
817 Data->WAPSettings->Settings[Number].Bearer=WAPSETTINGS_BEARER_USSD;
818 smprintf(s, "Settings for USSD bearer:\n");
819 tmp = 7;
820 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].Service,false);
821#ifdef DEBUG
822 if (msg.Buffer[6]==0x01)
823 smprintf(s, "Service number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Service));
824 else
825 smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Service));
826#endif
827 Data->WAPSettings->Settings[Number].IsIP=true;
828 if (msg.Buffer[6]==0x01) Data->WAPSettings->Settings[Number].IsIP=false;
829 NOKIA_GetUnicodeString(s, &tmp, msg.Buffer, Data->WAPSettings->Settings[Number].Code,false);
830 smprintf(s, "Service code: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[Number].Code));
831 }
832 Data->WAPSettings->Number++;
833 return ERR_NONE;
834 case 0x1d:
835 smprintf(s, "Incorrect WAP settings location\n");
836 return ERR_NONE;
837 }
838 return ERR_UNKNOWNRESPONSE;
839}
840
841GSM_Error DCT3_GetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
842{
843#ifdef GSM_ENABLE_NOKIA6110
844 GSM_Phone_N6110Data *Priv6110 = &s->Phone.Data.Priv.N6110;
845#endif
846#ifdef GSM_ENABLE_NOKIA7110
847 GSM_Phone_N7110Data *Priv7110 = &s->Phone.Data.Priv.N7110;
848#endif
849 GSM_Error error;
850 int i;
851 unsigned char req[] = {N6110_FRAME_HEADER,0x15,
852 0x00}; /* Location */
853 unsigned char req2[] = {N6110_FRAME_HEADER,0x1b,
854 0x00}; /* Location */
855
856 /* We have to enable WAP frames in phone */
857 error=DCT3DCT4_EnableWAPFunctions(s);
858 if (error!=ERR_NONE) return error;
859
860 s->Phone.Data.WAPSettings = settings;
861 settings->Number = 0;
862 settings->ReadOnly = false;
863
864 req[4] = settings->Location-1;
865 smprintf(s, "Getting WAP settings part 1\n");
866 error = GSM_WaitFor (s, req, 5, 0x3f, 4, ID_GetConnectSet);
867 if (error != ERR_NONE) return error;
868
869#ifdef GSM_ENABLE_NOKIA7110
870 if (strstr(N7110Phone.models, s->Phone.Data.ModelInfo->model) != NULL) {
871 for (i=0;i<4;i++) {
872 req2[4] = Priv7110->WAPLocations.Locations[i];
873 smprintf(s, "Getting WAP settings part 2\n");
874 error=GSM_WaitFor (s, req2, 5, 0x3f, 4, ID_GetConnectSet);
875 if (error != ERR_NONE) return error;
876 if (Priv7110->WAPLocations.Locations[i] == Priv7110->WAPLocations.CurrentLocation) {
877 settings->ActiveBearer = settings->Settings[settings->Number-1].Bearer;
878 }
879 }
880 }
881#endif
882#ifdef GSM_ENABLE_NOKIA6110
883 if (strstr(N6110Phone.models, s->Phone.Data.ModelInfo->model) != NULL) {
884 for (i=0;i<4;i++) {
885 req2[4] = Priv6110->WAPLocations.Locations[i];
886 smprintf(s, "Getting WAP settings part 2\n");
887 error=GSM_WaitFor (s, req2, 5, 0x3f, 4, ID_GetConnectSet);
888 if (error != ERR_NONE) return error;
889 if (Priv6110->WAPLocations.Locations[i] == Priv6110->WAPLocations.CurrentLocation) {
890 settings->ActiveBearer = settings->Settings[settings->Number-1].Bearer;
891 }
892 }
893 }
894#endif
895 if (error == ERR_NONE) {
896 for (i=1;i<3;i++) {
897 CopyUnicodeString(settings->Settings[i].Title,settings->Settings[0].Title);
898 CopyUnicodeString(settings->Settings[i].HomePage,settings->Settings[0].HomePage);
899 settings->Settings[i].IsContinuous = settings->Settings[0].IsContinuous;
900 settings->Settings[i].IsSecurity = settings->Settings[0].IsSecurity;
901
902 settings->Settings[i].IsContinuous = settings->Settings[0].IsContinuous;
903 settings->Settings[i].IsSecurity = settings->Settings[0].IsSecurity;
904 }
905 error = DCT3DCT4_GetActiveConnectSet(s);
906 }
907 if (error != ERR_NONE) return error;
908
909 settings->Proxy[0] = 0x00;
910 settings->Proxy[1] = 0x00;
911 settings->ProxyPort = 8080;
912
913 settings->Proxy2[0] = 0x00;
914 settings->Proxy2[1] = 0x00;
915 settings->Proxy2Port = 8080;
916
917 return DCT3DCT4_DisableConnectionFunctions(s);
918}
919
920GSM_Error DCT3_ReplySetWAPSettings(GSM_Protocol_Message msg, GSM_StateMachine *s)
921{
922 switch(msg.Buffer[3]) {
923 case 0x19:
924 smprintf(s, "WAP settings part 1 set OK\n");
925 return ERR_NONE;
926 case 0x1a:
927 smprintf(s, "WAP settings part 1 setting error\n");
928 switch (msg.Buffer[4]) {
929 case 0x01:
930 smprintf(s, "Security error. Inside WAP settings menu\n");
931 return ERR_INSIDEPHONEMENU;
932 case 0x02:
933 smprintf(s, "Incorrect data\n");
934 return ERR_UNKNOWN;
935 default:
936 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
937 return ERR_UNKNOWNRESPONSE;
938 }
939 case 0x1F:
940 smprintf(s, "WAP settings part 2 set OK\n");
941 return ERR_NONE;
942 }
943 return ERR_UNKNOWNRESPONSE;
944}
945
946GSM_Error DCT3_SetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
947{
948#ifdef GSM_ENABLE_NOKIA6110
949 GSM_Phone_N6110Data *Priv6110 = &s->Phone.Data.Priv.N6110;
950#endif
951#ifdef GSM_ENABLE_NOKIA7110
952 GSM_Phone_N7110Data *Priv7110 = &s->Phone.Data.Priv.N7110;
953#endif
954 GSM_Error error;
955 GSM_MultiWAPSettingssettings2;
956 int i,pos,phone1=-1,phone2=-1,phone3=-1;
957 int ID=0,locations[4],loc1=-1,loc2=-1,loc3=-1;
958 unsigned char req[] = {N6110_FRAME_HEADER,0x15,
959 0x00};/* Location */
960 unsigned char req2[] = {N6110_FRAME_HEADER,0x1b,
961 0x00};/* Location */
962 unsigned char SetReq[200] = {N7110_FRAME_HEADER, 0x18,
963 0x00}; /* Location */
964 unsigned char SetReq2[200] = {N7110_FRAME_HEADER, 0x1e,
965 0x00}; /* Location */
966
967 /* We have to enable WAP frames in phone */
968 error=DCT3DCT4_EnableWAPFunctions(s);
969 if (error!=ERR_NONE) return error;
970
971 s->Phone.Data.WAPSettings = &settings2;
972 settings2.Number = 0;
973
974 req[4] = settings->Location-1;
975 smprintf(s, "Getting WAP settings part 1\n");
976 error = GSM_WaitFor (s, req, 6, 0x3f, 4, ID_GetConnectSet);
977 if (error != ERR_NONE) return error;
978
979#ifdef GSM_ENABLE_NOKIA6110
980 if (strstr(N6110Phone.models, s->Phone.Data.ModelInfo->model) != NULL) {
981 for (i=0;i<4;i++) locations[i] = Priv6110->WAPLocations.Locations[i];
982 ID = Priv6110->WAPLocations.ID;
983 }
984#endif
985#ifdef GSM_ENABLE_NOKIA7110
986 if (strstr(N7110Phone.models, s->Phone.Data.ModelInfo->model) != NULL) {
987 for (i=0;i<4;i++) locations[i] = Priv7110->WAPLocations.Locations[i];
988 ID = Priv7110->WAPLocations.ID;
989 }
990#endif
991
992 /* Now we get info about supported types by phone and their locations */
993 for (i=0;i<4;i++) {
994 settings2.Number = 0;
995 settings2.Settings[0].Bearer = 0;
996 req2[4] = locations[i];
997 smprintf(s, "Getting WAP settings part 2\n");
998 error=GSM_WaitFor (s, req2, 6, 0x3f, 4, ID_GetConnectSet);
999 if (error != ERR_NONE) return error;
1000 switch (settings2.Settings[0].Bearer) {
1001 case WAPSETTINGS_BEARER_DATA: phone1 = locations[i]; break;
1002 case WAPSETTINGS_BEARER_SMS : phone2 = locations[i]; break;
1003 case WAPSETTINGS_BEARER_USSD: phone3 = locations[i]; break;
1004 default : break;
1005 }
1006 if (error != ERR_NONE) return error;
1007 }
1008
1009 /* We have some phone locations and some data to set. We try to
1010 * find info about locations in phone used to write concrete bearers
1011 */
1012 for (i=0;i<settings->Number;i++) {
1013 if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_DATA) {
1014 if (phone1 != -1) loc1=i;
1015 }
1016 if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_SMS) {
1017 if (phone2 != -1) loc2=i;
1018 }
1019 if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_USSD) {
1020 if (phone3 != -1) loc3=i;
1021 }
1022 }
1023
1024 pos = 5;
1025 memset(SetReq + pos, 0, 200 - pos);
1026 SetReq[4] = settings->Location - 1;
1027 if (loc1 != -1) {
1028 /* Name */
1029 pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc1].Title, false);
1030 /* HomePage */
1031 pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc1].HomePage, false);
1032 if (settings->Settings[loc1].IsContinuous) SetReq[pos] = 0x01;
1033 pos++;
1034 SetReq[pos++] = ID;
1035
1036 SetReq[pos] = phone1; /* bearer */
1037 switch (settings->ActiveBearer) {
1038 case WAPSETTINGS_BEARER_DATA:
1039 if (loc1 != -1) SetReq[pos] = phone1;
1040 break;
1041 case WAPSETTINGS_BEARER_SMS:
1042 if (loc2 != -1) SetReq[pos] = phone2;
1043 break;
1044 case WAPSETTINGS_BEARER_USSD:
1045 if (loc3 != -1) SetReq[pos] = phone3;
1046 break;
1047 default: break;
1048 }
1049 pos++;
1050
1051 if (settings->Settings[loc1].IsSecurity) SetReq[pos] = 0x01;
1052 pos++;
1053 } else if (loc2 != -1) {
1054 /* Name */
1055 pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc2].Title, false);
1056 /* HomePage */
1057 pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc2].HomePage, false);
1058 if (settings->Settings[loc2].IsContinuous) SetReq[pos] = 0x01;
1059 pos++;
1060 SetReq[pos++] = ID;
1061
1062 SetReq[pos] = phone2; /* bearer */
1063 switch (settings->ActiveBearer) {
1064 case WAPSETTINGS_BEARER_DATA:
1065 if (loc1 != -1) SetReq[pos] = phone1;
1066 break;
1067 case WAPSETTINGS_BEARER_SMS:
1068 if (loc2 != -1) SetReq[pos] = phone2;
1069 break;
1070 case WAPSETTINGS_BEARER_USSD:
1071 if (loc3 != -1) SetReq[pos] = phone3;
1072 break;
1073 default: break;
1074 }
1075 pos++;
1076
1077 if (settings->Settings[loc2].IsSecurity) SetReq[pos] = 0x01;
1078 pos++;
1079 } else if (loc3 != -1) {
1080 /* Name */
1081 pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc3].Title, false);
1082 /* HomePage */
1083 pos += NOKIA_SetUnicodeString(s, SetReq + pos, settings->Settings[loc3].HomePage, false);
1084 if (settings->Settings[loc3].IsContinuous) SetReq[pos] = 0x01;
1085 pos++;
1086 SetReq[pos++] = ID;
1087
1088 SetReq[pos] = phone3; /* bearer */
1089 switch (settings->ActiveBearer) {
1090 case WAPSETTINGS_BEARER_DATA:
1091 if (loc1 != -1) SetReq[pos] = phone1;
1092 break;
1093 case WAPSETTINGS_BEARER_SMS:
1094 if (loc2 != -1) SetReq[pos] = phone2;
1095 break;
1096 case WAPSETTINGS_BEARER_USSD:
1097 if (loc3 != -1) SetReq[pos] = phone3;
1098 break;
1099 default: break;
1100 }
1101 pos++;
1102
1103 if (settings->Settings[loc3].IsSecurity) SetReq[pos] = 0x01;
1104 pos++;
1105 } else {
1106 return ERR_UNKNOWN;/* We have to have write something known */
1107 }
1108 memcpy(SetReq + pos, "\x01\x80\x00\x00\x00\x00\x00\x00\x00", 9);
1109 pos += 9;
1110
1111 smprintf(s, "Writing WAP settings part 1\n");
1112 error=GSM_WaitFor (s, SetReq, pos, 0x3f, 4, ID_SetConnectSet);
1113 if (error != ERR_NONE) return error;
1114
1115 /* Data */
1116 if (phone1 != -1) {
1117 pos = 4;
1118 memset(SetReq2 + pos, 0, 200 - pos);
1119 SetReq2[pos++] = phone1;
1120 SetReq2[pos++] = 0x02;
1121 SetReq2[pos++] = 0x01; /* GSMdata */
1122 if (loc1 != -1) {
1123 if (!settings->Settings[loc1].IsNormalAuthentication) SetReq2[pos] = 0x01;
1124 }
1125 pos++;
1126 if (loc1 != -1) {
1127 if (settings->Settings[loc1].IsISDNCall) SetReq2[pos] = 0x01;
1128 }
1129 pos++;
1130 if (loc1 != -1) {
1131 switch (settings->Settings[loc1].Speed) {
1132 case WAPSETTINGS_SPEED_9600 : SetReq2[pos++] = 0x01; break;
1133 case WAPSETTINGS_SPEED_14400 : SetReq2[pos++] = 0x02; break;
1134 default : SetReq2[pos++] = 0x02; break;
1135 }
1136 switch (settings->Settings[loc1].Speed) {
1137 case WAPSETTINGS_SPEED_9600 : SetReq2[pos++] = 0x01; break;
1138 case WAPSETTINGS_SPEED_14400 : SetReq2[pos++] = 0x02; break;
1139 default : SetReq2[pos++] = 0x02; break;
1140 }
1141 } else pos+=2;
1142 if (loc1 != -1) {
1143 /* IP */
1144 pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc1].IPAddress, false);
1145 /* Number */
1146 pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc1].DialUp, false);
1147 /* Username */
1148 pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc1].User, false);
1149 /* Password */
1150 pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc1].Password, false);
1151 } else pos+=5;
1152 memcpy(SetReq2 + pos, "\x80\x00\x00\x00\x00\x00\x00\x00", 8);
1153 pos += 8;
1154 smprintf(s, "Writing WAP settings part 2 (Data bearer)\n");
1155 error=GSM_WaitFor (s, SetReq2, pos, 0x3f, 4, ID_SetConnectSet);
1156 if (error != ERR_NONE) return error;
1157 }
1158 /* SMS */
1159 if (phone2 != -1) {
1160 pos = 4;
1161 memset(SetReq2 + pos, 0, 200 - pos);
1162 SetReq2[pos++] = phone2;
1163 SetReq2[pos++] = 0x02;
1164 SetReq2[pos++] = 0x00; /* SMS */
1165 if (loc2 != -1) {
1166 /* Service number */
1167 pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc2].Service, false);
1168 /* Server number */
1169 pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc2].Server, false);
1170 } else pos += 2;
1171 memcpy(SetReq2 + pos, "\x80\x00\x00\x00\x00\x00\x00\x00", 8);
1172 pos += 8;
1173 smprintf(s, "Writing WAP settings part 2 (SMS bearer)\n");
1174 error=GSM_WaitFor (s, SetReq2, pos, 0x3f, 4, ID_SetConnectSet);
1175 if (error != ERR_NONE) return error;
1176 }
1177 /* USSD */
1178 if (phone3 != -1) {
1179 pos = 4;
1180 memset(SetReq2 + pos, 0, 200 - pos);
1181 SetReq2[pos++] = phone3;
1182 SetReq2[pos++] = 0x02;
1183 SetReq2[pos++] = 0x02; /* USSD */
1184 if (loc3 != -1) {
1185 if (!settings->Settings[loc3].IsIP) SetReq2[pos] = 0x01;
1186 }
1187 pos++;
1188 if (loc3 != -1) {
1189 /* Service number or IP address */
1190 pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc3].Service, false);
1191 /* Code number */
1192 pos += NOKIA_SetUnicodeString(s, SetReq2 + pos, settings->Settings[loc3].Code, false);
1193 } else pos+=2;
1194 memcpy(SetReq2 + pos, "\x80\x00\x00\x00\x00\x00\x00\x00", 8);
1195 pos += 8;
1196 smprintf(s, "Writing WAP settings part 2 (USSD bearer)\n");
1197 error=GSM_WaitFor (s, SetReq2, pos, 0x3f, 4, ID_SetConnectSet);
1198 if (error != ERR_NONE) return error;
1199 }
1200 error = DCT3DCT4_SetActiveConnectSet(s, settings);
1201 if (error != ERR_NONE) return error;
1202
1203 return DCT3DCT4_DisableConnectionFunctions(s);
1204}
1205
1206GSM_Error DCT3_ReplySendSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
1207{
1208 switch (msg.Buffer[3]) {
1209 case 0x02:
1210 smprintf(s, "SMS sent OK\n");
1211 if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,0,0);
1212 return ERR_NONE;
1213 case 0x03:
1214 smprintf(s, "Error %i\n",msg.Buffer[6]);
1215 if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s->CurrentConfig->Device,msg.Buffer[6],0);
1216 return ERR_NONE;
1217 }
1218 return ERR_UNKNOWNRESPONSE;
1219}
1220
1221GSM_Error DCT3_SendSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
1222{
1223 int length;
1224 GSM_Error error;
1225 unsigned char req[256] = {N6110_FRAME_HEADER, 0x01, 0x02, 0x00};
1226
1227 error=PHONE_EncodeSMSFrame(s,sms,req+6,PHONE_SMSSubmit,&length, true);
1228 if (error != ERR_NONE) return error;
1229
1230 smprintf(s, "Sending sms\n");
1231 return s->Protocol.Functions->WriteMessage(s, req, 6+length, 0x02);
1232}
1233
1234GSM_Error DCT3_ReplyNetmonitor(GSM_Protocol_Message msg, GSM_StateMachine *s)
1235{
1236 switch (msg.Buffer[3]) {
1237 case 0x00:
1238 smprintf(s, "Netmonitor correctly set\n");
1239 break;
1240 default:
1241 smprintf(s, "Menu %i\n",msg.Buffer[3]);
1242 smprintf(s, "%s\n",msg.Buffer+4);
1243 strcpy(s->Phone.Data.Netmonitor,msg.Buffer+4);
1244 break;
1245 }
1246 return ERR_NONE;
1247}
1248
1249GSM_Error DCT3_Netmonitor(GSM_StateMachine *s, int testnumber, char *value)
1250{
1251 GSM_Error error;
1252 unsigned char req[] = {0x00, 0x01, 0x7e,
1253 0x00}; /* Test number */
1254
1255 value[0] = 0;
1256
1257 error=DCT3_EnableSecurity (s, 0x01);
1258 if (error != ERR_NONE) return error;
1259
1260 req[3] = testnumber;
1261
1262 smprintf(s, "Getting netmonitor test\n");
1263 s->Phone.Data.Netmonitor = value;
1264 return GSM_WaitFor (s, req, 4, 0x40, 4, ID_Netmonitor);
1265}
1266
1267GSM_Error DCT3_GetManufactureMonth(GSM_StateMachine *s, char *value)
1268{
1269 GSM_Error error;
1270
1271 error=DCT3_EnableSecurity (s, 0x01);
1272 if (error != ERR_NONE) return error;
1273 return NOKIA_GetPhoneString(s,"\x00\x01\xCC\x02",4,0x40,value,ID_GetManufactureMonth,5);
1274}
1275
1276GSM_Error DCT3_GetProductCode(GSM_StateMachine *s, char *value)
1277{
1278 GSM_Error error;
1279
1280 if (strlen(s->Phone.Data.ProductCodeCache)!=0) {
1281 strcpy(value,s->Phone.Data.ProductCodeCache);
1282 return ERR_NONE;
1283 }
1284
1285 error=DCT3_EnableSecurity (s, 0x01);
1286 if (error != ERR_NONE) return error;
1287 return NOKIA_GetPhoneString(s,"\x00\x01\xCA\x01",4,0x40,value,ID_GetProductCode,5);
1288}
1289
1290GSM_Error DCT3_GetOriginalIMEI(GSM_StateMachine *s, char *value)
1291{
1292 GSM_Error error;
1293
1294 error=DCT3_EnableSecurity (s, 0x01);
1295 if (error != ERR_NONE) return error;
1296 return NOKIA_GetPhoneString(s,"\x00\x01\xCC\x01",4,0x40,value,ID_GetOriginalIMEI,5);
1297}
1298
1299GSM_Error DCT3_GetHardware(GSM_StateMachine *s, char *value)
1300{
1301 GSM_Error error;
1302
1303 if (strlen(s->Phone.Data.HardwareCache)!=0) {
1304 strcpy(value,s->Phone.Data.HardwareCache);
1305 return ERR_NONE;
1306 }
1307
1308 error=DCT3_EnableSecurity (s, 0x01);
1309 if (error != ERR_NONE) return error;
1310 return NOKIA_GetPhoneString(s,"\x00\x01\xC8\x05",4,0x40,value,ID_GetHardware,5);
1311}
1312
1313GSM_Error DCT3_GetPPM(GSM_StateMachine *s, char *value)
1314{
1315 GSM_Error error;
1316
1317 error=DCT3_EnableSecurity (s, 0x01);
1318 if (error != ERR_NONE) return error;
1319 return NOKIA_GetPhoneString(s,"\x00\x01\xC8\x12",4,0x40,value,ID_GetPPM,5);
1320}
1321
1322GSM_Error DCT3_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status)
1323{
1324 unsigned char req[] = {N6110_FRAME_HEADER, 0x36, 0x64};
1325
1326 s->Phone.Data.SMSStatus=status;
1327 smprintf(s, "Getting SMS status\n");
1328 return GSM_WaitFor (s, req, 5, 0x14, 2, ID_GetSMSStatus);
1329
1330 /* 6210 family doesn't show in frame with SMS status info
1331 * about Templates. We get separately info about this SMS folder.
1332 */
1333}
1334
1335GSM_Error DCT3_ReplyDeleteSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
1336{
1337 switch(msg.Buffer[3]) {
1338 case 0x0b:
1339 smprintf(s, "SMS deleted\n");
1340 return ERR_NONE;
1341 case 0x0c:
1342 smprintf(s, "Error deleting SMS\n");
1343 switch (msg.Buffer[4]) {
1344 case 0x00:
1345 /* Not tested on 6210 */
1346 smprintf(s, "Unknown meaning, SMS seems to be deleted\n");
1347 return ERR_NONE;
1348 case 0x02:
1349 /* Not tested on 6210 */
1350 smprintf(s, "Invalid location\n");
1351 return ERR_INVALIDLOCATION;
1352 case 0x06:
1353 /* Not tested on 6210 */
1354 smprintf(s, "Phone is OFF\n");
1355 return ERR_PHONEOFF;
1356 default:
1357 smprintf(s, "Unknown error: %02x\n",msg.Buffer[4]);
1358 return ERR_UNKNOWNRESPONSE;
1359 }
1360 }
1361 return ERR_UNKNOWNRESPONSE;
1362}
1363
1364GSM_Error N71_92_ReplyGetSignalQuality(GSM_Protocol_Message msg, GSM_StateMachine *s)
1365{
1366 GSM_Phone_Data *Data = &s->Phone.Data;
1367
1368 smprintf(s, "Network level received: %i\n",msg.Buffer[4]);
1369 Data->SignalQuality->SignalStrength = -1;
1370 Data->SignalQuality->SignalPercent = ((int)msg.Buffer[4]);
1371 Data->SignalQuality->BitErrorRate = -1;
1372 return ERR_NONE;
1373}
1374
1375GSM_Error N71_92_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig)
1376{
1377 unsigned char req[] = {N6110_FRAME_HEADER, 0x81};
1378
1379 s->Phone.Data.SignalQuality = sig;
1380 smprintf(s, "Getting network level\n");
1381 return GSM_WaitFor (s, req, 4, 0x0a, 4, ID_GetSignalQuality);
1382}
1383
1384GSM_Error N71_92_ReplyGetBatteryCharge(GSM_Protocol_Message msg, GSM_StateMachine *s)
1385{
1386 GSM_Phone_Data *Data = &s->Phone.Data;
1387
1388 smprintf(s, "Battery level received: %i\n",msg.Buffer[5]);
1389 Data->BatteryCharge->BatteryPercent = ((int)msg.Buffer[5]);
1390 Data->BatteryCharge->ChargeState = 0;
1391 return ERR_NONE;
1392}
1393
1394GSM_Error N71_92_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat)
1395{
1396 unsigned char req[] = {N6110_FRAME_HEADER, 0x02};
1397
1398 s->Phone.Data.BatteryCharge = bat;
1399 smprintf(s, "Getting battery level\n");
1400 return GSM_WaitFor (s, req, 4, 0x17, 4, ID_GetBatteryCharge);
1401}
1402
1403GSM_Error N71_92_ReplyPhoneSetting(GSM_Protocol_Message msg, GSM_StateMachine *s)
1404{
1405 GSM_Phone_Bitmap_TypesBmpType;
1406 GSM_Phone_Data *Data = &s->Phone.Data;
1407
1408 switch (msg.Buffer[4]) {
1409 case 0x02:
1410 if (Data->RequestID == ID_GetBitmap || Data->RequestID == ID_EachFrame) {
1411 smprintf(s, "Welcome note text received\n");
1412 CopyUnicodeString(Data->Bitmap->Text,msg.Buffer+6);
1413 smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text));
1414 return ERR_NONE;
1415 }
1416 if (Data->RequestID == ID_SetBitmap || Data->RequestID == ID_EachFrame) {
1417 smprintf(s, "Startup text set\n");
1418 return ERR_NONE;
1419 }
1420 case 0x15:
1421 if (Data->RequestID == ID_GetBitmap || Data->RequestID == ID_EachFrame) {
1422 smprintf(s, "Startup logo received\n");
1423 BmpType=GSM_Nokia7110StartupLogo;
1424 if (msg.Buffer[17]==0x60) BmpType=GSM_Nokia6210StartupLogo;
1425 if (msg.Buffer[17]==0xc0) BmpType=GSM_NokiaStartupLogo;
1426 PHONE_DecodeBitmap(BmpType, msg.Buffer+22, Data->Bitmap);
1427 return ERR_NONE;
1428 }
1429 if (Data->RequestID == ID_SetBitmap || Data->RequestID == ID_EachFrame) {
1430 smprintf(s, "Startup logo set\n");
1431 return ERR_NONE;
1432 }
1433 case 0x17:
1434 if (Data->RequestID == ID_GetBitmap || Data->RequestID == ID_EachFrame) {
1435 smprintf(s, "Dealer note text received\n");
1436 CopyUnicodeString(Data->Bitmap->Text,msg.Buffer+6);
1437 smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text));
1438 return ERR_NONE;
1439 }
1440 if (Data->RequestID == ID_SetBitmap || Data->RequestID == ID_EachFrame) {
1441 smprintf(s, "Dealer text set\n");
1442 return ERR_NONE;
1443 }
1444 }
1445 return ERR_UNKNOWNRESPONSE;
1446}
1447
1448GSM_Error N71_92_GetPhoneSetting(GSM_StateMachine *s, int Request, int Setting)
1449{
1450 unsigned char req[] = {N7110_FRAME_HEADER, 0xee,
1451 0x1c}; /* Setting */
1452
1453 req[4]=Setting;
1454 return GSM_WaitFor (s, req, 5, 0x7a, 4, Request);
1455}
1456
1457GSM_Error N71_92_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
1458{
1459 return DCT3_GetDateTime(s, date_time, 0x19);
1460}
1461
1462GSM_Error N71_92_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
1463{
1464 return DCT3_SetDateTime(s, date_time, 0x19);
1465}
1466
1467GSM_Error DCT3_DecodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *SMS, unsigned char *buffer)
1468{
1469 switch (buffer[12] & 0x03) {
1470 case 0x00:
1471 smprintf(s, "SMS type - deliver\n");
1472 SMS->PDU = SMS_Deliver;
1473 return GSM_DecodeSMSFrame(SMS,buffer,PHONE_SMSDeliver);
1474 case 0x01:
1475 smprintf(s, "SMS type - submit\n");
1476 SMS->PDU = SMS_Submit;
1477 return GSM_DecodeSMSFrame(SMS,buffer,PHONE_SMSSubmit);
1478 case 0x02:
1479 smprintf(s, "SMS type - delivery report\n");
1480 SMS->PDU = SMS_Status_Report;
1481 return GSM_DecodeSMSFrame(SMS,buffer,PHONE_SMSStatusReport);
1482 }
1483 return ERR_UNKNOWN;
1484}
1485
1486GSM_Error N61_91_ReplySetOpLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
1487{
1488 switch (msg.Buffer[3]) {
1489 case 0x31:
1490 smprintf(s, "Operator logo set OK\n");
1491 return ERR_NONE;
1492 case 0x32:
1493 smprintf(s, "Error setting operator logo\n");
1494 switch (msg.Buffer[4]) {
1495 case 0x7d:
1496 smprintf(s, "Too high location ?\n");
1497 return ERR_INVALIDLOCATION;
1498 default:
1499 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
1500 }
1501 }
1502 return ERR_UNKNOWNRESPONSE;
1503}
1504
1505GSM_Error N61_71_ReplyResetPhoneSettings(GSM_Protocol_Message msg, GSM_StateMachine *s)
1506{
1507 smprintf(s, "Phone settings cleaned OK\n");
1508 return ERR_NONE;
1509}
1510
1511GSM_Error N61_71_ResetPhoneSettings(GSM_StateMachine *s, GSM_ResetSettingsType Type)
1512{
1513 GSM_Errorerror;
1514 unsigned char req[] = {0x00, 0x01, 0x65,
1515 0x01}; /* Reset type */
1516
1517 switch (Type) {
1518 case GSM_RESET_PHONESETTINGS : req[3] = 0x01; break;
1519 case GSM_RESET_DEVICE : req[3] = 0x02; break;
1520 case GSM_RESET_USERINTERFACE : req[3] = 0x08; break;
1521 case GSM_RESET_USERINTERFACE_PHONESETTINGS: req[3] = 0x38; break;
1522 case GSM_RESET_FULLFACTORY : req[3] = 0xff; break;
1523 }
1524
1525 error=DCT3_EnableSecurity (s, 0x01);
1526 if (error != ERR_NONE) return error;
1527
1528 return GSM_WaitFor (s, req, 4, 0x40, 4, ID_ResetPhoneSettings);
1529}
1530
1531#endif
1532
1533/* How should editor hadle tabs in this file? Add editor commands here.
1534 * vim: noexpandtab sw=8 ts=8 sts=8:
1535 */
diff --git a/gammu/emb/common/phone/nokia/dct3/dct3func.h b/gammu/emb/common/phone/nokia/dct3/dct3func.h
new file mode 100644
index 0000000..66b67ec
--- a/dev/null
+++ b/gammu/emb/common/phone/nokia/dct3/dct3func.h
@@ -0,0 +1,78 @@
1/* (c) 2002-2003 by Marcin Wiacek */
2
3#ifndef phone_nokia_dct3_h
4#define phone_nokia_dct3_h
5
6 GSM_Error DCT3_ReplyPressKey (GSM_Protocol_Message msg, GSM_StateMachine *s);
7 GSM_Error DCT3_ReplyPlayTone (GSM_Protocol_Message msg, GSM_StateMachine *s);
8 GSM_Error DCT3_ReplyEnableSecurity(GSM_Protocol_Message msg, GSM_StateMachine *s);
9 GSM_Error DCT3_ReplyGetIMEI (GSM_Protocol_Message msg, GSM_StateMachine *s);
10 GSM_Error DCT3_ReplyGetSMSC (GSM_Protocol_Message msg, GSM_StateMachine *s);
11 GSM_Error DCT3_ReplySIMLogin (GSM_Protocol_Message msg, GSM_StateMachine *s);
12 GSM_Error DCT3_ReplySIMLogout (GSM_Protocol_Message msg, GSM_StateMachine *s);
13 GSM_Error DCT3_ReplyGetDateTime (GSM_Protocol_Message msg, GSM_StateMachine *s);
14 GSM_Error DCT3_ReplyGetAlarm (GSM_Protocol_Message msg, GSM_StateMachine *s);
15 GSM_Error DCT3_ReplySetDateTime (GSM_Protocol_Message msg, GSM_StateMachine *s);
16 GSM_Error DCT3_ReplySetAlarm (GSM_Protocol_Message msg, GSM_StateMachine *s);
17 GSM_Error DCT3_ReplyDialCommand (GSM_Protocol_Message msg, GSM_StateMachine *s);
18 GSM_Error DCT3_ReplyGetWAPBookmark(GSM_Protocol_Message msg, GSM_StateMachine *s);
19 GSM_Error DCT3_ReplyGetNetworkInfo(GSM_Protocol_Message msg, GSM_StateMachine *s);
20 GSM_Error DCT3_ReplySendSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s);
21 GSM_Error DCT3_ReplySetSMSC (GSM_Protocol_Message msg, GSM_StateMachine *s);
22 GSM_Error DCT3_ReplyGetWAPSettings(GSM_Protocol_Message msg, GSM_StateMachine *s);
23 GSM_Error DCT3_ReplySetWAPSettings(GSM_Protocol_Message msg, GSM_StateMachine *s);
24 GSM_Error DCT3_ReplyNetmonitor (GSM_Protocol_Message msg, GSM_StateMachine *s);
25 GSM_Error DCT3_ReplyDeleteSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s);
26 GSM_Error N71_92_ReplyGetSignalQuality(GSM_Protocol_Message msg, GSM_StateMachine *s);
27 GSM_Error N71_92_ReplyGetBatteryCharge(GSM_Protocol_Message msg, GSM_StateMachine *s);
28 GSM_Error N71_92_ReplyPhoneSetting(GSM_Protocol_Message msg, GSM_StateMachine *s);
29GSM_Error N61_71_ReplyResetPhoneSettings(GSM_Protocol_Message msg, GSM_StateMachine *s);
30 GSM_Error N61_91_ReplySetOpLogo (GSM_Protocol_Message msg, GSM_StateMachine *s);
31#ifdef GSM_ENABLE_CELLBROADCAST
32 GSM_Error DCT3_ReplySetIncomingCB(GSM_Protocol_Message msg, GSM_StateMachine *s);
33 GSM_Error DCT3_ReplyIncomingCB (GSM_Protocol_Message msg, GSM_StateMachine *s);
34#endif
35
36 GSM_Error DCT3_DeleteWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark);
37 GSM_Error DCT3_GetWAPBookmark (GSM_StateMachine *s, GSM_WAPBookmark *bookmark);
38 GSM_Error DCT3_PressKey (GSM_StateMachine *s, GSM_KeyCode Key, bool Press);
39 GSM_Error DCT3_PlayTone (GSM_StateMachine *s, int Herz, unsigned char Volume, bool start);
40 GSM_Error DCT3_EnableSecurity (GSM_StateMachine *s, unsigned char status);
41 GSM_Error DCT3_GetIMEI (GSM_StateMachine *s);
42 GSM_Error DCT3_GetSMSC (GSM_StateMachine *s, GSM_SMSC *smsc );
43 GSM_Error DCT3_GetNetworkInfo (GSM_StateMachine *s, GSM_NetworkInfo *netinfo);
44 GSM_Error DCT3_DialVoice (GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber);
45 GSM_Error DCT3_Reset (GSM_StateMachine *s, bool hard );
46 GSM_Error DCT3_CancelCall (GSM_StateMachine *s, int ID, bool all);
47 GSM_Error DCT3_AnswerAllCalls (GSM_StateMachine *s);
48 GSM_Error DCT3_SendSMSMessage (GSM_StateMachine *s, GSM_SMSMessage *sms );
49 GSM_Error DCT3_GetAlarm (GSM_StateMachine *s, GSM_Alarm *alarm,unsigned char msgtype);
50 GSM_Error DCT3_GetDateTime (GSM_StateMachine *s, GSM_DateTime *date_time, unsigned char msgtype);
51 GSM_Error DCT3_SetAlarm (GSM_StateMachine *s, GSM_Alarm *alarm, unsigned char msgtype);
52 GSM_Error DCT3_SetDateTime (GSM_StateMachine *s, GSM_DateTime *date_time, unsigned char msgtype);
53 GSM_Error DCT3_SetIncomingCB (GSM_StateMachine *s, bool enable);
54 GSM_Error DCT3_GetSMSStatus (GSM_StateMachine *s, GSM_SMSMemoryStatus *status);
55 GSM_Error DCT3_SetSMSC (GSM_StateMachine *s, GSM_SMSC *smsc );
56 GSM_Error DCT3_GetWAPSettings (GSM_StateMachine *s, GSM_MultiWAPSettings *settings);
57 GSM_Error DCT3_SetWAPSettings (GSM_StateMachine *s, GSM_MultiWAPSettings *settings);
58 GSM_Error DCT3_SetWAPBookmark (GSM_StateMachine *s, GSM_WAPBookmark *bookmark);
59 GSM_Error DCT3_Netmonitor (GSM_StateMachine *s, int testnumber, char *value);
60 GSM_Error DCT3_GetManufactureMonth (GSM_StateMachine *s, char *value);
61 GSM_Error DCT3_GetProductCode (GSM_StateMachine *s, char *value);
62 GSM_Error DCT3_GetOriginalIMEI (GSM_StateMachine *s, char *value);
63 GSM_Error DCT3_GetHardware (GSM_StateMachine *s, char *value);
64 GSM_Error DCT3_GetPPM (GSM_StateMachine *s, char *value);
65 GSM_Error N61_71_ResetPhoneSettings(GSM_StateMachine *s, GSM_ResetSettingsType Type);
66 GSM_Error N71_92_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat);
67 GSM_Error N71_92_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig);
68 GSM_Error N71_92_GetPhoneSetting(GSM_StateMachine *s, int Request, int Setting);
69 GSM_Error N71_92_GetDateTime (GSM_StateMachine *s, GSM_DateTime *date_time);
70 GSM_Error N71_92_SetDateTime (GSM_StateMachine *s, GSM_DateTime *date_time);
71
72 GSM_Error DCT3_DecodeSMSFrame (GSM_StateMachine *s, GSM_SMSMessage *SMS, unsigned char *buffer);
73
74#endif
75
76/* How should editor hadle tabs in this file? Add editor commands here.
77 * vim: noexpandtab sw=8 ts=8 sts=8:
78 */
diff --git a/gammu/emb/common/phone/nokia/dct3/n6110.c b/gammu/emb/common/phone/nokia/dct3/n6110.c
new file mode 100644
index 0000000..263d12b
--- a/dev/null
+++ b/gammu/emb/common/phone/nokia/dct3/n6110.c
@@ -0,0 +1,2884 @@
1/* (c) 2001-2004 by Marcin Wiacek */
2/* based on some work from Markus Plail and Gnokii */
3/* Authentication function (c) 1999 or earlier by Pavel Janik */
4/* 5210 calendar IDs by Frederick Ros */
5
6#include "../../../gsmstate.h"
7
8#ifdef GSM_ENABLE_NOKIA6110
9
10#include <string.h>
11
12#include "../../../../cfg/config.h"
13#include "../../../misc/coding/coding.h"
14#include "../../../service/sms/gsmsms.h"
15#include "../../../gsmcomon.h"
16#include "../../pfunc.h"
17#include "../nfunc.h"
18#include "n6110.h"
19#include "dct3func.h"
20
21static unsigned char N6110_MEMORY_TYPES[] = {
22 MEM_ME, 0x02,
23 MEM_SM, 0x03,
24 MEM_ON, 0x05,
25 MEM_DC, 0x07,
26 MEM_RC, 0x08,
27 MEM_MC, 0x09,
28 MEM_VM, 0x0b,
29 0x00, 0x00
30};
31
32static GSM_Error N6110_ReplyGetPhoneLanguage(GSM_Protocol_Message msg, GSM_StateMachine *s)
33{
34 N6110_Language lang = N6110_Auto;
35
36 if (msg.Buffer[3] == 0x15) return ERR_NONE;
37
38 smprintf(s, "Phone language is %02x\n",msg.Buffer[6]);
39 switch (msg.Buffer[6]) {
40 case 0x21: lang = N6110_Europe; break; //Polish
41 }
42 s->Phone.Data.Priv.N6110.PhoneLanguage = lang;
43 return ERR_NONE;
44}
45
46static GSM_Error N6110_GetPhoneLanguage(GSM_StateMachine *s)
47{
48 unsigned char feat_req[] = {N6110_FRAME_HEADER, 0x13, 0x01,
49 0x00, /* Profile location */
50 0x00}; /* Feature number */
51
52 s->Phone.Data.Priv.N6110.PhoneLanguage = N6110_Auto;
53
54 feat_req[5] = 0;
55 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) {
56 feat_req[6] = 0x1E;
57 } else {
58 feat_req[6] = 0x21;
59 }
60 smprintf(s, "Getting profile feature\n");
61 return GSM_WaitFor (s, feat_req, 7, 0x05, 4, ID_GetLanguage);
62}
63
64struct N6110_Lang_Char {
65 N6110_Language Lang;
66 unsigned char Phone;
67 unsigned char Unicode1;
68 unsigned char Unicode2;
69};
70
71static struct N6110_Lang_Char N6110_Lang_Table[] = {
72{N6110_Europe,0x13,0x01,0x04},//Latin capital letter a with ogonek
73{N6110_Europe,0x14,0x01,0x05},//Latin small letter a with ogonek
74{N6110_Europe,0x15,0x01,0x06},//Latin capital letter c with acute
75{N6110_Europe,0x17,0x01,0x07},//Latin small letter c with acute
76{N6110_Europe,0x1D,0x01,0x18},//Latin capital letter e with ogonek
77{N6110_Europe,0x1E,0x01,0x19},//Latin small letter e with ogonek
78{N6110_Europe,0x83,0x00,0xD3},//Latin capital letter o with acute
79{N6110_Europe,0x8E,0x01,0x41},//Latin capital letter l with stroke
80{N6110_Europe,0x90,0x01,0x42},//Latin small letter l with stroke
81{N6110_Europe,0x92,0x01,0x43},//Latin capital letter n with acute
82{N6110_Europe,0x93,0x01,0x44},//Latin small letter n with acute
83{N6110_Europe,0x9A,0x00,0xF3},//Latin small letter o with acute
84{N6110_Europe,0xB2,0x20,0xAC},//euro
85{N6110_Europe,0xB5,0x01,0x5A},//Latin capital letter s with acute
86{N6110_Europe,0xB6,0x01,0x5B},//Latin small letter s with acute
87{N6110_Europe,0xE7,0x01,0x79},//Latin capital letter z with acute
88{N6110_Europe,0xEE,0x01,0x7A},//Latin small letter z with acute
89{N6110_Europe,0xF4,0x01,0x7C},//Latin small letter z with dot above
90{N6110_Europe,0xF0,0x01,0x7B},//Latin capital letter z with dot above
91{0,0,0,0}
92};
93
94static void N6110_EncodeUnicode(GSM_StateMachine *s, unsigned char *dest, const unsigned char *src, int len)
95{
96 int i_len = 0, o_len, i;
97 wchar_t wc;
98 GSM_Phone_N6110Data *Priv = &s->Phone.Data.Priv.N6110;
99 bool found;
100
101 for (o_len = 0; i_len < len; o_len++) {
102 found = false;
103 if (Priv->PhoneLanguage != N6110_Auto) {
104 i = 0;
105 while(1) {
106 if (N6110_Lang_Table[i].Lang == 0) break;
107 if (N6110_Lang_Table[i].Lang == Priv->PhoneLanguage &&
108 N6110_Lang_Table[i].Phone == src[i_len]) {
109 dest[o_len*2] = N6110_Lang_Table[i].Unicode1;
110 dest[(o_len*2)+1] = N6110_Lang_Table[i].Unicode2;
111 i_len++;
112 found = true;
113 break;
114 }
115 i++;
116 }
117 }
118 if (!found) {
119 i_len += EncodeWithUnicodeAlphabet(&src[i_len], &wc);
120 dest[o_len*2] = (wc >> 8) & 0xff;
121 dest[(o_len*2)+1] = wc & 0xff;
122 }
123 }
124 dest[o_len*2] = 0;
125 dest[(o_len*2)+1] = 0;
126}
127
128#ifndef ENABLE_LGPL
129
130/* This function provides Nokia authentication protocol.
131 * Nokia authentication protocol is used in the communication between Nokia
132 * mobile phones (e.g. Nokia 6110) and Nokia Cellular Data Suite software,
133 * commercially sold by Nokia Corp.
134 * The authentication scheme is based on the token send by the phone to the
135 * software. The software does it's magic (see the function
136 * N6110_GetNokiaAuthentication) and returns the result back to the phone.
137 * If the result is correct the phone responds with the message "Accessory
138 * connected!" displayed on the LCD. Otherwise it will display "Accessory not
139 * supported" and some functions will not be available for use (?).
140 * The specification of the protocol is not publicly available, no comment.
141 */
142static void N6110_GetNokiaAuthentication(unsigned char *Imei, unsigned char *MagicBytes, unsigned char *MagicResponse)
143{
144 int i, j, CRC=0;
145 unsigned char Temp[16]; /* This is our temporary working area. */
146
147 /* Here we put FAC (Final Assembly Code) and serial number into our area. */
148 Temp[0] = Imei[6]; Temp[1] = Imei[7];
149 Temp[2] = Imei[8]; Temp[3] = Imei[9];
150 Temp[4] = Imei[10]; Temp[5] = Imei[11];
151 Temp[6] = Imei[12]; Temp[7] = Imei[13];
152
153 /* And now the TAC (Type Approval Code). */
154 Temp[8] = Imei[2]; Temp[9] = Imei[3];
155 Temp[10] = Imei[4]; Temp[11] = Imei[5];
156
157 /* And now we pack magic bytes from the phone. */
158 Temp[12] = MagicBytes[0]; Temp[13] = MagicBytes[1];
159 Temp[14] = MagicBytes[2]; Temp[15] = MagicBytes[3];
160
161 for (i=0; i<=11; i++) if (Temp[i + 1]& 1) Temp[i]<<=1;
162 switch (Temp[15] & 0x03) {
163 case 1:
164 case 2: j = Temp[13] & 0x07;
165 for (i=0; i<=3; i++) Temp[i+j] ^= Temp[i+12];
166 break;
167 default: j = Temp[14] & 0x07;
168 for (i=0; i<=3; i++) Temp[i + j] |= Temp[i + 12];
169 }
170 for (i=0; i<=15; i++) CRC ^= Temp[i];
171 for (i=0; i<=15; i++) {
172 switch (Temp[15 - i] & 0x06) {
173 case 0: j = Temp[i] | CRC; break;
174 case 2:
175 case 4: j = Temp[i] ^ CRC; break;
176 case 6: j = Temp[i] & CRC; break;
177 }
178 if (j == CRC) j = 0x2c;
179 if (Temp[i] == 0) j = 0;
180 MagicResponse[i] = j;
181 }
182}
183
184static GSM_Error N6110_ReplyGetMagicBytes(GSM_Protocol_Message msg, GSM_StateMachine *s)
185{
186 GSM_Phone_N6110Data *Priv = &s->Phone.Data.Priv.N6110;
187 GSM_Phone_Data *Data = &s->Phone.Data;
188
189 sprintf(Data->IMEI, "%s", msg.Buffer+9);
190 sprintf(Data->HardwareCache, "%s", msg.Buffer+39);
191 sprintf(Data->ProductCodeCache, "%s", msg.Buffer+31);
192
193 smprintf(s, "Message: Mobile phone identification received:\n");
194 smprintf(s, "IMEI : %s\n", msg.Buffer+9);
195 smprintf(s, "Model : %s\n", msg.Buffer+25);
196 smprintf(s, "Production Code : %s\n", msg.Buffer+31);
197 smprintf(s, "HW : %s\n", msg.Buffer+39);
198 smprintf(s, "Firmware : %s\n", msg.Buffer+44);
199
200 /* These bytes are probably the source of the "Accessory not connected"
201 * messages on the phone when trying to emulate NCDS... I hope....
202 * UPDATE: of course, now we have the authentication algorithm.
203 */
204 smprintf(s, " Magic bytes : %02x %02x %02x %02x\n", msg.Buffer[50], msg.Buffer[51], msg.Buffer[52], msg.Buffer[53]);
205
206 Priv->MagicBytes[0]=msg.Buffer[50];
207 Priv->MagicBytes[1]=msg.Buffer[51];
208 Priv->MagicBytes[2]=msg.Buffer[52];
209 Priv->MagicBytes[3]=msg.Buffer[53];
210
211 return ERR_NONE;
212}
213
214static GSM_Error N6110_MakeAuthentication(GSM_StateMachine *s)
215{
216 GSM_Phone_N6110Data *Priv = &s->Phone.Data.Priv.N6110;
217 GSM_Error error;
218 unsigned char connect4[] = {N6110_FRAME_HEADER, 0x10};
219 unsigned char magic_connect[] = {
220 N6110_FRAME_HEADER, 0x12,
221 /* The real magic goes here ... These bytes are filled in
222 * with the function N6110_GetNokiaAuthentication. */
223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 /* NOKIA&GNOKII Accessory */
226 'N', 'O', 'K', 'I', 'A', '&', 'N', 'O', 'K', 'I', 'A',
227 'a', 'c', 'c', 'e', 's', 's', 'o', 'r', 'y',
228 0x00, 0x00, 0x00, 0x00};
229
230 smprintf(s, "Getting magic bytes for authentication\n");
231 error=GSM_WaitFor (s, connect4, 4, 0x64, 4, ID_MakeAuthentication);
232 if (error!=ERR_NONE) return error;
233
234 N6110_GetNokiaAuthentication(s->Phone.Data.IMEI, Priv->MagicBytes, magic_connect+4);
235 smprintf(s, "Sending authentication bytes\n");
236 return s->Protocol.Functions->WriteMessage(s, magic_connect, 45, 0x64);
237}
238
239#endif
240
241static GSM_Error N6110_ShowStartInfo(GSM_StateMachine *s, bool enable)
242{
243#ifdef ENABLE_LGPL
244 return ERR_NONE;
245#else
246 GSM_Error error=ERR_NONE;
247
248 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_MAGICBYTES)) {
249 if (s->ConnectionType == GCT_FBUS2 ||
250 s->ConnectionType == GCT_FBUS2IRDA) {
251 error=N6110_MakeAuthentication(s);
252 }
253 }
254 return error;
255#endif
256}
257
258static GSM_Error N6110_Initialise (GSM_StateMachine *s)
259{
260#ifdef DEBUG
261 DCT3_SetIncomingCB(s,true);
262#endif
263 N6110_GetPhoneLanguage(s);
264 return ERR_NONE;
265}
266
267static GSM_Error N6110_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
268{
269 return DCT3_GetDateTime(s, date_time, 0x11);
270}
271
272static GSM_Error N6110_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm)
273{
274 return DCT3_GetAlarm(s, alarm, 0x11);
275}
276
277static GSM_Error N6110_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
278{
279 return DCT3_SetDateTime(s, date_time, 0x11);
280}
281
282static GSM_Error N6110_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm)
283{
284 return DCT3_SetAlarm(s, alarm, 0x11);
285}
286
287static GSM_Error N6110_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s)
288{
289 int count;
290 GSM_Phone_Data *Data = &s->Phone.Data;
291
292 smprintf(s, "Phonebook entry received\n");
293 switch (msg.Buffer[3]) {
294 case 0x02:
295 Data->Memory->EntriesNum = 0;
296 count=5;
297 /* If name is not empty */
298 if (msg.Buffer[count]!=0x00) {
299 if (msg.Buffer[count]>GSM_PHONEBOOK_TEXT_LENGTH) {
300 smprintf(s, "Too long text\n");
301 return ERR_UNKNOWNRESPONSE;
302 }
303 Data->Memory->Entries[Data->Memory->EntriesNum].EntryType=PBK_Text_Name;
304 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOPBKUNICODE)) {
305 if (Data->Memory->MemoryType==MEM_DC ||
306 Data->Memory->MemoryType==MEM_RC ||
307 Data->Memory->MemoryType==MEM_MC ||
308 Data->Memory->MemoryType==MEM_ME) {
309 N6110_EncodeUnicode(s,Data->Memory->Entries[Data->Memory->EntriesNum].Text,
310 msg.Buffer+count+1,msg.Buffer[count]);
311 } else {
312 EncodeUnicode(Data->Memory->Entries[Data->Memory->EntriesNum].Text,
313 msg.Buffer+count+1,msg.Buffer[count]);
314 }
315 } else {
316 memcpy(Data->Memory->Entries[Data->Memory->EntriesNum].Text,
317 msg.Buffer+count+1,msg.Buffer[count]);
318 Data->Memory->Entries[Data->Memory->EntriesNum].Text[msg.Buffer[count]]=0x00;
319 Data->Memory->Entries[Data->Memory->EntriesNum].Text[msg.Buffer[count]+1]=0x00;
320 }
321 smprintf(s, "Name \"%s\"\n",
322 DecodeUnicodeString(Data->Memory->Entries[Data->Memory->EntriesNum].Text));
323 Data->Memory->EntriesNum++;
324 }
325 count=count+msg.Buffer[count]+1;
326
327 /* If number is empty */
328 if (msg.Buffer[count]==0x00) return ERR_EMPTY;
329
330 if (msg.Buffer[count]>GSM_PHONEBOOK_TEXT_LENGTH) {
331 smprintf(s, "Too long text\n");
332 return ERR_UNKNOWNRESPONSE;
333 }
334 Data->Memory->Entries[Data->Memory->EntriesNum].EntryType = PBK_Number_General;
335 Data->Memory->Entries[Data->Memory->EntriesNum].VoiceTag = 0;
336 Data->Memory->Entries[Data->Memory->EntriesNum].SMSList[0] = 0;
337 EncodeUnicode(Data->Memory->Entries[Data->Memory->EntriesNum].Text,
338 msg.Buffer+count+1,msg.Buffer[count]);
339 smprintf(s, "Number \"%s\"\n",
340 DecodeUnicodeString(Data->Memory->Entries[Data->Memory->EntriesNum].Text));
341 Data->Memory->EntriesNum++;
342 count=count+msg.Buffer[count]+1;
343
344 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOCALLER)) {
345 if (msg.Buffer[count]<5) {
346 Data->Memory->Entries[Data->Memory->EntriesNum].EntryType=PBK_Caller_Group;
347 smprintf(s, "Caller group \"%i\"\n",msg.Buffer[count]);
348 Data->Memory->Entries[Data->Memory->EntriesNum].Number=msg.Buffer[count]+1;
349 Data->Memory->EntriesNum++;
350 }
351 }
352 count++;
353
354 if (Data->Memory->MemoryType==MEM_DC ||
355 Data->Memory->MemoryType==MEM_RC ||
356 Data->Memory->MemoryType==MEM_MC) {
357 NOKIA_DecodeDateTime(s, msg.Buffer+count+1,&Data->Memory->Entries[Data->Memory->EntriesNum].Date);
358 Data->Memory->Entries[Data->Memory->EntriesNum].EntryType=PBK_Date;
359
360 /* These values are set, when date and time unavailable in phone.
361 * Values from 3310 - in other can be different */
362 if (Data->Memory->Entries[2].Date.Day !=20 ||
363 Data->Memory->Entries[2].Date.Month !=1 ||
364 Data->Memory->Entries[2].Date.Year !=2118||
365 Data->Memory->Entries[2].Date.Hour !=3 ||
366 Data->Memory->Entries[2].Date.Minute!=14 ||
367 Data->Memory->Entries[2].Date.Second!=7)
368 Data->Memory->EntriesNum++;
369 }
370
371 return ERR_NONE;
372 default:
373 switch (msg.Buffer[4]) {
374 case 0x6f:
375 smprintf(s, "Phone is OFF\n");
376 return ERR_PHONEOFF;
377 case 0x74:
378 /* TODO: check if not too high */
379 smprintf(s, "ERROR: Empty ????\n");
380 Data->Memory->EntriesNum = 0;
381 return ERR_EMPTY;
382 case 0x7d:
383 smprintf(s, "ERROR: Invalid memory type\n");
384 return ERR_NOTSUPPORTED;
385 case 0x8d:
386 smprintf(s, "ERROR: no PIN\n");
387 return ERR_SECURITYERROR;
388 default:
389 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
390 }
391 }
392 return ERR_UNKNOWNRESPONSE;
393}
394
395static GSM_Error N6110_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry)
396{
397 unsigned char req[] = {N6110_FRAME_HEADER, 0x01,
398 0x00, /* memory type */
399 0x00, /* location */
400 0x00};
401
402 req[4] = NOKIA_GetMemoryType(s, entry->MemoryType,N6110_MEMORY_TYPES);
403 if (req[4]==0xff) return ERR_NOTSUPPORTED;
404
405 req[5] = entry->Location;
406 if (entry->MemoryType==MEM_DC || entry->MemoryType==MEM_RC || entry->MemoryType==MEM_MC) req[5]--;
407
408 s->Phone.Data.Memory=entry;
409 smprintf(s, "Getting phonebook entry\n");
410 return GSM_WaitFor (s, req, 7, 0x03, 4, ID_GetMemory);
411}
412
413static GSM_Error N6110_ReplyGetMemoryStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
414{
415 GSM_Phone_Data *Data = &s->Phone.Data;
416
417 smprintf(s, "Memory status received\n");
418 switch (msg.Buffer[3]) {
419 case 0x08:
420 smprintf(s, "Memory type: %i\n",msg.Buffer[4]);
421
422 smprintf(s, "Free : %i\n",msg.Buffer[5]);
423 Data->MemoryStatus->MemoryFree=msg.Buffer[5];
424
425 smprintf(s, "Used : %i\n",msg.Buffer[6]);
426 Data->MemoryStatus->MemoryUsed=msg.Buffer[6];
427
428 return ERR_NONE;
429 break;
430 case 0x09:
431 switch (msg.Buffer[4]) {
432 case 0x6f:
433 smprintf(s, "Phone is probably powered off.\n");
434 return ERR_TIMEOUT;
435 case 0x7d:
436 smprintf(s, "Memory type not supported by phone model.\n");
437 return ERR_NOTSUPPORTED;
438 case 0x8d:
439 smprintf(s, "Waiting for security code.\n");
440 return ERR_SECURITYERROR;
441 default:
442 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
443 }
444 default:
445 return ERR_UNKNOWNRESPONSE;
446 }
447}
448
449static GSM_Error N6110_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status)
450{
451 unsigned char req[] = {N6110_FRAME_HEADER, 0x07,
452 0x00}; /* memory type */
453
454 req[4] = NOKIA_GetMemoryType(s, Status->MemoryType,N6110_MEMORY_TYPES);
455 if (req[4]==0xff) return ERR_NOTSUPPORTED;
456
457 s->Phone.Data.MemoryStatus=Status;
458 smprintf(s, "Getting memory status\n");
459 return GSM_WaitFor (s, req, 5, 0x03, 4, ID_GetMemoryStatus);
460}
461
462static GSM_Error N6110_ReplyGetSMSStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
463{
464 GSM_Phone_Data *Data = &s->Phone.Data;
465
466 smprintf(s, "SMS status received\n");
467 switch (msg.Buffer[3]) {
468 case 0x37:
469 smprintf(s, "SIM size : %i\n",msg.Buffer[7]);
470 smprintf(s, "Used in SIM : %i\n",msg.Buffer[10]);
471 smprintf(s, "Unread in SIM : %i\n",msg.Buffer[11]);
472 Data->SMSStatus->SIMUsed = msg.Buffer[10];
473 Data->SMSStatus->SIMUnRead = msg.Buffer[11];
474 Data->SMSStatus->SIMSize = msg.Buffer[7];
475 Data->SMSStatus->PhoneUsed = 0;
476 Data->SMSStatus->PhoneUnRead = 0;
477 Data->SMSStatus->PhoneSize = 0;
478 Data->SMSStatus->TemplatesUsed = 0;
479 return ERR_NONE;
480 case 0x38:
481 smprintf(s, "Error. No PIN ?\n");
482 return ERR_SECURITYERROR;
483 }
484 return ERR_UNKNOWNRESPONSE;
485}
486
487static GSM_Error N6110_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
488{
489 GSM_Phone_Data *Data = &s->Phone.Data;
490
491 smprintf(s, "SMS Message received\n");
492 switch(msg.Buffer[3]) {
493 case 0x08:
494 Data->GetSMSMessage->Number = 1;
495 Data->GetSMSMessage->SMS[0].Name[0] = 0;
496 Data->GetSMSMessage->SMS[0].Name[1] = 0;
497 Data->GetSMSMessage->SMS[0].Memory = MEM_SM;
498 NOKIA_DecodeSMSState(s, msg.Buffer[4], &Data->GetSMSMessage->SMS[0]);
499 switch (msg.Buffer[7]) {
500 case 0x00: case 0x01: /* Report or SMS_Deliver */
501 Data->GetSMSMessage->SMS[0].Folder = 0x01;
502 Data->GetSMSMessage->SMS[0].InboxFolder = true;
503 break;
504 case 0x02: /* SMS_Submit */
505 Data->GetSMSMessage->SMS[0].Folder = 0x02;
506 Data->GetSMSMessage->SMS[0].InboxFolder = false;
507 break;
508 default:
509 return ERR_UNKNOWNRESPONSE;
510 }
511 DCT3_DecodeSMSFrame(s, &Data->GetSMSMessage->SMS[0],msg.Buffer+8);
512 return ERR_NONE;
513 case 0x09:
514 switch (msg.Buffer[4]) {
515 case 0x00:
516 smprintf(s, "Unknown. Probably phone too busy\n");
517 return ERR_UNKNOWN;
518 case 0x02:
519 smprintf(s, "Too high location ?\n");
520 return ERR_INVALIDLOCATION;
521 case 0x06:
522 smprintf(s, "Phone is OFF\n");
523 return ERR_PHONEOFF;
524 case 0x07:
525 smprintf(s, "Empty\n");
526 return ERR_EMPTY;
527 case 0x0c:
528 smprintf(s, "Access error. No PIN ?\n");
529 return ERR_SECURITYERROR;
530 default:
531 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
532 }
533 }
534 return ERR_UNKNOWNRESPONSE;
535}
536
537static GSM_Error N6110_GetSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms)
538{
539 unsigned char req[] = {N6110_FRAME_HEADER, 0x07, 0x02,
540 0x00, /* Location */
541 0x01, 0x64};
542
543 if (sms->SMS[0].Folder!=0x00) return ERR_NOTSUPPORTED;
544
545 req[5] = sms->SMS[0].Location;
546
547 s->Phone.Data.GetSMSMessage=sms;
548 smprintf(s, "Getting sms\n");
549 return GSM_WaitFor (s, req, 8, 0x02, 4, ID_GetSMSMessage);
550}
551
552static GSM_Error N6110_GetNextSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start)
553{
554 GSM_Phone_N6110Data *Priv = &s->Phone.Data.Priv.N6110;
555 GSM_Error error;
556
557 if (start) {
558 error=s->Phone.Functions->GetSMSStatus(s,&Priv->LastSMSStatus);
559 if (error!=ERR_NONE) return error;
560 Priv->LastSMSRead=0;
561 sms->SMS[0].Location=0;
562 }
563 while (true) {
564 sms->SMS[0].Location++;
565 if (Priv->LastSMSRead>=(Priv->LastSMSStatus.SIMUsed+Priv->LastSMSStatus.PhoneUsed+Priv->LastSMSStatus.TemplatesUsed)) return ERR_EMPTY;
566 error=s->Phone.Functions->GetSMS(s, sms);
567 if (error==ERR_NONE) {
568 Priv->LastSMSRead++;
569 break;
570 }
571 if (error != ERR_EMPTY) return error;
572 }
573 return error;
574}
575
576static GSM_Error N6110_ReplyGetStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
577{
578 GSM_Phone_Data *Data = &s->Phone.Data;
579
580#ifdef DEBUG
581 smprintf(s, "Phone status received :\n");
582 smprintf(s, "Mode : ");
583 switch (msg.Buffer[4]) {
584 case 0x01: smprintf(s, "registered within the network\n"); break;
585 case 0x02: smprintf(s, "call in progress\n"); break; /* ringing or already answered call */
586 case 0x03: smprintf(s, "waiting for security code\n"); break;
587 case 0x04: smprintf(s, "powered off\n"); break;
588 default : smprintf(s, "unknown\n");
589 }
590 smprintf(s, "Power source : ");
591 switch (msg.Buffer[7]) {
592 case 0x01: smprintf(s, "AC/DC\n"); break;
593 case 0x02: smprintf(s, "battery\n"); break;
594 default : smprintf(s, "unknown\n");
595 }
596 smprintf(s, "Battery Level : %d\n", msg.Buffer[8]);
597 smprintf(s, "Signal strength : %d\n", msg.Buffer[5]);
598#endif
599
600 switch (Data->RequestID) {
601 case ID_GetBatteryCharge:
602 Data->BatteryCharge->BatteryPercent = ((int)msg.Buffer[8])*25;
603 switch (msg.Buffer[7]) {
604 case 0x01: Data->BatteryCharge->ChargeState = GSM_BatteryConnected; break;
605 case 0x02: Data->BatteryCharge->ChargeState = GSM_BatteryPowered; break;
606 default : Data->BatteryCharge->ChargeState = 0;
607 }
608 return ERR_NONE;
609 case ID_GetSignalQuality:
610 Data->SignalQuality->SignalPercent = ((int)msg.Buffer[5])*25;
611 return ERR_NONE;
612 default:
613 return ERR_UNKNOWNRESPONSE;
614 }
615}
616
617static GSM_Error N6110_GetStatus(GSM_StateMachine *s, int ID)
618{
619 unsigned char req[] = {N6110_FRAME_HEADER, 0x01};
620
621 return GSM_WaitFor (s, req, 4, 0x04, 4, ID);
622}
623
624static GSM_Error N6110_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig)
625{
626 char value[100];
627 GSM_Error error;
628
629 sig->BitErrorRate = -1;
630 sig->SignalStrength = -1; /* TODO for netmon */
631
632 smprintf(s, "Getting network level\n");
633 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_POWER_BATT)) {
634 error = DCT3_Netmonitor(s, 1, value);
635 if (error!=ERR_NONE) return error;
636 sig->SignalPercent = 100;
637 if (value[4]!='-') {
638 if (value[5]=='9' && value[6]>'4') sig->SignalPercent = 25;
639 if (value[5]=='9' && value[6]<'5') sig->SignalPercent = 50;
640 if (value[5]=='8' && value[6]>'4') sig->SignalPercent = 75;
641 } else sig->SignalPercent = 0;
642 return ERR_NONE;
643 } else {
644 s->Phone.Data.SignalQuality = sig;
645 return N6110_GetStatus(s, ID_GetSignalQuality);
646 }
647}
648
649static GSM_Error N6110_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat)
650{
651 char value[100];
652 GSM_Error error;
653
654 smprintf(s, "Getting battery level\n");
655 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_POWER_BATT)) {
656 error = DCT3_Netmonitor(s, 23, value);
657 if (error!=ERR_NONE) return error;
658 bat->BatteryPercent = 100;
659 bat->ChargeState = 0;
660 if (value[29]=='7') bat->BatteryPercent = 75;
661 if (value[29]=='5') bat->BatteryPercent = 50;
662 if (value[29]=='2') bat->BatteryPercent = 25;
663 return ERR_NONE;
664 } else {
665 s->Phone.Data.BatteryCharge = bat;
666 return N6110_GetStatus(s, ID_GetBatteryCharge);
667 }
668}
669
670static GSM_Error N6110_ReplySaveSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
671{
672 GSM_Phone_Data *Data = &s->Phone.Data;
673
674 smprintf(s, "SMS message saving status\n");
675 switch (msg.Buffer[3]) {
676 case 0x05:
677 smprintf(s, "Saved at location %i\n",msg.Buffer[5]);
678 Data->SaveSMSMessage->Location=msg.Buffer[5];
679 return ERR_NONE;
680 case 0x06:
681 switch (msg.Buffer[4]) {
682 case 0x02:
683 smprintf(s, "All locations busy\n");
684 return ERR_FULL;
685 case 0x03:
686 smprintf(s, "Too high ?\n");
687 return ERR_INVALIDLOCATION;
688 default:
689 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
690 }
691 }
692 return ERR_UNKNOWNRESPONSE;
693}
694
695static GSM_Error N6110_PrivSetSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
696{
697 int length;
698 GSM_Error error;
699 unsigned char req[256] = {N6110_FRAME_HEADER, 0x04,
700 0x00, /* SMS status */
701 0x02,
702 0x00, /* SMS location */
703 0x02}; /* SMS type */
704
705 req[6] = sms->Location;
706 if (sms->Folder==1) { /* Inbox */
707 req[4] = 1; /* SMS status - GSM_Read */
708 req[7] = 0x00; /* SMS type */
709 sms->PDU = SMS_Deliver;
710 error=PHONE_EncodeSMSFrame(s,sms,req+8,PHONE_SMSDeliver,&length,true);
711 } else { /* Outbox */
712 req[4] = 5; /* SMS status - GSM_Sent */
713 req[7] = 0x02; /* SMS type */
714 sms->PDU = SMS_Submit;
715 error=PHONE_EncodeSMSFrame(s,sms,req+8,PHONE_SMSSubmit,&length,true);
716 }
717 if (error != ERR_NONE) return error;
718
719 /* SMS State - GSM_Read -> GSM_Unread and GSM_Sent -> GSM_UnSent */
720 if (sms->State == SMS_UnSent || sms->State == SMS_UnRead) req[4] |= 0x02;
721
722 s->Phone.Data.SaveSMSMessage=sms;
723 smprintf(s, "Saving sms\n");
724 return GSM_WaitFor (s, req, 8+length, 0x14, 4, ID_SaveSMSMessage);
725}
726
727static GSM_Error N6110_SetSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
728{
729 if (sms->Location == 0) return ERR_INVALIDLOCATION;
730 return N6110_PrivSetSMSMessage(s, sms);
731}
732
733static GSM_Error N6110_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
734{
735 sms->Location = 0;
736 return N6110_PrivSetSMSMessage(s, sms);
737}
738
739static GSM_Error N6110_ReplySetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
740{
741 switch (msg.Buffer[3]) {
742 case 0x37:
743 smprintf(s, "Ringtone set OK\n");
744 return ERR_NONE;
745 break;
746 case 0x38:
747 smprintf(s, "Error setting ringtone\n");
748 switch (msg.Buffer[4]) {
749 case 0x7d:
750 smprintf(s, "Too high location ?\n");
751 return ERR_INVALIDLOCATION;
752 default:
753 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
754 }
755 }
756 return ERR_UNKNOWNRESPONSE;
757}
758
759static GSM_Error N6110_ReplySetBinRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
760{
761 switch (msg.Buffer[4]) {
762 case 0x00:
763 smprintf(s, "Set at location %i\n",msg.Buffer[3]+1);
764 return ERR_NONE;
765 default:
766 smprintf(s, "Invalid location. Too high ?\n");
767 return ERR_INVALIDLOCATION;
768 }
769}
770
771static GSM_Error N6110_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
772{
773 GSM_NetworkInfo NetInfo;
774 GSM_Error error;
775 int size=200,current=8;
776 GSM_UDHHeader UDHHeader;
777 unsigned char req[1000] = {N6110_FRAME_HEADER, 0x36,
778 0x00, /* Location */
779 0x00,0x78};
780 unsigned char reqBin[1000] = {0x00,0x01,0xa0,0x00,0x00,0x0c,0x01,0x2c};
781
782 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NORING)) return ERR_NOTSUPPORTED;
783 if (Ringtone->Location == 0) return ERR_INVALIDLOCATION;
784
785 switch (Ringtone->Format) {
786 case RING_NOTETONE:
787 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) {
791 req[0] = 0x0c;
792 req[1] = 0x01;
793 UDHHeader.Type = UDH_NokiaRingtone;
794 GSM_EncodeUDHHeader(&UDHHeader);
795 /* We copy UDH now */
796 memcpy(req+2,UDHHeader.Text,UDHHeader.Length);
797 *maxlength=GSM_EncodeNokiaRTTLRingtone(*Ringtone, req+2+UDHHeader.Length, &size);
798 error = s->Protocol.Functions->WriteMessage(s, req, 2+UDHHeader.Length+size, 0x12);
799 if (error!=ERR_NONE) return error;
800 my_sleep(1000);
801 /* We have to make something (not important, what) now */
802 /* no answer from phone*/
803 return DCT3_GetNetworkInfo(s,&NetInfo);
804 } else {
805 return ERR_NOTSUPPORTED;
806 }
807 }
808 *maxlength=GSM_EncodeNokiaRTTLRingtone(*Ringtone, req+7, &size);
809 req[4] = Ringtone->Location - 1;
810 smprintf(s, "Setting ringtone\n");
811 return GSM_WaitFor (s, req, 7 + size, 0x05, 4, ID_SetRingtone);
812 case RING_NOKIABINARY:
813 error=DCT3_EnableSecurity (s, 0x01);
814 if (error!=ERR_NONE) return error;
815 memcpy(reqBin+current,DecodeUnicodeString(Ringtone->Name),UnicodeLength(Ringtone->Name));
816 current += UnicodeLength(Ringtone->Name);
817 reqBin[current++] = 0x00;
818 reqBin[current++] = 0x00;
819 reqBin[current++] = 0x00;/*xxx*/
820 memcpy(reqBin+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length);
821 current=current+Ringtone->NokiaBinary.Length;
822 reqBin[3]=Ringtone->Location-1;
823 if (!strcmp(s->Phone.Data.ModelInfo->model,"3210")) reqBin[5]=0x10;
824 smprintf(s, "Setting binary ringtone\n");
825 return GSM_WaitFor (s, reqBin, current, 0x40, 4, ID_SetRingtone);
826 case RING_MIDI:
827 return ERR_NOTSUPPORTED;
828 }
829 return ERR_NOTSUPPORTED;
830}
831
832static GSM_Error N6110_ReplyGetOpLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
833{
834 int count=5;
835 GSM_Phone_Data *Data = &s->Phone.Data;
836
837 smprintf(s, "Operator logo received\n");
838 NOKIA_DecodeNetworkCode(msg.Buffer+count,Data->Bitmap->NetworkCode);
839 count = count + 3;
840 smprintf(s, "Network code : %s\n", Data->Bitmap->NetworkCode);
841 smprintf(s, "Network name for Gammu : %s ",
842 DecodeUnicodeString(GSM_GetNetworkName(Data->Bitmap->NetworkCode)));
843 smprintf(s, "(%s)\n",DecodeUnicodeString(GSM_GetCountryName(Data->Bitmap->NetworkCode)));
844
845 count = count + 3; /* We ignore size */
846 Data->Bitmap->BitmapWidth = msg.Buffer[count++];
847 Data->Bitmap->BitmapHeight = msg.Buffer[count++];
848 count++;
849 PHONE_DecodeBitmap(GSM_NokiaOperatorLogo,msg.Buffer+count,Data->Bitmap);
850 return ERR_NONE;
851}
852
853static GSM_Error N6110_ReplyGetStartup(GSM_Protocol_Message msg, GSM_StateMachine *s)
854{
855 int i, count = 5;
856 GSM_Phone_Data *Data = &s->Phone.Data;
857
858 smprintf(s, "Startup logo & notes received\n");
859 for (i=0;i<msg.Buffer[4];i++) {
860 switch (msg.Buffer[count++]) {
861 case 0x01:
862 smprintf(s, "Startup logo\n");
863 if (Data->Bitmap->Type == GSM_StartupLogo) {
864 Data->Bitmap->BitmapHeight = msg.Buffer[count++];
865 Data->Bitmap->BitmapWidth = msg.Buffer[count++];
866 PHONE_DecodeBitmap(GSM_NokiaStartupLogo, msg.Buffer + count, Data->Bitmap);
867 } else {
868 count = count + 2;
869 }
870 count = count + PHONE_GetBitmapSize(GSM_NokiaStartupLogo,0,0);
871 break;
872 case 0x02:
873 smprintf(s, "Welcome note\n");
874 if (Data->Bitmap->Type == GSM_WelcomeNote_Text) {
875 EncodeUnicode(Data->Bitmap->Text,msg.Buffer+count, msg.Buffer[count]);
876 smprintf(s, "Text is \"%s\"\n",Data->Bitmap->Text);
877 }
878 count = count + msg.Buffer[count] + 1;
879 break;
880 case 0x03:
881 smprintf(s, "Dealer welcome note\n");
882 if (Data->Bitmap->Type == GSM_DealerNote_Text) {
883 EncodeUnicode(Data->Bitmap->Text,msg.Buffer+count, msg.Buffer[count]);
884 smprintf(s, "Text is \"%s\"\n",Data->Bitmap->Text);
885 }
886 count = count + msg.Buffer[count] + 1;
887 break;
888 default:
889 smprintf(s, "Unknown block\n");
890 return ERR_UNKNOWNRESPONSE;
891 break;
892 }
893 }
894 return ERR_NONE;
895}
896
897static GSM_Error N6110_ReplyGetCallerLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
898{
899 int count;
900 GSM_Phone_Data *Data = &s->Phone.Data;
901
902 switch (msg.Buffer[3]) {
903 case 0x11:
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->RingtoneID = msg.Buffer[count++];
911 Data->Bitmap->DefaultRingtone = false;
912 Data->Bitmap->FileSystemRingtone = false;
913 if (Data->Bitmap->RingtoneID == 16) Data->Bitmap->DefaultRingtone = true;
914 smprintf(s, "Ringtone ID: %02x\n",Data->Bitmap->RingtoneID);
915 Data->Bitmap->BitmapEnabled=(msg.Buffer[count++]==1);
916#ifdef DEBUG
917 smprintf(s, "Caller group logo ");
918 if (Data->Bitmap->BitmapEnabled) {
919 smprintf(s, "enabled\n");
920 } else {
921 smprintf(s, "disabled\n");
922 }
923#endif
924 count = count + 3; /* We ignore size */
925 Data->Bitmap->BitmapWidth = msg.Buffer[count++];
926 Data->Bitmap->BitmapHeight = msg.Buffer[count++];
927 count++;
928 PHONE_DecodeBitmap(GSM_NokiaCallerLogo,msg.Buffer+count,Data->Bitmap);
929 Data->Bitmap->DefaultBitmap = false;
930 return ERR_NONE;
931 case 0x12:
932 smprintf(s, "Error getting caller group info\n");
933 return ERR_INVALIDLOCATION;
934 }
935 return ERR_UNKNOWNRESPONSE;
936}
937
938static GSM_Error N6110_ReplyGetSetPicture(GSM_Protocol_Message msg, GSM_StateMachine *s)
939{
940 int count = 5, i;
941 GSM_Phone_Data *Data = &s->Phone.Data;
942
943 switch (msg.Buffer[3]) {
944 case 0x02:
945 smprintf(s, "Picture Image received\n");
946 if (msg.Buffer[count]!=0) {
947 GSM_UnpackSemiOctetNumber(Data->Bitmap->Sender, msg.Buffer + 5, true);
948 /* Convert number of semioctets to number of chars */
949 i = msg.Buffer[5];
950 if (i % 2) i++;
951 i=i / 2 + 1;
952 count = count + i + 1;
953 } else {
954 Data->Bitmap->Sender[0] = 0x00;
955 Data->Bitmap->Sender[1] = 0x00;
956 count+=2;
957 }
958 smprintf(s, "Sender : \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Sender));
959 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOPICTUREUNI) ||
960 (!strcmp(Data->Model,"NHM-5") && Data->VerNum < 5.79)) {
961 count++;
962 EncodeUnicode(Data->Bitmap->Text,msg.Buffer+count+1,msg.Buffer[count]);
963 count += UnicodeLength(Data->Bitmap->Text) + 1;
964 } else {
965 if (!strcmp(Data->Model,"NHM-5")) {
966 i = msg.Buffer[count] * 256 + msg.Buffer[count+1];
967 } else {
968 /* 3410 4.26 */
969 i = msg.Buffer[count] * 256 + msg.Buffer[count+1] - 2;
970 count += 2;
971 }
972 memcpy(Data->Bitmap->Text,msg.Buffer+count+2,i);
973 Data->Bitmap->Text[i] = 0;
974 Data->Bitmap->Text[i+1] = 0;
975 count += i + 2;
976 }
977 smprintf(s, "Text : \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text));
978 Data->Bitmap->BitmapWidth = msg.Buffer[count++];
979 Data->Bitmap->BitmapHeight = msg.Buffer[count++];
980 PHONE_DecodeBitmap(GSM_NokiaPictureImage, msg.Buffer + count + 2, Data->Bitmap);
981#ifdef DEBUG
982 if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,Data->Bitmap);
983#endif
984 return ERR_NONE;
985 break;
986 case 0x04:
987 smprintf(s, "Picture Image set OK\n");
988 return ERR_NONE;
989 case 0x05:
990 smprintf(s, "Can't set Picture Image - invalid location ?\n");
991 return ERR_INVALIDLOCATION;
992 break;
993 case 0x06:
994 smprintf(s, "Can't get Picture Image - invalid location ?\n");
995 return ERR_INVALIDLOCATION;
996 break;
997 }
998 return ERR_UNKNOWNRESPONSE;
999}
1000
1001static GSM_Error N6110_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
1002{
1003 GSM_Error error;
1004 unsigned char req[10] = {N6110_FRAME_HEADER};
1005
1006 s->Phone.Data.Bitmap=Bitmap;
1007 switch (Bitmap->Type) {
1008 case GSM_StartupLogo:
1009 case GSM_WelcomeNote_Text:
1010 case GSM_DealerNote_Text:
1011 if (Bitmap->Type == GSM_StartupLogo && IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOSTARTUP)) return ERR_NOTSUPPORTED;
1012 req[3] = 0x16;
1013 return GSM_WaitFor (s, req, 4, 0x05, 4, ID_GetBitmap);
1014 case GSM_CallerGroupLogo:
1015 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOCALLER)) return ERR_NOTSUPPORTED;
1016 req[3] = 0x10;
1017 req[4] = Bitmap->Location - 1;
1018 error = GSM_WaitFor (s, req, 5, 0x03, 4, ID_GetBitmap);
1019 if (error==ERR_NONE) NOKIA_GetDefaultCallerGroupName(s,Bitmap);
1020 return error;
1021 case GSM_OperatorLogo:
1022 req[3] = 0x33;
1023 req[4] = 0x01;
1024 return GSM_WaitFor (s, req, 5, 0x05, 4, ID_GetBitmap);
1025 case GSM_PictureImage:
1026 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOPICTURE)) return ERR_NOTSUPPORTED;
1027 req[3] = 0x01;
1028 req[4] = Bitmap->Location - 1;
1029 return GSM_WaitFor (s, req, 5, 0x47, 4, ID_GetBitmap);
1030 default:
1031 break;
1032 }
1033 return ERR_NOTSUPPORTED;
1034}
1035
1036static GSM_Error N6110_ReplySetProfileFeature(GSM_Protocol_Message msg, GSM_StateMachine *s)
1037{
1038 switch (msg.Buffer[3]) {
1039 case 0x11:
1040 smprintf(s, "Feature of profile set\n");
1041 return ERR_NONE;
1042 case 0x12:
1043 smprintf(s, "Error setting profile feature\n");
1044 return ERR_NOTSUPPORTED;
1045 }
1046 return ERR_UNKNOWNRESPONSE;
1047}
1048
1049static GSM_Error N6110_SetProfileFeature(GSM_StateMachine *s, unsigned char profile, unsigned char feature, unsigned char value)
1050{
1051 unsigned char req[] = {N6110_FRAME_HEADER, 0x10, 0x01,
1052 0x00, /* Profile */
1053 0x00, /* Feature */
1054 0x00}; /* Value */
1055
1056 req[5]=profile;
1057 req[6]=feature;
1058 req[7]=value;
1059 smprintf(s, "Setting profile feature\n");
1060 return GSM_WaitFor (s, req, 8, 0x05, 4, ID_SetProfile);
1061}
1062
1063static GSM_Error N6110_ReplySetStartup(GSM_Protocol_Message msg, GSM_StateMachine *s)
1064{
1065 smprintf(s, "Startup logo set OK\n");
1066 return ERR_NONE;
1067}
1068
1069static GSM_Error N6110_ReplySetCallerLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
1070{
1071 switch (msg.Buffer[3]) {
1072 case 0x14:
1073 smprintf(s, "Caller group set OK\n");
1074 return ERR_NONE;
1075 case 0x15:
1076 smprintf(s, "Error setting caller group\n");
1077 return ERR_INVALIDLOCATION;
1078 }
1079 return ERR_UNKNOWNRESPONSE;
1080}
1081
1082static GSM_Error N6110_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
1083{
1084 unsigned char reqPreview[1000] = {0x0c,0x01};
1085 unsigned char req[600] = {N6110_FRAME_HEADER};
1086 GSM_UDH UDHType = UDH_NokiaOperatorLogo;
1087 int count = 0, textlen, Width, Height;
1088 GSM_UDHHeader UDHHeader;
1089 GSM_NetworkInfo NetInfo;
1090 GSM_Error error;
1091
1092 switch (Bitmap->Type) {
1093 case GSM_CallerGroupLogo:
1094 case GSM_OperatorLogo:
1095 if (Bitmap->Location == 255) {
1096 /* Only 6110, 6130 and 6150 support it */
1097 if (strcmp(s->Phone.Data.Model,"NSE-3") == 0 || strcmp(s->Phone.Data.Model,"NSK-3") == 0 ||
1098 strcmp(s->Phone.Data.Model,"NSM-1") == 0) {
1099 if (Bitmap->Type==GSM_CallerGroupLogo) UDHType = UDH_NokiaCallerLogo;
1100 UDHHeader.Type = UDHType;
1101 GSM_EncodeUDHHeader(&UDHHeader);
1102 /* We copy UDH now */
1103 memcpy(reqPreview+2,UDHHeader.Text,UDHHeader.Length);
1104 count = count + UDHHeader.Length;
1105 if (Bitmap->Type == GSM_OperatorLogo) {
1106 NOKIA_EncodeNetworkCode(reqPreview+count,Bitmap->NetworkCode);
1107 count = count + 3;
1108 } else {
1109 if (Bitmap->DefaultBitmap) {
1110 Bitmap->BitmapWidth = 72;
1111 Bitmap->BitmapHeight = 14;
1112 GSM_ClearBitmap(Bitmap);
1113 }
1114 }
1115 NOKIA_CopyBitmap(GSM_NokiaOperatorLogo,Bitmap,reqPreview, &count);
1116 reqPreview[count]=0x00;
1117 error = s->Protocol.Functions->WriteMessage(s, reqPreview, count + 1, 0x12);
1118 if (error!=ERR_NONE) return error;
1119 my_sleep(1000);
1120 /* We have to make something (not important, what) now */
1121 /* no answer from phone*/
1122 return DCT3_GetNetworkInfo(s,&NetInfo);
1123 } else {
1124 smprintf(s, "%s\n",s->Phone.Data.Model);
1125 return ERR_NOTSUPPORTED;
1126 }
1127 }
1128 break;
1129 default:
1130 break;
1131 }
1132
1133 count = 3;
1134
1135 switch (Bitmap->Type) {
1136 case GSM_StartupLogo:
1137 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOSTARTUP)) return ERR_NOTSUPPORTED;
1138 if (Bitmap->Location != 1) {
1139 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOSTARTANI)) return ERR_NOTSUPPORTED;
1140 }
1141 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOSTARTANI)) {
1142 if (!strcmp(s->Phone.Data.ModelInfo->model,"3210")) {
1143 error = N6110_SetProfileFeature(s,0,0x2e,((unsigned char)(Bitmap->Location-1)));
1144 } else {
1145 error = N6110_SetProfileFeature(s,0,0x29,((unsigned char)(Bitmap->Location-1)));
1146 }
1147 if (error == ERR_NOTSUPPORTED) error = ERR_SECURITYERROR;
1148 if (error != ERR_NONE) return error;
1149 if (Bitmap->Location != 1) return ERR_NONE;
1150 }
1151 req[count++] = 0x18;
1152 req[count++] = 0x01; /* One block */
1153 req[count++] = 0x01;
1154 PHONE_GetBitmapWidthHeight(GSM_NokiaStartupLogo, &Width, &Height);
1155 req[count++] = Height;
1156 req[count++] = Width;
1157 PHONE_EncodeBitmap(GSM_NokiaStartupLogo, req + count, Bitmap);
1158 count = count + PHONE_GetBitmapSize(GSM_NokiaStartupLogo,0,0);
1159 return GSM_WaitFor (s, req, count, 0x05, 4, ID_SetBitmap);
1160 case GSM_WelcomeNote_Text:
1161 case GSM_DealerNote_Text:
1162 req[count++] = 0x18;
1163 req[count++] = 0x01; /* One block */
1164 if (Bitmap->Type == GSM_WelcomeNote_Text) {
1165 req[count++] = 0x02;
1166 } else {
1167 req[count++] = 0x03;
1168 }
1169 textlen = UnicodeLength(Bitmap->Text);
1170 req[count++] = textlen;
1171 memcpy(req + count,DecodeUnicodeString(Bitmap->Text),textlen);
1172 count += textlen;
1173 return GSM_WaitFor (s, req, count, 0x05, 4, ID_SetBitmap);
1174 case GSM_CallerGroupLogo:
1175 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOCALLER)) return ERR_NOTSUPPORTED;
1176 req[count++] = 0x13;
1177 req[count++] = Bitmap->Location - 1;
1178 if (Bitmap->DefaultName) {
1179 req[count++] = 0;
1180 } else {
1181 textlen = UnicodeLength(Bitmap->Text);
1182 req[count++] = textlen;
1183 memcpy(req+count,DecodeUnicodeString(Bitmap->Text),textlen);
1184 count += textlen;
1185 }
1186 if (Bitmap->DefaultRingtone) {
1187 req[count++] = 16;
1188 } else {
1189 req[count++] = Bitmap->RingtoneID;
1190 }
1191 /* Value here is number of phone menu connected
1192 * with caller logo in Nokia 61x0: 0x00 = Off, 0x01 = On,
1193 * 0x02 = View Graphics, 0x03 = Send Graphics,
1194 * 0x04 = Send via IR. For higher menu option connected with
1195 * caller logo is not displayed
1196 */
1197 if (Bitmap->DefaultBitmap) {
1198 Bitmap->BitmapWidth = 72;
1199 Bitmap->BitmapHeight = 14;
1200 GSM_ClearBitmap(Bitmap);
1201 req[count++] = 0;
1202 } else {
1203 if (Bitmap->BitmapEnabled) req[count++] = 0x01; else req[count++] = 0x00;
1204 }
1205 req[count++] = (PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 4) / 256;
1206 req[count++] = (PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 4) % 256;
1207 NOKIA_CopyBitmap(GSM_NokiaCallerLogo, Bitmap, req, &count);
1208 return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetBitmap);
1209 case GSM_OperatorLogo:
1210 req[count++] = 0x30;
1211 req[count++] = 0x01;
1212 NOKIA_EncodeNetworkCode(req+count, Bitmap->NetworkCode);
1213 count = count + 3;
1214 req[count++] = (PHONE_GetBitmapSize(GSM_NokiaOperatorLogo,0,0) + 4) / 256;
1215 req[count++] = (PHONE_GetBitmapSize(GSM_NokiaOperatorLogo,0,0) + 4) % 256;
1216 NOKIA_CopyBitmap(GSM_NokiaOperatorLogo, Bitmap, req, &count);
1217 return GSM_WaitFor (s, req, count, 0x05, 4, ID_SetBitmap);
1218 case GSM_PictureImage:
1219 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NOPICTURE)) return ERR_NOTSUPPORTED;
1220 req[count++] = 0x03;
1221 req[count++] = Bitmap->Location - 1;
1222 if (Bitmap->Sender[0]!=0 || Bitmap->Sender[1]!=0) {
1223 req[count]=GSM_PackSemiOctetNumber(Bitmap->Sender, req+count+1,true);
1224 /* Convert number of semioctets to number of chars and add count */
1225 textlen = req[count];
1226 if (textlen % 2) textlen++;
1227 count += textlen / 2 + 1;
1228 count++;
1229 } else {
1230 req[count++] = 0x00;
1231 req[count++] = 0x00;
1232 }
1233 req[count++] = 0x00;
1234 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOPICTUREUNI) ||
1235 (!strcmp(s->Phone.Data.Model,"NHM-5") && s->Phone.Data.VerNum < 5.79)) {
1236 textlen = UnicodeLength(Bitmap->Text);
1237 req[count++] = textlen;
1238 memcpy(req+count,DecodeUnicodeString(Bitmap->Text),textlen);
1239 count += textlen;
1240 } else {
1241 textlen = UnicodeLength(Bitmap->Text)*2;
1242 if (!strcmp(s->Phone.Data.Model,"NHM-5")) {
1243 req[count++] = textlen;
1244 } else {
1245 /* 3410 4.26 */
1246 req[count++] = textlen+2;
1247 req[count++] = 0x00;
1248 req[count++] = 0x1e;
1249 }
1250 memcpy(req+count,Bitmap->Text,textlen);
1251 count += textlen;
1252 }
1253 NOKIA_CopyBitmap(GSM_NokiaPictureImage, Bitmap, req, &count);
1254 return GSM_WaitFor (s, req, count, 0x47, 4, ID_SetBitmap);
1255 default:
1256 break;
1257 }
1258 return ERR_NOTSUPPORTED;
1259}
1260
1261static GSM_Error N6110_ReplyCallInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
1262{
1263 GSM_Phone_Data *Data = &s->Phone.Data;
1264 int tmp, count;
1265 GSM_Call call;
1266
1267 call.CallIDAvailable = true;
1268 call.Status = 0;
1269 smprintf(s, "Call info, ");
1270 switch (msg.Buffer[3]) {
1271 case 0x02:
1272 smprintf(s, "Call established, waiting for answer\n");
1273 call.Status = GSM_CALL_CallEstablished;
1274 break;
1275 case 0x03:
1276 smprintf(s, "Call started\n");
1277 /* no phone number in frame */
1278 call.Status = GSM_CALL_CallStart;
1279 break;
1280 case 0x04:
1281 smprintf(s, "Remote end hang up\n");
1282 smprintf(s, "CC : %i\n",msg.Buffer[6]);
1283 call.Status = GSM_CALL_CallRemoteEnd;
1284 call.StatusCode = msg.Buffer[6];
1285 break;
1286 case 0x05:
1287 smprintf(s, "Incoming call\n");
1288 smprintf(s, "Number : \"");
1289 count=msg.Buffer[6];
1290 for (tmp=0; tmp <count; tmp++) smprintf(s, "%c", msg.Buffer[7+tmp]);
1291 smprintf(s, "\"\nName : \"");
1292 for (tmp=0; tmp<msg.Buffer[7+count]; tmp++) smprintf(s, "%c", msg.Buffer[8+count+tmp]);
1293 smprintf(s, "\"\n");
1294
1295 call.Status = GSM_CALL_IncomingCall;
1296 EncodeUnicode(call.PhoneNumber, msg.Buffer+7, msg.Buffer[6]);
1297 break;
1298 case 0x07:
1299 smprintf(s, "Call answer initiated\n");
1300 break;
1301 case 0x09:
1302 smprintf(s, "Call released\n");
1303 call.Status = GSM_CALL_CallLocalEnd;
1304 break;
1305 case 0x0a:
1306 smprintf(s, "Call is being released\n");
1307 break;
1308 case 0x23:
1309 smprintf(s, "Call held\n");
1310 call.Status = GSM_CALL_CallHeld;
1311 break;
1312 case 0x25:
1313 smprintf(s, "Call resumed\n");
1314 call.Status = GSM_CALL_CallResumed;
1315 break;
1316 case 0x27:
1317 smprintf(s, "Call switched\n");
1318 /* incorrect call id in frame - 6150 5.22 */
1319 call.CallIDAvailable = false;
1320 call.Status = GSM_CALL_CallSwitched;
1321 break;
1322 case 0x29:
1323 smprintf(s, "Joining call to the conference (conference)\n");
1324 break;
1325 case 0x2A:
1326 smprintf(s, "Removing call from the conference (split)\n");
1327 break;
1328 }
1329 if (call.CallIDAvailable) smprintf(s, "Call ID : %d\n",msg.Buffer[4]);
1330 if (Data->EnableIncomingCall && s->User.IncomingCall!=NULL && call.Status != 0) {
1331 if (call.CallIDAvailable) call.CallID = msg.Buffer[4];
1332 s->User.IncomingCall(s->CurrentConfig->Device, call);
1333 }
1334 if (s->Phone.Data.RequestID == ID_CancelCall) {
1335 if (msg.Buffer[3] == 0x09) {
1336 if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE;
1337 /* when we canceled call and see frame about other
1338 * call releasing, we don't give ERR_NONE for "our"
1339 * call release command
1340 */
1341 return ERR_NEEDANOTHERANSWER;
1342 }
1343 }
1344 if (s->Phone.Data.RequestID == ID_AnswerCall) {
1345 if (msg.Buffer[3] == 0x07) {
1346 if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE;
1347 return ERR_NEEDANOTHERANSWER;
1348 }
1349 }
1350 if (s->Phone.Data.RequestID == ID_UnholdCall) {
1351 if (msg.Buffer[3] == 0x25) {
1352 if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE;
1353 return ERR_NEEDANOTHERANSWER;
1354 }
1355 }
1356 if (s->Phone.Data.RequestID == ID_HoldCall) {
1357 if (msg.Buffer[3] == 0x23) {
1358 if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE;
1359 return ERR_NEEDANOTHERANSWER;
1360 }
1361 }
1362 if (s->Phone.Data.RequestID == ID_ConferenceCall) {
1363 if (msg.Buffer[3] == 0x29) {
1364 if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE;
1365 return ERR_NEEDANOTHERANSWER;
1366 }
1367 }
1368 if (s->Phone.Data.RequestID == ID_SplitCall) {
1369 if (msg.Buffer[3] == 0x2B) {
1370 if (s->Phone.Data.CallID == msg.Buffer[4]) return ERR_NONE;
1371 return ERR_NEEDANOTHERANSWER;
1372 }
1373 }
1374 return ERR_NONE;
1375}
1376
1377static GSM_Error N6110_DeleteSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
1378{
1379 unsigned char req[] = {N6110_FRAME_HEADER, 0x0a, 0x02,
1380 0x00}; /* Location */
1381
1382 if (sms->Folder!=0x00) return ERR_NOTSUPPORTED;
1383
1384 req[5]=sms->Location;
1385
1386 smprintf(s, "Deleting sms\n");
1387 return GSM_WaitFor (s, req, 6, 0x14, 4, ID_DeleteSMSMessage);
1388}
1389
1390static GSM_Error N6110_ReplySetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s)
1391{
1392 smprintf(s, "Reply for writing memory\n");
1393 switch (msg.Buffer[3]) {
1394 case 0x05:
1395 smprintf(s, "Done OK\n");
1396 return ERR_NONE;
1397 case 0x06:
1398 smprintf(s, "Error\n");
1399 switch (msg.Buffer[4]) {
1400 case 0x7d:
1401 smprintf(s, "Too high location ?\n");
1402 return ERR_INVALIDLOCATION;
1403 case 0x90:
1404 smprintf(s, "Too long name...or other error\n");
1405 return ERR_NOTSUPPORTED;
1406 default:
1407 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
1408 }
1409 }
1410 return ERR_UNKNOWNRESPONSE;
1411}
1412
1413static GSM_Error N6110_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1414{
1415 int current, Group, Name, Number;
1416 unsigned char req[128] = {N6110_FRAME_HEADER, 0x04,
1417 0x00, /* memory type */
1418 0x00}; /* location */
1419
1420 if (entry->Location == 0) return ERR_NOTSUPPORTED;
1421
1422 GSM_PhonebookFindDefaultNameNumberGroup(entry, &Name, &Number, &Group);
1423
1424 req[4] = NOKIA_GetMemoryType(s, entry->MemoryType,N6110_MEMORY_TYPES);
1425 req[5] = entry->Location;
1426
1427 current = 7;
1428
1429 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOPBKUNICODE)) {
1430 if (Name != -1) {
1431 req[6] = UnicodeLength(entry->Entries[Name].Text);
1432 memcpy(req+current,DecodeUnicodeString(entry->Entries[Name].Text),UnicodeLength(entry->Entries[Name].Text));
1433 current += UnicodeLength(entry->Entries[Name].Text);
1434 } else req[6] = 0;
1435 } else {
1436 if (Name != -1) {
1437 req[6] = UnicodeLength(entry->Entries[Name].Text)*2+2;
1438 memcpy(req+current,entry->Entries[Name].Text,UnicodeLength(entry->Entries[Name].Text)*2);
1439 current += UnicodeLength(entry->Entries[Name].Text)*2;
1440 } else req[6] = 0;
1441 req[current++]=0x00;
1442 req[current++]=0x00;
1443 }
1444
1445 if (Number != -1) {
1446 req[current++]=UnicodeLength(entry->Entries[Number].Text);
1447 memcpy(req+current,DecodeUnicodeString(entry->Entries[Number].Text),UnicodeLength(entry->Entries[Number].Text));
1448 current += UnicodeLength(entry->Entries[Number].Text);
1449 } else req[current++] = 0;
1450
1451 /* This allow to save 14 characters name into SIM memory, when
1452 * no caller group is selected. */
1453 if (Group == -1) {
1454 req[current++] = 0xff;
1455 } else {
1456 req[current++] = entry->Entries[Group].Number-1;
1457 }
1458
1459 smprintf(s, "Writing phonebook entry\n");
1460 return GSM_WaitFor (s, req, current, 0x03, 4, ID_SetMemory);
1461}
1462
1463static GSM_Error N6110_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1464{
1465 GSM_MemoryEntry dwa;
1466
1467 dwa.Location = entry->Location;
1468 dwa.MemoryType = entry->MemoryType;
1469 dwa.EntriesNum = 0;
1470
1471 return N6110_SetMemory(s, &dwa);
1472}
1473
1474static GSM_Error N6110_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
1475{
1476 GSM_Phone_Data *Data = &s->Phone.Data;
1477 char buffer[2000];
1478 GSM_Error error;
1479 int i,end,start;
1480
1481 smprintf(s, "Ringtone received\n");
1482 switch (msg.Buffer[4]) {
1483 case 0x00:
1484 switch (Data->Ringtone->Format) {
1485 case RING_NOTETONE:
1486 memcpy(buffer,msg.Buffer,msg.Length);
1487 i=7;
1488 if (buffer[9]==0x4a && buffer[10]==0x3a) i=8;
1489 buffer[i]=0x02;
1490 error=GSM_DecodeNokiaRTTLRingtone(Data->Ringtone, buffer+i, msg.Length-i);
1491 if (error!=ERR_NONE) return ERR_EMPTY;
1492 return ERR_NONE;
1493 case RING_NOKIABINARY:
1494 i=8;
1495 while (msg.Buffer[i]!=0) {
1496 i++;
1497 if (i>msg.Length) return ERR_EMPTY;
1498 }
1499 EncodeUnicode(Data->Ringtone->Name,msg.Buffer+8,i-8);
1500 smprintf(s, "Name \"%s\"\n",DecodeUnicodeString(Data->Ringtone->Name));
1501 /* Looking for start && end */
1502 end=0;start=0;i=0;
1503 while (true) {
1504 if (start!=0) {
1505 if (msg.Buffer[i]==0x07 && msg.Buffer[i+1]==0x0b) {
1506 end=i+2; break;
1507 }
1508 if (msg.Buffer[i]==0x0e && msg.Buffer[i+1]==0x0b) {
1509 end=i+2; break;
1510 }
1511 } else {
1512 if (msg.Buffer[i]==0x02 && msg.Buffer[i+1]==0xfc && msg.Buffer[i+2]==0x09) {
1513 start = i;
1514 }
1515 }
1516 i++;
1517 if (i==msg.Length-3) return ERR_EMPTY;
1518 }
1519 /* Copying frame */
1520 memcpy(Data->Ringtone->NokiaBinary.Frame,msg.Buffer+start,end-start);
1521 Data->Ringtone->NokiaBinary.Length=end-start;
1522#ifdef DEBUG
1523 if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) DumpMessage(di.df, di.dl, Data->Ringtone->NokiaBinary.Frame, Data->Ringtone->NokiaBinary.Length);
1524#endif
1525 return ERR_NONE;
1526 case RING_MIDI:
1527 return ERR_NOTSUPPORTED;
1528 }
1529 smprintf(s, "Ringtone format is %i\n",Data->Ringtone->Format);
1530 break;
1531 default:
1532 smprintf(s, "Invalid location. Too high ?\n");
1533 return ERR_INVALIDLOCATION;
1534 }
1535 return ERR_UNKNOWNRESPONSE;
1536}
1537
1538static GSM_Error N6110_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone)
1539{
1540 GSM_Error error;
1541 unsigned char req[] = {0x00, 0x01, 0x9e,
1542 0x00}; /* location */
1543
1544 if (PhoneRingtone) return ERR_NOTSUPPORTED;
1545 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_NORING)) return ERR_NOTSUPPORTED;
1546 if (Ringtone->Location == 0) return ERR_INVALIDLOCATION;
1547
1548 if (Ringtone->Format == 0x00) {
1549 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_RING_SM)) {
1550 Ringtone->Format = RING_NOTETONE;
1551 } else {
1552 Ringtone->Format = RING_NOKIABINARY;
1553 }
1554 }
1555
1556 switch (Ringtone->Format) {
1557 case RING_NOTETONE:
1558 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_RING_SM)) return ERR_NOTSUPPORTED;
1559 break;
1560 case RING_NOKIABINARY:
1561 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_RING_SM)) return ERR_NOTSUPPORTED;
1562 break;
1563 case RING_MIDI:
1564 return ERR_NOTSUPPORTED;
1565 }
1566
1567 error=DCT3_EnableSecurity (s, 0x01);
1568 if (error!=ERR_NONE) return error;
1569
1570 req[3]=Ringtone->Location-1;
1571 s->Phone.Data.Ringtone=Ringtone;
1572 smprintf(s, "Getting (binary) ringtone\n");
1573 return GSM_WaitFor (s, req, 4, 0x40, 4, ID_GetRingtone);
1574}
1575
1576static GSM_Error N6110_ReplyGetSecurityStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
1577{
1578 *s->Phone.Data.SecurityStatus = msg.Buffer[4];
1579
1580#ifdef DEBUG
1581 smprintf(s, "Security code status\n");
1582 switch(msg.Buffer[4]) {
1583 case SEC_SecurityCode: smprintf(s, "waiting for Security Code.\n"); break;
1584 case SEC_Pin : smprintf(s, "waiting for PIN.\n"); break;
1585 case SEC_Pin2 : smprintf(s, "waiting for PIN2.\n"); break;
1586 case SEC_Puk : smprintf(s, "waiting for PUK.\n"); break;
1587 case SEC_Puk2 : smprintf(s, "waiting for PUK2.\n"); break;
1588 case SEC_None : smprintf(s, "nothing to enter.\n"); break;
1589 default : smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
1590 return ERR_UNKNOWNRESPONSE;
1591 }
1592#endif
1593 return ERR_NONE;
1594}
1595
1596static GSM_Error N6110_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status)
1597{
1598 unsigned char req[4] = {N6110_FRAME_HEADER, 0x07};
1599
1600 s->Phone.Data.SecurityStatus=Status;
1601 smprintf(s, "Getting security code status\n");
1602 return GSM_WaitFor (s, req, 4, 0x08, 2, ID_GetSecurityStatus);
1603}
1604
1605static GSM_Error N6110_ReplyEnterSecurityCode(GSM_Protocol_Message msg, GSM_StateMachine *s)
1606{
1607 switch (msg.Buffer[3]) {
1608 case 0x0b:
1609 smprintf(s, "Security code OK\n");
1610 return ERR_NONE;
1611 case 0x0c:
1612 switch (msg.Buffer[4]) {
1613 case 0x88:
1614 smprintf(s, "Wrong code\n");
1615 return ERR_SECURITYERROR;
1616 case 0x8b:
1617 smprintf(s, "Not required\n");
1618 return ERR_NONE;
1619 default:
1620 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
1621 }
1622 }
1623 return ERR_UNKNOWNRESPONSE;
1624}
1625
1626static GSM_Error N6110_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode Code)
1627{
1628 int len = 0;
1629 unsigned char req[15] = {N6110_FRAME_HEADER, 0x0a,
1630 0x00}; /* Type of code to enter */
1631
1632 req[4]=Code.Type;
1633
1634 len = strlen(Code.Code);
1635 memcpy(req+5,Code.Code,len);
1636 req[5+len]=0x00;
1637 req[6+len]=0x00;
1638
1639 smprintf(s, "Entering security code\n");
1640 return GSM_WaitFor (s, req, 7+len, 0x08, 4, ID_EnterSecurityCode);
1641}
1642
1643static GSM_Error N6110_ReplyGetSpeedDial(GSM_Protocol_Message msg, GSM_StateMachine *s)
1644{
1645 GSM_Phone_Data *Data = &s->Phone.Data;
1646
1647 switch (msg.Buffer[3]) {
1648 case 0x17:
1649 smprintf(s, "Speed dial received\n");
1650 switch (msg.Buffer[4]) {
1651 case 0x02:
1652 Data->SpeedDial->MemoryType = MEM_ME;
1653 smprintf(s, "ME ");
1654 break;
1655 case 0x03:
1656 Data->SpeedDial->MemoryType = MEM_SM;
1657 smprintf(s, "SIM ");
1658 break;
1659 default:
1660 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
1661 return ERR_UNKNOWNRESPONSE;
1662 }
1663 Data->SpeedDial->MemoryLocation = msg.Buffer[5];
1664 if (msg.Buffer[5] == 0x00) Data->SpeedDial->MemoryLocation = Data->SpeedDial->Location;
1665 Data->SpeedDial->MemoryNumberID = 2;
1666 smprintf(s, "location %i\n",Data->SpeedDial->MemoryLocation);
1667 return ERR_NONE;
1668 case 0x18:
1669 smprintf(s, "Error getting speed dial. Invalid location\n");
1670 return ERR_INVALIDLOCATION;
1671 }
1672 return ERR_UNKNOWNRESPONSE;
1673}
1674
1675static GSM_Error N6110_GetSpeedDial(GSM_StateMachine *s, GSM_SpeedDial *SpeedDial)
1676{
1677 unsigned char req[] = {N6110_FRAME_HEADER, 0x16,
1678 0x01}; /* location */
1679
1680 req[4] = SpeedDial->Location;
1681
1682 s->Phone.Data.SpeedDial=SpeedDial;
1683 smprintf(s, "Getting speed dial\n");
1684 return GSM_WaitFor (s, req, 5, 0x03, 4, ID_GetSpeedDial);
1685}
1686
1687static GSM_Error N6110_ReplySendDTMF(GSM_Protocol_Message msg, GSM_StateMachine *s)
1688{
1689 switch (msg.Buffer[3]) {
1690 case 0x40:
1691 smprintf(s, "During sending DTMF\n");
1692 return ERR_NONE;
1693 case 0x51:
1694 smprintf(s, "DTMF sent OK\n");
1695 return ERR_NONE;
1696 }
1697 return ERR_UNKNOWNRESPONSE;
1698}
1699
1700static GSM_Error N6110_ReplyGetDisplayStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
1701{
1702 int i;
1703 GSM_Phone_Data *Data = &s->Phone.Data;
1704
1705 smprintf(s, "Display status received\n");
1706 if (Data->RequestID == ID_GetDisplayStatus) Data->DisplayFeatures->Number=0;
1707 for (i=0;i<msg.Buffer[4];i++) {
1708 if (msg.Buffer[2*i+6] == 0x02) {
1709#ifdef DEBUG
1710 switch (msg.Buffer[2*i+5]) {
1711 case 0x01: smprintf(s, "Call in progress\n"); break;
1712 case 0x02: smprintf(s, "Unknown\n"); break;
1713 case 0x03: smprintf(s, "Unread SMS\n"); break;
1714 case 0x04: smprintf(s, "Voice call\n"); break;
1715 case 0x05: smprintf(s, "Fax call active\n"); break;
1716 case 0x06: smprintf(s, "Data call active\n"); break;
1717 case 0x07: smprintf(s, "Keyboard lock\n"); break;
1718 case 0x08: smprintf(s, "SMS storage full\n"); break;
1719 }
1720#endif
1721 if (Data->RequestID == ID_GetDisplayStatus) {
1722 switch (msg.Buffer[2*i+5]) {
1723 case 0x01: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_CallActive;
1724 break;
1725 case 0x03: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_UnreadSMS;
1726 break;
1727 case 0x04: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_VoiceCall;
1728 break;
1729 case 0x05: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_FaxCall;
1730 break;
1731 case 0x06: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_DataCall;
1732 break;
1733 case 0x07: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_KeypadLocked;
1734 break;
1735 case 0x08: Data->DisplayFeatures->Feature[Data->DisplayFeatures->Number] = GSM_SMSMemoryFull;
1736 break;
1737 }
1738 if (msg.Buffer[2*i+5]!=0x02) Data->DisplayFeatures->Number++;
1739 }
1740 }
1741 }
1742 return ERR_NONE;
1743}
1744
1745static GSM_Error N6110_GetDisplayStatus(GSM_StateMachine *s, GSM_DisplayFeatures *features)
1746{
1747 unsigned char req[] = {N6110_FRAME_HEADER, 0x51};
1748
1749 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_DISPSTATUS)) return ERR_NOTSUPPORTED;
1750
1751 s->Phone.Data.DisplayFeatures = features;
1752 smprintf(s, "Getting display status\n");
1753 return GSM_WaitFor (s, req, 4, 0x0d, 4, ID_GetDisplayStatus);
1754}
1755
1756static GSM_Profile_PhoneTableValue Profile6110[] = {
1757 {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL1, 0x00,0x00},
1758 {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL2, 0x00,0x01},
1759 {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL3, 0x00,0x02},
1760 {Profile_KeypadTone, PROFILE_KEYPAD_OFF, 0x00,0xff},
1761 {Profile_Lights, PROFILE_LIGHTS_OFF, 0x01,0x00},
1762 {Profile_Lights, PROFILE_LIGHTS_AUTO, 0x01,0x01},
1763 {Profile_CallAlert, PROFILE_CALLALERT_RINGING, 0x02,0x01},
1764 {Profile_CallAlert, PROFILE_CALLALERT_BEEPONCE, 0x02,0x02},
1765 {Profile_CallAlert, PROFILE_CALLALERT_OFF, 0x02,0x04},
1766 {Profile_CallAlert, PROFILE_CALLALERT_RINGONCE, 0x02,0x05},
1767 {Profile_CallAlert, PROFILE_CALLALERT_ASCENDING, 0x02,0x06},
1768 {Profile_CallAlert, PROFILE_CALLALERT_CALLERGROUPS,0x02,0x07},
1769 /* Ringtone ID */
1770 {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL1, 0x04,0x06},
1771 {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL2, 0x04,0x07},
1772 {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL3, 0x04,0x08},
1773 {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL4, 0x04,0x09},
1774 {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL5, 0x04,0x0a},
1775 {Profile_MessageTone, PROFILE_MESSAGE_NOTONE, 0x05,0x00},
1776 {Profile_MessageTone, PROFILE_MESSAGE_STANDARD, 0x05,0x01},
1777 {Profile_MessageTone, PROFILE_MESSAGE_SPECIAL, 0x05,0x02},
1778 {Profile_MessageTone, PROFILE_MESSAGE_BEEPONCE, 0x05,0x03},
1779 {Profile_MessageTone, PROFILE_MESSAGE_ASCENDING, 0x05,0x04},
1780 {Profile_Vibration, PROFILE_VIBRATION_OFF, 0x06,0x00},
1781 {Profile_Vibration, PROFILE_VIBRATION_ON, 0x06,0x01},
1782 {Profile_WarningTone, PROFILE_WARNING_OFF, 0x07,0xff},
1783 {Profile_WarningTone, PROFILE_WARNING_ON, 0x07,0x04},
1784 /* Caller groups */
1785 {Profile_AutoAnswer, PROFILE_AUTOANSWER_OFF, 0x09,0x00},
1786 {Profile_AutoAnswer, PROFILE_AUTOANSWER_ON, 0x09,0x01},
1787 {0x00, 0x00, 0x00,0x00}
1788};
1789
1790static GSM_Profile_PhoneTableValue Profile3310[] = {
1791 {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL1, 0x00,0x00},
1792 {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL2, 0x00,0x01},
1793 {Profile_KeypadTone, PROFILE_KEYPAD_LEVEL3, 0x00,0x02},
1794 {Profile_KeypadTone, PROFILE_KEYPAD_OFF, 0x00,0xff},
1795 {Profile_CallAlert, PROFILE_CALLALERT_RINGING, 0x01,0x01},
1796 {Profile_CallAlert, PROFILE_CALLALERT_BEEPONCE, 0x01,0x02},
1797 {Profile_CallAlert, PROFILE_CALLALERT_OFF, 0x01,0x04},
1798 {Profile_CallAlert, PROFILE_CALLALERT_RINGONCE, 0x01,0x05},
1799 {Profile_CallAlert, PROFILE_CALLALERT_ASCENDING, 0x01,0x06},
1800 /* Ringtone ID */
1801 {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL1, 0x03,0x06},
1802 {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL2, 0x03,0x07},
1803 {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL3, 0x03,0x08},
1804 {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL4, 0x03,0x09},
1805 {Profile_RingtoneVolume, PROFILE_VOLUME_LEVEL5, 0x03,0x0a},
1806 {Profile_MessageTone, PROFILE_MESSAGE_NOTONE, 0x04,0x00},
1807 {Profile_MessageTone, PROFILE_MESSAGE_STANDARD, 0x04,0x01},
1808 {Profile_MessageTone, PROFILE_MESSAGE_SPECIAL, 0x04,0x02},
1809 {Profile_MessageTone, PROFILE_MESSAGE_BEEPONCE, 0x04,0x03},
1810 {Profile_MessageTone, PROFILE_MESSAGE_ASCENDING, 0x04,0x04},
1811 {Profile_MessageTone, PROFILE_MESSAGE_PERSONAL, 0x04,0x05},
1812 {Profile_Vibration, PROFILE_VIBRATION_OFF, 0x05,0x00},
1813 {Profile_Vibration, PROFILE_VIBRATION_ON, 0x05,0x01},
1814 {Profile_Vibration, PROFILE_VIBRATION_FIRST, 0x05,0x02},
1815 {Profile_WarningTone, PROFILE_WARNING_OFF, 0x06,0xff},
1816 {Profile_WarningTone, PROFILE_WARNING_ON, 0x06,0x04},
1817 {Profile_ScreenSaver, PROFILE_SAVER_OFF, 0x07,0x00},
1818 {Profile_ScreenSaver, PROFILE_SAVER_ON, 0x07,0x01},
1819 {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_5SEC, 0x08,0x00},
1820 {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_20SEC, 0x08,0x01},
1821 {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_1MIN, 0x08,0x02},
1822 {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_2MIN, 0x08,0x03},
1823 {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_5MIN, 0x08,0x04},
1824 {Profile_ScreenSaverTime,PROFILE_SAVER_TIMEOUT_10MIN, 0x08,0x05},
1825 {0x00, 0x00, 0x00,0x00}
1826};
1827
1828static GSM_Error N6110_ReplyGetProfileFeature(GSM_Protocol_Message msg, GSM_StateMachine *s)
1829{
1830 GSM_Phone_Data *Data = &s->Phone.Data;
1831
1832 switch (msg.Buffer[3]) {
1833 case 0x14:
1834 smprintf(s, "Profile feature %02x with value %02x\n",msg.Buffer[6],msg.Buffer[8]);
1835 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) {
1836 switch (msg.Buffer[6]) {
1837 case 0x02:
1838 smprintf(s, "Ringtone ID\n");
1839 Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_RingtoneID;
1840 Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = msg.Buffer[8];
1841 Data->Profile->FeaturesNumber++;
1842 break;
1843 case 0x09 :
1844 smprintf(s, "screen saver number\n");
1845 Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_ScreenSaverNumber;
1846 Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = msg.Buffer[8] + 1;
1847 Data->Profile->FeaturesNumber++;
1848 break;
1849 case 0x24:
1850 smprintf(s, "selected profile\n");
1851 if (msg.Buffer[8] + 1 == Data->Profile->Location) Data->Profile->Active = true;
1852 break;
1853 default:
1854 NOKIA_FindFeatureValue(s, Profile3310,msg.Buffer[6],msg.Buffer[8],Data,false);
1855 }
1856 return ERR_NONE;
1857 }
1858 switch (msg.Buffer[6]) {
1859 case 0x01: /* Lights */
1860 if (Data->Profile->CarKitProfile) {
1861 NOKIA_FindFeatureValue(s, Profile6110,msg.Buffer[6],msg.Buffer[8],Data,false);
1862 }
1863 break;
1864 case 0x03:
1865 smprintf(s, "Ringtone ID\n");
1866 Data->Profile->FeatureID [Data->Profile->FeaturesNumber] = Profile_RingtoneID;
1867 Data->Profile->FeatureValue [Data->Profile->FeaturesNumber] = msg.Buffer[8];
1868 Data->Profile->FeaturesNumber++;
1869 break;
1870 case 0x08: /* Caller groups */
1871 if (!IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES51)) {
1872 NOKIA_FindFeatureValue(s, Profile6110,msg.Buffer[6],msg.Buffer[8],Data,true);
1873 }
1874 break;
1875 case 0x09: /* Autoanswer */
1876 if (Data->Profile->CarKitProfile || Data->Profile->HeadSetProfile) {
1877 NOKIA_FindFeatureValue(s, Profile6110,msg.Buffer[6],msg.Buffer[8],Data,false);
1878 }
1879 break;
1880 case 0x2A:
1881 smprintf(s, "selected profile\n");
1882 if (msg.Buffer[8] + 1 == Data->Profile->Location) Data->Profile->Active = true;
1883 break;
1884 default:
1885 NOKIA_FindFeatureValue(s, Profile6110,msg.Buffer[6],msg.Buffer[8],Data,false);
1886 }
1887 return ERR_NONE;
1888 case 0x15:
1889 smprintf(s, "Invalid profile location\n");
1890 return ERR_INVALIDLOCATION;
1891 case 0x1b:
1892 Data->Profile->Name[0] = 0;
1893 Data->Profile->Name[1] = 0;
1894 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) {
1895 EncodeUnicode(Data->Profile->Name,msg.Buffer+10,msg.Buffer[9]);
1896 } else {
1897 if (msg.Length > 0x0A) {
1898 CopyUnicodeString(Data->Profile->Name,msg.Buffer+10);
1899 }
1900 }
1901 smprintf(s, "Profile name: \"%s\"\n",Data->Profile->Name);
1902 Data->Profile->DefaultName = false;
1903 if (msg.Buffer[9]==0x00) Data->Profile->DefaultName = true;
1904 return ERR_NONE;
1905 }
1906 return ERR_UNKNOWNRESPONSE;
1907}
1908
1909static GSM_Error N6110_GetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
1910{
1911 GSM_Error error;
1912 int i,j;
1913 unsigned char name_req[] = {N6110_FRAME_HEADER, 0x1a, 0x00};
1914 unsigned char feat_req[] = {N6110_FRAME_HEADER, 0x13, 0x01,
1915 0x00, /* Profile location */
1916 0x00}; /* Feature number */
1917
1918 s->Phone.Data.Profile=Profile;
1919
1920 smprintf(s, "Getting profile name\n");
1921 error = GSM_WaitFor (s, name_req, 5, 0x05, 4, ID_GetProfile);
1922 if (error!=ERR_NONE) return error;
1923 if (Profile->DefaultName) {
1924 NOKIA_GetDefaultProfileName(s, Profile);
1925 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES51)) {
1926 switch(Profile->Location) {
1927 case 1: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Personal"),strlen(GetMsg(s->msg,"Personal")));
1928 break;
1929 case 2: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Car"),strlen(GetMsg(s->msg,"Car")));
1930 break;
1931 case 3: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Headset"),strlen(GetMsg(s->msg,"Headset")));
1932 break;
1933 }
1934 }
1935 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) {
1936 switch(Profile->Location) {
1937 case 1: EncodeUnicode(Profile->Name,GetMsg(s->msg,"General"),strlen(GetMsg(s->msg,"General")));
1938 break;
1939 case 2: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Silent"),strlen(GetMsg(s->msg,"Silent")));
1940 break;
1941 case 3: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Discreet"),strlen(GetMsg(s->msg,"Discreet")));
1942 break;
1943 case 4: EncodeUnicode(Profile->Name,GetMsg(s->msg,"Loud"),strlen(GetMsg(s->msg,"Loud")));
1944 break;
1945 case 5: EncodeUnicode(Profile->Name,GetMsg(s->msg,"My style"),strlen(GetMsg(s->msg,"My style")));
1946 break;
1947 case 6: Profile->Name[0] = 0; Profile->Name[1] = 0;
1948 break;
1949 }
1950 }
1951 }
1952
1953 Profile->FeaturesNumber = 0;
1954
1955 Profile->CarKitProfile = false;
1956 Profile->HeadSetProfile = false;
1957 if (Profile->Location == 6) Profile->CarKitProfile = true;
1958 if (Profile->Location == 7) Profile->HeadSetProfile = true;
1959 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES51)) {
1960 if (Profile->Location == 2) Profile->CarKitProfile = true;
1961 if (Profile->Location == 3) Profile->HeadSetProfile = true;
1962 }
1963 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) {
1964 Profile->HeadSetProfile = false; //fixme
1965 Profile->CarKitProfile = false;
1966 }
1967
1968 for (i = 0x00; i <= 0x09; i++) {
1969 feat_req[5] = Profile->Location - 1;
1970 feat_req[6] = i;
1971 smprintf(s, "Getting profile feature\n");
1972 error = GSM_WaitFor (s, feat_req, 7, 0x05, 4, ID_GetProfile);
1973 if (error!=ERR_NONE) return error;
1974 }
1975
1976 for (i=0;i<Profile->FeaturesNumber;i++) {
1977 if (Profile->FeatureID[i] == Profile_CallAlert &&
1978 Profile->FeatureValue[i] != PROFILE_CALLALERT_CALLERGROUPS) {
1979 for (j=0;j<5;j++) Profile->CallerGroups[j] = true;
1980 }
1981 }
1982
1983 Profile->Active = false;
1984 feat_req[5] = 0;
1985 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) {
1986 feat_req[6] = 0x24;
1987 } else {
1988 feat_req[6] = 0x2A;
1989 }
1990 smprintf(s, "Getting profile feature\n");
1991 error = GSM_WaitFor (s, feat_req, 7, 0x05, 4, ID_GetProfile);
1992
1993 return error;
1994}
1995
1996static GSM_Error N6110_SetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
1997{
1998 int i;
1999 bool found;
2000 unsigned char ID,Value;
2001 GSM_Error error;
2002 GSM_Profile_PhoneTableValue *ProfilePhone = Profile6110;
2003
2004 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES33)) ProfilePhone = Profile3310;
2005
2006 for (i=0;i<Profile->FeaturesNumber;i++) {
2007 found = false;
2008 if (ProfilePhone == Profile3310) {
2009 switch (Profile->FeatureID[i]) {
2010 case Profile_RingtoneID:
2011 ID = 0x02;
2012 Value = Profile->FeatureValue[i];
2013 found = true;
2014 break;
2015 case Profile_ScreenSaverNumber:
2016 ID = 0x09;
2017 Value = Profile->FeatureValue[i];
2018 found = true;
2019 break;
2020 default:
2021 found=NOKIA_FindPhoneFeatureValue(
2022 s,
2023 ProfilePhone,
2024 Profile->FeatureID[i],Profile->FeatureValue[i],
2025 &ID,&Value);
2026 }
2027 }
2028 if (ProfilePhone == Profile6110) {
2029 switch (Profile->FeatureID[i]) {
2030 case Profile_RingtoneID:
2031 ID = 0x03;
2032 Value = Profile->FeatureValue[i];
2033 found = true;
2034 break;
2035 default:
2036 found=NOKIA_FindPhoneFeatureValue(
2037 s,
2038 ProfilePhone,
2039 Profile->FeatureID[i],Profile->FeatureValue[i],
2040 &ID,&Value);
2041 }
2042 }
2043 if (found) {
2044 error=N6110_SetProfileFeature (s,((unsigned char)(Profile->Location-1)),ID,Value);
2045 if (error!=ERR_NONE) return error;
2046 }
2047 }
2048 return ERR_NONE;
2049}
2050
2051static GSM_Error N6110_ReplyIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s)
2052{
2053 GSM_Phone_Data *Data = &s->Phone.Data;
2054 GSM_SMSMessage sms;
2055
2056#ifdef DEBUG
2057 smprintf(s, "SMS message received\n");
2058 sms.State = SMS_UnRead;
2059 sms.InboxFolder = true;
2060 DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+7);
2061#endif
2062 if (Data->EnableIncomingSMS && s->User.IncomingSMS!=NULL) {
2063 sms.State = SMS_UnRead;
2064 sms.InboxFolder = true;
2065 DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+7);
2066
2067 s->User.IncomingSMS(s->CurrentConfig->Device,sms);
2068 }
2069 return ERR_NONE;
2070}
2071
2072static GSM_Error N6110_ReplyAddCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s)
2073{
2074 smprintf(s, "Writting calendar note: ");
2075 switch (msg.Buffer[4]) {
2076 case 0x01:
2077 smprintf(s, "OK\n");
2078 return ERR_NONE;
2079 case 0x73:
2080 case 0x7d:
2081 smprintf(s, "error\n");
2082 return ERR_UNKNOWN;
2083 case 0x81:
2084 smprintf(s,"during editing notes in phone menu\n");
2085 return ERR_INSIDEPHONEMENU;
2086 default:
2087 smprintf(s, "unknown ERROR %i\n",msg.Buffer[4]);
2088 }
2089 return ERR_UNKNOWNRESPONSE;
2090}
2091
2092static GSM_Error N6110_AddCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note)
2093{
2094 bool Reminder3310 = false;
2095 int Text, Time, Alarm, Phone, Recurrance, EndTime, Location, i, current;
2096 unsigned char mychar1,mychar2;
2097 unsigned char req[200] = {N6110_FRAME_HEADER, 0x64, 0x01, 0x10,
2098 0x00, /* Length of the rest of the frame */
2099 0x00, /* Calendar note type */
2100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2101 0x00, 0x00, 0x00, 0x01, 0x00, 0x66, 0x01};
2102
2103 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOCALENDAR)) return ERR_NOTSUPPORTED;
2104
2105 GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note, &Text, &Time, &Alarm, &Phone, &Recurrance, &EndTime, &Location);
2106
2107 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL52)) {
2108 switch(Note->Type) {
2109 case GSM_CAL_REMINDER: req[7]=0x01; break;
2110 case GSM_CAL_CALL : req[7]=0x02; break;
2111 case GSM_CAL_MEETING : req[7]=0x03; break;
2112 case GSM_CAL_BIRTHDAY: req[7]=0x04; break;
2113 case GSM_CAL_T_ATHL : req[7]=0x05; break;
2114 case GSM_CAL_T_BALL : req[7]=0x06; break;
2115 case GSM_CAL_T_CYCL : req[7]=0x07; break;
2116 case GSM_CAL_T_BUDO : req[7]=0x08; break;
2117 case GSM_CAL_T_DANC : req[7]=0x09; break;
2118 case GSM_CAL_T_EXTR : req[7]=0x0a; break;
2119 case GSM_CAL_T_FOOT : req[7]=0x0b; break;
2120 case GSM_CAL_T_GOLF : req[7]=0x0c; break;
2121 case GSM_CAL_T_GYM : req[7]=0x0d; break;
2122 case GSM_CAL_T_HORS : req[7]=0x0e; break;
2123 case GSM_CAL_T_HOCK : req[7]=0x0f; break;
2124 case GSM_CAL_T_RACE : req[7]=0x10; break;
2125 case GSM_CAL_T_RUGB : req[7]=0x11; break;
2126 case GSM_CAL_T_SAIL : req[7]=0x12; break;
2127 case GSM_CAL_T_STRE : req[7]=0x13; break;
2128 case GSM_CAL_T_SWIM : req[7]=0x14; break;
2129 case GSM_CAL_T_TENN : req[7]=0x15; break;
2130 case GSM_CAL_T_TRAV : req[7]=0x16; break;
2131 case GSM_CAL_T_WINT : req[7]=0x17; break;
2132 default : req[7]=0x01; break;
2133 }
2134 } else {
2135 switch(Note->Type) {
2136 case GSM_CAL_CALL : req[7]=0x02; break;
2137 case GSM_CAL_MEETING : req[7]=0x03; break;
2138 case GSM_CAL_BIRTHDAY: req[7]=0x04; break;
2139 case GSM_CAL_REMINDER:
2140 default : req[7]=0x01; break;
2141 }
2142 }
2143
2144 if (Time == -1) return ERR_UNKNOWN;
2145 NOKIA_EncodeDateTime(s, req+8, &Note->Entries[Time].Date);
2146 req[14] = Note->Entries[Time].Date.Second;
2147
2148 if (Alarm != -1) {
2149 NOKIA_EncodeDateTime(s, req+15, &Note->Entries[Alarm].Date);
2150 req[21] = Note->Entries[Alarm].Date.Second;
2151 }
2152
2153 current = 23;
2154
2155 if (Text != -1) {
2156 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL52) ||
2157 IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL82)) {
2158 req[22] = UnicodeLength(Note->Entries[Text].Text)*2;
2159 memcpy(req+current,Note->Entries[Text].Text,UnicodeLength(Note->Entries[Text].Text)*2);
2160 current += UnicodeLength(Note->Entries[Text].Text)*2;
2161 } else {
2162 req[22] = UnicodeLength(Note->Entries[Text].Text);
2163 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL33)) {
2164 Reminder3310 = true;
2165 if (!strcmp(s->Phone.Data.ModelInfo->model,"3310") && s->Phone.Data.VerNum<5.11) {
2166 if (Note->Type!=GSM_CAL_REMINDER) Reminder3310 = false;
2167 }
2168 if (!strcmp(s->Phone.Data.ModelInfo->model,"3330") && s->Phone.Data.VerNum<=4.50) {
2169 if (Note->Type!=GSM_CAL_REMINDER) Reminder3310 = false;
2170 }
2171 if (Reminder3310) {
2172 req[22]++; /* one additional char */
2173 req[current++] = 0x01; /* we use now subset 1 */
2174 for (i=0;i<((int)UnicodeLength(Note->Entries[Text].Text));i++) {
2175 /* Euro char */
2176 if (Note->Entries[Text].Text[i*2]==0x20 && Note->Entries[Text].Text[i*2+1]==0xAC) {
2177 req[current++] = 0xe2;
2178 req[current++] = 0x82;
2179 req[current++] = 0xac;
2180 req[23] = 0x03; /* use subset 3 */
2181 req[22]+=2; /* two additional chars */
2182 } else if (EncodeWithUTF8Alphabet(Note->Entries[Text].Text[i*2],Note->Entries[Text].Text[i*2+1],&mychar1,&mychar2)) {
2183 req[current++] = mychar1;
2184 req[current++] = mychar2;
2185 req[23] = 0x03; /* use subset 3 */
2186 req[22]++; /* one additional char */
2187 } else {
2188 current+=DecodeWithUnicodeAlphabet(((wchar_t)(Note->Entries[Text].Text[i*2]*256+Note->Entries[Text].Text[i*2+1])),req+current);
2189 }
2190 }
2191 }
2192 }
2193 if (!Reminder3310) {
2194 memcpy(req+current,DecodeUnicodeString(Note->Entries[Text].Text),UnicodeLength(Note->Entries[Text].Text));
2195 current += UnicodeLength(Note->Entries[Text].Text);
2196 }
2197 }
2198 } else req[22] = 0x00;
2199
2200 if (Note->Type == GSM_CAL_CALL) {
2201 if (Phone != -1) {
2202 req[current++] = UnicodeLength(Note->Entries[Phone].Text);
2203 memcpy(req+current,DecodeUnicodeString(Note->Entries[Phone].Text),UnicodeLength(Note->Entries[Phone].Text));
2204 current += UnicodeLength(Note->Entries[Phone].Text);
2205 } else req[current++] = 0x00;
2206 }
2207
2208 req[6] = current - 8;
2209
2210 smprintf(s, "Writing calendar note\n");
2211 return GSM_WaitFor (s, req, current, 0x13, 4, ID_SetCalendarNote);
2212}
2213
2214static GSM_Error N6110_ReplyDeleteCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s)
2215{
2216 smprintf(s, "Deleting calendar note: ");
2217 switch (msg.Buffer[4]) {
2218 case 0x01:
2219 smprintf(s, "done OK\n");
2220 return ERR_NONE;
2221 case 0x81:
2222 smprintf(s,"during editing notes in phone menu\n");
2223 return ERR_INSIDEPHONEMENU;
2224 case 0x93:
2225 smprintf(s, "Can't be done - too high location ?\n");
2226 return ERR_INVALIDLOCATION;
2227 default:
2228 smprintf(s, "unknown ERROR %i\n",msg.Buffer[4]);
2229 return ERR_UNKNOWNRESPONSE;
2230 }
2231}
2232
2233static GSM_Error N6110_DeleteCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note)
2234{
2235 unsigned char req[] = {N6110_FRAME_HEADER, 0x68,
2236 0x00}; /* Location */
2237
2238 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOCALENDAR)) return ERR_NOTSUPPORTED;
2239
2240 req[4] = Note->Location;
2241
2242 smprintf(s, "Deleting calendar note\n");
2243 return GSM_WaitFor (s, req, 5, 0x13, 5, ID_DeleteCalendarNote);
2244}
2245
2246/* for example: "Euro_char" text */
2247static void Decode3310Subset3(int j, GSM_Protocol_Message msg, GSM_Phone_Data *Data)
2248{
2249 wchar_t wc;
2250 int len = 0;
2251 int i;
2252 bool charfound;
2253 GSM_CalendarEntry *Entry = Data->Cal;
2254
2255 i = j;
2256 while (i!=msg.Buffer[23]) {
2257 EncodeWithUnicodeAlphabet(msg.Buffer+24+i,&wc);
2258 charfound = false;
2259 if (i!=msg.Buffer[23]-2) {
2260 if (msg.Buffer[24+i] ==0xe2 && msg.Buffer[24+i+1]==0x82 &&
2261 msg.Buffer[24+i+2]==0xac) {
2262 wc = 0x20 * 256 + 0xac;
2263 i+=2;
2264 charfound = true;
2265 }
2266 }
2267 if (i!=msg.Buffer[23]-1 && !charfound) {
2268 if (msg.Buffer[24+i]>=0xc2) {
2269 wc = DecodeWithUTF8Alphabet(msg.Buffer[24+i],msg.Buffer[24+i+1]);
2270 i++;
2271 }
2272 }
2273 Entry->Entries[Entry->EntriesNum].Text[len++] = (wc >> 8) & 0xff;
2274 Entry->Entries[Entry->EntriesNum].Text[len++] = wc & 0xff;
2275 i++;
2276 }
2277 Entry->Entries[Entry->EntriesNum].Text[len++] = 0;
2278 Entry->Entries[Entry->EntriesNum].Text[len++] = 0;
2279}
2280
2281/* For example: "a with : above" char */
2282static void Decode3310Subset2(int j, GSM_Protocol_Message msg, GSM_Phone_Data *Data)
2283{
2284 int len = 0;
2285 int i;
2286 GSM_CalendarEntry *Entry = Data->Cal;
2287
2288 i = j;
2289 while (i!=msg.Buffer[23]) {
2290 Entry->Entries[Entry->EntriesNum].Text[len++] = 0x00;
2291 Entry->Entries[Entry->EntriesNum].Text[len++] = msg.Buffer[24+i];
2292 i++;
2293 }
2294 Entry->Entries[Entry->EntriesNum].Text[len++] = 0;
2295 Entry->Entries[Entry->EntriesNum].Text[len++] = 0;
2296}
2297
2298static GSM_Error N6110_ReplyGetNextCalendar(GSM_Protocol_Message msg, GSM_StateMachine *s)
2299{
2300 int i = 0;
2301 bool SpecialSubSet = false;
2302 GSM_CalendarEntry *Entry = s->Phone.Data.Cal;
2303
2304 switch (msg.Buffer[4]) {
2305 case 0x01:
2306 smprintf(s, "Calendar note received\n");
2307 switch (msg.Buffer[8]) {
2308 case 0x01: Entry->Type = GSM_CAL_REMINDER; break;
2309 case 0x02: Entry->Type = GSM_CAL_CALL; break;
2310 case 0x03: Entry->Type = GSM_CAL_MEETING; break;
2311 case 0x04: Entry->Type = GSM_CAL_BIRTHDAY; break;
2312 case 0x05: Entry->Type = GSM_CAL_T_ATHL; break;
2313 case 0x06: Entry->Type = GSM_CAL_T_BALL; break;
2314 case 0x07: Entry->Type = GSM_CAL_T_CYCL; break;
2315 case 0x08: Entry->Type = GSM_CAL_T_BUDO; break;
2316 case 0x09: Entry->Type = GSM_CAL_T_DANC; break;
2317 case 0x0a: Entry->Type = GSM_CAL_T_EXTR; break;
2318 case 0x0b: Entry->Type = GSM_CAL_T_FOOT; break;
2319 case 0x0c: Entry->Type = GSM_CAL_T_GOLF; break;
2320 case 0x0d: Entry->Type = GSM_CAL_T_GYM; break;
2321 case 0x0e: Entry->Type = GSM_CAL_T_HORS; break;
2322 case 0x0f: Entry->Type = GSM_CAL_T_HOCK; break;
2323 case 0x10: Entry->Type = GSM_CAL_T_RACE; break;
2324 case 0x11: Entry->Type = GSM_CAL_T_RUGB; break;
2325 case 0x12: Entry->Type = GSM_CAL_T_SAIL; break;
2326 case 0x13: Entry->Type = GSM_CAL_T_STRE; break;
2327 case 0x14: Entry->Type = GSM_CAL_T_SWIM; break;
2328 case 0x15: Entry->Type = GSM_CAL_T_TENN; break;
2329 case 0x16: Entry->Type = GSM_CAL_T_TRAV; break;
2330 case 0x17: Entry->Type = GSM_CAL_T_WINT; break;
2331 default :
2332 smprintf(s, "Unknown note type %i\n",msg.Buffer[8]);
2333 return ERR_UNKNOWNRESPONSE;
2334 }
2335#ifdef DEBUG
2336 switch (msg.Buffer[8]) {
2337 case 0x01: smprintf(s, "Reminder\n"); break;
2338 case 0x02: smprintf(s, "Call\n"); break;
2339 case 0x03: smprintf(s, "Meeting\n"); break;
2340 case 0x04: smprintf(s, "Birthday\n"); break;
2341 }
2342#endif
2343 Entry->EntriesNum = 0;
2344
2345 NOKIA_DecodeDateTime(s, msg.Buffer+9, &Entry->Entries[0].Date);
2346 smprintf(s, "Time : %02i-%02i-%04i %02i:%02i:%02i\n",
2347 Entry->Entries[0].Date.Day,Entry->Entries[0].Date.Month,Entry->Entries[0].Date.Year,
2348 Entry->Entries[0].Date.Hour,Entry->Entries[0].Date.Minute,Entry->Entries[0].Date.Second);
2349 Entry->Entries[0].EntryType = CAL_START_DATETIME;
2350 Entry->EntriesNum++;
2351
2352 NOKIA_DecodeDateTime(s, msg.Buffer+16, &Entry->Entries[1].Date);
2353 if (Entry->Entries[1].Date.Year!=0) {
2354 smprintf(s, "Alarm : %02i-%02i-%04i %02i:%02i:%02i\n",
2355 Entry->Entries[1].Date.Day,Entry->Entries[1].Date.Month,Entry->Entries[1].Date.Year,
2356 Entry->Entries[1].Date.Hour,Entry->Entries[1].Date.Minute,Entry->Entries[1].Date.Second);
2357 Entry->Entries[1].EntryType = CAL_ALARM_DATETIME;
2358 Entry->EntriesNum++;
2359 } else {
2360 smprintf(s, "No alarm\n");
2361 }
2362
2363 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL52) ||
2364 IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL82)) {
2365 memcpy(Entry->Entries[Entry->EntriesNum].Text,msg.Buffer+24,msg.Buffer[23]);
2366 Entry->Entries[Entry->EntriesNum].Text[msg.Buffer[23] ]=0;
2367 Entry->Entries[Entry->EntriesNum].Text[msg.Buffer[23]+1]=0;
2368 } else {
2369 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo,F_CAL33)) {
2370 /* first char is subset for 33xx and reminders */
2371 if (Entry->Type == GSM_CAL_REMINDER) {
2372 i=1;
2373 smprintf(s, "Subset %i in reminder note !\n",msg.Buffer[24]);
2374 }
2375 SpecialSubSet = true;
2376 switch (msg.Buffer[24]) {
2377 case 2 : Decode3310Subset2(i,msg,&s->Phone.Data); break;
2378 case 3 : Decode3310Subset3(i,msg,&s->Phone.Data); break;
2379 default : SpecialSubSet = false; break;
2380 }
2381 }
2382 if (!SpecialSubSet) {
2383 N6110_EncodeUnicode(s,Entry->Entries[Entry->EntriesNum].Text,msg.Buffer+24+i,msg.Buffer[23]-i);
2384 }
2385 }
2386 smprintf(s, "Text \"%s\"\n",DecodeUnicodeString(Entry->Entries[Entry->EntriesNum].Text));
2387 if (msg.Buffer[23] != 0x00) {
2388 Entry->Entries[Entry->EntriesNum].EntryType = CAL_TEXT;
2389 Entry->EntriesNum++;
2390 }
2391
2392 if (Entry->Type == GSM_CAL_CALL) {
2393 EncodeUnicode(Entry->Entries[Entry->EntriesNum].Text,msg.Buffer+24+msg.Buffer[23]+1,msg.Buffer[24+msg.Buffer[23]]);
2394 smprintf(s, "Phone : \"%s\"\n",DecodeUnicodeString(Entry->Entries[Entry->EntriesNum].Text));
2395 if (msg.Buffer[24+msg.Buffer[23]] != 0x00) {
2396 Entry->Entries[Entry->EntriesNum].EntryType = CAL_PHONE;
2397 Entry->EntriesNum++;
2398 }
2399 }
2400 return ERR_NONE;
2401 case 0x93:
2402 smprintf(s, "Can't get calendar note - too high location?\n");
2403 return ERR_INVALIDLOCATION;
2404 }
2405 return ERR_UNKNOWNRESPONSE;
2406}
2407
2408static GSM_Error N6110_GetNextCalendarNote(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start)
2409{
2410 int Text, Time, Alarm, Phone, Recurrance, EndTime, Location;
2411 GSM_Error error;
2412 GSM_DateTime date_time;
2413 GSM_Phone_N6110Data *Priv = &s->Phone.Data.Priv.N6110;
2414 unsigned char req[] = {N6110_FRAME_HEADER, 0x66,
2415 0x00}; /* Location */
2416
2417 if (IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOCALENDAR)) return ERR_NOTSUPPORTED;
2418
2419 if (start) {
2420 Priv->LastCalendarPos = 1;
2421 } else {
2422 Priv->LastCalendarPos++;
2423 }
2424
2425 Note->Location = Priv->LastCalendarPos;
2426 req[4] = Priv->LastCalendarPos;
2427
2428 s->Phone.Data.Cal=Note;
2429 smprintf(s, "Getting calendar note\n");
2430 error=GSM_WaitFor (s, req, 5, 0x13, 4, ID_GetCalendarNote);
2431
2432 GSM_CalendarFindDefaultTextTimeAlarmPhoneRecurrance(Note, &Text, &Time, &Alarm, &Phone, &Recurrance, &EndTime, &Location);
2433 /* 2090 year is set for example in 3310 */
2434 if (error == ERR_NONE && Note->Entries[Time].Date.Year == 2090) {
2435 error=N6110_GetDateTime(s, &date_time);
2436 if (error == ERR_NONE) Note->Entries[Time].Date.Year = date_time.Year;
2437 }
2438 return error;
2439}
2440
2441GSM_Error N6110_ReplyUSSDInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
2442{
2443 unsigned char buffer[2000],buffer2[4000];
2444 int tmp;
2445
2446 tmp=GSM_UnpackEightBitsToSeven(0, 82, 82, msg.Buffer+8, buffer);
2447 msg.Buffer[tmp] = 0;
2448
2449 smprintf(s, "USSD reply: \"%s\"\n",buffer);
2450
2451 if (s->Phone.Data.EnableIncomingUSSD && s->User.IncomingUSSD!=NULL) {
2452 EncodeUnicode(buffer2,buffer,strlen(buffer));
2453 s->User.IncomingUSSD(s->CurrentConfig->Device, buffer2);
2454 }
2455
2456 return ERR_NONE;
2457}
2458
2459GSM_Error N6110_AnswerCall(GSM_StateMachine *s, int ID, bool all)
2460{
2461 GSM_Error error;
2462 unsigned char req1[] = {N6110_FRAME_HEADER, 0x42, 0x05, 0x01,
2463 0x07, 0xa2, 0x88, 0x81, 0x21, 0x15, 0x63, 0xa8,
2464 0x00, 0x00, 0x07, 0xa3, 0xb8, 0x81, 0x20, 0x15,
2465 0x63, 0x80};
2466
2467 if (!all) {
2468 smprintf(s, "Answering call part 1\n");
2469 error = GSM_WaitFor (s, req1, 24, 0x01, 5, ID_AnswerCall);
2470 if (error != ERR_NONE) return error;
2471 return DCT3DCT4_AnswerCall(s,ID);
2472 }
2473
2474 return DCT3_AnswerAllCalls(s);
2475}
2476
2477static GSM_Error N6110_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber)
2478{
2479 unsigned int pos = 4;
2480 unsigned char req[100] = {N6110_FRAME_HEADER,0x01,
2481 0x0c}; /* Length of number */
2482
2483 if (ShowNumber == GSM_CALL_DefaultNumberPresence) return DCT3_DialVoice(s,number,ShowNumber);
2484
2485 req[pos++] = strlen(number);
2486 memcpy(req+pos,number,strlen(number));
2487 pos += strlen(number);
2488 req[pos++] = 0x05; /* call type: voice - 0x05, data - 0x01 */
2489 req[pos++] = 0x01;
2490 req[pos++] = 0x01;
2491 req[pos++] = 0x05;
2492 req[pos++] = 0x81;
2493 switch (ShowNumber) {
2494 case GSM_CALL_HideNumber:
2495 req[pos++] = 0x02;
2496 break;
2497 case GSM_CALL_ShowNumber:
2498 req[pos++] = 0x03;
2499 break;
2500 case GSM_CALL_DefaultNumberPresence:
2501 req[pos++] = 0x01;
2502 break;
2503 }
2504 req[pos++] = 0x00;
2505 req[pos++] = 0x00;
2506
2507 smprintf(s, "Making voice call\n");
2508 return GSM_WaitFor (s, req, pos, 0x01, 4, ID_DialVoice);
2509}
2510
2511GSM_Error N6110_UnholdCall(GSM_StateMachine *s, int ID)
2512{
2513 unsigned char req[] = {N6110_FRAME_HEADER, 0x24, 0x00, 0x02};
2514
2515 req[4] = (unsigned char)ID;
2516 s->Phone.Data.CallID = ID;
2517
2518 smprintf(s, "Unholding call\n");
2519 return GSM_WaitFor (s, req, 6, 0x01, 4, ID_UnholdCall);
2520}
2521
2522GSM_Error N6110_HoldCall(GSM_StateMachine *s, int ID)
2523{
2524 unsigned char req[] = {N6110_FRAME_HEADER, 0x22, 0x00, 0x00};
2525
2526 req[4] = (unsigned char)ID;
2527 s->Phone.Data.CallID = ID;
2528
2529 smprintf(s, "Unholding call\n");
2530 return GSM_WaitFor (s, req, 6, 0x01, 4, ID_HoldCall);
2531}
2532
2533/* Joining selected call to current (and making conference) */
2534GSM_Error N6110_ConferenceCall(GSM_StateMachine *s, int ID)
2535{
2536 unsigned char req[] = {N6110_FRAME_HEADER, 0x28, 0x00, 0x01};
2537
2538 req[4] = (unsigned char)ID;
2539 s->Phone.Data.CallID = ID;
2540
2541 smprintf(s, "Conference call\n");
2542 return GSM_WaitFor (s, req, 6, 0x01, 4, ID_ConferenceCall);
2543}
2544
2545/* Removing selected call from conference and making private call with it
2546 * (conference call is on hold) */
2547GSM_Error N6110_SplitCall(GSM_StateMachine *s, int ID)
2548{
2549 unsigned char req[] = {N6110_FRAME_HEADER, 0x2A, 0x00, 0x01};
2550
2551 req[4] = (unsigned char)ID;
2552 s->Phone.Data.CallID = ID;
2553
2554 smprintf(s, "Split call\n");
2555 return GSM_WaitFor (s, req, 6, 0x01, 4, ID_SplitCall);
2556}
2557
2558/* This probably need more investigation */
2559GSM_Error N6110_SwitchCall(GSM_StateMachine *s, int ID, bool next)
2560{
2561// unsigned char req[] = {N6110_FRAME_HEADER, 0x20}; calls info
2562 unsigned char req[] = {N6110_FRAME_HEADER, 0x26, 0x00};
2563
2564 s->Phone.Data.CallID = ID;
2565
2566 if (next) {
2567 smprintf(s, "Switch call\n");
2568 return GSM_WaitFor (s, req, 4, 0x01, 4, ID_SwitchCall);
2569 } else {
2570 req[4] = (unsigned char)ID;
2571
2572 smprintf(s, "Switch call\n");
2573 return GSM_WaitFor (s, req, 5, 0x01, 4, ID_SwitchCall);
2574 }
2575}
2576
2577/* This probably need more investigation */
2578GSM_Error N6110_TransferCall(GSM_StateMachine *s, int ID, bool next)
2579{
2580 unsigned char req[] = {N6110_FRAME_HEADER, 0x2C, 0x00};
2581
2582 s->Phone.Data.CallID = ID;
2583
2584 if (next) {
2585 smprintf(s, "Transfer call\n");
2586 return GSM_WaitFor (s, req, 4, 0x01, 4, ID_TransferCall);
2587 } else {
2588 req[4] = (unsigned char)ID;
2589
2590 smprintf(s, "Transfer call\n");
2591 return GSM_WaitFor (s, req, 5, 0x01, 4, ID_TransferCall);
2592 }
2593}
2594
2595static GSM_Reply_Function N6110ReplyFunctions[] = {
2596 {N6110_ReplyCallInfo, "\x01",0x03,0x02,ID_IncomingFrame },
2597 {N6110_ReplyCallInfo, "\x01",0x03,0x03,ID_IncomingFrame },
2598 {N6110_ReplyCallInfo, "\x01",0x03,0x04,ID_IncomingFrame },
2599 {N6110_ReplyCallInfo, "\x01",0x03,0x05,ID_IncomingFrame },
2600 {N6110_ReplyCallInfo, "\x01",0x03,0x07,ID_AnswerCall },
2601 {N6110_ReplyCallInfo, "\x01",0x03,0x07,ID_IncomingFrame },
2602 {N6110_ReplyCallInfo, "\x01",0x03,0x09,ID_CancelCall },
2603 {N6110_ReplyCallInfo, "\x01",0x03,0x09,ID_IncomingFrame },
2604 {N6110_ReplyCallInfo, "\x01",0x03,0x0A,ID_IncomingFrame },
2605 {N6110_ReplyCallInfo, "\x01",0x03,0x23,ID_HoldCall },
2606 {N6110_ReplyCallInfo, "\x01",0x03,0x23,ID_IncomingFrame },
2607 {N6110_ReplyCallInfo, "\x01",0x03,0x25,ID_UnholdCall },
2608 {N6110_ReplyCallInfo, "\x01",0x03,0x25,ID_IncomingFrame },
2609 {N6110_ReplyCallInfo, "\x01",0x03,0x27,ID_IncomingFrame },
2610 {N6110_ReplyCallInfo, "\x01",0x03,0x29,ID_ConferenceCall },
2611 {N6110_ReplyCallInfo, "\x01",0x03,0x29,ID_IncomingFrame },
2612 {N6110_ReplyCallInfo, "\x01",0x03,0x2B,ID_SplitCall },
2613 {N6110_ReplyCallInfo, "\x01",0x03,0x2B,ID_IncomingFrame },
2614 {N6110_ReplySendDTMF, "\x01",0x03,0x40,ID_SendDTMF },
2615 {NoneReply, "\x01",0x03,0x40,ID_DialVoice },
2616 {NoneReply, "\x01",0x03,0x40,ID_IncomingFrame },
2617 {NoneReply, "\x01",0x03,0x43,ID_AnswerCall },
2618 {N6110_ReplySendDTMF, "\x01",0x03,0x51,ID_SendDTMF },
2619
2620 {DCT3_ReplySendSMSMessage, "\x02",0x03,0x02,ID_IncomingFrame },
2621 {DCT3_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame },
2622 {N6110_ReplyIncomingSMS, "\x02",0x03,0x10,ID_IncomingFrame },
2623#ifdef GSM_ENABLE_CELLBROADCAST
2624 {DCT3_ReplySetIncomingCB, "\x02",0x03,0x21,ID_SetIncomingCB },
2625 {DCT3_ReplySetIncomingCB, "\x02",0x03,0x22,ID_SetIncomingCB },
2626 {DCT3_ReplyIncomingCB, "\x02",0x03,0x23,ID_IncomingFrame },
2627#endif
2628 {DCT3_ReplySetSMSC, "\x02",0x03,0x31,ID_SetSMSC },
2629 {DCT3_ReplyGetSMSC, "\x02",0x03,0x34,ID_GetSMSC },
2630 {DCT3_ReplyGetSMSC, "\x02",0x03,0x35,ID_GetSMSC },
2631
2632 {N6110_ReplyGetMemory, "\x03",0x03,0x02,ID_GetMemory },
2633 {N6110_ReplyGetMemory, "\x03",0x03,0x03,ID_GetMemory },
2634 {N6110_ReplySetMemory, "\x03",0x03,0x05,ID_SetMemory },
2635 {N6110_ReplySetMemory, "\x03",0x03,0x06,ID_SetMemory },
2636 {N6110_ReplyGetMemoryStatus, "\x03",0x03,0x08,ID_GetMemoryStatus },
2637 {N6110_ReplyGetMemoryStatus, "\x03",0x03,0x09,ID_GetMemoryStatus },
2638 {N6110_ReplyGetCallerLogo, "\x03",0x03,0x11,ID_GetBitmap },
2639 {N6110_ReplyGetCallerLogo, "\x03",0x03,0x12,ID_GetBitmap },
2640 {N6110_ReplySetCallerLogo, "\x03",0x03,0x14,ID_SetBitmap },
2641 {N6110_ReplySetCallerLogo, "\x03",0x03,0x15,ID_SetBitmap },
2642 {N6110_ReplyGetSpeedDial, "\x03",0x03,0x17,ID_GetSpeedDial },
2643 {N6110_ReplyGetSpeedDial, "\x03",0x03,0x18,ID_GetSpeedDial },
2644 /* 0x1A, 0x1B - reply set speed dial */
2645
2646 {N6110_ReplyGetStatus, "\x04",0x03,0x02,ID_GetSignalQuality },
2647 {N6110_ReplyGetStatus, "\x04",0x03,0x02,ID_GetBatteryCharge },
2648
2649 {N6110_ReplySetProfileFeature, "\x05",0x03,0x11,ID_SetProfile },
2650 {N6110_ReplySetProfileFeature, "\x05",0x03,0x12,ID_SetProfile },
2651 {N6110_ReplyGetProfileFeature, "\x05",0x03,0x14,ID_GetProfile },
2652 {N6110_ReplyGetPhoneLanguage, "\x05",0x03,0x14,ID_GetLanguage },
2653 {N6110_ReplyGetProfileFeature, "\x05",0x03,0x15,ID_GetProfile },
2654 {N6110_ReplyGetPhoneLanguage, "\x05",0x03,0x15,ID_GetLanguage },
2655 {N6110_ReplyGetStartup, "\x05",0x03,0x17,ID_GetBitmap },
2656 {N6110_ReplySetStartup, "\x05",0x03,0x19,ID_SetBitmap },
2657 {N6110_ReplyGetProfileFeature, "\x05",0x03,0x1b,ID_GetProfile },
2658 {N61_91_ReplySetOpLogo, "\x05",0x03,0x31,ID_SetBitmap },
2659 {N61_91_ReplySetOpLogo, "\x05",0x03,0x32,ID_SetBitmap },
2660 {N6110_ReplyGetOpLogo, "\x05",0x03,0x34,ID_GetBitmap },
2661 {N6110_ReplySetRingtone, "\x05",0x03,0x37,ID_SetRingtone },
2662 {N6110_ReplySetRingtone, "\x05",0x03,0x38,ID_SetRingtone },
2663
2664 {DCT3DCT4_ReplyCallDivert, "\x06",0x03,0x02,ID_Divert },
2665 {DCT3DCT4_ReplyCallDivert, "\x06",0x03,0x03,ID_Divert },
2666 {N6110_ReplyUSSDInfo, "\x06",0x03,0x05,ID_IncomingFrame },
2667 {NoneReply, "\x06",0x03,0x06,ID_IncomingFrame },//incoming call divert info
2668
2669 {N6110_ReplyGetSecurityStatus, "\x08",0x03,0x08,ID_GetSecurityStatus },
2670 {N6110_ReplyEnterSecurityCode, "\x08",0x03,0x0b,ID_EnterSecurityCode },
2671 {N6110_ReplyEnterSecurityCode, "\x08",0x03,0x0c,ID_EnterSecurityCode },
2672
2673 {DCT3_ReplySIMLogin, "\x09",0x03,0x80,ID_IncomingFrame },
2674 {DCT3_ReplySIMLogout, "\x09",0x03,0x81,ID_IncomingFrame },
2675
2676 {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_GetNetworkInfo },
2677 {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_IncomingFrame },
2678
2679 {N6110_ReplyGetDisplayStatus, "\x0D",0x03,0x52,ID_GetDisplayStatus },
2680 {N6110_ReplyGetDisplayStatus, "\x0D",0x03,0x52,ID_IncomingFrame },
2681
2682 {DCT3_ReplySetDateTime, "\x11",0x03,0x61,ID_SetDateTime },
2683 {DCT3_ReplyGetDateTime, "\x11",0x03,0x63,ID_GetDateTime },
2684 {DCT3_ReplySetAlarm, "\x11",0x03,0x6C,ID_SetAlarm },
2685 {DCT3_ReplyGetAlarm, "\x11",0x03,0x6E,ID_GetAlarm },
2686
2687 {N6110_ReplyAddCalendar, "\x13",0x03,0x65,ID_SetCalendarNote },
2688 {N6110_ReplyAddCalendar, "\x13",0x03,0x65,ID_IncomingFrame },
2689 {N6110_ReplyGetNextCalendar, "\x13",0x03,0x67,ID_GetCalendarNote },
2690 {N6110_ReplyDeleteCalendar, "\x13",0x03,0x69,ID_DeleteCalendarNote },
2691 {N6110_ReplyDeleteCalendar, "\x13",0x03,0x69,ID_IncomingFrame },
2692
2693 {N6110_ReplySaveSMSMessage, "\x14",0x03,0x05,ID_SaveSMSMessage },
2694 {N6110_ReplySaveSMSMessage, "\x14",0x03,0x06,ID_SaveSMSMessage },
2695 {N6110_ReplyGetSMSMessage, "\x14",0x03,0x08,ID_GetSMSMessage },
2696 {N6110_ReplyGetSMSMessage, "\x14",0x03,0x09,ID_GetSMSMessage },
2697 {DCT3_ReplyDeleteSMSMessage, "\x14",0x03,0x0B,ID_DeleteSMSMessage },
2698 {DCT3_ReplyDeleteSMSMessage, "\x14",0x03,0x0C,ID_DeleteSMSMessage },
2699 {N6110_ReplyGetSMSStatus, "\x14",0x03,0x37,ID_GetSMSStatus },
2700 {N6110_ReplyGetSMSStatus, "\x14",0x03,0x38,ID_GetSMSStatus },
2701
2702 {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x01,ID_EnableConnectFunc },
2703 {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x02,ID_EnableConnectFunc },
2704 {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x04,ID_DisableConnectFunc },
2705 {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x05,ID_DisableConnectFunc },
2706 {DCT3_ReplyGetWAPBookmark, "\x3f",0x03,0x07,ID_GetWAPBookmark },
2707 {DCT3_ReplyGetWAPBookmark, "\x3f",0x03,0x08,ID_GetWAPBookmark },
2708 {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0A,ID_SetWAPBookmark },
2709 {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0B,ID_SetWAPBookmark },
2710 {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0D,ID_DeleteWAPBookmark },
2711 {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0E,ID_DeleteWAPBookmark },
2712 {DCT3DCT4_ReplyGetActiveConnectSet,"\x3f",0x03,0x10,ID_GetConnectSet },
2713 {DCT3DCT4_ReplySetActiveConnectSet,"\x3f",0x03,0x13,ID_SetConnectSet },
2714 {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x16,ID_GetConnectSet },
2715 {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x17,ID_GetConnectSet },
2716 {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x19,ID_SetConnectSet },
2717 {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x1A,ID_SetConnectSet },
2718 {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x1C,ID_GetConnectSet },
2719 {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x1D,ID_GetConnectSet },
2720 {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x1F,ID_SetConnectSet },
2721
2722 {DCT3_ReplyEnableSecurity, "\x40",0x02,0x64,ID_EnableSecurity },
2723 {N61_71_ReplyResetPhoneSettings, "\x40",0x02,0x65,ID_ResetPhoneSettings },
2724 {DCT3_ReplyGetIMEI, "\x40",0x02,0x66,ID_GetIMEI },
2725 {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_DialVoice },
2726 {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_CancelCall },
2727 {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_AnswerCall },
2728 {DCT3_ReplyNetmonitor, "\x40",0x02,0x7E,ID_Netmonitor },
2729 {DCT3_ReplyPlayTone, "\x40",0x02,0x8F,ID_PlayTone },
2730 {N6110_ReplyGetRingtone, "\x40",0x02,0x9E,ID_GetRingtone },
2731 {N6110_ReplySetBinRingtone, "\x40",0x02,0xA0,ID_SetRingtone },
2732 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetHardware },
2733 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetPPM },
2734 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCA,ID_GetProductCode },
2735 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetManufactureMonth},
2736 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetOriginalIMEI },
2737
2738 {N6110_ReplyGetSetPicture, "\x47",0x03,0x02,ID_GetBitmap },
2739 {N6110_ReplyGetSetPicture, "\x47",0x03,0x04,ID_SetBitmap },
2740 {N6110_ReplyGetSetPicture, "\x47",0x03,0x05,ID_SetBitmap },
2741 {N6110_ReplyGetSetPicture, "\x47",0x03,0x06,ID_GetBitmap },
2742
2743#ifndef ENABLE_LGPL
2744 {N6110_ReplyGetMagicBytes, "\x64",0x00,0x00,ID_MakeAuthentication },
2745#endif
2746
2747 {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetModel },
2748 {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetFirmware },
2749 {DCT3_ReplyPressKey, "\xD2",0x02,0x46,ID_PressKey },
2750 {DCT3_ReplyPressKey, "\xD2",0x02,0x47,ID_PressKey },
2751
2752 {NULL, "\x00",0x00,0x00,ID_None }
2753};
2754
2755GSM_Phone_Functions N6110Phone = {
2756 "2100|3210|3310|3330|3390|3410|3610|5110|5110i|5130|5190|5210|5510|6110|6130|6150|6190|8210|8250|8290|8850|8855|8890",
2757 N6110ReplyFunctions,
2758 N6110_Initialise,
2759 PHONE_Terminate,
2760 GSM_DispatchMessage,
2761 N6110_ShowStartInfo,
2762 NOKIA_GetManufacturer,
2763 DCT3DCT4_GetModel,
2764 DCT3DCT4_GetFirmware,
2765 DCT3_GetIMEI,
2766 DCT3_GetOriginalIMEI,
2767 DCT3_GetManufactureMonth,
2768 DCT3_GetProductCode,
2769 DCT3_GetHardware,
2770 DCT3_GetPPM,
2771 NOTSUPPORTED, /* GetSIMIMSI */
2772 N6110_GetDateTime,
2773 N6110_SetDateTime,
2774 N6110_GetAlarm,
2775 N6110_SetAlarm,
2776 NOTSUPPORTED, /* GetLocale */
2777 NOTSUPPORTED, /* SetLocale */
2778 DCT3_PressKey,
2779 DCT3_Reset,
2780 N61_71_ResetPhoneSettings,
2781 N6110_EnterSecurityCode,
2782 N6110_GetSecurityStatus,
2783 N6110_GetDisplayStatus,
2784 NOTIMPLEMENTED, /* SetAutoNetworkLogin */
2785 N6110_GetBatteryCharge,
2786 N6110_GetSignalQuality,
2787 DCT3_GetNetworkInfo,
2788 NOTSUPPORTED, /* GetCategory */
2789 NOTSUPPORTED, /* AddCategory */
2790 NOTSUPPORTED, /* GetCategoryStatus */
2791 N6110_GetMemoryStatus,
2792 N6110_GetMemory,
2793 NOTIMPLEMENTED, /* GetNextMemory */
2794 N6110_SetMemory,
2795 NOTIMPLEMENTED, /* AddMemory */
2796 N6110_DeleteMemory,
2797 NOTIMPLEMENTED, /* DeleteAllMemory */
2798 N6110_GetSpeedDial,
2799 NOTIMPLEMENTED, /* SetSpeedDial */
2800 DCT3_GetSMSC,
2801 DCT3_SetSMSC,
2802 DCT3_GetSMSStatus,
2803 N6110_GetSMSMessage,
2804 N6110_GetNextSMSMessage,
2805 N6110_SetSMS,
2806 N6110_AddSMS,
2807 N6110_DeleteSMSMessage,
2808 DCT3_SendSMSMessage,
2809 NOTSUPPORTED, /* SendSavedSMS */
2810 NOKIA_SetIncomingSMS,
2811 DCT3_SetIncomingCB,
2812 PHONE_GetSMSFolders,
2813 NOTSUPPORTED, /* AddSMSFolder */
2814 NOTSUPPORTED, /* DeleteSMSFolder */
2815 N6110_DialVoice,
2816 N6110_AnswerCall,
2817 DCT3_CancelCall,
2818 N6110_HoldCall,
2819 N6110_UnholdCall,
2820 N6110_ConferenceCall,
2821 N6110_SplitCall,
2822 N6110_TransferCall,
2823 N6110_SwitchCall,
2824 DCT3DCT4_GetCallDivert,
2825 DCT3DCT4_SetCallDivert,
2826 DCT3DCT4_CancelAllDiverts,
2827 NOKIA_SetIncomingCall,
2828 NOKIA_SetIncomingUSSD,
2829 DCT3DCT4_SendDTMF,
2830 N6110_GetRingtone,
2831 N6110_SetRingtone,
2832 NOTSUPPORTED, /* GetRingtonesInfo */
2833 NOTSUPPORTED, /* DeleteUserRingtones */
2834 DCT3_PlayTone,
2835 DCT3_GetWAPBookmark,
2836 DCT3_SetWAPBookmark,
2837 DCT3_DeleteWAPBookmark,
2838 DCT3_GetWAPSettings,
2839 DCT3_SetWAPSettings,
2840 NOTSUPPORTED, /* GetMMSSettings */
2841 NOTSUPPORTED, /* SetMMSSettings */
2842 NOTSUPPORTED, /* GetSyncMLSettings*/
2843 NOTSUPPORTED, /* SetSyncMLSettings*/
2844 NOTSUPPORTED, /* GetChatSettings */
2845 NOTSUPPORTED, /* SetChatSettings */
2846 N6110_GetBitmap,
2847 N6110_SetBitmap,
2848 NOTSUPPORTED, /* GetToDoStatus */
2849 NOTSUPPORTED, /* GetToDo */
2850 NOTSUPPORTED, /* GetNextToDo */
2851 NOTSUPPORTED, /* SetToDo */
2852 NOTSUPPORTED, /* AddToDo */
2853 NOTSUPPORTED, /* DeleteToDo */
2854 NOTSUPPORTED, /* DeleteAllToDo */
2855 NOTIMPLEMENTED, /* GetCalendarStatus */
2856 NOTIMPLEMENTED, /* GetCalendar */
2857 N6110_GetNextCalendarNote,
2858 NOTIMPLEMENTED, /* SetCalendar */
2859 N6110_AddCalendarNote,
2860 N6110_DeleteCalendarNote,
2861 NOTIMPLEMENTED, /* DeleteAllCalendar */
2862 NOTSUPPORTED, /* GetCalendarSettings */
2863 NOTSUPPORTED, /* SetCalendarSettings */
2864 NOTSUPPORTED, /* GetNote */
2865 N6110_GetProfile,
2866 N6110_SetProfile,
2867 NOTSUPPORTED, /* GetFMStation */
2868 NOTSUPPORTED, /* SetFMStation */
2869 NOTSUPPORTED, /* ClearFMStations */
2870 NOTSUPPORTED, /* GetNextFileFolder */
2871 NOTSUPPORTED, /* GetFilePart */
2872 NOTSUPPORTED, /* AddFile */
2873 NOTSUPPORTED, /* GetFileSystemStatus */
2874 NOTSUPPORTED, /* DeleteFile */
2875 NOTSUPPORTED, /* AddFolder */
2876 NOTSUPPORTED, /* GetGPRSAccessPoint */
2877 NOTSUPPORTED /* SetGPRSAccessPoint */
2878};
2879
2880#endif
2881
2882/* How should editor hadle tabs in this file? Add editor commands here.
2883 * vim: noexpandtab sw=8 ts=8 sts=8:
2884 */
diff --git a/gammu/emb/common/phone/nokia/dct3/n6110.h b/gammu/emb/common/phone/nokia/dct3/n6110.h
new file mode 100644
index 0000000..d243766
--- a/dev/null
+++ b/gammu/emb/common/phone/nokia/dct3/n6110.h
@@ -0,0 +1,45 @@
1/* (c) 2002-2003 by Marcin Wiacek */
2
3#ifndef n6110_h
4#define n6110_h
5
6#include "../../../config.h"
7#include "../../../service/sms/gsmsms.h"
8#include "dct3comm.h"
9
10typedef struct {
11#ifndef ENABLE_LGPL
12 unsigned char MagicBytes[4];
13#endif
14 int LastCalendarPos;
15 DCT3_WAPSettings_LocationsWAPLocations;
16
17 GSM_SMSMemoryStatus LastSMSStatus;
18 int LastSMSRead;
19
20 int PhoneLanguage;
21} GSM_Phone_N6110Data;
22
23typedef enum {
24 N6110_Auto = 1,
25 N6110_Europe
26} N6110_Language;
27
28#ifndef GSM_USED_MBUS2
29# define GSM_USED_MBUS2
30#endif
31#ifndef GSM_USED_FBUS2
32# define GSM_USED_FBUS2
33#endif
34#ifndef GSM_USED_FBUS2IRDA
35# define GSM_USED_FBUS2IRDA
36#endif
37#ifndef GSM_USED_IRDAPHONET
38# define GSM_USED_IRDAPHONET
39#endif
40
41#endif
42
43/* How should editor hadle tabs in this file? Add editor commands here.
44 * vim: noexpandtab sw=8 ts=8 sts=8:
45 */
diff --git a/gammu/emb/common/phone/nokia/dct3/n7110.c b/gammu/emb/common/phone/nokia/dct3/n7110.c
new file mode 100644
index 0000000..5a02c9c
--- a/dev/null
+++ b/gammu/emb/common/phone/nokia/dct3/n7110.c
@@ -0,0 +1,1724 @@
1/* (c) 2001-2004 by Marcin Wiacek */
2/* based on some work from Markus Plail and Gnokii */
3
4#include "../../../gsmstate.h"
5
6#ifdef GSM_ENABLE_NOKIA7110
7
8#include <string.h>
9#include <time.h>
10
11#include "../../../misc/coding/coding.h"
12#include "../../../gsmcomon.h"
13#include "../../../service/gsmlogo.h"
14#include "../../pfunc.h"
15#include "../nfunc.h"
16#include "../nfuncold.h"
17#include "n7110.h"
18#include "dct3func.h"
19
20static GSM_Error N7110_GetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm)
21{
22 return DCT3_GetAlarm(s, alarm, 0x19);
23}
24
25static GSM_Error N7110_SetAlarm(GSM_StateMachine *s, GSM_Alarm *alarm)
26{
27 return DCT3_SetAlarm(s, alarm, 0x19);
28}
29
30static GSM_Error N7110_ReplyGetMemory(GSM_Protocol_Message msg, GSM_StateMachine *s)
31{
32 GSM_Phone_Data *Data = &s->Phone.Data;
33
34 smprintf(s, "Phonebook entry received\n");
35 switch (msg.Buffer[6]) {
36 case 0x0f:
37 return N71_65_ReplyGetMemoryError(msg.Buffer[10], s);
38 default:
39 return N71_65_DecodePhonebook(s, Data->Memory,Data->Bitmap,Data->SpeedDial,msg.Buffer+18,msg.Length-18,false);
40 }
41 return ERR_UNKNOWN;
42}
43
44static GSM_Error N7110_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry)
45{
46 unsigned char req[] = {N7110_FRAME_HEADER, 0x07, 0x01, 0x01, 0x00, 0x01,
47 0x02, /* memory type */
48 0x05,
49 0x00, 0x00,/* location */
50 0x00, 0x00};
51
52 req[9] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
53 if (req[9]==0xff) return ERR_NOTSUPPORTED;
54
55 if (entry->Location==0x00) return ERR_INVALIDLOCATION;
56
57 req[10] = entry->Location / 256;
58 req[11] = entry->Location % 256;
59
60 s->Phone.Data.Memory=entry;
61 smprintf(s, "Getting phonebook entry\n");
62 return GSM_WaitFor (s, req, 14, 0x03, 4, ID_GetMemory);
63}
64
65static GSM_Error N7110_ReplyGetMemoryStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
66{
67 GSM_Phone_Data *Data = &s->Phone.Data;
68
69 smprintf(s, "Memory status received\n");
70 /* Quess ;-)) */
71 if (msg.Buffer[10]==0x10) {
72 Data->MemoryStatus->MemoryFree = msg.Buffer[14]*256 + msg.Buffer[15];
73 } else {
74 Data->MemoryStatus->MemoryFree = msg.Buffer[18];
75 }
76 smprintf(s, " Size : %i\n",Data->MemoryStatus->MemoryFree);
77 Data->MemoryStatus->MemoryUsed = msg.Buffer[16]*256 + msg.Buffer[17];
78 smprintf(s, " Used : %i\n",Data->MemoryStatus->MemoryUsed);
79 Data->MemoryStatus->MemoryFree -= Data->MemoryStatus->MemoryUsed;
80 smprintf(s, " Free : %i\n",Data->MemoryStatus->MemoryFree);
81 return ERR_NONE;
82}
83
84static GSM_Error N7110_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status)
85{
86 unsigned char req[] = {N6110_FRAME_HEADER, 0x03, 0x02,
87 0x05}; /* Memory type */
88
89 req[5] = NOKIA_GetMemoryType(s, Status->MemoryType,N71_65_MEMORY_TYPES);
90 if (req[5]==0xff) return ERR_NOTSUPPORTED;
91
92 s->Phone.Data.MemoryStatus=Status;
93 smprintf(s, "Getting memory status\n");
94 return GSM_WaitFor (s, req, 6, 0x03, 4, ID_GetMemoryStatus);
95}
96
97static void N7110_GetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *folderid, int *location)
98{
99 int ifolderid;
100
101 /* simulate flat SMS memory */
102 if (sms->Folder==0x00) {
103 ifolderid = sms->Location / PHONE_MAXSMSINFOLDER;
104 *folderid = (ifolderid + 1) * 0x08;
105 *location = sms->Location - ifolderid * PHONE_MAXSMSINFOLDER;
106 } else {
107 *folderid = sms->Folder * 0x08;
108 *location = sms->Location;
109 }
110 smprintf(s, "SMS folder %i & location %i -> 7110 folder %i & location %i\n",
111 sms->Folder,sms->Location,*folderid,*location);
112}
113
114static void N7110_SetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char folderid, int location)
115{
116 sms->Folder= 0;
117 sms->Location= (folderid / 0x08 - 1) * PHONE_MAXSMSINFOLDER + location;
118 smprintf(s, "7110 folder %i & location %i -> SMS folder %i & location %i\n",
119 folderid,location,sms->Folder,sms->Location);
120}
121
122static GSM_Error N7110_ReplyGetSMSFolders(GSM_Protocol_Message msg, GSM_StateMachine *s)
123{
124 int j,current=5;
125 unsigned char buffer[200];
126 GSM_Phone_Data*Data = &s->Phone.Data;
127
128 switch (msg.Buffer[3]) {
129 case 0x7B:
130 smprintf(s, "Names for SMS folders received\n");
131 Data->SMSFolders->Number=msg.Buffer[4];
132 for (j=0;j<msg.Buffer[4];j++) {
133 smprintf(s, "Folder index: %02x",msg.Buffer[current]);
134 current++;
135 smprintf(s, ", folder name: \"");
136 CopyUnicodeString(buffer,msg.Buffer+current);
137 if ((UnicodeLength(buffer))>GSM_MAX_SMS_FOLDER_NAME_LEN) {
138 smprintf(s, "Too long text\n");
139 return ERR_UNKNOWNRESPONSE;
140 }
141 CopyUnicodeString(Data->SMSFolders->Folder[j].Name,buffer);
142 smprintf(s, "%s\"\n",DecodeUnicodeString(buffer));
143 current=current+2+UnicodeLength(buffer)*2;
144 Data->SMSFolders->Folder[j].InboxFolder = false;
145 if (j==0) Data->SMSFolders->Folder[j].InboxFolder = true;
146 Data->SMSFolders->Folder[j].Memory = MEM_ME;
147 if (j==0 || j==1) Data->SMSFolders->Folder[j].InboxFolder = MEM_MT;
148 }
149 return ERR_NONE;
150 case 0x7C:
151 smprintf(s, "Security error ? No PIN ?\n");
152 return ERR_SECURITYERROR;
153 case 0xCA:
154 smprintf(s, "Wait a moment. Phone is during power on and busy now\n");
155 return ERR_SECURITYERROR;
156 }
157 return ERR_UNKNOWNRESPONSE;
158}
159
160static GSM_Error N7110_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders)
161{
162 unsigned char req[] = {N6110_FRAME_HEADER, 0x7A, 0x00, 0x00};
163
164 s->Phone.Data.SMSFolders=folders;
165 smprintf(s, "Getting SMS folders\n");
166 return GSM_WaitFor (s, req, 6, 0x14, 4, ID_GetSMSFolders);
167}
168
169static GSM_Error N7110_ReplyGetSMSFolderStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
170{
171 int i;
172 GSM_Phone_N7110Data*Priv = &s->Phone.Data.Priv.N7110;
173
174 smprintf(s, "SMS folder status received\n");
175 Priv->LastSMSFolder.Number=msg.Buffer[4]*256+msg.Buffer[5];
176 smprintf(s, "Number of Entries: %i\n",Priv->LastSMSFolder.Number);
177 smprintf(s, "Locations: ");
178 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
179 Priv->LastSMSFolder.Location[i]=msg.Buffer[6+(i*2)]*256+msg.Buffer[(i*2)+7];
180 if (Priv->LastSMSFolder.Location[i] > PHONE_MAXSMSINFOLDER) {
181 smprintf(s, "Increase PHONE_MAXSMSINFOLDER\n");
182 return ERR_UNKNOWNRESPONSE;
183 }
184 smprintf(s, "%i ",Priv->LastSMSFolder.Location[i]);
185 }
186 smprintf(s, "\n");
187 NOKIA_SortSMSFolderStatus(s, &Priv->LastSMSFolder);
188 return ERR_NONE;
189}
190
191static GSM_Error N7110_PrivGetSMSFolderStatus(GSM_StateMachine *s, int folderid)
192{
193 unsigned char req[] = {N7110_FRAME_HEADER, 0x6b,
194 0x08, /* folderID */
195 0x0F, 0x01};
196
197 req[4] = folderid;
198
199 smprintf(s, "Getting SMS folder status\n");
200 return GSM_WaitFor (s, req, 7, 0x14, 4, ID_GetSMSFolderStatus);
201}
202
203static GSM_Error N7110_GetSMSFolderStatus(GSM_StateMachine *s, int folderid)
204{
205 GSM_Error error;
206 int i;
207 GSM_NOKIASMSFolderfolder;
208
209 error = N7110_PrivGetSMSFolderStatus(s,folderid);
210 /* 0x08 contais read Inbox, 0xf8 unread Inbox.
211 * we want all msg from Inbox, so read both 0x08 and 0xf8 */
212 if (folderid==0x08 && error==ERR_NONE) {
213 folder=s->Phone.Data.Priv.N7110.LastSMSFolder;
214 error = N7110_PrivGetSMSFolderStatus(s,0xf8);
215 if (error==ERR_NONE) {
216 for (i=0;i<folder.Number;i++) {
217 s->Phone.Data.Priv.N7110.LastSMSFolder.Location[s->Phone.Data.Priv.N7110.LastSMSFolder.Number++]=folder.Location[i];
218 }
219 }
220 }
221 return error;
222}
223
224static GSM_SMSMessageLayout N7110_SMSTemplate = {
225 36 /* SMS Text */, 17 /* Phone number*/,
226 255 /* SMSC Number */, 15 /* TPDCS */,
227 255 /* SendingDateTime */, 255 /* SMSCDateTime*/,
228 255 /* TPStatus */, 16 /* TPUDL */,
229 255 /* TPVP */, 12 /* firstbyte*/,
230 13 /* TPMR */, 255 /* TPPID?? */};
231
232static GSM_Error N7110_ReplyGetSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
233{
234 int i;
235 int Width, Height;
236 unsigned char output[500], output2[500];
237 GSM_Phone_Data *Data = &s->Phone.Data;
238
239 switch(msg.Buffer[3]) {
240 case 0x08:
241 switch (msg.Buffer[8]) {
242 case 0x00:
243 case 0x01:
244 smprintf(s, "SMS message\n");
245 if (Data->RequestID == ID_GetSMSMessage) {
246 Data->GetSMSMessage->Number=1;
247 NOKIA_DecodeSMSState(s, msg.Buffer[4], &Data->GetSMSMessage->SMS[0]);
248 DCT3_DecodeSMSFrame(s, &Data->GetSMSMessage->SMS[0],msg.Buffer+9);
249 return ERR_NONE;
250 }
251 case 0x02:
252 smprintf(s, "SMS template\n");
253 if (Data->RequestID == ID_GetSMSMessage) {
254 Data->GetSMSMessage->Number=1;
255 NOKIA_DecodeSMSState(s, msg.Buffer[4], &Data->GetSMSMessage->SMS[0]);
256 Data->GetSMSMessage->SMS[0].PDU=SMS_Submit;
257 GSM_DecodeSMSFrame(&Data->GetSMSMessage->SMS[0],msg.Buffer+9,N7110_SMSTemplate);
258 return ERR_NONE;
259 }
260 case 0x07:
261 smprintf(s, "Picture Image\n");
262 switch (Data->RequestID) {
263 case ID_GetBitmap:
264 PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height);
265 Data->Bitmap->BitmapWidth= Width;
266 Data->Bitmap->BitmapHeight= Height;
267 PHONE_DecodeBitmap(GSM_NokiaPictureImage, msg.Buffer + 51, Data->Bitmap);
268 GSM_UnpackSemiOctetNumber(Data->Bitmap->Sender,msg.Buffer+22,true);
269#ifdef DEBUG
270 GSM_UnpackSemiOctetNumber(output,msg.Buffer+9,true);
271 smprintf(s, "SMSC : %s\n",DecodeUnicodeString(output));
272#endif
273 Data->Bitmap->Text[0] = 0;
274 Data->Bitmap->Text[1] = 0;
275 if (msg.Length!=304) {
276 GSM_UnpackEightBitsToSeven(0, msg.Length-304, msg.Length-304, msg.Buffer+52+PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0),output);
277 DecodeDefault(Data->Bitmap->Text, output, msg.Length - 304, true, NULL);
278 }
279 return ERR_NONE;
280 case ID_GetSMSMessage:
281 Data->GetSMSMessage->Number = 0;
282 i = 0;
283 output[i++] = 0x30; /* Smart Messaging 3.0 */
284 output[i++] = SM30_OTA;
285 output[i++] = 0x01; /* Length */
286 output[i++] = 0x00; /* Length */
287 output[i++] = 0x00;
288 PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height);
289 output[i++] = Width;
290 output[i++] = Height;
291 output[i++] = 0x01;
292 memcpy(output+i,msg.Buffer+51,PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0));
293 i = i + PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0);
294 if (msg.Length!=304) {
295 output[i++] = SM30_UNICODETEXT;
296 output[i++] = 0;
297 output[i++] = 0; /* Length - later changed */
298 GSM_UnpackEightBitsToSeven(0, msg.Length-304, msg.Length-304, msg.Buffer+52+PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0),output2);
299 DecodeDefault(output+i, output2, msg.Length - 304, true, NULL);
300 output[i - 1] = UnicodeLength(output+i) * 2;
301 i = i + output[i-1];
302 }
303 GSM_MakeMultiPartSMS(Data->GetSMSMessage,output,i,UDH_NokiaProfileLong,SMS_Coding_8bit,1,0);
304 for (i=0;i<3;i++) {
305 Data->GetSMSMessage->SMS[i].Number[0]=0;
306 Data->GetSMSMessage->SMS[i].Number[1]=0;
307 }
308 return ERR_NONE;
309 default:
310 smprintf(s, "Unknown SMS type: %i\n",msg.Buffer[8]);
311 return ERR_UNKNOWNRESPONSE;
312 }
313 default:
314 smprintf(s, "Unknown SMS type: %i\n",msg.Buffer[8]);
315 }
316 break;
317 case 0x09:
318 switch (msg.Buffer[4]) {
319 case 0x02:
320 smprintf(s, "Too high location ?\n");
321 return ERR_INVALIDLOCATION;
322 case 0x07:
323 smprintf(s, "Empty\n");
324 return ERR_EMPTY;
325 default:
326 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
327 }
328 case 0x6F:
329 smprintf(s, "SMS message info received\n");
330 if (msg.Length == 43) {
331 Data->GetSMSMessage->SMS[0].Name[0] = 0;
332 Data->GetSMSMessage->SMS[0].Name[1] = 0;
333 } else {
334 CopyUnicodeString(Data->GetSMSMessage->SMS[0].Name,msg.Buffer+43);
335 }
336 smprintf(s, "Name: \"%s\"\n",DecodeUnicodeString(Data->GetSMSMessage->SMS[0].Name));
337 return ERR_NONE;
338 }
339 return ERR_UNKNOWNRESPONSE;
340}
341
342static GSM_Error N7110_PrivGetSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms)
343{
344 GSM_Error error;
345 unsigned char folderid;
346 int location;
347 int i;
348 unsigned char req[] = {N6110_FRAME_HEADER, 0x07,
349 0x08, /* folder ID */
350 0x00, 0x05, /* location */
351 0x01, 0x65, 0x01};
352 unsigned char NameReq[] = {N6110_FRAME_HEADER, 0x6E,
353 0x08, /* folder ID */
354 0x00, 0x05}; /* location */
355
356 N7110_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
357
358 req[4]=folderid;
359 req[5]=location / 256;
360 req[6]=location;
361
362 s->Phone.Data.GetSMSMessage=sms;
363 smprintf(s, "Getting sms\n");
364 error=GSM_WaitFor (s, req, 10, 0x14, 4, ID_GetSMSMessage);
365 if (error==ERR_NONE) {
366 NameReq[4] = folderid;
367 NameReq[5] = location / 256;
368 NameReq[6] = location;
369 smprintf(s, "Getting sms info\n");
370 error=GSM_WaitFor (s, NameReq, 7, 0x14, 4, ID_GetSMSMessage);
371 if (error != ERR_NONE) return error;
372 for (i=0;i<sms->Number;i++) {
373 N7110_SetSMSLocation(s, &sms->SMS[i], folderid, location);
374 sms->SMS[i].Folder = folderid/0x08;
375 sms->SMS[i].InboxFolder = true;
376 if (folderid/0x08 != 0x01) sms->SMS[i].InboxFolder = false;
377 CopyUnicodeString(sms->SMS[i].Name,sms->SMS[0].Name);
378 sms->SMS[i].Memory = MEM_ME;
379 if (folderid/0x08 == 0x01 || folderid/0x08 == 0x02) {
380 sms->SMS[i].Memory = MEM_MT;
381 if (folderid/0x08 == 0x01) { /* Inbox */
382 if (sms->SMS[i].State == SMS_Sent) sms->SMS[i].Memory = MEM_ME;
383 if (sms->SMS[i].State == SMS_UnSent) sms->SMS[i].Memory = MEM_ME;
384 if (sms->SMS[i].State == SMS_Read) sms->SMS[i].Memory = MEM_SM;
385 if (sms->SMS[i].State == SMS_UnRead) sms->SMS[i].Memory = MEM_SM;
386 }
387 if (folderid/0x08 == 0x02) { /* Outbox */
388 if (sms->SMS[i].State == SMS_Sent) sms->SMS[i].Memory = MEM_SM;
389 if (sms->SMS[i].State == SMS_UnSent) sms->SMS[i].Memory = MEM_SM;
390 if (sms->SMS[i].State == SMS_Read) sms->SMS[i].Memory = MEM_ME;
391 if (sms->SMS[i].State == SMS_UnRead) sms->SMS[i].Memory = MEM_ME;
392 }
393 }
394 }
395 }
396 return error;
397}
398
399static GSM_Error N7110_GetSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms)
400{
401 GSM_Error error;
402 unsigned char folderid;
403 int location;
404 GSM_Phone_N7110Data*Priv = &s->Phone.Data.Priv.N7110;
405 int i;
406 bool found = false;
407
408 N7110_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
409 error=N7110_GetSMSFolderStatus(s, folderid);
410 if (error!=ERR_NONE) return error;
411 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
412 if (Priv->LastSMSFolder.Location[i]==location) {
413 found = true;
414 break;
415 }
416 }
417 if (!found) return ERR_EMPTY;
418 return N7110_PrivGetSMSMessage(s,sms);
419}
420
421static GSM_Error N7110_GetNextSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, bool start)
422{
423 GSM_Phone_N7110Data*Priv = &s->Phone.Data.Priv.N7110;
424 unsigned char folderid;
425 int location;
426 GSM_Error error;
427 int i;
428 bool findnextfolder = false;
429
430 if (start) {
431 folderid=0x00;
432 findnextfolder=true;
433 error=N7110_GetSMSFolders(s,&Priv->LastSMSFolders);
434 if (error!=ERR_NONE) return error;
435 } else {
436 N7110_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
437 for (i=0;i<Priv->LastSMSFolder.Number;i++) {
438 if (Priv->LastSMSFolder.Location[i]==location) break;
439 }
440 /* Is this last location in this folder ? */
441 if (i==Priv->LastSMSFolder.Number-1) {
442 findnextfolder=true;
443 } else {
444 location=Priv->LastSMSFolder.Location[i+1];
445 }
446 }
447 if (findnextfolder) {
448 Priv->LastSMSFolder.Number=0;
449 while (Priv->LastSMSFolder.Number==0) {
450 folderid=folderid+0x08;
451 /* Too high folder number */
452 if ((folderid/0x08)>Priv->LastSMSFolders.Number) return ERR_EMPTY;
453 /* Get next folder status */
454 error=N7110_GetSMSFolderStatus(s, folderid);
455 if (error!=ERR_NONE) return error;
456 /* First location from this folder */
457 location=Priv->LastSMSFolder.Location[0];
458 }
459 }
460 N7110_SetSMSLocation(s, &sms->SMS[0], folderid, location);
461
462 return N7110_PrivGetSMSMessage(s, sms);
463}
464
465static int N7110_ReturnBinaryRingtoneLocation(char *model)
466{
467 if (strcmp(model,"NSE-5") == 0) return 0x72; /* first 0x72 - 7110 */
468 if (strcmp(model,"NPE-3") == 0) return 0x89; /* first 0x89 - 6210 */
469 if (strcmp(model,"NHM-3") == 0) return 0x89; /* quess for 6250 */
470 return 0;
471}
472
473static GSM_Error N7110_ReplyGetRingtone(GSM_Protocol_Message msg, GSM_StateMachine *s)
474{
475 int tmp,i;
476 GSM_Phone_Data *Data = &s->Phone.Data;
477
478 smprintf(s, "Ringtone received\n");
479 switch (msg.Buffer[3]) {
480 case 0x23:
481 tmp=0;i=4;
482 while (msg.Buffer[i]!=0 || msg.Buffer[i+1]!=0) {
483 tmp++;
484 i=i+2;
485 if (i>msg.Length) return ERR_EMPTY;
486 }
487 memcpy(Data->Ringtone->Name,msg.Buffer+6,tmp*2);
488 smprintf(s, "Name \"%s\"\n",DecodeUnicodeString(Data->Ringtone->Name));
489 /* Looking for end */
490 i=37;
491 while (true) {
492 if (msg.Buffer[i]==0x07 && msg.Buffer[i+1]==0x0b) {
493 i=i+2; break;
494 }
495 if (msg.Buffer[i]==0x0e && msg.Buffer[i+1]==0x0b) {
496 i=i+2; break;
497 }
498 i++;
499 if (i==msg.Length) return ERR_EMPTY;
500 }
501 /* Copying frame */
502 memcpy(Data->Ringtone->NokiaBinary.Frame,msg.Buffer+37,i-37);
503 Data->Ringtone->NokiaBinary.Length=i-37;
504 return ERR_NONE;
505 case 0x24:
506 smprintf(s, "Invalid location. Too high ?\n");
507 return ERR_INVALIDLOCATION;
508 }
509 return ERR_UNKNOWNRESPONSE;
510}
511
512static GSM_Error N7110_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, bool PhoneRingtone)
513{
514 unsigned char req[] = {N7110_FRAME_HEADER, 0x22, 0x00, 0x00};
515
516 if (PhoneRingtone) return ERR_NOTSUPPORTED;
517 if (Ringtone->Format == 0x00) Ringtone->Format = RING_NOKIABINARY;
518
519 switch (Ringtone->Format) {
520 case RING_NOTETONE:
521 /* In the future get binary and convert */
522 return ERR_NOTSUPPORTED;
523 case RING_NOKIABINARY:
524 req[5]=N7110_ReturnBinaryRingtoneLocation(s->Phone.Data.Model)+Ringtone->Location;
525 s->Phone.Data.Ringtone=Ringtone;
526 smprintf(s, "Getting binary ringtone\n");
527 return GSM_WaitFor (s, req, 6, 0x1f, 4, ID_GetRingtone);
528 case RING_MIDI:
529 return ERR_NOTSUPPORTED;
530 }
531 return ERR_NOTSUPPORTED;
532}
533
534static GSM_Error N7110_ReplyGetPictureImageInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
535{
536 int i;
537 GSM_Phone_N7110Data*Priv = &s->Phone.Data.Priv.N7110;
538
539 smprintf(s, "Received info for Picture Images\n");
540 smprintf(s, "Number : %i\n",msg.Buffer[4]*256+msg.Buffer[5]);
541 smprintf(s, "Locations :");
542 Priv->LastPictureImageFolder.Number=msg.Buffer[4]*256+msg.Buffer[5];
543 for (i=0;i<Priv->LastPictureImageFolder.Number;i++) {
544 Priv->LastPictureImageFolder.Location[i]=msg.Buffer[6+i*2]*256+msg.Buffer[7+i*2];
545 smprintf(s, " %i",Priv->LastPictureImageFolder.Location[i]);
546 }
547 smprintf(s, "\n");
548 return ERR_NONE;
549}
550
551static GSM_Error N7110_GetPictureImageLocation(GSM_StateMachine *s, GSM_Bitmap *Bitmap, unsigned char *folder, int *location)
552{
553 GSM_Phone_N7110Data*Priv = &s->Phone.Data.Priv.N7110;
554 GSM_SMSFolders folders;
555 GSM_Error error;
556 int i, j = 0, count = 0;
557 unsigned char req[] = {N6110_FRAME_HEADER, 0x96,
558 0x00, /* Folder ID */
559 0x0f, 0x07};
560
561 error=N7110_GetSMSFolders (s, &folders);
562 if (error!=ERR_NONE) return error;
563
564 for (i=0;i<folders.Number;i++) {
565 req[4] = (i+1) * 0x08;/* SMS folder ID */
566 error = GSM_WaitFor (s, req, 7, 0x14, 4, ID_GetBitmap);
567 if (error!=ERR_NONE) return error;
568 for (j=0;j<Priv->LastPictureImageFolder.Number;j++) {
569 count++;
570 if (count==Bitmap->Location) break;
571 }
572 if (count==Bitmap->Location) break;
573 }
574 if (count!=Bitmap->Location) return ERR_INVALIDLOCATION;
575 *folder = (i+1) * 0x08;/* SMS Folder ID */
576 *location= Priv->LastPictureImageFolder.Location[j];
577 return ERR_NONE;
578}
579
580static GSM_Error N7110_GetPictureImage(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
581{
582 unsigned char folder;
583 int location;
584 GSM_Error error;
585 unsigned char req[] = {N6110_FRAME_HEADER, 0x07,
586 0x00, /* Folder ID */
587 0x00, 0x00, /* Location */
588 0x00, 0x64};
589
590 error = N7110_GetPictureImageLocation(s, Bitmap, &folder, &location);
591 switch (error) {
592 case ERR_NONE:
593 req[4] = folder;
594 req[5] = location / 256;
595 req[6] = location % 256;
596 return GSM_WaitFor (s, req, 9, 0x14, 4, ID_GetBitmap);
597 default:
598 return error;
599 }
600}
601
602static GSM_Error N7110_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
603{
604 GSM_MemoryEntry pbk;
605 GSM_Error error;
606 unsigned char OpReq[] = {N6110_FRAME_HEADER, 0x70};
607
608 s->Phone.Data.Bitmap=Bitmap;
609 switch (Bitmap->Type) {
610 case GSM_StartupLogo:
611 smprintf(s, "Getting startup logo\n");
612 return N71_92_GetPhoneSetting(s, ID_GetBitmap, 0x15);
613 case GSM_WelcomeNote_Text:
614 smprintf(s, "Getting welcome note\n");
615 return N71_92_GetPhoneSetting(s, ID_GetBitmap, 0x02);
616 case GSM_DealerNote_Text:
617 smprintf(s, "Getting dealer note\n");
618 return N71_92_GetPhoneSetting(s, ID_GetBitmap, 0x17);
619 case GSM_CallerGroupLogo:
620 pbk.MemoryType = MEM7110_CG;
621 pbk.Location = Bitmap->Location;
622 smprintf(s, "Getting caller group logo\n");
623 error=N7110_GetMemory(s,&pbk);
624 if (error==ERR_NONE) NOKIA_GetDefaultCallerGroupName(s,Bitmap);
625 return error;
626 case GSM_OperatorLogo:
627 smprintf(s, "Getting operator logo\n");
628 /* This is like DCT3_GetNetworkInfo */
629 return GSM_WaitFor (s, OpReq, 4, 0x0a, 4, ID_GetBitmap);
630 case GSM_PictureImage:
631 /* 7110 doesn't support it */
632 if (strcmp(s->Phone.Data.Model,"NSE-5") == 0) return ERR_NOTSUPPORTED;
633 return N7110_GetPictureImage(s, Bitmap);
634 default:
635 break;
636 }
637 return ERR_NOTSUPPORTED;
638}
639
640static GSM_Error N7110_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
641{
642 GSM_Ringtonedest;
643 GSM_Errorerror;
644 GSM_NetworkInfoNetInfo;
645 int size=200;
646 unsigned charreq[1000] = {0x7C, 0x01, 0x00, 0x0D, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00}; /*Length*/
649 unsigned charreq2[4000] = {N7110_FRAME_HEADER, 0x1F, 0x00,
650 0x87, /* Location */
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
656
657 switch (Ringtone->Format) {
658 case RING_NOTETONE:
659 if (Ringtone->Location==255) {
660 /* 7110 doesn't support it */
661 if (strcmp(s->Phone.Data.Model,"NSE-5") == 0) return ERR_NOTSUPPORTED;
662 *maxlength=GSM_EncodeNokiaRTTLRingtone(*Ringtone, req+11, &size);
663 req[10] = size;
664 error = s->Protocol.Functions->WriteMessage(s, req, size+11, 0x00);
665 if (error!=ERR_NONE) return error;
666 my_sleep(1000);
667 /* We have to make something (not important, what) now */
668 /* no answer from phone*/
669 return DCT3_GetNetworkInfo(s,&NetInfo);
670 }
671 GSM_RingtoneConvert(&dest, Ringtone, RING_NOKIABINARY);
672 break;
673 case RING_NOKIABINARY:
674 memcpy(&dest,Ringtone,sizeof(GSM_Ringtone));
675 break;
676 default:
677 return ERR_NOTSUPPORTED;
678 }
679 req2[5]=N7110_ReturnBinaryRingtoneLocation(s->Phone.Data.Model)+Ringtone->Location;
680 CopyUnicodeString(req2+6,Ringtone->Name);
681 memcpy(req2+37,dest.NokiaBinary.Frame,dest.NokiaBinary.Length);
682 error = s->Protocol.Functions->WriteMessage(s, req2, 37+dest.NokiaBinary.Length, 0x1F);
683 if (error!=ERR_NONE) return error;
684 my_sleep(1000);
685 /* We have to make something (not important, what) now */
686 /* no answer from phone*/
687 return DCT3_GetNetworkInfo(s,&NetInfo);
688}
689
690static GSM_Error N7110_ReplySaveSMSMessage(GSM_Protocol_Message msg, GSM_StateMachine *s)
691{
692 GSM_Phone_Data *Data = &s->Phone.Data;
693
694 switch (msg.Buffer[3]) {
695 case 0x05:
696 smprintf(s, "SMS message saving status\n");
697 smprintf(s, "Saved in folder %i at location %i\n",msg.Buffer[4], msg.Buffer[5]*256+msg.Buffer[6]);
698 if (msg.Buffer[4] == 0xf8) {
699 N7110_SetSMSLocation(s, Data->SaveSMSMessage,0x08,msg.Buffer[5]*256+msg.Buffer[6]);
700 Data->SaveSMSMessage->Folder = 0x01;
701 } else {
702 N7110_SetSMSLocation(s, Data->SaveSMSMessage,msg.Buffer[4],msg.Buffer[5]*256+msg.Buffer[6]);
703 Data->SaveSMSMessage->Folder = msg.Buffer[4] / 0x08;
704 }
705 return ERR_NONE;
706 case 0x06:
707 smprintf(s, "SMS message saving status\n");
708 switch (msg.Buffer[4]) {
709 case 0x03:
710 smprintf(s, "Too high location ?\n");
711 return ERR_INVALIDLOCATION;
712 default:
713 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
714 }
715 break;
716 case 0x84:
717 smprintf(s, "Name for SMS changed OK to \"%s\"\n",DecodeUnicodeString(msg.Buffer+7));
718 smprintf(s, "Saved in folder %i at location %i\n",msg.Buffer[4], msg.Buffer[5]*256+msg.Buffer[6]);
719 if (msg.Buffer[4] == 0xf8) {
720 N7110_SetSMSLocation(s, Data->SaveSMSMessage,0x08,msg.Buffer[5]*256+msg.Buffer[6]);
721 Data->SaveSMSMessage->Folder = 0x01;
722 } else {
723 N7110_SetSMSLocation(s, Data->SaveSMSMessage,msg.Buffer[4],msg.Buffer[5]*256+msg.Buffer[6]);
724 Data->SaveSMSMessage->Folder = msg.Buffer[4] / 0x08;
725 }
726 return ERR_NONE;
727 }
728 return ERR_UNKNOWNRESPONSE;
729}
730
731static GSM_Error N7110_PrivSetSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
732{
733 int length, location;
734 unsigned char folderid, folder;
735 GSM_Error error;
736 unsigned char req[256] = {N6110_FRAME_HEADER, 0x04,
737 0x03, /* sms status */
738 0x10, /* folder */
739 0x00,0x00, /* location */
740 0x00};
741 unsigned char NameReq[200] = {N6110_FRAME_HEADER, 0x83};
742
743 switch (sms->State) {
744 case SMS_Read: req[4] = 0x01; break;
745 case SMS_UnRead: req[4] = 0x03; break;
746 case SMS_Sent: req[4] = 0x05; break;
747 case SMS_UnSent: req[4] = 0x07; break;
748 }
749
750 N7110_GetSMSLocation(s, sms, &folderid, &location);
751 req[5] = folderid;
752 req[6] = location / 256;
753 req[7] = location;
754
755 /* Outbox */
756 if (folderid == 0x10 && (sms->State == SMS_Sent || sms->State == SMS_UnSent)) {
757 /* We will use SIM Outbox */
758 sms->PDU = SMS_Submit;
759 }
760 /* Inbox */
761 if (folderid == 0x08 && sms->State == SMS_UnRead) {
762 /* We will use SIM Inbox */
763 req[5] = 0xf8;
764 }
765
766 switch (sms->PDU) {
767 case SMS_Deliver:
768 error = PHONE_EncodeSMSFrame(s,sms,req+9,PHONE_SMSDeliver,&length,true);
769 break;
770 case SMS_Submit:
771 smprintf(s, "Saving SMS template\n");
772 error = PHONE_EncodeSMSFrame(s,sms,req+9,N7110_SMSTemplate,&length,true);
773 req[8] = 0x02;/* SMS Template info */
774 break;
775 default:
776 return ERR_UNKNOWN;
777 }
778 if (error != ERR_NONE) return error;
779
780 s->Phone.Data.SaveSMSMessage=sms;
781 smprintf(s, "Saving sms\n");
782 error=GSM_WaitFor (s, req, 9+length, 0x14, 4, ID_SaveSMSMessage);
783 if (error == ERR_NONE && UnicodeLength(sms->Name)!=0) {
784 folder = sms->Folder;
785 sms->Folder = 0;
786 N7110_GetSMSLocation(s, sms, &folderid, &location);
787 length = 4;
788 NameReq[length++] = folderid;
789 NameReq[length++] = location / 256;
790 NameReq[length++] = location;
791 CopyUnicodeString(NameReq+length, sms->Name);
792 length = length+UnicodeLength(sms->Name)*2;
793 NameReq[length++] = 0;
794 NameReq[length++] = 0;
795 error=GSM_WaitFor (s, NameReq, length, 0x14, 4, ID_SaveSMSMessage);
796 sms->Folder = folder;
797 }
798 return error;
799}
800
801static GSM_Error N7110_SetSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
802{
803 int location;
804 unsigned char folderid;
805
806 N7110_GetSMSLocation(s, sms, &folderid, &location);
807 if (location == 0) return ERR_INVALIDLOCATION;
808 return N7110_PrivSetSMSMessage(s, sms);
809}
810
811static GSM_Error N7110_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
812{
813 int location;
814 unsigned char folderid;
815
816 N7110_GetSMSLocation(s, sms, &folderid, &location);
817 location = 0;
818 N7110_SetSMSLocation(s, sms, folderid, location);
819 return N7110_PrivSetSMSMessage(s, sms);
820}
821
822static GSM_Error N7110_ReplyClearOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
823{
824 smprintf(s, "Clearing operator logo.....\n");
825 return ERR_NONE;
826}
827
828static GSM_Error N7110_ReplySetOperatorLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
829{
830 smprintf(s, "Setting operator logo.....\n");
831 return ERR_NONE;
832}
833
834static GSM_Error N7110_SetCallerLogo(GSM_StateMachine *s, GSM_Bitmap *bitmap)
835{
836 int block=0, i, Width, Height;
837 unsigned int count = 18;
838 char string[500];
839 unsigned char req[500] = {N6110_FRAME_HEADER, 0x0b, 0x00,
840 0x01, 0x01, 0x00, 0x00, 0x0c,
841 0x00, 0x10, /* memory type */
842 0x00, 0x00, /* location */
843 0x00, 0x00, 0x00};
844
845 req[13] = bitmap->Location;
846
847 /* Enabling/disabling logo */
848 if (bitmap->DefaultBitmap) {
849 string[0] = 0; //disabling
850 } else {
851 string[0] = bitmap->BitmapEnabled?1:0;
852 }
853 string[1] = 0;
854 count += N71_65_PackPBKBlock(s, N7110_PBK_LOGOON, 2, block++, string, req + count);
855
856 /* Ringtone */
857 if (!bitmap->DefaultRingtone) {
858 string[0] = bitmap->RingtoneID;
859 string[1] = 0;
860 count += N71_65_PackPBKBlock(s, N7110_PBK_RINGTONE_ID, 2, block++, string, req + count);
861 }
862
863 /* Number of group */
864 string[0] = bitmap->Location;
865 string[1] = 0;
866 count += N71_65_PackPBKBlock(s, N7110_PBK_GROUP, 2, block++, string, req + count);
867
868 /* Name */
869 if (!bitmap->DefaultName) {
870 i = UnicodeLength(bitmap->Text) * 2;
871 string[0] = i + 2;
872 memcpy(string + 1, bitmap->Text, i);
873 string[i + 1] = 0;
874 count += N71_65_PackPBKBlock(s, N7110_PBK_NAME, i + 2, block++, string, req + count);
875 }
876
877 /* Logo */
878 if (bitmap->DefaultBitmap) {
879 bitmap->BitmapWidth = 72;
880 bitmap->BitmapHeight = 14;
881 GSM_ClearBitmap(bitmap);
882 }
883 PHONE_GetBitmapWidthHeight(GSM_NokiaCallerLogo, &Width, &Height);
884 string[0] = Width;
885 string[1] = Height;
886 string[2] = 0;
887 string[3] = 0;
888 string[4] = PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0);
889 PHONE_EncodeBitmap(GSM_NokiaCallerLogo, string + 5, bitmap);
890 count += N71_65_PackPBKBlock(s, N7110_PBK_GROUPLOGO, PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 5, block++, string, req + count);
891
892 req[17] = block;
893
894 return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetBitmap);
895}
896
897static GSM_Error N7110_ReplySetPicture(GSM_Protocol_Message msg, GSM_StateMachine *s)
898{
899 smprintf(s, "Picture Image written OK, folder %i, location %i\n",msg.Buffer[4],msg.Buffer[5]*256+msg.Buffer[6]);
900 return ERR_NONE;
901}
902
903static GSM_Error N7110_SetPictureImage(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
904{
905 unsigned char folder;
906 GSM_Error error;
907 int location, i, count, Width, Height;
908 GSM_Phone_Bitmap_TypesType = GSM_NokiaPictureImage;
909 unsigned char req[500] = {N6110_FRAME_HEADER, 0x50, 0x07,
910 0x00, /* location*/
911 0x00, 0x00, /* index*/
912 0x07};
913
914 error=N7110_GetPictureImageLocation(s, Bitmap, &folder, &location);
915 switch (error) {
916 case ERR_NONE:
917 req[5] = folder;
918 req[6] = location / 256;
919 req[7] = location % 256;
920 break;
921 case ERR_INVALIDLOCATION:
922 req[5] = 0x21;/* Save in Templates folder */
923 req[6] = 0;
924 req[7] = 0;
925 break;
926 default:
927 return error;
928 }
929
930 /* Cleaning */
931 for (i=0;i<36;i++) req[i+9]=0;
932
933 count=8;
934 if (UnicodeLength(Bitmap->Text)==0) {
935 count+=2 ;req[count]=0x0c;
936 count+=2 ;req[count]=0x0d;
937 count+=2 ;req[count]=0x0e;
938 count+=2 ;req[count]=0x0f;
939 count+=2 ;req[count]=0x10;
940 count+=2 ;req[count]=0x11;
941 count+=23;req[count]=0x02;
942 count++ ;
943 } else {
944 count+=2 ;req[count]=0x54;
945 count++ ;req[count]=0xd4;
946 count++ ;req[count]=0x0d;
947 count+=2 ;req[count]=0x0e;
948 count+=2 ;req[count]=0x0f;
949 count+=2 ;req[count]=0x10;
950 count+=2 ;req[count]=0x11;
951 count+=21;req[count]=0x01;
952 count+=3 ;
953 }
954 req[count] = 0x01;
955 count+=2;
956 req[count++] = 0x01;
957 PHONE_GetBitmapWidthHeight(Type, &Width, &Height);
958 req[count++] = Width;
959 req[count++] = Height;
960 req[count++] = PHONE_GetBitmapSize(Type,0,0) / 256;
961 req[count++] = PHONE_GetBitmapSize(Type,0,0) % 256;
962 PHONE_EncodeBitmap(Type, req + count, Bitmap);
963 count += PHONE_GetBitmapSize(Type,0,0);
964 if (UnicodeLength(Bitmap->Text)!=0) {
965 req[count] = UnicodeLength(Bitmap->Text);
966 GSM_PackSevenBitsToEight(0, Bitmap->Text, req+count+1,strlen(Bitmap->Text));
967 count = count + req[count];
968 } else {
969 req[count++]=0x00;
970 }
971 req[count++]=0x00;
972 smprintf(s, "Setting Picture Image\n");
973 return GSM_WaitFor (s, req, count, 0x14, 4, ID_SetBitmap);
974}
975
976static GSM_Error N7110_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
977{
978 GSM_Error error;
979 GSM_Phone_Bitmap_TypesType;
980 int Width, Height, i;
981 unsigned char reqStartup[1000] = {N7110_FRAME_HEADER, 0xec,
982 0x15, /* Startup Logo setting */
983 0x00, 0x00, 0x00, 0x04, 0xc0, 0x02, 0x00,
984 0x00, /* Bitmap height */
985 0xc0, 0x03, 0x00,
986 0x00, /* Bitmap width */
987 0xc0, 0x04, 0x03, 0x00};
988 unsigned char reqOp[1000] = {N7110_FRAME_HEADER, 0xa3, 0x01,
989 0x00, /* logo disabled */
990 0x00, 0xf0, 0x00,/* network code (000 00) */
991 0x00 ,0x04,
992 0x08, /* length of rest */
993 0x00, 0x00, /* Bitmap width / height */
994 0x00,
995 0x00, /* Bitmap size */
996 0x00, 0x00};
997 unsigned char reqClrOp[] = {0x00, 0x01, 0x00, 0xaf, 0x00};
998 unsigned char reqStartupText[500] = {N7110_FRAME_HEADER, 0xec,
999 0x02}; /* Startup Text setting */
1000
1001 switch (Bitmap->Type) {
1002 case GSM_StartupLogo:
1003 if (Bitmap->Location!=1) return ERR_NOTSUPPORTED;
1004 Type=GSM_Nokia6210StartupLogo;
1005 if (strcmp(s->Phone.Data.Model,"NSE-5") == 0) Type=GSM_Nokia7110StartupLogo;
1006 PHONE_GetBitmapWidthHeight(Type, &Width, &Height);
1007 reqStartup[12] = Height;
1008 reqStartup[16] = Width;
1009 PHONE_EncodeBitmap(Type, reqStartup + 21, Bitmap);
1010 smprintf(s, "Setting startup logo\n");
1011 return GSM_WaitFor (s, reqStartup, 21+PHONE_GetBitmapSize(Type,0,0), 0x7A, 4, ID_SetBitmap);
1012 case GSM_WelcomeNote_Text:
1013 CopyUnicodeString(reqStartupText + 5, Bitmap->Text);
1014 i = 6 + UnicodeLength(Bitmap->Text) * 2;
1015 reqStartupText[i++] = 0;
1016 reqStartupText[i++] = 0;
1017 return GSM_WaitFor (s, reqStartupText, i, 0x7A, 4, ID_SetBitmap);
1018 case GSM_DealerNote_Text:
1019 reqStartupText[4] = 0x17;
1020 CopyUnicodeString(reqStartupText + 5, Bitmap->Text);
1021 i = 6 + UnicodeLength(Bitmap->Text) * 2;
1022 reqStartupText[i++] = 0;
1023 reqStartupText[i++] = 0;
1024 return GSM_WaitFor (s, reqStartupText, i, 0x7A, 4, ID_SetBitmap);
1025 case GSM_OperatorLogo:
1026 /* We want to set operator logo, not clear */
1027 if (strcmp(Bitmap->NetworkCode,"000 00")) {
1028 reqOp[5] = 0x01;/* Logo enabled */
1029 NOKIA_EncodeNetworkCode(reqOp+6, Bitmap->NetworkCode);
1030 Type = GSM_Nokia7110OperatorLogo;
1031 reqOp[11] = 8 + PHONE_GetBitmapSize(Type,0,0);
1032 PHONE_GetBitmapWidthHeight(Type, &Width, &Height);
1033 reqOp[12]=Width;
1034 reqOp[13]=Height;
1035 reqOp[15]=PHONE_GetBitmapSize(Type,0,0);
1036 PHONE_EncodeBitmap(Type, reqOp + 18, Bitmap);
1037 smprintf(s, "Setting operator logo\n");
1038 return GSM_WaitFor (s, reqOp, 18+PHONE_GetBitmapSize(Type,0,0), 0x0A, 4, ID_SetBitmap);
1039 } else {
1040 smprintf(s, "Clearing operator logo\n");
1041 for (i=0;i<5;i++) {
1042 reqClrOp[4]=i;
1043 error=GSM_WaitFor (s, reqClrOp, 5, 0x0A, 4, ID_SetBitmap);
1044 if (error!=ERR_NONE) return error;
1045 }
1046 return GSM_WaitFor (s, reqOp, 18, 0x0A, 4, ID_SetBitmap);
1047 }
1048 case GSM_CallerGroupLogo:
1049 return N7110_SetCallerLogo(s,Bitmap);
1050 case GSM_PictureImage:
1051 return N7110_SetPictureImage(s,Bitmap);
1052 default:
1053 break;
1054 }
1055 return ERR_NOTSUPPORTED;
1056}
1057
1058static GSM_Error N7110_ReplyDeleteMemory(GSM_Protocol_Message msg, GSM_StateMachine *s)
1059{
1060 smprintf(s, "Phonebook entry deleted\n");
1061 return ERR_NONE;
1062}
1063
1064static GSM_Error N7110_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1065{
1066 unsigned char req[] = {N7110_FRAME_HEADER, 0x0f, 0x00, 0x01,
1067 0x04, 0x00, 0x00, 0x0c, 0x01, 0xff,
1068 0x00, 0x01, /* location*/
1069 0x05, /* memory type*/
1070 0x00, 0x00, 0x00};
1071
1072 req[12] = entry->Location / 256;
1073 req[13] = entry->Location % 256;
1074
1075 req[14] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
1076 if (req[14]==0xff) return ERR_NOTSUPPORTED;
1077
1078 smprintf(s, "Deleting phonebook entry\n");
1079 return GSM_WaitFor (s, req, 18, 0x03, 4, ID_SetMemory);
1080}
1081
1082static GSM_Error N7110_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1083{
1084 int count = 18, blocks;
1085 unsigned char req[500] = {N7110_FRAME_HEADER, 0x0b, 0x00,
1086 0x01, 0x01, 0x00, 0x00, 0x0c,
1087 0x00, 0x00, /* memory type*/
1088 0x00, 0x00, /* location*/
1089 0x00, 0x00, 0x00};
1090
1091 if (entry->Location == 0) return ERR_NOTSUPPORTED;
1092
1093 req[11] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
1094 if (req[11]==0xff) return ERR_NOTSUPPORTED;
1095
1096 req[12] = entry->Location >> 8;
1097 req[13] = entry->Location & 0xff;
1098
1099 count = count + N71_65_EncodePhonebookFrame(s, req+18, *entry, &blocks, false, IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_VOICETAGS));
1100 req[17] = blocks;
1101
1102 smprintf(s, "Writing phonebook entry\n");
1103 return GSM_WaitFor (s, req, count, 0x03, 4, ID_SetMemory);
1104}
1105
1106static GSM_Error N7110_DeleteSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
1107{
1108 unsigned char folderid;
1109 int location;
1110 unsigned char req[] = {N7110_FRAME_HEADER, 0x0a,
1111 0x00, /* folder */
1112 0x00, 0x00, /* location */
1113 0x01};
1114
1115 N7110_GetSMSLocation(s, sms, &folderid, &location);
1116 req[4] = folderid;
1117 req[5] = location / 256;
1118 req[6] = location;
1119
1120 smprintf(s, "Deleting sms\n");
1121 return GSM_WaitFor (s, req, 8, 0x14, 4, ID_DeleteSMSMessage);
1122}
1123
1124static GSM_Error N7110_ReplyGetSMSStatus(GSM_Protocol_Message msg, GSM_StateMachine *s)
1125{
1126 GSM_Phone_Data *Data = &s->Phone.Data;
1127
1128 smprintf(s, "SMS status received\n");
1129 switch (msg.Buffer[3]) {
1130 case 0x37:
1131 smprintf(s, "SIM size : %i\n",msg.Buffer[8]*256+msg.Buffer[9]);
1132 smprintf(s, "Used in phone memory : %i\n",msg.Buffer[10]*256+msg.Buffer[11]);
1133 smprintf(s, "Unread in phone memory : %i\n",msg.Buffer[12]*256+msg.Buffer[13]);
1134 smprintf(s, "Used in SIM : %i\n",msg.Buffer[14]*256+msg.Buffer[15]);
1135 smprintf(s, "Unread in SIM : %i\n",msg.Buffer[16]*256+msg.Buffer[17]);
1136 Data->SMSStatus->SIMSize= msg.Buffer[8]*256+msg.Buffer[9];
1137 Data->SMSStatus->PhoneUsed= msg.Buffer[10]*256+msg.Buffer[11];
1138 Data->SMSStatus->PhoneUnRead = msg.Buffer[12]*256+msg.Buffer[13];
1139 Data->SMSStatus->PhoneSize= 150;
1140 Data->SMSStatus->SIMUsed = msg.Buffer[14]*256+msg.Buffer[15];
1141 Data->SMSStatus->SIMUnRead = msg.Buffer[16]*256+msg.Buffer[17];
1142 return ERR_NONE;
1143 case 0x38:
1144 smprintf(s, "Error. No PIN ?\n");
1145 return ERR_SECURITYERROR;
1146 }
1147 return ERR_UNKNOWNRESPONSE;
1148}
1149
1150static GSM_Error N7110_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status)
1151{
1152 GSM_Error error;
1153 GSM_Phone_N7110Data*Priv = &s->Phone.Data.Priv.N7110;
1154
1155 error = DCT3_GetSMSStatus(s,status);
1156 if (error != ERR_NONE) return error;
1157
1158 /* 6210 family doesn't show in frame with SMS status info
1159 * about Templates. We get separately info about this SMS folder.
1160 */
1161 error = N7110_GetSMSFolderStatus(s, 0x20);
1162 if (error != ERR_NONE) return error;
1163 status->TemplatesUsed = Priv->LastSMSFolder.Number;
1164
1165 return ERR_NONE;
1166}
1167
1168static GSM_Error N7110_ReplyGetProfileFeature(GSM_Protocol_Message msg, GSM_StateMachine *s)
1169{
1170 GSM_Phone_Data *Data = &s->Phone.Data;
1171
1172 switch (msg.Buffer[3]) {
1173 case 0x02:
1174 smprintf(s, "Profile feature %02x with value %02x\n",msg.Buffer[6],msg.Buffer[10]);
1175 switch (msg.Buffer[6]) {
1176 case 0x03:
1177 smprintf(s, "Ringtone ID\n");
1178 Data->Profile->FeatureID[Data->Profile->FeaturesNumber] = Profile_RingtoneID;
1179 Data->Profile->FeatureValue[Data->Profile->FeaturesNumber] = msg.Buffer[10];
1180 Data->Profile->FeaturesNumber++;
1181 break;
1182 case 0x08:/* Caller groups */
1183 NOKIA_FindFeatureValue(s, Profile71_65,msg.Buffer[6],msg.Buffer[10],Data,true);
1184 break;
1185 case 0x09:/* Autoanswer */
1186 if (Data->Profile->CarKitProfile || Data->Profile->HeadSetProfile) {
1187 NOKIA_FindFeatureValue(s, Profile71_65,msg.Buffer[6],msg.Buffer[10],Data,false);
1188 }
1189 break;
1190 case 0xff :
1191 CopyUnicodeString(Data->Profile->Name, msg.Buffer+10);
1192 smprintf(s, "profile Name: \"%s\"\n", DecodeUnicodeString(Data->Profile->Name));
1193 Data->Profile->DefaultName = false;
1194 break;
1195 default:
1196 NOKIA_FindFeatureValue(s, Profile71_65,msg.Buffer[6],msg.Buffer[10],Data,false);
1197 }
1198 return ERR_NONE;
1199 }
1200 return ERR_UNKNOWNRESPONSE;
1201}
1202
1203static GSM_Error N7110_GetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
1204{
1205 GSM_Error error;
1206 int i;
1207 unsigned char Features[12] = {0x00,0x02,0x03,0x04,0x05,0x06,
1208 0x07,0x08,0x09,0xff,
1209 0x0a,0x22};
1210 unsigned char req[] = {N6110_FRAME_HEADER, 0x01, 0x01, 0x01, 0x01,
1211 0x00, /* Profile Location*/
1212 0xff}; /* Feature number*/
1213
1214 if (Profile->Location > 7) return ERR_INVALIDLOCATION;
1215
1216 Profile->CarKitProfile = false;
1217 Profile->HeadSetProfile = false;
1218 if (Profile->Location == 6) Profile->CarKitProfile = true;
1219 if (Profile->Location == 7) Profile->HeadSetProfile = true;
1220
1221 Profile->FeaturesNumber = 0;
1222
1223 s->Phone.Data.Profile=Profile;
1224 for (i = 0; i < 10; i++) {
1225 req[7] = Profile->Location;
1226 req[8] = Features[i];
1227 smprintf(s, "Getting profile feature\n");
1228 error = GSM_WaitFor (s, req, 9, 0x39, 4, ID_GetProfile);
1229 if (error!=ERR_NONE) return error;
1230 }
1231 NOKIA_GetDefaultProfileName(s, Profile);
1232 Profile->Active = false;
1233 return error;
1234}
1235
1236static GSM_Error N7110_ReplySetProfileFeature(GSM_Protocol_Message msg, GSM_StateMachine *s)
1237{
1238 smprintf(s, "Profile feature set\n");
1239 return ERR_NONE;
1240}
1241
1242static GSM_Error N7110_SetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
1243{
1244 int i;
1245 bool found;
1246 GSM_Errorerror;
1247 unsigned charID,Value;
1248 unsigned char req[] = {N6110_FRAME_HEADER, 0x03, 0x01, 0x01, 0x03,
1249 0x02, /* feature number*/
1250 0x01, /* Profile Location */
1251 0x01,
1252 0xff}; /* Value */
1253
1254 for (i=0;i<Profile->FeaturesNumber;i++) {
1255 found = false;
1256 switch (Profile->FeatureID[i]) {
1257 case Profile_RingtoneID:
1258 ID = 0x03;
1259 Value = Profile->FeatureValue[i];
1260 found = true;
1261 break;
1262 default:
1263 found=NOKIA_FindPhoneFeatureValue(
1264 s,
1265 Profile71_65,
1266 Profile->FeatureID[i],Profile->FeatureValue[i],
1267 &ID,&Value);
1268 }
1269 if (found) {
1270 req[7] = ID;
1271 req[8] = Profile->Location;
1272 req[10] = Value;
1273 smprintf(s, "Setting profile feature\n");
1274 error = GSM_WaitFor (s, req, 11, 0x39, 4, ID_SetProfile);
1275 if (error!=ERR_NONE) return error;
1276 }
1277 }
1278 return ERR_NONE;
1279}
1280
1281static GSM_Error N7110_GetSpeedDial(GSM_StateMachine *s, GSM_SpeedDial *SpeedDial)
1282{
1283 GSM_MemoryEntry pbk;
1284 GSM_Error error;
1285
1286 pbk.MemoryType = MEM7110_SP;
1287 pbk.Location = SpeedDial->Location;
1288 SpeedDial->MemoryLocation = 0;
1289 s->Phone.Data.SpeedDial = SpeedDial;
1290
1291 smprintf(s, "Getting speed dial\n");
1292 error=N7110_GetMemory(s,&pbk);
1293 switch (error) {
1294 case ERR_NOTSUPPORTED:
1295 smprintf(s, "No speed dials set in phone\n");
1296 return ERR_EMPTY;
1297 case ERR_NONE:
1298 if (SpeedDial->MemoryLocation == 0) {
1299 smprintf(s, "Speed dial not assigned or error in firmware\n");
1300 return ERR_EMPTY;
1301 }
1302 return ERR_NONE;
1303 default:
1304 return error;
1305 }
1306}
1307
1308static GSM_Error N7110_ReplyIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s)
1309{
1310 GSM_SMSMessage sms;
1311 GSM_Phone_Data *Data = &s->Phone.Data;
1312
1313#ifdef DEBUG
1314 smprintf(s, "SMS message received\n");
1315 sms.State = SMS_UnRead;
1316 sms.InboxFolder = true;
1317 DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+8);
1318#endif
1319 if (Data->EnableIncomingSMS && s->User.IncomingSMS!=NULL) {
1320 sms.State = SMS_UnRead;
1321 sms.InboxFolder = true;
1322 DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+8);
1323
1324 s->User.IncomingSMS(s->CurrentConfig->Device,sms);
1325 }
1326 return ERR_NONE;
1327}
1328
1329static GSM_Error N7110_Initialise (GSM_StateMachine *s)
1330{
1331#ifdef DEBUG
1332 DCT3_SetIncomingCB(s,true);
1333#endif
1334#ifdef GSM_ENABLE_N71_92INCOMINGINFO
1335 /* Enables various things like incoming SMS, call info, etc. */
1336 return N71_65_EnableFunctions (s, "\x01\x02\x06\x0A\x14\x17", 6);
1337#endif
1338 return ERR_NONE;
1339}
1340
1341static GSM_Error N7110_ReplyGetCalendarInfo(GSM_Protocol_Message msg, GSM_StateMachine *s)
1342{
1343 /* Old method 1 for accessing calendar */
1344 return N71_65_ReplyGetCalendarInfo1(msg, s, &s->Phone.Data.Priv.N7110.LastCalendar);
1345}
1346
1347#ifdef DEBUG
1348static GSM_Error N7110_ReplyGetCalendarNotePos(GSM_Protocol_Message msg, GSM_StateMachine *s)
1349{
1350 /* Old method 1 for accessing calendar */
1351 return N71_65_ReplyGetCalendarNotePos1(msg, s, &s->Phone.Data.Priv.N7110.FirstCalendarPos);
1352}
1353#endif
1354
1355static GSM_Error N7110_GetNextCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note, bool start)
1356{
1357 return N71_65_GetNextCalendar1(s,Note,start,&s->Phone.Data.Priv.N7110.LastCalendar,&s->Phone.Data.Priv.N7110.LastCalendarYear,&s->Phone.Data.Priv.N7110.LastCalendarPos);
1358 //return N71_65_GetNextCalendar2(s,Note,start,&s->Phone.Data.Priv.N7110.LastCalendarYear,&s->Phone.Data.Priv.N7110.LastCalendarPos);
1359}
1360
1361static GSM_Error N7110_GetCalendarStatus(GSM_StateMachine *s, GSM_CalendarStatus *Status)
1362{
1363 GSM_Error error;
1364
1365 /* Method 1 */
1366 error=N71_65_GetCalendarInfo1(s, &s->Phone.Data.Priv.N7110.LastCalendar);
1367 if (error!=ERR_NONE) return error;
1368 Status->Used = s->Phone.Data.Priv.N6510.LastCalendar.Number;
1369 return ERR_NONE;
1370
1371 /* Method 2 */
1372 // return GE_NOTSUPPORTED;
1373}
1374
1375static GSM_Error N7110_AddCalendar(GSM_StateMachine *s, GSM_CalendarEntry *Note)
1376{
1377 //return N71_65_AddCalendar1(s, Note, NULL);
1378 return N71_65_AddCalendar2(s,Note);
1379}
1380
1381static GSM_Error N7110_ReplyGetNetworkInfoError(GSM_Protocol_Message msg, GSM_StateMachine *s)
1382{
1383 smprintf(s, "Probably means no PIN\n");
1384 return ERR_SECURITYERROR;
1385}
1386
1387static GSM_Error N7110_SetIncomingCall(GSM_StateMachine *s, bool enable)
1388{
1389#ifndef GSM_ENABLE_N71_92INCOMINGINFO
1390 return ERR_SOURCENOTAVAILABLE;
1391#endif
1392 return NOKIA_SetIncomingCall(s,enable);
1393}
1394
1395static GSM_Error N7110_SetIncomingUSSD(GSM_StateMachine *s, bool enable)
1396{
1397#ifndef GSM_ENABLE_N71_92INCOMINGINFO
1398 return ERR_SOURCENOTAVAILABLE;
1399#endif
1400 return NOKIA_SetIncomingUSSD(s,enable);
1401}
1402
1403static GSM_Error N7110_SetIncomingSMS(GSM_StateMachine *s, bool enable)
1404{
1405#ifndef GSM_ENABLE_N71_92INCOMINGINFO
1406 return ERR_SOURCENOTAVAILABLE;
1407#endif
1408 return NOKIA_SetIncomingSMS(s,enable);
1409}
1410
1411GSM_Error N7110_AnswerCall(GSM_StateMachine *s, int ID, bool all)
1412{
1413 if (!all) return DCT3DCT4_AnswerCall(s,ID);
1414 return DCT3_AnswerAllCalls(s);
1415}
1416
1417GSM_Error N7110_SetCallDivert(GSM_StateMachine *s, GSM_MultiCallDivert *divert)
1418{
1419 GSM_Errorerror;
1420 int i;
1421
1422 /* No answer from phone side */
1423 i = s->ReplyNum;
1424 s->ReplyNum = 1;
1425 error = DCT3DCT4_SetCallDivert(s,divert);
1426 s->ReplyNum = i;
1427 return error;
1428}
1429
1430GSM_Error N7110_CancelAllDiverts(GSM_StateMachine *s)
1431{
1432 GSM_Errorerror;
1433 int i;
1434
1435 /* No answer from phone side */
1436 i = s->ReplyNum;
1437 s->ReplyNum = 1;
1438 error = DCT3DCT4_CancelAllDiverts(s);
1439 s->ReplyNum = i;
1440 return error;
1441}
1442
1443static GSM_Reply_Function N7110ReplyFunctions[] = {
1444 {N71_65_ReplyCallInfo, "\x01",0x03,0x02,ID_IncomingFrame },
1445 {N71_65_ReplyCallInfo, "\x01",0x03,0x03,ID_IncomingFrame },
1446 {N71_65_ReplyCallInfo, "\x01",0x03,0x04,ID_IncomingFrame },
1447 {N71_65_ReplyCallInfo, "\x01",0x03,0x05,ID_IncomingFrame },
1448 {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_AnswerCall },
1449 {N71_65_ReplyCallInfo, "\x01",0x03,0x07,ID_IncomingFrame },
1450 {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_CancelCall },
1451 {N71_65_ReplyCallInfo, "\x01",0x03,0x09,ID_IncomingFrame },
1452 {N71_65_ReplyCallInfo, "\x01",0x03,0x0A,ID_IncomingFrame },
1453 {N71_65_ReplyCallInfo, "\x01",0x03,0x0B,ID_IncomingFrame },
1454 {N71_65_ReplyCallInfo, "\x01",0x03,0x0C,ID_IncomingFrame },
1455 {N71_65_ReplySendDTMF, "\x01",0x03,0x51,ID_SendDTMF },
1456 {N71_65_ReplyCallInfo, "\x01",0x03,0x53,ID_IncomingFrame },
1457 {N71_65_ReplySendDTMF, "\x01",0x03,0x59,ID_SendDTMF },
1458 {N71_65_ReplySendDTMF, "\x01",0x03,0x5E,ID_SendDTMF },
1459
1460 {DCT3_ReplySendSMSMessage, "\x02",0x03,0x02,ID_IncomingFrame },
1461 {DCT3_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame },
1462 {N7110_ReplyIncomingSMS, "\x02",0x03,0x10,ID_IncomingFrame },
1463#ifdef GSM_ENABLE_CELLBROADCAST
1464 {DCT3_ReplySetIncomingCB, "\x02",0x03,0x21,ID_SetIncomingCB },
1465 {DCT3_ReplySetIncomingCB, "\x02",0x03,0x22,ID_SetIncomingCB },
1466 {DCT3_ReplyIncomingCB, "\x02",0x03,0x23,ID_IncomingFrame },
1467#endif
1468 {DCT3_ReplySetSMSC, "\x02",0x03,0x31,ID_SetSMSC },
1469 {DCT3_ReplyGetSMSC, "\x02",0x03,0x34,ID_GetSMSC },
1470 {DCT3_ReplyGetSMSC, "\x02",0x03,0x35,ID_GetSMSC },
1471#ifdef GSM_ENABLE_CELLBROADCAST
1472 {DCT3_ReplySetIncomingCB, "\x02",0x03,0xCA,ID_SetIncomingCB },
1473#endif
1474
1475 {N7110_ReplyGetMemoryStatus, "\x03",0x03,0x04,ID_GetMemoryStatus },
1476 {N7110_ReplyGetMemory, "\x03",0x03,0x08,ID_GetMemory },
1477 {N7110_ReplyDeleteMemory, "\x03",0x03,0x10,ID_SetMemory },
1478 {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetBitmap },
1479 {N71_65_ReplyWritePhonebook, "\x03",0x03,0x0C,ID_SetMemory },
1480
1481 {N71_65_ReplyUSSDInfo, "\x06",0x03,0x03,ID_IncomingFrame },
1482 {NoneReply, "\x06",0x03,0x06,ID_IncomingFrame },
1483
1484 {DCT3_ReplySIMLogin, "\x09",0x03,0x80,ID_IncomingFrame },
1485 {DCT3_ReplySIMLogout, "\x09",0x03,0x81,ID_IncomingFrame },
1486
1487 {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_GetNetworkInfo },
1488 {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_GetBitmap },
1489 {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_IncomingFrame },
1490 {N7110_ReplyGetNetworkInfoError, "\x0A",0x03,0x72,ID_GetNetworkInfo },
1491 {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x73,ID_IncomingFrame },
1492 {N71_92_ReplyGetSignalQuality, "\x0A",0x03,0x82,ID_GetSignalQuality },
1493 {N7110_ReplySetOperatorLogo, "\x0A",0x03,0xA4,ID_SetBitmap },
1494 {N7110_ReplyClearOperatorLogo, "\x0A",0x03,0xB0,ID_SetBitmap },
1495 {NoneReply, "\x0A",0x03,0xB5,ID_IncomingFrame },
1496
1497#ifdef DEBUG
1498 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x02,ID_SetCalendarNote },/*method 1*/
1499 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x04,ID_SetCalendarNote },/*method 1*/
1500 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x06,ID_SetCalendarNote },/*method 1*/
1501 {N71_65_ReplyAddCalendar1, "\x13",0x03,0x08,ID_SetCalendarNote },/*method 1*/
1502#endif
1503 {N71_65_ReplyDelCalendar, "\x13",0x03,0x0C,ID_DeleteCalendarNote },
1504 {N71_65_ReplyGetNextCalendar1, "\x13",0x03,0x1A,ID_GetCalendarNote },/*method 1*/
1505#ifdef DEBUG
1506 {N7110_ReplyGetCalendarNotePos, "\x13",0x03,0x32,ID_GetCalendarNotePos },/*method 1*/
1507#endif
1508 {N7110_ReplyGetCalendarInfo, "\x13",0x03,0x3B,ID_GetCalendarNotesInfo},/*method 1*/
1509#ifdef DEBUG
1510 {N71_65_ReplyGetNextCalendar2, "\x13",0x03,0x3F,ID_GetCalendarNote },/*method 2*/
1511#endif
1512 {N71_65_ReplyAddCalendar2, "\x13",0x03,0x41,ID_SetCalendarNote },/*method 2*/
1513
1514 {N7110_ReplySaveSMSMessage, "\x14",0x03,0x05,ID_SaveSMSMessage },
1515 {N7110_ReplySaveSMSMessage, "\x14",0x03,0x06,ID_SaveSMSMessage },
1516 {N7110_ReplyGetSMSMessage, "\x14",0x03,0x08,ID_GetSMSMessage },
1517 {N7110_ReplyGetSMSMessage, "\x14",0x03,0x08,ID_GetBitmap },
1518 {N7110_ReplyGetSMSMessage, "\x14",0x03,0x09,ID_GetSMSMessage },
1519 {DCT3_ReplyDeleteSMSMessage, "\x14",0x03,0x0B,ID_DeleteSMSMessage },
1520 {DCT3_ReplyDeleteSMSMessage, "\x14",0x03,0x0C,ID_DeleteSMSMessage },
1521 {N7110_ReplyGetSMSStatus, "\x14",0x03,0x37,ID_GetSMSStatus },
1522 {N7110_ReplyGetSMSStatus, "\x14",0x03,0x38,ID_GetSMSStatus },
1523 {N7110_ReplySetPicture, "\x14",0x03,0x51,ID_SetBitmap },
1524 {N7110_ReplyGetSMSFolderStatus, "\x14",0x03,0x6C,ID_GetSMSFolderStatus },
1525 {N7110_ReplyGetSMSMessage, "\x14",0x03,0x6F,ID_GetSMSMessage },
1526 {N7110_ReplyGetSMSFolders, "\x14",0x03,0x7B,ID_GetSMSFolders },
1527 {N7110_ReplyGetSMSFolders, "\x14",0x03,0x7C,ID_GetSMSFolders },
1528 {N7110_ReplySaveSMSMessage, "\x14",0x03,0x84,ID_SaveSMSMessage },
1529 {N7110_ReplyGetPictureImageInfo, "\x14",0x03,0x97,ID_GetBitmap },
1530 {N7110_ReplyGetSMSFolders, "\x14",0x03,0xCA,ID_GetSMSFolders },
1531
1532 {N71_92_ReplyGetBatteryCharge, "\x17",0x03,0x03,ID_GetBatteryCharge },
1533
1534 {DCT3_ReplySetDateTime, "\x19",0x03,0x61,ID_SetDateTime },
1535 {DCT3_ReplyGetDateTime, "\x19",0x03,0x63,ID_GetDateTime },
1536 {DCT3_ReplySetAlarm, "\x19",0x03,0x6C,ID_SetAlarm },
1537 {DCT3_ReplyGetAlarm, "\x19",0x03,0x6E,ID_GetAlarm },
1538
1539 {N7110_ReplyGetRingtone, "\x1f",0x03,0x23,ID_GetRingtone },
1540 {N7110_ReplyGetRingtone, "\x1f",0x03,0x24,ID_GetRingtone },
1541
1542 {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x01,ID_EnableConnectFunc },
1543 {DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x02,ID_EnableConnectFunc },
1544 {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x04,ID_DisableConnectFunc },
1545 {DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x05,ID_DisableConnectFunc },
1546 {DCT3_ReplyGetWAPBookmark, "\x3f",0x03,0x07,ID_GetWAPBookmark },
1547 {DCT3_ReplyGetWAPBookmark, "\x3f",0x03,0x08,ID_GetWAPBookmark },
1548 {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0A,ID_SetWAPBookmark },
1549 {DCT3DCT4_ReplySetWAPBookmark, "\x3f",0x03,0x0B,ID_SetWAPBookmark },
1550 {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0D,ID_DeleteWAPBookmark },
1551 {DCT3DCT4_ReplyDelWAPBookmark, "\x3f",0x03,0x0E,ID_DeleteWAPBookmark },
1552 {DCT3DCT4_ReplyGetActiveConnectSet,"\x3f",0x03,0x10,ID_GetConnectSet },
1553 {DCT3DCT4_ReplySetActiveConnectSet,"\x3f",0x03,0x13,ID_SetConnectSet },
1554 {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x16,ID_GetConnectSet },
1555 {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x17,ID_GetConnectSet },
1556 {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x19,ID_SetConnectSet },
1557 {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x1A,ID_SetConnectSet },
1558 {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x1C,ID_GetConnectSet },
1559 {DCT3_ReplyGetWAPSettings, "\x3f",0x03,0x1D,ID_GetConnectSet },
1560 {DCT3_ReplySetWAPSettings, "\x3f",0x03,0x1F,ID_SetConnectSet },
1561
1562 {N7110_ReplyGetProfileFeature, "\x39",0x03,0x02,ID_GetProfile },
1563 {N7110_ReplySetProfileFeature, "\x39",0x03,0x04,ID_SetProfile },
1564
1565 {DCT3_ReplyEnableSecurity, "\x40",0x02,0x64,ID_EnableSecurity },
1566 {N61_71_ReplyResetPhoneSettings, "\x40",0x02,0x65,ID_ResetPhoneSettings },
1567 {DCT3_ReplyGetIMEI, "\x40",0x02,0x66,ID_GetIMEI },
1568 {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_DialVoice },
1569 {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_CancelCall },
1570 {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_AnswerCall },
1571 {DCT3_ReplyNetmonitor, "\x40",0x02,0x7E,ID_Netmonitor },
1572 {DCT3_ReplyPlayTone, "\x40",0x02,0x8F,ID_PlayTone },
1573 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetHardware },
1574 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetPPM },
1575 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCA,ID_GetProductCode },
1576 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetManufactureMonth },
1577 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetOriginalIMEI },
1578 {NoneReply, "\x40",0x02,0xFF,ID_IncomingFrame },
1579
1580 {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x02,ID_GetBitmap },
1581 {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x02,ID_SetBitmap },
1582 {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x15,ID_GetBitmap },
1583 {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x15,ID_SetBitmap },
1584 {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x17,ID_GetBitmap },
1585 {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x17,ID_SetBitmap },
1586
1587 {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetModel },
1588 {DCT3DCT4_ReplyGetModelFirmware, "\xD2",0x02,0x00,ID_GetFirmware },
1589 {DCT3_ReplyPressKey, "\xD2",0x02,0x46,ID_PressKey },
1590 {DCT3_ReplyPressKey, "\xD2",0x02,0x47,ID_PressKey },
1591
1592 {NULL, "\x00",0x00,0x00,ID_None }
1593};
1594
1595GSM_Phone_Functions N7110Phone = {
1596 "6210|6250|7110|7190",
1597 N7110ReplyFunctions,
1598 N7110_Initialise,
1599 PHONE_Terminate,
1600 GSM_DispatchMessage,
1601 NOTSUPPORTED, /* ShowStartInfo */
1602 NOKIA_GetManufacturer,
1603 DCT3DCT4_GetModel,
1604 DCT3DCT4_GetFirmware,
1605 DCT3_GetIMEI,
1606 DCT3_GetOriginalIMEI,
1607 DCT3_GetManufactureMonth,
1608 DCT3_GetProductCode,
1609 DCT3_GetHardware,
1610 DCT3_GetPPM,
1611 NOTSUPPORTED, /* GetSIMIMSI */
1612 N71_92_GetDateTime,
1613 N71_92_SetDateTime,
1614 N7110_GetAlarm,
1615 N7110_SetAlarm,
1616 NOTSUPPORTED, /* GetLocale */
1617 NOTSUPPORTED, /* SetLocale */
1618 DCT3_PressKey,
1619 DCT3_Reset,
1620 N61_71_ResetPhoneSettings,
1621 NOTSUPPORTED, /* EnterSecurityCode*/
1622 NOTSUPPORTED, /* GetSecurityStatus*/
1623 NOTSUPPORTED, /* GetDisplayStatus*/
1624 NOTIMPLEMENTED, /* SetAutoNetworkLogin*/
1625 N71_92_GetBatteryCharge,
1626 N71_92_GetSignalQuality,
1627 DCT3_GetNetworkInfo,
1628 NOTSUPPORTED, /* GetCategory */
1629 NOTSUPPORTED, /* AddCategory */
1630 NOTSUPPORTED, /* GetCategoryStatus */
1631 N7110_GetMemoryStatus,
1632 N7110_GetMemory,
1633 NOTIMPLEMENTED, /* GetNextMemory */
1634 N7110_SetMemory,
1635 NOTIMPLEMENTED, /* AddMemory */
1636 N7110_DeleteMemory,
1637 NOTIMPLEMENTED, /* DeleteAllMemory */
1638 N7110_GetSpeedDial,
1639 NOTIMPLEMENTED, /* SetSpeedDial */
1640 DCT3_GetSMSC,
1641 DCT3_SetSMSC,
1642 N7110_GetSMSStatus,
1643 N7110_GetSMSMessage,
1644 N7110_GetNextSMSMessage,
1645 N7110_SetSMS,
1646 N7110_AddSMS,
1647 N7110_DeleteSMS,
1648 DCT3_SendSMSMessage,
1649 NOTSUPPORTED, /* SendSavedSMS */
1650 N7110_SetIncomingSMS,
1651 DCT3_SetIncomingCB,
1652 N7110_GetSMSFolders,
1653 NOTIMPLEMENTED, /* AddSMSFolder */
1654 NOTIMPLEMENTED, /* DeleteSMSFolder */
1655 DCT3_DialVoice,
1656 N7110_AnswerCall,
1657 DCT3_CancelCall,
1658 NOTIMPLEMENTED, /* HoldCall */
1659 NOTIMPLEMENTED, /* UnholdCall */
1660 NOTIMPLEMENTED, /* ConferenceCall */
1661 NOTIMPLEMENTED, /* SplitCall */
1662 NOTIMPLEMENTED, /* TransferCall */
1663 NOTIMPLEMENTED, /* SwitchCall */
1664 NOTSUPPORTED, /* GetCallDivert */
1665 N7110_SetCallDivert,
1666 N7110_CancelAllDiverts,
1667 N7110_SetIncomingCall,
1668 N7110_SetIncomingUSSD,
1669 DCT3DCT4_SendDTMF,
1670 N7110_GetRingtone,
1671 N7110_SetRingtone,
1672 NOTSUPPORTED, /* GetRingtonesInfo*/
1673 NOTSUPPORTED, /* DeleteUserRingtones*/
1674 DCT3_PlayTone,
1675 DCT3_GetWAPBookmark,
1676 DCT3_SetWAPBookmark,
1677 DCT3_DeleteWAPBookmark,
1678 DCT3_GetWAPSettings,
1679 DCT3_SetWAPSettings,
1680 NOTSUPPORTED, /* GetMMSSettings */
1681 NOTSUPPORTED, /* SetMMSSettings */
1682 NOTSUPPORTED, /* GetSyncMLSettings*/
1683 NOTSUPPORTED, /* SetSyncMLSettings*/
1684 NOTSUPPORTED, /* GetChatSettings */
1685 NOTSUPPORTED, /* SetChatSettings */
1686 N7110_GetBitmap,
1687 N7110_SetBitmap,
1688 NOTSUPPORTED, /* GetToDoStatus */
1689 NOTSUPPORTED, /* GetToDo */
1690 NOTSUPPORTED, /* GetNextToDo */
1691 NOTSUPPORTED, /* SetToDo */
1692 NOTSUPPORTED, /* AddToDo */
1693 NOTSUPPORTED, /* DeleteToDo */
1694 NOTSUPPORTED, /* DeleteAllToDo */
1695 N7110_GetCalendarStatus,
1696 NOTIMPLEMENTED, /* GetCalendar */
1697 N7110_GetNextCalendar,
1698 NOTIMPLEMENTED, /* SetCalendar */
1699 N7110_AddCalendar,
1700 N71_65_DelCalendar,
1701 NOTIMPLEMENTED, /* DeleteAllCalendar*/
1702 NOTSUPPORTED, /* GetCalendarSettings*/
1703 NOTSUPPORTED, /* SetCalendarSettings*/
1704 NOTSUPPORTED, /* GetNote */
1705 N7110_GetProfile,
1706 N7110_SetProfile,
1707 NOTSUPPORTED, /* GetFMStation */
1708 NOTSUPPORTED, /* SetFMStation */
1709 NOTSUPPORTED, /* ClearFMStations */
1710 NOTSUPPORTED, /* GetNextFileFolder*/
1711 NOTSUPPORTED, /* GetFilePart */
1712 NOTSUPPORTED, /* AddFile */
1713 NOTSUPPORTED, /* GetFileSystemStatus*/
1714 NOTSUPPORTED, /* DeleteFile */
1715 NOTSUPPORTED, /* AddFolder */
1716 NOTSUPPORTED, /* GetGPRSAccessPoint*/
1717 NOTSUPPORTED /* SetGPRSAccessPoint*/
1718};
1719
1720#endif
1721
1722/* How should editor hadle tabs in this file? Add editor commands here.
1723 * vim: noexpandtab sw=8 ts=8 sts=8:
1724 */
diff --git a/gammu/emb/common/phone/nokia/dct3/n7110.h b/gammu/emb/common/phone/nokia/dct3/n7110.h
new file mode 100644
index 0000000..a7934c2
--- a/dev/null
+++ b/gammu/emb/common/phone/nokia/dct3/n7110.h
@@ -0,0 +1,45 @@
1/* (c) 2002-2003 by Marcin Wiacek */
2
3#ifndef n7110_h
4#define n7110_h
5
6#include "../ncommon.h"
7#include "dct3comm.h"
8
9typedef struct {
10 int LastCalendarYear;
11 int LastCalendarPos;
12 GSM_NOKIACalToDoLocationsLastCalendar;
13 int FirstCalendarPos;
14
15 GSM_NOKIASMSFolder LastSMSFolder;
16 GSM_SMSFolders LastSMSFolders;
17 GSM_NOKIASMSFolder LastPictureImageFolder;
18
19 DCT3_WAPSettings_LocationsWAPLocations;
20} GSM_Phone_N7110Data;
21
22#ifndef GSM_USED_MBUS2
23# define GSM_USED_MBUS2
24#endif
25#ifndef GSM_USED_FBUS2
26# define GSM_USED_FBUS2
27#endif
28#ifndef GSM_USED_FBUS2DLR3
29# define GSM_USED_FBUS2DLR3
30#endif
31#ifndef GSM_USED_FBUS2BLUE
32# define GSM_USED_FBUS2BLUE
33#endif
34#ifndef GSM_USED_IRDAPHONET
35# define GSM_USED_IRDAPHONET
36#endif
37#ifndef GSM_USED_BLUEFBUS2
38# define GSM_USED_BLUEFBUS2
39#endif
40
41#endif
42
43/* How should editor hadle tabs in this file? Add editor commands here.
44 * vim: noexpandtab sw=8 ts=8 sts=8:
45 */
diff --git a/gammu/emb/common/phone/nokia/dct3/n9210.c b/gammu/emb/common/phone/nokia/dct3/n9210.c
new file mode 100644
index 0000000..e82d530
--- a/dev/null
+++ b/gammu/emb/common/phone/nokia/dct3/n9210.c
@@ -0,0 +1,396 @@
1/* (c) 2002-2003 by Marcin Wiacek */
2
3#include "../../../gsmstate.h"
4
5#ifdef GSM_ENABLE_NOKIA9210
6
7#include <string.h>
8#include <time.h>
9
10#include "../../../misc/coding/coding.h"
11#include "../../../gsmcomon.h"
12#include "../../../service/gsmlogo.h"
13#include "../../pfunc.h"
14#include "../nfunc.h"
15#include "n9210.h"
16#include "dct3func.h"
17
18static GSM_Error N9210_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
19{
20 unsigned char OpReq[] = {N6110_FRAME_HEADER, 0x70};
21
22 s->Phone.Data.Bitmap=Bitmap;
23 switch (Bitmap->Type) {
24 case GSM_OperatorLogo:
25 smprintf(s, "Getting operator logo\n");
26 /* This is like DCT3_GetNetworkInfo */
27 return GSM_WaitFor (s, OpReq, 4, 0x0a, 4, ID_GetBitmap);
28 case GSM_StartupLogo:
29 smprintf(s, "Getting startup logo\n");
30 return N71_92_GetPhoneSetting(s, ID_GetBitmap, 0x15);
31 case GSM_WelcomeNote_Text:
32 smprintf(s, "Getting welcome note\n");
33 return N71_92_GetPhoneSetting(s, ID_GetBitmap, 0x02);
34 default:
35 break;
36 }
37 return ERR_NOTSUPPORTED;
38}
39
40static GSM_Error N9210_ReplySetOpLogo(GSM_Protocol_Message msg, GSM_StateMachine *s)
41{
42 smprintf(s, "Operator logo clear/set\n");
43 return ERR_NONE;
44}
45
46static GSM_Error N9210_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
47{
48 GSM_Error error;
49 GSM_Phone_Bitmap_TypesType;
50 int Width, Height, i,count=3;
51 unsigned char req[600] = { N7110_FRAME_HEADER };
52 unsigned char reqStartup[1000] = {
53 N6110_FRAME_HEADER, 0xec,
54 0x15, /* Startup Logo setting */
55 0x04, 0x00, 0x00, 0x00, 0x30, 0x00,
56 0x02, 0xc0, 0x54, 0x00, 0x03, 0xc0,
57 0xf8, 0xf8, 0x01, 0x04};
58 unsigned char reqStartupText[500] = {
59 N7110_FRAME_HEADER, 0xec,
60 0x02}; /* Startup Text setting */
61 unsigned char reqClrOp[] = {
62 N7110_FRAME_HEADER, 0xAF,
63 0x02}; /* Number of logo = 0 - 0x04 */
64
65 switch (Bitmap->Type) {
66 case GSM_StartupLogo:
67 if (Bitmap->Location!=1) return ERR_NOTSUPPORTED;
68 Type=GSM_NokiaStartupLogo;
69 PHONE_GetBitmapWidthHeight(Type, &Width, &Height);
70 PHONE_EncodeBitmap(Type, reqStartup + 21, Bitmap);
71 smprintf(s, "Setting startup logo\n");
72 return GSM_WaitFor (s, reqStartup, 21+PHONE_GetBitmapSize(Type,0,0), 0x7A, 4, ID_SetBitmap);
73 case GSM_WelcomeNote_Text:
74 /* Nokia bug: Unicode text is moved one char to left */
75 CopyUnicodeString(reqStartupText + 4, Bitmap->Text);
76 reqStartupText[4] = 0x02;
77 i = 5 + UnicodeLength(Bitmap->Text) * 2;
78 reqStartupText[i++] = 0;
79 reqStartupText[i++] = 0;
80 return GSM_WaitFor (s, reqStartupText, i, 0x7A, 4, ID_SetBitmap);
81 case GSM_OperatorLogo:
82 /* First part for clearing logo */
83 if (!strcmp(Bitmap->NetworkCode,"000 00")) {
84 for (i=0;i<5;i++) {
85 reqClrOp[4] = i;
86 error=GSM_WaitFor (s, reqClrOp, 5, 0x0A, 4, ID_SetBitmap);
87 if (error != ERR_NONE) return error;
88 }
89 }
90 Type=GSM_NokiaOperatorLogo;
91 req[count++] = 0xA3;
92 req[count++] = 0x01;
93 req[count++] = 0x00; /* Logo removed */
94 NOKIA_EncodeNetworkCode(req+count, "000 00");
95 count = count + 3;
96 req[count++] = 0x00;
97 req[count++] = 0x04;
98 req[count++] = 0x08; /* Length of rest + 2 */
99 memcpy(req+count, "\x00\x00\x00\x00\x00\x00", 6);
100 count += 6;
101 error=GSM_WaitFor (s, req, count, 0x0A, 4, ID_SetBitmap);
102 if (error != ERR_NONE) return error;
103 /* We wanted only clear - now exit */
104 if (!strcmp(Bitmap->NetworkCode,"000 00")) return error;
105
106 /* Now setting logo */
107 count=3;
108 req[count++] = 0xA3;
109 req[count++] = 0x01;
110 req[count++] = 0x01; /* Logo set */
111 NOKIA_EncodeNetworkCode(req+count, Bitmap->NetworkCode);
112 count = count + 3;
113 req[count++] = 0x00;
114 req[count++] = 0x04;
115 req[count++] = PHONE_GetBitmapSize(Type,0,0)+8;
116 PHONE_GetBitmapWidthHeight(Type, &Width, &Height);
117 req[count++] = Width;
118 req[count++] = Height;
119 req[count++] = PHONE_GetBitmapSize(Type,0,0);
120 req[count++] = 0x00;
121 req[count++] = 0x00;
122 req[count++] = 0x00;
123 PHONE_EncodeBitmap(Type, req+count, Bitmap);
124 return GSM_WaitFor (s, req, count+PHONE_GetBitmapSize(Type,0,0), 0x0A, 4, ID_SetBitmap);
125 default:
126 break;
127 }
128 return ERR_NOTSUPPORTED;
129}
130
131static GSM_Error N9210_ReplyIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s)
132{
133 GSM_SMSMessage sms;
134 GSM_Phone_Data *Data = &s->Phone.Data;
135
136#ifdef DEBUG
137 smprintf(s, "SMS message received\n");
138 sms.State = SMS_UnRead;
139 sms.InboxFolder = true;
140 DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+5);
141#endif
142 if (Data->EnableIncomingSMS && s->User.IncomingSMS!=NULL) {
143 sms.State = SMS_UnRead;
144 sms.InboxFolder = true;
145 DCT3_DecodeSMSFrame(s, &sms,msg.Buffer+5);
146
147 s->User.IncomingSMS(s->CurrentConfig->Device,sms);
148 }
149 return ERR_NONE;
150}
151
152#ifdef GSM_ENABLE_N71_92INCOMINGINFO
153static GSM_Error N9210_ReplySetIncomingSMS(GSM_Protocol_Message msg, GSM_StateMachine *s)
154{
155 switch (msg.Buffer[3]) {
156 case 0x0e:
157 s->Phone.Data.EnableIncomingSMS = true;
158 smprintf(s, "Incoming SMS enabled\n");
159 return ERR_NONE;
160 case 0x0f:
161 smprintf(s, "Error enabling incoming SMS\n");
162 switch (msg.Buffer[4]) {
163 case 0x0c:
164 smprintf(s, "No PIN ?\n");
165 return ERR_SECURITYERROR;
166 default:
167 smprintf(s, "ERROR: unknown %i\n",msg.Buffer[4]);
168 }
169 }
170 return ERR_UNKNOWNRESPONSE;
171}
172#endif
173
174static GSM_Error N9210_SetIncomingSMS(GSM_StateMachine *s, bool enable)
175{
176#ifdef GSM_ENABLE_N71_92INCOMINGINFO
177 unsigned char req[] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x02};
178
179 if (enable!=s->Phone.Data.EnableIncomingSMS) {
180 if (enable) {
181 smprintf(s, "Enabling incoming SMS\n");
182 return GSM_WaitFor (s, req, 7, 0x02, 4, ID_SetIncomingSMS);
183 } else {
184 s->Phone.Data.EnableIncomingSMS = false;
185 smprintf(s, "Disabling incoming SMS\n");
186 }
187 }
188 return ERR_NONE;
189#else
190 return ERR_SOURCENOTAVAILABLE;
191#endif
192}
193
194static GSM_Error N9210_Initialise (GSM_StateMachine *s)
195{
196#ifdef DEBUG
197 DCT3_SetIncomingCB(s,true);
198
199#ifdef GSM_ENABLE_N71_92INCOMINGINFO
200 N9210_SetIncomingSMS(s,true);
201#endif
202
203#endif
204 return ERR_NONE;
205}
206
207GSM_Error N9210_AnswerCall(GSM_StateMachine *s, int ID, bool all)
208{
209 if (!all) return DCT3DCT4_AnswerCall(s,ID);
210 return DCT3_AnswerAllCalls(s);
211}
212
213static GSM_Reply_Function N9210ReplyFunctions[] = {
214 {DCT3_ReplySendSMSMessage, "\x02",0x03,0x02,ID_IncomingFrame},
215 {DCT3_ReplySendSMSMessage, "\x02",0x03,0x03,ID_IncomingFrame},
216#ifdef GSM_ENABLE_N71_92INCOMINGINFO
217 {N9210_ReplySetIncomingSMS, "\x02",0x03,0x0E,ID_SetIncomingSMS},
218 {N9210_ReplySetIncomingSMS, "\x02",0x03,0x0F,ID_SetIncomingSMS},
219#endif
220 {N9210_ReplyIncomingSMS, "\x02",0x03,0x11,ID_IncomingFrame},
221#ifdef GSM_ENABLE_CELLBROADCAST
222 {DCT3_ReplySetIncomingCB, "\x02",0x03,0x21,ID_SetIncomingCB},
223 {DCT3_ReplySetIncomingCB, "\x02",0x03,0x22,ID_SetIncomingCB},
224 {DCT3_ReplyIncomingCB, "\x02",0x03,0x23,ID_IncomingFrame},
225#endif
226 {DCT3_ReplySetSMSC, "\x02",0x03,0x31,ID_SetSMSC },
227 {DCT3_ReplyGetSMSC, "\x02",0x03,0x34,ID_GetSMSC },
228 {DCT3_ReplyGetSMSC, "\x02",0x03,0x35,ID_GetSMSC },
229
230 {N61_91_ReplySetOpLogo, "\x05",0x03,0x31,ID_SetBitmap },
231 {N61_91_ReplySetOpLogo, "\x05",0x03,0x32,ID_SetBitmap },
232
233 {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_GetNetworkInfo},
234 {DCT3_ReplyGetNetworkInfo, "\x0A",0x03,0x71,ID_IncomingFrame},
235 {N71_92_ReplyGetSignalQuality, "\x0A",0x03,0x82,ID_GetSignalQuality},
236 {N9210_ReplySetOpLogo, "\x0A",0x03,0xA4,ID_SetBitmap },
237 {N9210_ReplySetOpLogo, "\x0A",0x03,0xB0,ID_SetBitmap },
238
239 {N71_92_ReplyGetBatteryCharge, "\x17",0x03,0x03,ID_GetBatteryCharge},
240
241 {DCT3_ReplySetDateTime, "\x19",0x03,0x61,ID_SetDateTime },
242 {DCT3_ReplyGetDateTime, "\x19",0x03,0x63,ID_GetDateTime },
243
244 {DCT3_ReplyEnableSecurity, "\x40",0x02,0x64,ID_EnableSecurity},
245 {DCT3_ReplyGetIMEI, "\x40",0x02,0x66,ID_GetIMEI },
246 {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_DialVoice },
247 {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_CancelCall },
248 {DCT3_ReplyDialCommand, "\x40",0x02,0x7C,ID_AnswerCall },
249 {DCT3_ReplyNetmonitor, "\x40",0x02,0x7E,ID_Netmonitor },
250 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetHardware },
251 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xC8,ID_GetPPM },
252 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCA,ID_GetProductCode},
253 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetManufactureMonth},
254 {NOKIA_ReplyGetPhoneString, "\x40",0x02,0xCC,ID_GetOriginalIMEI},
255
256 {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x02,ID_GetBitmap },
257 {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x02,ID_SetBitmap },
258 {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x15,ID_GetBitmap },
259 {N71_92_ReplyPhoneSetting, "\x7a",0x04,0x15,ID_SetBitmap },
260
261 {DCT3DCT4_ReplyGetModelFirmware,"\xD2",0x02,0x00,ID_GetModel },
262 {DCT3DCT4_ReplyGetModelFirmware,"\xD2",0x02,0x00,ID_GetFirmware },
263
264 {NULL, "\x00",0x00,0x00,ID_None }
265};
266
267GSM_Phone_Functions N9210Phone = {
268 "9210|9210i",
269 N9210ReplyFunctions,
270 N9210_Initialise,
271 PHONE_Terminate,
272 GSM_DispatchMessage,
273 NOTSUPPORTED, /* ShowStartInfo */
274 NOKIA_GetManufacturer,
275 DCT3DCT4_GetModel,
276 DCT3DCT4_GetFirmware,
277 DCT3_GetIMEI,
278 DCT3_GetOriginalIMEI,
279 DCT3_GetManufactureMonth,
280 DCT3_GetProductCode,
281 DCT3_GetHardware,
282 DCT3_GetPPM,
283 NOTSUPPORTED, /* GetSIMIMSI */
284 N71_92_GetDateTime,
285 N71_92_SetDateTime,
286 NOTIMPLEMENTED, /* GetAlarm */
287 NOTIMPLEMENTED, /* SetAlarm */
288 NOTSUPPORTED, /* GetLocale */
289 NOTSUPPORTED, /* SetLocale */
290 NOTIMPLEMENTED, /* PressKey */
291 NOTIMPLEMENTED, /* Reset */
292 NOTIMPLEMENTED, /* ResetPhoneSettings*/
293 NOTSUPPORTED, /* EnterSecurityCode*/
294 NOTSUPPORTED, /* GetSecurityStatus*/
295 NOTSUPPORTED, /* GetDisplayStatus*/
296 NOTIMPLEMENTED, /* SetAutoNetworkLogin*/
297 N71_92_GetBatteryCharge,
298 N71_92_GetSignalQuality,
299 DCT3_GetNetworkInfo,
300 NOTSUPPORTED, /* GetCategory */
301 NOTSUPPORTED, /* AddCategory */
302 NOTSUPPORTED, /* GetCategoryStatus */
303 NOTIMPLEMENTED, /* GetMemoryStatus */
304 NOTIMPLEMENTED, /* GetMemory */
305 NOTIMPLEMENTED, /* GetNextMemory */
306 NOTIMPLEMENTED, /* SetMemory */
307 NOTIMPLEMENTED, /* AddMemory */
308 NOTIMPLEMENTED, /* DeleteMemory */
309 NOTIMPLEMENTED, /* DeleteAllMemory */
310 NOTIMPLEMENTED, /* GetSpeedDial */
311 NOTIMPLEMENTED, /* SetSpeedDial */
312 DCT3_GetSMSC,
313 DCT3_SetSMSC, /* FIXME: test it */
314 NOTIMPLEMENTED, /* GetSMSStatus */
315 NOTIMPLEMENTED, /* GetSMS */
316 NOTIMPLEMENTED, /* GetNextSMS */
317 NOTIMPLEMENTED, /* SetSMS */
318 NOTIMPLEMENTED, /* AddSMS */
319 NOTIMPLEMENTED, /* DeleteSMS */
320 DCT3_SendSMSMessage,
321 NOTSUPPORTED, /* SendSavedSMS */
322 N9210_SetIncomingSMS,
323 DCT3_SetIncomingCB,
324 NOTIMPLEMENTED, /* GetSMSFolders */
325 NOTSUPPORTED, /* AddSMSFolder */
326 NOTSUPPORTED, /* DeleteSMSFolder */
327 DCT3_DialVoice,
328 N9210_AnswerCall,
329 DCT3_CancelCall,
330 NOTSUPPORTED, /* HoldCall */
331 NOTSUPPORTED, /* UnholdCall */
332 NOTSUPPORTED, /* ConferenceCall */
333 NOTSUPPORTED, /* SplitCall */
334 NOTSUPPORTED, /* TransferCall */
335 NOTSUPPORTED, /* SwitchCall */
336 NOTSUPPORTED, /* GetCallDivert */
337 NOTSUPPORTED, /* SetCallDivert */
338 NOTSUPPORTED, /* CancelAllDiverts*/
339 NOTSUPPORTED, /* SetIncomingCall */
340 NOTIMPLEMENTED, /* SetIncomingUSSD */
341 NOTSUPPORTED, /* SendDTMF */
342 NOTIMPLEMENTED, /* GetRingtone */
343 NOTIMPLEMENTED, /* SetRingtone */
344 NOTSUPPORTED, /* GetRingtonesInfo*/
345 NOTSUPPORTED, /* DeleteUserRingtones*/
346 NOTSUPPORTED, /* PlayTone */
347 NOTIMPLEMENTED, /* GetWAPBookmark */
348 NOTIMPLEMENTED, /* SetWAPBookmark */
349 NOTIMPLEMENTED, /* DeleteWAPBookmark */
350 NOTIMPLEMENTED, /* GetWAPSettings */
351 NOTSUPPORTED, /* SetWAPSettings */
352 NOTSUPPORTED, /* GetMMSSettings */
353 NOTSUPPORTED, /* SetMMSSettings */
354 NOTSUPPORTED, /* GetSyncMLSettings*/
355 NOTSUPPORTED, /* SetSyncMLSettings*/
356 NOTSUPPORTED, /* GetChatSettings */
357 NOTSUPPORTED, /* SetChatSettings */
358 N9210_GetBitmap,
359 N9210_SetBitmap,
360 NOTSUPPORTED, /* GetToDoStatus */
361 NOTSUPPORTED, /* GetToDo */
362 NOTSUPPORTED, /* GetNextToDo */
363 NOTSUPPORTED, /* SetToDo */
364 NOTSUPPORTED, /* AddToDo */
365 NOTSUPPORTED, /* DeleteToDo */
366 NOTSUPPORTED, /* DeleteAllToDo */
367 NOTSUPPORTED, /* GetCalendarStatus*/
368 NOTSUPPORTED, /* GetCalendar */
369 NOTSUPPORTED, /* GetNextCalendar */
370 NOTSUPPORTED, /* SetCalendar */
371 NOTSUPPORTED, /* AddCalendar */
372 NOTSUPPORTED, /* DeleteCalendar */
373 NOTSUPPORTED, /* DeleteAllCalendar*/
374 NOTSUPPORTED, /* GetCalendarSettings*/
375 NOTSUPPORTED, /* SetCalendarSettings*/
376 NOTSUPPORTED, /* GetNote */
377 NOTIMPLEMENTED, /* GetProfile */
378 NOTSUPPORTED, /* SetProfile */
379 NOTSUPPORTED, /* GetFMStation */
380 NOTSUPPORTED, /* SetFMStation */
381 NOTSUPPORTED, /* ClearFMStations */
382 NOTSUPPORTED, /* GetNextFileFolder*/
383 NOTSUPPORTED, /* GetFilePart */
384 NOTSUPPORTED, /* AddFile */
385 NOTSUPPORTED, /* GetFileSystemStatus*/
386 NOTSUPPORTED, /* DeleteFile */
387 NOTSUPPORTED, /* AddFolder */
388 NOTSUPPORTED, /* GetGPRSAccessPoint*/
389 NOTSUPPORTED /* SetGPRSAccessPoint*/
390};
391
392#endif
393
394/* How should editor hadle tabs in this file? Add editor commands here.
395 * vim: noexpandtab sw=8 ts=8 sts=8:
396 */
diff --git a/gammu/emb/common/phone/nokia/dct3/n9210.h b/gammu/emb/common/phone/nokia/dct3/n9210.h
new file mode 100644
index 0000000..8998532
--- a/dev/null
+++ b/gammu/emb/common/phone/nokia/dct3/n9210.h
@@ -0,0 +1,17 @@
1/* (c) 2002-2003 by Marcin Wiacek */
2
3#ifndef n9210_h
4#define n9210_h
5
6#ifndef GSM_USED_MBUS2
7# define GSM_USED_MBUS2
8#endif
9#ifndef GSM_USED_FBUS2
10# define GSM_USED_FBUS2
11#endif
12
13#endif
14
15/* How should editor hadle tabs in this file? Add editor commands here.
16 * vim: noexpandtab sw=8 ts=8 sts=8:
17 */