4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
25 #include <dbus/dbus.h>
31 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
32 #include <syspopup_caller.h>
36 #include "bt-internal-types.h"
37 #include "bt-service-common.h"
38 #include "bt-service-event.h"
39 #include "bt-service-adapter.h"
40 #include "bt-service-adapter-le.h"
43 #define BT_ADV_INTERVAL_MIN 20 /* msec */
44 #define BT_ADV_INTERVAL_MAX 10240
45 #define BT_ADV_INTERVAL_SPLIT 0.625
46 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
47 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
48 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
49 #define BT_ADV_TYPE_DEFAULT 0x00
50 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
56 } bt_adapter_le_feature_info_t;
61 gboolean is_advertising;
62 } bt_adapter_le_adv_slot_t;
68 } bt_adapter_le_scanner_t;
70 static bluetooth_advertising_params_t adv_params = {
71 BT_DEFAULT_ADV_MIN_INTERVAL,
72 BT_DEFAULT_ADV_MAX_INTERVAL,
73 BT_ADV_FILTER_POLICY_DEFAULT,
75 static bluetooth_advertising_data_t adv_data = { {0} };
76 static int adv_data_len;
77 static bluetooth_scan_resp_data_t resp_data = { {0} };
78 static int resp_data_len;
80 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
81 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
83 GSList *scanner_list = NULL;
84 static gboolean is_le_set_scan_parameter = FALSE;
85 static gboolean is_le_scanning = FALSE;
86 static gboolean scan_filter_enabled = FALSE;
87 static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN;
89 static GSList *gatt_client_senders = NULL;
92 gboolean _bt_is_set_scan_parameter(void)
94 return is_le_set_scan_parameter;
97 void _bt_init_gatt_client_senders(void)
99 _bt_clear_request_list();
102 int _bt_insert_gatt_client_sender(char *sender)
106 retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
108 info = g_strdup(sender);
109 retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
111 gatt_client_senders = g_slist_append(gatt_client_senders, info);
113 BT_DBG("insert sender: %s", sender);
115 return BLUETOOTH_ERROR_NONE;
118 int _bt_delete_gatt_client_sender(char *sender)
123 BT_DBG("remove sender: %s", sender);
125 for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) {
130 if (g_strcmp0(info, sender) == 0) {
131 BT_DBG("remove info");
132 gatt_client_senders = g_slist_remove(gatt_client_senders, info);
134 return BLUETOOTH_ERROR_NONE;
138 return BLUETOOTH_ERROR_NOT_FOUND;
141 void _bt_clear_gatt_client_senders(void)
143 if (gatt_client_senders) {
144 g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL);
145 g_slist_free(gatt_client_senders);
146 gatt_client_senders = NULL;
150 static void __bt_send_foreach_event(gpointer data, gpointer user_data)
153 GVariant *param = user_data;
155 _bt_send_event_to_dest(sender, BT_DEVICE_EVENT,BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
159 void _bt_send_char_value_changed_event(void *param)
161 g_slist_foreach(gatt_client_senders, __bt_send_foreach_event,
165 void __bt_free_le_adv_slot(void)
169 if (le_adv_slot == NULL)
172 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
173 if (le_adv_slot[i].sender)
174 g_free(le_adv_slot[i].sender);
180 int _bt_service_adapter_le_init(void)
182 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
184 return BLUETOOTH_ERROR_NONE;
187 void _bt_service_adapter_le_deinit(void)
189 __bt_free_le_adv_slot();
192 gboolean _bt_update_le_feature_support(const char *item, const char *value)
194 if (item== NULL || value == NULL)
197 if (g_strcmp0(item, "adv_inst_max") == 0) {
198 if (atoi(value) != le_feature_info.adv_inst_max) {
199 __bt_free_le_adv_slot();
200 le_feature_info.adv_inst_max = atoi(value);
201 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
203 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
204 le_feature_info.rpa_offloading = atoi(value);
205 } else if (g_strcmp0(item, "max_filter") == 0) {
206 le_feature_info.max_filter = atoi(value);
208 BT_DBG("No registered item");
215 static gboolean __bt_is_factory_test_mode(void)
218 #ifdef ENABLE_TIZEN_2_4
219 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
220 BT_ERR("Get the DUT Mode fail");
225 BT_INFO("DUT Test Mode !!");
232 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
236 if (le_adv_slot == NULL)
239 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
240 if (le_adv_slot[i].sender == NULL)
242 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
246 if (le_feature_info.adv_inst_max <= 2)
248 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
253 for (; i < le_feature_info.adv_inst_max; i++) {
254 if (le_adv_slot[i].sender == NULL)
261 void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
263 if (le_adv_slot[slot_id].sender == NULL) {
264 le_adv_slot[slot_id].sender = strdup(sender);
265 le_adv_slot[slot_id].adv_handle = adv_handle;
269 void __bt_unregister_adv_slot_owner(int slot_id)
271 g_free(le_adv_slot[slot_id].sender);
272 le_adv_slot[slot_id].sender = NULL;
273 le_adv_slot[slot_id].adv_handle = 0;
276 const char* _bt_get_adv_slot_owner(int slot_id)
278 if (le_adv_slot == NULL)
281 return le_adv_slot[slot_id].sender;
284 int _bt_get_adv_slot_adv_handle(int slot_id)
286 if (le_adv_slot == NULL)
289 return le_adv_slot[slot_id].adv_handle;
292 void _bt_set_advertising_status(int slot_id, gboolean mode)
294 le_adv_slot[slot_id].is_advertising = mode;
297 gboolean _bt_is_advertising(void)
299 gboolean status = FALSE;
302 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
303 if (le_adv_slot[i].is_advertising == TRUE)
310 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
314 if (le_adv_slot == NULL)
317 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
318 if (le_adv_slot[i].sender != NULL) {
319 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
320 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
321 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
327 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
332 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
337 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
340 GError *error = NULL;
344 if (__bt_is_factory_test_mode()) {
345 BT_ERR("Unable to start advertising in factory binary !!");
346 return BLUETOOTH_ERROR_NOT_SUPPORT;
349 if (_bt_adapter_get_status() != BT_ACTIVATED &&
350 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
351 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
354 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
356 BT_ERR("There is NO available slot!!");
357 return BLUETOOTH_ERROR_NO_RESOURCES;
360 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
361 return BLUETOOTH_ERROR_IN_PROGRESS;
363 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
364 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
366 proxy = _bt_get_adapter_proxy();
367 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
369 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
370 g_variant_new("(bi)", enable, slot_id),
371 G_DBUS_CALL_FLAGS_NONE,
377 BT_ERR("SetAdvertising Fail: %s", error->message);
378 g_clear_error(&error);
379 return BLUETOOTH_ERROR_INTERNAL;
383 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
385 le_adv_slot[slot_id].is_advertising = enable;
386 BT_INFO("Set advertising [%d]", enable);
389 g_variant_unref(ret);
391 return BLUETOOTH_ERROR_NONE;
394 int _bt_set_custom_advertising(const char *sender, int adv_handle,
395 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
399 GError *error = NULL;
404 BT_CHECK_PARAMETER(params, return);
406 if (__bt_is_factory_test_mode()) {
407 BT_ERR("Unable to start advertising in factory binary !!");
408 return BLUETOOTH_ERROR_NOT_SUPPORT;
411 if (_bt_adapter_get_status() != BT_ACTIVATED &&
412 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
413 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
416 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
418 BT_ERR("There is NO available slot!!");
419 return BLUETOOTH_ERROR_NO_RESOURCES;
422 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
423 return BLUETOOTH_ERROR_IN_PROGRESS;
425 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
426 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
428 proxy = _bt_get_adapter_proxy();
429 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
431 if (params->interval_min > params->interval_max ||
432 params->interval_min < BT_ADV_INTERVAL_MIN ||
433 params->interval_max > BT_ADV_INTERVAL_MAX)
434 return BLUETOOTH_ERROR_INVALID_PARAM;
436 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
437 return BLUETOOTH_ERROR_INVALID_PARAM;
439 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
440 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
441 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
442 return BLUETOOTH_ERROR_NOT_SUPPORT;
444 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
445 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
447 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
448 g_variant_new("(uuuui)", min, max,
449 params->filter_policy, params->type,
450 slot_id), G_DBUS_CALL_FLAGS_NONE,
454 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
455 g_clear_error(&error);
456 return BLUETOOTH_ERROR_INTERNAL;
459 adv_params.interval_min = params->interval_min;
460 adv_params.interval_max = params->interval_max;
461 adv_params.filter_policy = params->filter_policy;
462 adv_params.type= params->type;
465 g_variant_unref(ret);
467 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
468 g_variant_new("(bi)", enable, slot_id),
469 G_DBUS_CALL_FLAGS_NONE,
475 BT_ERR("SetAdvertising Fail: %s", error->message);
476 g_clear_error(&error);
477 return BLUETOOTH_ERROR_INTERNAL;
481 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
483 __bt_unregister_adv_slot_owner(slot_id);
485 le_adv_slot[slot_id].is_advertising = enable;
486 BT_INFO_C("Set advertising [%d]", enable);
488 g_variant_unref(ret);
490 return BLUETOOTH_ERROR_NONE;
493 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
494 char in_type, char **data, int *data_len)
496 if (in_data == NULL || data == NULL || data_len == NULL)
497 return BLUETOOTH_ERROR_INTERNAL;
500 return BLUETOOTH_ERROR_INTERNAL;
506 for (i = 0; i < in_len; i++) {
508 if (len <= 0 || i + 1 >= in_len) {
509 BT_ERR("Invalid advertising data");
510 return BLUETOOTH_ERROR_INTERNAL;
513 type = in_data[i + 1];
514 if (type == in_type) {
524 if (i + len > in_len) {
525 BT_ERR("Invalid advertising data");
526 return BLUETOOTH_ERROR_INTERNAL;
527 } else if (len == 0) {
528 BT_DBG("AD Type 0x%02x data is not set", in_type);
531 return BLUETOOTH_ERROR_NONE;
534 *data = g_memdup(&in_data[i], len);
536 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
539 return BLUETOOTH_ERROR_NONE;
542 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
544 BT_CHECK_PARAMETER(adv, return);
545 BT_CHECK_PARAMETER(length, return);
547 memcpy(adv, &adv_data, sizeof(adv_data));
548 *length = adv_data_len;
550 return BLUETOOTH_ERROR_NONE;
553 int _bt_set_advertising_data(const char *sender, int adv_handle,
554 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
557 GError *error = NULL;
558 GVariant *ret, *ad_data, *param = NULL;
559 GVariant *temp = NULL;
560 GVariantBuilder *builder;
562 char *old_mdata = NULL;
563 char *new_mdata = NULL;
568 if (__bt_is_factory_test_mode()) {
569 BT_ERR("Unable to set advertising data in factory binary !!");
570 return BLUETOOTH_ERROR_NOT_SUPPORT;
573 BT_CHECK_PARAMETER(adv, return);
575 if (_bt_adapter_get_status() != BT_ACTIVATED &&
576 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
577 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
580 proxy = _bt_get_adapter_proxy();
581 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
583 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
585 BT_ERR("There is NO available slot!!");
586 return BLUETOOTH_ERROR_NO_RESOURCES;
589 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
590 for (i = 0; i < length; i++) {
591 g_variant_builder_add(builder, "y", adv->data[i]);
594 temp = g_variant_new("ay", builder);
595 g_variant_builder_unref(builder);
596 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
597 g_variant_new("(@ayi)", temp, slot_id),
598 G_DBUS_CALL_FLAGS_NONE,
602 BT_ERR("SetAdvertisingData Fail: %s", error->message);
603 g_clear_error(&error);
604 return BLUETOOTH_ERROR_INTERNAL;
607 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
609 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
610 &old_mdata, &old_len);
611 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
612 &new_mdata, &new_len);
613 if (old_len != new_len ||
614 (old_mdata && new_mdata &&
615 memcmp(old_mdata, new_mdata, new_len))) {
616 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
617 new_mdata, new_len, TRUE, NULL, NULL);
618 param = g_variant_new("(@ay)", ad_data);
619 _bt_send_event(BT_ADAPTER_EVENT,
620 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
626 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
627 memcpy(&adv_data, adv, length);
628 adv_data_len = length;
630 BT_INFO("Set advertising data");
632 g_variant_unref(ret);
634 return BLUETOOTH_ERROR_NONE;
637 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
639 BT_CHECK_PARAMETER(response, return);
640 BT_CHECK_PARAMETER(length, return);
642 memcpy(response, &resp_data, sizeof(resp_data));
643 *length = resp_data_len;
645 return BLUETOOTH_ERROR_NONE;
648 int _bt_set_scan_response_data(const char *sender, int adv_handle,
649 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
652 GError *error = NULL;
653 GVariant *ret, *scan_data, *param = NULL;
654 GVariant *temp = NULL;
655 GVariantBuilder *builder;
657 char *old_mdata = NULL;
658 char *new_mdata = NULL;
663 if (__bt_is_factory_test_mode()) {
664 BT_ERR("Unable to set scan response list in factory binary !!");
665 return BLUETOOTH_ERROR_NOT_SUPPORT;
668 BT_CHECK_PARAMETER(response, return);
670 if (_bt_adapter_get_status() != BT_ACTIVATED &&
671 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
672 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
675 proxy = _bt_get_adapter_proxy();
676 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
678 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
680 BT_ERR("There is NO available slot!!");
681 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", response->data[i]);
688 temp = g_variant_new("ay", builder);
689 g_variant_builder_unref(builder);
690 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
691 g_variant_new("(@ayi)", temp, slot_id),
692 G_DBUS_CALL_FLAGS_NONE,
696 BT_ERR("SetScanRespData Fail: %s", error->message);
697 g_clear_error(&error);
698 return BLUETOOTH_ERROR_INTERNAL;
701 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
703 /* Compare with previous scan resp data */
704 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
705 &old_mdata, &old_len);
706 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
707 &new_mdata, &new_len);
708 if (old_len != new_len ||
709 (old_mdata && new_mdata &&
710 memcmp(old_mdata, new_mdata, new_len))) {
711 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
712 new_mdata, new_len, TRUE, NULL, NULL);
713 param = g_variant_new("(@ay)", scan_data);
714 _bt_send_event(BT_ADAPTER_EVENT,
715 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
721 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
722 memcpy(&resp_data, response, length);
723 resp_data_len = length;
726 g_variant_unref(ret);
727 BT_INFO("Set scan response data");
728 return BLUETOOTH_ERROR_NONE;
731 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
734 GError *error = NULL;
739 BT_CHECK_PARAMETER(params, return);
741 if (_bt_adapter_get_status() != BT_ACTIVATED &&
742 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
743 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
746 proxy = _bt_get_adapter_proxy();
747 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
749 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
750 return BLUETOOTH_ERROR_INVALID_PARAM;
752 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
753 return BLUETOOTH_ERROR_INVALID_PARAM;
755 if (params->window > params->interval)
756 return BLUETOOTH_ERROR_INVALID_PARAM;
758 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
759 win = params->window / BT_ADV_INTERVAL_SPLIT;
761 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
762 g_variant_new("(uuu)", params->type, itv, win),
763 G_DBUS_CALL_FLAGS_NONE, -1,
767 BT_ERR("SetScanParameters Fail: %s", error->message);
768 g_clear_error(&error);
769 return BLUETOOTH_ERROR_INTERNAL;
772 _bt_set_le_scan_type(params->type);
774 is_le_set_scan_parameter = TRUE;
777 g_variant_unref(ret);
778 BT_INFO("Set scan parameters");
779 return BLUETOOTH_ERROR_NONE;
782 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
785 bt_adapter_le_scanner_t *scanner;
787 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
789 if (g_strcmp0(scanner->sender, sender) == 0)
796 int __bt_get_available_scan_filter_slot_id(void)
799 bt_adapter_le_scanner_t *scanner;
801 bluetooth_le_scan_filter_t *filter_data;
802 gboolean *slot_check_list = NULL;
805 if (le_feature_info.max_filter == 0) {
806 BT_ERR("Scan filter is NOT Supported");
809 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
810 if (slot_check_list == NULL) {
811 BT_ERR("Fail to allocate memory");
815 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
817 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
818 filter_data = fl->data;
819 if (filter_data->slot_id < le_feature_info.max_filter) {
820 slot_check_list[filter_data->slot_id] = TRUE;
825 for (i = 0; i < le_feature_info.max_filter; i++) {
826 if (slot_check_list[i] == FALSE) {
827 g_free(slot_check_list);
832 BT_ERR("There is NO available slot for scan filter.");
833 g_free(slot_check_list);
837 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
840 GError *error = NULL;
841 GVariant *ret, *param;
842 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
843 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
844 GArray *arr_uuid = NULL;
845 GArray *arr_uuid_mask = NULL;
846 GArray *arr_data = NULL;
847 GArray *arr_data_mask = NULL;
848 bt_adapter_le_scanner_t *scanner = NULL;
849 bluetooth_le_scan_filter_t *filter_data = NULL;
850 int feature_selection = 0;
852 *slot_id = __bt_get_available_scan_filter_slot_id();
854 return BLUETOOTH_ERROR_NO_RESOURCES;
856 proxy = _bt_get_adapter_proxy();
857 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
859 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
860 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
861 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
863 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
865 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
866 NULL, 0, TRUE, NULL, NULL);
867 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
868 NULL, 0, TRUE, NULL, NULL);
869 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
870 NULL, 0, TRUE, NULL, NULL);
871 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
872 NULL, 0, TRUE, NULL, NULL);
874 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
876 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
877 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
878 *slot_id, // filter_index
880 0, // company_id_mask
881 arr_uuid_param, // p_uuid
882 arr_uuid_mask_param, // p_uuid_mask
885 arr_data_param, // p_data
886 arr_data_mask_param); // p_mask
888 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
889 param, G_DBUS_CALL_FLAGS_NONE,
893 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
894 g_clear_error(&error);
897 g_variant_unref(ret);
900 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
901 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
903 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
904 NULL, 0, TRUE, NULL, NULL);
905 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
906 NULL, 0, TRUE, NULL, NULL);
907 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
908 NULL, 0, TRUE, NULL, NULL);
909 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
910 NULL, 0, TRUE, NULL, NULL);
912 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
914 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
915 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
916 *slot_id, // filter_index
918 0, // company_id_mask
919 arr_uuid_param, // p_uuid
920 arr_uuid_mask_param, // p_uuid_mask
921 filter->device_name, // string
923 arr_data_param, // p_data
924 arr_data_mask_param);
926 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
927 param, G_DBUS_CALL_FLAGS_NONE,
931 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
932 g_clear_error(&error);
935 g_variant_unref(ret);
938 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
939 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
941 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
942 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
944 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
945 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
947 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
948 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
949 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
950 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
951 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
952 NULL, 0, TRUE, NULL, NULL);
953 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
954 NULL, 0, TRUE, NULL, NULL);
956 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
958 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
959 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
960 *slot_id, // filter_index
962 0, // company_id_mask
963 arr_uuid_param, // p_uuid
964 arr_uuid_mask_param, // p_uuid_mask
967 arr_data_param, // p_data
968 arr_data_mask_param);
970 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
971 param, G_DBUS_CALL_FLAGS_NONE,
975 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
976 g_clear_error(&error);
979 g_variant_unref(ret);
981 g_array_free(arr_uuid, TRUE);
982 g_array_free(arr_uuid_mask, TRUE);
983 g_array_free(arr_data, TRUE);
984 g_array_free(arr_data_mask, TRUE);
987 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
988 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
990 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
991 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
993 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
994 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
996 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
997 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
998 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
999 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
1000 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1001 NULL, 0, TRUE, NULL, NULL);
1002 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1003 NULL, 0, TRUE, NULL, NULL);
1005 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1007 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1008 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1009 *slot_id, // filter_index
1011 0, // company_id_mask
1012 arr_uuid_param, // p_uuid
1013 arr_uuid_mask_param, // p_uuid_mask
1016 arr_data_param, // p_data
1017 arr_data_mask_param);
1019 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1020 G_DBUS_CALL_FLAGS_NONE,
1024 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1025 g_clear_error(&error);
1028 g_variant_unref(ret);
1030 g_array_free(arr_uuid, TRUE);
1031 g_array_free(arr_uuid_mask, TRUE);
1034 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1035 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1037 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1038 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1040 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1041 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1043 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1044 NULL, 0, TRUE, NULL, NULL);
1045 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1046 NULL, 0, TRUE, NULL, NULL);
1047 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1048 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1049 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1050 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1052 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1054 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1055 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1056 *slot_id, // filter_index
1058 0, // company_id_mask
1059 arr_uuid_param, // p_uuid
1060 arr_uuid_mask_param, // p_uuid_mask
1063 arr_data_param, // p_data
1064 arr_data_mask_param);
1066 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1067 G_DBUS_CALL_FLAGS_NONE,
1071 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1072 g_clear_error(&error);
1075 g_variant_unref(ret);
1077 g_array_free(arr_data, TRUE);
1078 g_array_free(arr_data_mask, TRUE);
1081 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1082 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1084 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1085 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1087 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1088 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1090 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1091 NULL, 0, TRUE, NULL, NULL);
1092 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1093 NULL, 0, TRUE, NULL, NULL);
1094 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1095 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1096 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1097 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1099 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1101 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1102 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1103 *slot_id, // filter_index
1104 filter->manufacturer_id, // company_id
1105 0xFFFF, // company_id_mask
1106 arr_uuid_param, // p_uuid
1107 arr_uuid_mask_param, // p_uuid_mask
1110 arr_data_param, // p_data
1111 arr_data_mask_param);
1113 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1114 G_DBUS_CALL_FLAGS_NONE,
1118 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1119 g_clear_error(&error);
1122 g_variant_unref(ret);
1124 g_array_free(arr_data, TRUE);
1125 g_array_free(arr_data_mask, TRUE);
1128 BT_DBG("Filter selection %.2x", feature_selection);
1130 param = g_variant_new("(iiiiiiiiiiii)",
1132 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1133 *slot_id, // filter_index
1134 feature_selection, // feat_seln
1135 0, // list_logic_type (OR - 0x00, AND - 0x01)
1136 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1137 -127, // rssi_high_thres
1138 -127, // rssi_low_thres
1139 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1142 0); // found_timeout_cnt
1143 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1144 param, G_DBUS_CALL_FLAGS_NONE,
1148 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1149 g_clear_error(&error);
1152 scanner = __bt_find_scanner_from_list(sender);
1153 if (scanner == NULL) {
1154 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1156 scanner->sender = strdup(sender);
1157 scanner_list = g_slist_append(scanner_list, scanner);
1161 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1163 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1164 filter_data->slot_id = *slot_id;
1167 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1171 g_variant_unref(ret);
1172 return BLUETOOTH_ERROR_NONE;
1175 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1178 GError *error = NULL;
1180 bt_adapter_le_scanner_t *scanner = NULL;
1181 bluetooth_le_scan_filter_t *filter_data = NULL;
1183 gboolean is_slot_id_found = FALSE;
1185 scanner = __bt_find_scanner_from_list(sender);
1186 if (scanner == NULL) {
1187 BT_ERR("There is NO available scanner.");
1188 return BLUETOOTH_ERROR_NOT_FOUND;
1191 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1192 filter_data = l->data;
1193 if (filter_data->slot_id == slot_id) {
1194 is_slot_id_found = TRUE;
1198 if (is_slot_id_found == FALSE) {
1199 BT_ERR("There is NO registered slot.");
1200 return BLUETOOTH_ERROR_NOT_FOUND;
1203 proxy = _bt_get_adapter_proxy();
1204 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1206 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1207 g_variant_new("(ii)", 0, slot_id),
1208 G_DBUS_CALL_FLAGS_NONE,
1212 BT_ERR("scan_filter_clear Fail: %s", error->message);
1213 g_clear_error(&error);
1216 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1217 g_free(filter_data);
1220 g_variant_unref(ret);
1221 return BLUETOOTH_ERROR_NONE;
1224 int _bt_unregister_all_scan_filters(const char *sender)
1227 GError *error = NULL;
1229 bt_adapter_le_scanner_t *scanner = NULL;
1230 bluetooth_le_scan_filter_t *filter_data = NULL;
1233 scanner = __bt_find_scanner_from_list(sender);
1234 if (scanner == NULL) {
1235 BT_ERR("There is NO available scanner.");
1236 return BLUETOOTH_ERROR_NOT_FOUND;
1239 proxy = _bt_get_adapter_proxy();
1240 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1242 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1243 filter_data = l->data;
1245 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1246 g_variant_new("(ii)", 0, filter_data->slot_id),
1247 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1250 BT_ERR("scan_filter_clear Fail: %s", error->message);
1251 g_clear_error(&error);
1254 g_variant_unref(ret);
1257 g_slist_free_full(scanner->filter_list, g_free);
1258 scanner->filter_list = NULL;
1260 return BLUETOOTH_ERROR_NONE;
1263 int _bt_start_le_scan(const char *sender)
1266 GError *error = NULL;
1268 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1270 if (scanner == NULL) {
1271 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1272 retv_if(scanner == NULL, BLUETOOTH_ERROR_INTERNAL);
1274 scanner->sender = strdup(sender);
1275 scanner_list = g_slist_append(scanner_list, scanner);
1278 if (scanner->is_scanning == TRUE) {
1279 BT_ERR("BT is already in LE scanning");
1280 return BLUETOOTH_ERROR_IN_PROGRESS;
1282 scanner->is_scanning = TRUE;
1284 proxy = _bt_get_adapter_proxy();
1285 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1287 if (_bt_is_le_scanning()) {
1288 if (scan_filter_enabled == TRUE) {
1289 if (scanner->filter_list == NULL) {
1290 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1291 g_variant_new("(ib)", 0, FALSE),
1292 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1295 BT_ERR("scan_filter_clear Fail: %s", error->message);
1296 g_clear_error(&error);
1300 g_variant_unref(ret);
1301 BT_INFO("Disable LE Scan Filter");
1302 scan_filter_enabled = FALSE;
1304 BT_INFO("LE Filter Scan is continue");
1307 BT_INFO("LE Full Scan is already on progress");
1309 return BLUETOOTH_ERROR_NONE;
1311 if (is_le_set_scan_parameter == FALSE) {
1312 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1313 bluetooth_le_scan_params_t scan_params;
1314 scan_params.type = BT_LE_ACTIVE_SCAN;
1315 scan_params.interval = 5000;
1316 scan_params.window = 500;
1317 _bt_set_scan_parameters(&scan_params);
1320 if (scanner->filter_list == NULL) {
1321 BT_INFO("Start LE Full Scan");
1322 scan_filter_enabled = FALSE;
1324 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1325 g_variant_new("(ib)", 0, TRUE),
1326 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1329 BT_ERR("scan_filter_clear Fail: %s", error->message);
1330 g_clear_error(&error);
1334 g_variant_unref(ret);
1335 BT_INFO("Enable LE Scan Filter");
1336 scan_filter_enabled = TRUE;
1340 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1341 NULL,G_DBUS_CALL_FLAGS_NONE,
1345 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1346 g_clear_error(&error);
1347 return BLUETOOTH_ERROR_INTERNAL;
1351 g_variant_unref(ret);
1352 return BLUETOOTH_ERROR_NONE;
1355 int _bt_stop_le_scan(const char *sender)
1358 GError *error = NULL;
1360 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1362 gboolean next_scanning = FALSE;
1363 gboolean need_scan_filter = TRUE;
1365 if (scanner == NULL || scanner->is_scanning == FALSE)
1366 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1368 scanner->is_scanning = FALSE;
1370 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1372 if (scanner->is_scanning == TRUE) {
1373 next_scanning = TRUE;
1374 if (scanner->filter_list == NULL)
1375 need_scan_filter = FALSE;
1379 proxy = _bt_get_adapter_proxy();
1380 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1382 if (next_scanning == TRUE) {
1383 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1384 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1385 g_variant_new("(ib)", 0, TRUE),
1386 G_DBUS_CALL_FLAGS_NONE,
1390 BT_ERR("scan_filter_clear Fail: %s", error->message);
1391 g_clear_error(&error);
1395 g_variant_unref(ret);
1396 BT_INFO("Enable LE Scan Filter");
1397 scan_filter_enabled = TRUE;
1399 return BLUETOOTH_ERROR_NONE;
1401 if (scan_filter_enabled == TRUE) {
1402 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1403 g_variant_new("(ib)", 0, FALSE),
1404 G_DBUS_CALL_FLAGS_NONE,
1408 BT_ERR("scan_filter_clear Fail: %s", error->message);
1409 g_clear_error(&error);
1413 g_variant_unref(ret);
1414 BT_INFO("Disable LE Scan Filter");
1416 BT_INFO("Just stop LE scan");
1420 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1421 NULL,G_DBUS_CALL_FLAGS_NONE,
1424 BT_ERR("LE Scan stop failed");
1425 return BLUETOOTH_ERROR_INTERNAL;
1428 scan_filter_enabled = FALSE;
1429 is_le_set_scan_parameter = FALSE;
1431 g_variant_unref(ret);
1432 return BLUETOOTH_ERROR_NONE;
1435 void _bt_disable_all_scanner_status(void)
1438 bt_adapter_le_scanner_t *scanner;
1440 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1442 scanner->is_scanning = FALSE;
1446 void _bt_set_le_scan_status(gboolean mode)
1448 is_le_scanning = mode;
1451 gboolean _bt_is_le_scanning(void)
1453 return is_le_scanning;
1456 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1458 le_scan_type = type;
1461 bt_le_scan_type_t _bt_get_le_scan_type(void)
1463 return le_scan_type;
1466 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1467 int adv_data_len, const char *svc_uuid, int uuid_len,
1468 const char *uuid_mask, char ad_type)
1474 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1475 ad_type, &data, &data_len);
1477 _bt_swap_byte_ordering(data, data_len);
1478 for (i = 0; i < data_len; i += uuid_len) {
1479 if (uuid_len > (data_len - i))
1482 if (_bt_byte_arr_cmp_with_mask(data + i,
1483 svc_uuid, uuid_mask, uuid_len) == 0) {
1494 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1495 const char *adv_data, int adv_data_len,
1496 const char *scan_data, int scan_data_len,
1497 const bt_adapter_le_scanner_t *scanner)
1500 bluetooth_le_scan_filter_t *filter_data = NULL;
1503 gboolean is_matched = FALSE;
1505 if (scanner->filter_list == NULL) {
1506 BT_INFO("This scanner is on Full Scan.");
1510 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1511 filter_data = l->data;
1513 if (filter_data->added_features &
1514 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1515 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1517 _bt_convert_addr_type_to_string(address,
1518 filter_data->device_address.addr);
1519 if (strncmp(address, device_address,
1520 BT_ADDRESS_STRING_SIZE) != 0)
1524 if (filter_data->added_features &
1525 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1528 if (__bt_check_scan_result_uuid(adv_data,
1530 (char*)filter_data->service_uuid.data.data,
1531 filter_data->service_uuid.data_len,
1532 (char*)filter_data->service_uuid_mask.data.data,
1533 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1536 if (__bt_check_scan_result_uuid(adv_data,
1538 (char*)filter_data->service_uuid.data.data,
1539 filter_data->service_uuid.data_len,
1540 (char*)filter_data->service_uuid_mask.data.data,
1541 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1544 if (__bt_check_scan_result_uuid(adv_data,
1546 (char*)filter_data->service_uuid.data.data,
1547 filter_data->service_uuid.data_len,
1548 (char*)filter_data->service_uuid_mask.data.data,
1549 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1552 if (__bt_check_scan_result_uuid(adv_data,
1554 (char*)filter_data->service_uuid.data.data,
1555 filter_data->service_uuid.data_len,
1556 (char*)filter_data->service_uuid_mask.data.data,
1557 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1560 if (__bt_check_scan_result_uuid(scan_data,
1562 (char*)filter_data->service_uuid.data.data,
1563 filter_data->service_uuid.data_len,
1564 (char*)filter_data->service_uuid_mask.data.data,
1565 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1568 if (__bt_check_scan_result_uuid(scan_data,
1570 (char*)filter_data->service_uuid.data.data,
1571 filter_data->service_uuid.data_len,
1572 (char*)filter_data->service_uuid_mask.data.data,
1573 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1576 if (__bt_check_scan_result_uuid(scan_data,
1578 (char*)filter_data->service_uuid.data.data,
1579 filter_data->service_uuid.data_len,
1580 (char*)filter_data->service_uuid_mask.data.data,
1581 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1584 if (__bt_check_scan_result_uuid(scan_data,
1586 (char*)filter_data->service_uuid.data.data,
1587 filter_data->service_uuid.data_len,
1588 (char*)filter_data->service_uuid_mask.data.data,
1589 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1593 if (is_matched == FALSE)
1596 if (filter_data->added_features &
1597 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1600 if (__bt_check_scan_result_uuid(adv_data,
1602 (char*)filter_data->service_solicitation_uuid.data.data,
1603 filter_data->service_solicitation_uuid.data_len,
1604 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1605 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1608 if (__bt_check_scan_result_uuid(adv_data,
1610 (char*)filter_data->service_solicitation_uuid.data.data,
1611 filter_data->service_solicitation_uuid.data_len,
1612 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1613 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1616 if (__bt_check_scan_result_uuid(scan_data,
1618 (char*)filter_data->service_solicitation_uuid.data.data,
1619 filter_data->service_solicitation_uuid.data_len,
1620 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1621 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1624 if (__bt_check_scan_result_uuid(scan_data,
1626 (char*)filter_data->service_solicitation_uuid.data.data,
1627 filter_data->service_solicitation_uuid.data_len,
1628 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1629 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1633 if (is_matched == FALSE)
1636 if (filter_data->added_features &
1637 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1638 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1643 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1644 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1647 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1648 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1649 memcpy(name, data, data_len);
1650 name[data_len] = '\0';
1653 if (strncmp(filter_data->device_name,
1654 name, data_len) == 0)
1657 __bt_get_ad_data_by_type((char*)scan_data,
1659 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1662 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1663 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1664 memcpy(name, data, data_len);
1665 name[data_len] = '\0';
1668 if (strncmp(filter_data->device_name,
1669 name, data_len) == 0)
1673 if (is_matched == FALSE)
1676 if (filter_data->added_features &
1677 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1682 __bt_get_ad_data_by_type((char*)adv_data,
1684 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1687 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1688 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1689 if (_bt_byte_arr_cmp_with_mask(data,
1690 (char*)filter_data->manufacturer_data.data.data,
1691 (char*)filter_data->manufacturer_data_mask.data.data,
1698 __bt_get_ad_data_by_type((char*)scan_data,
1700 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1703 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1704 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1705 if (_bt_byte_arr_cmp_with_mask(data,
1706 (char*)filter_data->manufacturer_data.data.data,
1707 (char*)filter_data->manufacturer_data_mask.data.data,
1715 if (is_matched == FALSE)
1718 if (filter_data->added_features &
1719 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1724 __bt_get_ad_data_by_type((char*)adv_data,
1726 BT_LE_AD_TYPE_SERVICE_DATA,
1729 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1730 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1731 if (_bt_byte_arr_cmp_with_mask(data,
1732 (char*)filter_data->service_data.data.data,
1733 (char*)filter_data->service_data_mask.data.data,
1740 __bt_get_ad_data_by_type((char*)scan_data,
1742 BT_LE_AD_TYPE_SERVICE_DATA,
1745 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1746 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1747 if (_bt_byte_arr_cmp_with_mask(data,
1748 (char*)filter_data->service_data.data.data,
1749 (char*)filter_data->service_data_mask.data.data,
1757 if (is_matched == FALSE)
1761 BT_INFO("The scan result is conformable.");
1765 BT_INFO("The scan result is NOT conformable.");
1769 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1770 const bt_le_adv_info_t *adv_info)
1772 int result = BLUETOOTH_ERROR_NONE;
1774 GVariant *scan_data_param, *adv_data_param;
1776 bt_adapter_le_scanner_t *scanner = NULL;
1777 const char *adv_data = NULL;
1778 int adv_data_len = 0;
1779 const char *scan_data = NULL;
1780 int scan_data_len = 0;
1782 ret_if(le_dev_info == NULL);
1783 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1784 ret_if(adv_info == NULL);
1786 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1787 adv_data = le_dev_info->adv_data;
1788 adv_data_len = le_dev_info->adv_data_len;
1789 scan_data = le_dev_info->adv_data;
1792 adv_data = adv_info->data;
1793 adv_data_len = adv_info->data_len;
1794 scan_data = le_dev_info->adv_data;
1795 scan_data_len = le_dev_info->adv_data_len;
1798 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1800 if (scanner->is_scanning == FALSE)
1803 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1804 adv_data, adv_data_len, scan_data, scan_data_len,
1808 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1809 adv_data, adv_data_len, TRUE, NULL, NULL);
1810 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1811 scan_data, scan_data_len, TRUE, NULL, NULL);
1813 param = g_variant_new("(isnnn@ayn@ay)",
1815 le_dev_info->address,
1816 le_dev_info->addr_type,
1823 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1824 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1828 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1831 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1832 GError *error = NULL;
1835 if (__bt_is_factory_test_mode()) {
1836 BT_ERR("Unable to add white list in factory binary !!");
1837 return BLUETOOTH_ERROR_NOT_SUPPORT;
1840 BT_CHECK_PARAMETER(device_address, return);
1842 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1843 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1844 return BLUETOOTH_ERROR_INVALID_PARAM;
1846 _bt_convert_addr_type_to_string(address, device_address->addr);
1848 proxy = _bt_get_adapter_proxy();
1849 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1851 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1852 g_variant_new("(su)", address, address_type),
1853 G_DBUS_CALL_FLAGS_NONE, -1,
1857 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
1858 g_clear_error(&error);
1859 return BLUETOOTH_ERROR_INTERNAL;
1863 g_variant_unref(ret);
1864 BT_INFO("Add white list");
1866 return BLUETOOTH_ERROR_NONE;
1869 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1872 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1873 GError *error = NULL;
1876 if (__bt_is_factory_test_mode()) {
1877 BT_ERR("Unable to remove white list in factory binary !!");
1878 return BLUETOOTH_ERROR_NOT_SUPPORT;
1881 BT_CHECK_PARAMETER(device_address, return);
1883 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1884 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1885 return BLUETOOTH_ERROR_INVALID_PARAM;
1887 _bt_convert_addr_type_to_string(address, device_address->addr);
1889 proxy = _bt_get_adapter_proxy();
1890 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1892 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1893 g_variant_new("(su)", address, address_type),
1894 G_DBUS_CALL_FLAGS_NONE, -1,
1898 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
1899 g_clear_error(&error);
1900 return BLUETOOTH_ERROR_INTERNAL;
1904 g_variant_unref(ret);
1905 BT_INFO("Remove white list");
1907 return BLUETOOTH_ERROR_NONE;
1910 int _bt_clear_white_list(void)
1913 GError *error = NULL;
1916 if (__bt_is_factory_test_mode()) {
1917 BT_ERR("Unable to clear white list in factory binary !!");
1918 return BLUETOOTH_ERROR_NOT_SUPPORT;
1921 proxy = _bt_get_adapter_proxy();
1922 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1924 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
1925 NULL,G_DBUS_CALL_FLAGS_NONE,
1929 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
1930 g_clear_error(&error);
1931 return BLUETOOTH_ERROR_INTERNAL;
1934 g_variant_unref(ret);
1936 BT_INFO("Clear white list");
1938 return BLUETOOTH_ERROR_NONE;
1941 int _bt_initialize_ipsp(void)
1945 GError *error = NULL;
1948 if (_bt_adapter_get_status() != BT_ACTIVATED &&
1949 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
1950 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1953 proxy = _bt_get_adapter_proxy();
1954 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1956 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
1957 NULL,G_DBUS_CALL_FLAGS_NONE,
1960 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
1961 g_clear_error(&error);
1962 return BLUETOOTH_ERROR_INTERNAL;
1965 g_variant_unref(ret);
1967 BT_INFO("IPSP initialization called successfully");
1969 return BLUETOOTH_ERROR_NONE;
1972 int _bt_deinitialize_ipsp(void)
1976 GError *error = NULL;
1978 bt_le_status_t le_status = _bt_adapter_get_le_status();
1980 if (_bt_adapter_get_status() != BT_ACTIVATED &&
1981 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
1982 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1985 proxy = _bt_get_adapter_proxy();
1986 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1988 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
1989 NULL,G_DBUS_CALL_FLAGS_NONE,
1992 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
1993 g_clear_error(&error);
1994 return BLUETOOTH_ERROR_INTERNAL;
1997 g_variant_unref(ret);
1999 BT_INFO("IPSP De-initialization called successfully");
2001 return BLUETOOTH_ERROR_NONE;
2004 int _bt_le_read_maximum_data_length(
2005 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2007 GError *error = NULL;
2009 GVariant *reply = NULL;
2010 int ret = BLUETOOTH_ERROR_NONE;
2011 guint16 max_tx_octets, max_tx_time;
2012 guint16 max_rx_octets, max_rx_time;
2014 proxy = _bt_get_adapter_proxy();
2015 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2017 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2018 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2020 g_object_unref(proxy);
2022 if (reply == NULL) {
2023 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2024 if (error != NULL) {
2025 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2026 error->code, error->message);
2027 g_clear_error(&error);
2029 return BLUETOOTH_ERROR_INTERNAL;
2032 g_variant_get(reply ,"(qqqq)", &max_tx_octets, &max_tx_time,
2033 &max_rx_octets, &max_rx_time);
2035 max_le_datalength->max_tx_octets = max_tx_octets;
2036 max_le_datalength->max_tx_time = max_tx_time;
2037 max_le_datalength->max_rx_octets = max_rx_octets;
2038 max_le_datalength->max_rx_time = max_rx_time;
2040 g_variant_unref(reply);
2042 return BLUETOOTH_ERROR_NONE;
2044 int _bt_le_write_host_suggested_default_data_length(
2045 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2047 GError *error = NULL;
2049 GVariant *reply = NULL;
2050 int ret = BLUETOOTH_ERROR_NONE;
2052 proxy = _bt_get_adapter_proxy();
2053 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2055 reply = g_dbus_proxy_call_sync(proxy,
2056 "LEWriteHostSuggestedDataLength",
2057 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2058 G_DBUS_CALL_FLAGS_NONE,
2063 g_object_unref(proxy);
2065 if (reply == NULL) {
2066 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2067 if (error != NULL) {
2068 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2069 error->code, error->message);
2070 g_clear_error(&error);
2072 return BLUETOOTH_ERROR_INTERNAL;
2075 g_variant_unref(reply);
2077 return BLUETOOTH_ERROR_NONE;
2080 int _bt_le_read_host_suggested_default_data_length(
2081 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2083 GError *error = NULL;
2085 GVariant *reply = NULL;
2086 int ret = BLUETOOTH_ERROR_NONE;
2087 guint16 def_tx_octets, def_tx_time;
2089 proxy = _bt_get_adapter_proxy();
2090 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2092 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2093 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2095 if (reply == NULL) {
2096 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2097 if (error != NULL) {
2098 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2099 error->code, error->message);
2100 g_clear_error(&error);
2102 return BLUETOOTH_ERROR_INTERNAL;
2105 g_variant_get(reply ,"(qq)", &def_tx_octets, &def_tx_time);
2107 def_data_length->def_tx_octets = def_tx_octets;
2108 def_data_length->def_tx_time = def_tx_time;
2110 g_variant_unref(reply);
2112 return BLUETOOTH_ERROR_NONE;
2115 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2116 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2118 GError *error = NULL;
2120 GVariant *reply = NULL;
2121 int ret = BLUETOOTH_ERROR_NONE;
2122 guint16 txOctets = max_tx_Octets;
2123 guint16 txTime = max_tx_Time;
2124 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2125 gchar *device_path = NULL;
2126 GDBusConnection *conn;
2127 GDBusProxy *device_proxy;
2129 _bt_convert_addr_type_to_string(address, device_address->addr);
2131 device_path = _bt_get_device_object_path(&address);
2133 if (device_path == NULL) {
2134 BT_DBG("Device path is null");
2135 return BLUETOOTH_ERROR_INTERNAL;
2138 conn = _bt_get_system_gconn();
2140 BT_ERR("conn == NULL");
2141 g_free(device_path);
2145 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2146 NULL, BT_BLUEZ_NAME,
2147 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2149 g_free(device_path);
2150 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2152 g_dbus_proxy_call_sync(device_proxy,
2154 g_variant_new("(qq)", txOctets, txTime),
2155 G_DBUS_CALL_FLAGS_NONE,
2160 g_object_unref(device_proxy);
2163 BT_ERR("LESetDataLength error: [%s]", error->message);
2164 g_error_free(error);
2165 return BLUETOOTH_ERROR_INTERNAL;
2168 return BLUETOOTH_ERROR_NONE;