|
|
@@ -114,6 +114,7 @@ static u8_t seg_rx_buf_data[(CONFIG_BLE_MESH_RX_SEG_MSG_COUNT *
|
|
|
static u16_t hb_sub_dst = BLE_MESH_ADDR_UNASSIGNED;
|
|
|
|
|
|
static bt_mesh_mutex_t tx_seg_lock;
|
|
|
+static bt_mesh_mutex_t rx_seg_lock;
|
|
|
|
|
|
static void bt_mesh_tx_seg_mutex_new(void)
|
|
|
{
|
|
|
@@ -137,6 +138,28 @@ static void bt_mesh_tx_seg_unlock(void)
|
|
|
bt_mesh_mutex_unlock(&tx_seg_lock);
|
|
|
}
|
|
|
|
|
|
+static void bt_mesh_rx_seg_mutex_new(void)
|
|
|
+{
|
|
|
+ if (!rx_seg_lock.mutex) {
|
|
|
+ bt_mesh_mutex_create(&rx_seg_lock);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void bt_mesh_rx_seg_mutex_free(void)
|
|
|
+{
|
|
|
+ bt_mesh_mutex_free(&rx_seg_lock);
|
|
|
+}
|
|
|
+
|
|
|
+static void bt_mesh_rx_seg_lock(void)
|
|
|
+{
|
|
|
+ bt_mesh_mutex_lock(&rx_seg_lock);
|
|
|
+}
|
|
|
+
|
|
|
+static void bt_mesh_rx_seg_unlock(void)
|
|
|
+{
|
|
|
+ bt_mesh_mutex_unlock(&rx_seg_lock);
|
|
|
+}
|
|
|
+
|
|
|
u8_t bt_mesh_get_seg_retrans_num(void)
|
|
|
{
|
|
|
return SEG_RETRANSMIT_ATTEMPTS;
|
|
|
@@ -910,7 +933,9 @@ static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr,
|
|
|
while ((bit = find_lsb_set(ack))) {
|
|
|
if (tx->seg[bit - 1]) {
|
|
|
BT_DBG("seg %u/%u acked", bit - 1, tx->seg_n);
|
|
|
+ bt_mesh_tx_seg_lock();
|
|
|
seg_tx_done(tx, bit - 1);
|
|
|
+ bt_mesh_tx_seg_unlock();
|
|
|
}
|
|
|
|
|
|
ack &= ~BIT(bit - 1);
|
|
|
@@ -1257,6 +1282,8 @@ static void seg_rx_reset(struct seg_rx *rx, bool full_reset)
|
|
|
{
|
|
|
BT_DBG("rx %p", rx);
|
|
|
|
|
|
+ bt_mesh_rx_seg_lock();
|
|
|
+
|
|
|
k_delayed_work_cancel(&rx->ack);
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && rx->obo &&
|
|
|
@@ -1278,6 +1305,8 @@ static void seg_rx_reset(struct seg_rx *rx, bool full_reset)
|
|
|
rx->src = BLE_MESH_ADDR_UNASSIGNED;
|
|
|
rx->dst = BLE_MESH_ADDR_UNASSIGNED;
|
|
|
}
|
|
|
+
|
|
|
+ bt_mesh_rx_seg_unlock();
|
|
|
}
|
|
|
|
|
|
static u32_t incomplete_timeout(struct seg_rx *rx)
|
|
|
@@ -1306,16 +1335,29 @@ static void seg_ack(struct k_work *work)
|
|
|
|
|
|
BT_DBG("rx %p", rx);
|
|
|
|
|
|
+ bt_mesh_rx_seg_lock();
|
|
|
+
|
|
|
if (k_uptime_get_32() - rx->last > incomplete_timeout(rx)) {
|
|
|
BT_WARN("Incomplete timer expired");
|
|
|
+ bt_mesh_rx_seg_unlock();
|
|
|
seg_rx_reset(rx, false);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ /* Add this check in case the timeout handler is just executed
|
|
|
+ * after the seg_rx_reset() which may reset rx->sub to NULL.
|
|
|
+ */
|
|
|
+ if (rx->sub == NULL) {
|
|
|
+ bt_mesh_rx_seg_unlock();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
send_ack(rx->sub, rx->dst, rx->src, rx->ttl, &rx->seq_auth,
|
|
|
rx->block, rx->obo);
|
|
|
|
|
|
k_delayed_work_submit(&rx->ack, ack_timeout(rx));
|
|
|
+
|
|
|
+ bt_mesh_rx_seg_unlock();
|
|
|
}
|
|
|
|
|
|
static inline u8_t seg_len(bool ctl)
|
|
|
@@ -1814,6 +1856,7 @@ void bt_mesh_trans_init(void)
|
|
|
}
|
|
|
|
|
|
bt_mesh_tx_seg_mutex_new();
|
|
|
+ bt_mesh_rx_seg_mutex_new();
|
|
|
}
|
|
|
|
|
|
void bt_mesh_trans_deinit(bool erase)
|
|
|
@@ -1841,6 +1884,7 @@ void bt_mesh_trans_deinit(bool erase)
|
|
|
}
|
|
|
|
|
|
bt_mesh_tx_seg_mutex_free();
|
|
|
+ bt_mesh_rx_seg_mutex_free();
|
|
|
}
|
|
|
|
|
|
void bt_mesh_rpl_clear(void)
|