4 #include "../misc/coding/coding.h"
8 unsigned char *GSM_PhonebookGetEntryName (GSM_MemoryEntry
*entry
)
10 /* We possibly store here "LastName, FirstName" so allocate enough memory */
11 static char dest
[(GSM_PHONEBOOK_TEXT_LENGTH
*2+2+1)*2];
12 static char split
[] = { '\0', ',', '\0', ' ', '\0', '\0'};
14 int first
= -1, last
= -1, name
= -1;
17 for (i
= 0; i
< entry
->EntriesNum
; i
++) {
18 switch (entry
->Entries
[i
].EntryType
) {
19 case PBK_Text_LastName
:
22 case PBK_Text_FirstName
:
34 CopyUnicodeString(dest
, entry
->Entries
[name
].Text
);
36 if (last
!= -1 && first
!= -1) {
37 len
= UnicodeLength(entry
->Entries
[last
].Text
);
38 CopyUnicodeString(dest
, entry
->Entries
[last
].Text
);
39 CopyUnicodeString(dest
+ 2*len
, split
);
40 CopyUnicodeString(dest
+ 2*len
+ 4, entry
->Entries
[first
].Text
);
41 } else if (last
!= -1) {
42 CopyUnicodeString(dest
, entry
->Entries
[last
].Text
);
43 } else if (first
!= -1) {
44 CopyUnicodeString(dest
, entry
->Entries
[first
].Text
);
53 void GSM_PhonebookFindDefaultNameNumberGroup(GSM_MemoryEntry
*entry
, int *Name
, int *Number
, int *Group
)
60 for (i
= 0; i
< entry
->EntriesNum
; i
++) {
61 switch (entry
->Entries
[i
].EntryType
) {
62 case PBK_Number_General
: if (*Number
== -1) *Number
= i
; break;
63 case PBK_Text_Name
: if (*Name
== -1) *Name
= i
; break;
64 case PBK_Caller_Group
: if (*Group
== -1) *Group
= i
; break;
68 if ((*Number
) == -1) {
69 for (i
= 0; i
< entry
->EntriesNum
; i
++) {
70 switch (entry
->Entries
[i
].EntryType
) {
71 case PBK_Number_Mobile
:
75 case PBK_Number_Pager
:
76 case PBK_Number_Other
:
77 if (*Number
== -1) *Number
= i
;
85 for (i
= 0; i
< entry
->EntriesNum
; i
++) {
86 switch (entry
->Entries
[i
].EntryType
) {
87 case PBK_Text_LastName
:
88 if (*Name
== -1) *Name
= i
;
96 for (i
= 0; i
< entry
->EntriesNum
; i
++) {
97 switch (entry
->Entries
[i
].EntryType
) {
98 case PBK_Text_FirstName
:
99 if (*Name
== -1) *Name
= i
;
108 void GSM_EncodeVCARD(char *Buffer
, int *Length
, GSM_MemoryEntry
*pbk
, bool header
, GSM_VCardVersion Version
)
110 int Name
, Number
, Group
, i
;
113 GSM_PhonebookFindDefaultNameNumberGroup(pbk
, &Name
, &Number
, &Group
);
115 if (Version
== Nokia_VCard10
) {
116 if (header
) *Length
+=sprintf(Buffer
+(*Length
),"BEGIN:VCARD%c%c",13,10);
118 *Length
+=sprintf(Buffer
+(*Length
),"N:%s%c%c",DecodeUnicodeString(pbk
->Entries
[Name
].Text
),13,10);
121 *Length
+=sprintf(Buffer
+(*Length
),"TEL:%s%c%c",DecodeUnicodeString(pbk
->Entries
[Number
].Text
),13,10);
123 if (header
) *Length
+=sprintf(Buffer
+(*Length
),"END:VCARD%c%c",13,10);
124 } else if (Version
== Nokia_VCard21
) {
125 if (header
) *Length
+=sprintf(Buffer
+(*Length
),"BEGIN:VCARD%c%cVERSION:2.1%c%c",13,10,13,10);
127 SaveVCALText(Buffer
, Length
, pbk
->Entries
[Name
].Text
, "N");
129 for (i
=0; i
< pbk
->EntriesNum
; i
++) {
132 switch(pbk
->Entries
[i
].EntryType
) {
135 case PBK_Caller_Group
:
138 case PBK_Number_General
:
139 *Length
+=sprintf(Buffer
+(*Length
),"TEL");
140 if (Number
== i
) (*Length
)+=sprintf(Buffer
+(*Length
),";PREF");
142 case PBK_Number_Mobile
:
143 *Length
+=sprintf(Buffer
+(*Length
),"TEL");
144 if (Number
== i
) (*Length
)+=sprintf(Buffer
+(*Length
),";PREF");
145 *Length
+=sprintf(Buffer
+(*Length
),";CELL");
147 case PBK_Number_Work
:
148 *Length
+=sprintf(Buffer
+(*Length
),"TEL");
149 if (Number
== i
) (*Length
)+=sprintf(Buffer
+(*Length
),";PREF");
150 *Length
+=sprintf(Buffer
+(*Length
),";WORK;VOICE");
152 case PBK_Number_Fax
:
153 *Length
+=sprintf(Buffer
+(*Length
),"TEL");
154 if (Number
== i
) (*Length
)+=sprintf(Buffer
+(*Length
),";PREF");
155 *Length
+=sprintf(Buffer
+(*Length
),";FAX");
157 case PBK_Number_Home
:
158 *Length
+=sprintf(Buffer
+(*Length
),"TEL");
159 if (Number
== i
) (*Length
)+=sprintf(Buffer
+(*Length
),";PREF");
160 *Length
+=sprintf(Buffer
+(*Length
),";HOME;VOICE");
163 *Length
+=sprintf(Buffer
+(*Length
),"NOTE");
165 case PBK_Text_Postal
:
166 /* Don't ask why. Nokia phones save postal address
167 * double - once like LABEL, second like ADR
169 SaveVCALText(Buffer
, Length
, pbk
->Entries
[i
].Text
, "LABEL");
170 *Length
+=sprintf(Buffer
+(*Length
),"ADR");
172 case PBK_Text_Email
:
173 case PBK_Text_Email2
:
174 *Length
+=sprintf(Buffer
+(*Length
),"EMAIL");
177 *Length
+=sprintf(Buffer
+(*Length
),"URL");
184 SaveVCALText(Buffer
, Length
, pbk
->Entries
[i
].Text
, "");
188 if (header
) *Length
+=sprintf(Buffer
+(*Length
),"END:VCARD%c%c",13,10);
192 GSM_Error
GSM_DecodeVCARD(unsigned char *Buffer
, int *Pos
, GSM_MemoryEntry
*Pbk
, GSM_VCardVersion Version
)
194 unsigned char Line
[2000],Buff
[2000];
201 MyGetLine(Buffer
, Pos
, Line
, strlen(Buffer
));
202 if (strlen(Line
) == 0) break;
205 if (strstr(Line
,"BEGIN:VCARD")) Level
= 1;
208 if (strstr(Line
,"END:VCARD")) {
209 if (Pbk
->EntriesNum
== 0) return GE_EMPTY
;
212 if (ReadVCALText(Line
, "N", Buff
)) {
213 CopyUnicodeString(Pbk
->Entries
[Pbk
->EntriesNum
].Text
,Buff
);
214 Pbk
->Entries
[Pbk
->EntriesNum
].EntryType
= PBK_Text_Name
;
217 if (ReadVCALText(Line
, "TEL", Buff
) ||
218 ReadVCALText(Line
, "TEL;VOICE", Buff
) ||
219 ReadVCALText(Line
, "TEL;PREF", Buff
) ||
220 ReadVCALText(Line
, "TEL;PREF;VOICE", Buff
)) {
221 CopyUnicodeString(Pbk
->Entries
[Pbk
->EntriesNum
].Text
,Buff
);
222 Pbk
->Entries
[Pbk
->EntriesNum
].EntryType
= PBK_Number_General
;
225 if (ReadVCALText(Line
, "TEL;CELL", Buff
) ||
226 ReadVCALText(Line
, "TEL;CELL;VOICE", Buff
) ||
227 ReadVCALText(Line
, "TEL;PREF;CELL", Buff
) ||
228 ReadVCALText(Line
, "TEL;PREF;CELL;VOICE", Buff
)) {
229 CopyUnicodeString(Pbk
->Entries
[Pbk
->EntriesNum
].Text
,Buff
);
230 Pbk
->Entries
[Pbk
->EntriesNum
].EntryType
= PBK_Number_Mobile
;
233 if (ReadVCALText(Line
, "TEL;WORK", Buff
) ||
234 ReadVCALText(Line
, "TEL;PREF;WORK", Buff
) ||
235 ReadVCALText(Line
, "TEL;WORK;VOICE", Buff
) ||
236 ReadVCALText(Line
, "TEL;PREF;WORK;VOICE", Buff
)) {
237 CopyUnicodeString(Pbk
->Entries
[Pbk
->EntriesNum
].Text
,Buff
);
238 Pbk
->Entries
[Pbk
->EntriesNum
].EntryType
= PBK_Number_Work
;
241 if (ReadVCALText(Line
, "TEL;FAX", Buff
) ||
242 ReadVCALText(Line
, "TEL;PREF;FAX", Buff
) ||
243 ReadVCALText(Line
, "TEL;FAX;VOICE", Buff
) ||
244 ReadVCALText(Line
, "TEL;PREF;FAX;VOICE", Buff
)) {
245 CopyUnicodeString(Pbk
->Entries
[Pbk
->EntriesNum
].Text
,Buff
);
246 Pbk
->Entries
[Pbk
->EntriesNum
].EntryType
= PBK_Number_Fax
;
249 if (ReadVCALText(Line
, "TEL;HOME", Buff
) ||
250 ReadVCALText(Line
, "TEL;PREF;HOME", Buff
) ||
251 ReadVCALText(Line
, "TEL;HOME;VOICE", Buff
) ||
252 ReadVCALText(Line
, "TEL;PREF;HOME;VOICE", Buff
)) {
253 CopyUnicodeString(Pbk
->Entries
[Pbk
->EntriesNum
].Text
,Buff
);
254 Pbk
->Entries
[Pbk
->EntriesNum
].EntryType
= PBK_Number_Home
;
257 if (ReadVCALText(Line
, "NOTE", Buff
)) {
258 CopyUnicodeString(Pbk
->Entries
[Pbk
->EntriesNum
].Text
,Buff
);
259 Pbk
->Entries
[Pbk
->EntriesNum
].EntryType
= PBK_Text_Note
;
262 if (ReadVCALText(Line
, "ADR", Buff
)) {
263 CopyUnicodeString(Pbk
->Entries
[Pbk
->EntriesNum
].Text
,Buff
);
264 Pbk
->Entries
[Pbk
->EntriesNum
].EntryType
= PBK_Text_Postal
;
267 if (ReadVCALText(Line
, "EMAIL", Buff
)) {
268 CopyUnicodeString(Pbk
->Entries
[Pbk
->EntriesNum
].Text
,Buff
);
269 Pbk
->Entries
[Pbk
->EntriesNum
].EntryType
= PBK_Text_Email
;
272 if (ReadVCALText(Line
, "URL", Buff
)) {
273 CopyUnicodeString(Pbk
->Entries
[Pbk
->EntriesNum
].Text
,Buff
);
274 Pbk
->Entries
[Pbk
->EntriesNum
].EntryType
= PBK_Text_URL
;
281 if (Pbk
->EntriesNum
== 0) return GE_EMPTY
;
285 /* -------------------------------- OLD ------------------------------------ */
287 static void ParseVCardLine(char **pos
, char *Name
, char *Parameters
, char *Value
)
291 Name
[0] = Parameters
[0] = Value
[0] = 0;
293 if (**pos
== 0) return;
295 for (i
=0; **pos
&& **pos
!= ':' && **pos
!= ';'; i
++, (*pos
)++) Name
[i
] = **pos
;
298 //dbgprintf("ParseVCardLine: name tag = '%s'\n", Name);
301 for (i
=0; **pos
&& **pos
!= ':'; i
++, (*pos
)++) Parameters
[i
] = **pos
;
304 //dbgprintf("ParseVCardLine: parameter tag = '%s'\n", Parameters);
307 if (**pos
!= 0) (*pos
)++;
311 if ((*pos
)[0] == '\x0d' && (*pos
)[1] == '\x0a') {
313 if (**pos
!= '\t' && **pos
!= ' ') break;
314 while (**pos
== '\t' || **pos
== ' ') (*pos
)++;
322 //dbgprintf("ParseVCardLine: value tag = '%s'\n", Value);
325 void DecodeVCARD21Text(char *VCard
, GSM_MemoryEntry
*pbk
)
328 char Name
[32], Parameters
[256], Value
[1024];
330 dbgprintf("Parsing VCard:\n%s\n", VCard
);
332 ParseVCardLine(&pos
, Name
, Parameters
, Value
);
333 if (!mystrncasecmp(Name
, "BEGIN", 0) || !mystrncasecmp(Value
, "VCARD", 0)) {
334 dbgprintf("No valid VCARD signature\n");
339 GSM_SubMemoryEntry
*pbe
= &pbk
->Entries
[pbk
->EntriesNum
];
341 ParseVCardLine(&pos
, Name
, Parameters
, Value
);
342 if (Name
[0] == 0x00 ||
343 (mystrncasecmp(Name
, "END", 0) && mystrncasecmp(Value
, "VCARD", 0)))
346 if (mystrncasecmp(Name
, "N", 0)) {
347 //FIXME: Name is tagged field which should be parsed
348 pbe
->EntryType
= PBK_Text_Name
;
349 EncodeUnicode(pbe
->Text
, Value
, strlen(Value
));
351 } else if (mystrncasecmp(Name
, "EMAIL", 0)) {
352 pbe
->EntryType
= PBK_Text_Email
;
353 EncodeUnicode(pbe
->Text
, Value
, strlen(Value
));
355 } else if (mystrncasecmp(Name
, "TEL", 0)) {
356 if (strstr(Parameters
, "WORK;"))
357 pbe
->EntryType
= PBK_Number_Work
;
358 else if (strstr(Name
, "HOME;"))
359 pbe
->EntryType
= PBK_Number_Home
;
360 else if (strstr(Name
, "FAX;"))
361 pbe
->EntryType
= PBK_Number_Fax
;
362 else pbe
->EntryType
= PBK_Number_General
;
364 EncodeUnicode(pbe
->Text
, Value
, strlen(Value
));
370 /* How should editor hadle tabs in this file? Add editor commands here.
371 * vim: noexpandtab sw=8 ts=8 sts=8: