AgIsoStack++
A control-function-focused implementation of the major ISOBUS and J1939 protocols
Loading...
Searching...
No Matches
isobus_diagnostic_protocol.hpp
Go to the documentation of this file.
1//================================================================================================
34//================================================================================================
35
36#ifndef ISOBUS_DIAGNOSTIC_PROTOCOL_HPP
37#define ISOBUS_DIAGNOSTIC_PROTOCOL_HPP
38
41#include "isobus/utility/processing_flags.hpp"
42
43#include <array>
44#include <list>
45#include <memory>
46#include <string>
47
48namespace isobus
49{
50 //================================================================================================
53 //================================================================================================
55 {
56 public:
58 enum class ECUIdentificationFields : std::uint8_t
59 {
60 PartNumber = 0,
62 Location,
63 Type,
67 };
68
86
112
114 enum class TransmitFlags
115 {
116 DM1 = 0,
117 DM2,
120 DM22,
123
125 };
126
128 enum class NetworkType : std::uint8_t
129 {
130 SAEJ1939Network1PrimaryVehicleNetwork = 0,
131 SAEJ1922Network = 1,
132 SAEJ1587Network = 2,
133 CurrentDataLink = 3,
134 OtherManufacturerSpecifiedPort = 4,
135 SAEJ1850Network = 5,
136 ISO9141Network = 6,
137 SAEJ1939Network2 = 7,
138 SAEJ1939Network4 = 8,
139 ProprietaryNetwork2 = 9,
140 ProprietaryNetwork1 = 10,
141 SAEJ1939Network3 = 11,
142 SAEJ1939Network5 = 25,
143 SAEJ1939Network6 = 26,
144 SAEJ1939Network7 = 27,
145 SAEJ1939Network8 = 28,
146 SAEJ1939Network11 = 29,
147 SAEJ1939Network10 = 30,
148 SAEJ1939Network9 = 31,
149 Reserved = 32
150 };
151
153 enum class StopStartCommand : std::uint8_t
154 {
155 StopBroadcast = 0,
156 StartBroadcast = 1,
157 Reserved = 2,
159 };
160
162 enum class SuspendSignalState : std::uint8_t
163 {
168 Resuming = 4,
169 NotAvailable = 15
170 };
171
172 //================================================================================================
175 //================================================================================================
177 {
178 public:
181
186 DiagnosticTroubleCode(std::uint32_t spn, FailureModeIdentifier fmi, LampStatus lamp);
187
191 bool operator==(const DiagnosticTroubleCode &obj) const;
192
195 std::uint8_t get_occurrence_count() const;
196
199 std::uint32_t get_suspect_parameter_number() const;
200
204
205 private:
206 friend class DiagnosticProtocol;
207 std::uint32_t suspectParameterNumber = 0xFFFFFFFF;
209 LampStatus lampState = LampStatus::None;
210 std::uint8_t occurrenceCount = 0;
211 };
212
216 DiagnosticProtocol(std::shared_ptr<InternalControlFunction> internalControlFunction,
217 NetworkType networkType = NetworkType::ProprietaryNetwork1);
218
221
224 bool initialize();
225
228 bool get_initialized() const;
229
231 void terminate();
232
234 void update();
235
239 void set_j1939_mode(bool value);
240
243 bool get_j1939_mode() const;
244
251
254
257
260
268 void set_ecu_id_field(ECUIdentificationFields field, const std::string &value);
269
277 bool set_diagnostic_trouble_code_active(const DiagnosticTroubleCode &dtc, bool active);
278
283
291 bool set_product_identification_code(const std::string &value);
292
298 bool set_product_identification_brand(const std::string &value);
299
304 bool set_product_identification_model(const std::string &value);
305
316 void set_software_id_field(std::uint32_t index, const std::string &value);
317
322 bool suspend_broadcasts(std::uint16_t suspendTime_seconds = 0xFFFF);
323
326 bool get_broadcast_state() const;
327
328 private:
330 enum class Lamps
331 {
336 };
337
339 enum class FlashState
340 {
341 Solid,
342 Slow,
343 Fast
344 };
345
356
358 enum class DM22NegativeAcknowledgeIndicator : std::uint8_t
359 {
360 General = 0x00,
361 AccessDenied = 0x01,
362 UnknownOrDoesNotExist = 0x02,
364 DTCNoLongerActive = 0x04
365 };
366
368 struct DM22Data
369 {
370 std::shared_ptr<ControlFunction> destination;
373 std::uint8_t nackIndicator;
375 bool nack;
376 };
377
378 static constexpr std::uint32_t DM_MAX_FREQUENCY_MS = 1000;
379 static constexpr std::uint32_t DM13_HOLD_SIGNAL_TRANSMIT_INTERVAL_MS = 5000;
380 static constexpr std::uint32_t DM13_TIMEOUT_MS = 6000;
381 static constexpr std::uint16_t MAX_PAYLOAD_SIZE_BYTES = 1785;
382 static constexpr std::uint16_t MAX_DM13_CUSTOM_SUSPEND_TIME_MS = 64255;
383 static constexpr std::uint8_t DM_PAYLOAD_BYTES_PER_DTC = 4;
384 static constexpr std::uint8_t PRODUCT_IDENTIFICATION_MAX_STRING_LENGTH = 50;
385 static constexpr std::uint8_t DM13_NUMBER_OF_J1939_NETWORKS = 11;
386 static constexpr std::uint8_t DM13_NETWORK_BITMASK = 0x03;
387 static constexpr std::uint8_t DM13_BITS_PER_NETWORK = 2;
388
392 std::uint8_t convert_flash_state_to_byte(FlashState flash) const;
393
400 void get_active_list_lamp_state_and_flash_state(Lamps targetLamp, FlashState &flash, bool &lampOn) const;
401
408 void get_inactive_list_lamp_state_and_flash_state(Lamps targetLamp, FlashState &flash, bool &lampOn) const;
409
413 void on_address_violation(std::shared_ptr<InternalControlFunction> affectedControlFunction);
414
417 bool send_diagnostic_message_1() const;
418
421 bool send_diagnostic_message_2() const;
422
426
430 bool send_dm13_announce_suspension(std::uint16_t suspendTime_seconds) const;
431
434 bool send_ecu_identification() const;
435
438 bool send_product_identification() const;
439
442 bool send_software_identification() const;
443
448
451 void process_message(const CANMessage &message);
452
456 static void process_message(const CANMessage &message, void *parent);
457
461 bool parse_j1939_network_states(const CANMessage &message);
462
469 bool process_parameter_group_number_request(std::uint32_t parameterGroupNumber,
470 std::shared_ptr<ControlFunction> requestingControlFunction,
471 bool &acknowledge,
472 AcknowledgementType &acknowledgementType);
473
474 // @brief Handles PGN requests for the diagnostic protocol
481 static bool process_parameter_group_number_request(std::uint32_t parameterGroupNumber,
482 std::shared_ptr<ControlFunction> requestingControlFunction,
483 bool &acknowledge,
484 AcknowledgementType &acknowledgementType,
485 void *parentPointer);
486
490 static void process_flags(std::uint32_t flag, void *parentPointer);
491
492 std::shared_ptr<InternalControlFunction> myControlFunction;
493 EventCallbackHandle addressViolationEventHandle;
495 std::vector<DiagnosticTroubleCode> activeDTCList;
496 std::vector<DiagnosticTroubleCode> inactiveDTCList;
497 std::vector<DM22Data> dm22ResponseQueue;
498 std::vector<std::string> ecuIdentificationFields;
499 std::vector<std::string> softwareIdentificationFields;
500 ProcessingFlags txFlags;
504 std::uint32_t lastDM1SentTimestamp = 0;
505 std::uint32_t lastDM13ReceivedTimestamp = 0;
506 std::uint16_t customDM13SuspensionTime = 0;
507 bool broadcastState = true;
508 bool j1939Mode = false;
509 bool initialized = false;
510 };
511}
512
513#endif // ISOBUS_DIAGNOSTIC_PROTOCOL_HPP
A representation of an ISOBUS ECU that we can send from. Use this class when defining your own contro...
A class that represents a generic CAN message of arbitrary length.
Manages the control function functionalities message.
A storage class for describing a complete DTC.
std::uint32_t suspectParameterNumber
This 19-bit number is used to identify the item for which diagnostics are being reported.
std::uint8_t occurrenceCount
Number of times the DTC has been active (0 to 126 with 127 being not available)
DiagnosticTroubleCode()=default
Constructor for a DTC, sets default values at construction time.
LampStatus lampState
The J1939 lamp state for this DTC.
bool operator==(const DiagnosticTroubleCode &obj) const
A useful way to compare DTC objects to each other for equality.
std::uint8_t get_occurrence_count() const
Returns the occurrence count, which will be kept track of by the protocol.
std::uint32_t get_suspect_parameter_number() const
Returns the suspect parameter number.
FailureModeIdentifier get_failure_mode_identifier() const
Returns the failure mode indicator.
FailureModeIdentifier failureModeIdentifier
The FMI defines the type of failure detected in the sub-system identified by an SPN.
Manages the DM1, DM2, and DM3 messages for ISO11783 or J1939.
SuspendSignalState
Enumerates the different suspend signals for DM13.
@ IndefiniteSuspension
Indefinite suspension of all broadcasts.
@ PartialTemporarySuspension
Temporary suspension of some messages.
@ Resuming
Resuming normal broadcast pattern.
@ PartialIndefiniteSuspension
Indefinite suspension of some messages.
@ TemporarySuspension
Temporary suspension of all broadcasts.
bool broadcastState
Bitfield for tracking the network broadcast state for DM13.
~DiagnosticProtocol()
The destructor for this protocol.
void process_message(const CANMessage &message)
A generic way for a protocol to process a received message.
FailureModeIdentifier
FMI as defined in ISO11783-12 Annex E.
@ VoltageBelowNormal
A voltage signal, data or otherwise, is below the predefined limits that bound the range.
@ ReceivedNetworkDataInError
Any failure that is detected when the data received through the network are found replaced by the �er...
@ DataValidBelowNormalMostSevere
Condition is below normal as determined by the predefined most severe level limits for that particula...
@ DataValidAboveNormalMostSevere
Condition is above normal as determined by the predefined most severe level limits for that particula...
@ DataValidBelowNormalModeratelySevere
Condition is below what would be considered normal as determined by the predefined moderately severe ...
@ AbnormalUpdateRate
Any failure that is detected when receipt of data through the data network is not at the update rate ...
@ MechanicalSystemNotResponding
Any fault that is detected as the result of an improper mechanical adjustment, an improper response o...
@ RootCauseNotKnown
It has been detected that a failure has occurred in a particular subsystem but the exact nature of th...
@ DataValidAboveNormalLeastSevere
Condition is above what would be considered normal as determined by the predefined least severe level...
@ DataValidAboveNormalModeratelySevere
Condition is above what would be considered normal as determined by the predefined moderately severe ...
@ VoltageAboveNormal
A voltage signal, data or otherwise, is above the predefined limits that bound the range.
@ DataValidBelowNormalLeastSevere
Condition is below what would be considered normal as determined by the predefined least severe level...
@ OutOfCalibration
A failure that can be identified as the result of improper calibration.
@ AbnormalRateOfChange
Any data, exclusive of FMI 2, that are considered valid but which are changing at a rate that is outs...
@ SpecialInstructions
Used when the on-board system can isolate the failure to a small number of choices but not to a singl...
@ ConditionExists
The condition that is identified by the SPN exists when no applicable FMI exists (any other error)
@ DataErratic
Erratic or intermittent data include all measurements that change at a rate not considered possible i...
@ CurrentAboveNormal
A current signal, data or otherwise, is above the predefined limits that bound the range.
@ CurrentBelowNormal
A current signal, data or otherwise, is below the predefined limits that bound the range.
@ AbnormalFrequency
Any frequency or PWM signal that is outside the predefined limits which bound the signal range for fr...
@ BadIntelligentDevice
Internal diagnostic procedures have determined that the failure is one which requires the replacement...
ProcessingFlags txFlags
An instance of the processing flags to handle retries of some messages.
void get_inactive_list_lamp_state_and_flash_state(Lamps targetLamp, FlashState &flash, bool &lampOn) const
This is a way to find the overall lamp states to report.
std::string productIdentificationBrand
The product identification brand for sending the product identification message.
static void process_flags(std::uint32_t flag, void *parentPointer)
A generic callback for a the class to process flags from the ProcessingFlags
void clear_software_id_fields()
Clears all previously configured software ID fields set with set_software_id_field.
NetworkType networkType
The diagnostic network type that this protocol will use.
bool get_initialized() const
Returns if the protocol has been initialized.
bool set_product_identification_model(const std::string &value)
Sets the product identification model used in the diagnostic protocol "Product Identification" messag...
static constexpr std::uint16_t MAX_PAYLOAD_SIZE_BYTES
DM 1 and 2 are limited to the BAM message max, because ETP does not allow global destinations.
EventCallbackHandle addressViolationEventHandle
Stores the handle from registering for address violation events.
static constexpr std::uint32_t DM_MAX_FREQUENCY_MS
You are technically allowed to send more than this under limited circumstances, but a hard limit save...
bool suspend_broadcasts(std::uint16_t suspendTime_seconds=0xFFFF)
Informs the diagnostic protocol that you are going to suspend broadcasts.
bool send_ecu_identification() const
Sends the ECU ID message.
NetworkType
Enumerates the different networks in the DM13.
bool send_dm13_announce_suspension(std::uint16_t suspendTime_seconds) const
Sends the DM13 to alert network devices of impending suspended broadcasts.
bool send_diagnostic_protocol_identification() const
Sends a message that identifies which diagnostic protocols are supported.
StopStartCommand
Enumerates the commands in the DM13.
@ DontCareNoAction
Don’t Care/take no action (leave as is)
std::vector< std::string > ecuIdentificationFields
Stores the ECU ID fields so we can transmit them when ECU ID's PGN is requested.
FlashState
Enumerates lamp flash states in J1939.
std::uint16_t customDM13SuspensionTime
If using a non-standard DM13 suspension time, this tracks that duration in milliseconds.
void update()
Updates the diagnostic protocol.
DiagnosticProtocol(std::shared_ptr< InternalControlFunction > internalControlFunction, NetworkType networkType=NetworkType::ProprietaryNetwork1)
The constructor for this protocol.
bool set_diagnostic_trouble_code_active(const DiagnosticTroubleCode &dtc, bool active)
Adds a DTC to the active list, or removes one from the active list.
std::shared_ptr< InternalControlFunction > myControlFunction
The internal control function that this protocol will send from.
LampStatus
The DTC lamp status as defined in J1939-73. Not used when in ISO11783 mode.
@ EngineProtectLampSolid
This lamp is used to relay trouble code information that is reporting a problem with a vehicle system...
@ EngineProtectLampSlowFlash
This lamp is used to relay trouble code information that is reporting a problem with a vehicle system...
@ EngineProtectLampFastFlash
This lamp is used to relay trouble code information that is reporting a problem with a vehicle system...
@ AmberWarningLampSlowFlash
This lamp is used to relay trouble code information that is reporting a problem with the vehicle syst...
@ AmberWarningLampFastFlash
This lamp is used to relay trouble code information that is reporting a problem with the vehicle syst...
@ AmberWarningLampSolid
This lamp is used to relay trouble code information that is reporting a problem with the vehicle syst...
@ MalfunctionIndicatorLampSolid
A lamp used to relay only emissions-related trouble code information.
@ RedStopLampSolid
This lamp is used to relay trouble code information that is of a severe-enough condition that it warr...
@ MalfunctionIndicatorLampSlowFlash
A lamp used to relay only emissions-related trouble code information.
@ MalfunctionIndicatorLampFastFlash
A lamp used to relay only emissions-related trouble code information.
@ RedStopLampFastFlash
This lamp is used to relay trouble code information that is of a severe-enough condition that it warr...
@ RedStopLampSlowFlash
This lamp is used to relay trouble code information that is of a severe-enough condition that it warr...
Lamps
Lists the different lamps in J1939-73.
@ ProtectLamp
The engine protect lamp.
std::uint32_t lastDM13ReceivedTimestamp
A timestamp in milliseconds when we last got a DM13 message.
void clear_inactive_diagnostic_trouble_codes()
Clears the list of inactive DTCs and clears occurrence counts.
DM22ControlByte
The DM22 multiplexer bytes. All bytes not given a value here are reserved by SAE.
@ NegativeAcknowledgeOfPreviouslyActiveDTCClear
NACK for clearing a previously active DTC.
@ RequestToClearPreviouslyActiveDTC
Clear a previously active DTC.
@ PositiveAcknowledgeOfPreviouslyActiveDTCClear
ACK for clearing a previously active DTC.
@ PositiveAcknowledgeOfActiveDTCClear
ACK clearing an active DTC.
@ NegativeAcknowledgeOfActiveDTCClear
NACK clearing an active DTC.
bool set_product_identification_brand(const std::string &value)
Sets the product identification brand used in the diagnostic protocol "Product Identification" messag...
static constexpr std::uint32_t DM13_TIMEOUT_MS
The timeout in 5.7.13 after which nodes shall revert back to the normal broadcast state.
DM22NegativeAcknowledgeIndicator
The negative acknowledge (NACK) reasons for a DM22 message.
@ DTCNoLongerActive
DTC is inactive, not active, but active was requested to be cleared.
@ DTCNoLongerPreviouslyActive
The DTC in in the active list but it was requested to clear from inactive list.
@ UnknownOrDoesNotExist
The DTC is unknown or does not exist.
std::string productIdentificationModel
The product identification model name for sending the product identification message.
std::vector< std::string > softwareIdentificationFields
Stores the Software ID fields so we can transmit them when the PGN is requested.
static constexpr std::uint8_t DM13_NETWORK_BITMASK
Used to mask the network SPN values.
static constexpr std::uint8_t PRODUCT_IDENTIFICATION_MAX_STRING_LENGTH
The max string length allowed in the fields of product ID, as defined in ISO 11783-12.
ControlFunctionFunctionalities ControlFunctionFunctionalitiesMessageInterface
Use this interface to configure your CF's functionalities. This info will be reported to any ECU that...
std::string productIdentificationCode
The product identification code for sending the product identification message.
bool set_product_identification_code(const std::string &value)
Sets the product ID code used in the diagnostic protocol "Product Identification" message (PGN 0xFC8D...
void terminate()
The protocol's terminate function.
bool get_j1939_mode() const
Returns true if the protocol is in J1939 mode instead of ISO11783 mode, false if using ISO11783 mode.
std::uint8_t convert_flash_state_to_byte(FlashState flash) const
A utility function to get the CAN representation of a FlashState.
std::vector< DM22Data > dm22ResponseQueue
Maintaining a list of DM22 responses we need to send to allow for retrying in case of Tx failures.
bool get_diagnostic_trouble_code_active(const DiagnosticTroubleCode &dtc)
Returns if a DTC is active.
bool initialize()
The protocol's initializer function.
bool send_diagnostic_message_2() const
Sends a DM2 encoded CAN message.
bool j1939Mode
Tells the protocol to operate according to J1939 instead of ISO11783.
void set_software_id_field(std::uint32_t index, const std::string &value)
Adds an ascii string to this internal control function's software ID.
bool get_broadcast_state() const
Gets the current broadcast state for the connected network type.
void set_ecu_id_field(ECUIdentificationFields field, const std::string &value)
Sets one of the ECU identification strings for the ECU ID message.
static constexpr std::uint8_t DM13_BITS_PER_NETWORK
Number of bits for the network SPNs.
TransmitFlags
A set of transmit flags to manage sending DM1, DM2, and protocol ID.
@ DM1
A flag to manage sending the DM1 message.
@ ProductIdentification
A flag to manage sending the product identification message.
@ DM2
A flag to manage sending the DM2 message.
@ SoftwareIdentification
A flag to manage sending the software ID message.
@ ECUIdentification
A flag to manage sending the ECU ID message.
@ DiagnosticProtocolID
A flag to manage sending the Diagnostic protocol ID message.
@ DM22
Process queued up DM22 responses.
@ NumberOfFlags
The number of flags in the enum.
std::vector< DiagnosticTroubleCode > inactiveDTCList
Keeps track of all the previously active DTCs.
void clear_active_diagnostic_trouble_codes()
Clears the list of active DTCs and makes them all inactive.
void set_j1939_mode(bool value)
Enables the protocol to run in J1939 mode instead of ISO11783 mode.
static constexpr std::uint8_t DM13_NUMBER_OF_J1939_NETWORKS
The number of networks in DM13 that are set aside for J1939.
bool parse_j1939_network_states(const CANMessage &message)
Parses out the DM13 J1939 network states from a CAN message.
static constexpr std::uint8_t DM_PAYLOAD_BYTES_PER_DTC
The number of payload bytes per DTC that gets encoded into the messages.
void get_active_list_lamp_state_and_flash_state(Lamps targetLamp, FlashState &flash, bool &lampOn) const
This is a way to find the overall lamp states to report.
static constexpr std::uint32_t DM13_HOLD_SIGNAL_TRANSMIT_INTERVAL_MS
Defined in 5.7.13.13 SPN 1236.
void on_address_violation(std::shared_ptr< InternalControlFunction > affectedControlFunction)
A callback function used to consume address violation events and activate a DTC as required in ISO117...
bool send_product_identification() const
Sends the product identification message (PGN 0xFC8D)
bool send_diagnostic_message_1() const
Sends a DM1 encoded CAN message.
std::uint32_t lastDM1SentTimestamp
A timestamp in milliseconds of the last time a DM1 was sent.
ECUIdentificationFields
Enumerates the different fields in the ECU identification message.
@ Type
The type of ECU. One example of a use of the ECU type could be for classifying ECU capabilities,...
@ SerialNumber
The serial number of the physical ECU.
@ NumberOfFields
The number of fields currently defined in the ISO standard.
@ Location
The location of the ECU within a network.
@ HardwareID
ISO 11783 only, This parameter is used to associate the hardware version of an ECU connected to the I...
@ PartNumber
The part number of the physical ECU.
bool initialized
Stores if the interface has been initialized.
std::vector< DiagnosticTroubleCode > activeDTCList
Keeps track of all the active DTCs.
bool process_parameter_group_number_request(std::uint32_t parameterGroupNumber, std::shared_ptr< ControlFunction > requestingControlFunction, bool &acknowledge, AcknowledgementType &acknowledgementType)
Handles PGN requests for the diagnostic protocol.
bool process_all_dm22_responses()
Processes any DM22 responses from the queue.
bool send_software_identification() const
Sends the software ID message.
static constexpr std::uint16_t MAX_DM13_CUSTOM_SUSPEND_TIME_MS
The max valid value for a DM13 suspension time in milliseconds.
Defines a class that manages the control function functionalities message data. (PGN 64654,...
This namespace encompasses all of the ISO11783 stack's functionality to reduce global namespace pollu...
AcknowledgementType
The types of acknowledgement that can be sent in the Ack PGN.
A structure to hold data about DM22 responses we need to send.
std::uint8_t nackIndicator
The NACK reason, if applicable.
std::uint32_t suspectParameterNumber
SPN of the DTC for the DM22.
bool nack
true if we are sending a NACK instead of PACK. Determines if we use nackIndicator
bool clearActive
true if the DM22 was for an active DTC, false for previously active
std::shared_ptr< ControlFunction > destination
Destination for the DM22 message.
std::uint8_t failureModeIdentifier
FMI of the DTC for the DM22.