]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Added feature to connect to "distant" radios by specifiying the IP addr of the radio.
authorc vw <dl1ycf@darc.de>
Thu, 6 Jan 2022 18:56:53 +0000 (19:56 +0100)
committerc vw <dl1ycf@darc.de>
Thu, 6 Jan 2022 18:56:53 +0000 (19:56 +0100)
In this case, the discovery packet does not go "broadcast" but is routed to the
given IP address. This work across routers, VPNs etc.

MacOS.h
discovered.h
discovery.c
discovery.h
old_discovery.c
stemlab_discovery.c
stemlab_discovery.h

diff --git a/MacOS.h b/MacOS.h
index 252090ebb16b0f93de01129d117b84e1a59100b4..73811bb73d130b4b0bbb5870df05b4360c0ebe26 100644 (file)
--- a/MacOS.h
+++ b/MacOS.h
 //
 // MacOS < 10.12 does not have clock_gettime
 //
-// Contribution from github user "ra1nb0w"
+// Contributed initially by Davide "ra1nb0w"
 //
 
 #define CLOCK_REALTIME  0
 #define CLOCK_MONOTONIC 6
-#define CLOCK_MONOTONIC_RAW 6
+#define CLOCK_MONOTONIC_RAW 4
 typedef int clockid_t;
 
 #include <sys/time.h>
@@ -38,8 +38,12 @@ static inline int clock_gettime( clockid_t clk_id, struct timespec *ts )
       ts->tv_sec  = tv.tv_sec;
       ts->tv_nsec = tv.tv_usec * 1000;
     }
