4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
25 #include <dbus/dbus-glib.h>
26 #include <dbus/dbus.h>
31 #include <syspopup_caller.h>
33 #include <notification.h>
34 //#include <journal/device.h>
36 #include "bt-internal-types.h"
37 #include "bt-service-common.h"
38 #include "bt-service-event.h"
39 #include "bt-service-adapter.h"
40 #include "bt-service-adapter-le.h"
43 #define BT_ADV_INTERVAL_MIN 20 /* msec */
44 #define BT_ADV_INTERVAL_MAX 10240
45 #define BT_ADV_INTERVAL_SPLIT 0.625
46 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
47 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
48 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
49 #define BT_ADV_TYPE_DEFAULT 0x00
50 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
56 } bt_adapter_le_feature_info_t;
60 gboolean is_advertising;
61 } bt_adapter_le_adv_slot_t;
63 static bluetooth_advertising_params_t adv_params = {
64 BT_DEFAULT_ADV_MIN_INTERVAL,
65 BT_DEFAULT_ADV_MAX_INTERVAL,
66 BT_ADV_FILTER_POLICY_DEFAULT,
68 static bluetooth_advertising_data_t adv_data = { {0} };
69 static int adv_data_len;
70 static bluetooth_scan_resp_data_t resp_data = { {0} };
71 static int resp_data_len;
73 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
74 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
76 void __bt_free_le_adv_slot(void)
80 if (le_adv_slot == NULL)
83 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
84 if (le_adv_slot[i].sender)
85 g_free(le_adv_slot[i].sender);
91 int _bt_service_adapter_le_init(void)
93 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
95 return BLUETOOTH_ERROR_NONE;
98 void _bt_service_adapter_le_deinit(void)
100 __bt_free_le_adv_slot();
103 gboolean _bt_update_le_feature_support(const char *item, const char *value)
105 if (item== NULL || value == NULL)
108 if (g_strcmp0(item, "adv_inst_max") == 0) {
109 if (atoi(value) != le_feature_info.adv_inst_max) {
110 __bt_free_le_adv_slot();
111 le_feature_info.adv_inst_max = atoi(value);
112 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
114 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
115 le_feature_info.rpa_offloading = atoi(value);
116 } else if (g_strcmp0(item, "max_filter") == 0) {
117 le_feature_info.max_filter = atoi(value);
119 BT_DBG("No registered item");
126 static gboolean __bt_is_factory_test_mode(void)
129 #ifdef ENABLE_TIZEN_2_4
130 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
131 BT_ERR("Get the DUT Mode fail");
136 BT_INFO("DUT Test Mode !!");
143 int __bt_get_available_adv_slot_id(const char *sender, gboolean use_reserved_slot)
147 if (le_adv_slot == NULL)
150 if (use_reserved_slot == TRUE) {
151 if (le_feature_info.adv_inst_max > 1)
153 else if (le_adv_slot[0].sender == NULL ||
154 g_strcmp0(le_adv_slot[0].sender, sender) == 0)
160 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
161 if (le_adv_slot[i].sender == NULL)
163 if (g_strcmp0(le_adv_slot[i].sender, sender) == 0)
167 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
168 if (le_adv_slot[i].sender == NULL)
175 void __bt_register_adv_slot_owner(const char *sender, int slot_id)
177 if (le_adv_slot[slot_id].sender == NULL)
178 le_adv_slot[slot_id].sender = strdup(sender);
181 void __bt_unregister_adv_slot_owner(int slot_id)
183 g_free(le_adv_slot[slot_id].sender);
184 le_adv_slot[slot_id].sender = NULL;
185 le_adv_slot[slot_id].is_advertising = FALSE;
188 const char* _bt_get_adv_slot_owner(int slot_id)
190 if (le_adv_slot == NULL)
193 return le_adv_slot[slot_id].sender;
196 void _bt_set_advertising_status(int slot_id, gboolean mode)
198 le_adv_slot[slot_id].is_advertising = mode;
201 gboolean _bt_is_advertising(void)
203 gboolean status = FALSE;
206 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
207 if (le_adv_slot[i].is_advertising == TRUE)
214 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
218 if (le_adv_slot == NULL)
221 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
222 if (le_adv_slot[i].sender != NULL) {
223 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
224 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
225 _bt_set_advertising(FALSE, terminated_name, FALSE);
231 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
236 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
241 int _bt_set_advertising(gboolean enable, const char *sender, gboolean use_reserved_slot)
244 GError *error = NULL;
247 if (__bt_is_factory_test_mode()) {
248 BT_ERR("Unable to start advertising in factory binary !!");
249 return BLUETOOTH_ERROR_NOT_SUPPORT;
252 if (_bt_adapter_get_status() != BT_ACTIVATED &&
253 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
254 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
257 slot_id = __bt_get_available_adv_slot_id(sender, use_reserved_slot);
259 BT_ERR("There is NO available slot!!");
260 return BLUETOOTH_ERROR_NO_RESOURCES;
263 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
264 return BLUETOOTH_ERROR_IN_PROGRESS;
266 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
267 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
269 proxy = _bt_get_adapter_proxy();
270 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
272 dbus_g_proxy_call(proxy, "SetAdvertising", &error,
273 G_TYPE_BOOLEAN, enable,
275 G_TYPE_INVALID, G_TYPE_INVALID);
278 BT_ERR("SetAdvertising Fail: %s", error->message);
280 return BLUETOOTH_ERROR_INTERNAL;
283 le_adv_slot[slot_id].is_advertising = enable;
286 __bt_register_adv_slot_owner(sender, slot_id);
288 __bt_unregister_adv_slot_owner(slot_id);
290 BT_INFO("Set advertising [%d]", enable);
292 return BLUETOOTH_ERROR_NONE;
295 int _bt_set_custom_advertising(gboolean enable, bluetooth_advertising_params_t *params,
296 const char *sender, gboolean use_reserved_slot)
299 GError *error = NULL;
304 BT_CHECK_PARAMETER(params, return);
306 if (__bt_is_factory_test_mode()) {
307 BT_ERR("Unable to start advertising in factory binary !!");
308 return BLUETOOTH_ERROR_NOT_SUPPORT;
311 if (_bt_adapter_get_status() != BT_ACTIVATED &&
312 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
313 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
316 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
317 return BLUETOOTH_ERROR_IN_PROGRESS;
319 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
320 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
322 proxy = _bt_get_adapter_proxy();
323 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
325 if (params->interval_min > params->interval_max ||
326 params->interval_min < BT_ADV_INTERVAL_MIN ||
327 params->interval_max > BT_ADV_INTERVAL_MAX)
328 return BLUETOOTH_ERROR_INVALID_PARAM;
330 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
331 return BLUETOOTH_ERROR_INVALID_PARAM;
333 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
334 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
335 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
336 return BLUETOOTH_ERROR_NOT_SUPPORT;
338 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
339 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
341 slot_id = __bt_get_available_adv_slot_id(sender, use_reserved_slot);
343 BT_ERR("There is NO available slot!!");
344 return BLUETOOTH_ERROR_NO_RESOURCES;
347 dbus_g_proxy_call(proxy, "SetAdvertisingParameters", &error,
350 G_TYPE_UINT, params->filter_policy,
351 G_TYPE_UINT, params->type,
353 G_TYPE_INVALID, G_TYPE_INVALID);
356 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
358 return BLUETOOTH_ERROR_INTERNAL;
361 adv_params.interval_min = params->interval_min;
362 adv_params.interval_max = params->interval_max;
363 adv_params.filter_policy = params->filter_policy;
364 adv_params.type= params->type;
366 dbus_g_proxy_call(proxy, "SetAdvertising", &error,
367 G_TYPE_BOOLEAN, enable,
369 G_TYPE_INVALID, G_TYPE_INVALID);
372 BT_ERR("SetAdvertising Fail: %s", error->message);
374 return BLUETOOTH_ERROR_INTERNAL;
377 le_adv_slot[slot_id].is_advertising = enable;
380 __bt_register_adv_slot_owner(sender, slot_id);
382 __bt_unregister_adv_slot_owner(slot_id);
384 BT_INFO_C("Set advertising [%d]", enable);
385 return BLUETOOTH_ERROR_NONE;
388 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
389 char in_type, char **data, int *data_len)
391 if (in_data == NULL || data == NULL || data_len == NULL)
392 return BLUETOOTH_ERROR_INTERNAL;
395 return BLUETOOTH_ERROR_INTERNAL;
401 for (i = 0; i < in_len; i++) {
403 if (len <= 0 || i + 1 >= in_len) {
404 BT_ERR("Invalid advertising data");
405 return BLUETOOTH_ERROR_INTERNAL;
408 type = in_data[i + 1];
409 if (type == in_type) {
419 if (i + len > in_len) {
420 BT_ERR("Invalid advertising data");
421 return BLUETOOTH_ERROR_INTERNAL;
422 } else if (len == 0) {
423 BT_DBG("AD Type 0x%02x data is not set", in_type);
426 return BLUETOOTH_ERROR_NONE;
429 *data = g_memdup(&in_data[i], len);
431 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
434 return BLUETOOTH_ERROR_NONE;
437 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
439 BT_CHECK_PARAMETER(adv, return);
440 BT_CHECK_PARAMETER(length, return);
442 memcpy(adv, &adv_data, sizeof(adv_data));
443 *length = adv_data_len;
445 return BLUETOOTH_ERROR_NONE;
448 int _bt_set_advertising_data(bluetooth_advertising_data_t *adv, int length,
449 const char *sender, gboolean use_reserved_slot)
452 GError *error = NULL;
455 char *old_mdata = NULL;
456 char *new_mdata = NULL;
461 if (__bt_is_factory_test_mode()) {
462 BT_ERR("Unable to set advertising data in factory binary !!");
463 return BLUETOOTH_ERROR_NOT_SUPPORT;
466 BT_CHECK_PARAMETER(adv, return);
468 if (_bt_adapter_get_status() != BT_ACTIVATED &&
469 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
470 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
473 proxy = _bt_get_adapter_proxy();
474 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
476 arr = g_array_new(TRUE, TRUE, sizeof(guint8));
478 for (i = 0; i < length; i++)
479 g_array_append_vals(arr, &(adv->data[i]), sizeof(guint8));
481 slot_id = __bt_get_available_adv_slot_id(sender, use_reserved_slot);
483 BT_ERR("There is NO available slot!!");
484 return BLUETOOTH_ERROR_NO_RESOURCES;
487 dbus_g_proxy_call(proxy, "SetAdvertisingData", &error,
488 DBUS_TYPE_G_UCHAR_ARRAY, arr,
490 G_TYPE_INVALID, G_TYPE_INVALID);
492 g_array_free(arr, TRUE);
495 BT_ERR("SetAdvertisingData Fail: %s", error->message);
497 return BLUETOOTH_ERROR_INTERNAL;
500 __bt_register_adv_slot_owner(sender, slot_id);
502 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
503 &old_mdata, &old_len);
504 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
505 &new_mdata, &new_len);
506 if (old_len != new_len ||
507 (old_mdata && new_mdata &&
508 memcmp(old_mdata, new_mdata, new_len))) {
509 _bt_send_event(BT_ADAPTER_EVENT,
510 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
511 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
518 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
519 memcpy(&adv_data, adv, length);
520 adv_data_len = length;
522 BT_INFO("Set advertising data");
524 return BLUETOOTH_ERROR_NONE;
527 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
529 BT_CHECK_PARAMETER(response, return);
530 BT_CHECK_PARAMETER(length, return);
532 memcpy(response, &resp_data, sizeof(resp_data));
533 *length = resp_data_len;
535 return BLUETOOTH_ERROR_NONE;
538 int _bt_set_scan_response_data(bluetooth_scan_resp_data_t *response, int length,
539 const char *sender, gboolean use_reserved_slot)
542 GError *error = NULL;
545 char *old_mdata = NULL;
546 char *new_mdata = NULL;
551 if (__bt_is_factory_test_mode()) {
552 BT_ERR("Unable to set scan response list in factory binary !!");
553 return BLUETOOTH_ERROR_NOT_SUPPORT;
556 BT_CHECK_PARAMETER(response, return);
558 if (_bt_adapter_get_status() != BT_ACTIVATED &&
559 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
560 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
563 proxy = _bt_get_adapter_proxy();
564 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
566 arr = g_array_new(TRUE, TRUE, sizeof(guint8));
568 for (i = 0; i < length; i++)
569 g_array_append_vals(arr, &(response->data[i]), sizeof(guint8));
571 slot_id = __bt_get_available_adv_slot_id(sender, use_reserved_slot);
573 BT_ERR("There is NO available slot!!");
574 return BLUETOOTH_ERROR_NO_RESOURCES;
577 dbus_g_proxy_call(proxy, "SetScanRespData", &error,
578 DBUS_TYPE_G_UCHAR_ARRAY, arr,
580 G_TYPE_INVALID, G_TYPE_INVALID);
582 g_array_free(arr, TRUE);
585 BT_ERR("SetScanRespData Fail: %s", error->message);
587 return BLUETOOTH_ERROR_INTERNAL;
590 __bt_register_adv_slot_owner(sender, slot_id);
592 /* Compare with previous scan resp data */
593 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
594 &old_mdata, &old_len);
595 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
596 &new_mdata, &new_len);
597 if (old_len != new_len ||
598 (old_mdata && new_mdata &&
599 memcmp(old_mdata, new_mdata, new_len))) {
600 _bt_send_event(BT_ADAPTER_EVENT,
601 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
602 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
609 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
610 memcpy(&resp_data, response, length);
611 resp_data_len = length;
613 BT_INFO("Set scan response data");
614 return BLUETOOTH_ERROR_NONE;
617 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
620 GError *error = NULL;
624 BT_CHECK_PARAMETER(params, return);
626 if (_bt_adapter_get_status() != BT_ACTIVATED &&
627 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
628 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
631 proxy = _bt_get_adapter_proxy();
632 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
634 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
635 return BLUETOOTH_ERROR_INVALID_PARAM;
637 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
638 return BLUETOOTH_ERROR_INVALID_PARAM;
640 if (params->window > params->interval)
641 return BLUETOOTH_ERROR_INVALID_PARAM;
643 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
644 win = params->window / BT_ADV_INTERVAL_SPLIT;
646 dbus_g_proxy_call(proxy, "SetScanParameters", &error,
647 G_TYPE_UINT, params->type,
650 G_TYPE_INVALID, G_TYPE_INVALID);
653 BT_ERR("SetScanParameters Fail: %s", error->message);
655 return BLUETOOTH_ERROR_INTERNAL;
658 _bt_set_le_discovery_type(params->type);
660 BT_INFO("Set scan parameters");
661 return BLUETOOTH_ERROR_NONE;
664 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
667 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
668 GError *error = NULL;
670 if (__bt_is_factory_test_mode()) {
671 BT_ERR("Unable to add white list in factory binary !!");
672 return BLUETOOTH_ERROR_NOT_SUPPORT;
675 BT_CHECK_PARAMETER(device_address, return);
677 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
678 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
679 return BLUETOOTH_ERROR_INVALID_PARAM;
681 _bt_convert_addr_type_to_string(address, device_address->addr);
683 proxy = _bt_get_adapter_proxy();
684 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
686 dbus_g_proxy_call(proxy, "AddDeviceWhiteList", &error,
687 G_TYPE_STRING, address,
688 G_TYPE_UINT, address_type,
689 G_TYPE_INVALID, G_TYPE_INVALID);
692 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
694 return BLUETOOTH_ERROR_INTERNAL;
697 BT_INFO("Add white list");
699 return BLUETOOTH_ERROR_NONE;
702 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
705 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
706 GError *error = NULL;
708 if (__bt_is_factory_test_mode()) {
709 BT_ERR("Unable to remove white list in factory binary !!");
710 return BLUETOOTH_ERROR_NOT_SUPPORT;
713 BT_CHECK_PARAMETER(device_address, return);
715 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
716 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
717 return BLUETOOTH_ERROR_INVALID_PARAM;
719 _bt_convert_addr_type_to_string(address, device_address->addr);
721 proxy = _bt_get_adapter_proxy();
722 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
724 dbus_g_proxy_call(proxy, "RemoveDeviceWhiteList", &error,
725 G_TYPE_STRING, address,
726 G_TYPE_UINT, address_type,
727 G_TYPE_INVALID, G_TYPE_INVALID);
730 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
732 return BLUETOOTH_ERROR_INTERNAL;
735 BT_INFO("Remove white list");
737 return BLUETOOTH_ERROR_NONE;
740 int _bt_clear_white_list(void)
743 GError *error = NULL;
745 if (__bt_is_factory_test_mode()) {
746 BT_ERR("Unable to clear white list in factory binary !!");
747 return BLUETOOTH_ERROR_NOT_SUPPORT;
750 proxy = _bt_get_adapter_proxy();
751 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
753 dbus_g_proxy_call(proxy, "ClearDeviceWhiteList", &error,
754 G_TYPE_INVALID, G_TYPE_INVALID);
757 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
759 return BLUETOOTH_ERROR_INTERNAL;
762 BT_INFO("Clear white list");
764 return BLUETOOTH_ERROR_NONE;