Handle ACL Disconnect Reason
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-event-receiver.c
index 8161fdc..719681c 100644 (file)
@@ -95,7 +95,7 @@ static void __bt_hal_device_property_changed_event(GVariant *msg, const char *pa
 static void __bt_hal_dbus_device_found_properties(const char *device_path);
 static void __bt_hal_device_properties_lookup(GVariant *result, char *address);
 static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *member, const char *path);
-static void __bt_hal_send_device_acl_connection_state_event(gboolean connected, const char *address);
+static void __bt_hal_send_device_acl_connection_state_event(int status, gboolean connected, const char *address);
 static void __bt_hal_handle_input_event(GVariant *msg, const char *path);
 static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address);
 static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address);
@@ -435,7 +435,7 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
                        GVariantIter *iter = NULL;
                        g_variant_get(value, "as", &iter);
                        bt_local_le_features_t le_features;
-                        gboolean le_features_present = FALSE;
+                       gboolean le_features_present = FALSE;
 
                        if (iter == NULL)
                                continue;
@@ -475,7 +475,7 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
 
 
        if (size > 2) {
-               DBG("Send Adapter properties changed event to HAL user, Num Prop [%d] total size [%d]", ev->num_props, size);
+               DBG("Send Adapter properties changed event to HAL user, Num Prop [%d] total size [%zd]", ev->num_props, size);
                event_cb(HAL_EV_ADAPTER_PROPS_CHANGED, buf, size);
        }
 
@@ -530,7 +530,7 @@ void _bt_hal_handle_adapter_event(GVariant *msg, const char *member)
 
                g_variant_get(msg, "(siii)", &address, &link_type, &alert_type, &rssi_dbm);
                DBG("RSSI Alert: [Address %s LinkType %d] [Type %d DBM %d]",
-                               address, alert_type, rssi_dbm);
+                               address, alert_type, rssi_dbm, link_type);
 
                _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
                ev.link_type = link_type;
@@ -660,7 +660,7 @@ static gboolean __bt_hal_parse_device_properties(GVariant *item)
                        gsize size1 = 0;
                        int i = 0;
                        size1 = g_variant_get_size(val);
-                       DBG("UUID count from size  [%d]\n", size1);
+                       DBG("UUID count from size  [%zu]\n", size1);
                        int num_props_tmp = ev->num_props;
 
                        if (size1 > 0) {
@@ -703,7 +703,7 @@ static gboolean __bt_hal_parse_device_properties(GVariant *item)
        DBG("-");
 
        if (size > 1) {
-               DBG("Send Device found event to HAL user, Num Prop [%d] total size [%d]", ev->num_props, size);
+               DBG("Send Device found event to HAL user, Num Prop [%d] total size [%zd]", ev->num_props, size);
                event_cb(HAL_EV_DEVICE_FOUND, (void*) buf, size);
        }
 
@@ -906,6 +906,36 @@ static gboolean __bt_hal_parse_interface(GVariant *msg)
        return FALSE;
 }
 
