From 5fa5a4f365cd7aa57d1dbc5db1308935bdc5732d Mon Sep 17 00:00:00 2001 From: ilia-sheremet Date: Fri, 24 Jul 2015 21:04:56 +0100 Subject: [PATCH] Acceptance filter update for new transport layer --- .../can_acceptance_filter_configurator.hpp | 46 ++++++++------- .../uc_can_acceptance_filter_configurator.cpp | 47 +++++++-------- .../can_acceptance_filter_configurator.cpp | 57 +++++++++++++------ 3 files changed, 90 insertions(+), 60 deletions(-) diff --git a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp index 2a0decf265..eb8b944ed4 100644 --- a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp +++ b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp @@ -16,6 +16,10 @@ namespace uavcan { +/** + * These arguments defines whether acceptance filter configuration has anonymous massages or not + */ +enum AnonMassagePresence {WithAnonMsg,NoAnonMsg}; /** * This class configures hardware acceptance filters (if this feature is present on the particular CAN driver) to @@ -35,22 +39,25 @@ namespace uavcan class CanAcceptanceFilterConfigurator { /** - * Below constants based on UAVCAN transport layer specification. Masks and ID's depends on message Priority, - * TypeID, TransferID (RequestNotResponse - for service types, BroadcastNotUnicast - for message types). + * Below constants based on UAVCAN transport layer specification. Masks and ID's depends on message + * TypeID, TransferID (RequestNotResponse - for service types, ServiceNotMessage - for all types of messages). * For more details refer to uavcan.org/CAN_bus_transport_layer_specification. - * For clarity let's represent "i" as Data Type ID - * DefaultFilterMsgMask = 00111111111110000000000000000 - * DefaultFilterMsgID = 00iiiiiiiiiii0000000000000000, no need to explicitly define, since MsgID initialized as 0. - * DefaultFilterServiceRequestMask = 11111111111100000000000000000 - * DefaultFilterServiceRequestID = 101iiiiiiiii00000000000000000 - * ServiceRespFrameMask = 11100000000000000000000000000 - * ServiceRespFrameID = 10000000000000000000000000000, all Service Response Frames are accepted by HW filters. + * For clarity let's represent "i" as Data Type ID and "d" as Destination Node Id + * DefaultFilterMsgMask = 00000 11111111 11111111 10000000 + * DefaultFilterMsgID = 00000 iiiiiiii iiiiiiii 00000000, no need to explicitly define, since MsgID initialized + * as 0. + * DefaultFilterServiceMask = 00000 00000000 01111111 10000000 + * DefaultFilterServiceID = 00000 00000000 0ddddddd 10000000, all Service Response Frames are accepted by + * HW filters. + * DefaultAnonMsgMask = 00000 00000000 00000000 11111111 + * DefaultAnonMsgID = 00000 00000000 00000000 00000000, by default the config is added to accept all anonymous + * frames. In case there are no anonymous massages, invoke configureFilters(NoAnonMsg). */ - static const unsigned DefaultFilterMsgMask = 0x7FF0000; - static const unsigned DefaultFilterServiceRequestID = 0x14000000; - static const unsigned DefaultFilterServiceRequestMask = 0x1FFE0000; - static const unsigned ServiceRespFrameID = 0x10000000; - static const unsigned ServiceRespFrameMask = 0x1C000000; + static const unsigned DefaultFilterMsgMask = 0xFFFF80; + static const unsigned DefaultFilterServiceMask = 0x7F80; + static const unsigned DefaultFilterServiceID = 0x80; + static const unsigned DefaultAnonMsgMask = 0xF; + static const unsigned DefaultAnonMsgID = 0x0; typedef uavcan::Multiset MultisetConfigContainer; @@ -61,7 +68,7 @@ class CanAcceptanceFilterConfigurator /** * Fills the multiset_configs_ to proceed it with computeConfiguration() */ - int16_t loadInputConfiguration(); + int16_t loadInputConfiguration(AnonMassagePresence load_mode); /** * This method merges several listeners's filter configurations by predetermined algorithm @@ -84,11 +91,12 @@ public: { } /** - * This method invokes loadInputConfiguration(), computeConfiguration() and applyConfiguration() consequently, so that - * optimal acceptance filter configuration will be computed and loaded through CanDriver::configureFilters() - * @return 0 = success, negative for error. + * This method invokes loadInputConfiguration(), computeConfiguration() and applyConfiguration() consequently, so + * that optimal acceptance filter configuration will be computed and loaded through CanDriver::configureFilters() + * @return 0 = success, negative for error. Input argument defines the presence of anonymous massages + * WithAnonMsg(default)/NoAnonMsg. */ - int configureFilters(); + int configureFilters(AnonMassagePresence mode = WithAnonMsg); /** * Returns the configuration computed with computeConfiguration(). diff --git a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp index 16fcb53a48..03690f43a6 100644 --- a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp +++ b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp @@ -9,18 +9,30 @@ namespace uavcan { const unsigned CanAcceptanceFilterConfigurator::DefaultFilterMsgMask; -const unsigned CanAcceptanceFilterConfigurator::DefaultFilterServiceRequestID; -const unsigned CanAcceptanceFilterConfigurator::DefaultFilterServiceRequestMask; -const unsigned CanAcceptanceFilterConfigurator::ServiceRespFrameID; -const unsigned CanAcceptanceFilterConfigurator::ServiceRespFrameMask; +const unsigned CanAcceptanceFilterConfigurator::DefaultFilterServiceID; +const unsigned CanAcceptanceFilterConfigurator::DefaultFilterServiceMask; +const unsigned CanAcceptanceFilterConfigurator::DefaultAnonMsgMask; +const unsigned CanAcceptanceFilterConfigurator::DefaultAnonMsgID; -int16_t CanAcceptanceFilterConfigurator::loadInputConfiguration() +int16_t CanAcceptanceFilterConfigurator::loadInputConfiguration(AnonMassagePresence load_mode) { multiset_configs_.clear(); + if (load_mode == WithAnonMsg) + { + CanFilterConfig anon_frame_cfg; + anon_frame_cfg.id = DefaultAnonMsgID; + anon_frame_cfg.mask = DefaultAnonMsgMask; + if (multiset_configs_.emplace(anon_frame_cfg) == NULL) + { + return -ErrMemory; + } + } + CanFilterConfig service_resp_cfg; - service_resp_cfg.id = ServiceRespFrameID; - service_resp_cfg.mask = ServiceRespFrameMask; + service_resp_cfg.id = DefaultFilterServiceID; + service_resp_cfg.id |= static_cast(node_.getNodeID().get()) << 8; + service_resp_cfg.mask = DefaultFilterServiceMask; if (multiset_configs_.emplace(service_resp_cfg) == NULL) { return -ErrMemory; @@ -30,8 +42,7 @@ int16_t CanAcceptanceFilterConfigurator::loadInputConfiguration() while (p) { CanFilterConfig cfg; - cfg.id = static_cast(p->getDataTypeDescriptor().getID().get()) << 16; - cfg.id |= static_cast(p->getDataTypeDescriptor().getKind()) << 8; + cfg.id = static_cast(p->getDataTypeDescriptor().getID().get()) << 8; cfg.mask = DefaultFilterMsgMask; if (multiset_configs_.emplace(cfg) == NULL) { @@ -40,20 +51,6 @@ int16_t CanAcceptanceFilterConfigurator::loadInputConfiguration() p = p->getNextListNode(); } - const TransferListenerBase* p1 = node_.getDispatcher().getListOfServiceRequestListeners().get(); - while (p1) - { - CanFilterConfig cfg; - cfg.id = DefaultFilterServiceRequestID; - cfg.id |= static_cast(p1->getDataTypeDescriptor().getID().get()) << 17; - cfg.mask = DefaultFilterServiceRequestMask; - if (multiset_configs_.emplace(cfg) == NULL) - { - return -ErrMemory; - } - p1 = p1->getNextListNode(); - } - if (multiset_configs_.getSize() == 0) { return -ErrLogic; @@ -152,7 +149,7 @@ int16_t CanAcceptanceFilterConfigurator::applyConfiguration(void) return 0; } -int CanAcceptanceFilterConfigurator::configureFilters() +int CanAcceptanceFilterConfigurator::configureFilters(AnonMassagePresence mode) { if (getNumFilters() == 0) { @@ -160,7 +157,7 @@ int CanAcceptanceFilterConfigurator::configureFilters() return -ErrDriver; } - int16_t fill_array_error = loadInputConfiguration(); + int16_t fill_array_error = loadInputConfiguration(mode); if (fill_array_error != 0) { UAVCAN_TRACE("CanAcceptanceFilter::loadInputConfiguration", "Failed to execute loadInputConfiguration()"); diff --git a/libuavcan/test/transport/can_acceptance_filter_configurator.cpp b/libuavcan/test/transport/can_acceptance_filter_configurator.cpp index 3ef59479c5..868fbf2bb3 100644 --- a/libuavcan/test/transport/can_acceptance_filter_configurator.cpp +++ b/libuavcan/test/transport/can_acceptance_filter_configurator.cpp @@ -19,10 +19,7 @@ #include #include #include -#include -// TODO FIXME: Requires update -#if 0 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11 template @@ -128,14 +125,15 @@ TEST(CanAcceptanceFilter, Basic_test) server.start(writeServiceServerCallback); std::cout << "Subscribers are initialized ..." << std::endl; - uavcan::CanAcceptanceFilterConfigurator test_configurator(node); - int configure_filters_assert = test_configurator.configureFilters(); + + uavcan::CanAcceptanceFilterConfigurator anon_test_configuration(node); + int configure_filters_assert = anon_test_configuration.configureFilters(); if (configure_filters_assert == 0) { - std::cout << "Filters are configured ..." << std::endl; + std::cout << "Filters are configured with anonymous configuration..." << std::endl; } - const auto& configure_array = test_configurator.getConfiguration(); + const auto& configure_array = anon_test_configuration.getConfiguration(); uint32_t configure_array_size = configure_array.getSize(); ASSERT_EQ(configure_filters_assert, 0); @@ -147,14 +145,41 @@ TEST(CanAcceptanceFilter, Basic_test) std::cout << "config.MK [" << i << "]= " << configure_array.getByIndex(i)->mask << std::endl; } - ASSERT_EQ(configure_array.getByIndex(0)->id, 268435456); - ASSERT_EQ(configure_array.getByIndex(0)->mask, 469762048); - ASSERT_EQ(configure_array.getByIndex(1)->id, 363069440); - ASSERT_EQ(configure_array.getByIndex(1)->mask, 536739840); - ASSERT_EQ(configure_array.getByIndex(2)->id, 16777216); - ASSERT_EQ(configure_array.getByIndex(2)->mask, 124452864); - ASSERT_EQ(configure_array.getByIndex(3)->id, 18874368); - ASSERT_EQ(configure_array.getByIndex(3)->mask, 133169152); + ASSERT_EQ(configure_array.getByIndex(0)->id, 0); + ASSERT_EQ(configure_array.getByIndex(0)->mask, 15); + ASSERT_EQ(configure_array.getByIndex(1)->id, 256000); + ASSERT_EQ(configure_array.getByIndex(1)->mask, 16771968); + ASSERT_EQ(configure_array.getByIndex(2)->id, 6272); + ASSERT_EQ(configure_array.getByIndex(2)->mask, 32640); + ASSERT_EQ(configure_array.getByIndex(3)->id, 262144); + ASSERT_EQ(configure_array.getByIndex(3)->mask, 16771200); + + + uavcan::CanAcceptanceFilterConfigurator no_anon_test_confiruration(node); + configure_filters_assert = no_anon_test_confiruration.configureFilters(uavcan::NoAnonMsg); + if (configure_filters_assert == 0) + { + std::cout << "Filters are configured without anonymous configuration..."<< std::endl; + } + const auto& configure_array_2 = no_anon_test_confiruration.getConfiguration(); + configure_array_size = configure_array_2.getSize(); + + ASSERT_EQ(configure_filters_assert, 0); + ASSERT_EQ(configure_array_size, 4); + + for (uint16_t i = 0; i