nRF51 IoT SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
Server

The CoAP server example application show the usage of Nordic's implementation of the CoAP protocol. The two supplied CoAP server examples have the same behavior, but use different IPv6 protocol stacks as UDP transport.

Both examples implement an endpoint that hosts the following resources:

    host
    |-- .well-known
    |   `-- core
    `-- lights
        |-- led3
        `-- led4

CoAP Server resources exposed by this application can be accessed by any CoAP Client provided the clients knows the server's IPv6 address.

Figure 1 shows a CoAP client in PC accessing the resources exposed by this application on CoAP.


CoAP_Server.svg
Figure 1: Setup of the CoAP server application.


Figure 2 shows LED control from a CoAP client example included in the SDK.


CoAP_Client_Server.svg
Figure 2: Setup of the CoAP client with Light server application.


Note
The figures above show one CoAP client controlling resources on the server. However, multiple CoAP clients could be communicating with these examples concurrently.

Configuration parameters for all used modules are defined and described in the sdk_config.h file, which is located in the main application folder.

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 nRF51 resources and common modules in the examples apart from the IoT 6lowpan and IPv6 stack library.

Module Inclusion/Usage Description
Timer 1 One timer is used for servicing the IoT timer.
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 'COAP_Server', 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

  • The example named iot_ipv6_coap_server uses Nordic's IPv6 stack. You can find the source code and project files of this example in the following folder:
    <InstallFolder>/Nordic/nrf51/examples/iot/coap/ipv6/server
  • The example named iot_lwip_coap_server uses the lwIP IPv6 stack. You can find the source code and project files of this example in the following folder:
    <InstallFolder>/Nordic/nrf51/examples/iot/coap/lwip/server

LED assignments:

  • The state of LED 3 and LED 4 can be set and queried via CoAP. Both are turned on in case of an assertion failure in the application.
  • LED 1 and LED 2 display the state of the application as described in the table below.
LED 1 LED 2
Blinking Off Device advertising as BLE peripheral.
On Blinking BLE link established, IPv6 interface down.
Off On BLE link established, IPv6 interface up.
On On Assertion failure in the application.

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 any CoAP client to interact with the application and set the states of LED 3 and LED 4. A freely available CoAP client implementation is the Mozilla Firefox browser with the Copper (Cu) CoAP user-agent add-on (Figure 3).
    Note
    This example is designed to complement the Nordic CoAP client example, and they will work together provided that the Nordic CoAP client application is modified with the server address.
  9. Disconnect from the device using Bluetooth 6LoWPAN disconnect command.
  10. Observe that the device is advertising.
copper_coap_client.png
Figure 3: Mozilla Firefox browser with the Copper (Cu) CoAP user-agent add-on.

Python Client Example

Below is a sample Python client that connects to the server application, sends 100 GET and PUT request for each LED resource, and exits. The server address used here is an example address and will need to be modified based on the server address of the nRF51 device that runs the server application.

Note
The CoAP protocol stack (aiocoap) used in this example needs at least Python version 3.4.
You can find the documentation for the aiocoap stack here: http://aiocoap.readthedocs.org/en/latest/index.html
The easiest way to run aiocoap without installing it is to clone the GIT repository from the project page and run the python script in the cloned directory.
import asyncio
from aiocoap import *
SERVER_ADDR = '2001:DB8::2AA:BBFF:FECC:DDEE'
SERVER_PORT = '5683'
SERVER_URI = 'coap://[' + SERVER_ADDR + ']:' + SERVER_PORT
@asyncio.coroutine
def main():
protocol = yield from Context.create_client_context()
sequence_number = 1
while sequence_number < 101:
request_led3 = Message(code=GET)
request_led3.set_request_uri(SERVER_URI + '/lights/led3')
request_led4 = Message(code=GET)
request_led4.set_request_uri(SERVER_URI + '/lights/led4')
response = yield from protocol.request(request_led3).response
print('State of LED 3: %s Response Code: %s\n'%(response.payload, response.code))
response = yield from protocol.request(request_led4).response
print('State of LED 4: %s Response Code: %s\n'%(response.payload, response.code))
print('Sending PUT request to change both leds state\n')
request_led3 = Message(code=PUT, payload=b'1' if sequence_number % 2 else b'0')
request_led3.set_request_uri(SERVER_URI + '/lights/led3')
request_led4 = Message(code=PUT, payload=b'0' if sequence_number % 2 else b'1')
request_led4.set_request_uri(SERVER_URI + '/lights/led4')
response = yield from protocol.request(request_led3).response
print('Server Response Code: %s\n'%(response.code))
response = yield from protocol.request(request_led4).response
print('Server Response Code: %s\n'%(response.code))
sequence_number += 1
if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())

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 CoAP server responses are received at the btX interface but the CoAP client device 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 CoAP client device is reachable, but the requests from the CoAP client device 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.