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"
57 } bt_adapter_le_feature_info_t;
61 gboolean is_multi_adv; /* To be removed once we complete descope Legacy Adv */
63 gboolean is_advertising;
66 } bt_adapter_le_adv_slot_t;
68 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
69 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
76 } bt_hal_adv_event_data_t;
79 #define BT_HAL_ADV_CONNECTABLE 0x00 /* ADV_IND */
80 #define BT_HAL_ADV_CONNECTABLE_DIRECT_HIGH 0x01 /* ADV_DIRECT_IND, high duty cycle */
81 #define BT_HAL_ADV_SCANNABLE 0x02 /* ADV_SCAN_IND */
82 #define BT_HAL_ADV_NON_CONNECTABLE 0x03 /* ADV_NONCOND_IND */
83 #define BT_HAL_ADV_CONNECTABLE_DIRECT_LOW 0x04 /* ADV_DIRECT_IND, low duty cycle */
85 #define BT_HAL_ADV_INTERVAL_MIN 20 /* msec */
86 #define BT_HAL_ADV_INTERVAL_MAX 10240
87 #define BT_HAL_ADV_INTERVAL_SPLIT 0.625
88 #define BT_HAL_DEFAULT_ADV_MIN_INTERVAL 500
89 #define BT_HAL_DEFAULT_ADV_MAX_INTERVAL 500
90 #define BT_HAL_ADV_FILTER_POLICY_DEFAULT 0x00
91 #define BT_HAL_ADV_TYPE_DEFAULT 0x00
92 #define BT_HAL_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
94 /* Multi Advertisement callback event */
95 #define BT_HAL_MULTI_ADV_ENB_EVT 1
96 #define BT_HAL_MULTI_ADV_DISABLE_EVT 2
97 #define BT_HAL_MULTI_ADV_PARAM_EVT 3
98 #define BT_HAL_MULTI_ADV_DATA_EVT 4
99 #define BT_HAL_MULTI_ADV_UPDATE_EVT 5
100 #define BT_HAL_LEGACY_ADV_STATUS 6
102 handle_stack_msg gatt_le_event_cb;
104 /* Forward declarations */
105 static gboolean __bt_hal_is_factory_test_mode(void);
106 static void __bt_hal_free_le_adv_slot(void);
107 static gboolean __bt_hal_adv_event_cb(gpointer param);
110 /* Enable LE Adapter */
111 int _bt_hal_le_enable(void)
113 return _bt_hal_dbus_enable_le();
116 /* Disable LE Adapter */
117 int _bt_hal_le_disable(void)
119 return _bt_hal_dbus_disable_le();
122 int _bt_hal_set_le_static_random_address(uint8_t enable)
125 GError *error = NULL;
129 proxy = _bt_hal_get_adapter_proxy();
131 return BT_STATUS_FAIL;
133 ret = g_dbus_proxy_call_sync(proxy, "SetLeStaticRandomAddress",
134 g_variant_new("(b)", (enable ? TRUE : FALSE)),
135 G_DBUS_CALL_FLAGS_NONE,
141 ERR("Set static address Fail: %s", error->message);
142 g_clear_error(&error);
143 return BT_STATUS_FAIL;
146 INFO("Set le static address [%d]", enable);
148 g_variant_unref(ret);
150 return BT_STATUS_SUCCESS;
154 static void __bt_hal_free_le_adv_slot(void)
158 if (le_adv_slot == NULL)
161 for (i = 0; i < le_feature_info.adv_inst_max; i++)
162 memset(&le_adv_slot[i], 0x00, sizeof(bt_adapter_le_adv_slot_t));
168 void _bt_hal_unregister_adv_slot_owner(int slot_id)
170 if (le_adv_slot == NULL)
172 INFO("Unregister Adv Slot [%d]", slot_id);
173 memset(&le_adv_slot[slot_id], 0x00, sizeof(bt_adapter_le_adv_slot_t));
176 int _bt_hal_get_adv_slot_adv_handle(int slot_id)
178 if (le_adv_slot == NULL)
181 return le_adv_slot[slot_id].adv_handle;
184 gboolean _bt_hal_is_advertising_in_slot(int slot)
186 return le_adv_slot[slot].is_advertising;
189 void _bt_hal_set_advertising_status(int slot_id, gboolean mode)
191 DBG("Advertising enabled [%s] server_slot [%d]", mode ? "TRUE" : "FALSE", slot_id);
192 bt_hal_adv_event_data_t *event;
193 int adv_slot_id = -1;
195 if (le_adv_slot == NULL)
198 adv_slot_id = bt_hal_gatts_get_adv_slot_id(slot_id);
202 le_adv_slot[adv_slot_id].is_advertising = mode;
204 event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
205 event->event = mode ? BT_HAL_MULTI_ADV_ENB_EVT : BT_HAL_MULTI_ADV_DISABLE_EVT;
206 event->server_if = slot_id;
207 event->status = BT_STATUS_SUCCESS;
208 /* To be removed later when we completely descope Legacy Adv concept */
210 DBG("adv_slot_id[%d] Is multi ? [%d]", adv_slot_id, le_adv_slot[adv_slot_id].is_multi_adv);
211 if (le_adv_slot[adv_slot_id].is_multi_adv == FALSE)
212 event->event = BT_HAL_LEGACY_ADV_STATUS;
214 if (mode == false ) {
215 DBG("release the adv_slot");
216 bt_hal_gatts_release_adv_slot(slot_id);
219 __bt_hal_adv_event_cb((gpointer)event);
222 gboolean _bt_hal_is_advertising(void)
226 if (le_adv_slot == NULL)
229 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
230 if (le_adv_slot[i].is_advertising == TRUE)
237 int _bt_hal_le_init(void)
239 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
240 return BT_STATUS_SUCCESS;
242 void _bt_hal_le_deinit(void)
244 __bt_hal_free_le_adv_slot();
247 gboolean _bt_hal_update_le_feature_support(const char *item, const char *value,
248 bt_local_le_features_t *le_features)
250 if (item == NULL || value == NULL)
255 if (g_strcmp0(item, "adv_inst_max") == 0) {
258 slot_num = atoi(value);
259 INFO("slot_num:[%d]", slot_num);
261 ERR("ERR:Advertising MAX instance [%d]", slot_num);
265 if (slot_num != le_feature_info.adv_inst_max) {
266 __bt_hal_free_le_adv_slot();
267 le_feature_info.adv_inst_max = slot_num;
268 INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
269 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
272 INFO("Advertising instance max: [%d]", le_feature_info.adv_inst_max);
273 /* Fill LE feature bytes */
274 le_features->max_adv_instance = atoi(value);
276 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
277 le_feature_info.rpa_offloading = atoi(value);
278 INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
280 /* Fill LE feature bytes */
281 le_features->rpa_offload_supported = atoi(value);
283 } else if (g_strcmp0(item, "max_filter") == 0) {
284 le_feature_info.max_filter = atoi(value);
285 INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
287 /* Fill LE feature bytes */
288 le_features->max_adv_filter_supported = atoi(value);
290 } else if (g_strcmp0(item, "2m_phy") == 0) {
291 if (g_strcmp0(value, "true") == 0) {
292 le_feature_info.le_2m_phy = TRUE;
293 /* Fill LE feature bytes */
294 le_features->le_2m_phy_supported = 0x1;
296 le_feature_info.le_2m_phy = FALSE;
297 /* Fill LE feature bytes */
298 le_features->le_2m_phy_supported = 0x0;
300 INFO("2M PHY Supported [%s]", le_feature_info.le_2m_phy ? "TRUE" : "FALSE");
301 } else if (g_strcmp0(item, "coded_phy") == 0) {
302 if (g_strcmp0(value, "true") == 0) {
303 le_feature_info.le_coded_phy = TRUE;
304 /* Fill LE feature bytes */
305 le_features->le_coded_phy_supported = 0x1;
307 le_feature_info.le_coded_phy = FALSE;
308 /* Fill LE feature bytes */
309 le_features->le_coded_phy_supported = 0x0;
311 INFO("CODED PHY Supported [%s]", le_feature_info.le_coded_phy ? "TRUE" : "FALSE");
313 DBG("No registered item");
320 void _bt_hal_free_server_slot(int slot_id)
322 if (le_adv_slot == NULL)
324 memset(&le_adv_slot[slot_id], 0x00, sizeof(bt_adapter_le_adv_slot_t));
327 int _bt_hal_get_available_adv_slot_id(bt_uuid_t *uuid, gboolean use_reserved_slot)
331 if (le_adv_slot == NULL) {
332 ERR("le_adv_slot is NULL");
336 DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
338 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
339 if (le_adv_slot[i].initialized == 0)
341 if (memcmp(uuid->uu, le_adv_slot[i].app_uuid.uu, sizeof(bt_uuid_t)) == 0) {
342 DBG("UUID [%s] matched, return slot [%d]", btuuid2str(uuid->uu), i);
347 /* We should consider 'use_reverved_slot' in later */
348 if (le_feature_info.adv_inst_max <= 1)
350 else if (use_reserved_slot == TRUE)
355 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
356 if (le_adv_slot[i].initialized == 0) {
357 DBG("Slot to be allocated [%d] UUID to be registered [%s]",
358 i, btuuid2str(uuid->uu));
359 le_adv_slot[i].initialized = 1;
360 memcpy(&le_adv_slot[i].app_uuid.uu, &uuid->uu, sizeof(bt_uuid_t));
368 void _bt_hal_get_gatt_server_instance_initialized(int *instance)
371 if (le_adv_slot == NULL) {
372 ERR("le_adv_slot is NULL");
376 DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
378 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
379 if (le_adv_slot[i].initialized == 0)
381 DBG("Initialized Slot found: UUID [%s] slot [%d]", le_adv_slot[i].app_uuid.uu, i);
387 gboolean _bt_is_advertising(void)
392 int _bt_set_advertising(const char *sender, int adv_handle,
393 gboolean enable, gboolean use_reserved_slot)
396 return BT_STATUS_UNSUPPORTED;
399 static int __bt_hal_uuid_type(uint8_t* p_uuid)
405 for (i = 0; i != 16; ++i) {
406 if (i == 12 || i == 13)
409 if (p_uuid[i] == BASE_UUID_CONVERTED[i])
418 return BT_HAL_UUID_32;
420 return BT_HAL_UUID_16;
421 return BT_HAL_UUID_128;
424 static void __bt_hal_parse_uuid(int len, char *src, uint8_t *dest, int *length, int is_solicit)
427 int prev_byte_len = 0;
428 /* dest[index] will contain the length followed by AD Type
429 Move length only when different byte_len is found Ex) 2->4, 2->16, 4->16 etc */
434 /* Create Local buffer & copy source 16 bytes in sequence */
437 memset(&uuid, 0, sizeof(bt_uuid_t));
438 memcpy(&uuid.uu, src, 16);
440 /* Compute current UUID's byte length */
441 byte_len = __bt_hal_uuid_type(uuid.uu);
445 if (prev_byte_len == byte_len) {
446 memcpy(&(dest[dest[index] + 1]), &src[12], byte_len);
450 if (dest[index] != 0)
451 index = dest[index] +1;
452 dest[index] = byte_len + 1;
454 dest[index+1] = 0x14; /* AD Type */
456 dest[index+1] = 0x02; /* AD Type */
457 memcpy(&(dest[index + 2]), &src[12], byte_len);
461 /* Update current type */
462 prev_byte_len = byte_len;
466 if (prev_byte_len == byte_len) {
467 memcpy(&(dest[dest[index] + 1]), &src[12], byte_len);;
471 if (dest[index] != 0)
472 index = dest[index] +1;
473 dest[index] = byte_len + 1;
475 dest[index+1] = 0x1F; /* AD Type */
477 dest[index+1] = 0x04; /* AD Type */
478 memcpy(&(dest[index + 2]), &src[12], byte_len);
481 /* Update current type */
482 prev_byte_len = byte_len;
486 if (dest[index] != 0)
487 index = dest[index] +1;
488 dest[index] = byte_len + 1;
490 dest[index+1] = 0x15; /* AD Type */
492 dest[index+1] = 0x06; /* AD Type */
493 memcpy(&(dest[index + 2]), &src[12], byte_len);
494 /* Update current type */
495 prev_byte_len = byte_len;
500 ERR("Abnormal Byte len [%d]", byte_len);
505 /* Process Next 16 bytes of MW UUID */
512 static gboolean __bt_hal_is_factory_test_mode(void)
516 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
517 ERR("Get the DUT Mode fail");
522 INFO("DUT Test Mode !!");
529 static gboolean __bt_hal_adv_event_cb(gpointer param)
531 bt_hal_adv_event_data_t *event = (bt_hal_adv_event_data_t*)param;
537 if (!gatt_le_event_cb) {
538 ERR("GATT event callback not registered!!!");
542 switch (event->event) {
543 case BT_HAL_MULTI_ADV_ENB_EVT: {
544 INFO("BLE Advertising enabled slot [%d]", event->server_if);
545 struct hal_ev_multi_adv_enable ev;
546 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_enable));
547 ev.status = event->status;
548 ev.server_instance = event->server_if;
549 gatt_le_event_cb(HAL_EV_MULTI_ADV_ENABLE, (void *)&ev, sizeof(ev));
552 case BT_HAL_MULTI_ADV_DISABLE_EVT: {
553 INFO("BLE Advertising disabled slot [%d]", event->server_if);
554 struct hal_ev_multi_adv_disable ev;
555 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_disable));
556 ev.status = event->status;
557 ev.server_instance = event->server_if;
558 gatt_le_event_cb(HAL_EV_MULTI_ADV_DISABLE, (void *)&ev, sizeof(ev));
561 case BT_HAL_MULTI_ADV_PARAM_EVT: {
562 INFO("Unhandled event slot [%d]", event->server_if);
565 case BT_HAL_MULTI_ADV_UPDATE_EVT: {
566 INFO("BLE Advertising Param update slot [%d]", event->server_if);
567 struct hal_ev_multi_adv_update ev;
568 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_update));
569 ev.status = event->status;
570 ev.server_instance = event->server_if;
571 gatt_le_event_cb(HAL_EV_MULTI_ADV_UPDATE, (void *)&ev, sizeof(ev));
574 case BT_HAL_MULTI_ADV_DATA_EVT: {
575 INFO("BLE Advertising data set slot [%d]", event->server_if);
576 struct hal_ev_multi_adv_data_set ev_data_set;
578 memset(&ev_data_set, 0, sizeof(struct hal_ev_multi_adv_data_set));
579 ev_data_set.status = event->status;
580 ev_data_set.server_instance = event->server_if;
581 gatt_le_event_cb(HAL_EV_MULTI_ADV_DATA_SET, (void *)&ev_data_set, sizeof(ev_data_set));
584 case BT_HAL_LEGACY_ADV_STATUS: {
585 INFO("BLE Legacy Advertising [%d]", event->server_if);
586 struct hal_ev_legacy_adv_status ev;
588 memset(&ev, 0, sizeof(struct hal_ev_legacy_adv_status));
589 ev.status = event->status;
590 ev.server_instance = event->server_if;
591 gatt_le_event_cb(HAL_EV_LEGACY_ADV_ENABLE, (void *)&ev, sizeof(ev));
595 ERR("Unknown event");
605 int _bt_hal_enable_advertising(int server_if, int adv_slot_id, bool enable, bool is_multi_adv)
608 GError *error = NULL;
612 proxy = _bt_hal_get_adapter_proxy();
614 return BT_STATUS_FAIL;
616 if (le_adv_slot[adv_slot_id].is_advertising == TRUE && enable == TRUE)
617 return BT_STATUS_BUSY;
619 if (le_adv_slot[adv_slot_id].initialized == TRUE &&
620 le_adv_slot[adv_slot_id].is_advertising == FALSE &&
622 return BT_STATUS_DONE;
624 if (le_adv_slot[adv_slot_id].hold_timer_id > 0) {
625 g_source_remove(le_adv_slot[adv_slot_id].hold_timer_id);
626 le_adv_slot[adv_slot_id].hold_timer_id = 0;
629 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
630 g_variant_new("(bi)", enable, server_if),
631 G_DBUS_CALL_FLAGS_NONE,
637 ERR("SetAdvertising Fail: %s", error->message);
638 g_clear_error(&error);
639 return BT_STATUS_FAIL;
642 INFO("Enable advertising [%d] SLot Id [%d] gatt_server [%d] Is Multi? [%d]",
643 enable, adv_slot_id, server_if, is_multi_adv);
645 g_variant_unref(ret);
647 le_adv_slot[adv_slot_id].is_multi_adv = is_multi_adv;
648 le_adv_slot[adv_slot_id].is_advertising = enable;
649 return BT_STATUS_SUCCESS;
652 int _bt_hal_set_advertising_params(int server_if, int min_interval,
653 int max_interval, int adv_type,
654 int chnl_map, int tx_power, int timeout_s)
659 GError *error = NULL;
662 bt_hal_adv_event_data_t *event;
665 proxy = _bt_hal_get_adapter_proxy();
667 return BT_STATUS_FAIL;
669 if (min_interval > max_interval ||
670 min_interval < BT_HAL_ADV_INTERVAL_MIN ||
671 max_interval > BT_HAL_ADV_INTERVAL_MAX)
672 return BT_STATUS_PARM_INVALID;
675 if (adv_type == BT_HAL_ADV_CONNECTABLE_DIRECT_HIGH ||
676 adv_type == BT_HAL_ADV_CONNECTABLE_DIRECT_LOW ||
677 adv_type == BT_HAL_ADV_NON_CONNECTABLE)
678 return BT_STATUS_UNSUPPORTED;
681 min = min_interval / BT_HAL_ADV_INTERVAL_SPLIT;
682 max = max_interval / BT_HAL_ADV_INTERVAL_SPLIT;
684 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
685 g_variant_new("(uuuuii)", min, max,
686 BT_HAL_ADV_FILTER_POLICY_DEFAULT, adv_type,
687 tx_power, server_if), G_DBUS_CALL_FLAGS_NONE,
690 ERR("SetAdvertisingParameters Fail: %s", error->message);
691 g_clear_error(&error);
692 return BT_STATUS_FAIL;
695 INFO("Set advertising data");
697 g_variant_unref(ret);
700 * As we need to provide async callback to user from HAL, simply schedule a
701 * callback method which will carry actual result
703 event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
704 event->event = BT_HAL_MULTI_ADV_UPDATE_EVT;
705 event->server_if = server_if;
706 event->status = BT_STATUS_SUCCESS;
707 g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
709 return BT_STATUS_SUCCESS;
712 /* Takes care of both Scan Response and Advertising data */
713 int _bt_hal_set_advertising_data(btgatt_adv_param_setup_t adv_param_setup)
716 uint8_t adv_data[31];
719 GError *error = NULL;
720 GVariant *ret = NULL;
721 GVariant *temp = NULL;
722 GVariantBuilder *builder;
723 bt_hal_adv_event_data_t *event;
727 /* Parse data according to Bluez Interface */
728 if (__bt_hal_is_factory_test_mode()) {
729 ERR("Unable to set advertising data in factory binary !!");
730 return BT_STATUS_UNSUPPORTED;
733 /* TODO: Check adapter and LE adapter status */
734 proxy = _bt_hal_get_adapter_proxy();
736 return BT_STATUS_FAIL;
738 memset(&adv_data, 0, 31);
741 DBG("Service UUID length [%d]", adv_param_setup.service_uuid_len);
742 if (adv_param_setup.service_uuid_len > 0) {
743 __bt_hal_parse_uuid(adv_param_setup.service_uuid_len,
744 adv_param_setup.service_uuid, &adv_data[index], &length, FALSE);
746 DBG("After Service UUID:Index [%d]", index);
750 DBG("Solicit UUID length [%d]", adv_param_setup.solicit_uuid_len);
751 if (adv_param_setup.solicit_uuid_len > 0) {
752 __bt_hal_parse_uuid(adv_param_setup.solicit_uuid_len,
753 adv_param_setup.solicit_uuid, &adv_data[index], &length, TRUE);
755 DBG("After Solicit UUID: Index [%d]", index);
758 /* Service Data UUID*/
759 DBG("Service Data length [%d]", adv_param_setup.service_data_len);
760 if (adv_param_setup.service_data_len > 0) {
761 adv_data[index] = 1 + adv_param_setup.service_data_len;
762 adv_data[index+1] = 0x16; /* Fixed */
763 memcpy(&adv_data[index+2], adv_param_setup.service_data, adv_param_setup.service_data_len);
764 index += (2 + adv_param_setup.service_data_len);
765 length += (2 + adv_param_setup.service_data_len);
766 DBG("After Service data: Index [%d]", index);
770 if (adv_param_setup.appearance > 0) {
771 adv_data[index] = 0x03;
772 adv_data[index+1] = 0x19;
773 adv_data[index+2] = (uint8_t) (adv_param_setup.appearance & 0xFF);
774 adv_data[index+3] = (uint8_t) ((adv_param_setup.appearance >> 8) & 0xFF);
777 DBG("After Apperance: Index [%d]", index);
781 if (adv_param_setup.include_txpower != 0) {
782 adv_data[index] = 0x01;
783 adv_data[index+1] = 0x0A;
786 DBG("After TX Power: Index [%d]", index);
790 if (adv_param_setup.include_name != 0) {
791 adv_data[index] = 0x01;
792 adv_data[index+1] = 0x09;
795 DBG("After Name: Index [%d]", index);
798 /* Manufacturer data */
799 if (adv_param_setup.manufacturer_data_len > 0) {
800 adv_data[index] = 1 + adv_param_setup.manufacturer_data_len;
801 adv_data[index+1] = 0xFF;
802 memcpy(&adv_data[index+2], adv_param_setup.manufacturer_data, adv_param_setup.manufacturer_data_len);
803 index += (2 + adv_param_setup.manufacturer_data_len);
804 length += (2 + adv_param_setup.manufacturer_data_len);
805 DBG("After Manuf Data: Index [%d]", index);
809 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
810 for (i = 0; i < length; i++)
811 g_variant_builder_add(builder, "y", adv_data[i]);
813 temp = g_variant_new("ay", builder);
814 g_variant_builder_unref(builder);
816 DBG("####Adv data length [%d] Index [%d]", length, index);
817 for (i = 0; i < length; i++)
818 DBG("##Data[%d] [0x%x]", i, adv_data[i]);
820 if (adv_param_setup.set_scan_rsp == 0) {
821 /* Set Advertising data to stack */
822 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
823 g_variant_new("(@ayi)", temp, adv_param_setup.server_if),
824 G_DBUS_CALL_FLAGS_NONE,
827 /* Set Scan response data to stack */
828 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
829 g_variant_new("(@ayi)", temp, adv_param_setup.server_if),
830 G_DBUS_CALL_FLAGS_NONE,
835 ERR("SetAdvertisingData Fail: %s", error->message);
836 g_clear_error(&error);
837 return BT_STATUS_FAIL;
840 INFO("Set advertising data");
842 g_variant_unref(ret);
845 * As we need to provide async callback to user from HAL, simply schedule a
846 * callback method which will carry actual result
848 event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
849 event->event = BT_HAL_MULTI_ADV_DATA_EVT;
850 event->server_if = adv_param_setup.server_if;
851 event->status = BT_STATUS_SUCCESS;
852 memcpy(&event->data, adv_data, 31);
853 g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
855 return BT_STATUS_SUCCESS;
858 int _bt_hal_adapter_le_start_scan(void)
861 GError *error = NULL;
866 /* TODO: Check adapter and LE adapter status */
867 proxy = _bt_hal_get_adapter_proxy();
869 return BT_STATUS_FAIL;
871 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
872 NULL, G_DBUS_CALL_FLAGS_NONE,
876 ERR("StartLEDiscovery Fail: %s", error->message);
877 g_clear_error(&error);
880 return BT_STATUS_FAIL;
883 g_variant_unref(ret);
886 return BT_STATUS_SUCCESS;
889 int _bt_hal_adapter_le_stop_scan(void)
892 GError *error = NULL;
897 /* TODO: Check adapter and LE adapter status */
898 proxy = _bt_hal_get_adapter_proxy();
900 return BT_STATUS_FAIL;
902 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
903 NULL, G_DBUS_CALL_FLAGS_NONE,
907 g_dbus_error_strip_remote_error(error);
908 ERR("StopLEDiscovery Fail: %s", error->message);
910 /* Abnormal case for ARTIK530 */
911 if (g_strrstr(error->message, "No discovery started") ||
912 g_strrstr(error->message, "Operation already in progress")) {
913 g_clear_error(&error);
914 return BT_STATUS_SUCCESS;
917 g_clear_error(&error);
918 return BT_STATUS_FAIL;
922 g_variant_unref(ret);
925 return BT_STATUS_SUCCESS;
928 /*sets the privacy functionality of the adapter*/
929 int _bt_hal_adapter_le_set_privacy(uint8_t set_privacy)
932 GError *error = NULL;
933 GVariant *result = NULL;
934 proxy = _bt_hal_get_adapter_proxy();
936 return BT_STATUS_FAIL;
938 result = g_dbus_proxy_call_sync(proxy,
940 g_variant_new("(b)", set_privacy),
941 G_DBUS_CALL_FLAGS_NONE,
948 ERR("Failed to SetLePrivacy (Error: %s)", error->message);
949 g_clear_error(&error);
951 ERR("Failed to SetLePrivacy");
952 return BT_STATUS_FAIL;
955 g_variant_unref(result);
956 INFO("SetLePrivacy as %d", set_privacy);
957 return BT_STATUS_SUCCESS;
960 int _bt_hal_adapter_le_set_scan_parameters(
961 int scan_type, int scan_interval, int scan_window)
964 GError *error = NULL;
969 /* TODO: Check adapter and LE adapter status */
970 proxy = _bt_hal_get_adapter_proxy();
972 return BT_STATUS_FAIL;
974 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
975 g_variant_new("(uuu)", scan_type, scan_interval, scan_window),
976 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
979 ERR("SetScanParameters Fail: %s", error->message);
980 g_clear_error(&error);
983 return BT_STATUS_FAIL;
986 g_variant_unref(ret);
989 return BT_STATUS_SUCCESS;
992 /* To send stack event to hal-av handler */
993 void _bt_hal_register_gatt_le_dbus_handler_cb(handle_stack_msg cb)
995 gatt_le_event_cb = cb;
998 void _bt_hal_unregister_gatt_le_dbus_handler_cb(void)
1000 gatt_le_event_cb = NULL;
1003 int _bt_hal_adapter_le_set_manufacturer_data(bt_manufacturer_data_t *m_data)
1006 GError *error = NULL;
1010 GVariantBuilder *builder;
1012 proxy = _bt_hal_get_adapter_proxy();
1014 return BT_STATUS_FAIL;
1016 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1018 if (m_data->data_len + 2 >= BT_MANUFACTURER_DATA_LENGTH_MAX)
1019 return BT_STATUS_PARM_INVALID;
1020 for (i = 0; i < (m_data->data_len) + 2; i++)
1021 g_variant_builder_add(builder, "y", m_data->data[i]);
1023 val = g_variant_new("(ay)", builder);
1025 ret = g_dbus_proxy_call_sync(proxy,
1026 "SetManufacturerData",
1028 G_DBUS_CALL_FLAGS_NONE,
1032 g_variant_builder_unref(builder);
1034 if (error != NULL) {
1035 ERR("Failed to SetManufacturerData (Error: %s)", error->message);
1036 g_clear_error(&error);
1038 ERR("Failed to SetManufacturerData");
1040 return BT_STATUS_FAIL;
1043 INFO("Set manufacturer data");
1044 g_variant_unref(ret);
1046 return BT_STATUS_SUCCESS;
1051 /*add/remove remote device address from white list*/
1052 int _bt_hal_adapter_le_set_white_list(bt_bdaddr_t *device_address, bt_dev_addr_type_t address_type, bool is_add)
1055 char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1056 GError *error = NULL;
1059 if (address_type != BLUETOOTH_HAL_DEVICE_PUBLIC_ADDRESS &&
1060 address_type != BLUETOOTH_HAL_DEVICE_RANDOM_ADDRESS)
1061 return BT_STATUS_PARM_INVALID;
1063 _bt_hal_convert_addr_type_to_string(address, device_address->address);
1065 proxy = _bt_hal_get_adapter_proxy();
1067 return BT_STATUS_FAIL;
1069 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1070 g_variant_new("(su)", address, address_type),
1071 G_DBUS_CALL_FLAGS_NONE, -1,
1074 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1075 g_variant_new("(su)", address, address_type),
1076 G_DBUS_CALL_FLAGS_NONE, -1,
1081 ERR("RemoveDeviceWhiteList Fail: %s", error->message);
1083 ERR("AddDeviceWhiteList Fail: %s", error->message);
1084 g_clear_error(&error);
1085 return BT_STATUS_FAIL;
1089 g_variant_unref(ret);
1091 INFO("Device Added to white list");
1093 INFO("Device Removed from white list");
1094 return BT_STATUS_SUCCESS;