Modify the map agent for gtest
[platform/core/connectivity/bluetooth-agent.git] / map-agent / bluetooth_map_sms.c
1 /*
2  * Bluetooth-agent
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Syam Sidhardhan <s.syam@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
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
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
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.
21  *
22  */
23
24 #include <bluetooth_map_agent.h>
25 #include <map_bmessage.h>
26
27 /*Messaging Header Files*/
28 #include "msg.h"
29 #include "msg_storage.h"
30 #include "msg_storage_types.h"
31 #include "msg_transport.h"
32 #include "msg_transport_types.h"
33 #include "msg_types.h"
34
35 #include <glib.h>
36
37 #define BT_MAP_STATUS_CB "sent status callback"
38 #define BT_MAP_MSG_CB "sms message callback"
39 #define BT_MAP_DELETED_FOLDER_NAME "DELETED"
40 #define BT_MAP_SENT_FOLDER_NAME "SENT"
41 #define BT_MAP_MSG_TEMPLATE "TEMPLATE"
42
43 #define BT_MAP_MSG_INFO_MAX 256
44 #define BT_MAP_MSG_HANDLE_MAX 21
45 #define BT_MAP_TIMESTAMP_MAX_LEN 16
46 #define BT_MAP_MSG_BODY_MAX 1024
47
48 #define BEGIN_BMSEG "BEGIN:BMSG\r\n"
49 #define END_BMSEG "END:BMSG\r\n"
50 #define BMSEG_VERSION "VERSION:1.0\r\n"
51 #define MSEG_STATUS "STATUS:%s\r\n"
52 #define MSEG_TYPE "TYPE:%s\r\n"
53 #define FOLDER_PATH "FOLDER:%s\r\n"
54 #define VCARD "BEGIN:VCARD\r\nVERSION:2.1\r\nN:%s\r\nTEL:%s\r\nEND:VCARD\r\n"
55 #define BEGIN_BENV "BEGIN:BENV\r\n"
56 #define END_BENV "END:BENV\r\n"
57 #define BEGIN_BBODY "BEGIN:BBODY\r\n"
58 #define END_BBODY "END:BBODY\r\n"
59 #define ENCODING "ENCODING:%s\r\n"
60 #define CHARSET "CHARSET:%s\r\n"
61 #define LANGUAGE "LANGUAGE:%s\r\n"
62 #define LENGTH "LENGTH:%d\r\n"
63 #define MSG_BODY "BEGIN:MSG\r\n%s\r\nEND:MSG\r\n"
64 #define MSG_BODY_BEGIN "BEGIN:MSG\r\n"
65 #define MSG_BODY_END "\r\nEND:MSG\r\n"
66
67 static msg_handle_t g_msg_handle = NULL;
68 extern guint64 current_push_map_id;
69
70 static int __bt_get_sms_folder_id(char *folder_path)
71 {
72         FN_START;
73         int folder_id = -1;
74         int i;
75         char *folder;
76         msg_struct_list_s folder_list = {0,};
77         msg_error_t err;
78         msg_struct_t p_folder;
79         DBG_SECURE("folder_path %s\n", folder_path);
80
81         folder = strrchr(folder_path, '/');
82         if (NULL == folder)
83                 folder = folder_path;
84         else
85                 folder++;
86
87         err = msg_get_folder_list(g_msg_handle, &folder_list);
88         if (err != MSG_SUCCESS)
89                 goto done;
90
91         for (i = 0; i < folder_list.nCount; i++) {
92                 char folder_name[BT_MAP_MSG_INFO_MAX] = {0, };
93
94                 p_folder = folder_list.msg_struct_info[i];
95
96                 err = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
97                                         folder_name, BT_MAP_MSG_INFO_MAX);
98                 if (err != MSG_SUCCESS)
99                         continue;
100
101                 DBG_SECURE("folder_name %s\n", folder_name);
102                 if (!g_ascii_strncasecmp(folder_name, folder, strlen(folder))) {
103                         err = msg_get_int_value(p_folder,
104                                         MSG_FOLDER_INFO_ID_INT,
105                                         &folder_id);
106                         if (err != MSG_SUCCESS)
107                                 goto done;
108
109                         DBG("folder_id %d", folder_id);
110                         break;
111                 }
112         }
113
114 done:
115         if (folder_list.msg_struct_info)
116                 msg_release_list_struct(&folder_list);
117
118         FN_END;
119         return folder_id;
120
121 }
122
123
124 static void __bt_add_deleted_folder(void)
125 {
126         FN_START;
127         msg_error_t err;
128         msg_struct_t folder_info = msg_create_struct(MSG_STRUCT_FOLDER_INFO);
129
130         err = msg_set_int_value(folder_info, MSG_FOLDER_INFO_TYPE_INT,
131                                                 MSG_FOLDER_TYPE_USER_DEF);
132         if (err != MSG_SUCCESS) {
133                 ERR("Failed adding type %d", err);
134                 msg_release_struct(&folder_info);
135                 return;
136         }
137
138         err = msg_set_str_value(folder_info, MSG_FOLDER_INFO_NAME_STR,
139                                         "DELETED", MAX_FOLDER_NAME_SIZE);
140         if (err != MSG_SUCCESS) {
141                 ERR("Failed adding str %d", err);
142                 msg_release_struct(&folder_info);
143                 return;
144         }
145
146         err = msg_add_folder(g_msg_handle, folder_info);
147         if (err != MSG_SUCCESS) {
148                 ERR("Failed adding folder %d", err);
149                 msg_release_struct(&folder_info);
150                 return;
151         }
152
153         msg_release_struct(&folder_info);
154         FN_END;
155 }
156
157 static void __bluetooth_map_msg_incoming_status_cb(msg_handle_t handle,
158                                                         msg_struct_t msg,
159                                                         void *user_param)
160 {
161         FN_START;
162         int msg_id = 0;
163         int msg_type = 0;
164         int ret;
165
166         guint64 uid;
167
168         if (is_mns_connected() == FALSE) {
169                 INFO("MNS Client not connected");
170                 return;
171         }
172
173         ret = msg_get_int_value(msg, MSG_MESSAGE_TYPE_INT, &msg_type);
174         if (ret != MSG_SUCCESS)
175                 return;
176
177         if (msg_type != MSG_TYPE_SMS) {
178                 INFO("Not a SMS");
179                 return;
180         }
181
182         ret = msg_get_int_value(msg, MSG_MESSAGE_ID_INT, &msg_id);
183         if (ret != MSG_SUCCESS)
184                 return;
185
186         uid = _bt_add_id(msg_id, BT_MAP_ID_SMS);
187
188         _bt_mns_client_event_notify("NewMessage", uid,
189                                                 "TELECOM/MSG/INBOX", "",
190                                                 "SMS_GSM");
191
192         FN_END;
193 }
194
195 static void __bluetooth_map_msg_sent_status_cb(msg_handle_t handle,
196                                                         msg_struct_t msg,
197                                                         void *user_param)
198 {
199         FN_START;
200         int ret;
201         int status;
202
203         if (is_mns_connected() == FALSE) {
204                 INFO("MNS Client not connected");
205                 return;
206         }
207
208         ret = msg_get_int_value(msg, MSG_SENT_STATUS_NETWORK_STATUS_INT,
209                                                                 &status);
210         if (ret != MSG_SUCCESS)
211                 return;
212
213         if (status == MSG_NETWORK_SEND_SUCCESS) {
214                 INFO("MSG SENT SUCCESS !!! ");
215                 _bt_mns_client_event_notify("MessageShift",
216                                         current_push_map_id,
217                                         "TELECOM/MSG/SENT",
218                                         "TELECOM/MSG/OUTBOX",
219                                         "SMS_GSM");
220
221                 _bt_mns_client_event_notify("SendingSuccess",
222                                         current_push_map_id,
223                                         "TELECOM/MSG/SENT", "",
224                                         "SMS_GSM");
225         } else {
226                 ERR("MSG SENT FAIL !!! [%d]", status);
227                 _bt_mns_client_event_notify("SendingFailure",
228                                         current_push_map_id,
229                                         "TELECOM/MSG/OUTBOX", "",
230                                         "SMS_GSM");
231         }
232
233         FN_END;
234 }
235
236 gboolean _bt_map_sms_get_supported_folders(gboolean folders[FOLDER_COUNT][MSG_TYPES])
237 {
238         FN_START;
239         char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
240         int i;
241         int ret;
242         gboolean msg_ret = TRUE;
243
244         msg_struct_list_s folder_list = {0,};
245         msg_struct_t p_folder;
246
247         if (g_msg_handle == NULL) {
248                 msg_ret = FALSE;
249                 goto done;
250         }
251
252         if (msg_get_folder_list(g_msg_handle, &folder_list) != MSG_SUCCESS) {
253                 msg_ret = FALSE;
254                 goto done;
255         }
256
257         for (i = 0; i < folder_list.nCount; i++) {
258                 p_folder = folder_list.msg_struct_info[i];
259                 memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX);
260
261                 ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
262                                         folder_name, BT_MAP_MSG_INFO_MAX);
263                 if (ret != MSG_SUCCESS)
264                         continue;
265
266                 DBG("%d. %s", i, folder_name);
267                 if (g_strstr_len(folder_name, -1, BT_MAP_MSG_TEMPLATE) ||
268                                 g_strstr_len(folder_name, -1, "CBMSGBOX") ||
269                                 g_strstr_len(folder_name, -1, "SPAMBOX"))
270                         continue;
271
272                 if (!g_ascii_strncasecmp(folder_name, BT_MAP_SENT_FOLDER_NAME,
273                                         strlen(BT_MAP_SENT_FOLDER_NAME))) {
274                         memset(folder_name, 0, sizeof(folder_name));
275                         g_strlcpy(folder_name, BT_MAP_SENT_FOLDER_NAME,
276                                                         sizeof(folder_name));
277                         folders[BT_MSG_SENT][BT_MSG_SOURCE_SMS] = TRUE;
278                         DBG("SENT");
279                 } else if (!g_ascii_strcasecmp(folder_name, "INBOX")) {
280                         folders[BT_MSG_INBOX][BT_MSG_SOURCE_SMS] = TRUE;
281                         DBG("INBOX");
282                 } else if (!g_ascii_strcasecmp(folder_name, "OUTBOX")) {
283                         folders[BT_MSG_OUTBOX][BT_MSG_SOURCE_SMS] = TRUE;
284                         DBG("OUTBOX");
285                 } else if (!g_ascii_strcasecmp(folder_name, "DRAFT")) {
286                         folders[BT_MSG_DRAFT][BT_MSG_SOURCE_SMS] = TRUE;
287                         DBG("DRAFT");
288                 } else if (!g_ascii_strcasecmp(folder_name, "DELETED")) {
289                         folders[BT_MSG_DELETED][BT_MSG_SOURCE_SMS] = TRUE;
290                         DBG("DELETED");
291                 }
292         }
293
294 done:
295
296         if (folder_list.msg_struct_info)
297                 msg_release_list_struct(&folder_list);
298
299         FN_END;
300         return msg_ret;
301 }
302
303 gboolean _bt_map_sms_set_read_status(int msg_id, gboolean read_status)
304 {
305         FN_START;
306         msg_error_t msg_err;
307
308         msg_err = msg_update_read_status(g_msg_handle, msg_id,
309                                                         read_status);
310         if (msg_err != MSG_SUCCESS) {
311                 ERR("Failed to Set Read Status");
312                 return FALSE;
313
314         }
315         FN_END;
316         return TRUE;
317 }
318
319
320 static gchar *__bt_get_sms_folder_name(int id)
321 {
322         FN_START;
323         int ret;
324         int i;
325         int folder_id;
326         gboolean path_found = FALSE;
327         char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
328
329         msg_struct_list_s folder_list = {0,};
330         msg_struct_t p_folder;
331
332         ret = msg_get_folder_list(g_msg_handle, &folder_list);
333         if (ret != MSG_SUCCESS)
334                 return g_strdup("TELECOM/MSG");
335
336         if (folder_list.msg_struct_info == NULL)
337                 return g_strdup("TELECOM/MSG");
338
339         for (i = 0; i < folder_list.nCount; i++) {
340                 p_folder = folder_list.msg_struct_info[i];
341
342                 ret = msg_get_int_value(p_folder,
343                                         MSG_FOLDER_INFO_ID_INT,
344                                         &folder_id);
345                 if (ret != MSG_SUCCESS)
346                         break;
347                 DBG("folder_id %d, id = %d", folder_id, id);
348                 if (folder_id == id) {
349                         ret = msg_get_str_value(p_folder,
350                                         MSG_FOLDER_INFO_NAME_STR,
351                                         folder_name, BT_MAP_MSG_INFO_MAX);
352                         if (ret != MSG_SUCCESS)
353                                 break;
354
355                         path_found = TRUE;
356                         DBG_SECURE("folder_name %s", folder_name);
357                         break;
358                 }
359         }
360
361         if (folder_list.msg_struct_info) {
362                 ret = msg_release_list_struct(&folder_list);
363                 ERR("Err %d", ret);
364         }
365
366         FN_END;
367         if (path_found != TRUE)
368                 return g_strdup("TELECOM/MSG");
369         else
370                 return g_strdup_printf("TELECOM/MSG/%s", folder_name);
371 }
372
373 gboolean _bt_map_set_sms_delete_status(int msg_id, gboolean delete_status)
374 {
375         FN_START;
376         int folder_id;
377         int del_folder_id;
378         int err;
379         gchar *folder_name = NULL;
380         guint64 map_id;
381         msg_struct_t msg = NULL;
382         msg_struct_t send_opt = NULL;
383
384
385         if (msg_id == -1)
386                 goto fail;
387
388         if (g_msg_handle == NULL)
389                 goto fail;
390
391         msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
392         if (msg == NULL)
393                 goto fail;
394
395         send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
396         if (send_opt == NULL)
397                 goto fail;
398
399         err = msg_get_message(g_msg_handle,
400                                         (msg_message_id_t)msg_id,
401                                         msg, send_opt);
402         if (err != MSG_SUCCESS)
403                 goto fail;
404
405         err = msg_get_int_value(msg, MSG_MESSAGE_FOLDER_ID_INT,
406                                                         &folder_id);
407         if (err != MSG_SUCCESS)
408                 goto fail;
409
410         folder_name = __bt_get_sms_folder_name(folder_id);
411         del_folder_id = __bt_get_sms_folder_id(BT_MAP_DELETED_FOLDER_NAME);
412         map_id = _bt_validate_uid(msg_id, BT_MAP_ID_SMS);
413
414         DBG("msg_id = %d, delete_status = %d\n", msg_id, delete_status);
415
416         if (del_folder_id == -1) {
417                 ERR("Delete folder not present");
418                 if (delete_status == TRUE) {
419                         err = msg_delete_message(g_msg_handle, msg_id);
420                         if (err != MSG_SUCCESS)
421                                 goto fail;
422                 }
423         } else {
424                 if (delete_status == TRUE) {
425                         err = msg_move_msg_to_folder(g_msg_handle, msg_id, del_folder_id);
426                         if (err == MSG_SUCCESS) {
427                                 _bt_mns_client_event_notify("MessageShift",
428                                                 map_id,
429                                                 "TELECOM/MSG/DELETED",
430                                                 folder_name,
431                                                 "SMS_GSM");
432                         }
433                 } else {
434                         if (folder_id != del_folder_id) {
435                                 DBG("Message not in delete folder");
436                                 goto fail;
437                         }
438
439                         err = msg_move_msg_to_folder(g_msg_handle, msg_id, MSG_INBOX_ID);
440                         if (err == MSG_SUCCESS) {
441                                 _bt_mns_client_event_notify("MessageShift",
442                                                 map_id,
443                                                 "TELECOM/MSG/INBOX",
444                                                 "TELECOM/MSG/DELETED",
445                                                 "SMS_GSM");
446                         }
447                 }
448         }
449
450         g_free(folder_name);
451         msg_release_struct(&msg);
452         msg_release_struct(&send_opt);
453
454         FN_END;
455         return TRUE;
456
457 fail:
458         g_free(folder_name);
459
460         msg_release_struct(&msg);
461         msg_release_struct(&send_opt);
462
463         ERR("Failed to Delete SMS");
464         return FALSE;
465 }
466
467 static msg_error_t __bt_send_sms(int msg_id, msg_struct_t p_msg, msg_struct_t p_send_opt)
468 {
469         FN_START;
470         msg_error_t err;
471         msg_struct_t p_req;
472
473         p_req = msg_create_struct(MSG_STRUCT_REQUEST_INFO);
474
475         msg_set_int_value(p_msg, MSG_MESSAGE_ID_INT, msg_id);
476         msg_set_struct_handle(p_req, MSG_REQUEST_MESSAGE_HND, p_msg);
477         msg_set_struct_handle(p_req, MSG_REQUEST_SENDOPT_HND, p_send_opt);
478
479         err = msg_sms_send_message(g_msg_handle, p_req);
480         if (err != MSG_SUCCESS)
481                 ERR("Failed msg_sms_send_message %d", err);
482
483         msg_release_struct(&p_req);
484         FN_END;
485         return err;
486 }
487
488 static int __bt_push_sms(gboolean send, int folder_id, char *body,
489                 GSList *recepients, msg_send_option_t *option)
490 {
491         FN_START;
492         msg_struct_t msg_info = NULL;
493         msg_struct_t send_opt = NULL;
494         msg_error_t err;
495
496         int msg_id = -1;
497
498         msg_info = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
499         if (msg_info == NULL)
500                 goto fail;
501
502         err = msg_set_int_value(msg_info, MSG_MESSAGE_TYPE_INT, MSG_TYPE_SMS);
503         if (err != MSG_SUCCESS)
504                 goto fail;
505
506         if (body) {
507                 err = msg_set_str_value(msg_info,
508                                         MSG_MESSAGE_SMS_DATA_STR,
509                                         body, strlen(body));
510                 if (err != MSG_SUCCESS)
511                         goto fail;
512         } else {
513                 err = msg_set_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR,
514                                                                 NULL, 0);
515                 if (err != MSG_SUCCESS)
516                         goto fail;
517         }
518
519         DBG("folder_id  %d\n", folder_id);
520         err = msg_set_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
521                                                                 folder_id);
522         if (err != MSG_SUCCESS)
523                 goto fail;
524
525         while (recepients) {
526                 msg_struct_t tmp_addr;
527                 char *address = recepients->data;
528                 if (address == NULL) {
529                         ERR("[ERROR] address is value NULL, skip");
530                         recepients = g_slist_next(recepients);
531                         continue;
532                 }
533
534                 msg_list_add_item(msg_info,
535                                 MSG_MESSAGE_ADDR_LIST_HND, &tmp_addr);
536
537                 msg_set_int_value(tmp_addr,
538                                 MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT,
539                                 MSG_RECIPIENTS_TYPE_TO);
540
541                 msg_set_str_value(tmp_addr,
542                                 MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
543                                 address, strlen(address));
544
545                 recepients = g_slist_next(recepients);
546         }
547
548         send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
549
550         err = msg_set_bool_value(send_opt, MSG_SEND_OPT_SETTING_BOOL, true);
551         if (err != MSG_SUCCESS)
552                 goto fail;
553
554         /* Do not keep a copy
555         err = msg_set_bool_value(send_opt, MSG_SEND_OPT_KEEPCOPY_BOOL,
556                         option->save_copy);
557         */
558         err = msg_set_bool_value(send_opt, MSG_SEND_OPT_KEEPCOPY_BOOL,
559                         true);
560         if (err != MSG_SUCCESS)
561                 goto fail;
562
563         msg_id = msg_add_message(g_msg_handle, msg_info, send_opt);
564         DBG("msg_id = %d\n", msg_id);
565
566         if (send == TRUE)
567                 __bt_send_sms(msg_id, msg_info, send_opt);
568
569
570 fail:
571         msg_release_struct(&msg_info);
572         msg_release_struct(&send_opt);
573         FN_END;
574         return msg_id;
575 }
576
577 gboolean _bt_map_push_sms_data(struct bmsg_data *bmsg_info,
578                 msg_send_option_t *option, char *folder)
579 {
580         FN_START;
581         int id = -1;
582         int folder_id;
583         char *body = NULL;
584         GSList *recepients = NULL;
585         gboolean send = FALSE;
586
587         DBG("Length of Folder String: %d", strlen(bmsg_info->folder));
588         if (strlen(bmsg_info->folder) == 0) {
589                 DBG("No Folder Info. Default to OUTBOX");
590                 bmsg_info->folder = g_strdup(folder);
591         }
592
593         folder_id = __bt_get_sms_folder_id(bmsg_info->folder);
594         if (folder_id == -1)
595                 goto done;
596
597         if (folder_id == MSG_OUTBOX_ID)
598                 send = TRUE;
599
600         body = bmsg_get_msg_body(bmsg_info, option->native);
601         if (body == NULL)
602                 goto done;
603
604         recepients = bmsg_get_msg_recepients(bmsg_info, BT_MAP_ID_SMS);
605
606         id = __bt_push_sms(send, folder_id, body, recepients, option);
607         if (id == -1)
608                 goto done;
609
610         _bt_update_id(current_push_map_id, id, BT_MAP_ID_SMS);
611
612 done:
613         g_free(body);
614         g_slist_free(recepients);
615
616         if (id == -1) {
617                 FN_END;
618                 return FALSE;
619         }
620
621         FN_END;
622         return TRUE;
623 }
624
625
626 static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach,
627                                                         gboolean transcode)
628 {
629         FN_START;
630         int ret;
631         int m_type = MSG_TYPE_SMS;
632         int folder_id;
633         int count;
634         int dptime = 0;
635         int j;
636         bool read_status = false;
637         char msg_body[BT_MAP_MSG_BODY_MAX] = {0,};
638         char addr_value[MAX_ADDRESS_VAL_LEN] = {0,};
639         char name_value[MAX_DISPLAY_NAME_LEN] = {0,};
640
641         msg_list_handle_t addr_list = NULL;
642         msg_struct_t addr_info = NULL;
643
644         GString *msg;
645         gchar *folder_path = NULL;
646         gchar *msg_pdu;
647
648         msg = g_string_new(BEGIN_BMSEG);
649         g_string_append(msg, BMSEG_VERSION);
650
651         ret = msg_get_bool_value(msg_info, MSG_MESSAGE_READ_BOOL, &read_status);
652         if (ret == MSG_SUCCESS)
653                 INFO("read_status %d\n", read_status);
654
655         if (read_status)
656                 g_string_append_printf(msg, MSEG_STATUS, "READ");
657         else
658                 g_string_append_printf(msg, MSEG_STATUS, "UNREAD");
659
660         ret = msg_get_int_value(msg_info, MSG_MESSAGE_TYPE_INT, &m_type);
661         if (ret == MSG_SUCCESS) {
662                 INFO("m_type %d\n", m_type);
663                  g_string_append_printf(msg, MSEG_TYPE, "SMS_GSM");
664         }
665
666         ret = msg_get_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
667                                                         &folder_id);
668         if (ret == MSG_SUCCESS) {
669                 DBG("folder_id %d\n", folder_id);
670
671                 folder_path = __bt_get_sms_folder_name(folder_id);
672                 g_string_append_printf(msg, FOLDER_PATH, folder_path);
673         }
674
675         ret = msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_HND,
676                                                 (void **)&addr_list);
677         if (ret == MSG_SUCCESS) {
678                 count = msg_list_length(addr_list);
679                 DBG("count %d \n", count);
680
681                 if (count > 0) {
682                         addr_info = (msg_struct_t)msg_list_nth_data(addr_list,
683                                                                         0);
684
685                         msg_get_str_value(addr_info,
686                                         MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
687                                         addr_value, MAX_ADDRESS_VAL_LEN);
688                         DBG_SECURE("addr_value %s\n", addr_value);
689                         msg_get_str_value(addr_info,
690                                         MSG_ADDRESS_INFO_DISPLAYNAME_STR,
691                                         name_value, MAX_DISPLAY_NAME_LEN);
692                         if (!strlen(name_value))
693                                 g_stpcpy(name_value, addr_value);
694
695                         DBG_SECURE("name_value %s\n", name_value);
696
697                         g_string_append_printf(msg, VCARD, name_value,
698                                                                 addr_value);
699                 }
700         }
701
702         g_string_append(msg, BEGIN_BENV);
703         g_string_append(msg, BEGIN_BBODY);
704
705         if (transcode) {
706                 g_string_append_printf(msg, CHARSET, "UTF-8");
707
708
709                 ret = msg_get_str_value(msg_info,
710                                         MSG_MESSAGE_SMS_DATA_STR,
711                                         msg_body, BT_MAP_MSG_BODY_MAX);
712                 if (ret == MSG_SUCCESS) {
713 #ifdef ARCH64
714                         g_string_append_printf(msg, LENGTH, (int)(unsigned int)strlen(msg_body));
715 #else
716                         g_string_append_printf(msg, LENGTH, strlen(msg_body));
717 #endif
718                         g_string_append_printf(msg, MSG_BODY, msg_body);
719                 }
720         } else {
721                 g_string_append_printf(msg, ENCODING, "G-7BIT");
722                 g_string_append_printf(msg, CHARSET, "native");
723
724                 msg_get_int_value(msg_info,
725                                 MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
726
727                 ret = msg_get_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR,
728                                         msg_body, BT_MAP_MSG_BODY_MAX);
729                 if (ret == MSG_SUCCESS) {
730                         int msg_pdu_len = 0;
731                         msg_pdu = _bt_get_sms_pdu_from_msg_data(addr_value,
732                                                         msg_body, dptime,
733                                                         &msg_pdu_len);
734                         if (msg_pdu) {
735                                 DBG("msg_pdu_len = %d", msg_pdu_len);
736
737                                 g_string_append_printf(msg, LENGTH, msg_pdu_len);
738                                 g_string_append(msg, MSG_BODY_BEGIN);
739                                 for (j = 0; j < msg_pdu_len; j++)
740                                         g_string_append_printf(msg, "%02x",
741                                                                         msg_pdu[j]);
742
743                                 g_string_append(msg, MSG_BODY_END);
744                                 g_free(msg_pdu);
745                         }
746                 }
747         }
748
749         g_string_append(msg, END_BBODY);
750         g_string_append(msg, END_BENV);
751         g_string_append(msg, END_BMSEG);
752         g_free(folder_path);
753
754         FN_END;
755         return g_string_free(msg, FALSE);
756 }
757
758 gboolean _bt_map_get_sms_message(int message_id, gboolean attach,
759                 gboolean transcode, gboolean first_request, gchar **bmseg)
760 {
761         FN_START;
762         msg_error_t msg_err;
763         msg_struct_t msg = NULL;
764         msg_struct_t send_opt = NULL;
765
766         DBG("message_id %d \n", message_id);
767         DBG("attach %d \n", attach);
768         DBG("transcode %d \n", transcode);
769         DBG("first_request %d \n", first_request);
770
771         if (g_msg_handle == NULL)
772                 goto fail;
773
774         msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
775         if (!msg)
776                 goto fail;
777
778         send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
779         if (!send_opt)
780                 goto fail;
781
782         msg_err = msg_get_message(g_msg_handle,
783                                         (msg_message_id_t)message_id,
784                                         msg, send_opt);
785         if (msg_err != MSG_SUCCESS)
786                 goto fail;
787
788         *bmseg = __bt_prepare_msg_bmseg(msg, attach, transcode);
789         msg_release_struct(&msg);
790         msg_release_struct(&send_opt);
791
792         FN_END;
793         return TRUE;
794
795 fail:
796
797         if (msg)
798                 msg_release_struct(&msg);
799
800         if (send_opt)
801                 msg_release_struct(&send_opt);
802
803         ERR("Unable to Get SMS Message");
804         return FALSE;
805 }
806
807 static char *__bt_get_truncated_utf8_string(char *src)
808 {
809         FN_START;
810         char *p = src;
811         char *next;
812         char dest[BT_MAP_SUBJECT_MAX_LEN] = {0,};
813         int count;
814         int i = 0;
815
816         if (src == NULL)
817                 return NULL;
818
819         while (*p != '\0' && i < sizeof(dest)) {
820                 next = g_utf8_next_char(p);
821                 count = next - p;
822
823                 while (count > 0 && ((i + count) < sizeof(dest))) {
824                         dest[i++] = *p;
825                         p++;
826                         count--;
827                 }
828                 p = next;
829         }
830
831         FN_END;
832         return g_strdup(dest);
833 }
834
835
836 static message_info_t *__bt_message_info_get(msg_struct_t msg_struct_handle,
837                                                         guint8 subject_len)
838 {
839         FN_START;
840         message_info_t *msg_info = NULL;
841         int ret;
842         int msg_id;
843         guint64 uid;
844         time_t dptime;
845         int m_type = 0;
846         int data_size;
847         int priority;
848         int direction_type;
849         int count;
850         bool protect_status = 0;
851         bool read_status = 0;
852
853         char msg_handle[BT_MAP_MSG_HANDLE_MAX] = {0,};
854         char msg_datetime[BT_MAP_TIMESTAMP_MAX_LEN] = {0,};
855         char msg_size[5] = {0,};
856         char msg_body[BT_MAP_MSG_BODY_MAX] = {0,};
857         char addr_value[MAX_ADDRESS_VAL_LEN] = {0,};
858         char name_value[MAX_DISPLAY_NAME_LEN] = {0,};
859
860         msg_info = g_new0(message_info_t, 1);
861         msg_info->text = FALSE;
862         msg_info->protect = FALSE;
863         msg_info->read = FALSE;
864         msg_info->priority = FALSE;
865
866         msg_struct_t msg = NULL;
867         msg_struct_t send_opt = NULL;
868         msg_list_handle_t addr_list = NULL;
869         msg_struct_t addr_info = NULL;
870
871         ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_ID_INT, &msg_id);
872         if (ret != MSG_SUCCESS)
873                 ERR("Could not get Message ID");
874
875         uid = _bt_add_id(msg_id, BT_MAP_ID_SMS);
876 #ifdef ARCH64
877         snprintf(msg_handle, sizeof(msg_handle), "%lx", uid);
878 #else
879         snprintf(msg_handle, sizeof(msg_handle), "%llx", uid);
880 #endif
881         DBG("HANDLE: %s, MAP Id: %d, MSG ID:%d", msg_handle, uid, msg_id);
882         msg_info->handle = g_strdup(msg_handle);
883
884         msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
885         if (msg == NULL)
886                 goto next;
887
888         send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
889         if (send_opt == NULL)
890                 goto next;
891
892         ret = msg_get_message(g_msg_handle,
893                                                 (msg_message_id_t)msg_id,
894                                                 msg, send_opt);
895         if (ret != MSG_SUCCESS) {
896                 DBG("ret = %d\n", ret);
897                 goto next;
898         }
899
900         ret = msg_get_list_handle(msg, MSG_MESSAGE_ADDR_LIST_HND,
901                                                         (void **)&addr_list);
902         if (ret != MSG_SUCCESS) {
903                 DBG("ret = %d\n", ret);
904                 goto next;
905         }
906
907         count = msg_list_length(addr_list);
908
909         if (count != 0) {
910                 addr_info = (msg_struct_t)msg_list_nth_data(addr_list, 0);
911
912                 ret = msg_get_str_value(addr_info,
913                                         MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
914                                         addr_value, MAX_ADDRESS_VAL_LEN);
915                 if (ret == MSG_SUCCESS)
916                         DBG_SECURE("addr_value %s\n", addr_value);
917
918                 ret = msg_get_str_value(addr_info,
919                                         MSG_ADDRESS_INFO_DISPLAYNAME_STR,
920                                         name_value, MAX_DISPLAY_NAME_LEN);
921
922                 if (ret == MSG_SUCCESS)
923                         DBG_SECURE("name_value %s\n", name_value);
924
925                 if (!strlen(name_value))
926                         g_stpcpy(name_value, addr_value);
927
928                 DBG_SECURE("name_value %s\n", name_value);
929         }
930
931         ret = msg_get_int_value(msg, MSG_MESSAGE_DIRECTION_INT,
932                                                 &direction_type);
933         if (ret != MSG_SUCCESS)
934                 goto next;
935
936         if (direction_type == MSG_DIRECTION_TYPE_MT) {
937                 msg_info->sender_name = g_strdup(name_value);
938                 msg_info->sender_addressing = g_strdup(addr_value);
939                 msg_info->recipient_name = g_strdup("Unknown");
940                 msg_info->recipient_addressing = g_strdup("0000");
941         } else {
942                 msg_info->sender_name = g_strdup("Unknown");
943                 msg_info->sender_addressing = g_strdup("0000");
944                 msg_info->recipient_name = g_strdup(name_value);
945                 msg_info->recipient_addressing = g_strdup(addr_value);
946         }
947
948 next:
949         msg_release_struct(&msg);
950         msg_release_struct(&send_opt);
951
952         ret = msg_get_int_value(msg_struct_handle,
953                                 MSG_MESSAGE_DISPLAY_TIME_INT, (int *)&dptime);
954         if (ret == MSG_SUCCESS)
955                 _get_msg_timestamp(&dptime, msg_datetime);
956
957         DBG("Got date time: %s", msg_datetime);
958
959         msg_info->datetime = g_strdup(msg_datetime);
960         msg_info->time = dptime; // for sorting
961
962         ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_TYPE_INT,
963                                                                 &m_type);
964         if (ret == MSG_SUCCESS)
965                 DBG("m_type %d\n", m_type);
966
967         msg_info->type = g_strdup("SMS_GSM");
968
969         ret = msg_get_str_value(msg_struct_handle,
970                                 MSG_MESSAGE_SMS_DATA_STR, msg_body,
971                                 BT_MAP_MSG_BODY_MAX);
972         if (ret == MSG_SUCCESS) {
973                 DBG_SECURE("SMS subject %s", msg_body);
974                 if (strlen(msg_body)) {
975                         char *subject;
976                         msg_info->text = TRUE;
977                         subject = __bt_get_truncated_utf8_string(msg_body);
978                         msg_info->subject = g_strndup(subject, subject_len);
979                         g_free(subject);
980                 }
981         }
982
983         ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_DATA_SIZE_INT,
984                                                                 &data_size);
985         if (ret == MSG_SUCCESS)
986                 snprintf(msg_size, sizeof(msg_size), "%d", data_size);
987
988         msg_info->size = g_strdup(msg_size);
989
990         msg_info->reception_status = g_strdup("complete");
991         msg_info->attachment_size = g_strdup("0");
992
993         ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_PROTECTED_BOOL,
994                                                         &protect_status);
995         if (ret == MSG_SUCCESS) {
996                 if (protect_status)
997                         msg_info->protect = TRUE;
998         }
999
1000         ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_READ_BOOL,
1001                                                                 &read_status);
1002         if (ret == MSG_SUCCESS) {
1003                 if (read_status)
1004                         msg_info->read = TRUE;
1005         }
1006
1007         ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_PRIORITY_INT,
1008                                                                 &priority);
1009         if (ret == MSG_SUCCESS) {
1010                 if (priority == MSG_MESSAGE_PRIORITY_HIGH)
1011                         msg_info->priority = TRUE;
1012         }
1013
1014         FN_END;
1015         return msg_info;
1016 }
1017
1018 gboolean _bt_map_get_sms_message_list(gchar *folder, guint16 max,
1019                 guint8 subject_len, map_msg_filter_t *filter,
1020                 GSList **sms_list, guint64 *count, gboolean *newmsg)
1021 {
1022         FN_START;
1023         int i = 0;
1024         int ret = 0;
1025         int folder_id = -1;
1026         guint64 local_count;
1027         bool read;
1028
1029         msg_struct_list_s folder_list = {0,};
1030         msg_struct_list_s msg_list = {0,};
1031         msg_struct_t list_cond;
1032         GSList *list = NULL;
1033         int msg_count;
1034
1035         DBG("Folder:%s Max:%d", folder, max);
1036         if (max == 0)
1037                 max = 1024;
1038
1039         ret = msg_get_folder_list(g_msg_handle, &folder_list);
1040         if (ret != MSG_SUCCESS)
1041                 goto fail;
1042
1043         for (i = 0; i < folder_list.nCount; i++) {
1044                 char f_name[BT_MAP_MSG_INFO_MAX] = {0, };
1045                 msg_struct_t p_folder = folder_list.msg_struct_info[i];
1046
1047                 ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
1048                                         f_name, BT_MAP_MSG_INFO_MAX);
1049                 if (ret  != MSG_SUCCESS)
1050                         continue;
1051
1052                 if (!g_ascii_strncasecmp(f_name, folder, strlen(folder))) {
1053                         ret = msg_get_int_value(p_folder, MSG_FOLDER_INFO_ID_INT,
1054                                                                 &folder_id);
1055                         if (ret != MSG_SUCCESS)
1056                                 goto fail;
1057
1058                         DBG("folder_id %d \n", folder_id);
1059
1060                         break;
1061                 }
1062         }
1063
1064         if (folder_id == -1)
1065                 goto fail;
1066
1067         list_cond = msg_create_struct(MSG_STRUCT_MSG_LIST_CONDITION);
1068         ret = msg_set_int_value(list_cond,
1069                                 MSG_LIST_CONDITION_FOLDER_ID_INT,
1070                                 folder_id);
1071         if (ret != MSG_SUCCESS)
1072                 goto fail;
1073
1074         ret = msg_set_int_value(list_cond,
1075                                 MSG_LIST_CONDITION_MSGTYPE_INT, MSG_TYPE_SMS);
1076         if (ret != MSG_SUCCESS)
1077                 goto fail;
1078
1079         ret = msg_get_message_list2(g_msg_handle, list_cond, &msg_list);
1080
1081         msg_release_struct(&list_cond);
1082
1083         if (ret != MSG_SUCCESS)
1084                 goto fail;
1085
1086         local_count = (guint64)msg_list.nCount;
1087         DBG("msg_list.nCount: %d, count:%d", msg_list.nCount, local_count);
1088         for (i = 0; i < local_count; i++) {
1089                 msg_get_bool_value(msg_list.msg_struct_info[i],
1090                                         MSG_MESSAGE_READ_BOOL, &read);
1091                 if (read == false) {
1092                         *newmsg = TRUE;
1093                         break;
1094                 }
1095         }
1096
1097         DBG("count = %llx, newmsg = %d, max = %d", local_count, *newmsg, max);
1098
1099         for (i = 0, msg_count = 0; i < local_count && msg_count < max; i++) {
1100                 message_info_t *msg_info;
1101
1102                 msg_info = __bt_message_info_get(msg_list.msg_struct_info[i],
1103                                                                 subject_len);
1104
1105                 if (!_bt_verify_read_status(msg_info, filter->read_status) ||
1106                                 !_bt_verify_receiver(msg_info, filter->recipient) ||
1107                                 !_bt_verify_sender(msg_info, filter->originator) ||
1108                                 !_bt_verify_time(msg_info, filter) ||
1109                                 !_bt_filter_priority(msg_info, filter->priority) ||
1110                                 !_bt_validate_msg_data(msg_info)) {
1111                         _bt_message_info_free((gpointer)msg_info);
1112                         continue;
1113                 }
1114
1115                 list = g_slist_append(list, msg_info);
1116                 msg_count++;
1117         }
1118
1119         if (folder_list.msg_struct_info)
1120                 ret = msg_release_list_struct(&folder_list);
1121
1122         if (msg_list.msg_struct_info)
1123                 ret = msg_release_list_struct(&msg_list);
1124
1125         *count = local_count;
1126         *sms_list = list;
1127         FN_END;
1128         return TRUE;
1129
1130 fail:
1131         if (folder_list.msg_struct_info)
1132                 ret = msg_release_list_struct(&folder_list);
1133
1134         if (msg_list.msg_struct_info)
1135                 ret = msg_release_list_struct(&msg_list);
1136
1137         ERR("Getting SMS List Failed");
1138         return FALSE;
1139 }
1140
1141 void _bt_map_stop_sms_service(void)
1142 {
1143         FN_START;
1144         msg_error_t err =  MSG_SUCCESS;
1145         int folder_id;
1146
1147         folder_id = __bt_get_sms_folder_id(BT_MAP_DELETED_FOLDER_NAME);
1148         if (folder_id != -1) {
1149                 err = msg_delete_folder(g_msg_handle, folder_id);
1150                 if (err != MSG_SUCCESS)
1151                         ERR("Delete folder failed");
1152         }
1153
1154         if (g_msg_handle) {
1155                 msg_close_msg_handle(&g_msg_handle);
1156                 g_msg_handle = NULL;
1157         }
1158
1159         FN_END;
1160 }
1161
1162 gboolean _bt_map_start_sms_service(void)
1163 {
1164         FN_START;
1165         msg_error_t err;
1166
1167         err = msg_open_msg_handle(&g_msg_handle);
1168         if (err != MSG_SUCCESS) {
1169                 ERR("msg_open_msg_handle error = %d\n", err);
1170                 return FALSE;
1171         }
1172
1173         if (__bt_get_sms_folder_id(BT_MAP_DELETED_FOLDER_NAME) == -1)
1174                 __bt_add_deleted_folder();
1175
1176         err = msg_reg_sms_message_callback(g_msg_handle,
1177                                         __bluetooth_map_msg_incoming_status_cb,
1178                                         0, (void *)BT_MAP_MSG_CB);
1179         if (err != MSG_SUCCESS) {
1180                 ERR("msg_reg_sms_message_callback error  = %d\n", err);
1181                 return FALSE;
1182         }
1183
1184         err = msg_reg_sent_status_callback(g_msg_handle,
1185                                         __bluetooth_map_msg_sent_status_cb,
1186                                         NULL);
1187         if (err != MSG_SUCCESS) {
1188                 ERR("msg_reg_sent_status_callback error  = %d\n", err);
1189                 return FALSE;
1190         }
1191
1192         FN_END;
1193         return TRUE;
1194 }