@ -1,4 +1,4 @@
# define ident "1C02 "
# define ident "1C06 "
# ifdef VAXC
# module AsynSrv_Utility ident
# endif
@ -46,24 +46,52 @@
** 100 - 999999).
** 1C01 21-Mar-2000 MZ. Introduced idleHandler
** 1C02 30-Mar-2000 DM. Add trace and flush facilities.
** 1C06 30-Aug-2000 DM. Add AsynSrv_GetLenTerm.
**============================================================================
** The entry points included in this module are described below. Prototypes
** can be defined via:
**
** #include <sinq_prototypes.h>
**
** AsynSrv_ChanClose - Send a "CLOSE CHAN" request to RS-232-C Server.
** AsynSrv_Close - Close a connection to an RS-232-C Server.
** AsynSrv_Config - Configure an open AsynSrv_Utility connection.
** AsynSrv_ConfigDflt - Set defaults for AsynSrv_Open.
** AsynSrv_ErrInfo - Return detailed status from last operation.
** AsynSrv_Flush - Send a "FLUSH" request to an RS-232-C Server.
** AsynSrv_GetLenTerm - Get length and terminator of a reply.
** AsynSrv_GetReply - Get next reply from a reply buffer.
** AsynSrv_Open - Open a connection to an RS-232-C Server.
** AsynSrv_OpenNew - Same as AsynSrv_Open but forces the opening
** of a new socket.
** AsynSrv_SendCmnds - Send commands to a channel of an RS-232-C Server.
** AsynSrv_SendCmndsBig - Similar to AsynSrv_SendCmnds but with user
** defined buffer sizes.
** AsynSrv_Trace - Send a "TRACE ON" or "TRACE OFF" request to
** an RS-232-C Server.
** AsynSrv_Trace_Write - Send a "TRACE WRITE" request to RS-232-C Server.
** Other entry points which are private (i.e. not in <sinq_prototypes.h>):
** AsynSrv_SendSpecCmnd - Send a "special" command to an RS-232-C Server.
**---------------------------------------------------------------------
** int AsynSrv_ChanClose (&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:
** True if no problems detected, otherwise False and errcode (see
** AsynSrv_ErrInfo) is set to indicate the nature of the problem.
** See AsynSrv_SendSpecCmnd for possible error codes.
** Routines called:
** AsynSrv_SendSpecCmnd
** Description:
** AsynSrv_SendSpecCmnd is called to send the 4-byte "special"
** command "-006" to the server to cause it to close its serial ports.
**---------------------------------------------------------------------
** int AsynSrv_Close (&asyn_info, force_flag)
** -------------
@ -205,12 +233,40 @@
** Modified Args:
** none
** Return status:
** Same as AsynSrv_Trac e
** Same as AsynSrv_ChanClos e
** Routines called:
** Socket library routines send and recv.
** Same as AsynSrv_ChanClose
** 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 .
** AsynSrv_SendSpecCmnd is called to send the 4-byte "special"
** command "-004" to the server to cause it to close its serial ports .
**-------------------------------------------------------------------------
** int AsynSrv_GetLenTerm (&asyn_info, &rcve_buff, &rply, *len, &term)
** ------------------
** Input Args:
** struct AsynSrv__info *asyn_info - the structure used in the call to
** AsynSrv_Open. It is used to hold status info
** between calls to this routine.
** struct RS__RespStruct *rcve_buff - address of receive buffer used
** in last call to AsynSrv_SendCmnds.
** char *rply - address of a reply in rcve_buff as
** returned by AsynSrv_GetReply.
** Output Args:
** int *len - address of location to receive the
** length of the reply.
** char *term - address of location to receive the
** terminator of the reply.
** Modified Args:
** none
** Return status:
** True if everything seems to be OK. Otherwise, False.
** Routines called:
** none
** Description:
** AsynSrv_GetLenTerm simply converts the length of the reply as saved
** in rply[-hdr_size-1] from ASCII to binary, subtracts 2 from it (to
** allow for the terminator byte and the null termination character) and
** returns it to the caller. *term is set to the value of the character
** at location rply[-1].
**-------------------------------------------------------------------------
** char *AsynSrv_GetReply (&asyn_info, &rcve_buff, &last_rply)
** ----------------
@ -246,10 +302,12 @@
** int AsynSrv_Open (&asyn_info)
** ------------
** Input Args:
** asyn_info->host - Name of host offering the RS-232-C service. The name
** struct AsynSrv__info *asyn_info
** asyn_info->host - Name of host offering the RS-232-C service. The name
** can be either symbolic or numeric, e.g.
** "lnsw02.psi.ch" or "129.129.90.18".
** asyn_info->port - Number of TCP/IP port of TCP/IP server.
** asyn_info->port - Number of TCP/IP port of TCP/IP server.
** asyn_info->chan - Number of RS-232-C channel to be used.
** Output Args:
** none
** Modified Args:
@ -285,6 +343,31 @@
** "force-close" function can be performed. The link is added to this
** table too.
**-------------------------------------------------------------------------
** int AsynSrv_OpenNew (&asyn_info)
** ---------------
** Input Args:
** struct AsynSrv__info *asyn_info
** asyn_info->host - Name of host offering the RS-232-C service. The name
** can be either symbolic or numeric, e.g.
** "lnsw02.psi.ch" or "129.129.90.18".
** asyn_info->port - Number of TCP/IP port of TCP/IP server.
** asyn_info->chan - Number of RS-232-C channel to be used.
** Output Args:
** none
** Modified Args:
** struct AsynSrv__info *asyn_info - a structure holding skt, host and
** port of the connection. On return
** skt = socket number of connection.
** Set to 0 if error.
** Return status:
** See AsynSrv_Open
** Routines called:
** See AsynSrv_Open
** Description:
** This routine is the same as AsynSrv_Open but forces the opening
** of a new socket. The socket will be marked to ensure that no other
** connections share this connection.
**-------------------------------------------------------------------------
** int AsynSrv_SendCmnds (&asyn_info, &send_buff, &rcve_buff, ...)
** -----------------
** Input Args:
@ -422,13 +505,13 @@
** to have been extended to the sizes specified by suitable declarations
** in the calling module.
**-------------------------------------------------------------------------
** int AsynSrv_Trace (&asyn_info, state )
** -------------
** int AsynSrv_SendSpecCmnd (&asyn_info, &cmnd )
** -------------------
** 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 .
** char *cmnd - the 4-byte special command to be sent .
** Output Args:
** none
** Modified Args:
@ -465,15 +548,15 @@
** 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-byt e m essage "-003" is sent to the server.
** The server is expected to respond by echoing the message .
**
** AsynSrv_SendSpecCmnd sends the 4-byte "special" command, cmnd, to the
** server and reads th e r esponse. The response should be an echo of the
** command which was sent .
** Note:
** 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_SEND
** ASYNSRV__BAD_SEND_PIPE
** ASYNSRV__BAD_SEND_NET
** ASYNSRV__BAD_SEND_UNKN
** ASYNSRV__BAD_RECV
** ASYNSRV__BAD_RECV_PIPE
** ASYNSRV__BAD_RECV_NET
@ -484,6 +567,51 @@
** 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.
**-------------------------------------------------------------------------
** 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:
** Same as AsynSrv_ChanClose
** Routines called:
** Same as AsynSrv_ChanClose
** Description:
** AsynSrv_SendSpecCmnd is called to send a 4-byte "special" command
** to the server. The command is "-002" to turn on tracing and "-003"
** to turn off tracing.
** 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.
**
**-------------------------------------------------------------------------
** int AsynSrv_Trace_Write (&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_ChanClose
** Routines called:
** Same as AsynSrv_ChanClose
** Description:
** AsynSrv_SendSpecCmnd is called to send the 4-byte "special"
** command "-005" to the server to cause it to write its trace
** buffer to disk.
**============================================================================*/
/*
**---------------------------------------------------------------------------
@ -517,6 +645,10 @@
# define False 0
# define MAX_OPEN 64
int AsynSrv_SendSpecCmnd ( /* A prototype for a local routine */
struct AsynSrv__info * asyn_info ,
char * cmnd ) ;
/*--------------------------------------------------------------------------
** Global Variables
*/
@ -540,6 +672,43 @@
static struct AsynSrv__info * AsynSrv_active [ MAX_OPEN ] ;
/*
**---------------------------------------------------------------------------
** AsynSrv_ChanClose: Send a "CLOSE CHAN" request to
** RS232C server.
*/
int AsynSrv_ChanClose (
/* =================
*/ 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_ChanClose " ) ;
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 ;
}
/*----------------------------------------------
** Send message and get reply.
*/
status = AsynSrv_SendSpecCmnd ( asyn_info , " -006 " ) ;
if ( AsynSrv_errcode = = 0 ) AsynSrv_call_depth - - ;
return status ;
}
/*
**---------------------------------------------------------------------------
** AsynSrv_Close: Close a connection to an RS-232-C server.
*/
int AsynSrv_Close (
@ -884,63 +1053,34 @@
return False ;
}
/*----------------------------------------------
** Set up message for server .
** Send message and get reply .
*/
strcpy ( cmnd , " -004 " ) ;
status = AsynSrv_SendSpecCmnd ( asyn_info , " -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 , " \n AsynSrv_Flush/send: probable network problem " ) ;
} else if ( status = = - 1 ) {
if ( AsynSrv_errno = = EPIPE ) {
AsynSrv_errcode = ASYNSRV__BAD_SEND_PIPE ; /* Server exited (probably) */
fprintf ( stderr , " \n AsynSrv_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 , " \n AsynSrv_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 , " \n AsynSrv_Flush/recv: probable network problem " ) ;
} else if ( status = = - 1 ) {
if ( AsynSrv_errno = = EPIPE ) {
AsynSrv_errcode = ASYNSRV__BAD_RECV_PIPE ; /* Server exited (probably) */
fprintf ( stderr , " \n AsynSrv_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 , " \n AsynSrv_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 , " \n AsynSrv_Flush/recv: command not echoed correctly "
" - link to server force-closed. \n " ) ;
return False ;
}
if ( AsynSrv_errcode = = 0 ) AsynSrv_call_depth - - ;
return status ;
}
/*
**---------------------------------------------------------------------------
** AsynSrv_GetLenTerm: Get length and terminator of given
** reply from reply buffer.
*/
int AsynSrv_GetLenTerm (
/* ==================
*/ struct AsynSrv__info * asyn_info ,
struct RS__RespStruct * rcve_buff ,
char * rply , /* In: Addr of a reply as got ..
** .. got from _GetReply */
int * len , /* Out: The returned length */
char * term ) { /* Out: The returned t'nator */
int i ;
i = sscanf ( ( rply - asyn_info - > rply_hdr_len - 1 ) , asyn_info - > rply_fmt , len ) ;
* len = ( i = = 1 ) ? ( * len - 2 ) : 0 ;
* term = * ( rply - 1 ) ;
if ( i ! = 1 ) return False ;
return True ;
}
/*
@ -1023,6 +1163,7 @@
** See if a table entry for this connection already exists.
*/
for ( i = 0 ; i < AsynSrv_n_cnct ; i + + ) {
if ( AsynSrv_HPS_list [ i ] . status ! = 0 ) continue ;
if ( AsynSrv_HPS_list [ i ] . port ! = asyn_info - > port ) continue ;
if ( strcmp ( AsynSrv_HPS_list [ i ] . host , asyn_info - > host ) = = 0 ) break ;
}
@ -1061,8 +1202,73 @@
return True ;
}
/*--------------------------------------------------------
** There is no existing connection. Is there room for
** a new connection entry?
** There is no existing connection. Open a new one.
*/
status = AsynSrv_OpenNew ( asyn_info ) ;
if ( ! status ) return False ;
/*--------------------------------------------------------
** Allow the entry to be shared (i.e. status = 0)
*/
AsynSrv_HPS_list [ AsynSrv_n_cnct - 1 ] . status = 0 ;
/*--------------------------------------------------------
*/
AsynSrv_errcode = AsynSrv_errno = AsynSrv_vaxc_errno = 0 ;
AsynSrv_call_depth = 0 ;
return True ;
}
/*
**---------------------------------------------------------------------------
** AsynSrv_OpenNew: Open a new connection to an RS-232-C Server.
*/
int AsynSrv_OpenNew (
/* ===============
*/ struct AsynSrv__info * asyn_info ) {
int i , status ;
int my_skt ;
char old_time_out [ 4 ] ;
union {
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 ;
if ( ( AsynSrv_call_depth = = 1 ) & &
( strcmp ( AsynSrv_routine [ 0 ] , " AsynSrv_Open " ) = = 0 ) ) {
strcpy ( AsynSrv_routine [ 1 ] , " AsynSrv_OpenNew " ) ;
AsynSrv_call_depth = 2 ;
} else {
strcpy ( AsynSrv_routine [ 0 ] , " AsynSrv_OpenNew " ) ;
AsynSrv_call_depth = 1 ;
}
/*--------------------------------------------------------
** Is there room for a new AsynSrv_Open table entry?
*/
if ( AsynSrv_n_active > = MAX_OPEN ) {
AsynSrv_errcode = ASYNSRV__NO_ROOM ; /* There isn't! */
return False ;
}
/*--------------------------------------------------------
** Is there room for a new connection entry?
*/
if ( AsynSrv_n_cnct > = AsynSrv_MAX_LINK ) {
AsynSrv_errcode = ASYNSRV__NO_ROOM ; /* There isn't! */
@ -1097,7 +1303,7 @@
if ( rmt_hostent = = NULL ) {
AsynSrv_errcode = ASYNSRV__BAD_HOST ;
GetErrno ( & AsynSrv_errno , & AsynSrv_vaxc_errno ) ; /* Save errno info */
fprintf ( stderr , " \n AsynSrv_Open/gethostbyname: Failed to get Internet "
fprintf ( stderr , " \n AsynSrv_OpenNew /gethostbyname: Failed to get Internet "
" address of \" %s \" . \n " , asyn_info - > host ) ;
return False ;
}
@ -1110,7 +1316,7 @@
if ( my_skt < = 0 ) {
AsynSrv_errcode = ASYNSRV__BAD_SOCKET ;
GetErrno ( & AsynSrv_errno , & AsynSrv_vaxc_errno ) ; /* Save the errno info */
fprintf ( stderr , " \n AsynSrv_Open/socket: Failed to create a socket. \n " ) ;
fprintf ( stderr , " \n AsynSrv_OpenNew /socket: Failed to create a socket. \n " ) ;
return False ;
}
lcl_sockname . sin_family = AF_INET ;
@ -1122,7 +1328,7 @@
close ( my_skt ) ;
AsynSrv_errcode = ASYNSRV__BAD_BIND ;
GetErrno ( & AsynSrv_errno , & AsynSrv_vaxc_errno ) ; /* Save the errno info */
fprintf ( stderr , " \n AsynSrv_Open/bind: Failed to bind socket. \n " ) ;
fprintf ( stderr , " \n AsynSrv_OpenNew /bind: Failed to bind socket. \n " ) ;
return False ;
}
/*---------------------------
@ -1153,8 +1359,8 @@
AsynSrv_errcode = ASYNSRV__BAD_CONNECT ;
GetErrno ( & AsynSrv_errno , & AsynSrv_vaxc_errno ) ; /* Save the errno info */
fprintf ( stderr ,
" \n AsynSrv_Open/connect: Failed to connect to server. \n " ) ;
perror ( " AsynSrv_Open " ) ;
" \n AsynSrv_OpenNew /connect: Failed to connect to server. \n " ) ;
perror ( " AsynSrv_OpenNew " ) ;
return False ;
}
/*---------------------------
@ -1222,7 +1428,7 @@
close ( my_skt ) ;
asyn_info - > skt = 0 ;
fprintf ( stderr ,
" \n AsynSrv_Open: Server protocol level is unrecognised. \n "
" \n AsynSrv_OpenNew : Server protocol level is unrecognised. \n "
" Server level is \" %4s \" \n " , r_buff . s_pcol_lvl ) ;
return False ;
}
@ -1231,7 +1437,7 @@
asyn_info - > skt = 0 ;
AsynSrv_errcode = ASYNSRV__BAD_PROT_LVL ;
fprintf ( stderr ,
" \n AsynSrv_Open: Problem getting protocol level of Server! \n " ) ;
" \n AsynSrv_OpenNew : Problem getting protocol level of Server! \n " ) ;
return False ;
}
/*---------------------------------------------------
@ -1244,6 +1450,7 @@
AsynSrv_HPS_list [ AsynSrv_n_cnct ] . cmnd_hdr_len = asyn_info - > cmnd_hdr_len ;
AsynSrv_HPS_list [ AsynSrv_n_cnct ] . rply_hdr_len = asyn_info - > rply_hdr_len ;
AsynSrv_HPS_list [ AsynSrv_n_cnct ] . usage_cnt = 1 ;
AsynSrv_HPS_list [ AsynSrv_n_cnct ] . status = 1 ;
AsynSrv_n_cnct + + ;
AsynSrv_active [ AsynSrv_n_active ] = /* Remember the open in case .. */
@ -1251,7 +1458,7 @@
AsynSrv_n_active + + ;
AsynSrv_errcode = AsynSrv_errno = AsynSrv_vaxc_errno = 0 ;
AsynSrv_call_depth = 0 ;
AsynSrv_call_depth - - ;
return True ;
}
/*
@ -1742,7 +1949,95 @@
}
/*
**---------------------------------------------------------------------------
** AsynSrv_Trace : Send a Trace command to RS232C server.
** AsynSrv_SendSpecCmnd : Send a "special" command to an
** RS232C server.
*/
int AsynSrv_SendSpecCmnd (
/* ====================
*/ struct AsynSrv__info * asyn_info ,
char * cmnd ) {
int status ;
char 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_SendSpecCmnd " ) ;
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 ;
}
/*----------------------------------------------
** Send the message to the server.
*/
status = send ( asyn_info - > skt , cmnd , 4 , 0 ) ;
if ( status ! = 4 ) {
GetErrno ( & AsynSrv_errno , & AsynSrv_vaxc_errno ) ;
if ( status = = 0 ) {
AsynSrv_errcode = ASYNSRV__BAD_SEND ; /* Server exited (probably) */
fprintf ( stderr , " \n AsynSrv_SendSpecCmnd/send: probable network problem " ) ;
} else if ( status = = - 1 ) {
if ( AsynSrv_errno = = EPIPE ) {
AsynSrv_errcode = ASYNSRV__BAD_SEND_PIPE ; /* Server exited (probably) */
fprintf ( stderr , " \n AsynSrv_SendSpecCmnd/send: broken network pipe " ) ;
} else {
AsynSrv_errcode = ASYNSRV__BAD_SEND_NET ; /* It's some other net problem */
perror ( " AsynSrv_SendSpecCmnd/send " ) ;
}
} else {
AsynSrv_errcode = ASYNSRV__BAD_SEND_UNKN ; /* TCP/IP problems */
fprintf ( stderr , " \n AsynSrv_SendSpecCmnd/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 , " \n AsynSrv_SendSpecCmnd/recv: probable network problem " ) ;
} else if ( status = = - 1 ) {
if ( AsynSrv_errno = = EPIPE ) {
AsynSrv_errcode = ASYNSRV__BAD_RECV_PIPE ; /* Server exited (probably) */
fprintf ( stderr , " \n AsynSrv_SendSpecCmnd/recv: broken network pipe " ) ;
} else {
AsynSrv_errcode = ASYNSRV__BAD_RECV_NET ; /* It's some other net problem */
perror ( " AsynSrv_SendSpecCmnd/recv " ) ;
}
} else {
AsynSrv_errcode = ASYNSRV__BAD_RECV_UNKN ; /* TCP/IP problems */
fprintf ( stderr , " \n AsynSrv_SendSpecCmnd/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 , " \n AsynSrv_SendSpecCmnd/recv: command not echoed correctly "
" - link to server force-closed. \n " ) ;
return False ;
}
if ( AsynSrv_errcode = = 0 ) AsynSrv_call_depth - - ;
return True ;
}
/*
**---------------------------------------------------------------------------
** AsynSrv_Trace: Send a "TRACE" request to RS232C server.
*/
int AsynSrv_Trace (
/* =============
@ -1777,265 +2072,49 @@
} else {
strcpy ( cmnd , " -003 " ) ;
}
/*----------------------------------------------
** Send message and get reply.
*/
status = AsynSrv_SendSpecCmnd ( asyn_info , cmnd ) ;
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 , " \n AsynSrv_Trace/send: probable network problem " ) ;
} else if ( status = = - 1 ) {
if ( AsynSrv_errno = = EPIPE ) {
AsynSrv_errcode = ASYNSRV__BAD_SEND_PIPE ; /* Server exited (probably) */
fprintf ( stderr , " \n AsynSrv_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 , " \n AsynSrv_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 , " \n AsynSrv_Trace/recv: probable network problem " ) ;
} else if ( status = = - 1 ) {
if ( AsynSrv_errno = = EPIPE ) {
AsynSrv_errcode = ASYNSRV__BAD_RECV_PIPE ; /* Server exited (probably) */
fprintf ( stderr , " \n AsynSrv_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 , " \n AsynSrv_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 , " \n AsynSrv_Trace/recv: command not echoed correctly "
" - link to server force-closed. \n " ) ;
return False ;
}
if ( AsynSrv_errcode = = 0 ) AsynSrv_call_depth - - ;
return True ;
return status ;
}
/*
**---------------------------------------------------------------------------
** AsynSrv_Forc e: Op en a connection to an RS-232-C Server.
** Thereby insisting on an own socket .
** AsynSrv_Trace_Writ e: S end a Trace_Write command to
** RS232C server .
*/
int AsynSrv_Forc e (
/* ============
int AsynSrv_Trace_Writ e (
/* ===================
*/ struct AsynSrv__info * asyn_info ) {
int i , status ;
int my_skt ;
char old_time_out [ 4 ] ;
union {
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 , " \n AsynSrv_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 , " \n AsynSrv_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 , " \n AsynSrv_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 ,
" \n AsynSrv_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.
int status ;
char cmnd [ 8 ] , rply [ 8 ] ;
/*----------------------------------------------
** Pre-set the routine name (in case of error)
*/
memcpy ( a syn_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 ) {
a syn_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 {
close ( my_skt ) ;
asyn_info - > skt = 0 ;
fprintf ( stderr ,
" \n AsynSrv_Open: Server protocol level is unrecognised. \n "
" Server level is \" %4s \" \n " , r_buff . s_pcol_lvl ) ;
return False ;
if ( A synSrv_errcode = = 0 & & AsynSrv_call_depth < 5 ) {
strcpy ( AsynSrv_routine [ AsynSrv_call_depth ] , " AsynSrv_Trace_Write " ) ;
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 ) ) {
A synSrv_errcode = ASYNSRV__FORCED_CLOSED ;
}
} else {
close ( my_skt ) ;
asyn_info - > skt = 0 ;
AsynSrv_errcode = ASYNSRV__BAD_PROT_LVL ;
fprintf ( stderr ,
" \n AsynSrv_Open: Problem getting protocol level of Server! \n " ) ;
return False ;
}
AsynSrv_errcode = AsynSrv_errno = AsynSrv_vaxc_errno = 0 ;
AsynSrv_call_depth = 0 ;
return True ;
}
/*----------------------------------------------
** Send message and get reply.
*/
status = AsynSrv_SendSpecCmnd ( asyn_info , " -005 " ) ;
if ( AsynSrv_errcode = = 0 ) AsynSrv_call_depth - - ;
return status ;
}
/*-------------------------------------------- End of AsynSrv_Utility.C -----*/