Skip to content

Commit 5d6f27b

Browse files
committed
skald_bthome_saul: add message fragmentation
1 parent 7d0d41a commit 5d6f27b

File tree

3 files changed

+51
-12
lines changed

3 files changed

+51
-12
lines changed

sys/include/net/skald/bthome.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,24 @@ struct skald_bthome_ctx {
167167
*/
168168
uint8_t encrypt;
169169
#endif
170+
#if IS_USED(MODULE_SKALD_BTHOME_SAUL) || defined(DOXYGEN)
171+
/**
172+
* @brief The index of the last device sent in skald_bthome_ctx_t::devs.
173+
*
174+
* Will be updated on each periodic advertisement to allow for fragmenting
175+
* different measurement readings across multiple advertisements (in case all
176+
* measurements from skald_bthome_ctx_t::devs are too large for one
177+
* advertisement). Is initialized to 0.
178+
*
179+
* If a single reading is too big to fit into an advertisement,
180+
* the skald_ctx_t::update_pkt() callback will just return (i.e. BTHome
181+
* payload may be left empty) and skald_bthome_ctx_t::last_dev_sent will
182+
* be reset to 0.
183+
* This can e.g. happen with a @ref BTHOME_ID_TEXT or @ref BTHOME_ID_RAW record
184+
* if the appended bytes are larger than a BLE advertisement.
185+
*/
186+
uint8_t last_dev_sent;
187+
#endif
170188
};
171189

172190
/**

sys/net/ble/skald/skald_bthome.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,11 @@ int skald_bthome_add_measurement(
160160
uint16_t exp_size = ctx->skald.pkt.len + sizeof(obj_id) + data_len + data_contains_length;
161161
uint8_t offset = ctx->skald.pkt.len;
162162

163+
#ifdef MODULE_SKALD_BTHOME_ENCRYPT
164+
exp_size += 8;
165+
#endif
166+
163167
if (exp_size >= NETDEV_BLE_PDU_MAXLEN) {
164-
assert(exp_size < NETDEV_BLE_PDU_MAXLEN);
165168
return -EMSGSIZE;
166169
}
167170
ctx->skald.pkt.pdu[offset++] = (uint8_t)obj_id;

sys/net/ble/skald/skald_bthome_saul.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -423,32 +423,50 @@ static void _reset_hdr(skald_bthome_ctx_t *ctx)
423423
static void _update_saul_measurements(skald_ctx_t *skald_ctx)
424424
{
425425
skald_bthome_ctx_t *ctx = container_of(skald_ctx, skald_bthome_ctx_t, skald);
426+
uint8_t dev_idx = 0;
427+
uint8_t orig_last_dev_sent = ctx->last_dev_sent;
426428

427429
_reset_hdr(ctx);
428430
skald_bthome_saul_t *ptr = ctx->devs;
429431
while (ptr) {
430-
int dim = 1;
431-
phydat_t data = { 0 };
432-
433-
if (ptr->saul.driver) {
434-
dim = saul_reg_read(&ptr->saul, &data);
435-
if (dim <= 0) {
436-
continue;
432+
if ((ctx->last_dev_sent == 0) ||
433+
(dev_idx > ctx->last_dev_sent)) {
434+
int dim = 1;
435+
int res = 0;
436+
phydat_t data = { 0 };
437+
438+
if (ptr->saul.driver) {
439+
dim = saul_reg_read(&ptr->saul, &data);
440+
if (dim <= 0) {
441+
continue;
442+
}
437443
}
438-
}
439-
for (uint8_t i = 0; i < dim; i++) {
440-
if (ptr->add_measurement(ctx, ptr->obj_id, &data, i) < 0) {
444+
for (uint8_t i = 0; i < dim; i++) {
445+
if ((res = ptr->add_measurement(ctx, ptr->obj_id, &data, i)) < 0) {
446+
break;
447+
}
448+
}
449+
if ((res == -EMSGSIZE) && (dev_idx > 0)) {
450+
ctx->last_dev_sent = dev_idx - 1;
451+
}
452+
if (res < 0) {
441453
break;
442454
}
443455
}
444-
445456
ptr = container_of(
446457
ptr->saul.next, skald_bthome_saul_t, saul
447458
);
459+
dev_idx++;
448460
}
449461
#if IS_USED(MODULE_SKALD_BTHOME_ENCRYPT)
450462
skald_bthome_encrypt(ctx);
451463
#endif
464+
if ((ptr == NULL) ||
465+
/* or value just too big */
466+
(orig_last_dev_sent == ctx->last_dev_sent)) {
467+
/* reset device train */
468+
ctx->last_dev_sent = 0;
469+
}
452470
}
453471

454472
int skald_bthome_saul_add(skald_bthome_ctx_t *ctx, skald_bthome_saul_t *saul)

0 commit comments

Comments
 (0)