From 501329fabaf55edfa9e2b88a4c04141f069bbd13 Mon Sep 17 00:00:00 2001 From: Matthias Ringwald Date: Thu, 13 Jul 2017 15:27:27 +0200 Subject: [PATCH] l2cap-ertm: add ERTM configuration options to create and accept l2cap connection API --- src/l2cap.c | 31 ++++++++++++++++++++++++++----- src/l2cap.h | 22 +++++++++++++++++++--- test/pts/l2cap_test.c | 7 ++++--- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/l2cap.c b/src/l2cap.c index 66d6bdb4b..fdb8e8ec4 100644 --- a/src/l2cap.c +++ b/src/l2cap.c @@ -1167,13 +1167,24 @@ uint8_t l2cap_create_channel(btstack_packet_handler_t channel_packet_handler, bd } #ifdef ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE -uint8_t l2cap_create_ertm_channel(btstack_packet_handler_t channel_packet_handler, bd_addr_t address, uint16_t psm, uint16_t mtu, int ertm_mandatory, uint16_t * out_local_cid){ +uint8_t l2cap_create_ertm_channel(btstack_packet_handler_t packet_handler, bd_addr_t address, uint16_t psm, + 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, uint16_t * out_local_cid){ + + UNUSED(max_transmit); + UNUSED(retransmission_timeout_ms); + UNUSED(monitor_timeout_ms); + UNUSED(num_rx_buffers); + UNUSED(num_tx_buffers); + UNUSED(buffer); + UNUSED(size); + // limit MTU to the size of our outtgoing HCI buffer - uint16_t local_mtu = btstack_min(mtu, l2cap_max_mtu()); + uint16_t local_mtu = l2cap_max_mtu(); - log_info("L2CAP_CREATE_CHANNEL addr %s psm 0x%x mtu %u -> local mtu %u", bd_addr_to_str(address), psm, mtu, local_mtu); + log_info("L2CAP_CREATE_CHANNEL addr %s psm 0x%x -> local mtu %u", bd_addr_to_str(address), psm, local_mtu); - l2cap_channel_t * channel = l2cap_create_channel_entry(channel_packet_handler, address, BD_ADDR_TYPE_CLASSIC, psm, local_mtu, LEVEL_0); + 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; } @@ -1544,7 +1555,17 @@ 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){ +void 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){ + + UNUSED(max_transmit); + UNUSED(retransmission_timeout_ms); + UNUSED(monitor_timeout_ms); + UNUSED(num_rx_buffers); + UNUSED(num_tx_buffers); + UNUSED(buffer); + UNUSED(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) { diff --git a/src/l2cap.h b/src/l2cap.h index ed37a9585..20750f711 100644 --- a/src/l2cap.h +++ b/src/l2cap.h @@ -273,12 +273,20 @@ uint8_t l2cap_create_channel(btstack_packet_handler_t packet_handler, bd_addr_t * @param packet_handler * @param address * @param psm - * @param mtu * @param ertm_mandatory If not mandatory, the use of ERTM can be decided by the remote + * @param max_transmit Number of retransmissions that L2CAP is allowed to try before accepting that a packet and the channel is lost. + * @param retransmission_timeout_ms Recommended : 2000 ms (ACL Flush timeout not used) + * @param monitor_timeout_ms Recommended: 12000 ms (ACL Flush timeout not used) + * @param num_tx_buffers Number of unacknowledged packets stored in buffer + * @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 * @param local_cid * @return status */ -uint8_t l2cap_create_ertm_channel(btstack_packet_handler_t packet_handler, bd_addr_t address, uint16_t psm, uint16_t mtu, int ertm_mandatory, uint16_t * out_local_cid); +uint8_t l2cap_create_ertm_channel(btstack_packet_handler_t packet_handler, bd_addr_t address, uint16_t psm, + 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, uint16_t * out_local_cid); /** * @brief Disconnects L2CAP channel with given identifier. @@ -313,8 +321,16 @@ void l2cap_accept_connection(uint16_t local_cid); /** * @brief Accepts incoming L2CAP connection for Enhanced Retransmission Mode * @param ertm_mandatory If not mandatory, the use of ERTM can be decided by the remote + * @param max_transmit Number of retransmissions that L2CAP is allowed to try before accepting that a packet and the channel is lost. Recommended: 1 + * @param retransmission_timeout_ms Recommended : 2000 ms (ACL Flush timeout not used) + * @param monitor_timeout_ms Recommended: 12000 ms (ACL Flush timeout not used) + * @param num_tx_buffers Number of unacknowledged packets stored in buffer + * @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 */ -void l2cap_accept_ertm_connection(uint16_t local_cid, int ertm_mandatory); +void 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); /** * @brief Deny incoming L2CAP connection. diff --git a/test/pts/l2cap_test.c b/test/pts/l2cap_test.c index 89ced51e8..484ce5c54 100644 --- a/test/pts/l2cap_test.c +++ b/test/pts/l2cap_test.c @@ -71,6 +71,7 @@ static int l2cap_ertm; static int l2cap_ertm_mandatory; static btstack_packet_callback_registration_t hci_event_callback_registration; +static uint8_t ertm_buffer[10000]; static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ @@ -112,7 +113,7 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack uint16_t l2cap_cid = little_endian_read_16(packet, 12); if (l2cap_ertm){ printf("L2CAP Accepting incoming connection request in ERTM\n"); - l2cap_accept_ertm_connection(l2cap_cid, l2cap_ertm_mandatory); + l2cap_accept_ertm_connection(l2cap_cid, l2cap_ertm_mandatory, 1, 2000, 12000, 4, 4, ertm_buffer, sizeof(ertm_buffer)); } else { printf("L2CAP Accepting incoming connection request in Basic Mode\n"); l2cap_accept_connection(l2cap_cid); @@ -153,9 +154,9 @@ static void stdin_process(char buffer){ case 'c': printf("Creating L2CAP Connection to %s, PSM SDP\n", bd_addr_to_str(remote)); if (l2cap_ertm){ - l2cap_create_ertm_channel(packet_handler, remote, BLUETOOTH_PROTOCOL_SDP, 100, l2cap_ertm_mandatory, NULL); + l2cap_create_ertm_channel(packet_handler, remote, BLUETOOTH_PROTOCOL_SDP, l2cap_ertm_mandatory, 1, 2000, 12000, 4, 4, ertm_buffer, sizeof(ertm_buffer), &local_cid); } else { - l2cap_create_channel(packet_handler, remote, BLUETOOTH_PROTOCOL_SDP, 100, NULL); + l2cap_create_channel(packet_handler, remote, BLUETOOTH_PROTOCOL_SDP, 100, &local_cid); } break; case 's':