1 /* (c) 2002-2005 by Marcin Wiacek */
2 /* based on some Markus Plail, Pawel Kot work from Gnokii (www.gnokii.org)
3  * (C) 1999-2000 Hugh Blemings & Pavel Janik ml. (C) 2001-2004 Pawel Kot
4  * GNU GPL version 2 or later
5  */
6 /* Due to a problem in the source code management, the names of some of
7  * the authors have unfortunately been lost. We do not mean to belittle
8  * their efforts and hope they will contact us to see their names
9  * properly added to the Copyright notice above.
10  * Having published their contributions under the terms of the GNU
11  * General Public License (GPL) [version 2], the Copyright of these
12  * authors will remain respected by adhering to the license they chose
13  * to publish their code under.
14  */
15 
16 #include <gammu-config.h>
17 
18 #ifdef GSM_ENABLE_NOKIA6510
19 
20 #include <string.h>
21 #include <time.h>
22 #ifdef HAVE_STDINT_H
23 #include <stdint.h>
24 #endif
25 
26 #include <gammu-nokia.h>
27 
28 #include "../../../../misc/coding/coding.h"
29 #include "../../../../misc/locales.h"
30 #include "../../../../gsmcomon.h"
31 #include "../../../../service/gsmlogo.h"
32 #include "../../../../service/gsmnet.h"
33 #include "../../../../service/gsmring.h"
34 #include "../../../../service/sms/gsmmulti.h"
35 #include "../../nfunc.h"
36 #include "../../nfuncold.h"
37 #include "../../../pfunc.h"
38 #include "../dct4func.h"
39 #include "n6510.h"
40 #include "6510cal.h"
41 #include "6510file.h"
42 
N6510_Initialise(GSM_StateMachine * s)43 static GSM_Error N6510_Initialise (GSM_StateMachine *s)
44 {
45 	s->Phone.Data.Priv.N6510.CalendarIconsNum  = 0;
46 	s->Phone.Data.Priv.N6510.LastFreeMemoryLocation = 0;
47 	s->Phone.Data.Priv.N6510.LastFreeMemoryType = 0;
48 	s->Phone.Data.Priv.N6510.FilesLocationsAvail = 0;
49 	s->Phone.Data.Priv.N6510.FilesLocationsUsed = 0;
50 	s->Phone.Data.Priv.N6510.FilesCache = NULL;
51 	s->Phone.Data.Priv.N6510.ScreenWidth = 0;
52 	s->Phone.Data.Priv.N6510.ScreenHeight = 0;
53 
54 	/* Default timeout for cables */
55 	s->Phone.Data.Priv.N6510.Timeout = 8;
56 	if (s->ConnectionType == GCT_IRDAPHONET || s->ConnectionType == GCT_FBUS2IRDA) {
57 		s->Phone.Data.Priv.N6510.Timeout = 40;
58 	}
59 	if (s->ConnectionType == GCT_BLUEPHONET || s->ConnectionType == GCT_BLUEFBUS2) {
60 		s->Phone.Data.Priv.N6510.Timeout = 20;
61 	}
62 
63 	/* Enables various things like incoming SMS, call info, etc. */
64 	return N71_65_EnableFunctions (s, "\x01\x02\x06\x0A\x14\x17\x39", 7);
65 }
66 
N6510_Terminate(GSM_StateMachine * s)67 static GSM_Error N6510_Terminate (GSM_StateMachine *s)
68 {
69 	free(s->Phone.Data.Priv.N6510.FilesCache);
70 	s->Phone.Data.Priv.N6510.FilesCache = NULL;
71 	return ERR_NONE;
72 }
73 
N6510_ReplyGetMemory(GSM_Protocol_Message * msg,GSM_StateMachine * s)74 static GSM_Error N6510_ReplyGetMemory(GSM_Protocol_Message *msg, GSM_StateMachine *s)
75 {
76 	smprintf(s, "Phonebook entry received\n");
77 	if (msg->Buffer[6] == 0x0f)
78 		return N71_65_ReplyGetMemoryError(msg->Buffer[10], s);
79 
80 	if (msg->Length < 22) {
81 		return ERR_UNKNOWN;
82 	}
83 	return N71_65_DecodePhonebook(s,
84 			s->Phone.Data.Memory,
85 			s->Phone.Data.Bitmap,
86 			s->Phone.Data.SpeedDial,
87 			msg->Buffer + 22,
88 			msg->Length - 22,
89 			FALSE);
90 }
91 
N6510_GetMemory(GSM_StateMachine * s,GSM_MemoryEntry * entry)92 static GSM_Error N6510_GetMemory (GSM_StateMachine *s, GSM_MemoryEntry *entry)
93 {
94 	GSM_Error error;
95 	unsigned char req[] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x01, 0x00, 0x01,
96 			       0xfe, 0x10, 	/* memory type */
97 			       0x00, 0x00, 0x00, 0x00,
98 			       0x00, 0x01, 	/* location */
99 			       0x00, 0x00, 0x01};
100 
101 	req[9] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
102 	if (req[9]==0xff) return ERR_NOTSUPPORTED;
103 
104 	if (entry->Location==0x00) return ERR_INVALIDLOCATION;
105 
106 	req[14] = entry->Location / 256;
107 	req[15] = entry->Location % 256;
108 
109 	s->Phone.Data.Memory=entry;
110 	smprintf(s, "Getting phonebook entry\n");
111 	error = GSM_WaitFor (s, req, 19, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_GetMemory);
112 	if (error == ERR_WORKINPROGRESS) {
113 		sleep(2);
114 		smprintf(s, "Retrying to get phonebook entry\n");
115 		error = GSM_WaitFor (s, req, 19, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_GetMemory);
116 	}
117 	if (entry->MemoryType == MEM_DC || entry->MemoryType == MEM_RC || entry->MemoryType == MEM_MC) {
118 		/* 6111 */
119 		if (error == ERR_NOTSUPPORTED) return ERR_EMPTY;
120 	}
121 	return error;
122 }
123 
N6510_ReplyGetMemoryStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)124 static GSM_Error N6510_ReplyGetMemoryStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
125 {
126 	GSM_Phone_Data *Data = &s->Phone.Data;
127 
128 	smprintf(s, "Memory status received\n");
129 	/* Quess ;-)) */
130 	if (msg->Buffer[14]==0x10) {
131 		Data->MemoryStatus->MemoryFree = msg->Buffer[18]*256 + msg->Buffer[19];
132 		Data->MemoryStatus->MemoryUsed = msg->Buffer[20]*256 + msg->Buffer[21];
133 	} else if (msg->Buffer[14]==0x02) {
134 		Data->MemoryStatus->MemoryFree = msg->Buffer[22];
135 		Data->MemoryStatus->MemoryUsed = msg->Buffer[21];
136 	} else {
137 		Data->MemoryStatus->MemoryFree = msg->Buffer[17];
138 		Data->MemoryStatus->MemoryUsed = msg->Buffer[20]*256 + msg->Buffer[21];
139 	}
140 	smprintf(s, "Size       : %i\n",Data->MemoryStatus->MemoryFree);
141 	smprintf(s, "Used       : %i\n",Data->MemoryStatus->MemoryUsed);
142 	Data->MemoryStatus->MemoryFree -= Data->MemoryStatus->MemoryUsed;
143 	smprintf(s, "Free       : %i\n",Data->MemoryStatus->MemoryFree);
144 	return ERR_NONE;
145 }
146 
N6510_GetMemoryStatus(GSM_StateMachine * s,GSM_MemoryStatus * Status)147 static GSM_Error N6510_GetMemoryStatus(GSM_StateMachine *s, GSM_MemoryStatus *Status)
148 {
149 	unsigned char req[] = {N6110_FRAME_HEADER, 0x03, 0x02,
150 			       0x00,		/* memory type */
151 			       0x55, 0x55, 0x55, 0x00};
152 
153 	req[5] = NOKIA_GetMemoryType(s, Status->MemoryType,N71_65_MEMORY_TYPES);
154 	if (req[5]==0xff) return ERR_NOTSUPPORTED;
155 
156 	s->Phone.Data.MemoryStatus=Status;
157 	smprintf(s, "Getting memory status\n");
158 	return GSM_WaitFor (s, req, 10, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_GetMemoryStatus);
159 }
160 
N6510_ReplyGetSMSC(GSM_Protocol_Message * msg,GSM_StateMachine * s)161 static GSM_Error N6510_ReplyGetSMSC(GSM_Protocol_Message *msg, GSM_StateMachine *s)
162 {
163 	int 			i, current, j;
164 	GSM_Phone_Data		*Data = &s->Phone.Data;
165 	size_t pos;
166 	GSM_Error error;
167 
168 	switch (msg->Buffer[4]) {
169 		case 0x00:
170 			smprintf(s, "SMSC received\n");
171 			break;
172 		case 0x02:
173 			smprintf(s, "SMSC empty\n");
174 			return ERR_INVALIDLOCATION;
175 		case 0x09:
176 			smprintf(s, "SMSC empty???\n");
177 			return ERR_INVALIDLOCATION;
178 		default:
179 			smprintf(s, "Unknown SMSC state: %02x\n",msg->Buffer[4]);
180 			return ERR_UNKNOWNRESPONSE;
181 	}
182 	memset(Data->SMSC,0,sizeof(GSM_SMSC));
183 	Data->SMSC->Location 	= msg->Buffer[8];
184 	Data->SMSC->Format 	= SMS_FORMAT_Text;
185 	switch (msg->Buffer[10]) {
186 		case 0x00: Data->SMSC->Format = SMS_FORMAT_Text; 	break;
187 		case 0x22: Data->SMSC->Format = SMS_FORMAT_Fax; 	break;
188 		case 0x26: Data->SMSC->Format = SMS_FORMAT_Pager;	break;
189 		case 0x32: Data->SMSC->Format = SMS_FORMAT_Email;	break;
190 	}
191 	Data->SMSC->Validity.Format	= SMS_Validity_RelativeFormat;
192 	Data->SMSC->Validity.Relative	= msg->Buffer[12];
193 	if (msg->Buffer[12] == 0x00) Data->SMSC->Validity.Relative = SMS_VALID_Max_Time;
194 
195 	current = 14;
196 	for (i=0;i<msg->Buffer[13];i++) {
197 		switch (msg->Buffer[current]) {
198 		case 0x81:
199 			j=current+4;
200 			while (msg->Buffer[j]!=0) {j++;}
201 			j=j-33;
202 			if (j>GSM_MAX_SMSC_NAME_LENGTH) {
203 				smprintf(s, "Too long name\n");
204 				return ERR_UNKNOWNRESPONSE;
205 			}
206 			CopyUnicodeString(Data->SMSC->Name,msg->Buffer+current+4);
207 			smprintf(s, "   Name \"%s\"\n", DecodeUnicodeString(Data->SMSC->Name));
208 			break;
209 		case 0x82:
210 			switch (msg->Buffer[current+2]) {
211 			case 0x01:
212 				pos = current + 4;
213 				error = GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->DefaultNumber, msg->Buffer, &pos, msg->Length, TRUE);
214 				if (error != ERR_NONE) {
215 					return error;
216 				}
217 				smprintf(s, "   Default number \"%s\"\n", DecodeUnicodeString(Data->SMSC->DefaultNumber));
218 				break;
219 			case 0x02:
220 				pos = current + 4;
221 				error = GSM_UnpackSemiOctetNumber(&(s->di), Data->SMSC->Number, msg->Buffer, &pos, msg->Length, FALSE);
222 				if (error != ERR_NONE) {
223 					return error;
224 				}
225 				smprintf(s, "   Number \"%s\"\n", DecodeUnicodeString(Data->SMSC->Number));
226 				break;
227 			default:
228 				smprintf(s, "Unknown SMSC number: %02x\n",msg->Buffer[current+2]);
229 				return ERR_UNKNOWNRESPONSE;
230 			}
231 			break;
232 		default:
233 			smprintf(s, "Unknown SMSC block: %02x\n",msg->Buffer[current]);
234 			return ERR_UNKNOWNRESPONSE;
235 		}
236 		current = current + msg->Buffer[current+1];
237 	}
238 	return ERR_NONE;
239 }
240 
N6510_GetSMSC(GSM_StateMachine * s,GSM_SMSC * smsc)241 static GSM_Error N6510_GetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
242 {
243 	unsigned char req[] = {N6110_FRAME_HEADER, 0x14,
244 			       0x01,		/* location */
245 			       0x00};
246 
247 	if (smsc->Location==0x00) return ERR_INVALIDLOCATION;
248 
249 	req[4]=smsc->Location;
250 
251 	s->Phone.Data.SMSC=smsc;
252 	smprintf(s, "Getting SMSC\n");
253 	return GSM_WaitFor (s, req, 6, 0x02, s->Phone.Data.Priv.N6510.Timeout, ID_GetSMSC);
254 }
255 
N6510_ReplySetSMSC(GSM_Protocol_Message * msg,GSM_StateMachine * s)256 static GSM_Error N6510_ReplySetSMSC(GSM_Protocol_Message *msg, GSM_StateMachine *s)
257 {
258 	switch (msg->Buffer[4]) {
259 		case 0x00:
260 			smprintf(s, "SMSC set OK\n");
261 			return ERR_NONE;
262 		case 0x02:
263 			smprintf(s, "Invalid SMSC location\n");
264 			return ERR_INVALIDLOCATION;
265 		default:
266 			smprintf(s, "Unknown SMSC state: %02x\n",msg->Buffer[4]);
267 			return ERR_UNKNOWNRESPONSE;
268 	}
269 }
270 
N6510_SetSMSC(GSM_StateMachine * s,GSM_SMSC * smsc)271 static GSM_Error N6510_SetSMSC(GSM_StateMachine *s, GSM_SMSC *smsc)
272 {
273 	int 		count = 13,i;
274 	unsigned char 	req[256] = {N6110_FRAME_HEADER,
275 		    		    0x12, 0x55, 0x01, 0x0B, 0x34,
276 				    0x05,		/* Location 	*/
277 				    0x00,
278 				    0x00,		/* Format 	*/
279 				    0x00,
280 				    0xFF};		/* Validity	*/
281 
282 	req[8]  = smsc->Location;
283 	switch (smsc->Format) {
284 		case SMS_FORMAT_Text:	req[10] = 0x00;	break;
285 		case SMS_FORMAT_Fax:	req[10] = 0x22;	break;
286 		case SMS_FORMAT_Pager:	req[10] = 0x26;	break;
287 		case SMS_FORMAT_Email:	req[10] = 0x32;	break;
288 	}
289 	req[12]  = smsc->Validity.Relative;
290 
291 	/* We have now blocks. Number of blocks = 3 */
292 	req[count++] 	 	 = 0x03;
293 
294 	/* -------------- SMSC number ----------------- */
295 	/* Block type: number */
296 	req[count++] 		 = 0x82;
297 	/* Offset to next block */
298 	req[count++] 		 = 0x1A;
299  	/* Type of number: SMSC number */
300 	req[count++] 		 = 0x02;
301 	req[count] = GSM_PackSemiOctetNumber(smsc->Number, req+count+2, FALSE) + 1;
302 	if (req[count]>18) {
303 		smprintf(s, "Too long SMSC number in frame\n");
304 		return ERR_UNKNOWN;
305 	}
306 	req[count+1] = req[count] - 1;
307 	count += 23;
308 
309 	/* --------------- Default number ------------- */
310 	/* Block type: number */
311 	req[count++] 		 = 0x82;
312 	/* Offset to next block */
313 	req[count++] 		 = 0x14;
314  	/* Type of number: default number */
315 	req[count++] 		 = 0x01;
316 	req[count] = GSM_PackSemiOctetNumber(smsc->DefaultNumber, req+count+2, TRUE) + 1;
317 	if (req[count]*2>12) {
318 		smprintf(s, "Too long SMSC number in frame\n");
319 		return ERR_UNKNOWN;
320 	}
321 	req[count+1] = req[count] - 1;
322 	count += 17;
323 
324 	/* -------------- SMSC name ------------------- */
325 	req[count++] 		 = 0x81;
326 	req[count++] 		 = UnicodeLength(smsc->Name)*2 + 2 + 4;
327 	req[count++] 		 = UnicodeLength(smsc->Name)*2 + 2;
328 	req[count++] 		 = 0x00;
329 	/* Can't make CopyUnicodeString(req+count,sms->Name) !!!!
330 	 * with MSVC6 count is changed then
331 	 */
332 	i = count;
333 	CopyUnicodeString(req+i,smsc->Name);
334 	count += UnicodeLength(smsc->Name)*2 + 2;
335 
336 	smprintf(s, "Setting SMSC\n");
337 	return GSM_WaitFor (s, req, count, 0x02, s->Phone.Data.Priv.N6510.Timeout, ID_SetSMSC);
338 }
339 
N6510_ReplyGetNetworkInfo(GSM_Protocol_Message * msg,GSM_StateMachine * s)340 static GSM_Error N6510_ReplyGetNetworkInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
341 {
342 	int		current = msg->Buffer[7]+7, pos;
343 	GSM_Phone_Data	*Data = &s->Phone.Data;
344 	GSM_NetworkInfo network_info_local, *network_info;
345 
346 	if (msg->Buffer[3] == 0xf0) {
347 		return ERR_NOTSUPPORTED;
348 	}
349 
350 	if (Data->RequestID == ID_GetNetworkInfo) {
351 		network_info = Data->NetworkInfo;
352 	} else {
353 		network_info = &network_info_local;
354 	}
355 
356 	network_info->NetworkName[0] = 0x00;
357 	network_info->NetworkName[1] = 0x00;
358 
359 	switch (msg->Buffer[8]) {
360 		case 0x00:
361 			smprintf(s, "home network\n");
362 			network_info->State = GSM_HomeNetwork;
363 			break;
364 		case 0x01:
365 			smprintf(s, "roaming network\n");
366 			network_info->State = GSM_RoamingNetwork;
367 			break;
368 		case 0x04:
369 			smprintf(s, "not logged");
370 			network_info->State = GSM_NoNetwork;
371 			break;
372 		case 0x06:
373 			smprintf(s, "SIM card rejected\n");
374 			network_info->State = GSM_RegistrationDenied;
375 			break;
376 		case 0x09:
377 			smprintf(s, "not logged");
378 			network_info->State = GSM_NoNetwork;
379 			break;
380 		default:
381 			smprintf(s, "unknown %i!\n",msg->Buffer[8]);
382 			network_info->State = GSM_NetworkStatusUnknown;
383 	}
384 	if (network_info->State == GSM_HomeNetwork || network_info->State == GSM_RoamingNetwork) {
385 		pos = 10;
386 		NOKIA_GetUnicodeString(s, &pos, msg->Buffer, network_info->NetworkName, TRUE);
387 		smprintf(s, "Network name: %s ", DecodeUnicodeString(network_info->NetworkName));
388 		NOKIA_DecodeNetworkCode(msg->Buffer + (current + 7), network_info->NetworkCode);
389 		smprintf(s, "Network code: %s\n", network_info->NetworkCode);
390 		smprintf(s, "Network name in libGammu: %s ", DecodeUnicodeString(GSM_GetNetworkName(network_info->NetworkCode)));
391 		sprintf(network_info->LAC, "%02X%02X", msg->Buffer[current+1], msg->Buffer[current+2]);
392 		smprintf(s, "LAC: %s\n", network_info->LAC);
393 		sprintf(network_info->CID, "%02X%02X", msg->Buffer[current+5], msg->Buffer[current+6]);
394 		smprintf(s, "CID: %s\n", network_info->CID);
395 	}
396 	return ERR_NONE;
397 }
398 
N6510_GetNetworkInfo(GSM_StateMachine * s,GSM_NetworkInfo * netinfo)399 static GSM_Error N6510_GetNetworkInfo(GSM_StateMachine *s, GSM_NetworkInfo *netinfo)
400 {
401 	unsigned char req[] = {N6110_FRAME_HEADER, 0x00, 0x00};
402 
403 	netinfo->GPRS = 0;
404 	s->Phone.Data.NetworkInfo=netinfo;
405 	smprintf(s, "Getting network info\n");
406 	return GSM_WaitFor (s, req, 5, 0x0a, s->Phone.Data.Priv.N6510.Timeout, ID_GetNetworkInfo);
407 }
408 
N6510_EncodeSMSFrame(GSM_StateMachine * s,GSM_SMSMessage * sms,unsigned char * req,GSM_SMSMessageLayout * Layout,int * length)409 static GSM_Error N6510_EncodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *req, GSM_SMSMessageLayout *Layout, int *length)
410 {
411 	int			count = 0, pos1, pos2, pos3, pos4, pos5;
412 	GSM_Error		error;
413 
414 	memset(Layout,255,sizeof(GSM_SMSMessageLayout));
415 
416 	req[count++]		 = 0x01;
417 	if (sms->PDU != SMS_Deliver) {
418 		req[count++] 	 = 0x02;
419 	} else {
420 		req[count++] 	 = 0x00;
421 	}
422 
423 	pos1		  	 = count; count++;
424 	/* firstbyte set in SMS Layout */
425 	Layout->firstbyte 	 = count; count++;
426 	if (sms->PDU != SMS_Deliver) {
427 		Layout->TPMR 	 = count; count++;
428 
429 		Layout->TPPID	 = count; count++;
430 
431 		/* TP.DCS set in SMS layout */
432 		Layout->TPDCS 	 = count; count++;
433                 req[count++] 	 = 0x00;
434 	} else {
435 		Layout->TPPID 	 = count; count++;
436 		/* TP.DCS set in SMS layout */
437 		Layout->TPDCS 	 = count; count++;
438 		Layout->DateTime = count; count += 7;
439 		req[count++] 	 = 0x55;
440 		req[count++] 	 = 0x55;
441 		req[count++] 	 = 0x55;
442 	}
443 
444 	/* We have now blocks. Number of blocks = 3 or 4 */
445 	if (sms->PDU != SMS_Deliver) {
446 		req[count++] 	 = 0x04;
447 	} else {
448 		req[count++] 	 = 0x03;
449 	}
450 
451 	/* -------------- Phone number ------------- */
452 	/* Block type: number */
453 	req[count++] 		 = 0x82;
454 	/* Offset to next block */
455 	req[count++] 		 = 0x10;
456  	/* Type of number: default number */
457 	req[count++] 		 = 0x01;
458 	pos4 			 = count; count++;
459  	/* now coded Number in SMS Layout */
460 	Layout->Number 		 = count; count+= 12;
461 
462 	/* -------------- SMSC number -------------- */
463 	/* Block type: number */
464 	req[count++] 		 = 0x82;
465 	/* Offset to next block */
466 	req[count++] 		 = 0x10;
467  	/* Type of number: SMSC number */
468 	req[count++] 		 = 0x02;
469 	pos5 			 = count; count++;
470 	/* now coded SMSC number in SMS Layout */
471 	Layout->SMSCNumber 	 = count; count += 12;
472 
473 	/* -------------- SMS validity ------------- */
474 	if (sms->PDU != SMS_Deliver) {
475  		/* Block type: validity */
476 		req[count++] 	 = 0x08;
477 		req[count++] 	 = 0x04;
478  		/* data length */
479 		req[count++] 	 = 0x01;
480 		Layout->TPVP 	 = count; count++;
481 	}
482 
483 	/* --------------- SMS text ---------------- */
484 	/* Block type: SMS text */
485 	req[count++] 		 = 0x80;
486 	/* this the same as req[11] but starting from req[42] */
487 	pos2			 = count; count++;
488 	pos3			 = count; count++;
489  	/* FIXME*/
490 	Layout->TPUDL 		 = count; count++;
491 	/* SMS text and UDH coded in SMS Layout */
492 	Layout->Text 		 = count;
493 
494 	error = PHONE_EncodeSMSFrame(s,sms,req,*Layout,length,FALSE);
495 	if (error != ERR_NONE) return error;
496 
497 	req[pos1] 		 = *length - 1;
498 	req[pos2] 		 = *length - Layout->Text + 6;
499 	req[pos3] 		 = *length - Layout->Text;
500 
501 	/* Convert number of semioctets to number of chars */
502 	req[pos4]		 = req[Layout->Number] + 4;
503 	if (req[pos4] % 2) req[pos4]++;
504 	req[pos4] /= 2;
505 
506 	req[pos5]		 = req[Layout->SMSCNumber] + 1;
507 
508 	if (req[pos4]>12 || req[pos5]>12) {
509 		smprintf(s, "Too long phone number in frame\n");
510 		return ERR_UNKNOWN;
511 	}
512 
513 	return ERR_NONE;
514 }
515 
N6510_ReplyGetSMSFolders(GSM_Protocol_Message * msg,GSM_StateMachine * s)516 static GSM_Error N6510_ReplyGetSMSFolders(GSM_Protocol_Message *msg, GSM_StateMachine *s)
517 {
518 	int 			j, num = 0;
519 	size_t pos;
520 	GSM_Phone_Data		*Data = &s->Phone.Data;
521 
522 	switch (msg->Buffer[3]) {
523 	case 0x13:
524 		smprintf(s, "SMS folders names received\n");
525 		Data->SMSFolders->Number = msg->Buffer[5]+2;
526 		pos 			 = 6;
527 		for (j=0;j<msg->Buffer[5];j++) {
528 			while (TRUE) {
529 				if (msg->Buffer[pos]   == msg->Buffer[6] &&
530 				    msg->Buffer[pos+1] == msg->Buffer[7]) break;
531 				if (pos+4 > msg->Length) return ERR_UNKNOWNRESPONSE;
532 				pos++;
533 			}
534 			pos+=4;
535 			smprintf(s, "Folder index: %02x",msg->Buffer[pos - 2]);
536 			if (msg->Buffer[pos - 1]>GSM_MAX_SMS_FOLDER_NAME_LEN) {
537 				smprintf(s, "Too long text\n");
538 				return ERR_UNKNOWNRESPONSE;
539 			}
540 			CopyUnicodeString(Data->SMSFolders->Folder[num].Name,msg->Buffer + pos);
541 			smprintf(s, ", folder name: \"%s\"\n",DecodeUnicodeString(Data->SMSFolders->Folder[num].Name));
542 			Data->SMSFolders->Folder[num].InboxFolder = FALSE;
543 			Data->SMSFolders->Folder[num].Memory 	  = MEM_ME;
544 			if (num == 0x01) { /* OUTBOX SIM */
545 				Data->SMSFolders->Folder[0].Memory 	= MEM_SM;
546 				Data->SMSFolders->Folder[0].InboxFolder = TRUE;
547 				Data->SMSFolders->Folder[0].OutboxFolder = FALSE;
548 
549 				Data->SMSFolders->Folder[1].Memory 	= MEM_SM;
550 				Data->SMSFolders->Folder[1].InboxFolder = FALSE;
551 				Data->SMSFolders->Folder[1].OutboxFolder = TRUE;
552 
553 				CopyUnicodeString(Data->SMSFolders->Folder[2].Name,Data->SMSFolders->Folder[0].Name);
554 				Data->SMSFolders->Folder[2].Memory 	= MEM_ME;
555 				Data->SMSFolders->Folder[2].InboxFolder = TRUE;
556 				Data->SMSFolders->Folder[2].OutboxFolder = FALSE;
557 
558 				CopyUnicodeString(Data->SMSFolders->Folder[3].Name,Data->SMSFolders->Folder[1].Name);
559 				Data->SMSFolders->Folder[3].Memory 	= MEM_ME;
560 				Data->SMSFolders->Folder[3].InboxFolder = FALSE;
561 				Data->SMSFolders->Folder[3].OutboxFolder = TRUE;
562 
563 				num+=2;
564 			}
565 			num++;
566 		}
567 		return ERR_NONE;
568 	case 0xf0:
569 		smprintf(s, "HINT: Maybe phone needs F_SMS_FILES?\n");
570 		break;
571 	}
572 	return ERR_UNKNOWNRESPONSE;
573 }
574 
N6510_GetSMSFoldersS40_30(GSM_StateMachine * s UNUSED,GSM_SMSFolders * folders)575 GSM_Error N6510_GetSMSFoldersS40_30(GSM_StateMachine *s UNUSED, GSM_SMSFolders *folders)
576 {
577 	folders->Number=4;
578 	EncodeUnicode(folders->Folder[0].Name,_("SIM"),strlen(_("SIM")));
579 	EncodeUnicode(folders->Folder[1].Name,_("Inbox"),strlen(_("Inbox")));
580 	EncodeUnicode(folders->Folder[2].Name,_("Sent items"),strlen(_("Sent items")));
581 	EncodeUnicode(folders->Folder[3].Name,_("Saved items"),strlen(_("Saved items")));
582 	folders->Folder[0].InboxFolder = TRUE;
583 	folders->Folder[1].InboxFolder = TRUE;
584 	folders->Folder[2].InboxFolder = FALSE;
585 	folders->Folder[3].InboxFolder = FALSE;
586 	folders->Folder[0].OutboxFolder = TRUE;
587 	folders->Folder[1].OutboxFolder = FALSE;
588 	folders->Folder[2].OutboxFolder = TRUE;
589 	folders->Folder[3].OutboxFolder = FALSE;
590 	folders->Folder[0].Memory      = MEM_SM;
591 	folders->Folder[1].Memory      = MEM_ME;
592 	folders->Folder[2].Memory      = MEM_ME;
593 	folders->Folder[3].Memory      = MEM_ME;
594 	return ERR_NONE;
595 }
596 
N6510_GetSMSFolders(GSM_StateMachine * s,GSM_SMSFolders * folders)597 static GSM_Error N6510_GetSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders)
598 {
599 	unsigned char req[] = {N6110_FRAME_HEADER, 0x12, 0x00, 0x00};
600 
601 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
602 		if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMS_FILES)) return N6510_GetFilesystemSMSFolders(s,folders);
603 		return N6510_GetSMSFoldersS40_30(s,folders);
604 	}
605 
606 	s->Phone.Data.SMSFolders=folders;
607 	smprintf(s, "Getting SMS folders\n");
608 	return GSM_WaitFor (s, req, 6, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_GetSMSFolders);
609 }
610 
N6510_ReplyGetSMSFolderStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)611 static GSM_Error N6510_ReplyGetSMSFolderStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
612 {
613 	int			i;
614 	GSM_Phone_N6510Data	*Priv = &s->Phone.Data.Priv.N6510;
615 
616 	smprintf(s, "SMS folder status received\n");
617 	Priv->LastSMSFolder.Number=msg->Buffer[6]*256+msg->Buffer[7];
618 	smprintf(s, "Number of Entries: %i\n",Priv->LastSMSFolder.Number);
619 	smprintf(s, "Locations: ");
620 	for (i=0;i<Priv->LastSMSFolder.Number;i++) {
621 		Priv->LastSMSFolder.Location[i]=msg->Buffer[8+(i*2)]*256+msg->Buffer[(i*2)+9];
622 		smprintf(s, "%i ",Priv->LastSMSFolder.Location[i]);
623 	}
624 	smprintf(s, "\n");
625 	NOKIA_SortSMSFolderStatus(s, &Priv->LastSMSFolder);
626 	return ERR_NONE;
627 }
628 
N6510_GetSMSFolderStatus(GSM_StateMachine * s,int folderid)629 static GSM_Error N6510_GetSMSFolderStatus(GSM_StateMachine *s, int folderid)
630 {
631 	unsigned char req[] = {N7110_FRAME_HEADER, 0x0C,
632 			       0x01,		/* 0x01=SIM, 0x02=ME 	*/
633 			       0x00,		/* Folder ID		*/
634 			       0x0f, 0x55, 0x55, 0x55};
635 
636 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
637 		switch (folderid) {
638 			case 0x01: req[5] = 0x01; 			break; /* SIM 		*/
639 			default	 : req[5] = folderid; req[4] = 0x02; 	break; /* ME folders	*/
640 		}
641 	} else {
642 		switch (folderid) {
643 			case 0x01: req[5] = 0x02; 			 break; /* INBOX SIM 	*/
644 			case 0x02: req[5] = 0x03; 			 break; /* OUTBOX SIM 	*/
645 			default	 : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders	*/
646 		}
647 	}
648 
649 	smprintf(s, "Getting SMS folder status\n");
650 	return GSM_WaitFor (s, req, 10, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_GetSMSFolderStatus);
651 }
652 
N6510_GetSMSLocation(GSM_StateMachine * s,GSM_SMSMessage * sms,unsigned char * folderid,unsigned int * location)653 static void N6510_GetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *folderid, unsigned int *location)
654 {
655 	int ifolderid;
656 
657 	/* simulate flat SMS memory */
658 	if (sms->Folder==0x00) {
659 		ifolderid = sms->Location / GSM_PHONE_MAXSMSINFOLDER;
660 		*folderid = ifolderid + 0x01;
661 		*location = sms->Location - ifolderid * GSM_PHONE_MAXSMSINFOLDER;
662 		if (*folderid == 0x1B) (*folderid)=0x99; /* 0x1A is Outbox in 6230i */
663 	} else {
664 		*folderid = sms->Folder;
665 		*location = sms->Location;
666 		if (*folderid == 0x1A) (*folderid)=0x99; /* 0x1A is Outbox in 6230i */
667 	}
668 	smprintf(s, "SMS folder %i & location %i -> 6510 folder %i & location %i\n",
669 		sms->Folder,sms->Location,*folderid,*location);
670 }
671 
N6510_SetSMSLocation(GSM_StateMachine * s,GSM_SMSMessage * sms,unsigned char folderid,int location)672 static void N6510_SetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char folderid, int location)
673 {
674 	sms->Folder	= 0;
675 	sms->Location	= (folderid - 0x01) * GSM_PHONE_MAXSMSINFOLDER + location;
676 	smprintf(s, "6510 folder %i & location %i -> SMS folder %i & location %i\n",
677 		folderid,location,sms->Folder,sms->Location);
678 }
679 
N6510_DecodeSMSFrame(GSM_StateMachine * s,GSM_SMSMessage * sms,unsigned char * buffer,size_t * current2)680 static GSM_Error N6510_DecodeSMSFrame(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *buffer, size_t *current2)
681 {
682 	int 			i, current, blocks=0, SMSTemplateDateTime = 0;
683 	GSM_SMSMessageLayout 	Layout;
684 	GSM_Error		error;
685 
686 	memset(&Layout,255,sizeof(GSM_SMSMessageLayout));
687 	Layout.firstbyte = 2;
688 	switch (buffer[0]) {
689 	case 0x00:
690 		smprintf(s, "SMS deliver\n");
691 		sms->PDU 	= SMS_Deliver;
692 		Layout.TPPID 	= 3;
693 		Layout.TPDCS 	= 4;
694 		Layout.DateTime = 5;
695 		blocks 		= 15;
696 		break;
697 	case 0x01:
698 		smprintf(s, "Delivery report\n");
699 		sms->PDU = SMS_Status_Report;
700 		Layout.TPMR	= 3;
701 		Layout.TPStatus	= 4;
702 		Layout.DateTime = 5;
703 		Layout.SMSCTime = 12;
704 		blocks 		= 19;
705 		break;
706 	case 0x02:
707 		smprintf(s, "SMS template\n");
708 		sms->PDU 	= SMS_Submit;
709 		Layout.TPMR	= 3;
710 		Layout.TPPID 	= 4;
711 		Layout.TPDCS 	= 5;
712 		blocks 		= 7;
713 		break;
714 	}
715 	current = blocks + 1;
716 	for (i=0;i<buffer[blocks];i++) {
717 		switch (buffer[current]) {
718 		case 0x08:
719 			smprintf(s, "SMSC timestamp (ignored)\n");
720 			break;
721 		case 0x80:
722 			smprintf(s, "SMS text\n");
723 			if (buffer[current + 2] > buffer[current + 3]) {
724 				Layout.TPUDL 	= current + 2;
725 			} else {
726 				Layout.TPUDL 	= current + 3;
727 			}
728 			Layout.Text 		= current + 4;
729 			break;
730 		case 0x82:
731 			switch (buffer[current+2]) {
732 			case 0x01:
733 				smprintf(s, "Phone number\n");
734 				Layout.Number = current + 4;
735 				break;
736 			case 0x02:
737 				smprintf(s, "SMSC number\n");
738 				Layout.SMSCNumber = current + 4;
739 				break;
740 			default:
741 				smprintf(s, "Unknown number\n");
742 				break;
743 			}
744 			break;
745 		case 0x84:
746 			smprintf(s, "Date and time of saving for SMS template\n");
747 			SMSTemplateDateTime = current + 2;
748 			break;
749 		default:
750 			smprintf(s, "Unknown block %02x\n",buffer[current]);
751 		}
752 		current = current + buffer[current + 1];
753 	}
754 	error = GSM_DecodeSMSFrame(&(s->di), sms,buffer,Layout);
755 	if (SMSTemplateDateTime != 0) {
756 		sms->PDU = SMS_Deliver;
757 		NOKIA_DecodeDateTime(s, buffer+SMSTemplateDateTime, &sms->DateTime, TRUE, FALSE);
758 	}
759 	(*current2) = current;
760 	return error;
761 }
762 
N6510_ReplyGetSMSMessage(GSM_Protocol_Message * msg,GSM_StateMachine * s)763 GSM_Error N6510_ReplyGetSMSMessage(GSM_Protocol_Message *msg, GSM_StateMachine *s)
764 {
765 	size_t			i,j;
766 	size_t			Width, Height;
767 	unsigned char		output[500]; /* output2[500]; */
768 	GSM_Phone_Data		*Data = &s->Phone.Data;
769 	GSM_Error		error;
770 
771 	switch(msg->Buffer[3]) {
772 	case 0x03:
773 		smprintf(s, "SMS Message received\n");
774 		GSM_SetDefaultReceivedSMSData(Data->GetSMSMessage->SMS);
775 		Data->GetSMSMessage->Number=1;
776 		NOKIA_DecodeSMSState(s, msg->Buffer[5], &(Data->GetSMSMessage->SMS[0]));
777 		if (msg->Length < 15) {
778 			smprintf(s, "No message data!\n");
779 			Data->GetSMSMessage->SMS[0].PDU = SMS_Deliver;
780 			return ERR_NONE;
781 		}
782 		switch (msg->Buffer[14]) {
783 		case 0x00:
784 		case 0x01:
785 		case 0x02:
786 			if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
787 				Data->GetSMSMessage->Number=0;
788 				i = 14;
789 				while (TRUE) {
790 					error = N6510_DecodeSMSFrame(s, &Data->GetSMSMessage->SMS[Data->GetSMSMessage->Number],msg->Buffer+i,&j);
791 					if (error != ERR_NONE) return error;
792 					NOKIA_DecodeSMSState(s, msg->Buffer[5], &Data->GetSMSMessage->SMS[Data->GetSMSMessage->Number]);
793 					i+=j;
794 					Data->GetSMSMessage->Number++;
795 					if (i>=msg->Length) break;
796 				}
797 				return error;
798 			} else {
799 				return N6510_DecodeSMSFrame(s, &Data->GetSMSMessage->SMS[0],msg->Buffer+14,&j);
800 			}
801 		case 0xA0:
802 			smprintf(s, "Picture Image\n");
803 			Data->GetSMSMessage->Number = 0;
804 			i = 0;
805 			output[i++] = 0x30;	 /* Smart Messaging 3.0 */
806 			output[i++] = SM30_OTA;
807 			output[i++] = 0x01;	 /* Length */
808 			output[i++] = 0x00;	 /* Length */
809 			output[i++] = 0x00;
810 			PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height);
811 			output[i++] = Width;
812 			output[i++] = Height;
813 			output[i++] = 0x01;
814 			memcpy(output+i,msg->Buffer+30,PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0));
815 			i = i + PHONE_GetBitmapSize(GSM_NokiaPictureImage,0,0);
816 #if 0
817  			if (msg->Length!=282) {
818  				output[i++] = SM30_UNICODETEXT;
819  				output[i++] = 0;
820  				output[i++] = 0; /* Length - later changed */
821  				GSM_UnpackEightBitsToSeven(0, msg->Length-282, msg->Length-304, msg->Buffer+282,output2);
822  				DecodeDefault(output+i, output2, msg->Length - 282, TRUE, NULL);
823  				output[i - 1] = UnicodeLength(output+i) * 2;
824  				i = i + output[i-1];
825  			}
826 #endif
827 			GSM_MakeMultiPartSMS(&(s->di), Data->GetSMSMessage,output,i,UDH_NokiaProfileLong,SMS_Coding_8bit,1,0);
828 			for (i=0;i<3;i++) {
829                 		Data->GetSMSMessage->SMS[i].Number[0]=0;
830                 		Data->GetSMSMessage->SMS[i].Number[1]=0;
831 			}
832 			if (Data->Bitmap != NULL) {
833 				Data->Bitmap->Location	= 0;
834 				PHONE_GetBitmapWidthHeight(GSM_NokiaPictureImage, &Width, &Height);
835 				Data->Bitmap->BitmapWidth	= Width;
836 				Data->Bitmap->BitmapHeight	= Height;
837 				PHONE_DecodeBitmap(GSM_NokiaPictureImage, msg->Buffer + 30, Data->Bitmap);
838 				Data->Bitmap->Sender[0] = 0x00;
839 				Data->Bitmap->Sender[1] = 0x00;
840 				Data->Bitmap->Text[0] = 0;
841 				Data->Bitmap->Text[1] = 0;
842 			}
843 			return ERR_NONE;
844 		default:
845 			smprintf(s, "Unknown SMS type: %i\n",msg->Buffer[8]);
846 		}
847 		break;
848 	case 0x0f:
849 		smprintf(s, "SMS message info received\n");
850 		CopyUnicodeString(Data->GetSMSMessage->SMS[0].Name,msg->Buffer+52);
851 		smprintf(s, "Name: \"%s\"\n",DecodeUnicodeString(Data->GetSMSMessage->SMS[0].Name));
852 		return ERR_NONE;
853 	}
854 	return ERR_UNKNOWNRESPONSE;
855 }
856 
N6510_PrivGetSMSMessageBitmap(GSM_StateMachine * s,GSM_MultiSMSMessage * sms,GSM_Bitmap * bitmap)857 static GSM_Error N6510_PrivGetSMSMessageBitmap(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, GSM_Bitmap *bitmap)
858 {
859 	GSM_Error		error;
860 	unsigned char		folderid,namebuffer[200];
861 	unsigned int		location;
862 	int			i;
863 	unsigned char req[] = {
864 		N6110_FRAME_HEADER,
865 		0x02,		/* msg type: 0x02 for getting sms, 0x0e for sms status */
866 		0x01,		/* 0x01=SIM, 0x02=ME 	*/
867 		0x00, 		/* FolderID */
868 		0x00, 0x02,	/* Location */
869 		0x01, 0x00};
870 
871 	N6510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
872 
873 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
874 		switch (folderid) {
875 			case 0x01: req[5] = 0x01; 			 break; /* SIM 		*/
876 			default	 : req[5] = folderid; req[4] = 0x02; 	 break; /* ME folders	*/
877 		}
878 	} else {
879 		switch (folderid) {
880 			case 0x01: req[5] = 0x02; 			 break; /* INBOX SIM 	*/
881 			case 0x02: req[5] = 0x03; 			 break; /* OUTBOX SIM 	*/
882 			default	 : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders	*/
883 		}
884 	}
885 
886 	req[6]=location / 256;
887 	req[7]=location % 256;
888 
889 	s->Phone.Data.GetSMSMessage 	= sms;
890 	s->Phone.Data.Bitmap 		= bitmap;
891 	smprintf(s, "Getting sms message info\n");
892 	req[3] = 0x0e; req[8] = 0x55; req[9] = 0x55;
893 	error=GSM_WaitFor (s, req, 10, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_GetSMSMessage);
894 	if (error!=ERR_NONE) return error;
895 	CopyUnicodeString(namebuffer,sms->SMS[0].Name);
896 
897 	smprintf(s, "Getting sms\n");
898 	req[3] = 0x02; req[8] = 0x01; req[9] = 0x00;
899 	error = GSM_WaitFor (s, req, 10, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_GetSMSMessage);
900 	if (error == ERR_NONE) {
901 		if (sms->Number == 0) {
902 			return ERR_EMPTY;
903 		}
904 		for (i=0;i<sms->Number;i++) {
905 			N6510_SetSMSLocation(s, &sms->SMS[i], folderid, location);
906 			sms->SMS[i].Folder 	= folderid;
907 
908 			if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
909 				sms->SMS[i].InboxFolder = TRUE;
910 				if (folderid > 2) sms->SMS[i].InboxFolder = FALSE;
911 				sms->SMS[i].Memory = MEM_ME;
912 				if (folderid == 0x01) sms->SMS[i].Memory = MEM_SM;
913 			} else {
914 				sms->SMS[i].InboxFolder = TRUE;
915 				if (folderid != 0x01 && folderid != 0x03) sms->SMS[i].InboxFolder = FALSE;
916 				sms->SMS[i].Memory	= MEM_ME;
917 				if (folderid == 0x01 || folderid == 0x02) sms->SMS[i].Memory = MEM_SM;
918 			}
919 
920 			CopyUnicodeString(sms->SMS[i].Name,namebuffer);
921 		}
922 	}
923 	return error;
924 }
925 
N6510_GetSMSMessage(GSM_StateMachine * s,GSM_MultiSMSMessage * sms)926 static GSM_Error N6510_GetSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms)
927 {
928 	GSM_Error		error;
929 	unsigned char		folderid;
930 	unsigned int		location;
931 	GSM_Phone_N6510Data	*Priv = &s->Phone.Data.Priv.N6510;
932 	int			i;
933 	gboolean			found = FALSE;
934 
935 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
936 		if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMS_FILES)) return ERR_NOTSUPPORTED;
937 	}
938 
939 	/* Clear SMS structure of any possible junk */
940 	GSM_SetDefaultReceivedSMSData(&(sms->SMS[0]));
941 
942 	N6510_GetSMSLocation(s, &(sms->SMS[0]), &folderid, &location);
943 	error=N6510_GetSMSFolderStatus(s, folderid);
944 	if (error!=ERR_NONE) return error;
945 	for (i=0;i<Priv->LastSMSFolder.Number;i++) {
946 		if (Priv->LastSMSFolder.Location[i]==location) {
947 			found = TRUE;
948 			break;
949 		}
950 	}
951 	if (!found) return ERR_EMPTY;
952 	return N6510_PrivGetSMSMessageBitmap(s,sms,NULL);
953 }
954 
N6510_GetNextSMSMessageBitmap(GSM_StateMachine * s,GSM_MultiSMSMessage * sms,gboolean start,GSM_Bitmap * bitmap)955 static GSM_Error N6510_GetNextSMSMessageBitmap(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboolean start, GSM_Bitmap *bitmap)
956 {
957 	GSM_Phone_N6510Data	*Priv = &s->Phone.Data.Priv.N6510;
958 	unsigned char		folderid;
959 	unsigned int		location;
960 	GSM_Error		error;
961 	int			i;
962 	gboolean			findnextfolder = FALSE;
963 
964 	if (start) {
965 		folderid	= 0x00;
966 		findnextfolder	= TRUE;
967 		error=N6510_GetSMSFolders(s,&Priv->LastSMSFolders);
968 		if (error!=ERR_NONE) return error;
969 	} else {
970 		N6510_GetSMSLocation(s, &(sms->SMS[0]), &folderid, &location);
971 		for (i=0;i<Priv->LastSMSFolder.Number;i++) {
972 			if (Priv->LastSMSFolder.Location[i]==location) break;
973 		}
974 		/* Is this last location in this folder ? */
975 		if (i==Priv->LastSMSFolder.Number-1) {
976 			findnextfolder=TRUE;
977 		} else {
978 			location=Priv->LastSMSFolder.Location[i+1];
979 		}
980 	}
981 	if (findnextfolder) {
982 		Priv->LastSMSFolder.Number=0;
983 		while (Priv->LastSMSFolder.Number==0) {
984 			folderid++;
985 			/* Too high folder number */
986 			if ((folderid-1)>=Priv->LastSMSFolders.Number) return ERR_EMPTY;
987 			/* Get next folder status */
988 			error=N6510_GetSMSFolderStatus(s, folderid);
989 			if (error!=ERR_NONE) return error;
990 			/* First location from this folder */
991 			location=Priv->LastSMSFolder.Location[0];
992 		}
993 	}
994 	N6510_SetSMSLocation(s, &sms->SMS[0], folderid, location);
995 
996 	return N6510_PrivGetSMSMessageBitmap(s, sms, bitmap);
997 }
998 
N6510_GetNextSMSMessage(GSM_StateMachine * s,GSM_MultiSMSMessage * sms,gboolean start)999 static GSM_Error N6510_GetNextSMSMessage(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboolean start)
1000 {
1001 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30) &&
1002 			GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMS_FILES)) {
1003 		return N6510_GetNextFilesystemSMS(s,sms,start);
1004 	}
1005 
1006 	return N6510_GetNextSMSMessageBitmap(s, sms, start, NULL);
1007 }
1008 
N6510_ReplyStartupNoteLogo(GSM_Protocol_Message * msg,GSM_StateMachine * s)1009 static GSM_Error N6510_ReplyStartupNoteLogo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1010 {
1011 	GSM_Phone_Data *Data = &s->Phone.Data;
1012 
1013 	if (Data->RequestID == ID_GetBitmap) {
1014 		switch (msg->Buffer[4]) {
1015 		case 0x01:
1016 			smprintf(s, "Welcome note text received\n");
1017 			CopyUnicodeString(Data->Bitmap->Text,msg->Buffer+6);
1018 			smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text));
1019 			return ERR_NONE;
1020 		case 0x10:
1021 			smprintf(s, "Dealer note text received\n");
1022 			CopyUnicodeString(Data->Bitmap->Text,msg->Buffer+6);
1023 			smprintf(s, "Text is \"%s\"\n",DecodeUnicodeString(Data->Bitmap->Text));
1024 			return ERR_NONE;
1025 		case 0x0f:
1026 			smprintf(s, "Startup logo received\n");
1027 			PHONE_DecodeBitmap(GSM_Nokia7110StartupLogo, msg->Buffer + 22, Data->Bitmap);
1028 			return ERR_NONE;
1029 		}
1030 	}
1031 	if (Data->RequestID == ID_SetBitmap) {
1032 		switch (msg->Buffer[4]) {
1033 			case 0x01:
1034 			case 0x10:
1035 			case 0x0f:
1036 			case 0x25:
1037 				return ERR_NONE;
1038 		}
1039 	}
1040 	return ERR_UNKNOWN;
1041 }
1042 
N6510_GetPictureImage(GSM_StateMachine * s,GSM_Bitmap * Bitmap,int * location)1043 static GSM_Error N6510_GetPictureImage(GSM_StateMachine *s, GSM_Bitmap *Bitmap, int *location)
1044 {
1045 	GSM_MultiSMSMessage 	sms;
1046 	int			Number;
1047 	GSM_Bitmap		bitmap;
1048 	GSM_Error		error;
1049 
1050 	sms.SMS[0].Folder	= 0;
1051 	Number			= 0;
1052 	bitmap.Location		= 255;
1053 	error=N6510_GetNextSMSMessageBitmap(s, &sms, TRUE, &bitmap);
1054 	while (error == ERR_NONE) {
1055 		if (bitmap.Location != 255) {
1056 			Number++;
1057 			if (Number == Bitmap->Location) {
1058 				bitmap.Location = Bitmap->Location;
1059 				memcpy(Bitmap,&bitmap,sizeof(GSM_Bitmap));
1060 				*location = sms.SMS[0].Location;
1061 				return ERR_NONE;
1062 			}
1063 		}
1064 		bitmap.Location		= 255;
1065 		sms.SMS[0].Folder 	= 0;
1066 		error=N6510_GetNextSMSMessageBitmap(s, &sms, FALSE, &bitmap);
1067 	}
1068 	return ERR_INVALIDLOCATION;
1069 }
1070 
N6510_GetBitmap(GSM_StateMachine * s,GSM_Bitmap * Bitmap)1071 static GSM_Error N6510_GetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
1072 {
1073 	unsigned char reqOp	[] = {N6110_FRAME_HEADER, 0x23, 0x00, 0x00, 0x55, 0x55, 0x55};
1074 	unsigned char reqStartup[] = {N6110_FRAME_HEADER, 0x02, 0x0f};
1075 	unsigned char reqNote	[] = {N6110_FRAME_HEADER, 0x02, 0x01, 0x00};
1076 	GSM_MemoryEntry	pbk;
1077 	GSM_Error		error;
1078 	int			Location;
1079 
1080 	s->Phone.Data.Bitmap=Bitmap;
1081 	switch (Bitmap->Type) {
1082 	case GSM_StartupLogo:
1083 		Bitmap->BitmapWidth  = 96;
1084 		Bitmap->BitmapHeight = 65;
1085 		GSM_ClearBitmap(Bitmap);
1086 		smprintf(s, "Getting startup logo\n");
1087 		return GSM_WaitFor (s, reqStartup, 5, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_GetBitmap);
1088 	case GSM_DealerNote_Text:
1089 		reqNote[4] = 0x10;
1090 		smprintf(s, "Getting dealer note\n");
1091 		return GSM_WaitFor (s, reqNote, 6, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_GetBitmap);
1092 	case GSM_WelcomeNote_Text:
1093 		smprintf(s, "Getting welcome note\n");
1094 		return GSM_WaitFor (s, reqNote, 6, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_GetBitmap);
1095 	case GSM_CallerGroupLogo:
1096 		if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PBK35)) return ERR_NOTSUPPORTED;
1097 		if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1098 			pbk.MemoryType	= (GSM_MemoryType)MEM6510_CG2;
1099 			pbk.Location	= Bitmap->Location;
1100 			smprintf(s, "Getting caller group logo method 2\n");
1101 			return N6510_GetMemory(s,&pbk);
1102 		}
1103 		Bitmap->BitmapWidth  	 = 72;
1104 		Bitmap->BitmapHeight 	 = 14;
1105 		GSM_ClearBitmap(Bitmap);
1106 		pbk.MemoryType	= (GSM_MemoryType)MEM7110_CG;
1107 		pbk.Location	= Bitmap->Location;
1108 		smprintf(s, "Getting caller group logo\n");
1109 		error=N6510_GetMemory(s,&pbk);
1110 		if (error==ERR_NONE) NOKIA_GetDefaultCallerGroupName(Bitmap);
1111 		return error;
1112 	case GSM_OperatorLogo:
1113 		smprintf(s, "Getting operator logo\n");
1114 		return GSM_WaitFor (s, reqOp, 9, 0x0A, s->Phone.Data.Priv.N6510.Timeout, ID_GetBitmap);
1115 	case GSM_PictureImage:
1116 		return N6510_GetPictureImage(s, Bitmap, &Location);
1117 	default:
1118 		break;
1119 	}
1120 	return ERR_NOTSUPPORTED;
1121 }
1122 
N6510_ReplyGetIncSignalQuality(GSM_Protocol_Message * msg,GSM_StateMachine * s)1123 static GSM_Error N6510_ReplyGetIncSignalQuality(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1124 {
1125 	smprintf(s, "Network level changed to: %i\n",msg->Buffer[4]);
1126 	return ERR_NONE;
1127 }
1128 
N6510_ReplyGetSignalQuality(GSM_Protocol_Message * msg,GSM_StateMachine * s)1129 static GSM_Error N6510_ReplyGetSignalQuality(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1130 {
1131 	GSM_Phone_Data *Data = &s->Phone.Data;
1132 
1133 	smprintf(s, "Network level received: %i\n",msg->Buffer[8]);
1134     	Data->SignalQuality->SignalStrength 	= -1;
1135     	Data->SignalQuality->SignalPercent 	= ((int)msg->Buffer[8]);
1136     	Data->SignalQuality->BitErrorRate 	= -1;
1137 	return ERR_NONE;
1138 }
1139 
N6510_GetSignalQuality(GSM_StateMachine * s,GSM_SignalQuality * sig)1140 static GSM_Error N6510_GetSignalQuality(GSM_StateMachine *s, GSM_SignalQuality *sig)
1141 {
1142 	unsigned char req[] = {N6110_FRAME_HEADER, 0x0B, 0x00, 0x02, 0x00, 0x00, 0x00};
1143 
1144 	s->Phone.Data.SignalQuality = sig;
1145 	smprintf(s, "Getting network level\n");
1146 	return GSM_WaitFor (s, req, 9, 0x0a, s->Phone.Data.Priv.N6510.Timeout * 3, ID_GetSignalQuality);
1147 }
1148 
N6510_IncomingBatteryCharge(GSM_Protocol_Message * msg,GSM_StateMachine * s)1149 static GSM_Error N6510_IncomingBatteryCharge(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1150 {
1151 	smprintf(s, "Incoming battery level received???: %i\n",
1152 			msg->Buffer[9]*100/7);
1153 	return ERR_NONE;
1154 }
1155 
N6510_ReplyGetBatteryCharge(GSM_Protocol_Message * msg,GSM_StateMachine * s)1156 static GSM_Error N6510_ReplyGetBatteryCharge(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1157 {
1158 	GSM_Phone_Data *Data = &s->Phone.Data;
1159 
1160 	Data->BatteryCharge->BatteryPercent 	= ((int)(msg->Buffer[9]*100/msg->Buffer[8]));
1161     	Data->BatteryCharge->ChargeState 	= 0;
1162 
1163 	smprintf(s, "Battery level received: %i\n",
1164 			Data->BatteryCharge->BatteryPercent);
1165 
1166 	return ERR_NONE;
1167 }
1168 
N6510_GetBatteryCharge(GSM_StateMachine * s,GSM_BatteryCharge * bat)1169 static GSM_Error N6510_GetBatteryCharge(GSM_StateMachine *s, GSM_BatteryCharge *bat)
1170 {
1171 	unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x02, 0x00};
1172 
1173 	GSM_ClearBatteryCharge(bat);
1174 	s->Phone.Data.BatteryCharge = bat;
1175 	smprintf(s, "Getting battery level\n");
1176 	return GSM_WaitFor (s, req, 6, 0x17, s->Phone.Data.Priv.N6510.Timeout, ID_GetBatteryCharge);
1177 }
1178 
N6510_ReplyGetWAPBookmark(GSM_Protocol_Message * msg,GSM_StateMachine * s)1179 static GSM_Error N6510_ReplyGetWAPBookmark(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1180 {
1181 	return DCT3DCT4_ReplyGetWAPBookmark (msg, s, TRUE);
1182 }
1183 
N6510_ReplyGetOperatorLogo(GSM_Protocol_Message * msg,GSM_StateMachine * s)1184 static GSM_Error N6510_ReplyGetOperatorLogo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1185 {
1186 	GSM_Phone_Data *Data = &s->Phone.Data;
1187 
1188 	if (msg->Buffer[3] == 0xf0) return ERR_NOTSUPPORTED;
1189 
1190 	smprintf(s, "Operator logo received\n");
1191 	if (msg->Length <= 18) {
1192 		smprintf(s, "Packet too short to contain operator logo\n");
1193 		return ERR_EMPTY;
1194 	}
1195 	NOKIA_DecodeNetworkCode(msg->Buffer+12,Data->Bitmap->NetworkCode);
1196 	smprintf(s, "Network code %s\n",Data->Bitmap->NetworkCode);
1197 	Data->Bitmap->BitmapWidth	= msg->Buffer[20];
1198 	Data->Bitmap->BitmapHeight	= msg->Buffer[21];
1199 	PHONE_DecodeBitmap(GSM_Nokia6510OperatorLogo,msg->Buffer+26,Data->Bitmap);
1200 	return ERR_NONE;
1201 }
1202 
N6510_ReplyDeleteMemory(GSM_Protocol_Message * msg,GSM_StateMachine * s)1203 GSM_Error N6510_ReplyDeleteMemory(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1204 {
1205 	if (msg->Buffer[5] == 0x1) {
1206 		switch (msg->Buffer[6]) {
1207 		case 0x0f:
1208 			switch (msg->Buffer[10]) {
1209 			case 0x21:
1210 				smprintf(s, "Still busy processing the last command\n");
1211 				return ERR_BUSY;
1212 			case 0x3B:
1213 				smprintf(s, "Nothing to delete\n");
1214 				return ERR_NONE;
1215 			case 0x33:
1216 				smprintf(s, "Entry is read only\n");
1217 				return ERR_READ_ONLY;
1218 	                default:
1219 		                smprintf(s, "ERROR: unknown 0x%x\n", msg->Buffer[10]);
1220 			        return ERR_UNKNOWNRESPONSE;
1221 			}
1222 		}
1223 	}
1224 	smprintf(s, "Phonebook entry deleted\n");
1225 	return ERR_NONE;
1226 }
1227 
N6510_DeleteMemory(GSM_StateMachine * s,GSM_MemoryEntry * entry)1228 GSM_Error N6510_DeleteMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1229 {
1230 	unsigned char req[] = {N7110_FRAME_HEADER, 0x0f, 0x55, 0x01,
1231 			       0x04, 0x55, 0x00, 0x10, 0xFF, 0x02,
1232 			       0x00, 0x01,		/* location	*/
1233 			       0x00, 0x00, 0x00, 0x00,
1234 			       0x05, 			/* memory type	*/
1235 			       0x55, 0x55, 0x55};
1236 
1237 	req[12] = entry->Location / 256;
1238 	req[13] = entry->Location % 256;
1239 
1240 	req[18] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
1241 	if (req[18]==0xff) return ERR_NOTSUPPORTED;
1242 
1243 	smprintf(s, "Deleting phonebook entry\n");
1244 	return GSM_WaitFor (s, req, 22, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_SetMemory);
1245 }
1246 
N6510_SetMemory(GSM_StateMachine * s,GSM_MemoryEntry * entry)1247 static GSM_Error N6510_SetMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1248 {
1249 	int 		count = 22;
1250 	size_t blocks;
1251 	unsigned char 	req[5000] = {
1252 		N7110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x10, 0x02,
1253 		0x00,  			/* memory type */
1254 		0x00, 0x00,  		/* location */
1255 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1256 		0x00};			/* Number of blocks */
1257 	GSM_Error error;
1258 	GSM_MemoryEntry tmp;
1259 	GSM_MemoryStatus status;
1260 	GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1261 
1262 	if (entry->Location == 0) {
1263 		/*
1264 		 * We want to remember last location so that we don't check the
1265 		 * same place again and again.
1266 		 */
1267 		if (Priv->LastFreeMemoryType != entry->MemoryType) {
1268 			Priv->LastFreeMemoryLocation = 0;
1269 			Priv->LastFreeMemoryType = entry->MemoryType;
1270 			status.MemoryType = entry->MemoryType;
1271 			error = N6510_GetMemoryStatus(s, &status);
1272 			if (error != ERR_NONE) return error;
1273 			Priv->LastFreeMemorySize = status.MemoryUsed + status.MemoryFree;
1274 		}
1275 
1276 		/* Advance beyond last used location */
1277 		tmp.MemoryType = entry->MemoryType;
1278 		error = ERR_NONE;
1279 		for (tmp.Location = Priv->LastFreeMemoryLocation + 1;
1280 			tmp.Location < Priv->LastFreeMemorySize;
1281 			tmp.Location++) {
1282 			error = N6510_GetMemory(s, &tmp);
1283 			if (error != ERR_NONE) break;
1284 		}
1285 		if (error == ERR_NONE) {
1286 			/* Memory full */
1287 			return ERR_FULL;
1288 		} else if (error != ERR_EMPTY) {
1289 			/* Other failure */
1290 			return error;
1291 		}
1292 		/* We've got the location */
1293 		entry->Location = tmp.Location;
1294 		smprintf(s, "Found empty location: %d\n", entry->Location);
1295 	}
1296 
1297 	req[11] = NOKIA_GetMemoryType(s, entry->MemoryType,N71_65_MEMORY_TYPES);
1298 	if (req[11]==0xff) return ERR_NOTSUPPORTED;
1299 
1300 	req[12] = entry->Location / 256;
1301 	req[13] = entry->Location % 256;
1302 
1303 	count = count + N71_65_EncodePhonebookFrame(s, req+22, entry, &blocks, TRUE, GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_VOICETAGS));
1304 	req[21] = blocks;
1305 
1306 	smprintf(s, "Writing phonebook entry\n");
1307 	return GSM_WaitFor (s, req, count, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_SetMemory);
1308 }
1309 
N6510_AddMemory(GSM_StateMachine * s,GSM_MemoryEntry * entry)1310 static GSM_Error N6510_AddMemory(GSM_StateMachine *s, GSM_MemoryEntry *entry)
1311 {
1312 	entry->Location = 0;
1313 	return N6510_SetMemory(s, entry);
1314 }
1315 
N6510_ReplySetOperatorLogo(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)1316 static GSM_Error N6510_ReplySetOperatorLogo(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
1317 {
1318 	smprintf(s, "Operator logo set OK\n");
1319 	return ERR_NONE;
1320 }
1321 
N6510_SetCallerLogo(GSM_StateMachine * s,GSM_Bitmap * bitmap)1322 static GSM_Error N6510_SetCallerLogo(GSM_StateMachine *s, GSM_Bitmap *bitmap)
1323 {
1324 	char		string[500];
1325 	int		block=0, i;
1326 	size_t Width, Height;
1327 	unsigned int 	count = 22;
1328 	unsigned char 	req[500] = {
1329 		N6110_FRAME_HEADER, 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x10,
1330 		0xfe, 0x00,		/* memory type */
1331 		0x00, 0x00,		/* location */
1332 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1333 
1334 	/* Set memory type */
1335 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1336 		req[11] = MEM6510_CG2;
1337 	} else {
1338 		req[11] = MEM7110_CG;
1339 	}
1340 
1341 	req[13] = bitmap->Location;
1342 
1343 	/* Enabling/disabling logo */
1344 	if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1345 		string[0] = bitmap->BitmapEnabled?1:0;
1346 		string[1] = 0;
1347 		count += N71_65_PackPBKBlock(s, N7110_PBK_LOGOON, 2, block++, string, req + count);
1348 	}
1349 
1350 	/* Ringtone */
1351 	if (!bitmap->DefaultRingtone) {
1352 		if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1353 			string[0] = 0x00;
1354 			string[1] = 0x00;
1355 			string[2] = 0x00;
1356 			string[3] = 0x10;
1357 			string[4] = 0x00;
1358 			string[5] = 0x00;
1359 			string[6] = bitmap->RingtoneID;
1360 			string[7] = 0x00;
1361 			string[8] = 0x00;
1362 			string[9] = 0x00;
1363 			count += N71_65_PackPBKBlock(s, N6510_PBK_RINGTONEFILE_ID, 10, block++, string, req + count);
1364 			req[count - 1] = 0x01;
1365 		} else if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PBKTONEGAL)) {
1366 			/* do nothing ? */
1367 		} else {
1368 			string[0] = 0x00;
1369 			string[1] = 0x00;
1370 			string[2] = bitmap->RingtoneID;
1371 			count += N71_65_PackPBKBlock(s, N7110_PBK_RINGTONE_ID, 3, block++, string, req + count);
1372 			count --;
1373 			req[count-5] = 8;
1374 		}
1375 	}
1376 
1377 	/* Number of group */
1378 	if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1379 		string[0] = bitmap->Location;
1380 		string[1] = 0;
1381 		count += N71_65_PackPBKBlock(s, N7110_PBK_GROUP, 2, block++, string, req + count);
1382 	}
1383 
1384 	/* Name */
1385 	if (!bitmap->DefaultName) {
1386 		i = UnicodeLength(bitmap->Text) * 2;
1387 		string[0] = i + 2;
1388 		memcpy(string + 1, bitmap->Text, i);
1389 		string[i + 1] = 0;
1390 		count += N71_65_PackPBKBlock(s, N7110_PBK_NAME, i + 2, block++, string, req + count);
1391 	}
1392 
1393 	/* Logo */
1394 	if (!bitmap->DefaultBitmap) {
1395 		if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iCALLER)) {
1396 			/* write N6510_PBK_PICTURE_ID ? */
1397 		} else {
1398 			PHONE_GetBitmapWidthHeight(GSM_NokiaCallerLogo, &Width, &Height);
1399 			string[0] = Width;
1400 			string[1] = Height;
1401 			string[2] = 0;
1402 			string[3] = 0;
1403 			string[4] = PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0);
1404 			PHONE_EncodeBitmap(GSM_NokiaCallerLogo, string + 5, bitmap);
1405 			count += N71_65_PackPBKBlock(s, N7110_PBK_GROUPLOGO, PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 5, block++, string, req + count);
1406 		}
1407 	}
1408 
1409 	req[21] = block;
1410 
1411 	return GSM_WaitFor (s, req, count, 0x03, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1412 }
1413 
N6510_ReplySetPicture(GSM_Protocol_Message * msg,GSM_StateMachine * s)1414 static GSM_Error N6510_ReplySetPicture(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1415 {
1416 	smprintf(s, "Picture Image written OK, folder %i, location %i\n",msg->Buffer[4],msg->Buffer[5]*256+msg->Buffer[6]);
1417 	return ERR_NONE;
1418 }
1419 
N6510_SetBitmap(GSM_StateMachine * s,GSM_Bitmap * Bitmap)1420 static GSM_Error N6510_SetBitmap(GSM_StateMachine *s, GSM_Bitmap *Bitmap)
1421 {
1422 	GSM_SMSMessage		sms;
1423 	GSM_Phone_Bitmap_Types	Type;
1424 	size_t			Width, Height, i, count;
1425 	unsigned char		folderid;
1426 	unsigned int		location;
1427 	GSM_NetworkInfo 	NetInfo;
1428 	GSM_Error		error;
1429 	unsigned char reqStartup[1000] = {
1430 		N7110_FRAME_HEADER, 0x04, 0x0F,
1431 		0x00, 0x00, 0x00,
1432 		0x04, 0xC0, 0x02, 0x00,
1433 		0x41, 0xC0, 0x03, 0x00,
1434 		0x60, 0xC0, 0x04};
1435 	unsigned char reqColourWallPaper[200] = {
1436 		N6110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0xD5,
1437 		0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
1438 		0x00, 0x00, 0x00, 0x01, 0x00,
1439 		0x18};		/* Bitmap ID */
1440 	unsigned char reqColourStartup[200] = {
1441 		N6110_FRAME_HEADER, 0x04, 0x25, 0x00, 0x01, 0x00, 0x18};
1442 	unsigned char reqOp[1000] = {
1443 		N7110_FRAME_HEADER, 0x25, 0x01,
1444 		0x55, 0x00, 0x00, 0x55,
1445 		0x01,			/* 0x01 - not set, 0x02 - set */
1446 		0x0C, 0x08,
1447 		0x62, 0xF0, 0x10,	/* Network code */
1448 		0x03, 0x55, 0x55};
1449 	unsigned char reqColourOp[200] = {
1450 		N6110_FRAME_HEADER,
1451 		0x07, 0x00, 0x00, 0x00, 0xE7, 0x00, 0x00, 0x00, 0xF9, 0x00,
1452 		0x08, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00,
1453 		0x18,			/* File ID */
1454 		0x00,
1455 		0x00, 0x00, 0x00};	/* Network code */
1456 	unsigned char reqNote[200] = {N6110_FRAME_HEADER, 0x04, 0x01};
1457 	unsigned char reqPicture[2000] = {
1458 		N6110_FRAME_HEADER, 0x00,
1459 		0x02, 0x05,		/* SMS folder 	*/
1460 		0x00, 0x00,		/* location 	*/
1461 		0x01, 0x01, 0xa0, 0x02, 0x01, 0x40, 0x00, 0x34,
1462 		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1463 		0x00, 0x00, 0x55, 0x55, 0x55, 0x03, 0x82, 0x10,
1464 		0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1465 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x10,
1466 		0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1467 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04,
1468 		0x00, 0x00, 0xa1, 0x55, 0x01, 0x08, 0x00, 0x00,
1469 		0x00, 0x01, 0x48, 0x1c, 0x00, 0xfc, 0x00};
1470 
1471 	switch (Bitmap->Type) {
1472 	case GSM_ColourWallPaper_ID:
1473 		reqColourWallPaper[21] = Bitmap->ID;
1474 		smprintf(s, "Setting colour wall paper\n");
1475 		return GSM_WaitFor (s, reqColourWallPaper, 22, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1476 	case GSM_StartupLogo:
1477 		Type = GSM_Nokia7110StartupLogo;
1478 		switch (Bitmap->Location) {
1479 			case 1:	 PHONE_EncodeBitmap(Type, reqStartup + 22, Bitmap);
1480 				 break;
1481 			case 2:  memset(reqStartup+5,0x00,15);
1482 				 PHONE_ClearBitmap(Type, reqStartup + 22,0,0);
1483 				 break;
1484 			default: return ERR_NOTSUPPORTED;
1485 		}
1486 		smprintf(s, "Setting startup logo\n");
1487 		return GSM_WaitFor (s, reqStartup, 22+PHONE_GetBitmapSize(Type,0,0), 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1488 	case GSM_DealerNote_Text:
1489 		reqNote[4] = 0x10;
1490 		CopyUnicodeString(reqNote + 5, Bitmap->Text);
1491 		i = 6 + UnicodeLength(Bitmap->Text) * 2;
1492 		reqNote[i++] 	= 0;
1493 		reqNote[i] 	= 0;
1494 		return GSM_WaitFor (s, reqNote, i, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1495 	case GSM_WelcomeNote_Text:
1496 		CopyUnicodeString(reqNote + 5, Bitmap->Text);
1497 		i = 6 + UnicodeLength(Bitmap->Text) * 2;
1498 		reqNote[i++] 	= 0;
1499 		reqNote[i] 	= 0;
1500 		return GSM_WaitFor (s, reqNote, i, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1501 	case GSM_OperatorLogo:
1502 		/* We want to set operator logo, not clear */
1503 		if (strcmp(Bitmap->NetworkCode,"000 00")) {
1504 			memset(reqOp + 19, 0, 281);
1505 			NOKIA_EncodeNetworkCode(reqOp+12, Bitmap->NetworkCode);
1506 			Type = GSM_Nokia6510OperatorLogo;
1507 			reqOp[9]  = 0x02;	/* Logo enabled */
1508 			reqOp[18] = 0x1a;	/* FIXME */
1509 			reqOp[19] = PHONE_GetBitmapSize(Type,0,0) + 8 + 29 + 2;
1510 			PHONE_GetBitmapWidthHeight(Type, &Width, &Height);
1511 			reqOp[20] = Width;
1512 			reqOp[21] = Height;
1513 			reqOp[22] = 0x00;
1514 			reqOp[23] = PHONE_GetBitmapSize(Type,0,0) + 29;
1515 			reqOp[24] = 0x00;
1516 			reqOp[25] = PHONE_GetBitmapSize(Type,0,0) + 29;
1517 			PHONE_EncodeBitmap(Type, reqOp + 26, Bitmap);
1518 			smprintf(s, "Setting operator logo\n");
1519 			return GSM_WaitFor (s, reqOp, reqOp[19]+reqOp[11]+10, 0x0A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1520 		} else {
1521 			error=N6510_GetNetworkInfo(s,&NetInfo);
1522 			if (error != ERR_NONE) return error;
1523 			NOKIA_EncodeNetworkCode(reqOp+12, NetInfo.NetworkCode);
1524 			smprintf(s, "Clearing operator logo\n");
1525 			return GSM_WaitFor (s, reqOp, 18, 0x0A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1526 		}
1527 	case GSM_ColourOperatorLogo_ID:
1528 		/* We want to set operator logo, not clear */
1529 		if (strcmp(Bitmap->NetworkCode,"000 00")) {
1530 			EncodeBCD(reqColourOp+23, Bitmap->NetworkCode, 6, FALSE);
1531 			reqColourOp[21] = Bitmap->ID;
1532 		}
1533 		smprintf(s, "Setting colour operator logo\n");
1534 		return GSM_WaitFor (s, reqColourOp, 26, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1535 	case GSM_ColourStartupLogo_ID:
1536 		switch (Bitmap->Location) {
1537 			case 0: reqColourStartup[6] = 0x00;
1538 				reqColourStartup[8] = 0x00;
1539 				smprintf(s, "Setting colour startup logo\n");
1540 				return GSM_WaitFor (s, reqColourStartup, 9, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1541 			case 1: reqColourStartup[8] = Bitmap->ID;
1542 				smprintf(s, "Setting colour startup logo\n");
1543 				return GSM_WaitFor (s, reqColourStartup, 9, 0x7A, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1544 			default:return ERR_NOTSUPPORTED;
1545 		}
1546 	case GSM_CallerGroupLogo:
1547 		return N6510_SetCallerLogo(s,Bitmap);
1548 	case GSM_PictureImage:
1549 		error = N6510_GetPictureImage(s, Bitmap, &sms.Location);
1550 		if (error == ERR_NONE) {
1551 			sms.Folder = 0;
1552 			N6510_GetSMSLocation(s, &sms, &folderid, &location);
1553 			switch (folderid) {
1554 				case 0x01: reqPicture[5] = 0x02; 				break; /* INBOX SIM 	*/
1555 				case 0x02: reqPicture[5] = 0x03; 				break; /* OUTBOX SIM 	*/
1556 				default	 : reqPicture[5] = folderid - 1; reqPicture[4] = 0x02; 	break; /* ME folders	*/
1557 			}
1558 			reqPicture[6]=location / 256;
1559 			reqPicture[7]=location;
1560 		}
1561 		Type = GSM_NokiaPictureImage;
1562 		count = 78;
1563 		PHONE_EncodeBitmap(Type, reqPicture + count, Bitmap);
1564 		count += PHONE_GetBitmapSize(Type,0,0);
1565 		smprintf(s, "Setting Picture Image\n");
1566 		return GSM_WaitFor (s, reqPicture, count, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_SetBitmap);
1567 	default:
1568 		break;
1569 	}
1570 	return ERR_NOTSUPPORTED;
1571 }
1572 
N6510_ReplyGetRingtoneID(GSM_Protocol_Message * msg,GSM_StateMachine * s)1573 static GSM_Error N6510_ReplyGetRingtoneID(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1574 {
1575 	GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1576 
1577 	smprintf(s, "Ringtone ID received\n");
1578 	Priv->RingtoneID = msg->Buffer[15];
1579 	return ERR_NONE;
1580 }
1581 
N6510_ReplySetBinRingtone(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)1582 static GSM_Error N6510_ReplySetBinRingtone(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
1583 {
1584 	smprintf(s, "Binary ringtone set\n");
1585 	return ERR_NONE;
1586 }
1587 
N6510_SetRingtone(GSM_StateMachine * s,GSM_Ringtone * Ringtone,int * maxlength)1588 static GSM_Error N6510_SetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, int *maxlength)
1589 {
1590 	GSM_Error		error;
1591 	GSM_Phone_N6510Data 	*Priv = &s->Phone.Data.Priv.N6510;
1592 	GSM_NetworkInfo		NetInfo;
1593 	size_t			size=200, current;
1594 	unsigned char 		GetIDReq[] = {
1595 		N7110_FRAME_HEADER, 0x01, 0x00, 0x00,
1596 		0x00, 0xFF, 0x06, 0xE1, 0x00,
1597 		0xFF, 0x06, 0xE1, 0x01, 0x42};
1598 	unsigned char		SetPreviewReq[1000] = {
1599 		0xAE,		/* Ringtone ID */
1600 		0x01, 0x00, 0x0D, 0x00,
1601 		0x00, 0x00, 0x00, 0x00, 0x00,
1602 		0x00};  	/*Length*/
1603 	unsigned char		AddBinaryReq[33000] = {
1604 		N7110_FRAME_HEADER, 0x0E, 0x7F, 0xFF, 0xFE};
1605 
1606 	if (Ringtone->Format == RING_NOTETONE && Ringtone->Location==255)
1607 	{
1608 		smprintf(s, "Getting ringtone ID\n");
1609 		error=GSM_WaitFor (s, GetIDReq, 14, 0xDB, s->Phone.Data.Priv.N6510.Timeout, ID_SetRingtone);
1610 		if (error != ERR_NONE) return error;
1611 		*maxlength=GSM_EncodeNokiaRTTLRingtone(Ringtone, SetPreviewReq+11, &size);
1612 		SetPreviewReq[0]  = Priv->RingtoneID;
1613 		SetPreviewReq[10] = size;
1614 		smprintf(s, "Setting ringtone\n");
1615 		error = s->Protocol.Functions->WriteMessage(s, SetPreviewReq, size+11, 0x00);
1616 		if (error!=ERR_NONE) return error;
1617 		sleep(1);
1618 		/* We have to make something (not important, what) now */
1619 		/* no answer from phone*/
1620 		return s->Phone.Functions->GetNetworkInfo(s,&NetInfo);
1621 	}
1622 	if (Ringtone->Format == RING_NOKIABINARY) {
1623 		AddBinaryReq[7] = UnicodeLength(Ringtone->Name);
1624 		CopyUnicodeString(AddBinaryReq+8,Ringtone->Name);
1625 		current = 8 + UnicodeLength(Ringtone->Name)*2;
1626 		AddBinaryReq[current++] = Ringtone->NokiaBinary.Length/256 + 1;
1627 		AddBinaryReq[current++] = Ringtone->NokiaBinary.Length%256 + 1;
1628 		AddBinaryReq[current++] = 0x00;
1629 		memcpy(AddBinaryReq+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length);
1630 		current += Ringtone->NokiaBinary.Length;
1631 		smprintf(s, "Adding binary ringtone\n");
1632 		return GSM_WaitFor (s, AddBinaryReq, current, 0x1F, s->Phone.Data.Priv.N6510.Timeout, ID_SetRingtone);
1633 	}
1634 	if (Ringtone->Format == RING_MIDI) {
1635 		AddBinaryReq[7] = UnicodeLength(Ringtone->Name);
1636 		CopyUnicodeString(AddBinaryReq+8,Ringtone->Name);
1637 		current = 8 + UnicodeLength(Ringtone->Name)*2;
1638 		AddBinaryReq[current++] = Ringtone->NokiaBinary.Length/256;
1639 		AddBinaryReq[current++] = Ringtone->NokiaBinary.Length%256;
1640 		memcpy(AddBinaryReq+current,Ringtone->NokiaBinary.Frame,Ringtone->NokiaBinary.Length);
1641 		current += Ringtone->NokiaBinary.Length;
1642 		AddBinaryReq[current++] = 0x00;
1643 		AddBinaryReq[current++] = 0x00;
1644 		smprintf(s, "Adding binary or MIDI ringtone\n");
1645 		return GSM_WaitFor (s, AddBinaryReq, current, 0x1F, s->Phone.Data.Priv.N6510.Timeout, ID_SetRingtone);
1646 	}
1647 	return ERR_NOTSUPPORTED;
1648 }
1649 
N6510_ReplyDeleteRingtones(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)1650 static GSM_Error N6510_ReplyDeleteRingtones(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
1651 {
1652 	smprintf(s, "Ringtones deleted\n");
1653 	return ERR_NONE;
1654 }
1655 
N6510_DeleteUserRingtones(GSM_StateMachine * s)1656 static GSM_Error N6510_DeleteUserRingtones(GSM_StateMachine *s)
1657 {
1658 	unsigned char DelAllRingtoneReq[] = {N7110_FRAME_HEADER, 0x10, 0x7F, 0xFE};
1659 
1660 	smprintf(s, "Deleting all user ringtones\n");
1661 	return GSM_WaitFor (s, DelAllRingtoneReq, 6, 0x1F, s->Phone.Data.Priv.N6510.Timeout, ID_SetRingtone);
1662 }
1663 
N6510_ReplyPressKey(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)1664 static GSM_Error N6510_ReplyPressKey(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
1665 {
1666 	if (msg->Buffer[3] == 0x33) {
1667 		smprintf(s, "Key auto released\n");
1668 	} else if (msg->Buffer[3] == 0x12) {
1669 		smprintf(s, "Key pressed\n");
1670 	} else {
1671 		return ERR_UNKNOWN;
1672 	}
1673 	return ERR_NONE;
1674 }
1675 
N6510_PressKey(GSM_StateMachine * s,GSM_KeyCode Key,gboolean Press)1676 static GSM_Error N6510_PressKey(GSM_StateMachine *s, GSM_KeyCode Key, gboolean Press)
1677 {
1678 	unsigned char req[] = {N6110_FRAME_HEADER, 0x11, 0x00, 0x01, 0x00, 0x00,
1679 			       0x00,		/* Event */
1680 			       0x01};		/* Number of presses */
1681 
1682 	if (Key != GSM_KEY_GREEN) {
1683 		smprintf(s, "Mapping for key code %d missing!\n", Key);
1684 		return ERR_NOTIMPLEMENTED;
1685 	}
1686 
1687 	req[7] = Key;
1688 	if (Press) {
1689 		req[8] = NOKIA_PRESSPHONEKEY;
1690 		s->Phone.Data.PressKey = TRUE;
1691 		smprintf(s, "Pressing key\n");
1692 	} else {
1693 		req[8] = NOKIA_RELEASEPHONEKEY;
1694 		s->Phone.Data.PressKey = FALSE;
1695 		smprintf(s, "Releasing key\n");
1696 	}
1697 	return GSM_WaitFor (s, req, 10, 0x0c, s->Phone.Data.Priv.N6510.Timeout, ID_PressKey);
1698 }
1699 
N6510_EnableConnectionFunctions(GSM_StateMachine * s,N6510_Connection_Settings Type)1700 static GSM_Error N6510_EnableConnectionFunctions(GSM_StateMachine *s, N6510_Connection_Settings Type)
1701 {
1702 	GSM_Error	error;
1703 	unsigned char 	req2[] = {N6110_FRAME_HEADER, 0x00, 0x01};
1704 	unsigned char 	req3[] = {N6110_FRAME_HEADER, 0x00, 0x03};
1705 	unsigned char 	req4[] = {N6110_FRAME_HEADER, 0x00, 0x04};
1706 
1707 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_6230iWAP)) return ERR_NOTSUPPORTED;
1708 
1709 	if (Type == N6510_MMS_SETTINGS    && GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOMMS)) return ERR_NOTSUPPORTED;
1710 	if (Type == N6510_CHAT_SETTINGS   && !GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_CHAT)) return ERR_NOTSUPPORTED;
1711 	if (Type == N6510_SYNCML_SETTINGS && !GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SYNCML)) return ERR_NOTSUPPORTED;
1712 
1713 	error=DCT3DCT4_DisableConnectionFunctions(s);
1714 	if (error!=ERR_NONE) return error;
1715 
1716 	switch (Type) {
1717 	case N6510_WAP_SETTINGS:
1718 		return DCT3DCT4_EnableWAPFunctions(s);
1719 	case N6510_MMS_SETTINGS:
1720 		smprintf(s, "Enabling MMS\n");
1721 		return GSM_WaitFor (s, req2, 5, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_EnableConnectFunc);
1722 	case N6510_SYNCML_SETTINGS:
1723 		smprintf(s, "Enabling SyncML\n");
1724 		return GSM_WaitFor (s, req3, 5, 0x3f, 5, ID_EnableConnectFunc);
1725 	case N6510_CHAT_SETTINGS:
1726 		smprintf(s, "Enabling Chat\n");
1727 		return GSM_WaitFor (s, req4, 5, 0x3f, 5, ID_EnableConnectFunc);
1728 	default:
1729 		return ERR_UNKNOWN;
1730 	}
1731 }
1732 
N6510_ReplyGetConnectionSettings(GSM_Protocol_Message * msg,GSM_StateMachine * s)1733 static GSM_Error N6510_ReplyGetConnectionSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
1734 {
1735 	GSM_Phone_N6510Data	*Priv = &s->Phone.Data.Priv.N6510;
1736 	int 			tmp,num=0,i;
1737 	GSM_Phone_Data		*Data = &s->Phone.Data;
1738 	unsigned char		buff[2000];
1739 
1740 	switch(msg->Buffer[3]) {
1741 	case 0x16:
1742 		smprintf(s, "Connection settings received OK\n");
1743 
1744 		Data->WAPSettings->Number = Priv->BearerNumber;
1745 
1746 		Data->WAPSettings->Proxy[0]   = 0x00;
1747 		Data->WAPSettings->Proxy[1]   = 0x00;
1748 		Data->WAPSettings->ProxyPort  = 8080;
1749 
1750 		Data->WAPSettings->Proxy2[0]  = 0x00;
1751 		Data->WAPSettings->Proxy2[1]  = 0x00;
1752 		Data->WAPSettings->Proxy2Port = 8080;
1753 
1754 		tmp = 4;
1755 
1756 		NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].Title,TRUE);
1757 		CopyUnicodeString(Data->WAPSettings->Settings[1].Title,Data->WAPSettings->Settings[0].Title);
1758 		smprintf(s, "Title: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Title));
1759 
1760 		NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].HomePage,TRUE);
1761 		CopyUnicodeString(Data->WAPSettings->Settings[1].HomePage,Data->WAPSettings->Settings[0].HomePage);
1762 		smprintf(s, "Homepage: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].HomePage));
1763 
1764 #ifdef DEBUG
1765 		smprintf(s, "Connection type: ");
1766 		switch (msg->Buffer[tmp]) {
1767 			case 0x00: smprintf(s, "temporary\n");  break;
1768 			case 0x01: smprintf(s, "continuous\n"); break;
1769 			default:   smprintf(s, "unknown\n");
1770 		}
1771 		smprintf(s, "Connection security: ");
1772 		switch (msg->Buffer[tmp+1]) {
1773 			case 0x00: smprintf(s, "off\n");	break;
1774 			case 0x01: smprintf(s, "on\n");		break;
1775 			default:   smprintf(s, "unknown\n");
1776 		}
1777 		smprintf(s, "Bearer: ");
1778 		switch (msg->Buffer[tmp+2]) {
1779 			case 0x01: smprintf(s, "GSM data\n");	break;
1780 			case 0x03: smprintf(s, "GPRS\n");	break;
1781 			default:   smprintf(s, "unknown\n");
1782 		}
1783 		if (msg->Buffer[tmp+3] == 0x01) smprintf(s, "locked\n");
1784 #endif
1785 		Data->WAPSettings->Settings[0].IsContinuous = FALSE;
1786 		if (msg->Buffer[tmp] == 0x01) Data->WAPSettings->Settings[0].IsContinuous = TRUE;
1787 		Data->WAPSettings->Settings[1].IsContinuous = Data->WAPSettings->Settings[0].IsContinuous;
1788 
1789 		Data->WAPSettings->Settings[0].IsSecurity = FALSE;
1790 		if (msg->Buffer[tmp+1] == 0x01) Data->WAPSettings->Settings[0].IsSecurity = TRUE;
1791 		Data->WAPSettings->Settings[1].IsSecurity = Data->WAPSettings->Settings[0].IsSecurity;
1792 
1793 		Data->WAPSettings->ActiveBearer = WAPSETTINGS_BEARER_DATA;
1794 		if (msg->Buffer[tmp+2] == 0x03) Data->WAPSettings->ActiveBearer = WAPSETTINGS_BEARER_GPRS;
1795 
1796 		Data->WAPSettings->ReadOnly = FALSE;
1797 		if (msg->Buffer[tmp+3] == 0x01) Data->WAPSettings->ReadOnly = TRUE;
1798 
1799 		tmp+=3;
1800 
1801 		if (Priv->BearerNumber == 2) {
1802 			/* Here starts settings for data bearer */
1803 			Data->WAPSettings->Settings[0].Bearer = WAPSETTINGS_BEARER_DATA;
1804 			while ((msg->Buffer[tmp] != 0x01) || (msg->Buffer[tmp + 1] != 0x00)) tmp++;
1805 			tmp += 4;
1806 
1807 #ifdef DEBUG
1808 			smprintf(s, "Authentication type: ");
1809 			switch (msg->Buffer[tmp]) {
1810 				case 0x00: smprintf(s, "normal\n");	break;
1811 				case 0x01: smprintf(s, "secure\n");	break;
1812 				default:   smprintf(s, "unknown\n");	break;
1813 			}
1814 			smprintf(s, "Data call type: ");
1815 			switch (msg->Buffer[tmp+1]) {
1816 				case 0x00: smprintf(s, "analogue\n");	break;
1817 				case 0x01: smprintf(s, "ISDN\n");	break;
1818 				default:   smprintf(s, "unknown\n");	break;
1819 			}
1820 			smprintf(s, "Data call speed: ");
1821 			switch (msg->Buffer[tmp+2]) {
1822 				case 0x00: smprintf(s, "automatic\n"); 	break;
1823 				case 0x01: smprintf(s, "9600\n");	break;
1824 				case 0x02: smprintf(s, "14400\n");	break;
1825 				default:   smprintf(s, "unknown\n");	break;
1826 			}
1827 			smprintf(s, "Login Type: ");
1828 			switch (msg->Buffer[tmp+4]) {
1829 				case 0x00: smprintf(s, "manual\n");	break;
1830 				case 0x01: smprintf(s, "automatic\n");	break;
1831 				default:   smprintf(s, "unknown\n");	break;
1832 			}
1833 #endif
1834 			Data->WAPSettings->Settings[0].IsNormalAuthentication=TRUE;
1835 			if (msg->Buffer[tmp]==0x01) Data->WAPSettings->Settings[0].IsNormalAuthentication=FALSE;
1836 
1837 			Data->WAPSettings->Settings[0].IsISDNCall=FALSE;
1838 			if (msg->Buffer[tmp+1]==0x01) Data->WAPSettings->Settings[0].IsISDNCall=TRUE;
1839 
1840 			switch (msg->Buffer[tmp+2]) {
1841 				case 0x00: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_AUTO;  break;
1842 				case 0x01: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_9600;	 break;
1843 				case 0x02: Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_14400; break;
1844 				default:
1845 					smprintf(s, "Unknown speed settings: 0x%0x\n", msg->Buffer[tmp+2]);
1846 					Data->WAPSettings->Settings[0].Speed=WAPSETTINGS_SPEED_AUTO;
1847 					break;
1848 			}
1849 
1850 			Data->WAPSettings->Settings[0].ManualLogin=FALSE;
1851 			if (msg->Buffer[tmp+4]==0x00) Data->WAPSettings->Settings[0].ManualLogin = TRUE;
1852 
1853 			tmp+=5;
1854 
1855 			NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].IPAddress,FALSE);
1856 			smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].IPAddress));
1857 
1858 			NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].DialUp,TRUE);
1859 			smprintf(s, "Dial-up number: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].DialUp));
1860 
1861 			NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].User,TRUE);
1862 			smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].User));
1863 
1864 			NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[0].Password,TRUE);
1865 			smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[0].Password));
1866 
1867 			num = 1;
1868 		} else {
1869 			num = 0;
1870 		}
1871 
1872 		/* Here starts settings for gprs bearer */
1873 		Data->WAPSettings->Settings[num].Bearer = WAPSETTINGS_BEARER_GPRS;
1874 		while (msg->Buffer[tmp] != 0x03) tmp++;
1875 		tmp += 4;
1876 
1877 #ifdef DEBUG
1878 		smprintf(s, "Authentication type: ");
1879 		switch (msg->Buffer[tmp]) {
1880 			case 0x00: smprintf(s, "normal\n");	break;
1881 			case 0x01: smprintf(s, "secure\n");	break;
1882 			default:   smprintf(s, "unknown\n");	break;
1883 		}
1884 		smprintf(s, "GPRS connection: ");
1885 		switch (msg->Buffer[tmp+1]) {
1886 			case 0x00: smprintf(s, "ALWAYS online\n"); break;
1887 			case 0x01: smprintf(s, "when needed\n");   break;
1888 			default:   smprintf(s, "unknown\n"); 	   break;
1889 		}
1890 		smprintf(s, "Login Type: ");
1891 		switch (msg->Buffer[tmp+2]) {
1892 			case 0x00: smprintf(s, "manual\n");	break;
1893 			case 0x01: smprintf(s, "automatic\n");	break;
1894 			default:   smprintf(s, "unknown\n");	break;
1895 		}
1896 #endif
1897 		Data->WAPSettings->Settings[num].IsNormalAuthentication=TRUE;
1898 		if (msg->Buffer[tmp]==0x01) Data->WAPSettings->Settings[num].IsNormalAuthentication=FALSE;
1899 
1900 		Data->WAPSettings->Settings[num].IsISDNCall=FALSE;
1901 		Data->WAPSettings->Settings[num].Speed = WAPSETTINGS_SPEED_AUTO;
1902 
1903 		Data->WAPSettings->Settings[num].IsContinuous = TRUE;
1904 		if (msg->Buffer[tmp+1] == 0x01) Data->WAPSettings->Settings[num].IsContinuous = FALSE;
1905 
1906 		Data->WAPSettings->Settings[num].ManualLogin=FALSE;
1907 		if (msg->Buffer[tmp+2]==0x00) Data->WAPSettings->Settings[num].ManualLogin = TRUE;
1908 
1909 		tmp+=3;
1910 
1911 		NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[num].DialUp,FALSE);
1912 		smprintf(s, "Access point: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].DialUp));
1913 
1914 		NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[num].IPAddress,TRUE);
1915 		smprintf(s, "IP address: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].IPAddress));
1916 
1917 		NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[num].User,TRUE);
1918 		smprintf(s, "User name: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].User));
1919 
1920 		NOKIA_GetUnicodeString(s, &tmp, msg->Buffer, Data->WAPSettings->Settings[num].Password,TRUE);
1921 		smprintf(s, "Password: \"%s\"\n",DecodeUnicodeString(Data->WAPSettings->Settings[num].Password));
1922 
1923 		if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) {
1924 			if (msg->Buffer[tmp] == 0x00 && msg->Buffer[tmp+1] == 0x00) tmp = tmp+2;
1925 
1926 			memcpy(buff,msg->Buffer+tmp+10,msg->Buffer[tmp+4]);
1927 			buff[msg->Buffer[tmp+4]] = 0x00;
1928 			smprintf(s, "Proxy 1: \"%s\", port %i\n",buff,msg->Buffer[tmp+6]*256+msg->Buffer[tmp+7]);
1929 			EncodeUnicode(Data->WAPSettings->Proxy,buff,strlen(buff));
1930 			Data->WAPSettings->ProxyPort = msg->Buffer[tmp+6]*256+msg->Buffer[tmp+7];
1931 
1932 			memcpy(buff,msg->Buffer+tmp+10+msg->Buffer[tmp+4],msg->Buffer[tmp+5]);
1933 			buff[msg->Buffer[tmp+5]] = 0x00;
1934 			smprintf(s, "Proxy 2: \"%s\", port %i\n",buff,msg->Buffer[tmp+8]*256+msg->Buffer[tmp+9]);
1935 			EncodeUnicode(Data->WAPSettings->Proxy2,buff,strlen(buff));
1936 			Data->WAPSettings->Proxy2Port = msg->Buffer[tmp+8]*256+msg->Buffer[tmp+9];
1937 
1938 			tmp = tmp + msg->Buffer[tmp+3] + 19;
1939 
1940 			for (i=0;i<4;i++) {
1941 #ifdef DEBUG
1942 				smprintf(s, "Proxy data %i\n",i+1);
1943 				if (msg->Buffer[tmp+2]!=0) memcpy(buff,msg->Buffer+tmp+9,msg->Buffer[tmp+2]*2);
1944 				buff[msg->Buffer[tmp+2]*2]  =0;
1945 				buff[msg->Buffer[tmp+2]*2+1]=0;
1946 				smprintf(s, "IP: \"%s\"",DecodeUnicodeString(buff));
1947 				smprintf(s, ", port %i\n",msg->Buffer[tmp+3]*256+msg->Buffer[tmp+4]);
1948 #endif
1949 				tmp = tmp + msg->Buffer[tmp];
1950 			}
1951 
1952 #ifdef DEBUG
1953 			smprintf(s, "%02x %02x\n",msg->Buffer[tmp],msg->Buffer[tmp+1]);
1954 			smprintf(s, "Port %i\n",msg->Buffer[tmp+3]*256+msg->Buffer[tmp+4]);
1955 			tmp = tmp + msg->Buffer[tmp];
1956 #endif
1957 		}
1958 
1959 		return ERR_NONE;
1960 	case 0xf0:
1961 		/*
1962 		 * Don't know exactly what 0x0f means, but the message is too short
1963 		 * to contain information:
1964 		 *
1965 		 * 01 |58X|00 |F0 |01 |15 |00 |00 |00 |00
1966 		 */
1967 		smprintf(s, "Connection settings receiving error, assuming empty\n");
1968 		return ERR_EMPTY;
1969 	case 0x11:
1970 	case 0x17:
1971 		smprintf(s, "Connection settings receiving error\n");
1972 		switch (msg->Buffer[4]) {
1973 		case 0x01:
1974 			smprintf(s, "Security error. Inside phone settings menu\n");
1975 			return ERR_INSIDEPHONEMENU;
1976 		case 0x02:
1977 		case 0x03: /* Guess */
1978 			smprintf(s, "Invalid or empty\n");
1979 			return ERR_INVALIDLOCATION;
1980 		default:
1981 			smprintf(s, "ERROR: unknown %i\n",msg->Buffer[4]);
1982 			return ERR_UNKNOWNRESPONSE;
1983 		}
1984 	}
1985 	return ERR_UNKNOWNRESPONSE;
1986 }
1987 
N6510_GetConnectionSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings,N6510_Connection_Settings Type)1988 static GSM_Error N6510_GetConnectionSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings, N6510_Connection_Settings Type)
1989 {
1990 	GSM_Phone_N6510Data	*Priv = &s->Phone.Data.Priv.N6510;
1991 	GSM_Error 		error;
1992 	unsigned char 		req[] = {N6110_FRAME_HEADER, 0x15,
1993 				 	 0x00};		/* Location */
1994 
1995 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) return ERR_NOTSUPPORTED;
1996 	if (!strcmp(s->Phone.Data.ModelInfo->model,"6020")) return ERR_NOTSUPPORTED;
1997 
1998 	error = N6510_EnableConnectionFunctions(s, Type);
1999 	if (error!=ERR_NONE) return error;
2000 
2001 	req[4] 			  = settings->Location-1;
2002 	s->Phone.Data.WAPSettings = settings;
2003 
2004 	switch (Type) {
2005 	case N6510_MMS_SETTINGS:
2006 		smprintf(s, "Getting MMS settings\n");
2007 		Priv->BearerNumber = 1;
2008 		break;
2009 	case N6510_WAP_SETTINGS:
2010 		smprintf(s, "Getting WAP settings\n");
2011 		Priv->BearerNumber = 2;
2012 		break;
2013 	case N6510_SYNCML_SETTINGS:
2014 		smprintf(s, "Getting SyncML settings\n");
2015 		Priv->BearerNumber = 2;
2016 		break;
2017 	case N6510_CHAT_SETTINGS:
2018 		smprintf(s, "Getting Chat settings\n");
2019 		Priv->BearerNumber = 1;
2020 		break;
2021 	}
2022 
2023 	error=GSM_WaitFor (s, req, 5, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_GetConnectSet);
2024 	if (error != ERR_NONE) {
2025 		if (error == ERR_INVALIDLOCATION || error == ERR_INSIDEPHONEMENU) {
2026 			DCT3DCT4_DisableConnectionFunctions(s);
2027 		}
2028 		return error;
2029 	}
2030 
2031 	error=DCT3DCT4_GetActiveConnectSet(s);
2032 	if (error != ERR_NONE) return error;
2033 
2034 	return DCT3DCT4_DisableConnectionFunctions(s);
2035 }
2036 
N6510_GetWAPSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings)2037 static GSM_Error N6510_GetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2038 {
2039 	return N6510_GetConnectionSettings(s, settings, N6510_WAP_SETTINGS);
2040 }
2041 
N6510_GetMMSSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings)2042 static GSM_Error N6510_GetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2043 {
2044 	return N6510_GetConnectionSettings(s, settings, N6510_MMS_SETTINGS);
2045 }
2046 
N6510_ReplyGetSyncMLSettings(GSM_Protocol_Message * msg,GSM_StateMachine * s)2047 static GSM_Error N6510_ReplyGetSyncMLSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2048 {
2049 	GSM_SyncMLSettings *Sett = s->Phone.Data.SyncMLSettings;
2050 
2051 	smprintf(s, "SyncML settings received OK\n");
2052 	CopyUnicodeString(Sett->User,msg->Buffer+18);
2053 	CopyUnicodeString(Sett->Password,msg->Buffer+86);
2054 	CopyUnicodeString(Sett->PhonebookDataBase,msg->Buffer+130);
2055 	CopyUnicodeString(Sett->CalendarDataBase,msg->Buffer+234);
2056 	CopyUnicodeString(Sett->Server,msg->Buffer+338);
2057 
2058 	Sett->SyncPhonebook = FALSE;
2059 	Sett->SyncCalendar  = FALSE;
2060 	if ((msg->Buffer[598] & 0x02)==0x02) Sett->SyncCalendar = TRUE;
2061 	if ((msg->Buffer[598] & 0x01)==0x01) Sett->SyncPhonebook = TRUE;
2062 
2063 	return ERR_NONE;
2064 }
2065 
N6510_ReplyGetSyncMLName(GSM_Protocol_Message * msg,GSM_StateMachine * s)2066 static GSM_Error N6510_ReplyGetSyncMLName(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2067 {
2068 	GSM_SyncMLSettings *Sett = s->Phone.Data.SyncMLSettings;
2069 
2070 	smprintf(s, "SyncML names received OK\n");
2071 
2072 	CopyUnicodeString(Sett->Name,msg->Buffer+18);
2073 
2074 	return ERR_NONE;
2075 }
2076 
N6510_GetSyncMLSettings(GSM_StateMachine * s,GSM_SyncMLSettings * settings)2077 static GSM_Error N6510_GetSyncMLSettings(GSM_StateMachine *s, GSM_SyncMLSettings *settings)
2078 {
2079 	GSM_Error 	error;
2080 /* 	unsigned char 	NameReq[] = {N6110_FRAME_HEADER, 0x05, */
2081 /* 				 0x00, 0x00, 0x00, 0x31, 0x00, */
2082 /* 				 0x06, 0x00, 0x00, 0x00, 0xDE, 0x00, 0x00}; */
2083 /* 	unsigned char 	GetActive[] = {N6110_FRAME_HEADER, 0x05, */
2084 /* 				 0x00, 0x00, 0x00, 0x31, 0x00, */
2085 /* 				 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; */
2086 	unsigned char 	req[] = {N6110_FRAME_HEADER, 0x05,
2087 				 0x00, 0x00, 0x00, 0x31, 0x00,
2088 				 0x01, /* location */
2089 				 0x00, 0x00, 0x02, 0x46, 0x00, 0x00};
2090 
2091 	settings->Connection.Location = settings->Location;
2092 	error = N6510_GetConnectionSettings(s, &settings->Connection, N6510_SYNCML_SETTINGS);
2093 	if (error != ERR_NONE) return error;
2094 
2095 	settings->Active = settings->Connection.Active;
2096 
2097 	settings->Name[0] = 0;
2098 	settings->Name[1] = 0;
2099 	s->Phone.Data.SyncMLSettings  = settings;
2100 
2101 /* 	smprintf(s, "Getting SyncML settings name\n"); */
2102 /* 	error = GSM_WaitFor (s, NameReq, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_GetSyncMLName); */
2103 /* 	if (error != ERR_NONE) return error; */
2104 
2105 	req[9] = settings->Location - 1;
2106 	smprintf(s, "Getting additional SyncML settings\n");
2107 	return GSM_WaitFor (s, req, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_GetSyncMLSettings);
2108 }
2109 
N6510_ReplyGetChatSettings(GSM_Protocol_Message * msg,GSM_StateMachine * s)2110 static GSM_Error N6510_ReplyGetChatSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2111 {
2112 	GSM_ChatSettings 	*Sett = s->Phone.Data.ChatSettings;
2113 	int			i;
2114 
2115 	Sett->Name[0] 	  = 0;
2116 	Sett->Name[1] 	  = 0;
2117 	Sett->HomePage[0] = 0;
2118 	Sett->HomePage[1] = 0;
2119 	Sett->User[0] 	  = 0;
2120 	Sett->User[1] 	  = 0;
2121 	Sett->Password[0] = 0;
2122 	Sett->Password[1] = 0;
2123 
2124 	switch(msg->Buffer[3]) {
2125 	case 0x3B:
2126 		smprintf(s, "Chat settings received OK\n");
2127 		memcpy(Sett->Name,msg->Buffer+20,msg->Buffer[12]*2);
2128 		Sett->Name[msg->Buffer[12]*2] 	   = 0;
2129 		Sett->Name[msg->Buffer[12]*2+1] 	   = 0;
2130 		memcpy(Sett->HomePage,msg->Buffer+20+msg->Buffer[12]*2,msg->Buffer[15]*2);
2131 		Sett->HomePage[msg->Buffer[15]*2]   = 0;
2132 		Sett->HomePage[msg->Buffer[15]*2+1] = 0;
2133 		i = msg->Buffer[12]*2 + msg->Buffer[15]*2 + 29;
2134 		memcpy(Sett->User,msg->Buffer+i+3,msg->Buffer[i]*2);
2135 		Sett->User[msg->Buffer[i]*2]   = 0;
2136 		Sett->User[msg->Buffer[i]*2+1] = 0;
2137 		memcpy(Sett->Password,msg->Buffer+i+3+msg->Buffer[i]*2,msg->Buffer[i+1]*2);
2138 		Sett->Password[msg->Buffer[i+1]*2]   = 0;
2139 		Sett->Password[msg->Buffer[i+1]*2+1] = 0;
2140 		return ERR_NONE;
2141 	case 0x3C:
2142 		smprintf(s, "Empty chat settings received\n");
2143 		return ERR_NONE;
2144 	}
2145 	return ERR_UNKNOWNRESPONSE;
2146 }
2147 
N6510_GetChatSettings(GSM_StateMachine * s,GSM_ChatSettings * settings)2148 static GSM_Error N6510_GetChatSettings(GSM_StateMachine *s, GSM_ChatSettings *settings)
2149 {
2150 	GSM_Error 	error;
2151 	unsigned char 	req[] = {N6110_FRAME_HEADER, 0x3a,
2152 				 0x09,			/*  location */
2153 				 0x01, 0x0e};
2154 
2155 	settings->Connection.Location = settings->Location;
2156 	error = N6510_GetConnectionSettings(s, &settings->Connection, N6510_CHAT_SETTINGS);
2157 	if (error != ERR_NONE) return error;
2158 
2159 	settings->Active = settings->Connection.Active;
2160 
2161 	s->Phone.Data.ChatSettings  = settings;
2162 	req[4] 			    = settings->Location - 1;
2163 	smprintf(s, "Getting additional Chat settings\n");
2164 	return GSM_WaitFor (s, req, 7, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_GetChatSettings);
2165 }
2166 
N6510_ReplySetConnectionSettings(GSM_Protocol_Message * msg,GSM_StateMachine * s)2167 static GSM_Error N6510_ReplySetConnectionSettings(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2168 {
2169 	switch (msg->Buffer[3]) {
2170 	case 0x19:
2171 		smprintf(s, "Connection settings cleaned\n");
2172 		return ERR_NONE;
2173 	case 0x1a:
2174 		smprintf(s, "Connection settings setting status\n");
2175 		switch (msg->Buffer[4]) {
2176 		case 0x01:
2177 			smprintf(s, "Security error. Inside phone settings menu\n");
2178 			return ERR_INSIDEPHONEMENU;
2179 		case 0x03:
2180 			smprintf(s, "Invalid location\n");
2181 			return ERR_INVALIDLOCATION;
2182 		case 0x05:
2183 			smprintf(s, "Written OK\n");
2184 			return ERR_NONE;
2185 		default:
2186 			smprintf(s, "ERROR: unknown %i\n",msg->Buffer[4]);
2187 			return ERR_UNKNOWNRESPONSE;
2188 		}
2189 	case 0x28:
2190 	case 0x2B:
2191 		smprintf(s, "Set OK\n");
2192 		return ERR_NONE;
2193 	}
2194 	return ERR_UNKNOWNRESPONSE;
2195 }
2196 
N6510_SetConnectionSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings,N6510_Connection_Settings Type)2197 static GSM_Error N6510_SetConnectionSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings, N6510_Connection_Settings Type)
2198 {
2199 	GSM_Error 	error;
2200 	int 		i, pad = 0, length, pos = 5, loc1=-1,loc2=-1,port;
2201 	unsigned char	*Proxy;
2202 	unsigned char 	req[2000] = {N6110_FRAME_HEADER, 0x18,
2203 				     0x00};		/* Location */
2204 	unsigned char 	Lock[5] = {N6110_FRAME_HEADER, 0x27,
2205 				   0x00};		/* Location */
2206 	unsigned char 	UnLock[5] = {N6110_FRAME_HEADER, 0x2A,
2207 				   0x00};		/* Location */
2208 
2209 	error = N6510_EnableConnectionFunctions(s, Type);
2210 	if (error!=ERR_NONE) return error;
2211 
2212 	memset(req + pos, 0, 1000 - pos);
2213 
2214 	req[4] = settings->Location-1;
2215 
2216 	for (i=0;i<settings->Number;i++) {
2217 		if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_DATA) loc1=i;
2218 		if (settings->Settings[i].Bearer == WAPSETTINGS_BEARER_GPRS) loc2=i;
2219 	}
2220 
2221 	if (loc1 != -1) {
2222 		/* Name */
2223 		length = UnicodeLength(settings->Settings[loc1].Title);
2224 		if (!(length % 2)) pad = 1;
2225 		pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].Title, FALSE);
2226 
2227 		/* Home */
2228 		length = UnicodeLength(settings->Settings[loc1].HomePage);
2229 		if (((length + pad) % 2)) pad = 2; else pad = 0;
2230 		pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].HomePage, TRUE);
2231 
2232 		if (settings->Settings[loc1].IsContinuous) {
2233 			req[pos] = 0x01;
2234 		}
2235 		pos++;
2236 		if (settings->Settings[loc1].IsSecurity) {
2237 			req[pos] = 0x01;
2238 		}
2239 		pos++;
2240 	} else if (loc2 != -1) {
2241 		/* Name */
2242 		length = UnicodeLength(settings->Settings[loc2].Title);
2243 		if (!(length % 2)) pad = 1;
2244 		pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].Title, FALSE);
2245 
2246 		/* Home */
2247 		length = UnicodeLength(settings->Settings[loc2].HomePage);
2248 		if (((length + pad) % 2)) pad = 2; else pad = 0;
2249 		pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].HomePage, TRUE);
2250 
2251 		if (settings->Settings[loc2].IsContinuous) {
2252 			req[pos] = 0x01;
2253 		}
2254 		pos++;
2255 		if (settings->Settings[loc2].IsSecurity) {
2256 			req[pos] = 0x01;
2257 		}
2258 		pos++;
2259 	} else {
2260 		/* Name */
2261 		length = 0;
2262 		if (!(length % 2)) pad = 1;
2263 		pos ++;
2264 
2265 		/* Home */
2266 		length = 0;
2267 		if (((length + pad) % 2)) pad = 2; else pad = 0;
2268 		pos += 2;
2269 
2270 		pos += 2;
2271 	}
2272 
2273 	if (Type == N6510_MMS_SETTINGS || Type == N6510_CHAT_SETTINGS) {
2274 		req[pos++] = 0x03; /* active bearer: GPRS */
2275 	} else {
2276 		if (settings->ActiveBearer == WAPSETTINGS_BEARER_GPRS && loc2 != -1) {
2277 			req[pos++] = 0x03; /* active bearer: GPRS */
2278 		} else {
2279 			req[pos++] = 0x01; /* active bearer: data set */
2280 		}
2281 	}
2282 
2283 	/* Number of sent bearers */
2284 	if (Type == N6510_MMS_SETTINGS || Type == N6510_CHAT_SETTINGS) {
2285 		req[pos] = 0x01;
2286 	} else {
2287 		req[pos] = 0x02;
2288 	}
2289 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) req[pos] += 2;
2290 	pos++;
2291  	pos += pad;
2292 
2293 	if (Type != N6510_MMS_SETTINGS && Type != N6510_CHAT_SETTINGS) {
2294 		/* GSM data block */
2295 		memcpy(req + pos, "\x01\x00", 2);	pos += 2;
2296 
2297 		if (loc1 != -1) {
2298 			length  = UnicodeLength(settings->Settings[loc1].IPAddress)*2+1;
2299 			length += UnicodeLength(settings->Settings[loc1].DialUp)   *2+2;
2300 			length += UnicodeLength(settings->Settings[loc1].User)     *2+2;
2301 			length += UnicodeLength(settings->Settings[loc1].Password) *2+2;
2302 		} else {
2303 			length = 1 + 2 + 2 + 2;
2304 		}
2305 		length += 11;
2306 		req[pos++] = length / 256;
2307 		req[pos++] = length % 256;
2308 
2309 		if (loc1 != -1) {
2310 			if (!settings->Settings[loc1].IsNormalAuthentication) {
2311 				req[pos]=0x01;
2312 			}
2313 			pos++;
2314 			if (settings->Settings[loc1].IsISDNCall) {
2315 				req[pos]=0x01;
2316 			}
2317 			pos++;
2318 			switch (settings->Settings[loc1].Speed) {
2319 				case WAPSETTINGS_SPEED_AUTO	: 		 break;
2320 				case WAPSETTINGS_SPEED_9600	: req[pos]=0x01; break;
2321 				case WAPSETTINGS_SPEED_14400	: req[pos]=0x02; break;
2322 			}
2323 			pos++;
2324 			req[pos++]=0x01;
2325 			if (!settings->Settings[loc1].ManualLogin) {
2326 				req[pos] = 0x01;
2327 			}pos++;
2328 
2329 			pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].IPAddress, FALSE);
2330 			pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].DialUp, TRUE);
2331 			pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].User, TRUE);
2332 			pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc1].Password, TRUE);
2333 		} else {
2334 			pos += 3;
2335 			req[pos++]=0x01;
2336 			pos += 8;
2337 		}
2338 
2339 		/* Padding */
2340 		pos+=2;
2341 	}
2342 
2343 	/* GPRS block */
2344 	memcpy(req + pos, "\x03\x00", 2);	pos += 2;
2345 
2346 	if (loc2 != -1) {
2347 		length  = UnicodeLength(settings->Settings[loc2].DialUp)   *2+1;
2348 		length += UnicodeLength(settings->Settings[loc2].IPAddress)*2+2;
2349 		length += UnicodeLength(settings->Settings[loc2].User)     *2+2;
2350 		length += UnicodeLength(settings->Settings[loc2].Password) *2+2;
2351 	} else {
2352 		length = 7;
2353 	}
2354 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) length+=2;
2355 	length += 7;
2356 	req[pos++] = length / 256;
2357 	req[pos++] = length % 256;
2358 
2359 	if (loc2 != -1) {
2360 		if (!settings->Settings[loc2].IsNormalAuthentication) {
2361 			req[pos] = 0x01;
2362 		}
2363 		pos++;
2364 		if (!settings->Settings[loc2].IsContinuous) {
2365 			req[pos] = 0x01;
2366 		}
2367 		pos++;
2368 		if (!settings->Settings[loc2].ManualLogin) {
2369 			req[pos] = 0x01;
2370 		}
2371 		pos++;
2372 
2373 		pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].DialUp, FALSE);
2374 		pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].IPAddress, TRUE);
2375 		pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].User, TRUE);
2376 		pos += NOKIA_SetUnicodeString(s, req + pos, settings->Settings[loc2].Password, TRUE);
2377 	} else {
2378 		pos += 10;
2379 	}
2380 
2381 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_WAPMMSPROXY)) {
2382 		req[pos++] = 0x00;
2383 		req[pos++] = 0x00;
2384 
2385 		/* Proxy block */
2386 		req[pos++] = 0x06;
2387 		req[pos++] = 0x01;
2388 		if (UnicodeLength(settings->Proxy)!=0 ||
2389 		    UnicodeLength(settings->Proxy2)!=0) {
2390 			req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+13)/256;
2391 			req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+13)%256;
2392 		} else {
2393 			req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+12)/256;
2394 			req[pos++] = (UnicodeLength(settings->Proxy)+UnicodeLength(settings->Proxy2)+12)%256;
2395 		}
2396 		req[pos++] = UnicodeLength(settings->Proxy);
2397 		req[pos++] = UnicodeLength(settings->Proxy2);
2398 		req[pos++] = settings->ProxyPort/256;
2399 		req[pos++] = settings->ProxyPort%256;
2400 		req[pos++] = settings->Proxy2Port/256;
2401 		req[pos++] = settings->Proxy2Port%256;
2402 		if (UnicodeLength(settings->Proxy)!=0) {
2403 			sprintf(req+pos,"%s",DecodeUnicodeString(settings->Proxy));
2404 			pos+=UnicodeLength(settings->Proxy);
2405 		}
2406 		if (UnicodeLength(settings->Proxy2)!=0) {
2407 			sprintf(req+pos,"%s",DecodeUnicodeString(settings->Proxy2));
2408 			pos+=UnicodeLength(settings->Proxy2);
2409 		}
2410 		if (UnicodeLength(settings->Proxy)!=0 ||
2411 		    UnicodeLength(settings->Proxy2)!=0) {
2412 			req[pos++] = 0x00;
2413 		}
2414 		req[pos++] = 0x00; req[pos++] = 0x00;
2415 		req[pos++] = 0x07; /* unknown */
2416 		req[pos++] = 0x00; req[pos++] = 0x00;
2417 		req[pos++] = 0x80; /* unknown */
2418 		req[pos++] = 0x01; /* unknown */
2419 		req[pos++] = 0x05; /* unknown */
2420 		req[pos++] = 0x00; req[pos++] = 0x00;
2421 
2422 		/* Proxy data blocks */
2423 		for (i=0;i<4;i++) {
2424 			port  = 8080;
2425 			Proxy = NULL;
2426 			if (i==0) {
2427 				port  = settings->ProxyPort;
2428 				Proxy = settings->Proxy;
2429 			} else if (i==1) {
2430 				port  = settings->Proxy2Port;
2431 				Proxy = settings->Proxy2;
2432 			}
2433 			req[pos++] = 0x08; req[pos++] = 0x00;
2434 			if (Proxy != NULL && UnicodeLength(Proxy)!=0) {
2435 				if (UnicodeLength(Proxy)%2 != 0) {
2436 					req[pos++] = (12 + (UnicodeLength(Proxy)+1)*2)/256;
2437 					req[pos++] = (12 + (UnicodeLength(Proxy)+1)*2)%256;
2438 				} else {
2439 					req[pos++] = (12 + UnicodeLength(Proxy)*2)/256;
2440 					req[pos++] = (12 + UnicodeLength(Proxy)*2)%256;
2441 				}
2442 			} else {
2443 				req[pos++] = 12/256;
2444 				req[pos++] = 12%256;
2445 			}
2446 			req[pos++] = i+1;
2447 			if (Proxy != NULL) {
2448 				req[pos++] = UnicodeLength(Proxy);
2449 			} else {
2450 				req[pos++] = 0;
2451 			}
2452 			req[pos++] = port/256;
2453 			req[pos++] = port%256;
2454 			req[pos++] = 0x00;
2455 
2456 			req[pos++] = 0x00;
2457 			req[pos++] = 0x01;
2458 
2459 			req[pos++] = 0x00;
2460 			if (Proxy != NULL && UnicodeLength(Proxy)!=0) {
2461 				CopyUnicodeString(req+pos,Proxy);
2462 				pos+=UnicodeLength(Proxy)*2;
2463 				if (UnicodeLength(Proxy)%2 != 0) {
2464 					req[pos++] = 0x00;
2465 					req[pos++] = 0x00;
2466 				}
2467 			}
2468 		}
2469 
2470 		req[pos++] = 0x09; req[pos++] = 0x00; req[pos++] = 0x00;
2471 		req[pos++] = 0x0C; req[pos++] = 0x02; req[pos++] = 0x00;
2472 		req[pos++] = 0x00; req[pos++] = 0x02; req[pos++] = 0x00;
2473 		req[pos++] = 0x00; req[pos++] = 0x00; req[pos++] = 0x00;
2474 	} else {
2475 		/* end of blocks ? */
2476 		memcpy(req + pos, "\x80\x00\x00\x0c", 4);	pos += 4;
2477 	}
2478 
2479 	UnLock[4] = settings->Location-1;
2480 	smprintf(s, "Making Connection settings read-write\n");
2481 	error = GSM_WaitFor (s, UnLock, 5, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_SetConnectSet);
2482 	if (error != ERR_NONE) return error;
2483 
2484 	switch (Type) {
2485 	case N6510_MMS_SETTINGS:
2486 		smprintf(s, "Setting MMS settings\n");
2487 		break;
2488 	case N6510_CHAT_SETTINGS:
2489 		smprintf(s, "Setting Chat settings\n");
2490 		break;
2491 	case N6510_WAP_SETTINGS:
2492 		smprintf(s, "Setting WAP settings\n");
2493 		break;
2494 	case N6510_SYNCML_SETTINGS:
2495 		smprintf(s, "Setting SyncML settings\n");
2496 		break;
2497 	}
2498 	error = GSM_WaitFor (s, req, pos, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_SetConnectSet);
2499 	if (error != ERR_NONE) {
2500 		if (error == ERR_INSIDEPHONEMENU || error == ERR_INVALIDLOCATION) {
2501 			DCT3DCT4_DisableConnectionFunctions(s);
2502 		}
2503 		return error;
2504 	}
2505 
2506 	if (settings->ReadOnly) {
2507 		Lock[4] = settings->Location-1;
2508 		smprintf(s, "Making Connection settings readonly\n");
2509 		error = GSM_WaitFor (s, Lock, 5, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_SetConnectSet);
2510 		if (error != ERR_NONE) return error;
2511 	}
2512 
2513 	error = DCT3DCT4_SetActiveConnectSet(s, settings);
2514 	if (error != ERR_NONE) return error;
2515 
2516 	return DCT3DCT4_DisableConnectionFunctions(s);
2517 }
2518 
N6510_SetWAPSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings)2519 static GSM_Error N6510_SetWAPSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2520 {
2521 	return N6510_SetConnectionSettings(s, settings, N6510_WAP_SETTINGS);
2522 }
2523 
N6510_SetMMSSettings(GSM_StateMachine * s,GSM_MultiWAPSettings * settings)2524 static GSM_Error N6510_SetMMSSettings(GSM_StateMachine *s, GSM_MultiWAPSettings *settings)
2525 {
2526 	return N6510_SetConnectionSettings(s, settings, N6510_MMS_SETTINGS);
2527 }
2528 
N6510_ReplyGetOriginalIMEI(GSM_Protocol_Message * msg,GSM_StateMachine * s)2529 static GSM_Error N6510_ReplyGetOriginalIMEI(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2530 {
2531 	if (msg->Buffer[7] == 0x00) {
2532 		smprintf(s, "No SIM card\n");
2533 		return ERR_NOSIM;
2534 	} else {
2535 		return NOKIA_ReplyGetPhoneString(msg, s);
2536 	}
2537 }
2538 
N6510_GetOriginalIMEI(GSM_StateMachine * s,char * value)2539 static GSM_Error N6510_GetOriginalIMEI(GSM_StateMachine *s, char *value)
2540 {
2541 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) return ERR_NOTSUPPORTED;
2542 
2543 	return NOKIA_GetPhoneString(s,"\x00\x07\x02\x01\x00\x01",6,0x42,value,ID_GetOriginalIMEI,14);
2544 }
2545 
N6510_ReplyGetSMSStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)2546 static GSM_Error N6510_ReplyGetSMSStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2547 {
2548 	GSM_Phone_Data *Data = &s->Phone.Data;
2549 
2550 	switch (msg->Buffer[3]) {
2551 	case 0x09:
2552 		switch (msg->Buffer[4]) {
2553 		case 0x00:
2554 			smprintf(s, "Max. in phone memory   : %i\n",msg->Buffer[10]*256+msg->Buffer[11]);
2555 			smprintf(s, "Used in phone memory   : %i\n",msg->Buffer[12]*256+msg->Buffer[13]);
2556 			smprintf(s, "Unread in phone memory : %i\n",msg->Buffer[14]*256+msg->Buffer[15]);
2557 			smprintf(s, "Max. in SIM            : %i\n",msg->Buffer[22]*256+msg->Buffer[23]);
2558 			smprintf(s, "Used in SIM            : %i\n",msg->Buffer[24]*256+msg->Buffer[25]);
2559 			smprintf(s, "Unread in SIM          : %i\n",msg->Buffer[26]*256+msg->Buffer[27]);
2560 			Data->SMSStatus->PhoneSize	= msg->Buffer[10]*256+msg->Buffer[11];
2561 			Data->SMSStatus->PhoneUsed	= msg->Buffer[12]*256+msg->Buffer[13];
2562 			Data->SMSStatus->PhoneUnRead 	= msg->Buffer[14]*256+msg->Buffer[15];
2563 			Data->SMSStatus->SIMSize	= msg->Buffer[22]*256+msg->Buffer[23];
2564 			Data->SMSStatus->SIMUsed 	= msg->Buffer[24]*256+msg->Buffer[25];
2565 			Data->SMSStatus->SIMUnRead 	= msg->Buffer[26]*256+msg->Buffer[27];
2566 			return ERR_NONE;
2567 		case 0x0f:
2568 			smprintf(s, "No PIN\n");
2569 			return ERR_SECURITYERROR;
2570 		default:
2571 			smprintf(s, "ERROR: unknown SMS status %i\n",msg->Buffer[4]);
2572 			return ERR_UNKNOWNRESPONSE;
2573 		}
2574 	case 0x1a:
2575 		smprintf(s, "Wait a moment. Phone is during power on and busy now\n");
2576 		return ERR_SECURITYERROR;
2577 	case 0xf0:
2578 		/* 01 |00 |00 |F0ð|01 |12 |00 |00 |00 */
2579 		smprintf(s, "Handling of this reply is not known, please help!\n");
2580 		return ERR_NOTIMPLEMENTED;
2581 	}
2582 	return ERR_UNKNOWNRESPONSE;
2583 }
2584 
N6510_GetSMSStatus(GSM_StateMachine * s,GSM_SMSMemoryStatus * status)2585 static GSM_Error N6510_GetSMSStatus(GSM_StateMachine *s, GSM_SMSMemoryStatus *status)
2586 {
2587 	GSM_Error 		error;
2588 	GSM_Phone_N6510Data	*Priv = &s->Phone.Data.Priv.N6510;
2589 	unsigned char req[] = {N6110_FRAME_HEADER, 0x08, 0x00, 0x00};
2590 
2591 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) return ERR_NOTSUPPORTED;
2592 
2593 	s->Phone.Data.SMSStatus=status;
2594 	smprintf(s, "Getting SMS status\n");
2595 	error = GSM_WaitFor (s, req, 6, 0x14, 20, ID_GetSMSStatus);
2596 	if (error != ERR_NONE) return error;
2597 
2598 	/* DCT4 family doesn't show in frame with SMS status info
2599          * about Templates. We get separately info about this SMS folder.
2600 	 */
2601 	error = N6510_GetSMSFolderStatus(s, 0x06);
2602 	if (error != ERR_NONE) return error;
2603 	status->TemplatesUsed = Priv->LastSMSFolder.Number;
2604 
2605 	return error;
2606 }
2607 
N6510_ReplyDeleteSMSMessage(GSM_Protocol_Message * msg,GSM_StateMachine * s)2608 static GSM_Error N6510_ReplyDeleteSMSMessage(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2609 {
2610 	switch (msg->Buffer[3]) {
2611 		case 0x05:
2612 			smprintf(s, "SMS deleted OK\n");
2613 			return ERR_NONE;
2614 		case 0x06:
2615 			switch (msg->Buffer[4]) {
2616 				case 0x02:
2617 					smprintf(s, "Invalid location\n");
2618 					return ERR_INVALIDLOCATION;
2619 				default:
2620 					smprintf(s, "Unknown error: %02x\n",msg->Buffer[4]);
2621 					return ERR_UNKNOWNRESPONSE;
2622 			}
2623 	}
2624 	return ERR_UNKNOWNRESPONSE;
2625 }
2626 
N6510_DeleteSMSMessage(GSM_StateMachine * s,GSM_SMSMessage * sms)2627 static GSM_Error N6510_DeleteSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
2628 {
2629 	unsigned char		folderid;
2630 	unsigned int		location;
2631 	unsigned char 		req[] = {N6110_FRAME_HEADER, 0x04,
2632 					 0x01, 		/* 0x01=SM, 0x02=ME */
2633 					 0x00, 		/* FolderID */
2634 					 0x00, 0x02, 	/* Location */
2635 					 0x0F, 0x55};
2636 
2637 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2638 		if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMS_FILES)) return ERR_NOTSUPPORTED;
2639 	}
2640 
2641 	N6510_GetSMSLocation(s, sms, &folderid, &location);
2642 
2643 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2644 		switch (folderid) {
2645 			case 0x01: req[5] = 0x01; 			 break; /* SIM 		*/
2646 			default	 : req[5] = folderid; req[4] = 0x02; 	 break; /* ME folders	*/
2647 		}
2648 	} else {
2649 		switch (folderid) {
2650 			case 0x01: req[5] = 0x02; 			 break; /* INBOX SIM 	*/
2651 			case 0x02: req[5] = 0x03; 			 break; /* OUTBOX SIM 	*/
2652 			default	 : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders	*/
2653 		}
2654 	}
2655 	req[6]=location / 256;
2656 	req[7]=location % 256;
2657 
2658 	smprintf(s, "Deleting sms\n");
2659 	return GSM_WaitFor (s, req, 10, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_DeleteSMSMessage);
2660 }
2661 
N6510_ReplySendSMSMessage(GSM_Protocol_Message * msg,GSM_StateMachine * s)2662 static GSM_Error N6510_ReplySendSMSMessage(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2663 {
2664 	switch (msg->Buffer[8]) {
2665 	case 0x00:
2666 		smprintf(s, "SMS sent OK, TPMR for sent sms is %d\n",msg->Buffer[10]);
2667 		if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s,0,msg->Buffer[10], s->User.SendSMSStatusUserData);
2668 		return ERR_NONE;
2669 	default:
2670 		smprintf(s, "SMS not sent OK, error code probably %i\n",msg->Buffer[8]);
2671 		if (s->User.SendSMSStatus!=NULL) s->User.SendSMSStatus(s,msg->Buffer[8],msg->Buffer[10], s->User.SendSMSStatusUserData);
2672 		return ERR_NONE;
2673 	}
2674 }
2675 
N6510_SendSMSMessage(GSM_StateMachine * s,GSM_SMSMessage * sms)2676 static GSM_Error N6510_SendSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
2677 {
2678 	int			length = 11;
2679 	GSM_Error		error;
2680 	GSM_SMSMessageLayout 	Layout;
2681 	unsigned char req [300] = {
2682 		N6110_FRAME_HEADER, 0x02, 0x00, 0x00, 0x00, 0x55, 0x55};
2683 
2684 	if (sms->PDU == SMS_Deliver) sms->PDU = SMS_Submit;
2685 	memset(req+9,0x00,sizeof(req) - 9);
2686 	error=N6510_EncodeSMSFrame(s, sms, req + 9, &Layout, &length);
2687 	if (error != ERR_NONE) return error;
2688 
2689 	smprintf(s, "Sending sms\n");
2690 	return s->Protocol.Functions->WriteMessage(s, req, length + 9, 0x02);
2691 }
2692 
N6510_ReplyGetSecurityStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)2693 static GSM_Error N6510_ReplyGetSecurityStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2694 {
2695 	GSM_Phone_Data *Data = &s->Phone.Data;
2696 
2697 	if (msg->Buffer[3] == 0xf0) {
2698 		return ERR_NOTSUPPORTED;
2699 	}
2700 
2701 	smprintf(s, "Security Code status received: ");
2702 	switch (msg->Buffer[4]) {
2703 	case 0x01 : smprintf(s, "waiting for Security Code.\n"); *Data->SecurityStatus = SEC_SecurityCode;	break;
2704 	case 0x07 :
2705 	case 0x02 : smprintf(s, "waiting for PIN.\n");		 *Data->SecurityStatus = SEC_Pin;		break;
2706 	case 0x03 : smprintf(s, "waiting for PUK.\n");		 *Data->SecurityStatus = SEC_Puk;		break;
2707 	case 0x05 : smprintf(s, "PIN ok, SIM ok\n");		 *Data->SecurityStatus = SEC_None;		break;
2708 	case 0x06 : smprintf(s, "No input status\n"); 		 *Data->SecurityStatus = SEC_None;		break;
2709 	case 0x16 : smprintf(s, "No SIM card\n");		 return ERR_NOSIM;
2710 	case 0x1A : smprintf(s, "SIM card rejected!\n");	 *Data->SecurityStatus = SEC_None;		break;
2711 	default   : smprintf(s, "ERROR: unknown %i\n",msg->Buffer[4]);
2712 		    return ERR_UNKNOWNRESPONSE;
2713 	}
2714 	return ERR_NONE;
2715 }
2716 
N6510_GetSecurityStatus(GSM_StateMachine * s,GSM_SecurityCodeType * Status)2717 static GSM_Error N6510_GetSecurityStatus(GSM_StateMachine *s, GSM_SecurityCodeType *Status)
2718 {
2719 	unsigned char req[5] = {N6110_FRAME_HEADER, 0x11, 0x00};
2720 
2721 	s->Phone.Data.SecurityStatus=Status;
2722 	smprintf(s, "Getting security code status\n");
2723 	return GSM_WaitFor (s, req, 5, 0x08, 2, ID_GetSecurityStatus);
2724 }
2725 
N6510_ReplyEnterSecurityCode(GSM_Protocol_Message * msg,GSM_StateMachine * s)2726 static GSM_Error N6510_ReplyEnterSecurityCode(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2727 {
2728 	switch (msg->Buffer[3]) {
2729 	case 0x08:
2730 		smprintf(s, "Security code OK\n");
2731 		return ERR_NONE;
2732 	case 0x09:
2733 		switch (msg->Buffer[4]) {
2734 		case 0x06:
2735 			smprintf(s, "Wrong PIN\n");
2736 			return ERR_SECURITYERROR;
2737 		case 0x09:
2738 			smprintf(s, "Wrong PUK\n");
2739 			return ERR_SECURITYERROR;
2740 		default:
2741 			smprintf(s, "ERROR: unknown security code status %i\n",msg->Buffer[4]);
2742 		}
2743 	}
2744 	return ERR_UNKNOWNRESPONSE;
2745 }
2746 
N6510_EnterSecurityCode(GSM_StateMachine * s,GSM_SecurityCode * Code)2747 static GSM_Error N6510_EnterSecurityCode(GSM_StateMachine *s, GSM_SecurityCode *Code)
2748 {
2749 	int 		len = 0;
2750 	unsigned char 	req[15] = {N6110_FRAME_HEADER, 0x07,
2751 				   0x00};	/* Code type */
2752 
2753 	switch (Code->Type) {
2754 		case SEC_Pin	: req[4] = 0x02; break;
2755 		case SEC_Puk	: req[4] = 0x03; break;/* FIXME */
2756 		default		: return ERR_NOTSUPPORTED;
2757 	}
2758 
2759 	len = strlen(Code->Code);
2760 	memcpy(req+5,Code->Code,len);
2761 	req[5+len]=0x00;
2762 
2763 	smprintf(s, "Entering security code\n");
2764 	return GSM_WaitFor (s, req, 6+len, 0x08, s->Phone.Data.Priv.N6510.Timeout, ID_EnterSecurityCode);
2765 }
2766 
N6510_ReplySaveSMSMessage(GSM_Protocol_Message * msg,GSM_StateMachine * s)2767 static GSM_Error N6510_ReplySaveSMSMessage(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2768 {
2769 	unsigned char 		folder;
2770 	GSM_Phone_Data		*Data = &s->Phone.Data;
2771 
2772 	switch (msg->Buffer[3]) {
2773 	case 0x01:
2774 		switch (msg->Buffer[4]) {
2775 		case 0x00:
2776 			smprintf(s, "Done OK\n");
2777 			break;
2778 		case 0x02:
2779 			smprintf(s, "Incorrect location\n");
2780 			return ERR_INVALIDLOCATION;
2781 		case 0x03:
2782 			smprintf(s, "Memory full (for example no empty space in SIM)\n");
2783 			return ERR_FULL;
2784 		case 0x05:
2785 			smprintf(s, "Incorrect folder\n");
2786 			return ERR_INVALIDLOCATION;
2787 		default:
2788 			smprintf(s, "ERROR: unknown reply on saving message %i\n",msg->Buffer[4]);
2789 			return ERR_UNKNOWNRESPONSE;
2790 		}
2791 
2792 		smprintf(s, "Folder info: %i %i\n",msg->Buffer[5],msg->Buffer[8]);
2793 		Data->SaveSMSMessage->Memory = MEM_ME;
2794 		if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2795 			folder = msg->Buffer[8];
2796 		} else {
2797 			folder = msg->Buffer[8] + 1;
2798 			/* inbox,outbox */
2799 			if (msg->Buffer[8] == 0x02 || msg->Buffer[8] == 0x03) {
2800 				if (msg->Buffer[5] == 0x01) {
2801 					folder = msg->Buffer[8] - 1;
2802 					Data->SaveSMSMessage->Memory = MEM_SM;
2803 				}
2804 			}
2805 		}
2806 		N6510_SetSMSLocation(s, Data->SaveSMSMessage,folder,msg->Buffer[6]*256+msg->Buffer[7]);
2807 		smprintf(s, "Saved in folder %i at location %i\n",folder, msg->Buffer[6]*256+msg->Buffer[7]);
2808 		Data->SaveSMSMessage->Folder = folder;
2809 		return ERR_NONE;
2810 	case 0x17:
2811 		smprintf(s, "SMS name changed\n");
2812 		return ERR_NONE;
2813 	}
2814 	return ERR_UNKNOWNRESPONSE;
2815 }
2816 
N6510_PrivSetSMSMessage(GSM_StateMachine * s,GSM_SMSMessage * sms)2817 static GSM_Error N6510_PrivSetSMSMessage(GSM_StateMachine *s, GSM_SMSMessage *sms)
2818 {
2819 	int			length = 11;
2820 	unsigned int		location;
2821 	unsigned char		folderid, folder;
2822 	GSM_SMSMessageLayout 	Layout;
2823 	GSM_Error		error;
2824 	unsigned char req [300] = {
2825 		N6110_FRAME_HEADER, 0x00,
2826 		0x01,			/* 1 = SIM, 2 = ME 	*/
2827 		0x02,			/* Folder   		*/
2828 		0x00, 0x01,		/* Location 		*/
2829 		0x01};			/* SMS state 		*/
2830 	unsigned char NameReq[200] = {
2831 		N6110_FRAME_HEADER, 0x16,
2832 		0x01,			/* 1 = SIM, 2 = ME 	*/
2833 		0x02,			/* Folder   		*/
2834 		0x00, 0x01};		/* Location 		*/
2835 
2836 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2837 		if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SMS_FILES)) return ERR_NOTSUPPORTED;
2838 	}
2839 
2840 	N6510_GetSMSLocation(s, sms, &folderid, &location);
2841 	if (folderid == 0x99) return ERR_INVALIDLOCATION;
2842 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2843 		switch (folderid) {
2844 			case 0x02: req[4] = 0x02; req[5] = 0x02; break; /* inbox */
2845 			/* sms saved to sent items make problems later during reading */
2846 			/* case 0x03: req[4] = 0x02; req[5] = 0x03; break; //sent items */
2847 			default	 : return ERR_NOTSUPPORTED; /* at least 6111 doesn't support saving to other */
2848 		}
2849 	} else {
2850 		switch (folderid) {
2851 			case 0x01: req[5] = 0x02; 			 break; /* INBOX SIM 	*/
2852 			case 0x02: req[5] = 0x03; 			 break; /* OUTBOX SIM 	*/
2853 			default	 : req[5] = folderid - 1; req[4] = 0x02; break; /* ME folders	*/
2854 		}
2855 	}
2856 	req[6]=location / 256;
2857 	req[7]=location % 256;
2858 
2859 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2860 		switch (sms->PDU) {
2861 		case SMS_Status_Report: /* this is SMS submit with delivery report request */
2862 		case SMS_Submit:
2863 			break;
2864 		case SMS_Deliver:
2865 			/* Sent items */
2866 			if (folderid == 0x03) sms->PDU = SMS_Submit;
2867 			break;
2868 		default:
2869 			return ERR_UNKNOWN;
2870 		}
2871 	} else {
2872 		switch (sms->PDU) {
2873 		case SMS_Status_Report: /* this is SMS submit with delivery report request */
2874 		case SMS_Submit:
2875 			/* Inbox */
2876 			if (folderid == 0x01 || folderid == 0x03) sms->PDU = SMS_Deliver;
2877 			break;
2878 		case SMS_Deliver:
2879 			/* SIM Outbox */
2880 			if (folderid == 0x02) sms->PDU = SMS_Submit;
2881 			break;
2882 		default:
2883 			return ERR_UNKNOWN;
2884 		}
2885 		if (sms->PDU == SMS_Deliver) {
2886 			switch (sms->State) {
2887 				case SMS_Sent	: /* We use GSM_Read, because phone return error */
2888 				case SMS_Read	: req[8] = 0x01; break;
2889 				case SMS_UnSent	: /* We use GSM_UnRead, because phone return error */
2890 				case SMS_UnRead	: req[8] = 0x03; break;
2891 			}
2892 		} else {
2893 			switch (sms->State) {
2894 				case SMS_Sent	: /* We use GSM_Sent, because phone change folder */
2895 				case SMS_Read	: req[8] = 0x05; break;
2896 				case SMS_UnSent	: /* We use GSM_UnSent, because phone change folder */
2897 				case SMS_UnRead	: req[8] = 0x07; break;
2898 			}
2899 		}
2900 	}
2901 	memset(req+9,0x00,sizeof(req) - 9);
2902 	error=N6510_EncodeSMSFrame(s, sms, req + 9, &Layout, &length);
2903 	if (error != ERR_NONE) return error;
2904 
2905 	s->Phone.Data.SaveSMSMessage=sms;
2906 	smprintf(s, "Saving sms\n");
2907 	error=GSM_WaitFor (s, req, length+9, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_SaveSMSMessage);
2908 	if (error != ERR_NONE) return error;
2909 
2910 	/* no adding to SIM SMS */
2911 	if (UnicodeLength(sms->Name)==0 || sms->Folder < 3) return ERR_NONE;
2912 
2913 	folder = sms->Folder;
2914 	sms->Folder = 0;
2915 	N6510_GetSMSLocation(s, sms, &folderid, &location);
2916 
2917 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2918 		switch (folderid) {
2919 			case 0x03: NameReq[4] = 0x02; NameReq[5] = 0x02; break; /* sent items */
2920 			case 0x02: NameReq[4] = 0x02; NameReq[5] = 0x03; break; /* inbox */
2921 			default	 : return ERR_NOTSUPPORTED; /* at least 6111 doesn't support saving to other */
2922 		}
2923 	} else {
2924 		switch (folderid) {
2925 			case 0x01: NameReq[5] = 0x02; 				 break; /* INBOX SIM 	*/
2926 			case 0x02: NameReq[5] = 0x03; 			 	 break; /* OUTBOX SIM 	*/
2927 			default	 : NameReq[5] = folderid - 1; NameReq[4] = 0x02; break; /* ME folders	*/
2928 		}
2929 	}
2930 	NameReq[6]=location / 256;
2931 	NameReq[7]=location % 256;
2932 	length = 8;
2933 	CopyUnicodeString(NameReq+length, sms->Name);
2934 	length = length+UnicodeLength(sms->Name)*2;
2935 	NameReq[length++] = 0;
2936 	NameReq[length++] = 0;
2937 	error=GSM_WaitFor (s, NameReq, length, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_SaveSMSMessage);
2938 	sms->Folder = folder;
2939 	return error;
2940 }
2941 
N6510_SetSMS(GSM_StateMachine * s,GSM_SMSMessage * sms)2942 static GSM_Error N6510_SetSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2943 {
2944 	unsigned int		location;
2945 	unsigned char		folderid;
2946 
2947 	N6510_GetSMSLocation(s, sms, &folderid, &location);
2948 	if (location == 0) return ERR_INVALIDLOCATION;
2949 	return N6510_PrivSetSMSMessage(s, sms);
2950 }
2951 
N6510_AddSMS(GSM_StateMachine * s,GSM_SMSMessage * sms)2952 static GSM_Error N6510_AddSMS(GSM_StateMachine *s, GSM_SMSMessage *sms)
2953 {
2954 	unsigned int		location;
2955 	unsigned char		folderid;
2956 
2957 	N6510_GetSMSLocation(s, sms, &folderid, &location);
2958 	location = 0;
2959 	N6510_SetSMSLocation(s, sms, folderid, location);
2960 	return N6510_PrivSetSMSMessage(s, sms);
2961 }
2962 
N6510_ReplyGetDateTime(GSM_Protocol_Message * msg,GSM_StateMachine * s)2963 static GSM_Error N6510_ReplyGetDateTime(GSM_Protocol_Message *msg, GSM_StateMachine *s)
2964 {
2965 	smprintf(s, "Date & time received\n");
2966 	if (msg->Buffer[4]==0x01) {
2967 		NOKIA_DecodeDateTime(s, msg->Buffer+10, s->Phone.Data.DateTime, TRUE, FALSE);
2968 		return ERR_NONE;
2969 	}
2970 	smprintf(s, "Not set in phone\n");
2971 	return ERR_EMPTY;
2972 }
2973 
N6510_GetDateTime(GSM_StateMachine * s,GSM_DateTime * date_time)2974 static GSM_Error N6510_GetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
2975 {
2976 	unsigned char req[] = {N6110_FRAME_HEADER, 0x0A, 0x00, 0x00};
2977 
2978 	s->Phone.Data.DateTime=date_time;
2979 	smprintf(s, "Getting date & time\n");
2980 	return GSM_WaitFor (s, req, 6, 0x19, s->Phone.Data.Priv.N6510.Timeout, ID_GetDateTime);
2981 }
2982 
N6510_ReplySetDateTime(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)2983 static GSM_Error N6510_ReplySetDateTime(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
2984 {
2985 	smprintf(s, "Date & time set\n");
2986 	return ERR_NONE;
2987 }
2988 
N6510_SetDateTime(GSM_StateMachine * s,GSM_DateTime * date_time)2989 static GSM_Error N6510_SetDateTime(GSM_StateMachine *s, GSM_DateTime *date_time)
2990 {
2991 	unsigned char req[]  = {N6110_FRAME_HEADER,
2992 				0x01, 0x00, 0x01, 0x01, 0x0c, 0x01, 0x03,
2993 				0x00, 0x00,	/* Year */
2994 				0x08, 0x01,     /* Month & Day */
2995 				0x15, 0x1f,	/* Hours & Minutes */
2996 				0x2b,		/* Second ? */
2997 				0x00};
2998 
2999 	NOKIA_EncodeDateTime(s, req+10, date_time);
3000 	req[16] = date_time->Second;
3001 	smprintf(s, "Setting date & time\n");
3002 	return GSM_WaitFor (s, req, 18, 0x19, s->Phone.Data.Priv.N6510.Timeout, ID_SetDateTime);
3003 }
3004 
N6510_ReplyGetManufactureMonth(GSM_Protocol_Message * msg,GSM_StateMachine * s)3005 static GSM_Error N6510_ReplyGetManufactureMonth(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3006 {
3007 	if (msg->Buffer[7] == 0x00) {
3008 		smprintf(s, "No SIM card\n");
3009 		return ERR_NOSIM;
3010 	} else {
3011 		sprintf(s->Phone.Data.PhoneString,"%02i/%04i",msg->Buffer[13],msg->Buffer[14]*256+msg->Buffer[15]);
3012 	        return ERR_NONE;
3013 	}
3014 }
3015 
N6510_GetManufactureMonth(GSM_StateMachine * s,char * value)3016 static GSM_Error N6510_GetManufactureMonth(GSM_StateMachine *s, char *value)
3017 {
3018 	unsigned char req[6] = {0x00, 0x05, 0x02, 0x01, 0x00, 0x02};
3019 /* 	unsigned char req[6] = {0x00, 0x03, 0x04, 0x0B, 0x01, 0x00}; */
3020 
3021 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) return ERR_NOTSUPPORTED;
3022 
3023 	s->Phone.Data.PhoneString=value;
3024 	smprintf(s, "Getting manufacture month\n");
3025 	return GSM_WaitFor (s, req, 6, 0x42, 2, ID_GetManufactureMonth);
3026 /* 	return GSM_WaitFor (s, req, 6, 0x1B, 2, ID_GetManufactureMonth); */
3027 }
3028 
N6510_ReplyGetAlarm(GSM_Protocol_Message * msg,GSM_StateMachine * s)3029 static GSM_Error N6510_ReplyGetAlarm(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3030 {
3031 	GSM_Phone_Data *Data = &s->Phone.Data;
3032 
3033 	switch(msg->Buffer[3]) {
3034 	case 0x1A:
3035 		smprintf(s, "   Alarm: %02d:%02d\n", msg->Buffer[14], msg->Buffer[15]);
3036 		Data->Alarm->Repeating 		= TRUE;
3037 		Data->Alarm->Text[0] 		= 0;
3038 		Data->Alarm->Text[1] 		= 0;
3039 		Data->Alarm->DateTime.Hour	= msg->Buffer[14];
3040 		Data->Alarm->DateTime.Minute	= msg->Buffer[15];
3041 		Data->Alarm->DateTime.Second	= 0;
3042 		return ERR_NONE;
3043 	case 0x20:
3044 		smprintf(s, "Alarm state received\n");
3045 		if (msg->Buffer[37] == 0x01) {
3046 			smprintf(s, "   Not set in phone\n");
3047 			return ERR_EMPTY;
3048 		}
3049 		smprintf(s, "Enabled\n");
3050 		return ERR_NONE;
3051 	}
3052 	return ERR_UNKNOWNRESPONSE;
3053 }
3054 
N6510_GetAlarm(GSM_StateMachine * s,GSM_Alarm * Alarm)3055 static GSM_Error N6510_GetAlarm(GSM_StateMachine *s, GSM_Alarm *Alarm)
3056 {
3057 	unsigned char   StateReq[] = {N6110_FRAME_HEADER, 0x1f, 0x01, 0x00};
3058 	unsigned char   GetReq  [] = {N6110_FRAME_HEADER, 0x19, 0x00, 0x02};
3059 	GSM_Error	error;
3060 
3061 	if (Alarm->Location != 1) return ERR_NOTSUPPORTED;
3062 
3063 	s->Phone.Data.Alarm=Alarm;
3064 	smprintf(s, "Getting alarm state\n");
3065 	error = GSM_WaitFor (s, StateReq, 6, 0x19, s->Phone.Data.Priv.N6510.Timeout, ID_GetAlarm);
3066 	if (error != ERR_NONE) return error;
3067 
3068 	smprintf(s, "Getting alarm\n");
3069 	return GSM_WaitFor (s, GetReq, 6, 0x19, s->Phone.Data.Priv.N6510.Timeout, ID_GetAlarm);
3070 }
3071 
N6510_ReplySetAlarm(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)3072 static GSM_Error N6510_ReplySetAlarm(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
3073 {
3074 	smprintf(s, "Alarm set\n");
3075 	return ERR_NONE;
3076 }
3077 
N6510_SetAlarm(GSM_StateMachine * s,GSM_Alarm * Alarm)3078 static GSM_Error N6510_SetAlarm(GSM_StateMachine *s, GSM_Alarm *Alarm)
3079 {
3080 	unsigned char req[]  = {N6110_FRAME_HEADER,
3081 				0x11, 0x00, 0x01, 0x01, 0x0c, 0x02,
3082 				0x01, 0x00, 0x00, 0x00, 0x00,
3083 				0x00, 0x00,		/* Hours, Minutes */
3084 				0x00, 0x00, 0x00 };
3085 
3086 	if (Alarm->Location != 1) return ERR_NOTSUPPORTED;
3087 
3088 	req[14] = Alarm->DateTime.Hour;
3089 	req[15] = Alarm->DateTime.Minute;
3090 
3091 	smprintf(s, "Setting alarm\n");
3092 	return GSM_WaitFor (s, req, 19, 0x19, s->Phone.Data.Priv.N6510.Timeout, ID_SetAlarm);
3093 }
3094 
N6510_ReplyGetRingtonesInfo(GSM_Protocol_Message * msg,GSM_StateMachine * s)3095 static GSM_Error N6510_ReplyGetRingtonesInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3096 {
3097 	int 			tmp,i;
3098 	GSM_Phone_Data		*Data = &s->Phone.Data;
3099 
3100 	smprintf(s, "Ringtones info received\n");
3101 	memset(Data->RingtonesInfo,0,sizeof(GSM_AllRingtonesInfo));
3102 	if (msg->Buffer[4] * 256 + msg->Buffer[5] == 0x00) return ERR_EMPTY;
3103 	Data->RingtonesInfo->Number = msg->Buffer[4] * 256 + msg->Buffer[5];
3104 	/*  allocate array of ringtones based on number */
3105 	Data->RingtonesInfo->Ringtone = calloc(Data->RingtonesInfo->Number, sizeof(GSM_RingtoneInfo));
3106 	tmp = 6;
3107 	for (i=0;i<Data->RingtonesInfo->Number;i++) {
3108 		Data->RingtonesInfo->Ringtone[i].Group = msg->Buffer[tmp+4];
3109 		Data->RingtonesInfo->Ringtone[i].ID    = msg->Buffer[tmp+2] * 256 + msg->Buffer[tmp+3];
3110 		memcpy(Data->RingtonesInfo->Ringtone[i].Name,msg->Buffer+tmp+8,(msg->Buffer[tmp+6]*256+msg->Buffer[tmp+7])*2);
3111 		smprintf(s, "%5i (%5i). \"%s\"\n",
3112 			Data->RingtonesInfo->Ringtone[i].ID,
3113 			Data->RingtonesInfo->Ringtone[i].Group,
3114 			DecodeUnicodeString(Data->RingtonesInfo->Ringtone[i].Name));
3115 		tmp = tmp + (msg->Buffer[tmp]*256+msg->Buffer[tmp+1]);
3116 	}
3117 	return ERR_NONE;
3118 }
3119 
N6510_PrivGetRingtonesInfo(GSM_StateMachine * s,GSM_AllRingtonesInfo * Info,gboolean AllRingtones)3120 static GSM_Error N6510_PrivGetRingtonesInfo(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info, gboolean AllRingtones)
3121 {
3122 	GSM_Error	error;
3123 	unsigned char 	UserReq[8] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0x02};
3124 /* 	unsigned char 	All_Req[9] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x7D}; */
3125 	unsigned char 	All_Req[8] = {N7110_FRAME_HEADER, 0x07, 0x00, 0x00, 0x00, 0x00};
3126 
3127 	s->Phone.Data.RingtonesInfo=Info;
3128 	smprintf(s, "Getting binary ringtones ID\n");
3129 	if (AllRingtones) {
3130 /* 		error = GSM_WaitFor (s, All_Req, 9, 0x1f, s->Phone.Data.Priv.N6510.Timeout, ID_GetRingtonesInfo); */
3131 		error = GSM_WaitFor (s, All_Req, 8, 0x1f, s->Phone.Data.Priv.N6510.Timeout, ID_GetRingtonesInfo);
3132 		if (error == ERR_EMPTY && Info->Number == 0) return ERR_NOTSUPPORTED;
3133 		return error;
3134 	} else {
3135 		error = GSM_WaitFor (s, UserReq, 8, 0x1f, s->Phone.Data.Priv.N6510.Timeout, ID_GetRingtonesInfo);
3136 		if (error == ERR_EMPTY && Info->Number == 0) return ERR_NOTSUPPORTED;
3137 		return error;
3138 	}
3139 }
3140 
N6510_GetRingtonesInfo(GSM_StateMachine * s,GSM_AllRingtonesInfo * Info)3141 static GSM_Error N6510_GetRingtonesInfo(GSM_StateMachine *s, GSM_AllRingtonesInfo *Info)
3142 {
3143 	return N6510_PrivGetRingtonesInfo(s, Info, TRUE);
3144 }
3145 
N6510_ReplyGetRingtone(GSM_Protocol_Message * msg,GSM_StateMachine * s)3146 static GSM_Error N6510_ReplyGetRingtone(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3147 {
3148 	size_t 			tmp,i;
3149 	GSM_Phone_Data		*Data = &s->Phone.Data;
3150 
3151 	smprintf(s, "Ringtone received\n");
3152 	memcpy(Data->Ringtone->Name,msg->Buffer+8,msg->Buffer[7]*2);
3153 	Data->Ringtone->Name[msg->Buffer[7]*2]=0;
3154 	Data->Ringtone->Name[msg->Buffer[7]*2+1]=0;
3155 	smprintf(s, "Name \"%s\"\n",DecodeUnicodeString(Data->Ringtone->Name));
3156  	if (msg->Buffer[msg->Buffer[7]*2+10] == 'M' &&
3157  	    msg->Buffer[msg->Buffer[7]*2+11] == 'T' &&
3158  	    msg->Buffer[msg->Buffer[7]*2+12] == 'h' &&
3159  	    msg->Buffer[msg->Buffer[7]*2+13] == 'd') {
3160  		smprintf(s,"MIDI\n");
3161  		tmp 	= msg->Buffer[7]*2+10;
3162  		i 	= msg->Length - 2; /* ?????? */
3163  		Data->Ringtone->Format = RING_MIDI;
3164  	} else {
3165  		/* Looking for end */
3166  		i=8+msg->Buffer[7]*2+3;
3167  		tmp = i;
3168  		while (TRUE) {
3169  			if (msg->Buffer[i]==0x07 && msg->Buffer[i+1]==0x0b) {
3170  				i=i+2; break;
3171  			}
3172  			i++;
3173  			if (i==msg->Length) return ERR_EMPTY;
3174  		}
3175 	}
3176 	/* Copying frame */
3177 	memcpy(Data->Ringtone->NokiaBinary.Frame,msg->Buffer+tmp,i-tmp);
3178 	Data->Ringtone->NokiaBinary.Length=i-tmp;
3179 	return ERR_NONE;
3180 }
3181 
N6510_GetRingtone(GSM_StateMachine * s,GSM_Ringtone * Ringtone,gboolean PhoneRingtone)3182 static GSM_Error N6510_GetRingtone(GSM_StateMachine *s, GSM_Ringtone *Ringtone, gboolean PhoneRingtone)
3183 {
3184  	GSM_AllRingtonesInfo 	Info = {0, NULL};
3185 	GSM_Error		error;
3186 	unsigned char 		req2[6] = {N7110_FRAME_HEADER, 0x12,
3187 					   0x00, 0xe7}; 	/* Location */
3188 
3189 	if (Ringtone->Format == 0x00) Ringtone->Format = RING_NOKIABINARY;
3190 
3191 	switch (Ringtone->Format) {
3192 	case RING_NOTETONE:
3193 		/* In the future get binary and convert */
3194 		return ERR_NOTSUPPORTED;
3195 	case RING_NOKIABINARY:
3196 		s->Phone.Data.Ringtone	= Ringtone;
3197 		Info.Number 		= 0;
3198 		error=N6510_PrivGetRingtonesInfo(s, &Info, PhoneRingtone);
3199 		if (error != ERR_NONE) return error;
3200 		if (Ringtone->Location > Info.Number) return ERR_INVALIDLOCATION;
3201 		req2[4] = Info.Ringtone[Ringtone->Location-1].ID / 256;
3202 		req2[5] = Info.Ringtone[Ringtone->Location-1].ID % 256;
3203 		smprintf(s, "Getting binary ringtone\n");
3204  		error = GSM_WaitFor (s, req2, 6, 0x1f, s->Phone.Data.Priv.N6510.Timeout, ID_GetRingtone);
3205  		if (Info.Ringtone) {
3206 			free(Info.Ringtone);
3207 			Info.Ringtone=NULL;
3208 		}
3209  		return error;
3210 	case RING_MIDI:
3211 	case RING_MMF:
3212 		return ERR_NOTSUPPORTED;
3213 	}
3214 	return ERR_NOTSUPPORTED;
3215 }
3216 
N6510_PlayTone(GSM_StateMachine * s,int Herz,unsigned char Volume,gboolean start)3217 static GSM_Error N6510_PlayTone(GSM_StateMachine *s, int Herz, unsigned char Volume, gboolean start)
3218 {
3219 	GSM_Error 	error;
3220 	unsigned char 	reqStart[] = {
3221 		0x00,0x06,0x01,0x00,0x07,0x00 };
3222 	unsigned char 	reqPlay[] = {
3223 		0x00,0x06,0x01,0x14,0x05,0x04,
3224 		0x00,0x00,0x00,0x03,0x03,0x08,
3225 		0x00,0x00,0x00,0x01,0x00,0x00,
3226 		0x03,0x08,0x01,0x00,
3227 		0x07,0xd0,	/*Frequency */
3228 		0x00,0x00,0x03,0x08,0x02,0x00,0x00,
3229 		0x05,		/*Volume */
3230 		0x00,0x00};
3231 	unsigned char 	reqOff[] = {
3232 		0x00,0x06,0x01,0x14,0x05,0x05,
3233 		0x00,0x00,0x00,0x01,0x03,0x08,
3234 		0x05,0x00,0x00,0x08,0x00,0x00};
3235 /* 	unsigned char 	reqOff2[] = { */
3236 /* 		0x00,0x06,0x01,0x14,0x05,0x04, */
3237 /* 		0x00,0x00,0x00,0x01,0x03,0x08, */
3238 /* 		0x00,0x00,0x00,0x00,0x00,0x00}; */
3239 
3240 	if (start) {
3241 		smprintf(s, "Enabling sound - part 1\n");
3242 		error=GSM_WaitFor (s, reqStart, 6, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone);
3243 		if (error!=ERR_NONE) return error;
3244 		smprintf(s, "Enabling sound - part 2 (disabling sound command)\n");
3245 		error=GSM_WaitFor (s, reqOff, 18, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone);
3246 		if (error!=ERR_NONE) return error;
3247 	}
3248 
3249 	/* For Herz==255*255 we have silent */
3250 	if (Herz!=255*255) {
3251 		reqPlay[23] = Herz%256;
3252 		reqPlay[22] = Herz/256;
3253 		reqPlay[31] = Volume;
3254 		smprintf(s, "Playing sound\n");
3255 		return GSM_WaitFor (s, reqPlay, 34, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone);
3256 	} else {
3257 		reqPlay[23] = 0;
3258 		reqPlay[22] = 0;
3259 		reqPlay[31] = 0;
3260 		smprintf(s, "Playing silent sound\n");
3261 		return GSM_WaitFor (s, reqPlay, 34, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone);
3262 
3263 /* 		smprintf(s, "Disabling sound - part 1\n"); */
3264 /* 		error=GSM_WaitFor (s, reqOff, 18, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone); */
3265 /* 		if (error!=ERR_NONE) return error; */
3266 /* 		smprintf(s, "Disabling sound - part 2\n"); */
3267 /* 		return GSM_WaitFor (s, reqOff2, 18, 0x0b, s->Phone.Data.Priv.N6510.Timeout, ID_PlayTone); */
3268 	}
3269 }
3270 
N6510_ReplyGetPPM(GSM_Protocol_Message * msg,GSM_StateMachine * s)3271 static GSM_Error N6510_ReplyGetPPM(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3272 {
3273 	GSM_Phone_Data 	*Data = &s->Phone.Data;
3274 	size_t		pos = 6,len;
3275 
3276 	smprintf(s, "Received phone info\n");
3277 
3278 	while(pos < msg->Length) {
3279 		if (msg->Buffer[pos] == 0x55 && msg->Buffer[pos+1] == 0x55) {
3280 			while(1) {
3281 				if (msg->Buffer[pos] != 0x55) break;
3282 				pos++;
3283 			}
3284 		}
3285 		len = pos;
3286 		while(len < msg->Length) {
3287 			if (msg->Buffer[len] == 0x00 && msg->Buffer[len+1] == 0x00) break;
3288 			len++;
3289 		}
3290 		while(len < msg->Length) {
3291 			if (msg->Buffer[len] != 0x00) break;
3292 			len++;
3293 		}
3294 		len = len-pos;
3295 		smprintf(s, "Block with ID %02x",msg->Buffer[pos]);
3296 #ifdef DEBUG
3297 		if (s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXTALLDATE) DumpMessage(&s->di, msg->Buffer+pos, len);
3298 #endif
3299 		switch (msg->Buffer[pos]) {
3300 		case 0x49:
3301 			smprintf(s, "hardware version\n");
3302 			break;
3303 		case 0x58:
3304 			pos += 3;
3305 			while (msg->Buffer[pos] != 0x00) pos++;
3306 			Data->PhoneString[0] = msg->Buffer[pos - 1];
3307 			Data->PhoneString[1] = 0x00;
3308 			smprintf(s, "PPM %s\n",Data->PhoneString);
3309 			return ERR_NONE;
3310 		default:
3311 			break;
3312 		}
3313 		pos += len;
3314 	}
3315 	return ERR_NOTSUPPORTED;
3316 }
3317 
N6510_GetPPM(GSM_StateMachine * s,char * value)3318 static GSM_Error N6510_GetPPM(GSM_StateMachine *s,char *value)
3319 {
3320 /* 	unsigned char req[6] = {N6110_FRAME_HEADER, 0x07, 0x01, 0xff}; */
3321 	unsigned char req[6] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x00};
3322 
3323 	s->Phone.Data.PhoneString=value;
3324 	smprintf(s, "Getting PPM\n");
3325 	return GSM_WaitFor (s, req, 6, 0x1b, 3, ID_GetPPM);
3326 }
3327 
N6510_GetSpeedDial(GSM_StateMachine * s,GSM_SpeedDial * SpeedDial)3328 static GSM_Error N6510_GetSpeedDial(GSM_StateMachine *s, GSM_SpeedDial *SpeedDial)
3329 {
3330 	GSM_MemoryEntry 	pbk;
3331 	GSM_Error		error;
3332 
3333 	pbk.MemoryType			= (GSM_MemoryType)MEM7110_SP;
3334 	pbk.Location			= SpeedDial->Location;
3335 	SpeedDial->MemoryLocation 	= 0;
3336 	s->Phone.Data.SpeedDial		= SpeedDial;
3337 
3338 	smprintf(s, "Getting speed dial\n");
3339 	error=N6510_GetMemory(s,&pbk);
3340 	switch (error) {
3341 	case ERR_NOTSUPPORTED:
3342 		smprintf(s, "No speed dials set in phone\n");
3343 		return ERR_EMPTY;
3344 	case ERR_NONE:
3345 		if (SpeedDial->MemoryLocation == 0) {
3346 			smprintf(s, "Speed dial not assigned or error in firmware\n");
3347 			return ERR_EMPTY;
3348 		}
3349 		return ERR_NONE;
3350 	default:
3351 		return error;
3352 	}
3353 }
3354 
N6510_ReplyGetProfile(GSM_Protocol_Message * msg,GSM_StateMachine * s)3355 static GSM_Error N6510_ReplyGetProfile(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3356 {
3357 	unsigned char 	*blockstart;
3358 	int 		i,j;
3359 	GSM_Phone_Data	*Data = &s->Phone.Data;
3360 
3361 	switch (msg->Buffer[3]) {
3362 	case 0x02:
3363 	blockstart = msg->Buffer + 7;
3364 	for (i = 0; i < 11; i++) {
3365 		smprintf(s, "Profile feature %02x ",blockstart[1]);
3366 #ifdef DEBUG
3367 		if (s->di.dl == DL_TEXTALL || s->di.dl == DL_TEXTALLDATE) DumpMessage(&s->di, blockstart, blockstart[0]);
3368 #endif
3369 
3370 		switch (blockstart[1]) {
3371 		case 0x03:
3372 			smprintf(s, "Ringtone ID\n");
3373 			Data->Profile->FeatureID	[Data->Profile->FeaturesNumber] = Profile_RingtoneID;
3374 			Data->Profile->FeatureValue	[Data->Profile->FeaturesNumber] = blockstart[7];
3375 			if (blockstart[7] == 0x00) {
3376 				Data->Profile->FeatureValue[Data->Profile->FeaturesNumber] = blockstart[10];
3377 			}
3378 			Data->Profile->FeaturesNumber++;
3379 			break;
3380 		case 0x05:	/* SMS tone */
3381 			j = Data->Profile->FeaturesNumber;
3382 			NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,FALSE);
3383 			if (j == Data->Profile->FeaturesNumber) {
3384 				Data->Profile->FeatureID	[Data->Profile->FeaturesNumber] = Profile_MessageTone;
3385 				Data->Profile->FeatureValue	[Data->Profile->FeaturesNumber] = PROFILE_MESSAGE_PERSONAL;
3386 				Data->Profile->FeaturesNumber++;
3387 				Data->Profile->FeatureID	[Data->Profile->FeaturesNumber] = Profile_MessageToneID;
3388 				Data->Profile->FeatureValue	[Data->Profile->FeaturesNumber] = blockstart[7];
3389 				Data->Profile->FeaturesNumber++;
3390 			}
3391 			break;
3392 		case 0x08:	/* Caller groups */
3393 			NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,TRUE);
3394 			break;
3395 		case 0x0c :
3396 			CopyUnicodeString(Data->Profile->Name,blockstart + 7);
3397 			smprintf(s, "profile Name: \"%s\"\n", DecodeUnicodeString(Data->Profile->Name));
3398 			Data->Profile->DefaultName = FALSE;
3399 			break;
3400 		default:
3401 			NOKIA_FindFeatureValue(s, Profile71_65,blockstart[1],blockstart[7],Data,FALSE);
3402 		}
3403 		blockstart = blockstart + blockstart[0];
3404 	}
3405 	return ERR_NONE;
3406 	case 0x06:
3407 		Data->Profile->Active = FALSE;
3408 		if (Data->Profile->Location == msg->Buffer[5]) Data->Profile->Active = TRUE;
3409 		return ERR_NONE;
3410 	}
3411 	return ERR_UNKNOWNRESPONSE;
3412 }
3413 
N6510_GetProfile(GSM_StateMachine * s,GSM_Profile * Profile)3414 static GSM_Error N6510_GetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
3415 {
3416 	unsigned char 	req[150]    = {N6110_FRAME_HEADER, 0x01, 0x01, 0x0C, 0x01};
3417 	unsigned char	reqActive[] = {N6110_FRAME_HEADER, 0x05};
3418 	int 		i, length = 7;
3419 	GSM_Error	error;
3420 
3421 	if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES)) return ERR_NOTSUPPORTED;
3422 
3423 /* 	if (!strcmp(s->Phone.Data.ModelInfo->model,"3510")) { */
3424 /* 		if (s->Phone.Data.VerNum>3.37) return ERR_NOTSUPPORTED; */
3425 /* 	if (!strcmp(s->Phone.Data.ModelInfo->model,"6230")) { */
3426 /* 	if (!strcmp(s->Phone.Data.ModelInfo->model,"6220")) { */
3427 /* 	if (!strcmp(s->Phone.Data.ModelInfo->model,"5140")) { */
3428 /* 	if (!strcmp(s->Phone.Data.ModelInfo->model,"6230i")) { */
3429 /* 	if (!strcmp(s->Phone.Data.ModelInfo->model,"6020")) { */
3430 
3431 	if (Profile->Location>5) return ERR_INVALIDLOCATION;
3432 
3433 	for (i = 0; i < 0x0a; i++) {
3434 		req[length++] = 0x04;
3435 		req[length++] = Profile->Location;
3436 		req[length++] = i;
3437 		req[length++] = 0x01;
3438 	}
3439 
3440 	req[length++] = 0x04;
3441 	req[length++] = Profile->Location;
3442 	req[length++] = 0x0c;
3443 	req[length++] = 0x01;
3444 
3445 	req[length++] = 0x04;
3446 
3447 	Profile->CarKitProfile	= FALSE;
3448 	Profile->HeadSetProfile	= FALSE;
3449 
3450 	Profile->FeaturesNumber = 0;
3451 
3452 	s->Phone.Data.Profile=Profile;
3453 	smprintf(s, "Getting profile\n");
3454 	error = GSM_WaitFor (s, req, length, 0x39, s->Phone.Data.Priv.N6510.Timeout, ID_GetProfile);
3455 	if (error != ERR_NONE) return error;
3456 
3457 	smprintf(s, "Checking, which profile is active\n");
3458 	return GSM_WaitFor (s, reqActive, 4, 0x39, s->Phone.Data.Priv.N6510.Timeout, ID_GetProfile);
3459 }
3460 
N6510_ReplySetProfile(GSM_Protocol_Message * msg,GSM_StateMachine * s)3461 static GSM_Error N6510_ReplySetProfile(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3462 {
3463 	unsigned char 	*blockstart;
3464 	int 		i;
3465 
3466 	smprintf(s, "Response to profile writing received!\n");
3467 
3468 	blockstart = msg->Buffer + 6;
3469 	for (i = 0; i < msg->Buffer[5]; i++) {
3470 		switch (blockstart[2]) {
3471 			case 0x00: smprintf(s, "keypad tone level"); 	break;
3472 			case 0x02: smprintf(s, "call alert"); 		break;
3473 			case 0x03: smprintf(s, "ringtone"); 		break;
3474 			case 0x04: smprintf(s, "ringtone volume"); 	break;
3475 			case 0x05: smprintf(s, "SMS tone"); 		break;
3476 			case 0x06: smprintf(s, "vibration"); 		break;
3477 			case 0x07: smprintf(s, "warning tone level"); 	break;
3478 			case 0x08: smprintf(s, "caller groups"); 	break;
3479 			case 0x09: smprintf(s, "automatic answer"); 	break;
3480 			case 0x0c: smprintf(s, "name"); 		break;
3481 			default:
3482 				smprintf(s, "Unknown block type %02x", blockstart[2]);
3483 				break;
3484 		}
3485 		if (msg->Buffer[4] == 0x00) {
3486 			smprintf(s, ": set OK\n");
3487 		} else {
3488 			smprintf(s, ": setting error %i\n", msg->Buffer[4]);
3489 		}
3490 		blockstart = blockstart + blockstart[1];
3491 	}
3492 	return ERR_NONE;
3493 }
3494 
N6510_SetProfile(GSM_StateMachine * s,GSM_Profile * Profile)3495 static GSM_Error N6510_SetProfile(GSM_StateMachine *s, GSM_Profile *Profile)
3496 {
3497 	int 		i, length = 7, blocks = 0;
3498 	gboolean		found;
3499 	unsigned char	ID,Value;
3500 	unsigned char 	req[150] = {N6110_FRAME_HEADER, 0x03, 0x01,
3501 				    0x06,		/* Number of blocks */
3502 				    0x03};
3503 
3504 	if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_PROFILES)) return ERR_NOTSUPPORTED;
3505 
3506 	if (Profile->Location>5) return ERR_INVALIDLOCATION;
3507 
3508 	for (i=0;i<Profile->FeaturesNumber;i++) {
3509 		found = FALSE;
3510 		switch (Profile->FeatureID[i]) {
3511 			case Profile_RingtoneID:
3512 				ID 	= 0x03;
3513 				Value 	= Profile->FeatureValue[i];
3514 				found 	= TRUE;
3515 				break;
3516 			default:
3517 				found=NOKIA_FindPhoneFeatureValue(
3518 					s,
3519 					Profile71_65,
3520 					Profile->FeatureID[i],Profile->FeatureValue[i],
3521 					&ID,&Value);
3522 		}
3523 		if (found) {
3524 			req[length] 	= 0x09;
3525 			req[length + 1] = ID;
3526 			req[length + 2] = Profile->Location;
3527 			memcpy(req + length + 4, "\x00\x00\x01", 3);
3528 			req[length + 8] = 0x03;
3529 			req[length + 3] = req[length + 7] = Value;
3530 			blocks++;
3531 			length += 9;
3532 		}
3533 	}
3534 
3535 	smprintf(s, "Setting profile\n");
3536 	return GSM_WaitFor (s, req, length, 0x39, s->Phone.Data.Priv.N6510.Timeout, ID_SetProfile);
3537 }
3538 
N6510_ReplyIncomingCB(GSM_Protocol_Message * msg,GSM_StateMachine * s)3539 static GSM_Error N6510_ReplyIncomingCB(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3540 {
3541 	switch (msg->Buffer[3]) {
3542 		case 0x21:
3543 			smprintf(s, "Ignoring cell broadcast ok event\n");
3544 			break;
3545 		case 0x22:
3546 			smprintf(s, "Ignoring cell broadcast fail event\n");
3547 			break;
3548 		case 0x23:
3549 			smprintf(s, "Ignoring cell broadcast read event\n");
3550 			break;
3551 		default:
3552 			smprintf(s, "Ignoring cell broadcast event 0x%02x\n", msg->Buffer[3]);
3553 			break;
3554 	}
3555 	return ERR_NONE;
3556 }
N6510_ReplyIncomingSMS(GSM_Protocol_Message * msg,GSM_StateMachine * s)3557 static GSM_Error N6510_ReplyIncomingSMS(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3558 {
3559 	GSM_SMSMessage 	sms;
3560 	size_t 		i;
3561 
3562 #ifdef DEBUG
3563 	smprintf(s, "SMS message received\n");
3564 	N6510_DecodeSMSFrame(s, &sms, msg->Buffer+10,&i);
3565 #endif
3566 
3567 	if (s->Phone.Data.EnableIncomingSMS && s->User.IncomingSMS!=NULL) {
3568 		GSM_SetDefaultSMSData(&sms);
3569 
3570 		sms.State 	 = SMS_UnRead;
3571 		sms.InboxFolder  = TRUE;
3572 
3573 		N6510_DecodeSMSFrame(s, &sms, msg->Buffer+10,&i);
3574 
3575 		s->User.IncomingSMS(s, &sms, s->User.IncomingSMSUserData);
3576 	}
3577 	return ERR_NONE;
3578 }
3579 
N6510_DialVoice(GSM_StateMachine * s,char * number,GSM_CallShowNumber ShowNumber)3580 static GSM_Error N6510_DialVoice(GSM_StateMachine *s, char *number, GSM_CallShowNumber ShowNumber)
3581 {
3582 	unsigned int 	pos2 = 15;
3583 	unsigned int	pos = 4;
3584 	unsigned char 	req2[100] = {N6110_FRAME_HEADER,0x01,
3585 				    0x00,0x02,0x07,0x04,
3586 				    0x01,  /*  1 - voice, 2 - data */
3587 				    0x00,0x03,
3588 				    0x18,  /*  length of rest + 1 */
3589 				    0x00,0x00,0x00};
3590 	unsigned char 	req[100] = {N6110_FRAME_HEADER,0x01,
3591 				    0x0c};	/* Number length */
3592 	GSM_Error	error;
3593 
3594 	/* USSD not supported */
3595 	if (number[0] == '*') return ERR_NOTSUPPORTED;
3596 	if (number[0] == '#') return ERR_NOTSUPPORTED;
3597 
3598 	req[pos++] = strlen(number);
3599 	EncodeUnicode(req+pos,number,strlen(number));
3600 	pos += strlen(number)*2;
3601 	req[pos++] = 0x05; /* call type: voice - 0x05, data - 0x01 */
3602 	req[pos++] = 0x01;
3603 	req[pos++] = 0x05;
3604 	req[pos++] = 0x00;
3605 	req[pos++] = 0x02;
3606 	req[pos++] = 0x00;
3607 	req[pos++] = 0x00;
3608 	switch (ShowNumber) {
3609 	case GSM_CALL_HideNumber:
3610 		req[pos++] = 0x02;
3611 		break;
3612 	case GSM_CALL_ShowNumber:
3613 		req[pos++] = 0x03;
3614 		break;
3615 	case GSM_CALL_DefaultNumberPresence:
3616 		req[pos++] = 0x01;
3617 		break;
3618 	}
3619 	smprintf(s, "Making voice call\n");
3620 	error = GSM_WaitFor (s, req, pos, 0x01, s->Phone.Data.Priv.N6510.Timeout, ID_DialVoice);
3621 	if (error != ERR_NOTSUPPORTED) return error;
3622 
3623 	if (ShowNumber != GSM_CALL_DefaultNumberPresence) return ERR_NOTSUPPORTED;
3624 
3625 	req2[11] = strlen(number)*2+6;
3626 	req2[pos2++] = strlen(number);
3627 	EncodeUnicode(req2+pos2,number,strlen(number));
3628 	pos2 += strlen(number)*2;
3629 
3630 	smprintf(s, "Making voice call\n");
3631 	error = GSM_WaitFor (s, req2, pos2, 0x01, s->Phone.Data.Priv.N6510.Timeout, ID_DialVoice);
3632 	if (error == ERR_NOTSUPPORTED) return ERR_NONE;
3633 	return error;
3634 }
3635 
N6510_ReplyLogIntoNetwork(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)3636 static GSM_Error N6510_ReplyLogIntoNetwork(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
3637 {
3638 	smprintf(s, "Probably phone says: I log into network\n");
3639 	return ERR_NONE;
3640 }
3641 
N6510_EncodeFMFrequency(double freq,unsigned char * buff)3642 void N6510_EncodeFMFrequency(double freq, unsigned char *buff)
3643 {
3644 	unsigned int		freq2;
3645 
3646  	freq2 = (unsigned int)(freq * 100);
3647  	freq2	= freq2 - 0xffff;
3648  	buff[0] = freq2 / 0x100;
3649  	buff[1] = freq2 % 0x100;
3650 }
3651 
N6510_DecodeFMFrequency(double * freq,unsigned char * buff)3652 void N6510_DecodeFMFrequency(double *freq, unsigned char *buff)
3653 {
3654 	*freq = (double)(0xffff + buff[0] * 0x100 + buff[1])/1000.0;
3655 }
3656 
N6510_ReplyGetFMStatus(GSM_Protocol_Message * msg,GSM_StateMachine * s)3657 static GSM_Error N6510_ReplyGetFMStatus(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3658 {
3659   	smprintf(s, "getting FM status OK\n");
3660 	memcpy(s->Phone.Data.Priv.N6510.FMStatus,msg->Buffer,msg->Length);
3661 	s->Phone.Data.Priv.N6510.FMStatusLength = msg->Length;
3662 	return ERR_NONE;
3663 }
3664 
N6510_GetFMStatus(GSM_StateMachine * s)3665 static GSM_Error N6510_GetFMStatus(GSM_StateMachine *s)
3666 {
3667  	unsigned char req[7] = {N6110_FRAME_HEADER, 0x0d, 0x00, 0x00, 0x01};
3668 
3669  	if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3670  	return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_GetFMStation);
3671 }
3672 
N6510_ReplyGetFMStation(GSM_Protocol_Message * msg,GSM_StateMachine * s)3673 static GSM_Error N6510_ReplyGetFMStation(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3674 {
3675   	unsigned char 	name[GSM_MAX_FMSTATION_LENGTH*2+2];
3676   	int		length;
3677   	GSM_Phone_Data	*Data = &s->Phone.Data;
3678 
3679 	switch (msg->Buffer[3]) {
3680 	case 0x06:
3681 	  	smprintf(s, "Received FM station\n");
3682  		length = msg->Buffer[8];
3683 		if (length > GSM_MAX_FMSTATION_LENGTH) {
3684 			smprintf(s, "FM station name too long (%d), truncating!\n", length);
3685 			length = GSM_MAX_FMSTATION_LENGTH;
3686 		}
3687  		memcpy(name,msg->Buffer+18,length*2);
3688  		name[length*2]	 = 0x00;
3689  		name[length*2+1] = 0x00;
3690  		CopyUnicodeString(Data->FMStation->StationName,name);
3691 		smprintf(s,"Station name: \"%s\"\n",DecodeUnicodeString(Data->FMStation->StationName));
3692 		N6510_DecodeFMFrequency(&Data->FMStation->Frequency, msg->Buffer+16);
3693 		return ERR_NONE;
3694 	case 0x16:
3695 	  	smprintf(s, "Received FM station. Empty ?\n");
3696 		return ERR_EMPTY;
3697 	case 0xf0:
3698 	  	smprintf(s, "FM radio not supported\n");
3699 		return ERR_NOTSUPPORTED;
3700 	}
3701 	return ERR_UNKNOWNRESPONSE;
3702 }
3703 
N6510_GetFMStation(GSM_StateMachine * s,GSM_FMStation * FMStation)3704 static GSM_Error N6510_GetFMStation (GSM_StateMachine *s, GSM_FMStation *FMStation)
3705 {
3706  	GSM_Error 		error;
3707  	int			location;
3708   	unsigned char 		req[7] = {N6110_FRAME_HEADER, 0x05,
3709  					  0x00, 		/*  location */
3710 	    				  0x00,0x01};
3711 
3712   	if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3713    	if (FMStation->Location > GSM_MAX_FM_STATION) return ERR_INVALIDLOCATION;
3714 
3715   	s->Phone.Data.FMStation = FMStation;
3716 
3717  	error = N6510_GetFMStatus(s);
3718  	if (error != ERR_NONE) return error;
3719 
3720  	location = FMStation->Location-1;
3721   	if (s->Phone.Data.Priv.N6510.FMStatus[14+location] == 0xFF) return ERR_EMPTY;
3722  	req[4]   = s->Phone.Data.Priv.N6510.FMStatus[14+location];
3723 
3724  	smprintf(s, "Getting FM Station %i\n",FMStation->Location);
3725  	return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_GetFMStation);
3726 }
3727 
N6510_ReplySetFMStation(GSM_Protocol_Message * msg,GSM_StateMachine * s)3728 static GSM_Error N6510_ReplySetFMStation(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3729 {
3730 #ifdef DEBUG
3731  	switch (msg->Buffer[4]){
3732  		case 0x03: smprintf(s, "FM stations cleaned\n");	  break;
3733  		case 0x11: smprintf(s, "Setting FM station status OK\n"); break;
3734  		case 0x12: smprintf(s, "Setting FM station OK\n");	  break;
3735  	}
3736 #endif
3737  	return ERR_NONE;
3738 }
3739 
N6510_ClearFMStations(GSM_StateMachine * s)3740 static GSM_Error N6510_ClearFMStations (GSM_StateMachine *s)
3741 {
3742 	unsigned char req[7] = {N6110_FRAME_HEADER, 0x03,0x0f,0x00,0x01};
3743 
3744 	if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3745 
3746 	smprintf(s, "Cleaning FM Stations\n");
3747 	return GSM_WaitFor (s, req, 7, 0x3E, 2, ID_SetFMStation);
3748 }
3749 
N6510_SetFMStation(GSM_StateMachine * s,GSM_FMStation * FMStation)3750 static GSM_Error N6510_SetFMStation (GSM_StateMachine *s, GSM_FMStation *FMStation)
3751 {
3752 	unsigned int 		len, location;
3753  	GSM_Error 		error;
3754  	unsigned char setstatus[36] = {N6110_FRAME_HEADER,0x11,0x00,0x01,0x01,
3755  	    			0x00,0x00,0x1c,0x00,0x14,0x00,0x00,
3756  				0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3757  				0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
3758  				0xff,0xff,0xff,0xff,0xff,0x01};
3759  	unsigned char req[64] = {N6110_FRAME_HEADER, 0x12,0x00,0x01,0x00,
3760  				0x00, 			/*  0x0e + (strlen(name) * 2) */
3761  				0x00,			/*  strlen(name) */
3762  				0x14,0x09,0x00,
3763  				0x00, 			/*  location */
3764  				0x00,0x00,0x01,
3765  				0x00, 			/*  freqHi */
3766  				0x00, 			/*  freqLo */
3767  				0x01};
3768 
3769  	if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_RADIO)) return ERR_NOTSUPPORTED;
3770 
3771  	s->Phone.Data.FMStation = FMStation;
3772  	location = FMStation->Location-1;
3773 
3774  	error = N6510_GetFMStatus(s);
3775  	if (error != ERR_NONE) return error;
3776 
3777  	memcpy(setstatus+14,s->Phone.Data.Priv.N6510.FMStatus+14,20);
3778  	setstatus [14+location] = location;
3779 
3780  	smprintf(s, "Setting FM status %i\n",FMStation->Location);
3781  	error = GSM_WaitFor (s, setstatus, 36 , 0x3E, 2, ID_SetFMStation);
3782  	if (error != ERR_NONE) return error;
3783 
3784  	req[12] = location;
3785 
3786 	/* Name */
3787  	len 	= UnicodeLength(FMStation->StationName);
3788  	req[8] 	= len;
3789  	req[7] 	= 0x0e + len * 2;
3790  	memcpy (req+18,FMStation->StationName,len*2);
3791 
3792 	/* Frequency */
3793 	N6510_EncodeFMFrequency(FMStation->Frequency, req+16);
3794 
3795  	smprintf(s, "Setting FM Station %i\n",FMStation->Location);
3796  	return GSM_WaitFor (s, req, 0x13+len*2, 0x3E, 2, ID_SetFMStation);
3797 }
3798 
N6510_ReplySetLight(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s)3799 static GSM_Error N6510_ReplySetLight(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s)
3800 {
3801 	smprintf(s, "Light set\n");
3802 	return ERR_NONE;
3803 }
3804 
N6510_SetLight(GSM_StateMachine * s,N6510_PHONE_LIGHTS light,gboolean enable)3805 GSM_Error N6510_SetLight(GSM_StateMachine *s, N6510_PHONE_LIGHTS light, gboolean enable)
3806 {
3807 	unsigned char req[14] = {
3808 		N6110_FRAME_HEADER, 0x05,
3809 		0x01,		/* 0x01 = Display, 0x03 = keypad */
3810 		0x01,		/* 0x01 = Enable, 0x02 = disable */
3811 		0x00, 0x00, 0x00, 0x01,
3812 		0x05, 0x04, 0x02, 0x00};
3813 
3814 	req[4] = light;
3815 	if (!enable) req[5] = 0x02;
3816  	smprintf(s, "Setting light\n");
3817 	return GSM_WaitFor (s, req, 14, 0x3A, s->Phone.Data.Priv.N6510.Timeout, ID_SetLight);
3818 }
3819 
N6510_ShowStartInfo(GSM_StateMachine * s,gboolean enable)3820 static GSM_Error N6510_ShowStartInfo(GSM_StateMachine *s, gboolean enable)
3821 {
3822 	GSM_Error error;
3823 
3824 	if (enable) {
3825 		error=N6510_SetLight(s,N6510_LIGHT_DISPLAY,TRUE);
3826 		if (error != ERR_NONE) return error;
3827 
3828 		error=N6510_SetLight(s,N6510_LIGHT_TORCH,TRUE);
3829 		if (error != ERR_NONE) return error;
3830 
3831 		return N6510_SetLight(s,N6510_LIGHT_KEYPAD,TRUE);
3832 	} else {
3833 		error=N6510_SetLight(s,N6510_LIGHT_DISPLAY,FALSE);
3834 		if (error != ERR_NONE) return error;
3835 
3836 		error=N6510_SetLight(s,N6510_LIGHT_TORCH,FALSE);
3837 		if (error != ERR_NONE) return error;
3838 
3839 		return N6510_SetLight(s,N6510_LIGHT_KEYPAD,FALSE);
3840 	}
3841 }
3842 
N6510_ReplyGetGPRSAccessPoint(GSM_Protocol_Message * msg,GSM_StateMachine * s)3843 static GSM_Error N6510_ReplyGetGPRSAccessPoint(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3844 {
3845 	GSM_GPRSAccessPoint *point = s->Phone.Data.GPRSPoint;
3846 
3847 	switch (msg->Buffer[13]) {
3848 	case 0x01:
3849 		smprintf(s,"Active GPRS point received\n");
3850 		point->Active = FALSE;
3851 		if (point->Location == msg->Buffer[18]) point->Active = TRUE;
3852 		return ERR_NONE;
3853 	case 0xD2:
3854 		smprintf(s,"Names for GPRS points received\n");
3855 		CopyUnicodeString(point->Name,msg->Buffer+18+(point->Location-1)*42);
3856 		smprintf(s,"\"%s\"\n",DecodeUnicodeString(point->Name));
3857 		return ERR_NONE;
3858 	case 0xF2:
3859 		smprintf(s,"URL for GPRS points received\n");
3860 		CopyUnicodeString(point->URL,msg->Buffer+18+(point->Location-1)*202);
3861 		smprintf(s,"\"%s\"\n",DecodeUnicodeString(point->URL));
3862 		return ERR_NONE;
3863 	}
3864 	return ERR_UNKNOWNRESPONSE;
3865 }
3866 
N6510_GetGPRSAccessPoint(GSM_StateMachine * s,GSM_GPRSAccessPoint * point)3867 static GSM_Error N6510_GetGPRSAccessPoint(GSM_StateMachine *s, GSM_GPRSAccessPoint *point)
3868 {
3869 	GSM_Error	error;
3870 	unsigned char 	URL[] = {
3871 		N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3872 		0x00, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00};
3873 	unsigned char 	Name[] = {
3874 		N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3875 		0x01, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00};
3876 	unsigned char 	Active[] = {
3877 		N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3878 		0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
3879 
3880 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return ERR_NOTSUPPORTED;
3881 	if (point->Location < 1) return ERR_UNKNOWN;
3882 	if (point->Location > 5) return ERR_INVALIDLOCATION;
3883 
3884 	s->Phone.Data.GPRSPoint = point;
3885 
3886 	smprintf(s, "Getting GPRS access point name\n");
3887 	error=GSM_WaitFor (s, Name, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_GetGPRSPoint);
3888 	if (error != ERR_NONE) return error;
3889 
3890 	smprintf(s, "Getting GPRS access point URL\n");
3891 	error=GSM_WaitFor (s, URL, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_GetGPRSPoint);
3892 	if (error != ERR_NONE) return error;
3893 
3894 	smprintf(s, "Getting number of active GPRS access point\n");
3895 	error=GSM_WaitFor (s, Active, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_GetGPRSPoint);
3896 	if (error != ERR_NONE) return error;
3897 
3898 	if (UnicodeLength(point->URL)==0 && UnicodeLength(point->Name)==0) return ERR_EMPTY;
3899 	return error;
3900 }
3901 
N6510_ReplySetGPRSAccessPoint1(GSM_Protocol_Message * msg,GSM_StateMachine * s)3902 static GSM_Error N6510_ReplySetGPRSAccessPoint1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3903 {
3904 	switch (msg->Buffer[13]) {
3905 	case 0x01:
3906 	case 0xD2:
3907 	case 0xF2:
3908 		memcpy(s->Phone.Data.Priv.N6510.GPRSPoints,msg->Buffer,msg->Length);
3909 		s->Phone.Data.Priv.N6510.GPRSPointsLength = msg->Length;
3910 		return ERR_NONE;
3911 	}
3912 	return ERR_UNKNOWNRESPONSE;
3913 }
3914 
N6510_SetGPRSAccessPoint(GSM_StateMachine * s,GSM_GPRSAccessPoint * point)3915 static GSM_Error N6510_SetGPRSAccessPoint(GSM_StateMachine *s, GSM_GPRSAccessPoint *point)
3916 {
3917 	unsigned char	*buff = s->Phone.Data.Priv.N6510.GPRSPoints;
3918 	GSM_Error	error;
3919 	unsigned char 	URL[] = {
3920 		N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3921 		0x00, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00};
3922 	unsigned char 	Name[] = {
3923 		N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3924 		0x01, 0x00, 0x00, 0x00, 0xD2, 0x00, 0x00};
3925 	unsigned char 	Active[] = {
3926 		N7110_FRAME_HEADER, 0x05, 0x00, 0x00, 0x00, 0x2C, 0x00,
3927 		0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
3928 
3929 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOGPRSPOINT)) return ERR_NOTSUPPORTED;
3930 	if (point->Location < 1) return ERR_UNKNOWN;
3931 	if (point->Location > 5) return ERR_INVALIDLOCATION;
3932 
3933 	s->Phone.Data.GPRSPoint = point;
3934 
3935 	smprintf(s, "Getting GPRS access point name\n");
3936 	error=GSM_WaitFor (s, Name, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3937 	if (error != ERR_NONE) return error;
3938 	CopyUnicodeString(buff+18+(point->Location-1)*42,point->Name);
3939 	buff[0] = 0x00;
3940 	buff[1] = 0x01;
3941 	buff[2] = 0x01;
3942 	buff[3] = 0x07;
3943 	smprintf(s, "Setting GPRS access point name\n");
3944 	error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3945 	if (error != ERR_NONE) return error;
3946 
3947 	smprintf(s, "Getting GPRS access point URL\n");
3948 	error=GSM_WaitFor (s, URL, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3949 	if (error != ERR_NONE) return error;
3950 	CopyUnicodeString(buff+18+(point->Location-1)*42,point->URL);
3951 	buff[0] = 0x00;
3952 	buff[1] = 0x01;
3953 	buff[2] = 0x01;
3954 	buff[3] = 0x07;
3955 	smprintf(s, "Setting GPRS access point URL\n");
3956 	error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3957 	if (error != ERR_NONE) return error;
3958 
3959 	if (point->Active) {
3960 		smprintf(s, "Getting number of active GPRS access point\n");
3961 		error=GSM_WaitFor (s, Active, 16, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3962 		if (error != ERR_NONE) return error;
3963 		buff[0] = 0x00;
3964 		buff[1] = 0x01;
3965 		buff[2] = 0x01;
3966 		buff[3] = 0x07;
3967 		buff[18]= point->Location;
3968 		smprintf(s, "Setting number of active GPRS access point\n");
3969 		error=GSM_WaitFor (s, buff, s->Phone.Data.Priv.N6510.GPRSPointsLength, 0x43, s->Phone.Data.Priv.N6510.Timeout, ID_SetGPRSPoint);
3970 		if (error != ERR_NONE) return error;
3971 	}
3972 
3973 	return error;
3974 }
3975 
N6510_ReplyGetLocale(GSM_Protocol_Message * msg,GSM_StateMachine * s)3976 static GSM_Error N6510_ReplyGetLocale(GSM_Protocol_Message *msg, GSM_StateMachine *s)
3977 {
3978 	GSM_Locale *locale = s->Phone.Data.Locale;
3979 
3980 	switch (msg->Buffer[3]) {
3981 	case 0x8A:
3982 		smprintf(s, "Date settings received\n");
3983 		switch (msg->Buffer[4]) {
3984 		case 0x00:
3985 			locale->DateFormat 	= GSM_Date_DDMMYYYY;
3986 			locale->DateSeparator 	= '.';
3987 			break;
3988 		case 0x01:
3989 			locale->DateFormat 	= GSM_Date_MMDDYYYY;
3990 			locale->DateSeparator 	= '.';
3991 			break;
3992 		case 0x02:
3993 			locale->DateFormat 	= GSM_Date_YYYYMMDD;
3994 			locale->DateSeparator 	= '.';
3995 			break;
3996 		case 0x04:
3997 			locale->DateFormat 	= GSM_Date_DDMMYYYY;
3998 			locale->DateSeparator 	= '/';
3999 			break;
4000 		case 0x05:
4001 			locale->DateFormat 	= GSM_Date_MMDDYYYY;
4002 			locale->DateSeparator 	= '/';
4003 			break;
4004 		case 0x06:
4005 			locale->DateFormat 	= GSM_Date_YYYYMMDD;
4006 			locale->DateSeparator 	= '/';
4007 			break;
4008 		case 0x08:
4009 			locale->DateFormat 	= GSM_Date_DDMMYYYY;
4010 			locale->DateSeparator 	= '-';
4011 			break;
4012 		case 0x09:
4013 			locale->DateFormat 	= GSM_Date_MMDDYYYY;
4014 			locale->DateSeparator 	= '-';
4015 			break;
4016 		case 0x0A:
4017 			locale->DateFormat 	= GSM_Date_YYYYMMDD;
4018 			locale->DateSeparator 	= '-';
4019 			break;
4020 		default:/* FIXME */
4021 			locale->DateFormat 	= GSM_Date_DDMMYYYY;
4022 			locale->DateSeparator 	= '/';
4023 			break;
4024 		}
4025 		return ERR_NONE;
4026 	}
4027 	return ERR_UNKNOWNRESPONSE;
4028 }
4029 
N6510_GetLocale(GSM_StateMachine * s,GSM_Locale * locale)4030 static GSM_Error N6510_GetLocale(GSM_StateMachine *s, GSM_Locale *locale)
4031 {
4032 	unsigned char req[] = {N6110_FRAME_HEADER, 0x89};
4033 
4034 	s->Phone.Data.Locale = locale;
4035 
4036 	smprintf(s, "Getting date format\n");
4037 	return GSM_WaitFor (s, req, 4, 0x13, s->Phone.Data.Priv.N6510.Timeout, ID_GetLocale);
4038 }
4039 
N6510_CancelCall(GSM_StateMachine * s,int ID,gboolean all)4040 GSM_Error N6510_CancelCall(GSM_StateMachine *s, int ID, gboolean all)
4041 {
4042 	if (all) return ERR_NOTSUPPORTED;
4043 	return DCT3DCT4_CancelCall(s,ID);
4044 }
4045 
N6510_AnswerCall(GSM_StateMachine * s,int ID,gboolean all)4046 GSM_Error N6510_AnswerCall(GSM_StateMachine *s, int ID, gboolean all)
4047 {
4048 	if (all) return ERR_NOTSUPPORTED;
4049 	return DCT3DCT4_AnswerCall(s,ID);
4050 }
4051 
N6510_ReplyAddSMSFolder(GSM_Protocol_Message * msg,GSM_StateMachine * s)4052 static GSM_Error N6510_ReplyAddSMSFolder(GSM_Protocol_Message *msg, GSM_StateMachine *s)
4053 {
4054 	smprintf(s,"SMS folder \"%s\" has been added\n",DecodeUnicodeString(msg->Buffer+10));
4055 	return ERR_NONE;
4056 }
4057 
N6510_AddSMSFolder(GSM_StateMachine * s,unsigned char * name)4058 GSM_Error N6510_AddSMSFolder(GSM_StateMachine *s, unsigned char *name)
4059 {
4060 	unsigned char req[200] = {N6110_FRAME_HEADER, 0x10, 0x01, 0x00, 0x01,
4061 			          0x00,     		/* Length */
4062 				  0x00, 0x00};
4063 
4064 	CopyUnicodeString(req+10,name);
4065 	req[7] = UnicodeLength(name)*2 + 6;
4066 
4067 	smprintf(s, "Adding SMS folder\n");
4068 	return GSM_WaitFor (s, req, req[7] + 6, 0x14, s->Phone.Data.Priv.N6510.Timeout, ID_AddSMSFolder);
4069 }
4070 
N6510_SetWAPBookmark(GSM_StateMachine * s,GSM_WAPBookmark * bookmark)4071 static GSM_Error N6510_SetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
4072 {
4073 	GSM_Error 	error;
4074 	int 		count=4, location;
4075 	unsigned char 	req[600] = {N6110_FRAME_HEADER, 0x09};
4076 
4077 	/* We have to enable WAP frames in phone */
4078 	error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS);
4079 	if (error!=ERR_NONE) return error;
4080 
4081 	location = bookmark->Location - 1;
4082 	if (bookmark->Location == 0) location = 0xffff;
4083 	req[count++] = (location & 0xff00) >> 8;
4084 	req[count++] = location & 0x00ff;
4085 
4086 	count += NOKIA_SetUnicodeString(s, req+count, bookmark->Title,   TRUE);
4087 	count += NOKIA_SetUnicodeString(s, req+count, bookmark->Address, TRUE);
4088 
4089 	req[count++] = 0x00;
4090 	req[count++] = 0x00;
4091 	req[count++] = 0x00;
4092 	req[count++] = 0x00;
4093 
4094 	smprintf(s, "Setting WAP bookmark\n");
4095 	error = GSM_WaitFor (s, req, count, 0x3f, s->Phone.Data.Priv.N6510.Timeout, ID_SetWAPBookmark);
4096 	if (error != ERR_NONE) {
4097 		if (error == ERR_INSIDEPHONEMENU || error == ERR_EMPTY || error == ERR_FULL) {
4098 			DCT3DCT4_DisableConnectionFunctions(s);
4099 		}
4100 		return error;
4101 	}
4102 
4103 	return DCT3DCT4_DisableConnectionFunctions(s);
4104 }
4105 
N6510_DeleteWAPBookmark(GSM_StateMachine * s,GSM_WAPBookmark * bookmark)4106 GSM_Error N6510_DeleteWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
4107 {
4108 	GSM_Error error;
4109 
4110 	/* We have to enable WAP frames in phone */
4111 	error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS);
4112 	if (error!=ERR_NONE) return error;
4113 
4114 	return DCT3DCT4_DeleteWAPBookmarkPart(s,bookmark);
4115 }
4116 
N6510_GetWAPBookmark(GSM_StateMachine * s,GSM_WAPBookmark * bookmark)4117 GSM_Error N6510_GetWAPBookmark(GSM_StateMachine *s, GSM_WAPBookmark *bookmark)
4118 {
4119 	GSM_Error error;
4120 
4121 	if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) return ERR_NOTSUPPORTED;
4122 
4123 	/* We have to enable WAP frames in phone */
4124 	error=N6510_EnableConnectionFunctions(s,N6510_WAP_SETTINGS);
4125 	if (error!=ERR_NONE) return error;
4126 
4127 	return DCT3DCT4_GetWAPBookmarkPart(s,bookmark);
4128 }
4129 
DCT4_ReplyGetScreenDump(GSM_Protocol_Message * msg,GSM_StateMachine * s)4130 static GSM_Error DCT4_ReplyGetScreenDump(GSM_Protocol_Message *msg, GSM_StateMachine *s)
4131 {
4132 	int len;
4133 
4134 	/* Data is at offset 10 */
4135 
4136 	len = msg->Buffer[7] | (msg->Buffer[6] << 8);
4137 	smprintf(s, "Received screenshot part, length %d\n", len);
4138 	s->Phone.Data.Picture->Buffer = realloc(s->Phone.Data.Picture->Buffer, s->Phone.Data.Picture->Length + len);
4139 	if (s->Phone.Data.Picture->Buffer == NULL) {
4140 		return ERR_MOREMEMORY;
4141 	}
4142 	memcpy(s->Phone.Data.Picture->Buffer + s->Phone.Data.Picture->Length, msg->Buffer + 10, len);
4143 	s->Phone.Data.Picture->Length += len;
4144 	if (len < 500) {
4145 		return ERR_NONE;
4146 	}
4147 	return ERR_NEEDANOTHERANSWER;
4148 }
4149 
DCT4_ReplyGetScreenInfo(GSM_Protocol_Message * msg,GSM_StateMachine * s)4150 static GSM_Error DCT4_ReplyGetScreenInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
4151 {
4152 	s->Phone.Data.Priv.N6510.ScreenWidth = msg->Buffer[5] | (msg->Buffer[4] << 8);
4153 	s->Phone.Data.Priv.N6510.ScreenHeight = msg->Buffer[7] | (msg->Buffer[6] << 8);
4154 	smprintf(s, "Screen size %dx%d\n", s->Phone.Data.Priv.N6510.ScreenWidth, s->Phone.Data.Priv.N6510.ScreenHeight);
4155 
4156 	return ERR_NONE;
4157 }
4158 
DCT4_Screenshot(GSM_StateMachine * s,GSM_BinaryPicture * picture)4159 GSM_Error DCT4_Screenshot(GSM_StateMachine *s, GSM_BinaryPicture *picture)
4160 {
4161 	unsigned char req_data[] = {N6110_FRAME_HEADER, 0x07, 0x01, 0x00};
4162 	unsigned char req_screen[] = {N6110_FRAME_HEADER, 0x06, 0x01, 0x00};
4163 	unsigned char bmp_header[] = {0x42, 0x4D, /* BMP magic "BM" */
4164 				0, 0, 0, 0, /* Size of BMP in bytes */
4165 				0, 0, 0, 0, /* reserved */
4166 				0x7a, 0, 0, 0 , /* Offset of data */
4167 				0x6c, 0, 0, 0, /* Size of header */
4168 				0, 0, 0, 0, /* width */
4169 				0, 0, 0, 0, /* height */
4170 				1, 0, /* color planes */
4171 				32, 0, /* bpp */
4172 				3, 0, 0, 0, /* compression, BI_BITFIELDS */
4173 				32, 0, 0, 0, /* Size of image pixel */
4174 				0x13,0x0b,0x00,0x00, /* XPelsPerMeter */
4175 				0x13,0x0b,0x00,0x00, /* YPelsPerMeter */
4176 				0, 0, 0, 0, /* palette */
4177 				0, 0, 0, 0, /* important colors */
4178 				0, 0xFF, 0, 0, /* red mask */
4179 				0, 0, 0xFF, 0, /* green mask */
4180 				0, 0, 0, 0xFF, /* blue mask */
4181 				0xFF, 0, 0, 0, /* alpha mask */
4182 				0x20, 0x6E, 0x69, 0x57, /* LCS_WINDOWS_COLOR_SPACE */
4183 				0, 0, 0, 0, /* CIEXYZTRIPLE */
4184 				0, 0, 0, 0,
4185 				0, 0, 0, 0,
4186 				0, 0, 0, 0,
4187 				0, 0, 0, 0,
4188 				0, 0, 0, 0,
4189 				0, 0, 0, 0,
4190 				0, 0, 0, 0,
4191 				0, 0, 0, 0,
4192 				0, 0, 0, 0, /* red gamma */
4193 				0, 0, 0, 0, /* green gamma */
4194 				0, 0, 0, 0, /* blue gamma */
4195 	};
4196 	GSM_Error error;
4197 	int tmp;
4198 
4199 	/* Get screen size */
4200 	error = GSM_WaitFor(s, req_screen, 6, 0x0E, 4, ID_GetScreenSize);
4201 	if (error != ERR_NONE) {
4202 		return error;
4203 	}
4204 
4205 	/* Allocate buffer */
4206 	s->Phone.Data.Picture = picture;
4207 	picture->Type = PICTURE_BMP;
4208 	picture->Buffer = malloc(sizeof(bmp_header));
4209 	if (picture->Buffer == NULL) {
4210 		return ERR_MOREMEMORY;
4211 	}
4212 	memcpy(picture->Buffer, bmp_header, sizeof(bmp_header));
4213 	picture->Length = sizeof(bmp_header);
4214 
4215 	/* Fill BMP header */
4216 #define STORE_INT(data, pos) picture->Buffer[pos] = data & 0xff; picture->Buffer[pos + 1] = (data >> 8) & 0xff; picture->Buffer[pos + 2] = (data >> 16) & 0xff; picture->Buffer[pos + 3] = (data >> 24) & 0xff;
4217 	/* Size */
4218 	tmp = 0x7a + (s->Phone.Data.Priv.N6510.ScreenWidth * s->Phone.Data.Priv.N6510.ScreenHeight * 4);
4219 	STORE_INT(tmp, 2);
4220 	tmp = s->Phone.Data.Priv.N6510.ScreenWidth;
4221 	STORE_INT(tmp, 18);
4222 	tmp = -s->Phone.Data.Priv.N6510.ScreenHeight;
4223 	STORE_INT(tmp, 22);
4224 
4225 	/* And fill in bitmap */
4226 	return  GSM_WaitFor(s, req_data, 6, 0x0E, 4, ID_Screenshot);
4227 }
4228 
4229 
4230 static GSM_Reply_Function N6510ReplyFunctions[] = {
4231 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x02,ID_IncomingFrame	  },
4232 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x03,ID_IncomingFrame	  },
4233 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x04,ID_IncomingFrame	  },
4234 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x05,ID_IncomingFrame	  },
4235 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x07,ID_AnswerCall	  },
4236 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x07,ID_IncomingFrame	  },
4237 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x09,ID_CancelCall	  },
4238 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x09,ID_IncomingFrame	  },
4239 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x0A,ID_IncomingFrame	  },
4240 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x0B,ID_IncomingFrame	  },
4241 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x0C,ID_DialVoice		  },
4242 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x0C,ID_IncomingFrame	  },
4243 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x0F,ID_IncomingFrame	  },
4244 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x10,ID_DialVoice		  },
4245 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x10,ID_IncomingFrame	  },
4246 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x23,ID_IncomingFrame	  },
4247 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x25,ID_IncomingFrame	  },
4248 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x27,ID_IncomingFrame	  },
4249 	{N71_65_ReplySendDTMF,		  "\x01",0x03,0x51,ID_SendDTMF		  },
4250 	{N71_65_ReplySendDTMF,		  "\x01",0x03,0xf0,ID_SendDTMF		  },
4251 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0x53,ID_IncomingFrame	  },
4252 	{N71_65_ReplySendDTMF,		  "\x01",0x03,0x59,ID_SendDTMF		  },
4253 	{N71_65_ReplySendDTMF,		  "\x01",0x03,0x5E,ID_SendDTMF		  },
4254 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0xA6,ID_IncomingFrame	  },
4255 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0xD2,ID_IncomingFrame	  },
4256 	{N71_65_ReplyCallInfo,		  "\x01",0x03,0xD3,ID_IncomingFrame	  },
4257 	{N6510_ReplyPressKey,		  "\x01",0x03,0x33,ID_PressKey		  },
4258 	{N6510_ReplyPressKey,		  "\x01",0x03,0x12,ID_PressKey		  },
4259 
4260 	{N6510_ReplySendSMSMessage,	  "\x02",0x03,0x03,ID_IncomingFrame	  },
4261 	{N6510_ReplyIncomingSMS,	  "\x02",0x03,0x04,ID_IncomingFrame	  },
4262 	{N6510_ReplySetSMSC,		  "\x02",0x03,0x13,ID_SetSMSC		  },
4263 	{N6510_ReplyGetSMSC,		  "\x02",0x03,0x15,ID_GetSMSC		  },
4264 	{N6510_ReplyIncomingCB,		  "\x02",0x03,0x21,ID_IncomingFrame	  },
4265 	{N6510_ReplyIncomingCB,		  "\x02",0x03,0x22,ID_IncomingFrame	  },
4266 	{N6510_ReplyIncomingCB,		  "\x02",0x03,0x23,ID_IncomingFrame	  },
4267 
4268 	{N6510_ReplyGetMemoryStatus,	  "\x03",0x03,0x04,ID_GetMemoryStatus	  },
4269 	{N6510_ReplyGetMemory,		  "\x03",0x03,0x08,ID_GetMemory		  },
4270 	{N71_65_ReplyWritePhonebook,	  "\x03",0x03,0x0C,ID_SetBitmap		  },
4271 	{N71_65_ReplyWritePhonebook,	  "\x03",0x03,0x0C,ID_SetMemory		  },
4272 	{N6510_ReplyDeleteMemory,	  "\x03",0x03,0x10,ID_SetMemory		  },
4273 
4274 	{DCT3DCT4_ReplyCallDivert,	  "\x06",0x03,0x02,ID_Divert		  },
4275 	{N71_65_ReplyUSSDInfo,		  "\x06",0x03,0x03,ID_IncomingFrame	  },
4276 	{NoneReply,			  "\x06",0x03,0x06,ID_IncomingFrame	  },
4277 	{NoneReply,			  "\x06",0x03,0x09,ID_IncomingFrame	  },
4278 
4279 	{N6510_ReplyEnterSecurityCode,	  "\x08",0x03,0x08,ID_EnterSecurityCode	  },
4280 	{N6510_ReplyEnterSecurityCode,	  "\x08",0x03,0x09,ID_EnterSecurityCode	  },
4281 	{N6510_ReplyGetSecurityStatus,	  "\x08",0x03,0x12,ID_GetSecurityStatus	  },
4282 	{N6510_ReplyGetSecurityStatus,	  "\x08",0x03,0xf0,ID_GetSecurityStatus	  },
4283 
4284 	{N6510_ReplyGetNetworkInfo,	  "\x0A",0x03,0x01,ID_GetNetworkInfo	  },
4285 	{N6510_ReplyGetNetworkInfo,	  "\x0A",0x03,0xf0,ID_GetNetworkInfo	  },
4286 	{N6510_ReplyGetSignalQuality,	  "\x0A",0x03,0x0C,ID_GetSignalQuality	  },
4287 	{N6510_ReplyGetOperatorLogo,	  "\x0A",0x03,0x24,ID_GetBitmap		  },
4288 	{N6510_ReplyGetOperatorLogo,	  "\x0A",0x03,0xf0,ID_GetBitmap		  },
4289 	{N6510_ReplySetOperatorLogo,	  "\x0A",0x03,0x26,ID_SetBitmap		  },
4290 	/* This needs to be last of type */
4291 	{N6510_ReplyGetNetworkInfo,	  "\x0A",0x03,0x01,ID_IncomingFrame	  },
4292 	{N6510_ReplyLogIntoNetwork,	  "\x0A",0x03,0x02,ID_IncomingFrame	  },
4293 	{NoneReply,			  "\x0A",0x03,0x16,ID_IncomingFrame	  },
4294 	{N6510_ReplyGetIncSignalQuality,  "\x0A",0x03,0x1E,ID_IncomingFrame	  },
4295 	{NoneReply,			  "\x0A",0x03,0x20,ID_IncomingFrame	  },
4296 	{N6510_ReplyGetNetworkInfo,	  "\x0A",0x03,0xf0,ID_IncomingFrame	  },
4297 
4298 	{NoneReply,			  "\x0B",0x03,0x01,ID_PlayTone		  },
4299 	{NoneReply,			  "\x0B",0x03,0x15,ID_PlayTone		  },
4300 	{NoneReply,			  "\x0B",0x03,0x16,ID_PlayTone		  },
4301 
4302 	{N71_65_ReplyAddCalendar1,	  "\x13",0x03,0x02,ID_SetCalendarNote	  },
4303 	{N71_65_ReplyAddCalendar1,	  "\x13",0x03,0x04,ID_SetCalendarNote	  },
4304 	{N71_65_ReplyAddCalendar1,	  "\x13",0x03,0x06,ID_SetCalendarNote	  },
4305 	{N71_65_ReplyAddCalendar1,	  "\x13",0x03,0x08,ID_SetCalendarNote	  },
4306 	{N71_65_ReplyDelCalendar,	  "\x13",0x03,0x0C,ID_DeleteCalendarNote  },
4307 	{N71_65_ReplyDelCalendar,	  "\x13",0x03,0xF0,ID_DeleteCalendarNote  },
4308 	{N71_65_ReplyGetNextCalendar1,	  "\x13",0x03,0x1A,ID_GetCalendarNote	  },/*method 1*/
4309 	{N6510_ReplyGetCalendarNotePos,	  "\x13",0x03,0x32,ID_GetCalendarNotePos  },/*method 1*/
4310 	{N6510_ReplyGetCalendarNotePos,	  "\x13",0x03,0xF0,ID_GetCalendarNotePos  },/*method 1*/
4311 	{N6510_ReplyGetCalendarInfo,	  "\x13",0x03,0x3B,ID_GetCalendarNotesInfo},/*method 1*/
4312 #ifdef DEBUG
4313 	{N71_65_ReplyGetNextCalendar2,	  "\x13",0x03,0x3F,ID_GetCalendarNote	  },
4314 #endif
4315 	{N71_65_ReplyAddCalendar2,	  "\x13",0x03,0x41,ID_SetCalendarNote	  },/*method 2*/
4316 	{N6510_ReplyAddCalendar3,	  "\x13",0x03,0x66,ID_SetCalendarNote	  },/*method 3*/
4317 	{N6510_ReplyAddToDo2,		  "\x13",0x03,0x66,ID_SetToDo		  },
4318 	{N6510_ReplyAddNote,		  "\x13",0x03,0x66,ID_SetNote		  },
4319 	{N6510_ReplyGetCalendar3,	  "\x13",0x03,0x7E,ID_GetCalendarNote	  },/*method 3*/
4320 	{N6510_ReplyGetToDo2,		  "\x13",0x03,0x7E,ID_GetToDo		  },
4321 	{N6510_ReplyGetNote,		  "\x13",0x03,0x7E,ID_GetNote		  },
4322 	{N6510_ReplyGetCalendarSettings,  "\x13",0x03,0x86,ID_GetCalendarSettings },
4323 	{N6510_ReplyGetLocale,		  "\x13",0x03,0x8A,ID_GetLocale		  },
4324 	{N6510_ReplyGetCalendarSettings,  "\x13",0x03,0x8E,ID_GetCalendarSettings },
4325 	{N6510_ReplyGetCalendarNotePos,	  "\x13",0x03,0x96,ID_GetCalendarNotePos  },/*method 3*/
4326 	{N6510_ReplyGetToDoFirstLoc2,	  "\x13",0x03,0x96,ID_SetToDo		  },
4327 	{N6510_ReplyGetNoteFirstLoc,	  "\x13",0x03,0x96,ID_SetNote		  },
4328 	{N6510_ReplyGetCalendarInfo,	  "\x13",0x03,0x9F,ID_GetCalendarNotesInfo},/*method 3*/
4329 	{N6510_ReplyGetToDoStatus2,	  "\x13",0x03,0x9F,ID_GetToDo		  },
4330 	{N6510_ReplyGetNoteInfo,	  "\x13",0x03,0x9F,ID_GetNote		  },
4331 
4332 	{N6510_ReplySaveSMSMessage,	  "\x14",0x03,0x01,ID_SaveSMSMessage	  },
4333 	{N6510_ReplySetPicture,		  "\x14",0x03,0x01,ID_SetBitmap		  },
4334 	{N6510_ReplyGetSMSMessage,	  "\x14",0x03,0x03,ID_GetSMSMessage	  },
4335 	{N6510_ReplyDeleteSMSMessage,	  "\x14",0x03,0x05,ID_DeleteSMSMessage	  },
4336 	{N6510_ReplyDeleteSMSMessage,	  "\x14",0x03,0x06,ID_DeleteSMSMessage	  },
4337 	{N6510_ReplyGetSMSStatus,	  "\x14",0x03,0x09,ID_GetSMSStatus	  },
4338 	{N6510_ReplyGetSMSFolderStatus,	  "\x14",0x03,0x0d,ID_GetSMSFolderStatus  },
4339 	{N6510_ReplyGetSMSMessage,	  "\x14",0x03,0x0f,ID_GetSMSMessage	  },
4340 	{N6510_ReplyAddSMSFolder,	  "\x14",0x03,0x11,ID_AddSMSFolder	  },
4341 	{N6510_ReplyGetSMSFolders,	  "\x14",0x03,0x13,ID_GetSMSFolders	  },
4342 	{N6510_ReplySaveSMSMessage,	  "\x14",0x03,0x17,ID_SaveSMSMessage	  },
4343 	{N6510_ReplyGetSMSStatus,	  "\x14",0x03,0x1a,ID_GetSMSStatus	  },
4344 	{N6510_ReplyGetSMSStatus,	  "\x14",0x03,0xf0,ID_GetSMSStatus	  },
4345 
4346 	{DCT4_ReplySetPhoneMode,	  "\x15",0x03,0x64,ID_Reset		  },
4347 	{DCT4_ReplyGetPhoneMode,	  "\x15",0x03,0x65,ID_Reset		  },
4348 	{NoneReply,		  	  "\x15",0x03,0x68,ID_Reset		  },
4349 
4350 	{N6510_ReplyGetBatteryCharge,	  "\x17",0x03,0x0B,ID_GetBatteryCharge	  },
4351 	{N6510_IncomingBatteryCharge,	  "\x17",0x03,0x2c,ID_IncomingFrame	  },
4352 
4353 	{N6510_ReplySetDateTime,	  "\x19",0x03,0x02,ID_SetDateTime	  },
4354 	{N6510_ReplyGetDateTime,	  "\x19",0x03,0x0B,ID_GetDateTime	  },
4355 	{N6510_ReplySetAlarm,		  "\x19",0x03,0x12,ID_SetAlarm		  },
4356 	{N6510_ReplyGetAlarm,		  "\x19",0x03,0x1A,ID_GetAlarm		  },
4357 	{N6510_ReplyGetAlarm,		  "\x19",0x03,0x20,ID_GetAlarm		  },
4358 
4359 	{DCT4_ReplyGetIMEI,		  "\x1B",0x03,0x01,ID_GetIMEI		  },
4360 	{NOKIA_ReplyGetPhoneString,	  "\x1B",0x03,0x08,ID_GetHardware	  },
4361 	{N6510_ReplyGetPPM,		  "\x1B",0x03,0x08,ID_GetPPM		  },
4362 	{NOKIA_ReplyGetPhoneString,	  "\x1B",0x03,0x0C,ID_GetProductCode	  },
4363 
4364 	/* 0x1C - vibra */
4365 
4366 	{N6510_ReplyGetRingtonesInfo,	  "\x1f",0x03,0x08,ID_GetRingtonesInfo	  },
4367 	{N6510_ReplyDeleteRingtones,	  "\x1f",0x03,0x11,ID_SetRingtone	  },
4368 	{N6510_ReplyGetRingtone,	  "\x1f",0x03,0x13,ID_GetRingtone	  },
4369 	{N6510_ReplySetBinRingtone,	  "\x1f",0x03,0x0F,ID_SetRingtone	  },
4370 
4371 	/* 0x23 - voice records */
4372 
4373 	{N6510_ReplyGetProfile,		  "\x39",0x03,0x02,ID_GetProfile	  },
4374 	{N6510_ReplySetProfile,		  "\x39",0x03,0x04,ID_SetProfile	  },
4375 	{N6510_ReplyGetProfile,		  "\x39",0x03,0x06,ID_GetProfile	  },
4376 
4377 	{N6510_ReplySetLight,		  "\x3A",0x03,0x06,ID_SetLight		  },
4378 
4379  	{N6510_ReplyGetFMStation,	  "\x3E",0x03,0x06,ID_GetFMStation	  },
4380  	{N6510_ReplyGetFMStatus,	  "\x3E",0x03,0x0E,ID_GetFMStation	  },
4381  	{N6510_ReplySetFMStation,	  "\x3E",0x03,0x15,ID_SetFMStation	  },
4382  	{N6510_ReplyGetFMStation,	  "\x3E",0x03,0x16,ID_GetFMStation	  },
4383  	{N6510_ReplyGetFMStation,	  "\x3E",0x03,0xF0,ID_GetFMStation	  },
4384 
4385 	{DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x01,ID_EnableConnectFunc	  },
4386 	{DCT3DCT4_ReplyEnableConnectFunc, "\x3f",0x03,0x02,ID_EnableConnectFunc	  },
4387 	{DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x04,ID_DisableConnectFunc  },
4388 	{DCT3DCT4_ReplyDisableConnectFunc,"\x3f",0x03,0x05,ID_DisableConnectFunc  },
4389 	{N6510_ReplyGetWAPBookmark,	  "\x3f",0x03,0x07,ID_GetWAPBookmark	  },
4390 	{N6510_ReplyGetWAPBookmark,	  "\x3f",0x03,0x08,ID_GetWAPBookmark	  },
4391 	{DCT3DCT4_ReplySetWAPBookmark,	  "\x3f",0x03,0x0A,ID_SetWAPBookmark	  },
4392 	{DCT3DCT4_ReplySetWAPBookmark,	  "\x3f",0x03,0x0B,ID_SetWAPBookmark	  },
4393 	{DCT3DCT4_ReplyDelWAPBookmark,	  "\x3f",0x03,0x0D,ID_DeleteWAPBookmark	  },
4394 	{DCT3DCT4_ReplyDelWAPBookmark,	  "\x3f",0x03,0x0E,ID_DeleteWAPBookmark	  },
4395 	{DCT3DCT4_ReplyGetActiveConnectSet,"\x3f",0x03,0x10,ID_GetConnectSet	  },
4396 	{DCT3DCT4_ReplySetActiveConnectSet,"\x3f",0x03,0x13,ID_SetConnectSet	  },
4397 	{N6510_ReplyGetConnectionSettings,"\x3f",0x03,0x11,ID_GetConnectSet	  },
4398 	{N6510_ReplyGetConnectionSettings,"\x3f",0x03,0x16,ID_GetConnectSet	  },
4399 	{N6510_ReplyGetConnectionSettings,"\x3f",0x03,0x17,ID_GetConnectSet	  },
4400 	{N6510_ReplySetConnectionSettings,"\x3f",0x03,0x19,ID_SetConnectSet	  },
4401 	{N6510_ReplySetConnectionSettings,"\x3f",0x03,0x1A,ID_SetConnectSet	  },
4402 	{N6510_ReplySetConnectionSettings,"\x3f",0x03,0x28,ID_SetConnectSet	  },
4403 	{N6510_ReplySetConnectionSettings,"\x3f",0x03,0x2B,ID_SetConnectSet	  },
4404 	{N6510_ReplyGetChatSettings,	  "\x3f",0x03,0x3B,ID_GetChatSettings	  },
4405 	{N6510_ReplyGetChatSettings,	  "\x3f",0x03,0x3C,ID_GetChatSettings	  },
4406 	{N6510_ReplyGetConnectionSettings,"\x3f",0x03,0xf0,ID_GetConnectSet	  },
4407 
4408 	{N6510_ReplyGetOriginalIMEI,	  "\x42",0x07,0x00,ID_GetOriginalIMEI	  },
4409 	{N6510_ReplyGetManufactureMonth,  "\x42",0x07,0x00,ID_GetManufactureMonth },
4410 	{N6510_ReplyGetOriginalIMEI,	  "\x42",0x07,0x01,ID_GetOriginalIMEI	  },
4411 	{N6510_ReplyGetManufactureMonth,  "\x42",0x07,0x02,ID_GetManufactureMonth },
4412 
4413 	{N6510_ReplySetOperatorLogo,	  "\x43",0x03,0x08,ID_SetBitmap		  },
4414 	{N6510_ReplyGetGPRSAccessPoint,	  "\x43",0x03,0x06,ID_GetGPRSPoint	  },
4415 	{N6510_ReplySetGPRSAccessPoint1,  "\x43",0x03,0x06,ID_SetGPRSPoint	  },
4416 	{N6510_ReplyGetSyncMLSettings,	  "\x43",0x03,0x06,ID_GetSyncMLSettings	  },
4417 	{N6510_ReplyGetSyncMLName,	  "\x43",0x03,0x06,ID_GetSyncMLName	  },
4418 	{NoneReply,			  "\x43",0x03,0x08,ID_SetGPRSPoint	  },
4419 
4420 	/* 0x4A - voice records */
4421 
4422 	/* 0x53 - simlock */
4423 
4424 	{N6510_ReplyAddToDo1,		  "\x55",0x03,0x02,ID_SetToDo		  },
4425 	{N6510_ReplyGetToDo1,		  "\x55",0x03,0x04,ID_GetToDo		  },
4426 	{N6510_ReplyGetToDoFirstLoc1,	  "\x55",0x03,0x10,ID_SetToDo		  },
4427 	{N6510_ReplyDeleteAllToDo1,	  "\x55",0x03,0x12,ID_DeleteAllToDo	  },
4428 	{N6510_ReplyGetToDoStatus1,	  "\x55",0x03,0x16,ID_GetToDo		  },
4429 
4430 	{N6510_ReplyAddFileHeader1,	  "\x6D",0x03,0x03,ID_AddFile		  },
4431 	{N6510_ReplyAddFolder1,		  "\x6D",0x03,0x05,ID_AddFolder		  },
4432 	{N6510_ReplyGetFilePart12,	  "\x6D",0x03,0x0F,ID_GetFile		  },/* filesystem1&2 */
4433 	{N6510_ReplyAddFileHeader1,	  "\x6D",0x03,0x13,ID_AddFile		  },
4434 	{N6510_ReplyGetFileFolderInfo1,	  "\x6D",0x03,0x15,ID_GetFileInfo	  },
4435 	{NoneReply,			  "\x6D",0x03,0x19,ID_SetAttrib		  },
4436 	{N6510_ReplyDeleteFileFolder1,	  "\x6D",0x03,0x1F,ID_DeleteFile	  },
4437 	{N6510_ReplyGetFileSystemStatus1, "\x6D",0x03,0x23,ID_FileSystemStatus	  },
4438 	{N6510_ReplyGetFileFolderInfo1,	  "\x6D",0x03,0x2F,ID_GetFileInfo	  },
4439 	{N6510_ReplyGetFileSystemStatus1, "\x6D",0x03,0x2F,ID_FileSystemStatus	  },
4440 	{N6510_ReplyGetFileFolderInfo1,	  "\x6D",0x03,0x33,ID_GetFileInfo	  },
4441 	{N6510_ReplyGetFileFolderInfo1,	  "\x6D",0x03,0xF0,ID_GetFileInfo	  },
4442 	{N6510_ReplyAddFilePart1,	  "\x6D",0x03,0x41,ID_AddFile		  },
4443 	{N6510_ReplyGetFileCRC12,	  "\x6D",0x03,0x43,ID_GetCRC		  },
4444 	{NoneReply,			  "\x6D",0x03,0x59,ID_AddFile		  },/* filesystem2 */
4445 	{N6510_ReplyGetFilePart12,	  "\x6D",0x03,0x5F,ID_GetFile		  },/* filesystem2 */
4446 	{N6510_ReplyDeleteFile2,	  "\x6D",0x03,0x63,ID_DeleteFile	  },/* filesystem2 */
4447 	{N6510_ReplyAddFolder2,		  "\x6D",0x03,0x65,ID_AddFolder		  },/* filesystem2 */
4448 	{N6510_ReplyGetFileCRC12,   	  "\x6D",0x03,0x67,ID_GetCRC		  },/* filesystem2 */
4449 	{N6510_ReplyGetFileFolderInfo2,   "\x6D",0x03,0x69,ID_IncomingFrame	  },/* filesystem2 */
4450 	{N6510_ReplyDeleteFolder2,	  "\x6D",0x03,0x6B,ID_DeleteFolder	  },/* filesystem2 */
4451 	{N6510_ReplyGetFileFolderInfo2,   "\x6D",0x03,0x6D,ID_GetFileInfo	  },/* filesystem2 */
4452 	{N6510_ReplySetAttrib2,		  "\x6D",0x03,0x6F,ID_SetAttrib		  },/* filesystem2 */
4453 	{N6510_ReplyOpenFile2,		  "\x6D",0x03,0x73,ID_OpenFile		  },/* filesystem2 */
4454 	{NoneReply,			  "\x6D",0x03,0x75,ID_CloseFile		  },/* filesystem2 */
4455 	{N6510_ReplySetFileDate2,	  "\x6D",0x03,0x87,ID_AddFile		  },/* filesystem2 */
4456 
4457 	{N6510_ReplyStartupNoteLogo,	  "\x7A",0x04,0x01,ID_GetBitmap		  },
4458 	{N6510_ReplyStartupNoteLogo,	  "\x7A",0x04,0x01,ID_SetBitmap		  },
4459 	{N6510_ReplyStartupNoteLogo,	  "\x7A",0x04,0x0F,ID_GetBitmap		  },
4460 	{N6510_ReplyStartupNoteLogo,	  "\x7A",0x04,0x0F,ID_SetBitmap		  },
4461 	{N6510_ReplyStartupNoteLogo,	  "\x7A",0x04,0x10,ID_GetBitmap		  },
4462 	{N6510_ReplyStartupNoteLogo,	  "\x7A",0x04,0x10,ID_SetBitmap		  },
4463 	{N6510_ReplyStartupNoteLogo,	  "\x7A",0x04,0x25,ID_SetBitmap		  },
4464 
4465 	{DCT3DCT4_ReplyGetModelFirmware,  "\xD2",0x02,0x00,ID_GetModel		  },
4466 	{DCT3DCT4_ReplyGetModelFirmware,  "\xD2",0x02,0x00,ID_GetFirmware	  },
4467 
4468 	/* 0xD7 - Bluetooth */
4469 
4470 	{N6510_ReplyGetRingtoneID,	  "\xDB",0x03,0x02,ID_SetRingtone	  },
4471 
4472 	{DCT4_ReplyGetScreenDump,	  "\x0E",0x00,0x00,ID_Screenshot		},
4473 	{DCT4_ReplyGetScreenInfo,	  "\x0E",0x00,0x00,ID_GetScreenSize	  },
4474 
4475 	{NULL,				  "\x00",0x00,0x00,ID_None		  }
4476 };
4477 
4478 GSM_Phone_Functions N6510Phone = {
4479 	"1100|1100a|1100b|1112|1200|1209|1600|1650|1680|2600|2610|2630|2650|2660|2680|2760|3100|3100b|3105|3108|3109c|3200|3200a|3205|3220|3300|3510|3510i|3530|3589i|3590|3595|5000|5100|5140|5140i|5200|5220|5300|5310|6020|6020b|6021|6030|6060|6070|6085|6086|6100|6101|6103|6111|6125|6131|6151|6170|6200|6220|6220c|6225|6230|6230i|6233|6234|6270|6275i|6280|6300|6303c|6310|6310i|6340i|6385|6500c|6500s|6510|6600|6610|6610i|6800|6810|6820|6822|7200|7210|7210s|7230|7250|7250i|7260|7270|7360|7370|7500|7600|7900|8310|8390|8800|8910|8910i",
4480 	N6510ReplyFunctions,
4481 	NOTSUPPORTED,			/* 	Install			*/
4482 	N6510_Initialise,
4483 	N6510_Terminate,
4484 	GSM_DispatchMessage,
4485 	N6510_ShowStartInfo,
4486 	NOKIA_GetManufacturer,
4487 	DCT3DCT4_GetModel,
4488 	DCT3DCT4_GetFirmware,
4489 	DCT4_GetIMEI,
4490 	N6510_GetOriginalIMEI,
4491 	N6510_GetManufactureMonth,
4492 	DCT4_GetProductCode,
4493 	DCT4_GetHardware,
4494 	N6510_GetPPM,
4495 	NOTSUPPORTED,			/*	GetSIMIMSI		*/
4496 	N6510_GetDateTime,
4497 	N6510_SetDateTime,
4498 	N6510_GetAlarm,
4499 	N6510_SetAlarm,
4500 	N6510_GetLocale,
4501 	NOTSUPPORTED,			/* 	SetLocale		*/
4502 	N6510_PressKey,
4503 	DCT4_Reset,
4504 	NOTIMPLEMENTED,			/*	ResetPhoneSettings	*/
4505 	N6510_EnterSecurityCode,
4506 	N6510_GetSecurityStatus,
4507 	NOTSUPPORTED,			/*	GetDisplayStatus	*/
4508 	NOTIMPLEMENTED,			/*	SetAutoNetworkLogin	*/
4509 	N6510_GetBatteryCharge,
4510 	N6510_GetSignalQuality,
4511 	N6510_GetNetworkInfo,
4512 	NOTSUPPORTED,       		/*  	GetCategory 		*/
4513  	NOTSUPPORTED,       		/*  	AddCategory 		*/
4514 	NOTSUPPORTED,        		/*  	GetCategoryStatus 	*/
4515 	N6510_GetMemoryStatus,
4516 	N6510_GetMemory,
4517 	NOTIMPLEMENTED,			/*	GetNextMemory		*/
4518 	N6510_SetMemory,
4519 	N6510_AddMemory,
4520 	N6510_DeleteMemory,
4521 	NOTIMPLEMENTED,			/*	DeleteAllMemory		*/
4522 	N6510_GetSpeedDial,
4523 	NOTIMPLEMENTED,			/*	SetSpeedDial		*/
4524 	N6510_GetSMSC,
4525 	N6510_SetSMSC,
4526 	N6510_GetSMSStatus,
4527 	N6510_GetSMSMessage,
4528 	N6510_GetNextSMSMessage,
4529 	N6510_SetSMS,
4530 	N6510_AddSMS,
4531 	N6510_DeleteSMSMessage,
4532 	N6510_SendSMSMessage,
4533 	NOTSUPPORTED,			/*	SendSavedSMS		*/
4534 	NOTSUPPORTED,			/*	SetFastSMSSending	*/
4535 	NOKIA_SetIncomingSMS,
4536 	NOTIMPLEMENTED,			/* 	SetIncomingCB		*/
4537 	N6510_GetSMSFolders,
4538  	N6510_AddSMSFolder,
4539  	NOTIMPLEMENTED,			/* 	DeleteSMSFolder		*/
4540 	N6510_DialVoice,
4541         NOTIMPLEMENTED,			/*	DialService		*/
4542  	N6510_AnswerCall,
4543  	N6510_CancelCall,
4544  	NOTIMPLEMENTED,			/* 	HoldCall 		*/
4545  	NOTIMPLEMENTED,			/* 	UnholdCall 		*/
4546  	NOTIMPLEMENTED,			/* 	ConferenceCall 		*/
4547  	NOTIMPLEMENTED,			/* 	SplitCall		*/
4548  	NOTIMPLEMENTED,			/* 	TransferCall		*/
4549  	NOTIMPLEMENTED,			/* 	SwitchCall		*/
4550  	DCT3DCT4_GetCallDivert,
4551  	DCT3DCT4_SetCallDivert,
4552  	DCT3DCT4_CancelAllDiverts,
4553 	NOKIA_SetIncomingCall,
4554 	NOKIA_SetIncomingUSSD,
4555 	DCT3DCT4_SendDTMF,
4556 	N6510_GetRingtone,
4557 	N6510_SetRingtone,
4558 	N6510_GetRingtonesInfo,
4559 	N6510_DeleteUserRingtones,
4560 	N6510_PlayTone,
4561 	N6510_GetWAPBookmark,
4562 	N6510_SetWAPBookmark,
4563 	N6510_DeleteWAPBookmark,
4564 	N6510_GetWAPSettings,
4565 	N6510_SetWAPSettings,
4566 	N6510_GetSyncMLSettings,
4567 	NOTSUPPORTED,			/*	SetSyncMLSettings	*/
4568 	N6510_GetChatSettings,
4569 	NOTSUPPORTED,			/*	SetChatSettings		*/
4570 	N6510_GetMMSSettings,
4571 	N6510_SetMMSSettings,
4572 	N6510_GetMMSFolders,
4573 	N6510_GetNextMMSFileInfo,
4574 	N6510_GetBitmap,
4575 	N6510_SetBitmap,
4576 	N6510_GetToDoStatus,
4577 	NOTIMPLEMENTED,			/*	GetToDo			*/
4578 	N6510_GetNextToDo,
4579 	NOTIMPLEMENTED,			/*	SetToDo			*/
4580 	N6510_AddToDo,
4581 	N6510_DeleteToDo2,
4582 	N6510_DeleteAllToDo1,
4583 	N6510_GetCalendarStatus,
4584 	NOTIMPLEMENTED,			/*	GetCalendar		*/
4585     	N6510_GetNextCalendar,
4586 	NOTIMPLEMENTED,			/*	SetCalendar		*/
4587 	N6510_AddCalendar,
4588 	N71_65_DelCalendar,
4589 	NOTIMPLEMENTED,			/*	DeleteAllCalendar	*/
4590 	N6510_GetCalendarSettings,
4591 	NOTSUPPORTED,			/* 	SetCalendarSettings	*/
4592 	N6510_GetNoteStatus,
4593 	NOTIMPLEMENTED,			/*	GetNote			*/
4594 	N6510_GetNextNote,
4595 	NOTIMPLEMENTED,			/*	SetNote			*/
4596 	N6510_AddNote,
4597 	N6510_DeleteNote,
4598 	NOTSUPPORTED,			/*	DeleteAllNotes		*/
4599 	N6510_GetProfile,
4600 	N6510_SetProfile,
4601     	N6510_GetFMStation,
4602      	N6510_SetFMStation,
4603  	N6510_ClearFMStations,
4604 	N6510_GetNextFileFolder,
4605 	N6510_GetFolderListing,
4606 	N6510_GetNextRootFolder,
4607 	N6510_SetFileAttributes,
4608 	N6510_GetFilePart,
4609 	N6510_AddFilePart,
4610 	NOTSUPPORTED,			/* 	SendFilePart		*/
4611 	N6510_GetFileSystemStatus,
4612 	N6510_DeleteFile,
4613 	N6510_AddFolder,
4614 	N6510_DeleteFolder,
4615 	N6510_GetGPRSAccessPoint,
4616 	N6510_SetGPRSAccessPoint,
4617 	DCT4_Screenshot,
4618 	NOTSUPPORTED,			/* 	SetPower		*/
4619 	NOTSUPPORTED,			/* 	PostConnect	*/
4620 	NONEFUNCTION			/*	PreAPICall		*/
4621 };
4622 
4623 #endif
4624 
4625 /* How should editor hadle tabs in this file? Add editor commands here.
4626  * vim: noexpandtab sw=8 ts=8 sts=8:
4627  */
4628