mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(ble_mesh): Support Bluetooth Mesh SAR enhancement
This commit is contained in:
parent
f57acc21d6
commit
d9876ffd53
@ -515,7 +515,6 @@ if(CONFIG_BT_ENABLED)
|
||||
"esp_ble_mesh/core/rpl.c"
|
||||
"esp_ble_mesh/core/scan.c"
|
||||
"esp_ble_mesh/core/test.c"
|
||||
"esp_ble_mesh/core/transport.c"
|
||||
"esp_ble_mesh/models/common/device_property.c"
|
||||
"esp_ble_mesh/models/common/model_common.c"
|
||||
"esp_ble_mesh/models/client/client_common.c"
|
||||
@ -552,6 +551,12 @@ if(CONFIG_BT_ENABLED)
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_sar_model.c"
|
||||
"esp_ble_mesh/v1.1/btc/btc_ble_mesh_srpl_model.c"
|
||||
"esp_ble_mesh/v1.1/ext.c")
|
||||
|
||||
if(CONFIG_BLE_MESH_SAR_ENHANCEMENT)
|
||||
list(APPEND srcs "esp_ble_mesh/core/transport.enh.c")
|
||||
else()
|
||||
list(APPEND srcs "esp_ble_mesh/core/transport.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
|
@ -678,6 +678,13 @@ if BLE_MESH
|
||||
When the above situation is encountered, this option can be used to decide whether
|
||||
to perform the IV index recovery procedure.
|
||||
|
||||
config BLE_MESH_SAR_ENHANCEMENT
|
||||
bool "Segmentation and reassembly enhancement"
|
||||
default n
|
||||
help
|
||||
Enable this option to use the enhanced segmentation and reassembly
|
||||
mechanism introduced in Bluetooth Mesh Protocol 1.1.
|
||||
|
||||
config BLE_MESH_TX_SEG_MSG_COUNT
|
||||
int "Maximum number of simultaneous outgoing segmented messages"
|
||||
default 1
|
||||
|
@ -32,8 +32,11 @@
|
||||
/* Pre-5.0 controllers enforce a minimum interval of 100ms
|
||||
* whereas 5.0+ controllers can go down to 20ms.
|
||||
*/
|
||||
#define ADV_INT_DEFAULT_MS 100
|
||||
#define ADV_INT_FAST_MS 20
|
||||
#if CONFIG_BLE_MESH_HCI_5_0
|
||||
#define ADV_ITVL_MIN 20
|
||||
#else
|
||||
#define ADV_ITVL_MIN 100
|
||||
#endif
|
||||
|
||||
static const uint8_t adv_type[] = {
|
||||
[BLE_MESH_ADV_PROV] = BLE_MESH_DATA_MESH_PROV,
|
||||
@ -141,10 +144,19 @@ static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb,
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t bt_mesh_pdu_duration(uint8_t xmit)
|
||||
{
|
||||
uint16_t duration = 0U;
|
||||
uint16_t adv_int = 0U;
|
||||
|
||||
adv_int = MAX(ADV_ITVL_MIN, BLE_MESH_TRANSMIT_INT(xmit));
|
||||
duration = (BLE_MESH_TRANSMIT_COUNT(xmit) + 1) * (adv_int + 10);
|
||||
|
||||
return duration;
|
||||
}
|
||||
|
||||
static inline int adv_send(struct net_buf *buf)
|
||||
{
|
||||
const int32_t adv_int_min = ((bt_mesh_dev.hci_version >= BLE_MESH_HCI_VERSION_5_0) ?
|
||||
ADV_INT_FAST_MS : ADV_INT_DEFAULT_MS);
|
||||
const struct bt_mesh_send_cb *cb = BLE_MESH_ADV(buf)->cb;
|
||||
void *cb_data = BLE_MESH_ADV(buf)->cb_data;
|
||||
struct bt_mesh_adv_param param = {0};
|
||||
@ -158,7 +170,7 @@ static inline int adv_send(struct net_buf *buf)
|
||||
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
|
||||
if (BLE_MESH_ADV(buf)->type != BLE_MESH_ADV_BLE) {
|
||||
#endif
|
||||
adv_int = MAX(adv_int_min,
|
||||
adv_int = MAX(ADV_ITVL_MIN,
|
||||
BLE_MESH_TRANSMIT_INT(BLE_MESH_ADV(buf)->xmit));
|
||||
duration = (BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1) *
|
||||
(adv_int + 10);
|
||||
|
@ -25,6 +25,8 @@ extern "C" {
|
||||
|
||||
#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf))
|
||||
|
||||
uint16_t bt_mesh_pdu_duration(uint8_t xmit);
|
||||
|
||||
typedef struct bt_mesh_msg {
|
||||
bool relay; /* Flag indicates if the packet is a relayed one */
|
||||
void *arg; /* Pointer to the struct net_buf */
|
||||
|
@ -90,7 +90,7 @@ static struct seg_tx {
|
||||
uint8_t tag; /* Additional metadata */
|
||||
const struct bt_mesh_send_cb *cb;
|
||||
void *cb_data;
|
||||
struct k_delayed_work retransmit; /* Retransmit timer */
|
||||
struct k_delayed_work rtx_timer; /* Segment Retransmission timer */
|
||||
} seg_tx[CONFIG_BLE_MESH_TX_SEG_MSG_COUNT];
|
||||
|
||||
static struct seg_rx {
|
||||
@ -106,7 +106,7 @@ static struct seg_rx {
|
||||
uint16_t dst;
|
||||
uint32_t block;
|
||||
uint32_t last;
|
||||
struct k_delayed_work ack;
|
||||
struct k_delayed_work ack_timer;
|
||||
struct net_buf_simple buf;
|
||||
} seg_rx[CONFIG_BLE_MESH_RX_SEG_MSG_COUNT] = {
|
||||
[0 ... (CONFIG_BLE_MESH_RX_SEG_MSG_COUNT - 1)] = {
|
||||
@ -145,7 +145,7 @@ uint8_t bt_mesh_get_seg_rtx_num(void)
|
||||
return SEG_RETRANSMIT_ATTEMPTS;
|
||||
}
|
||||
|
||||
int32_t bt_mesh_get_seg_rtx_timeout(uint8_t ttl)
|
||||
int32_t bt_mesh_get_seg_rtx_timeout(uint16_t dst, uint8_t ttl)
|
||||
{
|
||||
/* This function will be used when a client model sending an
|
||||
* acknowledged message. And if the dst of a message is not
|
||||
@ -322,7 +322,7 @@ static void seg_tx_reset(struct seg_tx *tx)
|
||||
|
||||
bt_mesh_seg_tx_lock();
|
||||
|
||||
k_delayed_work_cancel(&tx->retransmit);
|
||||
k_delayed_work_cancel(&tx->rtx_timer);
|
||||
|
||||
tx->cb = NULL;
|
||||
tx->cb_data = NULL;
|
||||
@ -360,6 +360,8 @@ static inline void seg_tx_complete(struct seg_tx *tx, int err)
|
||||
|
||||
seg_tx_reset(tx);
|
||||
|
||||
/* TODO: notify the completion of sending segmented message */
|
||||
|
||||
if (cb && cb->end) {
|
||||
cb->end(err, cb_data);
|
||||
}
|
||||
@ -377,7 +379,7 @@ static void schedule_retransmit(struct seg_tx *tx)
|
||||
return;
|
||||
}
|
||||
|
||||
k_delayed_work_submit(&tx->retransmit, SEG_RETRANSMIT_TIMEOUT(tx));
|
||||
k_delayed_work_submit(&tx->rtx_timer, SEG_RETRANSMIT_TIMEOUT(tx));
|
||||
}
|
||||
|
||||
static void seg_first_send_start(uint16_t duration, int err, void *user_data)
|
||||
@ -471,7 +473,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx)
|
||||
|
||||
static void seg_retransmit(struct k_work *work)
|
||||
{
|
||||
struct seg_tx *tx = CONTAINER_OF(work, struct seg_tx, retransmit);
|
||||
struct seg_tx *tx = CONTAINER_OF(work, struct seg_tx, rtx_timer);
|
||||
|
||||
seg_tx_send_unacked(tx);
|
||||
}
|
||||
@ -511,10 +513,6 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
||||
}
|
||||
|
||||
tx->dst = net_tx->ctx->addr;
|
||||
/* TODO:
|
||||
* When SAR Transmitter is introduced, the xmit may be
|
||||
* updated with "bt_mesh_get_sar_seg_transmit()".
|
||||
*/
|
||||
if (sdu->len) {
|
||||
tx->seg_n = (sdu->len - 1) / seg_len(!!ctl_op);
|
||||
} else {
|
||||
@ -784,6 +782,12 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr,
|
||||
rx->ctl, rx->ctx.recv_ttl, rx->ctx.addr, rx->ctx.recv_dst,
|
||||
bt_hex(sdu->data, sdu->len));
|
||||
|
||||
/* When the Device Key Candidate is available, and an access message
|
||||
* is decrypted using the Device Key Candidate that was delivered to
|
||||
* the access layer, then the node shall revoke the device key, the
|
||||
* Device Key Candidate shall become the device key, and the Device
|
||||
* Key Candidate shall become unavailable.
|
||||
*/
|
||||
revoke_dev_key(dev_key);
|
||||
|
||||
rx->ctx.app_idx = BLE_MESH_KEY_DEV;
|
||||
@ -942,7 +946,7 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
k_delayed_work_cancel(&tx->retransmit);
|
||||
k_delayed_work_cancel(&tx->rtx_timer);
|
||||
|
||||
while ((bit = find_lsb_set(ack))) {
|
||||
if (tx->seg[bit - 1]) {
|
||||
@ -1216,11 +1220,9 @@ static int send_ack(struct bt_mesh_subnet *sub, uint16_t src, uint16_t dst,
|
||||
|
||||
static void seg_rx_reset(struct seg_rx *rx, bool full_reset)
|
||||
{
|
||||
BT_DBG("rx %p", rx);
|
||||
|
||||
bt_mesh_seg_rx_lock();
|
||||
|
||||
k_delayed_work_cancel(&rx->ack);
|
||||
k_delayed_work_cancel(&rx->ack_timer);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && rx->obo &&
|
||||
rx->block != BLOCK_COMPLETE(rx->seg_n)) {
|
||||
@ -1267,9 +1269,7 @@ static uint32_t incomplete_timeout(struct seg_rx *rx)
|
||||
|
||||
static void seg_ack(struct k_work *work)
|
||||
{
|
||||
struct seg_rx *rx = CONTAINER_OF(work, struct seg_rx, ack);
|
||||
|
||||
BT_DBG("rx %p", rx);
|
||||
struct seg_rx *rx = CONTAINER_OF(work, struct seg_rx, ack_timer);
|
||||
|
||||
bt_mesh_seg_rx_lock();
|
||||
|
||||
@ -1291,14 +1291,14 @@ static void seg_ack(struct k_work *work)
|
||||
send_ack(rx->sub, rx->dst, rx->src, rx->ttl, &rx->seq_auth,
|
||||
rx->block, rx->obo);
|
||||
|
||||
k_delayed_work_submit(&rx->ack, ack_timeout(rx));
|
||||
k_delayed_work_submit(&rx->ack_timer, ack_timeout(rx));
|
||||
|
||||
bt_mesh_seg_rx_unlock();
|
||||
}
|
||||
|
||||
static inline bool sdu_len_is_ok(bool ctl, uint8_t seg_n)
|
||||
{
|
||||
return ((seg_n * seg_len(ctl) + 1) <= CONFIG_BLE_MESH_RX_SDU_MAX);
|
||||
return ((seg_n + 1) * seg_len(ctl) <= CONFIG_BLE_MESH_RX_SDU_MAX);
|
||||
}
|
||||
|
||||
static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx,
|
||||
@ -1568,9 +1568,9 @@ found_rx:
|
||||
/* Reset the Incomplete Timer */
|
||||
rx->last = k_uptime_get_32();
|
||||
|
||||
if (!k_delayed_work_remaining_get(&rx->ack) &&
|
||||
if (!k_delayed_work_remaining_get(&rx->ack_timer) &&
|
||||
!bt_mesh_lpn_established()) {
|
||||
k_delayed_work_submit(&rx->ack, ack_timeout(rx));
|
||||
k_delayed_work_submit(&rx->ack_timer, ack_timeout(rx));
|
||||
}
|
||||
|
||||
/* Location in buffer can be calculated based on seg_o & rx->ctl */
|
||||
@ -1594,7 +1594,7 @@ found_rx:
|
||||
|
||||
*pdu_type = BLE_MESH_FRIEND_PDU_COMPLETE;
|
||||
|
||||
k_delayed_work_cancel(&rx->ack);
|
||||
k_delayed_work_cancel(&rx->ack_timer);
|
||||
|
||||
send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr,
|
||||
net_rx->ctx.send_ttl, seq_auth, rx->block, rx->obo);
|
||||
@ -1754,11 +1754,11 @@ void bt_mesh_trans_init(void)
|
||||
bt_mesh_sar_init();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(seg_tx); i++) {
|
||||
k_delayed_work_init(&seg_tx[i].retransmit, seg_retransmit);
|
||||
k_delayed_work_init(&seg_tx[i].rtx_timer, seg_retransmit);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(seg_rx); i++) {
|
||||
k_delayed_work_init(&seg_rx[i].ack, seg_ack);
|
||||
k_delayed_work_init(&seg_rx[i].ack_timer, seg_ack);
|
||||
seg_rx[i].buf.__buf = (seg_rx_buf_data +
|
||||
(i * CONFIG_BLE_MESH_RX_SDU_MAX));
|
||||
seg_rx[i].buf.data = seg_rx[i].buf.__buf;
|
||||
@ -1778,11 +1778,11 @@ void bt_mesh_trans_deinit(bool erase)
|
||||
bt_mesh_rpl_reset(erase);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(seg_tx); i++) {
|
||||
k_delayed_work_free(&seg_tx[i].retransmit);
|
||||
k_delayed_work_free(&seg_tx[i].rtx_timer);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(seg_rx); i++) {
|
||||
k_delayed_work_free(&seg_rx[i].ack);
|
||||
k_delayed_work_free(&seg_rx[i].ack_timer);
|
||||
}
|
||||
|
||||
bt_mesh_mutex_free(&seg_tx_lock);
|
||||
|
2344
components/bt/esp_ble_mesh/core/transport.enh.c
Normal file
2344
components/bt/esp_ble_mesh/core/transport.enh.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -96,7 +96,7 @@ struct bt_mesh_ctl_friend_sub_confirm {
|
||||
|
||||
uint8_t bt_mesh_get_seg_rtx_num(void);
|
||||
|
||||
int32_t bt_mesh_get_seg_rtx_timeout(uint8_t ttl);
|
||||
int32_t bt_mesh_get_seg_rtx_timeout(uint16_t dst, uint8_t ttl);
|
||||
|
||||
struct bt_mesh_app_key *bt_mesh_app_key_get(uint16_t app_idx);
|
||||
|
||||
|
@ -198,7 +198,7 @@ static int32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx,
|
||||
* All the messages sent from here are access messages.
|
||||
*/
|
||||
seg_rtx_num = bt_mesh_get_seg_rtx_num();
|
||||
seg_rtx_to = bt_mesh_get_seg_rtx_timeout(ctx->send_ttl);
|
||||
seg_rtx_to = bt_mesh_get_seg_rtx_timeout(ctx->addr, ctx->send_ttl);
|
||||
seg_count = (msg->len + mic_size - 1) / 12U + 1U;
|
||||
|
||||
duration = bt_mesh_get_adv_duration(ctx);
|
||||
|
@ -63,7 +63,7 @@ typedef struct {
|
||||
sar_unicast_retrans_interval_step:4; /*!< SAR Unicast Retransmissions Interval Step state */
|
||||
uint8_t sar_unicast_retrans_interval_increment:4, /*!< SAR Unicast Retransmissions Interval Increment state */
|
||||
sar_multicast_retrans_count:4; /*!< SAR Multicast Retransmissions Count state */
|
||||
uint8_t sar_multicast_retrans_interval:4; /*!< SAR Multicast Retransmissions Interval state */
|
||||
uint8_t sar_multicast_retrans_interval_step:4; /*!< SAR Multicast Retransmissions Interval state */
|
||||
} esp_ble_mesh_sar_transmitter_set_t;
|
||||
|
||||
/** Parameters of SAR Receiver Set */
|
||||
@ -91,7 +91,7 @@ typedef struct {
|
||||
sar_unicast_retrans_interval_step:4; /*!< SAR Unicast Retransmissions Interval Step state */
|
||||
uint8_t sar_unicast_retrans_interval_increment:4, /*!< SAR Unicast Retransmissions Interval Increment state */
|
||||
sar_multicast_retrans_count:4; /*!< SAR Multicast Retransmissions Count state */
|
||||
uint8_t sar_multicast_retrans_interval:4; /*!< SAR Multicast Retransmissions Interval state */
|
||||
uint8_t sar_multicast_retrans_interval_step:4; /*!< SAR Multicast Retransmissions Interval state */
|
||||
} esp_ble_mesh_sar_transmitter_status_t;
|
||||
|
||||
/** Parameters of SAR Receiver Status */
|
||||
|
@ -248,6 +248,30 @@ uint8_t bt_mesh_net_retrans_match(void *rx, uint8_t *cred, uint8_t *tag);
|
||||
|
||||
bool bt_mesh_dev_key_ca_valid(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_sis(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_urc(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_urwpc(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_uris(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_urii(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_mrc(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_mris(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_st(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_adi(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_arc(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_dt(void);
|
||||
|
||||
uint8_t bt_mesh_get_sar_rsis(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user