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)
156 g_slist_foreach(gatt_client_senders, __bt_send_foreach_event,
160 void __bt_free_le_adv_slot(void)
164 if (le_adv_slot == NULL)
167 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
168 if (le_adv_slot[i].sender)
169 g_free(le_adv_slot[i].sender);
175 int _bt_service_adapter_le_init(void)
177 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
179 return BLUETOOTH_ERROR_NONE;
182 void _bt_service_adapter_le_deinit(void)
184 __bt_free_le_adv_slot();
187 gboolean _bt_update_le_feature_support(const char *item, const char *value)
189 if (item== NULL || value == NULL)
192 if (g_strcmp0(item, "adv_inst_max") == 0) {
193 if (atoi(value) != le_feature_info.adv_inst_max) {
194 __bt_free_le_adv_slot();
195 le_feature_info.adv_inst_max = atoi(value);
196 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
198 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
199 le_feature_info.rpa_offloading = atoi(value);
200 } else if (g_strcmp0(item, "max_filter") == 0) {
201 le_feature_info.max_filter = atoi(value);
203 BT_DBG("No registered item");
210 static gboolean __bt_is_factory_test_mode(void)
213 #ifdef ENABLE_TIZEN_2_4
214 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
215 BT_ERR("Get the DUT Mode fail");
220 BT_INFO("DUT Test Mode !!");
227 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
231 if (le_adv_slot == NULL)
234 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
235 if (le_adv_slot[i].sender == NULL)
237 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
241 if (le_feature_info.adv_inst_max <= 2)
243 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
248 for (; i < le_feature_info.adv_inst_max; i++) {
249 if (le_adv_slot[i].sender == NULL)
256 void _bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
258 if (le_adv_slot[slot_id].sender == NULL) {
259 le_adv_slot[slot_id].sender = strdup(sender);
260 le_adv_slot[slot_id].adv_handle = adv_handle;
264 void _bt_unregister_adv_slot_owner(int slot_id)
266 g_free(le_adv_slot[slot_id].sender);
267 le_adv_slot[slot_id].sender = NULL;
268 le_adv_slot[slot_id].adv_handle = 0;
271 const char* _bt_get_adv_slot_owner(int slot_id)
273 if (le_adv_slot == NULL)
276 return le_adv_slot[slot_id].sender;
279 int _bt_get_adv_slot_adv_handle(int slot_id)
281 if (le_adv_slot == NULL)
284 return le_adv_slot[slot_id].adv_handle;
287 void _bt_set_advertising_status(int slot_id, gboolean mode)
289 le_adv_slot[slot_id].is_advertising = mode;
292 gboolean _bt_is_advertising(void)
294 gboolean status = FALSE;
297 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
298 if (le_adv_slot[i].is_advertising == TRUE)
305 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
309 if (le_adv_slot == NULL)
312 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
313 if (le_adv_slot[i].sender != NULL) {
314 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
315 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
316 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
322 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
327 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
332 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
335 GError *error = NULL;
339 if (__bt_is_factory_test_mode()) {
340 BT_ERR("Unable to start advertising in factory binary !!");
341 return BLUETOOTH_ERROR_NOT_SUPPORT;
344 if (_bt_adapter_get_status() != BT_ACTIVATED &&
345 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
346 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
349 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
351 BT_ERR("There is NO available slot!!");
352 return BLUETOOTH_ERROR_NO_RESOURCES;
355 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
356 return BLUETOOTH_ERROR_IN_PROGRESS;
358 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
359 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
361 proxy = _bt_get_adapter_proxy();
362 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
364 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
365 g_variant_new("(bi)", enable, slot_id),
366 G_DBUS_CALL_FLAGS_NONE,
372 BT_ERR("SetAdvertising Fail: %s", error->message);
373 g_clear_error(&error);
374 return BLUETOOTH_ERROR_INTERNAL;
378 _bt_register_adv_slot_owner(sender, adv_handle, slot_id);
380 le_adv_slot[slot_id].is_advertising = enable;
381 BT_INFO("Set advertising [%d]", enable);
384 g_variant_unref(ret);
386 return BLUETOOTH_ERROR_NONE;
389 int _bt_set_custom_advertising(const char *sender, int adv_handle,
390 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
394 GError *error = NULL;
399 BT_CHECK_PARAMETER(params, return);
401 if (__bt_is_factory_test_mode()) {
402 BT_ERR("Unable to start advertising in factory binary !!");
403 return BLUETOOTH_ERROR_NOT_SUPPORT;
406 if (_bt_adapter_get_status() != BT_ACTIVATED &&
407 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
408 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
411 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
413 BT_ERR("There is NO available slot!!");
414 return BLUETOOTH_ERROR_NO_RESOURCES;
417 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
418 return BLUETOOTH_ERROR_IN_PROGRESS;
420 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
421 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
423 proxy = _bt_get_adapter_proxy();
424 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
426 if (params->interval_min > params->interval_max ||
427 params->interval_min < BT_ADV_INTERVAL_MIN ||
428 params->interval_max > BT_ADV_INTERVAL_MAX)
429 return BLUETOOTH_ERROR_INVALID_PARAM;
431 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
432 return BLUETOOTH_ERROR_INVALID_PARAM;
434 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
435 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
436 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
437 return BLUETOOTH_ERROR_NOT_SUPPORT;
439 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
440 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
442 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
443 g_variant_new("(uuuui)", min, max,
444 params->filter_policy, params->type,
445 slot_id), G_DBUS_CALL_FLAGS_NONE,
449 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
450 g_clear_error(&error);
451 return BLUETOOTH_ERROR_INTERNAL;
454 adv_params.interval_min = params->interval_min;
455 adv_params.interval_max = params->interval_max;
456 adv_params.filter_policy = params->filter_policy;
457 adv_params.type= params->type;
460 g_variant_unref(ret);
462 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
463 g_variant_new("(bi)", enable, slot_id),
464 G_DBUS_CALL_FLAGS_NONE,
470 BT_ERR("SetAdvertising Fail: %s", error->message);
471 g_clear_error(&error);
472 return BLUETOOTH_ERROR_INTERNAL;
476 _bt_register_adv_slot_owner(sender, adv_handle, slot_id);
478 _bt_unregister_adv_slot_owner(slot_id);
480 le_adv_slot[slot_id].is_advertising = enable;
481 BT_INFO_C("Set advertising [%d]", enable);
483 g_variant_unref(ret);
485 return BLUETOOTH_ERROR_NONE;
488 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
489 char in_type, char **data, int *data_len)
491 if (in_data == NULL || data == NULL || data_len == NULL)
492 return BLUETOOTH_ERROR_INTERNAL;
495 return BLUETOOTH_ERROR_INTERNAL;
501 for (i = 0; i < in_len; i++) {
503 if (len <= 0 || i + 1 >= in_len) {
504 BT_ERR("Invalid advertising data");
505 return BLUETOOTH_ERROR_INTERNAL;
508 type = in_data[i + 1];
509 if (type == in_type) {
519 if (i + len > in_len) {
520 BT_ERR("Invalid advertising data");
521 return BLUETOOTH_ERROR_INTERNAL;
522 } else if (len == 0) {
523 BT_DBG("AD Type 0x%02x data is not set", in_type);
526 return BLUETOOTH_ERROR_NONE;
529 *data = g_memdup(&in_data[i], len);
531 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
534 return BLUETOOTH_ERROR_NONE;
537 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
539 BT_CHECK_PARAMETER(adv, return);
540 BT_CHECK_PARAMETER(length, return);
542 memcpy(adv, &adv_data, sizeof(adv_data));
543 *length = adv_data_len;
545 return BLUETOOTH_ERROR_NONE;
548 int _bt_set_advertising_data(const char *sender, int adv_handle,
549 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
552 GError *error = NULL;
553 GVariant *ret, *ad_data, *param = NULL;
554 GVariant *temp = NULL;
555 GVariantBuilder *builder;
557 char *old_mdata = NULL;
558 char *new_mdata = NULL;
563 if (__bt_is_factory_test_mode()) {
564 BT_ERR("Unable to set advertising data in factory binary !!");
565 return BLUETOOTH_ERROR_NOT_SUPPORT;
568 BT_CHECK_PARAMETER(adv, return);
570 if (_bt_adapter_get_status() != BT_ACTIVATED &&
571 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
572 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
575 proxy = _bt_get_adapter_proxy();
576 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
578 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
580 BT_ERR("There is NO available slot!!");
581 return BLUETOOTH_ERROR_NO_RESOURCES;
584 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
585 for (i = 0; i < length; i++) {
586 g_variant_builder_add(builder, "y", adv->data[i]);
589 temp = g_variant_new("ay", builder);
590 g_variant_builder_unref(builder);
591 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
592 g_variant_new("(@ayi)", temp, slot_id),
593 G_DBUS_CALL_FLAGS_NONE,
597 BT_ERR("SetAdvertisingData Fail: %s", error->message);
598 g_clear_error(&error);
599 return BLUETOOTH_ERROR_INTERNAL;
602 _bt_register_adv_slot_owner(sender, adv_handle, slot_id);
604 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
605 &old_mdata, &old_len);
606 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
607 &new_mdata, &new_len);
608 if (old_len != new_len ||
609 (old_mdata && new_mdata &&
610 memcmp(old_mdata, new_mdata, new_len))) {
611 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
612 new_mdata, new_len, TRUE, NULL, NULL);
613 param = g_variant_new("(@ay)", ad_data);
614 _bt_send_event(BT_ADAPTER_EVENT,
615 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
621 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
622 memcpy(&adv_data, adv, length);
623 adv_data_len = length;
625 BT_INFO("Set advertising data");
627 g_variant_unref(ret);
629 return BLUETOOTH_ERROR_NONE;
632 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
634 BT_CHECK_PARAMETER(response, return);
635 BT_CHECK_PARAMETER(length, return);
637 memcpy(response, &resp_data, sizeof(resp_data));
638 *length = resp_data_len;
640 return BLUETOOTH_ERROR_NONE;
643 int _bt_set_scan_response_data(const char *sender, int adv_handle,
644 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
647 GError *error = NULL;
648 GVariant *ret, *scan_data, *param = NULL;
649 GVariant *temp = NULL;
650 GVariantBuilder *builder;
652 char *old_mdata = NULL;
653 char *new_mdata = NULL;
658 if (__bt_is_factory_test_mode()) {
659 BT_ERR("Unable to set scan response list in factory binary !!");
660 return BLUETOOTH_ERROR_NOT_SUPPORT;
663 BT_CHECK_PARAMETER(response, return);
665 if (_bt_adapter_get_status() != BT_ACTIVATED &&
666 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
667 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
670 proxy = _bt_get_adapter_proxy();
671 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
673 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
675 BT_ERR("There is NO available slot!!");
676 return BLUETOOTH_ERROR_NO_RESOURCES;
678 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
679 for (i = 0; i < length; i++) {
680 g_variant_builder_add(builder, "y", response->data[i]);
683 temp = g_variant_new("ay", builder);
684 g_variant_builder_unref(builder);
685 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
686 g_variant_new("(@ayi)", temp, slot_id),
687 G_DBUS_CALL_FLAGS_NONE,
691 BT_ERR("SetScanRespData Fail: %s", error->message);
692 g_clear_error(&error);
693 return BLUETOOTH_ERROR_INTERNAL;
696 _bt_register_adv_slot_owner(sender, adv_handle, slot_id);
698 /* Compare with previous scan resp data */
699 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
700 &old_mdata, &old_len);
701 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
702 &new_mdata, &new_len);
703 if (old_len != new_len ||
704 (old_mdata && new_mdata &&
705 memcmp(old_mdata, new_mdata, new_len))) {
706 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
707 new_mdata, new_len, TRUE, NULL, NULL);
708 param = g_variant_new("(@ay)", scan_data);
709 _bt_send_event(BT_ADAPTER_EVENT,
710 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
716 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
717 memcpy(&resp_data, response, length);
718 resp_data_len = length;
721 g_variant_unref(ret);
722 BT_INFO("Set scan response data");
723 return BLUETOOTH_ERROR_NONE;
726 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
729 GError *error = NULL;
734 BT_CHECK_PARAMETER(params, return);
736 if (_bt_adapter_get_status() != BT_ACTIVATED &&
737 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
738 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
741 proxy = _bt_get_adapter_proxy();
742 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
744 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
745 return BLUETOOTH_ERROR_INVALID_PARAM;
747 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
748 return BLUETOOTH_ERROR_INVALID_PARAM;
750 if (params->window > params->interval)
751 return BLUETOOTH_ERROR_INVALID_PARAM;
753 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
754 win = params->window / BT_ADV_INTERVAL_SPLIT;
756 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
757 g_variant_new("(uuu)", params->type, itv, win),
758 G_DBUS_CALL_FLAGS_NONE, -1,
762 BT_ERR("SetScanParameters Fail: %s", error->message);
763 g_clear_error(&error);
764 return BLUETOOTH_ERROR_INTERNAL;
767 _bt_set_le_scan_type(params->type);
769 is_le_set_scan_parameter = TRUE;
772 g_variant_unref(ret);
773 BT_INFO("Set scan parameters");
774 return BLUETOOTH_ERROR_NONE;
777 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
780 bt_adapter_le_scanner_t *scanner;
782 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
784 if (g_strcmp0(scanner->sender, sender) == 0)
791 int __bt_get_available_scan_filter_slot_id(void)
794 bt_adapter_le_scanner_t *scanner;
796 bluetooth_le_scan_filter_t *filter_data;
797 gboolean *slot_check_list = NULL;
800 if (le_feature_info.max_filter == 0) {
801 BT_ERR("Scan filter is NOT Supported");
804 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
805 if (slot_check_list == NULL) {
806 BT_ERR("Fail to allocate memory");
810 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
812 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
813 filter_data = fl->data;
814 if (filter_data->slot_id < le_feature_info.max_filter) {
815 slot_check_list[filter_data->slot_id] = TRUE;
820 for (i = 0; i < le_feature_info.max_filter; i++) {
821 if (slot_check_list[i] == FALSE) {
822 g_free(slot_check_list);
827 BT_ERR("There is NO available slot for scan filter.");
828 g_free(slot_check_list);
832 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
835 GError *error = NULL;
836 GVariant *ret, *param;
837 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
838 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
839 GArray *arr_uuid = NULL;
840 GArray *arr_uuid_mask = NULL;
841 GArray *arr_data = NULL;
842 GArray *arr_data_mask = NULL;
843 bt_adapter_le_scanner_t *scanner = NULL;
844 bluetooth_le_scan_filter_t *filter_data = NULL;
845 int feature_selection = 0;
847 *slot_id = __bt_get_available_scan_filter_slot_id();
849 return BLUETOOTH_ERROR_NO_RESOURCES;
851 proxy = _bt_get_adapter_proxy();
852 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
854 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
855 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
856 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
858 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
860 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
861 NULL, 0, TRUE, NULL, NULL);
862 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
863 NULL, 0, TRUE, NULL, NULL);
864 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
865 NULL, 0, TRUE, NULL, NULL);
866 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
867 NULL, 0, TRUE, NULL, NULL);
869 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
871 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
872 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
873 *slot_id, // filter_index
875 0, // company_id_mask
876 arr_uuid_param, // p_uuid
877 arr_uuid_mask_param, // p_uuid_mask
880 arr_data_param, // p_data
881 arr_data_mask_param); // p_mask
883 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
884 param, G_DBUS_CALL_FLAGS_NONE,
888 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
889 g_clear_error(&error);
892 g_variant_unref(ret);
895 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
896 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
898 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
899 NULL, 0, TRUE, NULL, NULL);
900 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
901 NULL, 0, TRUE, NULL, NULL);
902 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
903 NULL, 0, TRUE, NULL, NULL);
904 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
905 NULL, 0, TRUE, NULL, NULL);
907 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
909 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
910 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
911 *slot_id, // filter_index
913 0, // company_id_mask
914 arr_uuid_param, // p_uuid
915 arr_uuid_mask_param, // p_uuid_mask
916 filter->device_name, // string
918 arr_data_param, // p_data
919 arr_data_mask_param);
921 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
922 param, G_DBUS_CALL_FLAGS_NONE,
926 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
927 g_clear_error(&error);
930 g_variant_unref(ret);
933 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
934 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
936 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
937 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
939 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
940 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
942 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
943 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
944 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
945 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
946 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
947 NULL, 0, TRUE, NULL, NULL);
948 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
949 NULL, 0, TRUE, NULL, NULL);
951 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
953 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
954 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
955 *slot_id, // filter_index
957 0, // company_id_mask
958 arr_uuid_param, // p_uuid
959 arr_uuid_mask_param, // p_uuid_mask
962 arr_data_param, // p_data
963 arr_data_mask_param);
965 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
966 param, G_DBUS_CALL_FLAGS_NONE,
970 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
971 g_clear_error(&error);
974 g_variant_unref(ret);
976 g_array_free(arr_uuid, TRUE);
977 g_array_free(arr_uuid_mask, TRUE);
978 g_array_free(arr_data, TRUE);
979 g_array_free(arr_data_mask, TRUE);
982 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
983 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
985 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
986 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
988 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
989 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
991 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
992 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
993 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
994 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
995 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
996 NULL, 0, TRUE, NULL, NULL);
997 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
998 NULL, 0, TRUE, NULL, NULL);
1000 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1002 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1003 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1004 *slot_id, // filter_index
1006 0, // company_id_mask
1007 arr_uuid_param, // p_uuid
1008 arr_uuid_mask_param, // p_uuid_mask
1011 arr_data_param, // p_data
1012 arr_data_mask_param);
1014 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1015 G_DBUS_CALL_FLAGS_NONE,
1019 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1020 g_clear_error(&error);
1023 g_variant_unref(ret);
1025 g_array_free(arr_uuid, TRUE);
1026 g_array_free(arr_uuid_mask, TRUE);
1029 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1030 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1032 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1033 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1035 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1036 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1038 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1039 NULL, 0, TRUE, NULL, NULL);
1040 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1041 NULL, 0, TRUE, NULL, NULL);
1042 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1043 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1044 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1045 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1047 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1049 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1050 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1051 *slot_id, // filter_index
1053 0, // company_id_mask
1054 arr_uuid_param, // p_uuid
1055 arr_uuid_mask_param, // p_uuid_mask
1058 arr_data_param, // p_data
1059 arr_data_mask_param);
1061 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1062 G_DBUS_CALL_FLAGS_NONE,
1066 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1067 g_clear_error(&error);
1070 g_variant_unref(ret);
1072 g_array_free(arr_data, TRUE);
1073 g_array_free(arr_data_mask, TRUE);
1076 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1077 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1079 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1080 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1082 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1083 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1085 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1086 NULL, 0, TRUE, NULL, NULL);
1087 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1088 NULL, 0, TRUE, NULL, NULL);
1089 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1090 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1091 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1092 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1094 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1096 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1097 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1098 *slot_id, // filter_index
1099 filter->manufacturer_id, // company_id
1100 0xFFFF, // company_id_mask
1101 arr_uuid_param, // p_uuid
1102 arr_uuid_mask_param, // p_uuid_mask
1105 arr_data_param, // p_data
1106 arr_data_mask_param);
1108 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1109 G_DBUS_CALL_FLAGS_NONE,
1113 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1114 g_clear_error(&error);
1117 g_variant_unref(ret);
1119 g_array_free(arr_data, TRUE);
1120 g_array_free(arr_data_mask, TRUE);
1123 BT_DBG("Filter selection %.2x", feature_selection);
1125 param = g_variant_new("(iiiiiiiiiiii)",
1127 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1128 *slot_id, // filter_index
1129 feature_selection, // feat_seln
1130 0, // list_logic_type (OR - 0x00, AND - 0x01)
1131 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1132 -127, // rssi_high_thres
1133 -127, // rssi_low_thres
1134 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1137 0); // found_timeout_cnt
1138 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1139 param, G_DBUS_CALL_FLAGS_NONE,
1143 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1144 g_clear_error(&error);
1147 scanner = __bt_find_scanner_from_list(sender);
1148 if (scanner == NULL) {
1149 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1151 scanner->sender = strdup(sender);
1152 scanner_list = g_slist_append(scanner_list, scanner);
1156 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1158 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1159 filter_data->slot_id = *slot_id;
1162 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1166 g_variant_unref(ret);
1167 return BLUETOOTH_ERROR_NONE;
1170 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1173 GError *error = NULL;
1175 bt_adapter_le_scanner_t *scanner = NULL;
1176 bluetooth_le_scan_filter_t *filter_data = NULL;
1178 gboolean is_slot_id_found = FALSE;
1180 scanner = __bt_find_scanner_from_list(sender);
1181 if (scanner == NULL) {
1182 BT_ERR("There is NO available scanner.");
1183 return BLUETOOTH_ERROR_NOT_FOUND;
1186 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1187 filter_data = l->data;
1188 if (filter_data->slot_id == slot_id) {
1189 is_slot_id_found = TRUE;
1193 if (is_slot_id_found == FALSE) {
1194 BT_ERR("There is NO registered slot.");
1195 return BLUETOOTH_ERROR_NOT_FOUND;
1198 proxy = _bt_get_adapter_proxy();
1199 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1201 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1202 g_variant_new("(ii)", 0, slot_id),
1203 G_DBUS_CALL_FLAGS_NONE,
1207 BT_ERR("scan_filter_clear Fail: %s", error->message);
1208 g_clear_error(&error);
1211 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1212 g_free(filter_data);
1215 g_variant_unref(ret);
1216 return BLUETOOTH_ERROR_NONE;
1219 int _bt_unregister_all_scan_filters(const char *sender)
1222 GError *error = NULL;
1224 bt_adapter_le_scanner_t *scanner = NULL;
1225 bluetooth_le_scan_filter_t *filter_data = NULL;
1228 scanner = __bt_find_scanner_from_list(sender);
1229 if (scanner == NULL) {
1230 BT_ERR("There is NO available scanner.");
1231 return BLUETOOTH_ERROR_NOT_FOUND;
1234 proxy = _bt_get_adapter_proxy();
1235 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1237 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1238 filter_data = l->data;
1240 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1241 g_variant_new("(ii)", 0, filter_data->slot_id),
1242 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1245 BT_ERR("scan_filter_clear Fail: %s", error->message);
1246 g_clear_error(&error);
1249 g_variant_unref(ret);
1252 g_slist_free_full(scanner->filter_list, g_free);
1253 scanner->filter_list = NULL;
1255 return BLUETOOTH_ERROR_NONE;
1258 int _bt_start_le_scan(const char *sender)
1261 GError *error = NULL;
1263 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1265 if (scanner == NULL) {
1266 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1267 retv_if(scanner == NULL, BLUETOOTH_ERROR_INTERNAL);
1269 scanner->sender = strdup(sender);
1270 scanner_list = g_slist_append(scanner_list, scanner);
1273 if (scanner->is_scanning == TRUE) {
1274 BT_ERR("BT is already in LE scanning");
1275 return BLUETOOTH_ERROR_IN_PROGRESS;
1277 scanner->is_scanning = TRUE;
1279 proxy = _bt_get_adapter_proxy();
1280 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1282 if (_bt_is_le_scanning()) {
1283 if (scan_filter_enabled == TRUE) {
1284 if (scanner->filter_list == NULL) {
1285 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1286 g_variant_new("(ib)", 0, FALSE),
1287 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1290 BT_ERR("scan_filter_clear Fail: %s", error->message);
1291 g_clear_error(&error);
1295 g_variant_unref(ret);
1296 BT_INFO("Disable LE Scan Filter");
1297 scan_filter_enabled = FALSE;
1299 BT_INFO("LE Filter Scan is continue");
1302 BT_INFO("LE Full Scan is already on progress");
1304 return BLUETOOTH_ERROR_NONE;
1306 if (is_le_set_scan_parameter == FALSE) {
1307 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1308 bluetooth_le_scan_params_t scan_params;
1309 scan_params.type = BT_LE_ACTIVE_SCAN;
1310 scan_params.interval = 5000;
1311 scan_params.window = 500;
1312 _bt_set_scan_parameters(&scan_params);
1315 if (scanner->filter_list == NULL) {
1316 BT_INFO("Start LE Full Scan");
1317 scan_filter_enabled = FALSE;
1319 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1320 g_variant_new("(ib)", 0, TRUE),
1321 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1324 BT_ERR("scan_filter_clear Fail: %s", error->message);
1325 g_clear_error(&error);
1329 g_variant_unref(ret);
1330 BT_INFO("Enable LE Scan Filter");
1331 scan_filter_enabled = TRUE;
1335 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1336 NULL,G_DBUS_CALL_FLAGS_NONE,
1340 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1341 g_clear_error(&error);
1342 return BLUETOOTH_ERROR_INTERNAL;
1346 g_variant_unref(ret);
1347 return BLUETOOTH_ERROR_NONE;
1350 int _bt_stop_le_scan(const char *sender)
1353 GError *error = NULL;
1355 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1357 gboolean next_scanning = FALSE;
1358 gboolean need_scan_filter = TRUE;
1360 if (scanner == NULL || scanner->is_scanning == FALSE)
1361 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1363 scanner->is_scanning = FALSE;
1365 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1367 if (scanner->is_scanning == TRUE) {
1368 next_scanning = TRUE;
1369 if (scanner->filter_list == NULL)
1370 need_scan_filter = FALSE;
1374 proxy = _bt_get_adapter_proxy();
1375 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1377 if (next_scanning == TRUE) {
1378 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1379 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1380 g_variant_new("(ib)", 0, TRUE),
1381 G_DBUS_CALL_FLAGS_NONE,
1385 BT_ERR("scan_filter_clear Fail: %s", error->message);
1386 g_clear_error(&error);
1390 g_variant_unref(ret);
1391 BT_INFO("Enable LE Scan Filter");
1392 scan_filter_enabled = TRUE;
1394 return BLUETOOTH_ERROR_NONE;
1396 if (scan_filter_enabled == TRUE) {
1397 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1398 g_variant_new("(ib)", 0, FALSE),
1399 G_DBUS_CALL_FLAGS_NONE,
1403 BT_ERR("scan_filter_clear Fail: %s", error->message);
1404 g_clear_error(&error);
1408 g_variant_unref(ret);
1409 BT_INFO("Disable LE Scan Filter");
1411 BT_INFO("Just stop LE scan");
1415 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1416 NULL,G_DBUS_CALL_FLAGS_NONE,
1419 BT_ERR("LE Scan stop failed");
1420 return BLUETOOTH_ERROR_INTERNAL;
1423 scan_filter_enabled = FALSE;
1424 is_le_set_scan_parameter = FALSE;
1426 g_variant_unref(ret);
1427 return BLUETOOTH_ERROR_NONE;
1430 void _bt_disable_all_scanner_status(void)
1433 bt_adapter_le_scanner_t *scanner;
1435 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1437 scanner->is_scanning = FALSE;
1441 void _bt_set_le_scan_status(gboolean mode)
1443 is_le_scanning = mode;
1446 gboolean _bt_is_le_scanning(void)
1448 return is_le_scanning;
1451 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1453 le_scan_type = type;
1456 bt_le_scan_type_t _bt_get_le_scan_type(void)
1458 return le_scan_type;
1461 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1462 int adv_data_len, const char *svc_uuid, int uuid_len,
1463 const char *uuid_mask, char ad_type)
1469 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1470 ad_type, &data, &data_len);
1472 _bt_swap_byte_ordering(data, data_len);
1473 for (i = 0; i < data_len; i += uuid_len) {
1474 if (uuid_len > (data_len - i))
1477 if (_bt_byte_arr_cmp_with_mask(data + i,
1478 svc_uuid, uuid_mask, uuid_len) == 0) {
1489 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1490 const char *adv_data, int adv_data_len,
1491 const char *scan_data, int scan_data_len,
1492 const bt_adapter_le_scanner_t *scanner)
1495 bluetooth_le_scan_filter_t *filter_data = NULL;
1498 gboolean is_matched = FALSE;
1500 if (scanner->filter_list == NULL) {
1501 BT_INFO("This scanner is on Full Scan.");
1505 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1506 filter_data = l->data;
1508 if (filter_data->added_features &
1509 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1510 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1512 _bt_convert_addr_type_to_string(address,
1513 filter_data->device_address.addr);
1514 if (strncmp(address, device_address,
1515 BT_ADDRESS_STRING_SIZE) != 0)
1519 if (filter_data->added_features &
1520 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1523 if (__bt_check_scan_result_uuid(adv_data,
1525 (char*)filter_data->service_uuid.data.data,
1526 filter_data->service_uuid.data_len,
1527 (char*)filter_data->service_uuid_mask.data.data,
1528 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1531 if (__bt_check_scan_result_uuid(adv_data,
1533 (char*)filter_data->service_uuid.data.data,
1534 filter_data->service_uuid.data_len,
1535 (char*)filter_data->service_uuid_mask.data.data,
1536 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1539 if (__bt_check_scan_result_uuid(adv_data,
1541 (char*)filter_data->service_uuid.data.data,
1542 filter_data->service_uuid.data_len,
1543 (char*)filter_data->service_uuid_mask.data.data,
1544 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1547 if (__bt_check_scan_result_uuid(adv_data,
1549 (char*)filter_data->service_uuid.data.data,
1550 filter_data->service_uuid.data_len,
1551 (char*)filter_data->service_uuid_mask.data.data,
1552 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1555 if (__bt_check_scan_result_uuid(scan_data,
1557 (char*)filter_data->service_uuid.data.data,
1558 filter_data->service_uuid.data_len,
1559 (char*)filter_data->service_uuid_mask.data.data,
1560 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1563 if (__bt_check_scan_result_uuid(scan_data,
1565 (char*)filter_data->service_uuid.data.data,
1566 filter_data->service_uuid.data_len,
1567 (char*)filter_data->service_uuid_mask.data.data,
1568 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1571 if (__bt_check_scan_result_uuid(scan_data,
1573 (char*)filter_data->service_uuid.data.data,
1574 filter_data->service_uuid.data_len,
1575 (char*)filter_data->service_uuid_mask.data.data,
1576 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1579 if (__bt_check_scan_result_uuid(scan_data,
1581 (char*)filter_data->service_uuid.data.data,
1582 filter_data->service_uuid.data_len,
1583 (char*)filter_data->service_uuid_mask.data.data,
1584 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1588 if (is_matched == FALSE)
1591 if (filter_data->added_features &
1592 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1595 if (__bt_check_scan_result_uuid(adv_data,
1597 (char*)filter_data->service_solicitation_uuid.data.data,
1598 filter_data->service_solicitation_uuid.data_len,
1599 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1600 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1603 if (__bt_check_scan_result_uuid(adv_data,
1605 (char*)filter_data->service_solicitation_uuid.data.data,
1606 filter_data->service_solicitation_uuid.data_len,
1607 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1608 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1611 if (__bt_check_scan_result_uuid(scan_data,
1613 (char*)filter_data->service_solicitation_uuid.data.data,
1614 filter_data->service_solicitation_uuid.data_len,
1615 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1616 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1619 if (__bt_check_scan_result_uuid(scan_data,
1621 (char*)filter_data->service_solicitation_uuid.data.data,
1622 filter_data->service_solicitation_uuid.data_len,
1623 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1624 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1628 if (is_matched == FALSE)
1631 if (filter_data->added_features &
1632 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1633 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1638 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1639 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1642 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1643 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1644 memcpy(name, data, data_len);
1645 name[data_len] = '\0';
1648 if (strncmp(filter_data->device_name,
1649 name, data_len) == 0)
1652 __bt_get_ad_data_by_type((char*)scan_data,
1654 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1657 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1658 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1659 memcpy(name, data, data_len);
1660 name[data_len] = '\0';
1663 if (strncmp(filter_data->device_name,
1664 name, data_len) == 0)
1668 if (is_matched == FALSE)
1671 if (filter_data->added_features &
1672 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1677 __bt_get_ad_data_by_type((char*)adv_data,
1679 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1682 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1683 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1684 if (_bt_byte_arr_cmp_with_mask(data,
1685 (char*)filter_data->manufacturer_data.data.data,
1686 (char*)filter_data->manufacturer_data_mask.data.data,
1693 __bt_get_ad_data_by_type((char*)scan_data,
1695 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1698 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1699 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1700 if (_bt_byte_arr_cmp_with_mask(data,
1701 (char*)filter_data->manufacturer_data.data.data,
1702 (char*)filter_data->manufacturer_data_mask.data.data,
1710 if (is_matched == FALSE)
1713 if (filter_data->added_features &
1714 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1719 __bt_get_ad_data_by_type((char*)adv_data,
1721 BT_LE_AD_TYPE_SERVICE_DATA,
1724 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1725 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1726 if (_bt_byte_arr_cmp_with_mask(data,
1727 (char*)filter_data->service_data.data.data,
1728 (char*)filter_data->service_data_mask.data.data,
1735 __bt_get_ad_data_by_type((char*)scan_data,
1737 BT_LE_AD_TYPE_SERVICE_DATA,
1740 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1741 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1742 if (_bt_byte_arr_cmp_with_mask(data,
1743 (char*)filter_data->service_data.data.data,
1744 (char*)filter_data->service_data_mask.data.data,
1752 if (is_matched == FALSE)
1756 BT_INFO("The scan result is conformable.");
1760 BT_INFO("The scan result is NOT conformable.");
1764 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1765 const bt_le_adv_info_t *adv_info)
1767 int result = BLUETOOTH_ERROR_NONE;
1769 GVariant *scan_data_param, *adv_data_param;
1771 bt_adapter_le_scanner_t *scanner = NULL;
1772 const char *adv_data = NULL;
1773 int adv_data_len = 0;
1774 const char *scan_data = NULL;
1775 int scan_data_len = 0;
1777 ret_if(le_dev_info == NULL);
1778 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1779 ret_if(adv_info == NULL);
1781 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1782 adv_data = le_dev_info->adv_data;
1783 adv_data_len = le_dev_info->adv_data_len;
1784 scan_data = le_dev_info->adv_data;
1787 adv_data = adv_info->data;
1788 adv_data_len = adv_info->data_len;
1789 scan_data = le_dev_info->adv_data;
1790 scan_data_len = le_dev_info->adv_data_len;
1793 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1795 if (scanner->is_scanning == FALSE)
1798 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1799 adv_data, adv_data_len, scan_data, scan_data_len,
1803 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1804 adv_data, adv_data_len, TRUE, NULL, NULL);
1805 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1806 scan_data, scan_data_len, TRUE, NULL, NULL);
1808 param = g_variant_new("(isnnn@ayn@ay)",
1810 le_dev_info->address,
1811 le_dev_info->addr_type,
1818 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1819 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1823 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1826 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1827 GError *error = NULL;
1830 if (__bt_is_factory_test_mode()) {
1831 BT_ERR("Unable to add white list in factory binary !!");
1832 return BLUETOOTH_ERROR_NOT_SUPPORT;
1835 BT_CHECK_PARAMETER(device_address, return);
1837 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1838 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1839 return BLUETOOTH_ERROR_INVALID_PARAM;
1841 _bt_convert_addr_type_to_string(address, device_address->addr);
1843 proxy = _bt_get_adapter_proxy();
1844 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1846 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1847 g_variant_new("(su)", address, address_type),
1848 G_DBUS_CALL_FLAGS_NONE, -1,
1852 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
1853 g_clear_error(&error);
1854 return BLUETOOTH_ERROR_INTERNAL;
1858 g_variant_unref(ret);
1859 BT_INFO("Add white list");
1861 return BLUETOOTH_ERROR_NONE;
1864 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1867 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1868 GError *error = NULL;
1871 if (__bt_is_factory_test_mode()) {
1872 BT_ERR("Unable to remove white list in factory binary !!");
1873 return BLUETOOTH_ERROR_NOT_SUPPORT;
1876 BT_CHECK_PARAMETER(device_address, return);
1878 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1879 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1880 return BLUETOOTH_ERROR_INVALID_PARAM;
1882 _bt_convert_addr_type_to_string(address, device_address->addr);
1884 proxy = _bt_get_adapter_proxy();
1885 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1887 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1888 g_variant_new("(su)", address, address_type),
1889 G_DBUS_CALL_FLAGS_NONE, -1,
1893 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
1894 g_clear_error(&error);
1895 return BLUETOOTH_ERROR_INTERNAL;
1899 g_variant_unref(ret);
1900 BT_INFO("Remove white list");
1902 return BLUETOOTH_ERROR_NONE;
1905 int _bt_clear_white_list(void)
1908 GError *error = NULL;
1911 if (__bt_is_factory_test_mode()) {
1912 BT_ERR("Unable to clear white list in factory binary !!");
1913 return BLUETOOTH_ERROR_NOT_SUPPORT;
1916 proxy = _bt_get_adapter_proxy();
1917 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1919 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
1920 NULL,G_DBUS_CALL_FLAGS_NONE,
1924 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
1925 g_clear_error(&error);
1926 return BLUETOOTH_ERROR_INTERNAL;
1929 g_variant_unref(ret);
1931 BT_INFO("Clear white list");
1933 return BLUETOOTH_ERROR_NONE;
1936 int _bt_initialize_ipsp(void)
1940 GError *error = NULL;
1943 if (_bt_adapter_get_status() != BT_ACTIVATED &&
1944 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
1945 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1948 proxy = _bt_get_adapter_proxy();
1949 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1951 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
1952 NULL,G_DBUS_CALL_FLAGS_NONE,
1955 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
1956 g_clear_error(&error);
1957 return BLUETOOTH_ERROR_INTERNAL;
1960 g_variant_unref(ret);
1962 BT_INFO("IPSP initialization called successfully");
1964 return BLUETOOTH_ERROR_NONE;
1967 int _bt_deinitialize_ipsp(void)
1971 GError *error = NULL;
1974 if (_bt_adapter_get_status() != BT_ACTIVATED &&
1975 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
1976 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1979 proxy = _bt_get_adapter_proxy();
1980 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1982 ret = g_dbus_proxy_call_sync(proxy, "DeinitializeIpsp",
1983 NULL,G_DBUS_CALL_FLAGS_NONE,
1986 BT_ERR("De-Initialize IPSP Failed :[%s]", error->message);
1987 g_clear_error(&error);
1988 return BLUETOOTH_ERROR_INTERNAL;
1991 g_variant_unref(ret);
1993 BT_INFO("IPSP De-initialization called successfully");
1995 return BLUETOOTH_ERROR_NONE;
1998 int _bt_le_read_maximum_data_length(
1999 bluetooth_le_read_maximum_data_length_t *max_le_datalength)
2001 GError *error = NULL;
2003 GVariant *reply = NULL;
2004 guint16 max_tx_octets, max_tx_time;
2005 guint16 max_rx_octets, max_rx_time;
2007 proxy = _bt_get_adapter_proxy();
2008 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2010 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2011 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2013 g_object_unref(proxy);
2015 if (reply == NULL) {
2016 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2017 if (error != NULL) {
2018 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2019 error->code, error->message);
2020 g_clear_error(&error);
2022 return BLUETOOTH_ERROR_INTERNAL;
2025 g_variant_get(reply ,"(qqqq)", &max_tx_octets, &max_tx_time,
2026 &max_rx_octets, &max_rx_time);
2028 max_le_datalength->max_tx_octets = max_tx_octets;
2029 max_le_datalength->max_tx_time = max_tx_time;
2030 max_le_datalength->max_rx_octets = max_rx_octets;
2031 max_le_datalength->max_rx_time = max_rx_time;
2033 g_variant_unref(reply);
2035 return BLUETOOTH_ERROR_NONE;
2037 int _bt_le_write_host_suggested_default_data_length(
2038 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2040 GError *error = NULL;
2042 GVariant *reply = NULL;
2044 proxy = _bt_get_adapter_proxy();
2045 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2047 reply = g_dbus_proxy_call_sync(proxy,
2048 "LEWriteHostSuggestedDataLength",
2049 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2050 G_DBUS_CALL_FLAGS_NONE,
2055 g_object_unref(proxy);
2057 if (reply == NULL) {
2058 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2059 if (error != NULL) {
2060 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2061 error->code, error->message);
2062 g_clear_error(&error);
2064 return BLUETOOTH_ERROR_INTERNAL;
2067 g_variant_unref(reply);
2069 return BLUETOOTH_ERROR_NONE;
2072 int _bt_le_read_host_suggested_default_data_length(
2073 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2075 GError *error = NULL;
2077 GVariant *reply = NULL;
2078 guint16 def_tx_octets, def_tx_time;
2080 proxy = _bt_get_adapter_proxy();
2081 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2083 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2084 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2086 if (reply == NULL) {
2087 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2088 if (error != NULL) {
2089 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2090 error->code, error->message);
2091 g_clear_error(&error);
2093 return BLUETOOTH_ERROR_INTERNAL;
2096 g_variant_get(reply ,"(qq)", &def_tx_octets, &def_tx_time);
2098 def_data_length->def_tx_octets = def_tx_octets;
2099 def_data_length->def_tx_time = def_tx_time;
2101 g_variant_unref(reply);
2103 return BLUETOOTH_ERROR_NONE;
2106 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2107 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2109 GError *error = NULL;
2110 guint16 txOctets = max_tx_Octets;
2111 guint16 txTime = max_tx_Time;
2112 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2113 gchar *device_path = NULL;
2114 GDBusConnection *conn;
2115 GDBusProxy *device_proxy;
2117 _bt_convert_addr_type_to_string(address, device_address->addr);
2119 device_path = _bt_get_device_object_path(address);
2121 if (device_path == NULL) {
2122 BT_DBG("Device path is null");
2123 return BLUETOOTH_ERROR_INTERNAL;
2126 conn = _bt_get_system_gconn();
2128 BT_ERR("conn == NULL");
2129 g_free(device_path);
2130 return BLUETOOTH_ERROR_INTERNAL;
2133 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2134 NULL, BT_BLUEZ_NAME,
2135 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2137 g_free(device_path);
2138 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2140 g_dbus_proxy_call_sync(device_proxy,
2142 g_variant_new("(qq)", txOctets, txTime),
2143 G_DBUS_CALL_FLAGS_NONE,
2148 g_object_unref(device_proxy);
2151 BT_ERR("LESetDataLength error: [%s]", error->message);
2152 g_error_free(error);
2153 return BLUETOOTH_ERROR_INTERNAL;
2156 return BLUETOOTH_ERROR_NONE;