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_ERR("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]);
686 temp = g_variant_new("ay", builder);
687 g_variant_builder_unref(builder);
688 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
689 g_variant_new("(@ayi)", temp, slot_id),
690 G_DBUS_CALL_FLAGS_NONE,
694 BT_ERR("SetAdvertisingData Fail: %s", error->message);
695 g_clear_error(&error);
696 return BLUETOOTH_ERROR_INTERNAL;
699 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
701 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
702 &old_mdata, &old_len);
703 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
704 &new_mdata, &new_len);
705 if (old_len != new_len ||
706 (old_mdata && new_mdata &&
707 memcmp(old_mdata, new_mdata, new_len))) {
708 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
709 new_mdata, new_len, TRUE, NULL, NULL);
710 param = g_variant_new("(@ay)", ad_data);
711 _bt_send_event(BT_ADAPTER_EVENT,
712 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
718 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
719 memcpy(&adv_data, adv, length);
720 adv_data_len = length;
722 BT_INFO("Set advertising data");
724 g_variant_unref(ret);
726 return BLUETOOTH_ERROR_NONE;
729 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
731 BT_CHECK_PARAMETER(response, return);
732 BT_CHECK_PARAMETER(length, return);
734 memcpy(response, &resp_data, sizeof(resp_data));
735 *length = resp_data_len;
737 return BLUETOOTH_ERROR_NONE;
740 int _bt_set_scan_response_data(const char *sender, int adv_handle,
741 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
744 GError *error = NULL;
745 GVariant *ret, *scan_data, *param = NULL;
746 GVariant *temp = NULL;
747 GVariantBuilder *builder;
749 char *old_mdata = NULL;
750 char *new_mdata = NULL;
755 if (__bt_is_factory_test_mode()) {
756 BT_ERR("Unable to set scan response list in factory binary !!");
757 return BLUETOOTH_ERROR_NOT_SUPPORT;
760 BT_CHECK_PARAMETER(response, return);
762 if (_bt_adapter_get_status() != BT_ACTIVATED &&
763 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
764 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
767 proxy = _bt_get_adapter_proxy();
768 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
770 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
772 BT_ERR("There is NO available slot!!");
773 return BLUETOOTH_ERROR_NO_RESOURCES;
775 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
776 for (i = 0; i < length; i++) {
777 g_variant_builder_add(builder, "y", response->data[i]);
780 temp = g_variant_new("ay", builder);
781 g_variant_builder_unref(builder);
782 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
783 g_variant_new("(@ayi)", temp, slot_id),
784 G_DBUS_CALL_FLAGS_NONE,
788 BT_ERR("SetScanRespData Fail: %s", error->message);
789 g_clear_error(&error);
790 return BLUETOOTH_ERROR_INTERNAL;
793 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
795 /* Compare with previous scan resp data */
796 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
797 &old_mdata, &old_len);
798 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
799 &new_mdata, &new_len);
800 if (old_len != new_len ||
801 (old_mdata && new_mdata &&
802 memcmp(old_mdata, new_mdata, new_len))) {
803 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
804 new_mdata, new_len, TRUE, NULL, NULL);
805 param = g_variant_new("(@ay)", scan_data);
806 _bt_send_event(BT_ADAPTER_EVENT,
807 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
813 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
814 memcpy(&resp_data, response, length);
815 resp_data_len = length;
818 g_variant_unref(ret);
819 BT_INFO("Set scan response data");
820 return BLUETOOTH_ERROR_NONE;
823 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
826 GError *error = NULL;
831 BT_CHECK_PARAMETER(params, return);
833 if (_bt_adapter_get_status() != BT_ACTIVATED &&
834 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
835 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
838 proxy = _bt_get_adapter_proxy();
839 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
841 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
842 return BLUETOOTH_ERROR_INVALID_PARAM;
844 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
845 return BLUETOOTH_ERROR_INVALID_PARAM;
847 if (params->window > params->interval)
848 return BLUETOOTH_ERROR_INVALID_PARAM;
850 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
851 win = params->window / BT_ADV_INTERVAL_SPLIT;
853 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
854 g_variant_new("(uuu)", params->type, itv, win),
855 G_DBUS_CALL_FLAGS_NONE, -1,
859 BT_ERR("SetScanParameters Fail: %s", error->message);
860 g_clear_error(&error);
861 return BLUETOOTH_ERROR_INTERNAL;
864 _bt_set_le_scan_type(params->type);
866 is_le_set_scan_parameter = TRUE;
869 g_variant_unref(ret);
870 BT_INFO("Set scan parameters");
871 return BLUETOOTH_ERROR_NONE;
874 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
877 bt_adapter_le_scanner_t *scanner;
879 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
881 if (g_strcmp0(scanner->sender, sender) == 0)
888 int __bt_get_available_scan_filter_slot_id(void)
891 bt_adapter_le_scanner_t *scanner;
893 bluetooth_le_scan_filter_t *filter_data;
894 gboolean *slot_check_list = NULL;
897 if (le_feature_info.max_filter == 0) {
898 BT_ERR("Scan filter is NOT Supported");
901 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
902 if (slot_check_list == NULL) {
903 BT_ERR("Fail to allocate memory");
907 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
909 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
910 filter_data = fl->data;
911 if (filter_data->slot_id < le_feature_info.max_filter) {
912 slot_check_list[filter_data->slot_id] = TRUE;
917 for (i = 0; i < le_feature_info.max_filter; i++) {
918 if (slot_check_list[i] == FALSE) {
919 g_free(slot_check_list);
924 BT_ERR("There is NO available slot for scan filter.");
925 g_free(slot_check_list);
929 gboolean _bt_is_scan_filter_supported(void)
931 if (le_feature_info.max_filter > 0) {
938 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
941 GError *error = NULL;
942 GVariant *ret, *param;
943 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
944 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
945 GArray *arr_uuid = NULL;
946 GArray *arr_uuid_mask = NULL;
947 GArray *arr_data = NULL;
948 GArray *arr_data_mask = NULL;
949 bt_adapter_le_scanner_t *scanner = NULL;
950 bluetooth_le_scan_filter_t *filter_data = NULL;
951 int feature_selection = 0;
953 *slot_id = __bt_get_available_scan_filter_slot_id();
955 return BLUETOOTH_ERROR_NO_RESOURCES;
957 proxy = _bt_get_adapter_proxy();
958 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
960 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
961 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
962 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
964 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
966 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
967 NULL, 0, TRUE, NULL, NULL);
968 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
969 NULL, 0, TRUE, NULL, NULL);
970 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
971 NULL, 0, TRUE, NULL, NULL);
972 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
973 NULL, 0, TRUE, NULL, NULL);
975 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
977 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
978 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
979 *slot_id, // filter_index
981 0, // company_id_mask
982 arr_uuid_param, // p_uuid
983 arr_uuid_mask_param, // p_uuid_mask
986 arr_data_param, // p_data
987 arr_data_mask_param); // p_mask
989 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
990 param, G_DBUS_CALL_FLAGS_NONE,
994 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
995 g_clear_error(&error);
998 g_variant_unref(ret);
1001 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1002 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
1004 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1005 NULL, 0, TRUE, NULL, NULL);
1006 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1007 NULL, 0, TRUE, NULL, NULL);
1008 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1009 NULL, 0, TRUE, NULL, NULL);
1010 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1011 NULL, 0, TRUE, NULL, NULL);
1013 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1015 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1016 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1017 *slot_id, // filter_index
1019 0, // company_id_mask
1020 arr_uuid_param, // p_uuid
1021 arr_uuid_mask_param, // p_uuid_mask
1022 filter->device_name, // string
1024 arr_data_param, // p_data
1025 arr_data_mask_param);
1027 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1028 param, G_DBUS_CALL_FLAGS_NONE,
1032 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1033 g_clear_error(&error);
1036 g_variant_unref(ret);
1039 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1040 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1042 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1043 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1045 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1046 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1048 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1049 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1050 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1051 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1052 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1053 NULL, 0, TRUE, NULL, NULL);
1054 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1055 NULL, 0, TRUE, NULL, NULL);
1057 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1059 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1060 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1061 *slot_id, // filter_index
1063 0, // company_id_mask
1064 arr_uuid_param, // p_uuid
1065 arr_uuid_mask_param, // p_uuid_mask
1068 arr_data_param, // p_data
1069 arr_data_mask_param);
1071 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1072 param, G_DBUS_CALL_FLAGS_NONE,
1076 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1077 g_clear_error(&error);
1080 g_variant_unref(ret);
1082 g_array_free(arr_uuid, TRUE);
1083 g_array_free(arr_uuid_mask, TRUE);
1084 g_array_free(arr_data, TRUE);
1085 g_array_free(arr_data_mask, TRUE);
1088 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1089 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1091 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1092 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1094 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1095 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1097 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1098 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1099 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1100 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1101 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1102 NULL, 0, TRUE, NULL, NULL);
1103 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1104 NULL, 0, TRUE, NULL, NULL);
1106 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1108 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1109 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1110 *slot_id, // filter_index
1112 0, // company_id_mask
1113 arr_uuid_param, // p_uuid
1114 arr_uuid_mask_param, // p_uuid_mask
1117 arr_data_param, // p_data
1118 arr_data_mask_param);
1120 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1121 G_DBUS_CALL_FLAGS_NONE,
1125 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1126 g_clear_error(&error);
1129 g_variant_unref(ret);
1131 g_array_free(arr_uuid, TRUE);
1132 g_array_free(arr_uuid_mask, TRUE);
1135 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1136 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1138 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1139 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1141 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1142 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1144 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1145 NULL, 0, TRUE, NULL, NULL);
1146 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1147 NULL, 0, TRUE, NULL, NULL);
1148 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1149 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1150 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1151 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1153 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1155 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1156 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1157 *slot_id, // filter_index
1159 0, // company_id_mask
1160 arr_uuid_param, // p_uuid
1161 arr_uuid_mask_param, // p_uuid_mask
1164 arr_data_param, // p_data
1165 arr_data_mask_param);
1167 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1168 G_DBUS_CALL_FLAGS_NONE,
1172 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1173 g_clear_error(&error);
1176 g_variant_unref(ret);
1178 g_array_free(arr_data, TRUE);
1179 g_array_free(arr_data_mask, TRUE);
1182 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1183 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1185 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1186 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1188 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1189 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1191 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1192 NULL, 0, TRUE, NULL, NULL);
1193 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1194 NULL, 0, TRUE, NULL, NULL);
1195 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1196 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1197 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1198 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1200 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1202 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1203 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1204 *slot_id, // filter_index
1205 filter->manufacturer_id, // company_id
1206 0xFFFF, // company_id_mask
1207 arr_uuid_param, // p_uuid
1208 arr_uuid_mask_param, // p_uuid_mask
1211 arr_data_param, // p_data
1212 arr_data_mask_param);
1214 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1215 G_DBUS_CALL_FLAGS_NONE,
1219 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1220 g_clear_error(&error);
1223 g_variant_unref(ret);
1225 g_array_free(arr_data, TRUE);
1226 g_array_free(arr_data_mask, TRUE);
1229 BT_DBG("Filter selection %.2x", feature_selection);
1231 param = g_variant_new("(iiiiiiiiiiii)",
1233 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1234 *slot_id, // filter_index
1235 feature_selection, // feat_seln
1236 0, // list_logic_type (OR - 0x00, AND - 0x01)
1237 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1238 -127, // rssi_high_thres
1239 -127, // rssi_low_thres
1240 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1243 0); // found_timeout_cnt
1244 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1245 param, G_DBUS_CALL_FLAGS_NONE,
1249 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1250 g_clear_error(&error);
1253 scanner = __bt_find_scanner_from_list(sender);
1254 if (scanner == NULL) {
1255 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1257 scanner->sender = strdup(sender);
1258 scanner_list = g_slist_append(scanner_list, scanner);
1262 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1264 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1265 filter_data->slot_id = *slot_id;
1268 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1272 g_variant_unref(ret);
1273 return BLUETOOTH_ERROR_NONE;
1276 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1279 GError *error = NULL;
1281 bt_adapter_le_scanner_t *scanner = NULL;
1282 bluetooth_le_scan_filter_t *filter_data = NULL;
1284 gboolean is_slot_id_found = FALSE;
1286 scanner = __bt_find_scanner_from_list(sender);
1287 if (scanner == NULL) {
1288 BT_ERR("There is NO available scanner.");
1289 return BLUETOOTH_ERROR_NOT_FOUND;
1292 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1293 filter_data = l->data;
1294 if (filter_data->slot_id == slot_id) {
1295 is_slot_id_found = TRUE;
1299 if (is_slot_id_found == FALSE) {
1300 BT_ERR("There is NO registered slot.");
1301 return BLUETOOTH_ERROR_NOT_FOUND;
1304 proxy = _bt_get_adapter_proxy();
1305 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1307 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1308 g_variant_new("(ii)", 0, slot_id),
1309 G_DBUS_CALL_FLAGS_NONE,
1313 BT_ERR("scan_filter_clear Fail: %s", error->message);
1314 g_clear_error(&error);
1317 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1318 g_free(filter_data);
1321 g_variant_unref(ret);
1322 return BLUETOOTH_ERROR_NONE;
1325 int _bt_unregister_all_scan_filters(const char *sender)
1328 GError *error = NULL;
1330 bt_adapter_le_scanner_t *scanner = NULL;
1331 bluetooth_le_scan_filter_t *filter_data = NULL;
1334 scanner = __bt_find_scanner_from_list(sender);
1335 if (scanner == NULL) {
1336 BT_ERR("There is NO available scanner.");
1337 return BLUETOOTH_ERROR_NOT_FOUND;
1340 proxy = _bt_get_adapter_proxy();
1341 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1343 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1344 filter_data = l->data;
1346 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1347 g_variant_new("(ii)", 0, filter_data->slot_id),
1348 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1351 BT_ERR("scan_filter_clear Fail: %s", error->message);
1352 g_clear_error(&error);
1355 g_variant_unref(ret);
1358 g_slist_free_full(scanner->filter_list, g_free);
1359 scanner->filter_list = NULL;
1361 return BLUETOOTH_ERROR_NONE;
1364 int _bt_start_le_scan(const char *sender)
1367 GError *error = NULL;
1369 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1371 if (scanner == NULL) {
1372 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1373 retv_if(scanner == NULL, BLUETOOTH_ERROR_INTERNAL);
1375 scanner->sender = strdup(sender);
1376 scanner_list = g_slist_append(scanner_list, scanner);
1379 if (scanner->is_scanning == TRUE) {
1380 BT_ERR("BT is already in LE scanning");
1381 return BLUETOOTH_ERROR_IN_PROGRESS;
1383 scanner->is_scanning = TRUE;
1385 proxy = _bt_get_adapter_proxy();
1386 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1388 if (_bt_is_le_scanning()) {
1389 if (scan_filter_enabled == TRUE) {
1390 if (scanner->filter_list == NULL) {
1391 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1392 g_variant_new("(ib)", 0, FALSE),
1393 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1396 BT_ERR("scan_filter_clear Fail: %s", error->message);
1397 g_clear_error(&error);
1401 g_variant_unref(ret);
1402 BT_INFO("Disable LE Scan Filter");
1403 scan_filter_enabled = FALSE;
1405 BT_INFO("LE Filter Scan is continue");
1408 BT_INFO("LE Full Scan is already on progress");
1410 return BLUETOOTH_ERROR_NONE;
1412 if (is_le_set_scan_parameter == FALSE) {
1413 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1414 bluetooth_le_scan_params_t scan_params;
1415 scan_params.type = BT_LE_ACTIVE_SCAN;
1416 scan_params.interval = 5000;
1417 scan_params.window = 500;
1418 _bt_set_scan_parameters(&scan_params);
1421 if (scanner->filter_list == NULL) {
1422 BT_INFO("Start LE Full Scan");
1423 scan_filter_enabled = FALSE;
1425 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1426 g_variant_new("(ib)", 0, TRUE),
1427 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1430 BT_ERR("scan_filter_clear Fail: %s", error->message);
1431 g_clear_error(&error);
1435 g_variant_unref(ret);
1436 BT_INFO("Enable LE Scan Filter");
1437 scan_filter_enabled = TRUE;
1441 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1442 NULL, G_DBUS_CALL_FLAGS_NONE,
1446 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1447 g_clear_error(&error);
1448 return BLUETOOTH_ERROR_INTERNAL;
1452 g_variant_unref(ret);
1453 return BLUETOOTH_ERROR_NONE;
1456 int _bt_stop_le_scan(const char *sender)
1459 GError *error = NULL;
1461 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1463 gboolean next_scanning = FALSE;
1464 gboolean need_scan_filter = TRUE;
1466 if (scanner == NULL || scanner->is_scanning == FALSE)
1467 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1469 scanner->is_scanning = FALSE;
1471 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1473 if (scanner->is_scanning == TRUE) {
1474 next_scanning = TRUE;
1475 if (scanner->filter_list == NULL)
1476 need_scan_filter = FALSE;
1480 proxy = _bt_get_adapter_proxy();
1481 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1483 if (next_scanning == TRUE) {
1484 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1485 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1486 g_variant_new("(ib)", 0, TRUE),
1487 G_DBUS_CALL_FLAGS_NONE,
1491 BT_ERR("scan_filter_clear Fail: %s", error->message);
1492 g_clear_error(&error);
1496 g_variant_unref(ret);
1497 BT_INFO("Enable LE Scan Filter");
1498 scan_filter_enabled = TRUE;
1500 return BLUETOOTH_ERROR_NONE;
1502 if (scan_filter_enabled == TRUE) {
1503 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1504 g_variant_new("(ib)", 0, FALSE),
1505 G_DBUS_CALL_FLAGS_NONE,
1509 BT_ERR("scan_filter_clear Fail: %s", error->message);
1510 g_clear_error(&error);
1514 g_variant_unref(ret);
1515 BT_INFO("Disable LE Scan Filter");
1517 BT_INFO("Just stop LE scan");
1521 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1522 NULL, G_DBUS_CALL_FLAGS_NONE,
1525 BT_ERR("LE Scan stop failed");
1526 return BLUETOOTH_ERROR_INTERNAL;
1529 scan_filter_enabled = FALSE;
1530 is_le_set_scan_parameter = FALSE;
1532 g_variant_unref(ret);
1533 return BLUETOOTH_ERROR_NONE;
1536 void _bt_disable_all_scanner_status(void)
1539 bt_adapter_le_scanner_t *scanner;
1541 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1543 scanner->is_scanning = FALSE;
1547 void _bt_set_le_scan_status(gboolean mode)
1549 is_le_scanning = mode;
1552 gboolean _bt_is_le_scanning(void)
1554 return is_le_scanning;
1557 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1559 le_scan_type = type;
1562 bt_le_scan_type_t _bt_get_le_scan_type(void)
1564 return le_scan_type;
1567 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1568 int adv_data_len, const char *svc_uuid, int uuid_len,
1569 const char *uuid_mask, char ad_type)
1575 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1576 ad_type, &data, &data_len);
1578 for (i = 0; i < data_len; i += uuid_len) {
1579 if (uuid_len > (data_len - i))
1582 if (_bt_byte_arr_cmp_with_mask(data + i,
1583 svc_uuid, uuid_mask, uuid_len) == 0) {
1594 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1595 const char *adv_data, int adv_data_len,
1596 const char *scan_data, int scan_data_len,
1597 const bt_adapter_le_scanner_t *scanner)
1600 bluetooth_le_scan_filter_t *filter_data = NULL;
1603 gboolean is_matched = FALSE;
1605 if (scanner->filter_list == NULL) {
1606 BT_INFO("This scanner is on Full Scan.");
1610 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1611 filter_data = l->data;
1613 if (filter_data->added_features &
1614 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1615 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1617 _bt_convert_addr_type_to_string(address,
1618 filter_data->device_address.addr);
1619 if (strncmp(address, device_address,
1620 BT_ADDRESS_STRING_SIZE) != 0)
1624 if (filter_data->added_features &
1625 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1628 if (__bt_check_scan_result_uuid(adv_data,
1630 (char*)filter_data->service_uuid.data.data,
1631 filter_data->service_uuid.data_len,
1632 (char*)filter_data->service_uuid_mask.data.data,
1633 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1636 if (__bt_check_scan_result_uuid(adv_data,
1638 (char*)filter_data->service_uuid.data.data,
1639 filter_data->service_uuid.data_len,
1640 (char*)filter_data->service_uuid_mask.data.data,
1641 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1644 if (__bt_check_scan_result_uuid(adv_data,
1646 (char*)filter_data->service_uuid.data.data,
1647 filter_data->service_uuid.data_len,
1648 (char*)filter_data->service_uuid_mask.data.data,
1649 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1652 if (__bt_check_scan_result_uuid(adv_data,
1654 (char*)filter_data->service_uuid.data.data,
1655 filter_data->service_uuid.data_len,
1656 (char*)filter_data->service_uuid_mask.data.data,
1657 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1660 if (__bt_check_scan_result_uuid(scan_data,
1662 (char*)filter_data->service_uuid.data.data,
1663 filter_data->service_uuid.data_len,
1664 (char*)filter_data->service_uuid_mask.data.data,
1665 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1668 if (__bt_check_scan_result_uuid(scan_data,
1670 (char*)filter_data->service_uuid.data.data,
1671 filter_data->service_uuid.data_len,
1672 (char*)filter_data->service_uuid_mask.data.data,
1673 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1676 if (__bt_check_scan_result_uuid(scan_data,
1678 (char*)filter_data->service_uuid.data.data,
1679 filter_data->service_uuid.data_len,
1680 (char*)filter_data->service_uuid_mask.data.data,
1681 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1684 if (__bt_check_scan_result_uuid(scan_data,
1686 (char*)filter_data->service_uuid.data.data,
1687 filter_data->service_uuid.data_len,
1688 (char*)filter_data->service_uuid_mask.data.data,
1689 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1693 if (is_matched == FALSE)
1696 if (filter_data->added_features &
1697 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1700 if (__bt_check_scan_result_uuid(adv_data,
1702 (char*)filter_data->service_solicitation_uuid.data.data,
1703 filter_data->service_solicitation_uuid.data_len,
1704 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1705 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1708 if (__bt_check_scan_result_uuid(adv_data,
1710 (char*)filter_data->service_solicitation_uuid.data.data,
1711 filter_data->service_solicitation_uuid.data_len,
1712 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1713 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1716 if (__bt_check_scan_result_uuid(scan_data,
1718 (char*)filter_data->service_solicitation_uuid.data.data,
1719 filter_data->service_solicitation_uuid.data_len,
1720 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1721 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1724 if (__bt_check_scan_result_uuid(scan_data,
1726 (char*)filter_data->service_solicitation_uuid.data.data,
1727 filter_data->service_solicitation_uuid.data_len,
1728 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1729 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1733 if (is_matched == FALSE)
1736 if (filter_data->added_features &
1737 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1738 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1743 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1744 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1747 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1748 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1749 memcpy(name, data, data_len);
1750 name[data_len] = '\0';
1753 if (strncmp(filter_data->device_name,
1754 name, data_len) == 0)
1757 __bt_get_ad_data_by_type((char*)scan_data,
1759 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1762 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1763 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1764 memcpy(name, data, data_len);
1765 name[data_len] = '\0';
1768 if (strncmp(filter_data->device_name,
1769 name, data_len) == 0)
1773 if (is_matched == FALSE)
1776 if (filter_data->added_features &
1777 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1782 __bt_get_ad_data_by_type((char*)adv_data,
1784 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1788 int manufacturer_id;
1789 manufacturer_id = (data[1] << 8) + data[0];
1791 if (filter_data->manufacturer_id == manufacturer_id) {
1792 if (filter_data->manufacturer_data.data_len == 0) {
1795 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1796 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1797 if (_bt_byte_arr_cmp_with_mask(data + 2,
1798 (char*)filter_data->manufacturer_data.data.data,
1799 (char*)filter_data->manufacturer_data_mask.data.data,
1800 data_len - 2) == 0) {
1808 __bt_get_ad_data_by_type((char*)scan_data,
1810 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1814 int manufacturer_id;
1815 manufacturer_id = (data[1] << 8) + data[0];
1817 if (filter_data->manufacturer_id == manufacturer_id) {
1818 if (filter_data->manufacturer_data.data_len == 0) {
1821 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1822 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1823 if (_bt_byte_arr_cmp_with_mask(data + 2,
1824 (char*)filter_data->manufacturer_data.data.data,
1825 (char*)filter_data->manufacturer_data_mask.data.data,
1826 data_len - 2) == 0) {
1835 if (is_matched == FALSE)
1838 if (filter_data->added_features &
1839 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1844 __bt_get_ad_data_by_type((char*)adv_data,
1846 BT_LE_AD_TYPE_SERVICE_DATA,
1849 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1850 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1851 if (_bt_byte_arr_cmp_with_mask(data,
1852 (char*)filter_data->service_data.data.data,
1853 (char*)filter_data->service_data_mask.data.data,
1860 __bt_get_ad_data_by_type((char*)scan_data,
1862 BT_LE_AD_TYPE_SERVICE_DATA,
1865 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1866 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1867 if (_bt_byte_arr_cmp_with_mask(data,
1868 (char*)filter_data->service_data.data.data,
1869 (char*)filter_data->service_data_mask.data.data,
1877 if (is_matched == FALSE)
1881 BT_INFO("The scan result is conformable.");
1885 BT_INFO("The scan result is NOT conformable.");
1889 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1890 const bt_le_adv_info_t *adv_info)
1892 int result = BLUETOOTH_ERROR_NONE;
1894 GVariant *scan_data_param, *adv_data_param;
1896 bt_adapter_le_scanner_t *scanner = NULL;
1897 const char *adv_data = NULL;
1898 int adv_data_len = 0;
1899 const char *scan_data = NULL;
1900 int scan_data_len = 0;
1902 ret_if(le_dev_info == NULL);
1903 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1904 ret_if(adv_info == NULL);
1906 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1907 adv_data = le_dev_info->adv_data;
1908 adv_data_len = le_dev_info->adv_data_len;
1909 scan_data = le_dev_info->adv_data;
1912 adv_data = adv_info->data;
1913 adv_data_len = adv_info->data_len;
1914 scan_data = le_dev_info->adv_data;
1915 scan_data_len = le_dev_info->adv_data_len;
1918 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1920 if (scanner->is_scanning == FALSE)
1923 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1924 adv_data, adv_data_len, scan_data, scan_data_len,
1928 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1929 adv_data, adv_data_len, TRUE, NULL, NULL);
1930 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1931 scan_data, scan_data_len, TRUE, NULL, NULL);
1933 param = g_variant_new("(isnnn@ayn@ay)",
1935 le_dev_info->address,
1936 le_dev_info->addr_type,
1944 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1945 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1947 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1952 void _bt_send_ibeacon_scan_result_event(const bt_remote_ibeacon_dev_info_t *ibeacon_dev_info)
1954 int result = BLUETOOTH_ERROR_NONE;
1957 bt_adapter_le_scanner_t *scanner = NULL;
1959 ret_if(ibeacon_dev_info == NULL);
1960 BT_DBG("_bt_send_ibeacon_scan_result_event");
1962 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1964 if (scanner->is_scanning == FALSE)
1967 param = g_variant_new("(isnnnsnnn)",
1969 ibeacon_dev_info->address,
1970 ibeacon_dev_info->addr_type,
1971 ibeacon_dev_info->company_id,
1972 ibeacon_dev_info->ibeacon_type,
1973 ibeacon_dev_info->uuid,
1974 ibeacon_dev_info->major_id,
1975 ibeacon_dev_info->minor_id,
1976 ibeacon_dev_info->measured_power);
1978 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_IBEACON_DEVICE_FOUND, param);
1982 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1985 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1986 GError *error = NULL;
1989 if (__bt_is_factory_test_mode()) {
1990 BT_ERR("Unable to add white list in factory binary !!");
1991 return BLUETOOTH_ERROR_NOT_SUPPORT;
1994 BT_CHECK_PARAMETER(device_address, return);
1996 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1997 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1998 return BLUETOOTH_ERROR_INVALID_PARAM;
2000 _bt_convert_addr_type_to_string(address, device_address->addr);
2002 proxy = _bt_get_adapter_proxy();
2003 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2005 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
2006 g_variant_new("(su)", address, address_type),
2007 G_DBUS_CALL_FLAGS_NONE, -1,
2011 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
2012 g_clear_error(&error);
2013 return BLUETOOTH_ERROR_INTERNAL;
2017 g_variant_unref(ret);
2018 BT_INFO("Add white list");
2020 return BLUETOOTH_ERROR_NONE;
2023 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2026 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2027 GError *error = NULL;
2030 if (__bt_is_factory_test_mode()) {
2031 BT_ERR("Unable to remove white list in factory binary !!");
2032 return BLUETOOTH_ERROR_NOT_SUPPORT;
2035 BT_CHECK_PARAMETER(device_address, return);
2037 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2038 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2039 return BLUETOOTH_ERROR_INVALID_PARAM;
2041 _bt_convert_addr_type_to_string(address, device_address->addr);
2043 proxy = _bt_get_adapter_proxy();
2044 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2046 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
2047 g_variant_new("(su)", address, address_type),
2048 G_DBUS_CALL_FLAGS_NONE, -1,
2052 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2053 g_clear_error(&error);
2054 return BLUETOOTH_ERROR_INTERNAL;
2058 g_variant_unref(ret);
2059 BT_INFO("Remove white list");
2061 return BLUETOOTH_ERROR_NONE;
2064 int _bt_clear_white_list(void)
2067 GError *error = NULL;
2070 if (__bt_is_factory_test_mode()) {
2071 BT_ERR("Unable to clear white list in factory binary !!");
2072 return BLUETOOTH_ERROR_NOT_SUPPORT;
2075 proxy = _bt_get_adapter_proxy();
2076 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2078 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2079 NULL, G_DBUS_CALL_FLAGS_NONE,
2083 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2084 g_clear_error(&error);
2085 return BLUETOOTH_ERROR_INTERNAL;
2088 g_variant_unref(ret);
2090 BT_INFO("Clear white list");
2092 return BLUETOOTH_ERROR_NONE;
2095 int _bt_initialize_ipsp(void)
2099 GError *error = NULL;
2102 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2103 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2104 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2107 proxy = _bt_get_adapter_proxy();
2108 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2110 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2111 NULL, G_DBUS_CALL_FLAGS_NONE,
2114 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2115 g_clear_error(&error);
2116 return BLUETOOTH_ERROR_INTERNAL;
2119 g_variant_unref(ret);
2121 BT_INFO("IPSP initialization called successfully");
2123 return BLUETOOTH_ERROR_NONE;
2126 int _bt_deinitialize_ipsp(void)
2130 GError *error = NULL;
2133 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2134 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2135 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2138 proxy = _bt_get_adapter_proxy();
2139 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2141 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2142 NULL, G_DBUS_CALL_FLAGS_NONE,
2145 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2146 g_clear_error(&error);
2147 return BLUETOOTH_ERROR_INTERNAL;
2150 g_variant_unref(ret);
2152 BT_INFO("IPSP De-initialization called successfully");
2154 return BLUETOOTH_ERROR_NONE;
2157 int _bt_le_read_maximum_data_length(
2158 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2160 GError *error = NULL;
2162 GVariant *reply = NULL;
2163 guint16 max_tx_octets, max_tx_time;
2164 guint16 max_rx_octets, max_rx_time;
2166 proxy = _bt_get_adapter_proxy();
2167 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2169 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2170 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2172 g_object_unref(proxy);
2174 if (reply == NULL) {
2175 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2176 if (error != NULL) {
2177 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2178 error->code, error->message);
2179 g_clear_error(&error);
2181 return BLUETOOTH_ERROR_INTERNAL;
2184 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2185 &max_rx_octets, &max_rx_time);
2187 max_le_datalength->max_tx_octets = max_tx_octets;
2188 max_le_datalength->max_tx_time = max_tx_time;
2189 max_le_datalength->max_rx_octets = max_rx_octets;
2190 max_le_datalength->max_rx_time = max_rx_time;
2192 g_variant_unref(reply);
2194 return BLUETOOTH_ERROR_NONE;
2196 int _bt_le_write_host_suggested_default_data_length(
2197 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2199 GError *error = NULL;
2201 GVariant *reply = NULL;
2203 proxy = _bt_get_adapter_proxy();
2204 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2206 reply = g_dbus_proxy_call_sync(proxy,
2207 "LEWriteHostSuggestedDataLength",
2208 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2209 G_DBUS_CALL_FLAGS_NONE,
2214 g_object_unref(proxy);
2216 if (reply == NULL) {
2217 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2218 if (error != NULL) {
2219 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2220 error->code, error->message);
2221 g_clear_error(&error);
2223 return BLUETOOTH_ERROR_INTERNAL;
2226 g_variant_unref(reply);
2228 return BLUETOOTH_ERROR_NONE;
2231 int _bt_le_read_host_suggested_default_data_length(
2232 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2234 GError *error = NULL;
2236 GVariant *reply = NULL;
2237 guint16 def_tx_octets, def_tx_time;
2239 proxy = _bt_get_adapter_proxy();
2240 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2242 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2243 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2245 if (reply == NULL) {
2246 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2247 if (error != NULL) {
2248 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2249 error->code, error->message);
2250 g_clear_error(&error);
2252 return BLUETOOTH_ERROR_INTERNAL;
2255 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2257 def_data_length->def_tx_octets = def_tx_octets;
2258 def_data_length->def_tx_time = def_tx_time;
2260 g_variant_unref(reply);
2262 return BLUETOOTH_ERROR_NONE;
2265 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2266 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2268 GError *error = NULL;
2269 guint16 txOctets = max_tx_Octets;
2270 guint16 txTime = max_tx_Time;
2271 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2272 gchar *device_path = NULL;
2273 GDBusConnection *conn;
2274 GDBusProxy *device_proxy;
2276 _bt_convert_addr_type_to_string(address, device_address->addr);
2278 device_path = _bt_get_device_object_path(address);
2280 if (device_path == NULL) {
2281 BT_DBG("Device path is null");
2282 return BLUETOOTH_ERROR_INTERNAL;
2285 conn = _bt_gdbus_get_system_gconn();
2287 BT_ERR("conn == NULL");
2288 g_free(device_path);
2289 return BLUETOOTH_ERROR_INTERNAL;
2292 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2293 NULL, BT_BLUEZ_NAME,
2294 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2296 g_free(device_path);
2297 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2299 g_dbus_proxy_call_sync(device_proxy,
2301 g_variant_new("(qq)", txOctets, txTime),
2302 G_DBUS_CALL_FLAGS_NONE,
2307 g_object_unref(device_proxy);
2310 BT_ERR("LESetDataLength error: [%s]", error->message);
2311 g_error_free(error);
2312 return BLUETOOTH_ERROR_INTERNAL;
2315 return BLUETOOTH_ERROR_NONE;