This is Unofficial EPICS BASE Doxygen Site
server.h File Reference
#include "epicsThread.h"
#include "epicsMutex.h"
#include "epicsEvent.h"
#include "bucketLib.h"
#include "asLib.h"
#include "dbChannel.h"
#include "dbNotify.h"
#include "caProto.h"
#include "ellLib.h"
#include "epicsTime.h"
#include "epicsAssert.h"
#include "osiSock.h"
+ Include dependency graph for server.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  caHdrLargeArray
 
struct  message_buffer
 
struct  client
 
struct  channel_in_use
 
struct  event_ext
 
struct  rsrv_iface_config
 

Macros

#define CA_MINOR_PROTOCOL_REVISION   13
 
#define GLBLTYPE   extern
 
#define GLBLTYPE_INIT(A)
 
#define DLOG(LEVEL, ARGSINPAREN)
 
#define CAS_HASH_TABLE_SIZE   4096
 
#define SEND_LOCK(CLIENT)   epicsMutexMustLock((CLIENT)->lock)
 
#define SEND_UNLOCK(CLIENT)   epicsMutexUnlock((CLIENT)->lock)
 
#define LOCK_CLIENTQ   epicsMutexMustLock (clientQlock);
 
#define UNLOCK_CLIENTQ   epicsMutexUnlock (clientQlock);
 

Typedefs

typedef struct caHdrLargeArray caHdrLargeArray
 
typedef struct client client
 

Enumerations

enum  messageBufferType { mbtUDP, mbtSmallTCP, mbtLargeTCP }
 
enum  rsrvChanState {
  rsrvCS_invalid, rsrvCS_pendConnectResp, rsrvCS_inService, rsrvCS_pendConnectRespUpdatePendAR,
  rsrvCS_inServiceUpdatePendAR, rsrvCS_shutdown
}
 
enum  ctl { ctlInit, ctlRun, ctlPause, ctlExit }
 

Functions

GLBLTYPE ELLLIST clientQ GLBLTYPE_INIT (ELLLIST_INIT)
 
void camsgtask (void *client)
 
void cas_send_bs_msg (struct client *pclient, int lock_needed)
 
void cas_send_dg_msg (struct client *pclient)
 
void rsrv_online_notify_task (void *)
 
void cast_server (void *)
 
struct clientcreate_client (SOCKET sock, int proto)
 
void destroy_client (struct client *)
 
struct clientcreate_tcp_client (SOCKET sock, const osiSockAddr *peerAddr)
 
void destroy_tcp_client (struct client *)
 
void casAttachThreadToClient (struct client *)
 
int camessage (struct client *client)
 
void rsrv_extra_labor (void *pArg)
 
int rsrvCheckPut (const struct channel_in_use *pciu)
 
int rsrv_version_reply (struct client *client)
 
void rsrvFreePutNotify (struct client *pClient, struct rsrv_put_notify *pNotify)
 
void initializePutNotifyFreeList (void)
 
unsigned rsrvSizeOfPutNotify (struct rsrv_put_notify *pNotify)
 
void casExpandRecvBuffer (struct client *pClient, ca_uint32_t size)
 
void casExpandSendBuffer (struct client *pClient, ca_uint32_t size)
 
int cas_copy_in_header (struct client *pClient, ca_uint16_t response, ca_uint32_t payloadSize, ca_uint16_t dataType, ca_uint32_t nElem, ca_uint32_t cid, ca_uint32_t responseSpecific, void **pPayload)
 
void cas_set_header_cid (struct client *pClient, ca_uint32_t)
 
void cas_set_header_count (struct client *pClient, ca_uint32_t count)
 
void cas_commit_msg (struct client *pClient, ca_uint32_t size)
 

Variables

epicsThreadPrivateId rsrvCurrentClient
 
GLBLTYPE int CASDEBUG
 
GLBLTYPE unsigned short ca_server_port
 
GLBLTYPE unsigned short ca_udp_port
 
GLBLTYPE unsigned short ca_beacon_port
 
GLBLTYPE ELLLIST servers
 
GLBLTYPE ELLLIST beaconAddrList
 
GLBLTYPE SOCKET beaconSocket
 
GLBLTYPE ELLLIST casIntfAddrList
 
GLBLTYPE ELLLIST casMCastAddrList
 
GLBLTYPE epicsUInt32casIgnoreAddrs
 
GLBLTYPE epicsMutexId clientQlock
 
GLBLTYPE BUCKETpCaBucket
 
GLBLTYPE void * rsrvClientFreeList
 
GLBLTYPE void * rsrvChanFreeList
 
GLBLTYPE void * rsrvEventFreeList
 
GLBLTYPE void * rsrvSmallBufFreeListTCP
 
GLBLTYPE void * rsrvLargeBufFreeListTCP
 
GLBLTYPE unsigned rsrvSizeofLargeBufTCP
 
GLBLTYPE void * rsrvPutNotifyFreeList
 
GLBLTYPE unsigned rsrvChannelCount
 
GLBLTYPE epicsEventId casudp_startStopEvent
 
GLBLTYPE epicsEventId beacon_startStopEvent
 
GLBLTYPE epicsEventId castcp_startStopEvent
 
GLBLTYPE enum ctl casudp_ctl
 
GLBLTYPE enum ctl beacon_ctl
 
GLBLTYPE enum ctl castcp_ctl
 
GLBLTYPE unsigned int threadPrios [5]
 

Macro Definition Documentation

#define CA_MINOR_PROTOCOL_REVISION   13

Definition at line 30 of file server.h.

#define CAS_HASH_TABLE_SIZE   4096

Definition at line 218 of file server.h.

#define DLOG (   LEVEL,
  ARGSINPAREN 
)

Definition at line 187 of file server.h.

#define GLBLTYPE   extern

Definition at line 176 of file server.h.

#define GLBLTYPE_INIT (   A)

Definition at line 177 of file server.h.

#define LOCK_CLIENTQ   epicsMutexMustLock (clientQlock);

Definition at line 223 of file server.h.

#define SEND_LOCK (   CLIENT)    epicsMutexMustLock((CLIENT)->lock)

Definition at line 220 of file server.h.

#define SEND_UNLOCK (   CLIENT)    epicsMutexUnlock((CLIENT)->lock)

Definition at line 221 of file server.h.

#define UNLOCK_CLIENTQ   epicsMutexUnlock (clientQlock);

Definition at line 224 of file server.h.

Typedef Documentation

typedef struct client client

Enumeration Type Documentation

enum ctl
Enumerator
ctlInit 
ctlRun 
ctlPause 
ctlExit 

Definition at line 169 of file server.h.

Enumerator
mbtUDP 
mbtSmallTCP 
mbtLargeTCP 

Definition at line 63 of file server.h.

Enumerator
rsrvCS_invalid 
rsrvCS_pendConnectResp 
rsrvCS_inService 
rsrvCS_pendConnectRespUpdatePendAR 
rsrvCS_inServiceUpdatePendAR 
rsrvCS_shutdown 

Definition at line 118 of file server.h.

Function Documentation

int camessage ( struct client client)

Definition at line 2391 of file camessage.c.

