[Warnings] Fixed build warnings.
[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, 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", 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         g_free(msg_info.handle);
1070
1071         ret = msg_get_int_value(msg_struct_handle,
1072                                 MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
1073         if (ret == MSG_SUCCESS) {
1074                 __get_msg_timestamp((time_t *)&dptime, msg_datetime);
1075         }
1076         msg_info.datetime = g_strdup(msg_datetime);
1077
1078         ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_TYPE_INT,
1079                                                                 &m_type);
1080         if (ret == MSG_SUCCESS) {
1081                 DBG("m_type %d\n", m_type);
1082         }
1083
1084         msg_info.type = g_strdup("SMS_GSM");
1085
1086         ret = msg_get_str_value(msg_struct_handle,
1087                                 MSG_MESSAGE_SMS_DATA_STR, msg_body,
1088                                 BT_MAP_MSG_BODY_MAX);
1089         if (ret == MSG_SUCCESS) {
1090                 DBG_SECURE("SMS subject %s", msg_body);
1091                 if (strlen(msg_body)) {
1092                         msg_info.text = TRUE ;
1093                         msg_info.subject = __bt_get_truncated_utf8_string(msg_body);
1094                 }
1095         }
1096
1097         ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_DATA_SIZE_INT,
1098                                                                 &data_size);
1099         if (ret == MSG_SUCCESS)
1100                 snprintf(msg_size, sizeof(msg_size), "%d", data_size);
1101
1102         msg_info.size = g_strdup(msg_size);
1103
1104         msg_info.reception_status = g_strdup("complete");
1105         msg_info.attachment_size = g_strdup("0");
1106
1107         ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_PROTECTED_BOOL,
1108                                                         &protect_status);
1109         if (ret == MSG_SUCCESS) {
1110                 if (protect_status)
1111                         msg_info.protect = TRUE;
1112         }
1113
1114         ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_READ_BOOL,
1115                                                                 &read_status);
1116         if (ret == MSG_SUCCESS) {
1117                 if (read_status)
1118                         msg_info.read = TRUE;
1119         }
1120
1121         ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_PRIORITY_INT,
1122                                                                 &priority);
1123         if (ret == MSG_SUCCESS) {
1124                 if (priority == MSG_MESSAGE_PRIORITY_HIGH)
1125                         msg_info.priority = TRUE;
1126         }
1127
1128         FN_END;
1129         return msg_info;
1130 }
1131
1132 static void __bluetooth_map_msg_incoming_status_cb(msg_handle_t handle,
1133                                                         msg_struct_t msg,
1134                                                         void *user_param)
1135 {
1136         FN_START;
1137         int msg_id = 0;
1138         int msg_type = 0;
1139         int ret;
1140
1141         guint64 uid;
1142
1143         if (!g_mns_proxy) {
1144                 INFO("MNS Client not connected");
1145                 return;
1146         }
1147
1148         ret = msg_get_int_value(msg, MSG_MESSAGE_TYPE_INT, &msg_type);
1149         if (ret != MSG_SUCCESS)
1150                 return;
1151
1152         if (msg_type != MSG_TYPE_SMS) {
1153                 INFO("Not a SMS");
1154                 return;
1155         }
1156
1157         ret = msg_get_int_value(msg, MSG_MESSAGE_ID_INT, &msg_id);
1158         if (ret != MSG_SUCCESS)
1159                 return;;
1160
1161         uid = __bt_add_id(msg_id);
1162
1163         __bt_mns_client_event_notify("NewMessage", uid,
1164                                                 "TELECOM/MSG/INBOX", "",
1165                                                 "SMS_GSM");
1166
1167         FN_END;
1168         return;
1169 }
1170
1171 static void __bluetooth_map_msg_sent_status_cb(msg_handle_t handle,
1172                                                         msg_struct_t msg,
1173                                                         void *user_param)
1174 {
1175         FN_START;
1176         int ret;
1177         int status;
1178
1179         if (!g_mns_proxy) {
1180                 INFO("MNS Client not connected");
1181                 return;
1182         }
1183
1184         ret = msg_get_int_value(msg, MSG_SENT_STATUS_NETWORK_STATUS_INT,
1185                                                                 &status);
1186         if (ret != MSG_SUCCESS)
1187                 return;
1188
1189         if (status == MSG_NETWORK_SEND_SUCCESS) {
1190                 INFO("MSG SENT SUCCESS !!! ");
1191                 __bt_mns_client_event_notify("MessageShift",
1192                                         current_push_map_id,
1193                                         "TELECOM/MSG/SENT",
1194                                         "TELECOM/MSG/OUTBOX",
1195                                         "SMS_GSM");
1196
1197                 __bt_mns_client_event_notify("SendingSuccess",
1198                                         current_push_map_id,
1199                                         "TELECOM/MSG/SENT", "",
1200                                         "SMS_GSM");
1201         } else {
1202                 ERR("MSG SENT FAIL !!! [%d]", status);
1203                 __bt_mns_client_event_notify("SendingFailure",
1204                                         current_push_map_id,
1205                                         "TELECOM/MSG/OUTBOX", "",
1206                                         "SMS_GSM");
1207         }
1208
1209         FN_END;
1210         return;
1211 }
1212
1213 static gboolean __bluetooth_map_start_service()
1214 {
1215         FN_START;
1216         msg_error_t err;
1217
1218         err = msg_open_msg_handle(&g_msg_handle);
1219         if (err != MSG_SUCCESS) {
1220                 ERR("msg_open_msg_handle error = %d\n", err);
1221                 return FALSE;
1222         }
1223
1224         if (-1 == __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME))
1225                 __bt_add_deleted_folder();
1226
1227         err = msg_reg_sms_message_callback(g_msg_handle,
1228                                         __bluetooth_map_msg_incoming_status_cb,
1229                                         0, (void *)BT_MAP_MSG_CB);
1230         if (err != MSG_SUCCESS) {
1231                 ERR("msg_reg_sms_message_callback error  = %d\n", err);
1232                 return FALSE;
1233         }
1234
1235         err = msg_reg_sent_status_callback(g_msg_handle,
1236                                         __bluetooth_map_msg_sent_status_cb,
1237                                         NULL);
1238         if (err != MSG_SUCCESS) {
1239                 ERR("msg_reg_sent_status_callback error  = %d\n", err);
1240                 return FALSE;
1241         }
1242
1243         FN_END;
1244         return TRUE;
1245 }
1246
1247 static void __bluetooth_map_stop_service()
1248 {
1249         FN_START;
1250         msg_error_t err =  MSG_SUCCESS;
1251         int folder_id;
1252
1253         folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME);
1254         if (-1 != folder_id) {
1255                 err = msg_delete_folder(g_msg_handle, folder_id);
1256                 if (err != MSG_SUCCESS)
1257                         ERR("Delete folder failed");
1258         }
1259
1260         if (NULL != g_msg_handle)
1261                 msg_close_msg_handle(&g_msg_handle);
1262
1263         g_msg_handle = NULL;
1264
1265         FN_END;
1266         return;
1267 }
1268
1269 static gboolean __bt_validate_utf8(char **text)
1270 {
1271         FN_START;
1272         if (g_utf8_validate(*text, -1, NULL))
1273                 return TRUE;
1274
1275         FN_END;
1276         return FALSE;
1277 }
1278
1279 static gboolean __bt_validate_msg_data(struct message_info *msg_info)
1280 {
1281         FN_START;
1282         if (msg_info == NULL)
1283                 return FALSE;
1284
1285         if (msg_info->subject)
1286                 return __bt_validate_utf8(&msg_info->subject);
1287
1288         if (msg_info->sender_name)
1289                 return __bt_validate_utf8(&msg_info->sender_name);
1290
1291         if (msg_info->sender_addressing)
1292                 return __bt_validate_utf8(&msg_info->sender_addressing);
1293
1294         if (msg_info->replyto_addressing)
1295                 return __bt_validate_utf8(&msg_info->replyto_addressing);
1296
1297         if (msg_info->recipient_name)
1298                 return __bt_validate_utf8(&msg_info->recipient_name);
1299
1300         if (msg_info->recipient_addressing)
1301                 return __bt_validate_utf8(&msg_info->recipient_addressing);
1302
1303         FN_END;
1304         return TRUE;
1305 }
1306
1307 msg_error_t __bt_send_sms(int msg_id, msg_struct_t p_msg, msg_struct_t p_send_opt)
1308 {
1309         FN_START;
1310         msg_error_t err;
1311         msg_struct_t p_req;
1312
1313         p_req = msg_create_struct(MSG_STRUCT_REQUEST_INFO);
1314
1315         msg_set_int_value(p_msg, MSG_MESSAGE_ID_INT, msg_id);
1316         msg_set_struct_handle(p_req, MSG_REQUEST_MESSAGE_HND, p_msg);
1317         msg_set_struct_handle(p_req, MSG_REQUEST_SENDOPT_HND, p_send_opt);
1318
1319         err = msg_sms_send_message(g_msg_handle, p_req);
1320         if (err != MSG_SUCCESS)
1321                 ERR("Failed msg_sms_send_message %d", err);
1322
1323         msg_release_struct(&p_req);
1324         FN_END;
1325         return err;
1326 }
1327
1328 static int __bt_push_sms(gboolean send, int folder_id, char *body,
1329                                                         GSList *recepients)
1330 {
1331         FN_START;
1332         msg_struct_t msg_info = NULL;
1333         msg_struct_t send_opt = NULL;
1334         msg_error_t err;
1335
1336         int count = 0;
1337         int i = 0;
1338         int msg_id = -1;
1339
1340         msg_info = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
1341         if (msg_info == NULL)
1342                 goto fail;
1343
1344         err = msg_set_int_value(msg_info, MSG_MESSAGE_TYPE_INT, MSG_TYPE_SMS);
1345         if (err != MSG_SUCCESS)
1346                 goto fail;
1347
1348         if (body) {
1349                 err = msg_set_str_value(msg_info,
1350                                         MSG_MESSAGE_SMS_DATA_STR,
1351                                         body, strlen(body));
1352                 if (err != MSG_SUCCESS)
1353                         goto fail;
1354         } else {
1355                 err = msg_set_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR,
1356                                                                 NULL, 0);
1357                 if (err != MSG_SUCCESS)
1358                         goto fail;
1359         }
1360
1361         DBG("folder_id  %d\n", folder_id);
1362         err = msg_set_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
1363                                                                 folder_id);
1364         if (err != MSG_SUCCESS)
1365                 goto fail;
1366
1367         if (recepients) {
1368                 count = g_slist_length(recepients);
1369                 DBG("Count = %d\n", count);
1370
1371                 for (i = 0; i < count; i++) {
1372                         msg_struct_t tmp_addr;
1373                         char *address = (char *)g_slist_nth_data(recepients, i);
1374                         if (address == NULL) {
1375                                 ERR("[ERROR] address is value NULL, skip");
1376                                 continue;
1377                         }
1378                         msg_list_add_item(msg_info,
1379                                 MSG_MESSAGE_ADDR_LIST_HND, &tmp_addr);
1380
1381                         msg_set_int_value(tmp_addr,
1382                                 MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT,
1383                                 MSG_RECIPIENTS_TYPE_TO);
1384
1385                         msg_set_str_value(tmp_addr,
1386                                 MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
1387                                 address, strlen(address));
1388                 }
1389         }
1390
1391         send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
1392
1393         err = msg_set_bool_value(send_opt, MSG_SEND_OPT_SETTING_BOOL, true);
1394         if (err != MSG_SUCCESS)
1395                 goto fail;
1396
1397         /* Do not keep a copy */
1398         err = msg_set_bool_value(send_opt, MSG_SEND_OPT_KEEPCOPY_BOOL,
1399                                                         opt.save_copy);
1400         if (err != MSG_SUCCESS)
1401                 goto fail;
1402
1403         msg_id = msg_add_message(g_msg_handle, msg_info, send_opt);
1404         DBG("msg_id = %d\n", msg_id);
1405
1406         if (send == TRUE)
1407                 __bt_send_sms(msg_id, msg_info, send_opt);
1408
1409
1410 fail:
1411         msg_release_struct(&msg_info);
1412         msg_release_struct(&send_opt);
1413         FN_END;
1414         return msg_id;
1415 }
1416
1417 static void __bt_mns_client_connect(char *address)
1418 {
1419         FN_START;
1420         GHashTable *hash;
1421         GValue *tgt_value;
1422         GError *error = NULL;
1423         const char *session_path = NULL;
1424
1425         if (g_mns_proxy) {
1426                 DBG_SECURE("MNS Client already connected to %s", address);
1427                 return;
1428         }
1429
1430         g_mns_proxy = dbus_g_proxy_new_for_name(g_connection,
1431                                                 OBEX_CLIENT_SERVICE,
1432                                                 OBEX_CLIENT_PATH,
1433                                                 OBEX_CLIENT_INTERFACE);
1434         if (!g_mns_proxy) {
1435                 ERR("Failed to get a proxy for D-Bus\n");
1436                 return;
1437         }
1438
1439         hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1440                                      NULL, (GDestroyNotify)g_free);
1441
1442         tgt_value = g_new0(GValue, 1);
1443         g_value_init(tgt_value, G_TYPE_STRING);
1444         g_value_set_string(tgt_value, "MNS");
1445         g_hash_table_insert(hash, "Target", tgt_value);
1446
1447         dbus_g_proxy_call(g_mns_proxy, "CreateSession", &error,
1448                 G_TYPE_STRING,address,
1449                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
1450                 hash, G_TYPE_INVALID,
1451                 DBUS_TYPE_G_OBJECT_PATH, &session_path,
1452                 G_TYPE_INVALID);
1453         if (error) {
1454                 ERR("Error [%s]", error->message);
1455                 g_error_free(error);
1456                 g_hash_table_destroy(hash);
1457                 g_object_unref(g_mns_proxy);
1458                 g_mns_proxy = NULL;
1459                 return;
1460         }
1461
1462         g_mns_path = g_strdup(session_path);
1463         DBG("g_mns_path = %s\n", g_mns_path);
1464
1465         g_hash_table_destroy(hash);
1466
1467         FN_END;
1468         return;
1469 }
1470
1471 static void __bt_mns_client_disconnect()
1472 {
1473         FN_START;
1474         GError *error = NULL;
1475
1476         if (!g_mns_proxy) {
1477                 ERR("No proxy to disconnect");
1478                 return;
1479         }
1480
1481         dbus_g_proxy_call(g_mns_proxy, "RemoveSession", &error,
1482                 DBUS_TYPE_G_OBJECT_PATH, g_mns_path,
1483                 G_TYPE_INVALID, G_TYPE_INVALID);
1484         if (error) {
1485                 ERR("Error [%s]", error->message);
1486                 g_error_free(error);
1487         }
1488
1489         g_free(g_mns_path);
1490         g_mns_path = NULL;
1491
1492         g_object_unref(g_mns_proxy);
1493         g_mns_proxy = NULL;
1494
1495         FN_END;
1496         return;
1497 }
1498
1499 static void __bt_mns_client_event_notify(gchar *event, guint64 handle,
1500                                         gchar *folder, gchar *old_folder,
1501                                         gchar *msg_type)
1502 {
1503         FN_START;
1504         GError *error = NULL;
1505         DBusGProxy *mns_proxy;
1506
1507         if (!g_mns_proxy) {
1508                 ERR("No client proxy");
1509                 return;
1510         }
1511
1512         mns_proxy = dbus_g_proxy_new_for_name(g_connection,
1513                                                 OBEX_CLIENT_SERVICE,
1514                                                 g_mns_path,
1515                                                 MNS_CLIENT_INTERFACE);
1516         if (mns_proxy == NULL) {
1517                 ERR("Failed to get a proxy for D-Bus\n");
1518                 return;
1519         }
1520
1521         dbus_g_proxy_call(mns_proxy, "SendEvent", &error,
1522                 G_TYPE_STRING, event,
1523                 G_TYPE_UINT64, handle,
1524                 G_TYPE_STRING, folder,
1525                 G_TYPE_STRING, old_folder,
1526                 G_TYPE_STRING, msg_type,
1527                 G_TYPE_INVALID, G_TYPE_INVALID);
1528         if (error) {
1529                 ERR("Error [%s]", error->message);
1530                 g_error_free(error);
1531         }
1532
1533         g_object_unref(mns_proxy);
1534         FN_END;
1535 }
1536
1537 static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
1538                                                 DBusGMethodInvocation *context)
1539 {
1540         FN_START;
1541         GPtrArray *array = g_ptr_array_new();
1542         GValue value;
1543         GError *error = NULL;
1544
1545         char name[BT_MAP_MSG_INFO_MAX] = {0,};
1546         char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
1547         int i;
1548         int ret;
1549         gboolean msg_ret = TRUE;
1550
1551         msg_struct_list_s folder_list = {0,};
1552         msg_struct_t p_folder;
1553
1554         if (g_msg_handle == NULL) {
1555                 msg_ret = FALSE;
1556                 goto done;
1557         }
1558
1559         if (msg_get_folder_list(g_msg_handle, &folder_list) != MSG_SUCCESS) {
1560                 msg_ret = FALSE;
1561                 goto done;
1562         }
1563
1564         for (i = 0; i < folder_list.nCount; i++) {
1565                 p_folder = folder_list.msg_struct_info[i];
1566                 memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX);
1567
1568                 ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
1569                                         folder_name, BT_MAP_MSG_INFO_MAX);
1570                 if (ret != MSG_SUCCESS)
1571                         continue;
1572
1573                 if (g_strstr_len(folder_name, -1, BT_MAP_MSG_TEMPLATE))
1574                         continue;
1575
1576                 if (!g_ascii_strncasecmp(folder_name, BT_MAP_SENT_FOLDER_NAME,
1577                                         strlen(BT_MAP_SENT_FOLDER_NAME))) {
1578                         memset(folder_name, 0, sizeof(folder_name));
1579                         g_strlcpy(folder_name, BT_MAP_SENT_FOLDER_NAME,
1580                                                         sizeof(folder_name));
1581                 }
1582
1583                 g_strlcpy(name, folder_name, sizeof(name));
1584                 memset(&value, 0, sizeof(GValue));
1585                 g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
1586                 g_value_take_boxed(&value, dbus_g_type_specialized_construct(
1587                                         DBUS_STRUCT_STRING_STRING_UINT));
1588                 dbus_g_type_struct_set(&value, 0, name, G_MAXUINT);
1589                 g_ptr_array_add(array, g_value_get_boxed(&value));
1590         }
1591
1592 done:
1593
1594         if (folder_list.msg_struct_info)
1595                 msg_release_list_struct(&folder_list);
1596
1597         if (msg_ret == FALSE) {
1598                 g_ptr_array_free(array, TRUE);
1599
1600                 error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1601                                                 "InternalError");
1602                 dbus_g_method_return_error(context, error);
1603                 g_error_free(error);
1604                 return FALSE;
1605         } else {
1606                 dbus_g_method_return(context, array);
1607                 g_ptr_array_free(array, TRUE);
1608                 FN_END;
1609                 return TRUE;
1610         }
1611 }
1612
1613 static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
1614                                                 gchar *folder_name, guint16 max,
1615                                                 DBusGMethodInvocation *context)
1616 {
1617         FN_START;
1618         GPtrArray *array = g_ptr_array_new();
1619         GValue value;
1620         GError *error = NULL;
1621
1622         char *folder = NULL;
1623         int i = 0;
1624         int ret = 0;
1625         int folder_id = -1;
1626         int folder_len;
1627         bool read;
1628         guint64 count = 0;
1629         gboolean newmsg = FALSE;
1630
1631         msg_struct_list_s folder_list = {0,};
1632         msg_struct_list_s msg_list = {0,};
1633         msg_struct_t list_cond;
1634
1635         if (g_msg_handle == NULL)
1636                 goto fail;
1637
1638         if (!folder_name)
1639                 goto fail;
1640
1641         folder_len = strlen(folder_name);
1642         /* In case of parent folders send empty message listing */
1643         if (!g_ascii_strncasecmp(folder_name, "/", folder_len) ||
1644                 !g_ascii_strncasecmp(folder_name, "/telecom", folder_len) ||
1645                 !g_ascii_strncasecmp(folder_name, "/telecom/msg", folder_len))
1646                 goto done;
1647
1648         folder = strrchr(folder_name, '/');
1649         if (NULL == folder)
1650                 folder = folder_name;
1651         else
1652                 folder++;
1653
1654         ret = msg_get_folder_list(g_msg_handle, &folder_list);
1655         if (ret != MSG_SUCCESS)
1656                 goto fail;
1657
1658         for (i = 0; i < folder_list.nCount; i++) {
1659                 char f_name[BT_MAP_MSG_INFO_MAX] = {0, };
1660                 msg_struct_t p_folder = folder_list.msg_struct_info[i];
1661
1662                 ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
1663                                         f_name, BT_MAP_MSG_INFO_MAX);
1664                 if (ret  != MSG_SUCCESS)
1665                         continue;
1666
1667                 if (!g_ascii_strncasecmp(f_name, folder, strlen(folder))) {
1668                         ret = msg_get_int_value(p_folder, MSG_FOLDER_INFO_ID_INT,
1669                                                                 &folder_id);
1670                         if (ret != MSG_SUCCESS)
1671                                 goto fail;
1672
1673                         DBG("folder_id %d \n", folder_id);
1674
1675                         break;
1676                 }
1677         }
1678
1679         if (folder_id == -1)
1680                 goto fail;
1681
1682         list_cond = msg_create_struct(MSG_STRUCT_MSG_LIST_CONDITION);
1683         ret = msg_set_int_value(list_cond,
1684                                 MSG_LIST_CONDITION_FOLDER_ID_INT,
1685                                 folder_id);
1686         if (ret != MSG_SUCCESS)
1687                 goto fail;
1688
1689         ret = msg_set_int_value(list_cond,
1690                                 MSG_LIST_CONDITION_MSGTYPE_INT, MSG_TYPE_SMS);
1691         if (ret != MSG_SUCCESS)
1692                 goto fail;
1693
1694         ret = msg_get_message_list2(g_msg_handle, list_cond, &msg_list);
1695
1696         msg_release_struct(&list_cond);
1697
1698         if (ret != MSG_SUCCESS)
1699                 goto fail;
1700
1701         count = msg_list.nCount;
1702
1703         for (i = 0; i < count; i++) {
1704                 msg_get_bool_value(msg_list.msg_struct_info[i],
1705                                         MSG_MESSAGE_READ_BOOL, &read);
1706                 if (read == false) {
1707                         newmsg = TRUE;
1708                         break;
1709                 }
1710         }
1711
1712         DBG("count = %llx, newmsg = %d, max = %d", count, newmsg, max);
1713
1714         if (max == 0)
1715                 goto done;
1716
1717         for (i = 0; i < msg_list.nCount; i++) {
1718
1719                 struct message_info msg_info;
1720
1721                 memset(&value, 0, sizeof(GValue));
1722                 g_value_init(&value, DBUS_STRUCT_MESSAGE_LIST);
1723                 g_value_take_boxed(&value, dbus_g_type_specialized_construct(
1724                                                 DBUS_STRUCT_MESSAGE_LIST));
1725
1726                 msg_info = __bt_message_info_get(msg_list.msg_struct_info[i]);
1727
1728                 if (!__bt_validate_msg_data(&msg_info)) {
1729                         __bt_message_info_free(msg_info);
1730                         count--;
1731                         continue;
1732                 }
1733
1734                 dbus_g_type_struct_set(&value, 0, msg_info.handle,
1735                                         1, msg_info.subject,
1736                                         2, msg_info.datetime,
1737                                         3, msg_info.sender_name,
1738                                         4, msg_info.sender_addressing,
1739                                         5, msg_info.recipient_name,
1740                                         6, msg_info.recipient_addressing,
1741                                         7, msg_info.type,
1742                                         8, msg_info.size,
1743                                         9, msg_info.reception_status,
1744                                         10, msg_info.text,
1745                                         11, msg_info.attachment_size,
1746                                         12, msg_info.priority,
1747                                         13, msg_info.read,
1748                                         14, msg_info.sent,
1749                                         15, msg_info.protect,
1750                                         16, msg_info.replyto_addressing,
1751                                         G_MAXUINT);
1752                 g_ptr_array_add(array, g_value_get_boxed(&value));
1753
1754                 __bt_message_info_free(msg_info);
1755         }
1756
1757 done:
1758         if (folder_list.msg_struct_info)
1759                 ret = msg_release_list_struct(&folder_list);
1760
1761         if (msg_list.msg_struct_info)
1762                 ret = msg_release_list_struct(&msg_list);
1763
1764         dbus_g_method_return(context, newmsg, count, array);
1765         g_ptr_array_free(array, TRUE);
1766         FN_END;
1767         return TRUE;
1768
1769 fail:
1770         if (folder_list.msg_struct_info)
1771                 ret = msg_release_list_struct(&folder_list);
1772
1773         if (msg_list.msg_struct_info)
1774                 ret = msg_release_list_struct(&msg_list);
1775
1776         g_ptr_array_free(array, TRUE);
1777         error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1778                                                           "InternalError");
1779         dbus_g_method_return_error(context, error);
1780         g_error_free(error);
1781         ERR("fail -");
1782         return FALSE;
1783 }
1784
1785 static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent,
1786                                                 gchar *message_name,
1787                                                 gboolean attach,
1788                                                 gboolean transcode,
1789                                                 gboolean first_request,
1790                                                 DBusGMethodInvocation *context)
1791 {
1792         FN_START;
1793         char *buf = NULL;
1794         int message_id = 0;
1795
1796         GError *error = NULL;
1797
1798         msg_error_t msg_err;
1799         msg_struct_t msg = NULL;
1800         msg_struct_t send_opt = NULL;
1801
1802         message_id = __bt_get_uid(message_name);
1803         if (message_id == -1)
1804                 goto fail;
1805
1806         DBG("message_id %d \n", message_id);
1807         DBG("attach %d \n", attach);
1808         DBG("transcode %d \n", transcode);
1809         DBG("first_request %d \n", first_request);
1810
1811         if (g_msg_handle == NULL)
1812                 goto fail;
1813
1814         msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
1815         if (!msg)
1816                 goto fail;
1817
1818         send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
1819         if (!send_opt)
1820                 goto fail;
1821
1822         msg_err = msg_get_message(g_msg_handle,
1823                                         (msg_message_id_t)message_id,
1824                                         msg, send_opt);
1825         if (msg_err != MSG_SUCCESS)
1826                 goto fail;
1827
1828         buf = __bt_prepare_msg_bmseg(msg, attach, transcode);
1829
1830         dbus_g_method_return(context, FALSE, buf);
1831         msg_release_struct(&msg);
1832         msg_release_struct(&send_opt);
1833         g_free(buf);
1834
1835         FN_END;
1836         return TRUE;
1837
1838 fail:
1839
1840         if (msg)
1841                 msg_release_struct(&msg);
1842
1843         if (send_opt)
1844                 msg_release_struct(&send_opt);
1845
1846         error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1847                                                         "InternalError");
1848         dbus_g_method_return_error(context, error);
1849         g_error_free(error);
1850         ERR("fail - \n");
1851         return FALSE;
1852 }
1853
1854 static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent,
1855                                         gboolean save_copy,
1856                                         gboolean retry_send,
1857                                         gboolean native,
1858                                         gchar *folder_name,
1859                                         DBusGMethodInvocation *context)
1860 {
1861         FN_START;
1862         guint64 handle = 0;
1863
1864         DBG_SECURE("folder_name = %s\n", folder_name);
1865
1866         handle = __bt_add_id(-1);
1867         current_push_map_id = handle;
1868
1869         /* FALSE : Keep messages in Sent folder */
1870         /* TRUE : don't keep messages in sent folder */
1871         opt.save_copy = save_copy;
1872         DBG("opt.save_copy = %d\n", opt.save_copy);
1873
1874         /* FALSE : don't retry */
1875         /* TRUE  : retry */
1876         opt.retry_send = retry_send;
1877         DBG("opt.retry_send = %d\n", opt.retry_send);
1878
1879         /* FALSE : native */
1880         /* TRUE : UTF-8 */
1881         opt.native = native;
1882         DBG("opt.native = %d\n", opt.native);
1883
1884         dbus_g_method_return(context, handle);
1885         FN_END;
1886         return TRUE;
1887 }
1888
1889 static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
1890                                         gchar *bmsg,
1891                                         DBusGMethodInvocation *context)
1892 {
1893         FN_START;
1894         int id = -1;
1895         int folder_id;
1896         char *body = NULL;
1897         GSList *recepients = NULL;
1898         gboolean send = FALSE;
1899
1900         GError *error = NULL;
1901
1902         INFO("BMSG is \n %s", bmsg);
1903
1904         struct bmsg_data *bmsg_info = NULL;
1905
1906         bmsg_info = bmsg_parse(bmsg);
1907         if (!bmsg_info)
1908                 goto done;
1909
1910         folder_id = __bt_get_folder_id(bmsg_info->folder);
1911         if (folder_id == -1)
1912                 goto done;
1913
1914         if (MSG_OUTBOX_ID == folder_id)
1915                 send = TRUE;
1916
1917         body = bmsg_get_msg_body(bmsg_info, opt.native);
1918         if (body == NULL)
1919                 goto done;
1920
1921         recepients = bmsg_get_msg_recepients(bmsg_info);
1922
1923         id = __bt_push_sms(send, folder_id, body, recepients);
1924         if (id == -1)
1925                 goto done;
1926
1927         __bt_update_id(current_push_map_id, id);
1928
1929 done:
1930         g_free(body);
1931         g_slist_free(recepients);
1932         bmsg_free_bmsg(bmsg_info);
1933
1934         if (id == -1) {
1935                 error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1936                                                         "InternalError");
1937                 dbus_g_method_return_error(context, error);
1938                 g_error_free(error);
1939                 FN_END;
1940                 return FALSE;
1941         }
1942
1943         dbus_g_method_return(context);
1944         FN_END;
1945         return TRUE;
1946 }
1947
1948 static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent,
1949                                                 DBusGMethodInvocation *context)
1950 {
1951         int err = TRUE;
1952
1953         dbus_g_method_return(context, err);
1954         return TRUE;
1955 }
1956
1957 static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent,
1958                                                 gchar *handle,
1959                                                 gboolean read_status,
1960                                                 DBusGMethodInvocation *context)
1961 {
1962         FN_START;
1963         int msg_id;
1964         GError *error = NULL;
1965         msg_error_t msg_err;
1966
1967         msg_id = __bt_get_uid(handle);
1968         if (msg_id == -1)
1969                 goto fail;
1970
1971         DBG("msg_id = %d,  read_status = %d\n", msg_id, read_status);
1972
1973         msg_err = msg_update_read_status(g_msg_handle, msg_id,
1974                                                         read_status);
1975         if (msg_err != MSG_SUCCESS)
1976                 goto fail;
1977
1978         dbus_g_method_return(context);
1979         FN_END;
1980         return TRUE;
1981
1982 fail:
1983         error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1984                                                         "InternalError");
1985         dbus_g_method_return_error(context, error);
1986         g_error_free(error);
1987
1988         ERR("fail -\n");
1989         return FALSE;
1990 }
1991
1992 static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent,
1993                                                 gchar *handle,
1994                                                 gboolean delete_status,
1995                                                 DBusGMethodInvocation *context)
1996 {
1997         FN_START;
1998         int msg_id = 0;
1999         int folder_id;
2000         int del_folder_id;
2001         gchar *folder_name = NULL;
2002         guint64 map_id;
2003         GError *error = NULL;
2004         msg_error_t err;
2005         msg_struct_t msg = NULL;
2006         msg_struct_t send_opt = NULL;
2007
2008         msg_id = __bt_get_uid(handle);
2009         if (msg_id == -1)
2010                 goto fail;
2011
2012         if (g_msg_handle == NULL)
2013                 goto fail;
2014
2015         msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
2016         if (msg == NULL)
2017                 goto fail;
2018
2019         send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
2020         if (send_opt == NULL)
2021                 goto fail;
2022
2023         err = msg_get_message(g_msg_handle,
2024                                         (msg_message_id_t)msg_id,
2025                                         msg, send_opt);
2026         if (err != MSG_SUCCESS)
2027                 goto fail;
2028
2029         err = msg_get_int_value(msg, MSG_MESSAGE_FOLDER_ID_INT,
2030                                                         &folder_id);
2031         if (err != MSG_SUCCESS)
2032                 goto fail;
2033
2034         folder_name = __bt_get_folder_name(folder_id);
2035         del_folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME);
2036         map_id = __bt_validate_uid(msg_id);
2037
2038         DBG("msg_id = %d, delete_status = %d\n", msg_id, delete_status);
2039
2040         if (-1 == del_folder_id) {
2041                 ERR("Delete folder not present");
2042                 if (delete_status == TRUE) {
2043                         err = msg_delete_message(g_msg_handle, msg_id);
2044                         if (err != MSG_SUCCESS)
2045                                 goto fail;
2046                 }
2047
2048         } else {
2049                 if (delete_status == TRUE) {
2050                         err = msg_move_msg_to_folder(g_msg_handle, msg_id, del_folder_id);
2051                         if (err == MSG_SUCCESS) {
2052                                 __bt_mns_client_event_notify("MessageShift",
2053                                                 map_id,
2054                                                 "TELECOM/MSG/DELETED",
2055                                                 folder_name,
2056                                                 "SMS_GSM");
2057                         }
2058                 } else {
2059                         if (folder_id != del_folder_id) {
2060                                 DBG("Message not in delete folder");
2061                                 goto fail;
2062                         }
2063
2064                         err = msg_move_msg_to_folder(g_msg_handle, msg_id, MSG_INBOX_ID);
2065                         if (err == MSG_SUCCESS) {
2066                                 __bt_mns_client_event_notify("MessageShift",
2067                                                 map_id,
2068                                                 "TELECOM/MSG/INBOX",
2069                                                 "TELECOM/MSG/DELETED",
2070                                                 "SMS_GSM");
2071                         }
2072                 }
2073         }
2074
2075         g_free(folder_name);
2076         msg_release_struct(&msg);
2077         msg_release_struct(&send_opt);
2078         dbus_g_method_return(context);
2079         FN_END;
2080         return TRUE;
2081
2082 fail:
2083         g_free(folder_name);
2084
2085         msg_release_struct(&msg);
2086         msg_release_struct(&send_opt);
2087
2088         error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
2089                                                         "InternalError");
2090         dbus_g_method_return_error(context, error);
2091         g_error_free(error);
2092         ERR("fail -\n");
2093         return FALSE;
2094 }
2095
2096 static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent,
2097                                                 gchar *remote_addr,
2098                                                 gboolean status,
2099                                                 DBusGMethodInvocation *context)
2100 {
2101         FN_START;
2102         DBG_SECURE("remote_addr = %s \n", remote_addr);
2103
2104         if (status == TRUE)
2105                 __bt_mns_client_connect(remote_addr);
2106         else
2107                 __bt_mns_client_disconnect();
2108
2109         return TRUE;
2110 }
2111
2112 static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent,
2113                                         DBusGMethodInvocation *context)
2114 {
2115         FN_START;
2116         g_main_loop_quit(g_mainloop);
2117         return TRUE;
2118 }
2119
2120 int main(void)
2121 {
2122         FN_START;
2123         BluetoothMapAgent *bluetooth_map_obj = NULL;
2124         DBusGProxy *bus_proxy = NULL;
2125         guint result = 0;
2126         int ret;
2127         GError *error = NULL;
2128         DBG("Starting Bluetooth MAP agent");
2129
2130         g_mainloop = g_main_loop_new(NULL, FALSE);
2131
2132         if (g_mainloop == NULL) {
2133                 ERR("Couldn't create GMainLoop\n");
2134                 return EXIT_FAILURE;
2135         }
2136
2137         g_connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
2138
2139         if (error != NULL) {
2140                 ERR("Couldn't connect to system bus[%s]\n", error->message);
2141                 g_error_free(error);
2142                 return EXIT_FAILURE;
2143         }
2144
2145         bus_proxy = dbus_g_proxy_new_for_name(g_connection, DBUS_SERVICE_DBUS,
2146                                                 DBUS_PATH_DBUS,
2147                                                 DBUS_INTERFACE_DBUS);
2148         if (bus_proxy == NULL) {
2149                 ERR("Failed to get a proxy for D-Bus\n");
2150                 goto failure;
2151         }
2152
2153         if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING,
2154                                         BT_MAP_SERVICE_NAME, G_TYPE_UINT, 0,
2155                                         G_TYPE_INVALID, G_TYPE_UINT, &result,
2156                                         G_TYPE_INVALID)) {
2157                 if (error != NULL) {
2158                         ERR("RequestName RPC failed[%s]\n", error->message);
2159                         g_error_free(error);
2160                 }
2161                 goto failure;
2162         }
2163
2164         if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
2165                 ERR("Failed to get the primary well-known name.\n");
2166                 goto failure;
2167         }
2168
2169         g_object_unref(bus_proxy);
2170         bus_proxy = NULL;
2171
2172         bluetooth_map_obj = g_object_new(BLUETOOTH_MAP_TYPE_AGENT, NULL);
2173
2174         /* Registering it on the D-Bus */
2175         dbus_g_connection_register_g_object(g_connection,
2176                                                 BT_MAP_SERVICE_OBJECT_PATH,
2177                                                 G_OBJECT(bluetooth_map_obj));
2178
2179         if (__bluetooth_map_start_service() == FALSE)
2180                 goto failure;
2181
2182         g_tapi_handle = tel_init(NULL);
2183         if (!g_tapi_handle)
2184                 goto failure;
2185
2186         ret = tel_get_sms_sca(g_tapi_handle, 0, __bt_get_sms_sca, NULL);
2187         if (ret != TAPI_API_SUCCESS) {
2188                 ERR("TAPI err = %d", ret);
2189                 goto failure;
2190         }
2191
2192         g_main_loop_run(g_mainloop);
2193
2194  failure:
2195
2196         __bt_remove_list(id_list);
2197
2198         tel_deinit(g_tapi_handle);
2199         g_free(g_sca_info);
2200
2201         __bt_mns_client_disconnect();
2202
2203         if (bus_proxy)
2204                 g_object_unref(bus_proxy);
2205         if (bluetooth_map_obj)
2206                 g_object_unref(bluetooth_map_obj);
2207         if (g_connection)
2208                 dbus_g_connection_unref(g_connection);
2209
2210         __bluetooth_map_stop_service();
2211         DBG("Bluetooth MAP agent Terminated successfully\n");
2212         FN_END;
2213         return EXIT_FAILURE;
2214 }