#ifndef CPSW_RSSI_H #define CPSW_RSSI_H #include #include #include #include #include #include #include #include #include #include using boost::weak_ptr; using boost::atomic; #define RSSI_DEBUG 0 // level #ifdef RSSI_DEBUG extern int rssi_debug; #endif class IRxEventHandler : public IEventHandler { protected: virtual void handleRxEvent(IIntEventSource*) = 0; virtual void handle(IIntEventSource *s) { handleRxEvent(s); } }; class IUsrInputEventHandler : public IEventHandler { protected: virtual void handleUsrInputEvent(IIntEventSource*) = 0; virtual void handle(IIntEventSource *s) { handleUsrInputEvent(s); } }; class IUsrOutputEventHandler : public IEventHandler { protected: virtual void handleUsrOutputEvent(IIntEventSource*) = 0; virtual void handle(IIntEventSource *s) { handleUsrOutputEvent(s); } }; class IRexTimer : public RssiTimer { protected: virtual void processRetransmissionTimeout() = 0; public: IRexTimer(RssiTimerList *l) : RssiTimer("REX", l) {} virtual void process() { processRetransmissionTimeout(); } }; class IAckTimer : public RssiTimer { protected: virtual void processAckTimeout() = 0; public: IAckTimer(RssiTimerList *l) : RssiTimer("ACK", l) {} virtual void process() { processAckTimeout(); } }; class INulTimer : public RssiTimer { protected: virtual void processNulTimeout() = 0; public: INulTimer(RssiTimerList *l) : RssiTimer("NUL", l) {} virtual void process() { processNulTimeout(); } }; // currently posts events when the state is changed to // the defined target state (currently: open/closed) class CConnectionStateEventSource : public IIntEventSource { protected: atomic connState_; static const int CONN_STATE_OPEN = 10; // could support other states static const int CONN_STATE_CLOSED = -1; public: CConnectionStateEventSource(); virtual void connectionStateChanged(int); }; class CConnectionOpenEventSource : public CConnectionStateEventSource { public: CConnectionOpenEventSource(); protected: virtual bool checkForEvent(); }; class CConnectionNotOpenEventSource : public CConnectionStateEventSource { public: CConnectionNotOpenEventSource(); protected: virtual bool checkForEvent(); }; class CConnectionClosedEventSource : public CConnectionStateEventSource { public: CConnectionClosedEventSource(); protected: virtual bool checkForEvent(); }; class CRssi : public CRunnable, public IRxEventHandler, public IUsrInputEventHandler, public IUsrOutputEventHandler, public IRexTimer, public IAckTimer, public INulTimer, public CConnectionOpenEventSource, public CConnectionNotOpenEventSource, public CConnectionClosedEventSource { public: static const uint8_t LD_MAX_UNACKED_SEGS = 4; static const uint8_t MAX_UNACKED_SEGS = 1< buf_; BufIdx rp_; BufIdx msk_; SeqNo oldest_; public: BufBase(unsigned ldsz) : buf_( (capa_= (1<rp_) {} iterator & operator++() { if ( idx_ != rb_->wp_ ) idx_++; return *this; } BufChain operator*() { if ( idx_ == rb_->wp_ ) return BufChain(); return rb_->buf_.at( (idx_ & rb_->msk_) ); } }; iterator begin() { return iterator(this); } unsigned getSize() { return (unsigned)(wp_ - rp_); } int ack(SeqNo ackNo) { SeqNo cumAck = ackNo - oldest_ + 1; unsigned i; if ( cumAck > getSize() ) { // an error -- misformed packet? // the caller should discard... return -1; } for ( i=0; i capa_ ) { // should never happen since we must // not have more than ossMX outstanding // transmits throw InternalError("RingBuf Overflow"); } buf_[ widx ] = b; wp_++; } void resize(unsigned new_capa) { unsigned i; unsigned sz = getSize(); std::vector tmp( sz ); SeqNo tmpo = getOldest(); for ( i=0; itv_ ) ) throw InternalError("clock_gettime failed"); } virtual void forceACK() { numCak_ = cakMX_; } virtual void * threadBody(); virtual void changeState(STATE *newState); virtual bool threadStop(); }; #endif