[Adapt : Bluez HAL] Added A2DP Sink role 27/116927/1
authorNilesh Trimbake <t.shripati@samsung.com>
Fri, 25 Nov 2016 10:00:03 +0000 (15:30 +0530)
committerNilesh Trimbake <t.shripati@samsung.com>
Thu, 2 Mar 2017 05:15:30 +0000 (10:45 +0530)
This patch primarily adds following:-
        a/ AV(Sink) Android HAL interface
        b/ Implement Bluez based A2DP Sink Init, Connect, Disconnect methods
        c/ Implemnt A2DP Sink Connection event handlers

Change-Id: I6ec89a5288d05475f881ef872236fce7001fb59d
Signed-off-by: Nilesh Trimbake <t.shripati@samsung.com>
bt-oal/bluez_hal/CMakeLists.txt
bt-oal/bluez_hal/inc/bt-hal-msg.h
bt-oal/bluez_hal/src/bt-hal-a2dp-sink-dbus-handler.c [new file with mode: 0644]
bt-oal/bluez_hal/src/bt-hal-a2dp-sink-dbus-handler.h [new file with mode: 0644]
bt-oal/bluez_hal/src/bt-hal-a2dp-sink.c [new file with mode: 0644]
bt-oal/bluez_hal/src/bt-hal-a2dp-sink.h [new file with mode: 0644]
bt-oal/bluez_hal/src/bt-hal-bluetooth.c
bt-oal/bluez_hal/src/bt-hal-event-receiver.c
bt-oal/bluez_hal/src/bt-hal-event-receiver.h
bt-oal/bluez_hal/src/bt-hal-internal.h
bt-oal/bluez_hal/src/bt-hal-utils.c