2392 {
2393  unsigned nmsg = 0;
2394  unsigned msgsize;
2395  unsigned bytes_left;
2396  int status = RSRV_ERROR;
2397 
2398  assert(pCaBucket);
2399 
2400  /* drain remnents of large messages that will not fit */
2401  if ( client->recvBytesToDrain ) {
2402  if ( client->recvBytesToDrain >= client->recv.cnt ) {
2403  client->recvBytesToDrain -= client->recv.cnt;
2404  client->recv.stk = client->recv.cnt;
2405  return RSRV_OK;
2406  }
2407  else {
2408  client->recv.stk += client->recvBytesToDrain;
2409  client->recvBytesToDrain = 0u;
2410  }
2411  }
2412 
2413  DLOG ( 2, ( "CAS: Parsing %d(decimal) bytes\n", recv->cnt ) );
2414 
2415  while ( 1 )
2416  {
2418  caHdr *mp;
2419  void *pBody;
2420 
2421  /* wait for at least a complete caHdr */
2422  bytes_left = client->recv.cnt - client->recv.stk;
2423  if ( bytes_left < sizeof(*mp) ) {
2424  status = RSRV_OK;
2425  break;
2426  }
2427 
2428  mp = (caHdr *) &client->recv.buf[client->recv.stk];
2429  msg.m_cmmd = ntohs ( mp->m_cmmd );
2430  msg.m_postsize = ntohs ( mp->m_postsize );
2431  msg.m_dataType = ntohs ( mp->m_dataType );
2432  msg.m_count = ntohs ( mp->m_count );
2433  msg.m_cid = ntohl ( mp->m_cid );
2434  msg.m_available = ntohl ( mp->m_available );
2435 
2436  if ( CA_V49(client->minor_version_number) && msg.m_postsize == 0xffff ) {
2437  ca_uint32_t *pLW = ( ca_uint32_t * ) ( mp + 1 );
2438  if ( bytes_left < sizeof(*mp) + 2 * sizeof(*pLW) ) {
2439  status = RSRV_OK;
2440  break;
2441  }
2442  msg.m_postsize = ntohl ( pLW[0] );
2443  msg.m_count = ntohl ( pLW[1] );
2444  msgsize = msg.m_postsize + sizeof(*mp) + 2 * sizeof ( *pLW );
2445  pBody = ( void * ) ( pLW + 2 );
2446  }
2447  else {
2448  msgsize = msg.m_postsize + sizeof(*mp);
2449  pBody = ( void * ) ( mp + 1 );
2450  }
2451 
2452  /* ignore deprecated clients, but let newer clients identify themselves. */
2454  if (client->proto==IPPROTO_TCP) {
2455  /* log and error for too old clients, but keep the connection open to avoid a
2456  * re-connect loop.
2457  */
2458  SEND_LOCK(client);
2459  send_err ( &msg, ECA_DEFUNCT, client,
2460  "CAS: Client version %u too old", client->minor_version_number );
2461  SEND_UNLOCK(client);
2462  log_header ( "CAS: Client version too old",
2463  client, &msg, 0, nmsg );
2464  client->recvBytesToDrain = msgsize - bytes_left;
2465  client->recv.stk = client->recv.cnt;
2466  status = RSRV_OK;
2467  } else {
2468  /* silently ignore UDP from old clients */
2469  status = RSRV_ERROR;
2470  }
2471  break;
2472  }
2473 
2474  /*
2475  * disconnect clients that dont send 8 byte
2476  * aligned payloads
2477  */
2478  if ( msgsize & 0x7 ) {
2479  if (client->proto==IPPROTO_TCP) {
2480  SEND_LOCK(client);
2481  send_err ( &msg, ECA_INTERNAL, client,
2482  "CAS: Missaligned protocol rejected" );
2483  SEND_UNLOCK(client);
2484  log_header ( "CAS: Missaligned protocol rejected",
2485  client, &msg, 0, nmsg );
2486  }
2487  status = RSRV_ERROR;
2488  break;
2489  }
2490 
2491  /* problem: we have a complete header,
2492  * but before we check msgsize we don't know
2493  * if we have a complete message body
2494  * -> we may be called again with the same header
2495  * after receiving the full message
2496  */
2497  if ( msgsize > client->recv.maxstk ) {
2498  casExpandRecvBuffer ( client, msgsize );
2499  if ( msgsize > client->recv.maxstk ) {
2500  if (client->proto==IPPROTO_TCP) {
2501  SEND_LOCK(client);
2502  send_err ( &msg, ECA_TOLARGE, client,
2503  "CAS: Server unable to load large request message. Max bytes=%lu",
2505  SEND_UNLOCK(client);
2506  log_header ( "CAS: server unable to load large request message",
2507  client, &msg, 0, nmsg );
2508  }
2509  assert ( client->recv.cnt <= client->recv.maxstk );
2510  assert ( msgsize >= bytes_left );
2511  client->recvBytesToDrain = msgsize - bytes_left;
2512  client->recv.stk = client->recv.cnt;
2513  status = RSRV_OK;
2514  break;
2515  }
2516  }
2517 
2518  /*
2519  * wait for complete message body
2520  */
2521  if ( msgsize > bytes_left ) {
2522  status = RSRV_OK;
2523  break;
2524  }
2525 
2526  nmsg++;
2527 
2528  if ( CASDEBUG > 2 )
2529  log_header (NULL, client, &msg, pBody, nmsg);
2530 
2531  if ( client->proto==IPPROTO_UDP ) {
2532  if ( msg.m_cmmd < NELEMENTS ( udpJumpTable ) ) {
2533  status = ( *udpJumpTable[msg.m_cmmd] )( &msg, pBody, client );
2534  if (status!=RSRV_OK) {
2535  status = RSRV_ERROR;
2536  break;
2537  }
2538  }
2539  else {
2540  status = bad_udp_cmd_action ( &msg, pBody, client );
2541  break;
2542  }
2543  }
2544  else {
2545  if ( msg.m_cmmd < NELEMENTS(tcpJumpTable) ) {
2546  status = ( *tcpJumpTable[msg.m_cmmd] ) ( &msg, pBody, client );
2547  if ( status != RSRV_OK ) {
2548  status = RSRV_ERROR;
2549  break;
2550  }
2551  }
2552  else {
2553  return bad_tcp_cmd_action ( &msg, pBody, client );
2554  }
2555  }
2556 
2557  client->recv.stk += msgsize;
2558  }
2559 
2560  return status;
2561 }
GLBLTYPE int CASDEBUG
Definition: server.h:190
struct message_buffer recv
Definition: server.h:81
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
unsigned cnt
Definition: server.h:70
pvd::Status status
unsigned maxstk
Definition: server.h:68
#define CA_PROTO_VERSION
Definition: caProto.h:83
#define ECA_INTERNAL
Definition: caerr.h:94
ca_uint32_t m_postsize
ca_uint32_t m_available
Definition: caProto.h:166
void casExpandRecvBuffer(struct client *pClient, ca_uint32_t size)
unsigned int ca_uint32_t
Definition: caProto.h:76
#define NULL
Definition: catime.c:38
ca_uint16_t m_dataType
unsigned stk
Definition: server.h:67
int proto
Definition: server.h:97
#define CA_V49(MINOR)
Definition: caProto.h:40
ca_uint16_t m_cmmd
Definition: caProto.h:161
caHdrLargeArray msg
Definition: server.h:150
ca_uint32_t m_count
#define SEND_UNLOCK(CLIENT)
Definition: server.h:221
#define ECA_TOLARGE
Definition: caerr.h:86
unsigned recvBytesToDrain
Definition: server.h:101
ca_uint32_t m_cid
Definition: caProto.h:165
#define RSRV_OK
Definition: rsrv.h:23
char * buf
Definition: server.h:65
ca_uint16_t m_postsize
Definition: caProto.h:162
GLBLTYPE BUCKET * pCaBucket
Definition: server.h:199
ca_uint16_t m_dataType
Definition: caProto.h:163
#define NELEMENTS(A)
Definition: aToIPAddr.c:21
ca_uint16_t m_count
Definition: caProto.h:164
GLBLTYPE unsigned rsrvSizeofLargeBufTCP
Definition: server.h:205
ca_uint32_t m_cid
#define RSRV_ERROR
Definition: rsrv.h:24
#define DLOG(LEVEL, ARGSINPAREN)
Definition: server.h:187
#define CA_VSUPPORTED(MINOR)
Definition: caProto.h:31
ca_uint16_t m_cmmd
ca_uint32_t m_available
unsigned minor_version_number
Definition: server.h:99
#define ECA_DEFUNCT
Definition: caerr.h:111
#define SEND_LOCK(CLIENT)
Definition: server.h:220
void camsgtask ( void *  client)

Definition at line 42 of file camsgtask.c.

43 {
44  struct client *client = (struct client *) pParm;
45 
46  casAttachThreadToClient ( client );
47 
48  while (castcp_ctl == ctlRun && !client->disconnect) {
49  osiSockIoctl_t check_nchars;
50  long nchars;
51  int status;
52 
53  /*
54  * allow message to batch up if more are comming
55  */
56  status = socket_ioctl (client->sock, FIONREAD, &check_nchars);
57  if (status < 0) {
58  char sockErrBuf[64];
59 
61  sockErrBuf, sizeof ( sockErrBuf ) );
62  errlogPrintf("CAS: FIONREAD error: %s\n",
63  sockErrBuf);
64  cas_send_bs_msg(client, TRUE);
65  }
66  else if (check_nchars == 0){
67  cas_send_bs_msg(client, TRUE);
68  }
69 
70  client->recv.stk = 0;
71  assert ( client->recv.maxstk >= client->recv.cnt );
72  nchars = recv ( client->sock, &client->recv.buf[client->recv.cnt],
73  (int) ( client->recv.maxstk - client->recv.cnt ), 0 );
74  if ( nchars == 0 ){
75  if ( CASDEBUG > 0 ) {
76  /* convert to u long so that %lu works on both 32 and 64 bit archs */
77  unsigned long cnt = sizeof ( client->recv.buf ) - client->recv.cnt;
78  errlogPrintf ( "CAS: nill message disconnect ( %lu bytes request )\n",
79  cnt );
80  }
81  break;
82  }
83  else if ( nchars < 0 ) {
84  int anerrno = SOCKERRNO;
85 
86  if ( anerrno == SOCK_EINTR ) {
87  continue;
88  }
89 
90  if ( anerrno == SOCK_ENOBUFS ) {
91  errlogPrintf (
92  "CAS: Out of network buffers, retring receive in 15 seconds\n" );
93  epicsThreadSleep ( 15.0 );
94  continue;
95  }
96 
97  /*
98  * normal conn lost conditions
99  */
100  if ( ( anerrno != SOCK_ECONNABORTED &&
101  anerrno != SOCK_ECONNRESET &&
102  anerrno != SOCK_ETIMEDOUT ) ||
103  CASDEBUG > 2 ) {
104  char sockErrBuf[64];
105 
107  sockErrBuf, sizeof ( sockErrBuf ), anerrno);
108  errlogPrintf ( "CAS: Client disconnected - %s\n",
109  sockErrBuf );
110  }
111  break;
112  }
113 
115  client->recv.cnt += ( unsigned ) nchars;
116 
117  status = camessage ( client );
118  if (status == 0) {
119  /*
120  * if there is a partial message
121  * align it with the start of the buffer
122  */
123  if (client->recv.cnt > client->recv.stk) {
124  unsigned bytes_left;
125 
126  bytes_left = client->recv.cnt - client->recv.stk;
127 
128  /*
129  * overlapping regions handled
130  * properly by memmove
131  */
132  memmove (client->recv.buf,
133  &client->recv.buf[client->recv.stk], bytes_left);
134  client->recv.cnt = bytes_left;
135  }
136  else {
137  client->recv.cnt = 0ul;
138  }
139  }
140  else {
141  char buf[64];
142 
143  /* flush any queued messages before shutdown */
144  cas_send_bs_msg(client, 1);
145 
146  client->recv.cnt = 0ul;
147 
148  /*
149  * disconnect when there are severe message errors
150  */
151  ipAddrToDottedIP (&client->addr, buf, sizeof(buf));
152  epicsPrintf ("CAS: forcing disconnect from %s\n", buf);
153  break;
154  }
155  }
156 
157  LOCK_CLIENTQ;
158  ellDelete ( &clientQ, &client->node );
160 
161  destroy_tcp_client ( client );
162 }
GLBLTYPE int CASDEBUG
Definition: server.h:190
void casAttachThreadToClient(struct client *pClient)
#define SOCK_ECONNABORTED
Definition: osdSock.h:59
struct message_buffer recv
Definition: server.h:81
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
unsigned cnt
Definition: server.h:70
void destroy_tcp_client(struct client *client)
pvd::Status status
unsigned maxstk
Definition: server.h:68
#define SOCK_ENOBUFS
Definition: osdSock.h:52
#define SOCK_ETIMEDOUT
Definition: osdSock.h:54
#define LOCK_CLIENTQ
Definition: server.h:223
SOCKET sock
Definition: server.h:96
unsigned stk
Definition: server.h:67
struct sockaddr_in addr
Definition: server.h:89
void epicsSocketConvertErrnoToString(char *pBuf, unsigned bufSize)
#define socket_ioctl(A, B, C)
Definition: osdSock.h:34
#define SOCK_ECONNRESET
Definition: osdSock.h:53
char disconnect
Definition: server.h:103
int osiSockIoctl_t
Definition: osdSock.h:35
Definition: server.h:169
Definition: server.h:76
epicsTimeStamp time_at_last_recv
Definition: server.h:91
int epicsStdCall epicsTimeGetCurrent(epicsTimeStamp *pDest)
Get current time into *pDest.
#define epicsPrintf
Definition: errlog.h:51
char * buf
Definition: server.h:65
int camessage(struct client *client)
Definition: camessage.c:2391
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
GLBLTYPE enum ctl castcp_ctl
Definition: server.h:214
#define SOCKERRNO
Definition: osdSock.h:33
#define SOCK_EINTR
Definition: osdSock.h:64
#define TRUE
Definition: dbDefs.h:27
LIBCOM_API void epicsStdCall epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
Definition: osdThread.c:790
ELLNODE node
Definition: server.h:77
#define UNLOCK_CLIENTQ
Definition: server.h:224
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
Definition: ellLib.c:75
void cas_send_bs_msg(struct client *pclient, int lock_needed)
Definition: caserverio.c:44
void epicsSocketConvertErrorToString(char *pBuf, unsigned bufSize, int theSockError)
unsigned epicsStdCall ipAddrToDottedIP(const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize)
Definition: osiSock.c:144
void cas_commit_msg ( struct client pClient,
ca_uint32_t  size 
)

