Handle ACL Disconnect Reason
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-event-receiver.c
index db0f47d..719681c 100644 (file)
@@ -38,6 +38,7 @@
 #include "bt-hal-agent.h"
 #include "bt-hal-adapter-le.h"
 #include "bt-hal-gatt-server.h"
+#include "bt-hal-gatt-client.h"
 
 #define BASELEN_PROP_CHANGED (sizeof(struct hal_ev_adapter_props_changed) \
                + sizeof(struct hal_property))
@@ -59,15 +60,15 @@ static handle_stack_msg gatt_event_cb = NULL;
 static guint event_id;
 
 /*State Management sepration Control for Adapter and LE */
-static gboolean is_adapter_activating=FALSE;
-static gboolean is_le_activating=FALSE;
+static gboolean is_adapter_activating = FALSE;
+static gboolean is_le_activating = FALSE;
 
 typedef struct {
-       gchar* sender_name;
-       gchar* object_path;
-      gchar* interface_name;
-       gchar* signal_name;
-       GVariant *parameters;
+       gchar* sender_name;
+       gchar* object_path;
+       gchar* interface_name;
+       gchar* signal_name;
+       GVariant *parameters;
 } bt_hal_main_event_data_t;
 
 /* Forward declarations */
@@ -93,17 +94,18 @@ static gboolean __bt_hal_discovery_finished_cb(gpointer user_data);
 static void __bt_hal_device_property_changed_event(GVariant *msg, const char *path);
 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_handle_device_specific_events(GVariant *msg, const char *member, const char *path);
+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);
 static void __bt_hal_send_avrcp_ctrl_connection_state_event(gboolean connected, const char *address);
 static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member, const char *path);
+static void __bt_hal_handle_avrcp_transport_events(GVariant *msg, const char *member, const char *path);
 
 static void __bt_hal_send_device_trust_state_event(gboolean is_trusted, const char *address);
 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn, int subscribe);
-static void __bt_hal_handle_headset_events(GVariant *msg, const char *member,const char *path);
+static void __bt_hal_handle_headset_events(GVariant *msg, const char *member, const char *path);
 static void __bt_hal_send_hf_audio_connection_state_event(gboolean connected, const char *address);
 static void __bt_hal_send_hf_connection_state_event(gboolean connected, const char *address);
 static void __bt_hal_send_device_trusted_profile_changed_event(uint32_t trust_val, const char *address);
