2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dbus/dbus.h>
25 #include <syspopup_caller.h>
28 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-event.h"
31 #include "bt-service-adapter.h"
32 #include "bt-service-adapter-le.h"
33 #include "bt-service-util.h"
36 #define BT_ADV_INTERVAL_MIN 20 /* msec */
37 #define BT_ADV_INTERVAL_MAX 10240
38 #define BT_ADV_INTERVAL_SPLIT 0.625
39 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
40 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
41 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
42 #define BT_ADV_TYPE_DEFAULT 0x00
43 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
49 } bt_adapter_le_feature_info_t;
54 gboolean is_advertising;
56 } bt_adapter_le_adv_slot_t;
62 } bt_adapter_le_scanner_t;
64 static bluetooth_advertising_params_t adv_params = {
65 BT_DEFAULT_ADV_MIN_INTERVAL,
66 BT_DEFAULT_ADV_MAX_INTERVAL,
67 BT_ADV_FILTER_POLICY_DEFAULT,
69 static bluetooth_advertising_data_t adv_data = { {0} };
70 static int adv_data_len;
71 static bluetooth_scan_resp_data_t resp_data = { {0} };
72 static int resp_data_len;
74 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
75 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
77 GSList *scanner_list = NULL;
78 static gboolean is_le_set_scan_parameter = FALSE;
79 static gboolean is_le_scanning = FALSE;
80 static gboolean scan_filter_enabled = FALSE;
81 static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN;
83 static GSList *gatt_client_senders = NULL;
86 gboolean _bt_is_set_scan_parameter(void)
88 return is_le_set_scan_parameter;
91 void _bt_init_gatt_client_senders(void)
93 _bt_clear_request_list();
96 int _bt_insert_gatt_client_sender(char *sender)
100 retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
102 info = g_strdup(sender);
103 retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
105 gatt_client_senders = g_slist_append(gatt_client_senders, info);
107 BT_DBG("insert sender: %s", sender);
109 return BLUETOOTH_ERROR_NONE;
112 int _bt_delete_gatt_client_sender(char *sender)
117 BT_DBG("remove sender: %s", sender);
119 for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) {
124 if (g_strcmp0(info, sender) == 0) {
125 BT_DBG("remove info");
126 gatt_client_senders = g_slist_remove(gatt_client_senders, info);
128 return BLUETOOTH_ERROR_NONE;
132 return BLUETOOTH_ERROR_NOT_FOUND;
135 void _bt_clear_gatt_client_senders(void)
137 if (gatt_client_senders) {
138 g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL);
139 g_slist_free(gatt_client_senders);
140 gatt_client_senders = NULL;
144 static void __bt_send_foreach_event(gpointer data, gpointer user_data)
147 GVariant *param = user_data;
149 _bt_send_event_to_dest(sender, BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
153 void _bt_send_char_value_changed_event(void *param)
156 g_slist_foreach(gatt_client_senders, __bt_send_foreach_event,
159 _bt_send_event(BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED, param);
163 void __bt_free_le_adv_slot(void)
167 if (le_adv_slot == NULL)
170 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
171 if (le_adv_slot[i].sender)
172 g_free(le_adv_slot[i].sender);
173 if (le_adv_slot[i].hold_timer_id > 0)
174 g_source_remove(le_adv_slot[i].hold_timer_id);
180 int _bt_service_adapter_le_init(void)
182 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
184 return BLUETOOTH_ERROR_NONE;
187 void _bt_service_adapter_le_deinit(void)
189 __bt_free_le_adv_slot();
192 int _bt_le_set_max_packet_len(void)
194 int result = BLUETOOTH_ERROR_NONE;
195 int tx_octets, tx_time;
196 bluetooth_le_read_maximum_data_length_t max_len = {0};
198 if (BLUETOOTH_ERROR_NONE != _bt_le_read_maximum_data_length(&max_len))
199 return BLUETOOTH_ERROR_INTERNAL;
201 if (max_len.max_tx_octets > BT_LE_TX_LEN_DEFAULT) {
202 tx_octets = max_len.max_tx_octets > BT_LE_TX_LEN_MAX ?
203 BT_LE_TX_LEN_MAX : max_len.max_tx_octets;
204 tx_time = BT_LE_TX_TIME_MAX;
206 result = _bt_le_write_host_suggested_default_data_length(tx_octets, tx_time);
208 BT_DBG("Wrote max packet size : result[%d], MAX[%d], set[%d]",
209 result, max_len.max_tx_octets, tx_octets);
215 gboolean _bt_update_le_feature_support(const char *item, const char *value)
217 if (item == NULL || value == NULL)
220 if (g_strcmp0(item, "adv_inst_max") == 0) {
223 slot_num = atoi(value);
224 retv_if(slot_num < 0, FALSE);
226 if (slot_num != le_feature_info.adv_inst_max) {
227 __bt_free_le_adv_slot();
228 le_feature_info.adv_inst_max = slot_num;
229 BT_INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
230 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
232 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
233 le_feature_info.rpa_offloading = atoi(value);
234 BT_INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
235 } else if (g_strcmp0(item, "max_filter") == 0) {
236 le_feature_info.max_filter = atoi(value);
237 BT_INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
239 BT_DBG("No registered item");
246 static gboolean __bt_is_factory_test_mode(void)
250 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
251 BT_ERR("Get the DUT Mode fail");
256 BT_INFO("DUT Test Mode !!");
263 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
267 if (le_adv_slot == NULL) {
268 BT_ERR("le_adv_slot is NULL");
272 BT_DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
274 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
275 if (le_adv_slot[i].sender == NULL)
277 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
281 if (le_feature_info.adv_inst_max <= 2)
283 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
288 for (; i < le_feature_info.adv_inst_max; i++) {
289 if (le_adv_slot[i].sender == NULL)
296 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
298 if (le_adv_slot[slot_id].sender == NULL) {
299 le_adv_slot[slot_id].sender = strdup(sender);
300 le_adv_slot[slot_id].adv_handle = adv_handle;
304 void _bt_unregister_adv_slot_owner(int slot_id)
306 if (le_adv_slot[slot_id].hold_timer_id > 0) {
307 BT_INFO("Hold state adv is not unregistered");
311 g_free(le_adv_slot[slot_id].sender);
312 le_adv_slot[slot_id].sender = NULL;
313 le_adv_slot[slot_id].adv_handle = 0;
316 const char* _bt_get_adv_slot_owner(int slot_id)
318 if (le_adv_slot == NULL)
321 return le_adv_slot[slot_id].sender;
324 int _bt_get_adv_slot_adv_handle(int slot_id)
326 if (le_adv_slot == NULL)
329 return le_adv_slot[slot_id].adv_handle;
332 void _bt_set_advertising_status(int slot_id, gboolean mode)
334 le_adv_slot[slot_id].is_advertising = mode;
337 gboolean _bt_is_advertising(void)
339 gboolean status = FALSE;
342 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
343 if (le_adv_slot[i].is_advertising == TRUE)
350 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
354 if (le_adv_slot == NULL)
357 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
358 if (le_adv_slot[i].sender != NULL) {
359 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
360 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
361 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
367 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
372 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
377 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
380 GError *error = NULL;
384 if (__bt_is_factory_test_mode()) {
385 BT_ERR("Unable to start advertising in factory binary !!");
386 return BLUETOOTH_ERROR_NOT_SUPPORT;
389 if (_bt_adapter_get_status() != BT_ACTIVATED &&
390 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
391 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
394 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
396 BT_ERR("There is NO available slot!!");
397 return BLUETOOTH_ERROR_NO_RESOURCES;
400 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
401 return BLUETOOTH_ERROR_IN_PROGRESS;
403 if (le_adv_slot[slot_id].hold_timer_id > 0) {
404 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
405 le_adv_slot[slot_id].hold_timer_id = 0;
406 _bt_unregister_adv_slot_owner(slot_id);
409 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
410 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
412 proxy = _bt_get_adapter_proxy();
413 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
415 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
416 g_variant_new("(bi)", enable, slot_id),
417 G_DBUS_CALL_FLAGS_NONE,
423 BT_ERR("SetAdvertising Fail: %s", error->message);
424 g_clear_error(&error);
425 return BLUETOOTH_ERROR_INTERNAL;
429 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
431 le_adv_slot[slot_id].is_advertising = enable;
432 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
435 g_variant_unref(ret);
437 return BLUETOOTH_ERROR_NONE;
440 int _bt_set_custom_advertising(const char *sender, int adv_handle,
441 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
445 GError *error = NULL;
450 BT_CHECK_PARAMETER(params, return);
452 if (__bt_is_factory_test_mode()) {
453 BT_ERR("Unable to start advertising in factory binary !!");
454 return BLUETOOTH_ERROR_NOT_SUPPORT;
457 if (_bt_adapter_get_status() != BT_ACTIVATED &&
458 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
459 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
462 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
464 BT_ERR("There is NO available slot!!");
465 return BLUETOOTH_ERROR_NO_RESOURCES;
468 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
469 return BLUETOOTH_ERROR_IN_PROGRESS;
471 if (le_adv_slot[slot_id].hold_timer_id > 0) {
472 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
473 le_adv_slot[slot_id].hold_timer_id = 0;
474 _bt_unregister_adv_slot_owner(slot_id);
477 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
478 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
480 proxy = _bt_get_adapter_proxy();
481 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
483 if (params->interval_min > params->interval_max ||
484 params->interval_min < BT_ADV_INTERVAL_MIN ||
485 params->interval_max > BT_ADV_INTERVAL_MAX)
486 return BLUETOOTH_ERROR_INVALID_PARAM;
488 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
489 return BLUETOOTH_ERROR_INVALID_PARAM;
491 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
492 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
493 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
494 return BLUETOOTH_ERROR_NOT_SUPPORT;
496 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
497 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
499 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
500 g_variant_new("(uuuui)", min, max,
501 params->filter_policy, params->type,
502 slot_id), G_DBUS_CALL_FLAGS_NONE,
506 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
507 g_clear_error(&error);
508 return BLUETOOTH_ERROR_INTERNAL;
511 adv_params.interval_min = params->interval_min;
512 adv_params.interval_max = params->interval_max;
513 adv_params.filter_policy = params->filter_policy;
514 adv_params.type = params->type;
517 g_variant_unref(ret);
519 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
520 g_variant_new("(bi)", enable, slot_id),
521 G_DBUS_CALL_FLAGS_NONE,
527 BT_ERR("SetAdvertising Fail: %s", error->message);
528 g_clear_error(&error);
529 return BLUETOOTH_ERROR_INTERNAL;
533 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
535 le_adv_slot[slot_id].is_advertising = enable;
536 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
538 g_variant_unref(ret);
540 return BLUETOOTH_ERROR_NONE;
543 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
546 GError *error = NULL;
549 BT_INFO("Restart advertising stopped by bt-service");
551 le_adv_slot[0].hold_timer_id = 0;
553 proxy = _bt_get_adapter_proxy();
554 retv_if(proxy == NULL, FALSE);
556 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
557 g_variant_new("(bi)", TRUE, 0),
558 G_DBUS_CALL_FLAGS_NONE,
564 BT_ERR("SetAdvertising Fail: %s", error->message);
565 g_clear_error(&error);
570 g_variant_unref(ret);
575 int _bt_hold_current_advertising(void)
578 GError *error = NULL;
581 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
582 BT_INFO("Stop current advertising by bt-service");
584 proxy = _bt_get_adapter_proxy();
585 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
587 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
588 g_variant_new("(bi)", FALSE, 0),
589 G_DBUS_CALL_FLAGS_NONE,
595 BT_ERR("SetAdvertising Fail: %s", error->message);
596 g_clear_error(&error);
597 return BLUETOOTH_ERROR_INTERNAL;
601 g_variant_unref(ret);
603 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
604 __bt_hold_current_advertising_timeout_cb, NULL);
606 BT_INFO("It's NOT advertising");
607 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
610 return BLUETOOTH_ERROR_NONE;
613 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
614 char in_type, char **data, int *data_len)
616 if (in_data == NULL || data == NULL || data_len == NULL)
617 return BLUETOOTH_ERROR_INTERNAL;
620 return BLUETOOTH_ERROR_INTERNAL;
626 for (i = 0; i < in_len; i++) {
628 if (len <= 0 || i + 1 >= in_len) {
629 BT_ERR("Invalid advertising data");
630 return BLUETOOTH_ERROR_INTERNAL;
633 type = in_data[i + 1];
634 if (type == in_type) {
644 if (i + len > in_len) {
645 BT_ERR("Invalid advertising data");
646 return BLUETOOTH_ERROR_INTERNAL;
647 } else if (len == 0) {
648 BT_DBG("AD Type 0x%02x data is not set", in_type);
651 return BLUETOOTH_ERROR_NONE;
654 *data = g_memdup(&in_data[i], len);
656 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
659 return BLUETOOTH_ERROR_NONE;
662 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
664 BT_CHECK_PARAMETER(adv, return);
665 BT_CHECK_PARAMETER(length, return);
667 memcpy(adv, &adv_data, sizeof(adv_data));
668 *length = adv_data_len;
670 return BLUETOOTH_ERROR_NONE;
673 int _bt_set_advertising_data(const char *sender, int adv_handle,
674 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
677 GError *error = NULL;
678 GVariant *ret, *ad_data, *param = NULL;
679 GVariant *temp = NULL;
680 GVariantBuilder *builder;
682 char *old_mdata = NULL;
683 char *new_mdata = NULL;
688 if (__bt_is_factory_test_mode()) {
689 BT_ERR("Unable to set advertising data in factory binary !!");
690 return BLUETOOTH_ERROR_NOT_SUPPORT;
693 BT_CHECK_PARAMETER(adv, return);
695 if (_bt_adapter_get_status() != BT_ACTIVATED &&
696 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
697 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
700 proxy = _bt_get_adapter_proxy();
701 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
703 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
705 BT_ERR("There is NO available slot!!");
706 return BLUETOOTH_ERROR_NO_RESOURCES;
709 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
710 for (i = 0; i < length; i++)
711 g_variant_builder_add(builder, "y", adv->data[i]);
713 temp = g_variant_new("ay", builder);
714 g_variant_builder_unref(builder);
715 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
716 g_variant_new("(@ayi)", temp, slot_id),
717 G_DBUS_CALL_FLAGS_NONE,
721 BT_ERR("SetAdvertisingData Fail: %s", error->message);
722 g_clear_error(&error);
723 return BLUETOOTH_ERROR_INTERNAL;
726 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
728 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
729 &old_mdata, &old_len);
730 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
731 &new_mdata, &new_len);
732 if (old_len != new_len ||
733 (old_mdata && new_mdata &&
734 memcmp(old_mdata, new_mdata, new_len))) {
735 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
736 new_mdata, new_len, TRUE, NULL, NULL);
737 param = g_variant_new("(@ay)", ad_data);
738 _bt_send_event(BT_ADAPTER_EVENT,
739 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
745 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
746 memcpy(&adv_data, adv, length);
747 adv_data_len = length;
749 BT_INFO("Set advertising data");
751 g_variant_unref(ret);
753 return BLUETOOTH_ERROR_NONE;
756 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
758 BT_CHECK_PARAMETER(response, return);
759 BT_CHECK_PARAMETER(length, return);
761 memcpy(response, &resp_data, sizeof(resp_data));
762 *length = resp_data_len;
764 return BLUETOOTH_ERROR_NONE;
767 int _bt_set_scan_response_data(const char *sender, int adv_handle,
768 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
771 GError *error = NULL;
772 GVariant *ret, *scan_data, *param = NULL;
773 GVariant *temp = NULL;
774 GVariantBuilder *builder;
776 char *old_mdata = NULL;
777 char *new_mdata = NULL;
782 if (__bt_is_factory_test_mode()) {
783 BT_ERR("Unable to set scan response list in factory binary !!");
784 return BLUETOOTH_ERROR_NOT_SUPPORT;
787 BT_CHECK_PARAMETER(response, return);
789 if (_bt_adapter_get_status() != BT_ACTIVATED &&
790 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
791 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
794 proxy = _bt_get_adapter_proxy();
795 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
797 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
799 BT_ERR("There is NO available slot!!");
800 return BLUETOOTH_ERROR_NO_RESOURCES;
802 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
803 for (i = 0; i < length; i++)
804 g_variant_builder_add(builder, "y", response->data[i]);
806 temp = g_variant_new("ay", builder);
807 g_variant_builder_unref(builder);
808 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
809 g_variant_new("(@ayi)", temp, slot_id),
810 G_DBUS_CALL_FLAGS_NONE,
814 BT_ERR("SetScanRespData Fail: %s", error->message);
815 g_clear_error(&error);
816 return BLUETOOTH_ERROR_INTERNAL;
819 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
821 /* Compare with previous scan resp data */
822 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
823 &old_mdata, &old_len);
824 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
825 &new_mdata, &new_len);
826 if (old_len != new_len ||
827 (old_mdata && new_mdata &&
828 memcmp(old_mdata, new_mdata, new_len))) {
829 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
830 new_mdata, new_len, TRUE, NULL, NULL);
831 param = g_variant_new("(@ay)", scan_data);
832 _bt_send_event(BT_ADAPTER_EVENT,
833 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
839 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
840 memcpy(&resp_data, response, length);
841 resp_data_len = length;
844 g_variant_unref(ret);
845 BT_INFO("Set scan response data");
846 return BLUETOOTH_ERROR_NONE;
849 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
852 GError *error = NULL;
857 BT_CHECK_PARAMETER(params, return);
859 if (_bt_adapter_get_status() != BT_ACTIVATED &&
860 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
861 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
864 proxy = _bt_get_adapter_proxy();
865 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
867 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
868 return BLUETOOTH_ERROR_INVALID_PARAM;
870 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
871 return BLUETOOTH_ERROR_INVALID_PARAM;
873 if (params->window > params->interval)
874 return BLUETOOTH_ERROR_INVALID_PARAM;
876 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
877 win = params->window / BT_ADV_INTERVAL_SPLIT;
879 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
880 g_variant_new("(uuu)", params->type, itv, win),
881 G_DBUS_CALL_FLAGS_NONE, -1,
885 BT_ERR("SetScanParameters Fail: %s", error->message);
886 g_clear_error(&error);
887 return BLUETOOTH_ERROR_INTERNAL;
890 _bt_set_le_scan_type(params->type);
892 is_le_set_scan_parameter = TRUE;
895 g_variant_unref(ret);
896 BT_INFO("Set scan parameters");
897 return BLUETOOTH_ERROR_NONE;
900 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
903 bt_adapter_le_scanner_t *scanner;
905 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
907 if (g_strcmp0(scanner->sender, sender) == 0)
914 int __bt_get_available_scan_filter_slot_id(void)
917 bt_adapter_le_scanner_t *scanner;
919 bluetooth_le_scan_filter_t *filter_data;
920 gboolean *slot_check_list = NULL;
923 if (le_feature_info.max_filter == 0) {
924 BT_ERR("Scan filter is NOT Supported");
927 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
929 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
931 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
932 filter_data = fl->data;
933 if (filter_data->slot_id < le_feature_info.max_filter)
934 slot_check_list[filter_data->slot_id] = TRUE;
938 for (i = 0; i < le_feature_info.max_filter; i++) {
939 if (slot_check_list[i] == FALSE) {
940 g_free(slot_check_list);
945 BT_ERR("There is NO available slot for scan filter.");
946 g_free(slot_check_list);
950 gboolean _bt_is_scan_filter_supported(void)
952 if (le_feature_info.max_filter > 0)
958 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
961 GError *error = NULL;
962 GVariant *ret, *param;
963 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
964 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
965 GArray *arr_uuid = NULL;
966 GArray *arr_uuid_mask = NULL;
967 GArray *arr_data = NULL;
968 GArray *arr_data_mask = NULL;
969 bt_adapter_le_scanner_t *scanner = NULL;
970 bluetooth_le_scan_filter_t *filter_data = NULL;
971 int feature_selection = 0;
973 *slot_id = __bt_get_available_scan_filter_slot_id();
975 return BLUETOOTH_ERROR_NO_RESOURCES;
977 proxy = _bt_get_adapter_proxy();
978 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
980 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
981 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
982 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
984 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
986 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
987 NULL, 0, TRUE, NULL, NULL);
988 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
989 NULL, 0, TRUE, NULL, NULL);
990 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
991 NULL, 0, TRUE, NULL, NULL);
992 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
993 NULL, 0, TRUE, NULL, NULL);
995 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
997 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
998 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
999 *slot_id, // filter_index
1001 0, // company_id_mask
1002 arr_uuid_param, // p_uuid
1003 arr_uuid_mask_param, // p_uuid_mask
1006 arr_data_param, // p_data
1007 arr_data_mask_param); // p_mask
1009 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1010 param, G_DBUS_CALL_FLAGS_NONE,
1014 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1015 g_clear_error(&error);
1018 g_variant_unref(ret);
1021 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1022 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
1024 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1025 NULL, 0, TRUE, NULL, NULL);
1026 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1027 NULL, 0, TRUE, NULL, NULL);
1028 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1029 NULL, 0, TRUE, NULL, NULL);
1030 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1031 NULL, 0, TRUE, NULL, NULL);
1033 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1035 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1036 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1037 *slot_id, // filter_index
1039 0, // company_id_mask
1040 arr_uuid_param, // p_uuid
1041 arr_uuid_mask_param, // p_uuid_mask
1042 filter->device_name, // string
1044 arr_data_param, // p_data
1045 arr_data_mask_param);
1047 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1048 param, G_DBUS_CALL_FLAGS_NONE,
1052 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1053 g_clear_error(&error);
1056 g_variant_unref(ret);
1059 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1060 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1062 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1063 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1065 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1066 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1068 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1069 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1070 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1071 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1072 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1073 NULL, 0, TRUE, NULL, NULL);
1074 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1075 NULL, 0, TRUE, NULL, NULL);
1077 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1079 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1080 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1081 *slot_id, // filter_index
1083 0, // company_id_mask
1084 arr_uuid_param, // p_uuid
1085 arr_uuid_mask_param, // p_uuid_mask
1088 arr_data_param, // p_data
1089 arr_data_mask_param);
1091 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1092 param, G_DBUS_CALL_FLAGS_NONE,
1096 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1097 g_clear_error(&error);
1100 g_variant_unref(ret);
1102 g_array_free(arr_uuid, TRUE);
1103 g_array_free(arr_uuid_mask, TRUE);
1106 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1107 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1109 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1110 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1112 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1113 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1115 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1116 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1117 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1118 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1119 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1120 NULL, 0, TRUE, NULL, NULL);
1121 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1122 NULL, 0, TRUE, NULL, NULL);
1124 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1126 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1127 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1128 *slot_id, // filter_index
1130 0, // company_id_mask
1131 arr_uuid_param, // p_uuid
1132 arr_uuid_mask_param, // p_uuid_mask
1135 arr_data_param, // p_data
1136 arr_data_mask_param);
1138 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1139 G_DBUS_CALL_FLAGS_NONE,
1143 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1144 g_clear_error(&error);
1147 g_variant_unref(ret);
1149 g_array_free(arr_uuid, TRUE);
1150 g_array_free(arr_uuid_mask, TRUE);
1153 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1154 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1156 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1157 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1159 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1160 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1162 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1163 NULL, 0, TRUE, NULL, NULL);
1164 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1165 NULL, 0, TRUE, NULL, NULL);
1166 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1167 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1168 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1169 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1171 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1173 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1174 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1175 *slot_id, // filter_index
1177 0, // company_id_mask
1178 arr_uuid_param, // p_uuid
1179 arr_uuid_mask_param, // p_uuid_mask
1182 arr_data_param, // p_data
1183 arr_data_mask_param);
1185 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1186 G_DBUS_CALL_FLAGS_NONE,
1190 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1191 g_clear_error(&error);
1194 g_variant_unref(ret);
1196 g_array_free(arr_data, TRUE);
1197 g_array_free(arr_data_mask, TRUE);
1200 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1201 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1203 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1204 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1206 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1207 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1209 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1210 NULL, 0, TRUE, NULL, NULL);
1211 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1212 NULL, 0, TRUE, NULL, NULL);
1213 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1214 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1215 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1216 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1218 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1220 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1221 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1222 *slot_id, // filter_index
1223 filter->manufacturer_id, // company_id
1224 0xFFFF, // company_id_mask
1225 arr_uuid_param, // p_uuid
1226 arr_uuid_mask_param, // p_uuid_mask
1229 arr_data_param, // p_data
1230 arr_data_mask_param);
1232 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1233 G_DBUS_CALL_FLAGS_NONE,
1237 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1238 g_clear_error(&error);
1241 g_variant_unref(ret);
1243 g_array_free(arr_data, TRUE);
1244 g_array_free(arr_data_mask, TRUE);
1247 BT_DBG("Filter selection %.2x", feature_selection);
1249 param = g_variant_new("(iiiiiiiiiiii)",
1251 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1252 *slot_id, // filter_index
1253 feature_selection, // feat_seln
1254 0, // list_logic_type (OR - 0x00, AND - 0x01)
1255 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1256 -127, // rssi_high_thres
1257 -127, // rssi_low_thres
1258 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1261 0); // found_timeout_cnt
1262 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1263 param, G_DBUS_CALL_FLAGS_NONE,
1267 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1268 g_clear_error(&error);
1271 scanner = __bt_find_scanner_from_list(sender);
1272 if (scanner == NULL) {
1273 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1274 scanner->sender = g_strdup(sender);
1275 scanner_list = g_slist_append(scanner_list, scanner);
1280 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1281 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1282 filter_data->slot_id = *slot_id;
1284 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1288 g_variant_unref(ret);
1289 return BLUETOOTH_ERROR_NONE;
1292 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1295 GError *error = NULL;
1297 bt_adapter_le_scanner_t *scanner = NULL;
1298 bluetooth_le_scan_filter_t *filter_data = NULL;
1300 gboolean is_slot_id_found = FALSE;
1302 scanner = __bt_find_scanner_from_list(sender);
1303 if (scanner == NULL) {
1304 BT_ERR("There is NO available scanner.");
1305 return BLUETOOTH_ERROR_NOT_FOUND;
1308 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1309 filter_data = l->data;
1310 if (filter_data->slot_id == slot_id) {
1311 is_slot_id_found = TRUE;
1315 if (is_slot_id_found == FALSE) {
1316 BT_ERR("There is NO registered slot.");
1317 return BLUETOOTH_ERROR_NOT_FOUND;
1320 proxy = _bt_get_adapter_proxy();
1321 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1323 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1324 g_variant_new("(ii)", 0, slot_id),
1325 G_DBUS_CALL_FLAGS_NONE,
1329 BT_ERR("scan_filter_clear Fail: %s", error->message);
1330 g_clear_error(&error);
1333 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1334 g_free(filter_data);
1337 g_variant_unref(ret);
1338 return BLUETOOTH_ERROR_NONE;
1341 int _bt_unregister_all_scan_filters(const char *sender)
1344 GError *error = NULL;
1346 bt_adapter_le_scanner_t *scanner = NULL;
1347 bluetooth_le_scan_filter_t *filter_data = NULL;
1350 scanner = __bt_find_scanner_from_list(sender);
1351 if (scanner == NULL) {
1352 BT_ERR("There is NO available scanner.");
1353 return BLUETOOTH_ERROR_NOT_FOUND;
1356 proxy = _bt_get_adapter_proxy();
1357 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1359 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1360 filter_data = l->data;
1362 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1363 g_variant_new("(ii)", 0, filter_data->slot_id),
1364 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1367 BT_ERR("scan_filter_clear Fail: %s", error->message);
1368 g_clear_error(&error);
1371 g_variant_unref(ret);
1374 g_slist_free_full(scanner->filter_list, g_free);
1375 scanner->filter_list = NULL;
1377 return BLUETOOTH_ERROR_NONE;
1380 int _bt_start_le_scan(const char *sender)
1383 GError *error = NULL;
1385 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1387 if (scanner == NULL) {
1388 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1389 scanner->sender = g_strdup(sender);
1390 scanner_list = g_slist_append(scanner_list, scanner);
1393 if (scanner->is_scanning == TRUE) {
1394 BT_ERR("BT is already in LE scanning");
1395 return BLUETOOTH_ERROR_IN_PROGRESS;
1397 scanner->is_scanning = TRUE;
1399 proxy = _bt_get_adapter_proxy();
1400 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1402 if (_bt_is_le_scanning()) {
1403 if (scan_filter_enabled == TRUE) {
1404 if (scanner->filter_list == NULL) {
1405 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1406 g_variant_new("(ib)", 0, FALSE),
1407 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1410 BT_ERR("scan_filter_clear Fail: %s", error->message);
1411 g_clear_error(&error);
1415 g_variant_unref(ret);
1416 BT_INFO("Disable LE Scan Filter");
1417 scan_filter_enabled = FALSE;
1419 BT_INFO("LE Filter Scan is continue");
1422 BT_INFO("LE Full Scan is already on progress");
1424 return BLUETOOTH_ERROR_NONE;
1426 if (is_le_set_scan_parameter == FALSE) {
1427 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1428 bluetooth_le_scan_params_t scan_params;
1429 scan_params.type = BT_LE_ACTIVE_SCAN;
1430 scan_params.interval = 5000;
1431 scan_params.window = 500;
1432 _bt_set_scan_parameters(&scan_params);
1435 if (scanner->filter_list == NULL) {
1436 BT_INFO("Start LE Full Scan");
1437 scan_filter_enabled = FALSE;
1439 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1440 g_variant_new("(ib)", 0, TRUE),
1441 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1444 BT_ERR("scan_filter_clear Fail: %s", error->message);
1445 g_clear_error(&error);
1449 g_variant_unref(ret);
1450 BT_INFO("Enable LE Scan Filter");
1451 scan_filter_enabled = TRUE;
1455 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1456 NULL, G_DBUS_CALL_FLAGS_NONE,
1460 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1461 g_clear_error(&error);
1462 return BLUETOOTH_ERROR_INTERNAL;
1466 g_variant_unref(ret);
1467 return BLUETOOTH_ERROR_NONE;
1470 int _bt_stop_le_scan(const char *sender)
1473 GError *error = NULL;
1475 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1477 gboolean next_scanning = FALSE;
1478 gboolean need_scan_filter = TRUE;
1480 if (scanner == NULL || scanner->is_scanning == FALSE)
1481 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1483 scanner->is_scanning = FALSE;
1485 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1487 if (scanner->is_scanning == TRUE) {
1488 next_scanning = TRUE;
1489 if (scanner->filter_list == NULL)
1490 need_scan_filter = FALSE;
1494 proxy = _bt_get_adapter_proxy();
1495 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1497 if (next_scanning == TRUE) {
1498 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1499 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1500 g_variant_new("(ib)", 0, TRUE),
1501 G_DBUS_CALL_FLAGS_NONE,
1505 BT_ERR("scan_filter_clear Fail: %s", error->message);
1506 g_clear_error(&error);
1510 g_variant_unref(ret);
1511 BT_INFO("Enable LE Scan Filter");
1512 scan_filter_enabled = TRUE;
1514 return BLUETOOTH_ERROR_NONE;
1516 if (scan_filter_enabled == TRUE) {
1517 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1518 g_variant_new("(ib)", 0, FALSE),
1519 G_DBUS_CALL_FLAGS_NONE,
1523 BT_ERR("scan_filter_clear Fail: %s", error->message);
1524 g_clear_error(&error);
1528 g_variant_unref(ret);
1529 BT_INFO("Disable LE Scan Filter");
1531 BT_INFO("Just stop LE scan");
1535 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1536 NULL, G_DBUS_CALL_FLAGS_NONE,
1539 BT_ERR("LE Scan stop failed");
1540 return BLUETOOTH_ERROR_INTERNAL;
1543 scan_filter_enabled = FALSE;
1544 is_le_set_scan_parameter = FALSE;
1546 g_variant_unref(ret);
1547 return BLUETOOTH_ERROR_NONE;
1550 void _bt_disable_all_scanner_status(void)
1553 bt_adapter_le_scanner_t *scanner;
1555 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1557 scanner->is_scanning = FALSE;
1561 void _bt_set_le_scan_status(gboolean mode)
1563 is_le_scanning = mode;
1566 gboolean _bt_is_le_scanning(void)
1568 return is_le_scanning;
1571 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1573 le_scan_type = type;
1576 bt_le_scan_type_t _bt_get_le_scan_type(void)
1578 return le_scan_type;
1581 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1582 int adv_data_len, const char *svc_uuid, int uuid_len,
1583 const char *uuid_mask, char ad_type)
1589 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1590 ad_type, &data, &data_len);
1592 for (i = 0; i < data_len; i += uuid_len) {
1593 if (uuid_len > (data_len - i))
1596 if (_bt_byte_arr_cmp_with_mask(data + i,
1597 svc_uuid, uuid_mask, uuid_len) == 0) {
1608 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1609 const char *adv_data, int adv_data_len,
1610 const char *scan_data, int scan_data_len,
1611 const bt_adapter_le_scanner_t *scanner)
1614 bluetooth_le_scan_filter_t *filter_data = NULL;
1617 gboolean is_matched = FALSE;
1619 if (scanner->filter_list == NULL) {
1620 BT_INFO("This scanner is on Full Scan.");
1624 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1625 filter_data = l->data;
1627 if (filter_data->added_features &
1628 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1629 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1631 _bt_convert_addr_type_to_string(address,
1632 filter_data->device_address.addr);
1633 if (strncmp(address, device_address,
1634 BT_ADDRESS_STRING_SIZE) != 0)
1638 if (filter_data->added_features &
1639 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1642 if (__bt_check_scan_result_uuid(adv_data,
1644 (char*)filter_data->service_uuid.data.data,
1645 filter_data->service_uuid.data_len,
1646 (char*)filter_data->service_uuid_mask.data.data,
1647 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1650 if (__bt_check_scan_result_uuid(adv_data,
1652 (char*)filter_data->service_uuid.data.data,
1653 filter_data->service_uuid.data_len,
1654 (char*)filter_data->service_uuid_mask.data.data,
1655 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1658 if (__bt_check_scan_result_uuid(adv_data,
1660 (char*)filter_data->service_uuid.data.data,
1661 filter_data->service_uuid.data_len,
1662 (char*)filter_data->service_uuid_mask.data.data,
1663 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1666 if (__bt_check_scan_result_uuid(adv_data,
1668 (char*)filter_data->service_uuid.data.data,
1669 filter_data->service_uuid.data_len,
1670 (char*)filter_data->service_uuid_mask.data.data,
1671 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1674 if (__bt_check_scan_result_uuid(scan_data,
1676 (char*)filter_data->service_uuid.data.data,
1677 filter_data->service_uuid.data_len,
1678 (char*)filter_data->service_uuid_mask.data.data,
1679 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1682 if (__bt_check_scan_result_uuid(scan_data,
1684 (char*)filter_data->service_uuid.data.data,
1685 filter_data->service_uuid.data_len,
1686 (char*)filter_data->service_uuid_mask.data.data,
1687 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1690 if (__bt_check_scan_result_uuid(scan_data,
1692 (char*)filter_data->service_uuid.data.data,
1693 filter_data->service_uuid.data_len,
1694 (char*)filter_data->service_uuid_mask.data.data,
1695 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1698 if (__bt_check_scan_result_uuid(scan_data,
1700 (char*)filter_data->service_uuid.data.data,
1701 filter_data->service_uuid.data_len,
1702 (char*)filter_data->service_uuid_mask.data.data,
1703 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1707 if (is_matched == FALSE)
1710 if (filter_data->added_features &
1711 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1714 if (__bt_check_scan_result_uuid(adv_data,
1716 (char*)filter_data->service_solicitation_uuid.data.data,
1717 filter_data->service_solicitation_uuid.data_len,
1718 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1719 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1722 if (__bt_check_scan_result_uuid(adv_data,
1724 (char*)filter_data->service_solicitation_uuid.data.data,
1725 filter_data->service_solicitation_uuid.data_len,
1726 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1727 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1730 if (__bt_check_scan_result_uuid(scan_data,
1732 (char*)filter_data->service_solicitation_uuid.data.data,
1733 filter_data->service_solicitation_uuid.data_len,
1734 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1735 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1738 if (__bt_check_scan_result_uuid(scan_data,
1740 (char*)filter_data->service_solicitation_uuid.data.data,
1741 filter_data->service_solicitation_uuid.data_len,
1742 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1743 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1747 if (is_matched == FALSE)
1750 if (filter_data->added_features &
1751 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1752 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1757 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1758 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1761 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1762 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1763 memcpy(name, data, data_len);
1764 name[data_len] = '\0';
1767 if (strncmp(filter_data->device_name,
1768 name, data_len) == 0)
1771 __bt_get_ad_data_by_type((char*)scan_data,
1773 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1776 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1777 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1778 memcpy(name, data, data_len);
1779 name[data_len] = '\0';
1782 if (strncmp(filter_data->device_name,
1783 name, data_len) == 0)
1787 if (is_matched == FALSE)
1790 if (filter_data->added_features &
1791 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1796 __bt_get_ad_data_by_type((char*)adv_data,
1798 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1802 int manufacturer_id;
1803 manufacturer_id = (data[1] << 8) + data[0];
1805 if (filter_data->manufacturer_id == manufacturer_id) {
1806 if (filter_data->manufacturer_data.data_len == 0) {
1809 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1810 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1811 if (_bt_byte_arr_cmp_with_mask(data + 2,
1812 (char*)filter_data->manufacturer_data.data.data,
1813 (char*)filter_data->manufacturer_data_mask.data.data,
1814 data_len - 2) == 0) {
1822 __bt_get_ad_data_by_type((char*)scan_data,
1824 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1828 int manufacturer_id;
1829 manufacturer_id = (data[1] << 8) + data[0];
1831 if (filter_data->manufacturer_id == manufacturer_id) {
1832 if (filter_data->manufacturer_data.data_len == 0) {
1835 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1836 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1837 if (_bt_byte_arr_cmp_with_mask(data + 2,
1838 (char*)filter_data->manufacturer_data.data.data,
1839 (char*)filter_data->manufacturer_data_mask.data.data,
1840 data_len - 2) == 0) {
1849 if (is_matched == FALSE)
1852 if (filter_data->added_features &
1853 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1858 __bt_get_ad_data_by_type((char*)adv_data,
1860 BT_LE_AD_TYPE_SERVICE_DATA,
1863 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1864 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1865 if (_bt_byte_arr_cmp_with_mask(data,
1866 (char*)filter_data->service_data.data.data,
1867 (char*)filter_data->service_data_mask.data.data,
1874 __bt_get_ad_data_by_type((char*)scan_data,
1876 BT_LE_AD_TYPE_SERVICE_DATA,
1879 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1880 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1881 if (_bt_byte_arr_cmp_with_mask(data,
1882 (char*)filter_data->service_data.data.data,
1883 (char*)filter_data->service_data_mask.data.data,
1891 if (is_matched == FALSE)
1895 BT_INFO("The scan result is conformable.");
1899 BT_INFO("The scan result is NOT conformable.");
1903 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1904 const bt_le_adv_info_t *adv_info)
1906 int result = BLUETOOTH_ERROR_NONE;
1908 GVariant *scan_data_param, *adv_data_param;
1910 bt_adapter_le_scanner_t *scanner = NULL;
1911 const char *adv_data = NULL;
1912 int adv_data_len = 0;
1913 const char *scan_data = NULL;
1914 int scan_data_len = 0;
1916 ret_if(le_dev_info == NULL);
1917 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1918 ret_if(adv_info == NULL);
1920 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1921 adv_data = le_dev_info->adv_data;
1922 adv_data_len = le_dev_info->adv_data_len;
1923 scan_data = le_dev_info->adv_data;
1926 adv_data = adv_info->data;
1927 adv_data_len = adv_info->data_len;
1928 scan_data = le_dev_info->adv_data;
1929 scan_data_len = le_dev_info->adv_data_len;
1932 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1934 if (scanner->is_scanning == FALSE)
1937 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1938 adv_data, adv_data_len, scan_data, scan_data_len,
1942 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1943 adv_data, adv_data_len, TRUE, NULL, NULL);
1944 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1945 scan_data, scan_data_len, TRUE, NULL, NULL);
1947 param = g_variant_new("(isnnn@ayn@ay)",
1949 le_dev_info->address,
1950 le_dev_info->addr_type,
1958 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1959 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1961 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1966 void _bt_send_ibeacon_scan_result_event(const bt_remote_ibeacon_dev_info_t *ibeacon_dev_info)
1968 int result = BLUETOOTH_ERROR_NONE;
1971 bt_adapter_le_scanner_t *scanner = NULL;
1973 ret_if(ibeacon_dev_info == NULL);
1974 BT_DBG("_bt_send_ibeacon_scan_result_event");
1976 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1978 if (scanner->is_scanning == FALSE)
1981 param = g_variant_new("(isnnnsnnn)",
1983 ibeacon_dev_info->address,
1984 ibeacon_dev_info->addr_type,
1985 ibeacon_dev_info->company_id,
1986 ibeacon_dev_info->ibeacon_type,
1987 ibeacon_dev_info->uuid,
1988 ibeacon_dev_info->major_id,
1989 ibeacon_dev_info->minor_id,
1990 ibeacon_dev_info->measured_power);
1992 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_IBEACON_DEVICE_FOUND, param);
1996 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1999 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2000 GError *error = NULL;
2003 if (__bt_is_factory_test_mode()) {
2004 BT_ERR("Unable to add white list in factory binary !!");
2005 return BLUETOOTH_ERROR_NOT_SUPPORT;
2008 BT_CHECK_PARAMETER(device_address, return);
2010 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2011 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2012 return BLUETOOTH_ERROR_INVALID_PARAM;
2014 _bt_convert_addr_type_to_string(address, device_address->addr);
2016 proxy = _bt_get_adapter_proxy();
2017 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2019 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
2020 g_variant_new("(su)", address, address_type),
2021 G_DBUS_CALL_FLAGS_NONE, -1,
2025 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
2026 g_clear_error(&error);
2027 return BLUETOOTH_ERROR_INTERNAL;
2031 g_variant_unref(ret);
2032 BT_INFO("Add white list");
2034 return BLUETOOTH_ERROR_NONE;
2037 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2040 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2041 GError *error = NULL;
2044 if (__bt_is_factory_test_mode()) {
2045 BT_ERR("Unable to remove white list in factory binary !!");
2046 return BLUETOOTH_ERROR_NOT_SUPPORT;
2049 BT_CHECK_PARAMETER(device_address, return);
2051 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2052 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2053 return BLUETOOTH_ERROR_INVALID_PARAM;
2055 _bt_convert_addr_type_to_string(address, device_address->addr);
2057 proxy = _bt_get_adapter_proxy();
2058 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2060 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
2061 g_variant_new("(su)", address, address_type),
2062 G_DBUS_CALL_FLAGS_NONE, -1,
2066 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2067 g_clear_error(&error);
2068 return BLUETOOTH_ERROR_INTERNAL;
2072 g_variant_unref(ret);
2073 BT_INFO("Remove white list");
2075 return BLUETOOTH_ERROR_NONE;
2078 int _bt_clear_white_list(void)
2081 GError *error = NULL;
2084 if (__bt_is_factory_test_mode()) {
2085 BT_ERR("Unable to clear white list in factory binary !!");
2086 return BLUETOOTH_ERROR_NOT_SUPPORT;
2089 proxy = _bt_get_adapter_proxy();
2090 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2092 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2093 NULL, G_DBUS_CALL_FLAGS_NONE,
2097 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2098 g_clear_error(&error);
2099 return BLUETOOTH_ERROR_INTERNAL;
2102 g_variant_unref(ret);
2104 BT_INFO("Clear white list");
2106 return BLUETOOTH_ERROR_NONE;
2109 int _bt_initialize_ipsp(void)
2113 GError *error = NULL;
2116 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2117 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2118 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2121 proxy = _bt_get_adapter_proxy();
2122 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2124 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2125 NULL, G_DBUS_CALL_FLAGS_NONE,
2128 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2129 g_clear_error(&error);
2130 return BLUETOOTH_ERROR_INTERNAL;
2133 g_variant_unref(ret);
2135 BT_INFO("IPSP initialization called successfully");
2137 return BLUETOOTH_ERROR_NONE;
2140 int _bt_deinitialize_ipsp(void)
2144 GError *error = NULL;
2147 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2148 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2149 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2152 proxy = _bt_get_adapter_proxy();
2153 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2155 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2156 NULL, G_DBUS_CALL_FLAGS_NONE,
2159 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2160 g_clear_error(&error);
2161 return BLUETOOTH_ERROR_INTERNAL;
2164 g_variant_unref(ret);
2166 BT_INFO("IPSP De-initialization called successfully");
2168 return BLUETOOTH_ERROR_NONE;
2171 int _bt_le_read_maximum_data_length(
2172 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2174 GError *error = NULL;
2176 GVariant *reply = NULL;
2177 guint16 max_tx_octets, max_tx_time;
2178 guint16 max_rx_octets, max_rx_time;
2180 proxy = _bt_get_adapter_proxy();
2181 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2183 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2184 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2186 if (reply == NULL) {
2187 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2188 if (error != NULL) {
2189 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2190 error->code, error->message);
2191 g_clear_error(&error);
2193 return BLUETOOTH_ERROR_INTERNAL;
2196 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2197 &max_rx_octets, &max_rx_time);
2199 max_le_datalength->max_tx_octets = max_tx_octets;
2200 max_le_datalength->max_tx_time = max_tx_time;
2201 max_le_datalength->max_rx_octets = max_rx_octets;
2202 max_le_datalength->max_rx_time = max_rx_time;
2204 g_variant_unref(reply);
2206 return BLUETOOTH_ERROR_NONE;
2208 int _bt_le_write_host_suggested_default_data_length(
2209 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2211 GError *error = NULL;
2213 GVariant *reply = NULL;
2215 proxy = _bt_get_adapter_proxy();
2216 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2218 reply = g_dbus_proxy_call_sync(proxy,
2219 "LEWriteHostSuggestedDataLength",
2220 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2221 G_DBUS_CALL_FLAGS_NONE,
2226 if (reply == NULL) {
2227 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2228 if (error != NULL) {
2229 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2230 error->code, error->message);
2231 g_clear_error(&error);
2233 return BLUETOOTH_ERROR_INTERNAL;
2236 g_variant_unref(reply);
2238 return BLUETOOTH_ERROR_NONE;
2241 int _bt_le_read_host_suggested_default_data_length(
2242 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2244 GError *error = NULL;
2246 GVariant *reply = NULL;
2247 guint16 def_tx_octets, def_tx_time;
2249 proxy = _bt_get_adapter_proxy();
2250 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2252 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2253 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2255 if (reply == NULL) {
2256 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2257 if (error != NULL) {
2258 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2259 error->code, error->message);
2260 g_clear_error(&error);
2262 return BLUETOOTH_ERROR_INTERNAL;
2265 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2267 def_data_length->def_tx_octets = def_tx_octets;
2268 def_data_length->def_tx_time = def_tx_time;
2270 g_variant_unref(reply);
2272 return BLUETOOTH_ERROR_NONE;
2275 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2276 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2278 GError *error = NULL;
2279 guint16 txOctets = max_tx_Octets;
2280 guint16 txTime = max_tx_Time;
2281 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2282 gchar *device_path = NULL;
2283 GDBusConnection *conn;
2284 GDBusProxy *device_proxy;
2286 _bt_convert_addr_type_to_string(address, device_address->addr);
2288 device_path = _bt_get_device_object_path(address);
2290 if (device_path == NULL) {
2291 BT_DBG("Device path is null");
2292 return BLUETOOTH_ERROR_INTERNAL;
2295 conn = _bt_gdbus_get_system_gconn();
2297 BT_ERR("conn == NULL");
2298 g_free(device_path);
2299 return BLUETOOTH_ERROR_INTERNAL;
2302 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2303 NULL, BT_BLUEZ_NAME,
2304 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2306 g_free(device_path);
2307 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2309 g_dbus_proxy_call_sync(device_proxy,
2311 g_variant_new("(qq)", txOctets, txTime),
2312 G_DBUS_CALL_FLAGS_NONE,
2317 g_object_unref(device_proxy);
2320 BT_ERR("LESetDataLength error: [%s]", error->message);
2321 g_error_free(error);
2322 return BLUETOOTH_ERROR_INTERNAL;
2325 return BLUETOOTH_ERROR_NONE;