2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dbus/dbus.h>
25 #include <syspopup_caller.h>
28 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-event.h"
31 #include "bt-service-adapter.h"
32 #include "bt-service-adapter-le.h"
33 #include "bt-service-util.h"
36 #define BT_ADV_INTERVAL_MIN 20 /* msec */
37 #define BT_ADV_INTERVAL_MAX 10240
38 #define BT_ADV_INTERVAL_SPLIT 0.625
39 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
40 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
41 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
42 #define BT_ADV_TYPE_DEFAULT 0x00
43 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
44 #define BT_SCAN_INTERVAL_SPLIT 0.625
51 } bt_adapter_le_feature_info_t;
56 gboolean is_advertising;
58 } bt_adapter_le_adv_slot_t;
64 gboolean stop_pending;
65 } bt_adapter_le_scanner_t;
67 static bluetooth_advertising_params_t adv_params = {
68 BT_DEFAULT_ADV_MIN_INTERVAL,
69 BT_DEFAULT_ADV_MAX_INTERVAL,
70 BT_ADV_FILTER_POLICY_DEFAULT,
72 static bluetooth_advertising_data_t adv_data = { {0} };
73 static int adv_data_len;
74 static bluetooth_scan_resp_data_t resp_data = { {0} };
75 static int resp_data_len;
77 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
78 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
80 GSList *scanner_list = NULL;
81 static gboolean is_le_set_scan_parameter = FALSE;
82 static gboolean is_le_scanning = FALSE;
83 static gboolean scan_filter_enabled = FALSE;
84 static bt_le_scan_type_t le_scan_type = BT_LE_ACTIVE_SCAN;
85 static bluetooth_le_scan_params_t le_scan_params = { BT_LE_ACTIVE_SCAN, 0, 0 };
87 static GSList *gatt_client_senders = NULL;
90 gboolean _bt_is_set_scan_parameter(void)
92 return is_le_set_scan_parameter;
95 void _bt_init_gatt_client_senders(void)
97 _bt_clear_request_list();
100 int _bt_insert_gatt_client_sender(char *sender)
104 retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
106 info = g_strdup(sender);
107 retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
109 gatt_client_senders = g_slist_append(gatt_client_senders, info);
111 BT_DBG("insert sender: %s", sender);
113 return BLUETOOTH_ERROR_NONE;
116 int _bt_delete_gatt_client_sender(char *sender)
121 BT_DBG("remove sender: %s", sender);
123 for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) {
128 if (g_strcmp0(info, sender) == 0) {
129 BT_DBG("remove info");
130 gatt_client_senders = g_slist_remove(gatt_client_senders, info);
132 return BLUETOOTH_ERROR_NONE;
136 return BLUETOOTH_ERROR_NOT_FOUND;
139 void _bt_clear_gatt_client_senders(void)
141 if (gatt_client_senders) {
142 g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL);
143 g_slist_free(gatt_client_senders);
144 gatt_client_senders = NULL;
148 static void __bt_send_foreach_event(gpointer data, gpointer user_data)
151 GVariant *param = user_data;
153 _bt_send_event_to_dest(sender, BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
157 void _bt_send_char_value_changed_event(void *param)
160 g_slist_foreach(gatt_client_senders, __bt_send_foreach_event,
163 _bt_send_event(BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED, param);
167 void __bt_free_le_adv_slot(void)
171 if (le_adv_slot == NULL)
174 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
175 if (le_adv_slot[i].sender)
176 g_free(le_adv_slot[i].sender);
177 if (le_adv_slot[i].hold_timer_id > 0)
178 g_source_remove(le_adv_slot[i].hold_timer_id);
184 int _bt_le_set_max_packet_len(void)
186 int result = BLUETOOTH_ERROR_NONE;
187 int tx_octets, tx_time;
188 bluetooth_le_read_maximum_data_length_t max_len = {0};
190 if (BLUETOOTH_ERROR_NONE != _bt_le_read_maximum_data_length(&max_len))
191 return BLUETOOTH_ERROR_INTERNAL;
193 if (max_len.max_tx_octets > BT_LE_TX_LEN_DEFAULT) {
194 tx_octets = max_len.max_tx_octets > BT_LE_TX_LEN_MAX ?
195 BT_LE_TX_LEN_MAX : max_len.max_tx_octets;
196 tx_time = BT_LE_TX_TIME_MAX;
198 result = _bt_le_write_host_suggested_default_data_length(tx_octets, tx_time);
200 BT_DBG("Wrote max packet size : result[%d], MAX[%d], set[%d]",
201 result, max_len.max_tx_octets, tx_octets);
207 gboolean _bt_update_le_feature_support(const char *item, const char *value)
209 if (item == NULL || value == NULL)
213 _bt_service_adapter_le_init();
215 if (g_strcmp0(item, "adv_inst_max") == 0) {
218 slot_num = atoi(value);
219 retv_if(slot_num < 0, FALSE);
221 if (slot_num != le_feature_info.adv_inst_max) {
222 __bt_free_le_adv_slot();
223 le_feature_info.adv_inst_max = slot_num;
224 BT_INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
225 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
227 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
228 le_feature_info.rpa_offloading = atoi(value);
229 BT_INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
230 } else if (g_strcmp0(item, "max_filter") == 0) {
231 le_feature_info.max_filter = atoi(value);
232 BT_INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
234 BT_DBG("No registered item");
241 static gboolean __bt_is_factory_test_mode(void)
245 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
246 BT_ERR("Get the DUT Mode fail");
251 BT_INFO("DUT Test Mode !!");
258 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
262 if (le_adv_slot == NULL) {
263 BT_ERR("le_adv_slot is NULL");
267 BT_DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
269 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
270 if (le_adv_slot[i].sender == NULL)
272 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
276 if (le_feature_info.adv_inst_max <= 1)
278 else if (use_reserved_slot == TRUE)
283 for (; i < le_feature_info.adv_inst_max; i++) {
284 if (le_adv_slot[i].sender == NULL)
291 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
293 if (le_adv_slot[slot_id].sender == NULL) {
294 le_adv_slot[slot_id].sender = strdup(sender);
295 le_adv_slot[slot_id].adv_handle = adv_handle;
299 void _bt_unregister_adv_slot_owner(int slot_id)
301 if (le_adv_slot[slot_id].hold_timer_id > 0) {
302 BT_INFO("Hold state adv is not unregistered");
306 g_free(le_adv_slot[slot_id].sender);
307 le_adv_slot[slot_id].sender = NULL;
308 le_adv_slot[slot_id].adv_handle = 0;
311 const char* _bt_get_adv_slot_owner(int slot_id)
313 if (le_adv_slot == NULL)
316 return le_adv_slot[slot_id].sender;
319 int _bt_get_adv_slot_adv_handle(int slot_id)
321 if (le_adv_slot == NULL)
324 return le_adv_slot[slot_id].adv_handle;
327 void _bt_set_advertising_status(int slot_id, gboolean mode)
329 le_adv_slot[slot_id].is_advertising = mode;
332 gboolean _bt_is_advertising(void)
334 gboolean status = FALSE;
337 if (le_adv_slot == NULL)
340 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
341 if (le_adv_slot[i].is_advertising == TRUE)
348 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
352 if (le_adv_slot == NULL)
355 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
356 if (le_adv_slot[i].sender != NULL) {
357 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
358 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
359 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
365 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
370 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
375 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
378 GError *error = NULL;
382 if (__bt_is_factory_test_mode()) {
383 BT_ERR("Unable to start advertising in factory binary !!");
384 return BLUETOOTH_ERROR_NOT_SUPPORT;
387 if (_bt_adapter_get_status() != BT_ACTIVATED &&
388 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
389 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
392 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
394 BT_ERR("There is NO available slot!!");
395 return BLUETOOTH_ERROR_NO_RESOURCES;
398 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
399 return BLUETOOTH_ERROR_IN_PROGRESS;
401 if (le_adv_slot[slot_id].hold_timer_id > 0) {
402 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
403 le_adv_slot[slot_id].hold_timer_id = 0;
404 _bt_unregister_adv_slot_owner(slot_id);
407 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
408 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
410 proxy = _bt_get_adapter_proxy();
411 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
413 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
414 g_variant_new("(bi)", enable, slot_id),
415 G_DBUS_CALL_FLAGS_NONE,
421 BT_INFO("SetAdvertising %d, slot_id %d", enable, slot_id);
422 BT_ERR("SetAdvertising Fail: %s", error->message);
423 g_clear_error(&error);
424 return BLUETOOTH_ERROR_INTERNAL;
428 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
430 le_adv_slot[slot_id].is_advertising = enable;
431 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
434 g_variant_unref(ret);
436 return BLUETOOTH_ERROR_NONE;
439 int _bt_set_custom_advertising(const char *sender, int adv_handle,
440 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
444 GError *error = NULL;
449 BT_CHECK_PARAMETER(params, return);
451 if (__bt_is_factory_test_mode()) {
452 BT_ERR("Unable to start advertising in factory binary !!");
453 return BLUETOOTH_ERROR_NOT_SUPPORT;
456 if (_bt_adapter_get_status() != BT_ACTIVATED &&
457 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
458 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
461 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
463 BT_ERR("There is NO available slot!!");
464 return BLUETOOTH_ERROR_NO_RESOURCES;
467 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
468 return BLUETOOTH_ERROR_IN_PROGRESS;
470 if (le_adv_slot[slot_id].hold_timer_id > 0) {
471 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
472 le_adv_slot[slot_id].hold_timer_id = 0;
473 _bt_unregister_adv_slot_owner(slot_id);
476 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
477 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
479 proxy = _bt_get_adapter_proxy();
480 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
482 if (params->interval_min > params->interval_max ||
483 params->interval_min < BT_ADV_INTERVAL_MIN ||
484 params->interval_max > BT_ADV_INTERVAL_MAX)
485 return BLUETOOTH_ERROR_INVALID_PARAM;
487 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
488 return BLUETOOTH_ERROR_INVALID_PARAM;
490 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
491 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
492 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
493 return BLUETOOTH_ERROR_NOT_SUPPORT;
495 if (params->tx_power_level > 1 ||
496 params->tx_power_level < -127)
497 return BLUETOOTH_ERROR_INVALID_PARAM;
499 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
500 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
502 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
503 g_variant_new("(uuuuii)", min, max,
504 params->filter_policy, params->type,
505 params->tx_power_level, slot_id),
506 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
509 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
510 g_clear_error(&error);
511 return BLUETOOTH_ERROR_INTERNAL;
514 adv_params.interval_min = params->interval_min;
515 adv_params.interval_max = params->interval_max;
516 adv_params.filter_policy = params->filter_policy;
517 adv_params.type = params->type;
518 adv_params.tx_power_level = params->tx_power_level;
521 g_variant_unref(ret);
523 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
524 g_variant_new("(bi)", enable, slot_id),
525 G_DBUS_CALL_FLAGS_NONE,
531 BT_ERR("SetAdvertising Fail: %s", error->message);
532 g_clear_error(&error);
533 return BLUETOOTH_ERROR_INTERNAL;
537 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
539 le_adv_slot[slot_id].is_advertising = enable;
540 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
542 g_variant_unref(ret);
544 return BLUETOOTH_ERROR_NONE;
547 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
550 GError *error = NULL;
553 BT_INFO("Restart advertising stopped by bt-service");
555 le_adv_slot[0].hold_timer_id = 0;
557 proxy = _bt_get_adapter_proxy();
558 retv_if(proxy == NULL, FALSE);
560 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
561 g_variant_new("(bi)", TRUE, 0),
562 G_DBUS_CALL_FLAGS_NONE,
568 BT_ERR("SetAdvertising Fail: %s", error->message);
569 g_clear_error(&error);
574 g_variant_unref(ret);
579 int _bt_hold_current_advertising(void)
582 GError *error = NULL;
585 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
586 BT_INFO("Stop current advertising by bt-service");
588 proxy = _bt_get_adapter_proxy();
589 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
591 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
592 g_variant_new("(bi)", FALSE, 0),
593 G_DBUS_CALL_FLAGS_NONE,
599 BT_ERR("SetAdvertising Fail: %s", error->message);
600 g_clear_error(&error);
601 return BLUETOOTH_ERROR_INTERNAL;
605 g_variant_unref(ret);
607 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
608 __bt_hold_current_advertising_timeout_cb, NULL);
610 BT_INFO("It's NOT advertising");
611 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
614 return BLUETOOTH_ERROR_NONE;
617 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
618 char in_type, char **data, int *data_len)
620 if (in_data == NULL || data == NULL || data_len == NULL)
621 return BLUETOOTH_ERROR_INTERNAL;
624 return BLUETOOTH_ERROR_INTERNAL;
630 for (i = 0; i < in_len; i++) {
632 if (len <= 0 || i + 1 >= in_len) {
633 BT_ERR("Invalid advertising data");
634 return BLUETOOTH_ERROR_INTERNAL;
637 type = in_data[i + 1];
638 if (type == in_type) {
648 if (i + len > in_len) {
649 BT_ERR("Invalid advertising data");
650 return BLUETOOTH_ERROR_INTERNAL;
651 } else if (len == 0) {
652 BT_DBG("AD Type 0x%02x data is not set", in_type);
655 return BLUETOOTH_ERROR_NONE;
658 *data = g_memdup(&in_data[i], len);
660 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
663 return BLUETOOTH_ERROR_NONE;
666 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
668 BT_CHECK_PARAMETER(adv, return);
669 BT_CHECK_PARAMETER(length, return);
671 memcpy(adv, &adv_data, sizeof(adv_data));
672 *length = adv_data_len;
674 return BLUETOOTH_ERROR_NONE;
677 int _bt_set_advertising_data(const char *sender, int adv_handle,
678 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
681 GError *error = NULL;
682 GVariant *ret, *ad_data, *param = NULL;
683 GVariant *temp = NULL;
684 GVariantBuilder *builder;
686 char *old_mdata = NULL;
687 char *new_mdata = NULL;
692 if (__bt_is_factory_test_mode()) {
693 BT_ERR("Unable to set advertising data in factory binary !!");
694 return BLUETOOTH_ERROR_NOT_SUPPORT;
697 BT_CHECK_PARAMETER(adv, return);
699 if (_bt_adapter_get_status() != BT_ACTIVATED &&
700 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
701 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
704 proxy = _bt_get_adapter_proxy();
705 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
707 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
709 BT_ERR("There is NO available slot!!");
710 return BLUETOOTH_ERROR_NO_RESOURCES;
713 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
714 for (i = 0; i < length; i++)
715 g_variant_builder_add(builder, "y", adv->data[i]);
717 temp = g_variant_new("ay", builder);
718 g_variant_builder_unref(builder);
719 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
720 g_variant_new("(@ayi)", temp, slot_id),
721 G_DBUS_CALL_FLAGS_NONE,
725 BT_ERR("SetAdvertisingData Fail: %s", error->message);
726 g_clear_error(&error);
727 return BLUETOOTH_ERROR_INTERNAL;
730 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
732 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
733 &old_mdata, &old_len);
734 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
735 &new_mdata, &new_len);
736 if (old_len != new_len ||
737 (old_mdata && new_mdata &&
738 memcmp(old_mdata, new_mdata, new_len))) {
739 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
740 new_mdata, new_len, TRUE, NULL, NULL);
741 param = g_variant_new("(@ay)", ad_data);
742 _bt_send_event(BT_ADAPTER_EVENT,
743 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
749 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
750 memcpy(&adv_data, adv, length);
751 adv_data_len = length;
753 BT_INFO("Set advertising data");
755 g_variant_unref(ret);
757 return BLUETOOTH_ERROR_NONE;
760 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
762 BT_CHECK_PARAMETER(response, return);
763 BT_CHECK_PARAMETER(length, return);
765 memcpy(response, &resp_data, sizeof(resp_data));
766 *length = resp_data_len;
768 return BLUETOOTH_ERROR_NONE;
771 int _bt_set_scan_response_data(const char *sender, int adv_handle,
772 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
775 GError *error = NULL;
776 GVariant *ret, *scan_data, *param = NULL;
777 GVariant *temp = NULL;
778 GVariantBuilder *builder;
780 char *old_mdata = NULL;
781 char *new_mdata = NULL;
786 if (__bt_is_factory_test_mode()) {
787 BT_ERR("Unable to set scan response list in factory binary !!");
788 return BLUETOOTH_ERROR_NOT_SUPPORT;
791 BT_CHECK_PARAMETER(response, return);
793 if (_bt_adapter_get_status() != BT_ACTIVATED &&
794 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
795 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
798 proxy = _bt_get_adapter_proxy();
799 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
801 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
803 BT_ERR("There is NO available slot!!");
804 return BLUETOOTH_ERROR_NO_RESOURCES;
806 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
807 for (i = 0; i < length; i++)
808 g_variant_builder_add(builder, "y", response->data[i]);
810 temp = g_variant_new("ay", builder);
811 g_variant_builder_unref(builder);
812 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
813 g_variant_new("(@ayi)", temp, slot_id),
814 G_DBUS_CALL_FLAGS_NONE,
818 BT_ERR("SetScanRespData Fail: %s", error->message);
819 g_clear_error(&error);
820 return BLUETOOTH_ERROR_INTERNAL;
823 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
825 /* Compare with previous scan resp data */
826 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
827 &old_mdata, &old_len);
828 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
829 &new_mdata, &new_len);
830 if (old_len != new_len ||
831 (old_mdata && new_mdata &&
832 memcmp(old_mdata, new_mdata, new_len))) {
833 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
834 new_mdata, new_len, TRUE, NULL, NULL);
835 param = g_variant_new("(@ay)", scan_data);
836 _bt_send_event(BT_ADAPTER_EVENT,
837 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
843 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
844 memcpy(&resp_data, response, length);
845 resp_data_len = length;
848 g_variant_unref(ret);
849 BT_INFO("Set scan response data");
850 return BLUETOOTH_ERROR_NONE;
853 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
856 GError *error = NULL;
861 BT_CHECK_PARAMETER(params, return);
863 if (_bt_adapter_get_status() != BT_ACTIVATED &&
864 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
865 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
868 proxy = _bt_get_adapter_proxy();
869 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
871 BT_DBG("inteval %f, win %f, type %d", params->interval, params->window, params->type);
873 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
874 return BLUETOOTH_ERROR_INVALID_PARAM;
876 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
877 return BLUETOOTH_ERROR_INVALID_PARAM;
879 if (params->window > params->interval)
880 return BLUETOOTH_ERROR_INVALID_PARAM;
882 itv = params->interval / BT_SCAN_INTERVAL_SPLIT;
883 win = params->window / BT_SCAN_INTERVAL_SPLIT;
885 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
886 g_variant_new("(uuu)", params->type, itv, win),
887 G_DBUS_CALL_FLAGS_NONE, -1,
891 BT_ERR("SetScanParameters Fail: %s", error->message);
892 g_clear_error(&error);
893 return BLUETOOTH_ERROR_INTERNAL;
896 _bt_set_le_scan_type(params->type);
898 is_le_set_scan_parameter = TRUE;
901 g_variant_unref(ret);
902 BT_INFO("Set scan parameters inteval %f, win %f, type %d",
903 itv * BT_SCAN_INTERVAL_SPLIT, win * BT_SCAN_INTERVAL_SPLIT, params->type);
904 return BLUETOOTH_ERROR_NONE;
907 int _bt_prepare_scan_parameters(bluetooth_le_scan_params_t *params, int scan_type)
909 if (_bt_adapter_get_status() != BT_ACTIVATED &&
910 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
911 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
915 BT_DBG("inteval %f, win %f", params->interval, params->window);
917 BT_DBG("type %d", scan_type);
920 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
921 return BLUETOOTH_ERROR_INVALID_PARAM;
923 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
924 return BLUETOOTH_ERROR_INVALID_PARAM;
926 if (params->window > params->interval)
927 return BLUETOOTH_ERROR_INVALID_PARAM;
929 le_scan_params.interval = params->interval;
930 le_scan_params.window = params->window;
932 le_scan_params.type = scan_type;
933 if (le_scan_params.interval == 0) {
934 /* Set default scan interval same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
935 le_scan_params.interval = 5120;
936 le_scan_params.window = 512;
940 is_le_set_scan_parameter = TRUE;
942 return BLUETOOTH_ERROR_NONE;
945 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
948 bt_adapter_le_scanner_t *scanner;
950 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
952 if (g_strcmp0(scanner->sender, sender) == 0)
959 int __bt_get_available_scan_filter_slot_id(void)
962 bt_adapter_le_scanner_t *scanner;
964 bluetooth_le_scan_filter_t *filter_data;
965 gboolean *slot_check_list = NULL;
968 if (le_feature_info.max_filter == 0) {
969 BT_ERR("Scan filter is NOT Supported");
972 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
974 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
976 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
977 filter_data = fl->data;
978 if (filter_data->slot_id < le_feature_info.max_filter)
979 slot_check_list[filter_data->slot_id] = TRUE;
983 for (i = 0; i < le_feature_info.max_filter; i++) {
984 if (slot_check_list[i] == FALSE) {
985 g_free(slot_check_list);
990 BT_ERR("There is NO available slot for scan filter.");
991 g_free(slot_check_list);
995 gboolean _bt_is_scan_filter_supported(void)
997 if (le_feature_info.max_filter > 0)
1003 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
1006 GError *error = NULL;
1007 GVariant *ret, *param;
1008 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
1009 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
1010 GArray *arr_uuid = NULL;
1011 GArray *arr_uuid_mask = NULL;
1012 GArray *arr_data = NULL;
1013 GArray *arr_data_mask = NULL;
1014 bt_adapter_le_scanner_t *scanner = NULL;
1015 bluetooth_le_scan_filter_t *filter_data = NULL;
1016 int feature_selection = 0;
1018 *slot_id = __bt_get_available_scan_filter_slot_id();
1020 return BLUETOOTH_ERROR_NO_RESOURCES;
1022 proxy = _bt_get_adapter_proxy();
1023 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1025 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1026 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1027 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
1029 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
1031 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1032 NULL, 0, TRUE, NULL, NULL);
1033 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1034 NULL, 0, TRUE, NULL, NULL);
1035 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1036 NULL, 0, TRUE, NULL, NULL);
1037 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1038 NULL, 0, TRUE, NULL, NULL);
1040 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1042 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1043 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
1044 *slot_id, // filter_index
1046 0, // company_id_mask
1047 arr_uuid_param, // p_uuid
1048 arr_uuid_mask_param, // p_uuid_mask
1051 arr_data_param, // p_data
1052 arr_data_mask_param); // p_mask
1054 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1055 param, G_DBUS_CALL_FLAGS_NONE,
1059 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1060 g_clear_error(&error);
1063 g_variant_unref(ret);
1066 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1067 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
1069 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1070 NULL, 0, TRUE, NULL, NULL);
1071 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1072 NULL, 0, TRUE, NULL, NULL);
1073 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1074 NULL, 0, TRUE, NULL, NULL);
1075 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1076 NULL, 0, TRUE, NULL, NULL);
1078 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1080 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1081 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1082 *slot_id, // filter_index
1084 0, // company_id_mask
1085 arr_uuid_param, // p_uuid
1086 arr_uuid_mask_param, // p_uuid_mask
1087 filter->device_name, // string
1089 arr_data_param, // p_data
1090 arr_data_mask_param);
1092 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1093 param, G_DBUS_CALL_FLAGS_NONE,
1097 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1098 g_clear_error(&error);
1101 g_variant_unref(ret);
1104 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1105 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1107 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1108 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1110 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1111 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1113 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1114 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1115 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1116 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1117 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1118 NULL, 0, TRUE, NULL, NULL);
1119 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1120 NULL, 0, TRUE, NULL, NULL);
1122 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1124 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1125 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1126 *slot_id, // filter_index
1128 0, // company_id_mask
1129 arr_uuid_param, // p_uuid
1130 arr_uuid_mask_param, // p_uuid_mask
1133 arr_data_param, // p_data
1134 arr_data_mask_param);
1136 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1137 param, G_DBUS_CALL_FLAGS_NONE,
1141 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1142 g_clear_error(&error);
1145 g_variant_unref(ret);
1147 g_array_free(arr_uuid, TRUE);
1148 g_array_free(arr_uuid_mask, TRUE);
1151 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1152 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1154 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1155 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1157 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1158 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1160 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1161 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1162 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1163 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1164 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1165 NULL, 0, TRUE, NULL, NULL);
1166 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1167 NULL, 0, TRUE, NULL, NULL);
1169 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1171 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1172 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1173 *slot_id, // filter_index
1175 0, // company_id_mask
1176 arr_uuid_param, // p_uuid
1177 arr_uuid_mask_param, // p_uuid_mask
1180 arr_data_param, // p_data
1181 arr_data_mask_param);
1183 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1184 G_DBUS_CALL_FLAGS_NONE,
1188 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1189 g_clear_error(&error);
1192 g_variant_unref(ret);
1194 g_array_free(arr_uuid, TRUE);
1195 g_array_free(arr_uuid_mask, TRUE);
1198 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1199 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1201 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1202 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1204 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1205 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1207 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1208 NULL, 0, TRUE, NULL, NULL);
1209 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1210 NULL, 0, TRUE, NULL, NULL);
1211 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1212 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1213 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1214 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1216 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1218 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1219 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1220 *slot_id, // filter_index
1222 0, // company_id_mask
1223 arr_uuid_param, // p_uuid
1224 arr_uuid_mask_param, // p_uuid_mask
1227 arr_data_param, // p_data
1228 arr_data_mask_param);
1230 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1231 G_DBUS_CALL_FLAGS_NONE,
1235 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1236 g_clear_error(&error);
1239 g_variant_unref(ret);
1241 g_array_free(arr_data, TRUE);
1242 g_array_free(arr_data_mask, TRUE);
1245 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1246 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1248 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1249 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1251 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1252 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1254 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1255 NULL, 0, TRUE, NULL, NULL);
1256 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1257 NULL, 0, TRUE, NULL, NULL);
1258 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1259 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1260 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1261 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1263 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1265 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1266 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1267 *slot_id, // filter_index
1268 filter->manufacturer_id, // company_id
1269 0xFFFF, // company_id_mask
1270 arr_uuid_param, // p_uuid
1271 arr_uuid_mask_param, // p_uuid_mask
1274 arr_data_param, // p_data
1275 arr_data_mask_param);
1277 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1278 G_DBUS_CALL_FLAGS_NONE,
1282 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1283 g_clear_error(&error);
1286 g_variant_unref(ret);
1288 g_array_free(arr_data, TRUE);
1289 g_array_free(arr_data_mask, TRUE);
1292 BT_DBG("Filter selection %.2x", feature_selection);
1294 param = g_variant_new("(iiiiiiiiiiii)",
1296 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1297 *slot_id, // filter_index
1298 feature_selection, // feat_seln
1299 0, // list_logic_type (OR - 0x00, AND - 0x01)
1300 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1301 -127, // rssi_high_thres
1302 -127, // rssi_low_thres
1303 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1306 0); // found_timeout_cnt
1307 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1308 param, G_DBUS_CALL_FLAGS_NONE,
1312 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1313 g_clear_error(&error);
1316 scanner = __bt_find_scanner_from_list(sender);
1317 if (scanner == NULL) {
1318 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1319 scanner->sender = g_strdup(sender);
1320 scanner_list = g_slist_append(scanner_list, scanner);
1325 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1326 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1327 filter_data->slot_id = *slot_id;
1329 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1333 g_variant_unref(ret);
1334 return BLUETOOTH_ERROR_NONE;
1337 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1340 GError *error = NULL;
1342 bt_adapter_le_scanner_t *scanner = NULL;
1343 bluetooth_le_scan_filter_t *filter_data = NULL;
1345 gboolean is_slot_id_found = FALSE;
1347 scanner = __bt_find_scanner_from_list(sender);
1348 if (scanner == NULL) {
1349 BT_ERR("There is NO available scanner.");
1350 return BLUETOOTH_ERROR_NOT_FOUND;
1353 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1354 filter_data = l->data;
1355 if (filter_data->slot_id == slot_id) {
1356 is_slot_id_found = TRUE;
1360 if (is_slot_id_found == FALSE) {
1361 BT_ERR("There is NO registered slot.");
1362 return BLUETOOTH_ERROR_NOT_FOUND;
1365 proxy = _bt_get_adapter_proxy();
1366 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1368 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1369 g_variant_new("(ii)", 0, slot_id),
1370 G_DBUS_CALL_FLAGS_NONE,
1374 BT_ERR("scan_filter_clear Fail: %s", error->message);
1375 g_clear_error(&error);
1378 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1379 g_free(filter_data);
1382 g_variant_unref(ret);
1383 return BLUETOOTH_ERROR_NONE;
1386 int _bt_unregister_all_scan_filters(const char *sender)
1389 GError *error = NULL;
1391 bt_adapter_le_scanner_t *scanner = NULL;
1392 bluetooth_le_scan_filter_t *filter_data = NULL;
1395 scanner = __bt_find_scanner_from_list(sender);
1396 if (scanner == NULL) {
1397 BT_ERR("There is NO available scanner.");
1398 return BLUETOOTH_ERROR_NOT_FOUND;
1401 proxy = _bt_get_adapter_proxy();
1402 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1404 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1405 filter_data = l->data;
1407 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1408 g_variant_new("(ii)", 0, filter_data->slot_id),
1409 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1412 BT_ERR("scan_filter_clear Fail: %s", error->message);
1413 g_clear_error(&error);
1416 g_variant_unref(ret);
1419 g_slist_free_full(scanner->filter_list, g_free);
1420 scanner->filter_list = NULL;
1422 return BLUETOOTH_ERROR_NONE;
1425 static gboolean __start_le_scan_timeout(gpointer user_data)
1427 char *sender = (char *)user_data;
1428 _bt_start_le_scan(sender);
1434 int _bt_start_le_scan(const char *sender)
1437 GError *error = NULL;
1439 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1441 if (scanner == NULL) {
1442 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1443 scanner->sender = g_strdup(sender);
1444 scanner_list = g_slist_append(scanner_list, scanner);
1447 if (scanner->stop_pending == TRUE) {
1448 BT_DBG("Waiting LEDiscoveryFinished");
1449 g_timeout_add(500, (GSourceFunc)__start_le_scan_timeout, scanner->sender);
1450 return BLUETOOTH_ERROR_NONE;
1453 if (scanner->is_scanning == TRUE) {
1454 BT_ERR("BT is already in LE scanning");
1455 return BLUETOOTH_ERROR_IN_PROGRESS;
1457 scanner->is_scanning = TRUE;
1459 proxy = _bt_get_adapter_proxy();
1460 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1462 if (_bt_is_le_scanning()) {
1463 if (scan_filter_enabled == TRUE) {
1464 if (scanner->filter_list == NULL) {
1465 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1466 g_variant_new("(ib)", 0, FALSE),
1467 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1470 BT_ERR("scan_filter_enable Fail: %s", error->message);
1471 g_clear_error(&error);
1475 g_variant_unref(ret);
1476 BT_INFO("Disable LE Scan Filter");
1477 scan_filter_enabled = FALSE;
1479 BT_INFO("LE Filter Scan is continue");
1482 BT_INFO("LE Full Scan is already on progress");
1484 return BLUETOOTH_ERROR_NONE;
1486 if (is_le_set_scan_parameter == FALSE) {
1487 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1488 bluetooth_le_scan_params_t scan_params;
1489 scan_params.type = BT_LE_ACTIVE_SCAN;
1490 scan_params.interval = 5120;
1491 scan_params.window = 512;
1492 _bt_set_scan_parameters(&scan_params);
1494 _bt_set_scan_parameters(&le_scan_params);
1496 if (scanner->filter_list == NULL) {
1497 BT_INFO("Start LE Full Scan");
1498 scan_filter_enabled = FALSE;
1500 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1501 g_variant_new("(ib)", 0, TRUE),
1502 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1505 BT_ERR("scan_filter_enable Fail: %s", error->message);
1506 g_clear_error(&error);
1510 g_variant_unref(ret);
1511 BT_INFO("Enable LE Scan Filter");
1512 scan_filter_enabled = TRUE;
1516 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1517 NULL, G_DBUS_CALL_FLAGS_NONE,
1521 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1522 g_clear_error(&error);
1523 return BLUETOOTH_ERROR_INTERNAL;
1527 g_variant_unref(ret);
1528 return BLUETOOTH_ERROR_NONE;
1531 int _bt_stop_le_scan(const char *sender)
1534 GError *error = NULL;
1536 bt_adapter_le_scanner_t *scan_sender = __bt_find_scanner_from_list(sender);
1537 bt_adapter_le_scanner_t *scanner;
1539 gboolean next_scanning = FALSE;
1540 gboolean need_scan_filter = TRUE;
1542 if (scan_sender == NULL || scan_sender->is_scanning == FALSE)
1543 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1545 scan_sender->is_scanning = FALSE;
1546 scan_sender->stop_pending = TRUE;
1548 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1550 if (scanner->is_scanning == TRUE) {
1551 next_scanning = TRUE;
1552 if (scanner->filter_list == NULL)
1553 need_scan_filter = FALSE;
1557 proxy = _bt_get_adapter_proxy();
1558 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1560 if (next_scanning == TRUE) {
1561 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1562 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1563 g_variant_new("(ib)", 0, TRUE),
1564 G_DBUS_CALL_FLAGS_NONE,
1568 BT_ERR("scan_filter_enable Fail: %s", error->message);
1569 g_clear_error(&error);
1573 g_variant_unref(ret);
1574 BT_INFO("Enable LE Scan Filter");
1575 scan_filter_enabled = TRUE;
1577 BT_INFO("next_scanning exists. Keep the LE scanning");
1578 scan_sender->stop_pending = FALSE;
1579 return BLUETOOTH_ERROR_NONE;
1581 if (scan_filter_enabled == TRUE) {
1582 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1583 g_variant_new("(ib)", 0, FALSE),
1584 G_DBUS_CALL_FLAGS_NONE,
1588 BT_ERR("scan_filter_enable Fail: %s", error->message);
1589 g_clear_error(&error);
1593 g_variant_unref(ret);
1594 BT_INFO("Disable LE Scan Filter");
1596 BT_INFO("Just stop LE scan");
1600 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1601 NULL, G_DBUS_CALL_FLAGS_NONE,
1604 BT_ERR("StopLEDiscovery Fail: %s", error->message);
1605 g_clear_error(&error);
1609 BT_ERR("LE Scan stop failed");
1610 return BLUETOOTH_ERROR_INTERNAL;
1613 scan_filter_enabled = FALSE;
1614 is_le_set_scan_parameter = FALSE;
1615 le_scan_params.type = BT_LE_ACTIVE_SCAN;
1616 le_scan_params.interval = 0;
1617 le_scan_params.window = 0;
1619 g_variant_unref(ret);
1620 return BLUETOOTH_ERROR_NONE;
1623 void _bt_disable_all_scanner_status(void)
1626 bt_adapter_le_scanner_t *scanner;
1628 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1630 scanner->is_scanning = FALSE;
1631 scanner->stop_pending = FALSE;
1635 static void __bt_free_le_scanner(void)
1638 bt_adapter_le_scanner_t *scanner;
1640 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1642 g_free(scanner->sender);
1643 g_slist_free_full(scanner->filter_list, g_free);
1647 g_slist_free(scanner_list);
1648 scanner_list = NULL;
1650 scan_filter_enabled = FALSE;
1651 is_le_scanning = FALSE;
1652 is_le_set_scan_parameter = FALSE;
1653 le_scan_params.type = BT_LE_ACTIVE_SCAN;
1654 le_scan_params.interval = 0;
1655 le_scan_params.window = 0;
1658 void _bt_set_le_scan_status(gboolean mode)
1660 BT_DBG("set is_le_scanning : %d -> %d", is_le_scanning, mode);
1661 is_le_scanning = mode;
1664 gboolean _bt_is_le_scanning(void)
1666 return is_le_scanning;
1669 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1671 le_scan_type = type;
1674 bt_le_scan_type_t _bt_get_le_scan_type(void)
1676 return le_scan_type;
1679 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1680 int adv_data_len, const char *svc_uuid, int uuid_len,
1681 const char *uuid_mask, char ad_type)
1687 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1688 ad_type, &data, &data_len);
1690 for (i = 0; i < data_len; i += uuid_len) {
1691 if (uuid_len > (data_len - i))
1694 if (_bt_byte_arr_cmp_with_mask(data + i,
1695 svc_uuid, uuid_mask, uuid_len) == 0) {
1706 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1707 const char *adv_data, int adv_data_len,
1708 const char *scan_data, int scan_data_len,
1709 const bt_adapter_le_scanner_t *scanner)
1712 bluetooth_le_scan_filter_t *filter_data = NULL;
1715 gboolean is_matched = FALSE;
1717 if (scanner->filter_list == NULL) {
1718 BT_INFO("This scanner is on Full Scan.");
1722 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1723 filter_data = l->data;
1725 if (filter_data->added_features &
1726 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1727 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1729 _bt_convert_addr_type_to_string(address,
1730 filter_data->device_address.addr);
1731 if (strncmp(address, device_address,
1732 BT_ADDRESS_STRING_SIZE) != 0)
1736 if (filter_data->added_features &
1737 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1740 if (__bt_check_scan_result_uuid(adv_data,
1742 (char*)filter_data->service_uuid.data.data,
1743 filter_data->service_uuid.data_len,
1744 (char*)filter_data->service_uuid_mask.data.data,
1745 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1748 if (__bt_check_scan_result_uuid(adv_data,
1750 (char*)filter_data->service_uuid.data.data,
1751 filter_data->service_uuid.data_len,
1752 (char*)filter_data->service_uuid_mask.data.data,
1753 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1756 if (__bt_check_scan_result_uuid(adv_data,
1758 (char*)filter_data->service_uuid.data.data,
1759 filter_data->service_uuid.data_len,
1760 (char*)filter_data->service_uuid_mask.data.data,
1761 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1764 if (__bt_check_scan_result_uuid(adv_data,
1766 (char*)filter_data->service_uuid.data.data,
1767 filter_data->service_uuid.data_len,
1768 (char*)filter_data->service_uuid_mask.data.data,
1769 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1772 if (__bt_check_scan_result_uuid(scan_data,
1774 (char*)filter_data->service_uuid.data.data,
1775 filter_data->service_uuid.data_len,
1776 (char*)filter_data->service_uuid_mask.data.data,
1777 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1780 if (__bt_check_scan_result_uuid(scan_data,
1782 (char*)filter_data->service_uuid.data.data,
1783 filter_data->service_uuid.data_len,
1784 (char*)filter_data->service_uuid_mask.data.data,
1785 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1788 if (__bt_check_scan_result_uuid(scan_data,
1790 (char*)filter_data->service_uuid.data.data,
1791 filter_data->service_uuid.data_len,
1792 (char*)filter_data->service_uuid_mask.data.data,
1793 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1796 if (__bt_check_scan_result_uuid(scan_data,
1798 (char*)filter_data->service_uuid.data.data,
1799 filter_data->service_uuid.data_len,
1800 (char*)filter_data->service_uuid_mask.data.data,
1801 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1805 if (is_matched == FALSE)
1808 if (filter_data->added_features &
1809 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1812 if (__bt_check_scan_result_uuid(adv_data,
1814 (char*)filter_data->service_solicitation_uuid.data.data,
1815 filter_data->service_solicitation_uuid.data_len,
1816 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1817 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1820 if (__bt_check_scan_result_uuid(adv_data,
1822 (char*)filter_data->service_solicitation_uuid.data.data,
1823 filter_data->service_solicitation_uuid.data_len,
1824 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1825 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1828 if (__bt_check_scan_result_uuid(scan_data,
1830 (char*)filter_data->service_solicitation_uuid.data.data,
1831 filter_data->service_solicitation_uuid.data_len,
1832 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1833 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1836 if (__bt_check_scan_result_uuid(scan_data,
1838 (char*)filter_data->service_solicitation_uuid.data.data,
1839 filter_data->service_solicitation_uuid.data_len,
1840 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1841 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1845 if (is_matched == FALSE)
1848 if (filter_data->added_features &
1849 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1850 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1855 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1856 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1859 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1860 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1861 memcpy(name, data, data_len);
1862 name[data_len] = '\0';
1865 if (strncmp(filter_data->device_name,
1866 name, data_len) == 0)
1869 __bt_get_ad_data_by_type((char*)scan_data,
1871 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1874 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1875 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1876 memcpy(name, data, data_len);
1877 name[data_len] = '\0';
1880 if (strncmp(filter_data->device_name,
1881 name, data_len) == 0)
1885 if (is_matched == FALSE)
1888 if (filter_data->added_features &
1889 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1894 __bt_get_ad_data_by_type((char*)adv_data,
1896 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1900 int manufacturer_id;
1901 manufacturer_id = (data[1] << 8) + data[0];
1903 if (filter_data->manufacturer_id == manufacturer_id) {
1904 if (filter_data->manufacturer_data.data_len == 0) {
1907 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1908 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1909 if (_bt_byte_arr_cmp_with_mask(data + 2,
1910 (char*)filter_data->manufacturer_data.data.data,
1911 (char*)filter_data->manufacturer_data_mask.data.data,
1912 data_len - 2) == 0) {
1920 __bt_get_ad_data_by_type((char*)scan_data,
1922 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1926 int manufacturer_id;
1927 manufacturer_id = (data[1] << 8) + data[0];
1929 if (filter_data->manufacturer_id == manufacturer_id) {
1930 if (filter_data->manufacturer_data.data_len == 0) {
1933 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1934 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1935 if (_bt_byte_arr_cmp_with_mask(data + 2,
1936 (char*)filter_data->manufacturer_data.data.data,
1937 (char*)filter_data->manufacturer_data_mask.data.data,
1938 data_len - 2) == 0) {
1947 if (is_matched == FALSE)
1950 if (filter_data->added_features &
1951 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1956 __bt_get_ad_data_by_type((char*)adv_data,
1958 BT_LE_AD_TYPE_SERVICE_DATA,
1961 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1962 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1963 if (_bt_byte_arr_cmp_with_mask(data,
1964 (char*)filter_data->service_data.data.data,
1965 (char*)filter_data->service_data_mask.data.data,
1972 __bt_get_ad_data_by_type((char*)scan_data,
1974 BT_LE_AD_TYPE_SERVICE_DATA,
1977 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1978 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1979 if (_bt_byte_arr_cmp_with_mask(data,
1980 (char*)filter_data->service_data.data.data,
1981 (char*)filter_data->service_data_mask.data.data,
1989 if (is_matched == FALSE)
1993 BT_INFO("The scan result is conformable.");
1997 BT_INFO("The scan result is NOT conformable.");
2001 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
2002 const bt_le_adv_info_t *adv_info)
2004 int result = BLUETOOTH_ERROR_NONE;
2006 GVariant *scan_data_param, *adv_data_param;
2008 bt_adapter_le_scanner_t *scanner = NULL;
2009 const char *adv_data = NULL;
2010 int adv_data_len = 0;
2011 const char *scan_data = NULL;
2012 int scan_data_len = 0;
2014 ret_if(le_dev_info == NULL);
2016 if (adv_info == NULL) { /* Not received scan response data within 1 sec */
2017 adv_data = le_dev_info->adv_data;
2018 adv_data_len = le_dev_info->adv_data_len;
2019 scan_data = le_dev_info->adv_data;
2022 adv_data = adv_info->data;
2023 adv_data_len = adv_info->data_len;
2024 scan_data = le_dev_info->adv_data;
2025 scan_data_len = le_dev_info->adv_data_len;
2028 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
2030 if (scanner->is_scanning == FALSE)
2033 if (__bt_check_scan_result_with_filter(le_dev_info->address,
2034 adv_data, adv_data_len, scan_data, scan_data_len,
2038 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
2039 adv_data, adv_data_len, TRUE, NULL, NULL);
2040 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
2041 scan_data, scan_data_len, TRUE, NULL, NULL);
2043 param = g_variant_new("(isnnn@ayn@ay)",
2045 le_dev_info->address,
2046 le_dev_info->addr_type,
2054 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
2055 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
2057 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
2062 void _bt_send_ibeacon_scan_result_event(const bt_remote_ibeacon_dev_info_t *ibeacon_dev_info)
2064 int result = BLUETOOTH_ERROR_NONE;
2067 bt_adapter_le_scanner_t *scanner = NULL;
2069 ret_if(ibeacon_dev_info == NULL);
2070 BT_DBG("_bt_send_ibeacon_scan_result_event");
2072 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
2074 if (scanner->is_scanning == FALSE)
2077 param = g_variant_new("(isnnnsnnn)",
2079 ibeacon_dev_info->address,
2080 ibeacon_dev_info->addr_type,
2081 ibeacon_dev_info->company_id,
2082 ibeacon_dev_info->ibeacon_type,
2083 ibeacon_dev_info->uuid,
2084 ibeacon_dev_info->major_id,
2085 ibeacon_dev_info->minor_id,
2086 ibeacon_dev_info->measured_power);
2088 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_IBEACON_DEVICE_FOUND, param);
2092 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2095 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2096 GError *error = NULL;
2099 if (__bt_is_factory_test_mode()) {
2100 BT_ERR("Unable to add white list in factory binary !!");
2101 return BLUETOOTH_ERROR_NOT_SUPPORT;
2104 BT_CHECK_PARAMETER(device_address, return);
2106 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2107 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2108 return BLUETOOTH_ERROR_INVALID_PARAM;
2110 _bt_convert_addr_type_to_string(address, device_address->addr);
2112 proxy = _bt_get_adapter_proxy();
2113 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2115 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
2116 g_variant_new("(su)", address, address_type),
2117 G_DBUS_CALL_FLAGS_NONE, -1,
2121 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
2122 g_clear_error(&error);
2123 return BLUETOOTH_ERROR_INTERNAL;
2127 g_variant_unref(ret);
2128 BT_INFO("Add white list");
2130 return BLUETOOTH_ERROR_NONE;
2133 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2136 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2137 GError *error = NULL;
2140 if (__bt_is_factory_test_mode()) {
2141 BT_ERR("Unable to remove white list in factory binary !!");
2142 return BLUETOOTH_ERROR_NOT_SUPPORT;
2145 BT_CHECK_PARAMETER(device_address, return);
2147 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2148 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2149 return BLUETOOTH_ERROR_INVALID_PARAM;
2151 _bt_convert_addr_type_to_string(address, device_address->addr);
2153 proxy = _bt_get_adapter_proxy();
2154 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2156 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
2157 g_variant_new("(su)", address, address_type),
2158 G_DBUS_CALL_FLAGS_NONE, -1,
2162 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2163 g_clear_error(&error);
2164 return BLUETOOTH_ERROR_INTERNAL;
2168 g_variant_unref(ret);
2169 BT_INFO("Remove white list");
2171 return BLUETOOTH_ERROR_NONE;
2174 int _bt_clear_white_list(void)
2177 GError *error = NULL;
2180 if (__bt_is_factory_test_mode()) {
2181 BT_ERR("Unable to clear white list in factory binary !!");
2182 return BLUETOOTH_ERROR_NOT_SUPPORT;
2185 proxy = _bt_get_adapter_proxy();
2186 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2188 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2189 NULL, G_DBUS_CALL_FLAGS_NONE,
2193 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2194 g_clear_error(&error);
2195 return BLUETOOTH_ERROR_INTERNAL;
2198 g_variant_unref(ret);
2200 BT_INFO("Clear white list");
2202 return BLUETOOTH_ERROR_NONE;
2205 int _bt_initialize_ipsp(void)
2209 GError *error = NULL;
2212 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2213 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2214 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2217 proxy = _bt_get_adapter_proxy();
2218 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2220 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2221 NULL, G_DBUS_CALL_FLAGS_NONE,
2224 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2225 g_clear_error(&error);
2226 return BLUETOOTH_ERROR_INTERNAL;
2229 g_variant_unref(ret);
2231 BT_INFO("IPSP initialization called successfully");
2233 return BLUETOOTH_ERROR_NONE;
2236 int _bt_deinitialize_ipsp(void)
2240 GError *error = NULL;
2243 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2244 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2245 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2248 proxy = _bt_get_adapter_proxy();
2249 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2251 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2252 NULL, G_DBUS_CALL_FLAGS_NONE,
2255 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2256 g_clear_error(&error);
2257 return BLUETOOTH_ERROR_INTERNAL;
2260 g_variant_unref(ret);
2262 BT_INFO("IPSP De-initialization called successfully");
2264 return BLUETOOTH_ERROR_NONE;
2267 int _bt_le_read_maximum_data_length(
2268 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2270 GError *error = NULL;
2272 GVariant *reply = NULL;
2273 guint16 max_tx_octets, max_tx_time;
2274 guint16 max_rx_octets, max_rx_time;
2276 proxy = _bt_get_adapter_proxy();
2277 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2279 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2280 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2282 if (reply == NULL) {
2283 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2284 if (error != NULL) {
2285 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2286 error->code, error->message);
2287 g_clear_error(&error);
2289 return BLUETOOTH_ERROR_INTERNAL;
2292 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2293 &max_rx_octets, &max_rx_time);
2295 max_le_datalength->max_tx_octets = max_tx_octets;
2296 max_le_datalength->max_tx_time = max_tx_time;
2297 max_le_datalength->max_rx_octets = max_rx_octets;
2298 max_le_datalength->max_rx_time = max_rx_time;
2300 g_variant_unref(reply);
2302 return BLUETOOTH_ERROR_NONE;
2304 int _bt_le_write_host_suggested_default_data_length(
2305 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2307 GError *error = NULL;
2309 GVariant *reply = NULL;
2311 proxy = _bt_get_adapter_proxy();
2312 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2314 reply = g_dbus_proxy_call_sync(proxy,
2315 "LEWriteHostSuggestedDataLength",
2316 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2317 G_DBUS_CALL_FLAGS_NONE,
2322 if (reply == NULL) {
2323 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2324 if (error != NULL) {
2325 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2326 error->code, error->message);
2327 g_clear_error(&error);
2329 return BLUETOOTH_ERROR_INTERNAL;
2332 g_variant_unref(reply);
2334 return BLUETOOTH_ERROR_NONE;
2337 int _bt_le_read_host_suggested_default_data_length(
2338 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2340 GError *error = NULL;
2342 GVariant *reply = NULL;
2343 guint16 def_tx_octets, def_tx_time;
2345 proxy = _bt_get_adapter_proxy();
2346 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2348 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2349 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2351 if (reply == NULL) {
2352 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2353 if (error != NULL) {
2354 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2355 error->code, error->message);
2356 g_clear_error(&error);
2358 return BLUETOOTH_ERROR_INTERNAL;
2361 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2363 def_data_length->def_tx_octets = def_tx_octets;
2364 def_data_length->def_tx_time = def_tx_time;
2366 g_variant_unref(reply);
2368 return BLUETOOTH_ERROR_NONE;
2371 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2372 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2374 GError *error = NULL;
2375 guint16 txOctets = max_tx_Octets;
2376 guint16 txTime = max_tx_Time;
2377 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2378 gchar *device_path = NULL;
2379 GDBusConnection *conn;
2380 GDBusProxy *device_proxy;
2382 _bt_convert_addr_type_to_string(address, device_address->addr);
2384 device_path = _bt_get_device_object_path(address);
2386 if (device_path == NULL) {
2387 BT_DBG("Device path is null");
2388 return BLUETOOTH_ERROR_INTERNAL;
2391 conn = _bt_gdbus_get_system_gconn();
2393 BT_ERR("conn == NULL");
2394 g_free(device_path);
2395 return BLUETOOTH_ERROR_INTERNAL;
2398 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2399 NULL, BT_BLUEZ_NAME,
2400 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2402 g_free(device_path);
2403 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2405 g_dbus_proxy_call_sync(device_proxy,
2407 g_variant_new("(qq)", txOctets, txTime),
2408 G_DBUS_CALL_FLAGS_NONE,
2413 g_object_unref(device_proxy);
2416 BT_ERR("LESetDataLength error: [%s]", error->message);
2417 g_error_free(error);
2418 return BLUETOOTH_ERROR_INTERNAL;
2421 return BLUETOOTH_ERROR_NONE;
2424 int _bt_service_adapter_le_init(void)
2426 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
2428 return BLUETOOTH_ERROR_NONE;
2431 void _bt_service_adapter_le_deinit(void)
2433 __bt_free_le_adv_slot();
2434 __bt_free_le_scanner();