Use secure atcmd on log to protect private information.
[platform/core/connectivity/bluetooth-agent.git] / ag-agent / bluetooth-ag-agent.c
old mode 100755 (executable)
new mode 100644 (file)
index 7bfdb17..00cb6c2
@@ -29,6 +29,7 @@
 #include <bundle_internal.h>
 #include "bluetooth-ag-agent.h"
 #include "bluetooth-ag-handler.h"
+#include "bluetooth-agent-profile.h"
 
 #include <TapiUtility.h>
 #include <ITapiSim.h>
@@ -43,8 +44,9 @@
 
 static GMainLoop *gmain_loop = NULL;
 static GDBusProxy *service_gproxy;
-static int owner_sig_id = -1;
-static int name_owner_sig_id = -1;
+static guint interface_added_sig_id = 0;
+static guint interface_removed_sig_id = 0;
+static guint name_owner_sig_id = 0;
 GDBusConnection *ag_dbus_conn = NULL;
 gchar *remote_dev_path = NULL;
 gboolean wbs_en;
@@ -63,8 +65,8 @@ static guint hf_bluez_id;
 static guint hs_bluez_id;
 static guint app_id;
 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
-static int media_sig_id = -1;
-static int media_state_sig_id = -1;
+static guint media_sig_id = 0;
+static guint media_state_sig_id = 0;
 static bt_ag_media_transport_state_t transport_state;
 #endif
 
@@ -74,10 +76,7 @@ static bt_ag_media_transport_state_t transport_state;
 #define A2DP_SINK_UUID "0000110b-0000-1000-8000-00805f9b34fb"
 #endif
 #define DEFAULT_ADAPTER_OBJECT_PATH "/org/bluez/hci0"
-
-#ifdef TIZEN_FEATURE_BT_LUNAR_DEVICE
 #define VCONF_KEY_BT_LUNAR_ENABLED "db/wms/bt_loop_device_hfp_connected"
-#endif
 
 #if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG)
 #define CALL_APP_ID "org.tizen.call-ui"
@@ -555,7 +554,6 @@ static gboolean __bt_get_outgoing_call_condition(int *condition)
 #endif
 }
 
-#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_TELEPHONY_ENABLED)
 static gboolean  __bt_ag_agent_launch_call_app(const char *number)
 {
        FN_START;
@@ -581,7 +579,6 @@ static gboolean  __bt_ag_agent_launch_call_app(const char *number)
        FN_END;
        return TRUE;
 }
