From a2ed997cb4616f5ca4e150c9c5116e6593269a18 Mon Sep 17 00:00:00 2001 From: Ilia Date: Mon, 14 Dec 2015 00:20:35 +0000 Subject: [PATCH 01/12] socketcan HW filters moved to userspace --- .../linux/include/uavcan_linux/socketcan.hpp | 59 +++++++++++++++---- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp index 638e0874ec..f3abdad535 100644 --- a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp +++ b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp @@ -148,6 +148,9 @@ class SocketCanIface : public uavcan::ICanIface std::queue rx_queue_; // TODO: Use pool allocator std::unordered_multiset pending_loopback_ids_; // TODO: Use pool allocator + std::vector hw_filters_container_; + bool filters_configured_ = false; + void registerError(SocketCanError e) { errors_[e]++; } void incrementNumFramesInSocketTxQueue() @@ -301,7 +304,17 @@ class SocketCanIface : public uavcan::ICanIface if (accept) { rx.ts_utc += clock_.getPrivateAdjustment(); - rx_queue_.push(rx); + if (filters_configured_) + { + if (checkHWFilters(rx.frame)) + { + rx_queue_.push(rx); + } + } + else + { + rx_queue_.push(rx); + } } } else if (res == 0) @@ -315,6 +328,22 @@ class SocketCanIface : public uavcan::ICanIface } } + /** + * Returns true if a frame accepted by HW filters + */ + bool checkHWFilters(const uavcan::CanFrame frame) + { + uint16_t container_size = hw_filters_container_.size(); + for (uint16_t i = 0; i < container_size; i++) + { + if (((frame.id & hw_filters_container_[i].mask) ^ hw_filters_container_[i].id) == 0) + { + return 1; + } + } + return 0; + } + public: /** * Takes ownership of socket's file descriptor. @@ -404,38 +433,46 @@ public: assert(0); return -1; } - std::vector< ::can_filter> filts(num_configs); + hw_filters_container_.clear(); + hw_filters_container_.resize(num_configs); + for (unsigned i = 0; i < num_configs; i++) { const uavcan::CanFilterConfig& fc = filter_configs[i]; - filts[i].can_id = fc.id & uavcan::CanFrame::MaskExtID; - filts[i].can_mask = fc.mask & uavcan::CanFrame::MaskExtID; + hw_filters_container_[i].id = fc.id & uavcan::CanFrame::MaskExtID; + hw_filters_container_[i].mask = fc.mask & uavcan::CanFrame::MaskExtID; if (fc.id & uavcan::CanFrame::FlagEFF) { - filts[i].can_id |= CAN_EFF_FLAG; + hw_filters_container_[i].id |= CAN_EFF_FLAG; } if (fc.id & uavcan::CanFrame::FlagRTR) { - filts[i].can_id |= CAN_RTR_FLAG; + hw_filters_container_[i].id |= CAN_RTR_FLAG; } if (fc.mask & uavcan::CanFrame::FlagEFF) { - filts[i].can_mask |= CAN_EFF_FLAG; + hw_filters_container_[i].mask |= CAN_EFF_FLAG; } if (fc.mask & uavcan::CanFrame::FlagRTR) { - filts[i].can_mask |= CAN_RTR_FLAG; + hw_filters_container_[i].mask |= CAN_RTR_FLAG; } } - int ret = setsockopt(fd_, SOL_CAN_RAW, CAN_RAW_FILTER, filts.data(), sizeof(::can_filter) * num_configs); - return (ret < 0) ? -1 : 0; + + if (! hw_filters_container_.empty()) + { + filters_configured_ = true; + return 0; + } + + return -1; } /** * SocketCAN emulates the CAN filters in software, so the number of filters is virtually unlimited. * This method returns a constant value. */ - std::uint16_t getNumFilters() const override { return 255; } + std::uint16_t getNumFilters() const override { return 8; } /** * Returns total number of errors of each kind detected since the object was created. From 5563dbacff677c88f74f44a805a206b88dc44efe Mon Sep 17 00:00:00 2001 From: Ilia Date: Wed, 16 Dec 2015 00:33:00 +0000 Subject: [PATCH 02/12] addFilterConfig() added. computeConfiguration() separated from applyConfiguration. Other small corrections --- .../can_acceptance_filter_configurator.hpp | 44 +++++---- .../uc_can_acceptance_filter_configurator.cpp | 95 ++++++++++++------- 2 files changed, 88 insertions(+), 51 deletions(-) diff --git a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp index e7c7d6e7a1..d73adda99e 100644 --- a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp +++ b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp @@ -21,10 +21,11 @@ namespace uavcan * preclude reception of irrelevant CAN frames on the hardware level. * * Configuration starts by creating an object of class @ref CanAcceptanceFilterConfigurator on the stack. - * Through the method configureFilters() it determines the number of available HW filters and the number - * of listeners. In case the number of listeners is higher than the number of available HW filters, the function - * automatically merges configs in the most efficient way until their number is reduced to the number of - * available HW filters. Subsequently obtained configurations are then loaded into the CAN driver. + * By means of computeConfiguration() method the class determines the number of available HW filters and the number + * of listeners. In case if custom configuration required, it is possible to add it through addFilterConfig(). + * Subsequently obtained configurations are then loaded into the CAN driver by calling the applyConfiguration() method. + * If the cumulative number of configurations obtained by computeConfiguration() and addFilterConfig() is higher than + * the number of available HW filters, configurations will be merged automatically in the most efficient way. * * The maximum number of CAN acceptance filters is predefined in uavcan/build_config.hpp through a constant * @ref MaxCanAcceptanceFilters. The algorithm doesn't allow to have higher number of HW filters configurations than @@ -57,7 +58,7 @@ private: * 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 messages, invoke configureFilters(IgnoreAnonymousMessages). + * frames. In case there are no anonymous messages, invoke computeConfiguration(IgnoreAnonymousMessages). */ static const unsigned DefaultFilterMsgMask = 0xFFFF80; static const unsigned DefaultFilterServiceMask = 0x7F80; @@ -72,7 +73,7 @@ private: uint16_t getNumFilters() const; /** - * Fills the multiset_configs_ to proceed it with computeConfiguration() + * Fills the multiset_configs_ to proceed it with mergeConfigurations() */ int16_t loadInputConfiguration(AnonymousMessages load_mode); @@ -80,35 +81,44 @@ private: * This method merges several listeners's filter configurations by predetermined algorithm * if number of available hardware acceptance filters less than number of listeners */ - int16_t computeConfiguration(); - - /** - * This method loads the configuration computed with computeConfiguration() to the CAN driver. - */ - int16_t applyConfiguration(); + int16_t mergeConfigurations(); INode& node_; //< Node reference is needed for access to ICanDriver and Dispatcher MultisetConfigContainer multiset_configs_; + uint16_t filters_number_; public: - explicit CanAcceptanceFilterConfigurator(INode& node) + explicit CanAcceptanceFilterConfigurator(INode& node, uint16_t filters_number = 0) : node_(node) , multiset_configs_(node.getAllocator()) + , filters_number_(filters_number) { } /** - * This method invokes loadInputConfiguration(), computeConfiguration() and applyConfiguration() consequently, so + * This method invokes loadInputConfiguration() and mergeConfigurations() consequently, so * that optimal acceptance filter configuration will be computed and loaded through CanDriver::configureFilters() * * @param mode Either: AcceptAnonymousMessages - the filters will accept all anonymous messages (this is default) * IgnoreAnonymousMessages - anonymous messages will be ignored * @return 0 = success, negative for error. */ - int configureFilters(AnonymousMessages mode = AcceptAnonymousMessages); + int computeConfiguration(AnonymousMessages mode = AcceptAnonymousMessages); /** - * Returns the configuration computed with computeConfiguration(). - * If computeConfiguration() has not been called yet, an empty configuration will be returned. + * Add the additional filter configuration to multiset_configs_. This method should be invoked only before + * computeConfiguration() member. + */ + int16_t addFilterConfig(const CanFilterConfig& config); + + /** + * This method loads the configuration computed with mergeConfigurations() or explicitly added by addFilterConfig() + * to the CAN driver. Must be called after computeConfiguration() and addFilterConfig(). + */ + int16_t applyConfiguration(); + + /** + * Returns the configuration computed with mergeConfigurations() or added by addFilterConfig(). + * If mergeConfigurations() or addFilterConfig() has not been called yet, an empty configuration will be returned. */ const MultisetConfigContainer& getConfiguration() const { diff --git a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp index 820c0b22d2..448ebe8405 100644 --- a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp +++ b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp @@ -16,24 +16,22 @@ const unsigned CanAcceptanceFilterConfigurator::DefaultAnonMsgID; int16_t CanAcceptanceFilterConfigurator::loadInputConfiguration(AnonymousMessages load_mode) { - multiset_configs_.clear(); - if (load_mode == AcceptAnonymousMessages) { CanFilterConfig anon_frame_cfg; - anon_frame_cfg.id = DefaultAnonMsgID; - anon_frame_cfg.mask = DefaultAnonMsgMask; + anon_frame_cfg.id = DefaultAnonMsgID | CanFrame::FlagEFF; + anon_frame_cfg.mask = DefaultAnonMsgMask | CanFrame::FlagEFF | CanFrame::FlagRTR | CanFrame::FlagERR; if (multiset_configs_.emplace(anon_frame_cfg) == NULL) { return -ErrMemory; } } - CanFilterConfig service_resp_cfg; - 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) + CanFilterConfig service_cfg; + service_cfg.id = DefaultFilterServiceID; + service_cfg.id |= (static_cast(node_.getNodeID().get()) << 8) | CanFrame::FlagEFF; + service_cfg.mask = DefaultFilterServiceMask | CanFrame::FlagEFF | CanFrame::FlagRTR | CanFrame::FlagERR; + if (multiset_configs_.emplace(service_cfg) == NULL) { return -ErrMemory; } @@ -42,8 +40,8 @@ int16_t CanAcceptanceFilterConfigurator::loadInputConfiguration(AnonymousMessage while (p != NULL) { CanFilterConfig cfg; - cfg.id = static_cast(p->getDataTypeDescriptor().getID().get()) << 8; - cfg.mask = DefaultFilterMsgMask; + cfg.id = (static_cast(p->getDataTypeDescriptor().getID().get()) << 8) | CanFrame::FlagEFF; + cfg.mask = DefaultFilterMsgMask | CanFrame::FlagEFF | CanFrame::FlagRTR | CanFrame::FlagERR; if (multiset_configs_.emplace(cfg) == NULL) { return -ErrMemory; @@ -56,20 +54,10 @@ int16_t CanAcceptanceFilterConfigurator::loadInputConfiguration(AnonymousMessage return -ErrLogic; } -#if UAVCAN_DEBUG - for (uint16_t i = 0; i < multiset_configs_.getSize(); i++) - { - UAVCAN_TRACE("CanAcceptanceFilterConfigurator::loadInputConfiguration()", "cfg.ID [%u] = %d", i, - multiset_configs_.getByIndex(i)->id); - UAVCAN_TRACE("CanAcceptanceFilterConfigurator::loadInputConfiguration()", "cfg.MK [%u] = %d", i, - multiset_configs_.getByIndex(i)->mask); - } -#endif - return 0; } -int16_t CanAcceptanceFilterConfigurator::computeConfiguration() +int16_t CanAcceptanceFilterConfigurator::mergeConfigurations() { const uint16_t acceptance_filters_number = getNumFilters(); if (acceptance_filters_number == 0) @@ -115,12 +103,27 @@ int16_t CanAcceptanceFilterConfigurator::computeConfiguration() int16_t CanAcceptanceFilterConfigurator::applyConfiguration(void) { CanFilterConfig filter_conf_array[MaxCanAcceptanceFilters]; - const unsigned int filter_array_size = multiset_configs_.getSize(); + unsigned int filter_array_size = multiset_configs_.getSize(); + + const uint16_t acceptance_filters_number = getNumFilters(); + if (acceptance_filters_number == 0) + { + UAVCAN_TRACE("CanAcceptanceFilter", "No HW filters available"); + return -ErrDriver; + } + + if (filter_array_size > acceptance_filters_number) + { + UAVCAN_TRACE("CanAcceptanceFilter", "Too many filter configurations. Executing computeConfiguration()"); + computeConfiguration(IgnoreAnonymousMessages); + filter_array_size = multiset_configs_.getSize(); + } if (filter_array_size > MaxCanAcceptanceFilters) { UAVCAN_ASSERT(0); return -ErrLogic; + UAVCAN_TRACE("CanAcceptanceFilter", "Failed to apply HW filter configuration"); } for (uint16_t i = 0; i < filter_array_size; i++) @@ -130,6 +133,16 @@ int16_t CanAcceptanceFilterConfigurator::applyConfiguration(void) filter_conf_array[i] = temp_filter_config; } +#if UAVCAN_DEBUG + for (uint16_t i = 0; i < multiset_configs_.getSize(); i++) + { + UAVCAN_TRACE("CanAcceptanceFilterConfigurator::applyConfiguration()", "cfg.ID [%u] = %d", i, + multiset_configs_.getByIndex(i)->id); + UAVCAN_TRACE("CanAcceptanceFilterConfigurator::applyConfiguration()", "cfg.MK [%u] = %d", i, + multiset_configs_.getByIndex(i)->mask); + } +#endif + ICanDriver& can_driver = node_.getDispatcher().getCanIOManager().getCanDriver(); for (uint8_t i = 0; i < node_.getDispatcher().getCanIOManager().getNumIfaces(); i++) { @@ -137,19 +150,21 @@ int16_t CanAcceptanceFilterConfigurator::applyConfiguration(void) if (iface == NULL) { return -ErrDriver; + UAVCAN_TRACE("CanAcceptanceFilter", "Failed to apply HW filter configuration"); } int16_t num = iface->configureFilters(reinterpret_cast(&filter_conf_array), static_cast(filter_array_size)); if (num < 0) { return -ErrDriver; + UAVCAN_TRACE("CanAcceptanceFilter", "Failed to apply HW filter configuration"); } } return 0; } -int CanAcceptanceFilterConfigurator::configureFilters(AnonymousMessages mode) +int CanAcceptanceFilterConfigurator::computeConfiguration(AnonymousMessages mode) { if (getNumFilters() == 0) { @@ -164,17 +179,11 @@ int CanAcceptanceFilterConfigurator::configureFilters(AnonymousMessages mode) return fill_array_error; } - int16_t compute_configuration_error = computeConfiguration(); - if (compute_configuration_error != 0) + int16_t merge_configurations_error = mergeConfigurations(); + if (merge_configurations_error != 0) { UAVCAN_TRACE("CanAcceptanceFilter", "Failed to compute optimal acceptance fliter's configuration"); - return compute_configuration_error; - } - - if (applyConfiguration() != 0) - { - UAVCAN_TRACE("CanAcceptanceFilter", "Failed to apply HW filter configuration"); - return -ErrDriver; + return merge_configurations_error; } return 0; @@ -182,8 +191,10 @@ int CanAcceptanceFilterConfigurator::configureFilters(AnonymousMessages mode) uint16_t CanAcceptanceFilterConfigurator::getNumFilters() const { + if (filters_number_ == 0) + { static const uint16_t InvalidOut = 0xFFFF; - uint16_t out = InvalidOut; + uint16_t out = InvalidOut; ICanDriver& can_driver = node_.getDispatcher().getCanIOManager().getCanDriver(); for (uint8_t i = 0; i < node_.getDispatcher().getCanIOManager().getNumIfaces(); i++) @@ -204,6 +215,22 @@ uint16_t CanAcceptanceFilterConfigurator::getNumFilters() const } return (out == InvalidOut) ? 0 : out; + } + else + { + return filters_number_; + } +} + +int16_t CanAcceptanceFilterConfigurator::addFilterConfig(const CanFilterConfig& config) +{ + CanFilterConfig supl_config = config; + if (multiset_configs_.emplace(supl_config) == NULL) + { + return -ErrMemory; + } + + return 0; } CanFilterConfig CanAcceptanceFilterConfigurator::mergeFilters(CanFilterConfig& a_, CanFilterConfig& b_) From 8a5719248f02f56aaef7c18995e14a92f7ec297a Mon Sep 17 00:00:00 2001 From: Ilia Date: Sat, 19 Dec 2015 16:43:29 +0000 Subject: [PATCH 03/12] HW acceptance filters unit test corrected. specificator changed for cfg.MK-ID print --- .../uc_can_acceptance_filter_configurator.cpp | 4 +- .../can_acceptance_filter_configurator.cpp | 109 ++++++++++++------ 2 files changed, 77 insertions(+), 36 deletions(-) diff --git a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp index 448ebe8405..9a2f9af901 100644 --- a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp +++ b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp @@ -136,9 +136,9 @@ int16_t CanAcceptanceFilterConfigurator::applyConfiguration(void) #if UAVCAN_DEBUG for (uint16_t i = 0; i < multiset_configs_.getSize(); i++) { - UAVCAN_TRACE("CanAcceptanceFilterConfigurator::applyConfiguration()", "cfg.ID [%u] = %d", i, + UAVCAN_TRACE("CanAcceptanceFilterConfigurator::applyConfiguration()", "cfg.ID [%u] = %u", i, multiset_configs_.getByIndex(i)->id); - UAVCAN_TRACE("CanAcceptanceFilterConfigurator::applyConfiguration()", "cfg.MK [%u] = %d", i, + UAVCAN_TRACE("CanAcceptanceFilterConfigurator::applyConfiguration()", "cfg.MK [%u] = %u", i, multiset_configs_.getByIndex(i)->mask); } #endif diff --git a/libuavcan/test/transport/can_acceptance_filter_configurator.cpp b/libuavcan/test/transport/can_acceptance_filter_configurator.cpp index ff3e647989..c3d2ba963a 100644 --- a/libuavcan/test/transport/can_acceptance_filter_configurator.cpp +++ b/libuavcan/test/transport/can_acceptance_filter_configurator.cpp @@ -123,21 +123,49 @@ TEST(CanAcceptanceFilter, Basic_test) sub_6.start(listener_6.bindExtended()); sub_6_1.start(listener_6.bindExtended()); server.start(writeServiceServerCallback); - std::cout << "Subscribers are initialized ..." << std::endl; + std::cout << "Subscribers are initialized." << std::endl; + uavcan::CanAcceptanceFilterConfigurator anon_test_configuration(node, 10); - uavcan::CanAcceptanceFilterConfigurator anon_test_configuration(node); - int configure_filters_assert = anon_test_configuration.configureFilters(); - if (configure_filters_assert == 0) - { - std::cout << "Filters are configured with anonymous configuration..." << std::endl; - } + uavcan::CanFilterConfig aux_config_1, aux_config_2; + aux_config_1.id = 0; + aux_config_1.mask = 1488; + aux_config_2.id = 24; + aux_config_2.mask = 72; + int configure_filters_assert; + configure_filters_assert = anon_test_configuration.addFilterConfig(aux_config_1); + ASSERT_EQ(configure_filters_assert, 0); + configure_filters_assert = anon_test_configuration.addFilterConfig(aux_config_2); + ASSERT_EQ(configure_filters_assert, 0); + + configure_filters_assert = anon_test_configuration.computeConfiguration(); + ASSERT_EQ(configure_filters_assert, 0); + std::cout << "Filters are calculated with anonymous configuration." << std::endl; const auto& configure_array = anon_test_configuration.getConfiguration(); uint32_t configure_array_size = configure_array.getSize(); + std::cout << "Number of configs after first time computeConfiguration() invoked: " + << configure_array_size << std::endl; + ASSERT_EQ(configure_array_size, 10); + std::cout << "Adding two additional configurations ... " << std::endl; + aux_config_2.id = 999999; + aux_config_2.mask = 849128412; + configure_filters_assert = anon_test_configuration.addFilterConfig(aux_config_1); ASSERT_EQ(configure_filters_assert, 0); - ASSERT_EQ(configure_array_size, 4); + configure_filters_assert = anon_test_configuration.addFilterConfig(aux_config_2); + ASSERT_EQ(configure_filters_assert, 0); + configure_array_size = configure_array.getSize(); + std::cout << "New configuration anon_container size: " << configure_array_size << std::endl; + ASSERT_EQ(configure_array_size, 12); + + std::cout << "Applying configuration ... " << std::endl; + configure_filters_assert = anon_test_configuration.applyConfiguration(); + ASSERT_EQ(configure_filters_assert, 0); + std::cout << "Filters are configured." << std::endl; + configure_array_size = configure_array.getSize(); + std::cout << "Final configuration anon_container size: " << configure_array_size << std::endl; + ASSERT_EQ(configure_array_size, 10); for (uint16_t i = 0; i MaxCanAcceptanceFilters) { UAVCAN_ASSERT(0); - return -ErrLogic; UAVCAN_TRACE("CanAcceptanceFilter", "Failed to apply HW filter configuration"); + return -ErrLogic; } for (uint16_t i = 0; i < filter_array_size; i++) @@ -149,15 +151,15 @@ int16_t CanAcceptanceFilterConfigurator::applyConfiguration(void) ICanIface* iface = can_driver.getIface(i); if (iface == NULL) { - return -ErrDriver; UAVCAN_TRACE("CanAcceptanceFilter", "Failed to apply HW filter configuration"); + return -ErrDriver; } int16_t num = iface->configureFilters(reinterpret_cast(&filter_conf_array), static_cast(filter_array_size)); if (num < 0) { - return -ErrDriver; UAVCAN_TRACE("CanAcceptanceFilter", "Failed to apply HW filter configuration"); + return -ErrDriver; } } @@ -194,7 +196,7 @@ uint16_t CanAcceptanceFilterConfigurator::getNumFilters() const if (filters_number_ == 0) { static const uint16_t InvalidOut = 0xFFFF; - uint16_t out = InvalidOut; + uint16_t out = InvalidOut; ICanDriver& can_driver = node_.getDispatcher().getCanIOManager().getCanDriver(); for (uint8_t i = 0; i < node_.getDispatcher().getCanIOManager().getNumIfaces(); i++) @@ -224,8 +226,7 @@ uint16_t CanAcceptanceFilterConfigurator::getNumFilters() const int16_t CanAcceptanceFilterConfigurator::addFilterConfig(const CanFilterConfig& config) { - CanFilterConfig supl_config = config; - if (multiset_configs_.emplace(supl_config) == NULL) + if (multiset_configs_.emplace(config) == NULL) { return -ErrMemory; } diff --git a/libuavcan/test/transport/can_acceptance_filter_configurator.cpp b/libuavcan/test/transport/can_acceptance_filter_configurator.cpp index c3d2ba963a..1d3f3fc6a7 100644 --- a/libuavcan/test/transport/can_acceptance_filter_configurator.cpp +++ b/libuavcan/test/transport/can_acceptance_filter_configurator.cpp @@ -127,28 +127,20 @@ TEST(CanAcceptanceFilter, Basic_test) uavcan::CanAcceptanceFilterConfigurator anon_test_configuration(node, 10); - uavcan::CanFilterConfig aux_config_1, aux_config_2; - aux_config_1.id = 0; - aux_config_1.mask = 1488; - aux_config_2.id = 24; - aux_config_2.mask = 72; - int configure_filters_assert; - configure_filters_assert = anon_test_configuration.addFilterConfig(aux_config_1); - ASSERT_EQ(configure_filters_assert, 0); - configure_filters_assert = anon_test_configuration.addFilterConfig(aux_config_2); - ASSERT_EQ(configure_filters_assert, 0); - - configure_filters_assert = anon_test_configuration.computeConfiguration(); + int configure_filters_assert = anon_test_configuration.computeConfiguration(); ASSERT_EQ(configure_filters_assert, 0); std::cout << "Filters are calculated with anonymous configuration." << std::endl; const auto& configure_array = anon_test_configuration.getConfiguration(); uint32_t configure_array_size = configure_array.getSize(); - std::cout << "Number of configs after first time computeConfiguration() invoked: " + std::cout << "Number of configurations after first time computeConfiguration() invoked: " << configure_array_size << std::endl; - ASSERT_EQ(configure_array_size, 10); + ASSERT_EQ(configure_array_size, 9); std::cout << "Adding two additional configurations ... " << std::endl; + uavcan::CanFilterConfig aux_config_1, aux_config_2; + aux_config_1.id = 911; + aux_config_1.mask = 1488; aux_config_2.id = 999999; aux_config_2.mask = 849128412; configure_filters_assert = anon_test_configuration.addFilterConfig(aux_config_1); @@ -157,7 +149,7 @@ TEST(CanAcceptanceFilter, Basic_test) ASSERT_EQ(configure_filters_assert, 0); configure_array_size = configure_array.getSize(); std::cout << "New configuration anon_container size: " << configure_array_size << std::endl; - ASSERT_EQ(configure_array_size, 12); + ASSERT_EQ(configure_array_size, 11); std::cout << "Applying configuration ... " << std::endl; configure_filters_assert = anon_test_configuration.applyConfiguration(); @@ -173,26 +165,26 @@ TEST(CanAcceptanceFilter, Basic_test) std::cout << "config.MK [" << i << "]= " << configure_array.getByIndex(i)->mask << std::endl; } - ASSERT_EQ(configure_array.getByIndex(0)->id, 2147489920); - ASSERT_EQ(configure_array.getByIndex(0)->mask, 3758129024); - ASSERT_EQ(configure_array.getByIndex(1)->id, 2147739648); - ASSERT_EQ(configure_array.getByIndex(1)->mask, 3774868352); - ASSERT_EQ(configure_array.getByIndex(2)->id, 0); - ASSERT_EQ(configure_array.getByIndex(2)->mask, 1488); - ASSERT_EQ(configure_array.getByIndex(3)->id, 999999); - ASSERT_EQ(configure_array.getByIndex(3)->mask, 849128412); - ASSERT_EQ(configure_array.getByIndex(4)->id, 2147745792); - ASSERT_EQ(configure_array.getByIndex(4)->mask, 3774872704); - ASSERT_EQ(configure_array.getByIndex(5)->id, 2147489920); - ASSERT_EQ(configure_array.getByIndex(5)->mask, 3758129024); - ASSERT_EQ(configure_array.getByIndex(6)->id, 2147745792); - ASSERT_EQ(configure_array.getByIndex(6)->mask, 3774868352); - ASSERT_EQ(configure_array.getByIndex(7)->id, 0); - ASSERT_EQ(configure_array.getByIndex(7)->mask, 1488); - ASSERT_EQ(configure_array.getByIndex(8)->id, 24); - ASSERT_EQ(configure_array.getByIndex(8)->mask, 72); - ASSERT_EQ(configure_array.getByIndex(9)->id, 2147483648); - ASSERT_EQ(configure_array.getByIndex(9)->mask, 3758096639); + ASSERT_EQ(configure_array.getByIndex(0)->id, 911); + ASSERT_EQ(configure_array.getByIndex(0)->mask, 1488); + ASSERT_EQ(configure_array.getByIndex(1)->id, 999999); + ASSERT_EQ(configure_array.getByIndex(1)->mask, 849128412); + ASSERT_EQ(configure_array.getByIndex(2)->id, 2147746048); + ASSERT_EQ(configure_array.getByIndex(2)->mask, 3774873472); + ASSERT_EQ(configure_array.getByIndex(3)->id, 2147744768); + ASSERT_EQ(configure_array.getByIndex(3)->mask, 3774873472); + ASSERT_EQ(configure_array.getByIndex(4)->id, 2147739648); + ASSERT_EQ(configure_array.getByIndex(4)->mask, 3774873472); + ASSERT_EQ(configure_array.getByIndex(5)->id, 2147746816); + ASSERT_EQ(configure_array.getByIndex(5)->mask, 3774873472); + ASSERT_EQ(configure_array.getByIndex(6)->id, 2147746304); + ASSERT_EQ(configure_array.getByIndex(6)->mask, 3774873472); + ASSERT_EQ(configure_array.getByIndex(7)->id, 2147483648); + ASSERT_EQ(configure_array.getByIndex(7)->mask, 3758096639); + ASSERT_EQ(configure_array.getByIndex(8)->id, 2147489920); + ASSERT_EQ(configure_array.getByIndex(8)->mask, 3758129024); + ASSERT_EQ(configure_array.getByIndex(9)->id, 2147749888); + ASSERT_EQ(configure_array.getByIndex(9)->mask, 3774873472); uavcan::CanAcceptanceFilterConfigurator no_anon_test_confiruration(node, 4); configure_filters_assert = no_anon_test_confiruration.computeConfiguration diff --git a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp index f3abdad535..bdc433a5b6 100644 --- a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp +++ b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp @@ -148,8 +148,7 @@ class SocketCanIface : public uavcan::ICanIface std::queue rx_queue_; // TODO: Use pool allocator std::unordered_multiset pending_loopback_ids_; // TODO: Use pool allocator - std::vector hw_filters_container_; - bool filters_configured_ = false; + std::vector<::can_filter> hw_filters_container_; void registerError(SocketCanError e) { errors_[e]++; } @@ -228,6 +227,16 @@ class SocketCanIface : public uavcan::ICanIface { return (res < 0 && errno == EWOULDBLOCK) ? 0 : res; } + /* + * Flags + */ + loopback = (msg.msg_flags & static_cast(MSG_CONFIRM)) != 0; + + if (!checkHWFilters(sockcan_frame) && !loopback) + { + return 0; + } + frame = makeUavcanFrame(sockcan_frame); /* * Timestamp @@ -246,10 +255,6 @@ class SocketCanIface : public uavcan::ICanIface assert(0); return -1; } - /* - * Flags - */ - loopback = (msg.msg_flags & static_cast(MSG_CONFIRM)) != 0; return 1; } @@ -304,17 +309,8 @@ class SocketCanIface : public uavcan::ICanIface if (accept) { rx.ts_utc += clock_.getPrivateAdjustment(); - if (filters_configured_) - { - if (checkHWFilters(rx.frame)) - { - rx_queue_.push(rx); - } - } - else - { - rx_queue_.push(rx); - } + rx_queue_.push(rx); + } } else if (res == 0) @@ -331,17 +327,24 @@ class SocketCanIface : public uavcan::ICanIface /** * Returns true if a frame accepted by HW filters */ - bool checkHWFilters(const uavcan::CanFrame frame) + bool checkHWFilters (const ::can_frame frame) const { - uint16_t container_size = hw_filters_container_.size(); - for (uint16_t i = 0; i < container_size; i++) + if (! hw_filters_container_.empty()) { - if (((frame.id & hw_filters_container_[i].mask) ^ hw_filters_container_[i].id) == 0) + uint16_t container_size = hw_filters_container_.size(); + for (uint16_t i = 0; i < container_size; i++) { - return 1; + if (((frame.can_id & hw_filters_container_[i].can_mask) ^ hw_filters_container_[i].can_id) == 0) + { + return true; + } } + return false; + } + else + { + return true; } - return 0; } public: @@ -439,40 +442,36 @@ public: for (unsigned i = 0; i < num_configs; i++) { const uavcan::CanFilterConfig& fc = filter_configs[i]; - hw_filters_container_[i].id = fc.id & uavcan::CanFrame::MaskExtID; - hw_filters_container_[i].mask = fc.mask & uavcan::CanFrame::MaskExtID; + hw_filters_container_[i].can_id = fc.id & uavcan::CanFrame::MaskExtID; + hw_filters_container_[i].can_mask = fc.mask & uavcan::CanFrame::MaskExtID; if (fc.id & uavcan::CanFrame::FlagEFF) { - hw_filters_container_[i].id |= CAN_EFF_FLAG; + hw_filters_container_[i].can_id |= CAN_EFF_FLAG; } if (fc.id & uavcan::CanFrame::FlagRTR) { - hw_filters_container_[i].id |= CAN_RTR_FLAG; + hw_filters_container_[i].can_id |= CAN_RTR_FLAG; } if (fc.mask & uavcan::CanFrame::FlagEFF) { - hw_filters_container_[i].mask |= CAN_EFF_FLAG; + hw_filters_container_[i].can_mask |= CAN_EFF_FLAG; } if (fc.mask & uavcan::CanFrame::FlagRTR) { - hw_filters_container_[i].mask |= CAN_RTR_FLAG; + hw_filters_container_[i].can_mask |= CAN_RTR_FLAG; } } - if (! hw_filters_container_.empty()) - { - filters_configured_ = true; - return 0; - } - - return -1; + return 0; } /** * SocketCAN emulates the CAN filters in software, so the number of filters is virtually unlimited. * This method returns a constant value. */ - std::uint16_t getNumFilters() const override { return 8; } + static constexpr unsigned NumFilters = 8; + std::uint16_t getNumFilters() const override { return NumFilters; } + /** * Returns total number of errors of each kind detected since the object was created. From 73f0a9074de131ae6d5a0721a4b55726190618f4 Mon Sep 17 00:00:00 2001 From: Ilia Date: Mon, 21 Dec 2015 00:34:38 +0000 Subject: [PATCH 05/12] uncrustify applied --- .../can_acceptance_filter_configurator.hpp | 3 +- .../uc_can_acceptance_filter_configurator.cpp | 57 +++++++++---------- .../linux/include/uavcan_linux/socketcan.hpp | 11 ++-- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp index d73adda99e..d8641b6b4f 100644 --- a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp +++ b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp @@ -68,7 +68,7 @@ private: typedef uavcan::Multiset MultisetConfigContainer; - static CanFilterConfig mergeFilters(CanFilterConfig &a_, CanFilterConfig &b_); + static CanFilterConfig mergeFilters(CanFilterConfig& a_, CanFilterConfig& b_); static uint8_t countBits(uint32_t n_); uint16_t getNumFilters() const; @@ -127,5 +127,4 @@ public: }; } - #endif // UAVCAN_BUILD_CONFIG_HPP_INCLUDED diff --git a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp index fa45b11411..cf551cb2cd 100644 --- a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp +++ b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp @@ -193,35 +193,35 @@ int CanAcceptanceFilterConfigurator::computeConfiguration(AnonymousMessages mode uint16_t CanAcceptanceFilterConfigurator::getNumFilters() const { - if (filters_number_ == 0) - { - static const uint16_t InvalidOut = 0xFFFF; - uint16_t out = InvalidOut; - ICanDriver& can_driver = node_.getDispatcher().getCanIOManager().getCanDriver(); - - for (uint8_t i = 0; i < node_.getDispatcher().getCanIOManager().getNumIfaces(); i++) + if (filters_number_ == 0) { - const ICanIface* iface = can_driver.getIface(i); - if (iface == NULL) - { - UAVCAN_ASSERT(0); - out = 0; - break; - } - const uint16_t num = iface->getNumFilters(); - out = min(out, num); - if (out > MaxCanAcceptanceFilters) - { - out = MaxCanAcceptanceFilters; - } - } + static const uint16_t InvalidOut = 0xFFFF; + uint16_t out = InvalidOut; + ICanDriver& can_driver = node_.getDispatcher().getCanIOManager().getCanDriver(); - return (out == InvalidOut) ? 0 : out; - } - else - { - return filters_number_; - } + for (uint8_t i = 0; i < node_.getDispatcher().getCanIOManager().getNumIfaces(); i++) + { + const ICanIface* iface = can_driver.getIface(i); + if (iface == NULL) + { + UAVCAN_ASSERT(0); + out = 0; + break; + } + const uint16_t num = iface->getNumFilters(); + out = min(out, num); + if (out > MaxCanAcceptanceFilters) + { + out = MaxCanAcceptanceFilters; + } + } + + return (out == InvalidOut) ? 0 : out; + } + else + { + return filters_number_; + } } int16_t CanAcceptanceFilterConfigurator::addFilterConfig(const CanFilterConfig& config) @@ -231,7 +231,7 @@ int16_t CanAcceptanceFilterConfigurator::addFilterConfig(const CanFilterConfig& return -ErrMemory; } - return 0; + return 0; } CanFilterConfig CanAcceptanceFilterConfigurator::mergeFilters(CanFilterConfig& a_, CanFilterConfig& b_) @@ -253,5 +253,4 @@ uint8_t CanAcceptanceFilterConfigurator::countBits(uint32_t n_) return c_; } - } diff --git a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp index bdc433a5b6..14383b3497 100644 --- a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp +++ b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp @@ -58,7 +58,7 @@ class SocketCanIface : public uavcan::ICanIface { static inline ::can_frame makeSocketCanFrame(const uavcan::CanFrame& uavcan_frame) { - ::can_frame sockcan_frame { uavcan_frame.id & uavcan::CanFrame::MaskExtID, uavcan_frame.dlc, { } }; + ::can_frame sockcan_frame { uavcan_frame.id& uavcan::CanFrame::MaskExtID, uavcan_frame.dlc, { } }; (void)std::copy(uavcan_frame.data, uavcan_frame.data + uavcan_frame.dlc, sockcan_frame.data); if (uavcan_frame.isExtended()) { @@ -310,7 +310,6 @@ class SocketCanIface : public uavcan::ICanIface { rx.ts_utc += clock_.getPrivateAdjustment(); rx_queue_.push(rx); - } } else if (res == 0) @@ -327,9 +326,9 @@ class SocketCanIface : public uavcan::ICanIface /** * Returns true if a frame accepted by HW filters */ - bool checkHWFilters (const ::can_frame frame) const + bool checkHWFilters(const ::can_frame frame) const { - if (! hw_filters_container_.empty()) + if (!hw_filters_container_.empty()) { uint16_t container_size = hw_filters_container_.size(); for (uint16_t i = 0; i < container_size; i++) @@ -486,7 +485,7 @@ public: /** * Returns number of errors of each kind in a map. */ - const decltype(errors_)& getErrors() const { return errors_; } + const decltype(errors_) & getErrors() const { return errors_; } int getFileDescriptor() const { return fd_; } @@ -537,7 +536,7 @@ public: goto fail; } // Non-blocking - if (::fcntl(s, F_SETFL , O_NONBLOCK) < 0) + if (::fcntl(s, F_SETFL, O_NONBLOCK) < 0) { goto fail; } From 7236370409d0c0921976b2f768c37fd12940788c Mon Sep 17 00:00:00 2001 From: Ilia Date: Sun, 27 Dec 2015 14:38:00 +0000 Subject: [PATCH 06/12] checkHWFilters arg by reference. loopback checked first --- libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp index 14383b3497..aae50675d7 100644 --- a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp +++ b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp @@ -232,7 +232,7 @@ class SocketCanIface : public uavcan::ICanIface */ loopback = (msg.msg_flags & static_cast(MSG_CONFIRM)) != 0; - if (!checkHWFilters(sockcan_frame) && !loopback) + if (!loopback && !checkHWFilters(sockcan_frame)) { return 0; } @@ -326,7 +326,7 @@ class SocketCanIface : public uavcan::ICanIface /** * Returns true if a frame accepted by HW filters */ - bool checkHWFilters(const ::can_frame frame) const + bool checkHWFilters(const ::can_frame& frame) const { if (!hw_filters_container_.empty()) { From 8f67bcbc39bd89150c443fbaaef6def9a53b22ad Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 27 Dec 2015 18:39:57 +0300 Subject: [PATCH 07/12] Updated copyrights and include guards in CAN filter cfger --- .../transport/can_acceptance_filter_configurator.hpp | 9 +++++---- .../transport/uc_can_acceptance_filter_configurator.cpp | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp index d8641b6b4f..ae34947567 100644 --- a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp +++ b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp @@ -1,10 +1,10 @@ /* - * Copyright (C) 2014 Pavel Kirienko , + * Copyright (C) 2015 Pavel Kirienko , * Ilia Sheremet */ -#ifndef UAVCAN_ACCEPTANCE_FILTER_CONFIGURATOR_HPP_INCLUDED -#define UAVCAN_ACCEPTANCE_FILTER_CONFIGURATOR_HPP_INCLUDED +#ifndef UAVCAN_TRANSPORT_CAN_ACCEPTANCE_FILTER_CONFIGURATOR_HPP_INCLUDED +#define UAVCAN_TRANSPORT_CAN_ACCEPTANCE_FILTER_CONFIGURATOR_HPP_INCLUDED #include #include @@ -127,4 +127,5 @@ public: }; } -#endif // UAVCAN_BUILD_CONFIG_HPP_INCLUDED + +#endif diff --git a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp index cf551cb2cd..efdd336455 100644 --- a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp +++ b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Pavel Kirienko , + * Copyright (C) 2015 Pavel Kirienko , * Ilia Sheremet */ From 9a55a4fc9b62568ed4253a71524ef6ea899e84e5 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 27 Dec 2015 19:34:16 +0300 Subject: [PATCH 08/12] CAN filter cfger API doc clarifications --- .../can_acceptance_filter_configurator.hpp | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp index ae34947567..3a240affed 100644 --- a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp +++ b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp @@ -27,6 +27,9 @@ namespace uavcan * If the cumulative number of configurations obtained by computeConfiguration() and addFilterConfig() is higher than * the number of available HW filters, configurations will be merged automatically in the most efficient way. * + * Note that if the application adds additional server or subscriber objects after the filters have been configured, + * the configuration procedure will have to be performed again. + * * The maximum number of CAN acceptance filters is predefined in uavcan/build_config.hpp through a constant * @ref MaxCanAcceptanceFilters. The algorithm doesn't allow to have higher number of HW filters configurations than * defined by MaxCanAcceptanceFilters. You can change this value according to the number specified in your CAN driver @@ -88,6 +91,13 @@ private: uint16_t filters_number_; public: + /** + * @param node Libuavcan node whose subscribers/servers/etc will be used to configure the filters. + * + * @param filters_number Allows to override the maximum number of hardware filters to use. + * If set to zero (which is default), the class will obtain the number of available + * filters from the CAN driver via @ref ICanIface::getNumFilters(). + */ explicit CanAcceptanceFilterConfigurator(INode& node, uint16_t filters_number = 0) : node_(node) , multiset_configs_(node.getAllocator()) @@ -95,8 +105,11 @@ public: { } /** - * This method invokes loadInputConfiguration() and mergeConfigurations() consequently, so - * that optimal acceptance filter configuration will be computed and loaded through CanDriver::configureFilters() + * This method invokes loadInputConfiguration() and mergeConfigurations() consequently + * in order to comute optimal filter configurations for the current hardware. + * + * It can only be invoked when all of the subscriber and server objects are initialized. + * If new subscriber or server objects are added later, the filters will have to be reconfigured again. * * @param mode Either: AcceptAnonymousMessages - the filters will accept all anonymous messages (this is default) * IgnoreAnonymousMessages - anonymous messages will be ignored @@ -105,8 +118,8 @@ public: int computeConfiguration(AnonymousMessages mode = AcceptAnonymousMessages); /** - * Add the additional filter configuration to multiset_configs_. This method should be invoked only before - * computeConfiguration() member. + * Add an additional filter configuration. + * This method must not be invoked after @ref computeConfiguration(). */ int16_t addFilterConfig(const CanFilterConfig& config); @@ -118,7 +131,7 @@ public: /** * Returns the configuration computed with mergeConfigurations() or added by addFilterConfig(). - * If mergeConfigurations() or addFilterConfig() has not been called yet, an empty configuration will be returned. + * If mergeConfigurations() or addFilterConfig() have not been called yet, an empty configuration will be returned. */ const MultisetConfigContainer& getConfiguration() const { From 288478fa4a5e051bbfa99446994d3a78d92f5dd7 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 27 Dec 2015 19:41:12 +0300 Subject: [PATCH 09/12] Linux driver: Avoiding use of cstdint from global scope, using proper loops --- libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp index aae50675d7..43799db066 100644 --- a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp +++ b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp @@ -330,10 +330,9 @@ class SocketCanIface : public uavcan::ICanIface { if (!hw_filters_container_.empty()) { - uint16_t container_size = hw_filters_container_.size(); - for (uint16_t i = 0; i < container_size; i++) + for (auto& f : hw_filters_container_) { - if (((frame.can_id & hw_filters_container_[i].can_mask) ^ hw_filters_container_[i].can_id) == 0) + if (((frame.can_id & f.can_mask) ^ f.can_id) == 0) { return true; } From 1447674bfa9523b75cf7014227c170054203d067 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 27 Dec 2015 19:42:38 +0300 Subject: [PATCH 10/12] CAN cfger - using consistent return types --- .../uavcan/transport/can_acceptance_filter_configurator.hpp | 6 ++++-- .../src/transport/uc_can_acceptance_filter_configurator.cpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp index 3a240affed..5b591602f1 100644 --- a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp +++ b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp @@ -120,14 +120,16 @@ public: /** * Add an additional filter configuration. * This method must not be invoked after @ref computeConfiguration(). + * @return 0 = success, negative for error. */ - int16_t addFilterConfig(const CanFilterConfig& config); + int addFilterConfig(const CanFilterConfig& config); /** * This method loads the configuration computed with mergeConfigurations() or explicitly added by addFilterConfig() * to the CAN driver. Must be called after computeConfiguration() and addFilterConfig(). + * @return 0 = success, negative for error. */ - int16_t applyConfiguration(); + int applyConfiguration(); /** * Returns the configuration computed with mergeConfigurations() or added by addFilterConfig(). diff --git a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp index efdd336455..a7d5a9f29f 100644 --- a/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp +++ b/libuavcan/src/transport/uc_can_acceptance_filter_configurator.cpp @@ -102,7 +102,7 @@ int16_t CanAcceptanceFilterConfigurator::mergeConfigurations() return 0; } -int16_t CanAcceptanceFilterConfigurator::applyConfiguration(void) +int CanAcceptanceFilterConfigurator::applyConfiguration(void) { CanFilterConfig filter_conf_array[MaxCanAcceptanceFilters]; unsigned int filter_array_size = multiset_configs_.getSize(); @@ -224,7 +224,7 @@ uint16_t CanAcceptanceFilterConfigurator::getNumFilters() const } } -int16_t CanAcceptanceFilterConfigurator::addFilterConfig(const CanFilterConfig& config) +int CanAcceptanceFilterConfigurator::addFilterConfig(const CanFilterConfig& config) { if (multiset_configs_.emplace(config) == NULL) { From 3e5f2e5efff8658c32ac52dcdfc0a3c05fb38849 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 27 Dec 2015 19:52:59 +0300 Subject: [PATCH 11/12] configureCanAcceptanceFilters() --- .../can_acceptance_filter_configurator.hpp | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp index 5b591602f1..22b98809e0 100644 --- a/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp +++ b/libuavcan/include/uavcan/transport/can_acceptance_filter_configurator.hpp @@ -141,6 +141,31 @@ public: } }; +/** + * This function is a shortcut for @ref CanAcceptanceFilterConfigurator. + * It allows to compute filter configuration and then apply it in just one step. + * It implements only the most common use case; if you have special requirements, + * use @ref CanAcceptanceFilterConfigurator directly. + * + * @param node Refer to @ref CanAcceptanceFilterConfigurator constructor for explanation. + * @param mode Refer to @ref CanAcceptanceFilterConfigurator::computeConfiguration() for explanation. + * @return non-negative on success, negative error code on error. + */ +static inline int configureCanAcceptanceFilters(INode& node, + CanAcceptanceFilterConfigurator::AnonymousMessages mode + = CanAcceptanceFilterConfigurator::AcceptAnonymousMessages) +{ + CanAcceptanceFilterConfigurator cfger(node); + + const int compute_res = cfger.computeConfiguration(mode); + if (compute_res < 0) + { + return compute_res; + } + + return cfger.applyConfiguration(); +} + } #endif From ff13fa866f75e6b32580a0c03c57d7b3a99787d5 Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Sun, 27 Dec 2015 20:01:22 +0300 Subject: [PATCH 12/12] Linux driver copyright update --- libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp index 43799db066..a0d988f77e 100644 --- a/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp +++ b/libuavcan_drivers/linux/include/uavcan_linux/socketcan.hpp @@ -1,5 +1,6 @@ /* - * Copyright (C) 2014 Pavel Kirienko + * Copyright (C) 2014-2015 Pavel Kirienko + * Ilia Sheremet */ #pragma once