aboutsummaryrefslogtreecommitdiffstats
path: root/src/can/can-signals.hpp
blob: d4b22ccca4e8d0ce28e0b37bc859cdec10a81395 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
 * Copyright (C) 2015, 2016 "IoT.bzh"
 * Author "Romain Forlot" <romain.forlot@iot.bzh>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	 http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <map>
#include <mutex>
#include <queue>
#include <vector>
#include <string>

#include "openxc.pb.h"
#include "utils/timer.hpp"
#include "can/can-bus.hpp"
#include "can/can-message.hpp"
#include "obd2/obd2-signals.hpp"

extern "C"
{
	#include <afb/afb-binding.h>
	#include <afb/afb-event-itf.h>
}

#define MESSAGE_SET_ID 0

/**
 * @brief The type signature for a CAN signal decoder.
 *
 * @desc A SignalDecoder transforms a raw floating point CAN signal into a number,
 * string or boolean.
 *
 * @param[in] signal - The CAN signal that we are decoding.
 * @param[in] signals - The list of all signals.
 * @param[in] signalCount - The length of the signals array.
 * @param[in] value - The CAN signal parsed from the message as a raw floating point
 *	value.
 * @param[out] send - An output parameter. If the decoding failed or the CAN signal should
 *	not send for some other reason, this should be flipped to false.
 *
 * @return a decoded value in an openxc_DynamicField struct.
 */
typedef openxc_DynamicField (*SignalDecoder)(struct CanSignal& signal,
		const std::vector<CanSignal>& signals, float value, bool* send);

/**
 * @brief: The type signature for a CAN signal encoder.
 *
 * @desc A SignalEncoder transforms a number, string or boolean into a raw floating
 * point value that fits in the CAN signal.
 *
 * @params[in] signal - The CAN signal to encode. 
 * @params[in] 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);

/**
 * @struct CanSignalState
 *
 * @brief A state encoded (SED) signal's mapping from numerical values to
 * OpenXC state names.
 */
struct CanSignalState {
	const int value; /*!< value - The integer value of the state on the CAN bus.*/
	const char* name; /*!< name - The corresponding string name for the state in OpenXC. */
};
typedef struct CanSignalState CanSignalState;

/**
 * @struct CanSignal
 *
 * @brief A CAN signal to decode from the bus and output over USB.
 */
struct CanSignal {
	struct CanMessageDefinition* message; /*!< message - The message this signal is a part of. */
	const char* generic_name; /*!< generic_name - The name of the signal to be output over USB.*/
	uint8_t bitPosition; /*!< bitPosition - The starting bit of the signal in its CAN message (assuming
 						*	non-inverted bit numbering, i.e. the most significant bit of
 						*	each byte is 0) */
	uint8_t bitSize; /*!< bitSize - The width of the bit field in the CAN message. */
	float factor; /*!< factor - The final value will be multiplied by this factor. Use 1 if you
 				*	don't need a factor. */
	float offset; /*!< offset	   - The final value will be added to this offset. Use 0 if you
 				*	don't need an offset. */
	float minValue; /*!< minValue    - The minimum value for the processed signal.*/
	float maxValue; /*!< maxValue    - The maximum value for the processed signal. */
	FrequencyClock frequencyClock; /*!< frequencyClock - A FrequencyClock struct to control the maximum frequency to
 								*	process and send this signal. To process every value, set the
 								*	clock's frequency to 0. */
	bool sendSame; /*!< sendSame    - If true, will re-send even if the value hasn't changed.*/
	bool forceSendChanged; /*!< forceSendChanged - If true, regardless of the frequency, it will send the
 						*	value if it has changed. */
	const CanSignalState* states; /*!< states	   - An array of CanSignalState describing the mapping
 								*	between numerical and string values for valid states. */
	uint8_t stateCount; /*!< stateCount  - The length of the states array. */
	bool writable; /*!< writable    - True if the signal is allowed to be written from the USB host
 				*	back to CAN. Defaults to false.*/
	SignalDecoder decoder; /*!< decoder	   - An optional function to decode a signal from the bus to a human
 						*	readable value. If NULL, the default numerical decoder is used. */
	SignalEncoder encoder; /*!< encoder	   - An optional function to encode a signal value to be written to
 						*	CAN into a byte array. If NULL, the default numerical encoder
 						*	is used. */
	bool received; /*!< received    - True if this signal has ever been received.*/
	float lastValue; /*!< lastValue   - The last received value of the signal. If 'received' is false,
 					*	this value is undefined. */
};
typedef struct CanSignal CanSignal;

class can_signal_t
{
	private:
		struct can_message_definition_t* message_; /*!< message_ - The message this signal is a part of. */
		const std::string generic_name_; /*!< generic_name_ - The name of the signal to be output over USB.*/
		uint8_t bitPosition_; /*!< bitPosition_ - The starting bit of the signal in its CAN message (assuming
							   *	non-inverted bit numbering, i.e. the most significant bit of
							   *	each byte is 0) */
		uint8_t bitSize_; /*!< bitSize_ - The width of the bit field in the CAN message. */
		float factor_; /*!< factor_ - The final value will be multiplied by this factor. Use 1 if you
						*	don't need a factor. */
		float offset_; /*!< offset_ - The final value will be added to this offset. Use 0 if you
						*	don't need an offset. */
		float min_value_; /*!< min_value_ - The minimum value for the processed signal.*/
		float max_value_; /*!< max_value_ - The maximum value for the processed signal. */
		FrequencyClock frequency_; /*!< frequency_ - A FrequencyClock struct to control the maximum frequency to
								*	process and send this signal. To process every value, set the
								*	clock's frequency to 0. */
		bool send_same_; /*!< send_same_ - If true, will re-send even if the value hasn't changed.*/
		bool force_send_changed_; /*!< force_send_changed_ - If true, regardless of the frequency, it will send the
								 *	value if it has changed. */
		const std::map<const int, const std::string> states_; /*!< states_ - A map of CAN signal state describing the mapping
															   * between numerical and string values for valid states. */
		uint8_t state_count_; /*!< state_count_ - The length of the states array. */
		bool writable_; /*!< writable - True if the signal is allowed to be written from the USB host
						*	back to CAN. Defaults to false.*/
		SignalDecoder decoder_; /*!< decoder_ - An optional function to decode a signal from the bus to a human
								 * readable value. If NULL, the default numerical decoder is used. */
		SignalEncoder encoder_; /*!< encoder_ - An optional function to encode a signal value to be written to
								 * CAN into a byte array. If NULL, the default numerical encoder
								 * is used. */
		bool received_; /*!< received_ - True if this signal has ever been received.*/
		float lastValue_; /*!< lastValue_ - The last received value of the signal. If 'received' is false,
						   *	this value is undefined. */

	public:
		can_message_definition_t* get_message()
		{
			return message_;
		}

		const std::string& get_generic_name()
		{
			return generic_name_;
		}
};

void find_can_signals(const openxc_DynamicField &key, std::vector<CanSignal*>& found_signals);