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_C("### 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);
578 BT_INFO("It's NOT advertising");
579 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
582 return BLUETOOTH_ERROR_NONE;
585 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
586 char in_type, char **data, int *data_len)
588 if (in_data == NULL || data == NULL || data_len == NULL)
589 return BLUETOOTH_ERROR_INTERNAL;
592 return BLUETOOTH_ERROR_INTERNAL;
598 for (i = 0; i < in_len; i++) {
600 if (len <= 0 || i + 1 >= in_len) {
601 BT_ERR("Invalid advertising data");
602 return BLUETOOTH_ERROR_INTERNAL;
605 type = in_data[i + 1];
606 if (type == in_type) {
616 if (i + len > in_len) {
617 BT_ERR("Invalid advertising data");
618 return BLUETOOTH_ERROR_INTERNAL;
619 } else if (len == 0) {
620 BT_DBG("AD Type 0x%02x data is not set", in_type);
623 return BLUETOOTH_ERROR_NONE;
626 *data = g_memdup(&in_data[i], len);
628 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
631 return BLUETOOTH_ERROR_NONE;
634 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
636 BT_CHECK_PARAMETER(adv, return);
637 BT_CHECK_PARAMETER(length, return);
639 memcpy(adv, &adv_data, sizeof(adv_data));
640 *length = adv_data_len;
642 return BLUETOOTH_ERROR_NONE;
645 int _bt_set_advertising_data(const char *sender, int adv_handle,
646 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
649 GError *error = NULL;
650 GVariant *ret, *ad_data, *param = NULL;
651 GVariant *temp = NULL;
652 GVariantBuilder *builder;
654 char *old_mdata = NULL;
655 char *new_mdata = NULL;
660 if (__bt_is_factory_test_mode()) {
661 BT_ERR("Unable to set advertising data in factory binary !!");
662 return BLUETOOTH_ERROR_NOT_SUPPORT;
665 BT_CHECK_PARAMETER(adv, return);
667 if (_bt_adapter_get_status() != BT_ACTIVATED &&
668 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
669 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
672 proxy = _bt_get_adapter_proxy();
673 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
675 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
677 BT_ERR("There is NO available slot!!");
678 return BLUETOOTH_ERROR_NO_RESOURCES;
681 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
682 for (i = 0; i < length; i++)
683 g_variant_builder_add(builder, "y", adv->data[i]);
685 temp = g_variant_new("ay", builder);
686 g_variant_builder_unref(builder);
687 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
688 g_variant_new("(@ayi)", temp, slot_id),
689 G_DBUS_CALL_FLAGS_NONE,
693 BT_ERR("SetAdvertisingData Fail: %s", error->message);
694 g_clear_error(&error);
695 return BLUETOOTH_ERROR_INTERNAL;
698 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
700 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
701 &old_mdata, &old_len);
702 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
703 &new_mdata, &new_len);
704 if (old_len != new_len ||
705 (old_mdata && new_mdata &&
706 memcmp(old_mdata, new_mdata, new_len))) {
707 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
708 new_mdata, new_len, TRUE, NULL, NULL);
709 param = g_variant_new("(@ay)", ad_data);
710 _bt_send_event(BT_ADAPTER_EVENT,
711 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
717 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
718 memcpy(&adv_data, adv, length);
719 adv_data_len = length;
721 BT_INFO("Set advertising data");
723 g_variant_unref(ret);
725 return BLUETOOTH_ERROR_NONE;
728 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
730 BT_CHECK_PARAMETER(response, return);
731 BT_CHECK_PARAMETER(length, return);
733 memcpy(response, &resp_data, sizeof(resp_data));
734 *length = resp_data_len;
736 return BLUETOOTH_ERROR_NONE;
739 int _bt_set_scan_response_data(const char *sender, int adv_handle,
740 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
743 GError *error = NULL;
744 GVariant *ret, *scan_data, *param = NULL;
745 GVariant *temp = NULL;
746 GVariantBuilder *builder;
748 char *old_mdata = NULL;
749 char *new_mdata = NULL;
754 if (__bt_is_factory_test_mode()) {
755 BT_ERR("Unable to set scan response list in factory binary !!");
756 return BLUETOOTH_ERROR_NOT_SUPPORT;
759 BT_CHECK_PARAMETER(response, return);
761 if (_bt_adapter_get_status() != BT_ACTIVATED &&
762 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
763 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
766 proxy = _bt_get_adapter_proxy();
767 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
769 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
771 BT_ERR("There is NO available slot!!");
772 return BLUETOOTH_ERROR_NO_RESOURCES;
774 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
775 for (i = 0; i < length; i++)
776 g_variant_builder_add(builder, "y", response->data[i]);
778 temp = g_variant_new("ay", builder);
779 g_variant_builder_unref(builder);
780 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
781 g_variant_new("(@ayi)", temp, slot_id),
782 G_DBUS_CALL_FLAGS_NONE,
786 BT_ERR("SetScanRespData Fail: %s", error->message);
787 g_clear_error(&error);
788 return BLUETOOTH_ERROR_INTERNAL;
791 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
793 /* Compare with previous scan resp data */
794 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
795 &old_mdata, &old_len);
796 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
797 &new_mdata, &new_len);
798 if (old_len != new_len ||
799 (old_mdata && new_mdata &&
800 memcmp(old_mdata, new_mdata, new_len))) {
801 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
802 new_mdata, new_len, TRUE, NULL, NULL);
803 param = g_variant_new("(@ay)", scan_data);
804 _bt_send_event(BT_ADAPTER_EVENT,
805 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
811 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
812 memcpy(&resp_data, response, length);
813 resp_data_len = length;
816 g_variant_unref(ret);
817 BT_INFO("Set scan response data");
818 return BLUETOOTH_ERROR_NONE;
821 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
824 GError *error = NULL;
829 BT_CHECK_PARAMETER(params, return);
831 if (_bt_adapter_get_status() != BT_ACTIVATED &&
832 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
833 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
836 proxy = _bt_get_adapter_proxy();
837 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
839 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
840 return BLUETOOTH_ERROR_INVALID_PARAM;
842 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
843 return BLUETOOTH_ERROR_INVALID_PARAM;
845 if (params->window > params->interval)
846 return BLUETOOTH_ERROR_INVALID_PARAM;
848 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
849 win = params->window / BT_ADV_INTERVAL_SPLIT;
851 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
852 g_variant_new("(uuu)", params->type, itv, win),
853 G_DBUS_CALL_FLAGS_NONE, -1,
857 BT_ERR("SetScanParameters Fail: %s", error->message);
858 g_clear_error(&error);
859 return BLUETOOTH_ERROR_INTERNAL;
862 _bt_set_le_scan_type(params->type);
864 is_le_set_scan_parameter = TRUE;
867 g_variant_unref(ret);
868 BT_INFO("Set scan parameters");
869 return BLUETOOTH_ERROR_NONE;
872 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
875 bt_adapter_le_scanner_t *scanner;
877 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
879 if (g_strcmp0(scanner->sender, sender) == 0)
886 int __bt_get_available_scan_filter_slot_id(void)
889 bt_adapter_le_scanner_t *scanner;
891 bluetooth_le_scan_filter_t *filter_data;
892 gboolean *slot_check_list = NULL;
895 if (le_feature_info.max_filter == 0) {
896 BT_ERR("Scan filter is NOT Supported");
899 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
900 if (slot_check_list == NULL) {
901 BT_ERR("Fail to allocate memory");
905 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
907 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
908 filter_data = fl->data;
909 if (filter_data->slot_id < le_feature_info.max_filter)
910 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)
934 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
937 GError *error = NULL;
938 GVariant *ret, *param;
939 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
940 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
941 GArray *arr_uuid = NULL;
942 GArray *arr_uuid_mask = NULL;
943 GArray *arr_data = NULL;
944 GArray *arr_data_mask = NULL;
945 bt_adapter_le_scanner_t *scanner = NULL;
946 bluetooth_le_scan_filter_t *filter_data = NULL;
947 int feature_selection = 0;
949 *slot_id = __bt_get_available_scan_filter_slot_id();
951 return BLUETOOTH_ERROR_NO_RESOURCES;
953 proxy = _bt_get_adapter_proxy();
954 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
956 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
957 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
958 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
960 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
962 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
963 NULL, 0, TRUE, NULL, NULL);
964 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
965 NULL, 0, TRUE, NULL, NULL);
966 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
967 NULL, 0, TRUE, NULL, NULL);
968 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
969 NULL, 0, TRUE, NULL, NULL);
971 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
973 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
974 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
975 *slot_id, // filter_index
977 0, // company_id_mask
978 arr_uuid_param, // p_uuid
979 arr_uuid_mask_param, // p_uuid_mask
982 arr_data_param, // p_data
983 arr_data_mask_param); // p_mask
985 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
986 param, G_DBUS_CALL_FLAGS_NONE,
990 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
991 g_clear_error(&error);
994 g_variant_unref(ret);
997 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
998 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
1000 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1001 NULL, 0, TRUE, NULL, NULL);
1002 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1003 NULL, 0, TRUE, NULL, NULL);
1004 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1005 NULL, 0, TRUE, NULL, NULL);
1006 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1007 NULL, 0, TRUE, NULL, NULL);
1009 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1011 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1012 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1013 *slot_id, // filter_index
1015 0, // company_id_mask
1016 arr_uuid_param, // p_uuid
1017 arr_uuid_mask_param, // p_uuid_mask
1018 filter->device_name, // string
1020 arr_data_param, // p_data
1021 arr_data_mask_param);
1023 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1024 param, G_DBUS_CALL_FLAGS_NONE,
1028 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1029 g_clear_error(&error);
1032 g_variant_unref(ret);
1035 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1036 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1038 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1039 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1041 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1042 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1044 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1045 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1046 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1047 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1048 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1049 NULL, 0, TRUE, NULL, NULL);
1050 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1051 NULL, 0, TRUE, NULL, NULL);
1053 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1055 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1056 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1057 *slot_id, // filter_index
1059 0, // company_id_mask
1060 arr_uuid_param, // p_uuid
1061 arr_uuid_mask_param, // p_uuid_mask
1064 arr_data_param, // p_data
1065 arr_data_mask_param);
1067 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1068 param, G_DBUS_CALL_FLAGS_NONE,
1072 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1073 g_clear_error(&error);
1076 g_variant_unref(ret);
1078 g_array_free(arr_uuid, TRUE);
1079 g_array_free(arr_uuid_mask, TRUE);
1082 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1083 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1085 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1086 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1088 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1089 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1091 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1092 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1093 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1094 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1095 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1096 NULL, 0, TRUE, NULL, NULL);
1097 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1098 NULL, 0, TRUE, NULL, NULL);
1100 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1102 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1103 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1104 *slot_id, // filter_index
1106 0, // company_id_mask
1107 arr_uuid_param, // p_uuid
1108 arr_uuid_mask_param, // p_uuid_mask
1111 arr_data_param, // p_data
1112 arr_data_mask_param);
1114 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1115 G_DBUS_CALL_FLAGS_NONE,
1119 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1120 g_clear_error(&error);
1123 g_variant_unref(ret);
1125 g_array_free(arr_uuid, TRUE);
1126 g_array_free(arr_uuid_mask, TRUE);
1129 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1130 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1132 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1133 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1135 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1136 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1138 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1139 NULL, 0, TRUE, NULL, NULL);
1140 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1141 NULL, 0, TRUE, NULL, NULL);
1142 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1143 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1144 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1145 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1147 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1149 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1150 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1151 *slot_id, // filter_index
1153 0, // company_id_mask
1154 arr_uuid_param, // p_uuid
1155 arr_uuid_mask_param, // p_uuid_mask
1158 arr_data_param, // p_data
1159 arr_data_mask_param);
1161 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1162 G_DBUS_CALL_FLAGS_NONE,
1166 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1167 g_clear_error(&error);
1170 g_variant_unref(ret);
1172 g_array_free(arr_data, TRUE);
1173 g_array_free(arr_data_mask, TRUE);
1176 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1177 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1179 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1180 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1182 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1183 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1185 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1186 NULL, 0, TRUE, NULL, NULL);
1187 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1188 NULL, 0, TRUE, NULL, NULL);
1189 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1190 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1191 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1192 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1194 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1196 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1197 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1198 *slot_id, // filter_index
1199 filter->manufacturer_id, // company_id
1200 0xFFFF, // company_id_mask
1201 arr_uuid_param, // p_uuid
1202 arr_uuid_mask_param, // p_uuid_mask
1205 arr_data_param, // p_data
1206 arr_data_mask_param);
1208 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1209 G_DBUS_CALL_FLAGS_NONE,
1213 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1214 g_clear_error(&error);
1217 g_variant_unref(ret);
1219 g_array_free(arr_data, TRUE);
1220 g_array_free(arr_data_mask, TRUE);
1223 BT_DBG("Filter selection %.2x", feature_selection);
1225 param = g_variant_new("(iiiiiiiiiiii)",
1227 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1228 *slot_id, // filter_index
1229 feature_selection, // feat_seln
1230 0, // list_logic_type (OR - 0x00, AND - 0x01)
1231 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1232 -127, // rssi_high_thres
1233 -127, // rssi_low_thres
1234 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1237 0); // found_timeout_cnt
1238 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1239 param, G_DBUS_CALL_FLAGS_NONE,
1243 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1244 g_clear_error(&error);
1247 scanner = __bt_find_scanner_from_list(sender);
1248 if (scanner == NULL) {
1249 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1251 scanner->sender = strdup(sender);
1252 scanner_list = g_slist_append(scanner_list, scanner);
1256 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1258 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1259 filter_data->slot_id = *slot_id;
1262 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1266 g_variant_unref(ret);
1267 return BLUETOOTH_ERROR_NONE;
1270 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1273 GError *error = NULL;
1275 bt_adapter_le_scanner_t *scanner = NULL;
1276 bluetooth_le_scan_filter_t *filter_data = NULL;
1278 gboolean is_slot_id_found = FALSE;
1280 scanner = __bt_find_scanner_from_list(sender);
1281 if (scanner == NULL) {
1282 BT_ERR("There is NO available scanner.");
1283 return BLUETOOTH_ERROR_NOT_FOUND;
1286 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1287 filter_data = l->data;
1288 if (filter_data->slot_id == slot_id) {
1289 is_slot_id_found = TRUE;
1293 if (is_slot_id_found == FALSE) {
1294 BT_ERR("There is NO registered slot.");
1295 return BLUETOOTH_ERROR_NOT_FOUND;
1298 proxy = _bt_get_adapter_proxy();
1299 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1301 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1302 g_variant_new("(ii)", 0, slot_id),
1303 G_DBUS_CALL_FLAGS_NONE,
1307 BT_ERR("scan_filter_clear Fail: %s", error->message);
1308 g_clear_error(&error);
1311 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1312 g_free(filter_data);
1315 g_variant_unref(ret);
1316 return BLUETOOTH_ERROR_NONE;
1319 int _bt_unregister_all_scan_filters(const char *sender)
1322 GError *error = NULL;
1324 bt_adapter_le_scanner_t *scanner = NULL;
1325 bluetooth_le_scan_filter_t *filter_data = NULL;
1328 scanner = __bt_find_scanner_from_list(sender);
1329 if (scanner == NULL) {
1330 BT_ERR("There is NO available scanner.");
1331 return BLUETOOTH_ERROR_NOT_FOUND;
1334 proxy = _bt_get_adapter_proxy();
1335 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1337 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1338 filter_data = l->data;
1340 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1341 g_variant_new("(ii)", 0, filter_data->slot_id),
1342 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1345 BT_ERR("scan_filter_clear Fail: %s", error->message);
1346 g_clear_error(&error);
1349 g_variant_unref(ret);
1352 g_slist_free_full(scanner->filter_list, g_free);
1353 scanner->filter_list = NULL;
1355 return BLUETOOTH_ERROR_NONE;
1358 int _bt_start_le_scan(const char *sender)
1361 GError *error = NULL;
1363 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1365 if (scanner == NULL) {
1366 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1367 retv_if(scanner == NULL, BLUETOOTH_ERROR_INTERNAL);
1369 scanner->sender = strdup(sender);
1370 scanner_list = g_slist_append(scanner_list, scanner);
1373 if (scanner->is_scanning == TRUE) {
1374 BT_ERR("BT is already in LE scanning");
1375 return BLUETOOTH_ERROR_IN_PROGRESS;
1377 scanner->is_scanning = TRUE;
1379 proxy = _bt_get_adapter_proxy();
1380 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1382 if (_bt_is_le_scanning()) {
1383 if (scan_filter_enabled == TRUE) {
1384 if (scanner->filter_list == NULL) {
1385 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1386 g_variant_new("(ib)", 0, FALSE),
1387 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1390 BT_ERR("scan_filter_clear Fail: %s", error->message);
1391 g_clear_error(&error);
1395 g_variant_unref(ret);
1396 BT_INFO("Disable LE Scan Filter");
1397 scan_filter_enabled = FALSE;
1399 BT_INFO("LE Filter Scan is continue");
1402 BT_INFO("LE Full Scan is already on progress");
1404 return BLUETOOTH_ERROR_NONE;
1406 if (is_le_set_scan_parameter == FALSE) {
1407 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1408 bluetooth_le_scan_params_t scan_params;
1409 scan_params.type = BT_LE_ACTIVE_SCAN;
1410 scan_params.interval = 5000;
1411 scan_params.window = 500;
1412 _bt_set_scan_parameters(&scan_params);
1415 if (scanner->filter_list == NULL) {
1416 BT_INFO("Start LE Full Scan");
1417 scan_filter_enabled = FALSE;
1419 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1420 g_variant_new("(ib)", 0, TRUE),
1421 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1424 BT_ERR("scan_filter_clear Fail: %s", error->message);
1425 g_clear_error(&error);
1429 g_variant_unref(ret);
1430 BT_INFO("Enable LE Scan Filter");
1431 scan_filter_enabled = TRUE;
1435 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1436 NULL, G_DBUS_CALL_FLAGS_NONE,
1440 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1441 g_clear_error(&error);
1442 return BLUETOOTH_ERROR_INTERNAL;
1446 g_variant_unref(ret);
1447 return BLUETOOTH_ERROR_NONE;
1450 int _bt_stop_le_scan(const char *sender)
1453 GError *error = NULL;
1455 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1457 gboolean next_scanning = FALSE;
1458 gboolean need_scan_filter = TRUE;
1460 if (scanner == NULL || scanner->is_scanning == FALSE)
1461 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1463 scanner->is_scanning = FALSE;
1465 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1467 if (scanner->is_scanning == TRUE) {
1468 next_scanning = TRUE;
1469 if (scanner->filter_list == NULL)
1470 need_scan_filter = FALSE;
1474 proxy = _bt_get_adapter_proxy();
1475 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1477 if (next_scanning == TRUE) {
1478 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1479 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1480 g_variant_new("(ib)", 0, TRUE),
1481 G_DBUS_CALL_FLAGS_NONE,
1485 BT_ERR("scan_filter_clear Fail: %s", error->message);
1486 g_clear_error(&error);
1490 g_variant_unref(ret);
1491 BT_INFO("Enable LE Scan Filter");
1492 scan_filter_enabled = TRUE;
1494 return BLUETOOTH_ERROR_NONE;
1496 if (scan_filter_enabled == TRUE) {
1497 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1498 g_variant_new("(ib)", 0, FALSE),
1499 G_DBUS_CALL_FLAGS_NONE,
1503 BT_ERR("scan_filter_clear Fail: %s", error->message);
1504 g_clear_error(&error);
1508 g_variant_unref(ret);
1509 BT_INFO("Disable LE Scan Filter");
1511 BT_INFO("Just stop LE scan");
1515 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1516 NULL, G_DBUS_CALL_FLAGS_NONE,
1519 BT_ERR("LE Scan stop failed");
1520 return BLUETOOTH_ERROR_INTERNAL;
1523 scan_filter_enabled = FALSE;
1524 is_le_set_scan_parameter = FALSE;
1526 g_variant_unref(ret);
1527 return BLUETOOTH_ERROR_NONE;
1530 void _bt_disable_all_scanner_status(void)
1533 bt_adapter_le_scanner_t *scanner;
1535 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1537 scanner->is_scanning = FALSE;
1541 void _bt_set_le_scan_status(gboolean mode)
1543 is_le_scanning = mode;
1546 gboolean _bt_is_le_scanning(void)
1548 return is_le_scanning;
1551 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1553 le_scan_type = type;
1556 bt_le_scan_type_t _bt_get_le_scan_type(void)
1558 return le_scan_type;
1561 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1562 int adv_data_len, const char *svc_uuid, int uuid_len,
1563 const char *uuid_mask, char ad_type)
1569 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1570 ad_type, &data, &data_len);
1572 for (i = 0; i < data_len; i += uuid_len) {
1573 if (uuid_len > (data_len - i))
1576 if (_bt_byte_arr_cmp_with_mask(data + i,
1577 svc_uuid, uuid_mask, uuid_len) == 0) {
1588 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1589 const char *adv_data, int adv_data_len,
1590 const char *scan_data, int scan_data_len,
1591 const bt_adapter_le_scanner_t *scanner)
1594 bluetooth_le_scan_filter_t *filter_data = NULL;
1597 gboolean is_matched = FALSE;
1599 if (scanner->filter_list == NULL) {
1600 BT_INFO("This scanner is on Full Scan.");
1604 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1605 filter_data = l->data;
1607 if (filter_data->added_features &
1608 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1609 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1611 _bt_convert_addr_type_to_string(address,
1612 filter_data->device_address.addr);
1613 if (strncmp(address, device_address,
1614 BT_ADDRESS_STRING_SIZE) != 0)
1618 if (filter_data->added_features &
1619 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1622 if (__bt_check_scan_result_uuid(adv_data,
1624 (char*)filter_data->service_uuid.data.data,
1625 filter_data->service_uuid.data_len,
1626 (char*)filter_data->service_uuid_mask.data.data,
1627 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1630 if (__bt_check_scan_result_uuid(adv_data,
1632 (char*)filter_data->service_uuid.data.data,
1633 filter_data->service_uuid.data_len,
1634 (char*)filter_data->service_uuid_mask.data.data,
1635 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1638 if (__bt_check_scan_result_uuid(adv_data,
1640 (char*)filter_data->service_uuid.data.data,
1641 filter_data->service_uuid.data_len,
1642 (char*)filter_data->service_uuid_mask.data.data,
1643 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1646 if (__bt_check_scan_result_uuid(adv_data,
1648 (char*)filter_data->service_uuid.data.data,
1649 filter_data->service_uuid.data_len,
1650 (char*)filter_data->service_uuid_mask.data.data,
1651 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1654 if (__bt_check_scan_result_uuid(scan_data,
1656 (char*)filter_data->service_uuid.data.data,
1657 filter_data->service_uuid.data_len,
1658 (char*)filter_data->service_uuid_mask.data.data,
1659 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1662 if (__bt_check_scan_result_uuid(scan_data,
1664 (char*)filter_data->service_uuid.data.data,
1665 filter_data->service_uuid.data_len,
1666 (char*)filter_data->service_uuid_mask.data.data,
1667 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1670 if (__bt_check_scan_result_uuid(scan_data,
1672 (char*)filter_data->service_uuid.data.data,
1673 filter_data->service_uuid.data_len,
1674 (char*)filter_data->service_uuid_mask.data.data,
1675 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1678 if (__bt_check_scan_result_uuid(scan_data,
1680 (char*)filter_data->service_uuid.data.data,
1681 filter_data->service_uuid.data_len,
1682 (char*)filter_data->service_uuid_mask.data.data,
1683 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1687 if (is_matched == FALSE)
1690 if (filter_data->added_features &
1691 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1694 if (__bt_check_scan_result_uuid(adv_data,
1696 (char*)filter_data->service_solicitation_uuid.data.data,
1697 filter_data->service_solicitation_uuid.data_len,
1698 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1699 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1702 if (__bt_check_scan_result_uuid(adv_data,
1704 (char*)filter_data->service_solicitation_uuid.data.data,
1705 filter_data->service_solicitation_uuid.data_len,
1706 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1707 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1710 if (__bt_check_scan_result_uuid(scan_data,
1712 (char*)filter_data->service_solicitation_uuid.data.data,
1713 filter_data->service_solicitation_uuid.data_len,
1714 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1715 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1718 if (__bt_check_scan_result_uuid(scan_data,
1720 (char*)filter_data->service_solicitation_uuid.data.data,
1721 filter_data->service_solicitation_uuid.data_len,
1722 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1723 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1727 if (is_matched == FALSE)
1730 if (filter_data->added_features &
1731 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1732 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1737 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1738 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1741 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1742 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1743 memcpy(name, data, data_len);
1744 name[data_len] = '\0';
1747 if (strncmp(filter_data->device_name,
1748 name, data_len) == 0)
1751 __bt_get_ad_data_by_type((char*)scan_data,
1753 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1756 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1757 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1758 memcpy(name, data, data_len);
1759 name[data_len] = '\0';
1762 if (strncmp(filter_data->device_name,
1763 name, data_len) == 0)
1767 if (is_matched == FALSE)
1770 if (filter_data->added_features &
1771 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1776 __bt_get_ad_data_by_type((char*)adv_data,
1778 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1782 int manufacturer_id;
1783 manufacturer_id = (data[1] << 8) + data[0];
1785 if (filter_data->manufacturer_id == manufacturer_id) {
1786 if (filter_data->manufacturer_data.data_len == 0) {
1789 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1790 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1791 if (_bt_byte_arr_cmp_with_mask(data + 2,
1792 (char*)filter_data->manufacturer_data.data.data,
1793 (char*)filter_data->manufacturer_data_mask.data.data,
1794 data_len - 2) == 0) {
1802 __bt_get_ad_data_by_type((char*)scan_data,
1804 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1808 int manufacturer_id;
1809 manufacturer_id = (data[1] << 8) + data[0];
1811 if (filter_data->manufacturer_id == manufacturer_id) {
1812 if (filter_data->manufacturer_data.data_len == 0) {
1815 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1816 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1817 if (_bt_byte_arr_cmp_with_mask(data + 2,
1818 (char*)filter_data->manufacturer_data.data.data,
1819 (char*)filter_data->manufacturer_data_mask.data.data,
1820 data_len - 2) == 0) {
1829 if (is_matched == FALSE)
1832 if (filter_data->added_features &
1833 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1838 __bt_get_ad_data_by_type((char*)adv_data,
1840 BT_LE_AD_TYPE_SERVICE_DATA,
1843 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1844 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1845 if (_bt_byte_arr_cmp_with_mask(data,
1846 (char*)filter_data->service_data.data.data,
1847 (char*)filter_data->service_data_mask.data.data,
1854 __bt_get_ad_data_by_type((char*)scan_data,
1856 BT_LE_AD_TYPE_SERVICE_DATA,
1859 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1860 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1861 if (_bt_byte_arr_cmp_with_mask(data,
1862 (char*)filter_data->service_data.data.data,
1863 (char*)filter_data->service_data_mask.data.data,
1871 if (is_matched == FALSE)
1875 BT_INFO("The scan result is conformable.");
1879 BT_INFO("The scan result is NOT conformable.");
1883 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1884 const bt_le_adv_info_t *adv_info)
1886 int result = BLUETOOTH_ERROR_NONE;
1888 GVariant *scan_data_param, *adv_data_param;
1890 bt_adapter_le_scanner_t *scanner = NULL;
1891 const char *adv_data = NULL;
1892 int adv_data_len = 0;
1893 const char *scan_data = NULL;
1894 int scan_data_len = 0;
1896 ret_if(le_dev_info == NULL);
1897 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1898 ret_if(adv_info == NULL);
1900 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1901 adv_data = le_dev_info->adv_data;
1902 adv_data_len = le_dev_info->adv_data_len;
1903 scan_data = le_dev_info->adv_data;
1906 adv_data = adv_info->data;
1907 adv_data_len = adv_info->data_len;
1908 scan_data = le_dev_info->adv_data;
1909 scan_data_len = le_dev_info->adv_data_len;
1912 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1914 if (scanner->is_scanning == FALSE)
1917 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1918 adv_data, adv_data_len, scan_data, scan_data_len,
1922 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1923 adv_data, adv_data_len, TRUE, NULL, NULL);
1924 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1925 scan_data, scan_data_len, TRUE, NULL, NULL);
1927 param = g_variant_new("(isnnn@ayn@ay)",
1929 le_dev_info->address,
1930 le_dev_info->addr_type,
1938 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1939 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1941 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1946 void _bt_send_ibeacon_scan_result_event(const bt_remote_ibeacon_dev_info_t *ibeacon_dev_info)
1948 int result = BLUETOOTH_ERROR_NONE;
1951 bt_adapter_le_scanner_t *scanner = NULL;
1953 ret_if(ibeacon_dev_info == NULL);
1954 BT_DBG("_bt_send_ibeacon_scan_result_event");
1956 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1958 if (scanner->is_scanning == FALSE)
1961 param = g_variant_new("(isnnnsnnn)",
1963 ibeacon_dev_info->address,
1964 ibeacon_dev_info->addr_type,
1965 ibeacon_dev_info->company_id,
1966 ibeacon_dev_info->ibeacon_type,
1967 ibeacon_dev_info->uuid,
1968 ibeacon_dev_info->major_id,
1969 ibeacon_dev_info->minor_id,
1970 ibeacon_dev_info->measured_power);
1972 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_IBEACON_DEVICE_FOUND, param);
1976 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1979 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1980 GError *error = NULL;
1983 if (__bt_is_factory_test_mode()) {
1984 BT_ERR("Unable to add white list in factory binary !!");
1985 return BLUETOOTH_ERROR_NOT_SUPPORT;
1988 BT_CHECK_PARAMETER(device_address, return);
1990 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1991 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1992 return BLUETOOTH_ERROR_INVALID_PARAM;
1994 _bt_convert_addr_type_to_string(address, device_address->addr);
1996 proxy = _bt_get_adapter_proxy();
1997 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1999 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
2000 g_variant_new("(su)", address, address_type),
2001 G_DBUS_CALL_FLAGS_NONE, -1,
2005 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
2006 g_clear_error(&error);
2007 return BLUETOOTH_ERROR_INTERNAL;
2011 g_variant_unref(ret);
2012 BT_INFO("Add white list");
2014 return BLUETOOTH_ERROR_NONE;
2017 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2020 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2021 GError *error = NULL;
2024 if (__bt_is_factory_test_mode()) {
2025 BT_ERR("Unable to remove white list in factory binary !!");
2026 return BLUETOOTH_ERROR_NOT_SUPPORT;
2029 BT_CHECK_PARAMETER(device_address, return);
2031 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2032 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2033 return BLUETOOTH_ERROR_INVALID_PARAM;
2035 _bt_convert_addr_type_to_string(address, device_address->addr);
2037 proxy = _bt_get_adapter_proxy();
2038 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2040 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
2041 g_variant_new("(su)", address, address_type),
2042 G_DBUS_CALL_FLAGS_NONE, -1,
2046 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2047 g_clear_error(&error);
2048 return BLUETOOTH_ERROR_INTERNAL;
2052 g_variant_unref(ret);
2053 BT_INFO("Remove white list");
2055 return BLUETOOTH_ERROR_NONE;
2058 int _bt_clear_white_list(void)
2061 GError *error = NULL;
2064 if (__bt_is_factory_test_mode()) {
2065 BT_ERR("Unable to clear white list in factory binary !!");
2066 return BLUETOOTH_ERROR_NOT_SUPPORT;
2069 proxy = _bt_get_adapter_proxy();
2070 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2072 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2073 NULL, G_DBUS_CALL_FLAGS_NONE,
2077 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2078 g_clear_error(&error);
2079 return BLUETOOTH_ERROR_INTERNAL;
2082 g_variant_unref(ret);
2084 BT_INFO("Clear white list");
2086 return BLUETOOTH_ERROR_NONE;
2089 int _bt_initialize_ipsp(void)
2093 GError *error = NULL;
2096 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2097 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2098 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2101 proxy = _bt_get_adapter_proxy();
2102 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2104 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2105 NULL, G_DBUS_CALL_FLAGS_NONE,
2108 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2109 g_clear_error(&error);
2110 return BLUETOOTH_ERROR_INTERNAL;
2113 g_variant_unref(ret);
2115 BT_INFO("IPSP initialization called successfully");
2117 return BLUETOOTH_ERROR_NONE;
2120 int _bt_deinitialize_ipsp(void)
2124 GError *error = NULL;
2127 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2128 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2129 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2132 proxy = _bt_get_adapter_proxy();
2133 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2135 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2136 NULL, G_DBUS_CALL_FLAGS_NONE,
2139 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2140 g_clear_error(&error);
2141 return BLUETOOTH_ERROR_INTERNAL;
2144 g_variant_unref(ret);
2146 BT_INFO("IPSP De-initialization called successfully");
2148 return BLUETOOTH_ERROR_NONE;
2151 int _bt_le_read_maximum_data_length(
2152 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2154 GError *error = NULL;
2156 GVariant *reply = NULL;
2157 guint16 max_tx_octets, max_tx_time;
2158 guint16 max_rx_octets, max_rx_time;
2160 proxy = _bt_get_adapter_proxy();
2161 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2163 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2164 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2166 g_object_unref(proxy);
2168 if (reply == NULL) {
2169 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2170 if (error != NULL) {
2171 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2172 error->code, error->message);
2173 g_clear_error(&error);
2175 return BLUETOOTH_ERROR_INTERNAL;
2178 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2179 &max_rx_octets, &max_rx_time);
2181 max_le_datalength->max_tx_octets = max_tx_octets;
2182 max_le_datalength->max_tx_time = max_tx_time;
2183 max_le_datalength->max_rx_octets = max_rx_octets;
2184 max_le_datalength->max_rx_time = max_rx_time;
2186 g_variant_unref(reply);
2188 return BLUETOOTH_ERROR_NONE;
2190 int _bt_le_write_host_suggested_default_data_length(
2191 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2193 GError *error = NULL;
2195 GVariant *reply = NULL;
2197 proxy = _bt_get_adapter_proxy();
2198 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2200 reply = g_dbus_proxy_call_sync(proxy,
2201 "LEWriteHostSuggestedDataLength",
2202 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2203 G_DBUS_CALL_FLAGS_NONE,
2208 g_object_unref(proxy);
2210 if (reply == NULL) {
2211 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2212 if (error != NULL) {
2213 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2214 error->code, error->message);
2215 g_clear_error(&error);
2217 return BLUETOOTH_ERROR_INTERNAL;
2220 g_variant_unref(reply);
2222 return BLUETOOTH_ERROR_NONE;
2225 int _bt_le_read_host_suggested_default_data_length(
2226 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2228 GError *error = NULL;
2230 GVariant *reply = NULL;
2231 guint16 def_tx_octets, def_tx_time;
2233 proxy = _bt_get_adapter_proxy();
2234 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2236 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2237 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2239 if (reply == NULL) {
2240 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2241 if (error != NULL) {
2242 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2243 error->code, error->message);
2244 g_clear_error(&error);
2246 return BLUETOOTH_ERROR_INTERNAL;
2249 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2251 def_data_length->def_tx_octets = def_tx_octets;
2252 def_data_length->def_tx_time = def_tx_time;
2254 g_variant_unref(reply);
2256 return BLUETOOTH_ERROR_NONE;
2259 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2260 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2262 GError *error = NULL;
2263 guint16 txOctets = max_tx_Octets;
2264 guint16 txTime = max_tx_Time;
2265 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2266 gchar *device_path = NULL;
2267 GDBusConnection *conn;
2268 GDBusProxy *device_proxy;
2270 _bt_convert_addr_type_to_string(address, device_address->addr);
2272 device_path = _bt_get_device_object_path(address);
2274 if (device_path == NULL) {
2275 BT_DBG("Device path is null");
2276 return BLUETOOTH_ERROR_INTERNAL;
2279 conn = _bt_gdbus_get_system_gconn();
2281 BT_ERR("conn == NULL");
2282 g_free(device_path);
2283 return BLUETOOTH_ERROR_INTERNAL;
2286 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2287 NULL, BT_BLUEZ_NAME,
2288 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2290 g_free(device_path);
2291 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2293 g_dbus_proxy_call_sync(device_proxy,
2295 g_variant_new("(qq)", txOctets, txTime),
2296 G_DBUS_CALL_FLAGS_NONE,
2301 g_object_unref(device_proxy);
2304 BT_ERR("LESetDataLength error: [%s]", error->message);
2305 g_error_free(error);
2306 return BLUETOOTH_ERROR_INTERNAL;
2309 return BLUETOOTH_ERROR_NONE;