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

The CoAP observe 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.

These examples are designed to complement the Observable Server applications.

Figure 1 shows LED observation from a CoAP observe client example included in the SDK.


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


These examples are designed to complement the CoAP observable server example applications. The server is identified by its IPv6 address, which needs to be configured in main.c.

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 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 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_Obs', 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_observe uses Nordic's IPv6 stack. You can find the source code and project files for this example in the following folder:
    <InstallFolder>/Nordic/nrf51/examples/iot/coap/ipv6/client_observe
  • The example named iot_lwip_coap_client_observe uses the lwIP IPv6 stack. You can find the source code and project files for this example in the following folder:
    <InstallFolder>/Nordic/nrf51/examples/iot/coap/lwip/client_observe

LED assignments:

  • 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.
  • LED 3 shows the latest state of the observable resource lights/led3 in the peer running the CoAP observable server. It will be turned on in case of an assertion failure in the application.
  • LED 4 show whether the CoAP observer client is receiving notifications from the observable server. It will be turned on in case of an assertion failure in the application.

Button assignments:

  • Button 1: send a CoAP GET request with an observe option set to 0 to the peer running the CoAP observable server example in order to register as observer to the observable resource lights/led3.
  • Button 2: send a CoAP GET request with an observe option set to 1 to the peer running the CoAP observable server example in order to unregister as observer.

Test

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 observe client, this application can be used to observe LED 3 on a peer running the CoAP observable server example. Press Button 1, in order to initiate observation of the peer observable resource.
  9. Observe that LED 4 is lid. This indicates that observation is ongoing, and the observer client will receive any change in state of the observable resource from the CoAP observable server example.
  10. Toggle the state of the observable resource on the peer running the CoAP observable server example, by using the buttons or with a seperate CoAP Client. A freely available CoAP client implementation is the Mozilla Firefox browser with the Copper (Cu) CoAP user-agent add-on.
  11. Observe that LED 3 on the CoAP observe client toggles according to the state shown on LED 3 on the peer CoAP observable server.
  12. Unregister the observer by pressing Button 2 on the CoAP observable client. Observe that LED 4 turns off.
  13. Disconnect from the device using the Bluetooth 6LoWPAN disconnect command.
  14. Observe that the device is advertising.

Python Server Example

Below is a Python CoAP Server example that listens on the default CoAP Port (5683). After nRF51 kit sends GET request with Observe option to /lights/led3 resource, python server sends notification with 3 seconds interval. 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.
Current version of aiocoap does not implement Max-Age option, which may cause the client running on the nRF51 to invalidate the peer-server and remove the matching rule if no notifications are received within 60 seconds (default Max-Age value if the option is omitted).
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.ObservableResource):
# State of LED3
led3_state = b'0'
def __init__(self):
super(LedResource, self).__init__()
self.notify()
def notify(self):
self.led3_state = b'1' if self.led3_state == b'0' else b'0'
self.updated_state()
asyncio.get_event_loop().call_later(3, self.notify)
@asyncio.coroutine
def render_get(self, request):
print('State of LED3: %s', self.led3_state)
return aiocoap.Message(code=aiocoap.CONTENT, payload=self.led3_state)
def main():
root = resource.Site()
root.add_resource(('lights', 'led3'), 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 observe 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 observe client device is reachable, but the requests from the CoAP observe 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.