Some cleaning and comments
[apps/agl-service-can-low-level.git] / src / can-utils.hpp
1 /*
2  * Copyright (C) 2015, 2016 "IoT.bzh"
3  * Author "Romain Forlot" <romain.forlot@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #pragma once
19
20 #include <map>
21 #include <queue>
22 #include <vector>
23 #include <cstdio>
24 #include <string>
25 #include <thread>
26 #include <linux/can.h>
27
28 #include "timer.hpp"
29 #include "openxc.pb.h"
30
31 // TODO actual max is 32 but dropped to 24 for memory considerations
32 #define MAX_ACCEPTANCE_FILTERS 24
33 // TODO this takes up a ton of memory
34 #define MAX_DYNAMIC_MESSAGE_COUNT 12
35
36 #define CAN_MESSAGE_SIZE 8
37
38 #define CAN_ACTIVE_TIMEOUT_S 30
39
40 /**
41  * @brief The type signature for a CAN signal decoder.
42  *
43  * @desc A SignalDecoder transforms a raw floating point CAN signal into a number,
44  * string or boolean.
45  *
46  * @param[in] CanSignal signal - The CAN signal that we are decoding.
47  * @param[in] CanSignal signals - The list of all signals.
48  * @param[in] int signalCount - The length of the signals array.
49  * @param[in] float value - The CAN signal parsed from the message as a raw floating point
50  *      value.
51  * @param[out] bool send - An output parameter. If the decoding failed or the CAN signal should
52  *      not send for some other reason, this should be flipped to false.
53  *
54  * @return a decoded value in an openxc_DynamicField struct.
55  */
56 typedef openxc_DynamicField (*SignalDecoder)(struct CanSignal* signal,
57                 CanSignal* signals, int signalCount, float value, bool* send);
58
59 /**
60  * @brief: The type signature for a CAN signal encoder.
61  *
62  * @desc A SignalEncoder transforms a number, string or boolean into a raw floating
63  * point value that fits in the CAN signal.
64  *
65  * @params[signal] - The CAN signal to encode. 
66  * @params[value] - The dynamic field to encode.
67  * @params[send] - An output parameter. If the encoding failed or the CAN signal should
68  * not be encoded for some other reason, this will be flipped to false.
69  */
70 typedef uint64_t (*SignalEncoder)(struct CanSignal* signal,
71                 openxc_DynamicField* value, bool* send);
72
73 /**
74  * @brief The ID format for a CAN message.
75  *
76  * STANDARD - standard 11-bit CAN arbitration ID.
77  * EXTENDED - an extended frame, with a 29-bit arbitration ID.
78  */
79 enum CanMessageFormat {
80         STANDARD,
81         EXTENDED,
82 };
83 typedef enum CanMessageFormat CanMessageFormat;
84
85 /**
86  * @brief A compact representation of a single CAN message, meant to be used in in/out
87  * buffers.
88  *
89  * param[in] uint32_t id - The ID of the message.
90  * param[in] CanMessageFormat format - the format of the message's ID.
91  * param[in] uint8_t data  - The message's data field.
92  * @param[in] uint8_t length - the length of the data array (max 8).
93 *************************
94 * old CanMessage struct *
95 *************************
96 struct CanMessage {
97         uint32_t id;
98         CanMessageFormat format;
99         uint8_t data[CAN_MESSAGE_SIZE];
100         uint8_t length;
101 };
102 typedef struct CanMessage CanMessage;
103 */
104 class can_message_t {
105         private:
106                 const struct afb_binding_interface *interface_;
107                 uint32_t id_;
108                 CanMessageFormat format_;
109                 uint8_t data_[CAN_MESSAGE_SIZE];
110                 uint8_t length_;
111
112         public:
113                 uint32_t get_id() const;
114                 int get_format() const;
115                 uint8_t get_data() const;
116                 uint8_t get_lenght() const;
117
118                 void set_id(uint32_t id);
119                 void set_format(CanMessageFormat format);
120                 void set_data(uint8_t data);
121                 void set_lenght(uint8_t length);
122
123                 void convert_from_canfd_frame(canfd_frame frame);
124                 canfd_frame convert_to_canfd_frame();
125 };
126
127 /** 
128  * @brief Object representing a can device. Handle opening, closing and reading on the
129  * socket. This is the low level object to be use by can_bus_t.
130  *
131  * @params[in] std::string device_name_ - name of the linux device handling the can bus. Generally vcan0, can0, etc.
132  */
133 class can_bus_dev_t {
134         private:
135                 std::string device_name_;
136                 int can_socket_;
137                 bool is_fdmode_on_;
138                 struct sockaddr_can txAddress_;
139
140                 bool has_can_message_;
141                 std::queue <can_message_t> can_message_q_;
142
143                 std::thread th_reading_;
144                 bool is_running_;
145
146         public:
147                 can_bus_dev_t(const std::string& dev_name);
148
149                 int open();
150                 int close();
151                 bool is_running();
152                 
153                 can_message_t* next_can_message();
154                 void push_new_can_message(const can_message_t& can_msg);                
155                 bool has_can_message() const;
156 };
157
158 /** 
159  * @brief Object used to handle decoding and manage event queue to be pushed.
160  *
161  * @params[in] interface_ - afb_binding_interface pointer to the binder. Used to log messages
162  * @params[in] conf_file_ - configuration file handle used to initialize can_bus_dev_t objects.
163  */
164 class can_bus_t {
165         private:
166                 const struct afb_binding_interface *interface_;
167                 int conf_file_;
168                 
169                 std::thread th_decoding_;
170                 std::thread th_pushing_;
171
172                 bool has_vehicle_message_;
173                 std::queue <openxc_VehicleMessage> vehicle_message_q_;
174
175         public:
176                 can_bus_t(const struct afb_binding_interface *itf, int& conf_file);
177                 int init_can_dev();
178                 std::vector<std::string> read_conf();
179                 
180                 void start_threads();
181                 
182                 int send_can_message(can_message_t can_msg);
183
184                 openxc_VehicleMessage& next_vehicle_message();
185                 void push_new_vehicle_message(const openxc_VehicleMessage& v_msg);
186                 bool has_vehicle_message() const;
187 };
188
189 /**
190  * @brief A state encoded (SED) signal's mapping from numerical values to
191  * OpenXC state names.
192  *
193  * @param[in] in value - The integer value of the state on the CAN bus.
194  * @param[in] char* name  - The corresponding string name for the state in OpenXC.
195  */
196 struct CanSignalState {
197         const int value;
198         const char* name;
199 };
200 typedef struct CanSignalState CanSignalState;
201
202 /**
203  * @brief A CAN signal to decode from the bus and output over USB.
204  *
205  * @param[in] message      - The message this signal is a part of.
206  * @param[in] genericName - The name of the signal to be output over USB.
207  * @param[in] bitPosition - The starting bit of the signal in its CAN message (assuming
208  *                               non-inverted bit numbering, i.e. the most significant bit of
209  *                               each byte is 0)
210  * @param[in] bitSize      - The width of the bit field in the CAN message.
211  * @param[in] factor       - The final value will be multiplied by this factor. Use 1 if you
212  *                               don't need a factor.
213  * @param[in] offset       - The final value will be added to this offset. Use 0 if you
214  *                               don't need an offset.
215  * @param[in] minValue    - The minimum value for the processed signal.
216  * @param[in] maxValue    - The maximum value for the processed signal.
217  * @param[in] frequencyClock - A FrequencyClock struct to control the maximum frequency to
218  *                              process and send this signal. To process every value, set the
219  *                              clock's frequency to 0.
220  * @param[in] sendSame    - If true, will re-send even if the value hasn't changed.
221  * @param[in] forceSendChanged - If true, regardless of the frequency, it will send the
222  *                              value if it has changed.
223  * @param[in] states       - An array of CanSignalState describing the mapping
224  *                               between numerical and string values for valid states.
225  * @param[in] stateCount  - The length of the states array.
226  * @param[in] writable    - True if the signal is allowed to be written from the USB host
227  *                               back to CAN. Defaults to false.
228  * @param[in] decoder      - An optional function to decode a signal from the bus to a human
229  *                              readable value. If NULL, the default numerical decoder is used.
230  * @param[in] encoder      - An optional function to encode a signal value to be written to
231  *                                CAN into a byte array. If NULL, the default numerical encoder
232  *                                is used.
233  * @param[in] received    - True if this signal has ever been received.
234  * @param[in] lastValue   - The last received value of the signal. If 'received' is false,
235  *              this value is undefined.
236  */
237 struct CanSignal {
238         struct CanMessageDefinition* message;
239         const char* genericName;
240         uint8_t bitPosition;
241         uint8_t bitSize;
242         float factor;
243         float offset;
244         float minValue;
245         float maxValue;
246         FrequencyClock frequencyClock;
247         bool sendSame;
248         bool forceSendChanged;
249         const CanSignalState* states;
250         uint8_t stateCount;
251         bool writable;
252         SignalDecoder decoder;
253         SignalEncoder encoder;
254         bool received;
255         float lastValue;
256 };
257 typedef struct CanSignal CanSignal;
258
259 /**
260  * @brief The definition of a CAN message. This includes a lot of metadata, so
261  * to save memory this struct should not be used for storing incoming and
262  * outgoing CAN messages.
263  *
264  * @param[in] bus - A pointer to the bus this message is on.
265  * @param[in] id - The ID of the message.
266  * @param[in] format - the format of the message's ID.
267  * @param[in] clock - an optional frequency clock to control the output of this
268  *              message, if sent raw, or simply to mark the max frequency for custom
269  *              handlers to retrieve.
270  * @param[in] forceSendChanged - If true, regardless of the frequency, it will send CAN
271  *              message if it has changed when using raw passthrough.
272  * @param[in] lastValue - The last received value of the message. Defaults to undefined.
273  *              This is required for the forceSendChanged functionality, as the stack
274  *              needs to compare an incoming CAN message with the previous frame.
275  */
276 struct CanMessageDefinition {
277         struct CanBus* bus;
278         uint32_t id;
279         CanMessageFormat format;
280         FrequencyClock frequencyClock;
281         bool forceSendChanged;
282         uint8_t lastValue[CAN_MESSAGE_SIZE];
283 };
284 typedef struct CanMessageDefinition CanMessageDefinition;
285
286 /**
287  * @brief A parent wrapper for a particular set of CAN messages and associated
288  *      CAN buses(e.g. a vehicle or program).
289  *
290  *      @param[in] index - A numerical ID for the message set, ideally the index in an array
291  *              for fast lookup
292  *      @param[in] name - The name of the message set.
293  *      @param[in] busCount - The number of CAN buses defined for this message set.
294  *      @param[in] messageCount - The number of CAN messages (across all buses) defined for
295  *              this message set.
296  *      @param[in] signalCount - The number of CAN signals (across all messages) defined for
297  *              this message set.
298  *      @param[in] commandCount - The number of CanCommmands defined for this message set.
299  */
300  typedef struct {
301         uint8_t index;
302         const char* name;
303         uint8_t busCount;
304         unsigned short messageCount;
305         unsigned short signalCount;
306         unsigned short commandCount;
307 } CanMessageSet;
308
309 /**
310  * @brief The type signature for a function to handle a custom OpenXC command.
311  *
312  * @param[in] char* name - the name of the received command.
313  * @param[in] openxc_DynamicField* value - the value of the received command, in a DynamicField. The actual type
314  *              may be a number, string or bool.
315  * @param[in] openxc_DynamicField* event - an optional event from the received command, in a DynamicField. The
316  *              actual type may be a number, string or bool.
317  * @param[in] CanSignal* signals - The list of all signals.
318  * @param[in] int signalCount - The length of the signals array.
319  */
320 typedef void (*CommandHandler)(const char* name, openxc_DynamicField* value,
321                 openxc_DynamicField* event, CanSignal* signals, int signalCount);
322
323 /* Public: The structure to represent a supported custom OpenXC command.
324  *
325  * For completely customized CAN commands without a 1-1 mapping between an
326  * OpenXC message from the host and a CAN signal, you can define the name of the
327  * command and a custom function to handle it in the VI. An example is
328  * the "turn_signal_status" command in OpenXC, which has a value of "left" or
329  * "right". The vehicle may have separate CAN signals for the left and right
330  * turn signals, so you will need to implement a custom command handler to send
331  * the correct signals.
332  *
333  * Command handlers are also useful if you want to trigger multiple CAN messages
334  * or signals from a signal OpenXC message.
335  *
336  * genericName - The name of the command.
337  * handler - An function to process the received command's data and perform some
338  *              action.
339  */
340 typedef struct {
341         const char* genericName;
342         CommandHandler handler;
343 } CanCommand;
344
345 /**
346  * @brief Pre initialize actions made before CAN bus initialization
347  *
348  * @param[in] can_bus_dev_t bus - A CanBus struct defining the bus's metadata
349  * @param[in] bool writable - configure the controller in a writable mode. If false, it will be
350  *              configured as "listen only" and will not allow writes or even CAN ACKs.
351  * @param[in] buses - An array of all CAN buses.
352  * @param[in] int busCount - The length of the buses array.
353  */
354 void pre_initialize(can_bus_dev_t* bus, bool writable, can_bus_dev_t* buses, const int busCount);
355
356 /* Post-initialize actions made after CAN bus initialization and before the
357  * event loop connection.
358  *
359  * bus - A CanBus struct defining the bus's metadata
360  * writable - configure the controller in a writable mode. If false, it will be
361  *              configured as "listen only" and will not allow writes or even CAN ACKs.
362  * buses - An array of all CAN buses.
363  * busCount - The length of the buses array.
364  */
365 void post_initialize(can_bus_dev_t* bus, bool writable, can_bus_dev_t* buses, const int busCount);
366
367 /* Public: Check if the device is connected to an active CAN bus, i.e. it's
368  * received a message in the recent past.
369  *
370  * Returns true if a message was received on the CAN bus within
371  * CAN_ACTIVE_TIMEOUT_S seconds.
372  */
373 bool isBusActive(can_bus_dev_t* bus);
374
375 /* Public: Log transfer statistics about all active CAN buses to the debug log.
376  *
377  * buses - an array of active CAN buses.
378  * busCount - the length of the buses array.
379  */
380 void logBusStatistics(can_bus_dev_t* buses, const int busCount);