Definition at line 351 of file caserverio.c.

352 {
353  caHdr * pMsg = ( caHdr * ) &pClient->send.buf[pClient->send.stk];
354  size = CA_MESSAGE_ALIGN ( size );
355  if ( pMsg->m_postsize == htons ( 0xffff ) ) {
356  ca_uint32_t * pLW = ( ca_uint32_t * ) ( pMsg + 1 );
357  assert ( size <= ntohl ( *pLW ) );
358  pLW[0] = htonl ( size );
359  size += sizeof ( caHdr ) + 2 * sizeof ( *pLW );
360  }
361  else {
362  assert ( size <= ntohs ( pMsg->m_postsize ) );
363  pMsg->m_postsize = htons ( (ca_uint16_t) size );
364  size += sizeof ( caHdr );
365  }
366  pClient->send.stk += size;
367 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
unsigned int ca_uint32_t
Definition: caProto.h:76
unsigned short ca_uint16_t
Definition: caProto.h:75
unsigned stk
Definition: server.h:67
#define CA_MESSAGE_ALIGN(A)
Definition: caProto.h:154
struct message_buffer send
Definition: server.h:79
char * buf
Definition: server.h:65
ca_uint16_t m_postsize
Definition: caProto.h:162
struct ca_hdr caHdr
int cas_copy_in_header ( struct client pClient,
ca_uint16_t  response,
ca_uint32_t  payloadSize,
ca_uint16_t  dataType,
ca_uint32_t  nElem,
ca_uint32_t  cid,
ca_uint32_t  responseSpecific,
void **  pPayload 
)

Definition at line 251 of file caserverio.c.

255 {
256  unsigned msgSize;
257  ca_uint32_t alignedPayloadSize;
258  caHdr *pMsg;
259 
260  if ( payloadSize > UINT_MAX - sizeof ( caHdr ) - 8u ) {
261  return ECA_TOLARGE;
262  }
263 
264  alignedPayloadSize = CA_MESSAGE_ALIGN ( payloadSize );
265 
266  msgSize = alignedPayloadSize + sizeof ( caHdr );
267  if ( alignedPayloadSize >= 0xffff || nElem >= 0xffff ) {
268  if ( ! CA_V49 ( pclient->minor_version_number ) ) {
269  return ECA_16KARRAYCLIENT;
270  }
271  msgSize += 2 * sizeof ( ca_uint32_t );
272  }
273 
274  if ( msgSize > pclient->send.maxstk ) {
275  casExpandSendBuffer ( pclient, msgSize );
276  if ( msgSize > pclient->send.maxstk ) {
277  return ECA_TOLARGE;
278  }
279  }
280 
281  if ( pclient->send.stk > pclient->send.maxstk - msgSize ) {
282  if ( pclient->disconnect ) {
283  pclient->send.stk = 0;
284  }
285  else{
286  if ( pclient->proto == IPPROTO_TCP) {
287  cas_send_bs_msg ( pclient, FALSE );
288  }
289  else if ( pclient->proto == IPPROTO_UDP ) {
290  cas_send_dg_msg ( pclient );
291  }
292  else {
293  return ECA_INTERNAL;
294  }
295  }
296  }
297 
298  pMsg = (caHdr *) &pclient->send.buf[pclient->send.stk];
299  pMsg->m_cmmd = htons(response);
300  pMsg->m_dataType = htons(dataType);
301  pMsg->m_cid = htonl(cid);
302  pMsg->m_available = htonl(responseSpecific);
303  if (alignedPayloadSize < 0xffff && nElem < 0xffff) {
304  pMsg->m_postsize = htons(((ca_uint16_t) alignedPayloadSize));
305  pMsg->m_count = htons(((ca_uint16_t) nElem));
306  if (ppPayload)
307  *ppPayload = (void *) (pMsg + 1);
308  }
309  else {
310  ca_uint32_t *pW32 = (ca_uint32_t *) (pMsg + 1);
311  pMsg->m_postsize = htons(0xffff);
312  pMsg->m_count = htons(0u);
313  pW32[0] = htonl(alignedPayloadSize);
314  pW32[1] = htonl(nElem);
315  if (ppPayload)
316  *ppPayload = (void *) (pW32 + 2);
317  }
318 
319  /* zero out pad bytes */
320  if ( alignedPayloadSize > payloadSize ) {
321  char *p = ( char * ) *ppPayload;
322  memset ( p + payloadSize, '\0',
323  alignedPayloadSize - payloadSize );
324  }
325 
326  return ECA_NORMAL;
327 }
#define FALSE
Definition: dbDefs.h:32
#define ECA_INTERNAL
Definition: caerr.h:94
ca_uint32_t m_available
Definition: caProto.h:166
unsigned int ca_uint32_t
Definition: caProto.h:76
unsigned short ca_uint16_t
Definition: caProto.h:75
#define CA_V49(MINOR)
Definition: caProto.h:40
ca_uint16_t m_cmmd
Definition: caProto.h:161
#define ECA_NORMAL
Definition: caerr.h:77
#define CA_MESSAGE_ALIGN(A)
Definition: caProto.h:154
#define ECA_TOLARGE
Definition: caerr.h:86
ca_uint32_t m_cid
Definition: caProto.h:165
ca_uint16_t m_postsize
Definition: caProto.h:162
void casExpandSendBuffer(struct client *pClient, ca_uint32_t size)
ca_uint16_t m_dataType
Definition: caProto.h:163
struct ca_hdr caHdr
ca_uint16_t m_count
Definition: caProto.h:164
void cas_send_dg_msg(struct client *pclient)
Definition: caserverio.c:173
void cas_send_bs_msg(struct client *pclient, int lock_needed)
Definition: caserverio.c:44
#define ECA_16KARRAYCLIENT
Definition: caerr.h:135
void cas_send_bs_msg ( struct client pclient,
int  lock_needed 
)

Definition at line 44 of file caserverio.c.

45 {
46  int status;
47 
48  if ( lock_needed ) {
49  SEND_LOCK ( pclient );
50  }
51 
52  if ( CASDEBUG > 2 && pclient->send.stk ) {
53  errlogPrintf ( "CAS: Sending a message of %d bytes\n", pclient->send.stk );
54  }
55 
56  if ( pclient->disconnect ) {
57  if ( CASDEBUG > 2 ) {
58  errlogPrintf ( "CAS: msg Discard for sock %d addr %x\n",
59  (int)pclient->sock, (unsigned) pclient->addr.sin_addr.s_addr );
60  }
61  pclient->send.stk = 0u;
62  if(lock_needed)
63  SEND_UNLOCK(pclient);
64  return;
65  }
66 
67  while ( pclient->send.stk && ! pclient->disconnect ) {
68  status = send ( pclient->sock, pclient->send.buf, pclient->send.stk, 0 );
69  if ( status >= 0 ) {
70  unsigned transferSize = (unsigned) status;
71  if ( transferSize >= pclient->send.stk ) {
72  pclient->send.stk = 0;
74  break;
75  }
76  else {
77  unsigned bytesLeft = pclient->send.stk - transferSize;
78  memmove ( pclient->send.buf, &pclient->send.buf[transferSize],
79  bytesLeft );
80  pclient->send.stk = bytesLeft;
81  }
82  }
83  else {
84  int causeWasSocketHangup = 0;
85  int anerrno = SOCKERRNO;
86  char buf[64];
87 
88  if ( pclient->disconnect ) {
89  pclient->send.stk = 0u;
90  break;
91  }
92 
93  if ( anerrno == SOCK_EINTR ) {
94  continue;
95  }
96 
97  if ( anerrno == SOCK_ENOBUFS ) {
98  errlogPrintf (
99  "CAS: Out of network buffers, retrying send in 15 seconds\n" );
100  epicsThreadSleep ( 15.0 );
101  continue;
102  }
103 
104  ipAddrToDottedIP ( &pclient->addr, buf, sizeof(buf) );
105 
106  if (
107  anerrno == SOCK_ECONNABORTED ||
108  anerrno == SOCK_ECONNRESET ||
109  anerrno == SOCK_EPIPE ||
110  anerrno == SOCK_ETIMEDOUT ) {
111  causeWasSocketHangup = 1;
112  }
113  else {
114  char sockErrBuf[64];
116  sockErrBuf, sizeof ( sockErrBuf ) );
117  errlogPrintf ( "CAS: TCP send to %s failed: %s\n",
118  buf, sockErrBuf);
119  }
120  pclient->disconnect = TRUE;
121  pclient->send.stk = 0u;
122 
123  /*
124  * wakeup the receive thread
125  */
126  if ( ! causeWasSocketHangup ) {
129  switch ( info ) {
131  if ( pclient->sock != INVALID_SOCKET ) {
132  epicsSocketDestroy ( pclient->sock );
133  pclient->sock = INVALID_SOCKET;
134  }
135  break;
137  {
138  int status = shutdown ( pclient->sock, SHUT_RDWR );
139  if ( status ) {
140  char sockErrBuf[64];
142  sockErrBuf, sizeof ( sockErrBuf ) );
143  errlogPrintf ("CAS: Socket shutdown error: %s\n",
144  sockErrBuf );
145  }
146  }
147  break;
149  epicsSignalRaiseSigAlarm ( pclient->tid );
150  break;
151  default:
152  break;
153  };
154  break;
155  }
156  }
157  }
158 
159  if ( lock_needed ) {
160  SEND_UNLOCK(pclient);
161  }
162 
163  DLOG ( 3, ( "------------------------------\n\n" ) );
164 
165  return;
166 }
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
Definition: osdSock.c:117
GLBLTYPE int CASDEBUG
Definition: server.h:190
#define SOCK_ECONNABORTED
Definition: osdSock.h:59
#define INVALID_SOCKET
Definition: osdSock.h:32
pvd::Status status
#define SOCK_ENOBUFS
Definition: osdSock.h:52
LIBCOM_API void epicsStdCall epicsSignalRaiseSigAlarm(struct epicsThreadOSD *)
Definition: osdSignal.cpp:19
#define SOCK_ETIMEDOUT
Definition: osdSock.h:54
enum epicsSocketSystemCallInterruptMechanismQueryInfo epicsSocketSystemCallInterruptMechanismQuery()
SOCKET sock
Definition: server.h:96
unsigned stk
Definition: server.h:67
epicsSocketSystemCallInterruptMechanismQueryInfo
Definition: osiSock.h:47
struct sockaddr_in addr
Definition: server.h:89
void epicsSocketConvertErrnoToString(char *pBuf, unsigned bufSize)
#define SOCK_ECONNRESET
Definition: osdSock.h:53
#define SEND_UNLOCK(CLIENT)
Definition: server.h:221
char disconnect
Definition: server.h:103
epicsThreadId tid
Definition: server.h:98
struct message_buffer send
Definition: server.h:79
int epicsStdCall epicsTimeGetCurrent(epicsTimeStamp *pDest)
Get current time into *pDest.
char * buf
Definition: server.h:65
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
#define SOCKERRNO
Definition: osdSock.h:33
#define SOCK_EPIPE
Definition: osdSock.h:65
#define DLOG(LEVEL, ARGSINPAREN)
Definition: server.h:187
#define SOCK_EINTR
Definition: osdSock.h:64
#define TRUE
Definition: dbDefs.h:27
LIBCOM_API void epicsStdCall epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
Definition: osdThread.c:790
epicsTimeStamp time_at_last_send
Definition: server.h:90
#define SHUT_RDWR
Definition: osdSock.h:48
#define SEND_LOCK(CLIENT)
Definition: server.h:220
unsigned epicsStdCall ipAddrToDottedIP(const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize)
Definition: osiSock.c:144
void cas_send_dg_msg ( struct client pclient)

