aboutsummaryrefslogtreecommitdiffstats
path: root/low-can-binding
diff options
context:
space:
mode:
authorArthur Guyader <arthur.guyader@iot.bzh>2019-11-07 10:06:25 +0100
committerRomain Forlot <romain.forlot@iot.bzh>2019-11-07 10:06:25 +0100
commit5912e67b3fe1366089102d1860c9f8ae01f8aec4 (patch)
treea95089c08af19a37cb6bfa391f8b8816187b6800 /low-can-binding
parent33cc8f946c04532d395a3929ccb06938014b0714 (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.cpp3
-rw-r--r--low-can-binding/binding/low-can-subscription.cpp4
-rw-r--r--low-can-binding/can/can-encoder.cpp112
-rw-r--r--low-can-binding/can/can-encoder.hpp5
-rw-r--r--low-can-binding/can/message/can-message.hpp4
-rw-r--r--low-can-binding/can/message/j1939-message.cpp19
-rw-r--r--low-can-binding/can/message/j1939-message.hpp2
-rw-r--r--low-can-binding/can/message/message.cpp2
-rw-r--r--low-can-binding/utils/socketcan-isotp.hpp2
-rw-r--r--low-can-binding/utils/socketcan.hpp11
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
{