@@ -125,13 +127,13 @@ static int __bt_hal_parse_event(GVariant *msg)
 {
        GVariantIter iter;
        GVariant *child;
-       char *interface_name= NULL;
+       char *interface_name = NULL;
        GVariant *inner_iter = NULL;
 
        g_variant_iter_init(&iter, msg);
 
        while ((child = g_variant_iter_next_value(&iter))) {
-               g_variant_get(child,"{&s@a{sv}}", &interface_name, &inner_iter);
+               g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
                if (g_strcmp0(interface_name,
                                        BT_HAL_DEVICE_INTERFACE) == 0) {
                        DBG("__bt_hal_parse_event: Interface: BT_HAL_DEVICE_INTERFACE");
@@ -188,7 +190,7 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
        GDBusProxy *adapter_proxy;
        GError *err = NULL;
        char *key = NULL;
-       g_variant_iter_init (&value_iter, msg);
+       g_variant_iter_init(&value_iter, msg);
 
        /* Buffer and propety count management */
        uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
@@ -202,13 +204,13 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
        unsigned int scan_mode = BT_SCAN_MODE_NONE;
        unsigned int disc_timeout;
        const gchar *version;
-       const gboolean ipsp_initialized;
+       gboolean ipsp_initialized;
        gboolean powered;
        gboolean pairable;
        unsigned int pairable_timeout;
        gboolean scan_mode_property_update = FALSE;
        gboolean is_discovering;
-        gboolean is_le_discovering;
+       gboolean is_le_discovering;
 
        memset(buf, 0, sizeof(buf));
        size = sizeof(*ev);
@@ -218,7 +220,7 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
        DBG("+");
 
        while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
-               if(!g_strcmp0(key, "Address")) {
+               if (!g_strcmp0(key, "Address")) {
                        uint8_t bdaddr[6];
 
                        address = g_variant_get_string(value, NULL);
@@ -233,7 +235,6 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
                        size += __bt_insert_hal_properties(buf + size,
                                        HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
                        ev->num_props++;
-                       g_free(name);
                } else if (!g_strcmp0(key, "Class")) {
                        cod = g_variant_get_uint32(value);
                        DBG("##Class [%d]", cod);
@@ -274,7 +275,6 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
                        size += __bt_insert_hal_properties(buf + size,
                                        HAL_PROP_ADAPTER_NAME, strlen(name) + 1, name);
                        ev->num_props++;
-                       g_free(name);
                } else if (!g_strcmp0(key, "Powered")) {
                        powered = g_variant_get_boolean(value);
                        DBG("##Powered = %d", powered);
@@ -293,7 +293,7 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
                                _bt_hal_destroy_adapter_agent();
                        } else {
                                DBG("###### Adapter Powered Up ######");
-                               if(_bt_hal_get_adapter_request_state()) {
+                               if (_bt_hal_get_adapter_request_state()) {
                                        DBG("Sending STATE CHANGE EVENT for Adapter... ");
                                        _bt_hal_set_adapter_request_state(FALSE);
                                        struct hal_ev_adapter_state_changed ev;
@@ -301,7 +301,7 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
                                        event_cb(HAL_EV_ADAPTER_STATE_CHANGED, &ev, sizeof(ev));
                                }
 #ifdef TIZEN_BT_HAL
-                               if(_bt_hal_get_le_request_state()) {
+                               if (_bt_hal_get_le_request_state()) {
                                        DBG("Sending STATE CHANGE EVENT for LE... ");
                                        _bt_hal_set_le_request_state(FALSE);
                                        struct hal_ev_le_state_changed ev;
@@ -323,7 +323,7 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
                        char **uuid_value;
                        int uuid_count = 0;
                        gsize size1 = 0;
-                       int i =0;
+                       int i = 0;
                        size1 = g_variant_get_size(value);
                        int num_props_tmp = ev->num_props;
                        if (size1 > 0) {
@@ -434,21 +434,33 @@ static void __bt_hal_adapter_property_changed_event(GVariant *msg)
                        char *val = NULL;
                        GVariantIter *iter = NULL;
                        g_variant_get(value, "as", &iter);
+                       bt_local_le_features_t le_features;
+                       gboolean le_features_present = FALSE;
 
                        if (iter == NULL)
                                continue;
 
+                       memset(&le_features, 0x00, sizeof(le_features));
+
                        while (g_variant_iter_next(iter, "&s", &name) &&
-                               g_variant_iter_next(iter, "&s", &value)) {
-                               DBG("name = %s, Value = %s", name, value);
-                               g_variant_iter_loop(iter, "s", &val);
-                               if (FALSE == _bt_hal_update_le_feature_support(name, value))
-                                       ERR("Failed to update LE feature (name = %s, value = %s)", name, value);
+                                       g_variant_iter_next(iter, "&s", &val)) {
+                               DBG("name = %s, Value = %s", name, val);
+                               if (FALSE == _bt_hal_update_le_feature_support(name, val, &le_features))
+                                       ERR("Failed to update LE feature (name = %s, value = %s)", name, val);
+                               else
+                                       le_features_present = TRUE;
                        }
 
                        g_variant_iter_free(iter);
+                       if (le_features_present) {
+                               size += __bt_insert_hal_properties(buf + size,
+                                               HAL_PROP_ADAPTER_LOCAL_LE_FEAT, sizeof(le_features), &le_features);
+                               ev->num_props++;
+                       } else {
+                               DBG("le supported features values are NOT provided by Stack");
+                       }
                } else if (!g_strcmp0(key, "IpspInitStateChanged")) {
-                       g_variant_get(value, "b" ,&ipsp_initialized);
+                       g_variant_get(value, "b" , &ipsp_initialized);
                        DBG("##IPSP Initialized = %d", ipsp_initialized);
                } else {
                        ERR("Unhandled Property:[%s]", key);
@@ -463,10 +475,10 @@ 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);
        }
-       g_variant_unref(value);
+
        DBG("-");
 }
 
@@ -518,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;
@@ -592,8 +604,8 @@ static gboolean __bt_hal_parse_device_properties(GVariant *item)
                                        sizeof(bdaddr), bdaddr);
 
                        ev->num_props++;
-                       DBG("Device address [%s] property Num [%d]",address, ev->num_props);
-
+                       DBG("Device address [%s] property Num [%d]", address, ev->num_props);
+                       g_free(address);
                } else if (strcasecmp(key, "Class") == 0) {
                        unsigned int class = g_variant_get_uint32(val);
                        size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CLASS,
@@ -602,12 +614,15 @@ static gboolean __bt_hal_parse_device_properties(GVariant *item)
                        DBG("Device class [%d] Property num [%d]", class, ev->num_props);
                } else if (strcasecmp(key, "name") == 0) {
                        char *name = g_variant_dup_string(val, &len);
-                       size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
-                                       strlen(name) + 1, name);
-                       ev->num_props++;
-                       DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
+                       if (name) {
+                               size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
+                                               strlen(name) + 1, name);
+                               ev->num_props++;
+                               DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
+                       }
+                       g_free(name);
                } else if (strcasecmp(key, "Connected") == 0) {
-                       unsigned int connected = g_variant_get_uint32(val);
+                       unsigned int connected = g_variant_get_byte(val);
 
                        size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
                                        sizeof(unsigned int), &connected);
@@ -643,9 +658,9 @@ static gboolean __bt_hal_parse_device_properties(GVariant *item)
                        char **uuid_value;
                        int uuid_count = 0;
                        gsize size1 = 0;
-                       int i =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) {
@@ -677,9 +692,9 @@ static gboolean __bt_hal_parse_device_properties(GVariant *item)
                                g_free(uuid_value);
                        }
 
-               } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
+               } else if (strcasecmp(key, "LegacyManufacturerDataLen") == 0) {
                        /* TODO: To be handled later*/
-               } else if (strcasecmp(key, "ManufacturerData") == 0) {
+               } else if (strcasecmp(key, "LegacyManufacturerData") == 0) {
                        /* TODO: To be handled later*/
                } else {
                        ERR("Unhandled Property:[%s]", key);
@@ -688,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);
        }
 