-#endif
 
 static void *__bt_ag_agent_launch_call_req(void *arg)
 {
@@ -599,14 +596,13 @@ static gboolean __bt_ag_agent_make_call(const char *number)
 {
        FN_START;
 
-#if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG)
-       FN_END;
-       return __bt_ag_agent_launch_call_app(number);
-#else
        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);
+
        if (call_launch_requested == TRUE) {
                DBG("Launch request is in progress");
                return TRUE;
@@ -634,7 +630,6 @@ static gboolean __bt_ag_agent_make_call(const char *number)
 
        FN_END;
        return TRUE;
-#endif
 }
 
 static gboolean __bt_ag_agent_make_video_call(const char *mo_number)
@@ -893,7 +888,7 @@ bt_hfp_agent_error_t _bt_ag_agent_send_dtmf(const gchar *dtmf,
 
        if (dtmf == NULL || path == NULL || sender == NULL) {
                ERR("Invalid Argument");
-               return FALSE;
+               return BT_HFP_AGENT_ERROR_INVALID_PARAM;
        }
 
        DBG("Dtmf = %s", dtmf);
@@ -1636,16 +1631,16 @@ 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 = g_new0(struct ag_codec, 1);
+       struct ag_codec *data = NULL;;
 
-#ifdef TIZEN_FEATURE_BT_KIRAN_DEVICE
-       codec = BT_CVSD_CODEC_ID;
-#else
-       if (hs->codec_info.remote_codecs & BT_MSBC_CODEC_MASK)
-               codec = BT_MSBC_CODEC_ID;
-       else
+       if (TIZEN_MODEL_NAME_TM1) {
                codec = BT_CVSD_CODEC_ID;
-#endif
+       } else {
+               if (hs->codec_info.remote_codecs & BT_MSBC_CODEC_MASK)
+                       codec = BT_MSBC_CODEC_ID;
+               else
+                       codec = BT_CVSD_CODEC_ID;
+       }
 
        if (wbs_opts.wbs_enable == FALSE)
                codec = BT_CVSD_CODEC_ID;
@@ -1663,6 +1658,10 @@ static bt_hfp_agent_error_t __bt_hfp_send_bcs_command(bt_ag_info_t *hs,
        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");
 
@@ -1984,6 +1983,9 @@ static void __bt_ag_close_sco(bt_ag_info_t *hs)
 
        if (hs->sco_id)
                __bt_ag_agent_remove_watch(&hs->sco_id);
+
+       if (hs->sco_incoming_id)
+               __bt_ag_agent_remove_watch(&hs->sco_incoming_id);
 }
 
 static gboolean __bt_ag_sco_server_conn_cb(GIOChannel *chan,
@@ -2000,6 +2002,9 @@ static gboolean __bt_ag_sco_server_conn_cb(GIOChannel *chan,
                if (ag_info->sco_id)
                        __bt_ag_agent_remove_watch(&ag_info->sco_id);
 
+               if (ag_info->sco_incoming_id)
+                       __bt_ag_agent_remove_watch(&ag_info->sco_incoming_id);
+
                if (ag_info->watch_id)
                        _bt_ag_set_headset_state(ag_info, HEADSET_STATE_CONNECTED);
                return FALSE;
@@ -2061,7 +2066,7 @@ static gboolean __bt_ag_sco_server_cb(GIOChannel *chan,
        }
 
        ag_info->sco = sco_io;
-       ag_info->sco_id = g_io_add_watch(sco_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+       ag_info->sco_incoming_id = g_io_add_watch(sco_io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
                                        __bt_ag_sco_server_conn_cb, ag_info);
 
        if (remote_dev_path)
@@ -2359,7 +2364,7 @@ static struct event at_event_callbacks[] = {
 int num_of_secure_command = 4;
 static const char* secure_command[] = {"CLCC", "CLIP", "CPBR", "CCWA"};
 
-void __bt_ag_agent_print_at_buffer(char *message, const char *buf)
+static void __bt_ag_agent_print_at_buffer(char *message, const char *buf)
 {
 
        int i = 0;
@@ -2550,6 +2555,7 @@ static gboolean __bt_ag_event_handler(GIOChannel *channel,
        size_t available_buffer;
        int fd;
        bt_ag_info_t *bt_ag_info = (bt_ag_info_t *)user_data;
+       int err_return = 0;
 
 
        if (cond & G_IO_NVAL)
@@ -2577,7 +2583,7 @@ static gboolean __bt_ag_event_handler(GIOChannel *channel,
                goto failed;
        }
 
-       memcpy(&slconn->buffer[slconn->start], event_buf, len);
+       memcpy(&slconn->buffer[slconn->start + slconn->length], event_buf, len);
        slconn->length += len;
 
        slconn->buffer[slconn->start + slconn->length] = '\0';
@@ -2588,8 +2594,10 @@ static gboolean __bt_ag_event_handler(GIOChannel *channel,
                off_t cmd_len;
 
                get_cr = strchr(&slconn->buffer[slconn->start], '\r');
-               if (!get_cr)
+               if (!get_cr) {
+                       ERR("Broken AT command received, break");
                        break;
+               }
 
                cmd_len = 1 + (off_t) get_cr -
                        (off_t) &slconn->buffer[slconn->start];
@@ -2604,22 +2612,31 @@ static gboolean __bt_ag_event_handler(GIOChannel *channel,
                        err = 0;
                }
 
-               if (err == -EINVAL) {
-                       ERR("Unrecognized command: %s",
-                               &slconn->buffer[slconn->start]);
-                       err = _bt_ag_send_response(bt_ag_info,
-                                       HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
-                       if (err < 0)
-                               goto failed;
-               } else if (err < 0)
+               if (err < 0) {
+                       switch (err) {
+                       case -EINVAL:
+                               err_return = HFP_STATE_MNGR_ERR_NOT_SUPPORTED;
+                               break;
+                       case -EACCES:
+                               err_return = HFP_STATE_MNGR_ERR_NOT_ALLOWED;
+                               break;
+                       default:
+                               err_return = HFP_STATE_MNGR_ERR_NOT_SUPPORTED;
+                               break;
+                       }
                        ERR("Error handling command %s: %s (%d)",
                                                &slconn->buffer[slconn->start],
                                                strerror(-err), -err);
+                       err = _bt_ag_send_response(bt_ag_info,
+                                       err_return);
+                       if (err < 0)
+                               goto failed;
+               }
 
                slconn->start += cmd_len;
                slconn->length -= cmd_len;
 
-               if (!slconn->length)
+               if (slconn->length <= 0)
                        slconn->start = 0;
        }
        return TRUE;
@@ -2830,7 +2847,6 @@ static gboolean __bt_ag_agent_connection_release(bt_ag_info_t *hs)
        if (hs->sco) {
                __bt_ag_close_sco(hs);
                _bt_ag_set_headset_state(hs, HEADSET_STATE_CONNECTED);
-               hs->sco = NULL;
        }
        __bt_ag_agent_remove_watch(&hs->watch_id);
 
@@ -3124,6 +3140,9 @@ static void __bt_ag_agent_method(GDBusConnection *connection,
 
                        g_free(codec);
                        g_free(nrec);
+               } else {
+                       ret = BT_HFP_AGENT_ERROR_NOT_CONNECTED;
+                       goto fail;
                }
        } else if (g_strcmp0(method_name, "Disconnect") == 0) {
                char hdset_address[18] = { 0, };
@@ -3750,7 +3769,6 @@ static void __bt_ag_agent_network_signal_status_cb(keynode_t *node)
        _bt_hfp_set_property_value("SignalBarsChanged", signal_bar);
 }
 
-#ifdef TIZEN_FEATURE_BT_LUNAR_DEVICE
 static void __bt_ag_agent_lunar_connection_status_cb(keynode_t *node)
 {
        gboolean status = vconf_keynode_get_bool(node);
@@ -3764,7 +3782,6 @@ static void __bt_ag_agent_lunar_connection_status_cb(keynode_t *node)
                }
        }
 }
-#endif
 
 static void __bt_ag_agent_network_register_status_cb(keynode_t *node)
 {
@@ -3823,13 +3840,12 @@ static void __bt_ag_agent_subscribe_vconf_updates(void)
        if (0 != ret)
                ERR("Subsrciption to network failed err =  [%d]\n", ret);
 
-#ifdef TIZEN_FEATURE_BT_LUNAR_DEVICE
-       ret = vconf_notify_key_changed(VCONF_KEY_BT_LUNAR_ENABLED,
-                       (void *)__bt_ag_agent_lunar_connection_status_cb, NULL);
-       if (0 != ret)
-               ERR("Subsrciption to lunar connection failed err =  [%d]\n", ret);
-
-#endif
+       if (TIZEN_PROFILE_WEARABLE) {
+               ret = vconf_notify_key_changed(VCONF_KEY_BT_LUNAR_ENABLED,
+                               (void *)__bt_ag_agent_lunar_connection_status_cb, NULL);
+               if (0 != ret)
+                       ERR("Subsrciption to lunar connection failed err =  [%d]\n", ret);
+       }
 }
 
 static void __bt_ag_agent_release_vconf_updates(void)
@@ -4086,23 +4102,32 @@ static void __bt_ag_agent_dbus_deinit(void)
        if (ag_dbus_conn) {
                __bt_ag_unregister_profile_methods();
 
-               if (owner_sig_id != -1)
+               if (interface_added_sig_id)
+                       g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
+                                               interface_added_sig_id);
+
+               if (interface_removed_sig_id)
                        g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
-                                               owner_sig_id);
+                                               interface_removed_sig_id);
 
-               if (name_owner_sig_id != -1)
+               if (name_owner_sig_id)
                        g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
                                                name_owner_sig_id);
 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
-               if (media_sig_id != -1)
+               if (media_sig_id)
                        g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
                                                media_sig_id);
+               media_sig_id = 0;
 
-               if (media_state_sig_id != -1)
+               if (media_state_sig_id)
                        g_dbus_connection_signal_unsubscribe(ag_dbus_conn,
                                                media_state_sig_id);
+               media_state_sig_id = 0;
 #endif
-               name_owner_sig_id = -1;
+
+               interface_added_sig_id = 0;
+               interface_removed_sig_id = 0;
+               name_owner_sig_id = 0;
                g_free(sco_owner);
                sco_owner = NULL;
 
@@ -4267,7 +4292,6 @@ static void __bt_ag_agent_media_filter_cb(GDBusConnection *connection,
                                }
                        }
                        g_variant_iter_free(iter);
-                       g_variant_unref(dict_param);
                }
        } else if (strcasecmp(signal_name, "ProfileStateChanged") == 0) {
                char *profile_uuid = NULL;
@@ -4314,9 +4338,16 @@ static void __bt_ag_agent_dbus_init(void)
                        HSP_AG_UUID, "Headset Audio Gateway");
        }
 
