Line data Source code
1 : // Copyright 2024 Accenture. 2 : 3 : /** 4 : * Contains class AbstractCANTransceiver. 5 : * \file AbstractCANTransceiver.h 6 : * \ingroup transceiver 7 : */ 8 : #pragma once 9 : 10 : #include "can/canframes/BufferedCANFrame.h" 11 : #include "can/framemgmt/AbstractBitFieldFilteredCANFrameListener.h" 12 : #include "can/framemgmt/AbstractIntervalFilteredCANFrameListener.h" 13 : #include "can/framemgmt/IFilteredCANFrameSentListener.h" 14 : #include "can/transceiver/ICANTransceiverStateListener.h" 15 : #include "can/transceiver/ICanTransceiver.h" 16 : 17 : #include <estd/forward_list.h> 18 : #include <platform/estdint.h> 19 : 20 : namespace can 21 : { 22 : class ICANFrameSentListener; 23 : class IFilteredCANFrameSentListener; 24 : class FrameDispatcher; 25 : class CanTransportLayer; 26 : 27 : /** 28 : * Cpp2CAN AbstractCANTransceiver 29 : * \class AbstractCANTransceiver 30 : * 31 : * 32 : * An AbstractCANTransceiver is the common hardware independent base class for 33 : * CanTransceiverS classes. This base implementation or the ICanTransceiver interface 34 : * shall be used in all applications to avoid HW dependencies. 35 : * 36 : * This abstract class implements the HW independent methods. 37 : * 38 : * \section Reception 39 : * An implementation of AbstractCANTransceiver has to fill a CANFrame object 40 : * with the data of the received can frame and then call 41 : * notifyListeners() with the received CANFrame which distributes it to all 42 : * listeners, i.e. to all listeners whose filter match the id of fRxFrame. 43 : * 44 : */ 45 : class AbstractCANTransceiver : public ICanTransceiver 46 : { 47 : public: 48 : /** 49 : * constructor 50 : * \param busId busId of MultiChannelCanTransceiver 51 : * \post getState() == CLOSED 52 : */ 53 : explicit AbstractCANTransceiver(uint8_t busId); 54 : 55 : /** 56 : * \return internal state of transceiver 57 : * \see State 58 : */ 59 : State getState() const override; 60 : 61 : /** 62 : * adds an ICANFrameListener to listener list 63 : * \param canFrameListener listener to register 64 : * 65 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts. 66 : * 67 : * \attention 68 : * The filter of canFrameListener is merged into the transceivers rx-filter. 69 : * It must be configured before adding the listener! 70 : */ 71 : void addCANFrameListener(ICANFrameListener& listener) override; 72 : 73 : /** 74 : * Adds a listener to the front of the receiver list. 75 : * \see addCANFrameListener 76 : * Using this method makes sure that the added listener is notified first 77 : * of a incoming CANFrame. 78 : */ 79 : void addVIPCANFrameListener(ICANFrameListener& listener) override; 80 : 81 : /** 82 : * removes an ICANFrameListener from listener list 83 : * \param canFrameListener listener to remove 84 : * 85 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts. 86 : * 87 : * \note 88 : * The elements of canFrameListeners filter will not be removed from 89 : * the transceivers rx-filter. 90 : */ 91 : void removeCANFrameListener(ICANFrameListener& listener) override; 92 : 93 : /** 94 : * adds an addCANFrameSentListener to listener list 95 : * \param listener listener to register 96 : * 97 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts. 98 : * 99 : * \attention 100 : * The filter of listener is merged into the transceivers rx-filter. 101 : * It must be configured before adding the listener! 102 : */ 103 : void addCANFrameSentListener(IFilteredCANFrameSentListener& listener) override; 104 : 105 : /** 106 : * removes an ICANFrameListener from listener list 107 : * \param listener listener to remove 108 : * 109 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts. 110 : * 111 : * \note 112 : * The elements of listener filter will not be removed from 113 : * the transceivers rx-filter. 114 : */ 115 : void removeCANFrameSentListener(IFilteredCANFrameSentListener& listener) override; 116 : 117 : /** 118 : * \return busId of transceiver 119 : */ 120 0 : uint8_t getBusId() const override { return _busId; } 121 : 122 : /** 123 : * Get the hardware state of the CAN transceiver. 124 : * \return state hardware state of the CAN transceiver 125 : */ 126 1 : ICANTransceiverStateListener::CANTransceiverState getCANTransceiverState() const override 127 : { 128 1 : return _transceiverState; 129 : } 130 : 131 : /** 132 : * Sets the transceivers ICANTransceiverStateListener. 133 : * \param pListener ICANTransceiverStateListener to notify when an error 134 : * occurrs. 0L if no class needs to be notified. 135 : */ 136 1 : void setStateListener(ICANTransceiverStateListener& listener) override 137 : { 138 1 : _stateListener = &listener; 139 1 : } 140 : 141 1 : void removeStateListener() override { _stateListener = nullptr; } 142 : 143 : /** 144 : * \note OBSOLETE INTERFACE 145 : * 146 : * Please use addCANFrameSentListener() 147 : * 148 : * Sets and ICANFrameSentListener that gets called when a frame has been 149 : * sent. There is only one listener possible. 150 : * \param pListener 151 : */ 152 : void setCANFrameSentListener(IFilteredCANFrameSentListener* pListener) override; 153 : 154 : protected: 155 : void setState(State newState); 156 : 157 : bool isInState(State state) const; 158 : 159 : /** 160 : * Notifies all appropriate listeners about the reception of a CANFrame. 161 : * \param frame CANFrame that will be passed to all listeners 162 : */ 163 : void notifyListeners(CANFrame const& frame); 164 : 165 : void notifySentListeners(can::CANFrame const& frame); 166 : 167 : /** 168 : * Notifies the attached ICANTransceiverStateListener that a phy error occurred 169 : */ 170 3 : void notifyStateListenerWithPhyError() 171 : { 172 3 : if (_stateListener != nullptr) 173 : { 174 1 : _stateListener->phyErrorOccurred(*this); 175 : } 176 3 : } 177 : 178 : /** 179 : * Notifies the attached ICANTransceiverStateListener with a given 180 : * state 181 : * \param state new can transceiver state. 182 : */ 183 : void notifyStateListenerWithState(ICANTransceiverStateListener::CANTransceiverState state); 184 : 185 : protected: 186 : BitFieldFilter _filter; 187 : ::estd::forward_list<ICANFrameListener> _listeners; 188 : IFilteredCANFrameSentListener* _sentListener; 189 : ::estd::forward_list<IFilteredCANFrameSentListener> _sentListeners; 190 : /** baudrate of transceiver */ 191 : uint32_t _baudrate; 192 : /** internal State */ 193 : State _state; 194 : uint8_t _busId; 195 : ICANTransceiverStateListener* _stateListener; 196 : ICANTransceiverStateListener::CANTransceiverState _transceiverState; 197 : }; 198 : 199 2 : inline ICanTransceiver::State AbstractCANTransceiver::getState() const { return _state; } 200 : 201 : // virtual 202 : inline void 203 7 : AbstractCANTransceiver::setCANFrameSentListener(IFilteredCANFrameSentListener* const pListener) 204 : { 205 5 : if (nullptr != pListener) 206 : { 207 3 : _sentListener = pListener; 208 3 : addCANFrameSentListener(*pListener); 209 : } 210 4 : else if (nullptr != _sentListener) 211 : { 212 3 : removeCANFrameSentListener(*_sentListener); 213 3 : _sentListener = nullptr; 214 : } 215 : else 216 : { 217 : // nothing to do 218 : } 219 5 : } 220 : 221 2 : inline void AbstractCANTransceiver::setState(ICanTransceiver::State const newState) 222 : { 223 2 : _state = newState; 224 : } 225 : 226 2 : inline bool AbstractCANTransceiver::isInState(ICanTransceiver::State const state) const 227 : { 228 2 : return (_state == state); 229 : } 230 : 231 6 : inline void AbstractCANTransceiver::notifyStateListenerWithState( 232 : ICANTransceiverStateListener::CANTransceiverState const state) 233 : { 234 6 : if (_stateListener != nullptr) 235 : { 236 1 : _stateListener->canTransceiverStateChanged(*this, state); 237 : } 238 6 : } 239 : 240 : } // namespace can