This is Unofficial EPICS BASE Doxygen Site
udpiiu Class Reference

#include "udpiiu.h"

+ Inheritance diagram for udpiiu:
+ Collaboration diagram for udpiiu:

Classes

class  noSocket
 

Public Member Functions

 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
 

Friends

class udpRecvThread
 
class udpiiu::SearchDestUDP
 
class udpiiu::SearchRespCallback
 
class udpiiu::M_repeaterTimerNotify
 

Detailed Description

Definition at line 79 of file udpiiu.h.

Constructor & Destructor Documentation

udpiiu::udpiiu ( epicsGuard< epicsMutex > &  cacGuard,
class epicsTimerQueueActive &  timerQueue,
epicsMutex &  callbackControl,
epicsMutex &  mutualExclusion,
cacContextNotify ctxNotifyIn,
class cac cac,
unsigned  port,
tsDLList< SearchDest > &  searchDestListIn 
)

Definition at line 115 of file udpiiu.cpp.

123  :
124  recvThread ( *this, ctxNotifyIn, cbMutexIn, "CAC-UDP",
129  m_repeaterTimerNotify ( *this ),
130  repeaterSubscribeTmr (
131  m_repeaterTimerNotify, timerQueue, cbMutexIn, ctxNotifyIn ),
132  govTmr ( *this, timerQueue, cacMutexIn ),
133  maxPeriod ( getMaxPeriod() ),
134  rtteMean ( minRoundTripEstimate ),
135  rtteMeanDev ( 0 ),
136  cacRef ( cac ),
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 ),
145  sock ( 0 ),
146  repeaterPort ( 0 ),
147  serverPort ( port ),
148  localPort ( 0 ),
149  shutdownCmd ( false ),
150  lastReceivedSeqNoIsValid ( false )
151 {
152  cacGuard.assertIdenticalMutex ( cacMutex );
153 
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;
158  }
159 
160  for ( unsigned i = 0; i < this->nTimers; i++ ) {
161  this->ppSearchTmr[i].reset (
162  new searchTimer ( *this, timerQueue, i, cacMutexIn,
163  i > this->beaconAnomalyTimerIndex ) );
164  }
165 
166  this->repeaterPort =
168  static_cast <unsigned short> (CA_REPEATER_PORT) );
169 
170  this->sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
171  if ( this->sock == INVALID_SOCKET ) {
172  char sockErrBuf[64];
174  sockErrBuf, sizeof ( sockErrBuf ) );
175  errlogPrintf ("CAC: unable to create datagram socket because = \"%s\"\n",
176  sockErrBuf );
177  throwWithLocation ( noSocket () );
178  }
179 
180 #ifdef IP_ADD_MEMBERSHIP
181  {
182  osiSockOptMcastLoop_t flag = 1;
183  if ( setsockopt ( this->sock, IPPROTO_IP, IP_MULTICAST_LOOP,
184  (char *) &flag, sizeof ( flag ) ) == -1 ) {
185  char sockErrBuf[64];
187  sockErrBuf, sizeof ( sockErrBuf ) );
188  errlogPrintf("CAC: failed to set mcast loopback\n");
189  }
190  }
191 #endif
192 
193 #ifdef IP_MULTICAST_TTL
194  {
196  long val;
198  val =1;
199  ttl = val;
200  if ( setsockopt(this->sock, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl))) {
201  char sockErrBuf[64];
203  sockErrBuf, sizeof ( sockErrBuf ) );
204  errlogPrintf("CAC: failed to set mcast ttl %d\n", ttl);
205  }
206  }
207 #endif
208 
209  int boolValue = true;
210  int status = setsockopt ( this->sock, SOL_SOCKET, SO_BROADCAST,
211  (char *) &boolValue, sizeof ( boolValue ) );
212  if ( status < 0 ) {
213  char sockErrBuf[64];
215  sockErrBuf, sizeof ( sockErrBuf ) );
216  errlogPrintf ("CAC: IP broadcasting enable failed because = \"%s\"\n",
217  sockErrBuf );
218  }
219 
220 #if 0
221  {
222  /*
223  * some concern that vxWorks will run out of mBuf's
224  * if this change is made joh 11-10-98
225  *
226  * bump up the UDP recv buffer
227  */
228  int size = 1u<<15u;
229  status = setsockopt ( this->sock, SOL_SOCKET, SO_RCVBUF,
230  (char *)&size, sizeof (size) );
231  if (status<0) {
232  char sockErrBuf[64];
233  epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) );
234  errlogPrintf ( "CAC: unable to set socket option SO_RCVBUF because \"%s\"\n",
235  sockErrBuf );
236  }
237  }
238 #endif
239 
240  // force a bind to an unconstrained address so we can obtain
241  // the local port number below
242  static const unsigned short PORT_ANY = 0u;
243  osiSockAddr addr;
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) );
249  if ( status < 0 ) {
250  char sockErrBuf[64];
252  sockErrBuf, sizeof ( sockErrBuf ) );
253  epicsSocketDestroy (this->sock);
254  errlogPrintf ( "CAC: unable to bind to an unconstrained address because = \"%s\"\n",
255  sockErrBuf );
256  throwWithLocation ( noSocket () );
257  }
258 
259  {
260  osiSockAddr tmpAddr;
261  osiSocklen_t saddr_length = sizeof ( tmpAddr );
262  status = getsockname ( this->sock, &tmpAddr.sa, &saddr_length );
263  if ( status < 0 ) {
264  char sockErrBuf[64];
266  sockErrBuf, sizeof ( sockErrBuf ) );
267  epicsSocketDestroy ( this->sock );
268  errlogPrintf ( "CAC: getsockname () error was \"%s\"\n", sockErrBuf );
269  throwWithLocation ( noSocket () );
270  }
271  if ( tmpAddr.sa.sa_family != AF_INET) {
272  epicsSocketDestroy ( this->sock );
273  errlogPrintf ( "CAC: UDP socket was not inet addr family\n" );
274  throwWithLocation ( noSocket () );
275  }
276  this->localPort = ntohs ( tmpAddr.ia.sin_port );
277  }
278 
279  /*
280  * load user and auto configured
281  * broadcast address list
282  */
283  ELLLIST dest;
284  ellInit ( & dest );
285  configureChannelAccessAddressList ( & dest, this->sock, this->serverPort );
286  while ( osiSockAddrNode *
287  pNode = reinterpret_cast < osiSockAddrNode * > ( ellGet ( & dest ) ) ) {
288  SearchDestUDP & searchDest = *
289  new SearchDestUDP ( pNode->addr, *this );
290  _searchDestList.add ( searchDest );
291  free ( pNode );
292  }
293 
294  /* add list of tcp name service addresses */
295  _searchDestList.add ( searchDestListIn );
296 
297  caStartRepeaterIfNotInstalled ( this->repeaterPort );
298 
299  this->pushVersionMsg ();
300 
301  // start timers and receive thread
302  for ( unsigned j =0; j < this->nTimers; j++ ) {
303  this->ppSearchTmr[j]->start ( cacGuard );
304  }
305  this->govTmr.start ();
306  this->repeaterSubscribeTmr.start ();
307  this->recvThread.start ();
308 }
#define CA_REPEATER_PORT
Definition: caProto.h:54
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
Definition: osdSock.c:117
Definition: cac.h:97
unsigned getInitializingThreadsPriority() const
Definition: cac.h:353
#define INVALID_SOCKET
Definition: osdSock.h:32
void add(T &item)
Definition: tsDLList.h:313
pvd::Status status
int osiSocklen_t
Definition: osdSock.h:36
int i
Definition: scan.c:967
struct sockaddr sa
Definition: osiSock.h:158
struct sockaddr_in ia
Definition: osiSock.h:157
ELLNODE * ellGet(ELLLIST *pList)
Deletes and returns the first node from a list.
Definition: ellLib.c:147
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
int osiSockOptMcastLoop_t
Definition: osdSock.h:37
LIBCOM_API unsigned int epicsStdCall epicsThreadGetStackSize(epicsThreadStackSizeClass size)
Definition: osdThread.c:466
void epicsSocketConvertErrnoToString(char *pBuf, unsigned bufSize)
LIBCOM_API SOCKET epicsStdCall epicsSocketCreate(int domain, int type, int protocol)
Definition: osdSock.c:71
void epicsStdCall caStartRepeaterIfNotInstalled(unsigned repeaterPort)
Definition: udpiiu.cpp:581
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.
Definition: envSubr.c:398
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
LIBCA_API void epicsStdCall configureChannelAccessAddressList(struct ELLLIST *pList, SOCKET sock, unsigned short port)
Definition: iocinf.cpp:183
LIBCOM_API long epicsStdCall envGetLongConfigParam(const ENV_PARAM *pParam, long *pLong)
Get value of a long configuration parameter.
Definition: envSubr.c:303
#define ellInit(PLIST)
Initialize a list type.
Definition: ellLib.h:76
void start()
Definition: udpiiu.cpp:380
LIBCOM_API const ENV_PARAM EPICS_CA_MCAST_TTL
static unsigned lowestPriorityLevelAbove(unsigned priority)
Definition: cac.cpp:362
List header type.
Definition: ellLib.h:56
#define throwWithLocation(parm)
int osiSockOptMcastTTL_t
Definition: osdSock.h:38
udpiiu::~udpiiu ( )
virtual