@@ -725,8 +740,8 @@ static void __bt_hal_handle_avrcp_tg_events(GVariant *msg, const char *path)
                        DBG("connected: %d", connected);
                        DBG("address: %s", address);
 
-                       /* Prepare to send AVRCP Target connection state event */
-                       memset(&ev, 0, sizeof(ev));
+                       /* Prepare to send AVRCP Target connection state event */
+                       memset(&ev, 0, sizeof(ev));
                        _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
                        ev.state = state;
                        if (!avrcp_tg_event_cb)
@@ -747,8 +762,17 @@ static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *ob
 {
        char *interface_name = NULL;
        GVariant *val = NULL;
+       DBG("+");
 
-       g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val,NULL);
+       g_variant_get(msg, "(&s@a{sv}@as)", &interface_name, &val, NULL);
+
+       if (!interface_name) {
+               DBG("Failed to get interface name");
+
+               if (val)
+                       g_variant_unref(val);
+               return;
+       }
 
        if (strcasecmp(interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
                DBG("Event: Property Changed: Interface: BT_HAL_ADAPTER_INTERFACE");
@@ -766,6 +790,9 @@ static void __bt_hal_handle_property_changed_event(GVariant *msg, const char *ob
        } else if (strcasecmp(interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
                DBG("Event: Property Changed: Interface: BT_HAL_PLAYER_CONTROL_INTERFACE");
                __bt_hal_handle_avrcp_ctrl_events(val, NULL, object_path);
+       } else if (strcasecmp(interface_name, BT_HAL_MEDIATRANSPORT_INTERFACE) == 0) {
+               DBG("Event: Property Changed: Interface: BT_HAL_MEDIATRANSPORT_INTERFACE");
+               __bt_hal_handle_avrcp_transport_events(val, NULL, object_path);
        } else if (strcasecmp(interface_name, BT_HAL_NETWORK_CLIENT_INTERFACE) == 0) {
                DBG("Event: Property Changed: Interface: BT_HAL_NETWORK_CLIENT_INTERFACE");
                /* TODO: Handle event */
@@ -817,8 +844,8 @@ static void __bt_hal_handle_input_event(GVariant *msg, const char *path)
        GVariant *child = NULL, *val = NULL;
 
        DBG("+");
-       g_variant_iter_init (&value_iter, msg);
-       while ((child = g_variant_iter_next_value (&value_iter))) {
+       g_variant_iter_init(&value_iter, msg);
+       while ((child = g_variant_iter_next_value(&value_iter))) {
                g_variant_get(child, "{sv}", &property, &val);
 
                if (property == NULL)
@@ -847,14 +874,14 @@ static gboolean __bt_hal_parse_interface(GVariant *msg)
        GVariant *optional_param;
        GVariantIter iter;
        GVariant *child;
-       char *interface_name= NULL;
+       char *interface_name = NULL;
        GVariant *inner_iter = NULL;
        g_variant_get(msg, "(&o@a{sa{sv}})",
                        &path, &optional_param);
        g_variant_iter_init(&iter, optional_param);
 
        while ((child = g_variant_iter_next_value(&iter))) {
-               g_variant_get(child,"{&s@a{sv}}", &interface_name, &inner_iter);
+               g_variant_get(child, "{&s@a{sv}}", &interface_name, &inner_iter);
                if (g_strcmp0(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
                        DBG("Found a device: %s", path);
                        if (__bt_hal_parse_device_properties(inner_iter) == FALSE) {
@@ -879,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;
@@ -893,6 +950,11 @@ static gboolean __bt_hal_event_manager(gpointer data)
 
                g_variant_get(param->parameters, "(&o@a{sa{sv}})", &obj_path, &value);
 
+               if (obj_path == NULL) {
+                       DBG("obj_path is NULL");
+                       return FALSE;
+               }
+
                if (strcasecmp(obj_path, BT_HAL_BLUEZ_HCI_PATH) == 0) {
                        /* TODO: Handle adapter added */
                        DBG("Manager Event: Signal Name: InterfiacesAdded: Adapter added in bluetoothd: path [hci0]");
@@ -950,6 +1012,7 @@ static gboolean __bt_hal_event_manager(gpointer data)
                g_free(current);
 
        } else if (g_strcmp0(param->interface_name, BT_HAL_PROPERTIES_INTERFACE) == 0) {
+               DBG("Manager Event: Interface Name: BT_HAL_PROPERTIES_INTERFACE");
                __bt_hal_handle_property_changed_event(param->parameters, param->object_path);
        } else if (g_strcmp0(param->interface_name, BT_HAL_ADAPTER_INTERFACE) == 0) {
                DBG("Manager Event: Interface Name: BT_HAL_ADAPTER_INTERFACE");
@@ -973,9 +1036,16 @@ static gboolean __bt_hal_event_manager(gpointer data)
                DBG("Manager Event: Interface Name:BT_HAL_DEVICE_INTERFACE");
                __bt_hal_handle_device_specific_events(param->parameters, param->signal_name, param->object_path);
        } else if (g_strcmp0(param->interface_name, BT_HAL_PLAYER_CONTROL_INTERFACE) == 0) {
-                DBG("Manager Event: Interface Name: BT_HAL_PLAYER_CONTROL_INTERFACE");
-                __bt_hal_handle_avrcp_ctrl_events(param->parameters, param->signal_name, param->object_path);
-        }
+               DBG("Manager Event: Interface Name: BT_HAL_PLAYER_CONTROL_INTERFACE");
+               __bt_hal_handle_avrcp_ctrl_events(param->parameters, param->signal_name, param->object_path);
+       } 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);
+       }
+
 
        /* Free data */
        g_free(param->sender_name);
@@ -988,12 +1058,12 @@ static gboolean __bt_hal_event_manager(gpointer data)
 }
 
 static  void __bt_hal_manager_event_filter(GDBusConnection *connection,
-                const gchar *sender_name,
-                const gchar *object_path,
-                const gchar *interface_name,
-                const gchar *signal_name,
-                GVariant *parameters,
-                gpointer user_data)
+               const gchar *sender_name,
+               const gchar *object_path,
+               const gchar *interface_name,
+               const gchar *signal_name,
+               GVariant *parameters,
+               gpointer user_data)
 {
        if (signal_name == NULL)
                return;
@@ -1009,7 +1079,7 @@ static  void __bt_hal_manager_event_filter(GDBusConnection *connection,
        return;
 }
 
-static void __bt_hal_handle_headset_events(GVariant *msg, const char *member,const char *path)
+static void __bt_hal_handle_headset_events(GVariant *msg, const char *member, const char *path)
 {
        gboolean property_flag = FALSE;
        char *property = NULL;
@@ -1164,7 +1234,7 @@ static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn,
 }
 
 static int __bt_hal_register_device_subscribe_signal(GDBusConnection *conn,
-                                int subscribe)
+               int subscribe)
 {
        static int subs_device_id = -1;
 
@@ -1222,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("+");
@@ -1243,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;
@@ -1252,7 +1353,7 @@ static int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_ty
 }
 
 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn,
-                                int subscribe)
+               int subscribe)
 {
        if (conn == NULL)
                return -1;
@@ -1318,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) {
@@ -1358,11 +1462,11 @@ static void __bt_hal_device_property_changed_event(GVariant *msg, const char *pa
        GVariantIter value_iter;
        GVariant *value = NULL;
        char *key = NULL;
-       g_variant_iter_init (&value_iter, msg);
+       g_variant_iter_init(&value_iter, msg);
        DBG("+");
 
        while (g_variant_iter_loop(&value_iter, "{sv}", &key, &value)) {
-               if(!g_strcmp0(key, "Connected")) {
+               if (!g_strcmp0(key, "Connected")) {
                        guint connected = 0;
                        g_variant_get(value, "i", &connected);
                        DBG("Device property changed : Connected [%d]", connected);
@@ -1378,6 +1482,7 @@ static void __bt_hal_device_property_changed_event(GVariant *msg, const char *pa
                        DBG("@@gatt_connected: %d", gatt_connected);
                        DBG("@@address: %s", address);
                        _bt_hal_gatt_connected_state_event(gatt_connected, address);
+                       _bt_hal_handle_gattc_connected_event(address, gatt_connected);
                        g_free(address);
                } else if (!g_strcmp0(key, "Paired")) {
                        gboolean paired = FALSE;
@@ -1436,62 +1541,62 @@ 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)
 {
-       char *address;
-       GError *error = NULL;
-       GDBusProxy *device_proxy;
-       GDBusConnection *conn;
-       GVariant *result;
-       DBG("+");
-
-       if(!device_path) {
-               ERR("Invalid device path");
-               return;
-       }
-
-       conn = _bt_hal_get_system_gconn();
-       if (!conn) {
-               ERR("_bt_hal_get_system_gconn failed");
-               return;
-       }
-
-       device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
-                       NULL,
-                       BT_HAL_BLUEZ_NAME,
-                       device_path,
-                       BT_HAL_PROPERTIES_INTERFACE,
-                       NULL, NULL);
-
-       if (!device_proxy) {
-               ERR("Error creating device_proxy");
-               return;
-       }
-
-       result = g_dbus_proxy_call_sync(device_proxy,
-                       "GetAll",
-                       g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
-                       G_DBUS_CALL_FLAGS_NONE,
-                       -1,
-                       NULL,
-                       &error);
-       if (!result) {
-               ERR("Error occured in Proxy call");
-               if (error != NULL) {
-                       ERR("Error occured in Proxy call (Error: %s)", error->message);
-                       g_clear_error(&error);
-               }
-               g_object_unref(device_proxy);
-               return;
-       }
-
-       address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
-       _bt_hal_convert_device_path_to_address(device_path, address);
-
-       __bt_hal_device_properties_lookup(result, address);
-
-       g_object_unref(device_proxy);
-       g_free(address);
-
-       DBG("-");
+       char *address;
+       GError *error = NULL;
+       GDBusProxy *device_proxy;
+       GDBusConnection *conn;
+       GVariant *result;
+       DBG("+");
+
+       if (!device_path) {
+               ERR("Invalid device path");
+               return;
+       }
+
+       conn = _bt_hal_get_system_gconn();
+       if (!conn) {
+               ERR("_bt_hal_get_system_gconn failed");
+               return;
+       }
+
+       device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+                       NULL,
+                       BT_HAL_BLUEZ_NAME,
+                       device_path,
+                       BT_HAL_PROPERTIES_INTERFACE,
+                       NULL, NULL);
+
+       if (!device_proxy) {
+               ERR("Error creating device_proxy");
+               return;
+       }
+
+       result = g_dbus_proxy_call_sync(device_proxy,
+                       "GetAll",
+                       g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       &error);
+       if (!result) {
+               ERR("Error occured in Proxy call");
+               if (error != NULL) {
+                       ERR("Error occured in Proxy call (Error: %s)", error->message);
+                       g_clear_error(&error);
+               }
+               g_object_unref(device_proxy);
+               return;
+       }
+
+       address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
+       _bt_hal_convert_device_path_to_address(device_path, address);
+
+       __bt_hal_device_properties_lookup(result, address);
+
+       g_object_unref(device_proxy);
+       g_free(address);
+
+       DBG("-");
 }
 
 static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
@@ -1515,7 +1620,7 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                g_variant_unref(result);
 
                /* Alias */
-               tmp_value = g_variant_lookup_value (value, "Alias", G_VARIANT_TYPE_STRING);
+               tmp_value = g_variant_lookup_value(value, "Alias", G_VARIANT_TYPE_STRING);
 
                g_variant_get(tmp_value, "s", &name);
 
@@ -1529,7 +1634,9 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                } else {
                        /* Name */
                        tmp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
+                       g_variant_get(tmp_value, "s", &name);
                        g_variant_unref(tmp_value);
+
                        size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
                                        strlen(name) + 1, name);
                        ev->num_props++;
@@ -1543,7 +1650,8 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CLASS,
                                sizeof(unsigned int), &class);
                ev->num_props++;
-               g_variant_unref(tmp_value);
+               if (tmp_value)
+                       g_variant_unref(tmp_value);
 
 
                /* Connected */
@@ -1553,7 +1661,8 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                                sizeof(unsigned int), &connected);
                ev->num_props++;
                DBG("Device connected [%u] Property num [%d]", connected,  ev->num_props);
-               g_variant_unref(tmp_value);
+               if (tmp_value)
+                       g_variant_unref(tmp_value);
 
                /* Trust */
                tmp_value = g_variant_lookup_value(value, "Trusted",  G_VARIANT_TYPE_BOOLEAN);
@@ -1562,7 +1671,8 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                                sizeof(uint8_t), &trust);
                ev->num_props++;
                DBG("Device trusted [%d] Property num [%d]", trust, ev->num_props);
-               g_variant_unref(tmp_value);
+               if (tmp_value)
+                       g_variant_unref(tmp_value);
 
                /* Paired */
                tmp_value = g_variant_lookup_value(value, "Paired",  G_VARIANT_TYPE_BOOLEAN);
@@ -1572,7 +1682,8 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                                sizeof(uint8_t), &paired);
                ev->num_props++;
                DBG("Device Paired [%d] Property num [%d]", paired, ev->num_props);
-               g_variant_unref(tmp_value);
+               if (tmp_value)
+                       g_variant_unref(tmp_value);
 
                /* RSSI*/
                tmp_value = g_variant_lookup_value(value, "RSSI", G_VARIANT_TYPE_INT32);
@@ -1581,12 +1692,14 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                                sizeof(int), &rssi);
                ev->num_props++;
                DBG("Device RSSI [%d] Property num [%d]", rssi, ev->num_props);
