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"
37 #define BT_ADV_INTERVAL_MIN 20 /* msec */
38 #define BT_ADV_INTERVAL_MAX 10240
39 #define BT_ADV_INTERVAL_SPLIT 0.625
40 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
41 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
42 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
43 #define BT_ADV_TYPE_DEFAULT 0x00
44 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
50 } bt_adapter_le_feature_info_t;
55 gboolean is_advertising;
56 } bt_adapter_le_adv_slot_t;
62 } bt_adapter_le_scanner_t;
64 static bluetooth_advertising_params_t adv_params = {
65 BT_DEFAULT_ADV_MIN_INTERVAL,
66 BT_DEFAULT_ADV_MAX_INTERVAL,
67 BT_ADV_FILTER_POLICY_DEFAULT,
69 static bluetooth_advertising_data_t adv_data = { {0} };
70 static int adv_data_len;
71 static bluetooth_scan_resp_data_t resp_data = { {0} };
72 static int resp_data_len;
74 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
75 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
77 GSList *scanner_list = NULL;
78 static gboolean is_le_set_scan_parameter = FALSE;
79 static gboolean is_le_scanning = FALSE;
80 static gboolean scan_filter_enabled = FALSE;
81 static bt_le_scan_type_t le_scan_type = BT_LE_PASSIVE_SCAN;
83 static GSList *gatt_client_senders = NULL;
86 gboolean _bt_is_set_scan_parameter(void)
88 return is_le_set_scan_parameter;
91 void _bt_init_gatt_client_senders(void)
93 _bt_clear_request_list();
96 int _bt_insert_gatt_client_sender(char *sender)
100 retv_if(sender == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
102 info = g_strdup(sender);
103 retv_if(info == NULL, BLUETOOTH_ERROR_MEMORY_ALLOCATION);
105 gatt_client_senders = g_slist_append(gatt_client_senders, info);
107 BT_DBG("insert sender: %s", sender);
109 return BLUETOOTH_ERROR_NONE;
112 int _bt_delete_gatt_client_sender(char *sender)
117 BT_DBG("remove sender: %s", sender);
119 for (l = gatt_client_senders; l != NULL; l = g_slist_next(l)) {
124 if (g_strcmp0(info, sender) == 0) {
125 BT_DBG("remove info");
126 gatt_client_senders = g_slist_remove(gatt_client_senders, info);
128 return BLUETOOTH_ERROR_NONE;
132 return BLUETOOTH_ERROR_NOT_FOUND;
135 void _bt_clear_gatt_client_senders(void)
137 if (gatt_client_senders) {
138 g_slist_foreach(gatt_client_senders, (GFunc)g_free, NULL);
139 g_slist_free(gatt_client_senders);
140 gatt_client_senders = NULL;
144 static void __bt_send_foreach_event(gpointer data, gpointer user_data)
147 GVariant *param = user_data;
149 _bt_send_event_to_dest(sender, BT_DEVICE_EVENT,BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
153 void _bt_send_char_value_changed_event(void *param)
155 g_slist_foreach(gatt_client_senders, __bt_send_foreach_event,
159 void __bt_free_le_adv_slot(void)
163 if (le_adv_slot == NULL)
166 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
167 if (le_adv_slot[i].sender)
168 g_free(le_adv_slot[i].sender);
174 int _bt_service_adapter_le_init(void)
176 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
178 return BLUETOOTH_ERROR_NONE;
181 void _bt_service_adapter_le_deinit(void)
183 __bt_free_le_adv_slot();
186 gboolean _bt_update_le_feature_support(const char *item, const char *value)
188 if (item== NULL || value == NULL)
191 if (g_strcmp0(item, "adv_inst_max") == 0) {
192 if (atoi(value) != le_feature_info.adv_inst_max) {
193 __bt_free_le_adv_slot();
194 le_feature_info.adv_inst_max = atoi(value);
195 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
197 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
198 le_feature_info.rpa_offloading = atoi(value);
199 } else if (g_strcmp0(item, "max_filter") == 0) {
200 le_feature_info.max_filter = atoi(value);
202 BT_DBG("No registered item");
209 static gboolean __bt_is_factory_test_mode(void)
212 #ifdef ENABLE_TIZEN_2_4
213 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
214 BT_ERR("Get the DUT Mode fail");
219 BT_INFO("DUT Test Mode !!");
226 int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean use_reserved_slot)
230 if (le_adv_slot == NULL)
233 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
234 if (le_adv_slot[i].sender == NULL)
236 if ((g_strcmp0(le_adv_slot[i].sender, sender) == 0) && (le_adv_slot[i].adv_handle == adv_handle))
240 if (le_feature_info.adv_inst_max <= 2)
242 else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE)
247 for (; i < le_feature_info.adv_inst_max; i++) {
248 if (le_adv_slot[i].sender == NULL)
255 void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int slot_id)
257 if (le_adv_slot[slot_id].sender == NULL) {
258 le_adv_slot[slot_id].sender = strdup(sender);
259 le_adv_slot[slot_id].adv_handle = adv_handle;
263 void __bt_unregister_adv_slot_owner(int slot_id)
265 g_free(le_adv_slot[slot_id].sender);
266 le_adv_slot[slot_id].sender = NULL;
267 le_adv_slot[slot_id].adv_handle = 0;
270 const char* _bt_get_adv_slot_owner(int slot_id)
272 if (le_adv_slot == NULL)
275 return le_adv_slot[slot_id].sender;
278 int _bt_get_adv_slot_adv_handle(int slot_id)
280 if (le_adv_slot == NULL)
283 return le_adv_slot[slot_id].adv_handle;
286 void _bt_set_advertising_status(int slot_id, gboolean mode)
288 le_adv_slot[slot_id].is_advertising = mode;
291 gboolean _bt_is_advertising(void)
293 gboolean status = FALSE;
296 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
297 if (le_adv_slot[i].is_advertising == TRUE)
304 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
308 if (le_adv_slot == NULL)
311 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
312 if (le_adv_slot[i].sender != NULL) {
313 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
314 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
315 _bt_set_advertising(terminated_name, le_adv_slot[i].adv_handle, FALSE, FALSE);
321 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
326 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
331 int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
334 GError *error = NULL;
338 if (__bt_is_factory_test_mode()) {
339 BT_ERR("Unable to start advertising in factory binary !!");
340 return BLUETOOTH_ERROR_NOT_SUPPORT;
343 if (_bt_adapter_get_status() != BT_ACTIVATED &&
344 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
345 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
348 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
350 BT_ERR("There is NO available slot!!");
351 return BLUETOOTH_ERROR_NO_RESOURCES;
354 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
355 return BLUETOOTH_ERROR_IN_PROGRESS;
357 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
358 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
360 proxy = _bt_get_adapter_proxy();
361 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
363 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
364 g_variant_new("(bi)", enable, slot_id),
365 G_DBUS_CALL_FLAGS_NONE,
371 BT_ERR("SetAdvertising Fail: %s", error->message);
372 g_clear_error(&error);
373 return BLUETOOTH_ERROR_INTERNAL;
377 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
379 le_adv_slot[slot_id].is_advertising = enable;
380 BT_INFO("Set advertising [%d]", enable);
383 g_variant_unref(ret);
385 return BLUETOOTH_ERROR_NONE;
388 int _bt_set_custom_advertising(const char *sender, int adv_handle,
389 gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
393 GError *error = NULL;
398 BT_CHECK_PARAMETER(params, return);
400 if (__bt_is_factory_test_mode()) {
401 BT_ERR("Unable to start advertising in factory binary !!");
402 return BLUETOOTH_ERROR_NOT_SUPPORT;
405 if (_bt_adapter_get_status() != BT_ACTIVATED &&
406 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
407 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
410 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
412 BT_ERR("There is NO available slot!!");
413 return BLUETOOTH_ERROR_NO_RESOURCES;
416 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
417 return BLUETOOTH_ERROR_IN_PROGRESS;
419 if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
420 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
422 proxy = _bt_get_adapter_proxy();
423 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
425 if (params->interval_min > params->interval_max ||
426 params->interval_min < BT_ADV_INTERVAL_MIN ||
427 params->interval_max > BT_ADV_INTERVAL_MAX)
428 return BLUETOOTH_ERROR_INVALID_PARAM;
430 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
431 return BLUETOOTH_ERROR_INVALID_PARAM;
433 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
434 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
435 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
436 return BLUETOOTH_ERROR_NOT_SUPPORT;
438 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
439 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
441 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters",
442 g_variant_new("(uuuui)", min, max,
443 params->filter_policy, params->type,
444 slot_id), G_DBUS_CALL_FLAGS_NONE,
448 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
449 g_clear_error(&error);
450 return BLUETOOTH_ERROR_INTERNAL;
453 adv_params.interval_min = params->interval_min;
454 adv_params.interval_max = params->interval_max;
455 adv_params.filter_policy = params->filter_policy;
456 adv_params.type= params->type;
459 g_variant_unref(ret);
461 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertising",
462 g_variant_new("(bi)", enable, slot_id),
463 G_DBUS_CALL_FLAGS_NONE,
469 BT_ERR("SetAdvertising Fail: %s", error->message);
470 g_clear_error(&error);
471 return BLUETOOTH_ERROR_INTERNAL;
475 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
477 __bt_unregister_adv_slot_owner(slot_id);
479 le_adv_slot[slot_id].is_advertising = enable;
480 BT_INFO_C("Set advertising [%d]", enable);
482 g_variant_unref(ret);
484 return BLUETOOTH_ERROR_NONE;
487 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
488 char in_type, char **data, int *data_len)
490 if (in_data == NULL || data == NULL || data_len == NULL)
491 return BLUETOOTH_ERROR_INTERNAL;
494 return BLUETOOTH_ERROR_INTERNAL;
500 for (i = 0; i < in_len; i++) {
502 if (len <= 0 || i + 1 >= in_len) {
503 BT_ERR("Invalid advertising data");
504 return BLUETOOTH_ERROR_INTERNAL;
507 type = in_data[i + 1];
508 if (type == in_type) {
518 if (i + len > in_len) {
519 BT_ERR("Invalid advertising data");
520 return BLUETOOTH_ERROR_INTERNAL;
521 } else if (len == 0) {
522 BT_DBG("AD Type 0x%02x data is not set", in_type);
525 return BLUETOOTH_ERROR_NONE;
528 *data = g_memdup(&in_data[i], len);
530 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
533 return BLUETOOTH_ERROR_NONE;
536 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
538 BT_CHECK_PARAMETER(adv, return);
539 BT_CHECK_PARAMETER(length, return);
541 memcpy(adv, &adv_data, sizeof(adv_data));
542 *length = adv_data_len;
544 return BLUETOOTH_ERROR_NONE;
547 int _bt_set_advertising_data(const char *sender, int adv_handle,
548 bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
551 GError *error = NULL;
552 GVariant *ret, *ad_data, *param = NULL;
553 GVariant *temp = NULL;
554 GVariantBuilder *builder;
556 char *old_mdata = NULL;
557 char *new_mdata = NULL;
562 if (__bt_is_factory_test_mode()) {
563 BT_ERR("Unable to set advertising data in factory binary !!");
564 return BLUETOOTH_ERROR_NOT_SUPPORT;
567 BT_CHECK_PARAMETER(adv, return);
569 if (_bt_adapter_get_status() != BT_ACTIVATED &&
570 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
571 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
574 proxy = _bt_get_adapter_proxy();
575 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
577 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
579 BT_ERR("There is NO available slot!!");
580 return BLUETOOTH_ERROR_NO_RESOURCES;
583 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
584 for (i = 0; i < length; i++) {
585 g_variant_builder_add(builder, "y", adv->data[i]);
588 temp = g_variant_new("ay", builder);
589 g_variant_builder_unref(builder);
590 ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingData",
591 g_variant_new("(@ayi)", temp, slot_id),
592 G_DBUS_CALL_FLAGS_NONE,
596 BT_ERR("SetAdvertisingData Fail: %s", error->message);
597 g_clear_error(&error);
598 return BLUETOOTH_ERROR_INTERNAL;
601 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
603 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
604 &old_mdata, &old_len);
605 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
606 &new_mdata, &new_len);
607 if (old_len != new_len ||
608 (old_mdata && new_mdata &&
609 memcmp(old_mdata, new_mdata, new_len))) {
610 ad_data = g_variant_new_from_data((const GVariantType *)"ay",
611 new_mdata, new_len, TRUE, NULL, NULL);
612 param = g_variant_new("(@ay)", ad_data);
613 _bt_send_event(BT_ADAPTER_EVENT,
614 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
620 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
621 memcpy(&adv_data, adv, length);
622 adv_data_len = length;
624 BT_INFO("Set advertising data");
626 g_variant_unref(ret);
628 return BLUETOOTH_ERROR_NONE;
631 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
633 BT_CHECK_PARAMETER(response, return);
634 BT_CHECK_PARAMETER(length, return);
636 memcpy(response, &resp_data, sizeof(resp_data));
637 *length = resp_data_len;
639 return BLUETOOTH_ERROR_NONE;
642 int _bt_set_scan_response_data(const char *sender, int adv_handle,
643 bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
646 GError *error = NULL;
647 GVariant *ret, *scan_data, *param = NULL;
648 GVariant *temp = NULL;
649 GVariantBuilder *builder;
651 char *old_mdata = NULL;
652 char *new_mdata = NULL;
657 if (__bt_is_factory_test_mode()) {
658 BT_ERR("Unable to set scan response list in factory binary !!");
659 return BLUETOOTH_ERROR_NOT_SUPPORT;
662 BT_CHECK_PARAMETER(response, return);
664 if (_bt_adapter_get_status() != BT_ACTIVATED &&
665 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
666 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
669 proxy = _bt_get_adapter_proxy();
670 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
672 slot_id = __bt_get_available_adv_slot_id(sender, adv_handle, use_reserved_slot);
674 BT_ERR("There is NO available slot!!");
675 return BLUETOOTH_ERROR_NO_RESOURCES;
677 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
678 for (i = 0; i < length; i++) {
679 g_variant_builder_add(builder, "y", response->data[i]);
682 temp = g_variant_new("ay", builder);
683 g_variant_builder_unref(builder);
684 ret = g_dbus_proxy_call_sync(proxy, "SetScanRespData",
685 g_variant_new("(@ayi)", temp, slot_id),
686 G_DBUS_CALL_FLAGS_NONE,
690 BT_ERR("SetScanRespData Fail: %s", error->message);
691 g_clear_error(&error);
692 return BLUETOOTH_ERROR_INTERNAL;
695 __bt_register_adv_slot_owner(sender, adv_handle, slot_id);
697 /* Compare with previous scan resp data */
698 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
699 &old_mdata, &old_len);
700 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
701 &new_mdata, &new_len);
702 if (old_len != new_len ||
703 (old_mdata && new_mdata &&
704 memcmp(old_mdata, new_mdata, new_len))) {
705 scan_data = g_variant_new_from_data((const GVariantType *)"ay",
706 new_mdata, new_len, TRUE, NULL, NULL);
707 param = g_variant_new("(@ay)", scan_data);
708 _bt_send_event(BT_ADAPTER_EVENT,
709 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
715 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
716 memcpy(&resp_data, response, length);
717 resp_data_len = length;
720 g_variant_unref(ret);
721 BT_INFO("Set scan response data");
722 return BLUETOOTH_ERROR_NONE;
725 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
728 GError *error = NULL;
733 BT_CHECK_PARAMETER(params, return);
735 if (_bt_adapter_get_status() != BT_ACTIVATED &&
736 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
737 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
740 proxy = _bt_get_adapter_proxy();
741 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
743 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
744 return BLUETOOTH_ERROR_INVALID_PARAM;
746 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
747 return BLUETOOTH_ERROR_INVALID_PARAM;
749 if (params->window > params->interval)
750 return BLUETOOTH_ERROR_INVALID_PARAM;
752 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
753 win = params->window / BT_ADV_INTERVAL_SPLIT;
755 ret = g_dbus_proxy_call_sync(proxy, "SetScanParameters",
756 g_variant_new("(uuu)", params->type, itv, win),
757 G_DBUS_CALL_FLAGS_NONE, -1,
761 BT_ERR("SetScanParameters Fail: %s", error->message);
762 g_clear_error(&error);
763 return BLUETOOTH_ERROR_INTERNAL;
766 _bt_set_le_scan_type(params->type);
768 is_le_set_scan_parameter = TRUE;
771 g_variant_unref(ret);
772 BT_INFO("Set scan parameters");
773 return BLUETOOTH_ERROR_NONE;
776 bt_adapter_le_scanner_t* __bt_find_scanner_from_list(const char *sender)
779 bt_adapter_le_scanner_t *scanner;
781 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
783 if (g_strcmp0(scanner->sender, sender) == 0)
790 int __bt_get_available_scan_filter_slot_id(void)
793 bt_adapter_le_scanner_t *scanner;
795 bluetooth_le_scan_filter_t *filter_data;
796 gboolean *slot_check_list = NULL;
799 if (le_feature_info.max_filter == 0) {
800 BT_ERR("Scan filter is NOT Supported");
803 slot_check_list = g_malloc0(sizeof(gboolean) * le_feature_info.max_filter);
804 if (slot_check_list == NULL) {
805 BT_ERR("Fail to allocate memory");
809 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
811 for (fl = scanner->filter_list; fl != NULL; fl = g_slist_next(fl)) {
812 filter_data = fl->data;
813 if (filter_data->slot_id < le_feature_info.max_filter) {
814 slot_check_list[filter_data->slot_id] = TRUE;
819 for (i = 0; i < le_feature_info.max_filter; i++) {
820 if (slot_check_list[i] == FALSE) {
821 g_free(slot_check_list);
826 BT_ERR("There is NO available slot for scan filter.");
827 g_free(slot_check_list);
831 int _bt_register_scan_filter(const char *sender, bluetooth_le_scan_filter_t *filter, int *slot_id)
834 GError *error = NULL;
835 GVariant *ret, *param;
836 GVariant *arr_uuid_param = NULL, *arr_uuid_mask_param = NULL;
837 GVariant *arr_data_param = NULL, *arr_data_mask_param = NULL;
838 GArray *arr_uuid = NULL;
839 GArray *arr_uuid_mask = NULL;
840 GArray *arr_data = NULL;
841 GArray *arr_data_mask = NULL;
842 bt_adapter_le_scanner_t *scanner = NULL;
843 bluetooth_le_scan_filter_t *filter_data = NULL;
844 int feature_selection = 0;
846 *slot_id = __bt_get_available_scan_filter_slot_id();
848 return BLUETOOTH_ERROR_NO_RESOURCES;
850 proxy = _bt_get_adapter_proxy();
851 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
853 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
854 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
855 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS;
857 _bt_convert_addr_type_to_string(address, filter->device_address.addr);
859 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
860 NULL, 0, TRUE, NULL, NULL);
861 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
862 NULL, 0, TRUE, NULL, NULL);
863 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
864 NULL, 0, TRUE, NULL, NULL);
865 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
866 NULL, 0, TRUE, NULL, NULL);
868 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
870 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
871 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS, // filter_type
872 *slot_id, // filter_index
874 0, // company_id_mask
875 arr_uuid_param, // p_uuid
876 arr_uuid_mask_param, // p_uuid_mask
879 arr_data_param, // p_data
880 arr_data_mask_param); // p_mask
882 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
883 param, G_DBUS_CALL_FLAGS_NONE,
887 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
888 g_clear_error(&error);
891 g_variant_unref(ret);
894 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
895 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME;
897 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
898 NULL, 0, TRUE, NULL, NULL);
899 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
900 NULL, 0, TRUE, NULL, NULL);
901 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
902 NULL, 0, TRUE, NULL, NULL);
903 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
904 NULL, 0, TRUE, NULL, NULL);
906 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
908 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
909 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME, // filter_type
910 *slot_id, // filter_index
912 0, // company_id_mask
913 arr_uuid_param, // p_uuid
914 arr_uuid_mask_param, // p_uuid_mask
915 filter->device_name, // string
917 arr_data_param, // p_data
918 arr_data_mask_param);
920 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
921 param, G_DBUS_CALL_FLAGS_NONE,
925 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
926 g_clear_error(&error);
929 g_variant_unref(ret);
932 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
933 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID;
935 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
936 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
938 g_array_append_vals(arr_uuid, filter->service_uuid.data.data, filter->service_uuid.data_len * sizeof(guint8));
939 g_array_append_vals(arr_uuid_mask, filter->service_uuid_mask.data.data, filter->service_uuid_mask.data_len * sizeof(guint8));
941 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
942 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
943 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
944 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
945 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
946 NULL, 0, TRUE, NULL, NULL);
947 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
948 NULL, 0, TRUE, NULL, NULL);
950 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
952 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
953 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID, // filter_type
954 *slot_id, // filter_index
956 0, // company_id_mask
957 arr_uuid_param, // p_uuid
958 arr_uuid_mask_param, // p_uuid_mask
961 arr_data_param, // p_data
962 arr_data_mask_param);
964 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove",
965 param, G_DBUS_CALL_FLAGS_NONE,
969 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
970 g_clear_error(&error);
973 g_variant_unref(ret);
975 g_array_free(arr_uuid, TRUE);
976 g_array_free(arr_uuid_mask, TRUE);
977 g_array_free(arr_data, TRUE);
978 g_array_free(arr_data_mask, TRUE);
981 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
982 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID;
984 arr_uuid = g_array_new(TRUE, TRUE, sizeof(guint8));
985 arr_uuid_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
987 g_array_append_vals(arr_uuid, filter->service_solicitation_uuid.data.data, filter->service_solicitation_uuid.data_len * sizeof(guint8));
988 g_array_append_vals(arr_uuid_mask, filter->service_solicitation_uuid_mask.data.data, filter->service_solicitation_uuid_mask.data_len * sizeof(guint8));
990 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
991 arr_uuid->data, arr_uuid->len, TRUE, NULL, NULL);
992 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
993 arr_uuid_mask->data, arr_uuid_mask->len, TRUE, NULL, NULL);
994 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
995 NULL, 0, TRUE, NULL, NULL);
996 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
997 NULL, 0, TRUE, NULL, NULL);
999 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1001 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1002 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID, // filter_type
1003 *slot_id, // filter_index
1005 0, // company_id_mask
1006 arr_uuid_param, // p_uuid
1007 arr_uuid_mask_param, // p_uuid_mask
1010 arr_data_param, // p_data
1011 arr_data_mask_param);
1013 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1014 G_DBUS_CALL_FLAGS_NONE,
1018 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1019 g_clear_error(&error);
1022 g_variant_unref(ret);
1024 g_array_free(arr_uuid, TRUE);
1025 g_array_free(arr_uuid_mask, TRUE);
1028 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1029 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA;
1031 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1032 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1034 g_array_append_vals(arr_data, filter->service_data.data.data, filter->service_data.data_len * sizeof(guint8));
1035 g_array_append_vals(arr_data_mask, filter->service_data_mask.data.data, filter->service_data_mask.data_len * sizeof(guint8));
1037 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1038 NULL, 0, TRUE, NULL, NULL);
1039 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1040 NULL, 0, TRUE, NULL, NULL);
1041 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1042 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1043 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1044 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1046 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1048 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1049 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA, // filter_type
1050 *slot_id, // filter_index
1052 0, // company_id_mask
1053 arr_uuid_param, // p_uuid
1054 arr_uuid_mask_param, // p_uuid_mask
1057 arr_data_param, // p_data
1058 arr_data_mask_param);
1060 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1061 G_DBUS_CALL_FLAGS_NONE,
1065 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1066 g_clear_error(&error);
1069 g_variant_unref(ret);
1071 g_array_free(arr_data, TRUE);
1072 g_array_free(arr_data_mask, TRUE);
1075 if (filter->added_features & BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1076 feature_selection |= BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA;
1078 arr_data = g_array_new(TRUE, TRUE, sizeof(guint8));
1079 arr_data_mask = g_array_new(TRUE, TRUE, sizeof(guint8));
1081 g_array_append_vals(arr_data, filter->manufacturer_data.data.data, filter->manufacturer_data.data_len * sizeof(guint8));
1082 g_array_append_vals(arr_data_mask, filter->manufacturer_data_mask.data.data, filter->manufacturer_data_mask.data_len * sizeof(guint8));
1084 arr_uuid_param = g_variant_new_from_data((const GVariantType *)"ay",
1085 NULL, 0, TRUE, NULL, NULL);
1086 arr_uuid_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1087 NULL, 0, TRUE, NULL, NULL);
1088 arr_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1089 arr_data->data, arr_data->len, TRUE, NULL, NULL);
1090 arr_data_mask_param = g_variant_new_from_data((const GVariantType *)"ay",
1091 arr_data_mask->data, arr_data_mask->len, TRUE, NULL, NULL);
1093 param = g_variant_new("(iiiiii@ay@aysu@ay@ay)",
1095 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1096 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA, // filter_type
1097 *slot_id, // filter_index
1098 filter->manufacturer_id, // company_id
1099 0xFFFF, // company_id_mask
1100 arr_uuid_param, // p_uuid
1101 arr_uuid_mask_param, // p_uuid_mask
1104 arr_data_param, // p_data
1105 arr_data_mask_param);
1107 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_add_remove", param,
1108 G_DBUS_CALL_FLAGS_NONE,
1112 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1113 g_clear_error(&error);
1116 g_variant_unref(ret);
1118 g_array_free(arr_data, TRUE);
1119 g_array_free(arr_data_mask, TRUE);
1122 BT_DBG("Filter selection %.2x", feature_selection);
1124 param = g_variant_new("(iiiiiiiiiiii)",
1126 0, // action (Add - 0x00, Delete - 0x01, Clear - 0x02)
1127 *slot_id, // filter_index
1128 feature_selection, // feat_seln
1129 0, // list_logic_type (OR - 0x00, AND - 0x01)
1130 1, // filt_logic_type (OR - 0x00, AND - 0x01)
1131 -127, // rssi_high_thres
1132 -127, // rssi_low_thres
1133 0, // dely_mode (Immediate - 0x00, on found - 0x01, batched - 0x02)
1136 0); // found_timeout_cnt
1137 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_param_setup",
1138 param, G_DBUS_CALL_FLAGS_NONE,
1142 BT_ERR("scan_filter_add_remove Fail: %s", error->message);
1143 g_clear_error(&error);
1146 scanner = __bt_find_scanner_from_list(sender);
1147 if (scanner == NULL) {
1148 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1150 scanner->sender = strdup(sender);
1151 scanner_list = g_slist_append(scanner_list, scanner);
1155 filter_data = g_malloc0(sizeof(bluetooth_le_scan_filter_t));
1157 memcpy(filter_data, filter, sizeof(bluetooth_le_scan_filter_t));
1158 filter_data->slot_id = *slot_id;
1161 scanner->filter_list = g_slist_append(scanner->filter_list, filter_data);
1165 g_variant_unref(ret);
1166 return BLUETOOTH_ERROR_NONE;
1169 int _bt_unregister_scan_filter(const char *sender, int slot_id)
1172 GError *error = NULL;
1174 bt_adapter_le_scanner_t *scanner = NULL;
1175 bluetooth_le_scan_filter_t *filter_data = NULL;
1177 gboolean is_slot_id_found = FALSE;
1179 scanner = __bt_find_scanner_from_list(sender);
1180 if (scanner == NULL) {
1181 BT_ERR("There is NO available scanner.");
1182 return BLUETOOTH_ERROR_NOT_FOUND;
1185 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1186 filter_data = l->data;
1187 if (filter_data->slot_id == slot_id) {
1188 is_slot_id_found = TRUE;
1192 if (is_slot_id_found == FALSE) {
1193 BT_ERR("There is NO registered slot.");
1194 return BLUETOOTH_ERROR_NOT_FOUND;
1197 proxy = _bt_get_adapter_proxy();
1198 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1200 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1201 g_variant_new("(ii)", 0, slot_id),
1202 G_DBUS_CALL_FLAGS_NONE,
1206 BT_ERR("scan_filter_clear Fail: %s", error->message);
1207 g_clear_error(&error);
1210 scanner->filter_list = g_slist_remove(scanner->filter_list, filter_data);
1211 g_free(filter_data);
1214 g_variant_unref(ret);
1215 return BLUETOOTH_ERROR_NONE;
1218 int _bt_unregister_all_scan_filters(const char *sender)
1221 GError *error = NULL;
1223 bt_adapter_le_scanner_t *scanner = NULL;
1224 bluetooth_le_scan_filter_t *filter_data = NULL;
1227 scanner = __bt_find_scanner_from_list(sender);
1228 if (scanner == NULL) {
1229 BT_ERR("There is NO available scanner.");
1230 return BLUETOOTH_ERROR_NOT_FOUND;
1233 proxy = _bt_get_adapter_proxy();
1234 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1236 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1237 filter_data = l->data;
1239 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_clear",
1240 g_variant_new("(ii)", 0, filter_data->slot_id),
1241 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1244 BT_ERR("scan_filter_clear Fail: %s", error->message);
1245 g_clear_error(&error);
1248 g_variant_unref(ret);
1251 g_slist_free_full(scanner->filter_list, g_free);
1252 scanner->filter_list = NULL;
1254 return BLUETOOTH_ERROR_NONE;
1257 int _bt_start_le_scan(const char *sender)
1260 GError *error = NULL;
1262 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1264 if (scanner == NULL) {
1265 scanner = g_malloc0(sizeof(bt_adapter_le_scanner_t));
1266 retv_if(scanner == NULL, BLUETOOTH_ERROR_INTERNAL);
1268 scanner->sender = strdup(sender);
1269 scanner_list = g_slist_append(scanner_list, scanner);
1272 if (scanner->is_scanning == TRUE) {
1273 BT_ERR("BT is already in LE scanning");
1274 return BLUETOOTH_ERROR_IN_PROGRESS;
1276 scanner->is_scanning = TRUE;
1278 proxy = _bt_get_adapter_proxy();
1279 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1281 if (_bt_is_le_scanning()) {
1282 if (scan_filter_enabled == TRUE) {
1283 if (scanner->filter_list == NULL) {
1284 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1285 g_variant_new("(ib)", 0, FALSE),
1286 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1289 BT_ERR("scan_filter_clear Fail: %s", error->message);
1290 g_clear_error(&error);
1294 g_variant_unref(ret);
1295 BT_INFO("Disable LE Scan Filter");
1296 scan_filter_enabled = FALSE;
1298 BT_INFO("LE Filter Scan is continue");
1301 BT_INFO("LE Full Scan is already on progress");
1303 return BLUETOOTH_ERROR_NONE;
1305 if (is_le_set_scan_parameter == FALSE) {
1306 /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
1307 bluetooth_le_scan_params_t scan_params;
1308 scan_params.type = BT_LE_ACTIVE_SCAN;
1309 scan_params.interval = 5000;
1310 scan_params.window = 500;
1311 _bt_set_scan_parameters(&scan_params);
1314 if (scanner->filter_list == NULL) {
1315 BT_INFO("Start LE Full Scan");
1316 scan_filter_enabled = FALSE;
1318 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1319 g_variant_new("(ib)", 0, TRUE),
1320 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1323 BT_ERR("scan_filter_clear Fail: %s", error->message);
1324 g_clear_error(&error);
1328 g_variant_unref(ret);
1329 BT_INFO("Enable LE Scan Filter");
1330 scan_filter_enabled = TRUE;
1334 ret = g_dbus_proxy_call_sync(proxy, "StartLEDiscovery",
1335 NULL,G_DBUS_CALL_FLAGS_NONE,
1339 BT_ERR("StartLEDiscovery Fail: %s", error->message);
1340 g_clear_error(&error);
1341 return BLUETOOTH_ERROR_INTERNAL;
1345 g_variant_unref(ret);
1346 return BLUETOOTH_ERROR_NONE;
1349 int _bt_stop_le_scan(const char *sender)
1352 GError *error = NULL;
1354 bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender);
1356 gboolean next_scanning = FALSE;
1357 gboolean need_scan_filter = TRUE;
1359 if (scanner == NULL || scanner->is_scanning == FALSE)
1360 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1362 scanner->is_scanning = FALSE;
1364 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1366 if (scanner->is_scanning == TRUE) {
1367 next_scanning = TRUE;
1368 if (scanner->filter_list == NULL)
1369 need_scan_filter = FALSE;
1373 proxy = _bt_get_adapter_proxy();
1374 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1376 if (next_scanning == TRUE) {
1377 if (scan_filter_enabled == FALSE && need_scan_filter == TRUE) {
1378 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1379 g_variant_new("(ib)", 0, TRUE),
1380 G_DBUS_CALL_FLAGS_NONE,
1384 BT_ERR("scan_filter_clear Fail: %s", error->message);
1385 g_clear_error(&error);
1389 g_variant_unref(ret);
1390 BT_INFO("Enable LE Scan Filter");
1391 scan_filter_enabled = TRUE;
1393 return BLUETOOTH_ERROR_NONE;
1395 if (scan_filter_enabled == TRUE) {
1396 ret = g_dbus_proxy_call_sync(proxy, "scan_filter_enable",
1397 g_variant_new("(ib)", 0, FALSE),
1398 G_DBUS_CALL_FLAGS_NONE,
1402 BT_ERR("scan_filter_clear Fail: %s", error->message);
1403 g_clear_error(&error);
1407 g_variant_unref(ret);
1408 BT_INFO("Disable LE Scan Filter");
1410 BT_INFO("Just stop LE scan");
1414 ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery",
1415 NULL,G_DBUS_CALL_FLAGS_NONE,
1418 BT_ERR("LE Scan stop failed");
1419 return BLUETOOTH_ERROR_INTERNAL;
1422 scan_filter_enabled = FALSE;
1423 is_le_set_scan_parameter = FALSE;
1425 g_variant_unref(ret);
1426 return BLUETOOTH_ERROR_NONE;
1429 void _bt_disable_all_scanner_status(void)
1432 bt_adapter_le_scanner_t *scanner;
1434 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1436 scanner->is_scanning = FALSE;
1440 void _bt_set_le_scan_status(gboolean mode)
1442 is_le_scanning = mode;
1445 gboolean _bt_is_le_scanning(void)
1447 return is_le_scanning;
1450 void _bt_set_le_scan_type(bt_le_scan_type_t type)
1452 le_scan_type = type;
1455 bt_le_scan_type_t _bt_get_le_scan_type(void)
1457 return le_scan_type;
1460 static gboolean __bt_check_scan_result_uuid(const char *adv_data,
1461 int adv_data_len, const char *svc_uuid, int uuid_len,
1462 const char *uuid_mask, char ad_type)
1468 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1469 ad_type, &data, &data_len);
1471 _bt_swap_byte_ordering(data, data_len);
1472 for (i = 0; i < data_len; i += uuid_len) {
1473 if (uuid_len > (data_len - i))
1476 if (_bt_byte_arr_cmp_with_mask(data + i,
1477 svc_uuid, uuid_mask, uuid_len) == 0) {
1488 static gboolean __bt_check_scan_result_with_filter(const char *device_address,
1489 const char *adv_data, int adv_data_len,
1490 const char *scan_data, int scan_data_len,
1491 const bt_adapter_le_scanner_t *scanner)
1494 bluetooth_le_scan_filter_t *filter_data = NULL;
1497 gboolean is_matched = FALSE;
1499 if (scanner->filter_list == NULL) {
1500 BT_INFO("This scanner is on Full Scan.");
1504 for (l = scanner->filter_list; l != NULL; l = g_slist_next(l)) {
1505 filter_data = l->data;
1507 if (filter_data->added_features &
1508 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_ADDRESS) {
1509 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1511 _bt_convert_addr_type_to_string(address,
1512 filter_data->device_address.addr);
1513 if (strncmp(address, device_address,
1514 BT_ADDRESS_STRING_SIZE) != 0)
1518 if (filter_data->added_features &
1519 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_UUID) {
1522 if (__bt_check_scan_result_uuid(adv_data,
1524 (char*)filter_data->service_uuid.data.data,
1525 filter_data->service_uuid.data_len,
1526 (char*)filter_data->service_uuid_mask.data.data,
1527 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1530 if (__bt_check_scan_result_uuid(adv_data,
1532 (char*)filter_data->service_uuid.data.data,
1533 filter_data->service_uuid.data_len,
1534 (char*)filter_data->service_uuid_mask.data.data,
1535 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1538 if (__bt_check_scan_result_uuid(adv_data,
1540 (char*)filter_data->service_uuid.data.data,
1541 filter_data->service_uuid.data_len,
1542 (char*)filter_data->service_uuid_mask.data.data,
1543 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1546 if (__bt_check_scan_result_uuid(adv_data,
1548 (char*)filter_data->service_uuid.data.data,
1549 filter_data->service_uuid.data_len,
1550 (char*)filter_data->service_uuid_mask.data.data,
1551 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1554 if (__bt_check_scan_result_uuid(scan_data,
1556 (char*)filter_data->service_uuid.data.data,
1557 filter_data->service_uuid.data_len,
1558 (char*)filter_data->service_uuid_mask.data.data,
1559 BT_LE_AD_TYPE_INCOMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1562 if (__bt_check_scan_result_uuid(scan_data,
1564 (char*)filter_data->service_uuid.data.data,
1565 filter_data->service_uuid.data_len,
1566 (char*)filter_data->service_uuid_mask.data.data,
1567 BT_LE_AD_TYPE_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS)
1570 if (__bt_check_scan_result_uuid(scan_data,
1572 (char*)filter_data->service_uuid.data.data,
1573 filter_data->service_uuid.data_len,
1574 (char*)filter_data->service_uuid_mask.data.data,
1575 BT_LE_AD_TYPE_INCOMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1578 if (__bt_check_scan_result_uuid(scan_data,
1580 (char*)filter_data->service_uuid.data.data,
1581 filter_data->service_uuid.data_len,
1582 (char*)filter_data->service_uuid_mask.data.data,
1583 BT_LE_AD_TYPE_COMP_LIST_128_BIT_SERVICE_CLASS_UUIDS)
1587 if (is_matched == FALSE)
1590 if (filter_data->added_features &
1591 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_SOLICITATION_UUID) {
1594 if (__bt_check_scan_result_uuid(adv_data,
1596 (char*)filter_data->service_solicitation_uuid.data.data,
1597 filter_data->service_solicitation_uuid.data_len,
1598 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1599 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1602 if (__bt_check_scan_result_uuid(adv_data,
1604 (char*)filter_data->service_solicitation_uuid.data.data,
1605 filter_data->service_solicitation_uuid.data_len,
1606 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1607 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1610 if (__bt_check_scan_result_uuid(scan_data,
1612 (char*)filter_data->service_solicitation_uuid.data.data,
1613 filter_data->service_solicitation_uuid.data_len,
1614 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1615 BT_LE_AD_TYPE_LIST_16_BIT_SERVICE_SOLICITATION_UUIDS)
1618 if (__bt_check_scan_result_uuid(scan_data,
1620 (char*)filter_data->service_solicitation_uuid.data.data,
1621 filter_data->service_solicitation_uuid.data_len,
1622 (char*)filter_data->service_solicitation_uuid_mask.data.data,
1623 BT_LE_AD_TYPE_LIST_128_BIT_SERVICE_SOLICITATION_UUIDS)
1627 if (is_matched == FALSE)
1630 if (filter_data->added_features &
1631 BLUETOOTH_LE_SCAN_FILTER_FEATURE_DEVICE_NAME) {
1632 char name[BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX] = {0, };
1637 __bt_get_ad_data_by_type((char*)adv_data, adv_data_len,
1638 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1641 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1642 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1643 memcpy(name, data, data_len);
1644 name[data_len] = '\0';
1647 if (strncmp(filter_data->device_name,
1648 name, data_len) == 0)
1651 __bt_get_ad_data_by_type((char*)scan_data,
1653 BT_LE_AD_TYPE_COMPLETE_LOCAL_NAME,
1656 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1657 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1658 memcpy(name, data, data_len);
1659 name[data_len] = '\0';
1662 if (strncmp(filter_data->device_name,
1663 name, data_len) == 0)
1667 if (is_matched == FALSE)
1670 if (filter_data->added_features &
1671 BLUETOOTH_LE_SCAN_FILTER_FEATURE_MANUFACTURER_DATA) {
1676 __bt_get_ad_data_by_type((char*)adv_data,
1678 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1681 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1682 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1683 if (_bt_byte_arr_cmp_with_mask(data,
1684 (char*)filter_data->manufacturer_data.data.data,
1685 (char*)filter_data->manufacturer_data_mask.data.data,
1692 __bt_get_ad_data_by_type((char*)scan_data,
1694 BT_LE_AD_TYPE_MANUFACTURER_SPECIFIC_DATA,
1697 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1698 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1699 if (_bt_byte_arr_cmp_with_mask(data,
1700 (char*)filter_data->manufacturer_data.data.data,
1701 (char*)filter_data->manufacturer_data_mask.data.data,
1709 if (is_matched == FALSE)
1712 if (filter_data->added_features &
1713 BLUETOOTH_LE_SCAN_FILTER_FEATURE_SERVICE_DATA) {
1718 __bt_get_ad_data_by_type((char*)adv_data,
1720 BT_LE_AD_TYPE_SERVICE_DATA,
1723 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1724 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1725 if (_bt_byte_arr_cmp_with_mask(data,
1726 (char*)filter_data->service_data.data.data,
1727 (char*)filter_data->service_data_mask.data.data,
1734 __bt_get_ad_data_by_type((char*)scan_data,
1736 BT_LE_AD_TYPE_SERVICE_DATA,
1739 if (data_len >= BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
1740 data_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - 1;
1741 if (_bt_byte_arr_cmp_with_mask(data,
1742 (char*)filter_data->service_data.data.data,
1743 (char*)filter_data->service_data_mask.data.data,
1751 if (is_matched == FALSE)
1755 BT_INFO("The scan result is conformable.");
1759 BT_INFO("The scan result is NOT conformable.");
1763 void _bt_send_scan_result_event(const bt_remote_le_dev_info_t *le_dev_info,
1764 const bt_le_adv_info_t *adv_info)
1766 int result = BLUETOOTH_ERROR_NONE;
1768 GVariant *scan_data_param, *adv_data_param;
1770 bt_adapter_le_scanner_t *scanner = NULL;
1771 const char *adv_data = NULL;
1772 int adv_data_len = 0;
1773 const char *scan_data = NULL;
1774 int scan_data_len = 0;
1776 ret_if(le_dev_info == NULL);
1777 if (_bt_get_le_scan_type() == BT_LE_ACTIVE_SCAN)
1778 ret_if(adv_info == NULL);
1780 if (_bt_get_le_scan_type() == BT_LE_PASSIVE_SCAN) {
1781 adv_data = le_dev_info->adv_data;
1782 adv_data_len = le_dev_info->adv_data_len;
1783 scan_data = le_dev_info->adv_data;
1786 adv_data = adv_info->data;
1787 adv_data_len = adv_info->data_len;
1788 scan_data = le_dev_info->adv_data;
1789 scan_data_len = le_dev_info->adv_data_len;
1792 for (l = scanner_list; l != NULL; l = g_slist_next(l)) {
1794 if (scanner->is_scanning == FALSE)
1797 if (__bt_check_scan_result_with_filter(le_dev_info->address,
1798 adv_data, adv_data_len, scan_data, scan_data_len,
1802 adv_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1803 adv_data, adv_data_len, TRUE, NULL, NULL);
1804 scan_data_param = g_variant_new_from_data((const GVariantType *)"ay",
1805 scan_data, scan_data_len, TRUE, NULL, NULL);
1807 param = g_variant_new("(isnnn@ayn@ay)",
1809 le_dev_info->address,
1810 le_dev_info->addr_type,
1817 _bt_send_event_to_dest(scanner->sender, BT_LE_ADAPTER_EVENT,
1818 BLUETOOTH_EVENT_REMOTE_LE_DEVICE_FOUND, param);
1822 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1825 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1826 GError *error = NULL;
1829 if (__bt_is_factory_test_mode()) {
1830 BT_ERR("Unable to add white list in factory binary !!");
1831 return BLUETOOTH_ERROR_NOT_SUPPORT;
1834 BT_CHECK_PARAMETER(device_address, return);
1836 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1837 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1838 return BLUETOOTH_ERROR_INVALID_PARAM;
1840 _bt_convert_addr_type_to_string(address, device_address->addr);
1842 proxy = _bt_get_adapter_proxy();
1843 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1845 ret = g_dbus_proxy_call_sync(proxy, "AddDeviceWhiteList",
1846 g_variant_new("(su)", address, address_type),
1847 G_DBUS_CALL_FLAGS_NONE, -1,
1851 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
1852 g_clear_error(&error);
1853 return BLUETOOTH_ERROR_INTERNAL;
1857 g_variant_unref(ret);
1858 BT_INFO("Add white list");
1860 return BLUETOOTH_ERROR_NONE;
1863 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
1866 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1867 GError *error = NULL;
1870 if (__bt_is_factory_test_mode()) {
1871 BT_ERR("Unable to remove white list in factory binary !!");
1872 return BLUETOOTH_ERROR_NOT_SUPPORT;
1875 BT_CHECK_PARAMETER(device_address, return);
1877 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
1878 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
1879 return BLUETOOTH_ERROR_INVALID_PARAM;
1881 _bt_convert_addr_type_to_string(address, device_address->addr);
1883 proxy = _bt_get_adapter_proxy();
1884 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1886 ret = g_dbus_proxy_call_sync(proxy, "RemoveDeviceWhiteList",
1887 g_variant_new("(su)", address, address_type),
1888 G_DBUS_CALL_FLAGS_NONE, -1,
1892 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
1893 g_clear_error(&error);
1894 return BLUETOOTH_ERROR_INTERNAL;
1898 g_variant_unref(ret);
1899 BT_INFO("Remove white list");
1901 return BLUETOOTH_ERROR_NONE;
1904 int _bt_clear_white_list(void)
1907 GError *error = NULL;
1910 if (__bt_is_factory_test_mode()) {
1911 BT_ERR("Unable to clear white list in factory binary !!");
1912 return BLUETOOTH_ERROR_NOT_SUPPORT;
1915 proxy = _bt_get_adapter_proxy();
1916 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1918 ret = g_dbus_proxy_call_sync(proxy, "ClearDeviceWhiteList",
1919 NULL,G_DBUS_CALL_FLAGS_NONE,
1923 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
1924 g_clear_error(&error);
1925 return BLUETOOTH_ERROR_INTERNAL;
1928 g_variant_unref(ret);
1930 BT_INFO("Clear white list");
1932 return BLUETOOTH_ERROR_NONE;
1935 int _bt_initialize_ipsp(void)
1939 GError *error = NULL;
1942 if (_bt_adapter_get_status() != BT_ACTIVATED &&
1943 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
1944 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1947 proxy = _bt_get_adapter_proxy();
1948 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1950 ret = g_dbus_proxy_call_sync(proxy, "InitializeIpsp",
1951 NULL,G_DBUS_CALL_FLAGS_NONE,
1954 BT_ERR("Initialize IPSP Failed :[%s]", error->message);
1955 g_clear_error(&error);
1956 return BLUETOOTH_ERROR_INTERNAL;
1959 g_variant_unref(ret);
1961 BT_INFO("IPSP initialization called successfully");
1963 return BLUETOOTH_ERROR_NONE;
1966 int _bt_deinitialize_ipsp(void)
1970 GError *error = NULL;
1972 bt_le_status_t le_status = _bt_adapter_get_le_status();
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 int ret = BLUETOOTH_ERROR_NONE;
2005 guint16 max_tx_octets, max_tx_time;
2006 guint16 max_rx_octets, max_rx_time;
2008 proxy = _bt_get_adapter_proxy();
2009 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2011 reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength",
2012 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2014 g_object_unref(proxy);
2016 if (reply == NULL) {
2017 BT_ERR("LEReadMaximumDataLength dBUS-RPC failed");
2018 if (error != NULL) {
2019 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2020 error->code, error->message);
2021 g_clear_error(&error);
2023 return BLUETOOTH_ERROR_INTERNAL;
2026 g_variant_get(reply ,"(qqqq)", &max_tx_octets, &max_tx_time,
2027 &max_rx_octets, &max_rx_time);
2029 max_le_datalength->max_tx_octets = max_tx_octets;
2030 max_le_datalength->max_tx_time = max_tx_time;
2031 max_le_datalength->max_rx_octets = max_rx_octets;
2032 max_le_datalength->max_rx_time = max_rx_time;
2034 g_variant_unref(reply);
2036 return BLUETOOTH_ERROR_NONE;
2038 int _bt_le_write_host_suggested_default_data_length(
2039 const unsigned int def_tx_Octets, const unsigned int def_tx_Time)
2041 GError *error = NULL;
2043 GVariant *reply = NULL;
2044 int ret = BLUETOOTH_ERROR_NONE;
2046 proxy = _bt_get_adapter_proxy();
2047 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2049 reply = g_dbus_proxy_call_sync(proxy,
2050 "LEWriteHostSuggestedDataLength",
2051 g_variant_new("(qq)", def_tx_Octets, def_tx_Time),
2052 G_DBUS_CALL_FLAGS_NONE,
2057 g_object_unref(proxy);
2059 if (reply == NULL) {
2060 BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed");
2061 if (error != NULL) {
2062 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2063 error->code, error->message);
2064 g_clear_error(&error);
2066 return BLUETOOTH_ERROR_INTERNAL;
2069 g_variant_unref(reply);
2071 return BLUETOOTH_ERROR_NONE;
2074 int _bt_le_read_host_suggested_default_data_length(
2075 bluetooth_le_read_host_suggested_data_length_t *def_data_length)
2077 GError *error = NULL;
2079 GVariant *reply = NULL;
2080 int ret = BLUETOOTH_ERROR_NONE;
2081 guint16 def_tx_octets, def_tx_time;
2083 proxy = _bt_get_adapter_proxy();
2084 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2086 reply = g_dbus_proxy_call_sync(proxy, "LEReadHostSuggestedDataLength",
2087 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2089 if (reply == NULL) {
2090 BT_ERR("LEReadHostSuggestedDataLength dBUS-RPC failed");
2091 if (error != NULL) {
2092 BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
2093 error->code, error->message);
2094 g_clear_error(&error);
2096 return BLUETOOTH_ERROR_INTERNAL;
2099 g_variant_get(reply ,"(qq)", &def_tx_octets, &def_tx_time);
2101 def_data_length->def_tx_octets = def_tx_octets;
2102 def_data_length->def_tx_time = def_tx_time;
2104 g_variant_unref(reply);
2106 return BLUETOOTH_ERROR_NONE;
2109 int _bt_le_set_data_length(bluetooth_device_address_t *device_address,
2110 const unsigned int max_tx_Octets, const unsigned int max_tx_Time)
2112 GError *error = NULL;
2114 GVariant *reply = NULL;
2115 int ret = BLUETOOTH_ERROR_NONE;
2116 guint16 txOctets = max_tx_Octets;
2117 guint16 txTime = max_tx_Time;
2118 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2119 gchar *device_path = NULL;
2120 GDBusConnection *conn;
2121 GDBusProxy *device_proxy;
2123 _bt_convert_addr_type_to_string(address, device_address->addr);
2125 device_path = _bt_get_device_object_path(&address);
2127 if (device_path == NULL) {
2128 BT_DBG("Device path is null");
2129 return BLUETOOTH_ERROR_INTERNAL;
2132 conn = _bt_get_system_gconn();
2134 BT_ERR("conn == NULL");
2135 g_free(device_path);
2139 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2140 NULL, BT_BLUEZ_NAME,
2141 device_path, BT_DEVICE_INTERFACE, NULL, NULL);
2143 g_free(device_path);
2144 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2146 g_dbus_proxy_call_sync(device_proxy,
2148 g_variant_new("(qq)", txOctets, txTime),
2149 G_DBUS_CALL_FLAGS_NONE,
2154 g_object_unref(device_proxy);
2157 BT_ERR("LESetDataLength error: [%s]", error->message);
2158 g_error_free(error);
2159 return BLUETOOTH_ERROR_INTERNAL;
2162 return BLUETOOTH_ERROR_NONE;