Fix mingw build for multicast.c

https://github.com/Hamlib/Hamlib/issues/695
pull/1289/head
Mike Black W9MDB 2023-05-09 07:00:03 -05:00
rodzic 1d96a84b44
commit 7835329e32
1 zmienionych plików z 166 dodań i 173 usunięć

Wyświetl plik

@ -327,198 +327,191 @@ void *multicast_thread(void *vrig)
#ifdef WIN32
static char *GetWinsockLastError(char *errorBuffer, DWORD errorBufferSize)
{
void GetWinsockErrorString(char *errorBuffer, DWORD errorBufferSize)
{
int errorCode = WSAGetLastError();
DWORD charsWritten;
int errorCode = WSAGetLastError();
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
errorBuffer,
errorBufferSize,
NULL
);
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
errorBuffer,
errorBufferSize,
NULL
);
return errorBuffer;
}
#endif
int multicast_init(RIG *rig, char *addr, int port)
{
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
char errorMessage[1024];
fprintf(stderr, "WSAStartup failed: %s\n", GetWinsockLastError(errorMessage,
sizeof(errorMessage)));
return 1;
}
#endif
int multicast_init(RIG * rig, char *addr, int port)
if (rig->state.multicast == NULL)
{
rig->state.multicast = calloc(1, sizeof(struct multicast_s));
}
else if (rig->state.multicast->multicast_running) { return RIG_OK; } // we only need one port
//rig->state.multicast->mreq = {0};
if (addr == NULL) { addr = RIG_MULTICAST_ADDR; }
if (port == 0) { port = RIG_MULTICAST_PORT; }
// Create a UDP socket
rig->state.multicast->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (rig->state.multicast->sock < 0)
{
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
char errorMessage[1024];
fprintf(stderr, "WSAStartup failed: %s\n", GetWinsockLastError(errorMessage,
sizeof(errorMessage)));
return 1;
}
#endif
if (rig->state.multicast == NULL)
{
rig->state.multicast = calloc(1, sizeof(struct multicast_s));
}
else if (rig->state.multicast->multicast_running) { return RIG_OK; } // we only need one port
//rig->state.multicast->mreq = {0};
if (addr == NULL) { addr = RIG_MULTICAST_ADDR; }
if (port == 0) { port = RIG_MULTICAST_PORT; }
// Create a UDP socket
rig->state.multicast->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (rig->state.multicast->sock < 0)
{
#ifdef _WIN32
int err = WSAGetLastError();
rig_debug(RIG_DEBUG_ERR, "%s: socket: WSAGetLastError=%d\n", __func__, err);
int err = WSAGetLastError();
rig_debug(RIG_DEBUG_ERR, "%s: socket: WSAGetLastError=%d\n", __func__, err);
#else
rig_debug(RIG_DEBUG_ERR, "%s: socket: %s\n", __func__, strerror(errno));
rig_debug(RIG_DEBUG_ERR, "%s: socket: %s\n", __func__, strerror(errno));
#endif
return -RIG_EIO;
}
// Set the SO_REUSEADDR option to allow multiple processes to use the same address
int optval = 1;
if (setsockopt(rig->state.multicast->sock, SOL_SOCKET, SO_REUSEADDR,
(char *)&optval,
sizeof(optval)) < 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
return -RIG_EIO;
}
// Bind the socket to any available local address and the specified port
struct sockaddr_in saddr = {0};
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(port);
if (bind(rig->state.multicast->sock, (struct sockaddr *)&saddr,
sizeof(saddr)) < 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: bind: %s\n", __func__, strerror(errno));
return -RIG_EIO;
}
// Construct the multicast group address
// struct ip_mreq mreq = {0};
rig->state.multicast->mreq.imr_multiaddr.s_addr = inet_addr(addr);
rig->state.multicast->mreq.imr_interface.s_addr = htonl(INADDR_ANY);
// Set the multicast TTL (time-to-live) to limit the scope of the packets
char ttl = 1;
if (setsockopt(rig->state.multicast->sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
sizeof(ttl)) < 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
return -RIG_EIO;
}
// Join the multicast group
if (setsockopt(rig->state.multicast->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char *)&rig->state.multicast->mreq, sizeof(rig->state.multicast->mreq)) < 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
return -RIG_EIO;
}
// prime the dest_addr for the send routine
rig->state.multicast->dest_addr.sin_family = AF_INET;
rig->state.multicast->dest_addr.sin_addr.s_addr = inet_addr(addr);
rig->state.multicast->dest_addr.sin_port = htons(port);
printf("starting thread\n");
rig->state.multicast->runflag = 1;
pthread_create(&rig->state.multicast->threadid, NULL, multicast_thread,
(void *)rig);
//printf("threadid=%ld\n", rig->state.multicast->threadid);
rig->state.multicast->multicast_running = 1;
return RIG_OK;
return -RIG_EIO;
}
void multicast_close(RIG * rig)
// Set the SO_REUSEADDR option to allow multiple processes to use the same address
int optval = 1;
if (setsockopt(rig->state.multicast->sock, SOL_SOCKET, SO_REUSEADDR,
(char *)&optval,
sizeof(optval)) < 0)
{
int retval;
// Leave the multicast group
if ((retval = setsockopt(rig->state.multicast->sock, IPPROTO_IP,
IP_DROP_MEMBERSHIP, (char *)&rig->state.multicast->mreq,
sizeof(rig->state.multicast->mreq))) < 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
return;
}
// Close the socket
if ((retval = close(rig->state.multicast->sock)))
{
rig_debug(RIG_DEBUG_ERR, "%s: close: %s\n", __func__, strerror(errno));
}
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
return -RIG_EIO;
}
// Bind the socket to any available local address and the specified port
struct sockaddr_in saddr = {0};
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(port);
if (bind(rig->state.multicast->sock, (struct sockaddr *)&saddr,
sizeof(saddr)) < 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: bind: %s\n", __func__, strerror(errno));
return -RIG_EIO;
}
// Construct the multicast group address
// struct ip_mreq mreq = {0};
rig->state.multicast->mreq.imr_multiaddr.s_addr = inet_addr(addr);
rig->state.multicast->mreq.imr_interface.s_addr = htonl(INADDR_ANY);
// Set the multicast TTL (time-to-live) to limit the scope of the packets
char ttl = 1;
if (setsockopt(rig->state.multicast->sock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
sizeof(ttl)) < 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
return -RIG_EIO;
}
// Join the multicast group
if (setsockopt(rig->state.multicast->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char *)&rig->state.multicast->mreq, sizeof(rig->state.multicast->mreq)) < 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
return -RIG_EIO;
}
// prime the dest_addr for the send routine
rig->state.multicast->dest_addr.sin_family = AF_INET;
rig->state.multicast->dest_addr.sin_addr.s_addr = inet_addr(addr);
rig->state.multicast->dest_addr.sin_port = htons(port);
printf("starting thread\n");
rig->state.multicast->runflag = 1;
pthread_create(&rig->state.multicast->threadid, NULL, multicast_thread,
(void *)rig);
//printf("threadid=%ld\n", rig->state.multicast->threadid);
rig->state.multicast->multicast_running = 1;
return RIG_OK;
}
void multicast_close(RIG *rig)
{
int retval;
// Leave the multicast group
if ((retval = setsockopt(rig->state.multicast->sock, IPPROTO_IP,
IP_DROP_MEMBERSHIP, (char *)&rig->state.multicast->mreq,
sizeof(rig->state.multicast->mreq))) < 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: setsockopt: %s\n", __func__, strerror(errno));
return;
}
// Close the socket
if ((retval = close(rig->state.multicast->sock)))
{
rig_debug(RIG_DEBUG_ERR, "%s: close: %s\n", __func__, strerror(errno));
}
}
// if msglen=0 msg is assumed to be a string
int multicast_send(RIG * rig, const char *msg, int msglen)
int multicast_send(RIG *rig, const char *msg, int msglen)
{
// Construct the message to send
if (msglen == 0) { msglen = strlen((char *)msg); }
// Send the message to the multicast group
ssize_t num_bytes = sendto(rig->state.multicast->sock, msg, msglen, 0,
(struct sockaddr *)&rig->state.multicast->dest_addr,
sizeof(rig->state.multicast->dest_addr));
if (num_bytes < 0)
{
// Construct the message to send
if (msglen == 0) { msglen = strlen((char *)msg); }
// Send the message to the multicast group
ssize_t num_bytes = sendto(rig->state.multicast->sock, msg, msglen, 0,
(struct sockaddr *)&rig->state.multicast->dest_addr,
sizeof(rig->state.multicast->dest_addr));
if (num_bytes < 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: sendto: %s\n", __func__, strerror(errno));
return -RIG_EIO;
}
else
{
// printf("Sent %zd bytes to multicast group %s:%d\n", num_bytes, MULTICAST_ADDR,
// PORT);
}
return num_bytes;
rig_debug(RIG_DEBUG_ERR, "%s: sendto: %s\n", __func__, strerror(errno));
return -RIG_EIO;
}
return num_bytes;
}
//#define TEST
#ifdef TEST
int main(int argc, char *argv[])
int main(int argc, char *argv[])
{
RIG *rig;
rig_model_t myrig_model;
rig_set_debug_level(RIG_DEBUG_NONE);
if (argc > 1) { myrig_model = atoi(argv[1]); }
else
{
RIG *rig;
rig_model_t myrig_model;
rig_set_debug_level(RIG_DEBUG_NONE);
if (argc > 1) { myrig_model = atoi(argv[1]); }
else
{
myrig_model = 1035;
}
rig = rig_init(myrig_model);
if (rig == NULL)
{
}
strncpy(rig->state.rigport.pathname, "/dev/ttyUSB0", HAMLIB_FILPATHLEN - 1);
rig->state.rigport.parm.serial.rate = 38400;
rig_open(rig);
multicast_init(rig, "224.0.0.1", 4532);
pthread_join(rig->state.multicast->threadid, NULL);
pthread_exit(NULL);
return 0;
myrig_model = 1035;
}
rig = rig_init(myrig_model);
if (rig == NULL)
{
}
strncpy(rig->state.rigport.pathname, "/dev/ttyUSB0", HAMLIB_FILPATHLEN - 1);
rig->state.rigport.parm.serial.rate = 38400;
rig_open(rig);
multicast_init(rig, "224.0.0.1", 4532);
pthread_join(rig->state.multicast->threadid, NULL);
pthread_exit(NULL);
return 0;
}
#endif