mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-27 04:10:04 +00:00
nimble/l2cap: Add TX_UNSTALLED event to L2CAP CoC
With this patch if L2CAP CoC has been stalled due to lack of credits BLE_HS_ESTALLED code will be returned. When NimBLE gets back credits and finish sending SDU, BLE_L2CAP_EVENT_COC_TX_UNSTALLED will be sent to the application as the indication that L2CAP CoC is unstalled and ready for sending new data.
This commit is contained in:
@@ -94,6 +94,7 @@ extern "C" {
|
||||
#define BLE_HS_ESTORE_FAIL 28
|
||||
#define BLE_HS_EPREEMPTED 29
|
||||
#define BLE_HS_EDISABLED 30
|
||||
#define BLE_HS_ESTALLED 31
|
||||
|
||||
/** Error base for ATT errors */
|
||||
#define BLE_HS_ERR_ATT_BASE 0x100
|
||||
|
||||
@@ -75,6 +75,7 @@ struct ble_hs_conn;
|
||||
#define BLE_L2CAP_EVENT_COC_DISCONNECTED 1
|
||||
#define BLE_L2CAP_EVENT_COC_ACCEPT 2
|
||||
#define BLE_L2CAP_EVENT_COC_DATA_RECEIVED 3
|
||||
#define BLE_L2CAP_EVENT_COC_TX_UNSTALLED 4
|
||||
|
||||
typedef void ble_l2cap_sig_update_fn(uint16_t conn_handle, int status,
|
||||
void *arg);
|
||||
@@ -173,6 +174,28 @@ struct ble_l2cap_event {
|
||||
/** The mbuf with received SDU. */
|
||||
struct os_mbuf *sdu_rx;
|
||||
} receive;
|
||||
|
||||
/**
|
||||
* Represents tx_unstalled data. Valid for the following event
|
||||
* types:
|
||||
* o BLE_L2CAP_EVENT_COC_TX_UNSTALLED
|
||||
*/
|
||||
struct {
|
||||
/** Connection handle of the relevant connection */
|
||||
uint16_t conn_handle;
|
||||
|
||||
/** The L2CAP channel of the relevant L2CAP connection. */
|
||||
struct ble_l2cap_chan *chan;
|
||||
|
||||
/**
|
||||
* The status of the send attempt which was stalled due to
|
||||
* lack of credits; This can be non zero only if there
|
||||
* is an issue with memory allocation for following SDU fragments.
|
||||
* In such a case last SDU has been partially sent to peer device
|
||||
* and it is up to application to decide how to handle it.
|
||||
*/
|
||||
int status;
|
||||
} tx_unstalled;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -316,6 +316,23 @@ ble_l2cap_coc_cleanup_chan(struct ble_l2cap_chan *chan)
|
||||
os_mbuf_free_chain(chan->coc_tx.sdu);
|
||||
}
|
||||
|
||||
static void
|
||||
ble_l2cap_event_coc_unstalled(struct ble_l2cap_chan *chan, int status)
|
||||
{
|
||||
struct ble_l2cap_event event = { };
|
||||
|
||||
if (!chan->cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.type = BLE_L2CAP_EVENT_COC_TX_UNSTALLED;
|
||||
event.tx_unstalled.conn_handle = chan->conn_handle;
|
||||
event.tx_unstalled.chan = chan;
|
||||
event.tx_unstalled.status = status;
|
||||
|
||||
chan->cb(&event, chan->cb_arg);
|
||||
}
|
||||
|
||||
static int
|
||||
ble_l2cap_coc_continue_tx(struct ble_l2cap_chan *chan)
|
||||
{
|
||||
@@ -402,16 +419,30 @@ ble_l2cap_coc_continue_tx(struct ble_l2cap_chan *chan)
|
||||
os_mbuf_free_chain(tx->sdu);
|
||||
tx->sdu = 0;
|
||||
tx->data_offset = 0;
|
||||
if (tx->flags & BLE_L2CAP_COC_FLAG_STALLED) {
|
||||
ble_l2cap_event_coc_unstalled(chan, 0);
|
||||
tx->flags &= ~BLE_L2CAP_COC_FLAG_STALLED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tx->sdu) {
|
||||
/* Not complete SDU sent, wait for credits */
|
||||
tx->flags |= BLE_L2CAP_COC_FLAG_STALLED;
|
||||
return BLE_HS_ESTALLED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
os_mbuf_free_chain(tx->sdu);
|
||||
tx->sdu = NULL;
|
||||
os_mbuf_free_chain(txom);
|
||||
if (tx->flags & BLE_L2CAP_COC_FLAG_STALLED) {
|
||||
ble_l2cap_event_coc_unstalled(chan, rc);
|
||||
tx->flags &= ~BLE_L2CAP_COC_FLAG_STALLED;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -35,11 +35,14 @@ extern "C" {
|
||||
|
||||
struct ble_l2cap_chan;
|
||||
|
||||
#define BLE_L2CAP_COC_FLAG_STALLED 0x01
|
||||
|
||||
struct ble_l2cap_coc_endpoint {
|
||||
struct os_mbuf *sdu;
|
||||
uint16_t mtu;
|
||||
uint16_t credits;
|
||||
uint16_t data_offset;
|
||||
struct os_mbuf *sdu;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
struct ble_l2cap_coc_srv {
|
||||
|
||||
@@ -736,6 +736,9 @@ ble_l2cap_test_event(struct ble_l2cap_event *event, void *arg)
|
||||
OS_MBUF_PKTLEN(event->receive.sdu_rx));
|
||||
TEST_ASSERT(memcmp(sdu_rx->om_data, ev->data, ev->data_len) == 0);
|
||||
return 0;
|
||||
case BLE_L2CAP_EVENT_COC_TX_UNSTALLED:
|
||||
/* TODO Add tests for this */
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user