1 /* (c) 2003-2006 by Marcin Wiacek */
2 /* function for making CRC for filesystem (c) 2003 by Michael Schroeder */
3
4 #include <gammu-config.h>
5
6 #ifdef GSM_ENABLE_NOKIA6510
7
8 #include <string.h>
9 #include <time.h>
10
11 #include "../../../../misc/coding/coding.h"
12 #include "../../../../gsmcomon.h"
13 #include "../../../../service/gsmlogo.h"
14 #include "../../nfunc.h"
15 #include "../../nfuncold.h"
16 #include "../../../pfunc.h"
17 #include "../dct4func.h"
18 #include "n6510.h"
19 #include "../../../../../libgammu/misc/string.h"
20
21 /* shared */
22
23 /**
24 * Shifts data in file cache by defined count.
25 *
26 * \param move How to move entries. +10 means that i entry will become
27 * i + 10, while -10 means that entries will be moved backwards. Of
28 * course starting at the beginning of the list. So 10 entry will become 0.
29 */
N6510_ShiftFileCache(GSM_StateMachine * s,int move)30 static GSM_Error N6510_ShiftFileCache(GSM_StateMachine *s, int move)
31 {
32 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
33 int i;
34
35 if (move < 0) {
36 for (i = 0; i < Priv->FilesLocationsUsed + move; i++) {
37 memcpy(&Priv->FilesCache[i], &Priv->FilesCache[i - move], sizeof(GSM_File));
38 smprintf(s, "Copying %i to %i\n", i - move, i);
39 }
40 } else {
41 for (i = Priv->FilesLocationsUsed - 1; i >= 0; i--) {
42 memcpy(&Priv->FilesCache[i + move], &Priv->FilesCache[i], sizeof(GSM_File));
43 smprintf(s, "Copying %i to %i\n", i, i + move);
44 }
45 }
46
47 Priv->FilesLocationsUsed += move;
48
49 return ERR_NONE;
50 }
51 /**
52 * Allocates enough entries in file cache.
53 *
54 * \param requested Number of files which are requested.
55 */
N6510_AllocFileCache(GSM_StateMachine * s,int requested)56 static GSM_Error N6510_AllocFileCache(GSM_StateMachine *s, int requested)
57 {
58 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
59 int newsize;
60
61 /* Maybe there is already enough allocated */
62 if (Priv->FilesLocationsAvail >= requested) return ERR_NONE;
63
64 /* Do not allocate one by one */
65 newsize = requested + 10;
66
67 /* Reallocate memory */
68 Priv->FilesCache = (GSM_File *)realloc(Priv->FilesCache, newsize * sizeof(GSM_File));
69 if (Priv->FilesCache == NULL) return ERR_MOREMEMORY;
70
71 /* Store new cache size */
72 Priv->FilesLocationsAvail = newsize;
73
74 return ERR_NONE;
75 }
76
N6510_FindFileCheckSum12(GSM_StateMachine * s,unsigned char * ptr,int len)77 static int N6510_FindFileCheckSum12(GSM_StateMachine *s, unsigned char *ptr, int len)
78 {
79 int acc, i, accx;
80
81 accx = 0;
82 acc = 0xffff;
83 while (len--) {
84 accx = (accx & 0xffff00ff) | (acc & 0xff00);
85 acc = (acc & 0xffff00ff) | (*ptr++ << 8);
86 for (i = 0; i < 8; i++) {
87 acc <<= 1;
88 if (acc & 0x10000) acc ^= 0x1021;
89 if (accx & 0x80000000) acc ^= 0x1021;
90 accx <<= 1;
91 }
92 }
93 smprintf(s, "Checksum from Gammu is %04X\n",(acc & 0xffff));
94 return (acc & 0xffff);
95 }
96
N6510_ReplyGetFilePart12(GSM_Protocol_Message * msg,GSM_StateMachine * s)97 GSM_Error N6510_ReplyGetFilePart12(GSM_Protocol_Message *msg, GSM_StateMachine *s)
98 {
99 int old;
100
101 smprintf(s,"File part received\n");
102 old = s->Phone.Data.File->Used;
103 s->Phone.Data.File->Used += msg->Buffer[6]*256*256*256+
104 msg->Buffer[7]*256*256+
105 msg->Buffer[8]*256+
106 msg->Buffer[9];
107 smprintf(s,"Length of file part: %i\n",
108 msg->Buffer[6]*256*256*256+
109 msg->Buffer[7]*256*256+
110 msg->Buffer[8]*256+
111 msg->Buffer[9]);
112 s->Phone.Data.File->Buffer = (unsigned char *)realloc(s->Phone.Data.File->Buffer,s->Phone.Data.File->Used);
113 memcpy(s->Phone.Data.File->Buffer+old,msg->Buffer+10,s->Phone.Data.File->Used-old);
114 return ERR_NONE;
115 }
116
N6510_ReplyGetFileCRC12(GSM_Protocol_Message * msg,GSM_StateMachine * s)117 GSM_Error N6510_ReplyGetFileCRC12(GSM_Protocol_Message *msg, GSM_StateMachine *s)
118 {
119 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
120
121 Priv->FileCheckSum = msg->Buffer[6] * 256 + msg->Buffer[7];
122 smprintf(s,"File checksum from phone is %04X\n",Priv->FileCheckSum);
123 return ERR_NONE;
124 }
125
126 /* filesystem 1 */
127
N6510_GetFileCRC1(GSM_StateMachine * s,unsigned char * id)128 static GSM_Error N6510_GetFileCRC1(GSM_StateMachine *s, unsigned char *id)
129 {
130 unsigned char GetCRC[] = {
131 N7110_FRAME_HEADER, 0x42, 0x00, 0x00, 0x00, 0x01,
132 0x00, 0x1E}; /* file ID */
133
134 GetCRC[8] = atoi(DecodeUnicodeString(id)) / 256;
135 GetCRC[9] = atoi(DecodeUnicodeString(id)) % 256;
136 smprintf(s,"Getting CRC for file in filesystem\n");
137 return GSM_WaitFor (s, GetCRC, 10, 0x6D, 4, ID_GetCRC);
138 }
139
N6510_ReplyGetFileFolderInfo1(GSM_Protocol_Message * msg,GSM_StateMachine * s)140 GSM_Error N6510_ReplyGetFileFolderInfo1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
141 {
142 GSM_File *File = s->Phone.Data.FileInfo;
143 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
144 int i, newsize;
145 unsigned char buffer[500];
146 GSM_Error error;
147
148 switch (msg->Buffer[3]) {
149 case 0x15:
150 smprintf(s,"File or folder details received\n");
151 CopyUnicodeString(File->Name,msg->Buffer+10);
152 if (msg->Length == 14) {
153 smprintf(s,"File not exist\n");
154 return ERR_FILENOTEXIST;
155 }
156 if (!strncmp(DecodeUnicodeString(File->Name),"GMSTemp",7)) return ERR_EMPTY;
157 if (File->Name[0] == 0x00 && File->Name[1] == 0x00) return ERR_UNKNOWN;
158
159 /* EncodeHexUnicode (buffer, File->Name, UnicodeLength(File->Name)); */
160 /* smprintf(s,"Name encoded: %s\n",buffer); */
161
162 i = msg->Buffer[8]*256+msg->Buffer[9];
163 smprintf(s, "%02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
164 msg->Buffer[i-5],msg->Buffer[i-4],msg->Buffer[i-3],
165 msg->Buffer[i-2],msg->Buffer[i-1],msg->Buffer[i],
166 msg->Buffer[i+1],msg->Buffer[i+2],msg->Buffer[i+3]);
167
168 File->Folder = FALSE;
169 if (msg->Buffer[i-5] == 0x00 && msg->Buffer[i-3]==0x02) File->Folder = TRUE;
170
171 File->ReadOnly = FALSE;
172 File->Protected = FALSE;
173 File->System = FALSE;
174 File->Hidden = FALSE;
175 if (msg->Buffer[i+2] == 0x01) File->Protected = TRUE;
176 if (msg->Buffer[i+4] == 0x01) File->ReadOnly = TRUE;
177 if (msg->Buffer[i+5] == 0x01) File->Hidden = TRUE;
178 if (msg->Buffer[i+6] == 0x01) File->System = TRUE;/* fixme */
179
180 File->ModifiedEmpty = FALSE;
181 NOKIA_DecodeDateTime(s, msg->Buffer+i-22, &File->Modified, TRUE, FALSE);
182 if (File->Modified.Year == 0x00) File->ModifiedEmpty = TRUE;
183 if (File->Modified.Year == 0xffff) File->ModifiedEmpty = TRUE;
184 smprintf(s, "%02x %02x %02x %02x\n",msg->Buffer[i-22],msg->Buffer[i-21],msg->Buffer[i-20],msg->Buffer[i-19]);
185
186 Priv->FileToken = msg->Buffer[i-10]*256+msg->Buffer[i-9];
187 Priv->ParentID = msg->Buffer[i]*256+msg->Buffer[i+1];
188 smprintf(s,"ParentID is %i\n",Priv->ParentID);
189
190 File->Type = GSM_File_Other;
191 if (msg->Length > 240){
192 i = 227;
193 if (msg->Buffer[i]==0x02 && msg->Buffer[i+2]==0x01)
194 File->Type = GSM_File_Image_JPG;
195 else if (msg->Buffer[i]==0x02 && msg->Buffer[i+2]==0x02)
196 File->Type = GSM_File_Image_BMP;
197 else if (msg->Buffer[i]==0x02 && msg->Buffer[i+2]==0x07)
198 File->Type = GSM_File_Image_BMP;
199 else if (msg->Buffer[i]==0x02 && msg->Buffer[i+2]==0x03)
200 File->Type = GSM_File_Image_PNG;
201 else if (msg->Buffer[i]==0x02 && msg->Buffer[i+2]==0x05)
202 File->Type = GSM_File_Image_GIF;
203 else if (msg->Buffer[i]==0x02 && msg->Buffer[i+2]==0x09)
204 File->Type = GSM_File_Image_WBMP;
205 else if (msg->Buffer[i]==0x04 && msg->Buffer[i+2]==0x01)
206 File->Type = GSM_File_Sound_AMR;
207 else if (msg->Buffer[i]==0x04 && msg->Buffer[i+2]==0x02)
208 File->Type = GSM_File_Sound_MIDI;
209 else if (msg->Buffer[i]==0x08 && msg->Buffer[i+2]==0x05)
210 File->Type = GSM_File_Video_3GP;
211 else if (msg->Buffer[i]==0x10 && msg->Buffer[i+2]==0x01)
212 File->Type = GSM_File_Java_JAR;
213 else if (msg->Buffer[i]==0x00 && msg->Buffer[i+2]==0x01)
214 File->Type = GSM_File_MMS;
215 }
216 return ERR_NONE;
217 case 0x2F:
218 smprintf(s,"File or folder used bytes received\n");
219 File->Used = msg->Buffer[6]*256*256*256+
220 msg->Buffer[7]*256*256+
221 msg->Buffer[8]*256+
222 msg->Buffer[9];
223 return ERR_NONE;
224 case 0x33:
225 if (s->Phone.Data.RequestID == ID_GetFileInfo) {
226
227 newsize = msg->Buffer[8] * 256 + msg->Buffer[9];
228
229 error = N6510_AllocFileCache(s, Priv->FilesLocationsUsed + newsize);
230 if (error != ERR_NONE) return error;
231
232 error = N6510_ShiftFileCache(s, newsize);
233 if (error != ERR_NONE) return error;
234
235 for (i = 0; i < newsize; i++) {
236 sprintf(buffer,"%i",msg->Buffer[13+i*4-1]*256 + msg->Buffer[13+i*4]);
237 EncodeUnicode(Priv->FilesCache[i].ID_FullName,buffer,strlen(buffer));
238 Priv->FilesCache[i].Level = File->Level+1;
239 smprintf(s, "%s ",DecodeUnicodeString(Priv->FilesCache[i].ID_FullName));
240 }
241 smprintf(s, "\n");
242 }
243 if ((msg->Buffer[8]*256+msg->Buffer[9]) != 0x00) File->Folder = TRUE;
244 return ERR_NONE;
245 case 0xf0:
246 smprintf(s, "File system is not supported\n");
247 return ERR_NOTSUPPORTED;
248 }
249 return ERR_UNKNOWNRESPONSE;
250 }
251
N6510_GetFileFolderInfo1(GSM_StateMachine * s,GSM_File * File,gboolean full)252 static GSM_Error N6510_GetFileFolderInfo1(GSM_StateMachine *s, GSM_File *File, gboolean full)
253 {
254 GSM_Error error;
255 unsigned char req[10] = {
256 N7110_FRAME_HEADER,
257 0x14, /* 0x14 - info, 0x22 - free/total, 0x2E - used, 0x32 - sublocations */
258 0x01, /* 0x00 for sublocations reverse sorting, 0x01 for free */
259 0x00, 0x00, 0x01,
260 0x00, 0x01}; /* Folder or file number */
261
262 s->Phone.Data.FileInfo = File;
263 req[8] = atoi(DecodeUnicodeString(File->ID_FullName)) / 256;
264 req[9] = atoi(DecodeUnicodeString(File->ID_FullName)) % 256;
265
266 req[3] = 0x14;
267 req[4] = 0x01;
268 smprintf(s,"Getting info for file in filesystem\n");
269 error=GSM_WaitFor (s, req, 10, 0x6D, 4, ID_GetFileInfo);
270 if (error != ERR_NONE) return error;
271
272 if (full) {
273 req[3] = 0x32;
274 req[4] = 0x00;
275 smprintf(s,"Getting subfolders for filesystem\n");
276 error=GSM_WaitFor (s, req, 10, 0x6D, 4, ID_GetFileInfo);
277 if (error != ERR_NONE) return error;
278 }
279
280 if (!File->Folder) {
281 req[3] = 0x2E;
282 req[4] = 0x01;
283 smprintf(s,"Getting used memory for file in filesystem\n");
284 return GSM_WaitFor (s, req, 10, 0x6D, 4, ID_GetFileInfo);
285 }
286
287 return error;
288 }
289
N6510_GetNextFileFolder1(GSM_StateMachine * s,GSM_File * File,gboolean start)290 static GSM_Error N6510_GetNextFileFolder1(GSM_StateMachine *s, GSM_File *File, gboolean start)
291 {
292 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
293 GSM_Error error;
294 unsigned char buffer[5];
295
296 if (start) {
297 error = N6510_AllocFileCache(s, 1);
298 if (error != ERR_NONE) return error;
299
300 Priv->FilesLocationsUsed = 1;
301
302 sprintf(buffer,"%i",0x01);
303 EncodeUnicode(Priv->FilesCache[0].ID_FullName,buffer,strlen(buffer));
304 Priv->FilesCache[0].Level = 1;
305 }
306
307 while (1) {
308 if (Priv->FilesLocationsUsed == 0) return ERR_EMPTY;
309
310 CopyUnicodeString(File->ID_FullName,Priv->FilesCache[0].ID_FullName);
311 File->Level = Priv->FilesCache[0].Level;
312
313 error = N6510_ShiftFileCache(s, -1);
314 if (error != ERR_NONE) return error;
315
316 error = N6510_GetFileFolderInfo1(s, File, TRUE);
317 if (error == ERR_EMPTY) continue;
318 return error;
319 }
320 }
321
N6510_ReplyGetFileSystemStatus1(GSM_Protocol_Message * msg,GSM_StateMachine * s)322 GSM_Error N6510_ReplyGetFileSystemStatus1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
323 {
324 switch (msg->Buffer[3]) {
325 case 0x23:
326 if (!strcmp(s->Phone.Data.ModelInfo->model,"6310i")) {
327 smprintf(s,"File or folder total bytes received\n");
328 s->Phone.Data.FileSystemStatus->Free =
329 3*256*256 + msg->Buffer[8]*256 + msg->Buffer[9] -
330 s->Phone.Data.FileSystemStatus->Used;
331 } else {
332 smprintf(s,"File or folder free bytes received\n");
333 s->Phone.Data.FileSystemStatus->Free =
334 msg->Buffer[6]*256*256*256+
335 msg->Buffer[7]*256*256+
336 msg->Buffer[8]*256+
337 msg->Buffer[9];
338 }
339 return ERR_NONE;
340 case 0x2F:
341 smprintf(s,"File or folder used bytes received\n");
342 s->Phone.Data.FileSystemStatus->Used =
343 msg->Buffer[6]*256*256*256+
344 msg->Buffer[7]*256*256+
345 msg->Buffer[8]*256+
346 msg->Buffer[9];
347 return ERR_NONE;
348 }
349 return ERR_UNKNOWNRESPONSE;
350 }
351
N6510_GetFileSystemStatus1(GSM_StateMachine * s,GSM_FileSystemStatus * status)352 static GSM_Error N6510_GetFileSystemStatus1(GSM_StateMachine *s, GSM_FileSystemStatus *status)
353 {
354 GSM_Error error;
355 unsigned char req[10] = {
356 N7110_FRAME_HEADER,
357 0x22, /* 0x14 - info, 0x22 - free/total, 0x2E - used, 0x32 - sublocations */
358 0x01, /* 0x00 for sublocations reverse sorting, 0x01 for free */
359 0x00, 0x00, 0x01,
360 0x00, 0x01}; /* Folder or file number */
361
362 /* Used memory by types */
363 status->UsedImages = 0;
364 status->UsedSounds = 0;
365 status->UsedThemes = 0;
366 s->Phone.Data.FileSystemStatus = status;
367
368 status->Free = 0;
369
370 req[3] = 0x2E;
371 req[4] = 0x01;
372 smprintf(s, "Getting used/total memory in filesystem\n");
373 error = GSM_WaitFor (s, req, 10, 0x6D, 4, ID_FileSystemStatus);
374 if (error != ERR_NONE) return error;
375
376 req[3] = 0x22;
377 req[4] = 0x01;
378 smprintf(s, "Getting free memory in filesystem\n");
379 return GSM_WaitFor (s, req, 10, 0x6D, 4, ID_FileSystemStatus);
380 }
381
N6510_GetFilePart1(GSM_StateMachine * s,GSM_File * File,int * Handle UNUSED,size_t * Size)382 static GSM_Error N6510_GetFilePart1(GSM_StateMachine *s, GSM_File *File, int *Handle UNUSED, size_t *Size)
383 {
384 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
385 int old;
386 GSM_Error error;
387 unsigned char req[] = {
388 N7110_FRAME_HEADER, 0x0E, 0x00, 0x00, 0x00, 0x01,
389 0x00, 0x01, /* Folder or file number */
390 0x00, 0x00, 0x00, 0x00, /* Start from xxx byte */
391 0x00, 0x00,
392 0x03, 0xE8}; /* Read xxx bytes */
393
394 if (File->Used == 0x00) {
395 error = N6510_GetFileFolderInfo1(s, File, FALSE);
396 if (error != ERR_NONE) return error;
397
398 if (File->Folder) return ERR_SHOULDBEFILE;
399
400 (*Size) = File->Used;
401 File->Used = 0;
402 }
403
404 old = File->Used;
405 req[8] = atoi(DecodeUnicodeString(File->ID_FullName)) / 256;
406 req[9] = atoi(DecodeUnicodeString(File->ID_FullName)) % 256;
407 req[10] = old / (256*256*256);
408 req[11] = old / (256*256);
409 req[12] = old / 256;
410 req[13] = old % 256;
411
412 s->Phone.Data.File = File;
413 smprintf(s, "Getting file part from filesystem\n");
414 error=GSM_WaitFor (s, req, 18, 0x6D, 4, ID_GetFile);
415 if (error != ERR_NONE) return error;
416 if (File->Used - old != (0x03 * 256 + 0xE8)) {
417 error = N6510_GetFileCRC1(s, File->ID_FullName);
418 if (error != ERR_NONE) return error;
419
420 if (N6510_FindFileCheckSum12(s, File->Buffer, File->Used) != Priv->FileCheckSum) {
421 smprintf(s,"File2 checksum is %i, File checksum is %i\n",N6510_FindFileCheckSum12(s, File->Buffer, File->Used),Priv->FileCheckSum);
422 return ERR_WRONGCRC;
423 }
424 return ERR_EMPTY;
425 }
426 return ERR_NONE;
427 }
428
N6510_SetReadOnly1(GSM_StateMachine * s,unsigned char * ID,gboolean enable)429 static GSM_Error N6510_SetReadOnly1(GSM_StateMachine *s, unsigned char *ID, gboolean enable)
430 {
431 unsigned char SetAttr[] = {
432 N7110_FRAME_HEADER, 0x18,
433 0x00, /* state */
434 0x00, 0x00, 0x01,
435 0x00, 0x20}; /* File ID */
436
437 if (!enable) SetAttr[4] = 0x06;
438
439 SetAttr[8] = atoi(DecodeUnicodeString(ID)) / 256;
440 SetAttr[9] = atoi(DecodeUnicodeString(ID)) % 256;
441 smprintf(s, "Setting readonly attribute\n");
442 return GSM_WaitFor (s, SetAttr, 10, 0x6D, 4, ID_SetAttrib);
443 }
444
N6510_SetFileAttributes1(GSM_StateMachine * s,GSM_File * File)445 static GSM_Error N6510_SetFileAttributes1(GSM_StateMachine *s, GSM_File *File)
446 {
447 GSM_Error error;
448 GSM_File file2;
449
450 memset(&file2, 0, sizeof(file2));
451
452 CopyUnicodeString(file2.ID_FullName,File->ID_FullName);
453 error = N6510_GetFileFolderInfo1(s, &file2, FALSE);
454 if (error != ERR_NONE) return error;
455
456 /* setting folder attrib works, but we block it */
457 if (file2.Folder) return ERR_SHOULDBEFILE;
458
459 /* todo */
460 if (file2.System != File->System ||
461 file2.Hidden != File->Hidden ||
462 file2.Protected != File->Protected) {
463 return ERR_NOTSUPPORTED;
464 }
465
466 return N6510_SetReadOnly1(s, File->ID_FullName, File->ReadOnly);
467 }
468
469 /* function checks if there is file/folder with searched name in folder with specified ID */
N6510_SearchForFileName1(GSM_StateMachine * s,GSM_File * File)470 static GSM_Error N6510_SearchForFileName1(GSM_StateMachine *s, GSM_File *File)
471 {
472 GSM_Error error;
473 GSM_File *BackupCache, *NewFiles;
474 int FilesLocationsUsed,FilesLocationsUsed2,i;
475 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
476
477 File->Folder = FALSE;
478
479 /* making backup */
480 BackupCache = (GSM_File *)malloc(sizeof(GSM_File) * Priv->FilesLocationsUsed);
481 if (BackupCache == NULL) return ERR_MOREMEMORY;
482 memcpy(BackupCache, Priv->FilesCache, sizeof(GSM_File) * Priv->FilesLocationsUsed);
483 FilesLocationsUsed = Priv->FilesLocationsUsed;
484
485 /* Allocate new cache */
486 error = N6510_AllocFileCache(s, 1);
487 if (error != ERR_NONE) {
488 free(BackupCache);
489 return error;
490 }
491
492 /* putting own data */
493 Priv->FilesCache[0].Level = 1;
494 Priv->FilesLocationsUsed = 1;
495 CopyUnicodeString(Priv->FilesCache[0].ID_FullName,File->ID_FullName);
496
497 /* checking */
498 error = N6510_GetFileFolderInfo1(s, &Priv->FilesCache[0], TRUE);
499
500 /* backuping new data */
501 NewFiles = (GSM_File *)malloc(sizeof(GSM_File) * Priv->FilesLocationsUsed);
502 if (NewFiles == NULL) {
503 free(BackupCache);
504 BackupCache=NULL;
505 return ERR_MOREMEMORY;
506 }
507 memcpy(NewFiles, Priv->FilesCache, sizeof(GSM_File) * Priv->FilesLocationsUsed);
508 FilesLocationsUsed2 = Priv->FilesLocationsUsed;
509
510 /* restoring */
511 memcpy(Priv->FilesCache, BackupCache, sizeof(GSM_File) * FilesLocationsUsed);
512 free(BackupCache);
513 BackupCache=NULL;
514 Priv->FilesLocationsUsed = FilesLocationsUsed;
515
516 if (error != ERR_NONE) {
517 free(NewFiles);
518 NewFiles=NULL;
519 return error;
520 }
521
522 for (i = 0; i < FilesLocationsUsed2; i++) {
523 smprintf(s, "ID is %s\n",DecodeUnicodeString(NewFiles[i].ID_FullName));
524 error = N6510_GetFileFolderInfo1(s, &NewFiles[i], FALSE);
525 if (error == ERR_EMPTY) continue;
526 if (error != ERR_NONE) {
527 free(NewFiles);
528 NewFiles=NULL;
529 return error;
530 }
531 smprintf(s, "%s",DecodeUnicodeString(File->Name));
532 smprintf(s, "%s \n",DecodeUnicodeString(NewFiles[i].Name));
533 if (mywstrncasecmp(NewFiles[i].Name,File->Name,0)) {
534 smprintf(s, "the same\n");
535 File->Folder = NewFiles[i].Folder;
536 free(NewFiles);
537 NewFiles=NULL;
538 return ERR_NONE;
539 }
540 }
541 free(NewFiles);
542 NewFiles=NULL;
543 return ERR_EMPTY;
544 }
545
N6510_ReplyAddFileHeader1(GSM_Protocol_Message * msg,GSM_StateMachine * s)546 GSM_Error N6510_ReplyAddFileHeader1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
547 {
548 unsigned char buffer[8];
549
550 switch (msg->Buffer[3]) {
551 case 0x03:
552 smprintf(s,"File header added\n");
553 sprintf(buffer,"%i",msg->Buffer[8]*256+msg->Buffer[9]);
554 EncodeUnicode(s->Phone.Data.File->ID_FullName,buffer,strlen(buffer));
555 return ERR_NONE;
556 case 0x13:
557 return ERR_NONE;
558 }
559 return ERR_UNKNOWNRESPONSE;
560 }
561
N6510_ReplyAddFilePart1(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s UNUSED)562 GSM_Error N6510_ReplyAddFilePart1(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s UNUSED)
563 {
564 return ERR_NONE;
565 }
566
N6510_AddFilePart1(GSM_StateMachine * s,GSM_File * File,size_t * Pos,int * Handle UNUSED)567 static GSM_Error N6510_AddFilePart1(GSM_StateMachine *s, GSM_File *File, size_t *Pos, int *Handle UNUSED)
568 {
569 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
570 GSM_File File2;
571 GSM_Error error;
572 int j;
573 unsigned char Header[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))] = {
574 N7110_FRAME_HEADER, 0x02, 0x00, 0x00, 0x00, 0x01,
575 0x00, 0x0C, /* parent folder ID */
576 0x00, 0x00, 0x00, 0xE8};
577 unsigned char Add[15000] = {
578 N7110_FRAME_HEADER, 0x40, 0x00, 0x00, 0x00, 0x01,
579 0x00, 0x04, /* file ID */
580 0x00, 0x00,
581 0x01, 0x28}; /* length */
582 unsigned char end[30] = {
583 N7110_FRAME_HEADER, 0x40, 0x00, 0x00, 0x00, 0x01,
584 0x00, 0x04, /* file ID */
585 0x00, 0x00, 0x00, 0x00};
586
587 memset(&File2, 0, sizeof(File2));
588
589 s->Phone.Data.File = File;
590
591 if (*Pos == 0) {
592 error = N6510_SearchForFileName1(s,File);
593 if (error == ERR_NONE) return ERR_FILEALREADYEXIST;
594 if (error != ERR_EMPTY) return error;
595
596 Header[8] = atoi(DecodeUnicodeString(File->ID_FullName)) / 256;
597 Header[9] = atoi(DecodeUnicodeString(File->ID_FullName)) % 256;
598 memset(Header+14, 0x00, 300);
599 CopyUnicodeString(Header+14,File->Name);
600 Header[222] = File->Used / (256*256*256);
601 Header[223] = File->Used / (256*256);
602 Header[224] = File->Used / 256;
603 Header[225] = File->Used % 256;
604 switch(File->Type) {
605 case GSM_File_Image_JPG : Header[231]=0x02; Header[233]=0x01; break;
606 case GSM_File_Image_BMP : Header[231]=0x02; Header[233]=0x02; break;
607 case GSM_File_Image_PNG : Header[231]=0x02; Header[233]=0x03; break;
608 case GSM_File_Image_GIF : Header[231]=0x02; Header[233]=0x05; break;
609 case GSM_File_Image_WBMP : Header[231]=0x02; Header[233]=0x09; break;
610 case GSM_File_Sound_AMR : Header[231]=0x04; Header[233]=0x01; break;
611 case GSM_File_Sound_MIDI : Header[231]=0x04; Header[233]=0x05; break; /* Header[238]=0x01; */
612 case GSM_File_Sound_NRT : Header[231]=0x04; Header[233]=0x06; break;
613 case GSM_File_Video_3GP : Header[231]=0x08; Header[233]=0x05; break;
614 case GSM_File_Java_JAR : Header[231]=0x10; Header[233]=0x01; break;
615 case GSM_File_MMS:
616 Header[214]=0x07;
617 Header[215]=0xd3;
618 Header[216]=0x06;
619 Header[217]=0x01;
620 Header[218]=0x12;
621 Header[219]=0x13;
622 Header[220]=0x29;
623 Header[233]=0x01;
624 break;
625 default : Header[231]=0x01; Header[233]=0x05;
626 }
627 Header[235] = 0x01;
628 Header[236] = atoi(DecodeUnicodeString(File->ID_FullName)) / 256;
629 Header[237] = atoi(DecodeUnicodeString(File->ID_FullName)) % 256;
630 if (File->Protected) Header[238] = 0x01; /* Nokia forward lock */
631 if (File->Hidden) Header[241] = 0x01;
632 if (File->System) Header[242] = 0x01; /* fixme */
633 smprintf(s, "Adding file header\n");
634 error=GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFile);
635 if (error != ERR_NONE) return error;
636 }
637
638 j = 1000;
639 if (File->Used - *Pos < 1000) j = File->Used - *Pos;
640 Add[ 8] = atoi(DecodeUnicodeString(File->ID_FullName)) / 256;
641 Add[ 9] = atoi(DecodeUnicodeString(File->ID_FullName)) % 256;
642 Add[12] = j / 256;
643 Add[13] = j % 256;
644 memcpy(Add+14,File->Buffer+(*Pos),j);
645 smprintf(s, "Adding file part %ld %i\n", (long)*Pos,j);
646 error=GSM_WaitFor (s, Add, 14+j, 0x6D, 4, ID_AddFile);
647 if (error != ERR_NONE) return error;
648 *Pos = *Pos + j;
649
650 if (j < 1000) {
651 /* FIXME: This looks strange */
652 end[8] = atoi(DecodeUnicodeString(File->ID_FullName)) / 256;
653 end[9] = atoi(DecodeUnicodeString(File->ID_FullName)) % 256;
654 smprintf(s, "Frame for ending adding file\n");
655 error = GSM_WaitFor (s, end, 14, 0x6D, 4, ID_AddFile);
656 if (error != ERR_NONE) return error;
657
658 CopyUnicodeString(File2.ID_FullName,File->ID_FullName);
659 error = N6510_GetFileFolderInfo1(s, &File2, FALSE);
660 if (error != ERR_NONE) return error;
661
662 if (!File->ModifiedEmpty) {
663 Header[3] = 0x12;
664 Header[4] = 0x01;
665 Header[12] = 0x00;
666 Header[13] = 0xE8;
667 Header[8] = atoi(DecodeUnicodeString(File->ID_FullName)) / 256;
668 Header[9] = atoi(DecodeUnicodeString(File->ID_FullName)) % 256;
669 memset(Header+14, 0x00, 300);
670 CopyUnicodeString(Header+14,File->Name);
671 NOKIA_EncodeDateTime(s,Header+214,&File->Modified);
672 /* When you save too big file for phone and it changes
673 * size (some part is cut by firmware), you HAVE to write
674 * here correct file size. In other case filesystem
675 * will be damaged
676 */
677 Header[224] = File2.Used / 256;
678 Header[225] = File2.Used % 256;
679 Header[226] = Priv->FileToken / 256;
680 Header[227] = Priv->FileToken % 256;
681 switch(File->Type) {
682 case GSM_File_Image_JPG : Header[231]=0x02; Header[233]=0x01; break;
683 case GSM_File_Image_BMP : Header[231]=0x02; Header[233]=0x02; break;
684 case GSM_File_Image_PNG : Header[231]=0x02; Header[233]=0x03; break;
685 case GSM_File_Image_GIF : Header[231]=0x02; Header[233]=0x05; break;
686 case GSM_File_Image_WBMP : Header[231]=0x02; Header[233]=0x09; break;
687 case GSM_File_Sound_AMR : Header[231]=0x04; Header[233]=0x01; break;
688 case GSM_File_Sound_MIDI : Header[231]=0x04; Header[233]=0x05; break; /* Header[238]=0x01; */
689 case GSM_File_Sound_NRT : Header[231]=0x04; Header[233]=0x06; break;
690 case GSM_File_Video_3GP : Header[231]=0x08; Header[233]=0x05; break;
691 case GSM_File_Java_JAR : Header[231]=0x10; Header[233]=0x01; break;
692 case GSM_File_MMS:
693 Header[214]=0x07;
694 Header[215]=0xd3;
695 Header[216]=0x06;
696 Header[217]=0x01;
697 Header[218]=0x12;
698 Header[219]=0x13;
699 Header[220]=0x29;
700 Header[233]=0x01;
701 break;
702 default : Header[231]=0x01; Header[233]=0x05;
703 }
704 Header[235] = 0x01;
705 Header[236] = Priv->ParentID / 256;
706 Header[237] = Priv->ParentID % 256;
707 smprintf(s, "Adding file header\n");
708 error=GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFile);
709 if (error != ERR_NONE) return error;
710 }
711
712 /* Can't delete from phone menu */
713 if (File->ReadOnly) {
714 error = N6510_SetReadOnly1(s, File->ID_FullName, TRUE);
715 if (error != ERR_NONE) return error;
716 }
717
718 error = N6510_GetFileCRC1(s, File->ID_FullName);
719 if (error != ERR_NONE) return error;
720
721 if (N6510_FindFileCheckSum12(s, File->Buffer, File->Used) != Priv->FileCheckSum) {
722 smprintf(s,"File2 checksum is %i, File checksum is %i\n",N6510_FindFileCheckSum12(s, File->Buffer, File->Used),Priv->FileCheckSum);
723 return ERR_WRONGCRC;
724 }
725
726 return ERR_EMPTY;
727 }
728
729 return ERR_NONE;
730 }
731
N6510_ReplyDeleteFileFolder1(GSM_Protocol_Message * msg,GSM_StateMachine * s UNUSED)732 GSM_Error N6510_ReplyDeleteFileFolder1(GSM_Protocol_Message *msg, GSM_StateMachine *s UNUSED)
733 {
734 if (msg->Buffer[4] == 0x01) {
735 return ERR_NONE;
736 } else if (msg->Buffer[4] == 0x04) {
737 return ERR_FILENOTEXIST;
738 }
739 return ERR_UNKNOWNRESPONSE;
740 }
741
N6510_PrivDeleteFileFolder1(GSM_StateMachine * s,unsigned char * ID,gboolean file)742 static GSM_Error N6510_PrivDeleteFileFolder1(GSM_StateMachine *s, unsigned char *ID, gboolean file)
743 {
744 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
745 GSM_File File;
746 GSM_Error error;
747 unsigned char Delete[40] = {
748 N7110_FRAME_HEADER, 0x1E, 0x00, 0x00, 0x00, 0x01,
749 0x00, 0x35}; /* File ID */
750
751 memset(&File, 0, sizeof(File));
752
753 Priv->FilesLocationsUsed = 0;
754 CopyUnicodeString(File.ID_FullName,ID);
755 error = N6510_GetFileFolderInfo1(s, &File, TRUE);
756 if (error != ERR_NONE) return error;
757 if (file) {
758 if (File.Folder) return ERR_SHOULDBEFILE;
759 } else {
760 if (!File.Folder) return ERR_SHOULDBEFOLDER;
761 /* dont allow to delete non empty folder */
762 if (Priv->FilesLocationsUsed != 0) return ERR_FOLDERNOTEMPTY;
763 }
764
765 error = N6510_SetReadOnly1(s, ID, FALSE);
766 if (error != ERR_NONE) return error;
767
768 /* FIXME: This looks wrong */
769 Delete[8] = atoi(DecodeUnicodeString(ID)) / 256;
770 Delete[9] = atoi(DecodeUnicodeString(ID)) % 256;
771
772 return GSM_WaitFor (s, Delete, 10, 0x6D, 4, ID_DeleteFile);
773 }
774
N6510_DeleteFile1(GSM_StateMachine * s,unsigned char * ID)775 static GSM_Error N6510_DeleteFile1(GSM_StateMachine *s, unsigned char *ID)
776 {
777 return N6510_PrivDeleteFileFolder1(s,ID,TRUE);
778 }
779
N6510_DeleteFolder1(GSM_StateMachine * s,unsigned char * ID)780 static GSM_Error N6510_DeleteFolder1(GSM_StateMachine *s, unsigned char *ID)
781 {
782 return N6510_PrivDeleteFileFolder1(s,ID,FALSE);
783 }
784
N6510_ReplyAddFolder1(GSM_Protocol_Message * msg,GSM_StateMachine * s)785 GSM_Error N6510_ReplyAddFolder1(GSM_Protocol_Message *msg, GSM_StateMachine *s)
786 {
787 unsigned char buffer[8];
788
789 sprintf(buffer,"%i",msg->Buffer[8]*256+msg->Buffer[9]);
790 EncodeUnicode(s->Phone.Data.File->ID_FullName,buffer,strlen(buffer));
791 return ERR_NONE;
792 }
793
N6510_AddFolder1(GSM_StateMachine * s,GSM_File * File)794 static GSM_Error N6510_AddFolder1(GSM_StateMachine *s, GSM_File *File)
795 {
796 GSM_File File2;
797 GSM_Error error;
798 unsigned char Header[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))] = {
799 N7110_FRAME_HEADER, 0x04, 0x00, 0x00, 0x00, 0x01,
800 0x00, 0x0C, /* parent folder ID */
801 0x00, 0x00, 0x00, 0xE8};
802
803 memset(&File2, 0, sizeof(File2));
804
805 CopyUnicodeString(File2.ID_FullName,File->ID_FullName);
806 error = N6510_GetFileFolderInfo1(s, &File2, FALSE);
807 if (error != ERR_NONE) return error;
808 if (!File2.Folder) return ERR_SHOULDBEFOLDER;
809
810 Header[8] = atoi(DecodeUnicodeString(File->ID_FullName)) / 256;
811 Header[9] = atoi(DecodeUnicodeString(File->ID_FullName)) % 256;
812 memset(Header+14, 0x00, 300);
813 CopyUnicodeString(Header+14,File->Name);
814 Header[233] = 0x02;
815 Header[235] = 0x01;
816 Header[236] = atoi(DecodeUnicodeString(File->ID_FullName)) / 256;
817 Header[237] = atoi(DecodeUnicodeString(File->ID_FullName)) % 256;
818
819 s->Phone.Data.File = File;
820 smprintf(s, "Adding folder\n");
821 error = GSM_WaitFor (s, Header, 246, 0x6D, 4, ID_AddFolder);
822 if (error != ERR_NONE) return error;
823
824 if (!strcmp(DecodeUnicodeString(File->ID_FullName),"0")) return ERR_FILEALREADYEXIST;
825
826 /* Can't delete from phone menu */
827 if (File->ReadOnly) {
828 error = N6510_SetReadOnly1(s, File->ID_FullName, TRUE);
829 if (error != ERR_NONE) return error;
830 }
831
832 return error;
833 }
834
N6510_GetFolderListing1(GSM_StateMachine * s,GSM_File * File,gboolean start)835 static GSM_Error N6510_GetFolderListing1(GSM_StateMachine *s, GSM_File *File, gboolean start)
836 {
837 GSM_Error error;
838 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
839
840 if (start) {
841 Priv->FilesLocationsUsed = 0;
842
843 error = N6510_GetFileFolderInfo1(s, File, TRUE);
844 if (error != ERR_NONE) return error;
845
846 if (!File->Folder) return ERR_SHOULDBEFOLDER;
847 }
848
849 while (TRUE) {
850 if (Priv->FilesLocationsUsed == 0) return ERR_EMPTY;
851
852 memcpy(File,&Priv->FilesCache[0],sizeof(GSM_File));
853 error = N6510_GetFileFolderInfo1(s, File, FALSE);
854 if (error != ERR_NONE) return error;
855
856 error = N6510_ShiftFileCache(s, -1);
857 if (error != ERR_NONE) return error;
858
859 break;
860 }
861 return error;
862 }
863
864 /* filesystem 2 */
865
N6510_ReplyOpenFile2(GSM_Protocol_Message * msg,GSM_StateMachine * s)866 GSM_Error N6510_ReplyOpenFile2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
867 {
868 if (msg->Buffer[4]==0) {
869 smprintf(s,"File opened and handle received\n");
870 s->Phone.Data.FileHandle = msg->Buffer[6]*256*256*256+
871 msg->Buffer[7]*256*256+
872 msg->Buffer[8]*256+
873 msg->Buffer[9];
874 smprintf(s,"File handle: %i\n",
875 msg->Buffer[6]*256*256*256+
876 msg->Buffer[7]*256*256+
877 msg->Buffer[8]*256+
878 msg->Buffer[9]);
879 return ERR_NONE;
880 } else if (msg->Buffer[4] == 0x03) {
881 smprintf(s,"You can't open already existing folder\n");
882 return ERR_FILEALREADYEXIST;
883 } else if (msg->Buffer[4] == 0x06) {
884 smprintf(s,"File not exist\n");
885 return ERR_FILENOTEXIST;
886 }
887 return ERR_UNKNOWNRESPONSE;
888 }
889
N6510_OpenFile2(GSM_StateMachine * s,char * Name,int * Handle,gboolean Create)890 static GSM_Error N6510_OpenFile2(GSM_StateMachine *s, char *Name, int *Handle, gboolean Create)
891 {
892 unsigned char req[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))] =
893 {N6110_FRAME_HEADER, 0x72,
894 0x00, /* mode 0 - open read only, 0x11 - read write create */
895 0x02,
896 0xFF, 0xFF}; /* name length */
897 int Pos = 8;
898 GSM_Error error;
899
900 if (Create) req[4] = 0x11;
901 req[6] = (UnicodeLength(Name)*2 + 2)/ 256 ;
902 req[7] = (UnicodeLength(Name)*2 + 2)% 256 ;
903 CopyUnicodeString(req+8,Name);
904 if (req[9] == 'a' || req[9] == 'A') req[9] = 'b';
905 if (req[9] == 'd' || req[9] == 'D') req[9] = 'a';
906 Pos+=UnicodeLength(Name)*2;
907 req[Pos++] = 0;
908 req[Pos++] = 0;
909
910 smprintf(s, "Opening file\n");
911 error = GSM_WaitFor (s, req, Pos, 0x6D, 4, ID_OpenFile);
912 if (error==ERR_NONE) (*Handle) = s->Phone.Data.FileHandle;
913 return error;
914 }
915
N6510_CloseFile2(GSM_StateMachine * s,int * Handle)916 static GSM_Error N6510_CloseFile2(GSM_StateMachine *s, int *Handle)
917 {
918 unsigned char req[200] = {N6110_FRAME_HEADER, 0x74, 0x00, 0x00,
919 0x00, 0x00, 0x00, 0x00}; /* file handle */
920
921 req[6] = (*Handle) / (256*256*256);
922 req[7] = (*Handle) / (256*256);
923 req[8] = (*Handle) / 256;
924 req[9] = (*Handle) % 256;
925
926 smprintf(s, "Closing file\n");
927 return GSM_WaitFor (s, req, 10, 0x6D, 4, ID_CloseFile);
928 }
929
N6510_GetFileCRC2(GSM_StateMachine * s,int * Handle)930 static GSM_Error N6510_GetFileCRC2(GSM_StateMachine *s, int *Handle)
931 {
932 unsigned char req2[15000] = {
933 N7110_FRAME_HEADER, 0x66, 0x00, 0x00,
934 0x00, 0x00, 0x00, 0x00}; /* handle */
935
936 req2[6] = (*Handle) / (256*256*256);
937 req2[7] = (*Handle) / (256*256);
938 req2[8] = (*Handle) / 256;
939 req2[9] = (*Handle) % 256;
940 return GSM_WaitFor (s, req2, 10, 0x6D, 8, ID_GetCRC);
941 }
942
N6510_ReplyGetFileFolderInfo2(GSM_Protocol_Message * msg,GSM_StateMachine * s)943 GSM_Error N6510_ReplyGetFileFolderInfo2(GSM_Protocol_Message *msg, GSM_StateMachine *s)
944 {
945 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
946 GSM_File *FileInfo = s->Phone.Data.FileInfo;
947 GSM_File *File;
948 GSM_Error error;
949
950 switch (msg->Buffer[3]) {
951 case 0x69:
952 case 0x6D:
953 switch (msg->Buffer[4]) {
954 case 0x0C:
955 smprintf(s,"Probably no MMC card\n");
956 Priv->filesystem2error = ERR_MEMORY;
957 Priv->FilesEnd = TRUE;
958 return ERR_MEMORY;
959 case 0x00:
960 case 0x0D:
961 switch (msg->Buffer[5]) {
962 case 0x00:
963 break;
964 case 0x06:
965 smprintf(s,"File not exist\n");
966 return ERR_FILENOTEXIST;
967 case 0x0C:
968 smprintf(s,"Probably no MMC card\n");
969 return ERR_MEMORY;
970 default:
971 smprintf(s,"unknown status code\n");
972 return ERR_UNKNOWNRESPONSE;
973 }
974 smprintf(s,"File or folder details received\n");
975
976 if (msg->Buffer[3] == 0x69) {
977 /* File/Folder without can not be handled */
978 if (UnicodeLength(msg->Buffer+32) == 0) {
979 smprintf(s, "Ignoring file without name!\n");
980 return ERR_NONE;
981 }
982 error = N6510_AllocFileCache(s, Priv->FilesLocationsUsed + 1);
983 if (error != ERR_NONE) {
984 return error;
985 }
986
987 error = N6510_ShiftFileCache(s, 1);
988 if (error != ERR_NONE) return error;
989
990 File = &Priv->FilesCache[1];
991
992 File->Level = Priv->FilesCache[0].Level + 1;
993
994 CopyUnicodeString(File->Name,msg->Buffer+32);
995 smprintf(s,"\"%s\"\n",DecodeUnicodeString(File->Name));
996
997 CopyUnicodeString(File->ID_FullName,FileInfo->ID_FullName);
998 EncodeUnicode(File->ID_FullName+UnicodeLength(File->ID_FullName)*2,"/",1);
999 CopyUnicodeString(File->ID_FullName+UnicodeLength(File->ID_FullName)*2,msg->Buffer+32);
1000 smprintf(s,"\"%s\"\n",DecodeUnicodeString(File->ID_FullName));
1001 } else {
1002 File = FileInfo;
1003 }
1004
1005 smprintf(s, "File type: 0x%02X\n", msg->Buffer[29]);
1006 if ((msg->Buffer[29] & 0x10) == 0x10) {
1007 File->Folder = TRUE;
1008 smprintf(s,"Folder\n");
1009 } else {
1010 File->Folder = FALSE;
1011 smprintf(s,"File\n");
1012 File->Used = msg->Buffer[10]*256*256*256+
1013 msg->Buffer[11]*256*256+
1014 msg->Buffer[12]*256+
1015 msg->Buffer[13];
1016 smprintf(s,"Size %ld bytes\n", (long)File->Used);
1017 }
1018 File->ReadOnly = FALSE;
1019 if ((msg->Buffer[29] & 1) == 1) {
1020 File->ReadOnly = TRUE;
1021 smprintf(s,"Readonly\n");
1022 }
1023 File->Hidden = FALSE;
1024 if ((msg->Buffer[29] & 2) == 2) {
1025 File->Hidden = TRUE;
1026 smprintf(s,"Hidden\n");
1027 }
1028 File->System = FALSE;
1029 if ((msg->Buffer[29] & 4) == 4) {
1030 File->System = TRUE;
1031 smprintf(s,"System\n");
1032 }
1033 File->Protected = FALSE;
1034 if ((msg->Buffer[29] & 0x40) == 0x40) {
1035 File->Protected = TRUE;
1036 smprintf(s,"Protected\n");
1037 }
1038
1039 File->ModifiedEmpty = FALSE;
1040 NOKIA_DecodeDateTime(s, msg->Buffer+14, &File->Modified, TRUE, FALSE);
1041 if (File->Modified.Year == 0x00) File->ModifiedEmpty = TRUE;
1042 if (File->Modified.Year == 0xffff) File->ModifiedEmpty = TRUE;
1043
1044 if (msg->Buffer[3] == 0x69 && msg->Buffer[4] == 0) Priv->FilesEnd = TRUE;
1045
1046 return ERR_NONE;
1047 case 0x06:
1048 smprintf(s,"File or folder details received - not available ?\n");
1049 Priv->filesystem2error = ERR_FILENOTEXIST;
1050 Priv->FilesEnd = TRUE;
1051 return ERR_FILENOTEXIST;
1052 case 0x0E:
1053 smprintf(s,"File or folder details received - empty\n");
1054 Priv->FilesEnd = TRUE;
1055 return ERR_NONE;
1056 }
1057 }
1058 return ERR_UNKNOWNRESPONSE;
1059 }
1060
N6510_GetFileFolderInfo2(GSM_StateMachine * s,GSM_File * File)1061 static GSM_Error N6510_GetFileFolderInfo2(GSM_StateMachine *s, GSM_File *File)
1062 {
1063 int Pos=6;
1064 unsigned char req[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))] = {
1065 N7110_FRAME_HEADER,0x6C,
1066 0xFF, 0xFF}; /* name length */
1067
1068 s->Phone.Data.FileInfo = File;
1069
1070 req[4] = (UnicodeLength(File->ID_FullName)*2 + 2)/256;
1071 req[5] = (UnicodeLength(File->ID_FullName)*2 + 2)%256;
1072 CopyUnicodeString(req+6,File->ID_FullName);
1073 if (req[7] == 'a' || req[7] == 'A') req[7] = 'b';
1074 if (req[7] == 'd' || req[7] == 'D') req[7] = 'a';
1075 Pos+=UnicodeLength(File->ID_FullName)*2;
1076 req[Pos++] = 0;
1077 req[Pos++] = 0;
1078
1079 smprintf(s,"Getting info for file in filesystem\n");
1080 return GSM_WaitFor (s, req, Pos, 0x6D, 4, ID_GetFileInfo);
1081 }
1082
N6510_PrivGetFolderListing2(GSM_StateMachine * s,GSM_File * File)1083 static GSM_Error N6510_PrivGetFolderListing2(GSM_StateMachine *s, GSM_File *File)
1084 {
1085 GSM_Error error;
1086 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1087 unsigned char req[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))] = {
1088 N6110_FRAME_HEADER, 0x68,
1089 0xFF, 0xFF}; /* name length */
1090 int Pos = 6, i = 0;
1091
1092 req[4] = (UnicodeLength(File->ID_FullName)*2 + 6)/ 256 ;
1093 req[5] = (UnicodeLength(File->ID_FullName)*2 + 6)% 256 ;
1094 CopyUnicodeString(req+6,File->ID_FullName);
1095 if (req[7] == 'a' || req[7] == 'A') req[7] = 'b';
1096 if (req[7] == 'd' || req[7] == 'D') req[7] = 'a';
1097 Pos+=UnicodeLength(File->ID_FullName)*2;
1098 req[Pos++] = 0;
1099 req[Pos++] = '/';
1100 req[Pos++] = 0;
1101 req[Pos++] = '*';
1102 req[Pos++] = 0;
1103 req[Pos++] = 0;
1104
1105 smprintf(s, "Getting folder info %s\n",DecodeUnicodeString(File->ID_FullName));
1106
1107 Priv->filesystem2error = ERR_NONE;
1108 s->Phone.Data.FileInfo = File;
1109 Priv->FilesEnd = FALSE;
1110 error = s->Protocol.Functions->WriteMessage(s, req, Pos, 0x6D);
1111 if (error!=ERR_NONE) return error;
1112
1113 while (!Priv->FilesEnd) {
1114 usleep(1000);
1115 if (GSM_ReadDevice(s,TRUE) <= 0) {
1116 i++;
1117 } else {
1118 i=0;
1119 }
1120 if (i == 3) {
1121 smprintf(s,"Connection broken or WELL KNOWN phone firmware problem (which makes, that not all files are reported)\n");
1122 Priv->filesystem2error = ERR_FOLDERPART;
1123 return ERR_NONE;
1124 }
1125 }
1126
1127 return ERR_NONE;
1128 }
1129
N6510_GetNextFileFolder2(GSM_StateMachine * s,GSM_File * File,gboolean start)1130 static GSM_Error N6510_GetNextFileFolder2(GSM_StateMachine *s, GSM_File *File, gboolean start)
1131 {
1132 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1133 GSM_Error error;
1134
1135 if (start) {
1136 error = N6510_AllocFileCache(s, 2);
1137 if (error != ERR_NONE) return error;
1138
1139 Priv->FilesLocationsUsed = 2;
1140
1141 Priv->FilesCache[0].Level = 1;
1142 Priv->FilesCache[0].Folder = TRUE;
1143 Priv->FilesCache[0].Level = 1;
1144 Priv->FilesCache[0].ReadOnly = FALSE;
1145 Priv->FilesCache[0].System = FALSE;
1146 Priv->FilesCache[0].Hidden = FALSE;
1147 Priv->FilesCache[0].Protected = FALSE;
1148 EncodeUnicode(Priv->FilesCache[0].ID_FullName,"d:",2);
1149 EncodeUnicode(Priv->FilesCache[0].Name,"D (Permanent_memory 2)",22);
1150
1151 Priv->FilesCache[1].Level = 1;
1152 Priv->FilesCache[1].Folder = TRUE;
1153 Priv->FilesCache[1].Level = 1;
1154 Priv->FilesCache[1].ReadOnly = FALSE;
1155 Priv->FilesCache[1].System = FALSE;
1156 Priv->FilesCache[1].Hidden = FALSE;
1157 Priv->FilesCache[1].Protected = FALSE;
1158 EncodeUnicode(Priv->FilesCache[1].ID_FullName,"a:",2);
1159 EncodeUnicode(Priv->FilesCache[1].Name,"A (Memory card)",15);
1160 }
1161
1162 smprintf(s, "Currently %i locations\n",Priv->FilesLocationsUsed);
1163 if (Priv->FilesLocationsUsed == 0) return ERR_EMPTY;
1164
1165
1166 if (!Priv->FilesCache[0].Folder) {
1167 memcpy(File,&Priv->FilesCache[0],sizeof(GSM_File));
1168 error = N6510_ShiftFileCache(s, -1);
1169 if (error != ERR_NONE) return error;
1170 smprintf(s, "Returning file %s, level %d\n", DecodeUnicodeString(File->ID_FullName), File->Level);
1171 return ERR_NONE;
1172 }
1173
1174 memcpy(File,&Priv->FilesCache[0],sizeof(GSM_File));
1175 error = N6510_PrivGetFolderListing2(s, File);
1176 if (error != ERR_NONE) return error;
1177
1178 memcpy(File,&Priv->FilesCache[0],sizeof(GSM_File));
1179 error = N6510_ShiftFileCache(s, -1);
1180 if (error != ERR_NONE) return error;
1181
1182 smprintf(s, "Returning folder %s, level %d\n", DecodeUnicodeString(File->ID_FullName), File->Level);
1183
1184 if (Priv->filesystem2error == ERR_FOLDERPART) return ERR_FOLDERPART;
1185
1186 return error;
1187 }
1188
N6510_GetFilePart2(GSM_StateMachine * s,GSM_File * File,int * Handle,size_t * Size)1189 static GSM_Error N6510_GetFilePart2(GSM_StateMachine *s, GSM_File *File, int *Handle, size_t *Size)
1190 {
1191 int old,j;
1192 GSM_Error error;
1193 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1194 unsigned char req[] = {
1195 N7110_FRAME_HEADER, 0x5E, 0x00, 0x00,
1196 0x00, 0x00, 0x00, 0x01, /* file handle */
1197 0x00, 0x00, 0x00, 0x00, /* position */
1198 0x00, 0x00, 0x03, 0xE8, /* length */
1199 0x00, 0x00, 0x03, 0xE8}; /* buffer length */
1200
1201 if (File->Used == 0x00) {
1202 error = N6510_GetFileFolderInfo2(s, File);
1203 if (error != ERR_NONE) return error;
1204
1205 if (File->Folder) return ERR_SHOULDBEFILE;
1206
1207 error = N6510_OpenFile2(s, File->ID_FullName, Handle, FALSE);
1208 if (error != ERR_NONE) return error;
1209
1210 for (j=UnicodeLength(File->ID_FullName)-1;j>0;j--) {
1211 if (File->ID_FullName[j*2+1] == '\\' || File->ID_FullName[j*2+1] == '/') break;
1212 }
1213 if (File->ID_FullName[j*2+1] == '\\' || File->ID_FullName[j*2+1] == '/') {
1214 CopyUnicodeString(File->Name,File->ID_FullName+j*2+2);
1215 } else {
1216 CopyUnicodeString(File->Name,File->ID_FullName);
1217 }
1218
1219 (*Size) = File->Used;
1220 File->Used = 0;
1221 }
1222
1223 req[6] = (*Handle) / (256*256*256);
1224 req[7] = (*Handle) / (256*256);
1225 req[8] = (*Handle) / 256;
1226 req[9] = (*Handle) % 256;
1227
1228 old = File->Used;
1229 req[10] = old / (256*256*256);
1230 req[11] = old / (256*256);
1231 req[12] = old / 256;
1232 req[13] = old % 256;
1233
1234 s->Phone.Data.File = File;
1235 smprintf(s, "Getting file part from filesystem\n");
1236 error=GSM_WaitFor (s, req, 22, 0x6D, 4, ID_GetFile);
1237 if (error != ERR_NONE) return error;
1238
1239 if (File->Used - old != (0x03 * 256 + 0xE8)) {
1240 error = N6510_GetFileCRC2(s, Handle);
1241 if (error != ERR_NONE) return error;
1242
1243 error = N6510_CloseFile2(s, Handle);
1244 if (error != ERR_NONE) return error;
1245
1246 if (N6510_FindFileCheckSum12(s, File->Buffer, File->Used) != Priv->FileCheckSum) {
1247 smprintf(s,"File2 checksum is %i, File checksum is %i\n",N6510_FindFileCheckSum12(s, File->Buffer, File->Used),Priv->FileCheckSum);
1248 return ERR_WRONGCRC;
1249 }
1250
1251 return ERR_EMPTY;
1252 }
1253 return ERR_NONE;
1254 }
1255
N6510_ReplySetFileDate2(GSM_Protocol_Message * msg UNUSED,GSM_StateMachine * s UNUSED)1256 GSM_Error N6510_ReplySetFileDate2(GSM_Protocol_Message *msg UNUSED, GSM_StateMachine *s UNUSED)
1257 {
1258 return ERR_NONE;
1259 }
1260
N6510_ReplySetAttrib2(GSM_Protocol_Message * msg,GSM_StateMachine * s UNUSED)1261 GSM_Error N6510_ReplySetAttrib2(GSM_Protocol_Message *msg, GSM_StateMachine *s UNUSED)
1262 {
1263 if (msg->Buffer[4] == 0x00) {
1264 return ERR_NONE;
1265 } else if (msg->Buffer[4] == 0x06) {
1266 return ERR_FILENOTEXIST;
1267 }
1268 return ERR_UNKNOWNRESPONSE;
1269 }
1270
N6510_SetFileAttributes2(GSM_StateMachine * s,GSM_File * File)1271 static GSM_Error N6510_SetFileAttributes2(GSM_StateMachine *s, GSM_File *File)
1272 {
1273 int P = 10;
1274 GSM_Error error;
1275 GSM_File File2;
1276 unsigned char Header2[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))] = {
1277 N7110_FRAME_HEADER, 0x6E,
1278 0x00, 0x0c}; /* name len */
1279
1280 memcpy(&File2,File,sizeof(GSM_File));
1281
1282 error = N6510_GetFileFolderInfo2(s, File);
1283 if (error != ERR_NONE) return error;
1284
1285 /* haven't checked. */
1286 if (File->Folder) return ERR_SHOULDBEFILE;
1287
1288 Header2[4] = (UnicodeLength(File2.ID_FullName) + 1)/ 256 ;
1289 Header2[5] = (UnicodeLength(File2.ID_FullName) + 1)% 256 ;
1290 Header2[6] = 0x00;
1291 Header2[7] = 0x00;
1292 Header2[8] = 0x00;
1293 Header2[9] = 0x00;
1294 if (File2.ReadOnly) Header2[9] += 1;
1295 if (File2.Hidden) Header2[9] += 2;
1296 if (File2.System) Header2[9] += 4;
1297 if (File2.Protected) Header2[9] += 0x40;
1298 CopyUnicodeString(Header2+10,File2.ID_FullName);
1299 if (Header2[11] == 'a' || Header2[11] == 'A') Header2[11] = 'b';
1300 if (Header2[11] == 'd' || Header2[11] == 'D') Header2[11] = 'a';
1301 P+=UnicodeLength(File2.ID_FullName)*2;
1302 Header2[P++] = 0;
1303 Header2[P++] = 0;
1304 error = GSM_WaitFor (s, Header2, P, 0x6D, 4, ID_SetAttrib);
1305 if (error != ERR_NONE) return error;
1306
1307 error = N6510_GetFileFolderInfo2(s, File);
1308 if (error != ERR_NONE) return error;
1309
1310 /* mmc doesn't support protected */
1311 if (File2.System != File->System ||
1312 File2.ReadOnly != File->ReadOnly ||
1313 File2.Hidden != File->Hidden ) {
1314 /* File2.Protected != File->Protected) { */
1315 return ERR_NOTSUPPORTED;
1316 }
1317
1318 return ERR_NONE;
1319 }
1320
N6510_AddFilePart2(GSM_StateMachine * s,GSM_File * File,size_t * Pos,int * Handle)1321 static GSM_Error N6510_AddFilePart2(GSM_StateMachine *s, GSM_File *File, size_t *Pos, int *Handle)
1322 {
1323 GSM_Error error;
1324 int j,P;
1325 /* GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510; */
1326 /* unsigned char buffer[500]; */
1327 unsigned char req[15000] = {
1328 N7110_FRAME_HEADER, 0x58, 0x00, 0x00,
1329 0x00, 0x00, 0x00, 0x00, /* handle */
1330 0x00, 0x00, 0x04, 0x00}; /* buffer len */
1331 unsigned char Header[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))] = {
1332 N7110_FRAME_HEADER, 0x86,
1333 0x00, 0x0c}; /* name len */
1334
1335 s->Phone.Data.File = File;
1336
1337 if (*Pos == 0) {
1338 EncodeUnicode(File->ID_FullName+UnicodeLength(File->ID_FullName)*2,"/",1);
1339 CopyUnicodeString(File->ID_FullName+UnicodeLength(File->ID_FullName)*2,File->Name);
1340
1341 error = N6510_GetFileFolderInfo2(s, File);
1342 switch (error) {
1343 case ERR_FILENOTEXIST:
1344 break;
1345 case ERR_NONE:
1346 return ERR_FILEALREADYEXIST;
1347 default:
1348 return error;
1349 }
1350
1351 error = N6510_OpenFile2(s, File->ID_FullName, Handle, TRUE);
1352 if (error != ERR_NONE) return error;
1353 }
1354
1355 req[6] = (*Handle) / (256*256*256);
1356 req[7] = (*Handle) / (256*256);
1357 req[8] = (*Handle) / 256;
1358 req[9] = (*Handle) % 256;
1359
1360 j = 2000;
1361 if (File->Used - *Pos < 2000) j = File->Used - *Pos;
1362 req[10] = j / (256*256*256);
1363 req[11] = j / (256*256);
1364 req[12] = j / 256;
1365 req[13] = j % 256;
1366 memcpy(req+14,File->Buffer+(*Pos),j);
1367
1368 smprintf(s, "Adding file part %ld %i\n",(long)*Pos,j);
1369 error=GSM_WaitFor (s, req, 14+j, 0x6D, 4, ID_AddFile);
1370 if (error != ERR_NONE) return error;
1371 *Pos = *Pos + j;
1372
1373 if (j < 2000) {
1374 error = N6510_CloseFile2(s, Handle);
1375 if (error != ERR_NONE) return error;
1376
1377 P = 14;
1378 Header[4] = (UnicodeLength(File->ID_FullName) + 1)/ 256 ;
1379 Header[5] = (UnicodeLength(File->ID_FullName) + 1)% 256 ;
1380 Header[6] = File->Modified.Year / 256;
1381 Header[7] = File->Modified.Year % 256;
1382 Header[8] = File->Modified.Month;
1383 Header[9] = File->Modified.Day;
1384 Header[10] = 0x00;
1385 Header[11] = File->Modified.Hour;
1386 Header[12] = File->Modified.Minute;
1387 Header[13] = File->Modified.Second;
1388 CopyUnicodeString(Header+14,File->ID_FullName);
1389 if (Header[15] == 'a' || Header[15] == 'A') Header[15] = 'b';
1390 if (Header[15] == 'd' || Header[15] == 'D') Header[15] = 'a';
1391 P+=UnicodeLength(File->ID_FullName)*2;
1392 req[P++] = 0;
1393 req[P++] = 0;
1394 smprintf(s,"Setting file date\n");
1395 error = GSM_WaitFor (s, Header, P, 0x6D, 4, ID_AddFile);
1396 if (error != ERR_NONE) return error;
1397
1398 error = N6510_SetFileAttributes2(s,File);
1399 if (error != ERR_NONE) return error;
1400
1401 /* error = N6510_OpenFile2(s, File->ID_FullName, Handle, FALSE); */
1402 /* if (error != ERR_NONE) return error; */
1403 /* if ((*Handle) == 0) { */
1404 /* error = N6510_OpenFile2(s, File->ID_FullName, Handle, FALSE); */
1405 /* if (error != ERR_NONE) return error; */
1406 /* } */
1407 /* error = N6510_GetFileCRC2(s, Handle); */
1408 /* if (error != ERR_NONE) return error; */
1409 /* error = N6510_CloseFile2(s, Handle); */
1410 /* if (error != ERR_NONE) return error; */
1411 /* if (N6510_FindFileCheckSum12(s, File->Buffer, File->Used) != Priv->FileCheckSum) { */
1412 /* smprintf(s,"File2 checksum is %i, File checksum is %i\n",N6510_FindFileCheckSum12(s, File->Buffer, File->Used),Priv->FileCheckSum); */
1413 /* return ERR_WRONGCRC; */
1414 /* } */
1415
1416 return ERR_EMPTY;
1417 }
1418
1419 return ERR_NONE;
1420 }
1421
N6510_GetFolderListing2(GSM_StateMachine * s,GSM_File * File,gboolean start)1422 static GSM_Error N6510_GetFolderListing2(GSM_StateMachine *s, GSM_File *File, gboolean start)
1423 {
1424 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1425 GSM_Error error;
1426
1427 if (start) {
1428 if (strcasecmp(DecodeUnicodeString(File->ID_FullName),"a:") == 0 ||
1429 strcasecmp(DecodeUnicodeString(File->ID_FullName),"a:\\") == 0 ||
1430 strcasecmp(DecodeUnicodeString(File->ID_FullName),"d:") == 0 ||
1431 strcasecmp(DecodeUnicodeString(File->ID_FullName),"d:\\") == 0) {
1432 } else {
1433 /* we must check, if user gave folder name or not */
1434 error = N6510_GetFileFolderInfo2(s, File);
1435 if (error != ERR_NONE) return error;
1436 if (!File->Folder) return ERR_SHOULDBEFOLDER;
1437 }
1438
1439 error = N6510_AllocFileCache(s, 1);
1440 if (error != ERR_NONE) return error;
1441
1442 Priv->FilesLocationsUsed = 1;
1443
1444 error = N6510_PrivGetFolderListing2(s, File);
1445 if (error != ERR_NONE) return error;
1446
1447 memcpy(File,&Priv->FilesCache[0],sizeof(GSM_File));
1448
1449 error = N6510_ShiftFileCache(s, -1);
1450 if (error != ERR_NONE) return error;
1451 }
1452
1453 if (Priv->FilesLocationsUsed == 0) return ERR_EMPTY;
1454
1455 memcpy(File,&Priv->FilesCache[0],sizeof(GSM_File));
1456
1457 error = N6510_ShiftFileCache(s, -1);
1458 if (error != ERR_NONE) return error;
1459
1460 if (start) {
1461 if (Priv->filesystem2error == ERR_FOLDERPART) return ERR_FOLDERPART;
1462 }
1463 return ERR_NONE;
1464 }
1465
N6510_ReplyDeleteFile2(GSM_Protocol_Message * msg,GSM_StateMachine * s UNUSED)1466 GSM_Error N6510_ReplyDeleteFile2(GSM_Protocol_Message *msg, GSM_StateMachine *s UNUSED)
1467 {
1468 if (msg->Buffer[4] == 0x00) {
1469 return ERR_NONE;
1470 } else if (msg->Buffer[4] == 0x03) {
1471 /* trying to delete read only */
1472 return ERR_UNKNOWN;
1473 } else if (msg->Buffer[4] == 0x06) {
1474 return ERR_FILENOTEXIST;
1475 }
1476
1477 return ERR_UNKNOWNRESPONSE;
1478 }
1479
N6510_DeleteFile2(GSM_StateMachine * s,unsigned char * ID)1480 static GSM_Error N6510_DeleteFile2(GSM_StateMachine *s, unsigned char *ID)
1481 {
1482 unsigned char req[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))] = {
1483 N7110_FRAME_HEADER, 0x62};
1484 int Pos = 6;
1485 GSM_File file;
1486 GSM_Error error;
1487
1488 /* first remove readonly */
1489 file.ReadOnly = FALSE;
1490 file.Hidden = FALSE;
1491 file.System = FALSE;
1492 file.Protected = FALSE;
1493
1494 CopyUnicodeString(file.ID_FullName,ID);
1495 error = N6510_SetFileAttributes2(s,&file);
1496 if (error != ERR_NONE) return error;
1497
1498 req[4] = (UnicodeLength(ID)*2 + 2)/ 256 ;
1499 req[5] = (UnicodeLength(ID)*2 + 2)% 256 ;
1500 CopyUnicodeString(req+6,ID);
1501 if (req[7] == 'a' || req[7] == 'A') req[7] = 'b';
1502 if (req[7] == 'd' || req[7] == 'D') req[7] = 'a';
1503 Pos+=UnicodeLength(ID)*2;
1504 req[Pos++] = 0;
1505 req[Pos++] = 0;
1506
1507 smprintf(s,"Deleting file\n");
1508 return GSM_WaitFor (s, req, Pos, 0x6D, 4, ID_DeleteFile);
1509 }
1510
N6510_ReplyAddFolder2(GSM_Protocol_Message * msg,GSM_StateMachine * s UNUSED)1511 GSM_Error N6510_ReplyAddFolder2(GSM_Protocol_Message *msg, GSM_StateMachine *s UNUSED)
1512 {
1513 if (msg->Buffer[4] == 0x00) {
1514 return ERR_NONE;
1515 } if (msg->Buffer[4] == 0x04) {
1516 return ERR_FILEALREADYEXIST;
1517 } if (msg->Buffer[4] == 0x06) {
1518 return ERR_FILENOTEXIST;
1519 } if (msg->Buffer[4] == 0x0C) {
1520 return ERR_MEMORY;
1521 }
1522 return ERR_UNKNOWNRESPONSE;
1523 }
1524
N6510_AddFolder2(GSM_StateMachine * s,GSM_File * File)1525 static GSM_Error N6510_AddFolder2(GSM_StateMachine *s, GSM_File *File)
1526 {
1527 GSM_Error error;
1528 unsigned char req[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))] = {
1529 N7110_FRAME_HEADER, 0x64};
1530 int Pos = 6;
1531 int Len = 0;
1532
1533 Len = UnicodeLength(File->ID_FullName)*2 + 2;
1534
1535 CopyUnicodeString(req+6,File->ID_FullName);
1536 Pos+=UnicodeLength(File->ID_FullName)*2;
1537 if (DecodeUnicodeString(File->ID_FullName)[UnicodeLength(File->ID_FullName)-1] != '\\' &&
1538 DecodeUnicodeString(File->ID_FullName)[UnicodeLength(File->ID_FullName)-1] != '/') {
1539 req[Pos++] = 0;
1540 req[Pos++] = '/';
1541 Len += 2;
1542 }
1543 CopyUnicodeString(req+Pos,File->Name);
1544 if (req[Pos+1] == 'a' || req[Pos+1] == 'A') req[Pos+1] = 'b';
1545 if (req[Pos+1] == 'd' || req[Pos+1] == 'D') req[Pos+1] = 'a';
1546 Pos += UnicodeLength(File->Name)*2;
1547 Len += UnicodeLength(File->Name)*2;
1548 req[Pos++] = 0;
1549 req[Pos++] = 0;
1550 req[4] = Len / 256 ;
1551 req[5] = Len % 256 ;
1552 smprintf(s,"Adding folder\n");
1553 error=GSM_WaitFor (s, req, Pos, 0x6D, 4, ID_AddFolder);
1554 if (error == ERR_NONE) memcpy(File->ID_FullName,req+6,Pos);
1555 return error;
1556 }
1557
N6510_ReplyDeleteFolder2(GSM_Protocol_Message * msg,GSM_StateMachine * s UNUSED)1558 GSM_Error N6510_ReplyDeleteFolder2(GSM_Protocol_Message *msg, GSM_StateMachine *s UNUSED)
1559 {
1560 if (msg->Buffer[4] == 0x00) {
1561 return ERR_NONE;
1562 } if (msg->Buffer[4] == 0x03) {
1563 return ERR_SHOULDBEFOLDER;
1564 } if (msg->Buffer[4] == 0x06) {
1565 return ERR_FILENOTEXIST;
1566 } if (msg->Buffer[4] == 0x0C) {
1567 return ERR_MEMORY;
1568 }
1569 return ERR_UNKNOWNRESPONSE;
1570 }
1571
N6510_DeleteFolder2(GSM_StateMachine * s,unsigned char * ID)1572 static GSM_Error N6510_DeleteFolder2(GSM_StateMachine *s, unsigned char *ID)
1573 {
1574 GSM_File File2;
1575 GSM_Error error;
1576 unsigned char req[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))] = {
1577 N7110_FRAME_HEADER, 0x6A};
1578 int Pos = 6;
1579
1580 /* we don't want to allow deleting non empty folders */
1581 CopyUnicodeString(File2.ID_FullName,ID);
1582 error = N6510_GetFolderListing2(s, &File2, TRUE);
1583 switch (error) {
1584 case ERR_EMPTY:
1585 break;
1586 case ERR_NONE:
1587 return ERR_FOLDERNOTEMPTY;
1588 default:
1589 return error;
1590 }
1591
1592 req[4] = (UnicodeLength(ID)*2 + 2)/ 256 ;
1593 req[5] = (UnicodeLength(ID)*2 + 2)% 256 ;
1594 CopyUnicodeString(req+6,ID);
1595 if (req[7] == 'a' || req[7] == 'A') req[7] = 'b';
1596 if (req[7] == 'd' || req[7] == 'D') req[7] = 'a';
1597 Pos+=UnicodeLength(ID)*2;
1598 req[Pos++] = 0;
1599 req[Pos++] = 0;
1600
1601 smprintf(s,"Deleting folder\n");
1602 return GSM_WaitFor (s, req, Pos, 0x6D, 4, ID_DeleteFolder);
1603 }
1604
1605 /* shared */
1606
N6510_GetFolderListing(GSM_StateMachine * s,GSM_File * File,gboolean start)1607 GSM_Error N6510_GetFolderListing(GSM_StateMachine *s, GSM_File *File, gboolean start)
1608 {
1609 GSM_Error error;
1610 GSM_File File2;
1611
1612 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
1613
1614 if (DecodeUnicodeString(File->ID_FullName)[0] == 'c' ||
1615 DecodeUnicodeString(File->ID_FullName)[0] == 'C') {
1616 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30) ||
1617 GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILE1)) {
1618 return ERR_NOTSUPPORTED;
1619 }
1620
1621 memcpy(&File2,File,sizeof(GSM_File));
1622 CopyUnicodeString(File2.ID_FullName,File->ID_FullName+3*2);
1623 error = N6510_GetFolderListing1(s,&File2,start);
1624 memcpy(File,&File2,sizeof(GSM_File));
1625 /* GetFolderListing changes ID */
1626 EncodeUnicode(File->ID_FullName,"c:/",3);
1627 CopyUnicodeString(File->ID_FullName+UnicodeLength(File->ID_FullName)*2,File2.ID_FullName);
1628 return error;
1629 } else {
1630 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_FILES2)) {
1631 return N6510_GetFolderListing2(s,File,start);
1632 } else {
1633 return ERR_NOTSUPPORTED;
1634 }
1635 }
1636 }
1637
N6510_GetNextFileFolder(GSM_StateMachine * s,GSM_File * File,gboolean start)1638 GSM_Error N6510_GetNextFileFolder(GSM_StateMachine *s, GSM_File *File, gboolean start)
1639 {
1640 GSM_Error error;
1641 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1642 char buf[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))];
1643
1644 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
1645
1646 if (start) {
1647 Priv->UseFs1 = TRUE;
1648 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
1649 /* series 40 3.0 don't have filesystem 1 */
1650 Priv->UseFs1 = FALSE;
1651 }
1652 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILE1)) {
1653 Priv->UseFs1 = FALSE;
1654 }
1655 }
1656 if (Priv->UseFs1) {
1657 error = N6510_GetNextFileFolder1(s,File,start);
1658 if (error == ERR_EMPTY) {
1659 if (!GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_FILES2)) {
1660 return error;
1661 }
1662 Priv->UseFs1 = FALSE;
1663 start = TRUE;
1664 } else {
1665 if (error == ERR_NONE) {
1666 sprintf(buf,"c:/%s",DecodeUnicodeString(File->ID_FullName));
1667 EncodeUnicode(File->ID_FullName,buf,strlen(buf));
1668
1669 if (File->Level != 1) return error;
1670
1671 buf[0] = 0;
1672 buf[1] = 0;
1673 CopyUnicodeString(buf,File->Name);
1674 EncodeUnicode(File->Name,"C (",3);
1675 CopyUnicodeString(File->Name+6,buf);
1676 EncodeUnicode(File->Name+UnicodeLength(File->Name)*2,")",1);
1677 }
1678 return error;
1679 }
1680 }
1681 return N6510_GetNextFileFolder2(s,File,start);
1682 }
1683
N6510_GetFilePart(GSM_StateMachine * s,GSM_File * File,int * Handle,size_t * Size)1684 GSM_Error N6510_GetFilePart(GSM_StateMachine *s, GSM_File *File, int *Handle, size_t *Size)
1685 {
1686 GSM_File File2;
1687 char buf[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))];
1688 GSM_Error error;
1689
1690 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
1691
1692 if (DecodeUnicodeString(File->ID_FullName)[0] == 'c' ||
1693 DecodeUnicodeString(File->ID_FullName)[0] == 'C') {
1694 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30) ||
1695 GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILE1)) {
1696 return ERR_NOTSUPPORTED;
1697 }
1698 memcpy(&File2,File,sizeof(GSM_File));
1699 CopyUnicodeString(File2.ID_FullName,File->ID_FullName+3*2);
1700 error = N6510_GetFilePart1(s,&File2, Handle, Size);
1701 CopyUnicodeString(buf,File->ID_FullName);
1702 memcpy(File,&File2,sizeof(GSM_File));
1703 CopyUnicodeString(File->ID_FullName,buf);
1704 return error;
1705 } else {
1706 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_FILES2)) {
1707 return N6510_GetFilePart2(s,File, Handle, Size);
1708 } else {
1709 return ERR_NOTSUPPORTED;
1710 }
1711 }
1712 }
1713
N6510_AddFilePart(GSM_StateMachine * s,GSM_File * File,size_t * Pos,int * Handle)1714 GSM_Error N6510_AddFilePart(GSM_StateMachine *s, GSM_File *File, size_t *Pos, int *Handle)
1715 {
1716 GSM_File File2;
1717 GSM_Error error;
1718
1719 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
1720
1721 if (DecodeUnicodeString(File->ID_FullName)[0] == 'c' ||
1722 DecodeUnicodeString(File->ID_FullName)[0] == 'C') {
1723 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30) ||
1724 GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILE1)) {
1725 return ERR_NOTSUPPORTED;
1726 }
1727
1728 memcpy(&File2,File,sizeof(GSM_File));
1729 CopyUnicodeString(File2.ID_FullName,File->ID_FullName+3*2);
1730 error = N6510_AddFilePart1(s,&File2,Pos,Handle);
1731 memcpy(File,&File2,sizeof(GSM_File));
1732 /* addfilepart returns new ID */
1733 EncodeUnicode(File->ID_FullName,"c:/",3);
1734 CopyUnicodeString(File->ID_FullName+UnicodeLength(File->ID_FullName)*2,File2.ID_FullName);
1735 return error;
1736 } else {
1737 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_FILES2)) {
1738 return N6510_AddFilePart2(s,File,Pos,Handle);
1739 } else {
1740 return ERR_NOTSUPPORTED;
1741 }
1742 }
1743 }
1744
N6510_DeleteFile(GSM_StateMachine * s,unsigned char * ID)1745 GSM_Error N6510_DeleteFile(GSM_StateMachine *s, unsigned char *ID)
1746 {
1747 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
1748
1749 if (DecodeUnicodeString(ID)[0] == 'c' ||
1750 DecodeUnicodeString(ID)[0] == 'C') {
1751 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30) ||
1752 GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILE1)) {
1753 return ERR_NOTSUPPORTED;
1754 }
1755
1756 return N6510_DeleteFile1(s,ID+6);
1757 } else {
1758 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_FILES2)) {
1759 return N6510_DeleteFile2(s,ID);
1760 } else {
1761 return ERR_NOTSUPPORTED;
1762 }
1763 }
1764 }
1765
N6510_AddFolder(GSM_StateMachine * s,GSM_File * File)1766 GSM_Error N6510_AddFolder(GSM_StateMachine *s, GSM_File *File)
1767 {
1768 GSM_File File2;
1769 GSM_Error error;
1770
1771 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
1772
1773 if (DecodeUnicodeString(File->ID_FullName)[0] == 'c' ||
1774 DecodeUnicodeString(File->ID_FullName)[0] == 'C') {
1775 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30) ||
1776 GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILE1)) {
1777 return ERR_NOTSUPPORTED;
1778 }
1779 memcpy(&File2,File,sizeof(GSM_File));
1780 CopyUnicodeString(File2.ID_FullName,File->ID_FullName+3*2);
1781 error = N6510_AddFolder1(s,&File2);
1782 memcpy(File,&File2,sizeof(GSM_File));
1783 /* addfolder returns new ID */
1784 EncodeUnicode(File->ID_FullName,"c:/",3);
1785 CopyUnicodeString(File->ID_FullName+UnicodeLength(File->ID_FullName)*2,File2.ID_FullName);
1786 return error;
1787 } else {
1788 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_FILES2)) {
1789 return N6510_AddFolder2(s,File);
1790 } else {
1791 return ERR_NOTSUPPORTED;
1792 }
1793 }
1794 }
1795
N6510_DeleteFolder(GSM_StateMachine * s,unsigned char * ID)1796 GSM_Error N6510_DeleteFolder(GSM_StateMachine *s, unsigned char *ID)
1797 {
1798 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
1799
1800 if (DecodeUnicodeString(ID)[0] == 'c' ||
1801 DecodeUnicodeString(ID)[0] == 'C') {
1802 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30) ||
1803 GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILE1)) {
1804 return ERR_NOTSUPPORTED;
1805 }
1806 return N6510_DeleteFolder1(s,ID+6);
1807 } else {
1808 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_FILES2)) {
1809 return N6510_DeleteFolder2(s,ID);
1810 } else {
1811 return ERR_NOTSUPPORTED;
1812 }
1813 }
1814 }
1815
N6510_GetFileSystemStatus(GSM_StateMachine * s,GSM_FileSystemStatus * status)1816 GSM_Error N6510_GetFileSystemStatus(GSM_StateMachine *s, GSM_FileSystemStatus *status)
1817 {
1818 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
1819
1820 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_FILES2)) {
1821 return ERR_NOTSUPPORTED;
1822 } else {
1823 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30) ||
1824 GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILE1)) {
1825 return ERR_NOTSUPPORTED;
1826 }
1827 return N6510_GetFileSystemStatus1(s,status);
1828 }
1829 }
1830
N6510_SetFileAttributes(GSM_StateMachine * s,GSM_File * File)1831 GSM_Error N6510_SetFileAttributes(GSM_StateMachine *s, GSM_File *File)
1832 {
1833 GSM_File File2;
1834 char buf[20 + (2 * (GSM_MAX_FILENAME_ID_LENGTH + 1))];
1835 GSM_Error error;
1836
1837 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
1838
1839 if (DecodeUnicodeString(File->ID_FullName)[0] == 'c' ||
1840 DecodeUnicodeString(File->ID_FullName)[0] == 'C') {
1841 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30) ||
1842 GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILE1)) {
1843 return ERR_NOTSUPPORTED;
1844 }
1845 memcpy(&File2,File,sizeof(GSM_File));
1846 CopyUnicodeString(File2.ID_FullName,File->ID_FullName+3*2);
1847 error = N6510_SetFileAttributes1(s,&File2);
1848 CopyUnicodeString(buf,File->ID_FullName);
1849 memcpy(File,&File2,sizeof(GSM_File));
1850 CopyUnicodeString(File->ID_FullName,buf);
1851 return error;
1852 } else {
1853 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_FILES2)) {
1854 return N6510_SetFileAttributes2(s,File);
1855 } else {
1856 return ERR_NOTSUPPORTED;
1857 }
1858 }
1859 }
1860
N6510_GetNextRootFolder(GSM_StateMachine * s,GSM_File * File)1861 GSM_Error N6510_GetNextRootFolder(GSM_StateMachine *s, GSM_File *File)
1862 {
1863 GSM_Error error;
1864 GSM_File File2;
1865 unsigned char buffer[5];
1866
1867 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
1868
1869 memset(&File2, 0, sizeof(File2));
1870
1871 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30) ||
1872 GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILE1)) {
1873 if (UnicodeLength(File->ID_FullName) == 0) {
1874 EncodeUnicode(File->ID_FullName,"d:",2);
1875 EncodeUnicode(File->Name,"D (Permanent_memory 2)",22);
1876 } else if (!strcmp(DecodeUnicodeString(File->ID_FullName),"d:")) {
1877 EncodeUnicode(File->ID_FullName,"a:",2);
1878 error = N6510_GetFolderListing2(s, File, TRUE);
1879 if (error != ERR_NONE && error != ERR_EMPTY) return ERR_EMPTY;
1880 EncodeUnicode(File->Name,"A (Memory card)",15);
1881 EncodeUnicode(File->ID_FullName,"a:",2);
1882 } else {
1883 return ERR_EMPTY;
1884 }
1885 return ERR_NONE;
1886 }
1887
1888 if (UnicodeLength(File->ID_FullName) == 0) {
1889 sprintf(buffer,"%i",0x01);
1890 EncodeUnicode(File2.ID_FullName,buffer,strlen(buffer));
1891 File2.Level = 1;
1892
1893 error = N6510_GetFileFolderInfo1(s, &File2, FALSE);
1894 if (error != ERR_NONE) return error;
1895 }
1896
1897 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_FILES2)) {
1898 if (UnicodeLength(File->ID_FullName) == 0) {
1899 memcpy(File,&File2,sizeof(GSM_File));
1900 EncodeUnicode(File->Name,"C (",3);
1901 CopyUnicodeString(File->Name+6,File2.Name);
1902 EncodeUnicode(File->Name+UnicodeLength(File->Name)*2,")",1);
1903 sprintf(buffer,"c:\\%i",0x01);
1904 EncodeUnicode(File->ID_FullName,buffer,strlen(buffer));
1905 } else if (!strcmp(DecodeUnicodeString(File->ID_FullName),"c:\\1")) {
1906 EncodeUnicode(File->ID_FullName,"d:",2);
1907 EncodeUnicode(File->Name,"D (Permanent_memory 2)",22);
1908 } else if (!strcmp(DecodeUnicodeString(File->ID_FullName),"d:")) {
1909 EncodeUnicode(File->ID_FullName,"a:",2);
1910 error = N6510_GetFolderListing2(s, File, TRUE);
1911 if (error != ERR_NONE && error != ERR_EMPTY) return ERR_EMPTY;
1912 EncodeUnicode(File->Name,"A (Memory card)",15);
1913 EncodeUnicode(File->ID_FullName,"a:",2);
1914 } else {
1915 return ERR_EMPTY;
1916 }
1917 return ERR_NONE;
1918 }
1919 if (UnicodeLength(File->ID_FullName) == 0) {
1920 memcpy(File,&File2,sizeof(GSM_File));
1921 EncodeUnicode(File->Name,"C (",3);
1922 CopyUnicodeString(File->Name+6,File2.Name);
1923 EncodeUnicode(File->Name+UnicodeLength(File->Name)*2,")",1);
1924 sprintf(buffer,"c:\\%i",0x01);
1925 EncodeUnicode(File->ID_FullName,buffer,strlen(buffer));
1926 } else if (!strcmp(DecodeUnicodeString(File->ID_FullName),"c:\\1")) {
1927 return ERR_EMPTY;
1928 }
1929 return ERR_NONE;
1930 }
1931
N6510_PrivGet3220FilesystemMMSFolders(GSM_StateMachine * s,GSM_MMSFolders * folders)1932 GSM_Error N6510_PrivGet3220FilesystemMMSFolders(GSM_StateMachine *s, GSM_MMSFolders *folders)
1933 {
1934 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1935 gboolean Start = TRUE;
1936 GSM_File Files;
1937 GSM_Error error;
1938
1939 memset(&Files, 0, sizeof(Files));
1940
1941 EncodeUnicode(Files.ID_FullName,"d:/predefmessages",17);
1942
1943 folders->Number = 0;
1944
1945 smprintf(s, "Getting MMS folders\n");
1946 while (1) {
1947 error = N6510_GetFolderListing(s,&Files,Start);
1948 if (error == ERR_EMPTY) return ERR_NONE;
1949 if (error != ERR_NONE) return error;
1950
1951 Start = FALSE;
1952
1953 folders->Folder[folders->Number].InboxFolder = FALSE;
1954 if (!strcmp(DecodeUnicodeString(Files.Name),"predefinbox")) {
1955 folders->Folder[folders->Number].InboxFolder = TRUE;
1956 }
1957
1958 CopyUnicodeString(Priv->MMSFoldersID2[folders->Number],Files.ID_FullName);
1959
1960 if (!strcmp(DecodeUnicodeString(Files.Name),"predefinbox")) {
1961 EncodeUnicode(folders->Folder[folders->Number].Name,"Inbox",5);
1962 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefsent")) {
1963 EncodeUnicode(folders->Folder[folders->Number].Name,"Sent items",10);
1964 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefoutbox")) {
1965 EncodeUnicode(folders->Folder[folders->Number].Name,"Outbox",6);
1966 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefdrafts")) {
1967 EncodeUnicode(folders->Folder[folders->Number].Name,"Templates",9);
1968 } else {
1969 continue;
1970 }
1971
1972 folders->Number++;
1973 }
1974 }
1975
1976 /* Series 40 3.0 */
N6510_PrivGetFilesystemMMSFolders(GSM_StateMachine * s,GSM_MMSFolders * folders)1977 GSM_Error N6510_PrivGetFilesystemMMSFolders(GSM_StateMachine *s, GSM_MMSFolders *folders)
1978 {
1979 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
1980 gboolean Start = TRUE;
1981 GSM_File Files;
1982 GSM_Error error;
1983
1984 memset(&Files, 0, sizeof(Files));
1985
1986 EncodeUnicode(Files.ID_FullName,"d:/predefmessages",17);
1987
1988 folders->Number = 0;
1989
1990 smprintf(s, "Getting MMS folders\n");
1991 while (1) {
1992 error = N6510_GetFolderListing(s,&Files,Start);
1993 if (error == ERR_EMPTY) return ERR_NONE;
1994 if (error != ERR_NONE) return error;
1995
1996 Start = FALSE;
1997
1998 if (!strcmp(DecodeUnicodeString(Files.Name),"exchange")) {
1999 continue;
2000 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefdrafts")) {
2001 continue;
2002 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefsent")) {
2003 continue;
2004 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefoutbox")) {
2005 continue;
2006 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefinbox")) {
2007 continue;
2008 }
2009
2010 folders->Folder[folders->Number].InboxFolder = FALSE;
2011 if (!strcmp(DecodeUnicodeString(Files.Name),"1")) {
2012 folders->Folder[folders->Number].InboxFolder = TRUE;
2013 }
2014
2015 CopyUnicodeString(Priv->MMSFoldersID2[folders->Number],Files.ID_FullName);
2016
2017 if (!strcmp(DecodeUnicodeString(Files.Name),"1")) {
2018 EncodeUnicode(folders->Folder[folders->Number].Name,"Inbox",5);
2019 } else if (!strcmp(DecodeUnicodeString(Files.Name),"3")) {
2020 EncodeUnicode(folders->Folder[folders->Number].Name,"Sent items",10);
2021 } else if (!strcmp(DecodeUnicodeString(Files.Name),"4")) {
2022 EncodeUnicode(folders->Folder[folders->Number].Name,"Saved messages",14);
2023 } else if (!strcmp(DecodeUnicodeString(Files.Name),"5")) {
2024 EncodeUnicode(folders->Folder[folders->Number].Name,"Drafts",6);
2025 } else if (!strcmp(DecodeUnicodeString(Files.Name),"6")) {
2026 EncodeUnicode(folders->Folder[folders->Number].Name,"Templates",9);
2027 } else {
2028 CopyUnicodeString(folders->Folder[folders->Number].Name,Files.Name);
2029 }
2030
2031 folders->Number++;
2032 }
2033 }
2034
N6510_GetMMSFolders(GSM_StateMachine * s,GSM_MMSFolders * folders)2035 GSM_Error N6510_GetMMSFolders(GSM_StateMachine *s, GSM_MMSFolders *folders)
2036 {
2037 GSM_Error error;
2038 GSM_File Files;
2039 gboolean Start = TRUE;
2040 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
2041 int i;
2042
2043
2044 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_NOFILESYSTEM)) return ERR_NOTSUPPORTED;
2045
2046 memset(&Files, 0, sizeof(Files));
2047
2048 for (i=0;i<10;i++) {
2049 Priv->MMSFoldersID2[i][0] = 0;
2050 Priv->MMSFoldersID2[i][1] = 0;
2051 }
2052
2053 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_3220_MMS)) {
2054 return N6510_PrivGet3220FilesystemMMSFolders(s,folders);
2055 }
2056
2057 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2058 return N6510_PrivGetFilesystemMMSFolders(s,folders);
2059 }
2060
2061 EncodeUnicode(Files.ID_FullName,"c:/1",4);
2062 while (1) {
2063 error = N6510_GetFolderListing(s,&Files,Start);
2064 if (error == ERR_EMPTY) break;
2065 if (error != ERR_NONE) return error;
2066 Start = FALSE;
2067 if (!Files.Folder || strcmp(DecodeUnicodeConsole(Files.Name),"Messages")) {
2068 continue;
2069 }
2070 Start = TRUE;
2071 folders->Number = 0;
2072
2073 while (1) {
2074 error = N6510_GetFolderListing(s,&Files,Start);
2075 if (error == ERR_EMPTY) return ERR_NONE;
2076 if (error != ERR_NONE) return error;
2077 Start = FALSE;
2078 if (!Files.Folder) continue;
2079 CopyUnicodeString(folders->Folder[folders->Number].Name,Files.Name);
2080 CopyUnicodeString(Priv->MMSFoldersID2[folders->Number],Files.ID_FullName);
2081 folders->Folder[folders->Number].InboxFolder = FALSE;
2082 if (!strcmp(DecodeUnicodeString(Files.Name),"Inbox")) {
2083 folders->Folder[folders->Number].InboxFolder = TRUE;
2084 }
2085 folders->Number++;
2086 }
2087 }
2088
2089 /* 6230i */
2090 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_FILES2)) {
2091 EncodeUnicode(Files.ID_FullName,"d:/predefmessages",17);
2092 folders->Number = 0;
2093 Start = TRUE;
2094 while (1) {
2095 error = N6510_GetFolderListing(s,&Files,Start);
2096 if (error == ERR_EMPTY) break;
2097 if (error != ERR_NONE) return error;
2098 Start = FALSE;
2099 if (!Files.Folder) continue;
2100 folders->Folder[folders->Number].InboxFolder = FALSE;
2101 if (!strcmp(DecodeUnicodeString(Files.Name),"predefinbox")) {
2102 EncodeUnicode(folders->Folder[folders->Number].Name,"Inbox",5);
2103 folders->Folder[folders->Number].InboxFolder = TRUE;
2104 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefoutbox")) {
2105 EncodeUnicode(folders->Folder[folders->Number].Name,"Outbox",6);
2106 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefsent")) {
2107 EncodeUnicode(folders->Folder[folders->Number].Name,"Sent items",10);
2108 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefdrafts")) {
2109 EncodeUnicode(folders->Folder[folders->Number].Name,"Drafts",6);
2110 } else {
2111 CopyUnicodeString(folders->Folder[folders->Number].Name,Files.Name);
2112 }
2113 CopyUnicodeString(Priv->MMSFoldersID2[folders->Number],Files.ID_FullName);
2114 folders->Number++;
2115 }
2116
2117 return ERR_NONE;
2118 }
2119
2120 return ERR_NOTSUPPORTED;
2121 }
2122
N6510_GetNextMMSFileInfo(GSM_StateMachine * s,unsigned char * FileID,int * MMSFolder,gboolean start)2123 GSM_Error N6510_GetNextMMSFileInfo(GSM_StateMachine *s, unsigned char *FileID, int *MMSFolder, gboolean start)
2124 {
2125 GSM_MMSFolders folders;
2126 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
2127 GSM_Error error;
2128 GSM_File file;
2129 int Handle;
2130 size_t Size;
2131
2132 if (start) {
2133 error = N6510_GetMMSFolders(s, &folders);
2134 if (error != ERR_NONE)
2135 return error;
2136
2137 Priv->MMSFolderNum = 0;
2138 Priv->MMSFolderError = ERR_EMPTY;
2139 }
2140
2141 while(TRUE) {
2142 if (Priv->MMSFolderError == ERR_NONE) {
2143 Priv->MMSFolderError = N6510_GetFolderListing(s,&Priv->MMSFile,FALSE);
2144 if (Priv->MMSFolderError != ERR_EMPTY && Priv->MMSFolderError != ERR_NONE)
2145 return Priv->MMSFolderError;
2146 }
2147
2148 if (Priv->MMSFolderError == ERR_EMPTY) {
2149 while (1) {
2150 if (UnicodeLength(Priv->MMSFoldersID2[Priv->MMSFolderNum]) == 0)
2151 return ERR_EMPTY;
2152
2153 CopyUnicodeString(Priv->MMSFile.ID_FullName,Priv->MMSFoldersID2[Priv->MMSFolderNum]);
2154 Priv->MMSFolderNum++;
2155
2156 Priv->MMSFolderError = N6510_GetFolderListing(s,&Priv->MMSFile,TRUE);
2157 if (Priv->MMSFolderError == ERR_EMPTY)
2158 continue;
2159 if (Priv->MMSFolderError != ERR_NONE)
2160 return Priv->MMSFolderError;
2161 break;
2162 }
2163 }
2164 (*MMSFolder) = Priv->MMSFolderNum;
2165 CopyUnicodeString(FileID,Priv->MMSFile.ID_FullName);
2166
2167 if (GSM_IsPhoneFeatureAvailable(s->Phone.Data.ModelInfo, F_SERIES40_30)) {
2168 CopyUnicodeString(file.ID_FullName,FileID);
2169 file.Used = 0;
2170 file.Buffer = NULL;
2171 error = N6510_GetFilePart2(s, &file, &Handle, &Size);
2172 if (error == ERR_NONE) {
2173 error = N6510_CloseFile2(s, &Handle);
2174 if (error != ERR_NONE)
2175 return error;
2176 } else if (error != ERR_EMPTY) {
2177 return error;
2178 }
2179
2180 /* 0x00 = SMS, 0x01,0x03 = MMS */
2181 if (file.Buffer[6] != 0x00) {
2182 free(file.Buffer);
2183 file.Buffer = NULL;
2184 break;
2185 }
2186 free(file.Buffer);
2187 file.Buffer = NULL;
2188 } else {
2189 break;
2190 }
2191 }
2192
2193 return ERR_NONE;
2194 }
2195
2196 /* Series 40 3.0 */
N6510_PrivGetFilesystemSMSFolders(GSM_StateMachine * s,GSM_SMSFolders * folders,gboolean real)2197 GSM_Error N6510_PrivGetFilesystemSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders, gboolean real)
2198 {
2199 gboolean Start = TRUE;
2200 GSM_File Files;
2201 GSM_Error error;
2202
2203 EncodeUnicode(Files.ID_FullName,"d:/predefmessages",17);
2204
2205 folders->Number = 0;
2206
2207 smprintf(s, "Getting SMS folders\n");
2208 while (1) {
2209 error = N6510_GetFolderListing(s,&Files,Start);
2210 if (error == ERR_EMPTY) return ERR_NONE;
2211 if (error != ERR_NONE) return error;
2212
2213 Start = FALSE;
2214
2215 smprintf(s, "Folder name: '%s'\n", DecodeUnicodeString(Files.Name));
2216
2217 if (!strcmp(DecodeUnicodeString(Files.Name),"exchange")) {
2218 continue;
2219 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefdrafts")) {
2220 continue;
2221 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefsent")) {
2222 continue;
2223 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefoutbox")) {
2224 continue;
2225 } else if (!strcmp(DecodeUnicodeString(Files.Name),"predefinbox")) {
2226 continue;
2227 }
2228
2229 folders->Folder[folders->Number].InboxFolder = FALSE;
2230 if (!strcmp(DecodeUnicodeString(Files.Name),"1")) {
2231 folders->Folder[folders->Number].InboxFolder = TRUE;
2232 }
2233 folders->Folder[folders->Number].OutboxFolder = FALSE;
2234 if (!strcmp(DecodeUnicodeString(Files.Name),"2")) {
2235 folders->Folder[folders->Number].OutboxFolder = TRUE;
2236 }
2237 if (real) {
2238 CopyUnicodeString(folders->Folder[folders->Number].Name,Files.Name);
2239 } else {
2240 if (!strcmp(DecodeUnicodeString(Files.Name),"1")) {
2241 EncodeUnicode(folders->Folder[folders->Number].Name,"Inbox",5);
2242 } else if (!strcmp(DecodeUnicodeString(Files.Name),"2")) {
2243 EncodeUnicode(folders->Folder[folders->Number].Name,"Outbox",6);
2244 } else if (!strcmp(DecodeUnicodeString(Files.Name),"3")) {
2245 EncodeUnicode(folders->Folder[folders->Number].Name,"Sent items",10);
2246 } else if (!strcmp(DecodeUnicodeString(Files.Name),"4")) {
2247 EncodeUnicode(folders->Folder[folders->Number].Name,"Saved messages",14);
2248 } else if (!strcmp(DecodeUnicodeString(Files.Name),"5")) {
2249 EncodeUnicode(folders->Folder[folders->Number].Name,"Drafts",6);
2250 } else if (!strcmp(DecodeUnicodeString(Files.Name),"6")) {
2251 EncodeUnicode(folders->Folder[folders->Number].Name,"Templates",9);
2252 } else {
2253 EncodeUnicode(folders->Folder[folders->Number].Name,"User folder ",12);
2254 CopyUnicodeString(folders->Folder[folders->Number].Name + 24, Files.Name);
2255 }
2256 }
2257 folders->Folder[folders->Number].Memory = MEM_ME;
2258 smprintf(s, "Folder[%d] = \"%s\", memory: %s, inbox: %d, outbox: %d\n",
2259 folders->Number,
2260 DecodeUnicodeString(folders->Folder[folders->Number].Name),
2261 GSM_MemoryTypeToString(folders->Folder[folders->Number].Memory),
2262 folders->Folder[folders->Number].InboxFolder,
2263 folders->Folder[folders->Number].OutboxFolder);
2264 folders->Number++;
2265 }
2266 }
2267
2268 /* Series 40 3.0 */
N6510_GetFilesystemSMSFolders(GSM_StateMachine * s,GSM_SMSFolders * folders)2269 GSM_Error N6510_GetFilesystemSMSFolders(GSM_StateMachine *s, GSM_SMSFolders *folders)
2270 {
2271 return N6510_PrivGetFilesystemSMSFolders(s, folders, FALSE);
2272 }
2273
2274 /* Series 40 3.0 */
N26510_GetSMSLocation(GSM_StateMachine * s,GSM_SMSMessage * sms,unsigned char * folderid,int * location)2275 static void N26510_GetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char *folderid, int *location)
2276 {
2277 int ifolderid;
2278
2279 /* simulate flat SMS memory */
2280 if (sms->Folder==0x00) {
2281 ifolderid = sms->Location / GSM_PHONE_MAXSMSINFOLDER;
2282 *folderid = ifolderid + 0x01;
2283 *location = sms->Location - ifolderid * GSM_PHONE_MAXSMSINFOLDER;
2284 } else {
2285 *folderid = sms->Folder;
2286 *location = sms->Location;
2287 }
2288 smprintf(s, "SMS folder %i & location %i -> 6510 folder %i & location %i\n",
2289 sms->Folder,sms->Location,*folderid,*location);
2290 }
2291
2292 /* Series 40 3.0 */
N26510_SetSMSLocation(GSM_StateMachine * s,GSM_SMSMessage * sms,unsigned char folderid,int location)2293 static void N26510_SetSMSLocation(GSM_StateMachine *s, GSM_SMSMessage *sms, unsigned char folderid, int location)
2294 {
2295 sms->Folder = 0;
2296 sms->Location = (folderid - 0x01) * GSM_PHONE_MAXSMSINFOLDER + location;
2297 smprintf(s, "6510 folder %i & location %i -> SMS folder %i & location %i\n",
2298 folderid,location,sms->Folder,sms->Location);
2299 }
2300
2301 /* Series 40 3.0 */
N6510_DecodeFilesystemSMS(GSM_StateMachine * s,GSM_MultiSMSMessage * sms,GSM_File * FFF,int location)2302 GSM_Error N6510_DecodeFilesystemSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, GSM_File *FFF, int location)
2303 {
2304 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
2305 size_t parse_len, pos;
2306 int loc;
2307 GSM_Error error;
2308 gboolean unknown, has_number;
2309
2310 sms->Number = 1;
2311 sms->SMS[0].OtherNumbersNum = 0;
2312
2313 loc = sms->SMS[0].Location;
2314
2315 if (FFF->Used < 96) {
2316 smprintf(s, "Too short message data!\n");
2317 return ERR_CORRUPTED;
2318 }
2319
2320 /* Copy recipient/sender number */
2321 /* Data we get from PDU seem to be bogus */
2322 /* This might be later overwriten using tags at the end of file */
2323 CopyUnicodeString(sms->SMS[0].Number, FFF->Buffer + 94);
2324 smprintf(s, "SMS number: %s\n", DecodeUnicodeString(sms->SMS[0].Number));
2325 has_number = FALSE;
2326
2327 /* Do we have any PDU data? */
2328 if (FFF->Buffer[7] > 0 && FFF->Used > 176) {
2329 /* Parse PDU data */
2330 error = GSM_DecodePDUFrame(&(s->di), &(sms->SMS[0]), FFF->Buffer + 176, FFF->Used - 176, &parse_len, FALSE);
2331 if (error != ERR_NONE) return error;
2332
2333 sms->SMS[0].Location = loc;
2334
2335 switch (sms->SMS[0].PDU) {
2336 case SMS_Deliver:
2337 sms->SMS[0].State = SMS_Read; /* @bug FIXME: this is wrong */
2338 break;
2339 case SMS_Submit:
2340 sms->SMS[0].State = SMS_Sent; /* @bug FIXME: this is wrong */
2341 break;
2342 case SMS_Status_Report:
2343 sms->SMS[0].State = SMS_Read; /* @bug FIXME: this is wrong */
2344 break;
2345 }
2346
2347 if (parse_len != FFF->Buffer[7]) {
2348 smprintf(s, "ERROR: Parsed PDU data have different length than header says!\n");
2349 return ERR_CORRUPTED;
2350 }
2351 } else {
2352 GSM_SetDefaultReceivedSMSData(&sms->SMS[0]);
2353 sms->SMS[0].PDU = SMS_Submit;
2354 sms->SMS[0].State = SMS_Read; /* @bug FIXME: this is wrong */
2355 }
2356
2357 /* Process structured data */
2358 pos = 176 + FFF->Buffer[7];
2359
2360 /* No structured data? */
2361 if (pos >= FFF->Used) {
2362 goto done;
2363 }
2364
2365 /* First master block - 0x01 <WORD LENGTH> */
2366 if (FFF->Buffer[pos] != 0x01) {
2367 smprintf(s, "Unknown block in SMS data after PDU: 0x%02x\n", FFF->Buffer[pos]);
2368 DumpMessage(&(s->di), FFF->Buffer + pos, FFF->Used - pos);
2369 return ERR_UNKNOWN;
2370 }
2371 pos += 3;
2372
2373 while (pos < FFF->Used) {
2374 unknown = FALSE;
2375 if (pos + 1 >= FFF->Used) {
2376 if (pos + 1 == FFF->Used && FFF->Buffer[pos] == 0x00) {
2377 smprintf(s, "File padded with 0x00, assuming it is okay\n");
2378 break;
2379 }
2380 smprintf(s, "ERROR: Reach end of file before type of block!\n");
2381 return ERR_BUG;
2382 }
2383 if (FFF->Buffer[pos] == 0x00) {
2384 smprintf(s, "WARNING: 0x00 block, assuming rest is just junk!\n");
2385 break;
2386 }
2387 if (pos + 2 == FFF->Used && FFF->Buffer[pos] == 0x01) {
2388 smprintf(s, "WARNING: 0x01 block, assuming rest is just junk!\n");
2389 break;
2390 }
2391 if (pos + 2 >= FFF->Used) {
2392 smprintf(s, "ERROR: Reach end of file before size of block!\n");
2393 return ERR_BUG;
2394 }
2395 switch (FFF->Buffer[pos]) {
2396 case 0x02: /* SMSC number, ASCII */
2397 if (FFF->Buffer[pos + 2] <= 1) break;
2398 if (FFF->Buffer[pos + 2] - 1 > GSM_MAX_NUMBER_LENGTH) {
2399 smprintf(s, "WARNING: Too long SMS number, ignoring!\n");
2400 } else {
2401 EncodeUnicode(sms->SMS[0].SMSC.Number, FFF->Buffer + pos + 3, FFF->Buffer[pos + 2]);
2402 }
2403 break;
2404 case 0x03: /* Name, unicode */
2405 if (FFF->Buffer[pos + 2] <= 1) break;
2406 if (FFF->Buffer[pos + 2]/2 - 1 > GSM_MAX_SMS_NAME_LENGTH) {
2407 smprintf(s, "WARNING: Too long SMS name, ignoring!\n");
2408 } else {
2409 CopyUnicodeString(sms->SMS[0].Name, FFF->Buffer + pos + 3);
2410 }
2411 break;
2412 case 0x04: /* Sender, unicode */
2413 case 0x05: /* Recipient, unicode */
2414 case 0x2b: /* some text (Sender?), unicode */
2415 if (FFF->Buffer[pos + 2] <= 1) break;
2416 if (FFF->Buffer[pos + 2]/2 - 1 > GSM_MAX_NUMBER_LENGTH) {
2417 smprintf(s, "WARNING: Too long SMS number, ignoring!\n");
2418 } else {
2419 if (!has_number) {
2420 CopyUnicodeString(sms->SMS[0].Number, FFF->Buffer + pos + 3);
2421 has_number = TRUE;
2422 } else {
2423 if (sms->SMS[0].OtherNumbersNum < GSM_SMS_OTHER_NUMBERS) {
2424 CopyUnicodeString(sms->SMS[0].OtherNumbers[sms->SMS[0].OtherNumbersNum++], FFF->Buffer + pos + 3);
2425 } else {
2426 smprintf(s, "WARNING: Too many recipients, ignoring some!\n");
2427 }
2428 }
2429 }
2430 break;
2431 case 0x25: /* Some unicode text (Name?) */
2432 case 0x20: /* Some ascii text (GmailId) */
2433 unknown = TRUE;
2434 break;
2435 case 0x01:
2436 /* This is probably 0 = received, 1 = sent */
2437 if (FFF->Buffer[pos + 2] != 1 ||
2438 (FFF->Buffer[pos + 3] != 0x00 && FFF->Buffer[pos + 3] != 0x01)) {
2439 unknown = TRUE;
2440 }
2441 break;
2442 case 0x0c:
2443 /* This seems to be message ID (per number) */
2444 break;
2445 case 0x24:
2446 /* 24$|00 |01 |01 */
2447 /* 24$|00 |01 |00 */
2448 if ((FFF->Buffer[pos + 2] != 1 || FFF->Buffer[pos + 3] != 1) &&
2449 (FFF->Buffer[pos + 2] != 1 || FFF->Buffer[pos + 3] != 0)) {
2450 unknown = TRUE;
2451 }
2452 break;
2453 case 0x07:
2454 /* 07 |00 |01 |00 */
2455 if (FFF->Buffer[pos + 2] != 1 || (FFF->Buffer[pos + 3] != 0x0F && FFF->Buffer[pos + 3] != 0x0e && FFF->Buffer[pos + 3] != 0x00)) {
2456 unknown = TRUE;
2457 }
2458 break;
2459 case 0x0b:
2460 case 0x0e:
2461 case 0x22:
2462 /* 22"|00 |01 |84 */
2463 case 0x26:
2464 case 0x27:
2465 case 0x2a:
2466 case 0x2f:
2467 case 0x08:
2468 if (FFF->Buffer[pos + 2] != 1 || FFF->Buffer[pos + 3] != 0x00) {
2469 unknown = TRUE;
2470 }
2471 break;
2472 case 0x06:
2473 case 0x09:
2474 case 0x12:
2475 /* Some ID: 12 |00 |04 |355|EA |6En|D2 */
2476 case 0x23:
2477 /* Some ID: 23#|00 |04 |00 |00 |09 |A6 */
2478 case 0x2D:
2479 /* Some ID: 2D-|00 |04 |00 |00 |00 |00 */
2480 if (FFF->Buffer[pos + 2] != 4 ||
2481 FFF->Buffer[pos + 3] != 0x00 ||
2482 FFF->Buffer[pos + 4] != 0x00 ||
2483 FFF->Buffer[pos + 5] != 0x00 ||
2484 FFF->Buffer[pos + 6] != 0x00
2485 ) {
2486 unknown = TRUE;
2487 }
2488 break;
2489 case 0x0f:
2490 if (FFF->Buffer[pos + 2] != 2 ||
2491 FFF->Buffer[pos + 3] != 0x00 ||
2492 FFF->Buffer[pos + 4] != 0x00
2493 ) {
2494 unknown = TRUE;
2495 }
2496 break;
2497 default:
2498 unknown = TRUE;
2499 break;
2500 }
2501 if (unknown) {
2502 smprintf(s, "WARNING: Unknown block 0x%02x, see <https://wammu.eu/support/bugs/> how to report\n", FFF->Buffer[pos]);
2503 DumpMessage(&(s->di), FFF->Buffer + pos, 3 + (FFF->Buffer[pos + 1] << 8) + FFF->Buffer[pos + 2]);
2504 #ifdef DEBUG
2505 } else {
2506 smprintf(s, "Decoded block 0x%02x\n", FFF->Buffer[pos]);
2507 DumpMessage(&(s->di), FFF->Buffer + pos, 3 + (FFF->Buffer[pos + 1] << 8) + FFF->Buffer[pos + 2]);
2508 #endif
2509 }
2510 pos += 3 + (FFF->Buffer[pos + 1] << 8) + FFF->Buffer[pos + 2];
2511 }
2512
2513 done:
2514 sms->SMS[0].DateTime = FFF->Modified;
2515 sms->SMS[0].DateTime.Timezone = 0;
2516
2517 free(FFF->Buffer);
2518 FFF->Buffer = NULL;
2519
2520 N26510_SetSMSLocation(s, &sms->SMS[0], 0, location);
2521
2522 sms->SMS[0].Folder = Priv->SMSFileFolder;
2523 smprintf(s, "Folder[%d] %s: %d\n", sms->SMS[0].Folder, DecodeUnicodeString(Priv->LastSMSFolders.Folder[sms->SMS[0].Folder].Name), Priv->LastSMSFolders.Folder[sms->SMS[0].Folder].InboxFolder);
2524 sms->SMS[0].InboxFolder = Priv->LastSMSFolders.Folder[sms->SMS[0].Folder].InboxFolder;
2525 sms->SMS[0].Location = 0; /* fixme */
2526
2527 return ERR_NONE;
2528 }
2529
N6510_GetNextFilesystemSMS(GSM_StateMachine * s,GSM_MultiSMSMessage * sms,gboolean start)2530 GSM_Error N6510_GetNextFilesystemSMS(GSM_StateMachine *s, GSM_MultiSMSMessage *sms, gboolean start)
2531 {
2532 GSM_Phone_N6510Data *Priv = &s->Phone.Data.Priv.N6510;
2533 unsigned char folderid;
2534 int location,Handle;
2535 size_t Size;
2536 GSM_Error error;
2537 GSM_File FFF;
2538 gboolean start2=start;
2539
2540 GSM_SetDefaultReceivedSMSData(&sms->SMS[0]);
2541
2542 while (TRUE) {
2543 if (start2) {
2544 Priv->SMSFileError = ERR_EMPTY;
2545 Priv->SMSFileFolder = 0;
2546 location = 1;
2547 error=N6510_PrivGetFilesystemSMSFolders(s,&Priv->LastSMSFolders,TRUE);
2548 if (error!=ERR_NONE) return error;
2549 } else {
2550 sms->SMS[0].Folder = 0;
2551 N26510_GetSMSLocation(s, &sms->SMS[0], &folderid, &location);
2552 location++;
2553 if (Priv->SMSFileError != ERR_EMPTY) {
2554 Priv->SMSFileError = N6510_GetFolderListing(s,&Priv->SMSFile,FALSE);
2555 }
2556 }
2557 start2 = FALSE;
2558 while (Priv->SMSFileError == ERR_EMPTY) {
2559 Priv->SMSFileFolder++;
2560 /* Too high folder number */
2561 if (Priv->SMSFileFolder > Priv->LastSMSFolders.Number) {
2562 return ERR_EMPTY;
2563 }
2564
2565 EncodeUnicode(Priv->SMSFile.ID_FullName, "d:/predefmessages/", 18);
2566 CopyUnicodeString(Priv->SMSFile.ID_FullName + 36, Priv->LastSMSFolders.Folder[Priv->SMSFileFolder-1].Name);
2567 smprintf(s,"folder name is %s\n", DecodeUnicodeString(Priv->SMSFile.ID_FullName));
2568
2569 Priv->SMSFileError = N6510_GetFolderListing(s,&Priv->SMSFile,TRUE);
2570 }
2571
2572 /* readfile */
2573 FFF.Buffer= NULL;
2574 FFF.Used = 0;
2575 FFF.ID_FullName[0] = 0;
2576 FFF.ID_FullName[1] = 0;
2577 CopyUnicodeString(FFF.ID_FullName,Priv->SMSFile.ID_FullName);
2578 smprintf(s,"sms file name is %s\n",DecodeUnicodeString(FFF.ID_FullName));
2579 error = ERR_NONE;
2580 while (error == ERR_NONE) {
2581 error = N6510_GetFilePart(s,&FFF,&Handle,&Size);
2582 /* if mms, don't read all */
2583 if (error==ERR_NONE && FFF.Used>5 && FFF.Buffer[6] != 0x00) {
2584 error = N6510_CloseFile2(s, &Handle);
2585 if (error != ERR_NONE) return error;
2586 break;
2587 }
2588 }
2589 if (FFF.Buffer != NULL) {
2590 DumpMessage(&s->di, FFF.Buffer, FFF.Used);
2591
2592 /* 0x00 = SMS, 0x01,0x03 = MMS
2593 * We care only messages with PDU */
2594 if (FFF.Buffer[6] == 0x00 && FFF.Buffer[7] != 0) break;
2595
2596
2597 smprintf(s,"mms file");
2598 free(FFF.Buffer);
2599 FFF.Buffer = NULL;
2600 }
2601 }
2602
2603 return N6510_DecodeFilesystemSMS(s, sms, &FFF, location);
2604 }
2605 #endif
2606
2607 /* How should editor hadle tabs in this file? Add editor commands here.
2608 * vim: noexpandtab sw=8 ts=8 sts=8:
2609 */
2610