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 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
32 #include <syspopup_caller.h>
35 #include <notification.h>
36 #ifdef ENABLE_TIZEN_2_4
37 #include <journal/device.h>
40 #include "bt-internal-types.h"
41 #include "bt-service-common.h"
42 #include "bt-service-event.h"
43 #include "bt-service-adapter.h"
44 #include "bt-service-adapter-le.h"
47 #define BT_ADV_INTERVAL_MIN 20 /* msec */
48 #define BT_ADV_INTERVAL_MAX 10240
49 #define BT_ADV_INTERVAL_SPLIT 0.625
50 #define BT_DEFAULT_ADV_MIN_INTERVAL 500
51 #define BT_DEFAULT_ADV_MAX_INTERVAL 500
52 #define BT_ADV_FILTER_POLICY_DEFAULT 0x00
53 #define BT_ADV_TYPE_DEFAULT 0x00
54 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03
60 } bt_adapter_le_feature_info_t;
64 gboolean is_advertising;
65 } bt_adapter_le_adv_slot_t;
67 static bluetooth_advertising_params_t adv_params = {
68 BT_DEFAULT_ADV_MIN_INTERVAL,
69 BT_DEFAULT_ADV_MAX_INTERVAL,
70 BT_ADV_FILTER_POLICY_DEFAULT,
72 static bluetooth_advertising_data_t adv_data = { {0} };
73 static int adv_data_len;
74 static bluetooth_scan_resp_data_t resp_data = { {0} };
75 static int resp_data_len;
77 static bt_adapter_le_feature_info_t le_feature_info = { 1, 0, 0 };
78 static bt_adapter_le_adv_slot_t *le_adv_slot = NULL;
80 void __bt_free_le_adv_slot(void)
84 if (le_adv_slot == NULL)
87 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
88 if (le_adv_slot[i].sender)
89 g_free(le_adv_slot[i].sender);
95 int _bt_service_adapter_le_init(void)
97 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
99 return BLUETOOTH_ERROR_NONE;
102 void _bt_service_adapter_le_deinit(void)
104 __bt_free_le_adv_slot();
107 gboolean _bt_update_le_feature_support(const char *item, const char *value)
109 if (item== NULL || value == NULL)
112 if (g_strcmp0(item, "adv_inst_max") == 0) {
113 if (atoi(value) != le_feature_info.adv_inst_max) {
114 __bt_free_le_adv_slot();
115 le_feature_info.adv_inst_max = atoi(value);
116 le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max);
118 } else if (g_strcmp0(item, "rpa_offloading") == 0) {
119 le_feature_info.rpa_offloading = atoi(value);
120 } else if (g_strcmp0(item, "max_filter") == 0) {
121 le_feature_info.max_filter = atoi(value);
123 BT_DBG("No registered item");
130 static gboolean __bt_is_factory_test_mode(void)
133 #ifdef ENABLE_TIZEN_2_4
134 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
135 BT_ERR("Get the DUT Mode fail");
140 BT_INFO("DUT Test Mode !!");
147 int __bt_get_available_adv_slot_id(const char *sender, gboolean use_reserved_slot)
151 if (le_adv_slot == NULL)
154 if (use_reserved_slot == TRUE) {
155 if (le_feature_info.adv_inst_max > 1)
157 else if (le_adv_slot[0].sender == NULL ||
158 g_strcmp0(le_adv_slot[0].sender, sender) == 0)
164 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
165 if (le_adv_slot[i].sender == NULL)
167 if (g_strcmp0(le_adv_slot[i].sender, sender) == 0)
171 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
172 if (le_adv_slot[i].sender == NULL)
179 void __bt_register_adv_slot_owner(const char *sender, int slot_id)
181 if (le_adv_slot[slot_id].sender == NULL)
182 le_adv_slot[slot_id].sender = strdup(sender);
185 void __bt_unregister_adv_slot_owner(int slot_id)
187 g_free(le_adv_slot[slot_id].sender);
188 le_adv_slot[slot_id].sender = NULL;
189 le_adv_slot[slot_id].is_advertising = FALSE;
192 const char* _bt_get_adv_slot_owner(int slot_id)
194 if (le_adv_slot == NULL)
197 return le_adv_slot[slot_id].sender;
200 void _bt_set_advertising_status(int slot_id, gboolean mode)
202 le_adv_slot[slot_id].is_advertising = mode;
205 gboolean _bt_is_advertising(void)
207 gboolean status = FALSE;
210 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
211 if (le_adv_slot[i].is_advertising == TRUE)
218 void _bt_stop_advertising_by_terminated_process(const char* terminated_name)
222 if (le_adv_slot == NULL)
225 for (i = 0; i < le_feature_info.adv_inst_max; i++) {
226 if (le_adv_slot[i].sender != NULL) {
227 if (strcasecmp(terminated_name, le_adv_slot[i].sender) == 0) {
228 BT_ERR("Stop advertising by terminated process(%s).", terminated_name);
229 _bt_set_advertising(FALSE, terminated_name, FALSE);
235 gboolean _bt_get_advertising_params(bluetooth_advertising_params_t *params)
240 memcpy(params, &adv_params, sizeof(bluetooth_advertising_params_t));
245 int _bt_set_advertising(gboolean enable, const char *sender, gboolean use_reserved_slot)
248 GError *error = NULL;
251 if (__bt_is_factory_test_mode()) {
252 BT_ERR("Unable to start advertising in factory binary !!");
253 return BLUETOOTH_ERROR_NOT_SUPPORT;
256 if (_bt_adapter_get_status() != BT_ACTIVATED &&
257 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
258 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
261 slot_id = __bt_get_available_adv_slot_id(sender, use_reserved_slot);
263 BT_ERR("There is NO available slot!!");
264 return BLUETOOTH_ERROR_NO_RESOURCES;
267 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
268 return BLUETOOTH_ERROR_IN_PROGRESS;
270 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
271 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
273 proxy = _bt_get_adapter_proxy();
274 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
276 dbus_g_proxy_call(proxy, "SetAdvertising", &error,
277 G_TYPE_BOOLEAN, enable,
279 G_TYPE_INVALID, G_TYPE_INVALID);
282 BT_ERR("SetAdvertising Fail: %s", error->message);
284 return BLUETOOTH_ERROR_INTERNAL;
287 le_adv_slot[slot_id].is_advertising = enable;
290 __bt_register_adv_slot_owner(sender, slot_id);
292 __bt_unregister_adv_slot_owner(slot_id);
294 BT_INFO("Set advertising [%d]", enable);
296 return BLUETOOTH_ERROR_NONE;
299 int _bt_set_custom_advertising(gboolean enable, bluetooth_advertising_params_t *params,
300 const char *sender, gboolean use_reserved_slot)
303 GError *error = NULL;
308 BT_CHECK_PARAMETER(params, return);
310 if (__bt_is_factory_test_mode()) {
311 BT_ERR("Unable to start advertising in factory binary !!");
312 return BLUETOOTH_ERROR_NOT_SUPPORT;
315 if (_bt_adapter_get_status() != BT_ACTIVATED &&
316 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
317 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
320 if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE)
321 return BLUETOOTH_ERROR_IN_PROGRESS;
323 if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE)
324 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
326 proxy = _bt_get_adapter_proxy();
327 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
329 if (params->interval_min > params->interval_max ||
330 params->interval_min < BT_ADV_INTERVAL_MIN ||
331 params->interval_max > BT_ADV_INTERVAL_MAX)
332 return BLUETOOTH_ERROR_INVALID_PARAM;
334 if (params->filter_policy > BLUETOOTH_ALLOW_SCAN_CONN_WHITE_LIST)
335 return BLUETOOTH_ERROR_INVALID_PARAM;
337 if (params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_HIGH ||
338 params->type == BLUETOOTH_ADV_CONNECTABLE_DIRECT_LOW ||
339 params->type == BLUETOOTH_ADV_NON_CONNECTABLE)
340 return BLUETOOTH_ERROR_NOT_SUPPORT;
342 min = params->interval_min / BT_ADV_INTERVAL_SPLIT;
343 max = params->interval_max / BT_ADV_INTERVAL_SPLIT;
345 slot_id = __bt_get_available_adv_slot_id(sender, use_reserved_slot);
347 BT_ERR("There is NO available slot!!");
348 return BLUETOOTH_ERROR_NO_RESOURCES;
351 dbus_g_proxy_call(proxy, "SetAdvertisingParameters", &error,
354 G_TYPE_UINT, params->filter_policy,
355 G_TYPE_UINT, params->type,
357 G_TYPE_INVALID, G_TYPE_INVALID);
360 BT_ERR("SetAdvertisingParameters Fail: %s", error->message);
362 return BLUETOOTH_ERROR_INTERNAL;
365 adv_params.interval_min = params->interval_min;
366 adv_params.interval_max = params->interval_max;
367 adv_params.filter_policy = params->filter_policy;
368 adv_params.type= params->type;
370 dbus_g_proxy_call(proxy, "SetAdvertising", &error,
371 G_TYPE_BOOLEAN, enable,
373 G_TYPE_INVALID, G_TYPE_INVALID);
376 BT_ERR("SetAdvertising Fail: %s", error->message);
378 return BLUETOOTH_ERROR_INTERNAL;
381 le_adv_slot[slot_id].is_advertising = enable;
384 __bt_register_adv_slot_owner(sender, slot_id);
386 __bt_unregister_adv_slot_owner(slot_id);
388 BT_INFO_C("Set advertising [%d]", enable);
389 return BLUETOOTH_ERROR_NONE;
392 static int __bt_get_ad_data_by_type(char *in_data, int in_len,
393 char in_type, char **data, int *data_len)
395 if (in_data == NULL || data == NULL || data_len == NULL)
396 return BLUETOOTH_ERROR_INTERNAL;
399 return BLUETOOTH_ERROR_INTERNAL;
405 for (i = 0; i < in_len; i++) {
407 if (len <= 0 || i + 1 >= in_len) {
408 BT_ERR("Invalid advertising data");
409 return BLUETOOTH_ERROR_INTERNAL;
412 type = in_data[i + 1];
413 if (type == in_type) {
423 if (i + len > in_len) {
424 BT_ERR("Invalid advertising data");
425 return BLUETOOTH_ERROR_INTERNAL;
426 } else if (len == 0) {
427 BT_DBG("AD Type 0x%02x data is not set", in_type);
430 return BLUETOOTH_ERROR_NONE;
433 *data = g_memdup(&in_data[i], len);
435 return BLUETOOTH_ERROR_OUT_OF_MEMORY;
438 return BLUETOOTH_ERROR_NONE;
441 int _bt_get_advertising_data(bluetooth_advertising_data_t *adv, int *length)
443 BT_CHECK_PARAMETER(adv, return);
444 BT_CHECK_PARAMETER(length, return);
446 memcpy(adv, &adv_data, sizeof(adv_data));
447 *length = adv_data_len;
449 return BLUETOOTH_ERROR_NONE;
452 int _bt_set_advertising_data(bluetooth_advertising_data_t *adv, int length,
453 const char *sender, gboolean use_reserved_slot)
456 GError *error = NULL;
459 char *old_mdata = NULL;
460 char *new_mdata = NULL;
465 if (__bt_is_factory_test_mode()) {
466 BT_ERR("Unable to set advertising data in factory binary !!");
467 return BLUETOOTH_ERROR_NOT_SUPPORT;
470 BT_CHECK_PARAMETER(adv, return);
472 if (_bt_adapter_get_status() != BT_ACTIVATED &&
473 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
474 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
477 proxy = _bt_get_adapter_proxy();
478 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
480 arr = g_array_new(TRUE, TRUE, sizeof(guint8));
482 for (i = 0; i < length; i++)
483 g_array_append_vals(arr, &(adv->data[i]), sizeof(guint8));
485 slot_id = __bt_get_available_adv_slot_id(sender, use_reserved_slot);
487 BT_ERR("There is NO available slot!!");
488 return BLUETOOTH_ERROR_NO_RESOURCES;
491 dbus_g_proxy_call(proxy, "SetAdvertisingData", &error,
492 DBUS_TYPE_G_UCHAR_ARRAY, arr,
494 G_TYPE_INVALID, G_TYPE_INVALID);
496 g_array_free(arr, TRUE);
499 BT_ERR("SetAdvertisingData Fail: %s", error->message);
501 return BLUETOOTH_ERROR_INTERNAL;
504 __bt_register_adv_slot_owner(sender, slot_id);
506 __bt_get_ad_data_by_type((char *)adv_data.data, adv_data_len, 0xff,
507 &old_mdata, &old_len);
508 __bt_get_ad_data_by_type((char *)adv->data, length, 0xff,
509 &new_mdata, &new_len);
510 if (old_len != new_len ||
511 (old_mdata && new_mdata &&
512 memcmp(old_mdata, new_mdata, new_len))) {
513 _bt_send_event(BT_ADAPTER_EVENT,
514 BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
515 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
522 memset(&adv_data, 0x00, sizeof(bluetooth_advertising_data_t));
523 memcpy(&adv_data, adv, length);
524 adv_data_len = length;
526 BT_INFO("Set advertising data");
528 return BLUETOOTH_ERROR_NONE;
531 int _bt_get_scan_response_data(bluetooth_scan_resp_data_t *response, int *length)
533 BT_CHECK_PARAMETER(response, return);
534 BT_CHECK_PARAMETER(length, return);
536 memcpy(response, &resp_data, sizeof(resp_data));
537 *length = resp_data_len;
539 return BLUETOOTH_ERROR_NONE;
542 int _bt_set_scan_response_data(bluetooth_scan_resp_data_t *response, int length,
543 const char *sender, gboolean use_reserved_slot)
546 GError *error = NULL;
549 char *old_mdata = NULL;
550 char *new_mdata = NULL;
555 if (__bt_is_factory_test_mode()) {
556 BT_ERR("Unable to set scan response list in factory binary !!");
557 return BLUETOOTH_ERROR_NOT_SUPPORT;
560 BT_CHECK_PARAMETER(response, return);
562 if (_bt_adapter_get_status() != BT_ACTIVATED &&
563 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
564 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
567 proxy = _bt_get_adapter_proxy();
568 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
570 arr = g_array_new(TRUE, TRUE, sizeof(guint8));
572 for (i = 0; i < length; i++)
573 g_array_append_vals(arr, &(response->data[i]), sizeof(guint8));
575 slot_id = __bt_get_available_adv_slot_id(sender, use_reserved_slot);
577 BT_ERR("There is NO available slot!!");
578 return BLUETOOTH_ERROR_NO_RESOURCES;
581 dbus_g_proxy_call(proxy, "SetScanRespData", &error,
582 DBUS_TYPE_G_UCHAR_ARRAY, arr,
584 G_TYPE_INVALID, G_TYPE_INVALID);
586 g_array_free(arr, TRUE);
589 BT_ERR("SetScanRespData Fail: %s", error->message);
591 return BLUETOOTH_ERROR_INTERNAL;
594 __bt_register_adv_slot_owner(sender, slot_id);
596 /* Compare with previous scan resp data */
597 __bt_get_ad_data_by_type((char *)resp_data.data, resp_data_len, 0xff,
598 &old_mdata, &old_len);
599 __bt_get_ad_data_by_type((char *)response->data, length, 0xff,
600 &new_mdata, &new_len);
601 if (old_len != new_len ||
602 (old_mdata && new_mdata &&
603 memcmp(old_mdata, new_mdata, new_len))) {
604 _bt_send_event(BT_ADAPTER_EVENT,
605 BLUETOOTH_EVENT_SCAN_RESPONSE_MANUFACTURER_DATA_CHANGED,
606 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
613 memset(&resp_data, 0x00, sizeof(bluetooth_scan_resp_data_t));
614 memcpy(&resp_data, response, length);
615 resp_data_len = length;
617 BT_INFO("Set scan response data");
618 return BLUETOOTH_ERROR_NONE;
621 int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params)
624 GError *error = NULL;
628 BT_CHECK_PARAMETER(params, return);
630 if (_bt_adapter_get_status() != BT_ACTIVATED &&
631 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
632 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
635 proxy = _bt_get_adapter_proxy();
636 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
638 if (params->interval < BT_LE_SCAN_INTERVAL_MIN || params->interval > BT_LE_SCAN_INTERVAL_MAX)
639 return BLUETOOTH_ERROR_INVALID_PARAM;
641 if (params->window < BT_LE_SCAN_WINDOW_MIN || params->window > BT_LE_SCAN_WINDOW_MAX)
642 return BLUETOOTH_ERROR_INVALID_PARAM;
644 if (params->window > params->interval)
645 return BLUETOOTH_ERROR_INVALID_PARAM;
647 itv = params->interval / BT_ADV_INTERVAL_SPLIT;
648 win = params->window / BT_ADV_INTERVAL_SPLIT;
650 dbus_g_proxy_call(proxy, "SetScanParameters", &error,
651 G_TYPE_UINT, params->type,
654 G_TYPE_INVALID, G_TYPE_INVALID);
657 BT_ERR("SetScanParameters Fail: %s", error->message);
659 return BLUETOOTH_ERROR_INTERNAL;
662 _bt_set_le_discovery_type(params->type);
664 BT_INFO("Set scan parameters");
665 return BLUETOOTH_ERROR_NONE;
668 int _bt_add_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
671 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
672 GError *error = NULL;
674 if (__bt_is_factory_test_mode()) {
675 BT_ERR("Unable to add white list in factory binary !!");
676 return BLUETOOTH_ERROR_NOT_SUPPORT;
679 BT_CHECK_PARAMETER(device_address, return);
681 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
682 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
683 return BLUETOOTH_ERROR_INVALID_PARAM;
685 _bt_convert_addr_type_to_string(address, device_address->addr);
687 proxy = _bt_get_adapter_proxy();
688 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
690 dbus_g_proxy_call(proxy, "AddDeviceWhiteList", &error,
691 G_TYPE_STRING, address,
692 G_TYPE_UINT, address_type,
693 G_TYPE_INVALID, G_TYPE_INVALID);
696 BT_ERR("AddDeviceWhiteList Fail: %s", error->message);
698 return BLUETOOTH_ERROR_INTERNAL;
701 BT_INFO("Add white list");
703 return BLUETOOTH_ERROR_NONE;
706 int _bt_remove_white_list(bluetooth_device_address_t *device_address, bluetooth_device_address_type_t address_type)
709 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
710 GError *error = NULL;
712 if (__bt_is_factory_test_mode()) {
713 BT_ERR("Unable to remove white list in factory binary !!");
714 return BLUETOOTH_ERROR_NOT_SUPPORT;
717 BT_CHECK_PARAMETER(device_address, return);
719 if (address_type != BLUETOOTH_DEVICE_PUBLIC_ADDRESS &&
720 address_type != BLUETOOTH_DEVICE_RANDOM_ADDRESS)
721 return BLUETOOTH_ERROR_INVALID_PARAM;
723 _bt_convert_addr_type_to_string(address, device_address->addr);
725 proxy = _bt_get_adapter_proxy();
726 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
728 dbus_g_proxy_call(proxy, "RemoveDeviceWhiteList", &error,
729 G_TYPE_STRING, address,
730 G_TYPE_UINT, address_type,
731 G_TYPE_INVALID, G_TYPE_INVALID);
734 BT_ERR("RemoveDeviceWhiteList Fail: %s", error->message);
736 return BLUETOOTH_ERROR_INTERNAL;
739 BT_INFO("Remove white list");
741 return BLUETOOTH_ERROR_NONE;
744 int _bt_clear_white_list(void)
747 GError *error = NULL;
749 if (__bt_is_factory_test_mode()) {
750 BT_ERR("Unable to clear white list in factory binary !!");
751 return BLUETOOTH_ERROR_NOT_SUPPORT;
754 proxy = _bt_get_adapter_proxy();
755 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
757 dbus_g_proxy_call(proxy, "ClearDeviceWhiteList", &error,
758 G_TYPE_INVALID, G_TYPE_INVALID);
761 BT_ERR("ClearDeviceWhiteList Fail: %s", error->message);
763 return BLUETOOTH_ERROR_INTERNAL;
766 BT_INFO("Clear white list");
768 return BLUETOOTH_ERROR_NONE;