This nRF UDP Server example shows the usage of Nordic's IPv6 Stack for sending and receiving UDP packets. The port numbers for transmitting and receiving UDP packets are configured in main.c
. The server responds to ICMPv6 Echo Requests and any received UDP packets are sent back to their source address without any modification. The operation of the application is reflected by two LEDs on the board. If UART trace is enabled, the sequence numbers of the received UDP packets are logged. For this feature to work, the payload of the received UDP packet is expected to have the following format:
Packet sequence number
in uint32 format (4 bytes) | 16 bytes of random data |
The UDP client could be a PC application communicating to the UDP server on the kit, as shown in Figure 1 below.
Figure 1: Setup of the Nordic's IPv6 stack based UDP server application.
Or, the UDP client could be the example client application included in the SDK sending requests to the server, as shown in Figure 2.
Figure 2: Setup of the Nordic's IPv6 stack based UDP client with UDP server application.
Figure 3 shows the application state diagram.
Figure 3: nRF UDP Server 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 UDP port configuration, see main.c
.
- Note
- This application needs a 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 nRF51 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 for LED blinks and one for initiating periodic echo requests. |
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_Server_Node', IPSP Service UUID is included in the UUID list. |
Scheduler | No | Scheduler is used for processing stack events. |
UART Trace | Included not enabled | Tracing is included but not enabled by default. |
Setup
The name of the example is iot_ipv6_udp_server. You can find the source code and project files of the examples in the following folder:
<InstallFolder>/Nordic/nrf51/examples/iot/udp/ipv6/server
LED assignments:
LED 1 | LED 2 | |
Blinking | Off | Device advertising as BLE peripheral. |
On | Blinking | BLE link established, IPv6 interface down. |
On | Off | BLE link established, IPv6 interface up. |
On | Two rapid flashes | Echo Request received and Echo Response is sent. |
Blinking | On | Receiving and immediately transmitting UDP packets. |
On | On | Assertion failure in the application. |
Testing
See Connecting devices to the router for a list of relevant Linux commands.
- Compile and program the application. Observe that the device is advertising.
- Prepare the Linux router device by initializing the 6LoWPAN module.
- Discover the advertising device by using the hcitool lescan command.
- Connect to the discovered device from the Linux console by using the Bluetooth 6LoWPAN connect command.
- Check if the connected state is reflected by the LEDs.
- Run the Wireshark or hcidump program to monitor the btX interface.
- 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.
- When sending Echo Requests or UDP packets to port number 0x1717 on the server, observe the LED light pattern as described in Setup. Send UDP packets to port number 0x1717 on the server and observe that packets are sent back.
- Note
- This example is designed to complement the Nordic UDP Client example, and they will work together provided that the Nordic UDP Client application is modified with the address of the server.
- Disconnect from the device by using the Bluetooth 6LoWPAN disconnect command.
- Observe that the device is advertising.
Python Client Example
Use the code below to start a simple Python client that sends UDP packets to port 0x1717, prints the sequence number from both transmitted and incoming packets and check if they are equal.
import socket
import struct
import random
#This example assumes the server BD address to be 00:AA:BB:CC:DD:EE and the global prefix used to be 2004::/64.
#Therefore, the global IPv6 address of the server will be 2004::02AA:BBFF:FECC:DDEE.
SERVER_ADDR = '2004::02AA:BBFF:FECC:DDEE'
#This example assumes that the global IPv6 address 2004::02AA:BBFF:FECC:DDEE is available on one of the network interfaces.
CLIENT_ADDR = '2004::02AA:BBFF:FECC:DDEE'
UDP_PORT = 0x1717
if __name__ == '__main__':
sequence_number = 0
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
client_addr = (CLIENT_ADDR, UDP_PORT)
sock.bind(client_addr)
while sequence_number < 101 :
sequence_number+= 1
data = struct.pack("I", sequence_number)
data += ''.join(chr(val) for val in [random.randint(0,0xFF) for r in xrange(16)])
sock.sendto(data, (SERVER_ADDR, UDP_PORT))
print 'Tx Sequence Number: ' + str(sequence_number)
recv_data = sock.recvfrom(8)
rx_sequence_number = struct.unpack("I", recv_data[0][:4])[0]
print 'Rx Sequence Number: ' + str(rx_sequence_number)
if sequence_number != rx_sequence_number:
print 'Sequence number mismatch!'
sock.close()
del sock
Troubleshooting Guide
- 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.
- If you observe that the packets from the client are received at the btX interface but the server 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
.
- In case the server 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.