2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dbus/dbus.h>
25 #include <syspopup_caller.h>
28 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-event.h"
31 #include "bt-service-adapter.h"
32 #include "bt-service-adapter-le.h"
33 #include "bt-service-util.h"
36 #define BT_ADV_INTERVAL_MIN 20 /* msec */
37 #define BT_ADV_INTERVAL_MAX 10240
38 #define BT_ADV_INTERVAL_SPLIT 0.625
39 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
40 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
41 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
42 #define BT_ADV_TYPE_DEFAULT 0x00
43 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
44 #define BT_SCAN_INTERVAL_SPLIT 0.625
51 } bt_adapter_le_feature_info_t;
56 gboolean is_advertising;
58 } bt_adapter_le_adv_slot_t;
64 } bt_adapter_le_scanner_t;
66 static bluetooth_advertising_params_t adv_params = {
67 BT_DEFAULT_ADV_MIN_INTERVAL,
68 BT_DEFAULT_ADV_MAX_INTERVAL,
69 BT_ADV_FILTER_POLICY_DEFAULT,
71 static bluetooth_advertising_data_t adv_data = { {0} };
72 static int adv_data_len;
73 static bluetooth_scan_resp_data_t resp_data = { {0} };
74 static int resp_data_len;
76 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
77 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
79 GSList *scanner_list = NULL;
80 static gboolean is_le_set_scan_parameter = FALSE;
81 static gboolean is_le_scanning = FALSE;
82 static gboolean scan_filter_enabled = FALSE;
83 static bt_le_scan_type_t le_scan_type = BT_LE_ACTIVE_SCAN;
84 static bluetooth_le_scan_params_t le_scan_params = { BT_LE_ACTIVE_SCAN, 0, 0 };
86 static GSList *gatt_client_senders = NULL;
89 gboolean _bt_is_set_scan_parameter(void)
91 return is_le_set_scan_parameter;
94 void _bt_init_gatt_client_senders(void)
96 _bt_clear_request_list();
99 int _bt_insert_gatt_client_sender(char *sender)
103 retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
105 info = g_strdup(sender);
106 retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
108 gatt_client_senders = g_slist_append(gatt_client_senders, info);
110 BT_DBG("insert sender: %s", sender);
112 return BLUETOOTH_ERROR_NONE;
115 int _bt_delete_gatt_client_sender(char *sender)
120 BT_DBG("remove sender: %s", sender);
122 for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) {
127 if (g_strcmp0(info, sender) == 0) {
128 BT_DBG("remove info");
129 gatt_client_senders = g_slist_remove(gatt_client_senders, info);
131 return BLUETOOTH_ERROR_NONE;
135 return BLUETOOTH_ERROR_NOT_FOUND;
138 void _bt_clear_gatt_client_senders(void)
140 if (gatt_client_senders) {
141 g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL);
142 g_slist_free(gatt_client_senders);
143 gatt_client_senders = NULL;
147 static void __bt_send_foreach_event(gpointer data, gpointer user_data)
150 GVariant *param = user_data;
152 _bt_send_event_to_dest(sender, BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
156 void _bt_send_char_value_changed_event(void *param)
159 g_slist_foreach(gatt_client_senders, __bt_send_foreach_event,
162 _bt_send_event(BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED, param);
166 void __bt_free_le_adv_slot(void)
170 if (le_adv_slot == NULL)
173 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
174 if (le_adv_slot[i].sender)
175 g_free(le_adv_slot[i].sender);
176 if (le_adv_slot[i].hold_timer_id > 0)
177 g_source_remove(le_adv_slot[i].hold_timer_id);
183 static void __bt_free_le_scanner(bt_adapter_le_scanner_t *scanner)
185 g_free(scanner->sender);
186 g_slist_free_full(scanner->filter_list, g_free);
190 static void __bt_free_le_scanner_all(void)
192 g_slist_free_full(scanner_list, (GDestroyNotify)__bt_free_le_scanner);
195 scan_filter_enabled = FALSE;
196 is_le_scanning = FALSE;
197 is_le_set_scan_parameter = FALSE;
198 le_scan_params.type = BT_LE_ACTIVE_SCAN;
199 le_scan_params.interval = 0;
200 le_scan_params.window = 0;
203 int _bt_le_set_max_packet_len(void)
205 int result = BLUETOOTH_ERROR_NONE;
206 int tx_octets, tx_time;
207 bluetooth_le_read_maximum_data_length_t max_len = {0};
209 if (BLUETOOTH_ERROR_NONE != _bt_le_read_maximum_data_length(&max_len))
210 return BLUETOOTH_ERROR_INTERNAL;
212 if (max_len.max_tx_octets > BT_LE_TX_LEN_DEFAULT) {
213 tx_octets = max_len.max_tx_octets > BT_LE_TX_LEN_MAX ?
214 BT_LE_TX_LEN_MAX : max_len.max_tx_octets;
215 tx_time = BT_LE_TX_TIME_MAX;
217 result = _bt_le_write_host_suggested_default_data_length(tx_octets, tx_time);
219 BT_DBG("Wrote max packet size : result[%d], MAX[%d], set[%d]",
220 result, max_len.max_tx_octets, tx_octets);
226 gboolean _bt_update_le_feature_support(const char *item, const char *value)
228 if (item == NULL || value == NULL)
232 _bt_service_adapter_le_init();
234 if (g_strcmp0(item, "adv_inst_max") == 0) {
237 slot_num = atoi(value);
238 retv_if(slot_num < 0, FALSE);
240 if (slot_num != le_feature_info.adv_inst_max) {
241 __bt_free_le_adv_slot();
242 le_feature_info.adv_inst_max = slot_num;
243 BT_INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
244 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
246 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
247 le_feature_info.rpa_offloading = atoi(value);
248 BT_INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
249 } else if (g_strcmp0(item, "max_filter") == 0) {
250 le_feature_info.max_filter = atoi(value);
251 BT_INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
253 BT_DBG("No registered item");
260 static gboolean __bt_is_factory_test_mode(void)
264 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
265 BT_ERR("Get the DUT Mode fail");
270 BT_INFO("DUT Test Mode !!");
277 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
281 if (le_adv_slot == NULL) {
282 BT_ERR("le_adv_slot is NULL");
286 BT_DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
288 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
289 if (le_adv_slot[i].sender == NULL)
291 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
295 if (le_feature_info.adv_inst_max <= 1)
297 else if (use_reserved_slot == TRUE)
302 for (; i < le_feature_info.adv_inst_max; i++) {
303 if (le_adv_slot[i].sender == NULL)
310 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
312 if (le_adv_slot[slot_id].sender == NULL) {
313 le_adv_slot[slot_id].sender = strdup(sender);
314 le_adv_slot[slot_id].adv_handle = adv_handle;
318 void _bt_unregister_adv_slot_owner(int slot_id)
320 if (le_adv_slot[slot_id].hold_timer_id > 0) {
321 BT_INFO("Hold state adv is not unregistered");
325 g_free(le_adv_slot[slot_id].sender);
326 le_adv_slot[slot_id].sender = NULL;
327 le_adv_slot[slot_id].adv_handle = 0;
330 const char* _bt_get_adv_slot_owner(int slot_id)
332 if (le_adv_slot == NULL)
335 return le_adv_slot[slot_id].sender;
338 int _bt_get_adv_slot_adv_handle(int slot_id)
340 if (le_adv_slot == NULL)
343 return le_adv_slot[slot_id].adv_handle;
346 void _bt_set_advertising_status(int slot_id, gboolean mode)
348 le_adv_slot[slot_id].is_advertising = mode;
351 gboolean _bt_is_advertising(void)
353 gboolean status = FALSE;
356 if (le_adv_slot == NULL)
359 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
360 if (le_adv_slot[i].is_advertising == TRUE)
367 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
371 if (le_adv_slot == NULL)
374 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
375 if (le_adv_slot[i].sender != NULL) {
376 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
377 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
378 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
384 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
389 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
394 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
397 GError *error = NULL;
401 if (__bt_is_factory_test_mode()) {
402 BT_ERR("Unable to start advertising in factory binary !!");
403 return BLUETOOTH_ERROR_NOT_SUPPORT;
406 if (_bt_adapter_get_status() != BT_ACTIVATED &&
407 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
408 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
411 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
413 BT_ERR("There is NO available slot!!");
414 return BLUETOOTH_ERROR_NO_RESOURCES;
417 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
418 return BLUETOOTH_ERROR_IN_PROGRESS;
420 if (le_adv_slot[slot_id].hold_timer_id > 0) {
421 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
422 le_adv_slot[slot_id].hold_timer_id = 0;
423 _bt_unregister_adv_slot_owner(slot_id);
426 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
427 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
429 proxy = _bt_get_adapter_proxy();
430 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
432 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
433 g_variant_new("(bi)", enable, slot_id),
434 G_DBUS_CALL_FLAGS_NONE,
440 BT_INFO("SetAdvertising %d, slot_id %d", enable, slot_id);
441 BT_ERR("SetAdvertising Fail: %s", error->message);
442 g_clear_error(&error);
443 return BLUETOOTH_ERROR_INTERNAL;
447 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
449 le_adv_slot[slot_id].is_advertising = enable;
450 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
453 g_variant_unref(ret);
455 return BLUETOOTH_ERROR_NONE;
458 int _bt_set_custom_advertising(const char *sender, int adv_handle,
459 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
463 GError *error = NULL;
468 BT_CHECK_PARAMETER(params, return);
470 if (__bt_is_factory_test_mode()) {
471 BT_ERR("Unable to start advertising in factory binary !!");
472 return BLUETOOTH_ERROR_NOT_SUPPORT;
475 if (_bt_adapter_get_status() != BT_ACTIVATED &&
476 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
477 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
480 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
482 BT_ERR("There is NO available slot!!");
483 return BLUETOOTH_ERROR_NO_RESOURCES;
486 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
487 return BLUETOOTH_ERROR_IN_PROGRESS;
489 if (le_adv_slot[slot_id].hold_timer_id > 0) {
490 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
491 le_adv_slot[slot_id].hold_timer_id = 0;
492 _bt_unregister_adv_slot_owner(slot_id);
495 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
496 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
498 proxy = _bt_get_adapter_proxy();
499 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
501 if (params->interval_min > params->interval_max ||
502 params->interval_min < BT_ADV_INTERVAL_MIN ||
503 params->interval_max > BT_ADV_INTERVAL_MAX)
504 return BLUETOOTH_ERROR_INVALID_PARAM;
506 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
507 return BLUETOOTH_ERROR_INVALID_PARAM;
509 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
510 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
511 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
512 return BLUETOOTH_ERROR_NOT_SUPPORT;
514 if (params->tx_power_level > 1 ||
515 params->tx_power_level < -127)
516 return BLUETOOTH_ERROR_INVALID_PARAM;
518 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
519 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
521 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
522 g_variant_new("(uuuuii)", min, max,
523 params->filter_policy, params->type,
524 params->tx_power_level, slot_id),
525 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
528 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
529 g_clear_error(&error);
530 return BLUETOOTH_ERROR_INTERNAL;
533 adv_params.interval_min = params->interval_min;
534 adv_params.interval_max = params->interval_max;
535 adv_params.filter_policy = params->filter_policy;
536 adv_params.type = params->type;
537 adv_params.tx_power_level = params->tx_power_level;
540 g_variant_unref(ret);
542 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
543 g_variant_new("(bi)", enable, slot_id),
544 G_DBUS_CALL_FLAGS_NONE,
550 BT_ERR("SetAdvertising Fail: %s", error->message);
551 g_clear_error(&error);
552 return BLUETOOTH_ERROR_INTERNAL;
556 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
558 le_adv_slot[slot_id].is_advertising = enable;
559 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
561 g_variant_unref(ret);
563 return BLUETOOTH_ERROR_NONE;
566 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
569 GError *error = NULL;
572 BT_INFO("Restart advertising stopped by bt-service");
574 le_adv_slot[0].hold_timer_id = 0;
576 proxy = _bt_get_adapter_proxy();
577 retv_if(proxy == NULL, FALSE);
579 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
580 g_variant_new("(bi)", TRUE, 0),
581 G_DBUS_CALL_FLAGS_NONE,
587 BT_ERR("SetAdvertising Fail: %s", error->message);
588 g_clear_error(&error);
593 g_variant_unref(ret);
598 int _bt_hold_current_advertising(void)
601 GError *error = NULL;
604 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
605 BT_INFO("Stop current advertising by bt-service");
607 proxy = _bt_get_adapter_proxy();
608 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
610 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
611 g_variant_new("(bi)", FALSE, 0),
612 G_DBUS_CALL_FLAGS_NONE,
618 BT_ERR("SetAdvertising Fail: %s", error->message);
619 g_clear_error(&error);
620 return BLUETOOTH_ERROR_INTERNAL;
624 g_variant_unref(ret);
626 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
627 __bt_hold_current_advertising_timeout_cb, NULL);
629 BT_INFO("It's NOT advertising");
630 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
633 return BLUETOOTH_ERROR_NONE;
636 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
637 char in_type, char **data, int *data_len)
639 if (in_data == NULL || data == NULL || data_len == NULL)
640 return BLUETOOTH_ERROR_INTERNAL;
643 return BLUETOOTH_ERROR_INTERNAL;
649 for (i = 0; i < in_len; i++) {
651 if (len <= 0 || i + 1 >= in_len) {
652 BT_ERR("Invalid advertising data");
653 return BLUETOOTH_ERROR_INTERNAL;
656 type = in_data[i + 1];
657 if (type == in_type) {
667 if (i + len > in_len) {
668 BT_ERR("Invalid advertising data");
669 return BLUETOOTH_ERROR_INTERNAL;
670 } else if (len == 0) {
671 BT_DBG("AD Type 0x%02x data is not set", in_type);
674 return BLUETOOTH_ERROR_NONE;
677 *data = g_memdup(&in_data[i], len);
679 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
682 return BLUETOOTH_ERROR_NONE;
685 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
687 BT_CHECK_PARAMETER(adv, return);
688 BT_CHECK_PARAMETER(length, return);
690 memcpy(adv, &adv_data, sizeof(adv_data));
691 *length = adv_data_len;
693 return BLUETOOTH_ERROR_NONE;
696 int _bt_set_advertising_data(const char *sender, int adv_handle,
697 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
700 GError *error = NULL;
701 GVariant *ret, *ad_data, *param = NULL;
702 GVariant *temp = NULL;
703 GVariantBuilder *builder;
705 char *old_mdata = NULL;
706 char *new_mdata = NULL;
711 if (__bt_is_factory_test_mode()) {
712 BT_ERR("Unable to set advertising data in factory binary !!");
713 return BLUETOOTH_ERROR_NOT_SUPPORT;
716 BT_CHECK_PARAMETER(adv, return);
718 if (_bt_adapter_get_status() != BT_ACTIVATED &&
719 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
720 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
723 proxy = _bt_get_adapter_proxy();
724 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
726 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
728 BT_ERR("There is NO available slot!!");
729 return BLUETOOTH_ERROR_NO_RESOURCES;
732 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
733 for (i = 0; i < length; i++)
734 g_variant_builder_add(builder, "y", adv->data[i]);
736 temp = g_variant_new("ay", builder);
737 g_variant_builder_unref(builder);
738 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
739 g_variant_new("(@ayi)", temp, slot_id),
740 G_DBUS_CALL_FLAGS_NONE,
744 BT_ERR("SetAdvertisingData Fail: %s", error->message);
745 g_clear_error(&error);
746 return BLUETOOTH_ERROR_INTERNAL;
749 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
751 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
752 &old_mdata, &old_len);
753 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
754 &new_mdata, &new_len);
755 if (old_len != new_len ||
756 (old_mdata && new_mdata &&
757 memcmp(old_mdata, new_mdata, new_len))) {
758 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
759 new_mdata, new_len, TRUE, NULL, NULL);
760 param = g_variant_new("(@ay)", ad_data);
761 _bt_send_event(BT_ADAPTER_EVENT,
762 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
768 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
769 memcpy(&adv_data, adv, length);
770 adv_data_len = length;
772 BT_INFO("Set advertising data");
774 g_variant_unref(ret);
776 return BLUETOOTH_ERROR_NONE;
779 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
781 BT_CHECK_PARAMETER(response, return);
782 BT_CHECK_PARAMETER(length, return);
784 memcpy(response, &resp_data, sizeof(resp_data));
785 *length = resp_data_len;
787 return BLUETOOTH_ERROR_NONE;
790 int _bt_set_scan_response_data(const char *sender, int adv_handle,
791 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
794 GError *error = NULL;
795 GVariant *ret, *scan_data, *param = NULL;
796 GVariant *temp = NULL;
797 GVariantBuilder *builder;
799 char *old_mdata = NULL;
800 char *new_mdata = NULL;
805 if (__bt_is_factory_test_mode()) {
806 BT_ERR("Unable to set scan response list in factory binary !!");
807 return BLUETOOTH_ERROR_NOT_SUPPORT;
810 BT_CHECK_PARAMETER(response, return);
812 if (_bt_adapter_get_status() != BT_ACTIVATED &&
813 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
814 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
817 proxy = _bt_get_adapter_proxy();
818 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
820 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
822 BT_ERR("There is NO available slot!!");
823 return BLUETOOTH_ERROR_NO_RESOURCES;
825 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
826 for (i = 0; i < length; i++)
827 g_variant_builder_add(builder, "y", response->data[i]);
829 temp = g_variant_new("ay", builder);
830 g_variant_builder_unref(builder);
831 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
832 g_variant_new("(@ayi)", temp, slot_id),
833 G_DBUS_CALL_FLAGS_NONE,
837 BT_ERR("SetScanRespData Fail: %s", error->message);
838 g_clear_error(&error);
839 return BLUETOOTH_ERROR_INTERNAL;
842 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
844 /* Compare with previous scan resp data */
845 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
846 &old_mdata, &old_len);
847 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
848 &new_mdata, &new_len);
849 if (old_len != new_len ||
850 (old_mdata && new_mdata &&
851 memcmp(old_mdata, new_mdata, new_len))) {
852 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
853 new_mdata, new_len, TRUE, NULL, NULL);
854 param = g_variant_new("(@ay)", scan_data);
855 _bt_send_event(BT_ADAPTER_EVENT,
856 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
862 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
863 memcpy(&resp_data, response, length);
864 resp_data_len = length;
867 g_variant_unref(ret);
868 BT_INFO("Set scan response data");
869 return BLUETOOTH_ERROR_NONE;
872 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
875 GError *error = NULL;
880 BT_CHECK_PARAMETER(params, return);
882 if (_bt_adapter_get_status() != BT_ACTIVATED &&
883 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
884 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
887 proxy = _bt_get_adapter_proxy();
888 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
890 BT_DBG("inteval %f, win %f, type %d", params->interval, params->window, params->type);
892 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
893 return BLUETOOTH_ERROR_INVALID_PARAM;
895 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
896 return BLUETOOTH_ERROR_INVALID_PARAM;
898 if (params->window > params->interval)
899 return BLUETOOTH_ERROR_INVALID_PARAM;
901 itv = params->interval / BT_SCAN_INTERVAL_SPLIT;
902 win = params->window / BT_SCAN_INTERVAL_SPLIT;
904 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
905 g_variant_new("(uuu)", params->type, itv, win),
906 G_DBUS_CALL_FLAGS_NONE, -1,
910 BT_ERR("SetScanParameters Fail: %s", error->message);
911 g_clear_error(&error);
912 return BLUETOOTH_ERROR_INTERNAL;
915 _bt_set_le_scan_type(params->type);
917 is_le_set_scan_parameter = TRUE;
920 g_variant_unref(ret);
921 BT_INFO("Set scan parameters inteval %f, win %f, type %d",
922 itv * BT_SCAN_INTERVAL_SPLIT, win * BT_SCAN_INTERVAL_SPLIT, params->type);
923 return BLUETOOTH_ERROR_NONE;
926 int _bt_prepare_scan_parameters(bluetooth_le_scan_params_t *params, int scan_type)
928 if (_bt_adapter_get_status() != BT_ACTIVATED &&
929 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
930 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
934 BT_DBG("inteval %f, win %f", params->interval, params->window);
936 BT_DBG("type %d", scan_type);
939 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
940 return BLUETOOTH_ERROR_INVALID_PARAM;
942 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
943 return BLUETOOTH_ERROR_INVALID_PARAM;
945 if (params->window > params->interval)
946 return BLUETOOTH_ERROR_INVALID_PARAM;
948 le_scan_params.interval = params->interval;
949 le_scan_params.window = params->window;
951 le_scan_params.type = scan_type;
952 if (le_scan_params.interval == 0) {
953 /* Set default scan interval same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
954 le_scan_params.interval = 5120;
955 le_scan_params.window = 512;
959 is_le_set_scan_parameter = TRUE;
961 return BLUETOOTH_ERROR_NONE;
964 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
967 bt_adapter_le_scanner_t *scanner;
969 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
971 if (g_strcmp0(scanner->sender, sender) == 0)
978 static int __bt_get_available_scan_filter_slot_id(void)
981 bt_adapter_le_scanner_t *scanner;
983 bluetooth_le_scan_filter_t *filter_data;
984 gboolean *slot_check_list = NULL;
987 if (le_feature_info.max_filter == 0) {
988 BT_ERR("Scan filter is NOT Supported");
991 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
993 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
995 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
996 filter_data = fl->data;
997 if (filter_data->slot_id < le_feature_info.max_filter)
998 slot_check_list[filter_data->slot_id] = TRUE;
1002 for (i = 0; i < le_feature_info.max_filter; i++) {
1003 if (slot_check_list[i] == FALSE) {
1004 g_free(slot_check_list);
1009 BT_ERR("There is NO available slot for scan filter.");
1010 g_free(slot_check_list);
1014 gboolean _bt_is_scan_filter_supported(void)
1016 if (le_feature_info.max_filter > 0)
1022 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter)
1025 GError *error = NULL;
1026 GVariant *ret, *param;
1027 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
1028 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
1029 GArray *arr_uuid = NULL;
1030 GArray *arr_uuid_mask = NULL;
1031 GArray *arr_data = NULL;
1032 GArray *arr_data_mask = NULL;
1033 bt_adapter_le_scanner_t *scanner = NULL;
1034 bluetooth_le_scan_filter_t *filter_data = NULL;
1035 int feature_selection = 0;
1038 slot_id = __bt_get_available_scan_filter_slot_id();
1040 return BLUETOOTH_ERROR_NO_RESOURCES;
1042 proxy = _bt_get_adapter_proxy();
1043 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1045 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1046 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1047 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
1049 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
1051 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1052 NULL, 0, TRUE, NULL, NULL);
1053 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1054 NULL, 0, TRUE, NULL, NULL);
1055 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1056 NULL, 0, TRUE, NULL, NULL);
1057 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1058 NULL, 0, TRUE, NULL, NULL);
1060 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1062 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1063 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
1064 slot_id, // filter_index
1066 0, // company_id_mask
1067 arr_uuid_param, // p_uuid
1068 arr_uuid_mask_param, // p_uuid_mask
1071 arr_data_param, // p_data
1072 arr_data_mask_param); // p_mask
1074 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1075 param, G_DBUS_CALL_FLAGS_NONE,
1079 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1080 g_clear_error(&error);
1083 g_variant_unref(ret);
1086 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1087 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
1089 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1090 NULL, 0, TRUE, NULL, NULL);
1091 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1092 NULL, 0, TRUE, NULL, NULL);
1093 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1094 NULL, 0, TRUE, NULL, NULL);
1095 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1096 NULL, 0, TRUE, NULL, NULL);
1098 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1100 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1101 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1102 slot_id, // filter_index
1104 0, // company_id_mask
1105 arr_uuid_param, // p_uuid
1106 arr_uuid_mask_param, // p_uuid_mask
1107 filter->device_name, // string
1109 arr_data_param, // p_data
1110 arr_data_mask_param);
1112 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1113 param, G_DBUS_CALL_FLAGS_NONE,
1117 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1118 g_clear_error(&error);
1121 g_variant_unref(ret);
1124 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1125 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1127 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1128 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1130 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1131 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1133 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1134 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1135 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1136 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1137 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1138 NULL, 0, TRUE, NULL, NULL);
1139 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1140 NULL, 0, TRUE, NULL, NULL);
1142 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1144 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1145 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1146 slot_id, // filter_index
1148 0, // company_id_mask
1149 arr_uuid_param, // p_uuid
1150 arr_uuid_mask_param, // p_uuid_mask
1153 arr_data_param, // p_data
1154 arr_data_mask_param);
1156 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1157 param, G_DBUS_CALL_FLAGS_NONE,
1161 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1162 g_clear_error(&error);
1165 g_variant_unref(ret);
1167 g_array_free(arr_uuid, TRUE);
1168 g_array_free(arr_uuid_mask, TRUE);
1171 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1172 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1174 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1175 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1177 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1178 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1180 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1181 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1182 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1183 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1184 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1185 NULL, 0, TRUE, NULL, NULL);
1186 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1187 NULL, 0, TRUE, NULL, NULL);
1189 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1191 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1192 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1193 slot_id, // filter_index
1195 0, // company_id_mask
1196 arr_uuid_param, // p_uuid
1197 arr_uuid_mask_param, // p_uuid_mask
1200 arr_data_param, // p_data
1201 arr_data_mask_param);
1203 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1204 G_DBUS_CALL_FLAGS_NONE,
1208 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1209 g_clear_error(&error);
1212 g_variant_unref(ret);
1214 g_array_free(arr_uuid, TRUE);
1215 g_array_free(arr_uuid_mask, TRUE);
1218 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1219 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1221 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1222 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1224 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1225 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1227 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1228 NULL, 0, TRUE, NULL, NULL);
1229 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1230 NULL, 0, TRUE, NULL, NULL);
1231 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1232 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1233 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1234 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1236 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1238 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1239 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1240 slot_id, // filter_index
1242 0, // company_id_mask
1243 arr_uuid_param, // p_uuid
1244 arr_uuid_mask_param, // p_uuid_mask
1247 arr_data_param, // p_data
1248 arr_data_mask_param);
1250 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1251 G_DBUS_CALL_FLAGS_NONE,
1255 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1256 g_clear_error(&error);
1259 g_variant_unref(ret);
1261 g_array_free(arr_data, TRUE);
1262 g_array_free(arr_data_mask, TRUE);
1265 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1266 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1268 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1269 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1271 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1272 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1274 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1275 NULL, 0, TRUE, NULL, NULL);
1276 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1277 NULL, 0, TRUE, NULL, NULL);
1278 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1279 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1280 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1281 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1283 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1285 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1286 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1287 slot_id, // filter_index
1288 filter->manufacturer_id, // company_id
1289 0xFFFF, // company_id_mask
1290 arr_uuid_param, // p_uuid
1291 arr_uuid_mask_param, // p_uuid_mask
1294 arr_data_param, // p_data
1295 arr_data_mask_param);
1297 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1298 G_DBUS_CALL_FLAGS_NONE,
1302 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1303 g_clear_error(&error);
1306 g_variant_unref(ret);
1308 g_array_free(arr_data, TRUE);
1309 g_array_free(arr_data_mask, TRUE);
1312 BT_DBG("Filter selection %.2x", feature_selection);
1314 param = g_variant_new("(iiiiiiiiiiii)",
1316 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1317 slot_id, // filter_index
1318 feature_selection, // feat_seln
1319 0, // list_logic_type (OR - 0x00, AND - 0x01)
1320 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1321 -127, // rssi_high_thres
1322 -127, // rssi_low_thres
1323 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1326 0); // found_timeout_cnt
1327 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1328 param, G_DBUS_CALL_FLAGS_NONE,
1332 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1333 g_clear_error(&error);
1336 scanner = __bt_find_scanner_from_list(sender);
1337 if (scanner == NULL) {
1338 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1339 scanner->sender = g_strdup(sender);
1340 scanner_list = g_slist_append(scanner_list, scanner);
1345 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1346 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1347 filter_data->slot_id = slot_id;
1349 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1353 g_variant_unref(ret);
1354 return BLUETOOTH_ERROR_NONE;
1357 int _bt_unregister_all_scan_filters(const char *sender)
1360 GError *error = NULL;
1362 bt_adapter_le_scanner_t *scanner = NULL;
1363 bluetooth_le_scan_filter_t *filter_data = NULL;
1366 scanner = __bt_find_scanner_from_list(sender);
1367 if (scanner == NULL) {
1368 BT_ERR("There is NO available scanner.");
1369 return BLUETOOTH_ERROR_NOT_FOUND;
1372 proxy = _bt_get_adapter_proxy();
1373 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1375 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1376 filter_data = l->data;
1378 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1379 g_variant_new("(ii)", 0, filter_data->slot_id),
1380 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1383 BT_ERR("scan_filter_clear Fail: %s", error->message);
1384 g_clear_error(&error);
1387 g_variant_unref(ret);
1390 g_slist_free_full(scanner->filter_list, g_free);
1391 scanner->filter_list = NULL;
1393 return BLUETOOTH_ERROR_NONE;
1396 int _bt_start_le_scan(const char *sender)
1399 GError *error = NULL;
1401 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1403 if (scanner == NULL) {
1404 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1405 scanner->sender = g_strdup(sender);
1406 scanner_list = g_slist_append(scanner_list, scanner);
1409 if (scanner->is_scanning == TRUE) {
1410 BT_ERR("BT is already in LE scanning");
1411 return BLUETOOTH_ERROR_IN_PROGRESS;
1413 scanner->is_scanning = TRUE;
1415 proxy = _bt_get_adapter_proxy();
1416 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1418 if (_bt_is_le_scanning()) {
1419 if (scan_filter_enabled == TRUE) {
1420 if (scanner->filter_list == NULL) {
1421 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1422 g_variant_new("(ib)", 0, FALSE),
1423 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1426 BT_ERR("scan_filter_enable Fail: %s", error->message);
1427 g_clear_error(&error);
1431 g_variant_unref(ret);
1432 BT_INFO("Disable LE Scan Filter");
1433 scan_filter_enabled = FALSE;
1435 BT_INFO("LE Filter Scan is continue");
1438 BT_INFO("LE Full Scan is already on progress");
1440 return BLUETOOTH_ERROR_NONE;
1442 if (is_le_set_scan_parameter == FALSE) {
1443 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1444 bluetooth_le_scan_params_t scan_params;
1445 scan_params.type = BT_LE_ACTIVE_SCAN;
1446 scan_params.interval = 5120;
1447 scan_params.window = 512;
1448 _bt_set_scan_parameters(&scan_params);
1450 _bt_set_scan_parameters(&le_scan_params);
1452 if (scanner->filter_list == NULL) {
1453 BT_INFO("Start LE Full Scan");
1454 scan_filter_enabled = FALSE;
1456 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1457 g_variant_new("(ib)", 0, TRUE),
1458 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1461 BT_ERR("scan_filter_enable Fail: %s", error->message);
1462 g_clear_error(&error);
1466 g_variant_unref(ret);
1467 BT_INFO("Enable LE Scan Filter");
1468 scan_filter_enabled = TRUE;
1472 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1473 NULL, G_DBUS_CALL_FLAGS_NONE,
1477 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1478 g_clear_error(&error);
1479 return BLUETOOTH_ERROR_INTERNAL;
1483 g_variant_unref(ret);
1484 return BLUETOOTH_ERROR_NONE;
1487 int _bt_stop_le_scan(const char *sender)
1490 GError *error = NULL;
1492 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1494 gboolean next_scanning = FALSE;
1495 gboolean need_scan_filter = TRUE;
1497 if (scanner == NULL || scanner->is_scanning == FALSE)
1498 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1500 _bt_unregister_all_scan_filters(sender);
1502 scanner_list = g_slist_remove(scanner_list, scanner);
1503 __bt_free_le_scanner(scanner);
1505 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1507 if (scanner->is_scanning == TRUE) {
1508 next_scanning = TRUE;
1509 if (scanner->filter_list == NULL)
1510 need_scan_filter = FALSE;
1514 proxy = _bt_get_adapter_proxy();
1515 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1517 if (next_scanning == TRUE) {
1518 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1519 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1520 g_variant_new("(ib)", 0, TRUE),
1521 G_DBUS_CALL_FLAGS_NONE,
1525 BT_ERR("scan_filter_enable Fail: %s", error->message);
1526 g_clear_error(&error);
1530 g_variant_unref(ret);
1531 BT_INFO("Enable LE Scan Filter");
1532 scan_filter_enabled = TRUE;
1534 BT_INFO("next_scanning exists. Keep the LE scanning");
1535 return BLUETOOTH_ERROR_NONE;
1537 if (scan_filter_enabled == TRUE) {
1538 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1539 g_variant_new("(ib)", 0, FALSE),
1540 G_DBUS_CALL_FLAGS_NONE,
1544 BT_ERR("scan_filter_enable Fail: %s", error->message);
1545 g_clear_error(&error);
1549 g_variant_unref(ret);
1550 BT_INFO("Disable LE Scan Filter");
1552 BT_INFO("Just stop LE scan");
1556 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1557 NULL, G_DBUS_CALL_FLAGS_NONE,
1560 BT_ERR("StopLEDiscovery Fail: %s", error->message);
1561 g_clear_error(&error);
1565 BT_ERR("LE Scan stop failed");
1566 return BLUETOOTH_ERROR_INTERNAL;
1569 scan_filter_enabled = FALSE;
1570 is_le_set_scan_parameter = FALSE;
1571 le_scan_params.type = BT_LE_ACTIVE_SCAN;
1572 le_scan_params.interval = 0;
1573 le_scan_params.window = 0;
1575 g_variant_unref(ret);
1576 return BLUETOOTH_ERROR_NONE;
1579 void _bt_disable_all_scanner_status(void)
1582 bt_adapter_le_scanner_t *scanner;
1584 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1586 scanner->is_scanning = FALSE;
1590 void _bt_set_le_scan_status(gboolean mode)
1592 BT_DBG("set is_le_scanning : %d -> %d", is_le_scanning, mode);
1593 is_le_scanning = mode;
1596 gboolean _bt_is_le_scanning(void)
1598 return is_le_scanning;
1601 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1603 le_scan_type = type;
1606 bt_le_scan_type_t _bt_get_le_scan_type(void)
1608 return le_scan_type;
1611 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1612 int adv_data_len, const char *svc_uuid, int uuid_len,
1613 const char *uuid_mask, char ad_type)
1619 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1620 ad_type, &data, &data_len);
1622 for (i = 0; i < data_len; i += uuid_len) {
1623 if (uuid_len > (data_len - i))
1626 if (_bt_byte_arr_cmp_with_mask(data + i,
1627 svc_uuid, uuid_mask, uuid_len) == 0) {
1638 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1639 const char *adv_data, int adv_data_len,
1640 const char *scan_data, int scan_data_len,
1641 const bt_adapter_le_scanner_t *scanner)
1644 bluetooth_le_scan_filter_t *filter_data = NULL;
1647 gboolean is_matched = FALSE;
1649 if (scanner->filter_list == NULL) {
1650 BT_INFO("This scanner is on Full Scan.");
1654 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1655 filter_data = l->data;
1657 if (filter_data->added_features &
1658 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1659 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1661 _bt_convert_addr_type_to_string(address,
1662 filter_data->device_address.addr);
1663 if (strncmp(address, device_address,
1664 BT_ADDRESS_STRING_SIZE) != 0)
1668 if (filter_data->added_features &
1669 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
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_16_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_16_BIT_SERVICE_CLASS_UUIDS)
1688 if (__bt_check_scan_result_uuid(adv_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_128_BIT_SERVICE_CLASS_UUIDS)
1696 if (__bt_check_scan_result_uuid(adv_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_128_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_16_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_16_BIT_SERVICE_CLASS_UUIDS)
1720 if (__bt_check_scan_result_uuid(scan_data,
1722 (char*)filter_data->service_uuid.data.data,
1723 filter_data->service_uuid.data_len,
1724 (char*)filter_data->service_uuid_mask.data.data,
1725 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1728 if (__bt_check_scan_result_uuid(scan_data,
1730 (char*)filter_data->service_uuid.data.data,
1731 filter_data->service_uuid.data_len,
1732 (char*)filter_data->service_uuid_mask.data.data,
1733 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1737 if (is_matched == FALSE)
1740 if (filter_data->added_features &
1741 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1744 if (__bt_check_scan_result_uuid(adv_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(adv_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)
1760 if (__bt_check_scan_result_uuid(scan_data,
1762 (char*)filter_data->service_solicitation_uuid.data.data,
1763 filter_data->service_solicitation_uuid.data_len,
1764 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1765 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1768 if (__bt_check_scan_result_uuid(scan_data,
1770 (char*)filter_data->service_solicitation_uuid.data.data,
1771 filter_data->service_solicitation_uuid.data_len,
1772 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1773 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1777 if (is_matched == FALSE)
1780 if (filter_data->added_features &
1781 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1782 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1787 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1788 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1791 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1792 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1793 memcpy(name, data, data_len);
1794 name[data_len] = '\0';
1797 if (strncmp(filter_data->device_name,
1798 name, data_len) == 0)
1801 __bt_get_ad_data_by_type((char*)scan_data,
1803 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1806 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1807 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1808 memcpy(name, data, data_len);
1809 name[data_len] = '\0';
1812 if (strncmp(filter_data->device_name,
1813 name, data_len) == 0)
1817 if (is_matched == FALSE)
1820 if (filter_data->added_features &
1821 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1826 __bt_get_ad_data_by_type((char*)adv_data,
1828 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1832 int manufacturer_id;
1833 manufacturer_id = (data[1] << 8) + data[0];
1835 if (filter_data->manufacturer_id == manufacturer_id) {
1836 if (filter_data->manufacturer_data.data_len == 0) {
1839 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1840 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1841 if (_bt_byte_arr_cmp_with_mask(data + 2,
1842 (char*)filter_data->manufacturer_data.data.data,
1843 (char*)filter_data->manufacturer_data_mask.data.data,
1844 data_len - 2) == 0) {
1852 __bt_get_ad_data_by_type((char*)scan_data,
1854 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1858 int manufacturer_id;
1859 manufacturer_id = (data[1] << 8) + data[0];
1861 if (filter_data->manufacturer_id == manufacturer_id) {
1862 if (filter_data->manufacturer_data.data_len == 0) {
1865 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1866 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1867 if (_bt_byte_arr_cmp_with_mask(data + 2,
1868 (char*)filter_data->manufacturer_data.data.data,
1869 (char*)filter_data->manufacturer_data_mask.data.data,
1870 data_len - 2) == 0) {
1879 if (is_matched == FALSE)
1882 if (filter_data->added_features &
1883 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1888 __bt_get_ad_data_by_type((char*)adv_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,
1904 __bt_get_ad_data_by_type((char*)scan_data,
1906 BT_LE_AD_TYPE_SERVICE_DATA,
1909 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1910 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1911 if (_bt_byte_arr_cmp_with_mask(data,
1912 (char*)filter_data->service_data.data.data,
1913 (char*)filter_data->service_data_mask.data.data,
1921 if (is_matched == FALSE)
1925 BT_INFO("The scan result is conformable.");
1929 BT_INFO("The scan result is NOT conformable.");
1933 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1934 const bt_le_adv_info_t *adv_info)
1936 int result = BLUETOOTH_ERROR_NONE;
1938 GVariant *scan_data_param, *adv_data_param;
1940 bt_adapter_le_scanner_t *scanner = NULL;
1941 const char *adv_data = NULL;
1942 int adv_data_len = 0;
1943 const char *scan_data = NULL;
1944 int scan_data_len = 0;
1946 ret_if(le_dev_info == NULL);
1948 if (adv_info == NULL) { /* Not received scan response data within 1 sec */
1949 adv_data = le_dev_info->adv_data;
1950 adv_data_len = le_dev_info->adv_data_len;
1951 scan_data = le_dev_info->adv_data;
1954 adv_data = adv_info->data;
1955 adv_data_len = adv_info->data_len;
1956 scan_data = le_dev_info->adv_data;
1957 scan_data_len = le_dev_info->adv_data_len;
1960 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1962 if (scanner->is_scanning == FALSE)
1965 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1966 adv_data, adv_data_len, scan_data, scan_data_len,
1970 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1971 adv_data, adv_data_len, TRUE, NULL, NULL);
1972 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1973 scan_data, scan_data_len, TRUE, NULL, NULL);
1975 param = g_variant_new("(isnnn@ayn@ay)",
1977 le_dev_info->address,
1978 le_dev_info->addr_type,
1986 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1987 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1989 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1994 void _bt_send_ibeacon_scan_result_event(const bt_remote_ibeacon_dev_info_t *ibeacon_dev_info)
1996 int result = BLUETOOTH_ERROR_NONE;
1999 bt_adapter_le_scanner_t *scanner = NULL;
2001 ret_if(ibeacon_dev_info == NULL);
2002 BT_DBG("_bt_send_ibeacon_scan_result_event");
2004 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
2006 if (scanner->is_scanning == FALSE)
2009 param = g_variant_new("(isnnnsnnn)",
2011 ibeacon_dev_info->address,
2012 ibeacon_dev_info->addr_type,
2013 ibeacon_dev_info->company_id,
2014 ibeacon_dev_info->ibeacon_type,
2015 ibeacon_dev_info->uuid,
2016 ibeacon_dev_info->major_id,
2017 ibeacon_dev_info->minor_id,
2018 ibeacon_dev_info->measured_power);
2020 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_IBEACON_DEVICE_FOUND, param);
2024 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2027 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2028 GError *error = NULL;
2031 if (__bt_is_factory_test_mode()) {
2032 BT_ERR("Unable to add white list in factory binary !!");
2033 return BLUETOOTH_ERROR_NOT_SUPPORT;
2036 BT_CHECK_PARAMETER(device_address, return);
2038 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2039 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2040 return BLUETOOTH_ERROR_INVALID_PARAM;
2042 _bt_convert_addr_type_to_string(address, device_address->addr);
2044 proxy = _bt_get_adapter_proxy();
2045 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2047 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
2048 g_variant_new("(su)", address, address_type),
2049 G_DBUS_CALL_FLAGS_NONE, -1,
2053 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
2054 g_clear_error(&error);
2055 return BLUETOOTH_ERROR_INTERNAL;
2059 g_variant_unref(ret);
2060 BT_INFO("Add white list");
2062 return BLUETOOTH_ERROR_NONE;
2065 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2068 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2069 GError *error = NULL;
2072 if (__bt_is_factory_test_mode()) {
2073 BT_ERR("Unable to remove white list in factory binary !!");
2074 return BLUETOOTH_ERROR_NOT_SUPPORT;
2077 BT_CHECK_PARAMETER(device_address, return);
2079 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2080 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2081 return BLUETOOTH_ERROR_INVALID_PARAM;
2083 _bt_convert_addr_type_to_string(address, device_address->addr);
2085 proxy = _bt_get_adapter_proxy();
2086 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2088 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
2089 g_variant_new("(su)", address, address_type),
2090 G_DBUS_CALL_FLAGS_NONE, -1,
2094 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2095 g_clear_error(&error);
2096 return BLUETOOTH_ERROR_INTERNAL;
2100 g_variant_unref(ret);
2101 BT_INFO("Remove white list");
2103 return BLUETOOTH_ERROR_NONE;
2106 int _bt_clear_white_list(void)
2109 GError *error = NULL;
2112 if (__bt_is_factory_test_mode()) {
2113 BT_ERR("Unable to clear white list in factory binary !!");
2114 return BLUETOOTH_ERROR_NOT_SUPPORT;
2117 proxy = _bt_get_adapter_proxy();
2118 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2120 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2121 NULL, G_DBUS_CALL_FLAGS_NONE,
2125 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2126 g_clear_error(&error);
2127 return BLUETOOTH_ERROR_INTERNAL;
2130 g_variant_unref(ret);
2132 BT_INFO("Clear white list");
2134 return BLUETOOTH_ERROR_NONE;
2137 int _bt_initialize_ipsp(void)
2141 GError *error = NULL;
2144 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2145 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2146 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2149 proxy = _bt_get_adapter_proxy();
2150 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2152 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2153 NULL, G_DBUS_CALL_FLAGS_NONE,
2156 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2157 g_clear_error(&error);
2158 return BLUETOOTH_ERROR_INTERNAL;
2161 g_variant_unref(ret);
2163 BT_INFO("IPSP initialization called successfully");
2165 return BLUETOOTH_ERROR_NONE;
2168 int _bt_deinitialize_ipsp(void)
2172 GError *error = NULL;
2175 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2176 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2177 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2180 proxy = _bt_get_adapter_proxy();
2181 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2183 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2184 NULL, G_DBUS_CALL_FLAGS_NONE,
2187 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2188 g_clear_error(&error);
2189 return BLUETOOTH_ERROR_INTERNAL;
2192 g_variant_unref(ret);
2194 BT_INFO("IPSP De-initialization called successfully");
2196 return BLUETOOTH_ERROR_NONE;
2199 int _bt_le_read_maximum_data_length(
2200 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2202 GError *error = NULL;
2204 GVariant *reply = NULL;
2205 guint16 max_tx_octets, max_tx_time;
2206 guint16 max_rx_octets, max_rx_time;
2208 proxy = _bt_get_adapter_proxy();
2209 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2211 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2212 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2214 if (reply == NULL) {
2215 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2216 if (error != NULL) {
2217 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2218 error->code, error->message);
2219 g_clear_error(&error);
2221 return BLUETOOTH_ERROR_INTERNAL;
2224 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2225 &max_rx_octets, &max_rx_time);
2227 max_le_datalength->max_tx_octets = max_tx_octets;
2228 max_le_datalength->max_tx_time = max_tx_time;
2229 max_le_datalength->max_rx_octets = max_rx_octets;
2230 max_le_datalength->max_rx_time = max_rx_time;
2232 g_variant_unref(reply);
2234 return BLUETOOTH_ERROR_NONE;
2236 int _bt_le_write_host_suggested_default_data_length(
2237 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2239 GError *error = NULL;
2241 GVariant *reply = NULL;
2243 proxy = _bt_get_adapter_proxy();
2244 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2246 reply = g_dbus_proxy_call_sync(proxy,
2247 "LEWriteHostSuggestedDataLength",
2248 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2249 G_DBUS_CALL_FLAGS_NONE,
2254 if (reply == NULL) {
2255 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2256 if (error != NULL) {
2257 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2258 error->code, error->message);
2259 g_clear_error(&error);
2261 return BLUETOOTH_ERROR_INTERNAL;
2264 g_variant_unref(reply);
2266 return BLUETOOTH_ERROR_NONE;
2269 int _bt_le_read_host_suggested_default_data_length(
2270 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2272 GError *error = NULL;
2274 GVariant *reply = NULL;
2275 guint16 def_tx_octets, def_tx_time;
2277 proxy = _bt_get_adapter_proxy();
2278 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2280 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2281 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2283 if (reply == NULL) {
2284 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2285 if (error != NULL) {
2286 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2287 error->code, error->message);
2288 g_clear_error(&error);
2290 return BLUETOOTH_ERROR_INTERNAL;
2293 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2295 def_data_length->def_tx_octets = def_tx_octets;
2296 def_data_length->def_tx_time = def_tx_time;
2298 g_variant_unref(reply);
2300 return BLUETOOTH_ERROR_NONE;
2303 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2304 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2306 GError *error = NULL;
2307 guint16 txOctets = max_tx_Octets;
2308 guint16 txTime = max_tx_Time;
2309 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2310 gchar *device_path = NULL;
2311 GDBusConnection *conn;
2312 GDBusProxy *device_proxy;
2314 _bt_convert_addr_type_to_string(address, device_address->addr);
2316 device_path = _bt_get_device_object_path(address);
2318 if (device_path == NULL) {
2319 BT_DBG("Device path is null");
2320 return BLUETOOTH_ERROR_INTERNAL;
2323 conn = _bt_gdbus_get_system_gconn();
2325 BT_ERR("conn == NULL");
2326 g_free(device_path);
2327 return BLUETOOTH_ERROR_INTERNAL;
2330 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2331 NULL, BT_BLUEZ_NAME,
2332 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2334 g_free(device_path);
2335 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2337 g_dbus_proxy_call_sync(device_proxy,
2339 g_variant_new("(qq)", txOctets, txTime),
2340 G_DBUS_CALL_FLAGS_NONE,
2345 g_object_unref(device_proxy);
2348 BT_ERR("LESetDataLength error: [%s]", error->message);
2349 g_error_free(error);
2350 return BLUETOOTH_ERROR_INTERNAL;
2353 return BLUETOOTH_ERROR_NONE;
2356 int _bt_service_adapter_le_init(void)
2358 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
2360 return BLUETOOTH_ERROR_NONE;
2363 void _bt_service_adapter_le_deinit(void)
2365 __bt_free_le_adv_slot();
2366 __bt_free_le_scanner_all();