X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-service%2Fbt-service-adapter-le.c;h=7566c484b0e67b23f998adafd2b5e74ef34b15be;hb=1fa07edcd0e77a445700975773db3300f556caf5;hp=56a2ff8020ab8217ca1e1424a893957e2c1e3024;hpb=c7fc7ee21bbbf183f5c65b5305105854b9d19dd3;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-service/bt-service-adapter-le.c b/bt-service/bt-service-adapter-le.c index 56a2ff8..7566c48 100644 --- a/bt-service/bt-service-adapter-le.c +++ b/bt-service/bt-service-adapter-le.c @@ -41,7 +41,6 @@ #define BT_ADV_FILTER_POLICY_DEFAULT 0x00 #define BT_ADV_TYPE_DEFAULT 0x00 #define BT_ADV_FILTER_POLICY_ALLOW_SCAN_CONN_WL_ONLY 0x03 -#define BT_ADV_MULTI_MAX 16 typedef struct { int adv_inst_max; @@ -60,6 +59,7 @@ typedef struct { char *sender; GSList *filter_list; gboolean is_scanning; + gboolean stop_pending; } bt_adapter_le_scanner_t; static bluetooth_advertising_params_t adv_params = { @@ -178,16 +178,27 @@ void __bt_free_le_adv_slot(void) le_adv_slot = NULL; } -int _bt_service_adapter_le_init(void) +int _bt_le_set_max_packet_len(void) { - le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max); + int result = BLUETOOTH_ERROR_NONE; + int tx_octets, tx_time; + bluetooth_le_read_maximum_data_length_t max_len = {0}; - return BLUETOOTH_ERROR_NONE; -} + if (BLUETOOTH_ERROR_NONE != _bt_le_read_maximum_data_length(&max_len)) + return BLUETOOTH_ERROR_INTERNAL; -void _bt_service_adapter_le_deinit(void) -{ - __bt_free_le_adv_slot(); + if (max_len.max_tx_octets > BT_LE_TX_LEN_DEFAULT) { + tx_octets = max_len.max_tx_octets > BT_LE_TX_LEN_MAX ? + BT_LE_TX_LEN_MAX : max_len.max_tx_octets; + tx_time = BT_LE_TX_TIME_MAX; + + result = _bt_le_write_host_suggested_default_data_length(tx_octets, tx_time); + + BT_DBG("Wrote max packet size : result[%d], MAX[%d], set[%d]", + result, max_len.max_tx_octets, tx_octets); + } + + return result; } gboolean _bt_update_le_feature_support(const char *item, const char *value) @@ -195,12 +206,14 @@ gboolean _bt_update_le_feature_support(const char *item, const char *value) if (item == NULL || value == NULL) return FALSE; + if (!le_adv_slot) + _bt_service_adapter_le_init(); + if (g_strcmp0(item, "adv_inst_max") == 0) { int slot_num; slot_num = atoi(value); retv_if(slot_num < 0, FALSE); - retv_if(slot_num > BT_ADV_MULTI_MAX, FALSE); if (slot_num != le_feature_info.adv_inst_max) { __bt_free_le_adv_slot(); @@ -257,10 +270,10 @@ int __bt_get_available_adv_slot_id(const char *sender, int adv_handle, gboolean return i; } - if (le_feature_info.adv_inst_max <= 2) - i = 0; - else if (le_feature_info.adv_inst_max > 2 && use_reserved_slot == TRUE) + if (le_feature_info.adv_inst_max <= 1) i = 0; + else if (use_reserved_slot == TRUE) + i = 1; else i = 2; @@ -282,6 +295,11 @@ static void __bt_register_adv_slot_owner(const char *sender, int adv_handle, int void _bt_unregister_adv_slot_owner(int slot_id) { + if (le_adv_slot[slot_id].hold_timer_id > 0) { + BT_INFO("Hold state adv is not unregistered"); + return; + } + g_free(le_adv_slot[slot_id].sender); le_adv_slot[slot_id].sender = NULL; le_adv_slot[slot_id].adv_handle = 0; @@ -313,6 +331,9 @@ gboolean _bt_is_advertising(void) gboolean status = FALSE; int i; + if (le_adv_slot == NULL) + return FALSE; + for (i = 0; i < le_feature_info.adv_inst_max; i++) { if (le_adv_slot[i].is_advertising == TRUE) status = TRUE; @@ -374,14 +395,15 @@ int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gbo if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE) return BLUETOOTH_ERROR_IN_PROGRESS; - if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE) - return BLUETOOTH_ERROR_NOT_IN_OPERATION; - if (le_adv_slot[slot_id].hold_timer_id > 0) { g_source_remove(le_adv_slot[slot_id].hold_timer_id); le_adv_slot[slot_id].hold_timer_id = 0; + _bt_unregister_adv_slot_owner(slot_id); } + if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE) + return BLUETOOTH_ERROR_NOT_IN_OPERATION; + proxy = _bt_get_adapter_proxy(); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -393,6 +415,7 @@ int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gbo &error); if (error) { + BT_INFO("SetAdvertising %d, slot_id %d", enable, slot_id); BT_ERR("SetAdvertising Fail: %s", error->message); g_clear_error(&error); return BLUETOOTH_ERROR_INTERNAL; @@ -441,14 +464,15 @@ int _bt_set_custom_advertising(const char *sender, int adv_handle, if (le_adv_slot[slot_id].is_advertising == TRUE && enable == TRUE) return BLUETOOTH_ERROR_IN_PROGRESS; - if (le_adv_slot[slot_id].sender != NULL && le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE) - return BLUETOOTH_ERROR_NOT_IN_OPERATION; - if (le_adv_slot[slot_id].hold_timer_id > 0) { g_source_remove(le_adv_slot[slot_id].hold_timer_id); le_adv_slot[slot_id].hold_timer_id = 0; + _bt_unregister_adv_slot_owner(slot_id); } + if (le_adv_slot[slot_id].is_advertising == FALSE && enable == FALSE) + return BLUETOOTH_ERROR_NOT_IN_OPERATION; + proxy = _bt_get_adapter_proxy(); retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL); @@ -465,14 +489,18 @@ int _bt_set_custom_advertising(const char *sender, int adv_handle, params->type == BLUETOOTH_ADV_NON_CONNECTABLE) return BLUETOOTH_ERROR_NOT_SUPPORT; + if (params->tx_power_level > 1 || + params->tx_power_level < -127) + return BLUETOOTH_ERROR_INVALID_PARAM; + min = params->interval_min / BT_ADV_INTERVAL_SPLIT; max = params->interval_max / BT_ADV_INTERVAL_SPLIT; ret = g_dbus_proxy_call_sync(proxy, "SetAdvertisingParameters", - g_variant_new("(uuuui)", min, max, + g_variant_new("(uuuuii)", min, max, params->filter_policy, params->type, - slot_id), G_DBUS_CALL_FLAGS_NONE, - -1, NULL, &error); + params->tx_power_level, slot_id), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error) { BT_ERR("SetAdvertisingParameters Fail: %s", error->message); @@ -484,6 +512,7 @@ int _bt_set_custom_advertising(const char *sender, int adv_handle, adv_params.interval_max = params->interval_max; adv_params.filter_policy = params->filter_policy; adv_params.type = params->type; + adv_params.tx_power_level = params->tx_power_level; if (ret) g_variant_unref(ret); @@ -503,8 +532,6 @@ int _bt_set_custom_advertising(const char *sender, int adv_handle, if (enable == TRUE) __bt_register_adv_slot_owner(sender, adv_handle, slot_id); - else - _bt_unregister_adv_slot_owner(slot_id); le_adv_slot[slot_id].is_advertising = enable; BT_INFO_C("### Set advertising [%d], Slot id [%d]", enable, slot_id); @@ -1351,6 +1378,15 @@ int _bt_unregister_all_scan_filters(const char *sender) return BLUETOOTH_ERROR_NONE; } +static gboolean __start_le_scan_timeout(gpointer user_data) +{ + char *sender = (char *)user_data; + _bt_start_le_scan(sender); + + return FALSE; +} + + int _bt_start_le_scan(const char *sender) { GDBusProxy *proxy; @@ -1364,6 +1400,12 @@ int _bt_start_le_scan(const char *sender) scanner_list = g_slist_append(scanner_list, scanner); } + if (scanner->stop_pending == TRUE) { + BT_DBG("Waiting LEDiscoveryFinished"); + g_timeout_add(500, (GSourceFunc)__start_le_scan_timeout, scanner->sender); + return BLUETOOTH_ERROR_NONE; + } + if (scanner->is_scanning == TRUE) { BT_ERR("BT is already in LE scanning"); return BLUETOOTH_ERROR_IN_PROGRESS; @@ -1381,7 +1423,7 @@ int _bt_start_le_scan(const char *sender) G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error) { - BT_ERR("scan_filter_clear Fail: %s", error->message); + BT_ERR("scan_filter_enable Fail: %s", error->message); g_clear_error(&error); } @@ -1415,7 +1457,7 @@ int _bt_start_le_scan(const char *sender) G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error) { - BT_ERR("scan_filter_clear Fail: %s", error->message); + BT_ERR("scan_filter_enable Fail: %s", error->message); g_clear_error(&error); } @@ -1446,15 +1488,17 @@ int _bt_stop_le_scan(const char *sender) GDBusProxy *proxy; GError *error = NULL; GVariant *ret; - bt_adapter_le_scanner_t *scanner = __bt_find_scanner_from_list(sender); + bt_adapter_le_scanner_t *scan_sender = __bt_find_scanner_from_list(sender); + bt_adapter_le_scanner_t *scanner; GSList *l; gboolean next_scanning = FALSE; gboolean need_scan_filter = TRUE; - if (scanner == NULL || scanner->is_scanning == FALSE) + if (scan_sender == NULL || scan_sender->is_scanning == FALSE) return BLUETOOTH_ERROR_NOT_IN_OPERATION; - scanner->is_scanning = FALSE; + scan_sender->is_scanning = FALSE; + scan_sender->stop_pending = TRUE; for (l = scanner_list; l != NULL; l = g_slist_next(l)) { scanner = l->data; @@ -1476,7 +1520,7 @@ int _bt_stop_le_scan(const char *sender) -1, NULL, &error); if (error) { - BT_ERR("scan_filter_clear Fail: %s", error->message); + BT_ERR("scan_filter_enable Fail: %s", error->message); g_clear_error(&error); } @@ -1485,6 +1529,8 @@ int _bt_stop_le_scan(const char *sender) BT_INFO("Enable LE Scan Filter"); scan_filter_enabled = TRUE; } + BT_INFO("next_scanning exists. Keep the LE scanning"); + scan_sender->stop_pending = FALSE; return BLUETOOTH_ERROR_NONE; } else { if (scan_filter_enabled == TRUE) { @@ -1494,7 +1540,7 @@ int _bt_stop_le_scan(const char *sender) -1, NULL, &error); if (error) { - BT_ERR("scan_filter_clear Fail: %s", error->message); + BT_ERR("scan_filter_enable Fail: %s", error->message); g_clear_error(&error); } @@ -1509,6 +1555,11 @@ int _bt_stop_le_scan(const char *sender) ret = g_dbus_proxy_call_sync(proxy, "StopLEDiscovery", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + BT_ERR("StopLEDiscovery Fail: %s", error->message); + g_clear_error(&error); + } + if (ret == NULL) { BT_ERR("LE Scan stop failed"); return BLUETOOTH_ERROR_INTERNAL; @@ -1529,11 +1580,33 @@ void _bt_disable_all_scanner_status(void) for (l = scanner_list; l != NULL; l = g_slist_next(l)) { scanner = l->data; scanner->is_scanning = FALSE; + scanner->stop_pending = FALSE; } } +static void __bt_free_le_scanner(void) +{ + GSList *l; + bt_adapter_le_scanner_t *scanner; + + for (l = scanner_list; l != NULL; l = g_slist_next(l)) { + scanner = l->data; + g_free(scanner->sender); + g_slist_free_full(scanner->filter_list, g_free); + g_free(scanner); + } + + g_slist_free(scanner_list); + scanner_list = NULL; + + scan_filter_enabled = FALSE; + is_le_scanning = FALSE; + is_le_set_scan_parameter = FALSE; +} + void _bt_set_le_scan_status(gboolean mode) { + BT_DBG("set is_le_scanning : %d -> %d", is_le_scanning, mode); is_le_scanning = mode; } @@ -2157,8 +2230,6 @@ int _bt_le_read_maximum_data_length( reply = g_dbus_proxy_call_sync(proxy, "LEReadMaximumDataLength", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); - g_object_unref(proxy); - if (reply == NULL) { BT_ERR("LEReadMaximumDataLength dBUS-RPC failed"); if (error != NULL) { @@ -2199,8 +2270,6 @@ int _bt_le_write_host_suggested_default_data_length( NULL, &error); - g_object_unref(proxy); - if (reply == NULL) { BT_ERR("_bt_le_write_host_suggested_default_data_length dBUS-RPC failed"); if (error != NULL) { @@ -2302,3 +2371,16 @@ int _bt_le_set_data_length(bluetooth_device_address_t *device_address, return BLUETOOTH_ERROR_NONE; } + +int _bt_service_adapter_le_init(void) +{ + le_adv_slot = g_malloc0(sizeof(bt_adapter_le_adv_slot_t) * le_feature_info.adv_inst_max); + + return BLUETOOTH_ERROR_NONE; +} + +void _bt_service_adapter_le_deinit(void) +{ + __bt_free_le_adv_slot(); + __bt_free_le_scanner(); +}