Definition at line 313 of file udpiiu.cpp.

314 {
315  {
316  epicsGuard < epicsMutex > cbGuard ( this->cbMutex );
317  epicsGuard < epicsMutex > guard ( this->cacMutex );
318  this->shutdown ( cbGuard, guard );
319  }
320 
321  tsDLIter < SearchDest > iter ( _searchDestList.firstIter () );
322  while ( iter.valid () )
323  {
324  SearchDest & curr ( *iter );
325  iter++;
326  delete & curr;
327  }
328 
329  epicsSocketDestroy ( this->sock );
330 }
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
Definition: osdSock.c:117
tsDLIterConst< T > firstIter() const
Definition: tsDLList.h:459
void shutdown(epicsGuard< epicsMutex > &cbGuard, epicsGuard< epicsMutex > &guard)
Definition: udpiiu.cpp:332

Member Function Documentation

void udpiiu::beaconAnomalyNotify ( epicsGuard< epicsMutex > &  guard)

Definition at line 1200 of file udpiiu.cpp.

1202 {
1203  for ( unsigned i = this->beaconAnomalyTimerIndex+1u;
1204  i < this->nTimers; i++ ) {
1205  this->ppSearchTmr[i]->moveChannels ( cacGuard,
1206  *this->ppSearchTmr[this->beaconAnomalyTimerIndex] );
1207  }
1208 }
int i
Definition: scan.c:967
void udpiiu::installDisconnectedChannel ( epicsGuard< epicsMutex > &  guard,
nciu chan 
)

