UDP

UDP datagrams are the fundamental messaging abstraction provided to applications. Protocols may wire below this layer to send raw IP datagrams. The sockaddr structure is used for addressing, while the inet6_aton function may be used to fill in an IPv6 address from its string representation.

/*
 * the address of a socket endpoint
 */
struct sockaddr {
  uint16_t sin_port;
  ip6_addr_t sin_addr;
};

/*
 * friendly representation of an IP address
 */
void inet6_aton(char *addr, ip6_addr_t dest);

Interface

The UDP interface contains one command and one event. The buffer contract is such that a command or event never implies a transfer of control of the buffer in question; following the send call, the application can immediatly reuse the payload buffer, while following the receive call, the application has no claim to the payload. This interface eliminates the buffer management complexity which the first release had.

interface UDP {
  command error_t sendto(struct sockaddr_in6 *dest, void *payload,
                         uint16_t len);
  event void recvfrom(struct sockaddr_in6 *src, void *payload,
                      uint16_t len, struct ip_metadata *meta);
}

The struct ip_metadata is defined ip.h and allows an application inspect the L2 sender, and link RSSI and CCI values if available.

An Example: UDP Echo

Because of the buffer semantics, it is safe to call send directly from a receive event handler.

  event void Echo.recvfrom(struct sockaddr_in6 *from, void *data,
                           uint16_t len, struct ip_metadata *meta) {
    call Echo.sendto(from, data, len);
  }

The wiring is as follows. Every UDP component must bind a local port, and the parameterized interface implicitly binds all local addresses of the mote. By default, the mote binds the link local address (ff02::), a global address (if available), and local multicast groups (ff02::1 and ff02::2).

  components IPDispatchC;
  UDPEchoP.Echo -> IPDispatchC.UDP[7];