mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-03 20:35:33 +02:00
Merge branch 'feat/ble_mesh_long_package_support' into 'master'
feat(ble_mesh): long packet mode support Closes BLERP-2273 See merge request espressif/esp-idf!39175
This commit is contained in:
@@ -41,6 +41,86 @@ if BLE_MESH
|
||||
help
|
||||
This option to enable BLE Mesh using some BLE 5.0 APIs.
|
||||
|
||||
menuconfig BLE_MESH_EXT_ADV
|
||||
bool "Enable extended advertising for BLE Mesh"
|
||||
depends on BLE_MESH_USE_BLE_50
|
||||
default n
|
||||
help
|
||||
Enable broadcasting of BLE Mesh messages using BLE 5.0 extended advertising.
|
||||
This allows control of extended advertising parameters (e.g., PHY selection)
|
||||
while maintaining standard BLE Mesh packet length.
|
||||
|
||||
config BLE_MESH_EXT_ADV_BUF_COUNT
|
||||
int "Number of extended advertising buffers"
|
||||
depends on BLE_MESH_EXT_ADV
|
||||
range 6 256
|
||||
default 60
|
||||
help
|
||||
Number of buffer slots allocated for extended advertising packets.
|
||||
|
||||
config BLE_MESH_EXT_RELAY_ADV_BUF_COUNT
|
||||
int "Number of extended relay advertising buffers"
|
||||
depends on BLE_MESH_EXT_ADV
|
||||
depends on BLE_MESH_RELAY
|
||||
range 0 256
|
||||
default 60
|
||||
help
|
||||
Number of buffer slots allocated for extended advertising packets used in message relay.
|
||||
|
||||
menuconfig BLE_MESH_LONG_PACKET
|
||||
bool "Enable non-standard long packet mode for BLE Mesh"
|
||||
depends on BLE_MESH_EXT_ADV
|
||||
default n
|
||||
help
|
||||
Enable extended-length advertising packets for BLE Mesh using BLE 5.0 extended advertising.
|
||||
This overrides the standard BLE Mesh packet length limitations.
|
||||
|
||||
config BLE_MESH_LONG_PACKET_ADV_LEN
|
||||
int "Maximum advertising payload length"
|
||||
depends on BLE_MESH_LONG_PACKET
|
||||
range 30 249
|
||||
default 105
|
||||
help
|
||||
Maximum payload length for extended advertising packets (bytes).
|
||||
Range: 30-249 bytes.
|
||||
Default: 105.
|
||||
Note: Maximum access payload = (LENGTH - 17) × SEGMENT_COUNT
|
||||
- Transmission: Uses BLE_MESH_LONG_PACKET_TX_SEG_CNT
|
||||
- Reception: Uses BLE_MESH_LONG_PACKET_RX_SEG_CNT
|
||||
|
||||
config BLE_MESH_LONG_PACKET_ADV_BUF_COUNT
|
||||
int "Long packet advertising buffer count"
|
||||
depends on BLE_MESH_LONG_PACKET
|
||||
default 20
|
||||
help
|
||||
Number of advertising buffers allocated for long packet transmissions.
|
||||
|
||||
config BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT
|
||||
int "Long packet relay buffer count"
|
||||
depends on BLE_MESH_LONG_PACKET
|
||||
depends on BLE_MESH_RELAY
|
||||
default 20
|
||||
help
|
||||
Number of advertising buffers allocated for relay long packets.
|
||||
|
||||
config BLE_MESH_LONG_PACKET_TX_SEG_CNT
|
||||
int "Maximum transmission segments per message"
|
||||
depends on BLE_MESH_LONG_PACKET
|
||||
range 1 BLE_MESH_TX_SEG_MAX if BLE_MESH_TX_SEG_MAX < BLE_MESH_LONG_PACKET_ADV_BUF_COUNT
|
||||
range 1 BLE_MESH_LONG_PACKET_ADV_BUF_COUNT if BLE_MESH_TX_SEG_MAX >= BLE_MESH_LONG_PACKET_ADV_BUF_COUNT
|
||||
default 20
|
||||
help
|
||||
Maximum number of segments for outgoing long packet messages.
|
||||
Upper bound: min(BLE_MESH_TX_SEG_MAX, BLE_MESH_LONG_PACKET_ADV_BUF_COUNT)
|
||||
|
||||
config BLE_MESH_LONG_PACKET_RX_SEG_CNT
|
||||
int "Maximum reception segments per message"
|
||||
depends on BLE_MESH_LONG_PACKET
|
||||
range 1 BLE_MESH_LONG_PACKET_ADV_BUF_COUNT
|
||||
default 20
|
||||
help
|
||||
Maximum number of segments supported for receiving long packet messages.
|
||||
|
||||
config BLE_MESH_ADV_INST_ID
|
||||
depends on BLE_MESH_USE_BLE_50
|
||||
int "Extended adv instance for Mesh normal packets"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -30,8 +30,55 @@ static esp_err_t ble_mesh_model_send_msg(esp_ble_mesh_model_t *model,
|
||||
|
||||
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
|
||||
|
||||
if (ctx && ctx->addr == ESP_BLE_MESH_ADDR_UNASSIGNED) {
|
||||
BT_ERR("Invalid destination address 0x0000");
|
||||
if (ctx) {
|
||||
if (ctx->addr == ESP_BLE_MESH_ADDR_UNASSIGNED) {
|
||||
BT_ERR("Invalid destination address 0x0000");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (ctx->enh.adv_cfg_used &&
|
||||
ctx->enh.adv_cfg.channel_map & BIT(3)) {
|
||||
BT_ERR("Invalid channel map 0x%04x: bit 3 is reserved", ctx->enh.adv_cfg.channel_map);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (ctx->enh.ext_adv_cfg_used) {
|
||||
if (ctx->enh.ext_adv_cfg.primary_phy == ESP_BLE_MESH_ADV_PHY_CODED) {
|
||||
BT_ERR("Primary phy can't be set to coded phy");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (ctx->enh.ext_adv_cfg.primary_phy == ESP_BLE_MESH_ADV_PHY_UNASSIGNED) {
|
||||
ctx->enh.ext_adv_cfg.primary_phy = ESP_BLE_MESH_ADV_PHY_DEFAULT;
|
||||
}
|
||||
|
||||
if (ctx->enh.ext_adv_cfg.secondary_phy == ESP_BLE_MESH_ADV_PHY_UNASSIGNED) {
|
||||
ctx->enh.ext_adv_cfg.secondary_phy = ESP_BLE_MESH_ADV_PHY_DEFAULT;
|
||||
}
|
||||
}
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (ctx->enh.long_pkt_cfg_used &&
|
||||
(ctx->enh.long_pkt_cfg != ESP_BLE_MESH_LONG_PACKET_FORCE &&
|
||||
ctx->enh.long_pkt_cfg != ESP_BLE_MESH_LONG_PACKET_PREFER)) {
|
||||
BT_ERR("Invalid long packet configuration %d (expected FORCE=1 or PREFER=2)",
|
||||
ctx->enh.long_pkt_cfg);
|
||||
}
|
||||
|
||||
if (ctx->enh.long_pkt_cfg_used && (op_len + length + mic_len > ESP_BLE_MESH_EXT_SDU_MAX_LEN)) {
|
||||
BT_ERR("The length(%d) exceeds the maximum length supported by the long packet", length);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (((!ctx->enh.long_pkt_cfg_used) && op_len + length + mic_len > MIN(ESP_BLE_MESH_SDU_MAX_LEN, ESP_BLE_MESH_TX_SDU_MAX))) {
|
||||
BT_ERR("Too large data length %d", length);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
} // if (ctx)
|
||||
|
||||
if (op_len + length + mic_len > MIN(ESP_BLE_MESH_SDU_MAX_LEN, ESP_BLE_MESH_TX_SDU_MAX)) {
|
||||
BT_ERR("Too large data length %d", length);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -70,11 +117,6 @@ static esp_err_t ble_mesh_model_send_msg(esp_ble_mesh_model_t *model,
|
||||
ESP_BLE_MESH_MIC_LONG : ESP_BLE_MESH_MIC_SHORT;
|
||||
}
|
||||
|
||||
if (op_len + length + mic_len > MIN(ESP_BLE_MESH_SDU_MAX_LEN, ESP_BLE_MESH_TX_SDU_MAX)) {
|
||||
BT_ERR("Too large data length %d", length);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) {
|
||||
bt_mesh_model_msg_init(model->pub->msg, opcode);
|
||||
net_buf_simple_add_mem(model->pub->msg, data, length);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -20,6 +20,12 @@ extern "C" {
|
||||
|
||||
/*!< The maximum length of a BLE Mesh message, including Opcode, Payload and TransMIC */
|
||||
#define ESP_BLE_MESH_SDU_MAX_LEN 384
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
/* Extended SDU maximum length (included Opcode, Payload and TransMIC) calculation:
|
||||
* SEGMENT_COUNT × (ADV_PAYLOAD_LEN - 17 bytes overhead)
|
||||
* 17 bytes = 9 bytes mesh network header + 4 bytes transport overhead + 4 bytes NetMIC */
|
||||
#define ESP_BLE_MESH_EXT_SDU_MAX_LEN (CONFIG_BLE_MESH_LONG_PACKET_TX_SEG_CNT * (CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN - 17))
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
|
||||
/*!< Length of a short Mesh MIC. */
|
||||
#define ESP_BLE_MESH_MIC_SHORT 4
|
||||
@@ -613,6 +619,166 @@ struct esp_ble_mesh_model {
|
||||
*/
|
||||
#define ESP_BLE_MESH_MODEL_NONE ((esp_ble_mesh_model_t []){})
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
#define ESP_BLE_MESH_ADV_CHAN_UNASSIGNED (0)
|
||||
#define ESP_BLE_MESH_ADV_CHAN_37 BIT(0)
|
||||
#define ESP_BLE_MESH_ADV_CHAN_38 BIT(1)
|
||||
#define ESP_BLE_MESH_ADV_CHAN_39 BIT(2)
|
||||
|
||||
#define ESP_BLE_MESH_DEFAULT_CHANNEL_MAP (ESP_BLE_MESH_ADV_CHAN_37| \
|
||||
ESP_BLE_MESH_ADV_CHAN_38| \
|
||||
ESP_BLE_MESH_ADV_CHAN_39)
|
||||
|
||||
#define ESP_BLE_MESH_ADV_PHY_UNASSIGNED (0)
|
||||
#define ESP_BLE_MESH_ADV_PHY_1M (1)
|
||||
#define ESP_BLE_MESH_ADV_PHY_2M (2)
|
||||
#define ESP_BLE_MESH_ADV_PHY_CODED (3)
|
||||
#define ESP_BLE_MESH_ADV_PHY_DEFAULT ESP_BLE_MESH_ADV_PHY_1M
|
||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||
|
||||
/**
|
||||
* Enhanced configuration for Mesh messages with legacy advertising
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Advertising interval in milliseconds.
|
||||
* If set to 0, the Mesh protocol stack's xmit parameters are used.
|
||||
* If set to another value (e.g., 10), the advertising interval will be 10 ms.
|
||||
*/
|
||||
uint32_t adv_itvl;
|
||||
|
||||
/**
|
||||
* Number of advertising per packet.
|
||||
* If set to 0, the Mesh protocol stack's xmit parameters are used.
|
||||
* If set to another value (e.g., 3), the number of advertising per packet will be 3.
|
||||
*/
|
||||
uint8_t adv_cnt;
|
||||
|
||||
/**
|
||||
* Advertising channel map.
|
||||
* If set to 0, the protocol stack uses default channels.
|
||||
* If set to another value (e.g., ESP_BLE_MESH_ADV_CHAN_37),
|
||||
* the advertising channel map will be 0x01, the advertising
|
||||
* packet will only advertise on channel 37.
|
||||
*/
|
||||
uint8_t channel_map;
|
||||
} esp_ble_mesh_adv_cfg_t;
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
/** Enhanced configuration for Mesh messages with extended advertising */
|
||||
typedef struct {
|
||||
/**
|
||||
* Primary PHY for advertising (ESP_BLE_MESH_ADV_PHY_1M or
|
||||
* ESP_BLE_MESH_ADV_PHY_CODED).
|
||||
* When using coded PHY, receivers must use coded scanning.
|
||||
*/
|
||||
uint8_t primary_phy;
|
||||
|
||||
/**
|
||||
* Secondary PHY for advertising (ESP_BLE_MESH_ADV_PHY_1M,
|
||||
* ESP_BLE_MESH_ADV_PHY_2M, or ESP_BLE_MESH_ADV_PHY_CODED).
|
||||
* When using coded PHY, receivers must use coded scanning.
|
||||
*/
|
||||
uint8_t secondary_phy;
|
||||
|
||||
/**
|
||||
* Include TX power in advertising packets (0: disabled, 1: enabled).
|
||||
* Allows receivers/relays to maintain original transmission power.
|
||||
*/
|
||||
uint8_t include_tx_power:1;
|
||||
|
||||
/** Transmission power level (in dBm) */
|
||||
int8_t tx_power;
|
||||
} esp_ble_mesh_ext_adv_cfg_t;
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
/** Force this message to use long packet format */
|
||||
#define ESP_BLE_MESH_LONG_PACKET_FORCE (1)
|
||||
|
||||
/**
|
||||
* Whether to use the long packet mode will be chosen by the protocol stack,
|
||||
* which currently makes the decision based on message length.
|
||||
* Advertising using the standard BLE Mesh protocol when possible.
|
||||
* Switch to long packet mode for advertising when the standard BLE
|
||||
* Mesh protocol cannot be used.
|
||||
*/
|
||||
#define ESP_BLE_MESH_LONG_PACKET_PREFER (2)
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
|
||||
/** Enhanced message advertising parameters */
|
||||
typedef struct {
|
||||
/**
|
||||
* Use custom advertising parameters (0: disabled, 1: enabled).
|
||||
* When enabled, `adv_cfg` parameters override stack defaults.
|
||||
*/
|
||||
uint8_t adv_cfg_used:1;
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
/**
|
||||
* Use extended advertising parameters (0: disabled, 1: enabled).
|
||||
* When enabled, `ext_adv_cfg` parameters override stack defaults.
|
||||
*/
|
||||
uint8_t ext_adv_cfg_used:1;
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
/**
|
||||
* Control long packet usage (0: disabled, 1: enabled).
|
||||
* When disabled, the protocol stack cannot use long packets to
|
||||
* send this message.
|
||||
*/
|
||||
uint8_t long_pkt_cfg_used:1;
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
|
||||
/** Standard advertising parameters */
|
||||
esp_ble_mesh_adv_cfg_t adv_cfg;
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
/** Extended advertising parameters */
|
||||
esp_ble_mesh_ext_adv_cfg_t ext_adv_cfg;
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
/**
|
||||
* Long packet configuration:
|
||||
* - ESP_BLE_MESH_LONG_PACKET_FORCE
|
||||
* - ESP_BLE_MESH_LONG_PACKET_PREFER
|
||||
*/
|
||||
uint8_t long_pkt_cfg:2;
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
} esp_ble_mesh_msg_enh_params_t;
|
||||
|
||||
#define ESP_BLE_MESH_ADV_CFG_NULL ((esp_ble_mesh_adv_cfg_t){0})
|
||||
#define ESP_BLE_MESH_EXT_ADV_CFG_NULL ((esp_ble_mesh_ext_adv_cfg_t){0})
|
||||
|
||||
#define ESP_BLE_MESH_ADV_CFG_DEFAULT \
|
||||
((esp_ble_mesh_adv_cfg_t){\
|
||||
.adv_itvl= 0, \
|
||||
.adv_cnt = 0, \
|
||||
.channel_map = ESP_BLE_MESH_DEFAULT_CHANNEL_MAP, \
|
||||
})
|
||||
|
||||
#define ESP_BLE_MESH_EXT_ADV_CFG_DEFAULT \
|
||||
((esp_ble_mesh_ext_adv_cfg_t){ \
|
||||
.primary_phy = ESP_BLE_MESH_ADV_PHY_1M, \
|
||||
.secondary_phy = ESP_BLE_MESH_ADV_PHY_1M, \
|
||||
.tx_power = 0x7f, \
|
||||
.include_tx_power = false,\
|
||||
})
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
#define ESP_BLE_MESH_LONG_PACKET_DEF_ENH_SET(ADV_CFG, EXT_ADV_CFG, LONG_PACKET_CFG) \
|
||||
((esp_ble_mesh_msg_enh_params_t){ \
|
||||
.adv_cfg_used = true,\
|
||||
.adv_cfg = ADV_CFG, \
|
||||
.ext_adv_cfg_used = true, \
|
||||
.ext_adv_cfg = EXT_ADV_CFG, \
|
||||
.long_pkt_cfg_used = true, \
|
||||
.long_pkt_cfg = LONG_PACKET_CFG, \
|
||||
})
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
|
||||
/** Message sending context.
|
||||
* This structure is associated with struct bt_mesh_msg_ctx in mesh_access.h
|
||||
*/
|
||||
@@ -664,6 +830,9 @@ typedef struct {
|
||||
|
||||
/** Indicate if the message is sent by a node server model, no need to be initialized before sending message */
|
||||
bool srv_send __attribute__((deprecated));
|
||||
|
||||
/** Enhanced message advertising parameters */
|
||||
esp_ble_mesh_msg_enh_params_t enh;
|
||||
} esp_ble_mesh_msg_ctx_t;
|
||||
|
||||
/** Provisioning properties & capabilities.
|
||||
|
||||
@@ -2950,6 +2950,8 @@ void btc_ble_mesh_model_call_handler(btc_msg_t *msg)
|
||||
.msg_timeout = arg->model_send.msg_timeout,
|
||||
};
|
||||
|
||||
memcpy(¶m.ctx.enh, &arg->model_send.ctx->enh, sizeof(bt_mesh_msg_enh_params_t));
|
||||
|
||||
err = bt_mesh_client_send_msg(¶m, buf, arg->model_send.need_rsp,
|
||||
btc_ble_mesh_client_model_timeout_cb);
|
||||
bt_mesh_free_buf(buf);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -29,6 +29,11 @@
|
||||
|
||||
#define BLE_MESH_SDU_MAX_LEN 384
|
||||
|
||||
/* Extended SDU maximum length (message length + TransMIC size) calculation:
|
||||
* 32 segments maximum × (249 bytes max PDU - 17 bytes overhead)
|
||||
* 17 bytes = 9 bytes mesh header + 4 bytes transport overhead + 4-byte NetMIC */
|
||||
#define BLE_MESH_EXT_SDU_MAX_LEN (32*(249-17))
|
||||
|
||||
extern const struct bt_mesh_comp *comp_0;
|
||||
static uint16_t dev_primary_addr;
|
||||
|
||||
@@ -973,10 +978,24 @@ static int model_send(struct bt_mesh_model *model,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (msg->len > MIN(BLE_MESH_EXT_TX_SDU_MAX, BLE_MESH_EXT_SDU_MAX_LEN) - BLE_MESH_MIC_SHORT) {
|
||||
BT_ERR("Too big ext message (len %d)", msg->len);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
if ((msg->len <= MIN(BLE_MESH_EXT_TX_SDU_MAX, BLE_MESH_EXT_SDU_MAX_LEN) - BLE_MESH_MIC_SHORT) &&
|
||||
(msg->len > MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SDU_MAX_LEN) - BLE_MESH_MIC_SHORT) &&
|
||||
!tx->ctx->enh.long_pkt_cfg_used) {
|
||||
BT_ERR("Extended message length %d requires long packet mode, but long_pkt_cfg_used is false", msg->len);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
#else
|
||||
if (msg->len > MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SDU_MAX_LEN) - BLE_MESH_MIC_SHORT) {
|
||||
BT_ERR("Too big message (len %d)", msg->len);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!implicit_bind && !model_has_key(model, tx->ctx->app_idx)) {
|
||||
BT_ERR("Model not bound to AppKey 0x%04x", tx->ctx->app_idx);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -60,6 +60,7 @@ static inline int adv_send(struct net_buf *buf)
|
||||
void *cb_data = BLE_MESH_ADV(buf)->cb_data;
|
||||
struct bt_mesh_adv_param param = {0};
|
||||
uint16_t duration = 0U, adv_int = 0U;
|
||||
uint8_t adv_cnt = 0;
|
||||
struct bt_mesh_adv_data ad = {0};
|
||||
int err = 0;
|
||||
|
||||
@@ -69,10 +70,20 @@ 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_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);
|
||||
if (BLE_MESH_ADV(buf)->adv_itvl != BLE_MESH_ADV_ITVL_DEFAULT) {
|
||||
adv_int = MAX(ADV_ITVL_MIN, BLE_MESH_ADV(buf)->adv_itvl);
|
||||
} else {
|
||||
adv_int = MAX(ADV_ITVL_MIN,
|
||||
BLE_MESH_TRANSMIT_INT(BLE_MESH_ADV(buf)->xmit));
|
||||
}
|
||||
|
||||
if (BLE_MESH_ADV(buf)->adv_cnt != BLE_MESH_ADV_CNT_DEFAULT) {
|
||||
adv_cnt = BLE_MESH_ADV(buf)->adv_cnt;
|
||||
} else {
|
||||
adv_cnt = BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1;
|
||||
}
|
||||
|
||||
duration = adv_cnt * (adv_int + 10);
|
||||
|
||||
BT_DBG("count %u interval %ums duration %ums",
|
||||
BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1, adv_int,
|
||||
@@ -86,10 +97,38 @@ static inline int adv_send(struct net_buf *buf)
|
||||
param.interval_min = ADV_SCAN_UNIT(adv_int);
|
||||
param.interval_max = param.interval_min;
|
||||
|
||||
if (BLE_MESH_ADV(buf)->channel_map) {
|
||||
param.channel_map = BLE_MESH_ADV(buf)->channel_map;
|
||||
} else {
|
||||
param.channel_map = BLE_MESH_ADV_CHAN_DEFAULT;
|
||||
}
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
param.adv_duration = duration;
|
||||
param.adv_count = BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1;
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_EXT_PROV ||
|
||||
BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_EXT_DATA ||
|
||||
BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_EXT_RELAY_DATA
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
|| BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_EXT_LONG_PROV
|
||||
|| BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_EXT_LONG_DATA
|
||||
|| BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_EXT_LONG_RELAY_DATA
|
||||
#endif
|
||||
) {
|
||||
param.primary_phy = EXT_ADV(buf)->primary_phy;
|
||||
param.secondary_phy = EXT_ADV(buf)->secondary_phy;
|
||||
param.include_tx_power = EXT_ADV(buf)->include_tx_power;
|
||||
param.tx_power = EXT_ADV(buf)->tx_power;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
param.primary_phy = BLE_MESH_ADV_PRI_PHY_DEFAULT;
|
||||
param.secondary_phy = BLE_MESH_ADV_SEC_PHY_DEFAULT;
|
||||
param.include_tx_power = BLE_MESH_TX_POWER_INCLUDE_DEFAULT;
|
||||
param.tx_power = BLE_MESH_TX_POWER_DEFAULT;
|
||||
}
|
||||
|
||||
param.adv_duration = duration;
|
||||
param.adv_count = adv_cnt;
|
||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||
|
||||
#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
|
||||
if (BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_PROXY_SOLIC) {
|
||||
|
||||
@@ -35,6 +35,36 @@ struct bt_mesh_adv_queue relay_adv_queue;
|
||||
#endif
|
||||
|
||||
static bt_mesh_mutex_t adv_buf_alloc_lock;
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
NET_BUF_POOL_DEFINE(ext_adv_buf_pool, CONFIG_BLE_MESH_EXT_ADV_BUF_COUNT,
|
||||
BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
|
||||
static bt_mesh_ext_adv_t ext_adv_pool[CONFIG_BLE_MESH_EXT_ADV_BUF_COUNT];
|
||||
#if CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT
|
||||
NET_BUF_POOL_DEFINE(ext_relay_adv_buf_pool, CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT,
|
||||
BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
|
||||
static bt_mesh_ext_adv_t ext_relay_adv_pool[CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT];
|
||||
#endif /* CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT */
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
NET_BUF_POOL_DEFINE(ext_long_adv_buf_pool, CONFIG_BLE_MESH_LONG_PACKET_TX_SEG_CNT,
|
||||
CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
|
||||
static bt_mesh_ext_adv_t ext_long_adv_pool[CONFIG_BLE_MESH_LONG_PACKET_TX_SEG_CNT];
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT
|
||||
NET_BUF_POOL_DEFINE(ext_long_relay_adv_buf_pool, CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT,
|
||||
CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
|
||||
static bt_mesh_ext_adv_t ext_long_relay_adv_pool[CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT];
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT */
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
|
||||
static inline void init_adv_with_defaults(struct bt_mesh_adv *adv,
|
||||
enum bt_mesh_adv_type type)
|
||||
{
|
||||
memset(adv, 0, sizeof(struct bt_mesh_adv));
|
||||
adv->type = type;
|
||||
adv->adv_itvl = BLE_MESH_ADV_ITVL_DEFAULT;
|
||||
adv->adv_cnt = BLE_MESH_ADV_CNT_DEFAULT;
|
||||
adv->channel_map = BLE_MESH_ADV_CHAN_DEFAULT;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_FRIEND
|
||||
/* We reserve one extra buffer for each friendship, since we need to be able
|
||||
@@ -48,8 +78,10 @@ NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT,
|
||||
|
||||
bt_mesh_friend_adv_t frnd_adv_pool[FRIEND_BUF_COUNT];
|
||||
|
||||
struct bt_mesh_adv *bt_mesh_frnd_adv_buf_get(int idx)
|
||||
struct bt_mesh_adv *bt_mesh_frnd_adv_buf_get(int idx, enum bt_mesh_adv_type type)
|
||||
{
|
||||
memset(&frnd_adv_pool[idx].adv, 0, sizeof(struct bt_mesh_adv));
|
||||
init_adv_with_defaults(&frnd_adv_pool[idx].adv, type);
|
||||
frnd_adv_pool[idx].app_idx = BLE_MESH_KEY_UNUSED;
|
||||
return &frnd_adv_pool[idx].adv;
|
||||
}
|
||||
@@ -154,11 +186,58 @@ int bt_mesh_adv_inst_deinit(enum bt_mesh_adv_inst_type inst_type)
|
||||
|
||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||
|
||||
struct bt_mesh_adv *adv_alloc(int id)
|
||||
struct bt_mesh_adv *adv_alloc(int id, enum bt_mesh_adv_type type)
|
||||
{
|
||||
init_adv_with_defaults(&adv_pool[id], type);
|
||||
return &adv_pool[id];
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
struct bt_mesh_adv *ext_adv_alloc(int id, enum bt_mesh_adv_type type)
|
||||
{
|
||||
init_adv_with_defaults(&ext_adv_pool[id].adv, type);
|
||||
ext_adv_pool[id].primary_phy = BLE_MESH_ADV_PRI_PHY_DEFAULT;
|
||||
ext_adv_pool[id].secondary_phy = BLE_MESH_ADV_SEC_PHY_DEFAULT;
|
||||
ext_adv_pool[id].include_tx_power = BLE_MESH_TX_POWER_INCLUDE_DEFAULT;
|
||||
ext_adv_pool[id].tx_power = BLE_MESH_TX_POWER_DEFAULT;
|
||||
return &ext_adv_pool[id].adv;
|
||||
}
|
||||
#if CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT
|
||||
struct bt_mesh_adv *ext_relay_adv_alloc(int id, enum bt_mesh_adv_type type)
|
||||
{
|
||||
init_adv_with_defaults(&ext_relay_adv_pool[id].adv, type);
|
||||
ext_relay_adv_pool[id].primary_phy = BLE_MESH_ADV_PRI_PHY_DEFAULT;
|
||||
ext_relay_adv_pool[id].secondary_phy = BLE_MESH_ADV_SEC_PHY_DEFAULT;
|
||||
ext_relay_adv_pool[id].include_tx_power = BLE_MESH_TX_POWER_INCLUDE_DEFAULT;
|
||||
ext_relay_adv_pool[id].tx_power = BLE_MESH_TX_POWER_DEFAULT;
|
||||
return &ext_relay_adv_pool[id].adv;
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
struct bt_mesh_adv *ext_long_adv_alloc(int id, enum bt_mesh_adv_type type)
|
||||
{
|
||||
init_adv_with_defaults(&ext_long_adv_pool[id].adv, type);
|
||||
ext_long_adv_pool[id].primary_phy = BLE_MESH_ADV_PRI_PHY_DEFAULT;
|
||||
ext_long_adv_pool[id].secondary_phy = BLE_MESH_ADV_SEC_PHY_DEFAULT;
|
||||
ext_long_adv_pool[id].include_tx_power = BLE_MESH_TX_POWER_INCLUDE_DEFAULT;
|
||||
ext_long_adv_pool[id].tx_power = BLE_MESH_TX_POWER_DEFAULT;
|
||||
return &ext_long_adv_pool[id].adv;
|
||||
}
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT
|
||||
struct bt_mesh_adv *ext_long_relay_adv_alloc(int id, enum bt_mesh_adv_type type)
|
||||
{
|
||||
init_adv_with_defaults(&ext_long_relay_adv_pool[id].adv, type);
|
||||
ext_long_relay_adv_pool[id].primary_phy = BLE_MESH_ADV_PRI_PHY_DEFAULT;
|
||||
ext_long_relay_adv_pool[id].secondary_phy = BLE_MESH_ADV_SEC_PHY_DEFAULT;
|
||||
ext_long_relay_adv_pool[id].include_tx_power = BLE_MESH_TX_POWER_INCLUDE_DEFAULT;
|
||||
ext_long_relay_adv_pool[id].tx_power = BLE_MESH_TX_POWER_DEFAULT;
|
||||
return &ext_long_relay_adv_pool[id].adv;
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT */
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
|
||||
struct bt_mesh_adv_type_manager *bt_mesh_adv_types_mgnt_get(enum bt_mesh_adv_type adv_type)
|
||||
{
|
||||
return &adv_types[adv_type];
|
||||
@@ -357,12 +436,8 @@ struct net_buf *bt_mesh_adv_create_from_pool(enum bt_mesh_adv_type type,
|
||||
BT_DBG("pool %p, buf_count %d, uinit_count %d, ref %d",
|
||||
buf->pool, pool->buf_count, pool->uninit_count, buf->ref);
|
||||
|
||||
adv = adv_types[type].pool_allocator(net_buf_id(buf));
|
||||
adv = adv_types[type].pool_allocator(net_buf_id(buf), type);
|
||||
BLE_MESH_ADV(buf) = adv;
|
||||
|
||||
(void)memset(adv, 0, sizeof(*adv));
|
||||
|
||||
adv->type = type;
|
||||
bt_mesh_r_mutex_unlock(&adv_buf_alloc_lock);
|
||||
return buf;
|
||||
}
|
||||
@@ -476,8 +551,10 @@ bool bt_mesh_ignore_relay_packet(uint32_t timestamp)
|
||||
return ((interval >= BLE_MESH_RELAY_TIME_INTERVAL) ? true : false);
|
||||
}
|
||||
|
||||
static struct bt_mesh_adv *relay_adv_alloc(int id)
|
||||
static struct bt_mesh_adv *relay_adv_alloc(int id, enum bt_mesh_adv_type type)
|
||||
{
|
||||
memset(&relay_adv_pool[id], 0, sizeof(struct bt_mesh_adv));
|
||||
init_adv_with_defaults(&relay_adv_pool[id], type);
|
||||
return &relay_adv_pool[id];
|
||||
}
|
||||
|
||||
@@ -531,21 +608,58 @@ uint16_t bt_mesh_get_stored_relay_count(void)
|
||||
return (uint16_t)uxQueueMessagesWaiting(relay_adv_queue.q.handle);
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE
|
||||
uint16_t ble_mesh_relay_adv_buf_count_get(void)
|
||||
{
|
||||
uint16_t relay_adv_count = 2 + CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT;
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV && CONFIG_BLE_MESH_RELAY
|
||||
relay_adv_count += CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT;
|
||||
#endif
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET && CONFIG_BLE_MESH_RELAY
|
||||
relay_adv_count += CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT;
|
||||
#endif
|
||||
return relay_adv_count;
|
||||
}
|
||||
|
||||
void bt_mesh_relay_adv_init(void)
|
||||
{
|
||||
bt_mesh_adv_queue_init(&relay_adv_queue, CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT,
|
||||
bt_mesh_adv_queue_init(&relay_adv_queue, ble_mesh_relay_adv_buf_count_get(),
|
||||
ble_mesh_relay_task_post);
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_RELAY_DATA, &relay_adv_queue,
|
||||
&relay_adv_buf_pool, &relay_adv_alloc);
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_RELAY_DATA, &relay_adv_queue,
|
||||
&ext_adv_buf_pool, &ext_relay_adv_alloc);
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET && CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_LONG_RELAY_DATA, &relay_adv_queue,
|
||||
&ext_long_relay_adv_buf_pool, ext_long_relay_adv_alloc);
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
|
||||
bt_mesh_adv_inst_init(BLE_MESH_RELAY_ADV_INS,
|
||||
CONFIG_BLE_MESH_RELAY_ADV_INST_ID);
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_EXT_RELAY_DATA);
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
#else
|
||||
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
|
||||
#endif
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_RELAY_DATA);
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||
#endif /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */
|
||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||
}
|
||||
@@ -554,14 +668,33 @@ void bt_mesh_relay_adv_deinit(void)
|
||||
{
|
||||
bt_mesh_adv_queue_deinit(&relay_adv_queue);
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_RELAY_DATA);
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_RELAY_DATA);
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
|
||||
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_EXT_RELAY_DATA);
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_RELAY_ADV_INS, BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
bt_mesh_adv_inst_deinit(BLE_MESH_RELAY_ADV_INS);
|
||||
#else
|
||||
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_RELAY_DATA);
|
||||
#endif
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_RELAY_DATA);
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||
#endif /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */
|
||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||
bt_mesh_unref_buf_from_pool(&relay_adv_buf_pool);
|
||||
@@ -597,6 +730,27 @@ void bt_mesh_frnd_adv_deinit(void)
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_FRIEND */
|
||||
|
||||
static ALWAYS_INLINE
|
||||
uint16_t ble_mesh_adv_buf_count_get(void)
|
||||
{
|
||||
uint16_t adv_count = 2 + CONFIG_BLE_MESH_ADV_BUF_COUNT;
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
adv_count += CONFIG_BLE_MESH_EXT_ADV_BUF_COUNT;
|
||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_RELAY
|
||||
adv_count += CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
adv_count += CONFIG_BLE_MESH_LONG_PACKET_ADV_BUF_COUNT;
|
||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_RELAY
|
||||
adv_count += CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT;
|
||||
#endif
|
||||
#endif
|
||||
return adv_count;
|
||||
}
|
||||
|
||||
void bt_mesh_adv_task_init(void adv_thread(void *p))
|
||||
{
|
||||
if (!adv_thread) {
|
||||
@@ -625,7 +779,7 @@ void bt_mesh_adv_task_init(void adv_thread(void *p))
|
||||
void bt_mesh_adv_common_init(void)
|
||||
{
|
||||
bt_mesh_r_mutex_create(&adv_buf_alloc_lock);
|
||||
bt_mesh_adv_queue_init(&adv_queue, BLE_MESH_ADV_QUEUE_SIZE, bt_mesh_task_post);
|
||||
bt_mesh_adv_queue_init(&adv_queue, ble_mesh_adv_buf_count_get(), bt_mesh_task_post);
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_PROV, &adv_queue, &adv_buf_pool, adv_alloc);
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_DATA, &adv_queue, &adv_buf_pool, adv_alloc);
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_BEACON, &adv_queue, &adv_buf_pool, adv_alloc);
|
||||
@@ -636,7 +790,21 @@ void bt_mesh_adv_common_init(void)
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
bt_mesh_adv_inst_init(BLE_MESH_ADV_INS, CONFIG_BLE_MESH_ADV_INST_ID);
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_PROV, &adv_queue, &ext_adv_buf_pool, ext_adv_alloc);
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_DATA, &adv_queue, &ext_adv_buf_pool, ext_adv_alloc);
|
||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_EXT_RELAY_ADV_BUF_COUNT
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_RELAY_DATA, &adv_queue, &ext_relay_adv_buf_pool, ext_relay_adv_alloc);
|
||||
#endif
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_LONG_PROV, &adv_queue, &ext_long_adv_buf_pool, ext_long_adv_alloc);
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_LONG_DATA, &adv_queue, &ext_long_adv_buf_pool, ext_long_adv_alloc);
|
||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT
|
||||
bt_mesh_adv_type_init(BLE_MESH_ADV_EXT_LONG_RELAY_DATA, &adv_queue, &ext_long_relay_adv_buf_pool, ext_long_relay_adv_alloc);
|
||||
#endif /* !CONFIG_BLE_MESH_RELAY_ADV_BUF && CONFIG_BLE_MESH_LONG_PACKET_RELAY_ADV_BUF_COUNT */
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||
|
||||
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||
/**
|
||||
@@ -651,7 +819,21 @@ void bt_mesh_adv_common_init(void)
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_DATA);
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_BEACON);
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_URI);
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_PROV);
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_DATA);
|
||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_RELAY_DATA);
|
||||
#endif
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_PROV);
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_DATA);
|
||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||
bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
|
||||
#endif /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_DEINIT
|
||||
@@ -677,6 +859,25 @@ void bt_mesh_adv_common_deinit(void)
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_BEACON);
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_URI);
|
||||
|
||||
#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_PROXY_SOLIC);
|
||||
#endif
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_PROV);
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_DATA);
|
||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_RELAY_DATA);
|
||||
#endif
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_LONG_PROV);
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_LONG_DATA);
|
||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||
bt_mesh_adv_type_deinit(BLE_MESH_ADV_EXT_LONG_RELAY_DATA);
|
||||
#endif
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
|
||||
bt_mesh_adv_queue_deinit(&adv_queue);
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
bt_mesh_adv_inst_deinit(BLE_MESH_ADV_INS);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -48,9 +48,6 @@ extern "C" {
|
||||
|
||||
#define BLE_MESH_ADV_INS_UNUSED 0xFF
|
||||
|
||||
/* We reserve one queue item for bt_mesh_adv_update() */
|
||||
#define BLE_MESH_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_ADV_BUF_COUNT + 1)
|
||||
|
||||
struct bt_mesh_adv {
|
||||
const struct bt_mesh_send_cb *cb;
|
||||
void *cb_data;
|
||||
@@ -60,8 +57,23 @@ struct bt_mesh_adv {
|
||||
bt_mesh_atomic_t busy;
|
||||
|
||||
uint8_t xmit;
|
||||
|
||||
uint32_t adv_itvl;
|
||||
uint8_t adv_cnt;
|
||||
uint8_t channel_map;
|
||||
};
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
#define EXT_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), bt_mesh_ext_adv_t, adv)
|
||||
typedef struct {
|
||||
struct bt_mesh_adv adv;
|
||||
uint8_t primary_phy;
|
||||
uint8_t secondary_phy;
|
||||
uint8_t include_tx_power:1;
|
||||
int8_t tx_power;
|
||||
} bt_mesh_ext_adv_t;
|
||||
#endif
|
||||
|
||||
#if CONFIG_BLE_MESH_FRIEND
|
||||
|
||||
#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), bt_mesh_friend_adv_t, adv)
|
||||
@@ -110,14 +122,6 @@ typedef struct bt_mesh_msg {
|
||||
uint32_t timestamp; /* Timestamp recorded when the relay packet is posted to queue */
|
||||
} bt_mesh_msg_t;
|
||||
|
||||
typedef struct bt_mesh_adv *(*bt_mesh_pool_allocator_t)(int id);
|
||||
typedef void (*bt_mesh_adv_queue_send_cb_t)(bt_mesh_msg_t *msg, uint32_t timeout, bool front);
|
||||
|
||||
struct bt_mesh_adv_queue {
|
||||
bt_mesh_queue_t q;
|
||||
bt_mesh_adv_queue_send_cb_t send;
|
||||
};
|
||||
|
||||
struct bt_mesh_adv_inst {
|
||||
uint8_t id;
|
||||
#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
|
||||
@@ -132,6 +136,16 @@ struct bt_mesh_adv_inst {
|
||||
enum bt_mesh_adv_type {
|
||||
BLE_MESH_ADV_PROV,
|
||||
BLE_MESH_ADV_DATA,
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
BLE_MESH_ADV_EXT_PROV,
|
||||
BLE_MESH_ADV_EXT_DATA,
|
||||
BLE_MESH_ADV_EXT_RELAY_DATA,
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
BLE_MESH_ADV_EXT_LONG_PROV,
|
||||
BLE_MESH_ADV_EXT_LONG_DATA,
|
||||
BLE_MESH_ADV_EXT_LONG_RELAY_DATA,
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
#if CONFIG_BLE_MESH_FRIEND
|
||||
BLE_MESH_ADV_FRIEND,
|
||||
#endif
|
||||
@@ -155,15 +169,20 @@ typedef enum {
|
||||
BLE_MESH_BUF_REF_MAX,
|
||||
} bt_mesh_buf_ref_flag_t;
|
||||
|
||||
struct bt_mesh_adv_type_manager {
|
||||
struct bt_mesh_adv_queue *adv_q;
|
||||
struct net_buf_pool *pool;
|
||||
bt_mesh_pool_allocator_t pool_allocator;
|
||||
};
|
||||
|
||||
static const uint8_t adv_type[] = {
|
||||
[BLE_MESH_ADV_PROV] = BLE_MESH_DATA_MESH_PROV,
|
||||
[BLE_MESH_ADV_DATA] = BLE_MESH_DATA_MESH_MESSAGE,
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
[BLE_MESH_ADV_EXT_PROV] = BLE_MESH_DATA_MESH_PROV,
|
||||
[BLE_MESH_ADV_EXT_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE,
|
||||
[BLE_MESH_ADV_EXT_DATA] = BLE_MESH_DATA_MESH_MESSAGE,
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
[BLE_MESH_ADV_EXT_LONG_PROV] = BLE_MESH_DATA_MESH_PROV,
|
||||
[BLE_MESH_ADV_EXT_LONG_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE,
|
||||
[BLE_MESH_ADV_EXT_LONG_DATA] = BLE_MESH_DATA_MESH_MESSAGE,
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
#if CONFIG_BLE_MESH_FRIEND
|
||||
[BLE_MESH_ADV_FRIEND] = BLE_MESH_DATA_MESH_MESSAGE,
|
||||
#endif
|
||||
@@ -174,6 +193,20 @@ static const uint8_t adv_type[] = {
|
||||
[BLE_MESH_ADV_URI] = BLE_MESH_DATA_URI,
|
||||
};
|
||||
|
||||
typedef struct bt_mesh_adv *(*bt_mesh_pool_allocator_t)(int id, enum bt_mesh_adv_type type);
|
||||
typedef void (*bt_mesh_adv_queue_send_cb_t)(bt_mesh_msg_t *msg, uint32_t timeout, bool front);
|
||||
|
||||
struct bt_mesh_adv_type_manager {
|
||||
struct bt_mesh_adv_queue *adv_q;
|
||||
struct net_buf_pool *pool;
|
||||
bt_mesh_pool_allocator_t pool_allocator;
|
||||
};
|
||||
|
||||
struct bt_mesh_adv_queue {
|
||||
bt_mesh_queue_t q;
|
||||
bt_mesh_adv_queue_send_cb_t send;
|
||||
};
|
||||
|
||||
static inline TickType_t K_WAIT(int32_t val)
|
||||
{
|
||||
return (val == K_FOREVER) ? portMAX_DELAY : (val / portTICK_PERIOD_MS);
|
||||
@@ -255,7 +288,7 @@ void bt_mesh_relay_adv_deinit(void);
|
||||
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
|
||||
|
||||
#if CONFIG_BLE_MESH_FRIEND
|
||||
struct bt_mesh_adv *bt_mesh_frnd_adv_buf_get(int id);
|
||||
struct bt_mesh_adv *bt_mesh_frnd_adv_buf_get(int id, enum bt_mesh_adv_type type);
|
||||
struct net_buf_pool *bt_mesh_frnd_adv_pool_get(void);
|
||||
void bt_mesh_frnd_adv_init(void);
|
||||
#if CONFIG_BLE_MESH_DEINIT
|
||||
|
||||
@@ -30,8 +30,10 @@ static struct bt_mesh_ble_adv_tx ble_adv_tx[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
|
||||
|
||||
static void bt_mesh_ble_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front);
|
||||
|
||||
static struct bt_mesh_adv *ble_adv_alloc(int id)
|
||||
static struct bt_mesh_adv *ble_adv_alloc(int id, enum bt_mesh_adv_type type)
|
||||
{
|
||||
memset(&ble_adv_pool[id], 0, sizeof(struct bt_mesh_adv));
|
||||
ble_adv_pool[id].type = type;
|
||||
return &ble_adv_pool[id];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA
|
||||
* SPDX-FileCopyrightText: 2015-2016 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -240,9 +240,19 @@ void bt_mesh_ble_ext_adv_report(tBTM_BLE_EXT_ADV_REPORT *ext_adv_report)
|
||||
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
static struct {
|
||||
struct bt_mesh_adv_report adv_rpt;
|
||||
uint8_t adv_data_len;
|
||||
uint8_t adv_data[2 + CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN];
|
||||
} adv_report_cache;
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
|
||||
static bool bt_mesh_scan_result_process(tBTM_BLE_EXT_ADV_REPORT *ext_adv_report)
|
||||
{
|
||||
struct bt_mesh_adv_report adv_rpt = {0};
|
||||
uint8_t *adv_data = NULL;
|
||||
uint8_t adv_data_len = 0;
|
||||
|
||||
assert(ext_adv_report);
|
||||
|
||||
@@ -251,23 +261,31 @@ static bool bt_mesh_scan_result_process(tBTM_BLE_EXT_ADV_REPORT *ext_adv_report)
|
||||
adv_rpt.primary_phy = ext_adv_report->primary_phy;
|
||||
adv_rpt.secondary_phy = ext_adv_report->secondry_phy;
|
||||
adv_rpt.rssi = ext_adv_report->rssi;
|
||||
adv_rpt.tx_power = ext_adv_report->tx_power;
|
||||
adv_data = ext_adv_report->adv_data;
|
||||
adv_data_len = ext_adv_report->adv_data_len;
|
||||
|
||||
#if !CONFIG_BLE_MESH_EXT_ADV
|
||||
if (!(ext_adv_report->event_type & BTM_BLE_ADV_LEGACY_MASK)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
BT_DBG("Recv adv report type %04x", ext_adv_report->event_type);
|
||||
|
||||
if (ext_adv_report->adv_data_len > BLE_MESH_GAP_ADV_MAX_LEN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (ext_adv_report->event_type) {
|
||||
case BLE_MESH_ADV_IND:
|
||||
case BLE_MESH_ADV_DIRECT_IND:
|
||||
case BLE_MESH_ADV_SCAN_IND:
|
||||
case BLE_MESH_ADV_NONCONN_IND:
|
||||
case BLE_MESH_ADV_SCAN_RSP:
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
case BLE_MESH_EXT_ADV_NONCONN_IND:
|
||||
#endif
|
||||
adv_rpt.adv_type = ext_adv_report->event_type;
|
||||
break;
|
||||
default:
|
||||
@@ -275,10 +293,51 @@ static bool bt_mesh_scan_result_process(tBTM_BLE_EXT_ADV_REPORT *ext_adv_report)
|
||||
break;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
switch (ext_adv_report->data_status) {
|
||||
case BTM_BLE_EXT_ADV_DATA_COMPLETE:
|
||||
if (adv_report_cache.adv_data_len) {
|
||||
memcpy(adv_report_cache.adv_data + adv_report_cache.adv_data_len,
|
||||
ext_adv_report->adv_data, ext_adv_report->adv_data_len);
|
||||
adv_report_cache.adv_data_len += ext_adv_report->adv_data_len;
|
||||
adv_data = adv_report_cache.adv_data;
|
||||
adv_data_len = adv_report_cache.adv_data_len;
|
||||
adv_report_cache.adv_data_len = 0;
|
||||
}
|
||||
break;
|
||||
case BTM_BLE_EXT_ADV_DATA_INCOMPLETE:
|
||||
if ((adv_report_cache.adv_data_len + ext_adv_report->adv_data_len) > BLE_MESH_GAP_ADV_MAX_LEN) {
|
||||
adv_report_cache.adv_data_len = 0;
|
||||
return false;
|
||||
}
|
||||
if (adv_report_cache.adv_data_len == 0) {
|
||||
memcpy(&adv_report_cache.adv_rpt, &adv_rpt, sizeof(struct bt_mesh_adv_report));
|
||||
}
|
||||
memcpy(adv_report_cache.adv_data + adv_report_cache.adv_data_len,
|
||||
ext_adv_report->adv_data, ext_adv_report->adv_data_len);
|
||||
adv_report_cache.adv_data_len += ext_adv_report->adv_data_len;
|
||||
/* To avoid discarding user's packets,
|
||||
* it is assumed here that this packet
|
||||
* is not mesh's packet */
|
||||
return false;
|
||||
case BTM_BLE_EXT_ADV_DATA_TRUNCATED:
|
||||
if (adv_report_cache.adv_data_len) {
|
||||
memset(&adv_report_cache, 0, sizeof(adv_report_cache));
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
#else /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
if (ext_adv_report->data_status != BTM_BLE_EXT_ADV_DATA_COMPLETE) {
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
|
||||
if (bt_mesh_scan_dev_found_cb) {
|
||||
net_buf_simple_init_with_data(&adv_rpt.adv_data, ext_adv_report->adv_data, ext_adv_report->adv_data_len);
|
||||
net_buf_simple_init_with_data(&adv_rpt.adv_data, adv_data, adv_data_len);
|
||||
bt_mesh_scan_dev_found_cb(&adv_rpt);
|
||||
if (adv_rpt.adv_data.len != ext_adv_report->adv_data_len) {
|
||||
if (adv_rpt.adv_data.len != adv_data_len) {
|
||||
/* The advertising data has been processed by Mesh Protocol */
|
||||
return true;
|
||||
}
|
||||
@@ -430,7 +489,7 @@ static int set_adv_data(uint16_t hci_op, const struct bt_mesh_adv_data *ad, size
|
||||
|
||||
for (i = 0; i < ad_len; i++) {
|
||||
/* Check if ad fit in the remaining buffer */
|
||||
if (param.len + ad[i].data_len + 2 > 31) {
|
||||
if (param.len + ad[i].data_len + 2 > sizeof(param.data)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -593,6 +652,11 @@ static void bt_mesh_scan_result_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARC
|
||||
#endif
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
static struct {
|
||||
bool set;
|
||||
tBTA_DM_BLE_GAP_EXT_ADV_PARAMS param;
|
||||
} last_param[BLE_MESH_ADV_INS_TYPES_NUM];
|
||||
|
||||
int bt_le_ext_adv_start(const uint8_t inst_id,
|
||||
const struct bt_mesh_adv_param *param,
|
||||
const struct bt_mesh_adv_data *ad, size_t ad_len,
|
||||
@@ -624,11 +688,10 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
|
||||
ext_adv_params.type = BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_SCAN;
|
||||
} else {
|
||||
if (param->primary_phy == BLE_MESH_ADV_PHY_1M &&
|
||||
param->secondary_phy == BLE_MESH_ADV_PHY_1M) {
|
||||
ext_adv_params.type = BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_NONCONN;
|
||||
} else {
|
||||
BT_ERR("Unsupported PHY: pri %d sec %d",param->primary_phy, param->secondary_phy);
|
||||
return -EINVAL;
|
||||
param->secondary_phy == BLE_MESH_ADV_PHY_1M &&
|
||||
param->include_tx_power == false &&
|
||||
ad->data_len <= 29) {
|
||||
ext_adv_params.type = BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_NONCONN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -648,12 +711,16 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
|
||||
|
||||
ext_adv_params.sid = inst_id;
|
||||
ext_adv_params.max_skip = 0;
|
||||
ext_adv_params.tx_power = 0x7F;
|
||||
ext_adv_params.tx_power = param->tx_power;
|
||||
ext_adv_params.scan_req_notif = false;
|
||||
ext_adv_params.primary_phy = param->primary_phy;
|
||||
ext_adv_params.secondary_phy = param->secondary_phy;
|
||||
ext_adv_params.filter_policy = BLE_MESH_AP_SCAN_CONN_ALL;
|
||||
ext_adv_params.channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
|
||||
ext_adv_params.channel_map = param->channel_map;
|
||||
|
||||
if (param->include_tx_power) {
|
||||
ext_adv_params.type |= BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_INCLUDE_TX_PWR;
|
||||
}
|
||||
|
||||
interval = param->interval_min;
|
||||
|
||||
@@ -674,8 +741,18 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
|
||||
ext_adv_params.interval_min = interval;
|
||||
ext_adv_params.interval_max = interval;
|
||||
|
||||
/* Check if we can start adv using BTM_BleSetAdvParamsStartAdvCheck */
|
||||
BTA_DmBleGapExtAdvSetParams(inst_id, &ext_adv_params);
|
||||
if (memcmp(&ext_adv_params, &last_param[inst_id].param, sizeof(tBTA_DM_BLE_GAP_EXT_ADV_PARAMS))) {
|
||||
if (last_param[inst_id].set) {
|
||||
BTA_DmBleGapExtAdvSetRemove(inst_id);
|
||||
}
|
||||
|
||||
last_param[inst_id].set = true;
|
||||
|
||||
/* Check if we can start adv using BTM_BleSetAdvParamsStartAdvCheck */
|
||||
BTA_DmBleGapExtAdvSetParams(inst_id, &ext_adv_params);
|
||||
|
||||
memcpy(&last_param[inst_id].param, &ext_adv_params, sizeof(tBTA_DM_BLE_GAP_EXT_ADV_PARAMS));
|
||||
}
|
||||
|
||||
err = set_adv_data(BLE_MESH_HCI_OP_SET_ADV_DATA, inst_id, ad, ad_len);
|
||||
if (err) {
|
||||
@@ -723,7 +800,6 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
|
||||
const struct bt_mesh_adv_data *sd, size_t sd_len)
|
||||
{
|
||||
tBTA_START_ADV_CMPL_CBACK *p_start_adv_cb = NULL;
|
||||
tBTM_BLE_ADV_CHNL_MAP channel_map = 0U;
|
||||
tBLE_ADDR_TYPE addr_type_own = 0U;
|
||||
tBLE_BD_ADDR p_dir_bda = {0};
|
||||
tBTM_BLE_AFP adv_fil_pol = 0U;
|
||||
@@ -787,7 +863,6 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
|
||||
addr_type_own = BLE_MESH_ADDR_PUBLIC;
|
||||
#endif
|
||||
|
||||
channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
|
||||
adv_fil_pol = BLE_MESH_AP_SCAN_CONN_ALL;
|
||||
p_start_adv_cb = start_adv_completed_cb;
|
||||
|
||||
@@ -810,7 +885,7 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
|
||||
BLE_MESH_BTM_CHECK_STATUS(
|
||||
BTM_BleSetAdvParamsAll(interval, interval, adv_type,
|
||||
addr_type_own, &p_dir_bda,
|
||||
channel_map, adv_fil_pol, p_start_adv_cb));
|
||||
param->channel_map, adv_fil_pol, p_start_adv_cb));
|
||||
BLE_MESH_BTM_CHECK_STATUS(BTM_BleStartAdv());
|
||||
|
||||
#if BLE_MESH_DEV
|
||||
@@ -891,7 +966,7 @@ int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
|
||||
ext_adv_params.primary_phy = BLE_MESH_ADV_PHY_1M;
|
||||
ext_adv_params.secondary_phy = BLE_MESH_ADV_PHY_1M;
|
||||
ext_adv_params.filter_policy = BLE_MESH_AP_SCAN_CONN_ALL;
|
||||
ext_adv_params.channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
|
||||
ext_adv_params.channel_map = BLE_MESH_ADV_CHAN_37 | BLE_MESH_ADV_CHAN_38 | BLE_MESH_ADV_CHAN_39;
|
||||
|
||||
if (param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID ||
|
||||
param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID ||
|
||||
@@ -939,7 +1014,7 @@ int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
|
||||
}
|
||||
}
|
||||
|
||||
channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
|
||||
channel_map = BLE_MESH_ADV_CHAN_37 | BLE_MESH_ADV_CHAN_38 | BLE_MESH_ADV_CHAN_39;
|
||||
adv_fil_pol = BLE_MESH_AP_SCAN_CONN_ALL;
|
||||
if (param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID ||
|
||||
param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID ||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -56,13 +56,30 @@ static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration
|
||||
void *cb_data = BLE_MESH_ADV(buf)->cb_data;
|
||||
struct bt_mesh_adv_param param = {0};
|
||||
uint16_t duration = 0U, adv_int = 0U;
|
||||
uint8_t adv_cnt = 0;
|
||||
struct bt_mesh_adv_data ad = {0};
|
||||
int err = 0;
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
uint8_t is_ext_adv = false;
|
||||
#endif
|
||||
|
||||
BT_DBG("type %u len %u: %s", BLE_MESH_ADV(buf)->type,
|
||||
buf->len, bt_hex(buf->data, buf->len));
|
||||
buf->len, bt_hex(buf->data, buf->len));
|
||||
|
||||
switch (BLE_MESH_ADV(buf)->type) {
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
case BLE_MESH_ADV_EXT_PROV:
|
||||
case BLE_MESH_ADV_EXT_DATA:
|
||||
case BLE_MESH_ADV_EXT_RELAY_DATA:
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
case BLE_MESH_ADV_EXT_LONG_PROV:
|
||||
case BLE_MESH_ADV_EXT_LONG_DATA:
|
||||
case BLE_MESH_ADV_EXT_LONG_RELAY_DATA:
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
{
|
||||
is_ext_adv = true;
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
case BLE_MESH_ADV_PROV:
|
||||
case BLE_MESH_ADV_DATA:
|
||||
#if CONFIG_BLE_MESH_FRIEND
|
||||
@@ -76,14 +93,38 @@ static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration
|
||||
#endif
|
||||
case BLE_MESH_ADV_BEACON:
|
||||
case BLE_MESH_ADV_URI: {
|
||||
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);
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (is_ext_adv) {
|
||||
param.primary_phy = EXT_ADV(buf)->primary_phy;
|
||||
param.secondary_phy = EXT_ADV(buf)->secondary_phy;
|
||||
param.include_tx_power = EXT_ADV(buf)->include_tx_power;
|
||||
param.tx_power = EXT_ADV(buf)->tx_power;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
param.primary_phy = BLE_MESH_ADV_PRI_PHY_DEFAULT;
|
||||
param.secondary_phy = BLE_MESH_ADV_SEC_PHY_DEFAULT;
|
||||
param.include_tx_power = BLE_MESH_TX_POWER_INCLUDE_DEFAULT;
|
||||
param.tx_power = BLE_MESH_TX_POWER_DEFAULT;
|
||||
}
|
||||
|
||||
if (BLE_MESH_ADV(buf)->adv_itvl != BLE_MESH_ADV_ITVL_DEFAULT) {
|
||||
adv_int = MAX(ADV_ITVL_MIN, BLE_MESH_ADV(buf)->adv_itvl);
|
||||
} else {
|
||||
adv_int = MAX(ADV_ITVL_MIN,
|
||||
BLE_MESH_TRANSMIT_INT(BLE_MESH_ADV(buf)->xmit));
|
||||
}
|
||||
|
||||
if (BLE_MESH_ADV(buf)->adv_cnt != BLE_MESH_ADV_CNT_DEFAULT) {
|
||||
adv_cnt = BLE_MESH_ADV(buf)->adv_cnt;
|
||||
} else {
|
||||
adv_cnt = BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1;
|
||||
}
|
||||
|
||||
duration = adv_cnt * (adv_int + 10);
|
||||
|
||||
BT_DBG("count %u interval %ums duration %ums",
|
||||
BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1, adv_int,
|
||||
duration);
|
||||
adv_cnt, adv_int, duration);
|
||||
|
||||
ad.type = adv_type[BLE_MESH_ADV(buf)->type];
|
||||
ad.data_len = buf->len;
|
||||
@@ -94,10 +135,13 @@ static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration
|
||||
param.interval_max = param.interval_min;
|
||||
|
||||
param.adv_duration = duration;
|
||||
param.adv_count = BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1;
|
||||
param.adv_count = adv_cnt;
|
||||
|
||||
param.primary_phy = BLE_MESH_ADV_PHY_1M;
|
||||
param.secondary_phy = BLE_MESH_ADV_PHY_1M;
|
||||
if (BLE_MESH_ADV(buf)->channel_map) {
|
||||
param.channel_map = BLE_MESH_ADV(buf)->channel_map;
|
||||
} else {
|
||||
param.channel_map = BLE_MESH_ADV_CHAN_DEFAULT;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
|
||||
if (BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_PROXY_SOLIC) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -154,6 +154,49 @@ struct bt_mesh_elem {
|
||||
#define BLE_MESH_MODEL_ID_MBT_SRV 0x1400
|
||||
#define BLE_MESH_MODEL_ID_MBT_CLI 0x1401
|
||||
|
||||
typedef struct {
|
||||
uint32_t adv_itvl;
|
||||
uint8_t adv_cnt;
|
||||
uint8_t channel_map;
|
||||
} ble_mesh_adv_cfg_t;
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
typedef struct {
|
||||
uint8_t primary_phy;
|
||||
uint8_t secondary_phy;
|
||||
uint8_t include_tx_power:1;
|
||||
int8_t tx_power;
|
||||
} ble_mesh_ext_adv_cfg_t;
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
#define BLE_MESH_LONG_PACKET_FORCE (1)
|
||||
#define BLE_MESH_LONG_PACKET_PREFER (2)
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
|
||||
typedef struct {
|
||||
uint8_t adv_cfg_used : 1;
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
uint8_t ext_adv_cfg_used : 1;
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
uint8_t long_pkt_cfg_used : 1;
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
|
||||
ble_mesh_adv_cfg_t adv_cfg;
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
ble_mesh_ext_adv_cfg_t ext_adv_cfg;
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
/**
|
||||
* Long packets will be used for broadcasting
|
||||
* only if this flag is set and the traditional
|
||||
* packet length (380 bytes) cannot be used.
|
||||
*/
|
||||
uint8_t long_pkt_cfg : 2;
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
} bt_mesh_msg_enh_params_t;
|
||||
|
||||
/** Message sending context. */
|
||||
struct bt_mesh_msg_ctx {
|
||||
/** NetKey Index of the subnet to send the message on. */
|
||||
@@ -204,6 +247,8 @@ struct bt_mesh_msg_ctx {
|
||||
/** Change by Espressif, if the message is sent by a server
|
||||
* model. Not used for receiving message. */
|
||||
bool srv_send __attribute__((deprecated));
|
||||
|
||||
bt_mesh_msg_enh_params_t enh;
|
||||
};
|
||||
|
||||
struct bt_mesh_model_op {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA
|
||||
* SPDX-FileCopyrightText: 2015-2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -77,11 +77,17 @@ extern "C" {
|
||||
#endif
|
||||
#endif /* CONFIG_BT_NIMBLE_ENABLED */
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
#define BLE_MESH_GAP_ADV_MAX_LEN (2 + CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN)
|
||||
#else
|
||||
#define BLE_MESH_GAP_ADV_MAX_LEN 31
|
||||
#endif
|
||||
|
||||
#define BLE_MESH_GATT_DEF_MTU_SIZE 23
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
#define BLE_MESH_TX_POWER_INCLUDE_DEFAULT false
|
||||
#define BLE_MESH_TX_POWER_DEFAULT 0x7f
|
||||
#define BLE_MESH_ADV_PHY_UNASSIGNED 0
|
||||
#define BLE_MESH_ADV_PHY_1M 1
|
||||
#define BLE_MESH_ADV_PHY_2M 2
|
||||
@@ -91,6 +97,8 @@ extern "C" {
|
||||
#define BLE_MESH_ADV_PHY_OPTION_PREFER_S8 2
|
||||
#define BLE_MESH_ADV_PHY_OPTION_REQUIRE_S2 3
|
||||
#define BLE_MESH_ADV_PHY_OPTION_REQUIRE_S8 4
|
||||
#define BLE_MESH_ADV_PRI_PHY_DEFAULT BLE_MESH_ADV_PHY_1M
|
||||
#define BLE_MESH_ADV_SEC_PHY_DEFAULT BLE_MESH_ADV_PHY_1M
|
||||
#endif
|
||||
|
||||
/* BD ADDR types */
|
||||
@@ -112,6 +120,9 @@ extern "C" {
|
||||
#define BLE_MESH_ADV_SCAN_RSP 0x04
|
||||
#else
|
||||
/* Bluetooth Core Spec 6.0, Vol 4, Part E, 7.7.65.13 */
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
#define BLE_MESH_EXT_ADV_NONCONN_IND (0)
|
||||
#endif
|
||||
#define BLE_MESH_ADV_IND (0x13)
|
||||
#define BLE_MESH_ADV_DIRECT_IND (0x15)
|
||||
#define BLE_MESH_ADV_SCAN_IND (0x12)
|
||||
@@ -120,10 +131,15 @@ extern "C" {
|
||||
#define BLE_MESH_ADV_SCAN_RSP (0x1b)
|
||||
#endif
|
||||
|
||||
#define BLE_MESH_ADV_ITVL_DEFAULT (0)
|
||||
#define BLE_MESH_ADV_CNT_DEFAULT (0)
|
||||
|
||||
/* advertising channel map */
|
||||
#define BLE_MESH_ADV_CHNL_37 BIT(0)
|
||||
#define BLE_MESH_ADV_CHNL_38 BIT(1)
|
||||
#define BLE_MESH_ADV_CHNL_39 BIT(2)
|
||||
#define BLE_MESH_ADV_CHAN_UNASSIGNED (0)
|
||||
#define BLE_MESH_ADV_CHAN_37 BIT(0)
|
||||
#define BLE_MESH_ADV_CHAN_38 BIT(1)
|
||||
#define BLE_MESH_ADV_CHAN_39 BIT(2)
|
||||
#define BLE_MESH_ADV_CHAN_DEFAULT (BLE_MESH_ADV_CHAN_39|BLE_MESH_ADV_CHAN_38|BLE_MESH_ADV_CHAN_37)
|
||||
|
||||
/* Advertising filter policy */
|
||||
#define BLE_MESH_AP_SCAN_CONN_ALL 0x00
|
||||
@@ -472,6 +488,8 @@ struct bt_mesh_adv_param {
|
||||
/** Maximum Advertising Interval (N * 0.625) */
|
||||
uint16_t interval_max;
|
||||
|
||||
uint8_t channel_map;
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
/** Maximum Advertising Duration (N * 0.625) */
|
||||
uint16_t adv_duration;
|
||||
@@ -484,6 +502,10 @@ struct bt_mesh_adv_param {
|
||||
|
||||
/** Advertising Secondary PHY */
|
||||
uint8_t secondary_phy;
|
||||
|
||||
int8_t tx_power;
|
||||
|
||||
uint8_t include_tx_power : 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -577,6 +599,8 @@ struct bt_mesh_adv_report {
|
||||
|
||||
/* Secondary advertising PHY */
|
||||
uint8_t secondary_phy;
|
||||
|
||||
uint8_t tx_power;
|
||||
#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||
};
|
||||
|
||||
|
||||
@@ -112,7 +112,11 @@ struct bt_mesh_hci_cp_set_adv_param {
|
||||
#define BLE_MESH_HCI_OP_SET_ADV_DATA BLE_MESH_OP(BLE_MESH_OGF_LE, 0x0008)
|
||||
struct bt_mesh_hci_cp_set_adv_data {
|
||||
uint8_t len;
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
uint8_t data[2 + CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN];
|
||||
#else
|
||||
uint8_t data[31];
|
||||
#endif
|
||||
} __attribute__((packed));
|
||||
|
||||
#define BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA BLE_MESH_OP(BLE_MESH_OGF_LE, 0x0009)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "fast_prov.h"
|
||||
#include "prov_node.h"
|
||||
#include "test.h"
|
||||
#include "fast_prov.h"
|
||||
#include "proxy_client.h"
|
||||
#include "proxy_server.h"
|
||||
#include "pvnr_mgmt.h"
|
||||
@@ -1674,7 +1673,27 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
|
||||
*/
|
||||
|
||||
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
|
||||
buf = bt_mesh_adv_create(BLE_MESH_ADV_DATA, K_NO_WAIT);
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (rx->ctx.enh.ext_adv_cfg_used) {
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (rx->ctx.enh.long_pkt_cfg) {
|
||||
buf = bt_mesh_adv_create(BLE_MESH_ADV_EXT_LONG_RELAY_DATA, K_NO_WAIT);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
buf = bt_mesh_adv_create(BLE_MESH_ADV_EXT_DATA, K_NO_WAIT);
|
||||
}
|
||||
if (buf) {
|
||||
EXT_ADV(buf)->primary_phy = rx->ctx.enh.ext_adv_cfg.primary_phy;
|
||||
EXT_ADV(buf)->secondary_phy = rx->ctx.enh.ext_adv_cfg.secondary_phy;
|
||||
EXT_ADV(buf)->include_tx_power = rx->ctx.enh.ext_adv_cfg.include_tx_power;
|
||||
EXT_ADV(buf)->tx_power = rx->ctx.enh.ext_adv_cfg.tx_power;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
buf = bt_mesh_adv_create(BLE_MESH_ADV_DATA, K_NO_WAIT);
|
||||
}
|
||||
#else
|
||||
/* Check if the number of relay packets in queue is too large, if so
|
||||
* use minimum relay retransmit value for later relay packets.
|
||||
@@ -1682,7 +1701,27 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
|
||||
if (bt_mesh_get_stored_relay_count() >= BLE_MESH_MAX_STORED_RELAY_COUNT) {
|
||||
xmit = BLE_MESH_TRANSMIT(0, 20);
|
||||
}
|
||||
buf = bt_mesh_relay_adv_create(BLE_MESH_ADV_RELAY_DATA, K_NO_WAIT);
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (rx->ctx.enh.ext_adv_cfg_used) {
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (rx->ctx.enh.long_pkt_cfg) {
|
||||
buf = bt_mesh_adv_create(BLE_MESH_ADV_EXT_LONG_RELAY_DATA, K_NO_WAIT);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
buf = bt_mesh_adv_create(BLE_MESH_ADV_EXT_DATA, K_NO_WAIT);
|
||||
}
|
||||
if (buf) {
|
||||
EXT_ADV(buf)->primary_phy = rx->ctx.enh.ext_adv_cfg.primary_phy;
|
||||
EXT_ADV(buf)->secondary_phy = rx->ctx.enh.ext_adv_cfg.secondary_phy;
|
||||
EXT_ADV(buf)->include_tx_power = rx->ctx.enh.ext_adv_cfg.include_tx_power;
|
||||
EXT_ADV(buf)->tx_power = rx->ctx.enh.ext_adv_cfg.tx_power;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
buf = bt_mesh_relay_adv_create(BLE_MESH_ADV_RELAY_DATA, K_NO_WAIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!buf) {
|
||||
@@ -1922,33 +1961,42 @@ void bt_mesh_generic_net_recv(struct net_buf_simple *data,
|
||||
struct bt_mesh_net_rx *rx,
|
||||
enum bt_mesh_net_if net_if)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(buf, 29);
|
||||
struct net_buf_simple_state state = {0};
|
||||
struct net_buf_simple *buf = NULL;
|
||||
|
||||
assert(rx);
|
||||
|
||||
BT_DBG("rssi %d net_if %u", rx->ctx.recv_rssi, net_if);
|
||||
if (data->len > (BLE_MESH_GAP_ADV_MAX_LEN - 2)) {
|
||||
BT_ERR("Invalid net message length %d", data->len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ready_to_recv()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bt_mesh_net_decode(data, net_if, rx, &buf)) {
|
||||
buf = bt_mesh_alloc_buf(data->len);
|
||||
if (!buf) {
|
||||
BT_ERR("Alloc net msg buffer failed");
|
||||
return;
|
||||
}
|
||||
|
||||
BT_DBG("rssi %d net_if %u", rx->ctx.recv_rssi, net_if);
|
||||
|
||||
if (bt_mesh_net_decode(data, net_if, rx, buf)) {
|
||||
goto free_net_msg_buf;
|
||||
}
|
||||
|
||||
if (ignore_net_msg(rx->ctx.addr, rx->ctx.recv_dst)) {
|
||||
return;
|
||||
goto free_net_msg_buf;
|
||||
}
|
||||
|
||||
/* Save the state so the buffer can later be relayed */
|
||||
net_buf_simple_save(&buf, &state);
|
||||
net_buf_simple_save(buf, &state);
|
||||
|
||||
BT_BQB(BLE_MESH_BQB_TEST_LOG_LEVEL_PRIMARY_ID_NODE | \
|
||||
BLE_MESH_BQB_TEST_LOG_LEVEL_SUB_ID_NET,
|
||||
"\nNetRecv: ctl: %d, src: %d, dst: %d, ttl: %d, data: 0x%s",
|
||||
rx->ctl, rx->ctx.addr, rx->ctx.recv_dst, rx->ctx.recv_ttl,
|
||||
bt_hex(buf.data + BLE_MESH_NET_HDR_LEN, buf.len - BLE_MESH_NET_HDR_LEN));
|
||||
bt_hex(buf->data + BLE_MESH_NET_HDR_LEN, buf->len - BLE_MESH_NET_HDR_LEN));
|
||||
|
||||
/* If trying to handle a message with DST set to all-directed-forwarding-nodes,
|
||||
* we need to make sure the directed forwarding functionality is enabled in the
|
||||
@@ -1958,6 +2006,15 @@ void bt_mesh_generic_net_recv(struct net_buf_simple *data,
|
||||
bt_mesh_fixed_direct_match(rx->sub, rx->ctx.recv_dst) ||
|
||||
bt_mesh_elem_find(rx->ctx.recv_dst));
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
/* It should be noted that if the length of buf
|
||||
* is less than or equal to 29, it still may be the
|
||||
* last segment for a long packet, But if the bit
|
||||
* is set, it must be part of the long packet*/
|
||||
rx->ctx.enh.long_pkt_cfg_used = (buf->len >= 29);
|
||||
rx->ctx.enh.long_pkt_cfg = BLE_MESH_LONG_PACKET_FORCE;
|
||||
#endif
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
|
||||
#if CONFIG_BLE_MESH_PRB_SRV
|
||||
bt_mesh_private_gatt_proxy_state_get() != BLE_MESH_PRIVATE_GATT_PROXY_ENABLED &&
|
||||
@@ -1968,7 +2025,7 @@ void bt_mesh_generic_net_recv(struct net_buf_simple *data,
|
||||
if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_DISABLED &&
|
||||
!rx->local_match) {
|
||||
BT_INFO("Proxy is disabled; ignoring message");
|
||||
return;
|
||||
goto free_net_msg_buf;
|
||||
}
|
||||
|
||||
/* If the Directed Proxy Server receives a valid Network PDU from the Directed
|
||||
@@ -1995,7 +2052,7 @@ void bt_mesh_generic_net_recv(struct net_buf_simple *data,
|
||||
* credentials. Remove it from the message cache so that we accept
|
||||
* it again in the future.
|
||||
*/
|
||||
if (bt_mesh_trans_recv(&buf, rx) == -EAGAIN) {
|
||||
if (bt_mesh_trans_recv(buf, rx) == -EAGAIN) {
|
||||
BT_WARN("Removing rejected message from Network Message Cache");
|
||||
msg_cache[rx->msg_cache_idx].src = BLE_MESH_ADDR_UNASSIGNED;
|
||||
/* Rewind the next index now that we're not using this entry */
|
||||
@@ -2011,9 +2068,12 @@ void bt_mesh_generic_net_recv(struct net_buf_simple *data,
|
||||
&& !rx->replay_msg
|
||||
#endif
|
||||
)) {
|
||||
net_buf_simple_restore(&buf, &state);
|
||||
bt_mesh_net_relay(&buf, rx);
|
||||
net_buf_simple_restore(buf, &state);
|
||||
bt_mesh_net_relay(buf, rx);
|
||||
}
|
||||
|
||||
free_net_msg_buf:
|
||||
bt_mesh_free(buf);
|
||||
}
|
||||
|
||||
static void ivu_refresh(struct k_work *work)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -473,6 +473,14 @@ static inline void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
|
||||
enum bt_mesh_net_if net_if)
|
||||
{
|
||||
struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi };
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
rx.ctx.enh.adv_cfg_used = false;
|
||||
rx.ctx.enh.ext_adv_cfg_used = false;
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
rx.ctx.enh.long_pkt_cfg_used = (data->len >= 29);
|
||||
rx.ctx.enh.long_pkt_cfg = BLE_MESH_LONG_PACKET_FORCE;
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
bt_mesh_generic_net_recv(data, &rx, net_if);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA
|
||||
* SPDX-FileCopyrightText: 2015-2016 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -494,6 +494,14 @@ void bt_mesh_ble_ext_adv_report(struct ble_gap_ext_disc_desc *desc)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
static struct {
|
||||
struct bt_mesh_adv_report adv_rpt;
|
||||
uint8_t adv_data_len;
|
||||
uint8_t adv_data[2 + CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN];
|
||||
} adv_report_cache;
|
||||
#endif
|
||||
|
||||
int disc_cb(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
@@ -517,29 +525,84 @@ int disc_cb(struct ble_gap_event *event, void *arg)
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
case BLE_GAP_EVENT_EXT_DISC: {
|
||||
struct bt_mesh_adv_report adv_rpt = {0};
|
||||
uint8_t *adv_data = NULL;
|
||||
uint8_t adv_data_len = 0;
|
||||
|
||||
desc = &event->ext_disc;
|
||||
|
||||
if (desc->length_data > BLE_MESH_GAP_ADV_MAX_LEN) {
|
||||
/* @todo: bt_mesh_ble_ext_adv_report and transfer
|
||||
* to user have functional duplication */
|
||||
goto report_to_user;
|
||||
}
|
||||
memcpy(&adv_rpt.addr, &desc->addr, sizeof(bt_mesh_addr_t));
|
||||
adv_rpt.rssi = desc->rssi;
|
||||
adv_rpt.adv_type = desc->props;
|
||||
adv_rpt.primary_phy = desc->prim_phy;
|
||||
adv_rpt.secondary_phy = desc->sec_phy;
|
||||
adv_rpt.tx_power = desc->tx_power;
|
||||
adv_data = (uint8_t *)desc->data;
|
||||
adv_data_len = desc->length_data;
|
||||
|
||||
net_buf_simple_init_with_data(&adv_rpt.adv_data, (void *)desc->data, desc->length_data);
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
switch (desc->data_status) {
|
||||
case BLE_GAP_EXT_ADV_DATA_STATUS_COMPLETE:
|
||||
if (adv_report_cache.adv_data_len) {
|
||||
memcpy(adv_report_cache.adv_data + adv_report_cache.adv_data_len,
|
||||
desc->data, desc->length_data);
|
||||
adv_report_cache.adv_data_len += desc->length_data;
|
||||
adv_data = adv_report_cache.adv_data;
|
||||
adv_data_len = adv_report_cache.adv_data_len;
|
||||
adv_report_cache.adv_data_len = 0;
|
||||
}
|
||||
break;
|
||||
case BLE_GAP_EXT_ADV_DATA_STATUS_INCOMPLETE:
|
||||
if ((adv_report_cache.adv_data_len + desc->length_data) > BLE_MESH_GAP_ADV_MAX_LEN) {
|
||||
adv_report_cache.adv_data_len = 0;
|
||||
return false;
|
||||
}
|
||||
if (adv_report_cache.adv_data_len == 0) {
|
||||
memcpy(&adv_report_cache.adv_rpt, &adv_rpt, sizeof(struct bt_mesh_adv_report));
|
||||
}
|
||||
memcpy(adv_report_cache.adv_data + adv_report_cache.adv_data_len,
|
||||
desc->data, desc->length_data);
|
||||
adv_report_cache.adv_data_len += desc->length_data;
|
||||
/* To avoid discarding user's packets,
|
||||
* it is assumed here that this packet
|
||||
* is not mesh's packet */
|
||||
goto report_to_user;
|
||||
case BLE_GAP_EXT_ADV_DATA_STATUS_TRUNCATED:
|
||||
if (adv_report_cache.adv_data_len) {
|
||||
memset(&adv_report_cache, 0, sizeof(adv_report_cache));
|
||||
}
|
||||
goto report_to_user;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
#else /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
if (desc->data_status != BLE_GAP_EXT_ADV_DATA_STATUS_COMPLETE) {
|
||||
goto report_to_user;
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
|
||||
net_buf_simple_init_with_data(&adv_rpt.adv_data, (void *)adv_data, adv_data_len);
|
||||
|
||||
if (bt_mesh_scan_dev_found_cb) {
|
||||
/* TODO: Support Scan Response data length for NimBLE host */
|
||||
if (desc->props & BLE_HCI_ADV_LEGACY_MASK) {
|
||||
if (desc->props & BLE_HCI_ADV_LEGACY_MASK ||
|
||||
(IS_ENABLED(CONFIG_BLE_MESH_EXT_ADV) &&
|
||||
desc->props == BLE_MESH_EXT_ADV_NONCONN_IND)) {
|
||||
bt_mesh_scan_dev_found_cb(&adv_rpt);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mesh didn't process that data */
|
||||
if (adv_rpt.adv_data.len == desc->length_data) {
|
||||
bt_mesh_ble_ext_adv_report(desc);
|
||||
if (adv_rpt.adv_data.len == adv_data_len) {
|
||||
goto report_to_user;
|
||||
}
|
||||
break;
|
||||
|
||||
report_to_user:
|
||||
bt_mesh_ble_ext_adv_report(desc);
|
||||
break;
|
||||
}
|
||||
#else /* CONFIG_BLE_MESH_USE_BLE_50 */
|
||||
@@ -1101,6 +1164,11 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
|
||||
#endif /* CONFIG_BLE_MESH_NODE */
|
||||
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
static struct {
|
||||
bool set;
|
||||
struct ble_gap_ext_adv_params param;
|
||||
} last_param[BLE_MESH_ADV_INS_TYPES_NUM];
|
||||
|
||||
int bt_le_ext_adv_start(const uint8_t inst_id,
|
||||
const struct bt_mesh_adv_param *param,
|
||||
const struct bt_mesh_adv_data *ad, size_t ad_len,
|
||||
@@ -1125,7 +1193,7 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
|
||||
return -EALREADY;
|
||||
}
|
||||
#endif
|
||||
buf = bt_mesh_calloc(ad_len * BLE_HS_ADV_MAX_SZ);
|
||||
buf = bt_mesh_calloc(ad_len * BLE_MESH_GAP_ADV_MAX_LEN);
|
||||
if (!buf) {
|
||||
BT_ERR("ad buffer alloc failed");
|
||||
return -ENOMEM;
|
||||
@@ -1201,16 +1269,19 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
|
||||
adv_params.legacy_pdu = true;
|
||||
} else {
|
||||
if (param->primary_phy == BLE_MESH_ADV_PHY_1M &&
|
||||
param->secondary_phy == BLE_MESH_ADV_PHY_1M) {
|
||||
adv_params.legacy_pdu = true;
|
||||
param->secondary_phy == BLE_MESH_ADV_PHY_1M &&
|
||||
param->include_tx_power == false &&
|
||||
ad->data_len <= 29) {
|
||||
adv_params.legacy_pdu = true;
|
||||
}
|
||||
}
|
||||
|
||||
adv_params.sid = inst_id;
|
||||
adv_params.primary_phy = param->primary_phy;
|
||||
adv_params.secondary_phy = param->secondary_phy;
|
||||
adv_params.tx_power = 0x7F; // tx power will be selected by controller
|
||||
adv_params.tx_power = param->tx_power;
|
||||
adv_params.own_addr_type = BLE_OWN_ADDR_PUBLIC;
|
||||
adv_params.include_tx_power = param->include_tx_power;
|
||||
|
||||
interval = param->interval_min;
|
||||
|
||||
@@ -1230,10 +1301,23 @@ int bt_le_ext_adv_start(const uint8_t inst_id,
|
||||
adv_params.itvl_min = interval;
|
||||
adv_params.itvl_max = interval;
|
||||
|
||||
err = ble_gap_ext_adv_configure(inst_id, &adv_params, NULL, gap_event_cb, NULL);
|
||||
if (err != 0) {
|
||||
BT_ERR("Advertising config failed: err %d", err);
|
||||
return err;
|
||||
if (memcmp(&adv_params, &last_param[inst_id].param,
|
||||
sizeof(struct ble_gap_ext_adv_params))) {
|
||||
if (last_param[inst_id].set) {
|
||||
err = ble_gap_ext_adv_remove(inst_id);
|
||||
if (err != 0 && err != BLE_HS_EALREADY) {
|
||||
BT_ERR("Advertising rm failed: err %d", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
last_param[inst_id].set = true;
|
||||
err = ble_gap_ext_adv_configure(inst_id, &adv_params, NULL, gap_event_cb, NULL);
|
||||
if (err != 0) {
|
||||
BT_ERR("Advertising config failed: err %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
memcpy(&last_param[inst_id].param, &adv_params, sizeof(struct ble_gap_ext_adv_params));
|
||||
}
|
||||
|
||||
err = ble_gap_ext_adv_set_data(inst_id, data);
|
||||
@@ -1358,6 +1442,7 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
|
||||
|
||||
adv_params.itvl_min = interval;
|
||||
adv_params.itvl_max = interval;
|
||||
adv_params.channel_map = param->channel_map;
|
||||
|
||||
again:
|
||||
err = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params,
|
||||
@@ -1460,7 +1545,7 @@ int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
|
||||
|
||||
adv_params.itvl_min = param->interval;
|
||||
adv_params.itvl_max = param->interval;
|
||||
adv_params.channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
|
||||
adv_params.channel_map = BLE_MESH_ADV_CHAN_37 | BLE_MESH_ADV_CHAN_38 | BLE_MESH_ADV_CHAN_39;
|
||||
adv_params.filter_policy = BLE_MESH_AP_SCAN_CONN_ALL;
|
||||
adv_params.primary_phy = BLE_MESH_ADV_PHY_1M;
|
||||
adv_params.secondary_phy = BLE_MESH_ADV_PHY_1M;
|
||||
@@ -1581,7 +1666,7 @@ int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
|
||||
}
|
||||
adv_params.itvl_min = param->interval;
|
||||
adv_params.itvl_max = param->interval;
|
||||
adv_params.channel_map = BLE_MESH_ADV_CHNL_37 | BLE_MESH_ADV_CHNL_38 | BLE_MESH_ADV_CHNL_39;
|
||||
adv_params.channel_map = BLE_MESH_ADV_CHAN_37 | BLE_MESH_ADV_CHAN_38 | BLE_MESH_ADV_CHAN_39;
|
||||
adv_params.filter_policy = BLE_MESH_AP_SCAN_CONN_ALL;
|
||||
adv_params.high_duty_cycle = (param->adv_type == BLE_MESH_ADV_DIRECT_IND) ? true : false;
|
||||
|
||||
|
||||
@@ -56,11 +56,14 @@ static const struct bt_mesh_adv_param slow_adv_param = {
|
||||
.options = ADV_OPT,
|
||||
.interval_min = BLE_MESH_GAP_ADV_SLOW_INT_MIN,
|
||||
.interval_max = BLE_MESH_GAP_ADV_SLOW_INT_MAX,
|
||||
.channel_map = BLE_MESH_ADV_CHAN_DEFAULT,
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
.primary_phy = BLE_MESH_ADV_PHY_1M,
|
||||
.secondary_phy = BLE_MESH_ADV_PHY_1M,
|
||||
.adv_duration = 0,
|
||||
.adv_count = 0,
|
||||
.tx_power = 0x7f,
|
||||
.include_tx_power = false,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -68,11 +71,14 @@ static const struct bt_mesh_adv_param fast_adv_param = {
|
||||
.options = ADV_OPT,
|
||||
.interval_min = BLE_MESH_GAP_ADV_FAST_INT_MIN_0,
|
||||
.interval_max = BLE_MESH_GAP_ADV_FAST_INT_MAX_0,
|
||||
.channel_map = BLE_MESH_ADV_CHAN_DEFAULT,
|
||||
#if CONFIG_BLE_MESH_USE_BLE_50
|
||||
.primary_phy = BLE_MESH_ADV_PHY_1M,
|
||||
.secondary_phy = BLE_MESH_ADV_PHY_1M,
|
||||
.adv_duration = 0,
|
||||
.adv_count = 0,
|
||||
.tx_power = 0x7f,
|
||||
.include_tx_power = false,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -424,7 +424,11 @@ static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
|
||||
|
||||
net_buf_simple_save(buf, &buf_state);
|
||||
|
||||
if (adv_rpt->adv_type != BLE_MESH_ADV_NONCONN_IND &&
|
||||
if (
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
adv_rpt->adv_type != 0 &&
|
||||
#endif
|
||||
adv_rpt->adv_type != BLE_MESH_ADV_NONCONN_IND &&
|
||||
adv_rpt->adv_type != BLE_MESH_ADV_IND
|
||||
#if CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
|
||||
&& adv_rpt->adv_type != BLE_MESH_ADV_SCAN_RSP
|
||||
@@ -490,7 +494,11 @@ static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
|
||||
buf->len = len - 1;
|
||||
|
||||
if ((type == BLE_MESH_DATA_MESH_PROV || type == BLE_MESH_DATA_MESH_MESSAGE ||
|
||||
type == BLE_MESH_DATA_MESH_BEACON) && (adv_rpt->adv_type != BLE_MESH_ADV_NONCONN_IND)) {
|
||||
type == BLE_MESH_DATA_MESH_BEACON) && (adv_rpt->adv_type != BLE_MESH_ADV_NONCONN_IND
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
&& adv_rpt->adv_type != BLE_MESH_EXT_ADV_NONCONN_IND
|
||||
#endif
|
||||
)) {
|
||||
BT_DBG("Ignore mesh packet (type 0x%02x) with adv_type 0x%02x", type, adv_rpt->adv_type);
|
||||
return;
|
||||
}
|
||||
@@ -500,6 +508,19 @@ static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
|
||||
struct bt_mesh_net_rx rx = {
|
||||
.ctx.recv_rssi = adv_rpt->rssi,
|
||||
};
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (adv_rpt->adv_type == BLE_MESH_EXT_ADV_NONCONN_IND) {
|
||||
rx.ctx.enh.ext_adv_cfg_used = true;
|
||||
rx.ctx.enh.ext_adv_cfg.primary_phy = adv_rpt->primary_phy;
|
||||
rx.ctx.enh.ext_adv_cfg.secondary_phy = adv_rpt->secondary_phy;
|
||||
if (adv_rpt->tx_power == 0x7f) {
|
||||
rx.ctx.enh.ext_adv_cfg.include_tx_power = false;
|
||||
} else {
|
||||
rx.ctx.enh.ext_adv_cfg.include_tx_power = true;
|
||||
}
|
||||
rx.ctx.enh.ext_adv_cfg.tx_power = adv_rpt->tx_power;
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
bt_mesh_generic_net_recv(buf, &rx, BLE_MESH_NET_IF_ADV);
|
||||
break;
|
||||
#if CONFIG_BLE_MESH_PB_ADV
|
||||
|
||||
@@ -77,8 +77,16 @@ _Static_assert(CONFIG_BLE_MESH_ADV_BUF_COUNT >= (CONFIG_BLE_MESH_TX_SEG_MAX + 3)
|
||||
/* How long to wait for available buffers before giving up */
|
||||
#define BUF_TIMEOUT K_NO_WAIT
|
||||
|
||||
struct seg_info {
|
||||
uint8_t ctl:1; /* Control message */
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
uint8_t long_pkt:1; /* Long packet */
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct seg_tx {
|
||||
struct bt_mesh_subnet *sub;
|
||||
// @todo: select the max one between large seg max and normal seg max
|
||||
struct net_buf *seg[CONFIG_BLE_MESH_TX_SEG_MAX];
|
||||
uint64_t seq_auth;
|
||||
uint16_t dst;
|
||||
@@ -100,10 +108,11 @@ static struct seg_tx {
|
||||
static struct seg_rx {
|
||||
struct bt_mesh_subnet *sub;
|
||||
uint64_t seq_auth;
|
||||
uint8_t seg_n:5,
|
||||
uint16_t seg_n:5,
|
||||
ctl:1,
|
||||
in_use:1,
|
||||
obo:1;
|
||||
obo:1,
|
||||
ext:1;
|
||||
uint8_t hdr;
|
||||
uint8_t ttl;
|
||||
uint16_t src;
|
||||
@@ -112,14 +121,20 @@ static struct seg_rx {
|
||||
uint32_t last;
|
||||
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)] = {
|
||||
.buf.size = CONFIG_BLE_MESH_RX_SDU_MAX,
|
||||
},
|
||||
};
|
||||
} seg_rx[CONFIG_BLE_MESH_RX_SEG_MSG_COUNT];
|
||||
|
||||
static uint8_t seg_rx_buf_data[(CONFIG_BLE_MESH_RX_SEG_MSG_COUNT *
|
||||
CONFIG_BLE_MESH_RX_SDU_MAX)];
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
/* @todo: could merge ext_seg_rx into seg_rx */
|
||||
static struct seg_rx ext_seg_rx[CONFIG_BLE_MESH_LONG_PACKET_RX_SEG_CNT];
|
||||
static uint8_t ext_seg_rx_buf_data[(CONFIG_BLE_MESH_LONG_PACKET_RX_SEG_CNT *
|
||||
BLE_MESH_EXT_RX_SDU_MAX)];
|
||||
#endif
|
||||
|
||||
static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx,
|
||||
const uint8_t *hdr, const uint64_t *seq_auth,
|
||||
uint8_t seg_n);
|
||||
|
||||
static bt_mesh_mutex_t seg_rx_lock;
|
||||
|
||||
@@ -236,15 +251,47 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu,
|
||||
{
|
||||
struct net_buf *buf = NULL;
|
||||
|
||||
enum bt_mesh_adv_type adv_type = BLE_MESH_ADV_DATA;
|
||||
BT_DBG("src 0x%04x dst 0x%04x app_idx 0x%04x sdu_len %u",
|
||||
tx->src, tx->ctx->addr, tx->ctx->app_idx, sdu->len);
|
||||
|
||||
buf = bt_mesh_adv_create(BLE_MESH_ADV_DATA, BUF_TIMEOUT);
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (tx->ctx->enh.long_pkt_cfg_used &&
|
||||
(tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_FORCE ||
|
||||
(tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_PREFER &&
|
||||
sdu->len > (BLE_MESH_SDU_UNSEG_MAX + 4)))) {
|
||||
adv_type = BLE_MESH_ADV_EXT_LONG_DATA;
|
||||
} else
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
{
|
||||
if (tx->ctx->enh.ext_adv_cfg_used) {
|
||||
adv_type = BLE_MESH_ADV_EXT_DATA;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
|
||||
buf = bt_mesh_adv_create(adv_type, BUF_TIMEOUT);
|
||||
if (!buf) {
|
||||
BT_ERR("Out of network buffers");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
if (tx->ctx->enh.adv_cfg_used) {
|
||||
BLE_MESH_ADV(buf)->channel_map = tx->ctx->enh.adv_cfg.channel_map;
|
||||
BLE_MESH_ADV(buf)->adv_cnt = tx->ctx->enh.adv_cfg.adv_cnt;
|
||||
BLE_MESH_ADV(buf)->adv_itvl = tx->ctx->enh.adv_cfg.adv_itvl;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (tx->ctx->enh.ext_adv_cfg_used) {
|
||||
EXT_ADV(buf)->primary_phy = tx->ctx->enh.ext_adv_cfg.primary_phy;
|
||||
EXT_ADV(buf)->secondary_phy = tx->ctx->enh.ext_adv_cfg.secondary_phy;
|
||||
EXT_ADV(buf)->include_tx_power = tx->ctx->enh.ext_adv_cfg.include_tx_power;
|
||||
EXT_ADV(buf)->tx_power = tx->ctx->enh.ext_adv_cfg.tx_power;
|
||||
}
|
||||
#endif
|
||||
|
||||
net_buf_reserve(buf, BLE_MESH_NET_HDR_LEN);
|
||||
|
||||
if (ctl_op) {
|
||||
@@ -287,13 +334,21 @@ send:
|
||||
return bt_mesh_net_send(tx, buf, cb, cb_data);
|
||||
}
|
||||
|
||||
static inline uint8_t seg_len(bool ctl)
|
||||
static inline uint8_t seg_len(struct seg_info *si)
|
||||
{
|
||||
if (ctl) {
|
||||
return BLE_MESH_CTL_SEG_SDU_MAX;
|
||||
if (si->ctl) {
|
||||
return
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
si->long_pkt ? BLE_MESH_EXT_CTL_SEG_SDU_MAX :
|
||||
#endif
|
||||
BLE_MESH_CTL_SEG_SDU_MAX;
|
||||
}
|
||||
|
||||
return BLE_MESH_APP_SEG_SDU_MAX;
|
||||
return
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
si->long_pkt ? BLE_MESH_EXT_APP_SEG_SDU_MAX :
|
||||
#endif
|
||||
BLE_MESH_APP_SEG_SDU_MAX;
|
||||
}
|
||||
|
||||
bool bt_mesh_tx_in_progress(void)
|
||||
@@ -311,7 +366,14 @@ bool bt_mesh_tx_in_progress(void)
|
||||
|
||||
static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx)
|
||||
{
|
||||
bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 3U, BLE_MESH_BUF_REF_SMALL);
|
||||
/* If the data is sent to itself, then last seg's ref count be equal to 3 */
|
||||
if (((IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) ||
|
||||
(IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en())) &&
|
||||
(bt_mesh_fixed_group_match(tx->dst) || bt_mesh_elem_find(tx->dst))) {
|
||||
bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 4U, BLE_MESH_BUF_REF_SMALL);
|
||||
} else {
|
||||
bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 3U, BLE_MESH_BUF_REF_SMALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* When cancelling a segment that is still in the adv sending queue, `tx->seg_pending`
|
||||
@@ -512,7 +574,9 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
||||
const struct bt_mesh_send_cb *cb, void *cb_data,
|
||||
const uint8_t *ctl_op)
|
||||
{
|
||||
enum bt_mesh_adv_type adv_type = BLE_MESH_ADV_DATA;
|
||||
struct seg_tx *tx = NULL;
|
||||
struct seg_info si = {0};
|
||||
uint16_t seq_zero = 0U;
|
||||
uint8_t seg_hdr = 0U;
|
||||
uint8_t seg_o = 0U;
|
||||
@@ -544,16 +608,28 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
||||
}
|
||||
|
||||
if (ctl_op) {
|
||||
si.ctl = 1;
|
||||
seg_hdr = TRANS_CTL_HDR(*ctl_op, 1);
|
||||
} else if (net_tx->ctx->app_idx == BLE_MESH_KEY_DEV) {
|
||||
si.ctl = 0;
|
||||
seg_hdr = SEG_HDR(0, 0);
|
||||
} else {
|
||||
si.ctl = 0;
|
||||
seg_hdr = SEG_HDR(1, net_tx->aid);
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (net_tx->ctx->enh.long_pkt_cfg_used &&
|
||||
(net_tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_FORCE ||
|
||||
(net_tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_PREFER &&
|
||||
sdu->len > BLE_MESH_TX_SDU_MAX))) {
|
||||
si.long_pkt = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
tx->dst = net_tx->ctx->addr;
|
||||
if (sdu->len) {
|
||||
tx->seg_n = (sdu->len - 1) / seg_len(!!ctl_op);
|
||||
tx->seg_n = (sdu->len - 1) / seg_len(&si);
|
||||
} else {
|
||||
tx->seg_n = 0;
|
||||
}
|
||||
@@ -594,14 +670,43 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
||||
for (seg_o = 0U; sdu->len; seg_o++) {
|
||||
struct net_buf *seg = NULL;
|
||||
uint16_t len = 0U;
|
||||
|
||||
seg = bt_mesh_adv_create(BLE_MESH_ADV_DATA, BUF_TIMEOUT);
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (si.long_pkt) {
|
||||
adv_type = BLE_MESH_ADV_EXT_LONG_DATA;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (net_tx->ctx->enh.ext_adv_cfg_used) {
|
||||
adv_type = BLE_MESH_ADV_EXT_DATA;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
adv_type = BLE_MESH_ADV_DATA;
|
||||
}
|
||||
}
|
||||
seg = bt_mesh_adv_create(adv_type, BUF_TIMEOUT);
|
||||
if (!seg) {
|
||||
BT_ERR("Out of segment buffers");
|
||||
err = -ENOBUFS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (net_tx->ctx->enh.adv_cfg_used) {
|
||||
BLE_MESH_ADV(seg)->channel_map = net_tx->ctx->enh.adv_cfg.channel_map;
|
||||
BLE_MESH_ADV(seg)->adv_cnt = net_tx->ctx->enh.adv_cfg.adv_cnt;
|
||||
BLE_MESH_ADV(seg)->adv_itvl = net_tx->ctx->enh.adv_cfg.adv_itvl;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (net_tx->ctx->enh.ext_adv_cfg_used) {
|
||||
EXT_ADV(seg)->primary_phy = net_tx->ctx->enh.ext_adv_cfg.primary_phy;
|
||||
EXT_ADV(seg)->secondary_phy = net_tx->ctx->enh.ext_adv_cfg.secondary_phy;
|
||||
EXT_ADV(seg)->include_tx_power = net_tx->ctx->enh.ext_adv_cfg.include_tx_power;
|
||||
EXT_ADV(seg)->tx_power = net_tx->ctx->enh.ext_adv_cfg.tx_power;
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
|
||||
net_buf_reserve(seg, BLE_MESH_NET_HDR_LEN);
|
||||
|
||||
net_buf_add_u8(seg, seg_hdr);
|
||||
@@ -609,7 +714,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
||||
net_buf_add_u8(seg, (((seq_zero & 0x3f) << 2) | (seg_o >> 3)));
|
||||
net_buf_add_u8(seg, ((seg_o & 0x07) << 5) | tx->seg_n);
|
||||
|
||||
len = MIN(sdu->len, seg_len(!!ctl_op));
|
||||
len = MIN(sdu->len, seg_len(&si));
|
||||
net_buf_add_mem(seg, net_buf_simple_pull_mem(sdu, len), len);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
|
||||
@@ -694,9 +799,22 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (tx->ctx->enh.long_pkt_cfg_used == true &&
|
||||
(tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_FORCE ||
|
||||
tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_PREFER) &&
|
||||
msg->len > BLE_MESH_EXT_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
} else {
|
||||
if (msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->sub->net_idx,
|
||||
tx->ctx->app_idx, tx->ctx->addr);
|
||||
@@ -794,7 +912,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr,
|
||||
/* Use bt_mesh_alloc_buf() instead of NET_BUF_SIMPLE_DEFINE to avoid
|
||||
* causing btu task stack overflow.
|
||||
*/
|
||||
sdu = bt_mesh_alloc_buf(CONFIG_BLE_MESH_RX_SDU_MAX - BLE_MESH_MIC_SHORT);
|
||||
sdu = bt_mesh_alloc_buf(buf->len);
|
||||
if (!sdu) {
|
||||
BT_ERR("%s, Out of memory", __func__);
|
||||
return -ENOMEM;
|
||||
@@ -1342,19 +1460,34 @@ static void seg_ack(struct k_work *work)
|
||||
bt_mesh_seg_rx_unlock();
|
||||
}
|
||||
|
||||
static inline bool sdu_len_is_ok(bool ctl, uint8_t seg_n)
|
||||
static inline uint16_t sdu_len_max(uint8_t seg_n,uint16_t seg_len)
|
||||
{
|
||||
return ((seg_n + 1) * seg_len(ctl) <= CONFIG_BLE_MESH_RX_SDU_MAX);
|
||||
return ((seg_n + 1) * seg_len);
|
||||
}
|
||||
|
||||
static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx,
|
||||
const uint64_t *seq_auth)
|
||||
static inline bool sdu_len_is_ok(bool ctl, uint8_t seg_n, uint16_t buf_len)
|
||||
{
|
||||
struct seg_info si = {
|
||||
.ctl = ctl,
|
||||
};
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if ((sdu_len_max(seg_n, buf_len) > CONFIG_BLE_MESH_RX_SDU_MAX)) {
|
||||
si.long_pkt = 1;
|
||||
return ((seg_n + 1) * seg_len(&si) <= BLE_MESH_EXT_RX_SDU_MAX);
|
||||
}
|
||||
#endif
|
||||
return ((seg_n + 1) * seg_len(&si) <= CONFIG_BLE_MESH_RX_SDU_MAX);
|
||||
}
|
||||
|
||||
static struct seg_rx *seg_rx_find_with_buf(struct bt_mesh_net_rx *net_rx,
|
||||
const uint64_t *seq_auth,
|
||||
struct seg_rx *rx_buf,
|
||||
uint16_t rx_buf_size )
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(seg_rx); i++) {
|
||||
struct seg_rx *rx = &seg_rx[i];
|
||||
|
||||
for (i = 0; i < rx_buf_size; i++) {
|
||||
struct seg_rx *rx = &rx_buf[i];
|
||||
if (rx->src != net_rx->ctx.addr ||
|
||||
rx->dst != net_rx->ctx.recv_dst) {
|
||||
continue;
|
||||
@@ -1387,6 +1520,64 @@ static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx,
|
||||
const uint64_t *seq_auth)
|
||||
{
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
struct seg_rx *rx = NULL;
|
||||
rx = seg_rx_find_with_buf(net_rx, seq_auth, seg_rx, ARRAY_SIZE(seg_rx));
|
||||
|
||||
if (rx) {
|
||||
if (likely(!net_rx->ctx.enh.long_pkt_cfg_used)) {
|
||||
return rx;
|
||||
}
|
||||
|
||||
if (rx->seq_auth != *seq_auth) {
|
||||
return rx;
|
||||
}
|
||||
|
||||
/* The first received segment that is possible is the last segment.
|
||||
* The segment information is stored in seg_rx, so it needs to be
|
||||
* confirmed in seg_rx.
|
||||
* This will only happen when the last segment is received
|
||||
* */
|
||||
assert(rx->block == BIT(rx->seg_n));
|
||||
assert(rx->ctl == net_rx->ctl);
|
||||
struct seg_info si = {
|
||||
.ctl = net_rx->ctl,
|
||||
.long_pkt = 0,
|
||||
};
|
||||
|
||||
/* @note: This situation will not occur in theory.
|
||||
* If it occurs, please check the reason carefully */
|
||||
if (rx->buf.len <= (rx->seg_n * seg_len(&si))) {
|
||||
BT_ERR("Incorrect packet length, the rx will be reset");
|
||||
seg_rx_reset(rx, true);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Copy the information in seg_rx into ext_seg_rx */
|
||||
struct seg_rx *ext_rx = seg_rx_alloc(net_rx, &(rx->hdr), seq_auth, rx->seg_n);
|
||||
uint16_t last_seg_len = rx->buf.len - (rx->seg_n * seg_len(&si));
|
||||
uint8_t *last_seg = rx->buf.data + (rx->seg_n * seg_len(&si));
|
||||
|
||||
/* Update to long packet length */
|
||||
si.long_pkt = 1;
|
||||
ext_rx->buf.len = rx->seg_n * seg_len(&si) + last_seg_len;
|
||||
ext_rx->block = rx->block;
|
||||
ext_rx->obo = rx->obo;
|
||||
|
||||
memcpy(ext_rx->buf.data + (rx->seg_n * seg_len(&si)), last_seg, last_seg_len);
|
||||
seg_rx_reset(rx, true);
|
||||
return ext_rx;
|
||||
}
|
||||
return seg_rx_find_with_buf(net_rx, seq_auth, ext_seg_rx, ARRAY_SIZE(ext_seg_rx));
|
||||
#else
|
||||
return seg_rx_find_with_buf(net_rx, seq_auth, seg_rx, ARRAY_SIZE(seg_rx));
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool seg_rx_is_valid(struct seg_rx *rx, struct bt_mesh_net_rx *net_rx,
|
||||
const uint8_t *hdr, uint8_t seg_n)
|
||||
{
|
||||
@@ -1413,9 +1604,25 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx,
|
||||
uint8_t seg_n)
|
||||
{
|
||||
int i;
|
||||
/* By default, traditional seg_rx is used for allocation.
|
||||
* If the first segment received is the last segment of
|
||||
* the long packet, and its length is the length of the traditional packet,
|
||||
* Since it is impossible to determine whether it is a long packet
|
||||
* under the current situation, can only copy the rx information
|
||||
* into the ext_rx buffer when the next segment received and can be
|
||||
* confirmed to be a long packet*/
|
||||
struct seg_rx *seg_rx_buf = seg_rx;
|
||||
uint16_t rx_buf_size = ARRAY_SIZE(seg_rx);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(seg_rx); i++) {
|
||||
struct seg_rx *rx = &seg_rx[i];
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (net_rx->ctx.enh.long_pkt_cfg_used) {
|
||||
seg_rx_buf = ext_seg_rx;
|
||||
rx_buf_size = ARRAY_SIZE(ext_seg_rx);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < rx_buf_size; i++) {
|
||||
struct seg_rx *rx = &seg_rx_buf[i];
|
||||
|
||||
if (rx->in_use) {
|
||||
continue;
|
||||
@@ -1432,7 +1639,11 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx,
|
||||
rx->src = net_rx->ctx.addr;
|
||||
rx->dst = net_rx->ctx.recv_dst;
|
||||
rx->block = 0U;
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
rx->ext = (seg_rx_buf == ext_seg_rx);
|
||||
#else
|
||||
rx->ext = 0;
|
||||
#endif
|
||||
BT_DBG("New RX context. Block Complete 0x%08x",
|
||||
BLOCK_COMPLETE(seg_n));
|
||||
|
||||
@@ -1483,6 +1694,14 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (buf->len > BLE_MESH_EXT_APP_SEG_SDU_MAX) {
|
||||
BT_ERR("The seg length(%d) exceeds the maximum seg length(%d) supported",
|
||||
buf->len, BLE_MESH_EXT_APP_SEG_SDU_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* According to Mesh 1.0 specification:
|
||||
* "The SeqAuth is composed of the IV Index and the sequence number
|
||||
* (SEQ) of the first segment"
|
||||
@@ -1543,7 +1762,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx,
|
||||
}
|
||||
|
||||
/* Bail out early if we're not ready to receive such a large SDU */
|
||||
if (!sdu_len_is_ok(net_rx->ctl, seg_n)) {
|
||||
if (!sdu_len_is_ok(net_rx->ctl, seg_n, buf->len)) {
|
||||
BT_ERR("Too big incoming SDU length");
|
||||
send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr,
|
||||
net_rx->ctx.send_ttl, seq_auth, 0,
|
||||
@@ -1586,17 +1805,26 @@ found_rx:
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
struct seg_info si = {
|
||||
.ctl = rx->ctl,
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
.long_pkt = rx->ext,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* All segments, except the last one, must either have 8 bytes of
|
||||
* payload (for 64bit Net MIC) or 12 bytes of payload (for 32bit
|
||||
* Net MIC).
|
||||
*/
|
||||
if (seg_o == seg_n) {
|
||||
/* Set the expected final buffer length */
|
||||
rx->buf.len = seg_n * seg_len(rx->ctl) + buf->len;
|
||||
BT_DBG("Target len %u * %u + %u = %u", seg_n, seg_len(rx->ctl),
|
||||
buf->len, rx->buf.len);
|
||||
rx->buf.len = seg_n * seg_len(&si) + buf->len;
|
||||
|
||||
if (rx->buf.len > CONFIG_BLE_MESH_RX_SDU_MAX) {
|
||||
if ((!rx->ext && rx->buf.len > CONFIG_BLE_MESH_RX_SDU_MAX)
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
|| (rx->ext && rx->buf.len > BLE_MESH_EXT_RX_SDU_MAX)
|
||||
#endif
|
||||
) {
|
||||
BT_ERR("Too large SDU len");
|
||||
send_ack(net_rx->sub, net_rx->ctx.recv_dst,
|
||||
net_rx->ctx.addr, net_rx->ctx.send_ttl,
|
||||
@@ -1605,8 +1833,9 @@ found_rx:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
} else {
|
||||
if (buf->len != seg_len(rx->ctl)) {
|
||||
BT_ERR("Incorrect segment size for message type");
|
||||
if (buf->len != seg_len(&si)) {
|
||||
BT_ERR("Incorrect segment size for message type %d %d len %d except %d",
|
||||
rx->ext, rx->ctl, buf->len, seg_len(&si));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@@ -1620,9 +1849,9 @@ found_rx:
|
||||
}
|
||||
|
||||
/* Location in buffer can be calculated based on seg_o & rx->ctl */
|
||||
memcpy(rx->buf.data + (seg_o * seg_len(rx->ctl)), buf->data, buf->len);
|
||||
memcpy(rx->buf.data + (seg_o * seg_len(&si)), buf->data, buf->len);
|
||||
|
||||
BT_INFO("Seg %u/%u received", seg_o, seg_n);
|
||||
BT_INFO("Seg %u/%u received",seg_o, seg_n);
|
||||
|
||||
/* Mark segment as received */
|
||||
rx->block |= BIT(seg_o);
|
||||
@@ -1804,11 +2033,22 @@ void bt_mesh_trans_init(void)
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(seg_rx); i++) {
|
||||
k_delayed_work_init(&seg_rx[i].ack_timer, seg_ack);
|
||||
seg_rx[i].buf.size = CONFIG_BLE_MESH_RX_SDU_MAX;
|
||||
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;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
for (i = 0; i < ARRAY_SIZE(ext_seg_rx); i++) {
|
||||
k_delayed_work_init(&ext_seg_rx[i].ack_timer, seg_ack);
|
||||
ext_seg_rx[i].buf.size = CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN;
|
||||
ext_seg_rx[i].buf.__buf = (ext_seg_rx_buf_data +
|
||||
(i * CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN));
|
||||
ext_seg_rx[i].buf.data = ext_seg_rx[i].buf.__buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
bt_mesh_mutex_create(&seg_rx_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -55,6 +55,13 @@ _Static_assert(CONFIG_BLE_MESH_ADV_BUF_COUNT >= (CONFIG_BLE_MESH_TX_SEG_MAX + 3)
|
||||
/* How long to wait for available buffers before giving up */
|
||||
#define BUF_TIMEOUT K_NO_WAIT
|
||||
|
||||
struct seg_info {
|
||||
uint8_t ctl:1; /* Control message */
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
uint8_t long_pkt:1; /* Long packet */
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct seg_tx {
|
||||
struct bt_mesh_subnet *sub;
|
||||
struct net_buf *seg[CONFIG_BLE_MESH_TX_SEG_MAX];
|
||||
@@ -95,7 +102,8 @@ static struct seg_rx {
|
||||
in_use:1,
|
||||
obo:1,
|
||||
new_seg:1, /* Indicate if a new segment is just received */
|
||||
sarc:2; /* SAR ACK Retransmissions Count */
|
||||
sarc:2, /* SAR ACK Retransmissions Count */
|
||||
ext:1;
|
||||
uint8_t hdr;
|
||||
uint8_t ttl;
|
||||
uint16_t src;
|
||||
@@ -114,11 +122,22 @@ static struct seg_rx {
|
||||
static uint8_t seg_rx_buf_data[(CONFIG_BLE_MESH_RX_SEG_MSG_COUNT *
|
||||
CONFIG_BLE_MESH_RX_SDU_MAX)];
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
/* @todo: could merge ext_seg_rx into seg_rx */
|
||||
static struct seg_rx ext_seg_rx[CONFIG_BLE_MESH_LONG_PACKET_RX_SEG_CNT];
|
||||
static uint8_t ext_seg_rx_buf_data[(CONFIG_BLE_MESH_LONG_PACKET_RX_SEG_CNT *
|
||||
BLE_MESH_EXT_RX_SDU_MAX)];
|
||||
#endif
|
||||
|
||||
static const struct bt_mesh_send_cb seg_sent_cb;
|
||||
|
||||
static bt_mesh_mutex_t seg_tx_lock;
|
||||
static bt_mesh_mutex_t seg_rx_lock;
|
||||
|
||||
static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx,
|
||||
const uint8_t *hdr, const uint64_t *seq_auth,
|
||||
uint8_t seg_n);
|
||||
|
||||
static inline void bt_mesh_seg_tx_lock(void)
|
||||
{
|
||||
bt_mesh_r_mutex_lock(&seg_tx_lock);
|
||||
@@ -263,16 +282,48 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu,
|
||||
const uint8_t *ctl_op)
|
||||
{
|
||||
struct net_buf *buf = NULL;
|
||||
enum bt_mesh_adv_type adv_type = BLE_MESH_ADV_DATA;
|
||||
|
||||
BT_DBG("src 0x%04x dst 0x%04x app_idx 0x%04x sdu_len %u",
|
||||
tx->src, tx->ctx->addr, tx->ctx->app_idx, sdu->len);
|
||||
|
||||
buf = bt_mesh_adv_create(BLE_MESH_ADV_DATA, BUF_TIMEOUT);
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (tx->ctx->enh.long_pkt_cfg_used &&
|
||||
(tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_FORCE ||
|
||||
(tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_PREFER &&
|
||||
sdu->len > (BLE_MESH_SDU_UNSEG_MAX + 4)))) {
|
||||
adv_type = BLE_MESH_ADV_EXT_LONG_DATA;
|
||||
} else
|
||||
#endif /* CONFIG_BLE_MESH_LONG_PACKET */
|
||||
{
|
||||
if (tx->ctx->enh.ext_adv_cfg_used) {
|
||||
adv_type = BLE_MESH_ADV_EXT_DATA;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_EXT_ADV */
|
||||
|
||||
buf = bt_mesh_adv_create(adv_type, BUF_TIMEOUT);
|
||||
if (!buf) {
|
||||
BT_ERR("Out of network buffers");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
if (tx->ctx->enh.adv_cfg_used) {
|
||||
BLE_MESH_ADV(buf)->channel_map = tx->ctx->enh.adv_cfg.channel_map;
|
||||
BLE_MESH_ADV(buf)->adv_cnt = tx->ctx->enh.adv_cfg.adv_cnt;
|
||||
BLE_MESH_ADV(buf)->adv_itvl = tx->ctx->enh.adv_cfg.adv_itvl;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (tx->ctx->enh.ext_adv_cfg_used) {
|
||||
EXT_ADV(buf)->primary_phy = tx->ctx->enh.ext_adv_cfg.primary_phy;
|
||||
EXT_ADV(buf)->secondary_phy = tx->ctx->enh.ext_adv_cfg.secondary_phy;
|
||||
EXT_ADV(buf)->include_tx_power = tx->ctx->enh.ext_adv_cfg.include_tx_power;
|
||||
EXT_ADV(buf)->tx_power = tx->ctx->enh.ext_adv_cfg.tx_power;
|
||||
}
|
||||
#endif
|
||||
|
||||
net_buf_reserve(buf, BLE_MESH_NET_HDR_LEN);
|
||||
|
||||
if (ctl_op) {
|
||||
@@ -315,13 +366,21 @@ send:
|
||||
return bt_mesh_net_send(tx, buf, cb, cb_data);
|
||||
}
|
||||
|
||||
static inline uint8_t seg_len(bool ctl)
|
||||
static inline uint8_t seg_len(struct seg_info *si)
|
||||
{
|
||||
if (ctl) {
|
||||
return BLE_MESH_CTL_SEG_SDU_MAX;
|
||||
if (si->ctl) {
|
||||
return
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
si->long_pkt ? BLE_MESH_EXT_CTL_SEG_SDU_MAX :
|
||||
#endif
|
||||
BLE_MESH_CTL_SEG_SDU_MAX;
|
||||
}
|
||||
|
||||
return BLE_MESH_APP_SEG_SDU_MAX;
|
||||
return
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
si->long_pkt ? BLE_MESH_EXT_APP_SEG_SDU_MAX :
|
||||
#endif
|
||||
BLE_MESH_APP_SEG_SDU_MAX;
|
||||
}
|
||||
|
||||
bool bt_mesh_tx_in_progress(void)
|
||||
@@ -812,7 +871,9 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
||||
const struct bt_mesh_send_cb *cb, void *cb_data,
|
||||
const uint8_t *ctl_op)
|
||||
{
|
||||
enum bt_mesh_adv_type adv_type = BLE_MESH_ADV_DATA;
|
||||
struct seg_tx *tx = NULL;
|
||||
struct seg_info si = {0};
|
||||
uint16_t seq_zero = 0U;
|
||||
uint8_t seg_o = 0U;
|
||||
int err = 0;
|
||||
@@ -863,12 +924,25 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
||||
tx->sub = net_tx->sub;
|
||||
tx->seq_auth = SEQ_AUTH(BLE_MESH_NET_IVI_TX, bt_mesh.seq);
|
||||
if (ctl_op) {
|
||||
si.ctl = true;
|
||||
tx->hdr = TRANS_CTL_HDR(*ctl_op, 1);
|
||||
} else if (net_tx->ctx->app_idx == BLE_MESH_KEY_DEV) {
|
||||
si.ctl = false;
|
||||
tx->hdr = SEG_HDR(0, 0);
|
||||
} else {
|
||||
si.ctl = false;
|
||||
tx->hdr = SEG_HDR(1, net_tx->aid);
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (net_tx->ctx->enh.long_pkt_cfg_used &&
|
||||
((net_tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_PREFER &&
|
||||
sdu->len > BLE_MESH_TX_SDU_MAX) ||
|
||||
net_tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_FORCE)) {
|
||||
si.long_pkt = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
tx->src = net_tx->src;
|
||||
tx->dst = net_tx->ctx->addr;
|
||||
tx->app_idx = net_tx->ctx->app_idx;
|
||||
@@ -883,7 +957,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
||||
tx->tag = net_tx->ctx->send_tag;
|
||||
tx->len = sdu->len;
|
||||
if (sdu->len) {
|
||||
tx->seg_n = (sdu->len - 1) / seg_len(!!ctl_op);
|
||||
tx->seg_n = (sdu->len - 1) / seg_len(&si);
|
||||
} else {
|
||||
tx->seg_n = 0;
|
||||
}
|
||||
@@ -933,13 +1007,45 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
||||
struct net_buf *seg = NULL;
|
||||
uint16_t len = 0U;
|
||||
|
||||
seg = bt_mesh_adv_create(BLE_MESH_ADV_DATA, BUF_TIMEOUT);
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (si.long_pkt) {
|
||||
adv_type = BLE_MESH_ADV_EXT_LONG_DATA;
|
||||
BT_INFO("use ext long adv data");
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (net_tx->ctx->enh.ext_adv_cfg_used) {
|
||||
adv_type = BLE_MESH_ADV_EXT_DATA;
|
||||
BT_INFO("use ext adv data");
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
adv_type = BLE_MESH_ADV_DATA;
|
||||
}
|
||||
}
|
||||
seg = bt_mesh_adv_create(adv_type, BUF_TIMEOUT);
|
||||
if (!seg) {
|
||||
BT_ERR("Out of segment buffers");
|
||||
seg_tx_reset(tx);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
if (net_tx->ctx->enh.adv_cfg_used) {
|
||||
BLE_MESH_ADV(seg)->channel_map = net_tx->ctx->enh.adv_cfg.channel_map;
|
||||
BLE_MESH_ADV(seg)->adv_cnt = net_tx->ctx->enh.adv_cfg.adv_cnt;
|
||||
BLE_MESH_ADV(seg)->adv_itvl = net_tx->ctx->enh.adv_cfg.adv_itvl;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_EXT_ADV
|
||||
if (net_tx->ctx->enh.ext_adv_cfg_used) {
|
||||
EXT_ADV(seg)->primary_phy = net_tx->ctx->enh.ext_adv_cfg.primary_phy;
|
||||
EXT_ADV(seg)->secondary_phy = net_tx->ctx->enh.ext_adv_cfg.secondary_phy;
|
||||
EXT_ADV(seg)->include_tx_power = net_tx->ctx->enh.ext_adv_cfg.include_tx_power;
|
||||
EXT_ADV(seg)->tx_power = net_tx->ctx->enh.ext_adv_cfg.tx_power;
|
||||
}
|
||||
#endif
|
||||
|
||||
net_buf_reserve(seg, BLE_MESH_NET_HDR_LEN);
|
||||
|
||||
net_buf_add_u8(seg, tx->hdr);
|
||||
@@ -947,7 +1053,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
||||
net_buf_add_u8(seg, (((seq_zero & 0x3f) << 2) | (seg_o >> 3)));
|
||||
net_buf_add_u8(seg, ((seg_o & 0x07) << 5) | tx->seg_n);
|
||||
|
||||
len = MIN(sdu->len, seg_len(!!ctl_op));
|
||||
len = MIN(sdu->len, seg_len(&si));
|
||||
net_buf_add_mem(seg, net_buf_simple_pull_mem(sdu, len), len);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
|
||||
@@ -1044,9 +1150,22 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (tx->ctx->enh.long_pkt_cfg_used == true &&
|
||||
(tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_FORCE ||
|
||||
tx->ctx->enh.long_pkt_cfg == BLE_MESH_LONG_PACKET_PREFER) &&
|
||||
msg->len > BLE_MESH_EXT_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
} else {
|
||||
if (msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (msg->len > BLE_MESH_SDU_UNSEG_MAX) {
|
||||
tx->ctx->send_tag |= BLE_MESH_TAG_SEND_SEGMENTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->sub->net_idx,
|
||||
tx->ctx->app_idx, tx->ctx->addr);
|
||||
@@ -1144,7 +1263,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, uint32_t seq, uint8_t hdr,
|
||||
/* Use bt_mesh_alloc_buf() instead of NET_BUF_SIMPLE_DEFINE to avoid
|
||||
* causing btu task stack overflow.
|
||||
*/
|
||||
sdu = bt_mesh_alloc_buf(CONFIG_BLE_MESH_RX_SDU_MAX - BLE_MESH_MIC_SHORT);
|
||||
sdu = bt_mesh_alloc_buf(buf->len);
|
||||
if (!sdu) {
|
||||
BT_ERR("%s, Out of memory", __func__);
|
||||
return -ENOMEM;
|
||||
@@ -1843,9 +1962,23 @@ static void discard_msg(struct k_work *work)
|
||||
seg_rx_reset(rx, false);
|
||||
}
|
||||
|
||||
static inline bool sdu_len_is_ok(bool ctl, uint8_t seg_n)
|
||||
static inline uint16_t sdu_len_max(uint8_t seg_n,uint16_t seg_len)
|
||||
{
|
||||
return ((seg_n + 1) * seg_len(ctl) <= CONFIG_BLE_MESH_RX_SDU_MAX);
|
||||
return ((seg_n + 1) * seg_len);
|
||||
}
|
||||
|
||||
static inline bool sdu_len_is_ok(bool ctl, uint8_t seg_n, uint16_t buf_len)
|
||||
{
|
||||
struct seg_info si = {
|
||||
.ctl = ctl,
|
||||
};
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if ((sdu_len_max(seg_n, buf_len) > CONFIG_BLE_MESH_RX_SDU_MAX)) {
|
||||
si.long_pkt = 1;
|
||||
return ((seg_n + 1) * seg_len(&si) <= BLE_MESH_EXT_RX_SDU_MAX);
|
||||
}
|
||||
#endif
|
||||
return ((seg_n + 1) * seg_len(&si) <= CONFIG_BLE_MESH_RX_SDU_MAX);
|
||||
}
|
||||
|
||||
static void seg_rx_reset_pending(struct bt_mesh_net_rx *net_rx,
|
||||
@@ -1867,22 +2000,93 @@ static void seg_rx_reset_pending(struct bt_mesh_net_rx *net_rx,
|
||||
}
|
||||
}
|
||||
|
||||
static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx,
|
||||
const uint64_t *seq_auth)
|
||||
static struct seg_rx *seg_rx_find_with_buf(struct bt_mesh_net_rx *net_rx,
|
||||
const uint64_t *seq_auth,
|
||||
struct seg_rx *rx_buf,
|
||||
uint16_t rx_buf_size )
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(seg_rx); i++) {
|
||||
struct seg_rx *rx = &seg_rx[i];
|
||||
for (size_t i = 0; i < rx_buf_size; i++) {
|
||||
struct seg_rx *rx = &rx_buf[i];
|
||||
|
||||
if (rx->src == net_rx->ctx.addr &&
|
||||
rx->dst == net_rx->ctx.recv_dst &&
|
||||
rx->seq_auth >= *seq_auth) {
|
||||
return rx;
|
||||
rx->dst == net_rx->ctx.recv_dst) {
|
||||
if (rx->seq_auth >= *seq_auth) {
|
||||
return rx;
|
||||
}
|
||||
|
||||
/* Received a new packet when the old packet was not fully obtained */
|
||||
BT_WARN("Duplicate SDU from src 0x%04x auth 0x%04x", net_rx->ctx.addr, rx->seq_auth);
|
||||
|
||||
/* Clear out the old context since the sender
|
||||
* has apparently started sending a new SDU.
|
||||
*/
|
||||
seg_rx_reset(rx, true);
|
||||
|
||||
/* Return non-match so caller can re-allocate */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx,
|
||||
const uint64_t *seq_auth)
|
||||
{
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
struct seg_rx *rx = NULL;
|
||||
|
||||
rx = seg_rx_find_with_buf(net_rx, seq_auth, seg_rx, ARRAY_SIZE(seg_rx));
|
||||
if (rx) {
|
||||
if (likely(!net_rx->ctx.enh.long_pkt_cfg_used)) {
|
||||
return rx;
|
||||
}
|
||||
|
||||
if (rx->seq_auth != *seq_auth) {
|
||||
return rx;
|
||||
}
|
||||
|
||||
/* The first received segment that is possible is the last segment.
|
||||
* The segment information is stored in seg_rx, so it needs to be
|
||||
* confirmed in seg_rx */
|
||||
/* This will only happen when the last segment is received */
|
||||
assert(rx->block == BIT(rx->seg_n));
|
||||
assert(rx->ctl == net_rx->ctl);
|
||||
|
||||
struct seg_info si = {
|
||||
.ctl = net_rx->ctl,
|
||||
.long_pkt = 0,
|
||||
};
|
||||
|
||||
/* @note: This situation will not occur in theory.
|
||||
* If it occurs, please check the reason carefully */
|
||||
if (rx->buf.len <= (rx->seg_n * seg_len(&si))) {
|
||||
BT_ERR("Incorrect packet length, the rx will be reset");
|
||||
seg_rx_reset(rx, true);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Copy the information in seg_rx into ext_seg_rx */
|
||||
struct seg_rx *ext_rx = seg_rx_alloc(net_rx, &(rx->hdr), seq_auth, rx->seg_n);
|
||||
uint16_t last_seg_len = rx->buf.len - (rx->seg_n * seg_len(&si));
|
||||
uint8_t *last_seg = rx->buf.data + (rx->seg_n * seg_len(&si));
|
||||
|
||||
/* Update to long packet length */
|
||||
si.long_pkt = 1;
|
||||
ext_rx->buf.len = rx->seg_n * seg_len(&si) + last_seg_len;
|
||||
ext_rx->block = rx->block;
|
||||
ext_rx->obo = rx->obo;
|
||||
|
||||
memcpy(ext_rx->buf.data + (rx->seg_n * seg_len(&si)), last_seg, last_seg_len);
|
||||
seg_rx_reset(rx, true);
|
||||
return ext_rx;
|
||||
}
|
||||
return seg_rx_find_with_buf(net_rx, seq_auth, ext_seg_rx, ARRAY_SIZE(ext_seg_rx));
|
||||
#else
|
||||
return seg_rx_find_with_buf(net_rx, seq_auth, seg_rx, ARRAY_SIZE(seg_rx));
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool seg_rx_is_valid(struct seg_rx *rx, struct bt_mesh_net_rx *net_rx,
|
||||
const uint8_t *hdr, uint8_t seg_n)
|
||||
{
|
||||
@@ -1905,8 +2109,25 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx,
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(seg_rx); i++) {
|
||||
struct seg_rx *rx = &seg_rx[i];
|
||||
/* By default, traditional seg_rx is used for allocation.
|
||||
* If the first segment received is the last segment of
|
||||
* the long packet, and its length is the length of the traditional packet,
|
||||
* Since it is impossible to determine whether it is a long packet
|
||||
* under the current situation, can only copy the rx information
|
||||
* into the ext_rx buffer when the next segment received and can be
|
||||
* confirmed to be a long packet*/
|
||||
struct seg_rx *seg_rx_buf = seg_rx;
|
||||
uint16_t rx_buf_size = ARRAY_SIZE(seg_rx);
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (net_rx->ctx.enh.long_pkt_cfg_used) {
|
||||
seg_rx_buf = ext_seg_rx;
|
||||
rx_buf_size = ARRAY_SIZE(ext_seg_rx);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < rx_buf_size; i++) {
|
||||
struct seg_rx *rx = &seg_rx_buf[i];
|
||||
|
||||
if (rx->in_use) {
|
||||
continue;
|
||||
@@ -1939,7 +2160,11 @@ static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx,
|
||||
rx->dst = net_rx->ctx.recv_dst;
|
||||
rx->block = 0U;
|
||||
rx->last_ack = 0;
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
rx->ext = (seg_rx_buf == ext_seg_rx);
|
||||
#else
|
||||
rx->ext = 0;
|
||||
#endif
|
||||
BT_DBG("New RX context. Block Complete 0x%08x",
|
||||
BLOCK_COMPLETE(seg_n));
|
||||
|
||||
@@ -2062,7 +2287,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx,
|
||||
}
|
||||
|
||||
/* Bail out early if we're not ready to receive such a large SDU */
|
||||
if (!sdu_len_is_ok(net_rx->ctl, seg_n)) {
|
||||
if (!sdu_len_is_ok(net_rx->ctl, seg_n, buf->len)) {
|
||||
BT_ERR("Too big incoming SDU length");
|
||||
send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr,
|
||||
net_rx->ctx.send_ttl, seq_auth, 0,
|
||||
@@ -2109,6 +2334,13 @@ found_rx:
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
struct seg_info si = {
|
||||
.ctl = rx->ctl,
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
.long_pkt = rx->ext,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* All segments, except the last one, must either have 8 bytes of
|
||||
* payload (for 64bit Net MIC) or 12 bytes of payload (for 32bit
|
||||
* Net MIC).
|
||||
@@ -2116,9 +2348,9 @@ found_rx:
|
||||
*/
|
||||
if (seg_o == seg_n) {
|
||||
/* Set the expected final buffer length */
|
||||
rx->buf.len = seg_n * seg_len(rx->ctl) + buf->len;
|
||||
rx->buf.len = seg_n * seg_len(&si) + buf->len;
|
||||
|
||||
BT_DBG("Target len %u * %u + %u = %u", seg_n, seg_len(rx->ctl),
|
||||
BT_DBG("Target len %u * %u + %u = %u", seg_n, seg_len(&si),
|
||||
buf->len, rx->buf.len);
|
||||
|
||||
/* This should not happen, since we have made sure the whole
|
||||
@@ -2126,7 +2358,11 @@ found_rx:
|
||||
* But if the peer device sends the segments of a segmented
|
||||
* message with different CTL, then the following could happen.
|
||||
*/
|
||||
if (rx->buf.len > CONFIG_BLE_MESH_RX_SDU_MAX) {
|
||||
if ((!rx->ext && rx->buf.len > CONFIG_BLE_MESH_RX_SDU_MAX)
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
|| (rx->ext && rx->buf.len > BLE_MESH_EXT_RX_SDU_MAX)
|
||||
#endif
|
||||
) {
|
||||
BT_ERR("Too large SDU len %u/%u", rx->buf.len,
|
||||
CONFIG_BLE_MESH_RX_SDU_MAX);
|
||||
|
||||
@@ -2138,14 +2374,14 @@ found_rx:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
} else {
|
||||
if (buf->len != seg_len(rx->ctl)) {
|
||||
if (buf->len != seg_len(&si)) {
|
||||
BT_ERR("Incorrect segment size for message type");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Location in buffer can be calculated based on seg_o & rx->ctl */
|
||||
memcpy(rx->buf.data + (seg_o * seg_len(rx->ctl)), buf->data, buf->len);
|
||||
memcpy(rx->buf.data + (seg_o * seg_len(&si)), buf->data, buf->len);
|
||||
|
||||
BT_INFO("Seg %u/%u received", seg_o, seg_n);
|
||||
|
||||
@@ -2342,13 +2578,24 @@ void bt_mesh_tx_reset_single(uint16_t dst)
|
||||
|
||||
void bt_mesh_trans_init(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
bt_mesh_sar_init();
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(seg_rx); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(seg_rx); i++) {
|
||||
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;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
for (i = 0; i < ARRAY_SIZE(ext_seg_rx); i++) {
|
||||
ext_seg_rx[i].buf.size = CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN;
|
||||
ext_seg_rx[i].buf.__buf = (ext_seg_rx_buf_data +
|
||||
(i * CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN));
|
||||
ext_seg_rx[i].buf.data = ext_seg_rx[i].buf.__buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
bt_mesh_r_mutex_create(&seg_tx_lock);
|
||||
bt_mesh_r_mutex_create(&seg_rx_lock);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017 Intel Corporation
|
||||
* SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -17,11 +17,58 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#define TRANS_SEQ_AUTH_NVAL 0xffffffffffffffff
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
#include "adv.h"
|
||||
/**
|
||||
* Advertising Packet Length: 29 bytes
|
||||
*
|
||||
* Network Layer:
|
||||
* - Network Header: 9 bytes
|
||||
* - NetMIC: 4 bytes (for unsegmented messages), 8 bytes (for segmented messages)
|
||||
*
|
||||
* Lower Transport PDU:
|
||||
* - Unsegmented:
|
||||
* - Header: 1 byte
|
||||
* - Payload: up to 15 bytes
|
||||
* - Segmented:
|
||||
* - Header: 4 bytes
|
||||
* - Payload: up to 12 bytes per segment
|
||||
*
|
||||
* Upper Transport PDU (Access Messages):
|
||||
* - Unsegmented:
|
||||
* - TransMIC: 4 bytes
|
||||
* - Max Access Payload: 11 bytes
|
||||
* - Segmented:
|
||||
* - TransMIC size depends on ASZMIC flag:
|
||||
* - 4-byte TransMIC: Max payload = (32 segments * 12 bytes) - 4 = 380 bytes
|
||||
* - 8-byte TransMIC: Max payload = (32 segments * 12 bytes) - 8 = 376 bytes
|
||||
*
|
||||
* Extended Advertising (ADV) Support:
|
||||
* - If ADV length is increased to 249 bytes:
|
||||
* - Max access payload = 32 * (249 - 17) - 8 = 7416 bytes
|
||||
* - (17 bytes = Network Header + Segment Header + TransMIC)
|
||||
*
|
||||
* Reliability Consideration:
|
||||
* - To achieve an expected valid message ratio of x,
|
||||
* the minimum ADV packet length should be:
|
||||
* min_adv_len = 21 / (1 - x)
|
||||
* Example:
|
||||
* For >80% success rate (x = 0.8), min_adv_len = 105 bytes
|
||||
*/
|
||||
#define BLE_MESH_EXT_SDU_UNSEG_MAX (CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN - 18)
|
||||
#define BLE_MESH_EXT_CTL_SEG_SDU_MAX (CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN - 21)
|
||||
#define BLE_MESH_EXT_APP_SEG_SDU_MAX (CONFIG_BLE_MESH_LONG_PACKET_ADV_LEN - 17)
|
||||
#define BLE_MESH_EXT_TX_SDU_MAX (CONFIG_BLE_MESH_LONG_PACKET_TX_SEG_CNT * BLE_MESH_EXT_APP_SEG_SDU_MAX)
|
||||
#define BLE_MESH_EXT_RX_SDU_MAX (CONFIG_BLE_MESH_LONG_PACKET_RX_SEG_CNT * BLE_MESH_EXT_APP_SEG_SDU_MAX)
|
||||
#endif
|
||||
#define BLE_MESH_SDU_UNSEG_MAX 11
|
||||
#define BLE_MESH_MSG_UNSEG_MAX (BLE_MESH_SDU_UNSEG_MAX + BLE_MESH_MIC_SHORT)
|
||||
#define BLE_MESH_CTL_SEG_SDU_MAX 8
|
||||
/** Maximum size of an access message segment (in octets). */
|
||||
#define BLE_MESH_APP_SEG_SDU_MAX 12
|
||||
#define BLE_MESH_TX_SDU_MAX (CONFIG_BLE_MESH_TX_SEG_MAX * 12)
|
||||
|
||||
#define BLE_MESH_TX_SDU_MAX MAX(BLE_MESH_MSG_UNSEG_MAX, (CONFIG_BLE_MESH_TX_SEG_MAX * 12))
|
||||
#define BLE_MESH_RX_SDU_MAX MAX(BLE_MESH_MSG_UNSEG_MAX, (BLE_MESH_APP_SEG_SDU_MAX * 32))
|
||||
|
||||
#define TRANS_SEQ_ZERO_MASK ((uint16_t)BIT_MASK(13))
|
||||
#define TRANS_CTL_OP_MASK ((uint8_t)BIT_MASK(7))
|
||||
|
||||
@@ -201,7 +201,16 @@ static int32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx,
|
||||
*/
|
||||
seg_rtx_num = bt_mesh_get_seg_rtx_num();
|
||||
seg_rtx_to = bt_mesh_get_seg_rtx_timeout(ctx->addr, ctx->send_ttl);
|
||||
seg_count = (msg->len + mic_size - 1) / 12U + 1U;
|
||||
|
||||
#if CONFIG_BLE_MESH_LONG_PACKET
|
||||
if (ctx->enh.long_pkt_cfg &&
|
||||
msg->len > BLE_MESH_TX_SDU_MAX) {
|
||||
seg_count = (msg->len + mic_size - 1) / BLE_MESH_EXT_APP_SEG_SDU_MAX + 1U;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
seg_count = (msg->len + mic_size - 1) / 12U + 1U;
|
||||
}
|
||||
|
||||
duration = bt_mesh_get_adv_duration(ctx);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user