index 6567c49..cd800bc 100644 (file)
@@ -13,6 +13,8 @@ SET(SRCS
 ./src/bt-hal-hidhost.c
 ./src/bt-hal-av.c
 ./src/bt-hal-av-dbus-handler.c
+./src/bt-hal-a2dp-sink.c
+./src/bt-hal-a2dp-sink-dbus-handler.c
 ./src/bt-hal-hf.c
 ./src/bt-hal-hf-dbus-handler.c
 ./src/bt-hal-hid-dbus-handler.c
index 29f23b9..6370c67 100644 (file)
@@ -293,6 +293,9 @@ struct hal_ev_a2dp_audio_config {
         uint8_t  channel_count;
 } __attribute__((packed));
 
+/* A2DP Sink Role connection*/
+#define HAL_EV_A2DP_SOURCE_CONN_STATE                   0x8F
+
 /* HandsFree Headers */
 #define HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED        0x00
 #define HAL_EV_HANDSFREE_CONN_STATE_CONNECTING          0x01
diff --git a/bt-oal/bluez_hal/src/bt-hal-a2dp-sink-dbus-handler.c b/bt-oal/bluez_hal/src/bt-hal-a2dp-sink-dbus-handler.c
new file mode 100644 (file)
index 0000000..36a8711
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Bluetooth HAL
+ *
+ * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Nilesh Trimbake <t.shripati@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <dlog.h>
+#include <vconf.h>
+
+#include "bt-hal-a2dp-sink-dbus-handler.h"
+#include "bt-hal-dbus-common-utils.h"
+#include "bt-hal-internal.h"
+
+
+static handle_stack_msg event_cb = NULL;
+
+/* To send stack event to hal-a2dp-sink handler */
+void _bt_hal_register_a2dp_sink_dbus_handler_cb(handle_stack_msg cb)
+{
+       event_cb = cb;
+}
+
+/* To send stack event to hal-a2dp-sink handler */
+void _bt_hal_unregister_a2dp_sink_dbus_handler_cb()
+{
+       event_cb = NULL;
+}
+
+static void __bt_a2dp_sink_connect_cb(GDBusProxy *proxy, GAsyncResult *res,
+                                                       gpointer user_data)
+{
+       GError *g_error = NULL;
+       struct hal_ev_a2dp_conn_state ev;
+       GVariant *reply = NULL;
+       char *address = user_data;
+       int result = BT_STATUS_SUCCESS;
+
+       DBG("+");
+
+       reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
+       g_object_unref(proxy);
+       if (reply == NULL) {
+               ERR("A2DP Source Connect Dbus Call Error");
+               if (g_error) {
+                       ERR("Error: %s\n", g_error->message);
+                       g_clear_error(&g_error);
+               }
+               result = BT_STATUS_FAIL;
+       }
+       g_variant_unref(reply);
+
+       DBG("Address: %s", address);
+       /*
+        * If result is success, Send connecting event
+        */
+       if (result == BT_STATUS_SUCCESS) {
+               /* Prepare to send A2DP Source connecting event */
+               memset(&ev, 0, sizeof(ev));
+               _bt_convert_addr_string_to_type(ev.bdaddr, address);
+               ev.state = HAL_EV_A2DP_STATE_CONNECTING;
+               if (!event_cb)
+                       ERR("A2DP SINK DBUS handler callback not registered");
+               else
+                       event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, (void *)&ev, sizeof(ev));
+       } else {
+               /* Prepare to send A2DP Source disconnected event */
+               memset(&ev, 0, sizeof(ev));
+               _bt_convert_addr_string_to_type(ev.bdaddr, address);
+               ev.state = HAL_EV_A2DP_STATE_DISCONNECTED;
+               if (!event_cb)
+                       ERR("A2DP SINK DBUS handler callback not registered");
+               else
+                       event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, (void *)&ev, sizeof(ev));
+       }
+       g_free(address);
+}
+
+bt_status_t _bt_hal_dbus_handler_a2dp_sink_connect(bt_bdaddr_t *bd_addr)
+{
+       char *address;
+       GDBusConnection *conn;
+
+       int ret;
+
+       if(!bd_addr) {
+               ERR("bd_addr is NULL, return");
+               return BT_STATUS_PARM_INVALID;
+       }
+
+       conn = _bt_get_system_gconn();
+       if(!conn) {
+               ERR("_bt_get_system_gconn returned NULL, return");
+               return BT_STATUS_FAIL;
+       }
+
+       address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE * sizeof(char));
+       if (!address) {
+               ERR("Memory allocation failed");
+               return BT_STATUS_NOMEM;
+       }
+       _bt_convert_addr_type_to_string(address, bd_addr->address);
+
+       ret = _bt_connect_profile(address, A2DP_SOURCE_UUID,
+                       __bt_a2dp_sink_connect_cb, address);
+
+       if (ret != BT_HAL_ERROR_NONE) {
+               ERR("_bt_connect_profile(A2DP source) Error");
+               return BT_STATUS_FAIL;
+       }
+
+       return BT_STATUS_SUCCESS;
+}
+
+static void __bt_a2dp_source_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
+                                                       gpointer user_data)
+{
+       GError *g_error = NULL;
+       struct hal_ev_a2dp_conn_state ev;
+       GVariant *reply = NULL;
+       char *address = user_data;
+       int result = BT_STATUS_SUCCESS;
+
+       DBG("+");
+
+       reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
+       g_object_unref(proxy);
+       if (reply == NULL) {
+               ERR("A2DP Source Disconnect Dbus Call Error");
+               if (g_error) {
+                       ERR("Error: %s\n", g_error->message);
+                       g_clear_error(&g_error);
+               }
+               result = BT_STATUS_FAIL;
+       }
+       g_variant_unref(reply);
+
+       if (result != BT_STATUS_FAIL)
+               DBG("A2DP Source Disconnect successful for Device: %s", address);
+       else
+               DBG("A2DP Source Disconnect un-successful for Device: %s", address);
+       if (result == BT_STATUS_FAIL) {
+               /* Prepare to send AV source disconnected state event */
+               memset(&ev, 0, sizeof(ev));
+               _bt_convert_addr_string_to_type(ev.bdaddr, address);
+               ev.state = HAL_EV_A2DP_STATE_DISCONNECTED;
+               if (!event_cb)
+                       ERR("A2DP SINK DBUS handler callback not registered");
+               else
+                       event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, (void *)&ev, sizeof(ev));
+       } else {
+               /* Prepare to send AV source disconnecting state event */
+               memset(&ev, 0, sizeof(ev));
+               _bt_convert_addr_string_to_type(ev.bdaddr, address);
+               ev.state = HAL_EV_A2DP_STATE_DISCONNECTING;
+               if (!event_cb)
+                       ERR("A2DP SINK DBUS handler callback not registered");
+               else
+                       event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, (void *)&ev, sizeof(ev));
+       }
+       g_free(address);
+       DBG("-");
+}
+
+bt_status_t _bt_hal_dbus_handler_a2dp_sink_disconnect(bt_bdaddr_t *bd_addr)
+{
+       char *address;
+       GDBusConnection *conn;
+
+       int ret;
+
+       if(!bd_addr) {
+               ERR("bd_addr is NULL, return");
+               return BT_STATUS_PARM_INVALID;
+       }
+
+       conn = _bt_get_system_gconn();
+       if(!conn) {
+               ERR("_bt_get_system_gconn returned NULL, return");
+               return BT_STATUS_FAIL;
+       }
+
+       address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE * sizeof(char));
+       if (!address) {
+               ERR("Memory allocation failed");
+               return BT_STATUS_NOMEM;
+       }
+       _bt_convert_addr_type_to_string(address, bd_addr->address);
+
+       ret = _bt_disconnect_profile(address, A2DP_SOURCE_UUID,
+                       __bt_a2dp_source_disconnect_cb, address);
+
+       if (ret != BT_HAL_ERROR_NONE) {
+               ERR("_bt_connect_profile(AV) Error");
+               return BT_STATUS_FAIL;
+       }
+
+       return BT_STATUS_SUCCESS;
+}
diff --git a/bt-oal/bluez_hal/src/bt-hal-a2dp-sink-dbus-handler.h b/bt-oal/bluez_hal/src/bt-hal-a2dp-sink-dbus-handler.h
new file mode 100644 (file)
index 0000000..3cc78f8
--- /dev/null
@@ -0,0 +1,49 @@
+/* Bluetooth HAL
+ *
+ * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Nilesh Trimbake <t.shripati@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_HAL_A2DP_SINK_DBUS_HANDLER_H_
+#define _BT_HAL_A2DP_SINK_DBUS_HANDLER_H_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#include "bt-hal.h"
+#include "bt-hal-log.h"
+#include "bt-hal-msg.h"
+
+#include "bt-hal-event-receiver.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _bt_hal_register_a2dp_sink_dbus_handler_cb(handle_stack_msg cb);
+
+void _bt_hal_unregister_a2dp_sink_dbus_handler_cb();
+
+bt_status_t _bt_hal_dbus_handler_a2dp_sink_connect(bt_bdaddr_t *bd_addr);
+
+bt_status_t _bt_hal_dbus_handler_a2dp_sink_disconnect(bt_bdaddr_t *bd_addr);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _BT_HAL_A2DP_SINK_DBUS_HANDLER_H_*/
diff --git a/bt-oal/bluez_hal/src/bt-hal-a2dp-sink.c b/bt-oal/bluez_hal/src/bt-hal-a2dp-sink.c
new file mode 100644 (file)
index 0000000..d2427b8
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Bluetooth HAL
+ *
+ * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Nilesh Trimbake <t.shripati@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+#include <dlog.h>
+
+#include "bt-hal.h"
+#include "bt-hal-log.h"
+#include "bt-hal-msg.h"
+#include "bt-hal-utils.h"
+#include "bt-hal-a2dp-sink-dbus-handler.h"
+
+static const btav_callbacks_t *bt_hal_a2dp_sink_cbacks;
+
+static bool interface_ready(void)
+{
+       return bt_hal_a2dp_sink_cbacks != NULL;
+}
+
+static bt_status_t a2dp_sink_connect(bt_bdaddr_t *bd_addr)
+{
+       DBG("");
+       return _bt_hal_dbus_handler_a2dp_sink_connect(bd_addr);
+}
+
+static bt_status_t a2dp_sink_disconnect(bt_bdaddr_t *bd_addr)
+{
+       DBG("");
+       return _bt_hal_dbus_handler_a2dp_sink_disconnect(bd_addr);
+}
+
+static void __bt_hal_handle_a2dp_sink_conn_state(void *buf, uint16_t len)
+{
+       struct hal_ev_a2dp_conn_state *ev = buf;
+
+       if (bt_hal_a2dp_sink_cbacks->connection_state_cb)
+               bt_hal_a2dp_sink_cbacks->connection_state_cb(ev->state, (bt_bdaddr_t *) ev->bdaddr);
+}
+
+static void __bt_hal_handle_a2dp_sink_audio_conn_state(void *buf, uint16_t len)
+{
+       struct hal_ev_a2dp_audio_state *ev = buf;
+
+       if (bt_hal_a2dp_sink_cbacks->audio_state_cb)
+               bt_hal_a2dp_sink_cbacks->audio_state_cb(ev->state, (bt_bdaddr_t *) ev->bdaddr);
+}
+
+static void __bt_hal_handle_a2dp_sink_events(int message, void *buf, uint16_t len)
+{
+        DBG("+");
+        if (!interface_ready())
+                return;
+        switch(message) {
+                case HAL_EV_A2DP_SOURCE_CONN_STATE:
+                        DBG("Event: HAL_EV_A2DP_SOURCE_CONN_STATE");
+                        __bt_hal_handle_a2dp_sink_conn_state(buf, len);
+                        break;
+                case HAL_EV_A2DP_AUDIO_STATE:
+                        DBG("Event: HAL_EV_A2DP_AUDIO_STATE");
+                        __bt_hal_handle_a2dp_sink_audio_conn_state(buf, len);
+                        break;
+                default:
+                        DBG("Event Currently not handled!!");
+                        break;
+        }
+        DBG("-");
+}
+
+static bt_status_t init(btav_callbacks_t* callbacks)
+{
+       DBG("");
+
+       if (interface_ready())
+               return BT_STATUS_DONE;
+
+       bt_hal_a2dp_sink_cbacks = callbacks;
+       DBG("Register A2DP Sink events callback function");
+       _bt_hal_register_a2dp_sink_dbus_handler_cb(__bt_hal_handle_a2dp_sink_events);
+       _bt_hal_register_a2dp_sink_event_handler_cb(__bt_hal_handle_a2dp_sink_events);
+       return BT_STATUS_SUCCESS;
+}
+
+static void cleanup(void)
+{
+       DBG("");
+
+       if (!interface_ready())
+               return;
+
+       bt_hal_a2dp_sink_cbacks = NULL;
+       _bt_hal_unregister_a2dp_sink_event_handler_cb();
+}
+
+static btav_interface_t a2dp_sink_if = {
+       .size = sizeof(a2dp_sink_if),
+       .init = init,
+       .connect = a2dp_sink_connect,
+       .disconnect = a2dp_sink_disconnect,
+       .cleanup = cleanup
+};
+
+btav_interface_t *bt_get_a2dp_sink_interface(void)
+{
+       DBG("Get A2DP Sink Profile Interface");
+       return &a2dp_sink_if;
+}
diff --git a/bt-oal/bluez_hal/src/bt-hal-a2dp-sink.h b/bt-oal/bluez_hal/src/bt-hal-a2dp-sink.h
new file mode 100644 (file)
index 0000000..248f810
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Bluetooth HAL
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Nilesh Trimbake <t.shripati@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __BT_HAL_A2DP_SINK_H__
+#define __BT_HAL_A2DP_SINK_H__
+
+#include <stdint.h>
+#include <glib.h>
+#include <unistd.h>
+#include <dlog.h>
+#include <stdio.h>
+
+btav_interface_t *bt_get_a2dp_sink_interface(void);
+
+#endif //__BT_HAL_A2DP_SINK_H__
index 92cf5f4..7796cf3 100644 (file)
@@ -37,6 +37,7 @@
 #include <bt-hal-av.h>
 #include <bt-hal-hf.h>
 #include <bt-hal-hdp.h>
