4 * Copyright (c) 2015 -2016 Samsung Electronics Co., Ltd All Rights Reserved.
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 <hardware/bluetooth.h>
25 #include <hardware/bt_gatt.h>
34 #include <vconf-keys.h>
35 #include <vconf-internal-radio-keys.h>
42 #include "bt-hal-log.h"
43 #include "bt-hal-msg.h"
44 #include "bt-hal-utils.h"
46 #include <bt-hal-adapter-dbus-handler.h>
47 #include <bt-hal-dbus-common-utils.h>
49 #include "bt-hal-gatt-server.h"
55 } bt_adapter_le_feature_info_t;
59 gboolean is_multi_adv; /* To be removed once we complete descope Legacy Adv */
61 gboolean is_advertising;
64 } bt_adapter_le_adv_slot_t;
66 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
67 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
74 } bt_hal_adv_event_data_t;
77 #define BT_HAL_ADV_CONNECTABLE 0x00 /* ADV_IND */
78 #define BT_HAL_ADV_CONNECTABLE_DIRECT_HIGH 0x01 /* ADV_DIRECT_IND, high duty cycle */
79 #define BT_HAL_ADV_SCANNABLE 0x02 /* ADV_SCAN_IND */
80 #define BT_HAL_ADV_NON_CONNECTABLE 0x03 /* ADV_NONCOND_IND */
81 #define BT_HAL_ADV_CONNECTABLE_DIRECT_LOW 0x04 /* ADV_DIRECT_IND, low duty cycle */
83 #define BT_HAL_ADV_INTERVAL_MIN 20 /* msec */
84 #define BT_HAL_ADV_INTERVAL_MAX 10240
85 #define BT_HAL_ADV_INTERVAL_SPLIT 0.625
86 #define BT_HAL_DEFAULT_ADV_MIN_INTERVAL 500
87 #define BT_HAL_DEFAULT_ADV_MAX_INTERVAL 500
88 #define BT_HAL_ADV_FILTER_POLICY_DEFAULT 0x00
89 #define BT_HAL_ADV_TYPE_DEFAULT 0x00
90 #define BT_HAL_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
92 /* Multi Advertisement callback event */
93 #define BT_HAL_MULTI_ADV_ENB_EVT 1
94 #define BT_HAL_MULTI_ADV_DISABLE_EVT 2
95 #define BT_HAL_MULTI_ADV_PARAM_EVT 3
96 #define BT_HAL_MULTI_ADV_DATA_EVT 4
97 #define BT_HAL_MULTI_ADV_UPDATE_EVT 5
98 #define BT_HAL_LEGACY_ADV_STATUS 6
100 handle_stack_msg gatt_le_event_cb;
102 /* Forward declarations */
103 static gboolean __bt_hal_is_factory_test_mode(void);
104 static void __bt_hal_free_le_adv_slot(void);
105 static gboolean __bt_hal_adv_event_cb(gpointer param);
108 /* Enable LE Adapter */
109 int _bt_hal_le_enable(void)
111 return _bt_hal_dbus_enable_le();
114 /* Disable LE Adapter */
115 int _bt_hal_le_disable(void)
117 return _bt_hal_dbus_disable_le();
121 static void __bt_hal_free_le_adv_slot(void)
125 if (le_adv_slot == NULL)
128 for (i = 0; i < le_feature_info.adv_inst_max; i++)
129 memset(&le_adv_slot[i], 0x00, sizeof(bt_adapter_le_adv_slot_t));
135 void _bt_hal_unregister_adv_slot_owner(int slot_id)
137 if (le_adv_slot == NULL)
139 INFO("Unregister Adv Slot [%d]", slot_id);
140 memset(&le_adv_slot[slot_id], 0x00, sizeof(bt_adapter_le_adv_slot_t));
143 int _bt_hal_get_adv_slot_adv_handle(int slot_id)
145 if (le_adv_slot == NULL)
148 return le_adv_slot[slot_id].adv_handle;
151 gboolean _bt_hal_is_advertising_in_slot(int slot)
153 return le_adv_slot[slot].is_advertising;
156 void _bt_hal_set_advertising_status(int slot_id, gboolean mode)
159 DBG("Advertising enabled [%s] slot [%d]", mode ? "TRUE" : "FALSE", slot_id);
160 bt_hal_adv_event_data_t *event;
162 if (le_adv_slot == NULL)
165 le_adv_slot[slot_id].is_advertising = mode;
167 event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
168 event->event = mode ? BT_HAL_MULTI_ADV_ENB_EVT : BT_HAL_MULTI_ADV_DISABLE_EVT;
169 event->server_if = slot_id;
170 event->status = BT_STATUS_SUCCESS;
171 /* To be removed later when we completely descope Legacy Adv concept */
172 DBG("Is multi ? [%d]", le_adv_slot[slot_id].is_multi_adv);
173 if (le_adv_slot[slot_id].is_multi_adv == FALSE)
174 event->event = BT_HAL_LEGACY_ADV_STATUS;
176 __bt_hal_adv_event_cb((gpointer)event);
179 gboolean _bt_hal_is_advertising(void)
181 gboolean status = FALSE;
184 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
185 if (le_adv_slot[i].is_advertising == TRUE)
192 int _bt_hal_le_init(void)
194 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
195 return BT_STATUS_SUCCESS;
197 void _bt_hal_le_deinit(void)
199 __bt_hal_free_le_adv_slot();
201 gboolean _bt_hal_update_le_feature_support(const char *item, const char *value)
203 if (item == NULL || value == NULL)
208 if (g_strcmp0(item, "adv_inst_max") == 0) {
211 slot_num = atoi(value);
213 ERR("ERR:Advertising MAX instance [%d]", slot_num);
217 if (slot_num != le_feature_info.adv_inst_max) {
218 __bt_hal_free_le_adv_slot();
219 le_feature_info.adv_inst_max = slot_num;
220 INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
221 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
223 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
224 le_feature_info.rpa_offloading = atoi(value);
225 INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
226 } else if (g_strcmp0(item, "max_filter") == 0) {
227 le_feature_info.max_filter = atoi(value);
228 INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
230 DBG("No registered item");
237 void _bt_hal_free_server_slot(int slot_id)
239 if (le_adv_slot == NULL)
241 memset(&le_adv_slot[slot_id], 0x00, sizeof(bt_adapter_le_adv_slot_t));
244 int _bt_hal_get_available_adv_slot_id(bt_uuid_t *uuid)
248 if (le_adv_slot == NULL) {
249 ERR("le_adv_slot is NULL");
253 DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
255 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
256 if (le_adv_slot[i].initialized == 0)
258 if (memcmp(uuid->uu, le_adv_slot[i].app_uuid.uu, sizeof(bt_uuid_t)) == 0) {
259 DBG("UUID [%s] matched, return slot [%d]", btuuid2str(uuid->uu), i);
264 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
265 if (le_adv_slot[i].initialized == 0) {
266 DBG("Slot to be allocated [%d] UUID to be registered [%s]",
267 i, btuuid2str(uuid->uu));
268 le_adv_slot[i].initialized = 1;
269 memcpy(&le_adv_slot[i].app_uuid.uu, &uuid->uu, sizeof(bt_uuid_t));
277 void _bt_hal_get_gatt_server_instance_initialized(int *instance)
280 if (le_adv_slot == NULL) {
281 ERR("le_adv_slot is NULL");
285 DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
287 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
288 if (le_adv_slot[i].initialized == 0)
290 DBG("Initialized Slot found: UUID [%s] slot [%d]", le_adv_slot[i].app_uuid.uu, i);
296 gboolean _bt_is_advertising(void)
301 int _bt_set_advertising(const char *sender, int adv_handle,
302 gboolean enable, gboolean use_reserved_slot)
305 return BT_STATUS_UNSUPPORTED;
308 static int __bt_hal_uuid_type(uint8_t* p_uuid)
314 for (i = 0; i != 16; ++i) {
315 if (i == 12 || i == 13)
318 if (p_uuid[i] == BASE_UUID_CONVERTED[i])
327 return BT_HAL_UUID_32;
329 return BT_HAL_UUID_16;
330 return BT_HAL_UUID_128;
333 static void __bt_hal_parse_uuid(int len, char *src, uint8_t *dest, int *length, int is_solicit)
336 int prev_byte_len = 0;
337 /* dest[index] will contain the length followed by AD Type
338 Move length only when different byte_len is found Ex) 2->4, 2->16, 4->16 etc */
343 /* Create Local buffer & copy source 16 bytes in sequence */
346 memset(&uuid, 0, sizeof(bt_uuid_t));
347 memcpy(&uuid.uu, src, 16);
349 /* Compute current UUID's byte length */
350 byte_len = __bt_hal_uuid_type(uuid.uu);
354 if (prev_byte_len == byte_len) {
355 memcpy(&(dest[dest[index] + 1]), &src[12], byte_len);
359 if (dest[index] != 0)
360 index = dest[index] +1;
361 dest[index] = byte_len + 1;
363 dest[index+1] = 0x14; /* AD Type */
365 dest[index+1] = 0x02; /* AD Type */
366 memcpy(&(dest[index + 2]), &src[12], byte_len);
370 /* Update current type */
371 prev_byte_len = byte_len;
375 if (prev_byte_len == byte_len) {
376 memcpy(&(dest[dest[index] + 1]), &src[12], byte_len);;
380 if (dest[index] != 0)
381 index = dest[index] +1;
382 dest[index] = byte_len + 1;
384 dest[index+1] = 0x1F; /* AD Type */
386 dest[index+1] = 0x04; /* AD Type */
387 memcpy(&(dest[index + 2]), &src[12], byte_len);
390 /* Update current type */
391 prev_byte_len = byte_len;
395 if (dest[index] != 0)
396 index = dest[index] +1;
397 dest[index] = byte_len + 1;
399 dest[index+1] = 0x15; /* AD Type */
401 dest[index+1] = 0x06; /* AD Type */
402 memcpy(&(dest[index + 2]), &src[12], byte_len);
403 /* Update current type */
404 prev_byte_len = byte_len;
409 ERR("Abnormal Byte len [%d]", byte_len);
414 /* Process Next 16 bytes of MW UUID */
421 static gboolean __bt_hal_is_factory_test_mode(void)
425 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
426 ERR("Get the DUT Mode fail");
431 INFO("DUT Test Mode !!");
438 static gboolean __bt_hal_adv_event_cb(gpointer param)
440 bt_hal_adv_event_data_t *event = (bt_hal_adv_event_data_t*)param;
446 if (!gatt_le_event_cb) {
447 ERR("GATT event callback not registered!!!");
451 switch (event->event) {
452 case BT_HAL_MULTI_ADV_ENB_EVT: {
453 INFO("BLE Advertising enabled slot [%d]", event->server_if);
454 struct hal_ev_multi_adv_enable ev;
455 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_enable));
456 ev.status = event->status;
457 ev.server_instance = event->server_if;
458 gatt_le_event_cb(HAL_EV_MULTI_ADV_ENABLE, (void *)&ev, sizeof(ev));
461 case BT_HAL_MULTI_ADV_DISABLE_EVT: {
462 INFO("BLE Advertising disabled slot [%d]", event->server_if);
463 struct hal_ev_multi_adv_disable ev;
464 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_disable));
465 ev.status = event->status;
466 ev.server_instance = event->server_if;
467 gatt_le_event_cb(HAL_EV_MULTI_ADV_DISABLE, (void *)&ev, sizeof(ev));
470 case BT_HAL_MULTI_ADV_PARAM_EVT: {
471 INFO("Unhandled event slot [%d]", event->server_if);
474 case BT_HAL_MULTI_ADV_UPDATE_EVT: {
475 INFO("BLE Advertising Param update slot [%d]", event->server_if);
476 struct hal_ev_multi_adv_update ev;
477 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_update));
478 ev.status = event->status;
479 ev.server_instance = event->server_if;
480 gatt_le_event_cb(HAL_EV_MULTI_ADV_UPDATE, (void *)&ev, sizeof(ev));
483 case BT_HAL_MULTI_ADV_DATA_EVT: {
484 INFO("BLE Advertising data set slot [%d]", event->server_if);
485 struct hal_ev_multi_adv_data_set ev_data_set;
487 memset(&ev_data_set, 0, sizeof(struct hal_ev_multi_adv_data_set));
488 ev_data_set.status = event->status;
489 ev_data_set.server_instance = event->server_if;
490 gatt_le_event_cb(HAL_EV_MULTI_ADV_DATA_SET, (void *)&ev_data_set, sizeof(ev_data_set));
493 case BT_HAL_LEGACY_ADV_STATUS: {
494 INFO("BLE Legacy Advertising [%d]", event->server_if);
495 struct hal_ev_legacy_adv_status ev;
497 memset(&ev, 0, sizeof(struct hal_ev_legacy_adv_status));
498 ev.status = event->status;
499 ev.server_instance = event->server_if;
500 gatt_le_event_cb(HAL_EV_LEGACY_ADV_ENABLE, (void *)&ev, sizeof(ev));
504 ERR("Unknown event");
514 int _bt_hal_enable_advertising(int server_if, bool enable, bool is_multi_adv)
517 GError *error = NULL;
521 proxy = _bt_hal_get_adapter_proxy();
523 return BT_STATUS_FAIL;
525 if (le_adv_slot[server_if].is_advertising == TRUE && enable == TRUE)
526 return BT_STATUS_BUSY;
528 if (le_adv_slot[server_if].initialized == TRUE &&
529 le_adv_slot[server_if].is_advertising == FALSE &&
531 return BT_STATUS_DONE;
533 if (le_adv_slot[server_if].hold_timer_id > 0) {
534 g_source_remove(le_adv_slot[server_if].hold_timer_id);
535 le_adv_slot[server_if].hold_timer_id = 0;
538 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
539 g_variant_new("(bi)", enable, server_if),
540 G_DBUS_CALL_FLAGS_NONE,
546 ERR("SetAdvertising Fail: %s", error->message);
547 g_clear_error(&error);
548 return BT_STATUS_FAIL;
551 INFO("Enable advertising [%d] SLot Id [%d] Is Multi? [%d]", enable, server_if, is_multi_adv);
553 g_variant_unref(ret);
555 le_adv_slot[server_if].is_multi_adv = is_multi_adv;
556 le_adv_slot[server_if].is_advertising = enable;
557 return BT_STATUS_SUCCESS;
560 int _bt_hal_set_advertising_params(int server_if, int min_interval,
561 int max_interval, int adv_type,
562 int chnl_map, int tx_power, int timeout_s)
567 GError *error = NULL;
570 bt_hal_adv_event_data_t *event;
573 proxy = _bt_hal_get_adapter_proxy();
575 return BT_STATUS_FAIL;
577 if (min_interval > max_interval ||
578 min_interval < BT_HAL_ADV_INTERVAL_MIN ||
579 max_interval > BT_HAL_ADV_INTERVAL_MAX)
580 return BT_STATUS_PARM_INVALID;
583 if (adv_type == BT_HAL_ADV_CONNECTABLE_DIRECT_HIGH ||
584 adv_type == BT_HAL_ADV_CONNECTABLE_DIRECT_LOW ||
585 adv_type == BT_HAL_ADV_NON_CONNECTABLE)
586 return BT_STATUS_UNSUPPORTED;
589 min = min_interval / BT_HAL_ADV_INTERVAL_SPLIT;
590 max = max_interval / BT_HAL_ADV_INTERVAL_SPLIT;
592 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
593 g_variant_new("(uuuui)", min, max,
594 BT_HAL_ADV_FILTER_POLICY_DEFAULT, adv_type,
595 server_if), G_DBUS_CALL_FLAGS_NONE,
598 ERR("SetAdvertisingParameters Fail: %s", error->message);
599 g_clear_error(&error);
600 return BT_STATUS_FAIL;
603 INFO("Set advertising data");
605 g_variant_unref(ret);
608 * As we need to provide async callback to user from HAL, simply schedule a
609 * callback method which will carry actual result
611 event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
612 event->event = BT_HAL_MULTI_ADV_UPDATE_EVT;
613 event->server_if = server_if;
614 event->status = BT_STATUS_SUCCESS;
615 g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
617 return BT_STATUS_SUCCESS;
620 /* Takes care of both Scan Response and Advertising data */
621 int _bt_hal_set_advertising_data(btgatt_adv_param_setup_t adv_param_setup)
624 uint8_t adv_data[31];
627 GError *error = NULL;
628 GVariant *ret = NULL;
629 GVariant *temp = NULL;
630 GVariantBuilder *builder;
631 bt_hal_adv_event_data_t *event;
635 /* Parse data according to Bluez Interface */
636 if (__bt_hal_is_factory_test_mode()) {
637 ERR("Unable to set advertising data in factory binary !!");
638 return BT_STATUS_UNSUPPORTED;
641 /* TODO: Check adapter and LE adapter status */
642 proxy = _bt_hal_get_adapter_proxy();
644 return BT_STATUS_FAIL;
646 memset(&adv_data, 0, 31);
649 DBG("Service UUID length [%d]", adv_param_setup.service_uuid_len);
650 if (adv_param_setup.service_uuid_len > 0) {
651 __bt_hal_parse_uuid(adv_param_setup.service_uuid_len,
652 adv_param_setup.service_uuid, &adv_data[index], &length, FALSE);
654 DBG("After Service UUID:Index [%d]", index);
658 DBG("Solicit UUID length [%d]", adv_param_setup.solicit_uuid_len);
659 if (adv_param_setup.solicit_uuid_len > 0) {
660 __bt_hal_parse_uuid(adv_param_setup.solicit_uuid_len,
661 adv_param_setup.solicit_uuid, &adv_data[index], &length, TRUE);
663 DBG("After Solicit UUID: Index [%d]", index);
666 /* Service Data UUID*/
667 DBG("Service Data length [%d]", adv_param_setup.service_data_len);
668 if (adv_param_setup.service_data_len > 0) {
669 adv_data[index] = 1 + adv_param_setup.service_data_len;
670 adv_data[index+1] = 0x16; /* Fixed */
671 memcpy(&adv_data[index+2], adv_param_setup.service_data, adv_param_setup.service_data_len);
672 index += (2 + adv_param_setup.service_data_len);
673 length += (2 + adv_param_setup.service_data_len);
674 DBG("After Service data: Index [%d]", index);
678 if (adv_param_setup.appearance > 0) {
679 adv_data[index] = 0x03;
680 adv_data[index+1] = 0x19;
681 adv_data[index+2] = (uint8_t) (adv_param_setup.appearance & 0xFF);
682 adv_data[index+3] = (uint8_t) ((adv_param_setup.appearance >> 8) & 0xFF);
685 DBG("After Apperance: Index [%d]", index);
689 if (adv_param_setup.include_txpower != 0) {
690 adv_data[index] = 0x01;
691 adv_data[index+1] = 0x0A;
694 DBG("After TX Power: Index [%d]", index);
698 if (adv_param_setup.include_name != 0) {
699 adv_data[index] = 0x01;
700 adv_data[index+1] = 0x09;
703 DBG("After Name: Index [%d]", index);
706 /* Manufacturer data */
707 if (adv_param_setup.manufacturer_data_len > 0) {
708 adv_data[index] = 1 + adv_param_setup.manufacturer_data_len;
709 adv_data[index+1] = 0xFF;
710 memcpy(&adv_data[index+2], adv_param_setup.manufacturer_data, adv_param_setup.manufacturer_data_len);
711 index += (2 + adv_param_setup.manufacturer_data_len);
712 length += (2 + adv_param_setup.manufacturer_data_len);
713 DBG("After Manuf Data: Index [%d]", index);
717 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
718 for (i = 0; i < length; i++)
719 g_variant_builder_add(builder, "y", adv_data[i]);
721 temp = g_variant_new("ay", builder);
722 g_variant_builder_unref(builder);
724 DBG("####Adv data length [%d] Index [%d]", length, index);
725 for (i = 0; i < length; i++)
726 DBG("##Data[%d] [0x%x]", i, adv_data[i]);
728 if (adv_param_setup.set_scan_rsp == 0) {
729 /* Set Advertising data to stack */
730 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
731 g_variant_new("(@ayi)", temp, adv_param_setup.server_if),
732 G_DBUS_CALL_FLAGS_NONE,
735 /* Set Scan response data to stack */
736 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
737 g_variant_new("(@ayi)", temp, adv_param_setup.server_if),
738 G_DBUS_CALL_FLAGS_NONE,
743 ERR("SetAdvertisingData Fail: %s", error->message);
744 g_clear_error(&error);
745 return BT_STATUS_FAIL;
748 INFO("Set advertising data");
750 g_variant_unref(ret);
753 * As we need to provide async callback to user from HAL, simply schedule a
754 * callback method which will carry actual result
756 event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
757 event->event = BT_HAL_MULTI_ADV_DATA_EVT;
758 event->server_if = adv_param_setup.server_if;
759 event->status = BT_STATUS_SUCCESS;
760 memcpy(&event->data, adv_data, 31);
761 g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
763 return BT_STATUS_SUCCESS;
766 int _bt_hal_adapter_le_start_scan(void)
769 GError *error = NULL;
774 /* TODO: Check adapter and LE adapter status */
775 proxy = _bt_hal_get_adapter_proxy();
777 return BT_STATUS_FAIL;
779 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
780 NULL, G_DBUS_CALL_FLAGS_NONE,
784 ERR("StartLEDiscovery Fail: %s", error->message);
785 g_clear_error(&error);
788 return BT_STATUS_FAIL;
791 g_variant_unref(ret);
794 return BT_STATUS_SUCCESS;
797 int _bt_hal_adapter_le_stop_scan(void)
800 GError *error = NULL;
805 /* TODO: Check adapter and LE adapter status */
806 proxy = _bt_hal_get_adapter_proxy();
808 return BT_STATUS_FAIL;
810 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
811 NULL, G_DBUS_CALL_FLAGS_NONE,
815 ERR("StopLEDiscovery Fail: %s", error->message);
816 g_clear_error(&error);
819 return BT_STATUS_FAIL;
823 g_variant_unref(ret);
826 return BT_STATUS_SUCCESS;
830 int _bt_hal_adapter_le_set_scan_parameters(
831 int scan_type, int scan_interval, int scan_window)
834 GError *error = NULL;
839 /* TODO: Check adapter and LE adapter status */
840 proxy = _bt_hal_get_adapter_proxy();
842 return BT_STATUS_FAIL;
844 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
845 g_variant_new("(uuu)", scan_type, scan_interval, scan_window),
846 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
849 ERR("SetScanParameters Fail: %s", error->message);
850 g_clear_error(&error);
853 return BT_STATUS_FAIL;
856 g_variant_unref(ret);
859 return BT_STATUS_SUCCESS;
862 /* To send stack event to hal-av handler */
863 void _bt_hal_register_gatt_le_dbus_handler_cb(handle_stack_msg cb)
865 gatt_le_event_cb = cb;
868 void _bt_hal_unregister_gatt_le_dbus_handler_cb(void)
870 gatt_le_event_cb = NULL;