Skip to content

Commit

Permalink
[WIP]host/eatt: Collision mitigation
Browse files Browse the repository at this point in the history
Handle collision mitigation
  • Loading branch information
szymon-czapracki committed Feb 27, 2025
1 parent 5506aeb commit 27abcd0
Showing 1 changed file with 76 additions and 2 deletions.
78 changes: 76 additions & 2 deletions nimble/host/src/ble_eatt.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ struct ble_eatt {
uint16_t conn_handle;
struct ble_l2cap_chan *chan;
uint8_t client_op;
uint8_t retry_cnt;
bool collision;

/* Packet transmit queue */
STAILQ_HEAD(, os_mbuf_pkthdr) eatt_tx_q;
Expand Down Expand Up @@ -214,6 +216,51 @@ ble_eatt_free(struct ble_eatt *eatt)
os_memblock_put(&ble_eatt_conn_pool, eatt);
}

/* Let master to create ecoc.
* TODO: Slave could setup after some timeout
* TODO: Jak master to od razu jak slave to czekamy 500ms
* TODO: Opoznienie tutaj
* TODO: Jak slave tutaj to rob - chyba ze konflikt to ble eatt start
* TODO: Nie wiecej niz dwa razy - zapisz sobie flage
* TODO: Jak byl konflikt to albo czyscisz alloc albo retry i trzymasz sobie
* Laczysz ustawiasz i jako master od razu, jako slave po timeout
* Jak insufficent to retry ale tylko raz
* Jak status jest insuff to nie eatt free tylko rozdziel start na dwie funkcje
* jedna do alloca druga do restartu
* skorzystaj z ble_eatt do trzymania informacji per conn
*/

static void
ble_eatt_retry(uint16_t conn_handle)
{
struct ble_gap_conn_desc desc;
struct ble_eatt *eatt;
int rc;

rc = ble_gap_conn_find(conn_handle, &desc);
assert(rc == 0);

/* Core Vol 3 Part G 5.4
* L2CAP collision mitigation
* Peripheral shall wait some time before retrying connection
*/
if (desc.role == BLE_GAP_ROLE_SLAVE) {
os_time_delay(500 * OS_TICKS_PER_SEC / 1000);
}

eatt = ble_eatt_alloc();
if (!eatt) {
return;
}

eatt->conn_handle = conn_handle;

eatt->retry_cnt++;

/* Setup EATT */
ble_npl_eventq_put(ble_hs_evq_get(), &eatt->setup_ev);
}

static int
ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg)
{
Expand All @@ -226,7 +273,15 @@ ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg)
case BLE_L2CAP_EVENT_COC_CONNECTED:
BLE_EATT_LOG_DEBUG("eatt: Connected \n");
if (event->connect.status) {
ble_eatt_free(eatt);
if (event->connect.status == BLE_L2CAP_COC_ERR_NO_RESOURCES) {
eatt->collision = true;
if (eatt->retry_cnt < 2) {
ble_eatt_retry(desc.conn_handle);
}
}
if (eatt->retry_cnt > 2) {
ble_eatt_free(eatt);
}
return 0;
}
eatt->chan = event->connect.chan;
Expand All @@ -238,6 +293,11 @@ ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg)
case BLE_L2CAP_EVENT_COC_ACCEPT:
BLE_EATT_LOG_DEBUG("eatt: Accept request\n");
eatt = ble_eatt_find_by_conn_handle(event->accept.conn_handle);

if (eatt->collision) {
ble_eatt_retry(event->accept.conn_handle);
}

if (eatt) {
/* For now we accept only one additional coc channel per ACL
* TODO: improve it
Expand Down Expand Up @@ -509,10 +569,24 @@ ble_eatt_start(uint16_t conn_handle)

rc = ble_gap_conn_find(conn_handle, &desc);
assert(rc == 0);
if (desc.role != BLE_GAP_ROLE_MASTER) {
if (desc.role == BLE_GAP_ROLE_SLAVE) {
if (eatt->retry_cnt <= 2) {
os_time_delay(500 * OS_TICKS_PER_SEC / 1000);
}
/* Let master to create ecoc.
* TODO: Slave could setup after some timeout
* TODO: Jak master to od razu jak slave to czekamy 500ms
* TODO: Opoznienie tutaj
* TODO: Jak slave tutaj to rob - chyba ze konflikt to ble eatt start
* TODO: Nie wiecej niz dwa razy - zapisz sobie flage
* TODO: Jak byl konflikt to albo czyscisz alloc albo retry i trzymasz sobie
* Laczysz ustawiasz i jako master od razu, jako slave po timeout
* Jak insufficent to retry ale tylko raz
* Jak status jest insuff to nie eatt free tylko rozdziel start na dwie funkcje
* jedna do alloca druga do restartu
* skorzystaj z ble_eatt do trzymania informacji per conn
*/
} else if (desc.role == BLE_GAP_ROLE_MASTER) {
return;
}

Expand Down

0 comments on commit 27abcd0

Please sign in to comment.