-    else if ( CLOCK_MONOTONIC == clk_id )
+    else if ( CLOCK_MONOTONIC == clk_id  || CLOCK_MONOTONIC_RAW == clk_id )
     {
+      //
+      // For the time being, accept CLOCK_MONOTONIC_RAW but treat it
+      // the same way as CLOCK_MONOTONIC.
+      //
       const uint64_t t = mach_absolute_time();
       mach_timebase_info_data_t timebase;
       mach_timebase_info(&timebase);
index 91e7b0b994f8a383c2da13dd3c1b841471d148cb..752aa88e98da0294a1d60081749ee13e060d8d08 100644 (file)
@@ -91,7 +91,8 @@
 struct _DISCOVERED {
     int protocol;
     int device;
-    int use_tcp;    // use TCP rather than UDP to connect to radio
+    int use_tcp;       // Radio connection is via TCP
+    int use_routing;    // Radio connection is "routed" to some IP address
     char name[64];
     int software_version;
     int status;
index e2edd70eb7d9be1e1ccfcd5906c201a9632728da..f8ba691be8cc49d911d1d4aabb1a95dde773c117 100644 (file)
@@ -63,8 +63,8 @@ static GtkWidget *apps_combobox[MAX_DEVICES];
 
 GtkWidget *tcpaddr;
 #define IPADDR_LEN 20
-static char ipaddr_tcp_buf[IPADDR_LEN] = "10.10.10.10";
-char *ipaddr_tcp = &ipaddr_tcp_buf[0];
+static char ipaddr_buf[IPADDR_LEN] = "";
+char *ipaddr_radio = &ipaddr_buf[0];
 
 #ifdef CLIENT_SERVER
 GtkWidget *host_addr_entry;
@@ -74,14 +74,6 @@ GtkWidget *host_port_spinner;
 gint host_port=50000;  // default listening port
 #endif
 
-//
-// This is a variable for the second phase of STEMlab discovery.
-// If set, we already have detected + selected the STEMlab,
-// started the SDR app on the RedPitaya and run a "P1 only"
-// discovery to obtain data from the SDR app
-//
-static int discover_only_p1 = 0;
-
 static gboolean delete_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data) {
   _exit(0);
 }
@@ -107,7 +99,7 @@ static gboolean start_cb (GtkWidget *widget, GdkEventButton *event, gpointer dat
     //
     stemlab_cleanup();
     sleep(2);          // let Stemlab SDR app start
-    discover_only_p1=1;
+    discover_only_stemlab=1;
     gtk_widget_destroy(discovery_dialog);
     g_idle_add(ext_discovery,NULL);
     return TRUE;
@@ -148,26 +140,29 @@ static gboolean exit_cb (GtkWidget *widget, GdkEventButton *event, gpointer data
   return TRUE;
 }
 
-static gboolean tcp_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
-    strncpy(ipaddr_tcp, gtk_entry_get_text(GTK_ENTRY(tcpaddr)), IPADDR_LEN);
-    ipaddr_tcp[IPADDR_LEN-1]=0;
-    // remove possible trailing newline chars in ipaddr_tcp
-           int len=strnlen(ipaddr_tcp,IPADDR_LEN);
-           while (--len >= 0) {
-             if (ipaddr_tcp[len] != '\n') break;
-             ipaddr_tcp[len]=0;
-           }
-           //fprintf(stderr,"New TCP addr = %s.\n", ipaddr_tcp);
-           // save this value to config file
-           FILE *fp = fopen("ip.addr", "w");
-           if (fp) {
-               fprintf(fp,"%s\n",ipaddr_tcp);
-               fclose(fp);
-           }
-           gtk_widget_destroy(discovery_dialog);
-           g_idle_add(ext_discovery,NULL);
-           return TRUE;
-       }
+static gboolean radio_ip_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
+    struct sockaddr_in sa;
+    int len;
+    const char *cp;
+
+    cp = gtk_entry_get_text(GTK_ENTRY(tcpaddr));
+    len=strnlen(cp,IPADDR_LEN);
+    fprintf(stderr,">>>>%s<<<<\n", cp);
+    if (len == 0) return TRUE;
+    if (inet_pton(AF_INET, cp, &(sa.sin_addr)) != 1) return TRUE;
+
+    strncpy(ipaddr_radio, cp, IPADDR_LEN);
+    ipaddr_radio[IPADDR_LEN-1]=0;
+
+    // The new value is written upon each key stroke, so what?
+    // fprintf(stderr,"New TCP addr = %s.\n", ipaddr_radio);
+    FILE *fp = fopen("ip.addr", "w");
+    if (fp) {
+       fprintf(fp,"%s\n",ipaddr_radio);
+       fclose(fp);
+    }
+    return FALSE;
+}
 
 #ifdef CLIENT_SERVER
 static gboolean connect_cb (GtkWidget *widget, GdkEventButton *event, gpointer data) {
@@ -208,14 +203,14 @@ void discovery() {
   // Try to locate IP addr
   FILE *fp=fopen("ip.addr","r");
   if (fp) {
-    char *c=fgets(ipaddr_tcp, IPADDR_LEN,fp);
+    char *c=fgets(ipaddr_radio, IPADDR_LEN,fp);
     fclose(fp);
-    ipaddr_tcp[IPADDR_LEN-1]=0;
-    // remove possible trailing newline char in ipaddr_tcp
-    int len=strnlen(ipaddr_tcp,IPADDR_LEN);
+    ipaddr_radio[IPADDR_LEN-1]=0;
+    // remove possible trailing newline char in ipaddr_radio
+    int len=strnlen(ipaddr_radio,IPADDR_LEN);
     while (--len >= 0) {
-      if (ipaddr_tcp[len] != '\n') break;
-      ipaddr_tcp[len]=0;
+      if (ipaddr_radio[len] != '\n') break;
+      ipaddr_radio[len]=0;
     }
   }
 #ifdef USBOZY
@@ -238,7 +233,7 @@ void discovery() {
 #endif
 
 #ifdef STEMLAB_DISCOVERY
-  if(enable_stemlab && !discover_only_p1) {
+  if(enable_stemlab && !discover_only_stemlab) {
 #ifdef NO_AVAHI
     status_text("Looking for STEMlab WEB apps");
 #else
@@ -253,20 +248,20 @@ void discovery() {
     old_discovery();
   }
 
-  if(enable_protocol_2 && !discover_only_p1) {
+  if(enable_protocol_2 && !discover_only_stemlab) {
     status_text("Protocol 2 ... Discovering Devices");
     new_discovery();
   }
 
 #ifdef SOAPYSDR
-  if(enable_soapy_protocol && !discover_only_p1) {
+  if(enable_soapy_protocol && !discover_only_stemlab) {
     status_text("SoapySDR ... Discovering Devices");
     soapy_discovery();
   }
 #endif
 
   // subsequent discoveries check all protocols enabled.
-  discover_only_p1=0;
+  discover_only_stemlab=0;
 
   status_text("Discovery");
   
@@ -377,29 +372,27 @@ fprintf(stderr,"%p Protocol=%d name=%s\n",d,d->protocol,d->name);
         }
 
 #ifdef SOAPYSDR
-        if(d->device!=SOAPYSDR_USB_DEVICE) {
+        if(d->device!=SOAPYSDR_USB_DEVICE)
 #endif
-          // if not on the same subnet then cannot start it
-         //
-          // NOTE: self-assigned IP  (a.k.a. APIPA) addresses
-          // these addresses are of the numerical form 169.254.xxx.yyy and used
-          // by many radios if they do not get a DHCP address. These addresses are valid even if outside the
-          // netmask of the (physical) interface making the connection - so do not complain in this case!
+       {
+         int can_connect = 0;
           //
-          // If the radio has a valid IP address but the computer only has an APIPA address, this also
-          // leads to a radio address outside the netmask and can be ignored. So if either the radio
-          // or the interface address starts with 169.254., suppress "Subnet!" complaint.
+         // We can connect if
+         //  a) either the computer or the radio have a self-assigned IP 169.254.xxx.yyy address
+         //  b) we have a "routed" (TCP or UDP) connection to the radio
+         //  c) radio and network address are in the same subnet
           //
-          if (strncmp(inet_ntoa(d->info.network.address.sin_addr),"169.254.",8) &&
-              strncmp(inet_ntoa(d->info.network.interface_address.sin_addr),"169.254.",8)) {
-            if((d->info.network.interface_address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr) != (d->info.network.address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr)) {
+          if (!strncmp(inet_ntoa(d->info.network.address.sin_addr),"169.254.",8)) can_connect=1;
+          if (!strncmp(inet_ntoa(d->info.network.interface_address.sin_addr),"169.254.",8)) can_connect=1;
+         if (d->use_routing) can_connect=1;
+          if((d->info.network.interface_address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr) ==
+             (d->info.network.address.sin_addr.s_addr&d->info.network.interface_netmask.sin_addr.s_addr)) can_connect=1;
+
+         if (!can_connect) {
               gtk_button_set_label(GTK_BUTTON(start_button),"Subnet!");
               gtk_widget_set_sensitive(start_button, FALSE);
-            }
           }
-#ifdef SOAPYSDR
         }
-#endif
 
 #ifdef STEMLAB_DISCOVERY
         if (d->protocol == STEMLAB_PROTOCOL) {
@@ -511,14 +504,14 @@ fprintf(stderr,"%p Protocol=%d name=%s\n",d,d->protocol,d->name);
     gtk_grid_attach(GTK_GRID(grid),gpio_b,0,row,1,1);
 #endif
 
-    GtkWidget *tcp_b=gtk_button_new_with_label("Use new TCP Addr:");
-    g_signal_connect (tcp_b, "button-press-event", G_CALLBACK(tcp_cb), NULL);
+    GtkWidget *tcp_b=gtk_label_new("Radio IP Addr:");
     gtk_grid_attach(GTK_GRID(grid),tcp_b,1,row,1,1);
 
     tcpaddr=gtk_entry_new();
     gtk_entry_set_max_length(GTK_ENTRY(tcpaddr), 20);
     gtk_grid_attach(GTK_GRID(grid),tcpaddr,2,row,1,1);
-    gtk_entry_set_text(GTK_ENTRY(tcpaddr), ipaddr_tcp);
+    gtk_entry_set_text(GTK_ENTRY(tcpaddr), ipaddr_radio);
+    g_signal_connect (tcpaddr, "changed", G_CALLBACK(radio_ip_cb), NULL);
 
     GtkWidget *exit_b=gtk_button_new_with_label("Exit");
     g_signal_connect (exit_b, "button-press-event", G_CALLBACK(exit_cb), NULL);
index fb540e1c96a5dfd4f456b053a49e474e67c7b96e..ff724dd9ae8965f154963b09175c65df7e84ada1 100644 (file)
@@ -18,4 +18,4 @@
 */
 
 extern void discovery(void);
-extern char *ipaddr_tcp;
+extern char *ipaddr_radio;
index 9b48c6cfaa1c026612a37514311067d8538c7e50..711a949f8adf2015645e093a8839cc834f936989 100644 (file)
@@ -37,6 +37,7 @@
 #include "discovered.h"
 #include "discovery.h"
 #include "old_discovery.h"
+#include "stemlab_discovery.h"
 
 static char interface_name[64];
 static struct sockaddr_in interface_addr={0};
@@ -50,7 +51,12 @@ static struct sockaddr_in discovery_addr;
 static GThread *discover_thread_id;
 static gpointer discover_receive_thread(gpointer data);
 
-static void discover(struct ifaddrs* iface) {
+//
+// discflag = 1:   discover by sending UDP broadcast packet
+// discflag = 2:   discover by sending UDP backet to Radio IP address
+// discflag = 3:   discover by connecting via TCP
+//
+static void discover(struct ifaddrs* iface, int discflag) {
     int rc;
     struct sockaddr_in *sa;
     struct sockaddr_in *mask;
@@ -63,19 +69,79 @@ static void discover(struct ifaddrs* iface) {
     unsigned char buffer[1032];
     int i, len;
 
-    if (iface == NULL) {
+    switch (discflag) {
+      case 1:
        //
-       // 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.
+       // Send METIS discovery packet to broadcast address on interface iface
        //
-        fprintf(stderr,"Trying to detect at TCP addr %s\n", ipaddr_tcp);
+        strcpy(interface_name,iface->ifa_name);
+        fprintf(stderr,"discover: looking for HPSDR devices on %s\n", 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:");
+            return;
+        }
+
+        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;
+        }
+
+        fprintf(stderr,"discover: bound to %s\n",interface_name);
+
+        // allow broadcast on the socket
+        int on=1;
+        rc=setsockopt(discovery_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+        if(rc != 0) {
+            fprintf(stderr,"discover: cannot set SO_BROADCAST: rc=%d\n", rc);
+            return;
+        }
+
+        // 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);
+        break;
+      case 2:
+       //
+       // Send METIS detection packet via UDP to ipaddr_radio
+       //
+       fprintf(stderr,"discover: looking for HPSDR device with IP %s\n", ipaddr_radio);
+
+        discovery_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
+        if(discovery_socket<0) {
+            perror("discover: create socket failed for discovery_socket:");
+            return;
+        }
+        to_addr.sin_family=AF_INET;
+        to_addr.sin_port=htons(DISCOVERY_PORT);
+        if (inet_aton(ipaddr_radio, &to_addr.sin_addr) == 0) {
+          fprintf(stderr, "discover: Radio UDP addr %s is invalid!\n", ipaddr_radio);
+          return;
+        }
+       break;
+      case 3:
+       //
+       // Send METIS detection packet via TCP to ipaddr_radio
+       // This is rather tricky, one must avoid "hanging" when the
+       // connection does not succeed.
+       //
+        fprintf(stderr,"Trying to detect via TCP with IP %s\n", ipaddr_radio);
        memset(&to_addr, 0, sizeof(to_addr));
        to_addr.sin_family = AF_INET;
-       if (inet_aton(ipaddr_tcp, &to_addr.sin_addr) == 0) {
-           fprintf(stderr,"discover: TCP addr %s is invalid!\n",ipaddr_tcp);
+       if (inet_aton(ipaddr_radio, &to_addr.sin_addr) == 0) {
+           fprintf(stderr,"discover: TCP addr %s is invalid!\n",ipaddr_radio);
            return;
        }
        to_addr.sin_port=htons(DISCOVERY_PORT);
@@ -139,47 +205,12 @@ static void discover(struct ifaddrs* iface) {
        }
        // Step 4. reset the socket to normal (blocking) mode
        fcntl(discovery_socket, F_SETFL, flags &  ~O_NONBLOCK);
-    } else {
-
-        strcpy(interface_name,iface->ifa_name);
-        fprintf(stderr,"discover: looking for HPSDR devices on %s\n", 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;
-        }
-
-        fprintf(stderr,"discover: bound to %s\n",interface_name);
-
-        // allow broadcast on the socket
-        int on=1;
-        rc=setsockopt(discovery_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
-        if(rc != 0) {
-            fprintf(stderr,"discover: cannot set SO_BROADCAST: rc=%d\n", 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);
+        break;
+      default:
+       return;
+       break;
     }
+
     optval = 1;
     setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
     setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
@@ -187,18 +218,18 @@ static void discover(struct ifaddrs* iface) {
     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 )
-    {
-        fprintf(stderr,"g_thread_new failed on discover_receive_thread\n");
-        exit( -1 );
-    }
-
-
 
     // send discovery packet
     // If this is a TCP connection, send a "long" packet
-    len=63;
-    if (iface == NULL) len=1032;
+    switch (discflag) {
+      case 1:
+      case 2:
+       len=63;  // send UDP packet
+       break;
+      case 3:
+       len=1032;  // send TCP packet
+       break;  
+    }
     buffer[0]=0xEF;
     buffer[1]=0xFE;
     buffer[2]=0x02;
@@ -216,26 +247,41 @@ static void discover(struct ifaddrs* iface) {
 
     close(discovery_socket);
 
-    if (iface == NULL) {
-      fprintf(stderr,"discover: exiting TCP discover for %s\n",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 {
-      fprintf(stderr,"discover: exiting discover for %s\n",iface->ifa_name);
+    switch (discflag) {
+      case 1:
+       fprintf(stderr,"discover: exiting discover for %s\n",iface->ifa_name);
+       break;
+      case 2:
+       fprintf(stderr,"discover: exiting HPSDR discover for IP %s\n",ipaddr_radio);
+       if (devices == rc+1) {
+         //
+         // METIS detection UDP packet sent to fixed IP address got a valid response.
+         //
+         memcpy((void *)&discovered[rc].info.network.address, (void *)&to_addr,sizeof(to_addr));
+         discovered[rc].info.network.address_length = sizeof(to_addr);
+          strcpy(discovered[rc].info.network.interface_name,"UDP");
+         discovered[rc].use_routing=1;
+       }
+       break;
+      case 3:
+       fprintf(stderr,"discover: exiting TCP discover for IP %s\n",ipaddr_radio);
+       if (devices == rc+1) {
+         //
+         // METIS detection TCP packet sent to fixed IP address got a valid response.
+         // Patch the IP 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_routing=1;
+         discovered[rc].use_tcp=1;
+        }
+       break;
     }
-
 }
 
 //static void *discover_receive_thread(void* arg) {
@@ -350,6 +396,7 @@ g_print("old_discovery: name=%s min=%f max=%f\n",discovered[devices].name, disco
                     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].use_routing=0;
                     discovered[devices].supported_receivers=2;
                    fprintf(stderr,"old_discovery: found device=%d software_version=%d status=%d address=%s (%02X:%02X:%02X:%02X:%02X:%02X) on %s min=%f max=%f\n",
                             discovered[devices].device,
@@ -380,23 +427,36 @@ void old_discovery() {
     struct ifaddrs *addrs,*ifa;
 
 fprintf(stderr,"old_discovery\n");
-    getifaddrs(&addrs);
-    ifa = addrs;
-    while (ifa) {
+    //
+    // In the second phase of the STEMlab (RedPitaya) discovery,
+    // we know that it can be reached by a specific IP address
+    // and do not need broadcast packets
+    //
+    if (!discover_only_stemlab) {
+      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);
+                discover(ifa, 1);   // send UDP broadcast packet to interface
             }
         }
         ifa = ifa->ifa_next;
+      }
+      freeifaddrs(addrs);
     }
-    freeifaddrs(addrs);
 
-    // Do one additional "discover" for a fixed TCP address
-    discover(NULL);
+    //
+    // If a radio ip addr is given, try sending a UDP packet to that address
+    // and try connecting via TCP
+    //
+    if (strlen(ipaddr_radio) > 1) {
+      discover(NULL, 2);
+      discover(NULL, 3);
+    }
 
     fprintf(stderr, "discovery found %d devices\n",devices);
 
index df9c45c08947164dacc734f9d62917beef62dc0b..6e8887dbdf18854fee92e0036ecfce6e1f94f7f6 100644 (file)
@@ -54,6 +54,8 @@
 #include <avahi-gobject/ga-service-resolver.h>
 #endif
 
+int discover_only_stemlab=0;
+
 // As we only run in the GTK+ main event loop, which is single-threaded and
 // non-preemptive, we shouldn't need any additional synchronisation mechanisms.
 static bool discovery_done = FALSE;
@@ -522,10 +524,10 @@ void stemlab_discovery() {
   struct sockaddr_in netmask;
 
    fprintf(stderr,"Stripped-down STEMLAB/HAMLAB discovery...\n");
-   fprintf(stderr,"STEMLAB: using inet addr %s\n", ipaddr_tcp);
+   fprintf(stderr,"STEMLAB: using inet addr %s\n", ipaddr_radio);
    ip_address.sin_family = AF_INET;
-   if (inet_aton(ipaddr_tcp, &ip_address.sin_addr) == 0) {
-       fprintf(stderr,"StemlabDiscovery: TCP %s is invalid!\n", ipaddr_tcp);
+   if (inet_aton(ipaddr_radio, &ip_address.sin_addr) == 0) {
+       fprintf(stderr,"StemlabDiscovery: TCP %s is invalid!\n", ipaddr_radio);
        return;
    }
 
@@ -543,7 +545,7 @@ void stemlab_discovery() {
     return;
   }
   app_list=0;
-  sprintf(txt,"http://%s",ipaddr_tcp);
+  sprintf(txt,"http://%s",ipaddr_radio);
   curl_easy_setopt(curl_handle, CURLOPT_URL, txt);
   curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, (long) 5);
   curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, get_list_cb);
@@ -551,7 +553,7 @@ void stemlab_discovery() {
   curl_error = curl_easy_perform(curl_handle);
   curl_easy_cleanup(curl_handle);
   if (curl_error ==  CURLE_OPERATION_TIMEDOUT) {
-    sprintf(txt,"No response from web server at %s", ipaddr_tcp);
+    sprintf(txt,"No response from web server at %s", ipaddr_radio);
     status_text(txt);
     fprintf(stderr,"%s\n",txt);
   }
@@ -569,7 +571,7 @@ void stemlab_discovery() {
       fprintf(stderr, "stemlab_start: Failed to create cURL handle\n");
       return;
     }
-    sprintf(txt,"http://%s/bazaar?apps=", ipaddr_tcp);
+    sprintf(txt,"http://%s/bazaar?apps=", ipaddr_radio);
     curl_easy_setopt(curl_handle, CURLOPT_URL, txt);
     curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, (long) 20);
     curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, app_list_cb);
index 69f7a0125d639603f9dd83f56f7ee1b4efef02c5..db337b5c846b0173d7c8a8caaf8229680ff5b9a3 100644 (file)
@@ -17,6 +17,8 @@
 *
 */
 
+extern int  discover_only_stemlab;
+
 extern void stemlab_discovery(void);
 extern int  stemlab_start_app(const char * const app_id);
 extern int  alpine_start_app(const char * const app_id);