-               g_variant_unref(tmp_value);
+               if (tmp_value)
+                       g_variant_unref(tmp_value);
 
                /* Last Addr Type */
                tmp_value = g_variant_lookup_value(value, "LastAddrType", G_VARIANT_TYPE_UINT32);
                unsigned int addr_type = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
-               g_variant_unref(tmp_value);
+               if (tmp_value)
+                       g_variant_unref(tmp_value);
                DBG("Device Last Address Type [0x%x]", addr_type);
 
                /* Is Alias Set */
@@ -1596,7 +1709,8 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                                        sizeof(uint8_t), &is_alias_set);
                ev->num_props++;
                DBG("IsAliasSet: [%s], Property num [%d]", (is_alias_set ? "TRUE" : "FALSE"), ev->num_props);
-               g_variant_unref(tmp_value);
+               if (tmp_value)
+                       g_variant_unref(tmp_value);
 
                /* UUID's */
                tmp_value = g_variant_lookup_value(value, "UUIDs", G_VARIANT_TYPE_STRING_ARRAY);
@@ -1624,7 +1738,7 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
 
                                _bt_hal_convert_uuid_string_to_type(uuid, uuid_str);
 #ifdef __TEST_
-                               for(z=0; z < 16; z++)
+                               for (z = 0; z < 16; z++)
                                        DBG("[0x%x]", uuid[z]);
 #endif
 