Definition at line 1262 of file udpiiu.cpp.

1264 {
1265  chan.setServerAddressUnknown ( *this, guard );
1266  this->govTmr.installChan ( guard, chan );
1267 }
void setServerAddressUnknown(netiiu &newiiu, epicsGuard< epicsMutex > &guard)
Definition: nciu.cpp:183
void installChan(epicsGuard< epicsMutex > &, nciu &)
void udpiiu::installNewChannel ( epicsGuard< epicsMutex > &  guard,
nciu chan,
netiiu *&  piiu 
)

Definition at line 1255 of file udpiiu.cpp.

1257 {
1258  piiu = this;
1259  this->ppSearchTmr[0]->installChannel ( guard, chan );
1260 }
void udpiiu::show ( unsigned  level) const

Definition at line 1143 of file udpiiu.cpp.

1144 {
1145  epicsGuard < epicsMutex > guard ( this->cacMutex );
1146 
1147  ::printf ( "Datagram IO circuit (and disconnected channel repository)\n");
1148  if ( level > 1u ) {
1149  ::printf ("\trepeater port %u\n", this->repeaterPort );
1150  ::printf ("\tdefault server port %u\n", this->serverPort );
1151  ::printf ( "Search Destination List with %u items\n",
1152  _searchDestList.count () );
1153  if ( level > 2u ) {
1155  _searchDestList.firstIter () );
1156  while ( iter.valid () )
1157  {
1158  iter->show ( guard, level - 2 );
1159  iter++;
1160  }
1161  }
1162  }
1163  if ( level > 2u ) {
1164  ::printf ("\tsocket identifier %d\n", int(this->sock) );
1165  ::printf ("\tbytes in xmit buffer %u\n", this->nBytesInXmitBuf );
1166  ::printf ("\tshut down command bool %u\n", this->shutdownCmd );
1167  ::printf ( "\trecv thread exit signal:\n" );
1168  this->recvThread.show ( level - 2u );
1169  this->repeaterSubscribeTmr.show ( level - 2u );
1170  this->govTmr.show ( level - 2u );
1171  }
1172  if ( level > 3u ) {
1173  for ( unsigned i =0; i < this->nTimers; i++ ) {
1174  this->ppSearchTmr[i]->show ( level - 3u );
1175  }
1176  }
1177 }
int i
Definition: scan.c:967
void show(unsigned level) const
tsDLIterConst< T > firstIter() const
Definition: tsDLList.h:459
#define printf
Definition: epicsStdio.h:41
unsigned count() const
Definition: tsDLList.h:181
void show(unsigned level) const
Definition: udpiiu.cpp:390
void show(unsigned level) const
void udpiiu::shutdown ( epicsGuard< epicsMutex > &  cbGuard,
epicsGuard< epicsMutex > &  guard 
)

