13#include "isobus/utility/system_timing.hpp"
22 m_isoname(ControlFunctionNAME),
23 m_portIndex(portIndex),
24 m_preferredAddress(preferredAddressValue)
34 std::default_random_engine generator;
35 std::uniform_int_distribution<unsigned int> distribution(0, 255);
41 AddressClaimStateMachine ::~AddressClaimStateMachine()
56 LOG_WARNING(
"[AC]: Address violation for address %u",
69 LOG_ERROR(
"[AC]: Our address was commanded to a new value, but our ISO NAME doesn't support changing our address.");
76 if (
nullptr == deviceAtOurPreferredAddress)
80 LOG_INFO(
"[AC]: Our address was commanded to a new value of %u", commandedAddress);
86 LOG_INFO(
"[AC]: Our address was commanded to a new value of %u, and an ECU at the target address is being evicted.", commandedAddress);
90 LOG_ERROR(
"[AC]: Our address was commanded to a new value of %u, but we cannot move to the target address.", commandedAddress);
147 const std::uint32_t addressContentionTime_ms = 250;
151 std::shared_ptr<ControlFunction> deviceAtOurPreferredAddress;
159 if ((
nullptr == deviceAtOurPreferredAddress) &&
179 if ((
nullptr == deviceAtOurPreferredAddress) ||
197 LOG_DEBUG(
"[AC]: Internal control function %016llx has claimed address %u on channel %u",
213 bool addressFound =
false;
215 for (std::uint8_t i = 128; i <= 235; i++)
225 LOG_DEBUG(
"[AC]: Internal control function %016llx could not use the preferred address, but has claimed address %u on channel %u",
236 LOG_CRITICAL(
"[AC]: Internal control function %016llx failed to claim an address on channel %u",
273 if (
nullptr != parentPointer)
282 case static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ParameterGroupNumberRequest):
284 const auto &messageData = message.
get_data();
285 std::uint32_t requestedPGN = messageData.at(0);
286 requestedPGN |= (
static_cast<std::uint32_t
>(messageData.at(1)) << 8);
287 requestedPGN |= (
static_cast<std::uint32_t
>(messageData.at(2)) << 16);
289 if ((
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::AddressClaim) == requestedPGN) &&
297 case static_cast<std::uint32_t
>(CANLibParameterGroupNumber::AddressClaim):
301 const auto &messageData = message.
get_data();
302 std::uint64_t NAMEClaimed = messageData.at(0);
303 NAMEClaimed |= (
static_cast<uint64_t
>(messageData.at(1)) << 8);
304 NAMEClaimed |= (
static_cast<uint64_t
>(messageData.at(2)) << 16);
305 NAMEClaimed |= (
static_cast<uint64_t
>(messageData.at(3)) << 24);
306 NAMEClaimed |= (
static_cast<uint64_t
>(messageData.at(4)) << 32);
307 NAMEClaimed |= (
static_cast<uint64_t
>(messageData.at(5)) << 40);
308 NAMEClaimed |= (
static_cast<uint64_t
>(messageData.at(6)) << 48);
309 NAMEClaimed |= (
static_cast<uint64_t
>(messageData.at(7)) << 56);
321 LOG_WARNING(
"[AC]: Internal control function %016llx on channel %u must re-arbitrate its address because it was stolen by another ECU with NAME %016llx.",
350 const std::uint8_t addressClaimRequestLength = 3;
351 const auto PGN =
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::AddressClaim);
352 std::uint8_t dataBuffer[addressClaimRequestLength];
354 dataBuffer[0] = (PGN & std::numeric_limits<std::uint8_t>::max());
355 dataBuffer[1] = ((PGN >> 8) & std::numeric_limits<std::uint8_t>::max());
356 dataBuffer[2] = ((PGN >> 16) & std::numeric_limits<std::uint8_t>::max());
361 static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ParameterGroupNumberRequest),
381 dataBuffer[0] =
static_cast<uint8_t
>(isoNAME);
382 dataBuffer[1] =
static_cast<uint8_t
>(isoNAME >> 8);
383 dataBuffer[2] =
static_cast<uint8_t
>(isoNAME >> 16);
384 dataBuffer[3] =
static_cast<uint8_t
>(isoNAME >> 24);
385 dataBuffer[4] =
static_cast<uint8_t
>(isoNAME >> 32);
386 dataBuffer[5] =
static_cast<uint8_t
>(isoNAME >> 40);
387 dataBuffer[6] =
static_cast<uint8_t
>(isoNAME >> 48);
388 dataBuffer[7] =
static_cast<uint8_t
>(isoNAME >> 56);
392 static_cast<std::uint32_t
>(CANLibParameterGroupNumber::AddressClaim),
Defines a class for managing the address claiming process.
Defines some PGNs that are used in the library or are very common.
The main class that manages the ISOBUS stack including: callbacks, Name to Address management,...
A class that acts as a logging sink. The intent is that someone could make their own derived class of...
Forward declare CANMessage.
std::uint8_t m_randomClaimDelay_ms
The random delay as required by the ISO11783 standard.
bool send_address_claim(std::uint8_t address)
Sends the address claim message.
void process_commanded_address(std::uint8_t commandedAddress)
Attempts to process a commanded address.
void update()
Updates the state machine, should be called periodically.
void set_current_state(State value)
Sets the current state machine state.
std::uint32_t m_timestamp_ms
A generic timestamp in milliseconds used to find timeouts.
std::uint8_t m_preferredAddress
The address we'd prefer to claim as (we may not get it)
std::uint8_t get_claimed_address() const
Returns the address claimed by the state machine or 0xFE if none claimed.
NAME m_isoname
The ISO NAME to claim as.
State get_current_state() const
Returns the current state of the state machine.
std::uint8_t m_portIndex
The CAN channel index to claim on.
std::uint8_t m_claimedAddress
The actual address we ended up claiming.
bool send_request_to_claim() const
Sends the PGN request for the address claim PGN.
State
Defines the state machine states for address claiming.
@ WaitForRequestContentionPeriod
State machine is waiting for the address claim contention period.
@ SendRequestForClaim
State machine is sending the request for address claim.
@ UnableToClaim
State machine could not claim an address.
@ SendReclaimAddressOnRequest
An ECU requested address claim, inform the bus of our current address.
@ None
Address claiming is uninitialized.
@ SendPreferredAddressClaim
State machine is claiming the preferred address.
@ WaitForClaim
State machine is waiting for the random delay time.
@ ContendForPreferredAddress
State machine is contending the preferred address.
@ SendArbitraryAddressClaim
State machine is claiming an address.
@ AddressClaimingComplete
Address claiming is complete and we have an address.
void on_address_violation()
Used to inform the address claim state machine that two CFs are using the same source address....
bool m_enabled
Enable/disable state for this state machine.
AddressClaimStateMachine(std::uint8_t preferredAddressValue, NAME ControlFunctionNAME, std::uint8_t portIndex)
The constructor of the state machine class.
void set_is_enabled(bool value)
Enables or disables the address claimer.
State m_currentState
The address claim state machine state.
static void process_rx_message(const CANMessage &message, void *parentPointer)
Processes a CAN message.
bool get_enabled() const
Returns if the address claimer is enabled.
@ PriorityDefault6
The default priority.
std::uint8_t get_source_address() const
Returns the source address of the frame encoded in the identifier.
std::uint32_t get_parameter_group_number() const
Returns the PGN encoded in the identifier.
A class that represents a generic CAN message of arbitrary length.
std::uint8_t get_can_port_index() const
Returns the CAN channel index associated with the message.
const std::vector< std::uint8_t > & get_data() const
Gets a reference to the data in the CAN message.
CANIdentifier get_identifier() const
Returns the identifier of the message.
void add_global_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent)
This is how you register a callback for any PGN destined for the global address (0xFF)
bool send_can_message_raw(std::uint32_t portIndex, std::uint8_t sourceAddress, std::uint8_t destAddress, std::uint32_t parameterGroupNumber, std::uint8_t priority, const void *data, std::uint32_t size, CANLibBadge< AddressClaimStateMachine >) const
Sends a CAN message using raw addresses. Used only by the stack.
std::shared_ptr< ControlFunction > get_control_function(std::uint8_t channelIndex, std::uint8_t address, CANLibBadge< AddressClaimStateMachine >) const
Called only by the stack, returns a control function based on certain port and address.
static CANNetworkManager CANNetwork
Static singleton of the one network manager. Use this to access stack functionality.
void remove_global_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent)
This is how you remove a callback for any PGN destined for the global address (0xFF)
A class that represents an ISO11783 control function NAME from an address claim.
bool get_arbitrary_address_capable() const
Returns if the ECU is capable of address arbitration.
std::uint64_t get_full_name() const
Gets the raw 64 bit NAME.
This namespace encompasses all of the ISO11783 stack's functionality to reduce global namespace pollu...
constexpr std::uint8_t NULL_CAN_ADDRESS
The NULL CAN address defined by J1939 and ISO11783.
constexpr std::uint8_t CAN_DATA_LENGTH
The length of a classical CAN frame.
constexpr std::uint8_t BROADCAST_CAN_ADDRESS
The global/broadcast CAN address.
constexpr std::uint32_t CAN_PORT_MAXIMUM
An arbitrary limit for memory consumption.