AgIsoStack++
A control-function-focused implementation of the major ISOBUS and J1939 protocols
Loading...
Searching...
No Matches
virtual_can_plugin.cpp
Go to the documentation of this file.
1//================================================================================================
8//================================================================================================
10
11namespace isobus
12{
13 std::mutex VirtualCANPlugin::mutex;
14 std::map<std::string, std::vector<std::shared_ptr<VirtualCANPlugin::VirtualDevice>>> VirtualCANPlugin::channels;
15
16 VirtualCANPlugin::VirtualCANPlugin(const std::string channel, const bool receiveOwnMessages) :
17 channel(channel),
18 receiveOwnMessages(receiveOwnMessages)
19 {
20 const std::lock_guard<std::mutex> lock(mutex);
21 ourDevice = std::make_shared<VirtualDevice>();
22 channels[channel].push_back(ourDevice);
23 }
24
26 {
27 // Prevent a deadlock in the read_frame() function
28 running = false;
29 ourDevice->condition.notify_one();
30 }
31
33 {
34 return running;
35 }
36
38 {
39 return channel;
40 }
41
43 {
44 running = true;
45 }
46
48 {
49 running = false;
50 ourDevice->condition.notify_one();
51 }
52
54 {
55 bool retVal = false;
56 const std::lock_guard<std::mutex> lock(mutex);
57 for (std::shared_ptr<VirtualDevice> device : channels[channel])
58 {
59 if (device->queue.size() < MAX_QUEUE_SIZE)
60 {
61 if (receiveOwnMessages || device != ourDevice)
62 {
63 device->queue.push_back(canFrame);
64 device->condition.notify_one();
65 retVal = true;
66 }
67 }
68 }
69 return retVal;
70 }
71
73 {
74 const std::lock_guard<std::mutex> lock(mutex);
75 ourDevice->queue.push_back(canFrame);
76 ourDevice->condition.notify_one();
77 }
78
80 {
81 return read_frame(canFrame, 1000);
82 }
83
84 bool VirtualCANPlugin::read_frame(isobus::CANMessageFrame &canFrame, std::uint32_t timeout) const
85 {
86 std::unique_lock<std::mutex> lock(mutex);
87 ourDevice->condition.wait_for(lock, std::chrono::milliseconds(timeout), [this] { return !ourDevice->queue.empty() || !running; });
88 if (!ourDevice->queue.empty())
89 {
90 canFrame = ourDevice->queue.front();
91 ourDevice->queue.pop_front();
92 return true;
93 }
94 return false;
95 }
96
98 {
99 const std::lock_guard<std::mutex> lock(mutex);
100 return ourDevice->queue.empty();
101 }
102
104 {
105 const std::lock_guard<std::mutex> lock(mutex);
106 ourDevice->queue.clear();
107 }
108}
A CAN frame for interfacing with a hardware layer, like socket CAN or other interface.
std::string get_channel_name() const
Returns the assigned virtual channel name.
void open() override
Connects to the socket.
const bool receiveOwnMessages
If true, the driver will receive its own messages.
void clear_queue() const
Clear the internal received message queue.
std::atomic_bool running
If true, the driver is running.
static constexpr size_t MAX_QUEUE_SIZE
The maximum size of the queue, mostly arbitrary.
const std::string channel
The virtual channel name.
bool write_frame(const isobus::CANMessageFrame &canFrame) override
Writes a frame to the bus (synchronous)
VirtualCANPlugin(const std::string channel="", const bool receiveOwnMessages=false)
Constructor for the virtual CAN driver.
bool read_frame(isobus::CANMessageFrame &canFrame) override
Returns a frame from the hardware (synchronous), or false if no frame can be read....
std::shared_ptr< VirtualDevice > ourDevice
A pointer to the virtual device of this instance.
bool get_queue_empty() const
Returns if the internal received message queue is empty or not.
bool get_is_valid() const override
Returns if the socket connection is valid.
static std::mutex mutex
Mutex to access channels and queues for thread safety.
void close() override
Closes the socket.
static std::map< std::string, std::vector< std::shared_ptr< VirtualDevice > > > channels
A channel is a vector of devices.
void write_frame_as_if_received(const isobus::CANMessageFrame &canFrame) const
Allows us to write messages as if we received them from the bus.
virtual ~VirtualCANPlugin()
Destructor for the virtual CAN driver.
This namespace encompasses all of the ISO11783 stack's functionality to reduce global namespace pollu...
An OS and hardware independent virtual CAN interface driver for testing purposes. Any instance connec...