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_le_set_max_packet_len(void)
182 int result = BLUETOOTH_ERROR_NONE;
183 int tx_octets, tx_time;
184 bluetooth_le_read_maximum_data_length_t max_len = {0};
186 if (BLUETOOTH_ERROR_NONE != _bt_le_read_maximum_data_length(&max_len))
187 return BLUETOOTH_ERROR_INTERNAL;
189 if (max_len.max_tx_octets > BT_LE_TX_LEN_DEFAULT) {
190 tx_octets = max_len.max_tx_octets > BT_LE_TX_LEN_MAX ?
191 BT_LE_TX_LEN_MAX : max_len.max_tx_octets;
192 tx_time = BT_LE_TX_TIME_MAX;
194 result = _bt_le_write_host_suggested_default_data_length(tx_octets, tx_time);
196 BT_DBG("Wrote max packet size : result[%d], MAX[%d], set[%d]",
197 result, max_len.max_tx_octets, tx_octets);
203 gboolean _bt_update_le_feature_support(const char *item, const char *value)
205 if (item == NULL || value == NULL)
209 _bt_service_adapter_le_init();
211 if (g_strcmp0(item, "adv_inst_max") == 0) {
214 slot_num = atoi(value);
215 retv_if(slot_num < 0, FALSE);
217 if (slot_num != le_feature_info.adv_inst_max) {
218 __bt_free_le_adv_slot();
219 le_feature_info.adv_inst_max = slot_num;
220 BT_INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
221 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
223 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
224 le_feature_info.rpa_offloading = atoi(value);
225 BT_INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
226 } else if (g_strcmp0(item, "max_filter") == 0) {
227 le_feature_info.max_filter = atoi(value);
228 BT_INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
230 BT_DBG("No registered item");
237 static gboolean __bt_is_factory_test_mode(void)
241 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
242 BT_ERR("Get the DUT Mode fail");
247 BT_INFO("DUT Test Mode !!");
254 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
258 if (le_adv_slot == NULL) {
259 BT_ERR("le_adv_slot is NULL");
263 BT_DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
265 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
266 if (le_adv_slot[i].sender == NULL)
268 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
272 if (le_feature_info.adv_inst_max <= 2)
274 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
279 for (; i < le_feature_info.adv_inst_max; i++) {
280 if (le_adv_slot[i].sender == NULL)
287 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
289 if (le_adv_slot[slot_id].sender == NULL) {
290 le_adv_slot[slot_id].sender = strdup(sender);
291 le_adv_slot[slot_id].adv_handle = adv_handle;
295 void _bt_unregister_adv_slot_owner(int slot_id)
297 if (le_adv_slot[slot_id].hold_timer_id > 0) {
298 BT_INFO("Hold state adv is not unregistered");
302 g_free(le_adv_slot[slot_id].sender);
303 le_adv_slot[slot_id].sender = NULL;
304 le_adv_slot[slot_id].adv_handle = 0;
307 const char* _bt_get_adv_slot_owner(int slot_id)
309 if (le_adv_slot == NULL)
312 return le_adv_slot[slot_id].sender;
315 int _bt_get_adv_slot_adv_handle(int slot_id)
317 if (le_adv_slot == NULL)
320 return le_adv_slot[slot_id].adv_handle;
323 void _bt_set_advertising_status(int slot_id, gboolean mode)
325 le_adv_slot[slot_id].is_advertising = mode;
328 gboolean _bt_is_advertising(void)
330 gboolean status = FALSE;
333 if (le_adv_slot == NULL)
336 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
337 if (le_adv_slot[i].is_advertising == TRUE)
344 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
348 if (le_adv_slot == NULL)
351 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
352 if (le_adv_slot[i].sender != NULL) {
353 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
354 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
355 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
361 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
366 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
371 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
374 GError *error = NULL;
378 if (__bt_is_factory_test_mode()) {
379 BT_ERR("Unable to start advertising in factory binary !!");
380 return BLUETOOTH_ERROR_NOT_SUPPORT;
383 if (_bt_adapter_get_status() != BT_ACTIVATED &&
384 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
385 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
388 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
390 BT_ERR("There is NO available slot!!");
391 return BLUETOOTH_ERROR_NO_RESOURCES;
394 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
395 return BLUETOOTH_ERROR_IN_PROGRESS;
397 if (le_adv_slot[slot_id].hold_timer_id > 0) {
398 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
399 le_adv_slot[slot_id].hold_timer_id = 0;
400 _bt_unregister_adv_slot_owner(slot_id);
403 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
404 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
406 proxy = _bt_get_adapter_proxy();
407 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
409 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
410 g_variant_new("(bi)", enable, slot_id),
411 G_DBUS_CALL_FLAGS_NONE,
417 BT_ERR("SetAdvertising Fail: %s", error->message);
418 g_clear_error(&error);
419 return BLUETOOTH_ERROR_INTERNAL;
423 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
425 le_adv_slot[slot_id].is_advertising = enable;
426 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
429 g_variant_unref(ret);
431 return BLUETOOTH_ERROR_NONE;
434 int _bt_set_custom_advertising(const char *sender, int adv_handle,
435 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
439 GError *error = NULL;
444 BT_CHECK_PARAMETER(params, return);
446 if (__bt_is_factory_test_mode()) {
447 BT_ERR("Unable to start advertising in factory binary !!");
448 return BLUETOOTH_ERROR_NOT_SUPPORT;
451 if (_bt_adapter_get_status() != BT_ACTIVATED &&
452 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
453 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
456 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
458 BT_ERR("There is NO available slot!!");
459 return BLUETOOTH_ERROR_NO_RESOURCES;
462 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
463 return BLUETOOTH_ERROR_IN_PROGRESS;
465 if (le_adv_slot[slot_id].hold_timer_id > 0) {
466 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
467 le_adv_slot[slot_id].hold_timer_id = 0;
468 _bt_unregister_adv_slot_owner(slot_id);
471 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
472 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
474 proxy = _bt_get_adapter_proxy();
475 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
477 if (params->interval_min > params->interval_max ||
478 params->interval_min < BT_ADV_INTERVAL_MIN ||
479 params->interval_max > BT_ADV_INTERVAL_MAX)
480 return BLUETOOTH_ERROR_INVALID_PARAM;
482 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
483 return BLUETOOTH_ERROR_INVALID_PARAM;
485 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
486 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
487 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
488 return BLUETOOTH_ERROR_NOT_SUPPORT;
490 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
491 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
493 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
494 g_variant_new("(uuuui)", min, max,
495 params->filter_policy, params->type,
496 slot_id), G_DBUS_CALL_FLAGS_NONE,
500 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
501 g_clear_error(&error);
502 return BLUETOOTH_ERROR_INTERNAL;
505 adv_params.interval_min = params->interval_min;
506 adv_params.interval_max = params->interval_max;
507 adv_params.filter_policy = params->filter_policy;
508 adv_params.type = params->type;
511 g_variant_unref(ret);
513 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
514 g_variant_new("(bi)", enable, slot_id),
515 G_DBUS_CALL_FLAGS_NONE,
521 BT_ERR("SetAdvertising Fail: %s", error->message);
522 g_clear_error(&error);
523 return BLUETOOTH_ERROR_INTERNAL;
527 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
529 le_adv_slot[slot_id].is_advertising = enable;
530 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
532 g_variant_unref(ret);
534 return BLUETOOTH_ERROR_NONE;
537 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
540 GError *error = NULL;
543 BT_INFO("Restart advertising stopped by bt-service");
545 le_adv_slot[0].hold_timer_id = 0;
547 proxy = _bt_get_adapter_proxy();
548 retv_if(proxy == NULL, FALSE);
550 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
551 g_variant_new("(bi)", TRUE, 0),
552 G_DBUS_CALL_FLAGS_NONE,
558 BT_ERR("SetAdvertising Fail: %s", error->message);
559 g_clear_error(&error);
564 g_variant_unref(ret);
569 int _bt_hold_current_advertising(void)
572 GError *error = NULL;
575 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
576 BT_INFO("Stop current advertising by bt-service");
578 proxy = _bt_get_adapter_proxy();
579 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
581 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
582 g_variant_new("(bi)", FALSE, 0),
583 G_DBUS_CALL_FLAGS_NONE,
589 BT_ERR("SetAdvertising Fail: %s", error->message);
590 g_clear_error(&error);
591 return BLUETOOTH_ERROR_INTERNAL;
595 g_variant_unref(ret);
597 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
598 __bt_hold_current_advertising_timeout_cb, NULL);
600 BT_INFO("It's NOT advertising");
601 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
604 return BLUETOOTH_ERROR_NONE;
607 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
608 char in_type, char **data, int *data_len)
610 if (in_data == NULL || data == NULL || data_len == NULL)
611 return BLUETOOTH_ERROR_INTERNAL;
614 return BLUETOOTH_ERROR_INTERNAL;
620 for (i = 0; i < in_len; i++) {
622 if (len <= 0 || i + 1 >= in_len) {
623 BT_ERR("Invalid advertising data");
624 return BLUETOOTH_ERROR_INTERNAL;
627 type = in_data[i + 1];
628 if (type == in_type) {
638 if (i + len > in_len) {
639 BT_ERR("Invalid advertising data");
640 return BLUETOOTH_ERROR_INTERNAL;
641 } else if (len == 0) {
642 BT_DBG("AD Type 0x%02x data is not set", in_type);
645 return BLUETOOTH_ERROR_NONE;
648 *data = g_memdup(&in_data[i], len);
650 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
653 return BLUETOOTH_ERROR_NONE;
656 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
658 BT_CHECK_PARAMETER(adv, return);
659 BT_CHECK_PARAMETER(length, return);
661 memcpy(adv, &adv_data, sizeof(adv_data));
662 *length = adv_data_len;
664 return BLUETOOTH_ERROR_NONE;
667 int _bt_set_advertising_data(const char *sender, int adv_handle,
668 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
671 GError *error = NULL;
672 GVariant *ret, *ad_data, *param = NULL;
673 GVariant *temp = NULL;
674 GVariantBuilder *builder;
676 char *old_mdata = NULL;
677 char *new_mdata = NULL;
682 if (__bt_is_factory_test_mode()) {
683 BT_ERR("Unable to set advertising data in factory binary !!");
684 return BLUETOOTH_ERROR_NOT_SUPPORT;
687 BT_CHECK_PARAMETER(adv, return);
689 if (_bt_adapter_get_status() != BT_ACTIVATED &&
690 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
691 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
694 proxy = _bt_get_adapter_proxy();
695 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
697 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
699 BT_ERR("There is NO available slot!!");
700 return BLUETOOTH_ERROR_NO_RESOURCES;
703 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
704 for (i = 0; i < length; i++)
705 g_variant_builder_add(builder, "y", adv->data[i]);
707 temp = g_variant_new("ay", builder);
708 g_variant_builder_unref(builder);
709 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
710 g_variant_new("(@ayi)", temp, slot_id),
711 G_DBUS_CALL_FLAGS_NONE,
715 BT_ERR("SetAdvertisingData Fail: %s", error->message);
716 g_clear_error(&error);
717 return BLUETOOTH_ERROR_INTERNAL;
720 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
722 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
723 &old_mdata, &old_len);
724 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
725 &new_mdata, &new_len);
726 if (old_len != new_len ||
727 (old_mdata && new_mdata &&
728 memcmp(old_mdata, new_mdata, new_len))) {
729 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
730 new_mdata, new_len, TRUE, NULL, NULL);
731 param = g_variant_new("(@ay)", ad_data);
732 _bt_send_event(BT_ADAPTER_EVENT,
733 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
739 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
740 memcpy(&adv_data, adv, length);
741 adv_data_len = length;
743 BT_INFO("Set advertising data");
745 g_variant_unref(ret);
747 return BLUETOOTH_ERROR_NONE;
750 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
752 BT_CHECK_PARAMETER(response, return);
753 BT_CHECK_PARAMETER(length, return);
755 memcpy(response, &resp_data, sizeof(resp_data));
756 *length = resp_data_len;
758 return BLUETOOTH_ERROR_NONE;
761 int _bt_set_scan_response_data(const char *sender, int adv_handle,
762 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
765 GError *error = NULL;
766 GVariant *ret, *scan_data, *param = NULL;
767 GVariant *temp = NULL;
768 GVariantBuilder *builder;
770 char *old_mdata = NULL;
771 char *new_mdata = NULL;
776 if (__bt_is_factory_test_mode()) {
777 BT_ERR("Unable to set scan response list in factory binary !!");
778 return BLUETOOTH_ERROR_NOT_SUPPORT;
781 BT_CHECK_PARAMETER(response, return);
783 if (_bt_adapter_get_status() != BT_ACTIVATED &&
784 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
785 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
788 proxy = _bt_get_adapter_proxy();
789 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
791 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
793 BT_ERR("There is NO available slot!!");
794 return BLUETOOTH_ERROR_NO_RESOURCES;
796 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
797 for (i = 0; i < length; i++)
798 g_variant_builder_add(builder, "y", response->data[i]);
800 temp = g_variant_new("ay", builder);
801 g_variant_builder_unref(builder);
802 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
803 g_variant_new("(@ayi)", temp, slot_id),
804 G_DBUS_CALL_FLAGS_NONE,
808 BT_ERR("SetScanRespData Fail: %s", error->message);
809 g_clear_error(&error);
810 return BLUETOOTH_ERROR_INTERNAL;
813 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
815 /* Compare with previous scan resp data */
816 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
817 &old_mdata, &old_len);
818 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
819 &new_mdata, &new_len);
820 if (old_len != new_len ||
821 (old_mdata && new_mdata &&
822 memcmp(old_mdata, new_mdata, new_len))) {
823 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
824 new_mdata, new_len, TRUE, NULL, NULL);
825 param = g_variant_new("(@ay)", scan_data);
826 _bt_send_event(BT_ADAPTER_EVENT,
827 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
833 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
834 memcpy(&resp_data, response, length);
835 resp_data_len = length;
838 g_variant_unref(ret);
839 BT_INFO("Set scan response data");
840 return BLUETOOTH_ERROR_NONE;
843 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
846 GError *error = NULL;
851 BT_CHECK_PARAMETER(params, return);
853 if (_bt_adapter_get_status() != BT_ACTIVATED &&
854 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
855 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
858 proxy = _bt_get_adapter_proxy();
859 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
861 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
862 return BLUETOOTH_ERROR_INVALID_PARAM;
864 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
865 return BLUETOOTH_ERROR_INVALID_PARAM;
867 if (params->window > params->interval)
868 return BLUETOOTH_ERROR_INVALID_PARAM;
870 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
871 win = params->window / BT_ADV_INTERVAL_SPLIT;
873 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
874 g_variant_new("(uuu)", params->type, itv, win),
875 G_DBUS_CALL_FLAGS_NONE, -1,
879 BT_ERR("SetScanParameters Fail: %s", error->message);
880 g_clear_error(&error);
881 return BLUETOOTH_ERROR_INTERNAL;
884 _bt_set_le_scan_type(params->type);
886 is_le_set_scan_parameter = TRUE;
889 g_variant_unref(ret);
890 BT_INFO("Set scan parameters");
891 return BLUETOOTH_ERROR_NONE;
894 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
897 bt_adapter_le_scanner_t *scanner;
899 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
901 if (g_strcmp0(scanner->sender, sender) == 0)
908 int __bt_get_available_scan_filter_slot_id(void)
911 bt_adapter_le_scanner_t *scanner;
913 bluetooth_le_scan_filter_t *filter_data;
914 gboolean *slot_check_list = NULL;
917 if (le_feature_info.max_filter == 0) {
918 BT_ERR("Scan filter is NOT Supported");
921 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
923 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
925 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
926 filter_data = fl->data;
927 if (filter_data->slot_id < le_feature_info.max_filter)
928 slot_check_list[filter_data->slot_id] = TRUE;
932 for (i = 0; i < le_feature_info.max_filter; i++) {
933 if (slot_check_list[i] == FALSE) {
934 g_free(slot_check_list);
939 BT_ERR("There is NO available slot for scan filter.");
940 g_free(slot_check_list);
944 gboolean _bt_is_scan_filter_supported(void)
946 if (le_feature_info.max_filter > 0)
952 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
955 GError *error = NULL;
956 GVariant *ret, *param;
957 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
958 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
959 GArray *arr_uuid = NULL;
960 GArray *arr_uuid_mask = NULL;
961 GArray *arr_data = NULL;
962 GArray *arr_data_mask = NULL;
963 bt_adapter_le_scanner_t *scanner = NULL;
964 bluetooth_le_scan_filter_t *filter_data = NULL;
965 int feature_selection = 0;
967 *slot_id = __bt_get_available_scan_filter_slot_id();
969 return BLUETOOTH_ERROR_NO_RESOURCES;
971 proxy = _bt_get_adapter_proxy();
972 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
974 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
975 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
976 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
978 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
980 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
981 NULL, 0, TRUE, NULL, NULL);
982 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
983 NULL, 0, TRUE, NULL, NULL);
984 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
985 NULL, 0, TRUE, NULL, NULL);
986 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
987 NULL, 0, TRUE, NULL, NULL);
989 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
991 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
992 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
993 *slot_id, // filter_index
995 0, // company_id_mask
996 arr_uuid_param, // p_uuid
997 arr_uuid_mask_param, // p_uuid_mask
1000 arr_data_param, // p_data
1001 arr_data_mask_param); // p_mask
1003 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1004 param, G_DBUS_CALL_FLAGS_NONE,
1008 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1009 g_clear_error(&error);
1012 g_variant_unref(ret);
1015 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1016 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
1018 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1019 NULL, 0, TRUE, NULL, NULL);
1020 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1021 NULL, 0, TRUE, NULL, NULL);
1022 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1023 NULL, 0, TRUE, NULL, NULL);
1024 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1025 NULL, 0, TRUE, NULL, NULL);
1027 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1029 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1030 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1031 *slot_id, // filter_index
1033 0, // company_id_mask
1034 arr_uuid_param, // p_uuid
1035 arr_uuid_mask_param, // p_uuid_mask
1036 filter->device_name, // string
1038 arr_data_param, // p_data
1039 arr_data_mask_param);
1041 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1042 param, G_DBUS_CALL_FLAGS_NONE,
1046 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1047 g_clear_error(&error);
1050 g_variant_unref(ret);
1053 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1054 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1056 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1057 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1059 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1060 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1062 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1063 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1064 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1065 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1066 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1067 NULL, 0, TRUE, NULL, NULL);
1068 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1069 NULL, 0, TRUE, NULL, NULL);
1071 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1073 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1074 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1075 *slot_id, // filter_index
1077 0, // company_id_mask
1078 arr_uuid_param, // p_uuid
1079 arr_uuid_mask_param, // p_uuid_mask
1082 arr_data_param, // p_data
1083 arr_data_mask_param);
1085 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1086 param, G_DBUS_CALL_FLAGS_NONE,
1090 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1091 g_clear_error(&error);
1094 g_variant_unref(ret);
1096 g_array_free(arr_uuid, TRUE);
1097 g_array_free(arr_uuid_mask, TRUE);
1100 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1101 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1103 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1104 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1106 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1107 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1109 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1110 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1111 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1112 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1113 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1114 NULL, 0, TRUE, NULL, NULL);
1115 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1116 NULL, 0, TRUE, NULL, NULL);
1118 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1120 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1121 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1122 *slot_id, // filter_index
1124 0, // company_id_mask
1125 arr_uuid_param, // p_uuid
1126 arr_uuid_mask_param, // p_uuid_mask
1129 arr_data_param, // p_data
1130 arr_data_mask_param);
1132 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1133 G_DBUS_CALL_FLAGS_NONE,
1137 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1138 g_clear_error(&error);
1141 g_variant_unref(ret);
1143 g_array_free(arr_uuid, TRUE);
1144 g_array_free(arr_uuid_mask, TRUE);
1147 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1148 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1150 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1151 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1153 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1154 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1156 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1157 NULL, 0, TRUE, NULL, NULL);
1158 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1159 NULL, 0, TRUE, NULL, NULL);
1160 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1161 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1162 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1163 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1165 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1167 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1168 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1169 *slot_id, // filter_index
1171 0, // company_id_mask
1172 arr_uuid_param, // p_uuid
1173 arr_uuid_mask_param, // p_uuid_mask
1176 arr_data_param, // p_data
1177 arr_data_mask_param);
1179 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1180 G_DBUS_CALL_FLAGS_NONE,
1184 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1185 g_clear_error(&error);
1188 g_variant_unref(ret);
1190 g_array_free(arr_data, TRUE);
1191 g_array_free(arr_data_mask, TRUE);
1194 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1195 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1197 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1198 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1200 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1201 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1203 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1204 NULL, 0, TRUE, NULL, NULL);
1205 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1206 NULL, 0, TRUE, NULL, NULL);
1207 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1208 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1209 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1210 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1212 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1214 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1215 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1216 *slot_id, // filter_index
1217 filter->manufacturer_id, // company_id
1218 0xFFFF, // company_id_mask
1219 arr_uuid_param, // p_uuid
1220 arr_uuid_mask_param, // p_uuid_mask
1223 arr_data_param, // p_data
1224 arr_data_mask_param);
1226 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1227 G_DBUS_CALL_FLAGS_NONE,
1231 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1232 g_clear_error(&error);
1235 g_variant_unref(ret);
1237 g_array_free(arr_data, TRUE);
1238 g_array_free(arr_data_mask, TRUE);
1241 BT_DBG("Filter selection %.2x", feature_selection);
1243 param = g_variant_new("(iiiiiiiiiiii)",
1245 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1246 *slot_id, // filter_index
1247 feature_selection, // feat_seln
1248 0, // list_logic_type (OR - 0x00, AND - 0x01)
1249 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1250 -127, // rssi_high_thres
1251 -127, // rssi_low_thres
1252 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1255 0); // found_timeout_cnt
1256 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1257 param, G_DBUS_CALL_FLAGS_NONE,
1261 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1262 g_clear_error(&error);
1265 scanner = __bt_find_scanner_from_list(sender);
1266 if (scanner == NULL) {
1267 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1268 scanner->sender = g_strdup(sender);
1269 scanner_list = g_slist_append(scanner_list, scanner);
1274 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1275 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1276 filter_data->slot_id = *slot_id;
1278 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1282 g_variant_unref(ret);
1283 return BLUETOOTH_ERROR_NONE;
1286 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1289 GError *error = NULL;
1291 bt_adapter_le_scanner_t *scanner = NULL;
1292 bluetooth_le_scan_filter_t *filter_data = NULL;
1294 gboolean is_slot_id_found = FALSE;
1296 scanner = __bt_find_scanner_from_list(sender);
1297 if (scanner == NULL) {
1298 BT_ERR("There is NO available scanner.");
1299 return BLUETOOTH_ERROR_NOT_FOUND;
1302 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1303 filter_data = l->data;
1304 if (filter_data->slot_id == slot_id) {
1305 is_slot_id_found = TRUE;
1309 if (is_slot_id_found == FALSE) {
1310 BT_ERR("There is NO registered slot.");
1311 return BLUETOOTH_ERROR_NOT_FOUND;
1314 proxy = _bt_get_adapter_proxy();
1315 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1317 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1318 g_variant_new("(ii)", 0, slot_id),
1319 G_DBUS_CALL_FLAGS_NONE,
1323 BT_ERR("scan_filter_clear Fail: %s", error->message);
1324 g_clear_error(&error);
1327 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1328 g_free(filter_data);
1331 g_variant_unref(ret);
1332 return BLUETOOTH_ERROR_NONE;
1335 int _bt_unregister_all_scan_filters(const char *sender)
1338 GError *error = NULL;
1340 bt_adapter_le_scanner_t *scanner = NULL;
1341 bluetooth_le_scan_filter_t *filter_data = NULL;
1344 scanner = __bt_find_scanner_from_list(sender);
1345 if (scanner == NULL) {
1346 BT_ERR("There is NO available scanner.");
1347 return BLUETOOTH_ERROR_NOT_FOUND;
1350 proxy = _bt_get_adapter_proxy();
1351 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1353 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1354 filter_data = l->data;
1356 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1357 g_variant_new("(ii)", 0, filter_data->slot_id),
1358 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1361 BT_ERR("scan_filter_clear Fail: %s", error->message);
1362 g_clear_error(&error);
1365 g_variant_unref(ret);
1368 g_slist_free_full(scanner->filter_list, g_free);
1369 scanner->filter_list = NULL;
1371 return BLUETOOTH_ERROR_NONE;
1374 int _bt_start_le_scan(const char *sender)
1377 GError *error = NULL;
1379 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1381 if (scanner == NULL) {
1382 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1383 scanner->sender = g_strdup(sender);
1384 scanner_list = g_slist_append(scanner_list, scanner);
1387 if (scanner->is_scanning == TRUE) {
1388 BT_ERR("BT is already in LE scanning");
1389 return BLUETOOTH_ERROR_IN_PROGRESS;
1391 scanner->is_scanning = TRUE;
1393 proxy = _bt_get_adapter_proxy();
1394 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1396 if (_bt_is_le_scanning()) {
1397 if (scan_filter_enabled == TRUE) {
1398 if (scanner->filter_list == NULL) {
1399 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1400 g_variant_new("(ib)", 0, FALSE),
1401 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1404 BT_ERR("scan_filter_clear Fail: %s", error->message);
1405 g_clear_error(&error);
1409 g_variant_unref(ret);
1410 BT_INFO("Disable LE Scan Filter");
1411 scan_filter_enabled = FALSE;
1413 BT_INFO("LE Filter Scan is continue");
1416 BT_INFO("LE Full Scan is already on progress");
1418 return BLUETOOTH_ERROR_NONE;
1420 if (is_le_set_scan_parameter == FALSE) {
1421 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1422 bluetooth_le_scan_params_t scan_params;
1423 scan_params.type = BT_LE_ACTIVE_SCAN;
1424 scan_params.interval = 5000;
1425 scan_params.window = 500;
1426 _bt_set_scan_parameters(&scan_params);
1429 if (scanner->filter_list == NULL) {
1430 BT_INFO("Start LE Full Scan");
1431 scan_filter_enabled = FALSE;
1433 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1434 g_variant_new("(ib)", 0, TRUE),
1435 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1438 BT_ERR("scan_filter_clear Fail: %s", error->message);
1439 g_clear_error(&error);
1443 g_variant_unref(ret);
1444 BT_INFO("Enable LE Scan Filter");
1445 scan_filter_enabled = TRUE;
1449 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1450 NULL, G_DBUS_CALL_FLAGS_NONE,
1454 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1455 g_clear_error(&error);
1456 return BLUETOOTH_ERROR_INTERNAL;
1460 g_variant_unref(ret);
1461 return BLUETOOTH_ERROR_NONE;
1464 int _bt_stop_le_scan(const char *sender)
1467 GError *error = NULL;
1469 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1471 gboolean next_scanning = FALSE;
1472 gboolean need_scan_filter = TRUE;
1474 if (scanner == NULL || scanner->is_scanning == FALSE)
1475 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1477 scanner->is_scanning = FALSE;
1479 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1481 if (scanner->is_scanning == TRUE) {
1482 next_scanning = TRUE;
1483 if (scanner->filter_list == NULL)
1484 need_scan_filter = FALSE;
1488 proxy = _bt_get_adapter_proxy();
1489 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1491 if (next_scanning == TRUE) {
1492 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1493 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1494 g_variant_new("(ib)", 0, TRUE),
1495 G_DBUS_CALL_FLAGS_NONE,
1499 BT_ERR("scan_filter_clear Fail: %s", error->message);
1500 g_clear_error(&error);
1504 g_variant_unref(ret);
1505 BT_INFO("Enable LE Scan Filter");
1506 scan_filter_enabled = TRUE;
1508 return BLUETOOTH_ERROR_NONE;
1510 if (scan_filter_enabled == TRUE) {
1511 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1512 g_variant_new("(ib)", 0, FALSE),
1513 G_DBUS_CALL_FLAGS_NONE,
1517 BT_ERR("scan_filter_clear Fail: %s", error->message);
1518 g_clear_error(&error);
1522 g_variant_unref(ret);
1523 BT_INFO("Disable LE Scan Filter");
1525 BT_INFO("Just stop LE scan");
1529 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1530 NULL, G_DBUS_CALL_FLAGS_NONE,
1533 BT_ERR("LE Scan stop failed");
1534 return BLUETOOTH_ERROR_INTERNAL;
1537 scan_filter_enabled = FALSE;
1538 is_le_set_scan_parameter = FALSE;
1540 g_variant_unref(ret);
1541 return BLUETOOTH_ERROR_NONE;
1544 void _bt_disable_all_scanner_status(void)
1547 bt_adapter_le_scanner_t *scanner;
1549 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1551 scanner->is_scanning = FALSE;
1555 static void __bt_free_le_scanner(void)
1558 bt_adapter_le_scanner_t *scanner;
1560 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1562 g_free(scanner->sender);
1563 g_slist_free_full(scanner->filter_list, g_free);
1567 g_slist_free(scanner_list);
1568 scanner_list = NULL;
1570 scan_filter_enabled = FALSE;
1571 is_le_scanning = FALSE;
1572 is_le_set_scan_parameter = FALSE;
1575 void _bt_set_le_scan_status(gboolean mode)
1577 is_le_scanning = mode;
1580 gboolean _bt_is_le_scanning(void)
1582 return is_le_scanning;
1585 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1587 le_scan_type = type;
1590 bt_le_scan_type_t _bt_get_le_scan_type(void)
1592 return le_scan_type;
1595 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1596 int adv_data_len, const char *svc_uuid, int uuid_len,
1597 const char *uuid_mask, char ad_type)
1603 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1604 ad_type, &data, &data_len);
1606 for (i = 0; i < data_len; i += uuid_len) {
1607 if (uuid_len > (data_len - i))
1610 if (_bt_byte_arr_cmp_with_mask(data + i,
1611 svc_uuid, uuid_mask, uuid_len) == 0) {
1622 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1623 const char *adv_data, int adv_data_len,
1624 const char *scan_data, int scan_data_len,
1625 const bt_adapter_le_scanner_t *scanner)
1628 bluetooth_le_scan_filter_t *filter_data = NULL;
1631 gboolean is_matched = FALSE;
1633 if (scanner->filter_list == NULL) {
1634 BT_INFO("This scanner is on Full Scan.");
1638 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1639 filter_data = l->data;
1641 if (filter_data->added_features &
1642 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1643 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1645 _bt_convert_addr_type_to_string(address,
1646 filter_data->device_address.addr);
1647 if (strncmp(address, device_address,
1648 BT_ADDRESS_STRING_SIZE) != 0)
1652 if (filter_data->added_features &
1653 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1656 if (__bt_check_scan_result_uuid(adv_data,
1658 (char*)filter_data->service_uuid.data.data,
1659 filter_data->service_uuid.data_len,
1660 (char*)filter_data->service_uuid_mask.data.data,
1661 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1664 if (__bt_check_scan_result_uuid(adv_data,
1666 (char*)filter_data->service_uuid.data.data,
1667 filter_data->service_uuid.data_len,
1668 (char*)filter_data->service_uuid_mask.data.data,
1669 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1672 if (__bt_check_scan_result_uuid(adv_data,
1674 (char*)filter_data->service_uuid.data.data,
1675 filter_data->service_uuid.data_len,
1676 (char*)filter_data->service_uuid_mask.data.data,
1677 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1680 if (__bt_check_scan_result_uuid(adv_data,
1682 (char*)filter_data->service_uuid.data.data,
1683 filter_data->service_uuid.data_len,
1684 (char*)filter_data->service_uuid_mask.data.data,
1685 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1688 if (__bt_check_scan_result_uuid(scan_data,
1690 (char*)filter_data->service_uuid.data.data,
1691 filter_data->service_uuid.data_len,
1692 (char*)filter_data->service_uuid_mask.data.data,
1693 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1696 if (__bt_check_scan_result_uuid(scan_data,
1698 (char*)filter_data->service_uuid.data.data,
1699 filter_data->service_uuid.data_len,
1700 (char*)filter_data->service_uuid_mask.data.data,
1701 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1704 if (__bt_check_scan_result_uuid(scan_data,
1706 (char*)filter_data->service_uuid.data.data,
1707 filter_data->service_uuid.data_len,
1708 (char*)filter_data->service_uuid_mask.data.data,
1709 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1712 if (__bt_check_scan_result_uuid(scan_data,
1714 (char*)filter_data->service_uuid.data.data,
1715 filter_data->service_uuid.data_len,
1716 (char*)filter_data->service_uuid_mask.data.data,
1717 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1721 if (is_matched == FALSE)
1724 if (filter_data->added_features &
1725 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1728 if (__bt_check_scan_result_uuid(adv_data,
1730 (char*)filter_data->service_solicitation_uuid.data.data,
1731 filter_data->service_solicitation_uuid.data_len,
1732 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1733 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1736 if (__bt_check_scan_result_uuid(adv_data,
1738 (char*)filter_data->service_solicitation_uuid.data.data,
1739 filter_data->service_solicitation_uuid.data_len,
1740 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1741 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1744 if (__bt_check_scan_result_uuid(scan_data,
1746 (char*)filter_data->service_solicitation_uuid.data.data,
1747 filter_data->service_solicitation_uuid.data_len,
1748 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1749 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1752 if (__bt_check_scan_result_uuid(scan_data,
1754 (char*)filter_data->service_solicitation_uuid.data.data,
1755 filter_data->service_solicitation_uuid.data_len,
1756 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1757 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1761 if (is_matched == FALSE)
1764 if (filter_data->added_features &
1765 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1766 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1771 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1772 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1775 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1776 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1777 memcpy(name, data, data_len);
1778 name[data_len] = '\0';
1781 if (strncmp(filter_data->device_name,
1782 name, data_len) == 0)
1785 __bt_get_ad_data_by_type((char*)scan_data,
1787 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1790 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1791 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1792 memcpy(name, data, data_len);
1793 name[data_len] = '\0';
1796 if (strncmp(filter_data->device_name,
1797 name, data_len) == 0)
1801 if (is_matched == FALSE)
1804 if (filter_data->added_features &
1805 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1810 __bt_get_ad_data_by_type((char*)adv_data,
1812 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1816 int manufacturer_id;
1817 manufacturer_id = (data[1] << 8) + data[0];
1819 if (filter_data->manufacturer_id == manufacturer_id) {
1820 if (filter_data->manufacturer_data.data_len == 0) {
1823 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1824 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1825 if (_bt_byte_arr_cmp_with_mask(data + 2,
1826 (char*)filter_data->manufacturer_data.data.data,
1827 (char*)filter_data->manufacturer_data_mask.data.data,
1828 data_len - 2) == 0) {
1836 __bt_get_ad_data_by_type((char*)scan_data,
1838 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1842 int manufacturer_id;
1843 manufacturer_id = (data[1] << 8) + data[0];
1845 if (filter_data->manufacturer_id == manufacturer_id) {
1846 if (filter_data->manufacturer_data.data_len == 0) {
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 + 2,
1852 (char*)filter_data->manufacturer_data.data.data,
1853 (char*)filter_data->manufacturer_data_mask.data.data,
1854 data_len - 2) == 0) {
1863 if (is_matched == FALSE)
1866 if (filter_data->added_features &
1867 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1872 __bt_get_ad_data_by_type((char*)adv_data,
1874 BT_LE_AD_TYPE_SERVICE_DATA,
1877 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1878 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1879 if (_bt_byte_arr_cmp_with_mask(data,
1880 (char*)filter_data->service_data.data.data,
1881 (char*)filter_data->service_data_mask.data.data,
1888 __bt_get_ad_data_by_type((char*)scan_data,
1890 BT_LE_AD_TYPE_SERVICE_DATA,
1893 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1894 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1895 if (_bt_byte_arr_cmp_with_mask(data,
1896 (char*)filter_data->service_data.data.data,
1897 (char*)filter_data->service_data_mask.data.data,
1905 if (is_matched == FALSE)
1909 BT_INFO("The scan result is conformable.");
1913 BT_INFO("The scan result is NOT conformable.");
1917 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1918 const bt_le_adv_info_t *adv_info)
1920 int result = BLUETOOTH_ERROR_NONE;
1922 GVariant *scan_data_param, *adv_data_param;
1924 bt_adapter_le_scanner_t *scanner = NULL;
1925 const char *adv_data = NULL;
1926 int adv_data_len = 0;
1927 const char *scan_data = NULL;
1928 int scan_data_len = 0;
1930 ret_if(le_dev_info == NULL);
1931 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1932 ret_if(adv_info == NULL);
1934 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1935 adv_data = le_dev_info->adv_data;
1936 adv_data_len = le_dev_info->adv_data_len;
1937 scan_data = le_dev_info->adv_data;
1940 adv_data = adv_info->data;
1941 adv_data_len = adv_info->data_len;
1942 scan_data = le_dev_info->adv_data;
1943 scan_data_len = le_dev_info->adv_data_len;
1946 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1948 if (scanner->is_scanning == FALSE)
1951 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1952 adv_data, adv_data_len, scan_data, scan_data_len,
1956 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1957 adv_data, adv_data_len, TRUE, NULL, NULL);
1958 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1959 scan_data, scan_data_len, TRUE, NULL, NULL);
1961 param = g_variant_new("(isnnn@ayn@ay)",
1963 le_dev_info->address,
1964 le_dev_info->addr_type,
1972 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1973 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1975 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1980 void _bt_send_ibeacon_scan_result_event(const bt_remote_ibeacon_dev_info_t *ibeacon_dev_info)
1982 int result = BLUETOOTH_ERROR_NONE;
1985 bt_adapter_le_scanner_t *scanner = NULL;
1987 ret_if(ibeacon_dev_info == NULL);
1988 BT_DBG("_bt_send_ibeacon_scan_result_event");
1990 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1992 if (scanner->is_scanning == FALSE)
1995 param = g_variant_new("(isnnnsnnn)",
1997 ibeacon_dev_info->address,
1998 ibeacon_dev_info->addr_type,
1999 ibeacon_dev_info->company_id,
2000 ibeacon_dev_info->ibeacon_type,
2001 ibeacon_dev_info->uuid,
2002 ibeacon_dev_info->major_id,
2003 ibeacon_dev_info->minor_id,
2004 ibeacon_dev_info->measured_power);
2006 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_IBEACON_DEVICE_FOUND, param);
2010 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2013 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2014 GError *error = NULL;
2017 if (__bt_is_factory_test_mode()) {
2018 BT_ERR("Unable to add white list in factory binary !!");
2019 return BLUETOOTH_ERROR_NOT_SUPPORT;
2022 BT_CHECK_PARAMETER(device_address, return);
2024 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2025 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2026 return BLUETOOTH_ERROR_INVALID_PARAM;
2028 _bt_convert_addr_type_to_string(address, device_address->addr);
2030 proxy = _bt_get_adapter_proxy();
2031 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2033 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
2034 g_variant_new("(su)", address, address_type),
2035 G_DBUS_CALL_FLAGS_NONE, -1,
2039 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
2040 g_clear_error(&error);
2041 return BLUETOOTH_ERROR_INTERNAL;
2045 g_variant_unref(ret);
2046 BT_INFO("Add white list");
2048 return BLUETOOTH_ERROR_NONE;
2051 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2054 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2055 GError *error = NULL;
2058 if (__bt_is_factory_test_mode()) {
2059 BT_ERR("Unable to remove white list in factory binary !!");
2060 return BLUETOOTH_ERROR_NOT_SUPPORT;
2063 BT_CHECK_PARAMETER(device_address, return);
2065 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2066 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2067 return BLUETOOTH_ERROR_INVALID_PARAM;
2069 _bt_convert_addr_type_to_string(address, device_address->addr);
2071 proxy = _bt_get_adapter_proxy();
2072 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2074 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
2075 g_variant_new("(su)", address, address_type),
2076 G_DBUS_CALL_FLAGS_NONE, -1,
2080 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2081 g_clear_error(&error);
2082 return BLUETOOTH_ERROR_INTERNAL;
2086 g_variant_unref(ret);
2087 BT_INFO("Remove white list");
2089 return BLUETOOTH_ERROR_NONE;
2092 int _bt_clear_white_list(void)
2095 GError *error = NULL;
2098 if (__bt_is_factory_test_mode()) {
2099 BT_ERR("Unable to clear white list in factory binary !!");
2100 return BLUETOOTH_ERROR_NOT_SUPPORT;
2103 proxy = _bt_get_adapter_proxy();
2104 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2106 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2107 NULL, G_DBUS_CALL_FLAGS_NONE,
2111 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2112 g_clear_error(&error);
2113 return BLUETOOTH_ERROR_INTERNAL;
2116 g_variant_unref(ret);
2118 BT_INFO("Clear white list");
2120 return BLUETOOTH_ERROR_NONE;
2123 int _bt_initialize_ipsp(void)
2127 GError *error = NULL;
2130 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2131 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2132 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2135 proxy = _bt_get_adapter_proxy();
2136 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2138 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2139 NULL, G_DBUS_CALL_FLAGS_NONE,
2142 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2143 g_clear_error(&error);
2144 return BLUETOOTH_ERROR_INTERNAL;
2147 g_variant_unref(ret);
2149 BT_INFO("IPSP initialization called successfully");
2151 return BLUETOOTH_ERROR_NONE;
2154 int _bt_deinitialize_ipsp(void)
2158 GError *error = NULL;
2161 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2162 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2163 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2166 proxy = _bt_get_adapter_proxy();
2167 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2169 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2170 NULL, G_DBUS_CALL_FLAGS_NONE,
2173 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2174 g_clear_error(&error);
2175 return BLUETOOTH_ERROR_INTERNAL;
2178 g_variant_unref(ret);
2180 BT_INFO("IPSP De-initialization called successfully");
2182 return BLUETOOTH_ERROR_NONE;
2185 int _bt_le_read_maximum_data_length(
2186 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2188 GError *error = NULL;
2190 GVariant *reply = NULL;
2191 guint16 max_tx_octets, max_tx_time;
2192 guint16 max_rx_octets, max_rx_time;
2194 proxy = _bt_get_adapter_proxy();
2195 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2197 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2198 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2200 if (reply == NULL) {
2201 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2202 if (error != NULL) {
2203 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2204 error->code, error->message);
2205 g_clear_error(&error);
2207 return BLUETOOTH_ERROR_INTERNAL;
2210 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2211 &max_rx_octets, &max_rx_time);
2213 max_le_datalength->max_tx_octets = max_tx_octets;
2214 max_le_datalength->max_tx_time = max_tx_time;
2215 max_le_datalength->max_rx_octets = max_rx_octets;
2216 max_le_datalength->max_rx_time = max_rx_time;
2218 g_variant_unref(reply);
2220 return BLUETOOTH_ERROR_NONE;
2222 int _bt_le_write_host_suggested_default_data_length(
2223 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2225 GError *error = NULL;
2227 GVariant *reply = NULL;
2229 proxy = _bt_get_adapter_proxy();
2230 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2232 reply = g_dbus_proxy_call_sync(proxy,
2233 "LEWriteHostSuggestedDataLength",
2234 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2235 G_DBUS_CALL_FLAGS_NONE,
2240 if (reply == NULL) {
2241 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2242 if (error != NULL) {
2243 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2244 error->code, error->message);
2245 g_clear_error(&error);
2247 return BLUETOOTH_ERROR_INTERNAL;
2250 g_variant_unref(reply);
2252 return BLUETOOTH_ERROR_NONE;
2255 int _bt_le_read_host_suggested_default_data_length(
2256 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2258 GError *error = NULL;
2260 GVariant *reply = NULL;
2261 guint16 def_tx_octets, def_tx_time;
2263 proxy = _bt_get_adapter_proxy();
2264 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2266 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2267 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2269 if (reply == NULL) {
2270 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2271 if (error != NULL) {
2272 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2273 error->code, error->message);
2274 g_clear_error(&error);
2276 return BLUETOOTH_ERROR_INTERNAL;
2279 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2281 def_data_length->def_tx_octets = def_tx_octets;
2282 def_data_length->def_tx_time = def_tx_time;
2284 g_variant_unref(reply);
2286 return BLUETOOTH_ERROR_NONE;
2289 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2290 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2292 GError *error = NULL;
2293 guint16 txOctets = max_tx_Octets;
2294 guint16 txTime = max_tx_Time;
2295 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2296 gchar *device_path = NULL;
2297 GDBusConnection *conn;
2298 GDBusProxy *device_proxy;
2300 _bt_convert_addr_type_to_string(address, device_address->addr);
2302 device_path = _bt_get_device_object_path(address);
2304 if (device_path == NULL) {
2305 BT_DBG("Device path is null");
2306 return BLUETOOTH_ERROR_INTERNAL;
2309 conn = _bt_gdbus_get_system_gconn();
2311 BT_ERR("conn == NULL");
2312 g_free(device_path);
2313 return BLUETOOTH_ERROR_INTERNAL;
2316 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2317 NULL, BT_BLUEZ_NAME,
2318 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2320 g_free(device_path);
2321 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2323 g_dbus_proxy_call_sync(device_proxy,
2325 g_variant_new("(qq)", txOctets, txTime),
2326 G_DBUS_CALL_FLAGS_NONE,
2331 g_object_unref(device_proxy);
2334 BT_ERR("LESetDataLength error: [%s]", error->message);
2335 g_error_free(error);
2336 return BLUETOOTH_ERROR_INTERNAL;
2339 return BLUETOOTH_ERROR_NONE;
2342 int _bt_service_adapter_le_init(void)
2344 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
2346 return BLUETOOTH_ERROR_NONE;
2349 void _bt_service_adapter_le_deinit(void)
2351 __bt_free_le_adv_slot();
2352 __bt_free_le_scanner();