Skip to content

Commit

Permalink
add canardRxHasSubscription
Browse files Browse the repository at this point in the history
  • Loading branch information
serges147 committed Apr 15, 2024
1 parent 1c4da0d commit a8b646c
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 0 deletions.
24 changes: 24 additions & 0 deletions libcanard/canard.c
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,30 @@ int8_t canardRxUnsubscribe(CanardInstance* const ins,
return out;
}

int8_t canardRxHasSubscription(CanardInstance* const ins,
const CanardTransferKind transfer_kind,
const CanardPortID port_id)
{
int8_t out = -CANARD_ERROR_INVALID_ARGUMENT;
const size_t tk = (size_t) transfer_kind;
if ((ins != NULL) && (tk < CANARD_NUM_TRANSFER_KINDS))
{
CanardPortID port_id_mutable = port_id;
const CanardRxSubscription* const sub = (const CanardRxSubscription*) (void*)
cavlSearch(&ins->rx_subscriptions[tk], &port_id_mutable, &rxSubscriptionPredicateOnPortID, NULL);
if (sub != NULL)
{
CANARD_ASSERT(sub->port_id == port_id);
out = 1;
}
else
{
out = 0;
}
}
return out;
}

CanardFilter canardMakeFilterForSubject(const CanardPortID subject_id)
{
CanardFilter out = {0};
Expand Down
4 changes: 4 additions & 0 deletions libcanard/canard.h
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,10 @@ int8_t canardRxUnsubscribe(CanardInstance* const ins,
const CanardTransferKind transfer_kind,
const CanardPortID port_id);

int8_t canardRxHasSubscription(CanardInstance* const ins,
const CanardTransferKind transfer_kind,
const CanardPortID port_id);

/// Utilities for generating CAN controller hardware acceptance filter configurations
/// to accept specific subjects, services, or nodes.
///
Expand Down
5 changes: 5 additions & 0 deletions tests/helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ class Instance
return canardRxUnsubscribe(&canard_, transfer_kind, port_id);
}

[[nodiscard]] auto rxHasSubscription(const CanardTransferKind transfer_kind, const CanardPortID port_id)
{
return canardRxHasSubscription(&canard_, transfer_kind, port_id);
}

/// The items are sorted by port-ID.
[[nodiscard]] auto getSubs(const CanardTransferKind tk) const -> std::vector<const CanardRxSubscription*>
{
Expand Down
29 changes: 29 additions & 0 deletions tests/test_public_rx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@ TEST_CASE("RxBasic0")

// Create a message subscription.
CanardRxSubscription sub_msg{};
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(1 == ins.rxSubscribe(CanardTransferKindMessage, 0b0110011001100, 32, 2'000'000, sub_msg)); // New.
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(0 == ins.rxSubscribe(CanardTransferKindMessage, 0b0110011001100, 16, 1'000'000, sub_msg)); // Replaced.
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(ins.getMessageSubs().at(0) == &sub_msg);
REQUIRE(ins.getMessageSubs().at(0)->port_id == 0b0110011001100);
REQUIRE(ins.getMessageSubs().at(0)->extent == 16);
Expand All @@ -61,7 +64,9 @@ TEST_CASE("RxBasic0")

// Create a request subscription.
CanardRxSubscription sub_req{};
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindRequest, 0b0000110011));
REQUIRE(1 == ins.rxSubscribe(CanardTransferKindRequest, 0b0000110011, 20, 3'000'000, sub_req));
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindRequest, 0b0000110011));
REQUIRE(ins.getMessageSubs().at(0) == &sub_msg);
REQUIRE(ins.getResponseSubs().empty());
REQUIRE(ins.getRequestSubs().at(0) == &sub_req);
Expand All @@ -72,7 +77,9 @@ TEST_CASE("RxBasic0")

// Create a response subscription.
CanardRxSubscription sub_res{};
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindResponse, 0b0000111100));
REQUIRE(1 == ins.rxSubscribe(CanardTransferKindResponse, 0b0000111100, 10, 100'000, sub_res));
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindResponse, 0b0000111100));
REQUIRE(ins.getMessageSubs().at(0) == &sub_msg);
REQUIRE(ins.getResponseSubs().at(0) == &sub_res);
REQUIRE(ins.getResponseSubs().at(0)->port_id == 0b0000111100);
Expand All @@ -83,7 +90,9 @@ TEST_CASE("RxBasic0")

