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
49 } bt_adapter_le_feature_info_t;
54 gboolean is_advertising;
56 } bt_adapter_le_adv_slot_t;
62 gboolean stop_pending;
63 } bt_adapter_le_scanner_t;
65 static bluetooth_advertising_params_t adv_params = {
66 BT_DEFAULT_ADV_MIN_INTERVAL,
67 BT_DEFAULT_ADV_MAX_INTERVAL,
68 BT_ADV_FILTER_POLICY_DEFAULT,
70 static bluetooth_advertising_data_t adv_data = { {0} };
71 static int adv_data_len;
72 static bluetooth_scan_resp_data_t resp_data = { {0} };
73 static int resp_data_len;
75 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
76 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
78 GSList *scanner_list = NULL;
79 static gboolean is_le_set_scan_parameter = FALSE;
80 static gboolean is_le_scanning = FALSE;
81 static gboolean scan_filter_enabled = FALSE;
82 static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN;
84 static GSList *gatt_client_senders = NULL;
87 gboolean _bt_is_set_scan_parameter(void)
89 return is_le_set_scan_parameter;
92 void _bt_init_gatt_client_senders(void)
94 _bt_clear_request_list();
97 int _bt_insert_gatt_client_sender(char *sender)
101 retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
103 info = g_strdup(sender);
104 retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
106 gatt_client_senders = g_slist_append(gatt_client_senders, info);
108 BT_DBG("insert sender: %s", sender);
110 return BLUETOOTH_ERROR_NONE;
113 int _bt_delete_gatt_client_sender(char *sender)
118 BT_DBG("remove sender: %s", sender);
120 for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) {
125 if (g_strcmp0(info, sender) == 0) {
126 BT_DBG("remove info");
127 gatt_client_senders = g_slist_remove(gatt_client_senders, info);
129 return BLUETOOTH_ERROR_NONE;
133 return BLUETOOTH_ERROR_NOT_FOUND;
136 void _bt_clear_gatt_client_senders(void)
138 if (gatt_client_senders) {
139 g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL);
140 g_slist_free(gatt_client_senders);
141 gatt_client_senders = NULL;
145 static void __bt_send_foreach_event(gpointer data, gpointer user_data)
148 GVariant *param = user_data;
150 _bt_send_event_to_dest(sender, BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
154 void _bt_send_char_value_changed_event(void *param)
157 g_slist_foreach(gatt_client_senders, __bt_send_foreach_event,
160 _bt_send_event(BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED, param);
164 void __bt_free_le_adv_slot(void)
168 if (le_adv_slot == NULL)
171 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
172 if (le_adv_slot[i].sender)
173 g_free(le_adv_slot[i].sender);
174 if (le_adv_slot[i].hold_timer_id > 0)
175 g_source_remove(le_adv_slot[i].hold_timer_id);
181 int _bt_le_set_max_packet_len(void)
183 int result = BLUETOOTH_ERROR_NONE;
184 int tx_octets, tx_time;
185 bluetooth_le_read_maximum_data_length_t max_len = {0};
187 if (BLUETOOTH_ERROR_NONE != _bt_le_read_maximum_data_length(&max_len))
188 return BLUETOOTH_ERROR_INTERNAL;
190 if (max_len.max_tx_octets > BT_LE_TX_LEN_DEFAULT) {
191 tx_octets = max_len.max_tx_octets > BT_LE_TX_LEN_MAX ?
192 BT_LE_TX_LEN_MAX : max_len.max_tx_octets;
193 tx_time = BT_LE_TX_TIME_MAX;
195 result = _bt_le_write_host_suggested_default_data_length(tx_octets, tx_time);
197 BT_DBG("Wrote max packet size : result[%d], MAX[%d], set[%d]",
198 result, max_len.max_tx_octets, tx_octets);
204 gboolean _bt_update_le_feature_support(const char *item, const char *value)
206 if (item == NULL || value == NULL)
210 _bt_service_adapter_le_init();
212 if (g_strcmp0(item, "adv_inst_max") == 0) {
215 slot_num = atoi(value);
216 retv_if(slot_num < 0, FALSE);
218 if (slot_num != le_feature_info.adv_inst_max) {
219 __bt_free_le_adv_slot();
220 le_feature_info.adv_inst_max = slot_num;
221 BT_INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
222 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
224 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
225 le_feature_info.rpa_offloading = atoi(value);
226 BT_INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
227 } else if (g_strcmp0(item, "max_filter") == 0) {
228 le_feature_info.max_filter = atoi(value);
229 BT_INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
231 BT_DBG("No registered item");
238 static gboolean __bt_is_factory_test_mode(void)
242 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
243 BT_ERR("Get the DUT Mode fail");
248 BT_INFO("DUT Test Mode !!");
255 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
259 if (le_adv_slot == NULL) {
260 BT_ERR("le_adv_slot is NULL");
264 BT_DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
266 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
267 if (le_adv_slot[i].sender == NULL)
269 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
273 if (le_feature_info.adv_inst_max <= 2)
275 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
280 for (; i < le_feature_info.adv_inst_max; i++) {
281 if (le_adv_slot[i].sender == NULL)
288 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
290 if (le_adv_slot[slot_id].sender == NULL) {
291 le_adv_slot[slot_id].sender = strdup(sender);
292 le_adv_slot[slot_id].adv_handle = adv_handle;
296 void _bt_unregister_adv_slot_owner(int slot_id)
298 if (le_adv_slot[slot_id].hold_timer_id > 0) {
299 BT_INFO("Hold state adv is not unregistered");
303 g_free(le_adv_slot[slot_id].sender);
304 le_adv_slot[slot_id].sender = NULL;
305 le_adv_slot[slot_id].adv_handle = 0;
308 const char* _bt_get_adv_slot_owner(int slot_id)
310 if (le_adv_slot == NULL)
313 return le_adv_slot[slot_id].sender;
316 int _bt_get_adv_slot_adv_handle(int slot_id)
318 if (le_adv_slot == NULL)
321 return le_adv_slot[slot_id].adv_handle;
324 void _bt_set_advertising_status(int slot_id, gboolean mode)
326 le_adv_slot[slot_id].is_advertising = mode;
329 gboolean _bt_is_advertising(void)
331 gboolean status = FALSE;
334 if (le_adv_slot == NULL)
337 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
338 if (le_adv_slot[i].is_advertising == TRUE)
345 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
349 if (le_adv_slot == NULL)
352 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
353 if (le_adv_slot[i].sender != NULL) {
354 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
355 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
356 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
362 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
367 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
372 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
375 GError *error = NULL;
379 if (__bt_is_factory_test_mode()) {
380 BT_ERR("Unable to start advertising in factory binary !!");
381 return BLUETOOTH_ERROR_NOT_SUPPORT;
384 if (_bt_adapter_get_status() != BT_ACTIVATED &&
385 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
386 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
389 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
391 BT_ERR("There is NO available slot!!");
392 return BLUETOOTH_ERROR_NO_RESOURCES;
395 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
396 return BLUETOOTH_ERROR_IN_PROGRESS;
398 if (le_adv_slot[slot_id].hold_timer_id > 0) {
399 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
400 le_adv_slot[slot_id].hold_timer_id = 0;
401 _bt_unregister_adv_slot_owner(slot_id);
404 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
405 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
407 proxy = _bt_get_adapter_proxy();
408 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
410 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
411 g_variant_new("(bi)", enable, slot_id),
412 G_DBUS_CALL_FLAGS_NONE,
418 BT_ERR("SetAdvertising Fail: %s", error->message);
419 g_clear_error(&error);
420 return BLUETOOTH_ERROR_INTERNAL;
424 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
426 le_adv_slot[slot_id].is_advertising = enable;
427 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
430 g_variant_unref(ret);
432 return BLUETOOTH_ERROR_NONE;
435 int _bt_set_custom_advertising(const char *sender, int adv_handle,
436 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
440 GError *error = NULL;
445 BT_CHECK_PARAMETER(params, return);
447 if (__bt_is_factory_test_mode()) {
448 BT_ERR("Unable to start advertising in factory binary !!");
449 return BLUETOOTH_ERROR_NOT_SUPPORT;
452 if (_bt_adapter_get_status() != BT_ACTIVATED &&
453 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
454 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
457 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
459 BT_ERR("There is NO available slot!!");
460 return BLUETOOTH_ERROR_NO_RESOURCES;
463 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
464 return BLUETOOTH_ERROR_IN_PROGRESS;
466 if (le_adv_slot[slot_id].hold_timer_id > 0) {
467 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
468 le_adv_slot[slot_id].hold_timer_id = 0;
469 _bt_unregister_adv_slot_owner(slot_id);
472 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
473 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
475 proxy = _bt_get_adapter_proxy();
476 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
478 if (params->interval_min > params->interval_max ||
479 params->interval_min < BT_ADV_INTERVAL_MIN ||
480 params->interval_max > BT_ADV_INTERVAL_MAX)
481 return BLUETOOTH_ERROR_INVALID_PARAM;
483 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
484 return BLUETOOTH_ERROR_INVALID_PARAM;
486 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
487 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
488 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
489 return BLUETOOTH_ERROR_NOT_SUPPORT;
491 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
492 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
494 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
495 g_variant_new("(uuuui)", min, max,
496 params->filter_policy, params->type,
497 slot_id), G_DBUS_CALL_FLAGS_NONE,
501 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
502 g_clear_error(&error);
503 return BLUETOOTH_ERROR_INTERNAL;
506 adv_params.interval_min = params->interval_min;
507 adv_params.interval_max = params->interval_max;
508 adv_params.filter_policy = params->filter_policy;
509 adv_params.type = params->type;
512 g_variant_unref(ret);
514 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
515 g_variant_new("(bi)", enable, slot_id),
516 G_DBUS_CALL_FLAGS_NONE,
522 BT_ERR("SetAdvertising Fail: %s", error->message);
523 g_clear_error(&error);
524 return BLUETOOTH_ERROR_INTERNAL;
528 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
530 le_adv_slot[slot_id].is_advertising = enable;
531 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
533 g_variant_unref(ret);
535 return BLUETOOTH_ERROR_NONE;
538 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
541 GError *error = NULL;
544 BT_INFO("Restart advertising stopped by bt-service");
546 le_adv_slot[0].hold_timer_id = 0;
548 proxy = _bt_get_adapter_proxy();
549 retv_if(proxy == NULL, FALSE);
551 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
552 g_variant_new("(bi)", TRUE, 0),
553 G_DBUS_CALL_FLAGS_NONE,
559 BT_ERR("SetAdvertising Fail: %s", error->message);
560 g_clear_error(&error);
565 g_variant_unref(ret);
570 int _bt_hold_current_advertising(void)
573 GError *error = NULL;
576 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
577 BT_INFO("Stop current advertising by bt-service");
579 proxy = _bt_get_adapter_proxy();
580 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
582 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
583 g_variant_new("(bi)", FALSE, 0),
584 G_DBUS_CALL_FLAGS_NONE,
590 BT_ERR("SetAdvertising Fail: %s", error->message);
591 g_clear_error(&error);
592 return BLUETOOTH_ERROR_INTERNAL;
596 g_variant_unref(ret);
598 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
599 __bt_hold_current_advertising_timeout_cb, NULL);
601 BT_INFO("It's NOT advertising");
602 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
605 return BLUETOOTH_ERROR_NONE;
608 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
609 char in_type, char **data, int *data_len)
611 if (in_data == NULL || data == NULL || data_len == NULL)
612 return BLUETOOTH_ERROR_INTERNAL;
615 return BLUETOOTH_ERROR_INTERNAL;
621 for (i = 0; i < in_len; i++) {
623 if (len <= 0 || i + 1 >= in_len) {
624 BT_ERR("Invalid advertising data");
625 return BLUETOOTH_ERROR_INTERNAL;
628 type = in_data[i + 1];
629 if (type == in_type) {
639 if (i + len > in_len) {
640 BT_ERR("Invalid advertising data");
641 return BLUETOOTH_ERROR_INTERNAL;
642 } else if (len == 0) {
643 BT_DBG("AD Type 0x%02x data is not set", in_type);
646 return BLUETOOTH_ERROR_NONE;
649 *data = g_memdup(&in_data[i], len);
651 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
654 return BLUETOOTH_ERROR_NONE;
657 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
659 BT_CHECK_PARAMETER(adv, return);
660 BT_CHECK_PARAMETER(length, return);
662 memcpy(adv, &adv_data, sizeof(adv_data));
663 *length = adv_data_len;
665 return BLUETOOTH_ERROR_NONE;
668 int _bt_set_advertising_data(const char *sender, int adv_handle,
669 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
672 GError *error = NULL;
673 GVariant *ret, *ad_data, *param = NULL;
674 GVariant *temp = NULL;
675 GVariantBuilder *builder;
677 char *old_mdata = NULL;
678 char *new_mdata = NULL;
683 if (__bt_is_factory_test_mode()) {
684 BT_ERR("Unable to set advertising data in factory binary !!");
685 return BLUETOOTH_ERROR_NOT_SUPPORT;
688 BT_CHECK_PARAMETER(adv, return);
690 if (_bt_adapter_get_status() != BT_ACTIVATED &&
691 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
692 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
695 proxy = _bt_get_adapter_proxy();
696 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
698 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
700 BT_ERR("There is NO available slot!!");
701 return BLUETOOTH_ERROR_NO_RESOURCES;
704 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
705 for (i = 0; i < length; i++)
706 g_variant_builder_add(builder, "y", adv->data[i]);
708 temp = g_variant_new("ay", builder);
709 g_variant_builder_unref(builder);
710 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
711 g_variant_new("(@ayi)", temp, slot_id),
712 G_DBUS_CALL_FLAGS_NONE,
716 BT_ERR("SetAdvertisingData Fail: %s", error->message);
717 g_clear_error(&error);
718 return BLUETOOTH_ERROR_INTERNAL;
721 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
723 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
724 &old_mdata, &old_len);
725 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
726 &new_mdata, &new_len);
727 if (old_len != new_len ||
728 (old_mdata && new_mdata &&
729 memcmp(old_mdata, new_mdata, new_len))) {
730 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
731 new_mdata, new_len, TRUE, NULL, NULL);
732 param = g_variant_new("(@ay)", ad_data);
733 _bt_send_event(BT_ADAPTER_EVENT,
734 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
740 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
741 memcpy(&adv_data, adv, length);
742 adv_data_len = length;
744 BT_INFO("Set advertising data");
746 g_variant_unref(ret);
748 return BLUETOOTH_ERROR_NONE;
751 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
753 BT_CHECK_PARAMETER(response, return);
754 BT_CHECK_PARAMETER(length, return);
756 memcpy(response, &resp_data, sizeof(resp_data));
757 *length = resp_data_len;
759 return BLUETOOTH_ERROR_NONE;
762 int _bt_set_scan_response_data(const char *sender, int adv_handle,
763 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
766 GError *error = NULL;
767 GVariant *ret, *scan_data, *param = NULL;
768 GVariant *temp = NULL;
769 GVariantBuilder *builder;
771 char *old_mdata = NULL;
772 char *new_mdata = NULL;
777 if (__bt_is_factory_test_mode()) {
778 BT_ERR("Unable to set scan response list in factory binary !!");
779 return BLUETOOTH_ERROR_NOT_SUPPORT;
782 BT_CHECK_PARAMETER(response, return);
784 if (_bt_adapter_get_status() != BT_ACTIVATED &&
785 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
786 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
789 proxy = _bt_get_adapter_proxy();
790 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
792 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
794 BT_ERR("There is NO available slot!!");
795 return BLUETOOTH_ERROR_NO_RESOURCES;
797 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
798 for (i = 0; i < length; i++)
799 g_variant_builder_add(builder, "y", response->data[i]);
801 temp = g_variant_new("ay", builder);
802 g_variant_builder_unref(builder);
803 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
804 g_variant_new("(@ayi)", temp, slot_id),
805 G_DBUS_CALL_FLAGS_NONE,
809 BT_ERR("SetScanRespData Fail: %s", error->message);
810 g_clear_error(&error);
811 return BLUETOOTH_ERROR_INTERNAL;
814 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
816 /* Compare with previous scan resp data */
817 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
818 &old_mdata, &old_len);
819 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
820 &new_mdata, &new_len);
821 if (old_len != new_len ||
822 (old_mdata && new_mdata &&
823 memcmp(old_mdata, new_mdata, new_len))) {
824 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
825 new_mdata, new_len, TRUE, NULL, NULL);
826 param = g_variant_new("(@ay)", scan_data);
827 _bt_send_event(BT_ADAPTER_EVENT,
828 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
834 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
835 memcpy(&resp_data, response, length);
836 resp_data_len = length;
839 g_variant_unref(ret);
840 BT_INFO("Set scan response data");
841 return BLUETOOTH_ERROR_NONE;
844 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
847 GError *error = NULL;
852 BT_CHECK_PARAMETER(params, return);
854 if (_bt_adapter_get_status() != BT_ACTIVATED &&
855 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
856 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
859 proxy = _bt_get_adapter_proxy();
860 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
862 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
863 return BLUETOOTH_ERROR_INVALID_PARAM;
865 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
866 return BLUETOOTH_ERROR_INVALID_PARAM;
868 if (params->window > params->interval)
869 return BLUETOOTH_ERROR_INVALID_PARAM;
871 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
872 win = params->window / BT_ADV_INTERVAL_SPLIT;
874 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
875 g_variant_new("(uuu)", params->type, itv, win),
876 G_DBUS_CALL_FLAGS_NONE, -1,
880 BT_ERR("SetScanParameters Fail: %s", error->message);
881 g_clear_error(&error);
882 return BLUETOOTH_ERROR_INTERNAL;
885 _bt_set_le_scan_type(params->type);
887 is_le_set_scan_parameter = TRUE;
890 g_variant_unref(ret);
891 BT_INFO("Set scan parameters");
892 return BLUETOOTH_ERROR_NONE;
895 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
898 bt_adapter_le_scanner_t *scanner;
900 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
902 if (g_strcmp0(scanner->sender, sender) == 0)
909 int __bt_get_available_scan_filter_slot_id(void)
912 bt_adapter_le_scanner_t *scanner;
914 bluetooth_le_scan_filter_t *filter_data;
915 gboolean *slot_check_list = NULL;
918 if (le_feature_info.max_filter == 0) {
919 BT_ERR("Scan filter is NOT Supported");
922 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
924 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
926 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
927 filter_data = fl->data;
928 if (filter_data->slot_id < le_feature_info.max_filter)
929 slot_check_list[filter_data->slot_id] = TRUE;
933 for (i = 0; i < le_feature_info.max_filter; i++) {
934 if (slot_check_list[i] == FALSE) {
935 g_free(slot_check_list);
940 BT_ERR("There is NO available slot for scan filter.");
941 g_free(slot_check_list);
945 gboolean _bt_is_scan_filter_supported(void)
947 if (le_feature_info.max_filter > 0)
953 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
956 GError *error = NULL;
957 GVariant *ret, *param;
958 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
959 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
960 GArray *arr_uuid = NULL;
961 GArray *arr_uuid_mask = NULL;
962 GArray *arr_data = NULL;
963 GArray *arr_data_mask = NULL;
964 bt_adapter_le_scanner_t *scanner = NULL;
965 bluetooth_le_scan_filter_t *filter_data = NULL;
966 int feature_selection = 0;
968 *slot_id = __bt_get_available_scan_filter_slot_id();
970 return BLUETOOTH_ERROR_NO_RESOURCES;
972 proxy = _bt_get_adapter_proxy();
973 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
975 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
976 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
977 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
979 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
981 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
982 NULL, 0, TRUE, NULL, NULL);
983 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
984 NULL, 0, TRUE, NULL, NULL);
985 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
986 NULL, 0, TRUE, NULL, NULL);
987 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
988 NULL, 0, TRUE, NULL, NULL);
990 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
992 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
993 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
994 *slot_id, // filter_index
996 0, // company_id_mask
997 arr_uuid_param, // p_uuid
998 arr_uuid_mask_param, // p_uuid_mask
1001 arr_data_param, // p_data
1002 arr_data_mask_param); // p_mask
1004 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1005 param, G_DBUS_CALL_FLAGS_NONE,
1009 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1010 g_clear_error(&error);
1013 g_variant_unref(ret);
1016 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1017 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
1019 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1020 NULL, 0, TRUE, NULL, NULL);
1021 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1022 NULL, 0, TRUE, NULL, NULL);
1023 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1024 NULL, 0, TRUE, NULL, NULL);
1025 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1026 NULL, 0, TRUE, NULL, NULL);
1028 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1030 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1031 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1032 *slot_id, // filter_index
1034 0, // company_id_mask
1035 arr_uuid_param, // p_uuid
1036 arr_uuid_mask_param, // p_uuid_mask
1037 filter->device_name, // string
1039 arr_data_param, // p_data
1040 arr_data_mask_param);
1042 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1043 param, G_DBUS_CALL_FLAGS_NONE,
1047 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1048 g_clear_error(&error);
1051 g_variant_unref(ret);
1054 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1055 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1057 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1058 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1060 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1061 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1063 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1064 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1065 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1066 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1067 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1068 NULL, 0, TRUE, NULL, NULL);
1069 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1070 NULL, 0, TRUE, NULL, NULL);
1072 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1074 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1075 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1076 *slot_id, // filter_index
1078 0, // company_id_mask
1079 arr_uuid_param, // p_uuid
1080 arr_uuid_mask_param, // p_uuid_mask
1083 arr_data_param, // p_data
1084 arr_data_mask_param);
1086 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1087 param, G_DBUS_CALL_FLAGS_NONE,
1091 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1092 g_clear_error(&error);
1095 g_variant_unref(ret);
1097 g_array_free(arr_uuid, TRUE);
1098 g_array_free(arr_uuid_mask, TRUE);
1101 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1102 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1104 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1105 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1107 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1108 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1110 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1111 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1112 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1113 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1114 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1115 NULL, 0, TRUE, NULL, NULL);
1116 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1117 NULL, 0, TRUE, NULL, NULL);
1119 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1121 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1122 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1123 *slot_id, // filter_index
1125 0, // company_id_mask
1126 arr_uuid_param, // p_uuid
1127 arr_uuid_mask_param, // p_uuid_mask
1130 arr_data_param, // p_data
1131 arr_data_mask_param);
1133 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1134 G_DBUS_CALL_FLAGS_NONE,
1138 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1139 g_clear_error(&error);
1142 g_variant_unref(ret);
1144 g_array_free(arr_uuid, TRUE);
1145 g_array_free(arr_uuid_mask, TRUE);
1148 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1149 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1151 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1152 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1154 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1155 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1157 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1158 NULL, 0, TRUE, NULL, NULL);
1159 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1160 NULL, 0, TRUE, NULL, NULL);
1161 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1162 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1163 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1164 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1166 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1168 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1169 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1170 *slot_id, // filter_index
1172 0, // company_id_mask
1173 arr_uuid_param, // p_uuid
1174 arr_uuid_mask_param, // p_uuid_mask
1177 arr_data_param, // p_data
1178 arr_data_mask_param);
1180 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1181 G_DBUS_CALL_FLAGS_NONE,
1185 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1186 g_clear_error(&error);
1189 g_variant_unref(ret);
1191 g_array_free(arr_data, TRUE);
1192 g_array_free(arr_data_mask, TRUE);
1195 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1196 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1198 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1199 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1201 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1202 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1204 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1205 NULL, 0, TRUE, NULL, NULL);
1206 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1207 NULL, 0, TRUE, NULL, NULL);
1208 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1209 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1210 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1211 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1213 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1215 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1216 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1217 *slot_id, // filter_index
1218 filter->manufacturer_id, // company_id
1219 0xFFFF, // company_id_mask
1220 arr_uuid_param, // p_uuid
1221 arr_uuid_mask_param, // p_uuid_mask
1224 arr_data_param, // p_data
1225 arr_data_mask_param);
1227 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1228 G_DBUS_CALL_FLAGS_NONE,
1232 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1233 g_clear_error(&error);
1236 g_variant_unref(ret);
1238 g_array_free(arr_data, TRUE);
1239 g_array_free(arr_data_mask, TRUE);
1242 BT_DBG("Filter selection %.2x", feature_selection);
1244 param = g_variant_new("(iiiiiiiiiiii)",
1246 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1247 *slot_id, // filter_index
1248 feature_selection, // feat_seln
1249 0, // list_logic_type (OR - 0x00, AND - 0x01)
1250 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1251 -127, // rssi_high_thres
1252 -127, // rssi_low_thres
1253 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1256 0); // found_timeout_cnt
1257 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1258 param, G_DBUS_CALL_FLAGS_NONE,
1262 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1263 g_clear_error(&error);
1266 scanner = __bt_find_scanner_from_list(sender);
1267 if (scanner == NULL) {
1268 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1269 scanner->sender = g_strdup(sender);
1270 scanner_list = g_slist_append(scanner_list, scanner);
1275 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1276 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1277 filter_data->slot_id = *slot_id;
1279 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1283 g_variant_unref(ret);
1284 return BLUETOOTH_ERROR_NONE;
1287 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1290 GError *error = NULL;
1292 bt_adapter_le_scanner_t *scanner = NULL;
1293 bluetooth_le_scan_filter_t *filter_data = NULL;
1295 gboolean is_slot_id_found = FALSE;
1297 scanner = __bt_find_scanner_from_list(sender);
1298 if (scanner == NULL) {
1299 BT_ERR("There is NO available scanner.");
1300 return BLUETOOTH_ERROR_NOT_FOUND;
1303 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1304 filter_data = l->data;
1305 if (filter_data->slot_id == slot_id) {
1306 is_slot_id_found = TRUE;
1310 if (is_slot_id_found == FALSE) {
1311 BT_ERR("There is NO registered slot.");
1312 return BLUETOOTH_ERROR_NOT_FOUND;
1315 proxy = _bt_get_adapter_proxy();
1316 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1318 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1319 g_variant_new("(ii)", 0, slot_id),
1320 G_DBUS_CALL_FLAGS_NONE,
1324 BT_ERR("scan_filter_clear Fail: %s", error->message);
1325 g_clear_error(&error);
1328 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1329 g_free(filter_data);
1332 g_variant_unref(ret);
1333 return BLUETOOTH_ERROR_NONE;
1336 int _bt_unregister_all_scan_filters(const char *sender)
1339 GError *error = NULL;
1341 bt_adapter_le_scanner_t *scanner = NULL;
1342 bluetooth_le_scan_filter_t *filter_data = NULL;
1345 scanner = __bt_find_scanner_from_list(sender);
1346 if (scanner == NULL) {
1347 BT_ERR("There is NO available scanner.");
1348 return BLUETOOTH_ERROR_NOT_FOUND;
1351 proxy = _bt_get_adapter_proxy();
1352 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1354 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1355 filter_data = l->data;
1357 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1358 g_variant_new("(ii)", 0, filter_data->slot_id),
1359 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1362 BT_ERR("scan_filter_clear Fail: %s", error->message);
1363 g_clear_error(&error);
1366 g_variant_unref(ret);
1369 g_slist_free_full(scanner->filter_list, g_free);
1370 scanner->filter_list = NULL;
1372 return BLUETOOTH_ERROR_NONE;
1375 static gboolean __start_le_scan_timeout(gpointer user_data)
1377 char *sender = (char *)user_data;
1378 _bt_start_le_scan(sender);
1384 int _bt_start_le_scan(const char *sender)
1387 GError *error = NULL;
1389 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1391 if (scanner == NULL) {
1392 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1393 scanner->sender = g_strdup(sender);
1394 scanner_list = g_slist_append(scanner_list, scanner);
1397 if (scanner->stop_pending == TRUE) {
1398 BT_DBG("Waiting LEDiscoveryFinished");
1399 g_timeout_add(500, (GSourceFunc)__start_le_scan_timeout, scanner->sender);
1400 return BLUETOOTH_ERROR_NONE;
1403 if (scanner->is_scanning == TRUE) {
1404 BT_ERR("BT is already in LE scanning");
1405 return BLUETOOTH_ERROR_IN_PROGRESS;
1407 scanner->is_scanning = TRUE;
1409 proxy = _bt_get_adapter_proxy();
1410 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1412 if (_bt_is_le_scanning()) {
1413 if (scan_filter_enabled == TRUE) {
1414 if (scanner->filter_list == NULL) {
1415 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1416 g_variant_new("(ib)", 0, FALSE),
1417 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1420 BT_ERR("scan_filter_enable Fail: %s", error->message);
1421 g_clear_error(&error);
1425 g_variant_unref(ret);
1426 BT_INFO("Disable LE Scan Filter");
1427 scan_filter_enabled = FALSE;
1429 BT_INFO("LE Filter Scan is continue");
1432 BT_INFO("LE Full Scan is already on progress");
1434 return BLUETOOTH_ERROR_NONE;
1436 if (is_le_set_scan_parameter == FALSE) {
1437 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1438 bluetooth_le_scan_params_t scan_params;
1439 scan_params.type = BT_LE_ACTIVE_SCAN;
1440 scan_params.interval = 5000;
1441 scan_params.window = 500;
1442 _bt_set_scan_parameters(&scan_params);
1445 if (scanner->filter_list == NULL) {
1446 BT_INFO("Start LE Full Scan");
1447 scan_filter_enabled = FALSE;
1449 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1450 g_variant_new("(ib)", 0, TRUE),
1451 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1454 BT_ERR("scan_filter_enable Fail: %s", error->message);
1455 g_clear_error(&error);
1459 g_variant_unref(ret);
1460 BT_INFO("Enable LE Scan Filter");
1461 scan_filter_enabled = TRUE;
1465 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1466 NULL, G_DBUS_CALL_FLAGS_NONE,
1470 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1471 g_clear_error(&error);
1472 return BLUETOOTH_ERROR_INTERNAL;
1476 g_variant_unref(ret);
1477 return BLUETOOTH_ERROR_NONE;
1480 int _bt_stop_le_scan(const char *sender)
1483 GError *error = NULL;
1485 bt_adapter_le_scanner_t *scan_sender = __bt_find_scanner_from_list(sender);
1486 bt_adapter_le_scanner_t *scanner;
1488 gboolean next_scanning = FALSE;
1489 gboolean need_scan_filter = TRUE;
1491 if (scan_sender == NULL || scan_sender->is_scanning == FALSE)
1492 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1494 scan_sender->is_scanning = FALSE;
1495 scan_sender->stop_pending = TRUE;
1497 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1499 if (scanner->is_scanning == TRUE) {
1500 next_scanning = TRUE;
1501 if (scanner->filter_list == NULL)
1502 need_scan_filter = FALSE;
1506 proxy = _bt_get_adapter_proxy();
1507 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1509 if (next_scanning == TRUE) {
1510 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1511 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1512 g_variant_new("(ib)", 0, TRUE),
1513 G_DBUS_CALL_FLAGS_NONE,
1517 BT_ERR("scan_filter_enable Fail: %s", error->message);
1518 g_clear_error(&error);
1522 g_variant_unref(ret);
1523 BT_INFO("Enable LE Scan Filter");
1524 scan_filter_enabled = TRUE;
1526 BT_INFO("next_scanning exists. Keep the LE scanning");
1527 scan_sender->stop_pending = FALSE;
1528 return BLUETOOTH_ERROR_NONE;
1530 if (scan_filter_enabled == TRUE) {
1531 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1532 g_variant_new("(ib)", 0, FALSE),
1533 G_DBUS_CALL_FLAGS_NONE,
1537 BT_ERR("scan_filter_enable Fail: %s", error->message);
1538 g_clear_error(&error);
1542 g_variant_unref(ret);
1543 BT_INFO("Disable LE Scan Filter");
1545 BT_INFO("Just stop LE scan");
1549 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1550 NULL, G_DBUS_CALL_FLAGS_NONE,
1553 BT_ERR("LE Scan stop failed");
1554 return BLUETOOTH_ERROR_INTERNAL;
1557 scan_filter_enabled = FALSE;
1558 is_le_set_scan_parameter = FALSE;
1560 g_variant_unref(ret);
1561 return BLUETOOTH_ERROR_NONE;
1564 void _bt_disable_all_scanner_status(void)
1567 bt_adapter_le_scanner_t *scanner;
1569 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1571 scanner->is_scanning = FALSE;
1572 scanner->stop_pending = FALSE;
1576 static void __bt_free_le_scanner(void)
1579 bt_adapter_le_scanner_t *scanner;
1581 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1583 g_free(scanner->sender);
1584 g_slist_free_full(scanner->filter_list, g_free);
1588 g_slist_free(scanner_list);
1589 scanner_list = NULL;
1591 scan_filter_enabled = FALSE;
1592 is_le_scanning = FALSE;
1593 is_le_set_scan_parameter = FALSE;
1596 void _bt_set_le_scan_status(gboolean mode)
1598 BT_DBG("set is_le_scanning : %d -> %d", is_le_scanning, mode);
1599 is_le_scanning = mode;
1602 gboolean _bt_is_le_scanning(void)
1604 return is_le_scanning;
1607 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1609 le_scan_type = type;
1612 bt_le_scan_type_t _bt_get_le_scan_type(void)
1614 return le_scan_type;
1617 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1618 int adv_data_len, const char *svc_uuid, int uuid_len,
1619 const char *uuid_mask, char ad_type)
1625 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1626 ad_type, &data, &data_len);
1628 for (i = 0; i < data_len; i += uuid_len) {
1629 if (uuid_len > (data_len - i))
1632 if (_bt_byte_arr_cmp_with_mask(data + i,
1633 svc_uuid, uuid_mask, uuid_len) == 0) {
1644 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1645 const char *adv_data, int adv_data_len,
1646 const char *scan_data, int scan_data_len,
1647 const bt_adapter_le_scanner_t *scanner)
1650 bluetooth_le_scan_filter_t *filter_data = NULL;
1653 gboolean is_matched = FALSE;
1655 if (scanner->filter_list == NULL) {
1656 BT_INFO("This scanner is on Full Scan.");
1660 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1661 filter_data = l->data;
1663 if (filter_data->added_features &
1664 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1665 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1667 _bt_convert_addr_type_to_string(address,
1668 filter_data->device_address.addr);
1669 if (strncmp(address, device_address,
1670 BT_ADDRESS_STRING_SIZE) != 0)
1674 if (filter_data->added_features &
1675 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1678 if (__bt_check_scan_result_uuid(adv_data,
1680 (char*)filter_data->service_uuid.data.data,
1681 filter_data->service_uuid.data_len,
1682 (char*)filter_data->service_uuid_mask.data.data,
1683 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1686 if (__bt_check_scan_result_uuid(adv_data,
1688 (char*)filter_data->service_uuid.data.data,
1689 filter_data->service_uuid.data_len,
1690 (char*)filter_data->service_uuid_mask.data.data,
1691 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1694 if (__bt_check_scan_result_uuid(adv_data,
1696 (char*)filter_data->service_uuid.data.data,
1697 filter_data->service_uuid.data_len,
1698 (char*)filter_data->service_uuid_mask.data.data,
1699 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1702 if (__bt_check_scan_result_uuid(adv_data,
1704 (char*)filter_data->service_uuid.data.data,
1705 filter_data->service_uuid.data_len,
1706 (char*)filter_data->service_uuid_mask.data.data,
1707 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1710 if (__bt_check_scan_result_uuid(scan_data,
1712 (char*)filter_data->service_uuid.data.data,
1713 filter_data->service_uuid.data_len,
1714 (char*)filter_data->service_uuid_mask.data.data,
1715 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1718 if (__bt_check_scan_result_uuid(scan_data,
1720 (char*)filter_data->service_uuid.data.data,
1721 filter_data->service_uuid.data_len,
1722 (char*)filter_data->service_uuid_mask.data.data,
1723 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1726 if (__bt_check_scan_result_uuid(scan_data,
1728 (char*)filter_data->service_uuid.data.data,
1729 filter_data->service_uuid.data_len,
1730 (char*)filter_data->service_uuid_mask.data.data,
1731 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1734 if (__bt_check_scan_result_uuid(scan_data,
1736 (char*)filter_data->service_uuid.data.data,
1737 filter_data->service_uuid.data_len,
1738 (char*)filter_data->service_uuid_mask.data.data,
1739 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1743 if (is_matched == FALSE)
1746 if (filter_data->added_features &
1747 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1750 if (__bt_check_scan_result_uuid(adv_data,
1752 (char*)filter_data->service_solicitation_uuid.data.data,
1753 filter_data->service_solicitation_uuid.data_len,
1754 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1755 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1758 if (__bt_check_scan_result_uuid(adv_data,
1760 (char*)filter_data->service_solicitation_uuid.data.data,
1761 filter_data->service_solicitation_uuid.data_len,
1762 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1763 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1766 if (__bt_check_scan_result_uuid(scan_data,
1768 (char*)filter_data->service_solicitation_uuid.data.data,
1769 filter_data->service_solicitation_uuid.data_len,
1770 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1771 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1774 if (__bt_check_scan_result_uuid(scan_data,
1776 (char*)filter_data->service_solicitation_uuid.data.data,
1777 filter_data->service_solicitation_uuid.data_len,
1778 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1779 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1783 if (is_matched == FALSE)
1786 if (filter_data->added_features &
1787 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1788 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1793 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1794 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1797 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1798 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1799 memcpy(name, data, data_len);
1800 name[data_len] = '\0';
1803 if (strncmp(filter_data->device_name,
1804 name, data_len) == 0)
1807 __bt_get_ad_data_by_type((char*)scan_data,
1809 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1812 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1813 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1814 memcpy(name, data, data_len);
1815 name[data_len] = '\0';
1818 if (strncmp(filter_data->device_name,
1819 name, data_len) == 0)
1823 if (is_matched == FALSE)
1826 if (filter_data->added_features &
1827 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1832 __bt_get_ad_data_by_type((char*)adv_data,
1834 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1838 int manufacturer_id;
1839 manufacturer_id = (data[1] << 8) + data[0];
1841 if (filter_data->manufacturer_id == manufacturer_id) {
1842 if (filter_data->manufacturer_data.data_len == 0) {
1845 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1846 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1847 if (_bt_byte_arr_cmp_with_mask(data + 2,
1848 (char*)filter_data->manufacturer_data.data.data,
1849 (char*)filter_data->manufacturer_data_mask.data.data,
1850 data_len - 2) == 0) {
1858 __bt_get_ad_data_by_type((char*)scan_data,
1860 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1864 int manufacturer_id;
1865 manufacturer_id = (data[1] << 8) + data[0];
1867 if (filter_data->manufacturer_id == manufacturer_id) {
1868 if (filter_data->manufacturer_data.data_len == 0) {
1871 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1872 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1873 if (_bt_byte_arr_cmp_with_mask(data + 2,
1874 (char*)filter_data->manufacturer_data.data.data,
1875 (char*)filter_data->manufacturer_data_mask.data.data,
1876 data_len - 2) == 0) {
1885 if (is_matched == FALSE)
1888 if (filter_data->added_features &
1889 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1894 __bt_get_ad_data_by_type((char*)adv_data,
1896 BT_LE_AD_TYPE_SERVICE_DATA,
1899 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1900 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1901 if (_bt_byte_arr_cmp_with_mask(data,
1902 (char*)filter_data->service_data.data.data,
1903 (char*)filter_data->service_data_mask.data.data,
1910 __bt_get_ad_data_by_type((char*)scan_data,
1912 BT_LE_AD_TYPE_SERVICE_DATA,
1915 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1916 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1917 if (_bt_byte_arr_cmp_with_mask(data,
1918 (char*)filter_data->service_data.data.data,
1919 (char*)filter_data->service_data_mask.data.data,
1927 if (is_matched == FALSE)
1931 BT_INFO("The scan result is conformable.");
1935 BT_INFO("The scan result is NOT conformable.");
1939 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1940 const bt_le_adv_info_t *adv_info)
1942 int result = BLUETOOTH_ERROR_NONE;
1944 GVariant *scan_data_param, *adv_data_param;
1946 bt_adapter_le_scanner_t *scanner = NULL;
1947 const char *adv_data = NULL;
1948 int adv_data_len = 0;
1949 const char *scan_data = NULL;
1950 int scan_data_len = 0;
1952 ret_if(le_dev_info == NULL);
1953 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1954 ret_if(adv_info == NULL);
1956 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1957 adv_data = le_dev_info->adv_data;
1958 adv_data_len = le_dev_info->adv_data_len;
1959 scan_data = le_dev_info->adv_data;
1962 adv_data = adv_info->data;
1963 adv_data_len = adv_info->data_len;
1964 scan_data = le_dev_info->adv_data;
1965 scan_data_len = le_dev_info->adv_data_len;
1968 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1970 if (scanner->is_scanning == FALSE)
1973 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1974 adv_data, adv_data_len, scan_data, scan_data_len,
1978 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1979 adv_data, adv_data_len, TRUE, NULL, NULL);
1980 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1981 scan_data, scan_data_len, TRUE, NULL, NULL);
1983 param = g_variant_new("(isnnn@ayn@ay)",
1985 le_dev_info->address,
1986 le_dev_info->addr_type,
1994 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1995 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1997 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
2002 void _bt_send_ibeacon_scan_result_event(const bt_remote_ibeacon_dev_info_t *ibeacon_dev_info)
2004 int result = BLUETOOTH_ERROR_NONE;
2007 bt_adapter_le_scanner_t *scanner = NULL;
2009 ret_if(ibeacon_dev_info == NULL);
2010 BT_DBG("_bt_send_ibeacon_scan_result_event");
2012 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
2014 if (scanner->is_scanning == FALSE)
2017 param = g_variant_new("(isnnnsnnn)",
2019 ibeacon_dev_info->address,
2020 ibeacon_dev_info->addr_type,
2021 ibeacon_dev_info->company_id,
2022 ibeacon_dev_info->ibeacon_type,
2023 ibeacon_dev_info->uuid,
2024 ibeacon_dev_info->major_id,
2025 ibeacon_dev_info->minor_id,
2026 ibeacon_dev_info->measured_power);
2028 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_IBEACON_DEVICE_FOUND, param);
2032 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2035 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2036 GError *error = NULL;
2039 if (__bt_is_factory_test_mode()) {
2040 BT_ERR("Unable to add white list in factory binary !!");
2041 return BLUETOOTH_ERROR_NOT_SUPPORT;
2044 BT_CHECK_PARAMETER(device_address, return);
2046 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2047 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2048 return BLUETOOTH_ERROR_INVALID_PARAM;
2050 _bt_convert_addr_type_to_string(address, device_address->addr);
2052 proxy = _bt_get_adapter_proxy();
2053 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2055 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
2056 g_variant_new("(su)", address, address_type),
2057 G_DBUS_CALL_FLAGS_NONE, -1,
2061 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
2062 g_clear_error(&error);
2063 return BLUETOOTH_ERROR_INTERNAL;
2067 g_variant_unref(ret);
2068 BT_INFO("Add white list");
2070 return BLUETOOTH_ERROR_NONE;
2073 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2076 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2077 GError *error = NULL;
2080 if (__bt_is_factory_test_mode()) {
2081 BT_ERR("Unable to remove white list in factory binary !!");
2082 return BLUETOOTH_ERROR_NOT_SUPPORT;
2085 BT_CHECK_PARAMETER(device_address, return);
2087 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2088 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2089 return BLUETOOTH_ERROR_INVALID_PARAM;
2091 _bt_convert_addr_type_to_string(address, device_address->addr);
2093 proxy = _bt_get_adapter_proxy();
2094 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2096 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
2097 g_variant_new("(su)", address, address_type),
2098 G_DBUS_CALL_FLAGS_NONE, -1,
2102 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2103 g_clear_error(&error);
2104 return BLUETOOTH_ERROR_INTERNAL;
2108 g_variant_unref(ret);
2109 BT_INFO("Remove white list");
2111 return BLUETOOTH_ERROR_NONE;
2114 int _bt_clear_white_list(void)
2117 GError *error = NULL;
2120 if (__bt_is_factory_test_mode()) {
2121 BT_ERR("Unable to clear white list in factory binary !!");
2122 return BLUETOOTH_ERROR_NOT_SUPPORT;
2125 proxy = _bt_get_adapter_proxy();
2126 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2128 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2129 NULL, G_DBUS_CALL_FLAGS_NONE,
2133 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2134 g_clear_error(&error);
2135 return BLUETOOTH_ERROR_INTERNAL;
2138 g_variant_unref(ret);
2140 BT_INFO("Clear white list");
2142 return BLUETOOTH_ERROR_NONE;
2145 int _bt_initialize_ipsp(void)
2149 GError *error = NULL;
2152 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2153 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2154 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2157 proxy = _bt_get_adapter_proxy();
2158 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2160 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2161 NULL, G_DBUS_CALL_FLAGS_NONE,
2164 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2165 g_clear_error(&error);
2166 return BLUETOOTH_ERROR_INTERNAL;
2169 g_variant_unref(ret);
2171 BT_INFO("IPSP initialization called successfully");
2173 return BLUETOOTH_ERROR_NONE;
2176 int _bt_deinitialize_ipsp(void)
2180 GError *error = NULL;
2183 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2184 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2185 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2188 proxy = _bt_get_adapter_proxy();
2189 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2191 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2192 NULL, G_DBUS_CALL_FLAGS_NONE,
2195 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2196 g_clear_error(&error);
2197 return BLUETOOTH_ERROR_INTERNAL;
2200 g_variant_unref(ret);
2202 BT_INFO("IPSP De-initialization called successfully");
2204 return BLUETOOTH_ERROR_NONE;
2207 int _bt_le_read_maximum_data_length(
2208 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2210 GError *error = NULL;
2212 GVariant *reply = NULL;
2213 guint16 max_tx_octets, max_tx_time;
2214 guint16 max_rx_octets, max_rx_time;
2216 proxy = _bt_get_adapter_proxy();
2217 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2219 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2220 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2222 if (reply == NULL) {
2223 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2224 if (error != NULL) {
2225 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2226 error->code, error->message);
2227 g_clear_error(&error);
2229 return BLUETOOTH_ERROR_INTERNAL;
2232 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2233 &max_rx_octets, &max_rx_time);
2235 max_le_datalength->max_tx_octets = max_tx_octets;
2236 max_le_datalength->max_tx_time = max_tx_time;
2237 max_le_datalength->max_rx_octets = max_rx_octets;
2238 max_le_datalength->max_rx_time = max_rx_time;
2240 g_variant_unref(reply);
2242 return BLUETOOTH_ERROR_NONE;
2244 int _bt_le_write_host_suggested_default_data_length(
2245 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2247 GError *error = NULL;
2249 GVariant *reply = NULL;
2251 proxy = _bt_get_adapter_proxy();
2252 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2254 reply = g_dbus_proxy_call_sync(proxy,
2255 "LEWriteHostSuggestedDataLength",
2256 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2257 G_DBUS_CALL_FLAGS_NONE,
2262 if (reply == NULL) {
2263 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2264 if (error != NULL) {
2265 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2266 error->code, error->message);
2267 g_clear_error(&error);
2269 return BLUETOOTH_ERROR_INTERNAL;
2272 g_variant_unref(reply);
2274 return BLUETOOTH_ERROR_NONE;
2277 int _bt_le_read_host_suggested_default_data_length(
2278 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2280 GError *error = NULL;
2282 GVariant *reply = NULL;
2283 guint16 def_tx_octets, def_tx_time;
2285 proxy = _bt_get_adapter_proxy();
2286 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2288 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2289 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2291 if (reply == NULL) {
2292 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2293 if (error != NULL) {
2294 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2295 error->code, error->message);
2296 g_clear_error(&error);
2298 return BLUETOOTH_ERROR_INTERNAL;
2301 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2303 def_data_length->def_tx_octets = def_tx_octets;
2304 def_data_length->def_tx_time = def_tx_time;
2306 g_variant_unref(reply);
2308 return BLUETOOTH_ERROR_NONE;
2311 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2312 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2314 GError *error = NULL;
2315 guint16 txOctets = max_tx_Octets;
2316 guint16 txTime = max_tx_Time;
2317 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2318 gchar *device_path = NULL;
2319 GDBusConnection *conn;
2320 GDBusProxy *device_proxy;
2322 _bt_convert_addr_type_to_string(address, device_address->addr);
2324 device_path = _bt_get_device_object_path(address);
2326 if (device_path == NULL) {
2327 BT_DBG("Device path is null");
2328 return BLUETOOTH_ERROR_INTERNAL;
2331 conn = _bt_gdbus_get_system_gconn();
2333 BT_ERR("conn == NULL");
2334 g_free(device_path);
2335 return BLUETOOTH_ERROR_INTERNAL;
2338 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2339 NULL, BT_BLUEZ_NAME,
2340 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2342 g_free(device_path);
2343 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2345 g_dbus_proxy_call_sync(device_proxy,
2347 g_variant_new("(qq)", txOctets, txTime),
2348 G_DBUS_CALL_FLAGS_NONE,
2353 g_object_unref(device_proxy);
2356 BT_ERR("LESetDataLength error: [%s]", error->message);
2357 g_error_free(error);
2358 return BLUETOOTH_ERROR_INTERNAL;
2361 return BLUETOOTH_ERROR_NONE;
2364 int _bt_service_adapter_le_init(void)
2366 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
2368 return BLUETOOTH_ERROR_NONE;
2371 void _bt_service_adapter_le_deinit(void)
2373 __bt_free_le_adv_slot();
2374 __bt_free_le_scanner();