+void __bt_hal_handle_gatt_char_event(GVariant *parameters, const char *signal_name)
+{
+       DBG("+");
+
+       if (signal_name == NULL)
+               return;
+
+       if (strcasecmp(signal_name, "GattValueChanged") == 0) {
+               DBG("GattValueChanged event received");
+
+               int result = 0;
+               const char *char_handle = NULL;
+               GVariant *char_value_var = NULL;
+               int len = 0;
+               char *char_value = NULL;
+
+               g_variant_get(parameters, "(i&s@ay)", &result, &char_handle, &char_value_var);
+               DBG("char handle: %s", char_handle);
+
+               len = g_variant_get_size(char_value_var);
+               if (len > 0)
+                       char_value = (char *)g_variant_get_data(char_value_var);
+
+               _bt_hal_handle_gattc_value_changed_event(result, char_handle, char_value, len);
+
+               g_variant_unref(char_value_var);
+       }
+}
+
+
 static gboolean __bt_hal_event_manager(gpointer data)
 {
        bt_hal_event_type_t bt_event = 0x00;
@@ -1011,6 +1041,9 @@ static gboolean __bt_hal_event_manager(gpointer data)
        } else if (g_strcmp0(param->interface_name, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
                DBG("Manager Event: Interface Name: BT_HAL_MEDIATRANSPORT_INTERFACE");
                __bt_hal_handle_avrcp_transport_events(param->parameters, param->signal_name, param->object_path);
+       } else if (g_strcmp0(param->interface_name, BT_HAL_GATT_CHAR_INTERFACE) == 0) {
+               DBG("Manager Event: Interface Name: BT_HAL_GATT_CHAR_INTERFACE");
+               __bt_hal_handle_gatt_char_event(param->parameters, param->signal_name);
        }
 
 
@@ -1259,6 +1292,34 @@ static int __bt_hal_register_input_subscribe_signal(GDBusConnection *conn, int s
        return 0;
 }
 
+static int __bt_hal_register_gatt_subscribe_signal(GDBusConnection *conn,
+               int subscribe)
+{
+       static int subs_gatt_id = -1;
+
+       DBG("+");
+
+       if (subscribe) {
+               if (subs_gatt_id == -1) {
+                       subs_gatt_id = g_dbus_connection_signal_subscribe(conn,
+                                       NULL, BT_HAL_GATT_CHAR_INTERFACE,
+                                       NULL, NULL, NULL, 0,
+                                       __bt_hal_manager_event_filter,
+                                       NULL, NULL);
+               }
+       } else {
+               if (subs_gatt_id == -1) {
+                       g_dbus_connection_signal_unsubscribe(conn,
+                                       subs_gatt_id);
+                       subs_gatt_id = -1;
+               }
+       }
+
+       return BT_HAL_ERROR_NONE;
+}
+
+
+
 static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type)
 {
        DBG("+");
@@ -1280,6 +1341,9 @@ static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_ty
        case BT_HAL_HEADSET_EVENT:
                 __bt_hal_register_audio_subscribe_signal(g_conn, TRUE);
                break;
+       case BT_HAL_GATT_EVENT:
+               __bt_hal_register_gatt_subscribe_signal(g_conn, TRUE);
+               break;
        default:
                INFO_C("Register Event: event_type [%d]", event_type);
                return BT_HAL_ERROR_NOT_SUPPORT;
@@ -1355,6 +1419,9 @@ static int __bt_hal_initialize_manager_receiver(void)
        if (__bt_hal_register_service_event(manager_conn,
                                BT_HAL_HEADSET_EVENT) != BT_HAL_ERROR_NONE)
                goto fail;
+       if (__bt_hal_register_service_event(manager_conn,
+                               BT_HAL_GATT_EVENT) != BT_HAL_ERROR_NONE)
+               goto fail;
        return BT_HAL_ERROR_NONE;
 fail:
        if (manager_conn) {
@@ -1729,18 +1796,18 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                ERR("result  is NULL\n");
        }
        if (size > 1) {
-               DBG("Send Device found event to HAL user, Num Prop [%d] total size [%d]", ev->num_props, size);
+               DBG("Send Device found event to HAL user, Num Prop [%d] total size [%zd]", ev->num_props, size);
                event_cb(HAL_EV_DEVICE_FOUND, (void*) buf, size);
        }
        DBG("-");
 }
 
