Document fresh CCC preparation and finalize reconnect regression

This commit is contained in:
evgeny committed 2026-10-30 21:43:26 +01:00
1 parent 752a3a7d95
commit 2cd3f966b2
2 files changed
+12 -1

No files matched your search

+10
View File
@@ -99,6 +99,13 @@ HELLO/ACCEPT идут только по DATA, сборка DATA и INVITE нез
frame_id увеличивается modulo 65536 отдельно для каждого направления и канала.
Планировщик чередует фрагменты DATA/INVITE; готовый ACK имеет высший приоритет,
затем HELLO/ACCEPT. До HELLO обязательны подписки DATA/INVITE/ACK с обеих сторон.
При новом подключении Android/WinRT сначала последовательно записывают CCC=0
для всех трёх каналов, затем включают DATA=Notify, INVITE=Indicate, ACK=Notify.
Только завершение всех шести операций разрешает HELLO; уведомления во время
подготовки не передаются протоколу. ACL и значения CCC могут пережить процесс:
повторное включение без сброса не гарантирует создания новых серверных fd.
Android-сервер принимает CCC=0 идемпотентно, завершает прежнюю сессию без
cancelConnection и не создаёт сессию до следующего включения подписок.
Размер значения <= min(ATT_MTU-3,512), минимальный ATT MTU=23.
Полезный DATA-фрагмент:11байт при MTU23,235 при247,503 при517; HELLO/ACCEPT занимают19.
Нулевой offset начинает новый кадр и заменяет незавершённую предыдущую сборку.
@@ -151,6 +158,9 @@ instance может иметь другой random address). Нехватка р
отдельный SOCK_SEQPACKET socketpair для каждого клиента и канала. DATA/ACK fd принимают
notifications: успешная запись завершает локальный send без ожидания ATT ACK.
INVITE fd передаёт indications; байт1 в обратную сторону подтверждает ATT completion.
HUP любого обязательного fd завершает сессию. Новый AcquireNotify занятого
канала заменяет прежнюю сессию, даже если HUP старого fd ещё не обработан.
Подписки других клиентов при этом сохраняются.
EAGAIN сохраняет фрагмент и ждёт writable; синхронных callbacks send нет.
Value/Confirm без адреса клиента для серверной передачи не используются.
Выходящий клиент: DATA/ACK WriteValue(type=command), INVITE WriteValue(type=request),
+2 -1
View File
@@ -245,10 +245,11 @@ int main(void) {
/* Повторный AcquireNotify до HUP старого fd: новая сессия A, действующая сессия B не затронута. */
ble_link_id old_a = links[1], old_b = links[2];
int closed_before = closed_links;
int old_ack = ack_fds[0]; ack_fds[0] = -1; /* poll_all не должен читать EOF закрываемой подписки. */
int new_fd1 = acquire(ADAPTER "/dev_A", 0);
CHECK(closed_links == closed_before + 1 && ready_links == 2);
CHECK(recv(invite1, data, sizeof(data), MSG_DONTWAIT) == 0);
close(ack_fds[0]); ack_fds[0] = -1;
close(old_ack);
close(invite1); close(fd1); fd1 = new_fd1;
invite1 = acquire(ADAPTER "/dev_A", 1);
CHECK(ready_links == 2);