feat(nimble): Added support for EATT Credit Based Flow Control Mode

This commit is contained in:
Sumeet Singh
2024-03-29 12:41:18 +05:30
committed by BLE BOT
parent daf465c038
commit 53a064274f
6 changed files with 186 additions and 4 deletions

View File

@ -737,6 +737,7 @@ if(CONFIG_BT_ENABLED)
"host/nimble/nimble/nimble/host/store/config/src/ble_store_nvs.c" "host/nimble/nimble/nimble/host/store/config/src/ble_store_nvs.c"
"host/nimble/nimble/nimble/host/src/ble_gattc_cache.c" "host/nimble/nimble/nimble/host/src/ble_gattc_cache.c"
"host/nimble/nimble/nimble/host/src/ble_gattc_cache_conn.c" "host/nimble/nimble/nimble/host/src/ble_gattc_cache_conn.c"
"host/nimble/nimble/nimble/host/src/ble_eatt.c"
) )
if(CONFIG_BT_CONTROLLER_DISABLED AND CONFIG_BT_NIMBLE_TRANSPORT_UART) if(CONFIG_BT_CONTROLLER_DISABLED AND CONFIG_BT_NIMBLE_TRANSPORT_UART)

View File

@ -1089,3 +1089,10 @@ menu "Host-controller Transport"
help help
UART HCI CTS pin UART HCI CTS pin
endmenu endmenu
config BT_NIMBLE_EATT_CHAN_NUM
int "Maximum number of EATT channels"
default 0
depends on BT_NIMBLE_ENABLED
help
Defines the number of channels EATT bearers can use

View File

@ -543,6 +543,10 @@
#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) #define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1)
#endif #endif
#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI
#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI (1)
#endif
#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE #ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE
#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) #define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1)
#endif #endif
@ -567,6 +571,10 @@
#define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT (1) #define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT (1)
#endif #endif
#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_MULT_VAR
#define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT_VAR (1)
#endif
#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE #ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE
#define MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE (1) #define MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE (1)
#endif #endif
@ -583,6 +591,49 @@
#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) #define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1)
#endif #endif
#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM
#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (CONFIG_BT_NIMBLE_EATT_CHAN_NUM)
#endif
#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL
#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1)
#endif
#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD
#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27)
#endif
#ifndef MYNEWT_VAL_BLE_EATT_MTU
#define MYNEWT_VAL_BLE_EATT_MTU (128)
#endif
#ifndef MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES
#if MYNEWT_VAL_BLE_GATT_CACHING
#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_ROBUST_CACHING (1)
#else
#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_ROBUST_CACHING (0)
#endif //MYNEWT_VAL_BLE_GATT_CACHING
#if CONFIG_BT_NIMBLE_EATT_CHAN_NUM
#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_EATT (2)
#else
#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_EATT (0)
#endif //CONFIG_BT_NIMBLE_EATT_CHAN_NUM
#if MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI
#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_NOTIFY_MULTI (4)
#else
#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_NOTIFY_MULTI (0)
#endif //MYNEWT_VAL_BLE_ATT_SVR_NOTIFY_MULTI
#define MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES ( \
MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_ROBUST_CACHING | \
MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_EATT | \
MYNEWT_VAL_BLE_CLIENT_SUPPORTED_FEATURES_NOTIFY_MULTI \
)
#endif //MYNEWT_VAL_CLIENT_SUPPORTED_FEATURES
#ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE #ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE
#define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) #define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1)
#endif #endif
@ -623,6 +674,10 @@
#define MYNEWT_VAL_BLE_GATT_NOTIFY (1) #define MYNEWT_VAL_BLE_GATT_NOTIFY (1)
#endif #endif
#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE
#define MYNEWT_VAL_BLE_GATT_NOTIFY_MULTIPLE (1)
#endif
#ifndef MYNEWT_VAL_BLE_GATT_READ #ifndef MYNEWT_VAL_BLE_GATT_READ
#define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) #define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL)
#endif #endif
@ -749,16 +804,26 @@
#define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200) #define MYNEWT_VAL_BLE_HS_SYSINIT_STAGE (200)
#endif #endif
#if CONFIG_BT_NIMBLE_EATT_CHAN_NUM
#define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (CONFIG_BT_NIMBLE_EATT_CHAN_NUM)
#else
#ifndef CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM #ifndef CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM
#define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (2) #define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (2)
#else #else
#define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM #define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM
#endif #endif //CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM
#endif //CONFIG_BT_NIMBLE_EATT_CHAN_NUM
#ifndef MYNEWT_VAL_BLE_L2CAP_COC_MPS #ifndef MYNEWT_VAL_BLE_L2CAP_COC_MPS
#define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8) #define MYNEWT_VAL_BLE_L2CAP_COC_MPS (MYNEWT_VAL_MSYS_1_BLOCK_SIZE-8)
#endif #endif
#if CONFIG_BT_NIMBLE_EATT_CHAN_NUM
#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (1)
#else
#define MYNEWT_VAL_BLE_L2CAP_ENHANCED_COC (0)
#endif
#ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS #ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS
#define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) #define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1)
#endif #endif
@ -772,8 +837,12 @@
#endif #endif
#ifndef MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS #ifndef MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS
#ifdef CONFIG_BT_NIMBLE_EATT_CHAN_NUM
#define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (CONFIG_BT_NIMBLE_EATT_CHAN_NUM)
#else
#define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) #define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1)
#endif #endif
#endif
#ifndef MYNEWT_VAL_BLE_MESH #ifndef MYNEWT_VAL_BLE_MESH
#ifdef CONFIG_BT_NIMBLE_MESH #ifdef CONFIG_BT_NIMBLE_MESH

