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

The CoAP client example application show the usage of Nordic's implementation of the CoAP protocol. The two supplied CoAP client examples have the same behavior, but use different IPv6 protocol stacks as UDP transport. This example application, although referred to as CoAP client, is technically an example of concurrent CoAP Client and Server implementation. This application as CoAP Client, sends LED state control requests to the Light Server Example application, as demonstrated in Figure 1.


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


Additionally, as a CoAP Server, temperature is exposed as a resource that can be GET and PUT from the CoAP client on the PC and shown in Figure 2.


CoAP_Client.svg
Figure 2: Setup of the CoAP client application


These examples are designed to complement the CoAP server example applications. The server is identified by its IPv6 address, which needs to be configured in main.c.
The client examples also implement an endpoint that hosts the following resources:

    host
    |-- .well-known
    |   `-- core
    `-- sensors
        `-- thermometer

The thermometer resource simply stores an integer value between -100 and +100, to demonstrate that the device can be set up to work as a CoAP client and server concurrently.
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.

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 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 for IoT timer and the other for the button module.
Buttons 2 Buttons are used for initiating CoAP requests. See Button assignments section for details.
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_Client', 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_client uses Nordic's IPv6 stack. You can find the source code and project files for this example in the following folder:
    <InstallFolder>/examples/iot/coap/ipv6/client
  • The example named iot_lwip_coap_client uses the lwIP IPv6 stack. You can find the source code and project files for this example in the following folder:
    <InstallFolder>/examples/iot/coap/lwip/client

LED assignments:

  • After sending a CoAP request by pressing either Button 1 or Button 2, LED 3 blinks once if the received response code is "2.04 - Changed", as expected. LED 4 blinks once if any other response code is received. 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.

Button assignments:

  • Button 1: send a CoAP request to the peer running the CoAP server example to toggle LED 3.
  • Button 2: send a CoAP request to the peer running the CoAP server example to toggle LED 4.
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. As a CoAP client, this application can be used to toggle LED 3 and LED 4 on a peer running the CoAP server example.
  9. Press Button 1, to toggle LED 3 state.
  10. Press Button 2, to toggle LED 4 state.
  11. Use any CoAP client to interact with the application and get or set the value of the thermometer resource. A freely available CoAP client implementation is the Mozilla Firefox browser with the Copper (Cu) CoAP user-agent add-on.
  12. Disconnect from the device using the Bluetooth 6LoWPAN disconnect command.
  13. Observe that the device is advertising.

Python Server Example

Below is a Python CoAP Server example that listens on the default CoAP Port (5683). It is triggered by pushing Button 1 and Button 2 on the nRF5x kit, and writes relative output to the console. The server address used in main.c of the example must be modified based on the server address of the btX interface.

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 logging
import asyncio
import aiocoap.resource as resource
import aiocoap
logging.basicConfig(level=logging.INFO)
logging.getLogger("coap-server").setLevel(logging.DEBUG)
class LedResource(resource.Resource):
def __init__(self):
resource.Resource.__init__(self)
self.visible = True
self.observable = False
@asyncio.coroutine
def render_put(self, request):
print('Led %s has been inverted'%(request.get_request_uri()[-4:]))
return aiocoap.Message(code=aiocoap.CHANGED)
def main():
root = resource.Site()
root.add_resource(('lights', 'led3'), LedResource())
root.add_resource(('lights', 'led4'), LedResource())
asyncio.async(aiocoap.Context.create_server_context(root))
asyncio.get_event_loop().run_forever()
if __name__ == "__main__":
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.