2008-09-21 19:30:35 +00:00
|
|
|
/*
|
|
|
|
* Hamlib Interface - network communication low-level support
|
2012-01-06 08:28:24 +00:00
|
|
|
* Copyright (c) 2000-2012 by Stephane Fillod
|
2008-09-21 19:30:35 +00:00
|
|
|
*
|
2011-08-22 01:07:57 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
2008-09-21 19:30:35 +00:00
|
|
|
*
|
2011-08-22 01:07:57 +00:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
2008-09-21 19:30:35 +00:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2011-08-22 01:07:57 +00:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2008-09-21 19:30:35 +00:00
|
|
|
*
|
2011-08-22 01:07:57 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2008-09-21 19:30:35 +00:00
|
|
|
* License along with this library; if not, write to the Free Software
|
2011-08-22 01:07:57 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2008-09-21 19:30:35 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \addtogroup rig_internal
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Network port IO
|
|
|
|
* \file network.c
|
|
|
|
*/
|
|
|
|
|
2008-11-02 12:42:45 +00:00
|
|
|
/* Forcing WINVER in MinGW yanks in getaddrinfo(), but locks out Win95/Win98 */
|
|
|
|
/* #define WINVER 0x0501 */
|
2008-09-21 19:30:35 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
2017-10-05 02:32:08 +00:00
|
|
|
# include "config.h"
|
2008-09-21 19:30:35 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h> /* Standard input/output definitions */
|
|
|
|
#include <string.h> /* String function definitions */
|
|
|
|
#include <unistd.h> /* UNIX standard function definitions */
|
|
|
|
#include <fcntl.h> /* File control definitions */
|
|
|
|
#include <errno.h> /* Error number definitions */
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/types.h>
|
2008-10-27 22:18:39 +00:00
|
|
|
#include <signal.h>
|
2008-09-21 19:30:35 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
2017-10-05 02:32:08 +00:00
|
|
|
# include <netinet/in.h>
|
2008-11-02 12:42:45 +00:00
|
|
|
#endif
|
2017-10-05 02:32:08 +00:00
|
|
|
|
2008-11-02 12:42:45 +00:00
|
|
|
#if HAVE_NETDB_H
|
2017-10-05 02:32:08 +00:00
|
|
|
# include <netdb.h>
|
2008-09-21 19:30:35 +00:00
|
|
|
#endif
|
2017-10-05 02:32:08 +00:00
|
|
|
|
2008-09-21 19:30:35 +00:00
|
|
|
#ifdef HAVE_ARPA_INET_H
|
2017-10-05 02:32:08 +00:00
|
|
|
# include <arpa/inet.h>
|
2008-09-21 19:30:35 +00:00
|
|
|
#endif
|
2017-10-05 02:32:08 +00:00
|
|
|
|
2017-01-26 14:28:14 +00:00
|
|
|
#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_SYS_IOCTL_H)
|
2017-10-05 02:32:08 +00:00
|
|
|
# include <sys/socket.h>
|
|
|
|
# include <sys/ioctl.h>
|
2008-09-21 19:30:35 +00:00
|
|
|
#elif HAVE_WS2TCPIP_H
|
2020-06-22 04:51:02 +00:00
|
|
|
#undef _WIN32_WINNT
|
|
|
|
// We need inet_pton to get defined and 0x0600 does it
|
2020-06-22 05:00:33 +00:00
|
|
|
// Eventually we should be able to get rid of this hack
|
2020-06-22 04:51:02 +00:00
|
|
|
#define _WIN32_WINNT 0x0600
|
2017-10-05 02:32:08 +00:00
|
|
|
# include <ws2tcpip.h>
|
2020-06-22 04:51:02 +00:00
|
|
|
#undef _WIN32_WINNT
|
|
|
|
// Then we'll go back to Server 2003
|
|
|
|
#define _WIN32_WINNT 0x0502
|
2017-10-05 02:32:08 +00:00
|
|
|
# if defined(HAVE_WSPIAPI_H)
|
|
|
|
# include <wspiapi.h>
|
|
|
|
# endif
|
2008-09-21 19:30:35 +00:00
|
|
|
#endif
|
|
|
|
|
2017-08-05 14:09:12 +00:00
|
|
|
#include <hamlib/rig.h>
|
2008-09-21 19:30:35 +00:00
|
|
|
#include "network.h"
|
|
|
|
#include "misc.h"
|
|
|
|
|
2008-11-02 12:42:45 +00:00
|
|
|
|
2008-11-05 23:02:00 +00:00
|
|
|
#ifdef __MINGW32__
|
|
|
|
static int wsstarted;
|
|
|
|
#endif
|
|
|
|
|
2020-04-09 22:56:19 +00:00
|
|
|
//! @cond Doxygen_Suppress
|
2020-04-22 17:26:08 +00:00
|
|
|
#define NET_BUFFER_SIZE 8192
|
2020-04-09 22:56:19 +00:00
|
|
|
//! @endcond
|
2017-01-24 04:21:49 +00:00
|
|
|
|
2017-08-05 14:09:12 +00:00
|
|
|
static void handle_error(enum rig_debug_level_e lvl, const char *msg)
|
2015-11-27 12:59:21 +00:00
|
|
|
{
|
2017-08-05 14:09:12 +00:00
|
|
|
int e;
|
2015-11-27 12:59:21 +00:00
|
|
|
#ifdef __MINGW32__
|
2017-08-05 14:09:12 +00:00
|
|
|
LPVOID lpMsgBuf;
|
|
|
|
|
|
|
|
lpMsgBuf = (LPVOID)"Unknown error";
|
|
|
|
e = WSAGetLastError();
|
|
|
|
|
|
|
|
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
|
|
|
| FORMAT_MESSAGE_FROM_SYSTEM
|
|
|
|
| FORMAT_MESSAGE_IGNORE_INSERTS,
|
2017-10-05 02:32:08 +00:00
|
|
|
NULL,
|
|
|
|
e,
|
2017-08-05 14:09:12 +00:00
|
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
|
|
// Default language
|
|
|
|
(LPTSTR)&lpMsgBuf,
|
|
|
|
0,
|
2017-10-05 02:32:08 +00:00
|
|
|
NULL))
|
|
|
|
{
|
2020-02-23 17:26:09 +00:00
|
|
|
rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, (char *)lpMsgBuf);
|
2017-08-05 14:09:12 +00:00
|
|
|
LocalFree(lpMsgBuf);
|
2017-10-05 02:32:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-08-05 14:09:12 +00:00
|
|
|
rig_debug(lvl, "%s: Network error %d\n", msg, e);
|
|
|
|
}
|
|
|
|
|
2015-11-27 12:59:21 +00:00
|
|
|
#else
|
2017-08-05 14:09:12 +00:00
|
|
|
e = errno;
|
|
|
|
rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e));
|
2015-11-27 12:59:21 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2008-09-21 19:30:35 +00:00
|
|
|
/**
|
|
|
|
* \brief Open network port using rig.state data
|
2008-10-27 22:18:39 +00:00
|
|
|
*
|
|
|
|
* Open Open network port using rig.state data.
|
2011-02-03 02:52:17 +00:00
|
|
|
* NB: The signal PIPE will be ignored for the whole application.
|
2008-10-27 22:18:39 +00:00
|
|
|
*
|
2011-02-03 02:52:17 +00:00
|
|
|
* \param rp Port data structure (must spec port id eg hostname:port)
|
|
|
|
* \param default_port Default network socket port
|
2008-09-21 19:30:35 +00:00
|
|
|
* \return RIG_OK or < 0 if error
|
|
|
|
*/
|
2008-10-31 07:51:46 +00:00
|
|
|
int network_open(hamlib_port_t *rp, int default_port)
|
|
|
|
{
|
2017-08-05 14:09:12 +00:00
|
|
|
int fd; /* File descriptor for the port */
|
|
|
|
int status;
|
|
|
|
struct addrinfo hints, *res, *saved_res;
|
2020-06-21 22:47:04 +00:00
|
|
|
struct in6_addr serveraddr;
|
2020-06-22 03:31:31 +00:00
|
|
|
char hoststr[256], portstr[6] = "";
|
2017-08-05 14:09:12 +00:00
|
|
|
|
2021-01-17 14:19:12 +00:00
|
|
|
ENTERFUNC;
|
2008-09-21 19:30:35 +00:00
|
|
|
|
2008-11-05 23:02:00 +00:00
|
|
|
#ifdef __MINGW32__
|
2017-08-05 14:09:12 +00:00
|
|
|
WSADATA wsadata;
|
2021-04-25 13:33:14 +00:00
|
|
|
int ret;
|
2017-08-05 14:09:12 +00:00
|
|
|
|
2021-04-25 13:33:14 +00:00
|
|
|
if (wsstarted == 0)
|
2017-10-05 02:32:08 +00:00
|
|
|
{
|
2021-04-25 13:33:14 +00:00
|
|
|
ret = WSAStartup(MAKEWORD(1, 1), &wsadata);
|
|
|
|
|
|
|
|
if (ret == 0)
|
|
|
|
{
|
|
|
|
wsstarted = 1;
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: WSAStartup OK\n", __func__);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rig_debug(RIG_DEBUG_ERR, "%s: error creating socket, WSAStartup ret=%d\n",
|
|
|
|
__func__, ret);
|
|
|
|
RETURNFUNC(-RIG_EIO);
|
|
|
|
}
|
2017-08-05 14:09:12 +00:00
|
|
|
}
|
|
|
|
|
2008-11-05 23:02:00 +00:00
|
|
|
#endif
|
|
|
|
|
2017-10-05 02:32:08 +00:00
|
|
|
if (!rp)
|
|
|
|
{
|
2021-03-07 17:42:01 +00:00
|
|
|
RETURNFUNC(-RIG_EINVAL);
|
2017-08-05 14:09:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
memset(&hints, 0, sizeof(hints));
|
2020-06-22 04:23:55 +00:00
|
|
|
hints.ai_flags = NI_NUMERICSERV;
|
2020-06-21 22:47:04 +00:00
|
|
|
hints.ai_family = AF_UNSPEC;
|
2017-08-05 14:09:12 +00:00
|
|
|
|
2017-10-05 02:32:08 +00:00
|
|
|
if (rp->type.rig == RIG_PORT_UDP_NETWORK)
|
|
|
|
{
|
2017-08-05 14:09:12 +00:00
|
|
|
hints.ai_socktype = SOCK_DGRAM;
|
2017-10-05 02:32:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-08-05 14:09:12 +00:00
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
|
|
}
|
|
|
|
|
2020-06-21 22:47:04 +00:00
|
|
|
if (rp->pathname[0] == ':' && rp->pathname[1] != ':')
|
2017-10-05 02:32:08 +00:00
|
|
|
{
|
2020-06-21 22:47:04 +00:00
|
|
|
snprintf(portstr, sizeof(portstr) - 1, "%s", rp->pathname + 1);
|
2017-10-05 02:32:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (strlen(rp->pathname))
|
|
|
|
{
|
2020-06-21 22:47:04 +00:00
|
|
|
status = parse_hoststr(rp->pathname, hoststr, portstr);
|
|
|
|
|
2021-03-07 17:42:01 +00:00
|
|
|
if (status != RIG_OK) { RETURNFUNC(status); }
|
2020-06-21 22:47:04 +00:00
|
|
|
|
2021-01-17 14:19:12 +00:00
|
|
|
rig_debug(RIG_DEBUG_TRACE, "%s: hoststr=%s, portstr=%s\n", __func__, hoststr,
|
2020-06-21 22:47:04 +00:00
|
|
|
portstr);
|
|
|
|
|
2017-08-05 14:09:12 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 22:47:04 +00:00
|
|
|
if (strlen(portstr) == 0)
|
|
|
|
{
|
|
|
|
sprintf(portstr, "%d", default_port);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
status = inet_pton(AF_INET, hoststr, &serveraddr);
|
|
|
|
|
|
|
|
if (status == 1) /* valid IPv4 address */
|
|
|
|
{
|
|
|
|
hints.ai_family = AF_INET;
|
|
|
|
hints.ai_flags |= AI_NUMERICHOST;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
status = inet_pton(AF_INET6, hoststr, &serveraddr);
|
|
|
|
|
2020-06-23 04:46:27 +00:00
|
|
|
if (status == 1) /* valid IPv6 address */
|
2017-10-05 02:32:08 +00:00
|
|
|
{
|
2020-06-21 22:47:04 +00:00
|
|
|
hints.ai_family = AF_INET6;
|
|
|
|
hints.ai_flags |= AI_NUMERICHOST;
|
2017-08-05 14:09:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
status = getaddrinfo(hoststr, portstr, &hints, &res);
|
|
|
|
|
2020-06-21 22:47:04 +00:00
|
|
|
if (status == 0 && res->ai_family == AF_INET6)
|
|
|
|
{
|
2021-02-05 05:47:59 +00:00
|
|
|
rig_debug(RIG_DEBUG_TRACE, "%s: Using IPV6\n", __func__);
|
2020-06-21 22:47:04 +00:00
|
|
|
//inet_pton(AF_INET6, hoststr, &h_addr.sin6_addr);
|
|
|
|
}
|
|
|
|
|
2017-10-05 02:32:08 +00:00
|
|
|
if (status != 0)
|
|
|
|
{
|
2017-08-05 14:09:12 +00:00
|
|
|
rig_debug(RIG_DEBUG_ERR,
|
|
|
|
"%s: cannot get host \"%s\": %s\n",
|
|
|
|
__func__,
|
|
|
|
rp->pathname,
|
2021-03-07 17:50:13 +00:00
|
|
|
gai_strerror(status));
|
2021-03-07 17:42:01 +00:00
|
|
|
RETURNFUNC(-RIG_ECONF);
|
2017-08-05 14:09:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
saved_res = res;
|
|
|
|
|
|
|
|
/* we don't want a signal when connection get broken */
|
2008-10-27 22:18:39 +00:00
|
|
|
#ifdef SIGPIPE
|
2017-08-05 14:09:12 +00:00
|
|
|
signal(SIGPIPE, SIG_IGN);
|
2008-10-27 22:18:39 +00:00
|
|
|
#endif
|
|
|
|
|
2017-10-05 02:32:08 +00:00
|
|
|
do
|
|
|
|
{
|
2019-12-09 23:12:13 +00:00
|
|
|
char msg[1024];
|
2017-08-05 14:09:12 +00:00
|
|
|
fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
|
|
|
|
2017-10-05 02:32:08 +00:00
|
|
|
if (fd < 0)
|
|
|
|
{
|
2017-08-05 14:09:12 +00:00
|
|
|
handle_error(RIG_DEBUG_ERR, "socket");
|
|
|
|
freeaddrinfo(saved_res);
|
2021-03-07 17:42:01 +00:00
|
|
|
RETURNFUNC(-RIG_EIO);
|
2017-08-05 14:09:12 +00:00
|
|
|
}
|
|
|
|
|
2020-01-15 05:36:01 +00:00
|
|
|
if (connect(fd, res->ai_addr, res->ai_addrlen) == 0)
|
2017-10-05 02:32:08 +00:00
|
|
|
{
|
2017-08-05 14:09:12 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-02-07 17:46:52 +00:00
|
|
|
|
|
|
|
snprintf(msg, sizeof(msg), "connect to %s failed, (trying next interface)",
|
|
|
|
rp->pathname);
|
2018-04-14 15:46:13 +00:00
|
|
|
handle_error(RIG_DEBUG_WARN, msg);
|
2008-09-21 19:30:35 +00:00
|
|
|
|
2015-11-27 12:59:21 +00:00
|
|
|
#ifdef __MINGW32__
|
2017-08-05 14:09:12 +00:00
|
|
|
closesocket(fd);
|
2015-11-27 12:59:21 +00:00
|
|
|
#else
|
2017-08-05 14:09:12 +00:00
|
|
|
close(fd);
|
2015-11-27 12:59:21 +00:00
|
|
|
#endif
|
2017-10-05 02:32:08 +00:00
|
|
|
}
|
|
|
|
while ((res = res->ai_next) != NULL);
|
2015-11-27 12:59:21 +00:00
|
|
|
|
2017-08-05 14:09:12 +00:00
|
|
|
freeaddrinfo(saved_res);
|
|
|
|
|
2017-10-05 02:32:08 +00:00
|
|
|
if (NULL == res)
|
|
|
|
{
|
2017-08-05 14:09:12 +00:00
|
|
|
rig_debug(RIG_DEBUG_ERR,
|
|
|
|
"%s: failed to connect to %s\n",
|
|
|
|
__func__,
|
|
|
|
rp->pathname);
|
2021-03-07 17:42:01 +00:00
|
|
|
RETURNFUNC(-RIG_EIO);
|
2017-08-05 14:09:12 +00:00
|
|
|
}
|
2015-11-27 12:59:21 +00:00
|
|
|
|
2017-08-05 14:09:12 +00:00
|
|
|
rp->fd = fd;
|
2008-09-21 19:30:35 +00:00
|
|
|
|
2021-03-07 17:42:01 +00:00
|
|
|
RETURNFUNC(RIG_OK);
|
2008-09-21 19:30:35 +00:00
|
|
|
}
|
|
|
|
|
2017-08-05 14:09:12 +00:00
|
|
|
|
2017-01-26 14:28:14 +00:00
|
|
|
/**
|
|
|
|
* \brief Clears any data in the read buffer of the socket
|
|
|
|
*
|
|
|
|
* \param rp Port data structure
|
|
|
|
*/
|
2017-08-05 14:09:12 +00:00
|
|
|
void network_flush(hamlib_port_t *rp)
|
2017-01-26 14:28:14 +00:00
|
|
|
{
|
|
|
|
#ifdef __MINGW32__
|
2020-01-15 05:36:01 +00:00
|
|
|
ULONG len;
|
2017-01-26 14:28:14 +00:00
|
|
|
#else
|
2020-01-15 05:36:01 +00:00
|
|
|
uint len;
|
2017-01-26 14:28:14 +00:00
|
|
|
#endif
|
|
|
|
|
2017-08-05 14:09:12 +00:00
|
|
|
char buffer[NET_BUFFER_SIZE] = { 0 };
|
|
|
|
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
|
|
|
|
2017-10-05 02:32:08 +00:00
|
|
|
for (;;)
|
|
|
|
{
|
2019-12-08 23:09:08 +00:00
|
|
|
int ret;
|
2019-02-05 15:40:46 +00:00
|
|
|
len = 0;
|
2017-01-26 14:28:14 +00:00
|
|
|
#ifdef __MINGW32__
|
2019-02-05 15:40:46 +00:00
|
|
|
ret = ioctlsocket(rp->fd, FIONREAD, &len);
|
2017-01-26 14:28:14 +00:00
|
|
|
#else
|
2019-02-05 15:40:46 +00:00
|
|
|
ret = ioctl(rp->fd, FIONREAD, &len);
|
2017-01-26 14:28:14 +00:00
|
|
|
#endif
|
2019-02-07 17:46:52 +00:00
|
|
|
|
|
|
|
if (ret != 0)
|
|
|
|
{
|
2019-11-30 16:16:28 +00:00
|
|
|
rig_debug(RIG_DEBUG_ERR, "%s: ioctl err '%s'\n", __func__, strerror(errno));
|
2019-02-07 17:46:52 +00:00
|
|
|
break;
|
2019-02-05 15:40:46 +00:00
|
|
|
}
|
2019-02-07 17:46:52 +00:00
|
|
|
|
2017-10-05 02:32:08 +00:00
|
|
|
if (len > 0)
|
|
|
|
{
|
2019-02-07 17:44:33 +00:00
|
|
|
int len_read = 0;
|
2017-08-05 14:09:12 +00:00
|
|
|
rig_debug(RIG_DEBUG_WARN,
|
2019-11-30 16:04:31 +00:00
|
|
|
"%s: network data clear d: ret=%d, len=%d, '%s'\n",
|
2017-08-05 14:09:12 +00:00
|
|
|
__func__,
|
2019-11-30 19:05:21 +00:00
|
|
|
ret, (int)len, buffer);
|
2019-02-07 17:46:52 +00:00
|
|
|
len_read = recv(rp->fd, buffer, len < NET_BUFFER_SIZE ? len : NET_BUFFER_SIZE,
|
|
|
|
0);
|
|
|
|
|
|
|
|
if (len_read < 0) // -1 indicates error occurred
|
|
|
|
{
|
|
|
|
rig_debug(RIG_DEBUG_ERR, "%s: read error '%s'\n", __func__, strerror(errno));
|
2019-02-07 17:44:33 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-02-07 17:46:52 +00:00
|
|
|
|
2019-02-07 17:44:33 +00:00
|
|
|
rig_debug(RIG_DEBUG_WARN,
|
|
|
|
"%s: network data cleared: ret=%d, len_read=%d/0x%x, '%s'\n",
|
|
|
|
__func__,
|
|
|
|
ret, len_read, len_read, buffer);
|
2017-10-05 02:32:08 +00:00
|
|
|
}
|
2019-11-30 16:19:08 +00:00
|
|
|
else
|
|
|
|
{
|
2019-08-01 04:13:35 +00:00
|
|
|
break;
|
|
|
|
}
|
2017-01-26 14:28:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-05 14:09:12 +00:00
|
|
|
|
2020-04-09 22:56:19 +00:00
|
|
|
//! @cond Doxygen_Suppress
|
2008-11-05 23:02:00 +00:00
|
|
|
int network_close(hamlib_port_t *rp)
|
|
|
|
{
|
2021-04-25 13:33:14 +00:00
|
|
|
int ret = 0;
|
2017-08-05 14:09:12 +00:00
|
|
|
|
2021-03-07 17:42:01 +00:00
|
|
|
ENTERFUNC;
|
2017-08-05 14:09:12 +00:00
|
|
|
|
2021-04-25 13:33:14 +00:00
|
|
|
if (rp->fd > 0)
|
|
|
|
{
|
|
|
|
#ifdef __MINGW32__
|
|
|
|
ret = closesocket(rp->fd);
|
|
|
|
#else
|
|
|
|
ret = close(rp->fd);
|
|
|
|
#endif
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: close socket ret=%d\n", __func__, ret);
|
|
|
|
rp->fd = 0;
|
|
|
|
}
|
|
|
|
|
2008-11-05 23:02:00 +00:00
|
|
|
#ifdef __MINGW32__
|
2017-08-05 14:09:12 +00:00
|
|
|
|
2021-04-25 13:33:14 +00:00
|
|
|
if (wsstarted)
|
2017-10-05 02:32:08 +00:00
|
|
|
{
|
2021-04-25 13:33:14 +00:00
|
|
|
ret = WSACleanup();
|
|
|
|
rig_debug(RIG_DEBUG_VERBOSE, "%s: WSACleanup ret=%d\n", __func__, ret);
|
|
|
|
wsstarted = 0;
|
2017-08-05 14:09:12 +00:00
|
|
|
}
|
|
|
|
|
2008-11-05 23:02:00 +00:00
|
|
|
#endif
|
2021-03-07 17:42:01 +00:00
|
|
|
RETURNFUNC(ret);
|
2008-11-05 23:02:00 +00:00
|
|
|
}
|
2020-04-09 22:56:19 +00:00
|
|
|
//! @endcond
|
2008-11-05 23:02:00 +00:00
|
|
|
|
2008-09-21 19:30:35 +00:00
|
|
|
/** @} */
|