Skip to content

Commit

Permalink
Add canardRxAccept2(), fix #163 (#164)
Browse files Browse the repository at this point in the history
* Fix #163
* [internals] Remove redundant declarations
* Bump Clang-Tools to v11
Co-authored-by: Peter van der Perk <[email protected]>
  • Loading branch information
pavel-kirienko authored May 18, 2021
1 parent 55938c5 commit 3879683
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 133 deletions.
42 changes: 19 additions & 23 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,16 @@ matrix:
organization: uavcan
token:
secure: "LbaAOcguJspiraxAb9RNkwtGvWDh1aMTEPdz2MCbeICxIIiJ6LRoabD58rLvPsrNSWsR3AAep9Q551dDzT8c04UX+C67N3CZ/oof4DwBT+XQCSfB8FMj2QpbglJqwFPclYUorROjH31VwGcgIq3kfQq3Cw8G+nsL8vRaaJXsJb/KPp6MU698NGzHJIgRyn29VW76dW0NSxOv4ub3e6aKOnwfI+h1Ctx4p3hCdzd402PaZspv1VgEmirf5sVUJvE67PVIzlwov+CF+2PlrIpGUWI98Gl6HqYHv3hkvSP+4iLvCMD99Zmee4yLnCFY3xcJuZ8zKCRBBoquuUxdzK0f/4l9TZXePDXDMhaj3cXLlaAPWDw+emqTcm+hzP1mt/DaIqopAf54bQojVWELbL6QcjBNkphSvWBeIoyKWuUWU2LWJcJNPXFNUug//D99uXNurkzAIWR+lcsx6zO+cr4EN00N92W6hPt7mhKCF0prs7SvMleEi9mAbxvd4lOHFT56RvcB5ny6IapX9/q1+xm5iSoAzLhbvU1aUCnX74S/yFFejvClxxhW+P0bXYNtZ9RRfl8BdSgENTgA9RSnqdtIJGA4cU3OxIHDyJIC2cgmsE38u7QaMO49r1liJFH+xmDPa6bkGGHiPoHaPu9+g+wYFttK9FNt5ozyHY+VpjwTrY4="
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-10
- g++-10-multilib
- gcc-10-multilib
- linux-libc-dev:i386
env:
- CC=gcc-10
- CXX=g++-10
script:
- sudo apt-get update ; sudo apt-get -y upgrade ; sudo apt-get -y autoremove
- sudo apt-get -yf install # fix missing
- sudo apt-get update ; sudo apt-get -y upgrade ; sudo apt-get -y autoremove
- sudo apt-get -yf --allow-downgrades install libc6=2.31-0ubuntu9.2 # https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1926918
- sudo apt-get -yfq install g++-10 g++-10-multilib gcc-10-multilib linux-libc-dev:i386

# ANALYSIS
# Using the build wrapper from Sonar and collecting the code coverage.
# Define NDEBUG=1 to avoid assertion checks being reported as uncovered statements.
Expand Down Expand Up @@ -53,23 +51,21 @@ matrix:

# -------------------- Clang --------------------
- language: cpp
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages: # Install a newer GCC because https://stackoverflow.com/a/51512150/1007777.
- g++-10
- g++-10-multilib
- gcc-10-multilib
- linux-libc-dev:i386
script:
- echo 'APT::Get::AllowUnauthenticated "true";' | sudo tee /etc/apt/apt.conf.d/99insecure
- sudo apt-get update ; sudo apt-get -y upgrade ; sudo apt-get -y autoremove
- sudo apt-get -yf install # fix missing
- sudo apt-get update ; sudo apt-get -y upgrade ; sudo apt-get -y autoremove
- sudo apt-get -yf --allow-downgrades install libc6=2.31-0ubuntu9.2 # https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1926918
- sudo apt-get -yfq install g++-10 g++-10-multilib gcc-10-multilib linux-libc-dev:i386

