diff --git a/src/l2cap.c b/src/l2cap.c index 770a8eae5..adedf9fb9 100644 --- a/src/l2cap.c +++ b/src/l2cap.c @@ -1168,6 +1168,35 @@ uint8_t l2cap_create_channel(btstack_packet_handler_t channel_packet_handler, bd #ifdef ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE +static uint8_t l2cap_ertm_validate_local_config(uint8_t max_transmit, uint16_t retransmission_timeout_ms, + uint16_t monitor_timeout_ms, uint8_t num_tx_buffers, uint8_t num_rx_buffers, uint8_t * buffer, uint32_t size){ + UNUSED(buffer); + UNUSED(size); + + uint8_t result = ERROR_CODE_SUCCESS; + if (max_transmit < 1){ + log_error("max_transmit must be >= 1"); + result = ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } + if (retransmission_timeout_ms < 2000){ + log_error("retransmission_timeout_ms must be >= 2000 ms"); + result = ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } + if (monitor_timeout_ms < 12000){ + log_error("monitor_timeout_ms must be >= 12000 ms"); + result = ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } + if (num_rx_buffers < 1){ + log_error("num_rx_buffers must be >= 1"); + result = ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } + if (num_tx_buffers < 1){ + log_error("num_rx_buffers must be >= 1"); + result = ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } + return result; +} + static void l2cap_ertm_configure_channel(l2cap_channel_t * channel, int ertm_mandatory, uint8_t max_transmit, uint16_t retransmission_timeout_ms, uint16_t monitor_timeout_ms, uint8_t num_tx_buffers, uint8_t num_rx_buffers, uint8_t * buffer, uint32_t size){ @@ -1203,6 +1232,10 @@ uint8_t l2cap_create_ertm_channel(btstack_packet_handler_t packet_handler, bd_ad log_info("L2CAP_CREATE_CHANNEL addr %s psm 0x%x -> local mtu %u", bd_addr_to_str(address), psm, local_mtu); + // validate local config + uint8_t result = l2cap_ertm_validate_local_config(max_transmit, retransmission_timeout_ms, monitor_timeout_ms, num_tx_buffers, num_rx_buffers, buffer, size); + if (result) return result; + l2cap_channel_t * channel = l2cap_create_channel_entry(packet_handler, address, BD_ADDR_TYPE_CLASSIC, psm, local_mtu, LEVEL_0); if (!channel) { return BTSTACK_MEMORY_ALLOC_FAILED; @@ -1575,16 +1608,20 @@ void l2cap_accept_connection(uint16_t local_cid){ #ifdef ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE -void l2cap_accept_ertm_connection(uint16_t local_cid, int ertm_mandatory, uint8_t max_transmit, +uint8_t l2cap_accept_ertm_connection(uint16_t local_cid, int ertm_mandatory, uint8_t max_transmit, uint16_t retransmission_timeout_ms, uint16_t monitor_timeout_ms, uint8_t num_tx_buffers, uint8_t num_rx_buffers, uint8_t * buffer, uint32_t size){ log_info("L2CAP_ACCEPT_ERTM_CONNECTION local_cid 0x%x", local_cid); l2cap_channel_t * channel = l2cap_get_channel_for_local_cid(local_cid); if (!channel) { log_error("l2cap_accept_connection called but local_cid 0x%x not found", local_cid); - return; + return L2CAP_LOCAL_CID_DOES_NOT_EXIST; } + // validate local config + uint8_t result = l2cap_ertm_validate_local_config(max_transmit, retransmission_timeout_ms, monitor_timeout_ms, num_tx_buffers, num_rx_buffers, buffer, size); + if (result) return result; + // configure L2CAP ERTM l2cap_ertm_configure_channel(channel, ertm_mandatory, max_transmit, retransmission_timeout_ms, monitor_timeout_ms, num_tx_buffers, num_rx_buffers, buffer, size); @@ -1593,6 +1630,8 @@ void l2cap_accept_ertm_connection(uint16_t local_cid, int ertm_mandatory, uint8_ // process l2cap_run(); + + return ERROR_CODE_SUCCESS; } #endif diff --git a/src/l2cap.h b/src/l2cap.h index 20688ff6a..8ea337028 100644 --- a/src/l2cap.h +++ b/src/l2cap.h @@ -364,8 +364,9 @@ void l2cap_accept_connection(uint16_t local_cid); * @param num_rx_buffers Number of packets that can be received out of order (-> our tx_window size) * @param buffer to store out-of-order packets and unacknowledged outgoing packets with their tretransmission timers * @param size of buffer + * @return status */ -void l2cap_accept_ertm_connection(uint16_t local_cid, int ertm_mandatory, uint8_t max_transmit, +uint8_t l2cap_accept_ertm_connection(uint16_t local_cid, int ertm_mandatory, uint8_t max_transmit, uint16_t retransmission_timeout_ms, uint16_t monitor_timeout_ms, uint8_t num_tx_buffers, uint8_t num_rx_buffers, uint8_t * buffer, uint32_t size); /**