Table of Contents
The main data transmission protocol used in embeNET is UDP. Most application level communication is done using this protocol. In order to transmit and receive UDP data, the Nodes as well as the Border Router are expected to register UDP sockets, through which the communication will be carried. A socket is a logical endpoint in the networked device, that allows to easily dispatch network traffic to various services running in the device. We may think of the socket as a filter that selects only particular network traffic and feeds it into a software component (service) that owns the socket. Typically various services running in the node will use different ports and thus will register their own sockets. Such sockets will be used for transmitting and receiving data. In embeNET each socket is associated with a port number and may have three types of behavior concerning the way the receiving (destination) device is addressed.
In order to understand types of sockets in embeNET we first need to understand the IPv6 addressing principles employed in embeNET. There are basically two types of network traffic supported:
- unicast traffic, where we send the data to one particular destination node which is described by its own unicast address
- multicast traffic, where we send the data to a group of nodes using group addressing (Note, that each node may belong to none, one or more than one group, and the groups it belongs to may vary from node to node)
Apart from that, the traffic is directed to a given port number in the destination device. Thus the destination IPv6 address (unicast or multicast) and destination port identify the actual data recipient.
In embeNET we can register sockets that:
- receive only unicast traffic on the given port (EMBENET_UDP_TRAFFIC_UNICAST)
- receive only multicast (group) traffic on the given port for the single specific group (EMBENET_UDP_TRAFFIC_MULTICAST)
- receive all traffic (unicast or multicast) on the given port for all joined groups (EMBENET_UDP_TRAFFIC_ALL)
This type of socket behavior is defined during socket registration (see EMBENET_UDP_RegisterSocket). There is no way to change that behavior other than unregister the given socket and register another one.
Let's assume that we have a network with the network prefix set to 2001:0db8:0000:0000. Within that network there is a node with UID = 0000:0000:1234:5678 This node belongs to two groups number 12 and 15
In order to address this node using unicast addressing we should use an address constructed in the following way:
In order to address this node as a member of the group number 12 we should use an address constructed in the following way:
Let's register three sockets in this node - all of them on the same port number = 2222, so that:
- socket U will handle only unicast traffic (EMBENET_UDP_TRAFFIC_UNICAST)
- socket M will handle only multicast traffic for group 12 (EMBENET_UDP_TRAFFIC_MULTICAST)
- socket A will handle both unicast traffic and multicast traffic for all joined groups (EMBENET_UDP_TRAFFIC_ALL)
- if we send data to port 2222 using unicast addressing (unicastAddr - from the above example), our node will receive the same data on socket U and A
- if we send data to port 2222 using multicast addressing to group 12 (multicastAddr12 - from the above example), our node will receive the same data on socket M and A
- if we send data to port 2222 using multicast addressing to group 15 (multicastAddr15 - from the above example), our node will receive the same data only on socket A
Now let's explore some corner cases:
- if we register socket N handling multicast traffic to group 13 the socket will not receive any data until the node joins this group
- similarly, when the node will leave group 13, socket N will stop receiving data
- if there are more sockets registered on the same port, they also will receive data (data will be "duplicated" and fed to each socket)
Before using a socket we must register it through a call to EMBENET_UDP_RegisterSocket. This call takes a pointer to a EMBENET_UDP_SocketDescriptor structure that describes the socket. The following example shows how to register a socket that accepts all types of traffic.
In the above example the socket is created with a data reception function called 'receptionHandler'. This function may look like this:
This function will be called every time a UDP packet through a given socket.
In order to send some data through a registered socket a call to EMBENET_UDP_Send has to be made. The following example illustrates the data sending mechanism by sending 5 bytes ('Hello') through a registered socket to a destination port 2000 in the destination node described by an IPv6 address.
The EMBENET_UDP_Send schedules a single UDP datagram to be sent. This call does not provide any fragmentation capabilities. The maximum amount of data that can be sent by a single call to EMBENET_UDP_Send can be determined using EMBENET_UDP_GetMaxDataSize function:
Once the socket is not needed anymore it can be unregistered by a call to EMBENET_UDP_UnregisterSocket. The following code illustrates this idea:
Each socket can be assigned with a user defined pointer called userContext. This variable can point to any user-defined data to you want to bind with the socket. The intended use case is to pass a user context to the data reception handler. Below is an example. Let's assume that we want the reception handler to store the received value in a buffer, that will be set during socket registration:
We can register the socket with a user context pointing to that buffer
Now, when the receptionHandler is called, we can retrieve the buffer and use it:
Generated on Wed Feb 8 2023 19:52:39 for embeNET NODE by 1.9.3