Definition at line 173 of file caserverio.c.

174 {
175  int status;
176  int sizeDG;
177  char * pDG;
178  caHdr * pMsg;
179 
180  if ( CASDEBUG > 2 && pclient->send.stk ) {
181  errlogPrintf ( "CAS: Sending a udp message of %d bytes\n", pclient->send.stk );
182  }
183 
184  SEND_LOCK ( pclient );
185 
186  if ( pclient->send.stk <= sizeof (caHdr) ) {
187  SEND_UNLOCK(pclient);
188  return;
189  }
190 
191  pDG = pclient->send.buf;
192  pMsg = ( caHdr * ) pDG;
193  sizeDG = pclient->send.stk;
194  assert ( ntohs ( pMsg->m_cmmd ) == CA_PROTO_VERSION );
195  if ( CA_V411 ( pclient->minor_version_number ) ) {
196  pMsg->m_cid = htonl ( pclient->seqNoOfReq );
197  pMsg->m_dataType = htons ( sequenceNoIsValid );
198  }
199  else {
200  pDG += sizeof (caHdr);
201  sizeDG -= sizeof (caHdr);
202  }
203 
204  status = sendto ( pclient->sock, pDG, sizeDG, 0,
205  (struct sockaddr *)&pclient->addr, sizeof(pclient->addr) );
206  if ( status >= 0 ) {
207  if ( status >= sizeDG ) {
209  }
210  else {
211  errlogPrintf (
212  "CAS: System failed to send entire udp frame?\n" );
213  }
214  }
215  else {
216  char sockErrBuf[64];
217  char buf[128];
219  sockErrBuf, sizeof ( sockErrBuf ) );
220  ipAddrToDottedIP ( &pclient->addr, buf, sizeof(buf) );
221  errlogPrintf( "CAS: UDP send to %s failed: %s\n",
222  buf, sockErrBuf);
223  }
224 
225  pclient->send.stk = 0u;
226 
227  /*
228  * add placeholder for the first version message should it be needed
229  */
230  rsrv_version_reply ( pclient );
231 
232  SEND_UNLOCK(pclient);
233 
234  DLOG ( 3, ( "------------------------------\n\n" ) );
235 
236  return;
237 }
GLBLTYPE int CASDEBUG
Definition: server.h:190
int rsrv_version_reply(struct client *client)
Definition: camessage.c:2141
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
pvd::Status status
#define CA_PROTO_VERSION
Definition: caProto.h:83
#define CA_V411(MINOR)
Definition: caProto.h:42
SOCKET sock
Definition: server.h:96
unsigned stk
Definition: server.h:67
struct sockaddr_in addr
Definition: server.h:89
void epicsSocketConvertErrnoToString(char *pBuf, unsigned bufSize)
ca_uint16_t m_cmmd
Definition: caProto.h:161
#define SEND_UNLOCK(CLIENT)
Definition: server.h:221
struct message_buffer send
Definition: server.h:79
ca_uint32_t m_cid
Definition: caProto.h:165
int epicsStdCall epicsTimeGetCurrent(epicsTimeStamp *pDest)
Get current time into *pDest.
char * buf
Definition: server.h:65
#define sequenceNoIsValid
Definition: caProto.h:124
ca_uint16_t m_dataType
Definition: caProto.h:163
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
struct ca_hdr caHdr
#define DLOG(LEVEL, ARGSINPAREN)
Definition: server.h:187
unsigned minor_version_number
Definition: server.h:99
epicsTimeStamp time_at_last_send
Definition: server.h:90
ca_uint32_t seqNoOfReq
Definition: server.h:100
#define SEND_LOCK(CLIENT)
Definition: server.h:220
unsigned epicsStdCall ipAddrToDottedIP(const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize)
Definition: osiSock.c:144
void cas_set_header_cid ( struct client pClient,
ca_uint32_t   
)

Definition at line 329 of file caserverio.c.

330 {
331  caHdr *pMsg = ( caHdr * ) &pClient->send.buf[pClient->send.stk];
332  pMsg->m_cid = htonl ( cid );
333 }
unsigned stk
Definition: server.h:67
struct message_buffer send
Definition: server.h:79
ca_uint32_t m_cid
Definition: caProto.h:165
char * buf
Definition: server.h:65
void cas_set_header_count ( struct client pClient,
ca_uint32_t  count 
)

Definition at line 335 of file caserverio.c.

