Add DA logic to fix le scan fail issue
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / oal-a2dp-sink.c
1 /*
2  * Open Adaptation Layer (OAL)
3  *
4  * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
5  *
6  * Contact: Nilesh Trimbake <t.shripati@samsung.com>
7  *
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
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <stdio.h>
23 #include <sys/un.h>
24 #include <sys/socket.h>
25 #include <sys/errno.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <dlog.h>
29
30 #include <bluetooth.h>
31 #include <bt_av.h>
32
33 #include "oal-internal.h"
34 #include "oal-a2dp-sink.h"
35 #include "oal-utils.h"
36 #include "oal-common.h"
37
38 #define CHECK_OAL_SINK_ENABLED() \
39         do { \
40                 if (blued_a2dp_sink_interface == NULL) { \
41                         BT_ERR("OAL, Audio Not Enabled"); \
42                         return OAL_STATUS_NOT_READY; \
43                 } \
44         } while (0)
45
46
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);
49
50 const bt_interface_t * _bt_get_stack_interface(void);
51 static const btav_interface_t *blued_a2dp_sink_interface = NULL;
52
53 static btav_callbacks_t blued_a2dp_sink_cb = {
54         .size = sizeof(blued_a2dp_sink_cb),
55         .connection_state_cb = cb_a2dp_sink_connection_state,
56         .audio_state_cb = cb_a2dp_sink_audio_state,
57         .audio_config_cb = NULL
58 };
59
60 oal_status_t a2dp_sink_enable(char *service_name , char *provider_name)
61 {
62         const bt_interface_t* blued_inf;
63         int ret;
64
65         API_TRACE("Audio Sink Enable");
66
67         if ((blued_inf = adapter_get_stack_interface()) == NULL) {
68                 BT_ERR("Bluetooth module is not loaded");
69                 return OAL_STATUS_NOT_READY;
70         }
71
72         if (blued_a2dp_sink_interface != NULL) {
73                 BT_WARN("A2DP Sink Interface is already initialized...");
74                 return OAL_STATUS_ALREADY_DONE;
75         }
76
77         if ((blued_a2dp_sink_interface = (const btav_interface_t *)blued_inf->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_SINK_ID)) == NULL) {
78                 BT_ERR("OAL, Failed to get Bluetooth A2DP Sink Interface");
79                 return OAL_STATUS_INTERNAL_ERROR;
80         }
81
82         BT_DBG("Got profile interface");
83         if ((ret = blued_a2dp_sink_interface->init(&blued_a2dp_sink_cb)) != BT_STATUS_SUCCESS) {
84                 BT_ERR("Failed to initialize Bluetooth A2DP, status: %s", status2string(ret));
85                 blued_a2dp_sink_interface = NULL;
86                 return convert_to_oal_status(ret);
87         }
88         BT_DBG("OAL, Bluetooth audio interface initialised");
89
90         return OAL_STATUS_SUCCESS;
91 }
92
93 /* Audio deinit: Resets all the audio information
94  * Note: Adapter should be disabled before calling deinit
95  * */
96 oal_status_t a2dp_sink_disable(void)
97 {
98
99         API_TRACE("Audio Sink Disable");
100
101         CHECK_OAL_SINK_ENABLED();
102
103         blued_a2dp_sink_interface->cleanup();
104         blued_a2dp_sink_interface = NULL;
105
106         return OAL_STATUS_SUCCESS;
107 }
108
109 oal_status_t a2dp_sink_connect(bt_address_t *device_address)
110 {
111         int result = OAL_STATUS_SUCCESS;
112         bt_status_t status;
113         bdstr_t bdstr;
114
115         API_TRACE();
116
117         CHECK_OAL_SINK_ENABLED();
118         OAL_CHECK_PARAMETER(device_address, return);
119
120         BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
121
122         /* Call connect function of Bluedroid*/
123         status = blued_a2dp_sink_interface->connect((bt_bdaddr_t *)device_address);
124         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
125                 BT_ERR("Connection could not be established, err: %s", status2string(status));;
126                 result =  convert_to_oal_status(status);
127         }
128         return result;
129 }
130
131
132 oal_status_t a2dp_sink_disconnect(bt_address_t *device_address)
133 {
134         int result = OAL_STATUS_SUCCESS;
135         bdstr_t bdstr;
136         bt_status_t status;
137
138         API_TRACE();
139
140         CHECK_OAL_SINK_ENABLED();
141         OAL_CHECK_PARAMETER(device_address, return);
142
143         BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
144
145         /* call Disconnect function of Bluedroid */
146         status = blued_a2dp_sink_interface->disconnect((bt_bdaddr_t *)device_address);
147         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
148                 BT_ERR("OAL, Disconnection failed err: %s", status2string(status));
149                 result =  convert_to_oal_status(status);
150         }
151         return result;
152 }
153
154 static void cb_a2dp_sink_connection_state(btav_connection_state_t state, bt_bdaddr_t* bd_addr)
155 {
156         bt_address_t * event_data = NULL;
157         bdstr_t bdstr;
158         oal_event_t event;
159
160         ret_if(bd_addr == NULL);
161         BT_INFO("state = %d,  BT Address = %s", state, bdt_bd2str((bt_address_t*)bd_addr, &bdstr));
162
163         event_data = g_new0(bt_address_t, 1);
164         memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
165
166         switch (state) {
167                 case BTAV_CONNECTION_STATE_CONNECTING: {
168                         event = OAL_EVENT_A2DP_SINK_CONNECTING;
169                         break;
170                 }
171                 case BTAV_CONNECTION_STATE_CONNECTED: {
172                         event = OAL_EVENT_A2DP_SINK_CONNECTED;
173                         break;
174                 }
175                 case BTAV_CONNECTION_STATE_DISCONNECTING: {
176                         event = OAL_EVENT_A2DP_SINK_DISCONNECTING;
177                         break;
178                 }
179                 case BTAV_CONNECTION_STATE_DISCONNECTED: {
180                         event = OAL_EVENT_A2DP_SINK_DISCONNECTED;
181                         break;
182                 }
183                 default: {
184                         BT_INFO("Invalid state");
185                         g_free(event_data);
186                         event_data = NULL;
187                         return;
188                 }
189         }
190         send_event_bda_trace(event, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
191 }
192
193 static void cb_a2dp_sink_audio_state(btav_audio_state_t state, bt_bdaddr_t* bd_addr)
194 {
195         bdstr_t bdstr;
196
197         ret_if(bd_addr == NULL);
198         BT_INFO("A2DP state = %d,  BT Address = %s", state, bdt_bd2str((bt_address_t*)bd_addr, &bdstr));
199
200         //stream_state = state; //removed by Moon
201
202         if (state == BTAV_AUDIO_STATE_REMOTE_SUSPEND) {
203                 BT_INFO("Audio Streaming Suspended");
204         } else if (state == BTAV_AUDIO_STATE_STOPPED) {
205                 BT_INFO("###Audio Streaming Stopped");
206                 bt_address_t * event_data = g_new0(bt_address_t, 1);
207
208                 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
209                 send_event_bda_trace(OAL_EVENT_AUDIO_STOPPED, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
210         } else if (state == BTAV_AUDIO_STATE_STARTED) {
211                 BT_INFO("###Audio Streaming Startted");
212                 bt_address_t * event_data = g_new0(bt_address_t, 1);
213
214                 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
215                 send_event_bda_trace(OAL_EVENT_AUDIO_STARTED, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
216         } else {
217                 BT_ERR("Unknown state received:%d", (int)state);
218         }
219 }