Skip to content

Commit 151a9ab

Browse files
nimble/eatt: Add option for manual EATT connection
Provide flexibility in managing EATT. Introduce function that manually establishes EATT. Add function that iterates over specific connection EATT and returns the maximum number of channels left for use.
1 parent 1834ecc commit 151a9ab

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

nimble/host/include/host/ble_att.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,18 @@ uint16_t ble_att_preferred_mtu(void);
355355
*/
356356
int ble_att_set_preferred_mtu(uint16_t mtu);
357357

358+
/**
359+
* Manually establish L2CAP Enhanced Connection
360+
*
361+
* @param conn_handle ACL connection handle
362+
* @param chan_num Number of channels to establish
363+
*
364+
* @return 0 on success;
365+
* NimBLE host core return code on unexpected
366+
* error.
367+
*/
368+
int ble_eatt_connect(uint16_t conn_handle, uint8_t chan_num);
369+
358370
#ifdef __cplusplus
359371
}
360372
#endif

nimble/host/src/ble_eatt.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ struct ble_eatt {
3737
uint16_t conn_handle;
3838
struct ble_l2cap_chan *chan;
3939
uint8_t client_op;
40+
uint8_t chan_num;
41+
uint8_t used_channels;
4042

4143
/* Packet transmit queue */
4244
STAILQ_HEAD(, os_mbuf_pkthdr) eatt_tx_q;
@@ -135,6 +137,21 @@ ble_eatt_find(uint16_t conn_handle, uint16_t cid)
135137
return NULL;
136138
}
137139

140+
static size_t
141+
ble_eatt_used_channels(uint16_t conn_handle)
142+
{
143+
struct ble_eatt *eatt;
144+
size_t used_channels = 0;
145+
146+
SLIST_FOREACH(eatt, &g_ble_eatt_list, next) {
147+
if (eatt->conn_handle == conn_handle) {
148+
used_channels += eatt->used_channels;
149+
}
150+
}
151+
152+
return used_channels;
153+
}
154+
138155
static int
139156
ble_eatt_prepare_rx_sdu(struct ble_l2cap_chan *chan)
140157
{
@@ -232,6 +249,7 @@ ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg)
232249
return 0;
233250
}
234251
eatt->chan = event->connect.chan;
252+
eatt->used_channels++;
235253
break;
236254
case BLE_L2CAP_EVENT_COC_DISCONNECTED:
237255
BLE_EATT_LOG_DEBUG("eatt: Disconnected \n");
@@ -506,6 +524,53 @@ ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom)
506524
return rc;
507525
}
508526

527+
int
528+
ble_eatt_connect(uint16_t conn_handle, uint8_t chan_num)
529+
{
530+
struct ble_eatt *eatt;
531+
struct ble_gap_conn_desc desc;
532+
uint8_t free_channels;
533+
int rc;
534+
535+
rc = ble_gap_conn_find(conn_handle, &desc);
536+
assert(rc == 0);
537+
538+
eatt = ble_eatt_find_by_conn_handle(conn_handle);
539+
if (!eatt) {
540+
eatt = ble_eatt_alloc();
541+
if (!eatt) {
542+
BLE_EATT_LOG_ERROR("ble_eatt_connect: Can't allocate EATT\n");
543+
return BLE_HS_ENOMEM;
544+
}
545+
}
546+
547+
/*
548+
return BLE_HS_EALREADY;
549+
* Warn about exceeding the number
550+
* of maximum per-conn EATT connections.
551+
*/
552+
if (chan_num == 0 || chan_num > MYNEWT_VAL(BLE_EATT_CHAN_PER_CONN)) {
553+
BLE_EATT_LOG_WARN("ble_eatt_connect | Invalid channel number\n");
554+
return BLE_HS_EREJECT;
555+
}
556+
557+
/* Get number of free channels for this connection */
558+
free_channels = MYNEWT_VAL(BLE_EATT_CHAN_PER_CONN) - ble_eatt_used_channels(conn_handle);
559+
560+
if (free_channels == 0) {
561+
BLE_EATT_LOG_ERROR("ble_eatt_connect | No free channel slots\n");
562+
return BLE_HS_ENOMEM;
563+
}
564+
565+
eatt->conn_handle = conn_handle;
566+
eatt->chan_num = (free_channels > chan_num) ? chan_num : free_channels;
567+
568+
/* Setup EATT */
569+
ble_npl_eventq_put(ble_hs_evq_get(), &eatt->setup_ev);
570+
571+
return 0;
572+
}
573+
509574
static void
510575
ble_eatt_start(uint16_t conn_handle)
511576
{

0 commit comments

Comments
 (0)