diff options
author | Romain Forlot <romain.forlot@iot.bzh> | 2019-11-26 16:18:36 +0100 |
---|---|---|
committer | Romain Forlot <romain.forlot@iot.bzh> | 2019-11-28 16:11:46 +0100 |
commit | 68d8bc019fab3e73654a330baf6b8dd7c11859ca (patch) | |
tree | e2a01ddfb0d640e1237ccae06e7be5e922cb237b /low-can-binding/can/message | |
parent | 006598ee46a227f52bcac7be172cd45a8a364aff (diff) |
Add feature to build messages and fix some functions
Allows to build a message (J1939,BCM) with a signal and a value.
Bug-AGL: SPEC-2386
Bug-AGL: SPEC-2976
Signed-off-by: Arthur Guyader <arthur.guyader@iot.bzh>
Change-Id: Iadca13a927ff83f713f39da441c88356695a1285
Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
Diffstat (limited to 'low-can-binding/can/message')
-rw-r--r-- | low-can-binding/can/message/can-message.cpp | 58 | ||||
-rw-r--r-- | low-can-binding/can/message/can-message.hpp | 10 | ||||
-rw-r--r-- | low-can-binding/can/message/j1939-message.cpp | 77 | ||||
-rw-r--r-- | low-can-binding/can/message/j1939-message.hpp | 12 | ||||
-rw-r--r-- | low-can-binding/can/message/message.cpp | 59 | ||||
-rw-r--r-- | low-can-binding/can/message/message.hpp | 12 |
6 files changed, 181 insertions, 47 deletions
diff --git a/low-can-binding/can/message/can-message.cpp b/low-can-binding/can/message/can-message.cpp index b012bbe5..945c0ba7 100644 --- a/low-can-binding/can/message/can-message.cpp +++ b/low-can-binding/can/message/can-message.cpp @@ -28,22 +28,20 @@ /// can_message_t::can_message_t() : message_t(), - maxdlen_{0}, id_{0}, rtr_flag_{false}, flags_{0} {} -can_message_t::can_message_t(uint8_t maxdlen, +can_message_t::can_message_t(uint32_t maxdlen, uint32_t id, - uint8_t length, + uint32_t length, message_format_t format, bool rtr_flag, - uint8_t flags, + uint32_t flags, std::vector<uint8_t>& data, uint64_t timestamp) - : message_t(length, format, data, timestamp), - maxdlen_{maxdlen}, + : message_t(maxdlen, length, format, data, timestamp), id_{id}, rtr_flag_{rtr_flag}, flags_{flags} @@ -86,7 +84,8 @@ bool can_message_t::is_correct_to_send() /// @return A can_message_t object fully initialized with canfd_frame values. std::shared_ptr<can_message_t> can_message_t::convert_from_frame(const struct canfd_frame& frame, size_t nbytes, uint64_t timestamp) { - uint8_t maxdlen = 0, length = 0, flags = 0; + uint32_t maxdlen = 0, length = 0; + uint8_t flags = 0; uint32_t id; message_format_t format; bool rtr_flag; @@ -164,6 +163,47 @@ std::shared_ptr<can_message_t> can_message_t::convert_from_frame(const struct ca return std::make_shared<can_message_t>(can_message_t(maxdlen, id, length, format, rtr_flag, flags, data, timestamp)); } +/// @brief Take all initialized class members and build a +/// 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 = (uint8_t) get_length(); + ::memcpy(frame.data, get_data(), length_); + } + else + AFB_ERROR("can_message_t not correctly initialized to be sent"); + + return frame; +} + +/// @brief Take all initialized class members and build a +/// 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 = (uint8_t) get_length(); + ::memcpy(frame.data, get_data(), length_); + } + else + AFB_ERROR("can_message_t not correctly initialized to be sent"); + + return frame; +} bool can_message_t::is_set() { @@ -192,3 +232,7 @@ void can_message_t::set_bcm_msg(struct bcm_msg bcm_msg) bcm_msg_ = bcm_msg; } +uint32_t can_message_t::get_flags() +{ + return flags_; +}
\ No newline at end of file diff --git a/low-can-binding/can/message/can-message.hpp b/low-can-binding/can/message/can-message.hpp index df0d2a19..7625cc17 100644 --- a/low-can-binding/can/message/can-message.hpp +++ b/low-can-binding/can/message/can-message.hpp @@ -26,24 +26,26 @@ /// buffers. It is a wrapper of a can_frame struct with some sugar around it for binding purposes. class can_message_t : public 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. */ 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.*/ + uint32_t flags_; ///< flags_ - flags of a CAN FD frame. Needed if we catch FD frames.*/ struct bcm_msg bcm_msg_; public: can_message_t(); - can_message_t(uint8_t maxdlen, uint32_t id, uint8_t length, message_format_t format, bool rtr_flag_, uint8_t flags, std::vector<uint8_t>& data, uint64_t timestamp); + can_message_t(uint32_t maxdlen, uint32_t id, uint32_t length, message_format_t format, bool rtr_flag_, uint32_t flags, std::vector<uint8_t>& data, uint64_t timestamp); uint32_t get_id() const; static std::shared_ptr<can_message_t> convert_from_frame(const canfd_frame& frame, size_t nbytes, uint64_t timestamp); + struct canfd_frame convert_to_canfd_frame(); + struct can_frame convert_to_can_frame(); + bool is_correct_to_send(); bool is_set(); struct bcm_msg get_bcm_msg(); void set_bcm_msg(struct bcm_msg bcm_msg); std::string get_debug_message(); - + uint32_t get_flags(); }; diff --git a/low-can-binding/can/message/j1939-message.cpp b/low-can-binding/can/message/j1939-message.cpp index dad8e7f1..08fc1302 100644 --- a/low-can-binding/can/message/j1939-message.cpp +++ b/low-can-binding/can/message/j1939-message.cpp @@ -16,14 +16,16 @@ */ #include <cstring> +#include <sstream> +#include <iomanip> +#include <net/if.h> #include "../../binding/low-can-hat.hpp" #include "j1939-message.hpp" -/// -/// @brief Class constructor -/// -/// j1939_message_t class constructor. -/// +/** + * @brief Construct a new j1939 message t::j1939 message t object + * + */ j1939_message_t::j1939_message_t(): message_t(), name_{0}, @@ -31,14 +33,27 @@ j1939_message_t::j1939_message_t(): addr_{0} {} -j1939_message_t::j1939_message_t(uint8_t length, +/** + * @brief Construct a new j1939 message t::j1939 message t object + * + * @param maxdlen The max length of the message + * @param length The length of the message + * @param format The format of the message + * @param data The vector data of the message + * @param timestamp The timetamp of the message + * @param name The name of the message + * @param pgn The PGN of the message + * @param addr The address of the message + */ +j1939_message_t::j1939_message_t(uint32_t maxdlen, + uint32_t length, message_format_t format, std::vector<uint8_t>& data, uint64_t timestamp, name_t name, pgn_t pgn, uint8_t addr): - message_t(length, format, data, timestamp), + message_t(maxdlen,length, format, data, timestamp), name_{name}, pgn_{pgn}, addr_{addr} @@ -71,6 +86,23 @@ uint8_t j1939_message_t::get_addr() const{ return addr_; } +/** + * @brief Convert hex data to string + * + * @param data An array of data + * @param length The length of the data + * @return std::string The string data + */ +std::string to_hex( uint8_t data[], const size_t length) +{ + std::stringstream stream; + stream << std::hex << std::setfill('0'); + for(int i = 0; i < length; i++) + { + stream << std::hex << ((int) data[i]); + } + return stream.str(); +} /// @brief Take a sockaddr_can struct and array of data to initialize class members /// @@ -84,9 +116,10 @@ uint8_t j1939_message_t::get_addr() const{ /// @return A j1939_message_t object fully initialized with sockaddr_can and data values. std::shared_ptr<j1939_message_t> j1939_message_t::convert_from_addr(struct sockaddr_can& addr, uint8_t (&data)[128],size_t nbytes, uint64_t timestamp) { - uint8_t length = 0; - message_format_t format; - std::vector<uint8_t> dataVector; + int i; + uint32_t length = 0; + message_format_t format; + std::vector<uint8_t> data_vector; if(nbytes > J1939_MAX_DLEN) { @@ -95,23 +128,27 @@ std::shared_ptr<j1939_message_t> j1939_message_t::convert_from_addr(struct socka } else { - AFB_DEBUG("Got a j1939 frame"); + //AFB_DEBUG("Got a j1939 frame"); format = message_format_t::J1939; } - length = (uint8_t) nbytes; - dataVector.reserve(length); - int i; - dataVector.clear(); + length = (uint32_t) nbytes; + data_vector.reserve(length); + + data_vector.clear(); + + std::string data_string; + data_string = to_hex(data,length); + for(i=0;i<length;i++) { - dataVector.push_back(data[i]); + data_vector.push_back(data[i]); }; - AFB_DEBUG("Found pgn: %X, format: %X, length: %X, data %02X%02X%02X%02X%02X%02X%02X%02X", - addr.can_addr.j1939.pgn, (uint8_t)format, length, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); + AFB_DEBUG("Found pgn: %X, format: %X, length: %X, data %s", + addr.can_addr.j1939.pgn, (uint8_t)format, length, data_string.c_str()); - return std::make_shared<j1939_message_t>(j1939_message_t(length, format, dataVector, timestamp,addr.can_addr.j1939.name,addr.can_addr.j1939.pgn,addr.can_addr.j1939.addr)); + return std::make_shared<j1939_message_t>(j1939_message_t(J1939_MAX_DLEN,length, format, data_vector, timestamp,addr.can_addr.j1939.name,addr.can_addr.j1939.pgn,addr.can_addr.j1939.addr)); } /// @brief Test if members pgn_ and length are set. @@ -143,7 +180,7 @@ std::string j1939_message_t::get_debug_message() /// uint32_t j1939_message_t::get_id() const { - AFB_WARNING("Prefer method get_pgn() for j1939 messages"); + AFB_DEBUG("Prefer method get_pgn() for j1939 messages"); return get_pgn(); } diff --git a/low-can-binding/can/message/j1939-message.hpp b/low-can-binding/can/message/j1939-message.hpp index 482f167d..aad62a1f 100644 --- a/low-can-binding/can/message/j1939-message.hpp +++ b/low-can-binding/can/message/j1939-message.hpp @@ -19,11 +19,12 @@ #include <linux/can/j1939.h> #include "message.hpp" -#include "../../utils/socketcan-j1939.hpp" + #define J1939_MAX_MULTIPACKETS 255 #define J1939_MAX_DLEN J1939_MAX_MULTIPACKETS * CAN_MAX_DLEN + class j1939_message_t : public message_t { private: @@ -54,12 +55,19 @@ class j1939_message_t : public message_t /* J1939 Address + 0-255 */ uint8_t addr_; + /** + * @brief The sockanme to send a message to + * an other ECU + */ + struct sockaddr_can sockname_; + public: j1939_message_t(); - j1939_message_t(uint8_t length, message_format_t format, std::vector<uint8_t>& data, uint64_t timestamp, name_t name, pgn_t pgn, uint8_t addr); + j1939_message_t(uint32_t maxdlen, uint32_t length, message_format_t format, std::vector<uint8_t>& data, uint64_t timestamp, name_t name, pgn_t pgn, uint8_t addr); uint64_t get_name() const; uint32_t get_pgn() const; uint8_t get_addr() const; diff --git a/low-can-binding/can/message/message.cpp b/low-can-binding/can/message/message.cpp index 2ae095cb..5384c021 100644 --- a/low-can-binding/can/message/message.cpp +++ b/low-can-binding/can/message/message.cpp @@ -21,29 +21,45 @@ #include "../../binding/low-can-hat.hpp" -/// -/// @brief Class constructor -/// -/// message_t class constructor. -/// +/** + * @brief Construct a new message t::message t object + * + */ message_t::message_t() - : length_{0}, + : maxdlen_{0}, + length_{0}, format_{message_format_t::INVALID}, timestamp_{0}, sub_id_{-1} {} -message_t::message_t(uint8_t length, +/** + * @brief Construct a new message t::message t object + * + * @param maxdlen The maxdlen of a message + * @param length The length of the message + * @param format The format of the message + * @param data The data vector of the message + * @param timestamp The timestamp of the message + */ +message_t::message_t(uint32_t maxdlen, + uint32_t length, message_format_t format, std::vector<uint8_t>& data, uint64_t timestamp) - : length_{length}, + : maxdlen_{maxdlen}, + length_{length}, format_{format}, data_{data}, timestamp_{timestamp}, sub_id_{-1} {} +/** + * @brief Return the sub_id of the message + * + * @return int The sub_id of the message + */ int message_t::get_sub_id() const { return sub_id_; @@ -75,21 +91,46 @@ const std::vector<uint8_t> message_t::get_data_vector() const /// /// @return length_ class member /// -uint8_t message_t::get_length() const +uint32_t message_t::get_length() const { return length_; } +/** + * @brief Set data vector of the message + * + * @param data A vector of data + */ +void message_t::set_data(std::vector<uint8_t> &data) +{ + data_ = data; +} + +/** + * @brief Set sub_id of the message + * + * @param sub_id The sub_id to set + */ void message_t::set_sub_id(int sub_id) { sub_id_ = sub_id; } +/** + * @brief Return the timestamp of the message + * + * @return uint64_t The timestamp + */ uint64_t message_t::get_timestamp() const { return timestamp_; } +/** + * @brief Return the format of the message + * + * @return message_format_t The message format + */ message_format_t message_t::get_msg_format() { return format_; diff --git a/low-can-binding/can/message/message.hpp b/low-can-binding/can/message/message.hpp index e62b6c6b..5be1ff18 100644 --- a/low-can-binding/can/message/message.hpp +++ b/low-can-binding/can/message/message.hpp @@ -57,30 +57,32 @@ enum class message_format_t { /// buffers. It is a wrapper of a can_frame struct with some sugar around it for binding purposes. class message_t { protected: - uint8_t length_; ///< length_ - the length of the data array (max 8). */ + uint32_t maxdlen_; ///< maxdlen_ - Max data length deduce from number of bytes read from the socket.*/ + uint32_t length_; ///< length_ - the length of the data array. */ message_format_t format_; ///< format_ - the format of the message's ID.*/ 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: message_t(); - message_t(uint8_t length, message_format_t format, std::vector<uint8_t>& data, uint64_t timestamp); + message_t(uint32_t maxdlen, uint32_t length, message_format_t format, std::vector<uint8_t>& data, uint64_t timestamp); + virtual ~message_t() = default; int get_sub_id() const; const uint8_t* get_data() const; const std::vector<uint8_t> get_data_vector() const; - uint8_t get_length() const; + uint32_t get_length() const; uint64_t get_timestamp() const; + void set_data(std::vector<uint8_t> &data); void set_sub_id(int sub_id); void set_timestamp(uint64_t timestamp); message_format_t get_msg_format(); virtual bool is_set() = 0; virtual std::string get_debug_message() = 0; virtual uint32_t get_id() const = 0; - virtual struct bcm_msg get_bcm_msg() = 0; - virtual void set_bcm_msg(struct bcm_msg bcm_msg) = 0; }; |