22 # pragma warning(disable:4355) 25 #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" 44 const udpiiu::pProtoStubUDP udpiiu::udpJumpTableCAC [] =
46 &udpiiu::versionAction,
47 &udpiiu::badUDPRespAction,
48 &udpiiu::badUDPRespAction,
49 &udpiiu::badUDPRespAction,
50 &udpiiu::badUDPRespAction,
51 &udpiiu::badUDPRespAction,
52 &udpiiu::searchRespAction,
53 &udpiiu::badUDPRespAction,
54 &udpiiu::badUDPRespAction,
55 &udpiiu::badUDPRespAction,
56 &udpiiu::badUDPRespAction,
57 &udpiiu::exceptionRespAction,
58 &udpiiu::badUDPRespAction,
59 &udpiiu::beaconAction,
60 &udpiiu::notHereRespAction,
61 &udpiiu::badUDPRespAction,
62 &udpiiu::badUDPRespAction,
63 &udpiiu::repeaterAckAction,
70 double maxPeriod = maxSearchPeriodDefault;
76 if ( maxPeriod < maxSearchPeriodLowerLimit ) {
79 maxPeriod = maxSearchPeriodLowerLimit;
96 unsigned getNTimers(
double maxPeriod)
98 unsigned nTimers = static_cast <
unsigned > ( 1.0 + log ( maxPeriod / minRoundTripEstimate ) / log ( 2.0 ) );
106 (1<<(nTimers-1)) * minRoundTripEstimate );
124 recvThread ( *this, ctxNotifyIn, cbMutexIn,
"CAC-UDP",
126 cac::lowestPriorityLevelAbove (
127 cac::lowestPriorityLevelAbove (
128 cac.getInitializingThreadsPriority () ) ) ),
129 m_repeaterTimerNotify ( *this ),
130 repeaterSubscribeTmr (
131 m_repeaterTimerNotify, timerQueue, cbMutexIn, ctxNotifyIn ),
132 govTmr ( *this, timerQueue, cacMutexIn ),
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 ();
322 while ( iter.valid () )
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 );
344 this->shutdownCmd =
true;
349 if ( ! this->recvThread.
exitWait ( 0.0 ) ) {
355 double shutdownDelay = 1.0;
356 while ( ! this->recvThread.
exitWait ( shutdownDelay ) ) {
358 if ( shutdownDelay < 16.0 ) {
359 shutdownDelay += shutdownDelay;
362 fprintf (
stderr,
"cac: timing out waiting for UDP thread shutdown\n" );
372 const char * pName,
unsigned stackSize,
unsigned priority ) :
373 iiu ( iiuIn ), cbMutex ( cbMutexIn ), ctxNotify ( ctxNotifyIn ),
374 thread ( *this, pName, stackSize, priority ) {}
382 this->thread.start ();
387 return this->thread.exitWait ( delay );
394 void udpRecvThread::run ()
398 if ( this->iiu._searchDestList.
count () == 0 ) {
408 int status = recvfrom ( this->iiu.sock,
409 this->iiu.recvBuf, sizeof ( this->iiu.recvBuf ), 0,
410 & src.
sa, & src_size );
429 sockErrBuf,
sizeof ( sockErrBuf ) );
435 else if ( status > 0 ) {
436 this->iiu.postMsg ( src, this->iiu.recvBuf,
440 }
while ( ! this->iiu.shutdownCmd );
444 udpiiu::M_repeaterTimerNotify::~M_repeaterTimerNotify ()
453 void udpiiu :: M_repeaterTimerNotify :: repeaterRegistrationMessage (
unsigned attemptNumber )
465 SOCKET sock,
unsigned repeaterPort,
unsigned attemptNumber )
472 assert ( repeaterPort <= USHRT_MAX );
473 unsigned short port = static_cast <
unsigned short> ( repeaterPort );
493 if ( attemptNumber & 1 ) {
495 if ( saddr.
sa.sa_family != AF_INET ) {
502 saddr.
ia.sin_family = AF_INET;
504 saddr.
ia.sin_port = htons ( port );
507 saddr.
ia.sin_port = htons ( port );
511 saddr.
ia.sin_family = AF_INET;
513 saddr.
ia.sin_port = htons ( port );
516 memset ( (
char *) &msg, 0,
sizeof (msg) );
527 # if defined ( DOES_NOT_ACCEPT_ZERO_LENGTH_UDP ) 533 status = sendto ( sock, (
char *) &msg, len, 0,
534 &saddr.
sa, sizeof ( saddr ) );
550 sockErrBuf,
sizeof ( sockErrBuf ) );
551 fprintf (
stderr,
"error sending registration message to CA repeater daemon was \"%s\"\n",
583 bool installed =
false;
587 struct sockaddr_in ia;
591 if ( repeaterPort > 0xffff ) {
592 fprintf (
stderr,
"caStartRepeaterIfNotInstalled () : strange repeater port specified\n" );
599 memset ( (
char *) &bd, 0,
sizeof ( bd ) );
600 bd.ia.sin_family = AF_INET;
601 bd.ia.sin_addr.s_addr = htonl ( INADDR_ANY );
602 bd.ia.sin_port = htons ( port );
603 status = bind ( tmpSock, &bd.sa, sizeof ( bd ) );
609 fprintf (
stderr,
"caStartRepeaterIfNotInstalled () : bind failed\n" );
638 fprintf (
stderr,
"caStartRepeaterIfNotInstalled : unable to create CA repeater daemon thread\n" );
642 fprintf (
stderr,
"caStartRepeaterIfNotInstalled (): unable to start CA repeater daemon detached process\n" );
647 bool udpiiu::badUDPRespAction (
653 currentTime.strftime ( date,
sizeof ( date ),
"%a %b %d %Y %H:%M:%S");
654 errlogPrintf (
"CAC: Undecipherable ( bad msg code %u ) UDP message from %s at %s\n",
659 bool udpiiu::versionAction (
666 this->lastReceivedSeqNo = hdr.
m_cid;
667 this->lastReceivedSeqNoIsValid =
true;
673 bool udpiiu :: searchRespAction (
681 if ( addr.
sa.sa_family != AF_INET ) {
691 if ( msg.
m_postsize >= sizeof ( minorVersion ) ){
697 reinterpret_cast <
const ca_uint8_t *> ( & msg + 1 );
698 unsigned byte0 = pPayLoad[0];
699 unsigned byte1 = pPayLoad[1];
700 minorVersion = ( byte0 << 8u ) | byte1;
711 serverAddr.
ia.sin_family = AF_INET;
712 if (
CA_V48 ( minorVersion ) ) {
713 if ( msg.
m_cid != INADDR_BROADCAST ) {
714 serverAddr.
ia.sin_addr.s_addr = htonl ( msg.
m_cid );
717 serverAddr.
ia.sin_addr = addr.
ia.sin_addr;
721 else if (
CA_V45 (minorVersion) ) {
723 serverAddr.
ia.sin_addr = addr.
ia.sin_addr;
726 serverAddr.
ia.sin_port = htons ( this->serverPort );
727 serverAddr.
ia.sin_addr = addr.
ia.sin_addr;
730 if (
CA_V42 ( minorVersion ) ) {
731 cacRef.transferChanToVirtCircuit
733 0, minorVersion, serverAddr, currentTime );
736 cacRef.transferChanToVirtCircuit
738 msg.
m_count, minorVersion, serverAddr, currentTime );
744 bool udpiiu::beaconAction (
748 struct sockaddr_in ina;
750 memset(&ina, 0,
sizeof(
struct sockaddr_in));
752 if ( net_addr.
sa.sa_family != AF_INET ) {
770 ina.sin_family = AF_INET;
773 ina.sin_port = htons ( msg.
m_count );
780 ina.sin_port = htons ( this->serverPort );
785 this->cacRef.beaconNotify ( ina, currentTime,
786 beaconNumber, protocolRevision );
791 bool udpiiu::repeaterAckAction (
795 this->repeaterSubscribeTmr.confirmNotify ();
799 bool udpiiu::notHereRespAction (
806 bool udpiiu::exceptionRespAction (
810 const caHdr &reqMsg = * ( &msg + 1 );
814 currentTime.strftime ( date,
sizeof ( date ),
"%a %b %d %Y %H:%M:%S");
818 "error condition \"%s\" detected by %s with context \"%s\" at %s\n",
820 name, reinterpret_cast <const char *> ( &reqMsg + 1 ), date );
824 "error condition \"%s\" detected by %s at %s\n",
831 void udpiiu::postMsg (
838 this->lastReceivedSeqNoIsValid =
false;
839 this->lastReceivedSeqNo = 0u;
841 while ( blockSize ) {
844 if ( blockSize <
sizeof ( *pCurMsg ) ) {
848 "%s: Undecipherable (too small) UDP msg from %s ignored\n",
853 pCurMsg = reinterpret_cast <
caHdr * > ( pInBuf );
866 printf (
"UDP Cmd=%3d Type=%3d Count=%4d Size=%4d",
871 printf (
" Avail=%8x Cid=%6d\n",
876 size = pCurMsg->
m_postsize +
sizeof ( *pCurMsg );
881 if ( size > blockSize ) {
885 "%s: Undecipherable (payload too small) UDP msg from %s ignored\n",
895 pStub = udpJumpTableCAC [pCurMsg->
m_cmmd];
898 pStub = &udpiiu::badUDPRespAction;
900 bool success = ( this->*pStub ) ( *pCurMsg, net_addr, currentTime );
904 errlogPrintf (
"CAC: Undecipherable UDP message from %s\n", buf );
913 bool udpiiu::pushVersionMsg ()
917 this->sequenceNumber++;
926 return this->pushDatagramMsg ( guard, msg, 0, 0 );
938 if ( msgsize >=
sizeof ( this->xmitBuf ) - 7 ) {
942 if ( msgsize + this->nBytesInXmitBuf >
sizeof ( this->xmitBuf ) ) {
946 caHdr * pbufmsg = (
caHdr * ) &this->xmitBuf[this->nBytesInXmitBuf];
948 if ( extsize && pExt ) {
949 memcpy ( pbufmsg + 1, pExt, extsize );
950 if ( extsize != alignedExtSize ) {
951 char *pDest = (
char *) ( pbufmsg + 1 );
952 memset ( pDest + extsize,
'\0', alignedExtSize - extsize );
956 this->nBytesInXmitBuf += msgsize;
961 udpiiu :: SearchDestUDP :: SearchDestUDP (
963 _lastError (0u), _destAddr ( destAddr ), _udpiiu ( udpiiuIn )
967 void udpiiu :: SearchDestUDP :: searchRequest (
971 assert ( bufSize <= INT_MAX );
972 int bufSizeAsInt = static_cast <
int > ( bufSize );
975 int status = sendto ( _udpiiu.sock, const_cast<char *>(pBuf), bufSizeAsInt, 0,
976 & _destAddr.sa, sizeof ( _destAddr.sa ) );
977 if ( status == bufSizeAsInt ) {
982 "CAC: ok sending UDP msg to %s\n", buf);
988 errlogPrintf (
"CAC: UDP sendto () call returned strange xmit count?\n" );
995 if ( _udpiiu.shutdownCmd ) {
1011 else if ( localErrno == _lastError) {
1014 char sockErrBuf[64];
1016 sockErrBuf,
sizeof ( sockErrBuf ) );
1020 "CAC: error = \"%s\" sending UDP msg to %s\n",
1023 _lastError = localErrno;
1030 void udpiiu :: SearchDestUDP :: show (
1036 :: printf (
"UDP Search destination \"%s\"\n", buf );
1039 udpiiu :: SearchRespCallback :: SearchRespCallback (
udpiiu & udpiiuIn ) :
1040 _udpiiu ( udpiiuIn )
1044 void udpiiu :: SearchRespCallback :: notify (
1045 const caHdr & msg,
const void * pPayloadUntyped,
1052 if ( addr.
sa.sa_family != AF_INET ) {
1062 if ( msg.
m_postsize >= sizeof ( minorVersion ) ){
1068 unsigned byte0 = pPayLoad[0];
1069 unsigned byte1 = pPayLoad[1];
1070 minorVersion = ( byte0 << 8u ) | byte1;
1081 serverAddr.
ia.sin_family = AF_INET;
1082 if (
CA_V48 ( minorVersion ) ) {
1083 if ( msg.
m_cid != INADDR_BROADCAST ) {
1084 serverAddr.
ia.sin_addr.s_addr = htonl ( msg.
m_cid );
1087 serverAddr.
ia.sin_addr = addr.
ia.sin_addr;
1091 else if (
CA_V45 (minorVersion) ) {
1093 serverAddr.
ia.sin_addr = addr.
ia.sin_addr;
1096 serverAddr.
ia.sin_port = htons ( _udpiiu.serverPort );
1097 serverAddr.
ia.sin_addr = addr.
ia.sin_addr;
1100 if (
CA_V42 ( minorVersion ) ) {
1101 _udpiiu.cacRef.transferChanToVirtCircuit
1103 0, minorVersion, serverAddr, currentTime );
1106 _udpiiu.cacRef.transferChanToVirtCircuit
1108 msg.
m_count, minorVersion, serverAddr, currentTime );
1112 void udpiiu :: SearchRespCallback :: show (
1116 ::printf (
"udpiiu :: SearchRespCallback\n" );
1119 bool udpiiu :: datagramFlush (
1125 if ( this->nBytesInXmitBuf <=
sizeof (
caHdr ) ) {
1130 while ( iter.valid () )
1132 iter->searchRequest ( guard, this->xmitBuf, this->nBytesInXmitBuf );
1136 this->nBytesInXmitBuf = 0u;
1138 this->pushVersionMsg ();
1147 ::printf (
"Datagram IO circuit (and disconnected channel repository)\n");
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 () );
1155 _searchDestList.firstIter () );
1156 while ( iter.valid () )
1158 iter->show ( guard, level - 2 );
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 );
1173 for (
unsigned i =0;
i < this->nTimers;
i++ ) {
1174 this->ppSearchTmr[
i]->show ( level - 3u );
1179 bool udpiiu::wakeupMsg ()
1190 addr.ia.sin_family = AF_INET;
1192 addr.ia.sin_port = htons ( this->localPort );
1195 int status = sendto ( this->sock, reinterpret_cast < char * > ( &msg ),
1196 sizeof (msg), 0, &addr.sa, sizeof ( addr.sa ) );
1197 return status ==
sizeof (msg);
1203 for (
unsigned i = this->beaconAnomalyTimerIndex+1u;
1204 i < this->nTimers;
i++ ) {
1205 this->ppSearchTmr[
i]->moveChannels ( cacGuard,
1206 *this->ppSearchTmr[this->beaconAnomalyTimerIndex] );
1210 void udpiiu::uninstallChanDueToSuccessfulSearchResponse (
1214 channelNode::channelState chanState =
1215 chan.channelNode::listMember;
1216 if ( chanState == channelNode::cs_disconnGov ) {
1217 this->govTmr.uninstallChan ( guard, chan );
1220 this->ppSearchTmr[ chan.getSearchTimerIndex ( guard ) ]->
1221 uninstallChanDueToSuccessfulSearchResponse (
1222 guard, chan, this->lastReceivedSeqNo,
1223 this->lastReceivedSeqNoIsValid, currentTime );
1227 void udpiiu::uninstallChan (
1230 channelNode::channelState chanState =
1231 chan.channelNode::listMember;
1232 if ( chanState == channelNode::cs_disconnGov ) {
1233 this->govTmr.uninstallChan ( guard, chan );
1236 this->ppSearchTmr[ chan.getSearchTimerIndex ( guard ) ]->
1237 uninstallChan ( guard, chan );
1241 bool udpiiu::searchMsg (
1243 const char * pName,
unsigned nameLength )
1251 return this->pushDatagramMsg (
1259 this->ppSearchTmr[0]->installChannel ( guard, chan );
1266 this->govTmr.installChan ( guard, chan );
1269 void udpiiu::noSearchRespNotify (
1272 const unsigned nTimersMinusOne = this->nTimers - 1;
1273 if ( index < nTimersMinusOne ) {
1277 index = nTimersMinusOne;
1279 this->ppSearchTmr[index]->installChannel ( guard, chan );
1282 void udpiiu::boostChannel (
1285 this->ppSearchTmr[this->beaconAnomalyTimerIndex]->
1286 installChannel ( guard, chan );
1289 void udpiiu::govExpireNotify (
1292 this->ppSearchTmr[0]->installChannel ( guard, chan );
1295 int udpiiu :: M_repeaterTimerNotify :: printFormated (
1297 const char * pformat, ... )
1302 va_start ( theArgs, pformat );
1304 status = m_udpiiu.cacRef.varArgsPrintFormated ( cbGuard, pformat, theArgs );
1314 if ( measured > maxRoundTripEstimate ) {
1315 measured = maxRoundTripEstimate;
1317 if ( measured < minRoundTripEstimate ) {
1318 measured = minRoundTripEstimate;
1320 double error = measured - this->rtteMean;
1321 this->rtteMean += 0.125 * error;
1322 if ( error < 0.0 ) {
1325 this->rtteMeanDev = this->rtteMeanDev + .25 * ( error - this->rtteMeanDev );
1331 return this->rtteMean + 4 * this->rtteMeanDev;
1334 unsigned udpiiu::getHostName (
1336 char *pBuf,
unsigned bufLength )
const throw ()
1341 const char * udpiiu::pHostName (
1347 bool udpiiu::ca_v42_ok (
1353 bool udpiiu::ca_v41_ok (
1359 void udpiiu::writeRequest (
1367 void udpiiu::writeNotifyRequest (
1375 void udpiiu::readNotifyRequest (
1382 void udpiiu::clearChannelRequest (
1389 void udpiiu::subscriptionRequest (
1396 void udpiiu::subscriptionUpdateRequest (
1401 guard, chan, subscr );
1404 void udpiiu::subscriptionCancelRequest (
1411 void udpiiu::flushRequest (
1417 unsigned udpiiu::requestMessageBytesPending (
1423 void udpiiu::flush (
1429 void udpiiu::requestRecvProcessPostponedFlush (
1441 double udpiiu::receiveWatchdogDelay (
1450 return this->sequenceNumber;
#define SOCK_ECONNREFUSED
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
unsigned epicsStdCall sockAddrToDottedIP(const struct sockaddr *paddr, char *pBuf, unsigned bufSize)
virtual bool ca_v42_ok(epicsGuard< epicsMutex > &) const =0
#define REPEATER_REGISTER
void beaconAnomalyNotify(epicsGuard< epicsMutex > &guard)
int(* pProtoStubUDP)(caHdrLargeArray *mp, void *pPayload, struct client *client)
#define assert(exp)
Declare that a condition should be true.
virtual void subscriptionCancelRequest(epicsGuard< epicsMutex > &, nciu &chan, netSubscription &subscr)=0
void setServerAddressUnknown(netiiu &newiiu, epicsGuard< epicsMutex > &guard)
char * name
Name of the parameter.
LIBCOM_API const char *epicsStdCall envGetConfigParamPtr(const ENV_PARAM *pParam)
Get a configuration parameter's value or default string.
virtual void requestRecvProcessPostponedFlush(epicsGuard< epicsMutex > &)=0
virtual void subscriptionRequest(epicsGuard< epicsMutex > &, nciu &, netSubscription &)=0
Routines to get and set EPICS environment parameters.
tsDLIterConst< T > firstIter() const
pvd::StructureConstPtr type
ELLNODE * ellGet(ELLLIST *pList)
Deletes and returns the first node from a list.
void shutdown(epicsGuard< epicsMutex > &cbGuard, epicsGuard< epicsMutex > &guard)
#define CA_UKN_MINOR_VERSION
void assertIdenticalMutex(const T &) const
udpRecvThread(class udpiiu &iiuIn, cacContextNotify &, epicsMutex &, const char *pName, unsigned stackSize, unsigned priority)
epicsThreadPrivateId caClientCallbackThreadId
virtual osiSockAddr getNetworkAddress(epicsGuard< epicsMutex > &) const =0
virtual void readNotifyRequest(epicsGuard< epicsMutex > &, nciu &, netReadNotifyIO &, unsigned type, arrayElementCount nElem)=0
int osiSockOptMcastLoop_t
unsigned short ca_uint16_t
virtual void flush(epicsGuard< epicsMutex > &mutualExclusionGuard)=0
Miscellaneous macro definitions.
virtual unsigned getHostName(epicsGuard< epicsMutex > &, char *pBuf, unsigned bufLength) const =0
LIBCOM_API unsigned int epicsStdCall epicsThreadGetStackSize(epicsThreadStackSizeClass size)
virtual bool ca_v41_ok(epicsGuard< epicsMutex > &) const =0
static unsigned getMaxSearchTimerCount()
epicsThreadId epicsStdCall epicsThreadCreate(const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr, void *parm)
#define CA_MINOR_PROTOCOL_REVISION
void installNewChannel(epicsGuard< epicsMutex > &, nciu &, netiiu *&)
void installDisconnectedChannel(epicsGuard< epicsMutex > &, nciu &)
void epicsSocketConvertErrnoToString(char *pBuf, unsigned bufSize)
LIBCOM_API SOCKET epicsStdCall epicsSocketCreate(int domain, int type, int protocol)
LIBCOM_API osiSockAddr epicsStdCall osiLocalAddr(SOCKET socket)
osiSpawnDetachedProcessReturn
void caRepeaterThread(void *)
LIBCOM_API long epicsStdCall envGetDoubleConfigParam(const ENV_PARAM *pParam, double *pDouble)
Get value of a double configuration parameter.
void show(unsigned level) const
#define CA_MESSAGE_ALIGN(A)
void show(unsigned level) const
void epicsStdCall caStartRepeaterIfNotInstalled(unsigned repeaterPort)
LIBCOM_API const ENV_PARAM EPICS_CA_REPEATER_PORT
LIBCOM_API void epicsStdCall epicsSocketEnableAddressReuseDuringTimeWaitState(SOCKET s)
LIBCOM_API void epicsStdCall epicsThreadPrivateSet(epicsThreadPrivateId, void *)
udpiiu(epicsGuard< epicsMutex > &cacGuard, class epicsTimerQueueActive &, epicsMutex &callbackControl, epicsMutex &mutualExclusion, cacContextNotify &, class cac &, unsigned port, tsDLList< SearchDest > &)
LIBCOM_API unsigned short epicsStdCall envGetInetPortConfigParam(const ENV_PARAM *pEnv, unsigned short defaultPort)
Get value of a port number configuration parameter.
virtual void subscriptionUpdateRequest(epicsGuard< epicsMutex > &, nciu &, netSubscription &)=0
#define epicsThreadPriorityLow
#define sequenceNoIsValid
void shutdown(epicsGuard< epicsMutex > &cbGuard, epicsGuard< epicsMutex > &guard)
virtual void flushRequest(epicsGuard< epicsMutex > &)=0
int errlogPrintf(const char *pFormat,...)
virtual const char * pHostName(epicsGuard< epicsMutex > &) const =0
void date(const char *format)
epicsGuard< epicsMutex > cbGuard
unsigned long arrayElementCount
const char *epicsStdCall ca_message(long ca_status)
LIBCA_API void epicsStdCall configureChannelAccessAddressList(struct ELLLIST *pList, SOCKET sock, unsigned short port)
LIBCOM_API const ENV_PARAM EPICS_CA_MAX_SEARCH_PERIOD
LIBCOM_API long epicsStdCall envGetLongConfigParam(const ENV_PARAM *pParam, long *pLong)
Get value of a long configuration parameter.
LIBCOM_API osiSpawnDetachedProcessReturn epicsStdCall osiSpawnDetachedProcess(const char *pProcessName, const char *pBaseExecutableName)
#define ellInit(PLIST)
Initialize a list type.
#define genLocalExcep(CBGUARD, GUARD, CAC, STAT, PCTX)
Contains a few templates out of the C++ standard header algorithm.
virtual void writeRequest(epicsGuard< epicsMutex > &, nciu &, unsigned type, arrayElementCount nElem, const void *pValue)=0
LIBCOM_API const ENV_PARAM EPICS_CA_MCAST_TTL
virtual unsigned requestMessageBytesPending(epicsGuard< epicsMutex > &mutualExclusionGuard)=0
void epicsStdCall caRepeaterRegistrationMessage(SOCKET sock, unsigned repeaterPort, unsigned attemptNumber)
void shutdown(epicsGuard< epicsMutex > &cbGuard, epicsGuard< epicsMutex > &guard)
virtual void clearChannelRequest(epicsGuard< epicsMutex > &, ca_uint32_t sid, ca_uint32_t cid)=0
#define throwWithLocation(parm)
virtual double receiveWatchdogDelay(epicsGuard< epicsMutex > &) const =0
bool exitWait(double delay)
virtual void writeNotifyRequest(epicsGuard< epicsMutex > &, nciu &, netWriteNotifyIO &, unsigned type, arrayElementCount nElem, const void *pValue)=0