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>
26 #include "oal-event.h"
27 #include "oal-internal.h"
28 #include "oal-common.h"
29 #include "oal-manager.h"
30 #include "oal-utils.h"
31 #include "oal-device-mgr.h"
33 static const bt_interface_t * blued_api;
35 void device_mgr_init(const bt_interface_t * stack_if)
40 void device_mgr_cleanup(void)
46 oal_status_t device_query_attributes(bt_address_t *addr)
51 CHECK_OAL_INITIALIZED();
53 OAL_CHECK_PARAMETER(addr, return);
55 API_TRACE("[%s]", bdt_bd2str(addr, &bdstr));
57 res = blued_api->get_remote_device_properties((bt_bdaddr_t *)addr);
58 if (res != BT_STATUS_SUCCESS) {
59 BT_ERR("get_remote_device_properties error: [%s]", status2string(res));
60 return convert_to_oal_status(res);
63 return OAL_STATUS_SUCCESS;
66 oal_status_t device_query_services(bt_address_t * addr)
71 CHECK_OAL_INITIALIZED();
73 OAL_CHECK_PARAMETER(addr, return);
75 API_TRACE("[%s]", bdt_bd2str(addr, &bdstr));
77 res = blued_api->get_remote_services((bt_bdaddr_t *)addr);
78 if (res != BT_STATUS_SUCCESS) {
79 BT_ERR("get_remote_services error: [%s]", status2string(res));
80 return convert_to_oal_status(res);
83 return OAL_STATUS_SUCCESS;
86 oal_status_t device_stop_query_sevices(bt_address_t * addr)
88 CHECK_OAL_INITIALIZED();
90 OAL_CHECK_PARAMETER(addr, return);
92 API_TRACE("Stop SDP search");
93 /* Currently no HAL Interface for Stopping Service Search */
94 return BT_STATUS_UNSUPPORTED;
97 oal_status_t device_set_alias(bt_address_t * addr, char * alias)
103 CHECK_OAL_INITIALIZED();
104 OAL_CHECK_PARAMETER(addr, return);
105 OAL_CHECK_PARAMETER(alias, return);
107 API_TRACE("%s ->Alias: %s", bdt_bd2str(addr, &bdstr), alias);
109 prop.type = BT_PROPERTY_REMOTE_FRIENDLY_NAME;
110 prop.len = strlen(alias);
112 res = blued_api->set_remote_device_property((bt_bdaddr_t*)addr, &prop);
113 if (res != BT_STATUS_SUCCESS) {
114 BT_ERR("set_remote_device_property error: [%s]", status2string(res));
115 BT_ERR("Alias: %s", alias);
116 return convert_to_oal_status(res);
119 return OAL_STATUS_SUCCESS;
122 oal_status_t device_create_bond(bt_address_t *addr, connection_type_e transport)
127 CHECK_OAL_INITIALIZED();
129 OAL_CHECK_PARAMETER(addr, return);
131 API_TRACE("[%s]", bdt_bd2str(addr, &bdstr));
133 res = blued_api->create_bond((bt_bdaddr_t *)addr, transport);
134 if (res != BT_STATUS_SUCCESS) {
135 BT_ERR("create_bond error: [%s]", status2string(res));
136 return convert_to_oal_status(res);
139 return OAL_STATUS_SUCCESS;
142 oal_status_t device_destroy_bond(bt_address_t * addr)
147 CHECK_OAL_INITIALIZED();
149 OAL_CHECK_PARAMETER(addr, return);
151 API_TRACE("[%s]", bdt_bd2str(addr, &bdstr));
153 res = blued_api->remove_bond((bt_bdaddr_t *)addr);
154 if (res != BT_STATUS_SUCCESS) {
155 BT_ERR("remove_bond error: [%s]", status2string(res));
156 return convert_to_oal_status(res);
159 return OAL_STATUS_SUCCESS;
162 oal_status_t device_stop_bond(bt_address_t * addr)
167 CHECK_OAL_INITIALIZED();
169 OAL_CHECK_PARAMETER(addr, return);
171 API_TRACE("[%s]", bdt_bd2str(addr, &bdstr));
173 res = blued_api->cancel_bond((bt_bdaddr_t *)addr);
174 if (res != BT_STATUS_SUCCESS) {
175 BT_ERR("cancel_bond error: [%s]", status2string(res));
176 return convert_to_oal_status(res);
179 return OAL_STATUS_SUCCESS;
182 oal_status_t device_accept_pin_request(bt_address_t * addr, const char * pin)
187 CHECK_OAL_INITIALIZED();
189 OAL_CHECK_PARAMETER(addr, return);
190 OAL_CHECK_PARAMETER(pin, return);
192 API_TRACE("[%s] PIN: %s", bdt_bd2str(addr, &bdstr), pin);
194 res = blued_api->pin_reply((bt_bdaddr_t *)addr, TRUE, strlen(pin), (bt_pin_code_t *)pin);
195 if (res != BT_STATUS_SUCCESS) {
196 BT_ERR("pin_reply error: [%s]", status2string(res));
197 BT_ERR("PIN: %s", pin);
198 return convert_to_oal_status(res);
201 return OAL_STATUS_SUCCESS;
204 oal_status_t device_reject_pin_request(bt_address_t * addr)
209 CHECK_OAL_INITIALIZED();
211 OAL_CHECK_PARAMETER(addr, return);
213 API_TRACE("[%s]", bdt_bd2str(addr, &bdstr));
215 res = blued_api->pin_reply((bt_bdaddr_t *)addr, FALSE, 0, NULL);
216 if (res != BT_STATUS_SUCCESS) {
217 BT_ERR("pin_reply error: [%s]", status2string(res));
218 return convert_to_oal_status(res);
221 return OAL_STATUS_SUCCESS;
224 oal_status_t device_accept_passkey_entry(bt_address_t * addr, uint32_t passkey)
229 CHECK_OAL_INITIALIZED();
231 OAL_CHECK_PARAMETER(addr, return);
233 API_TRACE("[%s] Passkey: %d", bdt_bd2str(addr, &bdstr), passkey);
235 res = blued_api->ssp_reply((bt_bdaddr_t *)addr, BT_SSP_VARIANT_PASSKEY_ENTRY, TRUE, passkey);
236 if (res != BT_STATUS_SUCCESS) {
237 BT_ERR("ssp_reply error: [%s]", status2string(res));
238 BT_ERR("Passkey: %d", passkey);
239 return convert_to_oal_status(res);
243 return OAL_STATUS_SUCCESS;
246 oal_status_t device_reject_passkey_entry(bt_address_t * addr)
251 CHECK_OAL_INITIALIZED();
253 OAL_CHECK_PARAMETER(addr, return);
255 API_TRACE("[%s]", bdt_bd2str(addr, &bdstr));
257 res = blued_api->ssp_reply((bt_bdaddr_t *)addr, BT_SSP_VARIANT_PASSKEY_ENTRY, FALSE, 0);
258 if (res != BT_STATUS_SUCCESS) {
259 BT_ERR("ssp_reply error: [%s]", status2string(res));
260 return convert_to_oal_status(res);
263 return OAL_STATUS_SUCCESS;
266 oal_status_t device_reply_passkey_confirmation(bt_address_t * addr, int accept)
271 CHECK_OAL_INITIALIZED();
273 OAL_CHECK_PARAMETER(addr, return);
275 API_TRACE("[%s] accept: %d", bdt_bd2str(addr, &bdstr), accept);
277 res = blued_api->ssp_reply((bt_bdaddr_t *)addr, BT_SSP_VARIANT_PASSKEY_CONFIRMATION, accept, 0);
278 if (res != BT_STATUS_SUCCESS) {
279 BT_ERR("ssp_reply error: [%s]", status2string(res));
280 BT_ERR("%d", accept);
281 return convert_to_oal_status(res);
284 return OAL_STATUS_SUCCESS;
288 oal_status_t device_reply_ssp_consent(bt_address_t * addr, int accept)
293 CHECK_OAL_INITIALIZED();
295 OAL_CHECK_PARAMETER(addr, return);
297 API_TRACE("[%s] %d", bdt_bd2str(addr, &bdstr), accept);
299 res = blued_api->ssp_reply((bt_bdaddr_t *)addr, BT_SSP_VARIANT_CONSENT, accept, 0);
300 if (res != BT_STATUS_SUCCESS) {
301 BT_ERR("ssp_reply error: [%s]", status2string(res));
302 BT_ERR("%d", accept);
303 return convert_to_oal_status(res);
306 return OAL_STATUS_SUCCESS;
309 oal_status_t device_reply_auth_request(bt_address_t * addr, oal_service_t service_type, int accept, int always)
314 CHECK_OAL_INITIALIZED();
316 OAL_CHECK_PARAMETER(addr, return);
318 API_TRACE("[%s] Accept: %d, always: %d, service_type: %d", bdt_bd2str(addr, &bdstr), accept, always, service_type);
320 res = blued_api->authorize_response((bt_bdaddr_t *)addr, service_type, accept, always);
321 if (res != BT_STATUS_SUCCESS) {
322 BT_ERR("authorize_response error: [%s]", status2string(res));
323 BT_ERR("Accept: [%d], always: [%d], service_type: [%d]", accept, always, service_type);
324 return convert_to_oal_status(res);
327 return OAL_STATUS_SUCCESS;
330 oal_status_t device_set_authorized(bt_address_t * addr, int authorize)
335 CHECK_OAL_INITIALIZED();
337 OAL_CHECK_PARAMETER(addr, return);
339 API_TRACE("[%s] %d", bdt_bd2str(addr, &bdstr), authorize);
341 res = blued_api->set_authorization((bt_bdaddr_t *)addr, authorize);
342 if (res != BT_STATUS_SUCCESS) {
343 BT_ERR("set_authorization error: [%s]", status2string(res));
344 BT_ERR("%d", authorize);
345 return convert_to_oal_status(res);
348 return OAL_STATUS_SUCCESS;
351 void cb_device_properties(bt_status_t status, bt_bdaddr_t *bd_addr,
352 int num_properties, bt_property_t *properties)
355 gpointer event_data = NULL;
356 remote_device_t *dev_info;
357 ble_adv_data_t adv_info;
361 BT_DBG("[%s]status: [%d] num properties [%d]", bdt_bd2str((bt_address_t*)bd_addr, &bdstr),
362 status, num_properties);
364 dev_info = g_new0(remote_device_t, 1);
365 memcpy(dev_info->address.addr, bd_addr->address, 6);
366 parse_device_properties(num_properties, properties, dev_info, &adv_info);
368 if (num_properties == 0) {
369 BT_ERR("!!Unexpected!! num properties is 0 status [%d]", status);
370 /* It is possible that app called get bonded device info for a device
371 which is not yet bonded or udner bonding, in such case, stack will return no properties.
372 It is also possible that after bonding is done, BT MW attempted to fetch
373 bonded device info, but due to internal stack error, 0 properties with status FAIL
374 are received from stack. In such cases, simply send the event to BT MW
375 and let it handle this event */
376 event_dev_properties_t *dev_props_event = g_new0(event_dev_properties_t, 1);
377 memcpy(&dev_props_event->device_info,
378 dev_info, sizeof(remote_device_t));
379 event_data = dev_props_event;
380 event = OAL_EVENT_DEVICE_PROPERTIES;
381 size = sizeof(event_dev_properties_t);
382 } else if (num_properties == 1) {
383 /* For one particular property a dedicated event to be sent */
384 switch(properties[0].type) {
385 case BT_PROPERTY_BDNAME:
386 event = OAL_EVENT_DEVICE_NAME;
387 event_data = dev_info;
388 send_event_trace(event, event_data, sizeof(remote_device_t),
389 (bt_address_t*)bd_addr, "Name: %s", dev_info->name);
391 case BT_PROPERTY_UUIDS: {
392 event_dev_services_t *services_info;
393 bt_uuid_t *uuids = (bt_uuid_t *) properties[0].val;
394 BT_INFO("Properties len [%d] event structure size [%d]", properties[0].len, sizeof(event_dev_services_t));
396 services_info = g_malloc(sizeof(event_dev_services_t) + properties[0].len);
397 services_info->address = dev_info->address;
398 memcpy(services_info->service_list, uuids, properties[0].len);
399 services_info->num = properties[0].len/sizeof(bt_uuid_t);
400 BT_INFO("Number of UUID [%d]", services_info->num);
401 event = OAL_EVENT_DEVICE_SERVICES;
402 event_data = services_info;
403 size = sizeof(event_dev_services_t) + properties[0].len;
408 BT_ERR("Single Property [%d] not handled", properties[0].type);
413 event_dev_properties_t *dev_props_event = g_new0(event_dev_properties_t, 1);
414 if (dev_info->type != DEV_TYPE_BREDR) {
417 BT_INFO("BLE Device");
418 /* BLE Single or DUAL mode found, so it should have Adv data */
419 dev_props_event->adv_len = adv_info.len;
420 if(dev_props_event->adv_len > 0)
421 memcpy(dev_props_event->adv_data,
422 adv_info.adv_data, adv_info.len);
424 for (i = 0; i < dev_props_event->adv_len; i++)
425 BT_INFO("Adv Data[%d] = [0x%x]",
426 i, dev_props_event->adv_data[i]);
427 memcpy(&dev_props_event->device_info,
428 dev_info, sizeof(remote_device_t));
430 BT_INFO("BREDR type Device");
431 memcpy(&dev_props_event->device_info,
432 dev_info, sizeof(remote_device_t));
435 event_data = dev_props_event;
436 event = OAL_EVENT_DEVICE_PROPERTIES;
437 size = sizeof(event_dev_properties_t);
440 send_event_bda_trace(event, event_data, size, (bt_address_t*)bd_addr);
443 void cb_device_bond_state_changed(bt_status_t status, bt_bdaddr_t *bd_addr,
444 bt_bond_state_t state)
446 bt_address_t * address = g_new0(bt_address_t, 1);
450 BT_DBG("status: %d, state: %d", status, state);
452 memcpy(address->addr, bd_addr->address, 6);
455 case BT_BOND_STATE_BONDED:
456 event = OAL_EVENT_DEVICE_BONDING_SUCCESS;
458 case BT_BOND_STATE_NONE:
459 /* Reaches both when bonding removed or bonding cancelled */
460 if (BT_STATUS_SUCCESS != status) {
461 event_dev_bond_failed_t * bond_fail_info = g_new0(event_dev_bond_failed_t, 1);
462 bond_fail_info->status = convert_to_oal_status(status);
463 bond_fail_info->address = *address;
464 size = sizeof(event_dev_bond_failed_t);
465 send_event_bda_trace(OAL_EVENT_DEVICE_BONDING_FAILED, bond_fail_info, size, (bt_address_t*)bd_addr);
469 event = OAL_EVENT_DEVICE_BONDING_REMOVED;
471 case BT_BOND_STATE_BONDING:
475 BT_ERR("Unexpected Bond state %d", state);
479 send_event_bda_trace(event, address, size, (bt_address_t*)bd_addr);
482 void cb_device_acl_state_changed(bt_status_t status, bt_bdaddr_t *bd_addr,
483 bt_acl_state_t state)
485 event_dev_conn_status_t * conn_status = g_new0(event_dev_conn_status_t, 1);
486 //bt_address_t * address = g_new0(bt_address_t, 1);
490 BT_DBG("ACL State:%d, state: %d", status, state);
492 memcpy(conn_status->address.addr, bd_addr->address, 6);
494 if (BT_STATUS_SUCCESS != status) {
495 /* At present only timeout will cause non-success status, later we can add more */
496 conn_status->status = OAL_STATUS_CONN_TIMEOUT;
497 BT_ERR("ACL State Error:%d, state: %d", status, state);
499 conn_status->status = OAL_STATUS_SUCCESS;
501 memcpy(conn_status->address.addr, bd_addr->address, 6);
503 case BT_ACL_STATE_CONNECTED:
504 event = OAL_EVENT_DEVICE_ACL_CONNECTED;
505 conn_status->status = OAL_STATUS_SUCCESS;
507 case BT_ACL_STATE_DISCONNECTED:
508 event = OAL_EVENT_DEVICE_ACL_DISCONNECTED;
511 BT_ERR("Unexpected ACL state %d", state);
516 size = sizeof(event_dev_conn_status_t);
517 send_event_bda_trace(event, conn_status, size, (bt_address_t*)bd_addr);
520 void cb_device_pin_request(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t device_class)
522 remote_device_t * dev_info = g_new0(remote_device_t, 1);
526 memcpy(dev_info->address.addr, bd_addr->address, 6);
527 g_strlcpy(dev_info->name, (const gchar *)bdname->name, BT_DEVICE_NAME_LENGTH_MAX);
528 dev_info->cod = device_class;
529 size = sizeof(remote_device_t);
531 send_event_bda_trace(OAL_EVENT_DEVICE_PIN_REQUEST, dev_info, size, (bt_address_t*)bd_addr);
534 void cb_device_ssp_request(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t device_class,
535 bt_ssp_variant_t pairing_variant, uint32_t pass_key)
538 gpointer event_data = NULL;
542 switch(pairing_variant) {
543 case BT_SSP_VARIANT_PASSKEY_ENTRY:
545 remote_device_t * dev_info = g_new0(remote_device_t, 1);
546 memcpy(dev_info->address.addr, bd_addr->address, 6);
547 g_strlcpy(dev_info->name, (const gchar *)bdname->name, BT_DEVICE_NAME_LENGTH_MAX);
548 dev_info->cod = device_class;
549 event = OAL_EVENT_DEVICE_PASSKEY_ENTRY_REQUEST;
550 event_data = dev_info;
551 size = sizeof(remote_device_t);
554 case BT_SSP_VARIANT_PASSKEY_NOTIFICATION:
556 event_dev_passkey_t * passkey_data = g_new0(event_dev_passkey_t, 1);
558 memcpy(passkey_data->device_info.address.addr, bd_addr->address, 6);
559 g_strlcpy(passkey_data->device_info.name, (const gchar *)bdname->name, BT_DEVICE_NAME_LENGTH_MAX);
560 passkey_data->device_info.cod = device_class;
561 passkey_data->pass_key = pass_key;
562 event = OAL_EVENT_DEVICE_PASSKEY_DISPLAY;
563 event_data = passkey_data;
564 size = sizeof(event_dev_passkey_t);
567 case BT_SSP_VARIANT_PASSKEY_CONFIRMATION:
569 event_dev_passkey_t * passkey_data = g_new0(event_dev_passkey_t, 1);
571 memcpy(passkey_data->device_info.address.addr, bd_addr->address, 6);
572 g_strlcpy(passkey_data->device_info.name, (const gchar *)bdname->name, BT_DEVICE_NAME_LENGTH_MAX);
573 passkey_data->device_info.cod = device_class;
574 passkey_data->pass_key = pass_key;
575 event = OAL_EVENT_DEVICE_PASSKEY_CONFIRMATION_REQUEST;
576 event_data = passkey_data;
577 size = sizeof(event_dev_passkey_t);
580 case BT_SSP_VARIANT_CONSENT:
582 remote_device_t * dev_info = g_new0(remote_device_t, 1);
584 memcpy(dev_info->address.addr, bd_addr->address, 6);
585 g_strlcpy(dev_info->name, (const gchar *)bdname->name, BT_DEVICE_NAME_LENGTH_MAX);
586 dev_info->cod = device_class;
587 event = OAL_EVENT_DEVICE_SSP_CONSENT_REQUEST;
588 event_data = dev_info;
589 size = sizeof(remote_device_t);
594 BT_ERR("Unhandled SSP request [%d]", pairing_variant);
598 send_event_bda_trace(event, event_data, size, (bt_address_t*)bd_addr);
601 void cb_device_authorize_request(bt_bdaddr_t *bd_addr, bt_service_id_t service_d)
603 event_dev_authorize_req_t * auth_req = g_new0(event_dev_authorize_req_t, 1);
605 BT_INFO("service_d: %d", service_d);
606 memcpy(auth_req->address.addr, bd_addr->address, 6);
607 auth_req->service_id = service_d;
609 send_event_bda_trace(OAL_EVENT_DEVICE_AUTHORIZE_REQUEST, auth_req, sizeof(event_dev_authorize_req_t), (bt_address_t*)bd_addr);
612 void cb_device_trust_state_changed(bt_bdaddr_t *bd_addr, bt_device_trust_state_t trusted)
615 event_dev_trust_t * trust_val = g_new0(event_dev_trust_t, 1);
617 if (trusted == BT_DEVICE_TRUSTED) {
618 BT_INFO("Device is Trusted");
619 event = OAL_EVENT_DEVICE_TRUSTED;
621 BT_INFO("Device is Un Trusted");
622 event = OAL_EVENT_DEVICE_UNTRUSTED;
624 memcpy(trust_val->address.addr, bd_addr->address, 6);
625 trust_val->status = OAL_STATUS_SUCCESS;
626 send_event_bda_trace(event, trust_val, sizeof(event_dev_trust_t), (bt_address_t*)bd_addr);