204 lines
4.1 KiB
C
204 lines
4.1 KiB
C
/*
|
|
* O N L I N E _ N O T I F Y . C
|
|
*
|
|
* tell CA clients this a server has joined the network
|
|
*
|
|
* Author: Jeffrey O. Hill
|
|
* hill@luke.lanl.gov
|
|
* (505) 665 1831
|
|
* Date: 103090
|
|
*
|
|
* Experimental Physics and Industrial Control System (EPICS)
|
|
*
|
|
* Copyright 1991, the Regents of the University of California,
|
|
* and the University of Chicago Board of Governors.
|
|
*
|
|
* This software was produced under U.S. Government contracts:
|
|
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
|
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
|
*
|
|
* Initial development by:
|
|
* The Controls and Automation Group (AT-8)
|
|
* Ground Test Accelerator
|
|
* Accelerator Technology Division
|
|
* Los Alamos National Laboratory
|
|
*
|
|
* Co-developed with
|
|
* The Controls and Computing Group
|
|
* Accelerator Systems Division
|
|
* Advanced Photon Source
|
|
* Argonne National Laboratory
|
|
*
|
|
* History
|
|
* .00 joh 021192 better diagnostics
|
|
*/
|
|
|
|
static char *sccsId = "@(#) $Id$";
|
|
|
|
/*
|
|
* ansi includes
|
|
*/
|
|
#include <string.h>
|
|
|
|
/*
|
|
* system includes
|
|
*/
|
|
#include <vxWorks.h>
|
|
#include <types.h>
|
|
#include <sockLib.h>
|
|
#include <socket.h>
|
|
#include <errnoLib.h>
|
|
#include <in.h>
|
|
#include <logLib.h>
|
|
#include <sysLib.h>
|
|
#include <taskLib.h>
|
|
|
|
#define MAX_BLOCK_THRESHOLD 100000
|
|
|
|
/*
|
|
* EPICS includes
|
|
*/
|
|
#include <envDefs.h>
|
|
#include "server.h"
|
|
#include <task_params.h>
|
|
|
|
/*
|
|
* RSRV_ONLINE_NOTIFY_TASK
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
int rsrv_online_notify_task()
|
|
{
|
|
caAddrNode *pNode;
|
|
unsigned long delay;
|
|
unsigned long maxdelay;
|
|
long longStatus;
|
|
double maxPeriod;
|
|
struct extmsg msg;
|
|
struct sockaddr_in recv_addr;
|
|
int status;
|
|
int sock;
|
|
int true = TRUE;
|
|
short port;
|
|
|
|
taskwdInsert(taskIdSelf(),NULL,NULL);
|
|
|
|
longStatus = envGetDoubleConfigParam (
|
|
&EPICS_CA_BEACON_PERIOD,
|
|
&maxPeriod);
|
|
if (longStatus) {
|
|
maxPeriod = 15.0;
|
|
ca_printf (
|
|
"EPICS \"%s\" float fetch failed\n",
|
|
EPICS_CA_BEACON_PERIOD.name);
|
|
ca_printf (
|
|
"Setting \"%s\" = %f\n",
|
|
EPICS_CA_BEACON_PERIOD.name,
|
|
maxPeriod);
|
|
}
|
|
|
|
/*
|
|
* 1 sec init delay between beacons
|
|
*/
|
|
delay = sysClkRateGet();
|
|
maxdelay = max(maxPeriod*sysClkRateGet(),sysClkRateGet());
|
|
|
|
/*
|
|
* Open the socket.
|
|
* Use ARPA Internet address format and datagram socket.
|
|
* Format described in <sys/socket.h>.
|
|
*/
|
|
if((sock = socket (AF_INET, SOCK_DGRAM, 0)) == ERROR){
|
|
logMsg("CAS: online socket creation error\n",
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0);
|
|
abort();
|
|
}
|
|
|
|
status = setsockopt( sock,
|
|
SOL_SOCKET,
|
|
SO_BROADCAST,
|
|
(char *)&true,
|
|
sizeof(true));
|
|
if(status<0){
|
|
abort();
|
|
}
|
|
|
|
bfill((char *)&recv_addr, sizeof recv_addr, 0);
|
|
recv_addr.sin_family = AF_INET;
|
|
recv_addr.sin_addr.s_addr = INADDR_ANY; /* let slib pick lcl addr */
|
|
recv_addr.sin_port = htons(0); /* let slib pick port */
|
|
status = bind(sock, (struct sockaddr *)&recv_addr, sizeof recv_addr);
|
|
if(status<0)
|
|
abort();
|
|
|
|
bfill((char *)&msg, sizeof msg, 0);
|
|
msg.m_cmmd = htons(IOC_RSRV_IS_UP);
|
|
|
|
ellInit(&beaconAddrList);
|
|
|
|
/*
|
|
* load user and auto configured
|
|
* broadcast address list
|
|
*/
|
|
port = caFetchPortConfig(&EPICS_CA_REPEATER_PORT, CA_REPEATER_PORT);
|
|
caSetupBCastAddrList (&beaconAddrList, sock, port);
|
|
|
|
# ifdef DEBUG
|
|
caPrintAddrList(&beaconAddrList);
|
|
# endif
|
|
|
|
while(TRUE){
|
|
int maxBlock;
|
|
|
|
/*
|
|
* check max block and disable new channels
|
|
* if its to small
|
|
*/
|
|
maxBlock = memFindMax();
|
|
if(maxBlock<MAX_BLOCK_THRESHOLD){
|
|
casDontAllowSearchReplies = TRUE;
|
|
}
|
|
else{
|
|
casDontAllowSearchReplies = FALSE;
|
|
}
|
|
|
|
pNode = (caAddrNode *) beaconAddrList.node.next;
|
|
while(pNode){
|
|
msg.m_available =
|
|
pNode->srcAddr.inetAddr.sin_addr.s_addr;
|
|
status = sendto(
|
|
sock,
|
|
(char *)&msg,
|
|
sizeof(msg),
|
|
0,
|
|
&pNode->destAddr.sockAddr,
|
|
sizeof(pNode->destAddr.sockAddr));
|
|
if(status < 0){
|
|
logMsg( "%s: CA beacon error was \"%s\"\n",
|
|
(int) __FILE__,
|
|
(int) strerror(errnoGet()),
|
|
0,
|
|
0,
|
|
0,
|
|
0);
|
|
}
|
|
else{
|
|
assert(status == sizeof(msg));
|
|
}
|
|
|
|
pNode = (caAddrNode *)pNode->node.next;
|
|
}
|
|
taskDelay(delay);
|
|
delay = min(delay << 1, maxdelay);
|
|
}
|
|
|
|
}
|
|
|
|
|