From 69117bda998eb0b2fa117b0e0f55b3a020340d69 Mon Sep 17 00:00:00 2001 From: Aleksander Nowakowski Date: Tue, 17 Oct 2023 23:24:47 +0200 Subject: [PATCH] Documentation improvements --- README.md | 5 +- .../Documentation.docc/Configuration.md | 15 ++- .../Documentation.docc/Connecting.md | 38 ++++++ .../Documentation.docc/CreatingNetwork.md | 30 +++++ .../Documentation.docc/LocalNode.md | 22 +++- .../Documentation.docc/Provisioning.md | 8 +- .../Documentation.docc/SendingMessages.md | 27 +++- nRFMeshProvision/Documentation.docc/Usage.md | 71 ++++++++++ .../Documentation.docc/nRFMeshProvision.md | 121 ++---------------- 9 files changed, 206 insertions(+), 131 deletions(-) create mode 100644 nRFMeshProvision/Documentation.docc/Connecting.md create mode 100644 nRFMeshProvision/Documentation.docc/CreatingNetwork.md create mode 100644 nRFMeshProvision/Documentation.docc/Usage.md diff --git a/README.md b/README.md index 48149bdf2..d2d5aec56 100755 --- a/README.md +++ b/README.md @@ -11,9 +11,10 @@ devices into a mesh network, configure them and send and receive messages. The library is compatible with the following [Bluetooth specifications](https://www.bluetooth.com/specifications/specs/?types=adopted&keyword=mesh): - Mesh Protocol 1.1 (backwards compatible with **Mesh Profile 1.0.1**) - Mesh Model 1.1 -- Mesh Device Properties 2 - Mesh Configuration Database Profile 1.0.1 +and [**Mesh Device Properties**](https://www.bluetooth.com/specifications/device-properties/). + See [documentation](https://nordicsemiconductor.github.io/IOS-nRF-Mesh-Library/documentation/nrfmeshprovision) for more information. > **Note** @@ -49,7 +50,7 @@ See [documentation](https://nordicsemiconductor.github.io/IOS-nRF-Mesh-Library/d The following features are not (yet) supported: -1. The rest of models defined by Bluetooth SIG - *PRs are welcome!** +1. The rest of models defined by Bluetooth SIG - *PRs are welcome!* 2. IV Index update (initiation) - *not a top priority, as other nodes may initiate the update.* 3. Health server messages - *in our TODO list.* 4. Device Firmware Update (DFU) - *coming next!* diff --git a/nRFMeshProvision/Documentation.docc/Configuration.md b/nRFMeshProvision/Documentation.docc/Configuration.md index 5b3969349..ac6692200 100644 --- a/nRFMeshProvision/Documentation.docc/Configuration.md +++ b/nRFMeshProvision/Documentation.docc/Configuration.md @@ -10,7 +10,7 @@ Configuration messages are secured using this Device Key on the Access Layer. On and the configured Node, which know the key, can encrypt and decrypt such messages. Use ``MeshNetworkManager/sendToLocalNode(_:)`` to configure the *local node*. The ``ConfigMessage``s -will be handled by the *Configuration Server* model automaticaly by the library. +will be handled by the *Configuration Server* model automatically by the library. To configure the remote nodes, use ``MeshNetworkManager/send(_:to:withTtl:)-2bthl``. @@ -18,9 +18,14 @@ Status messages for configuration messages are delivered using ``MeshNetworkDelegate/meshNetworkManager(_:didReceiveMessage:sentFrom:to:)`` to the ``MeshNetworkManager/delegate``. -The updated state of the mesh network is automaticaly saved in the ``Storage``. +The updated state of the mesh network is automatically saved in the ``Storage``. > Important: As the nRF Mesh library supports *Configuration Server* model, it also allows - other provisioners to remotely reconfigure the *local node* when it is connected to a Proxy node. - For example, the phone can be remotely removed from network. To avoid that, do not - share the Device Key of the local node when exporting network configuration. + other provisioners to remotely reconfigure the *local node* when it is connected to a + GATT Proxy node. In example, the phone can be remotely removed from network. + To make sure the node never gets remotely removed do not share the Device Key of + the local node when exporting network configuration. + +## What's next + +Having the network set up and ready, it's time to share the configuration: . diff --git a/nRFMeshProvision/Documentation.docc/Connecting.md b/nRFMeshProvision/Documentation.docc/Connecting.md new file mode 100644 index 000000000..136e742b4 --- /dev/null +++ b/nRFMeshProvision/Documentation.docc/Connecting.md @@ -0,0 +1,38 @@ +# Connecting to mesh network + +How to connect to the network via GATT Proxy node. + +## Overview + +The ``MeshNetworkManager`` is transport agnostic. In order to send messages, the ``MeshNetworkManager/transmitter`` +property needs to be set to a ``Bearer`` instance. The bearer is responsible for sending the messages +to the mesh network. Messages received from the bearer must be delivered to the manager using +``MeshNetworkManager/bearerDidDeliverData(_:ofType:)``. + +> Tip: To make the integration with ``Bearer`` easier, the manager instance can be set as Bearer's + ``Bearer/dataDelegate``. The nRF Mesh library includes ``GattBearer`` class, which implements + the ``Bearer`` protocol. + +```swift +let bearer = GattBearer(target: peripheral) +bearer.delegate = ... + +// Cross set the delegates. +bearer.dataDelegate = meshNetworkManager +meshNetworkManager.transmitter = bearer + +// To get the logs from the bearer, set the logger delegate to the bearer as well. +bearer.logger = ... +``` + +Before the bearer can be used it needs to be open. For GATT Proxy bearer this means connecting +over to the node over GATT. All mesh messages will be sent to the proxy using a GATT *Mesh Proxy Service* +and will be relayed over ADV bearer to the network. +```swift +// Open the bearer. The GATT Bearer will initiate Bluetooth LE connection. +bearer.open() +``` + +## What's next + +With the bearer open it's finally time to send mesh messages: . diff --git a/nRFMeshProvision/Documentation.docc/CreatingNetwork.md b/nRFMeshProvision/Documentation.docc/CreatingNetwork.md new file mode 100644 index 000000000..35926e655 --- /dev/null +++ b/nRFMeshProvision/Documentation.docc/CreatingNetwork.md @@ -0,0 +1,30 @@ +# Creating and loading a network configuration + +How to load or create a network. + +## Overview + +The mesh configuration may be loaded from the ``Storage``, provided in the manager's initializer. +```swift +let loaded = try meshNetworkManager.load() +``` +If no configuration exists, this method will return `false`. In that case either create +a new configuration, as shown below, or import an existing one from a file. +```swift +_ = meshNetworkManager.createNewMeshNetwork( + withName: "My Network", + by: "My Provisioner" +) +// Make sure to save the network in the Storage. +_ = meshNetworkManager.save() +``` + +Each time the network is modified, for example a new key is added, the configuration has to be saved +using ``MeshNetworkManager/save()``. When a Configuration message is received, either a Status message +sent as a response to a request, or a request sent from another node, the configuration is saved +automatically. + +## What's next + +Now, with the mesh network manager and network set up we can provision a device: , +or connect to the network using a GATT Proxy node: . diff --git a/nRFMeshProvision/Documentation.docc/LocalNode.md b/nRFMeshProvision/Documentation.docc/LocalNode.md index d0cbae595..7e6b3af60 100644 --- a/nRFMeshProvision/Documentation.docc/LocalNode.md +++ b/nRFMeshProvision/Documentation.docc/LocalNode.md @@ -5,15 +5,17 @@ Defining the behavior of the node. ## Overview The mobile application using nRF Mesh library is itself a mesh node, called the *local node*. -Being a node means, that it defines one or more *Elements*, each with one or more *Models* which support -sending and receiving messages. +Being a node means, that it is visible to other nodes as one or more *Elements*, each with +one or more *Models* which support specific behavior and allow sending and receiving messages. The library automatically supports the following models: - *Configuration Server* (required for all nodes) - *Configuration Client* (required for configuring nodes) -- *Health Server* (required for all nodes) +- *Health Server* (required for all nodes, but not implemented yet) - *Health Client* (currently not implemented) -- *Private Beacon Client* (experimental) +- *Private Beacon Client* +- *Remote Provisioning Client* +- *SAR Configuration Client* - *Scene Client* (for controlling scenes) and may be extended to support user models: either Bluetooth SIG defined, like *Generic OnOff Client*, @@ -25,6 +27,9 @@ Op Codes of supported messages to their types, and defines the behavior of the m For example, a model delegate can specify that it can handle messages with an Op Code *0x8204*, which should be decoded to ``GenericOnOffStatus`` type. +If a received message cannot be mapped to any message type (i.e. no local model +supports the op code of received message), it will be decoded as ``UnknownMessage``. + ```swift // Mind, that the first Element will contain the models mentioned above. let primaryElement = Element(name: "Primary Element", location: .first, @@ -44,14 +49,17 @@ meshNetworkManager.localElements = [primaryElement] > Important: Even if your implementation does not add any models to the default set, it is required to set the ``MeshNetworkManager/localElements``. It can be set to an empty array. -The model delegate is notified when a message targetting the model is received if, and only if, the model +The model delegate is notified when a message targeting the model is received if, and only if, the model is bound to the Application Key used to encrypt the message and is subscribed to its destination address. > Tip: The ``MeshNetworkDelegate``, set in the manager, is notified about every message received. This includes messages targeting models that are not configured to receive messages, i.e. not bound to any key, or not subscribed to the address set as destination address of the - message. If a received message cannot be mapped to any message type (i.e. no local model - supports the op code of received message), it will be decoded as ``UnknownMessage``. + message. > See `Example/nRFMeshProvision/AppDelegate.swift` in "nRF Mesh" sample app for an example. + +## What's next + +The next step is . diff --git a/nRFMeshProvision/Documentation.docc/Provisioning.md b/nRFMeshProvision/Documentation.docc/Provisioning.md index 2925c2761..7227861f4 100644 --- a/nRFMeshProvision/Documentation.docc/Provisioning.md +++ b/nRFMeshProvision/Documentation.docc/Provisioning.md @@ -15,6 +15,8 @@ Configuration messages are sent between *Configuration Client* model on the mana and *Configuration Server* model on the target device, and, on the Upper Transport layer, are encrypted using the node's Device Key, generated during provisioning. +More on that in . + To provision a new device, use ``MeshNetworkManager/provision(unprovisionedDevice:over:)``. ```swift let provisioningManager = try meshNetworkManager.provision( @@ -43,7 +45,7 @@ func centralManager(_ central: CBCentralManager, > Important: nRF Mesh library supports PB GATT Bearer and PB Remote Bearer. PB Adv Bearer is not supported. -To provision a device which does not support PB GATT Bearer a ``PBRemoteBearer`` must be used. +A ``PBRemoteBearer`` can be used to provision a device which does not support PB GATT Bearer. A node supporting *Remote Provisioning Server* model must be provisioned and in range of the unprovisioned device. All provisioning messages will be sent via that node. @@ -62,3 +64,7 @@ try provisioningManager.provision(usingAlgorithm: .BTM_ECDH_P256_HMAC_SHA2 authenticationMethod: ...) ``` The ``ProvisioningDelegate`` should be used to provide OOB (Out Of Band) information. + +## What's next + +Having a node provisioned we can connect to it using GATT Proxy feature: . diff --git a/nRFMeshProvision/Documentation.docc/SendingMessages.md b/nRFMeshProvision/Documentation.docc/SendingMessages.md index 8b279ae08..02a31858b 100644 --- a/nRFMeshProvision/Documentation.docc/SendingMessages.md +++ b/nRFMeshProvision/Documentation.docc/SendingMessages.md @@ -1,24 +1,41 @@ # Sending messages -Bluetooth mesh is built on publish-subscribe paradigm. Each node can publish messages and receive messages -sent by other nodes. +How to send mesh messages using the manager. ## Overview +Bluetooth mesh is built on publish-subscribe paradigm. Each node can publish messages and receive messages +sent by other nodes. + The nRF Mesh library supports sending messages in two ways: 1. From models on the local node, that are configured for publishing. 2. Directly. -The first method closely follows Bluetooth Mesh Profile specification, but is quite complex. +The first method closely follows Bluetooth Mesh Protocol specification, but is quite complex. A model needs to be bound to an Application Key using ``ConfigModelAppBind`` message and have a publication set using ``ConfigModelPublicationSet`` or -``ConfigModelPublicationVirtualAddressSet``. With that set, calling +``ConfigModelPublicationVirtualAddressSet``. With that, calling ``ModelDelegate/publish(using:)`` or ``ModelDelegate/publish(_:using:)`` will trigger a publication from the model to a destination specified in the ``Publish`` object. Responses will be delivered to ``ModelDelegate/model(_:didReceiveResponse:toAcknowledgedMessage:from:)`` of the model delegate. +> Note: The above is demonstrated in the nRF Mesh app on the **Local Node** tab. To set up the components + configure the models on the Primary and Secondary Element of the *local node* using **Network** tab. + The second method does not require setting up local models. Use ``MeshNetworkManager/send(_:from:to:withTtl:using:)-48vjl`` or other variants of this method to send a message to the desired destination. -> All methods used for sending messages in the ``MeshNetworkManager`` are asynchronous. +> Note: The second method can be shown using nRF Mesh app either by sending messages directly + from desired node's models' views in **Network** tab, or from **Groups** tab. + +Starting from nRF Mesh library version 4.0 all methods for sending messages come in 2 favors. +One is using `async` functions, which block execution until either the message was sent (for +``UnacknowledgedMeshMessage``), or the response was received (for ``AcknowledgedMeshMessage``). +Those have to be called from a [`Task`](https://developer.apple.com/documentation/swift/task). +The second favor is using completion handers instead, which are called in the same situations. +Both types can be used interchangeably. + +## What's next + +Knowing basics learn how to configure nodes, including the local one: . diff --git a/nRFMeshProvision/Documentation.docc/Usage.md b/nRFMeshProvision/Documentation.docc/Usage.md new file mode 100644 index 000000000..5ec50543d --- /dev/null +++ b/nRFMeshProvision/Documentation.docc/Usage.md @@ -0,0 +1,71 @@ +# Usage + +How to start. + +## Overview + +The ``MeshNetworkManager`` is the main entry point for interacting with the mesh network. +It can be used to create, load or import a Bluetooth mesh network configuration and send +and receive messages. + +The snippet below demonstrates how to start. + +```swift +// Create the Mesh Network Manager instance. +meshNetworkManager = MeshNetworkManager() + +// If needed, customize network parameters using basic: +meshNetworkManager.networkParameters = .basic { parameters in + parameters.setDefaultTtl(...) + // Configure SAR Receiver properties + parameters.discardIncompleteSegmentedMessages(after: ...) + parameters.transmitSegmentAcknowledgmentMessage( + usingSegmentReceptionInterval: ..., + multipliedByMinimumDelayIncrement: ...) + parameters.retransmitSegmentAcknowledgmentMessages( + exactly: ..., timesWhenNumberOfSegmentsIsGreaterThan: ...) + // Configure SAR Transmitter properties + parameters.transmitSegments(withInterval: ...) + parameters.retransmitUnacknowledgedSegmentsToUnicastAddress( + atMost: ..., timesAndWithoutProgress: ..., + timesWithRetransmissionInterval: ..., andIncrement: ...) + parameters.retransmitAllSegmentsToGroupAddress(exactly: ..., timesWithInterval: ...) + // Configure message configuration + parameters.retransmitAcknowledgedMessage(after: ...) + parameters.discardAcknowledgedMessages(after: ...) +} +// ...or advanced configurator: +meshNetworkManager.networkParameters = .advanced { parameters in + parameters.defaultTtl = ... + // Configure SAR Receiver properties + parameters.sarDiscardTimeout = ... + parameters.sarAcknowledgmentDelayIncrement = ... + parameters.sarReceiverSegmentIntervalStep = ... + parameters.sarSegmentsThreshold = ... + parameters.sarAcknowledgmentRetransmissionsCount = ... + // Configure SAR Transmitter properties + parameters.sarSegmentIntervalStep = ... + parameters.sarUnicastRetransmissionsCount = ... + parameters.sarUnicastRetransmissionsWithoutProgressCount = ... + parameters.sarUnicastRetransmissionsIntervalStep = ... + parameters.sarUnicastRetransmissionsIntervalIncrement = ... + parameters.sarMulticastRetransmissionsCount = ... + parameters.sarMulticastRetransmissionsIntervalStep = ... + // Configure acknowledged message timeouts + parameters.acknowledgmentMessageInterval = ... + parameters.acknowledgmentMessageTimeout = ... + // And if you really know what you're doing... + builder.allowIvIndexRecoveryOver42 = ... + builder.ivUpdateTestMode = ... +} +// You may also modify a parameter using this syntax: +meshNetworkManager.networkParameters.defaultTtl = ... + +// For debugging, set the logger delegate. +meshNetworkManager.logger = ... +``` + +## What's next + +The next step is to define the behavior of the manager determined by the set +of models on the local node: . diff --git a/nRFMeshProvision/Documentation.docc/nRFMeshProvision.md b/nRFMeshProvision/Documentation.docc/nRFMeshProvision.md index d033a7750..32eaaa27f 100644 --- a/nRFMeshProvision/Documentation.docc/nRFMeshProvision.md +++ b/nRFMeshProvision/Documentation.docc/nRFMeshProvision.md @@ -10,131 +10,30 @@ them and send and receive messages. The library is compatible with the following [Bluetooth specifications](https://www.bluetooth.com/specifications/specs/?types=adopted&keyword=mesh): - **Mesh Protocol 1.1** (backwards compatible with **Mesh Profile 1.0.1**) - **Mesh Model 1.1** -- **Mesh Device Properties 2** - **Configuration Database Profile 1.0.1** +and [**Mesh Device Properties**](https://www.bluetooth.com/specifications/device-properties/). + > Important: Implementing ADV Bearer on iOS is not possible due to API limitations. The library is using GATT Proxy protocol, specified in the Bluetooth Mesh Protocol 1.1, and requires a Node with GATT Proxy feature to relay messages to the mesh network. -## Usage - -The ``MeshNetworkManager`` is the main entry point for interacting with the mesh network. -It can be used to create, load or import a Bluetooth mesh network configuration and send -and receive messages. - -The snippet below demonstrates how to start. - -```swift -// Create the Mesh Network Manager instance. -meshNetworkManager = MeshNetworkManager() - -// If needed, customize network parameters using basic: -meshNetworkManager.networkParameters = .basic { parameters in - parameters.setDefaultTtl(...) - // Configure SAR Receiver properties - parameters.discardIncompleteSegmentedMessages(after: ...) - parameters.transmitSegmentAcknowledgmentMessage( - usingSegmentReceptionInterval: ..., - multipliedByMinimumDelayIncrement: ...) - parameters.retransmitSegmentAcknowledgmentMessages( - exactly: ..., timesWhenNumberOfSegmentsIsGreaterThan: ...) - // Configure SAR Transmitter properties - parameters.transmitSegments(withInterval: ...) - parameters.retransmitUnacknowledgedSegmentsToUnicastAddress( - atMost: ..., timesAndWithoutProgress: ..., - timesWithRetransmissionInterval: ..., andIncrement: ...) - parameters.retransmitAllSegmentsToGroupAddress(exactly: ..., timesWithInterval: ...) - // Configure message configuration - parameters.retransmitAcknowledgedMessage(after: ...) - parameters.discardAcknowledgedMessages(after: ...) -} -// ...or advanced configurator: -meshNetworkManager.networkParameters = .advanced { parameters in - parameters.defaultTtl = ... - // Configure SAR Receiver properties - parameters.sarDiscardTimeout = ... - parameters.sarAcknowledgmentDelayIncrement = ... - parameters.sarReceiverSegmentIntervalStep = ... - parameters.sarSegmentsThreshold = ... - parameters.sarAcknowledgmentRetransmissionsCount = ... - // Configure SAR Transmitter properties - parameters.sarSegmentIntervalStep = ... - parameters.sarUnicastRetransmissionsCount = ... - parameters.sarUnicastRetransmissionsWithoutProgressCount = ... - parameters.sarUnicastRetransmissionsIntervalStep = ... - parameters.sarUnicastRetransmissionsIntervalIncrement = ... - parameters.sarMulticastRetransmissionsCount = ... - parameters.sarMulticastRetransmissionsIntervalStep = ... - // Configure acknowledged message timeouts - parameters.acknowledgmentMessageInterval = ... - parameters.acknowledgmentMessageTimeout = ... - // And if you really know what you're doing... - builder.allowIvIndexRecoveryOver42 = ... - builder.ivUpdateTestMode = ... -} -// You may also modify a parameter using this syntax: -meshNetworkManager.networkParameters.defaultTtl = ... - -// For debugging, set the logger delegate. -meshNetworkManager.logger = ... -``` - -The next step is to define the behavior of the manager. The behavior is determined by set of -``Model``s existing on the Node. For more information, read . - -### Loading mesh configuration - -The mesh configuration may be loaded from the ``Storage``, provided in the manager's initializer. -```swift -let loaded = try meshNetworkManager.load() -``` -If no configuration exists, this method will return `false`. In that case either create -a new configuration, as shown below, or import an existing one from a file. -```swift -_ = meshNetworkManager.createNewMeshNetwork( - withName: "My Network", - by: "My Provisioner" -) -// Make sure to save the network in the Storage. -_ = meshNetworkManager.save() -``` - -### Connecting to mesh network using GATT Proxy - -The manager is transport agnostic. In order to send messages, the ``MeshNetworkManager/transmitter`` -property needs to be set to a ``Bearer`` instance. The bearer is responsible for sending the messages -to the mesh network. Messages received from the bearer must be delivered to the manager using -``MeshNetworkManager/bearerDidDeliverData(_:ofType:)``. - -> Tip: To make the integration with ``Bearer`` easier, the manager instance can be set as Bearer's - ``Bearer/dataDelegate``. The nRF Mesh library includes ``GattBearer`` class, which implements - the ``Bearer`` protocol. - -```swift -let bearer = GattBearer(target: peripheral) -bearer.delegate = ... - -// Cross set the delegates. -bearer.dataDelegate = meshNetworkManager -meshNetworkManager.transmitter = bearer - -// To get the logs from the bearer, set the logger delegate to the bearer as well. -bearer.logger = ... - -// Open the bearer. The GATT Bearer will initiate Bluetooth LE connection. -bearer.open() -``` +## First steps + +To learn how to use the library, start here: . ## Topics ### Articles +- - -- +- - -- +- - +- +- ### Mesh Network Manager