diff --git a/hardsup/Makefile b/hardsup/Makefile index a94ed51c..8123a698 100644 --- a/hardsup/Makefile +++ b/hardsup/Makefile @@ -4,9 +4,9 @@ # Mark Koennecke, November 1996 #-------------------------------------------------------------------------- OBJ= el734_utility.o asynsrv_utility.o stredit.o \ - strjoin.o geterrno.o el737_utility.o sinqhm.o serialsinq.o \ + strjoin.o failinet.o geterrno.o el737_utility.o sinqhm.o serialsinq.o \ itc4util.o dillutil.o table.o el755_utility.o el755_errorlog.o \ - makeprint.o + makeprint.o #---------- for Redhat linux CC= gcc diff --git a/hardsup/asynsrv_utility.c b/hardsup/asynsrv_utility.c index b8bae76f..b88f6793 100644 --- a/hardsup/asynsrv_utility.c +++ b/hardsup/asynsrv_utility.c @@ -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 ** +** 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 ): +** 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_Trace +** Same as AsynSrv_ChanClose ** 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-byte message "-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 the response. 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, "\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 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, "\nAsynSrv_Open/gethostbyname: Failed to get Internet " + fprintf (stderr, "\nAsynSrv_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, "\nAsynSrv_Open/socket: Failed to create a socket.\n"); + fprintf (stderr, "\nAsynSrv_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, "\nAsynSrv_Open/bind: Failed to bind socket.\n"); + fprintf (stderr, "\nAsynSrv_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, - "\nAsynSrv_Open/connect: Failed to connect to server.\n"); - perror ("AsynSrv_Open"); + "\nAsynSrv_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, - "\nAsynSrv_Open: Server protocol level is unrecognised.\n" + "\nAsynSrv_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, - "\nAsynSrv_Open: Problem getting protocol level of Server!\n"); + "\nAsynSrv_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, "\nAsynSrv_SendSpecCmnd/send: probable network problem"); + }else if (status == -1) { + if (AsynSrv_errno == EPIPE) { + AsynSrv_errcode = ASYNSRV__BAD_SEND_PIPE; /* Server exited (probably) */ + fprintf (stderr, "\nAsynSrv_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, "\nAsynSrv_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, "\nAsynSrv_SendSpecCmnd/recv: probable network problem"); + }else if (status == -1) { + if (AsynSrv_errno == EPIPE) { + AsynSrv_errcode = ASYNSRV__BAD_RECV_PIPE; /* Server exited (probably) */ + fprintf (stderr, "\nAsynSrv_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, "\nAsynSrv_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, "\nAsynSrv_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, "\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 status; } /* **--------------------------------------------------------------------------- -** AsynSrv_Force: Open a connection to an RS-232-C Server. -** Thereby insisting on an own socket. +** AsynSrv_Trace_Write: Send a Trace_Write command to +** RS232C server. */ - int AsynSrv_Force ( -/* ============ + int AsynSrv_Trace_Write ( +/* =================== */ 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, "\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. + int status; + char cmnd[8], rply[8]; + /*---------------------------------------------- + ** Pre-set the routine name (in case of error) */ - 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 { - 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; + if (AsynSrv_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)) { + AsynSrv_errcode = ASYNSRV__FORCED_CLOSED; } - }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; } - 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 -----*/ diff --git a/hardsup/rs232c_def.h b/hardsup/rs232c_def.h index 6b270d10..2753bd1b 100644 --- a/hardsup/rs232c_def.h +++ b/hardsup/rs232c_def.h @@ -1,14 +1,11 @@ #ifndef _rs232c_def_ #define _rs232c_def_ -/*------------------------------------------------ RS232C_DEF.H Ident V02F +/*------------------------------------------------ RS232C_DEF.H Ident V02G ** Definitions for the RS-232-C Server Protocol ** ** On UNIX systems, this file is located in /public/lib/include ** On VMS systems, this file is a module in mad_lib:sinq_c.tlb */ -#define RS__MAX_CLIENTS 3 -#define RS__MAX_ASYNCH 10 /* Asynch "ports" 0 - 9 will be allowed */ - #define RS__PROTOCOL_ID "V01A" #define RS__PROTOCOL_ID_V01B "V01B" @@ -37,6 +34,16 @@ ** cmnds 356 The command buffer. This is a concatenated list of ** commands with the structure described below. ** +** Special Cases of msg_size +** ------------------------- +** "-001" ==> the client is just about to close his connection. +** "-002" ==> this is a request to the server for him to turn on tracing. +** The reply should be simply an echo of the 4 bytes "-002". +** "-003" ==> this is a request to the server for him to turn off tracing. +** The reply should be simply an echo of the 4 bytes "-003". +** "-004" ==> this is a request to the server for him to flush his buffers. +** The reply should be simply an echo of the 4 bytes "-004". +** ** Structure of a command item in the cmnds buffer. ** ** a) RS__PROTOCOL_ID = "V01A" @@ -101,7 +108,7 @@ ** of 4). ** msg_id 4 Message ident (this is a copy of the msg_id field ** in the message from Client to Server). -** s_pcol_lvl 4 Server-Protocol-Level (should be "V01A"). +** s_pcol_lvl 4 Server-Protocol-Level (should be "V01A" or "V01B"). ** n_rply 4 Number of replies following. If < 0, an error has ** been detected and sub_status may give additional ** information. @@ -141,7 +148,7 @@ ** reply as received with the terminating character ** replaced by '\0'. ** -** An example of a reply item might be: "0008\r12.345\0" +** An example of a reply item might be: "0009\r12.3456\0" **--------------------------------------------------------------------------*/ struct RS__RespStruct { char msg_size[4]; diff --git a/hardsup/sinq_prototypes.h b/hardsup/sinq_prototypes.h index c0a4d33e..2be3165f 100644 --- a/hardsup/sinq_prototypes.h +++ b/hardsup/sinq_prototypes.h @@ -1,6 +1,6 @@ #ifndef _sinq_prototypes_loaded_ #define _sinq_prototypes_loaded_ -/*---------------------------------------------- SINQ_PROTOTYPES.H Ident V02E +/*---------------------------------------------- SINQ_PROTOTYPES.H Ident V02T ** ** Prototype header file for entry points in SINQ.OLB ** @@ -10,11 +10,17 @@ #ifdef VAXC #include asynsrv_def #include rs232c_def +#include el734_def +#include el737_def #else #include #include +#include +#include #endif /* ---------------------------------------------------------------------*/ + int AsynSrv_ChanClose ( + struct AsynSrv__info *asyn_info); int AsynSrv_Close ( struct AsynSrv__info *asyn_info, int force_flag); @@ -29,17 +35,39 @@ int *errcode, int *my_errno, int *vaxc_errno); + int AsynSrv_Flush ( + struct AsynSrv__info *asyn_info); + int AsynSrv_GetLenTerm ( + struct AsynSrv__info *asyn_info, + struct RS__RespStruct *rcve_buff, + char *rply, + int *len, + char *term); char *AsynSrv_GetReply ( struct AsynSrv__info *asyn_info, struct RS__RespStruct *rcve_buff, char *last_rply); int AsynSrv_Open ( struct AsynSrv__info *asyn_info); + int AsynSrv_OpenNew ( + struct AsynSrv__info *asyn_info); int AsynSrv_SendCmnds ( struct AsynSrv__info *asyn_info, struct RS__MsgStruct *send_buff, struct RS__RespStruct *rcve_buff, ...); + int AsynSrv_SendCmndsBig ( + struct AsynSrv__info *asyn_info, + struct RS__MsgStruct *send_buff, + int send_buff_size, + struct RS__RespStruct *rcve_buff, + int rcve_buff_size, + ...); + int AsynSrv_Trace ( + struct AsynSrv__info *asyn_info, + int state); + int AsynSrv_Trace_Write ( + struct AsynSrv__info *asyn_info); /* ---------------------------------------------------------------------*/ int C_log_arr_get ( char *name, @@ -107,6 +135,10 @@ int *errcode, int *my_errno, int *vaxc_errno); + int EL734_GetAirCush ( + void **handle, + int *present, + int *state); int EL734_GetEncGearing ( void **handle, int *nominator, @@ -138,6 +170,11 @@ int EL734_GetRefParam ( void **handle, float *param); + int EL734_GetSpeeds ( + void **handle, + int *lo, + int *hi, + int *ramp); int EL734_GetStatus ( void **handle, int *msr, @@ -166,16 +203,32 @@ int chan, int motor, char *id); - int EL734_SendCmnd ( - void **handle, - char *cmnd, - char *rply, - int rply_size); int EL734_PutOffline ( void **handle); int EL734_PutOnline ( void **handle, int echo); + int EL734_SendCmnd ( + void **handle, + char *cmnd, + char *rply, + int rply_size); + int EL734_SetAirCush ( + void **handle, + int state); + int EL734_SetErrcode ( + struct EL734info *info_ptr, + char *response, + char *cmnd); + int EL734_SetHighSpeed ( + void **handle, + int hi); + int EL734_SetLowSpeed ( + void **handle, + int lo); + int EL734_SetRamp ( + void **handle, + int ramp); int EL734_Stop ( void **handle); int EL734_WaitIdle ( @@ -196,6 +249,9 @@ int EL737_Continue ( void **handle, int *status); + int EL737_EnableThresh ( + void **handle, + int indx); void EL737_ErrInfo ( char **entry_txt, int *errcode, @@ -203,6 +259,7 @@ int *vaxc_errno); int EL737_GetMonIntegTime ( void **handle, + int indx, float *mon_integ_time); int EL737_GetRateIntegTime ( void **handle, @@ -224,6 +281,10 @@ int *c6, int *c7, int *c8); + int EL737_GetThresh ( + void **handle, + int *indx, + float *val); int EL737_Open ( void **handle, char *host, @@ -237,6 +298,14 @@ char *cmnd, char *rply, int rply_size); + int EL737_SetErrcode ( + struct EL737info *info_ptr, + char *response, + char *cmnd); + int EL737_SetThresh ( + void **handle, + int indx, + float val); int EL737_StartCnt ( void **handle, int preset_count, @@ -311,7 +380,7 @@ int EL755_PutOnline ( void **handle, int echo); - int EL755_SendTillSame ( + int EL755_SendTillSameStr ( void **handle, char *cmnd, char *rply, @@ -320,6 +389,11 @@ void **handle, char *cmnd, float *val); + int EL755_SendTillTwoVals ( + void **handle, + char *cmnd, + float *val0, + float *val1); int EL755_SetConstant ( void **handle, float value); @@ -338,6 +412,38 @@ int EL755_SetVoltageRange ( void **handle, float value); +/* ---------------------------------------------------------------------*/ + int Fluke_Close ( + void **handle, + int force_flag); + int Fluke_Config ( + void **handle, + ...); + void Fluke_ErrInfo ( + char **entry_txt, + int *errcode, + int *my_errno, + int *vaxc_errno); + int Fluke_ErrorLog ( + char *routine_name, + char *text); + int Fluke_Open ( + void **handle, + char *host, + int port, + int chan); + int Fluke_Read ( + void **handle, + float *ist); + int Fluke_SendTillSame ( + void **handle, + char *cmnd, + char *rply, + int rply_len); + int Fluke_SendTillSameVal ( + void **handle, + char *cmnd, + float *val); /* ---------------------------------------------------------------------*/ int ITC_Close ( void **handle, @@ -345,11 +451,27 @@ int ITC_Config ( void **handle, ...); + int ITC_Dump_RAM ( + void **handle, + int buff_size, + char *buff, + int *dump_len, + int *n_diffs); void ITC_ErrInfo ( char **entry_txt, int *errcode, int *my_errno, int *vaxc_errno); + int ITC_GetConfig ( + void **handle, + ...); + int ITC_Load_RAM ( + void **handle, + int load_len, + char *buff); + int ITC_Load_Table ( + void **handle, + char *buff); int ITC_Open ( void **handle, char *host, @@ -511,12 +633,17 @@ void GetErrno ( int *his_errno, int *his_vaxc_errno); + int MakeCharPrintable ( + char *out, + int out_size, + char in); char *MakePrint ( char *text); char *MakePrintable ( char *out, int out_size, char *in); + void *Map_to_ACS (); char *StrEdit ( char *out, char *in, @@ -527,17 +654,18 @@ int result_size, char *str_a, char *str_b); - + int StrMatch ( + char *str_a, + char *str_b, + int min_len); int Get_TASMAD_Info ( char *file_name, int *nItems, ...); - int Get_TASMAD_Info_Filename ( char *file_name, char *buf, int *bufSize); - int Update_TASMAD_Info ( char *file_name, int *nItems,