Send BlueZ flow acknowledgements without ATT responses
This commit is contained in:
1 parent
e0076d5d10
commit
d0df49446c
3 files changed
+13
-12
No files matched your search
@@ -1,6 +1,6 @@
|
||||
/* Внутренний платформенный контракт. Все вызовы/события в uasync, send/close не вызывают события синхронно.
|
||||
* ACCEPTED send копирует значение и даёт ровно один sent, либо closed отменяет все операции соединения.
|
||||
* DATA sent означает локальное завершение; INVITE/ACK используют Request/Indication.
|
||||
* DATA/ACK sent означает локальное завершение Without Response/Notify; только INVITE использует Request/Indication.
|
||||
* close/destroy отменяют callbacks; transport создаёт идентификаторы, backend не хранит указатели core-link.
|
||||
* Реализации не создают неограниченных очередей: максимум одна операция send на link. */
|
||||
#ifndef VIBECHAT_BLE_BACKEND_H
|
||||
|
||||
+7
-6
@@ -146,7 +146,7 @@ static void notify_read(int fd, void* arg) {
|
||||
link_error(l, "notification socket read failed"); return;
|
||||
}
|
||||
if (!n) { link_error(l, "notification subscription closed"); return; }
|
||||
if (n != 1 || data[0] != 1 || l->channel == BLE_WIRE_DATA || fd != l->fd[l->channel] ||
|
||||
if (n != 1 || data[0] != 1 || l->channel != BLE_WIRE_INVITE || fd != l->fd[l->channel] ||
|
||||
!l->sending || l->buffered) {
|
||||
DEBUG_WARN(CAT, "BLE indication completion invalid fd=%d expected_fd=%d bytes=%zd sending=%d buffered=%d",
|
||||
fd, l->fd[l->channel], n, l->sending, l->buffered);
|
||||
@@ -166,7 +166,7 @@ static void notify_write(int fd, void* arg) {
|
||||
link_error(l, "notification socket write failed"); return;
|
||||
}
|
||||
l->buffered = 0; uasync_set_socket_write(l->backend->ua, l->io[l->channel], 0);
|
||||
if (l->channel == BLE_WIRE_DATA) {
|
||||
if (l->channel != BLE_WIRE_INVITE) {
|
||||
l->sending = 0;
|
||||
ble_backend_sent(l->backend->owner, l->id, 1);
|
||||
}
|
||||
@@ -232,7 +232,7 @@ static int acquire_notify(sd_bus_message* m, void* arg, sd_bus_error* error) {
|
||||
link_error(l, "AcquireNotify reply failed"); return r;
|
||||
}
|
||||
DEBUG_DEBUG(CAT, "BLE BlueZ subscription link=%llu channel=%d mode=%s mtu=%u",
|
||||
(unsigned long long)l->id, channel, channel == BLE_WIRE_DATA ? "notification" : "indication", mtu);
|
||||
(unsigned long long)l->id, channel, channel == BLE_WIRE_INVITE ? "indication" : "notification", mtu);
|
||||
if (l->fd[0] >= 0 && l->fd[1] >= 0 && l->fd[2] >= 0 && !l->opened) {
|
||||
l->opened = 1; ble_backend_opened(b->owner, l->id, mtu);
|
||||
}
|
||||
@@ -249,7 +249,8 @@ static int get_char(sd_bus* bus, const char* path, const char* interface, const
|
||||
if (!strcmp(property, "UUID")) return sd_bus_message_append(reply, "s",
|
||||
ctx->tx == 3 ? BLE_ACK_UUID : ctx->tx == 2 ? BLE_INVITE_UUID : ctx->tx ? BLE_TX_UUID : BLE_RX_UUID);
|
||||
if (!strcmp(property, "Service")) return sd_bus_message_append(reply, "o", SERVICE);
|
||||
if (!strcmp(property, "Flags") && ctx->tx >= 2) return sd_bus_message_append(reply, "as", 2, "write", "indicate");
|
||||
if (!strcmp(property, "Flags") && ctx->tx == 2) return sd_bus_message_append(reply, "as", 2, "write", "indicate");
|
||||
if (!strcmp(property, "Flags") && ctx->tx == 3) return sd_bus_message_append(reply, "as", 2, "write-without-response", "notify");
|
||||
if (!strcmp(property, "Flags")) return sd_bus_message_append(reply, "as", 1, ctx->tx ? "notify" : "write-without-response");
|
||||
return sd_bus_message_append(reply, "b", 0); /* NotifyAcquired объявляет поддержку адресного fd API. */
|
||||
}
|
||||
@@ -635,11 +636,11 @@ int ble_backend_send(struct ble_backend* b, ble_link_id id, enum ble_wire_channe
|
||||
const char* path = channel == BLE_WIRE_ACK ? l->ack : channel == BLE_WIRE_INVITE ? l->invite : l->rx;
|
||||
int r = sd_bus_message_new_method_call(b->bus, &m, "org.bluez", path, CHAR_IF, "WriteValue");
|
||||
if (r >= 0) r = sd_bus_message_append_array(m, 'y', data, len);
|
||||
if (r >= 0) r = sd_bus_message_append(m, "a{sv}", 1, "type", "s", channel == BLE_WIRE_DATA ? "command" : "request");
|
||||
if (r >= 0) r = sd_bus_message_append(m, "a{sv}", 1, "type", "s", channel == BLE_WIRE_INVITE ? "request" : "command");
|
||||
if (r >= 0) r = sd_bus_call_async(b->bus, &l->write, m, written, l, 10000000);
|
||||
sd_bus_message_unref(m);
|
||||
if (r < 0) { DEBUG_ERROR(CAT, "BLE WriteValue request: %s", strerror(-r)); return BLE_ERROR; }
|
||||
DEBUG_TRACE(CAT, "BLE WriteValue submitted link=%llu channel=%d type=%s bytes=%zu", (unsigned long long)id, channel,
|
||||
channel == BLE_WIRE_DATA ? "command" : "request", len);
|
||||
channel == BLE_WIRE_INVITE ? "request" : "command", len);
|
||||
l->sending = 1; bus_update(b); return BLE_OK;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Private D-Bus + настоящий backend: DATA без ATT ACK, адресные INVITE/ACK indications, два клиента. */
|
||||
/* Private D-Bus + настоящий backend: DATA/ACK без ATT ACK, адресные INVITE indications, два клиента. */
|
||||
#include "ble_backend.h"
|
||||
#include "u_async.h"
|
||||
#include "mem.h"
|
||||
@@ -31,7 +31,7 @@ static void poll_all(void) {
|
||||
for (int j = 0; j < 2; j++) if (ack_fds[j] >= 0) {
|
||||
uint8_t ack[8]; ssize_t n = recv(ack_fds[j], ack, sizeof(ack), MSG_DONTWAIT);
|
||||
if (n < 0) { CHECK(errno == EAGAIN); continue; }
|
||||
CHECK(n == 2); ack_values++; CHECK(send(ack_fds[j], "\1", 1, MSG_NOSIGNAL) == 1);
|
||||
CHECK(n == 2); ack_values++; /* ACK notification не требует ATT confirmation. */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ static int remote_write(sd_bus_message* m, void* arg, sd_bus_error* e) {
|
||||
CHECK(sd_bus_message_read(m, "s", &type) > 0);
|
||||
int invitation = strstr(sd_bus_message_get_path(m), "/invite") != NULL;
|
||||
int ack = strstr(sd_bus_message_get_path(m), "/ack") != NULL;
|
||||
CHECK(!strcmp(type, invitation || ack ? "request" : "command"));
|
||||
CHECK(!strcmp(type, invitation ? "request" : "command"));
|
||||
if (ack) { CHECK(len == 2); ack_requests++; } else if (invitation) requests++; else commands++;
|
||||
int r = sd_bus_reply_method_return(m, "");
|
||||
if (!invitation && !ack && len == 19 && ((const uint8_t*)data)[2] == 1) {
|
||||
@@ -235,11 +235,11 @@ int main(void) {
|
||||
poll_all(); CHECK(ready_links == 3 && commands == 1);
|
||||
CHECK(!ble_tx_put(transport, links[3], frame(0xe5)));
|
||||
CHECK(!ble_channel_tx_put(transport, links[3], BLE_CHANNEL_INVITE, frame(0xe6)));
|
||||
poll_all(); CHECK(commands == 2 && requests == 1 && ack_requests >= 1); /* MTU517 и ACK Write Request. */
|
||||
poll_all(); CHECK(commands == 2 && requests == 1 && ack_requests >= 1); /* MTU517 и ACK Write Command. */
|
||||
ble_destroy(transport); uasync_destroy(ua, 0);
|
||||
for (int i = 0; i < 5; i++) sd_bus_slot_unref(remote[i]);
|
||||
sd_bus_slot_unref(manager); sd_bus_slot_unref(adapter); sd_bus_slot_unref(gatt); sd_bus_slot_unref(adv); sd_bus_close_unref(bus);
|
||||
CHECK(u_get_allocated_count() == before);
|
||||
puts("BlueZ private-bus tests PASS (DATA commands, addressed INVITE/ACK indications, mandatory ACK, two clients, teardown)");
|
||||
puts("BlueZ private-bus tests PASS (DATA/ACK commands and notifications, INVITE indications, two clients, teardown)");
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user