Add wireless detection for multicast address -- possible fix for UDP error messages by using 127.0.0.1 instead of IN_ADDR_ANY

https://github.com/Hamlib/Hamlib/issues/1409
pull/1432/head
Mike Black W9MDB 2023-11-16 09:05:29 -06:00
rodzic cb34dc3b20
commit c1780b19f4
5 zmienionych plików z 126 dodań i 7 usunięć

Wyświetl plik

@ -2288,7 +2288,7 @@ enum rig_caps_cptr_e {
* \brief Function to return int value from rig->caps
* Does not support > 32-bit rig_caps values
*/
extern HAMLIB_EXPORT (long long) rig_get_caps_int(rig_model_t rig_model, enum rig_caps_int_e rig_caps);
extern HAMLIB_EXPORT (uint64_t) rig_get_caps_int(rig_model_t rig_model, enum rig_caps_int_e rig_caps);
/**
* \brief Function to return char pointer value from rig->caps

Wyświetl plik

@ -456,6 +456,11 @@ int main(int argc, char *argv[])
{
sscanf(buf, "OM1%d", &modeSub);
}
else if (strcmp(buf,"RM;") == 0)
{
sprintf(buf, "RM2%04d;", 10);
write(fd, buf, strlen(buf));
}
else if (strlen(buf) > 0)
{
fprintf(stderr, "Unknown command: %s\n", buf);

Wyświetl plik

@ -2640,7 +2640,7 @@ void *HAMLIB_API rig_get_function_ptr(rig_model_t rig_model,
* \param RIG* and rig_caps_int_e
* \return the corresponding long value -- -RIG_EINVAL is the only error possible
*/
long long HAMLIB_API rig_get_caps_int(rig_model_t rig_model,
uint64_t HAMLIB_API rig_get_caps_int(rig_model_t rig_model,
enum rig_caps_int_e rig_caps)
{
const struct rig_caps *caps = rig_get_caps(rig_model);
@ -2676,6 +2676,7 @@ long long HAMLIB_API rig_get_caps_int(rig_model_t rig_model,
return caps->port_type;
case RIG_CAPS_HAS_GET_LEVEL:
rig_debug(RIG_DEBUG_TRACE, "%s(%d): return %8lx\n", __func__, __LINE__, caps->has_get_level);
return caps->has_get_level;
default:

Wyświetl plik

@ -983,6 +983,109 @@ void *multicast_publisher(void *arg)
return NULL;
}
#ifdef __MINGW32__
#include <winsock2.h>
#include <iphlpapi.h>
int is_wireless()
{
DWORD dwSize = 0;
DWORD dwRetVal = 0;
ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
PIP_ADAPTER_ADDRESSES pAddresses = NULL, pCurrAddresses = NULL;
// First call to determine actual memory size needed
GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAddresses, &dwSize);
pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(dwSize);
// Second call to get the actual data
dwRetVal = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAddresses, &dwSize);
if (dwRetVal == NO_ERROR)
{
for (pCurrAddresses = pAddresses; pCurrAddresses != NULL;
pCurrAddresses = pCurrAddresses->Next)
{
// printf("Adapter name: %s\n", pCurrAddresses->AdapterName);
// printf("Adapter description: %ls\n", pCurrAddresses->Description);
// printf("Adapter type: ");
if (pCurrAddresses->IfType == IF_TYPE_IEEE80211)
{
// printf("Wireless\n\n");
return 1;
}
else
{
// printf("Not Wireless\n\n");
}
}
}
else
{
//printf("GetAdaptersAddresses failed with error: %lu\n", dwRetVal);
}
if (pAddresses)
{
free(pAddresses);
}
return 0;
}
#else
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>
#include <linux/wireless.h>
#include <ifaddrs.h>
int is_wireless_linux(const char *ifname)
{
int sock = socket(AF_INET, SOCK_DGRAM, 0);
struct iwreq pwrq;
memset(&pwrq, 0, sizeof(pwrq));
strncpy(pwrq.ifr_name, ifname, IFNAMSIZ);
if (ioctl(sock, SIOCGIWNAME, &pwrq) != -1)
{
close(sock);
return 1; // Wireless
}
close(sock);
return 0; // Not wireless
}
int is_wireless()
{
struct ifaddrs *ifaddr, *ifa;
if (getifaddrs(&ifaddr) == -1)
{
perror("getifaddrs");
return 0;
}
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr == NULL)
{
continue;
}
int iswireless = is_wireless_linux(ifa->ifa_name);
//printf("%s is %s\n", ifa->ifa_name, iswireless ? "wireless" : "not wireless");
if (iswireless) {freeifaddrs(ifaddr); return 1;}
}
freeifaddrs(ifaddr);
return 0;
}
#endif
void *multicast_receiver(void *arg)
{
char data[4096];
@ -1024,8 +1127,15 @@ void *multicast_receiver(void *arg)
dest_addr.sin_family = AF_INET;
#ifdef __MINGW32__
// Windows cannot bind to multicast group addresses for some unknown reason
dest_addr.sin_addr.s_addr = htonl(INADDR_ANY);
rig_debug(RIG_DEBUG_ERR, "%s(%d): INADDR_ANY=%x,%x\n", htonl(INADDR_ANY), INADDR_ANY);
if (is_wireless())
{
rig_debug(RIG_DEBUG_VERBOSE, "%s: no wireless detect so INADDR_ANY is being used\n", __func__);
}
else
{
rig_debug(RIG_DEBUG_VERBOSE, "%s: wireless detected so localhost is being used\n", __func__);
dest_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
}
#else
dest_addr.sin_addr.s_addr = inet_addr(args->multicast_addr);
#endif

Wyświetl plik

@ -11,7 +11,7 @@
#include <hamlib/config.h>
#define SERIAL_PORT "/dev/ttyUSB0"
#define SERIAL_PORT "/dev/pts/2"
int main(int argc, const char *argv[])
@ -38,9 +38,9 @@ int main(int argc, const char *argv[])
* allocate memory, setup & open port
*/
hamlib_port_t myport;
if (argc < 2)
{
hamlib_port_t myport;
/* may be overridden by backend probe */
myport.type.rig = RIG_PORT_SERIAL;
myport.parm.serial.rate = 9600;
@ -48,7 +48,6 @@ int main(int argc, const char *argv[])
myport.parm.serial.stop_bits = 1;
myport.parm.serial.parity = RIG_PARITY_NONE;
myport.parm.serial.handshake = RIG_HANDSHAKE_NONE;
strncpy(myport.pathname, SERIAL_PORT, HAMLIB_FILPATHLEN - 1);
rig_load_all_backends();
myrig_model = rig_probe(&myport);
@ -59,6 +58,7 @@ int main(int argc, const char *argv[])
}
my_rig = rig_init(myrig_model);
rig_set_conf(my_rig, rig_token_lookup(my_rig, "rig_pathname"), SERIAL_PORT);
if (!my_rig)
{
@ -77,6 +77,9 @@ int main(int argc, const char *argv[])
exit(2);
}
uint64_t levels = rig_get_caps_int(my_rig->caps->rig_model, RIG_CAPS_HAS_GET_LEVEL);
printf("HAS_GET_LEVEL=0x%8lx, SWR=%8llx,true=%d\n", levels, levels & RIG_LEVEL_SWR, (levels & RIG_LEVEL_SWR) == RIG_LEVEL_SWR);
char val[256];
retcode = rig_get_conf2(my_rig, rig_token_lookup(my_rig, "write_delay"), val,
sizeof(val));