From 6afa5909e0fddd2af0cc7070faa58527d05a130c Mon Sep 17 00:00:00 2001 From: Sangki Park Date: Fri, 5 Jan 2018 14:02:49 +0900 Subject: [PATCH] Update AG and HF agent codes from wearable product Change-Id: I4ebc2965fca1aaab0c6d4e2c77493cd0cb3dc9e2 Signed-off-by: Sangki Park --- ag-agent/CMakeLists.txt | 4 + ag-agent/bluetooth-ag-agent.c | 1078 +++++++++++++++++++++----------- ag-agent/bluetooth-ag-agent.h | 30 +- ag-agent/bluetooth-ag-handler.c | 201 +++++- ag-agent/bluetooth-ag-handler.h | 6 + ag-agent/bluetooth-ag-manager.c | 337 +++++----- ag-agent/bluetooth-ag-phonebook.c | 1236 +++++++++++++++++++++++++++++++++++++ ag-agent/bluetooth-ag-phonebook.h | 71 +++ hf-agent/bluetooth-hf-agent.c | 18 + hf-agent/bluetooth-hf-agent.h | 2 + packaging/bluetooth-agent.spec | 15 +- 11 files changed, 2436 insertions(+), 562 deletions(-) mode change 100755 => 100644 ag-agent/bluetooth-ag-agent.h mode change 100755 => 100644 ag-agent/bluetooth-ag-handler.h create mode 100644 ag-agent/bluetooth-ag-phonebook.c create mode 100644 ag-agent/bluetooth-ag-phonebook.h diff --git a/ag-agent/CMakeLists.txt b/ag-agent/CMakeLists.txt index 99fe7b4..ba4b676 100644 --- a/ag-agent/CMakeLists.txt +++ b/ag-agent/CMakeLists.txt @@ -4,6 +4,7 @@ PROJECT(bluetooth-ag-agent C) SET(SRCS bluetooth-ag-agent.c bluetooth-ag-handler.c bluetooth-ag-manager.c + bluetooth-ag-phonebook.c ../include/bluetooth-agent-profile.c) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) @@ -12,9 +13,12 @@ SET(PKG_MODULES dlog dbus-glib-1 vconf + syspopup-caller + capi-network-bluetooth appsvc contacts-service2 tapi + capi-system-device capi-appfw-application aul capi-system-info diff --git a/ag-agent/bluetooth-ag-agent.c b/ag-agent/bluetooth-ag-agent.c index e3b1242..066d2d3 100644 --- a/ag-agent/bluetooth-ag-agent.c +++ b/ag-agent/bluetooth-ag-agent.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -31,44 +32,61 @@ #include "bluetooth-ag-handler.h" #include "bluetooth-agent-profile.h" +#include +#include + #include #include #include +#include #include +#include #include #include #include #include "contacts.h" #include "appsvc.h" - -static GMainLoop *gmain_loop = NULL; -static GDBusProxy *service_gproxy; -static guint interface_added_sig_id = 0; -static guint interface_removed_sig_id = 0; -static guint name_owner_sig_id = 0; +#include +#include +#include + +static GMainLoop *gmain_loop; +static GDBusProxy *profile_gproxy; +static guint interface_added_sig_id; +static guint interface_removed_sig_id; +static guint proterty_changed_sig_id; +static guint name_owner_sig_id; GDBusConnection *ag_dbus_conn = NULL; gchar *remote_dev_path = NULL; gboolean wbs_en; uint16_t hfp_ver; uint16_t hsp_ver; -static TapiHandle *tapi_handle; +static TapiHandle *tapi_handle[3]; +int sim1; +int sim2; +static TapiHandle *tapi_handle_preferred_sim; extern wbs_options wbs_opts; GSList *active_devices = NULL; -static gchar *local_addr = NULL; -static GDBusProxy *app_gproxy; +static gchar *local_addr; static gboolean call_launch_requested = FALSE; -static gchar* sco_owner = NULL; -static guint sco_open_timer_id = 0; -static gboolean sco_open_request = FALSE; +static gchar* sco_owner; +static guint sco_open_timer_id; +static gboolean sco_open_request; static guint hf_bluez_id; static guint hs_bluez_id; static guint app_id; +static guint device_property_id; #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE -static guint media_sig_id = 0; -static guint media_state_sig_id = 0; +static guint media_sig_id; +static guint media_state_sig_id; static bt_ag_media_transport_state_t transport_state; #endif +static int last_speaker_gain = 9; + +#define GET_TAPI_HANDLE \ + (tapi_handle_preferred_sim != NULL) ? tapi_handle_preferred_sim : \ + ((sim1 == 1) ? tapi_handle[0] : tapi_handle[1]) #define HSP_AG_UUID "00001112-0000-1000-8000-00805f9b34fb" #define HFP_AG_UUID "0000111f-0000-1000-8000-00805f9b34fb" @@ -78,9 +96,7 @@ static bt_ag_media_transport_state_t transport_state; #define DEFAULT_ADAPTER_OBJECT_PATH "/org/bluez/hci0" #define VCONF_KEY_BT_LUNAR_ENABLED "db/wms/bt_loop_device_hfp_connected" -#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG) -#define CALL_APP_ID "org.tizen.call-ui" -#endif +#define CALL_ALIAS_APP_ID "tizen.call" #if defined(TIZEN_SUPPORT_DUAL_HF) #define VCONF_KEY_BT_HOST_BT_MAC_ADDR "db/wms/host_bt_mac" @@ -105,6 +121,9 @@ static const gchar ag_agent_bluez_introspection_xml[] = " " " " " " +" " +" " +" " " " ""; @@ -191,11 +210,6 @@ typedef struct { uint16_t setting; } bt_voice; -struct ag_codec { - bt_ag_info_t *bt_ag_info; - char *codec_status; -}; - bt_ag_status_t ag = { .telephony_ready = FALSE, .features = 0, @@ -217,6 +231,10 @@ static int __bt_ag_sco_connect(bt_ag_info_t *hs); void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state); static void __bt_ag_agent_reg_sim_event(TapiHandle *handle, void *user_data); static void __bt_ag_agent_dereg_sim_event(TapiHandle *handle); +static uint32_t __bt_ag_agent_get_ag_features(void); +static void __bt_ag_agent_tel_cb(TapiHandle *handle, int result, void *data, void *user_data); +static void __bt_ag_agent_subscribe_tapi_updates(TapiHandle *handle); +static void __bt_ag_agent_unsubscribe_tapi_updates(TapiHandle *handle); static void __bt_ag_name_owner_changed_cb(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, @@ -224,6 +242,7 @@ static void __bt_ag_name_owner_changed_cb(GDBusConnection *connection, const gchar *signal_name, GVariant *parameters, gpointer user_data); +static GError *__bt_ag_agent_set_error(bt_hfp_agent_error_t error); static void __bt_convert_addr_type_to_rev_string(char *address, unsigned char *addr) @@ -236,8 +255,7 @@ static void __bt_convert_addr_type_to_rev_string(char *address, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); } -static GDBusProxy *__bt_ag_gdbus_init_service_proxy(const gchar *service, - const gchar *path, const gchar *interface) +static GDBusProxy *__bt_ag_gdbus_init_profile_proxy(void) { FN_START; @@ -257,9 +275,8 @@ static GDBusProxy *__bt_ag_gdbus_init_service_proxy(const gchar *service, proxy = g_dbus_proxy_new_sync(ag_dbus_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, - service, path, - interface, NULL, &err); - + BLUEZ_SERVICE_NAME, "/org/bluez", + BLUEZ_PROFILE_MGMT_INTERFACE, NULL, &err); if (!proxy) { if (err) { ERR("Unable to create proxy: %s", err->message); @@ -268,6 +285,8 @@ static GDBusProxy *__bt_ag_gdbus_init_service_proxy(const gchar *service, return NULL; } + profile_gproxy = proxy; + FN_END; return proxy; } @@ -275,9 +294,39 @@ static GDBusProxy *__bt_ag_gdbus_init_service_proxy(const gchar *service, static GDBusProxy *__bt_ag_gdbus_get_app_proxy(const gchar *service, const gchar *path, const gchar *interface) { - return (app_gproxy) ? app_gproxy : - __bt_ag_gdbus_init_service_proxy(service, - path, interface); + FN_START; + + GDBusProxy *proxy; + GError *err = NULL; + + if (ag_dbus_conn == NULL) + ag_dbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + + if (!ag_dbus_conn) { + if (err) { + ERR("Unable to connect to gdbus: %s", err->message); + g_clear_error(&err); + } + return NULL; + } + + DBG("%s %s %s", service, path, interface); + + proxy = g_dbus_proxy_new_sync(ag_dbus_conn, + G_DBUS_PROXY_FLAGS_NONE, NULL, + service, path, + interface, NULL, &err); + + if (!proxy) { + if (err) { + ERR("Unable to create proxy: %s", err->message); + g_clear_error(&err); + } + return NULL; + } + + FN_END; + return proxy; } static int __bt_ag_agent_gdbus_method_send(const char *service, @@ -310,6 +359,7 @@ static int __bt_ag_agent_gdbus_method_send(const char *service, g_clear_error(&error); } + g_object_unref(proxy); return BT_HFP_AGENT_ERROR_INTERNAL; } @@ -320,6 +370,8 @@ static int __bt_ag_agent_gdbus_method_send(const char *service, G_DBUS_CALL_FLAGS_NONE, 2000, NULL, NULL, NULL); } + g_object_unref(proxy); + return BT_HFP_AGENT_ERROR_NONE; } @@ -392,25 +444,24 @@ static void __bt_ag_agent_remove_watch(guint *watch_id) #if defined(TIZEN_SUPPORT_DUAL_HF) gboolean __bt_ag_agent_is_companion_device(const char *addr) { -#if defined(TIZEN_PROFILE_WEARABLE) - char *host_device_address = NULL; - host_device_address = vconf_get_str(VCONF_KEY_BT_HOST_BT_MAC_ADDR); + if (TIZEN_PROFILE_WEARABLE) { + char *host_device_address = NULL; + host_device_address = vconf_get_str(VCONF_KEY_BT_HOST_BT_MAC_ADDR); - if (!host_device_address) { - INFO("Failed to get a companion device address"); - return FALSE; - } + if (!host_device_address) { + INFO("Failed to get a companion device address"); + return FALSE; + } - if (g_strcmp0(host_device_address, addr) == 0) { - INFO("addr[%s] is companion device", addr); - return TRUE; + if (g_strcmp0(host_device_address, addr) == 0) { + INFO("addr[%s] is companion device", addr); + free(host_device_address); + return TRUE; + } + free(host_device_address); + return FALSE; } - - return FALSE; -#else - /* TODO : Need to add companion device check condition for Phone models */ return FALSE; -#endif } void __bt_convert_device_path_to_address(const gchar *device_path, @@ -459,7 +510,7 @@ gboolean __bt_ag_agent_check_dual_hf_condition(const gchar *device_path) __bt_convert_device_path_to_address(device_path, device_address); is_companion_device = __bt_ag_agent_is_companion_device(device_address); - DBG(" device_address[%s]", device_address); + DBG_SECURE(" device_address[%s]", device_address); DBG(" is_companion_device[%d]", is_companion_device); if (__bt_ag_agent_is_companion_device_connected()) { @@ -498,30 +549,9 @@ static gboolean __bt_get_outgoing_callapp_type(int *callapp_type) if (NULL == callapp_type) return FALSE; -#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG) - *callapp_type = BT_VOICE_CALL; - FN_END; - return TRUE; -#else -#if 0 - int ret; - ret = vconf_get_int( - VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT, - callapp_type); - if (ret != 0) { - ERR("Failed to read [%s]\n", - VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT); - return FALSE; - } - - INFO(" [%s] = [%d]\n", - VCONFKEY_CISSAPPL_OUTGOING_CALL_TYPE_INT, *callapp_type); -#endif - /* The vconf value does not include in platform. */ *callapp_type = BT_VOICE_CALL; FN_END; return TRUE; -#endif } static gboolean __bt_get_outgoing_call_condition(int *condition) @@ -531,27 +561,9 @@ static gboolean __bt_get_outgoing_call_condition(int *condition) if (NULL == condition) return FALSE; -#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG) *condition = BT_MO_ONLY_UNLOCKED; FN_END; return TRUE; -#else -#if 0 - int ret; - ret = vconf_get_int( - VCONFKEY_CISSAPPL_OUTGOING_CALL_CONDITIONS_INT, - condition); - if (ret != 0) { - ERR("Failed to read [%s]\n", - VCONFKEY_CISSAPPL_OUTGOING_CALL_CONDITIONS_INT); - return FALSE; - } -#endif - /* The vconf value does not include in platform. */ - *condition = BT_MO_ONLY_UNLOCKED; - FN_END; - return TRUE; -#endif } static gboolean __bt_ag_agent_launch_call_app(const char *number) @@ -573,23 +585,24 @@ static gboolean __bt_ag_agent_launch_call_app(const char *number) if (strlen(number) != 0) bundle_add(b, "number", number); - aul_launch_app_async(CALL_APP_ID, b); + aul_launch_app_async(CALL_ALIAS_APP_ID, b); bundle_free(b); FN_END; return TRUE; } -static void *__bt_ag_agent_launch_call_req(void *arg) +static gboolean __bt_ag_agent_launch_call_req(void *arg) { FN_START; bundle *b = (bundle *)arg; + if (appsvc_run_service(b, 0, NULL, NULL) < 0) ERR("Unable to run app svc"); bundle_free(b); call_launch_requested = FALSE; FN_END; - return NULL; + return FALSE; } static gboolean __bt_ag_agent_make_call(const char *number) @@ -598,7 +611,6 @@ static gboolean __bt_ag_agent_make_call(const char *number) char telnum[BT_MAX_TEL_NUM_STRING]; bundle *b; - pthread_t thread_id; if (TIZEN_PROFILE_WEARABLE) return __bt_ag_agent_launch_call_app(number); @@ -618,15 +630,7 @@ static gboolean __bt_ag_agent_make_call(const char *number) appsvc_add_data(b, "ctindex", "-1"); call_launch_requested = TRUE; - if (pthread_create(&thread_id, NULL, - (void *)&__bt_ag_agent_launch_call_req, - (void *)b) < 0) { - ERR("pthread_create() is failed"); - call_launch_requested = FALSE; - return FALSE; - } - if (pthread_detach(thread_id) < 0) - ERR("pthread_detach() is failed"); + g_idle_add(__bt_ag_agent_launch_call_req, b); FN_END; return TRUE; @@ -729,7 +733,7 @@ bt_hfp_agent_error_t _bt_ag_agent_dial_num(const gchar *number, guint flags) goto fail; } - DBG("Number = %s", number); + DBG_SECURE("Number = %s", number); DBG("flags = %d", flags); if (!__bt_is_phone_locked(&phone_lock_state)) { @@ -853,7 +857,7 @@ bt_hfp_agent_error_t _bt_ag_agent_dial_memory(unsigned int location) goto done; } - DBG("number %s", number); + DBG_SECURE("number %s", number); /*Make Voice call*/ if (!__bt_ag_agent_make_call(number)) { @@ -917,16 +921,17 @@ gboolean _bt_ag_agent_threeway_call(unsigned int chld_value, DBG("Value = %d", chld_value); DBG("Sender = %s", sender); -#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG) - /* Check if AG supports (i.e. ag_chld_str = "0,1,2") the requested CHLD; - if not return FALSE */ - if (chld_value != 0 && chld_value != 1 && chld_value != 2) - return FALSE; -#else + if (TIZEN_PROFILE_WEARABLE) { + /* Check if AG supports (i.e. ag_chld_str = "0,1,2") the requested CHLD; + if not return FALSE */ + if (chld_value != 0 && chld_value != 1 && chld_value != 2) + return FALSE; + } else { if (chld_value != 0 && chld_value != 1 && chld_value != 2 && chld_value != 3) return FALSE; -#endif + } + _bt_ag_agent_emit_signal(ag_dbus_conn, path, BT_AG_SERVICE_NAME, "Threeway", g_variant_new("(u)", chld_value)); @@ -1154,12 +1159,14 @@ bt_hfp_agent_error_t _bt_ag_agent_vendor_cmd(const gchar *cmd, gboolean _bt_ag_agent_get_signal_quality(void *device) { - gint rssi; + int rssi; + int ret; FN_START; - - if (vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &rssi)) { - DBG("VCONFKEY_TELEPHONY_RSSI failed\n"); + ret = tel_get_property_int(GET_TAPI_HANDLE, + TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL, &rssi); + if (ret != TAPI_API_SUCCESS) { + ERR("Get signal status failed err = %d\n", ret); goto fail; } @@ -1178,22 +1185,23 @@ fail: gboolean _bt_ag_agent_get_battery_status(void *device) { - gint battery_chrg_status; - gint battery_capacity; + bool battery_chrg_status; + int battery_capacity; + int ret; FN_START; - if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, - &battery_chrg_status)) { - DBG("VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW failed\n"); + ret = device_battery_is_charging(&battery_chrg_status); + if (ret != DEVICE_ERROR_NONE) { + ERR("Get battery charge status failed. Err = %d\n", ret); goto fail; } DBG("Status : %d\n", battery_chrg_status); - if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, - &battery_capacity)) { - DBG("VCONFKEY_SYSMAN_BATTERY_CAPACITY failed\n"); + ret = device_battery_get_percent(&battery_capacity); + if (ret != DEVICE_ERROR_NONE) { + ERR("Get battery capacity status failed. Err = %d\n", ret); goto fail; } @@ -1212,12 +1220,14 @@ fail: gboolean _bt_ag_agent_get_operator_name(void *device) { - char *operator_name; + char *operator_name = NULL; + int ret; FN_START; - operator_name = vconf_get_str(VCONFKEY_TELEPHONY_NWNAME); + ret = tel_get_property_string(GET_TAPI_HANDLE, + TAPI_PROP_NETWORK_NETWORK_NAME, &operator_name); if (NULL == operator_name) { - DBG("vconf_get_str failed"); + DBG("TAPI_PROP_NETWORK_NETWORK_NAME failed (%d)", ret); _bt_hfp_operator_reply(NULL, device); return FALSE; } @@ -1246,7 +1256,7 @@ gboolean _bt_hfp_agent_nrec_status(gboolean status, _bt_ag_agent_emit_signal(ag_dbus_conn, hs->path, BT_AG_SERVICE_NAME, "NrecStatusChanged", - g_variant_new("(b)", status)); + g_variant_new("(b)", hs->nrec_status)); FN_END; return TRUE; } @@ -1256,7 +1266,7 @@ gboolean _bt_ag_agent_get_imei_number(void *device) FN_START; char *imei_number; - imei_number = tel_get_misc_me_imei_sync(tapi_handle); + imei_number = tel_get_misc_me_imei_sync(GET_TAPI_HANDLE); if (NULL == imei_number) { ERR("tel_get_misc_me_imei_sync for imei_number failed"); goto fail; @@ -1311,7 +1321,7 @@ void _bt_ag_agent_get_imsi(void *device) FN_START; TelSimImsiInfo_t imsi; memset(&imsi, 0, sizeof(TelSimImsiInfo_t)); - if (tel_get_sim_imsi(tapi_handle, &imsi) != TAPI_API_SUCCESS) { + if (tel_get_sim_imsi(GET_TAPI_HANDLE, &imsi) != TAPI_API_SUCCESS) { ERR("tel_get_sim_imsi failed"); goto fail; } @@ -1351,8 +1361,8 @@ void _bt_ag_agent_get_creg_status(void *device) int registration_status = 0; int roam_status = 0; - ret = tel_get_property_int(tapi_handle, TAPI_PROP_NETWORK_CIRCUIT_STATUS, - &result); + ret = tel_get_property_int(GET_TAPI_HANDLE, + TAPI_PROP_NETWORK_CIRCUIT_STATUS, &result); if (ret != TAPI_API_SUCCESS) { ERR("tel_get_property_int failed"); return; @@ -1364,8 +1374,9 @@ void _bt_ag_agent_get_creg_status(void *device) DBG_SECURE("Mapped Status %d", registration_status); if (registration_status == BT_AGENT_NETWORK_REG_STATUS_REGISTER_HOME_NETWORK) { - ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status); - if (ret != 0) { + ret = tel_get_property_int(GET_TAPI_HANDLE, + TAPI_PROP_NETWORK_ROAMING_STATUS, &roam_status); + if (ret != TAPI_API_SUCCESS) { ERR("Get roaming status failed err = %d\n", ret); return; } @@ -1433,69 +1444,70 @@ void _bt_ag_agent_get_revision_information(void *device) FN_END; } -#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG) -static gboolean __bt_ag_agent_launch_voice_dial(gboolean activate) +void _bt_ag_agent_set_last_speaker_gain(int gain) { - FN_START; - bundle *b; - - b = bundle_create(); - if (NULL == b) { - ERR("bundle_create() Failed"); - return FALSE; - } - - bundle_add(b, "domain", "bt_headset"); - if (!activate) - bundle_add(b, "action_type", "deactivate"); - - aul_launch_app_async("org.tizen.svoice", b); - bundle_free(b); - FN_END; - return TRUE; + last_speaker_gain = gain; } -#else + static gboolean __bt_ag_agent_launch_voice_dial(gboolean activate) { FN_START; - app_control_h service = NULL; + if (TIZEN_PROFILE_WEARABLE) { + bundle *b; - app_control_create(&service); + b = bundle_create(); + if (NULL == b) { + ERR("bundle_create() Failed"); + return FALSE; + } - if (service == NULL) { - ERR("Service create failed"); - return FALSE; - } + bundle_add(b, "domain", "bt_headset"); + if (!activate) + bundle_add(b, "action_type", "deactivate"); - app_control_set_app_id(service, "org.tizen.svoice"); - app_control_set_operation(service, APP_CONTROL_OPERATION_DEFAULT); - if (app_control_add_extra_data(service, "domain", "bt_headset") - != APP_CONTROL_ERROR_NONE) { - ERR("app_control_add_extra_data failed"); - app_control_destroy(service); - return FALSE; - } + aul_launch_app_async("org.tizen.svoice", b); + bundle_free(b); + FN_END; + return TRUE; + } else { + app_control_h service = NULL; + + app_control_create(&service); + + if (service == NULL) { + ERR("Service create failed"); + return FALSE; + } - if (!activate) - if (app_control_add_extra_data(service, "action_type", "deactivate") + app_control_set_app_id(service, "org.tizen.svoice"); + app_control_set_operation(service, APP_CONTROL_OPERATION_DEFAULT); + if (app_control_add_extra_data(service, "domain", "bt_headset") != APP_CONTROL_ERROR_NONE) { ERR("app_control_add_extra_data failed"); app_control_destroy(service); return FALSE; } - if (app_control_send_launch_request(service, NULL, NULL) != + if (!activate) + if (app_control_add_extra_data(service, "action_type", "deactivate") + != APP_CONTROL_ERROR_NONE) { + ERR("app_control_add_extra_data failed"); + app_control_destroy(service); + return FALSE; + } + + if (app_control_send_launch_request(service, NULL, NULL) != APP_CONTROL_ERROR_NONE) { - ERR("launch failed"); + ERR("launch failed"); + app_control_destroy(service); + return FALSE; + } + app_control_destroy(service); - return FALSE; + FN_END; + return TRUE; } - - app_control_destroy(service); - FN_END; - return TRUE; } -#endif gboolean _bt_ag_agent_voice_dial(gboolean activate) { @@ -1510,6 +1522,9 @@ static void __bt_ag_codec_negotiation_info_reset(bt_ag_info_t *hs, hs->codec_info.is_negotiating = FALSE; hs->codec_info.requested_by_hf = FALSE; hs->codec_info.sending_codec = 0; + g_free(hs->codec_info.status); + hs->codec_info.status = NULL; + if (reset) { hs->codec_info.remote_codecs = 0; hs->codec_info.final_codec = 0; @@ -1525,27 +1540,26 @@ static void __bt_ag_codec_negotiation_info_reset(bt_ag_info_t *hs, static gboolean __bt_ag_codec_negotiation_finished(gpointer user_data) { - struct ag_codec *data = (struct ag_codec *)user_data; + bt_ag_info_t *hs = (bt_ag_info_t *)user_data; - if (g_strcmp0(data->codec_status, "finish") == 0) { + if (g_strcmp0(hs->codec_info.status, "finish") == 0) { DBG("Codec negotiation finished"); - __bt_ag_sco_connect(data->bt_ag_info); - __bt_ag_codec_negotiation_info_reset(data->bt_ag_info, FALSE); - g_free(data->codec_status); - g_free(data); + __bt_ag_sco_connect(hs); + __bt_ag_codec_negotiation_info_reset(hs, FALSE); return TRUE; - } else if (g_strcmp0(data->codec_status, "timeout") == 0) { - DBG("Timeout is occured in codec negotiation"); + } else if (g_strcmp0(hs->codec_info.status, "timeout") == 0) { + ERR("Timeout is occured in codec negotiation"); + /* Codec negotiation is timedout fall back to default NB */ + hs->codec = BT_CVSD_CODEC_ID; + hs->codec_info.final_codec = BT_CVSD_CODEC_ID; } - if (data->bt_ag_info->codec_info.requested_by_hf) { - __bt_ag_codec_negotiation_info_reset(data->bt_ag_info, FALSE); + if (hs->codec_info.requested_by_hf) { + __bt_ag_codec_negotiation_info_reset(hs, FALSE); } else { - __bt_ag_sco_connect(data->bt_ag_info); - __bt_ag_codec_negotiation_info_reset(data->bt_ag_info, FALSE); + __bt_ag_sco_connect(hs); + __bt_ag_codec_negotiation_info_reset(hs, FALSE); } - g_free(data->codec_status); - g_free(data); return FALSE; } @@ -1584,9 +1598,11 @@ static bt_hfp_agent_error_t __bt_ag_set_codec(void *device, char *method) g_clear_error(&err); } + g_object_unref(proxy); return BT_HFP_AGENT_ERROR_INTERNAL; } g_variant_unref(ret); + g_object_unref(proxy); return BT_HFP_AGENT_ERROR_NONE; } @@ -1631,12 +1647,15 @@ static bt_hfp_agent_error_t __bt_hfp_send_bcs_command(bt_ag_info_t *hs, gboolean init_by_hf) { uint32_t codec; - struct ag_codec *data = NULL;; +#ifdef TIZEN_FEATURE_BT_SCO_WIDEBAND if (hs->codec_info.remote_codecs & BT_MSBC_CODEC_MASK) codec = BT_MSBC_CODEC_ID; else codec = BT_CVSD_CODEC_ID; +#else + codec = BT_CVSD_CODEC_ID; +#endif if (wbs_opts.wbs_enable == FALSE) codec = BT_CVSD_CODEC_ID; @@ -1653,18 +1672,12 @@ static bt_hfp_agent_error_t __bt_hfp_send_bcs_command(bt_ag_info_t *hs, hs->codec_info.sending_codec = codec; hs->codec_info.requested_by_hf = init_by_hf; hs->codec_info.final_codec = codec; - - data = g_new0(struct ag_codec, 1); - if (data == NULL) - return BT_HFP_AGENT_ERROR_NO_MEMORY; - - data->bt_ag_info = hs; - data->codec_status = g_strdup("timeout"); + hs->codec_info.status = g_strdup("timeout"); hs->codec_info.nego_timer = g_timeout_add_seconds( HFP_CODEC_NEGOTIATION_TIMEOUT, (GSourceFunc)__bt_ag_codec_negotiation_finished, - data); + hs); return BT_HFP_AGENT_ERROR_NONE; } @@ -1757,6 +1770,8 @@ static int __bt_hfp_available_codecs(bt_ag_info_t *hs, const char *buf) hs->codec_info.is_negotiating = FALSE; hs->codec_info.requested_by_hf = FALSE; hs->codec_info.sending_codec = 0; + g_free(hs->codec_info.status); + hs->codec_info.status = NULL; g_source_remove(hs->codec_info.nego_timer); __bt_hfp_codec_connection_setup(hs, FALSE); } @@ -1787,12 +1802,13 @@ static int __bt_hfp_codec_selection(bt_ag_info_t *hs, const char *buf) { uint32_t codec = 0x00000000; hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE; - struct ag_codec *data = g_new0(struct ag_codec, 1); /* Timer reset */ if (hs->codec_info.nego_timer) { g_source_remove(hs->codec_info.nego_timer); hs->codec_info.nego_timer = 0; + g_free(hs->codec_info.status); + hs->codec_info.status = NULL; } if (!(ag.features & BT_AG_FEATURE_CODEC_NEGOTIATION)) @@ -1803,10 +1819,9 @@ static int __bt_hfp_codec_selection(bt_ag_info_t *hs, const char *buf) BT_HFP_AGENT_ERROR_NONE) err = HFP_STATE_MNGR_ERR_AG_FAILURE; - data->bt_ag_info = hs; - data->codec_status = g_strdup("finish"); + hs->codec_info.status = g_strdup("finish"); _bt_ag_send_response(hs, err); - __bt_ag_codec_negotiation_finished(data); + __bt_ag_codec_negotiation_finished(hs); return 0; } @@ -1836,7 +1851,7 @@ static const char *__bt_ag_state2str(hs_state_t state) return NULL; } -void _bt_convert_addr_string_to_type_rev(unsigned char *addr, +static void __bt_convert_addr_string_to_type_rev(unsigned char *addr, const char *address) { int i; @@ -1900,8 +1915,16 @@ static int __bt_ag_sco_connect(bt_ag_info_t *hs) memset(&sco_addr, 0, sizeof(sco_addr)); sco_addr.sco_family = AF_BLUETOOTH; - __bt_ag_str2ba(local_addr, &sco_addr.sco_bdaddr); - DBG("Local BD address: %s", local_addr); + if (local_addr) { + __bt_ag_str2ba(local_addr, &sco_addr.sco_bdaddr); + DBG_SECURE("Local BD address: %s", local_addr); + } else { + ERR("Local address is NULL"); + ERR("Close SCO skt"); + close(sco_skt); + return BT_HFP_AGENT_ERROR_INTERNAL; + } + err = bind(sco_skt, (struct sockaddr *) &sco_addr, sizeof(sco_addr)); if (err < 0) { @@ -1911,7 +1934,7 @@ static int __bt_ag_sco_connect(bt_ag_info_t *hs) return BT_HFP_AGENT_ERROR_INTERNAL; } - DBG("Socket FD : %d", sco_skt); + DBG_SECURE("Socket FD : %d", sco_skt); io = g_io_channel_unix_new(sco_skt); g_io_channel_set_close_on_unref(io, TRUE); @@ -1944,11 +1967,12 @@ static int __bt_ag_sco_connect(bt_ag_info_t *hs) memset(&sco_addr, 0, sizeof(sco_addr)); sco_addr.sco_family = AF_BLUETOOTH; __bt_ag_str2ba(hs->remote_addr, &sco_addr.sco_bdaddr); - DBG("remotel BD address: %s", hs->remote_addr); + DBG_SECURE("remotel BD address: %s", hs->remote_addr); err = connect(sco_skt, (struct sockaddr *) &sco_addr, sizeof(sco_addr)); if (err < 0 && !(errno == EINPROGRESS || errno == EAGAIN)) { - ERR("ERROR: sco socket connect failed : %d", err); + err = -errno; + ERR("sco socket connect failed : %s (%d)", strerror(-err), -err); ERR("Close SCO skt"); g_io_channel_unref(io); close(sco_skt); @@ -2056,6 +2080,7 @@ static gboolean __bt_ag_sco_server_cb(GIOChannel *chan, BT_VOICE_NUM, &bt_vo, sizeof(bt_vo)); if (err < 0) { ERR("Sco socket set socket option failed"); + g_io_channel_unref(sco_io); close(cli_sco_sock); return FALSE; } @@ -2099,8 +2124,8 @@ static int __bt_ag_start_sco_server(bt_ag_info_t *hs) memset(&addr, 0, sizeof(addr)); addr.sco_family = AF_BLUETOOTH; - _bt_convert_addr_string_to_type_rev(bd_addr.b, hs->remote_addr); - DBG("Bind to address %s", hs->remote_addr); + __bt_convert_addr_string_to_type_rev(bd_addr.b, hs->remote_addr); + DBG_SECURE("Bind to address %s", hs->remote_addr); memcpy(&addr.sco_bdaddr, &bd_addr, sizeof(bdaddr_t)); if (bind(sco_skt, (struct sockaddr *) &addr, sizeof(addr)) < 0) { @@ -2140,6 +2165,7 @@ void __bt_ag_stop_sco_server(bt_ag_info_t *hs) g_io_channel_unref(hs->sco_server); hs->sco_server = NULL; } + __bt_ag_agent_remove_watch(&hs->sco_watch_id); hs->sco_server_started = FALSE; } @@ -2165,10 +2191,10 @@ static gboolean __bt_ag_sco_cb(GIOChannel *chan, GIOCondition cond, if (cond & G_IO_NVAL) return FALSE; - if (name_owner_sig_id != -1) + if (name_owner_sig_id) g_dbus_connection_signal_unsubscribe(ag_dbus_conn, name_owner_sig_id); - name_owner_sig_id = -1; + name_owner_sig_id = 0; g_free(sco_owner); sco_owner = NULL; @@ -2197,6 +2223,7 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state) BT_HEADSET_INTERFACE, "State", g_variant_new("s", hs_state)); hs->state = state; + active_devices = g_slist_append(active_devices, hs); break; case HEADSET_STATE_CONNECTED: @@ -2208,6 +2235,7 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state) if (hs->state < state) { val = TRUE; + if (!g_slist_find(active_devices, hs)) active_devices = g_slist_append(active_devices, hs); _bt_ag_agent_emit_property_changed(ag_dbus_conn, hs->path, @@ -2215,7 +2243,13 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state) "Connected", g_variant_new("b", val)); - DBG("Device %s connected\n", hs->remote_addr); + DBG_SECURE("Device %s connected", hs->remote_addr); + + /* update remote dev path to last connected device. */ + if (remote_dev_path) + g_free(remote_dev_path); + remote_dev_path = g_strdup(hs->path); + #if defined(TIZEN_SUPPORT_DUAL_HF) if (!hs->is_companion_device) __bt_ag_start_sco_server(hs); @@ -2237,6 +2271,20 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state) break; case HEADSET_STATE_DISCONNECTED: + if (sco_open_timer_id > 0) { + g_source_remove(sco_open_timer_id); + sco_open_timer_id = 0; + if (hs->invocation) { + INFO("Disconnected before SCO Connection"); + /* Reply with error */ + GError *err = NULL; + err = __bt_ag_agent_set_error(BT_HFP_AGENT_ERROR_NOT_CONNECTED); + g_dbus_method_invocation_return_gerror(hs->invocation, err); + hs->invocation = NULL; + g_error_free(err); + } + } + __bt_ag_close_sco(hs); __bt_ag_headset_close_rfcomm(hs); @@ -2272,6 +2320,7 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state) __bt_ag_stop_sco_server(hs); g_free(hs->remote_addr); + g_free(hs->slc); g_free(hs); break; @@ -2293,11 +2342,13 @@ void _bt_ag_set_headset_state(bt_ag_info_t *hs, hs_state_t state) BT_HEADSET_INTERFACE, "Playing", g_variant_new("b", val)); - if (slconn->microphone_gain >= 0) + if (slconn->microphone_gain >= 0 && + !slconn->is_voice_recognition_running) _bt_ag_send_at(hs, "\r\n+VGM=%u\r\n", slconn->microphone_gain); - if (slconn->speaker_gain >= 0) + if (slconn->speaker_gain >= 0 && + !slconn->is_voice_recognition_running) _bt_ag_send_at(hs, "\r\n+VGS=%u\r\n", slconn->speaker_gain); @@ -2478,10 +2529,16 @@ static int __bt_ag_send_at_valist(bt_ag_info_t *hdset, va_list list, } /* Synchronize the sending buffer */ +#if 0 + /* Don't do sync call as it may block process untill all buffers are cleared + * On Z300F device this issue is reproduciable just connect with meacap + * select phonebook and call CPBR when we call CPBR multiple times it is + * blocking for 5 seconds.*/ sync(); +#endif fsync(fd); } else { - ERR("FD is 0. remote_addr : %s", hdset->remote_addr); + ERR_SECURE("FD is 0. remote_addr : %s", hdset->remote_addr); return -1; } @@ -2662,7 +2719,7 @@ static gboolean __bt_ag_agent_connection(gint32 fd, const gchar *device_path, __bt_ag_codec_negotiation_info_reset(bt_ag_info, TRUE); bt_ag_info->path = device_path; - DBG("device_path = [%s]", device_path); + DBG_SECURE("device_path = [%s]", device_path); address_len = sizeof(address); if (getpeername(fd, (struct sockaddr *) &address, &address_len) != 0) @@ -2690,7 +2747,7 @@ static gboolean __bt_ag_agent_connection(gint32 fd, const gchar *device_path, __bt_ag_agent_is_companion_device(bt_ag_info->remote_addr); #endif - DBG("remote Device Address = [%s]", bt_ag_info->remote_addr); + DBG_SECURE("remote Device Address = [%s]", bt_ag_info->remote_addr); if (g_strcmp0(object_path, BT_HS_AG_AGENT_OBJECT_PATH) == 0) { DBG("HSP connection completed"); @@ -2705,8 +2762,8 @@ static gboolean __bt_ag_agent_connection(gint32 fd, const gchar *device_path, __bt_ag_agent_start_watch(bt_ag_info); bt_ag_info->slc = g_new0(bt_ag_slconn_t, 1); - bt_ag_info->slc->speaker_gain = 15; - bt_ag_info->slc->microphone_gain = 15; + bt_ag_info->slc->speaker_gain = last_speaker_gain; + bt_ag_info->slc->microphone_gain = 9; bt_ag_info->slc->is_nrec = TRUE; return TRUE; @@ -2801,6 +2858,9 @@ static gboolean __bt_sco_open_delay_timeout_cb(gpointer user_data) } } else __bt_ag_sco_connect(bt_ag_info); + + DBG("Dbus Reply for SCO Connection request"); + g_dbus_method_invocation_return_value(bt_ag_info->invocation, NULL); } return FALSE; @@ -2946,6 +3006,7 @@ static void __bt_ag_agent_method(GDBusConnection *connection, int ret = BT_HFP_AGENT_ERROR_NONE; GError *err = NULL; const gchar *device_path = NULL; + GSList *l; if (g_strcmp0(method_name, "NewConnection") == 0) { gint32 fd; @@ -2966,17 +3027,18 @@ static void __bt_ag_agent_method(GDBusConnection *connection, g_variant_get(parameters, "(oha{sv})", &device_path, &index, &options); - -#if defined(TIZEN_SUPPORT_DUAL_HF) && defined(TIZEN_PROFILE_WEARABLE) - /* - * Below code is not required for dual HF support for - * mobile devices - */ - if (device_count && - __bt_ag_agent_check_dual_hf_condition(device_path) == FALSE) { - INFO("not allow to connect 2nd HF connection"); - ret = BT_HFP_AGENT_ERROR_INTERNAL; - goto fail; +#if defined(TIZEN_SUPPORT_DUAL_HF) + if (TIZEN_PROFILE_WEARABLE) { + /* + * Below code is not required for dual HF support for + * mobile devices + */ + if (device_count && + __bt_ag_agent_check_dual_hf_condition(device_path) == FALSE) { + INFO("not allow to connect 2nd HF connection"); + ret = BT_HFP_AGENT_ERROR_INTERNAL; + goto fail; + } } #endif msg = g_dbus_method_invocation_get_message(invocation); @@ -2992,7 +3054,7 @@ static void __bt_ag_agent_method(GDBusConnection *connection, goto fail; } - DBG("FD is = [%d], device_path = [%s]\n", fd, device_path); + DBG_SECURE("FD is = [%d], device_path = [%s]\n", fd, device_path); if (!__bt_ag_agent_connection(fd, device_path, object_path)) { ret = BT_HFP_AGENT_ERROR_INTERNAL; @@ -3001,15 +3063,14 @@ static void __bt_ag_agent_method(GDBusConnection *connection, g_dbus_method_invocation_return_value(invocation, NULL); } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) { - GSList *l; g_variant_get(parameters, "(o)", &device_path); - INFO("device_path %s", device_path); + INFO_SECURE("device_path %s", device_path); for (l = active_devices; l; l = l->next) { bt_ag_info_t *data = l->data; - INFO("data->path %s", data->path); + INFO_SECURE("data->path %s", data->path); if (g_strcmp0(data->path, device_path) == 0) { if (!__bt_ag_agent_connection_release(data)) { ret = BT_HFP_AGENT_ERROR_INTERNAL; @@ -3019,6 +3080,30 @@ static void __bt_ag_agent_method(GDBusConnection *connection, g_dbus_method_invocation_return_value(invocation, NULL); } } + } else if (g_strcmp0(method_name, "ReplyAuthorize") == 0) { + const guint accept; + bt_ag_info_t *data; + g_variant_get(parameters, "(u)", &accept); + INFO("Accept: %d", accept); + + l = active_devices; + data = l->data; + INFO_SECURE("data->path %s", data->path); + data->pbap_trusted = accept; + + _bt_hfp_select_phonebook_memory_status_reply(data); + + INFO("pbap_trusted %d", data->pbap_trusted); + + if (data->pbap_trusted == BT_AG_FEATURE_PBAP_ALLOWED) { + /* Allow Access update this to bluez */ + bt_device_set_profile_trusted(data->remote_addr, + 1, TRUE); + } else if (data->pbap_trusted == BT_AG_FEATURE_PBAP_BLOCKED) { + /* Blocked Access update this to bluez */ + bt_device_set_profile_trusted(data->remote_addr, + 1, FALSE); + } } else if (g_strcmp0(method_name, "RegisterApplication") == 0) { gchar *path = NULL; gchar *address = NULL; @@ -3033,7 +3118,7 @@ static void __bt_ag_agent_method(GDBusConnection *connection, g_free(local_addr); local_addr = g_strdup(address); - DBG("Address = %s\n", local_addr); + DBG_SECURE("Address = %s\n", local_addr); g_dbus_method_invocation_return_value(invocation, NULL); } else if (g_strcmp0(method_name, "UnregisterApplication") == 0) { gchar *path = NULL; @@ -3142,7 +3227,6 @@ static void __bt_ag_agent_method(GDBusConnection *connection, } } else if (g_strcmp0(method_name, "Disconnect") == 0) { char hdset_address[18] = { 0, }; - GSList *l; for (l = active_devices; l; l = l->next) { bt_ag_info_t *data = l->data; @@ -3150,7 +3234,7 @@ static void __bt_ag_agent_method(GDBusConnection *connection, __bt_convert_addr_type_to_rev_string(hdset_address, (unsigned char *)data->remote_addr); - DBG("Disconnect Headset %s, %s\n", + DBG_SECURE("Disconnect Headset %s, %s\n", hdset_address, data->path); _bt_ag_set_headset_state(data, HEADSET_STATE_DISCONNECTED); @@ -3158,12 +3242,11 @@ static void __bt_ag_agent_method(GDBusConnection *connection, g_dbus_method_invocation_return_value(invocation, NULL); } else if (g_strcmp0(method_name, "IsConnected") == 0) { gboolean is_connected = FALSE; - GSList *l; for (l = active_devices; l; l = l->next) { bt_ag_info_t *data = l->data; - if (data->state == HEADSET_STATE_CONNECTED) + if (data->state >= HEADSET_STATE_CONNECTED) is_connected = TRUE; } DBG("is_connected : %s", @@ -3172,7 +3255,6 @@ static void __bt_ag_agent_method(GDBusConnection *connection, g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", is_connected)); } else if (g_strcmp0(method_name, "IndicateCall") == 0) { - GSList *l; if (0 == g_slist_length(active_devices)) { ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED; @@ -3248,6 +3330,10 @@ static void __bt_ag_agent_method(GDBusConnection *connection, ERR("Play In Progress"); ret = BT_HFP_AGENT_ERROR_BUSY; break; + case HEADSET_STATE_ON_CALL: + ERR("SCO is already established"); + ret = BT_HFP_AGENT_ERROR_ALREADY_CONNECTED; + break; default: break; } @@ -3257,7 +3343,7 @@ static void __bt_ag_agent_method(GDBusConnection *connection, if (sco_open_timer_id > 0) { INFO("SCO open delay"); sco_open_request = TRUE; - g_dbus_method_invocation_return_value(invocation, NULL); + bt_ag_info->invocation = invocation; return; } @@ -3288,11 +3374,11 @@ static void __bt_ag_agent_method(GDBusConnection *connection, g_dbus_method_invocation_return_value(invocation, NULL); - name_owner_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn, + if (name_owner_sig_id == 0) + name_owner_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn, NULL, NULL, "NameOwnerChanged", NULL, NULL, 0, __bt_ag_name_owner_changed_cb, NULL, NULL); } else if (g_strcmp0(method_name, "Stop") == 0) { - GSList *l; for (l = active_devices; l; l = l->next) { bt_ag_info_t *data = l->data; @@ -3307,7 +3393,6 @@ static void __bt_ag_agent_method(GDBusConnection *connection, g_dbus_method_invocation_return_value(invocation, NULL); } else if (g_strcmp0(method_name, "IsPlaying") == 0) { gboolean is_playing = FALSE; - GSList *l; for (l = active_devices; l; l = l->next) { bt_ag_info_t *data = l->data; @@ -3324,12 +3409,8 @@ static void __bt_ag_agent_method(GDBusConnection *connection, guint16 gain_value = 0; bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path); - if (bt_ag_info == NULL) { - ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE; - goto fail; - } - - if (bt_ag_info->state < HEADSET_STATE_CONNECTED) { + if (bt_ag_info == NULL || + bt_ag_info->state < HEADSET_STATE_CONNECTED) { ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED; goto fail; } @@ -3343,15 +3424,15 @@ static void __bt_ag_agent_method(GDBusConnection *connection, } else if (g_strcmp0(method_name, "SetSpeakerGain") == 0) { guint16 gain = 0; bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path); + if (bt_ag_info == NULL || + bt_ag_info->state < HEADSET_STATE_CONNECTED) { + ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED; + goto fail; + } g_variant_get(parameters, "(q)", &gain); DBG("Speaker gain = %d\n", gain); - if (bt_ag_info == NULL) { - ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE; - goto fail; - } - ret = _bt_hfp_set_speaker_gain(bt_ag_info, gain); if (ret) goto fail; @@ -3361,8 +3442,9 @@ static void __bt_ag_agent_method(GDBusConnection *connection, guint16 gain_value = 0; bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path); - if (bt_ag_info == NULL) { - ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE; + if (bt_ag_info == NULL || + bt_ag_info->state < HEADSET_STATE_CONNECTED) { + ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED; goto fail; } @@ -3380,23 +3462,24 @@ static void __bt_ag_agent_method(GDBusConnection *connection, } else if (g_strcmp0(method_name, "SetMicrophoneGain") == 0) { guint16 gain = 0; bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path); + if (bt_ag_info == NULL || + bt_ag_info->state < HEADSET_STATE_CONNECTED) { + ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED; + goto fail; + } g_variant_get(parameters, "(q)", &gain); DBG("Microphone gain = %d\n", gain); - if (bt_ag_info == NULL) { - ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE; - goto fail; - } - ret = _bt_hfp_set_microphone_gain(bt_ag_info, gain); if (ret) goto fail; g_dbus_method_invocation_return_value(invocation, NULL); } else if (g_strcmp0(method_name, "SetVoiceDial") == 0) { bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path); - if (bt_ag_info == NULL) { - ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE; + if (bt_ag_info == NULL || + bt_ag_info->state < HEADSET_STATE_CONNECTED) { + ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED; goto fail; } @@ -3423,8 +3506,9 @@ static void __bt_ag_agent_method(GDBusConnection *connection, } else if (g_strcmp0(method_name, "SendVendorAtCmd") == 0) { gchar *cmd; bt_ag_info_t *bt_ag_info = __bt_get_active_headset(remote_dev_path); - if (bt_ag_info == NULL) { - ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE; + if (bt_ag_info == NULL || + bt_ag_info->state < HEADSET_STATE_CONNECTED) { + ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED; goto fail; } @@ -3643,12 +3727,10 @@ static void __bt_ag_unregister_profile_methods(void) } } -static GDBusProxy *__bt_ag_gdbus_get_service_proxy(const gchar *service, - const gchar *path, const gchar *interface) +static GDBusProxy *__bt_ag_gdbus_get_profile_proxy(void) { - return (service_gproxy) ? service_gproxy : - __bt_ag_gdbus_init_service_proxy(service, - path, interface); + return (profile_gproxy) ? profile_gproxy : + __bt_ag_gdbus_init_profile_proxy(); } static void __bt_ag_agent_register(gchar *path, uint16_t profile_version, @@ -3660,12 +3742,10 @@ static void __bt_ag_agent_register(gchar *path, uint16_t profile_version, GError *error = NULL; GVariantBuilder *builder; - proxy = __bt_ag_gdbus_get_service_proxy(BLUEZ_SERVICE_NAME, - "/org/bluez", BLUEZ_PROFILE_MGMT_INTERFACE); + proxy = __bt_ag_gdbus_get_profile_proxy(); if (proxy == NULL) return; - builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); g_variant_builder_add(builder, "{sv}", @@ -3715,15 +3795,13 @@ static void __bt_ag_agent_unregister(gchar *path) GVariant *ret; GError *error = NULL; - proxy = __bt_ag_gdbus_get_service_proxy(BLUEZ_SERVICE_NAME, - "/org/bluez", BLUEZ_PROFILE_MGMT_INTERFACE); + proxy = __bt_ag_gdbus_get_profile_proxy(); if (proxy == NULL) return; - ret = g_dbus_proxy_call_sync(proxy, "UnregisterProfile", g_variant_new("(o)", path), - G_DBUS_CALL_FLAGS_NONE, -1, + G_DBUS_CALL_FLAGS_NONE, 100, NULL, &error); g_free(path); /* set the name and role for the profile*/ @@ -3750,19 +3828,23 @@ static void __bt_ag_agent_unregister(gchar *path) return; } -static void __bt_ag_agent_battery_status_cb(keynode_t *node) +static void __bt_ag_agent_battery_status_cb(device_callback_e type, + void *value, void *user_data) { - int batt = vconf_keynode_get_int(node); - - _bt_hfp_set_property_value("BatteryBarsChanged", batt); + int batt_cap; + if (type == DEVICE_CALLBACK_BATTERY_CAPACITY) { + device_battery_get_percent(&batt_cap); + _bt_hfp_set_property_value("BatteryBarsChanged", batt_cap); + } } -static void __bt_ag_agent_network_signal_status_cb(keynode_t *node) +static void __bt_ag_agent_network_signal_status_cb(TapiHandle *handle, + const char *noti_id, void *data, void *user_data) { - int signal_bar = vconf_keynode_get_int(node); + int *signal_bar = data; - BT_CHECK_SIGNAL_STRENGTH(signal_bar); - _bt_hfp_set_property_value("SignalBarsChanged", signal_bar); + BT_CHECK_SIGNAL_STRENGTH(*signal_bar); + _bt_hfp_set_property_value("SignalBarsChanged", *signal_bar); } static void __bt_ag_agent_lunar_connection_status_cb(keynode_t *node) @@ -3779,19 +3861,73 @@ static void __bt_ag_agent_lunar_connection_status_cb(keynode_t *node) } } -static void __bt_ag_agent_network_register_status_cb(keynode_t *node) +static void __bt_ag_agent_call_preferred_voice_subscription_cb(TapiHandle *handle, + const char *noti_id, void *data, void *user_data) +{ + TelCallPreferredVoiceSubsNoti_t *noti_data = (TelCallPreferredVoiceSubsNoti_t *)data; + uint32_t ag_features; + int tapi_result; + if (!noti_data) { + ERR("Error happen during voice subscription data noti"); + return; + } + + INFO("TAPI_NOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION = Value %d", + noti_data->preferred_subs); + ag_features = __bt_ag_agent_get_ag_features(); + switch (noti_data->preferred_subs) { + case TAPI_CALL_PREFERRED_VOICE_SUBS_SIM1: + case TAPI_CALL_PREFERRED_VOICE_SUBS_ASK_ALWAYS: + if (tapi_handle_preferred_sim == tapi_handle[0]) { + INFO("No handler change. Preferred sim is same as SIM1"); + break; + } + __bt_ag_agent_unsubscribe_tapi_updates(tapi_handle_preferred_sim); + tapi_handle_preferred_sim = tapi_handle[0]; + _bt_hfp_initialize_telephony_manager(ag_features, tapi_handle_preferred_sim); + __bt_ag_agent_subscribe_tapi_updates(tapi_handle_preferred_sim); + tapi_result = tel_get_sim_msisdn(GET_TAPI_HANDLE, __bt_ag_agent_tel_cb, NULL); + if (tapi_result != TAPI_API_SUCCESS) + ERR("Fail to get sim info: %d", tapi_result); + break; + case TAPI_CALL_PREFERRED_VOICE_SUBS_SIM2: + if (tapi_handle_preferred_sim == tapi_handle[1]) { + INFO("No handler change. Preferred sim is same as SIM2"); + break; + } + __bt_ag_agent_unsubscribe_tapi_updates(tapi_handle_preferred_sim); + tapi_handle_preferred_sim = tapi_handle[1]; + _bt_hfp_initialize_telephony_manager(ag_features, tapi_handle_preferred_sim); + __bt_ag_agent_subscribe_tapi_updates(tapi_handle_preferred_sim); + tapi_result = tel_get_sim_msisdn(GET_TAPI_HANDLE, __bt_ag_agent_tel_cb, NULL); + if (tapi_result != TAPI_API_SUCCESS) + ERR("Fail to get sim info: %d", tapi_result); + + break; + + case TAPI_CALL_PREFERRED_VOICE_SUBS_CURRENT_NETWORK: + case TAPI_CALL_PREFERRED_VOICE_SUBS_UNKNOWN: + default: + break; + } +} + +static void __bt_ag_agent_network_register_status_cb(TapiHandle *handle, + const char *noti_id, void *data, void *user_data) { - int service = vconf_keynode_get_int(node); + int service; bt_hfp_agent_network_registration_status_t network_service; int roam_status; int ret; - DBG("Current Signal Level = [%d] \n", service); + int *service_type = data; - switch (service) { - case VCONFKEY_TELEPHONY_SVCTYPE_NONE: - case VCONFKEY_TELEPHONY_SVCTYPE_NOSVC: - case VCONFKEY_TELEPHONY_SVCTYPE_SEARCH: + DBG("Network service type changed = [%d]", *service_type); + + switch (*service_type) { + case TAPI_NETWORK_SERVICE_TYPE_UNKNOWN: + case TAPI_NETWORK_SERVICE_TYPE_NO_SERVICE: + case TAPI_NETWORK_SERVICE_TYPE_SEARCH: service = 0; break; default: @@ -3799,8 +3935,9 @@ static void __bt_ag_agent_network_register_status_cb(keynode_t *node) break; } - ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &roam_status); - if (ret != 0) { + ret = tel_get_property_int(GET_TAPI_HANDLE, + TAPI_PROP_NETWORK_ROAMING_STATUS, &roam_status); + if (ret != TAPI_API_SUCCESS) { ERR("Get roaming status failed err = %d\n", ret); return; } @@ -3820,21 +3957,11 @@ static void __bt_ag_agent_subscribe_vconf_updates(void) int ret; DBG("\n"); - - ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY, - (void *)__bt_ag_agent_battery_status_cb, NULL); - if (0 != ret) - ERR("Subsrciption to battery status failed err = [%d]\n", ret); - - ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_RSSI, - (void *)__bt_ag_agent_network_signal_status_cb, NULL); - if (0 != ret) - ERR("Subsrciption to netowrk signal failed err = [%d]\n", ret); - - ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SVCTYPE, - (void *)__bt_ag_agent_network_register_status_cb, NULL); - if (0 != ret) - ERR("Subsrciption to network failed err = [%d]\n", ret); + ret = device_add_callback(DEVICE_CALLBACK_BATTERY_CAPACITY, + __bt_ag_agent_battery_status_cb, NULL); + if (ret != DEVICE_ERROR_NONE) { + ERR("Subscription to battery status failed err = [%d]\n", ret); + } if (TIZEN_PROFILE_WEARABLE) { ret = vconf_notify_key_changed(VCONF_KEY_BT_LUNAR_ENABLED, @@ -3849,21 +3976,18 @@ static void __bt_ag_agent_release_vconf_updates(void) int ret; DBG("\n"); + ret = device_remove_callback(DEVICE_CALLBACK_BATTERY_CAPACITY, + __bt_ag_agent_battery_status_cb); + if (ret != DEVICE_ERROR_NONE) { + ERR("Unsubscription to battery status failed err = [%d]\n", ret); + } - ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY, - (vconf_callback_fn)__bt_ag_agent_battery_status_cb); - if (0 != ret) - ERR("vconf_ignore_key_changed failed\n"); - - ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_RSSI, - (vconf_callback_fn)__bt_ag_agent_network_signal_status_cb); - if (0 != ret) - ERR("vconf_ignore_key_changed failed\n"); - - ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SVCTYPE, - (vconf_callback_fn)__bt_ag_agent_network_register_status_cb); - if (0 != ret) - ERR("vconf_ignore_key_changed failed\n"); + if (TIZEN_PROFILE_WEARABLE) { + ret = vconf_ignore_key_changed(VCONF_KEY_BT_LUNAR_ENABLED, + (void *)__bt_ag_agent_lunar_connection_status_cb); + if (0 != ret) + ERR("Subsrciption to lunar connection failed err = [%d]\n", ret); + } } static gboolean __bt_ag_agent_send_subscriber_number_changed( @@ -3873,7 +3997,7 @@ static gboolean __bt_ag_agent_send_subscriber_number_changed( FN_START; - DBG("Number is %s", number); + DBG_SECURE("Number is %s", number); if (!_bt_hfp_set_property_name(property, number)) { DBG("Error- set property for subscriber no change - ERROR\n"); @@ -3925,7 +4049,15 @@ static void __bt_ag_agent_tel_cb(TapiHandle *handle, TelSimMsisdnList_t *number; gchar *subscriber_number; - ERR("*********** result = %d", result); + ERR("*********** Result =%d **********", result); + + if (result == TAPI_ERROR_OPERATION_FAILED || + result == TAPI_ERROR_ACCESS_DENIED || + result == TAPI_ERROR_OPERATION_NOT_SUPPORTED) { + ERR("SIM has limited capabilities"); + __bt_ag_agent_send_subscriber_number_changed(""); + return; + } if (result == TAPI_API_SIM_LOCKED || result == TAPI_API_SIM_NOT_INITIALIZED || @@ -4004,10 +4136,10 @@ static void __bt_ag_name_owner_changed_cb(GDBusConnection *connection, return; if (strcasecmp(name_owner, sco_owner) == 0) { - if (name_owner_sig_id != -1) + if (name_owner_sig_id) g_dbus_connection_signal_unsubscribe(ag_dbus_conn, name_owner_sig_id); - name_owner_sig_id = -1; + name_owner_sig_id = 0; g_free(sco_owner); sco_owner = NULL; @@ -4024,7 +4156,7 @@ static void __bt_ag_name_owner_changed_cb(GDBusConnection *connection, } } -static void __bt_ag_agent_filter_cb(GDBusConnection *connection, +static void __bt_ag_agent_bluez_interface_signal_cb(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, @@ -4047,7 +4179,7 @@ static void __bt_ag_agent_filter_cb(GDBusConnection *connection, return; } - INFO("Adapter Path = [%s]", path); + INFO_SECURE("Adapter Path = [%s]", path); if (strcasecmp(path, DEFAULT_ADAPTER_OBJECT_PATH) == 0) { gchar *path = g_strdup(BT_AG_AGENT_OBJECT_PATH); __bt_ag_agent_register(path, hfp_ver, @@ -4066,7 +4198,7 @@ static void __bt_ag_agent_filter_cb(GDBusConnection *connection, return; } - INFO("Adapter Path = [%s]", path); + INFO_SECURE("Adapter Path = [%s]", path); if (strcasecmp(path, DEFAULT_ADAPTER_OBJECT_PATH) == 0) { gchar *path = g_strdup(BT_AG_AGENT_OBJECT_PATH); __bt_ag_agent_unregister(path); @@ -4082,17 +4214,63 @@ static void __bt_ag_agent_filter_cb(GDBusConnection *connection, FN_END; } -static void __bt_ag_agent_dbus_deinit(void) +static void __bt_ag_agent_bluez_property_changed_cb(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) { + GVariant *optional_param = NULL; + char *inter = NULL; + GVariant *dict_param = NULL; - if (service_gproxy) { - g_object_unref(service_gproxy); - service_gproxy = NULL; + if (strcasecmp(signal_name, BT_PROPERTY_CHANGED) == 0) { + if (g_strcmp0(g_variant_get_type_string(parameters), + "(sa{sv}as)")) { + ERR("Incorrect parameters\n"); + return; + } + g_variant_get(parameters, "(&s@a{sv}@as)", + &inter, &dict_param, &optional_param); + if (strcasecmp(inter, BLUEZ_DEVICE_INTERFACE) == 0) { + GVariantDict dict; + int trusted = 0; + g_variant_dict_init(&dict, dict_param); + if (g_variant_dict_lookup( + &dict, "TrustedProfiles", "u", &trusted)) { + GSList *l; + for (l = active_devices ; l; l = l->next) { + bt_ag_info_t *data = l->data; + if (g_strcmp0(data->path, object_path) != 0) + continue; + if (trusted == BT_PROFILE_SUPPORTED_TRUSTED) { + data->pbap_trusted = + BT_AG_FEATURE_PBAP_ALLOWED; + DBG("[%s] PBAP is TRUSTED", object_path); + } else if (trusted == BT_PROFILE_SUPPORTED_BLOCKED) { + data->pbap_trusted = + BT_AG_FEATURE_PBAP_BLOCKED; + DBG("[%s] PBAP is BLOCKED", object_path); + } + } + } + g_variant_dict_end(&dict); + } + if (dict_param) + g_variant_unref(dict_param); } - if (app_gproxy) { - g_object_unref(app_gproxy); - app_gproxy = NULL; + if (optional_param) + g_variant_unref(optional_param); +} + +static void __bt_ag_agent_dbus_deinit(void) +{ + if (profile_gproxy) { + g_object_unref(profile_gproxy); + profile_gproxy = NULL; } if (ag_dbus_conn) { @@ -4106,6 +4284,10 @@ static void __bt_ag_agent_dbus_deinit(void) g_dbus_connection_signal_unsubscribe(ag_dbus_conn, interface_removed_sig_id); + if (proterty_changed_sig_id) + g_dbus_connection_signal_unsubscribe(ag_dbus_conn, + proterty_changed_sig_id); + if (name_owner_sig_id) g_dbus_connection_signal_unsubscribe(ag_dbus_conn, name_owner_sig_id); @@ -4113,16 +4295,17 @@ static void __bt_ag_agent_dbus_deinit(void) if (media_sig_id) g_dbus_connection_signal_unsubscribe(ag_dbus_conn, media_sig_id); - media_sig_id = 0; - if (media_state_sig_id) - g_dbus_connection_signal_unsubscribe(ag_dbus_conn, - media_state_sig_id); - media_state_sig_id = 0; + media_sig_id = 0; #endif + if (device_property_id) + g_dbus_connection_signal_unsubscribe(ag_dbus_conn, + device_property_id); + device_property_id = 0; interface_added_sig_id = 0; interface_removed_sig_id = 0; + proterty_changed_sig_id = 0; name_owner_sig_id = 0; g_free(sco_owner); sco_owner = NULL; @@ -4130,7 +4313,6 @@ static void __bt_ag_agent_dbus_deinit(void) g_object_unref(ag_dbus_conn); ag_dbus_conn = NULL; } - return; } static int __bt_ag_agent_get_adapter_path(GDBusConnection *conn, char *path) @@ -4228,6 +4410,7 @@ void _bt_ag_agent_check_transport_state(void) G_DBUS_CALL_FLAGS_NONE, 2000, NULL, NULL, NULL); transport_state = MEDIA_TRANSPORT_STATE_IDLE; + g_object_unref(proxy); } FN_END; @@ -4258,7 +4441,7 @@ static void __bt_ag_agent_media_filter_cb(GDBusConnection *connection, char *inter = NULL; GVariant *dict_param = NULL; GVariant *optional_param = NULL; - + GSList *l; if (strcasecmp(signal_name, "PropertiesChanged") == 0) { if (g_strcmp0(g_variant_get_type_string(parameters), "(sa{sv}as)")) { @@ -4273,7 +4456,7 @@ static void __bt_ag_agent_media_filter_cb(GDBusConnection *connection, GVariantIter *iter = NULL; const gchar *key = NULL; GVariant *value_var = NULL; - gchar *value = NULL; + const gchar *value = NULL; g_variant_get(dict_param, "a{sv}", &iter); while (g_variant_iter_loop( iter, "{sv}", &key, &value_var)) { @@ -4337,12 +4520,17 @@ static void __bt_ag_agent_dbus_init(void) interface_added_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn, NULL, BT_MANAGER_INTERFACE, BT_INTERFACES_ADDED, NULL, NULL, 0, - __bt_ag_agent_filter_cb, NULL, NULL); + __bt_ag_agent_bluez_interface_signal_cb, NULL, NULL); interface_removed_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn, NULL, BT_MANAGER_INTERFACE, BT_INTERFACES_REMOVED, NULL, NULL, 0, - __bt_ag_agent_filter_cb, NULL, NULL); + __bt_ag_agent_bluez_interface_signal_cb, NULL, NULL); + + proterty_changed_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn, + NULL, BT_MANAGER_INTERFACE, + BT_PROPERTY_CHANGED, NULL, NULL, 0, + __bt_ag_agent_bluez_property_changed_cb, NULL, NULL); #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE media_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn, @@ -4357,10 +4545,62 @@ static void __bt_ag_agent_dbus_init(void) transport_state = MEDIA_TRANSPORT_STATE_DISCONNECTED; #endif + device_property_id = g_dbus_connection_signal_subscribe(ag_dbus_conn, + NULL, BT_PROPERTIES_INTERFACE, BT_PROPERTY_CHANGED, NULL, + NULL, 0, __bt_ag_agent_bluez_property_changed_cb, + NULL, NULL); FN_END; return; } +static void __bt_ag_agent_subscribe_tapi_updates(TapiHandle *handle) +{ + int ret; + + DBG("\nSubscribe tapi update for handler %p", handle); + + ret = tel_register_noti_event(handle, TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL, + __bt_ag_agent_network_signal_status_cb, NULL); + if (ret != TAPI_API_SUCCESS) { + ERR("Subsrciption to netowrk signal failed err = [%d]\n", ret); + } + + ret = tel_register_noti_event(handle, TAPI_PROP_NETWORK_SERVICE_TYPE, + __bt_ag_agent_network_register_status_cb, NULL); + if (ret != TAPI_API_SUCCESS) { + ERR("Subsrciption to network failed err = [%d]\n", ret); + } + + ret = tel_register_noti_event(handle, TAPI_NOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION, + __bt_ag_agent_call_preferred_voice_subscription_cb, NULL); + if (ret != TAPI_API_SUCCESS) { + ERR("Subsrciption to preferred voice err = [%d]\n", ret); + } + +} + +static void __bt_ag_agent_unsubscribe_tapi_updates(TapiHandle *handle) +{ + int ret; + + DBG("\nUnsubscribe tapi update for handler %p", handle); + + ret = tel_deregister_noti_event(handle, TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL); + if (ret != TAPI_API_SUCCESS) { + ERR("Subsrciption to netowrk signal failed err = [%d]\n", ret); + } + + ret = tel_deregister_noti_event(handle, TAPI_PROP_NETWORK_SERVICE_TYPE); + if (ret != TAPI_API_SUCCESS) { + ERR("Subsrciption to network failed err = [%d]\n", ret); + } + + ret = tel_deregister_noti_event(handle, TAPI_NOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION); + if (ret != TAPI_API_SUCCESS) { + ERR("Subsrciption to preferred voice err = [%d]\n", ret); + } +} + static uint32_t __bt_ag_agent_get_ag_features(void) { @@ -4368,15 +4608,18 @@ static uint32_t __bt_ag_agent_get_ag_features(void) BT_AG_FEATURE_REJECT_CALL | BT_AG_FEATURE_ENHANCED_CALL_STATUS | BT_AG_FEATURE_THREE_WAY_CALL | +#if !defined(TIZEN_FEATURE_BT_VENDOR_SPRD) BT_AG_FEATURE_VOICE_RECOGNITION | +#endif BT_AG_FEATURE_EXTENDED_ERROR_RESULT_CODES; +#ifdef TIZEN_FEATURE_BT_SCO_WIDEBAND wbs_en = TRUE; -#if defined(TIZEN_FEATURE_BT_HFP_AG) - hfp_ver = HFP_VERSION_1_7; #else - hfp_ver = HFP_VERSION_1_5; + wbs_en = FALSE; #endif + + hfp_ver = HFP_VERSION_1_7; hsp_ver = HSP_VERSION_1_2; if (hfp_ver > HFP_VERSION_1_5) @@ -4387,23 +4630,120 @@ static uint32_t __bt_ag_agent_get_ag_features(void) return ag_features; } -void *__bt_ag_agent_telephony_init(void *arg) +static void __bt_ag_agent_tel_get_preferred_sim(TapiHandle *handler) { + TelCallPreferredVoiceSubs_t preferredSubscription; + int err_code = tel_get_call_preferred_voice_subscription(handler, &preferredSubscription); + if (err_code == TAPI_API_SUCCESS) { + if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_SIM1) { + tapi_handle_preferred_sim = tapi_handle[0]; + INFO("Preferred SIM 1"); + } else if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_SIM2) { + tapi_handle_preferred_sim = tapi_handle[1]; + INFO("Preferred SIM 2"); + } else if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_CURRENT_NETWORK) { + INFO("Preferred SIM Current Network"); + } else if (preferredSubscription == TAPI_CALL_PREFERRED_VOICE_SUBS_ASK_ALWAYS) { + tapi_handle_preferred_sim = tapi_handle[0]; + INFO("Preferred SIM Always Ask"); + } else { + ERR("Unknown Preferred voice subscription"); + } + } +} + +static void __bt_ag_agent_tel_init_multisim(void) +{ + INFO_C("Initializing the telephony multi sim info"); + + char **cp_list = NULL; + unsigned int modem_num = 0; + int err_code; + TelSimCardStatus_t simStatus = 0; + int card_changed = 0; + + + + /* Get CP name list ? cp_list */ + cp_list = tel_get_cp_name_list(); + if (cp_list == NULL) { + ERR("tel_get_cp_name_list() Failed"); + return; + } + + while (cp_list[modem_num]) { + /* Initialize TAPI handle */ + tapi_handle[modem_num] = tel_init(cp_list[modem_num]); + + if (tapi_handle[modem_num] == NULL) { + /* TAPI initialization ? Failure */ + ERR_SECURE("tel_init failed for Modem SIM number = %d", modem_num); + } else { + /* TAPI initialization ? Success */ + DBG_SECURE("Success for Modem SIM number = %d, handler = %p", + modem_num, tapi_handle[modem_num]); + err_code = tel_get_sim_init_info(tapi_handle[modem_num], + &simStatus, &card_changed); + INFO_SECURE("Sim number = %d SIM status = %d", modem_num, simStatus); + if ((TAPI_API_SUCCESS == err_code) && + (TAPI_SIM_STATUS_SIM_INIT_COMPLETED == simStatus)) { + if (modem_num == 0) + sim1 = 1; + else + sim2 = 1; + } + } + + /* Move to next CP Name in cp_list */ + modem_num++; + } + + tapi_handle[modem_num] = NULL; + + g_strfreev(cp_list); +} + +static void __bt_ag_agent_tel_deinit_multisim(void) +{ + INFO_C("DeInitializing the telephony multi sim info"); + + char **cp_list = NULL; + unsigned int modem_num = 0; + int result; + cp_list = tel_get_cp_name_list(); + if (cp_list == NULL) { + ERR("tel_get_cp_name_list() Failed"); + return; + } + + while (cp_list[modem_num]) { + result = tel_deinit(tapi_handle[modem_num]); + if (result != TAPI_API_SUCCESS) + ERR("Fail to tel_deinit"); + /* Move to next CP Name in cp_list */ + modem_num++; + } + + g_strfreev(cp_list); +} + +gboolean __bt_ag_agent_telephony_init(void *arg) +{ int tapi_result; uint32_t ag_features = *((uint32_t *)arg); INFO_C("Initializing the telephony info"); - - _bt_hfp_initialize_telephony_manager(ag_features); + __bt_ag_agent_tel_init_multisim(); + __bt_ag_agent_tel_get_preferred_sim(GET_TAPI_HANDLE); + _bt_hfp_initialize_telephony_manager(ag_features, GET_TAPI_HANDLE); + __bt_ag_agent_subscribe_tapi_updates(GET_TAPI_HANDLE); __bt_ag_agent_subscribe_vconf_updates(); - - tapi_handle = tel_init(NULL); - tapi_result = tel_get_sim_msisdn(tapi_handle, __bt_ag_agent_tel_cb, + tapi_result = tel_get_sim_msisdn(GET_TAPI_HANDLE, __bt_ag_agent_tel_cb, NULL); if (tapi_result != TAPI_API_SUCCESS) ERR("Fail to get sim info: %d", tapi_result); - return NULL; + return FALSE; } int main(void) @@ -4411,10 +4751,12 @@ int main(void) int i; uint32_t ag_features; struct sigaction sa; - pthread_t thread_id; INFO_C("### Starting Bluetooth AG agent"); +#if GLIB_VERSION_MIN_REQUIRED < GLIB_VERSION_2_36 + g_type_init(); +#endif ag_features = __bt_ag_agent_get_ag_features(); ag.sdp_features = (uint16_t) ag_features & 0x1F; @@ -4422,6 +4764,10 @@ int main(void) if (hfp_ver >= HFP_VERSION_1_6 && wbs_en == TRUE) ag.sdp_features |= BT_AG_FEATURE_SDP_WIDEBAND_SPEECH; + __bt_ag_agent_dbus_init(); + + g_idle_add(__bt_ag_agent_telephony_init, &ag_features); + memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = __bt_ag_agent_sigterm_handler; @@ -4436,27 +4782,15 @@ int main(void) return EXIT_FAILURE; } - __bt_ag_agent_dbus_init(); - if (pthread_create(&thread_id, NULL, - (void *)&__bt_ag_agent_telephony_init, - &ag_features) < 0) { - ERR("pthread_create() is failed"); - return EXIT_FAILURE; - } - - if (pthread_detach(thread_id) < 0) - ERR("pthread_detach() is failed"); - g_main_loop_run(gmain_loop); DBG("Cleaning up"); - tel_deinit(tapi_handle); - __bt_ag_agent_dbus_deinit(); _bt_hfp_deinitialize_telephony_manager(); __bt_ag_agent_release_vconf_updates(); - + __bt_ag_agent_unsubscribe_tapi_updates(GET_TAPI_HANDLE); + __bt_ag_agent_tel_deinit_multisim(); if (remote_dev_path) g_free(remote_dev_path); diff --git a/ag-agent/bluetooth-ag-agent.h b/ag-agent/bluetooth-ag-agent.h old mode 100755 new mode 100644 index 3198660..ea7c9cf --- a/ag-agent/bluetooth-ag-agent.h +++ b/ag-agent/bluetooth-ag-agent.h @@ -60,6 +60,10 @@ #include #include #include +#include +#include +#include +#include #include "vconf.h" #include "vconf-keys.h" @@ -75,13 +79,15 @@ #define TELEPHONY_APP_INTERFACE "org.tizen.csd.Call.Instance" #define BT_HEADSET_INTERFACE "org.bluez.Headset" #define BT_ADAPTER_INTERFACE "org.bluez.Adapter1" +#define BT_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" +#define BLUEZ_DEVICE_INTERFACE "org.bluez.Device1" #define BT_INTERFACES_ADDED "InterfacesAdded" #define BT_INTERFACES_REMOVED "InterfacesRemoved" +#define BT_PROPERTY_CHANGED "PropertiesChanged" + #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE -#define BT_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" #define BLUEZ_MEDIA_TRANSPORT_INTERFACE "org.bluez.MediaTransport1" #define BLUEZ_MEDIA_ENDPOINT_INTERFACE "org.bluez.MediaEndpoint1" -#define BLUEZ_DEVICE_INTERFACE "org.bluez.Device1" #define A2DP_SOURCE_ENDPOINT "/MediaEndpoint/A2DPSource" #endif @@ -262,6 +268,19 @@ typedef enum { BT_HF_FEATURE_CODEC_NEGOTIATION = 0x0080, } bt_hf_agent_feature_t; +typedef enum { + BT_AG_FEATURE_PBAP_SHOW_AUTHORIZATION = 0x0000, + BT_AG_FEATURE_PBAP_BLOCKED = 0x0001, + BT_AG_FEATURE_PBAP_CANCEL = 0x0002, + BT_AG_FEATURE_PBAP_ALLOWED= 0x0004 +} bt_pbap_trusted_feature_t; + +typedef enum { + BT_PROFILE_SHOW_AUTHORIZATION = 0x0, /* 0b00 */ + BT_PROFILE_SUPPORTED_BLOCKED = 0x1, /* 0b01 */ + BT_PROFILE_SUPPORTED_TRUSTED= 0x2, /* 0b10 */ +} bt_profile_trusted_states; + /* HFP AG service record bitmap. Bluetooth HFP 1.6 spec page 95 */ #define BT_AG_FEATURE_SDP_3WAY 0x1 #define BT_AG_FEATURE_SDP_ECNR 0x2 @@ -446,6 +465,7 @@ typedef struct { unsigned int remote_codecs; unsigned int sending_codec; unsigned int final_codec; + char *status; } bt_negotiation_info_t; typedef struct { @@ -484,6 +504,9 @@ typedef struct { #if defined(TIZEN_SUPPORT_DUAL_HF) gboolean is_companion_device; #endif + int pbap_trusted; + char at_pbap_buf[30]; + GDBusMethodInvocation *invocation; } bt_ag_info_t; typedef void (*headset_nrec_cb) (bt_ag_info_t *hs, @@ -595,7 +618,7 @@ bt_hfp_agent_error_t _bt_hfp_change_call_status(const char *call_path, uint32_t call_status, uint32_t call_id, const char *sender); -void _bt_hfp_initialize_telephony_manager(uint32_t ag_features); +void _bt_hfp_initialize_telephony_manager(uint32_t ag_features, TapiHandle *handler); void _bt_hfp_deinitialize_telephony_manager(void); gboolean _bt_ag_agent_emit_property_changed( GDBusConnection *connection, @@ -627,5 +650,6 @@ bt_hfp_agent_error_t _bt_ag_agent_vendor_cmd(const gchar *cmd, #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE void _bt_ag_agent_check_transport_state(void); #endif +void _bt_ag_agent_set_last_speaker_gain(int gain); #endif /* __DEF_BT_AG_AGENT_H_ */ diff --git a/ag-agent/bluetooth-ag-handler.c b/ag-agent/bluetooth-ag-handler.c index 2a761d3..82270a8 100644 --- a/ag-agent/bluetooth-ag-handler.c +++ b/ag-agent/bluetooth-ag-handler.c @@ -21,10 +21,15 @@ * limitations under the License. * */ +#include +#include +#include +#include #include "bluetooth-ag-agent.h" #include "bluetooth-ag-handler.h" #include "vconf.h" #include "vconf-keys.h" +#include extern bt_ag_status_t ag; extern GSList *active_devices; @@ -549,6 +554,7 @@ static int __bt_headset_set_gain(bt_ag_info_t *hs, uint16_t gain, char type) } property = "SpeakerGain"; slconn->speaker_gain = gain; + _bt_ag_agent_set_last_speaker_gain(gain); break; case BT_HFP_MICROPHONE_GAIN: if (slconn->microphone_gain == gain) { @@ -895,6 +901,11 @@ int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf) else enable = TRUE; + if (remote_dev_path) + g_free(remote_dev_path); + + remote_dev_path = g_strdup(hs->path); + _bt_hfp_voice_dial_request(enable, hs); slconn->is_voice_recognition_running = enable; @@ -905,7 +916,7 @@ int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf) int _bt_hfp_indicators_activation(bt_ag_info_t *hs, const char *buf) { if (strlen(buf) < 7) { - printf("Invalid indicator activation request\n"); + ERR("Invalid indicator activation request\n"); return -EINVAL; } @@ -978,10 +989,106 @@ int _bt_select_phonebook_memory_response(void *t_device, return _bt_ag_send_response(t_device, err); } -int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf) +static char *__bt_get_remote_device_name(const char *device_path) +{ + char *name = NULL; + GVariant *value; + GVariant *result = NULL; + GError *err = NULL; + GDBusProxy *device_proxy; + GDBusConnection *conn; + + if (device_path == NULL) + return NULL; + + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); + + INFO_SECURE("Device_path %s", device_path); + device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, "org.bluez", + device_path, + BT_PROPERTIES_INTERFACE, + NULL, &err); + + result = g_dbus_proxy_call_sync(device_proxy, "GetAll", + g_variant_new("(s)", "org.bluez.Device1"), + G_DBUS_CALL_FLAGS_NONE, + 20, NULL, + &err); + if (err) { + ERR("DBus Error : %s", err->message); + g_clear_error(&err); + return NULL; + } + if (result == NULL) { + ERR("g_dbus_proxy_call_sync function return NULL"); + return NULL; + } + g_variant_get(result, "(@a{sv})", &value); + + if (value) { + GVariant *temp_value = g_variant_lookup_value(value, "Alias", + G_VARIANT_TYPE_STRING); + g_variant_get(temp_value, "(s)", &name); + if (temp_value) + g_variant_unref(temp_value); + + if (name != NULL) + INFO_SECURE("Alias Name [%s]", name); + else { + temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING); + g_variant_get(temp_value, "s", &name); + if (temp_value) + g_variant_unref(temp_value); + INFO_SECURE("Name = %s", name); + } + } + g_variant_unref(result); + g_object_unref(device_proxy); + return name; +} + +int _bt_launch_pbap_popup(const char *device_name, + const char *agent_path) { - if (strlen(buf) < 8) - return -EINVAL; + int ret; + bundle *b; + char event_str[50 + 1]; + + b = bundle_create(); + if (!b) { + ERR("Launching system popup failed"); + return -1; + } + + bundle_add(b, "device-name", device_name); + bundle_add(b, "agent-path", agent_path); + + g_strlcpy(event_str, "phonebook-request", sizeof(event_str)); + + bundle_add(b, "event-type", event_str); + + ret = syspopup_launch("bt-syspopup", b); + if (0 > ret) { + ERR("Popup launch failed... %d", ret); + } + + bundle_free(b); + + INFO("_bt_agent_launch_system_popup"); + return 0; +} + +int _bt_hfp_select_phonebook_memory_status_reply(bt_ag_info_t *hs) +{ + const char *buf = hs->at_pbap_buf; + if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_BLOCKED + || hs->pbap_trusted == BT_AG_FEATURE_PBAP_CANCEL) { + INFO("Doesnot have Access reply with error"); + _bt_select_phonebook_memory_response(hs, + HFP_STATE_MNGR_ERR_NOT_ALLOWED); + return 0; + } if (buf[7] == '?') { _bt_hfp_select_phonebook_memory_status(hs); @@ -994,10 +1101,60 @@ int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf) return 0; } _bt_hfp_select_phonebook_memory(hs, &buf[8]); - return 0; } - return -EINVAL; + return 0; +} + +int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf) +{ + if (strlen(buf) < 8) + return -EINVAL; + INFO("Pbap_trusted %d", hs->pbap_trusted); + if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_SHOW_AUTHORIZATION + || hs->pbap_trusted == BT_AG_FEATURE_PBAP_CANCEL) { + strncpy(hs->at_pbap_buf, buf, sizeof(hs->at_pbap_buf) - 1); + /* Adding Popup here */ + int trust = 0; + bt_initialize(); + int err = bt_device_get_profile_trusted(hs->remote_addr, 1, &trust); + if (err != TIZEN_ERROR_NONE) { + INFO("Show authorization popup %d Error %d", trust, err); + char *name = __bt_get_remote_device_name(hs->path); + INFO_SECURE("remote device name %s", name); + _bt_launch_pbap_popup(name, + BT_AG_AGENT_OBJECT_PATH); + return 0; + } + if (trust == 0) { + INFO("This device has been marked as blocked"); + hs->pbap_trusted = BT_AG_FEATURE_PBAP_BLOCKED; + return -EACCES; + } else + hs->pbap_trusted = BT_AG_FEATURE_PBAP_ALLOWED; + } + if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_ALLOWED) { + INFO("Authorized from PBAP"); + if (buf[7] == '?') { + _bt_hfp_select_phonebook_memory_status(hs); + return 0; + } + + if (buf[7] == '=') { + if (buf[8] == '?') { + _bt_hfp_select_phonebook_memory_list(hs); + return 0; + } + _bt_hfp_select_phonebook_memory(hs, &buf[8]); + return 0; + } + } else if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_BLOCKED) { + INFO("Device is blocked"); + /* Reply with Error */ + return -EACCES; + } + + return 0; } int _bt_read_phonebook_entries_list_response(void *t_device, @@ -1021,7 +1178,7 @@ int _bt_read_phonebook_entries_list_response(void *t_device, } if (used < 1) - index = 0; + used = 1; send_err = _bt_ag_send_at(hs, "\r\n+CPBR: (%d-%d),%d,%d\r\n", index, used, number_length, name_length); @@ -1057,8 +1214,31 @@ int _bt_read_phonebook_entries_indicator(const char *name, const char *number, return 0; } +int _bt_read_phonebook_entries_indicator_by_name(const char *name, + const char *number, uint32_t handle) +{ + int type = 129; + const char *pos = NULL; + + pos = number; + while (*pos == ' ' || *pos == '\t') + pos++; + + /* 145 means international access code, otherwise 129 is used */ + if (*pos == '+') + type = 145; + + _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp, + "\r\n+CPBF: %d,\"%s\",%d,\"%s\"\r\n", + handle, number, type, name); + return 0; +} + int _bt_hfp_read_pb_entries(bt_ag_info_t *hs, const char *buf) { + if (hs->pbap_trusted != BT_AG_FEATURE_PBAP_ALLOWED) + return -EACCES; + if (strlen(buf) < 8) return -EINVAL; @@ -1097,6 +1277,10 @@ int _bt_find_phonebook_entries_status_indicator(uint32_t number_length, int _bt_hfp_find_pb_entires(bt_ag_info_t *hs, const char *buf) { + /* Check if Contact access is permitted or not */ + if (hs->pbap_trusted != BT_AG_FEATURE_PBAP_ALLOWED) + return -EACCES; + if (strlen(buf) < 8) return -EINVAL; @@ -1195,7 +1379,8 @@ int _bt_hfp_apl_command(bt_ag_info_t *hs, const char *buf) { DBG("Got Apple command: %s", buf); - return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NONE); + /*we don't support XAPL commands*/ + return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NOT_SUPPORTED); } /* convert signal strength to a RSSI level */ diff --git a/ag-agent/bluetooth-ag-handler.h b/ag-agent/bluetooth-ag-handler.h old mode 100755 new mode 100644 index 96bd7f3..d3060c6 --- a/ag-agent/bluetooth-ag-handler.h +++ b/ag-agent/bluetooth-ag-handler.h @@ -84,6 +84,7 @@ bt_hfp_agent_error_t _bt_hfp_event_indicator(int index); void _bt_hfp_set_ag_indicator(uint32_t ag_features, const bt_ag_indicators_t *ag_indicators, int rh, const char *chld); +int _bt_hfp_select_phonebook_memory_status_reply(bt_ag_info_t *hs); int _bt_calling_stopped_indicator(void); int _bt_incoming_call_indicator(const char *number, int type); int _bt_dial_number_response(void *t_device, bt_hfp_agent_error_t err); @@ -145,12 +146,17 @@ int _bt_transmit_dtmf_response(void *t_device, bt_hfp_agent_error_t err); int _bt_find_phonebook_entries_response(void *t_device, bt_hfp_agent_error_t err); +int _bt_read_phonebook_entries_indicator(const char *name, const char *number, + uint32_t handle); int _bt_response_and_hold_response(void *t_device, bt_hfp_agent_error_t err); int _bt_answer_call_response(void *hs, bt_hfp_agent_error_t err); int _bt_read_phonebook_entries_indicator(const char *name, const char *number, uint32_t handle); +int _bt_read_phonebook_entries_indicator_by_name(const char *name, + const char *number, + uint32_t handle); int _bt_hfp_get_activity_status_rsp(void *t_device, int status, bt_hfp_agent_error_t err); diff --git a/ag-agent/bluetooth-ag-manager.c b/ag-agent/bluetooth-ag-manager.c index 5ba4477..f58a500 100644 --- a/ag-agent/bluetooth-ag-manager.c +++ b/ag-agent/bluetooth-ag-manager.c @@ -25,7 +25,16 @@ #include #include "bluetooth-ag-agent.h" #include "bluetooth-ag-handler.h" -#include +#include "bluetooth-agent-profile.h" +#include + +#include "bluetooth-ag-phonebook.h" + +#include +#include + +#include +#include #define PHONEBOOK_AGENT_BUS_NAME "org.bluez.pb_agent" #define PHONEBOOK_AGENT_PATH "/org/bluez/pb_agent" @@ -116,20 +125,20 @@ static struct { .signal_strength = 0, }; +#ifdef TIZEN_FEATURE_BT_PBAP_SIM +static const char *agent_pb_store_list[] = { + "\"ME\"", "\"DC\"", "\"MC\"", "\"SM\"", "\"RC\"" +}; +#else static const char *agent_pb_store_list[] = { "\"ME\"", "\"DC\"", "\"MC\"", "\"RC\"" }; +#endif static const char *agent_supported_character_set[] = { "\"UTF-8\"", "\"IRA\"" }; -#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG) -static const char *ag_chld_str = "0,1,2"; -#else -static const char *ag_chld_str = "0,1,2,3"; -#endif - #define AGENT_PB_STORE_LIST_SIZE (sizeof(agent_pb_store_list) \ /sizeof(const char *)) #define AGENT_SUPPORTED_CHARACTER_SET_SIZE ( \ @@ -154,6 +163,33 @@ static struct { .charset_id = 0 }; +void __bt_hfp_print_callpath(const char *call_path, const char *call_sender) +{ + GSList *sender_list = call_senders_paths; + sender_info_t *sender; + + INFO("============================="); + INFO("call path is = %s\n", call_path); + INFO("sender is = %s\n", call_sender); + + if (call_path == NULL || call_sender == NULL) { + ERR("Invalid Parameters"); + return; + } + + while (sender_list != NULL) { + sender = sender_list->data; + + if (sender == NULL) + break; + + INFO("sender->sender_path [%s] ", sender->sender_path); + sender_list = sender_list->next; + } + INFO("============================="); + return; +} + static gboolean __bt_hfp_check_for_callpath(const char *call_path, const char *call_sender) { @@ -185,7 +221,7 @@ static gboolean __bt_hfp_check_for_callpath(const char *call_path, sender_list = sender_list->next; } - ERR("Call path is not already registered"); + ERR("Call path [%s] is not registered", call_path); return FALSE; } @@ -230,19 +266,24 @@ void _bt_hfp_device_disconnected(void *t_device) __bt_hfp_reset_indicators(); } -void _bt_hfp_initialize_telephony_manager(uint32_t ag_features) +void _bt_hfp_initialize_telephony_manager(uint32_t ag_features, TapiHandle *handler) { int index; int value; int ret; + char *ag_chld_str; + + if (TIZEN_PROFILE_WEARABLE) + ag_chld_str = "0,1,2"; + else + ag_chld_str = "0,1,2,3"; /* Reset the indicator values */ for (index = 0; hfp_ag_ind[index].indicator_desc != NULL; index++) { if (g_str_equal(hfp_ag_ind[index].indicator_desc, "battchg")) { - ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, - &value); - if (ret != 0) { - ERR("Get battery status failed : %d\n", ret); + ret = device_battery_get_percent(&value); + if (ret != DEVICE_ERROR_NONE) { + ERR("Get battery status failed. Err = %d\n", ret); } else { /* Send battery status ranging from 0-5 */ if (value < 5) @@ -253,28 +294,28 @@ void _bt_hfp_initialize_telephony_manager(uint32_t ag_features) hfp_ag_ind[index].hfp_value = value / 20 + 1; } } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "signal")) { - ret = vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &value); - if (ret != 0) { + ret = tel_get_property_int(handler, TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL, &value); + if (ret != TAPI_API_SUCCESS) { ERR("Get signal status failed err = %d\n", ret); } else { BT_CHECK_SIGNAL_STRENGTH(value); hfp_ag_ind[index].hfp_value = value; } } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "roam")) { - ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &value); - if (ret != 0) + ret = tel_get_property_int(handler, TAPI_PROP_NETWORK_ROAMING_STATUS, &value); + if (ret != TAPI_API_SUCCESS) ERR("Get roaming status failed err = %d\n", ret); else hfp_ag_ind[index].hfp_value = value; } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "service")) { - ret = vconf_get_int(VCONFKEY_TELEPHONY_SVCTYPE, &value); - if (ret != 0) { + ret = tel_get_property_int(handler, TAPI_PROP_NETWORK_SERVICE_TYPE, &value); + if (ret != TAPI_API_SUCCESS) { ERR("Get Service status failed : %d\n", ret); } else { switch (value) { - case VCONFKEY_TELEPHONY_SVCTYPE_NONE: - case VCONFKEY_TELEPHONY_SVCTYPE_NOSVC: - case VCONFKEY_TELEPHONY_SVCTYPE_SEARCH: + case TAPI_NETWORK_SERVICE_TYPE_UNKNOWN: + case TAPI_NETWORK_SERVICE_TYPE_NO_SERVICE: + case TAPI_NETWORK_SERVICE_TYPE_SEARCH: hfp_ag_ind[index].hfp_value = INDICATOR_EVENT_SERVICE_NONE; break; @@ -335,22 +376,21 @@ bt_hfp_agent_error_t _bt_hfp_register_telephony_agent(gboolean register_flag, if (sender == NULL || path_to_register == NULL) return BT_HFP_AGENT_ERROR_INVALID_PARAM; - DBG(" register_flag = %d", register_flag); - DBG(" path_to_register = %s", path_to_register); - DBG(" sender = %s", sender); + INFO(" register_flag = %d", register_flag); + INFO(" path_to_register = %s", path_to_register); + INFO(" sender = %s", sender); if (register_flag) { if (__bt_hfp_check_for_callpath(path_to_register, sender)) return BT_HFP_AGENT_ERROR_ALREADY_EXSIST; /* add call path to the senders list*/ - DBG("Call path doesn't exist. Add path %s to global path", + INFO("Call path doesn't exist. Add path %s to global path", path_to_register); sender_info = g_new0(sender_info_t, 1); sender_info->sender_path = g_strdup(path_to_register); sender_info->sender_name = g_strdup(sender); - call_senders_paths = g_slist_append(call_senders_paths, - sender_info); + call_senders_paths = g_slist_append(call_senders_paths, sender_info); return BT_HFP_AGENT_ERROR_NONE; } else { @@ -365,10 +405,12 @@ bt_hfp_agent_error_t _bt_hfp_register_telephony_agent(gboolean register_flag, if (g_strcmp0(sender_info->sender_path, path_to_register) == 0) { + INFO("Remove path [%s]", path_to_register); call_senders_paths = g_slist_remove( call_senders_paths, sender_info); __bt_hfp_clear_sender_path(sender_info); + return BT_HFP_AGENT_ERROR_NONE; } s_list = s_list->next; @@ -764,15 +806,17 @@ bt_hfp_agent_error_t _bt_hfp_incoming_call(const char *call_path, const char *sender) { struct telephony_call *t_call = NULL; - bt_hfp_agent_error_t hfp_err = BT_HFP_AGENT_ERROR_NOT_AVAILABLE; + bt_hfp_agent_error_t hfp_err = BT_HFP_AGENT_ERROR_NONE; int t_number = AGENT_NUMBER_TYPE_TELEPHONY; int error; if (sender == NULL || call_path == NULL) return BT_HFP_AGENT_ERROR_INVALID_PARAM; - if (!__bt_hfp_check_for_callpath(call_path, sender)) + if (!__bt_hfp_check_for_callpath(call_path, sender)) { + __bt_hfp_print_callpath(call_path, sender); return BT_HFP_AGENT_ERROR_NOT_AVAILABLE; + } if (!__bt_hfp_is_call_allowed(call_path)) return BT_HFP_AGENT_ERROR_NOT_AVAILABLE; @@ -840,11 +884,11 @@ bt_hfp_agent_error_t _bt_hfp_outgoing_call(const char *call_path, bt_hfp_agent_error_t ret = BT_HFP_AGENT_ERROR_NONE; gboolean err = FALSE; - err = __bt_hfp_check_for_callpath(call_path, sender); - if (!err) + if (!err) { + __bt_hfp_print_callpath(call_path, sender); return BT_HFP_AGENT_ERROR_NOT_AVAILABLE; - + } /*check if the call_path exisits in the active call list, if not don't allow as the call may be initated by some other application*/ @@ -878,8 +922,10 @@ bt_hfp_agent_error_t _bt_hfp_change_call_status(const char *call_path, ret = __bt_hfp_check_for_callpath(call_path, sender); - if (!ret) + if (!ret) { + __bt_hfp_print_callpath(call_path, sender); return BT_HFP_AGENT_ERROR_NOT_AVAILABLE; + } ret = __bt_hfp_is_call_allowed(call_path); if (!ret) @@ -1048,7 +1094,7 @@ int _bt_hfp_set_property_name(const char *property, const char *operator_name) if (g_str_equal("SubscriberNumberChanged", property)) { g_free(ag_subscriber_num); ag_subscriber_num = g_strdup(operator_name); - DBG("HFP: subscriber_number updated: %s", ag_subscriber_num); + DBG_SECURE("HFP: subscriber_number updated: %s", ag_subscriber_num); ret = 1; } return ret; @@ -1179,12 +1225,16 @@ static int __bt_hfp_release_call(struct telephony_call *t_call) static int __bt_hfp_release_conference(void) { GSList *temp_list = existing_call_list; + int ret = 0; while (temp_list != NULL) { struct telephony_call *t_call = temp_list->data; - if (t_call->call_conference) - __bt_hfp_release_call(t_call); + if (t_call->call_conference) { + ret = __bt_hfp_release_call(t_call); + if (ret < 0) + ERR("Seems like there are no active calls."); + } temp_list = temp_list->next; } @@ -1524,8 +1574,6 @@ void _bt_hfp_release_all_calls_by_sender(const char *sender) if (!sender) return; - DBG("sender [%s]", sender); - while (temp_list != NULL) { struct telephony_call *t_call = temp_list->data; @@ -1611,57 +1659,27 @@ fail: static int __bt_hfp_get_phonebook_count(const char *path, uint32_t *max_size, uint32_t *used) { -#ifndef TIZEN_PROFILE_WEARABLE - GDBusConnection *g_conn; - GDBusProxy *g_proxy; - GError *err = NULL; - GVariant *ret = NULL; + FN_START; + PhoneBookType pb_type = TELECOM_NONE; + guint count = 0; uint32_t max = 0; - uint32_t size = 0; - - g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); - if (!g_conn) { - if (err) { - ERR("Unable to connect to gdbus: %s", err->message); - g_clear_error(&err); - } - return -1; + INFO("name: %s\n", path); + if (contacts_connect() != CONTACTS_ERROR_NONE) { + ERR("Can not connect contacts server\n"); + return 0; } - g_proxy = g_dbus_proxy_new_sync(g_conn, - G_DBUS_PROXY_FLAGS_NONE, NULL, - PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH, - PHONEBOOK_AGENT_INTERFACE, NULL, &err); + pb_type = __bluetooth_pb_get_storage_pb_type(path); - if (!g_proxy) { - if (err) { - ERR("Unable to connect to gdbus: %s", err->message); - g_clear_error(&err); - } - return -1; + if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) { + ERR("unable to get count"); + if (contacts_disconnect() != CONTACTS_ERROR_NONE) + ERR("contacts_disconnect failed"); + return 0; } - ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookSizeAt", - g_variant_new("(s)", - path), - G_DBUS_CALL_FLAGS_NONE, -1, - NULL, &err); - - if (ret == NULL) { - ERR("dbus call failed"); - if (err != NULL) { - ERR("D-Bus API failure: errCode[%x], message[%s]", - err->code, err->message); - - g_clear_error(&err); - } - } - if (ret != NULL) { - g_variant_get(ret, "(u)", &size); - g_variant_unref(ret); - } - DBG("Size returned %d", size); + DBG("Size returned %d", count); if ((g_strcmp0(path, "\"SM\"") == 0) || (g_strcmp0(path, "\"ME\"") == 0)) { max = AGENT_MAX_PB_COUNT; @@ -1674,17 +1692,14 @@ static int __bt_hfp_get_phonebook_count(const char *path, uint32_t *max_size, if (max_size) *max_size = max; if (used) { - if (size > max) + if (count > max) *used = max; else - *used = size; + *used = count; } - - if (g_conn) - g_object_unref(g_conn); - if (g_proxy) - g_object_unref(g_proxy); -#endif + if (contacts_disconnect() != CONTACTS_ERROR_NONE) + ERR("contacts_disconnect failed"); + FN_END; return 0; } @@ -1790,96 +1805,33 @@ void _bt_hfp_read_phonebook_entries_list(void *t_device) static int __bt_hfp_get_phonebook_entries(int start_index, int end_index) { -#ifdef TIZEN_PROFILE_WEARABLE - int count = 0; -#else - GDBusConnection *g_conn; - GDBusProxy *g_proxy; - GError *err = NULL; - GVariant *ret = NULL; + FN_START; int count = 0; - GVariant *value = NULL; - GVariant *tuple = NULL; - const char *name = NULL; - const char *number = NULL; - - char *uni_name; - char *uni_number; - - uint32_t handle = 0; + PhoneBookType pb_type = TELECOM_NONE; - g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + DBG("command: %s, start_index: %d, end_index: %d\n", + agent_pb_store_list[ag_pb_info.path_id], start_index, end_index); - if (!g_conn) { - if (err) { - ERR("Unable to connect to gdbus: %s", err->message); - g_clear_error(&err); - } - return -1; + if (contacts_connect() != CONTACTS_ERROR_NONE) { + ERR("Can not connect contacts server"); + return 0; } - g_proxy = g_dbus_proxy_new_sync(g_conn, - G_DBUS_PROXY_FLAGS_NONE, NULL, - PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH, - PHONEBOOK_AGENT_INTERFACE, NULL, &err); - if (!g_proxy) { - if (err) { - ERR("Unable to connect to gdbus: %s", err->message); - g_clear_error(&err); - } - return -1; - } + pb_type = __bluetooth_pb_get_storage_pb_type( + agent_pb_store_list[ag_pb_info.path_id]); - ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookEntriesAt", - g_variant_new("(sii)", - agent_pb_store_list[ag_pb_info.path_id], - start_index, end_index), - G_DBUS_CALL_FLAGS_NONE, -1, - NULL, &err); + if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) { + if (contacts_disconnect() != CONTACTS_ERROR_NONE) + ERR("contacts_disconnect failed"); + return 0; + } - if (ret == NULL) { - ERR("Dbus call failed"); - if (err != NULL) { - ERR("D-Bus API failure: errCode[%x], message[%s]", - err->code, err->message); + __bluetooth_pb_get_list_number(pb_type, + start_index, end_index, &count); - g_clear_error(&err); - } else { - ERR("error returned was NULL"); - } - return -1; - } else { - tuple = g_variant_get_child_value(ret, 0); - if (tuple != NULL) { - int number_contacts = g_variant_n_children(tuple); - DBG("number of contacts %d", number_contacts); - while (count < number_contacts) { - value = NULL; - - value = g_variant_get_child_value(tuple, count); - - g_variant_get(value, "(ssu)", &name, &number, &handle); - count++; - uni_name = g_strndup(name, AGENT_PB_NAME_MAX_LENGTH); - uni_number = g_strndup(number, AGENT_PB_NAME_MAX_LENGTH); - - _bt_read_phonebook_entries_indicator(uni_name, - uni_number, handle); - g_variant_unref(value); - g_free(uni_name); - g_free(uni_number); - g_free((gpointer)name); - g_free((gpointer)number); - } - g_variant_unref(tuple); - } - } - g_variant_unref(ret); - if (g_conn) - g_object_unref(g_conn); - if (g_proxy) - g_object_unref(g_proxy); -#endif + if (contacts_disconnect() != CONTACTS_ERROR_NONE) + ERR("contacts_disconnect failed"); + FN_END; return count; } @@ -1934,8 +1886,47 @@ void _bt_hfp_find_phonebook_entries_status(void *t_device) HFP_STATE_MNGR_ERR_NONE); } +static int __bt_hfp_get_phonebook_entries_by_name(int start_index, + int end_index, + const char *str) +{ + FN_START; + int count = 0; + PhoneBookType pb_type = TELECOM_NONE; + + DBG("command: %s, start_index: %d, end_index: %d\n", + agent_pb_store_list[ag_pb_info.path_id], start_index, end_index); + + if (contacts_connect() != CONTACTS_ERROR_NONE) { + ERR("Can not connect contacts server"); + return 0; + } + + pb_type = __bluetooth_pb_get_storage_pb_type( + agent_pb_store_list[ag_pb_info.path_id]); + + if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) { + if (contacts_disconnect() != CONTACTS_ERROR_NONE) + ERR("contacts_disconnect failed"); + return 0; + } + + __bluetooth_pb_get_list_entries_by_name(pb_type, + start_index, end_index, str, &count); + + if (contacts_disconnect() != CONTACTS_ERROR_NONE) + ERR("contacts_disconnect failed"); + FN_END; + return count; +} + static int __bt_hfp_find_pb_entries(const char *str) { + char *search = g_ascii_strup(str, strlen(str)); + + /* No limit on number of searched item and need to search complete list*/ + __bt_hfp_get_phonebook_entries_by_name(0, 0, search); + g_free(search); return 0; } diff --git a/ag-agent/bluetooth-ag-phonebook.c b/ag-agent/bluetooth-ag-phonebook.c new file mode 100644 index 0000000..e6528e3 --- /dev/null +++ b/ag-agent/bluetooth-ag-phonebook.c @@ -0,0 +1,1236 @@ +/* + * bluetooth-ag-phonebook.c + * + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hocheol Seo + * Sangki Park + * Chanyeol Park + * Rakesh MK + * Anurag B + * + * 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. + * + */ + +#include "bluetooth-ag-phonebook.h" +#include "bluetooth-ag-agent.h" +#include "bluetooth-ag-handler.h" + + +static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void); + +static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void); + +static contacts_query_h __bluetooth_pb_query_phone_log_missed(void); + +static contacts_query_h __bluetooth_pb_query_phone_log_combined(void); + +#ifdef TIZEN_FEATURE_BT_PBAP_SIM +static gchar *_bluetooth_pb_number_from_person_id(gint person_id); + +static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact); + +static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact); +#endif + +PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name) +{ + FN_START; + if (name == NULL) + return TELECOM_NONE; + + if (g_strcmp0(name, "\"ME\"") == 0) + return TELECOM_PB; + + if (g_strcmp0(name, "\"RC\"") == 0) + return TELECOM_ICH; + + if (g_strcmp0(name, "\"DC\"") == 0) + return TELECOM_OCH; + + if (g_strcmp0(name, "\"MC\"") == 0) + return TELECOM_MCH; +#ifdef TIZEN_FEATURE_BT_PBAP_SIM + if (g_strcmp0(name, "\"SM\"") == 0) + return SIM_PB; +#endif + + FN_END; + return TELECOM_NONE; +} + +static bool _bt_is_sim_addressbook(const char *addressbook) +{ + return g_str_has_prefix(addressbook, SIM_ADDRESSBOOK_PREFIX); +} + +static bool __bt_is_matching_addressbook(const char *addressbook_name, + int addressbook) +{ + bool is_sim_addressbook = _bt_is_sim_addressbook(addressbook_name); + + if ((is_sim_addressbook == false + && addressbook == PBAP_ADDRESSBOOK_PHONE) || + (is_sim_addressbook == true + && addressbook == PBAP_ADDRESSBOOK_SIM)) + return true; + + return false; +} + +static contacts_query_h __bluetooth_pb_query_person(int addressbook) +{ + FN_START; + contacts_query_h query = NULL; + contacts_filter_h filter = NULL; + contacts_list_h recordList = NULL; + contacts_record_h record = NULL; + + char *addressbook_name = NULL; + int address_book_id = 0; + int count = 0; + unsigned int i = 0; + gint status; + bool is_first_condition = true; + DBG("Addressbook [%d]", addressbook); + /* Create query*/ + status = contacts_query_create(_contacts_person_contact._uri, &query); + if (status != 0) { + ERR("Could not create query"); + return NULL; + } + + /* Create addressbook Filter*/ + contacts_db_get_all_records(_contacts_address_book._uri, 0, 0, + &recordList); + contacts_filter_create(_contacts_person_contact._uri, &filter); + contacts_list_get_count(recordList, &count); + INFO("COUNT %d", count); + for (i = 0; i < count; i++) { + status = contacts_list_get_current_record_p(recordList, &record); + if (status != CONTACTS_ERROR_NONE) { + ERR("Contact list get api failed %d", status); + goto next; + } + status = contacts_record_get_str_p(record, _contacts_address_book.name, + &addressbook_name); + if (status != CONTACTS_ERROR_NONE) { + ERR("Contact record get api failed %d", status); + goto next; + } + status = contacts_record_get_int(record, _contacts_address_book.id, + &address_book_id); + if (status != CONTACTS_ERROR_NONE) { + ERR("contacts record get int api failed %d", status); + goto next; + } + + DBG("Addressbook ID: [%d] Addressbook Name: [%s]", + address_book_id, addressbook_name); + + if (__bt_is_matching_addressbook(addressbook_name, + addressbook)) { + if (is_first_condition) + is_first_condition = false; + else + contacts_filter_add_operator(filter, + CONTACTS_FILTER_OPERATOR_OR); + DBG("SELECTED Addressbook ID: [%d] Addressbook Name: [%s]", + address_book_id, addressbook_name); + status = contacts_filter_add_int(filter, + _contacts_person_contact.address_book_id, + CONTACTS_MATCH_EQUAL, address_book_id); + if (status != CONTACTS_ERROR_NONE) + ERR("Contact filter add failed %d", status); + } +next: + if (contacts_list_next(recordList) != CONTACTS_ERROR_NONE) + break; + } + + contacts_list_destroy(recordList, true); + + status = contacts_query_set_filter(query, filter); + if (status != CONTACTS_ERROR_NONE) + ERR("Could not Apply Filter"); + + contacts_filter_destroy(filter); + FN_END; + return query; +} + +gboolean __bluetooth_pb_get_count(PhoneBookType pb_type, + guint *count) +{ + FN_START; + contacts_query_h query = NULL; + + gint status; + gint signed_count; + INFO("Pb type %d", pb_type); + switch (pb_type) { + case TELECOM_PB: + query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE); + break; + case TELECOM_ICH: + query = __bluetooth_pb_query_phone_log_incoming(); + break; + case TELECOM_OCH: + query = __bluetooth_pb_query_phone_log_outgoing(); + break; + case TELECOM_MCH: + query = __bluetooth_pb_query_phone_log_missed(); + break; + case TELECOM_CCH: + query = __bluetooth_pb_query_phone_log_combined(); + break; +#ifdef TIZEN_FEATURE_BT_PBAP_SIM + case SIM_PB: + query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM); + break; +#endif + default: + return FALSE; + } + + if (query == NULL) + return FALSE; + + status = contacts_db_get_count_with_query(query, &signed_count); + + if (status != CONTACTS_ERROR_NONE) { + contacts_query_destroy(query); + return FALSE; + } + + contacts_query_destroy(query); + + if (signed_count < 0) + signed_count = 0; + + *count = (gint) signed_count; + + FN_END; + return TRUE; +} + +void __bluetooth_pb_list_ptr_array_add(const gchar *name, + const gchar *number, + gint handle) +{ + FN_START; + gchar *temp_name = g_strdup(name); + gchar *temp_number = NULL; + if (number == NULL) + temp_number = g_strdup(""); + else + temp_number = g_strdup(number); + + _bt_read_phonebook_entries_indicator(temp_name, + temp_number, handle); + + g_free(temp_name); + g_free(temp_number); + FN_END; +} + +void __bluetooth_pb_list_ptr_array_add_by_name(const gchar *name, + const gchar *number, + gint handle) +{ + FN_START; + gchar *temp_name = g_strdup(name); + gchar *temp_number = NULL; + if (number == NULL) + temp_number = g_strdup(""); + else + temp_number = g_strdup(number); + + _bt_read_phonebook_entries_indicator_by_name(temp_name, + temp_number, handle); + + g_free(temp_name); + g_free(temp_number); + FN_END; +} + +contacts_query_h __bluetooth_pb_query_person_number(void) +{ + FN_START; + contacts_query_h query = NULL; + + gint status; + + status = contacts_query_create(_contacts_person_number._uri, + &query); + + if (status != CONTACTS_ERROR_NONE) + return NULL; + + FN_END; + return query; +} + +void __bluetooth_pb_get_contact_list_number( + contacts_query_h query, + gint start_index, + gint end_index, + gint *count) +{ + FN_START; + contacts_list_h record_list = NULL; + gint status; + gint i; + gint from; + gint to; + gint offset; + + from = start_index; + to = end_index; + + if (from < 1) + from = 1; + + if (to < 1) + to = 1; + + offset = to - from + 1; + if (offset <= 0) + return; + + i = from; + + status = contacts_db_get_records_with_query(query, + from - 1 , offset, + &record_list); + + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); + return; + } + + status = contacts_list_first(record_list); + + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); + return; + } + + do { + contacts_record_h record; + + gchar *display_name; + gchar *number; + + record = NULL; + status = contacts_list_get_current_record_p(record_list, + &record); + + if (status != CONTACTS_ERROR_NONE) + continue; + + display_name = NULL; + number = NULL; + + contacts_record_get_str_p(record, + _contacts_person_number.display_name, + &display_name); + contacts_record_get_str_p(record, + _contacts_person_number.number, + &number); + + __bluetooth_pb_list_ptr_array_add(display_name, number, i); + + i++; + } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE); + *count = i; + + contacts_list_destroy(record_list, TRUE); + FN_END; +} + +#ifdef TIZEN_FEATURE_BT_PBAP_SIM +static gchar *__bluetooth_pb_number_from_contact(contacts_record_h contact) +{ + FN_START; + gint count = 0; + + gint status; + gint i; + + gchar *str = NULL; + + status = contacts_record_get_child_record_count(contact, + _contacts_contact.number, + &count); + + if (status != CONTACTS_ERROR_NONE) + return NULL; + + for (i = 0; i < count; i++) { + contacts_record_h number = NULL; + + gchar *tmp = NULL; + + bool is_default = false; + + status = contacts_record_get_child_record_at_p(contact, + _contacts_contact.number, i, &number); + + if (status != CONTACTS_ERROR_NONE) + continue; + + status = contacts_record_get_bool(number, + _contacts_number.is_default, + &is_default); + + if (status != CONTACTS_ERROR_NONE) + continue; + + if (is_default == FALSE) + continue; + + status = contacts_record_get_str_p(number, + _contacts_number.number, + &tmp); + + if (status != CONTACTS_ERROR_NONE) + continue; + + if (tmp) { + str = g_strdup(tmp); + break; + } + } + + /* get first number */ + if (str == NULL) { + gchar *tmp = NULL; + + contacts_record_h number = NULL; + + status = contacts_record_get_child_record_at_p(contact, + _contacts_contact.number, 0, &number); + + if (status != CONTACTS_ERROR_NONE) + return NULL; + + status = contacts_record_get_str_p(number, + _contacts_number.number, + &tmp); + + if (status != CONTACTS_ERROR_NONE) + return NULL; + + str = g_strdup(tmp); + } + + FN_END; + return str; +} + +gchar *_bluetooth_pb_number_from_person_id(gint person_id) +{ + FN_START; + contacts_record_h person = NULL; + contacts_record_h contact = NULL; + + gint status; + gint contact_id = 0; + + gchar *str; + + status = contacts_db_get_record(_contacts_person._uri, + person_id, + &person); + + if (status != CONTACTS_ERROR_NONE) + return NULL; + + + status = contacts_record_get_int(person, + _contacts_person.display_contact_id, + &contact_id); + + if (status != CONTACTS_ERROR_NONE) { + contacts_record_destroy(person, TRUE); + return NULL; + } + + status = contacts_db_get_record(_contacts_contact._uri, + contact_id, + &contact); + + if (status != CONTACTS_ERROR_NONE) { + contacts_record_destroy(person, TRUE); + return NULL; + } + + str = __bluetooth_pb_number_from_contact(contact); + + contacts_record_destroy(contact, TRUE); + contacts_record_destroy(person, TRUE); + + FN_END; + return str; +} + +gchar *_bluetooth_pb_name_from_person_id(gint person_id) +{ + FN_START; + contacts_record_h person = NULL; + contacts_record_h contact = NULL; + + gint status; + gint contact_id = 0; + + gchar *str; + + status = contacts_db_get_record(_contacts_person._uri, + person_id, + &person); + + if (status != CONTACTS_ERROR_NONE) + return NULL; + + status = contacts_record_get_int(person, + _contacts_person.display_contact_id, + &contact_id); + + if (status != CONTACTS_ERROR_NONE) { + contacts_record_destroy(person, TRUE); + return NULL; + } + + status = contacts_db_get_record(_contacts_contact._uri, + contact_id, + &contact); + + if (status != CONTACTS_ERROR_NONE) { + contacts_record_destroy(person, TRUE); + return NULL; + } + + str = __bluetooth_pb_name_from_contact(contact); + + contacts_record_destroy(contact, TRUE); + contacts_record_destroy(person, TRUE); + + FN_END; + return str; +} + +static gchar *__bluetooth_pb_vcard_escape(const gchar *str) +{ + FN_START; + GString *escaped; + + gchar *st = NULL; + gchar *pos = NULL; + + if (str == NULL) + return NULL; + + escaped = g_string_new(NULL); + + st = (gchar *)str; + pos = st; + + while (*pos != '\0') { + if (*pos == ';') { + g_string_append_len(escaped, st, (pos - st)); + g_string_append(escaped, "\\;"); + + pos++; + st = pos; + } else { + pos++; + } + } + + g_string_append_len(escaped, st, (pos - st)); + FN_END; + return g_string_free(escaped, FALSE); +} + +static gchar *__bluetooth_pb_name_from_contact(contacts_record_h contact) +{ + FN_START; + contacts_record_h name = NULL; + + GString *str; + + gint status; + gint i; + + gint name_size = 5; + gint name_val[] = { _contacts_name.last, + _contacts_name.first, + _contacts_name.addition, + _contacts_name.prefix, + _contacts_name.suffix }; + + + status = contacts_record_get_child_record_at_p(contact, + _contacts_contact.name, 0, &name); + + if (status != CONTACTS_ERROR_NONE) + return NULL; + + str = g_string_new(NULL); + + for (i = 0; i < name_size; i++) { + gchar *tmp = NULL; + gchar *escape = NULL; + + status = contacts_record_get_str_p(name, name_val[i], &tmp); + + if (status != CONTACTS_ERROR_NONE) + continue; + + escape = __bluetooth_pb_vcard_escape(tmp); + + g_string_append(str, escape); + + g_free(escape); + } + + FN_END; + return g_string_free(str, FALSE); +} + +static void __bluetooth_pb_get_contact_list( + contacts_query_h query, + gint start_index, + gint end_index, + gint *count) +{ + FN_START; + contacts_list_h record_list = NULL; + gint i = 0; + + gint status; + + status = contacts_db_get_records_with_query(query, + start_index, end_index, &record_list); + + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); + return; + } + + status = contacts_list_first(record_list); + + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); + return; + } + + do { + contacts_record_h record; + + gint id; + + record = NULL; + status = contacts_list_get_current_record_p(record_list, + &record); + + if (status != CONTACTS_ERROR_NONE) + continue; + + id = 0; + status = contacts_record_get_int(record, + _contacts_person_contact.person_id, + &id); + + if (status != CONTACTS_ERROR_NONE) + continue; + + gchar *name; + gchar *number; + + name = _bluetooth_pb_name_from_person_id(id); + number = _bluetooth_pb_number_from_person_id(id); + + __bluetooth_pb_list_ptr_array_add(name, number, id); + i++; + + g_free(name); + g_free(number); + + } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE); + + *count = i; + contacts_list_destroy(record_list, TRUE); + FN_END; +} + +static void __bluetooth_pb_get_contact_list_by_name( + contacts_query_h query, + gint start_index, + gint end_index, + const char *str, + gint *count) +{ + FN_START; + contacts_list_h record_list = NULL; + gint i = 0; + contacts_record_h record; + gint id; + gint status; + gchar *name; + gchar *number; + char *pb_name_up; + + status = contacts_db_get_records_with_query(query, + start_index, end_index, &record_list); + + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); + return; + } + + status = contacts_list_first(record_list); + + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); + return; + } + + do { + record = NULL; + status = contacts_list_get_current_record_p(record_list, + &record); + + if (status != CONTACTS_ERROR_NONE) + continue; + + id = 0; + status = contacts_record_get_int(record, + _contacts_person_contact.person_id, + &id); + + if (status != CONTACTS_ERROR_NONE) + continue; + + name = _bluetooth_pb_name_from_person_id(id); + number = _bluetooth_pb_number_from_person_id(id); + pb_name_up = g_ascii_strup(name, strlen(name)); + + if (g_strstr_len(pb_name_up, -1, str) != NULL) + __bluetooth_pb_list_ptr_array_add_by_name(name, number, id); + + g_free(pb_name_up); + i++; + + g_free(name); + g_free(number); + + } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE); + + *count = i; + contacts_list_destroy(record_list, TRUE); + FN_END; +} +#endif + +static contacts_query_h __bluetooth_pb_query_phone_log_incoming(void) +{ + FN_START; + gint size = 4; + gint match[] = { + CONTACTS_PLOG_TYPE_VOICE_INCOMMING, + CONTACTS_PLOG_TYPE_VIDEO_INCOMMING, + CONTACTS_PLOG_TYPE_VOICE_REJECT, + CONTACTS_PLOG_TYPE_VIDEO_REJECT + }; + + FN_END; + return __bluetooth_pb_query_phone_log(match, size); +} + +static contacts_query_h __bluetooth_pb_query_phone_log_outgoing(void) +{ + FN_START; + gint size = 2; + gint match[] = { + CONTACTS_PLOG_TYPE_VOICE_OUTGOING, + CONTACTS_PLOG_TYPE_VIDEO_OUTGOING + }; + + FN_END; + return __bluetooth_pb_query_phone_log(match, size); +} + +static contacts_query_h __bluetooth_pb_query_phone_log_missed(void) +{ + FN_START; + gint size = 4; + gint match[] = { + CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN, + CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN, + CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN, + CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN + }; + + FN_END; + return __bluetooth_pb_query_phone_log(match, size); +} + +static contacts_query_h __bluetooth_pb_query_phone_log_combined(void) +{ + FN_START; + gint size = 10; + gint match[] = { + CONTACTS_PLOG_TYPE_VOICE_INCOMMING, + CONTACTS_PLOG_TYPE_VIDEO_INCOMMING, + CONTACTS_PLOG_TYPE_VOICE_OUTGOING, + CONTACTS_PLOG_TYPE_VIDEO_OUTGOING, + CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN, + CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN, + CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN, + CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN, + CONTACTS_PLOG_TYPE_VOICE_REJECT, + CONTACTS_PLOG_TYPE_VIDEO_REJECT + }; + + FN_END; + return __bluetooth_pb_query_phone_log(match, size); +} + + +gint __bluetooth_pb_phone_log_filter_append(contacts_filter_h filter, + gint *match, + gint size) +{ + FN_START; + gint i; + gint status; + + for (i = 0; i < size; i++) { + + if (i > 0) { + status = contacts_filter_add_operator(filter, + CONTACTS_FILTER_OPERATOR_OR); + + if (status != CONTACTS_ERROR_NONE) + return status; + } + + status = contacts_filter_add_int(filter, + _contacts_phone_log.log_type, + CONTACTS_MATCH_EQUAL, + match[i]); + + if (status != CONTACTS_ERROR_NONE) + return status; + } + + FN_END; + return CONTACTS_ERROR_NONE; +} + +contacts_query_h __bluetooth_pb_query_phone_log(gint *match, + gint size) +{ + FN_START; + contacts_query_h query = NULL; + contacts_filter_h filter = NULL; + + gint status; + + status = contacts_query_create(_contacts_phone_log._uri, + &query); + + if (status != CONTACTS_ERROR_NONE) + return NULL; + + status = contacts_filter_create(_contacts_phone_log._uri, &filter); + + if (status != CONTACTS_ERROR_NONE) { + contacts_query_destroy(query); + return NULL; + } + + status = __bluetooth_pb_phone_log_filter_append(filter, match, size); + + if (status != CONTACTS_ERROR_NONE) { + contacts_filter_destroy(filter); + contacts_query_destroy(query); + return NULL; + } + + status = contacts_query_set_filter(query, filter); + + if (status != CONTACTS_ERROR_NONE) { + contacts_filter_destroy(filter); + contacts_query_destroy(query); + return NULL; + } + + status = contacts_query_set_sort(query, + _contacts_phone_log.log_time, + false); + + if (status != CONTACTS_ERROR_NONE) { + contacts_filter_destroy(filter); + contacts_query_destroy(query); + return NULL; + } + + contacts_filter_destroy(filter); + + FN_END; + return query; +} + +static gint __bluetooth_pb_person_id_from_phonelog_id(gint phonelog_id) +{ + FN_START; + contacts_query_h query = NULL; + contacts_filter_h filter = NULL; + contacts_list_h record_list = NULL; + + contacts_record_h phone_log = NULL; + contacts_record_h record = NULL; + + gint status; + gint person_id = 0; + + status = contacts_db_get_record(_contacts_phone_log._uri, + phonelog_id, + &phone_log); + + if (status != CONTACTS_ERROR_NONE) + return 0; + + status = contacts_record_get_int(phone_log, + _contacts_phone_log.person_id, + &person_id); + + if (status != CONTACTS_ERROR_NONE) { + contacts_record_destroy(phone_log, TRUE); + return 0; + } + + contacts_record_destroy(phone_log, TRUE); + + if (person_id) + return person_id; + + status = contacts_filter_create(_contacts_person_phone_log._uri, + &filter); + + if (status != CONTACTS_ERROR_NONE) + return 0; + + + status = contacts_filter_add_int(filter, + _contacts_person_phone_log.log_id, + CONTACTS_MATCH_EQUAL, + phonelog_id); + + if (status != CONTACTS_ERROR_NONE) + goto done; + + status = contacts_query_create(_contacts_person_phone_log._uri, &query); + + if (status != CONTACTS_ERROR_NONE) + goto done; + + status = contacts_query_set_filter(query, filter); + + if (status != CONTACTS_ERROR_NONE) + goto done; + + status = contacts_db_get_records_with_query(query, -1, -1, + &record_list); + + if (status != CONTACTS_ERROR_NONE) + goto done; + + status = contacts_list_first(record_list); + + if (status != CONTACTS_ERROR_NONE) + goto done; + + status = contacts_list_get_current_record_p(record_list, &record); + + 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) + goto done; + +done: + if (record_list != NULL) + contacts_list_destroy(record_list, TRUE); + + contacts_filter_destroy(filter); + + if (query != NULL) + contacts_query_destroy(query); + + FN_END; + return person_id; +} + +gchar *_bluetooth_pb_fn_from_person_id(gint person_id) +{ + FN_START; + contacts_record_h person = NULL; + + gint status; + + gchar *str = NULL; + + status = contacts_db_get_record(_contacts_person._uri, + person_id, + &person); + + if (status != CONTACTS_ERROR_NONE) + return NULL; + + status = contacts_record_get_str(person, + _contacts_person.display_name, + &str); + + if (status != CONTACTS_ERROR_NONE) + return NULL; + + contacts_record_destroy(person, TRUE); + + FN_END; + return str; +} + +gchar *_bluetooth_pb_fn_from_phonelog_id(gint phonelog_id) +{ + FN_START; + gint person_id = 0; + gchar *str = NULL; + + person_id = __bluetooth_pb_person_id_from_phonelog_id(phonelog_id); + + if (person_id > 0) + str = _bluetooth_pb_fn_from_person_id(person_id); + else + str = g_strdup(""); + + FN_END; + return str; +} + + +static void __bluetooth_pb_get_phone_log_list_number(contacts_query_h query, + gint start_index, + gint end_index, + int *count) +{ + FN_START; + contacts_list_h record_list = NULL; + + gint status; + + gint i; + + gint from; + gint to; + gint offset; + + from = start_index; + to = end_index; + + if (from < 1) + from = 1; + + if (to < 1) + to = 1; + + offset = to - from + 1; + if (offset <= 0) + return; + + i = from; + + status = contacts_db_get_records_with_query(query, + from - 1 , offset, + &record_list); + + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); + return; + } + + status = contacts_list_first(record_list); + if (status != CONTACTS_ERROR_NONE) { + contacts_list_destroy(record_list, TRUE); + return; + } + + do { + contacts_record_h record = NULL; + + gint id; + + gchar *display_name; + gchar *number; + + record = NULL; + status = contacts_list_get_current_record_p(record_list, + &record); + + if (status != CONTACTS_ERROR_NONE) + continue; + + id = 0; + status = contacts_record_get_int(record, + _contacts_phone_log.id, + &id); + if (status != CONTACTS_ERROR_NONE) { + ERR("contact_record_get_int api failed %d", status); + continue; + } + + display_name = _bluetooth_pb_fn_from_phonelog_id(id); + + number = NULL; + contacts_record_get_str_p(record, + _contacts_phone_log.address, + &number); + + + __bluetooth_pb_list_ptr_array_add(display_name, number, i); + + i++; + + g_free(display_name); + + } while (contacts_list_next(record_list) == CONTACTS_ERROR_NONE); + *count = i; + + contacts_list_destroy(record_list, TRUE); + FN_END; +} + +void __bluetooth_pb_get_list_entries_by_name( + PhoneBookType pb_type, + gint start_index, + gint end_index, + const char *str, + gint *count) +{ + FN_START; + contacts_query_h query; + + switch (pb_type) { + case TELECOM_PB: + query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE); + __bluetooth_pb_get_contact_list_by_name(query, + start_index, end_index, str, count); + break; + + case TELECOM_ICH: + query = __bluetooth_pb_query_phone_log_incoming(); + __bluetooth_pb_get_contact_list_by_name(query, + start_index, end_index, str, count); + break; + case TELECOM_OCH: + query = __bluetooth_pb_query_phone_log_outgoing(); + __bluetooth_pb_get_contact_list_by_name(query, + start_index, end_index, str, count); + break; + case TELECOM_MCH: + query = __bluetooth_pb_query_phone_log_missed(); + __bluetooth_pb_get_contact_list_by_name(query, + start_index, end_index, str, count); + break; + case TELECOM_CCH: + query = __bluetooth_pb_query_phone_log_combined(); + __bluetooth_pb_get_contact_list_by_name(query, + start_index, end_index, str, count); + break; +#ifdef TIZEN_FEATURE_BT_PBAP_SIM + case SIM_PB: + query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM); + __bluetooth_pb_get_contact_list_by_name(query, + start_index, end_index, str, count); + break; +#endif + default: + return; + } + + if (query) + contacts_query_destroy(query); + FN_END; +} + +void __bluetooth_pb_get_list_number( + PhoneBookType pb_type, + gint start_index, + gint end_index, + gint *count) +{ + FN_START; + contacts_query_h query; + + switch (pb_type) { + case TELECOM_PB: + query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_PHONE); + __bluetooth_pb_get_contact_list(query, + start_index, end_index, count); + break; + + case TELECOM_ICH: + query = __bluetooth_pb_query_phone_log_incoming(); + __bluetooth_pb_get_phone_log_list_number(query, + start_index, end_index, count); + break; + case TELECOM_OCH: + query = __bluetooth_pb_query_phone_log_outgoing(); + __bluetooth_pb_get_phone_log_list_number(query, + start_index, end_index, count); + break; + case TELECOM_MCH: + query = __bluetooth_pb_query_phone_log_missed(); + __bluetooth_pb_get_phone_log_list_number(query, + start_index, end_index, count); + break; + case TELECOM_CCH: + query = __bluetooth_pb_query_phone_log_combined(); + __bluetooth_pb_get_phone_log_list_number(query, + start_index, end_index, count); + break; +#ifdef TIZEN_FEATURE_BT_PBAP_SIM + case SIM_PB: + query = __bluetooth_pb_query_person(PBAP_ADDRESSBOOK_SIM); + __bluetooth_pb_get_contact_list(query, + start_index, end_index, count); + break; +#endif + default: + return; + } + + if (query) + contacts_query_destroy(query); + FN_END; +} + + diff --git a/ag-agent/bluetooth-ag-phonebook.h b/ag-agent/bluetooth-ag-phonebook.h new file mode 100644 index 0000000..bf02f6e --- /dev/null +++ b/ag-agent/bluetooth-ag-phonebook.h @@ -0,0 +1,71 @@ +/* + * bluetooth-ag-phonebook.h + * + * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Hocheol Seo + * Sangki Park + * Chanyeol Park + * Rakesh MK + * Anurag B + * + * 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. + * + */ + +#include +#include +#include +#include + +typedef enum { + TELECOM_PB = 0, + TELECOM_ICH, + TELECOM_OCH, + TELECOM_MCH, + TELECOM_CCH, +#ifdef TIZEN_FEATURE_BT_PBAP_SIM + SIM_PB, +#endif + TELECOM_NONE +} PhoneBookType; + +typedef enum { + PBAP_ADDRESSBOOK_PHONE, + PBAP_ADDRESSBOOK_SIM, +} bt_pbap_addressbook_e; + +#define SIM_ADDRESSBOOK_PREFIX "http://tizen.org/addressbook/sim" + + +PhoneBookType __bluetooth_pb_get_storage_pb_type(const char *name); + +contacts_query_h __bluetooth_pb_query_phone_log(gint *match, + gint size); + +gboolean __bluetooth_pb_get_count(PhoneBookType pb_type, + guint *count); + +void __bluetooth_pb_get_list_number( + PhoneBookType pb_type, + gint start_index, + gint end_index, + gint *count); + +void __bluetooth_pb_get_list_entries_by_name( + PhoneBookType pb_type, + gint start_index, + gint end_index, + const char *str, + gint *count); + diff --git a/hf-agent/bluetooth-hf-agent.c b/hf-agent/bluetooth-hf-agent.c index 1bf622f..90435e4 100644 --- a/hf-agent/bluetooth-hf-agent.c +++ b/hf-agent/bluetooth-hf-agent.c @@ -2895,6 +2895,24 @@ static void __bt_establish_initialization(bt_hf_agent_info_t *bt_hf_info) else ERR("BT_HF_XSAT sending failed"); + if (TIZEN_PROFILE_WEARABLE) { + /* send Bluetooth Samsung Support Feature cmd */ + ret = __bt_hf_send_and_read(bt_hf_info, BT_HF_BSSF, buf, + sizeof(BT_HF_BSSF) - 1); + + /* If we got a 'OK' reply, peer AG is samsung device. + * Otherwise, non-samsung device */ + if (ret && strstr(buf, "OK")) + bt_hf_info->is_companion_dev = TRUE; + else + bt_hf_info->is_companion_dev = FALSE; + + if (ret) + INFO("SLC completed with [%s] device", + bt_hf_info->is_companion_dev ? "SS Companion" : "Other"); + else + ERR("BT_HF_BSSF sending failed"); + } } static void __bt_hf_agent_sigterm_handler(int signo) diff --git a/hf-agent/bluetooth-hf-agent.h b/hf-agent/bluetooth-hf-agent.h index b5b51d6..1252960 100644 --- a/hf-agent/bluetooth-hf-agent.h +++ b/hf-agent/bluetooth-hf-agent.h @@ -276,6 +276,8 @@ typedef struct { gboolean is_dialing; gboolean call_active; gboolean inband_ringtone_support; + gboolean is_companion_dev; + guint ciev_call_status; guint ciev_call_setup_status; diff --git a/packaging/bluetooth-agent.spec b/packaging/bluetooth-agent.spec index a6c56a6..937288c 100644 --- a/packaging/bluetooth-agent.spec +++ b/packaging/bluetooth-agent.spec @@ -24,7 +24,7 @@ BuildRequires: pkgconfig(capi-appfw-app-manager) BuildRequires: pkgconfig(capi-system-device) %endif # This usage of profile macro does NOT conflict 4.0 configurability. -%if "%{?profile}" != "wearable" && "%{?profile}" != "ivi" +%if "%{?profile}" != "ivi" # Original: common, mobile, tv. Added: "undefined" BuildRequires: pkgconfig(contacts-service2) BuildRequires: pkgconfig(msg-service) @@ -33,8 +33,11 @@ BuildRequires: pkgconfig(email-service) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(dbus-glib-1) BuildRequires: pkgconfig(tapi) +BuildRequires: pkgconfig(capi-system-device) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(syspopup-caller) +BuildRequires: pkgconfig(capi-network-bluetooth) BuildRequires: pkgconfig(appsvc) BuildRequires: pkgconfig(capi-appfw-application) BuildRequires: pkgconfig(capi-network-connection) @@ -93,9 +96,9 @@ cp %{SOURCE1001} . export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" + #export CFLAGS="$CFLAGS -DTIZEN_FEATURE_BT_MEDIA_ENHANCE" -export CFLAGS="$CFLAGS -DTIZEN_FEATURE_BT_HFP_AG" -export CFLAGS="$CFLAGS -DTIZEN_SUPPORT_DUAL_HF" +#export CFLAGS="$CFLAGS -DTIZEN_SUPPORT_DUAL_HF" %ifarch aarch64 echo arch64 @@ -111,15 +114,15 @@ export CXXFLAGS+=" -DARCH64" export FFLAGS+=" -DARCH64" %endif -export CFLAGS+=" -fpie -DTIZEN_FEATURE_BP_PBAP_SIM -fvisibility=hidden " -export CXXFLAGS+=" -fpie -DTIZEN_FEATURE_BP_PBAP_SIM -fvisibility=hidden " +export CFLAGS+=" -fpie -DTIZEN_FEATURE_BT_PBAP_SIM -fvisibility=hidden " +export CXXFLAGS+=" -fpie -DTIZEN_FEATURE_BT_PBAP_SIM -fvisibility=hidden " export LDFLAGS+=" -Wl,--rpath=/usr/lib -Wl,--as-needed -Wl,--unresolved-symbols=ignore-in-shared-libs -pie" export CFLAGS_DEFAULT="$CFLAGS" # Build All (wearalbe/ivi/common/tv/mobile) -cmake . -DCMAKE_INSTALL_PREFIX=/usr -DTIZEN_FEATURE_BT_HFP_AG=1 +cmake . -DCMAKE_INSTALL_PREFIX=/usr make VERBOSE=1 %install -- 2.7.4