Revert "Merge branch 'master' into tizen_2.1"
[platform/core/connectivity/bluetooth-agent.git] / map-agent / map_bmessage.c
1 /*
2  * bluetooth-agent
3  *
4  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <glib.h>
23
24 #include <map_bmessage.h>
25
26 #include <bluetooth_map_agent.h>
27
28 #define CRLF_LEN 2
29
30 #define BMSG_TAG "BEGIN:BMSG\r\n"
31 #define VER_TAG "VERSION:"
32 #define STATUS_TAG "STATUS:"
33 #define TYPE_TAG "TYPE:"
34 #define FOLDER_TAG "FOLDER:"
35 #define VCARD_BEGIN_TAG "BEGIN:VCARD\r\n"
36 #define VCARD_END_TAG "END:VCARD\r\n"
37 #define VCARD_N_TAG "N:"
38 #define VCARD_FN_TAG "FN:"
39 #define VCARD_TEL_TAG "TEL:"
40 #define VCARD_EMAIL_TAG "EMAIL:"
41 #define BENV_TAG "BEGIN:BENV\r\n"
42 #define BBODY_TAG "BEGIN:BBODY\r\n"
43 #define MSG_TAG "BEGIN:MSG\r\n"
44 #define PARTID_TAG "PARTID:"
45 #define ENCODING_TAG "ENCODING:"
46 #define CHARSET_TAG "CHARSET:"
47 #define LANGUAGE_TAG "LANGUAGE:"
48 #define LENGTH_TAG "LENGTH:"
49
50
51 void print_bmsg(struct bmsg_data *bmsg)
52 {
53         if (bmsg == NULL)
54                 return;
55
56         struct benv_data *env_data = NULL;
57
58         DBG("bmsg->version = %s", bmsg->version);
59         DBG("bmsg->status = %s", bmsg->status);
60         DBG("bmsg->type = %s", bmsg->type);
61         DBG("bmsg->folder = %s", bmsg->folder);
62         DBG("bmsg->originator_vcard_data->version = %s",
63                                         bmsg->originator_vcard_data->version);
64         DBG("bmsg->originator_vcard_data->n = %s",
65                                         bmsg->originator_vcard_data->n);
66
67         int i = 0;
68         env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
69         while (env_data != NULL) {
70
71                 DBG("env_data = %d", env_data->encapsulation_level);
72                 int k = 0;
73                 struct bmsg_vcard *rvcard;
74
75                 rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
76
77                 while (rvcard != NULL) {
78                         k++;
79
80                         if (rvcard->version != NULL)
81                                 DBG("vcard->version = %s\n", rvcard->version);
82                         if (rvcard->n != NULL)
83                                 DBG("vcard->n = %s\n", rvcard->n);
84                         if (rvcard->fn != NULL)
85                                 DBG("vcard->fn = %s\n", rvcard->fn);
86                         if (rvcard->tel != NULL)
87                                 DBG("vcard->tel = %s\n", rvcard->tel);
88                         if (rvcard->email != NULL)
89                                 DBG("vcard->email = %s\n", rvcard->email);
90
91                         rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
92                 }
93
94                 if (env_data->body_content != NULL) {
95                         DBG("env_data->body_content->length = %"
96                                                 G_GUINT64_FORMAT "\n",
97                                                 env_data->body_content->length);
98                         DBG("env_data->body_content->msg = %s\n",
99                                                 env_data->body_content->msg);
100                 }
101
102                 i++;
103
104                 if (i > 2)
105                         break;
106
107                 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
108         }
109 }
110
111 char *bmsg_get_msg_folder(struct bmsg_data *bmsg)
112 {
113         return g_strdup(bmsg->folder);
114 }
115
116 char *bmsg_get_msg_body(struct bmsg_data *bmsg)
117 {
118         struct benv_data *env_data;
119         int i = 0;
120
121         env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
122
123         while (env_data != NULL) {
124                 if (env_data->body_content != NULL) {
125                         DBG("env_data->body_content->msg = %s\n",
126                                                 env_data->body_content->msg);
127                         DBG("env_data->body_content->length = %"
128                                                 G_GUINT64_FORMAT "\n",
129                                                 env_data->body_content->length);
130                         return g_strndup(env_data->body_content->msg,
131                                                                 env_data->body_content->length);
132                 }
133
134                 i++;
135                 if (i > 2)
136                         break;
137
138                 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
139         }
140
141         return NULL;
142 }
143
144 GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg)
145 {
146         struct benv_data *env_data;
147         GSList *receiver = NULL;
148         int i = 0;
149
150         env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
151
152         while (env_data != NULL) {
153
154                 DBG("env_data = %d", env_data->encapsulation_level);
155                 int k = 0;
156                 struct bmsg_vcard *rvcard;
157
158                 rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
159                 while (rvcard != NULL) {
160                         k++;
161
162                         if (rvcard->tel != NULL) {
163                                 DBG("vcard->tel = %s\n", rvcard->tel);
164                                 receiver = g_slist_append(receiver, rvcard->tel);
165                         }
166
167                         rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
168                 }
169
170                 i++;
171                 if (i > 2)
172                         break;
173
174                 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
175         }
176
177         return receiver;
178 }
179
180 void bmsg_free_vcard_data(struct bmsg_vcard *vcard_data)
181 {
182         if (vcard_data == NULL)
183                 return;
184
185         g_free(vcard_data->version);
186         g_free(vcard_data->n);
187         g_free(vcard_data->fn);
188         g_free(vcard_data->tel);
189         g_free(vcard_data->email);
190         g_free(vcard_data);
191
192         return;
193 }
194
195 void bmsg_free_bmsg(struct bmsg_data *bmsg)
196 {
197         struct benv_data *env_data;
198         int i = 0;
199
200         if (bmsg == NULL)
201                 return;
202
203         g_free(bmsg->version);
204         g_free(bmsg->status);
205         g_free(bmsg->type);
206         g_free(bmsg->folder);
207         bmsg_free_vcard_data(bmsg->originator_vcard_data);
208
209         if (bmsg->envelope_data == NULL)
210                 goto done;
211
212         if (bmsg->envelope_data->env_data == NULL)
213                 goto done;
214
215         env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
216         while (env_data != NULL) {
217
218                 DBG("env_data = %d", env_data->encapsulation_level);
219                 int k = 0;
220                 struct bmsg_vcard *rvcard;
221
222                 rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
223
224                 while (rvcard != NULL) {
225                         k++;
226                         bmsg_free_vcard_data(rvcard);
227                         rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
228                 }
229
230                 if (env_data->body_content != NULL) {
231                         g_free(env_data->body_content->encoding);
232                         g_free(env_data->body_content->charset);
233                         g_free(env_data->body_content->language);
234                         g_free(env_data->body_content->msg);
235                         g_free(env_data->body_content);
236                 }
237
238                 g_free(env_data);
239                 i++;
240
241                 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
242         }
243
244 done:
245         g_free(bmsg);
246 }
247
248 gchar *bmsg_get_parse_sub_block(char **sub_block_data, char *element)
249 {
250         gchar *start;
251         gchar *end;
252         gchar *block_start;
253         gchar *block_end;
254         gchar *sub_block = NULL;
255         size_t offset;
256         size_t len;
257
258         DBG("");
259
260         start = g_strdup_printf("BEGIN:%s\r\n", element);
261         end = g_strdup_printf("END:%s\r\n", element);
262         offset = strlen(start);
263
264         block_start = g_strstr_len(*sub_block_data, offset, start);
265         if (block_start == NULL)
266                 goto done;
267
268         if (!g_strcmp0(start, VCARD_BEGIN_TAG))
269                 block_end = g_strstr_len(*sub_block_data, -1,  end);
270         else
271                 block_end = g_strrstr(*sub_block_data, end);
272
273         if (block_end == NULL)
274                 goto done;
275
276         len = block_end - block_start - offset;
277         sub_block = g_strndup(block_start + offset, len);
278         *sub_block_data = *sub_block_data + strlen(sub_block) + strlen(start) +
279                                                                  strlen(end);
280 done:
281         g_free(start);
282         g_free(end);
283         return sub_block;
284 }
285
286 gchar *bmsg_get_tag_data(char **block_data, char *element)
287 {
288         gchar *end = "\r\n";
289         gchar *block_start;
290         gchar *block_end;
291         gchar *sub_block;
292         size_t offset;
293         size_t len;
294
295         DBG("");
296
297         if (*block_data == NULL || element == NULL)
298                 return NULL;
299
300         block_start = g_strstr_len(*block_data, -1, element);
301         if (block_start == NULL)
302                 return NULL;
303
304         offset = strlen(element);
305
306         block_end = g_strstr_len(block_start+offset, -1, end);
307         if (block_end == NULL)
308                 return NULL;
309
310         len = block_end - block_start - offset;
311         sub_block = g_strndup(block_start + offset, len);
312         *block_data = *block_data + offset + len + CRLF_LEN;
313
314         return sub_block;
315 }
316
317 struct bmsg_bbody *bmsg_get_bbody_data(gchar *block_data)
318 {
319         gchar *bbody_block_data_start;
320         gchar *temp;
321         struct bmsg_bbody *bbody;
322         DBG("");
323
324         bbody_block_data_start = block_data;
325
326         bbody = g_new0(struct bmsg_bbody, 1);
327
328         temp = bmsg_get_tag_data(&block_data, PARTID_TAG);
329         if (temp != NULL) {
330                 bbody->part_id = (guint16)g_ascii_strtoull(temp, NULL, 10);
331                 g_free(temp);
332         }
333
334         bbody->encoding = bmsg_get_tag_data(&block_data, ENCODING_TAG);
335         bbody->charset = bmsg_get_tag_data(&block_data, CHARSET_TAG);
336         bbody->language = bmsg_get_tag_data(&block_data, LANGUAGE_TAG);
337
338         temp = bmsg_get_tag_data(&block_data, LENGTH_TAG);
339
340         if (temp != NULL) {
341                 bbody->length = g_ascii_strtoull(temp, NULL, 10);
342                 g_free(temp);
343         }
344
345         bbody->msg = bmsg_get_parse_sub_block(&block_data, "MSG");
346
347         g_free(bbody_block_data_start);
348
349         return bbody;
350 }
351
352 struct bmsg_vcard *bmsg_get_vcard_data(gchar *sub_block_data)
353 {
354         gchar *vcard_block_data_start;
355         struct bmsg_vcard *vcard;
356         DBG("");
357
358         vcard_block_data_start = sub_block_data;
359
360         vcard = g_new0(struct bmsg_vcard, 1);
361
362         vcard->version = bmsg_get_tag_data(&sub_block_data, VER_TAG);
363         vcard->n = bmsg_get_tag_data(&sub_block_data, VCARD_N_TAG);
364         vcard->fn = bmsg_get_tag_data(&sub_block_data, VCARD_FN_TAG);
365         vcard->tel = bmsg_get_tag_data(&sub_block_data, VCARD_TEL_TAG);
366         vcard->email = bmsg_get_tag_data(&sub_block_data, VCARD_EMAIL_TAG);
367
368         g_free(vcard_block_data_start);
369
370         return vcard;
371 }
372
373 struct benv_data *bmsg_get_env_encapsulation_data(gchar **sub_block_data)
374 {
375         gchar *is_valid;
376         gchar *bbody_data = NULL;
377         static guint8 lvl = 1;
378
379         is_valid = g_strstr_len(*sub_block_data, strlen(VCARD_BEGIN_TAG),
380                                                         VCARD_BEGIN_TAG);
381         if (is_valid == NULL)
382                 return NULL;
383
384         if (lvl > 3)
385                 return NULL;
386
387         struct benv_data *rec_data = g_new0(struct benv_data, 1);
388
389         rec_data->encapsulation_level = lvl;
390         lvl++;
391
392         while (is_valid != NULL) {
393                 gchar *vcard_data = NULL;
394                 struct bmsg_vcard *vcard;
395
396                 vcard_data = bmsg_get_parse_sub_block(sub_block_data, "VCARD");
397                 if (vcard_data == NULL) {
398                         DBG("parse error\n");
399                         g_free(rec_data);
400                         return NULL;
401                 }
402                 vcard = bmsg_get_vcard_data(vcard_data);
403
404                 rec_data->recipient_vcard = g_slist_append(
405                                                 rec_data->recipient_vcard,
406                                                 vcard);
407
408                 is_valid = g_strstr_len(*sub_block_data,
409                                                 strlen(VCARD_BEGIN_TAG),
410                                                 VCARD_BEGIN_TAG);
411         }
412
413         is_valid = g_strstr_len(*sub_block_data, strlen(BBODY_TAG), BBODY_TAG);
414
415         if (!is_valid)
416                 return rec_data;
417
418         bbody_data = bmsg_get_parse_sub_block(sub_block_data, "BBODY");
419         if (bbody_data == NULL) {
420                 DBG("parse error\n");
421                 return rec_data;
422         }
423
424         rec_data->body_content = bmsg_get_bbody_data(bbody_data);
425
426         return rec_data;
427 }
428
429 struct bmsg_envelope *bmsg_get_envelope_data(gchar **block_data)
430 {
431         gchar *env_block_data_start;
432         gchar *sub_block_data;
433         struct bmsg_envelope *envelope_data;
434         struct benv_data *rec_data;
435
436         env_block_data_start = *block_data;
437
438         envelope_data = g_new0(struct bmsg_envelope, 1);
439
440         sub_block_data = bmsg_get_parse_sub_block(block_data, "BENV");
441
442         while (sub_block_data) {
443
444                 rec_data = bmsg_get_env_encapsulation_data(&sub_block_data);
445
446                 while (rec_data) {
447                         envelope_data->env_data = g_slist_append(
448                                                         envelope_data->env_data,
449                                                         rec_data);
450
451                         rec_data = bmsg_get_env_encapsulation_data(
452                                                         &sub_block_data);
453                 }
454                 sub_block_data = bmsg_get_parse_sub_block(&sub_block_data,
455                                                                         "BENV");
456         }
457         g_free(sub_block_data);
458
459         return envelope_data;
460 }
461
462 struct bmsg_data * bmsg_parse(gchar *buf)
463 {
464         gchar *block_data;
465         gchar *sub_block_data;
466         gchar *block_data_start;
467         struct bmsg_data *bmsg;
468
469         DBG("");
470
471         block_data = bmsg_get_parse_sub_block(&buf, "BMSG");
472         if (block_data == NULL)
473                 return NULL;
474
475         block_data_start = block_data;
476
477         bmsg = g_new0(struct bmsg_data, 1);
478
479         bmsg->version = bmsg_get_tag_data(&block_data, VER_TAG);
480         if (bmsg->version == NULL)
481                 goto parse_fail;
482
483         bmsg->status = bmsg_get_tag_data(&block_data, STATUS_TAG);
484         if (bmsg->status == NULL)
485                 goto parse_fail;
486
487         bmsg->type = bmsg_get_tag_data(&block_data, TYPE_TAG);
488         if (bmsg->type == NULL)
489                 goto parse_fail;
490
491         bmsg->folder = bmsg_get_tag_data(&block_data, FOLDER_TAG);
492         if (bmsg->folder == NULL)
493                 goto parse_fail;
494
495         sub_block_data = bmsg_get_parse_sub_block(&block_data, "VCARD");
496         if (sub_block_data == NULL)
497                 goto parse_fail;
498
499         bmsg->originator_vcard_data = bmsg_get_vcard_data(sub_block_data);
500         if (bmsg->originator_vcard_data == NULL)
501                 goto parse_fail;
502
503         bmsg->envelope_data = bmsg_get_envelope_data(&block_data);
504         if (bmsg->envelope_data == NULL)
505                 goto parse_fail;
506
507         g_free(block_data_start);
508
509         DBG("Parse done");
510         print_bmsg(bmsg);
511
512         return bmsg;
513
514 parse_fail:
515         DBG("Parse fail");
516         bmsg_free_bmsg(bmsg);
517
518         return NULL;
519 }
520