Fix the Svace issue
[platform/core/connectivity/bluetooth-agent.git] / map-agent / bluetooth_map_agent.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  *               Girishashok Joshi <girish.joshi@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 <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <glib.h>
29 #include <dbus/dbus-glib.h>
30 #include <dbus/dbus.h>
31 #include <time.h>
32 #include "vconf.h"
33 #include "vconf-keys.h"
34
35 #include <sys/types.h>
36 #include <fcntl.h>
37
38 /*Messaging Header Files*/
39 #include "msg.h"
40 #include "msg_storage.h"
41 #include "msg_storage_types.h"
42 #include "msg_transport.h"
43 #include "msg_transport_types.h"
44 #include "msg_types.h"
45
46 #include <TelSms.h>
47 #include <TapiUtility.h>
48 #include <ITapiNetText.h>
49 #include <bluetooth_map_agent.h>
50 #include <map_bmessage.h>
51
52 #define OBEX_CLIENT_SERVICE "org.bluez.obex"
53 #define OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
54 #define OBEX_CLIENT_PATH "/org/bluez/obex"
55
56 #define MNS_CLIENT_INTERFACE "org.openobex.MessageNotification"
57
58 #define DBUS_STRUCT_STRING_STRING_UINT (dbus_g_type_get_struct("GValueArray", \
59                 G_TYPE_STRING, G_TYPE_STRING,  G_TYPE_STRING, G_TYPE_INVALID))
60
61 #define DBUS_STRUCT_MESSAGE_LIST (dbus_g_type_get_struct("GValueArray", \
62                 G_TYPE_STRING, G_TYPE_STRING,  G_TYPE_STRING, G_TYPE_STRING, \
63                 G_TYPE_STRING, G_TYPE_STRING,  G_TYPE_STRING, G_TYPE_STRING, \
64                 G_TYPE_STRING, G_TYPE_STRING,   G_TYPE_BOOLEAN, G_TYPE_STRING, \
65                 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, \
66                 G_TYPE_BOOLEAN, G_TYPE_STRING, \
67                 G_TYPE_INVALID))
68
69 static msg_handle_t g_msg_handle = NULL;
70 static TapiHandle *g_tapi_handle = NULL;
71 static TelSmsAddressInfo_t *g_sca_info = NULL;
72 static DBusGProxy *g_mns_proxy;
73
74 #define BT_MAP_NEW_MESSAGE "NewMessage"
75 #define BT_MAP_STATUS_CB "sent status callback"
76 #define BT_MAP_MSG_CB "sms message callback"
77 #define BT_MNS_OBJECT_PATH "/org/bluez/mns"
78 #define BT_MNS_INTERFACE "org.bluez.mns"
79 #define BT_MAP_SENT_FOLDER_NAME "SENT"
80 #define BT_MAP_MSG_TEMPLATE "TEMPLATE"
81 #define BT_MAP_DELETED_FOLDER_NAME "DELETED"
82 #define BT_MAP_MSG_INFO_MAX 256
83 #define BT_MAP_MSG_HANDLE_MAX 21
84 #define BT_MAP_TIMESTAMP_MAX_LEN 16
85 #define BT_MAP_SUBJECT_MAX_LEN 50
86 #define BT_MAP_MSG_BODY_MAX 1024
87 #define BT_MSG_UPDATE   0
88 #define BT_MSG_DELETE   1
89 #define BT_SMS 0
90
91 #define BEGIN_BMSEG "BEGIN:BMSG\r\n"
92 #define END_BMSEG "END:BMSG\r\n"
93 #define BMSEG_VERSION "VERSION:1.0\r\n"
94 #define MSEG_STATUS "STATUS:%s\r\n"
95 #define MSEG_TYPE "TYPE:%s\r\n"
96 #define FOLDER_PATH "FOLDER:%s\r\n"
97 #define VCARD "BEGIN:VCARD\r\nVERSION:2.1\r\nN:%s\r\nTEL:%s\r\nEND:VCARD\r\n"
98 #define BEGIN_BENV "BEGIN:BENV\r\n"
99 #define END_BENV "END:BENV\r\n"
100 #define BEGIN_BBODY "BEGIN:BBODY\r\n"
101 #define END_BBODY "END:BBODY\r\n"
102 #define ENCODING "ENCODING:%s\r\n"
103 #define CHARSET "CHARSET:%s\r\n"
104 #define LANGUAGE "LANGUAGE:%s\r\n"
105 #define LENGTH "LENGTH:%d\r\n"
106 #define MSG_BODY "BEGIN:MSG\r\n%s\r\nEND:MSG\r\n"
107 #define MSG_BODY_BEGIN "BEGIN:MSG\r\n"
108 #define MSG_BODY_END "\r\nEND:MSG\r\n"
109
110 GSList *id_list = NULL;
111 guint64 current_push_map_id;
112
113 typedef enum {
114         SMS_TON_UNKNOWN = 0,            /* unknown */
115         SMS_TON_INTERNATIONAL = 1,      /* international number */
116         SMS_TON_NATIONAL = 2,           /* national number */
117         SMS_TON_NETWORK_SPECIFIC = 3, /* network specific number */
118         SMS_TON_DEDICATED_ACCESS = 4, /* subscriber number */
119         SMS_TON_ALPHA_NUMERIC = 5,      /* alphanumeric, GSM 7-bit default */
120         SMS_TON_ABBREVIATED_NUMBER = 6, /* abbreviated number */
121         SMS_TON_RESERVED_FOR_EXT = 7 /* reserved for extension */
122 } bt_sim_type_of_num_t;
123
124 struct id_info {
125         guint64 map_id;
126         int uid;
127 };
128
129 struct msg_send_option {
130         bool save_copy;
131         bool retry_send;
132         bool native;
133 };
134
135 struct message_info {
136         char *handle;
137         char *subject;
138         char *datetime;
139         char *sender_name;
140         char *sender_addressing;
141         char *recipient_name;
142         char *recipient_addressing;
143         char *type;
144         char *size;
145         char *reception_status;
146         char *attachment_size;
147         char *replyto_addressing;
148         gboolean text;
149         gboolean priority;
150         gboolean read;
151         gboolean sent;
152         gboolean protect;
153 };
154
155 typedef struct {
156         GObject parent;
157 } BluetoothMapAgent;
158
159 typedef struct {
160         GObjectClass parent;
161 } BluetoothMapAgentClass;
162
163 GType bluetooth_map_agent_get_type(void);
164
165 #define BLUETOOTH_MAP_TYPE_AGENT (bluetooth_map_agent_get_type())
166
167 #define BLUETOOTH_MAP_AGENT(object) \
168         (G_TYPE_CHECK_INSTANCE_CAST((object), \
169         BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgent))
170 #define BLUETOOTH_MAP_AGENT_CLASS(klass) \
171         (G_TYPE_CHECK_CLASS_CAST((klass), \
172         BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgentClass))
173 #define BLUETOOTH_MAP_IS_AGENT(object) \
174         (G_TYPE_CHECK_INSTANCE_TYPE((object), \
175         BLUETOOTH_MAP_TYPE_AGENT))
176 #define BLUETOOTH_MAP_IS_AGENT_CLASS(klass) \
177         (G_TYPE_CHECK_CLASS_TYPE((klass), \
178         BLUETOOTH_MAP_TYPE_AGENT))
179 #define BLUETOOTH_MAP_AGENT_GET_CLASS(obj) \
180         (G_TYPE_INSTANCE_GET_CLASS((obj), \
181         BLUETOOTH_MAP_TYPE_AGENT , BluetoothMapAgentClass))
182
183 G_DEFINE_TYPE(BluetoothMapAgent, bluetooth_map_agent, G_TYPE_OBJECT)
184
185 GMainLoop *g_mainloop = NULL;
186 static DBusGConnection *g_connection = NULL;
187 static char *g_mns_path = NULL;
188 static struct msg_send_option opt;
189
190 static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
191                                         DBusGMethodInvocation *context);
192 static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
193                                         gchar *folder_name, guint16 max,
194                                         DBusGMethodInvocation *context);
195 static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent,
196                                         gchar *message_name,
197                                         gboolean attach, gboolean transcode,
198                                         gboolean first_request,
199                                         DBusGMethodInvocation *context);
200 static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent,
201                                         gboolean save_copy,
202                                         gboolean retry_send,
203                                         gboolean native,
204                                         gchar *folder_name,
205                                         DBusGMethodInvocation *context);
206 static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
207                                         gchar *bmsg,
208                                         DBusGMethodInvocation *context);
209 static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent,
210                                         DBusGMethodInvocation *context);
211 static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent,
212                                         gchar *handle, gboolean read_status,
213                                         DBusGMethodInvocation *context);
214 static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent,
215                                         gchar *handle, gboolean delete_status,
216                                         DBusGMethodInvocation *context);
217 static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent,
218                                         gchar *remote_addr,
219                                         gboolean status,
220                                         DBusGMethodInvocation *context);
221 static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent,
222                                         DBusGMethodInvocation *context);
223
224 #include "bluetooth_map_agent_glue.h"
225
226 static void bluetooth_map_agent_init(BluetoothMapAgent *obj)
227 {
228         FN_START;
229         g_assert(obj != NULL);
230         FN_END;
231 }
232
233 static void bluetooth_map_agent_finalize(GObject *obj)
234 {
235         FN_START;
236         G_OBJECT_CLASS(bluetooth_map_agent_parent_class)->finalize(obj);
237         FN_END;
238 }
239
240 static void bluetooth_map_agent_class_init(BluetoothMapAgentClass *klass)
241 {
242         FN_START;
243         GObjectClass *object_class = (GObjectClass *) klass;
244
245         g_assert(klass != NULL);
246
247         object_class->finalize = bluetooth_map_agent_finalize;
248
249         dbus_g_object_type_install_info(BLUETOOTH_MAP_TYPE_AGENT,
250                                         &dbus_glib_bluetooth_map_object_info);
251         FN_END;
252 }
253
254 static GQuark __bt_map_agent_error_quark(void)
255 {
256         FN_START;
257         static GQuark quark = 0;
258         if (!quark)
259                 quark = g_quark_from_static_string("agent");
260
261         FN_END;
262         return quark;
263 }
264
265 static GError *__bt_map_agent_error(bt_map_agent_error_t error,
266                                      const char *err_msg)
267 {
268         FN_START;
269         return g_error_new(BT_MAP_AGENT_ERROR, error, err_msg, NULL);
270 }
271
272 static void __bt_mns_client_event_notify(gchar *event, guint64 handle,
273                                         gchar *folder, gchar *old_folder,
274                                         gchar *msg_type);
275
276 static char *__bt_get_truncated_utf8_string(char *src)
277 {
278         FN_START;
279         char *p = src;
280         char *next;
281         char dest[BT_MAP_SUBJECT_MAX_LEN] = {0,};
282         int count;
283         int i = 0;
284
285         if (src == NULL)
286                 return FALSE;
287
288         while (*p != '\0' && i < sizeof(dest)) {
289                 next = g_utf8_next_char(p);
290                 count = next - p;
291
292                 while (count > 0 && ((i + count) < sizeof(dest))) {
293                         dest[i++] = *p;
294                         p++;
295                         count --;
296                 }
297                 p = next;
298         }
299
300         FN_END;
301         return g_strdup(dest);
302 }
303
304 static guint64 __bt_validate_uid(int uid)
305 {
306         FN_START;
307         struct id_info *info;
308         int count;
309         int i;
310
311         count = g_slist_length(id_list);
312         for (i = 0; i < count; i++) {
313                 info = (struct id_info *)g_slist_nth_data(id_list, i);
314                 if (!info)
315                         break;
316
317                 if (info->uid == uid) {
318                         DBG("uid = %d\n", uid);
319                         return info->map_id;
320                 }
321         }
322
323         FN_END;
324         return 0;
325 }
326
327 static guint64 __bt_add_id(int uid)
328 {
329         FN_START;
330         static guint64 map_id;
331         struct id_info *info;
332         guint64 test;
333
334         DBG("Add id: %d\n", uid);
335         test = __bt_validate_uid(uid);
336         DBG("test: %llx\n", test);
337         if (test)
338                 return test;
339
340         info = g_new0(struct id_info, 1);
341
342         map_id++;
343
344         info->map_id = map_id;
345         info->uid = uid;
346         DBG("map_id = %llx, uid = %d \n", info->map_id, info->uid);
347
348         id_list = g_slist_append(id_list, info);
349
350         FN_END;
351         return map_id;
352 }
353
354 static int __bt_get_id(guint64 map_id)
355 {
356         FN_START;
357         struct id_info *info;
358         int count;
359         int i;
360
361         count = g_slist_length(id_list);
362
363         for (i = 0; i < count; i++) {
364                 info = (struct id_info *)g_slist_nth_data(id_list, i);
365
366                 if (info->map_id == map_id)
367                         return info->uid;
368         }
369
370         FN_END;
371         return -1;
372 }
373
374 static int __bt_get_uid(gchar *handle)
375 {
376         FN_START;
377         guint64 map_id;
378         int uid;
379
380         if (NULL == handle)
381                 return -1;
382
383         map_id = g_ascii_strtoull(handle, NULL, 16);
384         if (!map_id)
385                 return -1;
386
387         uid = __bt_get_id(map_id);
388
389         FN_END;
390         return uid;
391 }
392
393 static int __bt_update_id(guint64 map_id, int new_uid)
394 {
395         FN_START;
396         struct id_info *info;
397         int i;
398         int count;
399
400         count = g_slist_length(id_list);
401
402         for (i = 0; i < count; i++) {
403                 info = g_slist_nth_data(id_list, i);
404
405                 if (info->map_id == map_id) {
406                         info->uid = new_uid;
407                         return map_id;
408                 }
409         }
410
411         FN_END;
412         return -1;
413 }
414
415 static void __bt_remove_list(GSList *id_list)
416 {
417         FN_START;
418         if (!id_list)
419                 return;
420
421         DBG("Removing id list\n");
422         g_slist_free_full(id_list, g_free);
423         FN_END;
424 }
425
426 static int __bt_get_folder_id(char *folder_path)
427 {
428         FN_START;
429         int folder_id = -1;
430         int i;
431         char *folder;
432         msg_struct_list_s folder_list = {0,};
433         msg_error_t err;
434         msg_struct_t p_folder;
435         DBG_SECURE("folder_path %s\n", folder_path);
436
437         folder = strrchr(folder_path, '/');
438         if (NULL == folder)
439                 folder = folder_path;
440         else
441                 folder++;
442
443         err = msg_get_folder_list(g_msg_handle, &folder_list);
444         if (err != MSG_SUCCESS)
445                 goto done;
446
447         for (i = 0; i < folder_list.nCount; i++) {
448                 char folder_name[BT_MAP_MSG_INFO_MAX] = {0, };
449
450                 p_folder = folder_list.msg_struct_info[i];
451
452                 err = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
453                                         folder_name, BT_MAP_MSG_INFO_MAX);
454                 if (err != MSG_SUCCESS)
455                         continue;
456
457                 DBG_SECURE("folder_name %s\n", folder_name);
458                 if (!g_ascii_strncasecmp(folder_name, folder, strlen(folder))) {
459                         err = msg_get_int_value(p_folder,
460                                         MSG_FOLDER_INFO_ID_INT,
461                                         &folder_id);
462                         if (err != MSG_SUCCESS)
463                                 goto done;
464
465                         DBG("folder_id %d", folder_id);
466                         break;
467                 }
468         }
469
470 done:
471         if (folder_list.msg_struct_info)
472                 msg_release_list_struct(&folder_list);
473
474         FN_END;
475         return folder_id;
476
477 }
478
479 static void __bt_add_deleted_folder(void)
480 {
481         FN_START;
482         msg_error_t err;
483         msg_struct_t folder_info = msg_create_struct(MSG_STRUCT_FOLDER_INFO);
484
485         err = msg_set_int_value(folder_info, MSG_FOLDER_INFO_TYPE_INT,
486                                                 MSG_FOLDER_TYPE_USER_DEF);
487         if (err != MSG_SUCCESS) {
488                 ERR("Failed adding type %d", err);
489                 msg_release_struct(&folder_info);
490                 return;
491         }
492
493         err = msg_set_str_value(folder_info, MSG_FOLDER_INFO_NAME_STR,
494                                         "DELETED", MAX_FOLDER_NAME_SIZE);
495         if (err != MSG_SUCCESS) {
496                 ERR("Failed adding str %d", err);
497                 msg_release_struct(&folder_info);
498                 return;
499         }
500
501         err = msg_add_folder(g_msg_handle, folder_info);
502         if (err != MSG_SUCCESS) {
503                 ERR("Failed adding folder %d", err);
504                 msg_release_struct(&folder_info);
505                 return;
506         }
507
508         msg_release_struct(&folder_info);
509         FN_END;
510 }
511
512 static gchar *__bt_get_folder_name(int id)
513 {
514         FN_START;
515         int ret;
516         int i;
517         int folder_id;
518         gboolean path_found = FALSE;
519         char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
520
521         msg_struct_list_s folder_list = {0,};
522         msg_struct_t p_folder;
523
524         ret = msg_get_folder_list(g_msg_handle, &folder_list);
525         if (ret != MSG_SUCCESS)
526                 return g_strdup("TELECOM/MSG");
527
528         if (folder_list.msg_struct_info == NULL)
529                 return g_strdup("TELECOM/MSG");
530
531         for (i = 0; i < folder_list.nCount; i++) {
532                 p_folder = folder_list.msg_struct_info[i];
533
534                 ret = msg_get_int_value(p_folder,
535                                         MSG_FOLDER_INFO_ID_INT,
536                                         &folder_id);
537                 if (ret != MSG_SUCCESS)
538                         break;
539                 DBG("folder_id %d, id = %d", folder_id, id);
540                 if (folder_id == id) {
541                         ret = msg_get_str_value(p_folder,
542                                         MSG_FOLDER_INFO_NAME_STR,
543                                         folder_name, BT_MAP_MSG_INFO_MAX);
544                         if (ret != MSG_SUCCESS)
545                                 break;
546
547                         path_found = TRUE;
548                         DBG_SECURE("folder_name %s", folder_name);
549                         break;
550                 }
551         }
552
553         if (folder_list.msg_struct_info) {
554                 ret = msg_release_list_struct(&folder_list);
555                 ERR("Err %d", ret);
556         }
557
558         FN_END;
559         if (path_found != TRUE)
560                 return g_strdup("TELECOM/MSG");
561         else
562                 return g_strdup_printf("TELECOM/MSG/%s", folder_name);
563 }
564
565 static void __get_msg_timestamp(time_t *ltime, char *timestamp)
566 {
567         FN_START;
568         struct tm local_time;
569         int year;
570         int month;
571
572         if (!localtime_r(ltime, &local_time))
573                 return;
574
575         year = local_time.tm_year + 1900; /* years since 1900 */
576         month = local_time.tm_mon + 1; /* months since January */
577         snprintf(timestamp, 16, "%04d%02d%02dT%02d%02d%02d", year, month,
578                                         local_time.tm_mday, local_time.tm_hour,
579                                         local_time.tm_min, local_time.tm_sec);
580
581         FN_END;
582         return;
583 }
584
585 #define SET_TON_NPI(dest, ton, npi) {   \
586         dest = 0x80;                    \
587         dest |= (ton & 0x07) << 4;      \
588         dest |= npi & 0x0F;             \
589 }
590
591 static int __bt_ascii_to_upper(int ch)
592 {
593         return (('a' <= (ch) && (ch) <= 'z') ? ((ch) - ('a'-'A')) : (ch));
594 }
595
596 static int __bt_sms_pack_gsm_code(gchar *p_out, const char *data, int in_len)
597 {
598         FN_START;
599         int i;
600         int pos;
601         int shift = 0;
602
603         for (pos = 0, i = 0; i < in_len; pos++, i++) {
604                 /* pack the low bits */
605                 p_out[pos] = data[i] >> shift;
606
607                 if (i + 1 < in_len) {
608                         /* pack the high bits using the low bits
609                            of the next character */
610                         p_out[pos] |= data[i+1] << (7 - shift);
611
612                         shift++;
613
614                         if (shift == 7) {
615                                 shift = 0;
616                                 i++;
617                         }
618                 }
619         }
620
621         FN_END;
622         return pos;
623 }
624
625 static void __bt_sms_conv_digit_to_bcd(gchar *p_bcd, char *p_digits, int digit_len)
626 {
627         FN_START;
628         int i;
629         int j;
630         int digit;
631         unsigned char higher;
632         unsigned char lower;
633
634         if (p_bcd == NULL || p_digits == NULL)
635                 return;
636
637         /* 0123456789 -> 1032547698 */
638         for (i = 0, j = 0; i < digit_len; i = i + 2, j++) {
639                 if (p_digits[i] == '*')
640                         digit = 0x0A;
641                 else if (p_digits[i] == '#')
642                         digit = 0x0B;
643                 else if (__bt_ascii_to_upper(p_digits[i]) == 'P')
644                         digit = 0x0C;
645                 else
646                         digit = (int) (p_digits[i] - '0');
647
648                 lower = digit & 0x0F;
649
650                 if (digit_len != i + 1) {
651                         if (p_digits[i+1] == '*')
652                                 digit = 0x0A;
653                         else if (p_digits[i+1] == '#')
654                                 digit = 0x0B;
655                         else if (__bt_ascii_to_upper(p_digits[i+1]) == 'P')
656                                 digit = 0x0C;
657                         else
658                                 digit = (int) (p_digits[i+1] - '0');
659
660                         higher = digit & 0x0F;
661                 } else {
662                         higher = 0xFF;
663                 }
664
665                 p_bcd[j] = (higher << 4) | lower;
666         }
667         FN_END;
668 }
669
670 static int  __bt_sms_encode_addr(gchar *addr_field, char *dial_num,
671                                 int dial_num_len, int ton, int npi)
672 {
673         FN_START;
674         int index = 0;
675
676         if (dial_num == NULL || addr_field == NULL)
677                 return -1;
678
679         if (dial_num[0] == '+') {
680                 dial_num++;
681                 dial_num_len--;
682                 ton = SMS_TON_INTERNATIONAL;
683         }
684
685         if (ton != SMS_TON_ALPHA_NUMERIC) {
686                 /* Origination address length address length */
687                 addr_field[index++] = (unsigned char)dial_num_len;
688         } else {
689                 addr_field[index] = (unsigned char)
690                                         (((dial_num_len * 7 + 7) / 8) * 2);
691
692                 if (((dial_num_len * 7) % 8) <= 4)
693                         addr_field[index]--;
694
695                 index++;
696         }
697
698         SET_TON_NPI(addr_field[index], ton, npi);
699         index++; /* SET_TON_NPI */
700
701         if (ton != SMS_TON_ALPHA_NUMERIC) {
702                 __bt_sms_conv_digit_to_bcd(&addr_field[index],
703                                         (char *)dial_num, dial_num_len);
704
705                 if (dial_num_len % 2)
706                         index += (dial_num_len / 2) + 1;
707                 else
708                         index += dial_num_len / 2;
709         } else {
710                 index += __bt_sms_pack_gsm_code(&addr_field[index],
711                                                 dial_num, (int)dial_num_len);
712         }
713
714         FN_END;
715         return index;
716 }
717
718 static int __bt_sms_encode_time(gchar *addr_field, time_t *tm)
719 {
720         FN_START;
721         int index = 0;
722         struct tm ltime;
723         int year;
724         int month;
725
726         if (!localtime_r(tm, &ltime))
727                 return index;
728
729         year = ltime.tm_year + 1900; /* years since 1900 */
730         year = year % 100;
731         month = ltime.tm_mon + 1; /* months since January */
732
733         addr_field[index++] = ((year % 10)  << 4) + (year / 10);
734         addr_field[index++] = ((month % 10) << 4) + (month / 10);
735         addr_field[index++] = ((ltime.tm_mday % 10) << 4) +
736                                                         (ltime.tm_mday / 10);
737         addr_field[index++] = ((ltime.tm_hour % 10) << 4) +
738                                                         (ltime.tm_hour / 10);
739         addr_field[index++] = ((ltime.tm_min % 10) << 4) + (ltime.tm_min / 10);
740         addr_field[index++] = ((ltime.tm_sec % 10) << 4) + (ltime.tm_sec / 10);
741         addr_field[index] = 0x00;
742
743         FN_END;
744         return index;
745 }
746
747 static gchar *__bt_get_sms_pdu_from_msg_data(gchar *number,
748                                                 char *msg, time_t tm,
749                                                 int *msg_pdu_len)
750 {
751         FN_START;
752         gchar packet[TAPI_NETTEXT_MSG_SIZE_MAX] = {0,};
753         int index = 0;
754
755         packet[index] = 0x00; /* Since SCA is unknown for stored messages */
756         index++;
757
758         /* TP-MTI : Type of message */
759         packet[index] = 0x00;   /* SMS-DELIVER PDU */
760
761         /* TP-MMS bit is set to 1 as we support only SMS */
762         packet[index] |= 0x04;
763         index++;
764
765         /* TP-OA : Mobile originating address */
766         index += __bt_sms_encode_addr(packet+index,
767                                         number, strlen(number),
768                                         g_sca_info->Ton, g_sca_info->Npi);
769
770         /* TP-PID : Since we use only SMS so set to 0 */
771         packet[index++] = 0x00;
772
773         /* TP-DCS : Data Coding Scheme, default value set */
774         packet[index++] = 0x00;
775
776         /* TP-SCTS : Message timestamp */
777         index += __bt_sms_encode_time(packet+index, &tm);
778         index++;
779         /* TP-UDL : Message body length */
780         packet[index++] = strlen(msg);
781
782         /* TP-UD : Message body */
783         index += __bt_sms_pack_gsm_code(packet + index, msg, strlen(msg));
784
785         *msg_pdu_len = index;
786
787         FN_END;
788         return g_memdup(packet, index);
789 }
790
791 static void __bt_get_sms_sca(TapiHandle *handle, int result, void *data,
792                                                         void *user_data)
793 {
794         FN_START;
795         TelSmsAddressInfo_t *scaInfo = data;
796
797         DBG("__bt_get_sms_sca 0x%x", result);
798
799         if (data == NULL) {
800                 g_sca_info = g_malloc0(sizeof(TelSmsAddressInfo_t));
801                 g_sca_info->Ton = 0;
802                 g_sca_info->Npi = 0;
803                 g_sca_info->DialNumLen = 0;
804                 return;
805         }
806
807         g_sca_info = g_malloc0(sizeof(TelSmsAddressInfo_t));
808         g_sca_info->Ton = scaInfo->Ton;
809         g_sca_info->Npi = scaInfo->Npi;
810         g_sca_info->DialNumLen = scaInfo->DialNumLen;
811         FN_END;
812 }
813
814 static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach,
815                                                         gboolean transcode)
816 {
817         FN_START;
818         int ret;
819         int m_type = MSG_TYPE_SMS;
820         int folder_id;
821         int count;
822         int dptime = 0;
823         int j;
824         bool read_status = false;
825         char msg_body[BT_MAP_MSG_BODY_MAX] = {0,};
826         char addr_value[MAX_ADDRESS_VAL_LEN] = {0,};
827         char name_value[MAX_DISPLAY_NAME_LEN] = {0,};
828
829         msg_list_handle_t addr_list = NULL;
830         msg_struct_t addr_info = NULL;
831
832         GString *msg;
833         gchar *folder_path = NULL;
834         gchar *msg_pdu;
835
836         msg = g_string_new(BEGIN_BMSEG);
837         g_string_append(msg, BMSEG_VERSION);
838
839         ret = msg_get_bool_value(msg_info, MSG_MESSAGE_READ_BOOL, &read_status);
840         if (ret == MSG_SUCCESS) {
841                 INFO("read_status %d\n", read_status);
842         }
843
844         if (read_status)
845                 g_string_append_printf(msg, MSEG_STATUS, "READ");
846         else
847                 g_string_append_printf(msg, MSEG_STATUS, "UNREAD");
848
849         ret = msg_get_int_value(msg_info, MSG_MESSAGE_TYPE_INT, &m_type);
850         if (ret == MSG_SUCCESS) {
851                 INFO("m_type %d\n", m_type);
852                  g_string_append_printf(msg, MSEG_TYPE, "SMS_GSM");
853         }
854
855         ret = msg_get_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
856                                                         &folder_id);
857         if (ret == MSG_SUCCESS) {
858                 DBG("folder_id %d\n", folder_id);
859
860                 folder_path = __bt_get_folder_name(folder_id);
861                 g_string_append_printf(msg, FOLDER_PATH, folder_path);
862         }
863
864         ret = msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_HND,
865                                                 (void **)&addr_list);
866         if (ret == MSG_SUCCESS) {
867                 count = msg_list_length(addr_list);
868                 DBG("count %d \n", count);
869
870                 if (count > 0) {
871                         addr_info = (msg_struct_t)msg_list_nth_data(addr_list,
872                                                                         0);
873
874                         msg_get_str_value(addr_info,
875                                         MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
876                                         addr_value, MAX_ADDRESS_VAL_LEN);
877                         DBG_SECURE("addr_value %s\n", addr_value);
878                         msg_get_str_value(addr_info,
879                                         MSG_ADDRESS_INFO_DISPLAYNAME_STR,
880                                         name_value, MAX_DISPLAY_NAME_LEN);
881                         if (!strlen(name_value))
882                                 g_stpcpy(name_value, addr_value);
883
884                         DBG_SECURE("name_value %s\n", name_value);
885
886                         g_string_append_printf(msg, VCARD, name_value,
887                                                                 addr_value);
888                 }
889         }
890
891         g_string_append(msg, BEGIN_BENV);
892         g_string_append(msg, BEGIN_BBODY);
893
894         if (transcode) {
895                 g_string_append_printf(msg, CHARSET, "UTF-8");
896
897
898                 ret = msg_get_str_value(msg_info,
899                                         MSG_MESSAGE_SMS_DATA_STR,
900                                         msg_body, BT_MAP_MSG_BODY_MAX);
901                 if (ret == MSG_SUCCESS) {
902                         g_string_append_printf(msg, LENGTH, (int)strlen(msg_body));
903                         g_string_append_printf(msg, MSG_BODY, msg_body);
904                 }
905         } else {
906                 g_string_append_printf(msg, ENCODING, "G-7BIT");
907                 g_string_append_printf(msg, CHARSET, "native");
908
909                 msg_get_int_value(msg_info,
910                                 MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
911
912                 ret = msg_get_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR,
913                                         msg_body, BT_MAP_MSG_BODY_MAX);
914                 if (ret == MSG_SUCCESS) {
915                         int msg_pdu_len = 0;
916                         msg_pdu = __bt_get_sms_pdu_from_msg_data(addr_value,
917                                                         msg_body, dptime,
918                                                         &msg_pdu_len);
919                         if (msg_pdu) {
920                                 DBG("msg_pdu_len = %d", msg_pdu_len);
921
922                                 g_string_append_printf(msg, LENGTH, msg_pdu_len);
923                                 g_string_append(msg, MSG_BODY_BEGIN);
924                                 for (j = 0; j < msg_pdu_len; j++)
925                                         g_string_append_printf(msg, "%02x",
926                                                                         msg_pdu[j]);
927
928                                 g_string_append(msg, MSG_BODY_END);
929                                 g_free(msg_pdu);
930                         }
931                 }
932         }
933
934         g_string_append(msg, END_BBODY);
935         g_string_append(msg, END_BENV);
936         g_string_append(msg, END_BMSEG);
937         g_free(folder_path);
938
939         FN_END;
940         return g_string_free(msg, FALSE);
941 }
942
943 static void __bt_message_info_free(struct message_info msg_info)
944 {
945         FN_START;
946         g_free(msg_info.handle);
947         g_free(msg_info.subject);
948         g_free(msg_info.datetime);
949         g_free(msg_info.sender_name);
950         g_free(msg_info.sender_addressing);
951         g_free(msg_info.replyto_addressing);
952         g_free(msg_info.recipient_name);
953         g_free(msg_info.recipient_addressing);
954         g_free(msg_info.type);
955         g_free(msg_info.reception_status);
956         g_free(msg_info.size);
957         g_free(msg_info.attachment_size);
958         FN_END;
959 }
960
961 static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle)
962 {
963         FN_START;
964         struct message_info msg_info = {0,};
965         int ret;
966         int msg_id;
967         guint64 uid;
968         int dptime;
969         int m_type = 0;
970         int data_size;
971         int priority;
972         int direction_type;
973         int count;
974         bool protect_status = 0;
975         bool read_status = 0;
976
977         char msg_handle[BT_MAP_MSG_HANDLE_MAX] = {0,};
978         char msg_datetime[BT_MAP_TIMESTAMP_MAX_LEN] = {0,};
979         char msg_size[5] = {0,};
980         char msg_body[BT_MAP_MSG_BODY_MAX] = {0,};
981         char addr_value[MAX_ADDRESS_VAL_LEN] = {0,};
982         char name_value[MAX_DISPLAY_NAME_LEN] = {0,};
983
984         msg_info.text = FALSE;
985         msg_info.protect = FALSE;
986         msg_info.read = FALSE;
987         msg_info.priority = FALSE;
988
989         msg_struct_t msg = NULL;
990         msg_struct_t send_opt = NULL;
991         msg_list_handle_t addr_list = NULL;
992         msg_struct_t addr_info = NULL;
993
994         ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_ID_INT, &msg_id);
995         if (ret == MSG_SUCCESS) {
996                 uid = __bt_add_id(msg_id);
997                 snprintf(msg_handle, sizeof(msg_handle), "%llx", (long long unsigned int)uid);
998         }
999         msg_info.handle = g_strdup(msg_handle);
1000
1001         msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
1002         if (msg == NULL)
1003                 goto next;
1004
1005         send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
1006         if (send_opt == NULL)
1007                 goto next;
1008
1009         ret = msg_get_message(g_msg_handle,
1010                                                 (msg_message_id_t)msg_id,
1011                                                 msg, send_opt);
1012         if (ret != MSG_SUCCESS) {
1013                 DBG("ret = %d\n", ret);
1014                 goto next;
1015         }
1016
1017         ret = msg_get_list_handle(msg, MSG_MESSAGE_ADDR_LIST_HND,
1018                                                         (void **)&addr_list);
1019         if (ret != MSG_SUCCESS) {
1020                 DBG("ret = %d\n", ret);
1021                 goto next;
1022         }
1023
1024         count = msg_list_length(addr_list);
1025
1026         if (count != 0) {
1027                 addr_info = (msg_struct_t)msg_list_nth_data(addr_list, 0);
1028
1029                 ret = msg_get_str_value(addr_info,
1030                                         MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
1031                                         addr_value, MAX_ADDRESS_VAL_LEN);
1032                 if (ret == MSG_SUCCESS)
1033                         DBG_SECURE("addr_value %s\n", addr_value);
1034
1035                 ret = msg_get_str_value(addr_info,
1036                                         MSG_ADDRESS_INFO_DISPLAYNAME_STR,
1037                                         name_value, MAX_DISPLAY_NAME_LEN);
1038
1039                 if (ret == MSG_SUCCESS)
1040                         DBG_SECURE("name_value %s\n", name_value);
1041
1042                 if (!strlen(name_value))
1043                         g_stpcpy(name_value, addr_value);
1044
1045                 DBG_SECURE("name_value %s\n", name_value);
1046         }
1047
1048         ret = msg_get_int_value(msg, MSG_MESSAGE_DIRECTION_INT,
1049                                                 &direction_type);
1050         if (ret != MSG_SUCCESS)
1051                 goto next;
1052
1053         if (direction_type == MSG_DIRECTION_TYPE_MT) {
1054                 msg_info.sender_name = g_strdup(name_value);
1055                 msg_info.sender_addressing = g_strdup(addr_value);
1056                 msg_info.recipient_name = g_strdup("Unknown");
1057                 msg_info.recipient_addressing = g_strdup("0000");
1058         } else {
1059                 msg_info.sender_name = g_strdup("Unknown");
1060                 msg_info.sender_addressing = g_strdup("0000");
1061                 msg_info.recipient_name = g_strdup(name_value);
1062                 msg_info.recipient_addressing = g_strdup(addr_value);
1063         }
1064
1065 next:
1066         msg_release_struct(&msg);
1067         msg_release_struct(&send_opt);
1068
1069         ret = msg_get_int_value(msg_struct_handle,
1070                                 MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
1071         if (ret == MSG_SUCCESS) {
1072                 __get_msg_timestamp((time_t *)&dptime, msg_datetime);
1073         }
1074         msg_info.datetime = g_strdup(msg_datetime);
1075
1076         ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_TYPE_INT,
1077                                                                 &m_type);
1078         if (ret == MSG_SUCCESS) {
1079                 DBG("m_type %d\n", m_type);
1080         }
1081
1082         msg_info.type = g_strdup("SMS_GSM");
1083
1084         ret = msg_get_str_value(msg_struct_handle,
1085                                 MSG_MESSAGE_SMS_DATA_STR, msg_body,
1086                                 BT_MAP_MSG_BODY_MAX);
1087         if (ret == MSG_SUCCESS) {
1088                 DBG_SECURE("SMS subject %s", msg_body);
1089                 if (strlen(msg_body)) {
1090                         msg_info.text = TRUE ;
1091                         msg_info.subject = __bt_get_truncated_utf8_string(msg_body);
1092                 }
1093         }
1094
1095         ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_DATA_SIZE_INT,
1096                                                                 &data_size);
1097         if (ret == MSG_SUCCESS)
1098                 snprintf(msg_size, sizeof(msg_size), "%d", data_size);
1099
1100         msg_info.size = g_strdup(msg_size);
1101
1102         msg_info.reception_status = g_strdup("complete");
1103         msg_info.attachment_size = g_strdup("0");
1104
1105         ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_PROTECTED_BOOL,
1106                                                         &protect_status);
1107         if (ret == MSG_SUCCESS) {
1108                 if (protect_status)
1109                         msg_info.protect = TRUE;
1110         }
1111
1112         ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_READ_BOOL,
1113                                                                 &read_status);
1114         if (ret == MSG_SUCCESS) {
1115                 if (read_status)
1116                         msg_info.read = TRUE;
1117         }
1118
1119         ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_PRIORITY_INT,
1120                                                                 &priority);
1121         if (ret == MSG_SUCCESS) {
1122                 if (priority == MSG_MESSAGE_PRIORITY_HIGH)
1123                         msg_info.priority = TRUE;
1124         }
1125
1126         FN_END;
1127         return msg_info;
1128 }
1129
1130 static void __bluetooth_map_msg_incoming_status_cb(msg_handle_t handle,
1131                                                         msg_struct_t msg,
1132                                                         void *user_param)
1133 {
1134         FN_START;
1135         int msg_id = 0;
1136         int msg_type = 0;
1137         int ret;
1138
1139         guint64 uid;
1140
1141         if (!g_mns_proxy) {
1142                 INFO("MNS Client not connected");
1143                 return;
1144         }
1145
1146         ret = msg_get_int_value(msg, MSG_MESSAGE_TYPE_INT, &msg_type);
1147         if (ret != MSG_SUCCESS)
1148                 return;
1149
1150         if (msg_type != MSG_TYPE_SMS) {
1151                 INFO("Not a SMS");
1152                 return;
1153         }
1154
1155         ret = msg_get_int_value(msg, MSG_MESSAGE_ID_INT, &msg_id);
1156         if (ret != MSG_SUCCESS)
1157                 return;;
1158
1159         uid = __bt_add_id(msg_id);
1160
1161         __bt_mns_client_event_notify("NewMessage", uid,
1162                                                 "TELECOM/MSG/INBOX", "",
1163                                                 "SMS_GSM");
1164
1165         FN_END;
1166         return;
1167 }
1168
1169 static void __bluetooth_map_msg_sent_status_cb(msg_handle_t handle,
1170                                                         msg_struct_t msg,
1171                                                         void *user_param)
1172 {
1173         FN_START;
1174         int ret;
1175         int status;
1176
1177         if (!g_mns_proxy) {
1178                 INFO("MNS Client not connected");
1179                 return;
1180         }
1181
1182         ret = msg_get_int_value(msg, MSG_SENT_STATUS_NETWORK_STATUS_INT,
1183                                                                 &status);
1184         if (ret != MSG_SUCCESS)
1185                 return;
1186
1187         if (status == MSG_NETWORK_SEND_SUCCESS) {
1188                 INFO("MSG SENT SUCCESS !!! ");
1189                 __bt_mns_client_event_notify("MessageShift",
1190                                         current_push_map_id,
1191                                         "TELECOM/MSG/SENT",
1192                                         "TELECOM/MSG/OUTBOX",
1193                                         "SMS_GSM");
1194
1195                 __bt_mns_client_event_notify("SendingSuccess",
1196                                         current_push_map_id,
1197                                         "TELECOM/MSG/SENT", "",
1198                                         "SMS_GSM");
1199         } else {
1200                 ERR("MSG SENT FAIL !!! [%d]", status);
1201                 __bt_mns_client_event_notify("SendingFailure",
1202                                         current_push_map_id,
1203                                         "TELECOM/MSG/OUTBOX", "",
1204                                         "SMS_GSM");
1205         }
1206
1207         FN_END;
1208         return;
1209 }
1210
1211 static gboolean __bluetooth_map_start_service()
1212 {
1213         FN_START;
1214         msg_error_t err;
1215
1216         err = msg_open_msg_handle(&g_msg_handle);
1217         if (err != MSG_SUCCESS) {
1218                 ERR("msg_open_msg_handle error = %d\n", err);
1219                 return FALSE;
1220         }
1221
1222         if (-1 == __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME))
1223                 __bt_add_deleted_folder();
1224
1225         err = msg_reg_sms_message_callback(g_msg_handle,
1226                                         __bluetooth_map_msg_incoming_status_cb,
1227                                         0, (void *)BT_MAP_MSG_CB);
1228         if (err != MSG_SUCCESS) {
1229                 ERR("msg_reg_sms_message_callback error  = %d\n", err);
1230                 return FALSE;
1231         }
1232
1233         err = msg_reg_sent_status_callback(g_msg_handle,
1234                                         __bluetooth_map_msg_sent_status_cb,
1235                                         NULL);
1236         if (err != MSG_SUCCESS) {
1237                 ERR("msg_reg_sent_status_callback error  = %d\n", err);
1238                 return FALSE;
1239         }
1240
1241         FN_END;
1242         return TRUE;
1243 }
1244
1245 static void __bluetooth_map_stop_service()
1246 {
1247         FN_START;
1248         msg_error_t err =  MSG_SUCCESS;
1249         int folder_id;
1250
1251         folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME);
1252         if (-1 != folder_id) {
1253                 err = msg_delete_folder(g_msg_handle, folder_id);
1254                 if (err != MSG_SUCCESS)
1255                         ERR("Delete folder failed");
1256         }
1257
1258         if (NULL != g_msg_handle)
1259                 msg_close_msg_handle(&g_msg_handle);
1260
1261         g_msg_handle = NULL;
1262
1263         FN_END;
1264         return;
1265 }
1266
1267 static gboolean __bt_validate_utf8(char **text)
1268 {
1269         FN_START;
1270         if (g_utf8_validate(*text, -1, NULL))
1271                 return TRUE;
1272
1273         FN_END;
1274         return FALSE;
1275 }
1276
1277 static gboolean __bt_validate_msg_data(struct message_info *msg_info)
1278 {
1279         FN_START;
1280         if (msg_info == NULL)
1281                 return FALSE;
1282
1283         if (msg_info->subject)
1284                 return __bt_validate_utf8(&msg_info->subject);
1285
1286         if (msg_info->sender_name)
1287                 return __bt_validate_utf8(&msg_info->sender_name);
1288
1289         if (msg_info->sender_addressing)
1290                 return __bt_validate_utf8(&msg_info->sender_addressing);
1291
1292         if (msg_info->replyto_addressing)
1293                 return __bt_validate_utf8(&msg_info->replyto_addressing);
1294
1295         if (msg_info->recipient_name)
1296                 return __bt_validate_utf8(&msg_info->recipient_name);
1297
1298         if (msg_info->recipient_addressing)
1299                 return __bt_validate_utf8(&msg_info->recipient_addressing);
1300
1301         FN_END;
1302         return TRUE;
1303 }
1304
1305 msg_error_t __bt_send_sms(int msg_id, msg_struct_t p_msg, msg_struct_t p_send_opt)
1306 {
1307         FN_START;
1308         msg_error_t err;
1309         msg_struct_t p_req;
1310
1311         p_req = msg_create_struct(MSG_STRUCT_REQUEST_INFO);
1312
1313         msg_set_int_value(p_msg, MSG_MESSAGE_ID_INT, msg_id);
1314         msg_set_struct_handle(p_req, MSG_REQUEST_MESSAGE_HND, p_msg);
1315         msg_set_struct_handle(p_req, MSG_REQUEST_SENDOPT_HND, p_send_opt);
1316
1317         err = msg_sms_send_message(g_msg_handle, p_req);
1318         if (err != MSG_SUCCESS)
1319                 ERR("Failed msg_sms_send_message %d", err);
1320
1321         msg_release_struct(&p_req);
1322         FN_END;
1323         return err;
1324 }
1325
1326 static int __bt_push_sms(gboolean send, int folder_id, char *body,
1327                                                         GSList *recepients)
1328 {
1329         FN_START;
1330         msg_struct_t msg_info = NULL;
1331         msg_struct_t send_opt = NULL;
1332         msg_error_t err;
1333
1334         int count = 0;
1335         int i = 0;
1336         int msg_id = -1;
1337
1338         msg_info = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
1339         if (msg_info == NULL)
1340                 goto fail;
1341
1342         err = msg_set_int_value(msg_info, MSG_MESSAGE_TYPE_INT, MSG_TYPE_SMS);
1343         if (err != MSG_SUCCESS)
1344                 goto fail;
1345
1346         if (body) {
1347                 err = msg_set_str_value(msg_info,
1348                                         MSG_MESSAGE_SMS_DATA_STR,
1349                                         body, strlen(body));
1350                 if (err != MSG_SUCCESS)
1351                         goto fail;
1352         } else {
1353                 err = msg_set_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR,
1354                                                                 NULL, 0);
1355                 if (err != MSG_SUCCESS)
1356                         goto fail;
1357         }
1358
1359         DBG("folder_id  %d\n", folder_id);
1360         err = msg_set_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
1361                                                                 folder_id);
1362         if (err != MSG_SUCCESS)
1363                 goto fail;
1364
1365         if (recepients) {
1366                 count = g_slist_length(recepients);
1367                 DBG("Count = %d\n", count);
1368
1369                 for (i = 0; i < count; i++) {
1370                         msg_struct_t tmp_addr;
1371                         char *address = (char *)g_slist_nth_data(recepients, i);
1372                         if (address == NULL) {
1373                                 ERR("[ERROR] address is value NULL, skip");
1374                                 continue;
1375                         }
1376                         msg_list_add_item(msg_info,
1377                                 MSG_MESSAGE_ADDR_LIST_HND, &tmp_addr);
1378
1379                         msg_set_int_value(tmp_addr,
1380                                 MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT,
1381                                 MSG_RECIPIENTS_TYPE_TO);
1382
1383                         msg_set_str_value(tmp_addr,
1384                                 MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
1385                                 address, strlen(address));
1386                 }
1387         }
1388
1389         send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
1390
1391         err = msg_set_bool_value(send_opt, MSG_SEND_OPT_SETTING_BOOL, true);
1392         if (err != MSG_SUCCESS)
1393                 goto fail;
1394
1395         /* Do not keep a copy */
1396         err = msg_set_bool_value(send_opt, MSG_SEND_OPT_KEEPCOPY_BOOL,
1397                                                         opt.save_copy);
1398         if (err != MSG_SUCCESS)
1399                 goto fail;
1400
1401         msg_id = msg_add_message(g_msg_handle, msg_info, send_opt);
1402         DBG("msg_id = %d\n", msg_id);
1403
1404         if (send == TRUE)
1405                 __bt_send_sms(msg_id, msg_info, send_opt);
1406
1407
1408 fail:
1409         msg_release_struct(&msg_info);
1410         msg_release_struct(&send_opt);
1411         FN_END;
1412         return msg_id;
1413 }
1414
1415 static void __bt_mns_client_connect(char *address)
1416 {
1417         FN_START;
1418         GHashTable *hash;
1419         GValue *tgt_value;
1420         GError *error = NULL;
1421         const char *session_path = NULL;
1422
1423         if (g_mns_proxy) {
1424                 DBG_SECURE("MNS Client already connected to %s", address);
1425                 return;
1426         }
1427
1428         g_mns_proxy = dbus_g_proxy_new_for_name(g_connection,
1429                                                 OBEX_CLIENT_SERVICE,
1430                                                 OBEX_CLIENT_PATH,
1431                                                 OBEX_CLIENT_INTERFACE);
1432         if (!g_mns_proxy) {
1433                 ERR("Failed to get a proxy for D-Bus\n");
1434                 return;
1435         }
1436
1437         hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1438                                      NULL, (GDestroyNotify)g_free);
1439
1440         tgt_value = g_new0(GValue, 1);
1441         g_value_init(tgt_value, G_TYPE_STRING);
1442         g_value_set_string(tgt_value, "MNS");
1443         g_hash_table_insert(hash, "Target", tgt_value);
1444
1445         dbus_g_proxy_call(g_mns_proxy, "CreateSession", &error,
1446                 G_TYPE_STRING,address,
1447                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
1448                 hash, G_TYPE_INVALID,
1449                 DBUS_TYPE_G_OBJECT_PATH, &session_path,
1450                 G_TYPE_INVALID);
1451         if (error) {
1452                 ERR("Error [%s]", error->message);
1453                 g_error_free(error);
1454                 g_hash_table_destroy(hash);
1455                 g_object_unref(g_mns_proxy);
1456                 g_mns_proxy = NULL;
1457                 return;
1458         }
1459
1460         g_mns_path = g_strdup(session_path);
1461         DBG("g_mns_path = %s\n", g_mns_path);
1462
1463         g_hash_table_destroy(hash);
1464
1465         FN_END;
1466         return;
1467 }
1468
1469 static void __bt_mns_client_disconnect()
1470 {
1471         FN_START;
1472         GError *error = NULL;
1473
1474         if (!g_mns_proxy) {
1475                 ERR("No proxy to disconnect");
1476                 return;
1477         }
1478
1479         dbus_g_proxy_call(g_mns_proxy, "RemoveSession", &error,
1480                 DBUS_TYPE_G_OBJECT_PATH, g_mns_path,
1481                 G_TYPE_INVALID, G_TYPE_INVALID);
1482         if (error) {
1483                 ERR("Error [%s]", error->message);
1484                 g_error_free(error);
1485         }
1486
1487         g_free(g_mns_path);
1488         g_mns_path = NULL;
1489
1490         g_object_unref(g_mns_proxy);
1491         g_mns_proxy = NULL;
1492
1493         FN_END;
1494         return;
1495 }
1496
1497 static void __bt_mns_client_event_notify(gchar *event, guint64 handle,
1498                                         gchar *folder, gchar *old_folder,
1499                                         gchar *msg_type)
1500 {
1501         FN_START;
1502         GError *error = NULL;
1503         DBusGProxy *mns_proxy;
1504
1505         if (!g_mns_proxy) {
1506                 ERR("No client proxy");
1507                 return;
1508         }
1509
1510         mns_proxy = dbus_g_proxy_new_for_name(g_connection,
1511                                                 OBEX_CLIENT_SERVICE,
1512                                                 g_mns_path,
1513                                                 MNS_CLIENT_INTERFACE);
1514         if (mns_proxy == NULL) {
1515                 ERR("Failed to get a proxy for D-Bus\n");
1516                 return;
1517         }
1518
1519         dbus_g_proxy_call(mns_proxy, "SendEvent", &error,
1520                 G_TYPE_STRING, event,
1521                 G_TYPE_UINT64, handle,
1522                 G_TYPE_STRING, folder,
1523                 G_TYPE_STRING, old_folder,
1524                 G_TYPE_STRING, msg_type,
1525                 G_TYPE_INVALID, G_TYPE_INVALID);
1526         if (error) {
1527                 ERR("Error [%s]", error->message);
1528                 g_error_free(error);
1529         }
1530
1531         g_object_unref(mns_proxy);
1532         FN_END;
1533 }
1534
1535 static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
1536                                                 DBusGMethodInvocation *context)
1537 {
1538         FN_START;
1539         GPtrArray *array = g_ptr_array_new();
1540         GValue value;
1541         GError *error = NULL;
1542
1543         char name[BT_MAP_MSG_INFO_MAX] = {0,};
1544         char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
1545         int i;
1546         int ret;
1547         gboolean msg_ret = TRUE;
1548
1549         msg_struct_list_s folder_list = {0,};
1550         msg_struct_t p_folder;
1551
1552         if (g_msg_handle == NULL) {
1553                 msg_ret = FALSE;
1554                 goto done;
1555         }
1556
1557         if (msg_get_folder_list(g_msg_handle, &folder_list) != MSG_SUCCESS) {
1558                 msg_ret = FALSE;
1559                 goto done;
1560         }
1561
1562         for (i = 0; i < folder_list.nCount; i++) {
1563                 p_folder = folder_list.msg_struct_info[i];
1564                 memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX);
1565
1566                 ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
1567                                         folder_name, BT_MAP_MSG_INFO_MAX);
1568                 if (ret != MSG_SUCCESS)
1569                         continue;
1570
1571                 if (g_strstr_len(folder_name, -1, BT_MAP_MSG_TEMPLATE))
1572                         continue;
1573
1574                 if (!g_ascii_strncasecmp(folder_name, BT_MAP_SENT_FOLDER_NAME,
1575                                         strlen(BT_MAP_SENT_FOLDER_NAME))) {
1576                         memset(folder_name, 0, sizeof(folder_name));
1577                         g_strlcpy(folder_name, BT_MAP_SENT_FOLDER_NAME,
1578                                                         sizeof(folder_name));
1579                 }
1580
1581                 g_strlcpy(name, folder_name, sizeof(name));
1582                 memset(&value, 0, sizeof(GValue));
1583                 g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
1584                 g_value_take_boxed(&value, dbus_g_type_specialized_construct(
1585                                         DBUS_STRUCT_STRING_STRING_UINT));
1586                 dbus_g_type_struct_set(&value, 0, name, G_MAXUINT);
1587                 g_ptr_array_add(array, g_value_get_boxed(&value));
1588         }
1589
1590 done:
1591
1592         if (folder_list.msg_struct_info)
1593                 msg_release_list_struct(&folder_list);
1594
1595         if (msg_ret == FALSE) {
1596                 g_ptr_array_free(array, TRUE);
1597
1598                 error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1599                                                 "InternalError");
1600                 dbus_g_method_return_error(context, error);
1601                 g_error_free(error);
1602                 return FALSE;
1603         } else {
1604                 dbus_g_method_return(context, array);
1605                 g_ptr_array_free(array, TRUE);
1606                 FN_END;
1607                 return TRUE;
1608         }
1609 }
1610
1611 static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
1612                                                 gchar *folder_name, guint16 max,
1613                                                 DBusGMethodInvocation *context)
1614 {
1615         FN_START;
1616         GPtrArray *array = g_ptr_array_new();
1617         GValue value;
1618         GError *error = NULL;
1619
1620         char *folder = NULL;
1621         int i = 0;
1622         int ret = 0;
1623         int folder_id = -1;
1624         int folder_len;
1625         bool read;
1626         guint64 count = 0;
1627         gboolean newmsg = FALSE;
1628
1629         msg_struct_list_s folder_list = {0,};
1630         msg_struct_list_s msg_list = {0,};
1631         msg_struct_t list_cond;
1632
1633         if (g_msg_handle == NULL)
1634                 goto fail;
1635
1636         if (!folder_name)
1637                 goto fail;
1638
1639         folder_len = strlen(folder_name);
1640         /* In case of parent folders send empty message listing */
1641         if (!g_ascii_strncasecmp(folder_name, "/", folder_len) ||
1642                 !g_ascii_strncasecmp(folder_name, "/telecom", folder_len) ||
1643                 !g_ascii_strncasecmp(folder_name, "/telecom/msg", folder_len))
1644                 goto done;
1645
1646         folder = strrchr(folder_name, '/');
1647         if (NULL == folder)
1648                 folder = folder_name;
1649         else
1650                 folder++;
1651
1652         ret = msg_get_folder_list(g_msg_handle, &folder_list);
1653         if (ret != MSG_SUCCESS)
1654                 goto fail;
1655
1656         for (i = 0; i < folder_list.nCount; i++) {
1657                 char f_name[BT_MAP_MSG_INFO_MAX] = {0, };
1658                 msg_struct_t p_folder = folder_list.msg_struct_info[i];
1659
1660                 ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
1661                                         f_name, BT_MAP_MSG_INFO_MAX);
1662                 if (ret  != MSG_SUCCESS)
1663                         continue;
1664
1665                 if (!g_ascii_strncasecmp(f_name, folder, strlen(folder))) {
1666                         ret = msg_get_int_value(p_folder, MSG_FOLDER_INFO_ID_INT,
1667                                                                 &folder_id);
1668                         if (ret != MSG_SUCCESS)
1669                                 goto fail;
1670
1671                         DBG("folder_id %d \n", folder_id);
1672
1673                         break;
1674                 }
1675         }
1676
1677         if (folder_id == -1)
1678                 goto fail;
1679
1680         list_cond = msg_create_struct(MSG_STRUCT_MSG_LIST_CONDITION);
1681         ret = msg_set_int_value(list_cond,
1682                                 MSG_LIST_CONDITION_FOLDER_ID_INT,
1683                                 folder_id);
1684         if (ret != MSG_SUCCESS)
1685                 goto fail;
1686
1687         ret = msg_set_int_value(list_cond,
1688                                 MSG_LIST_CONDITION_MSGTYPE_INT, MSG_TYPE_SMS);
1689         if (ret != MSG_SUCCESS)
1690                 goto fail;
1691
1692         ret = msg_get_message_list2(g_msg_handle, list_cond, &msg_list);
1693
1694         msg_release_struct(&list_cond);
1695
1696         if (ret != MSG_SUCCESS)
1697                 goto fail;
1698
1699         count = (guint64)msg_list.nCount;
1700
1701         for (i = 0; i < count; i++) {
1702                 msg_get_bool_value(msg_list.msg_struct_info[i],
1703                                         MSG_MESSAGE_READ_BOOL, &read);
1704                 if (read == false) {
1705                         newmsg = TRUE;
1706                         break;
1707                 }
1708         }
1709
1710         DBG("count = %llx, newmsg = %d, max = %d", count, newmsg, max);
1711
1712         if (max == 0)
1713                 goto done;
1714
1715         for (i = 0; i < msg_list.nCount; i++) {
1716
1717                 struct message_info msg_info;
1718
1719                 memset(&value, 0, sizeof(GValue));
1720                 g_value_init(&value, DBUS_STRUCT_MESSAGE_LIST);
1721                 g_value_take_boxed(&value, dbus_g_type_specialized_construct(
1722                                                 DBUS_STRUCT_MESSAGE_LIST));
1723
1724                 msg_info = __bt_message_info_get(msg_list.msg_struct_info[i]);
1725
1726                 if (!__bt_validate_msg_data(&msg_info)) {
1727                         __bt_message_info_free(msg_info);
1728                         count--;
1729                         continue;
1730                 }
1731
1732                 dbus_g_type_struct_set(&value, 0, msg_info.handle,
1733                                         1, msg_info.subject,
1734                                         2, msg_info.datetime,
1735                                         3, msg_info.sender_name,
1736                                         4, msg_info.sender_addressing,
1737                                         5, msg_info.recipient_name,
1738                                         6, msg_info.recipient_addressing,
1739                                         7, msg_info.type,
1740                                         8, msg_info.size,
1741                                         9, msg_info.reception_status,
1742                                         10, msg_info.text,
1743                                         11, msg_info.attachment_size,
1744                                         12, msg_info.priority,
1745                                         13, msg_info.read,
1746                                         14, msg_info.sent,
1747                                         15, msg_info.protect,
1748                                         16, msg_info.replyto_addressing,
1749                                         G_MAXUINT);
1750                 g_ptr_array_add(array, g_value_get_boxed(&value));
1751
1752                 __bt_message_info_free(msg_info);
1753         }
1754
1755 done:
1756         if (folder_list.msg_struct_info)
1757                 ret = msg_release_list_struct(&folder_list);
1758
1759         if (msg_list.msg_struct_info)
1760                 ret = msg_release_list_struct(&msg_list);
1761
1762         dbus_g_method_return(context, newmsg, count, array);
1763         g_ptr_array_free(array, TRUE);
1764         FN_END;
1765         return TRUE;
1766
1767 fail:
1768         if (folder_list.msg_struct_info)
1769                 ret = msg_release_list_struct(&folder_list);
1770
1771         if (msg_list.msg_struct_info)
1772                 ret = msg_release_list_struct(&msg_list);
1773
1774         g_ptr_array_free(array, TRUE);
1775         error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1776                                                           "InternalError");
1777         dbus_g_method_return_error(context, error);
1778         g_error_free(error);
1779         ERR("fail -");
1780         return FALSE;
1781 }
1782
1783 static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent,
1784                                                 gchar *message_name,
1785                                                 gboolean attach,
1786                                                 gboolean transcode,
1787                                                 gboolean first_request,
1788                                                 DBusGMethodInvocation *context)
1789 {
1790         FN_START;
1791         char *buf = NULL;
1792         int message_id = 0;
1793
1794         GError *error = NULL;
1795
1796         msg_error_t msg_err;
1797         msg_struct_t msg = NULL;
1798         msg_struct_t send_opt = NULL;
1799
1800         message_id = __bt_get_uid(message_name);
1801         if (message_id == -1)
1802                 goto fail;
1803
1804         DBG("message_id %d \n", message_id);
1805         DBG("attach %d \n", attach);
1806         DBG("transcode %d \n", transcode);
1807         DBG("first_request %d \n", first_request);
1808
1809         if (g_msg_handle == NULL)
1810                 goto fail;
1811
1812         msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
1813         if (!msg)
1814                 goto fail;
1815
1816         send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
1817         if (!send_opt)
1818                 goto fail;
1819
1820         msg_err = msg_get_message(g_msg_handle,
1821                                         (msg_message_id_t)message_id,
1822                                         msg, send_opt);
1823         if (msg_err != MSG_SUCCESS)
1824                 goto fail;
1825
1826         buf = __bt_prepare_msg_bmseg(msg, attach, transcode);
1827
1828         dbus_g_method_return(context, FALSE, buf);
1829         msg_release_struct(&msg);
1830         msg_release_struct(&send_opt);
1831         g_free(buf);
1832
1833         FN_END;
1834         return TRUE;
1835
1836 fail:
1837
1838         if (msg)
1839                 msg_release_struct(&msg);
1840
1841         if (send_opt)
1842                 msg_release_struct(&send_opt);
1843
1844         error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1845                                                         "InternalError");
1846         dbus_g_method_return_error(context, error);
1847         g_error_free(error);
1848         ERR("fail - \n");
1849         return FALSE;
1850 }
1851
1852 static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent,
1853                                         gboolean save_copy,
1854                                         gboolean retry_send,
1855                                         gboolean native,
1856                                         gchar *folder_name,
1857                                         DBusGMethodInvocation *context)
1858 {
1859         FN_START;
1860         guint64 handle = 0;
1861
1862         DBG_SECURE("folder_name = %s\n", folder_name);
1863
1864         handle = __bt_add_id(-1);
1865         current_push_map_id = handle;
1866
1867         /* FALSE : Keep messages in Sent folder */
1868         /* TRUE : don't keep messages in sent folder */
1869         opt.save_copy = save_copy;
1870         DBG("opt.save_copy = %d\n", opt.save_copy);
1871
1872         /* FALSE : don't retry */
1873         /* TRUE  : retry */
1874         opt.retry_send = retry_send;
1875         DBG("opt.retry_send = %d\n", opt.retry_send);
1876
1877         /* FALSE : native */
1878         /* TRUE : UTF-8 */
1879         opt.native = native;
1880         DBG("opt.native = %d\n", opt.native);
1881
1882         dbus_g_method_return(context, handle);
1883         FN_END;
1884         return TRUE;
1885 }
1886
1887 static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
1888                                         gchar *bmsg,
1889                                         DBusGMethodInvocation *context)
1890 {
1891         FN_START;
1892         int id = -1;
1893         int folder_id;
1894         char *body = NULL;
1895         GSList *recepients = NULL;
1896         gboolean send = FALSE;
1897
1898         GError *error = NULL;
1899
1900         INFO("BMSG is \n %s", bmsg);
1901
1902         struct bmsg_data *bmsg_info = NULL;
1903
1904         bmsg_info = bmsg_parse(bmsg);
1905         if (!bmsg_info)
1906                 goto done;
1907
1908         folder_id = __bt_get_folder_id(bmsg_info->folder);
1909         if (folder_id == -1)
1910                 goto done;
1911
1912         if (MSG_OUTBOX_ID == folder_id)
1913                 send = TRUE;
1914
1915         body = bmsg_get_msg_body(bmsg_info, opt.native);
1916         if (body == NULL)
1917                 goto done;
1918
1919         recepients = bmsg_get_msg_recepients(bmsg_info);
1920
1921         id = __bt_push_sms(send, folder_id, body, recepients);
1922         if (id == -1)
1923                 goto done;
1924
1925         __bt_update_id(current_push_map_id, id);
1926
1927 done:
1928         g_free(body);
1929         g_slist_free(recepients);
1930         bmsg_free_bmsg(bmsg_info);
1931
1932         if (id == -1) {
1933                 error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1934                                                         "InternalError");
1935                 dbus_g_method_return_error(context, error);
1936                 g_error_free(error);
1937                 FN_END;
1938                 return FALSE;
1939         }
1940
1941         dbus_g_method_return(context);
1942         FN_END;
1943         return TRUE;
1944 }
1945
1946 static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent,
1947                                                 DBusGMethodInvocation *context)
1948 {
1949         int err = TRUE;
1950
1951         dbus_g_method_return(context, err);
1952         return TRUE;
1953 }
1954
1955 static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent,
1956                                                 gchar *handle,
1957                                                 gboolean read_status,
1958                                                 DBusGMethodInvocation *context)
1959 {
1960         FN_START;
1961         int msg_id;
1962         GError *error = NULL;
1963         msg_error_t msg_err;
1964
1965         msg_id = __bt_get_uid(handle);
1966         if (msg_id == -1)
1967                 goto fail;
1968
1969         DBG("msg_id = %d,  read_status = %d\n", msg_id, read_status);
1970
1971         msg_err = msg_update_read_status(g_msg_handle, msg_id,
1972                                                         read_status);
1973         if (msg_err != MSG_SUCCESS)
1974                 goto fail;
1975
1976         dbus_g_method_return(context);
1977         FN_END;
1978         return TRUE;
1979
1980 fail:
1981         error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1982                                                         "InternalError");
1983         dbus_g_method_return_error(context, error);
1984         g_error_free(error);
1985
1986         ERR("fail -\n");
1987         return FALSE;
1988 }
1989
1990 static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent,
1991                                                 gchar *handle,
1992                                                 gboolean delete_status,
1993                                                 DBusGMethodInvocation *context)
1994 {
1995         FN_START;
1996         int msg_id = 0;
1997         int folder_id;
1998         int del_folder_id;
1999         gchar *folder_name = NULL;
2000         guint64 map_id;
2001         GError *error = NULL;
2002         msg_error_t err;
2003         msg_struct_t msg = NULL;
2004         msg_struct_t send_opt = NULL;
2005
2006         msg_id = __bt_get_uid(handle);
2007         if (msg_id == -1)
2008                 goto fail;
2009
2010         if (g_msg_handle == NULL)
2011                 goto fail;
2012
2013         msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
2014         if (msg == NULL)
2015                 goto fail;
2016
2017         send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
2018         if (send_opt == NULL)
2019                 goto fail;
2020
2021         err = msg_get_message(g_msg_handle,
2022                                         (msg_message_id_t)msg_id,
2023                                         msg, send_opt);
2024         if (err != MSG_SUCCESS)
2025                 goto fail;
2026
2027         err = msg_get_int_value(msg, MSG_MESSAGE_FOLDER_ID_INT,
2028                                                         &folder_id);
2029         if (err != MSG_SUCCESS)
2030                 goto fail;
2031
2032         folder_name = __bt_get_folder_name(folder_id);
2033         del_folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME);
2034         map_id = __bt_validate_uid(msg_id);
2035
2036         DBG("msg_id = %d, delete_status = %d\n", msg_id, delete_status);
2037
2038         if (-1 == del_folder_id) {
2039                 ERR("Delete folder not present");
2040                 if (delete_status == TRUE) {
2041                         err = msg_delete_message(g_msg_handle, msg_id);
2042                         if (err != MSG_SUCCESS)
2043                                 goto fail;
2044                 }
2045
2046         } else {
2047                 if (delete_status == TRUE) {
2048                         err = msg_move_msg_to_folder(g_msg_handle, msg_id, del_folder_id);
2049                         if (err == MSG_SUCCESS) {
2050                                 __bt_mns_client_event_notify("MessageShift",
2051                                                 map_id,
2052                                                 "TELECOM/MSG/DELETED",
2053                                                 folder_name,
2054                                                 "SMS_GSM");
2055                         }
2056                 } else {
2057                         if (folder_id != del_folder_id) {
2058                                 DBG("Message not in delete folder");
2059                                 goto fail;
2060                         }
2061
2062                         err = msg_move_msg_to_folder(g_msg_handle, msg_id, MSG_INBOX_ID);
2063                         if (err == MSG_SUCCESS) {
2064                                 __bt_mns_client_event_notify("MessageShift",
2065                                                 map_id,
2066                                                 "TELECOM/MSG/INBOX",
2067                                                 "TELECOM/MSG/DELETED",
2068                                                 "SMS_GSM");
2069                         }
2070                 }
2071         }
2072
2073         g_free(folder_name);
2074         msg_release_struct(&msg);
2075         msg_release_struct(&send_opt);
2076         dbus_g_method_return(context);
2077         FN_END;
2078         return TRUE;
2079
2080 fail:
2081         g_free(folder_name);
2082
2083         msg_release_struct(&msg);
2084         msg_release_struct(&send_opt);
2085
2086         error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
2087                                                         "InternalError");
2088         dbus_g_method_return_error(context, error);
2089         g_error_free(error);
2090         ERR("fail -\n");
2091         return FALSE;
2092 }
2093
2094 static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent,
2095                                                 gchar *remote_addr,
2096                                                 gboolean status,
2097                                                 DBusGMethodInvocation *context)
2098 {
2099         FN_START;
2100         DBG_SECURE("remote_addr = %s \n", remote_addr);
2101
2102         if (status == TRUE)
2103                 __bt_mns_client_connect(remote_addr);
2104         else
2105                 __bt_mns_client_disconnect();
2106
2107         return TRUE;
2108 }
2109
2110 static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent,
2111                                         DBusGMethodInvocation *context)
2112 {
2113         FN_START;
2114         g_main_loop_quit(g_mainloop);
2115         return TRUE;
2116 }
2117
2118 int main(void)
2119 {
2120         FN_START;
2121         BluetoothMapAgent *bluetooth_map_obj = NULL;
2122         DBusGProxy *bus_proxy = NULL;
2123         guint result = 0;
2124         int ret;
2125         GError *error = NULL;
2126         DBG("Starting Bluetooth MAP agent");
2127
2128         g_mainloop = g_main_loop_new(NULL, FALSE);
2129
2130         if (g_mainloop == NULL) {
2131                 ERR("Couldn't create GMainLoop\n");
2132                 return EXIT_FAILURE;
2133         }
2134
2135         g_connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
2136
2137         if (error != NULL) {
2138                 ERR("Couldn't connect to system bus[%s]\n", error->message);
2139                 g_error_free(error);
2140                 return EXIT_FAILURE;
2141         }
2142
2143         bus_proxy = dbus_g_proxy_new_for_name(g_connection, DBUS_SERVICE_DBUS,
2144                                                 DBUS_PATH_DBUS,
2145                                                 DBUS_INTERFACE_DBUS);
2146         if (bus_proxy == NULL) {
2147                 ERR("Failed to get a proxy for D-Bus\n");
2148                 goto failure;
2149         }
2150
2151         if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING,
2152                                         BT_MAP_SERVICE_NAME, G_TYPE_UINT, 0,
2153                                         G_TYPE_INVALID, G_TYPE_UINT, &result,
2154                                         G_TYPE_INVALID)) {
2155                 if (error != NULL) {
2156                         ERR("RequestName RPC failed[%s]\n", error->message);
2157                         g_error_free(error);
2158                 }
2159                 goto failure;
2160         }
2161
2162         if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
2163                 ERR("Failed to get the primary well-known name.\n");
2164                 goto failure;
2165         }
2166
2167         g_object_unref(bus_proxy);
2168         bus_proxy = NULL;
2169
2170         bluetooth_map_obj = g_object_new(BLUETOOTH_MAP_TYPE_AGENT, NULL);
2171
2172         /* Registering it on the D-Bus */
2173         dbus_g_connection_register_g_object(g_connection,
2174                                                 BT_MAP_SERVICE_OBJECT_PATH,
2175                                                 G_OBJECT(bluetooth_map_obj));
2176
2177         if (__bluetooth_map_start_service() == FALSE)
2178                 goto failure;
2179
2180         g_tapi_handle = tel_init(NULL);
2181         if (!g_tapi_handle)
2182                 goto failure;
2183
2184         ret = tel_get_sms_sca(g_tapi_handle, 0, __bt_get_sms_sca, NULL);
2185         if (ret != TAPI_API_SUCCESS) {
2186                 ERR("TAPI err = %d", ret);
2187                 goto failure;
2188         }
2189
2190         g_main_loop_run(g_mainloop);
2191
2192  failure:
2193
2194         __bt_remove_list(id_list);
2195
2196         tel_deinit(g_tapi_handle);
2197         g_free(g_sca_info);
2198
2199         __bt_mns_client_disconnect();
2200
2201         if (bus_proxy)
2202                 g_object_unref(bus_proxy);
2203         if (bluetooth_map_obj)
2204                 g_object_unref(bluetooth_map_obj);
2205         if (g_connection)
2206                 dbus_g_connection_unref(g_connection);
2207
2208         __bluetooth_map_stop_service();
2209         DBG("Bluetooth MAP agent Terminated successfully\n");
2210         FN_END;
2211         return EXIT_FAILURE;
2212 }