1 /* (c) 2003 by Marcin Wiacek */
2
3 #include "../../../gsmstate.h"
4
5 #ifdef GSM_ENABLE_NOKIA3650
6
7 #include <string.h>
8 #include <time.h>
9
10 #include "../../../gsmcomon.h"
11 #include "../../../misc/coding/coding.h"
12 #include "../../../service/gsmlogo.h"
13 #include "../nfunc.h"
14 #include "../nfuncold.h"
15 #include "../../pfunc.h"
16 #include "../dct4s40/dct4func.h"
17 #include "n3650.h"
18
N3650_ReplyGetFilePart(GSM_Protocol_Message * msg,GSM_StateMachine * s)19 static GSM_Error N3650_ReplyGetFilePart(GSM_Protocol_Message *msg, GSM_StateMachine *s)
20 {
21 int old;
22
23 smprintf(s,"File part received\n");
24 old = s->Phone.Data.File->Used;
25
26 if (msg->Length < 10) {
27 if (old == 0) return ERR_UNKNOWN;
28 return ERR_EMPTY;
29 }
30
31 s->Phone.Data.File->Used += msg->Buffer[10]*256*256*256+
32 msg->Buffer[11]*256*256+
33 msg->Buffer[12]*256+
34 msg->Buffer[13];
35 smprintf(s,"Length: %i\n",
36 msg->Buffer[10]*256*256*256+
37 msg->Buffer[11]*256*256+
38 msg->Buffer[12]*256+
39 msg->Buffer[13]);
40 s->Phone.Data.File->Buffer = (unsigned char *)realloc(s->Phone.Data.File->Buffer,s->Phone.Data.File->Used);
41 memcpy(s->Phone.Data.File->Buffer+old,msg->Buffer+18,s->Phone.Data.File->Used-old);
42 if (s->Phone.Data.File->Used-old < 0x03 * 256 + 0xD4) return ERR_EMPTY;
43 return ERR_NONE;
44 }
45
N3650_GetFilePart(GSM_StateMachine * s,GSM_File * File,int * Handle UNUSED,size_t * Size)46 static GSM_Error N3650_GetFilePart(GSM_StateMachine *s, GSM_File *File, int *Handle UNUSED, size_t *Size)
47 {
48 unsigned int len=10,i;
49 GSM_Error error;
50 unsigned char *req;
51 unsigned const char StartReq[11] = {
52 N7110_FRAME_HEADER, 0x0D, 0x10, 0x01, 0x07,
53 0x24, /* len1 */
54 0x12, /* len2 */
55 0x0E, /* len3 */
56 0x00}; /* File name */
57 unsigned char ContinueReq[] = {
58 N7110_FRAME_HEADER, 0x0D, 0x20, 0x01, 0xF0,
59 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00};
60
61 if (File->Used == 0) {
62 req = malloc(strlen(File->ID_FullName) + 30);
63 if (req == NULL) {
64 return ERR_MOREMEMORY;
65 }
66 memcpy(req, StartReq, sizeof(StartReq));
67 (*Size) = 0;
68
69 sprintf(req+10,"%s",File->ID_FullName);
70 len+=strlen(File->ID_FullName)-1;
71 req[7] = strlen(File->ID_FullName) + 3;
72
73 req[8] = strlen(File->ID_FullName);
74 req[9] = 0;
75 while (File->ID_FullName[req[8]] != '\\') {
76 req[8]--;
77 req[9]++;
78 }
79 for (i=req[8];i<strlen(File->ID_FullName);i++) {
80 req[i+10] = req[i+1+10];
81 }
82 req[9]--;
83
84 EncodeUnicode(File->Name,File->ID_FullName+req[8]+1,req[9]);
85 File->Folder = FALSE;
86
87 error = DCT4_SetPhoneMode(s, DCT4_MODE_TEST);
88 if (error != ERR_NONE) return error;
89
90 s->Phone.Data.File = File;
91 return GSM_WaitFor (s, req, len, 0x58, 4, ID_GetFile);
92 }
93
94 s->Phone.Data.File = File;
95 error = GSM_WaitFor (s, ContinueReq, 14, 0x58, 4, ID_GetFile);
96
97 #if 0
98 if (error == GE_EMPTY) {
99 error = DCT4_SetPhoneMode(s, DCT4_MODE_NORMAL);
100 if (error != ERR_NONE) return error;
101 return GE_EMPTY;
102 }
103 #endif
104
105 return error;
106 }
107
N3650_ReplyGetFolderInfo(GSM_Protocol_Message * msg,GSM_StateMachine * s)108 static GSM_Error N3650_ReplyGetFolderInfo(GSM_Protocol_Message *msg, GSM_StateMachine *s)
109 {
110 GSM_File *File = s->Phone.Data.FileInfo;
111 GSM_Phone_N3650Data *Priv = &s->Phone.Data.Priv.N3650;
112 int i,pos = 6;
113
114 i = Priv->FilesLocationsUsed-1;
115 while (1) {
116 if (i==Priv->FilesLocationsCurrent-1) break;
117 smprintf(s, "Copying %i to %i, max %i, current %i\n",
118 i,i+msg->Buffer[5],
119 Priv->FilesLocationsUsed,Priv->FilesLocationsCurrent);
120 memcpy(Priv->Files[i+msg->Buffer[5]],Priv->Files[i],sizeof(GSM_File));
121 i--;
122 }
123 Priv->FileEntries = msg->Buffer[5];
124 Priv->FilesLocationsUsed += msg->Buffer[5];
125 for (i=0;i<msg->Buffer[5];i++) {
126 Priv->Files[Priv->FilesLocationsCurrent+i]->Folder = TRUE;
127 if (msg->Buffer[pos+2] == 0x01) {
128 Priv->Files[Priv->FilesLocationsCurrent+i]->Folder = FALSE;
129 smprintf(s,"File ");
130 }
131 EncodeUnicode(Priv->Files[Priv->FilesLocationsCurrent+i]->Name,msg->Buffer+pos+9,msg->Buffer[pos+8]);
132 smprintf(s,"%s\n",DecodeUnicodeString(Priv->Files[Priv->FilesLocationsCurrent+i]->Name));
133 Priv->Files[Priv->FilesLocationsCurrent+i]->Level = File->Level+1;
134 #if GSM_GNUC_PREREQ (7,0)
135 #pragma GCC diagnostic push
136 #pragma GCC diagnostic ignored "-Wformat-overflow"
137 #endif
138 /* Here we check limits before doing sprintf */
139 if (strlen(File->ID_FullName) + strlen(msg->Buffer+pos+9) + 20 >= sizeof(File->ID_FullName)) {
140 return ERR_MOREMEMORY;
141 }
142 sprintf(
143 Priv->Files[Priv->FilesLocationsCurrent+i]->ID_FullName,
144 "%s\\%s",
145 File->ID_FullName,
146 msg->Buffer + pos + 9
147 );
148 #if GSM_GNUC_PREREQ (7,0)
149 #pragma GCC diagnostic pop
150 #endif
151 pos += msg->Buffer[pos+1];
152 }
153 smprintf(s, "\n");
154 return ERR_NONE;
155 }
156
N3650_GetFolderInfo(GSM_StateMachine * s,GSM_File * File)157 static GSM_Error N3650_GetFolderInfo(GSM_StateMachine *s, GSM_File *File)
158 {
159 int len=10;
160 unsigned char *req;
161 unsigned const char template[11] = {
162 N7110_FRAME_HEADER, 0x0B, 0x00, 0x01, 0x07,
163 0x18, /* folder name length + 6 */
164 0x12, /* folder name length */
165 0x00,
166 0x00}; /* folder name */
167
168 req = malloc(strlen(File->ID_FullName) + 30);
169 if (req == NULL) {
170 return ERR_MOREMEMORY;
171 }
172 memcpy(req, template, sizeof(template));
173
174 /* FIXME: I doubt this works */
175 sprintf(req+10,"%s", File->ID_FullName);
176 len +=strlen(File->ID_FullName);
177 req[7] = strlen(File->ID_FullName) + 6;
178 req[8] = strlen(File->ID_FullName);
179 req[len++] = 0x00;
180 req[len++] = 0x00;
181
182 s->Phone.Data.FileInfo = File;
183 return GSM_WaitFor (s, req, len, 0x58, 4, ID_GetFile);
184 }
185
N3650_GetNextFileFolder(GSM_StateMachine * s,GSM_File * File,gboolean start)186 static GSM_Error N3650_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, gboolean start)
187 {
188 GSM_Error error;
189 GSM_Phone_N3650Data *Priv = &s->Phone.Data.Priv.N3650;
190
191 if (start) {
192 error = DCT4_SetPhoneMode(s, DCT4_MODE_LOCAL);
193 if (error != ERR_NONE) return error;
194
195 Priv->Files[0]->Folder = TRUE;
196 Priv->Files[0]->Level = 1;
197 Priv->Files[0]->Name[0] = 0;
198 Priv->Files[0]->Name[1] = 0;
199 Priv->Files[0]->ID_FullName[0] = 'Z';
200 Priv->Files[0]->ID_FullName[1] = ':';
201 Priv->Files[0]->ID_FullName[2] = 0;
202
203 Priv->Files[1]->Folder = TRUE;
204 Priv->Files[1]->Level = 1;
205 Priv->Files[1]->Name[0] = 0;
206 Priv->Files[1]->Name[1] = 0;
207 Priv->Files[1]->ID_FullName[0] = 'E';
208 Priv->Files[1]->ID_FullName[1] = ':';
209 Priv->Files[1]->ID_FullName[2] = 0;
210
211 Priv->Files[2]->Folder = TRUE;
212 Priv->Files[2]->Level = 1;
213 Priv->Files[2]->Name[0] = 0;
214 Priv->Files[2]->Name[1] = 0;
215 Priv->Files[2]->ID_FullName[0] = 'C';
216 Priv->Files[2]->ID_FullName[1] = ':';
217 Priv->Files[2]->ID_FullName[2] = 0;
218
219 Priv->FilesLocationsUsed = 3;
220 Priv->FilesLocationsCurrent = 0;
221 Priv->FileLev = 1;
222 }
223
224 if (Priv->FilesLocationsCurrent == Priv->FilesLocationsUsed) {
225 #if 0
226 error = DCT4_SetPhoneMode(s, DCT4_MODE_NORMAL);
227 if (error != ERR_NONE) return error;
228 #endif
229
230 return ERR_EMPTY;
231 }
232
233 strcpy(File->ID_FullName,Priv->Files[Priv->FilesLocationsCurrent]->ID_FullName);
234 File->Level = Priv->Files[Priv->FilesLocationsCurrent]->Level;
235 File->Folder = Priv->Files[Priv->FilesLocationsCurrent]->Folder;
236 CopyUnicodeString(File->Name,Priv->Files[Priv->FilesLocationsCurrent]->Name);
237 Priv->FilesLocationsCurrent++;
238
239 if (!File->Folder) return ERR_NONE;
240
241 if (Priv->FilesLocationsCurrent > 1) {
242 if (File->ID_FullName[0]!=Priv->Files[Priv->FilesLocationsCurrent-2]->ID_FullName[0]) {
243 if (File->ID_FullName[0] == 'E') {
244 error = DCT4_SetPhoneMode(s, DCT4_MODE_TEST);
245 if (error != ERR_NONE) return error;
246 error = DCT4_SetPhoneMode(s, DCT4_MODE_TEST);
247 if (error != ERR_NONE) return error;
248 }
249 if (File->ID_FullName[0] == 'C') {
250 error = DCT4_SetPhoneMode(s, DCT4_MODE_LOCAL);
251 if (error != ERR_NONE) return error;
252 error = DCT4_SetPhoneMode(s, DCT4_MODE_LOCAL);
253 if (error != ERR_NONE) return error;
254 }
255 #if 0
256 if (error != ERR_NONE) return error;
257 #endif
258 }
259 }
260
261 File->ReadOnly = FALSE;
262 File->System = FALSE;
263 File->Protected = FALSE;
264 File->Hidden = FALSE;
265
266 return N3650_GetFolderInfo(s, File);
267 }
268
N3650_Initialise(GSM_StateMachine * s)269 static GSM_Error N3650_Initialise (GSM_StateMachine *s)
270 {
271 GSM_Phone_N3650Data *Priv = &s->Phone.Data.Priv.N3650;
272 int i=0;
273
274 for (i=0;i<10000;i++) {
275 Priv->Files[i] = (GSM_File *)malloc(sizeof(GSM_File));
276 if (Priv->Files[i] == NULL) return ERR_MOREMEMORY;
277 }
278 return ERR_NONE;
279 }
280
N3650_Terminate(GSM_StateMachine * s)281 static GSM_Error N3650_Terminate(GSM_StateMachine *s)
282 {
283 GSM_Phone_N3650Data *Priv = &s->Phone.Data.Priv.N3650;
284 int i;
285
286 for (i=0;i<10000;i++) {
287 free(Priv->Files[i]);
288 Priv->Files[i]=NULL;
289 }
290 return ERR_NONE;
291 }
292
293 static GSM_Reply_Function N3650ReplyFunctions[] = {
294 {DCT4_ReplySetPhoneMode, "\x15",0x03,0x64,ID_Reset },
295 {DCT4_ReplyGetPhoneMode, "\x15",0x03,0x65,ID_Reset },
296 {NoneReply, "\x15",0x03,0x68,ID_Reset },
297
298 {DCT4_ReplyGetIMEI, "\x1B",0x03,0x01,ID_GetIMEI },
299 {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x08,ID_GetHardware },
300 {NOKIA_ReplyGetPhoneString, "\x1B",0x03,0x0C,ID_GetProductCode },
301
302 {N3650_ReplyGetFolderInfo, "\x58",0x03,0x0C,ID_GetFile },
303 {N3650_ReplyGetFilePart, "\x58",0x03,0x0E,ID_GetFile },
304
305 {NULL, "\x00",0x00,0x00,ID_None }
306 };
307
308 GSM_Phone_Functions N3650Phone = {
309 "3650|NGAGE",
310 N3650ReplyFunctions,
311 NOTSUPPORTED, /* Install */
312 N3650_Initialise,
313 N3650_Terminate,
314 GSM_DispatchMessage,
315 NOTSUPPORTED, /* ShowStartInfo */
316 NOKIA_GetManufacturer,
317 DCT3DCT4_GetModel,
318 DCT3DCT4_GetFirmware,
319 DCT4_GetIMEI,
320 NOTSUPPORTED, /* GetOriginalIMEI */
321 NOTSUPPORTED, /* GetManufactureMonth */
322 DCT4_GetProductCode,
323 DCT4_GetHardware,
324 NOTSUPPORTED, /* GetPPM */
325 NOTSUPPORTED, /* GetSIMIMSI */
326 NOTSUPPORTED, /* GetDateTime */
327 NOTSUPPORTED, /* SetDateTime */
328 NOTSUPPORTED, /* GetAlarm */
329 NOTSUPPORTED, /* SetAlarm */
330 NOTSUPPORTED, /* GetLocale */
331 NOTSUPPORTED, /* SetLocale */
332 NOTSUPPORTED, /* PressKey */
333 DCT4_Reset,
334 NOTSUPPORTED, /* ResetPhoneSettings */
335 NOTSUPPORTED, /* EnterSecurityCode */
336 NOTSUPPORTED, /* GetSecurityStatus */
337 NOTSUPPORTED, /* GetDisplayStatus */
338 NOTSUPPORTED, /* SetAutoNetworkLogin */
339 NOTSUPPORTED, /* GetBatteryCharge */
340 NOTSUPPORTED, /* GetSignalQuality */
341 NOTSUPPORTED, /* GetNetworkInfo */
342 NOTSUPPORTED, /* GetCategory */
343 NOTSUPPORTED, /* AddCategory */
344 NOTSUPPORTED, /* GetCategoryStatus */
345 NOTSUPPORTED, /* GetMemoryStatus */
346 NOTSUPPORTED, /* GetMemory */
347 NOTSUPPORTED, /* GetNextMemory */
348 NOTSUPPORTED, /* SetMemory */
349 NOTSUPPORTED, /* AddMemory */
350 NOTSUPPORTED, /* DeleteMemory */
351 NOTIMPLEMENTED, /* DeleteAllMemory */
352 NOTSUPPORTED, /* GetSpeedDial */
353 NOTSUPPORTED, /* SetSpeedDial */
354 NOTSUPPORTED, /* GetSMSC */
355 NOTSUPPORTED, /* SetSMSC */
356 NOTSUPPORTED, /* GetSMSStatus */
357 NOTSUPPORTED, /* GetSMS */
358 NOTSUPPORTED, /* GetNextSMS */
359 NOTSUPPORTED, /* SetSMS */
360 NOTSUPPORTED, /* AddSMS */
361 NOTSUPPORTED, /* DeleteSMS */
362 NOTSUPPORTED, /* SendSMS */
363 NOTSUPPORTED, /* SendSavedSMS */
364 NOTSUPPORTED, /* SetFastSMSSending */
365 NOTSUPPORTED, /* SetIncomingSMS */
366 NOTSUPPORTED, /* SetIncomingCB */
367 NOTSUPPORTED, /* GetSMSFolders */
368 NOTSUPPORTED, /* AddSMSFolder */
369 NOTSUPPORTED, /* DeleteSMSFolder */
370 NOTIMPLEMENTED, /* DialVoice */
371 NOTIMPLEMENTED, /* DialService */
372 NOTIMPLEMENTED, /* AnswerCall */
373 NOTIMPLEMENTED, /* CancelCall */
374 NOTIMPLEMENTED, /* HoldCall */
375 NOTIMPLEMENTED, /* UnholdCall */
376 NOTIMPLEMENTED, /* ConferenceCall */
377 NOTIMPLEMENTED, /* SplitCall */
378 NOTIMPLEMENTED, /* TransferCall */
379 NOTIMPLEMENTED, /* SwitchCall */
380 NOTSUPPORTED, /* GetCallDivert */
381 NOTSUPPORTED, /* SetCallDivert */
382 NOTSUPPORTED, /* CancelAllDiverts */
383 NOTIMPLEMENTED, /* SetIncomingCall */
384 NOTIMPLEMENTED, /* SetIncomingUSSD */
385 NOTSUPPORTED, /* SendDTMF */
386 NOTSUPPORTED, /* GetRingtone */
387 NOTSUPPORTED, /* SetRingtone */
388 NOTSUPPORTED, /* GetRingtonesInfo */
389 NOTIMPLEMENTED, /* DeleteUserRingtones */
390 NOTSUPPORTED, /* PlayTone */
391 NOTSUPPORTED, /* GetWAPBookmark */
392 NOTSUPPORTED, /* SetWAPBookmark */
393 NOTSUPPORTED, /* DeleteWAPBookmark */
394 NOTSUPPORTED, /* GetWAPSettings */
395 NOTSUPPORTED, /* SetWAPSettings */
396 NOTSUPPORTED, /* GetSyncMLSettings */
397 NOTSUPPORTED, /* SetSyncMLSettings */
398 NOTSUPPORTED, /* GetChatSettings */
399 NOTSUPPORTED, /* SetChatSettings */
400 NOTSUPPORTED, /* GetMMSSettings */
401 NOTSUPPORTED, /* SetMMSSettings */
402 NOTSUPPORTED, /* GetMMSFolders */
403 NOTSUPPORTED, /* GetNextMMSFile */
404 NOTSUPPORTED, /* GetBitmap */
405 NOTSUPPORTED, /* SetBitmap */
406 NOTSUPPORTED, /* GetToDoStatus */
407 NOTSUPPORTED, /* GetToDo */
408 NOTSUPPORTED, /* GetNextToDo */
409 NOTSUPPORTED, /* SetToDo */
410 NOTSUPPORTED, /* AddToDo */
411 NOTSUPPORTED, /* DeleteToDo */
412 NOTSUPPORTED, /* DeleteAllToDo */
413 NOTIMPLEMENTED, /* GetCalendarStatus */
414 NOTIMPLEMENTED, /* GetCalendar */
415 NOTSUPPORTED, /* GetNextCalendar */
416 NOTIMPLEMENTED, /* SetCalendar */
417 NOTSUPPORTED, /* AddCalendar */
418 NOTSUPPORTED, /* DeleteCalendar */
419 NOTIMPLEMENTED, /* DeleteAllCalendar */
420 NOTSUPPORTED, /* GetCalendarSettings */
421 NOTSUPPORTED, /* SetCalendarSettings */
422 NOTSUPPORTED, /* GetNoteStatus */
423 NOTSUPPORTED, /* GetNote */
424 NOTSUPPORTED, /* GetNextNote */
425 NOTSUPPORTED, /* SetNote */
426 NOTSUPPORTED, /* AddNote */
427 NOTSUPPORTED, /* DeleteNote */
428 NOTSUPPORTED, /* DeleteAllNotes */
429 NOTSUPPORTED, /* GetProfile */
430 NOTSUPPORTED, /* SetProfile */
431 NOTSUPPORTED, /* GetFMStation */
432 NOTSUPPORTED, /* SetFMStation */
433 NOTSUPPORTED, /* ClearFMStations */
434 N3650_GetNextFileFolder,
435 NOTSUPPORTED, /* GetFolderListing */
436 NOTSUPPORTED, /* GetNextRootFolder */
437 NOTSUPPORTED, /* SetFileAttributes */
438 N3650_GetFilePart,
439 NOTIMPLEMENTED, /* AddFilePart */
440 NOTSUPPORTED, /* SendFilePart */
441 NOTSUPPORTED, /* GetFileSystemStatus */
442 NOTIMPLEMENTED, /* DeleteFile */
443 NOTIMPLEMENTED, /* AddFolder */
444 NOTSUPPORTED, /* DeleteFolder */
445 NOTSUPPORTED, /* GetGPRSAccessPoint */
446 NOTSUPPORTED, /* SetGPRSAccessPoint */
447 NOTSUPPORTED, /* GetScreenshot */
448 NOTSUPPORTED, /* SetPower */
449 NOTSUPPORTED, /* PostConnect */
450 NONEFUNCTION /* PreAPICall */
451 };
452
453 #endif
454
455 /* How should editor hadle tabs in this file? Add editor commands here.
456 * vim: noexpandtab sw=8 ts=8 sts=8:
457 */
458