original files of m241
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
# Makefile - top level makefile for target/src/dsi to build runtime libraries
|
||||
#
|
||||
# modification history
|
||||
# --------------------
|
||||
# 01c,11oct04,p_r changed description comment to remove "wrn" (SPR#102446)
|
||||
# 01b,11jun04,ymz removed clean flag.
|
||||
# 01a,03dec03,als Created from target/src/wrn/Makefile
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This file contains the makefile rules to detect subdirectories that contain
|
||||
# sources for building the vx library and builds them.
|
||||
#
|
||||
#*/
|
||||
|
||||
TGT_DIR=$(WIND_BASE)/target
|
||||
|
||||
include $(TGT_DIR)/h/make/rules.library
|
||||
@@ -0,0 +1,22 @@
|
||||
# Makefile - makefile for dsi/backend
|
||||
#
|
||||
# modification history
|
||||
# --------------------
|
||||
# 01b,27oct04,bwa added flag to enable Windview instrumentation (SPR# 103042).
|
||||
# 01a,04oct04,p_r written (SPR#102446)
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This file contains the makefile rules for building the backend library
|
||||
#
|
||||
|
||||
TGT_DIR = $(WIND_BASE)/target
|
||||
|
||||
DOC_FILES= dsiSockLib.c
|
||||
|
||||
LIB_BASE_NAME = dsi
|
||||
|
||||
EXTRA_DEFINE+=-DINCLUDE_WVNETD
|
||||
|
||||
OBJS= dsiSockLib.o dsiUtilLib.o
|
||||
|
||||
include $(TGT_DIR)/h/make/rules.library
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,186 @@
|
||||
/* dsiUtilLib.c - utilities for the DSI stack */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004-2005, 2007, 2011, 2013 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01h,16sep13,f_f fix static overrun (WIND00435182)
|
||||
01g,07jun11,shi LP64 conversion
|
||||
01f,04jul07,ebh changes to allow DSI to run in SMP systems
|
||||
01e,04may07,ebh modify dsiTsleep to return EINTR (Defect #91328)
|
||||
01d,21feb05,ebh update manually (zippy merge was not running)
|
||||
01c,28jan05,dlk Fix compiler warning.
|
||||
01c,04jan05,bwa doc fix (SPR #103021).
|
||||
01b,11oct04,p_r fixed pathname for dsi header (SPR #102446)
|
||||
01a,17aug04,dlk written.
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This is an internal library that provides general utilities for the DSI
|
||||
stack.
|
||||
|
||||
In particular, it provides the mutual exclusion routines dsiLock() and
|
||||
dsiUnlock(), which replace splnet() and splx() for the DSI/AF_LOCAL/COMP
|
||||
stack. It also provides the dsiTsleep() routine, which replaces tsleep()
|
||||
and ksleep().
|
||||
|
||||
NOMANUAL
|
||||
*/
|
||||
|
||||
/* VxWorks system includes */
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <taskLib.h>
|
||||
#include <semLib.h>
|
||||
#include <private/semLibP.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <dsi/backend/dsiUtilLib.h>
|
||||
|
||||
typedef struct _DSI_LOCK_INFO
|
||||
{
|
||||
TASK_ID lockTask;
|
||||
SEMAPHORE sem;
|
||||
BOOL initialized;
|
||||
} DSI_LOCK_INFO;
|
||||
|
||||
/* globals */
|
||||
|
||||
int dsiLockMutexOptions = (SEM_Q_PRIORITY |
|
||||
SEM_DELETE_SAFE |
|
||||
SEM_INVERSION_SAFE);
|
||||
|
||||
/* locals */
|
||||
|
||||
LOCAL DSI_LOCK_INFO dsiLockInfo;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* dsiLockInit - initialize AF_LOCAL/COMP/DSI mutual exclusion.
|
||||
*
|
||||
* This routine must be called as part of DSI initialization.
|
||||
*
|
||||
* RETURNS: OK or ERROR.
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
STATUS dsiLockInit (void)
|
||||
{
|
||||
STATUS status;
|
||||
|
||||
if (dsiLockInfo.initialized)
|
||||
return OK;
|
||||
|
||||
dsiLockInfo.lockTask = 0;
|
||||
|
||||
status = semMInit (&dsiLockInfo.sem, dsiLockMutexOptions);
|
||||
|
||||
if (status == OK)
|
||||
dsiLockInfo.initialized = TRUE;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* dsiLock - obtain AF_LOCAL/COMP/DSI mutual exclusion.
|
||||
*
|
||||
* This routine is the equivalent of splnet() for the DSI stack.
|
||||
*
|
||||
* RETURNS: 1 if the caller owned the DSI lock before the call; 0 if the
|
||||
* caller did not.
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
int dsiLock (void)
|
||||
{
|
||||
if (dsiLockInfo.lockTask == (TASK_ID)taskIdCurrent)
|
||||
return 1;
|
||||
|
||||
(void)semTake (&dsiLockInfo.sem, WAIT_FOREVER);
|
||||
dsiLockInfo.lockTask = (TASK_ID)taskIdCurrent;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* dsiUnlock - release AF_LOCAL/COMP/DSI mutual exclusion.
|
||||
*
|
||||
* This routine is the equivalent of splx() for the DSI stack.
|
||||
* It gets passed the return value from the corresponding call to
|
||||
* dsiLock(); it releases mutual exlusion when the argument <key> is zero.
|
||||
*
|
||||
* RETURNS: N/A
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
void dsiUnlock
|
||||
(
|
||||
int key
|
||||
)
|
||||
{
|
||||
if (key == 0)
|
||||
{
|
||||
dsiLockInfo.lockTask = 0;
|
||||
semGive (&dsiLockInfo.sem);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* dsiTsleep - sleep with a timeout
|
||||
*
|
||||
* This routine is the equivalent of tsleep() for DSI.
|
||||
* It should only be called when holding DSI lock.
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
STATUS dsiTsleep
|
||||
(
|
||||
SEM_ID semId,
|
||||
int timeo_val
|
||||
)
|
||||
{
|
||||
STATUS status;
|
||||
|
||||
/* Note, we must be holding the DSI lock */
|
||||
|
||||
if (timeo_val != NO_WAIT)
|
||||
{
|
||||
/* give up DSI big lock */
|
||||
dsiLockInfo.lockTask = 0;
|
||||
semGive (&dsiLockInfo.sem);
|
||||
|
||||
/* wait for event */
|
||||
status = semTake (semId, timeo_val);
|
||||
|
||||
/* get DSI big lock */
|
||||
(void)semTake (&dsiLockInfo.sem, WAIT_FOREVER);
|
||||
dsiLockInfo.lockTask = (TASK_ID) taskIdCurrent;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do not wait, so don't give up DSI big lock */
|
||||
status = semTake (semId, timeo_val);
|
||||
}
|
||||
|
||||
/* assume timeout or interruption rather than corruption ! */
|
||||
|
||||
return(status == OK ? OK : (errno == EINTR) ? EINTR : EWOULDBLOCK);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# Makefile - makefile for dsi/sockapp
|
||||
#
|
||||
# modification history
|
||||
# --------------------
|
||||
# 01g,31mar05,ebh added dsalMonitor.o for distributed SAL
|
||||
# 01f,11oct04,p_r removed reference to "wrn" in comment (part of SPR#102446)
|
||||
# 01e,01sep04,ymz added snsCommon.c renamed salClientBase.c to salCommon.c
|
||||
# 01d,25may04,ymz update due to files merging.
|
||||
# 01c,17feb04,pch remove PPC32 hack, no longer needed
|
||||
# 01b,03dec03,als simplified DOC_FILES list
|
||||
# 01a,26nov03,als written
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This file contains the makefile rules for building the sockapp library
|
||||
#
|
||||
|
||||
TGT_DIR = $(WIND_BASE)/target
|
||||
|
||||
DOC_FILES= salClient.c salServer.c snsLib.c snsShow.c
|
||||
|
||||
LIB_BASE_NAME = dsi
|
||||
|
||||
OBJS= salCommon.o salClient.o salSns.o salServer.o snsCommon.o \
|
||||
snsLib.o snsShow.o snsRtpHook.o dsalMonitor.o
|
||||
|
||||
include $(TGT_DIR)/h/make/rules.library
|
||||
@@ -0,0 +1,795 @@
|
||||
/* dsalMonitor.c - Distributed SAL Monitor task */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005-2007, 2011-2013 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01l,27jun13,shi eliminate Coverity warnings.(WIND00423922)
|
||||
01k,07may13,shi eliminate Coverity warnings.(WIND00416493)
|
||||
01j,12jul12,shi clean up warnings (WIND00357529)
|
||||
01i,24jun11,shi LP64 conversion
|
||||
01h,17oct07,ebh Review comments included
|
||||
01g,15oct07,ebh modify DSAL sequence to allow for standalone->network mode
|
||||
transition in TIPC
|
||||
01f,20jun07,ebh modify outdated comments
|
||||
01e,15mar06,mze need a delay loop when connecting to the topology server
|
||||
01d,05jan06,mze update to use new TIPC subcription method
|
||||
01c,10may05,ebh update to use a single instance value
|
||||
01b,25apr05,ebh adjusted structures and names
|
||||
01a,22mar05,ebh created
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
|
||||
This code provides a monitor service needed by the distributed
|
||||
SAL (Socket Application Library) layer. It monitors the network
|
||||
for new or disappearing SNS servers and flags this information
|
||||
for processing.
|
||||
|
||||
The only responsibility of the dsalMonitor routine is to inform
|
||||
the SNS server of topology events. The snsServer takes care of
|
||||
everything else.
|
||||
|
||||
Note that the dsalMonitor relies on the TIPC protocol to monitor
|
||||
all the distributed SNS servers in the network. This method
|
||||
will obviously fail if TIPC is not part of the system.
|
||||
|
||||
The SNS server will query all new SNS servers for all named
|
||||
sockets that would be visible from this node. Disappearing SNS
|
||||
servers result in a purge of all information pertaining to that
|
||||
server from the locally maintained name database.
|
||||
|
||||
INTERNAL
|
||||
|
||||
Messaging
|
||||
|
||||
The SNS server is single-threaded. It can interact
|
||||
with any number of clients using COMP transport protocol connections
|
||||
or TIPC protocol connectionless channels (currently only connection
|
||||
oriented channels).
|
||||
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <ctype.h>
|
||||
#include <dllLib.h>
|
||||
#include <stdio.h>
|
||||
#include <errnoLib.h>
|
||||
#include <hostLib.h>
|
||||
#include <sockLib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <taskLib.h>
|
||||
#include <rtpLibCommon.h>
|
||||
#include <dsi/private/salClientP.h>
|
||||
#include <dsi/private/salServerP.h>
|
||||
#include <dsi/private/snsLibP.h>
|
||||
#include <tipc/tipc.h>
|
||||
#include <ioLib.h>
|
||||
|
||||
/* defines */
|
||||
|
||||
#define DPRINT /* swap order of these two lines to enable/disable */
|
||||
#undef DPRINT /* swap order of these two lines to enable/disable */
|
||||
#ifdef DPRINT
|
||||
# define dprintf printf
|
||||
#else
|
||||
# define dprintf if (0) printf
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* getSock - local routine getSock
|
||||
*
|
||||
* This routine gets a TIPC socket at a time when TIPC is just starting up
|
||||
* as a result the call to socket may fail. The code will allow for 5 failures
|
||||
* before it will give up and return ERROR
|
||||
*
|
||||
* RETURNS: OK or ERROR
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i "S_salLib_SERVER_SOCKET_ERROR"
|
||||
* A server socket has failed unexpectedly.
|
||||
* \ie
|
||||
*
|
||||
* \NOMANUAL
|
||||
*/
|
||||
LOCAL STATUS getSock
|
||||
(
|
||||
int *topsockfd /* topology socket descriptor */
|
||||
)
|
||||
{
|
||||
int sleepCount; /* length of time to sleep */
|
||||
|
||||
for (sleepCount = 1, *topsockfd = -1;
|
||||
(*topsockfd < 0 && sleepCount < 5);
|
||||
sleepCount++)
|
||||
{
|
||||
*topsockfd = socket (AF_TIPC, SOCK_SEQPACKET, 0);
|
||||
if (*topsockfd >= 0)
|
||||
{
|
||||
dprintf("dsalMonitor: set up communication socket %d.\n",
|
||||
*topsockfd);
|
||||
break;
|
||||
}
|
||||
|
||||
dprintf("dsalMonitor: Could not set up communication socket, "
|
||||
"sleeping %d.\nDone.\n",sleepCount);
|
||||
sleep(sleepCount);
|
||||
}
|
||||
|
||||
if (*topsockfd < 0)
|
||||
{
|
||||
dprintf("dsalMonitor: Could not set up communication socket.\nDone.\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* dsalMonitor - Distributed SNS server monitor task
|
||||
*
|
||||
* This routine sets up a TIPC socket that monitors topology events in the
|
||||
* system that deal with distributed SNS server events.
|
||||
*
|
||||
* All distributed SNS servers publish their existance in the TIPC world using
|
||||
* the {type, instance} configured in the CDF files. Each node uses the same
|
||||
* {type, instance} values.
|
||||
*
|
||||
* When a new distributed SNS server is detected, this information is sent to
|
||||
* the local SNS server via a TIPC message (the local SNS server then adds
|
||||
* the new server to its list of servers).
|
||||
*
|
||||
* When a known distributed SNS server disappears, a message is sent to the
|
||||
* local SNS server stating that the node is no longer accessible (the local
|
||||
* SNS server then deletes all socket information in its database pertaining
|
||||
* to that node).
|
||||
*
|
||||
* Order of operations in this routine:
|
||||
* - detect TIPC being up: use getSock() to repeatedly try to create TIPC socket
|
||||
* - detect network mode: use subscription to {0, 1-max} to detect other nodes
|
||||
* - tell our DSAL server we are in network mode
|
||||
* - enter full monitor state: monitor for external DSAL servers joining/leaving
|
||||
*
|
||||
* RETURNS: OK or ERROR
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i "S_salLib_SERVER_SOCKET_ERROR"
|
||||
* A server socket has failed unexpectedly.
|
||||
* \i "S_salLib_INTERNAL_ERROR"
|
||||
* The server's internal data structure has become corrupted.
|
||||
* \ie
|
||||
*
|
||||
* \NOMANUAL
|
||||
*/
|
||||
|
||||
STATUS dsalMonitor (
|
||||
const unsigned int dsalSnsServerType, /* SNS Server TIPC type */
|
||||
const unsigned int dsalSnsServerInstance/* SNS Server TIPC instance */
|
||||
)
|
||||
{
|
||||
struct tipc_subscr subscr; /* blocking subscription for dsal */
|
||||
int dsockfd = -1; /* socket descriptor */
|
||||
int topsockfd; /* topology socket descriptor */
|
||||
struct tipc_event event; /* event structure */
|
||||
DSAL_SNS_MSG msg; /* SNS message */
|
||||
int msgSize; /* size of the message */
|
||||
struct sockaddr_tipc addr; /* our TIPC address */
|
||||
struct sockaddr_tipc dsalTipcAddr; /* topology server address */
|
||||
int addrSize; /* size of socket structure */
|
||||
int sleepCount; /* length of time to sleep */
|
||||
int rc; /* return code for the connect */
|
||||
|
||||
dprintf("dsalMonitor: entry (type=%d, instance=%d).\n",
|
||||
dsalSnsServerType, dsalSnsServerInstance);
|
||||
|
||||
|
||||
/* ensure we have a type and instance to monitor */
|
||||
if (dsalSnsServerType == 0 || dsalSnsServerInstance == 0)
|
||||
{
|
||||
dprintf("dsalMonitor: DSAL type,instance pair not valid.\nDone.\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* create a connection to topology server to ensure TIPC is up */
|
||||
memset((char*)(&dsalTipcAddr),0,sizeof(dsalTipcAddr));
|
||||
dsalTipcAddr.family = AF_TIPC;
|
||||
dsalTipcAddr.addrtype = TIPC_ADDR_NAME;
|
||||
dsalTipcAddr.addr.name.name.type = TIPC_TOP_SRV;
|
||||
dsalTipcAddr.addr.name.name.instance = TIPC_TOP_SRV;
|
||||
dsalTipcAddr.addr.name.domain = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* create the socket to communicate with the topology server */
|
||||
if (getSock(&topsockfd)!= OK)
|
||||
return ERROR;
|
||||
|
||||
/* Connect to topology server - use backoff scheme to connect */
|
||||
for (sleepCount = 1,rc = -1;(sleepCount<5 && rc <0) ;sleepCount++)
|
||||
{
|
||||
rc = connect (topsockfd, (struct sockaddr *)&dsalTipcAddr,
|
||||
sizeof (dsalTipcAddr));
|
||||
if (rc >= 0)
|
||||
{
|
||||
dprintf("dsalMonitor: connected to topology Server.\n");
|
||||
break;
|
||||
}
|
||||
close(topsockfd); /* must close socket to try this again */
|
||||
dprintf("dsalMonitor: could not connect to topology Server , sleeping %d.\n",sleepCount);
|
||||
sleep(sleepCount);
|
||||
if (getSock(&topsockfd)!= OK)
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
perror("connect to topology server failed \n");
|
||||
dprintf("dsalMonitor: could not connect to topology Server.\nDone. "
|
||||
"Socket was %d\n",topsockfd);
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
/* wait for TIPC to go into network mode */
|
||||
subscr.seq.type = 0;
|
||||
subscr.seq.lower = 1; /* <0.0.0> is not network mode */
|
||||
subscr.seq.upper = (unsigned int)-1;
|
||||
subscr.timeout = WAIT_FOREVER; /* ms */
|
||||
subscr.filter = TIPC_SUB_SERVICE;
|
||||
subscr.usr_handle[0] = 0; /* use 0 here to distinguish later */
|
||||
|
||||
/* subscribe to topology events */
|
||||
if (send(topsockfd, (char *) &subscr, sizeof(subscr), 0) != sizeof(subscr))
|
||||
{
|
||||
dprintf("dsalMonitor:1 failure to set up a subscription.\n");
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
/* wait until we detect a network subscription */
|
||||
dprintf("dsalMonitor: waiting for Network subscription event.\n");
|
||||
if (recv(topsockfd, (char *)&event, sizeof(event), 0) != sizeof(event))
|
||||
{
|
||||
/* note that we will lose connectivity when going to network mode,
|
||||
* but maybe something else entirely happened, so we can't assume
|
||||
* that we are actually in network mode. So we will have to loop
|
||||
* back and try again.
|
||||
*/
|
||||
dprintf("dsalMonitor: failure to perform block get event.\n");
|
||||
close(topsockfd); /* close to cancel subscription */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we had an event */
|
||||
dprintf("dsalMonitor: wait for Net UP Event = %d.\n", event.event);
|
||||
dprintf("dsalMonitor: found_lower = %d, found_upper = %d, handle=%ld.\n",
|
||||
event.found_lower,event.found_upper, (long)event.s.usr_handle);
|
||||
dprintf("dsalMonitor: port.ref = %d, port.node = %d.\n",
|
||||
event.port.ref,event.port.node);
|
||||
close(topsockfd); /* close to cancel subscription */
|
||||
break; /* we are done here, exit loop */
|
||||
}
|
||||
} /* while loop for NETwork mode detection */
|
||||
|
||||
/* continue to detect our own distributed SNS server */
|
||||
|
||||
if (getSock(&topsockfd)!= OK)
|
||||
return ERROR;
|
||||
|
||||
rc = connect (topsockfd, (struct sockaddr *)&dsalTipcAddr,
|
||||
sizeof (dsalTipcAddr));
|
||||
if (rc < 0)
|
||||
{
|
||||
dprintf("dsalMonitor: cannot connect to topology Server (rc=%d, errno=%d).\n", rc, errno);
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
/* Determine own TIPC address - we must have an address in network mode */
|
||||
addrSize = sizeof(dsalTipcAddr);
|
||||
if (getsockname(topsockfd, (struct sockaddr *)&dsalTipcAddr, &addrSize) != OK)
|
||||
{
|
||||
dprintf("dsalMonitor: could not determine own address.\nDone.\n");
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
/* exit if we are running single node */
|
||||
if (dsalTipcAddr.addr.id.node == 0)
|
||||
{
|
||||
/* we should never be single node mode after detecting network above */
|
||||
dprintf("dsalMonitor: Should not be here. Running in single node mode. Shutting down.\n");
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
/* Display our own address information */
|
||||
dprintf("dsalMonitor: TIPC address = <%d.%d.%d>.\n",
|
||||
tipc_zone (dsalTipcAddr.addr.id.node),
|
||||
tipc_cluster (dsalTipcAddr.addr.id.node),
|
||||
tipc_node (dsalTipcAddr.addr.id.node));
|
||||
|
||||
/* create the socket to send data to the SNS server */
|
||||
dsockfd = socket (AF_TIPC, SOCK_RDM, 0);
|
||||
if (dsockfd < 0)
|
||||
{
|
||||
dprintf("dsalMonitor: Could not set up communication socket.\nDone.\n");
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
/* watch for our own node to come up before continuing */
|
||||
/* monitor the type for our local server */
|
||||
subscr.seq.type = dsalSnsServerType;
|
||||
subscr.seq.lower = dsalSnsServerInstance;
|
||||
subscr.seq.upper = dsalSnsServerInstance;
|
||||
subscr.timeout = 2000; /* ms */
|
||||
subscr.filter = TIPC_SUB_PORTS;
|
||||
subscr.usr_handle[0] = 1;
|
||||
|
||||
/* subscribe to topology events */
|
||||
if (send(topsockfd, (char *) &subscr, sizeof(subscr), 0) != sizeof(subscr))
|
||||
{
|
||||
dprintf("dsalMonitor:1 failure to set up a subscription.\n");
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
/* prepare the address structure */
|
||||
addr.family = AF_TIPC;
|
||||
addr.addrtype = TIPC_ADDR_ID;
|
||||
addr.addr.id.node = dsalTipcAddr.addr.id.node;
|
||||
/* addr.addr.id.ref = _determined below_; */
|
||||
|
||||
/* wait until the SNS server on our node comes up */
|
||||
while (1)
|
||||
{
|
||||
/* wait for an event */
|
||||
if (recv(topsockfd, (char *)&event, sizeof(event), 0) != sizeof(event))
|
||||
{
|
||||
dprintf("dsalMonitor: failure to perform block get event.\n");
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
/* we had an event */
|
||||
dprintf("dsalMonitor: Wait SNS server Event = %d.\n", event.event);
|
||||
dprintf("dsalMonitor: found_lower = %d, found_upper = %d, handle=%ld.\n",
|
||||
event.found_lower,event.found_upper, (long)event.s.usr_handle);
|
||||
dprintf("dsalMonitor: port.ref = %d, port.node = %d.\n",
|
||||
event.port.ref,event.port.node);
|
||||
|
||||
if (event.event == TIPC_PUBLISHED)
|
||||
{
|
||||
dprintf("dsalMonitor: event was TIPC_PUBLISHED\n");
|
||||
if (event.port.node == addr.addr.id.node ||
|
||||
event.port.node == 0 /* leftover standalone publication */)
|
||||
{
|
||||
/* the SNS server on our node is up!! */
|
||||
addr.addr.id.ref = event.port.ref;
|
||||
/* send a note to say that network mode in TIPC is achieved */
|
||||
|
||||
/* create a message */
|
||||
msg.cmd = htonl(DSAL_CMD_SNS_NETWORK);
|
||||
msg.nodeId = htonl(event.port.node);
|
||||
msg.ref = htonl(event.port.ref);
|
||||
msgSize = sizeof(msg);
|
||||
|
||||
dprintf("dsalMonitor: Msg created (%d bytes) our NODE is now up!\n",msgSize);
|
||||
|
||||
/* send the message to the local SNS server */
|
||||
if (sendto(dsockfd, (char *)&msg, msgSize, 0,
|
||||
(struct sockaddr *) &addr, sizeof(addr)) != msgSize)
|
||||
{
|
||||
dprintf("dsalMonitor: Could not send message to server\n");
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
break; /* no more waiting */
|
||||
}
|
||||
}
|
||||
|
||||
if (event.event == TIPC_SUBSCR_TIMEOUT)
|
||||
{
|
||||
dprintf("event was TIPC_TIMEOUT - did not find local SNS server\n");
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
} /* loop to wait for our distributed SNS server */
|
||||
|
||||
/* we do not bother to unsubscribe just look for a usr_handle[0] set to 2 */
|
||||
/* There really should not be that many events as the system runs unless
|
||||
* this is a very dynamic system. Even then, it will be a few extra
|
||||
* events.
|
||||
*/
|
||||
|
||||
/* subscr.seq.type = dsalSnsServerType; */
|
||||
/* subscr.seq.lower = dsalSnsServerInstance; */
|
||||
/* subscr.seq.upper = dsalSnsServerInstance; */
|
||||
subscr.timeout = TIPC_WAIT_FOREVER;
|
||||
/* subscr.filter = TIPC_SUB_PORTS; */
|
||||
subscr.usr_handle[0] = 2;
|
||||
|
||||
/* subscribe to topology events */
|
||||
if (send(topsockfd, (char *) &subscr, sizeof(subscr), 0) != sizeof(subscr))
|
||||
{
|
||||
dprintf("dsalMonitor:2 failure to set up a subscription.\n");
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
dprintf("dsalServer: entering loop to monitor for changes in servers\n");
|
||||
|
||||
FOREVER
|
||||
{
|
||||
|
||||
/* wait for an event */
|
||||
if (recv(topsockfd, (char *)&event, sizeof(event), 0) != sizeof(event))
|
||||
{
|
||||
/* things may be messed up if we get in here - exit */
|
||||
dprintf("dsalMonitor: failed to read topology event.\n");
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
/* ignore events from earlier subscription */
|
||||
if (event.s.usr_handle[0] != 2)
|
||||
{
|
||||
dprintf("dsalMonitor: Ignoring event (%d, nodeId=0x%x) with handle=%d.\n",
|
||||
event.event, event.port.node, event.s.usr_handle[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we had an event */
|
||||
dprintf("dsalMonitor: Event = %d.\n", event.event);
|
||||
dprintf("dsalMonitor: found_lower = %d, found_upper = %d, handle=%ld.\n",
|
||||
event.found_lower,event.found_upper, (long)event.s.usr_handle);
|
||||
dprintf("dsalMonitor: port.ref = %d, port.node = %d.\n",
|
||||
event.port.ref,event.port.node);
|
||||
|
||||
/* concerned about TIPC_PUBLISHED and TIPC_WITHDRAWN events only */
|
||||
|
||||
if (event.event != TIPC_PUBLISHED && event.event != TIPC_WITHDRAWN)
|
||||
continue;
|
||||
|
||||
dprintf("dsalMonitor: Event %s.\n", event.event == TIPC_PUBLISHED ?
|
||||
"TIPC_PUBLISHED" : "TIPC_WITHDRAWN");
|
||||
|
||||
/* check if this is our own node */
|
||||
if ((event.port.node == dsalTipcAddr.addr.id.node))
|
||||
{
|
||||
dprintf("dsalMonitor: Found our own node. Skipping it.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
dprintf("dsalMonitor: Node status changed - will send msg.\n");
|
||||
|
||||
/* send a node PUBLISHED / WITHDRAWN message to the local SNS server */
|
||||
|
||||
/* create a message */
|
||||
msg.cmd = (event.event == TIPC_PUBLISHED)
|
||||
? htonl(DSAL_CMD_SNS_PUBLISHED)
|
||||
: htonl(DSAL_CMD_SNS_WITHDRAWN);
|
||||
msg.nodeId = htonl(event.port.node);
|
||||
msg.ref = htonl(event.port.ref);
|
||||
msgSize = sizeof(msg);
|
||||
|
||||
dprintf("dsalMonitor: Msg created (%d bytes).\n",msgSize);
|
||||
|
||||
/* WORKAROUND for Nodes requiring a new route to be established by
|
||||
* TIPC. In TIPC, when a new node is discovered, it is possible that
|
||||
* information will get updated in the name table (including any
|
||||
* publications from that node) before the routing table has had a
|
||||
* chance to update.
|
||||
* For any node that requires a route (any node outside our cluster)
|
||||
* we introduce a slight delay here before telling our SNS server
|
||||
* about a NEW node. While inefficient, we at least do not slow down
|
||||
* any active communications using message channels.
|
||||
*/
|
||||
if (event.event == TIPC_PUBLISHED)
|
||||
{
|
||||
/* see if the new node is in a different cluster */
|
||||
if ((tipc_cluster(event.port.node)
|
||||
!= tipc_cluster(dsalTipcAddr.addr.id.node)) ||
|
||||
(tipc_zone(event.port.node)
|
||||
!= tipc_zone(dsalTipcAddr.addr.id.node)))
|
||||
{
|
||||
dprintf("dsalMonitor: Delay before telling SNS server about node=0x%x\n", event.port.node);
|
||||
taskDelay(10); /* delay to give TIPC a chance to run */
|
||||
}
|
||||
}
|
||||
|
||||
/* send the message to the local SNS server */
|
||||
if (sendto(dsockfd, (char *)&msg, msgSize, 0,
|
||||
(struct sockaddr *) &addr, sizeof(addr)) != msgSize)
|
||||
{
|
||||
dprintf("dsalMonitor: Could not send message to server\n");
|
||||
goto err_dsal;
|
||||
}
|
||||
|
||||
} /* end of FOREVER */
|
||||
|
||||
err_dsal:
|
||||
|
||||
/* shut down all sockets */
|
||||
close(topsockfd);
|
||||
if (dsockfd >= 0)
|
||||
close(dsockfd);
|
||||
|
||||
/* note that there is no way to exit this routine if things are good */
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0 /* EXAMPLE code follows */
|
||||
|
||||
/* ****************************************************** */
|
||||
/* EXAMPLE echo server code */
|
||||
|
||||
|
||||
|
||||
/* salServer.c - socket application server library */
|
||||
/*
|
||||
* salEchoServer - runs an echo server on a node
|
||||
*
|
||||
* Usage:
|
||||
* salEchoServer [ socket_family [, socket_type] ]
|
||||
* where:
|
||||
* socket_family defaults to AF_TIPC if not specified
|
||||
* socket_type defaults to SOCK_SEQPACKET if not specified
|
||||
*
|
||||
* This routine sets up a named server called "echo" at the
|
||||
* cluster scope. If not specified, the server will use AF_TIPC
|
||||
* and SOCK_SEQPACKET. Both the socket family and socket type can
|
||||
* be specified as parameters.
|
||||
*/
|
||||
#include "vxWorks.h"
|
||||
#include "sockLib.h"
|
||||
#include "dsi/salServer.h"
|
||||
|
||||
/* defines */
|
||||
|
||||
#define MAX_ECHO_SIZE 72 /* max message size */
|
||||
#define MAX_REQ_COUNT 5 /* max number of client requests */
|
||||
|
||||
/* forward declarations */
|
||||
|
||||
LOCAL SAL_RTN_STATUS salEchoServerRead (int sockfd, void * pData);
|
||||
|
||||
/* This routine creates and runs the server for the echo service */
|
||||
/* Note that if ai_family is not specified, the code will use AF_TIPC */
|
||||
|
||||
STATUS salEchoServer (
|
||||
int ai_family, /* protocol family to use */
|
||||
int sock_type /* socket type to use */
|
||||
)
|
||||
{
|
||||
SAL_SERVER_ID serverId; /* server structure */
|
||||
STATUS result; /* return value */
|
||||
int count; /* counter */
|
||||
|
||||
/* create server socket & register service with SNS */
|
||||
if (ai_family == 0)
|
||||
ai_family = AF_TIPC;
|
||||
if (sock_type == 0)
|
||||
sock_type = SOCK_SEQPACKET;
|
||||
|
||||
if ((serverId = salCreate ("echo@cluster",ai_family, sock_type, 0,
|
||||
NULL, 0)) == NULL)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* configure read routine for server */
|
||||
|
||||
salServerRtnSet (serverId, SAL_RTN_READ, salEchoServerRead);
|
||||
|
||||
/* request counter initialized */
|
||||
|
||||
count = 0;
|
||||
|
||||
/* activate the server (never returns unless a fatal error occurs */
|
||||
/* or the application processing routine requests a termination) */
|
||||
|
||||
result = salRun (serverId, &count);
|
||||
|
||||
/* close server socket & deregister service from SNS */
|
||||
|
||||
salDelete (serverId);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* This is the read routine for the echo server. */
|
||||
|
||||
LOCAL SAL_RTN_STATUS salEchoServerRead
|
||||
(
|
||||
int sockfd, /* active socket to read */
|
||||
void * pData /* user data */
|
||||
)
|
||||
{
|
||||
char message[MAX_ECHO_SIZE]; /* buffer for message */
|
||||
int msgSize; /* size of message */
|
||||
int * pCounter; /* request counter */
|
||||
|
||||
/* get message from specified client */
|
||||
|
||||
msgSize = recv (sockfd, message, sizeof (message), MSG_DONTWAIT);
|
||||
|
||||
if (msgSize <= 0)
|
||||
{
|
||||
/* client connection has been closed by client or has failed */
|
||||
|
||||
return SAL_SOCK_CLOSE;
|
||||
}
|
||||
|
||||
/* send message back to client */
|
||||
message[msgSize] = '\0'; /* null terminate string for printing */
|
||||
printf("SALECHOSERVER: Rcvd %d bytes. ('%s').\n",
|
||||
msgSize, message);
|
||||
|
||||
if (send (sockfd, message, msgSize, MSG_DONTWAIT) < 0)
|
||||
{
|
||||
/* client connection has failed */
|
||||
|
||||
close (sockfd);
|
||||
return SAL_SOCK_IGNORE;
|
||||
}
|
||||
|
||||
pCounter = pData;
|
||||
|
||||
if (*pCounter++ >= MAX_REQ_COUNT)
|
||||
return SAL_RUN_TERMINATE;
|
||||
|
||||
/* indicate that client connection is still OK */
|
||||
|
||||
return SAL_SOCK_KEEP;
|
||||
}
|
||||
|
||||
|
||||
/* salClient.c - socket application client library */
|
||||
/*
|
||||
* salEchoClient - runs an echo client on a node
|
||||
*
|
||||
* Usage:
|
||||
* salEchoClient "string"
|
||||
*
|
||||
* This routine sets up a connection to "echo@cluser" if it exists.
|
||||
* The "string" is sent to the listening server. The echo is checked
|
||||
* against the sent data for verification.
|
||||
*/
|
||||
/* This routine creates and runs a client of the echo service. */
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include "dsi/salClient.h"
|
||||
|
||||
#define MAX_ECHO_SIZE 72
|
||||
|
||||
STATUS salEchoClient
|
||||
(
|
||||
char * message /* message buffer */
|
||||
)
|
||||
{
|
||||
char reply[MAX_ECHO_SIZE]; /* reply buffer */
|
||||
int replySize; /* size of reply */
|
||||
int sockfd; /* socket file descriptor */
|
||||
int msgSize; /* size of the message passed */
|
||||
|
||||
msgSize = strlen(message);
|
||||
|
||||
/* set up client connection to ECHO server */
|
||||
|
||||
if ((sockfd = salOpen ("echo@cluster")) < 0)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* send message to ECHO server and get reply */
|
||||
|
||||
replySize = salCall (sockfd, message, msgSize,
|
||||
reply, sizeof (reply));
|
||||
|
||||
/* tear down client connection to ECHO server */
|
||||
|
||||
if (close (sockfd) <0)
|
||||
return ERROR;
|
||||
|
||||
/* check that reply matches message */
|
||||
if (replySize > 0)
|
||||
{
|
||||
reply[replySize] = '\0'; /* null terminate string for printing */
|
||||
printf("SALECHOCLIENT: Sent %d bytes. Received %d bytes ('%s').\n",
|
||||
msgSize, replySize, reply);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("SALECHOCLIENT: Sent %d bytes. Error on return (%d bytes received).\n",
|
||||
msgSize, replySize);
|
||||
}
|
||||
|
||||
if ((replySize != msgSize) || (memcmp (message, reply, msgSize) != 0))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* salTest.c - socket application client library */
|
||||
/*
|
||||
* salTest - runs a simple test with SAL
|
||||
*
|
||||
* Usage:
|
||||
* salTest n
|
||||
* where:
|
||||
* n is the test number
|
||||
*
|
||||
* This routine runs a test based on the simple code. It is designed to
|
||||
* allow the user to create separate simple test functions. This code
|
||||
* exists only to allow someone to test out something specific in a quick
|
||||
* manner.
|
||||
*/
|
||||
/* This routine creates and runs a client of the echo service. */
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include "dsi/salClient.h"
|
||||
|
||||
#define MAX_ECHO_SIZE 72
|
||||
|
||||
STATUS salTest
|
||||
(
|
||||
int testNum /* test number */
|
||||
)
|
||||
{
|
||||
char reply[MAX_ECHO_SIZE]; /* reply buffer */
|
||||
int replySize; /* size of reply */
|
||||
int sockfd; /* socket file descriptor */
|
||||
int msgSize; /* size of the message passed */
|
||||
SAL_SERVER_ID servId; /* server structure */
|
||||
|
||||
if (testNum == 0)
|
||||
{
|
||||
printf("salTest: usage\n");
|
||||
printf(" salTest(testNum)\n\n");
|
||||
printf(" where testNum values are:\n");
|
||||
printf(" 0 = usage\n");
|
||||
printf(" 1 = salCreate/pause/salDelete\n");
|
||||
printf(" 2 = ???\n");
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (testNum == 1)
|
||||
{
|
||||
printf("salTest: salCreate/pause/salDelete\n");
|
||||
|
||||
printf(" salCreate('mynode@cluster',30,5)\n");
|
||||
servId = salCreate ("mynode@cluster", 30, 5, 0, NULL, 0);
|
||||
printf(" servId = %.d\n",servId);
|
||||
|
||||
printf("Delay started (600 ticks)...\n");
|
||||
taskDelay(600); /* 600 ticks ~= 10 seconds */
|
||||
printf("... delay completed.\n");
|
||||
|
||||
printf(" salDelete...\n");
|
||||
salDelete(servId);
|
||||
printf(" ... done.\n");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,765 @@
|
||||
/* salClient.c - socket application client library */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2005,2007-2008, 2010-2011 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01x,22jul11,shi LP64 conversion
|
||||
01x,14jan10,pad System Viewer's instrumentation is available in the kernel
|
||||
only.
|
||||
01w,12may08,jpb Modifications for source build. Renamed
|
||||
WV_INSTRUMENTATION to _WRS_CONFIG_SV_INSTRUMENTATION.
|
||||
01v,04jan07,mze changed calls to freeaddrinfo to snsfreeaddrinfo
|
||||
01u,16may05,ebh Change ECHO to PING where needed
|
||||
01t,07mar05,ebh added distributed (AF_TIPC) support (original by fr)
|
||||
01s,22feb05,ebh update manually (zippy merge was not running)
|
||||
01r,10jan05,dgp update configuration references
|
||||
01q,15dec04,aeg added inclusion of unistd.h (SPR #105335).
|
||||
01p,13oct04,kk updated kernelBaseLib.h to private/kernelBaseLibP.h
|
||||
01o,13sep04,kk renamed rtpBaseLib.h to kernelBaseLib.h
|
||||
01n,01sep04,ymz modified documentation.
|
||||
01m,28may04,ymz removed internal definition of getpid.
|
||||
01l,20may04,ymz coding convention changes.
|
||||
01k,19may04,p_r documentation update
|
||||
01j,18may04,kk replaced rtpIdSelf() with MY_CTX_ID()
|
||||
01i,26apr04,ymz windview instrumentation.
|
||||
01h,08apr04,ymz code review changes.
|
||||
01g,06apr04,ymz fixed bug in salNameFind
|
||||
01f,30mar04,ymz renamed salSockFind to salSocketFind.
|
||||
added salNameFind routine.
|
||||
01e,20feb04,ymz code review changes
|
||||
01d,08jan04,als enable getpid() support for RTPs (SPR#92745); add examples
|
||||
01c,08dec03,als revised workaround for determining RTP ID
|
||||
01b,03dec03,als clean up (comments, errnos, etc.)
|
||||
01a,26nov03,als created
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This portion of the Socket Application Library (SAL) provides the
|
||||
infrastructure for implementing a socket-based client application.
|
||||
The routines provided by SAL allow client applications to communicate
|
||||
easily with socket-based server applications that are registered
|
||||
with the Socket Name Service (SNS).
|
||||
Some routines can also be used to communicate with unregistered
|
||||
server applications.
|
||||
SAL routines assume connection oriented message based communications.
|
||||
Although it could provide support for all protocols with the above
|
||||
features, the current implementation is supporting only local (single node)
|
||||
inter process communication using the COMP (Connection Oriented Message
|
||||
Passing) protocol and distributed (multi-node) inter process communication
|
||||
using the TIPC (Transparent Inter-Process Communication) protocol.
|
||||
|
||||
\sh SAL Client
|
||||
The SAL client API allows a client application to communicate with
|
||||
a specified server application by using socket descriptors.
|
||||
A client application can utilize SAL routines to communicate
|
||||
with different server applications in succession, or create
|
||||
multiple SAL clients that are each linked to a different server.
|
||||
|
||||
A client application typically calls salOpen() to configure a socket descriptor
|
||||
associated with a named server application. salOpen() simplifies
|
||||
the procedures needed to initialize the socket and its connection to
|
||||
the server. The server can be easily identified by a name, represented by
|
||||
a character string.
|
||||
The client application can then communicate with the server
|
||||
by passing the socket descriptor to standard socket API routines,
|
||||
such as send() and recv().
|
||||
Alternatively, the client application can perform a send() and recv()
|
||||
as a single operation using salCall().
|
||||
When the client application no longer needs to communicate with a server
|
||||
it calls close() to close the socket to the server.
|
||||
|
||||
A client application can utilize salSocketFind() to
|
||||
exercise more control over the establishment of communication
|
||||
with a server, as an alternative to using salOpen(). salSocketFind() can
|
||||
be used to determine the socket addresses related to a
|
||||
server, and then create a socket to communicate with the server. The client
|
||||
can therefore choose the server socket address or addresses that better suits
|
||||
its needs.
|
||||
A client can also use salNameFind() to identify one or more services based on a
|
||||
search pattern. Therefore, the client does not need to know the exact name of
|
||||
a service and, in case multiple names are found, it can choose which ones to
|
||||
use.
|
||||
|
||||
Because normal socket descriptors are used, the client application also has
|
||||
access to all of the standard socket API.
|
||||
|
||||
EXAMPLE
|
||||
The following code illustrates how to create a client
|
||||
that utilizes an "ping" service
|
||||
which simply returns each incoming message to the sender.
|
||||
The maximum size of a message is limited to MAX_PING_SIZE bytes.
|
||||
This service uses the connection-based COMP socket protocol.
|
||||
\cs
|
||||
/@ This routine creates and runs a client of the ping service. @/
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include "dsi/salClient.h"
|
||||
|
||||
#define MAX_PING_SIZE 72
|
||||
|
||||
STATUS pingClient
|
||||
(
|
||||
char * message, /@ message buffer @/
|
||||
int msgSize /@ size of message @/
|
||||
)
|
||||
{
|
||||
char reply[MAX_PING_SIZE]; /@ reply buffer @/
|
||||
int replySize; /@ size of reply @/
|
||||
int sockfd; /@ socket file descriptor @/
|
||||
|
||||
/@ set up client connection to PING server @/
|
||||
|
||||
if ((sockfd = salOpen ("ping")) < 0)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/@ send message to PING server and get reply @/
|
||||
|
||||
replySize = salCall (sockfd, message, msgSize,
|
||||
reply, sizeof (reply));
|
||||
|
||||
/@ tear down client connection to PING server @/
|
||||
|
||||
if (close (sockfd) <0)
|
||||
return ERROR;
|
||||
|
||||
/@ check that reply matches message @/
|
||||
|
||||
if ((replySize != msgSize) || (memcmp (message, reply, msgSize) != 0))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
\ce
|
||||
|
||||
CONFIGURATION
|
||||
To use the SAL client library, configure VxWorks with the INCLUDE_SAL_CLIENT
|
||||
component.
|
||||
|
||||
INCLUDE FILES: salClient.h
|
||||
|
||||
SEE ALSO: 'salServer', snsLib
|
||||
|
||||
APPEND salCommon.c
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include "errnoLib.h"
|
||||
#include "hostLib.h"
|
||||
#include "rtpLib.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#ifdef _WRS_KERNEL
|
||||
#include "private/kernelBaseLibP.h"
|
||||
#else
|
||||
#include "syscall.h"
|
||||
#endif /* _WRS_KERNEL */
|
||||
#include "taskLib.h"
|
||||
#include "sockLib.h"
|
||||
#include "dsi/private/salClientP.h"
|
||||
#include "dsi/private/snsLibP.h"
|
||||
|
||||
#ifndef _WRS_KERNEL
|
||||
#include "unistd.h" /* getpid */
|
||||
#endif /* _WRS_KERNEL */
|
||||
|
||||
#ifdef _WRS_KERNEL
|
||||
#ifdef _WRS_CONFIG_SV_INSTRUMENTATION
|
||||
#include "private/eventP.h"
|
||||
#endif /* _WRS_CONFIG_SV_INSTRUMENTATION */
|
||||
#endif /* _WRS_KERNEL */
|
||||
|
||||
/* forward declarations */
|
||||
|
||||
STATUS salSocketSearch
|
||||
(
|
||||
const char * name, /* service name in URL format */
|
||||
int sockFamily, /* desired socket address family */
|
||||
int sockType, /* desired socket type */
|
||||
int sockProtocol, /* desired socket protocol */
|
||||
struct addrinfo ** ppSockInfoList, /* list of socket entries */
|
||||
snsServDesc * service /* ptr to service descriptor */
|
||||
);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salOpen - establish communication with a named socket-based server
|
||||
*
|
||||
* This routine establishes a connection to the server application
|
||||
* corresponding to the SNS service name <name>. If the specified
|
||||
* service exists salOpen() tries to connect to each of the server's sockets
|
||||
* in turn, until it is successful or all sockets have been tried;
|
||||
* it returns the resulting socket descriptor.
|
||||
*
|
||||
* <name> is represented in the following URL format:
|
||||
*
|
||||
* '[SNS:]service_name[@scope]'
|
||||
*
|
||||
* If <name> contains wildcard characters, the routine will use
|
||||
* the first matching service.
|
||||
*
|
||||
* Refer to snsLib for more information on the format and the use
|
||||
* of wildcards.
|
||||
*
|
||||
* This routine uses the default socket options for the client socket it creates;
|
||||
* if special options are required by the client before completing the connection,
|
||||
* use salSocketFind() to establish communication with the server.
|
||||
*
|
||||
* User should close the returned socket using close().
|
||||
*
|
||||
* RETURNS:
|
||||
* >=0: the descriptor of the newly connected socket;
|
||||
* -1 : cannot establish communication.
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i S_salLib_INVALID_ARGUMENT
|
||||
* An invalid argument was passed to this routine.
|
||||
* \i S_salLib_SNS_UNAVAILABLE
|
||||
* Unable to establish connection to the SNS server task.
|
||||
* \i S_salLib_SNS_DID_NOT_REPLY
|
||||
* Did not receive a reply from the SNS server task.
|
||||
* \i S_salLib_SNS_PROTOCOL_ERROR
|
||||
* Received an invalid reply from the SNS server task.
|
||||
* \i S_salLib_SERVICE_NOT_FOUND
|
||||
* The specified service is not registered with SNS.
|
||||
* \i S_salLib_INVALID_SERVICE_DESCRIPTOR
|
||||
* The specified service was deregistered from SNS before all socket addresses
|
||||
* could be examined.
|
||||
* \i S_salLib_CLIENT_SOCKET_ERROR
|
||||
* Unable to connect to any of the specified server socket addresses.
|
||||
* \ie
|
||||
*
|
||||
* SEE ALSO: close(), salSocketFind(), snsLib
|
||||
*/
|
||||
|
||||
int salOpen
|
||||
(
|
||||
const char * name /* service name in URL format */
|
||||
)
|
||||
{
|
||||
struct addrinfo * pSockInfoList; /* info about server's sockets */
|
||||
snsServDesc service; /* service descriptor */
|
||||
int sockfd; /* client socket to the server */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_CONTROL, "entered, client '%s'", name);
|
||||
|
||||
/* validate parameters */
|
||||
|
||||
if ( (name == NULL) )
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE,
|
||||
"invalid parameters, NULL server Id 0x%x", name);
|
||||
errnoSet (S_salLib_INVALID_ARGUMENT);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* search from scratch */
|
||||
|
||||
service = NULL;
|
||||
|
||||
/* continue making connection attempts to services until a successful
|
||||
connection is made or the service list has been traversed */
|
||||
|
||||
FOREVER
|
||||
{
|
||||
pSockInfoList = NULL;
|
||||
|
||||
/* locate service & get info about server's sockets */
|
||||
|
||||
if (salSocketSearch (name, AF_UNSPEC, 0, 0, &pSockInfoList,
|
||||
&service) == ERROR)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ERROR, "failed, client '%s'", name);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* open connection to server */
|
||||
|
||||
sockfd = salAttach (pSockInfoList, NULL, 0);
|
||||
|
||||
#if defined(_WRS_CONFIG_SV_INSTRUMENTATION) && defined(_WRS_KERNEL)
|
||||
EVT_OBJ_SAL_STR_2 (EVENT_SALOPEN, name, sockfd);
|
||||
#endif /* _WRS_CONFIG_SV_INSTRUMENTATION */
|
||||
|
||||
/* release storage for info about server's sockets */
|
||||
|
||||
snsfreeaddrinfo (pSockInfoList);
|
||||
|
||||
/* break if connection to server is successful */
|
||||
|
||||
if (sockfd >= 0) break;
|
||||
}
|
||||
|
||||
/* indicate success or failure */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_CONTROL, "returned, sockfd 0x%0x", sockfd);
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salSocketFind - find sockets for a named socket-based server
|
||||
*
|
||||
* This routine looks for sockets related to a server application
|
||||
* registered with SNS, which matches the specified search criteria.
|
||||
* Each socket entry associated with the SNS service name <name>
|
||||
* is examined to see if it is compatible with the restrictions imposed by
|
||||
* <sockFamily>, <sockType>, and <sockProtocol>.
|
||||
* The search succeeds if at least one matching socket entry is found.
|
||||
*
|
||||
* <name> is represented in the following URL format:
|
||||
*
|
||||
* '[SNS:]service_name[@scope]'
|
||||
*
|
||||
* Please refer to snsLib for more information on the format.
|
||||
*
|
||||
* If <name> contains wildcard characters, the function will only
|
||||
* find the first matching service and retrieve its socket information.
|
||||
*
|
||||
* To obtain the complete list of service matching the given pattern, use the
|
||||
* salNameFind() routine.
|
||||
*
|
||||
* If <sockInfoList> is not NULL then a list of the matching socket entries
|
||||
* is created, and <sockInfoList> is set to the start of the list.
|
||||
* However if <sockInfoList> is NULL, or the service specified by <name>
|
||||
* does not exist, then no list of socket entries is created
|
||||
* and <sockInfoList> is left unchanged.
|
||||
*
|
||||
* WARNING
|
||||
* The storage for the socket list created by this routine must be released by
|
||||
* calling snsfreeaddrinfo() when the list is no longer required.
|
||||
*
|
||||
* RETURNS: OK or ERROR
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i S_salLib_INVALID_ARGUMENT
|
||||
* An invalid argument was passed to this routine.
|
||||
* \i S_salLib_SNS_UNAVAILABLE
|
||||
* Unable to establish connection to the SNS server task.
|
||||
* \i S_salLib_SNS_DID_NOT_REPLY
|
||||
* Did not receive a reply from the SNS server task.
|
||||
* \i S_salLib_SNS_PROTOCOL_ERROR
|
||||
* Received an invalid reply from the SNS server task.
|
||||
* \i S_salLib_SERVICE_NOT_FOUND
|
||||
* The specified service is not registered with SNS.
|
||||
* \i S_salLib_INVALID_SERVICE_DESCRIPTOR
|
||||
* The specified service was deregistered from SNS before all socket entries
|
||||
* could be examined.
|
||||
* \i S_salLib_NO_SOCKET_FOUND
|
||||
* The specified service has no sockets that match the desired criteria.
|
||||
* \ie
|
||||
*
|
||||
* SEE ALSO: salNameFind(), snsLib
|
||||
*/
|
||||
|
||||
STATUS salSocketFind
|
||||
(
|
||||
const char * name, /* service name in URL format */
|
||||
int sockFamily, /* desired socket address family */
|
||||
int sockType, /* desired socket type */
|
||||
int sockProtocol, /* desired socket protocol */
|
||||
struct addrinfo ** ppSockInfoList /* list of socket entries */
|
||||
)
|
||||
|
||||
{
|
||||
snsServDesc service = NULL;
|
||||
|
||||
/* start search from beginning of SNS list */
|
||||
|
||||
return salSocketSearch (name, sockFamily, sockType, sockProtocol,
|
||||
ppSockInfoList, &service);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salSocketSearch - continue to find sockets for a named socket based server
|
||||
*
|
||||
* This routine looks for sockets related to a server application, but the
|
||||
* search entry point is specified by the service descriptor which acts as an
|
||||
* index into the list of services. If <service> is NULL, then the search
|
||||
* starts at the beginning of the SNS list.
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
STATUS salSocketSearch
|
||||
(
|
||||
const char * name, /* service name in URL format */
|
||||
int sockFamily, /* desired socket address family */
|
||||
int sockType, /* desired socket type */
|
||||
int sockProtocol, /* desired socket protocol */
|
||||
struct addrinfo ** ppSockInfoList, /* list of socket entries */
|
||||
snsServDesc * service /* ptr to service descriptor */
|
||||
)
|
||||
{
|
||||
int snsClient; /* SNS client sockfd */
|
||||
SNS_FINDSERV_MSG msg; /* find service msg buffer */
|
||||
SNS_GET_NAMESOCK_REPLY_MSG reply; /* get socket reply buffer */
|
||||
int replySize; /* size of reply */
|
||||
int findErrno; /* error number for routine */
|
||||
|
||||
struct addrinfo dummySocket; /* (fake) first socket in list */
|
||||
struct addrinfo * lastSocket; /* ptr to last socket in list */
|
||||
int socketCount; /* # of sockets processed */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_CONTROL, "entered", 0);
|
||||
|
||||
/* validate parameters */
|
||||
|
||||
if ( (name == NULL) || (name[0] == '\0') ||
|
||||
(strlen (name) > SAL_SERV_NAME_MAXSIZE-1) )
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "invalid parameters", 0);
|
||||
errnoSet (S_salLib_INVALID_ARGUMENT);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* establish client to SNS server */
|
||||
|
||||
if ((snsClient = salSnsClientCreate ()) <0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "cannot contact SNS server", 0);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* create find service message */
|
||||
|
||||
msg.cmd = SNS_CMD_FINDSERV;
|
||||
msg.findSocket = TRUE;
|
||||
msg.rtpId = (long)getpid ();
|
||||
strcpy (msg.name, name);
|
||||
|
||||
/* search from specified service descriptor */
|
||||
msg.service = *service;
|
||||
|
||||
/* send find service message to SNS server and get reply */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "searching for '%s'", name);
|
||||
replySize = salCall (snsClient, &msg, sizeof (msg),
|
||||
&reply, sizeof (reply));
|
||||
|
||||
/*
|
||||
* set list of sockets to empty
|
||||
* NOTE: we use a dummy first entry (which is not returned to caller)
|
||||
* to avoid writing special code to handle insertion into an empty list
|
||||
*/
|
||||
|
||||
dummySocket.ai_next = NULL;
|
||||
lastSocket = &dummySocket;
|
||||
|
||||
/* build list of sockets for service, in the order they are returned */
|
||||
|
||||
for (socketCount = 1; ; socketCount++)
|
||||
{
|
||||
SNS_GETSOCK_MSG msg; /* get socket info msg buffer */
|
||||
|
||||
/* fail if reply is invalid */
|
||||
|
||||
findErrno = salSnsClientReplyCheck (replySize, sizeof (reply));
|
||||
if (findErrno != 0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "invalid reply, errno=%0x", findErrno);
|
||||
break;
|
||||
}
|
||||
|
||||
/* fail if service not known to SNS */
|
||||
|
||||
if (reply.service == NULL)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "service not known to SNS", 0);
|
||||
findErrno = reply.getSockErrno;
|
||||
break;
|
||||
}
|
||||
|
||||
/* compare socket info against hints to see if is acceptable */
|
||||
|
||||
if ( ((sockFamily == AF_UNSPEC) ||
|
||||
(sockFamily == reply.servSockInfo.ai_family)) &&
|
||||
((sockType == 0) ||
|
||||
(sockType == reply.servSockInfo.ai_socktype)) &&
|
||||
((sockProtocol == 0) ||
|
||||
(sockProtocol == reply.servSockInfo.ai_protocol))
|
||||
)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "socket %d matches hints", socketCount);
|
||||
|
||||
/*
|
||||
* Quit if caller isn't interested in knowing about the sockets
|
||||
* (one acceptable socket is all that is needed)
|
||||
*/
|
||||
|
||||
if (ppSockInfoList == NULL)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "socket list not required", 0);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate space for socket info & append to list.
|
||||
* (note that the "sockaddr_xxx" structure containing the actual
|
||||
* socket address is appended to the "addrinfo" struct rather than
|
||||
* being malloc'd separately -- this is in keeping with the approach
|
||||
* taken by the getaddrinfo() and freeaddrinfo() routines,
|
||||
* but we use malloc and snsfreeaddrinfo routines instead)
|
||||
*/
|
||||
|
||||
lastSocket->ai_next = malloc (sizeof (struct addrinfo) +
|
||||
reply.servSockInfo.ai_addrlen);
|
||||
lastSocket = lastSocket->ai_next;
|
||||
if (lastSocket == NULL)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "out of memory", 0);
|
||||
findErrno = errnoGet (); /* preserve errno from malloc */
|
||||
break;
|
||||
}
|
||||
|
||||
/* fill in socket info fields */
|
||||
|
||||
lastSocket->ai_flags = 0;
|
||||
lastSocket->ai_family = reply.servSockInfo.ai_family;
|
||||
lastSocket->ai_socktype = reply.servSockInfo.ai_socktype;
|
||||
lastSocket->ai_protocol = reply.servSockInfo.ai_protocol;
|
||||
lastSocket->ai_addrlen = reply.servSockInfo.ai_addrlen;
|
||||
lastSocket->ai_canonname = NULL;
|
||||
lastSocket->ai_addr = (struct sockaddr *)(lastSocket + 1);
|
||||
lastSocket->ai_next = NULL;
|
||||
|
||||
/* fill in socket address fields */
|
||||
|
||||
memcpy (lastSocket->ai_addr, &reply.servSockAddr,
|
||||
lastSocket->ai_addrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ignore socket that doesn't match hints criteria */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_ALL,
|
||||
"socket %d doesn't match hints", socketCount);
|
||||
}
|
||||
|
||||
/* bail out if SNS server has no more socket info to give */
|
||||
|
||||
if (reply.done)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "all sockets have been examined", 0);
|
||||
if (dummySocket.ai_next == NULL)
|
||||
{
|
||||
/* didn't find any acceptable sockets */
|
||||
findErrno = S_salLib_NO_SOCKET_FOUND;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* create get socket info message */
|
||||
|
||||
msg.cmd = SNS_CMD_GETSOCK;
|
||||
msg.rtpId = (long)getpid ();
|
||||
msg.service = reply.service;
|
||||
msg.numSockets = socketCount;
|
||||
|
||||
/* send get socket message to SNS server and get reply */
|
||||
|
||||
replySize = salCall (snsClient, &msg, sizeof (msg),
|
||||
&reply, sizeof (reply));
|
||||
}
|
||||
|
||||
/* terminate client to SNS server */
|
||||
|
||||
salSnsClientDelete (snsClient);
|
||||
|
||||
/* indicate results to caller */
|
||||
|
||||
if (findErrno != 0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ERROR, "failed, errno=%0x", findErrno);
|
||||
/* free up socket list if find operation failed */
|
||||
snsfreeaddrinfo (dummySocket.ai_next);
|
||||
errnoSet (findErrno);
|
||||
return ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SUCCESS, "succeeded", 0);
|
||||
|
||||
/*
|
||||
* pass back pointer to list of sockets (which may be empty)
|
||||
* if caller asked us to create such a list
|
||||
*/
|
||||
|
||||
if (ppSockInfoList != NULL)
|
||||
*ppSockInfoList = dummySocket.ai_next;
|
||||
|
||||
/* update service descriptor */
|
||||
|
||||
*service = reply.service;
|
||||
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salNameFind - find services with the specified name
|
||||
*
|
||||
* This function returns services with names that match the specified
|
||||
* <pattern>.
|
||||
*
|
||||
* Applications provide the buffer for storing the returned names. The function
|
||||
* returns the number of names found. The function also returns a cookie for
|
||||
* follow up searching.
|
||||
*
|
||||
* <pattern> is represented in the following URL format:
|
||||
*
|
||||
* '[SNS:]service_name[@scope]'
|
||||
*
|
||||
* If <pattern> contains wildcard characters, the routine will search for all
|
||||
* services that match the pattern.
|
||||
*
|
||||
* Refer to snsLib for more information on the format and the use
|
||||
* of wildcards.
|
||||
*
|
||||
* The function returns a number of services no greater than <num>.
|
||||
* If more matches are found the function can be called again to retrieve the
|
||||
* remaining values. The behavior of the function is determined by
|
||||
* the <ppCookie> field.
|
||||
*
|
||||
* In order to guarantee all data can be retrieved (possibly through
|
||||
* subsequent calls) when the function is called for the first time,
|
||||
* the <ppCookie> field needs to be
|
||||
* non-NULL and the value *<ppCookie> needs to be set to NULL.
|
||||
* If the returned value *<ppCookie> is still NULL, this means all the services
|
||||
* matching the <pattern> have been retrieved. XXX - Yiming to verify
|
||||
* If the returned value *<ppCookie> is not NULL, this means that more matches
|
||||
* might be available.
|
||||
* In this case, the client application can call salNameFind() again using the
|
||||
* returned <ppCookie> to retrieve further entries.
|
||||
*
|
||||
* Hence, in order to start a new search, either <ppCookie> is NULL (in which
|
||||
* case the function can not be called again to retrieve more values) or
|
||||
* *<ppCookie> is NULL.
|
||||
*
|
||||
* RETURNS:
|
||||
* >=0: number of services found,
|
||||
* -1: error.
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i S_salLib_INVALID_ARGUMENT
|
||||
* Invalid argument.
|
||||
* \i S_salLib_SNS_UNAVAILABLE
|
||||
* Unable to establish communications with the SNS server task.
|
||||
* \ie
|
||||
*
|
||||
* SEE ALSO: salSocketFind(), snsLib
|
||||
*/
|
||||
|
||||
int salNameFind
|
||||
(
|
||||
const char * pattern, /* services name pattern */
|
||||
char servName[][SAL_SERV_NAME_MAXSIZE],
|
||||
/* buffer to hold the returned name */
|
||||
int num, /* number of element in the servNames */
|
||||
void ** ppCookie /* cookie get/return last matching address */
|
||||
)
|
||||
|
||||
{
|
||||
int snsClient; /* socket to SNS server */
|
||||
int replySize; /* SNS server reply msg size */
|
||||
int numFound; /* number of matching found */
|
||||
int nameFindErrno; /* errNo for the command */
|
||||
SNS_FINDSERV_MSG msg; /* message to the SNS server */
|
||||
SNS_GET_NAMESOCK_REPLY_MSG reply; /* SNS server reply */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_CONTROL, "entered", 0);
|
||||
|
||||
if (NULL == pattern || '\0' == pattern[0] ||
|
||||
strlen (pattern) > SAL_SERV_NAME_MAXSIZE-1 ||
|
||||
NULL == servName || num<=0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "invalid parameters", 0);
|
||||
errnoSet (S_salLib_INVALID_ARGUMENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((snsClient = salSnsClientCreate ()) < 0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "Cannot connect to SNS server", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.cmd = SNS_CMD_FINDSERV;
|
||||
msg.findSocket = FALSE;
|
||||
msg.rtpId = (long)getpid();
|
||||
strcpy (msg.name, pattern);
|
||||
|
||||
/* if user passin NULL cookie reference, search from scratch */
|
||||
|
||||
if (NULL == ppCookie)
|
||||
msg.service = NULL;
|
||||
else
|
||||
msg.service = (snsServDesc) *ppCookie;
|
||||
|
||||
nameFindErrno = 0;
|
||||
|
||||
numFound = 0;
|
||||
|
||||
while (numFound < num)
|
||||
{
|
||||
replySize = salCall (snsClient, &msg, sizeof (msg),
|
||||
&reply, sizeof (reply));
|
||||
|
||||
nameFindErrno =
|
||||
salSnsClientReplyCheck (replySize, sizeof (reply));
|
||||
|
||||
if (nameFindErrno == 0)
|
||||
nameFindErrno = reply.getSockErrno;
|
||||
|
||||
if (nameFindErrno != 0)
|
||||
break;
|
||||
|
||||
if (NULL == reply.service)
|
||||
{
|
||||
/* not find anything in this loop, no need to continue */
|
||||
break;
|
||||
}
|
||||
|
||||
strcpy (servName[numFound], reply.serName);
|
||||
++numFound;
|
||||
|
||||
/* Check if necessary to continue */
|
||||
|
||||
if (reply.done)
|
||||
break;
|
||||
|
||||
msg.service = reply.service;
|
||||
}
|
||||
|
||||
salSnsClientDelete (snsClient);
|
||||
|
||||
if (nameFindErrno != 0)
|
||||
{
|
||||
errnoSet (nameFindErrno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ppCookie != NULL)
|
||||
*ppCookie = (reply.done)? NULL:reply.service;
|
||||
|
||||
return numFound;
|
||||
}
|
||||
@@ -0,0 +1,446 @@
|
||||
/* salCommon.c - socket application common library */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2008, 2010, 2012 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01n,12jul12,shi clean up warnings (WIND00357529)
|
||||
01m,14jan10,pad System Viewer's instrumentation is available in the kernel
|
||||
only.
|
||||
01l,12may08,jpb Modifications for source build. Renamed
|
||||
WV_INSTRUMENTATION to _WRS_CONFIG_SV_INSTRUMENTATION.
|
||||
01k,18apr05,ebh connectionless sockets are considered always connected
|
||||
01j,16feb05,ebh rename sockopt struct to salSockopt (it conflicts with
|
||||
target/h/wrn/coreip/net/socketvar.h)
|
||||
01i,01sep04,ymz renamed from salClientBase.c to salCommon.c (SPR 98185).
|
||||
01h,25may04,ymz merged salClientSns.c
|
||||
01g,20may04,ymz coding convention changes.
|
||||
01f,19may04,p_r documentation update
|
||||
01e,26apr04,ymz windview instrumentation.
|
||||
01d,08apr04,ymz iteration 5 code review changes
|
||||
01c,20feb04,ymz code review changes, added salCall timeout support
|
||||
01b,03dec03,als clean up (comments, errnos, etc.)
|
||||
01a,26nov03,als created
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This module contains the fundamental routines used by a SAL application,
|
||||
and utility routines used by the SAL client and server libraries.
|
||||
|
||||
The routines assist a SAL client to look up the Socket Name Service (SNS),
|
||||
and assist a SAL server to register register service with SNS.
|
||||
|
||||
These routines have been separated from the main SAL client and server library
|
||||
so that both the client and the server components can use this common code,
|
||||
without having to include each other's component.
|
||||
|
||||
INCLUDE FILES: salClient.h
|
||||
|
||||
NOMANUAL
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include "errnoLib.h"
|
||||
#include "ioLib.h"
|
||||
#include "semLib.h"
|
||||
#include "sockLib.h"
|
||||
#include "string.h"
|
||||
#include "sys/socket.h"
|
||||
#include "sys/un.h"
|
||||
#include "unistd.h"
|
||||
#include "dsi/private/salClientP.h"
|
||||
#include "dsi/private/snsLibP.h"
|
||||
#include "stdio.h" /* if using DPRINT */
|
||||
|
||||
#ifdef _WRS_KERNEL
|
||||
#ifdef _WRS_CONFIG_SV_INSTRUMENTATION
|
||||
#include "private/eventP.h"
|
||||
#endif /* _WRS_CONFIG_SV_INSTRUMENTATION */
|
||||
#endif /* _WRS_KERNEL */
|
||||
|
||||
/* defines */
|
||||
|
||||
#define DPRINT /* swap order of these two lines to enable/disable */
|
||||
#undef DPRINT /* swap order of these two lines to enable/disable */
|
||||
#ifdef DPRINT /* local file debug statements when DPRINT defined */
|
||||
# define dprintf printf
|
||||
#else
|
||||
# define dprintf if (0) printf
|
||||
#endif /* DPRINT */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salAttach - establish communication with a socket-based server
|
||||
*
|
||||
* This routine establishes a connection with the server application
|
||||
* using the sockets specified by <pSockInfoList>.
|
||||
* It tries to connect to each of the server's sockets in turn,
|
||||
* until it is successful or all sockets have been tried.
|
||||
*
|
||||
* User should close the attached socket using close().
|
||||
*
|
||||
* The <options> parameter points to an array of <numOptions> socket option
|
||||
* values that are applied to the client socket before a connection is attempted.
|
||||
* If no options are required, <numOptions> should be set to zero.
|
||||
*
|
||||
* If the socket is of a connectionless type, then this routine always
|
||||
* returns success. This allows the socket to be set up and be considered
|
||||
* "connected".
|
||||
*
|
||||
* RETURNS: >=0 opened socket file descriptor, -1 otherwise
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i S_salLib_INVALID_ARGUMENT
|
||||
* An invalid argument was passed to this routine.
|
||||
* \i S_salLib_CLIENT_SOCKET_ERROR
|
||||
* Unable to connect to server using any of the specified socket addresses.
|
||||
* \ie
|
||||
*
|
||||
* SEE ALSO: close().
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
int salAttach
|
||||
(
|
||||
struct addrinfo * pSockInfoList, /* list of server sockets */
|
||||
struct salSockopt * pSockOptions, /* array of socket options */
|
||||
int numOptions /* number of socket options */
|
||||
)
|
||||
{
|
||||
int newSockfd; /* new client socket */
|
||||
int currOpt; /* socket option counter */
|
||||
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_CONTROL, "entered, salAttach numOptions=%d.", numOptions);
|
||||
|
||||
/* validate parameters */
|
||||
|
||||
if ( (pSockInfoList == NULL) || (numOptions < 0) ||
|
||||
((numOptions > 0) && (pSockOptions == NULL)))
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "invalid parameters, numOptions 0x%x",
|
||||
numOptions);
|
||||
errnoSet (S_salLib_INVALID_ARGUMENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create connection to one of the specified server sockets */
|
||||
|
||||
newSockfd = -1;
|
||||
for (; pSockInfoList != NULL; pSockInfoList = pSockInfoList->ai_next)
|
||||
{
|
||||
/* create a client socket of the same type as the server uses */
|
||||
dprintf("salAttach: attempt sockfamily=%d.\n",pSockInfoList->ai_family);
|
||||
dprintf(" socktype=%d.\n",pSockInfoList->ai_socktype);
|
||||
dprintf(" protocol=%d.\n",pSockInfoList->ai_protocol);
|
||||
|
||||
newSockfd = socket (pSockInfoList->ai_family,
|
||||
pSockInfoList->ai_socktype,
|
||||
pSockInfoList->ai_protocol);
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "socket(...) returned fd=%d\n", newSockfd);
|
||||
|
||||
if (newSockfd == ERROR)
|
||||
{
|
||||
|
||||
/* try next server socket */
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* set the socket options (if any) */
|
||||
|
||||
for (currOpt = 0; currOpt < numOptions; currOpt++)
|
||||
{
|
||||
if (setsockopt (newSockfd, pSockOptions[currOpt].so_level,
|
||||
pSockOptions[currOpt].so_name,
|
||||
pSockOptions[currOpt].so_value,
|
||||
pSockOptions[currOpt].so_length) != OK)
|
||||
break;
|
||||
}
|
||||
|
||||
if (currOpt != numOptions)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ALL,
|
||||
"setsockopt(...) failed on option %d", currOpt);
|
||||
|
||||
/* get rid of the newly created client socket */
|
||||
|
||||
close (newSockfd);
|
||||
newSockfd = -1;
|
||||
|
||||
/* try next server socket */
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* connect to the server socket - if connection oriented */
|
||||
|
||||
if ((pSockInfoList->ai_socktype == SOCK_SEQPACKET) ||
|
||||
(pSockInfoList->ai_socktype == SOCK_STREAM))
|
||||
{
|
||||
|
||||
if (connect (newSockfd, pSockInfoList->ai_addr,
|
||||
pSockInfoList->ai_addr->sa_len) < 0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ALL,
|
||||
"connect(...) failed, socket 0x%x", newSockfd);
|
||||
|
||||
/* get rid of the newly created client socket */
|
||||
|
||||
close (newSockfd);
|
||||
newSockfd = -1;
|
||||
|
||||
/* try next server socket */
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
dprintf("salAttach: connection-less socket.\n");
|
||||
}
|
||||
|
||||
/* have successfully created a client socket, so exit loop */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* creation fails if unable to create a client socket */
|
||||
|
||||
if (newSockfd < 0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ERROR, "unable to create a client socket", 0);
|
||||
errnoSet (S_salLib_CLIENT_SOCKET_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_SUCCESS, "salAttach returned, sockfd 0x%0x",
|
||||
newSockfd);
|
||||
|
||||
return newSockfd;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salCall - invoke a socket-based server
|
||||
*
|
||||
* This routine sends a message to the server associated with the socket
|
||||
* descriptor <sockfd> and waits for a reply. The message consists of the
|
||||
* <sendLen> bytes pointed at by <pSendBuf>. The reply is placed in the
|
||||
* <recvLen> bytes pointed at by <pRecvBuf>. If fewer than <recvLen> bytes
|
||||
* are received the unused portion of <pRecvBuf> is not altered; if more
|
||||
* than <recvLen> bytes are received the unused portion of the reply may be
|
||||
* kept or discarded depending on the socket protocol being used.
|
||||
*
|
||||
* If the socket descriptor is used by multiple clients, mutual exclusion
|
||||
* needs to be provided before this routines is called. This is to avoid the
|
||||
* case when a reply is intercepted by a higher priority task sharing the
|
||||
* same <sockfd>.
|
||||
*
|
||||
* RETURNS:
|
||||
* # of bytes placed in reply buffer, for connection based transport,
|
||||
* 0 bytes may returned when the called end closes the connection;
|
||||
* ERROR otherwise.
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i S_salLib_INVALID_ARGUMENT
|
||||
* An invalid argument was passed to this routine.
|
||||
* \ie
|
||||
*/
|
||||
|
||||
int salCall
|
||||
(
|
||||
int sockfd, /* client socket fd */
|
||||
void * pSendBuf, /* message buffer */
|
||||
int sendLen, /* size of message buffer */
|
||||
void * pRecvBuf, /* reply buffer */
|
||||
int recvLen /* size of reply buffer */
|
||||
)
|
||||
{
|
||||
int replySize; /* actual size of reply */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_CONTROL, "entered with sockfd 0x%x", sockfd);
|
||||
|
||||
/* validate parameters */
|
||||
|
||||
if ( (sockfd < 0) || (pSendBuf == NULL) || (pRecvBuf == NULL) )
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE,
|
||||
"invalid parameters, socket 0x%0x", sockfd);
|
||||
errnoSet (S_salLib_INVALID_ARGUMENT);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
#if defined(_WRS_CONFIG_SV_INSTRUMENTATION) && defined(_WRS_KERNEL)
|
||||
EVT_OBJ_SAL_3 (EVENT_SALCALL_SENDREQ, sendLen, pSendBuf, sockfd);
|
||||
#endif /* _WRS_CONFIG_SV_INSTRUMENTATION */
|
||||
|
||||
/* send message to server */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "sending %d bytes", sendLen);
|
||||
if (send (sockfd, pSendBuf, sendLen, 0) == ERROR)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ERROR, "send to fd=%d failed", sockfd);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* get reply from server */
|
||||
|
||||
replySize = (int)recv (sockfd, pRecvBuf, recvLen, 0);
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "received %d bytes", replySize);
|
||||
|
||||
#if defined(_WRS_CONFIG_SV_INSTRUMENTATION) && defined(_WRS_KERNEL)
|
||||
EVT_OBJ_SAL_3 (EVENT_SALCALL_REPLY, replySize, pRecvBuf, sockfd);
|
||||
#endif /* _WRS_CONFIG_SV_INSTRUMENTATION */
|
||||
|
||||
|
||||
if (replySize == ERROR)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ERROR, "recv from fd=%d failed", sockfd);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* indicate success */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_CONTROL, "returned, replySize=%d", replySize);
|
||||
return replySize;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salSnsClientCreate - create an SNS client
|
||||
*
|
||||
* This routine establishes communication to the SNS server.
|
||||
*
|
||||
* RETURNS: socket fd if >=0; -1 if error.
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i S_salLib_SNS_UNAVAILABLE
|
||||
* Unable to establish communications with the SNS server task.
|
||||
* \ie
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
int salSnsClientCreate (void)
|
||||
{
|
||||
static struct addrinfo snsServerInfo; /* socket info for SNS server */
|
||||
static struct sockaddr_un snsServerAddr; /* socket address of SNS server */
|
||||
static BOOL addrCreated = FALSE; /* is server address created? */
|
||||
int sockfd; /* returned socket fd */
|
||||
|
||||
/* create info about the well-known socket for the SNS server */
|
||||
|
||||
if (!addrCreated)
|
||||
{
|
||||
snsServerAddr.sun_len = sizeof (snsServerAddr);
|
||||
snsServerAddr.sun_family = AF_LOCAL;
|
||||
strcpy (snsServerAddr.sun_path, SNS_SERVER_PATH);
|
||||
|
||||
snsServerInfo.ai_flags = 0;
|
||||
snsServerInfo.ai_family = AF_LOCAL;
|
||||
snsServerInfo.ai_socktype = SOCK_SEQPACKET;
|
||||
snsServerInfo.ai_protocol = 0;
|
||||
snsServerInfo.ai_addrlen = snsServerAddr.sun_len;
|
||||
snsServerInfo.ai_canonname = NULL;
|
||||
snsServerInfo.ai_addr = (struct sockaddr *)&snsServerAddr;
|
||||
snsServerInfo.ai_next = NULL;
|
||||
|
||||
addrCreated = TRUE;
|
||||
}
|
||||
|
||||
/* try to create a client that connects to the SNS server */
|
||||
|
||||
sockfd = salAttach (&snsServerInfo, NULL, 0);
|
||||
|
||||
/* indicate results to caller */
|
||||
|
||||
if (sockfd < 0)
|
||||
{
|
||||
errnoSet (S_salLib_SNS_UNAVAILABLE);
|
||||
}
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salSnsClientDelete - delete an SNS client
|
||||
*
|
||||
* This routine terminates communication with the SNS server.
|
||||
*
|
||||
* RETURNS: OK or ERROR.
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i S_salLib_INVALID_ARGUMENT
|
||||
* An invalid argument was passed to this routine.
|
||||
* \ie
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
STATUS salSnsClientDelete
|
||||
(
|
||||
int sockfd /* SNS client socket fd */
|
||||
)
|
||||
{
|
||||
return close (sockfd);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salSnsClientReplyCheck - validate the size of a reply from the SNS server
|
||||
*
|
||||
* This routine validates the size of a reply received from the SNS server
|
||||
* by comparing it to the expected reply size.
|
||||
*
|
||||
* RETURNS: S_salLib_SNS_DID_NOT_REPLY if size is negative;
|
||||
* S_salLib_SNS_PROTOCOL_ERROR if size does not match expected size;
|
||||
* 0 if size is correct.
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
int salSnsClientReplyCheck
|
||||
(
|
||||
int actualSize, /* message actual size */
|
||||
int expectedSize /* message expected size */
|
||||
)
|
||||
{
|
||||
int checkErrno; /* error code to return */
|
||||
|
||||
/* validate size of reply */
|
||||
|
||||
if (actualSize < 0)
|
||||
{
|
||||
checkErrno = S_salLib_SNS_DID_NOT_REPLY;
|
||||
}
|
||||
else if (actualSize != expectedSize)
|
||||
{
|
||||
checkErrno = S_salLib_SNS_PROTOCOL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkErrno = 0;
|
||||
}
|
||||
|
||||
/* indicate results of check */
|
||||
|
||||
return checkErrno;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,490 @@
|
||||
/* salSns.c - socket application serice naming library */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2005, 2011 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01u,22jul11,shi LP64 conversion
|
||||
01t,25apr05,ebh add 'scope' field to removal structure for distributed SAL
|
||||
01s,09apr05,ebh added distributed (AF_TIPC) support (original by fr)
|
||||
01r,22feb05,ebh update manually (zippy merge was not running)
|
||||
01q,11jan05,dgp convert mangen markup to apigen markup
|
||||
01p,15dec04,aeg added inclusion of unistd.h (SPR #105335).
|
||||
01o,13oct04,kk updated kernelBaseLib.h to private/kernelBaseLibP.h
|
||||
01n,10aug04,kk renamed rtpBaseLib.h to kernelBaseLib.h
|
||||
01m,10jun04,ymz made salRegsister and salDeregister private API.
|
||||
01l,27may04,ymz modified comment due to file name change.
|
||||
01k,21may04,ymz coding convention changes.
|
||||
01j,19may04,p_r documentation update
|
||||
01i,18may04,kk replaced rtpIdSelf() with MY_CTX_ID().
|
||||
01h,14apr04,ymz code review changes.
|
||||
01g,30mar04,ymz added salRemove support
|
||||
01f,02mar04,ymz code review changes
|
||||
01e,23feb04,ymz modified documentation.
|
||||
01d,08jan04,als enable getpid() support for RTPs (SPR#92745)
|
||||
01c,08dec03,als revised workaround for determining RTP ID
|
||||
01b,03dec03,als clean up (comments, errnos, etc.)
|
||||
01a,26nov03,als created
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This module contains routines that allow a SAL server to interact
|
||||
with the Socket Name Service.
|
||||
|
||||
These routines have been separated from the main SAL server library
|
||||
to allow an application that creates its own sockets
|
||||
to register a service with the SNS server task
|
||||
without forcing it to include unnecessary SAL code to create sockets.
|
||||
|
||||
INCLUDE FILES: snsLibP.h
|
||||
|
||||
\NOMANUAL
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include "errnoLib.h"
|
||||
#ifdef _WRS_KERNEL
|
||||
#include "private/kernelBaseLibP.h"
|
||||
#else
|
||||
#include "syscall.h"
|
||||
#include "unistd.h" /* getpid */
|
||||
#endif /* _WRS_KERNEL */
|
||||
#include "rtpLib.h"
|
||||
#include "string.h"
|
||||
#include "sockLib.h"
|
||||
#include "taskLib.h"
|
||||
#include "dsi/private/salClientP.h"
|
||||
#include "dsi/private/salServerP.h"
|
||||
#include "dsi/private/snsLibP.h"
|
||||
#include "tipc/tipc.h"
|
||||
|
||||
/* define */
|
||||
|
||||
#define DPRINT /* swap order of these two lines to enable/disable */
|
||||
#undef DPRINT /* swap order of these two lines to enable/disable */
|
||||
#ifdef DPRINT
|
||||
# define dprintf printf
|
||||
#else
|
||||
# define dprintf if (0) printf
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salRegister - register a service with SNS
|
||||
*
|
||||
* This routine registers the service name <name> with SNS. <name> is represented
|
||||
* in the following URL format:
|
||||
*
|
||||
* '[SNS:]service_name[@scope]'
|
||||
*
|
||||
* Refer to snsLib for more information on the format.
|
||||
*
|
||||
* The <sockInfoList> parameter points to a list of one or more socket entries
|
||||
* to be associated with the specified service.
|
||||
*
|
||||
* Server applications should typically call salCreate(),
|
||||
* however this routine is available to applications that wish
|
||||
* to create their server sockets themselves.
|
||||
*
|
||||
* RETURNS: service descriptor for service, or NULL if registration failed
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i S_salLib_INVALID_ARGUMENT
|
||||
* An invalid argument was passed to this routine.
|
||||
* \i S_salLib_SNS_UNAVAILABLE
|
||||
* Unable to establish communications with the SNS server task.
|
||||
* \i S_salLib_SNS_DID_NOT_REPLY
|
||||
* Did not receive a reply from the SNS server task.
|
||||
* \i S_salLib_SNS_PROTOCOL_ERROR
|
||||
* Received an invalid reply from the SNS server task.
|
||||
* \i S_salLib_SNS_OUT_OF_MEMORY
|
||||
* The SNS server task has insufficient memory to register the service.
|
||||
* \i S_salLib_SERVICE_ALREADY_EXISTS
|
||||
* The specified service is already registered with SNS.
|
||||
* \ie
|
||||
*
|
||||
* SEE ALSO: salDeregister(), salCreate (), snsLib
|
||||
*
|
||||
* \NOMANUAL
|
||||
*/
|
||||
|
||||
snsServDesc salRegister
|
||||
(
|
||||
const char * name, /* service name */
|
||||
struct addrinfo * pSockInfoList /* list of socket entries */
|
||||
)
|
||||
{
|
||||
int snsClient; /* SNS client socket */
|
||||
SNS_REGISTER_MSG msg; /* registration msg buffer */
|
||||
SNS_REGISTER_REPLY_MSG reply; /* registration reply buffer */
|
||||
int replySize; /* size of reply */
|
||||
int regErrno; /* error number for routine */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_CONTROL, "entered", 0);
|
||||
|
||||
/* validate parameters */
|
||||
|
||||
if ( (name == NULL) || (name[0] == '\0') ||
|
||||
(strlen (name) > sizeof(msg.name)-1) )
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "invalid service id", 0);
|
||||
errnoSet (S_salLib_INVALID_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( (pSockInfoList == NULL) || (pSockInfoList->ai_addr == NULL) ||
|
||||
(pSockInfoList->ai_addrlen > sizeof (msg.sockAddr)) )
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "invalid socket list", 0);
|
||||
errnoSet (S_salLib_INVALID_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* establish client to SNS server */
|
||||
|
||||
if ((snsClient = salSnsClientCreate ()) <0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "cannot contact SNS server", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create registration message, including info for first socket */
|
||||
|
||||
msg.cmd = SNS_CMD_REGISTER;
|
||||
msg.rtpId = (long)getpid ();
|
||||
msg.scope = SNS_SCOPE_NONE; /* don't override the scope */
|
||||
strcpy (msg.name, name);
|
||||
msg.sockInfo = *pSockInfoList;
|
||||
memcpy (&msg.sockAddr, pSockInfoList->ai_addr, pSockInfoList->ai_addrlen);
|
||||
pSockInfoList = pSockInfoList->ai_next;
|
||||
msg.done = (pSockInfoList == NULL);
|
||||
|
||||
/* send registration message and get reply */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "registering '%s'", name);
|
||||
replySize = salCall (snsClient, &msg, sizeof (msg),
|
||||
&reply, sizeof (reply));
|
||||
|
||||
/* continue registration until all sockets have been registered */
|
||||
|
||||
FOREVER
|
||||
{
|
||||
SNS_REGCONT_MSG msg; /* continue reg msg buffer */
|
||||
|
||||
/* quit if reply is invalid */
|
||||
|
||||
regErrno = salSnsClientReplyCheck (replySize, sizeof (reply));
|
||||
if (regErrno != 0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "invalid reply, errno=%0x", regErrno);
|
||||
break;
|
||||
}
|
||||
|
||||
/* quit if socket not successfully registered */
|
||||
|
||||
if (reply.service == NULL)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "SNS socket registration failed", 0);
|
||||
regErrno = reply.regErrno;
|
||||
break;
|
||||
}
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "SNS socket registration succeeded", 0);
|
||||
|
||||
/* return the scope */
|
||||
|
||||
/* quit if all sockets have been registered */
|
||||
|
||||
if (pSockInfoList == NULL)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "all sockets now registered", 0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* quit if the next socket to be registered is invalid */
|
||||
|
||||
if ( (pSockInfoList->ai_addr == NULL) ||
|
||||
(pSockInfoList->ai_addrlen > sizeof (msg.sockAddr)) )
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "invalid socket list", 0);
|
||||
|
||||
/* deregister the partially registered service */
|
||||
|
||||
salDeregister (reply.service);
|
||||
regErrno = S_salLib_INVALID_ARGUMENT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* create registration continuation message */
|
||||
|
||||
msg.cmd = SNS_CMD_REGCONT;
|
||||
msg.rtpId = (long)getpid ();
|
||||
msg.service = reply.service;
|
||||
msg.sockInfo = *pSockInfoList;
|
||||
memcpy (&msg.sockAddr, pSockInfoList->ai_addr,
|
||||
pSockInfoList->ai_addrlen);
|
||||
pSockInfoList = pSockInfoList->ai_next;
|
||||
msg.done = (pSockInfoList == NULL);
|
||||
|
||||
/* send registration continuation message and get reply */
|
||||
|
||||
replySize = salCall (snsClient, &msg, sizeof (msg),
|
||||
&reply, sizeof (reply));
|
||||
}
|
||||
|
||||
/* terminate client to SNS server */
|
||||
|
||||
salSnsClientDelete (snsClient);
|
||||
|
||||
/* indicate results to caller */
|
||||
if (regErrno != 0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ERROR, "failed, errno=0x%0x\n", regErrno);
|
||||
errnoSet (regErrno);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SUCCESS,
|
||||
"succeeded, service=0x%0x", reply.service);
|
||||
return reply.service;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salDeregister - deregister a service with SNS
|
||||
*
|
||||
* This routine deregisters the service specified by <servDesc> from SNS.
|
||||
*
|
||||
* Server applications should typically call salDelete(),
|
||||
* however this routine is available to applications that wish
|
||||
* to close their server sockets themselves.
|
||||
*
|
||||
* RETURNS: OK or ERROR
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i S_salLib_INVALID_ARGUMENT
|
||||
* An invalid argument was passed to this routine.
|
||||
* \i S_salLib_SNS_UNAVAILABLE
|
||||
* Unable to establish connection to the SNS server task.
|
||||
* \i S_salLib_SNS_DID_NOT_REPLY
|
||||
* Did not receive a reply from the SNS server task.
|
||||
* \i S_salLib_SNS_PROTOCOL_ERROR
|
||||
* Received an invalid reply from the SNS server task.
|
||||
* \i S_salLib_INVALID_SERVICE_DESCRIPTOR
|
||||
* Service descriptor is not registered with SNS, or has a different owner.
|
||||
* \ie
|
||||
*
|
||||
* SEE ALSO: salRegister(), salDelete(), salRemove()
|
||||
*
|
||||
* \NOMANUAL
|
||||
*/
|
||||
|
||||
STATUS salDeregister
|
||||
(
|
||||
snsServDesc servDesc /* service descriptor */
|
||||
)
|
||||
{
|
||||
int snsClient; /* SNS client socket */
|
||||
SNS_DEREGISTER_MSG msg; /* deregistration msg buffer */
|
||||
SNS_DEREGISTER_REPLY_MSG reply; /* deregistration reply buffer */
|
||||
int replySize; /* size of reply */
|
||||
int deregErrno; /* error number for routine */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_CONTROL, "entered, servDesc=0x%0x", servDesc);
|
||||
|
||||
/* validate parameters */
|
||||
|
||||
if (servDesc == NULL)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE,
|
||||
"invalid parameters, servDesc=0x%0x", servDesc);
|
||||
errnoSet (S_salLib_INVALID_ARGUMENT);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* establish client to SNS server */
|
||||
|
||||
if ((snsClient = salSnsClientCreate ()) <0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE,
|
||||
"cannot contact SNS server, servDesc=0x%0x", servDesc);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* create deregistration message */
|
||||
|
||||
msg.cmd = SNS_CMD_DEREGISTER;
|
||||
msg.rtpId = (long)getpid ();
|
||||
msg.service = servDesc;
|
||||
|
||||
/* send deregistration message and get reply */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "deregistering servDesc=0x%0x", servDesc);
|
||||
replySize = salCall (snsClient, &msg, sizeof (msg),
|
||||
&reply, sizeof (reply));
|
||||
|
||||
/* see if reply is invalid or service is not known to SNS */
|
||||
|
||||
deregErrno = salSnsClientReplyCheck (replySize, sizeof (reply));
|
||||
if (deregErrno != 0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "invalid reply, errno=%0x", deregErrno);
|
||||
}
|
||||
else
|
||||
{
|
||||
deregErrno = reply.deregErrno;
|
||||
}
|
||||
|
||||
/* terminate client to SNS server */
|
||||
|
||||
salSnsClientDelete (snsClient);
|
||||
|
||||
/* indicate results to caller */
|
||||
|
||||
if (deregErrno != 0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ERROR, "failed, errno=%0x", deregErrno);
|
||||
errnoSet (deregErrno);
|
||||
return ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SUCCESS, "succeeded, servDesc=0x%0x", servDesc);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* salRemove - Remove service from SNS by name
|
||||
*
|
||||
* This function removes a service identified by <name> from SNS.
|
||||
* Unlike salDelete(), which requires the caller and service owner to be in
|
||||
* the same memory space, this function can delete any service as long as
|
||||
* the service is visible to the caller. Therefore, a service with scope
|
||||
* 'node' can be deleted by any task on the same node, and a service
|
||||
* with scope 'private' can only be deleted by tasks in the same memory space.
|
||||
* Further, services of scope 'cluster' (or larger) can only be
|
||||
* deleted by the node that created them.
|
||||
*
|
||||
* <name> is represented in the following URL format:
|
||||
*
|
||||
* '[SNS:]service_name[@scope]'
|
||||
*
|
||||
* Refer to snsLib for more information on the format.
|
||||
*
|
||||
* <name> must uniquely identify a service:
|
||||
* \is
|
||||
* \i 'service_name'
|
||||
* should not contain any wildcard character
|
||||
* \i scope
|
||||
* must refer a specific level (i.e. the "upto_" prefix can not be used)
|
||||
* \ie
|
||||
*
|
||||
* NOTE
|
||||
* This routine removes only the service name from SNS. It does not remove the
|
||||
* service, nor does it close any of the sockets associated to it. These
|
||||
* features are provided by salDelete().
|
||||
*
|
||||
* RETURNS: OK if the service is removed, ERROR otherwise.
|
||||
*
|
||||
* ERRNO:
|
||||
* \is
|
||||
* \i S_salLib_INVALID_ARGUMENT
|
||||
* The service name is invalid
|
||||
* \i S_salLib_SERVICE_NOT_FOUND
|
||||
* The specified service is not found.
|
||||
* \ie
|
||||
*
|
||||
* SEE ALSO: salDelete(), salCreate(), snsLib
|
||||
*/
|
||||
|
||||
STATUS salRemove
|
||||
(
|
||||
const char * name /* service name */
|
||||
)
|
||||
|
||||
{
|
||||
SNS_REMOVE_MSG msg; /* message sent to the SNS server */
|
||||
SNS_REMOVE_REPLY_MSG reply; /* reply from the SNS server */
|
||||
int snsClient; /* SNS client socket */
|
||||
int removeErrno; /* error number for routine */
|
||||
int replySize; /* SNS server replied size */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_CONTROL, "entered, servname=%s", name);
|
||||
|
||||
if (NULL == name || '\0' == name[0] ||
|
||||
(strlen (name) > sizeof(msg.name)-1))
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE,
|
||||
"invalid parameters, name=0x%0x", name);
|
||||
errnoSet (S_salLib_INVALID_ARGUMENT);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* establish client to SNS server */
|
||||
|
||||
if ((snsClient = salSnsClientCreate ()) <0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE,
|
||||
"cannot contact SNS server, snsClient=0x%0x", snsClient);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
msg.cmd = SNS_CMD_REMOVE;
|
||||
msg.rtpId = (long)getpid();
|
||||
msg.scope = SNS_SCOPE_NONE;
|
||||
strcpy (msg.name, name);
|
||||
|
||||
/* send remove message and get reply */
|
||||
|
||||
SAL_DEBUG (SAL_DEBUG_ALL, "removing service=%s", name);
|
||||
|
||||
replySize = salCall (snsClient, &msg, sizeof (msg),
|
||||
&reply, sizeof (reply));
|
||||
|
||||
/* see if reply is invalid or service is not known to SNS */
|
||||
|
||||
removeErrno = salSnsClientReplyCheck (replySize, sizeof (reply));
|
||||
|
||||
if (removeErrno != 0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SEVERE, "invalid reply, errno=0x%x", removeErrno);
|
||||
}
|
||||
else
|
||||
{
|
||||
removeErrno = reply.removeErrno;
|
||||
}
|
||||
|
||||
/* terminate client to SNS server */
|
||||
|
||||
salSnsClientDelete (snsClient);
|
||||
|
||||
/* indicate results to caller */
|
||||
|
||||
if (removeErrno != 0)
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_ERROR, "failed, errno=0x%x", removeErrno);
|
||||
errnoSet (removeErrno);
|
||||
return ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
SAL_DEBUG (SAL_DEBUG_SUCCESS, "succeeded, name=%s", name);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/* snsCommon.c - Socket Name Service common library */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004-2005 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*/
|
||||
#include "copyright_wrs.h"
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01a,31mar05,ebh added new entries for snsShow to display truncated scope text
|
||||
01a,22aug04,ymz created (extracted from snsLib.c). SPR 98183
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This library contains the Socket Name Service (SNS) common variable
|
||||
and routine used by snsLib.c and snsShow.c. Therefore, both snsLib
|
||||
and snsShow components can use the common data and routine but still
|
||||
decoupled from each other in the project build.
|
||||
|
||||
INCLUDE FILES" snsLibP.h
|
||||
|
||||
NOMANUAL
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include "dsi/private/snsLibP.h"
|
||||
|
||||
/* defines */
|
||||
|
||||
/* globals */
|
||||
|
||||
/* table used in converting text form of scope to numeric form */
|
||||
|
||||
const struct sns_scope_info snsScopeTbl[SNS_NUM_SCOPES] =
|
||||
{
|
||||
{ SNS_SCOPE_PRIVATE, SNS_SCOPE_PRIVATE_STR, SNS_SCOPE_UPTO_PRIVATE_STR, SNS_SCOPE_SHOW_PRIVATE_STR},
|
||||
{ SNS_SCOPE_NODE, SNS_SCOPE_NODE_STR, SNS_SCOPE_UPTO_NODE_STR, SNS_SCOPE_SHOW_NODE_STR},
|
||||
{ SNS_SCOPE_CLUSTER, SNS_SCOPE_CLUSTER_STR, SNS_SCOPE_UPTO_CLUSTER_STR, SNS_SCOPE_SHOW_CLUSTER_STR},
|
||||
{ SNS_SCOPE_SYSTEM, SNS_SCOPE_SYSTEM_STR, SNS_SCOPE_UPTO_SYSTEM_STR, SNS_SCOPE_SHOW_SYSTEM_STR}
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* snsPatMatch - matching a wildcard pattern with a name string
|
||||
*
|
||||
* This function matches a pattern with a name string, the function only interpret
|
||||
* '*'s and/or '?'s as metacharacter for wildcard matching. This function
|
||||
* does not intepret other classic regular expression such as '.', brackets ,
|
||||
* backslash escape, nested grouping etc.
|
||||
*
|
||||
* Note, '*' denotes any number of characters, including zero,
|
||||
* '?' denote any single character matching.
|
||||
*
|
||||
* RETURNS: 1 if matched, 0 otherwise.
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
int snsPatMatch
|
||||
(
|
||||
const char * pat, /* pattern */
|
||||
const char * str /* string to be matched */
|
||||
)
|
||||
|
||||
{
|
||||
/*
|
||||
* The following code should be further optimized to reduce the
|
||||
* number of recursive calls.
|
||||
*/
|
||||
|
||||
switch (*pat)
|
||||
{
|
||||
case '\0': return !*str;
|
||||
case '*' : return (snsPatMatch (pat+1, str)) ||
|
||||
(*str && snsPatMatch (pat, str+1));
|
||||
case '?' : return *str && snsPatMatch (pat+1, str+1);
|
||||
default : return *pat == *str && snsPatMatch (pat+1, str+1);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,185 @@
|
||||
/* snsRtpHook.c - Socket Name Service hook for RTP deletion */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004-2007, 2009, 2011, 2013 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01g,16sep13,f_f fix static overrun (WIND00435182)
|
||||
01f,19jul11,shi LP64 conversion
|
||||
01e,03dec09,cww Moved rtp funcbind pointers
|
||||
01d,20jun07,ebh remove unnecessary variable taskId in snsRtpHookInit
|
||||
01c,08mar06,ebh correct typo as per code review
|
||||
01b,12jan05,bwa added check for presence of RTP hooks (SPR105673).
|
||||
01a,02sep04,ymz created (moved from snsLib.c)
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
|
||||
This file contains routines to invoke socket name service (SNS) to
|
||||
cleanup service records when the RTP where the service resides is deleted.
|
||||
|
||||
During the SNS initialization, SNS adds a routine to the RTP delete hook.
|
||||
The initialization process preallocates a socket used by SNS to receive RTP
|
||||
delete events.
|
||||
When a RTP is deleted, the SNS hook is invoked. The routine sends an
|
||||
asynchronous message to the SNS server asking for cleanup.
|
||||
|
||||
The routines in this file runs in the kernel, no matter whether the SNS
|
||||
server is running in the kernel or in a RTP.
|
||||
|
||||
\NOMANUAL
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <rtpLibCommon.h>
|
||||
#include <stdio.h>
|
||||
#include <taskLib.h>
|
||||
#include <sockLib.h>
|
||||
#include <private/rtpLibP.h>
|
||||
#include <dsi/private/salClientP.h>
|
||||
#include <dsi/private/snsLibP.h>
|
||||
|
||||
/* locals */
|
||||
|
||||
LOCAL int snsCleanUpSockFd; /* socket to sns server to request cleanup */
|
||||
|
||||
/* forward declarations */
|
||||
|
||||
LOCAL void snsCleanupRtnInit (void);
|
||||
LOCAL void snsCleanupHook (const RTP_ID rtpId, const int exitCode);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* snsRtpHookInit - initialize the cleanup mechanism
|
||||
*
|
||||
* This function initializes the cleanup mechanism. A task is spawned so the
|
||||
* vxWorks system initialization process does not get delayed.
|
||||
*
|
||||
* RETURNS: OK if initialization completes, ERROR otherwise.
|
||||
*
|
||||
* \NOMANUAL
|
||||
*/
|
||||
|
||||
STATUS snsRtpHookInit
|
||||
(
|
||||
int pri /* task priority */
|
||||
)
|
||||
{
|
||||
if (_func_rtpDeleteHookAdd == NULL)
|
||||
{
|
||||
printf ("Can't initialize SNS cleanup subsystem.\n"
|
||||
"RTP hooks not present in the system.\n");
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
if((taskSpawn ("tSnsCleanupInit",
|
||||
pri, /* priority */
|
||||
0, /* task options */
|
||||
20000, /* stack space */
|
||||
(FUNCPTR) snsCleanupRtnInit,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0 )) == TASK_ID_ERROR)
|
||||
{
|
||||
printf(" Cannot spawn SNS cleanup init task...\n");
|
||||
return ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* snsCleanupRtnInit - initializes SNS cleanup hook
|
||||
*
|
||||
* This routine initializes SNS cleanup mechanism by setting up RTP
|
||||
* deletion hook and attaching a connection to the SNS server.
|
||||
*
|
||||
* RETURNS: OK if the initialization is successful, ERROR otherwise.
|
||||
*
|
||||
* \NOMANUAL
|
||||
*/
|
||||
|
||||
LOCAL void snsCleanupRtnInit (void)
|
||||
{
|
||||
int i; /* number of attempts attaching to SNS server */
|
||||
|
||||
if ( _func_rtpHandleIdGet == NULL)
|
||||
{
|
||||
printf(" SNS cleanup init failed...\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<SNS_INIT_RETRY; i++)
|
||||
{
|
||||
|
||||
/* wait if sns server is not started yet */
|
||||
|
||||
if ((snsCleanUpSockFd = salSnsClientCreate ()) <0)
|
||||
taskDelay (SNS_INIT_TIMEOUT*10);
|
||||
else
|
||||
{
|
||||
if (_func_rtpDeleteHookAdd (snsCleanupHook, FALSE) != OK)
|
||||
{
|
||||
salSnsClientDelete (snsCleanUpSockFd);
|
||||
snsCleanUpSockFd = -1;
|
||||
printf(" Cannot install SNS cleanup hook...\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* snsCleanUpSockFd remains opened, no close mechanism
|
||||
* see comments in snsCleanupHook routine
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf(" SNS cleanup init failed...\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* snsCleanupHook - notify SNS server a rtp is being deleted.
|
||||
*
|
||||
* This routine notifies SNS server that a RTP is being deleted.
|
||||
*
|
||||
* RETURNS: N/A.
|
||||
*
|
||||
* \NOMANUAL
|
||||
*/
|
||||
|
||||
LOCAL void snsCleanupHook
|
||||
(
|
||||
const RTP_ID rtpId, /* rtp being deleted */
|
||||
const int exitCode
|
||||
)
|
||||
|
||||
{
|
||||
SNS_SERV_CLEANUP_MSG msg;
|
||||
|
||||
msg.cmd = SNS_CMD_CLEANUP;
|
||||
msg.rtpId = (long) _func_rtpHandleIdGet (rtpId);
|
||||
|
||||
(void) send (snsCleanUpSockFd, (void *) &msg, sizeof (SNS_SERV_CLEANUP_MSG),
|
||||
MSG_DONTWAIT);
|
||||
|
||||
/* we do not check if send is fails, just keep sending
|
||||
* the alternative is to close the socket and remove delete hook,
|
||||
* but it is not safe to delete the hook within the hook routine (the
|
||||
* next hook in the hook array may get skipped to call),
|
||||
* so we take the policy of doing nothing.
|
||||
*/
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
/* snsShow.c - Socket Name Service show routines */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003-2007, 2012 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01r,12jul12,shi clean up warnings (WIND00357529)
|
||||
01q,15oct07,ebh handle late change in TIPC address with snsShow()
|
||||
01p,20jun07,ebh close socket created when getting TIPC address in snsShow()
|
||||
01o,06jan06,mze change to getSockName from ioctl call
|
||||
01n,18mar05,ebh add support for distributed SAL
|
||||
01m,10jan05,dgp update configuration references, migrate to apigen markup
|
||||
01l,09sep04,ymz improve snsShow output layout (SPR # 101643).
|
||||
01k,01sep04,ymz modified to use routines in snsCommon.c (SPR 98183).
|
||||
01j,10jun04,ymz modified documentation.
|
||||
01i,27may04,ymz removed pSnsShowConvRtn.
|
||||
01h,24may04,ymz coding convention changes.
|
||||
01g,19may04,p_r documentation update
|
||||
01f,14apr04,ymz code review changes.
|
||||
01e,30mar04,ymz modified to support wildcard pattern.
|
||||
01d,02mar04,ymz code review changes
|
||||
01c,02feb04,ymz added message printing even if SNS has no servic record.
|
||||
Decoupled with TCP/IP stack.
|
||||
01b,03dec03,als clean up (comments, errnos, etc.)
|
||||
01a,26nov03,als created
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This library provides routines to show information about the services
|
||||
registered with Socket Name Service (SNS), including the name and scope
|
||||
of the service and the socket address(es) of the server application
|
||||
that provides the service.
|
||||
|
||||
An SNS server task must be operational, otherwise no information
|
||||
can be obtained about SNS.
|
||||
|
||||
CONFIGURATION
|
||||
To use the SNS show facility, configure VxWorks with the INCLUDE_SNS_SHOW
|
||||
component.
|
||||
|
||||
INCLUDE FILES: snsLib.h
|
||||
|
||||
SEE ALSO: snsLib
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <errnoLib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "dsi/private/salClientP.h"
|
||||
#include "dsi/private/snsLibP.h"
|
||||
#include <sockLib.h>
|
||||
#include <tipc/tipc.h>
|
||||
|
||||
/* defines */
|
||||
|
||||
#define SNS_SHOW_NAME_LEN 27 /* length of name field */
|
||||
#define SNS_SHOW_SCOPE_LEN 6 /* length of scope field */
|
||||
#define SNS_SHOW_FAMILY_LEN 7 /* length of family field */
|
||||
#define SNS_SHOW_TYPE_LEN 8 /* length of type field */
|
||||
#define SNS_SHOW_PROTO_LEN 4 /* length of protocol field */
|
||||
#define SNS_SHOW_ADDR_LEN 26 /* length of address field */
|
||||
#define SNS_INVALID_TIPC_ADDR (tipc_addr(1,1,0)) /* invalid address */
|
||||
|
||||
/* locals */
|
||||
|
||||
uint ownTipcAddr = SNS_INVALID_TIPC_ADDR; /* the TIPC address of this node */
|
||||
|
||||
/* forward declarations */
|
||||
|
||||
LOCAL int snsShowServ (SNS_NEXTSERV_REPLY_MSG * pServInfo, int sockfd);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* snsShow - show information about services in the SNS directory
|
||||
*
|
||||
* This routine displays information about the services registered with SNS.
|
||||
* <servName> is represented in URL format:
|
||||
*
|
||||
* '[SNS:]service_name[@scope]'
|
||||
*
|
||||
* where the parts in brackets, [ ], are optional.
|
||||
*
|
||||
* 'SNS:' represent the URL service, i.e. the Socket Name Service. It is the
|
||||
* only value accepted and can be omitted.
|
||||
* '@<scope>' represents the visibility of the service name within the system.
|
||||
* It can take several values, depending from the context and the application
|
||||
* needs.
|
||||
*
|
||||
* If the the scope is not specified, "@node" is assumed.
|
||||
*
|
||||
* The URL representation is case insensitive.
|
||||
*
|
||||
* All services whose name begins with the string specified by 'service_name'
|
||||
* are listed. 'service_name' may contain wildcard characters '*' or '?' for
|
||||
* name pattern matching, where '*' denotes matching as many characters as
|
||||
* possible, including zero number of character, '?' denotes matching any single
|
||||
* character.
|
||||
*
|
||||
* If <servName> is NULL, or points to a null string,
|
||||
* then all services in the SNS directory are listed.
|
||||
*
|
||||
* The information displayed for each service listed includes:
|
||||
* \ml
|
||||
* \m -
|
||||
* the service name
|
||||
* \m -
|
||||
* the service scope
|
||||
* \m -
|
||||
* socket address family associated with the service
|
||||
* \m -
|
||||
* socket type associated with the service
|
||||
* \m -
|
||||
* socket protocol number associated with the service: 0 represents the
|
||||
* dummy value, since the socket address family and type are known.
|
||||
* \m -
|
||||
* socket address associated with the service
|
||||
* \me
|
||||
*
|
||||
* Examples,
|
||||
*
|
||||
* \ts
|
||||
* NAME............. | SCOPE | FAMILY | .TYPE.. | PROTO | .... ADDR
|
||||
* ------------------+-------+----------+------------+-------+-----------------
|
||||
* webAdmin | node | LOCAL | SEQPKT | 0 | /comp/socket/0x4
|
||||
* eventBlog | priv | LOCAL | SEQPKT | 0 | /comp/socket/0x8
|
||||
* clusterTimeServer | clust | TIPC | SEQPKT | 0 * | <1.1.5>,1086717964
|
||||
* \te
|
||||
*
|
||||
* RETURNS: N/A.
|
||||
*
|
||||
* SEE ALSO: snsLib
|
||||
*/
|
||||
|
||||
void snsShow
|
||||
(
|
||||
const char * servName /* service name prefix */
|
||||
)
|
||||
{
|
||||
int snsClient; /* SNS client socket */
|
||||
SNS_NEXTSERV_MSG msg; /* next service msg buffer */
|
||||
SNS_NEXTSERV_REPLY_MSG reply; /* next service reply buffer */
|
||||
int replySize; /* size of reply */
|
||||
int showErrno; /* error number for command */
|
||||
int nameLen; /* length of service name prefix */
|
||||
UINT total; /* total entries found */
|
||||
int sockfd; /* socket to get tipc address */
|
||||
struct sockaddr_tipc dsalTipcAddr; /* our TIPC address */
|
||||
int addrSize; /* address size */
|
||||
|
||||
/* establish client to SNS server */
|
||||
|
||||
if ((snsClient = salSnsClientCreate ()) <0)
|
||||
{
|
||||
printf ("ERROR 0x%08x\n", errnoGet ());
|
||||
return;
|
||||
}
|
||||
|
||||
/* compute length of service name prefix */
|
||||
|
||||
if (servName != NULL)
|
||||
nameLen = (int)strlen (servName);
|
||||
else
|
||||
nameLen = 0;
|
||||
|
||||
total = 0;
|
||||
|
||||
/* print header */
|
||||
|
||||
printf (" NAME SCOPE FAMILY TYPE PROTO ADDR\n");
|
||||
printf ("-------------------------- ----- ------ ------- ----- --------------------------\n");
|
||||
|
||||
/*
|
||||
* The first time through, try to determine the current TIPC address
|
||||
* and use it for subsequent calls to this Show command. The
|
||||
* variable "ownTipcAddr" is initialized to an invalid value on
|
||||
* startup
|
||||
*/
|
||||
|
||||
if (ownTipcAddr == SNS_INVALID_TIPC_ADDR || ownTipcAddr == 0)
|
||||
{
|
||||
ownTipcAddr = 0;
|
||||
sockfd = socket (AF_TIPC, SOCK_DGRAM, 0);
|
||||
if (sockfd >= 0)
|
||||
{
|
||||
/* Determine own address information */
|
||||
addrSize = sizeof(dsalTipcAddr);
|
||||
if (getsockname(sockfd, (struct sockaddr *)&dsalTipcAddr, &addrSize) == OK)
|
||||
{
|
||||
/* FIXME: there is no support for a reconfiguration of TIPC */
|
||||
ownTipcAddr = dsalTipcAddr.addr.id.node;
|
||||
}
|
||||
close(sockfd);
|
||||
}
|
||||
}
|
||||
|
||||
/* loop through all SNS services */
|
||||
|
||||
msg.cmd = SNS_CMD_NEXTSERV;
|
||||
msg.service = NULL;
|
||||
FOREVER
|
||||
{
|
||||
/* send next service message and get reply */
|
||||
|
||||
replySize = salCall (snsClient, &msg, sizeof (msg),
|
||||
&reply, sizeof (reply));
|
||||
|
||||
/* fail if reply is invalid */
|
||||
|
||||
showErrno = salSnsClientReplyCheck (replySize, sizeof (reply));
|
||||
if (showErrno != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* fail if next service could not be located
|
||||
* (i.e. current service has been deregistered)
|
||||
*/
|
||||
|
||||
showErrno = reply.nextServErrno;
|
||||
if (showErrno != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* exit loop if all services have been returned */
|
||||
|
||||
if (reply.service == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* see if service name matches prefix specified for show command */
|
||||
|
||||
if ( (servName == NULL) ||
|
||||
(snsPatMatch (servName, reply.servName) == 1) )
|
||||
{
|
||||
/* display info about the service; exit loop if an error occurs */
|
||||
|
||||
showErrno = snsShowServ (&reply, snsClient);
|
||||
if (showErrno != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
++total;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* don't bother printing anything for this service */
|
||||
}
|
||||
|
||||
/* advance to next service in SNS database */
|
||||
|
||||
msg.service = reply.service;
|
||||
}
|
||||
|
||||
/* get rid of client to SNS server */
|
||||
|
||||
salSnsClientDelete (snsClient);
|
||||
|
||||
/* indicate results to user */
|
||||
|
||||
if (showErrno != 0)
|
||||
{
|
||||
errnoSet (showErrno);
|
||||
printf ("ERROR 0x%08x\n", showErrno);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 == total)
|
||||
printf ("\n*** No service found ***\n\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* snsShowServ - show information about a given SNS service
|
||||
*
|
||||
* This routine displays information about a service registered with SNS,
|
||||
* including:
|
||||
* \ms
|
||||
* \m -
|
||||
* service name
|
||||
* \m -
|
||||
* service scope (private, local, cluster, or global)
|
||||
* \m -
|
||||
* service owner (kernel or RTP id)
|
||||
* \m -
|
||||
* service availability (indicates partial registration)
|
||||
* \m -
|
||||
* socket addresses associated with service
|
||||
* \me
|
||||
*
|
||||
* RETURNS:
|
||||
* \is
|
||||
* \i S_salLib_SNS_DID_NOT_REPLY
|
||||
* if SNS server task failed to reply,
|
||||
* \i S_salLib_SNS_PROTOCOL_ERROR
|
||||
* if SNS server task sent invalid reply,
|
||||
* \i S_salLib_INVALID_SERVICE_DESCRIPTOR
|
||||
* if service became deregistered during the display process,
|
||||
* \i 0
|
||||
* if service information was displayed successfully
|
||||
* \ie
|
||||
*
|
||||
* \NOMANUAL
|
||||
*/
|
||||
|
||||
LOCAL int snsShowServ
|
||||
(
|
||||
SNS_NEXTSERV_REPLY_MSG * pServInfo, /* ptr to next service reply */
|
||||
int snsClient /* SNS client socket */
|
||||
)
|
||||
{
|
||||
SNS_GETSOCK_MSG msg; /* get socket info msg buffer */
|
||||
SNS_GET_NAMESOCK_REPLY_MSG reply; /* get socket info reply buffer */
|
||||
int replySize; /* size of reply */
|
||||
int showErrno; /* error number for command */
|
||||
int scopeIdx; /* array index for service scope */
|
||||
|
||||
/* do not display yet fully registered service */
|
||||
|
||||
if (pServInfo->servAvail != TRUE)
|
||||
return 0;
|
||||
|
||||
/* translate service scope into string form */
|
||||
|
||||
for (scopeIdx = 0; scopeIdx < SNS_NUM_SCOPES; scopeIdx++)
|
||||
{
|
||||
if (pServInfo->servScope == snsScopeTbl[scopeIdx].value)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (scopeIdx == SNS_NUM_SCOPES)
|
||||
{
|
||||
/* got an invalid scope value from SNS -- should never happen */
|
||||
|
||||
return S_salLib_SNS_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
/* if the name is too long, print out entirely and push rest to newline */
|
||||
|
||||
if (strlen (pServInfo->servName)>SNS_SHOW_NAME_LEN-1)
|
||||
{
|
||||
printf ("%-s\n", pServInfo->servName);
|
||||
printf ("%-*s%-*s", SNS_SHOW_NAME_LEN, " ----",
|
||||
SNS_SHOW_SCOPE_LEN, snsScopeTbl[scopeIdx].displayScope);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* print name and scope first */
|
||||
|
||||
printf ("%-*s%-*s", SNS_SHOW_NAME_LEN, pServInfo->servName,
|
||||
SNS_SHOW_SCOPE_LEN, snsScopeTbl[scopeIdx].displayScope);
|
||||
}
|
||||
|
||||
|
||||
/* loop through all sockets associated with service */
|
||||
|
||||
msg.cmd = SNS_CMD_GETSOCK;
|
||||
msg.rtpId = pServInfo->servOwner;
|
||||
msg.service = pServInfo->service;
|
||||
msg.numSockets = 0;
|
||||
FOREVER
|
||||
{
|
||||
|
||||
/* if more than one socket info to show, only display socket
|
||||
* info, print spaces for alignment.
|
||||
*/
|
||||
|
||||
if (msg.numSockets !=0)
|
||||
printf ("%-*s", SNS_SHOW_NAME_LEN + SNS_SHOW_SCOPE_LEN, " ");
|
||||
|
||||
/* ask SNS server about specified socket and get reply */
|
||||
|
||||
replySize = salCall (snsClient, &msg, sizeof (msg),
|
||||
&reply, sizeof (reply));
|
||||
|
||||
/* fail if reply is invalid */
|
||||
|
||||
showErrno = salSnsClientReplyCheck (replySize, sizeof (reply));
|
||||
if (showErrno != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* fail if SNS cannot locate current service
|
||||
* (i.e. current service has been deregistered)
|
||||
*/
|
||||
|
||||
if (reply.service == NULL)
|
||||
{
|
||||
showErrno = reply.getSockErrno;
|
||||
break;
|
||||
}
|
||||
|
||||
/* print info about socket */
|
||||
|
||||
switch (reply.servSockInfo.ai_family)
|
||||
{
|
||||
case AF_LOCAL:
|
||||
printf ("%-*s", SNS_SHOW_FAMILY_LEN, "LOCAL");
|
||||
break;
|
||||
case AF_TIPC:
|
||||
printf ("%-*s", SNS_SHOW_FAMILY_LEN, "TIPC");
|
||||
break;
|
||||
default:
|
||||
printf ("%-*s", SNS_SHOW_FAMILY_LEN, "UNKNWN");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (reply.servSockInfo.ai_socktype)
|
||||
{
|
||||
case SOCK_SEQPACKET:
|
||||
printf ("%-*s", SNS_SHOW_TYPE_LEN, "SEQPKT");
|
||||
break;
|
||||
case SOCK_RDM:
|
||||
printf ("%-*s", SNS_SHOW_TYPE_LEN, "RDM");
|
||||
break;
|
||||
case SOCK_DGRAM:
|
||||
printf ("%-*s", SNS_SHOW_TYPE_LEN, "DGRAM");
|
||||
break;
|
||||
case SOCK_STREAM:
|
||||
printf ("%-*s", SNS_SHOW_TYPE_LEN, "STREAM");
|
||||
break;
|
||||
default:
|
||||
printf ("%-*s", SNS_SHOW_TYPE_LEN, "UNKNWN");
|
||||
}
|
||||
|
||||
printf ("%-*d ", SNS_SHOW_PROTO_LEN-1, reply.servSockInfo.ai_protocol);
|
||||
|
||||
switch (reply.servSockInfo.ai_family)
|
||||
{
|
||||
case AF_LOCAL:
|
||||
printf (" %s",
|
||||
((struct sockaddr_un *)&reply.servSockAddr)->sun_path);
|
||||
break;
|
||||
case AF_TIPC:
|
||||
{
|
||||
uint addr; /* nodeId of owner of this name */
|
||||
|
||||
addr = ((struct sockaddr_tipc *)&reply.servSockAddr)->addr.id.node;
|
||||
printf("%c", (addr == ownTipcAddr) ? ' ' : '*');
|
||||
|
||||
printf (" <%d.%d.%d>,%u",
|
||||
tipc_zone(addr),
|
||||
tipc_cluster(addr),
|
||||
tipc_node(addr),
|
||||
((struct sockaddr_tipc *)&reply.servSockAddr)->addr.id.ref);
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
|
||||
/* end loop if no more socket info to get for current service */
|
||||
|
||||
if (reply.done)
|
||||
break;
|
||||
|
||||
/* move on to next socket */
|
||||
|
||||
msg.numSockets++;
|
||||
}
|
||||
|
||||
/* indicate results to caller */
|
||||
|
||||
return showErrno;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Makefile - makefile for un
|
||||
#
|
||||
# modification history
|
||||
# --------------------
|
||||
# 01i,21aug07,ebh Remove extraneous define of _KERNEL (WIND00102055)
|
||||
# 01h,11oct04,p_r removed coreip reference from comment (SPR#102446)
|
||||
# 01g,26aug04,ann added changes to select this directory only for 6.0 and
|
||||
# beyond
|
||||
# 01f,24may04,ann merged from /main/vdt/base6_itn5-int/1.
|
||||
# 01e,30apr04,rp check for sh endianness no longer required
|
||||
# 01d,17feb04,pch remove PPC32 hack, no longer needed
|
||||
# 01c,05dec03,xli add EXTRA_DEFINE
|
||||
# 01b,02dec03,bwa changed the make rules
|
||||
# 01a,09oct03,bwa written
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This file contains the makefile rules for building the un (AF_LOCAL
|
||||
# domain) library
|
||||
#
|
||||
|
||||
TGT_DIR = $(WIND_BASE)/target
|
||||
LIB_BASE_NAME = dsi
|
||||
|
||||
override EXTRA_DEFINE+=-DZ_PREFIX -D_WRS_VXWORKS_5_5
|
||||
|
||||
# Choose what we build for VxWorks 5.x
|
||||
|
||||
IS_BASE6 := $(wildcard $(TGT_DIR)/share/h/syscallApi.def)
|
||||
|
||||
ifneq ($(IS_BASE6),)
|
||||
OBJS = unLib.o unShow.o
|
||||
else
|
||||
OBJS =
|
||||
endif
|
||||
|
||||
DOC_FILES = unShow.c
|
||||
|
||||
include $(TGT_DIR)/h/make/rules.library
|
||||
@@ -0,0 +1,47 @@
|
||||
# Makefile - makefile for un/comp
|
||||
#
|
||||
# Copyright (c) 2003-2007 Wind River Systems, Inc.
|
||||
#
|
||||
# The right to copy, distribute, modify or otherwise make use
|
||||
# of this software may be licensed only pursuant to the terms
|
||||
# of an applicable Wind River license agreement.
|
||||
#
|
||||
#
|
||||
# modification history
|
||||
# --------------------
|
||||
# 01k,21aug07,ebh Remove extraneous define of _KERNEL (WIND00102055)
|
||||
# 01j,24aug06,kch Exclude netstat_uncomp.c from compilation for now.
|
||||
# 01i,11oct04,p_r removed coreip reference from comment (SPR#102446)
|
||||
# 01h,26aug04,ann added changes to select this directory only for 6.0 and
|
||||
# beyond
|
||||
# 01g,02jun04,ann merged from /main/vdt/base6_itn5-int/2.
|
||||
# 01f,24may04,ann merged from /main/vdt/base6_itn5-int/1.
|
||||
# 01e,30apr04,rp check for sh endianness no longer required
|
||||
# 01d,17feb04,pch remove PPC32 hack, no longer needed
|
||||
# 01c,05dec03,xli add EXTRA_DEFINE
|
||||
# 01b,02dec03,bwa changed the make rules
|
||||
# 01a,09oct03,bwa written
|
||||
#
|
||||
# DESCRIPTION
|
||||
# This file contains the makefile rules for building the AF_LOCAL/COMP library
|
||||
#
|
||||
|
||||
TGT_DIR = $(WIND_BASE)/target
|
||||
LIB_BASE_NAME = dsi
|
||||
|
||||
|
||||
override EXTRA_DEFINE+=-DZ_PREFIX -D_WRS_VXWORKS_5_5 -DINCLUDE_WVNETD $(ARCH_FLAGS)
|
||||
|
||||
# Choose what we build for VxWorks 5.x
|
||||
|
||||
IS_BASE6 := $(wildcard $(TGT_DIR)/share/h/syscallApi.def)
|
||||
|
||||
ifneq ($(IS_BASE6),)
|
||||
OBJS = unCompLib.o uncomp_usrreq.o uncompShow.o
|
||||
else
|
||||
OBJS =
|
||||
endif
|
||||
|
||||
DOC_FILES =
|
||||
|
||||
include $(TGT_DIR)/h/make/rules.library
|
||||
@@ -0,0 +1,277 @@
|
||||
/* netstat_uncomp.c - netstat() support for AF_LOCAL/COMP */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004-2005, 2011 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute or otherwise make use of this software
|
||||
* may be licensed only pursuant to the terms of an applicable Wind River
|
||||
* license agreement. No license to Wind River intellectual property rights
|
||||
* is granted herein. All rights not licensed by Wind River are reserved
|
||||
* by Wind River.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01l,28jun11,shi LP64 conversion
|
||||
01h,16feb05,aeg changed PRINTF to printf (SPR #106381).
|
||||
01j,21feb05,ebh update manually (zippy merge was not running)
|
||||
01i,16feb05,aeg changed PRINTF to printf (SPR #106381).
|
||||
01h,21jan05,vvv osdep.h cleanup
|
||||
01g,03jan05,bwa doc fix (SPR #102346).
|
||||
01f,02nov04,bwa BUG FIX: NULL-pointer dereference (SPR #103461).
|
||||
01e,11oct04,p_r fixed pathname for dsi header (SPR #102446)
|
||||
01d,17aug04,dlk Replace splnet()/splx() with dsiLock()/dsiUnlock().
|
||||
01c,27may04,bwa fixed 'netun' includes (SPR #97714).
|
||||
01b,03mar04,bwa changed netinet directory references to netun
|
||||
01a,27jan04,bwa written
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This module is the netstat() routine support for the AF_LOCAL/COMP protocol.
|
||||
|
||||
The netstat_uncompInit() routine links the AF_LOCAL/COMP netstat support into
|
||||
the VxWorks system. This is performed automatically if INCLUDE_NETSTAT_UN_COMP
|
||||
is defined.
|
||||
|
||||
NOMANUAL
|
||||
*/
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include <netconf.h>
|
||||
#include <stdio.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/socketvar.h>
|
||||
#include <net/domain.h>
|
||||
#include <net/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <sys/un.h>
|
||||
#include <dsi/un/uncomp_var.h>
|
||||
#include <dsi/un/uncomp_fsm.h>
|
||||
#include <dsi/backend/dsiUtilLib.h>
|
||||
|
||||
#include <net/utils/netstat.h>
|
||||
|
||||
/* externs */
|
||||
|
||||
extern DL_LIST uncompSocketList;
|
||||
extern char * uncomp_stateGet (uint16_t state, char * pBuffer);
|
||||
|
||||
/* forward declarations */
|
||||
|
||||
LOCAL void netstat_uncompStats (u_long off, char * name, int af_netstat);
|
||||
LOCAL void netstat_uncompCblocks (u_long off, char * name, int af_netstat);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* netstatUncompInit - initialize AF_LOCAL/COMP support for netstat()
|
||||
*
|
||||
* RETURNS: N/A
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
void netstatUncompInit (void)
|
||||
{
|
||||
struct protox *pTp;
|
||||
|
||||
/* find slot in netstat()'s table of printing routines */
|
||||
|
||||
if ((pTp = name2protox ("comp")) == NULL)
|
||||
return;
|
||||
|
||||
/* hook stats and control block printing routines in COMP's entry */
|
||||
|
||||
pTp->pr_stats = NULL;
|
||||
pTp->pr_cblocks = netstat_uncompCblocks;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* netstat_uncompCblocks - routine to print AF_LOCAL/COMP control block
|
||||
*
|
||||
* This routine is called from netstat()'s table of printing routines.
|
||||
*
|
||||
* RETURNS: N/A
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
LOCAL void netstat_uncompCblocks
|
||||
(
|
||||
u_long off,
|
||||
char * name,
|
||||
int af_netstat
|
||||
)
|
||||
{
|
||||
UNCOMPCB * pUnComp;
|
||||
int level = dsiLock ();
|
||||
|
||||
if ((pUnComp = (UNCOMPCB *) DLL_FIRST (&uncompSocketList)) == NULL)
|
||||
{
|
||||
dsiUnlock (level);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ignore invalid flags passed to netstat for AF_LOCAL/COMP */
|
||||
|
||||
if (Rflag || l1flag || bflag || d1flag || gflag || iflag || mflag ||
|
||||
tflag || Wflag || n1flag)
|
||||
{
|
||||
dsiUnlock (level);
|
||||
return;
|
||||
}
|
||||
|
||||
/* only flags valid for 'netstat -f unix': a, A, and L */
|
||||
|
||||
/*
|
||||
* to be of any use, 'L' flag must be paired with 'a' flag, since
|
||||
* 'L' prints listening queues, and 'a' prints server sockets, which
|
||||
* are the only ones to have listening queues
|
||||
*/
|
||||
|
||||
if (Lflag && a1flag)
|
||||
{
|
||||
BOOL isfirst = TRUE; /* will print header ? */
|
||||
|
||||
/* exhaust the AF_LOCAL/COMP socket list */
|
||||
do {
|
||||
/* only print listening sockets */
|
||||
|
||||
if (pUnComp->selfState == UNCOMPS_LISTENING)
|
||||
{
|
||||
/* print header */
|
||||
|
||||
if (isfirst)
|
||||
{
|
||||
printf ("\nAF_LOCAL/COMP sockets (servers only)\n\n");
|
||||
if (Aflag)
|
||||
#ifdef _WRS_CONFIG_LP64
|
||||
printf (" PCBs ");
|
||||
#else
|
||||
printf (" PCBs ");
|
||||
#endif
|
||||
printf (" addr qlen qlimit\n");
|
||||
if (Aflag)
|
||||
#ifdef _WRS_CONFIG_LP64
|
||||
printf ("--------------------");
|
||||
#else
|
||||
printf ("------------");
|
||||
#endif
|
||||
printf ("--------------------\n");
|
||||
|
||||
isfirst = FALSE; /* won't print header again */
|
||||
}
|
||||
|
||||
/*
|
||||
* print stats about sockets; in order:
|
||||
* if 'A' flag is on, CB address;
|
||||
* socket's address (name);
|
||||
* # of unaccepted connections;
|
||||
* max # of unaccepted connections.
|
||||
*/
|
||||
if (Aflag)
|
||||
#ifdef _WRS_CONFIG_LP64
|
||||
printf ("%16p ", (void *)pUnComp);
|
||||
#else
|
||||
printf ("0x%8.8x ", (int)pUnComp);
|
||||
#endif
|
||||
printf ("0x%4.4x ", pUnComp->selfName);
|
||||
printf ("%4d ", pUnComp->pSelfSocket->so_qlen);
|
||||
printf ("%5d", pUnComp->pSelfSocket->so_qlimit);
|
||||
printf ("\n");
|
||||
}
|
||||
} while ((pUnComp = (UNCOMPCB *) DLL_NEXT (pUnComp)) != NULL);
|
||||
}
|
||||
else if (!Lflag) /* anything but listening statistics */
|
||||
{
|
||||
UNCOMPCB * pUnCompPeer;
|
||||
BOOL isfirst = TRUE;
|
||||
char state[20];
|
||||
|
||||
/* exhaust AF_LOCAL/COMP socket list */
|
||||
do {
|
||||
/* if 'a' is not on, step over listening sockets */
|
||||
|
||||
if ((pUnComp->selfState == UNCOMPS_LISTENING) && !a1flag)
|
||||
continue;
|
||||
|
||||
/* print header */
|
||||
|
||||
if (isfirst)
|
||||
{
|
||||
printf ("\n");
|
||||
if (a1flag)
|
||||
printf ("all ");
|
||||
printf ("AF_LOCAL/COMP sockets");
|
||||
if (a1flag)
|
||||
printf (" (including servers)");
|
||||
printf ("\n");
|
||||
if (Aflag)
|
||||
#ifdef _WRS_CONFIG_LP64
|
||||
printf (" ");
|
||||
#else
|
||||
printf (" ");
|
||||
#endif
|
||||
printf (" data\n");
|
||||
if (Aflag)
|
||||
#ifdef _WRS_CONFIG_LP64
|
||||
printf (" PCBs ");
|
||||
#else
|
||||
printf (" PCBs ");
|
||||
#endif
|
||||
|
||||
printf ("address peer addr state queued\n");
|
||||
if (Aflag)
|
||||
#ifdef _WRS_CONFIG_LP64
|
||||
printf ("--------------------");
|
||||
#else
|
||||
printf ("------------");
|
||||
#endif
|
||||
printf ("-------------------------------------\n");
|
||||
|
||||
isfirst = FALSE; /* won't print header again */
|
||||
}
|
||||
|
||||
/*
|
||||
* print socket stats, in order:
|
||||
* if 'A' flag is on, CB address;
|
||||
* socket's address (name);
|
||||
* socket's peer's address (name);
|
||||
* socket's state;
|
||||
* amount of data queued (in bytes).
|
||||
*/
|
||||
|
||||
if (Aflag)
|
||||
#ifdef _WRS_CONFIG_LP64
|
||||
printf ("%16p ", (void *)pUnComp);
|
||||
#else
|
||||
printf ("0x%8.8x ", (int)pUnComp);
|
||||
#endif
|
||||
|
||||
printf (" 0x%4.4x ", pUnComp->selfName);
|
||||
|
||||
if (pUnComp->pPeerSocket != NULL)
|
||||
{
|
||||
pUnCompPeer = SO_TO_UNCOMPCB(pUnComp->pPeerSocket);
|
||||
printf (" 0x%4.4x ", pUnCompPeer->selfName);
|
||||
}
|
||||
else
|
||||
printf (" N/A ");
|
||||
|
||||
uncomp_stateGet (pUnComp->selfState, state);
|
||||
printf ("%-10.10s ", state);
|
||||
|
||||
printf ("%6d", pUnComp->pSelfSocket->so_rcv.sb_cc);
|
||||
|
||||
printf ("\n");
|
||||
|
||||
} while ((pUnComp = (UNCOMPCB *) DLL_NEXT (pUnComp)) != NULL);
|
||||
}
|
||||
|
||||
dsiUnlock (level);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/* unCompLib.c - initialization of the AF_LOCAL/COMP protocol switch entry */
|
||||
|
||||
/* Copyright 2003-2006 Wind River Systems, Inc. */
|
||||
#include "copyright_wrs.h"
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01n,06sep06,kch cleanup coreip stack header files.
|
||||
01m,21feb05,ebh update manually (zippy merge was not running)
|
||||
01l,21jan05,vvv osdep.h cleanup
|
||||
01l,04jan05,bwa removed 'Inst' part of init routine names (SPR #103232).
|
||||
01k,11oct04,p_r fixed pathname for dsi header (SPR #102446)
|
||||
01j,17aug04,dlk Replace splnet()/splx() with dsiLock()/dsiUnlock().
|
||||
01i,27may04,bwa fixed kernel.h/netun include (SPR #97714)
|
||||
01h,24apr04,p_r fixed headers pathnames
|
||||
01g,18mar04,bwa changed 'netinet' directory references to 'netun'
|
||||
01f,19feb04,bwa updated following code review
|
||||
01e,05dec03,xli change the include path
|
||||
01d,03dec03,bwa removed test code
|
||||
01c,26nov03,bwa changed S_unCompLib errnos to S_unLib
|
||||
01b,25nov03,bwa turned off debugging routines
|
||||
01a,03nov03,bwa written
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This is an internal library that initializes the entry in the protocol switch
|
||||
for the COMP protocol in the AF_LOCAL domain.
|
||||
|
||||
The COMP protocol is the Connection-Oriented Message Passing protocol. In
|
||||
essence, it is a protocol that require connection between the end sockets and
|
||||
that treats each packet as a whole message, that are delivered in the order
|
||||
they are sent.
|
||||
|
||||
INTERNAL:
|
||||
WINDVIEW INSTRUMENTATION
|
||||
Level 1:
|
||||
|
||||
Level 2:
|
||||
|
||||
Level 3:
|
||||
N/A
|
||||
|
||||
INCLUDE FILES: unCompLib.h
|
||||
|
||||
NOMANUAL
|
||||
*/
|
||||
|
||||
/* VxWorks system includes */
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <dllLib.h>
|
||||
#include <errnoLib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* networking includes */
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <net/domain.h>
|
||||
#include <net/protosw.h>
|
||||
#include <net/mbuf.h>
|
||||
#include <net/systm.h>
|
||||
|
||||
#include <dsi/backend/dsiUtilLib.h>
|
||||
|
||||
#include <sys/un.h>
|
||||
#include <dsi/un/uncomp.h>
|
||||
#include <dsi/un/uncomp_var.h>
|
||||
|
||||
#include <dsi/un/unLib.h>
|
||||
#include <dsi/un/unCompLib.h>
|
||||
|
||||
#include <sockLib.h>
|
||||
|
||||
/* globals */
|
||||
|
||||
DL_LIST uncompSocketList; /* list of AF_LOCAL/COMP sockets */
|
||||
|
||||
/* externs */
|
||||
|
||||
extern struct domain undomain; /* AF_LOCAL domain */
|
||||
extern struct protosw unsw[UN_PROTO_MAX]; /* AF_LOCAL protocol switch */
|
||||
extern struct pr_usrreqs uncomp_usrreqs; /* COMP protocol switch entry */
|
||||
extern int _unProtoSwIndex; /* 1st available slot in sw */
|
||||
|
||||
/* locals */
|
||||
|
||||
LOCAL BOOL unCompInitialized = FALSE;
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* unCompInit - AF_LOCAL/COMP protocol switch entry initialization
|
||||
*
|
||||
* RETURNS: OK or ERROR
|
||||
*
|
||||
* ERRNO: S_unLib_COMP_ALREADY_INITIALIZED
|
||||
* S_unLib_PROTOCOL_SWITCH_FULL
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
STATUS unCompInit (void * pInitValues)
|
||||
{
|
||||
struct protosw *pProtoSwitch;
|
||||
int level;
|
||||
|
||||
if (unCompInitialized)
|
||||
{
|
||||
errnoSet (S_unLib_COMP_ALREADY_INITIALIZED);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
dsiLockInit ();
|
||||
|
||||
level = dsiLock ();
|
||||
|
||||
if (_unProtoSwIndex >= sizeof(unsw)/sizeof(unsw[0]))
|
||||
{
|
||||
dsiUnlock (level);
|
||||
errnoSet (S_unLib_PROTOCOL_SWITCH_FULL);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
pProtoSwitch = &unsw [_unProtoSwIndex];
|
||||
_unProtoSwIndex++;
|
||||
|
||||
dsiUnlock (level);
|
||||
|
||||
if (pProtoSwitch->pr_domain != NULL)
|
||||
return (OK); /* already initialized */
|
||||
|
||||
pProtoSwitch->pr_type = SOCK_SEQPACKET;
|
||||
pProtoSwitch->pr_domain = &undomain;
|
||||
pProtoSwitch->pr_protocol = 0;
|
||||
pProtoSwitch->pr_flags = PR_CONNREQUIRED | PR_ATOMIC | PR_WANTRCVD;
|
||||
pProtoSwitch->pr_input = NULL;
|
||||
pProtoSwitch->pr_output = NULL;
|
||||
pProtoSwitch->pr_ctlinput = NULL;
|
||||
pProtoSwitch->pr_ctloutput = NULL;
|
||||
pProtoSwitch->pr_ousrreq = NULL;
|
||||
pProtoSwitch->pr_init = NULL;
|
||||
pProtoSwitch->pr_fasttimo = NULL;
|
||||
pProtoSwitch->pr_slowtimo = NULL;
|
||||
pProtoSwitch->pr_drain = NULL;
|
||||
pProtoSwitch->pr_usrreqs = &uncomp_usrreqs;
|
||||
|
||||
dllInit (&uncompSocketList);
|
||||
|
||||
unCompInitialized = TRUE;
|
||||
|
||||
return (OK);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
/* uncompShow.c - information display routines for AF_LOCAL/COMP */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004-2007 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute or otherwise make use of this software
|
||||
* may be licensed only pursuant to the terms of an applicable Wind River
|
||||
* license agreement. No license to Wind River intellectual property rights
|
||||
* is granted herein. All rights not licensed by Wind River are reserved
|
||||
* by Wind River.
|
||||
*/
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01l,22jun07,ebh changes to allow COMP to run in SMP systems.
|
||||
01k,06sep06,kch cleanup coreip stack header files.
|
||||
01j,16feb05,aeg changed PRINTF to printf (SPR #106381).
|
||||
01i,21feb05,ebh update manually (zippy merge was not running)
|
||||
01h,16feb05,aeg changed PRINTF to printf (SPR #106381).
|
||||
01g,21jan05,vvv osdep.h cleanup
|
||||
01f,03jan05,bwa doc fix (SPR #102346).
|
||||
01e,11oct04,p_r fixed pathname for dsi header (SPR #102446)
|
||||
01d,17aug04,dlk Replace splnet()/splx() with dsiLock()/dsiUnlock().
|
||||
01c,27may04,bwa fixed 'netun' includes (SPR #97714); fixed bug uncompShow() not
|
||||
releasing the splnet semaphore when list is empty.
|
||||
01b,03mar04,bwa changed netinet directory references to netun;
|
||||
updated uncompShow() display with more relevant information
|
||||
01a,22jan04,bwa written
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This library provides routines to display information for all sockets
|
||||
and statistics for the AF_LOCAL/COMP protocol.
|
||||
|
||||
The uncompShowInit() routine links the AF_LOCAL/COMP show facility into the
|
||||
VxWorks system. This is performed automatically if INCLUDE_UN_COMP_SHOW is
|
||||
defined.
|
||||
|
||||
NOMANUAL
|
||||
*/
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include <stdio.h>
|
||||
#include <netinet/in.h>
|
||||
#include <dsi/socketvar.h>
|
||||
#include <net/domain.h>
|
||||
#include <net/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <sys/un.h>
|
||||
#include <dsi/un/uncomp_var.h>
|
||||
#include <dsi/un/uncomp_fsm.h>
|
||||
#include <dsi/backend/dsiUtilLib.h>
|
||||
|
||||
/* externs */
|
||||
|
||||
extern DL_LIST uncompSocketList;
|
||||
extern VOIDFUNCPTR _pUncompShow;
|
||||
extern char * uncomp_stateGet (uint16_t state, char * pBuffer);
|
||||
|
||||
/* forward declarations */
|
||||
|
||||
LOCAL void uncompPrint (UNCOMPCB * pUnComp);
|
||||
LOCAL void uncompShow (void);
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* uncompShowInit - initialize AF_LOCAL/COMP show routines
|
||||
*
|
||||
* This routine links the AF_LOCAL show facility into the VxWorks system.
|
||||
* The library is included automatically if INCLUDE_UN_COMP_SHOW is defined.
|
||||
*
|
||||
* RETURNS: N/A
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
void uncompShowInit (void)
|
||||
{
|
||||
_pUncompShow = uncompShow;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* uncompPrint - prints information on one AF_LOCAL/COMP socket
|
||||
*
|
||||
* See unstatShow() in unShow library for sample output and description of
|
||||
* format.
|
||||
*
|
||||
* RETURNS: N/A
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
LOCAL void uncompPrint (UNCOMPCB * pUnComp)
|
||||
{
|
||||
char state[20]; /* socket state */
|
||||
struct socket *pSo = pUnComp->pSelfSocket; /* socket */
|
||||
|
||||
printf ("%3d", pSo->so_fd); /* socket # (relative to RTP) */
|
||||
|
||||
printf (" %4.4X/", pUnComp->selfName); /* socket address (name) */
|
||||
|
||||
/* peer socket's address (name) or N/A if not connected */
|
||||
|
||||
if (pUnComp->pPeerSocket != NULL)
|
||||
printf ("%4.4X",(SO_TO_UNCOMPCB(pUnComp->pPeerSocket))->selfName);
|
||||
else
|
||||
printf ("NONE");
|
||||
|
||||
/* socket's state */
|
||||
|
||||
uncomp_stateGet (pUnComp->selfState, state);
|
||||
printf (" %-10.10s", state);
|
||||
|
||||
/* amount of data received */
|
||||
|
||||
if (pUnComp->selfState == UNCOMPS_LISTENING)
|
||||
printf (" %5s", "N/A");
|
||||
else
|
||||
printf (" %5d", pSo->so_rcv.sb_cc);
|
||||
|
||||
/* high watermark */
|
||||
|
||||
if (pUnComp->selfState == UNCOMPS_LISTENING)
|
||||
printf (" %5s", "N/A");
|
||||
else
|
||||
printf (" %5d", pUnComp->hiwatermark);
|
||||
|
||||
if (pUnComp->selfState == UNCOMPS_LISTENING)
|
||||
printf (" %5s", "N/A");
|
||||
else
|
||||
printf (" %5d", pUnComp->dropped);
|
||||
|
||||
/* unaccepted connections, or N/A if not a listening socket */
|
||||
|
||||
if (pUnComp->selfState == UNCOMPS_LISTENING)
|
||||
printf (" %3d", pSo->so_qlen);
|
||||
else
|
||||
printf (" %7s", "N/A");
|
||||
|
||||
/* max unaccepted connections if a listening socket */
|
||||
|
||||
if (pUnComp->selfState == UNCOMPS_LISTENING)
|
||||
printf ("/%3d", pSo->so_qlimit);
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* uncompShow - display all AF_LOCAL/COMP sockets
|
||||
*
|
||||
* This routine displays a list of all active AF_LOCAL/COMP protocol socket in a
|
||||
* format similar to the UNIX `netstat -f unix' command.
|
||||
*
|
||||
* See unstatShow() in unShow library for sample output and description of
|
||||
* format.
|
||||
*
|
||||
* RETURNS: N/A
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
LOCAL void uncompShow (void)
|
||||
{
|
||||
DL_NODE * pUnComp;
|
||||
int level = dsiLock ();
|
||||
|
||||
if ((pUnComp = DLL_FIRST (&uncompSocketList)) == NULL)
|
||||
{
|
||||
dsiUnlock (level);
|
||||
return;
|
||||
}
|
||||
|
||||
/* print header */
|
||||
|
||||
printf
|
||||
(
|
||||
"\nAF_LOCAL/COMP protocol sockets \n"
|
||||
" pending \n"
|
||||
" address bytes high packets connections\n"
|
||||
"so# (self/peer) State of data watermark dropped (cur/max) \n"
|
||||
"--------------------------------------------------------------------\n"
|
||||
);
|
||||
|
||||
/* exhaust list of AF_LOCAL/COMP sockets */
|
||||
|
||||
do {
|
||||
uncompPrint ((UNCOMPCB *)pUnComp);
|
||||
} while ((pUnComp = (DL_NODE *) DLL_NEXT (pUnComp)) != NULL);
|
||||
|
||||
dsiUnlock (level);
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,114 @@
|
||||
/* unLib.c - installation of the AF_LOCAL domain */
|
||||
|
||||
/* Copyright 2003-2006 Wind River Systems, Inc. */
|
||||
#include "copyright_wrs.h"
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01k,06sep06,kch cleanup coreip stack header files.
|
||||
01j,21feb05,ebh update manually (zippy merge was not running)
|
||||
01i,21jan05,vvv osdep.h cleanup
|
||||
01i,04jan05,bwa removed 'Inst' part of init routine names (SPR #103232).
|
||||
01h,11oct04,p_r fixed pathname for dsi header (SPR #102446)
|
||||
01g,23sep04,bwa now using dsiDomainAdd() instead of addDomain().
|
||||
01f,27may04,bwa fixed 'netun' includes (SPR #97714).
|
||||
01e,18mar04,bwa changed netinet directory references to netun.
|
||||
01d,19feb04,bwa updated following code review
|
||||
01c,04dec03,xli change the include path
|
||||
01b,04dec03,bwa removed debugging info
|
||||
01a,03nov03,bwa written
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This is an internal library that installs the AF_LOCAL domain in the list of
|
||||
domains and initializes it.
|
||||
|
||||
INCLUDE FILES: unLib.h
|
||||
|
||||
NOMANUAL
|
||||
*/
|
||||
|
||||
/* VxWorks system includes */
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <errnoLib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* networking includes */
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <net/domain.h>
|
||||
#include <net/protosw.h>
|
||||
#include <net/mbuf.h>
|
||||
|
||||
#include <sys/un.h>
|
||||
#include <dsi/un/unLib.h>
|
||||
#include <dsi/backend/dsiSockLib.h>
|
||||
|
||||
/* globals */
|
||||
|
||||
struct domain undomain; /* AF_LOCAL domain */
|
||||
struct protosw unsw[UN_PROTO_MAX]; /* AF_LOCAL protocol switch */
|
||||
int _unProtoSwIndex; /* next available entry in switch */
|
||||
|
||||
/* locals */
|
||||
|
||||
LOCAL BOOL unLibInitialized = FALSE; /* prevents multiple inits */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* unInit - AF_LOCAL domain initialization
|
||||
*
|
||||
* RETURNS: OK or ERROR
|
||||
*
|
||||
* ERRNO: S_unLib_ALREADY_INITIALIZED
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
STATUS unInit (void * pInitValues)
|
||||
{
|
||||
/* bail out if already initialized */
|
||||
|
||||
if (unLibInitialized)
|
||||
{
|
||||
errnoSet (S_unLib_ALREADY_INITIALIZED);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
/* record family, name and register AF_LOCAL protocol switch */
|
||||
|
||||
undomain.dom_family = AF_LOCAL;
|
||||
undomain.dom_name = "AF_LOCAL";
|
||||
undomain.dom_init = NULL;
|
||||
undomain.dom_externalize = NULL;
|
||||
undomain.dom_dispose = NULL;
|
||||
undomain.dom_protosw = unsw;
|
||||
undomain.dom_protoswNPROTOSW =
|
||||
&unsw[sizeof(unsw)/sizeof(unsw[0])];
|
||||
undomain.dom_next = NULL;
|
||||
undomain.dom_rtattach = NULL;
|
||||
undomain.dom_rtoffset = 0;
|
||||
undomain.dom_maxrtkey = 0;
|
||||
|
||||
/* ZERO AF_LOCAL protocol switch */
|
||||
|
||||
bzero ((char *)unsw, sizeof (unsw));
|
||||
|
||||
/* add AF_LOCAL domain to list of domains */
|
||||
|
||||
dsiDomainAdd (&undomain);
|
||||
|
||||
/* first AF_LOCAL protocol switch entry will be at index 0 */
|
||||
|
||||
_unProtoSwIndex = 0;
|
||||
|
||||
/* AF_LOCAL domain is now installed */
|
||||
|
||||
unLibInitialized = TRUE;
|
||||
|
||||
return (OK);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/* unShow.c - information display routines for AF_LOCAL */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004-2005 Wind River Systems, Inc.
|
||||
*
|
||||
* The right to copy, distribute, modify or otherwise make use
|
||||
* of this software may be licensed only pursuant to the terms
|
||||
* of an applicable Wind River license agreement.
|
||||
*/
|
||||
|
||||
#include "copyright_wrs.h"
|
||||
|
||||
/*
|
||||
modification history
|
||||
--------------------
|
||||
01e,16feb05,aeg changed PRINTF to printf (SPR #106381).
|
||||
01d,21jan05,vvv osdep.h cleanup
|
||||
01c,10jun04,bwa corrected man page display (SPR98129).
|
||||
01b,03mar04,bwa updated unstatShow() display with more relevant information.
|
||||
01a,22jan04,bwa written.
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
This library provides routines to display information for all sockets
|
||||
and statistics for the AF_LOCAL address family.
|
||||
|
||||
The unShowInit() routine links the AF_LOCAL show facility into the VxWorks
|
||||
system. This is performed automatically if INCLUDE_UN_SHOW is defined.
|
||||
Components need to be added per-protocol as well, eg. INCLUDE_UN_COMP_SHOW
|
||||
for the COMP protocol unstatShow() support.
|
||||
|
||||
INTERNAL
|
||||
Some routines within this module are preempted by parallel versions
|
||||
built in to the Tornado shell source code in the $WIND_BASE/host/src/windsh
|
||||
directory. Changes to these routines must be duplicated within the shell to
|
||||
maintain consistent output. The versions in this module can still be
|
||||
accessed by prepending an "@" sign to the routine name.
|
||||
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#include "vxWorks.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* globals */
|
||||
|
||||
VOIDFUNCPTR _pUncompShow = NULL; /* ptr to AF_LOCAL/COMP show routine */
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* unShowInit - initialize AF_LOCAL show routines
|
||||
*
|
||||
* This routine links the AF_LOCAL show facility into the VxWorks system.
|
||||
* The library is included automatically if INCLUDE_UN_SHOW is defined.
|
||||
*
|
||||
* RETURNS: N/A
|
||||
*
|
||||
* NOMANUAL
|
||||
*/
|
||||
|
||||
void unShowInit (void)
|
||||
{
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* unstatShow - display all AF_LOCAL sockets
|
||||
*
|
||||
* This routine displays a list of all AF_LOCAL family sockets in a format
|
||||
* similar to the UNIX `netstat -f unix' command.
|
||||
*
|
||||
* Sample output:
|
||||
*
|
||||
* \cs
|
||||
* AF_LOCAL/COMP protocol sockets
|
||||
* pending
|
||||
* address bytes high packets connections
|
||||
* so# (self/peer) State of data watermark dropped (cur/max)
|
||||
* --------------------------------------------------------------------
|
||||
* 7 0001/NONE LISTENING 0 N/A N/A 1/ 20
|
||||
* 9 0001/0002 EXCHANGING 30012 65535 10 N/A
|
||||
* 8 0002/0001 EXCHANGING 20014 20014 0 N/A
|
||||
* 10 0003/NONE LISTENING 0 N/A N/A 5/ 5
|
||||
* 12 0003/0004 DONE_RECV 0 65535 132 N/A
|
||||
* 11 0004/0003 DONE_SEND 16 16 0 N/A
|
||||
* 4 0405/NONE LISTENING 0 N/A N/A 0/ 5
|
||||
* 5 0000/NONE CLOSED 0 0 0 N/A
|
||||
* 6 0000/NONE CLOSED 0 0 0 N/A
|
||||
*
|
||||
* \ce
|
||||
* \is
|
||||
* \i so#
|
||||
* Socket identifier, relative to owner's RTP.
|
||||
* \i address
|
||||
* Socket's and peer's addresses (/comp/socket/0xWXYZ).
|
||||
* 'peer' is only valid in the following state: 'EXCHANGING', 'DONE_RECV',
|
||||
* 'DONE_SEND'. 'NONE' is printed otherwise.
|
||||
* \i state
|
||||
* \ms
|
||||
* \m 'CLOSED': starting and ending state: no data can flow
|
||||
* \m 'LISTENING': socket is a listening one, cannot be used to transfer data
|
||||
* \m 'EXCHANGING': data can be sent in either direction
|
||||
* \m 'DONE_SEND': socket can only receive, shutdown(write) has been called on it
|
||||
* \m 'DONE_RECV': socket can only send, shutdown(write) has been done on peer
|
||||
* \me
|
||||
* \i bytes of data
|
||||
* Amount of data that is pending on the socket, waiting to be received.
|
||||
* \i high watermark
|
||||
* Largest amount of pending data at one given time.
|
||||
* \i dropped packets
|
||||
* Number of packets dropped due to lack of space in the receiver's buffer space.
|
||||
* \i pending connections
|
||||
* Current and maximum number of unaccepted connections on a listening socket,
|
||||
* i.e.: (number of connect() calls) - (number of accept() calls). 'N/A' is
|
||||
* printed if not in the LISTENING state.
|
||||
* \ie
|
||||
*
|
||||
* RETURNS: N/A
|
||||
*/
|
||||
|
||||
void unstatShow (void)
|
||||
{
|
||||
printf ("\nSockets for AF_LOCAL address family\n");
|
||||
|
||||
if (_pUncompShow != NULL)
|
||||
_pUncompShow();
|
||||
else
|
||||
printf ("\nNo protocol show routines installed\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user