From b460f7679351547e7fe99e6307c5cd1d7ccdcda0 Mon Sep 17 00:00:00 2001 From: DoHyun Pyun Date: Fri, 22 Mar 2013 08:45:30 +0900 Subject: [PATCH] Merge branch 'master' into tizen_2.1 Change-Id: I88a6f307936487c9d560b7ef5a6b51e0f1619b22 --- LICENSE.APLv2 | 203 +++++++ NOTICE | 3 + bluetooth-agent.manifest | 26 +- hfp-agent/CMakeLists.txt | 2 +- hfp-agent/bluetooth-hfp-agent.c | 261 ++++++++- map-agent/CMakeLists.txt | 2 +- map-agent/bluetooth_map_agent.c | 1123 +++++++++++++++++-------------------- map-agent/bluetooth_map_agent.xml | 3 + map-agent/map_bmessage.c | 133 ++++- map-agent/map_bmessage.h | 2 +- packaging/bluetooth-agent.spec | 8 +- pb-agent/bluetooth_pb_agent.c | 64 ++- pb-agent/bluetooth_pb_agent.xml | 4 + pb-agent/bluetooth_pb_vcard.c | 61 +- 14 files changed, 1194 insertions(+), 701 deletions(-) create mode 100644 LICENSE.APLv2 create mode 100644 NOTICE diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..43e91eb --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..0e0f016 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache License terms and conditions. diff --git a/bluetooth-agent.manifest b/bluetooth-agent.manifest index 839dfd4..6e4897d 100644 --- a/bluetooth-agent.manifest +++ b/bluetooth-agent.manifest @@ -1,18 +1,22 @@ - - + + + + + + + + + + + + + + - + - - - - - diff --git a/hfp-agent/CMakeLists.txt b/hfp-agent/CMakeLists.txt index 4c47c31..f5fc75f 100644 --- a/hfp-agent/CMakeLists.txt +++ b/hfp-agent/CMakeLists.txt @@ -8,7 +8,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE(FindPkgConfig) pkg_check_modules(pkgs_hfp_agent REQUIRED - dbus-glib-1 vconf appsvc contacts-service2 tapi) + dbus-glib-1 vconf appsvc contacts-service2 tapi capi-appfw-application aul) FOREACH(flag ${pkgs_hfp_agent_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/hfp-agent/bluetooth-hfp-agent.c b/hfp-agent/bluetooth-hfp-agent.c index 388eb89..4260fa1 100644 --- a/hfp-agent/bluetooth-hfp-agent.c +++ b/hfp-agent/bluetooth-hfp-agent.c @@ -16,7 +16,6 @@ * limitations under the License. * */ - #include #include #include @@ -29,6 +28,8 @@ #include #include +#include +#include #include "vconf.h" #include "vconf-keys.h" @@ -80,6 +81,26 @@ static gboolean nrec_status = FALSE; */ #define BT_MAX_TEL_NUM_STRING 20 +/** + * @brief Outgoing call type status + * + * 0 : Follow last call log \n + * 1 : Voice call \n + * 2 : Video call \n + */ +#define BT_FOLLOW_CALL_LOG 0 +#define BT_VOICE_CALL 1 +#define BT_VIDEO_CALL 2 + +/** + * @brief The status of making outgoing calls with BT headsets + * + * 0 : Even when device locked \n + * 1 : Only when device unlocked \n + */ +#define BT_MO_EVEN_LOCKED 0 +#define BT_MO_ONLY_UNLOCKED 1 + typedef struct { GObject parent; } BtHfpAgent; @@ -822,6 +843,66 @@ static gboolean bt_hfp_agent_get_properties(BtHfpAgent *agent, return TRUE; } +static gboolean __bt_is_phone_locked(int *phone_lock_state) +{ + int ret; + DBG("+\n"); + + if (NULL == phone_lock_state) + return FALSE; + + ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, phone_lock_state); + if (ret != 0) { + DBG("Failed to read [%s]\n", VCONFKEY_IDLE_LOCK_STATE); + return FALSE; + } + + DBG("[%s] = [%d]\n", VCONFKEY_IDLE_LOCK_STATE, *phone_lock_state); + DBG("-\n"); + + return TRUE; +} + +static gboolean __bt_get_outgoing_callapp_type(int *callapp_type) +{ + int ret; + DBG(" +\n"); + + if (NULL == callapp_type) + return FALSE; + + ret = vconf_get_int(VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT, callapp_type); + if (ret != 0) { + DBG("Failed to read [%s]\n", VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT); + return FALSE; + } + + DBG(" [%s] = [%d]\n", VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT, *callapp_type); + DBG("-\n"); + + return TRUE; +} + +static gboolean __bt_get_outgoing_call_condition(int *condition) +{ + int ret; + DBG("+\n"); + + if (NULL == condition) + return FALSE; + + ret = vconf_get_int(VCONFKEY_CISSAPPL_OUTGOING_CALL_CONDITIONS_INT, condition); + if (ret != 0) { + DBG("Failed to read [%s]\n", VCONFKEY_CISSAPPL_OUTGOING_CALL_CONDITIONS_INT); + return FALSE; + } + + DBG(" [%s] = [%d]\n", VCONFKEY_CISSAPPL_OUTGOING_CALL_CONDITIONS_INT, *condition); + DBG("-\n"); + + return TRUE; +} + static gboolean __bt_hfp_agent_make_call(const char *number) { bundle *b; @@ -841,18 +922,39 @@ static gboolean __bt_hfp_agent_make_call(const char *number) return TRUE; } +static gboolean __bt_hfp_agent_make_video_call(const char *mo_number) +{ + bundle *kb; + + kb = bundle_create(); + if (NULL == kb) + return FALSE; + + bundle_add(kb, "KEY_CALL_TYPE", "MO"); + bundle_add(kb, "number", mo_number); + aul_launch_app("com.samsung.vtmain", kb); + bundle_free(kb); + + return TRUE; +} + static gboolean bt_hfp_agent_dial_last_num(BtHfpAgent *agent, DBusGMethodInvocation *context) { GError *error; int error_code = BT_HFP_AGENT_ERROR_NONE; char *last_number = NULL; + int log_type; + int callapp_type; + int phone_lock_state; + int condition; contacts_list_h list = NULL; contacts_query_h query = NULL; contacts_filter_h filter = NULL; contacts_record_h record = NULL; unsigned int projections[] = { _contacts_phone_log.address, + _contacts_phone_log.log_type, }; DBG("+ \n"); @@ -939,8 +1041,11 @@ static gboolean bt_hfp_agent_dial_last_num(BtHfpAgent *agent, if (record == NULL) goto done; - contacts_record_get_str(record, _contacts_phone_log.address, - &last_number); + if (contacts_record_get_str(record, _contacts_phone_log.address, + &last_number)!= CONTACTS_ERROR_NONE) { + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + goto done; + } if (last_number == NULL) { ERR("No last number \n"); @@ -948,13 +1053,66 @@ static gboolean bt_hfp_agent_dial_last_num(BtHfpAgent *agent, goto done; } - /*Make Voice call*/ - if (!__bt_hfp_agent_make_call(last_number)) { - ERR("Problem launching application \n"); + if (!__bt_is_phone_locked(&phone_lock_state)) { + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + goto done; + } + + if (!__bt_get_outgoing_callapp_type(&callapp_type)) { error_code = BT_HFP_AGENT_ERROR_INTERNAL; + goto done; } - g_free(last_number); + if (!__bt_get_outgoing_call_condition(&condition)) { + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + goto done; + } + + if (condition == BT_MO_ONLY_UNLOCKED && + phone_lock_state == VCONFKEY_IDLE_LOCK) { + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + goto done; + } + + switch (callapp_type) { + case BT_VOICE_CALL: + if (!__bt_hfp_agent_make_call(last_number)) { + ERR("Problem launching application \n"); + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + } + break; + case BT_VIDEO_CALL: + if(!__bt_hfp_agent_make_video_call(last_number)) { + ERR("Problem launching application \n"); + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + } + break; + case BT_FOLLOW_CALL_LOG: + if(contacts_record_get_int(record, + _contacts_phone_log.log_type, + &log_type) != CONTACTS_ERROR_NONE) { + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + break; + } + if (log_type == CONTACTS_PLOG_TYPE_VOICE_OUTGOING) { + if (!__bt_hfp_agent_make_call(last_number)) { + ERR("Problem launching application \n"); + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + } + } + else if(log_type == CONTACTS_PLOG_TYPE_VIDEO_OUTGOING) { + if(!__bt_hfp_agent_make_video_call(last_number)) { + ERR("Problem launching application \n"); + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + } + } else { + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + } + break; + default: + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + break; + } done: if (list != NULL) @@ -968,6 +1126,9 @@ done: contacts_disconnect2(); + if (last_number != NULL) + g_free(last_number); + DBG("-\n"); if (error_code == BT_HFP_AGENT_ERROR_NONE) { @@ -987,6 +1148,9 @@ static gboolean bt_hfp_agent_dial_num(BtHfpAgent *agent, { GError *error; int error_code; + int callapp_type; + int phone_lock_state; + int condition; DBG("+\n"); @@ -1001,13 +1165,40 @@ static gboolean bt_hfp_agent_dial_num(BtHfpAgent *agent, /*TODO: Make use of flags*/ - /*Make Voice call*/ - if (!__bt_hfp_agent_make_call(number)) { - ERR("Problem launching application \n"); + if (!__bt_is_phone_locked(&phone_lock_state)) { + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + goto fail; + } + + if (!__bt_get_outgoing_callapp_type(&callapp_type)) { + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + goto fail; + } + + if (!__bt_get_outgoing_call_condition(&condition)) { + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + goto fail; + } + + if (condition == BT_MO_ONLY_UNLOCKED && phone_lock_state == VCONFKEY_IDLE_LOCK) { error_code = BT_HFP_AGENT_ERROR_INTERNAL; goto fail; } + if (callapp_type == BT_VIDEO_CALL) { + if(!__bt_hfp_agent_make_video_call(number)) { + ERR("Problem launching application \n"); + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + goto fail; + } + } else { + if (!__bt_hfp_agent_make_call(number)) { + ERR("Problem launching application \n"); + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + goto fail; + } + } + dbus_g_method_return(context); DBG("-\n"); @@ -1093,8 +1284,11 @@ static gboolean bt_hfp_agent_dial_memory(BtHfpAgent *agent, gint location, if (record == NULL) goto done; - contacts_record_get_str(record, _contacts_speeddial.number, - &number); + if (contacts_record_get_str(record, _contacts_speeddial.number, + &number)!= CONTACTS_ERROR_NONE) { + error_code = BT_HFP_AGENT_ERROR_INTERNAL; + goto done; + } if (number == NULL) { ERR("No number at the location \n"); @@ -1178,14 +1372,38 @@ static gboolean bt_hfp_agent_send_dtmf(BtHfpAgent *agent, const gchar *dtmf, return TRUE; } +static void __bt_hfp_agent_launch_voice_dial(gboolean activate) +{ + service_h service = NULL; + + service_create(&service); + + if (service == NULL) { + DBG("Service create failed"); + return; + } + + service_set_package(service, "com.samsung.svoice"); + service_set_operation(service, SERVICE_OPERATION_DEFAULT); + service_add_extra_data(service, "domain", "bt_headset"); + + if (!activate) + service_add_extra_data(service, "action_type", "deactivate"); + + if (service_send_launch_request(service, NULL, NULL) != + SERVICE_ERROR_NONE) + DBG("launch failed"); + + service_destroy(service); + return; +} + static gboolean bt_hfp_agent_voice_dial(BtHfpAgent *agent, gboolean activate, DBusGMethodInvocation *context) { - DBG("+\n"); - DBG("Activate = %d \n", activate); - /*App Selector code here needed*/ + __bt_hfp_agent_launch_voice_dial(activate); dbus_g_method_return(context); DBG("-\n"); @@ -1787,14 +2005,12 @@ static void __bt_hfp_agent_tel_cb(TapiHandle *handle, static void __bt_hfp_agent_sigterm_handler(int signo) { - DBG("+\n"); - - if (gmain_loop) + if (gmain_loop) { g_main_loop_quit(gmain_loop); - else + } else { + DBG("Terminating HFP agent"); exit(0); - - DBG("-\n"); + } } int main(void) @@ -1804,6 +2020,8 @@ int main(void) struct sigaction sa; int tapi_result; + DBG("Starting Bluetooth HFP agent"); + g_type_init(); memset(&sa, 0, sizeof(sa)); @@ -1855,5 +2073,6 @@ int main(void) if (gmain_loop) g_main_loop_unref(gmain_loop); + DBG("Terminating Bluetooth HFP agent"); return 0; } diff --git a/map-agent/CMakeLists.txt b/map-agent/CMakeLists.txt index 932bee4..84c4aa7 100644 --- a/map-agent/CMakeLists.txt +++ b/map-agent/CMakeLists.txt @@ -8,7 +8,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE(FindPkgConfig) pkg_check_modules(pkgs_map_agent REQUIRED - dbus-glib-1 dlog msg-service email-service vconf) + dbus-glib-1 dlog msg-service tapi vconf) FOREACH(flag ${pkgs_map_agent_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/map-agent/bluetooth_map_agent.c b/map-agent/bluetooth_map_agent.c index ab1af4d..08bbd82 100644 --- a/map-agent/bluetooth_map_agent.c +++ b/map-agent/bluetooth_map_agent.c @@ -39,15 +39,9 @@ #include "msg_transport_types.h" #include "msg_types.h" -#ifdef SUPPORT_EMAIL -/*Email Header Files*/ -#include "email-types.h" -#include "email-api-init.h" -#include "email-api-account.h" -#include "email-api-mailbox.h" -#include "email-api-mail.h" -#include "email-api-network.h" -#endif +#include +#include +#include #include @@ -70,6 +64,8 @@ G_TYPE_INVALID)) static msg_handle_t g_msg_handle = NULL; +static TapiHandle *g_tapi_handle = NULL; +static TelSmsAddressInfo_t *g_sca_info = NULL; #define BT_MAP_NEW_MESSAGE "NewMessage" #define BT_MAP_STATUS_CB "sent status callback" @@ -107,20 +103,23 @@ static msg_handle_t g_msg_handle = NULL; #define LANGUAGE "LANGUAGE:%s\r\n" #define LENGTH "LENGTH:%d\r\n" #define MSG_BODY "BEGIN:MSG\r\n%s\r\nEND:MSG\r\n" +#define MSG_BODY_BEGIN "BEGIN:MSG\r\n" +#define MSG_BODY_END "\r\nEND:MSG\r\n" -/* This has been added for testing purpose, will be removed when SMS APIs - are available. */ -#define TEST_PDU "06810000000000040681567777000021017101750261A05"\ - "376BA0D8297E5F3B73BCC4ED3F3A030FB1ECECF41613A"\ - "5D1E1ED3E7A0B2BD2CCF8362AEA4195407C941ECF77C9"\ - "E769F41753968FC769BD3E4B27B5C0691EB6510FD0D7AD"\ - "BCBF27B397D46D343A163990E42BFDB6590BCDC4E93D3"\ - "E539889E86CF41F437485E26D7C765D0DB5E96DFCBE933"\ - "9A1E9A36A72063900AA2BF41B5DBED760385E920E9DC357B35A9" - -GSList* id_list = NULL; +GSList *id_list = NULL; guint64 current_push_map_id; +typedef enum { + SMS_TON_UNKNOWN = 0, /* unknown */ + SMS_TON_INTERNATIONAL = 1, /* international number */ + SMS_TON_NATIONAL = 2, /* national number */ + SMS_TON_NETWORK_SPECIFIC = 3, /* network specific number */ + SMS_TON_DEDICATED_ACCESS = 4, /* subscriber number */ + SMS_TON_ALPHA_NUMERIC = 5, /* alphanumeric, GSM 7-bit default */ + SMS_TON_ABBREVIATED_NUMBER = 6, /* abbreviated number */ + SMS_TON_RESERVED_FOR_EXT = 7 /* reserved for extension */ +} bt_sim_type_of_num_t; + struct id_info { guint64 map_id; int uid; @@ -218,7 +217,8 @@ static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent, gchar *remote_addr, gboolean status, DBusGMethodInvocation *context); - +static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent, + DBusGMethodInvocation *context); #include "bluetooth_map_agent_glue.h" @@ -265,68 +265,68 @@ static GError *__bt_map_agent_error(bt_map_agent_error_t error, static guint64 _bt_validate_uid(int uid) { - DBG("Validate uid"); - struct id_info *info; - int count; - int i; - - count = g_slist_length(id_list); - for (i = 0; i < count; i++) { - info = (struct id_info *)g_slist_nth_data(id_list, i); + DBG("Validate uid"); + struct id_info *info; + int count; + int i; + + count = g_slist_length(id_list); + for (i = 0; i < count; i++) { + info = (struct id_info *)g_slist_nth_data(id_list, i); if (!info) break; - if (info->uid == uid) { - printf("uid = %d\n", uid); - return info->map_id; - } - } + if (info->uid == uid) { + printf("uid = %d\n", uid); + return info->map_id; + } + } - return 0; + return 0; } static guint64 __bt_add_id(int uid) { - DBG("Add id: %d\n", uid); - static guint64 map_id; - struct id_info *info; - guint64 test; + DBG("Add id: %d\n", uid); + static guint64 map_id; + struct id_info *info; + guint64 test; - test = _bt_validate_uid(uid); - DBG("test: %llx\n", test); - if (test) - return test; + test = _bt_validate_uid(uid); + DBG("test: %llx\n", test); + if (test) + return test; - info = g_new0(struct id_info, 1); + info = g_new0(struct id_info, 1); - map_id++; + map_id++; - info->map_id = map_id; - info->uid = uid; - DBG("map_id = %llx, uid = %d \n", info->map_id, info->uid); + info->map_id = map_id; + info->uid = uid; + DBG("map_id = %llx, uid = %d \n", info->map_id, info->uid); - id_list = g_slist_append(id_list, info); + id_list = g_slist_append(id_list, info); - return map_id; + return map_id; } static int __bt_get_id(guint64 map_id) { - DBG("get id\n"); - struct id_info *info; - int count; + DBG("get id\n"); + struct id_info *info; + int count; int i; - count = g_slist_length(id_list); + count = g_slist_length(id_list); - for (i = 0; i < count; i++) { - info = (struct id_info *)g_slist_nth_data(id_list, i); + for (i = 0; i < count; i++) { + info = (struct id_info *)g_slist_nth_data(id_list, i); - if (info->map_id == map_id) - return info->uid; - } + if (info->map_id == map_id) + return info->uid; + } - return -1; + return -1; } static int __bt_get_uid(gchar *handle) @@ -364,7 +364,7 @@ static int __bt_update_id(guint64 map_id, int new_uid) } } - return -1; + return -1; } static void __bt_remove_list(GSList *id_list) @@ -372,8 +372,8 @@ static void __bt_remove_list(GSList *id_list) if (!id_list) return; - DBG("Removing id list\n"); - g_slist_free_full(id_list, g_free); + DBG("Removing id list\n"); + g_slist_free_full(id_list, g_free); } @@ -382,24 +382,30 @@ static gchar *__bt_get_folder_name(int id) int ret; char folder_name[BT_MAP_MSG_INFO_MAX] = {0,}; - msg_struct_list_s g_folderList; + msg_struct_list_s folder_list = {0,}; msg_struct_t p_folder; - ret = msg_get_folder_list(g_msg_handle, &g_folderList); + ret = msg_get_folder_list(g_msg_handle, &folder_list); if (ret != MSG_SUCCESS) - goto done; + return g_strdup("TELECOM/MSG"); + + if (folder_list.msg_struct_info == NULL) + return g_strdup("TELECOM/MSG"); - p_folder = g_folderList.msg_struct_info[id]; + p_folder = folder_list.msg_struct_info[id]; ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR, folder_name, BT_MAP_MSG_INFO_MAX); - if (ret != MSG_SUCCESS) - goto done; - return g_strdup_printf("TELECOM/MSG/%s", folder_name); + if (folder_list.msg_struct_info) { + ret = msg_release_list_struct(&folder_list); + DBG("Err %d", ret); + } -done: - return g_strdup("TELECOM/MSG"); + if (ret != MSG_SUCCESS) + return g_strdup("TELECOM/MSG"); + else + return g_strdup_printf("TELECOM/MSG/%s", folder_name); } static void __get_msg_timestamp(time_t *ltime, char *timestamp) @@ -420,6 +426,233 @@ static void __get_msg_timestamp(time_t *ltime, char *timestamp) return; } +#define SET_TON_NPI(dest, ton, npi) { \ + dest = 0x80; \ + dest |= (ton & 0x07) << 4; \ + dest |= npi & 0x0F; \ +} + +static int __bt_ascii_to_upper(int ch) +{ + return (('a' <= (ch) && (ch) <= 'z') ? ((ch) - ('a'-'A')) : (ch)); +} + +static int __bt_sms_pack_gsm_code(gchar *p_out, const char *data, int in_len) +{ + DBG("+"); + int i; + int pos; + int shift = 0; + + for (pos = 0, i = 0; i < in_len; pos++, i++) { + /* pack the low bits */ + p_out[pos] = data[i] >> shift; + + if (i + 1 < in_len) { + /* pack the high bits using the low bits + of the next character */ + p_out[pos] |= data[i+1] << (7 - shift); + + shift++; + + if (shift == 7) { + shift = 0; + i++; + } + } + } + DBG("-"); + return pos; +} + +static void __bt_sms_conv_digit_to_bcd(gchar *p_bcd, char *p_digits, int digit_len) +{ + int i; + int j; + int digit; + unsigned char higher; + unsigned char lower; + + if (p_bcd == NULL || p_digits == NULL) + return; + + /* 0123456789 -> 1032547698 */ + for (i = 0, j = 0; i < digit_len; i = i + 2, j++) { + if (p_digits[i] == '*') + digit = 0x0A; + else if (p_digits[i] == '#') + digit = 0x0B; + else if (__bt_ascii_to_upper(p_digits[i]) == 'P') + digit = 0x0C; + else + digit = (int) (p_digits[i] - '0'); + + lower = digit & 0x0F; + + if (digit_len != i + 1) { + if (p_digits[i+1] == '*') + digit = 0x0A; + else if (p_digits[i+1] == '#') + digit = 0x0B; + else if (__bt_ascii_to_upper(p_digits[i+1]) == 'P') + digit = 0x0C; + else + digit = (int) (p_digits[i+1] - '0'); + + higher = digit & 0x0F; + } else { + higher = 0xFF; + } + + p_bcd[j] = (higher << 4) | lower; + } +} + +static int __bt_sms_encode_addr(gchar *addr_field, char *dial_num, + int dial_num_len, int ton, int npi) +{ + DBG("+"); + int index = 0; + + if (dial_num == NULL || addr_field == NULL) + return -1; + + if (dial_num[0] == '+') { + dial_num++; + dial_num_len--; + ton = SMS_TON_INTERNATIONAL; + } + + if (ton != SMS_TON_ALPHA_NUMERIC) { + /* Origination address length address length */ + addr_field[index++] = (unsigned char)dial_num_len; + } else { + addr_field[index] = (unsigned char) + (((dial_num_len * 7 + 7) / 8) * 2); + + if (((dial_num_len * 7) % 8) <= 4) + addr_field[index]--; + + index++; + } + + SET_TON_NPI(addr_field[index], ton, npi); + index++; /* SET_TON_NPI */ + + if (ton != SMS_TON_ALPHA_NUMERIC) { + __bt_sms_conv_digit_to_bcd(&addr_field[index], + (char *)dial_num, dial_num_len); + + if (dial_num_len % 2) + index += (dial_num_len / 2) + 1; + else + index += dial_num_len / 2; + } else { + index += __bt_sms_pack_gsm_code(&addr_field[index], + dial_num, (int)dial_num_len); + } + + return index; +} + +static int __bt_sms_encode_time(gchar *addr_field, time_t *tm) +{ + int index = 0; + struct tm ltime; + int year; + int month; + + if (!localtime_r(tm, <ime)) + return index; + + year = ltime.tm_year + 1900; /* years since 1900 */ + year = year % 100; + month = ltime.tm_mon + 1; /* months since January */ + + addr_field[index++] = ((year % 10) << 4) + (year / 10); + addr_field[index++] = ((month % 10) << 4) + (month / 10); + addr_field[index++] = ((ltime.tm_mday % 10) << 4) + + (ltime.tm_mday / 10); + addr_field[index++] = ((ltime.tm_hour % 10) << 4) + + (ltime.tm_hour / 10); + addr_field[index++] = ((ltime.tm_min % 10) << 4) + (ltime.tm_min / 10); + addr_field[index++] = ((ltime.tm_sec % 10) << 4) + (ltime.tm_sec / 10); + addr_field[index] = 0x00; + + return index; +} + +static gchar *__bt_get_sms_pdu_from_msg_data(gchar *number, + char *msg, time_t tm, + int *msg_pdu_len) +{ + DBG("+"); + gchar packet[TAPI_NETTEXT_MSG_SIZE_MAX] = {0,}; + int index = 0; + + packet[index] = 0x00; /* Since SCA is unknown for stored messages */ + index++; + + /* TP-MTI : Type of message */ + packet[index] = 0x00; /* SMS-DELIVER PDU */ + + /* TP-MMS bit is set to 1 as we support only SMS */ + packet[index] |= 0x04; + index++; + + /* TP-OA : Mobile originating address */ + index += __bt_sms_encode_addr(packet+index, + number, strlen(number), + g_sca_info->Ton, g_sca_info->Npi); + + /* TP-PID : Since we use only SMS so set to 0 */ + packet[index++] = 0x00; + + /* TP-DCS : Data Coding Scheme, default value set */ + packet[index++] = 0x00; + + /* TP-SCTS : Message timestamp */ + index += __bt_sms_encode_time(packet+index, &tm); + index++; + /* TP-UDL : Message body length */ + packet[index++] = strlen(msg); + + /* TP-UD : Message body */ + index += __bt_sms_pack_gsm_code(packet + index, msg, strlen(msg)); + + *msg_pdu_len = index; + DBG("-"); + + return g_memdup(packet, index); +} + +static void __bt_get_sms_sca(TapiHandle *handle, int result, void *data, + void *user_data) +{ + TelSmsAddressInfo_t *scaInfo = data; + unsigned int i = 0; + + DBG("__bt_get_sms_sca 0x%x", result); + + if (data == NULL) + return; + + g_sca_info = g_malloc0(sizeof(TelSmsAddressInfo_t)); + g_sca_info->Ton = scaInfo->Ton; + g_sca_info->Npi = scaInfo->Npi; + g_sca_info->DialNumLen = scaInfo->DialNumLen; + + DBG(" - TON = %d", scaInfo->Ton); + DBG(" - NPI = %d", scaInfo->Npi); + DBG(" - DialNumLen = %d", scaInfo->DialNumLen); + DBG(" - SCA Num"); + + for (i = 0; i < scaInfo->DialNumLen; i++) { + g_sca_info->szDiallingNum[i] = scaInfo->szDiallingNum[i]; + DBG("[%02x]", g_sca_info->szDiallingNum[i]); + } +} + static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach, gboolean transcode) { @@ -427,14 +660,19 @@ static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach, int m_type = MSG_TYPE_SMS; int folder_id; int count; + int dptime = 0; + int j; bool read_status = false; char msg_body[BT_MAP_MSG_BODY_MAX] = {0,}; char addr_value[MAX_ADDRESS_VAL_LEN] = {0,}; - char name_value[MAX_ADDRESS_VAL_LEN] = {0,}; - gchar *folder_path; + char name_value[MAX_DISPLAY_NAME_LEN] = {0,}; + + msg_list_handle_t addr_list = NULL; + msg_struct_t addr_info = NULL; - msg_struct_list_s *addr_list = NULL; GString *msg; + gchar *folder_path; + gchar *msg_pdu; msg = g_string_new(BEGIN_BMSEG); g_string_append(msg, BMSEG_VERSION); @@ -452,38 +690,27 @@ static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach, ret = msg_get_int_value(msg_info, MSG_MESSAGE_TYPE_INT, &m_type); if (ret == MSG_SUCCESS) { DBG("m_type %d\n", m_type); - } - - switch (m_type) { - case MSG_TYPE_MMS: - case MSG_TYPE_MMS_JAVA: - case MSG_TYPE_MMS_NOTI: - g_string_append_printf(msg, MSEG_TYPE, "MMS"); - break; - - default: g_string_append_printf(msg, MSEG_TYPE, "SMS_GSM"); - break; } ret = msg_get_int_value(msg_info, MSG_MESSAGE_FOLDER_ID_INT, &folder_id); if (ret == MSG_SUCCESS) { DBG("folder_id %d\n", folder_id); - } - - folder_path = __bt_get_folder_name(folder_id); - g_string_append_printf(msg, FOLDER_PATH, folder_path); + folder_path = __bt_get_folder_name(folder_id); + g_string_append_printf(msg, FOLDER_PATH, folder_path); + } - ret = msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_STRUCT, - (void **)&addr_list); + ret = msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_HND, + (void **)&addr_list); if (ret == MSG_SUCCESS) { - count = addr_list->nCount; + count = msg_list_length(addr_list); DBG("count %d \n", count); - while (count > 0) { - msg_struct_t addr_info = NULL; - addr_info = addr_list->msg_struct_info[count - 1]; + + if (count > 0) { + addr_info = (msg_struct_t)msg_list_nth_data(addr_list, + 0); msg_get_str_value(addr_info, MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, @@ -491,7 +718,7 @@ static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach, DBG("addr_value %s\n", addr_value); msg_get_str_value(addr_info, MSG_ADDRESS_INFO_DISPLAYNAME_STR, - name_value, MAX_ADDRESS_VAL_LEN); + name_value, MAX_DISPLAY_NAME_LEN); if (!strlen(name_value)) g_stpcpy(name_value, addr_value); @@ -499,7 +726,6 @@ static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach, g_string_append_printf(msg, VCARD, name_value, addr_value); - count--; } } @@ -509,29 +735,39 @@ static char *__bt_prepare_msg_bmseg(msg_struct_t msg_info, gboolean attach, if (transcode) { g_string_append_printf(msg, CHARSET, "UTF-8"); - if (m_type == MSG_TYPE_MMS) - ret = msg_get_str_value(msg_info, - MSG_MESSAGE_MMS_TEXT_STR, - msg_body, BT_MAP_SUBJECT_MAX_LEN); - else - ret = msg_get_str_value(msg_info, - MSG_MESSAGE_SMS_DATA_STR, - msg_body, BT_MAP_MSG_BODY_MAX); + ret = msg_get_str_value(msg_info, + MSG_MESSAGE_SMS_DATA_STR, + msg_body, BT_MAP_MSG_BODY_MAX); if (ret == MSG_SUCCESS) { g_string_append_printf(msg, LENGTH, strlen(msg_body)); g_string_append_printf(msg, MSG_BODY, msg_body); } } else { - gchar *msg_pdu; g_string_append_printf(msg, ENCODING, "G-7BIT"); g_string_append_printf(msg, CHARSET, "native"); - /* The below line has been added for testing purpose, - will be removed when SMS APIs are available. */ - msg_pdu = g_strdup(TEST_PDU); - g_string_append_printf(msg, LENGTH, strlen(msg_pdu)); - g_string_append_printf(msg, MSG_BODY, msg_pdu); - g_free(msg_pdu); + + msg_get_int_value(msg_info, + MSG_MESSAGE_DISPLAY_TIME_INT, &dptime); + + ret = msg_get_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR, + msg_body, BT_MAP_MSG_BODY_MAX); + if (ret == MSG_SUCCESS) { + int msg_pdu_len = 0; + msg_pdu = __bt_get_sms_pdu_from_msg_data(addr_value, + msg_body, dptime, + &msg_pdu_len); + DBG("msg_pdu_len = %d", msg_pdu_len); + + g_string_append_printf(msg, LENGTH, msg_pdu_len); + g_string_append(msg, MSG_BODY_BEGIN); + for (j = 0; j < msg_pdu_len; j++) + g_string_append_printf(msg, "%02x", + msg_pdu[j]); + + g_string_append(msg, MSG_BODY_END); + g_free(msg_pdu); + } } g_string_append(msg, END_BBODY); @@ -568,6 +804,7 @@ static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle) int data_size; int priority; int direction_type; + int count; bool protect_status = 0; bool read_status = 0; @@ -577,7 +814,7 @@ static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle) char msg_size[5] = {0,}; char msg_body[BT_MAP_MSG_BODY_MAX] = {0,}; char addr_value[MAX_ADDRESS_VAL_LEN] = {0,}; - char name_value[MAX_ADDRESS_VAL_LEN] = {0,}; + char name_value[MAX_DISPLAY_NAME_LEN] = {0,}; msg_info.text = FALSE; msg_info.protect = FALSE; @@ -586,7 +823,7 @@ static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle) msg_struct_t msg = NULL; msg_struct_t send_opt = NULL; - msg_struct_list_s *addr_list = NULL; + msg_list_handle_t addr_list = NULL; msg_struct_t addr_info = NULL; ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_ID_INT, &msg_id); @@ -607,31 +844,39 @@ static struct message_info __bt_message_info_get(msg_struct_t msg_struct_handle) goto next; } - ret = msg_get_list_handle(msg, MSG_MESSAGE_ADDR_LIST_STRUCT, + ret = msg_get_list_handle(msg, MSG_MESSAGE_ADDR_LIST_HND, (void **)&addr_list); if (ret != MSG_SUCCESS) { DBG("ret = %d\n", ret); goto next; } - addr_info = addr_list->msg_struct_info[0]; + count = msg_list_length(addr_list); - ret = msg_get_str_value(addr_info, MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, - addr_value, MAX_ADDRESS_VAL_LEN); - if (ret == MSG_SUCCESS) - DBG("addr_value %s\n", addr_value); + if (count != 0) { + addr_info = (msg_struct_t)msg_list_nth_data(addr_list, 0); - ret = msg_get_str_value(addr_info, MSG_ADDRESS_INFO_DISPLAYNAME_STR, - name_value, MAX_ADDRESS_VAL_LEN); - if (ret == MSG_SUCCESS) - DBG("name_value %s\n", name_value); + ret = msg_get_str_value(addr_info, + MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, + addr_value, MAX_ADDRESS_VAL_LEN); + if (ret == MSG_SUCCESS) + DBG("addr_value %s\n", addr_value); + + ret = msg_get_str_value(addr_info, + MSG_ADDRESS_INFO_DISPLAYNAME_STR, + name_value, MAX_DISPLAY_NAME_LEN); - if (!strlen(name_value)) - g_stpcpy(name_value, addr_value); + if (ret == MSG_SUCCESS) + DBG("name_value %s\n", name_value); - DBG("name_value %s\n", name_value); + if (!strlen(name_value)) + g_stpcpy(name_value, addr_value); - ret = msg_get_int_value(msg, MSG_MESSAGE_DIRECTION_INT, &direction_type); + DBG("name_value %s\n", name_value); + } + + ret = msg_get_int_value(msg, MSG_MESSAGE_DIRECTION_INT, + &direction_type); if (ret != MSG_SUCCESS) goto next; @@ -651,7 +896,8 @@ next: msg_release_struct(&msg); msg_release_struct(&send_opt); - ret = msg_get_int_value(msg_struct_handle, MSG_MESSAGE_DISPLAY_TIME_INT, &dptime); + ret = msg_get_int_value(msg_struct_handle, + MSG_MESSAGE_DISPLAY_TIME_INT, &dptime); if (ret == MSG_SUCCESS) { __get_msg_timestamp((time_t *)&dptime, msg_datetime); } @@ -811,10 +1057,6 @@ static gboolean __bluetooth_map_start_service() { msg_error_t err = MSG_SUCCESS; gboolean msg_ret = TRUE; -#ifdef SUPPORT_EMAIL - int email_err = EMAIL_ERROR_NONE; - gboolean email_ret = TRUE; -#endif err = msg_open_msg_handle(&g_msg_handle); if (err != MSG_SUCCESS) { @@ -832,25 +1074,7 @@ static gboolean __bluetooth_map_start_service() } done: - -#ifdef SUPPORT_EMAIL - - email_err = email_service_begin(); - if (email_err != EMAIL_ERROR_NONE) { - ERR("email_service_begin fail error = %d\n", email_err); - email_ret = FALSE; - } - - if (msg_ret || email_ret) - return TRUE; - else - return FALSE; - -#else - return msg_ret; - -#endif } static void __bluetooth_map_stop_service() @@ -860,131 +1084,69 @@ static void __bluetooth_map_stop_service() g_msg_handle = NULL; -#ifdef SUPPORT_EMAIL - if (EMAIL_ERROR_NONE != email_service_end()) - ERR("email_service_end fail \n"); -#endif return; } -#ifdef SUPPORT_EMAIL -static int __bt_store_mail(email_mailbox_type_e type, char *subject, - char *body, char *recepients) +static gboolean __bt_convert_to_utf8(char **text) { - int account_id; - int mail_id; - int err; - char from_address[BT_MAIL_ID_MAX_LENGTH] = { 0, }; - FILE *body_file; - struct stat st_buf; - - email_account_t *account_data = NULL; - email_mailbox_t *mailbox_data = NULL; - email_mail_data_t *mail_data = NULL; - - err = email_load_default_account_id(&account_id); - if (EMAIL_ERROR_NONE != err) - goto fail; - - err = email_get_account(account_id, GET_FULL_DATA_WITHOUT_PASSWORD, - &account_data); - if (EMAIL_ERROR_NONE != err) - goto fail; - - err = email_get_mailbox_by_mailbox_type(account_id, type, - &mailbox_data); - if (EMAIL_ERROR_NONE != err) - goto fail; + char *utf8; + gsize len; - snprintf(from_address, BT_MAIL_ID_MAX_LENGTH, "<%s>", - account_data->user_email_address); - email_free_account(&account_data, 1); - - mail_data = calloc(1, sizeof(email_mail_data_t)); - if (NULL == mail_data) { - email_free_mailbox(&mailbox_data, 1); - goto fail; - } - - DBG("\n account_id %d\n", account_id); - mail_data->account_id = account_id; - mail_data->save_status = 1; - mail_data->body_download_status = 1; - /* mail_data->flags_draft_field = 1; */ - mail_data->flags_seen_field = 1; - mail_data->file_path_plain = g_strdup(BT_MAIL_TEMP_BODY); - - mail_data->mailbox_id = mailbox_data->mailbox_id; - mail_data->mailbox_type = mailbox_data->mailbox_type; - email_free_mailbox(&mailbox_data, 1); - - mail_data->full_address_from = g_strdup(from_address); - mail_data->full_address_to = g_strdup(recepients); - mail_data->subject = g_strdup(subject); - mail_data->report_status = EMAIL_MAIL_REQUEST_DSN | - EMAIL_MAIL_REQUEST_MDN; - - body_file = fopen(BT_MAIL_TEMP_BODY, "w"); - if (body_file == NULL) { - DBG("\n fopen [%s]failed\n", BT_MAIL_TEMP_BODY); - email_free_mail_data(&mail_data, 1); - goto fail; - } + if (g_utf8_validate(*text, -1, NULL)) + return TRUE; - fprintf(body_file, body); - fflush(body_file); - fclose(body_file); + utf8 = g_convert(*text, -1, "UTF-8", "ISO-8859-1", 0, &len, NULL); + if (!utf8) + return FALSE; - err = email_add_mail(mail_data, NULL, 0, NULL, 0); - if (err != EMAIL_ERROR_NONE) { - DBG("email_add_mail failed. [%d]\n", err); - if (!stat(mail_data->file_path_plain, &st_buf)) - remove(mail_data->file_path_plain); + DBG("conversion done %d\n", len); + g_free(*text); + *text = utf8; - email_free_mail_data(&mail_data, 1); - goto fail; - } + return TRUE; +} - DBG("saved mail id = [%d]\n", mail_data->mail_id); +static gboolean __bt_convert_msg_data(struct message_info *msg_info) +{ + if (msg_info == NULL) + return FALSE; - mail_id = mail_data->mail_id; + if (msg_info->subject) + if (!__bt_convert_to_utf8(&msg_info->subject)) + return FALSE; - email_free_mail_data(&mail_data, 1); + if (msg_info->sender_name) + if (!__bt_convert_to_utf8(&msg_info->sender_name)) + return FALSE; - return mail_id; + if (msg_info->sender_addressing) + if (!__bt_convert_to_utf8(&msg_info->sender_addressing)) + return FALSE; -fail: - return 0; -} + if (msg_info->replyto_addressing) + if (!__bt_convert_to_utf8(&msg_info->replyto_addressing)) + return FALSE; -static int __bt_email_send(char *subject, char *body, char* recepients) -{ - int err; - int mail_id; - int handle; + if (msg_info->recipient_name) + if (!__bt_convert_to_utf8(&msg_info->recipient_name)) + return FALSE; - mail_id = __bt_store_mail(EMAIL_MAILBOX_TYPE_OUTBOX, subject, - body, recepients); - if (mail_id) { - DBG("mail_id = %d\n", mail_id); - err = email_send_mail(mail_id, &handle); - if (err != EMAIL_ERROR_NONE) - DBG("Sending failed[%d]\n", err); - } + if (msg_info->recipient_addressing) + if (!__bt_convert_to_utf8(&msg_info->recipient_addressing)) + return FALSE; - return mail_id; + return TRUE; } -#endif static int __bt_get_folder_id(char *folder_path) { int folder_id = -1; int i; char *folder; - msg_struct_list_s folder_list; + msg_struct_list_s folder_list = {0,}; msg_error_t err; msg_struct_t p_folder; - DBG("__bt_get_folder_id\n"); + DBG("folder_path %s\n", folder_path); folder = strrchr(folder_path, '/'); if (NULL == folder) @@ -996,7 +1158,7 @@ static int __bt_get_folder_id(char *folder_path) err = msg_get_folder_list(g_msg_handle, &folder_list); if (err != MSG_SUCCESS) - return -1; + goto done; for (i = 0; i < folder_list.nCount; i++) { p_folder = folder_list.msg_struct_info[i]; @@ -1007,17 +1169,25 @@ static int __bt_get_folder_id(char *folder_path) if (err != MSG_SUCCESS) continue; - DBG("folderName %s\n", folder_name); + DBG("folder_name %s\n", folder_name); if (!g_ascii_strncasecmp(folder_name, folder, strlen(folder))) { - err = msg_get_int_value(p_folder, MSG_FOLDER_INFO_ID_INT, - &folder_id); + err = msg_get_int_value(p_folder, + MSG_FOLDER_INFO_ID_INT, + &folder_id); if (err != MSG_SUCCESS) - return -1; + goto done; + DBG("folder_id %d", folder_id); break; } } +done: + if (folder_list.msg_struct_info) { + err = msg_release_list_struct(&folder_list); + DBG("Err%d", err); + } + return folder_id; } @@ -1049,7 +1219,6 @@ static int __bt_push_sms(gboolean send, int folder_id, char *body, DBG("+ \n"); msg_struct_t msg_info = NULL; msg_struct_t send_opt = NULL; - msg_struct_list_s *addr_list; msg_error_t err; int count = 0; @@ -1066,8 +1235,9 @@ static int __bt_push_sms(gboolean send, int folder_id, char *body, goto fail; if (body) { - err = msg_set_str_value(msg_info, MSG_MESSAGE_SMS_DATA_STR, body, - strlen(body)); + err = msg_set_str_value(msg_info, + MSG_MESSAGE_SMS_DATA_STR, + body, strlen(body)); if (err != MSG_SUCCESS) goto fail; } else { @@ -1086,27 +1256,24 @@ static int __bt_push_sms(gboolean send, int folder_id, char *body, if (recepients) { count = g_slist_length(recepients); DBG("Count = %d\n", count); - msg_get_list_handle(msg_info, MSG_MESSAGE_ADDR_LIST_STRUCT, - (void**)&addr_list); - addr_list->nCount = count; for (i = 0; i < count; i++) { + msg_struct_t tmp_addr; char *address = (char *)g_slist_nth_data(recepients, i); if (address == NULL) { DBG("[ERROR] address is value NULL, skip"); continue; } - msg_set_int_value(addr_list->msg_struct_info[i], - MSG_ADDRESS_INFO_ADDRESS_TYPE_INT, - MSG_ADDRESS_TYPE_PLMN); + msg_list_add_item(msg_info, + MSG_MESSAGE_ADDR_LIST_HND, &tmp_addr); - msg_set_int_value(addr_list->msg_struct_info[i], - MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT, - MSG_RECIPIENTS_TYPE_TO); + msg_set_int_value(tmp_addr, + MSG_ADDRESS_INFO_RECIPIENT_TYPE_INT, + MSG_RECIPIENTS_TYPE_TO); - msg_set_str_value(addr_list->msg_struct_info[i], - MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, - address, strlen(address)); + msg_set_str_value(tmp_addr, + MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, + address, strlen(address)); } } @@ -1261,29 +1428,21 @@ static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent, int ret; gboolean msg_ret = TRUE; - msg_struct_list_s g_folderList; + msg_struct_list_s folder_list = {0,}; msg_struct_t p_folder; -#ifdef SUPPORT_EMAIL - int j; - int account_id = 0; - int mailbox_count = 0; - gboolean flag = FALSE; - email_mailbox_t *mailbox_list = NULL; -#endif - if (g_msg_handle == NULL) { msg_ret = FALSE; goto done; } - if (msg_get_folder_list(g_msg_handle, &g_folderList) != MSG_SUCCESS) { + if (msg_get_folder_list(g_msg_handle, &folder_list) != MSG_SUCCESS) { msg_ret = FALSE; goto done; } - for (i = 0; i < g_folderList.nCount; i++) { - p_folder = g_folderList.msg_struct_info[i]; + for (i = 0; i < folder_list.nCount; i++) { + p_folder = folder_list.msg_struct_info[i]; memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX); ret = msg_get_str_value(p_folder, MSG_FOLDER_INFO_NAME_STR, @@ -1307,64 +1466,13 @@ static gboolean bluetooth_map_get_folder_tree(BluetoothMapAgent *agent, g_ptr_array_add(array, g_value_get_boxed(&value)); } -#ifdef SUPPORT_EMAIL -email: - if (EMAIL_ERROR_NONE != email_load_default_account_id(&account_id)) - goto done; - - if (EMAIL_ERROR_NONE != email_get_mailbox_list(account_id, - EMAIL_MAILBOX_ALL, - &mailbox_list, - &mailbox_count)) { - goto done; - } - - msg_ret = TRUE; - - for (i = 0; i < mailbox_count; i++) { - flag = FALSE; - for (j = 0; j < g_folderList.nCount; j++) { - - p_folder = g_folderList.msg_struct_info[j]; - memset(folder_name, 0x00, BT_MAP_MSG_INFO_MAX); - - ret = msg_get_str_value(p_folder, - MSG_FOLDER_INFO_NAME_STR, - folder_name, - BT_MAP_MSG_INFO_MAX); - if (ret != MSG_SUCCESS) - continue; - - if (!g_ascii_strncasecmp(mailbox_list[i].alias, - folder_name, strlen(mailbox_list[i].alias))) { - flag = TRUE; - break; - } - } - - if (!flag) { - g_strlcpy(name, mailbox_list[i].alias, sizeof(name)); - - if (!g_ascii_strncasecmp(name, BT_MAP_SENT_FOLDER_NAME, - strlen(BT_MAP_SENT_FOLDER_NAME))) - continue; +done: - memset(&value, 0, sizeof(GValue)); - g_value_init(&value, DBUS_STRUCT_STRING_STRING_UINT); - g_value_take_boxed(&value, - dbus_g_type_specialized_construct( - DBUS_STRUCT_STRING_STRING_UINT)); - dbus_g_type_struct_set(&value, 0, name, G_MAXUINT); - g_ptr_array_add(array, g_value_get_boxed(&value)); - } + if (folder_list.msg_struct_info) { + ret = msg_release_list_struct(&folder_list); + DBG("Err %d", ret); } - if (mailbox_list != NULL) - email_free_mailbox(&mailbox_list, mailbox_count); -#endif - -done: - if (msg_ret == FALSE) { g_ptr_array_free(array, TRUE); @@ -1391,27 +1499,15 @@ static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent, char *folder = NULL; int i = 0; int ret = 0; - int folder_id = 0; + int folder_id = -1; int unread_cnt; - guint64 count; - gboolean newmsg; + guint64 count = 0; + gboolean newmsg = FALSE; - msg_struct_list_s g_folderList; - msg_struct_list_s msg_list; + msg_struct_list_s folder_list = {0,}; + msg_struct_list_s msg_list = {0,}; msg_struct_t count_info; - -#ifdef SUPPORT_EMAIL - int total = 0; - int account_id = 0; - int mailbox_count = 0; - int mail_count = 0; - char *type = NULL; - char msg_datetime[BT_MAP_TIMESTAMP_MAX_LEN] = {0,}; - email_mailbox_t *mailbox_list = NULL; - email_mail_list_item_t *mail_list = NULL; - email_list_filter_t *filter_list = NULL; - email_list_sorting_rule_t *sorting_rule_list = NULL; -#endif + msg_struct_t list_cond; if (g_msg_handle == NULL) goto fail; @@ -1422,12 +1518,15 @@ static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent, else folder++; - ret = msg_get_folder_list(g_msg_handle, &g_folderList); + if (!strlen(folder)) + goto done; + + ret = msg_get_folder_list(g_msg_handle, &folder_list); if (ret != MSG_SUCCESS) goto fail; - for (i = 0; i < g_folderList.nCount; i++) { - msg_struct_t pFolder = g_folderList.msg_struct_info[i]; + for (i = 0; i < folder_list.nCount; i++) { + msg_struct_t pFolder = folder_list.msg_struct_info[i]; char folderName[BT_MAP_MSG_INFO_MAX] = {0, }; ret = msg_get_str_value(pFolder, MSG_FOLDER_INFO_NAME_STR, @@ -1447,9 +1546,21 @@ static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent, } } - ret = msg_get_folder_view_list(g_msg_handle, folder_id, - NULL, &msg_list); - if (ret != MSG_SUCCESS) + if (folder_id == -1) + goto done; + + list_cond = msg_create_struct(MSG_STRUCT_MSG_LIST_CONDITION); + ret = msg_set_int_value(list_cond, + MSG_LIST_CONDITION_FOLDER_ID_INT, + folder_id); + if (ret != MSG_SUCCESS) + goto fail; + + ret = msg_get_message_list2(g_msg_handle, list_cond, &msg_list); + + msg_release_struct(&list_cond); + + if (ret != MSG_SUCCESS) goto fail; count = msg_list.nCount; @@ -1470,8 +1581,6 @@ static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent, if (unread_cnt != 0) newmsg = TRUE; - else - newmsg = FALSE; msg_release_struct(&count_info); @@ -1490,28 +1599,10 @@ static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent, msg_info = __bt_message_info_get(msg_list.msg_struct_info[i]); -/* Keeping the bleow debug till stabilization is done. */ - -/* - DBG("msg_info.handle = %s\n", msg_info.handle); - DBG("msg_info.subject = %s\n", msg_info.subject); - DBG("msg_info.datetime = %s\n", msg_info.datetime); - DBG("msg_info.sender_name = %s\n", msg_info.sender_name); - DBG("msg_info.sender_addressing = %s\n", msg_info.sender_addressing); - DBG("msg_info.replyto_addressing = %s\n", msg_info.replyto_addressing); - DBG("msg_info.recipient_name = %s\n", msg_info.recipient_name); - DBG("msg_info.recipient_addressing = %s\n", - msg_info.recipient_addressing); - DBG("msg_info.type = %s\n", msg_info.type); - DBG("msg_info.reception_status = %s\n", msg_info.reception_status); - DBG("msg_info.size = %s\n", msg_info.size); - DBG("msg_info.attachment_size = %s\n", msg_info.attachment_size); - DBG("msg_info.text = %d\n", msg_info.text); - DBG("msg_info.read = %d\n", msg_info.read); - DBG("msg_info.sent = %d\n", msg_info.sent); - DBG("msg_info.protect = %d\n", msg_info.protect); - DBG("msg_info.priority = %d\n", msg_info.priority); -*/ + if (!__bt_convert_msg_data(&msg_info)) { + __bt_message_info_free(msg_info); + continue; + } dbus_g_type_struct_set(&value, 0, msg_info.handle, 1, msg_info.subject, @@ -1529,130 +1620,41 @@ static gboolean bluetooth_map_get_message_list(BluetoothMapAgent *agent, 13, msg_info.read, 14, msg_info.sent, 15, msg_info.protect, - 16, msg_info.replyto_addressing, G_MAXUINT); + 16, msg_info.replyto_addressing, + G_MAXUINT); g_ptr_array_add(array, g_value_get_boxed(&value)); __bt_message_info_free(msg_info); } -#ifdef SUPPORT_EMAIL -email: - if (EMAIL_ERROR_NONE != email_load_default_account_id(&account_id)) { - if (!msg_ret) - goto fail; - } +done: + DBG("Request completed \n"); - if (EMAIL_ERROR_NONE != email_get_mailbox_list(account_id, - EMAIL_MAILBOX_ALL, - &mailbox_list, - &mailbox_count)) { - if (!msg_ret) - goto fail; + if (folder_list.msg_struct_info) { + ret = msg_release_list_struct(&folder_list); + DBG("Err %d", ret); } - if (mailbox_list == NULL) - goto fail; - - for (i = 0; i < mailbox_count; i++) { - DBG("mailbox alias = %s \n", mailbox_list[i].alias); - if (!g_ascii_strncasecmp(mailbox_list[i].alias, folder, - strlen(folder))) { - total = mailbox_list[i].total_mail_count_on_server; - DBG("Total mail on sever:%d\n", total); - DBG("mailbox name:%s\n", mailbox_list[i].mailbox_name); - - break; - } - - if (!msg_ret) - goto fail; - else - goto done; - } - - /* Need to modify the filter code, have to make it dynamic - based on remote device request Also to check whether it needs - to be done in agent or in obexd */ - - filter_list = g_new0(email_list_filter_t, 3); - filter_list[0].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE; - filter_list[0].list_filter_item.rule.target_attribute = - EMAIL_MAIL_ATTRIBUTE_ACCOUNT_ID; - filter_list[0].list_filter_item.rule.rule_type = - EMAIL_LIST_FILTER_RULE_EQUAL; - filter_list[0].list_filter_item.rule.key_value.integer_type_value = - account_id; - - filter_list[1].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_OPERATOR; - filter_list[1].list_filter_item.operator_type = - EMAIL_LIST_FILTER_OPERATOR_AND; - - filter_list[2].list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE; - filter_list[2].list_filter_item.rule.target_attribute = - EMAIL_MAIL_ATTRIBUTE_MAILBOX_NAME; - filter_list[2].list_filter_item.rule.rule_type = - EMAIL_LIST_FILTER_RULE_EQUAL; - type = g_strdup(mailbox_list[i].mailbox_name); - filter_list[2].list_filter_item.rule.key_value.string_type_value = type; - filter_list[2].list_filter_item.rule.case_sensitivity = true; - - sorting_rule_list = g_new0(email_list_sorting_rule_t, 1); - sorting_rule_list->target_attribute = EMAIL_MAIL_ATTRIBUTE_DATE_TIME; - sorting_rule_list->sort_order = EMAIL_SORT_ORDER_ASCEND; - - ret = email_get_mail_list_ex(filter_list, 3, - sorting_rule_list, 1, 0, total - 1, - &mail_list, &mail_count); - - DBG("email API ret %d \n", ret); - if (ret != EMAIL_ERROR_NONE) { - if (!msg_ret) { - g_free(type); - g_free(filter_list); - g_free(sorting_rule_list); - goto fail; - } else - goto done; + if (msg_list.msg_struct_info) { + ret = msg_release_list_struct(&msg_list); + DBG("Err%d", ret); } - for (i = 0; i < mail_count; ++i) { - time_t time = {0,}; - memset(&value, 0, sizeof(GValue)); - g_value_init(&value, DBUS_STRUCT_MESSAGE_LIST); - g_value_take_boxed(&value, dbus_g_type_specialized_construct( - DBUS_STRUCT_MESSAGE_LIST)); - - uid = __bt_add_id(mail_list[i].mail_id); - snprintf(msg_handle, sizeof(msg_handle), "%llx", uid); - - g_strlcpy(msg_type, "EMAIL", sizeof(msg_type)); - - time = mail_list[i].date_time; - __get_msg_timestamp(&time, msg_datetime); - - dbus_g_type_struct_set(&value, 0, msg_handle, 1, msg_type, - 2, msg_datetime, G_MAXUINT); - g_ptr_array_add(array, g_value_get_boxed(&value)); - } - - if (mailbox_list != NULL) - email_free_mailbox(&mailbox_list, mailbox_count); - if (mail_list != NULL) - g_free(mail_list); - - g_free(filter_list); - g_free(sorting_rule_list); - g_free(type); -#endif - -done: - DBG("Request completed \n"); dbus_g_method_return(context, newmsg, count, array); g_ptr_array_free(array, TRUE); DBG("Request completed successfully \n"); return TRUE; fail: + if (folder_list.msg_struct_info) { + ret = msg_release_list_struct(&folder_list); + DBG("Err %d", ret); + } + + if (msg_list.msg_struct_info) { + ret = msg_release_list_struct(&msg_list); + DBG("Err%d", ret); + } g_ptr_array_free(array, TRUE); error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL, "InternalError"); @@ -1677,9 +1679,7 @@ static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent, msg_struct_t msg = NULL; msg_struct_t send_opt = NULL; -#ifdef SUPPORT_EMAIL - email_mail_data_t *mail_data = NULL; -#endif + message_id = __bt_get_uid(message_name); if (message_id == -1) goto fail; @@ -1709,44 +1709,6 @@ static gboolean bluetooth_map_get_message(BluetoothMapAgent *agent, msg_release_struct(&msg); msg_release_struct(&send_opt); -#ifdef SUPPORT_EMAIL - } else if (msg_type == BT_EMAIL) { - - FILE *body_file; - int account_id; - long read_size; - long email_size; - - if (EMAIL_ERROR_NONE != - email_load_default_account_id(&account_id)) - goto fail; - - if (EMAIL_ERROR_NONE != - email_get_mail_data(message_id, &mail_data)) - goto fail; - - body_file = fopen(mail_data->file_path_plain, "r"); - if (body_file == NULL) - body_file = fopen(mail_data->file_path_html, "rb"); - - if (body_file != NULL) { - fseek(body_file , 0, SEEK_END); - email_size = ftell(body_file); - rewind(body_file); - - buf = (char *)g_malloc0(sizeof(char) * email_size); - - read_size = fread(buf, 1, email_size, body_file); - - fclose(body_file); - - if (read_size != email_size) - goto fail; - } else - buf = (char *)g_strdup(""); - - email_free_mail_data(&mail_data, 1); -#endif } else { DBG("msg_type not supported %d \n", msg_type); goto fail; @@ -1767,11 +1729,6 @@ fail: if (send_opt) msg_release_struct(&send_opt); -#ifdef SUPPORT_EMAIL - if (mail_data) - email_free_mail_data(&mail_data, 1); -#endif - error = __bt_map_agent_error(BT_MAP_AGENT_ERROR_INTERNAL, "InternalError"); dbus_g_method_return_error(context, error); @@ -1860,7 +1817,7 @@ static gboolean bluetooth_map_push_message_data(BluetoothMapAgent *agent, if (MSG_OUTBOX_ID == folder_id) send = TRUE; - body = bmsg_get_msg_body(bmsg_info); + body = bmsg_get_msg_body(bmsg_info, opt.native); if (body == NULL) goto done; @@ -1896,22 +1853,9 @@ static gboolean bluetooth_map_update_message(BluetoothMapAgent *agent, DBusGMethodInvocation *context) { int err = TRUE; -#ifdef SUPPORT_EMAIL - int handle; - err = email_sync_header_for_all_account(&handle); - - if (err == EMAIL_ERROR_NONE) { - DBG("Handle to stop download = %d \n", handle); - } else { - ERR("Message Update failed \n"); - } dbus_g_method_return(context, err); - return (err == EMAIL_ERROR_NONE) ? TRUE : FALSE; -#else - dbus_g_method_return(context, err); return TRUE; -#endif } static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent, @@ -1921,9 +1865,7 @@ static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent, { int message_id = 0; int msg_type = BT_SMS; -#ifdef SUPPORT_EMAIL - email_mail_data_t *mail_data = NULL; -#endif + GError *error = NULL; DBG("+\n"); @@ -1981,26 +1923,9 @@ static gboolean bluetooth_map_set_read_status(BluetoothMapAgent *agent, if (msg_err != MSG_SUCCESS) goto fail; -#ifdef SUPPORT_EMAIL - } else if (msg_type == BT_EMAIL) { - - if (email_get_mail_data(message_id, &mail_data) != - EMAIL_ERROR_NONE) { - ERR("email_get_mail_data failed\n"); - goto fail; - } - - if (email_set_flags_field(mail_data->account_id, &message_id, 1, - EMAIL_FLAGS_SEEN_FIELD, read_status, 0) != - EMAIL_ERROR_NONE) { - email_free_mail_data(&mail_data, 1); - goto fail; - } - - email_free_mail_data(&mail_data, 1); -#endif - } else + } else { goto fail; + } dbus_g_method_return(context); DBG("-\n"); @@ -2022,9 +1947,7 @@ static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent, { int message_id = 0; int msg_type = BT_SMS; -#ifdef SUPPORT_EMAIL - email_mail_data_t *mail_data = NULL; -#endif + GError *error = NULL; DBG("+\n"); @@ -2040,21 +1963,6 @@ static gboolean bluetooth_map_set_delete_status(BluetoothMapAgent *agent, MSG_SUCCESS) { goto fail; } -#ifdef SUPPORT_EMAIL - } else if (msg_type == BT_EMAIL) { - - if (email_get_mail_data(message_id, &mail_data) != - EMAIL_ERROR_NONE) - goto fail; - - if (email_delete_mail(mail_data->mailbox_id, &message_id, - 1, 1) != EMAIL_ERROR_NONE) { - email_free_mail_data(&mail_data, 1); - goto fail; - } - - email_free_mail_data(&mail_data, 1); -#endif } else goto fail; @@ -2085,12 +1993,22 @@ static gboolean bluetooth_map_noti_registration(BluetoothMapAgent *agent, return TRUE; } -int main(int argc, char **argv) +static gboolean bluetooth_map_destroy_agent(BluetoothMapAgent *agent, + DBusGMethodInvocation *context) +{ + DBG("+"); + g_main_loop_quit(g_mainloop); + DBG("-"); +} + +int main(void) { BluetoothMapAgent *bluetooth_map_obj = NULL; DBusGProxy *bus_proxy = NULL; guint result = 0; + int ret; GError *error = NULL; + DBG("Starting Bluetooth MAP agent"); g_type_init(); @@ -2150,13 +2068,23 @@ int main(int argc, char **argv) if (__bluetooth_map_start_service() == FALSE) goto failure; + g_tapi_handle = tel_init(NULL); + if (!g_tapi_handle) + goto failure; + + ret = tel_get_sms_sca(g_tapi_handle, 0, __bt_get_sms_sca, NULL); + if (ret != TAPI_API_SUCCESS) + goto failure; + g_main_loop_run(g_mainloop); failure: - DBG("Terminate the bluetooth-map-agent\n"); __bt_remove_list(id_list); + tel_deinit(g_tapi_handle); + g_free(g_sca_info); + if (g_mns_path) __bt_mns_client_disconnect(); if (bus_proxy) @@ -2168,5 +2096,6 @@ int main(int argc, char **argv) __bluetooth_map_stop_service(); + DBG("Terminate Bluetooth MAP agent\n"); return EXIT_FAILURE; } diff --git a/map-agent/bluetooth_map_agent.xml b/map-agent/bluetooth_map_agent.xml index fea0177..977418b 100644 --- a/map-agent/bluetooth_map_agent.xml +++ b/map-agent/bluetooth_map_agent.xml @@ -56,5 +56,8 @@ + + + diff --git a/map-agent/map_bmessage.c b/map-agent/map_bmessage.c index febfe03..a6ab10a 100644 --- a/map-agent/map_bmessage.c +++ b/map-agent/map_bmessage.c @@ -21,11 +21,13 @@ #include #include -#include +#include +#include #include #define CRLF_LEN 2 +#define BT_SMS_DATA_MAX_LEN 165 #define BMSG_TAG "BEGIN:BMSG\r\n" #define VER_TAG "VERSION:" @@ -108,12 +110,122 @@ void print_bmsg(struct bmsg_data *bmsg) } } +static gchar *__bt_unpack_gsm7bit_msg(const char* pdu, int in_len) +{ + int i; + int pos = 0; + int shift = 0; + gchar data[BT_SMS_DATA_MAX_LEN + 1] = {0,}; + + for (i = 0; i < in_len; i++) { + if (shift == 0) { + data[i] = pdu[pos] & 0x7F; + + shift = 7; + pos++; + } else { + data[i] = (pdu[pos - 1] >> shift) | + (pdu[pos] << (8 - shift)); + data[i] &= 0x7F; + + shift--; + if (shift > 0) + pos++; + } + } + + DBG("msg = %s\n", data); + return g_strdup(data); +} + +static gchar *__bt_get_msg_body_from_pdu(gchar *pdu, guint64 pdu_len) +{ + int index = 0; + int i; + int j = 0; + int dcs; + int udh = 0; + int coding_scheme; + int phone_num_len = 0; + char temp[3]; + char msg_data[BT_SMS_DATA_MAX_LEN + 1] = {0,}; + unsigned char pdu_data[TAPI_NETTEXT_MSG_SIZE_MAX] = {0,}; + + for (i = 0; i < (pdu_len - 1);) { + snprintf(temp, sizeof(temp), "%c%c", pdu[i], pdu[i+1]); + + pdu_data[j] = g_ascii_strtoull(temp, NULL, 16); + DBG("pdu_data = %02x\n", pdu_data[j]); + j++; + i = i + 2; + } + + DBG("pdu[%d] = %x\n", index, pdu_data[index]); + if (pdu[index] == 0x00) + index++; + else + index = index + pdu_data[index]; + + /* TP-MTI */ + index = index + 1; + + if (pdu_data[index] & 0x40) + udh = 1; + + DBG("udh = %d", udh); + + /* TP-MR */ + index = index + 1; + + /* phone number length */ + index = index + 1; + DBG("pdu[%d] = %x\n", index, pdu_data[index]); + + if ((pdu_data[index] % 2) == 0) + phone_num_len = pdu_data[index] / 2; + else + phone_num_len = pdu_data[index] / 2 + 1; + + DBG("phone_num_len [%d]\n", phone_num_len); + + /* phone number type */ + index = index + 1; + + /* phone_num_len/2 encoded phone num length */ + index = index + phone_num_len; + + /* TP-PID */ + index = index + 1; + + /* TP-DCS */ + index = index + 1; + + dcs = pdu_data[index]; + coding_scheme = (dcs & 0x0C) >> 2; + DBG("coding_scheme = %d\n", coding_scheme); + + /* TP-VP */ + index = index + 1; + + /* TP-UDL */ + index = index + 1; + int udl = pdu_data[index]; + DBG("udl = %x\n", udl); + + /* message body */ + index = index + 1; + + memcpy(msg_data, (void*)&pdu_data[index], udl); + + return __bt_unpack_gsm7bit_msg(msg_data, udl); +} + char *bmsg_get_msg_folder(struct bmsg_data *bmsg) { return g_strdup(bmsg->folder); } -char *bmsg_get_msg_body(struct bmsg_data *bmsg) +char *bmsg_get_msg_body(struct bmsg_data *bmsg, gboolean utf) { struct benv_data *env_data; int i = 0; @@ -127,8 +239,16 @@ char *bmsg_get_msg_body(struct bmsg_data *bmsg) DBG("env_data->body_content->length = %" G_GUINT64_FORMAT "\n", env_data->body_content->length); - return g_strndup(env_data->body_content->msg, - env_data->body_content->length); + + if (utf == FALSE) { + return __bt_get_msg_body_from_pdu( + env_data->body_content->msg, + env_data->body_content->length); + } else { + return g_strndup( + env_data->body_content->msg, + env_data->body_content->length); + } } i++; @@ -161,7 +281,8 @@ GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg) if (rvcard->tel != NULL) { DBG("vcard->tel = %s\n", rvcard->tel); - receiver = g_slist_append(receiver, rvcard->tel); + receiver = g_slist_append(receiver, + rvcard->tel); } rvcard = g_slist_nth_data(env_data->recipient_vcard, k); @@ -459,7 +580,7 @@ struct bmsg_envelope *bmsg_get_envelope_data(gchar **block_data) return envelope_data; } -struct bmsg_data * bmsg_parse(gchar *buf) +struct bmsg_data *bmsg_parse(gchar *buf) { gchar *block_data; gchar *sub_block_data; diff --git a/map-agent/map_bmessage.h b/map-agent/map_bmessage.h index 4cdadf7..4e8ba69 100644 --- a/map-agent/map_bmessage.h +++ b/map-agent/map_bmessage.h @@ -62,7 +62,7 @@ struct bmsg_data { struct bmsg_data * bmsg_parse(gchar *buf); char *bmsg_get_msg_folder(struct bmsg_data *bmsg); -char *bmsg_get_msg_body(struct bmsg_data *bmsg); +char *bmsg_get_msg_body(struct bmsg_data *bmsg, gboolean utf); GSList *bmsg_get_msg_recepients(struct bmsg_data *bmsg); #ifdef __cplusplus diff --git a/packaging/bluetooth-agent.spec b/packaging/bluetooth-agent.spec index be47e72..5bfe3c3 100644 --- a/packaging/bluetooth-agent.spec +++ b/packaging/bluetooth-agent.spec @@ -3,17 +3,18 @@ Summary: Bluetooth agent packages that support various external profiles Version: 0.0.8 Release: 2 Group: TO_BE/FILLED_IN -License: TO BE FILLED IN +License: Apache License, Version 2.0 Source0: %{name}-%{version}.tar.gz +BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(contacts-service2) BuildRequires: pkgconfig(dbus-glib-1) BuildRequires: pkgconfig(msg-service) -BuildRequires: pkgconfig(email-service) BuildRequires: pkgconfig(tapi) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(appsvc) +BuildRequires: pkgconfig(capi-appfw-application) BuildRequires: cmake %description @@ -23,6 +24,9 @@ Bluetooth agent packages that support various external profiles %setup -q %build +export CFLAGS+=" -fpie -fvisibility=hidden" +export LDFLAGS+=" -Wl,--rpath=/usr/lib -Wl,--as-needed -Wl,--unresolved-symbols=ignore-in-shared-libs -pie" + cmake . -DCMAKE_INSTALL_PREFIX=/usr make VERBOSE=1 diff --git a/pb-agent/bluetooth_pb_agent.c b/pb-agent/bluetooth_pb_agent.c index 93ad026..f910fa0 100644 --- a/pb-agent/bluetooth_pb_agent.c +++ b/pb-agent/bluetooth_pb_agent.c @@ -169,6 +169,9 @@ static gboolean bluetooth_pb_add_contact (BluetoothPbAgent *agent, const char *filename, GError **error); +static gboolean bluetooth_pb_destroy_agent(BluetoothPbAgent *agent, + DBusGMethodInvocation *context); + static void __bluetooth_pb_dbus_return_error(DBusGMethodInvocation *context, gint code, const gchar *message); @@ -1270,6 +1273,7 @@ static void __bluetooth_pb_get_vcards(BluetoothPbAgent *agent, status = contacts_db_get_records_with_query(query, offset, limit, &record_list); if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); contacts_query_destroy(query); return; } @@ -1345,8 +1349,10 @@ static void __bluetooth_pb_get_contact_list(BluetoothPbAgent *agent, status = contacts_db_get_records_with_query(query, -1, -1, &record_list); - if (status != CONTACTS_ERROR_NONE) + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); return; + } status = contacts_list_first(record_list); @@ -1414,8 +1420,10 @@ static void __bluetooth_pb_get_phone_log_list(BluetoothPbAgent *agent, status = contacts_db_get_records_with_query(query, -1, -1, &record_list); - if (status != CONTACTS_ERROR_NONE) + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); return; + } status = contacts_list_first(record_list); @@ -1551,8 +1559,10 @@ static void __bluetooth_pb_get_contact_list_number(BluetoothPbAgent *agent, from - 1 , offset, &record_list); - if (status != CONTACTS_ERROR_NONE) + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); return; + } status = contacts_list_first(record_list); @@ -1628,8 +1638,10 @@ static void __bluetooth_pb_get_phone_log_list_number(BluetoothPbAgent *agent, from - 1 , offset, &record_list); - if (status != CONTACTS_ERROR_NONE) + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); return; + } status = contacts_list_first(record_list); if (status != CONTACTS_ERROR_NONE) { @@ -1732,8 +1744,10 @@ static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent, status = contacts_db_get_records_with_query(query, -1, -1, &record_list); - if (status != CONTACTS_ERROR_NONE) + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); return; + } status = contacts_list_first(record_list); @@ -1773,6 +1787,7 @@ static void __bluetooth_pb_get_contact_list_name(BluetoothPbAgent *agent, i++; } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE); + contacts_list_destroy(record_list, TRUE); } static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent, @@ -1790,8 +1805,10 @@ static void __bluetooth_pb_get_phone_log_list_name(BluetoothPbAgent *agent, -1, -1, &record_list); - if (status != CONTACTS_ERROR_NONE) + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); return; + } status = contacts_list_first(record_list); @@ -1962,10 +1979,12 @@ static void __bluetooth_pb_list_ptr_array_free(gpointer data) static void __bluetooth_pb_agent_signal_handler(int signum) { - if (mainloop) + if (mainloop) { g_main_loop_quit(mainloop); - else + } else { + DBG("Terminate Bluetooth PBAP agent"); exit(0); + } } @@ -2087,7 +2106,13 @@ static void __bluetooth_pb_agent_dbus_init(BluetoothPbAgent *agent) G_OBJECT(agent)); } -int main(int argc, char **argv) +static gboolean bluetooth_pb_destroy_agent(BluetoothPbAgent *agent, + DBusGMethodInvocation *context) +{ + g_main_loop_quit(mainloop); +} + +int main(void) { BluetoothPbAgent *agent; @@ -2095,6 +2120,7 @@ int main(int argc, char **argv) gint tapi_result; struct sigaction sa; + DBG("Starting Bluetooth PBAP agent"); g_type_init(); @@ -2139,23 +2165,21 @@ int main(int argc, char **argv) g_main_loop_run(mainloop); - DBG("Terminate the bluetooth-pb-agent\n"); - - if (agent) { - contacts_db_remove_changed_cb(_contacts_event._uri, - __bluetooth_pb_contact_changed, - g_object_ref(agent)); - - g_object_unref(agent); + if (contacts_db_remove_changed_cb(_contacts_event._uri, + __bluetooth_pb_contact_changed, + g_object_ref(agent)) != CONTACTS_ERROR_NONE) { + DBG("Cannot remove changed callback"); } + g_object_unref(agent); - contacts_disconnect2(); + if (contacts_disconnect2() != CONTACTS_ERROR_NONE) + DBG("contacts_disconnect2 failed \n"); g_signal_emit(agent, signals[CLEAR], 0); - if (agent) - g_object_unref(agent); + g_object_unref(agent); + DBG("Terminate Bluetooth PBAP agent"); return ret; } diff --git a/pb-agent/bluetooth_pb_agent.xml b/pb-agent/bluetooth_pb_agent.xml index f41836c..e9f758b 100644 --- a/pb-agent/bluetooth_pb_agent.xml +++ b/pb-agent/bluetooth_pb_agent.xml @@ -49,6 +49,10 @@ + + + + diff --git a/pb-agent/bluetooth_pb_vcard.c b/pb-agent/bluetooth_pb_vcard.c index c17dc44..a766666 100644 --- a/pb-agent/bluetooth_pb_vcard.c +++ b/pb-agent/bluetooth_pb_vcard.c @@ -2065,70 +2065,49 @@ static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id) CONTACTS_MATCH_EQUAL, phonelog_id); - if (status != CONTACTS_ERROR_NONE) { - contacts_filter_destroy(filter); - return 0; - } + if (status != CONTACTS_ERROR_NONE) + goto done; status = contacts_query_create(_contacts_person_phone_log._uri, &query); - if (status != CONTACTS_ERROR_NONE) { - contacts_filter_destroy(filter); - return 0; - } + if (status != CONTACTS_ERROR_NONE) + goto done; status = contacts_query_set_filter(query, filter); - if (status != CONTACTS_ERROR_NONE) { - contacts_filter_destroy(filter); - contacts_query_destroy(query); - return 0; - } + if (status != CONTACTS_ERROR_NONE) + goto done; status = contacts_db_get_records_with_query(query, -1, -1, &record_list); - if (status != CONTACTS_ERROR_NONE) { - contacts_filter_destroy(filter); - contacts_query_destroy(query); - - return 0; - } + if (status != CONTACTS_ERROR_NONE) + goto done; status = contacts_list_first(record_list); - if (status != CONTACTS_ERROR_NONE) { - contacts_list_destroy(record_list, TRUE); - contacts_filter_destroy(filter); - contacts_query_destroy(query); - - return 0; - } + if (status != CONTACTS_ERROR_NONE) + goto done; status = contacts_list_get_current_record_p(record_list, &record); - if (status != CONTACTS_ERROR_NONE) { - contacts_list_destroy(record_list, TRUE); - contacts_filter_destroy(filter); - contacts_query_destroy(query); - - return 0; - } + if (status != CONTACTS_ERROR_NONE) + goto done; status = contacts_record_get_int(record, _contacts_person_phone_log.person_id, &person_id); - if (status != CONTACTS_ERROR_NONE) { - contacts_list_destroy(record_list, TRUE); - contacts_filter_destroy(filter); - contacts_query_destroy(query); + if (status != CONTACTS_ERROR_NONE) + goto done; - return 0; - } +done: + if (record_list != NULL) + contacts_list_destroy(record_list, TRUE); - contacts_list_destroy(record_list, TRUE); contacts_filter_destroy(filter); - contacts_query_destroy(query); + + if (query != NULL) + contacts_query_destroy(query); return person_id; } -- 2.7.4