[coap] add support for RFC7641 (#4396)

* [coap] Add option scanning functions

In a few places in the OpenThread code-base, the following construct is
seen:

```
    otCoapOptionIterator iterator;
    otCoapOptionIteratorInit(&iterator, message);

    for (const otCoapOption *opt = otCoapOptionIteratorGetFirstOption(&iterator);
                             opt != NULL;
                             opt = otCoapOptionIteratorGetNextOption(&iterator))
    {
        if (opt->mNumber == OT_COAP_OPTION_DESIREDOPTION)
        {
            doSomethingWith(opt);
            break;
        }
    }
```

or its equivalent.  In cases where multiple options are sought, the
above is still the better approach (using a `switch` statement), but
otherwise this seems repetitive.

`otCoapOptionIteratorGetFirstOptionMatching` basically implements the
above loop, returning the first option that matches.  This same code can
also be used for testing for presence too by comparing the resultant
pointer to the `NULL` singleton.

For completeness in cases where a software developer may want to
*resume* looking for further matching options,
`otCoapOptionIteratorGetNextOptionMatching` is also provided.

* [coap] Add function for decoding Uint options

To properly implement features such as RFC7641 and RFC7959, one must be
able to decode unsigned integer options.  It seems silly to have an
encoder but not a decoder, so here is the missing piece.

Future considerations may be a `uint32_t` version since the majority of
use cases do not call for a `uint64_t`; the type was chosen since it was
the most general case.

* [coap] Reference the RFC for the Observe option.

For the sake of completeness, reference the relevant RFC in the
documentation so that developers can read up more on how it should work.

* [coap] Add mObserve flag to metadata.

When we're implementing observations, a few exceptions to the usual CoAP
conventions apply, notably:

- when we receive the initial reply, the request is _not_ finished, we
  will receive subsequent requests until we tell the server to stop.
- when we send a confirmable notification, the observing client will
  reply with an `ACK` with no further traffic: we need to differentiate
  this from an empty `ACK` to a request meaning we should expect a reply
  later.

While we could just repeatedly scan for the `Observe` option on the
request, that is wasteful in terms of processing time.  This allows us
to scan the request just once, and set a single-bit flag to save
processing later.

* [coap] Don't expect traffic after ACK to notification

If the client sends an empty `ACK` in reply to a confirmable RFC7641
notification, we will _NOT_ see further replies with additional
information.  Consider the notification as acknowledged and pass the
details back to the application.

* [coap] Pass through notifications to handler

Ensure that all notifications sent by the CoAP server are passed back to
the application's CoAP request handler.  When we receive the first one,
the request continues -- it does not finish until the server drops the
`Observe` flag or we tell the server to stop.

* [coap] Disable expiry timer once subscribed

If a request carries `Observe=0` and we receive the first reply, ignore
future time-out events as the transaction will finish only when
explicitly terminated.

* [coap] Support eager subscription cancellation

A CoAP client may signal its intention to unsubscribe from a resource by
sending a `GET` request with a token matching that of the original
request and setting the `Observe` option to the value 1.

In the event the application does this, we should pick this up and
cancel the pending transaction locally.  The handler will be notified of
this by a final call where `aError=OT_ERROR_NONE` and no message given.

* [cli] Add RFC7641 support to CLI example

As an aide to those developing code that uses RFC7641, implement an
example client and server that supports this feature.
17 files changed
tree: 9c127aff4eadf45ef534ecf13797ce3aeeae91d0
  1. .github/
  2. .travis/
  3. doc/
  4. etc/
  5. examples/
  6. include/
  7. script/
  8. src/
  9. tests/
  10. third_party/
  11. tools/
  12. .clang-format
  13. .codecov.yml
  14. .default-version
  15. .gitattributes
  16. .gitignore
  17. .gn
  18. .travis.yml
  19. Android.mk
  20. AUTHORS
  21. bootstrap
  22. BUILD.gn
  23. CMakeLists.txt
  24. CODE_OF_CONDUCT.md
  25. configure.ac
  26. CONTRIBUTING.md
  27. LICENSE
  28. Makefile.am
  29. NOTICE
  30. README.md
  31. STYLE_GUIDE.md
README.md

OpenThread Build Status Coverage Status Build Status


What is OpenThread?

OpenThread released by Google is...

...an open-source implementation of the Thread networking protocol. Google Nest has released OpenThread to make the technology used in Nest products more broadly available to developers to accelerate the development of products for the connected home.

...OS and platform agnostic, with a narrow platform abstraction layer and a small memory footprint, making it highly portable. It supports both system-on-chip (SoC) and network co-processor (NCP) designs.

...a Thread Certified Component, implementing all features defined in the Thread 1.1.1 specification, including all Thread networking layers (IPv6, 6LoWPAN, IEEE 802.15.4 with MAC security, Mesh Link Establishment, Mesh Routing) and device roles, as well as Border Router support.

More information about Thread can be found at threadgroup.org. Thread is a registered trademark of the Thread Group, Inc.

Who supports OpenThread?

Getting started

All end-user documentation and guides are located at openthread.io. If you're looking to do things like...

  • Learn more about OpenThread features and enhancements
  • Use OpenThread in your products
  • Learn how to build and configure a Thread network
  • Port OpenThread to a new platform
  • Build an application on top of OpenThread
  • Certify a product using OpenThread

...then openthread.io is the place for you.

Note: For users in China, end-user documentation is available at openthread.google.cn.

If you're interested in contributing to OpenThread, read on.

Contributing

We would love for you to contribute to OpenThread and help make it even better than it is today! See our Contributing Guidelines for more information.

Contributors are required to abide by our Code of Conduct and Coding Conventions and Style Guide.

Versioning

OpenThread follows the Semantic Versioning guidelines for release cycle transparency and to maintain backwards compatibility. OpenThread's versioning is independent of the Thread protocol specification version but will clearly indicate which version of the specification it currently supports.

License

OpenThread is released under the BSD 3-Clause license. See the LICENSE file for more information.

Please only use the OpenThread name and marks when accurately referencing this software distribution. Do not use the marks in a way that suggests you are endorsed by or otherwise affiliated with Nest, Google, or The Thread Group.

Need help?

There are numerous avenues for OpenThread support:

The openthread-users Google Group is the recommended place for users to discuss OpenThread and interact directly with the OpenThread team.