Pass desktop BLE identity to transport before startup

This commit is contained in:
evgeny committed 2026-10-30 17:50:32 +01:00
1 parent df23626c47
commit 4eefe43053
3 files changed
+17 -1

No files matched your search

+11 -1
View File
@@ -53,7 +53,7 @@ struct ble_transport {
struct ble_connection links[BLE_LINKS_MAX];
ble_link_id sequence;
void* timer;
int started, ready, reject_incoming;
int started, ready, reject_incoming, initial_advertisement_pending;
};
static uint16_t read16(const uint8_t* p) { return (uint16_t)((p[0] << 8) | p[1]); }
static void write16(uint8_t* p, uint16_t v) { p[0] = v >> 8; p[1] = v; }
@@ -278,6 +278,7 @@ static void tick(void* arg) {
}
struct ble_transport* ble_create(struct UASYNC* ua, const struct ble_config* config) {
if (!ua || !config || !config->node_id || config->tx_limit > BLE_QUEUE_MAX || config->tx_window > BLE_QUEUE_MAX ||
config->initial_advertisement_size > BLE_BROADCAST_MAX ||
(config->adapter && strlen(config->adapter) >= 64)) {
DEBUG_ERROR(CAT, "BLE create invalid configuration"); return NULL;
}
@@ -292,6 +293,7 @@ struct ble_transport* ble_create(struct UASYNC* ua, const struct ble_config* con
int ble_start(struct ble_transport* t) {
if (!t || t->started) { DEBUG_ERROR(CAT, "BLE invalid/repeated start"); return BLE_ERROR; }
t->started = 1;
t->initial_advertisement_pending = t->config.initial_advertisement_size != 0;
t->backend = ble_backend_create(t, t->ua, &t->config);
if (!t->backend) { t->started = 0; DEBUG_ERROR(CAT, "BLE backend creation failed"); return BLE_ERROR; }
t->timer = uasync_set_timeout(t->ua, 1000, t, tick, "ble_tick");
@@ -380,6 +382,14 @@ ble_link_id ble_backend_incoming(struct ble_transport* t, const struct ble_endpo
struct ble_connection* c = new_link(t, ep, 0, 0); return c ? c->id : 0;
}
void ble_backend_status(struct ble_transport* t, int ready, const char* reason) {
if (ready && t->initial_advertisement_pending) {
t->initial_advertisement_pending = 0;
/* WinRT уже запустил эти байты до GATT и принимает повтор без перезапуска; остальные backend начинают здесь. */
if (ble_backend_advertise(t->backend, t->config.initial_advertisement, t->config.initial_advertisement_size) != BLE_OK) {
DEBUG_ERROR(CAT, "BLE initial advertisement failed bytes=%zu", t->config.initial_advertisement_size);
ready = 0; reason = "initial BLE advertisement failed";
}
}
t->ready = ready;
if (!ready) {
DEBUG_ERROR(CAT, "BLE radio failed: %s", reason);
+2
View File
@@ -51,6 +51,8 @@ struct ble_config {
void* arg; /* Заимствованный контекст callbacks, живёт до destroy. */
unsigned tx_limit; /* Целых TX-пакетов, включая фрагментируемый: 0=64, 1..64. */
unsigned tx_window; /* DATA в очереди/отправке/ожидании удалённого ACK: 0=BLE_TX_WINDOW_FRAMES, 1..64. */
uint8_t initial_advertisement[BLE_BROADCAST_MAX]; /* Начальное объявление; копируется вместе с config. */
size_t initial_advertisement_size; /* 0: выключено; 1..24: Windows запускает publisher до GATT. */
};
/* Создать остановленный transport. ua/config заимствованы только ua; возвращает handle или NULL с логом. */
struct ble_transport* ble_create(struct UASYNC* ua, const struct ble_config* config);
+4
View File
@@ -45,6 +45,10 @@ void DesktopBle::apply(int flags, const char* name) {
}
ble_config config{};
config.node_id = m_nodeId; config.company_id = 0xffff; config.arg = this;
if (flags & 2) {
memcpy(config.initial_advertisement, bytes, size_t(length));
config.initial_advertisement_size = size_t(length);
}
config.callbacks.status = [](void* arg, ble_state state, const char* reason) {
auto* self = static_cast<DesktopBle*>(arg);
self->m_snapshot.state = state; self->m_snapshot.reason = QString::fromUtf8(reason);