-       owner_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
-                               NULL, BT_MANAGER_INTERFACE, NULL, NULL, NULL, 0,
+       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);
+
+       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);
+
 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
        media_sig_id = g_dbus_connection_signal_subscribe(ag_dbus_conn,
                                NULL, BT_PROPERTIES_INTERFACE, NULL, NULL,
@@ -4337,25 +4368,36 @@ static void __bt_ag_agent_dbus_init(void)
 static uint32_t __bt_ag_agent_get_ag_features(void)
 {
 
-       uint32_t ag_features = BT_AG_FEATURE_EC_AND_NR |
+       uint32_t ag_features;
+
+       if (TIZEN_MODEL_NAME_TM1) {
+               ag_features = BT_AG_FEATURE_EC_AND_NR |
+                               BT_AG_FEATURE_REJECT_CALL |
+                               BT_AG_FEATURE_ENHANCED_CALL_STATUS |
+                               BT_AG_FEATURE_THREE_WAY_CALL |
+                               BT_AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
+       } else {
+               ag_features = BT_AG_FEATURE_EC_AND_NR |
                                BT_AG_FEATURE_REJECT_CALL |
                                BT_AG_FEATURE_ENHANCED_CALL_STATUS |
                                BT_AG_FEATURE_THREE_WAY_CALL |
-#ifndef TIZEN_FEATURE_BT_KIRAN_DEVICE
                                BT_AG_FEATURE_VOICE_RECOGNITION |
-#endif
                                BT_AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
+       }
 
        wbs_en = TRUE;
 #if defined(TIZEN_FEATURE_BT_HFP_AG)
-       hfp_ver = HFP_VERSION_1_6;
+       hfp_ver = HFP_VERSION_1_7;
 #else
        hfp_ver = HFP_VERSION_1_5;
 #endif
        hsp_ver = HSP_VERSION_1_2;
 
-       if (hfp_ver == HFP_VERSION_1_6)
+       if (hfp_ver > HFP_VERSION_1_5)
                ag_features |= BT_AG_FEATURE_CODEC_NEGOTIATION;
+       if (hfp_ver == HFP_VERSION_1_7)
+               ag_features |= BT_AG_FEATURE_ESCO_S4_T2_SUPPORT;
+
        return ag_features;
 }
 
@@ -4383,7 +4425,7 @@ int main(void)
        int i;
        uint32_t ag_features;
        struct sigaction sa;
-       pthread_t thread_id;
+       pthread_t thread_id = 0;
 
        INFO_C("### Starting Bluetooth AG agent");
 
@@ -4391,7 +4433,7 @@ int main(void)
 
        ag.sdp_features = (uint16_t) ag_features & 0x1F;
 
-       if (hfp_ver == HFP_VERSION_1_6 && wbs_en == TRUE)
+       if (hfp_ver >= HFP_VERSION_1_6 && wbs_en == TRUE)
                ag.sdp_features |= BT_AG_FEATURE_SDP_WIDEBAND_SPEECH;
 
        memset(&sa, 0, sizeof(sa));