Definition at line 332 of file udpiiu.cpp.

335 {
336  // stop all of the timers
337  this->repeaterSubscribeTmr.shutdown ( cbGuard, guard );
338  this->govTmr.shutdown ( cbGuard, guard );
339  for ( unsigned i =0; i < this->nTimers; i++ ) {
340  this->ppSearchTmr[i]->shutdown ( cbGuard, guard );
341  }
342 
343  {
344  this->shutdownCmd = true;
345  epicsGuardRelease < epicsMutex > unguard ( guard );
346  {
347  epicsGuardRelease < epicsMutex > cbUnguard ( cbGuard );
348 
349  if ( ! this->recvThread.exitWait ( 0.0 ) ) {
350  unsigned tries = 0u;
351 
352  this->wakeupMsg ();
353 
354  // wait for recv threads to exit
355  double shutdownDelay = 1.0;
356  while ( ! this->recvThread.exitWait ( shutdownDelay ) ) {
357  this->wakeupMsg ();
358  if ( shutdownDelay < 16.0 ) {
359  shutdownDelay += shutdownDelay;
360  }
361  if ( ++tries > 3 ) {
362  fprintf ( stderr, "cac: timing out waiting for UDP thread shutdown\n" );
363  }
364  }
365  }
366  }
367  }
368 }
int i
Definition: scan.c:967
void shutdown(epicsGuard< epicsMutex > &cbGuard, epicsGuard< epicsMutex > &guard)
#define stderr
Definition: epicsStdio.h:32
void shutdown(epicsGuard< epicsMutex > &cbGuard, epicsGuard< epicsMutex > &guard)
bool exitWait(double delay)
Definition: udpiiu.cpp:385

Friends And Related Function Documentation

friend class udpiiu::M_repeaterTimerNotify
friend

Definition at line 305 of file udpiiu.h.

friend class udpiiu::SearchDestUDP
friend

Definition at line 303 of file udpiiu.h.

friend class udpiiu::SearchRespCallback
friend

Definition at line 304 of file udpiiu.h.

friend class udpRecvThread
friend

Definition at line 300 of file udpiiu.h.


The documentation for this class was generated from the following files: