Readded AsynSrc_ForceClose
This commit is contained in:
@ -1833,4 +1833,209 @@
|
||||
if (AsynSrv_errcode == 0) AsynSrv_call_depth--;
|
||||
return True;
|
||||
}
|
||||
/*
|
||||
**---------------------------------------------------------------------------
|
||||
** AsynSrv_Force: Open a connection to an RS-232-C Server.
|
||||
** Thereby insisting on an own socket.
|
||||
*/
|
||||
int AsynSrv_Force (
|
||||
/* ============
|
||||
*/ 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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}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;
|
||||
}
|
||||
|
||||
/*-------------------------------------------- End of AsynSrv_Utility.C -----*/
|
||||
|
Reference in New Issue
Block a user