|
#include <isobus/hardware_integration/can_hardware_interface.hpp> |
|
#include <isobus/hardware_integration/socket_can_interface.hpp> |
|
#include <isobus/isobus/can_network_manager.hpp> |
|
#include <isobus/isobus/can_parameter_group_number_request_protocol.hpp> |
|
|
|
#include <iostream> |
|
#include <csignal> |
|
|
|
#include "shared_utils.hpp" |
|
|
|
|
|
std::atomic<bool> running(true); |
|
|
|
void signal_handler(int signal) { |
|
running = false; |
|
} |
|
|
|
std::vector<isobus::NAMEFilter> create_partner_cf_mask(std::uint8_t identity) { |
|
return { |
|
isobus::NAMEFilter{isobus::NAME::NAMEParameters::IdentityNumber, identity} |
|
}; |
|
} |
|
|
|
struct PCFContainer { |
|
std::shared_ptr<isobus::PartneredControlFunction> pcf; |
|
uint8_t identity; |
|
PCFContainer(std::shared_ptr<isobus::PartneredControlFunction> pcf, std::uint8_t identity) : pcf(pcf), identity(identity) { |
|
|
|
} |
|
~PCFContainer() = default; |
|
}; |
|
|
|
void messageCallbackOne(const isobus::CANMessage& message, void* target) { |
|
auto container = reinterpret_cast<PCFContainer*>(target); |
|
auto sourceId = message.get_source_control_function()->get_NAME().get_identity_number(); |
|
auto expectedId = container->identity; |
|
|
|
if (message.get_source_control_function() != container->pcf) { |
|
printf("Warning: Received message from unexpected CF. Expected ID %d, got ID %d\n", |
|
expectedId, sourceId); |
|
} else { |
|
printf("Normal. Received message from expected CF with ID %d\n", sourceId); |
|
} |
|
} |
|
|
|
void messageCallbackTwo(const isobus::CANMessage& message, void* target) { |
|
auto container = reinterpret_cast<PCFContainer*>(target); |
|
auto sourceId = message.get_source_control_function()->get_NAME().get_identity_number(); |
|
auto expectedId = container->identity; |
|
|
|
if (message.get_source_control_function() != container->pcf) { |
|
printf("Warning: Received message from unexpected CF. Expected ID %d, got ID %d\n", |
|
expectedId, sourceId); |
|
} else { |
|
printf("Normal. Received message from expected CF with ID %d\n", sourceId); |
|
} |
|
} |
|
|
|
int main() { |
|
signal(SIGINT, signal_handler); |
|
|
|
// Set up two channels but both pointing to vcan0 |
|
std::shared_ptr<isobus::CANHardwarePlugin> canDriver0 = std::make_shared<isobus::SocketCANInterface>("vcan0"); |
|
|
|
// Configure for 2 channels |
|
isobus::CANHardwareInterface::set_number_of_can_channels(1); |
|
isobus::CANHardwareInterface::assign_can_channel_frame_handler(CH0, canDriver0); |
|
|
|
if (!isobus::CANHardwareInterface::start() || |
|
!canDriver0->get_is_valid()) { |
|
printf("Failed to start hardware interface\n"); |
|
return -1; |
|
} |
|
isobus::CANNetworkManager::CANNetwork.initialize(); |
|
|
|
// Setup OUR name |
|
isobus::NAME ourName; |
|
ourName.set_identity_number(1); |
|
|
|
// Create our control functions |
|
auto ourCF = isobus::CANNetworkManager::CANNetwork.create_internal_control_function( |
|
ourName, CH0, 0xd0); |
|
|
|
auto pcfFive = isobus::CANNetworkManager::CANNetwork.create_partnered_control_function( |
|
CH0, create_partner_cf_mask(5)); |
|
PCFContainer pcfFiveContainer = PCFContainer(pcfFive, 5); |
|
|
|
auto pcfTen = isobus::CANNetworkManager::CANNetwork.create_partnered_control_function( |
|
CH0, create_partner_cf_mask(10)); |
|
PCFContainer pcfTenContainer = PCFContainer(pcfTen, 10); |
|
|
|
pcfFive->add_parameter_group_number_callback( |
|
static_cast<std::uint32_t>(isobus::CANLibParameterGroupNumber::ProprietaryA), |
|
messageCallbackOne, &pcfFiveContainer, ourCF); |
|
pcfTen->add_parameter_group_number_callback( |
|
static_cast<std::uint32_t>(isobus::CANLibParameterGroupNumber::ProprietaryA), |
|
messageCallbackTwo, &pcfTenContainer, ourCF); |
|
|
|
make_address_claim(ourCF); |
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); |
|
|
|
while (running) { |
|
std::this_thread::sleep_for(std::chrono::milliseconds(100)); |
|
} |
|
|
|
return 0; |
|
} |