@@ -1640,21 +1754,22 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                }
                g_variant_unref(tmp_value);
 
-               /* ManufacturerDataLen */
-               tmp_value = g_variant_lookup_value(value, "ManufacturerDataLen", G_VARIANT_TYPE_UINT32);
+               /* LegacyManufacturerDataLen */
+               tmp_value = g_variant_lookup_value(value, "LegacyManufacturerDataLen", G_VARIANT_TYPE_UINT32);
                unsigned int manufacturer_data_len = tmp_value ? g_variant_get_uint32(tmp_value) : 0;
                if (manufacturer_data_len > BT_HAL_MANUFACTURER_DATA_LENGTH_MAX) {
                        ERR("manufacturer_data_len is too long(len = %d)", manufacturer_data_len);
                        manufacturer_data_len = BT_HAL_MANUFACTURER_DATA_LENGTH_MAX;
                }
-               g_variant_unref(tmp_value);
+               if (tmp_value)
+                       g_variant_unref(tmp_value);
                /*size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_MANUFACTURER_DATA_LEN,
                  sizeof(unsigned int), &manufacturer_data_len);
                  ev->num_props++;*/
-               DBG("Device Manufacturer data length [%u]", manufacturer_data_len);
+               DBG("Device Legacy Manufacturer data length [%u]", manufacturer_data_len);
 
                /* ManufacturerData */
