*** empty log message ***
This commit is contained in:
@ -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 {
|
||||||
|
@ -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;
|
if (AsynSrv_errcode == 0 && AsynSrv_call_depth < 5) {
|
||||||
/*--------------------------------------------------------
|
strcpy (AsynSrv_routine[AsynSrv_call_depth], "AsynSrv_Trace");
|
||||||
** Initialise the error info stack and pre-set the
|
AsynSrv_call_depth++;
|
||||||
** routine name (in case of error).
|
}
|
||||||
|
/*----------------------------------------------
|
||||||
|
** 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.
|
||||||
*/
|
*/
|
||||||
AsynSrv_errcode = AsynSrv_errno = AsynSrv_vaxc_errno = 0;
|
if (asyn_info->skt <= 0) {
|
||||||
strcpy (AsynSrv_routine[0], "AsynSrv_Open");
|
if ((AsynSrv_errcode == 0) && (asyn_info->skt < 0)) {
|
||||||
AsynSrv_call_depth = 1;
|
AsynSrv_errcode = ASYNSRV__FORCED_CLOSED;
|
||||||
/*--------------------------------------------------------
|
}
|
||||||
** 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;
|
return False;
|
||||||
}
|
}
|
||||||
if (asyn_info->chan < 0) asyn_info->chan = 0;
|
/*----------------------------------------------
|
||||||
if (asyn_info->chan > 255) asyn_info->chan = 0;
|
** Select message for server according to value of state.
|
||||||
/*--------------------------------------------------------
|
|
||||||
** Set up a new connection.
|
|
||||||
*/
|
*/
|
||||||
/*---------------------------
|
if (state) {
|
||||||
** Get the Internet address of the server.
|
strcpy (cmnd, "-002");
|
||||||
*/
|
|
||||||
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 {
|
}else {
|
||||||
rmt_hostent = gethostbyname (asyn_info->host);
|
strcpy (cmnd, "-003");
|
||||||
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) {
|
status = send (asyn_info->skt, cmnd, 4, 0); /* Send the request */
|
||||||
time_out.val = AsynSrv_connect_tmo; /* Set new time-out */
|
if (status != 4) {
|
||||||
status = setsockopt (my_skt, IPPROTO_TCP, UCX$C_TCP_PROBE_IDLE,
|
GetErrno (&AsynSrv_errno, &AsynSrv_vaxc_errno);
|
||||||
time_out.chars, sizeof (time_out));
|
if (status == 0) {
|
||||||
}
|
AsynSrv_errcode = ASYNSRV__BAD_SEND; /* Server exited (probably) */
|
||||||
#endif
|
fprintf (stderr, "\nAsynSrv_Trace/send: probable network problem");
|
||||||
/*---------------------------
|
}else if (status == -1) {
|
||||||
** Connect to RS-232-C Server.
|
if (AsynSrv_errno == EPIPE) {
|
||||||
*/
|
AsynSrv_errcode = ASYNSRV__BAD_SEND_PIPE; /* Server exited (probably) */
|
||||||
rmt_sockname_len = sizeof (rmt_sockname);
|
fprintf (stderr, "\nAsynSrv_Trace/send: broken network pipe");
|
||||||
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,
|
|
||||||
sizeof (r_buff.s_pcol_lvl));
|
|
||||||
if (strncmp (r_buff.s_pcol_lvl, RS__PROTOCOL_ID_V01B,
|
|
||||||
strlen (RS__PROTOCOL_ID_V01B)) == 0) {
|
|
||||||
asyn_info->protocol_code = RS__PROTOCOL_CODE_V01B;
|
|
||||||
asyn_info->cmnd_hdr_len = 4;
|
|
||||||
strcpy (asyn_info->cmnd_fmt, "%04d");
|
|
||||||
asyn_info->rply_hdr_len = 4;
|
|
||||||
strcpy (asyn_info->rply_fmt, "%4d");
|
|
||||||
}else if (strncmp (r_buff.s_pcol_lvl, RS__PROTOCOL_ID,
|
|
||||||
strlen (RS__PROTOCOL_ID)) == 0) {
|
|
||||||
asyn_info->protocol_code = RS__PROTOCOL_CODE;
|
|
||||||
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 {
|
}else {
|
||||||
close (my_skt);
|
AsynSrv_errcode = ASYNSRV__BAD_SEND_NET; /* It's some other net problem */
|
||||||
asyn_info->skt = 0;
|
perror ("AsynSrv_Trace/send");
|
||||||
fprintf (stderr,
|
|
||||||
"\nAsynSrv_Open: Server protocol level is unrecognised.\n"
|
|
||||||
" Server level is \"%4s\"\n", r_buff.s_pcol_lvl);
|
|
||||||
return False;
|
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
close (my_skt);
|
AsynSrv_errcode = ASYNSRV__BAD_SEND_UNKN; /* TCP/IP problems */
|
||||||
asyn_info->skt = 0;
|
fprintf (stderr, "\nAsynSrv_Trace/send: probable TCP/IP problem");
|
||||||
AsynSrv_errcode = ASYNSRV__BAD_PROT_LVL;
|
}
|
||||||
fprintf (stderr,
|
AsynSrv_Close (asyn_info, True); /* Force close TCP/IP connection */
|
||||||
"\nAsynSrv_Open: Problem getting protocol level of Server!\n");
|
fprintf (stderr, " - link to server force-closed.\n");
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
AsynSrv_errcode = AsynSrv_errno = AsynSrv_vaxc_errno = 0;
|
|
||||||
AsynSrv_call_depth = 0;
|
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 -----*/
|
||||||
|
Reference in New Issue
Block a user