nRF5 IoT SDK  v0.9.0
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Client

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 to 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 in length 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 in length. When it becomes 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, the 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 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. This file is located in the config subfodler of 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.

Common module dependency and usage

This section summarizes the usage of nRF5x resources and common modules in the examples apart from the IoT 6lowpan and IPv6 stack library.

Module Inclusion/Usage Description
Timer 2 Two timers are used - one timer for LED blinks and one for time-out on the echo response.
Buttons 0 No buttons are used in this examples.
LEDs 4 LEDs are used to indicate the application states. See LED assignments section for details.
Adv Data Encoder Yes The device name used is 'UDP6_Client_Node', IPSP Service UUID is included in the UUID list.
Scheduler No Scheduler is used for processing stack events.
UART Trace Included not enabledTracing is included but not enabled by default.

Setup

You can find the source code and project files of the example in the following folder:
<InstallFolder>/examples/iot/udp/ipv6/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.
Note
If commissioning is enabled, additional LED and Button assignments are made.

Testing

See Connecting devices to the router 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 9000 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 complement 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 9000, 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 = 9000
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.