124 recvThread ( *
this, ctxNotifyIn, cbMutexIn,
"CAC-UDP",
129 m_repeaterTimerNotify ( *
this ),
130 repeaterSubscribeTmr (
131 m_repeaterTimerNotify,
timerQueue, cbMutexIn, ctxNotifyIn ),
133 maxPeriod ( getMaxPeriod() ),
134 rtteMean ( minRoundTripEstimate ),
137 cbMutex ( cbMutexIn ),
138 cacMutex ( cacMutexIn ),
139 nTimers ( getNTimers(maxPeriod) ),
140 ppSearchTmr ( nTimers ),
141 nBytesInXmitBuf ( 0 ),
142 beaconAnomalyTimerIndex ( 0 ),
143 sequenceNumber ( 0 ),
144 lastReceivedSeqNo ( 0 ),
149 shutdownCmd (
false ),
150 lastReceivedSeqNoIsValid (
false )
154 double powerOfTwo = log ( beaconAnomalySearchPeriod / minRoundTripEstimate ) / log ( 2.0 );
155 this->beaconAnomalyTimerIndex = static_cast <
unsigned > ( powerOfTwo + 1.0 );
156 if ( this->beaconAnomalyTimerIndex >= this->nTimers ) {
157 this->beaconAnomalyTimerIndex = this->nTimers - 1;
160 for (
unsigned i = 0;
i < this->nTimers;
i++ ) {
161 this->ppSearchTmr[
i].reset (
163 i > this->beaconAnomalyTimerIndex ) );
174 sockErrBuf,
sizeof ( sockErrBuf ) );
175 errlogPrintf (
"CAC: unable to create datagram socket because = \"%s\"\n",
180 #ifdef IP_ADD_MEMBERSHIP 183 if ( setsockopt ( this->sock, IPPROTO_IP, IP_MULTICAST_LOOP,
184 (
char *) &flag,
sizeof ( flag ) ) == -1 ) {
187 sockErrBuf,
sizeof ( sockErrBuf ) );
193 #ifdef IP_MULTICAST_TTL 200 if ( setsockopt(this->sock, IPPROTO_IP, IP_MULTICAST_TTL, (
char*)&ttl,
sizeof(ttl))) {
203 sockErrBuf,
sizeof ( sockErrBuf ) );
209 int boolValue =
true;
210 int status = setsockopt ( this->sock, SOL_SOCKET, SO_BROADCAST,
211 (
char *) &boolValue,
sizeof ( boolValue ) );
215 sockErrBuf,
sizeof ( sockErrBuf ) );
216 errlogPrintf (
"CAC: IP broadcasting enable failed because = \"%s\"\n",
229 status = setsockopt ( this->sock, SOL_SOCKET, SO_RCVBUF,
230 (
char *)&size,
sizeof (size) );
234 errlogPrintf (
"CAC: unable to set socket option SO_RCVBUF because \"%s\"\n",
242 static const unsigned short PORT_ANY = 0u;
244 memset ( (
char *)&addr, 0 ,
sizeof (addr) );
245 addr.
ia.sin_family = AF_INET;
246 addr.
ia.sin_addr.s_addr = htonl ( INADDR_ANY );
247 addr.
ia.sin_port = htons ( PORT_ANY );
248 status = bind (this->sock, &addr.
sa, sizeof (addr) );
252 sockErrBuf,
sizeof ( sockErrBuf ) );
254 errlogPrintf (
"CAC: unable to bind to an unconstrained address because = \"%s\"\n",
262 status = getsockname ( this->sock, &tmpAddr.
sa, &saddr_length );
266 sockErrBuf,
sizeof ( sockErrBuf ) );
268 errlogPrintf (
"CAC: getsockname () error was \"%s\"\n", sockErrBuf );
271 if ( tmpAddr.
sa.sa_family != AF_INET) {
273 errlogPrintf (
"CAC: UDP socket was not inet addr family\n" );
276 this->localPort = ntohs ( tmpAddr.
ia.sin_port );
287 pNode = reinterpret_cast < osiSockAddrNode * > (
ellGet ( & dest ) ) ) {
288 SearchDestUDP & searchDest = *
289 new SearchDestUDP ( pNode->addr, *
this );
290 _searchDestList.
add ( searchDest );
295 _searchDestList.
add ( searchDestListIn );
299 this->pushVersionMsg ();
302 for (
unsigned j =0; j < this->nTimers; j++ ) {
303 this->ppSearchTmr[j]->start ( cacGuard );
305 this->govTmr.
start ();
306 this->repeaterSubscribeTmr.
start ();
307 this->recvThread.
start ();
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
unsigned getInitializingThreadsPriority() const
ELLNODE * ellGet(ELLLIST *pList)
Deletes and returns the first node from a list.
void assertIdenticalMutex(const T &) const
int osiSockOptMcastLoop_t
LIBCOM_API unsigned int epicsStdCall epicsThreadGetStackSize(epicsThreadStackSizeClass size)
void epicsSocketConvertErrnoToString(char *pBuf, unsigned bufSize)
LIBCOM_API SOCKET epicsStdCall epicsSocketCreate(int domain, int type, int protocol)
void epicsStdCall caStartRepeaterIfNotInstalled(unsigned repeaterPort)
LIBCOM_API const ENV_PARAM EPICS_CA_REPEATER_PORT
LIBCOM_API unsigned short epicsStdCall envGetInetPortConfigParam(const ENV_PARAM *pEnv, unsigned short defaultPort)
Get value of a port number configuration parameter.
int errlogPrintf(const char *pFormat,...)
LIBCA_API void epicsStdCall configureChannelAccessAddressList(struct ELLLIST *pList, SOCKET sock, unsigned short port)
LIBCOM_API long epicsStdCall envGetLongConfigParam(const ENV_PARAM *pParam, long *pLong)
Get value of a long configuration parameter.
#define ellInit(PLIST)
Initialize a list type.
LIBCOM_API const ENV_PARAM EPICS_CA_MCAST_TTL
static unsigned lowestPriorityLevelAbove(unsigned priority)
#define throwWithLocation(parm)