Fix NULL dereference issue and uninitialized variable issue
[platform/core/connectivity/bluetooth-agent.git] / hf-agent / bluetooth-hf-agent.c
index 9e80a01..8c2857c 100755 (executable)
@@ -40,6 +40,7 @@
 #include <bundle_internal.h>
 
 #include "bluetooth-hf-agent.h"
+#include "bluetooth-agent-profile.h"
 
 #define BT_AGENT_SYSPOPUP_MAX_ATTEMPT 3
 #define CALL_APP_ID "org.tizen.call-ui"
@@ -65,7 +66,8 @@ static char *g_obj_path;
 
 static GDBusConnection *gdbus_conn;
 static GDBusProxy *service_gproxy;
-static int owner_sig_id = -1;
+static guint interface_added_sig_id;
+static guint interface_removed_sig_id;
 int g_id = 0;
 uint16_t hf_ver;
 
@@ -218,6 +220,73 @@ static GVariant *bt_hf_agent_request_call_list(void);
 static int bt_hf_agent_send_at_cmd(GDBusMethodInvocation *context, char *atcmd);
 
 static int hf_handle_rx_at_cmd(bt_hf_agent_info_t *bt_hf_info, const char *buf);
+
+void __bt_hf_agent_print_at_buffer(char *message, const char *buf)
+{
+
+       int i = 0;
+       char s[BT_HF_DATA_BUF_SIZE] = {0, };
+       gboolean hide = FALSE;
+
+       gboolean has_clcc = FALSE;
+       gboolean has_clip = FALSE;
+       gboolean has_ccwa = FALSE;
+       char *xsat_ptr;
+
+       strncpy(s, buf, BT_HF_DATA_BUF_SIZE - 1);
+
+       has_clcc = strstr(buf, "CLCC:") ? TRUE : FALSE;
+       if (has_clcc == TRUE)
+               goto done;
+       has_clip = strstr(buf, "+CLIP:") ? TRUE : FALSE;
+       if (has_clip == TRUE)
+               goto done;
+       has_ccwa = strstr(buf, "+CCWA:") ? TRUE : FALSE;
+
+done:
+       /* +XSAT: 11,DISC */
+       xsat_ptr =  strstr(s, "11,DISC,");
+       if (xsat_ptr) {
+               xsat_ptr = xsat_ptr + 8;
+               int x = 0;
+               while (xsat_ptr[x] != '\0' && xsat_ptr[x] != '\r' && xsat_ptr[x] != '\n') {
+                       xsat_ptr[x] = 'X';
+                       x++;
+               }
+       }
+
+       /* AT+XSAT=11,Q_CT,X,XXXX */
+       xsat_ptr =  strstr(s, "11,Q_CT,");
+       if (xsat_ptr) {
+               xsat_ptr = xsat_ptr + 8;
+               int x = 0;
+               while (xsat_ptr[x] != '\0' && xsat_ptr[x] != '\r' && xsat_ptr[x] != '\n') {
+                       if (x > 1) /* ignore 0 and 1 position */
+                               xsat_ptr[x] = 'X';
+                       x++;
+               }
+       }
+
+       i = 0;
+       while (s[i] != '\0') {
+               if (s[i] == '\r' || s[i] == '\n') {
+                       s[i] = '.';
+               } else {
+                       if (s[i] == '\"')
+                               hide = hide ? FALSE : TRUE;
+                       else if ((has_clcc || has_clip || has_ccwa) && hide) {
+                               if (i % 2)
+                                       s[i] = 'X';
+                       }
+               }
+               i++;
+       }
+       if (message)
+               INFO("%s Buffer = %s, Length = %d ", message, s, strlen(s));
+       else
+               INFO("%s", s);
+}
+
 static GQuark __bt_hf_agent_error_quark(void)
 {
        DBG("");
@@ -431,7 +500,7 @@ static void __hf_agent_method(GDBusConnection *connection,
 
                g_variant_get(parameters, "(&s)", &cmd);
 
-               DBG("Going to call SendAtCmd, cmd is = [%s]\n", cmd);
+               DBG("Going to call SendAtCmd\n");
                ret = bt_hf_agent_send_at_cmd(context, cmd);
                if (ret)
                        goto fail;
@@ -785,10 +854,8 @@ gboolean __bt_hf_agent_add_queue(GDBusMethodInvocation *context, char *at,
        if (bt_hf_info.slc == FALSE)
                return FALSE;
 
-       if (pending_flag)
-               DBG("*** Add Pending queue request for = %s **** ", at);
-       else
-                DBG("Add Pending queue respnse for = %s ", at);
+       DBG("Add Pending queue. (pending_flag is %s)",
+                               pending_flag ? "TRUE" : "FALSE");
 
        bt_hf_agent_send_at_info *cmd = g_new0(bt_hf_agent_send_at_info, 1);
        cmd->id = ++g_id;
@@ -1052,7 +1119,8 @@ static int __bt_hf_agent_handle_ccwa(bt_hf_agent_info_t *bt_hf_info,
 {
        GDBusConnection *conn;
        gchar *ccwa;
-       gchar number[BT_HF_CALLER_NUM_SIZE];
+       gchar *number;
+       gchar *ptr;
        gchar *sep;
        char fmt_str[BT_HF_FMT_STR_SIZE];
        int len = strlen(buf);
@@ -1065,8 +1133,9 @@ static int __bt_hf_agent_handle_ccwa(bt_hf_agent_info_t *bt_hf_info,
 
        if ((ccwa = strstr(buf, "\r\n+CCWA"))) {
                snprintf(fmt_str, sizeof(fmt_str), "\r\n+CCWA: \"%%%ds",
-                                                                       (int)(sizeof(number) - 1));
-               if (sscanf(ccwa, fmt_str, number) == 1) {
+                                                                       BT_HF_CALLER_NUM_SIZE - 1);
+               if ((ptr = strstr(ccwa, "\"")) != NULL) {
+                       number = ptr + 1;
                        sep = strchr(number, '"');
                        sep[0] = '\0';
 
@@ -1098,6 +1167,7 @@ static GSList *__bt_hf_prepare_call_list(const char *buf)
        char *ptr = NULL;
        char *temp = NULL;
        char *sp;
+       char *stop;
        char delim_sep[] = "\r\n";
        char temp_buf[BT_HF_DATA_BUF_SIZE] = {0,};
 
@@ -1115,13 +1185,18 @@ static GSList *__bt_hf_prepare_call_list(const char *buf)
 
                call_info = g_new0(hf_call_list_info_t, 1);
 
-               sscanf(str, "+CLCC: %1d,%1d, %1d, %1d, %1d",
-                               &call_info->idx, &call_info->dir,
-                               &call_info->status, &call_info->mode,
-                               &call_info->multi_party);
-               DBG("Index = [%d], Direction = [%d], Status = [%d], Mode = [%d], Multi_party = [%d]\n",
-                               call_info->idx, call_info->dir, call_info->status,
-                               call_info->mode, call_info->multi_party);
+               /* str format : "+CLCC: %1d,%1d, %1d, %1d, %1d" */
+               if ((ptr = strchr(str, ':')) != NULL) {
+                       call_info->idx = strtol(ptr + 1, &stop, 10);
+                       call_info->dir = strtol(stop + 1, &stop, 10);
+                       call_info->status = strtol(stop + 1, &stop, 10);
+                       call_info->mode = strtol(stop + 1, &stop, 10);
+                       call_info->multi_party = strtol(stop + 1, &stop, 10);
+
+                       DBG("Index = [%d], Direction = [%d], Status = [%d], Mode = [%d], Multi_party = [%d]\n",
+                                       call_info->idx, call_info->dir, call_info->status,
+                                       call_info->mode, call_info->multi_party);
+               }
 
                ptr = strstr(str, "\"");
                if (ptr) {
@@ -1419,76 +1494,11 @@ static void __bt_hf_agent_handle_codec_select(bt_hf_agent_info_t *bt_hf_info,
                ERR("Failed to select the Codec");
 }
 
-void __bt_hf_agent_print_at_buffer(char *message, const char *buf)
-{
-
-       int i = 0;
-       char s[BT_HF_DATA_BUF_SIZE] = {0, };
-       gboolean hide = FALSE;
-
-       gboolean has_clcc = FALSE;
-       gboolean has_clip = FALSE;
-       gboolean has_ccwa = FALSE;
-       char *xsat_ptr;
-
-       strncpy(s, buf, BT_HF_DATA_BUF_SIZE - 1);
-
-       has_clcc = strstr(buf, "CLCC:") ? TRUE : FALSE;
-       if (has_clcc == TRUE)
-               goto done;
-       has_clip = strstr(buf, "+CLIP:") ? TRUE : FALSE;
-       if (has_clip == TRUE)
-               goto done;
-       has_ccwa = strstr(buf, "+CCWA:") ? TRUE : FALSE;
-
-done:
-       /* +XSAT: 11,DISC */
-       xsat_ptr =  strstr(s, "11,DISC,");
-       if (xsat_ptr) {
-               xsat_ptr = xsat_ptr + 8;
-               int x = 0;
-               while (xsat_ptr[x] != '\0' && xsat_ptr[x] != '\r' && xsat_ptr[x] != '\n') {
-                       xsat_ptr[x] = 'X';
-                       x++;
-               }
-       }
-
-       /* AT+XSAT=11,Q_CT,X,XXXX */
-       xsat_ptr =  strstr(s, "11,Q_CT,");
-       if (xsat_ptr) {
-               xsat_ptr = xsat_ptr + 8;
-               int x = 0;
-               while (xsat_ptr[x] != '\0' && xsat_ptr[x] != '\r' && xsat_ptr[x] != '\n') {
-                       if (x > 1) /* ignore 0 and 1 position */
-                               xsat_ptr[x] = 'X';
-                       x++;
-               }
-       }
-
-       i = 0;
-       while (s[i] != '\0') {
-               if (s[i] == '\r' || s[i] == '\n') {
-                       s[i] = '.';
-               } else {
-                       if (s[i] == '\"')
-                               hide = hide ? FALSE : TRUE;
-                       else if ((has_clcc || has_clip || has_ccwa) && hide) {
-                               if (i % 2)
-                                       s[i] = 'X';
-                       }
-               }
-               i++;
-       }
-       if (message)
-               INFO("%s Buffer = %s, Length = %d ", message, s, strlen(s));
-       else
-               INFO("%s", s);
-}
-
 static int __bt_hf_agent_handler_ciev(bt_hf_agent_info_t *bt_hf_info, const char *buf)
 {
-       gchar indicator[BT_HF_INDICATOR_DESCR_SIZE + 4];
+       gchar *indicator;
        gchar *sep;
+       gchar *ptr;
        gint value;
        guint index;
        char fmt_str[BT_HF_FMT_STR_SIZE];
@@ -1496,8 +1506,9 @@ static int __bt_hf_agent_handler_ciev(bt_hf_agent_info_t *bt_hf_info, const char
        DBG("++++++++ __bt_hf_agent_handler_ciev +++++++++");
 
        snprintf(fmt_str, sizeof(fmt_str), "\r\n+CIEV:%%%ds\r\n",
-                                                               (int)(sizeof(indicator) - 1));
-       if (sscanf(buf, fmt_str, indicator) == 1) {
+                                                               BT_HF_INDICATOR_DESCR_SIZE + 4 - 1);
+       if ((ptr = strchr(buf, ':')) != NULL) {
+               indicator = ptr + 1;
                sep = strchr(indicator, ',');
                sep[0] = '\0';
                sep += 1;
@@ -1556,8 +1567,12 @@ static int __bt_hf_agent_handler_bvra(bt_hf_agent_info_t *bt_hf_info, const char
 {
        DBG("+++++++++ __bt_hf_agent_handler_bvra +++++++++");
        gint value;
-        if (sscanf(buf, "\r\n+BVRA:%1d\r\n", &value) == 1)
+       gchar *ptr;
+       gchar *stop;
+       if ((ptr = strstr(buf, "BVRA:")) != NULL) {
+               value = strtol(ptr + 5, &stop, 10);
                __bt_hf_agent_handle_voice_activation(value);
+       }
 
         DBG("---------__bt_hf_agent_handler_bvra --------");
        return 0;
@@ -1566,9 +1581,13 @@ static int __bt_hf_agent_handler_bvra(bt_hf_agent_info_t *bt_hf_info, const char
 static int __bt_hf_agent_handler_bcs(bt_hf_agent_info_t *bt_hf_info, const char *buf)
 {
        guint codec_id;
+       gchar *ptr;
+       gchar *stop;
        DBG("+++++++++ __bt_hf_agent_handler_bcs +++++++++-");
-       if (sscanf(buf, "\r\n+BCS:%3d\r\n", &codec_id))
+       if ((ptr = strstr(buf, "BCS:")) != NULL) {
+               codec_id = strtol(ptr + 4, &stop, 10);
                __bt_hf_agent_handle_codec_select(bt_hf_info, codec_id);
+       }
 
        DBG("---------__bt_hf_agent_handler_bcs --------");
        return 0;
@@ -1577,9 +1596,13 @@ static int __bt_hf_agent_handler_bcs(bt_hf_agent_info_t *bt_hf_info, const char
 static int __bt_hf_agent_handler_vgs(bt_hf_agent_info_t *bt_hf_info, const char *buf)
 {
        gint value;
+       gchar *ptr;
+       gchar *stop;
        DBG("+++++++++ __bt_hf_agent_handler_vgs +++++++++");
-       if (sscanf(buf, "\r\n+VGS:%2d\r\n", &value))
+       if ((ptr = strstr(buf, "VGS:")) != NULL) {
+               value = strtol(ptr + 4, &stop, 10);
                __bt_hf_agent_handle_speaker_gain(value);
+       }
 
        DBG("---------__bt_hf_agent_handler_vgs --------");
 
@@ -1599,14 +1622,24 @@ static int __bt_hf_agent_handler_ccwa(bt_hf_agent_info_t *bt_hf_info, const char
 static int __bt_hf_agent_handler_xsat(bt_hf_agent_info_t *bt_hf_info,
                                                        const char *buf)
 {
-       gint app_id;
-       char msg[BT_HF_DATA_BUF_SIZE];
+       gint app_id = 0;
+       char *msg = NULL;
        char fmt_str[BT_HF_CMD_BUF_SIZE];
+       char *ptr = NULL;
+       char *save_ptr = NULL;
+       char *stop = NULL;
 
        DBG("+++++++++ __bt_hf_agent_handler_xsat +++++++++");
        snprintf(fmt_str, sizeof(fmt_str), "\r\n+XSAT:%%d,%%%ds\r\n",
                                                                                (int)(sizeof(msg) - 1));
-       if (sscanf(buf, fmt_str, &app_id, msg)) {
+       ptr = strstr(buf, "XSAT:");
+       if (ptr)
+               app_id = strtol(ptr + 5, &stop, 10);
+
+       if (stop)
+               msg = strtok_r(stop + 1, "\\", &save_ptr);
+
+       if (app_id > 0 && msg) {
                if (app_id == 2 && strstr(msg, "READTXPOWER")) {
                        char cmd_buf[BT_HF_CMD_BUF_SIZE * 2] = {0, };
                        char power = __bt_hf_agent_get_tx_power(bt_hf_info->remote_addr);
@@ -1963,7 +1996,7 @@ static gboolean __bt_hf_agent_data_cb(GIOChannel *chan, GIOCondition cond,
 
        if (cond & (G_IO_ERR | G_IO_HUP)) {
                ERR("ERR or HUP on RFCOMM socket");
-               INFO_C("Disconnected [HF role] [Terminated by remote dev]");
+               INFO_C("### Disconnected [HF role] [Terminated by remote dev]");
                is_hf_connected = FALSE;
                bt_hf_info->slc = FALSE;
                __bt_hf_agent_release();
@@ -2050,12 +2083,12 @@ static gboolean __bt_hf_send_only_without_queue(bt_hf_agent_info_t *bt_hf_info,
        g_io_channel_flush(io_chan, NULL);
 
        if (count > 2 && data[2] == 'D') { /* ATDXXXXX */
-               INFO("Send only buffer size =[%d] No len = %d - Send <<<<<| %s",
-                                        count, count - 6, "ATDXXXXXXX");
+               INFO("[HF AT CMD] Send only without queue <<<<<: Buffer = %s, Length = %d ",
+                                       "ATDXXXXXXX", count);
                snprintf(prev_cmd, BT_HF_CMD_BUF_SIZE, "%s", data);
        } else {
-               INFO("No queue....Send only buffer size =[%d] - Send <<<<<| %s",
-                                                               count, data);
+               __bt_hf_agent_print_at_buffer("[HF AT CMD] Send only without queue <<<<<:",
+                                       data);
        }
 
        send_flag++;
@@ -2085,10 +2118,11 @@ static gboolean __bt_hf_send_only(bt_hf_agent_info_t *bt_hf_info, gchar *data,
        g_io_channel_flush(io_chan, NULL);
 
        if (count > 2 && data[2] == 'D') /* ATDXXXXX */
-               INFO("Send only buffer size =[%d] No len = %d - Send <<<<<| %s",
-                                        count, count - 6, "ATDXXXXXXX");
+               INFO("[HF AT CMD] Send only <<<<<: Buffer = %s, Length = %d ",
+                                       "ATDXXXXXXX", count);
        else
-               INFO("Send only buffer size =[%d] - Send <<<<<| %s", count, data);
+               __bt_hf_agent_print_at_buffer("[HF AT CMD] Send only <<<<<:",
+                                       data);
 
        send_flag++;
        DBG("Ref %d(after) on Send only buffer size =[%d] - Send <<<<<| %s",
@@ -2217,11 +2251,12 @@ static GSList *__bt_hf_parse_indicator_values(gchar *values, GSList *indices)
        GSList *runner = indices;
 
        gchar *cur = values - 1;
+       gchar *stop;
        DBG("Indicator string = %s", values);
        __bt_hf_agent_print_at_buffer("Indicator values :", values);
        while (cur != NULL) {
                cur += 1;
-               sscanf(cur, "%1d", &val);
+               val = strtol(cur, &stop, 10);
                cur = strchr(cur, ',');
                ind = g_slist_nth_data(runner, 0);
                ind->value = val;
@@ -2546,6 +2581,7 @@ static gboolean __bt_establish_service_level_conn(bt_hf_agent_info_t *bt_hf_info
        gchar cmd_buf[BT_HF_CMD_BUF_SIZE] = {0};
        gboolean ret;
        char *buf_ptr;
+       char *stop;
        guint feature = BT_HF_FEATURE_EC_ANDOR_NR |
                        BT_HF_FEATURE_CALL_WAITING_AND_3WAY |
                        BT_HF_FEATURE_CLI_PRESENTATION |
@@ -2553,9 +2589,8 @@ static gboolean __bt_establish_service_level_conn(bt_hf_agent_info_t *bt_hf_info
                        BT_HF_FEATURE_REMOTE_VOLUME_CONTROL |
                        BT_HF_FEATURE_ENHANCED_CALL_STATUS;
 
-#ifdef TIZEN_PROFILE_WEARABLE
-       feature = feature | BT_HF_FEATURE_CODEC_NEGOTIATION;
-#endif
+       if (TIZEN_PROFILE_WEARABLE)
+               feature = feature | BT_HF_FEATURE_CODEC_NEGOTIATION;
 
        snprintf(cmd_buf, sizeof(cmd_buf), BT_HF_FEATURES, feature);
        ret = __bt_hf_send_and_read(bt_hf_info, cmd_buf, buf,
@@ -2567,22 +2602,25 @@ static gboolean __bt_establish_service_level_conn(bt_hf_agent_info_t *bt_hf_info
        if (buf_ptr == NULL)
                return FALSE;
 
-       if (!ret || sscanf(buf_ptr, "\r\n+BRSF:%5d", &bt_hf_info->ag_features) != 1)
+       buf_ptr = strstr(buf_ptr, "BRSF:");
+       bt_hf_info->ag_features = strtol(buf_ptr + 5, &stop, 10);
+
+
+       if (!ret || !bt_hf_info->ag_features)
                return FALSE;
        INFO("Gateway supported features are 0x%X", bt_hf_info->ag_features);
 
-#ifdef TIZEN_PROFILE_WEARABLE
-       if (bt_hf_info->ag_features & BT_AG_FEATURE_CODEC_NEGOTIATION) {
-               ret = _hf_agent_codec_setup(bt_hf_info->remote_addr, BT_HF_CODEC_ID_MSBC);
-               if (ret != BT_HF_AGENT_ERROR_NONE)
-                       ERR("Unable to set the default WBC codec");
+       if (TIZEN_PROFILE_WEARABLE) {
+               if (bt_hf_info->ag_features & BT_AG_FEATURE_CODEC_NEGOTIATION) {
+                       ret = _hf_agent_codec_setup(bt_hf_info->remote_addr, BT_HF_CODEC_ID_MSBC);
+                       if (ret != BT_HF_AGENT_ERROR_NONE)
+                               ERR("Unable to set the default WBC codec");
 
-               ret = __bt_hf_send_available_codec(bt_hf_info, 0);
-               if (!ret)
-                       return FALSE;
-       } else
-#endif
-       {
+                       ret = __bt_hf_send_available_codec(bt_hf_info, 0);
+                       if (!ret)
+                               return FALSE;
+               }
+       } else {
                /* Default codec is NB */
                ret = _hf_agent_codec_setup(bt_hf_info->remote_addr, BT_HF_CODEC_ID_CVSD);
                if (ret != BT_HF_AGENT_ERROR_NONE)
@@ -2751,7 +2789,7 @@ static gboolean __bt_agent_request_service_level_conn(gpointer data)
        remote_addr = bt_hf_info.remote_addr;
 
        INFO_SECURE("Address is : %s", remote_addr);
-       INFO_C("Connected [HF role]");
+       INFO_C("### Connected [HF role]");
 
        if (vconf_get_int(VCONFKEY_BT_DEVICE, &bt_device_state) == 0) {
                DBG("BT device state is : 0x%X", bt_device_state);
@@ -3044,9 +3082,14 @@ static void __bt_hf_agent_dbus_init(void)
                return;
        }
 
-       owner_sig_id = g_dbus_connection_signal_subscribe(conn,
-                               NULL, BT_MANAGER_INTERFACE, NULL, NULL, NULL, 0,
+       interface_added_sig_id = g_dbus_connection_signal_subscribe(conn,
+                               NULL, BT_MANAGER_INTERFACE, BT_INTERFACES_ADDED, NULL, NULL, 0,
+                               __bt_hf_agent_filter_cb, NULL, NULL);
+
+       interface_removed_sig_id = g_dbus_connection_signal_subscribe(conn,
+                               NULL, BT_MANAGER_INTERFACE, BT_INTERFACES_REMOVED, NULL, NULL, 0,
                                __bt_hf_agent_filter_cb, NULL, NULL);
+
        DBG("-");
        return;
 }
@@ -3060,9 +3103,16 @@ static void __bt_hf_agent_dbus_deinit(void)
        }
 
        if (gdbus_conn) {
-               if (owner_sig_id != -1)
+               if (interface_added_sig_id > 0)
+                       g_dbus_connection_signal_unsubscribe(gdbus_conn,
+                                               interface_added_sig_id);
+
+               if (interface_removed_sig_id > 0)
                        g_dbus_connection_signal_unsubscribe(gdbus_conn,
-                                               owner_sig_id);
+                                               interface_removed_sig_id);
+
+               interface_added_sig_id = 0;
+               interface_removed_sig_id = 0;
 
                g_object_unref(gdbus_conn);
                gdbus_conn = NULL;
@@ -3335,9 +3385,8 @@ static uint32_t __bt_hf_agent_get_hf_features(void)
                        BT_HF_FEATURE_ENHANCED_CALL_STATUS |
                        BT_HF_FEATURE_CODEC_NEGOTIATION;
 
-#ifdef TIZEN_PROFILE_WEARABLE
-       hf_features = hf_features | BT_HF_FEATURE_CODEC_NEGOTIATION;
-#endif
+       if (TIZEN_PROFILE_WEARABLE)
+               hf_features = hf_features | BT_HF_FEATURE_CODEC_NEGOTIATION;
 
        hf_ver = HFP_VERSION_1_6;
 
@@ -3349,7 +3398,7 @@ int main(void)
        struct sigaction sa;
        uint32_t hf_features;
 
-       INFO("Starting Bluetooth HF agent");
+       INFO_C("### Starting Bluetooth HF agent");
 
        hf_features = __bt_hf_agent_get_hf_features();
        bt_hf_info.feature = (uint16_t) hf_features & 0x3F;
@@ -3377,6 +3426,6 @@ int main(void)
        if (gmain_loop)
                g_main_loop_unref(gmain_loop);
 
-       INFO("Terminating Bluetooth HF agent");
+       INFO_C("### Terminating Bluetooth HF agent");
        return 0;
 }