4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
28 #include <ITapiNetText.h>
30 #include <map_bmessage.h>
31 #include <bluetooth_map_agent.h>
34 #define BT_SMS_DATA_MAX_LEN 165
36 #define BMSG_TAG "BEGIN:BMSG\r\n"
37 #define VER_TAG "VERSION:"
38 #define STATUS_TAG "STATUS:"
39 #define TYPE_TAG "TYPE:"
40 #define FOLDER_TAG "FOLDER:"
41 #define VCARD_BEGIN_TAG "BEGIN:VCARD\r\n"
42 #define VCARD_END_TAG "END:VCARD\r\n"
43 #define VCARD_N_TAG "N:"
44 #define VCARD_FN_TAG "FN:"
45 #define VCARD_TEL_TAG "TEL:"
46 #define VCARD_EMAIL_TAG "EMAIL:"
47 #define BENV_TAG "BEGIN:BENV\r\n"
48 #define BBODY_TAG "BEGIN:BBODY\r\n"
49 #define MSG_TAG "BEGIN:MSG\r\n"
50 #define PARTID_TAG "PARTID:"
51 #define ENCODING_TAG "ENCODING:"
52 #define CHARSET_TAG "CHARSET:"
53 #define LANGUAGE_TAG "LANGUAGE:"
54 #define LENGTH_TAG "LENGTH:"
56 static guint8 g_enc_lvl = 1;
58 void print_bmsg(struct bmsg_data *bmsg)
64 struct benv_data *env_data = NULL;
66 DBG("bmsg->version = %s", bmsg->version);
67 DBG("bmsg->status = %s", bmsg->status);
68 DBG("bmsg->type = %s", bmsg->type);
69 DBG_SECURE("bmsg->folder = %s", bmsg->folder);
71 if (bmsg->originator_vcard_data) {
72 DBG_SECURE("bmsg->originator_vcard_data->version = %s",
73 bmsg->originator_vcard_data->version);
74 DBG_SECURE("bmsg->originator_vcard_data->n = %s",
75 bmsg->originator_vcard_data->n);
79 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
80 while (env_data != NULL) {
82 DBG("env_data = %d", env_data->encapsulation_level);
84 struct bmsg_vcard *rvcard;
86 rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
88 while (rvcard != NULL) {
91 if (rvcard->version != NULL)
92 DBG("vcard->version = %s\n", rvcard->version);
93 if (rvcard->n != NULL)
94 DBG_SECURE("vcard->n = %s\n", rvcard->n);
95 if (rvcard->fn != NULL)
96 DBG_SECURE("vcard->fn = %s\n", rvcard->fn);
97 if (rvcard->tel != NULL)
98 DBG_SECURE("vcard->tel = %s\n", rvcard->tel);
99 if (rvcard->email != NULL)
100 DBG_SECURE("vcard->email = %s\n", rvcard->email);
102 rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
105 if (env_data->body_content != NULL) {
106 DBG_SECURE("env_data->body_content->length = %"
107 G_GUINT64_FORMAT "\n",
108 env_data->body_content->length);
109 DBG_SECURE("env_data->body_content->msg = %s\n",
110 env_data->body_content->msg);
118 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
123 static gchar *__bt_unpack_gsm7bit_msg(const char* pdu, int in_len)
129 gchar data[BT_SMS_DATA_MAX_LEN + 1] = {0,};
131 for (i = 0; i < in_len; i++) {
133 data[i] = pdu[pos] & 0x7F;
138 data[i] = (pdu[pos - 1] >> shift) |
139 (pdu[pos] << (8 - shift));
148 DBG_SECURE("msg = %s\n", data);
150 return g_strdup(data);
153 static gchar *__bt_get_msg_body_from_pdu(gchar *pdu, guint64 pdu_len)
162 int phone_num_len = 0;
164 char msg_data[BT_SMS_DATA_MAX_LEN + 1] = {0,};
165 unsigned char pdu_data[TAPI_NETTEXT_MSG_SIZE_MAX] = {0,};
167 for (i = 0; i < (pdu_len - 1);) {
168 snprintf(temp, sizeof(temp), "%c%c", pdu[i], pdu[i+1]);
170 pdu_data[j] = g_ascii_strtoull(temp, NULL, 16);
171 DBG("pdu_data = %02x\n", pdu_data[j]);
176 DBG("pdu[%d] = %x\n", index, pdu_data[index]);
177 if (pdu[index] == 0x00)
180 index = index + pdu_data[index];
185 if (pdu_data[index] & 0x40)
188 DBG("udh = %d", udh);
193 /* phone number length */
195 DBG("pdu[%d] = %x\n", index, pdu_data[index]);
197 if ((pdu_data[index] % 2) == 0)
198 phone_num_len = pdu_data[index] / 2;
200 phone_num_len = pdu_data[index] / 2 + 1;
202 DBG("phone_num_len [%d]\n", phone_num_len);
204 /* phone number type */
207 /* phone_num_len/2 encoded phone num length */
208 index = index + phone_num_len;
216 dcs = pdu_data[index];
217 coding_scheme = (dcs & 0x0C) >> 2;
218 DBG("coding_scheme = %d\n", coding_scheme);
225 int udl = pdu_data[index];
226 DBG("udl = %x\n", udl);
231 memcpy(msg_data, (void*)&pdu_data[index], udl);
234 return __bt_unpack_gsm7bit_msg(msg_data, udl);
237 static gchar *__bt_get_valid_number(gchar* num)
250 valid_num = g_malloc0(len + 1);
251 retv_if(valid_num == NULL, NULL);
253 for (i = 0, j = 0; i < len; i++) {
256 valid_num[j] = num[i];
267 char *bmsg_get_msg_folder(struct bmsg_data *bmsg)
270 return g_strdup(bmsg->folder);
273 char *bmsg_get_msg_body(struct bmsg_data *bmsg, gboolean utf)
276 struct benv_data *env_data;
279 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
281 while (env_data != NULL) {
282 if (env_data->body_content != NULL) {
283 DBG_SECURE("env_data->body_content->msg = %s\n",
284 env_data->body_content->msg);
285 DBG_SECURE("env_data->body_content->length = %"
286 G_GUINT64_FORMAT "\n",
287 env_data->body_content->length);
290 return __bt_get_msg_body_from_pdu(
291 env_data->body_content->msg,
292 env_data->body_content->length);
295 env_data->body_content->msg,
296 env_data->body_content->length);
304 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
311 char *get_line(char *string, int *len)
314 while (string[i] != '\n' && string[i] != '\0')
318 return g_strndup(string, i - 1);
321 gboolean bmsg_parse_msg_body(const char *message,
322 char **body, char **subject)
325 DBG("Message: %s", message);
326 char *temp = (char *)message;
332 while ((line = get_line(temp, &len)) != NULL) {
333 if (!g_ascii_strncasecmp(line, "Date:", strlen("Date:"))) {
334 //Currently nothing to be done
335 } else if (!g_ascii_strncasecmp(line, "Subject:", strlen("Subject:"))) {
336 char *sub = line + strlen("Subject:");
339 DBG("Subject: %s", sub);
340 *subject = g_strdup(sub);
341 } else if (!g_ascii_strncasecmp(line, "From:", strlen("From:"))) {
342 //Currently nothing to be done
343 } else if (!g_ascii_strncasecmp(line, "To:", strlen("To:"))) {
344 //Currently nothing to be done
346 DBG("BODY: %s", temp);
347 *body = g_strdup(temp);
352 while ((temp[len] == '\r' || temp[len] == '\n') && temp[len] != '\0')
363 GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg, int msg_type)
366 struct benv_data *env_data;
367 GSList *receiver = NULL;
370 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
372 while (env_data != NULL) {
374 DBG("env_data = %d", env_data->encapsulation_level);
376 struct bmsg_vcard *rvcard;
378 rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
379 while (rvcard != NULL) {
382 if (msg_type == BT_MAP_ID_SMS) {
383 if (rvcard->tel != NULL) {
384 DBG_SECURE("vcard->tel = %s\n", rvcard->tel);
385 receiver = g_slist_append(receiver,
389 if (rvcard->email != NULL) {
390 DBG_SECURE("vcard->email = %s\n", rvcard->email);
391 receiver = g_slist_append(receiver,
395 rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
402 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
408 void bmsg_free_vcard_data(struct bmsg_vcard *vcard_data)
411 if (vcard_data == NULL)
414 g_free(vcard_data->version);
415 g_free(vcard_data->n);
416 g_free(vcard_data->fn);
417 g_free(vcard_data->tel);
418 g_free(vcard_data->email);
424 void bmsg_free_bmsg(struct bmsg_data *bmsg)
427 struct benv_data *env_data;
433 g_free(bmsg->version);
434 g_free(bmsg->status);
436 g_free(bmsg->folder);
437 bmsg_free_vcard_data(bmsg->originator_vcard_data);
439 if (bmsg->envelope_data == NULL)
442 if (bmsg->envelope_data->env_data == NULL)
445 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
446 while (env_data != NULL) {
448 DBG("env_data = %d", env_data->encapsulation_level);
450 struct bmsg_vcard *rvcard;
452 rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
454 while (rvcard != NULL) {
456 bmsg_free_vcard_data(rvcard);
457 rvcard = g_slist_nth_data(env_data->recipient_vcard, k);
460 if (env_data->body_content != NULL) {
461 g_free(env_data->body_content->encoding);
462 g_free(env_data->body_content->charset);
463 g_free(env_data->body_content->language);
464 g_free(env_data->body_content->msg);
465 g_free(env_data->body_content);
471 env_data = g_slist_nth_data(bmsg->envelope_data->env_data, i);
479 gchar *bmsg_get_parse_sub_block(char **sub_block_data, char *element)
486 gchar *sub_block = NULL;
490 start = g_strdup_printf("BEGIN:%s\r\n", element);
491 end = g_strdup_printf("END:%s\r\n", element);
492 offset = strlen(start);
494 block_start = g_strstr_len(*sub_block_data, offset, start);
495 if (block_start == NULL)
498 if (!g_strcmp0(start, VCARD_BEGIN_TAG))
499 block_end = g_strstr_len(*sub_block_data, -1, end);
501 block_end = g_strrstr(*sub_block_data, end);
503 if (block_end == NULL)
506 len = block_end - block_start - offset;
507 sub_block = g_strndup(block_start + offset, len);
508 *sub_block_data = *sub_block_data + strlen(sub_block) + strlen(start) +
517 gchar *bmsg_get_tag_data(char **block_data, char *element)
527 if (*block_data == NULL || element == NULL)
530 block_start = g_strstr_len(*block_data, -1, element);
531 if (block_start == NULL)
534 offset = strlen(element);
536 block_end = g_strstr_len(block_start+offset, -1, end);
537 if (block_end == NULL)
540 len = block_end - block_start - offset;
541 sub_block = g_strndup(block_start + offset, len);
542 *block_data = *block_data + offset + len + CRLF_LEN;
547 struct bmsg_bbody *bmsg_get_bbody_data(gchar *block_data)
550 struct bmsg_bbody *bbody;
552 gchar *bbody_block_data_start = block_data;
554 bbody = g_new0(struct bmsg_bbody, 1);
556 temp = bmsg_get_tag_data(&block_data, PARTID_TAG);
558 bbody->part_id = (guint16)g_ascii_strtoull(temp, NULL, 10);
562 bbody->encoding = bmsg_get_tag_data(&block_data, ENCODING_TAG);
563 bbody->charset = bmsg_get_tag_data(&block_data, CHARSET_TAG);
564 bbody->language = bmsg_get_tag_data(&block_data, LANGUAGE_TAG);
566 temp = bmsg_get_tag_data(&block_data, LENGTH_TAG);
569 bbody->length = g_ascii_strtoull(temp, NULL, 10);
573 bbody->msg = bmsg_get_parse_sub_block(&block_data, "MSG");
575 g_free(bbody_block_data_start);
580 struct bmsg_vcard *bmsg_get_vcard_data(gchar *sub_block_data)
583 struct bmsg_vcard *vcard;
585 gchar *vcard_block_data_start = sub_block_data;
587 vcard = g_new0(struct bmsg_vcard, 1);
589 vcard->version = bmsg_get_tag_data(&sub_block_data, VER_TAG);
590 vcard->n = bmsg_get_tag_data(&sub_block_data, VCARD_N_TAG);
591 vcard->fn = bmsg_get_tag_data(&sub_block_data, VCARD_FN_TAG);
592 num = bmsg_get_tag_data(&sub_block_data, VCARD_TEL_TAG);
593 vcard->tel = __bt_get_valid_number(num);
594 vcard->email = bmsg_get_tag_data(&sub_block_data, VCARD_EMAIL_TAG);
596 g_free(vcard_block_data_start);
602 struct benv_data *bmsg_get_env_encapsulation_data(gchar **sub_block_data)
606 gchar *bbody_data = NULL;
608 is_valid = g_strstr_len(*sub_block_data, strlen(VCARD_BEGIN_TAG),
610 if (is_valid == NULL)
616 struct benv_data *rec_data = g_new0(struct benv_data, 1);
618 rec_data->encapsulation_level = g_enc_lvl;
621 while (is_valid != NULL) {
622 gchar *vcard_data = NULL;
623 struct bmsg_vcard *vcard;
625 vcard_data = bmsg_get_parse_sub_block(sub_block_data, "VCARD");
626 if (vcard_data == NULL) {
627 ERR("parse error\n");
631 vcard = bmsg_get_vcard_data(vcard_data);
633 rec_data->recipient_vcard = g_slist_append(
634 rec_data->recipient_vcard,
637 is_valid = g_strstr_len(*sub_block_data,
638 strlen(VCARD_BEGIN_TAG),
642 is_valid = g_strstr_len(*sub_block_data, strlen(BBODY_TAG), BBODY_TAG);
647 bbody_data = bmsg_get_parse_sub_block(sub_block_data, "BBODY");
648 if (bbody_data == NULL) {
649 ERR("parse error\n");
653 rec_data->body_content = bmsg_get_bbody_data(bbody_data);
658 struct bmsg_envelope *bmsg_get_envelope_data(gchar **block_data)
661 gchar *sub_block_data;
662 struct bmsg_envelope *envelope_data;
663 struct benv_data *rec_data;
665 envelope_data = g_new0(struct bmsg_envelope, 1);
667 sub_block_data = bmsg_get_parse_sub_block(block_data, "BENV");
669 while (sub_block_data) {
670 char *next_sub_block_data;
671 char *save_sub_block_data = sub_block_data;
672 rec_data = bmsg_get_env_encapsulation_data(&sub_block_data);
675 envelope_data->env_data = g_slist_append(
676 envelope_data->env_data,
679 rec_data = bmsg_get_env_encapsulation_data(
682 next_sub_block_data = bmsg_get_parse_sub_block(&sub_block_data,
684 g_free(save_sub_block_data);
685 sub_block_data = next_sub_block_data;
687 g_free(sub_block_data);
689 return envelope_data;
692 struct bmsg_data *bmsg_parse(gchar *buf)
696 gchar *sub_block_data;
697 gchar *block_data_start;
698 struct bmsg_data *bmsg;
702 block_data = bmsg_get_parse_sub_block(&buf, "BMSG");
703 if (block_data == NULL)
706 block_data_start = block_data;
708 bmsg = g_new0(struct bmsg_data, 1);
710 bmsg->version = bmsg_get_tag_data(&block_data, VER_TAG);
711 if (bmsg->version == NULL)
714 bmsg->status = bmsg_get_tag_data(&block_data, STATUS_TAG);
715 if (bmsg->status == NULL)
718 bmsg->type = bmsg_get_tag_data(&block_data, TYPE_TAG);
719 if (bmsg->type == NULL)
722 bmsg->folder = bmsg_get_tag_data(&block_data, FOLDER_TAG);
723 if (bmsg->folder == NULL)
726 sub_block_data = bmsg_get_parse_sub_block(&block_data, "VCARD");
727 if (sub_block_data != NULL) {
728 bmsg->originator_vcard_data = bmsg_get_vcard_data(sub_block_data);
729 if (bmsg->originator_vcard_data == NULL)
733 bmsg->envelope_data = bmsg_get_envelope_data(&block_data);
734 if (bmsg->envelope_data == NULL)
737 g_free(block_data_start);
745 g_free(block_data_start);
748 bmsg_free_bmsg(bmsg);