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