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 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
26 #include <syspopup_caller.h>
30 #include "bt-internal-types.h"
31 #include "bt-service-common.h"
32 #include "bt-service-event.h"
33 #include "bt-service-adapter.h"
34 #include "bt-service-adapter-le.h"
35 #include "bt-service-util.h"
38 #define BT_ADV_INTERVAL_MIN 20 /* msec */
39 #define BT_ADV_INTERVAL_MAX 10240
40 #define BT_ADV_INTERVAL_SPLIT 0.625
41 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
42 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
43 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
44 #define BT_ADV_TYPE_DEFAULT 0x00
45 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
51 } bt_adapter_le_feature_info_t;
56 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);
179 int _bt_service_adapter_le_init(void)
181 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
183 return BLUETOOTH_ERROR_NONE;
186 void _bt_service_adapter_le_deinit(void)
188 __bt_free_le_adv_slot();
191 gboolean _bt_update_le_feature_support(const char *item, const char *value)
193 if (item== NULL || value == NULL)
196 if (g_strcmp0(item, "adv_inst_max") == 0) {
197 if (atoi(value) != le_feature_info.adv_inst_max) {
198 __bt_free_le_adv_slot();
199 le_feature_info.adv_inst_max = atoi(value);
200 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
202 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
203 le_feature_info.rpa_offloading = atoi(value);
204 } else if (g_strcmp0(item, "max_filter") == 0) {
205 le_feature_info.max_filter = atoi(value);
207 BT_DBG("No registered item");
214 static gboolean __bt_is_factory_test_mode(void)
217 #ifdef ENABLE_TIZEN_2_4
218 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
219 BT_ERR("Get the DUT Mode fail");
224 BT_INFO("DUT Test Mode !!");
231 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
235 if (le_adv_slot == NULL)
238 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
239 if (le_adv_slot[i].sender == NULL)
241 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
245 if (le_feature_info.adv_inst_max <= 2)
247 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
252 for (; i < le_feature_info.adv_inst_max; i++) {
253 if (le_adv_slot[i].sender == NULL)
260 void _bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
262 if (le_adv_slot[slot_id].sender == NULL) {
263 le_adv_slot[slot_id].sender = strdup(sender);
264 le_adv_slot[slot_id].adv_handle = adv_handle;
268 void _bt_unregister_adv_slot_owner(int slot_id)
270 g_free(le_adv_slot[slot_id].sender);
271 le_adv_slot[slot_id].sender = NULL;
272 le_adv_slot[slot_id].adv_handle = 0;
275 const char* _bt_get_adv_slot_owner(int slot_id)
277 if (le_adv_slot == NULL)
280 return le_adv_slot[slot_id].sender;
283 int _bt_get_adv_slot_adv_handle(int slot_id)
285 if (le_adv_slot == NULL)
288 return le_adv_slot[slot_id].adv_handle;
291 void _bt_set_advertising_status(int slot_id, gboolean mode)
293 le_adv_slot[slot_id].is_advertising = mode;
296 gboolean _bt_is_advertising(void)
298 gboolean status = FALSE;
301 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
302 if (le_adv_slot[i].is_advertising == TRUE)
309 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
313 if (le_adv_slot == NULL)
316 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
317 if (le_adv_slot[i].sender != NULL) {
318 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
319 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
320 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
326 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
331 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
336 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
339 GError *error = NULL;
343 if (__bt_is_factory_test_mode()) {
344 BT_ERR("Unable to start advertising in factory binary !!");
345 return BLUETOOTH_ERROR_NOT_SUPPORT;
348 if (_bt_adapter_get_status() != BT_ACTIVATED &&
349 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
350 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
353 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
355 BT_ERR("There is NO available slot!!");
356 return BLUETOOTH_ERROR_NO_RESOURCES;
359 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
360 return BLUETOOTH_ERROR_IN_PROGRESS;
362 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
363 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
365 proxy = _bt_get_adapter_proxy();
366 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
368 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
369 g_variant_new("(bi)", enable, slot_id),
370 G_DBUS_CALL_FLAGS_NONE,
376 BT_ERR("SetAdvertising Fail: %s", error->message);
377 g_clear_error(&error);
378 return BLUETOOTH_ERROR_INTERNAL;
382 _bt_register_adv_slot_owner(sender, adv_handle, slot_id);
384 le_adv_slot[slot_id].is_advertising = enable;
385 BT_INFO("Set advertising [%d]", enable);
388 g_variant_unref(ret);
390 return BLUETOOTH_ERROR_NONE;
393 int _bt_set_custom_advertising(const char *sender, int adv_handle,
394 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
398 GError *error = NULL;
403 BT_CHECK_PARAMETER(params, return);
405 if (__bt_is_factory_test_mode()) {
406 BT_ERR("Unable to start advertising in factory binary !!");
407 return BLUETOOTH_ERROR_NOT_SUPPORT;
410 if (_bt_adapter_get_status() != BT_ACTIVATED &&
411 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
412 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
415 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
417 BT_ERR("There is NO available slot!!");
418 return BLUETOOTH_ERROR_NO_RESOURCES;
421 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
422 return BLUETOOTH_ERROR_IN_PROGRESS;
424 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
425 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
427 proxy = _bt_get_adapter_proxy();
428 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
430 if (params->interval_min > params->interval_max ||
431 params->interval_min < BT_ADV_INTERVAL_MIN ||
432 params->interval_max > BT_ADV_INTERVAL_MAX)
433 return BLUETOOTH_ERROR_INVALID_PARAM;
435 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
436 return BLUETOOTH_ERROR_INVALID_PARAM;
438 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
439 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
440 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
441 return BLUETOOTH_ERROR_NOT_SUPPORT;
443 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
444 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
446 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
447 g_variant_new("(uuuui)", min, max,
448 params->filter_policy, params->type,
449 slot_id), G_DBUS_CALL_FLAGS_NONE,
453 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
454 g_clear_error(&error);
455 return BLUETOOTH_ERROR_INTERNAL;
458 adv_params.interval_min = params->interval_min;
459 adv_params.interval_max = params->interval_max;
460 adv_params.filter_policy = params->filter_policy;
461 adv_params.type= params->type;
464 g_variant_unref(ret);
466 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
467 g_variant_new("(bi)", enable, slot_id),
468 G_DBUS_CALL_FLAGS_NONE,
474 BT_ERR("SetAdvertising Fail: %s", error->message);
475 g_clear_error(&error);
476 return BLUETOOTH_ERROR_INTERNAL;
480 _bt_register_adv_slot_owner(sender, adv_handle, slot_id);
482 _bt_unregister_adv_slot_owner(slot_id);
484 le_adv_slot[slot_id].is_advertising = enable;
485 BT_INFO_C("Set advertising [%d]", enable);
487 g_variant_unref(ret);
489 return BLUETOOTH_ERROR_NONE;
492 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
493 char in_type, char **data, int *data_len)
495 if (in_data == NULL || data == NULL || data_len == NULL)
496 return BLUETOOTH_ERROR_INTERNAL;
499 return BLUETOOTH_ERROR_INTERNAL;
505 for (i = 0; i < in_len; i++) {
507 if (len <= 0 || i + 1 >= in_len) {
508 BT_ERR("Invalid advertising data");
509 return BLUETOOTH_ERROR_INTERNAL;
512 type = in_data[i + 1];
513 if (type == in_type) {
523 if (i + len > in_len) {
524 BT_ERR("Invalid advertising data");
525 return BLUETOOTH_ERROR_INTERNAL;
526 } else if (len == 0) {
527 BT_DBG("AD Type 0x%02x data is not set", in_type);
530 return BLUETOOTH_ERROR_NONE;
533 *data = g_memdup(&in_data[i], len);
535 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
538 return BLUETOOTH_ERROR_NONE;
541 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
543 BT_CHECK_PARAMETER(adv, return);
544 BT_CHECK_PARAMETER(length, return);
546 memcpy(adv, &adv_data, sizeof(adv_data));
547 *length = adv_data_len;
549 return BLUETOOTH_ERROR_NONE;
552 int _bt_set_advertising_data(const char *sender, int adv_handle,
553 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
556 GError *error = NULL;
557 GVariant *ret, *ad_data, *param = NULL;
558 GVariant *temp = NULL;
559 GVariantBuilder *builder;
561 char *old_mdata = NULL;
562 char *new_mdata = NULL;
567 if (__bt_is_factory_test_mode()) {
568 BT_ERR("Unable to set advertising data in factory binary !!");
569 return BLUETOOTH_ERROR_NOT_SUPPORT;
572 BT_CHECK_PARAMETER(adv, return);
574 if (_bt_adapter_get_status() != BT_ACTIVATED &&
575 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
576 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
579 proxy = _bt_get_adapter_proxy();
580 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
582 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
584 BT_ERR("There is NO available slot!!");
585 return BLUETOOTH_ERROR_NO_RESOURCES;
588 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
589 for (i = 0; i < length; i++) {
590 g_variant_builder_add(builder, "y", adv->data[i]);
593 temp = g_variant_new("ay", builder);
594 g_variant_builder_unref(builder);
595 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
596 g_variant_new("(@ayi)", temp, slot_id),
597 G_DBUS_CALL_FLAGS_NONE,
601 BT_ERR("SetAdvertisingData Fail: %s", error->message);
602 g_clear_error(&error);
603 return BLUETOOTH_ERROR_INTERNAL;
606 _bt_register_adv_slot_owner(sender, adv_handle, slot_id);
608 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
609 &old_mdata, &old_len);
610 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
611 &new_mdata, &new_len);
612 if (old_len != new_len ||
613 (old_mdata && new_mdata &&
614 memcmp(old_mdata, new_mdata, new_len))) {
615 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
616 new_mdata, new_len, TRUE, NULL, NULL);
617 param = g_variant_new("(@ay)", ad_data);
618 _bt_send_event(BT_ADAPTER_EVENT,
619 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
625 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
626 memcpy(&adv_data, adv, length);
627 adv_data_len = length;
629 BT_INFO("Set advertising data");
631 g_variant_unref(ret);
633 return BLUETOOTH_ERROR_NONE;
636 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
638 BT_CHECK_PARAMETER(response, return);
639 BT_CHECK_PARAMETER(length, return);
641 memcpy(response, &resp_data, sizeof(resp_data));
642 *length = resp_data_len;
644 return BLUETOOTH_ERROR_NONE;
647 int _bt_set_scan_response_data(const char *sender, int adv_handle,
648 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
651 GError *error = NULL;
652 GVariant *ret, *scan_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 scan response list in factory binary !!");
664 return BLUETOOTH_ERROR_NOT_SUPPORT;
667 BT_CHECK_PARAMETER(response, 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;
682 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
683 for (i = 0; i < length; i++) {
684 g_variant_builder_add(builder, "y", response->data[i]);
687 temp = g_variant_new("ay", builder);
688 g_variant_builder_unref(builder);
689 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
690 g_variant_new("(@ayi)", temp, slot_id),
691 G_DBUS_CALL_FLAGS_NONE,
695 BT_ERR("SetScanRespData 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 /* Compare with previous scan resp data */
703 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
704 &old_mdata, &old_len);
705 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
706 &new_mdata, &new_len);
707 if (old_len != new_len ||
708 (old_mdata && new_mdata &&
709 memcmp(old_mdata, new_mdata, new_len))) {
710 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
711 new_mdata, new_len, TRUE, NULL, NULL);
712 param = g_variant_new("(@ay)", scan_data);
713 _bt_send_event(BT_ADAPTER_EVENT,
714 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
720 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
721 memcpy(&resp_data, response, length);
722 resp_data_len = length;
725 g_variant_unref(ret);
726 BT_INFO("Set scan response data");
727 return BLUETOOTH_ERROR_NONE;
730 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
733 GError *error = NULL;
738 BT_CHECK_PARAMETER(params, return);
740 if (_bt_adapter_get_status() != BT_ACTIVATED &&
741 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
742 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
745 proxy = _bt_get_adapter_proxy();
746 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
748 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
749 return BLUETOOTH_ERROR_INVALID_PARAM;
751 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
752 return BLUETOOTH_ERROR_INVALID_PARAM;
754 if (params->window > params->interval)
755 return BLUETOOTH_ERROR_INVALID_PARAM;
757 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
758 win = params->window / BT_ADV_INTERVAL_SPLIT;
760 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
761 g_variant_new("(uuu)", params->type, itv, win),
762 G_DBUS_CALL_FLAGS_NONE, -1,
766 BT_ERR("SetScanParameters Fail: %s", error->message);
767 g_clear_error(&error);
768 return BLUETOOTH_ERROR_INTERNAL;
771 _bt_set_le_scan_type(params->type);
773 is_le_set_scan_parameter = TRUE;
776 g_variant_unref(ret);
777 BT_INFO("Set scan parameters");
778 return BLUETOOTH_ERROR_NONE;
781 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
784 bt_adapter_le_scanner_t *scanner;
786 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
788 if (g_strcmp0(scanner->sender, sender) == 0)
795 int __bt_get_available_scan_filter_slot_id(void)
798 bt_adapter_le_scanner_t *scanner;
800 bluetooth_le_scan_filter_t *filter_data;
801 gboolean *slot_check_list = NULL;
804 if (le_feature_info.max_filter == 0) {
805 BT_ERR("Scan filter is NOT Supported");
808 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
809 if (slot_check_list == NULL) {
810 BT_ERR("Fail to allocate memory");
814 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
816 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
817 filter_data = fl->data;
818 if (filter_data->slot_id < le_feature_info.max_filter) {
819 slot_check_list[filter_data->slot_id] = TRUE;
824 for (i = 0; i < le_feature_info.max_filter; i++) {
825 if (slot_check_list[i] == FALSE) {
826 g_free(slot_check_list);
831 BT_ERR("There is NO available slot for scan filter.");
832 g_free(slot_check_list);
836 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
839 GError *error = NULL;
840 GVariant *ret, *param;
841 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
842 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
843 GArray *arr_uuid = NULL;
844 GArray *arr_uuid_mask = NULL;
845 GArray *arr_data = NULL;
846 GArray *arr_data_mask = NULL;
847 bt_adapter_le_scanner_t *scanner = NULL;
848 bluetooth_le_scan_filter_t *filter_data = NULL;
849 int feature_selection = 0;
851 *slot_id = __bt_get_available_scan_filter_slot_id();
853 return BLUETOOTH_ERROR_NO_RESOURCES;
855 proxy = _bt_get_adapter_proxy();
856 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
858 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
859 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
860 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
862 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
864 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
865 NULL, 0, TRUE, NULL, NULL);
866 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
867 NULL, 0, TRUE, NULL, NULL);
868 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
869 NULL, 0, TRUE, NULL, NULL);
870 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
871 NULL, 0, TRUE, NULL, NULL);
873 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
875 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
876 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
877 *slot_id, // filter_index
879 0, // company_id_mask
880 arr_uuid_param, // p_uuid
881 arr_uuid_mask_param, // p_uuid_mask
884 arr_data_param, // p_data
885 arr_data_mask_param); // p_mask
887 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
888 param, G_DBUS_CALL_FLAGS_NONE,
892 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
893 g_clear_error(&error);
896 g_variant_unref(ret);
899 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
900 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
902 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
903 NULL, 0, TRUE, NULL, NULL);
904 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
905 NULL, 0, TRUE, NULL, NULL);
906 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
907 NULL, 0, TRUE, NULL, NULL);
908 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
909 NULL, 0, TRUE, NULL, NULL);
911 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
913 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
914 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
915 *slot_id, // filter_index
917 0, // company_id_mask
918 arr_uuid_param, // p_uuid
919 arr_uuid_mask_param, // p_uuid_mask
920 filter->device_name, // string
922 arr_data_param, // p_data
923 arr_data_mask_param);
925 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
926 param, G_DBUS_CALL_FLAGS_NONE,
930 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
931 g_clear_error(&error);
934 g_variant_unref(ret);
937 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
938 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
940 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
941 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
943 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
944 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
946 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
947 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
948 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
949 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
950 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
951 NULL, 0, TRUE, NULL, NULL);
952 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
953 NULL, 0, TRUE, NULL, NULL);
955 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
957 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
958 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
959 *slot_id, // filter_index
961 0, // company_id_mask
962 arr_uuid_param, // p_uuid
963 arr_uuid_mask_param, // p_uuid_mask
966 arr_data_param, // p_data
967 arr_data_mask_param);
969 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
970 param, G_DBUS_CALL_FLAGS_NONE,
974 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
975 g_clear_error(&error);
978 g_variant_unref(ret);
980 g_array_free(arr_uuid, TRUE);
981 g_array_free(arr_uuid_mask, TRUE);
982 g_array_free(arr_data, TRUE);
983 g_array_free(arr_data_mask, TRUE);
986 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
987 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
989 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
990 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
992 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
993 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
995 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
996 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
997 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
998 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
999 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1000 NULL, 0, TRUE, NULL, NULL);
1001 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1002 NULL, 0, TRUE, NULL, NULL);
1004 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1006 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1007 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1008 *slot_id, // filter_index
1010 0, // company_id_mask
1011 arr_uuid_param, // p_uuid
1012 arr_uuid_mask_param, // p_uuid_mask
1015 arr_data_param, // p_data
1016 arr_data_mask_param);
1018 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1019 G_DBUS_CALL_FLAGS_NONE,
1023 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1024 g_clear_error(&error);
1027 g_variant_unref(ret);
1029 g_array_free(arr_uuid, TRUE);
1030 g_array_free(arr_uuid_mask, TRUE);
1033 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1034 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1036 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1037 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1039 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1040 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1042 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1043 NULL, 0, TRUE, NULL, NULL);
1044 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1045 NULL, 0, TRUE, NULL, NULL);
1046 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1047 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1048 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1049 arr_data_mask->data, arr_data_mask->len, 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_DATA, // 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", param,
1066 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_data, TRUE);
1077 g_array_free(arr_data_mask, TRUE);
1080 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1081 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1083 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1084 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1086 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1087 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1089 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1090 NULL, 0, TRUE, NULL, NULL);
1091 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1092 NULL, 0, TRUE, NULL, NULL);
1093 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1094 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1095 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1096 arr_data_mask->data, arr_data_mask->len, 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_MANUFACTURER_DATA, // filter_type
1102 *slot_id, // filter_index
1103 filter->manufacturer_id, // company_id
1104 0xFFFF, // 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_data, TRUE);
1124 g_array_free(arr_data_mask, TRUE);
1127 BT_DBG("Filter selection %.2x", feature_selection);
1129 param = g_variant_new("(iiiiiiiiiiii)",
1131 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1132 *slot_id, // filter_index
1133 feature_selection, // feat_seln
1134 0, // list_logic_type (OR - 0x00, AND - 0x01)
1135 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1136 -127, // rssi_high_thres
1137 -127, // rssi_low_thres
1138 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1141 0); // found_timeout_cnt
1142 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1143 param, G_DBUS_CALL_FLAGS_NONE,
1147 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1148 g_clear_error(&error);
1151 scanner = __bt_find_scanner_from_list(sender);
1152 if (scanner == NULL) {
1153 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1155 scanner->sender = strdup(sender);
1156 scanner_list = g_slist_append(scanner_list, scanner);
1160 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1162 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1163 filter_data->slot_id = *slot_id;
1166 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1170 g_variant_unref(ret);
1171 return BLUETOOTH_ERROR_NONE;
1174 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1177 GError *error = NULL;
1179 bt_adapter_le_scanner_t *scanner = NULL;
1180 bluetooth_le_scan_filter_t *filter_data = NULL;
1182 gboolean is_slot_id_found = FALSE;
1184 scanner = __bt_find_scanner_from_list(sender);
1185 if (scanner == NULL) {
1186 BT_ERR("There is NO available scanner.");
1187 return BLUETOOTH_ERROR_NOT_FOUND;
1190 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1191 filter_data = l->data;
1192 if (filter_data->slot_id == slot_id) {
1193 is_slot_id_found = TRUE;
1197 if (is_slot_id_found == FALSE) {
1198 BT_ERR("There is NO registered slot.");
1199 return BLUETOOTH_ERROR_NOT_FOUND;
1202 proxy = _bt_get_adapter_proxy();
1203 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1205 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1206 g_variant_new("(ii)", 0, slot_id),
1207 G_DBUS_CALL_FLAGS_NONE,
1211 BT_ERR("scan_filter_clear Fail: %s", error->message);
1212 g_clear_error(&error);
1215 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1216 g_free(filter_data);
1219 g_variant_unref(ret);
1220 return BLUETOOTH_ERROR_NONE;
1223 int _bt_unregister_all_scan_filters(const char *sender)
1226 GError *error = NULL;
1228 bt_adapter_le_scanner_t *scanner = NULL;
1229 bluetooth_le_scan_filter_t *filter_data = NULL;
1232 scanner = __bt_find_scanner_from_list(sender);
1233 if (scanner == NULL) {
1234 BT_ERR("There is NO available scanner.");
1235 return BLUETOOTH_ERROR_NOT_FOUND;
1238 proxy = _bt_get_adapter_proxy();
1239 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1241 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1242 filter_data = l->data;
1244 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1245 g_variant_new("(ii)", 0, filter_data->slot_id),
1246 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1249 BT_ERR("scan_filter_clear Fail: %s", error->message);
1250 g_clear_error(&error);
1253 g_variant_unref(ret);
1256 g_slist_free_full(scanner->filter_list, g_free);
1257 scanner->filter_list = NULL;
1259 return BLUETOOTH_ERROR_NONE;
1262 int _bt_start_le_scan(const char *sender)
1265 GError *error = NULL;
1267 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1269 if (scanner == NULL) {
1270 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1271 retv_if(scanner == NULL, BLUETOOTH_ERROR_INTERNAL);
1273 scanner->sender = strdup(sender);
1274 scanner_list = g_slist_append(scanner_list, scanner);
1277 if (scanner->is_scanning == TRUE) {
1278 BT_ERR("BT is already in LE scanning");
1279 return BLUETOOTH_ERROR_IN_PROGRESS;
1281 scanner->is_scanning = TRUE;
1283 proxy = _bt_get_adapter_proxy();
1284 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1286 if (_bt_is_le_scanning()) {
1287 if (scan_filter_enabled == TRUE) {
1288 if (scanner->filter_list == NULL) {
1289 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1290 g_variant_new("(ib)", 0, FALSE),
1291 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1294 BT_ERR("scan_filter_clear Fail: %s", error->message);
1295 g_clear_error(&error);
1299 g_variant_unref(ret);
1300 BT_INFO("Disable LE Scan Filter");
1301 scan_filter_enabled = FALSE;
1303 BT_INFO("LE Filter Scan is continue");
1306 BT_INFO("LE Full Scan is already on progress");
1308 return BLUETOOTH_ERROR_NONE;
1310 if (is_le_set_scan_parameter == FALSE) {
1311 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1312 bluetooth_le_scan_params_t scan_params;
1313 scan_params.type = BT_LE_ACTIVE_SCAN;
1314 scan_params.interval = 5000;
1315 scan_params.window = 500;
1316 _bt_set_scan_parameters(&scan_params);
1319 if (scanner->filter_list == NULL) {
1320 BT_INFO("Start LE Full Scan");
1321 scan_filter_enabled = FALSE;
1323 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1324 g_variant_new("(ib)", 0, TRUE),
1325 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1328 BT_ERR("scan_filter_clear Fail: %s", error->message);
1329 g_clear_error(&error);
1333 g_variant_unref(ret);
1334 BT_INFO("Enable LE Scan Filter");
1335 scan_filter_enabled = TRUE;
1339 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1340 NULL,G_DBUS_CALL_FLAGS_NONE,
1344 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1345 g_clear_error(&error);
1346 return BLUETOOTH_ERROR_INTERNAL;
1350 g_variant_unref(ret);
1351 return BLUETOOTH_ERROR_NONE;
1354 int _bt_stop_le_scan(const char *sender)
1357 GError *error = NULL;
1359 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1361 gboolean next_scanning = FALSE;
1362 gboolean need_scan_filter = TRUE;
1364 if (scanner == NULL || scanner->is_scanning == FALSE)
1365 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1367 scanner->is_scanning = FALSE;
1369 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1371 if (scanner->is_scanning == TRUE) {
1372 next_scanning = TRUE;
1373 if (scanner->filter_list == NULL)
1374 need_scan_filter = FALSE;
1378 proxy = _bt_get_adapter_proxy();
1379 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1381 if (next_scanning == TRUE) {
1382 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1383 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1384 g_variant_new("(ib)", 0, TRUE),
1385 G_DBUS_CALL_FLAGS_NONE,
1389 BT_ERR("scan_filter_clear Fail: %s", error->message);
1390 g_clear_error(&error);
1394 g_variant_unref(ret);
1395 BT_INFO("Enable LE Scan Filter");
1396 scan_filter_enabled = TRUE;
1398 return BLUETOOTH_ERROR_NONE;
1400 if (scan_filter_enabled == TRUE) {
1401 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1402 g_variant_new("(ib)", 0, FALSE),
1403 G_DBUS_CALL_FLAGS_NONE,
1407 BT_ERR("scan_filter_clear Fail: %s", error->message);
1408 g_clear_error(&error);
1412 g_variant_unref(ret);
1413 BT_INFO("Disable LE Scan Filter");
1415 BT_INFO("Just stop LE scan");
1419 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1420 NULL,G_DBUS_CALL_FLAGS_NONE,
1423 BT_ERR("LE Scan stop failed");
1424 return BLUETOOTH_ERROR_INTERNAL;
1427 scan_filter_enabled = FALSE;
1428 is_le_set_scan_parameter = FALSE;
1430 g_variant_unref(ret);
1431 return BLUETOOTH_ERROR_NONE;
1434 void _bt_disable_all_scanner_status(void)
1437 bt_adapter_le_scanner_t *scanner;
1439 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1441 scanner->is_scanning = FALSE;
1445 void _bt_set_le_scan_status(gboolean mode)
1447 is_le_scanning = mode;
1450 gboolean _bt_is_le_scanning(void)
1452 return is_le_scanning;
1455 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1457 le_scan_type = type;
1460 bt_le_scan_type_t _bt_get_le_scan_type(void)
1462 return le_scan_type;
1465 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1466 int adv_data_len, const char *svc_uuid, int uuid_len,
1467 const char *uuid_mask, char ad_type)
1473 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1474 ad_type, &data, &data_len);
1476 _bt_swap_byte_ordering(data, data_len);
1477 for (i = 0; i < data_len; i += uuid_len) {
1478 if (uuid_len > (data_len - i))
1481 if (_bt_byte_arr_cmp_with_mask(data + i,
1482 svc_uuid, uuid_mask, uuid_len) == 0) {
1493 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1494 const char *adv_data, int adv_data_len,
1495 const char *scan_data, int scan_data_len,
1496 const bt_adapter_le_scanner_t *scanner)
1499 bluetooth_le_scan_filter_t *filter_data = NULL;
1502 gboolean is_matched = FALSE;
1504 if (scanner->filter_list == NULL) {
1505 BT_INFO("This scanner is on Full Scan.");
1509 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1510 filter_data = l->data;
1512 if (filter_data->added_features &
1513 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1514 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1516 _bt_convert_addr_type_to_string(address,
1517 filter_data->device_address.addr);
1518 if (strncmp(address, device_address,
1519 BT_ADDRESS_STRING_SIZE) != 0)
1523 if (filter_data->added_features &
1524 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1527 if (__bt_check_scan_result_uuid(adv_data,
1529 (char*)filter_data->service_uuid.data.data,
1530 filter_data->service_uuid.data_len,
1531 (char*)filter_data->service_uuid_mask.data.data,
1532 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1535 if (__bt_check_scan_result_uuid(adv_data,
1537 (char*)filter_data->service_uuid.data.data,
1538 filter_data->service_uuid.data_len,
1539 (char*)filter_data->service_uuid_mask.data.data,
1540 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1543 if (__bt_check_scan_result_uuid(adv_data,
1545 (char*)filter_data->service_uuid.data.data,
1546 filter_data->service_uuid.data_len,
1547 (char*)filter_data->service_uuid_mask.data.data,
1548 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1551 if (__bt_check_scan_result_uuid(adv_data,
1553 (char*)filter_data->service_uuid.data.data,
1554 filter_data->service_uuid.data_len,
1555 (char*)filter_data->service_uuid_mask.data.data,
1556 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1559 if (__bt_check_scan_result_uuid(scan_data,
1561 (char*)filter_data->service_uuid.data.data,
1562 filter_data->service_uuid.data_len,
1563 (char*)filter_data->service_uuid_mask.data.data,
1564 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1567 if (__bt_check_scan_result_uuid(scan_data,
1569 (char*)filter_data->service_uuid.data.data,
1570 filter_data->service_uuid.data_len,
1571 (char*)filter_data->service_uuid_mask.data.data,
1572 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1575 if (__bt_check_scan_result_uuid(scan_data,
1577 (char*)filter_data->service_uuid.data.data,
1578 filter_data->service_uuid.data_len,
1579 (char*)filter_data->service_uuid_mask.data.data,
1580 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1583 if (__bt_check_scan_result_uuid(scan_data,
1585 (char*)filter_data->service_uuid.data.data,
1586 filter_data->service_uuid.data_len,
1587 (char*)filter_data->service_uuid_mask.data.data,
1588 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1592 if (is_matched == FALSE)
1595 if (filter_data->added_features &
1596 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1599 if (__bt_check_scan_result_uuid(adv_data,
1601 (char*)filter_data->service_solicitation_uuid.data.data,
1602 filter_data->service_solicitation_uuid.data_len,
1603 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1604 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1607 if (__bt_check_scan_result_uuid(adv_data,
1609 (char*)filter_data->service_solicitation_uuid.data.data,
1610 filter_data->service_solicitation_uuid.data_len,
1611 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1612 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1615 if (__bt_check_scan_result_uuid(scan_data,
1617 (char*)filter_data->service_solicitation_uuid.data.data,
1618 filter_data->service_solicitation_uuid.data_len,
1619 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1620 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1623 if (__bt_check_scan_result_uuid(scan_data,
1625 (char*)filter_data->service_solicitation_uuid.data.data,
1626 filter_data->service_solicitation_uuid.data_len,
1627 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1628 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1632 if (is_matched == FALSE)
1635 if (filter_data->added_features &
1636 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1637 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1642 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1643 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1646 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1647 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1648 memcpy(name, data, data_len);
1649 name[data_len] = '\0';
1652 if (strncmp(filter_data->device_name,
1653 name, data_len) == 0)
1656 __bt_get_ad_data_by_type((char*)scan_data,
1658 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1661 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1662 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1663 memcpy(name, data, data_len);
1664 name[data_len] = '\0';
1667 if (strncmp(filter_data->device_name,
1668 name, data_len) == 0)
1672 if (is_matched == FALSE)
1675 if (filter_data->added_features &
1676 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1681 __bt_get_ad_data_by_type((char*)adv_data,
1683 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1686 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1687 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1688 if (_bt_byte_arr_cmp_with_mask(data,
1689 (char*)filter_data->manufacturer_data.data.data,
1690 (char*)filter_data->manufacturer_data_mask.data.data,
1697 __bt_get_ad_data_by_type((char*)scan_data,
1699 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1702 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1703 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1704 if (_bt_byte_arr_cmp_with_mask(data,
1705 (char*)filter_data->manufacturer_data.data.data,
1706 (char*)filter_data->manufacturer_data_mask.data.data,
1714 if (is_matched == FALSE)
1717 if (filter_data->added_features &
1718 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1723 __bt_get_ad_data_by_type((char*)adv_data,
1725 BT_LE_AD_TYPE_SERVICE_DATA,
1728 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1729 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1730 if (_bt_byte_arr_cmp_with_mask(data,
1731 (char*)filter_data->service_data.data.data,
1732 (char*)filter_data->service_data_mask.data.data,
1739 __bt_get_ad_data_by_type((char*)scan_data,
1741 BT_LE_AD_TYPE_SERVICE_DATA,
1744 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1745 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1746 if (_bt_byte_arr_cmp_with_mask(data,
1747 (char*)filter_data->service_data.data.data,
1748 (char*)filter_data->service_data_mask.data.data,
1756 if (is_matched == FALSE)
1760 BT_INFO("The scan result is conformable.");
1764 BT_INFO("The scan result is NOT conformable.");
1768 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1769 const bt_le_adv_info_t *adv_info)
1771 int result = BLUETOOTH_ERROR_NONE;
1773 GVariant *scan_data_param, *adv_data_param;
1775 bt_adapter_le_scanner_t *scanner = NULL;
1776 const char *adv_data = NULL;
1777 int adv_data_len = 0;
1778 const char *scan_data = NULL;
1779 int scan_data_len = 0;
1781 ret_if(le_dev_info == NULL);
1782 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1783 ret_if(adv_info == NULL);
1785 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1786 adv_data = le_dev_info->adv_data;
1787 adv_data_len = le_dev_info->adv_data_len;
1788 scan_data = le_dev_info->adv_data;
1791 adv_data = adv_info->data;
1792 adv_data_len = adv_info->data_len;
1793 scan_data = le_dev_info->adv_data;
1794 scan_data_len = le_dev_info->adv_data_len;
1797 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1799 if (scanner->is_scanning == FALSE)
1802 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1803 adv_data, adv_data_len, scan_data, scan_data_len,
1807 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1808 adv_data, adv_data_len, TRUE, NULL, NULL);
1809 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1810 scan_data, scan_data_len, TRUE, NULL, NULL);
1812 param = g_variant_new("(isnnn@ayn@ay)",
1814 le_dev_info->address,
1815 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);
1826 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1831 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1834 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1835 GError *error = NULL;
1838 if (__bt_is_factory_test_mode()) {
1839 BT_ERR("Unable to add white list in factory binary !!");
1840 return BLUETOOTH_ERROR_NOT_SUPPORT;
1843 BT_CHECK_PARAMETER(device_address, return);
1845 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1846 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1847 return BLUETOOTH_ERROR_INVALID_PARAM;
1849 _bt_convert_addr_type_to_string(address, device_address->addr);
1851 proxy = _bt_get_adapter_proxy();
1852 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1854 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1855 g_variant_new("(su)", address, address_type),
1856 G_DBUS_CALL_FLAGS_NONE, -1,
1860 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
1861 g_clear_error(&error);
1862 return BLUETOOTH_ERROR_INTERNAL;
1866 g_variant_unref(ret);
1867 BT_INFO("Add white list");
1869 return BLUETOOTH_ERROR_NONE;
1872 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1875 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1876 GError *error = NULL;
1879 if (__bt_is_factory_test_mode()) {
1880 BT_ERR("Unable to remove white list in factory binary !!");
1881 return BLUETOOTH_ERROR_NOT_SUPPORT;
1884 BT_CHECK_PARAMETER(device_address, return);
1886 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1887 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1888 return BLUETOOTH_ERROR_INVALID_PARAM;
1890 _bt_convert_addr_type_to_string(address, device_address->addr);
1892 proxy = _bt_get_adapter_proxy();
1893 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1895 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1896 g_variant_new("(su)", address, address_type),
1897 G_DBUS_CALL_FLAGS_NONE, -1,
1901 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
1902 g_clear_error(&error);
1903 return BLUETOOTH_ERROR_INTERNAL;
1907 g_variant_unref(ret);
1908 BT_INFO("Remove white list");
1910 return BLUETOOTH_ERROR_NONE;
1913 int _bt_clear_white_list(void)
1916 GError *error = NULL;
1919 if (__bt_is_factory_test_mode()) {
1920 BT_ERR("Unable to clear white list in factory binary !!");
1921 return BLUETOOTH_ERROR_NOT_SUPPORT;
1924 proxy = _bt_get_adapter_proxy();
1925 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1927 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
1928 NULL,G_DBUS_CALL_FLAGS_NONE,
1932 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
1933 g_clear_error(&error);
1934 return BLUETOOTH_ERROR_INTERNAL;
1937 g_variant_unref(ret);
1939 BT_INFO("Clear white list");
1941 return BLUETOOTH_ERROR_NONE;
1944 int _bt_initialize_ipsp(void)
1948 GError *error = NULL;
1951 if (_bt_adapter_get_status() != BT_ACTIVATED &&
1952 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
1953 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1956 proxy = _bt_get_adapter_proxy();
1957 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1959 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
1960 NULL,G_DBUS_CALL_FLAGS_NONE,
1963 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
1964 g_clear_error(&error);
1965 return BLUETOOTH_ERROR_INTERNAL;
1968 g_variant_unref(ret);
1970 BT_INFO("IPSP initialization called successfully");
1972 return BLUETOOTH_ERROR_NONE;
1975 int _bt_deinitialize_ipsp(void)
1979 GError *error = NULL;
1982 if (_bt_adapter_get_status() != BT_ACTIVATED &&
1983 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
1984 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1987 proxy = _bt_get_adapter_proxy();
1988 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1990 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
1991 NULL,G_DBUS_CALL_FLAGS_NONE,
1994 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
1995 g_clear_error(&error);
1996 return BLUETOOTH_ERROR_INTERNAL;
1999 g_variant_unref(ret);
2001 BT_INFO("IPSP De-initialization called successfully");
2003 return BLUETOOTH_ERROR_NONE;
2006 int _bt_le_read_maximum_data_length(
2007 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2009 GError *error = NULL;
2011 GVariant *reply = NULL;
2012 guint16 max_tx_octets, max_tx_time;
2013 guint16 max_rx_octets, max_rx_time;
2015 proxy = _bt_get_adapter_proxy();
2016 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2018 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2019 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2021 g_object_unref(proxy);
2023 if (reply == NULL) {
2024 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2025 if (error != NULL) {
2026 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2027 error->code, error->message);
2028 g_clear_error(&error);
2030 return BLUETOOTH_ERROR_INTERNAL;
2033 g_variant_get(reply ,"(qqqq)", &max_tx_octets, &max_tx_time,
2034 &max_rx_octets, &max_rx_time);
2036 max_le_datalength->max_tx_octets = max_tx_octets;
2037 max_le_datalength->max_tx_time = max_tx_time;
2038 max_le_datalength->max_rx_octets = max_rx_octets;
2039 max_le_datalength->max_rx_time = max_rx_time;
2041 g_variant_unref(reply);
2043 return BLUETOOTH_ERROR_NONE;
2045 int _bt_le_write_host_suggested_default_data_length(
2046 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2048 GError *error = NULL;
2050 GVariant *reply = NULL;
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 guint16 def_tx_octets, def_tx_time;
2088 proxy = _bt_get_adapter_proxy();
2089 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2091 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2092 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2094 if (reply == NULL) {
2095 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2096 if (error != NULL) {
2097 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2098 error->code, error->message);
2099 g_clear_error(&error);
2101 return BLUETOOTH_ERROR_INTERNAL;
2104 g_variant_get(reply ,"(qq)", &def_tx_octets, &def_tx_time);
2106 def_data_length->def_tx_octets = def_tx_octets;
2107 def_data_length->def_tx_time = def_tx_time;
2109 g_variant_unref(reply);
2111 return BLUETOOTH_ERROR_NONE;
2114 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2115 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2117 GError *error = NULL;
2118 guint16 txOctets = max_tx_Octets;
2119 guint16 txTime = max_tx_Time;
2120 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2121 gchar *device_path = NULL;
2122 GDBusConnection *conn;
2123 GDBusProxy *device_proxy;
2125 _bt_convert_addr_type_to_string(address, device_address->addr);
2127 device_path = _bt_get_device_object_path(address);
2129 if (device_path == NULL) {
2130 BT_DBG("Device path is null");
2131 return BLUETOOTH_ERROR_INTERNAL;
2134 conn = _bt_get_system_gconn();
2136 BT_ERR("conn == NULL");
2137 g_free(device_path);
2138 return BLUETOOTH_ERROR_INTERNAL;
2141 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2142 NULL, BT_BLUEZ_NAME,
2143 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2145 g_free(device_path);
2146 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2148 g_dbus_proxy_call_sync(device_proxy,
2150 g_variant_new("(qq)", txOctets, txTime),
2151 G_DBUS_CALL_FLAGS_NONE,
2156 g_object_unref(device_proxy);
2159 BT_ERR("LESetDataLength error: [%s]", error->message);
2160 g_error_free(error);
2161 return BLUETOOTH_ERROR_INTERNAL;
2164 return BLUETOOTH_ERROR_NONE;