2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dbus/dbus.h>
25 #include <syspopup_caller.h>
28 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-event.h"
31 #include "bt-service-adapter.h"
32 #include "bt-service-adapter-le.h"
33 #include "bt-service-util.h"
36 #define BT_ADV_INTERVAL_MIN 20 /* msec */
37 #define BT_ADV_INTERVAL_MAX 10240
38 #define BT_ADV_INTERVAL_SPLIT 0.625
39 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
40 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
41 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
42 #define BT_ADV_TYPE_DEFAULT 0x00
43 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
44 #define BT_ADV_MULTI_MAX 16
50 } bt_adapter_le_feature_info_t;
55 gboolean is_advertising;
57 } bt_adapter_le_adv_slot_t;
63 } bt_adapter_le_scanner_t;
65 static bluetooth_advertising_params_t adv_params = {
66 BT_DEFAULT_ADV_MIN_INTERVAL,
67 BT_DEFAULT_ADV_MAX_INTERVAL,
68 BT_ADV_FILTER_POLICY_DEFAULT,
70 static bluetooth_advertising_data_t adv_data = { {0} };
71 static int adv_data_len;
72 static bluetooth_scan_resp_data_t resp_data = { {0} };
73 static int resp_data_len;
75 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
76 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
78 GSList *scanner_list = NULL;
79 static gboolean is_le_set_scan_parameter = FALSE;
80 static gboolean is_le_scanning = FALSE;
81 static gboolean scan_filter_enabled = FALSE;
82 static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN;
84 static GSList *gatt_client_senders = NULL;
87 gboolean _bt_is_set_scan_parameter(void)
89 return is_le_set_scan_parameter;
92 void _bt_init_gatt_client_senders(void)
94 _bt_clear_request_list();
97 int _bt_insert_gatt_client_sender(char *sender)
101 retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
103 info = g_strdup(sender);
104 retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
106 gatt_client_senders = g_slist_append(gatt_client_senders, info);
108 BT_DBG("insert sender: %s", sender);
110 return BLUETOOTH_ERROR_NONE;
113 int _bt_delete_gatt_client_sender(char *sender)
118 BT_DBG("remove sender: %s", sender);
120 for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) {
125 if (g_strcmp0(info, sender) == 0) {
126 BT_DBG("remove info");
127 gatt_client_senders = g_slist_remove(gatt_client_senders, info);
129 return BLUETOOTH_ERROR_NONE;
133 return BLUETOOTH_ERROR_NOT_FOUND;
136 void _bt_clear_gatt_client_senders(void)
138 if (gatt_client_senders) {
139 g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL);
140 g_slist_free(gatt_client_senders);
141 gatt_client_senders = NULL;
145 static void __bt_send_foreach_event(gpointer data, gpointer user_data)
148 GVariant *param = user_data;
150 _bt_send_event_to_dest(sender, BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
154 void _bt_send_char_value_changed_event(void *param)
157 g_slist_foreach(gatt_client_senders, __bt_send_foreach_event,
160 _bt_send_event(BT_DEVICE_EVENT, BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED, param);
164 void __bt_free_le_adv_slot(void)
168 if (le_adv_slot == NULL)
171 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
172 if (le_adv_slot[i].sender)
173 g_free(le_adv_slot[i].sender);
174 if (le_adv_slot[i].hold_timer_id > 0)
175 g_source_remove(le_adv_slot[i].hold_timer_id);
181 int _bt_service_adapter_le_init(void)
183 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
185 return BLUETOOTH_ERROR_NONE;
188 void _bt_service_adapter_le_deinit(void)
190 __bt_free_le_adv_slot();
193 gboolean _bt_update_le_feature_support(const char *item, const char *value)
195 if (item == NULL || value == NULL)
198 if (g_strcmp0(item, "adv_inst_max") == 0) {
201 slot_num = atoi(value);
202 retv_if(slot_num < 0, FALSE);
203 retv_if(slot_num > BT_ADV_MULTI_MAX, FALSE);
205 if (slot_num != le_feature_info.adv_inst_max) {
206 __bt_free_le_adv_slot();
207 le_feature_info.adv_inst_max = slot_num;
208 BT_INFO("Advertising instance max : %d", le_feature_info.adv_inst_max);
209 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
211 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
212 le_feature_info.rpa_offloading = atoi(value);
213 BT_INFO("RPA offloading : %d", le_feature_info.rpa_offloading);
214 } else if (g_strcmp0(item, "max_filter") == 0) {
215 le_feature_info.max_filter = atoi(value);
216 BT_INFO("BLE Scan max filter : %d", le_feature_info.max_filter);
218 BT_DBG("No registered item");
225 static gboolean __bt_is_factory_test_mode(void)
229 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
230 BT_ERR("Get the DUT Mode fail");
235 BT_INFO("DUT Test Mode !!");
242 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
246 if (le_adv_slot == NULL) {
247 BT_ERR("le_adv_slot is NULL");
251 BT_DBG("adv_inst_max : %d", le_feature_info.adv_inst_max);
253 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
254 if (le_adv_slot[i].sender == NULL)
256 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
260 if (le_feature_info.adv_inst_max <= 2)
262 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
267 for (; i < le_feature_info.adv_inst_max; i++) {
268 if (le_adv_slot[i].sender == NULL)
275 static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
277 if (le_adv_slot[slot_id].sender == NULL) {
278 le_adv_slot[slot_id].sender = strdup(sender);
279 le_adv_slot[slot_id].adv_handle = adv_handle;
283 void _bt_unregister_adv_slot_owner(int slot_id)
285 g_free(le_adv_slot[slot_id].sender);
286 le_adv_slot[slot_id].sender = NULL;
287 le_adv_slot[slot_id].adv_handle = 0;
290 const char* _bt_get_adv_slot_owner(int slot_id)
292 if (le_adv_slot == NULL)
295 return le_adv_slot[slot_id].sender;
298 int _bt_get_adv_slot_adv_handle(int slot_id)
300 if (le_adv_slot == NULL)
303 return le_adv_slot[slot_id].adv_handle;
306 void _bt_set_advertising_status(int slot_id, gboolean mode)
308 le_adv_slot[slot_id].is_advertising = mode;
311 gboolean _bt_is_advertising(void)
313 gboolean status = FALSE;
316 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
317 if (le_adv_slot[i].is_advertising == TRUE)
324 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
328 if (le_adv_slot == NULL)
331 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
332 if (le_adv_slot[i].sender != NULL) {
333 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
334 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
335 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
341 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
346 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
351 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
354 GError *error = NULL;
358 if (__bt_is_factory_test_mode()) {
359 BT_ERR("Unable to start advertising in factory binary !!");
360 return BLUETOOTH_ERROR_NOT_SUPPORT;
363 if (_bt_adapter_get_status() != BT_ACTIVATED &&
364 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
365 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
368 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
370 BT_ERR("There is NO available slot!!");
371 return BLUETOOTH_ERROR_NO_RESOURCES;
374 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
375 return BLUETOOTH_ERROR_IN_PROGRESS;
377 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
378 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
380 if (le_adv_slot[slot_id].hold_timer_id > 0) {
381 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
382 le_adv_slot[slot_id].hold_timer_id = 0;
385 proxy = _bt_get_adapter_proxy();
386 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
388 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
389 g_variant_new("(bi)", enable, slot_id),
390 G_DBUS_CALL_FLAGS_NONE,
396 BT_ERR("SetAdvertising Fail: %s", error->message);
397 g_clear_error(&error);
398 return BLUETOOTH_ERROR_INTERNAL;
402 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
404 le_adv_slot[slot_id].is_advertising = enable;
405 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
408 g_variant_unref(ret);
410 return BLUETOOTH_ERROR_NONE;
413 int _bt_set_custom_advertising(const char *sender, int adv_handle,
414 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
418 GError *error = NULL;
423 BT_CHECK_PARAMETER(params, return);
425 if (__bt_is_factory_test_mode()) {
426 BT_ERR("Unable to start advertising in factory binary !!");
427 return BLUETOOTH_ERROR_NOT_SUPPORT;
430 if (_bt_adapter_get_status() != BT_ACTIVATED &&
431 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
432 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
435 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
437 BT_ERR("There is NO available slot!!");
438 return BLUETOOTH_ERROR_NO_RESOURCES;
441 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
442 return BLUETOOTH_ERROR_IN_PROGRESS;
444 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
445 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
447 if (le_adv_slot[slot_id].hold_timer_id > 0) {
448 g_source_remove(le_adv_slot[slot_id].hold_timer_id);
449 le_adv_slot[slot_id].hold_timer_id = 0;
452 proxy = _bt_get_adapter_proxy();
453 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
455 if (params->interval_min > params->interval_max ||
456 params->interval_min < BT_ADV_INTERVAL_MIN ||
457 params->interval_max > BT_ADV_INTERVAL_MAX)
458 return BLUETOOTH_ERROR_INVALID_PARAM;
460 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
461 return BLUETOOTH_ERROR_INVALID_PARAM;
463 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
464 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
465 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
466 return BLUETOOTH_ERROR_NOT_SUPPORT;
468 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
469 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
471 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
472 g_variant_new("(uuuui)", min, max,
473 params->filter_policy, params->type,
474 slot_id), G_DBUS_CALL_FLAGS_NONE,
478 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
479 g_clear_error(&error);
480 return BLUETOOTH_ERROR_INTERNAL;
483 adv_params.interval_min = params->interval_min;
484 adv_params.interval_max = params->interval_max;
485 adv_params.filter_policy = params->filter_policy;
486 adv_params.type = params->type;
489 g_variant_unref(ret);
491 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
492 g_variant_new("(bi)", enable, slot_id),
493 G_DBUS_CALL_FLAGS_NONE,
499 BT_ERR("SetAdvertising Fail: %s", error->message);
500 g_clear_error(&error);
501 return BLUETOOTH_ERROR_INTERNAL;
505 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
507 _bt_unregister_adv_slot_owner(slot_id);
509 le_adv_slot[slot_id].is_advertising = enable;
510 BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id);
512 g_variant_unref(ret);
514 return BLUETOOTH_ERROR_NONE;
517 static gboolean __bt_hold_current_advertising_timeout_cb(gpointer user_data)
520 GError *error = NULL;
523 BT_INFO("Restart advertising stopped by bt-service");
525 le_adv_slot[0].hold_timer_id = 0;
527 proxy = _bt_get_adapter_proxy();
528 retv_if(proxy == NULL, FALSE);
530 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
531 g_variant_new("(bi)", TRUE, 0),
532 G_DBUS_CALL_FLAGS_NONE,
538 BT_ERR("SetAdvertising Fail: %s", error->message);
539 g_clear_error(&error);
544 g_variant_unref(ret);
549 int _bt_hold_current_advertising(void)
552 GError *error = NULL;
555 if (le_adv_slot[0].sender && le_adv_slot[0].is_advertising == TRUE) {
556 BT_INFO("Stop current advertising by bt-service");
558 proxy = _bt_get_adapter_proxy();
559 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
561 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
562 g_variant_new("(bi)", FALSE, 0),
563 G_DBUS_CALL_FLAGS_NONE,
569 BT_ERR("SetAdvertising Fail: %s", error->message);
570 g_clear_error(&error);
571 return BLUETOOTH_ERROR_INTERNAL;
575 g_variant_unref(ret);
577 le_adv_slot[0].hold_timer_id = g_timeout_add(2000,
578 __bt_hold_current_advertising_timeout_cb, NULL);
580 BT_INFO("It's NOT advertising");
581 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
584 return BLUETOOTH_ERROR_NONE;
587 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
588 char in_type, char **data, int *data_len)
590 if (in_data == NULL || data == NULL || data_len == NULL)
591 return BLUETOOTH_ERROR_INTERNAL;
594 return BLUETOOTH_ERROR_INTERNAL;
600 for (i = 0; i < in_len; i++) {
602 if (len <= 0 || i + 1 >= in_len) {
603 BT_ERR("Invalid advertising data");
604 return BLUETOOTH_ERROR_INTERNAL;
607 type = in_data[i + 1];
608 if (type == in_type) {
618 if (i + len > in_len) {
619 BT_ERR("Invalid advertising data");
620 return BLUETOOTH_ERROR_INTERNAL;
621 } else if (len == 0) {
622 BT_DBG("AD Type 0x%02x data is not set", in_type);
625 return BLUETOOTH_ERROR_NONE;
628 *data = g_memdup(&in_data[i], len);
630 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
633 return BLUETOOTH_ERROR_NONE;
636 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
638 BT_CHECK_PARAMETER(adv, return);
639 BT_CHECK_PARAMETER(length, return);
641 memcpy(adv, &adv_data, sizeof(adv_data));
642 *length = adv_data_len;
644 return BLUETOOTH_ERROR_NONE;
647 int _bt_set_advertising_data(const char *sender, int adv_handle,
648 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
651 GError *error = NULL;
652 GVariant *ret, *ad_data, *param = NULL;
653 GVariant *temp = NULL;
654 GVariantBuilder *builder;
656 char *old_mdata = NULL;
657 char *new_mdata = NULL;
662 if (__bt_is_factory_test_mode()) {
663 BT_ERR("Unable to set advertising data in factory binary !!");
664 return BLUETOOTH_ERROR_NOT_SUPPORT;
667 BT_CHECK_PARAMETER(adv, return);
669 if (_bt_adapter_get_status() != BT_ACTIVATED &&
670 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
671 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
674 proxy = _bt_get_adapter_proxy();
675 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
677 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
679 BT_ERR("There is NO available slot!!");
680 return BLUETOOTH_ERROR_NO_RESOURCES;
683 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
684 for (i = 0; i < length; i++)
685 g_variant_builder_add(builder, "y", adv->data[i]);
687 temp = g_variant_new("ay", builder);
688 g_variant_builder_unref(builder);
689 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
690 g_variant_new("(@ayi)", temp, slot_id),
691 G_DBUS_CALL_FLAGS_NONE,
695 BT_ERR("SetAdvertisingData Fail: %s", error->message);
696 g_clear_error(&error);
697 return BLUETOOTH_ERROR_INTERNAL;
700 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
702 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
703 &old_mdata, &old_len);
704 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
705 &new_mdata, &new_len);
706 if (old_len != new_len ||
707 (old_mdata && new_mdata &&
708 memcmp(old_mdata, new_mdata, new_len))) {
709 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
710 new_mdata, new_len, TRUE, NULL, NULL);
711 param = g_variant_new("(@ay)", ad_data);
712 _bt_send_event(BT_ADAPTER_EVENT,
713 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
719 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
720 memcpy(&adv_data, adv, length);
721 adv_data_len = length;
723 BT_INFO("Set advertising data");
725 g_variant_unref(ret);
727 return BLUETOOTH_ERROR_NONE;
730 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
732 BT_CHECK_PARAMETER(response, return);
733 BT_CHECK_PARAMETER(length, return);
735 memcpy(response, &resp_data, sizeof(resp_data));
736 *length = resp_data_len;
738 return BLUETOOTH_ERROR_NONE;
741 int _bt_set_scan_response_data(const char *sender, int adv_handle,
742 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
745 GError *error = NULL;
746 GVariant *ret, *scan_data, *param = NULL;
747 GVariant *temp = NULL;
748 GVariantBuilder *builder;
750 char *old_mdata = NULL;
751 char *new_mdata = NULL;
756 if (__bt_is_factory_test_mode()) {
757 BT_ERR("Unable to set scan response list in factory binary !!");
758 return BLUETOOTH_ERROR_NOT_SUPPORT;
761 BT_CHECK_PARAMETER(response, return);
763 if (_bt_adapter_get_status() != BT_ACTIVATED &&
764 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
765 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
768 proxy = _bt_get_adapter_proxy();
769 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
771 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
773 BT_ERR("There is NO available slot!!");
774 return BLUETOOTH_ERROR_NO_RESOURCES;
776 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
777 for (i = 0; i < length; i++)
778 g_variant_builder_add(builder, "y", response->data[i]);
780 temp = g_variant_new("ay", builder);
781 g_variant_builder_unref(builder);
782 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
783 g_variant_new("(@ayi)", temp, slot_id),
784 G_DBUS_CALL_FLAGS_NONE,
788 BT_ERR("SetScanRespData Fail: %s", error->message);
789 g_clear_error(&error);
790 return BLUETOOTH_ERROR_INTERNAL;
793 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
795 /* Compare with previous scan resp data */
796 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
797 &old_mdata, &old_len);
798 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
799 &new_mdata, &new_len);
800 if (old_len != new_len ||
801 (old_mdata && new_mdata &&
802 memcmp(old_mdata, new_mdata, new_len))) {
803 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
804 new_mdata, new_len, TRUE, NULL, NULL);
805 param = g_variant_new("(@ay)", scan_data);
806 _bt_send_event(BT_ADAPTER_EVENT,
807 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
813 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
814 memcpy(&resp_data, response, length);
815 resp_data_len = length;
818 g_variant_unref(ret);
819 BT_INFO("Set scan response data");
820 return BLUETOOTH_ERROR_NONE;
823 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
826 GError *error = NULL;
831 BT_CHECK_PARAMETER(params, return);
833 if (_bt_adapter_get_status() != BT_ACTIVATED &&
834 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
835 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
838 proxy = _bt_get_adapter_proxy();
839 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
841 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
842 return BLUETOOTH_ERROR_INVALID_PARAM;
844 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
845 return BLUETOOTH_ERROR_INVALID_PARAM;
847 if (params->window > params->interval)
848 return BLUETOOTH_ERROR_INVALID_PARAM;
850 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
851 win = params->window / BT_ADV_INTERVAL_SPLIT;
853 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
854 g_variant_new("(uuu)", params->type, itv, win),
855 G_DBUS_CALL_FLAGS_NONE, -1,
859 BT_ERR("SetScanParameters Fail: %s", error->message);
860 g_clear_error(&error);
861 return BLUETOOTH_ERROR_INTERNAL;
864 _bt_set_le_scan_type(params->type);
866 is_le_set_scan_parameter = TRUE;
869 g_variant_unref(ret);
870 BT_INFO("Set scan parameters");
871 return BLUETOOTH_ERROR_NONE;
874 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
877 bt_adapter_le_scanner_t *scanner;
879 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
881 if (g_strcmp0(scanner->sender, sender) == 0)
888 int __bt_get_available_scan_filter_slot_id(void)
891 bt_adapter_le_scanner_t *scanner;
893 bluetooth_le_scan_filter_t *filter_data;
894 gboolean *slot_check_list = NULL;
897 if (le_feature_info.max_filter == 0) {
898 BT_ERR("Scan filter is NOT Supported");
901 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
903 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
905 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
906 filter_data = fl->data;
907 if (filter_data->slot_id < le_feature_info.max_filter)
908 slot_check_list[filter_data->slot_id] = TRUE;
912 for (i = 0; i < le_feature_info.max_filter; i++) {
913 if (slot_check_list[i] == FALSE) {
914 g_free(slot_check_list);
919 BT_ERR("There is NO available slot for scan filter.");
920 g_free(slot_check_list);
924 gboolean _bt_is_scan_filter_supported(void)
926 if (le_feature_info.max_filter > 0)
932 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
935 GError *error = NULL;
936 GVariant *ret, *param;
937 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
938 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
939 GArray *arr_uuid = NULL;
940 GArray *arr_uuid_mask = NULL;
941 GArray *arr_data = NULL;
942 GArray *arr_data_mask = NULL;
943 bt_adapter_le_scanner_t *scanner = NULL;
944 bluetooth_le_scan_filter_t *filter_data = NULL;
945 int feature_selection = 0;
947 *slot_id = __bt_get_available_scan_filter_slot_id();
949 return BLUETOOTH_ERROR_NO_RESOURCES;
951 proxy = _bt_get_adapter_proxy();
952 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
954 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
955 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
956 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
958 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
960 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
961 NULL, 0, TRUE, NULL, NULL);
962 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
963 NULL, 0, TRUE, NULL, NULL);
964 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
965 NULL, 0, TRUE, NULL, NULL);
966 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
967 NULL, 0, TRUE, NULL, NULL);
969 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
971 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
972 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
973 *slot_id, // filter_index
975 0, // company_id_mask
976 arr_uuid_param, // p_uuid
977 arr_uuid_mask_param, // p_uuid_mask
980 arr_data_param, // p_data
981 arr_data_mask_param); // p_mask
983 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
984 param, G_DBUS_CALL_FLAGS_NONE,
988 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
989 g_clear_error(&error);
992 g_variant_unref(ret);
995 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
996 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
998 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
999 NULL, 0, TRUE, NULL, NULL);
1000 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1001 NULL, 0, TRUE, NULL, NULL);
1002 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1003 NULL, 0, TRUE, NULL, NULL);
1004 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1005 NULL, 0, TRUE, NULL, NULL);
1007 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1009 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1010 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
1011 *slot_id, // filter_index
1013 0, // company_id_mask
1014 arr_uuid_param, // p_uuid
1015 arr_uuid_mask_param, // p_uuid_mask
1016 filter->device_name, // string
1018 arr_data_param, // p_data
1019 arr_data_mask_param);
1021 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1022 param, G_DBUS_CALL_FLAGS_NONE,
1026 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1027 g_clear_error(&error);
1030 g_variant_unref(ret);
1033 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1034 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
1036 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1037 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1039 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
1040 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
1042 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1043 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1044 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1045 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1046 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1047 NULL, 0, TRUE, NULL, NULL);
1048 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1049 NULL, 0, TRUE, NULL, NULL);
1051 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1053 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1054 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
1055 *slot_id, // filter_index
1057 0, // company_id_mask
1058 arr_uuid_param, // p_uuid
1059 arr_uuid_mask_param, // p_uuid_mask
1062 arr_data_param, // p_data
1063 arr_data_mask_param);
1065 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
1066 param, G_DBUS_CALL_FLAGS_NONE,
1070 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1071 g_clear_error(&error);
1074 g_variant_unref(ret);
1076 g_array_free(arr_uuid, TRUE);
1077 g_array_free(arr_uuid_mask, TRUE);
1080 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1081 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
1083 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
1084 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1086 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
1087 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
1089 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1090 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
1091 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1092 arr_uuid_mask->data, arr_uuid_mask->len, 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_SERVICE_SOLICITATION_UUID, // 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
1109 arr_data_param, // p_data
1110 arr_data_mask_param);
1112 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1113 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);
1123 g_array_free(arr_uuid, TRUE);
1124 g_array_free(arr_uuid_mask, TRUE);
1127 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1128 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1130 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1131 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1133 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1134 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1136 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1137 NULL, 0, TRUE, NULL, NULL);
1138 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1139 NULL, 0, TRUE, NULL, NULL);
1140 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1141 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1142 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1143 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1145 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1147 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1148 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1149 *slot_id, // filter_index
1151 0, // company_id_mask
1152 arr_uuid_param, // p_uuid
1153 arr_uuid_mask_param, // p_uuid_mask
1156 arr_data_param, // p_data
1157 arr_data_mask_param);
1159 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1160 G_DBUS_CALL_FLAGS_NONE,
1164 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1165 g_clear_error(&error);
1168 g_variant_unref(ret);
1170 g_array_free(arr_data, TRUE);
1171 g_array_free(arr_data_mask, TRUE);
1174 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1175 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1177 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1178 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1180 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1181 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1183 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1184 NULL, 0, TRUE, NULL, NULL);
1185 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1186 NULL, 0, TRUE, NULL, NULL);
1187 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1188 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1189 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1190 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1192 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1194 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1195 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1196 *slot_id, // filter_index
1197 filter->manufacturer_id, // company_id
1198 0xFFFF, // company_id_mask
1199 arr_uuid_param, // p_uuid
1200 arr_uuid_mask_param, // p_uuid_mask
1203 arr_data_param, // p_data
1204 arr_data_mask_param);
1206 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1207 G_DBUS_CALL_FLAGS_NONE,
1211 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1212 g_clear_error(&error);
1215 g_variant_unref(ret);
1217 g_array_free(arr_data, TRUE);
1218 g_array_free(arr_data_mask, TRUE);
1221 BT_DBG("Filter selection %.2x", feature_selection);
1223 param = g_variant_new("(iiiiiiiiiiii)",
1225 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1226 *slot_id, // filter_index
1227 feature_selection, // feat_seln
1228 0, // list_logic_type (OR - 0x00, AND - 0x01)
1229 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1230 -127, // rssi_high_thres
1231 -127, // rssi_low_thres
1232 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1235 0); // found_timeout_cnt
1236 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1237 param, G_DBUS_CALL_FLAGS_NONE,
1241 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1242 g_clear_error(&error);
1245 scanner = __bt_find_scanner_from_list(sender);
1246 if (scanner == NULL) {
1247 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1248 scanner->sender = g_strdup(sender);
1249 scanner_list = g_slist_append(scanner_list, scanner);
1254 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1255 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1256 filter_data->slot_id = *slot_id;
1258 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1262 g_variant_unref(ret);
1263 return BLUETOOTH_ERROR_NONE;
1266 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1269 GError *error = NULL;
1271 bt_adapter_le_scanner_t *scanner = NULL;
1272 bluetooth_le_scan_filter_t *filter_data = NULL;
1274 gboolean is_slot_id_found = FALSE;
1276 scanner = __bt_find_scanner_from_list(sender);
1277 if (scanner == NULL) {
1278 BT_ERR("There is NO available scanner.");
1279 return BLUETOOTH_ERROR_NOT_FOUND;
1282 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1283 filter_data = l->data;
1284 if (filter_data->slot_id == slot_id) {
1285 is_slot_id_found = TRUE;
1289 if (is_slot_id_found == FALSE) {
1290 BT_ERR("There is NO registered slot.");
1291 return BLUETOOTH_ERROR_NOT_FOUND;
1294 proxy = _bt_get_adapter_proxy();
1295 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1297 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1298 g_variant_new("(ii)", 0, slot_id),
1299 G_DBUS_CALL_FLAGS_NONE,
1303 BT_ERR("scan_filter_clear Fail: %s", error->message);
1304 g_clear_error(&error);
1307 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1308 g_free(filter_data);
1311 g_variant_unref(ret);
1312 return BLUETOOTH_ERROR_NONE;
1315 int _bt_unregister_all_scan_filters(const char *sender)
1318 GError *error = NULL;
1320 bt_adapter_le_scanner_t *scanner = NULL;
1321 bluetooth_le_scan_filter_t *filter_data = NULL;
1324 scanner = __bt_find_scanner_from_list(sender);
1325 if (scanner == NULL) {
1326 BT_ERR("There is NO available scanner.");
1327 return BLUETOOTH_ERROR_NOT_FOUND;
1330 proxy = _bt_get_adapter_proxy();
1331 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1333 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1334 filter_data = l->data;
1336 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1337 g_variant_new("(ii)", 0, filter_data->slot_id),
1338 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1341 BT_ERR("scan_filter_clear Fail: %s", error->message);
1342 g_clear_error(&error);
1345 g_variant_unref(ret);
1348 g_slist_free_full(scanner->filter_list, g_free);
1349 scanner->filter_list = NULL;
1351 return BLUETOOTH_ERROR_NONE;
1354 int _bt_start_le_scan(const char *sender)
1357 GError *error = NULL;
1359 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1361 if (scanner == NULL) {
1362 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1363 scanner->sender = g_strdup(sender);
1364 scanner_list = g_slist_append(scanner_list, scanner);
1367 if (scanner->is_scanning == TRUE) {
1368 BT_ERR("BT is already in LE scanning");
1369 return BLUETOOTH_ERROR_IN_PROGRESS;
1371 scanner->is_scanning = TRUE;
1373 proxy = _bt_get_adapter_proxy();
1374 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1376 if (_bt_is_le_scanning()) {
1377 if (scan_filter_enabled == TRUE) {
1378 if (scanner->filter_list == NULL) {
1379 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1380 g_variant_new("(ib)", 0, FALSE),
1381 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1384 BT_ERR("scan_filter_clear Fail: %s", error->message);
1385 g_clear_error(&error);
1389 g_variant_unref(ret);
1390 BT_INFO("Disable LE Scan Filter");
1391 scan_filter_enabled = FALSE;
1393 BT_INFO("LE Filter Scan is continue");
1396 BT_INFO("LE Full Scan is already on progress");
1398 return BLUETOOTH_ERROR_NONE;
1400 if (is_le_set_scan_parameter == FALSE) {
1401 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1402 bluetooth_le_scan_params_t scan_params;
1403 scan_params.type = BT_LE_ACTIVE_SCAN;
1404 scan_params.interval = 5000;
1405 scan_params.window = 500;
1406 _bt_set_scan_parameters(&scan_params);
1409 if (scanner->filter_list == NULL) {
1410 BT_INFO("Start LE Full Scan");
1411 scan_filter_enabled = FALSE;
1413 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1414 g_variant_new("(ib)", 0, TRUE),
1415 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1418 BT_ERR("scan_filter_clear Fail: %s", error->message);
1419 g_clear_error(&error);
1423 g_variant_unref(ret);
1424 BT_INFO("Enable LE Scan Filter");
1425 scan_filter_enabled = TRUE;
1429 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1430 NULL, G_DBUS_CALL_FLAGS_NONE,
1434 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1435 g_clear_error(&error);
1436 return BLUETOOTH_ERROR_INTERNAL;
1440 g_variant_unref(ret);
1441 return BLUETOOTH_ERROR_NONE;
1444 int _bt_stop_le_scan(const char *sender)
1447 GError *error = NULL;
1449 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1451 gboolean next_scanning = FALSE;
1452 gboolean need_scan_filter = TRUE;
1454 if (scanner == NULL || scanner->is_scanning == FALSE)
1455 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1457 scanner->is_scanning = FALSE;
1459 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1461 if (scanner->is_scanning == TRUE) {
1462 next_scanning = TRUE;
1463 if (scanner->filter_list == NULL)
1464 need_scan_filter = FALSE;
1468 proxy = _bt_get_adapter_proxy();
1469 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1471 if (next_scanning == TRUE) {
1472 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1473 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1474 g_variant_new("(ib)", 0, TRUE),
1475 G_DBUS_CALL_FLAGS_NONE,
1479 BT_ERR("scan_filter_clear Fail: %s", error->message);
1480 g_clear_error(&error);
1484 g_variant_unref(ret);
1485 BT_INFO("Enable LE Scan Filter");
1486 scan_filter_enabled = TRUE;
1488 return BLUETOOTH_ERROR_NONE;
1490 if (scan_filter_enabled == TRUE) {
1491 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1492 g_variant_new("(ib)", 0, FALSE),
1493 G_DBUS_CALL_FLAGS_NONE,
1497 BT_ERR("scan_filter_clear Fail: %s", error->message);
1498 g_clear_error(&error);
1502 g_variant_unref(ret);
1503 BT_INFO("Disable LE Scan Filter");
1505 BT_INFO("Just stop LE scan");
1509 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1510 NULL, G_DBUS_CALL_FLAGS_NONE,
1513 BT_ERR("LE Scan stop failed");
1514 return BLUETOOTH_ERROR_INTERNAL;
1517 scan_filter_enabled = FALSE;
1518 is_le_set_scan_parameter = FALSE;
1520 g_variant_unref(ret);
1521 return BLUETOOTH_ERROR_NONE;
1524 void _bt_disable_all_scanner_status(void)
1527 bt_adapter_le_scanner_t *scanner;
1529 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1531 scanner->is_scanning = FALSE;
1535 void _bt_set_le_scan_status(gboolean mode)
1537 is_le_scanning = mode;
1540 gboolean _bt_is_le_scanning(void)
1542 return is_le_scanning;
1545 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1547 le_scan_type = type;
1550 bt_le_scan_type_t _bt_get_le_scan_type(void)
1552 return le_scan_type;
1555 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1556 int adv_data_len, const char *svc_uuid, int uuid_len,
1557 const char *uuid_mask, char ad_type)
1563 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1564 ad_type, &data, &data_len);
1566 for (i = 0; i < data_len; i += uuid_len) {
1567 if (uuid_len > (data_len - i))
1570 if (_bt_byte_arr_cmp_with_mask(data + i,
1571 svc_uuid, uuid_mask, uuid_len) == 0) {
1582 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1583 const char *adv_data, int adv_data_len,
1584 const char *scan_data, int scan_data_len,
1585 const bt_adapter_le_scanner_t *scanner)
1588 bluetooth_le_scan_filter_t *filter_data = NULL;
1591 gboolean is_matched = FALSE;
1593 if (scanner->filter_list == NULL) {
1594 BT_INFO("This scanner is on Full Scan.");
1598 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1599 filter_data = l->data;
1601 if (filter_data->added_features &
1602 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1603 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1605 _bt_convert_addr_type_to_string(address,
1606 filter_data->device_address.addr);
1607 if (strncmp(address, device_address,
1608 BT_ADDRESS_STRING_SIZE) != 0)
1612 if (filter_data->added_features &
1613 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1616 if (__bt_check_scan_result_uuid(adv_data,
1618 (char*)filter_data->service_uuid.data.data,
1619 filter_data->service_uuid.data_len,
1620 (char*)filter_data->service_uuid_mask.data.data,
1621 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1624 if (__bt_check_scan_result_uuid(adv_data,
1626 (char*)filter_data->service_uuid.data.data,
1627 filter_data->service_uuid.data_len,
1628 (char*)filter_data->service_uuid_mask.data.data,
1629 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1632 if (__bt_check_scan_result_uuid(adv_data,
1634 (char*)filter_data->service_uuid.data.data,
1635 filter_data->service_uuid.data_len,
1636 (char*)filter_data->service_uuid_mask.data.data,
1637 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1640 if (__bt_check_scan_result_uuid(adv_data,
1642 (char*)filter_data->service_uuid.data.data,
1643 filter_data->service_uuid.data_len,
1644 (char*)filter_data->service_uuid_mask.data.data,
1645 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1648 if (__bt_check_scan_result_uuid(scan_data,
1650 (char*)filter_data->service_uuid.data.data,
1651 filter_data->service_uuid.data_len,
1652 (char*)filter_data->service_uuid_mask.data.data,
1653 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1656 if (__bt_check_scan_result_uuid(scan_data,
1658 (char*)filter_data->service_uuid.data.data,
1659 filter_data->service_uuid.data_len,
1660 (char*)filter_data->service_uuid_mask.data.data,
1661 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1664 if (__bt_check_scan_result_uuid(scan_data,
1666 (char*)filter_data->service_uuid.data.data,
1667 filter_data->service_uuid.data_len,
1668 (char*)filter_data->service_uuid_mask.data.data,
1669 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1672 if (__bt_check_scan_result_uuid(scan_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_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1681 if (is_matched == FALSE)
1684 if (filter_data->added_features &
1685 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1688 if (__bt_check_scan_result_uuid(adv_data,
1690 (char*)filter_data->service_solicitation_uuid.data.data,
1691 filter_data->service_solicitation_uuid.data_len,
1692 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1693 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1696 if (__bt_check_scan_result_uuid(adv_data,
1698 (char*)filter_data->service_solicitation_uuid.data.data,
1699 filter_data->service_solicitation_uuid.data_len,
1700 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1701 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1704 if (__bt_check_scan_result_uuid(scan_data,
1706 (char*)filter_data->service_solicitation_uuid.data.data,
1707 filter_data->service_solicitation_uuid.data_len,
1708 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1709 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1712 if (__bt_check_scan_result_uuid(scan_data,
1714 (char*)filter_data->service_solicitation_uuid.data.data,
1715 filter_data->service_solicitation_uuid.data_len,
1716 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1717 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1721 if (is_matched == FALSE)
1724 if (filter_data->added_features &
1725 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1726 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1731 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1732 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1735 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1736 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1737 memcpy(name, data, data_len);
1738 name[data_len] = '\0';
1741 if (strncmp(filter_data->device_name,
1742 name, data_len) == 0)
1745 __bt_get_ad_data_by_type((char*)scan_data,
1747 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1750 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1751 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1752 memcpy(name, data, data_len);
1753 name[data_len] = '\0';
1756 if (strncmp(filter_data->device_name,
1757 name, data_len) == 0)
1761 if (is_matched == FALSE)
1764 if (filter_data->added_features &
1765 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1770 __bt_get_ad_data_by_type((char*)adv_data,
1772 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1776 int manufacturer_id;
1777 manufacturer_id = (data[1] << 8) + data[0];
1779 if (filter_data->manufacturer_id == manufacturer_id) {
1780 if (filter_data->manufacturer_data.data_len == 0) {
1783 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1784 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1785 if (_bt_byte_arr_cmp_with_mask(data + 2,
1786 (char*)filter_data->manufacturer_data.data.data,
1787 (char*)filter_data->manufacturer_data_mask.data.data,
1788 data_len - 2) == 0) {
1796 __bt_get_ad_data_by_type((char*)scan_data,
1798 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1802 int manufacturer_id;
1803 manufacturer_id = (data[1] << 8) + data[0];
1805 if (filter_data->manufacturer_id == manufacturer_id) {
1806 if (filter_data->manufacturer_data.data_len == 0) {
1809 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1810 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1811 if (_bt_byte_arr_cmp_with_mask(data + 2,
1812 (char*)filter_data->manufacturer_data.data.data,
1813 (char*)filter_data->manufacturer_data_mask.data.data,
1814 data_len - 2) == 0) {
1823 if (is_matched == FALSE)
1826 if (filter_data->added_features &
1827 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1832 __bt_get_ad_data_by_type((char*)adv_data,
1834 BT_LE_AD_TYPE_SERVICE_DATA,
1837 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1838 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1839 if (_bt_byte_arr_cmp_with_mask(data,
1840 (char*)filter_data->service_data.data.data,
1841 (char*)filter_data->service_data_mask.data.data,
1848 __bt_get_ad_data_by_type((char*)scan_data,
1850 BT_LE_AD_TYPE_SERVICE_DATA,
1853 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1854 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1855 if (_bt_byte_arr_cmp_with_mask(data,
1856 (char*)filter_data->service_data.data.data,
1857 (char*)filter_data->service_data_mask.data.data,
1865 if (is_matched == FALSE)
1869 BT_INFO("The scan result is conformable.");
1873 BT_INFO("The scan result is NOT conformable.");
1877 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1878 const bt_le_adv_info_t *adv_info)
1880 int result = BLUETOOTH_ERROR_NONE;
1882 GVariant *scan_data_param, *adv_data_param;
1884 bt_adapter_le_scanner_t *scanner = NULL;
1885 const char *adv_data = NULL;
1886 int adv_data_len = 0;
1887 const char *scan_data = NULL;
1888 int scan_data_len = 0;
1890 ret_if(le_dev_info == NULL);
1891 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1892 ret_if(adv_info == NULL);
1894 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1895 adv_data = le_dev_info->adv_data;
1896 adv_data_len = le_dev_info->adv_data_len;
1897 scan_data = le_dev_info->adv_data;
1900 adv_data = adv_info->data;
1901 adv_data_len = adv_info->data_len;
1902 scan_data = le_dev_info->adv_data;
1903 scan_data_len = le_dev_info->adv_data_len;
1906 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1908 if (scanner->is_scanning == FALSE)
1911 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1912 adv_data, adv_data_len, scan_data, scan_data_len,
1916 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1917 adv_data, adv_data_len, TRUE, NULL, NULL);
1918 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1919 scan_data, scan_data_len, TRUE, NULL, NULL);
1921 param = g_variant_new("(isnnn@ayn@ay)",
1923 le_dev_info->address,
1924 le_dev_info->addr_type,
1932 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1933 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1935 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1940 void _bt_send_ibeacon_scan_result_event(const bt_remote_ibeacon_dev_info_t *ibeacon_dev_info)
1942 int result = BLUETOOTH_ERROR_NONE;
1945 bt_adapter_le_scanner_t *scanner = NULL;
1947 ret_if(ibeacon_dev_info == NULL);
1948 BT_DBG("_bt_send_ibeacon_scan_result_event");
1950 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1952 if (scanner->is_scanning == FALSE)
1955 param = g_variant_new("(isnnnsnnn)",
1957 ibeacon_dev_info->address,
1958 ibeacon_dev_info->addr_type,
1959 ibeacon_dev_info->company_id,
1960 ibeacon_dev_info->ibeacon_type,
1961 ibeacon_dev_info->uuid,
1962 ibeacon_dev_info->major_id,
1963 ibeacon_dev_info->minor_id,
1964 ibeacon_dev_info->measured_power);
1966 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_IBEACON_DEVICE_FOUND, param);
1970 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1973 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1974 GError *error = NULL;
1977 if (__bt_is_factory_test_mode()) {
1978 BT_ERR("Unable to add white list in factory binary !!");
1979 return BLUETOOTH_ERROR_NOT_SUPPORT;
1982 BT_CHECK_PARAMETER(device_address, return);
1984 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1985 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1986 return BLUETOOTH_ERROR_INVALID_PARAM;
1988 _bt_convert_addr_type_to_string(address, device_address->addr);
1990 proxy = _bt_get_adapter_proxy();
1991 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1993 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1994 g_variant_new("(su)", address, address_type),
1995 G_DBUS_CALL_FLAGS_NONE, -1,
1999 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
2000 g_clear_error(&error);
2001 return BLUETOOTH_ERROR_INTERNAL;
2005 g_variant_unref(ret);
2006 BT_INFO("Add white list");
2008 return BLUETOOTH_ERROR_NONE;
2011 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
2014 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2015 GError *error = NULL;
2018 if (__bt_is_factory_test_mode()) {
2019 BT_ERR("Unable to remove white list in factory binary !!");
2020 return BLUETOOTH_ERROR_NOT_SUPPORT;
2023 BT_CHECK_PARAMETER(device_address, return);
2025 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
2026 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
2027 return BLUETOOTH_ERROR_INVALID_PARAM;
2029 _bt_convert_addr_type_to_string(address, device_address->addr);
2031 proxy = _bt_get_adapter_proxy();
2032 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2034 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
2035 g_variant_new("(su)", address, address_type),
2036 G_DBUS_CALL_FLAGS_NONE, -1,
2040 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
2041 g_clear_error(&error);
2042 return BLUETOOTH_ERROR_INTERNAL;
2046 g_variant_unref(ret);
2047 BT_INFO("Remove white list");
2049 return BLUETOOTH_ERROR_NONE;
2052 int _bt_clear_white_list(void)
2055 GError *error = NULL;
2058 if (__bt_is_factory_test_mode()) {
2059 BT_ERR("Unable to clear white list in factory binary !!");
2060 return BLUETOOTH_ERROR_NOT_SUPPORT;
2063 proxy = _bt_get_adapter_proxy();
2064 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2066 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
2067 NULL, G_DBUS_CALL_FLAGS_NONE,
2071 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
2072 g_clear_error(&error);
2073 return BLUETOOTH_ERROR_INTERNAL;
2076 g_variant_unref(ret);
2078 BT_INFO("Clear white list");
2080 return BLUETOOTH_ERROR_NONE;
2083 int _bt_initialize_ipsp(void)
2087 GError *error = NULL;
2090 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2091 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2092 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2095 proxy = _bt_get_adapter_proxy();
2096 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2098 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
2099 NULL, G_DBUS_CALL_FLAGS_NONE,
2102 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
2103 g_clear_error(&error);
2104 return BLUETOOTH_ERROR_INTERNAL;
2107 g_variant_unref(ret);
2109 BT_INFO("IPSP initialization called successfully");
2111 return BLUETOOTH_ERROR_NONE;
2114 int _bt_deinitialize_ipsp(void)
2118 GError *error = NULL;
2121 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2122 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2123 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2126 proxy = _bt_get_adapter_proxy();
2127 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2129 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
2130 NULL, G_DBUS_CALL_FLAGS_NONE,
2133 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
2134 g_clear_error(&error);
2135 return BLUETOOTH_ERROR_INTERNAL;
2138 g_variant_unref(ret);
2140 BT_INFO("IPSP De-initialization called successfully");
2142 return BLUETOOTH_ERROR_NONE;
2145 int _bt_le_read_maximum_data_length(
2146 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2148 GError *error = NULL;
2150 GVariant *reply = NULL;
2151 guint16 max_tx_octets, max_tx_time;
2152 guint16 max_rx_octets, max_rx_time;
2154 proxy = _bt_get_adapter_proxy();
2155 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2157 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2158 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2160 g_object_unref(proxy);
2162 if (reply == NULL) {
2163 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2164 if (error != NULL) {
2165 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2166 error->code, error->message);
2167 g_clear_error(&error);
2169 return BLUETOOTH_ERROR_INTERNAL;
2172 g_variant_get(reply, "(qqqq)", &max_tx_octets, &max_tx_time,
2173 &max_rx_octets, &max_rx_time);
2175 max_le_datalength->max_tx_octets = max_tx_octets;
2176 max_le_datalength->max_tx_time = max_tx_time;
2177 max_le_datalength->max_rx_octets = max_rx_octets;
2178 max_le_datalength->max_rx_time = max_rx_time;
2180 g_variant_unref(reply);
2182 return BLUETOOTH_ERROR_NONE;
2184 int _bt_le_write_host_suggested_default_data_length(
2185 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2187 GError *error = NULL;
2189 GVariant *reply = NULL;
2191 proxy = _bt_get_adapter_proxy();
2192 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2194 reply = g_dbus_proxy_call_sync(proxy,
2195 "LEWriteHostSuggestedDataLength",
2196 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2197 G_DBUS_CALL_FLAGS_NONE,
2202 g_object_unref(proxy);
2204 if (reply == NULL) {
2205 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2206 if (error != NULL) {
2207 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2208 error->code, error->message);
2209 g_clear_error(&error);
2211 return BLUETOOTH_ERROR_INTERNAL;
2214 g_variant_unref(reply);
2216 return BLUETOOTH_ERROR_NONE;
2219 int _bt_le_read_host_suggested_default_data_length(
2220 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2222 GError *error = NULL;
2224 GVariant *reply = NULL;
2225 guint16 def_tx_octets, def_tx_time;
2227 proxy = _bt_get_adapter_proxy();
2228 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2230 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2231 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2233 if (reply == NULL) {
2234 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2235 if (error != NULL) {
2236 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2237 error->code, error->message);
2238 g_clear_error(&error);
2240 return BLUETOOTH_ERROR_INTERNAL;
2243 g_variant_get(reply, "(qq)", &def_tx_octets, &def_tx_time);
2245 def_data_length->def_tx_octets = def_tx_octets;
2246 def_data_length->def_tx_time = def_tx_time;
2248 g_variant_unref(reply);
2250 return BLUETOOTH_ERROR_NONE;
2253 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2254 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2256 GError *error = NULL;
2257 guint16 txOctets = max_tx_Octets;
2258 guint16 txTime = max_tx_Time;
2259 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2260 gchar *device_path = NULL;
2261 GDBusConnection *conn;
2262 GDBusProxy *device_proxy;
2264 _bt_convert_addr_type_to_string(address, device_address->addr);
2266 device_path = _bt_get_device_object_path(address);
2268 if (device_path == NULL) {
2269 BT_DBG("Device path is null");
2270 return BLUETOOTH_ERROR_INTERNAL;
2273 conn = _bt_gdbus_get_system_gconn();
2275 BT_ERR("conn == NULL");
2276 g_free(device_path);
2277 return BLUETOOTH_ERROR_INTERNAL;
2280 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2281 NULL, BT_BLUEZ_NAME,
2282 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2284 g_free(device_path);
2285 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2287 g_dbus_proxy_call_sync(device_proxy,
2289 g_variant_new("(qq)", txOctets, txTime),
2290 G_DBUS_CALL_FLAGS_NONE,
2295 g_object_unref(device_proxy);
2298 BT_ERR("LESetDataLength error: [%s]", error->message);
2299 g_error_free(error);
2300 return BLUETOOTH_ERROR_INTERNAL;
2303 return BLUETOOTH_ERROR_NONE;