// Create a second response subscription. It will come before the one we added above due to lower port-ID.
CanardRxSubscription sub_res2{};
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindResponse, 0b0000000000));
REQUIRE(1 == ins.rxSubscribe(CanardTransferKindResponse, 0b0000000000, 10, 1'000, sub_res2));
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindResponse, 0b0000000000));
REQUIRE(ins.getMessageSubs().at(0) == &sub_msg);
REQUIRE(ins.getResponseSubs().at(0) == &sub_res2);
REQUIRE(ins.getResponseSubs().at(0)->port_id == 0b0000000000);
Expand Down Expand Up @@ -165,8 +174,11 @@ TEST_CASE("RxBasic0")
REQUIRE(ins.getAllocator().getTotalAllocatedAmount() == (3 * sizeof(RxSession) + 16 + 20));

// Destroy the message subscription and the buffer to free up memory.
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(1 == ins.rxUnsubscribe(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(0 == ins.rxUnsubscribe(CanardTransferKindMessage, 0b0110011001100)); // Repeat, nothing to do.
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(ins.getAllocator().getNumAllocatedFragments() == 4);
REQUIRE(ins.getAllocator().getTotalAllocatedAmount() == (2 * sizeof(RxSession) + 16 + 20));
ins.getAllocator().deallocate(msg_payload);
Expand Down Expand Up @@ -198,12 +210,21 @@ TEST_CASE("RxBasic0")
REQUIRE(subscription == nullptr);

// Unsubscribe.
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindRequest, 0b0000110011));
REQUIRE(1 == ins.rxUnsubscribe(CanardTransferKindRequest, 0b0000110011));
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindRequest, 0b0000110011));
REQUIRE(0 == ins.rxUnsubscribe(CanardTransferKindRequest, 0b0000110011));
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindRequest, 0b0000110011));
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindResponse, 0b0000111100));
REQUIRE(1 == ins.rxUnsubscribe(CanardTransferKindResponse, 0b0000111100));
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindResponse, 0b0000111100));
REQUIRE(0 == ins.rxUnsubscribe(CanardTransferKindResponse, 0b0000111100));
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindResponse, 0b0000111100));
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindResponse, 0b0000000000));
REQUIRE(1 == ins.rxUnsubscribe(CanardTransferKindResponse, 0b0000000000));
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindResponse, 0b0000000000));
REQUIRE(0 == ins.rxUnsubscribe(CanardTransferKindResponse, 0b0000000000));
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindResponse, 0b0000000000));
}

TEST_CASE("RxAnonymous")
Expand Down Expand Up @@ -239,7 +260,9 @@ TEST_CASE("RxAnonymous")
void* const my_user_reference = &ins;
CanardRxSubscription sub_msg{};
sub_msg.user_reference = my_user_reference;
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(1 == ins.rxSubscribe(CanardTransferKindMessage, 0b0110011001100, 16, 2'000'000, sub_msg)); // New.
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));

// Accepted anonymous message.
subscription = nullptr;
Expand Down Expand Up @@ -358,7 +381,9 @@ TEST_CASE("Issue189") // https://github.com/OpenCyphal/libcanard/issues/189

// Create a message subscription.
CanardRxSubscription sub_msg{};
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(1 == ins.rxSubscribe(CanardTransferKindMessage, 0b0110011001100, 50, 1'000'000, sub_msg));
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(ins.getMessageSubs().at(0) == &sub_msg);
REQUIRE(ins.getMessageSubs().at(0)->port_id == 0b0110011001100);
REQUIRE(ins.getMessageSubs().at(0)->extent == 50);
Expand Down Expand Up @@ -465,7 +490,9 @@ TEST_CASE("Issue212")

// Create a message subscription with the transfer-ID timeout of just one microsecond.
CanardRxSubscription sub_msg{};
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(1 == ins.rxSubscribe(CanardTransferKindMessage, 0b0110011001100, 50, 1, sub_msg));
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(ins.getMessageSubs().at(0) == &sub_msg);
REQUIRE(ins.getMessageSubs().at(0)->port_id == 0b0110011001100);
REQUIRE(ins.getMessageSubs().at(0)->extent == 50);
Expand Down Expand Up @@ -569,7 +596,9 @@ TEST_CASE("RxFixedTIDWithSmallTimeout")

// Create a message subscription with the transfer-ID timeout of just five microseconds.
CanardRxSubscription sub_msg{};
REQUIRE(0 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(1 == ins.rxSubscribe(CanardTransferKindMessage, 0b0110011001100, 50, 5, sub_msg));
REQUIRE(1 == ins.rxHasSubscription(CanardTransferKindMessage, 0b0110011001100));
REQUIRE(ins.getMessageSubs().at(0) == &sub_msg);
REQUIRE(ins.getMessageSubs().at(0)->port_id == 0b0110011001100);
REQUIRE(ins.getMessageSubs().at(0)->extent == 50);
Expand Down

0 comments on commit a8b646c

Please sign in to comment.