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