View File

@ -64,6 +64,11 @@ static const char *tag = "NimBLE_BLE_CENT";
static int blecent_gap_event(struct ble_gap_event *event, void *arg); static int blecent_gap_event(struct ble_gap_event *event, void *arg);
static uint8_t peer_addr[6]; static uint8_t peer_addr[6];
#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0
static uint16_t cids[MYNEWT_VAL(BLE_EATT_CHAN_NUM)];
static uint16_t bearers;
#endif
void ble_store_config_init(void); void ble_store_config_init(void);
/** /**
@ -777,6 +782,14 @@ blecent_gap_event(struct ble_gap_event *event, void *arg)
/* Forget about peer. */ /* Forget about peer. */
peer_delete(event->disconnect.conn.conn_handle); peer_delete(event->disconnect.conn.conn_handle);
#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0
/* Reset EATT config */
bearers = 0;
for (int i = 0; i < MYNEWT_VAL(BLE_EATT_CHAN_NUM); i++) {
cids[i] = 0;
}
#endif
/* Resume scanning. */ /* Resume scanning. */
blecent_scan(); blecent_scan();
return 0; return 0;
@ -793,14 +806,16 @@ blecent_gap_event(struct ble_gap_event *event, void *arg)
rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc); rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
assert(rc == 0); assert(rc == 0);
print_conn_desc(&desc); print_conn_desc(&desc);
#if !MYNEWT_VAL(BLE_EATT_CHAN_NUM)
#if CONFIG_EXAMPLE_ENCRYPTION #if CONFIG_EXAMPLE_ENCRYPTION
/*** Go for service discovery after encryption has been successfully enabled ***/ /*** Go for service discovery after encryption has been successfully enabled ***/
rc = peer_disc_all(event->connect.conn_handle, rc = peer_disc_all(event->enc_change.conn_handle,
blecent_on_disc_complete, NULL); blecent_on_disc_complete, NULL);
if (rc != 0) { if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc); MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc);
return 0; return 0;
} }
#endif
#endif #endif
return 0; return 0;
@ -872,6 +887,52 @@ blecent_gap_event(struct ble_gap_event *event, void *arg)
event->pathloss_threshold.zone_entered); event->pathloss_threshold.zone_entered);
return 0; return 0;
#endif #endif
#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0
case BLE_GAP_EVENT_EATT:
int i;
MODLOG_DFLT(INFO, "EATT %s : conn_handle=%d cid=%d",
event->eatt.status ? "disconnected" : "connected",
event->eatt.conn_handle,
event->eatt.cid);
if (event->eatt.status) {
/* Remove CID from the list of saved CIDs */
for (i = 0; i < bearers; i++) {
if (cids[i] == event->eatt.cid) {
break;
}
}
while (i < (bearers - 1)) {
cids[i] = cids[i + 1];
i += 1;
}
cids[i] = 0;
/* Now Abort */
return 0;
}
cids[bearers] = event->eatt.cid;
bearers += 1;
if (bearers != MYNEWT_VAL(BLE_EATT_CHAN_NUM)) {
/* Wait until all EATT bearers are connected before proceeding */
return 0;
}
/* Set the default bearer to use for further procedures */
rc = ble_att_set_default_bearer_using_cid(event->eatt.conn_handle, cids[0]);
if (rc != 0) {
MODLOG_DFLT(INFO, "Cannot set default EATT bearer, rc = %d\n", rc);
return rc;
}
/* Perform service discovery */
rc = peer_disc_all(event->eatt.conn_handle,
blecent_on_disc_complete, NULL);
if(rc != 0) {
MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc);
return 0;
}
#endif
return 0;
default: default:
return 0; return 0;
} }
@ -892,6 +953,7 @@ blecent_on_sync(void)
rc = ble_hs_util_ensure_addr(0); rc = ble_hs_util_ensure_addr(0);
assert(rc == 0); assert(rc == 0);
#if !CONFIG_EXAMPLE_INIT_DEINIT_LOOP #if !CONFIG_EXAMPLE_INIT_DEINIT_LOOP
/* Begin scanning for a peripheral to connect to. */ /* Begin scanning for a peripheral to connect to. */
blecent_scan(); blecent_scan();
@ -983,4 +1045,11 @@ app_main(void)
stack_init_deinit(); stack_init_deinit();
#endif #endif
#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0
bearers = 0;
for (int i = 0; i < MYNEWT_VAL(BLE_EATT_CHAN_NUM); i++) {
cids[i] = 0;
}
#endif
} }

