]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
gitignore: add .cache (generated by clangd)
authorRamakrishnan Muthukrishnan <ram@rkrishnan.org>
Thu, 5 Dec 2024 15:30:47 +0000 (21:00 +0530)
committerRamakrishnan Muthukrishnan <ram@rkrishnan.org>
Thu, 5 Dec 2024 15:30:47 +0000 (21:00 +0530)
.gitignore
new_discovery.c [deleted file]
new_discovery.h [deleted file]
old_discovery.c [deleted file]
old_discovery.h [deleted file]
p1_discovery.c [new file with mode: 0644]
p1_discovery.h [new file with mode: 0644]
p2_discovery.c [new file with mode: 0644]
p2_discovery.h [new file with mode: 0644]

index 3166f93a24509864695b2ca8c4f6b46b9c6b7cb1..b52d0116cce4ef002ecaa3934321318b4a972866 100644 (file)
@@ -2,3 +2,4 @@
 pihpsdr
 .vscode
 rust/*
+.cache/*
\ No newline at end of file
diff --git a/new_discovery.c b/new_discovery.c
deleted file mode 100644 (file)
index 1d860c9..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/* Copyright (C)
-* 2015 - John Melton, G0ORX/N6LYT
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-*
-*/
-
-#include <gtk/gtk.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <net/if_arp.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <ifaddrs.h>
-#include <string.h>
-#include <errno.h>
-
-#include "discovered.h"
-//#include "discovery.h"
-
-
-static char interface_name[64];
-static struct sockaddr_in interface_addr={0};
-static struct sockaddr_in interface_netmask={0};
-
-#define DISCOVERY_PORT 1024
-static int discovery_socket;
-
-void new_discover(struct ifaddrs* iface);
-
-static GThread *discover_thread_id;
-gpointer new_discover_receive_thread(gpointer data);
-
-void print_device(int i) {
-    fprintf(stderr,"discovery: found protocol=%d device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n", 
-        discovered[i].protocol,
-        discovered[i].device,
-        discovered[i].software_version,
-        discovered[i].status,
-        inet_ntoa(discovered[i].info.network.address.sin_addr),
-        discovered[i].info.network.mac_address[0],
-        discovered[i].info.network.mac_address[1],
-        discovered[i].info.network.mac_address[2],
-        discovered[i].info.network.mac_address[3],
-        discovered[i].info.network.mac_address[4],
-        discovered[i].info.network.mac_address[5],
-        discovered[i].info.network.interface_name);
-}
-
-void new_discovery() {
-    struct ifaddrs *addrs,*ifa;
-    getifaddrs(&addrs);
-    ifa = addrs;
-    while (ifa) {
-        g_main_context_iteration(NULL, 0);
-        if (ifa->ifa_addr) {
-          if(ifa->ifa_addr->sa_family == AF_INET &&
-            (ifa->ifa_flags&IFF_UP)==IFF_UP &&
-            (ifa->ifa_flags&IFF_RUNNING)==IFF_RUNNING) {
-               new_discover(ifa);
-          }
-        }
-        ifa = ifa->ifa_next;
-    }
-    freeifaddrs(addrs);
-
-    
-    fprintf(stderr, "new_discovery found %d devices\n",devices);
-    
-    int i;
-    for(i=0;i<devices;i++) {
-        print_device(i);
-    }
-}
-
-void new_discover(struct ifaddrs* iface) {
-    int rc;
-    struct sockaddr_in *sa;
-    struct sockaddr_in *mask;
-    char addr[16];
-    char net_mask[16];
-
-    strcpy(interface_name,iface->ifa_name);
-    fprintf(stderr,"new_discover: looking for HPSDR devices on %s\n",interface_name);
-
-    // send a broadcast to locate metis boards on the network
-    discovery_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
-    if(discovery_socket<0) {
-        perror("new_discover: create socket failed for discovery_socket\n");
-        exit(-1);
-    }
-
-    int optval = 1;
-    setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
-    setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
-
-    sa = (struct sockaddr_in *) iface->ifa_addr;
-    mask = (struct sockaddr_in *) iface->ifa_netmask;
-
-    interface_netmask.sin_addr.s_addr = mask->sin_addr.s_addr;
-
-    // bind to this interface and the discovery port
-    interface_addr.sin_family = AF_INET;
-    interface_addr.sin_addr.s_addr = sa->sin_addr.s_addr;
-    interface_addr.sin_port = htons(0);
-    if(bind(discovery_socket,(struct sockaddr*)&interface_addr,sizeof(interface_addr))<0) {
-        perror("new_discover: bind socket failed for discovery_socket\n");
-        exit(-1);
-    }
-
-    strcpy(addr,inet_ntoa(sa->sin_addr));
-    strcpy(net_mask,inet_ntoa(mask->sin_addr));
-
-    fprintf(stderr,"new_discover: bound to %s %s %s\n",interface_name,addr,net_mask);
-
-    // allow broadcast on the socket
-    int on=1;
-    rc=setsockopt(discovery_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
-    if(rc != 0) {
-        fprintf(stderr,"new_discover: cannot set SO_BROADCAST: rc=%d\n", rc);
-        exit(-1);
-    }
-
-    // setup to address
-    struct sockaddr_in to_addr={0};
-    to_addr.sin_family=AF_INET;
-    to_addr.sin_port=htons(DISCOVERY_PORT);
-    to_addr.sin_addr.s_addr=htonl(INADDR_BROADCAST);
-
-    // start a receive thread to collect discovery response packets
-    discover_thread_id = g_thread_new( "new discover receive", new_discover_receive_thread, NULL);
-    if( ! discover_thread_id )
-    {
-        fprintf(stderr,"g_thread_new failed on new_discover_receive_thread\n");
-        exit( -1 );
-    }
-    fprintf(stderr,"new_disovery: thread_id=%p\n",discover_thread_id);
-
-
-    // send discovery packet
-    unsigned char buffer[60];
-    buffer[0]=0x00;
-    buffer[1]=0x00;
-    buffer[2]=0x00;
-    buffer[3]=0x00;
-    buffer[4]=0x02;
-    int i;
-    for(i=5;i<60;i++) {
-        buffer[i]=0x00;
-    }
-
-    if(sendto(discovery_socket,buffer,60,0,(struct sockaddr*)&to_addr,sizeof(to_addr))<0) {
-        perror("new_discover: sendto socket failed for discovery_socket\n");
-        return;
-    }
-
-    // wait for receive thread to complete
-    g_thread_join(discover_thread_id);
-
-    close(discovery_socket);
-
-    fprintf(stderr,"new_discover: exiting discover for %s\n",iface->ifa_name);
-}
-
-//void* new_discover_receive_thread(void* arg) {
-gpointer new_discover_receive_thread(gpointer data) {
-    struct sockaddr_in addr;
-    socklen_t len;
-    unsigned char buffer[2048];
-    int bytes_read;
-    struct timeval tv;
-    int i;
-    double frequency_min, frequency_max;
-
-    tv.tv_sec = 2;
-    tv.tv_usec = 0;
-
-    setsockopt(discovery_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
-
-    len=sizeof(addr);
-    while(1) {
-        bytes_read=recvfrom(discovery_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&addr,&len);
-        if(bytes_read<0) {
-            fprintf(stderr,"new_discover: bytes read %d\n", bytes_read);
-            perror("new_discover: recvfrom socket failed for discover_receive_thread");
-            break;
-        }
-        fprintf(stderr,"new_discover: received %d bytes\n",bytes_read);
-        if(bytes_read==1444) {
-            if(devices>0) {
-                break;
-            }
-        } else {
-        if(buffer[0]==0 && buffer[1]==0 && buffer[2]==0 && buffer[3]==0) {
-            int status = buffer[4] & 0xFF;
-            if (status == 2 || status == 3) {
-                if(devices<MAX_DEVICES) {
-                    discovered[devices].protocol=NEW_PROTOCOL;
-                    discovered[devices].device=buffer[11]&0xFF;
-                    discovered[devices].software_version=buffer[13]&0xFF;
-                    discovered[devices].status=status;
-                    switch(discovered[devices].device) {
-                       case NEW_DEVICE_ATLAS:
-                            strcpy(discovered[devices].name,"Atlas");
-                            frequency_min=0.0;
-                            frequency_max=61440000.0;
-                            break;
-                       case NEW_DEVICE_HERMES:
-                            strcpy(discovered[devices].name,"Hermes");
-                            frequency_min=0.0;
-                            frequency_max=61440000.0;
-                            break;
-                       case NEW_DEVICE_HERMES2:
-                            strcpy(discovered[devices].name,"Hermes2");
-                            frequency_min=0.0;
-                            frequency_max=61440000.0;
-                            break;
-                       case NEW_DEVICE_ANGELIA:
-                            strcpy(discovered[devices].name,"Angelia");
-                            frequency_min=0.0;
-                            frequency_max=61440000.0;
-                            break;
-                       case NEW_DEVICE_ORION:
-                            strcpy(discovered[devices].name,"Orion");
-                            frequency_min=0.0;
-                            frequency_max=61440000.0;
-                            break;
-                       case NEW_DEVICE_ORION2:
-                            strcpy(discovered[devices].name,"Orion2");
-                            frequency_min=0.0;
-                            frequency_max=61440000.0;
-                            break;
-                       case NEW_DEVICE_HERMES_LITE:
-                           if (discovered[devices].software_version < 40) {
-                              strcpy(discovered[devices].name,"Hermes Lite V1");
-                           } else {
-                              strcpy(discovered[devices].name,"Hermes Lite V2");
-                             discovered[devices].device = NEW_DEVICE_HERMES_LITE2;
-                           }
-                            frequency_min=0.0;
-                            frequency_max=30720000.0;
-                            break;
-                        default:
-                            strcpy(discovered[devices].name,"Unknown");
-                            frequency_min=0.0;
-                            frequency_max=30720000.0;
-                            break;
-                    }
-                    for(i=0;i<6;i++) {
-                        discovered[devices].info.network.mac_address[i]=buffer[i+5];
-                    }
-                    memcpy((void*)&discovered[devices].info.network.address,(void*)&addr,sizeof(addr));
-                    discovered[devices].info.network.address_length=sizeof(addr);
-                    memcpy((void*)&discovered[devices].info.network.interface_address,(void*)&interface_addr,sizeof(interface_addr));
-                    memcpy((void*)&discovered[devices].info.network.interface_netmask,(void*)&interface_netmask,sizeof(interface_netmask));
-                    discovered[devices].info.network.interface_length=sizeof(interface_addr);
-                    strcpy(discovered[devices].info.network.interface_name,interface_name);
-                    discovered[devices].supported_receivers=2;
-                    fprintf(stderr,"new_discover: found %d protocol=%d device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n", 
-                            devices,
-                            discovered[devices].protocol,
-                            discovered[devices].device,
-                            discovered[devices].software_version,
-                            discovered[devices].status,
-                            inet_ntoa(discovered[devices].info.network.address.sin_addr),
-                            discovered[devices].info.network.mac_address[0],
-                            discovered[devices].info.network.mac_address[1],
-                            discovered[devices].info.network.mac_address[2],
-                            discovered[devices].info.network.mac_address[3],
-                            discovered[devices].info.network.mac_address[4],
-                            discovered[devices].info.network.mac_address[5],
-                            discovered[devices].info.network.interface_name);
-                            discovered[devices].frequency_min=frequency_min;
-                            discovered[devices].frequency_max=frequency_max;
-                    devices++;
-                }
-            }
-        }
-        }
-    }
-    fprintf(stderr,"new_discover: exiting new_discover_receive_thread\n");
-    g_thread_exit(NULL);
-    return NULL;
-}
diff --git a/new_discovery.h b/new_discovery.h
deleted file mode 100644 (file)
index 9851f22..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (C)
-* 2015 - John Melton, G0ORX/N6LYT
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-*
-*/
-
-#ifndef _NEW_DISCOVERY_H
-#define _NEW_DISCOVERY_H
-
-void new_discovery(void);
-
-#endif
diff --git a/old_discovery.c b/old_discovery.c
deleted file mode 100644 (file)
index 8c8cfc0..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-/* Copyright (C)
-* 2015 - John Melton, G0ORX/N6LYT
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-*
-*/
-
-#include <gtk/gtk.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <net/if_arp.h>
-#include <net/if.h>
-#include <ifaddrs.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/select.h>
-
-#include "discovered.h"
-#include "discovery.h"
-#include "old_discovery.h"
-#include "log.h"
-
-static char interface_name[64];
-static struct sockaddr_in interface_addr={0};
-static struct sockaddr_in interface_netmask={0};
-
-#define DISCOVERY_PORT 1024
-static int discovery_socket;
-
-static GThread *discover_thread_id;
-static gpointer discover_receive_thread(gpointer data);
-
-static void discover(struct ifaddrs* iface) {
-    int rc;
-    struct sockaddr_in *sa;
-    struct sockaddr_in *mask;
-    struct sockaddr_in to_addr={0};
-    int flags;
-    struct timeval tv;
-    int optval;
-    socklen_t optlen;
-    fd_set fds;
-    unsigned char buffer[1032];
-    int i, len;
-
-    if (iface == NULL) {
-       //
-       // This indicates that we want to connect to an SDR which
-       // cannot be reached by (UDP) broadcast packets, but that
-       // we know its fixed IP address
-       // Therefore we try to send a METIS detection packet via TCP 
-       // to a "fixed" ip address.
-       //
-        log_trace("Trying to detect at TCP addr %s", ipaddr_tcp);
-       memset(&to_addr, 0, sizeof(to_addr));
-       to_addr.sin_family = AF_INET;
-       if (inet_aton(ipaddr_tcp, &to_addr.sin_addr) == 0) {
-           log_error("discover: TCP addr %s is invalid!",ipaddr_tcp);
-           return;
-       }
-       to_addr.sin_port=htons(DISCOVERY_PORT);
-
-        discovery_socket=socket(AF_INET, SOCK_STREAM, 0);
-        if(discovery_socket<0) {
-            perror("discover: create socket failed for TCP discovery_socket\n");
-            return;
-       }
-       //
-       // Here I tried a bullet-proof approach to connect() such that the program
-        // does not "hang" under any circumstances.
-       // - First, one makes the socket non-blocking. Then, the connect() will
-        //   immediately return with error EINPROGRESS.
-       // - Then, one uses select() to look for *writeability* and check
-       //   the socket error if everything went right. Since one calls select()
-        //   with a time-out, one either succeed within this time or gives up.
-        // - Do not forget to make the socket blocking again.
-       //
-        // Step 1. Make socket non-blocking and connect()
-       flags=fcntl(discovery_socket, F_GETFL, 0);
-       fcntl(discovery_socket, F_SETFL, flags | O_NONBLOCK);
-       rc=connect(discovery_socket, (const struct sockaddr *)&to_addr, sizeof(to_addr));
-        if ((errno != EINPROGRESS) && (rc < 0)) {
-            perror("discover: connect() failed for TCP discovery_socket:");
-           close(discovery_socket);
-           return;
-       }
-       // Step 2. Use select to wait for the connection
-        tv.tv_sec=3;
-       tv.tv_usec=0;
-       FD_ZERO(&fds);
-       FD_SET(discovery_socket, &fds);
-       rc=select(discovery_socket+1, NULL, &fds, NULL, &tv);
-        if (rc < 0) {
-            perror("discover: select() failed on TCP discovery_socket:");
-           close(discovery_socket);
-           return;
-        }
-       // If no connection occured, return
-       if (rc == 0) {
-           // select timed out
-           log_error("discover: select() timed out on TCP discovery socket");
-           close(discovery_socket);
-           return;
-       }
-       // Step 3. select() succeeded. Check success of connect()
-       optlen=sizeof(int);
-       rc=getsockopt(discovery_socket, SOL_SOCKET, SO_ERROR, &optval, &optlen);
-       if (rc < 0) {
-           // this should very rarely happen
-            perror("discover: getsockopt() failed on TCP discovery_socket:");
-           close(discovery_socket);
-           return;
-       }
-       if (optval != 0) {
-           // connect did not succeed
-           log_error("discover: connect() on TCP socket did not succeed");
-           close(discovery_socket);
-           return;
-       }
-       // Step 4. reset the socket to normal (blocking) mode
-       fcntl(discovery_socket, F_SETFL, flags &  ~O_NONBLOCK);
-    } else {
-
-        strcpy(interface_name,iface->ifa_name);
-        log_trace("discover: looking for HPSDR devices on %s", interface_name);
-
-        // send a broadcast to locate hpsdr boards on the network
-        discovery_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
-        if(discovery_socket<0) {
-            perror("discover: create socket failed for discovery_socket:");
-            exit(-1);
-        }
-
-        sa = (struct sockaddr_in *) iface->ifa_addr;
-        mask = (struct sockaddr_in *) iface->ifa_netmask;
-        interface_netmask.sin_addr.s_addr = mask->sin_addr.s_addr;
-
-        // bind to this interface and the discovery port
-        interface_addr.sin_family = AF_INET;
-        interface_addr.sin_addr.s_addr = sa->sin_addr.s_addr;
-        //interface_addr.sin_port = htons(DISCOVERY_PORT*2);
-        interface_addr.sin_port = htons(0); // system assigned port
-        if(bind(discovery_socket,(struct sockaddr*)&interface_addr,sizeof(interface_addr))<0) {
-            perror("discover: bind socket failed for discovery_socket:");
-            return;
-        }
-
-        log_trace("discover: bound to %s",interface_name);
-
-        // allow broadcast on the socket
-        int on=1;
-        rc=setsockopt(discovery_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
-        if(rc != 0) {
-            log_error("discover: cannot set SO_BROADCAST: rc=%d", rc);
-            exit(-1);
-        }
-
-        // setup to address
-        to_addr.sin_family=AF_INET;
-        to_addr.sin_port=htons(DISCOVERY_PORT);
-        to_addr.sin_addr.s_addr=htonl(INADDR_BROADCAST);
-    }
-    optval = 1;
-    setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
-    setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
-
-    rc=devices;
-    // start a receive thread to collect discovery response packets
-    discover_thread_id = g_thread_new( "old discover receive", discover_receive_thread, NULL);
-    if( ! discover_thread_id )
-    {
-        log_error("g_thread_new failed on discover_receive_thread");
-        exit(-1);
-    }
-
-
-
-    // send discovery packet
-    // If this is a TCP connection, send a "long" packet
-    len=63;
-    if (iface == NULL) len=1032;
-    buffer[0]=0xEF;
-    buffer[1]=0xFE;
-    buffer[2]=0x02;
-    for(i=3;i<len;i++) {
-        buffer[i]=0x00;
-    }
-
-    if(sendto(discovery_socket,buffer,len,0,(struct sockaddr*)&to_addr,sizeof(to_addr))<0) {
-        perror("discover: sendto socket failed for discovery_socket:");
-        return;
-    }
-
-    // wait for receive thread to complete
-    g_thread_join(discover_thread_id);
-
-    close(discovery_socket);
-
-    if (iface == NULL) {
-       log_trace("discover: exiting TCP discover for %s",ipaddr_tcp);
-       if (devices == rc+1) {
-           //
-           // We have exactly found one TCP device
-           // and have to patch the TCP addr into the device field
-           // and set the "use TCP" flag.
-           //
-           memcpy((void*)&discovered[rc].info.network.address,(void*)&to_addr,sizeof(to_addr));
-           discovered[rc].info.network.address_length=sizeof(to_addr);
-           memcpy((void*)&discovered[rc].info.network.interface_address,(void*)&to_addr,sizeof(to_addr));
-           memcpy((void*)&discovered[rc].info.network.interface_netmask,(void*)&to_addr,sizeof(to_addr));
-           discovered[rc].info.network.interface_length=sizeof(to_addr);
-           strcpy(discovered[rc].info.network.interface_name,"TCP");
-           discovered[rc].use_tcp=1;
-       }
-    } else {
-       log_trace("discover: exiting discover for %s",iface->ifa_name);
-    }
-
-}
-
-
-//static void *discover_receive_thread(void* arg) {
-static gpointer discover_receive_thread(gpointer data) {
-    struct sockaddr_in addr;
-    socklen_t len;
-    unsigned char buffer[2048];
-    int bytes_read;
-    struct timeval tv;
-    int i;
-
-    tv.tv_sec = 2;
-    tv.tv_usec = 0;
-    setsockopt(discovery_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
-
-    len=sizeof(addr);
-    while(1) {
-        bytes_read=recvfrom(discovery_socket,buffer,sizeof(buffer),1032,(struct sockaddr*)&addr,&len);
-        if(bytes_read<0) {
-            log_debug("discovery: bytes read %d", bytes_read);
-            log_error("old_discovery: recvfrom socket failed for discover_receive_thread: %s", strerror(errno));
-            break;
-        }
-        if (bytes_read == 0) break;
-        log_trace("old_discovery: received %d bytes",bytes_read);
-        if ((buffer[0] & 0xFF) == 0xEF && (buffer[1] & 0xFF) == 0xFE) {
-            int status = buffer[2] & 0xFF;
-            if (status == 2 || status == 3) {
-                if(devices<MAX_DEVICES) {
-                    discovered[devices].protocol=ORIGINAL_PROTOCOL;
-                    discovered[devices].device=buffer[10]&0xFF;
-                    discovered[devices].software_version=buffer[9]&0xFF;
-                    switch(discovered[devices].device) {
-                        case DEVICE_METIS:
-                            strcpy(discovered[devices].name,"Metis");
-                            discovered[devices].frequency_min=0.0;
-                            discovered[devices].frequency_max=61440000.0;
-                            break;
-                        case DEVICE_HERMES:
-                            strcpy(discovered[devices].name,"Hermes");
-                            discovered[devices].frequency_min=0.0;
-                            discovered[devices].frequency_max=61440000.0;
-                            break;
-                        case DEVICE_GRIFFIN:
-                            strcpy(discovered[devices].name,"Griffin");
-                            discovered[devices].frequency_min=0.0;
-                            discovered[devices].frequency_max=61440000.0;
-                            break;
-                        case DEVICE_ANGELIA:
-                            strcpy(discovered[devices].name,"Angelia");
-                            discovered[devices].frequency_min=0.0;
-                            discovered[devices].frequency_max=61440000.0;
-                            break;
-                        case DEVICE_ORION:
-                            strcpy(discovered[devices].name,"Orion");
-                            discovered[devices].frequency_min=0.0;
-                            discovered[devices].frequency_max=61440000.0;
-                            break;
-                        case DEVICE_HERMES_LITE:
-                           //
-                           // It seems that some HermesLite V2 boards use
-                           // DEVICE_HERMES_LITE as the ID and a software version
-                           // that is larger or equal to 40, while the original
-                           // (V1) HermesLite boards have software versions up to 31.
-                           // Therefore this is possibly a HL2 board!
-                           if (discovered[devices].software_version < 40) {
-                              strcpy(discovered[devices].name,"HermesLite V1");                
-                           } else {
-                              strcpy(discovered[devices].name,"HermesLite V2");                
-                             discovered[devices].device = DEVICE_HERMES_LITE2;
-                             log_trace("discovered HL2: Gateware Major Version=%d Minor Version=%d",buffer[9],buffer[15]);
-                           }
-                            discovered[devices].frequency_min=0.0;
-                            discovered[devices].frequency_max=30720000.0;
-                            break;
-                        case DEVICE_HERMES_LITE2:
-                            strcpy(discovered[devices].name,"HermesLite V2");          
-                            discovered[devices].frequency_min=0.0;
-                            discovered[devices].frequency_max=30720000.0;
-                            break;
-                        case DEVICE_ORION2:
-                            strcpy(discovered[devices].name,"Orion2");
-                            discovered[devices].frequency_min=0.0;
-                            discovered[devices].frequency_max=61440000.0;
-                            break;
-                        default:
-                            strcpy(discovered[devices].name,"Unknown");
-                            discovered[devices].frequency_min=0.0;
-                            discovered[devices].frequency_max=61440000.0;
-                            break;
-                    }
-                   log_trace("old_discovery: name=%s min=%f max=%f",discovered[devices].name, discovered[devices].frequency_min, discovered[devices].frequency_max);
-                    for(i=0;i<6;i++) {
-                        discovered[devices].info.network.mac_address[i]=buffer[i+3];
-                    }
-                    discovered[devices].status=status;
-                    memcpy((void*)&discovered[devices].info.network.address,(void*)&addr,sizeof(addr));
-                    discovered[devices].info.network.address_length=sizeof(addr);
-                    memcpy((void*)&discovered[devices].info.network.interface_address,(void*)&interface_addr,sizeof(interface_addr));
-                    memcpy((void*)&discovered[devices].info.network.interface_netmask,(void*)&interface_netmask,sizeof(interface_netmask));
-                    discovered[devices].info.network.interface_length=sizeof(interface_addr);
-                    strcpy(discovered[devices].info.network.interface_name,interface_name);
-                   discovered[devices].use_tcp=0;
-                    discovered[devices].supported_receivers=2;
-                   log_trace("old_discovery: found device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s min=%f max=%f",
-                            discovered[devices].device,
-                            discovered[devices].software_version,
-                            discovered[devices].status,
-                            inet_ntoa(discovered[devices].info.network.address.sin_addr),
-                            discovered[devices].info.network.mac_address[0],
-                            discovered[devices].info.network.mac_address[1],
-                            discovered[devices].info.network.mac_address[2],
-                            discovered[devices].info.network.mac_address[3],
-                            discovered[devices].info.network.mac_address[4],
-                            discovered[devices].info.network.mac_address[5],
-                            discovered[devices].info.network.interface_name,
-                            discovered[devices].frequency_min,
-                            discovered[devices].frequency_max);
-                    devices++;
-                }
-            }
-        }
-
-    }
-    log_trace("discovery: exiting discover_receive_thread");
-    g_thread_exit(NULL);
-    return NULL;
-}
-
-void old_discovery() {
-    struct ifaddrs *addrs,*ifa;
-
-    getifaddrs(&addrs);
-    ifa = addrs;
-    while (ifa) {
-        g_main_context_iteration(NULL, 0);
-        if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
-            if((ifa->ifa_flags&IFF_UP)==IFF_UP
-               && (ifa->ifa_flags&IFF_RUNNING)==IFF_RUNNING) {
-               // && (ifa->ifa_flags&IFF_LOOPBACK)==IFF_LOOPBACK) {
-                discover(ifa);
-            }
-        }
-        ifa = ifa->ifa_next;
-    }
-    freeifaddrs(addrs);
-
-    // Do one additional "discover" for a fixed TCP address
-    discover(NULL);
-
-    log_trace("discovery found %d devices",devices);
-
-    for(size_t i = 0; i < devices; i++) {
-       log_trace("discovery: found device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s",
-                 discovered[i].device,
-                 discovered[i].software_version,
-                 discovered[i].status,
-                 inet_ntoa(discovered[i].info.network.address.sin_addr),
-                 discovered[i].info.network.mac_address[0],
-                 discovered[i].info.network.mac_address[1],
-                 discovered[i].info.network.mac_address[2],
-                 discovered[i].info.network.mac_address[3],
-                 discovered[i].info.network.mac_address[4],
-                 discovered[i].info.network.mac_address[5],
-                 discovered[i].info.network.interface_name);
-    }
-}
-
diff --git a/old_discovery.h b/old_discovery.h
deleted file mode 100644 (file)
index fb3a2f5..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright (C)
-* 2015 - John Melton, G0ORX/N6LYT
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-*
-*/
-
-#ifndef _OLD_DISCOVERY_H
-#define _OLD_DISCOVERY_H
-
-void old_discovery(void);
-
-#endif
diff --git a/p1_discovery.c b/p1_discovery.c
new file mode 100644 (file)
index 0000000..8c8cfc0
--- /dev/null
@@ -0,0 +1,406 @@
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <net/if_arp.h>
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/select.h>
+
+#include "discovered.h"
+#include "discovery.h"
+#include "old_discovery.h"
+#include "log.h"
+
+static char interface_name[64];
+static struct sockaddr_in interface_addr={0};
+static struct sockaddr_in interface_netmask={0};
+
+#define DISCOVERY_PORT 1024
+static int discovery_socket;
+
+static GThread *discover_thread_id;
+static gpointer discover_receive_thread(gpointer data);
+
+static void discover(struct ifaddrs* iface) {
+    int rc;
+    struct sockaddr_in *sa;
+    struct sockaddr_in *mask;
+    struct sockaddr_in to_addr={0};
+    int flags;
+    struct timeval tv;
+    int optval;
+    socklen_t optlen;
+    fd_set fds;
+    unsigned char buffer[1032];
+    int i, len;
+
+    if (iface == NULL) {
+       //
+       // This indicates that we want to connect to an SDR which
+       // cannot be reached by (UDP) broadcast packets, but that
+       // we know its fixed IP address
+       // Therefore we try to send a METIS detection packet via TCP 
+       // to a "fixed" ip address.
+       //
+        log_trace("Trying to detect at TCP addr %s", ipaddr_tcp);
+       memset(&to_addr, 0, sizeof(to_addr));
+       to_addr.sin_family = AF_INET;
+       if (inet_aton(ipaddr_tcp, &to_addr.sin_addr) == 0) {
+           log_error("discover: TCP addr %s is invalid!",ipaddr_tcp);
+           return;
+       }
+       to_addr.sin_port=htons(DISCOVERY_PORT);
+
+        discovery_socket=socket(AF_INET, SOCK_STREAM, 0);
+        if(discovery_socket<0) {
+            perror("discover: create socket failed for TCP discovery_socket\n");
+            return;
+       }
+       //
+       // Here I tried a bullet-proof approach to connect() such that the program
+        // does not "hang" under any circumstances.
+       // - First, one makes the socket non-blocking. Then, the connect() will
+        //   immediately return with error EINPROGRESS.
+       // - Then, one uses select() to look for *writeability* and check
+       //   the socket error if everything went right. Since one calls select()
+        //   with a time-out, one either succeed within this time or gives up.
+        // - Do not forget to make the socket blocking again.
+       //
+        // Step 1. Make socket non-blocking and connect()
+       flags=fcntl(discovery_socket, F_GETFL, 0);
+       fcntl(discovery_socket, F_SETFL, flags | O_NONBLOCK);
+       rc=connect(discovery_socket, (const struct sockaddr *)&to_addr, sizeof(to_addr));
+        if ((errno != EINPROGRESS) && (rc < 0)) {
+            perror("discover: connect() failed for TCP discovery_socket:");
+           close(discovery_socket);
+           return;
+       }
+       // Step 2. Use select to wait for the connection
+        tv.tv_sec=3;
+       tv.tv_usec=0;
+       FD_ZERO(&fds);
+       FD_SET(discovery_socket, &fds);
+       rc=select(discovery_socket+1, NULL, &fds, NULL, &tv);
+        if (rc < 0) {
+            perror("discover: select() failed on TCP discovery_socket:");
+           close(discovery_socket);
+           return;
+        }
+       // If no connection occured, return
+       if (rc == 0) {
+           // select timed out
+           log_error("discover: select() timed out on TCP discovery socket");
+           close(discovery_socket);
+           return;
+       }
+       // Step 3. select() succeeded. Check success of connect()
+       optlen=sizeof(int);
+       rc=getsockopt(discovery_socket, SOL_SOCKET, SO_ERROR, &optval, &optlen);
+       if (rc < 0) {
+           // this should very rarely happen
+            perror("discover: getsockopt() failed on TCP discovery_socket:");
+           close(discovery_socket);
+           return;
+       }
+       if (optval != 0) {
+           // connect did not succeed
+           log_error("discover: connect() on TCP socket did not succeed");
+           close(discovery_socket);
+           return;
+       }
+       // Step 4. reset the socket to normal (blocking) mode
+       fcntl(discovery_socket, F_SETFL, flags &  ~O_NONBLOCK);
+    } else {
+
+        strcpy(interface_name,iface->ifa_name);
+        log_trace("discover: looking for HPSDR devices on %s", interface_name);
+
+        // send a broadcast to locate hpsdr boards on the network
+        discovery_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
+        if(discovery_socket<0) {
+            perror("discover: create socket failed for discovery_socket:");
+            exit(-1);
+        }
+
+        sa = (struct sockaddr_in *) iface->ifa_addr;
+        mask = (struct sockaddr_in *) iface->ifa_netmask;
+        interface_netmask.sin_addr.s_addr = mask->sin_addr.s_addr;
+
+        // bind to this interface and the discovery port
+        interface_addr.sin_family = AF_INET;
+        interface_addr.sin_addr.s_addr = sa->sin_addr.s_addr;
+        //interface_addr.sin_port = htons(DISCOVERY_PORT*2);
+        interface_addr.sin_port = htons(0); // system assigned port
+        if(bind(discovery_socket,(struct sockaddr*)&interface_addr,sizeof(interface_addr))<0) {
+            perror("discover: bind socket failed for discovery_socket:");
+            return;
+        }
+
+        log_trace("discover: bound to %s",interface_name);
+
+        // allow broadcast on the socket
+        int on=1;
+        rc=setsockopt(discovery_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+        if(rc != 0) {
+            log_error("discover: cannot set SO_BROADCAST: rc=%d", rc);
+            exit(-1);
+        }
+
+        // setup to address
+        to_addr.sin_family=AF_INET;
+        to_addr.sin_port=htons(DISCOVERY_PORT);
+        to_addr.sin_addr.s_addr=htonl(INADDR_BROADCAST);
+    }
+    optval = 1;
+    setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
+    setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
+
+    rc=devices;
+    // start a receive thread to collect discovery response packets
+    discover_thread_id = g_thread_new( "old discover receive", discover_receive_thread, NULL);
+    if( ! discover_thread_id )
+    {
+        log_error("g_thread_new failed on discover_receive_thread");
+        exit(-1);
+    }
+
+
+
+    // send discovery packet
+    // If this is a TCP connection, send a "long" packet
+    len=63;
+    if (iface == NULL) len=1032;
+    buffer[0]=0xEF;
+    buffer[1]=0xFE;
+    buffer[2]=0x02;
+    for(i=3;i<len;i++) {
+        buffer[i]=0x00;
+    }
+
+    if(sendto(discovery_socket,buffer,len,0,(struct sockaddr*)&to_addr,sizeof(to_addr))<0) {
+        perror("discover: sendto socket failed for discovery_socket:");
+        return;
+    }
+
+    // wait for receive thread to complete
+    g_thread_join(discover_thread_id);
+
+    close(discovery_socket);
+
+    if (iface == NULL) {
+       log_trace("discover: exiting TCP discover for %s",ipaddr_tcp);
+       if (devices == rc+1) {
+           //
+           // We have exactly found one TCP device
+           // and have to patch the TCP addr into the device field
+           // and set the "use TCP" flag.
+           //
+           memcpy((void*)&discovered[rc].info.network.address,(void*)&to_addr,sizeof(to_addr));
+           discovered[rc].info.network.address_length=sizeof(to_addr);
+           memcpy((void*)&discovered[rc].info.network.interface_address,(void*)&to_addr,sizeof(to_addr));
+           memcpy((void*)&discovered[rc].info.network.interface_netmask,(void*)&to_addr,sizeof(to_addr));
+           discovered[rc].info.network.interface_length=sizeof(to_addr);
+           strcpy(discovered[rc].info.network.interface_name,"TCP");
+           discovered[rc].use_tcp=1;
+       }
+    } else {
+       log_trace("discover: exiting discover for %s",iface->ifa_name);
+    }
+
+}
+
+
+//static void *discover_receive_thread(void* arg) {
+static gpointer discover_receive_thread(gpointer data) {
+    struct sockaddr_in addr;
+    socklen_t len;
+    unsigned char buffer[2048];
+    int bytes_read;
+    struct timeval tv;
+    int i;
+
+    tv.tv_sec = 2;
+    tv.tv_usec = 0;
+    setsockopt(discovery_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
+
+    len=sizeof(addr);
+    while(1) {
+        bytes_read=recvfrom(discovery_socket,buffer,sizeof(buffer),1032,(struct sockaddr*)&addr,&len);
+        if(bytes_read<0) {
+            log_debug("discovery: bytes read %d", bytes_read);
+            log_error("old_discovery: recvfrom socket failed for discover_receive_thread: %s", strerror(errno));
+            break;
+        }
+        if (bytes_read == 0) break;
+        log_trace("old_discovery: received %d bytes",bytes_read);
+        if ((buffer[0] & 0xFF) == 0xEF && (buffer[1] & 0xFF) == 0xFE) {
+            int status = buffer[2] & 0xFF;
+            if (status == 2 || status == 3) {
+                if(devices<MAX_DEVICES) {
+                    discovered[devices].protocol=ORIGINAL_PROTOCOL;
+                    discovered[devices].device=buffer[10]&0xFF;
+                    discovered[devices].software_version=buffer[9]&0xFF;
+                    switch(discovered[devices].device) {
+                        case DEVICE_METIS:
+                            strcpy(discovered[devices].name,"Metis");
+                            discovered[devices].frequency_min=0.0;
+                            discovered[devices].frequency_max=61440000.0;
+                            break;
+                        case DEVICE_HERMES:
+                            strcpy(discovered[devices].name,"Hermes");
+                            discovered[devices].frequency_min=0.0;
+                            discovered[devices].frequency_max=61440000.0;
+                            break;
+                        case DEVICE_GRIFFIN:
+                            strcpy(discovered[devices].name,"Griffin");
+                            discovered[devices].frequency_min=0.0;
+                            discovered[devices].frequency_max=61440000.0;
+                            break;
+                        case DEVICE_ANGELIA:
+                            strcpy(discovered[devices].name,"Angelia");
+                            discovered[devices].frequency_min=0.0;
+                            discovered[devices].frequency_max=61440000.0;
+                            break;
+                        case DEVICE_ORION:
+                            strcpy(discovered[devices].name,"Orion");
+                            discovered[devices].frequency_min=0.0;
+                            discovered[devices].frequency_max=61440000.0;
+                            break;
+                        case DEVICE_HERMES_LITE:
+                           //
+                           // It seems that some HermesLite V2 boards use
+                           // DEVICE_HERMES_LITE as the ID and a software version
+                           // that is larger or equal to 40, while the original
+                           // (V1) HermesLite boards have software versions up to 31.
+                           // Therefore this is possibly a HL2 board!
+                           if (discovered[devices].software_version < 40) {
+                              strcpy(discovered[devices].name,"HermesLite V1");                
+                           } else {
+                              strcpy(discovered[devices].name,"HermesLite V2");                
+                             discovered[devices].device = DEVICE_HERMES_LITE2;
+                             log_trace("discovered HL2: Gateware Major Version=%d Minor Version=%d",buffer[9],buffer[15]);
+                           }
+                            discovered[devices].frequency_min=0.0;
+                            discovered[devices].frequency_max=30720000.0;
+                            break;
+                        case DEVICE_HERMES_LITE2:
+                            strcpy(discovered[devices].name,"HermesLite V2");          
+                            discovered[devices].frequency_min=0.0;
+                            discovered[devices].frequency_max=30720000.0;
+                            break;
+                        case DEVICE_ORION2:
+                            strcpy(discovered[devices].name,"Orion2");
+                            discovered[devices].frequency_min=0.0;
+                            discovered[devices].frequency_max=61440000.0;
+                            break;
+                        default:
+                            strcpy(discovered[devices].name,"Unknown");
+                            discovered[devices].frequency_min=0.0;
+                            discovered[devices].frequency_max=61440000.0;
+                            break;
+                    }
+                   log_trace("old_discovery: name=%s min=%f max=%f",discovered[devices].name, discovered[devices].frequency_min, discovered[devices].frequency_max);
+                    for(i=0;i<6;i++) {
+                        discovered[devices].info.network.mac_address[i]=buffer[i+3];
+                    }
+                    discovered[devices].status=status;
+                    memcpy((void*)&discovered[devices].info.network.address,(void*)&addr,sizeof(addr));
+                    discovered[devices].info.network.address_length=sizeof(addr);
+                    memcpy((void*)&discovered[devices].info.network.interface_address,(void*)&interface_addr,sizeof(interface_addr));
+                    memcpy((void*)&discovered[devices].info.network.interface_netmask,(void*)&interface_netmask,sizeof(interface_netmask));
+                    discovered[devices].info.network.interface_length=sizeof(interface_addr);
+                    strcpy(discovered[devices].info.network.interface_name,interface_name);
+                   discovered[devices].use_tcp=0;
+                    discovered[devices].supported_receivers=2;
+                   log_trace("old_discovery: found device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s min=%f max=%f",
+                            discovered[devices].device,
+                            discovered[devices].software_version,
+                            discovered[devices].status,
+                            inet_ntoa(discovered[devices].info.network.address.sin_addr),
+                            discovered[devices].info.network.mac_address[0],
+                            discovered[devices].info.network.mac_address[1],
+                            discovered[devices].info.network.mac_address[2],
+                            discovered[devices].info.network.mac_address[3],
+                            discovered[devices].info.network.mac_address[4],
+                            discovered[devices].info.network.mac_address[5],
+                            discovered[devices].info.network.interface_name,
+                            discovered[devices].frequency_min,
+                            discovered[devices].frequency_max);
+                    devices++;
+                }
+            }
+        }
+
+    }
+    log_trace("discovery: exiting discover_receive_thread");
+    g_thread_exit(NULL);
+    return NULL;
+}
+
+void old_discovery() {
+    struct ifaddrs *addrs,*ifa;
+
+    getifaddrs(&addrs);
+    ifa = addrs;
+    while (ifa) {
+        g_main_context_iteration(NULL, 0);
+        if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
+            if((ifa->ifa_flags&IFF_UP)==IFF_UP
+               && (ifa->ifa_flags&IFF_RUNNING)==IFF_RUNNING) {
+               // && (ifa->ifa_flags&IFF_LOOPBACK)==IFF_LOOPBACK) {
+                discover(ifa);
+            }
+        }
+        ifa = ifa->ifa_next;
+    }
+    freeifaddrs(addrs);
+
+    // Do one additional "discover" for a fixed TCP address
+    discover(NULL);
+
+    log_trace("discovery found %d devices",devices);
+
+    for(size_t i = 0; i < devices; i++) {
+       log_trace("discovery: found device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s",
+                 discovered[i].device,
+                 discovered[i].software_version,
+                 discovered[i].status,
+                 inet_ntoa(discovered[i].info.network.address.sin_addr),
+                 discovered[i].info.network.mac_address[0],
+                 discovered[i].info.network.mac_address[1],
+                 discovered[i].info.network.mac_address[2],
+                 discovered[i].info.network.mac_address[3],
+                 discovered[i].info.network.mac_address[4],
+                 discovered[i].info.network.mac_address[5],
+                 discovered[i].info.network.interface_name);
+    }
+}
+
diff --git a/p1_discovery.h b/p1_discovery.h
new file mode 100644 (file)
index 0000000..fb3a2f5
--- /dev/null
@@ -0,0 +1,25 @@
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+
+#ifndef _OLD_DISCOVERY_H
+#define _OLD_DISCOVERY_H
+
+void old_discovery(void);
+
+#endif
diff --git a/p2_discovery.c b/p2_discovery.c
new file mode 100644 (file)
index 0000000..1d860c9
--- /dev/null
@@ -0,0 +1,302 @@
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+
+#include <gtk/gtk.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <net/if_arp.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <ifaddrs.h>
+#include <string.h>
+#include <errno.h>
+
+#include "discovered.h"
+//#include "discovery.h"
+
+
+static char interface_name[64];
+static struct sockaddr_in interface_addr={0};
+static struct sockaddr_in interface_netmask={0};
+
+#define DISCOVERY_PORT 1024
+static int discovery_socket;
+
+void new_discover(struct ifaddrs* iface);
+
+static GThread *discover_thread_id;
+gpointer new_discover_receive_thread(gpointer data);
+
+void print_device(int i) {
+    fprintf(stderr,"discovery: found protocol=%d device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n", 
+        discovered[i].protocol,
+        discovered[i].device,
+        discovered[i].software_version,
+        discovered[i].status,
+        inet_ntoa(discovered[i].info.network.address.sin_addr),
+        discovered[i].info.network.mac_address[0],
+        discovered[i].info.network.mac_address[1],
+        discovered[i].info.network.mac_address[2],
+        discovered[i].info.network.mac_address[3],
+        discovered[i].info.network.mac_address[4],
+        discovered[i].info.network.mac_address[5],
+        discovered[i].info.network.interface_name);
+}
+
+void new_discovery() {
+    struct ifaddrs *addrs,*ifa;
+    getifaddrs(&addrs);
+    ifa = addrs;
+    while (ifa) {
+        g_main_context_iteration(NULL, 0);
+        if (ifa->ifa_addr) {
+          if(ifa->ifa_addr->sa_family == AF_INET &&
+            (ifa->ifa_flags&IFF_UP)==IFF_UP &&
+            (ifa->ifa_flags&IFF_RUNNING)==IFF_RUNNING) {
+               new_discover(ifa);
+          }
+        }
+        ifa = ifa->ifa_next;
+    }
+    freeifaddrs(addrs);
+
+    
+    fprintf(stderr, "new_discovery found %d devices\n",devices);
+    
+    int i;
+    for(i=0;i<devices;i++) {
+        print_device(i);
+    }
+}
+
+void new_discover(struct ifaddrs* iface) {
+    int rc;
+    struct sockaddr_in *sa;
+    struct sockaddr_in *mask;
+    char addr[16];
+    char net_mask[16];
+
+    strcpy(interface_name,iface->ifa_name);
+    fprintf(stderr,"new_discover: looking for HPSDR devices on %s\n",interface_name);
+
+    // send a broadcast to locate metis boards on the network
+    discovery_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
+    if(discovery_socket<0) {
+        perror("new_discover: create socket failed for discovery_socket\n");
+        exit(-1);
+    }
+
+    int optval = 1;
+    setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
+    setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
+
+    sa = (struct sockaddr_in *) iface->ifa_addr;
+    mask = (struct sockaddr_in *) iface->ifa_netmask;
+
+    interface_netmask.sin_addr.s_addr = mask->sin_addr.s_addr;
+
+    // bind to this interface and the discovery port
+    interface_addr.sin_family = AF_INET;
+    interface_addr.sin_addr.s_addr = sa->sin_addr.s_addr;
+    interface_addr.sin_port = htons(0);
+    if(bind(discovery_socket,(struct sockaddr*)&interface_addr,sizeof(interface_addr))<0) {
+        perror("new_discover: bind socket failed for discovery_socket\n");
+        exit(-1);
+    }
+
+    strcpy(addr,inet_ntoa(sa->sin_addr));
+    strcpy(net_mask,inet_ntoa(mask->sin_addr));
+
+    fprintf(stderr,"new_discover: bound to %s %s %s\n",interface_name,addr,net_mask);
+
+    // allow broadcast on the socket
+    int on=1;
+    rc=setsockopt(discovery_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+    if(rc != 0) {
+        fprintf(stderr,"new_discover: cannot set SO_BROADCAST: rc=%d\n", rc);
+        exit(-1);
+    }
+
+    // setup to address
+    struct sockaddr_in to_addr={0};
+    to_addr.sin_family=AF_INET;
+    to_addr.sin_port=htons(DISCOVERY_PORT);
+    to_addr.sin_addr.s_addr=htonl(INADDR_BROADCAST);
+
+    // start a receive thread to collect discovery response packets
+    discover_thread_id = g_thread_new( "new discover receive", new_discover_receive_thread, NULL);
+    if( ! discover_thread_id )
+    {
+        fprintf(stderr,"g_thread_new failed on new_discover_receive_thread\n");
+        exit( -1 );
+    }
+    fprintf(stderr,"new_disovery: thread_id=%p\n",discover_thread_id);
+
+
+    // send discovery packet
+    unsigned char buffer[60];
+    buffer[0]=0x00;
+    buffer[1]=0x00;
+    buffer[2]=0x00;
+    buffer[3]=0x00;
+    buffer[4]=0x02;
+    int i;
+    for(i=5;i<60;i++) {
+        buffer[i]=0x00;
+    }
+
+    if(sendto(discovery_socket,buffer,60,0,(struct sockaddr*)&to_addr,sizeof(to_addr))<0) {
+        perror("new_discover: sendto socket failed for discovery_socket\n");
+        return;
+    }
+
+    // wait for receive thread to complete
+    g_thread_join(discover_thread_id);
+
+    close(discovery_socket);
+
+    fprintf(stderr,"new_discover: exiting discover for %s\n",iface->ifa_name);
+}
+
+//void* new_discover_receive_thread(void* arg) {
+gpointer new_discover_receive_thread(gpointer data) {
+    struct sockaddr_in addr;
+    socklen_t len;
+    unsigned char buffer[2048];
+    int bytes_read;
+    struct timeval tv;
+    int i;
+    double frequency_min, frequency_max;
+
+    tv.tv_sec = 2;
+    tv.tv_usec = 0;
+
+    setsockopt(discovery_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
+
+    len=sizeof(addr);
+    while(1) {
+        bytes_read=recvfrom(discovery_socket,buffer,sizeof(buffer),0,(struct sockaddr*)&addr,&len);
+        if(bytes_read<0) {
+            fprintf(stderr,"new_discover: bytes read %d\n", bytes_read);
+            perror("new_discover: recvfrom socket failed for discover_receive_thread");
+            break;
+        }
+        fprintf(stderr,"new_discover: received %d bytes\n",bytes_read);
+        if(bytes_read==1444) {
+            if(devices>0) {
+                break;
+            }
+        } else {
+        if(buffer[0]==0 && buffer[1]==0 && buffer[2]==0 && buffer[3]==0) {
+            int status = buffer[4] & 0xFF;
+            if (status == 2 || status == 3) {
+                if(devices<MAX_DEVICES) {
+                    discovered[devices].protocol=NEW_PROTOCOL;
+                    discovered[devices].device=buffer[11]&0xFF;
+                    discovered[devices].software_version=buffer[13]&0xFF;
+                    discovered[devices].status=status;
+                    switch(discovered[devices].device) {
+                       case NEW_DEVICE_ATLAS:
+                            strcpy(discovered[devices].name,"Atlas");
+                            frequency_min=0.0;
+                            frequency_max=61440000.0;
+                            break;
+                       case NEW_DEVICE_HERMES:
+                            strcpy(discovered[devices].name,"Hermes");
+                            frequency_min=0.0;
+                            frequency_max=61440000.0;
+                            break;
+                       case NEW_DEVICE_HERMES2:
+                            strcpy(discovered[devices].name,"Hermes2");
+                            frequency_min=0.0;
+                            frequency_max=61440000.0;
+                            break;
+                       case NEW_DEVICE_ANGELIA:
+                            strcpy(discovered[devices].name,"Angelia");
+                            frequency_min=0.0;
+                            frequency_max=61440000.0;
+                            break;
+                       case NEW_DEVICE_ORION:
+                            strcpy(discovered[devices].name,"Orion");
+                            frequency_min=0.0;
+                            frequency_max=61440000.0;
+                            break;
+                       case NEW_DEVICE_ORION2:
+                            strcpy(discovered[devices].name,"Orion2");
+                            frequency_min=0.0;
+                            frequency_max=61440000.0;
+                            break;
+                       case NEW_DEVICE_HERMES_LITE:
+                           if (discovered[devices].software_version < 40) {
+                              strcpy(discovered[devices].name,"Hermes Lite V1");
+                           } else {
+                              strcpy(discovered[devices].name,"Hermes Lite V2");
+                             discovered[devices].device = NEW_DEVICE_HERMES_LITE2;
+                           }
+                            frequency_min=0.0;
+                            frequency_max=30720000.0;
+                            break;
+                        default:
+                            strcpy(discovered[devices].name,"Unknown");
+                            frequency_min=0.0;
+                            frequency_max=30720000.0;
+                            break;
+                    }
+                    for(i=0;i<6;i++) {
+                        discovered[devices].info.network.mac_address[i]=buffer[i+5];
+                    }
+                    memcpy((void*)&discovered[devices].info.network.address,(void*)&addr,sizeof(addr));
+                    discovered[devices].info.network.address_length=sizeof(addr);
+                    memcpy((void*)&discovered[devices].info.network.interface_address,(void*)&interface_addr,sizeof(interface_addr));
+                    memcpy((void*)&discovered[devices].info.network.interface_netmask,(void*)&interface_netmask,sizeof(interface_netmask));
+                    discovered[devices].info.network.interface_length=sizeof(interface_addr);
+                    strcpy(discovered[devices].info.network.interface_name,interface_name);
+                    discovered[devices].supported_receivers=2;
+                    fprintf(stderr,"new_discover: found %d protocol=%d device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s\n", 
+                            devices,
+                            discovered[devices].protocol,
+                            discovered[devices].device,
+                            discovered[devices].software_version,
+                            discovered[devices].status,
+                            inet_ntoa(discovered[devices].info.network.address.sin_addr),
+                            discovered[devices].info.network.mac_address[0],
+                            discovered[devices].info.network.mac_address[1],
+                            discovered[devices].info.network.mac_address[2],
+                            discovered[devices].info.network.mac_address[3],
+                            discovered[devices].info.network.mac_address[4],
+                            discovered[devices].info.network.mac_address[5],
+                            discovered[devices].info.network.interface_name);
+                            discovered[devices].frequency_min=frequency_min;
+                            discovered[devices].frequency_max=frequency_max;
+                    devices++;
+                }
+            }
+        }
+        }
+    }
+    fprintf(stderr,"new_discover: exiting new_discover_receive_thread\n");
+    g_thread_exit(NULL);
+    return NULL;
+}
diff --git a/p2_discovery.h b/p2_discovery.h
new file mode 100644 (file)
index 0000000..9851f22
--- /dev/null
@@ -0,0 +1,25 @@
+/* Copyright (C)
+* 2015 - John Melton, G0ORX/N6LYT
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+
+#ifndef _NEW_DISCOVERY_H
+#define _NEW_DISCOVERY_H
+
+void new_discovery(void);
+
+#endif