NRF_ERROR_RESOURCES 발생하는 경우 패킷을 pending 슬롯에 저장, TX_RDY 이벤트에서만 재전송
- ios에서 BLE 연결 안정성 개선을 위함 - 기존: NRF_ERROR_RESOURCES 발생 시 2ms 간격으로 최대 20회 재시도
This commit is contained in:
@@ -562,6 +562,49 @@ extern void maa_async_abort(void);
|
||||
static volatile uint8_t pending_cmd_buf[BLE_NUS_MAX_DATA_LEN] = {0};
|
||||
static volatile uint8_t pending_cmd_len = 0;
|
||||
|
||||
static bool ble_retry_pending_tx(void)
|
||||
{
|
||||
uint16_t send_len;
|
||||
uint32_t err;
|
||||
|
||||
if (!s_tx_pending)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (ble_connection_st != BLE_CONNECTED_ST)
|
||||
{
|
||||
s_tx_pending = false;
|
||||
s_tx_pending_len = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
send_len = s_tx_pending_len;
|
||||
err = ble_nus_data_send(&m_nus, s_tx_pending_buf, &send_len, m_conn_handle);
|
||||
|
||||
if (err == NRF_SUCCESS)
|
||||
{
|
||||
s_tx_pending = false;
|
||||
s_tx_pending_len = 0;
|
||||
return true;
|
||||
}
|
||||
if (err == NRF_ERROR_RESOURCES)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (err == NRF_ERROR_INVALID_STATE || err == NRF_ERROR_NOT_FOUND)
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Pending send aborted\r\n");
|
||||
s_tx_pending = false;
|
||||
s_tx_pending_len = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
DBG_PRINTF("[BLE TX] Pending err:0x%X\r\n", err);
|
||||
s_tx_pending = false;
|
||||
s_tx_pending_len = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief NUS (Nordic UART Service) data receive handler
|
||||
*
|
||||
@@ -601,22 +644,20 @@ static void nus_data_handler(ble_nus_evt_t * p_evt)
|
||||
}
|
||||
else if (p_evt->type == BLE_NUS_EVT_TX_RDY)
|
||||
{
|
||||
/* First drain any queued packet that previously hit NRF_ERROR_RESOURCES. */
|
||||
if (s_tx_pending)
|
||||
{
|
||||
if (!ble_retry_pending_tx())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* BLE TX buffer has space - continue async MAA transmission */
|
||||
if (maa_async_is_busy())
|
||||
{
|
||||
maa_async_on_tx_ready();
|
||||
}
|
||||
/* Retry pending packet (dr_binary_tx_safe async) */
|
||||
else if (s_tx_pending)
|
||||
{
|
||||
uint16_t send_len = s_tx_pending_len;
|
||||
uint32_t err = ble_nus_data_send(&m_nus, s_tx_pending_buf, &send_len, m_conn_handle);
|
||||
if (err == NRF_SUCCESS)
|
||||
{
|
||||
s_tx_pending = false;
|
||||
}
|
||||
/* NRF_ERROR_RESOURCES -> retry on next TX_RDY */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1458,7 +1499,8 @@ void ascii_format_data(uint8_t *buffer, const char *tag, const char *data_ascii,
|
||||
/**
|
||||
* @brief BLE binary safe transmission (preamble for dr_binary_tx_safe)
|
||||
*
|
||||
* On NRF_ERROR_RESOURCES (TX queue full), retries at 5ms intervals.
|
||||
* On NRF_ERROR_RESOURCES (TX queue full), stores one pending packet and retries
|
||||
* only when BLE_NUS_EVT_TX_RDY is received.
|
||||
* Returns gracefully on connection errors.
|
||||
*
|
||||
* @param ble_bin_buff Data buffer to transmit
|
||||
@@ -1507,8 +1549,8 @@ void dr_binary_tx_safe(uint8_t const *ble_bin_buff, uint16_t length)
|
||||
{
|
||||
uint32_t err_code;
|
||||
static uint8_t tx_buffer[BLE_NUS_MAX_DATA_LEN] = {0};
|
||||
uint16_t retry_count = 0;
|
||||
const uint16_t MAX_RETRIES = 20; /* Max retries: 2ms x 20 = 40ms (was 5ms x 100 = 500ms) */
|
||||
uint16_t send_len;
|
||||
uint16_t total_len;
|
||||
|
||||
if (ble_connection_st == 0) return;
|
||||
|
||||
@@ -1521,37 +1563,36 @@ void dr_binary_tx_safe(uint8_t const *ble_bin_buff, uint16_t length)
|
||||
tx_buffer[length * sizeof(uint16_t)] = (uint8_t)(crc & 0xFF);
|
||||
tx_buffer[length * sizeof(uint16_t) + 1] = (uint8_t)((crc >> 8) & 0xFF);
|
||||
|
||||
uint16_t total_len = length * sizeof(uint16_t) + 2;
|
||||
total_len = length * sizeof(uint16_t) + 2;
|
||||
send_len = total_len;
|
||||
err_code = ble_nus_data_send(&m_nus, tx_buffer, &send_len, m_conn_handle);
|
||||
|
||||
do
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
uint16_t send_len = total_len;
|
||||
err_code = ble_nus_data_send(&m_nus, tx_buffer, &send_len, m_conn_handle);
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (err_code == NRF_ERROR_RESOURCES)
|
||||
{
|
||||
nrf_delay_ms(2); /* Was 5ms -> 2ms */
|
||||
retry_count++;
|
||||
}
|
||||
else if (err_code == NRF_ERROR_INVALID_STATE || err_code == NRF_ERROR_NOT_FOUND)
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Disconnected\r\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Err:0x%X\r\n", err_code);
|
||||
return;
|
||||
}
|
||||
} while (retry_count < MAX_RETRIES);
|
||||
|
||||
if (retry_count >= MAX_RETRIES)
|
||||
return;
|
||||
}
|
||||
else if (err_code == NRF_ERROR_RESOURCES)
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] FAIL %u retries\r\n", retry_count);
|
||||
if (s_tx_pending)
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Pending queue busy, dropping new packet\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(s_tx_pending_buf, tx_buffer, total_len);
|
||||
s_tx_pending_len = total_len;
|
||||
s_tx_pending = true;
|
||||
return;
|
||||
}
|
||||
else if (err_code == NRF_ERROR_INVALID_STATE || err_code == NRF_ERROR_NOT_FOUND)
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Disconnected\r\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Err:0x%X\r\n", err_code);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user