2 * Open Adaptation Layer (OAL)
4 * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
22 #include <sys/socket.h>
23 #include <sys/errno.h>
28 #include <bluetooth.h>
31 #include "oal-internal.h"
32 #include "oal-audio-src.h"
33 #include "oal-utils.h"
34 #include "oal-common.h"
36 #define CHECK_OAL_AUDIO_ENABLED() \
38 if (blued_a2dp_interface == NULL) { \
39 BT_ERR("OAL, Audio Not Enabled"); \
40 return OAL_STATUS_NOT_READY; \
45 static void cb_audio_connection_state(btav_connection_state_t event, bt_bdaddr_t* bd_addr);
46 static void cb_audio_state(btav_audio_state_t state, bt_bdaddr_t* bd_addr);
48 const bt_interface_t * _bt_get_stack_interface(void);
49 static const btav_interface_t *blued_a2dp_interface = NULL;
51 static btav_callbacks_t blued_a2dp_cb = {
52 .size = sizeof(blued_a2dp_cb),
53 .connection_state_cb = cb_audio_connection_state,
54 .audio_state_cb = cb_audio_state,
55 .audio_config_cb = NULL
58 oal_status_t audio_enable(char *service_name , char *provider_name)
60 const bt_interface_t* blued_inf;
63 API_TRACE("Audio Enable");
65 if ((blued_inf = adapter_get_stack_interface()) == NULL) {
66 BT_ERR("Bluetooth module is not loaded");
67 return OAL_STATUS_NOT_READY;
70 if (blued_a2dp_interface != NULL) {
71 BT_WARN("A2DP Sink Interface is already initialized...");
72 return OAL_STATUS_ALREADY_DONE;
75 if ((blued_a2dp_interface = (const btav_interface_t *)blued_inf->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID)) == NULL) {
76 BT_ERR("OAL, Failed to get Bluetooth A2DP Interface");
77 return OAL_STATUS_INTERNAL_ERROR;
80 BT_DBG("Got profile interface");
81 if ((ret = blued_a2dp_interface->init(&blued_a2dp_cb)) != BT_STATUS_SUCCESS) {
82 BT_ERR("Failed to initialize Bluetooth A2DP, status: %s", status2string(ret));
83 blued_a2dp_interface = NULL;
84 return convert_to_oal_status(ret);
86 BT_DBG("OAL, Bluetooth audio interface initialised");
88 return OAL_STATUS_SUCCESS;
91 /* Audio deinit: Resets all the audio information
92 * Note: Adapter should be disabled before calling deinit
94 oal_status_t audio_disable(void)
96 API_TRACE("audio disable");
98 CHECK_OAL_AUDIO_ENABLED();
100 blued_a2dp_interface->cleanup();
101 blued_a2dp_interface = NULL;
103 return OAL_STATUS_SUCCESS;
106 oal_status_t audio_connect(bt_address_t *device_address)
108 int result = OAL_STATUS_SUCCESS;
112 API_TRACE("Audio connect");
114 CHECK_OAL_AUDIO_ENABLED();
115 OAL_CHECK_PARAMETER(device_address, return);
117 BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr) + 12);
119 /* Call connect function of Bluedroid*/
120 status = blued_a2dp_interface->connect((bt_bdaddr_t *)device_address);
121 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
122 BT_ERR("Connection could not be established, err: %s", status2string(status));;
123 result = convert_to_oal_status(status);
129 oal_status_t audio_disconnect(bt_address_t *device_address)
131 int result = OAL_STATUS_SUCCESS;
135 API_TRACE("Audio disconnect");
137 CHECK_OAL_AUDIO_ENABLED();
138 OAL_CHECK_PARAMETER(device_address, return);
140 BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr) + 12);
142 /* call Disconnect function of Bluedroid */
143 status = blued_a2dp_interface->disconnect((bt_bdaddr_t *)device_address);
144 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
145 BT_ERR("OAL, Disconnection failed err: %s", status2string(status));
146 result = convert_to_oal_status(status);
151 static void cb_audio_connection_state(btav_connection_state_t state, bt_bdaddr_t* bd_addr)
153 bt_address_t * event_data = NULL;
157 ret_if(bd_addr == NULL);
158 BT_INFO("state = %d, BT Address = %s", state, bdt_bd2str((bt_address_t*)bd_addr, &bdstr) + 12);
160 event_data = g_new0(bt_address_t, 1);
161 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
164 case BTAV_CONNECTION_STATE_CONNECTING: {
165 event = OAL_EVENT_AUDIO_CONNECTING;
168 case BTAV_CONNECTION_STATE_CONNECTED: {
169 event = OAL_EVENT_AUDIO_CONNECTED;
172 case BTAV_CONNECTION_STATE_DISCONNECTING: {
173 event = OAL_EVENT_AUDIO_DISCONNECTING;
176 case BTAV_CONNECTION_STATE_DISCONNECTED: {
177 event = OAL_EVENT_AUDIO_DISCONNECTED;
181 BT_INFO("Invalid state");
187 send_event_bda_trace(event, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
190 static void cb_audio_state(btav_audio_state_t state, bt_bdaddr_t* bd_addr)
194 ret_if(bd_addr == NULL);
195 BT_INFO("A2DP state = %d, BT Address = %s", state, bdt_bd2str((bt_address_t*)bd_addr, &bdstr) + 12);
197 if (state == BTAV_AUDIO_STATE_REMOTE_SUSPEND) {
198 BT_INFO("Audio Streaming Suspended");
199 } else if (state == BTAV_AUDIO_STATE_STOPPED) {
200 BT_INFO("###Audio Streaming Stopped");
201 bt_address_t * event_data = g_new0(bt_address_t, 1);
203 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
204 send_event_bda_trace(OAL_EVENT_AUDIO_STOPPED, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
205 } else if (state == BTAV_AUDIO_STATE_STARTED) {
206 BT_INFO("###Audio Streaming Startted");
207 bt_address_t * event_data = g_new0(bt_address_t, 1);
209 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
210 send_event_bda_trace(OAL_EVENT_AUDIO_STARTED, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
212 BT_ERR("Unknown state received:%d", (int)state);