-
Notifications
You must be signed in to change notification settings - Fork 45
/
Copy pathIDecoderManifest.h
338 lines (291 loc) · 11.1 KB
/
IDecoderManifest.h
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "EventTypes.h"
#include "MessageTypes.h"
#include "OBDDataTypes.h"
#include "SignalTypes.h"
#include <cstdint>
#include <string>
#include <unordered_map>
#include <utility>
namespace Aws
{
namespace IoTFleetWise
{
/**
* @brief An invalid CAN Message Format, set as a CANMessageFormat object initialized to all zeros
*/
const CANMessageFormat INVALID_CAN_MESSAGE_FORMAT = CANMessageFormat();
/**
* @brief Contains the decoding rules to decode OBD-II PID Signals
*/
struct PIDSignalDecoderFormat
{
/**
* @brief default constructor with no input
*/
PIDSignalDecoderFormat() = default;
/**
* @brief constructor with input to initialize all member variables
*/
PIDSignalDecoderFormat( size_t pidResponseLength,
SID sid,
PID pid,
double scaling,
double offset,
size_t startByte,
size_t byteLength,
uint8_t bitRightShift,
uint8_t bitMaskLength )
: mPidResponseLength( pidResponseLength )
, mServiceMode( sid )
, mPID( pid )
, mScaling( scaling )
, mOffset( offset )
, mStartByte( startByte )
, mByteLength( byteLength )
, mBitRightShift( bitRightShift )
, mBitMaskLength( bitMaskLength ){};
/*
* Length of the PID response. Note this is not the signal byte length as PID might contain
* multiple signals
*/
size_t mPidResponseLength{ 0 };
/*
* OBDII-PID Service Mode for the signal in decimal
*/
SID mServiceMode{ SID::INVALID_SERVICE_MODE };
/*
* OBD request PID in decimal
*/
PID mPID{ 0 };
/*
* scaling to decode OBD from raw bytes to double value
* e.g. A * 0.0125 - 40. scaling is 0.01
*/
double mScaling{ 0 };
/*
* offset to decode OBD from raw bytes to double value
* e.g. A * 0.0125 - 40. offset is -40.0
*/
double mOffset{ 0 };
/*
* the start byte order (starting from 0th) for this signal in its PID query response
* e.g. PID 0x14 contains two signals. SHRFT is the second byte. Its startByte is 1
*/
size_t mStartByte{ 0 };
/*
* number of bytes for this signal in its PID query response
* e.g. PID 0x14 contains two signals. SHRFT is one byte. Its byteLength is 1
*/
size_t mByteLength{ 0 };
/*
* Right shift on bits to decode this signal from raw bytes. Note the bit manipulation is
* only performed when byteLength is 1.
* e.g. Boost Pressure B Control Status is bit 2, 3 on byte J. The right shift shall be 2
* For non-bitmask signals, the right shift shall always be 0
*/
uint8_t mBitRightShift{ 0 };
/*
* bit Mask Length to be applied to decode this signal from raw byte. Note the bit manipulation
* is only performed when byteLength is 1.
* e.g. Boost Pressure B Control Status is bit 2, 3 on byte J. The bit Mask Length would be 2
* For non-bitmask signals, the bit Mask Length shall always be 8.
*/
uint8_t mBitMaskLength{ 0 };
/**
* @brief The datatype of the signal.
*/
SignalType mSignalType{ SignalType::UNKNOWN };
public:
/**
* @brief Overload of the == operator
* @param other Other PIDSignalDecoderFormat object to compare
* @return true if ==, false otherwise
*/
bool
operator==( const PIDSignalDecoderFormat &other ) const
{
return ( mPidResponseLength == other.mPidResponseLength ) && ( mServiceMode == other.mServiceMode ) &&
( mPID == other.mPID ) && ( mScaling == other.mScaling ) && ( mOffset == other.mOffset ) &&
( mStartByte == other.mStartByte ) && ( mByteLength == other.mByteLength ) &&
( mBitRightShift == other.mBitRightShift ) && ( mBitMaskLength == other.mBitMaskLength );
}
};
/*
* Custom signal decoder, which for example can be the fully-qualified-name of the signal
*/
using CustomSignalDecoder = std::string;
const CustomSignalDecoder INVALID_CUSTOM_SIGNAL_DECODER = {};
struct CustomSignalDecoderFormat
{
InterfaceID mInterfaceId;
CustomSignalDecoder mDecoder;
/**
* @brief Unique Signal ID provided by Cloud
*/
SignalID mSignalID{ 0x0 };
/**
* @brief The datatype of the signal. The default is double for backward compatibility
*/
SignalType mSignalType{ SignalType::DOUBLE };
public:
/**
* @brief Overload of the == operator
* @param other Other CustomSignalDecoderFormat object to compare
* @return true if ==, false otherwise
*/
bool
operator==( const CustomSignalDecoderFormat &other ) const
{
return ( mInterfaceId == other.mInterfaceId ) && ( mDecoder == other.mDecoder );
}
};
using SignalIDToCustomSignalDecoderFormatMap = std::unordered_map<SignalID, CustomSignalDecoderFormat>;
using SignalIDToCustomSignalDecoderFormatMapPtr = std::shared_ptr<const SignalIDToCustomSignalDecoderFormatMap>;
#ifdef FWE_FEATURE_VISION_SYSTEM_DATA
/**
* @brief Contains on ComplexSignal from the decoder manifest that can be used to decode big structured
* messages. To optimize the size of the decoder manifest the decoding rules are represented as
* a tree so repeating types can be just referenced by a ComplexDataTypeId. mRootTypeId gives
* the root of the tree. The position of an element in the tree is used for decoding.
*/
struct ComplexSignalDecoderFormat
{
InterfaceID mInterfaceId;
/*
* Interface-specific message information. The pair interface_id and message_id should be unique across all
* ComplexSignals. For ROS2 this is the topic on which the message is sent.
*/
ComplexDataMessageId mMessageId;
/*
* Type id of the root signal. 0 is reserved for future usage.
*/
ComplexDataTypeId mRootTypeId;
};
#endif
/**
* @brief Error Code for OBD-II PID Decoder Format Not Ready to read
*/
const PIDSignalDecoderFormat NOT_READY_PID_DECODER_FORMAT = PIDSignalDecoderFormat();
/**
* @brief Error Code for OBD-II PID Decoder Format Not Found in decoder manifest
*/
const PIDSignalDecoderFormat NOT_FOUND_PID_DECODER_FORMAT = PIDSignalDecoderFormat();
/**
* @brief Error code for custom signal decoder not found or not ready in decoder manifest
*/
const CustomSignalDecoderFormat INVALID_CUSTOM_SIGNAL_DECODER_FORMAT = CustomSignalDecoderFormat();
/**
* @brief IDecoderManifest is used to exchange DecoderManifest between components
*
* This is separated from ICollectionScheme to make it possible to also decode messages (for
* example for debug purpose) that are currently not collected from any Collection Scheme
*
*/
class IDecoderManifest
{
public:
/**
* @brief indicates if the decoder manifest is prepared to be used for example by calling getters
*
* @return true if ready and false if not ready then build function must be called first
* */
virtual bool isReady() const = 0;
/**
* @brief Build internal structures from raw input so lazy initialization is possible
*
* @return true if build succeeded false if the collectionScheme is corrupted and can not be used
* */
virtual bool build() = 0;
/**
* @brief Get the ID of the decoder manifest
*
* @return String ID of the decoder manifest. Empty string if error.
*/
virtual SyncID getID() const = 0;
/**
* @brief get CAN Message format to decode.
* @param canID msg id seen in the frame on the bus
* @param interfaceID the channel on which the frame was received
* @return if can frame id can't be found a CANMessageFormat equal to INVALID_CAN_MESSAGE_FORMAT
* is returned
*/
virtual const CANMessageFormat &getCANMessageFormat( CANRawFrameID canID, InterfaceID interfaceID ) const = 0;
/**
* @brief get the can frame that contains the signal
* @param signalID unique signal id
*
* @return if no can and can interface ids can be found invalid ids are returned
*/
virtual std::pair<CANRawFrameID, InterfaceID> getCANFrameAndInterfaceID( SignalID signalID ) const = 0;
/**
* @brief Get the Vehicle Data Source Protocol for this Signal
* @param signalID the unique signalID
* @return invalid Protocol Type if signal is not found in decoder manifest
*/
virtual VehicleDataSourceProtocol getNetworkProtocol( SignalID signalID ) const = 0;
/**
* @brief Get the OBD PID Signal decoder format
* @param signalID the unique signalID
* @return invalid Decoder format if signal is not OBD PID signal
*/
virtual PIDSignalDecoderFormat getPIDSignalDecoderFormat( SignalID signalID ) const = 0;
#ifdef FWE_FEATURE_VISION_SYSTEM_DATA
/**
* @brief Get the Complex Signal decoder format
* @param signalID the unique signalID
* @return invalid Decoder format if signal is not a Complex Signal
*/
virtual ComplexSignalDecoderFormat getComplexSignalDecoderFormat( SignalID signalID ) const = 0;
/**
* @brief Get the Complex Type
* @param typeId the unique typeId
* @return ComplexDataElement if complex data type does not exist
*/
virtual ComplexDataElement getComplexDataType( ComplexDataTypeId typeId ) const = 0;
#endif
/**
* @brief Get the custom decoder for this signal
* @param signalID the unique signalID
* @return invalid decoder if signal does not have a custom decoder
*/
virtual CustomSignalDecoderFormat getCustomSignalDecoderFormat( SignalID signalID ) const = 0;
/**
* @brief Get custom signal decoder format map
* @return empty map if no map is present in the decoder manifest
*/
virtual SignalIDToCustomSignalDecoderFormatMapPtr getSignalIDToCustomSignalDecoderFormatMap() const = 0;
/**
* @brief Used by the AWS IoT MQTT callback to copy data received from Cloud into this object without any further
* processing to minimize time spent in callback context.
*
* @param inputBuffer Byte array of raw protobuffer data for a decoder_manifest.proto type binary blob
* @param size Size of the data buffer
*
* @return True if successfully copied, false if failure to copy data.
*/
virtual bool copyData( const std::uint8_t *inputBuffer, const size_t size ) = 0;
/**
* @brief This function returns mProtoBinaryData majorly used for persistent
* storage
*
* @return binary data in a vector
*/
virtual const std::vector<uint8_t> &getData() const = 0;
/**
* @brief This function returns Signal Type from the Decoder
*
* @param signalID
* @return SignalType
*/
virtual SignalType getSignalType( const SignalID signalID ) const = 0;
/**
* @brief Virtual destructor to be implemented by the base class
*/
virtual ~IDecoderManifest() = default;
};
using IDecoderManifestPtr = std::shared_ptr<IDecoderManifest>;
} // namespace IoTFleetWise
} // namespace Aws