diff --git a/components/bt/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/bluedroid/bta/gatt/bta_gattc_act.c index 5a25ebafde..8c75f131ae 100644 --- a/components/bt/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/bluedroid/bta/gatt/bta_gattc_act.c @@ -2173,7 +2173,7 @@ void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg) cb_data.reg_oper.client_if = p_msg->api_listen.client_if; cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start, NULL); - + //TODO need modify callback if used if (p_clreg && p_clreg->p_cback) { (*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data); } diff --git a/components/bt/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/bluedroid/stack/btm/btm_ble_gap.c index 259e463696..7fd15ef6ea 100644 --- a/components/bt/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/bluedroid/stack/btm/btm_ble_gap.c @@ -517,7 +517,13 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s evt_type = p_cb->scan_rsp ? BTM_BLE_CONNECT_EVT : BTM_BLE_NON_CONNECT_EVT; } #endif - + // if adv state is BTM_BLE_ADV_PENDING, return immediately + if (p_cb->state == BTM_BLE_ADV_PENDING) { + if (p_stop_adv_cback) { + (*p_stop_adv_cback)(HCI_ERR_ILLEGAL_COMMAND); + } + return BTM_BUSY; + } if (start && p_cb->adv_mode == BTM_BLE_ADV_DISABLE) { /* update adv params */ if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : @@ -538,7 +544,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s } status = btm_ble_start_adv (); - } else if (!start) { + } else if (!start && p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { //save the stop adv callback to the BTM env. p_cb->p_stop_adv_cb = p_stop_adv_cback; status = btm_ble_stop_adv(); @@ -546,9 +552,14 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, TRUE); #endif } else { - status = BTM_WRONG_MODE; - BTM_TRACE_ERROR("Can not %s Broadcast, device %s in Broadcast mode", - (start ? "Start" : "Stop"), (start ? "already" : "not")); + /* + 1. start adv when adv has already started (not used) + 2. stop adv shen adv has already stoped + */ + status = BTM_SUCCESS; + if (p_stop_adv_cback) { + (*p_stop_adv_cback)(status); + } } return status; } @@ -1217,8 +1228,23 @@ tBTM_STATUS BTM_BleSetAdvParamsStartAdv(UINT16 adv_int_min, UINT16 adv_int_max, } BTM_TRACE_EVENT ("update params for an active adv\n"); - - btm_ble_stop_adv(); + // if adv state is BTM_BLE_ADV_PENDING, return immediately + if (p_cb->state == BTM_BLE_ADV_PENDING) { + if (p_cb->p_adv_cb) { + (*p_cb->p_adv_cb)(HCI_ERR_ILLEGAL_COMMAND); + } + return BTM_BUSY; + } + /* host will stop adv first and then start adv again if adv has already started + it will get callback twice. + */ + if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { + p_cb->adv_callback_twice = TRUE; + } + tBTM_STATUS status = btm_ble_stop_adv(); + if (status != BTM_SUCCESS) { + p_cb->adv_callback_twice = FALSE; + } /* update adv params */ btsnd_hcic_ble_write_adv_params (adv_int_min, @@ -3360,7 +3386,7 @@ tBTM_STATUS btm_ble_start_adv(void) if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE)) { p_cb->adv_mode = BTM_BLE_ADV_ENABLE; - p_cb->state = BTM_BLE_ADVERTISING; + p_cb->state = BTM_BLE_ADV_PENDING; btm_ble_adv_states_operation(btm_ble_set_topology_mask, p_cb->evt_type); rt = BTM_SUCCESS; BTM_TRACE_EVENT ("BTM_SUCCESS\n"); @@ -3389,7 +3415,7 @@ tBTM_STATUS btm_ble_stop_adv(void) if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) { p_cb->fast_adv_on = FALSE; p_cb->adv_mode = BTM_BLE_ADV_DISABLE; - p_cb->state = BTM_BLE_STOP_ADV; + p_cb->state = BTM_BLE_ADV_PENDING; btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV; /* clear all adv states */ @@ -3563,9 +3589,23 @@ void btm_ble_write_adv_enable_complete(UINT8 *p) // callback to the APP after receive the adv complete from the controller. if (p_cb->p_adv_cb && p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { - (*p_cb->p_adv_cb)(status); + if (p_cb->adv_callback_twice) { + p_cb->adv_callback_twice = FALSE; + }else { + p_cb->state = BTM_BLE_ADVERTISING; + (*p_cb->p_adv_cb)(status); + } } else if (p_cb->p_stop_adv_cb && p_cb->adv_mode == BTM_BLE_ADV_DISABLE) { + p_cb->state = BTM_BLE_STOP_ADV; (*p_cb->p_stop_adv_cb)(status); + }else { + // p_cb->p_adv_cb is NULL or p_cb->p_stop_adv_cb is NULL + if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) { + p_cb->state = BTM_BLE_ADVERTISING; + }else { + p_cb->state = BTM_BLE_STOP_ADV; + } + p_cb->adv_callback_twice = FALSE; } /* if write adv enable/disbale not succeed */ if (*p != HCI_SUCCESS) { diff --git a/components/bt/bluedroid/stack/include/btm_ble_int.h b/components/bt/bluedroid/stack/include/btm_ble_int.h index f5b6c90b15..a88108d737 100644 --- a/components/bt/bluedroid/stack/include/btm_ble_int.h +++ b/components/bt/bluedroid/stack/include/btm_ble_int.h @@ -150,6 +150,7 @@ typedef struct { tBTM_START_ADV_CMPL_CBACK *p_adv_cb; tBTM_START_STOP_ADV_CMPL_CBACK *p_stop_adv_cb; tBLE_ADDR_TYPE adv_addr_type; + BOOLEAN adv_callback_twice; UINT8 evt_type; UINT8 adv_mode; tBLE_BD_ADDR direct_bda;