4 Replies Latest reply on Jan 3, 2017 12:36 PM by Intel Corporation

    UDP broadcast from Edison to ESP8266s

    allene

      I am trying to expand an Edison app so it can broadcast over WiFi to several remote displays running ESP8266 UDP receivers.  I am able to receive and send UDP messages via this example http://www.binarytides.com/programming-udp-sockets-c-linux/http:// .  I am using the Android app "UDP Send / Receive" to test.

       

      Several months ago I tried unsuccessfully to do a UPD Broadcast in Edison but now realize about needing to switch the Edison to AP mode. Here is a reference to that. http://rwx.io/blog/2015/08/16/edison-wifi-config/http://

       

      The switch to AP mode is done with these two commands

      systemctl stop wpa_supplicant

      systemctl start hostapd

       

      To return to normal mode, just switch the start and stop.

       

      I have tried switching the ip address in the above linked example to INADDR_BROADCAST from INADDR_ANY but it does not work on the tablets I am using to test.

       

      My code from months ago was built to do UPD Broadcasts but it runs with an error 101 Network Unreachable.  The code is below.  I would appreciate any pointers. I don't have the ESP8266's yet so have just been using the Android app to test but the code below runs with an error exit from the line I highlighted in red. In other words, it won't send.

       

      Allen

      -------------------------------------------------------------------------------------------------------------------------

       

      #include<stdio.h> //printf

      #include<string.h> //memset

      #include<stdlib.h> //exit(0);

      #include<arpa/inet.h>

      #include<sys/socket.h>

      #include <errno.h>

      volatile int sock;

      #define BUFLEN 512  //Max length of buffer

      #define PORT 8888   //The port on which to listen for incoming data

      void init_udp(){

              sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

              if (sock < 0){

                      printf("ER UDP Socket error\n");

              }

              else printf("UP Socket %d OK\n",sock);

      }

       

       

      void write_udp(char *buf){

      // nmea data is in buff

              if (sock >= 0){

                      int on = 1;

                      setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on) );

                      struct sockaddr_in    address = {0};

                      address.sin_family = AF_INET;

                      address.sin_addr.s_addr = inet_addr( "255.255.255.255" ); //

                      address.sin_port = htons( PORT );

                      if ( sendto( sock, buf, strlen(buf), 0, (struct sockaddr*)&address, sizeof(address) ) < 0)

                           printf("ER UDP send error %i\n",errno);

                      else {

                           printf("UP %s\n",buf);

                      }

              }

      }

       

       

      int main(void){

          char local_buffer[100];

          sprintf(local_buffer,"Hello world!!");

          init_udp();

       

       

          write_udp(local_buffer);

       

       

          return 0;

      }

        • 1. Re: UDP broadcast from Edison to ESP8266s
          Intel Corporation
          This message was posted on behalf of Intel Corporation

          Hello Allen,

          Thanks for reaching out! 

          I don't have much experience in UDP programming (and I don't know if you do) but I believe the guide you shared assumes that you do. 

          So, what I would do in this situation is to take a step back to something simpler. The following guide is an introduction to UDP programming (that even a rookie like me can understand), it explains UDP programming step by step, so, it might be just what you need:

          https://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html

          I truly think it is very useful, so, I hope it helps.
          Let me know.
          -Peter.

          • 2. Re: UDP broadcast from Edison to ESP8266s
            Intel Corporation
            This message was posted on behalf of Intel Corporation

            Hello Allen,

            Do you have any updates about this?

            -Peter.

            • 3. Re: UDP broadcast from Edison to ESP8266s
              allene

              We did a couple of things to get this working. 

              1) We went to multi casting instead of broadcast

              2) The Edison was put in AP mode.  This is the critical thing.  You need a router function to make this work and the Edison provides this.

              systemctl stop wap_supplicant

              systemctl start hostapd

              3) We had to issue a command so that the Edison could find the router

              route add -net 224.0.0.0 netmask 224.0.0.0 wlan0

               

              Here is the code

              // UDP Transmitter

              // issue this command  route add -net 224.0.0.0 netmask 224.0.0.0 wlan0

               

               

              #include<stdio.h> //printf

              #include<string.h> //memset

              #include<stdlib.h> //exit(0);

              #include<arpa/inet.h>

              #include<sys/socket.h>

              #include<errno.h>

              volatile int sock;

              #define BUFLEN 512  //Max length of buffer

              #define PORT 12345   //The port on which to listen for incoming data

              void init_udp(){

                      sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

                      if (sock < 0){

                              printf("ER UDP Socket error\n");

                      }

                      else printf("UP Socket %d OK\n",sock);

              }

               

               

              void write_udp(char *buf){

              // nmea data is in buff

                int errno;

                      if (sock >= 0){

                              int on = 1;

                              int ret = setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on) );

                printf("return value is %d\n",ret);

                              struct sockaddr_in    address = {0};

                              address.sin_family = AF_INET;

                              address.sin_addr.s_addr = inet_addr( "224.0.0.251" ); //

                              address.sin_port = htons( PORT );

                              if ( sendto( sock, buf, strlen(buf), 0, (struct sockaddr*)&address, sizeof(address) ) < 0) {

                printf("ER UDP send error %d\n",errno);

                              }

                else {

                                   printf("UP %s\n",buf);

                              }

                      }

              }

               

               

              int main(void){

                  char local_buffer[100];

                  sprintf(local_buffer,"Hello world!!");

                  init_udp();

               

               

                  write_udp(local_buffer);

               

               

                  return 0;

              }

               

               

              And a receiver

               

              /* Receiver/client multicast Datagram example. */

                      // issue this command  route add -net 224.0.0.0 netmask 224.0.0.0 wlan0

                  #include <sys/types.h>

                  #include <string.h>

                  #include <sys/socket.h>

                  #include <arpa/inet.h>

                  #include <netinet/in.h>

                  #include <stdlib.h>

                  #include <stdio.h>

                  #include <fcntl.h> // for open

                  #include <unistd.h> // for close

               

               

                  struct sockaddr_in localSock;

                  struct ip_mreq group;

                  int sd;

                  int datalen;

                  char databuf[1024];

               

               

                  int main(int argc, char *argv[])

                  {

                  /* Create a datagram socket on which to receive. */

                  sd = socket(AF_INET, SOCK_DGRAM, 0);

                  if(sd < 0)

                  {

                  perror("Opening datagram socket error");

                  exit(1);

                  }

                  else

                  printf("Opening datagram socket....OK.\n");

               

               

                  /* Enable SO_REUSEADDR to allow multiple instances of this */

                  /* application to receive copies of the multicast datagrams. */

                  {

                  int reuse = 1;

                  if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) <

              0)

                  {

                  perror("Setting SO_REUSEADDR error");

                  close(sd);

                  exit(1);

                  }

                  else

                  printf("Setting SO_REUSEADDR...OK.\n");

                  }

               

               

                  /* Bind to the proper port number with the IP address */

                  /* specified as INADDR_ANY. */

                  memset((char *) &localSock, 0, sizeof(localSock));

                  localSock.sin_family = AF_INET;

                  localSock.sin_port = htons(12346);

                  localSock.sin_addr.s_addr = INADDR_ANY;

                  if(bind(sd, (struct sockaddr*)&localSock, sizeof(localSock)))

                  {

                  perror("Binding datagram socket error");

                  close(sd);

                  exit(1);

                  }

                  else

                  printf("Binding datagram socket...OK.\n");

               

               

                  /* Join the multicast group 226.1.1.1 on the local 203.106.93.94 */

                  /* interface. Note that this IP_ADD_MEMBERSHIP option must be */

                  /* called for each local interface over which the multicast */

                  /* datagrams are to be received. */

                  group.imr_multiaddr.s_addr = inet_addr("224.0.0.251");

                  //group.imr_interface.s_addr = inet_addr("192.168.0.15");

                      group.imr_interface.s_addr = INADDR_ANY;

               

               

                  if(setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(grou

              p)) < 0)

                  {

                  perror("Adding multicast group error");

                  close(sd);

                  exit(1);

                  }

                  else

                  printf("Adding multicast group...OK.\n");

                   for(;;) {

                  /* Read from the socket. */

                  datalen = sizeof(databuf);

                  if(read(sd, databuf, datalen) < 0)

                  {

                  perror("Reading datagram message error");

                  close(sd);

                  exit(1);

                  }

                  else

                  {

                  printf("Reading datagram message...OK.\n");

                  printf("The message from multicast server is: \"%s\"\n", databuf);

                  }

                      }

                  return 0;

                  }

              • 4. Re: UDP broadcast from Edison to ESP8266s
                Intel Corporation
                This message was posted on behalf of Intel Corporation

                Thanks a lot for sharing this information with the community, it will be of much help for future users that are trying to do similar things.
                 
                We appreciate your inputs and we hope to hear more from you.
                -Peter.