2 * Open Adaptation Layer (OAL)
4 * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
6 * Contact: Nilesh Trimbake <t.shripati@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
24 #include <sys/socket.h>
25 #include <sys/errno.h>
30 #include <bluetooth.h>
33 #include "oal-internal.h"
34 #include "oal-a2dp-sink.h"
35 #include "oal-utils.h"
36 #include "oal-common.h"
38 #define CHECK_OAL_SINK_ENABLED() \
40 if (blued_a2dp_sink_interface == NULL) { \
41 BT_ERR("OAL, Audio Not Enabled"); \
42 return OAL_STATUS_NOT_READY; \
47 static void cb_a2dp_sink_connection_state(btav_connection_state_t event, bt_bdaddr_t* bd_addr);
48 static void cb_a2dp_sink_audio_state(btav_audio_state_t state, bt_bdaddr_t* bd_addr);
50 const bt_interface_t * _bt_get_stack_interface(void);
51 static const btav_interface_t *blued_a2dp_sink_interface = NULL;
53 static btav_callbacks_t blued_a2dp_sink_cb = {
54 sizeof(blued_a2dp_sink_cb),
55 cb_a2dp_sink_connection_state,
56 cb_a2dp_sink_audio_state
59 oal_status_t a2dp_sink_enable(char *service_name , char *provider_name)
61 const bt_interface_t* blued_inf;
64 API_TRACE("Audio Sink Enable");
66 if ((blued_inf = adapter_get_stack_interface()) == NULL) {
67 BT_ERR("Bluetooth module is not loaded");
68 return OAL_STATUS_NOT_READY;
71 if (blued_a2dp_sink_interface != NULL) {
72 BT_WARN("A2DP Sink Interface is already initialized...");
73 return OAL_STATUS_ALREADY_DONE;
76 if ((blued_a2dp_sink_interface = (const btav_interface_t *)blued_inf->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_SINK_ID)) == NULL) {
77 BT_ERR("OAL, Failed to get Bluetooth A2DP Sink Interface");
78 return OAL_STATUS_INTERNAL_ERROR;
81 BT_DBG("Got profile interface");
82 if ((ret = blued_a2dp_sink_interface->init(&blued_a2dp_sink_cb)) != BT_STATUS_SUCCESS) {
83 BT_ERR("Failed to initialize Bluetooth A2DP, status: %s", status2string(ret));
84 blued_a2dp_sink_interface = NULL;
85 return convert_to_oal_status(ret);
87 BT_DBG("OAL, Bluetooth audio interface initialised");
89 return OAL_STATUS_SUCCESS;
92 /* Audio deinit: Resets all the audio information
93 * Note: Adapter should be disabled before calling deinit
95 oal_status_t a2dp_sink_disable(void)
98 API_TRACE("Audio Sink Disable");
100 CHECK_OAL_SINK_ENABLED();
102 blued_a2dp_sink_interface->cleanup();
103 blued_a2dp_sink_interface = NULL;
105 return OAL_STATUS_SUCCESS;
108 oal_status_t a2dp_sink_connect(bt_address_t *device_address)
110 int result = OAL_STATUS_SUCCESS;
116 CHECK_OAL_SINK_ENABLED();
117 OAL_CHECK_PARAMETER(device_address, return);
119 BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
121 /* Call connect function of Bluedroid*/
122 status = blued_a2dp_sink_interface->connect((bt_bdaddr_t *)device_address);
123 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
124 BT_ERR("Connection could not be established, err: %s", status2string(status));;
125 result = convert_to_oal_status(status);
131 oal_status_t a2dp_sink_disconnect(bt_address_t *device_address)
133 int result = OAL_STATUS_SUCCESS;
139 CHECK_OAL_SINK_ENABLED();
140 OAL_CHECK_PARAMETER(device_address, return);
142 BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
144 /* call Disconnect function of Bluedroid */
145 status = blued_a2dp_sink_interface->disconnect((bt_bdaddr_t *)device_address);
146 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
147 BT_ERR("OAL, Disconnection failed err: %s", status2string(status));
148 result = convert_to_oal_status(status);
153 static void cb_a2dp_sink_connection_state(btav_connection_state_t state, bt_bdaddr_t* bd_addr)
155 bt_address_t * event_data = NULL;
159 ret_if(bd_addr == NULL);
160 BT_INFO("state = %d, BT Address = %s", state, bdt_bd2str((bt_address_t*)bd_addr, &bdstr));
162 event_data = g_new0(bt_address_t, 1);
163 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
166 case BTAV_CONNECTION_STATE_CONNECTING: {
167 event = OAL_EVENT_A2DP_SINK_CONNECTING;
170 case BTAV_CONNECTION_STATE_CONNECTED: {
171 event = OAL_EVENT_A2DP_SINK_CONNECTED;
174 case BTAV_CONNECTION_STATE_DISCONNECTING: {
175 event = OAL_EVENT_A2DP_SINK_DISCONNECTING;
178 case BTAV_CONNECTION_STATE_DISCONNECTED: {
179 event = OAL_EVENT_A2DP_SINK_DISCONNECTED;
183 BT_INFO("Invalid state");
189 send_event_bda_trace(event, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
192 static void cb_a2dp_sink_audio_state(btav_audio_state_t state, bt_bdaddr_t* bd_addr)
196 ret_if(bd_addr == NULL);
197 BT_INFO("A2DP state = %d, BT Address = %s", state, bdt_bd2str((bt_address_t*)bd_addr, &bdstr));
199 //stream_state = state; //removed by Moon
201 if (state == BTAV_AUDIO_STATE_REMOTE_SUSPEND) {
202 BT_INFO("Audio Streaming Suspended");
203 } else if (state == BTAV_AUDIO_STATE_STOPPED) {
204 BT_INFO("###Audio Streaming Stopped");
205 bt_address_t * event_data = g_new0(bt_address_t, 1);
207 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
208 send_event_bda_trace(OAL_EVENT_AUDIO_STOPPED, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
209 } else if (state == BTAV_AUDIO_STATE_STARTED) {
210 BT_INFO("###Audio Streaming Startted");
211 bt_address_t * event_data = g_new0(bt_address_t, 1);
213 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
214 send_event_bda_trace(OAL_EVENT_AUDIO_STARTED, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
216 BT_ERR("Unknown state received:%d", (int)state);