2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dbus/dbus.h>
25 #include <syspopup_caller.h>
28 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-event.h"
31 #include "bt-service-adapter.h"
32 #include "bt-service-adapter-le.h"
33 #include "bt-service-util.h"
36 #define BT_ADV_INTERVAL_MIN 20 /* msec */
37 #define BT_ADV_INTERVAL_MAX 10240
38 #define BT_ADV_INTERVAL_SPLIT 0.625
39 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
40 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
41 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
42 #define BT_ADV_TYPE_DEFAULT 0x00
43 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
44 #define BT_ADV_MULTI_MAX 16
50 } bt_adapter_le_feature_info_t;
55 gboolean is_advertising;
57 } bt_adapter_le_adv_slot_t;
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);
179 int _bt_service_adapter_le_init(void)
181 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
183 return BLUETOOTH_ERROR_NONE;
186 void _bt_service_adapter_le_deinit(void)
188 __bt_free_le_adv_slot();
191 gboolean _bt_update_le_feature_support(const char *item, const char *value)
193 if (item == NULL || value == NULL)
196 if (g_strcmp0(item, "adv_inst_max") == 0) {
199 slot_num = atoi(value);
200 retv_if(slot_num < 0, FALSE);
201 retv_if(slot_num > BT_ADV_MULTI_MAX, FALSE);
203 if (slot_num != le_feature_info.adv_inst_max) {
204 __bt_free_le_adv_slot();
205 le_feature_info.adv_inst_max = slot_num;
206 BT_INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
207 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
209 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
210 le_feature_info.rpa_offloading = atoi(value);
211 BT_INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
212 } else if (g_strcmp0(item, "max_filter") == 0) {
213 le_feature_info.max_filter = atoi(value);
214 BT_INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
216 BT_DBG("No registered item");
223 static gboolean __bt_is_factory_test_mode(void)
227 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
228 BT_ERR("Get the DUT Mode fail");
233 BT_INFO("DUT Test Mode !!");
240 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
244 if (le_adv_slot == NULL) {
245 BT_ERR("le_adv_slot is NULL");
249 BT_DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
251 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
252 if (le_adv_slot[i].sender == NULL)
254 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
258 if (le_feature_info.adv_inst_max <= 2)
260 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
265 for (; i < le_feature_info.adv_inst_max; i++) {
266 if (le_adv_slot[i].sender == NULL)
273 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
275 if (le_adv_slot[slot_id].sender == NULL) {
276 le_adv_slot[slot_id].sender = strdup(sender);
277 le_adv_slot[slot_id].adv_handle = adv_handle;
281 void _bt_unregister_adv_slot_owner(int slot_id)
283 g_free(le_adv_slot[slot_id].sender);
284 le_adv_slot[slot_id].sender = NULL;
285 le_adv_slot[slot_id].adv_handle = 0;
288 const char* _bt_get_adv_slot_owner(int slot_id)
290 if (le_adv_slot == NULL)
293 return le_adv_slot[slot_id].sender;
296 int _bt_get_adv_slot_adv_handle(int slot_id)
298 if (le_adv_slot == NULL)
301 return le_adv_slot[slot_id].adv_handle;
304 void _bt_set_advertising_status(int slot_id, gboolean mode)
306 le_adv_slot[slot_id].is_advertising = mode;
309 gboolean _bt_is_advertising(void)
311 gboolean status = FALSE;
314 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
315 if (le_adv_slot[i].is_advertising == TRUE)
322 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
326 if (le_adv_slot == NULL)
329 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
330 if (le_adv_slot[i].sender != NULL) {
331 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
332 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
333 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
339 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
344 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
349 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
352 GError *error = NULL;
356 if (__bt_is_factory_test_mode()) {
357 BT_ERR("Unable to start advertising in factory binary !!");
358 return BLUETOOTH_ERROR_NOT_SUPPORT;
361 if (_bt_adapter_get_status() != BT_ACTIVATED &&
362 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
363 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
366 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
368 BT_ERR("There is NO available slot!!");
369 return BLUETOOTH_ERROR_NO_RESOURCES;
372 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
373 return BLUETOOTH_ERROR_IN_PROGRESS;
375 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
376 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
378 if (le_adv_slot[slot_id].hold_timer_id > 0) {
379 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
380 le_adv_slot[slot_id].hold_timer_id = 0;
383 proxy = _bt_get_adapter_proxy();
384 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
386 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
387 g_variant_new("(bi)", enable, slot_id),
388 G_DBUS_CALL_FLAGS_NONE,
394 BT_ERR("SetAdvertising Fail: %s", error->message);
395 g_clear_error(&error);
396 return BLUETOOTH_ERROR_INTERNAL;
400 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
402 le_adv_slot[slot_id].is_advertising = enable;
403 BT_INFO("Set advertising [%d]", enable);
406 g_variant_unref(ret);
408 return BLUETOOTH_ERROR_NONE;
411 int _bt_set_custom_advertising(const char *sender, int adv_handle,
412 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
416 GError *error = NULL;
421 BT_CHECK_PARAMETER(params, return);
423 if (__bt_is_factory_test_mode()) {
424 BT_ERR("Unable to start advertising in factory binary !!");
425 return BLUETOOTH_ERROR_NOT_SUPPORT;
428 if (_bt_adapter_get_status() != BT_ACTIVATED &&
429 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
430 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
433 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
435 BT_ERR("There is NO available slot!!");
436 return BLUETOOTH_ERROR_NO_RESOURCES;
439 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
440 return BLUETOOTH_ERROR_IN_PROGRESS;
442 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
443 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
445 if (le_adv_slot[slot_id].hold_timer_id > 0) {
446 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
447 le_adv_slot[slot_id].hold_timer_id = 0;
450 proxy = _bt_get_adapter_proxy();
451 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
453 if (params->interval_min > params->interval_max ||
454 params->interval_min < BT_ADV_INTERVAL_MIN ||
455 params->interval_max > BT_ADV_INTERVAL_MAX)
456 return BLUETOOTH_ERROR_INVALID_PARAM;
458 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
459 return BLUETOOTH_ERROR_INVALID_PARAM;
461 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
462 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
463 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
464 return BLUETOOTH_ERROR_NOT_SUPPORT;
466 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
467 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
469 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
470 g_variant_new("(uuuui)", min, max,
471 params->filter_policy, params->type,
472 slot_id), G_DBUS_CALL_FLAGS_NONE,
476 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
477 g_clear_error(&error);
478 return BLUETOOTH_ERROR_INTERNAL;
481 adv_params.interval_min = params->interval_min;
482 adv_params.interval_max = params->interval_max;
483 adv_params.filter_policy = params->filter_policy;
484 adv_params.type = params->type;
487 g_variant_unref(ret);
489 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
490 g_variant_new("(bi)", enable, slot_id),
491 G_DBUS_CALL_FLAGS_NONE,
497 BT_ERR("SetAdvertising Fail: %s", error->message);
498 g_clear_error(&error);
499 return BLUETOOTH_ERROR_INTERNAL;
503 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
505 _bt_unregister_adv_slot_owner(slot_id);
507 le_adv_slot[slot_id].is_advertising = enable;
508 BT_INFO_C("### Set advertising [%d]", enable);
510 g_variant_unref(ret);
512 return BLUETOOTH_ERROR_NONE;
515 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
518 GError *error = NULL;
521 BT_INFO("Restart advertising stopped by bt-service");
523 le_adv_slot[0].hold_timer_id = 0;
525 proxy = _bt_get_adapter_proxy();
526 retv_if(proxy == NULL, FALSE);
528 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
529 g_variant_new("(bi)", TRUE, 0),
530 G_DBUS_CALL_FLAGS_NONE,
536 BT_ERR("SetAdvertising Fail: %s", error->message);
537 g_clear_error(&error);
542 g_variant_unref(ret);
547 int _bt_hold_current_advertising(void)
550 GError *error = NULL;
553 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
554 BT_INFO("Stop current advertising by bt-service");
556 proxy = _bt_get_adapter_proxy();
557 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
559 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
560 g_variant_new("(bi)", FALSE, 0),
561 G_DBUS_CALL_FLAGS_NONE,
567 BT_ERR("SetAdvertising Fail: %s", error->message);
568 g_clear_error(&error);
569 return BLUETOOTH_ERROR_INTERNAL;
573 g_variant_unref(ret);
575 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
576 __bt_hold_current_advertising_timeout_cb, NULL);
579 return BLUETOOTH_ERROR_NONE;
582 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
583 char in_type, char **data, int *data_len)
585 if (in_data == NULL || data == NULL || data_len == NULL)
586 return BLUETOOTH_ERROR_INTERNAL;
589 return BLUETOOTH_ERROR_INTERNAL;
595 for (i = 0; i < in_len; i++) {
597 if (len <= 0 || i + 1 >= in_len) {
598 BT_ERR("Invalid advertising data");
599 return BLUETOOTH_ERROR_INTERNAL;
602 type = in_data[i + 1];
603 if (type == in_type) {
613 if (i + len > in_len) {
614 BT_ERR("Invalid advertising data");
615 return BLUETOOTH_ERROR_INTERNAL;
616 } else if (len == 0) {
617 BT_DBG("AD Type 0x%02x data is not set", in_type);
620 return BLUETOOTH_ERROR_NONE;
623 *data = g_memdup(&in_data[i], len);
625 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
628 return BLUETOOTH_ERROR_NONE;
631 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
633 BT_CHECK_PARAMETER(adv, return);
634 BT_CHECK_PARAMETER(length, return);
636 memcpy(adv, &adv_data, sizeof(adv_data));
637 *length = adv_data_len;
639 return BLUETOOTH_ERROR_NONE;
642 int _bt_set_advertising_data(const char *sender, int adv_handle,
643 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
646 GError *error = NULL;
647 GVariant *ret, *ad_data, *param = NULL;
648 GVariant *temp = NULL;
649 GVariantBuilder *builder;
651 char *old_mdata = NULL;
652 char *new_mdata = NULL;
657 if (__bt_is_factory_test_mode()) {
658 BT_ERR("Unable to set advertising data in factory binary !!");
659 return BLUETOOTH_ERROR_NOT_SUPPORT;
662 BT_CHECK_PARAMETER(adv, return);
664 if (_bt_adapter_get_status() != BT_ACTIVATED &&
665 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
666 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
669 proxy = _bt_get_adapter_proxy();
670 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
672 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
674 BT_ERR("There is NO available slot!!");
675 return BLUETOOTH_ERROR_NO_RESOURCES;
678 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
679 for (i = 0; i < length; i++) {
680 g_variant_builder_add(builder, "y", adv->data[i]);
683 temp = g_variant_new("ay", builder);
684 g_variant_builder_unref(builder);
685 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
686 g_variant_new("(@ayi)", temp, slot_id),
687 G_DBUS_CALL_FLAGS_NONE,
691 BT_ERR("SetAdvertisingData Fail: %s", error->message);
692 g_clear_error(&error);
693 return BLUETOOTH_ERROR_INTERNAL;
696 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
698 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
699 &old_mdata, &old_len);
700 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
701 &new_mdata, &new_len);
702 if (old_len != new_len ||
703 (old_mdata && new_mdata &&
704 memcmp(old_mdata, new_mdata, new_len))) {
705 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
706 new_mdata, new_len, TRUE, NULL, NULL);
707 param = g_variant_new("(@ay)", ad_data);
708 _bt_send_event(BT_ADAPTER_EVENT,
709 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
715 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
716 memcpy(&adv_data, adv, length);
717 adv_data_len = length;
719 BT_INFO("Set advertising data");
721 g_variant_unref(ret);
723 return BLUETOOTH_ERROR_NONE;
726 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
728 BT_CHECK_PARAMETER(response, return);
729 BT_CHECK_PARAMETER(length, return);
731 memcpy(response, &resp_data, sizeof(resp_data));
732 *length = resp_data_len;
734 return BLUETOOTH_ERROR_NONE;
737 int _bt_set_scan_response_data(const char *sender, int adv_handle,
738 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
741 GError *error = NULL;
742 GVariant *ret, *scan_data, *param = NULL;
743 GVariant *temp = NULL;
744 GVariantBuilder *builder;
746 char *old_mdata = NULL;
747 char *new_mdata = NULL;
752 if (__bt_is_factory_test_mode()) {
753 BT_ERR("Unable to set scan response list in factory binary !!");
754 return BLUETOOTH_ERROR_NOT_SUPPORT;
757 BT_CHECK_PARAMETER(response, return);
759 if (_bt_adapter_get_status() != BT_ACTIVATED &&
760 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
761 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
764 proxy = _bt_get_adapter_proxy();
765 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
767 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
769 BT_ERR("There is NO available slot!!");
770 return BLUETOOTH_ERROR_NO_RESOURCES;
772 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
773 for (i = 0; i < length; i++) {
774 g_variant_builder_add(builder, "y", response->data[i]);
777 temp = g_variant_new("ay", builder);
778 g_variant_builder_unref(builder);
779 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
780 g_variant_new("(@ayi)", temp, slot_id),
781 G_DBUS_CALL_FLAGS_NONE,
785 BT_ERR("SetScanRespData Fail: %s", error->message);
786 g_clear_error(&error);
787 return BLUETOOTH_ERROR_INTERNAL;
790 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
792 /* Compare with previous scan resp data */
793 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
794 &old_mdata, &old_len);
795 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
796 &new_mdata, &new_len);
797 if (old_len != new_len ||
798 (old_mdata && new_mdata &&
799 memcmp(old_mdata, new_mdata, new_len))) {
800 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
801 new_mdata, new_len, TRUE, NULL, NULL);
802 param = g_variant_new("(@ay)", scan_data);
803 _bt_send_event(BT_ADAPTER_EVENT,
804 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
810 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
811 memcpy(&resp_data, response, length);
812 resp_data_len = length;
815 g_variant_unref(ret);
816 BT_INFO("Set scan response data");
817 return BLUETOOTH_ERROR_NONE;
820 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
823 GError *error = NULL;
828 BT_CHECK_PARAMETER(params, return);
830 if (_bt_adapter_get_status() != BT_ACTIVATED &&
831 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
832 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
835 proxy = _bt_get_adapter_proxy();
836 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
838 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
839 return BLUETOOTH_ERROR_INVALID_PARAM;
841 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
842 return BLUETOOTH_ERROR_INVALID_PARAM;
844 if (params->window > params->interval)
845 return BLUETOOTH_ERROR_INVALID_PARAM;
847 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
848 win = params->window / BT_ADV_INTERVAL_SPLIT;
850 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
851 g_variant_new("(uuu)", params->type, itv, win),
852 G_DBUS_CALL_FLAGS_NONE, -1,
856 BT_ERR("SetScanParameters Fail: %s", error->message);
857 g_clear_error(&error);
858 return BLUETOOTH_ERROR_INTERNAL;
861 _bt_set_le_scan_type(params->type);
863 is_le_set_scan_parameter = TRUE;
866 g_variant_unref(ret);
867 BT_INFO("Set scan parameters");
868 return BLUETOOTH_ERROR_NONE;
871 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
874 bt_adapter_le_scanner_t *scanner;
876 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
878 if (g_strcmp0(scanner->sender, sender) == 0)
885 int __bt_get_available_scan_filter_slot_id(void)
888 bt_adapter_le_scanner_t *scanner;
890 bluetooth_le_scan_filter_t *filter_data;
891 gboolean *slot_check_list = NULL;
894 if (le_feature_info.max_filter == 0) {
895 BT_ERR("Scan filter is NOT Supported");
898 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
899 if (slot_check_list == NULL) {
900 BT_ERR("Fail to allocate memory");
904 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
906 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
907 filter_data = fl->data;
908 if (filter_data->slot_id < le_feature_info.max_filter) {
909 slot_check_list[filter_data->slot_id] = TRUE;
914 for (i = 0; i < le_feature_info.max_filter; i++) {
915 if (slot_check_list[i] == FALSE) {
916 g_free(slot_check_list);
921 BT_ERR("There is NO available slot for scan filter.");
922 g_free(slot_check_list);
926 gboolean _bt_is_scan_filter_supported(void)
928 if (le_feature_info.max_filter > 0) {
935 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
938 GError *error = NULL;
939 GVariant *ret, *param;
940 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
941 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
942 GArray *arr_uuid = NULL;
943 GArray *arr_uuid_mask = NULL;
944 GArray *arr_data = NULL;
945 GArray *arr_data_mask = NULL;
946 bt_adapter_le_scanner_t *scanner = NULL;
947 bluetooth_le_scan_filter_t *filter_data = NULL;
948 int feature_selection = 0;
950 *slot_id = __bt_get_available_scan_filter_slot_id();
952 return BLUETOOTH_ERROR_NO_RESOURCES;
954 proxy = _bt_get_adapter_proxy();
955 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
957 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
958 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
959 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
961 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
963 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
964 NULL, 0, TRUE, NULL, NULL);
965 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
966 NULL, 0, TRUE, NULL, NULL);
967 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
968 NULL, 0, TRUE, NULL, NULL);
969 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
970 NULL, 0, TRUE, NULL, NULL);
972 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
974 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
975 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
976 *slot_id, // filter_index
978 0, // company_id_mask
979 arr_uuid_param, // p_uuid
980 arr_uuid_mask_param, // p_uuid_mask
983 arr_data_param, // p_data
984 arr_data_mask_param); // p_mask
986 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
987 param, G_DBUS_CALL_FLAGS_NONE,
991 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
992 g_clear_error(&error);
995 g_variant_unref(ret);
998 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
999 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
1001 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1002 NULL, 0, TRUE, NULL, NULL);
1003 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1004 NULL, 0, TRUE, NULL, NULL);
1005 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1006 NULL, 0, TRUE, NULL, NULL);
1007 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1008 NULL, 0, TRUE, NULL, NULL);
1010 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1012 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1013 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1014 *slot_id, // filter_index
1016 0, // company_id_mask
1017 arr_uuid_param, // p_uuid
1018 arr_uuid_mask_param, // p_uuid_mask
1019 filter->device_name, // string
1021 arr_data_param, // p_data
1022 arr_data_mask_param);
1024 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1025 param, G_DBUS_CALL_FLAGS_NONE,
1029 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1030 g_clear_error(&error);
1033 g_variant_unref(ret);
1036 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1037 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1039 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1040 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1042 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1043 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1045 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1046 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1047 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1048 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1049 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1050 NULL, 0, TRUE, NULL, NULL);
1051 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1052 NULL, 0, TRUE, NULL, NULL);
1054 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1056 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1057 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1058 *slot_id, // filter_index
1060 0, // company_id_mask
1061 arr_uuid_param, // p_uuid
1062 arr_uuid_mask_param, // p_uuid_mask
1065 arr_data_param, // p_data
1066 arr_data_mask_param);
1068 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1069 param, G_DBUS_CALL_FLAGS_NONE,
1073 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1074 g_clear_error(&error);
1077 g_variant_unref(ret);
1079 g_array_free(arr_uuid, TRUE);
1080 g_array_free(arr_uuid_mask, TRUE);
1081 g_array_free(arr_data, TRUE);
1082 g_array_free(arr_data_mask, TRUE);
1085 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1086 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1088 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1089 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1091 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1092 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1094 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1095 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1096 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1097 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1098 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1099 NULL, 0, TRUE, NULL, NULL);
1100 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1101 NULL, 0, TRUE, NULL, NULL);
1103 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1105 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1106 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1107 *slot_id, // filter_index
1109 0, // company_id_mask
1110 arr_uuid_param, // p_uuid
1111 arr_uuid_mask_param, // p_uuid_mask
1114 arr_data_param, // p_data
1115 arr_data_mask_param);
1117 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1118 G_DBUS_CALL_FLAGS_NONE,
1122 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1123 g_clear_error(&error);
1126 g_variant_unref(ret);
1128 g_array_free(arr_uuid, TRUE);
1129 g_array_free(arr_uuid_mask, TRUE);
1132 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1133 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1135 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1136 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1138 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1139 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1141 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1142 NULL, 0, TRUE, NULL, NULL);
1143 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1144 NULL, 0, TRUE, NULL, NULL);
1145 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1146 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1147 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1148 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1150 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1152 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1153 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1154 *slot_id, // filter_index
1156 0, // company_id_mask
1157 arr_uuid_param, // p_uuid
1158 arr_uuid_mask_param, // p_uuid_mask
1161 arr_data_param, // p_data
1162 arr_data_mask_param);
1164 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1165 G_DBUS_CALL_FLAGS_NONE,
1169 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1170 g_clear_error(&error);
1173 g_variant_unref(ret);
1175 g_array_free(arr_data, TRUE);
1176 g_array_free(arr_data_mask, TRUE);
1179 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1180 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1182 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1183 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1185 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1186 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1188 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1189 NULL, 0, TRUE, NULL, NULL);
1190 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1191 NULL, 0, TRUE, NULL, NULL);
1192 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1193 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1194 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1195 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1197 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1199 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1200 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1201 *slot_id, // filter_index
1202 filter->manufacturer_id, // company_id
1203 0xFFFF, // company_id_mask
1204 arr_uuid_param, // p_uuid
1205 arr_uuid_mask_param, // p_uuid_mask
1208 arr_data_param, // p_data
1209 arr_data_mask_param);
1211 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1212 G_DBUS_CALL_FLAGS_NONE,
1216 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1217 g_clear_error(&error);
1220 g_variant_unref(ret);
1222 g_array_free(arr_data, TRUE);
1223 g_array_free(arr_data_mask, TRUE);
1226 BT_DBG("Filter selection %.2x", feature_selection);
1228 param = g_variant_new("(iiiiiiiiiiii)",
1230 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1231 *slot_id, // filter_index
1232 feature_selection, // feat_seln
1233 0, // list_logic_type (OR - 0x00, AND - 0x01)
1234 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1235 -127, // rssi_high_thres
1236 -127, // rssi_low_thres
1237 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1240 0); // found_timeout_cnt
1241 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1242 param, G_DBUS_CALL_FLAGS_NONE,
1246 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1247 g_clear_error(&error);
1250 scanner = __bt_find_scanner_from_list(sender);
1251 if (scanner == NULL) {
1252 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1254 scanner->sender = strdup(sender);
1255 scanner_list = g_slist_append(scanner_list, scanner);
1259 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1261 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1262 filter_data->slot_id = *slot_id;
1265 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1269 g_variant_unref(ret);
1270 return BLUETOOTH_ERROR_NONE;
1273 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1276 GError *error = NULL;
1278 bt_adapter_le_scanner_t *scanner = NULL;
1279 bluetooth_le_scan_filter_t *filter_data = NULL;
1281 gboolean is_slot_id_found = FALSE;
1283 scanner = __bt_find_scanner_from_list(sender);
1284 if (scanner == NULL) {
1285 BT_ERR("There is NO available scanner.");
1286 return BLUETOOTH_ERROR_NOT_FOUND;
1289 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1290 filter_data = l->data;
1291 if (filter_data->slot_id == slot_id) {
1292 is_slot_id_found = TRUE;
1296 if (is_slot_id_found == FALSE) {
1297 BT_ERR("There is NO registered slot.");
1298 return BLUETOOTH_ERROR_NOT_FOUND;
1301 proxy = _bt_get_adapter_proxy();
1302 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1304 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1305 g_variant_new("(ii)", 0, slot_id),
1306 G_DBUS_CALL_FLAGS_NONE,
1310 BT_ERR("scan_filter_clear Fail: %s", error->message);
1311 g_clear_error(&error);
1314 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1315 g_free(filter_data);
1318 g_variant_unref(ret);
1319 return BLUETOOTH_ERROR_NONE;
1322 int _bt_unregister_all_scan_filters(const char *sender)
1325 GError *error = NULL;
1327 bt_adapter_le_scanner_t *scanner = NULL;
1328 bluetooth_le_scan_filter_t *filter_data = NULL;
1331 scanner = __bt_find_scanner_from_list(sender);
1332 if (scanner == NULL) {
1333 BT_ERR("There is NO available scanner.");
1334 return BLUETOOTH_ERROR_NOT_FOUND;
1337 proxy = _bt_get_adapter_proxy();
1338 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1340 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1341 filter_data = l->data;
1343 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1344 g_variant_new("(ii)", 0, filter_data->slot_id),
1345 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1348 BT_ERR("scan_filter_clear Fail: %s", error->message);
1349 g_clear_error(&error);
1352 g_variant_unref(ret);
1355 g_slist_free_full(scanner->filter_list, g_free);
1356 scanner->filter_list = NULL;
1358 return BLUETOOTH_ERROR_NONE;
1361 int _bt_start_le_scan(const char *sender)
1364 GError *error = NULL;
1366 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1368 /* Before finishing kernel merge, temperary return TRUE always for TCT issue */
1369 #ifdef USB_BLUETOOTH
1370 return BLUETOOTH_ERROR_NONE;
1373 if (scanner == NULL) {
1374 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1375 retv_if(scanner == NULL, BLUETOOTH_ERROR_INTERNAL);
1377 scanner->sender = strdup(sender);
1378 scanner_list = g_slist_append(scanner_list, scanner);
1381 if (scanner->is_scanning == TRUE) {
1382 BT_ERR("BT is already in LE scanning");
1383 return BLUETOOTH_ERROR_IN_PROGRESS;
1385 scanner->is_scanning = TRUE;
1387 proxy = _bt_get_adapter_proxy();
1388 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1390 if (_bt_is_le_scanning()) {
1391 if (scan_filter_enabled == TRUE) {
1392 if (scanner->filter_list == NULL) {
1393 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1394 g_variant_new("(ib)", 0, FALSE),
1395 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1398 BT_ERR("scan_filter_clear Fail: %s", error->message);
1399 g_clear_error(&error);
1403 g_variant_unref(ret);
1404 BT_INFO("Disable LE Scan Filter");
1405 scan_filter_enabled = FALSE;
1407 BT_INFO("LE Filter Scan is continue");
1410 BT_INFO("LE Full Scan is already on progress");
1412 return BLUETOOTH_ERROR_NONE;
1414 if (is_le_set_scan_parameter == FALSE) {
1415 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1416 bluetooth_le_scan_params_t scan_params;
1417 scan_params.type = BT_LE_ACTIVE_SCAN;
1418 scan_params.interval = 5000;
1419 scan_params.window = 500;
1420 _bt_set_scan_parameters(&scan_params);
1423 if (scanner->filter_list == NULL) {
1424 BT_INFO("Start LE Full Scan");
1425 scan_filter_enabled = FALSE;
1427 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1428 g_variant_new("(ib)", 0, TRUE),
1429 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1432 BT_ERR("scan_filter_clear Fail: %s", error->message);
1433 g_clear_error(&error);
1437 g_variant_unref(ret);
1438 BT_INFO("Enable LE Scan Filter");
1439 scan_filter_enabled = TRUE;
1443 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1444 NULL, G_DBUS_CALL_FLAGS_NONE,
1448 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1449 g_clear_error(&error);
1450 return BLUETOOTH_ERROR_INTERNAL;
1454 g_variant_unref(ret);
1455 return BLUETOOTH_ERROR_NONE;
1458 int _bt_stop_le_scan(const char *sender)
1461 GError *error = NULL;
1463 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1465 gboolean next_scanning = FALSE;
1466 gboolean need_scan_filter = TRUE;
1468 /* Before finishing kernel merge, temperary return TRUE always for TCT issue */
1469 #ifdef USB_BLUETOOTH
1470 return BLUETOOTH_ERROR_NONE;
1473 if (scanner == NULL || scanner->is_scanning == FALSE)
1474 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1476 scanner->is_scanning = FALSE;
1478 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1480 if (scanner->is_scanning == TRUE) {
1481 next_scanning = TRUE;
1482 if (scanner->filter_list == NULL)
1483 need_scan_filter = FALSE;
1487 proxy = _bt_get_adapter_proxy();
1488 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1490 if (next_scanning == TRUE) {
1491 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1492 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1493 g_variant_new("(ib)", 0, TRUE),
1494 G_DBUS_CALL_FLAGS_NONE,
1498 BT_ERR("scan_filter_clear Fail: %s", error->message);
1499 g_clear_error(&error);
1503 g_variant_unref(ret);
1504 BT_INFO("Enable LE Scan Filter");
1505 scan_filter_enabled = TRUE;
1507 return BLUETOOTH_ERROR_NONE;
1509 if (scan_filter_enabled == TRUE) {
1510 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1511 g_variant_new("(ib)", 0, FALSE),
1512 G_DBUS_CALL_FLAGS_NONE,
1516 BT_ERR("scan_filter_clear Fail: %s", error->message);
1517 g_clear_error(&error);
1521 g_variant_unref(ret);
1522 BT_INFO("Disable LE Scan Filter");
1524 BT_INFO("Just stop LE scan");
1528 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1529 NULL, G_DBUS_CALL_FLAGS_NONE,
1532 BT_ERR("LE Scan stop failed");
1533 return BLUETOOTH_ERROR_INTERNAL;
1536 scan_filter_enabled = FALSE;
1537 is_le_set_scan_parameter = FALSE;
1539 g_variant_unref(ret);
1540 return BLUETOOTH_ERROR_NONE;
1543 void _bt_disable_all_scanner_status(void)
1546 bt_adapter_le_scanner_t *scanner;
1548 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1550 scanner->is_scanning = FALSE;
1554 void _bt_set_le_scan_status(gboolean mode)
1556 is_le_scanning = mode;
1559 gboolean _bt_is_le_scanning(void)
1561 return is_le_scanning;
1564 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1566 le_scan_type = type;
1569 bt_le_scan_type_t _bt_get_le_scan_type(void)
1571 return le_scan_type;
1574 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1575 int adv_data_len, const char *svc_uuid, int uuid_len,
1576 const char *uuid_mask, char ad_type)
1582 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1583 ad_type, &data, &data_len);
1585 for (i = 0; i < data_len; i += uuid_len) {
1586 if (uuid_len > (data_len - i))
1589 if (_bt_byte_arr_cmp_with_mask(data + i,
1590 svc_uuid, uuid_mask, uuid_len) == 0) {
1601 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1602 const char *adv_data, int adv_data_len,
1603 const char *scan_data, int scan_data_len,
1604 const bt_adapter_le_scanner_t *scanner)
1607 bluetooth_le_scan_filter_t *filter_data = NULL;
1610 gboolean is_matched = FALSE;
1612 if (scanner->filter_list == NULL) {
1613 BT_INFO("This scanner is on Full Scan.");
1617 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1618 filter_data = l->data;
1620 if (filter_data->added_features &
1621 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1622 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1624 _bt_convert_addr_type_to_string(address,
1625 filter_data->device_address.addr);
1626 if (strncmp(address, device_address,
1627 BT_ADDRESS_STRING_SIZE) != 0)
1631 if (filter_data->added_features &
1632 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1635 if (__bt_check_scan_result_uuid(adv_data,
1637 (char*)filter_data->service_uuid.data.data,
1638 filter_data->service_uuid.data_len,
1639 (char*)filter_data->service_uuid_mask.data.data,
1640 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1643 if (__bt_check_scan_result_uuid(adv_data,
1645 (char*)filter_data->service_uuid.data.data,
1646 filter_data->service_uuid.data_len,
1647 (char*)filter_data->service_uuid_mask.data.data,
1648 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1651 if (__bt_check_scan_result_uuid(adv_data,
1653 (char*)filter_data->service_uuid.data.data,
1654 filter_data->service_uuid.data_len,
1655 (char*)filter_data->service_uuid_mask.data.data,
1656 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1659 if (__bt_check_scan_result_uuid(adv_data,
1661 (char*)filter_data->service_uuid.data.data,
1662 filter_data->service_uuid.data_len,
1663 (char*)filter_data->service_uuid_mask.data.data,
1664 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1667 if (__bt_check_scan_result_uuid(scan_data,
1669 (char*)filter_data->service_uuid.data.data,
1670 filter_data->service_uuid.data_len,
1671 (char*)filter_data->service_uuid_mask.data.data,
1672 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1675 if (__bt_check_scan_result_uuid(scan_data,
1677 (char*)filter_data->service_uuid.data.data,
1678 filter_data->service_uuid.data_len,
1679 (char*)filter_data->service_uuid_mask.data.data,
1680 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1683 if (__bt_check_scan_result_uuid(scan_data,
1685 (char*)filter_data->service_uuid.data.data,
1686 filter_data->service_uuid.data_len,
1687 (char*)filter_data->service_uuid_mask.data.data,
1688 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1691 if (__bt_check_scan_result_uuid(scan_data,
1693 (char*)filter_data->service_uuid.data.data,
1694 filter_data->service_uuid.data_len,
1695 (char*)filter_data->service_uuid_mask.data.data,
1696 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1700 if (is_matched == FALSE)
1703 if (filter_data->added_features &
1704 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1707 if (__bt_check_scan_result_uuid(adv_data,
1709 (char*)filter_data->service_solicitation_uuid.data.data,
1710 filter_data->service_solicitation_uuid.data_len,
1711 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1712 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1715 if (__bt_check_scan_result_uuid(adv_data,
1717 (char*)filter_data->service_solicitation_uuid.data.data,
1718 filter_data->service_solicitation_uuid.data_len,
1719 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1720 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1723 if (__bt_check_scan_result_uuid(scan_data,
1725 (char*)filter_data->service_solicitation_uuid.data.data,
1726 filter_data->service_solicitation_uuid.data_len,
1727 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1728 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1731 if (__bt_check_scan_result_uuid(scan_data,
1733 (char*)filter_data->service_solicitation_uuid.data.data,
1734 filter_data->service_solicitation_uuid.data_len,
1735 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1736 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1740 if (is_matched == FALSE)
1743 if (filter_data->added_features &
1744 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1745 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1750 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1751 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1754 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1755 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1756 memcpy(name, data, data_len);
1757 name[data_len] = '\0';
1760 if (strncmp(filter_data->device_name,
1761 name, data_len) == 0)
1764 __bt_get_ad_data_by_type((char*)scan_data,
1766 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1769 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1770 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1771 memcpy(name, data, data_len);
1772 name[data_len] = '\0';
1775 if (strncmp(filter_data->device_name,
1776 name, data_len) == 0)
1780 if (is_matched == FALSE)
1783 if (filter_data->added_features &
1784 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1789 __bt_get_ad_data_by_type((char*)adv_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) {
1815 __bt_get_ad_data_by_type((char*)scan_data,
1817 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1821 int manufacturer_id;
1822 manufacturer_id = (data[1] << 8) + data[0];
1824 if (filter_data->manufacturer_id == manufacturer_id) {
1825 if (filter_data->manufacturer_data.data_len == 0) {
1828 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1829 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1830 if (_bt_byte_arr_cmp_with_mask(data + 2,
1831 (char*)filter_data->manufacturer_data.data.data,
1832 (char*)filter_data->manufacturer_data_mask.data.data,
1833 data_len - 2) == 0) {
1842 if (is_matched == FALSE)
1845 if (filter_data->added_features &
1846 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1851 __bt_get_ad_data_by_type((char*)adv_data,
1853 BT_LE_AD_TYPE_SERVICE_DATA,
1856 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1857 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1858 if (_bt_byte_arr_cmp_with_mask(data,
1859 (char*)filter_data->service_data.data.data,
1860 (char*)filter_data->service_data_mask.data.data,
1867 __bt_get_ad_data_by_type((char*)scan_data,
1869 BT_LE_AD_TYPE_SERVICE_DATA,
1872 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1873 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1874 if (_bt_byte_arr_cmp_with_mask(data,
1875 (char*)filter_data->service_data.data.data,
1876 (char*)filter_data->service_data_mask.data.data,
1884 if (is_matched == FALSE)
1888 BT_INFO("The scan result is conformable.");
1892 BT_INFO("The scan result is NOT conformable.");
1896 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1897 const bt_le_adv_info_t *adv_info)
1899 int result = BLUETOOTH_ERROR_NONE;
1901 GVariant *scan_data_param, *adv_data_param;
1903 bt_adapter_le_scanner_t *scanner = NULL;
1904 const char *adv_data = NULL;
1905 int adv_data_len = 0;
1906 const char *scan_data = NULL;
1907 int scan_data_len = 0;
1909 ret_if(le_dev_info == NULL);
1910 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1911 ret_if(adv_info == NULL);
1913 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1914 adv_data = le_dev_info->adv_data;
1915 adv_data_len = le_dev_info->adv_data_len;
1916 scan_data = le_dev_info->adv_data;
1919 adv_data = adv_info->data;
1920 adv_data_len = adv_info->data_len;
1921 scan_data = le_dev_info->adv_data;
1922 scan_data_len = le_dev_info->adv_data_len;
1925 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1927 if (scanner->is_scanning == FALSE)
1930 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1931 adv_data, adv_data_len, scan_data, scan_data_len,
1935 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1936 adv_data, adv_data_len, TRUE, NULL, NULL);
1937 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1938 scan_data, scan_data_len, TRUE, NULL, NULL);
1940 param = g_variant_new("(isnnn@ayn@ay)",
1942 le_dev_info->address,
1943 le_dev_info->addr_type,
1951 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1952 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1954 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1959 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1962 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1963 GError *error = NULL;
1966 if (__bt_is_factory_test_mode()) {
1967 BT_ERR("Unable to add white list in factory binary !!");
1968 return BLUETOOTH_ERROR_NOT_SUPPORT;
1971 BT_CHECK_PARAMETER(device_address, return);
1973 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1974 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1975 return BLUETOOTH_ERROR_INVALID_PARAM;
1977 _bt_convert_addr_type_to_string(address, device_address->addr);
1979 proxy = _bt_get_adapter_proxy();
1980 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1982 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1983 g_variant_new("(su)", address, address_type),
1984 G_DBUS_CALL_FLAGS_NONE, -1,
1988 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
1989 g_clear_error(&error);
1990 return BLUETOOTH_ERROR_INTERNAL;
1994 g_variant_unref(ret);
1995 BT_INFO("Add white list");
1997 return BLUETOOTH_ERROR_NONE;
2000 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2003 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2004 GError *error = NULL;
2007 if (__bt_is_factory_test_mode()) {
2008 BT_ERR("Unable to remove white list in factory binary !!");
2009 return BLUETOOTH_ERROR_NOT_SUPPORT;
2012 BT_CHECK_PARAMETER(device_address, return);
2014 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2015 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2016 return BLUETOOTH_ERROR_INVALID_PARAM;
2018 _bt_convert_addr_type_to_string(address, device_address->addr);
2020 proxy = _bt_get_adapter_proxy();
2021 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2023 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
2024 g_variant_new("(su)", address, address_type),
2025 G_DBUS_CALL_FLAGS_NONE, -1,
2029 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2030 g_clear_error(&error);
2031 return BLUETOOTH_ERROR_INTERNAL;
2035 g_variant_unref(ret);
2036 BT_INFO("Remove white list");
2038 return BLUETOOTH_ERROR_NONE;
2041 int _bt_clear_white_list(void)
2044 GError *error = NULL;
2047 if (__bt_is_factory_test_mode()) {
2048 BT_ERR("Unable to clear white list in factory binary !!");
2049 return BLUETOOTH_ERROR_NOT_SUPPORT;
2052 proxy = _bt_get_adapter_proxy();
2053 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2055 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2056 NULL, G_DBUS_CALL_FLAGS_NONE,
2060 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2061 g_clear_error(&error);
2062 return BLUETOOTH_ERROR_INTERNAL;
2065 g_variant_unref(ret);
2067 BT_INFO("Clear white list");
2069 return BLUETOOTH_ERROR_NONE;
2072 int _bt_initialize_ipsp(void)
2076 GError *error = NULL;
2079 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2080 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2081 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2084 proxy = _bt_get_adapter_proxy();
2085 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2087 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2088 NULL, G_DBUS_CALL_FLAGS_NONE,
2091 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2092 g_clear_error(&error);
2093 return BLUETOOTH_ERROR_INTERNAL;
2096 g_variant_unref(ret);
2098 BT_INFO("IPSP initialization called successfully");
2100 return BLUETOOTH_ERROR_NONE;
2103 int _bt_deinitialize_ipsp(void)
2107 GError *error = NULL;
2110 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2111 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2112 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2115 proxy = _bt_get_adapter_proxy();
2116 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2118 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2119 NULL, G_DBUS_CALL_FLAGS_NONE,
2122 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2123 g_clear_error(&error);
2124 return BLUETOOTH_ERROR_INTERNAL;
2127 g_variant_unref(ret);
2129 BT_INFO("IPSP De-initialization called successfully");
2131 return BLUETOOTH_ERROR_NONE;
2134 int _bt_le_read_maximum_data_length(
2135 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2137 GError *error = NULL;
2139 GVariant *reply = NULL;
2140 guint16 max_tx_octets, max_tx_time;
2141 guint16 max_rx_octets, max_rx_time;
2143 proxy = _bt_get_adapter_proxy();
2144 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2146 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2147 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2149 g_object_unref(proxy);
2151 if (reply == NULL) {
2152 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2153 if (error != NULL) {
2154 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2155 error->code, error->message);
2156 g_clear_error(&error);
2158 return BLUETOOTH_ERROR_INTERNAL;
2161 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2162 &max_rx_octets, &max_rx_time);
2164 max_le_datalength->max_tx_octets = max_tx_octets;
2165 max_le_datalength->max_tx_time = max_tx_time;
2166 max_le_datalength->max_rx_octets = max_rx_octets;
2167 max_le_datalength->max_rx_time = max_rx_time;
2169 g_variant_unref(reply);
2171 return BLUETOOTH_ERROR_NONE;
2173 int _bt_le_write_host_suggested_default_data_length(
2174 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2176 GError *error = NULL;
2178 GVariant *reply = NULL;
2180 proxy = _bt_get_adapter_proxy();
2181 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2183 reply = g_dbus_proxy_call_sync(proxy,
2184 "LEWriteHostSuggestedDataLength",
2185 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2186 G_DBUS_CALL_FLAGS_NONE,
2191 g_object_unref(proxy);
2193 if (reply == NULL) {
2194 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2195 if (error != NULL) {
2196 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2197 error->code, error->message);
2198 g_clear_error(&error);
2200 return BLUETOOTH_ERROR_INTERNAL;
2203 g_variant_unref(reply);
2205 return BLUETOOTH_ERROR_NONE;
2208 int _bt_le_read_host_suggested_default_data_length(
2209 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2211 GError *error = NULL;
2213 GVariant *reply = NULL;
2214 guint16 def_tx_octets, def_tx_time;
2216 proxy = _bt_get_adapter_proxy();
2217 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2219 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2220 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2222 if (reply == NULL) {
2223 BT_ERR("LEReadHostSuggestedDataLength 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, "(qq)", &def_tx_octets, &def_tx_time);
2234 def_data_length->def_tx_octets = def_tx_octets;
2235 def_data_length->def_tx_time = def_tx_time;
2237 g_variant_unref(reply);
2239 return BLUETOOTH_ERROR_NONE;
2242 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2243 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2245 GError *error = NULL;
2246 guint16 txOctets = max_tx_Octets;
2247 guint16 txTime = max_tx_Time;
2248 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2249 gchar *device_path = NULL;
2250 GDBusConnection *conn;
2251 GDBusProxy *device_proxy;
2253 _bt_convert_addr_type_to_string(address, device_address->addr);
2255 device_path = _bt_get_device_object_path(address);
2257 if (device_path == NULL) {
2258 BT_DBG("Device path is null");
2259 return BLUETOOTH_ERROR_INTERNAL;
2262 conn = _bt_get_system_gconn();
2264 BT_ERR("conn == NULL");
2265 g_free(device_path);
2266 return BLUETOOTH_ERROR_INTERNAL;
2269 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2270 NULL, BT_BLUEZ_NAME,
2271 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2273 g_free(device_path);
2274 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2276 g_dbus_proxy_call_sync(device_proxy,
2278 g_variant_new("(qq)", txOctets, txTime),
2279 G_DBUS_CALL_FLAGS_NONE,
2284 g_object_unref(device_proxy);
2287 BT_ERR("LESetDataLength error: [%s]", error->message);
2288 g_error_free(error);
2289 return BLUETOOTH_ERROR_INTERNAL;
2292 return BLUETOOTH_ERROR_NONE;