+#include <bt-hal-a2dp-sink.h>
 
 #define enum_prop_to_hal(prop, hal_prop, type) do { \
        static type e; \
@@ -246,7 +247,7 @@ static const void *get_profile_interface(const char *profile_id)
                return NULL;
 
        if (!strcmp(profile_id, BT_PROFILE_ADVANCED_AUDIO_SINK_ID))
-               return NULL;
+               return bt_get_a2dp_sink_interface();
 
        return NULL;
 }
index 99039e7..dd38dfd 100644 (file)
@@ -51,6 +51,7 @@ static GDBusConnection *manager_conn;
 static handle_stack_msg event_cb = NULL;
 static handle_stack_msg hid_event_cb = NULL;
 static handle_stack_msg av_event_cb = NULL;
+static handle_stack_msg a2dp_sink_event_cb = NULL;
 static handle_stack_msg hf_event_cb = NULL;
 static guint event_id;
 
@@ -80,6 +81,7 @@ static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *me
 static void __bt_hal_send_device_acl_connection_state_event(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_device_trust_state_event(gboolean is_trusted, const char *address);
 static int __bt_hal_register_audio_subscribe_signal(GDBusConnection *conn, int subscribe);
@@ -1495,6 +1497,18 @@ static void __bt_hal_handle_device_specific_events(GVariant *msg, const char *me
                        } else {
                                ERR("A2DP Profile state: Invalid");
                        }
+               } else if ((strncmp(profile_uuid, A2DP_SOURCE_UUID, strlen(A2DP_SOURCE_UUID)) == 0)) {
+                       if (state == BT_HAL_PROFILE_STATE_CONNECTED) {
+                               DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_CONNECTED");
+                               __bt_hal_send_a2dp_sink_connection_state_event(TRUE, address);
+                       } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTED) {
+                               DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTED");
+                               __bt_hal_send_a2dp_sink_connection_state_event(FALSE, address);
+                       } else if (state == BT_HAL_PROFILE_STATE_DISCONNECTING) {
+                               DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_DISCONNECTING");
+                       } else if (state == BT_HAL_PROFILE_STATE_CONNECTING) {
+                               DBG("A2DP Sink Profile state changed: BT_HAL_PROFILE_STATE_CONNECTING");
+                       }
                } else if (strncmp(profile_uuid, HFP_HF_UUID, strlen(HFP_HF_UUID)) == 0) {
                        if (state == BT_HAL_PROFILE_STATE_CONNECTING)
                                DBG("HFP Profile state changed: BT_PROFILE_STATE_CONNECTING");
@@ -1539,26 +1553,48 @@ void _bt_hal_unregister_av_event_handler_cb()
        av_event_cb = NULL;
 }
 
