AgIsoStack++
A control-function-focused implementation of the major ISOBUS and J1939 protocols
Loading...
Searching...
No Matches
toucan_vscp_canal.cpp
Go to the documentation of this file.
1//================================================================================================
10//================================================================================================
11
14#include "isobus/utility/to_string.hpp"
15
16#include <thread>
17
18namespace isobus
19{
20 TouCANPlugin::TouCANPlugin(std::int16_t deviceID, std::uint32_t serialNumber, std::uint16_t baudRate)
21 {
22 generate_device_name(deviceID, serialNumber, baudRate);
23 }
24
25 TouCANPlugin::TouCANPlugin(std::string deviceName) :
26 name(deviceName)
27 {
28 }
29
33
35 {
36 return (CANAL_ERROR_SUCCESS == openResult);
37 }
38
40 {
41 CanalClose(handle);
42 openResult = CANAL_ERROR_NOT_OPEN;
43 }
44
46 {
47 long tempHandle = CanalOpen(name.c_str(), 0);
48
49 if (0 != tempHandle)
50 {
51 handle = tempHandle;
52 openResult = CANAL_ERROR_SUCCESS;
53 }
54 else
55 {
56 LOG_CRITICAL("[TouCAN]: Error trying to connect to TouCAN probe. Check your device ID and serial number.");
57 }
58 }
59
61 {
62 long result = CANAL_ERROR_GENERIC;
63 structCanalMsg CANMsg = { 0 };
64
65 result = CanalReceive(handle, &CANMsg);
66
67 if (CANAL_ERROR_SUCCESS == result)
68 {
69 canFrame.dataLength = CANMsg.sizeData;
70 memcpy(canFrame.data, CANMsg.data, sizeof(canFrame.data));
71 canFrame.identifier = CANMsg.id;
72 canFrame.isExtendedFrame = (0 != (CANAL_IDFLAG_EXTENDED & CANMsg.flags));
73 canFrame.timestamp_us = CANMsg.timestamp;
74 }
75 else
76 {
77 std::this_thread::sleep_for(std::chrono::milliseconds(1));
78 }
79 return (CANAL_ERROR_SUCCESS == result);
80 }
81
83 {
84 std::uint32_t result = CANAL_ERROR_SUCCESS;
85 structCanalMsg msgCanMessage;
86
87 msgCanMessage.id = canFrame.identifier;
88 msgCanMessage.sizeData = canFrame.dataLength;
89 msgCanMessage.flags = canFrame.isExtendedFrame ? CANAL_IDFLAG_EXTENDED : CANAL_IDFLAG_STANDARD;
90 memcpy(msgCanMessage.data, canFrame.data, canFrame.dataLength);
91
92 result = CanalSend(handle, &msgCanMessage);
93
94 return (CANAL_ERROR_SUCCESS == result);
95 }
96
97 bool TouCANPlugin::reconfigure(std::int16_t deviceID, std::uint32_t serialNumber, std::uint16_t baudRate)
98 {
99 bool retVal = false;
100
101 if (!get_is_valid())
102 {
103 generate_device_name(deviceID, serialNumber, baudRate);
104 retVal = true;
105 }
106 return retVal;
107 }
108
110 {
112 }
113
114 void TouCANPlugin::generate_device_name(std::int16_t deviceID, std::uint32_t serialNumber, std::uint16_t baudRate)
115 {
116 std::string deviceConfigString;
117 std::string serialString;
118 constexpr std::uint32_t MAX_SERIAL_LENGTH = 999999999;
119 constexpr std::size_t SERIAL_NUMBER_CHARACTER_REQUIREMENT = 8;
120
121 if (serialNumber > MAX_SERIAL_LENGTH)
122 {
123 LOG_CRITICAL("[TouCAN]: Invalid serial number. Must be 8 digits max.");
124 serialNumber = 0;
125 }
126 currentlyConfiguredSerialNumber = serialNumber;
127 serialString = isobus::to_string(serialNumber);
128
129 if (SERIAL_NUMBER_CHARACTER_REQUIREMENT > serialString.length())
130 {
131 serialString.insert(0, SERIAL_NUMBER_CHARACTER_REQUIREMENT - serialString.length(), '0');
132 }
133
134 deviceConfigString += isobus::to_string(deviceID) + ';';
135 deviceConfigString += serialString + ';';
136 deviceConfigString += isobus::to_string(baudRate) + ';';
137 name = deviceConfigString;
138 }
139}
A class that acts as a logging sink. The intent is that someone could make their own derived class of...
A CAN frame for interfacing with a hardware layer, like socket CAN or other interface.
std::uint8_t dataLength
The length of the data used in the frame.
std::uint32_t identifier
The 32 bit identifier of the frame.
std::uint64_t timestamp_us
A microsecond timestamp.
bool isExtendedFrame
Denotes if the frame is extended format.
std::uint8_t data[8]
The data payload of the frame.
virtual ~TouCANPlugin()
The destructor for TouCANPlugin.
std::uint32_t currentlyConfiguredSerialNumber
The serial number of the device that is being used.
void close() override
Closes the connection to the hardware.
TouCANPlugin(std::int16_t deviceID, std::uint32_t serialNumber, std::uint16_t baudRate=250)
Constructor for a TouCAN hardware plugin object.
std::string name
A configuration string that is used to connect to the hardware through the CANAL api.
bool write_frame(const isobus::CANMessageFrame &canFrame) override
Writes a frame to the bus (synchronous)
std::uint32_t handle
The handle that the driver returns to us for the open hardware.
void open() override
Connects to the hardware.
void generate_device_name(std::int16_t deviceID, std::uint32_t serialNumber, std::uint16_t baudRate)
Generates a device name string for the TouCAN device.
std::uint32_t openResult
Stores the result of the call to begin CAN communication. Used for is_valid check later.
std::uint32_t get_serial_number() const
Returns the currently configured serial number of the device which will be used to connect to the har...
bool reconfigure(std::int16_t deviceID, std::uint32_t serialNumber, std::uint16_t baudRate=250)
Changes previously set configuration parameters. Only works if the device is not open.
bool read_frame(isobus::CANMessageFrame &canFrame) override
Returns a frame from the hardware (synchronous), or false if no frame can be read.
bool get_is_valid() const override
Returns if the connection with the hardware is valid.
This namespace encompasses all of the ISO11783 stack's functionality to reduce global namespace pollu...
An interface for using a Rusoku TouCAN device via the VSCP CANAL api.