View File

@ -45,6 +45,11 @@ static uint8_t own_addr_type = BLE_OWN_ADDR_RANDOM;
static uint8_t own_addr_type; static uint8_t own_addr_type;
#endif #endif
#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0
static uint16_t cids[MYNEWT_VAL(BLE_EATT_CHAN_NUM)];
static uint16_t bearers;
#endif
void ble_store_config_init(void); void ble_store_config_init(void);
/** /**
@ -416,13 +421,37 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg)
event->transmit_power.delta); event->transmit_power.delta);
return 0; return 0;
case BLE_GAP_EVENT_PATHLOSS_THRESHOLD: case BLE_GAP_EVENT_PATHLOSS_THRESHOLD:
MODLOG_DFLT(INFO, "Pathloss threshold event : conn_handle=%d current path loss=%d " MODLOG_DFLT(INFO, "Pathloss threshold event : conn_handle=%d current path loss=%d "
"zone_entered =%d", "zone_entered =%d",
event->pathloss_threshold.conn_handle, event->pathloss_threshold.conn_handle,
event->pathloss_threshold.current_path_loss, event->pathloss_threshold.current_path_loss,
event->pathloss_threshold.zone_entered); event->pathloss_threshold.zone_entered);
return 0; return 0;
#endif
#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0
case BLE_GAP_EVENT_EATT:
MODLOG_DFLT(INFO, "EATT %s : conn_handle=%d cid=%d",
event->eatt.status ? "disconnected" : "connected",
event->eatt.conn_handle,
event->eatt.cid);
if (event->eatt.status) {
/* Abort if disconnected */
return 0;
}
cids[bearers] = event->eatt.cid;
bearers += 1;
if (bearers != MYNEWT_VAL(BLE_EATT_CHAN_NUM)) {
/* Wait until all EATT bearers are connected before proceeding */
return 0;
}
/* Set the default bearer to use for further procedures */
rc = ble_att_set_default_bearer_using_cid(event->eatt.conn_handle, cids[0]);
if (rc != 0) {
MODLOG_DFLT(INFO, "Cannot set default EATT bearer, rc = %d\n", rc);
return rc;
}
return 0;
#endif #endif
} }
@ -566,4 +595,11 @@ app_main(void)
if (rc != ESP_OK) { if (rc != ESP_OK) {
ESP_LOGE(tag, "scli_init() failed"); ESP_LOGE(tag, "scli_init() failed");
} }
#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0
bearers = 0;
for (int i = 0; i < MYNEWT_VAL(BLE_EATT_CHAN_NUM); i++) {
cids[i] = 0;
}
#endif
} }