2 * Open Adaptation Layer (OAL)
4 * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
6 * Contact: Anupam Roy <anupam.r@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-common.h"
34 #include "oal-internal.h"
36 #include "oal-utils.h"
38 #define CHECK_OAL_HF_ENABLED() \
40 if (blued_hfp_interface == NULL) { \
41 BT_ERR("OAL, HFP Not Enabled"); \
42 return OAL_STATUS_NOT_READY; \
46 static void cb_hfp_connection_state(bthf_connection_state_t state, bt_bdaddr_t *bd_addr);
47 static void cb_hfp_audio_connection_state(bthf_audio_state_t state, bt_bdaddr_t *bd_addr);
49 const bt_interface_t * _bt_get_stack_interface(void);
50 static const bthf_interface_t *blued_hfp_interface = NULL;
52 static bthf_callbacks_t blued_hf_cb = {
53 .size = sizeof(blued_hf_cb),
54 .connection_state_cb = cb_hfp_connection_state,
55 .audio_state_cb = cb_hfp_audio_connection_state,
57 .answer_call_cmd_cb = NULL,
58 .hangup_call_cmd_cb = NULL,
59 .volume_cmd_cb = NULL,
60 .dial_call_cmd_cb = NULL,
69 .unknown_at_cmd_cb = NULL,
70 .key_pressed_cmd_cb = NULL
73 oal_status_t hfp_enable(int max_hf_clients_supported)
75 const bt_interface_t* blued_inf;
78 API_TRACE("HF Enable");
80 if (max_hf_clients_supported > 1)
81 return OAL_STATUS_NOT_SUPPORT;
83 if ((blued_inf = adapter_get_stack_interface()) == NULL) {
84 BT_ERR("Bluetooth module is not loaded");
85 return OAL_STATUS_NOT_READY;
88 if (blued_hfp_interface != NULL) {
89 BT_WARN("HF Interface is already initialized...");
90 return OAL_STATUS_ALREADY_DONE;
93 if ((blued_hfp_interface = (const bthf_interface_t *)blued_inf->get_profile_interface(BT_PROFILE_HANDSFREE_ID)) == NULL) {
94 BT_ERR("OAL, Failed to get Bluetooth HF Interface");
95 return OAL_STATUS_INTERNAL_ERROR;
98 BT_DBG("Got profile interface");
99 if ((ret = blued_hfp_interface->init(&blued_hf_cb, 1)) != BT_STATUS_SUCCESS) {
100 BT_ERR("Failed to initialize Bluetooth HF, status: %s", status2string(ret));
101 blued_hfp_interface = NULL;
102 return convert_to_oal_status(ret);
104 BT_DBG("OAL, Bluetooth HF interface initialised");
106 return OAL_STATUS_SUCCESS;
109 /* HF deinit: Resets all the HF information
110 * Note: Adapter should be disabled before calling deinit
112 oal_status_t hfp_disable(void)
114 API_TRACE("HF disable");
115 CHECK_OAL_HF_ENABLED();
117 blued_hfp_interface->cleanup();
118 blued_hfp_interface = NULL;
120 return OAL_STATUS_SUCCESS;
123 void hfp_cleanup(void)
125 API_TRACE("HF Cleanup");
126 blued_hfp_interface = NULL;
129 oal_status_t hfp_connect(bt_address_t *device_address)
131 int result = OAL_STATUS_SUCCESS;
134 API_TRACE("HF Connect");
136 CHECK_OAL_HF_ENABLED();
137 OAL_CHECK_PARAMETER(device_address, return);
139 BT_INFO("BT HF Address: %s", bdt_bd2str(device_address, &bdstr) + 12);
140 /* Call connect function of Bluedroid*/
141 status = blued_hfp_interface->connect((bt_bdaddr_t *)device_address);
142 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
143 BT_ERR("Connection could not be established, err: %s", status2string(status));;
144 result = convert_to_oal_status(status);
149 oal_status_t hfp_disconnect(bt_address_t *device_address)
151 int result = OAL_STATUS_SUCCESS;
154 API_TRACE("HF Disconnect");
156 CHECK_OAL_HF_ENABLED();
157 OAL_CHECK_PARAMETER(device_address, return);
159 BT_INFO("BT HF Address: %s", bdt_bd2str(device_address, &bdstr) + 12);
160 /* call Disconnect function of Bluedroid */
161 status = blued_hfp_interface->disconnect((bt_bdaddr_t *)device_address);
162 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
163 BT_ERR("OAL, Disconnection failed err: %s", status2string(status));
164 result = convert_to_oal_status(status);
169 oal_status_t hfp_connect_audio(bt_address_t *device_address)
172 int result = OAL_STATUS_SUCCESS;
174 API_TRACE("Connect HF Audio");
176 CHECK_OAL_HF_ENABLED();
177 OAL_CHECK_PARAMETER(device_address, return);
179 BT_INFO("BT HF Address: %s", bdt_bd2str(device_address, &bdstr) + 12);
180 status = blued_hfp_interface->connect_audio((bt_bdaddr_t *)device_address);
182 if (status != BT_STATUS_SUCCESS) {
183 BT_ERR("Start stream failed err: %s", status2string(status));
184 result = convert_to_oal_status(status);
189 oal_status_t hfp_disconnect_audio(bt_address_t *device_address)
192 int result = OAL_STATUS_SUCCESS;
194 API_TRACE("DisConnect HF Audio");
196 CHECK_OAL_HF_ENABLED();
198 OAL_CHECK_PARAMETER(device_address, return);
200 BT_INFO("BT HF Address: %s", bdt_bd2str(device_address, &bdstr) + 12);
201 status = blued_hfp_interface->disconnect_audio((bt_bdaddr_t *)device_address);
203 if (status != BT_STATUS_SUCCESS) {
204 BT_ERR("Start stream failed err: %s", status2string(status));
205 result = convert_to_oal_status(status);
210 static void cb_hfp_connection_state(bthf_connection_state_t state, bt_bdaddr_t *bd_addr)
214 bt_address_t * event_data = NULL;
216 if (bd_addr == NULL) {
217 BT_ERR("Address is NULL");
221 event_data = g_new0(bt_address_t, 1);
222 if (event_data == NULL) {
223 BT_ERR("failed to allocate event_data");
226 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
228 BT_INFO("HFP Profile state = [%d], BT Address = [%s]", state, bdt_bd2str((bt_address_t*)bd_addr, &bdstr) + 12);
230 case BTHF_CONNECTION_STATE_DISCONNECTED: {
231 event_type = OAL_EVENT_HFP_DISCONNECTED;
234 case BTHF_CONNECTION_STATE_CONNECTING: {
235 event_type = OAL_EVENT_HFP_CONNECTING;
238 case BTHF_CONNECTION_STATE_CONNECTED: {
239 event_type = OAL_EVENT_HFP_CONNECTED;
242 case BTHF_CONNECTION_STATE_DISCONNECTING: {
243 event_type = OAL_EVENT_HFP_DISCONNECTING;
247 BT_INFO("Invalid state");
252 send_event_bda_trace(event_type, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
255 static void cb_hfp_audio_connection_state(bthf_audio_state_t state, bt_bdaddr_t *bd_addr)
259 bt_address_t * event_data = NULL;
261 if (bd_addr == NULL) {
262 BT_ERR("Address is NULL");
266 event_data = g_new0(bt_address_t, 1);
267 if (event_data == NULL) {
268 BT_ERR("failed to allocate event_data");
271 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
273 BT_INFO("HFP Audio state = [%d], BT Address = [%s]", state, bdt_bd2str((bt_address_t*)bd_addr, &bdstr) + 12);
276 case BTHF_AUDIO_STATE_DISCONNECTED: {
277 BT_INFO("HFP Audio(SCO) DisConnected");
278 event_type = OAL_EVENT_HFP_AUDIO_DISCONNECTED;
281 case BTHF_AUDIO_STATE_CONNECTED: {
282 BT_INFO("HFP Audio(SCO) Connected");
283 event_type = OAL_EVENT_HFP_AUDIO_CONNECTED;
286 case BTHF_AUDIO_STATE_CONNECTING: {
287 BT_INFO("HFP Audio(SCO) Connecting");
288 event_type = OAL_EVENT_HFP_AUDIO_CONNECTING;
291 case BTHF_AUDIO_STATE_DISCONNECTING: {
292 BT_INFO("HFP Audio(SCO) DisConnecting");
293 event_type = OAL_EVENT_HFP_AUDIO_DISCONNECTING;
297 BT_INFO("Invalid state");
302 send_event_bda_trace(event_type, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);