-static void __bt_hal_send_device_acl_connection_state_event(gboolean connected, const char *address)
+static void __bt_hal_send_device_acl_connection_state_event(int status, gboolean connected, const char *address)
 {
        DBG("+");
        struct hal_ev_acl_state_changed ev;
 
-       ev.status = BT_STATUS_SUCCESS;
+       ev.status = status;
        ev.state = (connected == TRUE) ?
                HAL_ACL_STATE_CONNECTED :
                HAL_ACL_STATE_DISCONNECTED;
@@ -1754,12 +1821,12 @@ static void __bt_hal_send_device_acl_connection_state_event(gboolean connected,
        DBG("-");
 }
 
-static void __bt_hal_send_device_le_connection_state_event(gboolean connected, const char *address)
+static void __bt_hal_send_device_le_connection_state_event(int status, gboolean connected, const char *address)
 {
        DBG("+");
        struct hal_ev_le_conn_state_changed ev;
 
-       ev.status = BT_STATUS_SUCCESS;
+       ev.status = status;
        ev.state = (connected == TRUE) ?
                HAL_LE_STATE_CONNECTED :
                HAL_LE_STATE_DISCONNECTED;
@@ -1867,9 +1934,9 @@ static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *me
                DBG("Member: [%s]", member);
                ERR_C("Connected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
                if (!addr_type)
-                       __bt_hal_send_device_acl_connection_state_event(TRUE, address);
+                       __bt_hal_send_device_acl_connection_state_event(BT_STATUS_SUCCESS, TRUE, address);
                else
-                       __bt_hal_send_device_le_connection_state_event(TRUE, address);
+                       __bt_hal_send_device_le_connection_state_event(BT_STATUS_SUCCESS, TRUE, address);
                g_free(address);
        } else if (strcasecmp(member, "Disconnected") == 0) {
                unsigned char disc_reason = 0;
@@ -1882,13 +1949,14 @@ static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *me
                _bt_hal_convert_device_path_to_address(path, address);
 
                DBG("Member: [%s]", member);
+
                ERR_C("DisConnected [%s] [%s]", !addr_type ? "BREDR" : "LE", address);
-               DBG("Disconnect Reason: %d", disc_reason);
+               DBG("Disconnected Reason [%d : %s]", disc_reason, _bt_hal_convert_disc_reason_to_string(disc_reason));
                DBG("Name: %s", name);
                if (!addr_type)
-                       __bt_hal_send_device_acl_connection_state_event(FALSE, address);
+                       __bt_hal_send_device_acl_connection_state_event(_bt_hal_convert_disc_reason_to_status(disc_reason), FALSE, address);
                else
-                       __bt_hal_send_device_le_connection_state_event(FALSE, address);
+                       __bt_hal_send_device_le_connection_state_event(_bt_hal_convert_disc_reason_to_status(disc_reason), FALSE, address);
                g_free(address);
        } else if (strcasecmp(member, "ProfileStateChanged") == 0) {
                int state = 0;
@@ -2016,7 +2084,7 @@ static void __bt_hal_handle_adv_report(GVariant *msg, const char *path)
        memcpy(ev->adv_data, buffer, data_len);
        size += data_len;
 
-       DBG("Send le scan result event to HAL, size: [%d]", size);
+       DBG("Send le scan result event to HAL, size: [%zd]", size);
        gatt_event_cb(HAL_EV_GATT_CLIENT_SCAN_RESULT, buf, size);
        g_variant_unref(value);
 }
@@ -2116,7 +2184,7 @@ static void __bt_avrcp_control_parse_properties(struct hal_ev_track_changed *ev,
                        long int val;
 
                        val = g_variant_get_uint32(value);
-                       DBG("Value : %d", val);
+                       DBG("Value : %li", val);
                        ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_PLAYING_TIME;
                        snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
                        i++;
@@ -2124,7 +2192,7 @@ static void __bt_avrcp_control_parse_properties(struct hal_ev_track_changed *ev,
                        long int val;
 
                        val = g_variant_get_uint32(value);
-                       DBG("Value : %d", val);
+                       DBG("Value : %li", val);
                        ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_NUM_TRACKS;
                        snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
                        i++;
@@ -2132,7 +2200,7 @@ static void __bt_avrcp_control_parse_properties(struct hal_ev_track_changed *ev,
                        long int val;
 
                        val = g_variant_get_uint32(value);
-                       DBG("Value : %d", val);
+                       DBG("Value : %li", val);
                        ev->attr[i].attr_id = HAL_MEDIA_ATTR_ID_TRACK_NUM;
                        snprintf((char*)ev->attr[i].text, HAL_MAX_ATTR_STR_LEN, "%ld", val);
                        i++;