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

Overview

This example demonstrates how the lwIP stack can be used on Nordic's 6lowpan interface to listen on a UDP port. Port number 9000 is used in this example. The UDP listen port is not bound to a particular address and therefore it is possible to send data to the port on a link-local or on global address(es).

UDP Request Format

In order to demonstrate data exchange on the UDP port, the application is designed to expect an 8-byte echo request in the following format from the UDP Client.

Field Sequence number in uint32 format 'P' 'i' 'n' 'g'
Size (octets) 4 (Network Order) 1 1 1 1

UDP Response Format

In response to a request from the client, this application responds back to request with a 8-byte response packet of following format:

Field Requested Sequence number in uint32 format 'P' 'o' 'n' 'g'
Size (octets) 4 (Network Order) 1 1 1 1

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


lwIP_UDP_Server.svg
Figure 1: Setup of the lwIP based IPv6 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.

lwIP_UDP_Client_Server.svg
Figure 2: Setup of the lwIP based IPv6 UDP client with UDP server application.


Common Modules Dependency and Usage

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

Module Inclusion/Usage Description
Timer 1 One timer is used to periodically service the lwIP with a 200 ms interval.
Button 0 No buttons are used in the example.
LEDs 2 LEDs are used to indicate the application states. See the LED assignment section.
Adv Data Encoder Yes The device name used is 'LwIPUDPServer', IPSP Service UUID is included in the UUID list.
Scheduler No Scheduler is not used for processing stack events.
UART Trace Included not enabledTracing is included but not enabled by default.
Note
The lwIP library used for this example is under BSD-style license; this is different from the Nordic SDK license. The license text can be found at <InstallFolder>external/lwip/license.txt

Setup

The name of the example is iot_lwip_udp_server. The source code and project file of the example can be found at: <InstallFolder>/examples/iot/udp/lwip/server

See below for a state diagram that describes the application states.

LwIP_UDP_ApplicationStateDiagram.png
Figure 3: Application State Diagram.

LED assignments

Application State LED 1 State LED 2 State
Idle OFF OFF
Advertising ON OFF
IPv6 Interface Up OFF ON
IPv6 Interface Down ON OFF
UDP Ping Refer to table below Refer to table below
ASSERT ON ON

By using the LEDs on the board, the remainder after division of the received Sequence number by 4 is displayed in the following manner.

Value Binary LED 1 State LED 2 State
0 00000000 OFF OFF
1 00000001 ON OFF
2 00000010 OFF ON
3 00000011 ON ON
Note
If commissioning is enabled, additional LED and Button assignments are made.
If the application asserts, it is halted.
This application is not power optimized!

Testing

See Connecting devices to the router for a list of relevant Linux commands.

  1. Compile and program the application. Observe that the advertising LED is lit. Ensure that the custom SoftDevice located at <InstallFolder>components/softdevice/s110_for_ipv6 is used.
  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. Now the advertising LED is turned off and the connected LED is lit.
  6. Run the Wireshark or hcidump program and observe the btX interface. Observe the periodic Neighbor Solicitation messages sent by the lwIP stack.
  7. An ICMP ping can be used on the link-local and on the global IPv6 address assigned to the device to ensure that the device is reachable.
    Note
    To find the global address, use the prefix assigned to the interface in Router Advertisement.
  8. Use a UDP client to send request packets as described in the section UDP Request Format to the global address of the nRF5x and UDP port number 9000. The UDP client application can be another nRF5x running the lwIP UDP Client application or a local UDP client that connects to the server and sends data to the application.
  9. Disconnect from device by using the Bluetooth 6LoWPAN disconnect command.
  10. Observe that only the advertising LED is lit.

Python Client Example

Below is a Python client example that connects to the server application, sends 100 ping requests and then exits. The server address used here is an example address and will need to be modified to the server address of the nRF5x that runs the lwIP UDP server application.

import socket
import struct
#This example assumes the server BD address to be 00:AA:BB:CC:DD:EE and global prefix used to be 2004::/64.
#Therefore global IPv6 address of the server will be 2004::02AA:BBFF:FECC:DDEE.
SERVER_ADDR = '2004::02AA:BBFF:FECC:DDEE'
SERVER_PORT = 9000
sequence_number = 1
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
while sequence_number < 101 :
data = struct.pack("!I", sequence_number)
data += 'Ping'
sock.sendto(data, (SERVER_ADDR, SERVER_PORT, 0, 0))
recv_data = sock.recvfrom(8)
print recv_data
rx_sequence_number = struct.unpack("!I", recv_data[0][:4])[0]
if sequence_number is not rx_sequence_number:
print "Sequence number mismatch!"
sequence_number+= 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. In case no global address is assigned to the nRF5x, the lwIP stack does not permit sending packets to a global address. This means that if a UDP request packet was received from a global address, the response will not be sent as there is no global address available for this application. This is usually detected with the ERR_RTE error code when calling the udp_sendto_ip6 API of lwIP stack in the application.
  3. If you observe that the client requests are initiated on Ethernet but not sent on the Bluetooth network interface to the nRF5x running the UDP Server, 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.