Skip to content

Commit c90d6fe

Browse files
fixes
1 parent 0e4a94c commit c90d6fe

2 files changed

Lines changed: 28 additions & 10 deletions

File tree

libcanard/canard.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,17 @@ static byte_t txfer_shard(const canard_txfer_t* const tr)
617617

618618
static bool txfer_is_backlogged(const canard_txfer_t* const tr) { return tr->delayed_until == HEAT_DEATH; }
619619

620+
static bool txfer_is_pending(const canard_t* const self, const canard_txfer_t* const tr)
621+
{
622+
const byte_t shard = txfer_shard(tr);
623+
FOREACH_IFACE (i) {
624+
if (is_listed(&self->tx.pending[shard][i], &tr->list_pending[i])) {
625+
return true;
626+
}
627+
}
628+
return false;
629+
}
630+
620631
static void txfer_free_payload(canard_t* const self, canard_txfer_t* const tr)
621632
{
622633
CANARD_ASSERT(tr != NULL);
@@ -1006,9 +1017,10 @@ static bool tx_push(canard_t* const self,
10061017
// trying to push too many reliable transfers on the same topic too quickly.
10071018
// Insert at the same time to avoid double tree walk.
10081019
if (tr->reliable) {
1009-
const txfer_key_t key = { .topic_hash = tr->topic_hash, .transfer_id = tr->transfer_id };
1010-
canard_txfer_t* const rel = CAVL2_TO_OWNER(
1011-
cavl2_find_or_insert(&self->tx.reliable, &key, tx_cavl_compare_reliable, tr, cavl2_trivial_factory),
1020+
const txfer_key_t key = { .topic_hash = tr->topic_hash, .transfer_id = tr->transfer_id };
1021+
const canard_txfer_t* const rel = CAVL2_TO_OWNER(
1022+
cavl2_find_or_insert(
1023+
&self->tx.reliable, &key, tx_cavl_compare_reliable, &tr->index_reliable, cavl2_trivial_factory),
10121024
canard_txfer_t,
10131025
index_reliable);
10141026
if (rel != tr) { // Duplicate found.
@@ -1092,9 +1104,11 @@ static bool tx_push(canard_t* const self,
10921104
cavl2_lower_bound(self->tx.reliable, &key, tx_cavl_compare_reliable), canard_txfer_t, index_reliable);
10931105
while ((rel != NULL) && (rel->topic_hash == tr->topic_hash)) {
10941106
if ((rel != tr) && (txfer_shard(rel) == shard)) {
1095-
const bool delayed = rel->delayed_until > BIG_BANG; // Maybe backlogged also, but it's all the same.
1107+
// Check if the transfer is delayed (waiting for retransmission) or pending (waiting for first tx).
1108+
const bool delayed = rel->delayed_until > BIG_BANG; // In delayed list, waiting for retransmission.
1109+
const bool pending = txfer_is_pending(self, rel);
10961110
CANARD_ASSERT((!delayed) || is_listed(&self->tx.delayed[shard], &rel->list_delayed));
1097-
if (delayed) {
1111+
if (delayed || pending) {
10981112
has_preceding_reliable = true;
10991113
break;
11001114
}
@@ -1114,7 +1128,11 @@ static bool tx_push(canard_t* const self,
11141128
self->tx.pending_shards_bitmap[i] |= (1U << shard);
11151129
}
11161130
}
1117-
tx_arm_delay_if(self, tr); // Ensure it is repeatedly re-enqueued later until acknowledged or expired.
1131+
// tx_arm_delay_if is NOT called here; the retransmission timer is armed after transmission, not before.
1132+
// The transfer remains with delayed_until = BIG_BANG (set by txfer_new), ready for immediate transmission.
1133+
// For unreliable transfers, no retransmission is scheduled. For reliable transfers, the retransmission will be
1134+
// scheduled after the first transmission attempt completes.
1135+
CANARD_ASSERT(tr->delayed_until == BIG_BANG);
11181136
}
11191137
return true;
11201138
}

tests/src/test_intrusive_tx.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,11 +1512,11 @@ int main(void)
15121512
RUN_TEST(test_tx_push_unreliable_not_in_reliable_tree);
15131513
RUN_TEST(test_tx_push_empty_payload);
15141514
RUN_TEST(test_tx_push_v0_empty_payload);
1515-
// RUN_TEST(test_tx_push_with_topic_hash);
1515+
RUN_TEST(test_tx_push_with_topic_hash);
15161516
RUN_TEST(test_tx_push_fragmented_payload);
15171517
RUN_TEST(test_tx_push_large_payload_fd);
1518-
// RUN_TEST(test_tx_push_duplicate_reliable_transfer);
1519-
// RUN_TEST(test_tx_push_different_topic_hash_no_blocking);
1520-
// RUN_TEST(test_tx_push_pending_transfer_blocks_new);
1518+
RUN_TEST(test_tx_push_duplicate_reliable_transfer);
1519+
RUN_TEST(test_tx_push_different_topic_hash_no_blocking);
1520+
RUN_TEST(test_tx_push_pending_transfer_blocks_new);
15211521
return UNITY_END();
15221522
}

0 commit comments

Comments
 (0)