# Set up the toolchain.
- wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && sudo ./llvm.sh 10
- sudo apt install clang-tidy-10 clang-format-10
- clang++-10 -E -x c++ - -v < /dev/null # Print the Clang configuration for troubleshooting purposes.
- wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && sudo ./llvm.sh 11
- sudo apt install clang-tidy-11 clang-format-11
- clang++-11 -E -x c++ - -v < /dev/null # Print the Clang configuration for troubleshooting purposes.

# DEBUG + format check
- cmake -DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 tests -DCMAKE_BUILD_TYPE=Debug
- cmake -DCMAKE_C_COMPILER=clang-11 -DCMAKE_CXX_COMPILER=clang++-11 tests -DCMAKE_BUILD_TYPE=Debug
- make VERBOSE=1 && make test
- make format VERBOSE=1
- 'modified="$(git status --porcelain --untracked-files=no)"'
Expand All @@ -78,12 +74,12 @@ matrix:
- make clean

# RELEASE (skip static analysis because it is done in the DEBUG configuration)
- cmake -DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 tests -DCMAKE_BUILD_TYPE=Release -DNO_STATIC_ANALYSIS=1
- cmake -DCMAKE_C_COMPILER=clang-11 -DCMAKE_CXX_COMPILER=clang++-11 tests -DCMAKE_BUILD_TYPE=Release -DNO_STATIC_ANALYSIS=1
- make VERBOSE=1 && make test
- make clean

# MINSIZEREL (skip static analysis because it is done in the DEBUG configuration)
- cmake -DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 tests -DCMAKE_BUILD_TYPE=MinSizeRel -DNO_STATIC_ANALYSIS=1
- cmake -DCMAKE_C_COMPILER=clang-11 -DCMAKE_CXX_COMPILER=clang++-11 tests -DCMAKE_BUILD_TYPE=MinSizeRel -DNO_STATIC_ANALYSIS=1
- make VERBOSE=1 && make test
- make clean

Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ to prevent non-compliant code from being accepted into upstream.

The following tools are required to conduct library development locally:

- GCC v9 or newer.
- Clang and Clang-Tools v9 or newer.
- GCC v10 or newer.
- Clang and Clang-Tools v11 or newer.
- CMake v3.12 or newer.
- An AMD64 machine.

Expand Down
3 changes: 3 additions & 0 deletions libcanard/.clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ Checks: >-
-google-readability-todo,
-readability-avoid-const-params-in-decls,
-llvm-header-guard,
CheckOptions:
- key: readability-function-cognitive-complexity.Threshold
value: '99'
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: false
Expand Down
86 changes: 19 additions & 67 deletions libcanard/canard.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
#endif

/// This macro is needed only for testing and for library development. Do not redefine this in production.
#if defined(CANARD_CONFIG_EXPOSE_PRIVATE) && CANARD_CONFIG_EXPOSE_PRIVATE
# define CANARD_PRIVATE
#else // Consider defining an extra compilation option that turns this into "static inline"?
#ifndef CANARD_PRIVATE
# define CANARD_PRIVATE static
#endif

Expand Down Expand Up @@ -62,7 +60,6 @@ typedef uint16_t TransferCRC;
#define CRC_RESIDUE 0x0000U
#define CRC_SIZE_BYTES 2U

CANARD_PRIVATE TransferCRC crcAddByte(const TransferCRC crc, const uint8_t byte);
CANARD_PRIVATE TransferCRC crcAddByte(const TransferCRC crc, const uint8_t byte)
{
static const TransferCRC Top = 0x8000U;
Expand All @@ -81,7 +78,6 @@ CANARD_PRIVATE TransferCRC crcAddByte(const TransferCRC crc, const uint8_t byte)
return out;
}

CANARD_PRIVATE TransferCRC crcAdd(const TransferCRC crc, const size_t size, const void* const data);
CANARD_PRIVATE TransferCRC crcAdd(const TransferCRC crc, const size_t size, const void* const data)
{
CANARD_ASSERT((data != NULL) || (size == 0U));
Expand Down Expand Up @@ -114,7 +110,6 @@ typedef struct CanardInternalTxQueueItem
uint8_t payload_buffer[]; // NOSONAR
} CanardInternalTxQueueItem;

