summaryrefslogtreecommitdiffabout
path: root/gammu/emb/common/service/backup/backlmb.c
Unidiff
Diffstat (limited to 'gammu/emb/common/service/backup/backlmb.c') (more/less context) (ignore whitespace changes)
-rw-r--r--gammu/emb/common/service/backup/backlmb.c413
1 files changed, 413 insertions, 0 deletions
diff --git a/gammu/emb/common/service/backup/backlmb.c b/gammu/emb/common/service/backup/backlmb.c
new file mode 100644
index 0000000..d7f845a
--- a/dev/null
+++ b/gammu/emb/common/service/backup/backlmb.c
@@ -0,0 +1,413 @@
1/* (c) 2001-2004 by Marcin Wiacek */
2
3#include <string.h>
4#include <ctype.h>
5
6#include "../../phone/nokia/nfunc.h"
7#include "../../phone/nokia/dct3/n7110.h"
8#include "../../misc/coding/coding.h"
9#include "../gsmlogo.h"
10#include "../gsmmisc.h"
11#include "backlmb.h"
12
13#ifdef GSM_ENABLE_BACKUP
14
15static void SaveLMBStartupEntry(FILE *file, GSM_Bitmap bitmap)
16{
17 int count=13;
18 GSM_Phone_Bitmap_Types Type;
19 /* Welcome note and logo header block */
20 char req[1000] = {
21 'W','E','L',' ', /*block identifier*/
22 00,00, /*block data size*/
23 0x02,00,00,00,00,00,
24 0x00}; /*number of blocks (like in 6110 frame)*/
25
26 if (bitmap.Type == GSM_StartupLogo) {
27 req[count++] = 0x01;
28 req[count++] = bitmap.BitmapHeight;
29 req[count++] = bitmap.BitmapWidth;
30 Type = GSM_NokiaStartupLogo;
31 switch (bitmap.BitmapHeight) {
32 case 65: Type = GSM_Nokia7110StartupLogo; break;
33 case 60: Type = GSM_Nokia6210StartupLogo; break;
34 }
35 PHONE_EncodeBitmap(Type, req+count, &bitmap);
36 count = count + PHONE_GetBitmapSize(Type, 0, 0);
37
38 req[12]++;
39 }
40 if (bitmap.Type == GSM_WelcomeNote_Text) {
41 req[count++]=0x02;
42 req[count++]=UnicodeLength(bitmap.Text);
43 memcpy(req+count,DecodeUnicodeString(bitmap.Text),UnicodeLength(bitmap.Text));
44 count=count+UnicodeLength(bitmap.Text);
45
46 req[12]++;
47 }
48
49 req[4]=(count-12)%256;
50 req[5]=(count-12)/256;
51
52 fwrite(req, 1, count, file);
53 }
54
55static void SaveLMBCallerEntry(FILE *file, GSM_Bitmap bitmap)
56{
57 int count=12, textlen;
58 char req[500] = {
59 'C','G','R',' ', /*block identifier*/
60 00,00, /*block data size*/
61 02,00,
62 00, /*group number=0,1,etc.*/
63 00,00,00};
64
65 req[count++] = bitmap.Location - 1;
66 if (bitmap.DefaultName) {
67 req[count++] = 0;
68 } else {
69 textlen = UnicodeLength(bitmap.Text);
70 req[count++] = textlen;
71 memcpy(req+count,DecodeUnicodeString(bitmap.Text),textlen);
72 count += textlen;
73 }
74 if (bitmap.DefaultRingtone) {
75 req[count++] = 0x16;
76 } else {
77 req[count++] = bitmap.RingtoneID;
78 }
79 if (bitmap.BitmapEnabled) req[count++] = 0x01; else req[count++] = 0x00;
80 req[count++] = (PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 4) >> 8;
81 req[count++] = (PHONE_GetBitmapSize(GSM_NokiaCallerLogo,0,0) + 4) % 0xff;
82 if (bitmap.DefaultBitmap) {
83 bitmap.BitmapWidth = 72;
84 bitmap.BitmapHeight = 14;
85 GSM_ClearBitmap(&bitmap);
86 }
87 NOKIA_CopyBitmap(GSM_NokiaCallerLogo, &bitmap, req, &count);
88 req[count++]=0;
89
90 req[4]=(count-12)%256;
91 req[5]=(count-12)/256;
92 req[8]=bitmap.Location;
93
94 fwrite(req, 1, count, file);
95 }
96
97void SaveLMBPBKEntry(FILE *file, GSM_MemoryEntry *entry)
98{
99 int count = 16, blocks;
100 char req[500] = {
101 'P','B','E','2', /*block identifier*/
102 00,00, /*block data size*/
103 00,00,
104 00,00, /*position of phonebook entry*/
105 03, /*memory type. ME=02;SM=03*/
106 00,
107 00,00, /*position of phonebook entry*/
108 03, /*memory type. ME=02;SM=03*/
109 00};
110
111 count=count+N71_65_EncodePhonebookFrame(NULL, req+16, *entry, &blocks, true, true);
112
113 req[4]=(count-12)%256;
114 req[5]=(count-12)/256;
115 req[8]=req[12] = entry->Location & 0xff;
116 req[9]=req[13] = (entry->Location >> 8);
117 if (entry->MemoryType==MEM_ME) req[10]=req[14]=2;
118
119 fwrite(req, 1, count, file);
120}
121
122GSM_Error SaveLMB(char *FileName, GSM_Backup *backup)
123{
124 FILE *file;
125 int i;
126 char LMBHeader[] = {'L','M','B',' '}; /*file identifier*/
127 char PBKHeader[] = { /*Phonebook header block */
128 'P','B','K',' ', /*block identifier*/
129 0x08,00, /*block data size*/
130 0x02,00,
131 03, /*memory type. ME=02;SM=03*/
132 00,00,00,
133 00,00, /*size of phonebook*/
134 14, /*max length of each position*/
135 00,00,00,00,00};
136
137
138 file = fopen(FileName, "wb");
139 if (file == NULL) return ERR_CANTOPENFILE;
140
141 /* Write the header of the file. */
142 fwrite(LMBHeader, 1, sizeof(LMBHeader), file);
143
144 if (backup->PhonePhonebook[0]!=NULL) {
145 PBKHeader[8] = 2; /* memory type=MEM_ME */
146 PBKHeader[12] = (unsigned char)(500 % 256);
147 PBKHeader[13] = 500 / 256;
148 fwrite(PBKHeader, 1, sizeof(PBKHeader), file);
149 i=0;
150 while (backup->PhonePhonebook[i]!=NULL) {
151 SaveLMBPBKEntry(file, backup->PhonePhonebook[i]);
152 i++;
153 }
154 }
155 if (backup->SIMPhonebook[0]!=NULL) {
156 PBKHeader[8] = 3; /* memory type=MEM_SM */
157 PBKHeader[12] = (unsigned char)(250 % 256);
158 PBKHeader[13] = 250 / 256;
159 PBKHeader[14] = 0x16; /* max size of one entry */
160 fwrite(PBKHeader, 1, sizeof(PBKHeader), file);
161 i=0;
162 while (backup->SIMPhonebook[i]!=NULL) {
163 SaveLMBPBKEntry(file, backup->SIMPhonebook[i]);
164 i++;
165 }
166 }
167 i=0;
168 while (backup->CallerLogos[i]!=NULL) {
169 SaveLMBCallerEntry(file, *backup->CallerLogos[i]);
170 i++;
171 }
172 if (backup->StartupLogo!=NULL) {
173 SaveLMBStartupEntry(file, *backup->StartupLogo);
174 }
175
176 fclose(file);
177 return ERR_NONE;
178}
179
180static GSM_Error LoadLMBCallerEntry(unsigned char *buffer, unsigned char *buffer2, GSM_Backup *backup)
181{
182 GSM_Bitmap bitmap;
183 int num;
184
185#ifdef DEBUG
186 dbgprintf("Number %i, name \"", buffer2[0]+1);
187 for (num=0;num<buffer2[1];num++) dbgprintf("%c", buffer2[num+2]);
188 dbgprintf("\"\n");
189 dbgprintf("Ringtone ID=%i\n", buffer2[num+2]);
190 if (buffer2[num+3]==1) {
191 dbgprintf("Logo enabled\n");
192 } else {
193 dbgprintf("Logo disabled\n");
194 }
195#endif
196
197 bitmap.Location = buffer2[0] + 1;
198 bitmap.Type = GSM_CallerGroupLogo;
199 bitmap.DefaultRingtone = false;
200 bitmap.RingtoneID = buffer2[buffer2[1]+2];
201
202 EncodeUnicode(bitmap.Text,buffer2+2,buffer2[1]);
203 if (bitmap.Text[0] == 0x00 && bitmap.Text[1] == 0x00) {
204 bitmap.DefaultName = true;
205 } else {
206 bitmap.DefaultName = false;
207 }
208
209 bitmap.BitmapEnabled = false;
210 if (buffer2[buffer2[1]+3]==1) bitmap.BitmapEnabled=true;
211
212 bitmap.DefaultBitmap = false;
213 PHONE_DecodeBitmap(GSM_NokiaCallerLogo, buffer2+(buffer2[1]+10), &bitmap);
214
215#ifdef DEBUG
216 dbgprintf("Caller logo\n");
217 if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,&bitmap);
218#endif
219
220 num = 0;
221 while (backup->CallerLogos[num] != NULL) num++;
222 if (num < GSM_BACKUP_MAX_CALLER) {
223 backup->CallerLogos[num] = malloc(sizeof(GSM_Bitmap));
224 if (backup->CallerLogos[num] == NULL) return ERR_MOREMEMORY;
225 backup->CallerLogos[num + 1] = NULL;
226 } else {
227 dbgprintf("Increase GSM_BACKUP_MAX_CALLER\n");
228 return ERR_MOREMEMORY;
229 }
230 *backup->CallerLogos[num] = bitmap;
231
232 return ERR_NONE;
233 }
234
235static GSM_Error LoadLMBStartupEntry(unsigned char *buffer, unsigned char *buffer2, GSM_Backup *backup)
236{
237 int i,j;
238#ifdef DEBUG
239 int z;
240#endif
241 GSM_Phone_Bitmap_Types Type;
242
243 j=1;
244 for (i=0;i<buffer2[0];i++) {
245 switch (buffer2[j++]) {
246 case 1:
247 dbgprintf("Block 1 - startup logo\n");
248 backup->StartupLogo = malloc(sizeof(GSM_Bitmap));
249 if (backup->StartupLogo == NULL) return ERR_MOREMEMORY;
250 backup->StartupLogo->Location= 1;
251 backup->StartupLogo->BitmapHeight= buffer2[j++];
252 backup->StartupLogo->BitmapWidth= buffer2[j++];
253 Type = GSM_NokiaStartupLogo;
254 switch (backup->StartupLogo->BitmapHeight) {
255 case 65: Type = GSM_Nokia7110StartupLogo; break;
256 case 60: Type = GSM_Nokia6210StartupLogo; break;
257 }
258 PHONE_DecodeBitmap(Type, buffer2+j, backup->StartupLogo);
259#ifdef DEBUG
260 if (di.dl == DL_TEXTALL || di.dl == DL_TEXTALLDATE) GSM_PrintBitmap(di.df,backup->StartupLogo);
261#endif
262 j = j + PHONE_GetBitmapSize(Type,0,0);
263 break;
264 case 2:
265#ifdef DEBUG
266 dbgprintf("Block 2 - welcome note \"");
267 for (z=0;z<buffer2[j];z++) dbgprintf("%c",buffer2[j+z+1]);
268 dbgprintf("\"\n");
269#endif
270 if (backup->StartupLogo == NULL) {
271 backup->StartupLogo = malloc(sizeof(GSM_Bitmap));
272 if (backup->StartupLogo == NULL) return ERR_MOREMEMORY;
273 backup->StartupLogo->Type = GSM_WelcomeNote_Text;
274 EncodeUnicode(backup->StartupLogo->Text,buffer2+j,buffer2[j]);
275 }
276 j = j + buffer2[j];
277 break;
278 default:
279 dbgprintf("Unknown block %02x\n",buffer2[j]);
280 break;
281 }
282 }
283 return ERR_NONE;
284}
285
286static GSM_Error LoadLMBPbkEntry(unsigned char *buffer, unsigned char *buffer2, GSM_Backup *backup)
287{
288 GSM_MemoryEntry pbk;
289 int num;
290
291#ifdef DEBUG
292 dbgprintf("Memory : ");
293 switch(buffer[10]) {
294 case 2 : dbgprintf("(internal)\n"); break;
295 case 3 : dbgprintf("(sim)\n"); break;
296 default: dbgprintf("(unknown)\n"); break;
297 }
298 dbgprintf("Location : %i\n",buffer2[0]+buffer2[1]*256);
299#endif
300
301 N71_65_DecodePhonebook(NULL, &pbk, NULL,NULL,buffer2+4,(buffer[4]+buffer[5]*256)-4,false);
302
303 pbk.MemoryType=MEM_SM;
304 if (buffer[10]==2) pbk.MemoryType=MEM_ME;
305
306 pbk.Location=buffer2[0]+256*buffer2[1];
307
308 num = 0;
309 if (buffer[10]==2) {
310 while (backup->PhonePhonebook[num] != NULL) num++;
311 if (num < GSM_BACKUP_MAX_PHONEPHONEBOOK) {
312 backup->PhonePhonebook[num] = malloc(sizeof(GSM_MemoryEntry));
313 if (backup->PhonePhonebook[num] == NULL) return ERR_MOREMEMORY;
314 backup->PhonePhonebook[num + 1] = NULL;
315 } else {
316 dbgprintf("Increase GSM_BACKUP_MAX_PHONEPHONEBOOK\n");
317 return ERR_MOREMEMORY;
318 }
319 *backup->PhonePhonebook[num] = pbk;
320 } else {
321 while (backup->SIMPhonebook[num] != NULL) num++;
322 if (num < GSM_BACKUP_MAX_SIMPHONEBOOK) {
323 backup->SIMPhonebook[num] = malloc(sizeof(GSM_MemoryEntry));
324 if (backup->SIMPhonebook[num] == NULL) return ERR_MOREMEMORY;
325 backup->SIMPhonebook[num + 1] = NULL;
326 } else {
327 dbgprintf("Increase GSM_BACKUP_MAX_SIMPHONEBOOK\n");
328 return ERR_MOREMEMORY;
329 }
330 *backup->SIMPhonebook[num] = pbk;
331 }
332 return ERR_NONE;
333}
334
335GSM_Error LoadLMB(char *FileName, GSM_Backup *backup)
336{
337#ifdef DEBUG
338 int i;
339#endif
340 unsigned char buffer[12], buffer2[1000];
341 FILE *file;
342 GSM_Errorerror;
343
344 file = fopen(FileName, "rb");
345 if (file == NULL) return(ERR_CANTOPENFILE);
346
347 /* Read the header of the file. */
348 fread(buffer, 1, 4, file);
349
350 /* while we have something to read */
351 while (fread(buffer, 1, 12, file)==12) {
352#ifdef DEBUG
353 /* Info about block in the file */
354 dbgprintf("Block \"");
355 for (i=0;i<4;i++) {dbgprintf("%c",buffer[i]);}
356 dbgprintf("\" (");
357 if (memcmp(buffer, "PBK ",4)==0) { dbgprintf("Phonebook");
358 } else if (memcmp(buffer, "PBE2",4)==0) { dbgprintf("Phonebook entry");
359 } else if (memcmp(buffer, "CGR ",4)==0) { dbgprintf("Caller group");
360 } else if (memcmp(buffer, "SPD ",4)==0) { dbgprintf("Speed dial");
361 } else if (memcmp(buffer, "OLG ",4)==0) { dbgprintf("Operator logo");
362 } else if (memcmp(buffer, "WEL ",4)==0) { dbgprintf("Startup logo and welcome text");
363 } else { dbgprintf("unknown - ignored");
364 }
365 dbgprintf(") - length %i\n", buffer[4]+buffer[5]*256);
366#endif
367 /* reading block data */
368 fread(buffer2, 1, buffer[4]+buffer[5]*256, file);
369
370#ifdef DEBUG
371 if (memcmp(buffer, "PBK ",4)==0) {
372 dbgprintf("Size of phonebook %i, type %i ",(buffer2[0]+buffer2[1]*256),buffer[8]);
373 switch(buffer[8]) {
374 case 2 : dbgprintf("(internal)");break;
375 case 3 : dbgprintf("(sim)") ;break;
376 default: dbgprintf("(unknown)") ;break;
377 }
378 dbgprintf(", length of each position - %i\n",buffer2[2]);
379 }
380#endif
381 if (memcmp(buffer, "PBE2",4)==0) {
382 error = LoadLMBPbkEntry(buffer,buffer2,backup);
383 if (error != ERR_NONE) {
384 fclose(file);
385 return error;
386 }
387 }
388 if (memcmp(buffer, "CGR ",4)==0) {
389 error = LoadLMBCallerEntry(buffer, buffer2, backup);
390 if (error != ERR_NONE) {
391 fclose(file);
392 return error;
393 }
394 }
395 if (memcmp(buffer, "WEL ",4)==0) {
396 error = LoadLMBStartupEntry(buffer, buffer2, backup);
397 if (error != ERR_NONE) {
398 fclose(file);
399 return error;
400 }
401 }
402 }
403
404 fclose(file);
405
406 return ERR_NONE;
407}
408
409#endif
410
411/* How should editor hadle tabs in this file? Add editor commands here.
412 * vim: noexpandtab sw=8 ts=8 sts=8:
413 */