You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2018/03/12 13:37:52 UTC

[mynewt-nimble] 18/32: mesh: Fix handling of failed transmissions

This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch new-master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git

commit 35bcfc25b76b6be19093a5e85b94485e9160104c
Author: MichaƂ Narajowski <mi...@codecoup.pl>
AuthorDate: Tue Feb 20 14:23:49 2018 +0100

    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
---
 nimble/host/mesh/src/transport.c | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/nimble/host/mesh/src/transport.c b/nimble/host/mesh/src/transport.c
index 9902a6d..4ae20f3 100644
--- a/nimble/host/mesh/src/transport.c
+++ b/nimble/host/mesh/src/transport.c
@@ -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_sent(int err, void *user_data)
+static void seg_send_start(u16_t duration, 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.
+	/* 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.
 	 */
-	timeout = K_MSEC(400) + 50 * tx->ttl;
+	if (err) {
+		k_delayed_work_submit(&tx->retransmit,
+				      SEG_RETRANSMIT_TIMEOUT(tx));
+	}
+}
 
-	k_delayed_work_submit(&tx->retransmit, timeout);
+static void seg_sent(int err, void *user_data)
+{
+	struct seg_tx *tx = user_data;
+
+	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,
 };
 

-- 
To stop receiving notification emails like this one, please contact
andk@apache.org.