-               tmp_value = g_variant_lookup_value(value, "ManufacturerData", G_VARIANT_TYPE_BYTESTRING);
+               tmp_value = g_variant_lookup_value(value, "LegacyManufacturerData", G_VARIANT_TYPE_BYTESTRING);
                manufacturer_data = value ? (gchar *)g_variant_get_bytestring(tmp_value) : NULL;
                if (manufacturer_data) {
                        if (manufacturer_data_len > 0) {
@@ -1664,7 +1779,8 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                                ev->num_props++;
                        }
                }
-               g_variant_unref(tmp_value);
+               if (tmp_value)
+                       g_variant_unref(tmp_value);
 
                /* Address */
                uint8_t bdaddr[6];
@@ -1672,7 +1788,7 @@ static void __bt_hal_device_properties_lookup(GVariant *result, char *address)
                size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
                                sizeof(bdaddr), bdaddr);
                ev->num_props++;
-               DBG("Device address [%s] property Num [%d]",address, ev->num_props);
+               DBG("Device address [%s] property Num [%d]", address, ev->num_props);
 
                g_free(name);
                g_variant_unref(value);
@@ -1680,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;
@@ -1705,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;
@@ -1774,13 +1890,14 @@ static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *me
                if (strcasecmp(property, "GattConnected") == 0) {
                        INFO("GATT Connected");
                        gboolean connected = FALSE;
-                        char *address;
-                        address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
+                       char *address;
+                       address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
 
-                        _bt_hal_convert_device_path_to_address(path, address);
-                        g_variant_get(msg, "(b)", &connected);
+                       _bt_hal_convert_device_path_to_address(path, address);
+                       g_variant_get(msg, "(b)", &connected);
 
                        INFO("Connected device address[%s] connnected[%d]", address, connected);
+                       g_free(address);
                } else if (strcasecmp(property, "Paired") == 0) {
                        gboolean paired = FALSE;
                        struct hal_ev_bond_state_changed ev;
@@ -1817,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;
@@ -1832,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;
@@ -1911,9 +2029,8 @@ static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *me
                        } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
                                DBG("AVRCP Controller Profile state changed: BT_HAL_PROFILE_STATE_CONNECTING");
                        }
