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.
24 #include <bluetooth.h>
27 #include "oal-event.h"
28 #include "oal-internal.h"
29 #include "oal-common.h"
30 #include "oal-manager.h"
31 #include "oal-utils.h"
34 #define CHECK_OAL_HDP_ENABLED() \
36 if (hdp_api == NULL) { \
37 BT_ERR("HDP Not Enabled"); \
49 static void hdp_app_reg_state_cb(int app_id, bthl_app_reg_state_t state);
50 static void hdp_channel_state_cb(int app_id, bt_bdaddr_t *bd_addr,
51 int mdep_cfg_index, int channel_id, bthl_channel_state_t state, int fd);
53 static bthl_callbacks_t sBluetoothHdpCallbacks = {
54 sizeof(sBluetoothHdpCallbacks),
59 static const bthl_interface_t *hdp_api;
60 static GSList *app_list;
62 static oal_hdp_app_data_t *__get_hdp_app_data(int app_id)
66 for (l = app_list; l != NULL; l = g_slist_next(l)) {
67 oal_hdp_app_data_t *app = l->data;
69 if (app && (app->app_id == app_id))
76 static void __free_hdp_app_data(int app_id)
78 oal_hdp_app_data_t *app = __get_hdp_app_data(app_id);
81 BT_ERR("No app found with id: %d", app_id);
85 app_list = g_slist_remove(app_list, app);
89 static void hdp_app_reg_state_cb(int app_id, bthl_app_reg_state_t state)
91 event_hdp_app_reg_t *event_data = g_new0(event_hdp_app_reg_t, 1);
94 BT_DBG("app_id: %d, state: %d", app_id, state);
97 case BTHL_APP_REG_STATE_REG_SUCCESS:
98 event = OAL_EVENT_HDP_APP_REGISTERED;
99 event_data->status = OAL_STATUS_SUCCESS;
101 case BTHL_APP_REG_STATE_REG_FAILED:
102 event = OAL_EVENT_HDP_APP_REGISTERED;
103 event_data->status = OAL_STATUS_INTERNAL_ERROR;
104 __free_hdp_app_data(app_id);
106 case BTHL_APP_REG_STATE_DEREG_SUCCESS:
107 event = OAL_EVENT_HDP_APP_UNREGISTERED;
108 event_data->status = OAL_STATUS_SUCCESS;
109 __free_hdp_app_data(app_id);
111 case BTHL_APP_REG_STATE_DEREG_FAILED:
112 event = OAL_EVENT_HDP_APP_UNREGISTERED;
113 event_data->status = OAL_STATUS_INTERNAL_ERROR;
116 BT_ERR("Unknown state:%d received", state);
120 event_data->app_id = app_id;
121 send_event(event, event_data, sizeof(event_hdp_app_reg_t));
124 static void hdp_channel_state_cb(int app_id, bt_bdaddr_t *bd_addr,
125 int mdep_cfg_index, int channel_id, bthl_channel_state_t state, int fd)
127 event_hdp_channel_conn_t *event_data;
129 oal_hdp_app_data_t *app;
131 BT_DBG("app_id: %d, channel_id:%d, state:%d, fd:%d", app_id, channel_id, state, fd);
133 app = __get_hdp_app_data(app_id);
135 BT_ERR("No app found with app_id: %d", app_id);
140 case BTHL_CONN_STATE_CONNECTING:
141 BT_DBG("BTHL_CONN_STATE_CONNECTING");
143 case BTHL_CONN_STATE_DISCONNECTING:
144 BT_DBG("BTHL_CONN_STATE_DISCONNECTING");
146 case BTHL_CONN_STATE_CONNECTED:
147 BT_DBG("BTHL_CONN_STATE_CONNECTED");
148 event = OAL_EVENT_HDP_CHANNEL_CONNECTED;
150 case BTHL_CONN_STATE_DISCONNECTED:
151 BT_DBG("BTHL_CONN_STATE_DISCONNECTED");
152 event = OAL_EVENT_HDP_CHANNEL_DESTROYED;
154 case BTHL_CONN_STATE_DESTROYED:
155 BT_DBG("BTHL_CONN_STATE_DESTROYED");
156 event = OAL_EVENT_HDP_CHANNEL_DESTROYED;
159 BT_ERR("Unknown stat: %d", state);
163 event_data = g_new0(event_hdp_channel_conn_t, 1);
165 event_data->app_id = app_id;
166 event_data->channel_id = channel_id;
167 event_data->ch_type = app->channel_type;
168 memcpy(event_data->address.addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
170 send_event_bda_trace(event, event_data,
171 sizeof(event_hdp_channel_conn_t), (bt_address_t*)bd_addr);
174 oal_status_t hdp_init(void)
176 const bt_interface_t *blued_api;
181 if (hdp_api != NULL) {
182 BT_WARN("HID Interface is already initialized...");
183 return OAL_STATUS_ALREADY_DONE;
186 blued_api = adapter_get_stack_interface();
187 if (blued_api == NULL) {
188 BT_ERR("Stack is not initialized");
189 return OAL_STATUS_NOT_READY;
192 hdp_api = (const bthl_interface_t *)blued_api->get_profile_interface(BT_PROFILE_HEALTH_ID);
193 if (hdp_api == NULL) {
194 BT_ERR("HDP interface failed");
195 return OAL_STATUS_INTERNAL_ERROR;
198 if ((ret = hdp_api->init(&sBluetoothHdpCallbacks)) != BT_STATUS_SUCCESS) {
199 BT_ERR("HDP Init failed: %s", status2string(ret));
202 return convert_to_oal_status(ret);
205 return OAL_STATUS_SUCCESS;
208 oal_status_t hdp_cleanup(void)
210 GSList *l = app_list;
214 CHECK_OAL_HDP_ENABLED();
221 for (l = app_list; NULL != l;) {
222 oal_hdp_app_data_t *app = l->data;
225 __free_hdp_app_data(app->app_id);
232 return OAL_STATUS_SUCCESS;
235 int hdp_register_application(oal_hdp_role_t role,
236 oal_channel_type_t channel_type, const char *name, int data_type)
240 bthl_mdep_role_t mdep_role;
241 bthl_channel_type_t ch_type;
242 bthl_reg_param_t *reg_param;
243 oal_hdp_app_data_t *app_data;
247 CHECK_OAL_HDP_ENABLED();
250 case OAL_HDP_ROLE_SOURCE:
251 mdep_role = BTHL_MDEP_ROLE_SOURCE;
253 case OAL_HDP_ROLE_SINK:
254 mdep_role = BTHL_MDEP_ROLE_SINK;
257 BT_ERR("Unknown role:%d", role);
261 switch (channel_type) {
262 case OAL_CHANNEL_TYPE_RELIABLE:
263 ch_type = BTHL_CHANNEL_TYPE_RELIABLE;
265 case OAL_CHANNEL_TYPE_STREAMING:
266 ch_type = BTHL_CHANNEL_TYPE_STREAMING;
268 case OAL_CHANNEL_TYPE_ANY:
269 ch_type = BTHL_CHANNEL_TYPE_ANY;
272 BT_ERR("Unknown channel_type:%d", channel_type);
276 reg_param = g_new0(bthl_reg_param_t, 1);
277 reg_param->application_name = name;
278 reg_param->number_of_mdeps = 1;
279 reg_param->mdep_cfg = g_new0(bthl_mdep_cfg_t, 1);
280 reg_param->mdep_cfg->mdep_role = mdep_role;
281 reg_param->mdep_cfg->data_type = data_type;
282 reg_param->mdep_cfg->channel_type = ch_type;
284 ret = hdp_api->register_application(reg_param, &app_id);
285 g_free(reg_param->mdep_cfg);
288 if (ret != BT_STATUS_SUCCESS || 0 > app_id) {
289 BT_ERR("HDP register_application failed: %s", status2string(ret));
293 app_data = g_new0(oal_hdp_app_data_t, 1);
294 app_data->app_id = app_id;
295 app_data->role = role;
296 app_data->data_type = data_type;
297 app_data->channel_type = channel_type;
299 app_list = g_slist_append(app_list, app_data);
304 oal_status_t hdp_unregister_application(int app_id)
310 CHECK_OAL_HDP_ENABLED();
312 ret = hdp_api->unregister_application(app_id);
313 if (ret != BT_STATUS_SUCCESS) {
314 BT_ERR("HDP unregister_application failed: %s", status2string(ret));
315 return convert_to_oal_status(ret);
318 return OAL_STATUS_SUCCESS;
321 int hdp_connect_channel(int app_id, bt_address_t *address)
329 CHECK_OAL_HDP_ENABLED();
331 ret = hdp_api->connect_channel(app_id, (bt_bdaddr_t*)address, mdep_index, &channel_id);
332 if (BT_STATUS_SUCCESS != ret || 0 > channel_id) {
333 BT_ERR("HDP connect_channel failed: %s", status2string(ret));
340 oal_status_t hdp_disconnect_channel(int channel_id)
346 CHECK_OAL_HDP_ENABLED();
348 ret = hdp_api->destroy_channel(channel_id);
349 if (BT_STATUS_SUCCESS != ret) {
350 BT_ERR("HDP destroy_channel failed: %s", status2string(ret));
351 return convert_to_oal_status(ret);
354 return OAL_STATUS_SUCCESS;