336 {
337  caHdr *pMsg = (caHdr *) &pClient->send.buf[pClient->send.stk];
338  if (pMsg->m_postsize == htons(0xffff)) {
339  ca_uint32_t *pLW;
340 
341  assert(pMsg->m_count == 0);
342  pLW = (ca_uint32_t *) (pMsg + 1);
343  pLW[1] = htonl(count);
344  }
345  else {
346  assert(count < 65536);
347  pMsg->m_count = htons((ca_uint16_t) count);
348  }
349 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
unsigned int ca_uint32_t
Definition: caProto.h:76
unsigned short ca_uint16_t
Definition: caProto.h:75
unsigned stk
Definition: server.h:67
struct message_buffer send
Definition: server.h:79
char * buf
Definition: server.h:65
ca_uint16_t m_postsize
Definition: caProto.h:162
ca_uint16_t m_count
Definition: caProto.h:164
if(yy_init)
Definition: scan.c:972
void casAttachThreadToClient ( struct client )

Definition at line 1307 of file caservertask.c.

1308 {
1311  pClient->tid = epicsThreadGetIdSelf ();
1313  taskwdInsert ( pClient->tid, NULL, NULL );
1314 }
void taskwdInsert(epicsThreadId tid, TASKWDFUNC callback, void *usr)
Definition: taskwd.c:176
LIBCOM_API void epicsStdCall epicsSignalInstallSigPipeIgnore(void)
Definition: osdSignal.cpp:17
epicsThreadPrivateId rsrvCurrentClient
Definition: caservertask.c:50
#define NULL
Definition: catime.c:38
LIBCOM_API void epicsStdCall epicsThreadPrivateSet(epicsThreadPrivateId, void *)
Definition: osdThread.c:961
LIBCOM_API void epicsStdCall epicsSignalInstallSigAlarmIgnore(void)
Definition: osdSignal.cpp:18
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
void casExpandRecvBuffer ( struct client pClient,
ca_uint32_t  size 
)

Definition at line 1394 of file caservertask.c.

1395 {
1396  casExpandBuffer (&pClient->recv, size, 0);
1397 }
struct message_buffer recv
Definition: server.h:81
void casExpandSendBuffer ( struct client pClient,
ca_uint32_t  size 
)

Definition at line 1389 of file caservertask.c.

1390 {
1391  casExpandBuffer (&pClient->send, size, 1);
1392 }
struct message_buffer send
Definition: server.h:79
void cast_server ( void *  )

Definition at line 116 of file cast_server.c.

117 {
118  rsrv_iface_config *conf = pParm;
119  int status;
120  int count=0;
121  int mysocket=0;
122  struct sockaddr_in new_recv_addr;
123  osiSocklen_t recv_addr_size;
124  osiSockIoctl_t nchars;
125  SOCKET recv_sock, reply_sock;
126  struct client *client;
127 
128  recv_addr_size = sizeof(new_recv_addr);
129 
130  reply_sock = conf->udp;
131 
132  /*
133  * setup new client structure but reuse old structure if
134  * possible
135  *
136  */
137  while ( TRUE ) {
138  client = create_client ( reply_sock, IPPROTO_UDP );
139  if ( client ) {
140  break;
141  }
142  epicsThreadSleep(300.0);
143  }
144  if (conf->startbcast) {
145  recv_sock = conf->udpbcast;
146  conf->bclient = client;
147  }
148  else {
149  recv_sock = conf->udp;
150  conf->client = client;
151  }
152  client->udpRecv = recv_sock;
153 
154  casAttachThreadToClient ( client );
155 
156  /*
157  * add placeholder for the first version message should it be needed
158  */
159  rsrv_version_reply ( client );
160 
161  /* these pointers become invalid after signaling casudp_startStopEvent */
162  conf = NULL;
163 
165 
166  while (TRUE) {
167  status = recvfrom (
168  recv_sock,
169  client->recv.buf,
170  client->recv.maxstk,
171  0,
172  (struct sockaddr *)&new_recv_addr,
173  &recv_addr_size);
174  if (status < 0) {
175  if (SOCKERRNO != SOCK_EINTR) {
176  char sockErrBuf[64];
178  sockErrBuf, sizeof ( sockErrBuf ) );
179  epicsPrintf ("CAS: UDP recv error: %s\n",
180  sockErrBuf);
181  epicsThreadSleep(1.0);
182  }
183 
184  } else {
185  size_t idx;
186  for(idx=0; casIgnoreAddrs[idx]; idx++)
187  {
188  if(new_recv_addr.sin_addr.s_addr==casIgnoreAddrs[idx]) {
189  status = -1; /* ignore */
190  break;
191  }
192  }
193  }
194 
195  if (status >= 0 && casudp_ctl == ctlRun) {
196  client->recv.cnt = (unsigned) status;
197  client->recv.stk = 0ul;
199 
201  client->seqNoOfReq = 0;
202 
203  /*
204  * If we are talking to a new client flush to the old one
205  * in case we are holding UDP messages waiting to
206  * see if the next message is for this same client.
207  */
208  if (client->send.stk>sizeof(caHdr)) {
209  status = memcmp(&client->addr,
210  &new_recv_addr, recv_addr_size);
211  if(status){
212  /*
213  * if the address is different
214  */
215  cas_send_dg_msg(client);
216  client->addr = new_recv_addr;
217  }
218  }
219  else {
220  client->addr = new_recv_addr;
221  }
222 
223  if (CASDEBUG>1) {
224  char buf[40];
225 
226  ipAddrToDottedIP (&client->addr, buf, sizeof(buf));
227  errlogPrintf ("CAS: cast server msg of %d bytes from addr %s\n",
228  client->recv.cnt, buf);
229  }
230 
231  if (CASDEBUG>2)
232  count = ellCount (&client->chanList);
233 
234  status = camessage ( client );
235  if(status == RSRV_OK){
236  if(client->recv.cnt !=
237  client->recv.stk){
238  char buf[40];
239 
240  ipAddrToDottedIP (&client->addr, buf, sizeof(buf));
241 
242  epicsPrintf ("CAS: partial (damaged?) UDP msg of %d bytes from %s ?\n",
243  client->recv.cnt - client->recv.stk, buf);
244 
245  epicsTimeToStrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S",
246  &client->time_at_last_recv);
247  epicsPrintf ("CAS: message received at %s\n", buf);
248  }
249  }
250  else if (CASDEBUG>0){
251  char buf[40];
252 
253  ipAddrToDottedIP (&client->addr, buf, sizeof(buf));
254 
255  epicsPrintf ("CAS: invalid (damaged?) UDP request from %s ?\n", buf);
256 
257  epicsTimeToStrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S",
258  &client->time_at_last_recv);
259  epicsPrintf ("CAS: message received at %s\n", buf);
260  }
261 
262  if (CASDEBUG>2) {
263  if ( ellCount (&client->chanList) ) {
264  errlogPrintf ("CAS: Fnd %d name matches (%d tot)\n",
265  ellCount(&client->chanList)-count,
266  ellCount(&client->chanList));
267  }
268  }
269  }
270 
271  /*
272  * allow messages to batch up if more are comming
273  */
274  nchars = 0; /* supress purify warning */
275  status = socket_ioctl(recv_sock, FIONREAD, &nchars);
276  if (status<0) {
277  errlogPrintf ("CA cast server: Unable to fetch N characters pending\n");
278  cas_send_dg_msg (client);
279  clean_addrq (client);
280  }
281  else if (nchars == 0) {
282  cas_send_dg_msg (client);
283  clean_addrq (client);
284  }
285  }
286 
287  /* ATM never reached, just a placeholder */
288 
289  if(!mysocket)
290  client->sock = INVALID_SOCKET; /* only one cast_server should destroy the reply socket */
291  destroy_client(client);
292  epicsSocketDestroy(recv_sock);
293 }
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
Definition: osdSock.c:117
GLBLTYPE int CASDEBUG
Definition: server.h:190
void casAttachThreadToClient(struct client *pClient)
SOCKET udpbcast
Definition: server.h:163
struct message_buffer recv
Definition: server.h:81
#define INVALID_SOCKET
Definition: osdSock.h:32
int rsrv_version_reply(struct client *client)
Definition: camessage.c:2141
#define ellCount(PLIST)
Report the number of nodes in a list.
Definition: ellLib.h:84
unsigned cnt
Definition: server.h:70
struct client client
pvd::Status status
unsigned maxstk
Definition: server.h:68
int osiSocklen_t
Definition: osdSock.h:36
unsigned int startbcast
Definition: server.h:166
#define CA_UKN_MINOR_VERSION
Definition: caProto.h:29
#define NULL
Definition: catime.c:38
struct client * client
Definition: server.h:164
SOCKET sock
Definition: server.h:96
unsigned stk
Definition: server.h:67
struct sockaddr_in addr
Definition: server.h:89
void epicsSocketConvertErrnoToString(char *pBuf, unsigned bufSize)
void destroy_client(struct client *client)
#define socket_ioctl(A, B, C)
Definition: osdSock.h:34
LIBCOM_API size_t epicsStdCall epicsTimeToStrftime(char *pBuff, size_t bufLength, const char *pFormat, const epicsTimeStamp *pTS)
Convert epicsTimeStamp to string. See epicsTime::strftime()
Definition: epicsTime.cpp:1120
#define epicsEventSignal(ID)
A synonym for epicsEventTrigger().
Definition: epicsEvent.h:172
int osiSockIoctl_t
Definition: osdSock.h:35
Definition: server.h:169
Definition: server.h:76
struct message_buffer send
Definition: server.h:79
epicsTimeStamp time_at_last_recv
Definition: server.h:91
int epicsStdCall epicsTimeGetCurrent(epicsTimeStamp *pDest)
Get current time into *pDest.
#define RSRV_OK
Definition: rsrv.h:23
#define epicsPrintf
Definition: errlog.h:51
char * buf
Definition: server.h:65
int camessage(struct client *client)
Definition: camessage.c:2391
int SOCKET
Definition: osdSock.h:31
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
struct client * create_client(SOCKET sock, int proto)
GLBLTYPE epicsEventId casudp_startStopEvent
Definition: server.h:209
#define SOCKERRNO
Definition: osdSock.h:33
GLBLTYPE epicsUInt32 * casIgnoreAddrs
Definition: server.h:197
#define SOCK_EINTR
Definition: osdSock.h:64
#define TRUE
Definition: dbDefs.h:27
LIBCOM_API void epicsStdCall epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
Definition: osdThread.c:790
void cas_send_dg_msg(struct client *pclient)
Definition: caserverio.c:173
unsigned minor_version_number
Definition: server.h:99
ELLLIST chanList
Definition: server.h:86
ca_uint32_t seqNoOfReq
Definition: server.h:100
SOCKET udpRecv
Definition: server.h:96
GLBLTYPE enum ctl casudp_ctl
Definition: server.h:212
unsigned epicsStdCall ipAddrToDottedIP(const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize)
Definition: osiSock.c:144
struct client * bclient
Definition: server.h:164
struct client* create_client ( SOCKET  sock,
int  proto 
)

Definition at line 1225 of file caservertask.c.

