0

Rewritten to try and be clear on what I need.

My goal is to duplicate the function of a device made by Digital Yacht in an embedded Intel Edison processor running C and Linux. The device sends via UDP to phone apps such as iRegatta and others. To set up the app, only the port number is entered. No ip address is entered in UDP mode on the app. I thought this was trivial but the experts here so far have said it is impossible so it must not be trivial. Perhaps that is why with all my hours of reading I cannot find an example. I am being voted down because, I am told, that what I am trying to do it impossible but it is not as it is done. I don't know how it is done, which is why I came to experts here.

I want to send nmea messages that might look like this:

$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47

and I want any number of random Android phones to be able to receive them with the appropriate app. There are many apps that can be set up to receive UDP data where you just specify a port number. There is no ip address involved in the setup of the apps. Also, I do not wish to receive anything from the Android phones. This is one way and no ability to re-transmit so if a message does not get there, it has another chance next time. Everything is updated once a second.

I tried the following and I do not get data in the app. From the comments, I must need to add some kind of router function in my Linux machine.

void init_udp(){
    return;
    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){
    return;
// 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( 3000 );
        if ( sendto( sock, buf, strlen(buf), 0, (struct sockaddr*)&address, sizeof(address) ) < 0) printf("ER UDP send error\n");
        else {
            printf("UP %s\n",buf);
        }
    }
}

I am not really sure what I need to do.

0andriy
  • 4,183
  • 1
  • 24
  • 37
Allen Edwards
  • 1,488
  • 1
  • 27
  • 44
  • I should add that I have read almost every SO posting on UDP as well as most Google hits. Nothing is this simple case with no ip addresses involved. So down vote me and say nothing. Geeze. I hope someone is more thoughtful and can help me out. – Allen Edwards Oct 08 '15 at 05:10
  • I see I am getting up votes and down votes. Net -1 now. Please be helpful. This is a valid question and I have researched it. Why is such a simple thing, sending UDP data to existing Android apps not just shown somewhere? You can see below that there is disagreement on how this should be done so why not clear up the confusion rather than down voting or just saying shouldn't do it this way? What way should I use? – Allen Edwards Oct 08 '15 at 14:48
  • 1
    You're getting downvoted because your question indicates you are confused at a fundamental level about how mobile phones talk to the Internet. It is *not possible* to send UDP messages to "any number of random Android phones", precisely *because* you do not know their IP addresses (and you can't know them -- they change constantly). – zwol Oct 08 '15 at 15:01
  • What you *probably* need to do is redesign your whatever-this-is from the ground up, such that the embedded device posts its status to a central server with a stable IP address and then each phone pings it at intervals; both would be best done using HTTPS, not raw UDP. But since you haven't explained your larger goals, that's the best I can do. – zwol Oct 08 '15 at 15:01
  • What can I say. There are commercial devices that do this. They talk over UDP to any number of phones. One app that works this way that I have is called iRegatta. One device that sends UDP this way is made by Digital Yacht. This is a boat, no router, no ip address entered on either device in UDP mode. I want to duplicate the function of this commercial device within my embedded device running C on Linux. It is an Intel Edison. – Allen Edwards Oct 08 '15 at 18:28
  • Run a packet capture on one of these commercial devices or apps. It is probably not doing what you think it is doing. Even if I'm wrong about that, the packet capture will probably offer some insights into exactly what you need to do to mimic it. – zwol Oct 08 '15 at 19:01

1 Answers1

2

What you want to do is send a UDP packet to a broadcast IP address. This will send to thing in the subnet. eg 10.255.255.255 is the broadcast address for the 10.x.x.x subnet. You can also use the global 255.255.255.255 which should also send to your subnet and no router is going to pass that on to another one these days.

Also you need to make your socket able to send broadcast messages. In particular you need the option SO_BROADCAST set. The following is specifically Windows because of the BOOL. Its presumably an int for most platforms.

BOOL on = TRUE;
setsockopt( sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on) );

Also you can't use send() for a UDP socket unless its "connected", so you should use sendto() and use the broadcast address.

To specify an address and port, use need to create a socket address.

struct sockaddr_in    address = {0};

address.sin_family = AF_INET;
address.sin_add.s_addr = inet_addr( "255.255.255.255" );
address.sin_port = htons( 3000 );

sendto( sock, buff, strlen(buff), 0, (struct sockaddr*)&address, sizeof(address) );

Note the use of the typecast. This is because sendto takes a sockaddr which is a generic address type, and here we are using an IPV4 address specifically. The sockaddr_in maps onto the sockaddr

waterjuice
  • 829
  • 5
  • 14
  • OK, need sendto(). Thanks, One of the SO posts suggested send() but I see from the man page that I was mistaken. But this is where I am confused. There is no router and no subnet. These are phones listening to the embedded Linux device. The thing I know I need to specify is a port, like maybe 3000. – Allen Edwards Oct 08 '15 at 05:33
  • 1
    shouldn't use broadcast anymore its not in ipv6 for a reason. use multicast. – WalterM Oct 08 '15 at 07:14
  • Two questions. 1) would not using multicast require the Android side to also be multicast aware. I have no control over that as they are not my apps. I just specify a port. 2) I have seen INADDR_ANY used as the address. I see in posts that this is sometimes recommended and other times saying it is obsolete because of ipv6. If it is not recommended to use broadcast and I do not know if the app is multicast capable, what does one do? – Allen Edwards Oct 08 '15 at 14:45
  • This approach only works if all of the phones are on the same subnet as the embedded Linux device, and you must also have configuration control over the router. – zwol Oct 08 '15 at 14:56
  • There is no router. It is just the embedded device talking to the app, which listens on a port. There are commercial devices that do what I am trying to add to my device (mine does a lot more). There is text in their literature that says "This innovative and cost effective wireless device creates its own 802.11b+g wireless access point which any other wireless device can connect to, such as a Smart Phone, Netbook or Laptop. " Here is their product page http://www.digitalyachtamerica.com/index.php/en/products/interfacing/nmea-to-wifi-adaptors/product/50-wln10-wireless-nmea-server-4800-baud. – Allen Edwards Oct 08 '15 at 17:15
  • @AllenEdwards Hmm. What you say suggests that the commercial device *is its own router* and has assigned (private-use, presumably) IP addresses to the phones in communication with it, and that (because everyone involved is on a boat) there's no link to the global Internet to confuse the issue. If all of the above is correct, then waterjuice's answer does tell you how to go about this -- but you also have to mimic the router/AP/DHCP functionality of the commercial device, so that you know all the phones *are* on the private-use subnet that you control. – zwol Oct 08 '15 at 19:06
  • Humm. I can't say I know what those devices do. I also don't know if they work while the phone is on the internet. I am trying to get the Android code from one of the developers. That might help to shed some light on what is going on. – Allen Edwards Oct 08 '15 at 23:37
  • This code, with the typo corrected, ran but the app did not get the data. I am still trying to get information from the developer of the app. – Allen Edwards Oct 09 '15 at 15:46