Update flag FRAME_LAYOUT_IS_BIGENDIAN to BYTE_FRAME_IS_BIG_ENDIAN
[apps/agl-service-can-low-level.git] / low-can-binding / can / can-decoder.cpp
index 4a3f87f..160a22b 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include "can-decoder.hpp"
+#include <climits>
 
 #include "canutil/read.h"
 #include "../utils/openxc-utils.hpp"
@@ -41,9 +42,9 @@ int decoder_t::handle_sign(const signal_t& signal, std::vector<uint8_t>& data_si
        if(signal.get_sign() == sign_t::UNSIGNED)
                return 1;
        else if(signal.get_sign() == sign_t::SIGN_BIT_EXTERN) {
-               end_bit = signal.get_bit_sign_position()%8;
+               end_bit = signal.get_bit_sign_position() % CHAR_BIT;
                mask = static_cast<uint8_t>((1 << (end_bit + 1)) - 1);
-               data_byte = can_data[signal.get_bit_sign_position()/8] & mask;
+               data_byte = can_data[signal.get_bit_sign_position() / CHAR_BIT] & mask;
        }
        else {
                end_bit = new_end_bit;
@@ -64,11 +65,9 @@ int decoder_t::handle_sign(const signal_t& signal, std::vector<uint8_t>& data_si
                        case sign_t::TWOS_COMPLEMENT:
                                //complement only until end_bit
                                data_signal[0] = ((data_signal[0] ^ mask) & mask);
-                               if(data_signal.size() > 1) {
-                                       for(int i=1; i < data_signal.size(); i++) {
+                               if(data_signal.size() > 1)
+                                       for(int i=1; i < data_signal.size(); i++)
                                                data_signal[i] = data_signal[i] ^ 0xFF;
-                                       }
-                               }
                                if(signal.get_sign() == sign_t::TWOS_COMPLEMENT)
                                        data_signal[data_signal.size() - 1] = static_cast<uint8_t>(data_signal[data_signal.size() - 1] + 1);
                                break;
@@ -94,30 +93,35 @@ int decoder_t::handle_sign(const signal_t& signal, std::vector<uint8_t>& data_si
 ///
 float decoder_t::parse_signal_bitfield(signal_t& signal, std::shared_ptr<message_t> message)
 {
-       const std::vector<uint8_t> data = message->get_data_vector();
+       int sign;
+       std::vector<uint8_t> data;
        std::vector<uint8_t> data_signal;
        uint8_t bit_size = (uint8_t) signal.get_bit_size();
        uint32_t bit_position = signal.get_bit_position();
 
-       if(signal.get_message()->frame_layout_is_bigendian())
-       {
-               bit_position = converter_t::bit_position_swap(message->get_length(),
-                                                             signal.get_bit_position(),
-                                                             signal.get_bit_size());
-               message->frame_swap();
-       }
-
        int new_start_byte = 0;
        int new_end_byte = 0;
        uint8_t new_start_bit = 0;
        uint8_t new_end_bit = 0;
 
+       if(signal.get_message()->get_flags() & CONTINENTAL_BIT_POSITION)
+               bit_position = converter_t::continental_bit_position_mess(message->get_length(),
+                                                             signal.get_bit_position(),
+                                                             bit_size);
+       if(signal.get_message()->get_flags() & BIT_POSITION_REVERSED)
+               bit_position = converter_t::bit_position_swap(message->get_length(),
+                                                             signal.get_bit_position(),
+                                                             bit_size);
+       if(signal.get_message()->get_flags() & BYTE_FRAME_IS_BIG_ENDIAN)
+               message->frame_swap();
+
+       data = message->get_data_vector();
        converter_t::signal_to_bits_bytes(bit_position, bit_size, new_start_byte, new_end_byte, new_start_bit, new_end_bit);
 
        for(int i=new_start_byte;i<=new_end_byte;i++)
                data_signal.push_back(data[i]);
 
-       int sign = decoder_t::handle_sign(signal, data_signal, new_end_bit, data);
+       sign = handle_sign(signal, data_signal, new_end_bit, data);
 
        if(data_signal.size() > 65535)
                AFB_ERROR("Too long data signal %s", signal.get_name().c_str());
@@ -150,7 +154,7 @@ openxc_DynamicField decoder_t::decode_bytes(signal_t& signal, std::shared_ptr<me
        uint32_t bit_size = signal.get_bit_size();
 
        std::vector<uint8_t> new_data = std::vector<uint8_t>();
-       new_data.reserve((bit_size / 8) + 1);
+       new_data.reserve((bit_size / CHAR_BIT) + 1);
 
        int new_start_byte = 0;
        int new_end_byte = 0;
@@ -189,6 +193,60 @@ openxc_DynamicField decoder_t::decode_bytes(signal_t& signal, std::shared_ptr<me
        return decoded_value;
 }
 
+
+/// @brief Decode and return string bytes (hex) for a CAN signal's.
+///
+/// This is an implementation of the Signal type signature, and can be
+/// used directly in the signal_t.decoder field.
+///
+/// @param[in] signal  - The details of the signal.
+/// @param[in] message - The message with data to decode.
+/// @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 of bytes (hex)
+///
+openxc_DynamicField decoder_t::decode_ascii(signal_t& signal, std::shared_ptr<message_t> message, bool* send)
+{
+       std::string ret_s = "";
+       openxc_DynamicField openxc_bytes = decode_bytes(signal,message,send);
+       if(!openxc_bytes.has_bytes_value)
+               AFB_ERROR("Error no bytes value to translate to ascii");
+       ret_s = converter_t::to_ascii(openxc_bytes.bytes_value,openxc_bytes.length_array);
+       openxc_DynamicField ret = build_DynamicField(ret_s);
+       return ret;
+}
+
+//edit
+openxc_DynamicField decoder_t::decode_date(signal_t& signal, std::shared_ptr<message_t> message, bool* send)
+{
+       float value = decoder_t::parse_signal_bitfield(signal, message);
+       AFB_DEBUG("Decoded message from parse_signal_bitfield: %f", value);
+       openxc_DynamicField decoded_value = build_DynamicField(value);
+
+       // 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);
+
+       return decoded_value;
+}
+
+//edit
+openxc_DynamicField decoder_t::decode_time(signal_t& signal, std::shared_ptr<message_t> message, bool* send)
+{
+       float value = decoder_t::parse_signal_bitfield(signal, message);
+       AFB_DEBUG("Decoded message from parse_signal_bitfield: %f", value);
+       openxc_DynamicField decoded_value = build_DynamicField(value);
+
+       // Don't send if they is no changes
+       *send = (signal.get_last_value() == value && !signal.get_send_same()) || !*send ? false : true;
+       signal.set_last_value(value);
+
+       return decoded_value;
+}
+
+
 /// @brief Wraps a raw CAN signal value in a DynamicField without modification.
 ///
 /// This is an implementation of the Signal type signature, and can be
@@ -211,9 +269,7 @@ openxc_DynamicField decoder_t::decode_noop(signal_t& signal, std::shared_ptr<mes
 
        // 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);
 
        return decoded_value;
@@ -302,9 +358,7 @@ openxc_DynamicField decoder_t::decode_state(signal_t& signal, std::shared_ptr<me
 
        // 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);