Readded AsynSrc_ForceClose
This commit is contained in:
@ -1833,4 +1833,209 @@
|
|||||||
if (AsynSrv_errcode == 0) AsynSrv_call_depth--;
|
if (AsynSrv_errcode == 0) AsynSrv_call_depth--;
|
||||||
return True;
|
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 -----*/
|
/*-------------------------------------------- End of AsynSrv_Utility.C -----*/
|
||||||
|
Reference in New Issue
Block a user