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"
50 #include "bt-hal-gatt.h"
58 } bt_adapter_le_feature_info_t;
62 gboolean is_multi_adv; /* To be removed once we complete descope Legacy Adv */
64 gboolean is_advertising;
67 } bt_adapter_le_adv_slot_t;
69 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
70 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
77 } bt_hal_adv_event_data_t;
80 #define BT_HAL_ADV_CONNECTABLE 0x00 /* ADV_IND */
81 #define BT_HAL_ADV_CONNECTABLE_DIRECT_HIGH 0x01 /* ADV_DIRECT_IND, high duty cycle */
82 #define BT_HAL_ADV_SCANNABLE 0x02 /* ADV_SCAN_IND */
83 #define BT_HAL_ADV_NON_CONNECTABLE 0x03 /* ADV_NONCOND_IND */
84 #define BT_HAL_ADV_CONNECTABLE_DIRECT_LOW 0x04 /* ADV_DIRECT_IND, low duty cycle */
86 #define BT_HAL_ADV_INTERVAL_MIN 20 /* msec */
87 #define BT_HAL_ADV_INTERVAL_MAX 10240
88 #define BT_HAL_ADV_INTERVAL_SPLIT 0.625
89 #define BT_HAL_DEFAULT_ADV_MIN_INTERVAL 500
90 #define BT_HAL_DEFAULT_ADV_MAX_INTERVAL 500
91 #define BT_HAL_ADV_FILTER_POLICY_DEFAULT 0x00
92 #define BT_HAL_ADV_TYPE_DEFAULT 0x00
93 #define BT_HAL_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
95 /* Multi Advertisement callback event */
96 #define BT_HAL_MULTI_ADV_ENB_EVT 1
97 #define BT_HAL_MULTI_ADV_DISABLE_EVT 2
98 #define BT_HAL_MULTI_ADV_PARAM_EVT 3
99 #define BT_HAL_MULTI_ADV_DATA_EVT 4
100 #define BT_HAL_MULTI_ADV_UPDATE_EVT 5
101 #define BT_HAL_LEGACY_ADV_STATUS 6
103 static handle_stack_msg gatt_le_event_cb;
105 /* Advertising filter_policy */
106 static int adv_filter_policy;
108 /* Forward declarations */
109 static gboolean __bt_hal_is_factory_test_mode(void);
110 static void __bt_hal_free_le_adv_slot(void);
111 static gboolean __bt_hal_adv_event_cb(gpointer param);
115 /* Enable LE Adapter */
116 int _bt_hal_le_enable(void)
118 return _bt_hal_dbus_enable_le();
121 /* Disable LE Adapter */
122 int _bt_hal_le_disable(void)
124 return _bt_hal_dbus_disable_le();
127 void _bt_hal_set_filter_policy_param(int filter_policy)
129 adv_filter_policy = filter_policy;
132 int _bt_hal_set_le_static_random_address(uint8_t enable)
134 GError *error = NULL;
138 proxy = _bt_hal_get_adapter_proxy();
140 return BT_STATUS_FAIL;
142 ret = g_dbus_proxy_call_sync(proxy, "SetLeStaticRandomAddress",
143 g_variant_new("(b)", (enable ? TRUE : FALSE)),
144 G_DBUS_CALL_FLAGS_NONE,
150 ERR("Set static address Fail: %s", error->message);
151 g_clear_error(&error);
152 return BT_STATUS_FAIL;
155 INFO("Set le static address [%d]", enable);
157 g_variant_unref(ret);
159 return BT_STATUS_SUCCESS;
163 static void __bt_hal_free_le_adv_slot(void)
167 if (le_adv_slot == NULL)
170 for (i = 0; i < le_feature_info.adv_inst_max; i++)
171 memset(&le_adv_slot[i], 0x00, sizeof(bt_adapter_le_adv_slot_t));
177 void _bt_hal_unregister_adv_slot_owner(int slot_id)
179 if (le_adv_slot == NULL)
181 INFO("Unregister Adv Slot [%d]", slot_id);
182 memset(&le_adv_slot[slot_id], 0x00, sizeof(bt_adapter_le_adv_slot_t));
185 int _bt_hal_get_adv_slot_adv_handle(int slot_id)
187 if (le_adv_slot == NULL)
190 return le_adv_slot[slot_id].adv_handle;
193 gboolean _bt_hal_is_advertising_in_slot(int slot)
195 return le_adv_slot[slot].is_advertising;
198 void _bt_hal_set_advertising_status(int slot_id, gboolean mode)
200 bt_hal_adv_event_data_t *event;
201 int adv_slot_id = slot_id;
204 server_if = bt_hal_gatts_get_server_if(slot_id);
206 DBG("Advertising enabled [%s] server_slot [%d] server_if[%d]", mode ? "TRUE" : "FALSE", slot_id, server_if);
208 if (le_adv_slot == NULL)
211 le_adv_slot[adv_slot_id].is_advertising = mode;
213 event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
214 event->event = mode ? BT_HAL_MULTI_ADV_ENB_EVT : BT_HAL_MULTI_ADV_DISABLE_EVT;
216 event->server_if = server_if;
217 event->status = BT_STATUS_SUCCESS;
218 /* To be removed later when we completely descope Legacy Adv concept */
220 DBG("adv_slot_id[%d] Is multi ? [%d]", adv_slot_id, le_adv_slot[adv_slot_id].is_multi_adv);
221 if (le_adv_slot[adv_slot_id].is_multi_adv == FALSE)
222 event->event = BT_HAL_LEGACY_ADV_STATUS;
224 if (mode == false ) {
225 DBG("release the adv_slot");
226 bt_hal_gatts_release_adv_slot(server_if);
229 __bt_hal_adv_event_cb((gpointer)event);
232 gboolean _bt_hal_is_advertising(void)
236 if (le_adv_slot == NULL)
239 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
240 if (le_adv_slot[i].is_advertising == TRUE)
247 int _bt_hal_le_init(void)
249 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
250 return BT_STATUS_SUCCESS;
252 void _bt_hal_le_deinit(void)
254 __bt_hal_free_le_adv_slot();
257 gboolean _bt_hal_update_le_feature_support(const char *item, const char *value,
258 bt_local_le_features_t *le_features)
260 if (item == NULL || value == NULL)
265 if (g_strcmp0(item, "adv_inst_max") == 0) {
268 slot_num = atoi(value);
269 INFO("slot_num:[%d]", slot_num);
271 ERR("ERR:Advertising MAX instance [%d]", slot_num);
275 if (slot_num != le_feature_info.adv_inst_max) {
276 __bt_hal_free_le_adv_slot();
277 le_feature_info.adv_inst_max = slot_num;
278 INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
279 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
282 INFO("Advertising instance max: [%d]", le_feature_info.adv_inst_max);
283 /* Fill LE feature bytes */
284 le_features->max_adv_instance = atoi(value);
286 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
287 le_feature_info.rpa_offloading = atoi(value);
288 INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
290 /* Fill LE feature bytes */
291 le_features->rpa_offload_supported = atoi(value);
293 } else if (g_strcmp0(item, "max_filter") == 0) {
294 le_feature_info.max_filter = atoi(value);
295 INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
297 /* Fill LE feature bytes */
298 le_features->max_adv_filter_supported = atoi(value);
300 } else if (g_strcmp0(item, "2m_phy") == 0) {
301 if (g_strcmp0(value, "true") == 0) {
302 le_feature_info.le_2m_phy = TRUE;
303 /* Fill LE feature bytes */
304 le_features->le_2m_phy_supported = 0x1;
306 le_feature_info.le_2m_phy = FALSE;
307 /* Fill LE feature bytes */
308 le_features->le_2m_phy_supported = 0x0;
310 INFO("2M PHY Supported [%s]", le_feature_info.le_2m_phy ? "TRUE" : "FALSE");
311 } else if (g_strcmp0(item, "coded_phy") == 0) {
312 if (g_strcmp0(value, "true") == 0) {
313 le_feature_info.le_coded_phy = TRUE;
314 /* Fill LE feature bytes */
315 le_features->le_coded_phy_supported = 0x1;
317 le_feature_info.le_coded_phy = FALSE;
318 /* Fill LE feature bytes */
319 le_features->le_coded_phy_supported = 0x0;
321 INFO("CODED PHY Supported [%s]", le_feature_info.le_coded_phy ? "TRUE" : "FALSE");
323 DBG("No registered item");
330 void _bt_hal_free_server_slot(int slot_id)
332 if (le_adv_slot == NULL)
334 memset(&le_adv_slot[slot_id], 0x00, sizeof(bt_adapter_le_adv_slot_t));
337 gboolean _bt_hal_is_support_multi_adv(void)
339 return (le_feature_info.adv_inst_max > 1 ? TRUE : FALSE);
342 int _bt_hal_get_available_adv_slot_id(bt_uuid_t *uuid, gboolean use_reserved_slot)
346 if (le_adv_slot == NULL) {
347 ERR("le_adv_slot is NULL");
351 DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
353 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
354 if (le_adv_slot[i].initialized == 0)
356 if (memcmp(uuid->uu, le_adv_slot[i].app_uuid.uu, sizeof(bt_uuid_t)) == 0) {
357 DBG("UUID [%s] matched, return slot [%d]", btuuid2str(uuid->uu), i);
362 /* We should consider 'use_reverved_slot' in later */
363 if (le_feature_info.adv_inst_max <= 1)
365 else if (use_reserved_slot == TRUE)
370 for ( ; i < le_feature_info.adv_inst_max; i++) {
371 if (le_adv_slot[i].initialized == 0) {
372 DBG("Slot to be allocated [%d] UUID to be registered [%s]",
373 i, btuuid2str(uuid->uu));
374 le_adv_slot[i].initialized = 1;
375 memcpy(&le_adv_slot[i].app_uuid.uu, &uuid->uu, sizeof(bt_uuid_t));
383 void _bt_hal_get_gatt_server_instance_initialized(int *instance)
386 if (le_adv_slot == NULL) {
387 ERR("le_adv_slot is NULL");
391 DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
393 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
394 if (le_adv_slot[i].initialized == 0)
396 DBG("Initialized Slot found: UUID [%s] slot [%d]", le_adv_slot[i].app_uuid.uu, i);
402 gboolean _bt_is_advertising(void)
407 int _bt_set_advertising(const char *sender, int adv_handle,
408 gboolean enable, gboolean use_reserved_slot)
410 return BT_STATUS_UNSUPPORTED;
413 static int __bt_hal_uuid_type(uint8_t* p_uuid)
419 for (i = 0; i != 16; ++i) {
420 if (i == 12 || i == 13)
423 if (p_uuid[i] == BASE_UUID_CONVERTED[i])
432 return BT_HAL_UUID_32;
434 return BT_HAL_UUID_16;
435 return BT_HAL_UUID_128;
438 static void __bt_hal_parse_uuid(int len, char *src, uint8_t *dest, int *length, int is_solicit)
440 int prev_byte_len = 0;
441 /* dest[index] will contain the length followed by AD Type
442 Move length only when different byte_len is found Ex) 2->4, 2->16, 4->16 etc */
447 /* Create Local buffer & copy source 16 bytes in sequence */
450 memset(&uuid, 0, sizeof(bt_uuid_t));
451 memcpy(&uuid.uu, src, 16);
453 /* Compute current UUID's byte length */
454 byte_len = __bt_hal_uuid_type(uuid.uu);
458 if (prev_byte_len == byte_len) {
459 memcpy(&(dest[dest[index] + 1]), &src[12], byte_len);
463 if (dest[index] != 0)
464 index = dest[index] +1;
465 dest[index] = byte_len + 1;
467 dest[index+1] = 0x14; /* AD Type */
469 dest[index+1] = 0x02; /* AD Type */
470 memcpy(&(dest[index + 2]), &src[12], byte_len);
474 /* Update current type */
475 prev_byte_len = byte_len;
479 if (prev_byte_len == byte_len) {
480 memcpy(&(dest[dest[index] + 1]), &src[12], byte_len);;
484 if (dest[index] != 0)
485 index = dest[index] +1;
486 dest[index] = byte_len + 1;
488 dest[index+1] = 0x1F; /* AD Type */
490 dest[index+1] = 0x04; /* AD Type */
491 memcpy(&(dest[index + 2]), &src[12], byte_len);
494 /* Update current type */
495 prev_byte_len = byte_len;
499 if (dest[index] != 0)
500 index = dest[index] +1;
501 dest[index] = byte_len + 1;
503 dest[index+1] = 0x15; /* AD Type */
505 dest[index+1] = 0x06; /* AD Type */
506 memcpy(&(dest[index + 2]), &src[0], byte_len);
507 /* Update current type */
508 prev_byte_len = byte_len;
513 ERR("Abnormal Byte len [%d]", byte_len);
518 /* Process Next 16 bytes of MW UUID */
524 static gboolean __bt_hal_is_factory_test_mode(void)
528 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
529 ERR("Get the DUT Mode fail");
534 INFO("DUT Test Mode !!");
541 static gboolean __bt_hal_adv_event_cb(gpointer param)
543 bt_hal_adv_event_data_t *event = (bt_hal_adv_event_data_t*)param;
548 if (!gatt_le_event_cb) {
549 ERR("GATT event callback not registered!!!");
553 switch (event->event) {
554 case BT_HAL_MULTI_ADV_ENB_EVT: {
555 INFO("BLE Advertising enabled slot [%d]", event->server_if);
556 struct hal_ev_multi_adv_enable ev;
557 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_enable));
558 ev.status = event->status;
559 ev.server_instance = event->server_if;
560 gatt_le_event_cb(HAL_EV_MULTI_ADV_ENABLE, (void *)&ev, sizeof(ev));
563 case BT_HAL_MULTI_ADV_DISABLE_EVT: {
564 INFO("BLE Advertising disabled slot [%d]", event->server_if);
565 struct hal_ev_multi_adv_disable ev;
566 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_disable));
567 ev.status = event->status;
568 ev.server_instance = event->server_if;
569 gatt_le_event_cb(HAL_EV_MULTI_ADV_DISABLE, (void *)&ev, sizeof(ev));
572 case BT_HAL_MULTI_ADV_PARAM_EVT: {
573 INFO("Unhandled event slot [%d]", event->server_if);
576 case BT_HAL_MULTI_ADV_UPDATE_EVT: {
577 INFO("BLE Advertising Param update slot [%d]", event->server_if);
578 struct hal_ev_multi_adv_update ev;
579 memset(&ev, 0, sizeof(struct hal_ev_multi_adv_update));
580 ev.status = event->status;
581 ev.server_instance = event->server_if;
582 gatt_le_event_cb(HAL_EV_MULTI_ADV_UPDATE, (void *)&ev, sizeof(ev));
585 case BT_HAL_MULTI_ADV_DATA_EVT: {
586 INFO("BLE Advertising data set slot [%d]", event->server_if);
587 struct hal_ev_multi_adv_data_set ev_data_set;
589 memset(&ev_data_set, 0, sizeof(struct hal_ev_multi_adv_data_set));
590 ev_data_set.status = event->status;
591 ev_data_set.server_instance = event->server_if;
592 gatt_le_event_cb(HAL_EV_MULTI_ADV_DATA_SET, (void *)&ev_data_set, sizeof(ev_data_set));
595 case BT_HAL_LEGACY_ADV_STATUS: {
596 INFO("BLE Legacy Advertising [%d]", event->server_if);
597 struct hal_ev_legacy_adv_status ev;
599 memset(&ev, 0, sizeof(struct hal_ev_legacy_adv_status));
600 ev.status = event->status;
601 ev.server_instance = event->server_if;
602 gatt_le_event_cb(HAL_EV_LEGACY_ADV_ENABLE, (void *)&ev, sizeof(ev));
606 ERR("Unknown event");
615 int _bt_hal_enable_advertising(int server_if, int adv_slot_id, bool enable, bool is_multi_adv)
617 GError *error = NULL;
621 proxy = _bt_hal_get_adapter_proxy();
623 return BT_STATUS_FAIL;
625 if (le_adv_slot[adv_slot_id].is_advertising == TRUE && enable == TRUE) {
626 ERR("Already advertising inprogress. server_if %d, adv_slot_id %d",server_if, adv_slot_id);
627 return BT_STATUS_BUSY;
630 if (le_adv_slot[adv_slot_id].initialized == TRUE &&
631 le_adv_slot[adv_slot_id].is_advertising == FALSE &&
633 return BT_STATUS_DONE;
635 if (le_adv_slot[adv_slot_id].hold_timer_id > 0) {
636 g_source_remove(le_adv_slot[adv_slot_id].hold_timer_id);
637 le_adv_slot[adv_slot_id].hold_timer_id = 0;
640 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
641 g_variant_new("(bi)", enable, adv_slot_id),
642 G_DBUS_CALL_FLAGS_NONE,
648 ERR("SetAdvertising Fail: %s", error->message);
649 g_clear_error(&error);
650 return BT_STATUS_FAIL;
653 INFO_C("### %s advertising. gatt_server [%d] adv_slot_id [%d] Is Multi? [%d]",
654 enable ? "Start":"Stop", server_if, adv_slot_id, is_multi_adv);
656 g_variant_unref(ret);
658 le_adv_slot[adv_slot_id].is_multi_adv = is_multi_adv;
659 le_adv_slot[adv_slot_id].is_advertising = enable;
661 return BT_STATUS_SUCCESS;
664 int _bt_hal_set_advertising_params(int server_if, int min_interval,
665 int max_interval, int adv_type,
666 int chnl_map, int tx_power, int timeout_s)
670 GError *error = NULL;
673 bt_hal_adv_event_data_t *event;
677 proxy = _bt_hal_get_adapter_proxy();
679 return BT_STATUS_FAIL;
681 if (min_interval > max_interval ||
682 min_interval < BT_HAL_ADV_INTERVAL_MIN ||
683 max_interval > BT_HAL_ADV_INTERVAL_MAX)
684 return BT_STATUS_PARM_INVALID;
687 if (adv_type == BT_HAL_ADV_CONNECTABLE_DIRECT_HIGH ||
688 adv_type == BT_HAL_ADV_CONNECTABLE_DIRECT_LOW ||
689 adv_type == BT_HAL_ADV_NON_CONNECTABLE)
690 return BT_STATUS_UNSUPPORTED;
692 if (adv_filter_policy < 0 || adv_filter_policy > 3) {
693 ERR("Invalid filter policy, Setting the filter policy to default");
694 adv_filter_policy = BT_HAL_ADV_FILTER_POLICY_DEFAULT;
697 min = min_interval / BT_HAL_ADV_INTERVAL_SPLIT;
698 max = max_interval / BT_HAL_ADV_INTERVAL_SPLIT;
700 slot_id = bt_hal_gatts_allocate_adv_slot_by_server_if(server_if);
702 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
703 g_variant_new("(uuuuii)", min, max,
704 adv_filter_policy, adv_type,
705 tx_power, slot_id), G_DBUS_CALL_FLAGS_NONE,
708 ERR("SetAdvertisingParameters Fail: %s", error->message);
709 g_clear_error(&error);
710 return BT_STATUS_FAIL;
714 g_variant_unref(ret);
717 * As we need to provide async callback to user from HAL, simply schedule a
718 * callback method which will carry actual result
720 event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
721 event->event = BT_HAL_MULTI_ADV_UPDATE_EVT;
722 event->server_if = server_if;
723 event->status = BT_STATUS_SUCCESS;
724 g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
726 return BT_STATUS_SUCCESS;
729 static int __bt_hal_parse_service_data(int len, char *src, uint8_t *dest)
731 int total_service_len = len;
732 int service_data_len = 0;
736 if (src == NULL || dest == NULL)
741 while (total_service_len) {
742 /* parse length1 + service_data1 + length2 + service data2*/
743 service_data_len = ptr[0];
745 dest[idx] = 1 + service_data_len;
746 dest[idx + 1] = 0x16; /* Fixed */
747 memcpy(dest + idx + 2, ptr +1, service_data_len);
748 idx = idx + 2 + service_data_len;
750 ptr = ptr + service_data_len + 1;
751 total_service_len = total_service_len - service_data_len - 1;
758 /* Takes care of both Scan Response and Advertising data */
759 int _bt_hal_set_advertising_data(btgatt_adv_param_setup_t adv_param_setup)
761 uint8_t adv_data[31];
762 char adv_data_str[(31 * 2) + 1];
765 GError *error = NULL;
766 GVariant *ret = NULL;
767 GVariant *temp = NULL;
768 GVariantBuilder *builder;
769 bt_hal_adv_event_data_t *event;
774 /* Parse data according to Bluez Interface */
775 if (__bt_hal_is_factory_test_mode()) {
776 ERR("Unable to set advertising data in factory binary !!");
777 return BT_STATUS_UNSUPPORTED;
780 /* TODO: Check adapter and LE adapter status */
781 proxy = _bt_hal_get_adapter_proxy();
783 return BT_STATUS_FAIL;
785 slot_id = bt_hal_gatts_allocate_adv_slot_by_server_if(adv_param_setup.server_if);
787 memset(&adv_data, 0, 31);
790 if (adv_param_setup.service_uuid_len > 0) {
791 __bt_hal_parse_uuid(adv_param_setup.service_uuid_len,
792 adv_param_setup.service_uuid, &adv_data[index], &length, FALSE);
794 DBG("After Service UUID:Index [%d]", index);
798 if (adv_param_setup.solicit_uuid_len > 0) {
799 __bt_hal_parse_uuid(adv_param_setup.solicit_uuid_len,
800 adv_param_setup.solicit_uuid, &adv_data[index], &length, TRUE);
802 DBG("After Solicit UUID: Index [%d]", index);
805 /* Service Data UUID*/
806 if (adv_param_setup.service_data_len > 0) {
808 l = __bt_hal_parse_service_data(adv_param_setup.service_data_len,
809 adv_param_setup.service_data, &adv_data[index]);
817 if (adv_param_setup.include_appearance != 0) {
819 if (adv_param_setup.appearance > 0) {
821 adv_data[index] = 0x03;
822 adv_data[index+1] = 0x19;
823 adv_data[index+2] = (uint8_t) (adv_param_setup.appearance & 0xFF);
824 adv_data[index+3] = (uint8_t) ((adv_param_setup.appearance >> 8) & 0xFF);
827 DBG("After Apperance: Index [%d]", index);
831 if (adv_param_setup.include_txpower != 0) {
832 adv_data[index] = 0x01;
833 adv_data[index+1] = 0x0A;
836 DBG("After TX Power: Index [%d]", index);
840 if (adv_param_setup.include_name != 0) {
841 adv_data[index] = 0x01;
842 adv_data[index+1] = 0x09;
845 DBG("After Name: Index [%d]", index);
848 /* Manufacturer data */
849 if (adv_param_setup.manufacturer_data_len > 0) {
850 adv_data[index] = 1 + adv_param_setup.manufacturer_data_len;
851 adv_data[index+1] = 0xFF;
852 memcpy(&adv_data[index+2], adv_param_setup.manufacturer_data, adv_param_setup.manufacturer_data_len);
853 index += (2 + adv_param_setup.manufacturer_data_len);
854 length += (2 + adv_param_setup.manufacturer_data_len);
855 DBG("After Manuf Data: Index [%d]", index);
858 for (i = 0; i < length; i++)
859 snprintf(&adv_data_str[i * 2], 3, "%02X", adv_data[i]);
860 INFO("Set adv data. Index [%d] length [%d] Data[%s]", index, length, adv_data_str);
863 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
864 for (i = 0; i < length; i++)
865 g_variant_builder_add(builder, "y", adv_data[i]);
867 temp = g_variant_new("ay", builder);
868 g_variant_builder_unref(builder);
870 if (adv_param_setup.set_scan_rsp == 0) {
871 /* Set Advertising data to stack */
872 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
873 g_variant_new("(@ayi)", temp, slot_id),
874 G_DBUS_CALL_FLAGS_NONE,
877 /* Set Scan response data to stack */
878 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
879 g_variant_new("(@ayi)", temp, slot_id),
880 G_DBUS_CALL_FLAGS_NONE,
885 ERR("SetAdvertisingData Fail: %s", error->message);
886 g_clear_error(&error);
887 return BT_STATUS_FAIL;
890 INFO("Request of SetAdvertisingData or SetScanRespData is success");
893 g_variant_unref(ret);
896 * As we need to provide async callback to user from HAL, simply schedule a
897 * callback method which will carry actual result
899 event = g_malloc0(sizeof(bt_hal_adv_event_data_t));
900 event->event = BT_HAL_MULTI_ADV_DATA_EVT;
901 event->server_if = adv_param_setup.server_if;
902 event->status = BT_STATUS_SUCCESS;
903 memcpy(&event->data, adv_data, 31);
904 g_idle_add(__bt_hal_adv_event_cb, (gpointer)event);
906 return BT_STATUS_SUCCESS;
909 int _bt_hal_adapter_le_start_scan(void)
912 GError *error = NULL;
917 /* TODO: Check adapter and LE adapter status */
918 proxy = _bt_hal_get_adapter_proxy();
920 return BT_STATUS_FAIL;
922 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
923 NULL, G_DBUS_CALL_FLAGS_NONE,
927 ERR("StartLEDiscovery Fail: %s", error->message);
928 g_clear_error(&error);
931 return BT_STATUS_FAIL;
934 g_variant_unref(ret);
936 return BT_STATUS_SUCCESS;
939 int _bt_hal_adapter_le_stop_scan(void)
942 GError *error = NULL;
947 /* TODO: Check adapter and LE adapter status */
948 proxy = _bt_hal_get_adapter_proxy();
950 return BT_STATUS_FAIL;
952 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
953 NULL, G_DBUS_CALL_FLAGS_NONE,
957 g_dbus_error_strip_remote_error(error);
958 ERR("StopLEDiscovery Fail: %s", error->message);
961 /* Abnormal case for ARTIK530 */
962 if (g_strrstr(error->message, "No discovery started") ||
963 g_strrstr(error->message, "Operation already in progress")) {
964 g_clear_error(&error);
965 return BT_STATUS_SUCCESS;
969 g_clear_error(&error);
970 return BT_STATUS_FAIL;
974 g_variant_unref(ret);
976 bt_hal_release_pending_adv_ind_list();
978 return BT_STATUS_SUCCESS;
981 /*sets the privacy functionality of the adapter*/
982 int _bt_hal_adapter_le_set_privacy(uint8_t set_privacy)
985 GError *error = NULL;
986 GVariant *result = NULL;
987 proxy = _bt_hal_get_adapter_proxy();
989 return BT_STATUS_FAIL;
991 result = g_dbus_proxy_call_sync(proxy,
993 g_variant_new("(b)", set_privacy),
994 G_DBUS_CALL_FLAGS_NONE,
1000 if (error != NULL) {
1001 ERR("Failed to SetLePrivacy (Error: %s)", error->message);
1002 g_clear_error(&error);
1004 ERR("Failed to SetLePrivacy");
1005 return BT_STATUS_FAIL;
1008 g_variant_unref(result);
1009 INFO("SetLePrivacy as %d", set_privacy);
1010 return BT_STATUS_SUCCESS;
1013 int _bt_hal_adapter_le_set_scan_parameters(
1014 int scan_type, int scan_interval, int scan_window)
1017 GError *error = NULL;
1022 /* TODO: Check adapter and LE adapter status */
1023 proxy = _bt_hal_get_adapter_proxy();
1025 return BT_STATUS_FAIL;
1027 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
1028 g_variant_new("(uuu)", scan_type, scan_interval, scan_window),
1029 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1032 ERR("SetScanParameters Fail: %s", error->message);
1033 g_clear_error(&error);
1036 return BT_STATUS_FAIL;
1039 g_variant_unref(ret);
1041 return BT_STATUS_SUCCESS;
1044 /* To send stack event to hal-av handler */
1045 void _bt_hal_register_gatt_le_dbus_handler_cb(handle_stack_msg cb)
1047 gatt_le_event_cb = cb;
1050 void _bt_hal_unregister_gatt_le_dbus_handler_cb(void)
1052 gatt_le_event_cb = NULL;
1055 int _bt_hal_adapter_le_set_manufacturer_data(bt_manufacturer_data_t *m_data)
1058 GError *error = NULL;
1062 GVariantBuilder *builder;
1064 proxy = _bt_hal_get_adapter_proxy();
1066 return BT_STATUS_FAIL;
1068 if (m_data->data_len + 2 >= BT_MANUFACTURER_DATA_LENGTH_MAX)
1069 return BT_STATUS_PARM_INVALID;
1071 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1073 for (i = 0; i < (m_data->data_len) + 2; i++)
1074 g_variant_builder_add(builder, "y", m_data->data[i]);
1076 val = g_variant_new("(ay)", builder);
1078 ret = g_dbus_proxy_call_sync(proxy,
1079 "SetManufacturerData",
1081 G_DBUS_CALL_FLAGS_NONE,
1085 g_variant_builder_unref(builder);
1087 if (error != NULL) {
1088 ERR("Failed to SetManufacturerData (Error: %s)", error->message);
1089 g_clear_error(&error);
1091 ERR("Failed to SetManufacturerData");
1093 return BT_STATUS_FAIL;
1096 INFO("Set manufacturer data");
1097 g_variant_unref(ret);
1099 return BT_STATUS_SUCCESS;
1104 /*add/remove remote device address from white list*/
1105 int _bt_hal_adapter_le_set_white_list(bt_bdaddr_t *device_address, bt_dev_addr_type_t address_type, bool is_add)
1108 char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
1109 GError *error = NULL;
1112 if (address_type != BLUETOOTH_HAL_DEVICE_PUBLIC_ADDRESS &&
1113 address_type != BLUETOOTH_HAL_DEVICE_RANDOM_ADDRESS)
1114 return BT_STATUS_PARM_INVALID;
1116 _bt_hal_convert_addr_type_to_string(address, device_address->address);
1118 proxy = _bt_hal_get_adapter_proxy();
1120 return BT_STATUS_FAIL;
1122 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1123 g_variant_new("(su)", address, address_type),
1124 G_DBUS_CALL_FLAGS_NONE, -1,
1127 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1128 g_variant_new("(su)", address, address_type),
1129 G_DBUS_CALL_FLAGS_NONE, -1,
1134 ERR("RemoveDeviceWhiteList Fail: %s", error->message);
1136 ERR("AddDeviceWhiteList Fail: %s", error->message);
1137 g_clear_error(&error);
1138 return BT_STATUS_FAIL;
1142 g_variant_unref(ret);
1144 INFO("Device Added to white list");
1146 INFO("Device Removed from white list");
1147 return BT_STATUS_SUCCESS;