-               }
-               else {
-                       DBG("Profile[%s] State changed status [%d] ", profile_uuid,state);
+               } else {
+                       DBG("Profile[%s] State changed status [%d] ", profile_uuid, state);
                }
                g_free(address);
                g_free(profile_uuid);
@@ -1967,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);
 }
@@ -2034,7 +2151,7 @@ static void __bt_avrcp_control_parse_properties(struct hal_ev_track_changed *ev,
        const char *key = NULL;
        int i = 0;
 
-       if(ev == NULL)
+       if (ev == NULL)
                return;
 
        g_variant_iter_init(&iter, item);
@@ -2067,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++;
@@ -2075,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++;
@@ -2083,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++;
@@ -2147,7 +2264,7 @@ static int __bt_media_attrval_to_val(int type, const char *value)
 }
 
 static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member,
-                                       const char *path)
+               const char *path)
 {
        const char *property = NULL;
        GVariant *value = NULL;
@@ -2171,7 +2288,6 @@ static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member,
        while (g_variant_iter_loop(&iter, "{sv}", &property, &value)) {
                DBG("Property = %s \n", property);
                if ((strcasecmp(property, "Equalizer") == 0) ||
-                               (strcasecmp(property, "Equalizer") == 0) ||
                                (strcasecmp(property, "Repeat") == 0) ||
                                (strcasecmp(property, "Shuffle") == 0) ||
                                (strcasecmp(property, "Scan") == 0)) {
@@ -2238,6 +2354,54 @@ static void __bt_hal_handle_avrcp_ctrl_events(GVariant *msg, const char *member,
        g_variant_unref(value);
 }
 
+static void __bt_hal_handle_avrcp_transport_events(GVariant *msg, const char *member,
+               const char *path)
+{
+       const char *property = NULL;
+       GVariant *value = NULL;
+       GVariantIter iter;
+       char address[BT_HAL_ADDRESS_STRING_SIZE];
+       DBG("+");
+
+       if (!msg) {
+               ERR("Error returned in method call\n");
+               return;
+       }
+
+       if (!avrcp_tg_event_cb) {
+               ERR("AVRCP target DBUS handler callback not registered");
+               return;
+       }
+
+       g_variant_iter_init(&iter, msg);
+
+       _bt_hal_convert_device_path_to_address(path, address);
+
+       while (g_variant_iter_loop(&iter, "{sv}", &property, &value)) {
+               DBG("Property = %s \n", property);
+               if ((strcasecmp(property, "Delay") == 0)) {
+                       struct hal_ev_avrcp_tg_delay_changed ev;
+                       uint16_t val;
+
+                       memset(&ev, 0, sizeof(ev));
+                       _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
+
+                       val = g_variant_get_uint16(value);
+                       DBG("Value : %d", val);
+                       ev.value = val;
+
+                       /* Send event to application */
+                       avrcp_tg_event_cb(HAL_EV_AVRCP_TG_DELAY_CHANGE, &ev, sizeof(ev));
+               } else {
+                       DBG("Property not handled");
+               }
+       }
+
+       DBG("-");
+       g_free((char *)property);
+       g_variant_unref(value);
+}
+
 /* A2DP Src Role(Remote:Sink) Events */
 static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address)
 {
@@ -2402,12 +2566,12 @@ bool _bt_hal_get_le_request_state(void)
 
 void _bt_hal_set_adapter_request_state(bool enable)
 {
-       DBG("set_adapter_request_state %d",enable);
+       DBG("set_adapter_request_state %d", enable);
        is_adapter_activating = enable;
 }
 
 void _bt_hal_set_le_request_state(bool enable)
 {
-       DBG("set_le_request_state %d",enable);
+       DBG("set_le_request_state %d", enable);
        is_le_activating = enable;
 }