CANARD_PRIVATE uint32_t txMakeMessageSessionSpecifier(const CanardPortID subject_id, const CanardNodeID src_node_id);
CANARD_PRIVATE uint32_t txMakeMessageSessionSpecifier(const CanardPortID subject_id, const CanardNodeID src_node_id)
{
CANARD_ASSERT(src_node_id <= CANARD_NODE_ID_MAX);
Expand All @@ -123,10 +118,6 @@ CANARD_PRIVATE uint32_t txMakeMessageSessionSpecifier(const CanardPortID subject
return src_node_id | (tmp << OFFSET_SUBJECT_ID);
}

CANARD_PRIVATE uint32_t txMakeServiceSessionSpecifier(const CanardPortID service_id,
const bool request_not_response,
const CanardNodeID src_node_id,
const CanardNodeID dst_node_id);
CANARD_PRIVATE uint32_t txMakeServiceSessionSpecifier(const CanardPortID service_id,
const bool request_not_response,
const CanardNodeID src_node_id,
Expand All @@ -141,7 +132,6 @@ CANARD_PRIVATE uint32_t txMakeServiceSessionSpecifier(const CanardPortID service
}

/// This is the transport MTU rounded up to next full DLC minus the tail byte.
CANARD_PRIVATE size_t txGetPresentationLayerMTU(const CanardInstance* const ins);
CANARD_PRIVATE size_t txGetPresentationLayerMTU(const CanardInstance* const ins)
{
const size_t max_index = (sizeof(CanardCANLengthToDLC) / sizeof(CanardCANLengthToDLC[0])) - 1U;
Expand All @@ -161,9 +151,6 @@ CANARD_PRIVATE size_t txGetPresentationLayerMTU(const CanardInstance* const ins)
return mtu - 1U;
}

CANARD_PRIVATE int32_t txMakeCANID(const CanardTransfer* const tr,
const CanardNodeID local_node_id,
const size_t presentation_layer_mtu);
CANARD_PRIVATE int32_t txMakeCANID(const CanardTransfer* const tr,
const CanardNodeID local_node_id,
const size_t presentation_layer_mtu)
Expand Down Expand Up @@ -230,10 +217,6 @@ CANARD_PRIVATE int32_t txMakeCANID(const CanardTransfer* const tr,
return out;
}

CANARD_PRIVATE uint8_t txMakeTailByte(const bool start_of_transfer,
const bool end_of_transfer,
const bool toggle,
const CanardTransferID transfer_id);
CANARD_PRIVATE uint8_t txMakeTailByte(const bool start_of_transfer,
const bool end_of_transfer,
const bool toggle,
Expand All @@ -245,7 +228,6 @@ CANARD_PRIVATE uint8_t txMakeTailByte(const bool start_of_transfer,
}

/// Takes a frame payload size, returns a new size that is >=x and is rounded up to the nearest valid DLC.
CANARD_PRIVATE size_t txRoundFramePayloadSizeUp(const size_t x);
CANARD_PRIVATE size_t txRoundFramePayloadSizeUp(const size_t x)
{
CANARD_ASSERT(x < (sizeof(CanardCANLengthToDLC) / sizeof(CanardCANLengthToDLC[0])));
Expand All @@ -255,10 +237,6 @@ CANARD_PRIVATE size_t txRoundFramePayloadSizeUp(const size_t x)
return CanardCANDLCToLength[y];
}

CANARD_PRIVATE CanardInternalTxQueueItem* txAllocateQueueItem(CanardInstance* const ins,
const uint32_t id,
const CanardMicrosecond deadline_usec,
const size_t payload_size);
CANARD_PRIVATE CanardInternalTxQueueItem* txAllocateQueueItem(CanardInstance* const ins,
const uint32_t id,
const CanardMicrosecond deadline_usec,
Expand All @@ -281,7 +259,6 @@ CANARD_PRIVATE CanardInternalTxQueueItem* txAllocateQueueItem(CanardInstance* co

/// Returns the element after which new elements with the specified CAN ID should be inserted.
/// Returns NULL if the element shall be inserted in the beginning of the list (i.e., no prior elements).
CANARD_PRIVATE CanardInternalTxQueueItem* txFindQueueSupremum(const CanardInstance* const ins, const uint32_t can_id);
CANARD_PRIVATE CanardInternalTxQueueItem* txFindQueueSupremum(const CanardInstance* const ins, const uint32_t can_id)
{
CANARD_ASSERT(ins != NULL);
Expand All @@ -304,12 +281,6 @@ CANARD_PRIVATE CanardInternalTxQueueItem* txFindQueueSupremum(const CanardInstan
}

/// Returns the number of frames enqueued or error (i.e., =1 or <0).
CANARD_PRIVATE int32_t txPushSingleFrame(CanardInstance* const ins,
const CanardMicrosecond deadline_usec,
const uint32_t can_id,
const CanardTransferID transfer_id,
const size_t payload_size,
const void* const payload);
CANARD_PRIVATE int32_t txPushSingleFrame(CanardInstance* const ins,
const CanardMicrosecond deadline_usec,
const uint32_t can_id,
Expand Down Expand Up @@ -364,13 +335,6 @@ CANARD_PRIVATE int32_t txPushSingleFrame(CanardInstance* const ins,
}

/// Returns the number of frames enqueued or error.
CANARD_PRIVATE int32_t txPushMultiFrame(CanardInstance* const ins,
const size_t presentation_layer_mtu,
const CanardMicrosecond deadline_usec,
const uint32_t can_id,
const CanardTransferID transfer_id,
const size_t payload_size,
const void* const payload);
CANARD_PRIVATE int32_t txPushMultiFrame(CanardInstance* const ins,
const size_t presentation_layer_mtu,
const CanardMicrosecond deadline_usec,
Expand Down Expand Up @@ -541,7 +505,6 @@ typedef struct
} RxFrameModel;

/// Returns truth if the frame is valid and parsed successfully. False if the frame is not a valid UAVCAN/CAN frame.
CANARD_PRIVATE bool rxTryParseFrame(const CanardFrame* const frame, RxFrameModel* const out);
CANARD_PRIVATE bool rxTryParseFrame(const CanardFrame* const frame, RxFrameModel* const out)
{
CANARD_ASSERT(frame != NULL);
Expand Down Expand Up @@ -606,7 +569,6 @@ CANARD_PRIVATE bool rxTryParseFrame(const CanardFrame* const frame, RxFrameModel
return valid;
}

CANARD_PRIVATE void rxInitTransferFromFrame(const RxFrameModel* const frame, CanardTransfer* const out_transfer);
CANARD_PRIVATE void rxInitTransferFromFrame(const RxFrameModel* const frame, CanardTransfer* const out_transfer)
{
CANARD_ASSERT(frame != NULL);
Expand All @@ -622,7 +584,6 @@ CANARD_PRIVATE void rxInitTransferFromFrame(const RxFrameModel* const frame, Can
}

/// The implementation is borrowed from the Specification.
CANARD_PRIVATE uint8_t rxComputeTransferIDDifference(const uint8_t a, const uint8_t b);
CANARD_PRIVATE uint8_t rxComputeTransferIDDifference(const uint8_t a, const uint8_t b)
{
CANARD_ASSERT(a <= CANARD_TRANSFER_ID_MAX);
Expand All @@ -636,11 +597,6 @@ CANARD_PRIVATE uint8_t rxComputeTransferIDDifference(const uint8_t a, const uint
return (uint8_t) diff;
}

CANARD_PRIVATE int8_t rxSessionWritePayload(CanardInstance* const ins,
CanardInternalRxSession* const rxs,
const size_t extent,
const size_t payload_size,
const void* const payload);
CANARD_PRIVATE int8_t rxSessionWritePayload(CanardInstance* const ins,
CanardInternalRxSession* const rxs,
const size_t extent,
Expand Down Expand Up @@ -693,7 +649,6 @@ CANARD_PRIVATE int8_t rxSessionWritePayload(CanardInstance* const ins,
return out;
}

CANARD_PRIVATE void rxSessionRestart(CanardInstance* const ins, CanardInternalRxSession* const rxs);
CANARD_PRIVATE void rxSessionRestart(CanardInstance* const ins, CanardInternalRxSession* const rxs)
{
CANARD_ASSERT(ins != NULL);
Expand All @@ -708,11 +663,6 @@ CANARD_PRIVATE void rxSessionRestart(CanardInstance* const ins, CanardInternalRx
rxs->toggle = INITIAL_TOGGLE_STATE;
}

CANARD_PRIVATE int8_t rxSessionAcceptFrame(CanardInstance* const ins,
CanardInternalRxSession* const rxs,
const RxFrameModel* const frame,
const size_t extent,
CanardTransfer* const out_transfer);
CANARD_PRIVATE int8_t rxSessionAcceptFrame(CanardInstance* const ins,
CanardInternalRxSession* const rxs,
const RxFrameModel* const frame,
Expand Down Expand Up @@ -783,13 +733,6 @@ CANARD_PRIVATE int8_t rxSessionAcceptFrame(CanardInstance* const ins,
/// are given and the particular algorithms are left to be implementation-defined. Such abstract approach is much
/// advantageous because it allows implementers to choose whatever solution works best for the specific application at
/// hand, while the wire compatibility is still guaranteed by the high-level requirements given in the specification.
CANARD_PRIVATE int8_t rxSessionUpdate(CanardInstance* const ins,
CanardInternalRxSession* const rxs,
const RxFrameModel* const frame,
const uint8_t redundant_transport_index,
const CanardMicrosecond transfer_id_timeout_usec,
const size_t extent,
CanardTransfer* const out_transfer);
CANARD_PRIVATE int8_t rxSessionUpdate(CanardInstance* const ins,
CanardInternalRxSession* const rxs,
const RxFrameModel* const frame,
Expand Down Expand Up @@ -841,11 +784,6 @@ CANARD_PRIVATE int8_t rxSessionUpdate(CanardInstance* const ins,
return out;
}

CANARD_PRIVATE int8_t rxAcceptFrame(CanardInstance* const ins,
CanardRxSubscription* const subscription,
const RxFrameModel* const frame,
const uint8_t redundant_transport_index,
CanardTransfer* const out_transfer);
CANARD_PRIVATE int8_t rxAcceptFrame(CanardInstance* const ins,
CanardRxSubscription* const subscription,
const RxFrameModel* const frame,
Expand Down Expand Up @@ -1020,10 +958,11 @@ void canardTxPop(CanardInstance* const ins)
}
}

int8_t canardRxAccept(CanardInstance* const ins,
const CanardFrame* const frame,
const uint8_t redundant_transport_index,
CanardTransfer* const out_transfer)
int8_t canardRxAccept2(CanardInstance* const ins,
const CanardFrame* const frame,
const uint8_t redundant_transport_index,
CanardTransfer* const out_transfer,
CanardRxSubscription** const out_subscription)
{
int8_t out = -CANARD_ERROR_INVALID_ARGUMENT;
if ((ins != NULL) && (out_transfer != NULL) && (frame != NULL) && (frame->extended_can_id <= CAN_EXT_ID_MASK) &&
Expand All @@ -1044,6 +983,11 @@ int8_t canardRxAccept(CanardInstance* const ins,
sub = sub->_next;
}

if (out_subscription != NULL)
{
*out_subscription = sub; // Expose selected instance to the caller.
}

if (sub != NULL)
{
CANARD_ASSERT(sub->_port_id == model.port_id);
Expand All @@ -1068,6 +1012,14 @@ int8_t canardRxAccept(CanardInstance* const ins,
return out;
}

int8_t canardRxAccept(CanardInstance* const ins,
const CanardFrame* const frame,
const uint8_t redundant_transport_index,
CanardTransfer* const out_transfer)
{
return canardRxAccept2(ins, frame, redundant_transport_index, out_transfer, NULL);
}

int8_t canardRxSubscribe(CanardInstance* const ins,
const CanardTransferKind transfer_kind,
const CanardPortID port_id,
Expand Down
Loading

0 comments on commit 3879683

Please sign in to comment.