-/* HF(AG Role) Events */
-void _bt_hal_register_hf_event_handler_cb(handle_stack_msg cb)
+static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address)
 {
-       hf_event_cb = cb;
+       DBG("+");
+       struct hal_ev_a2dp_conn_state ev;
+
+       if (connected == TRUE)
+               INFO("A2DP(Src) Profile Connected for address [%s]", address);
+       else
+               INFO("A2DP(Src) Profile DisConnected for address [%s]", address);
+
+       ev.state = (connected == TRUE) ?
+               HAL_EV_A2DP_STATE_CONNECTED :
+               HAL_EV_A2DP_STATE_DISCONNECTED;
+
+       _bt_convert_addr_string_to_type(ev.bdaddr, address);
+
+       if (!av_event_cb)
+               ERR("AV event handler not registered");
+       else
+               av_event_cb(HAL_EV_A2DP_CONN_STATE, &ev, sizeof(ev));
 }
 
-void _bt_hal_unregister_hf_event_handler_cb()
+/* A2DP Sink Role(Remote:Source) Events */
+void _bt_hal_register_a2dp_sink_event_handler_cb(handle_stack_msg cb)
 {
-       hf_event_cb = NULL;
+       a2dp_sink_event_cb = cb;
 }
 
-static void __bt_hal_send_av_connection_state_event(gboolean connected, const char *address)
+void _bt_hal_unregister_a2dp_sink_event_handler_cb(void)
+{
+       a2dp_sink_event_cb = NULL;
+}
+
+static void __bt_hal_send_a2dp_sink_connection_state_event(gboolean connected, const char *address)
 {
        DBG("+");
        struct hal_ev_a2dp_conn_state ev;
 
        if (connected == TRUE)
-               INFO("A2DP(Src) Profile Connected for address [%s]", address);
+               INFO("A2DP(Sink) Profile Connected for address [%s]", address);
        else
-               INFO("A2DP(Src) Profile DisConnected for address [%s]", address);
+               INFO("A2DP(Sink) Profile DisConnected for address [%s]", address);
 
        ev.state = (connected == TRUE) ?
                HAL_EV_A2DP_STATE_CONNECTED :
@@ -1566,10 +1602,21 @@ static void __bt_hal_send_av_connection_state_event(gboolean connected, const ch
 
        _bt_convert_addr_string_to_type(ev.bdaddr, address);
 
-       if (!av_event_cb)
+       if (!a2dp_sink_event_cb)
                ERR("AV event handler not registered");
        else
-               av_event_cb(HAL_EV_A2DP_CONN_STATE, &ev, sizeof(ev));
+               a2dp_sink_event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, &ev, sizeof(ev));
+}
+
+/* HF(AG Role) Events */
+void _bt_hal_register_hf_event_handler_cb(handle_stack_msg cb)
+{
+       hf_event_cb = cb;
+}
+
+void _bt_hal_unregister_hf_event_handler_cb()
+{
+       hf_event_cb = NULL;
 }
 
 static void __bt_hal_send_hf_audio_connection_state_event(gboolean connected,
index 4c0b775..8736531 100644 (file)
@@ -49,6 +49,11 @@ void _bt_hal_register_av_event_handler_cb(handle_stack_msg cb);
 
 void _bt_hal_unregister_av_event_handler_cb();
 
+/* A2DP(SINK Role) Events */
+void _bt_hal_register_a2dp_sink_event_handler_cb(handle_stack_msg cb);
+
+void _bt_hal_unregister_a2dp_sink_event_handler_cb(void);
+
 /* HF(AG Role) Events*/
 void _bt_hal_register_hf_event_handler_cb(handle_stack_msg cb);
 
index 0745992..2acc64b 100644 (file)
@@ -65,6 +65,7 @@ typedef enum {
 /* UUIDs */
 #define HID_UUID                "00001124-0000-1000-8000-00805f9b34fb"
 #define A2DP_SINK_UUID          "0000110b-0000-1000-8000-00805f9b34fb"
+#define A2DP_SOURCE_UUID        "0000110a-0000-1000-8000-00805f9b34fb"
 #define HFP_HF_UUID             "0000111e-0000-1000-8000-00805f9b34fb"
 
 /* TODO  More declarations to be added in subsequent patches */
index 796dc7f..6db3726 100644 (file)
@@ -379,6 +379,8 @@ bt_service_id_t _bt_convert_uuid_string_to_service_id(const char *uuid)
                service_id = BT_A2DP_SERVICE_ID;
        else if (!strcasecmp(uuid, BT_HAL_A2DP_PROFILE_UUID))
                service_id = BT_A2DP_SERVICE_ID;
+       else if (!strcasecmp(uuid, BT_HAL_A2DP_SOURCE_UUID))
+               service_id = BT_A2DP_SRC_SERVICE_ID;
        else if (!strcasecmp(uuid, BT_HAL_AVRCP_TARGET_UUID))
                service_id = BT_AVRCP_SERVICE_ID;
        else if (!strcasecmp(uuid, BT_HAL_AVRCP_REMOTE_UUID))