diff options
author | 2019-11-07 10:06:25 +0100 | |
---|---|---|
committer | 2019-11-07 10:06:25 +0100 | |
commit | 5912e67b3fe1366089102d1860c9f8ae01f8aec4 (patch) | |
tree | a95089c08af19a37cb6bfa391f8b8816187b6800 /low-can-binding | |
parent | 33cc8f946c04532d395a3929ccb06938014b0714 (diff) |
write: 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
Signed-off-by: Arthur Guyader <arthur.guyader@iot.bzh>
Change-Id: Iadca13a927ff83f713f39da441c88356695a1285
Diffstat (limited to 'low-can-binding')
-rw-r--r-- | low-can-binding/binding/low-can-cb.cpp | 3 | ||||
-rw-r--r-- | low-can-binding/binding/low-can-subscription.cpp | 4 | ||||
-rw-r--r-- | low-can-binding/can/can-encoder.cpp | 112 | ||||
-rw-r--r-- | low-can-binding/can/can-encoder.hpp | 5 | ||||
-rw-r--r-- | low-can-binding/can/message/can-message.hpp | 4 | ||||
-rw-r--r-- | low-can-binding/can/message/j1939-message.cpp | 19 | ||||
-rw-r--r-- | low-can-binding/can/message/j1939-message.hpp | 2 | ||||
-rw-r--r-- | low-can-binding/can/message/message.cpp | 2 | ||||
-rw-r--r-- | low-can-binding/utils/socketcan-isotp.hpp | 2 | ||||
-rw-r--r-- | low-can-binding/utils/socketcan.hpp | 11 |
10 files changed, 153 insertions, 11 deletions
diff --git a/low-can-binding/binding/low-can-cb.cpp b/low-can-binding/binding/low-can-cb.cpp index 1c01738f..67386810 100644 --- a/low-can-binding/binding/low-can-cb.cpp +++ b/low-can-binding/binding/low-can-cb.cpp @@ -716,7 +716,9 @@ static void write_signal(afb_req_t request, const std::string& name, json_object if(! send_message(message, sig->get_message()->get_bus_device_name(), flags, event_filter, sig) && send) afb_req_success(request, nullptr, "Message correctly sent"); + } else + { afb_req_fail(request, "Error", "Sending the message. See the log for more details."); if(sig->get_message()->is_j1939()) @@ -867,7 +869,6 @@ void list(afb_req_t request) afb_req_success(request, ans, NULL); else afb_req_fail(request, "error", NULL); - } /// @brief Initialize the binding. diff --git a/low-can-binding/binding/low-can-subscription.cpp b/low-can-binding/binding/low-can-subscription.cpp index 8b5f302e..8c314af7 100644 --- a/low-can-binding/binding/low-can-subscription.cpp +++ b/low-can-binding/binding/low-can-subscription.cpp @@ -738,7 +738,9 @@ int low_can_subscription_t::tx_send(low_can_subscription_t &subscription, messag } if(! subscription.socket_.get()) - return -1; + { + return -1; + } return 0; } diff --git a/low-can-binding/can/can-encoder.cpp b/low-can-binding/can/can-encoder.cpp index 94db19b0..627cec3e 100644 --- a/low-can-binding/can/can-encoder.cpp +++ b/low-can-binding/can/can-encoder.cpp @@ -204,6 +204,118 @@ message_t* encoder_t::build_message(const std::shared_ptr<signal_t>& signal, uin } } + +/** + * @brief Allows to build a single frame message with correct data to be send + * + * @param signal The CAN signal to write, including the bit position and bit size. + * @param value The encoded integer value to write in the CAN signal. + * @param message A single frame message to complete + * @return message_t* The message that is generated + */ +message_t* encoder_t::build_one_frame_message(const std::shared_ptr<signal_t>& signal, uint64_t value, message_t *message) +{ + signal->set_last_value((float)value); + uint8_t data_tab[message->get_length()]; + std::vector<uint8_t> data; + + for(const auto& sig: signal->get_message()->get_signals()) + { + float last_value = sig->get_last_value(); + bitfield_encode_float(last_value, + sig->get_bit_position(), + sig->get_bit_size(), + sig->get_factor(), + sig->get_offset(), + data_tab, + (uint8_t)message->get_length()); + } + + for (size_t i = 0; i < (uint8_t) message->get_length(); i++) + { + data.push_back(data_tab[i]); + } + + message->set_data(data); + return message; +} + +/** + * @brief Allows to build a multi frame message with correct data to be send + * + * @param signal The CAN signal to write, including the bit position and bit size. + * @param value The encoded integer value to write in the CAN signal. + * @param message A multi frame message to complete + * @return message_t* The message that is generated + */ +message_t* encoder_t::build_multi_frame_message(const std::shared_ptr<signal_t>& signal, uint64_t value, message_t *message) +{ + signal->set_last_value((float)value); + std::vector<uint8_t> data; + + uint32_t msgs_len = signal->get_message()->get_length(); // multi frame - number of bytes + int number_of_frame = (int) msgs_len / 8; + + uint8_t data_tab[number_of_frame][8] = {0}; + + for(const auto& sig: signal->get_message()->get_signals()) + { + + int frame_position = (int) sig->get_bit_position() / 64; + float last_value = sig->get_last_value(); + uint8_t bit_position = sig->get_bit_position() - ((uint8_t)(64 * frame_position)); + + bitfield_encode_float(last_value, + bit_position, + sig->get_bit_size(), + sig->get_factor(), + sig->get_offset(), + data_tab[frame_position], + 8); + } + + for (size_t i = 0; i < number_of_frame; i++) + { + for(size_t j = 0; j < 8 ; j++) + { + data.push_back(data_tab[i][j]); + } + } + + message->set_data(data); + return message; +} + +/** + * @brief Allows to build a message_t with correct data to be send + * + * @param signal The CAN signal to write, including the bit position and bit size. + * @param value The encoded integer value to write in the CAN signal. + * @return message_t* The message that is generated + */ +message_t* encoder_t::build_message(const std::shared_ptr<signal_t>& signal, uint64_t value) +{ + message_t *message; + std::vector<uint8_t> data; + if(signal->get_message()->is_fd()) + { + message = new can_message_t(CANFD_MAX_DLEN,signal->get_message()->get_id(),CANFD_MAX_DLEN,signal->get_message()->get_format(),false,0,data,0); + return build_one_frame_message(signal,value,message); + } +#ifdef USE_FEATURE_J1939 + else if(signal->get_message()->is_j1939()) + { + message = new j1939_message_t(J1939_MAX_DLEN,signal->get_message()->get_length(),signal->get_message()->get_format(),data,0,J1939_NO_NAME,signal->get_message()->get_id(),J1939_NO_ADDR); + return build_multi_frame_message(signal,value,message); + } +#endif + else + { + message = new can_message_t(CAN_MAX_DLEN,signal->get_message()->get_id(),CAN_MAX_DLEN,signal->get_message()->get_format(),false,0,data,0); + return build_one_frame_message(signal,value,message); + } +} + /// @brief Encode a boolean into an integer, fit for a CAN signal bitfield. /// /// This is a shortcut for encodeDynamicField(CanSignal*, openxc_DynamicField*, diff --git a/low-can-binding/can/can-encoder.hpp b/low-can-binding/can/can-encoder.hpp index d4505f04..9989d0cd 100644 --- a/low-can-binding/can/can-encoder.hpp +++ b/low-can-binding/can/can-encoder.hpp @@ -30,10 +30,13 @@ class encoder_t public: static message_t* build_message(const std::shared_ptr<signal_t>& signal, uint64_t value, bool factor=true, bool offset=true); static message_t* build_frame(const std::shared_ptr<signal_t>& signal, uint64_t value, message_t *message, bool factor=true, bool offset=true); + static message_t* build_message(const std::shared_ptr<signal_t>& signal, uint64_t value); + static message_t* build_one_frame_message(const std::shared_ptr<signal_t>& signal, uint64_t value, message_t *message); + static message_t* build_multi_frame_message(const std::shared_ptr<signal_t>& signal, uint64_t value, message_t *message); static uint64_t encode_state(const signal_t& signal, const std::string& value, bool* send); static uint64_t encode_boolean(const signal_t& signal, bool value, bool* send); static uint64_t encode_number(const signal_t& signal, float value, bool* send); static void encode_data(std::shared_ptr<signal_t> sig, std::vector<uint8_t> &data, bool filter=false, bool factor=true, bool offset=true); static uint64_t encode_DynamicField(signal_t& signal, const openxc_DynamicField& field, bool* send); -};
\ 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 acc3bfc1..8bc9aabe 100644 --- a/low-can-binding/can/message/can-message.hpp +++ b/low-can-binding/can/message/can-message.hpp @@ -53,10 +53,6 @@ class can_message_t : public message_t { 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 std::vector<canfd_frame> convert_to_canfd_frame_vector(); - 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); diff --git a/low-can-binding/can/message/j1939-message.cpp b/low-can-binding/can/message/j1939-message.cpp index 432a1393..31e08fc9 100644 --- a/low-can-binding/can/message/j1939-message.cpp +++ b/low-can-binding/can/message/j1939-message.cpp @@ -83,6 +83,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 /// @@ -223,4 +240,4 @@ void j1939_message_t::set_sockname(pgn_t pgn, name_t name, uint8_t addr) { sockname_.can_addr.j1939.pgn = pgn; } -}
\ No newline at end of file +} diff --git a/low-can-binding/can/message/j1939-message.hpp b/low-can-binding/can/message/j1939-message.hpp index a513e94e..850455c4 100644 --- a/low-can-binding/can/message/j1939-message.hpp +++ b/low-can-binding/can/message/j1939-message.hpp @@ -79,4 +79,4 @@ class j1939_message_t : public message_t struct sockaddr_can get_sockname(); void set_sockname(struct sockaddr_can sockname); void set_sockname(pgn_t pgn, name_t name, uint8_t addr); -};
\ No newline at end of file +}; diff --git a/low-can-binding/can/message/message.cpp b/low-can-binding/can/message/message.cpp index 2496b672..ef468c65 100644 --- a/low-can-binding/can/message/message.cpp +++ b/low-can-binding/can/message/message.cpp @@ -188,4 +188,4 @@ void message_t::set_maxdlen(uint32_t maxdlen) void message_t::set_length(uint32_t length) { length_ = length; -}
\ No newline at end of file +} diff --git a/low-can-binding/utils/socketcan-isotp.hpp b/low-can-binding/utils/socketcan-isotp.hpp index 86ed9faf..dfaf0089 100644 --- a/low-can-binding/utils/socketcan-isotp.hpp +++ b/low-can-binding/utils/socketcan-isotp.hpp @@ -36,4 +36,4 @@ namespace utils virtual int write_message(message_t& obj); int define_tx_address(std::string device_name, canid_t rx_id, canid_t tx_id); }; -}
\ No newline at end of file +} diff --git a/low-can-binding/utils/socketcan.hpp b/low-can-binding/utils/socketcan.hpp index 7b2501af..b08eeff4 100644 --- a/low-can-binding/utils/socketcan.hpp +++ b/low-can-binding/utils/socketcan.hpp @@ -30,6 +30,17 @@ #define INVALID_SOCKET -1 #define NO_CAN_ID 0xFFFFFFFFU +/** + * @enum socket_type + * @brief The type of socket + */ +enum class socket_type { + BCM, ///< BCM - Socket BCM + J1939_ADDR_CLAIM, ///< J1939 - Socket J1939 + J1939, ///< J1939 - Socket J1939 + INVALID +}; + namespace utils { |