Register a handler for incoming data sent out on the local network via UDP
Device
Name | Type | Description |
---|---|---|
callback | Function |
Function to be called when a UDP packet is received
|
Nothing
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 |
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.
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;