diff options
author | Romain Forlot <romain.forlot@iot.bzh> | 2017-06-20 10:24:05 +0000 |
---|---|---|
committer | Romain Forlot <romain.forlot@iot.bzh> | 2017-06-20 10:24:05 +0000 |
commit | 32e25cbca210a359b09768537b6f443fe90a3070 (patch) | |
tree | 3309794c15d8a8f8e9c1c08cad072ee1378813ba /CAN-binder/low-can-binding | |
parent | 76c43dec62b2e21cd6446360c00d4fe6b437533f (diff) |
Separation Generator to a dedicated repo
Change-Id: Id94831651c3266861435272a6e36c7884bef2c45
Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
Diffstat (limited to 'CAN-binder/low-can-binding')
42 files changed, 0 insertions, 5960 deletions
diff --git a/CAN-binder/low-can-binding/CMakeLists.txt b/CAN-binder/low-can-binding/CMakeLists.txt deleted file mode 100644 index cd38fca..0000000 --- a/CAN-binder/low-can-binding/CMakeLists.txt +++ /dev/null @@ -1,67 +0,0 @@ -########################################################################### -# Copyright 2015, 2016, 2017 IoT.bzh -# -# author: Fulup Ar Foll <fulup@iot.bzh> -# contrib: Romain Forlot <romain.forlot@iot.bzh> -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################### - -# Add target to project dependency list -PROJECT_TARGET_ADD(low-can) - - # Define project Targets - add_library(${TARGET_NAME} MODULE - binding/${TARGET_NAME}-hat.cpp - binding/${TARGET_NAME}-cb.cpp - binding/${TARGET_NAME}-subscription.cpp - binding/application.cpp - binding/application-generated.cpp - can/can-bus.cpp - can/can-message-set.cpp - can/can-message-definition.cpp - can/can-message.cpp - can/can-signals.cpp - can/can-decoder.cpp - diagnostic/diagnostic-message.cpp - diagnostic/diagnostic-manager.cpp - diagnostic/active-diagnostic-request.cpp - utils/signals.cpp - utils/openxc-utils.cpp - utils/timer.cpp - utils/socketcan.cpp - utils/socketcan-raw.cpp - utils/socketcan-bcm.cpp - utils/config-parser.cpp) - - # Binder exposes a unique public entry point - SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES - PREFIX "afb-" - LABELS "BINDING" - LINK_FLAGS ${BINDINGS_LINK_FLAG} - OUTPUT_NAME ${TARGET_NAME} - ) - - # Library dependencies (include updates automatically) - TARGET_LINK_LIBRARIES(${TARGET_NAME} - ini-config - openxc-message-format - uds-c - isotp-c - bitfield-c - ${link_libraries}) - - # installation directory - INSTALL(TARGETS ${TARGET_NAME} - LIBRARY DESTINATION ${BINDINGS_INSTALL_DIR}) - diff --git a/CAN-binder/low-can-binding/binding/application-generated.cpp b/CAN-binder/low-can-binding/binding/application-generated.cpp deleted file mode 100644 index 60a21f5..0000000 --- a/CAN-binder/low-can-binding/binding/application-generated.cpp +++ /dev/null @@ -1,564 +0,0 @@ -#include "application.hpp" -#include "../can/can-decoder.hpp" - -application_t::application_t() - : can_bus_manager_{utils::config_parser_t{"/etc/dev-mapping.conf"}} - , can_message_set_{ - {std::make_shared<can_message_set_t>(can_message_set_t{0,"example", - { // beginning can_message_definition_ vector - {std::make_shared<can_message_definition_t>(can_message_definition_t{"hs",0x3D9,can_message_format_t::STANDARD,frequency_clock_t(5.00000f),true, - { // beginning can_signals vector - {std::make_shared<can_signal_t> (can_signal_t{ - "engine.speed", - 16, - 16, - 0.250000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - nullptr, - nullptr, - false - })}, - {std::make_shared<can_signal_t> (can_signal_t{ - "fuel.level.low", - 55, - 1, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - decoder_t::booleanDecoder, - nullptr, - false - })}, - {std::make_shared<can_signal_t> (can_signal_t{ - "fuel.level", - 8, - 8, - 0.392157f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - nullptr, - nullptr, - false - })} - } // end can_signals vector - })} // end can_message_definition entry -, {std::make_shared<can_message_definition_t>(can_message_definition_t{"hs",0x3E9,can_message_format_t::STANDARD,frequency_clock_t(5.00000f),true, - { // beginning can_signals vector - {std::make_shared<can_signal_t> (can_signal_t{ - "vehicle.average.speed", - 0, - 15, - 0.0156250f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - nullptr, - nullptr, - false - })} - } // end can_signals vector - })} // end can_message_definition entry -, {std::make_shared<can_message_definition_t>(can_message_definition_t{"hs",0x4D1,can_message_format_t::STANDARD,frequency_clock_t(5.00000f),true, - { // beginning can_signals vector - {std::make_shared<can_signal_t> (can_signal_t{ - "engine.oil.temp", - 16, - 8, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - nullptr, - nullptr, - false - })}, - {std::make_shared<can_signal_t> (can_signal_t{ - "engine.oil.temp.high", - 7, - 1, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - decoder_t::booleanDecoder, - nullptr, - false - })} - } // end can_signals vector - })} // end can_message_definition entry -, {std::make_shared<can_message_definition_t>(can_message_definition_t{"hs",0x620,can_message_format_t::STANDARD,frequency_clock_t(5.00000f),true, - { // beginning can_signals vector - {std::make_shared<can_signal_t> (can_signal_t{ - "doors.boot.open", - 47, - 1, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - decoder_t::booleanDecoder, - nullptr, - false - })}, - {std::make_shared<can_signal_t> (can_signal_t{ - "doors.front_left.open", - 43, - 1, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - decoder_t::booleanDecoder, - nullptr, - false - })}, - {std::make_shared<can_signal_t> (can_signal_t{ - "doors.front_right.open", - 44, - 1, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - decoder_t::booleanDecoder, - nullptr, - false - })}, - {std::make_shared<can_signal_t> (can_signal_t{ - "doors.rear_left.open", - 46, - 1, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - decoder_t::booleanDecoder, - nullptr, - false - })}, - {std::make_shared<can_signal_t> (can_signal_t{ - "doors.rear_right.open", - 45, - 4, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - decoder_t::booleanDecoder, - nullptr, - false - })} - } // end can_signals vector - })} // end can_message_definition entry -, {std::make_shared<can_message_definition_t>(can_message_definition_t{"hs",0x799,can_message_format_t::STANDARD,frequency_clock_t(5.00000f),true, - { // beginning can_signals vector - {std::make_shared<can_signal_t> (can_signal_t{ - "windows.front_left.open", - 43, - 1, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - decoder_t::booleanDecoder, - nullptr, - false - })}, - {std::make_shared<can_signal_t> (can_signal_t{ - "windows.front_right.open", - 44, - 1, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - decoder_t::booleanDecoder, - nullptr, - false - })}, - {std::make_shared<can_signal_t> (can_signal_t{ - "windows.rear_left.open", - 46, - 1, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - decoder_t::booleanDecoder, - nullptr, - false - })}, - {std::make_shared<can_signal_t> (can_signal_t{ - "windows.rear_right.open", - 45, - 4, - 1.00000f, - 0.00000, - 0, - 0, - frequency_clock_t(0.00000f), - true, - false, - { - }, - false, - decoder_t::booleanDecoder, - nullptr, - false - })} - } // end can_signals vector - })} // end can_message_definition entry - - }, // end can_message_definition vector - { // beginning diagnostic_messages_ vector - {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 4, - "engine.load", - 0, - 0, - UNIT::INVALID, - 5.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 5, - "engine.coolant.temperature", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 10, - "fuel.pressure", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 11, - "intake.manifold.pressure", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 12, - "engine.speed", - 0, - 0, - UNIT::INVALID, - 5.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 13, - "vehicle.speed", - 0, - 0, - UNIT::INVALID, - 5.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 15, - "intake.air.temperature", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 16, - "mass.airflow", - 0, - 0, - UNIT::INVALID, - 5.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 17, - "throttle.position", - 0, - 0, - UNIT::INVALID, - 5.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 31, - "running.time", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 45, - "EGR.error", - 0, - 0, - UNIT::INVALID, - 0.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 47, - "fuel.level", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 51, - "barometric.pressure", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 70, - "ambient.air.temperature", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 76, - "commanded.throttle.position", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 82, - "ethanol.fuel.percentage", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 90, - "accelerator.pedal.position", - 0, - 0, - UNIT::INVALID, - 5.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 91, - "hybrid.battery-pack.remaining.life", - 0, - 0, - UNIT::INVALID, - 5.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 92, - "engine.oil.temperature", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 94, - "engine.fuel.rate", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} -, {std::make_shared<diagnostic_message_t>(diagnostic_message_t{ - 99, - "engine.torque", - 0, - 0, - UNIT::INVALID, - 1.00000f, - decoder_t::decode_obd2_response, - nullptr, - true - })} - - } // end diagnostic_messages_ vector - })} // end can_message_set entry - } // end can_message_set vector -{ - for(auto& cms: can_message_set_) - { - std::vector<std::shared_ptr<can_message_definition_t> >& can_messages_definition = cms->get_can_message_definition(); - for(auto& cmd : can_messages_definition) - { - cmd->set_parent(cms.get()); - std::vector<std::shared_ptr<can_signal_t> >& can_signals = cmd->get_can_signals(); - for(auto& sig: can_signals) - { - sig->set_parent(cmd.get()); - } - } - - std::vector<std::shared_ptr<diagnostic_message_t> >& diagnostic_messages = cms->get_diagnostic_messages(); - for(auto& dm : diagnostic_messages) - { - dm->set_parent(cms.get()); - } - } - } - -const std::string application_t::get_diagnostic_bus() const -{ - return "hs"; -} - - diff --git a/CAN-binder/low-can-binding/binding/application.cpp b/CAN-binder/low-can-binding/binding/application.cpp deleted file mode 100644 index 6e6353b..0000000 --- a/CAN-binder/low-can-binding/binding/application.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "application.hpp" - -#include "../utils/signals.hpp" -#include "../utils/openxc-utils.hpp" - -/// @brief Return singleton instance of configuration object. -application_t& application_t::instance() -{ - static application_t config; - return config; -} - -can_bus_t& application_t::get_can_bus_manager() -{ - return can_bus_manager_; -} - -diagnostic_manager_t& application_t::get_diagnostic_manager() -{ - return diagnostic_manager_; -} - -uint8_t application_t::get_active_message_set() const -{ - return active_message_set_; -} - -std::vector<std::shared_ptr<can_message_set_t> > application_t::get_can_message_set() -{ - return can_message_set_; -} - -std::vector<std::shared_ptr<can_signal_t> > application_t::get_all_can_signals() -{ - return can_message_set_[active_message_set_]->get_all_can_signals(); -} - -std::vector<std::shared_ptr<diagnostic_message_t> >& application_t::get_diagnostic_messages() -{ - return can_message_set_[active_message_set_]->get_diagnostic_messages(); -} - -std::vector<std::shared_ptr<can_message_definition_t> >& application_t::get_can_message_definition() -{ - return can_message_set_[active_message_set_]->get_can_message_definition(); -} - -uint32_t application_t::get_signal_id(diagnostic_message_t& sig) const -{ - return sig.get_pid(); -} - -uint32_t application_t::get_signal_id(can_signal_t& sig) const -{ - return sig.get_message()->get_id(); -} - -void application_t::set_active_message_set(uint8_t id) -{ - active_message_set_ = id; -} diff --git a/CAN-binder/low-can-binding/binding/application.hpp b/CAN-binder/low-can-binding/binding/application.hpp deleted file mode 100644 index 5fa6478..0000000 --- a/CAN-binder/low-can-binding/binding/application.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <map> -#include <vector> -#include <string> -#include <memory> - -#include "../can/can-bus.hpp" -#include "../can/can-message-set.hpp" -#include "../can/can-signals.hpp" -#include "../diagnostic/diagnostic-manager.hpp" - -#include "low-can-hat.hpp" - -/// -/// @brief Class representing a configuration attached to the binding. -/// -/// It regroups all needed objects instance from other class -/// that will be used along the binding life. It gets a global vision -/// on which signals are implemented for that binding. -/// Here, it is only the definition of the class with predefined accessors -/// methods used in the binding. -/// -/// It will be the reference point to needed objects. -/// -class application_t -{ - private: - can_bus_t can_bus_manager_; ///< instanciate the CAN bus manager. It's the one in charge of initialize the CAN bus devices. - diagnostic_manager_t diagnostic_manager_; ///< Diagnostic manager use to manage diagnostic message communication. - uint8_t active_message_set_ = 0; ///< Which is the active message set ? Default to 0. - - std::vector<std::shared_ptr<can_message_set_t> > can_message_set_; ///< Vector holding all message set from JSON signals description file - - application_t(); ///< Private constructor with implementation generated by the AGL generator. - - public: - static application_t& instance(); - - can_bus_t& get_can_bus_manager(); - - const std::string get_diagnostic_bus() const; - - diagnostic_manager_t& get_diagnostic_manager() ; - - uint8_t get_active_message_set() const; - - std::vector<std::shared_ptr<can_message_set_t> > get_can_message_set(); - - std::vector<std::shared_ptr<can_signal_t> > get_all_can_signals(); - - std::vector<std::shared_ptr<diagnostic_message_t> >& get_diagnostic_messages(); - - const std::vector<std::string>& get_signals_prefix() const; - - std::vector<std::shared_ptr<can_message_definition_t> >& get_can_message_definition(); - - uint32_t get_signal_id(diagnostic_message_t& sig) const; - - uint32_t get_signal_id(can_signal_t& sig) const; - - void set_active_message_set(uint8_t id); - -/* - /// TODO: implement this function as method into can_bus class - /// @brief Pre initialize actions made before CAN bus initialization - /// @param[in] bus A CanBus struct defining the bus's metadata - /// @param[in] writable Configure the controller in a writable mode. If false, it will be configured as "listen only" and will not allow writes or even CAN ACKs. - /// @param[in] buses An array of all CAN buses. - void pre_initialize(can_bus_dev_t* bus, bool writable, can_bus_dev_t* buses, const int busCount); - /// TODO: implement this function as method into can_bus class - /// @brief Post-initialize actions made after CAN bus initialization - /// @param[in] bus A CanBus struct defining the bus's metadata - /// @param[in] writable Configure the controller in a writable mode. If false, it will be configured as "listen only" and will not allow writes or even CAN ACKs. - /// @param[in] buses An array of all CAN buses. - void post_initialize(can_bus_dev_t* bus, bool writable, can_bus_dev_t* buses, const int busCount); - /// TODO: implement this function as method into can_bus class - /// @brief Check if the device is connected to an active CAN bus, i.e. it's received a message in the recent past. - /// @return true if a message was received on the CAN bus within CAN_ACTIVE_TIMEOUT_S seconds. - void logBusStatistics(can_bus_dev_t* buses, const int busCount); - /// TODO: implement this function as method into can_bus class - /// @brief Log transfer statistics about all active CAN buses to the debug log. - /// @param[in] buses An array of active CAN buses. - bool isBusActive(can_bus_dev_t* bus); - */ -}; - diff --git a/CAN-binder/low-can-binding/binding/low-can-cb.cpp b/CAN-binder/low-can-binding/binding/low-can-cb.cpp deleted file mode 100644 index 97b6d20..0000000 --- a/CAN-binder/low-can-binding/binding/low-can-cb.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loic Collignon" <loic.collignon@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "low-can-hat.hpp" - -#include <map> -#include <queue> -#include <mutex> -#include <vector> -#include <thread> -#include <json-c/json.h> -#include <systemd/sd-event.h> - -#include "openxc.pb.h" -#include "application.hpp" -#include "../can/can-bus.hpp" -#include "../can/can-signals.hpp" -#include "../can/can-message.hpp" -#include "../utils/signals.hpp" -#include "../diagnostic/diagnostic-message.hpp" -#include "../utils/openxc-utils.hpp" - - -///****************************************************************************** -/// -/// SystemD event loop Callbacks -/// -///*******************************************************************************/ - -void on_no_clients(std::shared_ptr<low_can_subscription_t> can_subscription, uint32_t pid, std::map<int, std::shared_ptr<low_can_subscription_t> >& s) -{ - if( ! can_subscription->get_diagnostic_message().empty() && can_subscription->get_diagnostic_message(pid) != nullptr) - { - DiagnosticRequest diag_req = can_subscription->get_diagnostic_message(pid)->build_diagnostic_request(); - active_diagnostic_request_t* adr = application_t::instance().get_diagnostic_manager().find_recurring_request(diag_req); - if( adr != nullptr) - application_t::instance().get_diagnostic_manager().cleanup_request(adr, true); - } - - on_no_clients(can_subscription, s); -} - -void on_no_clients(std::shared_ptr<low_can_subscription_t> can_subscription, std::map<int, std::shared_ptr<low_can_subscription_t> >& s) -{ - auto it = s.find(can_subscription->get_index()); - s.erase(it); -} - -static void push_n_notify(const can_message_t& cm) -{ - can_bus_t& cbm = application_t::instance().get_can_bus_manager(); - { - std::lock_guard<std::mutex> can_message_lock(cbm.get_can_message_mutex()); - cbm.push_new_can_message(cm); - } - cbm.get_new_can_message_cv().notify_one(); -} - -int read_message(sd_event_source *event_source, int fd, uint32_t revents, void *userdata) -{ - low_can_subscription_t* can_subscription = (low_can_subscription_t*)userdata; - if ((revents & EPOLLIN) != 0) - { - can_message_t cm; - utils::socketcan_bcm_t& s = can_subscription->get_socket(); - s >> cm; - - // Sure we got a valid CAN message ? - if(! cm.get_id() == 0 && ! cm.get_length() == 0) - {push_n_notify(cm);} - } - - // check if error or hangup - if ((revents & (EPOLLERR|EPOLLRDHUP|EPOLLHUP)) != 0) - { - sd_event_source_unref(event_source); - can_subscription->get_socket().close(); - } - return 0; -} - -///****************************************************************************** -/// -/// Subscription and unsubscription -/// -///*******************************************************************************/ - -static int make_subscription_unsubscription(struct afb_req request, std::shared_ptr<low_can_subscription_t>& can_subscription, std::map<int, std::shared_ptr<low_can_subscription_t> >& s, bool subscribe) -{ - /* Make the subscription or unsubscription to the event */ - if (((subscribe ? afb_req_subscribe : afb_req_unsubscribe)(request, s[can_subscription->get_index()]->get_event())) < 0) - { - ERROR("Operation goes wrong for signal: %s", can_subscription->get_name().c_str()); - return -1; - } - return 0; -} - -static int create_event_handle(std::shared_ptr<low_can_subscription_t>& can_subscription, std::map<int, std::shared_ptr<low_can_subscription_t> >& s) -{ - int sub_index = can_subscription->get_index(); - can_subscription->set_event(afb_daemon_make_event(can_subscription->get_name().c_str())); - s[sub_index] = can_subscription; - if (!afb_event_is_valid(s[sub_index]->get_event())) - { - ERROR("Can't create an event for %s, something goes wrong.", can_subscription->get_name().c_str()); - return -1; - } - return 0; -} - -/// @brief Will determine if it is needed or not to create the event handle and checks it to be sure that -/// we got a valid afb_event to get subscribe or unsubscribe. Then launch the subscription or unsubscription -/// against the application framework using that event handle. -static int subscribe_unsubscribe_signal(struct afb_req request, bool subscribe, std::shared_ptr<low_can_subscription_t>& can_subscription, std::map<int, std::shared_ptr<low_can_subscription_t> >& s) -{ - int ret = -1; - int sub_index = can_subscription->get_index(); - - if (can_subscription && s.find(sub_index) != s.end()) - { - if (!afb_event_is_valid(s[sub_index]->get_event()) && !subscribe) - { - NOTICE("Event isn't valid, no need to unsubscribed."); - ret = -1; - } - ret = 0; - } - else - { - /* Event doesn't exist , so let's create it */ - can_subscription->set_event({nullptr, nullptr}); - s[sub_index] = can_subscription; - ret = create_event_handle(can_subscription, s); - } - - // Check whether or not the event handler has been correctly created and - // make the subscription/unsubscription operation is so. - if (ret < 0) - return ret; - return make_subscription_unsubscription(request, can_subscription, s, subscribe); -} - -static int add_to_event_loop(std::shared_ptr<low_can_subscription_t>& can_subscription) -{ - struct sd_event_source* event_source = nullptr; - return ( sd_event_add_io(afb_daemon_get_event_loop(), - &event_source, - can_subscription->get_socket().socket(), - EPOLLIN, - read_message, - can_subscription.get())); -} - -static int subscribe_unsubscribe_diagnostic_messages(struct afb_req request, bool subscribe, std::vector<std::shared_ptr<diagnostic_message_t> > diagnostic_messages, struct event_filter_t& event_filter, std::map<int, std::shared_ptr<low_can_subscription_t> >& s) -{ - int rets = 0; - application_t& app = application_t::instance(); - diagnostic_manager_t& diag_m = app.get_diagnostic_manager(); - - for(const auto& sig : diagnostic_messages) - { - DiagnosticRequest* diag_req = new DiagnosticRequest(sig->build_diagnostic_request()); - event_filter.frequency = std::isnan(event_filter.frequency) ? sig->get_frequency() : event_filter.frequency; - std::shared_ptr<low_can_subscription_t> can_subscription; - - auto it = std::find_if(s.begin(), s.end(), [&sig](std::pair<int, std::shared_ptr<low_can_subscription_t> > sub){ return (! sub.second->get_diagnostic_message().empty());}); - can_subscription = it != s.end() ? - it->second : - std::make_shared<low_can_subscription_t>(low_can_subscription_t(event_filter)); - // If the requested diagnostic message isn't supported by the car then unsubcribe it - // no matter what we want, worse case will be a fail unsubscription but at least we don't - // poll a PID for nothing. - //TODO: Adding callback requesting ignition status: diag_req, sig.c_str(), false, diagnostic_message_t::decode_obd2_response, diagnostic_message_t::check_ignition_status, frequency); - if(sig->get_supported() && subscribe) - { - diag_m.add_recurring_request(diag_req, sig->get_name().c_str(), false, sig->get_decoder(), sig->get_callback(), event_filter.frequency); - if(can_subscription->create_rx_filter(sig) < 0) - {return -1;} - DEBUG("Signal: %s subscribed", sig->get_name().c_str()); - if(it == s.end() && add_to_event_loop(can_subscription) < 0) - { - diag_m.cleanup_request( - diag_m.find_recurring_request(*diag_req), true); - WARNING("signal: %s isn't supported. Canceling operation.", sig->get_name().c_str()); - return -1; - } - } - else - { - if(sig->get_supported()) - {DEBUG("%s cancelled due to unsubscribe", sig->get_name().c_str());} - else - { - WARNING("signal: %s isn't supported. Canceling operation.", sig->get_name().c_str()); - return -1; - } - } - int ret = subscribe_unsubscribe_signal(request, subscribe, can_subscription, s); - if(ret < 0) - return ret; - - rets++; - } - - return rets; -} - -static int subscribe_unsubscribe_can_signals(struct afb_req request, bool subscribe, std::vector<std::shared_ptr<can_signal_t> > can_signals, struct event_filter_t& event_filter, std::map<int, std::shared_ptr<low_can_subscription_t> >& s) -{ - int rets = 0; - for(const auto& sig: can_signals) - { - auto it = std::find_if(s.begin(), s.end(), [&sig](std::pair<int, std::shared_ptr<low_can_subscription_t> > sub){ return sub.second->get_can_signal() == sig; }); - std::shared_ptr<low_can_subscription_t> can_subscription; - if(it != s.end()) - { - can_subscription = it->second; - } - else - { - can_subscription = std::make_shared<low_can_subscription_t>(low_can_subscription_t(event_filter)); - if(can_subscription->create_rx_filter(sig) < 0) - {return -1;} - if(add_to_event_loop(can_subscription) < 0) - {return -1;} - } - - if(subscribe_unsubscribe_signal(request, subscribe, can_subscription, s) < 0) - {return -1;} - - rets++; - DEBUG("signal: %s subscribed", sig->get_name().c_str()); - } - return rets; -} - -/// -/// @brief subscribe to all signals in the vector signals -/// -/// @param[in] afb_req request : contain original request use to subscribe or unsubscribe -/// @param[in] subscribe boolean value used to chose between a subscription operation or an unsubscription -/// @param[in] signals - struct containing vectors with can_signal_t and diagnostic_messages to subscribe -/// -/// @return Number of correctly subscribed signal -/// -static int subscribe_unsubscribe_signals(struct afb_req request, bool subscribe, const struct utils::signals_found& signals, struct event_filter_t& event_filter) -{ - int rets = 0; - utils::signals_manager_t& sm = utils::signals_manager_t::instance(); - - std::lock_guard<std::mutex> subscribed_signals_lock(sm.get_subscribed_signals_mutex()); - std::map<int, std::shared_ptr<low_can_subscription_t> >& s = sm.get_subscribed_signals(); - - rets += subscribe_unsubscribe_diagnostic_messages(request, subscribe, signals.diagnostic_messages, event_filter, s); - rets += subscribe_unsubscribe_can_signals(request, subscribe, signals.can_signals, event_filter, s); - - return rets; -} - -static int one_subscribe_unsubscribe(struct afb_req request, bool subscribe, const std::string& tag, json_object* args) -{ - int ret = 0; - struct event_filter_t event_filter; - struct json_object *filter, *obj; - struct utils::signals_found sf; - - // computes the filter - if (json_object_object_get_ex(args, "filter", &filter)) - { - if (json_object_object_get_ex(filter, "frequency", &obj) - && (json_object_is_type(obj, json_type_double) || json_object_is_type(obj, json_type_int))) - { - event_filter.frequency = (float)json_object_get_double(obj); - ret += 1; - } - if (json_object_object_get_ex(filter, "min", &obj) - && (json_object_is_type(obj, json_type_double) || json_object_is_type(obj, json_type_int))) - { - event_filter.min = (float)json_object_get_double(obj); - ret += 2; - } - if (json_object_object_get_ex(filter, "max", &obj) - && (json_object_is_type(obj, json_type_double) || json_object_is_type(obj, json_type_int))) - { - event_filter.max = (float)json_object_get_double(obj); - ret += 4; - } - } - - // subscribe or unsubscribe - openxc_DynamicField search_key = build_DynamicField(tag); - sf = utils::signals_manager_t::instance().find_signals(search_key); - if (sf.can_signals.empty() && sf.diagnostic_messages.empty()) - NOTICE("No signal(s) found for %s.", tag.c_str()); - else - ret = subscribe_unsubscribe_signals(request, subscribe, sf, event_filter); - - return ret; -} - -static void do_subscribe_unsubscribe(struct afb_req request, bool subscribe) -{ - int i, n, rc, rc2; - struct json_object *args, *event, *x; - - args = afb_req_json(request); - if (args == NULL || !json_object_object_get_ex(args, "event", &event)) - { - rc = one_subscribe_unsubscribe(request, subscribe, "*", args); - } - else if (json_object_get_type(event) != json_type_array) - { - rc = one_subscribe_unsubscribe(request, subscribe, json_object_get_string(event), args); - } - else - { - rc = 0; - n = json_object_array_length(event); - for (i = 0 ; i < n ; i++) - { - x = json_object_array_get_idx(event, i); - rc2 = one_subscribe_unsubscribe(request, subscribe, json_object_get_string(x), args); - if (rc >= 0) - rc = rc2 >= 0 ? rc + rc2 : rc2; - } - } - - if (rc >= 0) - afb_req_success(request, NULL, NULL); - else - afb_req_fail(request, "error", NULL); -} - -void subscribe(struct afb_req request) -{ - do_subscribe_unsubscribe(request, true); -} - -void unsubscribe(struct afb_req request) -{ - do_subscribe_unsubscribe(request, false); -} diff --git a/CAN-binder/low-can-binding/binding/low-can-hat.cpp b/CAN-binder/low-can-binding/binding/low-can-hat.cpp deleted file mode 100644 index 7113b69..0000000 --- a/CAN-binder/low-can-binding/binding/low-can-hat.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loic Collignon" <loic.collignon@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "low-can-hat.hpp" -#include "low-can-subscription.hpp" - -#include <map> -#include <queue> -#include <mutex> -#include <vector> -#include <json-c/json.h> - -#include "application.hpp" -#include "../can/can-bus.hpp" - -extern "C" -{ - static int initv2(); - - static const struct afb_verb_v2 verbs[]= - { - { .verb= "subscribe", .callback= subscribe, .auth= NULL, .session= AFB_SESSION_NONE}, - { .verb= "unsubscribe", .callback= unsubscribe, .auth= NULL, .session= AFB_SESSION_NONE}, - { .verb= NULL, .callback= NULL, .auth= NULL, .session= 0} - }; - - const struct afb_binding_v2 afbBindingV2 { - .api = "low-can", - .specification = NULL, - .verbs = verbs, - .preinit = NULL, - .init = initv2, - .onevent = NULL, - .noconcurrency = 0 - }; - - /// @brief Initialize the binding. - /// - /// @param[in] service Structure which represent the Application Framework Binder. - /// - /// @return Exit code, zero if success. - static int initv2() - { - can_bus_t& can_bus_manager = application_t::instance().get_can_bus_manager(); - - can_bus_manager.set_can_devices(); - can_bus_manager.start_threads(); - - /// Initialize Diagnostic manager that will handle obd2 requests. - /// We pass by default the first CAN bus device to its Initialization. - /// TODO: be able to choose the CAN bus device that will be use as Diagnostic bus. - if(application_t::instance().get_diagnostic_manager().initialize()) - return 0; - - ERROR("There was something wrong with CAN device Initialization."); - return 1; - } -}; diff --git a/CAN-binder/low-can-binding/binding/low-can-hat.hpp b/CAN-binder/low-can-binding/binding/low-can-hat.hpp deleted file mode 100644 index cf3d999..0000000 --- a/CAN-binder/low-can-binding/binding/low-can-hat.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loic Collignon" <loic.collignon@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <cstddef> -#include <map> -#include <string> -#include <memory> -#include <systemd/sd-event.h> - -extern "C" -{ - #define AFB_BINDING_VERSION 2 - #include <afb/afb-binding.h> -}; - -class low_can_subscription_t; - -void on_no_clients(std::shared_ptr<low_can_subscription_t> can_subscription, std::map<int, std::shared_ptr<low_can_subscription_t> >& s); -void on_no_clients(std::shared_ptr<low_can_subscription_t> can_subscription, uint32_t pid, std::map<int, std::shared_ptr<low_can_subscription_t> >& s); -int read_message(sd_event_source *s, int fd, uint32_t revents, void *userdata); - -void subscribe(struct afb_req request); -void unsubscribe(struct afb_req request);
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/binding/low-can-subscription.cpp b/CAN-binder/low-can-binding/binding/low-can-subscription.cpp deleted file mode 100644 index 5488cc5..0000000 --- a/CAN-binder/low-can-binding/binding/low-can-subscription.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loic Collignon" <loic.collignon@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "low-can-hat.hpp" - -#include "low-can-subscription.hpp" -#include "application.hpp" -#include "canutil/write.h" - -low_can_subscription_t::low_can_subscription_t() - : index_{-1}, - event_filter_{event_filter_t()}, - socket_{} -{} - -low_can_subscription_t::low_can_subscription_t(struct event_filter_t event_filter) - : event_filter_{event_filter} -{} - -low_can_subscription_t::low_can_subscription_t( low_can_subscription_t&& s) - : index_{s.index_}, - event_filter_{s.event_filter_}, - socket_{std::move(s.socket_)} -{} - -low_can_subscription_t& low_can_subscription_t::operator=(const low_can_subscription_t& s) -{ - socket_ = std::move(s.socket_); - return *this; -} - -low_can_subscription_t::~low_can_subscription_t() -{ - socket_.close(); -} - -low_can_subscription_t::operator bool() const -{ - return ((can_signal_ != nullptr || ! diagnostic_message_.empty()) && afb_event_is_valid(event_)); -} - -struct afb_event& low_can_subscription_t::get_event() -{ - return event_; -} - -int low_can_subscription_t::get_index() const -{ - return index_; -} - -const std::shared_ptr<can_signal_t> low_can_subscription_t::get_can_signal() const -{ - return can_signal_; -} - -const std::vector<std::shared_ptr<diagnostic_message_t> > low_can_subscription_t::get_diagnostic_message() const -{ - return diagnostic_message_; -} - -/// @brief Retrieve a diagnostic_message subscribed from a pid -/// -/// @param[in] pid - Diagnostic messages PID to search for -/// -/// @return shared_ptr diagnostic_message_ if found and nullptr if not found -const std::shared_ptr<diagnostic_message_t> low_can_subscription_t::get_diagnostic_message(uint32_t pid) const -{ - for(const auto& diag: diagnostic_message_) - { - if(diag->get_pid() == pid) - { - return diag; - } - } - return nullptr; -} - -/// @brief Retrieve a diagnostic message search from its name -/// -/// @return shared_ptr diagnostic_message_ if found and nullptr if not found -const std::shared_ptr<diagnostic_message_t> low_can_subscription_t::get_diagnostic_message(const std::string& name) const -{ - for(const auto& diag: diagnostic_message_) - { - if(diag->get_name() == name) - { - return diag; - } - } - return nullptr; -} - -/// @brief Return the CAN signal name and empty string if not found -/// or no CAN signal subscribed -const std::string low_can_subscription_t::get_name() const -{ - if (can_signal_ != nullptr) - return can_signal_->get_name(); - - return ""; -} - -/// @brief Return name from a diagnostic message from a PID -/// -/// @param[in] pid - Diagnostic message PID -const std::string low_can_subscription_t::get_name(uint32_t pid) const -{ - if (!diagnostic_message_.empty()) - return get_diagnostic_message(pid)->get_name() ; - - return ""; -} - -float low_can_subscription_t::get_frequency() const -{ - return event_filter_.frequency; -} - -float low_can_subscription_t::get_min() const -{ - return event_filter_.min; -} - -float low_can_subscription_t::get_max() const -{ - return event_filter_.max; -} - -utils::socketcan_bcm_t& low_can_subscription_t::get_socket() -{ - return socket_; -} - -void low_can_subscription_t::set_event(struct afb_event event) -{ - event_ = event; -} - -void low_can_subscription_t::set_frequency(float freq) -{ - event_filter_.frequency = freq; -} - -void low_can_subscription_t::set_min(float min) -{ - event_filter_.min = min; -} - -void low_can_subscription_t::set_max(float max) -{ - event_filter_.max = max; -} - -/// @brief Based upon which object is subscribed CAN signal or diagnostic message -/// this will open the socket with the required CAN bus device name. -/// -/// @return INVALID_SOCKET on failure else positive integer -int low_can_subscription_t::open_socket() -{ - int ret = 0; - if(! socket_) - { - if( can_signal_ != nullptr) - {ret = socket_.open(can_signal_->get_message()->get_bus_device_name());} - else if (! diagnostic_message_ .empty()) - {ret = socket_.open(application_t::instance().get_diagnostic_manager().get_bus_device_name());} - index_ = (int)socket_.socket(); - } - return ret; -} - -/// @brief Build a BCM message head but don't set can_frame. -/// -/// @return a simple_bcm_msg with the msg_head parts set and can_frame -/// zeroed. -struct utils::simple_bcm_msg low_can_subscription_t::make_bcm_head(uint32_t can_id, uint32_t flags, const struct timeval& timeout, const struct timeval& frequency_thinning) const -{ - struct utils::simple_bcm_msg bcm_msg; - - memset(&bcm_msg, 0, sizeof(bcm_msg)); - - bcm_msg.msg_head.opcode = RX_SETUP; - bcm_msg.msg_head.can_id = can_id; - bcm_msg.msg_head.flags = flags; - bcm_msg.msg_head.ival1.tv_sec = timeout.tv_sec ; - bcm_msg.msg_head.ival1.tv_usec = timeout.tv_usec; - bcm_msg.msg_head.ival2.tv_sec = frequency_thinning.tv_sec ; - bcm_msg.msg_head.ival2.tv_usec = frequency_thinning.tv_usec; - - return bcm_msg; -} - -/// @brief Take an existing simple_bcm_msg struct and add a can_frame to it. -/// Only possible for now to add 1 uniq can_frame, it isn't possible to build -/// a multiplexed message with several can_frame. -void low_can_subscription_t::add_bcm_frame(const struct can_frame& cfd, struct utils::simple_bcm_msg& bcm_msg) const -{ - for(int i=0; i < CAN_MAX_DLEN; i++) - { - if(cfd.data[i] != 0) - { - bcm_msg.msg_head.nframes = 1; - bcm_msg.frames = cfd; - return; - } - } -} - -/// @brief Create a RX_SETUP receive job used by the BCM socket for a CAN signal -/// subscription -/// -/// @return 0 if ok else -1 -int low_can_subscription_t::create_rx_filter(std::shared_ptr<can_signal_t> sig) -{ - can_signal_= sig; - - struct can_frame cfd; - memset(&cfd, 0, sizeof(cfd)); - - float val = (float)(1 << can_signal_->get_bit_size()) - 1; - bitfield_encode_float(val, - can_signal_->get_bit_position(), - can_signal_->get_bit_size(), - can_signal_->get_factor(), - can_signal_->get_offset(), - cfd.data, - CAN_MAX_DLEN); - - struct timeval freq, timeout = {0, 0}; - frequency_clock_t f = std::isnan(event_filter_.frequency) ? can_signal_->get_frequency() : frequency_clock_t(event_filter_.frequency); - freq = f.get_timeval_from_period(); - - utils::simple_bcm_msg bcm_msg = make_bcm_head(can_signal_->get_message()->get_id(), SETTIMER|RX_NO_AUTOTIMER, timeout, freq); - add_bcm_frame(cfd, bcm_msg); - - return create_rx_filter(bcm_msg); -} - -/// @brief Create a RX_SETUP receive job used by the BCM socket for a -/// diagnostic message subscription. -/// -/// @return 0 if ok else -1 -int low_can_subscription_t::create_rx_filter(std::shared_ptr<diagnostic_message_t> sig) -{ - diagnostic_message_.push_back(sig); - - struct timeval freq = frequency_clock_t(event_filter_.frequency).get_timeval_from_period(); - //struct timeval timeout = frequency_clock_t(10).get_timeval_from_period(); - struct timeval timeout = {0,0}; - - utils::simple_bcm_msg bcm_msg = make_bcm_head(OBD2_FUNCTIONAL_BROADCAST_ID, SETTIMER|RX_NO_AUTOTIMER|RX_FILTER_ID, timeout, freq); - return create_rx_filter(bcm_msg); -} - -/// @brief Create a RX_SETUP receive job used by the BCM socket directly from -/// a simple_bcm_msg. You will not use this method directly but rather use the -/// two previous method with can_signal_t or diagnostic_message_t object. -/// -/// If the CAN arbitration ID is the OBD2 functional broadcast id the subscribed -/// to the 8 classics OBD2 functional response ID -/// -/// @return 0 if ok else -1 -int low_can_subscription_t::create_rx_filter(utils::simple_bcm_msg& bcm_msg) -{ - // Make sure that socket has been opened. - if(open_socket() < 0) - {return -1;} - - // If it isn't an OBD2 CAN ID then just add a simple RX_SETUP job - // else monitor all standard 8 CAN OBD2 ID response. - if(bcm_msg.msg_head.can_id != OBD2_FUNCTIONAL_BROADCAST_ID) - { - socket_ << bcm_msg; - if(! socket_) - return -1; - } - else - { - for(uint8_t i = 0; i < 8; i++) - { - bcm_msg.msg_head.can_id = OBD2_FUNCTIONAL_RESPONSE_START + i; - - socket_ << bcm_msg; - if(! socket_) - return -1; - } - } - - return 0; -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/binding/low-can-subscription.hpp b/CAN-binder/low-can-binding/binding/low-can-subscription.hpp deleted file mode 100644 index 0ad7e3a..0000000 --- a/CAN-binder/low-can-binding/binding/low-can-subscription.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - #pragma once - -#include <string> -#include <cmath> -#include <utility> - -#include "../can/can-signals.hpp" -#include "../diagnostic/diagnostic-message.hpp" -#include "../utils/socketcan-bcm.hpp" - -/// @brief Filtering values. Theses values has to be tested into -/// can_bus_t::apply_filter method. -struct event_filter_t -{ - float frequency; ///< frequency - Maximum frequency which will be received and pushed a subscribed event. - float min; ///< min - Minimum value that the signal don't have to go below to be pushed. - float max; ///< max - Maximum value that the signal don't have to go above to be pushed. - event_filter_t() : frequency{NAN}, min{NAN}, max{NAN} {} -}; - -/// @brief A subscription object used has a context that handle all needed values to describe a subscription -/// to the low-can binding. It can holds a CAN signal or diagnostic message. Diagnostic message for OBD2 is a kind -/// of special because there is only 1 listener to retrieve OBD2 requests. So it's needed that all diagnostic messages -/// subscriptions is to be in 1 object. -class low_can_subscription_t -{ -private: - int index_; ///< index_ - index number is the socket (int) casted - struct afb_event event_; ///< event_ - application framework event used to push on client - - /// Signal part - std::shared_ptr<can_signal_t> can_signal_; ///< can_signal_ - the CAN signal subscribed - std::vector<std::shared_ptr<diagnostic_message_t> > diagnostic_message_; ///< diagnostic_message_ - diagnostic messages meant to received OBD2 responses. - /// normal diagnostic request and response not tested for now. - - /// Filtering part - struct event_filter_t event_filter_; ///< event_filter_ - filtering values applied to a subscription - - utils::socketcan_bcm_t socket_; ///< socket_ - socket_ that receives CAN messages. -public: - low_can_subscription_t(); - low_can_subscription_t(struct event_filter_t event_filter); - low_can_subscription_t(const low_can_subscription_t& s) = delete; - low_can_subscription_t(low_can_subscription_t&& s); - ~low_can_subscription_t(); - - low_can_subscription_t& operator=(const low_can_subscription_t& s); - explicit operator bool() const; - - int get_index() const; - struct afb_event& get_event(); - const std::shared_ptr<can_signal_t> get_can_signal() const; - const std::shared_ptr<diagnostic_message_t> get_diagnostic_message(uint32_t pid) const; - const std::vector<std::shared_ptr<diagnostic_message_t> > get_diagnostic_message() const; - const std::shared_ptr<diagnostic_message_t> get_diagnostic_message(const std::string& name) const; - const std::string get_name() const; - const std::string get_name(uint32_t pid) const; - float get_frequency() const; - float get_min() const; - float get_max() const; - utils::socketcan_bcm_t& get_socket(); - - void set_event(struct afb_event event); - void set_frequency(float freq); - void set_min(float min); - void set_max(float max); - - struct utils::simple_bcm_msg make_bcm_head(uint32_t can_id, uint32_t flags, const struct timeval& timeout, const struct timeval& frequency_thinning) const; - void add_bcm_frame(const struct can_frame& cfd, struct utils::simple_bcm_msg& bcm_msg) const; - int open_socket(); - int create_rx_filter(std::shared_ptr<can_signal_t> sig); - int create_rx_filter(std::shared_ptr<diagnostic_message_t> sig); - int create_rx_filter(utils::simple_bcm_msg& bcm_msg); -}; diff --git a/CAN-binder/low-can-binding/can/can-bus.cpp b/CAN-binder/low-can-binding/can/can-bus.cpp deleted file mode 100644 index 6167335..0000000 --- a/CAN-binder/low-can-binding/can/can-bus.cpp +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <net/if.h> -#include <sys/socket.h> -#include <json-c/json.h> -#include <linux/can/raw.h> -#include <map> -#include <cerrno> -#include <vector> -#include <string> -#include <algorithm> - -#include "can-bus.hpp" - -#include "can-signals.hpp" -#include "can-decoder.hpp" -#include "../binding/application.hpp" -#include "../utils/signals.hpp" -#include "../utils/openxc-utils.hpp" - -/// @brief Class constructor -/// -/// @param[in] conf_file - handle to the json configuration file. -can_bus_t::can_bus_t(utils::config_parser_t conf_file) - : conf_file_{conf_file} -{} - -/// @brief Take a decoded message to determine if its value comply with the wanted -/// filtering values. -/// -/// @param[in] vehicle_message - A decoded message to analyze -/// @param[in] can_subscription - the subscription which will be notified depending -/// on its filtering values. Filtering values are stored in the event_filtermember. -/// -/// @return True if the value is compliant with event filter values, false if not... -bool can_bus_t::apply_filter(const openxc_VehicleMessage& vehicle_message, std::shared_ptr<low_can_subscription_t> can_subscription) -{ - bool send = false; - if(is_valid(vehicle_message)) - { - float min = std::isnan(can_subscription->get_min()) ? -INFINITY : can_subscription->get_min(); - float max = std::isnan(can_subscription->get_max()) ? INFINITY : can_subscription->get_max(); - double value = get_numerical_from_DynamicField(vehicle_message); - send = (value < min && value > max) ? false : true; - } - return send; -} - -/// @brief Will make the decoding operation on a classic CAN message. It will not -/// handle CAN commands nor diagnostic messages that have their own method to get -/// this happens. -/// -/// It will add to the vehicle_message queue the decoded message and tell the event push -/// thread to process it. -/// -/// @param[in] can_message - a single CAN message from the CAN socket read, to be decode. -/// -/// @return How many signals has been decoded. -void can_bus_t::process_can_signals(const can_message_t& can_message, std::map<int, std::shared_ptr<low_can_subscription_t> >& s) -{ - int subscription_id = can_message.get_sub_id(); - openxc_DynamicField decoded_message; - openxc_VehicleMessage vehicle_message; - - // First we have to found which can_signal_t it is - std::shared_ptr<low_can_subscription_t> sig = s[subscription_id]; - - if( s.find(subscription_id) != s.end() && afb_event_is_valid(s[subscription_id]->get_event())) - { - bool send = true; - decoded_message = decoder_t::translateSignal(*sig->get_can_signal(), can_message, application_t::instance().get_all_can_signals(), &send); - openxc_SimpleMessage s_message = build_SimpleMessage(sig->get_name(), decoded_message); - vehicle_message = build_VehicleMessage(s_message, can_message.get_timestamp()); - - if(send && apply_filter(vehicle_message, sig)) - { - std::lock_guard<std::mutex> decoded_can_message_lock(decoded_can_message_mutex_); - push_new_vehicle_message(subscription_id, vehicle_message); - DEBUG("%s CAN signals processed.", sig->get_name().c_str()); - } - } -} - -/// @brief Will make the decoding operation on a diagnostic CAN message.Then it find the subscribed signal -/// corresponding and will add the vehicle_message to the queue of event to pushed before notifying -/// the event push thread to process it. -/// -/// @param[in] manager - the diagnostic manager object that handle diagnostic communication -/// @param[in] can_message - a single CAN message from the CAN socket read, to be decode. -/// -/// @return How many signals has been decoded. -void can_bus_t::process_diagnostic_signals(diagnostic_manager_t& manager, const can_message_t& can_message, std::map<int, std::shared_ptr<low_can_subscription_t> >& s) -{ - int subscription_id = can_message.get_sub_id(); - - openxc_VehicleMessage vehicle_message = manager.find_and_decode_adr(can_message); - if( (vehicle_message.has_simple_message && vehicle_message.simple_message.has_name) && - s.find(subscription_id) != s.end() && afb_event_is_valid(s[subscription_id]->get_event())) - { - if (apply_filter(vehicle_message, s[subscription_id])) - { - std::lock_guard<std::mutex> decoded_can_message_lock(decoded_can_message_mutex_); - push_new_vehicle_message(subscription_id, vehicle_message); - DEBUG("%s CAN signals processed.", s[subscription_id]->get_name().c_str()); - } - } -} - -/// @brief thread to decoding raw CAN messages. -/// -/// Depending on the nature of message, if arbitration ID matches ID for a diagnostic response -/// then decoding a diagnostic message else use classic CAN signals decoding functions. -/// -/// It will take from the can_message_q_ queue the next can message to process then it search -/// about signal subscribed if there is a valid afb_event for it. We only decode signal for which a -/// subscription has been made. Can message will be decoded using translateSignal that will pass it to the -/// corresponding decoding function if there is one assigned for that signal. If not, it will be the default -/// noopDecoder function that will operate on it. -/// -/// TODO: make diagnostic messages parsing optionnal. -void can_bus_t::can_decode_message() -{ - utils::signals_manager_t& sm = utils::signals_manager_t::instance(); - - while(is_decoding_) - { - std::unique_lock<std::mutex> can_message_lock(can_message_mutex_); - new_can_message_cv_.wait(can_message_lock); - while(!can_message_q_.empty()) - { - const can_message_t can_message = next_can_message(); - can_message_lock.unlock(); - - { - std::lock_guard<std::mutex> subscribed_signals_lock(sm.get_subscribed_signals_mutex()); - std::map<int, std::shared_ptr<low_can_subscription_t> >& s = sm.get_subscribed_signals(); - if(application_t::instance().get_diagnostic_manager().is_diagnostic_response(can_message)) - {process_diagnostic_signals(application_t::instance().get_diagnostic_manager(), can_message, s);} - else - {process_can_signals(can_message, s);} - } - can_message_lock.lock(); - } - new_decoded_can_message_.notify_one(); - can_message_lock.unlock(); - } -} - -/// @brief thread to push events to suscribers. It will read subscribed_signals map to look -/// which are events that has to be pushed. -void can_bus_t::can_event_push() -{ - openxc_SimpleMessage s_message; - json_object* jo; - utils::signals_manager_t& sm = utils::signals_manager_t::instance(); - - while(is_pushing_) - { - std::unique_lock<std::mutex> decoded_can_message_lock(decoded_can_message_mutex_); - new_decoded_can_message_.wait(decoded_can_message_lock); - while(!vehicle_message_q_.empty()) - { - std::pair<int, openxc_VehicleMessage> v_message = next_vehicle_message(); - decoded_can_message_lock.unlock(); - { - std::lock_guard<std::mutex> subscribed_signals_lock(sm.get_subscribed_signals_mutex()); - std::map<int, std::shared_ptr<low_can_subscription_t> >& s = sm.get_subscribed_signals(); - s_message = get_simple_message(v_message.second); - if(s.find(v_message.first) != s.end() && afb_event_is_valid(s[v_message.first]->get_event())) - { - jo = json_object_new_object(); - jsonify_simple(s_message, jo); - if(afb_event_push(s[v_message.first]->get_event(), jo) == 0) - { - if(v_message.second.has_diagnostic_response) - {on_no_clients(s[v_message.first], v_message.second.diagnostic_response.pid, s);} - else - {on_no_clients(s[v_message.first], s);} - } - } - } - decoded_can_message_lock.lock(); - } - decoded_can_message_lock.unlock(); - } -} - -/// @brief Will initialize threads that will decode -/// and push subscribed events. -void can_bus_t::start_threads() -{ - is_decoding_ = true; - th_decoding_ = std::thread(&can_bus_t::can_decode_message, this); - th_decoding_.detach(); - - is_pushing_ = true; - th_pushing_ = std::thread(&can_bus_t::can_event_push, this); - th_pushing_.detach(); -} - -/// @brief Will stop all threads holded by can_bus_t object -/// which are decoding and pushing then will wait that's -/// they'll finish their job. -void can_bus_t::stop_threads() -{ - is_decoding_ = false; - is_pushing_ = false; -} - -/// @brief return new_can_message_cv_ member -/// -/// @return return new_can_message_cv_ member -std::condition_variable& can_bus_t::get_new_can_message_cv() -{ - return new_can_message_cv_; -} - -/// @brief return can_message_mutex_ member -/// -/// @return return can_message_mutex_ member -std::mutex& can_bus_t::get_can_message_mutex() -{ - return can_message_mutex_; -} - -/// @brief Return first can_message_t on the queue -/// -/// @return a can_message_t -const can_message_t can_bus_t::next_can_message() -{ - can_message_t can_msg; - - if(!can_message_q_.empty()) - { - can_msg = can_message_q_.front(); - can_message_q_.pop(); - DEBUG("Here is the next can message : id %X, length %X, data %02X%02X%02X%02X%02X%02X%02X%02X", can_msg.get_id(), can_msg.get_length(), - can_msg.get_data()[0], can_msg.get_data()[1], can_msg.get_data()[2], can_msg.get_data()[3], can_msg.get_data()[4], can_msg.get_data()[5], can_msg.get_data()[6], can_msg.get_data()[7]); - return can_msg; - } - - return can_msg; -} - -/// @brief Push a can_message_t into the queue -/// -/// @param[in] can_msg - the const reference can_message_t object to push into the queue -void can_bus_t::push_new_can_message(const can_message_t& can_msg) -{ - can_message_q_.push(can_msg); -} - -/// @brief Return first openxc_VehicleMessage on the queue -/// -/// @return a openxc_VehicleMessage containing a decoded can message -std::pair<int, openxc_VehicleMessage> can_bus_t::next_vehicle_message() -{ - std::pair<int, openxc_VehicleMessage> v_msg; - - if(! vehicle_message_q_.empty()) - { - v_msg = vehicle_message_q_.front(); - vehicle_message_q_.pop(); - DEBUG("next vehicle message poped"); - return v_msg; - } - - return v_msg; -} - -/// @brief Push a openxc_VehicleMessage into the queue -/// -/// @param[in] v_msg - const reference openxc_VehicleMessage object to push into the queue -void can_bus_t::push_new_vehicle_message(int subscription_id, const openxc_VehicleMessage& v_msg) -{ - vehicle_message_q_.push(std::make_pair(subscription_id, v_msg)); -} - -/// @brief Fills the CAN device map member with value from device -/// mapping configuration file read at initialization. -void can_bus_t::set_can_devices() -{ - can_devices_ = conf_file_.get_devices_name(); - - if(can_devices_.empty()) - { - ERROR("No mapping found in config file: '%s'. Check it that it have a CANbus-mapping section.", - conf_file_.filepath().c_str()); - } -} - - -/// @brief Return the CAN device index from the map -/// map are sorted so index depend upon alphabetical sorting. -int can_bus_t::get_can_device_index(const std::string& bus_name) const -{ - int i = 0; - for(const auto& d: can_devices_) - { - if(d.first == bus_name) - break; - i++; - } - return i; -} - -/// @brief Return CAN device name from a logical CAN device name gotten from -/// the signals.json description file which comes from a CAN databases file in -/// general. -const std::string can_bus_t::get_can_device_name(const std::string& id_name) const -{ - std::string ret; - for(const auto& d: can_devices_) - { - if(d.first == id_name) - { - ret = d.second; - break; - } - } - return ret; -} diff --git a/CAN-binder/low-can-binding/can/can-bus.hpp b/CAN-binder/low-can-binding/can/can-bus.hpp deleted file mode 100644 index a76d3e8..0000000 --- a/CAN-binder/low-can-binding/can/can-bus.hpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2015, 2016, 2017 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loïc Collignon" <loic.collignon@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <utility> -#include <mutex> -#include <queue> -#include <thread> -#include <linux/can.h> -#include <condition_variable> - -#include "openxc.pb.h" -#include "can-message.hpp" -#include "../utils/config-parser.hpp" -#include "../binding/low-can-hat.hpp" -#include "../binding/low-can-subscription.hpp" - -// TODO actual max is 32 but dropped to 24 for memory considerations -#define MAX_ACCEPTANCE_FILTERS 24 -// TODO this takes up a ton of memory -#define MAX_DYNAMIC_MESSAGE_COUNT 12 - -#define CAN_ACTIVE_TIMEOUT_S 30 - -class diagnostic_manager_t; - -/// @brief Object used to handle decoding and manage event queue to be pushed. -/// -/// This object is also used to initialize can_bus_dev_t object after reading -/// json conf file describing the CAN devices to use. Thus, those object will read -/// on the device the CAN frame and push them into the can_bus_t can_message_q_ queue. -/// -/// That queue will be later used to be decoded and pushed to subscribers. -class can_bus_t -{ -private: - utils::config_parser_t conf_file_; ///< configuration file handle used to initialize can_bus_dev_t objects. - - bool apply_filter(const openxc_VehicleMessage& vehicle_message, std::shared_ptr<low_can_subscription_t> can_subscription); - void process_can_signals(const can_message_t& can_message, std::map<int, std::shared_ptr<low_can_subscription_t> >& s); - void process_diagnostic_signals(diagnostic_manager_t& manager, const can_message_t& can_message, std::map<int, std::shared_ptr<low_can_subscription_t> >& s); - - void can_decode_message(); - std::thread th_decoding_; ///< thread that'll handle decoding a can frame - bool is_decoding_ = false; ///< boolean member controling thread while loop - - void can_event_push(); - std::thread th_pushing_; ///< thread that'll handle pushing decoded can frame to subscribers - bool is_pushing_ = false; ///< boolean member controling thread while loop - - std::condition_variable new_can_message_cv_; ///< condition_variable use to wait until there is a new CAN message to read - std::mutex can_message_mutex_; ///< mutex protecting the can_message_q_ queue. - std::queue <can_message_t> can_message_q_; ///< queue that'll store can_message_t to decoded - - std::condition_variable new_decoded_can_message_; ///< condition_variable use to wait until there is a new vehicle message to read from the queue vehicle_message_q_ - std::mutex decoded_can_message_mutex_; ///< mutex protecting the vehicle_message_q_ queue. - std::queue <std::pair<int, openxc_VehicleMessage> > vehicle_message_q_; ///< queue that'll store openxc_VehicleMessage to pushed - - std::vector<std::pair<std::string, std::string> > can_devices_; ///< can_devices_ - holds a mapping between logical CAN devices names and linux CAN devices names. -public: - explicit can_bus_t(utils::config_parser_t conf_file); - can_bus_t(can_bus_t&&); - - void set_can_devices(); - int get_can_device_index(const std::string& bus_name) const; - const std::string get_can_device_name(const std::string& id_name) const; - - void start_threads(); - void stop_threads(); - - const can_message_t next_can_message(); - void push_new_can_message(const can_message_t& can_msg); - std::mutex& get_can_message_mutex(); - std::condition_variable& get_new_can_message_cv(); - - std::pair<int, openxc_VehicleMessage> next_vehicle_message(); - void push_new_vehicle_message(int subscription_id, const openxc_VehicleMessage& v_msg); -}; diff --git a/CAN-binder/low-can-binding/can/can-command.hpp b/CAN-binder/low-can-binding/can/can-command.hpp deleted file mode 100644 index 4cf20cb..0000000 --- a/CAN-binder/low-can-binding/can/can-command.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "openxc.pb.h" -#include "can-signals.hpp" - -/// -/// @brief The type signature for a function to handle a custom OpenXC command. -/// -/// @param[in] name - the name of the received command. -/// @param[in] value - the value of the received command, in a DynamicField. The actual type -/// may be a number, string or bool. -/// @param[in] event - an optional event from the received command, in a DynamicField. The -/// actual type may be a number, string or bool. -/// @param[in] signals - The list of all signals. -/// @param[in] signalCount - The length of the signals array. -/// -typedef void (*CommandHandler)(const char* name, openxc_DynamicField* value, - openxc_DynamicField* event, can_signal_t* signals, int signalCount); - -/// @struct CanCommand -/// @brief The structure to represent a supported custom OpenXC command. -/// -/// For completely customized CAN commands without a 1-1 mapping between an -/// OpenXC message from the host and a CAN signal, you can define the name of the -/// command and a custom function to handle it in the VI. An example is -/// the "turn_signal_status" command in OpenXC, which has a value of "left" or -/// "right". The vehicle may have separate CAN signals for the left and right -/// turn signals, so you will need to implement a custom command handler to send -/// the correct signals. -/// -/// Command handlers are also useful if you want to trigger multiple CAN messages -/// or signals from a signal OpenXC message. -/// -typedef struct { - const char* generic_name; /*!< generic_name - The name of the command.*/ - CommandHandler handler; /*!< handler - An function to process the received command's data and perform some - * action.*/ -} CanCommand; diff --git a/CAN-binder/low-can-binding/can/can-decoder.cpp b/CAN-binder/low-can-binding/can/can-decoder.cpp deleted file mode 100644 index 61bfe75..0000000 --- a/CAN-binder/low-can-binding/can/can-decoder.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "can-decoder.hpp" - -#include "canutil/read.h" -#include "../utils/openxc-utils.hpp" -#include "can-message-definition.hpp" -#include "../binding/low-can-hat.hpp" - -/// @brief Parse the signal's bitfield from the given data and return the raw -/// value. -/// -/// @param[in] signal - The signal to parse from the data. -/// @param[in] message - can_message_t to parse -/// -/// @return Returns the raw value of the signal parsed as a bitfield from the given byte -/// array. -/// -float decoder_t::parseSignalBitfield(can_signal_t& signal, const can_message_t& message) -{ - return bitfield_parse_float(message.get_data(), CAN_MESSAGE_SIZE, - signal.get_bit_position(), signal.get_bit_size(), signal.get_factor(), - signal.get_offset()); -} - -/// @brief Wrap a raw CAN signal value in a DynamicField without modification. -/// -/// This is an implementation of the SignalDecoder type signature, and can be -/// used directly in the can_signal_t.decoder field. -/// -/// @param[in] signal - The details of the signal that contains the state mapping. -/// @param[in] signals - The list of all signals -/// @param[in] value - The numerical value that will be wrapped in a DynamicField. -/// @param[out] send - An output argument that will be set to false if the value should -/// not be sent for any reason. -/// -/// @return Returns a DynamicField with the original, unmodified raw CAN signal value as -/// its numeric value. The 'send' argument will not be modified as this decoder -/// always succeeds. -/// -openxc_DynamicField decoder_t::noopDecoder(can_signal_t& signal, - const std::vector<std::shared_ptr<can_signal_t> >& signals, float value, bool* send) -{ - openxc_DynamicField decoded_value = build_DynamicField(value); - - return decoded_value; -} -/// @brief Coerces a numerical value to a boolean. -/// -/// This is an implementation of the SignalDecoder type signature, and can be -/// used directly in the can_signal_t.decoder field. -/// -/// @param[in] signal - The details of the signal that contains the state mapping. -/// @param[in] signals - The list of all signals -/// @param[in] value - The numerical value that will be converted to a boolean. -/// @param[out] send - An output argument that will be set to false if the value should -/// not be sent for any reason. -/// -/// @return Returns a DynamicField with a boolean value of false if the raw signal value -/// is 0.0, otherwise true. The 'send' argument will not be modified as this -/// decoder always succeeds. -/// -openxc_DynamicField decoder_t::booleanDecoder(can_signal_t& signal, - const std::vector<std::shared_ptr<can_signal_t> >& signals, float value, bool* send) -{ - openxc_DynamicField decoded_value = build_DynamicField(value == 0.0 ? false : true); - - return decoded_value; -} -/// @brief Update the metadata for a signal and the newly received value. -/// -/// This is an implementation of the SignalDecoder type signature, and can be -/// used directly in the can_signal_t.decoder field. -/// -/// This function always flips 'send' to false. -/// -/// @param[in] signal - The details of the signal that contains the state mapping. -/// @param[in] signals - The list of all signals. -/// @param[in] value - The numerical value that will be converted to a boolean. -/// @param[out] send - This output argument will always be set to false, so the caller will -/// know not to publish this value to the pipeline. -/// -/// @return Return value is undefined. -/// -openxc_DynamicField decoder_t::ignoreDecoder(can_signal_t& signal, - const std::vector<std::shared_ptr<can_signal_t> >& signals, float value, bool* send) -{ - if(send) - *send = false; - - openxc_DynamicField decoded_value; - - return decoded_value; -} - -/// @brief Find and return the corresponding string state for a CAN signal's -/// raw integer value. -/// -/// This is an implementation of the SignalDecoder type signature, and can be -/// used directly in the can_signal_t.decoder field. -/// -/// @param[in] signal - The details of the signal that contains the state mapping. -/// @param[in] signals - The list of all signals. -/// @param[in] value - The numerical value that should map to a state. -/// @param[out] send - An output argument that will be set to false if the value should -/// not be sent for any reason. -/// -/// @return Returns a DynamicField with a string value if a matching state is found in -/// the signal. If an equivalent isn't found, send is sent to false and the -/// return value is undefined. -/// -openxc_DynamicField decoder_t::stateDecoder(can_signal_t& signal, - const std::vector<std::shared_ptr<can_signal_t> >& signals, float value, bool* send) -{ - const std::string signal_state = signal.get_states((uint8_t)value); - openxc_DynamicField decoded_value = build_DynamicField(signal_state); - if(signal_state.size() <= 0) - { - *send = false; - ERROR("No state found with index: %d", (int)value); - } - return decoded_value; -} - - -/// @brief Parse a signal from a CAN message, apply any required transforations -/// to get a human readable value and public the result to the pipeline. -/// -/// If the can_signal_t has a non-NULL 'decoder' field, the raw CAN signal value -/// will be passed to the decoder before publishing. -/// -/// @param[in] signal - The details of the signal to decode and forward. -/// @param[in] message - The received CAN message that should contain this signal. -/// @param[in] signals - an array of all active signals. -/// @param[out] send - An output parameter that will be flipped to false if the value could -/// not be decoded. -/// -/// The decoder returns an openxc_DynamicField, which may contain a number, -/// string or boolean. -/// -openxc_DynamicField decoder_t::translateSignal(can_signal_t& signal, const can_message_t& message, - const std::vector<std::shared_ptr<can_signal_t> >& signals, bool* send) -{ - float value = decoder_t::parseSignalBitfield(signal, message); - DEBUG("Decoded message from parseSignalBitfield: %f", value); - - // Must call the decoders every time, regardless of if we are going to - // decide to send the signal or not. - openxc_DynamicField decoded_value = decoder_t::decodeSignal(signal, - value, signals, send); - - signal.set_received(true); - - // Don't send if they is no changes - if ((signal.get_last_value() == value && !signal.get_send_same()) || !*send ) - { - *send = false; - } - signal.set_last_value(value); - signal.set_timestamp(message.get_timestamp()); - signal.get_message()->set_last_value(message); - return decoded_value; -} - -/// @brief Parse a signal from a CAN message and apply any required -/// transforations to get a human readable value. -/// -/// If the can_signal_t has a non-NULL 'decoder' field, the raw CAN signal value -/// will be passed to the decoder before returning. -/// -/// @param[in] signal - The details of the signal to decode and forward. -/// @param[in] value - The numerical value that will be converted to a boolean. -/// @param[in] signals - an array of all active signals. -/// @param[out] send - An output parameter that will be flipped to false if the value could -/// not be decoded. -/// -/// @return The decoder returns an openxc_DynamicField, which may contain a number, -/// string or boolean. If 'send' is false, the return value is undefined. -/// -openxc_DynamicField decoder_t::decodeSignal( can_signal_t& signal, - float value, const std::vector<std::shared_ptr<can_signal_t> >& signals, bool* send) -{ - SignalDecoder decoder = signal.get_decoder() == nullptr ? - noopDecoder : signal.get_decoder(); - openxc_DynamicField decoded_value = decoder(signal, signals, - value, send); - return decoded_value; -} - -/// @brief Decode a transformed, human readable value from an raw CAN signal -/// already parsed from a CAN message. -/// -/// This is the same as decodeSignal but you must parse the bitfield value of the signal from the CAN -/// message yourself. This is useful if you need that raw value for something -/// else. -/// -/// @param[in] signal - The details of the signal to decode and forward. -/// @param[in] message - Raw CAN message to decode -/// @param[in] signals - an array of all active signals. -/// @param[out] send - An output parameter that will be flipped to false if the value could -/// not be decoded. -/// -openxc_DynamicField decoder_t::decodeSignal( can_signal_t& signal, - const can_message_t& message, const std::vector<std::shared_ptr<can_signal_t> >& signals, bool* send) -{ - float value = parseSignalBitfield(signal, message); - return decodeSignal(signal, value, signals, send); -} - - -/// -/// @brief Decode the payload of an OBD-II PID. -/// -/// This function matches the type signature for a DiagnosticResponseDecoder, so -/// it can be used as the decoder for a DiagnosticRequest. It returns the decoded -/// value of the PID, using the standard formulas (see -/// http://en.wikipedia.org/wiki/OBD-II_PIDs#Mode_01). -/// -/// @param[in] response - the received DiagnosticResponse (the data is in response.payload, -/// a byte array). This is most often used when the byte order is -/// signiticant, i.e. with many OBD-II PID formulas. -/// @param[in] parsed_payload - the entire payload of the response parsed as an int. -/// -/// @return Float decoded value. -/// -float decoder_t::decode_obd2_response(const DiagnosticResponse* response, float parsed_payload) -{ - return diagnostic_decode_obd2_pid(response); -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/can/can-decoder.hpp b/CAN-binder/low-can-binding/can/can-decoder.hpp deleted file mode 100644 index 7eaa4a7..0000000 --- a/CAN-binder/low-can-binding/can/can-decoder.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "can-signals.hpp" -#include "can-message.hpp" -#include "openxc.pb.h" - -class decoder_t -{ -public: - static float parseSignalBitfield(can_signal_t& signal, const can_message_t& message); - - static openxc_DynamicField stateDecoder(can_signal_t& signal, const std::vector<std::shared_ptr<can_signal_t> >& signals, - float value, bool* send); - static openxc_DynamicField booleanDecoder(can_signal_t& signal, const std::vector<std::shared_ptr<can_signal_t> >& signals, - float value, bool* send); - static openxc_DynamicField ignoreDecoder(can_signal_t& signal, const std::vector<std::shared_ptr<can_signal_t> >& signals, - float value, bool* send); - static openxc_DynamicField noopDecoder(can_signal_t& signal, const std::vector<std::shared_ptr<can_signal_t> >& signals, - float value, bool* send); - - static openxc_DynamicField translateSignal(can_signal_t& signal, const can_message_t& message, - const std::vector<std::shared_ptr<can_signal_t> >& signals, bool* send); - - static openxc_DynamicField decodeSignal(can_signal_t& signal, const can_message_t& message, - const std::vector<std::shared_ptr<can_signal_t> >& signals, bool* send); - - static openxc_DynamicField decodeSignal(can_signal_t& signal, float value, - const std::vector<std::shared_ptr<can_signal_t> >& signals, bool* send); - - static float decode_obd2_response(const DiagnosticResponse* response, float parsed_payload); - -};
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/can/can-message-definition.cpp b/CAN-binder/low-can-binding/can/can-message-definition.cpp deleted file mode 100644 index 28d45fe..0000000 --- a/CAN-binder/low-can-binding/can/can-message-definition.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "can-message-definition.hpp" - -#include "../binding/application.hpp" - -can_message_definition_t::can_message_definition_t(const std::string bus) - : parent_{nullptr}, bus_{bus}, last_value_{CAN_MESSAGE_SIZE} -{} - -can_message_definition_t::can_message_definition_t( - const std::string bus, - uint32_t id, - frequency_clock_t frequency_clock, - bool force_send_changed) - : parent_{nullptr}, - bus_{bus}, - id_{id}, - frequency_clock_{frequency_clock}, - force_send_changed_{force_send_changed}, - last_value_{CAN_MESSAGE_SIZE} -{} - -can_message_definition_t::can_message_definition_t( - const std::string bus, - uint32_t id, - can_message_format_t format, - frequency_clock_t frequency_clock, - bool force_send_changed) - : parent_{nullptr}, - bus_{bus}, - id_{id}, - format_{format}, - frequency_clock_{frequency_clock}, - force_send_changed_{force_send_changed}, - last_value_{CAN_MESSAGE_SIZE} -{} - -can_message_definition_t::can_message_definition_t( - const std::string bus, - uint32_t id, - can_message_format_t format, - frequency_clock_t frequency_clock, - bool force_send_changed, - const std::vector<std::shared_ptr<can_signal_t> >& can_signals) - : parent_{nullptr}, - bus_{bus}, - id_{id}, - format_{format}, - frequency_clock_{frequency_clock}, - force_send_changed_{force_send_changed}, - last_value_{CAN_MESSAGE_SIZE}, - can_signals_{can_signals} -{} - -const std::string can_message_definition_t::get_bus_name() const -{ - return bus_; -} - -const std::string can_message_definition_t::get_bus_device_name() const -{ - return application_t::instance().get_can_bus_manager() - .get_can_device_name(bus_); -} - -uint32_t can_message_definition_t::get_id() const -{ - return id_; -} - -std::vector<std::shared_ptr<can_signal_t> >& can_message_definition_t::get_can_signals() -{ - return can_signals_; -} - -void can_message_definition_t::set_parent(can_message_set_t* parent) -{ - parent_= parent; -} - -void can_message_definition_t::set_last_value(const can_message_t& cm) -{ - last_value_= cm.get_data_vector(); -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/can/can-message-definition.hpp b/CAN-binder/low-can-binding/can/can-message-definition.hpp deleted file mode 100644 index 6d0f17d..0000000 --- a/CAN-binder/low-can-binding/can/can-message-definition.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @class can_message_definition_t - * - * @brief The definition of a CAN message. This includes a lot of metadata, so - * to save memory this struct should not be used for storing incoming and - * outgoing CAN messages. - */ - -#pragma once - -#include <vector> -#include <memory> - -#include "can-signals.hpp" -#include "can-message.hpp" -#include "can-message-set.hpp" -#include "../utils/timer.hpp" - -class can_message_set_t; - -/// @brief The definition of a CAN message. This includes a lot of metadata, so -/// to save memory this class gets the can_signal_t object related to a CAN message. -class can_message_definition_t -{ -private: - can_message_set_t* parent_; ///< parent_ - Pointer to the CAN message set holding this CAN message definition */ - std::string bus_; ///< bus_ - Address of CAN bus device. */ - uint32_t id_; ///< id_ - The ID of the message.*/ - can_message_format_t format_; ///< format_ - the format of the message's ID.*/ - frequency_clock_t frequency_clock_; ///< clock_ - an optional frequency clock to control the output of this - /// message, if sent raw, or simply to mark the max frequency for custom - /// handlers to retrieve.*/ - bool force_send_changed_; ///< force_send_changed_ - If true, regardless of the frequency, it will send CAN - /// message if it has changed when using raw passthrough.*/ - std::vector<uint8_t> last_value_; ///< last_value_ - The last received value of the message. Defaults to undefined. - /// This is required for the forceSendChanged functionality, as the stack - /// needs to compare an incoming CAN message with the previous frame.*/ - std::vector<std::shared_ptr<can_signal_t> > can_signals_; ///< can_signals_ - Vector holding can_signal_t object which share the same arbitration ID */ - -public: - //can_message_definition_t(const can_message_definition_t& b); - can_message_definition_t(const std::string bus); - can_message_definition_t(const std::string bus, uint32_t id, frequency_clock_t frequency_clock, bool force_send_changed); - can_message_definition_t(const std::string bus, uint32_t id, can_message_format_t format, frequency_clock_t frequency_clock, bool force_send_changed); - can_message_definition_t(const std::string bus, uint32_t id, can_message_format_t format, frequency_clock_t frequency_clock, bool force_send_changed, const std::vector<std::shared_ptr<can_signal_t> >& can_signals); - - const std::string get_bus_name() const; - const std::string get_bus_device_name() const; - uint32_t get_id() const; - std::vector<std::shared_ptr<can_signal_t> >& get_can_signals(); - - void set_parent(can_message_set_t* parent); - void set_last_value(const can_message_t& cm); -}; diff --git a/CAN-binder/low-can-binding/can/can-message-set.cpp b/CAN-binder/low-can-binding/can/can-message-set.cpp deleted file mode 100644 index c31dec6..0000000 --- a/CAN-binder/low-can-binding/can/can-message-set.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2015, 2016, 2017 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loïc Collignon" <loic.collignon@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "can-message-set.hpp" - -#include "../can/can-message-definition.hpp" - -can_message_set_t::can_message_set_t( - uint8_t index, - const std::string& name, - const std::vector<std::shared_ptr<can_message_definition_t> >& can_messages_definition, - const std::vector<std::shared_ptr<diagnostic_message_t> >& diagnostic_messages) - : index_{index} - , name_{name} - , can_messages_definition_{can_messages_definition} - , diagnostic_messages_{diagnostic_messages} -{} - -/// @brief Return vector holding all message definition handled by this message set. -std::vector<std::shared_ptr<can_message_definition_t> >& can_message_set_t::get_can_message_definition() -{ - return can_messages_definition_; -} - -std::vector<std::shared_ptr<can_signal_t> > can_message_set_t::get_all_can_signals() const -{ - std::vector<std::shared_ptr<can_signal_t> > can_signals; - for(const auto& cmd: can_messages_definition_) - { - std::vector<std::shared_ptr<can_signal_t> >& cmd_signals = cmd->get_can_signals(); - can_signals.insert( can_signals.end(), - cmd_signals.begin(), - cmd_signals.end() - ); - } - - return can_signals; -} - -/// @brief Return vector holding all diagnostic messages definitions handled by this message set. -std::vector<std::shared_ptr<diagnostic_message_t> >& can_message_set_t::get_diagnostic_messages() -{ - return diagnostic_messages_; -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/can/can-message-set.hpp b/CAN-binder/low-can-binding/can/can-message-set.hpp deleted file mode 100644 index 2a7cb53..0000000 --- a/CAN-binder/low-can-binding/can/can-message-set.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2015, 2016, 2017 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loïc Collignon" <loic.collignon@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <cstdint> -#include <string> -#include <vector> -#include <memory> - -class can_signal_t; -class can_message_definition_t; -class diagnostic_message_t; - -/// @brief A parent wrapper for a particular set of CAN messages and diagnostic messages -/// (e.g. a vehicle or program). -class can_message_set_t -{ -private: - uint8_t index_; /// < A numerical ID for the message set, ideally the index in an array for fast lookup - const std::string name_; /// < The name of the message set. - std::vector<std::shared_ptr<can_message_definition_t> > can_messages_definition_; ///< Vector holding all message definition handled by this message set. - std::vector<std::shared_ptr<diagnostic_message_t> > diagnostic_messages_; ///< Vector holding all diagnostics messages from JSON signals description file. First vector map to message set - -public: - can_message_set_t( - uint8_t index, - const std::string& name, - const std::vector<std::shared_ptr<can_message_definition_t> >& can_messages_definition, - const std::vector<std::shared_ptr<diagnostic_message_t> >& diagnostic_messages); - - std::vector<std::shared_ptr<can_message_definition_t> >& get_can_message_definition(); - std::vector<std::shared_ptr<can_signal_t> > get_all_can_signals() const; - std::vector<std::shared_ptr<diagnostic_message_t> >& get_diagnostic_messages(); -}; diff --git a/CAN-binder/low-can-binding/can/can-message.cpp b/CAN-binder/low-can-binding/can/can-message.cpp deleted file mode 100644 index 057bc71..0000000 --- a/CAN-binder/low-can-binding/can/can-message.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "can-message.hpp" - -#include <cstring> - -#include "../binding/low-can-hat.hpp" - -/// -/// @brief Class constructor -/// -/// Constructor about can_message_t class. -/// -can_message_t::can_message_t() - : maxdlen_{0}, - id_{0}, - length_{0}, - format_{can_message_format_t::INVALID}, - rtr_flag_{false}, - flags_{0}, - timestamp_{0}, - sub_id_{-1} -{} - -can_message_t::can_message_t(uint8_t maxdlen, - uint32_t id, - uint8_t length, - can_message_format_t format, - bool rtr_flag, - uint8_t flags, - std::vector<uint8_t>& data, - uint64_t timestamp) - : maxdlen_{maxdlen}, - id_{id}, - length_{length}, - format_{format}, - rtr_flag_{rtr_flag}, - flags_{flags}, - data_{data}, - timestamp_{timestamp}, - sub_id_{-1} -{} - -/// -/// @brief Retrieve id_ member value. -/// -/// @return id_ class member -/// -uint32_t can_message_t::get_id() const -{ - return id_; -} - -int can_message_t::get_sub_id() const -{ - return sub_id_; -} - -/// -/// @brief Retrieve RTR flag member. -/// -/// @return rtr_flags_ class member -/// -bool can_message_t::get_rtr_flag_() const -{ - return rtr_flag_; -} - -/// -/// @brief Retrieve format_ member value. -/// -/// @return format_ class member. Default to INVALID. -/// -can_message_format_t can_message_t::get_format() const -{ - if (format_ != can_message_format_t::STANDARD || format_ != can_message_format_t::EXTENDED) - return can_message_format_t::INVALID; - return format_; -} - -/// -/// @brief Retrieve flags_ member value. -/// -/// @return flags_ class member -/// -uint8_t can_message_t::get_flags() const -{ - return flags_; -} - -/// -/// @brief Retrieve data_ member value. -/// -/// @return pointer to the first element -/// of class member data_ -/// -const uint8_t* can_message_t::get_data() const -{ - return data_.data(); -} - -/// -/// @brief Retrieve data_ member whole vector -/// -/// @return the vector as is -/// -const std::vector<uint8_t> can_message_t::get_data_vector() const -{ - return data_; -} - -/// -/// @brief Retrieve length_ member value. -/// -/// @return length_ class member -/// -uint8_t can_message_t::get_length() const -{ - return length_; -} - -void can_message_t::set_sub_id(int sub_id) -{ - sub_id_ = sub_id; -} - -uint64_t can_message_t::get_timestamp() const -{ - return timestamp_; -} - -void can_message_t::set_timestamp(uint64_t timestamp) -{ - timestamp_ = timestamp; -} - -/// @brief Control whether the object is correctly initialized -/// to be sent over the CAN bus -/// -/// @return True if object correctly initialized and false if not. -bool can_message_t::is_correct_to_send() -{ - if (id_ != 0 && length_ != 0 && format_ != can_message_format_t::INVALID) - { - int i; - for(i=0;i<CAN_MESSAGE_SIZE;i++) - if(data_[i] != 0) - return true; - } - return false; -} - -/// @brief Set format_ member value. -/// -/// Preferred way to initialize these members by using -/// convert_from_canfd_frame method. -/// -/// @param[in] new_format - class member -void can_message_t::set_format(const can_message_format_t new_format) -{ - if(new_format == can_message_format_t::STANDARD || new_format == can_message_format_t::EXTENDED || new_format == can_message_format_t::INVALID) - format_ = new_format; - else - ERROR("Can set format, wrong format chosen"); -} - -/// @brief Take a canfd_frame struct to initialize class members -/// -/// This is the preferred way to initialize class members. -/// -/// @param[in] frame - canfd_frame to convert coming from a read of CAN socket -/// @param[in] nbytes - bytes read from socket read operation. -/// -/// @return A can_message_t object fully initialized with canfd_frame values. -can_message_t can_message_t::convert_from_frame(const struct canfd_frame& frame, size_t nbytes, uint64_t timestamp) -{ - uint8_t maxdlen, length, flags = (uint8_t)NULL; - uint32_t id; - can_message_format_t format; - bool rtr_flag; - std::vector<uint8_t> data; - - switch(nbytes) - { - case CANFD_MTU: - DEBUG("Got an CAN FD frame"); - maxdlen = CANFD_MAX_DLEN; - break; - case CAN_MTU: - DEBUG("Got a legacy CAN frame"); - maxdlen = CAN_MAX_DLEN; - break; - default: - ERROR("unsupported CAN frame"); - break; - } - - if (frame.can_id & CAN_ERR_FLAG) - { - format = can_message_format_t::INVALID; - id = frame.can_id & (CAN_ERR_MASK|CAN_ERR_FLAG); - } - else if (frame.can_id & CAN_EFF_FLAG) - { - format = can_message_format_t::EXTENDED; - id = frame.can_id & CAN_EFF_MASK; - } - else - { - format = can_message_format_t::STANDARD; - id = frame.can_id & CAN_SFF_MASK; - } - - /* Overwrite length_ if RTR flags is detected. - * standard CAN frames may have RTR enabled. There are no ERR frames with RTR */ - if (frame.can_id & CAN_RTR_FLAG) - { - rtr_flag = true; - if(frame.len && frame.len <= CAN_MAX_DLC) - { - if(rtr_flag) - length = frame.len& 0xF; - else - { - length = (frame.len > maxdlen) ? maxdlen : frame.len; - } - } - } - else - { - length = (frame.len > maxdlen) ? maxdlen : frame.len; - - /* Flags field only present for CAN FD frames*/ - if(maxdlen == CANFD_MAX_DLEN) - flags = frame.flags & 0xF; - - if (data.capacity() < maxdlen) - data.reserve(maxdlen); - int i; - - data.clear(); - /* maxdlen_ is now set at CAN_MAX_DLEN or CANFD_MAX_DLEN, respectively 8 and 64 bytes*/ - for(i=0;i<maxdlen;i++) - { - data.push_back(frame.data[i]); - }; - - DEBUG("Found id: %X, format: %X, length: %X, data %02X%02X%02X%02X%02X%02X%02X%02X", - id, (uint8_t)format, length, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); - } - - return can_message_t(maxdlen, id, length, format, rtr_flag, flags, data, timestamp); -} - -/// @brief Take a can_frame struct to initialize class members -/// -/// This is the preferred way to initialize class members. -/// -/// @param[in] frame - can_frame to convert coming from a read of CAN socket -/// @param[in] nbytes - bytes read from socket read operation. -/// -/// @return A can_message_t object fully initialized with can_frame values. -can_message_t can_message_t::convert_from_frame(const struct can_frame& frame, size_t nbytes, uint64_t timestamp) -{ - uint8_t maxdlen, length, flags = (uint8_t)NULL; - uint32_t id; - can_message_format_t format; - bool rtr_flag; - std::vector<uint8_t> data; - - if(nbytes <= CAN_MTU) - { - DEBUG("Got a legacy CAN frame"); - maxdlen = CAN_MAX_DLEN; - } - else - { - ERROR("unsupported CAN frame"); - } - - if (frame.can_id & CAN_ERR_FLAG) - { - format = can_message_format_t::INVALID; - id = frame.can_id & (CAN_ERR_MASK|CAN_ERR_FLAG); - } - else if (frame.can_id & CAN_EFF_FLAG) - { - format = can_message_format_t::EXTENDED; - id = frame.can_id & CAN_EFF_MASK; - } - else - { - format = can_message_format_t::STANDARD; - id = frame.can_id & CAN_SFF_MASK; - } - - /* Overwrite length_ if RTR flags is detected. - * standard CAN frames may have RTR enabled. There are no ERR frames with RTR */ - if (frame.can_id & CAN_RTR_FLAG) - { - rtr_flag = true; - if(frame.can_dlc && frame.can_dlc <= CAN_MAX_DLC) - { - if(rtr_flag) - length = frame.can_dlc& 0xF; - else - { - length = (frame.can_dlc > maxdlen) ? maxdlen : frame.can_dlc; - } - } - } - else - { - length = (frame.can_dlc > maxdlen) ? maxdlen : frame.can_dlc; - - if (data.capacity() < maxdlen) - data.reserve(maxdlen); - int i; - - data.clear(); - /* maxdlen_ is now set at CAN_MAX_DLEN or CANFD_MAX_DLEN, respectively 8 and 64 bytes*/ - for(i=0;i<maxdlen;i++) - { - data.push_back(frame.data[i]); - }; - -// DEBUG("Found id: %X, format: %X, length: %X, data %02X%02X%02X%02X%02X%02X%02X%02X", -// id, (uint8_t)format, length, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); - } - - return can_message_t(maxdlen, id, length, format, rtr_flag, flags, data, timestamp); -} - -/// @brief Take all initialized class's members and build an -/// canfd_frame struct that can be use to send a CAN message over -/// the bus. -/// -/// @return canfd_frame struct built from class members. -struct canfd_frame can_message_t::convert_to_canfd_frame() -{ - canfd_frame frame; - - if(is_correct_to_send()) - { - frame.can_id = get_id(); - frame.len = get_length(); - ::memcpy(frame.data, get_data(), length_); - } - else - ERROR("can_message_t not correctly initialized to be sent"); - - return frame; -} - -/// @brief Take all initialized class's members and build an -/// can_frame struct that can be use to send a CAN message over -/// the bus. -/// -/// @return can_frame struct built from class members. -struct can_frame can_message_t::convert_to_can_frame() -{ - can_frame frame; - - if(is_correct_to_send()) - { - frame.can_id = get_id(); - frame.can_dlc = get_length(); - ::memcpy(frame.data, get_data(), length_); - } - else - ERROR("can_message_t not correctly initialized to be sent"); - - return frame; -} diff --git a/CAN-binder/low-can-binding/can/can-message.hpp b/CAN-binder/low-can-binding/can/can-message.hpp deleted file mode 100644 index b206ebd..0000000 --- a/CAN-binder/low-can-binding/can/can-message.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <vector> -#include <string> -#include <cstdint> -#include <linux/can.h> - -#include "../utils/timer.hpp" - -#define CAN_MESSAGE_SIZE 8 - -/** - * @enum can_message_format_t - * @brief The ID format for a CAN message. - */ -enum class can_message_format_t { - STANDARD, ///< STANDARD - standard 11-bit CAN arbitration ID. */ - EXTENDED, ///< EXTENDED - an extended frame, with a 29-bit arbitration ID. */ - INVALID, ///< INVALID - INVALID code used at initialization to signify that it isn't usable'*/ -}; - -/// @class can_message_t -/// -/// @brief A compact representation of a single CAN message, meant to be used in in/out -/// buffers. It is a wrapper of a can_frame struct with some sugar around it for binding purposes. -class can_message_t { -private: - uint8_t maxdlen_; ///< maxdlen_ - Max data length deduce from number of bytes read from the socket.*/ - uint32_t id_; ///< id_ - The ID of the message. */ - uint8_t length_; ///< length_ - the length of the data array (max 8). */ - can_message_format_t format_; ///< format_ - the format of the message's ID.*/ - bool rtr_flag_; ///< rtr_flag_ - Telling if the frame has RTR flag positionned. Then frame hasn't data field*/ - uint8_t flags_; ///< flags_ - flags of a CAN FD frame. Needed if we catch FD frames.*/ - std::vector<uint8_t> data_; ///< data_ - The message's data field with a size of 8 which is the standard about CAN bus messages.*/ - uint64_t timestamp_; ///< timestamp_ - timestamp of the received message*/ - int sub_id_; ///< sub_id_ - Subscription index. */ - -public: - can_message_t(); - can_message_t(uint8_t maxdlen, uint32_t id, uint8_t length, can_message_format_t format, bool rtr_flag_, uint8_t flags, std::vector<uint8_t>& data, uint64_t timestamp); - - uint32_t get_id() const; - int get_sub_id() const; - bool get_rtr_flag_() const; - can_message_format_t get_format() const; - uint8_t get_flags() const; - const uint8_t* get_data() const; - const std::vector<uint8_t> get_data_vector() const; - uint8_t get_length() const; - uint64_t get_timestamp() const; - - void set_sub_id(int sub_id); - void set_timestamp(uint64_t timestamp); - void set_format(const can_message_format_t new_format); - - bool is_correct_to_send(); - - static can_message_t convert_from_frame(const canfd_frame& frame, size_t nbytes, uint64_t timestamp); - static can_message_t convert_from_frame(const can_frame& frame, size_t nbytes, uint64_t timestamp); - - struct canfd_frame convert_to_canfd_frame(); - struct can_frame convert_to_can_frame(); -}; diff --git a/CAN-binder/low-can-binding/can/can-signals.cpp b/CAN-binder/low-can-binding/can/can-signals.cpp deleted file mode 100644 index fe74115..0000000 --- a/CAN-binder/low-can-binding/can/can-signals.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <fnmatch.h> - -#include "can-signals.hpp" - -#include "../binding/application.hpp" -#include "../utils/signals.hpp" -#include "can-decoder.hpp" -#include "can-message.hpp" -#include "can-bus.hpp" -#include "../diagnostic/diagnostic-message.hpp" -#include "canutil/write.h" - -std::string can_signal_t::prefix_ = "messages"; - -can_signal_t::can_signal_t( - std::string generic_name, - uint8_t bit_position, - uint8_t bit_size, - float factor, - float offset, - float min_value, - float max_value, - frequency_clock_t frequency, - bool send_same, - bool force_send_changed, - std::map<uint8_t, std::string> states, - bool writable, - SignalDecoder decoder, - SignalEncoder encoder, - bool received) - : parent_{nullptr}, - generic_name_{ generic_name } - , bit_position_{ bit_position } - , bit_size_{ bit_size } - , factor_{ factor } - , offset_{ offset } - , min_value_{min_value} - , max_value_{max_value} - , frequency_{frequency} - , send_same_{send_same} - , force_send_changed_{force_send_changed} - , states_{states} - , writable_{writable} - , decoder_{decoder} - , encoder_{encoder} - , received_{received} - , last_value_{.0f} -{} - -can_message_definition_t* can_signal_t::get_message() const -{ - return parent_; -} - -const std::string can_signal_t::get_generic_name() const -{ - return generic_name_; -} - -const std::string can_signal_t::get_name() const -{ - return prefix_ + "." + generic_name_; -} - -const std::string can_signal_t::get_prefix() const -{ - return prefix_; -} - -uint8_t can_signal_t::get_bit_position() const -{ - return bit_position_; -} - -uint8_t can_signal_t::get_bit_size() const -{ - return bit_size_; -} - -float can_signal_t::get_factor() const -{ - return factor_; -} - -float can_signal_t::get_offset() const -{ - return offset_; -} - -float can_signal_t::get_min_value() const -{ - return min_value_; -} - -float can_signal_t::get_max_value() const -{ - return max_value_; -} - -frequency_clock_t& can_signal_t::get_frequency() -{ - return frequency_; -} - -bool can_signal_t::get_send_same() const -{ - return send_same_; -} - -bool can_signal_t::get_force_send_changed() const -{ - return force_send_changed_; -} - -const std::map<uint8_t, std::string>& can_signal_t::get_states() const -{ - return states_; -} - -const std::string can_signal_t::get_states(uint8_t value) -{ - if (value < states_.size()) - return states_[value]; - return std::string(); -} - -size_t can_signal_t::get_state_count() const -{ - return states_.size(); -} - -bool can_signal_t::get_writable() const -{ - return writable_; -} - -SignalDecoder& can_signal_t::get_decoder() -{ - return decoder_; -} - -SignalEncoder& can_signal_t::get_encoder() -{ - return encoder_; -} - -bool can_signal_t::get_received() const -{ - return received_; -} - -float can_signal_t::get_last_value() const -{ - return last_value_; -} - -std::pair<float, uint64_t> can_signal_t::get_last_value_with_timestamp() const -{ - return std::make_pair(last_value_, frequency_.get_last_tick()); -} - -void can_signal_t::set_parent(can_message_definition_t* parent) -{ - parent_ = parent; -} - -void can_signal_t::set_prefix(std::string val) -{ - prefix_ = val; -} - -void can_signal_t::set_received(bool r) -{ - received_ = r; -} - -void can_signal_t::set_last_value(float val) -{ - last_value_ = val; -} - -void can_signal_t::set_timestamp(uint64_t timestamp) -{ - frequency_.tick(timestamp); -} - diff --git a/CAN-binder/low-can-binding/can/can-signals.hpp b/CAN-binder/low-can-binding/can/can-signals.hpp deleted file mode 100644 index a56fc8c..0000000 --- a/CAN-binder/low-can-binding/can/can-signals.hpp +++ /dev/null @@ -1,151 +0,0 @@ -/// -/// Copyright (C) 2015, 2016 "IoT.bzh" -/// Author "Romain Forlot" <romain.forlot@iot.bzh> -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - -#pragma once - -#include <map> -#include <mutex> -#include <vector> -#include <string> -#include <memory> - -#include "openxc.pb.h" -#include "can-message-definition.hpp" -#include "../utils/timer.hpp" -#include "../utils/socketcan-bcm.hpp" -#include "can-message.hpp" -#include "../diagnostic/diagnostic-message.hpp" - -#define MESSAGE_SET_ID 0 - -class can_signal_t; -/// -/// @brief The type signature for a CAN signal decoder. -/// -/// A SignalDecoder transforms a raw floating point CAN signal into a number, -/// string or boolean. -/// -/// @param[in] signal - The CAN signal that we are decoding. -/// @param[in] signals - The list of all signals. -/// @param[in] signalCount - The length of the signals array. -/// @param[in] value - The CAN signal parsed from the message as a raw floating point -/// value. -/// @param[out] send - An output parameter. If the decoding failed or the CAN signal should -/// not send for some other reason, this should be flipped to false. -/// -/// @return a decoded value in an openxc_DynamicField struct. -/// -typedef openxc_DynamicField (*SignalDecoder)(can_signal_t& signal, - const std::vector<std::shared_ptr<can_signal_t> >& signals, float value, bool* send); - -/// -/// @brief: The type signature for a CAN signal encoder. -/// -/// A SignalEncoder transforms a number, string or boolean into a raw floating -/// point value that fits in the CAN signal. -/// -/// @param[in] signal - The CAN signal to encode. -/// @param[in] value - The dynamic field to encode. -/// @param[out] send - An output parameter. If the encoding failed or the CAN signal should -/// not be encoded for some other reason, this will be flipped to false. -/// -typedef uint64_t (*SignalEncoder)(can_signal_t* signal, - openxc_DynamicField* value, bool* send); - -class can_signal_t -{ -private: - can_message_definition_t* parent_; /*!< parent_ - pointer to the parent message definition holding this signal*/ - std::string generic_name_; /*!< generic_name_ - The name of the signal to be output.*/ - static std::string prefix_; /*!< prefix_ - generic_name_ will be prefixed with it. It has to reflect the used protocol. - * which make easier to sort message when the come in.*/ - uint8_t bit_position_; /*!< bitPosition_ - The starting bit of the signal in its CAN message (assuming - * non-inverted bit numbering, i.e. the most significant bit of - * each byte is 0) */ - uint8_t bit_size_; /*!< bit_size_ - The width of the bit field in the CAN message. */ - float factor_; /*!< factor_ - The final value will be multiplied by this factor. Use 1 if you - * don't need a factor. */ - float offset_; /*!< offset_ - The final value will be added to this offset. Use 0 if you - * don't need an offset. */ - float min_value_; /*!< min_value_ - The minimum value for the processed signal.*/ - float max_value_; /*!< max_value_ - The maximum value for the processed signal. */ - frequency_clock_t frequency_; /*!< frequency_ - A frequency_clock_t struct to control the maximum frequency to - * process and send this signal. To process every value, set the - * clock's frequency to 0. */ - bool send_same_; /*!< send_same_ - If true, will re-send even if the value hasn't changed.*/ - bool force_send_changed_; /*!< force_send_changed_ - If true, regardless of the frequency, it will send the - * value if it has changed. */ - std::map<uint8_t, std::string> states_; /*!< states_ - A map of CAN signal state describing the mapping - * between numerical and string values for valid states. */ - bool writable_; /*!< writable - True if the signal is allowed to be written from the USB host - * back to CAN. Defaults to false.*/ - SignalDecoder decoder_; /*!< decoder_ - An optional function to decode a signal from the bus to a human - * readable value. If NULL, the default numerical decoder is used. */ - SignalEncoder encoder_; /*!< encoder_ - An optional function to encode a signal value to be written to - * CAN into a byte array. If NULL, the default numerical encoder - * is used. */ - bool received_; /*!< received_ - True if this signal has ever been received.*/ - float last_value_; /*!< lastValue_ - The last received value of the signal. If 'received' is false, - * this value is undefined. */ - -public: - can_signal_t( - std::string generic_name, - uint8_t bit_position, - uint8_t bit_size, - float factor, - float offset, - float min_value, - float max_value, - frequency_clock_t frequency, - bool send_same, - bool force_send_changed, - std::map<uint8_t, std::string> states, - bool writable, - SignalDecoder decoder, - SignalEncoder encoder, - bool received); - - can_message_definition_t* get_message() const; - const std::string get_generic_name() const; - const std::string get_name() const; - const std::string get_prefix() const; - uint8_t get_bit_position() const; - uint8_t get_bit_size() const; - float get_factor() const; - float get_offset() const; - float get_min_value() const; - float get_max_value() const; - frequency_clock_t& get_frequency(); - bool get_send_same() const; - bool get_force_send_changed() const; - const std::map<uint8_t, std::string>& get_states() const; - const std::string get_states(uint8_t value); - size_t get_state_count() const; - bool get_writable() const; - SignalDecoder& get_decoder(); - SignalEncoder& get_encoder(); - bool get_received() const; - float get_last_value() const; - std::pair<float, uint64_t> get_last_value_with_timestamp() const; - - void set_parent(can_message_definition_t* parent); - void set_prefix(std::string val); - void set_received(bool r); - void set_last_value(float val); - void set_timestamp(uint64_t timestamp); -}; diff --git a/CAN-binder/low-can-binding/diagnostic/active-diagnostic-request.cpp b/CAN-binder/low-can-binding/diagnostic/active-diagnostic-request.cpp deleted file mode 100644 index f503e0a..0000000 --- a/CAN-binder/low-can-binding/diagnostic/active-diagnostic-request.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <map> -#include <fnmatch.h> - -#include "active-diagnostic-request.hpp" - -#include "../binding/application.hpp" - -#define ERROR_PID 0xFF - -std::string active_diagnostic_request_t::prefix_ = "diagnostic_messages"; - -bool active_diagnostic_request_t::operator==(const active_diagnostic_request_t& b) -{ - return (bus_ == b.bus_ && id_ == b.id_ && handle_ == b.handle_); -} - -active_diagnostic_request_t& active_diagnostic_request_t::operator=(const active_diagnostic_request_t& adr) -{ - if (this != &adr) - { - bus_ = adr.bus_; - id_ = adr.id_; - handle_ = adr.handle_; - name_ = adr.name_; - decoder_ = adr.decoder_; - callback_ = adr.callback_; - recurring_ = adr.recurring_; - wait_for_multiple_responses_ = adr.wait_for_multiple_responses_; - frequency_clock_ = adr.frequency_clock_; - timeout_clock_ = adr.timeout_clock_; - socket_ = adr.socket_; - } - - return *this; -} - -active_diagnostic_request_t::active_diagnostic_request_t() - : bus_{nullptr}, - id_{0}, - handle_{nullptr}, - name_{""}, - decoder_{nullptr}, - callback_{nullptr}, - recurring_{false}, - wait_for_multiple_responses_{false}, - frequency_clock_{frequency_clock_t()}, - timeout_clock_{frequency_clock_t()}, - socket_{} -{} - -active_diagnostic_request_t::active_diagnostic_request_t(const std::string& bus, uint32_t id, - const std::string& name, - bool wait_for_multiple_responses, - const DiagnosticResponseDecoder decoder, - const DiagnosticResponseCallback callback, - float frequencyHz) - : bus_{bus}, - id_{id}, - handle_{nullptr}, - name_{name}, - decoder_{decoder}, - callback_{callback}, - recurring_{frequencyHz ? true : false}, - wait_for_multiple_responses_{wait_for_multiple_responses}, - frequency_clock_{frequency_clock_t(frequencyHz)}, - timeout_clock_{frequency_clock_t(10)}, - socket_{} -{} - -active_diagnostic_request_t::~active_diagnostic_request_t() -{ - socket_.close(); - delete handle_; - handle_ = nullptr; -} - -uint32_t active_diagnostic_request_t::get_id() const -{ - return id_; -} - -uint16_t active_diagnostic_request_t::get_pid() const -{ - if (handle_->request.has_pid) - return handle_->request.pid; - return ERROR_PID; -} - -DiagnosticRequestHandle* active_diagnostic_request_t::get_handle() -{ - return handle_; -} - -const std::string active_diagnostic_request_t::get_name() const -{ - return name_; -} - -std::string& active_diagnostic_request_t::get_prefix() -{ - return active_diagnostic_request_t::prefix_; -} - -DiagnosticResponseDecoder& active_diagnostic_request_t::get_decoder() -{ - return decoder_; -} - -DiagnosticResponseCallback& active_diagnostic_request_t::get_callback() -{ - return callback_; -} - -bool active_diagnostic_request_t::get_recurring() const -{ - return recurring_; -} - -frequency_clock_t& active_diagnostic_request_t::get_frequency_clock() -{ - return frequency_clock_; -} - -frequency_clock_t& active_diagnostic_request_t::get_timeout_clock() -{ - return timeout_clock_; -} - -utils::socketcan_bcm_t& active_diagnostic_request_t::get_socket() -{ - return socket_; -} - -void active_diagnostic_request_t::set_handle(DiagnosticShims& shims, DiagnosticRequest* request) -{ - handle_ = new DiagnosticRequestHandle(generate_diagnostic_request(&shims, request, nullptr)); -} - -/// -/// @brief Check if requested signal name is a diagnostic message. If the name -/// begin with the diagnostic message prefix then true else false. -/// -/// @param[in] name - A signal name. -/// -/// @return true if name began with the diagnostic message prefix else false. -/// -bool active_diagnostic_request_t::is_diagnostic_signal(const std::string& name) -{ - const std::string p = active_diagnostic_request_t::prefix_ + "*"; - if(::fnmatch(p.c_str(), name.c_str(), FNM_CASEFOLD) == 0) - return true; - return false; -} - -/// @brief Returns true if a sufficient response has been received for a -/// diagnostic request. -/// -/// This is true when at least one response has been received and the request is -/// configured to not wait for multiple responses. Functional broadcast requests -/// may often wish to wait the full 100ms for modules to respond. -bool active_diagnostic_request_t::response_received() const -{ - return !wait_for_multiple_responses_ && - handle_->completed && handle_->success; -} diff --git a/CAN-binder/low-can-binding/diagnostic/active-diagnostic-request.hpp b/CAN-binder/low-can-binding/diagnostic/active-diagnostic-request.hpp deleted file mode 100644 index d263a2d..0000000 --- a/CAN-binder/low-can-binding/diagnostic/active-diagnostic-request.hpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <string> -#include <vector> - -#include "../utils/socketcan-bcm.hpp" -#include "uds/uds.h" -#include "uds/uds_types.h" -#include "../utils/timer.hpp" - -class active_diagnostic_request_t; -class diagnostic_manager_t; - -/// @brief The signature for an optional function that can apply the neccessary -/// formula to translate the binary payload into meaningful data. -/// -/// @param[in] response - the received DiagnosticResponse (the data is in response.payload, -/// a byte array). This is most often used when the byte order is signiticant, i.e. with many OBD-II PID formulas. -/// @param[in] parsed_payload - the entire payload of the response parsed as an int. -/// -/// @return float value after decoding. -/// -typedef float (*DiagnosticResponseDecoder)(const DiagnosticResponse* response, - float parsed_payload); - -/// @brief: The signature for an optional function to handle a new diagnostic -/// response. -/// -/// @param[in] request - The original diagnostic request. -/// @param[in] response - The response object that was just received. -/// @param[in] parsed_payload - The payload of the response, parsed as a float. -/// -typedef void (*DiagnosticResponseCallback)(const active_diagnostic_request_t* request, - const DiagnosticResponse* response, float parsed_payload); - -/// -/// @brief An active diagnostic request, either recurring or one-time. -/// -/// Will host a diagnostic_message_t class members to describe an on going -/// diagnostic request on the CAN bus. Diagnostic message will be converted to -/// a DiagnosticRequest using ad-hoc method build_diagnostic_request from diagnostic message. -/// Then missing member, that can not be hosted into a DiagnosticRequest struct, will be passed -/// as argument when adding the request to (non)-recurrent vector. Argument will be used to instanciate -/// an active_diagnostic_request_t object before sending it. -/// -class active_diagnostic_request_t { -private: - std::string bus_; ///< bus_ - The CAN bus this request should be made on, or is currently in flight-on - uint32_t id_; ///< id_ - The arbitration ID (aka message ID) for the request. - DiagnosticRequestHandle* handle_; ///< handle_ - A handle for the request to keep track of it between - ///< sending the frames of the request and receiving all frames of the response. - std::string name_; ///< name_ - Human readable name, to be used when publishing received responses. - ///< TODO: If the name is NULL, the published output will use the raw OBD-II response format. - static std::string prefix_; ///< prefix_ - It has to reflect the JSON object which it comes from. It makes easier sorting - ///< incoming CAN messages. - DiagnosticResponseDecoder decoder_; ///< decoder_ - An optional DiagnosticResponseDecoder to parse the payload of responses - ///< to this request. If the decoder is NULL, the output will include the raw payload - ///< instead of a parsed value. - DiagnosticResponseCallback callback_; ///< callback_ - An optional DiagnosticResponseCallback to be notified whenever a - ///< response is received for this request. - bool recurring_; ///< bool recurring_ - If true, this is a recurring request and it will remain as active until explicitly cancelled. - ///< The frequencyClock attribute controls how often a recurrin request is made. - bool wait_for_multiple_responses_; ///< wait_for_multiple_responses_ - False by default, when any response is received for a request - ///< it will be removed from the active list. If true, the request will remain active until the timeout - ///< clock expires, to allow it to receive multiple response (e.g. to a functional broadcast request). - frequency_clock_t frequency_clock_; ///< frequency_clock_ - A frequency_clock_t object to control the send rate for a - ///< recurring request. If the request is not reecurring, this attribute is not used. - frequency_clock_t timeout_clock_; ///< timeout_clock_ - A frequency_clock_t object to monitor how long it's been since - ///< this request was sent. - utils::socketcan_bcm_t socket_; ///< socket_ - A BCM socket setup to send cyclic message to CAN ID 7DF. -public: - bool operator==(const active_diagnostic_request_t& b); - active_diagnostic_request_t& operator=(const active_diagnostic_request_t& adr); - - active_diagnostic_request_t(); - active_diagnostic_request_t(active_diagnostic_request_t&&) = default; - active_diagnostic_request_t(const std::string& bus, uint32_t id, - const std::string& name, bool wait_for_multiple_responses, - const DiagnosticResponseDecoder decoder, - const DiagnosticResponseCallback callback, float frequencyHz); - ~active_diagnostic_request_t(); - - uint32_t get_id() const; - DiagnosticRequestHandle* get_handle(); - uint16_t get_pid() const; - const std::string get_name() const; - static std::string& get_prefix(); - DiagnosticResponseDecoder& get_decoder(); - DiagnosticResponseCallback& get_callback(); - bool get_recurring() const; - frequency_clock_t& get_frequency_clock(); - frequency_clock_t& get_timeout_clock(); - utils::socketcan_bcm_t& get_socket(); - - void set_handle(DiagnosticShims& shims, DiagnosticRequest* request); - - static bool is_diagnostic_signal(const std::string& name); - - bool response_received() const; -}; diff --git a/CAN-binder/low-can-binding/diagnostic/diagnostic-manager.cpp b/CAN-binder/low-can-binding/diagnostic/diagnostic-manager.cpp deleted file mode 100644 index 61aa699..0000000 --- a/CAN-binder/low-can-binding/diagnostic/diagnostic-manager.cpp +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <systemd/sd-event.h> -#include <algorithm> -#include <string.h> - -#include "diagnostic-manager.hpp" - -#include "../utils/openxc-utils.hpp" -#include "../utils/signals.hpp" -#include "../binding/application.hpp" - -#define MAX_RECURRING_DIAGNOSTIC_FREQUENCY_HZ 10 -#define MAX_SIMULTANEOUS_DIAG_REQUESTS 50 -// There are only 8 slots of in flight diagnostic requests -#define MAX_SIMULTANEOUS_IN_FLIGHT_REQUESTS 8 -#define TIMERFD_ACCURACY 0 -#define MICRO 1000000 - -diagnostic_manager_t::diagnostic_manager_t() - : initialized_{false} -{} - -/// @brief Diagnostic manager isn't initialized at launch but after -/// CAN bus devices initialization. For the moment, it is only possible -/// to have 1 diagnostic bus which are the first bus declared in the JSON -/// description file. Configuration instance will return it. -/// -/// this will initialize DiagnosticShims and cancel all active requests -/// if there are any. -bool diagnostic_manager_t::initialize() -{ - // Mandatory to set the bus before intialize shims. - bus_ = application_t::instance().get_diagnostic_bus(); - - init_diagnostic_shims(); - reset(); - - initialized_ = true; - DEBUG("Diagnostic Manager initialized"); - return initialized_; -} - -/// @brief initialize shims used by UDS lib and set initialized_ to true. -/// It is needed before used the diagnostic manager fully because shims are -/// required by most member functions. -void diagnostic_manager_t::init_diagnostic_shims() -{ - shims_ = diagnostic_init_shims(shims_logger, shims_send, NULL); - DEBUG("Shims initialized"); -} - -/// @brief Force cleanup all active requests. -void diagnostic_manager_t::reset() -{ - DEBUG("Clearing existing diagnostic requests"); - cleanup_active_requests(true); -} - -/// @brief send function use by diagnostic library. It will open a BCM CAN socket TX_SETUP type. -/// That socket will send cyclic messages configured from a diagnostic request. -/// -/// @param[in] arbitration_id - CAN arbitration ID to use when send message. OBD2 broadcast ID -/// is 0x7DF by example. -/// @param[in] data - The data payload for the message. NULL is valid if size is also 0. -/// @param[in] size - The size of the data payload, in bytes. -/// -/// @return true if the CAN message was sent successfully. -bool diagnostic_manager_t::shims_send(const uint32_t arbitration_id, const uint8_t* data, const uint8_t size) -{ - diagnostic_manager_t& dm = application_t::instance().get_diagnostic_manager(); - active_diagnostic_request_t* current_adr = dm.get_last_recurring_requests(); - utils::socketcan_bcm_t& tx_socket = current_adr->get_socket(); - - // Make sure that socket has been opened. - if(! tx_socket) - tx_socket.open( - dm.get_bus_device_name()); - - struct utils::simple_bcm_msg bcm_msg; - struct can_frame cfd; - - memset(&cfd, 0, sizeof(cfd)); - memset(&bcm_msg.msg_head, 0, sizeof(bcm_msg.msg_head)); - - struct timeval freq = current_adr->get_frequency_clock().get_timeval_from_period(); - - bcm_msg.msg_head.opcode = TX_SETUP; - bcm_msg.msg_head.can_id = arbitration_id; - bcm_msg.msg_head.flags = SETTIMER|STARTTIMER|TX_CP_CAN_ID; - bcm_msg.msg_head.ival2.tv_sec = freq.tv_sec; - bcm_msg.msg_head.ival2.tv_usec = freq.tv_usec; - bcm_msg.msg_head.nframes = 1; - cfd.can_dlc = size; - ::memcpy(cfd.data, data, size); - - bcm_msg.frames = cfd; - - tx_socket << bcm_msg; - if(tx_socket) - return true; - return false; -} - -/// @brief The type signature for an optional logging function, if the user -/// wishes to provide one. It should print, store or otherwise display the -/// message. -/// -/// message - A format string to log using the given parameters. -/// ... (vargs) - the parameters for the format string. -/// -void diagnostic_manager_t::shims_logger(const char* format, ...) -{ - va_list args; - va_start(args, format); - - char buffer[256]; - vsnprintf(buffer, 256, format, args); - - DEBUG("%s", buffer); - va_end(args); -} - -/// @brief The type signature for a... OpenXC TODO: not used yet. -void diagnostic_manager_t::shims_timer() -{} - -const std::string diagnostic_manager_t::get_bus_name() const -{ - return bus_; -} - -const std::string diagnostic_manager_t::get_bus_device_name() const -{ - return application_t::instance().get_can_bus_manager() - .get_can_device_name(bus_); -} - -active_diagnostic_request_t* diagnostic_manager_t::get_last_recurring_requests() const -{ - return recurring_requests_.back(); -} - -/// @brief Return diagnostic manager shims member. -DiagnosticShims& diagnostic_manager_t::get_shims() -{ - return shims_; -} - -/// @brief Search for a specific active diagnostic request in the provided requests list -/// and erase it from the vector. This is useful at unsubscription to clean up the list otherwize -/// all received CAN messages will be passed to DiagnosticRequestHandle of all active diagnostic request -/// contained in the vector but no event if connected to, so we will decode uneeded request. -/// -/// @param[in] entry - a pointer of an active_diagnostic_request instance to clean up -/// @param[in] requests_list - a vector where to make the search and cleaning. -void diagnostic_manager_t::find_and_erase(active_diagnostic_request_t* entry, std::vector<active_diagnostic_request_t*>& requests_list) -{ - auto i = std::find(requests_list.begin(), requests_list.end(), entry); - if ( i != requests_list.end()) - requests_list.erase(i); -} - -/// @brief Free memory allocated on active_diagnostic_request_t object and close the socket. -void diagnostic_manager_t::cancel_request(active_diagnostic_request_t* entry) -{ - entry->get_socket().close(); - delete entry; - entry = nullptr; -} - -/// @brief Cleanup a specific request if it isn't running and get complete. As it is almost -/// impossible to get that state for a recurring request without waiting for that, you can -/// force the cleaning operation. -/// -/// @param[in] entry - the request to clean -/// @param[in] force - Force the cleaning or not ? -void diagnostic_manager_t::cleanup_request(active_diagnostic_request_t* entry, bool force) -{ - if(entry != nullptr && (force || entry->response_received())) - { - char request_string[128] = {0}; - diagnostic_request_to_string(&entry->get_handle()->request, - request_string, sizeof(request_string)); - if(force && entry->get_recurring()) - { - cancel_request(entry); - find_and_erase(entry, recurring_requests_); - DEBUG("Cancelling completed, recurring request: %s", request_string); - } - else if (!entry->get_recurring()) - { - DEBUG("Cancelling completed, non-recurring request: %s", request_string); - cancel_request(entry); - find_and_erase(entry, non_recurring_requests_); - } - } -} - -/// @brief Clean up all requests lists, recurring and not recurring. -/// -/// @param[in] force - Force the cleaning or not ? If true, that will do -/// the same effect as a call to reset(). -void diagnostic_manager_t::cleanup_active_requests(bool force) -{ - for(auto& entry : non_recurring_requests_) - { - if (entry != nullptr) - cleanup_request(entry, force); - } - - for(auto& entry : recurring_requests_) - { - if (entry != nullptr) - cleanup_request(entry, force); - } -} - -/// @brief Will return the active_diagnostic_request_t pointer for theDiagnosticRequest or nullptr if -/// not found. -/// -/// @param[in] request - Search key, method will go through recurring list to see if it find that request -/// holded by the DiagnosticHandle member. -active_diagnostic_request_t* diagnostic_manager_t::find_recurring_request(DiagnosticRequest& request) -{ - for (auto& entry : recurring_requests_) - { - if(entry != nullptr) - { - if(diagnostic_request_equals(&entry->get_handle()->request, &request)) - {return entry;} - } - } - return nullptr; -} - -/// @brief Add and send a new one-time diagnostic request. DON'T USED AT THIS TIME -/// -/// A one-time (aka non-recurring) request can existing in parallel with a -/// recurring request for the same PID or mode, that's not a problem. -/// -/// For an example, see the docs for addRecurringRequest. This function is very -/// similar but leaves out the frequencyHz parameter. -/// -/// @param[in] request - The parameters for the request. -/// @param[in] name - Human readable name this response, to be used when -/// publishing received responses. TODO: If the name is NULL, the published output -/// will use the raw OBD-II response format. -/// @param[in] wait_for_multiple_responses - If false, When any response is received -/// for this request it will be removed from the active list. If true, the -/// request will remain active until the timeout clock expires, to allow it -/// to receive multiple response. Functional broadcast requests will always -/// waint for the timeout, regardless of this parameter. -/// @param[in] decoder - An optional DiagnosticResponseDecoder to parse the payload of -/// responses to this request. If the decoder is NULL, the output will -/// include the raw payload instead of a parsed value. -/// @param[in] callback - An optional DiagnosticResponseCallback to be notified whenever a -/// response is received for this request. -/// -/// @return true if the request was added successfully. Returns false if there -/// wasn't a free active request entry, if the frequency was too high or if the -/// CAN acceptance filters could not be configured, -active_diagnostic_request_t* diagnostic_manager_t::add_request(DiagnosticRequest* request, const std::string& name, - bool wait_for_multiple_responses, const DiagnosticResponseDecoder decoder, - const DiagnosticResponseCallback callback) -{ - cleanup_active_requests(false); - - active_diagnostic_request_t* entry = nullptr; - - if (non_recurring_requests_.size() <= MAX_SIMULTANEOUS_DIAG_REQUESTS) - { - // TODO: implement Acceptance Filter - // if(updateRequiredAcceptanceFilters(bus, request)) { - active_diagnostic_request_t* entry = new active_diagnostic_request_t(bus_, request->arbitration_id, name, - wait_for_multiple_responses, decoder, callback, 0); - entry->set_handle(shims_, request); - - char request_string[128] = {0}; - diagnostic_request_to_string(&entry->get_handle()->request, request_string, - sizeof(request_string)); - - // Erase any existing request not already cleaned. - cleanup_request(entry, true); - DEBUG("Added one-time diagnostic request on bus %s: %s", - bus_.c_str(), request_string); - - non_recurring_requests_.push_back(entry); - } - else - { - WARNING("There isn't enough request entry. Vector exhausted %d/%d", (int)non_recurring_requests_.size(), MAX_SIMULTANEOUS_DIAG_REQUESTS); - non_recurring_requests_.resize(MAX_SIMULTANEOUS_DIAG_REQUESTS); - } - return entry; -} - -/// @brief Validate frequency asked don't get higher than the maximum of a classical -/// CAN bus OBD2 request. -/// -/// @param[in] frequencyHz - frequency asked for sending diagnostic requests. -/// -/// @return True if frequency is below the Maximum false if not. -bool diagnostic_manager_t::validate_optional_request_attributes(float frequencyHz) -{ - if(frequencyHz > MAX_RECURRING_DIAGNOSTIC_FREQUENCY_HZ) { - DEBUG("Requested recurring diagnostic frequency %lf is higher than maximum of %d", - frequencyHz, MAX_RECURRING_DIAGNOSTIC_FREQUENCY_HZ); - return false; - } - return true; -} - -/// @brief Add and send a new recurring diagnostic request. -/// -/// At most one recurring request can be active for the same arbitration ID, mode -/// and (if set) PID on the same bus at one time. If you try and call -/// add_recurring_request with the same key, it will return an error. -/// -/// @param[in] request - The parameters for the request. -/// @param[in] name - An optional human readable name this response, to be used when -/// publishing received responses. If the name is NULL, the published output -/// will use the raw OBD-II response format. -/// @param[in] wait_for_multiple_responses - If false, When any response is received -/// for this request it will be removed from the active list. If true, the -/// request will remain active until the timeout clock expires, to allow it -/// to receive multiple response. Functional broadcast requests will always -/// waint for the timeout, regardless of this parameter. -/// @param[in] decoder - An optional DiagnosticResponseDecoder to parse the payload of -/// responses to this request. If the decoder is NULL, the output will -/// include the raw payload instead of a parsed value. -/// @param[in] callback - An optional DiagnosticResponseCallback to be notified whenever a -/// response is received for this request. -/// @param[in] frequencyHz - The frequency (in Hz) to send the request. A frequency above -/// MAX_RECURRING_DIAGNOSTIC_FREQUENCY_HZ is not allowed, and will make this -/// function return false. -/// -/// @return true if the request was added successfully. Returns false if there -/// was too much already running requests, if the frequency was too high TODO:or if the -/// CAN acceptance filters could not be configured, -active_diagnostic_request_t* diagnostic_manager_t::add_recurring_request(DiagnosticRequest* request, const char* name, - bool wait_for_multiple_responses, const DiagnosticResponseDecoder decoder, - const DiagnosticResponseCallback callback, float frequencyHz) -{ - active_diagnostic_request_t* entry = nullptr; - - if(!validate_optional_request_attributes(frequencyHz)) - return entry; - - cleanup_active_requests(false); - - if(find_recurring_request(*request) == nullptr) - { - if(recurring_requests_.size() <= MAX_SIMULTANEOUS_DIAG_REQUESTS) - { - entry = new active_diagnostic_request_t(bus_, request->arbitration_id, name, - wait_for_multiple_responses, decoder, callback, frequencyHz); - recurring_requests_.push_back(entry); - - entry->set_handle(shims_, request); - start_diagnostic_request(&shims_, entry->get_handle()); - } - else - { - WARNING("There isn't enough request entry. Vector exhausted %d/%d", (int)recurring_requests_.size(), MAX_SIMULTANEOUS_DIAG_REQUESTS); - recurring_requests_.resize(MAX_SIMULTANEOUS_DIAG_REQUESTS); - } - } - else - { DEBUG("Can't add request, one already exists with same key");} - return entry; -} - -/// @brief Will decode the diagnostic response and build the final openxc_VehicleMessage to return. -/// -/// @param[in] adr - A pointer to an active diagnostic request holding a valid diagnostic handle -/// @param[in] response - The response to decode from which the Vehicle message will be built and returned -/// -/// @return A filled openxc_VehicleMessage or a zeroed struct if there is an error. -openxc_VehicleMessage diagnostic_manager_t::relay_diagnostic_response(active_diagnostic_request_t* adr, const DiagnosticResponse& response) -{ - openxc_VehicleMessage message = build_VehicleMessage(); - float value = (float)diagnostic_payload_to_integer(&response); - if(adr->get_decoder() != nullptr) - { - value = adr->get_decoder()(&response, value); - } - - if((response.success && adr->get_name().size()) > 0) - { - // If name, include 'value' instead of payload, and leave of response - // details. - message = build_VehicleMessage(build_SimpleMessage(adr->get_name(), build_DynamicField(value))); - message.has_diagnostic_response = true; - message.diagnostic_response = build_VehicleMessage(adr, response, value).diagnostic_response; - } - else - { - // If no name, only send full details of response but still include 'value' - // instead of 'payload' if they provided a decoder. The one case you - // can't get is the full detailed response with 'value'. We could add - // another parameter for that but it's onerous to carry that around. - message = build_VehicleMessage(adr, response, value); - } - - // If not success but completed then the pid isn't supported - if(!response.success) - { - struct utils::signals_found found_signals; - found_signals = utils::signals_manager_t::instance().find_signals(build_DynamicField(adr->get_name())); - found_signals.diagnostic_messages.front()->set_supported(false); - cleanup_request(adr, true); - NOTICE("PID not supported or ill formed. Please unsubscribe from it. Error code : %d", response.negative_response_code); - message = build_VehicleMessage(build_SimpleMessage(adr->get_name(), build_DynamicField("This PID isn't supported by your vehicle."))); - } - - if(adr->get_callback() != nullptr) - { - adr->get_callback()(adr, &response, value); - } - - // Reset the completed flag handle to make sure that it will be reprocessed the next time. - adr->get_handle()->success = false; - return message; -} - -/// @brief Will take the CAN message and pass it to the receive functions that will process -/// diagnostic handle for each active diagnostic request then depending on the result we will -/// return pass the diagnostic response to decode it. -/// -/// @param[in] entry - A pointer to an active diagnostic request holding a valid diagnostic handle -/// @param[in] cm - A raw CAN message. -/// -/// @return A pointer to a filled openxc_VehicleMessage or a nullptr if nothing has been found. -openxc_VehicleMessage diagnostic_manager_t::relay_diagnostic_handle(active_diagnostic_request_t* entry, const can_message_t& cm) -{ - DiagnosticResponse response = diagnostic_receive_can_frame(&shims_, entry->get_handle(), cm.get_id(), cm.get_data(), cm.get_length()); - if(response.completed && entry->get_handle()->completed) - { - if(entry->get_handle()->success) - return relay_diagnostic_response(entry, response); - } - else if(!response.completed && response.multi_frame) - { - // Reset the timeout clock while completing the multi-frame receive - entry->get_timeout_clock().tick( - entry->get_timeout_clock().get_time_function()()); - } - - return build_VehicleMessage(); -} - -/// @brief Find the active diagnostic request with the correct DiagnosticRequestHandle -/// member that will understand the CAN message using diagnostic_receive_can_frame function -/// from UDS-C library. Then decode it with an ad-hoc method. -/// -/// @param[in] cm - Raw CAN message received -/// -/// @return VehicleMessage with decoded value. -openxc_VehicleMessage diagnostic_manager_t::find_and_decode_adr(const can_message_t& cm) -{ - openxc_VehicleMessage vehicle_message = build_VehicleMessage(); - - for ( auto entry : non_recurring_requests_) - { - vehicle_message = relay_diagnostic_handle(entry, cm); - if (is_valid(vehicle_message)) - return vehicle_message; - } - - for ( auto entry : recurring_requests_) - { - vehicle_message = relay_diagnostic_handle(entry, cm); - if (is_valid(vehicle_message)) - return vehicle_message; - } - - return vehicle_message; -} - -/// @brief Tell if the CAN message received is a diagnostic response. -/// Request broadcast ID use 0x7DF and assigned ID goes from 0x7E0 to Ox7E7. That allows up to 8 ECU to respond -/// at the same time. The response is the assigned ID + 0x8, so response ID can goes from 0x7E8 to 0x7EF. -/// -/// @param[in] cm - CAN message received from the socket. -/// -/// @return True if the active diagnostic request match the response. -bool diagnostic_manager_t::is_diagnostic_response(const can_message_t& cm) -{ - if (cm.get_id() >= 0x7e8 && cm.get_id() <= 0x7ef) - return true; - return false; -} diff --git a/CAN-binder/low-can-binding/diagnostic/diagnostic-manager.hpp b/CAN-binder/low-can-binding/diagnostic/diagnostic-manager.hpp deleted file mode 100644 index 05a67c8..0000000 --- a/CAN-binder/low-can-binding/diagnostic/diagnostic-manager.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <systemd/sd-event.h> -#include <map> -#include <vector> - -#include "../utils/socketcan-bcm.hpp" -#include "uds/uds.h" -#include "openxc.pb.h" -#include "../can/can-bus.hpp" -#include "active-diagnostic-request.hpp" - -/// Each CAN bus needs its own set of shim functions, so this should -/// match the maximum CAN controller count. -/// -#define MAX_SHIM_COUNT can_bus_t.get_can_devices().size() -#define DIAGNOSTIC_RESPONSE_ARBITRATION_ID_OFFSET 0x8 - -class active_diagnostic_request_t; - -/// -/// @brief The core structure for running the diagnostics module by the binding. -/// -/// This stores details about the active requests and shims required to connect -/// the diagnostics library to the CAN device. -/// -class diagnostic_manager_t { -private: - DiagnosticShims shims_; /*!< shims_ - Shim functions for each CAN bus that plug the diagnostics - * library (uds-c) into the VI's CAN peripheral.*/ - std::string bus_; /*!< bus_ - A pointer to the CAN bus that should be used for all standard OBD-II requests, if the bus is not - * explicitly spcified in the request. Default to the first bus CAN at initialization.*/ - std::vector<active_diagnostic_request_t*> recurring_requests_; /*!< recurringRequests - A list of active recurring diagnostic requests.*/ - std::vector<active_diagnostic_request_t*> non_recurring_requests_; /*!< nonrecurringRequests - A list of active one-time diagnostic requests. When a - * response is received for a non-recurring request or it times out, it is removed*/ - bool initialized_; /*!< * initialized - True if the DiagnosticsManager has been initialized with shims. It will interface with the uds-c lib*/ - - void init_diagnostic_shims(); - void reset(); - - static bool shims_send(const uint32_t arbitration_id, const uint8_t* data, const uint8_t size); - static void shims_logger(const char* m, ...); - static void shims_timer(); -public: - diagnostic_manager_t(); - - bool initialize(); - - const std::string get_bus_name() const; - const std::string get_bus_device_name() const; - active_diagnostic_request_t* get_last_recurring_requests() const; - DiagnosticShims& get_shims(); - - void find_and_erase(active_diagnostic_request_t* entry, std::vector<active_diagnostic_request_t*>& requests_list); - void cancel_request(active_diagnostic_request_t* entry); - void cleanup_request(active_diagnostic_request_t* entry, bool force); - void cleanup_active_requests(bool force); - active_diagnostic_request_t* find_recurring_request(DiagnosticRequest& request); - - // Subscription parts - active_diagnostic_request_t* add_request(DiagnosticRequest* request, const std::string& name, - bool waitForMultipleResponses, const DiagnosticResponseDecoder decoder, - const DiagnosticResponseCallback callback); - bool validate_optional_request_attributes(float frequencyHz); - active_diagnostic_request_t* add_recurring_request(DiagnosticRequest* request, const char* name, - bool waitForMultipleResponses, const DiagnosticResponseDecoder decoder, - const DiagnosticResponseCallback callback, float frequencyHz); - - // Decoding part - openxc_VehicleMessage relay_diagnostic_response(active_diagnostic_request_t* adr, const DiagnosticResponse& response); - openxc_VehicleMessage relay_diagnostic_handle(active_diagnostic_request_t* entry, const can_message_t& cm); - openxc_VehicleMessage find_and_decode_adr(const can_message_t& cm); - bool is_diagnostic_response(const can_message_t& cm); -}; diff --git a/CAN-binder/low-can-binding/diagnostic/diagnostic-message.cpp b/CAN-binder/low-can-binding/diagnostic/diagnostic-message.cpp deleted file mode 100644 index 69ca4e3..0000000 --- a/CAN-binder/low-can-binding/diagnostic/diagnostic-message.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <map> - -#include "diagnostic-message.hpp" - -#include "../binding/application.hpp" -#include "../utils/signals.hpp" - -const char *UNIT_NAMES[10] = { - "POURCENT", - "DEGREES_CELSIUS", - "KPA", - "RPM", - "GRAMS_SEC", - "SECONDS", - "KM", - "KM_H", - "PA", - "NM" -}; - -diagnostic_message_t::diagnostic_message_t(uint8_t pid, const std::string& generic_name, const int min, - const int max, enum UNIT unit, float frequency, DiagnosticResponseDecoder decoder, - DiagnosticResponseCallback callback, bool supported) - : parent_{nullptr}, pid_{pid}, generic_name_{generic_name}, min_{min}, max_{max}, unit_{unit}, - frequency_{frequency}, decoder_{decoder}, callback_{callback}, supported_{supported} -{} - -uint32_t diagnostic_message_t::get_pid() -{ - return (uint32_t)pid_; -} - -const std::string diagnostic_message_t::get_generic_name() const -{ - return generic_name_; -} - -const std::string diagnostic_message_t::get_name() const -{ - return active_diagnostic_request_t::get_prefix() + "." + generic_name_; -} - -float diagnostic_message_t::get_frequency() const -{ - return frequency_; -} - -DiagnosticResponseDecoder diagnostic_message_t::get_decoder() const -{ - return decoder_; -} -DiagnosticResponseCallback diagnostic_message_t::get_callback() const -{ - return callback_; -} - -bool diagnostic_message_t::get_supported() const -{ - return supported_; -} - -void diagnostic_message_t::set_supported(bool value) -{ - supported_ = value; -} - -void diagnostic_message_t::set_parent(can_message_set_t* parent) -{ - parent_ = parent; -} - -/// -/// @brief Build a DiagnosticRequest struct to be passed -/// to diagnostic manager instance. -/// - const DiagnosticRequest diagnostic_message_t::build_diagnostic_request() const -{ - return {/*arbitration_id: */OBD2_FUNCTIONAL_BROADCAST_ID, - /*mode: */0x1, - /*has_pid: */true, - /*pid: */pid_, - /*pid_length: */0, - /*payload[]: */{0}, - /*payload_length: */0, - /*no_frame_padding: */false, - /*DiagnosticRequestType: */DiagnosticRequestType::DIAGNOSTIC_REQUEST_TYPE_PID }; -} - -/// -/// @brief Check if a request is an OBD-II PID request. -/// -/// @return true if the request is a mode 1 request and it has a 1 byte PID. -/// -bool diagnostic_message_t::is_obd2_request(const DiagnosticRequest* request) -{ - return request->mode == 0x1 && request->has_pid && request->pid < 0xff; -} diff --git a/CAN-binder/low-can-binding/diagnostic/diagnostic-message.hpp b/CAN-binder/low-can-binding/diagnostic/diagnostic-message.hpp deleted file mode 100644 index 99c4811..0000000 --- a/CAN-binder/low-can-binding/diagnostic/diagnostic-message.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <vector> -#include <string> - -#include "uds/uds.h" -#include "../can/can-message-set.hpp" -#include "../can/can-message.hpp" -#include "active-diagnostic-request.hpp" - -enum UNIT { - POURCENT, - DEGREES_CELSIUS, - KPA, - RPM, - GRAMS_SEC, - SECONDS, - KM, - KM_H, - PA, - NM, - INVALID -}; - -class can_message_set_t; - -/// @brief - A representation of an OBD-II PID. -class diagnostic_message_t -{ - private: - can_message_set_t* parent_; /*!< parent_ - Pointer to the CAN message set holding this diagnostic message */ - uint8_t pid_; /*!< pid_ - The 1 byte PID.*/ - std::string generic_name_; /*!< generic_name_ - A human readable name to use for this PID when published.*/ - int min_; /*!< min_ - Minimum value that can take this pid */ - int max_; /*!< max_ - Maximum value that can take this pid */ - enum UNIT unit_; /*!< unit_ : Which unit system is used by that pid. See enum UNIT above.*/ - float frequency_; /*!< frequency_ - The frequency to request this PID if supported by the vehicle when automatic, recurring OBD-II requests are enabled.*/ - DiagnosticResponseDecoder decoder_; /*!< decoder_ - An optional DiagnosticResponseDecoder to parse the payload of responses - * to this request. If the decoder is NULL, the output will include the raw payload - * instead of a parsed value.*/ - DiagnosticResponseCallback callback_; /*!< callback_ - An optional DiagnosticResponseCallback to be notified whenever a - * response is received for this request.*/ - - bool supported_; /*!< supported_ - boolean indicating whether this pid is supported by the vehicle or not.*/ - - public: - const char* generic_name = generic_name_.c_str(); - diagnostic_message_t(uint8_t pid, const std::string& generic_name, const int min, const int max, enum UNIT unit, float frequency, - DiagnosticResponseDecoder decoder, DiagnosticResponseCallback callback, bool supported); - - uint32_t get_pid(); - const std::string get_generic_name() const; - const std::string get_name() const; - float get_frequency() const; - DiagnosticResponseDecoder get_decoder() const; - DiagnosticResponseCallback get_callback() const; - bool get_supported() const; - - void set_supported(bool value); - void set_parent(can_message_set_t* parent); - const DiagnosticRequest build_diagnostic_request() const; - - bool is_obd2_response(const can_message_t& can_message); - bool is_obd2_request(const DiagnosticRequest *request); -}; diff --git a/CAN-binder/low-can-binding/utils/config-parser.cpp b/CAN-binder/low-can-binding/utils/config-parser.cpp deleted file mode 100644 index 8ccf5bc..0000000 --- a/CAN-binder/low-can-binding/utils/config-parser.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2015, 2016 ,2017 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "config-parser.hpp" - -#include "../binding/low-can-hat.hpp" - -namespace utils -{ - /// @brief constructor using path to file - config_parser_t::config_parser_t(std::string conf_file) - : filepath_{conf_file}, config_content_{} - { - config_content_.read_file(conf_file); - } - - const std::string& config_parser_t::filepath() const - { - return filepath_; - } - - /// @brief read the conf_file_ and parse it into an INIReader object - /// to search into later. - bool config_parser_t::check_conf() - { - if (config_content_.size() <= 0) - { - ERROR("Can't load the INI config file."); - return false; - } - DEBUG("Configuration file parsed"); - return true; - } - - /// @brief Public method to access devices_name_ vector. If vector size equal 0 - /// then it will parses the configuration file content to fill it. It could be empty even - /// after parsing if content file just don't have a correct "canbus" directive so you - /// have to test the returned value. - /// - /// @return A const vector with string of linux CAN devices. - const std::vector<std::pair<std::string, std::string> > config_parser_t::get_devices_name() - { - std::vector<std::pair<std::string, std::string> > devices_name; - - std::map<std::string, std::string> bus_mapping = config_content_.get_keys("CANbus-mapping"); - for(const auto& busIt : bus_mapping ) - { - devices_name.push_back(std::make_pair(busIt.first, busIt.second)); - } - - return devices_name; - } -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/utils/config-parser.hpp b/CAN-binder/low-can-binding/utils/config-parser.hpp deleted file mode 100644 index 3115e9b..0000000 --- a/CAN-binder/low-can-binding/utils/config-parser.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2015, 2016 ,2017 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <string> -#include <vector> -#include <utility> -#include "ini-config.hpp" - -namespace utils -{ - /// @brief A configuration file parser that handle INI configuration - /// file format. - class config_parser_t - { - private: - const std::string filepath_; /*!< filepath_ - Path to the config file*/ - ini_config config_content_; /*!< config_content_ - Parsed content of INI file.*/ - - public: - config_parser_t(config_parser_t&&) = default; - config_parser_t(const config_parser_t&) = default; - explicit config_parser_t(std::string conf_file); - - const std::string& filepath() const; - bool check_conf(); - const std::vector<std::pair<std::string, std::string> > get_devices_name(); - }; -} diff --git a/CAN-binder/low-can-binding/utils/openxc-utils.cpp b/CAN-binder/low-can-binding/utils/openxc-utils.cpp deleted file mode 100644 index f39f418..0000000 --- a/CAN-binder/low-can-binding/utils/openxc-utils.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loic Collignon" <loic.collignon@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "openxc-utils.hpp" - -#include "../binding/application.hpp" - -/// -/// @brief Build a specific VehicleMessage containing a DiagnosticResponse. -/// -/// @param[in] request - Original request use to retrieve decoder and callback -/// @param[in] response - Response to the request that will be decoded if decoder set -/// and put into the DiagnosticResponse of the VehicleMessage. -/// @param[in] parsed_value - raw parsed value of the payload from CAN message -/// -/// @return a vehicle message including simple message that will be convert into -/// a JSON object before being pushed to the subscribers -/// -const openxc_VehicleMessage build_VehicleMessage(active_diagnostic_request_t* request, const DiagnosticResponse& response, float parsed_value) -{ - openxc_VehicleMessage message; - application_t& app = application_t::instance(); - - message.has_type = true; - message.type = openxc_VehicleMessage_Type::openxc_VehicleMessage_Type_DIAGNOSTIC; - message.has_diagnostic_response = true; - message.diagnostic_response.has_bus = true; - message.diagnostic_response.bus = app.get_can_bus_manager().get_can_device_index( - app.get_diagnostic_manager().get_bus_name()); - message.diagnostic_response.has_message_id = true; - - if(request->get_id() != OBD2_FUNCTIONAL_BROADCAST_ID) - { - message.diagnostic_response.message_id = response.arbitration_id - - DIAGNOSTIC_RESPONSE_ARBITRATION_ID_OFFSET; - } - else - { - // must preserve responding arb ID for responses to functional broadcast - // requests, as they are the actual module address and not just arb ID + - // 8. - message.diagnostic_response.message_id = response.arbitration_id; - } - - message.diagnostic_response.has_mode = true; - message.diagnostic_response.mode = response.mode; - message.diagnostic_response.has_pid = response.has_pid; - if(message.diagnostic_response.has_pid) - message.diagnostic_response.pid = response.pid; - message.diagnostic_response.has_success = true; - message.diagnostic_response.success = response.success; - message.diagnostic_response.has_negative_response_code = !response.success; - message.diagnostic_response.negative_response_code = - response.negative_response_code; - - if(response.payload_length > 0) - { - if(request->get_decoder() != nullptr) - { - message.diagnostic_response.has_value = true; - message.diagnostic_response.value = parsed_value; - } - else - { - message.diagnostic_response.has_payload = true; - ::memcpy(message.diagnostic_response.payload.bytes, response.payload, - response.payload_length); - message.diagnostic_response.payload.size = response.payload_length; - } - } - - return message; -} -/// -/// @brief Build a specific VehicleMessage containing a SimpleMessage with associated timestamp -/// -/// @param[in] message - simple message to include into openxc_VehicleMessage -/// @param[in] timestamp - timestamp from ioctl when reading the socket -/// -/// @return a vehicle message including simple message that will be convert into -/// a JSON object before being pushed to the subscribers -/// -const openxc_VehicleMessage build_VehicleMessage(const openxc_SimpleMessage& message, uint64_t timestamp) -{ - openxc_VehicleMessage v; - - v.has_type = true, - v.type = openxc_VehicleMessage_Type::openxc_VehicleMessage_Type_SIMPLE; - v.has_simple_message = true; - v.simple_message = message; - v.has_timestamp = true; - v.timestamp = timestamp; - - return v; -} - -/// -/// @brief Build a specific VehicleMessage containing a SimpleMessage. -/// -/// @param[in] message - simple message to include into openxc_VehicleMessage -/// -/// @return a vehicle message including simple message that will be convert into -/// a JSON object before being pushed to the subscribers -/// -const openxc_VehicleMessage build_VehicleMessage(const openxc_SimpleMessage& message) -{ - openxc_VehicleMessage v; - - v.has_type = true, - v.type = openxc_VehicleMessage_Type::openxc_VehicleMessage_Type_SIMPLE; - v.has_simple_message = true; - v.simple_message = message; - v.has_timestamp = true; - v.timestamp = system_time_us(); - - return v; -} - -/// -/// @brief Build an empty VehicleMessage that isn't usable by at least the struct -/// is initialized for the most part and can be use to check a false return value. -/// -/// @return A VehicleMessage with all boolean value to false. -/// -openxc_VehicleMessage build_VehicleMessage() -{ - openxc_VehicleMessage v; - - ::memset(&v, 0, sizeof(openxc_VehicleMessage)); - return v; -} - -bool is_valid(const openxc_VehicleMessage& v) -{ - if (v.has_type == false && - v.has_can_message == false && - v.has_simple_message == false && - v.has_diagnostic_response == false && - v.has_control_command == false && - v.has_command_response == false && - v.has_timestamp == false) - return false; - return true; -} - -/// -/// @brief Build an openxc_SimpleMessage associating a name to an openxc_DynamicField -/// -/// @param[in] name - const string reference name to assign to the created SimpleMessage -/// this will set has_name member to true and assign name to the name member. Maximum size for name is -/// set to 100 char. -/// @param[in] value - const reference with DynamicField to assign to SimpleMessage -/// value. -/// -/// @return an openxc_SimpleMessage struct initialized with name and value provided. -/// -const openxc_SimpleMessage build_SimpleMessage(const std::string& name, const openxc_DynamicField& value) -{ - openxc_SimpleMessage s; - - s.has_name = true; - ::strncpy(s.name, name.c_str(), 100); - s.has_value = true; - s.value = value; - - return s; -} - -/// -/// @brief Build an openxc_DynamicField with a string value -/// -/// @param[in] value - const string reference value to assign to builded -/// openxc_DynamicField. -/// -/// @return openxc_DynamicField initialized with a string value. -/// -const openxc_DynamicField build_DynamicField(const char* value) -{ - openxc_DynamicField d; - d.has_type = true; - d.type = openxc_DynamicField_Type_STRING; - - d.has_string_value = true; - d.has_numeric_value = false; - d.has_boolean_value = false; - ::strncpy(d.string_value, value, 100); - - return d; -} - -/// -/// @brief Build an openxc_DynamicField with a string value -/// -/// @param[in] value - const string reference value to assign to builded -/// openxc_DynamicField. -/// -/// @return openxc_DynamicField initialized with a string value. -/// -const openxc_DynamicField build_DynamicField(const std::string& value) -{ - openxc_DynamicField d; - d.has_type = true; - d.type = openxc_DynamicField_Type_STRING; - - d.has_string_value = true; - d.has_numeric_value = false; - d.has_boolean_value = false; - ::strncpy(d.string_value, value.c_str(), 100); - - return d; -} - -/// -/// @fn openxc_DynamicField build_DynamicField(double value); -/// -/// @brief Build an openxc_DynamicField with a double value -/// -/// @param[in] value - double value to assign to builded openxc_DynamicField. -/// -/// @return openxc_DynamicField initialized with a double value. -/// -const openxc_DynamicField build_DynamicField(double value) -{ - openxc_DynamicField d; - d.has_type = true; - d.type = openxc_DynamicField_Type_NUM; - - d.has_string_value = false; - d.has_numeric_value = true; - d.has_boolean_value = false; - d.numeric_value = value; - - return d; -} - -/// -/// @brief Build an openxc_DynamicField with a boolean value -/// -/// @param[in] value - boolean value to assign to builded openxc_DynamicField. -/// -/// @return openxc_DynamicField initialized with a boolean value. -/// -const openxc_DynamicField build_DynamicField(bool value) -{ - openxc_DynamicField d; - d.has_type = true; - d.type = openxc_DynamicField_Type_BOOL; - - d.has_string_value = false; - d.has_numeric_value = false; - d.has_boolean_value = true; - d.boolean_value = value; - - return d; -} - -int get_bool_from_DynamicField(const openxc_VehicleMessage& v_msg, bool* ret) -{ - if(v_msg.has_simple_message && v_msg.simple_message.has_value && v_msg.simple_message.value.has_boolean_value) - { - *ret = v_msg.simple_message.value.boolean_value; - return 0; - } - - return -1; -} - -double get_numerical_from_DynamicField(const openxc_VehicleMessage& v_msg) -{ - return (v_msg.has_simple_message && v_msg.simple_message.has_value && v_msg.simple_message.value.has_numeric_value) ? - v_msg.simple_message.value.numeric_value : -1.0; -} - -const std::string get_string_from_DynamicField(const openxc_VehicleMessage& v_msg) -{ -return (v_msg.has_simple_message && v_msg.simple_message.has_value && v_msg.simple_message.value.has_string_value) ? - v_msg.simple_message.value.string_value : ""; -} - -/// -/// @brief Extract the simple message value from an openxc_VehicleMessage -/// and return it. If there isn't SimpleMessage in the VehicleMessage then -/// returned value will be a SimpleMessage with all field set at false. -/// DynamicField from SimpleMessage will be boolean DynamicField set to false too. -/// -/// @param[in] v_msg - const reference to openxc_VehicleMessage -/// -/// @return A simpleMessage from the provided VehicleMessage. -/// -const openxc_SimpleMessage get_simple_message(const openxc_VehicleMessage& v_msg) -{ - if (v_msg.has_simple_message) - return v_msg.simple_message; - - openxc_SimpleMessage s_msg = { false, "", false, build_DynamicField(false), false, build_DynamicField(false)}; - return s_msg; -} - -/// -/// @brief Make a JSON object from a DynamicField -/// -/// @param[in] field - openxc_DynamicField struct to convert into -/// a json object. -/// @param[out] value - pointer to the object to set up. -/// -void jsonify_DynamicField(const openxc_DynamicField& field, json_object* value) -{ - if(field.has_numeric_value) - json_object_object_add(value, "value", json_object_new_double(field.numeric_value)); - else if(field.has_boolean_value) - json_object_object_add(value, "value", json_object_new_boolean(field.boolean_value)); - else if(field.has_string_value) - json_object_object_add(value, "value", json_object_new_string(field.string_value)); -} - -/// -/// @brief Make a JSON object from a SimpleMessage -/// -/// @param[in] s_msg - const reference to an openxc_SimpleMessage -/// struct to convert into a json object. -/// @param[out] json - pointer with the DynamicField converted into json object -/// -/// @return True if SimpleMessage has been transformed into json object -/// and false if not. In such case, a json object is returned { "error": "error msg"} -/// -bool jsonify_simple(const openxc_SimpleMessage& s_msg, json_object* json) -{ - if(s_msg.has_name) - { - json_object_object_add(json, "name", json_object_new_string(s_msg.name)); - jsonify_DynamicField(s_msg.value, json); - return true; - } - json_object_object_add(json, "error", json_object_new_string("openxc_SimpleMessage doesn't have name'")); - return false; -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/utils/openxc-utils.hpp b/CAN-binder/low-can-binding/utils/openxc-utils.hpp deleted file mode 100644 index 83d6379..0000000 --- a/CAN-binder/low-can-binding/utils/openxc-utils.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loic Collignon" <loic.collignon@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <string> -#include <json-c/json.h> -#include <sys/timeb.h> - -#include "openxc.pb.h" -#include "../diagnostic/active-diagnostic-request.hpp" - -const openxc_VehicleMessage build_VehicleMessage(active_diagnostic_request_t* request, const DiagnosticResponse& response, float parsed_value); -const openxc_VehicleMessage build_VehicleMessage(const openxc_SimpleMessage& message, uint64_t timestamp); -const openxc_VehicleMessage build_VehicleMessage(const openxc_SimpleMessage& message); -openxc_VehicleMessage build_VehicleMessage(); -bool is_valid(const openxc_VehicleMessage& v); - -const openxc_SimpleMessage build_SimpleMessage(const std::string& name, const openxc_DynamicField& value); -const openxc_DynamicField build_DynamicField(const char* value); -const openxc_DynamicField build_DynamicField(const std::string& value); -const openxc_DynamicField build_DynamicField(double value); -const openxc_DynamicField build_DynamicField(bool value); - -int get_bool_from_DynamicField(const openxc_VehicleMessage& v_msg, bool& ret); -double get_numerical_from_DynamicField(const openxc_VehicleMessage& v_msg); -const std::string get_string_from_DynamicField(const openxc_VehicleMessage& v_msg); -const openxc_SimpleMessage get_simple_message(const openxc_VehicleMessage& v_msg); - -void jsonify_DynamicField(const openxc_DynamicField& field, json_object* value); - -bool jsonify_simple(const openxc_SimpleMessage& s_msg, json_object* json);
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/utils/signals.cpp b/CAN-binder/low-can-binding/utils/signals.cpp deleted file mode 100644 index fbc4904..0000000 --- a/CAN-binder/low-can-binding/utils/signals.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "signals.hpp" - -namespace utils -{ - signals_manager_t::signals_manager_t() - {} - - /// @brief Return singleton instance of configuration object. - signals_manager_t& signals_manager_t::instance() - { - static signals_manager_t sm; - return sm; - } - - /// @brief Return Subscribed signals map mutex. - std::mutex& signals_manager_t::get_subscribed_signals_mutex() - { - return subscribed_signals_mutex_; - } - - /// - /// @brief return the subscribed_signals map. - /// - /// @return Map of subscribed signals. - std::map<int, std::shared_ptr<low_can_subscription_t> >& signals_manager_t::get_subscribed_signals() - { - return subscribed_signals_; - } - - /// - /// @fn std::vector<std::string> find_signals(const openxc_DynamicField &key) - /// @brief return signals name found searching through CAN_signals and OBD2 pid - /// - /// @param[in] key : can contain numeric or string value in order to search against - /// can signals or obd2 signals name. - /// - /// @return Vector of signals name found. - /// - struct signals_found signals_manager_t::find_signals(const openxc_DynamicField &key) - { - struct signals_found sf; - - switch(key.type) - { - case openxc_DynamicField_Type::openxc_DynamicField_Type_STRING: - lookup_signals_by_name(key.string_value, application_t::instance().get_all_can_signals(), sf.can_signals); - lookup_signals_by_name(key.string_value, application_t::instance().get_diagnostic_messages(), sf.diagnostic_messages); - break; - case openxc_DynamicField_Type::openxc_DynamicField_Type_NUM: - lookup_signals_by_id(key.numeric_value, application_t::instance().get_all_can_signals(), sf.can_signals); - lookup_signals_by_id(key.numeric_value, application_t::instance().get_diagnostic_messages(), sf.diagnostic_messages); - break; - default: - ERROR("wrong openxc_DynamicField specified. Use openxc_DynamicField_Type_NUM or openxc_DynamicField_Type_STRING type only."); - break; - } - DEBUG("Found %d signal(s)", (int)(sf.can_signals.size() + sf.diagnostic_messages.size())); - return sf; - } -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/utils/signals.hpp b/CAN-binder/low-can-binding/utils/signals.hpp deleted file mode 100644 index 555c5dd..0000000 --- a/CAN-binder/low-can-binding/utils/signals.hpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <vector> -#include <string> -#include <fnmatch.h> - -#include "openxc.pb.h" -#include "../binding/application.hpp" -#include "../can/can-signals.hpp" -#include "../diagnostic/diagnostic-message.hpp" - -#include "../binding/low-can-hat.hpp" -#include "../binding/low-can-subscription.hpp" - -namespace utils -{ - struct signals_found - { - std::vector<std::shared_ptr<can_signal_t> > can_signals; - std::vector<std::shared_ptr<diagnostic_message_t> > diagnostic_messages; - }; - - /// @brief Signal manager singleton hold subscription object with attached afb_event and its mutex - /// to read and write it safely. - /// It can be used to browse CAN signals and Diagnostic messages vectors and find a particular signal to - /// subscribe to. - class signals_manager_t - { - private: - std::mutex subscribed_signals_mutex_; - std::map<int, std::shared_ptr<low_can_subscription_t> > subscribed_signals_; ///< Map containing all subscribed signals, key is the socket int value. - - signals_manager_t(); ///< Private constructor to make singleton class. - - public: - static signals_manager_t& instance(); - - std::mutex& get_subscribed_signals_mutex(); - std::map<int, std::shared_ptr<low_can_subscription_t> >& get_subscribed_signals(); - - struct signals_found find_signals(const openxc_DynamicField &key); - void find_diagnostic_messages(const openxc_DynamicField &key, std::vector<std::shared_ptr<diagnostic_message_t> >& found_signals); - void find_can_signals(const openxc_DynamicField &key, std::vector<std::shared_ptr<can_signal_t> >& found_signals); - - template <typename T> - void lookup_signals_by_name(const std::string& key, std::vector<std::shared_ptr<T> > signals, std::vector<std::shared_ptr<T> >& found_signals) - { - for(std::shared_ptr<T> s : signals) - { - if(::fnmatch(key.c_str(), s->get_generic_name().c_str(), FNM_CASEFOLD) == 0) - found_signals.push_back(s); - else if(::fnmatch(key.c_str(), s->get_name().c_str(), FNM_CASEFOLD) == 0) - found_signals.push_back(s); - } - } - - template <typename T> - void lookup_signals_by_id(const double key, std::vector<std::shared_ptr<T> > signals, std::vector<std::shared_ptr<T> >& found_signals) - { - for(std::shared_ptr<T> s : signals) - { - if(application_t::instance().get_signal_id(*s) == key) - { - found_signals.push_back(s); - } - } - } - }; -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/utils/socketcan-bcm.cpp b/CAN-binder/low-can-binding/utils/socketcan-bcm.cpp deleted file mode 100644 index e16b246..0000000 --- a/CAN-binder/low-can-binding/utils/socketcan-bcm.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2015, 2016 ,2017 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loïc Collignon" <loic.collignon@iot.bzh> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "socketcan-bcm.hpp" - -#include <net/if.h> -#include <sys/ioctl.h> -#include <fcntl.h> - -#include "../binding/application.hpp" - -namespace utils -{ - /// @brief Connect the socket. - /// @return 0 if success. - int socketcan_bcm_t::connect(const struct sockaddr* addr, socklen_t len) - { - return socket_ != INVALID_SOCKET ? ::connect(socket_, addr, len) : 0; - } - - /// @brief Open a raw socket CAN. - /// @param[in] device_name is the kernel network device name of the CAN interface. - /// - /// @return Upon successful completion, shall return a non-negative integer, the socket file descriptor. Otherwise, a value of -1 shall be returned and errno set to indicate the error. - int socketcan_bcm_t::open(std::string device_name) - { - close(); - - struct ifreq ifr; - socket_ = socketcan_t::open(PF_CAN, SOCK_DGRAM, CAN_BCM); - - // Attempts to open a socket to CAN bus - ::strcpy(ifr.ifr_name, device_name.c_str()); - DEBUG("BCM socket ifr_name is : %s", ifr.ifr_name); - if(::ioctl(socket_, SIOCGIFINDEX, &ifr) < 0) - { - ERROR("ioctl failed. Error was : %s", strerror(errno)); - close(); - } - else - { - tx_address_.can_family = AF_CAN; - tx_address_.can_ifindex = ifr.ifr_ifindex; - - if(connect((struct sockaddr *)&tx_address_, sizeof(tx_address_)) < 0) - { - ERROR("Connect failed. %s", strerror(errno)); - close(); - } - // Needed because of using systemD event loop. See sd_event_add_io manual. - fcntl(socketcan_t::socket_, F_SETFL, O_NONBLOCK); - } - return socket_; - } - - /// Read the socket to retrieve the associated CAN message. All the hard work is do into - /// convert_from_frame method and if there isn't CAN message retrieve, only BCM head struct, - /// then CAN message will be zeroed and must be handled later. - socketcan_bcm_t& operator>>(socketcan_bcm_t& s, can_message_t& cm) - { - struct utils::simple_bcm_msg msg; - - ::memset(&msg, 0, sizeof(msg)); - const struct sockaddr_can& addr = s.get_tx_address(); - socklen_t addrlen = sizeof(addr); - struct ifreq ifr; - - ssize_t nbytes = ::recvfrom(s.socket(), &msg, sizeof(msg), 0, (struct sockaddr*)&addr, &addrlen); - ifr.ifr_ifindex = addr.can_ifindex; - ioctl(s.socket(), SIOCGIFNAME, &ifr); - long unsigned int frame_size = nbytes-sizeof(struct bcm_msg_head); - - DEBUG("Data available: %li bytes read. BCM head, opcode: %i, can_id: %i, nframes: %i", frame_size, msg.msg_head.opcode, msg.msg_head.can_id, msg.msg_head.nframes); - DEBUG("read: Found on bus %s:\n id: %X, length: %X, data %02X%02X%02X%02X%02X%02X%02X%02X", ifr.ifr_name, msg.msg_head.can_id, msg.frames.can_dlc, - msg.frames.data[0], msg.frames.data[1], msg.frames.data[2], msg.frames.data[3], msg.frames.data[4], msg.frames.data[5], msg.frames.data[6], msg.frames.data[7]); - - struct timeval tv; - ioctl(s.socket(), SIOCGSTAMP, &tv); - uint64_t timestamp = 1000000 * tv.tv_sec + tv.tv_usec; - cm = ::can_message_t::convert_from_frame(msg.frames , - frame_size, - timestamp); - cm.set_sub_id((int)s.socket()); - - return s; - } -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/utils/socketcan-bcm.hpp b/CAN-binder/low-can-binding/utils/socketcan-bcm.hpp deleted file mode 100644 index 97f093d..0000000 --- a/CAN-binder/low-can-binding/utils/socketcan-bcm.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2015, 2016 ,2017 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loïc Collignon" <loic.collignon@iot.bzh> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "socketcan.hpp" -#include "../can/can-message.hpp" - -namespace utils -{ - struct simple_bcm_msg - { - struct bcm_msg_head msg_head; - struct can_frame frames; - }; - - struct canfd_bcm_msg - { - struct bcm_msg_head msg_head; - struct canfd_frame frames; - canfd_bcm_msg() { msg_head.flags |= CAN_FD_FRAME; } - }; - - /// @brief derivated socketcan class specialized for BCM CAN socket. - class socketcan_bcm_t : public socketcan_t - { - public: - using socketcan_t::socketcan_t; - - virtual int open(std::string device_name); - - private: - int connect(const struct sockaddr* addr, socklen_t len); - }; - - socketcan_bcm_t& operator>>(socketcan_bcm_t& s, can_message_t& cm); -// socketcan_bcm_t& operator<<(socketcan_bcm_t& s, const struct simple_bcm_msg& obj); -// socketcan_bcm_t& operator<<(socketcan_bcm_t& s, const struct canfd_bcm_msg& obj); -} diff --git a/CAN-binder/low-can-binding/utils/socketcan-raw.cpp b/CAN-binder/low-can-binding/utils/socketcan-raw.cpp deleted file mode 100644 index 31965c3..0000000 --- a/CAN-binder/low-can-binding/utils/socketcan-raw.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2015, 2016 ,2017 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loïc Collignon" <loic.collignon@iot.bzh> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "socketcan-raw.hpp" - -#include <net/if.h> -#include <sys/ioctl.h> - -namespace utils -{ - /// @brief Bind the socket. - /// @return 0 if success. - int socketcan_raw_t::bind(const struct sockaddr* addr, socklen_t len) - { - return socket_ != INVALID_SOCKET ? ::bind(socket_, addr, len) : 0; - } - - /// @brief Open a raw socket CAN. - /// @param[in] device_name is the kernel network device name of the CAN interface. - /// - /// @return Upon successful completion, shall return a non-negative integer, the socket file descriptor. Otherwise, a value of -1 shall be returned and errno set to indicate the error. - int socketcan_raw_t::open(std::string device_name) - { - close(); - - struct ifreq ifr; - socket_ = socketcan_t::open(PF_CAN, SOCK_RAW, CAN_RAW); - - // Attempts to open a socket to CAN bus - ::strcpy(ifr.ifr_name, device_name.c_str()); - DEBUG("ifr_name is : %s", ifr.ifr_name); - if(::ioctl(socket_, SIOCGIFINDEX, &ifr) < 0) - { - ERROR("ioctl failed. Error was : %s", strerror(errno)); - close(); - } - else - { - tx_address_.can_family = AF_CAN; - tx_address_.can_ifindex = ifr.ifr_ifindex; - - if(bind((struct sockaddr *)&tx_address_, sizeof(tx_address_)) < 0) - { - ERROR("Bind failed. %s", strerror(errno)); - close(); - } - } - return socket_; - } - - socketcan_raw_t& operator>>(socketcan_raw_t& s, can_message_t& cm) - { - struct canfd_frame frame; - - const struct sockaddr_can& addr = s.get_tx_address(); - socklen_t addrlen = sizeof(addr); - struct ifreq ifr; - - ssize_t nbytes = ::recvfrom(s.socket(), &frame, sizeof(frame), 0, (struct sockaddr*)&addr, &addrlen); - ifr.ifr_ifindex = addr.can_ifindex; - ioctl(s.socket(), SIOCGIFNAME, &ifr); - - DEBUG("Data available: %i bytes read", (int)nbytes); - DEBUG("read: Found on bus %s:\n id: %X, length: %X, data %02X%02X%02X%02X%02X%02X%02X%02X", ifr.ifr_name, frame.can_id, frame.len, - frame.data[0], frame.data[1], frame.data[2], frame.data[3], frame.data[4], frame.data[5], frame.data[6], frame.data[7]); - - struct timeval tv; - ioctl(s.socket(), SIOCGSTAMP, &tv); - uint64_t timestamp = 1000000 * tv.tv_sec + tv.tv_usec; - cm = ::can_message_t::convert_from_frame(frame , nbytes, timestamp); - - return s; - } -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/utils/socketcan-raw.hpp b/CAN-binder/low-can-binding/utils/socketcan-raw.hpp deleted file mode 100644 index 6167241..0000000 --- a/CAN-binder/low-can-binding/utils/socketcan-raw.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2015, 2016 ,2017 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loïc Collignon" <loic.collignon@iot.bzh> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include "socketcan.hpp" -#include "../can/can-message.hpp" - -namespace utils -{ - class socketcan_raw_t : public socketcan_t - { - public: - using socketcan_t::socketcan_t; - virtual int open(std::string device_name); - - private: - int bind(const struct sockaddr* addr, socklen_t len); - }; - - socketcan_raw_t& operator>>(socketcan_raw_t& s, can_message_t& cm); -} diff --git a/CAN-binder/low-can-binding/utils/socketcan.cpp b/CAN-binder/low-can-binding/utils/socketcan.cpp deleted file mode 100644 index 71588a6..0000000 --- a/CAN-binder/low-can-binding/utils/socketcan.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2015, 2016 ,2017 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loïc Collignon" <loic.collignon@iot.bzh> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <unistd.h> -#include <string> -#include <linux/can/raw.h> -#include <net/if.h> -#include <sys/ioctl.h> - -#include "socketcan.hpp" - -namespace utils -{ - - /// @brief Construct a default, invalid, socket. - socketcan_t::socketcan_t() - : socket_{INVALID_SOCKET} - {} - - /// @brief Construct a socket by moving an existing one. - socketcan_t::socketcan_t(socketcan_t&& s) - : socket_{s.socket_} - { - ::memset(&tx_address_, 0, sizeof(tx_address_)); - } - - socketcan_t& socketcan_t::operator=(const socketcan_t& s) - { - socket_ = std::move(s.socket_); - return *this; - } - - socketcan_t::~socketcan_t() - { - close(); - socket_ = INVALID_SOCKET; - } - - const struct sockaddr_can& socketcan_t::get_tx_address() const - { - return tx_address_; - } - - /// @brief Test if socket is valid. - /// @return true if valid, false otherwise. - socketcan_t::operator bool() const - { - return socket_ != INVALID_SOCKET; - } - - /// @brief Open the socket. - /// @param[in] domain Specifies the communications domain in which a socket is to be created. - /// @param[in] type Specifies the type of socket to be created. - /// @param[in] protocol Specifies a particular protocol to be used with the socket. Specifying a protocol of 0 causes socket() to use an unspecified default protocol appropriate for the requested socket type. - /// @return Upon successful completion, shall return a non-negative integer, the socket file descriptor. Otherwise, a value of -1 shall be returned and errno set to indicate the error. - int socketcan_t::open(int domain, int type, int protocol) - { - close(); - socket_ = ::socket(domain, type, protocol); - return socket_; - } - - /// @brief Close the socket. - /// @return 0 if success. - int socketcan_t::close() - { - return socket_ != INVALID_SOCKET ? ::close(socket_) : 0; - } - - /// @brief Set socket option. - /// @return 0 if success. - int socketcan_t::setopt(int level, int optname, const void* optval, socklen_t optlen) - { - return socket_ != INVALID_SOCKET ? ::setsockopt(socket_, level, optname, optval, optlen) : 0; - } - - /// @brief Get the file descriptor. - /// @return The socket's file descriptor - int socketcan_t::socket() const - { - return socket_; - } -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/utils/socketcan.hpp b/CAN-binder/low-can-binding/utils/socketcan.hpp deleted file mode 100644 index 82b797e..0000000 --- a/CAN-binder/low-can-binding/utils/socketcan.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2015, 2016 ,2017 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * Author "Loïc Collignon" <loic.collignon@iot.bzh> - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vector> - -#include <sys/socket.h> -#include <linux/can/bcm.h> -#include <string.h> - -#include "../binding/low-can-hat.hpp" - -#define INVALID_SOCKET -1 - -namespace utils -{ - class socketcan_t - { - public: - socketcan_t(); - socketcan_t(const socketcan_t& s) = delete; - socketcan_t(socketcan_t&&); - socketcan_t& operator=(const socketcan_t& s); - virtual ~socketcan_t(); - - const struct sockaddr_can& get_tx_address() const; - explicit operator bool() const; - - int socket() const; - virtual int open(std::string device_name) = 0; - int setopt(int level, int optname, const void* optval, socklen_t optlen); - int close(); - - protected: - int socket_; - struct sockaddr_can tx_address_; - - int open(int domain, int type, int protocol); - }; - - template <typename T> - socketcan_t& operator<<(socketcan_t& s, const std::vector<T>& vobj) - { - for(const auto& obj : vobj) - s << obj; - return s; - } - - template <typename T> - socketcan_t& operator<<(socketcan_t& s, const T& obj) - { - if (::sendto(s.socket(), &obj, sizeof(obj), 0, (const struct sockaddr*)&s.get_tx_address(), sizeof(s.get_tx_address())) < 0) - ERROR("Error sending : %i %s", errno, ::strerror(errno)); - return s; - } -} diff --git a/CAN-binder/low-can-binding/utils/timer.cpp b/CAN-binder/low-can-binding/utils/timer.cpp deleted file mode 100644 index f3cdd5e..0000000 --- a/CAN-binder/low-can-binding/utils/timer.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <time.h> -#include <stdlib.h> -#include <cmath> - -#include "timer.hpp" - -long long int system_time_us() -{ - struct timespec t_usec; - long long int timestamp_usec = 0; - - if(!::clock_gettime(CLOCK_MONOTONIC, &t_usec)) - timestamp_usec = (t_usec.tv_nsec / 1000ll) + (t_usec.tv_sec* 1000000ll); - return timestamp_usec; -} - -long long int system_time_ms() -{ - struct timespec t_msec; - long long int timestamp_msec = 0; - - if(!::clock_gettime(CLOCK_MONOTONIC, &t_msec)) - timestamp_msec = (t_msec.tv_nsec / 1000000ll) + (t_msec.tv_sec* 1000ll); - return timestamp_msec; -} - -long long int system_time_s() -{ - struct timespec t_sec; - long long int timestamp_sec = 0; - - if(!::clock_gettime(CLOCK_MONOTONIC, &t_sec)) - timestamp_sec = t_sec.tv_sec; - return timestamp_sec; -} - -frequency_clock_t::frequency_clock_t() - : unit_{1000000}, frequency_{10.0}, last_tick_{0}, time_function_{nullptr} -{} - -frequency_clock_t::frequency_clock_t(float frequency) - : unit_{1000000}, frequency_{frequency}, last_tick_{0}, time_function_{nullptr} -{ - if(frequency_ <= 0) - frequency_ = 1; -} - -frequency_clock_t::frequency_clock_t(float frequency, uint64_t last_tick, time_function_t time_function) - : unit_{1000000}, frequency_{frequency}, last_tick_{0}, time_function_{nullptr} -{ - if(frequency_ <= 0) - frequency_ = 1; -} - -/// @brief Return the period in ms given the frequency in hertz. -/// @param[in] frequency - Frequency to convert, in hertz -float frequency_clock_t::frequency_to_period() const -{ - return frequency_ == 0 ? 0 : 1 / frequency_; -} - -/// @brief Return a timeval struct based on the frequency_ member. used to -/// specified CAN BCM timers. -const struct timeval frequency_clock_t::get_timeval_from_period() const -{ - struct timeval freq = {0, 0}; - float f; - freq.tv_usec = (long int)(std::modf(frequency_to_period(), &f) * unit_); - freq.tv_sec = (time_t)f; - - return freq; -} - -bool frequency_clock_t::started() -{ - return last_tick_ != 0; -} - -time_function_t frequency_clock_t::get_time_function() -{ - return time_function_ != nullptr ? time_function_ : system_time_us; -} - -bool frequency_clock_t::elapsed(bool stagger) -{ - float period = frequency_to_period(); - float elapsed_time = 0; - if(!started() && stagger) - last_tick_ = get_time_function()() - (rand() % int(period)); - - // Make sure it ticks the the first call - elapsed_time = !started() ? period : (float)get_time_function()() - (float)last_tick_; - - return frequency_ == 0 || elapsed_time >= period; -} - -float frequency_clock_t::get_frequency() const -{ - return frequency_; -} - -uint64_t frequency_clock_t::get_last_tick() const -{ - return last_tick_; -} - -/// @brief Force the clock to tick, regardless of it its time has actually -/// elapsed. -void frequency_clock_t::tick(uint64_t timestamp) -{ - last_tick_ = timestamp; -}
\ No newline at end of file diff --git a/CAN-binder/low-can-binding/utils/timer.hpp b/CAN-binder/low-can-binding/utils/timer.hpp deleted file mode 100644 index a667022..0000000 --- a/CAN-binder/low-can-binding/utils/timer.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2015, 2016 "IoT.bzh" - * Author "Romain Forlot" <romain.forlot@iot.bzh> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <sys/time.h> -#include <stdint.h> - -/// @brief return epoch in milliseconds -/// -/// @return long long int epoch in milliseconds -typedef long long int (*time_function_t)(); - -long long int system_time_us(); -long long int system_time_ms(); -long long int system_time_s(); - - -/// @brief A frequency counting clock. -/// Utility class allowing some time function. -class frequency_clock_t -{ -private: - float unit_; ///< unit_ - multiplicator to make operation to be in the right unit (milli, micro, nano, etc) - float frequency_; ///< the clock frequency in Hz. - uint64_t last_tick_; ///< the last time (in microseconds since startup) that the clock ticked. - time_function_t time_function_; ///< a function returning current time - -public: - frequency_clock_t(); - explicit frequency_clock_t(float frequency); - frequency_clock_t(float frequency, uint64_t last_tick, time_function_t time_function); - - float get_frequency() const; - const struct timeval get_timeval_from_period() const; - - float frequency_to_period() const; - bool started(); - time_function_t get_time_function(); - bool elapsed(bool stagger); - - uint64_t get_last_tick() const; - void tick(uint64_t timestamp); -};
\ No newline at end of file |