diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/can-decoder.cpp | 44 | ||||
-rw-r--r-- | src/can-decoder.hpp (renamed from src/can-decoder.h) | 28 | ||||
-rw-r--r-- | src/can-signals.hpp (renamed from src/can-signals.h) | 0 | ||||
-rw-r--r-- | src/can-utils.cpp | 83 | ||||
-rw-r--r-- | src/can-utils.hpp (renamed from src/can-utils.h) | 89 | ||||
-rw-r--r-- | src/can_decode_message.cpp | 125 | ||||
-rw-r--r-- | src/can_reader.cpp | 2 | ||||
-rw-r--r-- | src/low-can-binding.cpp | 2 | ||||
-rw-r--r-- | src/obd2.hpp (renamed from src/obd2.h) | 0 | ||||
-rw-r--r-- | src/timer.hpp (renamed from src/timer.h) | 0 |
10 files changed, 200 insertions, 173 deletions
diff --git a/src/can-decoder.cpp b/src/can-decoder.cpp index 000db2a..0c8c803 100644 --- a/src/can-decoder.cpp +++ b/src/can-decoder.cpp @@ -15,23 +15,20 @@ * limitations under the License. */ -Decoder::Decoder +decoder_t::decoder_t() + : decoded_value{false, openxc_DynamicField_Type_STRING, false, "", false, 0, false, false} { - decoded_value = { .has_type = false, - .has_numeric_value = false, - .has_boolean_value = false, - .has_string_value = false }; } -float Decoder::parseSignalBitfield(CanSignal* signal, const CanMessage* message) +float decoder_t::parseSignalBitfield(const CanSignal& signal, const CanMessage& message) { return bitfield_parse_float(message->data, CAN_MESSAGE_SIZE, signal->bitPosition, signal->bitSize, signal->factor, signal->offset); } -openxc_DynamicField Decoder::noopDecoder(CanSignal* signal, - CanSignal* signals, int signalCount, float value, bool* send) +openxc_DynamicField decoder_t::noopDecoder(const CanSignal& signal, + const CanSignal& signals, float value, bool* send) { decoded_value = { .has_type = true, .type = openxc_DynamicField_Type_NUM, @@ -40,8 +37,8 @@ openxc_DynamicField Decoder::noopDecoder(CanSignal* signal, return decoded_value; } -openxc_DynamicField Decoder::booleanDecoder(CanSignal* signal, - CanSignal* signals, int signalCount, float value, bool* send) +openxc_DynamicField decoder_t::booleanDecoder(const CanSignal& signal, + const CanSignal& signals, float value, bool* send) { decoded_value = { .has_type = true, .type = openxc_DynamicField_Type_BOOL, @@ -50,16 +47,18 @@ openxc_DynamicField Decoder::booleanDecoder(CanSignal* signal, return decoded_value; } -openxc_DynamicField Decoder::ignoreDecoder(CanSignal* signal, - CanSignal* signals, int signalCount, float value, bool* send) +openxc_DynamicField decoder_t::ignoreDecoder(const CanSignal& signal, + const CanSignal& signals, float value, bool* send) { - *send = false; + if(send) + *send = false; + openxc_DynamicField decoded_value = {0}; return decoded_value; } -openxc_DynamicField Decoder::stateDecoder(CanSignal* signal, - CanSignal* signals, int signalCount, float value, bool* send) +openxc_DynamicField decoder_t::stateDecoder(const CanSignal& signal, + const CanSignal& signals, float value, bool* send) { openxc_DynamicField decoded_value = {0}; decoded_value.has_type = true; @@ -68,26 +67,25 @@ openxc_DynamicField Decoder::stateDecoder(CanSignal* signal, const CanSignalState* signalState = lookupSignalState(value, signal); if(signalState != NULL) { - strcpy(decoded_value.string_value, signalState->name); + ::strcpy(decoded_value.string_value, signalState->name); } else { *send = false; } return decoded_value; } -openxc_DynamicField Decoder::decodeSignal(CanSignal* signal, - float value, CanSignal* signals, int signalCount, bool* send) +openxc_DynamicField decoder_t::decodeSignal(const CanSignal& signal, + float value, const CanSignal& signals, bool* send) { SignalDecoder decoder = signal->decoder == NULL ? noopDecoder : signal->decoder; openxc_DynamicField decoded_value = decoder(signal, signals, - signalCount, value, send); + value, send); return decoded_value; } -openxc_DynamicField Decoder::decodeSignal(CanSignal* signal, - const CanMessage* message, CanSignal* signals, int signalCount, - bool* send) { +openxc_DynamicField decoder_t::decodeSignal(const CanSignal& signal, + const CanMessage& message, const CanSignal& signals, bool* send) { float value = parseSignalBitfield(signal, message); - return decodeSignal(signal, value, signals, signalCount, send); + return decodeSignal(signal, value, signals, send); }
\ No newline at end of file diff --git a/src/can-decoder.h b/src/can-decoder.hpp index 3754bae..b6234b5 100644 --- a/src/can-decoder.h +++ b/src/can-decoder.hpp @@ -34,7 +34,7 @@ class decoder_t * Returns the raw value of the signal parsed as a bitfield from the given byte * array. */ - float parseSignalBitfield(CanSignal* signal, const CanMessage* message); + float parseSignalBitfield(const CanSignal& signal, const CanMessage& message); /* Public: Find and return the corresponding string state for a CAN signal's * raw integer value. @@ -53,8 +53,8 @@ class decoder_t * the signal. If an equivalent isn't found, send is sent to false and the * return value is undefined. */ - openxc_DynamicField stateDecoder(CanSignal* signal, CanSignal* signals, - int signalCount, float value, bool* send); + openxc_DynamicField stateDecoder(const CanSignal& signal, const CanSignal& signals, + float value, bool* send); /* Public: Coerces a numerical value to a boolean. * @@ -72,8 +72,8 @@ class decoder_t * is 0.0, otherwise true. The 'send' argument will not be modified as this * decoder always succeeds. */ - openxc_DynamicField booleanDecoder(CanSignal* signal, CanSignal* signals, - int signalCount, float value, bool* send); + openxc_DynamicField booleanDecoder(const CanSignal& signal, const CanSignal& signals, + float value, bool* send); /* Public: Update the metadata for a signal and the newly received value. * @@ -91,8 +91,8 @@ class decoder_t * * The return value is undefined. */ - openxc_DynamicField ignoreDecoder(CanSignal* signal, CanSignal* signals, - int signalCount, float value, bool* send); + openxc_DynamicField ignoreDecoder(const CanSignal& signal, const CanSignal& signals, + float value, bool* send); /* Public: Wrap a raw CAN signal value in a DynamicField without modification. * @@ -110,8 +110,8 @@ class decoder_t * its numeric value. The 'send' argument will not be modified as this decoder * always succeeds. */ - openxc_DynamicField noopDecoder(CanSignal* signal, CanSignal* signals, - int signalCount, float value, bool* send); + openxc_DynamicField noopDecoder(const CanSignal& signal, const CanSignal& signals, + float value, bool* send); /* Public: Parse a signal from a CAN message and apply any required * transforations to get a human readable value. @@ -129,18 +129,18 @@ class decoder_t * 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 decodeSignal(CanSignal* signal, - const CanMessage* message, CanSignal* signals, int signalCount, + openxc_DynamicField decodeSignal(const CanSignal& signal, + const CanMessage& message, const CanSignal& signals, bool* send); /* Public: Decode a transformed, human readable value from an raw CAN signal * already parsed from a CAN message. * - * This is the same as decodeSignal(CanSignal*, CanMessage*, CanSignal*, int, + * This is the same as decodeSignal(const CanSignal&, CanMessage*, const CanSignal&, int, * bool*) 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. */ - openxc_DynamicField decodeSignal(CanSignal* signal, float value, - CanSignal* signals, int signalCount, bool* send); + openxc_DynamicField decodeSignal(const CanSignal& signal, float value, + const CanSignal& signals, bool* send); }
\ No newline at end of file diff --git a/src/can-signals.h b/src/can-signals.hpp index f34c743..f34c743 100644 --- a/src/can-signals.h +++ b/src/can-signals.hpp diff --git a/src/can-utils.cpp b/src/can-utils.cpp index e978cae..e41230b 100644 --- a/src/can-utils.cpp +++ b/src/can-utils.cpp @@ -23,12 +23,12 @@ * *********************************************************************************/ -can_bus_t::can_bus_t(afb_binding_interface *itf, const std:string &dev_name) - : interface{itf}, deviceName{dev_name} +can_bus_dev_t::can_bus_dev_t(afb_binding_interface *itf, const std:string &dev_name) + : interface{itf}, deviceName{dev_name} { } -int can_bus_t::open() +int can_bus_dev_t::open() { const int canfd_on = 1; struct ifreq ifr; @@ -81,14 +81,14 @@ int can_bus_t::open() return -1; } -int can_bus_t::close() +int can_bus_dev_t::close() { ::close(can_socket_); can_socket_ = -1; } -canfd_frame can_bus_t::can_read() +canfd_frame can_bus_dev_t::read() { ssize_t nbytes; //int maxdlen; @@ -124,6 +124,19 @@ canfd_frame can_bus_t::can_read() return canfd_frame; } +/* + * Return is_running_ bool + */ +bool can_bus_dev_t::is_running() +{ + return is_running_; +} + +can_bus_t::can_bus_t(afb_binding_interface *itf, const std:string &dev_name) + : interface{itf} +{ +} + void can_bus_t::start_threads() { th_reading_ = std::thread(can_reader, interface, socket, can_message_q_); @@ -134,11 +147,33 @@ void can_bus_t::start_threads() } /* - * Return is_running_ bool + * Get a CanMessage from can_message_q and return it + * then point to the next CanMessage in queue. + * + * Return the next queue element or NULL if queue is empty. */ -bool can_bus_t::is_running() +can_message_t can_bus_dev_t::next_can_message() { - return is_running_; + if(! can_message_q_.empty()) + { + can_message_t can_msg = can_message_q_.front(); + can_message_q_.pop() + return &can_msg; + } + has_can_message_ = false; +} + +/** + * @return has_can_message_ bool + */ +bool can_bus_dev_t::has_can_message() const +{ + return has_can_message_; +} + +void can_bus_dev_t::push_new_can_message(const can_message_t& can_msg) +{ + can_message_q_.push(can_msg); } /* @@ -172,36 +207,6 @@ int can_bus_t::send_can_message(can_message_t &can_msg) } /* - * Get a CanMessage from can_message_q and return it - * then point to the next CanMessage in queue. - * - * Return the next queue element or NULL if queue is empty. - */ -can_message_t* can_bus_t::next_can_message() -{ - if(! can_message_q_.empty()) - { - can_message_t can_msg = can_message_q_.front(); - can_message_q_.pop() - return &can_msg; - } - has_can_message_ = false; -} - -/** - * @return has_can_message_ bool - */ -bool can_bus_t::has_can_message() const -{ - return has_can_message_; -} - -void can_bus_t::insert_new_can_message(can_message_t &can_msg) -{ - can_message_q_.push(can_msg); -} - -/* * Get a VehicleMessage from vehicle_message_q and return it * then point to the next VehicleMessage in queue. * @@ -219,7 +224,7 @@ openxc_VehicleMessage* can_bus_t::next_vehicle_message() has_vehicle_message_ = false; } -void can_bus_t::insert_new_vehicle_message(openxc_VehicleMessage *v_msg) +void can_bus_t::push_new_vehicle_message(const openxc_VehicleMessage& v_msg) { vehicle_message_q_.push(v_msg); has_vehicle_message_ = true; diff --git a/src/can-utils.h b/src/can-utils.hpp index 1676392..da5f81c 100644 --- a/src/can-utils.h +++ b/src/can-utils.hpp @@ -30,27 +30,6 @@ #define CAN_ACTIVE_TIMEOUT_S 30 -#define QUEUE_DECLARE(type, max_length) \ -static const int queue_##type##_max_length = max_length; \ -static const int queue_##type##_max_internal_length = max_length + 1; \ -typedef struct queue_##type##_s { \ - int head; \ - int tail; \ - type elements[max_length + 1]; \ -} queue_##type; \ -\ -bool queue_##type##_push(queue_##type* queue, type value); \ -\ -type queue_##type##_pop(queue_##type* queue); \ -\ -type queue_##type##_peek(queue_##type* queue); \ -void queue_##type##_init(queue_##type* queue); \ -int queue_##type##_length(queue_##type* queue); \ -int queue_##type##_available(queue_##type* queue); \ -bool queue_##type##_full(queue_##type* queue); \ -bool queue_##type##_empty(queue_##type* queue); \ -void queue_##type##_snapshot(queue_##type* queue, type* snapshot, int max); - /* Public: The type signature for a CAN signal decoder. * * A SignalDecoder transforms a raw floating point CAN signal into a number, @@ -69,57 +48,79 @@ void queue_##type##_snapshot(queue_##type* queue, type* snapshot, int max); typedef openxc_DynamicField (*SignalDecoder)(struct CanSignal* signal, CanSignal* signals, int signalCount, float value, bool* send); -/* Public: The type signature for a CAN signal encoder. +/** + * @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. * - * signal - The CAN signal to encode. - * value - The dynamic field to encode. - * send - An output parameter. If the encoding failed or the CAN signal should + * @params[signal] - The CAN signal to encode. + * @params[value] - The dynamic field to encode. + * @params[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)(struct CanSignal* signal, openxc_DynamicField* value, bool* send); -/* - * CanBus represent a can device definition gotten from configuraiton file +/** + * @brief Object representing a can device. Handle opening, closing and reading on the + * socket. This is the low level object to be use by can_bus_t. + * + * @params[*interface_] - afb_binding_interface to the binder. Used to log messages + * @params[device_name_] - name of the linux device handling the can bus. Generally vcan0, can0, etc. + * */ -class can_bus_t { +class can_bus_dev_t { private: - afb_binding_interface *interface_; - - /* Got from conf file */ - std::string device_name; + std::string device_name_; + int can_socket_; int can_socket_; bool is_fdmode_on_; struct sockaddr_can txAddress_; + bool has_can_message_; + std::queue <can_message_t> can_message_q_; + std::thread th_reading_; bool is_running_; + + public: + int open(); + int close(); + bool is_running(); + + can_message_t* next_can_message(); + void push_new_can_message(const can_message_t& can_msg); +} + + +/** + * @brief Object used to handle decoding and manage event queue to be pushed. + * + * @params[*interface_] - afb_binding_interface to the binder. Used to log messages + * @params[conf_file_ifstream_] - stream of configuration file used to initialize + * can_bus_dev_t objects. + */ +class can_bus_t { + private: + afb_binding_interface *interface_; + + std::vector<can_bus_dev_t> devices; + std::thread th_decoding_; std::thread th_pushing_; - std::queue <can_message_t> can_message_q_; + bool has_vehicle_message_; std::queue <openxc_VehicleMessage> vehicle_message_q_; public: - int open(); - int close(); - void start_threads(); - bool is_running(); int send_can_message(can_message_t can_msg); - can_message_t* next_can_message(); - void insert_new_can_message(can_message_t &can_msg); - bool has_can_message_; - - openxc_VehicleMessage* next_vehicle_message(); - void insert_new_vehicle_message(openxc_VehicleMessage *v_msg); - bool has_vehicle_message_; + openxc_VehicleMessage& next_vehicle_message(); + void push_new_vehicle_message(const openxc_VehicleMessage& v_msg); }; /* A compact representation of a single CAN message, meant to be used in in/out diff --git a/src/can_decode_message.cpp b/src/can_decode_message.cpp index 6bb6459..7e20f88 100644 --- a/src/can_decode_message.cpp +++ b/src/can_decode_message.cpp @@ -23,8 +23,8 @@ #include <afb/afb-binding.h> -#include "can-utils.h" -#include "can-decoder.h" +#include "can-utils.hpp" +#include "can-decoder.hpp" #include "openxc.pb.h" union DynamicField @@ -36,36 +36,35 @@ union DynamicField void can_decode_message(can_bus_t &can_bus) { - can_message_t *can_message; + can_message_t can_message; std:vector <CanSignal> signals; std:vector <CanSignal>::iterator signals_i; openxc_VehicleMessage vehicle_message; openxc_DynamicField search_key, ret; + bool send = true; decoder_t decoder(); - while(true) { if(can_message = can_bus.next_can_message()) { /* First we have to found which CanSignal is */ - DynamicField signal_id = (double)can_message.get_id(); - search_key = build_DynamicField(openxc_DynamicField_Type_NUM, signal_id) + search_key = build_DynamicField(openxc_DynamicField_Type::openxc_DynamicField_Type_NUM, (double)can_message.get_id()) - signals = find_signals(search_key); + signals = find_can_signals(search_key); /* Decoding the message ! Don't kill the messenger ! */ - for(signals_i=signals.begin(); signal_i != signals.end(); signals_i++) - { - subscribed_signals_i = subscribed_signals.find(signals_i); + for(const auto& sig : signals) + { + subscribed_signals_i = subscribed_signals.find(sig); if(subscribed_signals_i != subscribed_signals.end() && afb_event_is_valid(subscribed_signals_i->second)) { - ret = decoder.decodeSignal(&sig, can_message, SIGNALS, SIGNALS.size(), true); + ret = decoder.decodeSignal(sig, can_message, getSignals(), &send); - s_message = build_SimpleMessage(subscribed_signals_i->first->genericName, ret); + s_message = build_SimpleMessage(sig.genericName, ret); vehicle_message = build_VehicleMessage_with_SimpleMessage(openxc_DynamicField_Type::openxc_DynamicField_Type_NUM, s_message); vehicle_message_q.push(vehicle_message); @@ -79,69 +78,93 @@ void can_decode_message(can_bus_t &can_bus) * Build a specific VehicleMessage containing a SimpleMessage. */ openxc_VehicleMessage build_VehicleMessage_with_SimpleMessage(openxc_DynamicField_Type type, - openxc_SimpleMessage message) + const openxc_SimpleMessage& message) { struct timeb t_msec; long long int timestamp_msec; + + openxc_VehicleMessage v = {0}; + if(!ftime(&t_msec)) { timestamp_msec = ((long long int) t_msec.time) * 1000ll + (long long int) t_msec.millitm; - return openxc_VehicleMessage v = {.has_type = true, - .type = openxc_VehicleMessage_Type::openxc_VehicleMessage_Type_SIMPLE, - .has_simple_message = true, - .simple_message = message, - .has_timestamp = true, - .timestamp = timestamp_msec}; + 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_msec; + + return v; } - return openxc_VehicleMessage v = {.has_type = true, - .type = openxc_VehicleMessage_Type::openxc_VehicleMessage_Type_SIMPLE, - .has_simple_message = true, - .simple_message = message}; + v.has_type = true, + v.type = openxc_VehicleMessage_Type::openxc_VehicleMessage_Type_SIMPLE; + v.has_simple_message = true; + v.simple_message = message; + + return v; } /* * Build an openxc_SimpleMessage associating a name to an openxc_DynamicField */ -openxc_SimpleMessage build_SimpleMessage(std:string name, openxc_DynamicField value) +openxc_SimpleMessage build_SimpleMessage(const std::string& name, const openxc_DynamicField& value) { - return openxc_SimpleMessage s = {.has_name = true, - .name = name, - .has_value = true, - .value = value}; + + openxc_SimpleMessage s = {0}; + + s.has_name = true; + ::strncpy(s.name, name.c_str(), 100); + s.has_value = true; + s.value = value; + + return s; } - +/* + * Build an openxc_DynamicField depending what we pass as argument + */ +openxc_DynamicField build_DynamicField(const std::string& value) +{ + openxc_DynamicField d = {0} + d.has_type = true; + d.type = openxc_DynamicField_Type_STRING; + + d.has_string_value = true; + ::strncpy(d.string_value, value.c_tr(), 100); + + return d; } /* - * Build an openxc_DynamicField using its type and an union. - * Why do not use of union in first place anyway... + * Build an openxc_DynamicField depending what we pass as argument */ -openxc_DynamicField build_DynamicField(openxc_DynamicField_Type type, DynamicField field) +openxc_DynamicField build_DynamicField(double value) { - openxc_DynamicField d = {.has_type = true, - .type = type}; + openxc_DynamicField d = {0} + d.has_type = true; + d.type = openxc_DynamicField_Type_NUM; - switch(type) - { - case openxc_DynamicField_Type_BOOL: - d.has_boolean_value = true; - d.boolean_value = field; - break; - case openxc_DynamicField_Type_NUM: - d.has_numeric_value = true; - d.numeric_value = field; - break; - case openxc_DynamicField_Type_STRING: - d.has_string_value = true; - strcpy(d.string_value, field); - break; - default: - return nullptr; - } + d.has_numeric_value = true; + d.numeric_value = field; + + return d; +} +/* + * Build an openxc_DynamicField depending what we pass as argument + */ +openxc_DynamicField build_DynamicField(bool value) +{ + openxc_DynamicField d = {0} + d.has_type = true; + d.type = openxc_DynamicField_Type_BOOL; + + d.has_boolean_value = true; + d.boolean_value = field; + return d; }
\ No newline at end of file diff --git a/src/can_reader.cpp b/src/can_reader.cpp index aab47b6..a8c5cf6 100644 --- a/src/can_reader.cpp +++ b/src/can_reader.cpp @@ -30,6 +30,6 @@ void can_reader(can_bus_t &can_bus) while(can_bus.is_running()) { can_message.convert_from_canfd_frame(canbus.read()); - can_bus.insert_new_can_message(can_message); + can_bus.push_new_can_message(can_message); } }
\ No newline at end of file diff --git a/src/low-can-binding.cpp b/src/low-can-binding.cpp index d5c116f..b895adc 100644 --- a/src/low-can-binding.cpp +++ b/src/low-can-binding.cpp @@ -40,7 +40,7 @@ #include <afb/afb-binding.h> #include <afb/afb-service-itf.h> -#include "obd2.h" +#include "obd2.hpp" /* * Interface between the daemon and the binding diff --git a/src/obd2.h b/src/obd2.hpp index cd362c7..cd362c7 100644 --- a/src/obd2.h +++ b/src/obd2.hpp diff --git a/src/timer.h b/src/timer.hpp index 76eb51d..76eb51d 100644 --- a/src/timer.h +++ b/src/timer.hpp |