diff --git a/docs/LwM2M_Client/Getting_started.md b/docs/LwM2M_Client/Getting_started.md index 4fcaaebb..88bae46e 100644 --- a/docs/LwM2M_Client/Getting_started.md +++ b/docs/LwM2M_Client/Getting_started.md @@ -2,6 +2,14 @@ Start developing LwM2M applications on your boards and IoT devices in just a few clicks using our Anjay LwM2M Client. +## Svetovid + +Integrate your Linux-based device with our Svetovid LwM2M Client. + +![RaspberryPi](images/raspberry_pi.jpg "Raspberry Pi"){ width=50% } + +[Start integration](./Svetovid/Intro.md){: .md-button .md-button--big } + ## Espressif ESP32 ### M5StickC diff --git a/docs/LwM2M_Client/Svetovid/Client_Configuration.md b/docs/LwM2M_Client/Svetovid/Client_Configuration.md new file mode 100644 index 00000000..76693760 --- /dev/null +++ b/docs/LwM2M_Client/Svetovid/Client_Configuration.md @@ -0,0 +1,306 @@ +# Client configuration + +## Introduction + +Svetovid keeps configuration in JSON files. For Raspberry Pi, the default +location of these JSONs is ``/etc/svetovid/config``. Default configuration +directory may be overwritten by passing ``--conf-dir`` command line argument +when starting a Svetovid binary. + +!!! Warning + Only the following JSON files are supposed to be modified manually: + + - ``security.json`` + - ``server.json`` + - ``svd.json`` + + Editing other JSON files in the configuration directory may cause unexpected + behavior of the client. + +!!! Note + The LwM2M client process may modify these files at runtime. To avoid + your changes from being overwritten, make sure to stop the ``svetovid`` + process before modifying the configuration (see the documentation relevant + for your target platform, e.g. + [launch instructions for the generic target](Supported_Platforms/generic.md#launch-instructions)). + +## General settings + +Settings not directly related to LwM2M server connections are stored in +``svd.json`` file. Example: + +!!! Note + This file can generally be left empty if you are fine with the defaults. + +```json +{ + "device": { + "endpoint_name": "53r14l", + "udp_listen_port": 1234 + }, + "logging": { + "default_log_level": "trace", + "log_level": { + "svd": "trace" + } + }, + "lwm2m_version_config": { + "min": "1.0", + "max": "1.1" + }, + "in_buffer_size_b": 1024, + "out_buffer_size_b": 1024, + "msg_cache_size_b": 65536 +} +``` + +- ``device.endpoint_name`` - if set, the endpoint name will be set to the + configured value.
+ **Default value:** automatically generated + ``urn:dev:os:MANUFACTURER_OUI-SERIAL_NUMBER``, where the method of getting + ``MANUFACTURER_OUI`` and ``SERIAL_NUMBER`` is specific to the platform used. +- ``device.udp_listen_port`` - force binding to a specific UDP port. If set to a + non-zero value, all UDP sockets created by the LwM2M client will be bound to + the configured port.
+ **Default value:** random ephemeral ports will be used. +- ``device.server_initiated_bootstrap`` - enables/disables LwM2M Server + initiated bootstrap support. If set to true, connection to the Bootstrap + Server will be closed immediately after making a successful connection to any + regular LwM2M Server and only opened again if (re)connection to a regular + server is rejected.
+ **Default value:** ``0``. +- ``device.core_persistence`` - enables/disables Anjay core persistence, which + allows Svetovid to keep information about DTLS sessions, active LwM2M server + registrations and active resource observations in non-volatile storage. Note + that this information is only persisted after a graceful shutdown of Svetovid. +
+ **Default value:** ``0``. +- ``device.rebuild_client_cert_chain`` - enables/disables rebuilding client + certificate chain based on the trust store (either the initial one or the one + provisioned via EST) for inclusion in the (D)TLS handshake when using + Certificate mode. If disabled, only the leaf client certificate will be sent + in the handshake.
+ **Default value:** ``0``. +- ``device.est_reenroll_config.enable`` - enables/disables usage of the EST + Simple Re-enroll (``/est/sren``) operation.
+ **Default value:** ``1``. +- ``device.est_reenroll_config.nominal_usage`` - nominal period for which a + certificate provisioned by the EST server is used, expressed as part of the + certificate validity period (value in the [0.0, 1.0] range).
+ **Default value:** ``0.9``. +- ``device.est_reenroll_config.max_margin_s`` - limit, in seconds, on the margin + between re-enrollment request and the certificate expiration time. In other + words, it is guaranteed that re-enroll request will not be sent earlier than + ``max_margin`` before the certificate expiration time. A negative value may be + set to disable the limit.
+ **Default value:** ``2592000`` (30 days). +- ``device.est_cacerts_policy`` - Policy of when to perform the ``/est/crts`` + request and which servers will use the trust store updated through it.
+ Possible values are: + - ``for_est_security_and_bootstrap`` (**default**) - perform the + ``/est/crts`` request if there are servers configured to use the EST + security mode, and use the updated trust store for those servers, as well + as for the Bootstrap Server if it's configured to use either EST or + Certificate security mode + - ``for_est_security`` - perform the ``/est/crts`` request if there are + servers configured to use the EST security mode, and use the updated trust + store for those servers only; the Bootstrap Server will use the updated + trust store only if it is itself configured to use the EST security mode + - ``if_est_configured`` - perform the ``/est/crts`` request if there are + servers configured to use the EST security mode, and use the updated trust + store for all servers configured to use either EST or Certificate security + mode + - ``always`` - perform the ``/est/crts`` request if there are servers + configured to use either EST or Certificate security mode, and use the + updated trust store for all such servers + - ``disabled`` - never perform the ``/est/crts`` request +- ``logging.default_log_level`` - log level applied to messages in case no more + specific log level exists.
+ Acceptable values: + - "trace" (log all messages) + - "debug" + - "info" + - "warning" + - "error" + - "quiet" (do not log anything) + + **Default value:** "info". + +- ``logging.log_level.MODULE_NAME`` - log level applied to messages originating + from ``MODULE_NAME`` only. Can be used to selectively control logging levels. +- ``lwm2m_version_config.min`` and ``lwm2m_version_config.max`` - minimum and + maximum version of the LwM2M protocol that the client will attempt to use. + Only ``1.0`` and ``1.1`` are currently supported versions, and both are used + by default. The client will always attempt to register using the highest + configured version and fall back to older versions if necessary. +- ``in_buffer_size_b`` - size (in bytes) of the buffer used for storing incoming + LwM2M messages. The client will not be able to handle packets bigger than this + size.
+ **Default value:** 4096. +- ``out_buffer_size_b`` - size (in bytes) of the buffer used for storing + outgoing LwM2M messages. In cases where the message sent would exceed this + size, the client will attempt a BLOCK-wise CoAP transfer instead.
+ **Default value:** 4096. +- ``msg_cache_size_b`` - size (in bytes) of the buffer used for storing outgoing + LwM2M messages. When the client receives a duplicate request while an + already-prepared response is in the cache, it is used instead of generating a + new one. Cached messages are removed after their validity expires. If total + size of cached messages exceeds configured value, oldest entries are evicted + to make room for fresh ones.
+ Setting this value to 0 disables message caching. In such case, the client + will handle all received retransmitted requests as if they were new ones, + which may result in performing non-idempotent operations multiple times.
+ **Default value:** 65536. +- ``retry_after_s`` - enables/disables reconnection policy which after specified + period of time (in seconds) after all server connections failed performs a + reconnection attempt. A value of 0 disables reconnection attempts, and causes + the client to shut down if it is unable to establish any connection. +
+ **Default value:** 30. +- ``dirs.persistence`` - path to the persistence directory. That path MUST NOT + get cleared on FW update.
+ **Default value:** `SVETOVID_PERSISTENCE_DIR` set during compile time. +- ``dirs.volatile_persistence`` - path to a volatile persistence directory. That + path MUST be cleared on FW update, but persist across reboots.
+ **Default value:** `SVETOVID_VOLATILE_PERSISTENCE_DIR` set during compile + time. +- ``dirs.plugins`` - path to Svetovid's plugin installation directory.
+ **Default value:** `SVETOVID_PLUGIN_DIR` set during compile time. +- ``dirs.temp`` - path to a directory used for temporary file storage.
+ **Default value:** `SVETOVID_TEMP_DIR` set during compile time. +- ``dirs.firmware_download_dir`` - path where PULL FW downloads will be kept. + It MAY be cleared on FW update, but SHOULD persist across reboots in order to + support firmware download resumption.
+ **Default value:** `SVETOVID_FIRMWARE_DOWNLOAD_DIR` set during compile time. +- ``dirs.pkix_trust_store`` - path to file or directory containing certificates + that shall be used as the initial trust store for Certificate Usage modes that + demand PKIX verification.
+ **Default value:** `SVETOVID_PKIX_TRUST_STORE` set during compile time, which + is the global system trust store (``/etc/ssl/certs``) on platforms that + support it, none otherwise. +- ``dirs.pkix_trust_store_crls`` - path to file containing CRLs that shall be + used in conjunction with ``pkix_trust_store`` as the initial trust store for + Certificate Usage modes that demand PKIX verification.
+ **Default value:** none. + +## Connection settings + +!!! Note + The default configuration is designed to let you easily connect to our + [{{ coiote_long_name }}](https://www.avsystem.com/products/coiote-iot-device-management-platform/). + Please register at [{{ coiote_server }}]({{ coiote_site_link }}) to get + access. + +To configure an LwM2M Bootstrap Server, an instance has to be created in +``security.json`` file. A non-Bootstrap LwM2M Server additionally requires +adding an instance to the ``server.json`` file. + +### Examples + +#### Bootstrap server + + - **security.json** + ```json + { + "2": { + "server_uri": "coap:\/\/{{ coiote_server }}:5693", + "is_bootstrap": "1", + "security_mode": "nosec", + "pubkey_or_identity_hex": "", + "server_pubkey_hex": "", + "privkey_or_psk_hex": "", + "ssid": "7", + "bs_timeout_s": "0" + } + } + ``` + + - **server.json** + ```json + {} + ``` + +#### Non-bootstrap server with DTLS in Pre-Shared Key mode + + - **security.json** + ```json + { + "2": { + "server_uri": "coaps:\/\/{{ coiote_server }}:5684", + "is_bootstrap": "0", + "security_mode": "psk", + "pubkey_or_identity_hex": "3030323343372D303036303634434444423130", + "server_pubkey_hex": "", + "privkey_or_psk_hex": "4573644175496D4E7536", + "ssid": "7", + "bs_timeout_s": "0" + } + } + ``` + + - **server.json** + ```json + { + "0": { + "ssid": "7", + "lifetime": "30", + "notification_storing": "0", + "binding": "U" + } + } + ``` + +In the ``security.json`` file you may need to change the ``privkey_or_psk_hex`` +with hexlified pre-shared-key of your choice. To convert raw string to +hexlified string, you can use: + +```sh +$ echo -n 'your-secret-key' | xxd -p +``` + +### Possible configuration options + +Specific options directly correspond to LwM2M Security/LwM2M Server Object +Resources. See the LwM2M protocol specification for more details. + +- ``security.json`` options: + - ``server_uri`` - LwM2M Server URI ("coap://" or "coaps://" URI, depending + on the ``security_mode`` value), + - ``is_bootstrap`` - Bootstrap Server (boolean) + - ``security_mode`` - Security Mode (one of: "psk", "nosec", "cert") + - ``pubkey_or_identity_hex`` - Public Key or Identity (hex string). + + !!! Note + this **MUST** be a hex string, even if the value is in fact a + printable text. For example, if the PSK identity is supposed to be + "identity", this value should be set to "6964656e74697479". + + - ``server_pubkey_hex`` - Server Public Key (hex string; see NOTE above) + - ``privkey_or_psk_hex`` - Secret Key (hex string; see NOTE above) + - ``ssid`` - Short Server ID (1-65534) + - ``holdoff_s`` - Client Hold Off Time (seconds) + - ``bs_timeout_s`` - Bootstrap-Server Account Timeout (seconds) + +- ``server.json`` options: + - ``ssid`` - Short Server ID (1-65534, must match ``ssid`` of some Security + Object Instance) + - ``lifetime`` - Lifetime (seconds) + - ``default_min_period`` - Default Minimum Period (seconds) + - ``default_max_period`` - Default Maximum Period (seconds) + - ``binding`` - Binding (one of: "U", "UQ") + - ``notification_storing`` - Notification Storing When Disabled or Offline + (boolean) + - ``disable_timeout`` - Disable Timeout (seconds) + +### Using a Bootstrap Server + +When using a Bootstrap Server, it may modify the contents of the Security and +Server objects. These changes will **NOT** be written back to ``security.json`` +or ``server.json`` files - instead, they will be persisted into +``/etc/svetovid/persistence/persistence.dat``. Note that this is a binary file +that is not intended for user modification. + +The configuration in ``security.json`` and ``server.json`` will take preference +if the ``persistence.dat`` file doesn't exist, or if either of the JSON files +is newer than the last time Svetovid has been bootstrapped from them. In other +words, if you modify or ``touch`` the JSON files, they shall take preference. diff --git a/docs/LwM2M_Client/Svetovid/FSDM.md b/docs/LwM2M_Client/Svetovid/FSDM.md new file mode 100644 index 00000000..f3670fb5 --- /dev/null +++ b/docs/LwM2M_Client/Svetovid/FSDM.md @@ -0,0 +1,549 @@ +# File System Data Model + +FSDM (File System Data Model) is a framework that allows implementing LwM2M +objects using Python or Bash scripts. It is provided as a plugin for Svetovid, +available in the commercial version and in certain binary distribution. + +## Directory mapping + +When enabled, this plugin maps a specific directory to LwM2M Objects, Instances +and Resources. Default mapped directory is ``/etc/svetovid/dm`` and it can be +changed in ``fsdm.json`` file. It is expected to have the following structure: + +- ``/etc/svetovid/dm/`` (default) + - ``$OBJECT_ID/`` - directory representing an LwM2M Object with given ID. + - ``resources/`` - directory containing scripts used to access + individual Resources. + - set of executable scripts representing individual Resources. Names + of these files MUST exactly correspond to their Resource IDs. +
+ See [FSDM resources](#fsdm-resources) for details. + - ``instances`` - (optional) executable script used for managing object + instances.
+ See [FSDM instances script](#fsdm-instances-script) for details. + - ``transaction`` - (optional) executable script used to handle + transactional processing of object resources.
+ See [FSDM transaction script](#fsdm-transaction-script) for details. + +Other remarks: + +- Any unexpected files contained within the directory are ignored, including: + - "root"-level directories with non-numeric names, + - any files present on the "Object" level, + - "Resource"-level files/directories with non-numeric names. +- Every LwM2M operation is mapped to execution of one or more scripts located + under the ``OBJECT_ID/`` directory. Examples: + - LwM2M Read on some ``/Object ID/Instance ID/Resource ID`` will be + transformed into: + - getting the list of instances from ``Object ID/instances`` script to + verify if the targeted instance exists, + - calling the ``Object ID/Resource ID`` script to read the value of the + resource for that instance (the Instance ID is passed to + ``Resource ID`` script as parameter). + - LwM2M Read on some ``/Object ID/Instance ID`` will be transformed into: + - getting the list of instances from ``Object ID/instances`` script to + enumerate instance to be read, + - calling resource scripts (as above), but for every present instance. + - LwM2M Delete is transformed into: + - calls to ``instances`` script to delete instances. + - LwM2M Observe is transformed into: + - periodical LwM2M Reads to see if resource values changed. It is + default Pull-mode mechanism. You can control the frequency of + reads/notifications by ``pmin`` and ``pmax`` LwM2M Attributes. + + !!! Note + Apart of Pull-mode, there is Push-mode called "external notify". + When it is enebled then it is the user responsibility to notify + Svetovid about the changes in FSDM (more in section + [external notify](#fsdm-external-notify-trigger)). + +## Input and output + +Resource scripts obtain necessary information either from parameters passed to +them or from the standard input. For example, the LwM2M Write on a Resource +containing payload "example", will execute the corresponding Resource script, +passing the "example" string on its standard input. + +Resource scripts return values to Svetovid via standard output when they're used +to extract the value they represent. Apart from that, the scripts' exit codes +are translated to CoAP error responses. In the Python implementations, any +errors are communicated by exceptions, which are in turn translated to error +codes by the runtime in a way transparent to the user. + +LwM2M Execute arguments are passed as arguments to the script body. In Python +implementations, execute arguments are passed as a parameter to ``execute()`` +method. + +## FSDM script stub generator + +FSDM plugin comes with a helper tool for generating stubs of required scripts. +Run ``svetovid-fsdmtool --help`` to see up-to-date help message with usage +examples. + +!!! Note + ``svetovid-fsdmtool`` is distributed as a separate installation package (e.g + ``avsystem_svetovid-24.04-raspberry-Linux-fsdmtool.deb`` in case of + the Raspberry Pi platform), so please make sure that it is installed before + starting. + +## FSDM config file + +FSDM settings are stored in ``fsdm.json`` file. Example: + +```json +{ + "dirs": { + "datamodel": "/tmp/datamodel" + } +} +``` + +- ``dirs.datamodel`` - directory containing LwM2M objects, as described before. + If not set, **default is:** ``/etc/svetovid/dm``. + +## FSDM resources + +Each Resource is an executable script, which is called as follows: + +``` +script OPERATION [ OPTIONS... ] +``` + +### Resource script operations + +- ``read`` - represents an LwM2M Read operation. The script MUST return resource + value on its standard output. + + !!! Note + The script **MUST NOT** add any trailing newlines that are not a part of + actual resource value. Anything printed on `stdout` is interpreted as + binary data, i.e. no newline translation (e.g. CRLF <-> LF) is + performed. + +- ``write`` - represents an LwM2M Write. The script MUST read new resource value + from its standard input. + + !!! Note + **ALL** data until EOF represents the resource value. Any trailing + newlines present on `stdin` MUST be handled as part of resource value. + `stdin` contents **MUST** be interpreted as binary data, i.e. no newline + translation (e.g. CRLF <-> LF) may be performed. + +- ``execute`` - represents LwM2M Execute operation. Arguments, if any, can be + passed using the ``--args`` option. +- ``reset`` - resets Resource to its original state - sets it to a default value + or deletes it. In case of a Multiple Resource, it shall remove all its + Multiple Resource Instances - right after ``reset``, the following ``list`` + command should print an empty string. + + !!! Note + It will be called for each resource of an instance before LwM2M + Write-Replace is performed on the instance (or on the resource if it is + a Multiple Resource). + +- ``list`` - only applicable to Multiple Resources. The script should print a + whitespace-separated list of valid Resource Instance IDs for this resource. +- ``describe`` - returns Resource metadata in JSON format, including: + - ``"operations"``: a combination of ``R``/``W``/``E`` + - ``"datatype"``: see [resource data types](#resource-data-types) section + below + - ``"multiple"``: (optional) boolean flag indicating that the script + represents a Multiple Resource. If omitted, it is assumed to be false + - ``"name"``: (optional) human-readable resource name + - ``"description"``: (optional) human-readable description of the resource + - ``"external-notify"``: (optional) enables external notification mechanism, + for this resource. See also + [external notify](#fsdm-external-notify-trigger) section + + Example: + + ```json + { + "operations": "RW", + "datatype": "opaque", + "multiple": false, + "name": "Data", + "description": "Some data" + } + ``` + +### Resource script options + +- ``--instance ID`` - ID of the LwM2M Instance being referred to. May not be + present if a specific Object Instance is not relevant, e.g. when querying + resource metadata. +- ``--resource-instance ID`` - ID of the LwM2M Multiple Resource Instance being + referred to. May not be present if the operation targets a Single Resource or + the Multiple Resource as a whole. +- ``--args ARGUMENTS...`` - Execute operation arguments. Only present if + ``OPERATION`` is ``execute``. Always passed as the last option, all arguments + that follow ``--args`` are to be interpreted as arguments to Execute + operation. ``--args`` may be omitted if the list of Execute arguments is + empty.
+ Each ``ARGUMENT`` can be either: + - a single digit, + - ``N=CONTENT`` string, where N is a single digit, and CONTENT is a string + consisting of any characters allowed within the Execute argument by the + LwM2M spec (space is not allowed). Badly formatted arguments from server + request won't be ever passed to the script. + + For example: + ``` + --args 2=foo 1 8=bar + ``` + +### Multiple Resources + +Multiple Resources are still implemented as single scripts. LwM2M requests map +to script operations as follows: + +- LwM2M Read: ``list`` + ``read`` on each Multiple Resource Instance, +- LwM2M Write (replace): ``delete`` + ``write`` on each Multiple Resource + Instance, +- LwM2M Write (update): ``write`` on each Multiple Resource Instance, +- LwM2M Execute: always fails with Method Not Allowed. Never calls the script. + +### Resource data types + +Data types used on the LwM2M layer SHOULD correspond to the schema definition. +Each resource script MUST support the ``describe`` operation, which MUST return +accurate resource metadata. + +- `string`: UTF-8 encoded plain text +- `integer`: stringified integer +- `float`: stringified double-precision floating-point value +- `boolean`: stringified integer `0` or `1` +- `opaque`: opaque binary data +- `time`: seconds since Unix epoch; same representation as integer +- `objlnk`: ``OID:IID`` string, where `OID` and `IID` are valid stringified + Object/Instance IDs + +!!! Note + - ``read`` operation MUST write data of correct type on standard output. + + - Implementations MAY assume data passed to the standard input when invoking + ``write`` operation have correct data type. + +### Script exit status + +The following exit status codes are handled by Svetovid: + +- ``0`` indicates successful execution. +- ``100`` - ``131`` - cause Svetovid to respond to the LwM2M server with a CoAP + error from the ``4.xx`` range, e.g.: + - ``100`` - *4.00 Bad Request* + - ``104`` - *4.04 Not Found* + - ``115`` - *4.15 Unsupported Content-Format* + - etc. + +- ``200`` - ``231`` - cause Svetovid to respond to the LwM2M server with a CoAP + error from the ``5.xx`` range, e.g.: + - ``200`` - *5.00 Internal Server Error* + - ``201`` - *5.01 Not Implemented* + - etc. + +!!! Note + See [CoAP RFC](https://tools.ietf.org/html/rfc7252#section-12.1.2) for a + more detailed list of CoAP response codes. + +## FSDM instances script + +``instances`` script is called as follows: + +``` +instances OPERATION [ ID ] +``` + +``OPERATION`` is one of: + +- ``list`` - the script should print a whitespace-separated list of valid + Instance IDs for its object. +- ``create ID`` - the script should create an LwM2M Object Instance when called. + This operation takes an ``ID`` argument, which is an integer in the [0; 65534] + range that MUST be used as the ID of created instance. The script MUST follow + [script exit status](#script-exit-status) to return operation status + (success/failure). + - After a successful ``create``, the newly created Instance ID MUST become + visible in the output of ``list`` operation. + - An attempt to ``create`` an Instance ID that is already present MUST fail + with a "4.00 Bad Request" code. Failure caused by any other reason MUST + result in an exit status representing a CoAP code from the 5.xx range (see + [script exit status](#script-exit-status)). + - The ``create`` operation MUST initialize all resources for the newly + created instance to their default values. If a particular resource has no + default value, it MUST be left undefined. The ``create`` operation will be + followed by a series of ``write`` operations which may fill them as + required, after which the ``transaction`` script is called to either + commit or rollback changes. + + See [transaction script](#fsdm-transaction-script) for details. + +- ``delete ID`` - the script should delete an instance ``ID`` if one exists. +- ``describe`` - returns Object metadata in JSON format, including: + - ``version`` - (optional) object version number, as described in + [LwM2M Core TS section 7.2](https://www.openmobilealliance.org/release/LightweightM2M/V1_1_1-20190617-A/HTML-Version/OMA-TS-LightweightM2M_Core-V1_1_1-20190617-A.html#7-2-0-72-Object-Versioning) + - ``"external-notify"`` - (optional) enables external notification mechanism + for the set of instances of this object.
+ See also [external-notify](#fsdm-external-notify-trigger). + +!!! Note + The ``instances`` script MAY not be present, in which case the Object is + assumed to be a Single-Instance Object, for which an Instance ID 0 always + exists and cannot be deleted.
+ When it is present, all operations other than ``list`` are optional. + +## FSDM transaction script + +``transaction`` script, if present, is called before and after every mutating +operation on an LwM2M object, i.e. Write/Create/Delete. + +``` +transaction OPERATION +``` + +``OPERATION`` is one of: + +- ``begin`` - called before the mutating LwM2M request to set up a savepoint + for future rollback.
+ The exit status of this script MUST follow the + [script exit status](#script-exit-status) rules. +- ``validate`` - called after the mutating LwM2M request. This operation checks + if the object is in a consistent state after all modifications. It MUST also + make sure that ``commit`` will be successful (see ``commit`` operation + description for more details). If ``validate`` fails, ``rollback`` is + performed. +- ``commit`` - called after all atomic operations the LwM2M request is split + into succeeded, to make sure they are actually applied. + + !!! Warning + If this operation fails, the data model will be left in an inconsistent + state (``rollback`` will not be invoked). For this reason, it may return + an error code if and only if a fatal, unpredictable and irrecoverable + error (e.g. physical I/O error) occurs. All other errors (e.g. being a + consequence of invalid object state) MUST be reported by ``validate`` + operation beforehand. + +- ``rollback`` - called after some of the atomic operations the LwM2M request is + split into fails. This operation MUST restore LwM2M object to the state it was + in at the point ``begin`` was called. + +!!! Note + The ``transaction`` script MAY not be present, in which the Object is + assumed to not require transactional processing of any kind. This is NOT + recommended if the object implements any writable resources or Create/Delete + operation on instances. + +## FSDM external Notify trigger + +There are two ways Svetovid can be notified about changes occurring in the File +System Data Model. + +1. **Pull-mode**: The default mode. Svetovid regularly polls ``instances list`` + and ``resource read`` operations to check if some changes in their outputs + have appeared. +2. **Push-mode** (external notify): The mode in which it is the user + responsibility to notify Svetovid about the following changes in FSDM: + - list of valid Instance IDs for an object (returned value of + ``instances list`` operation) has changed for **other** reason than + calling ``instances create`` or ``instances delete`` by Svetovid + - readable resource has changed its value for **other** reason than + calling ``write``, ``reset`` or ``clear`` by Svetovid + +### Usage + +To activate "Push-mode" for an object instance or a resource, user has to +explicitly enable that mode in the resource or instances scripts: + +- For `python` based scripts generated by ``fsdmtool``, for readable entities, + the class constant ``EXTERNAL_NOTIFY`` should be set to ``True`` (default + value is ``False``). +- For `sh` based scripts generated by ``fsdmtool``, for readable entities, + ``RESOURCE_EXTERNAL_NOTIFY`` and ``INSTANCES_EXTERNAL_NOTIFY`` should be set + to ``"true"`` (default value is ``"false"``). +- For scripts manually crafted, one should make sure that the ``describe`` + operation of the entity also returns ``"external-notify": true``. + +After enabling the functionality, it is possible to use special Unix domain +socket to notify about value changes. The socket is created after Svetovid +launch in Svetovid temporary directory (by default: ``/tmp/fsdm_local_socket``). + +!!! Note + Push mode may also be enabled for Resources whose values never change, and + for instance sets of objects whose instance sets never change. In this case, + it is enough to just set the external notify flag to true without the need + to send notifications to Svetovid. + +User may send JSON containing information about changed state of instances and +resources as follows: + +```json +{ "notify": ["/10", "/20", "/9/0/1", "/9/0/2"] } +``` + +In example above we want to inform that: + +- instances lists of objects 10 and 20 have changed +- values of resources ``/9/0/1`` and ``/9/0/2`` have changed + +If any of these resources is indeed observed, Svetovid will then invoke the Read +operation on the appropriate FSDM script to query the actual resource value. + +To send the message through the socket user can use standard tools like `nc` or +`socat`. + +#### nc + +```sh +echo '{ "notify": ["/10", "/20", "/9/0/1", "/9/0/2"] }' | nc -NU /tmp/fsdm_local_socket +``` + +!!! Note + Option ``-N`` is set because `nc` should shutdown the socket after EOF on + the input. + +#### socat + +```sh +echo '{ "notify": ["/10", "/20", "/9/0/1", "/9/0/2"] }' | socat - UNIX-CONNECT:/tmp/fsdm_local_socket +``` + +#### Native socket API + +User can use standard socket API of his preferred programming language. These +are important things to remember about user-side socket: + +- socket domain should be `AF_UNIX` / `AF_LOCAL` +- socket type should be `SOCK_STREAM` +- after sending the whole message the socket should be shut down for further + transmissions (`SHUT_WR` flag) + +### Response + +As a result of triggering a notify a response is sent through the socket. There +are 3 kinds of result: + +1. ``{"result": "OK"}``: There were no errors during triggering a notify. +2. ``{"result": "warning", "details": [ ... ] }``: In this case some of entries + could not be processed and the reasons for each entry are indicated in + `details` section. Entries omitted in `details` section were perfectly valid + and there is no need to try notifying them again. +3. ``{"result": "error", "details": "..." }``: There was some serious problem + with execution of user request (e.g. parsing error). In this case **all + entries** should be considered as **not processed**. + +#### Examples + +``"details"`` section for ``"OK"`` result is absent: + +```sh +user@host $ echo '{ "notify": ["/1337"] }' | nc -NU /tmp/fsdm_local_socket +{ + "result": "OK" +} +user@host $ +``` + +``"details"`` for ``"warning"`` result is an array of failure reasons: + +```sh +user@host $ echo '{ "notify": [":-)", "/1/2/3"] }' | nc -NU /tmp/fsdm_local_socket +{ + "result": "warning", + "details": [ + { + "path": ":-)", + "reason": "not object or resource path" + }, + { + "path": "\/1", + "reason": "non-FSDM object" + } + ] +} +user@host $ +``` + +``"details"`` for the ``"error"`` result is a single diagnostic string: + +```sh +user@host $ echo abcdefgh | nc -NU /tmp/fsdm_local_socket +{ + "result": "error", + "details": "malformed input" +} +user@host $ +``` + +## Triggering Send message + +Svetovid may be forced to generate a Send message where he will inform the +server about a specific resource. Similar to the Notify trigger in +**push-mode** the user can pass a JSON to the Unix domain socket to communicate +with Svetovid: + +```json +{ "send": ["/10", "/20/0", "/9/0/1", "/9/0/2"] } +``` + +In this example we will send to the LwM2M server: + +- all values of resources in all of the instances of object 10 +- all values of resources in ``/20/0`` +- values of resources ``/9/0/1`` and ``/9/0/2`` + +## FSDM key-value store for keeping volatile object state + +Sometimes, when implementing an object, there's a need to keep track of some +information for the object to function properly. An example could be an object +with two Resources: "Current Value" and "Max Value". + +To implement the "Max Value" Resource, one has to keep track of the values +being presented and save the largest one seen so far somewhere. One way to do +it would be by using some kind of temporary file storage. Another way is to +used our pre-implemented simple key-value store accessible through +``/tmp/fsdm_local_socket`` socket. + +### Supported commands + +#### set + +Sets or replaces keys to specified values. Example use: + +```sh +user@host $ echo '{ "store": { "set": { "foo1": "bar", "foo2": "baz" } } }' | nc -NU /tmp/fsdm_local_socket +{ + "result": "OK" +} +user@host $ +``` + +Which sets `foo1` to `bar` and `foo2` to `baz`. + +#### get + +```sh +user@host $ echo '{ "store": { "get": ["foo1", "foo2"] } }' | nc -NU /tmp/fsdm_local_socket +{ + "result": "OK", + "details": { + "foo1": "bar", + "foo2": "baz" + } +} +user@host $ +``` + +Gets the value assigned to keys `foo1` and `foo2`. Note that it is possible to +get more than one key, and if the key is not set, it is not returned. + +#### delete + +```sh +user@host $ echo '{ "store": { "delete": ["foo1"] } }' | nc -NU /tmp/fsdm_local_socket +{ + "result": "OK" +} +user@host $ +``` + +Deletes the key `foo1` and a key assigned to it from the store. diff --git a/docs/LwM2M_Client/Svetovid/Intro.md b/docs/LwM2M_Client/Svetovid/Intro.md new file mode 100644 index 00000000..a6fba63f --- /dev/null +++ b/docs/LwM2M_Client/Svetovid/Intro.md @@ -0,0 +1,8 @@ +# What is Svetovid? + +[Svetovid](https://github.com/AVSystem/Svetovid) is a complete LwM2M client +based on [Anjay library](https://github.com/AVSystem/Anjay), supporting several +Linux-based platforms. + +Svetovid provides an easy-to-use [FSDM (File System Data Model)](FSDM.md) +mechanism, allowing to implement LwM2M objects using Python or Bash scripts. diff --git a/docs/LwM2M_Client/Svetovid/Supported_Platforms/generic.md b/docs/LwM2M_Client/Svetovid/Supported_Platforms/generic.md new file mode 100644 index 00000000..3a8a110c --- /dev/null +++ b/docs/LwM2M_Client/Svetovid/Supported_Platforms/generic.md @@ -0,0 +1,368 @@ +# generic + +The ``generic`` platform allows running a minimal subset of Svetovid's +functionality on any otherwise unsupported platform. It is mostly intended for +testing and prototyping. + +## Supported hardware + +In principle, the ``generic`` target can be used on any device that is capable +of running Linux. It is primarily developed and tested on [Ubuntu +Desktop](https://ubuntu.com/download/desktop). + +Packaging this type of build as a Docker container is also officially supported. + +There is also an additional Docker image that integrates Svetovid with +OpenThread Border Router functionality. It is based on the official +[ot-br-posix](https://github.com/openthread/ot-br-posix) container, and adds +the functionality of managing the OTBR remotely via LwM2M. Please refer to the +documentation of that project for information about the hardware supported as +the Thread radio. + +More information about the OpenThread Border Router variant can be found in +AVSystem IoT Developer Zone article: [OpenThread Border Router configurable +through LwM2M server]({{ svetovid_devzone_doc_prefix }}/LwM2M_Client/OpenThread/OTBR_with_svetovid). + +!!! Note + Svetovid **only supports operating systems based on the Linux kernel**. If + you wish to run it on a machine that runs another operating system such as + Windows, macOS or \*BSD, please use a virtual machine or container runtime + (e.g. Docker) running Linux. + +## Features + +### Implemented objects + +Without any external additions, the ``generic`` platform implements the +following LwM2M objects: + +- Security (/0), +- Server (/1), +- Device (/3), +- Firmware Update (/5) - as a stub, +- Portfolio (/16), +- Event Log (/20). + +The commercial version also supports [FSDM](../FSDM.md) to facilitate extending +this basic functionality easily. + +The Firmware Update object expects an executable binary for the target platform, +and the update process will just perform ``exec()`` on that binary. This is +intended mostly for testing or as a proof-of-concept, not as a production +solution. + +### OpenThread Border Router + +The ``svetovid_with_otbr`` Docker target adds implementations of the following +objects (based on FSDM): + +- OTBR Configuration (/33630), +- OpenThread Neighbor List (/33633), +- OpenThread Commissioner Joiner Table (/33634), +- OpenThread Neighbor Networks (/33639), +- OpenThread Join Existing Network (/33640). + +!!! Note + The aforementioned objects are part of the Object ID range reserved for + AVSystem's private use, and as such are not standardized under OMA. They may + not be supported by third-party LwM2M Server implementations. + +## Device identity + +!!! Note + This section only applies to the standalone builds. Please see the + [Docker builds](#docker-builds) section for information about configuring + the Docker builds. + +If not configured otherwise (see [Client +Configuration](../Client_Configuration.md)), the client will use the following +information to connect to the LwM2M Server: + +| | | +| :-: | :-: | +| **Endpoint name** | ``urn:dev:os:generic-{hostname}-{machine_id}``
(note: ``{machine_id}`` is the contents of ``/etc/machine-id``) | +| **Default LwM2M Server** | ``coap://127.0.0.1:5683`` | + +!!! Note + DTLS is disabled in the default configuration. To enable it, the PSK key + needs to be configured explicitly in the + [security.json](../Client_Configuration.md#connection-settings) file. + +## Build instructions + +### Standalone build + +To do a standalone build of Svetovid, you will need the following prerequisites: + +- Clang (or GCC; Clang is recommended) with C++ support and all the essential + build dependencies +- CMake 3.6.3 or newer +- Git +- Zlib (optional, you can use ``-DWITH_AVS_HTTP_ZLIB=OFF`` CMake option to + remove this dependency, at the cost of no support for HTTP compression) +- Boost C++ Libraries (optional, you can use ``-DWITH_SYSTEM_BOOST=OFF`` CMake + option to download Boost as part of the build process instead) + +On Ubuntu 20.04, you can install all the required dependencies by running the +following commands (identical or similar commands should work on other +distributions from the Debian family; finding packages for other distributions +is outside the scope of this documentation): + +```sh +sudo apt update && +sudo apt install \ + build-essential \ + clang \ + cmake \ + git \ + libboost-all-dev \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + zlib1g-dev +``` + +The preferred way to build Svetovid for the ``generic`` target on the host +platform itself is running: + +```sh +git submodule update --init --recursive +env CC=clang CXX=clang++ cmake -DTARGET_PLATFORM=generic . +make -j$(nproc) +``` + +To additionally build the Debian packages, run: + +```sh +make package +``` + +### Docker image build + +The dockerfile is called ``Dockerfile.clean_svetovid`` and it is located in the +``dockerfiles`` directory within the source tree root. + +Docker build process is multi-stage, which means that there is an intermittent +image created used for the build process itself. The final Svetovid image +contains only necessary stuff and is as lightweight as possible. + +To build the Docker image, run: + +```sh +git submodule update --init --recursive +docker build . -f ./dockerfiles/Dockerfile.clean_svetovid +``` + +You may also optionally pass other arguments to ``docker build``, for example +the ``--tag`` parameter to automatically tag the resulting image (e.g. ``--tag +svetovid``), or the ``--platform`` image to build an image for a foreign +platform (e.g. ``--platform linux/arm/v7`` for running on a Raspberry Pi). + +## Installation instructions + +### Standalone installation instructions + +After running ``make package``, the following Debian packages will be created: + +- **svetovid_{version}_{architecture}.deb** - base binary of Svetovid itself and + the systemd service unit file; note: the post-install script will + automatically start Svetovid as a daemon + +Additionally in the commercial version only: + +- **svetovid-plugin-fsdm_{version}_{architecture}.deb** - dynamically loadable + library that enables the FSDM functionality in Svetovid +- **avsystem_svetovid-{version}-Linux-fsdmtool.deb** - + [fsdmtool](../FSDM.md#fsdm-script-stub-generator) script, that allows creating + stubs of FSDM scripts from XML object definitions and/or downloading them from + the LwM2M Object Registry +- **avsystem_svetovid-{version}-Linux-fsdmtool-runtime-python.deb** - runtime + library used by the Python scripts generated by ``svetovid-fsdmtool`` +- **avsystem_svetovid-{version}-Linux-fsdmtool-runtime-sh.deb** - runtime + library used by the shell scripts generated by ``svetovid-fsdmtool`` + +The preferred method of installing Svetovid is to install some or all of the +aforementioned files, depending on your needs, for example: + +```sh +sudo apt install ./*.deb +``` + +If you're running an RPM-based distribution, you can use ``alien`` (installing +``alien`` itself is beyond the scope of this documentation) to convert the +``*.deb`` files into ``*.rpm`` and install those: + +```sh +sudo alien --to-rpm --scripts *.deb +sudo rpm --replacefiles -ivh *.rpm +``` + +### Docker installation instructions + +The Docker build does not require additional installation - the built image is +ready to run. You may tag it for your convenience - any further instructions +will assume that the image has been tagged as just ``svetovid``. + +## Directory structure of an installed client + +Assuming that all the packages mentioned above are installed: + +- ``/etc/svetovid/`` + - ``/etc/svetovid/config/`` - configuration files, see + [Client Configuration](../Client_Configuration.md) + - ``/etc/svetovid/dm/`` - default directory for FSDM-based object + implementations + + !!! Note + In the Docker builds, this directory is initially populated with + files from the ``dockerfiles/docker-init-files/dm/`` subdirectory of + the source repository; that contains an alternative implementation + of the Device (/3) object. + + - ``/etc/svetovid/persistence/`` - data persisted across firmware updates + - ``/etc/svetovid/volatile_persistence/`` - data persisted across reboots, + but not firmware updates + +- ``/tmp/`` - temporary directory used by the Firmare Update object and the + [FSDM](../FSDM.md) plugin + - ``/tmp/fsdm_local_socket`` - UNIX domain socket used for additional + communication between the [FSDM](../FSDM.md) scripts and the Svetovid + binary +- ``/usr/`` + - ``/usr/bin/svetovid`` - main LwM2M client executable + - ``/usr/bin/svetovid-fsdmtool`` - convenience symbolic link for the + [fsdmtool](../FSDM.md#fsdm-script-stub-generator) executable + - ``/usr/lib/python2.7/dist-packages/fsdm`` - symbolic link to the + [FSDM](../FSDM.md) Python runtime for Python 2.7 + - ``/usr/lib/python3/dist-packages/fsdm`` - symbolic link to the + [FSDM](../FSDM.md) Python runtime for Python 3 + - ``/usr/lib/svetovid/`` - LwM2M client extensions loaded at runtime + - ``/usr/lib/svetovid/libfsdm_plugin.so`` - [FSDM](../FSDM.md) support + plugin + - ``/usr/lib/systemd/system/svetovid.service`` - systemd unit file for + Svetovid + - ``/usr/local/share/svetovid/`` - [FSDM](../FSDM.md) runtime and utilities + - ``/usr/local/share/svetovid/bin/svetovid-fsdmtool`` - main executable + for the [fsdmtool](../FSDM.md#fsdm-script-stub-generator) + - ``/usr/local/share/svetovid/bin/fsdm/`` - + [fsdmtool](../FSDM.md#fsdm-script-stub-generator) support modules + - ``/usr/local/share/svetovid/lib/fsdm/python/`` - [FSDM](../FSDM.md) + runtime for Python + - ``/usr/local/share/svetovid/lib/fsdm/sh/`` - [FSDM](../FSDM.md) + runtime for shell scripts + +### Additional files used by the Docker images + +- ``/etc/svetovid/svetovid_start.sh`` is the entry point of the Docker + container; this script starts the Svetovid process and allows to modify basic + LwM2M configuration (endpoint name, DTLS PSK identity and key, server + hostname) with the use of ENV values while starting the container (see the + [Docker builds](#docker-builds) section) + - The variant with OTBR support additionally contains + ``/etc/svetovid/svetovid_start_otbr.sh`` and uses that as the entry point. + That script launches both the OTBR and Svetovid startup scripts + concurrently. +- The ``/etc/svetovid/config/`` directory contains files copied from the + ``dockerfiles/docker-init-files/config/`` subdirectory of the source + repository; this is required for proper handling of startup with configuration + based on environment variables. +- The ``/etc/svetovid/dm/`` directory contains files copied from the + ``dockerfiles/docker-init-files/dm/`` subdirectory of the source repository; + that contains an alternative implementation of the Device (/3) object. + - The variant with OTBR supports also includes implementations of the objects + related to OpenThread. +- ``/var/cache/svetovid/`` - in the variant with OTBR support, contains data + related to the OTBR state, cached to limit the number of accesses to the OTBR + daemon socket, and to implement transactionality of modifications by the LwM2M + Server. +- ``/run/openthread-wpan0.sock`` - local UNIX-domain socket used for + communication with the OTBR daemon (note: this is part of the ``ot-br-posix`` + package and not related to Svetovid, but used by OTBR object implementations) +- ``/run/sve-openthread-wpan0.lock`` - in the variant with OTBR support, this + file is used to synchronize accesses to the OTBR daemon socket. + +## Launch instructions + +### Standalone build + +Svetovid is configured to launch through ``systemd`` and the install scripts +enable and launch it by default. + +To manually start the client, use: + +```sh +sudo systemctl start svetovid +``` + +To manually stop the client, use: + +```sh +sudo systemctl stop svetovid +``` + +LwM2M client process logs are sent to syslog. To access them, either: + +- read syslog directly, e.g.: + + ```sh + journalctl -fu svetovid + ``` + +- or stop the LwM2M client service as described above, then run it in the + foreground: + + ```sh + /usr/bin/svetovid + ``` + +### Docker builds + +The Docker builds use the following environment variables to configure the +LwM2M Client: + +- ``EP`` - LwM2M Client's endpoint name *as well as* DTLS Identity +- ``PSK`` - LwM2M Client's PSK in plain-text +- ``SERVER_HOST`` - LwM2M Server's endpoint (e.g. ``{{ coiote_server }}``) + +### Examples + +- run Svetovid LwM2M Client in background (as a daemon) + + ```sh + docker run -d -e EP='foo' -e PSK='bar' -e SERVER_HOST='{{ coiote_server }}' svetovid + ``` + +- stop LwM2M Client by stopping Svetovid container + + ```sh + docker stop + ``` + +- resume LwM2M Client by stopping Svetovid container + + ```sh + docker start + ``` + +- run container interactively with automatic container deletion after existing + + ```sh + docker run -it --rm -e EP='foo' -e PSK='bar' -e SERVER_HOST='{{ coiote_server }}' svetovid + ``` + +- run container with custom Svetovid log level e.g. to troubleshoot + + ```sh + docker run -it --rm -e EP='foo' -e PSK='bar' -e SERVER_HOST='{{ coiote_server }}' -e LOG_LEVEL='debug' svetovid + ``` + +- start container without running the Sevetovid LwM2M client (e.g. to prototype your own objects) + + ```sh + docker run -it -e EP='foo' -e PSK='bar' -e SERVER_HOST='{{ coiote_server }}' svetovid /bin/bash + ``` + +- run container interactively with OTBR (remember to connect RCP and edit its path if necessary) + + ```sh + docker run --rm --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" -p 8080:80 -p 8081:8081 --dns=127.0.0.1 -it --volume /dev/ttyACM0:/dev/ttyACM0 --privileged -e DNS64_ONLY=1 -e EP='foo' -e PSK='bar' -e SERVER_HOST='{{ coiote_server }}' openthread/svetovid_with_otbr --radio-url spinel+hdlc+uart:///dev/ttyACM0 + ``` diff --git a/docs/LwM2M_Client/Svetovid/Supported_Platforms/moxa.md b/docs/LwM2M_Client/Svetovid/Supported_Platforms/moxa.md new file mode 100644 index 00000000..dff91f19 --- /dev/null +++ b/docs/LwM2M_Client/Svetovid/Supported_Platforms/moxa.md @@ -0,0 +1,245 @@ +# moxa + +The ``moxa`` target is intended for [Moxa](https://www.moxa.com/) industrial +devices based on ARM Debian. + +## Supported hardware + +The officially supported device that was used for development and testing is +[Moxa UC-2116-T-LX](https://moxastore.express-inc.com/UC_2116_T_LX_p/uc-2116-t-lx.html) +running Debian 9, however, it should also work on other devices based on the +same OS. + +## Features + +### Implemented objects + +Without any external additions, the ``moxa`` platform implements the following +LwM2M objects: + +- Security (/0), +- Server (/1), +- Device (/3), +- Connectivity Monitoring (/4), +- Firmware Update (/5) - as a stub, +- Location (/6), +- LWM2M APN Connection Profile (/11), +- Portfolio (/16), +- Event Log (/20), +- Modbus Connection (/10374), +- Modbus Register Cluster (/10375). + +The commercial version also supports [FSDM](../FSDM.md) to facilitate extending +this basic functionality easily. + +The Firmware Update object expects an executable binary for the target platform, +and the update process will just perform ``exec()`` on that binary. This is +intended mostly for testing or as a proof-of-concept, not as a production +solution. + +### ModBus support + +This target platform includes support for the ModBus protocol, based on the +libmodbus library. + +## Device identity + +If not configured otherwise (see [Client +configuration](../Client_Configuration.md)), the client will use the following +information to connect to the LwM2M Server: + +| | | +| :-: | :-: | +| **Endpoint name** | ``moxa`` | +| **Default LwM2M Server** | ``coap://127.0.0.1:5683`` | + +!!! Note + DTLS is disabled in the default configuration. To enable it, the PSK key + needs to be configured explicitly in the + [security.json](../Client_Configuration.md#connection-settings) file. + +## Build instructions + +### Build environment + +1. Install Debian 9. A virtual machine, chroot environment or a container is + recommended for development. + - Main repositories for Debian 9 are no longer maintained. You may need to + edit ``/etc/apt/sources.list`` to use + [http://archive.debian.org/](http://archive.debian.org/) or + [http://snapshot.debian.org/](http://snapshot.debian.org/). +2. Add ``/etc/apt/sources.list.d/moxa.sources.list`` file with the following + line: + ```sh + deb http://debian.moxa.com/debian stretch main contrib non-free + ``` +3. Run ``apt-get update``, ``apt-get install moxa-archive-keyring`` and + ``apt-get update`` once again. +4. Execute ``dpkg --add-architecture armhf`` and then ``apt-get update`` once + again, to be able to install non-amd64 packages. +5. Install the toolchain and required built-time dependencies: + ```sh + apt install \ + cmake \ + crossbuild-essential-armhf \ + git \ + pkg-config + ``` +6. Install libmodbus development package: + ``apt-get install libmodbus-dev:armhf`` (note: this conflicts with + ``libmodbus-dev`` for the host platform, so a dedicated development VM or + chroot environment is highly recommended) + +### Compilation + +To compile Svetovid for Moxa industrial computers, run: + +```sh +git submodule update --init --recursive +cmake \ + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/arm-linux-gnueabihf.cmake \ + -DTARGET_PLATFORM=moxa \ + -DWITH_AVS_HTTP_ZLIB=OFF \ + -DWITH_SYSTEM_BOOST=OFF \ + . +make -j$(nproc) +make package +``` + +!!! Note + Boost C++ Libraries will be downloaded and built as part of the build + process. + +The ``*.deb`` files ready to install on the device will be generated in the +source root directory. + +## Installation instructions + +### Preparing the device + +``libmodbus5`` needs to be installed on the Moxa device for it to be able to run +Svetovid. It is not installed by default. + +To install ``fsdmtool`` or ``fsdmtool-runtime-python`` (only available in the +commercial version), **Python** has to be installed on the Moxa device itself. +It is not installed by default. + +You can install these dependencies by running: + +```sh +sudo apt-get update +sudo apt-get install libmodbus5 python3 +``` + +### Installing the packages + +The build result is the following set of Debian packages: + +- **svetovid_{version}_armhf.deb** - base binary of Svetovid itself and the + systemd service unit file; note: the post-install script will automatically + start Svetovid as a daemon + +Additionally, the following packages can be built from the commercial codebase: + +- **svetovid-plugin-fsdm_{version}_{version}.deb** - dynamically loadable + library that enables the FSDM functionality in Svetovid +- **avsystem_svetovid-{version}-Linux-fsdmtool.deb** - + [fsdmtool](../FSDM.md#fsdm-script-stub-generator) script, that allows creating + stubs of FSDM scripts from XML object definitions and/or downloading them from + the LwM2M Object Registry +- **avsystem_svetovid-{version}-Linux-fsdmtool-runtime-python.deb** - runtime + library used by the Python scripts generated by ``svetovid-fsdmtool`` +- **avsystem_svetovid-{version}-Linux-fsdmtool-runtime-sh.deb** - runtime + library used by the shell scripts generated by ``svetovid-fsdmtool`` + +You can put those files on the industrial computer using any method available, +e.g. using a USB drive, or by copying them using ``scp`` (requires SSH to be +enabled on the device): + +```sh +scp *.deb {Moxa_IP_ADDRESS}:/tmp/ +``` + +The preferred method of installing Svetovid is to install some or all of the +aformentioned files, depending on your needs, for example (on the Moxa device +terminal): + +```sh +sudo apt install /tmp/*.deb +``` + +## Directory structure of an installed client + +Assuming that all the packages mentioned above are installed: + +- ``/etc/svetovid/`` + - ``/etc/svetovid/config/`` - configuration files, see + [Client configuration](../Client_Configuration.md) + - ``/etc/svetovid/dm/`` - default directory for FSDM-based object + implementations + - ``/etc/svetovid/persistence/`` - data persisted across firmware updates + - ``/etc/svetovid/volatile_persistence/`` - data persisted across reboots, + but not firmware updates +- ``/tmp/`` - temporary directory used by the Firmare Update object and the + [FSDM](../FSDM.md) plugin + - ``/tmp/fsdm_local_socket`` - UNIX domain socket used for additional + communication between the [FSDM](../FSDM.md) scripts and the Svetovid + binary +- ``/usr/`` + - ``/usr/bin/svetovid`` - main LwM2M client executable + - ``/usr/bin/svetovid-fsdmtool`` - convenience symbolic link for the + [fsdmtool](../FSDM.md#fsdm-script-stub-generator) executable + - ``/usr/lib/python2.7/dist-packages/fsdm`` - symbolic link to the + [FSDM](../FSDM.md) Python runtime for Python 2.7 + - ``/usr/lib/python3/dist-packages/fsdm`` - symbolic link to the + [FSDM](../FSDM.md) Python runtime for Python 3 + - ``/usr/lib/svetovid/`` - LwM2M client extensions loaded at runtime + - ``/usr/lib/svetovid/libfsdm_plugin.so`` - [FSDM](../FSDM.md) support + plugin + - ``/usr/lib/systemd/system/svetovid.service`` - systemd unit file for + Svetovid + - ``/usr/local/share/svetovid/`` - FSDM runtime and utilities + - ``/usr/local/share/svetovid/bin/svetovid-fsdmtool`` - main executable + for the [fsdmtool](../FSDM.md#fsdm-script-stub-generator) + - ``/usr/local/share/svetovid/bin/fsdm/`` - + [fsdmtool](../FSDM.md#fsdm-script-stub-generator) support modules + - ``/usr/local/share/svetovid/lib/fsdm/python/`` - [FSDM](../FSDM.md) + runtime for Python + - ``/usr/local/share/svetovid/lib/fsdm/sh/`` - [FSDM](../FSDM.md) + runtime for shell scripts + +## Launch instructions + +Svetovid is configured to launch through ``systemd`` and the install scripts +enable and launch it by default. + +To manually start the client, use: +```sh +sudo systemctl start svetovid +``` + +To manually stop the client, use: +```sh +sudo systemctl stop svetovid +``` + +LwM2M client process logs are sent to syslog. To access them, either: + +- read syslog directly, e.g.: + ```sh + journalctl -fu svetovid + ``` +- or stop the LwM2M client service as described above, then run it in + foreground: + ```sh + /usr/bin/svetovid + ``` + +## ModBus configuration + +The built-in serial ports of the Moxa computer are switchable between RS-232 and +RS-485 modes, but the way this is configured on this hardware is incompatible +with libmodbus. To make these serial ports work, the ports shall always be +configured as RS-232 in the Modbus Connection object. The actual mode of +operation can be configured via the device's command line using the +``mx-uart-ctl`` utility. diff --git a/docs/LwM2M_Client/Svetovid/Supported_Platforms/raspberry.md b/docs/LwM2M_Client/Svetovid/Supported_Platforms/raspberry.md new file mode 100644 index 00000000..161fc2e3 --- /dev/null +++ b/docs/LwM2M_Client/Svetovid/Supported_Platforms/raspberry.md @@ -0,0 +1,362 @@ +# raspberry + +The ``raspberry`` platform is intended to run on Raspberry Pi devices and +implements a couple of additional functionalities on top of the basic client. +It is mostly intended as a base for implementing application-specific objects +using the [FSDM](../FSDM.md). + +The port of Svetovid for the Raspberry Pi is intended as a **LwM2M Starter +Kit** -- a hardware+software package that also contains the Pi itself. Binaries +prebuilt for this purpose are available on GitHub: [Svetovid Raspberry +Client](https://github.com/AVSystem/Svetovid-raspberry-client). + +## Supported hardware + +The ``raspberry`` target is intended to be compatible with all mainstream +Raspberry Pi models. It is primarily tested on [Raspberry Pi OS]( +https://www.raspberrypi.com/software/operating-systems/), which is a version +of Debian, but should in principle work on any mainstream Linux distribution. + +This target also includes an implementation of objects for some additional +peripherals, namely: + +- Generic push-buttons connected to GPIO pins +- Generic LED lights connected to GPIO pins +- The Raspberry Pi [Sense HAT](https://www.raspberrypi.com/products/sense-hat/) + +## Features + +### Implemented objects + +The core Svetovid binary build for the ``raspberry`` platform implements the +following LwM2M objects: + +- Security (/0), +- Server (/1), +- Device (/3), +- Firmware Update (/5) - as a stub, +- Portfolio (/16), +- Event Log (/20), +- Light Control (/3311), +- Push button (/3347). + +The Firmware Update object expects an executable binary for the target platform, +and the update process will just perform ``exec()`` on that binary. This is +intended mostly for testing or as a proof-of-concept, not as a production +solution. + +### Sense HAT support + +An optional Sense HAT support package adds implementation of the following +objects (based on FSDM): + +- Temperature (/3303), +- Accelerometer (/3313), +- Magnetometer (/3314), +- Barometer (/3315), +- Gyrometer (/3334), +- Addressable Text Display (/3341). + +## Device identity + +If not configured otherwise (see [Client +configuration](../Client_Configuration.md)), the client will use the following +information to connect to the LwM2M Server: + +| | | +| :-: | :-: | +| **Endpoint name** | ``urn:dev:os:B827EB-{serial_number}``
(note: ``{serial_number}`` is the ``Serial`` field from ``/proc/cpuinfo``) | +| **Default LwM2M Server** | ``coap://127.0.0.1:5683`` | + +!!! Note + DTLS is disabled in the default configuration. To enable it, the PSK key + needs to be configured explicitly in the + [security.json](../Client_Configuration.md#connection-settings) file. + +## Build instructions + +### Building on the Raspberry Pi itself + +To build Svetovid on the Raspberry Pi, you will need the following +prerequisites: + +- Clang (or GCC; Clang is recommended) with C++ support and all the essential + build dependencies +- CMake 3.6.3 or newer +- Git +- Zlib (optional, you can use ``-DWITH_AVS_HTTP_ZLIB=OFF`` CMake option to + remove this dependency, at the cost of no support for HTTP compression) +- Boost C++ Libraries (optional, you can use ``-DWITH_SYSTEM_BOOST=OFF`` CMake + option to download Boost as part of the build process instead) + +On Raspberry Pi OS Bookworm (based on Debian 12), you can install all the +required dependencies by running the following commands (identical or similar +commands should work on other distributions from the Debian family; finding +packages for other distributions is outside the scope of this documentation): + +```sh +sudo apt update && +sudo apt install \ + build-essential \ + clang \ + cmake \ + git \ + libboost-all-dev \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + zlib1g-dev +``` + +The preferred way to build Svetovid for the ``raspberry`` target on the +Raspberry Pi itself is running: + +```sh +git submodule update --init --recursive +env CC=clang CXX=clang++ cmake \ + -DCMAKE_BUILD_TYPE=MinSizeRel \ + -DTARGET_PLATFORM=raspberry \ + . +make -j$(nproc) +``` + +The preferred compiler is Clang, but Svetovid will compile using GCC as well. + +To additionally build the Debian packages, run: + +```sh +make package +``` + +### Cross-compiling + +To build Svetovid for the Raspberry Pi on another machine, you will need: + +- Build environment based on a Debian system in the same version as the target + Raspberry Pi OS (e.g. Debian 12 if targeting Raspberry Pi OS Bookworm) - + either a native installation, a virtual machine, or a container (e.g. Docker) + environment +- GCC cross-compile packages for the target platform (``arm-linux-gnueabihf`` + for 32-bit or ``aarch64-linux-gnu`` for 64-bit) +- CMake 3.6.3 or newer +- Git + +Once in the Debian build environment, you can install all the required +dependencies by running the following commands: + +```sh +sudo apt update && +sudo apt install \ + cmake \ + g++-aarch64-linux-gnu \ + g++-arm-linux-gnueabihf \ + gcc-aarch64-linux-gnu \ + gcc-arm-linux-gnueabihf \ + git \ + python3-sphinx \ + python3-sphinx-rtd-theme +``` + +To cross-compile Svetovid for the Raspberry Pi, run: + +```sh +git submodule update --init --recursive +cmake \ + -DCMAKE_BUILD_TYPE=MinSizeRel \ + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/raspberry-raspbian.cmake \ + -DTARGET_PLATFORM=raspberry \ + -DWITH_AVS_HTTP_ZLIB=OFF \ + -DWITH_GTEST=OFF \ + -DWITH_SYSTEM_BOOST=OFF \ + . +make -j$(nproc) +make package +``` + +!!! Note + To build a 64-bit version, use + ``cmake/toolchain/raspberry-raspbian64.cmake`` as the CMake toolchain file + instead. + +!!! Note + Boost C++ Libraries will be downloaded and built as part of the build + process. + +The ``*.deb`` files ready to install on the Raspberry Pi will be generated in +the source root directory. + +## Installation instructions + +The build result is the following set of Debian packages: + +- **svetovid_{version}_{architecture}.deb** - base binary of Svetovid itself and + the systemd service unit file; note: the post-install script will + automatically start Svetovid as a daemon + +Additionally, the following packages can be built from the commercial codebase +and are available publicly as binaries: + +- **svetovid-plugin-fsdm_{version}_{version}.deb** - dynamically loadable + library that enables the FSDM functionality in Svetovid +- **avsystem_svetovid-{version}-Linux-fsdmtool.deb** - + [fsdmtool](../FSDM.md#fsdm-script-stub-generator) script, that allows creating + stubs of FSDM scripts from XML object definitions and/or downloading them from + the LwM2M Object Registry +- **avsystem_svetovid-{version}-Linux-fsdmtool-runtime-python.deb** - runtime + library used by the Python scripts generated by ``svetovid-fsdmtool`` +- **avsystem_svetovid-{version}-Linux-fsdmtool-runtime-sh.deb** - runtime + library used by the shell scripts generated by ``svetovid-fsdmtool`` +- **avsystem_svetovid-{version}-Linux-sensehat.deb** - implementations of IPSO + sensor object targeting the + [Sense HAT](https://www.raspberrypi.com/products/sense-hat/), based on FSDM + +You can put those files on a Raspberry Pi using any method available, e.g. using +a USB drive, or by copying them using ``scp`` (requires SSH to be enabled on the +Pi): + +```sh +scp *.deb {Pi_IP_ADDRESS}:/tmp/ +``` + +The preferred method of installing Svetovid is to install some or all of the +aformentioned files, depending on your needs, for example (on the Pi terminal): + +```sh +sudo apt install /tmp/*.deb +``` + +## Directory structure of an installed client + +Assuming that all the packages mentioned above are installed: + +- ``/etc/svetovid/`` + - ``/etc/svetovid/config/`` - configuration files, see + [Client configuration](../Client_Configuration.md) + - ``/etc/svetovid/dm/`` - default directory for FSDM-based object + implementations + - The ``sensehat`` package puts implementations of some IPSO objects + here. + - ``/etc/svetovid/persistence/`` - data persisted across firmware updates + - ``/etc/svetovid/volatile_persistence/`` - data persisted across reboots, + but not firmware updates +- ``/tmp/`` - temporary directory used by the Firmare Update object and the + [FSDM](../FSDM.md) plugin + - ``/tmp/fsdm_local_socket`` - UNIX domain socket used for additional + communication between the [FSDM](../FSDM.md) scripts and the Svetovid + binary +- ``/usr/`` + - ``/usr/bin/svetovid`` - main LwM2M client executable + - ``/usr/bin/svetovid-fsdmtool`` - convenience symbolic link for the + [fsdmtool](../FSDM.md#fsdm-script-stub-generator) executable + - ``/usr/lib/python2.7/dist-packages/fsdm`` - symbolic link to the + [FSDM](../FSDM.md) Python runtime for Python 2.7 + - ``/usr/lib/python3/dist-packages/fsdm`` - symbolic link to the + [FSDM](../FSDM.md) Python runtime for Python 3 + - ``/usr/lib/svetovid/`` - LwM2M client extensions loaded at runtime + - ``/usr/lib/svetovid/libfsdm_plugin.so`` - [FSDM](../FSDM.md) support + plugin + - ``/usr/lib/systemd/system/svetovid.service`` - systemd unit file for + Svetovid + - ``/usr/local/share/svetovid/`` - [FSDM](../FSDM.md) runtime and utilities + - ``/usr/local/share/svetovid/bin/svetovid-fsdmtool`` - main executable + for the [fsdmtool](../FSDM.md#fsdm-script-stub-generator) + - ``/usr/local/share/svetovid/bin/fsdm/`` - + [fsdmtool](../FSDM.md#fsdm-script-stub-generator) support modules + - ``/usr/local/share/svetovid/lib/fsdm/python/`` - [FSDM](../FSDM.md) + runtime for Python + - ``/usr/local/share/svetovid/lib/fsdm/sh/`` - [FSDM](../FSDM.md) + runtime for shell scripts + +## Launch instructions + +Svetovid is configured to launch through ``systemd`` and the install scripts +enable and launch it by default. + +To manually start the client, use: +```sh +sudo systemctl start svetovid +``` + +To manually stop the client, use: +```sh +sudo systemctl stop svetovid +``` + +LwM2M client process logs are sent to syslog. To access them, either: + +- read syslog directly, e.g.: + ```sh + journalctl -fu svetovid + ``` + +- or stop the LwM2M client service as described above, then run it in + foreground: + ```sh + /usr/bin/svetovid + ``` + +## IPSO Objects configuration + +The LwM2M IPSO objects do not provide any way to configure sensors, thus they +can only be used to report information from devices already configured by some +other means. + +Right now, the Raspberry Pi client application supports the following IPSO +objects that can represent simple devices connected via the Pi's GPIO header: + +- [IPSO Light control](http://www.openmobilealliance.org/tech/profiles/lwm2m/3311.xml) +- [IPSO Push button](http://www.openmobilealliance.org/tech/profiles/lwm2m/3347.xml) + +Configuration of these IPSO objects should be placed in +``/etc/svetovid/config/``. + +### Pin mapping + +Pin identifiers entered in the configuration files described below are BCM pins. +Refer to [pinout.xyz](https://pinout.xyz/) for example to see where they are +located. + +### IPSO Light control (3311) + +Configuration options: + +- ``data_pin`` - used to control the light (by ``svetovid``), +- ``dimmer`` - PWM controlled light intensity in percents, may be omitted + (default value: 100). + +Example configuration file (`ipso_light.json`): + +```json +{ + "1": { + "data_pin": "20", + "dimmer": "45" + } +} +``` + +To use LED module, connect power supply pins to appriopriate 3.3 V and GND pins +of Raspberry Pi and the signal pin to configured ``data_pin`` of the Raspberry +Pi connector. Depending on LED module used, it's possible to drive the diode via +signal pin, without using 3.3 V power supply. Note, that standalone LED should +be connected via resistor to limit the current to not exceed diode capabilities +or maximum allowed RPi's GPIO current (16 mA). + +### IPSO Push button (3347) + +Configuration options: + +- ``data_pin`` - used to read the button state (by ``svetovid``). + +Example configuration file (`ipso_pushbutton.json`): + +```json +{ + "1": { + "data_pin": "19" + } +} +``` + +One terminal of the push button must be connected to configured ``data_pin``, +while the other one must be connected to 3.3 V power supply (available on pin 1 +and 17 of the RPi connector - not to be confused with BCM pins numbers). diff --git a/docs/LwM2M_Client/Svetovid/Supported_Platforms/yocto.md b/docs/LwM2M_Client/Svetovid/Supported_Platforms/yocto.md new file mode 100644 index 00000000..ec9c0580 --- /dev/null +++ b/docs/LwM2M_Client/Svetovid/Supported_Platforms/yocto.md @@ -0,0 +1,152 @@ +# yocto + +The [Yocto](https://www.yoctoproject.org/) project is, to quote its website, +"an open source collaboration project that helps developers create custom +Linux-based systems regardless of the hardware architecture." Svetovid includes +official support for running under Yocto-based systems. + +## Supported hardware + +The ``yocto`` target does not include any hardware-specific code, so it can be +run on any platform that can run Yocto. + +## Features + +### Implemented objects + +Without any external additions, the ``yocto`` platform implements the following +LwM2M objects: + +- Security (/0), +- Server (/1), +- Device (/3), +- Firmware Update (/5) - as a stub, +- Portfolio (/16), +- Event Log (/20). + +The commercial version also supports [FSDM](../FSDM.md) to facilitate extending +this basic functionality easily. + +The Firmware Update object expects an executable binary for the target platform, +and the update process will just perform ``exec()`` on that binary. This is +intended mostly for testing or as a proof-of-concept, not as a production +solution. + +## Device identity + +If not configured otherwise (see [Client +configuration](../Client_Configuration.md)), the client will use the following +information to connect to the LwM2M Server: + +| | | +| :-: | :-: | +| **Endpoint name** | ``svetovid-yocto`` | +| **Default LwM2M Server** | ``{{ coaps_uri }}`` | +| **Default DTLS PSK Identity** | ``svetovid-yocto`` | +| **Default DTLS PSK** | ``svetovid-yocto-psk`` | + +## Installation instructions + +### As part of the system image + +By default, Svetovid will be included in the system image that is ready to be +installed and booted on the target device. The instructions for installing those +images depend on the target platform, and as such are outside the scope of this +documentation. + +### Through a package manager + +Depending on the configuration, Yocto-based images may also support some +package management system, like [RPM](https://rpm.org/), +[APT](https://en.wikipedia.org/wiki/APT_(software)) or +[OPKG](https://en.wikipedia.org/wiki/Opkg). + +The default configuration of Poky (the reference Yocto distribution) currently +uses RPM. The packages will be generated in the +``build/tmp/deploy/rpm/{platform}`` directory of your Yocto directory: + +- **svetovid-{version}.{platform}.rpm** - all files necessary to run Svetovid + and all the additional plugins and scripts (e.g. [FSDM](../FSDM.md) in the + commercial version) +- **svetovid-dbg-{version}.{platform}.rpm** - debugging symbols for the binaries + contained in the main package +- **svetovid-src-{version}.{platform}.rpm** - source code that was used to build + the main package; note that it does NOT include build scripts and as such is + only usable as a debugging aid +- **svetovid-dev-{version}.{platform}.rpm** - currently empty and unused + +To install Svetovid on an existing device using RPM, copy the main RPM (or IPK) +file onto the device using any method available (e.g. using a USB drive or +``scp``), and run (in case of RPM): + +```sh +rpm -ivh svetovid-*.rpm +``` + +## Directory structure of an installed client + +Assuming that all the packages mentioned above are installed: + +- ``/etc/svetovid/`` + - ``/etc/svetovid/config/`` - configuration files, see + [Client configuration](../Client_Configuration.md) + - ``/etc/svetovid/dm/`` - default directory for FSDM-based object + implementations + - ``/etc/svetovid/persistence/`` - data persisted across firmware updates + - ``/etc/svetovid/volatile_persistence/`` - data persisted across reboots, + but not firmware updates +- ``/tmp/`` - temporary directory used by the Firmare Update object and the + [FSDM](../FSDM.md) plugin + - ``/tmp/fsdm_local_socket`` - UNIX domain socket used for additional + communication between the [FSDM](../FSDM.md) scripts and the Svetovid + binary +- ``/usr/`` + - ``/usr/bin/svetovid`` - main LwM2M client executable + - ``/usr/bin/svetovid-fsdmtool`` - convenience symbolic link for the + [fsdmtool](../FSDM.md#fsdm-script-stub-generator) executable + - ``/usr/lib/python2.7/dist-packages/fsdm`` - symbolic link to the + [FSDM](../FSDM.md) Python runtime for Python 2.7 + - ``/usr/lib/python3/dist-packages/fsdm`` - symbolic link to the + [FSDM](../FSDM.md) Python runtime for Python 3 + - ``/usr/lib/svetovid/`` - LwM2M client extensions loaded at runtime + - ``/usr/lib/svetovid/libfsdm_plugin.so`` - [FSDM](../FSDM.md) support + plugin + - ``/usr/lib/systemd/system/svetovid.service`` - systemd unit file for + Svetovid + - ``/usr/local/share/svetovid/`` - [FSDM](../FSDM.md) runtime and utilities + - ``/usr/local/share/svetovid/bin/svetovid-fsdmtool`` - main executable + for the [fsdmtool](../FSDM.md#fsdm-script-stub-generator) + - ``/usr/local/share/svetovid/bin/fsdm/`` - + [fsdmtool](../FSDM.md#fsdm-script-stub-generator) support modules + - ``/usr/local/share/svetovid/lib/fsdm/python/`` - [FSDM](../FSDM.md) + runtime for Python + - ``/usr/local/share/svetovid/lib/fsdm/sh/`` - [FSDM](../FSDM.md) + runtime for shell scripts + +## Launch instructions + +Svetovid is configured to launch through the System V init scripts and it is +enabled by default. + +To manually start the client, use: +```sh +service svetovid start +``` + +To manually stop the client, use: +```sh +service svetovid stop +``` + +LwM2M client process logs are sent to syslog. To access them, either: + +- read syslog directly, e.g.: + ```sh + tail -f /var/log/messages + ``` + +- or stop the LwM2M client service as described above, then run it in the + foreground: + ```sh + /usr/bin/svetovid + ``` diff --git a/docs/LwM2M_Client/images/raspberry_pi.jpg b/docs/LwM2M_Client/images/raspberry_pi.jpg new file mode 100644 index 00000000..fa6b7e65 Binary files /dev/null and b/docs/LwM2M_Client/images/raspberry_pi.jpg differ diff --git a/mkdocs.yml b/mkdocs.yml index cd6ff7d6..c23ae0b4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -79,6 +79,15 @@ nav: - 'OpenThread': - 'LwM2M_Client/OpenThread/Adding_device.md' - 'LwM2M_Client/OpenThread/OTBR_with_svetovid.md' + - 'Svetovid': + - 'LwM2M_Client/Svetovid/Intro.md' + - 'LwM2M_Client/Svetovid/Client_Configuration.md' + - 'LwM2M_Client/Svetovid/FSDM.md' + - 'Supported Platforms': + - 'LwM2M_Client/Svetovid/Supported_Platforms/generic.md' + - 'LwM2M_Client/Svetovid/Supported_Platforms/moxa.md' + - 'LwM2M_Client/Svetovid/Supported_Platforms/raspberry.md' + - 'LwM2M_Client/Svetovid/Supported_Platforms/yocto.md' - 'Coiote IoT DM': - 'Introduction': 'Coiote_IoT_DM/introduction.md' - 'Connecting devices': diff --git a/templates/default.yaml b/templates/default.yaml index 5b50110f..93323aaf 100644 --- a/templates/default.yaml +++ b/templates/default.yaml @@ -24,3 +24,4 @@ nRF7002DK_flash_downloaded_binary_step: 0. Run `nrfjprog -f NRF53 --program demo_nrf7002dk.hex --verify --reset` Thingy91_binary_step: 0. Download the `demo_thingy91_app_signed.hex` file. +svetovid_devzone_doc_prefix: ""