mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-06-06 05:14:45 +00:00
mesh: Fix handling of failed transmissions
When sending a segmented message, the state could get stuck if the advertising bearer fails in transmitting and we don't detect that it happened. Add a send_start callback for all packets so we can always know if sending fails. X-Original-Commit: c2f6fa5baf8eab609a705347e1c1b881e48bd710
This commit is contained in:
@@ -46,6 +46,12 @@
|
||||
/* Number of retransmit attempts (after the initial transmit) per segment */
|
||||
#define SEG_RETRANSMIT_ATTEMPTS 4
|
||||
|
||||
/* "This timer shall be set to a minimum of 200 + 50 * TTL milliseconds.".
|
||||
* We use 400 since 300 is a common send duration for standard HCI, and we
|
||||
* need to have a timeout that's bigger than that.
|
||||
*/
|
||||
#define SEG_RETRANSMIT_TIMEOUT(tx) (K_MSEC(400) + 50 * (tx)->ttl)
|
||||
|
||||
/* How long to wait for available buffers before giving up */
|
||||
#define BUF_TIMEOUT K_NO_WAIT
|
||||
|
||||
@@ -191,7 +197,7 @@ static inline void seg_tx_complete(struct seg_tx *tx, int err)
|
||||
seg_tx_reset(tx);
|
||||
}
|
||||
|
||||
static void seg_send_start(u16_t duration, int err, void *user_data)
|
||||
static void seg_first_send_start(u16_t duration, int err, void *user_data)
|
||||
{
|
||||
struct seg_tx *tx = user_data;
|
||||
|
||||
@@ -200,27 +206,35 @@ static void seg_send_start(u16_t duration, int err, void *user_data)
|
||||
}
|
||||
}
|
||||
|
||||
static void seg_send_start(u16_t duration, int err, void *user_data)
|
||||
{
|
||||
struct seg_tx *tx = user_data;
|
||||
|
||||
/* If there's an error in transmitting the 'sent' callback will never
|
||||
* be called. Make sure that we kick the retransmit timer also in this
|
||||
* case since otherwise we risk the transmission of becoming stale.
|
||||
*/
|
||||
if (err) {
|
||||
k_delayed_work_submit(&tx->retransmit,
|
||||
SEG_RETRANSMIT_TIMEOUT(tx));
|
||||
}
|
||||
}
|
||||
|
||||
static void seg_sent(int err, void *user_data)
|
||||
{
|
||||
struct seg_tx *tx = user_data;
|
||||
s32_t timeout;
|
||||
|
||||
/* "This timer shall be set to a minimum of 200 + 50 * TTL
|
||||
* milliseconds.". We use 400 since 300 is a common send
|
||||
* duration for standard HCI, and we need to have a timeout
|
||||
* that's bigger than that.
|
||||
*/
|
||||
timeout = K_MSEC(400) + 50 * tx->ttl;
|
||||
|
||||
k_delayed_work_submit(&tx->retransmit, timeout);
|
||||
k_delayed_work_submit(&tx->retransmit,
|
||||
SEG_RETRANSMIT_TIMEOUT(tx));
|
||||
}
|
||||
|
||||
static const struct bt_mesh_send_cb first_sent_cb = {
|
||||
.start = seg_send_start,
|
||||
.start = seg_first_send_start,
|
||||
.end = seg_sent,
|
||||
};
|
||||
|
||||
static const struct bt_mesh_send_cb seg_sent_cb = {
|
||||
.start = seg_send_start,
|
||||
.end = seg_sent,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user