Add a note to the access randomization feature that reordering can happen and what should be done to avoid it. Signed-off-by: Pavel Vasilyev <pavel.vasilyev@nordicsemi.no>
276 lines
13 KiB
ReStructuredText
276 lines
13 KiB
ReStructuredText
.. _bluetooth_mesh_access:
|
|
|
|
Access layer
|
|
############
|
|
|
|
The access layer is the application's interface to the Bluetooth Mesh network.
|
|
The access layer provides mechanisms for compartmentalizing the node behavior
|
|
into elements and models, which are implemented by the application.
|
|
|
|
Mesh models
|
|
***********
|
|
|
|
The functionality of a mesh node is represented by models. A model implements
|
|
a single behavior the node supports, like being a light, a sensor or a
|
|
thermostat. The mesh models are grouped into *elements*. Each element is
|
|
assigned its own unicast address, and may only contain one of each type of
|
|
model. Conventionally, each element represents a single aspect of the mesh
|
|
node behavior. For instance, a node that contains a sensor, two lights and a
|
|
power outlet would spread this functionality across four elements, with each
|
|
element instantiating all the models required for a single aspect of the
|
|
supported behavior.
|
|
|
|
The node's element and model structure is specified in the node composition
|
|
data, which is passed to :c:func:`bt_mesh_init` during initialization. The
|
|
Bluetooth SIG have defined a set of foundation models (see
|
|
:ref:`bluetooth_mesh_models`) and a set of models for implementing common
|
|
behavior in the `Bluetooth Mesh Model Specification
|
|
<https://www.bluetooth.com/specifications/mesh-specifications/>`_. All models
|
|
not specified by the Bluetooth SIG are vendor models, and must be tied to a
|
|
Company ID.
|
|
|
|
Mesh models have several parameters that can be configured either through
|
|
initialization of the mesh stack or with the
|
|
:ref:`bluetooth_mesh_models_cfg_srv`:
|
|
|
|
Opcode list
|
|
===========
|
|
|
|
The opcode list contains all message opcodes the model can receive, as well as
|
|
the minimum acceptable payload length and the callback to pass them to. Models
|
|
can support any number of opcodes, but each opcode can only be listed by one
|
|
model in each element.
|
|
|
|
The full opcode list must be passed to the model structure in the composition
|
|
data, and cannot be changed at runtime. The end of the opcode list is
|
|
determined by the special :c:macro:`BT_MESH_MODEL_OP_END` entry. This entry
|
|
must always be present in the opcode list, unless the list is empty. In that
|
|
case, :c:macro:`BT_MESH_MODEL_NO_OPS` should be used in place of a proper
|
|
opcode list definition.
|
|
|
|
AppKey list
|
|
===========
|
|
|
|
The AppKey list contains all the application keys the model can receive
|
|
messages on. Only messages encrypted with application keys in the AppKey list
|
|
will be passed to the model.
|
|
|
|
The maximum number of supported application keys each model can hold is
|
|
configured with the :kconfig:option:`CONFIG_BT_MESH_MODEL_KEY_COUNT` configuration
|
|
option. The contents of the AppKey list is managed by the
|
|
:ref:`bluetooth_mesh_models_cfg_srv`.
|
|
|
|
Subscription list
|
|
=================
|
|
|
|
A model will process all messages addressed to the unicast address of their
|
|
element (given that the utilized application key is present in the AppKey
|
|
list). Additionally, the model will process packets addressed to any group or
|
|
virtual address in its subscription list. This allows nodes to address
|
|
multiple nodes throughout the mesh network with a single message.
|
|
|
|
The maximum number of supported addresses in the Subscription list each model
|
|
can hold is configured with the :kconfig:option:`CONFIG_BT_MESH_MODEL_GROUP_COUNT`
|
|
configuration option. The contents of the subscription list is managed by the
|
|
:ref:`bluetooth_mesh_models_cfg_srv`.
|
|
|
|
Model publication
|
|
=================
|
|
|
|
The models may send messages in two ways:
|
|
|
|
* By specifying a set of message parameters in a :c:struct:`bt_mesh_msg_ctx`,
|
|
and calling :c:func:`bt_mesh_model_send`.
|
|
* By setting up a :c:struct:`bt_mesh_model_pub` structure and calling
|
|
:c:func:`bt_mesh_model_publish`.
|
|
|
|
When publishing messages with :c:func:`bt_mesh_model_publish`, the model
|
|
will use the publication parameters configured by the
|
|
:ref:`bluetooth_mesh_models_cfg_srv`. This is the recommended way to send
|
|
unprompted model messages, as it passes the responsibility of selecting
|
|
message parameters to the network administrator, which likely knows more about
|
|
the mesh network than the individual nodes will.
|
|
|
|
To support publishing with the publication parameters, the model must allocate
|
|
a packet buffer for publishing, and pass it to
|
|
:c:member:`bt_mesh_model_pub.msg`. The Config Server may also set up period
|
|
publication for the publication message. To support this, the model must
|
|
populate the :c:member:`bt_mesh_model_pub.update` callback. The
|
|
:c:member:`bt_mesh_model_pub.update` callback will be called right before the
|
|
message is published, allowing the model to change the payload to reflect its
|
|
current state.
|
|
|
|
By setting :c:member:`bt_mesh_model_pub.retr_update` to 1, the model can
|
|
configure the :c:member:`bt_mesh_model_pub.update` callback to be triggered
|
|
on every retransmission. This can, for example, be used by models that make
|
|
use of a Delay parameter, which can be adjusted for every retransmission.
|
|
The :c:func:`bt_mesh_model_pub_is_retransmission` function can be
|
|
used to differentiate a first publication and a retransmission.
|
|
The :c:macro:`BT_MESH_PUB_MSG_TOTAL` and :c:macro:`BT_MESH_PUB_MSG_NUM` macros
|
|
can be used to return total number of transmissions and the retransmission
|
|
number within one publication interval.
|
|
|
|
Extended models
|
|
===============
|
|
|
|
The Bluetooth Mesh specification allows the mesh models to extend each other.
|
|
When a model extends another, it inherits that model's functionality, and
|
|
extension can be used to construct complex models out of simple ones,
|
|
leveraging the existing model functionality to avoid defining new opcodes.
|
|
Models may extend any number of models, from any element. When one model
|
|
extends another in the same element, the two models will share subscription
|
|
lists. The mesh stack implements this by merging the subscription lists of the
|
|
two models into one, combining the number of subscriptions the models can have
|
|
in total. Models may extend models that extend others, creating an "extension
|
|
tree". All models in an extension tree share a single subscription list per
|
|
element it spans.
|
|
|
|
Model extensions are done by calling :c:func:`bt_mesh_model_extend` during
|
|
initialization. A model can only be extended by one other model, and
|
|
extensions cannot be circular. Note that binding of node states and other
|
|
relationships between the models must be defined by the model implementations.
|
|
|
|
The model extension concept adds some overhead in the access layer packet
|
|
processing, and must be explicitly enabled with
|
|
:kconfig:option:`CONFIG_BT_MESH_MODEL_EXTENSIONS` to have any effect.
|
|
|
|
Model data storage
|
|
==================
|
|
|
|
Mesh models may have data associated with each model instance that needs to be
|
|
stored persistently. The access API provides a mechanism for storing this
|
|
data, leveraging the internal model instance encoding scheme. Models can store
|
|
one user defined data entry per instance by calling
|
|
:c:func:`bt_mesh_model_data_store`. To be able to read out the data the
|
|
next time the device reboots, the model's
|
|
:c:member:`bt_mesh_model_cb.settings_set` callback must be populated. This
|
|
callback gets called when model specific data is found in the persistent
|
|
storage. The model can retrieve the data by calling the ``read_cb`` passed as
|
|
a parameter to the callback. See the :ref:`settings_api` module documentation for
|
|
details.
|
|
|
|
When model data changes frequently, storing it on every change may lead to
|
|
increased wear of flash. To reduce the wear, the model can postpone storing of
|
|
data by calling :c:func:`bt_mesh_model_data_store_schedule`. The stack will
|
|
schedule a work item with delay defined by the
|
|
:kconfig:option:`CONFIG_BT_MESH_STORE_TIMEOUT` option. When the work item is
|
|
running, the stack will call the :c:member:`bt_mesh_model_cb.pending_store`
|
|
callback for every model that has requested storing of data. The model can
|
|
then call :c:func:`bt_mesh_model_data_store` to store the data.
|
|
|
|
If :kconfig:option:`CONFIG_BT_MESH_SETTINGS_WORKQ` is enabled, the
|
|
:c:member:`bt_mesh_model_cb.pending_store` callback is called from a dedicated
|
|
thread. This allows the stack to process other incoming and outgoing messages
|
|
while model data is being stored. It is recommended to use this option and the
|
|
:c:func:`bt_mesh_model_data_store_schedule` function when large amount of data
|
|
needs to be stored.
|
|
|
|
Composition Data
|
|
================
|
|
|
|
The Composition Data provides information about a mesh device.
|
|
A device's Composition Data holds information about the elements on the
|
|
device, the models that it supports, and other features. The Composition
|
|
Data is split into different pages, where each page contains specific feature
|
|
information about the device. In order to access this information, the user
|
|
may use the :ref:`bluetooth_mesh_models_cfg_srv` model or, if supported,
|
|
the :ref:`bluetooth_mesh_lcd_srv` model.
|
|
|
|
Composition Data Page 0
|
|
-----------------------
|
|
|
|
Composition Data Page 0 provides the fundamental information about a device, and
|
|
is mandatory for all mesh devices. It contains the element and model composition,
|
|
the supported features, and manufacturer information.
|
|
|
|
Composition Data Page 1
|
|
-----------------------
|
|
|
|
Composition Data Page 1 provides information about the relationships between models,
|
|
and is mandatory for all mesh devices. A model may extend and/or correspond to one
|
|
or more models. A model can extend another model by calling :c:func:`bt_mesh_model_extend`,
|
|
or correspond to another model by calling :c:func:`bt_mesh_model_correspond`.
|
|
:kconfig:option:`CONFIG_BT_MESH_MODEL_EXTENSION_LIST_SIZE` specifies how many model
|
|
relations can be stored in the composition on a device, and this number should reflect the
|
|
number of :c:func:`bt_mesh_model_extend` and :c:func:`bt_mesh_model_correspond` calls.
|
|
|
|
Composition Data Page 2
|
|
-----------------------
|
|
|
|
Composition Data Page 2 provides information for supported mesh profiles. Mesh profile
|
|
specifications define product requirements for devices that want to support a specific
|
|
Bluetooth SIG defined profile. Currently supported profiles can be found in section
|
|
3.12 in `Bluetooth SIG Assigned Numbers
|
|
<https://www.bluetooth.com/specifications/assigned-numbers/uri-scheme-name-string-mapping/>`_.
|
|
Composition Data Page 2 is only mandatory for devices that claim support for one or more
|
|
mesh profile(s).
|
|
|
|
Composition Data Pages 128, 129 and 130
|
|
---------------------------------------
|
|
|
|
Composition Data Pages 128, 129 and 130 mirror Composition Data Pages 0, 1 and 2 respectively.
|
|
They are used to represent the new content of the mirrored pages when the Composition Data will
|
|
change after a firmware update. See :ref:`bluetooth_mesh_dfu_srv_comp_data_and_models_metadata`
|
|
for details.
|
|
|
|
Delayable messages
|
|
==================
|
|
|
|
The delayable message functionality is enabled with Kconfig option
|
|
:kconfig:option:`CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG`.
|
|
This is an optional functionality that implements specification recommendations for
|
|
messages that are transmitted by a model in a response to a received message, also called
|
|
response messages.
|
|
|
|
Response messages should be sent with the following random delays:
|
|
|
|
* Between 20 and 50 milliseconds if the received message was sent
|
|
to a unicast address
|
|
* Between 20 and 500 milliseconds if the received message was sent
|
|
to a group or virtual address
|
|
|
|
The delayable message functionality is triggered if the :c:member:`bt_mesh_msg_ctx.rnd_delay`
|
|
flag is set.
|
|
The delayable message functionality stores messages in the local memory while they are
|
|
waiting for the random delay expiration.
|
|
|
|
If the transport layer doesn't have sufficient memory to send a message at the moment
|
|
the random delay expires, the message is postponed for another 10 milliseconds.
|
|
If the transport layer cannot send a message for any other reason, the delayable message
|
|
functionality raises the :c:member:`bt_mesh_send_cb.start` callback with a transport layer
|
|
error code.
|
|
|
|
If the delayable message functionality cannot find enough free memory to store an incoming
|
|
message, it will send messages with delay close to expiration to free memory.
|
|
|
|
When the mesh stack is suspended or reset, messages not yet sent are removed and
|
|
the :c:member:`bt_mesh_send_cb.start` callback is raised with an error code.
|
|
|
|
.. note::
|
|
When a model sends several messages in a row, it may happen that the messages are not sent in
|
|
the order they were passed to the access layer. This is because some messages can be delayed
|
|
for a longer time than the others.
|
|
|
|
Disable the randomization by setting the :c:member:`bt_mesh_msg_ctx.rnd_delay` to ``false``,
|
|
when a set of messages originated by the same model needs to be sent in a certain order.
|
|
|
|
Delayable publications
|
|
======================
|
|
|
|
The delayable publication functionality implements the specification recommendations for message
|
|
publication delays in the following cases:
|
|
|
|
* Between 20 to 500 milliseconds when the Bluetooth Mesh stack starts or when the publication is
|
|
triggered by the :c:func:`bt_mesh_model_publish` function
|
|
* Between 20 to 50 milliseconds for periodically published messages
|
|
|
|
This feature is optional and enabled with the :kconfig:option:`CONFIG_BT_MESH_DELAYABLE_PUBLICATION`
|
|
Kconfig option. When enabled, each model can enable or disable the delayable publication by setting
|
|
the :c:member:`bt_mesh_model_pub.delayable` bit field to ``1`` or ``0`` correspondingly. This bit
|
|
field can be changed at any time.
|
|
|
|
API reference
|
|
*************
|
|
|
|
.. doxygengroup:: bt_mesh_access
|