Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
New Contributor III
1,351 Views

UDP broadcast from Edison to ESP8266s

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:// 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:// 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 //printf

# include //memset

# include //exit(0);

# include

# include

# include

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;

}

Tags (1)
0 Kudos
4 Replies
Highlighted
Community Manager
29 Views

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.
0 Kudos
Highlighted
Community Manager
29 Views

Hello Allen,

 

 

Do you have any updates about this?

 

 

-Peter.
0 Kudos
Highlighted
New Contributor III
29 Views

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 //printf

# include //memset

# include //exit(0);

# include

# include

# include

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

# include

# include

# include

# include

# include

# include

# include // for open

# include // 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;

}

0 Kudos
Highlighted
Community Manager
29 Views

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.

 

0 Kudos