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.
24 #include <syspopup_caller.h>
27 #include "bt-internal-types.h"
28 #include "bt-service-common.h"
29 #include "bt-service-event.h"
30 #include "bt-service-adapter.h"
31 #include "bt-service-adapter-le.h"
32 #include "bt-service-util.h"
35 #define BT_ADV_INTERVAL_MIN 20 /* msec */
36 #define BT_ADV_INTERVAL_MAX 10240
37 #define BT_ADV_INTERVAL_SPLIT 0.625
38 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
39 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
40 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
41 #define BT_ADV_TYPE_DEFAULT 0x00
42 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
43 #define BT_ADV_MULTI_MAX 16
49 } bt_adapter_le_feature_info_t;
54 gboolean is_advertising;
56 } bt_adapter_le_adv_slot_t;
62 } bt_adapter_le_scanner_t;
64 static bluetooth_advertising_params_t adv_params = {
65 BT_DEFAULT_ADV_MIN_INTERVAL,
66 BT_DEFAULT_ADV_MAX_INTERVAL,
67 BT_ADV_FILTER_POLICY_DEFAULT,
69 static bluetooth_advertising_data_t adv_data = { {0} };
70 static int adv_data_len;
71 static bluetooth_scan_resp_data_t resp_data = { {0} };
72 static int resp_data_len;
74 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
75 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
77 GSList *scanner_list = NULL;
78 static gboolean is_le_set_scan_parameter = FALSE;
79 static gboolean is_le_scanning = FALSE;
80 static gboolean scan_filter_enabled = FALSE;
81 static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN;
83 static GSList *gatt_client_senders = NULL;
86 gboolean _bt_is_set_scan_parameter(void)
88 return is_le_set_scan_parameter;
91 void _bt_init_gatt_client_senders(void)
93 _bt_clear_request_list();
96 int _bt_insert_gatt_client_sender(char *sender)
100 retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
102 info = g_strdup(sender);
103 retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
105 gatt_client_senders = g_slist_append(gatt_client_senders, info);
107 BT_DBG("insert sender: %s", sender);
109 return BLUETOOTH_ERROR_NONE;
112 int _bt_delete_gatt_client_sender(char *sender)
117 BT_DBG("remove sender: %s", sender);
119 for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) {
124 if (g_strcmp0(info, sender) == 0) {
125 BT_DBG("remove info");
126 gatt_client_senders = g_slist_remove(gatt_client_senders, info);
128 return BLUETOOTH_ERROR_NONE;
132 return BLUETOOTH_ERROR_NOT_FOUND;
135 void _bt_clear_gatt_client_senders(void)
137 if (gatt_client_senders) {
138 g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL);
139 g_slist_free(gatt_client_senders);
140 gatt_client_senders = NULL;
144 static void __bt_send_foreach_event(gpointer data, gpointer user_data)
147 GVariant *param = user_data;
149 _bt_send_event_to_dest(sender, BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
153 void _bt_send_char_value_changed_event(void *param)
155 g_slist_foreach(gatt_client_senders, __bt_send_foreach_event,
159 void __bt_free_le_adv_slot(void)
163 if (le_adv_slot == NULL)
166 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
167 if (le_adv_slot[i].sender)
168 g_free(le_adv_slot[i].sender);
174 int _bt_service_adapter_le_init(void)
176 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
178 return BLUETOOTH_ERROR_NONE;
181 void _bt_service_adapter_le_deinit(void)
183 __bt_free_le_adv_slot();
186 gboolean _bt_update_le_feature_support(const char *item, const char *value)
188 if (item == NULL || value == NULL)
191 if (g_strcmp0(item, "adv_inst_max") == 0) {
194 slot_num = atoi(value);
195 retv_if(slot_num < 0, FALSE);
196 retv_if(slot_num > BT_ADV_MULTI_MAX, FALSE);
198 if (slot_num != le_feature_info.adv_inst_max) {
199 __bt_free_le_adv_slot();
200 le_feature_info.adv_inst_max = slot_num;
201 BT_INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
202 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
204 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
205 le_feature_info.rpa_offloading = atoi(value);
206 BT_INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
207 } else if (g_strcmp0(item, "max_filter") == 0) {
208 le_feature_info.max_filter = atoi(value);
209 BT_INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
211 BT_DBG("No registered item");
218 static gboolean __bt_is_factory_test_mode(void)
222 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
223 BT_ERR("Get the DUT Mode fail");
228 BT_INFO("DUT Test Mode !!");
235 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
239 if (le_adv_slot == NULL) {
240 BT_ERR("le_adv_slot is NULL");
244 BT_DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
246 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
247 if (le_adv_slot[i].sender == NULL)
249 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
253 if (le_feature_info.adv_inst_max <= 2)
255 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
260 for (; i < le_feature_info.adv_inst_max; i++) {
261 if (le_adv_slot[i].sender == NULL)
268 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
270 if (le_adv_slot[slot_id].sender == NULL) {
271 le_adv_slot[slot_id].sender = strdup(sender);
272 le_adv_slot[slot_id].adv_handle = adv_handle;
276 void _bt_unregister_adv_slot_owner(int slot_id)
278 g_free(le_adv_slot[slot_id].sender);
279 le_adv_slot[slot_id].sender = NULL;
280 le_adv_slot[slot_id].adv_handle = 0;
283 const char* _bt_get_adv_slot_owner(int slot_id)
285 if (le_adv_slot == NULL)
288 return le_adv_slot[slot_id].sender;
291 int _bt_get_adv_slot_adv_handle(int slot_id)
293 if (le_adv_slot == NULL)
296 return le_adv_slot[slot_id].adv_handle;
299 void _bt_set_advertising_status(int slot_id, gboolean mode)
301 le_adv_slot[slot_id].is_advertising = mode;
304 gboolean _bt_is_advertising(void)
306 gboolean status = FALSE;
309 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
310 if (le_adv_slot[i].is_advertising == TRUE)
317 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
321 if (le_adv_slot == NULL)
324 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
325 if (le_adv_slot[i].sender != NULL) {
326 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
327 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
328 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
334 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
339 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
344 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
347 GError *error = NULL;
351 if (__bt_is_factory_test_mode()) {
352 BT_ERR("Unable to start advertising in factory binary !!");
353 return BLUETOOTH_ERROR_NOT_SUPPORT;
356 if (_bt_adapter_get_status() != BT_ACTIVATED &&
357 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
358 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
361 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
363 BT_ERR("There is NO available slot!!");
364 return BLUETOOTH_ERROR_NO_RESOURCES;
367 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
368 return BLUETOOTH_ERROR_IN_PROGRESS;
370 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
371 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
373 if (le_adv_slot[slot_id].hold_timer_id > 0) {
374 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
375 le_adv_slot[slot_id].hold_timer_id = 0;
378 proxy = _bt_get_adapter_proxy();
379 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
381 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
382 g_variant_new("(bi)", enable, slot_id),
383 G_DBUS_CALL_FLAGS_NONE,
389 BT_ERR("SetAdvertising Fail: %s", error->message);
390 g_clear_error(&error);
391 return BLUETOOTH_ERROR_INTERNAL;
395 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
397 le_adv_slot[slot_id].is_advertising = enable;
398 BT_INFO_C("### Set advertising [%d]", enable);
401 g_variant_unref(ret);
403 return BLUETOOTH_ERROR_NONE;
406 int _bt_set_custom_advertising(const char *sender, int adv_handle,
407 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
411 GError *error = NULL;
416 BT_CHECK_PARAMETER(params, return);
418 if (__bt_is_factory_test_mode()) {
419 BT_ERR("Unable to start advertising in factory binary !!");
420 return BLUETOOTH_ERROR_NOT_SUPPORT;
423 if (_bt_adapter_get_status() != BT_ACTIVATED &&
424 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
425 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
428 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
430 BT_ERR("There is NO available slot!!");
431 return BLUETOOTH_ERROR_NO_RESOURCES;
434 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
435 return BLUETOOTH_ERROR_IN_PROGRESS;
437 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
438 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
440 if (le_adv_slot[slot_id].hold_timer_id > 0) {
441 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
442 le_adv_slot[slot_id].hold_timer_id = 0;
445 proxy = _bt_get_adapter_proxy();
446 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
448 if (params->interval_min > params->interval_max ||
449 params->interval_min < BT_ADV_INTERVAL_MIN ||
450 params->interval_max > BT_ADV_INTERVAL_MAX)
451 return BLUETOOTH_ERROR_INVALID_PARAM;
453 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
454 return BLUETOOTH_ERROR_INVALID_PARAM;
456 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
457 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
458 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
459 return BLUETOOTH_ERROR_NOT_SUPPORT;
461 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
462 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
464 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
465 g_variant_new("(uuuui)", min, max,
466 params->filter_policy, params->type,
467 slot_id), G_DBUS_CALL_FLAGS_NONE,
471 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
472 g_clear_error(&error);
473 return BLUETOOTH_ERROR_INTERNAL;
476 adv_params.interval_min = params->interval_min;
477 adv_params.interval_max = params->interval_max;
478 adv_params.filter_policy = params->filter_policy;
479 adv_params.type = params->type;
482 g_variant_unref(ret);
484 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
485 g_variant_new("(bi)", enable, slot_id),
486 G_DBUS_CALL_FLAGS_NONE,
492 BT_ERR("SetAdvertising Fail: %s", error->message);
493 g_clear_error(&error);
494 return BLUETOOTH_ERROR_INTERNAL;
498 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
500 _bt_unregister_adv_slot_owner(slot_id);
502 le_adv_slot[slot_id].is_advertising = enable;
503 BT_INFO_C("### Set advertising [%d]", enable);
505 g_variant_unref(ret);
507 return BLUETOOTH_ERROR_NONE;
510 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
513 GError *error = NULL;
516 BT_INFO("Restart advertising stopped by bt-service");
518 le_adv_slot[0].hold_timer_id = 0;
520 proxy = _bt_get_adapter_proxy();
521 retv_if(proxy == NULL, FALSE);
523 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
524 g_variant_new("(bi)", TRUE, 0),
525 G_DBUS_CALL_FLAGS_NONE,
531 BT_ERR("SetAdvertising Fail: %s", error->message);
532 g_clear_error(&error);
537 g_variant_unref(ret);
542 int _bt_hold_current_advertising(void)
545 GError *error = NULL;
548 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
549 BT_INFO("Stop current advertising by bt-service");
551 proxy = _bt_get_adapter_proxy();
552 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
554 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
555 g_variant_new("(bi)", FALSE, 0),
556 G_DBUS_CALL_FLAGS_NONE,
562 BT_ERR("SetAdvertising Fail: %s", error->message);
563 g_clear_error(&error);
564 return BLUETOOTH_ERROR_INTERNAL;
568 g_variant_unref(ret);
570 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
571 __bt_hold_current_advertising_timeout_cb, NULL);
573 BT_ERR("It's NOT advertising");
574 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
577 return BLUETOOTH_ERROR_NONE;
580 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
581 char in_type, char **data, int *data_len)
583 if (in_data == NULL || data == NULL || data_len == NULL)
584 return BLUETOOTH_ERROR_INTERNAL;
587 return BLUETOOTH_ERROR_INTERNAL;
593 for (i = 0; i < in_len; i++) {
595 if (len <= 0 || i + 1 >= in_len) {
596 BT_ERR("Invalid advertising data");
597 return BLUETOOTH_ERROR_INTERNAL;
600 type = in_data[i + 1];
601 if (type == in_type) {
611 if (i + len > in_len) {
612 BT_ERR("Invalid advertising data");
613 return BLUETOOTH_ERROR_INTERNAL;
614 } else if (len == 0) {
615 BT_DBG("AD Type 0x%02x data is not set", in_type);
618 return BLUETOOTH_ERROR_NONE;
621 *data = g_memdup(&in_data[i], len);
623 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
626 return BLUETOOTH_ERROR_NONE;
629 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
631 BT_CHECK_PARAMETER(adv, return);
632 BT_CHECK_PARAMETER(length, return);
634 memcpy(adv, &adv_data, sizeof(adv_data));
635 *length = adv_data_len;
637 return BLUETOOTH_ERROR_NONE;
640 int _bt_set_advertising_data(const char *sender, int adv_handle,
641 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
644 GError *error = NULL;
645 GVariant *ret, *ad_data, *param = NULL;
646 GVariant *temp = NULL;
647 GVariantBuilder *builder;
649 char *old_mdata = NULL;
650 char *new_mdata = NULL;
655 if (__bt_is_factory_test_mode()) {
656 BT_ERR("Unable to set advertising data in factory binary !!");
657 return BLUETOOTH_ERROR_NOT_SUPPORT;
660 BT_CHECK_PARAMETER(adv, return);
662 if (_bt_adapter_get_status() != BT_ACTIVATED &&
663 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
664 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
667 proxy = _bt_get_adapter_proxy();
668 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
670 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
672 BT_ERR("There is NO available slot!!");
673 return BLUETOOTH_ERROR_NO_RESOURCES;
676 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
677 for (i = 0; i < length; i++)
678 g_variant_builder_add(builder, "y", adv->data[i]);
680 temp = g_variant_new("ay", builder);
681 g_variant_builder_unref(builder);
682 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
683 g_variant_new("(@ayi)", temp, slot_id),
684 G_DBUS_CALL_FLAGS_NONE,
688 BT_ERR("SetAdvertisingData Fail: %s", error->message);
689 g_clear_error(&error);
690 return BLUETOOTH_ERROR_INTERNAL;
693 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
695 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
696 &old_mdata, &old_len);
697 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
698 &new_mdata, &new_len);
699 if (old_len != new_len ||
700 (old_mdata && new_mdata &&
701 memcmp(old_mdata, new_mdata, new_len))) {
702 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
703 new_mdata, new_len, TRUE, NULL, NULL);
704 param = g_variant_new("(@ay)", ad_data);
705 _bt_send_event(BT_ADAPTER_EVENT,
706 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
712 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
713 memcpy(&adv_data, adv, length);
714 adv_data_len = length;
716 BT_INFO("Set advertising data");
718 g_variant_unref(ret);
720 return BLUETOOTH_ERROR_NONE;
723 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
725 BT_CHECK_PARAMETER(response, return);
726 BT_CHECK_PARAMETER(length, return);
728 memcpy(response, &resp_data, sizeof(resp_data));
729 *length = resp_data_len;
731 return BLUETOOTH_ERROR_NONE;
734 int _bt_set_scan_response_data(const char *sender, int adv_handle,
735 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
738 GError *error = NULL;
739 GVariant *ret, *scan_data, *param = NULL;
740 GVariant *temp = NULL;
741 GVariantBuilder *builder;
743 char *old_mdata = NULL;
744 char *new_mdata = NULL;
749 if (__bt_is_factory_test_mode()) {
750 BT_ERR("Unable to set scan response list in factory binary !!");
751 return BLUETOOTH_ERROR_NOT_SUPPORT;
754 BT_CHECK_PARAMETER(response, return);
756 if (_bt_adapter_get_status() != BT_ACTIVATED &&
757 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
758 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
761 proxy = _bt_get_adapter_proxy();
762 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
764 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
766 BT_ERR("There is NO available slot!!");
767 return BLUETOOTH_ERROR_NO_RESOURCES;
769 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
770 for (i = 0; i < length; i++)
771 g_variant_builder_add(builder, "y", response->data[i]);
773 temp = g_variant_new("ay", builder);
774 g_variant_builder_unref(builder);
775 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
776 g_variant_new("(@ayi)", temp, slot_id),
777 G_DBUS_CALL_FLAGS_NONE,
781 BT_ERR("SetScanRespData Fail: %s", error->message);
782 g_clear_error(&error);
783 return BLUETOOTH_ERROR_INTERNAL;
786 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
788 /* Compare with previous scan resp data */
789 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
790 &old_mdata, &old_len);
791 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
792 &new_mdata, &new_len);
793 if (old_len != new_len ||
794 (old_mdata && new_mdata &&
795 memcmp(old_mdata, new_mdata, new_len))) {
796 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
797 new_mdata, new_len, TRUE, NULL, NULL);
798 param = g_variant_new("(@ay)", scan_data);
799 _bt_send_event(BT_ADAPTER_EVENT,
800 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
806 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
807 memcpy(&resp_data, response, length);
808 resp_data_len = length;
811 g_variant_unref(ret);
812 BT_INFO("Set scan response data");
813 return BLUETOOTH_ERROR_NONE;
816 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
819 GError *error = NULL;
824 BT_CHECK_PARAMETER(params, return);
826 if (_bt_adapter_get_status() != BT_ACTIVATED &&
827 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
828 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
831 proxy = _bt_get_adapter_proxy();
832 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
834 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
835 return BLUETOOTH_ERROR_INVALID_PARAM;
837 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
838 return BLUETOOTH_ERROR_INVALID_PARAM;
840 if (params->window > params->interval)
841 return BLUETOOTH_ERROR_INVALID_PARAM;
843 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
844 win = params->window / BT_ADV_INTERVAL_SPLIT;
846 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
847 g_variant_new("(uuu)", params->type, itv, win),
848 G_DBUS_CALL_FLAGS_NONE, -1,
852 BT_ERR("SetScanParameters Fail: %s", error->message);
853 g_clear_error(&error);
854 return BLUETOOTH_ERROR_INTERNAL;
857 _bt_set_le_scan_type(params->type);
859 is_le_set_scan_parameter = TRUE;
862 g_variant_unref(ret);
863 BT_INFO("Set scan parameters");
864 return BLUETOOTH_ERROR_NONE;
867 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
870 bt_adapter_le_scanner_t *scanner;
872 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
874 if (g_strcmp0(scanner->sender, sender) == 0)
881 int __bt_get_available_scan_filter_slot_id(void)
884 bt_adapter_le_scanner_t *scanner;
886 bluetooth_le_scan_filter_t *filter_data;
887 gboolean *slot_check_list = NULL;
890 if (le_feature_info.max_filter == 0) {
891 BT_ERR("Scan filter is NOT Supported");
894 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
896 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
898 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
899 filter_data = fl->data;
900 if (filter_data->slot_id < le_feature_info.max_filter)
901 slot_check_list[filter_data->slot_id] = TRUE;
905 for (i = 0; i < le_feature_info.max_filter; i++) {
906 if (slot_check_list[i] == FALSE) {
907 g_free(slot_check_list);
912 BT_ERR("There is NO available slot for scan filter.");
913 g_free(slot_check_list);
917 gboolean _bt_is_scan_filter_supported(void)
919 if (le_feature_info.max_filter > 0)
925 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
928 GError *error = NULL;
929 GVariant *ret, *param;
930 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
931 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
932 GArray *arr_uuid = NULL;
933 GArray *arr_uuid_mask = NULL;
934 GArray *arr_data = NULL;
935 GArray *arr_data_mask = NULL;
936 bt_adapter_le_scanner_t *scanner = NULL;
937 bluetooth_le_scan_filter_t *filter_data = NULL;
938 int feature_selection = 0;
940 *slot_id = __bt_get_available_scan_filter_slot_id();
942 return BLUETOOTH_ERROR_NO_RESOURCES;
944 proxy = _bt_get_adapter_proxy();
945 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
947 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
948 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
949 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
951 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
953 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
954 NULL, 0, TRUE, NULL, NULL);
955 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
956 NULL, 0, TRUE, NULL, NULL);
957 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
958 NULL, 0, TRUE, NULL, NULL);
959 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
960 NULL, 0, TRUE, NULL, NULL);
962 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
964 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
965 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
966 *slot_id, // filter_index
968 0, // company_id_mask
969 arr_uuid_param, // p_uuid
970 arr_uuid_mask_param, // p_uuid_mask
973 arr_data_param, // p_data
974 arr_data_mask_param); // p_mask
976 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
977 param, G_DBUS_CALL_FLAGS_NONE,
981 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
982 g_clear_error(&error);
985 g_variant_unref(ret);
988 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
989 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
991 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
992 NULL, 0, TRUE, NULL, NULL);
993 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
994 NULL, 0, TRUE, NULL, NULL);
995 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
996 NULL, 0, TRUE, NULL, NULL);
997 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
998 NULL, 0, TRUE, NULL, NULL);
1000 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1002 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1003 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1004 *slot_id, // filter_index
1006 0, // company_id_mask
1007 arr_uuid_param, // p_uuid
1008 arr_uuid_mask_param, // p_uuid_mask
1009 filter->device_name, // string
1011 arr_data_param, // p_data
1012 arr_data_mask_param);
1014 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1015 param, G_DBUS_CALL_FLAGS_NONE,
1019 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1020 g_clear_error(&error);
1023 g_variant_unref(ret);
1026 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1027 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1029 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1030 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1032 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1033 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1035 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1036 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1037 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1038 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1039 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1040 NULL, 0, TRUE, NULL, NULL);
1041 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1042 NULL, 0, TRUE, NULL, NULL);
1044 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1046 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1047 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1048 *slot_id, // filter_index
1050 0, // company_id_mask
1051 arr_uuid_param, // p_uuid
1052 arr_uuid_mask_param, // p_uuid_mask
1055 arr_data_param, // p_data
1056 arr_data_mask_param);
1058 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1059 param, G_DBUS_CALL_FLAGS_NONE,
1063 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1064 g_clear_error(&error);
1067 g_variant_unref(ret);
1069 g_array_free(arr_uuid, TRUE);
1070 g_array_free(arr_uuid_mask, TRUE);
1071 g_array_free(arr_data, TRUE);
1072 g_array_free(arr_data_mask, TRUE);
1075 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1076 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1078 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1079 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1081 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1082 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1084 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1085 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1086 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1087 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1088 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1089 NULL, 0, TRUE, NULL, NULL);
1090 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1091 NULL, 0, TRUE, NULL, NULL);
1093 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1095 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1096 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1097 *slot_id, // filter_index
1099 0, // company_id_mask
1100 arr_uuid_param, // p_uuid
1101 arr_uuid_mask_param, // p_uuid_mask
1104 arr_data_param, // p_data
1105 arr_data_mask_param);
1107 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1108 G_DBUS_CALL_FLAGS_NONE,
1112 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1113 g_clear_error(&error);
1116 g_variant_unref(ret);
1118 g_array_free(arr_uuid, TRUE);
1119 g_array_free(arr_uuid_mask, TRUE);
1122 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1123 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1125 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1126 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1128 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1129 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1131 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1132 NULL, 0, TRUE, NULL, NULL);
1133 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1134 NULL, 0, TRUE, NULL, NULL);
1135 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1136 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1137 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1138 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1140 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1142 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1143 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1144 *slot_id, // filter_index
1146 0, // company_id_mask
1147 arr_uuid_param, // p_uuid
1148 arr_uuid_mask_param, // p_uuid_mask
1151 arr_data_param, // p_data
1152 arr_data_mask_param);
1154 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1155 G_DBUS_CALL_FLAGS_NONE,
1159 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1160 g_clear_error(&error);
1163 g_variant_unref(ret);
1165 g_array_free(arr_data, TRUE);
1166 g_array_free(arr_data_mask, TRUE);
1169 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1170 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1172 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1173 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1175 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1176 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1178 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1179 NULL, 0, TRUE, NULL, NULL);
1180 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1181 NULL, 0, TRUE, NULL, NULL);
1182 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1183 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1184 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1185 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1187 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1189 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1190 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1191 *slot_id, // filter_index
1192 filter->manufacturer_id, // company_id
1193 0xFFFF, // company_id_mask
1194 arr_uuid_param, // p_uuid
1195 arr_uuid_mask_param, // p_uuid_mask
1198 arr_data_param, // p_data
1199 arr_data_mask_param);
1201 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1202 G_DBUS_CALL_FLAGS_NONE,
1206 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1207 g_clear_error(&error);
1210 g_variant_unref(ret);
1212 g_array_free(arr_data, TRUE);
1213 g_array_free(arr_data_mask, TRUE);
1216 BT_DBG("Filter selection %.2x", feature_selection);
1218 param = g_variant_new("(iiiiiiiiiiii)",
1220 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1221 *slot_id, // filter_index
1222 feature_selection, // feat_seln
1223 0, // list_logic_type (OR - 0x00, AND - 0x01)
1224 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1225 -127, // rssi_high_thres
1226 -127, // rssi_low_thres
1227 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1230 0); // found_timeout_cnt
1231 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1232 param, G_DBUS_CALL_FLAGS_NONE,
1236 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1237 g_clear_error(&error);
1240 scanner = __bt_find_scanner_from_list(sender);
1241 if (scanner == NULL) {
1242 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1243 scanner->sender = strdup(sender);
1244 scanner_list = g_slist_append(scanner_list, scanner);
1247 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1248 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1249 filter_data->slot_id = *slot_id;
1252 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1255 g_variant_unref(ret);
1256 return BLUETOOTH_ERROR_NONE;
1259 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1262 GError *error = NULL;
1264 bt_adapter_le_scanner_t *scanner = NULL;
1265 bluetooth_le_scan_filter_t *filter_data = NULL;
1267 gboolean is_slot_id_found = FALSE;
1269 scanner = __bt_find_scanner_from_list(sender);
1270 if (scanner == NULL) {
1271 BT_ERR("There is NO available scanner.");
1272 return BLUETOOTH_ERROR_NOT_FOUND;
1275 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1276 filter_data = l->data;
1277 if (filter_data->slot_id == slot_id) {
1278 is_slot_id_found = TRUE;
1282 if (is_slot_id_found == FALSE) {
1283 BT_ERR("There is NO registered slot.");
1284 return BLUETOOTH_ERROR_NOT_FOUND;
1287 proxy = _bt_get_adapter_proxy();
1288 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1290 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1291 g_variant_new("(ii)", 0, slot_id),
1292 G_DBUS_CALL_FLAGS_NONE,
1296 BT_ERR("scan_filter_clear Fail: %s", error->message);
1297 g_clear_error(&error);
1300 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1301 g_free(filter_data);
1304 g_variant_unref(ret);
1305 return BLUETOOTH_ERROR_NONE;
1308 int _bt_unregister_all_scan_filters(const char *sender)
1311 GError *error = NULL;
1313 bt_adapter_le_scanner_t *scanner = NULL;
1314 bluetooth_le_scan_filter_t *filter_data = NULL;
1317 scanner = __bt_find_scanner_from_list(sender);
1318 if (scanner == NULL) {
1319 BT_ERR("There is NO available scanner.");
1320 return BLUETOOTH_ERROR_NOT_FOUND;
1323 proxy = _bt_get_adapter_proxy();
1324 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1326 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1327 filter_data = l->data;
1329 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1330 g_variant_new("(ii)", 0, filter_data->slot_id),
1331 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1334 BT_ERR("scan_filter_clear Fail: %s", error->message);
1335 g_clear_error(&error);
1338 g_variant_unref(ret);
1341 g_slist_free_full(scanner->filter_list, g_free);
1342 scanner->filter_list = NULL;
1344 return BLUETOOTH_ERROR_NONE;
1347 int _bt_start_le_scan(const char *sender)
1350 GError *error = NULL;
1352 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1354 if (scanner == NULL) {
1355 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1356 scanner->sender = strdup(sender);
1357 scanner_list = g_slist_append(scanner_list, scanner);
1360 if (scanner->is_scanning == TRUE) {
1361 BT_ERR("BT is already in LE scanning");
1362 return BLUETOOTH_ERROR_IN_PROGRESS;
1364 scanner->is_scanning = TRUE;
1366 proxy = _bt_get_adapter_proxy();
1367 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1369 if (_bt_is_le_scanning()) {
1370 if (scan_filter_enabled == TRUE) {
1371 if (scanner->filter_list == NULL) {
1372 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1373 g_variant_new("(ib)", 0, FALSE),
1374 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1377 BT_ERR("scan_filter_clear Fail: %s", error->message);
1378 g_clear_error(&error);
1382 g_variant_unref(ret);
1383 BT_INFO("Disable LE Scan Filter");
1384 scan_filter_enabled = FALSE;
1386 BT_INFO("LE Filter Scan is continue");
1389 BT_INFO("LE Full Scan is already on progress");
1391 return BLUETOOTH_ERROR_NONE;
1393 if (is_le_set_scan_parameter == FALSE) {
1394 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1395 bluetooth_le_scan_params_t scan_params;
1396 scan_params.type = BT_LE_ACTIVE_SCAN;
1397 scan_params.interval = 5000;
1398 scan_params.window = 500;
1399 _bt_set_scan_parameters(&scan_params);
1402 if (scanner->filter_list == NULL) {
1403 BT_INFO("Start LE Full Scan");
1404 scan_filter_enabled = FALSE;
1406 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1407 g_variant_new("(ib)", 0, TRUE),
1408 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1411 BT_ERR("scan_filter_clear Fail: %s", error->message);
1412 g_clear_error(&error);
1416 g_variant_unref(ret);
1417 BT_INFO("Enable LE Scan Filter");
1418 scan_filter_enabled = TRUE;
1422 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1423 NULL, G_DBUS_CALL_FLAGS_NONE,
1427 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1428 g_clear_error(&error);
1429 return BLUETOOTH_ERROR_INTERNAL;
1433 g_variant_unref(ret);
1434 return BLUETOOTH_ERROR_NONE;
1437 int _bt_stop_le_scan(const char *sender)
1440 GError *error = NULL;
1442 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1444 gboolean next_scanning = FALSE;
1445 gboolean need_scan_filter = TRUE;
1447 if (scanner == NULL || scanner->is_scanning == FALSE)
1448 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1450 scanner->is_scanning = FALSE;
1452 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1454 if (scanner->is_scanning == TRUE) {
1455 next_scanning = TRUE;
1456 if (scanner->filter_list == NULL)
1457 need_scan_filter = FALSE;
1461 proxy = _bt_get_adapter_proxy();
1462 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1464 if (next_scanning == TRUE) {
1465 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1466 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1467 g_variant_new("(ib)", 0, TRUE),
1468 G_DBUS_CALL_FLAGS_NONE,
1472 BT_ERR("scan_filter_clear Fail: %s", error->message);
1473 g_clear_error(&error);
1477 g_variant_unref(ret);
1478 BT_INFO("Enable LE Scan Filter");
1479 scan_filter_enabled = TRUE;
1481 return BLUETOOTH_ERROR_NONE;
1483 if (scan_filter_enabled == TRUE) {
1484 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1485 g_variant_new("(ib)", 0, FALSE),
1486 G_DBUS_CALL_FLAGS_NONE,
1490 BT_ERR("scan_filter_clear Fail: %s", error->message);
1491 g_clear_error(&error);
1495 g_variant_unref(ret);
1496 BT_INFO("Disable LE Scan Filter");
1498 BT_INFO("Just stop LE scan");
1502 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1503 NULL, G_DBUS_CALL_FLAGS_NONE,
1506 BT_ERR("LE Scan stop failed");
1507 return BLUETOOTH_ERROR_INTERNAL;
1510 scan_filter_enabled = FALSE;
1511 is_le_set_scan_parameter = FALSE;
1513 g_variant_unref(ret);
1514 return BLUETOOTH_ERROR_NONE;
1517 void _bt_disable_all_scanner_status(void)
1520 bt_adapter_le_scanner_t *scanner;
1522 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1524 scanner->is_scanning = FALSE;
1528 void _bt_set_le_scan_status(gboolean mode)
1530 is_le_scanning = mode;
1533 gboolean _bt_is_le_scanning(void)
1535 return is_le_scanning;
1538 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1540 le_scan_type = type;
1543 bt_le_scan_type_t _bt_get_le_scan_type(void)
1545 return le_scan_type;
1548 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1549 int adv_data_len, const char *svc_uuid, int uuid_len,
1550 const char *uuid_mask, char ad_type)
1556 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1557 ad_type, &data, &data_len);
1559 for (i = 0; i < data_len; i += uuid_len) {
1560 if (uuid_len > (data_len - i))
1563 if (_bt_byte_arr_cmp_with_mask(data + i,
1564 svc_uuid, uuid_mask, uuid_len) == 0) {
1575 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1576 const char *adv_data, int adv_data_len,
1577 const char *scan_data, int scan_data_len,
1578 const bt_adapter_le_scanner_t *scanner)
1581 bluetooth_le_scan_filter_t *filter_data = NULL;
1584 gboolean is_matched = FALSE;
1586 if (scanner->filter_list == NULL) {
1587 BT_INFO("This scanner is on Full Scan.");
1591 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1592 filter_data = l->data;
1594 if (filter_data->added_features &
1595 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1596 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1598 _bt_convert_addr_type_to_string(address,
1599 filter_data->device_address.addr);
1600 if (strncmp(address, device_address,
1601 BT_ADDRESS_STRING_SIZE) != 0)
1605 if (filter_data->added_features &
1606 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1609 if (__bt_check_scan_result_uuid(adv_data,
1611 (char*)filter_data->service_uuid.data.data,
1612 filter_data->service_uuid.data_len,
1613 (char*)filter_data->service_uuid_mask.data.data,
1614 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1617 if (__bt_check_scan_result_uuid(adv_data,
1619 (char*)filter_data->service_uuid.data.data,
1620 filter_data->service_uuid.data_len,
1621 (char*)filter_data->service_uuid_mask.data.data,
1622 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1625 if (__bt_check_scan_result_uuid(adv_data,
1627 (char*)filter_data->service_uuid.data.data,
1628 filter_data->service_uuid.data_len,
1629 (char*)filter_data->service_uuid_mask.data.data,
1630 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1633 if (__bt_check_scan_result_uuid(adv_data,
1635 (char*)filter_data->service_uuid.data.data,
1636 filter_data->service_uuid.data_len,
1637 (char*)filter_data->service_uuid_mask.data.data,
1638 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1641 if (__bt_check_scan_result_uuid(scan_data,
1643 (char*)filter_data->service_uuid.data.data,
1644 filter_data->service_uuid.data_len,
1645 (char*)filter_data->service_uuid_mask.data.data,
1646 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1649 if (__bt_check_scan_result_uuid(scan_data,
1651 (char*)filter_data->service_uuid.data.data,
1652 filter_data->service_uuid.data_len,
1653 (char*)filter_data->service_uuid_mask.data.data,
1654 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1657 if (__bt_check_scan_result_uuid(scan_data,
1659 (char*)filter_data->service_uuid.data.data,
1660 filter_data->service_uuid.data_len,
1661 (char*)filter_data->service_uuid_mask.data.data,
1662 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1665 if (__bt_check_scan_result_uuid(scan_data,
1667 (char*)filter_data->service_uuid.data.data,
1668 filter_data->service_uuid.data_len,
1669 (char*)filter_data->service_uuid_mask.data.data,
1670 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1674 if (is_matched == FALSE)
1677 if (filter_data->added_features &
1678 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1681 if (__bt_check_scan_result_uuid(adv_data,
1683 (char*)filter_data->service_solicitation_uuid.data.data,
1684 filter_data->service_solicitation_uuid.data_len,
1685 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1686 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1689 if (__bt_check_scan_result_uuid(adv_data,
1691 (char*)filter_data->service_solicitation_uuid.data.data,
1692 filter_data->service_solicitation_uuid.data_len,
1693 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1694 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1697 if (__bt_check_scan_result_uuid(scan_data,
1699 (char*)filter_data->service_solicitation_uuid.data.data,
1700 filter_data->service_solicitation_uuid.data_len,
1701 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1702 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1705 if (__bt_check_scan_result_uuid(scan_data,
1707 (char*)filter_data->service_solicitation_uuid.data.data,
1708 filter_data->service_solicitation_uuid.data_len,
1709 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1710 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1714 if (is_matched == FALSE)
1717 if (filter_data->added_features &
1718 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1719 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1724 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1725 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1728 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1729 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1730 memcpy(name, data, data_len);
1731 name[data_len] = '\0';
1734 if (strncmp(filter_data->device_name,
1735 name, data_len) == 0)
1738 __bt_get_ad_data_by_type((char*)scan_data,
1740 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1743 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1744 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1745 memcpy(name, data, data_len);
1746 name[data_len] = '\0';
1749 if (strncmp(filter_data->device_name,
1750 name, data_len) == 0)
1754 if (is_matched == FALSE)
1757 if (filter_data->added_features &
1758 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1763 __bt_get_ad_data_by_type((char*)adv_data,
1765 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1769 int manufacturer_id;
1770 manufacturer_id = (data[1] << 8) + data[0];
1772 if (filter_data->manufacturer_id == manufacturer_id) {
1773 if (filter_data->manufacturer_data.data_len == 0) {
1776 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1777 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1778 if (_bt_byte_arr_cmp_with_mask(data + 2,
1779 (char*)filter_data->manufacturer_data.data.data,
1780 (char*)filter_data->manufacturer_data_mask.data.data,
1781 data_len - 2) == 0) {
1789 __bt_get_ad_data_by_type((char*)scan_data,
1791 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1795 int manufacturer_id;
1796 manufacturer_id = (data[1] << 8) + data[0];
1798 if (filter_data->manufacturer_id == manufacturer_id) {
1799 if (filter_data->manufacturer_data.data_len == 0) {
1802 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1803 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1804 if (_bt_byte_arr_cmp_with_mask(data + 2,
1805 (char*)filter_data->manufacturer_data.data.data,
1806 (char*)filter_data->manufacturer_data_mask.data.data,
1807 data_len - 2) == 0) {
1816 if (is_matched == FALSE)
1819 if (filter_data->added_features &
1820 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1825 __bt_get_ad_data_by_type((char*)adv_data,
1827 BT_LE_AD_TYPE_SERVICE_DATA,
1830 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1831 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1832 if (_bt_byte_arr_cmp_with_mask(data,
1833 (char*)filter_data->service_data.data.data,
1834 (char*)filter_data->service_data_mask.data.data,
1841 __bt_get_ad_data_by_type((char*)scan_data,
1843 BT_LE_AD_TYPE_SERVICE_DATA,
1846 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1847 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1848 if (_bt_byte_arr_cmp_with_mask(data,
1849 (char*)filter_data->service_data.data.data,
1850 (char*)filter_data->service_data_mask.data.data,
1858 if (is_matched == FALSE)
1862 BT_INFO("The scan result is conformable.");
1866 BT_INFO("The scan result is NOT conformable.");
1870 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1871 const bt_le_adv_info_t *adv_info)
1873 int result = BLUETOOTH_ERROR_NONE;
1875 GVariant *scan_data_param, *adv_data_param;
1877 bt_adapter_le_scanner_t *scanner = NULL;
1878 const char *adv_data = NULL;
1879 int adv_data_len = 0;
1880 const char *scan_data = NULL;
1881 int scan_data_len = 0;
1883 ret_if(le_dev_info == NULL);
1884 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1885 ret_if(adv_info == NULL);
1887 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1888 adv_data = le_dev_info->adv_data;
1889 adv_data_len = le_dev_info->adv_data_len;
1890 scan_data = le_dev_info->adv_data;
1893 adv_data = adv_info->data;
1894 adv_data_len = adv_info->data_len;
1895 scan_data = le_dev_info->adv_data;
1896 scan_data_len = le_dev_info->adv_data_len;
1899 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1901 if (scanner->is_scanning == FALSE)
1904 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1905 adv_data, adv_data_len, scan_data, scan_data_len,
1909 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1910 adv_data, adv_data_len, TRUE, NULL, NULL);
1911 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1912 scan_data, scan_data_len, TRUE, NULL, NULL);
1914 param = g_variant_new("(isnnn@ayn@ay)",
1916 le_dev_info->address,
1917 le_dev_info->addr_type,
1925 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1926 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1928 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1933 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1936 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1937 GError *error = NULL;
1940 if (__bt_is_factory_test_mode()) {
1941 BT_ERR("Unable to add white list in factory binary !!");
1942 return BLUETOOTH_ERROR_NOT_SUPPORT;
1945 BT_CHECK_PARAMETER(device_address, return);
1947 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1948 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1949 return BLUETOOTH_ERROR_INVALID_PARAM;
1951 _bt_convert_addr_type_to_string(address, device_address->addr);
1953 proxy = _bt_get_adapter_proxy();
1954 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1956 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1957 g_variant_new("(su)", address, address_type),
1958 G_DBUS_CALL_FLAGS_NONE, -1,
1962 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
1963 g_clear_error(&error);
1964 return BLUETOOTH_ERROR_INTERNAL;
1968 g_variant_unref(ret);
1969 BT_INFO("Add white list");
1971 return BLUETOOTH_ERROR_NONE;
1974 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1977 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1978 GError *error = NULL;
1981 if (__bt_is_factory_test_mode()) {
1982 BT_ERR("Unable to remove white list in factory binary !!");
1983 return BLUETOOTH_ERROR_NOT_SUPPORT;
1986 BT_CHECK_PARAMETER(device_address, return);
1988 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1989 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1990 return BLUETOOTH_ERROR_INVALID_PARAM;
1992 _bt_convert_addr_type_to_string(address, device_address->addr);
1994 proxy = _bt_get_adapter_proxy();
1995 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1997 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1998 g_variant_new("(su)", address, address_type),
1999 G_DBUS_CALL_FLAGS_NONE, -1,
2003 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2004 g_clear_error(&error);
2005 return BLUETOOTH_ERROR_INTERNAL;
2009 g_variant_unref(ret);
2010 BT_INFO("Remove white list");
2012 return BLUETOOTH_ERROR_NONE;
2015 int _bt_clear_white_list(void)
2018 GError *error = NULL;
2021 if (__bt_is_factory_test_mode()) {
2022 BT_ERR("Unable to clear white list in factory binary !!");
2023 return BLUETOOTH_ERROR_NOT_SUPPORT;
2026 proxy = _bt_get_adapter_proxy();
2027 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2029 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2030 NULL, G_DBUS_CALL_FLAGS_NONE,
2034 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2035 g_clear_error(&error);
2036 return BLUETOOTH_ERROR_INTERNAL;
2039 g_variant_unref(ret);
2041 BT_INFO("Clear white list");
2043 return BLUETOOTH_ERROR_NONE;
2046 int _bt_initialize_ipsp(void)
2050 GError *error = NULL;
2053 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2054 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2055 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2058 proxy = _bt_get_adapter_proxy();
2059 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2061 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2062 NULL, G_DBUS_CALL_FLAGS_NONE,
2065 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2066 g_clear_error(&error);
2067 return BLUETOOTH_ERROR_INTERNAL;
2070 g_variant_unref(ret);
2072 BT_INFO("IPSP initialization called successfully");
2074 return BLUETOOTH_ERROR_NONE;
2077 int _bt_deinitialize_ipsp(void)
2081 GError *error = NULL;
2084 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2085 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2086 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2089 proxy = _bt_get_adapter_proxy();
2090 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2092 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2093 NULL, G_DBUS_CALL_FLAGS_NONE,
2096 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2097 g_clear_error(&error);
2098 return BLUETOOTH_ERROR_INTERNAL;
2101 g_variant_unref(ret);
2103 BT_INFO("IPSP De-initialization called successfully");
2105 return BLUETOOTH_ERROR_NONE;
2108 int _bt_le_read_maximum_data_length(
2109 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2111 GError *error = NULL;
2113 GVariant *reply = NULL;
2114 guint16 max_tx_octets, max_tx_time;
2115 guint16 max_rx_octets, max_rx_time;
2117 proxy = _bt_get_adapter_proxy();
2118 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2120 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2121 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2123 g_object_unref(proxy);
2125 if (reply == NULL) {
2126 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2127 if (error != NULL) {
2128 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2129 error->code, error->message);
2130 g_clear_error(&error);
2132 return BLUETOOTH_ERROR_INTERNAL;
2135 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2136 &max_rx_octets, &max_rx_time);
2138 max_le_datalength->max_tx_octets = max_tx_octets;
2139 max_le_datalength->max_tx_time = max_tx_time;
2140 max_le_datalength->max_rx_octets = max_rx_octets;
2141 max_le_datalength->max_rx_time = max_rx_time;
2143 g_variant_unref(reply);
2145 return BLUETOOTH_ERROR_NONE;
2147 int _bt_le_write_host_suggested_default_data_length(
2148 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2150 GError *error = NULL;
2152 GVariant *reply = NULL;
2154 proxy = _bt_get_adapter_proxy();
2155 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2157 reply = g_dbus_proxy_call_sync(proxy,
2158 "LEWriteHostSuggestedDataLength",
2159 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2160 G_DBUS_CALL_FLAGS_NONE,
2165 g_object_unref(proxy);
2167 if (reply == NULL) {
2168 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2169 if (error != NULL) {
2170 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2171 error->code, error->message);
2172 g_clear_error(&error);
2174 return BLUETOOTH_ERROR_INTERNAL;
2177 g_variant_unref(reply);
2179 return BLUETOOTH_ERROR_NONE;
2182 int _bt_le_read_host_suggested_default_data_length(
2183 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2185 GError *error = NULL;
2187 GVariant *reply = NULL;
2188 guint16 def_tx_octets, def_tx_time;
2190 proxy = _bt_get_adapter_proxy();
2191 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2193 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2194 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2196 if (reply == NULL) {
2197 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2198 if (error != NULL) {
2199 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2200 error->code, error->message);
2201 g_clear_error(&error);
2203 return BLUETOOTH_ERROR_INTERNAL;
2206 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2208 def_data_length->def_tx_octets = def_tx_octets;
2209 def_data_length->def_tx_time = def_tx_time;
2211 g_variant_unref(reply);
2213 return BLUETOOTH_ERROR_NONE;
2216 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2217 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2219 GError *error = NULL;
2220 guint16 txOctets = max_tx_Octets;
2221 guint16 txTime = max_tx_Time;
2222 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2223 gchar *device_path = NULL;
2224 GDBusConnection *conn;
2225 GDBusProxy *device_proxy;
2227 _bt_convert_addr_type_to_string(address, device_address->addr);
2229 device_path = _bt_get_device_object_path(address);
2231 if (device_path == NULL) {
2232 BT_DBG("Device path is null");
2233 return BLUETOOTH_ERROR_INTERNAL;
2236 conn = _bt_gdbus_get_system_gconn();
2238 BT_ERR("conn == NULL");
2239 g_free(device_path);
2240 return BLUETOOTH_ERROR_INTERNAL;
2243 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2244 NULL, BT_BLUEZ_NAME,
2245 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2247 g_free(device_path);
2248 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2250 g_dbus_proxy_call_sync(device_proxy,
2252 g_variant_new("(qq)", txOctets, txTime),
2253 G_DBUS_CALL_FLAGS_NONE,
2258 g_object_unref(device_proxy);
2261 BT_ERR("LESetDataLength error: [%s]", error->message);
2262 g_error_free(error);
2263 return BLUETOOTH_ERROR_INTERNAL;
2266 return BLUETOOTH_ERROR_NONE;