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