*** empty log message ***

This commit is contained in:
cvs
2000-03-31 14:11:23 +00:00
parent 714b8ae84d
commit 69a54f8624
2 changed files with 287 additions and 211 deletions

View File

@ -1,6 +1,6 @@
#ifndef _asynsrv_def_ #ifndef _asynsrv_def_
#define _asynsrv_def_ #define _asynsrv_def_
/*------------------------------------------------ AsynSrv_DEF.H Ident V01M /*------------------------------------------------ AsynSrv_DEF.H Ident V01N
*/ */
#ifndef OffsetOf #ifndef OffsetOf
#define OffsetOf(type, identifier) ((size_t)(&((type*) NULL)->identifier)) #define OffsetOf(type, identifier) ((size_t)(&((type*) NULL)->identifier))
@ -32,6 +32,8 @@
char eot[4]; /* Expected terminators */ char eot[4]; /* Expected terminators */
int max_replies; /* Binary version of #replies in response */ int max_replies; /* Binary version of #replies in response */
int n_replies; /* # of last response returned to caller */ int n_replies; /* # of last response returned to caller */
void (*idleHandler) (int, int); /* MZ. handler called when waiting ..
** .. on a response */
}; };
struct AsynSrv_HostPortSkt { struct AsynSrv_HostPortSkt {

View File

@ -1,4 +1,4 @@
#define ident "1B12" #define ident "1C02"
#ifdef VAXC #ifdef VAXC
#module AsynSrv_Utility ident #module AsynSrv_Utility ident
#endif #endif
@ -6,9 +6,6 @@
#pragma module AsynSrv_Utility ident #pragma module AsynSrv_Utility ident
#endif #endif
/* /*
#define DEBUG 1
*/
/*
** +--------------------------------------------------------------+ ** +--------------------------------------------------------------+
** | Paul Scherrer Institute | ** | Paul Scherrer Institute |
** | Department ASQ | ** | Department ASQ |
@ -47,6 +44,8 @@
** 1B02 5-May-1997 DM. Set 5 sec time-out on "connect" on VMS systems. ** 1B02 5-May-1997 DM. Set 5 sec time-out on "connect" on VMS systems.
** 1B07 11-Mar-1998 DM. Allow range of msecTmo to be 0 - 999999 (it was ** 1B07 11-Mar-1998 DM. Allow range of msecTmo to be 0 - 999999 (it was
** 100 - 999999). ** 100 - 999999).
** 1C01 21-Mar-2000 MZ. Introduced idleHandler
** 1C02 30-Mar-2000 DM. Add trace and flush facilities.
**============================================================================ **============================================================================
** The entry points included in this module are described below. Prototypes ** The entry points included in this module are described below. Prototypes
** can be defined via: ** can be defined via:
@ -57,11 +56,14 @@
** AsynSrv_Config - Configure an open AsynSrv_Utility connection. ** AsynSrv_Config - Configure an open AsynSrv_Utility connection.
** AsynSrv_ConfigDflt - Set defaults for AsynSrv_Open. ** AsynSrv_ConfigDflt - Set defaults for AsynSrv_Open.
** AsynSrv_ErrInfo - Return detailed status from last operation. ** AsynSrv_ErrInfo - Return detailed status from last operation.
** AsynSrv_Flush - Send a "FLUSH" request to an RS-232-C Server.
** AsynSrv_GetReply - Get next reply from a reply buffer. ** AsynSrv_GetReply - Get next reply from a reply buffer.
** AsynSrv_Open - Open a connection to an RS-232-C Server. ** AsynSrv_Open - Open a connection to an RS-232-C Server.
** AsynSrv_SendCmnds - Send commands to a channel of an RS-232-C Server. ** AsynSrv_SendCmnds - Send commands to a channel of an RS-232-C Server.
** AsynSrv_SendCmndsBig - Similar to AsynSrv_SendCmnds but with user ** AsynSrv_SendCmndsBig - Similar to AsynSrv_SendCmnds but with user
** defined buffer sizes. ** defined buffer sizes.
** AsynSrv_Trace - Send a "TRACE ON" or "TRACE OFF" request to
** an RS-232-C Server.
**--------------------------------------------------------------------- **---------------------------------------------------------------------
** int AsynSrv_Close (&asyn_info, force_flag) ** int AsynSrv_Close (&asyn_info, force_flag)
** ------------- ** -------------
@ -124,6 +126,13 @@
** commands sent to a serial channel on the ** commands sent to a serial channel on the
** server. The first character specifies the ** server. The first character specifies the
** number of terminators (max=3). ** number of terminators (max=3).
** "idleHdl" void (*hdl) (int msecTmo, int socket) MZ.
** A handler which is called in AsynSrv_SendCmds
** before receiving the response. The handler
** should contain a call to "select ()" and return
** on a read event on the socket passed as
** argument, or after the timeout specified
** has expired.
**--------------------------------------------------------------------- **---------------------------------------------------------------------
** int AsynSrv_ConfigDflt (&par_id, par_val, ...) ** int AsynSrv_ConfigDflt (&par_id, par_val, ...)
** ------------------ ** ------------------
@ -185,6 +194,24 @@
** Returns detailed status of the last operation. Once an error has been ** Returns detailed status of the last operation. Once an error has been
** detected, the error status is frozen until this routine has been called. ** detected, the error status is frozen until this routine has been called.
**------------------------------------------------------------------------- **-------------------------------------------------------------------------
** int AsynSrv_Flush (&asyn_info)
** -------------
** Input Args:
** struct AsynSrv__info *asyn_info - the structure used in the call to
** AsynSrv_Open. It contains settings required
** for setting up and sending send_buff.
** Output Args:
** none
** Modified Args:
** none
** Return status:
** Same as AsynSrv_Trace
** Routines called:
** Socket library routines send and recv.
** Description:
** The 4-byte message "-004" is sent to the server to cause it to flush
** its buffers. Otherwise, this routine is identical to AsynSrv_Trace.
**-------------------------------------------------------------------------
** char *AsynSrv_GetReply (&asyn_info, &rcve_buff, &last_rply) ** char *AsynSrv_GetReply (&asyn_info, &rcve_buff, &last_rply)
** ---------------- ** ----------------
** Input Args: ** Input Args:
@ -394,6 +421,69 @@
** transmission of zeros) and the send and receive structures are assumed ** transmission of zeros) and the send and receive structures are assumed
** to have been extended to the sizes specified by suitable declarations ** to have been extended to the sizes specified by suitable declarations
** in the calling module. ** in the calling module.
**-------------------------------------------------------------------------
** int AsynSrv_Trace (&asyn_info, state)
** -------------
** Input Args:
** struct AsynSrv__info *asyn_info - the structure used in the call to
** AsynSrv_Open. It contains settings required
** for setting up and sending send_buff.
** int state - True/False to turn tracing on/off.
** Output Args:
** none
** Modified Args:
** none
** Return status:
** True if no problems detected, otherwise False and errcode (see
** AsynSrv_ErrInfo) is set to indicate the nature of the problem.
** AsynSrv_errcode may be set as follows:
** The next 4 errors are related to network errors whilst sending the
** 4-byte message buffer to the server:
** ASYNSRV__BAD_SEND --> Network problem - server has
** probably abended.
** ASYNSRV__BAD_SEND_PIPE --> Network pipe broken - probably same
** cause as ASYNSRV__BAD_SEND.
** ASYNSRV__BAD_SEND_NET --> Some other network problem. "errno"
** may be helpful.
** ASYNSRV__BAD_SEND_UNKN --> Some other network problem happened
** resulting in the message not
** getting sent completely. "errno" is
** probably not helpful in this case.
** ASYNSRV__BAD_RECV \ These are network errors whilst
** ASYNSRV__BAD_RECV_PIPE > receiving the 4-byte response.
** ASYNSRV__BAD_RECV_NET / They are analogous to ASYNSRV__BAD_SEND
** ASYNSRV__BAD_RECV_UNKN / ... ASYNSRV__BAD_SEND_UNKN.
** ASYNSRV__BAD_NOT_BCD --> The 4-byte response header is not an
** echo of the 4 bytes which were sent.
** ASYNSRV__FORCED_CLOSED --> The connection to the channel has been
** forcefully closed. See below.
** ASYNSRV__FORCED_CLOSED occurs if AsynSrv_Close has been called
** for another device on the same server and the 'force_flag'
** was set (see AsynSrv_Close). The caller should call
** AsynSrv_Close and then AsynSrv_Open to re-establish a
** connection to the server.
** Routines called:
** Socket library routines send and recv.
** Description:
** To turn on tracing, the 4-byte message "-002" is sent to the server.
** To turn off tracing, the 4-byte message "-003" is sent to the server.
** The server is expected to respond by echoing the message.
**
** For any of the following errors:
** ASYNSRV__BAD_SEND (Note: ASYNSRV__BAD_SEND_LEN and
** ASYNSRV__BAD_SEND_PIPE ASYNSRV__BAD_RECV_LEN and
** ASYNSRV__BAD_SEND_NET ASYNSRV__BAD_REPLY
** ASYNSRV__BAD_SEND_UNKN do not cause a close)
** ASYNSRV__BAD_RECV
** ASYNSRV__BAD_RECV_PIPE
** ASYNSRV__BAD_RECV_NET
** ASYNSRV__BAD_RECV_UNKN
** ASYNSRV__BAD_NOT_BCD
** the network link to the server is force-closed via a call to
** AsynSrv_Close. Once the error has been corrected, the link can be
** re-opened via a call to AsynSrv_Open. As a result of the force-close,
** other active handles will need to be released via a call to
** AsynSrv_Close before AsynSrv_Open is called.
**============================================================================*/ **============================================================================*/
/* /*
**--------------------------------------------------------------------------- **---------------------------------------------------------------------------
@ -412,6 +502,7 @@
#include <string.h> #include <string.h>
#ifdef __VMS #ifdef __VMS
#pragma nostandard /* The "$" characters in ucx$inetdef.h give trouble! */
#include <ucx$inetdef.h> #include <ucx$inetdef.h>
#include <unixio.h> #include <unixio.h>
#else #else
@ -615,6 +706,8 @@
return False; return False;
} }
memcpy (asyn_info->eot, my_eot, 4); memcpy (asyn_info->eot, my_eot, 4);
}else if (strcmp (txt_ptr, "idleHdl") == 0) { /* MZ. */
asyn_info->idleHandler = (void (*) (int, int)) va_arg (ap, void *);
}else { }else {
AsynSrv_errcode = ASYNSRV__BAD_PAR; AsynSrv_errcode = ASYNSRV__BAD_PAR;
return False; return False;
@ -764,6 +857,94 @@
} }
/* /*
**--------------------------------------------------------------------------- **---------------------------------------------------------------------------
** AsynSrv_Flush: Send a Flush command to RS232C server.
*/
int AsynSrv_Flush (
/* =============
*/ struct AsynSrv__info *asyn_info) {
int status;
char cmnd[8], rply[8];
/*----------------------------------------------
** Pre-set the routine name (in case of error)
*/
if (AsynSrv_errcode == 0 && AsynSrv_call_depth < 5) {
strcpy (AsynSrv_routine[AsynSrv_call_depth], "AsynSrv_Flush");
AsynSrv_call_depth++;
}
/*----------------------------------------------
** Do nothing if no connection - the connection gets
** closed if an error is detected. The connection may
** also be marked to have been forcefully closed.
*/
if (asyn_info->skt <= 0) {
if ((AsynSrv_errcode == 0) && (asyn_info->skt < 0)) {
AsynSrv_errcode = ASYNSRV__FORCED_CLOSED;
}
return False;
}
/*----------------------------------------------
** Set up message for server.
*/
strcpy (cmnd, "-004");
status = send (asyn_info->skt, cmnd, 4, 0); /* Send the request */
if (status != 4) {
GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno);
if (status == 0) {
AsynSrv_errcode = ASYNSRV__BAD_SEND; /* Server exited (probably) */
fprintf (stderr, "\nAsynSrv_Flush/send: probable network problem");
}else if (status == -1) {
if (AsynSrv_errno == EPIPE) {
AsynSrv_errcode = ASYNSRV__BAD_SEND_PIPE; /* Server exited (probably) */
fprintf (stderr, "\nAsynSrv_Flush/send: broken network pipe");
}else {
AsynSrv_errcode = ASYNSRV__BAD_SEND_NET; /* It's some other net problem */
perror ("AsynSrv_Flush/send");
}
}else {
AsynSrv_errcode = ASYNSRV__BAD_SEND_UNKN; /* TCP/IP problems */
fprintf (stderr, "\nAsynSrv_Flush/send: probable TCP/IP problem");
}
AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */
fprintf (stderr, " - link to server force-closed.\n");
return False;
}
status = recv (asyn_info->skt, rply, 4, 0);
if (status != 4) {
GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno);
if (status == 0) {
AsynSrv_errcode = ASYNSRV__BAD_RECV; /* Server exited (probably) */
fprintf (stderr, "\nAsynSrv_Flush/recv: probable network problem");
}else if (status == -1) {
if (AsynSrv_errno == EPIPE) {
AsynSrv_errcode = ASYNSRV__BAD_RECV_PIPE; /* Server exited (probably) */
fprintf (stderr, "\nAsynSrv_Flush/recv: broken network pipe");
}else {
AsynSrv_errcode = ASYNSRV__BAD_RECV_NET; /* It's some other net problem */
perror ("AsynSrv_Flush/recv");
}
}else {
AsynSrv_errcode = ASYNSRV__BAD_RECV_UNKN; /* TCP/IP problems */
fprintf (stderr, "\nAsynSrv_Flush/recv: probable TCP/IP problem");
}
AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */
fprintf (stderr, " - link to server force-closed.\n");
return False;
}
if (memcmp (cmnd, rply, 4) != 0) {
AsynSrv_errcode = ASYNSRV__BAD_NOT_BCD; /* Message not echoed OK */
AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */
fprintf (stderr, "\nAsynSrv_Flush/recv: command not echoed correctly"
" - link to server force-closed.\n");
return False;
}
if (AsynSrv_errcode == 0) AsynSrv_call_depth--;
return True;
}
/*
**---------------------------------------------------------------------------
** AsynSrv_GetReply: Get next reply from a reply buffer. ** AsynSrv_GetReply: Get next reply from a reply buffer.
*/ */
char *AsynSrv_GetReply ( char *AsynSrv_GetReply (
@ -791,9 +972,6 @@
} }
} }
} }
#ifdef DEBUG
printf("Reply: %s\n", pntr);
#endif
return pntr; return pntr;
} }
/* /*
@ -878,6 +1056,7 @@
AsynSrv_eot, sizeof (asyn_info->eot)); AsynSrv_eot, sizeof (asyn_info->eot));
asyn_info->max_replies = asyn_info->n_replies = 0; asyn_info->max_replies = asyn_info->n_replies = 0;
asyn_info->idleHandler = NULL;
AsynSrv_call_depth--; AsynSrv_call_depth--;
return True; return True;
} }
@ -890,16 +1069,16 @@
return False; return False;
} }
/*-------------------------------------------------------- /*--------------------------------------------------------
** But, before going any further, do some quick checks on ** There's room for a new connection but, before going any
** values in asyn_info. ** further, do some quick checks on values in asyn_info.
*/ */
if ((asyn_info->port <= 0) || if ((asyn_info->port <= 0) ||
(asyn_info->port > 65535)) { (asyn_info->port > 65535) ||
(asyn_info->chan < 0) ||
(asyn_info->chan > 255)) {
AsynSrv_errcode = ASYNSRV__BAD_PAR; /* Something is bad! */ AsynSrv_errcode = ASYNSRV__BAD_PAR; /* Something is bad! */
return False; return False;
} }
if (asyn_info->chan < 0) asyn_info->chan = 0;
if (asyn_info->chan > 255) asyn_info->chan = 0;
/*-------------------------------------------------------- /*--------------------------------------------------------
** Set up a new connection. ** Set up a new connection.
*/ */
@ -1011,6 +1190,7 @@
** .. dflt terminator(s) */ ** .. dflt terminator(s) */
asyn_info->max_replies = 0; asyn_info->max_replies = 0;
asyn_info->n_replies = 0; asyn_info->n_replies = 0;
asyn_info->idleHandler = NULL;
/* /*
** Send a null command buffer to the server. This should give ** Send a null command buffer to the server. This should give
** a "protocol mismatch" error response and from this we can get ** a "protocol mismatch" error response and from this we can get
@ -1167,9 +1347,6 @@
cmnd_lst_ptr += c_len; cmnd_lst_ptr += c_len;
ncmnds++; ncmnds++;
bytes_left = bytes_left - size; bytes_left = bytes_left - size;
#ifdef DEBUG
printf("Sending: %s\n",txt_ptr);
#endif
txt_ptr = va_arg (ap, char *); txt_ptr = va_arg (ap, char *);
} }
} }
@ -1206,6 +1383,14 @@
return False; return False;
} }
if (asyn_info->idleHandler != NULL) { /* MZ. */
sscanf(asyn_info->tmo, "%4d", &i); /* Decode timeout from ASCII ..
** .. encoded deci-sec */
asyn_info->idleHandler (i*150, asyn_info->skt); /* Wait for an event ..
** .. on asyn_info->skt or a ..
** .. timeout of 1.5*tmo */
}
size = sizeof (rcve_buff->msg_size); size = sizeof (rcve_buff->msg_size);
status = recv (asyn_info->skt, rcve_buff->msg_size, size, 0); status = recv (asyn_info->skt, rcve_buff->msg_size, size, 0);
if (status != size) { if (status != size) {
@ -1557,206 +1742,95 @@
} }
/* /*
**--------------------------------------------------------------------------- **---------------------------------------------------------------------------
** AsynSrv_Force: Open a connection to an RS-232-C Server. ** AsynSrv_Trace: Send a Trace command to RS232C server.
** Thereby insisting on an own socket.
*/ */
int AsynSrv_Force ( int AsynSrv_Trace (
/* ============ /* =============
*/ struct AsynSrv__info *asyn_info) { */ struct AsynSrv__info *asyn_info,
int state) {
int i, status; int status;
int my_skt; char cmnd[8], rply[8];
char old_time_out[4]; /*----------------------------------------------
union { ** Pre-set the routine name (in case of error)
char chars[4];
int val;
} time_out;
char buff[128];
struct RS__MsgStruct s_buff;
struct RS__RespStruct r_buff;
unsigned int oto_len, oto_status;
struct hostent *rmt_hostent;
struct in_addr *rmt_inet_addr_pntr;
struct in_addr rmt_inet_addr;
int rmt_sockname_len;
struct sockaddr_in lcl_sockname;
struct sockaddr_in rmt_sockname;
char *errtxt_ptr;
int errcode, my_errno, my_vaxc_errno;
/*--------------------------------------------------------
*/
asyn_info->skt = 0;
/*--------------------------------------------------------
** Initialise the error info stack and pre-set the
** routine name (in case of error).
*/
AsynSrv_errcode = AsynSrv_errno = AsynSrv_vaxc_errno = 0;
strcpy (AsynSrv_routine[0], "AsynSrv_Open");
AsynSrv_call_depth = 1;
/*--------------------------------------------------------
** But, before going any further, do some quick checks on
** values in asyn_info.
*/
if ((asyn_info->port <= 0) ||
(asyn_info->port > 65535)) {
AsynSrv_errcode = ASYNSRV__BAD_PAR; /* Something is bad! */
return False;
}
if (asyn_info->chan < 0) asyn_info->chan = 0;
if (asyn_info->chan > 255) asyn_info->chan = 0;
/*--------------------------------------------------------
** Set up a new connection.
*/
/*---------------------------
** Get the Internet address of the server.
*/
rmt_inet_addr.s_addr = inet_addr (asyn_info->host);
if (rmt_inet_addr.s_addr != -1) {
rmt_inet_addr_pntr = &rmt_inet_addr;
}else {
rmt_hostent = gethostbyname (asyn_info->host);
if (rmt_hostent == NULL) {
AsynSrv_errcode = ASYNSRV__BAD_HOST;
GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); /* Save errno info */
fprintf (stderr, "\nAsynSrv_Open/gethostbyname: Failed to get Internet "
"address of \"%s\".\n", asyn_info->host);
return False;
}
rmt_inet_addr_pntr = (struct in_addr *) rmt_hostent->h_addr_list[0];
}
/*---------------------------
** Create a TCP/IP socket for connecting to server and bind it.
*/
my_skt = socket (AF_INET, SOCK_STREAM, 0);
if (my_skt <= 0) {
AsynSrv_errcode = ASYNSRV__BAD_SOCKET;
GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); /* Save the errno info */
fprintf (stderr, "\nAsynSrv_Open/socket: Failed to create a socket.\n");
return False;
}
lcl_sockname.sin_family = AF_INET;
lcl_sockname.sin_port = htons (0);
lcl_sockname.sin_addr.s_addr = 0;
status = bind (my_skt, (struct sockaddr *) &lcl_sockname,
sizeof (lcl_sockname));
if (status == -1) {
close (my_skt);
AsynSrv_errcode = ASYNSRV__BAD_BIND;
GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); /* Save the errno info */
fprintf (stderr, "\nAsynSrv_Open/bind: Failed to bind socket.\n");
return False;
}
/*---------------------------
** Set short time-out (VMS systems only)
*/
#ifdef __VMS
oto_len = sizeof (old_time_out); /* Save current time-out first */
oto_status = getsockopt (my_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE,
old_time_out, &oto_len);
if (oto_status == 0) {
time_out.val = AsynSrv_connect_tmo; /* Set new time-out */
status = setsockopt (my_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE,
time_out.chars, sizeof (time_out));
}
#endif
/*---------------------------
** Connect to RS-232-C Server.
*/
rmt_sockname_len = sizeof (rmt_sockname);
rmt_sockname.sin_family = AF_INET;
rmt_sockname.sin_port = htons (asyn_info->port);
rmt_sockname.sin_addr.s_addr = rmt_inet_addr_pntr->s_addr;
status = connect (my_skt, (struct sockaddr *) &rmt_sockname,
sizeof (rmt_sockname));
if (status != 0) {
close (my_skt);
AsynSrv_errcode = ASYNSRV__BAD_CONNECT;
GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno); /* Save the errno info */
fprintf (stderr,
"\nAsynSrv_Open/connect: Failed to connect to server.\n");
perror ("AsynSrv_Open");
return False;
}
/*---------------------------
** Restore time-out (VMS only)
*/
#ifdef __VMS
if (oto_status == 0) {
setsockopt (my_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE,
old_time_out, oto_len);
}
#endif
/*---------------------------------------------------
** Setup the defaults in the AsynSrv__info data structure.
*/
asyn_info->skt = my_skt; /* Return socket number to caller */
asyn_info->protocol_code = 0; /* Ensure protocol_code set to "unknown" */
memcpy (asyn_info->protocol_id, "\0\0\0\0",
sizeof (asyn_info->protocol_id));
asyn_info->cmnd_hdr_len = 4;
strcpy (asyn_info->cmnd_fmt, "%04d");
asyn_info->rply_hdr_len = 4;
strcpy (asyn_info->rply_fmt, "%4d");
sprintf (buff, "%04d", asyn_info->chan); /* Convert channel # to ASCII */
memcpy (asyn_info->chan_char, buff, sizeof (asyn_info->chan_char));
sprintf (buff, "%04d", AsynSrv_msec_tmo/100); /* Set dflt time-out ..
** .. (deci-secs) */
memcpy (asyn_info->tmo, buff, sizeof (asyn_info->tmo));
memcpy (asyn_info->eot, AsynSrv_eot, sizeof (asyn_info->eot)); /* Set ..
** .. dflt terminator(s) */
asyn_info->max_replies = 0;
asyn_info->n_replies = 0;
/*
** Send a null command buffer to the server. This should give
** a "protocol mismatch" error response and from this we can get
** the actual protocol level supported by the server.
*/
status = AsynSrv_SendCmnds (asyn_info, &s_buff, &r_buff, NULL);
if (!status && (AsynSrv_errcode == ASYNSRV__BAD_PROT_LVL)) {
/*
** As expected, we got a "protocol mismatch" error.
** Save the server's protocol level for future use.
*/ */
memcpy (asyn_info->protocol_id, r_buff.s_pcol_lvl, if (AsynSrv_errcode == 0 && AsynSrv_call_depth < 5) {
sizeof (r_buff.s_pcol_lvl)); strcpy (AsynSrv_routine[AsynSrv_call_depth], "AsynSrv_Trace");
if (strncmp (r_buff.s_pcol_lvl, RS__PROTOCOL_ID_V01B, AsynSrv_call_depth++;
strlen (RS__PROTOCOL_ID_V01B)) == 0) { }
asyn_info->protocol_code = RS__PROTOCOL_CODE_V01B; /*----------------------------------------------
asyn_info->cmnd_hdr_len = 4; ** Do nothing if no connection - the connection gets
strcpy (asyn_info->cmnd_fmt, "%04d"); ** closed if an error is detected. The connection may
asyn_info->rply_hdr_len = 4; ** also be marked to have been forcefully closed.
strcpy (asyn_info->rply_fmt, "%4d"); */
}else if (strncmp (r_buff.s_pcol_lvl, RS__PROTOCOL_ID, if (asyn_info->skt <= 0) {
strlen (RS__PROTOCOL_ID)) == 0) { if ((AsynSrv_errcode == 0) && (asyn_info->skt < 0)) {
asyn_info->protocol_code = RS__PROTOCOL_CODE; AsynSrv_errcode = ASYNSRV__FORCED_CLOSED;
asyn_info->cmnd_hdr_len = 2;
strcpy (asyn_info->cmnd_fmt, "%02d");
asyn_info->rply_hdr_len = 2;
strcpy (asyn_info->rply_fmt, "%2d");
}else {
close (my_skt);
asyn_info->skt = 0;
fprintf (stderr,
"\nAsynSrv_Open: Server protocol level is unrecognised.\n"
" Server level is \"%4s\"\n", r_buff.s_pcol_lvl);
return False;
} }
}else {
close (my_skt);
asyn_info->skt = 0;
AsynSrv_errcode = ASYNSRV__BAD_PROT_LVL;
fprintf (stderr,
"\nAsynSrv_Open: Problem getting protocol level of Server!\n");
return False; return False;
} }
AsynSrv_errcode = AsynSrv_errno = AsynSrv_vaxc_errno = 0; /*----------------------------------------------
AsynSrv_call_depth = 0; ** Select message for server according to value of state.
*/
if (state) {
strcpy (cmnd, "-002");
}else {
strcpy (cmnd, "-003");
}
status = send (asyn_info->skt, cmnd, 4, 0); /* Send the request */
if (status != 4) {
GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno);
if (status == 0) {
AsynSrv_errcode = ASYNSRV__BAD_SEND; /* Server exited (probably) */
fprintf (stderr, "\nAsynSrv_Trace/send: probable network problem");
}else if (status == -1) {
if (AsynSrv_errno == EPIPE) {
AsynSrv_errcode = ASYNSRV__BAD_SEND_PIPE; /* Server exited (probably) */
fprintf (stderr, "\nAsynSrv_Trace/send: broken network pipe");
}else {
AsynSrv_errcode = ASYNSRV__BAD_SEND_NET; /* It's some other net problem */
perror ("AsynSrv_Trace/send");
}
}else {
AsynSrv_errcode = ASYNSRV__BAD_SEND_UNKN; /* TCP/IP problems */
fprintf (stderr, "\nAsynSrv_Trace/send: probable TCP/IP problem");
}
AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */
fprintf (stderr, " - link to server force-closed.\n");
return False;
}
status = recv (asyn_info->skt, rply, 4, 0);
if (status != 4) {
GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno);
if (status == 0) {
AsynSrv_errcode = ASYNSRV__BAD_RECV; /* Server exited (probably) */
fprintf (stderr, "\nAsynSrv_Trace/recv: probable network problem");
}else if (status == -1) {
if (AsynSrv_errno == EPIPE) {
AsynSrv_errcode = ASYNSRV__BAD_RECV_PIPE; /* Server exited (probably) */
fprintf (stderr, "\nAsynSrv_Trace/recv: broken network pipe");
}else {
AsynSrv_errcode = ASYNSRV__BAD_RECV_NET; /* It's some other net problem */
perror ("AsynSrv_Trace/recv");
}
}else {
AsynSrv_errcode = ASYNSRV__BAD_RECV_UNKN; /* TCP/IP problems */
fprintf (stderr, "\nAsynSrv_Trace/recv: probable TCP/IP problem");
}
AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */
fprintf (stderr, " - link to server force-closed.\n");
return False;
}
if (memcmp (cmnd, rply, 4) != 0) {
AsynSrv_errcode = ASYNSRV__BAD_NOT_BCD; /* Message not echoed OK */
AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */
fprintf (stderr, "\nAsynSrv_Trace/recv: command not echoed correctly"
" - link to server force-closed.\n");
return False;
}
if (AsynSrv_errcode == 0) AsynSrv_call_depth--;
return True; return True;
} }
/*-------------------------------------------- End of AsynSrv_Utility.C -----*/ /*-------------------------------------------- End of AsynSrv_Utility.C -----*/