4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
29 #include <dbus/dbus-glib.h>
30 #include <dbus/dbus.h>
33 #include "vconf-keys.h"
35 #include <sys/types.h>
38 /*Messaging Header Files*/
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"
47 #include <TapiUtility.h>
48 #include <ITapiNetText.h>
49 #include <bluetooth_map_agent.h>
50 #include <map_bmessage.h>
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"
56 #define MNS_CLIENT_INTERFACE "org.openobex.MessageNotification"
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))
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, \
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;
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
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"
110 GSList *id_list = NULL;
111 guint64 current_push_map_id;
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;
129 struct msg_send_option {
135 struct message_info {
140 char *sender_addressing;
141 char *recipient_name;
142 char *recipient_addressing;
145 char *reception_status;
146 char *attachment_size;
147 char *replyto_addressing;
161 } BluetoothMapAgentClass;
163 GType bluetooth_map_agent_get_type(void);
165 #define BLUETOOTH_MAP_TYPE_AGENT (bluetooth_map_agent_get_type())
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))
183 G_DEFINE_TYPE(BluetoothMapAgent, bluetooth_map_agent, G_TYPE_OBJECT)
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;
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,
197 gboolean attach, gboolean transcode,
198 gboolean first_request,
199 DBusGMethodInvocation *context);
200 static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent,
205 DBusGMethodInvocation *context);
206 static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
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,
220 DBusGMethodInvocation *context);
221 static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent,
222 DBusGMethodInvocation *context);
224 #include "bluetooth_map_agent_glue.h"
226 static void bluetooth_map_agent_init(BluetoothMapAgent *obj)
229 g_assert(obj != NULL);
233 static void bluetooth_map_agent_finalize(GObject *obj)
236 G_OBJECT_CLASS(bluetooth_map_agent_parent_class)->finalize(obj);
240 static void bluetooth_map_agent_class_init(BluetoothMapAgentClass *klass)
243 GObjectClass *object_class = (GObjectClass *) klass;
245 g_assert(klass != NULL);
247 object_class->finalize = bluetooth_map_agent_finalize;
249 dbus_g_object_type_install_info(BLUETOOTH_MAP_TYPE_AGENT,
250 &dbus_glib_bluetooth_map_object_info);
254 static GQuark __bt_map_agent_error_quark(void)
257 static GQuark quark = 0;
259 quark = g_quark_from_static_string("agent");
265 static GError *__bt_map_agent_error(bt_map_agent_error_t error,
269 return g_error_new(BT_MAP_AGENT_ERROR, error, err_msg, NULL);
272 static void __bt_mns_client_event_notify(gchar *event, guint64 handle,
273 gchar *folder, gchar *old_folder,
276 static char *__bt_get_truncated_utf8_string(char *src)
281 char dest[BT_MAP_SUBJECT_MAX_LEN] = {0,};
288 while (*p != '\0' && i < sizeof(dest)) {
289 next = g_utf8_next_char(p);
292 while (count > 0 && ((i + count) < sizeof(dest))) {
301 return g_strdup(dest);
304 static guint64 __bt_validate_uid(int uid)
307 struct id_info *info;
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);
317 if (info->uid == uid) {
318 DBG("uid = %d\n", uid);
327 static guint64 __bt_add_id(int uid)
330 static guint64 map_id;
331 struct id_info *info;
334 DBG("Add id: %d\n", uid);
335 test = __bt_validate_uid(uid);
336 DBG("test: %llx\n", test);
340 info = g_new0(struct id_info, 1);
344 info->map_id = map_id;
346 DBG("map_id = %llx, uid = %d \n", info->map_id, info->uid);
348 id_list = g_slist_append(id_list, info);
354 static int __bt_get_id(guint64 map_id)
357 struct id_info *info;
361 count = g_slist_length(id_list);
363 for (i = 0; i < count; i++) {
364 info = (struct id_info *)g_slist_nth_data(id_list, i);
366 if (info->map_id == map_id)
374 static int __bt_get_uid(gchar *handle)
383 map_id = g_ascii_strtoull(handle, NULL, 16);
387 uid = __bt_get_id(map_id);
393 static int __bt_update_id(guint64 map_id, int new_uid)
396 struct id_info *info;
400 count = g_slist_length(id_list);
402 for (i = 0; i < count; i++) {
403 info = g_slist_nth_data(id_list, i);
405 if (info->map_id == map_id) {
415 static void __bt_remove_list(GSList *id_list)
421 DBG("Removing id list\n");
422 g_slist_free_full(id_list, g_free);
426 static int __bt_get_folder_id(char *folder_path)
432 msg_struct_list_s folder_list = {0,};
434 msg_struct_t p_folder;
435 DBG_SECURE("folder_path %s\n", folder_path);
437 folder = strrchr(folder_path, '/');
439 folder = folder_path;
443 err = msg_get_folder_list(g_msg_handle, &folder_list);
444 if (err != MSG_SUCCESS)
447 for (i = 0; i < folder_list.nCount; i++) {
448 char folder_name[BT_MAP_MSG_INFO_MAX] = {0, };
450 p_folder = folder_list.msg_struct_info[i];
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)
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,
462 if (err != MSG_SUCCESS)
465 DBG("folder_id %d", folder_id);
471 if (folder_list.msg_struct_info)
472 msg_release_list_struct(&folder_list);
479 static void __bt_add_deleted_folder(void)
483 msg_struct_t folder_info = msg_create_struct(MSG_STRUCT_FOLDER_INFO);
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);
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);
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);
508 msg_release_struct(&folder_info);
512 static gchar *__bt_get_folder_name(int id)
518 gboolean path_found = FALSE;
519 char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
521 msg_struct_list_s folder_list = {0,};
522 msg_struct_t p_folder;
524 ret = msg_get_folder_list(g_msg_handle, &folder_list);
525 if (ret != MSG_SUCCESS)
526 return g_strdup("TELECOM/MSG");
528 if (folder_list.msg_struct_info == NULL)
529 return g_strdup("TELECOM/MSG");
531 for (i = 0; i < folder_list.nCount; i++) {
532 p_folder = folder_list.msg_struct_info[i];
534 ret = msg_get_int_value(p_folder,
535 MSG_FOLDER_INFO_ID_INT,
537 if (ret != MSG_SUCCESS)
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)
548 DBG_SECURE("folder_name %s", folder_name);
553 if (folder_list.msg_struct_info) {
554 ret = msg_release_list_struct(&folder_list);
559 if (path_found != TRUE)
560 return g_strdup("TELECOM/MSG");
562 return g_strdup_printf("TELECOM/MSG/%s", folder_name);
565 static void __get_msg_timestamp(time_t *ltime, char *timestamp)
568 struct tm local_time;
572 if (!localtime_r(ltime, &local_time))
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);
585 #define SET_TON_NPI(dest, ton, npi) { \
587 dest |= (ton & 0x07) << 4; \
588 dest |= npi & 0x0F; \
591 static int __bt_ascii_to_upper(int ch)
593 return (('a' <= (ch) && (ch) <= 'z') ? ((ch) - ('a'-'A')) : (ch));
596 static int __bt_sms_pack_gsm_code(gchar *p_out, const char *data, int in_len)
603 for (pos = 0, i = 0; i < in_len; pos++, i++) {
604 /* pack the low bits */
605 p_out[pos] = data[i] >> shift;
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);
625 static void __bt_sms_conv_digit_to_bcd(gchar *p_bcd, char *p_digits, int digit_len)
631 unsigned char higher;
634 if (p_bcd == NULL || p_digits == NULL)
637 /* 0123456789 -> 1032547698 */
638 for (i = 0, j = 0; i < digit_len; i = i + 2, j++) {
639 if (p_digits[i] == '*')
641 else if (p_digits[i] == '#')
643 else if (__bt_ascii_to_upper(p_digits[i]) == 'P')
646 digit = (int) (p_digits[i] - '0');
648 lower = digit & 0x0F;
650 if (digit_len != i + 1) {
651 if (p_digits[i+1] == '*')
653 else if (p_digits[i+1] == '#')
655 else if (__bt_ascii_to_upper(p_digits[i+1]) == 'P')
658 digit = (int) (p_digits[i+1] - '0');
660 higher = digit & 0x0F;
665 p_bcd[j] = (higher << 4) | lower;
670 static int __bt_sms_encode_addr(gchar *addr_field, char *dial_num,
671 int dial_num_len, int ton, int npi)
676 if (dial_num == NULL || addr_field == NULL)
679 if (dial_num[0] == '+') {
682 ton = SMS_TON_INTERNATIONAL;
685 if (ton != SMS_TON_ALPHA_NUMERIC) {
686 /* Origination address length address length */
687 addr_field[index++] = (unsigned char)dial_num_len;
689 addr_field[index] = (unsigned char)
690 (((dial_num_len * 7 + 7) / 8) * 2);
692 if (((dial_num_len * 7) % 8) <= 4)
698 SET_TON_NPI(addr_field[index], ton, npi);
699 index++; /* SET_TON_NPI */
701 if (ton != SMS_TON_ALPHA_NUMERIC) {
702 __bt_sms_conv_digit_to_bcd(&addr_field[index],
703 (char *)dial_num, dial_num_len);
705 if (dial_num_len % 2)
706 index += (dial_num_len / 2) + 1;
708 index += dial_num_len / 2;
710 index += __bt_sms_pack_gsm_code(&addr_field[index],
711 dial_num, (int)dial_num_len);
718 static int __bt_sms_encode_time(gchar *addr_field, time_t *tm)
726 if (!localtime_r(tm, <ime))
729 year = ltime.tm_year + 1900; /* years since 1900 */
731 month = ltime.tm_mon + 1; /* months since January */
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;
747 static gchar *__bt_get_sms_pdu_from_msg_data(gchar *number,
748 char *msg, time_t tm,
752 gchar packet[TAPI_NETTEXT_MSG_SIZE_MAX] = {0,};
755 packet[index] = 0x00; /* Since SCA is unknown for stored messages */
758 /* TP-MTI : Type of message */
759 packet[index] = 0x00; /* SMS-DELIVER PDU */
761 /* TP-MMS bit is set to 1 as we support only SMS */
762 packet[index] |= 0x04;
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);
770 /* TP-PID : Since we use only SMS so set to 0 */
771 packet[index++] = 0x00;
773 /* TP-DCS : Data Coding Scheme, default value set */
774 packet[index++] = 0x00;
776 /* TP-SCTS : Message timestamp */
777 index += __bt_sms_encode_time(packet+index, &tm);
779 /* TP-UDL : Message body length */
780 packet[index++] = strlen(msg);
782 /* TP-UD : Message body */
783 index += __bt_sms_pack_gsm_code(packet + index, msg, strlen(msg));
785 *msg_pdu_len = index;
788 return g_memdup(packet, index);
791 static void __bt_get_sms_sca(TapiHandle *handle, int result, void *data,
795 TelSmsAddressInfo_t *scaInfo = data;
797 DBG("__bt_get_sms_sca 0x%x", result);
800 g_sca_info = g_malloc0(sizeof(TelSmsAddressInfo_t));
803 g_sca_info->DialNumLen = 0;
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;
814 static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach,
819 int m_type = MSG_TYPE_SMS;
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,};
829 msg_list_handle_t addr_list = NULL;
830 msg_struct_t addr_info = NULL;
833 gchar *folder_path = NULL;
836 msg = g_string_new(BEGIN_BMSEG);
837 g_string_append(msg, BMSEG_VERSION);
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);
845 g_string_append_printf(msg, MSEG_STATUS, "READ");
847 g_string_append_printf(msg, MSEG_STATUS, "UNREAD");
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");
855 ret = msg_get_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
857 if (ret == MSG_SUCCESS) {
858 DBG("folder_id %d\n", folder_id);
860 folder_path = __bt_get_folder_name(folder_id);
861 g_string_append_printf(msg, FOLDER_PATH, folder_path);
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);
871 addr_info = (msg_struct_t)msg_list_nth_data(addr_list,
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);
884 DBG_SECURE("name_value %s\n", name_value);
886 g_string_append_printf(msg, VCARD, name_value,
891 g_string_append(msg, BEGIN_BENV);
892 g_string_append(msg, BEGIN_BBODY);
895 g_string_append_printf(msg, CHARSET, "UTF-8");
898 ret = msg_get_str_value(msg_info,
899 MSG_MESSAGE_SMS_DATA_STR,
900 msg_body, BT_MAP_MSG_BODY_MAX);
901 if (ret == MSG_SUCCESS) {
902 g_string_append_printf(msg, LENGTH, (int)strlen(msg_body));
903 g_string_append_printf(msg, MSG_BODY, msg_body);
906 g_string_append_printf(msg, ENCODING, "G-7BIT");
907 g_string_append_printf(msg, CHARSET, "native");
909 msg_get_int_value(msg_info,
910 MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
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) {
916 msg_pdu = __bt_get_sms_pdu_from_msg_data(addr_value,
920 DBG("msg_pdu_len = %d", msg_pdu_len);
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",
928 g_string_append(msg, MSG_BODY_END);
934 g_string_append(msg, END_BBODY);
935 g_string_append(msg, END_BENV);
936 g_string_append(msg, END_BMSEG);
940 return g_string_free(msg, FALSE);
943 static void __bt_message_info_free(struct message_info msg_info)
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);
961 static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle)
964 struct message_info msg_info = {0,};
974 bool protect_status = 0;
975 bool read_status = 0;
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,};
984 msg_info.text = FALSE;
985 msg_info.protect = FALSE;
986 msg_info.read = FALSE;
987 msg_info.priority = FALSE;
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;
994 ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_ID_INT, &msg_id);
995 if (ret == MSG_SUCCESS) {
996 uid = __bt_add_id(msg_id);
997 snprintf(msg_handle, sizeof(msg_handle), "%llx", (long long unsigned int)uid);
999 msg_info.handle = g_strdup(msg_handle);
1001 msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
1005 send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
1006 if (send_opt == NULL)
1009 ret = msg_get_message(g_msg_handle,
1010 (msg_message_id_t)msg_id,
1012 if (ret != MSG_SUCCESS) {
1013 DBG("ret = %d\n", ret);
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);
1024 count = msg_list_length(addr_list);
1027 addr_info = (msg_struct_t)msg_list_nth_data(addr_list, 0);
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);
1035 ret = msg_get_str_value(addr_info,
1036 MSG_ADDRESS_INFO_DISPLAYNAME_STR,
1037 name_value, MAX_DISPLAY_NAME_LEN);
1039 if (ret == MSG_SUCCESS)
1040 DBG_SECURE("name_value %s\n", name_value);
1042 if (!strlen(name_value))
1043 g_stpcpy(name_value, addr_value);
1045 DBG_SECURE("name_value %s\n", name_value);
1048 ret = msg_get_int_value(msg, MSG_MESSAGE_DIRECTION_INT,
1050 if (ret != MSG_SUCCESS)
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");
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);
1066 msg_release_struct(&msg);
1067 msg_release_struct(&send_opt);
1069 ret = msg_get_int_value(msg_struct_handle,
1070 MSG_MESSAGE_DISPLAY_TIME_INT, &dptime);
1071 if (ret == MSG_SUCCESS) {
1072 __get_msg_timestamp((time_t *)&dptime, msg_datetime);
1074 msg_info.datetime = g_strdup(msg_datetime);
1076 ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_TYPE_INT,
1078 if (ret == MSG_SUCCESS) {
1079 DBG("m_type %d\n", m_type);
1082 msg_info.type = g_strdup("SMS_GSM");
1084 ret = msg_get_str_value(msg_struct_handle,
1085 MSG_MESSAGE_SMS_DATA_STR, msg_body,
1086 BT_MAP_MSG_BODY_MAX);
1087 if (ret == MSG_SUCCESS) {
1088 DBG_SECURE("SMS subject %s", msg_body);
1089 if (strlen(msg_body)) {
1090 msg_info.text = TRUE ;
1091 msg_info.subject = __bt_get_truncated_utf8_string(msg_body);
1095 ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_DATA_SIZE_INT,
1097 if (ret == MSG_SUCCESS)
1098 snprintf(msg_size, sizeof(msg_size), "%d", data_size);
1100 msg_info.size = g_strdup(msg_size);
1102 msg_info.reception_status = g_strdup("complete");
1103 msg_info.attachment_size = g_strdup("0");
1105 ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_PROTECTED_BOOL,
1107 if (ret == MSG_SUCCESS) {
1109 msg_info.protect = TRUE;
1112 ret = msg_get_bool_value(msg_struct_handle, MSG_MESSAGE_READ_BOOL,
1114 if (ret == MSG_SUCCESS) {
1116 msg_info.read = TRUE;
1119 ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_PRIORITY_INT,
1121 if (ret == MSG_SUCCESS) {
1122 if (priority == MSG_MESSAGE_PRIORITY_HIGH)
1123 msg_info.priority = TRUE;
1130 static void __bluetooth_map_msg_incoming_status_cb(msg_handle_t handle,
1142 INFO("MNS Client not connected");
1146 ret = msg_get_int_value(msg, MSG_MESSAGE_TYPE_INT, &msg_type);
1147 if (ret != MSG_SUCCESS)
1150 if (msg_type != MSG_TYPE_SMS) {
1155 ret = msg_get_int_value(msg, MSG_MESSAGE_ID_INT, &msg_id);
1156 if (ret != MSG_SUCCESS)
1159 uid = __bt_add_id(msg_id);
1161 __bt_mns_client_event_notify("NewMessage", uid,
1162 "TELECOM/MSG/INBOX", "",
1169 static void __bluetooth_map_msg_sent_status_cb(msg_handle_t handle,
1178 INFO("MNS Client not connected");
1182 ret = msg_get_int_value(msg, MSG_SENT_STATUS_NETWORK_STATUS_INT,
1184 if (ret != MSG_SUCCESS)
1187 if (status == MSG_NETWORK_SEND_SUCCESS) {
1188 INFO("MSG SENT SUCCESS !!! ");
1189 __bt_mns_client_event_notify("MessageShift",
1190 current_push_map_id,
1192 "TELECOM/MSG/OUTBOX",
1195 __bt_mns_client_event_notify("SendingSuccess",
1196 current_push_map_id,
1197 "TELECOM/MSG/SENT", "",
1200 ERR("MSG SENT FAIL !!! [%d]", status);
1201 __bt_mns_client_event_notify("SendingFailure",
1202 current_push_map_id,
1203 "TELECOM/MSG/OUTBOX", "",
1211 static gboolean __bluetooth_map_start_service()
1216 err = msg_open_msg_handle(&g_msg_handle);
1217 if (err != MSG_SUCCESS) {
1218 ERR("msg_open_msg_handle error = %d\n", err);
1222 if (-1 == __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME))
1223 __bt_add_deleted_folder();
1225 err = msg_reg_sms_message_callback(g_msg_handle,
1226 __bluetooth_map_msg_incoming_status_cb,
1227 0, (void *)BT_MAP_MSG_CB);
1228 if (err != MSG_SUCCESS) {
1229 ERR("msg_reg_sms_message_callback error = %d\n", err);
1233 err = msg_reg_sent_status_callback(g_msg_handle,
1234 __bluetooth_map_msg_sent_status_cb,
1236 if (err != MSG_SUCCESS) {
1237 ERR("msg_reg_sent_status_callback error = %d\n", err);
1245 static void __bluetooth_map_stop_service()
1248 msg_error_t err = MSG_SUCCESS;
1251 folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME);
1252 if (-1 != folder_id) {
1253 err = msg_delete_folder(g_msg_handle, folder_id);
1254 if (err != MSG_SUCCESS)
1255 ERR("Delete folder failed");
1258 if (NULL != g_msg_handle)
1259 msg_close_msg_handle(&g_msg_handle);
1261 g_msg_handle = NULL;
1267 static gboolean __bt_validate_utf8(char **text)
1270 if (g_utf8_validate(*text, -1, NULL))
1277 static gboolean __bt_validate_msg_data(struct message_info *msg_info)
1280 if (msg_info == NULL)
1283 if (msg_info->subject)
1284 return __bt_validate_utf8(&msg_info->subject);
1286 if (msg_info->sender_name)
1287 return __bt_validate_utf8(&msg_info->sender_name);
1289 if (msg_info->sender_addressing)
1290 return __bt_validate_utf8(&msg_info->sender_addressing);
1292 if (msg_info->replyto_addressing)
1293 return __bt_validate_utf8(&msg_info->replyto_addressing);
1295 if (msg_info->recipient_name)
1296 return __bt_validate_utf8(&msg_info->recipient_name);
1298 if (msg_info->recipient_addressing)
1299 return __bt_validate_utf8(&msg_info->recipient_addressing);
1305 msg_error_t __bt_send_sms(int msg_id, msg_struct_t p_msg, msg_struct_t p_send_opt)
1311 p_req = msg_create_struct(MSG_STRUCT_REQUEST_INFO);
1313 msg_set_int_value(p_msg, MSG_MESSAGE_ID_INT, msg_id);
1314 msg_set_struct_handle(p_req, MSG_REQUEST_MESSAGE_HND, p_msg);
1315 msg_set_struct_handle(p_req, MSG_REQUEST_SENDOPT_HND, p_send_opt);
1317 err = msg_sms_send_message(g_msg_handle, p_req);
1318 if (err != MSG_SUCCESS)
1319 ERR("Failed msg_sms_send_message %d", err);
1321 msg_release_struct(&p_req);
1326 static int __bt_push_sms(gboolean send, int folder_id, char *body,
1330 msg_struct_t msg_info = NULL;
1331 msg_struct_t send_opt = NULL;
1338 msg_info = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
1339 if (msg_info == NULL)
1342 err = msg_set_int_value(msg_info, MSG_MESSAGE_TYPE_INT, MSG_TYPE_SMS);
1343 if (err != MSG_SUCCESS)
1347 err = msg_set_str_value(msg_info,
1348 MSG_MESSAGE_SMS_DATA_STR,
1349 body, strlen(body));
1350 if (err != MSG_SUCCESS)
1353 err = msg_set_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR,
1355 if (err != MSG_SUCCESS)
1359 DBG("folder_id %d\n", folder_id);
1360 err = msg_set_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT,
1362 if (err != MSG_SUCCESS)
1366 count = g_slist_length(recepients);
1367 DBG("Count = %d\n", count);
1369 for (i = 0; i < count; i++) {
1370 msg_struct_t tmp_addr;
1371 char *address = (char *)g_slist_nth_data(recepients, i);
1372 if (address == NULL) {
1373 ERR("[ERROR] address is value NULL, skip");
1376 msg_list_add_item(msg_info,
1377 MSG_MESSAGE_ADDR_LIST_HND, &tmp_addr);
1379 msg_set_int_value(tmp_addr,
1380 MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT,
1381 MSG_RECIPIENTS_TYPE_TO);
1383 msg_set_str_value(tmp_addr,
1384 MSG_ADDRESS_INFO_ADDRESS_VALUE_STR,
1385 address, strlen(address));
1389 send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
1391 err = msg_set_bool_value(send_opt, MSG_SEND_OPT_SETTING_BOOL, true);
1392 if (err != MSG_SUCCESS)
1395 /* Do not keep a copy */
1396 err = msg_set_bool_value(send_opt, MSG_SEND_OPT_KEEPCOPY_BOOL,
1398 if (err != MSG_SUCCESS)
1401 msg_id = msg_add_message(g_msg_handle, msg_info, send_opt);
1402 DBG("msg_id = %d\n", msg_id);
1405 __bt_send_sms(msg_id, msg_info, send_opt);
1409 msg_release_struct(&msg_info);
1410 msg_release_struct(&send_opt);
1415 static void __bt_mns_client_connect(char *address)
1420 GError *error = NULL;
1421 const char *session_path = NULL;
1424 DBG_SECURE("MNS Client already connected to %s", address);
1428 g_mns_proxy = dbus_g_proxy_new_for_name(g_connection,
1429 OBEX_CLIENT_SERVICE,
1431 OBEX_CLIENT_INTERFACE);
1433 ERR("Failed to get a proxy for D-Bus\n");
1437 hash = g_hash_table_new_full(g_str_hash, g_str_equal,
1438 NULL, (GDestroyNotify)g_free);
1440 tgt_value = g_new0(GValue, 1);
1441 g_value_init(tgt_value, G_TYPE_STRING);
1442 g_value_set_string(tgt_value, "MNS");
1443 g_hash_table_insert(hash, "Target", tgt_value);
1445 dbus_g_proxy_call(g_mns_proxy, "CreateSession", &error,
1446 G_TYPE_STRING,address,
1447 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
1448 hash, G_TYPE_INVALID,
1449 DBUS_TYPE_G_OBJECT_PATH, &session_path,
1452 ERR("Error [%s]", error->message);
1453 g_error_free(error);
1454 g_hash_table_destroy(hash);
1455 g_object_unref(g_mns_proxy);
1460 g_mns_path = g_strdup(session_path);
1461 DBG("g_mns_path = %s\n", g_mns_path);
1463 g_hash_table_destroy(hash);
1469 static void __bt_mns_client_disconnect()
1472 GError *error = NULL;
1475 ERR("No proxy to disconnect");
1479 dbus_g_proxy_call(g_mns_proxy, "RemoveSession", &error,
1480 DBUS_TYPE_G_OBJECT_PATH, g_mns_path,
1481 G_TYPE_INVALID, G_TYPE_INVALID);
1483 ERR("Error [%s]", error->message);
1484 g_error_free(error);
1490 g_object_unref(g_mns_proxy);
1497 static void __bt_mns_client_event_notify(gchar *event, guint64 handle,
1498 gchar *folder, gchar *old_folder,
1502 GError *error = NULL;
1503 DBusGProxy *mns_proxy;
1506 ERR("No client proxy");
1510 mns_proxy = dbus_g_proxy_new_for_name(g_connection,
1511 OBEX_CLIENT_SERVICE,
1513 MNS_CLIENT_INTERFACE);
1514 if (mns_proxy == NULL) {
1515 ERR("Failed to get a proxy for D-Bus\n");
1519 dbus_g_proxy_call(mns_proxy, "SendEvent", &error,
1520 G_TYPE_STRING, event,
1521 G_TYPE_UINT64, handle,
1522 G_TYPE_STRING, folder,
1523 G_TYPE_STRING, old_folder,
1524 G_TYPE_STRING, msg_type,
1525 G_TYPE_INVALID, G_TYPE_INVALID);
1527 ERR("Error [%s]", error->message);
1528 g_error_free(error);
1531 g_object_unref(mns_proxy);
1535 static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent,
1536 DBusGMethodInvocation *context)
1539 GPtrArray *array = g_ptr_array_new();
1541 GError *error = NULL;
1543 char name[BT_MAP_MSG_INFO_MAX] = {0,};
1544 char folder_name[BT_MAP_MSG_INFO_MAX] = {0,};
1547 gboolean msg_ret = TRUE;
1549 msg_struct_list_s folder_list = {0,};
1550 msg_struct_t p_folder;
1552 if (g_msg_handle == NULL) {
1557 if (msg_get_folder_list(g_msg_handle, &folder_list) != MSG_SUCCESS) {
1562 for (i = 0; i < folder_list.nCount; i++) {
1563 p_folder = folder_list.msg_struct_info[i];
1564 memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX);
1566 ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
1567 folder_name, BT_MAP_MSG_INFO_MAX);
1568 if (ret != MSG_SUCCESS)
1571 if (g_strstr_len(folder_name, -1, BT_MAP_MSG_TEMPLATE))
1574 if (!g_ascii_strncasecmp(folder_name, BT_MAP_SENT_FOLDER_NAME,
1575 strlen(BT_MAP_SENT_FOLDER_NAME))) {
1576 memset(folder_name, 0, sizeof(folder_name));
1577 g_strlcpy(folder_name, BT_MAP_SENT_FOLDER_NAME,
1578 sizeof(folder_name));
1581 g_strlcpy(name, folder_name, sizeof(name));
1582 memset(&value, 0, sizeof(GValue));
1583 g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT);
1584 g_value_take_boxed(&value, dbus_g_type_specialized_construct(
1585 DBUS_STRUCT_STRING_STRING_UINT));
1586 dbus_g_type_struct_set(&value, 0, name, G_MAXUINT);
1587 g_ptr_array_add(array, g_value_get_boxed(&value));
1592 if (folder_list.msg_struct_info)
1593 msg_release_list_struct(&folder_list);
1595 if (msg_ret == FALSE) {
1596 g_ptr_array_free(array, TRUE);
1598 error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1600 dbus_g_method_return_error(context, error);
1601 g_error_free(error);
1604 dbus_g_method_return(context, array);
1605 g_ptr_array_free(array, TRUE);
1611 static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent,
1612 gchar *folder_name, guint16 max,
1613 DBusGMethodInvocation *context)
1616 GPtrArray *array = g_ptr_array_new();
1618 GError *error = NULL;
1620 char *folder = NULL;
1627 gboolean newmsg = FALSE;
1629 msg_struct_list_s folder_list = {0,};
1630 msg_struct_list_s msg_list = {0,};
1631 msg_struct_t list_cond;
1633 if (g_msg_handle == NULL)
1639 folder_len = strlen(folder_name);
1640 /* In case of parent folders send empty message listing */
1641 if (!g_ascii_strncasecmp(folder_name, "/", folder_len) ||
1642 !g_ascii_strncasecmp(folder_name, "/telecom", folder_len) ||
1643 !g_ascii_strncasecmp(folder_name, "/telecom/msg", folder_len))
1646 folder = strrchr(folder_name, '/');
1648 folder = folder_name;
1652 ret = msg_get_folder_list(g_msg_handle, &folder_list);
1653 if (ret != MSG_SUCCESS)
1656 for (i = 0; i < folder_list.nCount; i++) {
1657 char f_name[BT_MAP_MSG_INFO_MAX] = {0, };
1658 msg_struct_t p_folder = folder_list.msg_struct_info[i];
1660 ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR,
1661 f_name, BT_MAP_MSG_INFO_MAX);
1662 if (ret != MSG_SUCCESS)
1665 if (!g_ascii_strncasecmp(f_name, folder, strlen(folder))) {
1666 ret = msg_get_int_value(p_folder, MSG_FOLDER_INFO_ID_INT,
1668 if (ret != MSG_SUCCESS)
1671 DBG("folder_id %d \n", folder_id);
1677 if (folder_id == -1)
1680 list_cond = msg_create_struct(MSG_STRUCT_MSG_LIST_CONDITION);
1681 ret = msg_set_int_value(list_cond,
1682 MSG_LIST_CONDITION_FOLDER_ID_INT,
1684 if (ret != MSG_SUCCESS)
1687 ret = msg_set_int_value(list_cond,
1688 MSG_LIST_CONDITION_MSGTYPE_INT, MSG_TYPE_SMS);
1689 if (ret != MSG_SUCCESS)
1692 ret = msg_get_message_list2(g_msg_handle, list_cond, &msg_list);
1694 msg_release_struct(&list_cond);
1696 if (ret != MSG_SUCCESS)
1699 count = (guint64)msg_list.nCount;
1701 for (i = 0; i < count; i++) {
1702 msg_get_bool_value(msg_list.msg_struct_info[i],
1703 MSG_MESSAGE_READ_BOOL, &read);
1704 if (read == false) {
1710 DBG("count = %llx, newmsg = %d, max = %d", count, newmsg, max);
1715 for (i = 0; i < msg_list.nCount; i++) {
1717 struct message_info msg_info;
1719 memset(&value, 0, sizeof(GValue));
1720 g_value_init(&value, DBUS_STRUCT_MESSAGE_LIST);
1721 g_value_take_boxed(&value, dbus_g_type_specialized_construct(
1722 DBUS_STRUCT_MESSAGE_LIST));
1724 msg_info = __bt_message_info_get(msg_list.msg_struct_info[i]);
1726 if (!__bt_validate_msg_data(&msg_info)) {
1727 __bt_message_info_free(msg_info);
1732 dbus_g_type_struct_set(&value, 0, msg_info.handle,
1733 1, msg_info.subject,
1734 2, msg_info.datetime,
1735 3, msg_info.sender_name,
1736 4, msg_info.sender_addressing,
1737 5, msg_info.recipient_name,
1738 6, msg_info.recipient_addressing,
1741 9, msg_info.reception_status,
1743 11, msg_info.attachment_size,
1744 12, msg_info.priority,
1747 15, msg_info.protect,
1748 16, msg_info.replyto_addressing,
1750 g_ptr_array_add(array, g_value_get_boxed(&value));
1752 __bt_message_info_free(msg_info);
1756 if (folder_list.msg_struct_info)
1757 ret = msg_release_list_struct(&folder_list);
1759 if (msg_list.msg_struct_info)
1760 ret = msg_release_list_struct(&msg_list);
1762 dbus_g_method_return(context, newmsg, count, array);
1763 g_ptr_array_free(array, TRUE);
1768 if (folder_list.msg_struct_info)
1769 ret = msg_release_list_struct(&folder_list);
1771 if (msg_list.msg_struct_info)
1772 ret = msg_release_list_struct(&msg_list);
1774 g_ptr_array_free(array, TRUE);
1775 error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1777 dbus_g_method_return_error(context, error);
1778 g_error_free(error);
1783 static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent,
1784 gchar *message_name,
1787 gboolean first_request,
1788 DBusGMethodInvocation *context)
1794 GError *error = NULL;
1796 msg_error_t msg_err;
1797 msg_struct_t msg = NULL;
1798 msg_struct_t send_opt = NULL;
1800 message_id = __bt_get_uid(message_name);
1801 if (message_id == -1)
1804 DBG("message_id %d \n", message_id);
1805 DBG("attach %d \n", attach);
1806 DBG("transcode %d \n", transcode);
1807 DBG("first_request %d \n", first_request);
1809 if (g_msg_handle == NULL)
1812 msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
1816 send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
1820 msg_err = msg_get_message(g_msg_handle,
1821 (msg_message_id_t)message_id,
1823 if (msg_err != MSG_SUCCESS)
1826 buf = __bt_prepare_msg_bmseg(msg, attach, transcode);
1828 dbus_g_method_return(context, FALSE, buf);
1829 msg_release_struct(&msg);
1830 msg_release_struct(&send_opt);
1839 msg_release_struct(&msg);
1842 msg_release_struct(&send_opt);
1844 error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1846 dbus_g_method_return_error(context, error);
1847 g_error_free(error);
1852 static gboolean bluetooth_map_push_message(BluetoothMapAgent *agent,
1854 gboolean retry_send,
1857 DBusGMethodInvocation *context)
1862 DBG_SECURE("folder_name = %s\n", folder_name);
1864 handle = __bt_add_id(-1);
1865 current_push_map_id = handle;
1867 /* FALSE : Keep messages in Sent folder */
1868 /* TRUE : don't keep messages in sent folder */
1869 opt.save_copy = save_copy;
1870 DBG("opt.save_copy = %d\n", opt.save_copy);
1872 /* FALSE : don't retry */
1874 opt.retry_send = retry_send;
1875 DBG("opt.retry_send = %d\n", opt.retry_send);
1877 /* FALSE : native */
1879 opt.native = native;
1880 DBG("opt.native = %d\n", opt.native);
1882 dbus_g_method_return(context, handle);
1887 static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent,
1889 DBusGMethodInvocation *context)
1895 GSList *recepients = NULL;
1896 gboolean send = FALSE;
1898 GError *error = NULL;
1900 INFO("BMSG is \n %s", bmsg);
1902 struct bmsg_data *bmsg_info = NULL;
1904 bmsg_info = bmsg_parse(bmsg);
1908 folder_id = __bt_get_folder_id(bmsg_info->folder);
1909 if (folder_id == -1)
1912 if (MSG_OUTBOX_ID == folder_id)
1915 body = bmsg_get_msg_body(bmsg_info, opt.native);
1919 recepients = bmsg_get_msg_recepients(bmsg_info);
1921 id = __bt_push_sms(send, folder_id, body, recepients);
1925 __bt_update_id(current_push_map_id, id);
1929 g_slist_free(recepients);
1930 bmsg_free_bmsg(bmsg_info);
1933 error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1935 dbus_g_method_return_error(context, error);
1936 g_error_free(error);
1941 dbus_g_method_return(context);
1946 static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent,
1947 DBusGMethodInvocation *context)
1951 dbus_g_method_return(context, err);
1955 static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent,
1957 gboolean read_status,
1958 DBusGMethodInvocation *context)
1962 GError *error = NULL;
1963 msg_error_t msg_err;
1965 msg_id = __bt_get_uid(handle);
1969 DBG("msg_id = %d, read_status = %d\n", msg_id, read_status);
1971 msg_err = msg_update_read_status(g_msg_handle, msg_id,
1973 if (msg_err != MSG_SUCCESS)
1976 dbus_g_method_return(context);
1981 error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
1983 dbus_g_method_return_error(context, error);
1984 g_error_free(error);
1990 static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent,
1992 gboolean delete_status,
1993 DBusGMethodInvocation *context)
1999 gchar *folder_name = NULL;
2001 GError *error = NULL;
2003 msg_struct_t msg = NULL;
2004 msg_struct_t send_opt = NULL;
2006 msg_id = __bt_get_uid(handle);
2010 if (g_msg_handle == NULL)
2013 msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO);
2017 send_opt = msg_create_struct(MSG_STRUCT_SENDOPT);
2018 if (send_opt == NULL)
2021 err = msg_get_message(g_msg_handle,
2022 (msg_message_id_t)msg_id,
2024 if (err != MSG_SUCCESS)
2027 err = msg_get_int_value(msg, MSG_MESSAGE_FOLDER_ID_INT,
2029 if (err != MSG_SUCCESS)
2032 folder_name = __bt_get_folder_name(folder_id);
2033 del_folder_id = __bt_get_folder_id(BT_MAP_DELETED_FOLDER_NAME);
2034 map_id = __bt_validate_uid(msg_id);
2036 DBG("msg_id = %d, delete_status = %d\n", msg_id, delete_status);
2038 if (-1 == del_folder_id) {
2039 ERR("Delete folder not present");
2040 if (delete_status == TRUE) {
2041 err = msg_delete_message(g_msg_handle, msg_id);
2042 if (err != MSG_SUCCESS)
2047 if (delete_status == TRUE) {
2048 err = msg_move_msg_to_folder(g_msg_handle, msg_id, del_folder_id);
2049 if (err == MSG_SUCCESS) {
2050 __bt_mns_client_event_notify("MessageShift",
2052 "TELECOM/MSG/DELETED",
2057 if (folder_id != del_folder_id) {
2058 DBG("Message not in delete folder");
2062 err = msg_move_msg_to_folder(g_msg_handle, msg_id, MSG_INBOX_ID);
2063 if (err == MSG_SUCCESS) {
2064 __bt_mns_client_event_notify("MessageShift",
2066 "TELECOM/MSG/INBOX",
2067 "TELECOM/MSG/DELETED",
2073 g_free(folder_name);
2074 msg_release_struct(&msg);
2075 msg_release_struct(&send_opt);
2076 dbus_g_method_return(context);
2081 g_free(folder_name);
2083 msg_release_struct(&msg);
2084 msg_release_struct(&send_opt);
2086 error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL,
2088 dbus_g_method_return_error(context, error);
2089 g_error_free(error);
2094 static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent,
2097 DBusGMethodInvocation *context)
2100 DBG_SECURE("remote_addr = %s \n", remote_addr);
2103 __bt_mns_client_connect(remote_addr);
2105 __bt_mns_client_disconnect();
2110 static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent,
2111 DBusGMethodInvocation *context)
2114 g_main_loop_quit(g_mainloop);
2121 BluetoothMapAgent *bluetooth_map_obj = NULL;
2122 DBusGProxy *bus_proxy = NULL;
2125 GError *error = NULL;
2126 DBG("Starting Bluetooth MAP agent");
2128 g_mainloop = g_main_loop_new(NULL, FALSE);
2130 if (g_mainloop == NULL) {
2131 ERR("Couldn't create GMainLoop\n");
2132 return EXIT_FAILURE;
2135 g_connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
2137 if (error != NULL) {
2138 ERR("Couldn't connect to system bus[%s]\n", error->message);
2139 g_error_free(error);
2140 return EXIT_FAILURE;
2143 bus_proxy = dbus_g_proxy_new_for_name(g_connection, DBUS_SERVICE_DBUS,
2145 DBUS_INTERFACE_DBUS);
2146 if (bus_proxy == NULL) {
2147 ERR("Failed to get a proxy for D-Bus\n");
2151 if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING,
2152 BT_MAP_SERVICE_NAME, G_TYPE_UINT, 0,
2153 G_TYPE_INVALID, G_TYPE_UINT, &result,
2155 if (error != NULL) {
2156 ERR("RequestName RPC failed[%s]\n", error->message);
2157 g_error_free(error);
2162 if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
2163 ERR("Failed to get the primary well-known name.\n");
2167 g_object_unref(bus_proxy);
2170 bluetooth_map_obj = g_object_new(BLUETOOTH_MAP_TYPE_AGENT, NULL);
2172 /* Registering it on the D-Bus */
2173 dbus_g_connection_register_g_object(g_connection,
2174 BT_MAP_SERVICE_OBJECT_PATH,
2175 G_OBJECT(bluetooth_map_obj));
2177 if (__bluetooth_map_start_service() == FALSE)
2180 g_tapi_handle = tel_init(NULL);
2184 ret = tel_get_sms_sca(g_tapi_handle, 0, __bt_get_sms_sca, NULL);
2185 if (ret != TAPI_API_SUCCESS) {
2186 ERR("TAPI err = %d", ret);
2190 g_main_loop_run(g_mainloop);
2194 __bt_remove_list(id_list);
2196 tel_deinit(g_tapi_handle);
2199 __bt_mns_client_disconnect();
2202 g_object_unref(bus_proxy);
2203 if (bluetooth_map_obj)
2204 g_object_unref(bluetooth_map_obj);
2206 dbus_g_connection_unref(g_connection);
2208 __bluetooth_map_stop_service();
2209 DBG("Bluetooth MAP agent Terminated successfully\n");
2211 return EXIT_FAILURE;