Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bluetooth: L2CAP_BR: Enable Retransmission and Flow control #78879

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 197 additions & 16 deletions include/zephyr/bluetooth/l2cap.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,42 +271,223 @@ struct bt_l2cap_le_chan {
*/
#define BT_L2CAP_LE_CHAN(_ch) CONTAINER_OF(_ch, struct bt_l2cap_le_chan, chan)

/** L2CAP Endpoint Link Mode. Basic mode. */
#define BT_L2CAP_BR_LINK_MODE_BASIC 0x00
/** L2CAP Endpoint Link Mode. Retransmission mode. */
#define BT_L2CAP_BR_LINK_MODE_RET 0x01
/** L2CAP Endpoint Link Mode. Flow control mode. */
#define BT_L2CAP_BR_LINK_MODE_FC 0x02
/** L2CAP Endpoint Link Mode. Enhance retransmission mode. */
#define BT_L2CAP_BR_LINK_MODE_ERET 0x03
/** L2CAP Endpoint Link Mode. Streaming mode. */
#define BT_L2CAP_BR_LINK_MODE_STREAM 0x04

/** Frame Check Sequence type. No FCS. */
#define BT_L2CAP_BR_FCS_NO 0x00
/** Frame Check Sequence type. 16-bit FCS. */
#define BT_L2CAP_BR_FCS_16BIT 0x01

/** @brief BREDR L2CAP Endpoint structure. */
struct bt_l2cap_br_endpoint {
/** Endpoint Channel Identifier (CID) */
uint16_t cid;
uint16_t cid;
/** Endpoint Maximum Transmission Unit */
uint16_t mtu;
uint16_t mtu;
#if defined(CONFIG_BT_L2CAP_RET) || defined(CONFIG_BT_L2CAP_FC) || \
defined(CONFIG_BT_L2CAP_ENH_RET) || defined(CONFIG_BT_L2CAP_STREAM)
/** Endpoint Link Mode.
* The value is defined as BT_L2CAP_BR_LINK_MODE_*
*/
uint8_t mode;
/** Whether Endpoint Link Mode is optional
* If the `optional` is true, the `mode` could be
* changed according to the extended feature and
* peer configuration from L2CAP configuration
* response and request.
* Otherwise, if the channel configuration process
* does not meet the set mode, the L2CAP channel
* will be disconnected.
*/
bool optional;
/** Endpoint Maximum Transmit
* The field is used to set the max retransmission
* count.
* For `RET`, `FC`, and `ERET`, it should be not
* less 1.
* For `STREAM`, it should be 0.
*/
uint8_t transmit;
/** Endpoint Retransmission Timeout
* The field is configured by
* `@kconfig{BT_L2CAP_BR_RET_TIMEOUT}`
* The field should be no more than the field
* `monitor_timeout`.
*/
uint16_t ret_timeout;
/** Endpoint Monitor Timeout
* The field is configured by
* `@kconfig{BT_L2CAP_BR_MONITOR_TIMEOUT}`
*/
uint16_t monitor_timeout;
/** Endpoint Maximum PDU payload Size */
uint16_t mps;
/** Endpoint Maximum Window Size
* MAX supported window size is configured by
* `@kconfig{BT_L2CAP_MAX_WINDOW_SIZE}`. The field
* should be no more then `CONFIG_BT_L2CAP_MAX_WINDOW_SIZE`.
*/
uint16_t window;
/** Endpoint FCS Type
* The value is defined as BT_L2CAP_BR_FCS_*
* The default setting should be BT_L2CAP_BR_FCS_16BIT.
* For FC and RET, the FCS type should be
* BT_L2CAP_BR_FCS_16BIT.
* For ERET and STREAM, the FCS type is optional. If
* the field is not default value, the local will include
* FCS option in configuration request packet if both side
* support `FCS Option`.
*/
uint8_t fcs;
/** Endpoint Extended Control.
* If this field is true, and both side support
* `Extended Window size feature`, the local will
* include `extended window size` option in configuration
* request packet.
*/
bool extended_control;
#endif
};

/** I-Frame transmission window for none `BASIC` mode L2cap connected channel. */
struct bt_l2cap_br_window {
sys_snode_t node;

/** tx seq */
uint16_t tx_seq;
/** data address */
uint8_t *data;
/** data len */
uint16_t len;
/** Transmit Counter */
uint8_t transmit_counter;
/** SAR flag */
uint8_t sar;
/** srej flag */
bool srej;
/* Save PDU state */
struct net_buf_simple_state sdu_state;
/** @internal Holds the sending buffer. */
struct net_buf *sdu;
/** @internal Total length of TX SDU */
uint16_t sdu_total_len;
};

/** @brief BREDR L2CAP Channel structure. */
struct bt_l2cap_br_chan {
/** Common L2CAP channel reference object */
struct bt_l2cap_chan chan;
struct bt_l2cap_chan chan;
/** Channel Receiving Endpoint */
struct bt_l2cap_br_endpoint rx;
struct bt_l2cap_br_endpoint rx;
/** Channel Transmission Endpoint */
struct bt_l2cap_br_endpoint tx;
struct bt_l2cap_br_endpoint tx;
/* For internal use only */
atomic_t flags[1];
atomic_t flags[1];

bt_l2cap_chan_state_t state;
bt_l2cap_chan_state_t state;
/** Remote PSM to be connected */
uint16_t psm;
uint16_t psm;
/** Helps match request context during CoC */
uint8_t ident;
bt_security_t required_sec_level;
uint8_t ident;
bt_security_t required_sec_level;

/* Response Timeout eXpired (RTX) timer */
struct k_work_delayable rtx_work;
struct k_work_sync rtx_sync;
struct k_work_delayable rtx_work;
struct k_work_sync rtx_sync;

/** @internal To be used with @ref bt_conn.upper_data_ready */
sys_snode_t _pdu_ready;
sys_snode_t _pdu_ready;
/** @internal To be used with @ref bt_conn.upper_data_ready */
atomic_t _pdu_ready_lock;
/** @internal Queue of net bufs not yet sent to lower layer */
struct k_fifo _pdu_tx_queue;
atomic_t _pdu_ready_lock;
/** @internal List of net bufs not yet sent to lower layer */
sys_slist_t _pdu_tx_queue;

#if defined(CONFIG_BT_L2CAP_RET) || defined(CONFIG_BT_L2CAP_FC) || \
defined(CONFIG_BT_L2CAP_ENH_RET) || defined(CONFIG_BT_L2CAP_STREAM)
/** @internal Total length of TX SDU */
uint16_t _sdu_total_len;

/** @internal Holds the remaining length of current sending buffer */
size_t _pdu_remaining;

/** @internal Holds the sending buffer. */
struct net_buf *_pdu_buf;

/** @internal TX windows for outstanding frame */
sys_slist_t _pdu_outstanding;

/** @internal PDU restore state */
struct net_buf_simple_state _pdu_state;

/** @internal Free TX windows */
struct k_fifo _free_tx_win;

/** @internal TX windows */
struct bt_l2cap_br_window tx_win[CONFIG_BT_L2CAP_MAX_WINDOW_SIZE];

/** Segment SDU packet from upper layer */
struct net_buf *_sdu;
/** @internal RX SDU */
uint16_t _sdu_len;
#if defined(CONFIG_BT_L2CAP_SEG_RECV)
uint16_t _sdu_len_done;
#endif /* CONFIG_BT_L2CAP_SEG_RECV */


/** @internal variables and sequence numbers */
/** @internal The sending peer uses the following variables and sequence
* numbers.
*/
/** @internal The send sequence number used to sequentially number each
* new I-frame transmitted.
*/
uint16_t tx_seq;
/** @internal The sequence number to be used in the next new I-frame
* transmitted.
*/
uint16_t next_tx_seq;
/** @internal The sequence number of the next I-frame expected to be
* acknowledged by the receiving peer.
*/
uint16_t expected_ack_seq;
/** @internal The receiving peer uses the following variables and sequence
* numbers.
*/
/** @internal The sequence number sent in an acknowledgment frame to
* request transmission of I-frame with TxSeq = ReqSeq and acknowledge
* receipt of I-frames up to and including (ReqSeq-1).
*/
uint16_t req_seq;
/** @internal The value of TxSeq expected in the next I-frame.
*/
uint16_t expected_tx_seq;
/** @internal When segmented I-frames are buffered this is used to delay
* acknowledgment of received I-frame so that new I-frame transmissions do
* not cause buffer overflow.
*/
uint16_t buffer_seq;

/** @internal States of Enhanced Retransmission Mode */
/** @internal Holds the number of times an S-frame operation is retried
*/
uint16_t retry_count;
/** @internal save the ReqSeq of a SREJ frame */
uint16_t srej_save_req_seq;

/** @internal Retransmission Timer */
struct k_work_delayable ret_work;
/** @internal Monitor Timer */
struct k_work_delayable monitor_work;
#endif
};

/** @brief L2CAP Channel operations structure.
Expand Down
81 changes: 81 additions & 0 deletions subsys/bluetooth/host/classic/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ config BT_CLASSIC
select BT_CENTRAL
select BT_SMP
select BT_L2CAP_DYNAMIC_CHANNEL
select CRC
select EXPERIMENTAL
help
This option enables Bluetooth BR/EDR support
Expand All @@ -26,6 +27,86 @@ config BT_MAX_SCO_CONN
Maximum number of simultaneous Bluetooth synchronous connections
supported. The minimum (and default) number is 1.

config BT_L2CAP_RET
bool "Bluetooth L2CAP retransmission mode [EXPERIMENTAL]"
select EXPERIMENTAL
help
This option enables Bluetooth L2CAP retransmission mode

config BT_L2CAP_FC
bool "Bluetooth L2CAP flow control mode [EXPERIMENTAL]"
select EXPERIMENTAL
help
This option enables Bluetooth L2CAP flow control mode

config BT_L2CAP_ENH_RET
bool "Bluetooth L2CAP enhance retransmission [EXPERIMENTAL]"
select EXPERIMENTAL
help
This option enables Bluetooth L2CAP enhance retransmission

config BT_L2CAP_STREAM
bool "Bluetooth L2CAP streaming mode [EXPERIMENTAL]"
select EXPERIMENTAL
help
This option enables Bluetooth L2CAP streaming mode
Comment on lines +30 to +52
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there really no interdependencies with these, i.e. all four of them can be enabled independently without depending on any other option?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I think they can be enabled independently.


config BT_L2CAP_FCS
bool "Bluetooth L2CAP FCS Option [EXPERIMENTAL]"
select EXPERIMENTAL
depends on BT_L2CAP_STREAM || BT_L2CAP_ENH_RET
help
This option enables Bluetooth L2CAP FCS Option

config BT_L2CAP_EXT_WIN_SIZE
bool "Bluetooth L2CAP Extended window size Option [EXPERIMENTAL]"
select EXPERIMENTAL
depends on BT_L2CAP_STREAM || BT_L2CAP_ENH_RET
help
This option enables Bluetooth L2CAP Extended window size Option

if BT_L2CAP_RET || BT_L2CAP_FC || BT_L2CAP_ENH_RET || BT_L2CAP_STREAM
config BT_L2CAP_MPS
int "Bluetooth L2CAP MPS for retransmission and Flow control"
default 48
range 48 BT_L2CAP_TX_MTU
help
Bluetooth L2CAP MPS for retransmission and Flow control

config BT_L2CAP_MAX_WINDOW_SIZE
int "Maximum Windows Size of Retransmission and Flow Control"
default 1
range 1 32
help
Maximum Windows Size of Retransmission and Flow Control.
The minimum (and default) number is 1.
The range is 1 to 32 for Flow Control mode and Retransmission mode.
The range is 1 to 63 for Enhanced Retransmission mode.
The range is 1 to 0x3FFF for Enhanced Retransmission mode with
externed control.

config BT_L2CAP_BR_RET_TIMEOUT
int "Retransmission timeout"
default 2000
range 1000 2000
help
the Retransmission timeout shall be three times the value of flush
timeout, subject to a minimum of 1 second and maximum of 2 seconds.

config BT_L2CAP_BR_MONITOR_TIMEOUT
int "Monitor timeout"
default 12000 if BT_L2CAP_ENH_RET
default BT_L2CAP_BR_RET_TIMEOUT
range BT_L2CAP_BR_RET_TIMEOUT 12000
Comment on lines +69 to +100
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about these? They really don't depend on any of the other newly added options in this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are depended on BT_L2CAP_RET, BT_L2CAP_FC, BT_L2CAP_ENH_RET, or BT_L2CAP_STREAM.

Let me update the if condition for them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

help
If a flush timeout exists on the link for Enhanced Retransmission mode and
both sides of the link are configured to the same flush timeout value then the
monitor timeout shall be set to a value at least as large as the Retransmission
timeout otherwise the value of the Monitor timeout shall be six times the value
of flush timeout, subject to a minimum of the retransmission timeout value and
a maximum of 12 seconds.
endif # BT_L2CAP_RET || BT_L2CAP_FC || BT_L2CAP_ENH_RET || BT_L2CAP_STREAM

config BT_RFCOMM
bool "Bluetooth RFCOMM protocol support [EXPERIMENTAL]"
select EXPERIMENTAL
Expand Down
Loading
Loading