This information applies to the following SoftDevices: S132, S140
The CoAP observable server example application shows the usage of Nordic's implementation of the CoAP protocol. The two supplied CoAP observable 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
CoAP server resources exposed by this application can be accessed by any CoAP Client provided that the client knows the server's IPv6 address. In addition, the lights/led3 resource on the server is observable, so that any client with observe support can get continuous notifications of change in state of the observable resource. These examples are designed to complement the Observer Client applications.
Figure 1 shows a CoAP client in PC accessing the resources exposed by this application on CoAP.
Figure 1: Setup of the CoAP server application.
Figure 2 shows LED observation from a CoAP observe client example included in the SDK.
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 is not power optimized!
-
This application will start advertising again after disconnection.
Common module dependency and usage
This section summarizes the usage of nRF5 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. |
Adv Data Encoder | Yes | The device name used is 'COAP_ServerObs'. IPSP Service UUID is included in the UUID list. |
Scheduler | Yes | Scheduler is used for processing stack events. |
Setup
- Example that uses Nordic's IPv6 stack: You can find the source code and the project file of the example in the following folder:
<InstallFolder>\examples\iot\coap\ipv6\server_observe
- Example that uses the lwIP IPv6 stack: You can find the source code and the project file of the example in the following folder:
<InstallFolder>\examples\iot\coap\lwip\server_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. |
- The state of LED 3 can be set and queried via CoAP through the observable resource lights/led3. It will be turned on in case of an assertion failure in the application.
- LED 4 has no function. It will be turned on in case of an assertion failure in the application.
Button assignments:
- Button 1: Toggle state of the observable resource lights/led3.
- 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.
- 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.
- Use any CoAP client to interact with the application and read the states of LED 3. A freely available CoAP client implementation is the Mozilla Firefox browser with the Copper (Cu) CoAP user-agent add-on (Figure 3). Enable subscription to the observable resource by selecting the lights/led3 resource and click on the green "Observe" button in the Copper plugin menu.
- Note
- A global address is necessary to test the example with Copper (Cu). Link-local addresses (FE80::) cannot be resolved in the browser as they are not bound to a specific interface.
-
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.
- Press Button 1 on the device in order to toggle LED 3. The device should now send a notification to the observer with the new state. The value 0 means that LED 3 is off, while value 1 means that it is on.
- Unsubscribe to the notifications from the observable resource by pressing the "Cancel" button in the Copper plugin menu.
- Enable the "Debug Control" checkbox on the right side in the Copper plugin menu, and select "Accept"->"application/json".
- Resubscribe to the observable resource by selecting "Observe" in the Copper plugin menu. The value should now be represented in JSON format instead of plain text (Figure 4).
Figure 3: Mozilla Firefox browser with the Copper (Cu) CoAP user-agent add-on.
Figure 4: Mozilla Firefox browser with the Copper (Cu) CoAP user-agent add-on subscribing using JSON format.
Python Client Example
Below is a sample Python client that connects to the server application, sends a GET request with Observe option for the /lights/led3 resource, and listens for changes. The server address used here is an example address and will need to be modified based on the server address of the nRF5x 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 at 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 nRF5 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 asyncio
from aiocoap import *
SERVER_ADDR = '2001:DB8::2AA:BBFF:FECC:DDEE'
SERVER_PORT = '5683'
SERVER_URI = 'coap://[' + SERVER_ADDR + ']:' + SERVER_PORT
def observe_handle(response):
if response.code.is_successful():
print('State of LED3: %s Response Code: %s'%(response.payload, response.code))
else:
print('Error code %s' % response.code)
@asyncio.coroutine
def main():
protocol = yield from Context.create_client_context()
request = Message(code=GET)
request.set_request_uri(SERVER_URI + '/lights/led3')
request.opt.observe = 0
observation_is_over = asyncio.Future()
try:
requester = protocol.request(request)
response = yield from requester.response
exit_reason = yield from observation_is_over
print('Observation is over: %r' % exit_reason)
finally:
if not requester.response.done():
requester.response.cancel()
if not requester.observation.cancelled:
requester.observation.cancel()
if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
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 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
.
- 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.