Files
openthread/examples/Makefile-simulation
T
Stuart Longland 98f930c793 [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.
2020-02-27 21:46:43 -08:00

334 lines
9.0 KiB
Plaintext

#
# Copyright (c) 2016, The OpenThread Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of the copyright holder nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Don't allow this top-level makefile's targets to be built in parallel.
.NOTPARALLEL:
COVERAGE ?= 0
DEBUG ?= 0
# Enable most features by default to cover most code
BORDER_AGENT ?= 1
BORDER_ROUTER ?= 1
COAP ?= 1
COAP_OBSERVE ?= 1
COAPS ?= 1
COMMISSIONER ?= 1
CHANNEL_MANAGER ?= 1
CHANNEL_MONITOR ?= 1
CHILD_SUPERVISION ?= 1
DHCP6_CLIENT ?= 1
DHCP6_SERVER ?= 1
DIAGNOSTIC ?= 1
DNS_CLIENT ?= 1
ECDSA ?= 1
IP6_FRAGM ?= 1
JAM_DETECTION ?= 1
JOINER ?= 1
LEGACY ?= 1
LINK_RAW ?= 1
MAC_FILTER ?= 1
MTD_NETDIAG ?= 1
REFERENCE_DEVICE ?= 1
SERVICE ?= 1
SNTP_CLIENT ?= 1
UDP_FORWARD ?= 1
COMMONCFLAGS := \
-g \
$(NULL)
# If the user has asserted COVERAGE, alter the configuration options
# accordingly.
configure_OPTIONS = \
--enable-cli \
--enable-ftd \
--enable-mtd \
--enable-ncp \
--enable-radio-only \
--with-examples=simulation \
$(NULL)
# Platform specific switches
ifneq ($(DEBUG),1)
COMMONCFLAGS += \
-O2 \
$(NULL)
endif
ifeq ($(NCP_SPI),1)
COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_SPI_ENABLE=1
else
COMMONCFLAGS += -DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1
endif # NCP_SPI == 1
ifeq ($(VIRTUAL_TIME),1)
COMMONCFLAGS += -DOPENTHREAD_SIMULATION_VIRTUAL_TIME=1
endif
ifeq ($(VIRTUAL_TIME_UART),1)
COMMONCFLAGS += -DOPENTHREAD_SIMULATION_VIRTUAL_TIME_UART=1
endif
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk
TopSourceDir := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))..
AbsTopSourceDir := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))..
CONFIG_FILE = OPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-simulation-config.h\"'
CONFIG_FILE_PATH = $(AbsTopSourceDir)/examples/platforms/simulation/
COMMONCFLAGS += \
-D$(CONFIG_FILE) \
-I$(CONFIG_FILE_PATH) \
CPPFLAGS += \
$(COMMONCFLAGS) \
$(NULL)
CFLAGS += \
$(COMMONCFLAGS) \
$(NULL)
CXXFLAGS += \
$(COMMONCFLAGS) \
$(NULL)
LDFLAGS += \
$(COMMONCFLAGS) \
$(NULL)
ECHO := @echo
INSTALL := /usr/bin/install
INSTALLFLAGS := -p
LN_S := ln -s
MAKE := make
MKDIR_P := mkdir -p
RM_F := rm -f
BuildJobs ?= 10
BuildPath = build
TopBuildDir = $(BuildPath)
AbsTopBuildDir = $(PWD)/$(TopBuildDir)
ResultPath = output
TopResultDir = $(ResultPath)
AbsTopResultDir = $(PWD)/$(TopResultDir)
TargetTuple = $(shell ${AbsTopSourceDir}/third_party/nlbuild-autotools/repo/third_party/autoconf/config.guess | sed -e 's/[[:digit:].]*$$//g')
ifndef BuildJobs
BuildJobs := $(shell getconf _NPROCESSORS_ONLN)
endif
JOBSFLAG := -j$(BuildJobs)
#
# configure-arch <target>
#
# Configure OpenThread for the specified target.
#
# target - The target to configure.
#
define configure-target
$(ECHO) " CONFIG $(1)..."
(cd $(BuildPath)/$(1) && $(AbsTopSourceDir)/configure \
INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" \
--prefix=/ \
--exec-prefix=/$(1) \
$(configure_OPTIONS))
endef # configure-target
#
# build-target <target>
#
# Build the OpenThread intermediate build products for the specified
# target.
#
# target - The target to build.
#
define build-target
$(ECHO) " BUILD $(1)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
all
endef # build-target
#
# check-target <target>
#
# Check (run unit tests) OpenThread for the specified target.
#
# target - The target to check.
#
define check-target
$(ECHO) " CHECK $(1)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
check
endef # check-target
#
# distcheck-target <target>
#
# Check (run unit tests) OpenThread for the specified target.
#
# target - The target to distcheck.
#
define distcheck-target
$(ECHO) " DISTCHECK $(1)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
distcheck
endef # distcheck-target
#
# coverage-target <target>
#
# Generate code coverage from unit tests for OpenThread for the
# specified target.
#
# target - The target to generate code coverage for.
#
define coverage-target
$(ECHO) " COVERAGE $(1)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
coverage
endef # coverage-target
#
# stage-target <target>
#
# Stage (install) the OpenThread final build products for the specified
# target.
#
# target - The target to stage.
#
define stage-target
$(ECHO) " STAGE $(1)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
DESTDIR=$(AbsTopResultDir) \
install
endef # stage-target
#
# TARGET_template <target>
#
# Define macros, targets and rules to configure, build, and stage
# OpenThread for a single target.
#
# target - The target to instantiate the template for.
#
define TARGET_template
CONFIGURE_TARGETS += configure-$(1)
BUILD_TARGETS += do-build-$(1)
CHECK_TARGETS += check-$(1)
DISTCHECK_TARGETS += distcheck-$(1)
COVERAGE_TARGETS += coverage-$(1)
STAGE_TARGETS += stage-$(1)
BUILD_DIRS += $(BuildPath)/$(1)
DIRECTORIES += $(BuildPath)/$(1)
configure-$(1): $(BuildPath)/$(1)/config.status
$(BuildPath)/$(1)/config.status: | $(BuildPath)/$(1)
$$(call configure-target,$(1))
do-build-$(1): configure-$(1)
do-build-$(1):
+$$(call build-target,$(1))
check-$(1): do-build-$(1)
check-$(1):
+$$(call check-target,$(1))
distcheck-$(1): do-build-$(1)
distcheck-$(1):
+$$(call distcheck-target,$(1))
coverage-$(1): do-build-$(1)
coverage-$(1):
+$$(call coverage-target,$(1))
stage-$(1): do-build-$(1)
stage-$(1): | $(TopResultDir)
$$(call stage-target,$(1))
$(1): stage-$(1)
endef # TARGET_template
.DEFAULT_GOAL := all
all: stage
# Instantiate an target-specific build template for the target.
$(eval $(call TARGET_template,$(TargetTuple)))
#
# Common / Finalization
#
configure: $(CONFIGURE_TARGETS)
build: $(BUILD_TARGETS)
check: $(CHECK_TARGETS)
distcheck: $(DISTCHECK_TARGETS)
coverage: $(COVERAGE_TARGETS)
stage: $(STAGE_TARGETS)
DIRECTORIES = $(TopResultDir) $(TopResultDir)/$(TargetTuple)/lib $(BUILD_DIRS)
CLEAN_DIRS = $(TopResultDir) $(BUILD_DIRS)
all: stage
$(DIRECTORIES):
$(ECHO) " MKDIR $@"
@$(MKDIR_P) "$@"
clean:
$(ECHO) " CLEAN"
@$(RM_F) -r $(CLEAN_DIRS)
help:
$(ECHO) "Simply type 'make -f $(firstword $(MAKEFILE_LIST))' to build OpenThread for the following "
$(ECHO) "target:"
$(ECHO) ""
$(ECHO) " $(TargetTuple)"
$(ECHO) ""