nRF51 IoT SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Nordic's IPv6 Stack Based UDP Client Application

This nRF UDP Client example shows the usage of Nordic's IPv6 Stack for sending and receiving UDP packets. The server is identified by its IPv6 address, which needs be configured in main.c. The client application sends ICMPv6 Echo Requests to the server to determine whether it is reachable or not. Once an Echo Response is received, the application starts to send UDP packets to the peer. The port numbers for transmitting and receiving UDP packets are also configured in main.c. The payload of the UDP packets is 20 bytes long and has the following format:

Packet sequence number
in uint32 format (4 bytes)
16 bytes of random data

Each transmitted packet is stored until it is received back or until the buffer is full. The buffer of transmitted packets is of PACKET_BUFFER_LEN long. When it gets full, the transmission of UDP packets stops and the buffer is emptied. The packet sequence number is set to zero. Echo Requests are sent to the server to determine if it is reachable. When an Echo Response is received, transmission of UDP packets starts again. The operation of the application is reflected by two LEDs on the board.

The UDP server could be a PC application communicating to the UDP client on the kit as shown in Figure 1 below.


nRF_UDP_Client.svg
Figure 1: Setup of the Nordic's IPv6 stack based UDP client application.


Or, the UDP server could be the example server application included in the SDK responding to requests from this example application in Figure 2.

nRF_UDP_Client_Server.svg
Figure 2: Setup of the Nordic's IPv6 stack based UDP client with UDP server application.


Figure 3 shows the application state diagram.

Nordic_UDP_Example_Client.png
Figure 3: nRF UDP Client state diagram.

Configuration parameters for all used modules are defined and described in the sdk_config.h file, which is located in the main application folder. For the server address and UDP port configuration, see main.c.

Note
This application needs custom SoftDevice for IPv6.
This application is not power optimized!
This application will start advertising again after disconnection.

Setup

The name of this example is nrf_udp_client. You can find the source code and project files of the example in the following folder:
<InstallFolder>/Nordic/nrf51/examples/iot/nrf_udp_client

LED assignments:

LED 1 LED 2
Blinking Off Device advertising as BLE peripheral.
On Off BLE link established, IPv6 interface down.
On Blinking IPv6 interface up, Echo Requests are sent to the Server.
Blinking On UDP packets are sent to the Server.
On On Assertion failure in the application.

Testing

See Linux commands for 6LoWPAN for a list of relevant Linux commands.

  1. Compile and program the application. Observe that the device is advertising.
  2. Prepare the Linux router device by initializing the 6LoWPAN module.
  3. Discover the advertising device by using the hcitool lescan command.
  4. Connect to the discovered device from the Linux console by using the Bluetooth 6LoWPAN connect command.
  5. Check if the connected state is reflected by the LEDs.
  6. Run the Wireshark or hcidump program to monitor the btX interface.
  7. An ICMPv6 ping can be used on the link-local and on the global IPv6 address assigned to the device to check if the device is reachable.
    Note
    To find the global address, use the prefix assigned to the interface in Router Advertisement.
  8. Use a UDP server to listen on UDP port number 0x1717 and observe that the packets from the client are received in the format as described above. When sending back a packet with the same payload, observe the LED light pattern as described in Setup.
    Note
    This example is designed to compliment the Nordic UDP Server example, and they will work together provided that this application is modified with the servers address.
  9. Disconnect from the device using the Bluetooth 6LoWPAN disconnect command.
  10. Observe that the device is advertising.

Python Server Example

Use the code below to start a simple Python server that listens on port 0x1717, prints the sequence number from incoming packets and transmits them back to the sender.

import socket
import struct
#This example assumes that the global IPv6 address 2004::02AA:BBFF:FECC:DDEE is available on one of the network interfaces.
SERVER_ADDR = '2004::02AA:BBFF:FECC:DDEE'
UDP_PORT = 0x1717
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
server_addr = (SERVER_ADDR, UDP_PORT)
sock.bind(server_addr)
while 1 :
recv_data = sock.recvfrom(8)
print recv_data
rx_sequence_number = 0
rx_sequence_number = struct.unpack("!I", recv_data[0][:4])[0]
print ("Rx Sequence Number %08x" % rx_sequence_number)
data = recv_data[0]
sock.sendto(data, recv_data[1])
sock.close()
del sock

Troubleshooting Guide

  1. It is possible that the global address is not immediately available on the connection as the Neighbor Discovery, Router Advertisement, and Duplicate Address Detection procedures take a few seconds to complete.
  2. If you observe that the server responses are received at the btX interface but the client never receives them, it is possible that the forwarding between networks is not enabled. This can be done on Linux using the command sysctl -w net.ipv6.conf.all.forwarding=1.
  3. In case the client is reachable, but the Echo Requests from the client do not make it to the Server, it is possible that the application is not configured with the correct remote server address. Verify that the address SERVER_IPV6_ADDRESS in the client application matches the server address.