Device Synchronization
This page describes how the device can update its configuration and firmware via MQTT. The process is called Device Synchronization.
Device Synchronization is initiated by the device.
Synchronization Process
The synchronization process is as follows:
- The device requests a sync by publishing its current firmware names and configuration ETag to the
[topic prefix]/[DevEUI]/req/sync
topic after a reset and during Daily Status. - The backend should respond within 5 seconds by publishing to
[topic prefix]/[DevEUI]/down/sync
with the changed firmware names and/or changed configuration ETag. - If a firmware name is not null in the response, the device will request the firmware chunk-by-chunk by publishing to
[topic prefix]/[DevEUI]/req/fw
. The backend should then respond within 10 seconds by publishing the requested chunk to[topic prefix]/[DevEUI]/down/fw
. - If the configuration ETag is not null in the response, the device will request the changed configuration by publishing to
[topic prefix]/[DevEUI]/req/config
. The backend should then respond within 5 seconds by publishing the configuration to[topic prefix]/[DevEUI]/down/config
.
Configuration ETags
To identify configuration changes, the backend needs to assign a random value each time the configuration changes, called ETag.
Synchronization Messages
All device requests have the following payload message structure:
i
(string): The device EUI.n
(uint64): The uplink frame counter.q
(string): The query type, as written in the topic. Example:sync
.d
: The request data. Structure depends on the query type.
All backend responses have the following payload message structure:
n
(uint64): The downlink frame number.r
(uint64): Value of then
field from request the downlink is responding to.d
: The response data. Structure depends on the request type.
↑ Synchronization Request
Topic: [topic prefix]/[DevEUI]/req/sync
The device publishes its current synchronization state to this topic.
Expected response: Synchronization Response.
The message is published:
- After reset.
- During Daily Status.
Message data contents:
app
(string): Name of the installed application firmware.boot
(string): Name of the installed secure firmware.etag
(string): ETag of the installed configuration, as assigned by the backend.
Payload example
{
"i": "70b3d5e050010233",
"n": 123,
"q": "sync",
"d": {
"app": "app-nrf91-origin v0.1.1 TZ3 (Aug 16 2024 16:25:20)",
"boot": "app-nrf91-secure v0.1.8 TZ3 (Aug 12 2024 17:58:42)",
"etag": "92da513367c4d781598c85586bb2997954ced4e1"
}
}
↓ Synchronization Response
Topic: [topic prefix]/[DevEUI]/down/sync
The backend publishes possibly changed firmware and/or configuration ETag to this topic.
Message data contents:
app
(string|null): Name of the to-be-installed application firmware, ornull
.boot
(string|null): Name of the to-be-installed secure firmware, ornull
.etag
(string|null): ETag of the to-be-installed configuration, ornull
.
Payload example
{
"n": 7890,
"r": 123,
"d": {
"app": null,
"boot": null,
"etag": "12345678901234567890"
}
}
↑ Config Request
Topic: [topic prefix]/[DevEUI]/req/config
The device publishes to this topic to request a configuration update.
Expected response: Config Response.
Message data contents:
etag
(string): ETag of the requested configuration, as assigned by the backend.
Payload example
{
"i": "70b3d5e050010233",
"n": 124,
"q": "config",
"d": {
"etag": "12345678901234567890"
}
}
↓ Config Response
Topic: [topic prefix]/[DevEUI]/down/config
The backend publishes the configuration to this topic, as response to the Config Request.
Only the provided config parameters are changed on the device, all other parameters keep unchanged.
Message data contents:
etag
(string): ETag of the new configuration.config
(object): The new configuration.
Payload example
{
"n": 7891,
"r": 124,
"d": {
"etag": "12345678901234567890",
"config": {
"listenCron": "H H 10 * * *",
"cmodeDursec": 21,
"smodeDurSec": 0
}
}
}
↑ Firmware Chunk Request
Topic: [topic prefix]/[DevEUI]/req/fw
The device publishes to this topic to request a firmware chunk.
Expected response: Firmware Chunk Response.
Message data contents:
f
(string): Name of the firmware that the device is downloading.c
(uint64): Chunk number.
Payload example
{
"i": "70b3d5e050010233",
"n": 125,
"q": "fw",
"d": {
"f": "app-nrf91-origin+0.3.8+hw4.hex",
"c": 0
}
}
↓ Firmware Chunk Response
Topic: [topic prefix]/[DevEUI]/down/fw
The backend publishes a firmware chunk to this topic, as response to the Firmware Chunk Request.
Each chunk should be at maximum 512 bytes long.
Message data contents:
c
(uint64): Chunk ID.t
(uint64): Total number of chunks.a
(uint64): Memory address to write the chunk to.d
(string): Hex encoded chunk.
Payload example
{
"n": 7892,
"r": 125,
"d": {
"c": 0,
"t": 553,
"a": 364032,
"d": "d3e9002326f090f80022002326f0d2fc0028eed0002c36db3443e9d000261f4ce7e7332d06ddb5f5806f25d041ec100bbde8f081a3f213434ff0ff37df403842f4d013a3d3e9002326f06ef80022002326f0b0fc0028ccd0002c334609dd142d06d0c5f134050122aa4013449e4200d9013423ea0706bce702460b4626f054f841ec100bd4e700264ff00044b1e700bf9c7500883ce4377effff0f000000f03f70b555ec104bc5f30a522b46064672bb25f00043234329d03b4b20462946002226f0e8f9394b04460d469e4252dbc1f30a520b46363a4cf250318e4223dc164440f2fe7296421edc002e34dc16f1350f38db6ff31e5336360022204643ea06552b4b294626f0c6f941ec100b70bd40f2ff718a42dfd122462046294626f004f841ec100b70bd002d17a1d1e9000107db15a3d3e9002326f0adf941ec100b70bd13a1d1e9000110a3d3e9002326f0a2f941ec100bf3e76ff31e5343ea065545ec104b70bd002d0ca1d1e9000102da0ca1d1e9000108a3d3e9002326f08bf941ec100b70bdaff300809c7500883ce4377e9c7500883ce437fe59f3f8c21f6ea50159f3f8c21f6ea58100005043b03cffff0000903c000000002de9f04fc76999b08346229e09910e92139355ec104b8ded040b7fb9102027f075fd0246cbf81c0020b9a74bef21a74827f03efec0e901770760c760dbf81c30196859b15a680123"
}
}
Example communication flow of a configuration update
The device sends its current configuration ETag in a [topic prefix/[DevEUI]/req/sync
uplink.
To trigger a configuration update, respond with a different ETag. The device will then request the new configuration via [topic prefix/[DevEUI]/req/config
, to which you must respond with the complete new configuration.
-
Device publishes sync request to
LOB/70b3d5e050010233/req/sync
:{
"i": "70b3d5e050010233",
"n": 123,
"q": "sync",
"d": {
"app": "app-nrf91-origin v0.1.1 TZ3 (Aug 16 2024 16:25:20)",
"boot": "app-nrf91-secure v0.1.8 TZ3 (Aug 12 2024 17:58:42)",
"etag": "92da513367c4d781598c85586bb2997954ced4e1"
}
} -
Backend responds with a changed ETag by publishing to
LOB/70b3d5e050010233/down/sync
within 5 seconds:{
"n": 7890,
"r": 123,
"d": {
"app": null,
"boot": null,
"etag": "12345678901234567890"
}
} -
Device requests new configuration by publishing the desired ETag to
LOB/70b3d5e050010233/req/config
:{
"i": "70b3d5e050010233",
"n": 124,
"q": "config",
"d": {
"etag": "12345678901234567890"
}
} -
Backend responds with the new configuration by publishing to
LOB/70b3d5e050010233/down/config
within 5 seconds:{
"n": 7891,
"r": 124,
"d": {
"etag": "12345678901234567890",
"config": {
"listenCron": "H H 10 * * *",
"cmodeDursec": 21,
"smodeDurSec": 0
}
}
}
Example communication flow of a firmware update
-
Device publishes sync request to
LOB/70b3d5e050010233/req/sync
:{
"i": "70b3d5e050010233",
"n": 123,
"q": "sync",
"d": {
"app": "app-nrf91-origin v0.1.1 TZ3 (Aug 16 2024 16:25:20)",
"boot": "app-nrf91-secure v0.1.8 TZ3 (Aug 12 2024 17:58:42)",
"etag": "92da513367c4d781598c85586bb2997954ced4e1"
}
} -
Backend initiates firmware update by publishing to
LOB/70b3d5e050010233/down/sync
within 5 seconds:{
"n": 7890,
"r": 123,
"d": {
"app": "app-nrf91-origin+0.3.8+hw4.hex",
"boot": null,
"etag": null
}
} -
Device starts requesting firmware chunks by publishing to
LOB/70b3d5e050010233/req/fw
:{
"i": "70b3d5e050010233",
"n": 124,
"q": "fw",
"d": {
"f": "app-nrf91-origin+0.3.8+hw4.hex",
"c": 0
}
} -
Backend responds to each chunk request with firmware chunk by publishing to
LOB/70b3d5e050010233/down/fw
within 10 seconds:{
"n": 7891,
"r": 124,
"d": {
"c": 0,
"t": 553,
"a": 364032,
"d": "d3e9002326f090f80022002326f0d2fc0028eed0002c36db3443e9d000261f4ce7e7332d06ddb5f5806f25d041ec100bbde8f081a3f213434ff0ff37df403842f4d013a3d3e9002326f06ef80022002326f0b0fc0028ccd0002c334609dd142d06d0c5f134050122aa4013449e4200d9013423ea0706bce702460b4626f054f841ec100bd4e700264ff00044b1e700bf9c7500883ce4377effff0f000000f03f70b555ec104bc5f30a522b46064672bb25f00043234329d03b4b20462946002226f0e8f9394b04460d469e4252dbc1f30a520b46363a4cf250318e4223dc164440f2fe7296421edc002e34dc16f1350f38db6ff31e5336360022204643ea06552b4b294626f0c6f941ec100b70bd40f2ff718a42dfd122462046294626f004f841ec100b70bd002d17a1d1e9000107db15a3d3e9002326f0adf941ec100b70bd13a1d1e9000110a3d3e9002326f0a2f941ec100bf3e76ff31e5343ea065545ec104b70bd002d0ca1d1e9000102da0ca1d1e9000108a3d3e9002326f08bf941ec100b70bdaff300809c7500883ce4377e9c7500883ce437fe59f3f8c21f6ea50159f3f8c21f6ea58100005043b03cffff0000903c000000002de9f04fc76999b08346229e09910e92139355ec104b8ded040b7fb9102027f075fd0246cbf81c0020b9a74bef21a74827f03efec0e901770760c760dbf81c30196859b15a680123"
}
}