Skip to main content

udpsocket.onreceive(callback)

Register a handler for incoming data sent out on the local network via UDP

Availability

Device (from impOS™ 42)

Parameters

Name Type Description
callback Function Function to be called when a UDP packet is received

Returns

Nothing

Description

This is draft documentation which covers impOS™ functionality that, though currently in internal development, has been made available to a number of customers for testing purposes only. Both the functionality described here and the documentation itself are subject to change, including breaking changes, and may differ significantly from their final release versions.


This method registers a function that will be called whenever impOS™ receives a UDP datagram through the target socket.

If you registered such a function when you created the UDP socket with interface.openudp() then it isn’t necessary to call this method unless you wish to register a different callback or clear the registration and so stop receiving datagrams through the socket. In this last case, call the method with null as its argument.

Note If you register a new callback immediately after sending data (using udpsocket.send()) then there is a small window during which datagrams could be dropped. For this reason, you should either call updsocket.onreceive() before calling udpsocket.send(), or specify the receive callback and local port number in interface.openudp().

The function you pass into this method should have five parameters of its own:

Parameter Data Type Description
fromAddress String The address from which the datagram was received, in dotted quad IPv4 form, eg. "192.168.0.1"
fromPort Integer The port through which the datagram was sent
toAddress String The address for which the datagram was intended, or the network broadcast address, in dotted quad IPv4 form, eg. "192.168.0.2"
toPort Integer The port through which the datagram was received
data Blob The received data payload

IMPORTANT The addition of the toAddress and toPort parameters is a breaking change between impOS 41.2 and 41.3. You will need to update code that makes use of this method to set a data-received callback.

Note The callback will not be executed until the UDP socket has been bound to a local port. This is best ensured by passing a port number into interface.openudp() when you create the UDP socket, otherwise it will take place when data is first sent out through the socket.

The inclusion of the toAddress and toPort parameters allows your code to determine whether a received datagram is intended for the imp on which your code is running: either as a unicast targeting your imp or a broadcast targeting multiple devices on the local network. This is demonstrated in the example below.

Example

local udpsocket;
local interface;
local ucastIP;
local bcastIP;

function dataReceived(fromAddress, fromPort, toAddress, toPort, data) {
    // Check that we are the destination (unicast or broadcast)
    if (toAddress == ucastIP && fromPort == toPort) {
        // Log the receipt of data
        server.log("Was sent " + data.len() + "bytes from " + format("%s:%d", fromAddress, fromPort));

        // Echo it back
        udpsocket.send(fromAddress, fromPort, data);
    } else if (toAddress == bcastIP && fromPort == toPort) {
        server.log("Received broadcast from " + format("%s:%d", fromAddress, fromPort));

        // Echo it back
        local result = udpsocket.send(fromAddress, fromPort, data);
        if (result != 0) server.error("Could not send the data (code: " + result + ")");
    }  
}

function interfaceHandler(state) {
    if (state == imp.net.CONNECTED && udpsocket == null) {
        // We're connected, so initiate UDP
        udpsocket = interface.openudp(dataReceived, 1234);
    }

    if (state == imp.net.ETHERNET_STOPPED ||
        state == imp.net.ETHERNET_STOPPED_UNHAPPY ||
        state == imp.net.ETHERNET_STOPPED_NO_LINK ) {
            server.error("Ethernet error - closing UDP");
            if (udpsocket != null) {
                udpsocket.close();
                udpsocket = null;
            }
    }
}

// Set up a UDP echo server
// Get an interface object
interface = imp.net.open({"interface":"eth0"}, interfaceHandler);

// Get the imp's IP and the network broadcast IP
local i = imp.net.info();
ucastIP = i.ipv4.address;
bcastIP = i.ipv4.broadcast;