1226 {
1227  struct client *client;
1228  int spaceAvailOnFreeList;
1229  size_t spaceNeeded;
1230 
1231  /*
1232  * stop further use of server if memory becomes scarse
1233  */
1234  spaceAvailOnFreeList = freeListItemsAvail ( rsrvClientFreeList ) > 0
1236  spaceNeeded = sizeof (struct client) + MAX_TCP;
1237  if ( ! ( osiSufficentSpaceInPool(spaceNeeded) || spaceAvailOnFreeList ) ) {
1239  epicsPrintf ("CAS: no space in pool for a new client (below max block thresh)\n");
1240  return NULL;
1241  }
1242 
1243  client = freeListCalloc ( rsrvClientFreeList );
1244  if ( ! client ) {
1246  epicsPrintf ("CAS: no space in pool for a new client (alloc failed)\n");
1247  return NULL;
1248  }
1249 
1250  client->sock = sock;
1251  client->proto = proto;
1252 
1254  client->lock = epicsMutexCreate();
1255  client->putNotifyLock = epicsMutexCreate();
1256  client->chanListLock = epicsMutexCreate();
1257  client->eventqLock = epicsMutexCreate();
1258  if ( ! client->blockSem || ! client->lock || ! client->putNotifyLock ||
1259  ! client->chanListLock || ! client->eventqLock ) {
1260  destroy_client ( client );
1261  return NULL;
1262  }
1263 
1264  client->pUserName = NULL;
1265  client->pHostName = NULL;
1266  ellInit ( & client->chanList );
1267  ellInit ( & client->chanPendingUpdateARList );
1268  ellInit ( & client->putNotifyQue );
1269  memset ( (char *)&client->addr, 0, sizeof (client->addr) );
1270  client->tid = 0;
1271 
1272  if ( proto == IPPROTO_TCP ) {
1273  client->send.buf = (char *) freeListCalloc ( rsrvSmallBufFreeListTCP );
1274  client->send.maxstk = MAX_TCP;
1275  client->send.type = mbtSmallTCP;
1276  client->recv.buf = (char *) freeListCalloc ( rsrvSmallBufFreeListTCP );
1277  client->recv.maxstk = MAX_TCP;
1278  client->recv.type = mbtSmallTCP;
1279  }
1280  else if ( proto == IPPROTO_UDP ) {
1281  client->send.buf = malloc ( MAX_UDP_SEND );
1282  client->send.maxstk = MAX_UDP_SEND;
1283  client->send.type = mbtUDP;
1284  client->recv.buf = malloc ( MAX_UDP_RECV );
1285  client->recv.maxstk = MAX_UDP_RECV;
1286  client->recv.type = mbtUDP;
1287  }
1288  if ( ! client->send.buf || ! client->recv.buf ) {
1289  destroy_client ( client );
1290  return NULL;
1291  }
1292  client->send.stk = 0u;
1293  client->send.cnt = 0u;
1294  client->recv.stk = 0u;
1295  client->recv.cnt = 0u;
1296  client->evuser = NULL;
1297  client->priority = CA_PROTO_PRIORITY_MIN;
1298  client->disconnect = FALSE;
1302  client->recvBytesToDrain = 0u;
1303 
1304  return client;
1305 }
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
Definition: osdSock.c:117
LIBCOM_API void *epicsStdCall freeListCalloc(void *pvt)
Definition: freeListLib.c:60
#define MAX_TCP
Definition: caProto.h:63
struct message_buffer recv
Definition: server.h:81
#define FALSE
Definition: dbDefs.h:32
unsigned cnt
Definition: server.h:70
struct client client
unsigned maxstk
Definition: server.h:68
char * pUserName
Definition: server.h:93
Definition: server.h:63
GLBLTYPE void * rsrvSmallBufFreeListTCP
Definition: server.h:203
#define CA_UKN_MINOR_VERSION
Definition: caProto.h:29
epicsEventId blockSem
Definition: server.h:95
#define NULL
Definition: catime.c:38
LIBCOM_API int epicsStdCall osiSufficentSpaceInPool(size_t contiguousBlockSize)
Checks if a memory block of a specific size can be safely allocated.
Definition: osdPoolStatus.c:19
SOCKET sock
Definition: server.h:96
unsigned stk
Definition: server.h:67
int proto
Definition: server.h:97
ELLLIST putNotifyQue
Definition: server.h:88
struct sockaddr_in addr
Definition: server.h:89
void destroy_client(struct client *client)
char * pHostName
Definition: server.h:94
GLBLTYPE void * rsrvClientFreeList
Definition: server.h:200
epicsMutexId chanListLock
Definition: server.h:84
char disconnect
Definition: server.h:103
epicsThreadId tid
Definition: server.h:98
Definition: server.h:76
struct message_buffer send
Definition: server.h:79
epicsTimeStamp time_at_last_recv
Definition: server.h:91
unsigned recvBytesToDrain
Definition: server.h:101
int epicsStdCall epicsTimeGetCurrent(epicsTimeStamp *pDest)
Get current time into *pDest.
#define CA_PROTO_PRIORITY_MIN
Definition: caProto.h:66
#define epicsPrintf
Definition: errlog.h:51
LIBCOM_API size_t epicsStdCall freeListItemsAvail(void *pvt)
Definition: freeListLib.c:171
epicsMutexId lock
Definition: server.h:82
char * buf
Definition: server.h:65
epicsMutexId eventqLock
Definition: server.h:85
#define MAX_UDP_RECV
Definition: caProto.h:61
ELLLIST chanPendingUpdateARList
Definition: server.h:87
#define ellInit(PLIST)
Initialize a list type.
Definition: ellLib.h:76
#define epicsMutexCreate()
Create an epicsMutex semaphore for use from C code.
Definition: epicsMutex.h:168
void * evuser
Definition: server.h:92
unsigned minor_version_number
Definition: server.h:99
ELLLIST chanList
Definition: server.h:86
epicsMutexId putNotifyLock
Definition: server.h:83
epicsTimeStamp time_at_last_send
Definition: server.h:90
unsigned priority
Definition: server.h:102
LIBCOM_API epicsEventId epicsEventCreate(epicsEventInitialState initialState)
Create an epicsEvent for use from C code, or return NULL.
Definition: osdEvent.c:47
enum messageBufferType type
Definition: server.h:71
#define MAX_UDP_SEND
Definition: caProto.h:62
struct client* create_tcp_client ( SOCKET  sock,
const osiSockAddr peerAddr 
)

Definition at line 1402 of file caservertask.c.

