/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* * * * L O S A L A M O S * Los Alamos National Laboratory * Los Alamos, New Mexico 87545 * * Copyright, 1986, The Regents of the University of California. * * * Author Jeffrey O. Hill * johill@lanl.gov * 505 665 1831 */ #ifndef udpiiuh #define udpiiuh #ifdef epicsExportSharedSymbols # define udpiiuh_accessh_epicsExportSharedSymbols # undef epicsExportSharedSymbols #endif #include "osiSock.h" #include "epicsThread.h" #include "epicsMemory.h" #include "epicsTime.h" #include "tsMinMax.h" #include "tsDLList.h" #ifdef udpiiuh_accessh_epicsExportSharedSymbols # define epicsExportSharedSymbols # include "shareLib.h" #endif #include "netiiu.h" #include "searchTimer.h" #include "disconnectGovernorTimer.h" #include "repeaterSubscribeTimer.h" #include "SearchDest.h" extern "C" void cacRecvThreadUDP ( void *pParam ); epicsShareFunc void epicsShareAPI caStartRepeaterIfNotInstalled ( unsigned repeaterPort ); epicsShareFunc void epicsShareAPI caRepeaterRegistrationMessage ( SOCKET sock, unsigned repeaterPort, unsigned attemptNumber ); extern "C" epicsShareFunc void caRepeaterThread ( void * pDummy ); epicsShareFunc void ca_repeater ( void ); class cac; class cacContextNotify; class udpRecvThread : private epicsThreadRunable { public: udpRecvThread ( class udpiiu & iiuIn, cacContextNotify &, epicsMutex &, const char * pName, unsigned stackSize, unsigned priority ); virtual ~udpRecvThread (); void start (); bool exitWait ( double delay ); void show ( unsigned level ) const; private: class udpiiu & iiu; epicsMutex & cbMutex; cacContextNotify & ctxNotify; epicsThread thread; void run(); }; static const double minRoundTripEstimate = 32e-3; // seconds static const double maxRoundTripEstimate = 30; // seconds static const double maxSearchPeriodDefault = 5.0 * 60.0; // seconds static const double maxSearchPeriodLowerLimit = 60.0; // seconds static const double beaconAnomalySearchPeriod = 5.0; // seconds class udpiiu : private netiiu, private searchTimerNotify, private disconnectGovernorNotify, private repeaterTimerNotify { public: udpiiu ( epicsGuard < epicsMutex > & cacGuard, class epicsTimerQueueActive &, epicsMutex & callbackControl, epicsMutex & mutualExclusion, cacContextNotify &, class cac &, unsigned port, tsDLList < SearchDest > & ); virtual ~udpiiu (); void installNewChannel ( epicsGuard < epicsMutex > &, nciu &, netiiu * & ); void installDisconnectedChannel ( epicsGuard < epicsMutex > &, nciu & ); void beaconAnomalyNotify ( epicsGuard < epicsMutex > & guard ); void shutdown ( epicsGuard < epicsMutex > & cbGuard, epicsGuard < epicsMutex > & guard ); void show ( unsigned level ) const; // exceptions class noSocket {}; private: class SearchDestUDP : public SearchDest { public: SearchDestUDP ( const osiSockAddr &, udpiiu & ); void searchRequest ( epicsGuard < epicsMutex > &, const char * pBuf, size_t bufLen ); void show ( epicsGuard < epicsMutex > &, unsigned level ) const; private: osiSockAddr _destAddr; udpiiu & _udpiiu; }; class SearchRespCallback : public SearchDest :: Callback { public: SearchRespCallback ( udpiiu & ); void notify ( const caHdr &, const void * pPayload, const osiSockAddr &, const epicsTime & ); void show ( epicsGuard < epicsMutex > &, unsigned level ) const; private: udpiiu & _udpiiu; }; char xmitBuf [MAX_UDP_SEND]; char recvBuf [MAX_UDP_RECV]; udpRecvThread recvThread; repeaterSubscribeTimer repeaterSubscribeTmr; disconnectGovernorTimer govTmr; tsDLList < SearchDest > _searchDestList; double maxPeriod; double rtteMean; double rtteMeanDev; cac & cacRef; mutable epicsMutex & cbMutex; mutable epicsMutex & cacMutex; epics_auto_ptr < epics_auto_ptr < class searchTimer >, eapt_array > ppSearchTmr; unsigned nBytesInXmitBuf; unsigned nTimers; unsigned beaconAnomalyTimerIndex; ca_uint32_t sequenceNumber; ca_uint32_t lastReceivedSeqNo; SOCKET sock; ca_uint16_t repeaterPort; ca_uint16_t serverPort; ca_uint16_t localPort; bool shutdownCmd; bool lastReceivedSeqNoIsValid; bool wakeupMsg (); void postMsg ( const osiSockAddr & net_addr, char *pInBuf, arrayElementCount blockSize, const epicsTime ¤Time ); bool pushDatagramMsg ( epicsGuard < epicsMutex > &, const caHdr & hdr, const void * pExt, ca_uint16_t extsize); typedef bool ( udpiiu::*pProtoStubUDP ) ( const caHdr &, const osiSockAddr &, const epicsTime & ); // UDP protocol dispatch table static const pProtoStubUDP udpJumpTableCAC[]; // UDP protocol stubs bool versionAction ( const caHdr &, const osiSockAddr &, const epicsTime & ); bool badUDPRespAction ( const caHdr &msg, const osiSockAddr &netAddr, const epicsTime & ); bool searchRespAction ( const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); bool exceptionRespAction ( const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); bool beaconAction ( const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); bool notHereRespAction ( const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); bool repeaterAckAction ( const caHdr &msg, const osiSockAddr &net_addr, const epicsTime & ); // netiiu stubs unsigned getHostName ( epicsGuard < epicsMutex > &, char * pBuf, unsigned bufLength ) const throw (); const char * pHostName ( epicsGuard < epicsMutex > & ) const throw (); bool ca_v41_ok ( epicsGuard < epicsMutex > & ) const; bool ca_v42_ok ( epicsGuard < epicsMutex > & ) const; unsigned requestMessageBytesPending ( epicsGuard < epicsMutex > & mutualExclusionGuard ); void flush ( epicsGuard < epicsMutex > & mutualExclusionGuard ); void writeRequest ( epicsGuard < epicsMutex > &, nciu &, unsigned type, arrayElementCount nElem, const void *pValue ); void writeNotifyRequest ( epicsGuard < epicsMutex > &, nciu &, netWriteNotifyIO &, unsigned type, arrayElementCount nElem, const void *pValue ); void readNotifyRequest ( epicsGuard < epicsMutex > &, nciu &, netReadNotifyIO &, unsigned type, arrayElementCount nElem ); void clearChannelRequest ( epicsGuard < epicsMutex > &, ca_uint32_t sid, ca_uint32_t cid ); void subscriptionRequest ( epicsGuard < epicsMutex > &, nciu &, netSubscription & ); void subscriptionUpdateRequest ( epicsGuard < epicsMutex > &, nciu &, netSubscription & ); void subscriptionCancelRequest ( epicsGuard < epicsMutex > &, nciu & chan, netSubscription & subscr ); void flushRequest ( epicsGuard < epicsMutex > & ); void requestRecvProcessPostponedFlush ( epicsGuard < epicsMutex > & ); osiSockAddr getNetworkAddress ( epicsGuard < epicsMutex > & ) const; void uninstallChan ( epicsGuard < epicsMutex > &, nciu & ); void uninstallChanDueToSuccessfulSearchResponse ( epicsGuard < epicsMutex > &, nciu &, const class epicsTime & currentTime ); double receiveWatchdogDelay ( epicsGuard < epicsMutex > & ) const; bool searchMsg ( epicsGuard < epicsMutex > &, ca_uint32_t id, const char * pName, unsigned nameLength ); // searchTimerNotify stubs double getRTTE ( epicsGuard < epicsMutex > & ) const; void updateRTTE ( epicsGuard < epicsMutex > &, double rtte ); bool pushVersionMsg (); void boostChannel ( epicsGuard < epicsMutex > & guard, nciu & chan ); void noSearchRespNotify ( epicsGuard < epicsMutex > &, nciu & chan, unsigned index ); bool datagramFlush ( epicsGuard < epicsMutex > &, const epicsTime & currentTime ); ca_uint32_t datagramSeqNumber ( epicsGuard < epicsMutex > & ) const; // disconnectGovernorNotify void govExpireNotify ( epicsGuard < epicsMutex > &, nciu & ); // repeaterTimerNotify void repeaterRegistrationMessage ( unsigned attemptNumber ); int printFormated ( epicsGuard < epicsMutex > & callbackControl, const char * pformat, ... ); udpiiu ( const udpiiu & ); udpiiu & operator = ( const udpiiu & ); friend class udpRecvThread; // These are needed for the vxWorks 5.5 compiler: friend class udpiiu::SearchDestUDP; friend class udpiiu::SearchRespCallback; }; #endif // udpiiuh