Line data Source code
1 : // Copyright 2024 Accenture.
2 :
3 : #include "can/transceiver/AbstractCANTransceiver.h"
4 :
5 : #include <bsp/timer/SystemTimer.h>
6 : #include <interrupts/SuspendResumeAllInterruptsScopedLock.h>
7 :
8 : #include <platform/config.h>
9 :
10 : #include <cstring>
11 :
12 : namespace can
13 : {
14 : using interrupts::SuspendResumeAllInterruptsScopedLock;
15 :
16 48 : AbstractCANTransceiver::AbstractCANTransceiver(uint8_t const busId)
17 48 : : _filter()
18 48 : , _listeners()
19 48 : , _sentListener(nullptr)
20 48 : , _sentListeners()
21 48 : , _baudrate(0U)
22 48 : , _state(State::CLOSED)
23 48 : , _busId(busId)
24 48 : , _stateListener(nullptr)
25 48 : , _transceiverState(ICANTransceiverStateListener::CANTransceiverState::ACTIVE)
26 48 : {}
27 :
28 13 : void AbstractCANTransceiver::addCANFrameListener(ICANFrameListener& listener)
29 : {
30 13 : ESR_UNUSED const SuspendResumeAllInterruptsScopedLock lock;
31 13 : if (!_listeners.contains_node(listener))
32 : {
33 10 : _listeners.push_back(listener);
34 10 : listener.getFilter().acceptMerger(_filter);
35 : }
36 13 : }
37 :
38 3 : void AbstractCANTransceiver::addVIPCANFrameListener(ICANFrameListener& listener)
39 : {
40 3 : ESR_UNUSED const SuspendResumeAllInterruptsScopedLock lock;
41 3 : if (!_listeners.contains_node(listener))
42 : {
43 2 : _listeners.push_front(listener);
44 2 : listener.getFilter().acceptMerger(_filter);
45 : }
46 3 : }
47 :
48 12 : void AbstractCANTransceiver::removeCANFrameListener(ICANFrameListener& listener)
49 : {
50 12 : ESR_UNUSED const SuspendResumeAllInterruptsScopedLock lock;
51 12 : _listeners.erase(listener);
52 12 : }
53 :
54 5 : void AbstractCANTransceiver::addCANFrameSentListener(IFilteredCANFrameSentListener& listener)
55 : {
56 5 : ESR_UNUSED const SuspendResumeAllInterruptsScopedLock lock;
57 5 : _sentListeners.push_front(listener);
58 5 : }
59 :
60 5 : void AbstractCANTransceiver::removeCANFrameSentListener(IFilteredCANFrameSentListener& listener)
61 : {
62 5 : ESR_UNUSED const SuspendResumeAllInterruptsScopedLock lock;
63 5 : _sentListeners.erase(listener);
64 5 : }
65 :
66 5 : void AbstractCANTransceiver::notifyListeners(CANFrame const& frame)
67 : {
68 5 : if (_state == State::CLOSED)
69 : {
70 1 : return; // don't receive messages in state CLOSED
71 : }
72 :
73 19 : for (auto& listener : _listeners)
74 : {
75 15 : if (listener.getFilter().match(frame.getId()))
76 : {
77 7 : listener.frameReceived(frame);
78 : }
79 : }
80 : }
81 :
82 22 : void AbstractCANTransceiver::notifySentListeners(can::CANFrame const& frame)
83 : {
84 22 : if (_sentListeners.empty())
85 : {
86 18 : return;
87 : }
88 :
89 4 : const_cast<can::CANFrame&>(frame).setTimestamp(getSystemTimeUs32Bit());
90 9 : for (auto& sentListener : _sentListeners)
91 : {
92 5 : sentListener.canFrameSent(frame);
93 : }
94 : }
95 :
96 : } // namespace can
|