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 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
334 if (le_adv_slot[i].is_advertising == TRUE)
341 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
345 if (le_adv_slot == NULL)
348 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
349 if (le_adv_slot[i].sender != NULL) {
350 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
351 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
352 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
358 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
363 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
368 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
371 GError *error = NULL;
375 if (__bt_is_factory_test_mode()) {
376 BT_ERR("Unable to start advertising in factory binary !!");
377 return BLUETOOTH_ERROR_NOT_SUPPORT;
380 if (_bt_adapter_get_status() != BT_ACTIVATED &&
381 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
382 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
385 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
387 BT_ERR("There is NO available slot!!");
388 return BLUETOOTH_ERROR_NO_RESOURCES;
391 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
392 return BLUETOOTH_ERROR_IN_PROGRESS;
394 if (le_adv_slot[slot_id].hold_timer_id > 0) {
395 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
396 le_adv_slot[slot_id].hold_timer_id = 0;
397 _bt_unregister_adv_slot_owner(slot_id);
400 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
401 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
403 proxy = _bt_get_adapter_proxy();
404 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
406 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
407 g_variant_new("(bi)", enable, slot_id),
408 G_DBUS_CALL_FLAGS_NONE,
414 BT_ERR("SetAdvertising Fail: %s", error->message);
415 g_clear_error(&error);
416 return BLUETOOTH_ERROR_INTERNAL;
420 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
422 le_adv_slot[slot_id].is_advertising = enable;
423 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
426 g_variant_unref(ret);
428 return BLUETOOTH_ERROR_NONE;
431 int _bt_set_custom_advertising(const char *sender, int adv_handle,
432 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
436 GError *error = NULL;
441 BT_CHECK_PARAMETER(params, return);
443 if (__bt_is_factory_test_mode()) {
444 BT_ERR("Unable to start advertising in factory binary !!");
445 return BLUETOOTH_ERROR_NOT_SUPPORT;
448 if (_bt_adapter_get_status() != BT_ACTIVATED &&
449 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
450 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
453 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
455 BT_ERR("There is NO available slot!!");
456 return BLUETOOTH_ERROR_NO_RESOURCES;
459 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
460 return BLUETOOTH_ERROR_IN_PROGRESS;
462 if (le_adv_slot[slot_id].hold_timer_id > 0) {
463 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
464 le_adv_slot[slot_id].hold_timer_id = 0;
465 _bt_unregister_adv_slot_owner(slot_id);
468 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
469 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
471 proxy = _bt_get_adapter_proxy();
472 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
474 if (params->interval_min > params->interval_max ||
475 params->interval_min < BT_ADV_INTERVAL_MIN ||
476 params->interval_max > BT_ADV_INTERVAL_MAX)
477 return BLUETOOTH_ERROR_INVALID_PARAM;
479 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
480 return BLUETOOTH_ERROR_INVALID_PARAM;
482 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
483 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
484 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
485 return BLUETOOTH_ERROR_NOT_SUPPORT;
487 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
488 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
490 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
491 g_variant_new("(uuuui)", min, max,
492 params->filter_policy, params->type,
493 slot_id), G_DBUS_CALL_FLAGS_NONE,
497 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
498 g_clear_error(&error);
499 return BLUETOOTH_ERROR_INTERNAL;
502 adv_params.interval_min = params->interval_min;
503 adv_params.interval_max = params->interval_max;
504 adv_params.filter_policy = params->filter_policy;
505 adv_params.type = params->type;
508 g_variant_unref(ret);
510 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
511 g_variant_new("(bi)", enable, slot_id),
512 G_DBUS_CALL_FLAGS_NONE,
518 BT_ERR("SetAdvertising Fail: %s", error->message);
519 g_clear_error(&error);
520 return BLUETOOTH_ERROR_INTERNAL;
524 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
526 le_adv_slot[slot_id].is_advertising = enable;
527 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
529 g_variant_unref(ret);
531 return BLUETOOTH_ERROR_NONE;
534 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
537 GError *error = NULL;
540 BT_INFO("Restart advertising stopped by bt-service");
542 le_adv_slot[0].hold_timer_id = 0;
544 proxy = _bt_get_adapter_proxy();
545 retv_if(proxy == NULL, FALSE);
547 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
548 g_variant_new("(bi)", TRUE, 0),
549 G_DBUS_CALL_FLAGS_NONE,
555 BT_ERR("SetAdvertising Fail: %s", error->message);
556 g_clear_error(&error);
561 g_variant_unref(ret);
566 int _bt_hold_current_advertising(void)
569 GError *error = NULL;
572 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
573 BT_INFO("Stop current advertising by bt-service");
575 proxy = _bt_get_adapter_proxy();
576 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
578 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
579 g_variant_new("(bi)", FALSE, 0),
580 G_DBUS_CALL_FLAGS_NONE,
586 BT_ERR("SetAdvertising Fail: %s", error->message);
587 g_clear_error(&error);
588 return BLUETOOTH_ERROR_INTERNAL;
592 g_variant_unref(ret);
594 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
595 __bt_hold_current_advertising_timeout_cb, NULL);
597 BT_INFO("It's NOT advertising");
598 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
601 return BLUETOOTH_ERROR_NONE;
604 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
605 char in_type, char **data, int *data_len)
607 if (in_data == NULL || data == NULL || data_len == NULL)
608 return BLUETOOTH_ERROR_INTERNAL;
611 return BLUETOOTH_ERROR_INTERNAL;
617 for (i = 0; i < in_len; i++) {
619 if (len <= 0 || i + 1 >= in_len) {
620 BT_ERR("Invalid advertising data");
621 return BLUETOOTH_ERROR_INTERNAL;
624 type = in_data[i + 1];
625 if (type == in_type) {
635 if (i + len > in_len) {
636 BT_ERR("Invalid advertising data");
637 return BLUETOOTH_ERROR_INTERNAL;
638 } else if (len == 0) {
639 BT_DBG("AD Type 0x%02x data is not set", in_type);
642 return BLUETOOTH_ERROR_NONE;
645 *data = g_memdup(&in_data[i], len);
647 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
650 return BLUETOOTH_ERROR_NONE;
653 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
655 BT_CHECK_PARAMETER(adv, return);
656 BT_CHECK_PARAMETER(length, return);
658 memcpy(adv, &adv_data, sizeof(adv_data));
659 *length = adv_data_len;
661 return BLUETOOTH_ERROR_NONE;
664 int _bt_set_advertising_data(const char *sender, int adv_handle,
665 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
668 GError *error = NULL;
669 GVariant *ret, *ad_data, *param = NULL;
670 GVariant *temp = NULL;
671 GVariantBuilder *builder;
673 char *old_mdata = NULL;
674 char *new_mdata = NULL;
679 if (__bt_is_factory_test_mode()) {
680 BT_ERR("Unable to set advertising data in factory binary !!");
681 return BLUETOOTH_ERROR_NOT_SUPPORT;
684 BT_CHECK_PARAMETER(adv, return);
686 if (_bt_adapter_get_status() != BT_ACTIVATED &&
687 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
688 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
691 proxy = _bt_get_adapter_proxy();
692 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
694 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
696 BT_ERR("There is NO available slot!!");
697 return BLUETOOTH_ERROR_NO_RESOURCES;
700 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
701 for (i = 0; i < length; i++)
702 g_variant_builder_add(builder, "y", adv->data[i]);
704 temp = g_variant_new("ay", builder);
705 g_variant_builder_unref(builder);
706 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
707 g_variant_new("(@ayi)", temp, slot_id),
708 G_DBUS_CALL_FLAGS_NONE,
712 BT_ERR("SetAdvertisingData Fail: %s", error->message);
713 g_clear_error(&error);
714 return BLUETOOTH_ERROR_INTERNAL;
717 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
719 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
720 &old_mdata, &old_len);
721 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
722 &new_mdata, &new_len);
723 if (old_len != new_len ||
724 (old_mdata && new_mdata &&
725 memcmp(old_mdata, new_mdata, new_len))) {
726 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
727 new_mdata, new_len, TRUE, NULL, NULL);
728 param = g_variant_new("(@ay)", ad_data);
729 _bt_send_event(BT_ADAPTER_EVENT,
730 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
736 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
737 memcpy(&adv_data, adv, length);
738 adv_data_len = length;
740 BT_INFO("Set advertising data");
742 g_variant_unref(ret);
744 return BLUETOOTH_ERROR_NONE;
747 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
749 BT_CHECK_PARAMETER(response, return);
750 BT_CHECK_PARAMETER(length, return);
752 memcpy(response, &resp_data, sizeof(resp_data));
753 *length = resp_data_len;
755 return BLUETOOTH_ERROR_NONE;
758 int _bt_set_scan_response_data(const char *sender, int adv_handle,
759 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
762 GError *error = NULL;
763 GVariant *ret, *scan_data, *param = NULL;
764 GVariant *temp = NULL;
765 GVariantBuilder *builder;
767 char *old_mdata = NULL;
768 char *new_mdata = NULL;
773 if (__bt_is_factory_test_mode()) {
774 BT_ERR("Unable to set scan response list in factory binary !!");
775 return BLUETOOTH_ERROR_NOT_SUPPORT;
778 BT_CHECK_PARAMETER(response, return);
780 if (_bt_adapter_get_status() != BT_ACTIVATED &&
781 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
782 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
785 proxy = _bt_get_adapter_proxy();
786 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
788 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
790 BT_ERR("There is NO available slot!!");
791 return BLUETOOTH_ERROR_NO_RESOURCES;
793 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
794 for (i = 0; i < length; i++)
795 g_variant_builder_add(builder, "y", response->data[i]);
797 temp = g_variant_new("ay", builder);
798 g_variant_builder_unref(builder);
799 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
800 g_variant_new("(@ayi)", temp, slot_id),
801 G_DBUS_CALL_FLAGS_NONE,
805 BT_ERR("SetScanRespData Fail: %s", error->message);
806 g_clear_error(&error);
807 return BLUETOOTH_ERROR_INTERNAL;
810 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
812 /* Compare with previous scan resp data */
813 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
814 &old_mdata, &old_len);
815 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
816 &new_mdata, &new_len);
817 if (old_len != new_len ||
818 (old_mdata && new_mdata &&
819 memcmp(old_mdata, new_mdata, new_len))) {
820 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
821 new_mdata, new_len, TRUE, NULL, NULL);
822 param = g_variant_new("(@ay)", scan_data);
823 _bt_send_event(BT_ADAPTER_EVENT,
824 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
830 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
831 memcpy(&resp_data, response, length);
832 resp_data_len = length;
835 g_variant_unref(ret);
836 BT_INFO("Set scan response data");
837 return BLUETOOTH_ERROR_NONE;
840 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
843 GError *error = NULL;
848 BT_CHECK_PARAMETER(params, return);
850 if (_bt_adapter_get_status() != BT_ACTIVATED &&
851 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
852 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
855 proxy = _bt_get_adapter_proxy();
856 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
858 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
859 return BLUETOOTH_ERROR_INVALID_PARAM;
861 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
862 return BLUETOOTH_ERROR_INVALID_PARAM;
864 if (params->window > params->interval)
865 return BLUETOOTH_ERROR_INVALID_PARAM;
867 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
868 win = params->window / BT_ADV_INTERVAL_SPLIT;
870 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
871 g_variant_new("(uuu)", params->type, itv, win),
872 G_DBUS_CALL_FLAGS_NONE, -1,
876 BT_ERR("SetScanParameters Fail: %s", error->message);
877 g_clear_error(&error);
878 return BLUETOOTH_ERROR_INTERNAL;
881 _bt_set_le_scan_type(params->type);
883 is_le_set_scan_parameter = TRUE;
886 g_variant_unref(ret);
887 BT_INFO("Set scan parameters");
888 return BLUETOOTH_ERROR_NONE;
891 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
894 bt_adapter_le_scanner_t *scanner;
896 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
898 if (g_strcmp0(scanner->sender, sender) == 0)
905 int __bt_get_available_scan_filter_slot_id(void)
908 bt_adapter_le_scanner_t *scanner;
910 bluetooth_le_scan_filter_t *filter_data;
911 gboolean *slot_check_list = NULL;
914 if (le_feature_info.max_filter == 0) {
915 BT_ERR("Scan filter is NOT Supported");
918 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
920 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
922 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
923 filter_data = fl->data;
924 if (filter_data->slot_id < le_feature_info.max_filter)
925 slot_check_list[filter_data->slot_id] = TRUE;
929 for (i = 0; i < le_feature_info.max_filter; i++) {
930 if (slot_check_list[i] == FALSE) {
931 g_free(slot_check_list);
936 BT_ERR("There is NO available slot for scan filter.");
937 g_free(slot_check_list);
941 gboolean _bt_is_scan_filter_supported(void)
943 if (le_feature_info.max_filter > 0)
949 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
952 GError *error = NULL;
953 GVariant *ret, *param;
954 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
955 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
956 GArray *arr_uuid = NULL;
957 GArray *arr_uuid_mask = NULL;
958 GArray *arr_data = NULL;
959 GArray *arr_data_mask = NULL;
960 bt_adapter_le_scanner_t *scanner = NULL;
961 bluetooth_le_scan_filter_t *filter_data = NULL;
962 int feature_selection = 0;
964 *slot_id = __bt_get_available_scan_filter_slot_id();
966 return BLUETOOTH_ERROR_NO_RESOURCES;
968 proxy = _bt_get_adapter_proxy();
969 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
971 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
972 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
973 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
975 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
977 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
978 NULL, 0, TRUE, NULL, NULL);
979 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
980 NULL, 0, TRUE, NULL, NULL);
981 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
982 NULL, 0, TRUE, NULL, NULL);
983 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
984 NULL, 0, TRUE, NULL, NULL);
986 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
988 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
989 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
990 *slot_id, // filter_index
992 0, // company_id_mask
993 arr_uuid_param, // p_uuid
994 arr_uuid_mask_param, // p_uuid_mask
997 arr_data_param, // p_data
998 arr_data_mask_param); // p_mask
1000 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1001 param, G_DBUS_CALL_FLAGS_NONE,
1005 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1006 g_clear_error(&error);
1009 g_variant_unref(ret);
1012 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1013 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
1015 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1016 NULL, 0, TRUE, NULL, NULL);
1017 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1018 NULL, 0, TRUE, NULL, NULL);
1019 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1020 NULL, 0, TRUE, NULL, NULL);
1021 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1022 NULL, 0, TRUE, NULL, NULL);
1024 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1026 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1027 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1028 *slot_id, // filter_index
1030 0, // company_id_mask
1031 arr_uuid_param, // p_uuid
1032 arr_uuid_mask_param, // p_uuid_mask
1033 filter->device_name, // string
1035 arr_data_param, // p_data
1036 arr_data_mask_param);
1038 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1039 param, G_DBUS_CALL_FLAGS_NONE,
1043 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1044 g_clear_error(&error);
1047 g_variant_unref(ret);
1050 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1051 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1053 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1054 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1056 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1057 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1059 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1060 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1061 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1062 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1063 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1064 NULL, 0, TRUE, NULL, NULL);
1065 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1066 NULL, 0, TRUE, NULL, NULL);
1068 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1070 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1071 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1072 *slot_id, // filter_index
1074 0, // company_id_mask
1075 arr_uuid_param, // p_uuid
1076 arr_uuid_mask_param, // p_uuid_mask
1079 arr_data_param, // p_data
1080 arr_data_mask_param);
1082 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1083 param, G_DBUS_CALL_FLAGS_NONE,
1087 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1088 g_clear_error(&error);
1091 g_variant_unref(ret);
1093 g_array_free(arr_uuid, TRUE);
1094 g_array_free(arr_uuid_mask, TRUE);
1097 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1098 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1100 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1101 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1103 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1104 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1106 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1107 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1108 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1109 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1110 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1111 NULL, 0, TRUE, NULL, NULL);
1112 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1113 NULL, 0, TRUE, NULL, NULL);
1115 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1117 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1118 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1119 *slot_id, // filter_index
1121 0, // company_id_mask
1122 arr_uuid_param, // p_uuid
1123 arr_uuid_mask_param, // p_uuid_mask
1126 arr_data_param, // p_data
1127 arr_data_mask_param);
1129 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1130 G_DBUS_CALL_FLAGS_NONE,
1134 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1135 g_clear_error(&error);
1138 g_variant_unref(ret);
1140 g_array_free(arr_uuid, TRUE);
1141 g_array_free(arr_uuid_mask, TRUE);
1144 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1145 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1147 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1148 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1150 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1151 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1153 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1154 NULL, 0, TRUE, NULL, NULL);
1155 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1156 NULL, 0, TRUE, NULL, NULL);
1157 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1158 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1159 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1160 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1162 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1164 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1165 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1166 *slot_id, // filter_index
1168 0, // company_id_mask
1169 arr_uuid_param, // p_uuid
1170 arr_uuid_mask_param, // p_uuid_mask
1173 arr_data_param, // p_data
1174 arr_data_mask_param);
1176 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1177 G_DBUS_CALL_FLAGS_NONE,
1181 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1182 g_clear_error(&error);
1185 g_variant_unref(ret);
1187 g_array_free(arr_data, TRUE);
1188 g_array_free(arr_data_mask, TRUE);
1191 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1192 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1194 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1195 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1197 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1198 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1200 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1201 NULL, 0, TRUE, NULL, NULL);
1202 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1203 NULL, 0, TRUE, NULL, NULL);
1204 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1205 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1206 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1207 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1209 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1211 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1212 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1213 *slot_id, // filter_index
1214 filter->manufacturer_id, // company_id
1215 0xFFFF, // company_id_mask
1216 arr_uuid_param, // p_uuid
1217 arr_uuid_mask_param, // p_uuid_mask
1220 arr_data_param, // p_data
1221 arr_data_mask_param);
1223 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1224 G_DBUS_CALL_FLAGS_NONE,
1228 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1229 g_clear_error(&error);
1232 g_variant_unref(ret);
1234 g_array_free(arr_data, TRUE);
1235 g_array_free(arr_data_mask, TRUE);
1238 BT_DBG("Filter selection %.2x", feature_selection);
1240 param = g_variant_new("(iiiiiiiiiiii)",
1242 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1243 *slot_id, // filter_index
1244 feature_selection, // feat_seln
1245 0, // list_logic_type (OR - 0x00, AND - 0x01)
1246 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1247 -127, // rssi_high_thres
1248 -127, // rssi_low_thres
1249 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1252 0); // found_timeout_cnt
1253 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1254 param, G_DBUS_CALL_FLAGS_NONE,
1258 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1259 g_clear_error(&error);
1262 scanner = __bt_find_scanner_from_list(sender);
1263 if (scanner == NULL) {
1264 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1265 scanner->sender = g_strdup(sender);
1266 scanner_list = g_slist_append(scanner_list, scanner);
1271 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1272 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1273 filter_data->slot_id = *slot_id;
1275 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1279 g_variant_unref(ret);
1280 return BLUETOOTH_ERROR_NONE;
1283 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1286 GError *error = NULL;
1288 bt_adapter_le_scanner_t *scanner = NULL;
1289 bluetooth_le_scan_filter_t *filter_data = NULL;
1291 gboolean is_slot_id_found = FALSE;
1293 scanner = __bt_find_scanner_from_list(sender);
1294 if (scanner == NULL) {
1295 BT_ERR("There is NO available scanner.");
1296 return BLUETOOTH_ERROR_NOT_FOUND;
1299 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1300 filter_data = l->data;
1301 if (filter_data->slot_id == slot_id) {
1302 is_slot_id_found = TRUE;
1306 if (is_slot_id_found == FALSE) {
1307 BT_ERR("There is NO registered slot.");
1308 return BLUETOOTH_ERROR_NOT_FOUND;
1311 proxy = _bt_get_adapter_proxy();
1312 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1314 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1315 g_variant_new("(ii)", 0, slot_id),
1316 G_DBUS_CALL_FLAGS_NONE,
1320 BT_ERR("scan_filter_clear Fail: %s", error->message);
1321 g_clear_error(&error);
1324 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1325 g_free(filter_data);
1328 g_variant_unref(ret);
1329 return BLUETOOTH_ERROR_NONE;
1332 int _bt_unregister_all_scan_filters(const char *sender)
1335 GError *error = NULL;
1337 bt_adapter_le_scanner_t *scanner = NULL;
1338 bluetooth_le_scan_filter_t *filter_data = NULL;
1341 scanner = __bt_find_scanner_from_list(sender);
1342 if (scanner == NULL) {
1343 BT_ERR("There is NO available scanner.");
1344 return BLUETOOTH_ERROR_NOT_FOUND;
1347 proxy = _bt_get_adapter_proxy();
1348 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1350 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1351 filter_data = l->data;
1353 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1354 g_variant_new("(ii)", 0, filter_data->slot_id),
1355 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1358 BT_ERR("scan_filter_clear Fail: %s", error->message);
1359 g_clear_error(&error);
1362 g_variant_unref(ret);
1365 g_slist_free_full(scanner->filter_list, g_free);
1366 scanner->filter_list = NULL;
1368 return BLUETOOTH_ERROR_NONE;
1371 int _bt_start_le_scan(const char *sender)
1374 GError *error = NULL;
1376 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1378 if (scanner == NULL) {
1379 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1380 scanner->sender = g_strdup(sender);
1381 scanner_list = g_slist_append(scanner_list, scanner);
1384 if (scanner->is_scanning == TRUE) {
1385 BT_ERR("BT is already in LE scanning");
1386 return BLUETOOTH_ERROR_IN_PROGRESS;
1388 scanner->is_scanning = TRUE;
1390 proxy = _bt_get_adapter_proxy();
1391 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1393 if (_bt_is_le_scanning()) {
1394 if (scan_filter_enabled == TRUE) {
1395 if (scanner->filter_list == NULL) {
1396 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1397 g_variant_new("(ib)", 0, FALSE),
1398 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1401 BT_ERR("scan_filter_clear Fail: %s", error->message);
1402 g_clear_error(&error);
1406 g_variant_unref(ret);
1407 BT_INFO("Disable LE Scan Filter");
1408 scan_filter_enabled = FALSE;
1410 BT_INFO("LE Filter Scan is continue");
1413 BT_INFO("LE Full Scan is already on progress");
1415 return BLUETOOTH_ERROR_NONE;
1417 if (is_le_set_scan_parameter == FALSE) {
1418 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1419 bluetooth_le_scan_params_t scan_params;
1420 scan_params.type = BT_LE_ACTIVE_SCAN;
1421 scan_params.interval = 5000;
1422 scan_params.window = 500;
1423 _bt_set_scan_parameters(&scan_params);
1426 if (scanner->filter_list == NULL) {
1427 BT_INFO("Start LE Full Scan");
1428 scan_filter_enabled = FALSE;
1430 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1431 g_variant_new("(ib)", 0, TRUE),
1432 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1435 BT_ERR("scan_filter_clear Fail: %s", error->message);
1436 g_clear_error(&error);
1440 g_variant_unref(ret);
1441 BT_INFO("Enable LE Scan Filter");
1442 scan_filter_enabled = TRUE;
1446 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1447 NULL, G_DBUS_CALL_FLAGS_NONE,
1451 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1452 g_clear_error(&error);
1453 return BLUETOOTH_ERROR_INTERNAL;
1457 g_variant_unref(ret);
1458 return BLUETOOTH_ERROR_NONE;
1461 int _bt_stop_le_scan(const char *sender)
1464 GError *error = NULL;
1466 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1468 gboolean next_scanning = FALSE;
1469 gboolean need_scan_filter = TRUE;
1471 if (scanner == NULL || scanner->is_scanning == FALSE)
1472 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1474 scanner->is_scanning = FALSE;
1476 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1478 if (scanner->is_scanning == TRUE) {
1479 next_scanning = TRUE;
1480 if (scanner->filter_list == NULL)
1481 need_scan_filter = FALSE;
1485 proxy = _bt_get_adapter_proxy();
1486 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1488 if (next_scanning == TRUE) {
1489 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1490 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1491 g_variant_new("(ib)", 0, TRUE),
1492 G_DBUS_CALL_FLAGS_NONE,
1496 BT_ERR("scan_filter_clear Fail: %s", error->message);
1497 g_clear_error(&error);
1501 g_variant_unref(ret);
1502 BT_INFO("Enable LE Scan Filter");
1503 scan_filter_enabled = TRUE;
1505 return BLUETOOTH_ERROR_NONE;
1507 if (scan_filter_enabled == TRUE) {
1508 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1509 g_variant_new("(ib)", 0, FALSE),
1510 G_DBUS_CALL_FLAGS_NONE,
1514 BT_ERR("scan_filter_clear Fail: %s", error->message);
1515 g_clear_error(&error);
1519 g_variant_unref(ret);
1520 BT_INFO("Disable LE Scan Filter");
1522 BT_INFO("Just stop LE scan");
1526 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1527 NULL, G_DBUS_CALL_FLAGS_NONE,
1530 BT_ERR("LE Scan stop failed");
1531 return BLUETOOTH_ERROR_INTERNAL;
1534 scan_filter_enabled = FALSE;
1535 is_le_set_scan_parameter = FALSE;
1537 g_variant_unref(ret);
1538 return BLUETOOTH_ERROR_NONE;
1541 void _bt_disable_all_scanner_status(void)
1544 bt_adapter_le_scanner_t *scanner;
1546 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1548 scanner->is_scanning = FALSE;
1552 static void __bt_free_le_scanner(void)
1555 bt_adapter_le_scanner_t *scanner;
1557 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1559 g_free(scanner->sender);
1560 g_slist_free_full(scanner->filter_list, g_free);
1564 g_slist_free(scanner_list);
1565 scanner_list = NULL;
1567 scan_filter_enabled = FALSE;
1568 is_le_scanning = FALSE;
1569 is_le_set_scan_parameter = FALSE;
1572 void _bt_set_le_scan_status(gboolean mode)
1574 is_le_scanning = mode;
1577 gboolean _bt_is_le_scanning(void)
1579 return is_le_scanning;
1582 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1584 le_scan_type = type;
1587 bt_le_scan_type_t _bt_get_le_scan_type(void)
1589 return le_scan_type;
1592 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1593 int adv_data_len, const char *svc_uuid, int uuid_len,
1594 const char *uuid_mask, char ad_type)
1600 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1601 ad_type, &data, &data_len);
1603 for (i = 0; i < data_len; i += uuid_len) {
1604 if (uuid_len > (data_len - i))
1607 if (_bt_byte_arr_cmp_with_mask(data + i,
1608 svc_uuid, uuid_mask, uuid_len) == 0) {
1619 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1620 const char *adv_data, int adv_data_len,
1621 const char *scan_data, int scan_data_len,
1622 const bt_adapter_le_scanner_t *scanner)
1625 bluetooth_le_scan_filter_t *filter_data = NULL;
1628 gboolean is_matched = FALSE;
1630 if (scanner->filter_list == NULL) {
1631 BT_INFO("This scanner is on Full Scan.");
1635 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1636 filter_data = l->data;
1638 if (filter_data->added_features &
1639 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1640 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1642 _bt_convert_addr_type_to_string(address,
1643 filter_data->device_address.addr);
1644 if (strncmp(address, device_address,
1645 BT_ADDRESS_STRING_SIZE) != 0)
1649 if (filter_data->added_features &
1650 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1653 if (__bt_check_scan_result_uuid(adv_data,
1655 (char*)filter_data->service_uuid.data.data,
1656 filter_data->service_uuid.data_len,
1657 (char*)filter_data->service_uuid_mask.data.data,
1658 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1661 if (__bt_check_scan_result_uuid(adv_data,
1663 (char*)filter_data->service_uuid.data.data,
1664 filter_data->service_uuid.data_len,
1665 (char*)filter_data->service_uuid_mask.data.data,
1666 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1669 if (__bt_check_scan_result_uuid(adv_data,
1671 (char*)filter_data->service_uuid.data.data,
1672 filter_data->service_uuid.data_len,
1673 (char*)filter_data->service_uuid_mask.data.data,
1674 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1677 if (__bt_check_scan_result_uuid(adv_data,
1679 (char*)filter_data->service_uuid.data.data,
1680 filter_data->service_uuid.data_len,
1681 (char*)filter_data->service_uuid_mask.data.data,
1682 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1685 if (__bt_check_scan_result_uuid(scan_data,
1687 (char*)filter_data->service_uuid.data.data,
1688 filter_data->service_uuid.data_len,
1689 (char*)filter_data->service_uuid_mask.data.data,
1690 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1693 if (__bt_check_scan_result_uuid(scan_data,
1695 (char*)filter_data->service_uuid.data.data,
1696 filter_data->service_uuid.data_len,
1697 (char*)filter_data->service_uuid_mask.data.data,
1698 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1701 if (__bt_check_scan_result_uuid(scan_data,
1703 (char*)filter_data->service_uuid.data.data,
1704 filter_data->service_uuid.data_len,
1705 (char*)filter_data->service_uuid_mask.data.data,
1706 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1709 if (__bt_check_scan_result_uuid(scan_data,
1711 (char*)filter_data->service_uuid.data.data,
1712 filter_data->service_uuid.data_len,
1713 (char*)filter_data->service_uuid_mask.data.data,
1714 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1718 if (is_matched == FALSE)
1721 if (filter_data->added_features &
1722 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1725 if (__bt_check_scan_result_uuid(adv_data,
1727 (char*)filter_data->service_solicitation_uuid.data.data,
1728 filter_data->service_solicitation_uuid.data_len,
1729 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1730 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1733 if (__bt_check_scan_result_uuid(adv_data,
1735 (char*)filter_data->service_solicitation_uuid.data.data,
1736 filter_data->service_solicitation_uuid.data_len,
1737 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1738 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1741 if (__bt_check_scan_result_uuid(scan_data,
1743 (char*)filter_data->service_solicitation_uuid.data.data,
1744 filter_data->service_solicitation_uuid.data_len,
1745 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1746 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1749 if (__bt_check_scan_result_uuid(scan_data,
1751 (char*)filter_data->service_solicitation_uuid.data.data,
1752 filter_data->service_solicitation_uuid.data_len,
1753 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1754 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1758 if (is_matched == FALSE)
1761 if (filter_data->added_features &
1762 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1763 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1768 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1769 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1772 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1773 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1774 memcpy(name, data, data_len);
1775 name[data_len] = '\0';
1778 if (strncmp(filter_data->device_name,
1779 name, data_len) == 0)
1782 __bt_get_ad_data_by_type((char*)scan_data,
1784 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1787 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1788 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1789 memcpy(name, data, data_len);
1790 name[data_len] = '\0';
1793 if (strncmp(filter_data->device_name,
1794 name, data_len) == 0)
1798 if (is_matched == FALSE)
1801 if (filter_data->added_features &
1802 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1807 __bt_get_ad_data_by_type((char*)adv_data,
1809 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1813 int manufacturer_id;
1814 manufacturer_id = (data[1] << 8) + data[0];
1816 if (filter_data->manufacturer_id == manufacturer_id) {
1817 if (filter_data->manufacturer_data.data_len == 0) {
1820 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1821 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1822 if (_bt_byte_arr_cmp_with_mask(data + 2,
1823 (char*)filter_data->manufacturer_data.data.data,
1824 (char*)filter_data->manufacturer_data_mask.data.data,
1825 data_len - 2) == 0) {
1833 __bt_get_ad_data_by_type((char*)scan_data,
1835 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1839 int manufacturer_id;
1840 manufacturer_id = (data[1] << 8) + data[0];
1842 if (filter_data->manufacturer_id == manufacturer_id) {
1843 if (filter_data->manufacturer_data.data_len == 0) {
1846 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1847 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1848 if (_bt_byte_arr_cmp_with_mask(data + 2,
1849 (char*)filter_data->manufacturer_data.data.data,
1850 (char*)filter_data->manufacturer_data_mask.data.data,
1851 data_len - 2) == 0) {
1860 if (is_matched == FALSE)
1863 if (filter_data->added_features &
1864 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1869 __bt_get_ad_data_by_type((char*)adv_data,
1871 BT_LE_AD_TYPE_SERVICE_DATA,
1874 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1875 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1876 if (_bt_byte_arr_cmp_with_mask(data,
1877 (char*)filter_data->service_data.data.data,
1878 (char*)filter_data->service_data_mask.data.data,
1885 __bt_get_ad_data_by_type((char*)scan_data,
1887 BT_LE_AD_TYPE_SERVICE_DATA,
1890 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1891 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1892 if (_bt_byte_arr_cmp_with_mask(data,
1893 (char*)filter_data->service_data.data.data,
1894 (char*)filter_data->service_data_mask.data.data,
1902 if (is_matched == FALSE)
1906 BT_INFO("The scan result is conformable.");
1910 BT_INFO("The scan result is NOT conformable.");
1914 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1915 const bt_le_adv_info_t *adv_info)
1917 int result = BLUETOOTH_ERROR_NONE;
1919 GVariant *scan_data_param, *adv_data_param;
1921 bt_adapter_le_scanner_t *scanner = NULL;
1922 const char *adv_data = NULL;
1923 int adv_data_len = 0;
1924 const char *scan_data = NULL;
1925 int scan_data_len = 0;
1927 ret_if(le_dev_info == NULL);
1928 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1929 ret_if(adv_info == NULL);
1931 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1932 adv_data = le_dev_info->adv_data;
1933 adv_data_len = le_dev_info->adv_data_len;
1934 scan_data = le_dev_info->adv_data;
1937 adv_data = adv_info->data;
1938 adv_data_len = adv_info->data_len;
1939 scan_data = le_dev_info->adv_data;
1940 scan_data_len = le_dev_info->adv_data_len;
1943 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1945 if (scanner->is_scanning == FALSE)
1948 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1949 adv_data, adv_data_len, scan_data, scan_data_len,
1953 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1954 adv_data, adv_data_len, TRUE, NULL, NULL);
1955 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1956 scan_data, scan_data_len, TRUE, NULL, NULL);
1958 param = g_variant_new("(isnnn@ayn@ay)",
1960 le_dev_info->address,
1961 le_dev_info->addr_type,
1969 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1970 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1972 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1977 void _bt_send_ibeacon_scan_result_event(const bt_remote_ibeacon_dev_info_t *ibeacon_dev_info)
1979 int result = BLUETOOTH_ERROR_NONE;
1982 bt_adapter_le_scanner_t *scanner = NULL;
1984 ret_if(ibeacon_dev_info == NULL);
1985 BT_DBG("_bt_send_ibeacon_scan_result_event");
1987 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1989 if (scanner->is_scanning == FALSE)
1992 param = g_variant_new("(isnnnsnnn)",
1994 ibeacon_dev_info->address,
1995 ibeacon_dev_info->addr_type,
1996 ibeacon_dev_info->company_id,
1997 ibeacon_dev_info->ibeacon_type,
1998 ibeacon_dev_info->uuid,
1999 ibeacon_dev_info->major_id,
2000 ibeacon_dev_info->minor_id,
2001 ibeacon_dev_info->measured_power);
2003 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_IBEACON_DEVICE_FOUND, param);
2007 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2010 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2011 GError *error = NULL;
2014 if (__bt_is_factory_test_mode()) {
2015 BT_ERR("Unable to add white list in factory binary !!");
2016 return BLUETOOTH_ERROR_NOT_SUPPORT;
2019 BT_CHECK_PARAMETER(device_address, return);
2021 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2022 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2023 return BLUETOOTH_ERROR_INVALID_PARAM;
2025 _bt_convert_addr_type_to_string(address, device_address->addr);
2027 proxy = _bt_get_adapter_proxy();
2028 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2030 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
2031 g_variant_new("(su)", address, address_type),
2032 G_DBUS_CALL_FLAGS_NONE, -1,
2036 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
2037 g_clear_error(&error);
2038 return BLUETOOTH_ERROR_INTERNAL;
2042 g_variant_unref(ret);
2043 BT_INFO("Add white list");
2045 return BLUETOOTH_ERROR_NONE;
2048 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2051 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2052 GError *error = NULL;
2055 if (__bt_is_factory_test_mode()) {
2056 BT_ERR("Unable to remove white list in factory binary !!");
2057 return BLUETOOTH_ERROR_NOT_SUPPORT;
2060 BT_CHECK_PARAMETER(device_address, return);
2062 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2063 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2064 return BLUETOOTH_ERROR_INVALID_PARAM;
2066 _bt_convert_addr_type_to_string(address, device_address->addr);
2068 proxy = _bt_get_adapter_proxy();
2069 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2071 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
2072 g_variant_new("(su)", address, address_type),
2073 G_DBUS_CALL_FLAGS_NONE, -1,
2077 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2078 g_clear_error(&error);
2079 return BLUETOOTH_ERROR_INTERNAL;
2083 g_variant_unref(ret);
2084 BT_INFO("Remove white list");
2086 return BLUETOOTH_ERROR_NONE;
2089 int _bt_clear_white_list(void)
2092 GError *error = NULL;
2095 if (__bt_is_factory_test_mode()) {
2096 BT_ERR("Unable to clear white list in factory binary !!");
2097 return BLUETOOTH_ERROR_NOT_SUPPORT;
2100 proxy = _bt_get_adapter_proxy();
2101 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2103 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2104 NULL, G_DBUS_CALL_FLAGS_NONE,
2108 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2109 g_clear_error(&error);
2110 return BLUETOOTH_ERROR_INTERNAL;
2113 g_variant_unref(ret);
2115 BT_INFO("Clear white list");
2117 return BLUETOOTH_ERROR_NONE;
2120 int _bt_initialize_ipsp(void)
2124 GError *error = NULL;
2127 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2128 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2129 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2132 proxy = _bt_get_adapter_proxy();
2133 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2135 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2136 NULL, G_DBUS_CALL_FLAGS_NONE,
2139 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2140 g_clear_error(&error);
2141 return BLUETOOTH_ERROR_INTERNAL;
2144 g_variant_unref(ret);
2146 BT_INFO("IPSP initialization called successfully");
2148 return BLUETOOTH_ERROR_NONE;
2151 int _bt_deinitialize_ipsp(void)
2155 GError *error = NULL;
2158 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2159 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2160 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2163 proxy = _bt_get_adapter_proxy();
2164 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2166 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2167 NULL, G_DBUS_CALL_FLAGS_NONE,
2170 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2171 g_clear_error(&error);
2172 return BLUETOOTH_ERROR_INTERNAL;
2175 g_variant_unref(ret);
2177 BT_INFO("IPSP De-initialization called successfully");
2179 return BLUETOOTH_ERROR_NONE;
2182 int _bt_le_read_maximum_data_length(
2183 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2185 GError *error = NULL;
2187 GVariant *reply = NULL;
2188 guint16 max_tx_octets, max_tx_time;
2189 guint16 max_rx_octets, max_rx_time;
2191 proxy = _bt_get_adapter_proxy();
2192 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2194 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2195 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2197 if (reply == NULL) {
2198 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2199 if (error != NULL) {
2200 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2201 error->code, error->message);
2202 g_clear_error(&error);
2204 return BLUETOOTH_ERROR_INTERNAL;
2207 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2208 &max_rx_octets, &max_rx_time);
2210 max_le_datalength->max_tx_octets = max_tx_octets;
2211 max_le_datalength->max_tx_time = max_tx_time;
2212 max_le_datalength->max_rx_octets = max_rx_octets;
2213 max_le_datalength->max_rx_time = max_rx_time;
2215 g_variant_unref(reply);
2217 return BLUETOOTH_ERROR_NONE;
2219 int _bt_le_write_host_suggested_default_data_length(
2220 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2222 GError *error = NULL;
2224 GVariant *reply = NULL;
2226 proxy = _bt_get_adapter_proxy();
2227 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2229 reply = g_dbus_proxy_call_sync(proxy,
2230 "LEWriteHostSuggestedDataLength",
2231 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2232 G_DBUS_CALL_FLAGS_NONE,
2237 if (reply == NULL) {
2238 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2239 if (error != NULL) {
2240 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2241 error->code, error->message);
2242 g_clear_error(&error);
2244 return BLUETOOTH_ERROR_INTERNAL;
2247 g_variant_unref(reply);
2249 return BLUETOOTH_ERROR_NONE;
2252 int _bt_le_read_host_suggested_default_data_length(
2253 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2255 GError *error = NULL;
2257 GVariant *reply = NULL;
2258 guint16 def_tx_octets, def_tx_time;
2260 proxy = _bt_get_adapter_proxy();
2261 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2263 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2264 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2266 if (reply == NULL) {
2267 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2268 if (error != NULL) {
2269 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2270 error->code, error->message);
2271 g_clear_error(&error);
2273 return BLUETOOTH_ERROR_INTERNAL;
2276 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2278 def_data_length->def_tx_octets = def_tx_octets;
2279 def_data_length->def_tx_time = def_tx_time;
2281 g_variant_unref(reply);
2283 return BLUETOOTH_ERROR_NONE;
2286 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2287 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2289 GError *error = NULL;
2290 guint16 txOctets = max_tx_Octets;
2291 guint16 txTime = max_tx_Time;
2292 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2293 gchar *device_path = NULL;
2294 GDBusConnection *conn;
2295 GDBusProxy *device_proxy;
2297 _bt_convert_addr_type_to_string(address, device_address->addr);
2299 device_path = _bt_get_device_object_path(address);
2301 if (device_path == NULL) {
2302 BT_DBG("Device path is null");
2303 return BLUETOOTH_ERROR_INTERNAL;
2306 conn = _bt_gdbus_get_system_gconn();
2308 BT_ERR("conn == NULL");
2309 g_free(device_path);
2310 return BLUETOOTH_ERROR_INTERNAL;
2313 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2314 NULL, BT_BLUEZ_NAME,
2315 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2317 g_free(device_path);
2318 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2320 g_dbus_proxy_call_sync(device_proxy,
2322 g_variant_new("(qq)", txOctets, txTime),
2323 G_DBUS_CALL_FLAGS_NONE,
2328 g_object_unref(device_proxy);
2331 BT_ERR("LESetDataLength error: [%s]", error->message);
2332 g_error_free(error);
2333 return BLUETOOTH_ERROR_INTERNAL;
2336 return BLUETOOTH_ERROR_NONE;
2339 int _bt_service_adapter_le_init(void)
2341 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
2343 return BLUETOOTH_ERROR_NONE;
2346 void _bt_service_adapter_le_deinit(void)
2348 __bt_free_le_adv_slot();
2349 __bt_free_le_scanner();