1403 {
1404  int status;
1405  struct client *client;
1406  int intTrue = TRUE;
1407  unsigned priorityOfEvents;
1408 
1409  /* socket passed in is destroyed here if unsuccessful */
1410  client = create_client ( sock, IPPROTO_TCP );
1411  if ( ! client ) {
1412  return NULL;
1413  }
1414 
1415  client->addr = peerAddr->ia;
1416  if(asCheckClientIP) {
1417  epicsUInt32 ip = ntohl(client->addr.sin_addr.s_addr);
1418  client->pHostName = malloc(24);
1419  if(!client->pHostName) {
1420  destroy_client ( client );
1421  return NULL;
1422  }
1423  epicsSnprintf(client->pHostName, 24,
1424  "%u.%u.%u.%u",
1425  (ip>>24)&0xff,
1426  (ip>>16)&0xff,
1427  (ip>>8)&0xff,
1428  (ip>>0)&0xff);
1429  }
1430 
1431  /*
1432  * see TCP(4P) this seems to make unsolicited single events much
1433  * faster. I take care of queue up as load increases.
1434  */
1435  status = setsockopt ( sock, IPPROTO_TCP, TCP_NODELAY,
1436  (char *) &intTrue, sizeof (intTrue) );
1437  if (status < 0) {
1438  errlogPrintf ( "CAS: TCP_NODELAY option set failed\n" );
1439  destroy_client ( client );
1440  return NULL;
1441  }
1442 
1443  /*
1444  * turn on KEEPALIVE so if the client crashes
1445  * this task will find out and exit
1446  */
1447  status = setsockopt ( sock, SOL_SOCKET, SO_KEEPALIVE,
1448  (char *) &intTrue, sizeof (intTrue) );
1449  if ( status < 0 ) {
1450  errlogPrintf ( "CAS: SO_KEEPALIVE option set failed\n" );
1451  destroy_client ( client );
1452  return NULL;
1453  }
1454 
1455  /*
1456  * some concern that vxWorks will run out of mBuf's
1457  * if this change is made
1458  *
1459  * joh 11-10-98
1460  */
1461 #if 0
1462  /*
1463  * set TCP buffer sizes to be synergistic
1464  * with CA internal buffering
1465  */
1466  i = MAX_MSG_SIZE;
1467  status = setsockopt ( sock, SOL_SOCKET, SO_SNDBUF, (char *) &i, sizeof (i) );
1468  if (status < 0) {
1469  errlogPrintf ( "CAS: SO_SNDBUF set failed\n" );
1470  destroy_client ( client );
1471  return NULL;
1472  }
1473  i = MAX_MSG_SIZE;
1474  status = setsockopt ( sock, SOL_SOCKET, SO_RCVBUF, (char *) &i, sizeof (i) );
1475  if (status < 0) {
1476  errlogPrintf ( "CAS: SO_RCVBUF set failed\n" );
1477  destroy_client ( client );
1478  return NULL;
1479  }
1480 #endif
1481 
1482  client->evuser = (struct event_user *) db_init_events ();
1483  if ( ! client->evuser ) {
1484  errlogPrintf ("CAS: unable to init the event facility\n");
1485  destroy_tcp_client (client);
1486  return NULL;
1487  }
1488 
1489  status = db_add_extra_labor_event ( client->evuser, rsrv_extra_labor, client );
1490  if (status != DB_EVENT_OK) {
1491  errlogPrintf("CAS: unable to setup the event facility\n");
1492  destroy_tcp_client (client);
1493  return NULL;
1494  }
1495 
1496  {
1498 
1500  if ( tbs != epicsThreadBooleanStatusSuccess ) {
1501  priorityOfEvents = epicsThreadPriorityCAServerLow;
1502  }
1503  }
1504 
1505  status = db_start_events ( client->evuser, "CAS-event",
1506  NULL, NULL, priorityOfEvents );
1507  if ( status != DB_EVENT_OK ) {
1508  errlogPrintf ( "CAS: unable to start the event facility\n" );
1509  destroy_tcp_client ( client );
1510  return NULL;
1511  }
1512 
1513  /*
1514  * add first version message should it be needed
1515  */
1516  rsrv_version_reply ( client );
1517 
1518  if ( CASDEBUG > 0 ) {
1519  char buf[64];
1520  ipAddrToDottedIP ( &client->addr, buf, sizeof(buf) );
1521  errlogPrintf ( "CAS: conn req from %s\n", buf );
1522  }
1523 
1524  return client;
1525 }
GLBLTYPE int CASDEBUG
Definition: server.h:190
int rsrv_version_reply(struct client *client)
Definition: camessage.c:2141
epicsThreadBooleanStatus
Definition: epicsThread.h:93
LIBCOM_API int asCheckClientIP
Definition: asLibRoutines.c:31
struct client client
void destroy_tcp_client(struct client *client)
pvd::Status status
int i
Definition: scan.c:967
struct sockaddr_in ia
Definition: osiSock.h:157
#define NULL
Definition: catime.c:38
unsigned int epicsUInt32
Definition: epicsTypes.h:43
SOCKET sock
Definition: server.h:96
struct sockaddr_in addr
Definition: server.h:89
void destroy_client(struct client *client)
char * pHostName
Definition: server.h:94
Definition: server.h:76
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
struct client * create_client(SOCKET sock, int proto)
LIBCOM_API epicsThreadBooleanStatus epicsStdCall epicsThreadHighestPriorityLevelBelow(unsigned int priority, unsigned *pPriorityJustBelow)
Definition: osdThread.c:740
#define epicsThreadPriorityCAServerLow
Definition: epicsThread.h:80
#define TRUE
Definition: dbDefs.h:27
#define MAX_MSG_SIZE
Definition: caProto.h:64
void * evuser
Definition: server.h:92
void rsrv_extra_labor(void *pArg)
Definition: camessage.c:1497
LIBCOM_API int epicsStdCall epicsSnprintf(char *str, size_t size, const char *format,...) EPICS_PRINTF_STYLE(3
unsigned epicsStdCall ipAddrToDottedIP(const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize)
Definition: osiSock.c:144
void destroy_client ( struct client )

Definition at line 1047 of file caservertask.c.

1048 {
1049  if ( ! client ) {
1050  return;
1051  }
1052 
1053  if ( client->tid != 0 ) {
1054  taskwdRemove ( client->tid );
1055  }
1056 
1057  if ( client->sock != INVALID_SOCKET ) {
1059  }
1060 
1061  if ( client->proto == IPPROTO_TCP ) {
1062  if ( client->send.buf ) {
1063  if ( client->send.type == mbtSmallTCP ) {
1065  }
1066  else if ( client->send.type == mbtLargeTCP ) {
1069  else
1070  free(client->send.buf);
1071  }
1072  else {
1073  errlogPrintf ( "CAS: Corrupt send buffer free list type code=%u during client cleanup?\n",
1074  client->send.type );
1075  }
1076  }
1077  if ( client->recv.buf ) {
1078  if ( client->recv.type == mbtSmallTCP ) {
1080  }
1081  else if ( client->recv.type == mbtLargeTCP ) {
1084  else
1085  free(client->recv.buf);
1086  }
1087  else {
1088  errlogPrintf ( "CAS: Corrupt recv buffer free list type code=%u during client cleanup?\n",
1089  client->send.type );
1090  }
1091  }
1092  }
1093  else if ( client->proto == IPPROTO_UDP ) {
1094  if ( client->send.buf ) {
1095  free ( client->send.buf );
1096  }
1097  if ( client->recv.buf ) {
1098  free ( client->recv.buf );
1099  }
1100  }
1101 
1102  if ( client->eventqLock ) {
1104  }
1105 
1106  if ( client->chanListLock ) {
1108  }
1109 
1110  if ( client->putNotifyLock ) {
1112  }
1113 
1114  if ( client->lock ) {
1116  }
1117 
1118  if ( client->blockSem ) {
1120  }
1121 
1122  if ( client->pUserName ) {
1123  free ( client->pUserName );
1124  }
1125 
1126  if ( client->pHostName ) {
1127  free ( client->pHostName );
1128  }
1129 
1131 }
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
Definition: osdSock.c:117
struct message_buffer recv
Definition: server.h:81
#define INVALID_SOCKET
Definition: osdSock.h:32
void epicsStdCall epicsMutexDestroy(epicsMutexId pmutexNode)
Destroy an epicsMutex semaphore.
Definition: epicsMutex.cpp:127
char * pUserName
Definition: server.h:93
GLBLTYPE void * rsrvSmallBufFreeListTCP
Definition: server.h:203
epicsEventId blockSem
Definition: server.h:95
SOCKET sock
Definition: server.h:96
int proto
Definition: server.h:97
char * pHostName
Definition: server.h:94
GLBLTYPE void * rsrvClientFreeList
Definition: server.h:200
epicsMutexId chanListLock
Definition: server.h:84
epicsThreadId tid
Definition: server.h:98
Definition: server.h:76
struct message_buffer send
Definition: server.h:79
LIBCOM_API void epicsStdCall freeListFree(void *pvt, void *pmem)
Definition: freeListLib.c:131
GLBLTYPE void * rsrvLargeBufFreeListTCP
Definition: server.h:204
epicsMutexId lock
Definition: server.h:82
char * buf
Definition: server.h:65
LIBCOM_API void epicsEventDestroy(epicsEventId id)
Destroy an epicsEvent and any resources it holds.
Definition: osdEvent.c:70
epicsMutexId eventqLock
Definition: server.h:85
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
void taskwdRemove(epicsThreadId tid)
Definition: taskwd.c:206
epicsMutexId putNotifyLock
Definition: server.h:83
enum messageBufferType type
Definition: server.h:71
void destroy_tcp_client ( struct client )

Definition at line 1191 of file caservertask.c.

1192 {
1193  int status;
1194 
1195  if ( CASDEBUG > 0 ) {
1196  errlogPrintf ( "CAS: Connection %d Terminated\n", (int)client->sock );
1197  }
1198 
1199  if ( client->evuser ) {
1200  /*
1201  * turn off extra labor callbacks from the event thread
1202  */
1203  status = db_add_extra_labor_event ( client->evuser, NULL, NULL );
1204  assert ( ! status );
1205 
1206  /*
1207  * wait for extra labor in progress to comple
1208  */
1209  db_flush_extra_labor_event ( client->evuser );
1210  }
1211 
1212  destroyAllChannels ( client, & client->chanList );
1213  destroyAllChannels ( client, & client->chanPendingUpdateARList );
1214 
1215  if ( client->evuser ) {
1216  db_close_events (client->evuser);
1217  }
1218 
1219  destroy_client ( client );
1220 }
GLBLTYPE int CASDEBUG
Definition: server.h:190
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
pvd::Status status
#define NULL
Definition: catime.c:38
SOCKET sock
Definition: server.h:96
void destroy_client(struct client *client)
Definition: server.h:76
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
ELLLIST chanPendingUpdateARList
Definition: server.h:87
void * evuser
Definition: server.h:92
ELLLIST chanList
Definition: server.h:86
GLBLTYPE ELLLIST clientQ GLBLTYPE_INIT ( ELLLIST_INIT  )
void initializePutNotifyFreeList ( void  )

Definition at line 1530 of file camessage.c.

1531 {
1532  if ( ! rsrvPutNotifyFreeList ) {
1534  sizeof(struct rsrv_put_notify), 512 );
1536  }
1537 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
LIBCOM_API void epicsStdCall freeListInitPvt(void **ppvt, int size, int nmalloc)
Definition: freeListLib.c:44
GLBLTYPE void * rsrvPutNotifyFreeList
Definition: server.h:206
void rsrv_extra_labor ( void *  pArg)

Definition at line 1497 of file camessage.c.

1498 {
1499  struct client * pClient = pArg;
1500  write_notify_reply ( pClient );
1501  sendAllUpdateAS ( pClient );
1502  cas_send_bs_msg ( pClient, TRUE );
1503 }
Definition: server.h:76
#define TRUE
Definition: dbDefs.h:27
void cas_send_bs_msg(struct client *pclient, int lock_needed)
Definition: caserverio.c:44
void rsrv_online_notify_task ( void *  )

Definition at line 40 of file online_notify.c.

41 {
42  double delay;
43  double maxdelay;
44  long longStatus;
45  double maxPeriod;
46  caHdr msg;
47  int status;
48  ca_uint32_t beaconCounter = 0;
49  int *lastError;
50 
52 
54  longStatus = envGetDoubleConfigParam ( & EPICS_CAS_BEACON_PERIOD, & maxPeriod );
55  }
56  else {
57  longStatus = envGetDoubleConfigParam ( & EPICS_CA_BEACON_PERIOD, & maxPeriod );
58  }
59  if (longStatus || maxPeriod<=0.0) {
60  maxPeriod = 15.0;
61  epicsPrintf ("EPICS \"%s\" float fetch failed\n",
63  epicsPrintf ("Setting \"%s\" = %f\n",
64  EPICS_CAS_BEACON_PERIOD.name, maxPeriod);
65  }
66 
67  delay = 0.02; /* initial beacon period in sec */
68  maxdelay = maxPeriod;
69 
70  memset((char *)&msg, 0, sizeof msg);
71  msg.m_cmmd = htons (CA_PROTO_RSRV_IS_UP);
72  msg.m_count = htons (ca_server_port);
74 
75  /* beaconAddrList should not change after rsrv_init(), which then starts this thread */
76  lastError = callocMustSucceed(ellCount(&beaconAddrList), sizeof(*lastError), "rsrv_online_notify_task lastError");
77 
79 
80  while (TRUE) {
81  ELLNODE *cur;
82  unsigned i;
83 
84  /* send beacon to each interface */
85  for(i=0, cur=ellFirst(&beaconAddrList); cur; i++, cur=ellNext(cur))
86  {
88  status = sendto (beaconSocket, (char *)&msg, sizeof(msg), 0,
89  &pAddr->addr.sa, sizeof(pAddr->addr));
90  if (status < 0) {
91  int err = SOCKERRNO;
92  if(err != lastError[i]) {
93  char sockErrBuf[64];
94  char sockDipBuf[22];
95 
96  epicsSocketConvertErrorToString(sockErrBuf, sizeof(sockErrBuf), err);
97  ipAddrToDottedIP(&pAddr->addr.ia, sockDipBuf, sizeof(sockDipBuf));
98  errlogPrintf ( "CAS: CA beacon send to %s error: %s\n",
99  sockDipBuf, sockErrBuf);
100 
101  lastError[i] = err;
102  }
103  }
104  else {
105  assert (status == sizeof(msg));
106  if(lastError[i]) {
107  char sockDipBuf[22];
108 
109  ipAddrToDottedIP(&pAddr->addr.ia, sockDipBuf, sizeof(sockDipBuf));
110  errlogPrintf ( "CAS: CA beacon send to %s ok\n",
111  sockDipBuf);
112  }
113  lastError[i] = 0;
114  }
115  }
116 
117  epicsThreadSleep(delay);
118  if (delay<maxdelay) {
119  delay *= 2.0;
120  if (delay>maxdelay) {
121  delay = maxdelay;
122  }
123  }
124 
125  msg.m_cid = htonl ( beaconCounter++ ); /* expected to overflow */
126 
127  while (beacon_ctl == ctlPause) {
128  epicsThreadSleep(0.1);
129  delay = 0.02; /* Restart beacon timing if paused */
130  }
131  }
132 
133  free(lastError);
134 }
void taskwdInsert(epicsThreadId tid, TASKWDFUNC callback, void *usr)
Definition: taskwd.c:176
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
#define ellCount(PLIST)
Report the number of nodes in a list.
Definition: ellLib.h:84
osiSockAddr addr
Definition: osiSock.h:163
pvd::Status status
LIBCOM_API const ENV_PARAM EPICS_CA_BEACON_PERIOD
deprecated
char * name
Name of the parameter.
Definition: envDefs.h:42
#define CONTAINER(ptr, structure, member)
Find parent object from a member pointer.
Definition: dbDefs.h:66
int i
Definition: scan.c:967
LIBCOM_API const char *epicsStdCall envGetConfigParamPtr(const ENV_PARAM *pParam)
Get a configuration parameter&#39;s value or default string.
Definition: envSubr.c:81
struct sockaddr sa
Definition: osiSock.h:158
GLBLTYPE SOCKET beaconSocket
Definition: server.h:195
struct sockaddr_in ia
Definition: osiSock.h:157
unsigned int ca_uint32_t
Definition: caProto.h:76
#define NULL
Definition: catime.c:38
#define CA_MINOR_PROTOCOL_REVISION
Definition: nciu.h:35
GLBLTYPE ELLLIST beaconAddrList
Definition: server.h:194
ca_uint16_t m_cmmd
Definition: caProto.h:161
#define ellNext(PNODE)
Find the next node in list.
Definition: ellLib.h:99
LIBCOM_API long epicsStdCall envGetDoubleConfigParam(const ENV_PARAM *pParam, double *pDouble)
Get value of a double configuration parameter.
Definition: envSubr.c:191
#define epicsEventSignal(ID)
A synonym for epicsEventTrigger().
Definition: epicsEvent.h:172
ca_uint32_t m_cid
Definition: caProto.h:165
#define epicsPrintf
Definition: errlog.h:51
LIBCOM_API const ENV_PARAM EPICS_CAS_BEACON_PERIOD
ca_uint16_t m_dataType
Definition: caProto.h:163
LIBCOM_API void * callocMustSucceed(size_t count, size_t size, const char *msg)
A calloc() that never returns NULL.
Definition: cantProceed.c:22
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
List node type.
Definition: ellLib.h:45
ca_uint16_t m_count
Definition: caProto.h:164
#define SOCKERRNO
Definition: osdSock.h:33
GLBLTYPE enum ctl beacon_ctl
Definition: server.h:213
#define TRUE
Definition: dbDefs.h:27
LIBCOM_API void epicsStdCall epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
Definition: osdThread.c:790
GLBLTYPE unsigned short ca_server_port
Definition: server.h:191
GLBLTYPE epicsEventId beacon_startStopEvent
Definition: server.h:210
ELLNODE node
Definition: server.h:77
#define CA_PROTO_RSRV_IS_UP
Definition: caProto.h:96
void epicsSocketConvertErrorToString(char *pBuf, unsigned bufSize, int theSockError)
unsigned epicsStdCall ipAddrToDottedIP(const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize)
Definition: osiSock.c:144
#define ellFirst(PLIST)
Find the first node in list.
Definition: ellLib.h:89
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
int rsrv_version_reply ( struct client client)

Definition at line 2141 of file camessage.c.

2142 {
2143  int status;
2144  SEND_LOCK ( client );
2145  /*
2146  * sequence number is specified zero when we copy in the
2147  * header because we dont know it until we receive a datagram
2148  * from the client
2149  */
2150  status = cas_copy_in_header ( client, CA_PROTO_VERSION,
2152  0, 0, 0 );
2153  if ( status != ECA_NORMAL ) {
2154  SEND_UNLOCK ( client );
2155  return RSRV_ERROR;
2156  }
2157  cas_commit_msg ( client, 0 );
2158  SEND_UNLOCK ( client );
2159  return RSRV_OK;
2160 }
pvd::Status status
#define CA_PROTO_VERSION
Definition: caProto.h:83
#define CA_MINOR_PROTOCOL_REVISION
Definition: nciu.h:35
#define SEND_UNLOCK(CLIENT)
Definition: server.h:221
#define ECA_NORMAL
Definition: caerr.h:77
#define RSRV_OK
Definition: rsrv.h:23
int cas_copy_in_header(struct client *pclient, ca_uint16_t response, ca_uint32_t payloadSize, ca_uint16_t dataType, ca_uint32_t nElem, ca_uint32_t cid, ca_uint32_t responseSpecific, void **ppPayload)
Definition: caserverio.c:251
#define RSRV_ERROR
Definition: rsrv.h:24
void cas_commit_msg(struct client *pClient, ca_uint32_t size)
Definition: caserverio.c:351
#define SEND_LOCK(CLIENT)
Definition: server.h:220
int rsrvCheckPut ( const struct channel_in_use pciu)

Definition at line 2566 of file camessage.c.

2567 {
2568  /*
2569  * SPC_NOMOD fields are always unwritable
2570  */
2571  if (dbChannelSpecial(pciu->dbch) == SPC_NOMOD) {
2572  return 0;
2573  }
2574  else {
2575  return asCheckPut (pciu->asClientPVT);
2576  }
2577 }
struct dbChannel * dbch
Definition: server.h:139
#define asCheckPut(asClientPvt)
Definition: asLib.h:45
#define SPC_NOMOD
Definition: special.h:26
ASCLIENTPVT asClientPVT
Definition: server.h:140
void rsrvFreePutNotify ( struct client pClient,
struct rsrv_put_notify pNotify 
)

Definition at line 1616 of file camessage.c.

1618 {
1619  if ( pNotify ) {
1620  char busyTmp;
1621  void * asWritePvtTmp = 0;
1622 
1623  epicsMutexMustLock ( pClient->putNotifyLock );
1624  busyTmp = pNotify->busy;
1625  epicsMutexUnlock ( pClient->putNotifyLock );
1626 
1627  /*
1628  * if any possiblity that the put notify is
1629  * outstanding then cancel it
1630  */
1631  if ( busyTmp ) {
1632  dbNotifyCancel ( &pNotify->dbPutNotify );
1633  }
1634 
1635  epicsMutexMustLock ( pClient->putNotifyLock );
1636  if ( pNotify->onExtraLaborQueue ) {
1637  ellDelete ( &pClient->putNotifyQue,
1638  &pNotify->node );
1639  }
1640  busyTmp = pNotify->busy;
1641  asWritePvtTmp = pNotify->asWritePvt;
1642  pNotify->asWritePvt = 0;
1643  epicsMutexUnlock ( pClient->putNotifyLock );
1644 
1645  if ( busyTmp ) {
1646  asTrapWriteAfter ( asWritePvtTmp );
1647  }
1648 
1649  if ( pNotify->valueSize >
1650  sizeof(pNotify->dbrScalarValue) ) {
1651  free ( pNotify->pbuffer );
1652  }
1653  freeListFree ( rsrvPutNotifyFreeList, pNotify );
1654  }
1655 }
processNotify dbPutNotify
Definition: camessage.c:66
void * pbuffer
Definition: camessage.c:87
#define asTrapWriteAfter(pvt)
Definition: asLib.h:58
void epicsStdCall epicsMutexUnlock(epicsMutexId pmutexNode)
Release the semaphore.
Definition: epicsMutex.cpp:140
ELLLIST putNotifyQue
Definition: server.h:88
char onExtraLaborQueue
Definition: camessage.c:94
LIBCOM_API void epicsStdCall freeListFree(void *pvt, void *pmem)
Definition: freeListLib.c:131
union rsrv_put_notify::@1 dbrScalarValue
ELLNODE node
Definition: camessage.c:65
void * asWritePvt
Definition: camessage.c:91
unsigned valueSize
Definition: camessage.c:92
epicsMutexId putNotifyLock
Definition: server.h:83
#define epicsMutexMustLock(ID)
Claim a semaphore (see epicsMutexLock()).
Definition: epicsMutex.h:214
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
Definition: ellLib.c:75
GLBLTYPE void * rsrvPutNotifyFreeList
Definition: server.h:206
unsigned rsrvSizeOfPutNotify ( struct rsrv_put_notify pNotify)

Definition at line 1604 of file camessage.c.

1605 {
1606  unsigned size = sizeof ( *pNotify );
1607  if ( pNotify ) {
1608  if ( pNotify->valueSize >
1609  sizeof ( pNotify->dbrScalarValue ) ) {
1610  size += pNotify->valueSize;
1611  }
1612  }
1613  return size;
1614 }
union rsrv_put_notify::@1 dbrScalarValue
unsigned valueSize
Definition: camessage.c:92

Variable Documentation

GLBLTYPE enum ctl beacon_ctl

Definition at line 213 of file server.h.

GLBLTYPE epicsEventId beacon_startStopEvent

Definition at line 210 of file server.h.

GLBLTYPE ELLLIST beaconAddrList

Definition at line 194 of file server.h.

GLBLTYPE SOCKET beaconSocket

Definition at line 195 of file server.h.

GLBLTYPE unsigned short ca_beacon_port

Definition at line 191 of file server.h.

GLBLTYPE unsigned short ca_server_port

Definition at line 191 of file server.h.

GLBLTYPE unsigned short ca_udp_port

Definition at line 191 of file server.h.

GLBLTYPE int CASDEBUG

Definition at line 190 of file server.h.

GLBLTYPE epicsUInt32* casIgnoreAddrs

Definition at line 197 of file server.h.

GLBLTYPE ELLLIST casIntfAddrList

Definition at line 196 of file server.h.

GLBLTYPE ELLLIST casMCastAddrList

Definition at line 196 of file server.h.

GLBLTYPE enum ctl castcp_ctl

Definition at line 214 of file server.h.

GLBLTYPE epicsEventId castcp_startStopEvent

Definition at line 211 of file server.h.

GLBLTYPE enum ctl casudp_ctl

Definition at line 212 of file server.h.

GLBLTYPE epicsEventId casudp_startStopEvent

Definition at line 209 of file server.h.

GLBLTYPE epicsMutexId clientQlock

Definition at line 198 of file server.h.

GLBLTYPE BUCKET* pCaBucket

Definition at line 199 of file server.h.

GLBLTYPE void* rsrvChanFreeList

Definition at line 201 of file server.h.

GLBLTYPE unsigned rsrvChannelCount

Definition at line 207 of file server.h.

GLBLTYPE void* rsrvClientFreeList

Definition at line 200 of file server.h.

epicsThreadPrivateId rsrvCurrentClient

Definition at line 50 of file caservertask.c.

GLBLTYPE void* rsrvEventFreeList

Definition at line 202 of file server.h.

GLBLTYPE void* rsrvLargeBufFreeListTCP

Definition at line 204 of file server.h.

GLBLTYPE void* rsrvPutNotifyFreeList

Definition at line 206 of file server.h.

GLBLTYPE unsigned rsrvSizeofLargeBufTCP

Definition at line 205 of file server.h.

GLBLTYPE void* rsrvSmallBufFreeListTCP

Definition at line 203 of file server.h.

GLBLTYPE ELLLIST servers

Definition at line 193 of file server.h.

GLBLTYPE unsigned int threadPrios[5]

Definition at line 216 of file server.h.