summaryrefslogtreecommitdiff
path: root/lib/bt/esp_ble_mesh
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2025-07-25 13:33:07 +1000
committerjacqueline <me@jacqueline.id.au>2025-07-25 13:33:07 +1000
commitc8e79a926620e48830778714cfe4b2ea2453fcaf (patch)
tree8c756e08e01b8e147cf72bec128026f46bd854c5 /lib/bt/esp_ble_mesh
parent237136f3e93cb6b5be24670d7520adb17cc0fa36 (diff)
downloadtangara-fw-c8e79a926620e48830778714cfe4b2ea2453fcaf.tar.gz
Update forked idf components
Diffstat (limited to 'lib/bt/esp_ble_mesh')
-rw-r--r--lib/bt/esp_ble_mesh/Kconfig.in520
-rw-r--r--lib/bt/esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c26
-rw-r--r--lib/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c2
-rw-r--r--lib/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_ble_api.h88
-rw-r--r--lib/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h25
-rw-r--r--lib/bt/esp_ble_mesh/btc/btc_ble_mesh_ble.c49
-rw-r--r--lib/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c10
-rw-r--r--lib/bt/esp_ble_mesh/btc/include/btc_ble_mesh_ble.h39
-rw-r--r--lib/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h2
-rw-r--r--lib/bt/esp_ble_mesh/common/atomic.c16
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/atomic.h27
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/mutex.h7
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/queue.h33
-rw-r--r--lib/bt/esp_ble_mesh/common/include/mesh/utils.h2
-rw-r--r--lib/bt/esp_ble_mesh/common/mutex.c53
-rw-r--r--lib/bt/esp_ble_mesh/common/queue.c48
-rw-r--r--lib/bt/esp_ble_mesh/core/access.c148
-rw-r--r--lib/bt/esp_ble_mesh/core/adv.c775
-rw-r--r--lib/bt/esp_ble_mesh/core/adv.h82
-rw-r--r--lib/bt/esp_ble_mesh/core/adv_common.c683
-rw-r--r--lib/bt/esp_ble_mesh/core/adv_common.h293
-rw-r--r--lib/bt/esp_ble_mesh/core/beacon.c13
-rw-r--r--lib/bt/esp_ble_mesh/core/ble_adv.c323
-rw-r--r--lib/bt/esp_ble_mesh/core/ble_adv.h54
-rw-r--r--lib/bt/esp_ble_mesh/core/bluedroid_host/adapter.c597
-rw-r--r--lib/bt/esp_ble_mesh/core/cfg_srv.c165
-rw-r--r--lib/bt/esp_ble_mesh/core/crypto.c2
-rw-r--r--lib/bt/esp_ble_mesh/core/ext_adv.c427
-rw-r--r--lib/bt/esp_ble_mesh/core/ext_adv.h39
-rw-r--r--lib/bt/esp_ble_mesh/core/friend.c34
-rw-r--r--lib/bt/esp_ble_mesh/core/include/mesh/access.h4
-rw-r--r--lib/bt/esp_ble_mesh/core/include/mesh/adapter.h161
-rw-r--r--lib/bt/esp_ble_mesh/core/lpn.c3
-rw-r--r--lib/bt/esp_ble_mesh/core/main.c20
-rw-r--r--lib/bt/esp_ble_mesh/core/mesh.h1
-rw-r--r--lib/bt/esp_ble_mesh/core/net.c289
-rw-r--r--lib/bt/esp_ble_mesh/core/net.h14
-rw-r--r--lib/bt/esp_ble_mesh/core/nimble_host/adapter.c812
-rw-r--r--lib/bt/esp_ble_mesh/core/prov_common.c33
-rw-r--r--lib/bt/esp_ble_mesh/core/prov_common.h2
-rw-r--r--lib/bt/esp_ble_mesh/core/prov_node.c37
-rw-r--r--lib/bt/esp_ble_mesh/core/prov_pvnr.c55
-rw-r--r--lib/bt/esp_ble_mesh/core/prov_pvnr.h2
-rw-r--r--lib/bt/esp_ble_mesh/core/proxy_client.c91
-rw-r--r--lib/bt/esp_ble_mesh/core/proxy_client.h4
-rw-r--r--lib/bt/esp_ble_mesh/core/proxy_server.c121
-rw-r--r--lib/bt/esp_ble_mesh/core/proxy_server.h4
-rw-r--r--lib/bt/esp_ble_mesh/core/pvnr_mgmt.c2
-rw-r--r--lib/bt/esp_ble_mesh/core/scan.c218
-rw-r--r--lib/bt/esp_ble_mesh/core/scan.h8
-rw-r--r--lib/bt/esp_ble_mesh/core/storage/settings.c5
-rw-r--r--lib/bt/esp_ble_mesh/core/tag.h53
-rw-r--r--lib/bt/esp_ble_mesh/core/transport.c67
-rw-r--r--lib/bt/esp_ble_mesh/core/transport.enh.c6
-rw-r--r--lib/bt/esp_ble_mesh/lib/ext.c88
-rw-r--r--lib/bt/esp_ble_mesh/lib/include/mesh_v1.1/utils.h2
-rw-r--r--lib/bt/esp_ble_mesh/lib/lib/esp32/libble_mesh.abin943462 -> 1487706 bytes
-rw-r--r--lib/bt/esp_ble_mesh/lib/lib/esp32c3/libble_mesh.abin2057546 -> 2605230 bytes
-rw-r--r--lib/bt/esp_ble_mesh/lib/lib/esp32c5/libble_mesh.abin0 -> 2605230 bytes
-rw-r--r--lib/bt/esp_ble_mesh/lib/lib/esp32c6/libble_mesh.abin2057546 -> 2605230 bytes
-rw-r--r--lib/bt/esp_ble_mesh/lib/lib/esp32c61/libble_mesh.abin0 -> 2605230 bytes
-rw-r--r--lib/bt/esp_ble_mesh/lib/lib/esp32h2/libble_mesh.abin2057546 -> 2605230 bytes
-rw-r--r--lib/bt/esp_ble_mesh/lib/lib/esp32s3/libble_mesh.abin943462 -> 1487414 bytes
-rw-r--r--lib/bt/esp_ble_mesh/models/client/client_common.c2
-rw-r--r--lib/bt/esp_ble_mesh/models/server/time_scene_server.c6
-rw-r--r--lib/bt/esp_ble_mesh/v1.1/api/core/esp_ble_mesh_rpr_model_api.c33
-rw-r--r--lib/bt/esp_ble_mesh/v1.1/api/core/include/esp_ble_mesh_rpr_model_api.h22
-rw-r--r--lib/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c84
-rw-r--r--lib/bt/esp_ble_mesh/v1.1/btc/include/btc_ble_mesh_rpr_model.h20
69 files changed, 5474 insertions, 1377 deletions
diff --git a/lib/bt/esp_ble_mesh/Kconfig.in b/lib/bt/esp_ble_mesh/Kconfig.in
index 216ab39a..eb761a5e 100644
--- a/lib/bt/esp_ble_mesh/Kconfig.in
+++ b/lib/bt/esp_ble_mesh/Kconfig.in
@@ -6,22 +6,97 @@ if BLE_MESH
help
It is a temporary solution and needs further modifications.
+ config BLE_MESH_V11_SUPPORT
+ bool "Support ESP BLE Mesh v1.1 features (Preview)"
+ default y
+ help
+ Support BLE Mesh v1.1 features
+
config BLE_MESH_RANDOM_ADV_INTERVAL
bool "Support using random adv interval for mesh packets"
select BT_BLE_HIGH_DUTY_ADV_INTERVAL if BT_BLUEDROID_ENABLED
+ select BT_NIMBLE_HIGH_DUTY_ADV_ITVL if BT_NIMBLE_ENABLED
default n
help
Enable this option to allow using random advertising interval
for mesh packets. And this could help avoid collision of
advertising packets.
+ menuconfig BLE_MESH_USE_BLE_50
+ bool "Support using BLE 5.0 APIs for BLE Mesh"
+ depends on BLE_MESH_EXPERIMENTAL
+ select BT_NIMBLE_50_FEATURE_SUPPORT if BT_NIMBLE_ENABLED
+ select BT_NIMBLE_EXT_ADV if BT_NIMBLE_ENABLED
+ select BT_BLE_50_FEATURES_SUPPORTED if BT_BLUEDROID_ENABLED
+ select BT_LE_50_FEATURE_SUPPORT if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2
+ default n
+ help
+ This option to enable BLE Mesh using some BLE 5.0 APIs.
+
+ config BLE_MESH_ADV_INST_ID
+ depends on BLE_MESH_USE_BLE_50
+ int "Extended adv instance for Mesh normal packets"
+ default 0
+ range 0 3
+ help
+ Extended ADV instance used by Mesh normal advertising packets.
+
+ menuconfig BLE_MESH_SUPPORT_MULTI_ADV
+ bool "Support using multiple adv instance for BLE Mesh"
+ depends on BLE_MESH_USE_BLE_50
+ default n
+ help
+ Enable this option to support using multiple adv instance while running BLE Mesh.
+
+ config BLE_MESH_PROXY_ADV_INST_ID
+ int "Extended adv instance for Mesh proxy packets"
+ depends on BLE_MESH_PROXY
+ depends on (BLE_MESH_PB_GATT || BLE_MESH_GATT_PROXY_SERVER)
+ depends on BLE_MESH_SUPPORT_MULTI_ADV
+ default 1
+ range 0 3
+ help
+ Extended ADV instance used by Mesh proxy advertising packets.
+
+ menuconfig BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
+ bool "Use separate extended adv instance for Mesh relay packets"
+ depends on BLE_MESH_SUPPORT_MULTI_ADV
+ depends on BLE_MESH_RELAY_ADV_BUF
+ default n
+ help
+ Enable this option to support using a separate extended ADV instance for Mesh relay packets.
+
+ config BLE_MESH_RELAY_ADV_INST_ID
+ int "Extended adv instance for Mesh relay packets"
+ depends on BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
+ default 2
+ range 0 3
+ help
+ Extended ADV instance used by Mesh relay advertising packets.
+
+ menuconfig BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
+ bool "Use separate extended adv instance for BLE normal packets"
+ depends on BLE_MESH_SUPPORT_MULTI_ADV
+ depends on BLE_MESH_SUPPORT_BLE_ADV
+ default n
+ help
+ Enable this option to support using a separate extended ADV instance for normal BLE advertising packets.
+
+ config BLE_MESH_BLE_ADV_INST_ID
+ int "Extended adv instance for normal BLE packets"
+ depends on BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
+ default 3
+ range 0 3
+ help
+ Extended ADV instance used by normal BLE advertising packets.
+
config BLE_MESH_USE_DUPLICATE_SCAN
bool "Support Duplicate Scan in BLE Mesh"
select BTDM_BLE_SCAN_DUPL if IDF_TARGET_ESP32
select BTDM_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32
select BT_CTRL_BLE_SCAN_DUPL if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
select BT_CTRL_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
- select BT_LE_SCAN_DUPL if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2
+ select BT_LE_SCAN_DUPL if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32C61 || IDF_TARGET_ESP32C5
select BT_NIMBLE_VS_SUPPORT if BT_NIMBLE_ENABLED
default y
help
@@ -32,6 +107,7 @@ if BLE_MESH
config BLE_MESH_ACTIVE_SCAN
bool "Support Active Scan in BLE Mesh"
+ depends on BLE_MESH_V11_SUPPORT
help
Enable this option to allow using BLE Active Scan for BLE Mesh.
@@ -281,6 +357,7 @@ if BLE_MESH
config BLE_MESH_PROV_EPA
bool "BLE Mesh enhanced provisioning authentication"
depends on BLE_MESH_PROV
+ depends on BLE_MESH_V11_SUPPORT
default y
help
Enable this option to support BLE Mesh enhanced provisioning authentication
@@ -290,6 +367,7 @@ if BLE_MESH
config BLE_MESH_CERT_BASED_PROV
bool "Support Certificate-based provisioning"
depends on BLE_MESH_PROV
+ depends on BLE_MESH_V11_SUPPORT
default n
help
Enable this option to support BLE Mesh Certificate-Based Provisioning.
@@ -390,6 +468,7 @@ if BLE_MESH
config BLE_MESH_PROXY_SOLIC_PDU_RX
bool "Support receiving Proxy Solicitation PDU"
depends on BLE_MESH_GATT_PROXY_SERVER
+ depends on BLE_MESH_V11_SUPPORT
help
Enable this option to support receiving Proxy Solicitation PDU.
@@ -397,7 +476,7 @@ if BLE_MESH
int "Maximum capacity of solicitation replay protection list"
depends on BLE_MESH_PROXY_SOLIC_PDU_RX
default 2
- range 1 255
+ range 1 65536
help
This option specifies the maximum capacity of the solicitation replay
protection list. The solicitation replay protection list is used to
@@ -405,6 +484,13 @@ if BLE_MESH
will store the solicitation src and solicitation sequence number of
the received Solicitation PDU message.
+ config BLE_MESH_PROXY_CLI_SRV_COEXIST
+ bool "Support Proxy Client and Proxy Server coexistence"
+ depends on BLE_MESH_EXPERIMENTAL
+ default n
+ help
+ Enable this option to support the coexistence of proxy client and proxy server.
+
config BLE_MESH_GATT_PROXY_CLIENT
bool "BLE Mesh GATT Proxy Client"
select BLE_MESH_PROXY
@@ -417,6 +503,7 @@ if BLE_MESH
config BLE_MESH_PROXY_SOLIC_PDU_TX
bool "Support sending Proxy Solicitation PDU"
depends on BLE_MESH_GATT_PROXY_CLIENT
+ depends on BLE_MESH_V11_SUPPORT
help
Enable this option to support sending Proxy Solicitation PDU.
@@ -703,6 +790,7 @@ if BLE_MESH
to perform the IV index recovery procedure.
config BLE_MESH_SAR_ENHANCEMENT
+ depends on BLE_MESH_V11_SUPPORT
bool "Segmentation and reassembly enhancement"
default n
help
@@ -1102,253 +1190,257 @@ if BLE_MESH
help
Enable support for Health Server model.
- config BLE_MESH_BRC_CLI
- bool "Bridge Configuration Client model"
- help
- Enable support for Bridge Configuration Client model.
-
- config BLE_MESH_BRC_SRV
- bool "Bridge Configuration Server model"
- default n
- help
- Enable support for Bridge Configuration Server model.
-
- if BLE_MESH_BRC_SRV
+ if BLE_MESH_V11_SUPPORT
- config BLE_MESH_MAX_BRIDGING_TABLE_ENTRY_COUNT
- int "Maximum number of Bridging Table entries"
- range 16 65535
- default 16
+ config BLE_MESH_BRC_CLI
+ bool "Bridge Configuration Client model"
help
- Maximum number of Bridging Table entries that the Bridge Configuration Server can support.
+ Enable support for Bridge Configuration Client model.
- config BLE_MESH_BRIDGE_CRPL
- int "Maximum capacity of bridge replay protection list"
- default 5
- range 1 255
+ config BLE_MESH_BRC_SRV
+ bool "Bridge Configuration Server model"
+ default n
help
- This option specifies the maximum capacity of the bridge replay
- protection list. The bridge replay protection list is used to
- prevent a bridged subnet from replay attack, which will store the
- source address and sequence number of the received bridge messages.
+ Enable support for Bridge Configuration Server model.
- endif #BLE_MESH_BRC_SRV
+ if BLE_MESH_BRC_SRV
- config BLE_MESH_PRB_CLI
- bool "Mesh Private Beacon Client model"
- help
- Enable support for Mesh Private Beacon Client model.
+ config BLE_MESH_MAX_BRIDGING_TABLE_ENTRY_COUNT
+ int "Maximum number of Bridging Table entries"
+ range 16 65535
+ default 16
+ help
+ Maximum number of Bridging Table entries that the Bridge Configuration Server can support.
- config BLE_MESH_PRB_SRV
- bool "Mesh Private Beacon Server model"
- help
- Enable support for Mesh Private Beacon Server model.
+ config BLE_MESH_BRIDGE_CRPL
+ int "Maximum capacity of bridge replay protection list"
+ default 5
+ range 1 255
+ help
+ This option specifies the maximum capacity of the bridge replay
+ protection list. The bridge replay protection list is used to
+ prevent a bridged subnet from replay attack, which will store the
+ source address and sequence number of the received bridge messages.
- config BLE_MESH_ODP_CLI
- bool "On-Demand Private Proxy Client model"
- help
- Enable support for On-Demand Private Proxy Client model.
+ endif #BLE_MESH_BRC_SRV
- config BLE_MESH_ODP_SRV
- bool "On-Demand Private Proxy Server model"
- depends on BLE_MESH_PROXY_SOLIC_PDU_RX
- select BLE_MESH_SRPL_SRV
- help
- Enable support for On-Demand Private Proxy Server model.
+ config BLE_MESH_PRB_CLI
+ bool "Mesh Private Beacon Client model"
+ help
+ Enable support for Mesh Private Beacon Client model.
- config BLE_MESH_SRPL_CLI
- bool "Solicitation PDU RPL Configuration Client model"
- help
- Enable support for Solicitation PDU RPL Configuration Client model.
+ config BLE_MESH_PRB_SRV
+ bool "Mesh Private Beacon Server model"
+ help
+ Enable support for Mesh Private Beacon Server model.
- config BLE_MESH_SRPL_SRV
- bool "Solicitation PDU RPL Configuration Server model"
- depends on BLE_MESH_PROXY_SOLIC_PDU_RX
- help
- Enable support for Solicitation PDU RPL Configuration Server model.
- Note:
- This option depends on the functionality of receiving Solicitation
- PDU. If the device doesn't support receiving Solicitation PDU, then
- there is no need to enable this server model.
+ config BLE_MESH_ODP_CLI
+ bool "On-Demand Private Proxy Client model"
+ help
+ Enable support for On-Demand Private Proxy Client model.
- config BLE_MESH_AGG_CLI
- bool "Opcodes Aggregator Client model"
- help
- Enable support for Opcodes Aggregator Client model.
+ config BLE_MESH_ODP_SRV
+ bool "On-Demand Private Proxy Server model"
+ depends on BLE_MESH_PROXY_SOLIC_PDU_RX
+ select BLE_MESH_SRPL_SRV
+ help
+ Enable support for On-Demand Private Proxy Server model.
- config BLE_MESH_AGG_SRV
- bool "Opcodes Aggregator Server model"
- help
- Enable support for Opcodes Aggregator Server model.
+ config BLE_MESH_SRPL_CLI
+ bool "Solicitation PDU RPL Configuration Client model"
+ help
+ Enable support for Solicitation PDU RPL Configuration Client model.
- config BLE_MESH_SAR_CLI
- bool "SAR Configuration Client model"
- help
- Enable support for SAR Configuration Client model.
+ config BLE_MESH_SRPL_SRV
+ bool "Solicitation PDU RPL Configuration Server model"
+ depends on BLE_MESH_PROXY_SOLIC_PDU_RX
+ help
+ Enable support for Solicitation PDU RPL Configuration Server model.
+ Note:
+ This option depends on the functionality of receiving Solicitation
+ PDU. If the device doesn't support receiving Solicitation PDU, then
+ there is no need to enable this server model.
+
+ config BLE_MESH_AGG_CLI
+ bool "Opcodes Aggregator Client model"
+ help
+ Enable support for Opcodes Aggregator Client model.
- config BLE_MESH_SAR_SRV
- bool "SAR Configuration Server model"
- help
- Enable support for SAR Configuration Server model.
+ config BLE_MESH_AGG_SRV
+ bool "Opcodes Aggregator Server model"
+ help
+ Enable support for Opcodes Aggregator Server model.
- config BLE_MESH_COMP_DATA_1
- bool "Support Composition Data Page 1"
- help
- Composition Data Page 1 contains information about the relationships
- among models.
- Each model either can be a root model or can extend other models.
+ config BLE_MESH_SAR_CLI
+ bool "SAR Configuration Client model"
+ help
+ Enable support for SAR Configuration Client model.
- config BLE_MESH_COMP_DATA_128
- bool "Support Composition Data Page 128"
- help
- Composition Data Page 128 is used to indicate the structure of
- elements, features, and models of a node after the successful
- execution of the Node Address Refresh procedure or the Node
- Composition Refresh procedure, or after the execution of the
- Node Removal procedure followed by the provisioning process.
- Composition Data Page 128 shall be present if the node supports
- the Remote Provisioning Server model; otherwise it is optional.
+ config BLE_MESH_SAR_SRV
+ bool "SAR Configuration Server model"
+ help
+ Enable support for SAR Configuration Server model.
- config BLE_MESH_MODELS_METADATA_0
- bool "Support Models Metadata Page 0"
- help
- The Models Metadata state contains metadata of a node’s models.
- The Models Metadata state is composed of a number of pages of
- information.
- Models Metadata Page 0 shall be present if the node supports
- the Large Composition Data Server model.
+ config BLE_MESH_COMP_DATA_1
+ bool "Support Composition Data Page 1"
+ help
+ Composition Data Page 1 contains information about the relationships
+ among models.
+ Each model either can be a root model or can extend other models.
- config BLE_MESH_MODELS_METADATA_128
- bool "Support Models Metadata Page 128"
- depends on BLE_MESH_MODELS_METADATA_0
- help
- The Models Metadata state contains metadata of a node’s models.
- The Models Metadata state is composed of a number of pages of
- information.
- Models Metadata Page 128 contains metadata for the node’s models
- after the successful execution of the Node Address Refresh
- procedure or the Node Composition Refresh procedure, or after
- the execution of the Node Removal procedure followed by the
- provisioning process.
- Models Metadata Page 128 shall be present if the node supports
- the Remote Provisioning Server model and the node supports the
- Large Composition Data Server model.
+ config BLE_MESH_COMP_DATA_128
+ bool "Support Composition Data Page 128"
+ help
+ Composition Data Page 128 is used to indicate the structure of
+ elements, features, and models of a node after the successful
+ execution of the Node Address Refresh procedure or the Node
+ Composition Refresh procedure, or after the execution of the
+ Node Removal procedure followed by the provisioning process.
+ Composition Data Page 128 shall be present if the node supports
+ the Remote Provisioning Server model; otherwise it is optional.
+
+ config BLE_MESH_MODELS_METADATA_0
+ bool "Support Models Metadata Page 0"
+ help
+ The Models Metadata state contains metadata of a node’s models.
+ The Models Metadata state is composed of a number of pages of
+ information.
+ Models Metadata Page 0 shall be present if the node supports
+ the Large Composition Data Server model.
+
+ config BLE_MESH_MODELS_METADATA_128
+ bool "Support Models Metadata Page 128"
+ depends on BLE_MESH_MODELS_METADATA_0
+ help
+ The Models Metadata state contains metadata of a node’s models.
+ The Models Metadata state is composed of a number of pages of
+ information.
+ Models Metadata Page 128 contains metadata for the node’s models
+ after the successful execution of the Node Address Refresh
+ procedure or the Node Composition Refresh procedure, or after
+ the execution of the Node Removal procedure followed by the
+ provisioning process.
+ Models Metadata Page 128 shall be present if the node supports
+ the Remote Provisioning Server model and the node supports the
+ Large Composition Data Server model.
+
+ config BLE_MESH_LCD_CLI
+ bool "Large Composition Data Client model"
+ help
+ Enable support for Large Composition Data Client model.
- config BLE_MESH_LCD_CLI
- bool "Large Composition Data Client model"
- help
- Enable support for Large Composition Data Client model.
+ config BLE_MESH_LCD_SRV
+ bool "Large Composition Data Server model"
+ select BLE_MESH_MODELS_METADATA_0
+ help
+ Enable support for Large Composition Data Server model.
- config BLE_MESH_LCD_SRV
- bool "Large Composition Data Server model"
- select BLE_MESH_MODELS_METADATA_0
- help
- Enable support for Large Composition Data Server model.
+ config BLE_MESH_RPR_CLI
+ bool "Remote Provisioning Client model"
+ depends on BLE_MESH_PROVISIONER
+ select BLE_MESH_PROV
+ help
+ Enable support for Remote Provisioning Client model
- config BLE_MESH_RPR_CLI
- bool "Remote Provisioning Client model"
- depends on BLE_MESH_PROVISIONER
- select BLE_MESH_PROV
- help
- Enable support for Remote Provisioning Client model
+ if BLE_MESH_RPR_CLI
- if BLE_MESH_RPR_CLI
+ config BLE_MESH_RPR_CLI_PROV_SAME_TIME
+ int "Maximum number of PB-Remote running at the same time by Provisioner"
+ range 1 5
+ default 2
+ help
+ This option specifies how many devices can be provisioned at the same time
+ using PB-REMOTE. For example, if the value is 2, it means a Provisioner can
+ provision two unprovisioned devices with PB-REMOTE at the same time.
- config BLE_MESH_RPR_CLI_PROV_SAME_TIME
- int "Maximum number of PB-Remote running at the same time by Provisioner"
- range 1 5
- default 2
+ endif # BLE_MESH_RPR_CLI
+
+ config BLE_MESH_RPR_SRV
+ bool "Remote Provisioning Server model"
+ depends on BLE_MESH_NODE
+ select BLE_MESH_PB_ADV
help
- This option specifies how many devices can be provisioned at the same time
- using PB-REMOTE. For example, if the value is 2, it means a Provisioner can
- provision two unprovisioned devices with PB-REMOTE at the same time.
+ Enable support for Remote Provisioning Server model
- endif # BLE_MESH_RPR_CLI
+ if BLE_MESH_RPR_SRV
- config BLE_MESH_RPR_SRV
- bool "Remote Provisioning Server model"
- depends on BLE_MESH_NODE
- select BLE_MESH_PB_ADV
- help
- Enable support for Remote Provisioning Server model
+ config BLE_MESH_RPR_SRV_MAX_SCANNED_ITEMS
+ int "Maximum number of device information can be scanned"
+ range 4 255
+ default 10
+ help
+ This option specifies how many device information can a Remote
+ Provisioning Server store each time while scanning.
- if BLE_MESH_RPR_SRV
+ config BLE_MESH_RPR_SRV_ACTIVE_SCAN
+ bool "Support Active Scan for remote provisioning"
+ select BLE_MESH_ACTIVE_SCAN
+ help
+ Enable this option to support Active Scan for remote provisioning.
- config BLE_MESH_RPR_SRV_MAX_SCANNED_ITEMS
- int "Maximum number of device information can be scanned"
- range 4 255
- default 10
- help
- This option specifies how many device information can a Remote
- Provisioning Server store each time while scanning.
+ config BLE_MESH_RPR_SRV_MAX_EXT_SCAN
+ int "Maximum number of extended scan procedures"
+ range 1 10
+ default 1
+ help
+ This option specifies how many extended scan procedures can be
+ started by the Remote Provisioning Server.
- config BLE_MESH_RPR_SRV_ACTIVE_SCAN
- bool "Support Active Scan for remote provisioning"
- select BLE_MESH_ACTIVE_SCAN
- help
- Enable this option to support Active Scan for remote provisioning.
+ endif # BLE_MESH_RPR_SRV
- config BLE_MESH_RPR_SRV_MAX_EXT_SCAN
- int "Maximum number of extended scan procedures"
- range 1 10
- default 1
+ config BLE_MESH_DF_CLI
+ bool "Directed Forwarding Configuration Client model"
help
- This option specifies how many extended scan procedures can be
- started by the Remote Provisioning Server.
+ Enable support for Directed Forwarding Configuration Client model.
- endif # BLE_MESH_RPR_SRV
+ config BLE_MESH_DF_SRV
+ bool "Directed Forwarding Configuration Server model"
+ help
+ Enable support for Directed Forwarding Configuration Server model.
- config BLE_MESH_DF_CLI
- bool "Directed Forwarding Configuration Client model"
- help
- Enable support for Directed Forwarding Configuration Client model.
+ if BLE_MESH_DF_SRV
- config BLE_MESH_DF_SRV
- bool "Directed Forwarding Configuration Server model"
- help
- Enable support for Directed Forwarding Configuration Server model.
+ config BLE_MESH_MAX_DISC_TABLE_ENTRY_COUNT
+ int "Maximum number of discovery table entries in a given subnet"
+ range 2 255
+ default 2
+ help
+ Maximum number of Discovery Table entries supported by the node in a given subnet.
- if BLE_MESH_DF_SRV
+ config BLE_MESH_MAX_FORWARD_TABLE_ENTRY_COUNT
+ int "Maximum number of forward table entries in a given subnet"
+ range 2 64
+ default 2
+ help
+ Maximum number of Forward Table entries supported by the node in a given subnet.
- config BLE_MESH_MAX_DISC_TABLE_ENTRY_COUNT
- int "Maximum number of discovery table entries in a given subnet"
- range 2 255
- default 2
- help
- Maximum number of Discovery Table entries supported by the node in a given subnet.
+ config BLE_MESH_MAX_DEPS_NODES_PER_PATH
+ int "Maximum number of dependent nodes per path"
+ range 2 64
+ default 2
+ help
+ Maximum size of dependent nodes list supported by each forward table entry.
- config BLE_MESH_MAX_FORWARD_TABLE_ENTRY_COUNT
- int "Maximum number of forward table entries in a given subnet"
- range 2 64
- default 2
- help
- Maximum number of Forward Table entries supported by the node in a given subnet.
+ config BLE_MESH_PATH_MONITOR_TEST
+ bool "Enable Path Monitoring test mode"
+ default n
+ help
+ The option only removes the Path Use timer; all other behavior of the
+ device is not changed.
+ If Path Monitoring test mode is going to be used, this option should
+ be enabled.
- config BLE_MESH_MAX_DEPS_NODES_PER_PATH
- int "Maximum number of dependent nodes per path"
- range 2 64
- default 2
- help
- Maximum size of dependent nodes list supported by each forward table entry.
+ if BLE_MESH_GATT_PROXY_SERVER
+ config BLE_MESH_SUPPORT_DIRECTED_PROXY
+ bool "Enable Directed Proxy functionality"
+ default y
+ help
+ Support Directed Proxy functionality.
+ endif
- config BLE_MESH_PATH_MONITOR_TEST
- bool "Enable Path Monitoring test mode"
- default n
- help
- The option only removes the Path Use timer; all other behavior of the
- device is not changed.
- If Path Monitoring test mode is going to be used, this option should
- be enabled.
-
- if BLE_MESH_GATT_PROXY_SERVER
- config BLE_MESH_SUPPORT_DIRECTED_PROXY
- bool "Enable Directed Proxy functionality"
- default y
- help
- Support Directed Proxy functionality.
- endif
+ endif # BLE_MESH_DF_SRV
- endif # BLE_MESH_DF_SRV
+ endif # BLE_MESH_V11_SUPPORT
endmenu #Support for BLE Mesh Foundation models
@@ -1441,30 +1533,31 @@ if BLE_MESH
config BLE_MESH_GENERIC_SERVER
bool "Generic server models"
- default y
+ default n
help
Enable support for Generic server models.
config BLE_MESH_SENSOR_SERVER
bool "Sensor server models"
- default y
+ default n
help
Enable support for Sensor server models.
config BLE_MESH_TIME_SCENE_SERVER
bool "Time and Scenes server models"
- default y
+ default n
help
Enable support for Time and Scenes server models.
config BLE_MESH_LIGHTING_SERVER
bool "Lighting server models"
- default y
+ default n
help
Enable support for Lighting server models.
config BLE_MESH_MBT_CLI
bool "BLOB Transfer Client model"
+ depends on BLE_MESH_V11_SUPPORT
default n
help
Enable support for BLOB Transfer Client model.
@@ -1483,6 +1576,7 @@ if BLE_MESH
config BLE_MESH_MBT_SRV
bool "BLOB Transfer Server model"
+ depends on BLE_MESH_V11_SUPPORT
default n
help
Enable support for BLOB Transfer Server model.
@@ -1628,5 +1722,7 @@ if BLE_MESH
Make BLE Mesh Experimental features visible.
Experimental features list:
- CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG
+ - CONFIG_BLE_MESH_USE_BLE_50
+ - CONFIG_BLE_MESH_PROXY_CLI_SRV_COEXIST
endif # BLE_MESH
diff --git a/lib/bt/esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c b/lib/bt/esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c
index 559528e8..fcba1f4b 100644
--- a/lib/bt/esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c
+++ b/lib/bt/esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -12,14 +12,14 @@
#include "btc_ble_mesh_ble.h"
#include "esp_ble_mesh_ble_api.h"
-#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
+#if (CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50)
esp_err_t esp_ble_mesh_register_ble_callback(esp_ble_mesh_ble_cb_t callback)
{
ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED);
return (btc_profile_cb_set(BTC_PID_BLE_MESH_BLE_COEX, callback) == 0 ? ESP_OK : ESP_FAIL);
}
-#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT */
+#endif /* (CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50) */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
esp_err_t esp_ble_mesh_start_ble_advertising(const esp_ble_mesh_ble_adv_param_t *param,
@@ -100,3 +100,23 @@ esp_err_t esp_ble_mesh_stop_ble_scanning(void)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
+
+esp_err_t esp_ble_mesh_scan_params_update(esp_ble_mesh_scan_param_t *scan_param)
+{
+ btc_ble_mesh_ble_args_t arg = {0};
+ btc_msg_t msg = {0};
+
+ if (!scan_param) {
+ return ESP_FAIL;
+ }
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_BLE_MESH_BLE_COEX;
+ msg.act = BTC_BLE_MESH_ACT_UPDATE_SCAN_PARAMS;
+
+ arg.scan_params.scan_interval = scan_param->scan_interval;
+ arg.scan_params.uncoded_scan_window = scan_param->uncoded_scan_window;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_ble_args_t), NULL, NULL)
+ == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
diff --git a/lib/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c b/lib/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c
index 82128786..eaa18681 100644
--- a/lib/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c
+++ b/lib/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
diff --git a/lib/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_ble_api.h b/lib/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_ble_api.h
index 6818ba18..83d7e627 100644
--- a/lib/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_ble_api.h
+++ b/lib/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_ble_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -9,6 +9,10 @@
#include "esp_ble_mesh_defs.h"
+#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED
+#include "host/ble_gap.h"
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -20,9 +24,38 @@ typedef enum {
ESP_BLE_MESH_START_BLE_SCANNING_COMP_EVT, /*!< Start BLE scanning completion event */
ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT, /*!< Stop BLE scanning completion event */
ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT, /*!< Scanning BLE advertising packets event */
+ ESP_BLE_MESH_SCAN_PARAMS_UPDATE_COMP_EVT, /*!< Scan parameters update completion event */
+#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED
+ ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT, /*!< NIMBLE GAP event */
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED */
ESP_BLE_MESH_BLE_EVT_MAX,
} esp_ble_mesh_ble_cb_event_t;
+/** Context of BLE advertising report. */
+typedef struct {
+ uint8_t addr[6]; /*!< Device address */
+ uint8_t addr_type; /*!< Device address type */
+#if CONFIG_BLE_MESH_USE_BLE_50
+ uint8_t adv_type __attribute__((deprecated("`event_type` should be used to determine the advertising type"))); /*!< advertising type */
+#else
+ uint8_t adv_type; /*!< Advertising type */
+#endif
+ uint8_t *data; /*!< Advertising data */
+ uint16_t length; /*!< Advertising data length */
+ int8_t rssi; /*!< RSSI of the advertising packet */
+#if CONFIG_BLE_MESH_USE_BLE_50
+ uint8_t event_type; /*!< Extended advertising event type */
+ uint8_t primary_phy; /*!< Extended advertising primary PHY */
+ uint8_t secondary_phy; /*!< Extended advertising secondary PHY */
+ uint8_t sid; /*!< Extended advertising set ID */
+ uint8_t tx_power; /*!< Extended advertising TX power */
+ uint8_t dir_addr_type; /*!< Direct address type */
+ uint8_t dir_addr[6]; /*!< Direct address */
+ uint8_t data_status; /*!< Data type */
+ uint16_t per_adv_interval; /*!< Periodic advertising interval */
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+} esp_ble_mesh_ble_adv_rpt_t;
+
/** BLE operation callback parameters */
typedef union {
/**
@@ -52,16 +85,24 @@ typedef union {
int err_code; /*!< Indicate the result of stopping BLE scanning */
} stop_ble_scan_comp; /*!< Event parameters of ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT */
/**
- * @brief ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT
+ * @brief Event parameters of ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT
*/
- struct {
- uint8_t addr[6]; /*!< Device address */
- uint8_t addr_type; /*!< Device address type */
- uint8_t adv_type; /*!< Advertising data type */
- uint8_t *data; /*!< Advertising data */
- uint16_t length; /*!< Advertising data length */
- int8_t rssi; /*!< RSSI of the advertising packet */
- } scan_ble_adv_pkt; /*!< Event parameters of ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT */
+ esp_ble_mesh_ble_adv_rpt_t scan_ble_adv_pkt;
+ /**
+ * @brief Event parameter of ESP_BLE_MESH_SCAN_PARAMS_UPDATE_COMP_EVT
+ */
+ struct ble_mesh_scan_params_update_comp_param {
+ int err_code; /*!< Indicates the result of updating scan parameters */
+ } scan_params_update_comp; /*!< Event parameter of ESP_BLE_MESH_SCAN_PARAMS_UPDATE_COMP_EVT */
+#if CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED
+ /**
+ * @brief Event parameters of ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT
+ */
+ struct ble_mesh_nimble_gap_event_evt_param {
+ struct ble_gap_event event; /*!< GAP event parameters for NimBLE Host */
+ void *arg; /*!< User parameters */
+ } nimble_gap_evt; /*!< Event parameters of ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT */
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 && CONFIG_BT_NIMBLE_ENABLED */
} esp_ble_mesh_ble_cb_param_t;
/**
@@ -175,6 +216,33 @@ esp_err_t esp_ble_mesh_start_ble_scanning(esp_ble_mesh_ble_scan_param_t *param);
*/
esp_err_t esp_ble_mesh_stop_ble_scanning(void);
+/**
+ * @brief Update BLE Mesh scan parameters.
+ *
+ * @note
+ * 1. This function shall be used after ESP BLE Mesh is initialized!
+ * Parameters `scan_interval` and `uncoded_scan_window` must both
+ * be multiples of 8.
+ *
+ * 2. If the config BLE_MESH_USE_BLE_50 is enabled, within the scan_interval:
+ * - If uncoded_scan_window is not zero, the scan_interval is divided into
+ * two parts:
+ * - uncoded_scan_window: Used for performing uncoded scanning.
+ * - (scan_interval - uncoded_scan_window): The remaining time is
+ * used for coded scanning (coded_scan).
+ * - If uncoded_scan_window is set to 0, it means the entire scan_interval
+ * is used for coded scanning.
+ * - If uncoded_scan_window is equal to scan_interval, it means the entire
+ * scan_interval is used for uncoded scanning.
+ *
+ * @param[in] scan_param: Scan parameters
+ *
+ * @return
+ * - ESP_OK: Success
+ * - ESP_FAIL: Invalid parameters or unable transfer this command to the stack
+*/
+esp_err_t esp_ble_mesh_scan_params_update(esp_ble_mesh_scan_param_t *scan_param);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h b/lib/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h
index efbf2df5..188d6db2 100644
--- a/lib/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h
+++ b/lib/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -415,6 +415,29 @@ typedef struct {
bool erase_flash; /*!< Indicate if erasing flash when deinit mesh stack */
} esp_ble_mesh_deinit_param_t;
+/** Scan parameters */
+typedef struct {
+ /**
+ * Scan interval.
+ *
+ * Range: 0x0004 to 0x4000.
+ *
+ * Time = N * 0.625 ms. Time Range: 2.5 ms to 10.24 s
+ */
+ uint16_t scan_interval;
+
+ /**
+ * Uncoded Scan window.
+ *
+ * Time scanned on uncoded PHY within a scan interval.
+ *
+ * Range: 0x0004 to 0x4000.
+ *
+ * Time = N * 0.625 ms. Time Range: 2.5 ms to 10.24 s
+ */
+ uint16_t uncoded_scan_window;
+} esp_ble_mesh_scan_param_t;
+
/** Format of Unicast Address Range */
typedef struct {
uint16_t len_present:1, /*!< Indicate the presence or absence of the RangeLength field */
diff --git a/lib/bt/esp_ble_mesh/btc/btc_ble_mesh_ble.c b/lib/bt/esp_ble_mesh/btc/btc_ble_mesh_ble.c
index ead6c2cc..27699600 100644
--- a/lib/bt/esp_ble_mesh/btc/btc_ble_mesh_ble.c
+++ b/lib/bt/esp_ble_mesh/btc/btc_ble_mesh_ble.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -13,8 +13,7 @@
#include "mesh/adapter.h"
#include "esp_ble_mesh_ble_api.h"
-#if CONFIG_BLE_MESH_BLE_COEX_SUPPORT
-
+#if (CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50)
static void btc_ble_mesh_ble_copy_req_data(btc_msg_t *msg, void *p_dst, void *p_src)
{
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
@@ -29,6 +28,7 @@ static void btc_ble_mesh_ble_copy_req_data(btc_msg_t *msg, void *p_dst, void *p_
switch (msg->act) {
case ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT:
if (p_src_data->scan_ble_adv_pkt.data && p_src_data->scan_ble_adv_pkt.length) {
+ memcpy(&p_dst_data->scan_ble_adv_pkt, &p_src_data->scan_ble_adv_pkt, sizeof(p_src_data->scan_ble_adv_pkt));
p_dst_data->scan_ble_adv_pkt.length = p_src_data->scan_ble_adv_pkt.length;
p_dst_data->scan_ble_adv_pkt.data = bt_mesh_calloc(p_src_data->scan_ble_adv_pkt.length);
if (p_dst_data->scan_ble_adv_pkt.data) {
@@ -86,26 +86,34 @@ static void btc_ble_mesh_ble_callback(esp_ble_mesh_ble_cb_param_t *cb_params, ui
btc_ble_mesh_ble_copy_req_data, btc_ble_mesh_ble_free_req_data);
}
-#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
-void bt_mesh_ble_scan_cb_evt_to_btc(const bt_mesh_addr_t *addr,
- uint8_t adv_type, uint8_t data[],
- uint16_t length, int8_t rssi)
+#if CONFIG_BT_NIMBLE_ENABLED && CONFIG_BLE_MESH_USE_BLE_50
+void bt_mesh_ble_nimble_evt_to_btc(struct ble_gap_event *event, void *arg)
{
esp_ble_mesh_ble_cb_param_t param = {0};
- if (addr == NULL) {
+ if (event == NULL) {
BT_ERR("%s, Invalid parameter", __func__);
return;
}
- memcpy(param.scan_ble_adv_pkt.addr, addr->val, sizeof(addr->val));
- param.scan_ble_adv_pkt.addr_type = addr->type;
- if (data && length) {
- param.scan_ble_adv_pkt.data = data;
- param.scan_ble_adv_pkt.length = length;
+ memcpy(&param.nimble_gap_evt.event, event, sizeof(struct ble_gap_event));
+ param.nimble_gap_evt.arg = arg;
+
+ btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_NIMBLE_GAP_EVENT_EVT);
+}
+#endif /* CONFIG_BT_NIMBLE_ENABLED && CONFIG_BLE_MESH_USE_BLE_50 */
+
+#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
+void bt_mesh_ble_scan_cb_evt_to_btc(bt_mesh_ble_adv_report_t *adv_report)
+{
+ esp_ble_mesh_ble_cb_param_t param = {0};
+
+ if (adv_report == NULL) {
+ BT_ERR("%s, Invalid parameter", __func__);
+ return;
}
- param.scan_ble_adv_pkt.adv_type = adv_type;
- param.scan_ble_adv_pkt.rssi = rssi;
+
+ memcpy(&param.scan_ble_adv_pkt, adv_report, sizeof(bt_mesh_ble_adv_report_t));
btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_SCAN_BLE_ADVERTISING_PKT_EVT);
}
@@ -157,6 +165,14 @@ void btc_ble_mesh_ble_call_handler(btc_msg_t *msg)
btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_STOP_BLE_SCANNING_COMP_EVT);
break;
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
+ case BTC_BLE_MESH_ACT_UPDATE_SCAN_PARAMS:
+ struct bt_mesh_scan_param scan_param = {
+ .interval = arg->scan_params.scan_interval,
+ .window = arg->scan_params.uncoded_scan_window,
+ };
+ param.scan_params_update_comp.err_code = bt_mesh_scan_param_update(&scan_param);
+ btc_ble_mesh_ble_callback(&param, ESP_BLE_MESH_SCAN_PARAMS_UPDATE_COMP_EVT);
+ break;
default:
return;
}
@@ -191,5 +207,4 @@ void btc_ble_mesh_ble_cb_handler(btc_msg_t *msg)
btc_ble_mesh_ble_free_req_data(msg);
}
-
-#endif /* CONFIG_BLE_MESH_BLE_COEX_SUPPORT */
+#endif /* (CONFIG_BLE_MESH_BLE_COEX_SUPPORT || CONFIG_BLE_MESH_USE_BLE_50) */
diff --git a/lib/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c b/lib/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c
index 67d5353b..e8782500 100644
--- a/lib/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c
+++ b/lib/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c
@@ -10,11 +10,13 @@
#include "btc_ble_mesh_prov.h"
#include "btc_ble_mesh_config_model.h"
#include "btc_ble_mesh_health_model.h"
-#include "btc_ble_mesh_prb_model.h"
#include "btc_ble_mesh_generic_model.h"
#include "btc_ble_mesh_time_scene_model.h"
#include "btc_ble_mesh_sensor_model.h"
#include "btc_ble_mesh_lighting_model.h"
+
+#if CONFIG_BLE_MESH_V11_SUPPORT
+#include "btc_ble_mesh_prb_model.h"
#include "btc_ble_mesh_brc_model.h"
#include "btc_ble_mesh_odp_model.h"
#include "btc_ble_mesh_srpl_model.h"
@@ -24,8 +26,11 @@
#include "btc_ble_mesh_rpr_model.h"
#include "btc_ble_mesh_df_model.h"
#include "btc_ble_mesh_mbt_model.h"
+#include "mesh_v1.1/utils.h"
+#endif /* CONFIG_BLE_MESH_V11_SUPPORT */
#include "adv.h"
+#include "scan.h"
#include "mesh/kernel.h"
#include "mesh/proxy.h"
#include "mesh.h"
@@ -65,8 +70,6 @@
#include "mesh/state_binding.h"
#include "local.h"
-#include "mesh_v1.1/utils.h"
-
#include "esp_ble_mesh_common_api.h"
#include "esp_ble_mesh_provisioning_api.h"
#include "esp_ble_mesh_networking_api.h"
@@ -2946,6 +2949,7 @@ void btc_ble_mesh_model_call_handler(btc_msg_t *msg)
.ctx.send_tag = arg->model_send.ctx->send_tag,
.msg_timeout = arg->model_send.msg_timeout,
};
+
err = bt_mesh_client_send_msg(&param, buf, arg->model_send.need_rsp,
btc_ble_mesh_client_model_timeout_cb);
bt_mesh_free_buf(buf);
diff --git a/lib/bt/esp_ble_mesh/btc/include/btc_ble_mesh_ble.h b/lib/bt/esp_ble_mesh/btc/include/btc_ble_mesh_ble.h
index 8c63002a..e5d21df0 100644
--- a/lib/bt/esp_ble_mesh/btc/include/btc_ble_mesh_ble.h
+++ b/lib/bt/esp_ble_mesh/btc/include/btc_ble_mesh_ble.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -16,6 +16,30 @@
extern "C" {
#endif
+typedef struct {
+ uint8_t addr[6]; /*!< Device address */
+ uint8_t addr_type; /*!< Device address type */
+#if CONFIG_BLE_MESH_USE_BLE_50
+ uint8_t adv_type __attribute__((deprecated("`event_type` should be used to determine the advertising type"))); /*!< advertising type */
+#else
+ uint8_t adv_type; /*!< Advertising type */
+#endif
+ uint8_t *data; /*!< Advertising data */
+ uint16_t length; /*!< Advertising data length */
+ int8_t rssi; /*!< RSSI of the advertising packet */
+#if CONFIG_BLE_MESH_USE_BLE_50
+ uint8_t event_type; /*!< Extended advertising event type */
+ uint8_t primary_phy; /*!< Extended advertising primary PHY */
+ uint8_t secondary_phy; /*!< Extended advertising secondary PHY */
+ uint8_t sid; /*!< Extended advertising set ID */
+ uint8_t tx_power; /*!< Extended advertising TX power */
+ uint8_t dir_addr_type; /*!< Direct address type */
+ uint8_t dir_addr[6]; /*!< Direct address */
+ uint8_t data_status; /*!< Data type */
+ uint16_t per_adv_interval; /*!< Periodic advertising interval */
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+} bt_mesh_ble_adv_report_t;
+
typedef union {
struct {
esp_ble_mesh_ble_adv_param_t param;
@@ -30,6 +54,10 @@ typedef union {
struct {
/* RFU */
} stop_ble_scan;
+ struct ble_mesh_scan_params {
+ uint16_t scan_interval;
+ uint16_t uncoded_scan_window;
+ } scan_params;
} btc_ble_mesh_ble_args_t;
typedef enum {
@@ -37,11 +65,14 @@ typedef enum {
BTC_BLE_MESH_ACT_STOP_BLE_ADV,
BTC_BLE_MESH_ACT_START_BLE_SCAN,
BTC_BLE_MESH_ACT_STOP_BLE_SCAN,
+ BTC_BLE_MESH_ACT_UPDATE_SCAN_PARAMS,
} btc_ble_mesh_ble_act_t;
-void bt_mesh_ble_scan_cb_evt_to_btc(const bt_mesh_addr_t *addr,
- uint8_t adv_type, uint8_t data[],
- uint16_t length, int8_t rssi);
+void bt_mesh_ble_scan_cb_evt_to_btc(bt_mesh_ble_adv_report_t *adv_report);
+
+#if CONFIG_BT_NIMBLE_ENABLED && CONFIG_BLE_MESH_USE_BLE_50
+void bt_mesh_ble_nimble_evt_to_btc(struct ble_gap_event *event, void *arg);
+#endif /* CONFIG_BT_NIMBLE_ENABLED && CONFIG_BLE_MESH_USE_BLE_50 */
void btc_ble_mesh_ble_call_handler(btc_msg_t *msg);
diff --git a/lib/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h b/lib/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h
index f2777927..741a6b31 100644
--- a/lib/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h
+++ b/lib/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
diff --git a/lib/bt/esp_ble_mesh/common/atomic.c b/lib/bt/esp_ble_mesh/common/atomic.c
index 723ce7e3..9c856cc3 100644
--- a/lib/bt/esp_ble_mesh/common/atomic.c
+++ b/lib/bt/esp_ble_mesh/common/atomic.c
@@ -13,7 +13,7 @@
/*
* SPDX-FileCopyrightText: 2016 Intel Corporation
* SPDX-FileCopyrightText: 2011-2014 Wind River Systems, Inc.
- * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -170,4 +170,18 @@ bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target)
return ret;
}
+bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val)
+{
+ bt_mesh_atomic_lock();
+
+ if (*target == excepted) {
+ *target = new_val;
+ bt_mesh_atomic_unlock();
+ return true;
+ }
+
+ bt_mesh_atomic_unlock();
+ return false;
+}
+
#endif /* #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/atomic.h b/lib/bt/esp_ble_mesh/common/include/mesh/atomic.h
index f7283436..b2849743 100644
--- a/lib/bt/esp_ble_mesh/common/include/mesh/atomic.h
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/atomic.h
@@ -148,6 +148,33 @@ extern bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh
#endif
/**
+ * @brief Atomic CAS operation.
+ *
+ * This compares the contents of @a *target
+ * with the contents of @a excepted. If equal,
+ * the operation is a read-modify-write operation
+ * that writes @a new_val into @a *target and return true.
+ * If they are not equal, the operation is a read
+ * and return false.
+ *
+ * @param target Address of atomic variable.
+ * @param excepted Value of excepted.
+ * @param new_val Write if target value is equal to expected one.
+ *
+ * @return
+ * - true: Target value updated.
+ * - false: Target value not updated.
+ */
+#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN
+static inline bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val)
+{
+ return __atomic_compare_exchange_n(target, &excepted, &new_val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
+}
+#else
+extern bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val);
+#endif
+
+/**
* @cond INTERNAL_HIDDEN
*/
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/mutex.h b/lib/bt/esp_ble_mesh/common/include/mesh/mutex.h
index ee897500..0cc47eb0 100644
--- a/lib/bt/esp_ble_mesh/common/include/mesh/mutex.h
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/mutex.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -32,6 +32,11 @@ void bt_mesh_r_mutex_free(bt_mesh_mutex_t *mutex);
void bt_mesh_r_mutex_lock(bt_mesh_mutex_t *mutex);
void bt_mesh_r_mutex_unlock(bt_mesh_mutex_t *mutex);
+void bt_mesh_c_semaphore_create(bt_mesh_mutex_t *mutex, int max, int init);
+void bt_mesh_c_semaphore_free(bt_mesh_mutex_t *mutex);
+void bt_mesh_c_semaphore_give(bt_mesh_mutex_t *mutex);
+void bt_mesh_c_semaphore_take(bt_mesh_mutex_t *mutex, uint32_t timeout);
+
void bt_mesh_alarm_lock(void);
void bt_mesh_alarm_unlock(void);
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/queue.h b/lib/bt/esp_ble_mesh/common/include/mesh/queue.h
new file mode 100644
index 00000000..021c99ba
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/queue.h
@@ -0,0 +1,33 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_QUEUE_H_
+#define _BLE_MESH_QUEUE_H_
+
+#include "mesh/kernel.h"
+#include "mesh/slist.h"
+#include "mesh/atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ QueueHandle_t handle;
+#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
+ StaticQueue_t *buffer;
+ uint8_t *storage;
+#endif
+} bt_mesh_queue_t;
+
+int bt_mesh_queue_init(bt_mesh_queue_t *queue, uint16_t queue_size, uint8_t item_size);
+int bt_mesh_queue_deinit(bt_mesh_queue_t *queue);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_QUEUE_H_ */
diff --git a/lib/bt/esp_ble_mesh/common/include/mesh/utils.h b/lib/bt/esp_ble_mesh/common/include/mesh/utils.h
index 98243483..967fed2e 100644
--- a/lib/bt/esp_ble_mesh/common/include/mesh/utils.h
+++ b/lib/bt/esp_ble_mesh/common/include/mesh/utils.h
@@ -200,7 +200,7 @@ extern "C" {
* { MY_PWM0 , MY_PWM1 }
*
* @param LEN The length of the sequence. Must be an integer literal less
- * than 255.
+ * than 255 (ref: utils_loops.h).
* @param F A macro function that accepts at least two arguments:
* <tt>F(i, ...)</tt>. @p F is called repeatedly in the expansion.
* Its first argument @p i is the index in the sequence, and
diff --git a/lib/bt/esp_ble_mesh/common/mutex.c b/lib/bt/esp_ble_mesh/common/mutex.c
index 6c3b2bf6..3a3dedb8 100644
--- a/lib/bt/esp_ble_mesh/common/mutex.c
+++ b/lib/bt/esp_ble_mesh/common/mutex.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -125,6 +125,57 @@ void bt_mesh_r_mutex_unlock(bt_mesh_mutex_t *mutex)
}
}
+void bt_mesh_c_semaphore_free(bt_mesh_mutex_t *mutex)
+{
+ bt_mesh_mutex_free(mutex);
+}
+
+void bt_mesh_c_semaphore_create(bt_mesh_mutex_t *mutex, int max, int init)
+{
+ if (!mutex) {
+ BT_ERR("Create, invalid mutex");
+ return;
+ }
+
+#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
+#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
+ mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
+ mutex->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+#endif
+ __ASSERT(mutex->buffer, "Failed to create counting semaphore buffer");
+ mutex->mutex = xSemaphoreCreateCountingStatic(max, init, mutex->buffer);
+ __ASSERT(mutex->mutex, "Failed to create static counting semaphore");
+#else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
+ mutex->mutex = xSemaphoreCreateCounting(max, init);
+ __ASSERT(mutex->mutex, "Failed to create counting semaphore");
+#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
+}
+
+void bt_mesh_c_semaphore_take(bt_mesh_mutex_t *mutex, uint32_t timeout)
+{
+ if (!mutex) {
+ BT_ERR("Lock, invalid counting semaphore");
+ return;
+ }
+
+ if (mutex->mutex) {
+ xSemaphoreTake(mutex->mutex, timeout / portTICK_PERIOD_MS);
+ }
+}
+
+void bt_mesh_c_semaphore_give(bt_mesh_mutex_t *mutex)
+{
+ if (!mutex) {
+ BT_ERR("Unlock, invalid counting semaphore");
+ return;
+ }
+
+ if (mutex->mutex) {
+ xSemaphoreGive(mutex->mutex);
+ }
+}
+
void bt_mesh_alarm_lock(void)
{
bt_mesh_mutex_lock(&alarm_lock);
diff --git a/lib/bt/esp_ble_mesh/common/queue.c b/lib/bt/esp_ble_mesh/common/queue.c
new file mode 100644
index 00000000..1fc3d66a
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/common/queue.c
@@ -0,0 +1,48 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "mesh/common.h"
+#include "mesh/queue.h"
+
+int bt_mesh_queue_init(bt_mesh_queue_t *queue, uint16_t queue_size, uint8_t item_size)
+{
+ __ASSERT(queue && queue_size && item_size, "Invalid queue init parameters");
+
+#if !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
+ queue->handle = xQueueCreate(queue_size, item_size);
+ __ASSERT(queue->handle, "Failed to create queue");
+#else /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
+#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
+ queue->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
+ queue->buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+#endif
+ __ASSERT(queue->buffer, "Failed to create queue buffer");
+#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
+ queue->storage = heap_caps_calloc_prefer(1, (queue_size * item_size), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
+ queue->storage = heap_caps_calloc_prefer(1, (queue_size * item_size), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+#endif
+ __ASSERT(queue->storage, "Failed to create queue storage");
+ queue->handle = xQueueCreateStatic(queue_size, item_size, (uint8_t*)queue->storage, queue->buffer);
+ __ASSERT(queue->handle, "Failed to create static queue");
+#endif /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
+ return 0;
+}
+
+int bt_mesh_queue_deinit(bt_mesh_queue_t *queue)
+{
+ __ASSERT(queue, "Invalid queue init parameters");
+ vQueueDelete(queue->handle);
+ queue->handle = NULL;
+#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
+ heap_caps_free(queue->buffer);
+ queue->buffer = NULL;
+ heap_caps_free(queue->storage);
+ queue->storage = NULL;
+#endif
+ return 0;
+}
diff --git a/lib/bt/esp_ble_mesh/core/access.c b/lib/bt/esp_ble_mesh/core/access.c
index 9606581e..3791add9 100644
--- a/lib/bt/esp_ble_mesh/core/access.c
+++ b/lib/bt/esp_ble_mesh/core/access.c
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -11,6 +11,7 @@
#include <errno.h>
#include "mesh.h"
+#include "tag.h"
#include "adv.h"
#include "lpn.h"
#include "friend.h"
@@ -22,7 +23,9 @@
#include "fast_prov.h"
#include "pvnr_mgmt.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#define BLE_MESH_SDU_MAX_LEN 384
@@ -814,6 +817,135 @@ static bool ready_to_send(uint16_t dst)
return false;
}
+#if !CONFIG_BLE_MESH_V11_SUPPORT
+static bool use_friend_cred(uint16_t net_idx, uint16_t dst)
+{
+ /* Currently LPN only supports using NetKey in bt_mesh.sub[0] */
+ if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) &&
+ net_idx == 0 &&
+ bt_mesh_lpn_match(dst)) {
+ return true;
+ }
+
+ if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) &&
+ bt_mesh_friend_match(net_idx, dst)) {
+ return true;
+ }
+
+ return false;
+}
+
+bool bt_mesh_valid_security_cred(struct bt_mesh_net_tx *tx)
+{
+ /* If the message is tagged with immutable-credentials,
+ * then the security credentials shall not be changed
+ * in lower layers.
+ * If not, later a better security credentials could be
+ * chosen for the message.
+ */
+ if (!bt_mesh_tag_immutable_cred(tx->ctx->send_tag)) {
+ return true;
+ }
+
+ if (tx->ctx->send_cred > BLE_MESH_FRIENDSHIP_CRED) {
+ return false;
+ }
+
+ if (tx->ctx->send_cred == BLE_MESH_FRIENDSHIP_CRED &&
+ !use_friend_cred(tx->ctx->net_idx, tx->ctx->addr)) {
+ return false;
+ }
+
+ return true;
+}
+
+void bt_mesh_choose_better_security_cred(struct bt_mesh_net_tx *tx)
+{
+ uint8_t send_cred = 0U;
+ uint8_t send_tag = 0U;
+ uint16_t net_idx = 0U;
+ uint16_t addr = 0U;
+
+ send_cred = tx->ctx->send_cred;
+ send_tag = tx->ctx->send_tag;
+ net_idx = tx->ctx->net_idx;
+ addr = tx->ctx->addr;
+
+ /* If the message is tagged with immutable-credentials,
+ * then the security credentials shall not be changed.
+ */
+ if (bt_mesh_tag_immutable_cred(send_tag)) {
+ return;
+ }
+
+ if (send_cred > BLE_MESH_FRIENDSHIP_CRED) {
+ BT_INFO("Use managed flooding security credentials");
+ tx->ctx->send_cred = BLE_MESH_FLOODING_CRED;
+ return;
+ }
+
+ if (send_cred == BLE_MESH_FRIENDSHIP_CRED) {
+ if (!use_friend_cred(net_idx, addr)) {
+ BT_INFO("Use managed flooding security credentials");
+ tx->ctx->send_cred = BLE_MESH_FLOODING_CRED;
+ tx->ctx->send_tag = send_tag | BLE_MESH_TAG_IMMUTABLE_CRED;
+ } else {
+ /* TODO:
+ * For LPN, do we need to change the friendship security
+ * credentials to managed flooding credentials?
+ * If changed, this could increase the possibility that
+ * the corresponding Friend node receives this message.
+ */
+ }
+ return;
+ }
+
+ /* If the message is destinated to a LPN, the following could be
+ * introduced to send the message with the friendship credentials.
+ *
+ * For LPN, this optimization should not be introduced, since it
+ * may cause the message failed to received by the Friend node,
+ * using friendship credentials will make the message can not be
+ * relayed by other mesh nodes.
+ */
+ if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) &&
+ BLE_MESH_ADDR_IS_UNICAST(addr) &&
+ bt_mesh_friend_match(net_idx, addr)) {
+ BT_INFO("Use friendship security credentials");
+ tx->ctx->send_cred = BLE_MESH_FRIENDSHIP_CRED;
+ tx->ctx->send_tag = send_tag | BLE_MESH_TAG_IMMUTABLE_CRED;
+ return;
+ }
+
+ /**
+ * Spec 3.7.3.1
+ * The Low power node in friendship should use friendship security
+ * material.
+ *
+ * But in Spec 3.6.6.2
+ * Depending on the value of the Publish Friendship Credentials Flag
+ * (see Section 4.2.3.4), the Low Power node model publishes messages
+ * using either the friendship security credentials or the managed
+ * flooding security credentials (see Section 3.9.6.3.1).
+ *
+ * So use the BLE_MESH_TAG_IMMUTABLE_CRED to indicate that the
+ * credentials of the message should not be changed when the
+ * message is sent by model publishing, even though the spec
+ * didn't require this flag to be set when model publishing.
+ */
+
+#if CONFIG_BLE_MESH_LOW_POWER
+ if (BLE_MESH_ADDR_IS_UNICAST(addr) &&
+ bt_mesh.lpn.frnd == addr &&
+ !bt_mesh_tag_immutable_cred(send_tag)) {
+ tx->ctx->send_cred = BLE_MESH_FRIENDSHIP_CRED;
+ tx->ctx->send_tag = send_tag | BLE_MESH_TAG_IMMUTABLE_CRED;
+ return;
+ }
+#endif
+}
+#endif /* !CONFIG_BLE_MESH_V11_SUPPORT */
+
static int model_send(struct bt_mesh_model *model,
struct bt_mesh_net_tx *tx, bool implicit_bind,
struct net_buf_simple *msg,
@@ -1108,11 +1240,13 @@ size_t bt_mesh_rx_devkey_size(void)
#if CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER
if (bt_mesh_is_provisioned()) {
size = 1;
+#if CONFIG_BLE_MESH_RPR_SRV
if (bt_mesh_dev_key_ca_valid()) {
size += 1;
}
+#endif /* CONFIG_BLE_MESH_RPR_SRV */
}
-#endif
+#endif /* CONFIG_BLE_MESH_NODE && !CONFIG_BLE_MESH_PROVISIONER */
#if !CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER
if (bt_mesh_is_provisioner_en()) {
@@ -1122,9 +1256,11 @@ size_t bt_mesh_rx_devkey_size(void)
#if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER
size = 1;
+#if CONFIG_BLE_MESH_RPR_SRV
if (bt_mesh_dev_key_ca_valid()) {
size += 1;
}
+#endif /* CONFIG_BLE_MESH_RPR_SRV */
if (bt_mesh_is_provisioner_en()) {
size += 1;
}
@@ -1156,7 +1292,9 @@ const uint8_t *bt_mesh_rx_devkey_get(size_t index, uint16_t src)
#if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PROVISIONER
if (index == 0) {
key = bt_mesh.dev_key;
- } else if (index == 1 && bt_mesh_dev_key_ca_valid()) {
+ } else
+#if CONFIG_BLE_MESH_RPR_SRV
+ if (index == 1 && bt_mesh_dev_key_ca_valid()) {
/* If index == 1, there are two cases.
* 1. bt_mesh_dev_key_ca_valid() is true, it should be return bt_mesh.dev_key_ca.
* 2. bt_mesh_is_provisioner_en() is true, it should be return bt_mesh_provisioner_dev_key_get(src).
@@ -1166,7 +1304,9 @@ const uint8_t *bt_mesh_rx_devkey_get(size_t index, uint16_t src)
* Then this round of function bt_mesh_rx_devkey_get(2, src) will return bt_mesh_provisioner_dev_key_get(src).
*/
key = bt_mesh.dev_key_ca;
- } else {
+ } else
+#endif
+ {
key = bt_mesh_provisioner_dev_key_get(src);
}
#endif
diff --git a/lib/bt/esp_ble_mesh/core/adv.c b/lib/bt/esp_ble_mesh/core/adv.c
index dbbda0ab..54efa0d4 100644
--- a/lib/bt/esp_ble_mesh/core/adv.c
+++ b/lib/bt/esp_ble_mesh/core/adv.c
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2018-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -23,110 +23,20 @@
#include "proxy_client.h"
#include "prov_pvnr.h"
#include "mesh/adapter.h"
+#include "adv_common.h"
+#include "ble_adv.h"
-/* Convert from ms to 0.625ms units */
-#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5)
-/* Convert from 0.625ms units to interval(ms) */
-#define ADV_SCAN_INT(val) ((val) * 5 / 8)
-
-/* Pre-5.0 controllers enforce a minimum interval of 100ms
- * whereas 5.0+ controllers can go down to 20ms.
- */
-#if CONFIG_BLE_MESH_HCI_5_0
-#define ADV_ITVL_MIN 20
-#else
-#define ADV_ITVL_MIN 100
-#endif
-
-static const uint8_t adv_type[] = {
- [BLE_MESH_ADV_PROV] = BLE_MESH_DATA_MESH_PROV,
- [BLE_MESH_ADV_DATA] = BLE_MESH_DATA_MESH_MESSAGE,
- [BLE_MESH_ADV_BEACON] = BLE_MESH_DATA_MESH_BEACON,
- [BLE_MESH_ADV_URI] = BLE_MESH_DATA_URI,
-};
-
-NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BLE_MESH_ADV_BUF_COUNT,
- BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
-
-static struct bt_mesh_adv adv_pool[CONFIG_BLE_MESH_ADV_BUF_COUNT];
-
-struct bt_mesh_queue {
- QueueHandle_t handle;
-#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
- StaticQueue_t *buffer;
- uint8_t *storage;
-#endif
-};
-
-static struct bt_mesh_queue adv_queue;
-/* We reserve one queue item for bt_mesh_adv_update() */
-#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
-#define BLE_MESH_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_ADV_BUF_COUNT + CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT + 1)
-#else
-#define BLE_MESH_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_ADV_BUF_COUNT + 1)
-#endif
+static struct bt_mesh_adv_queue *adv_queue;
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
-NET_BUF_POOL_DEFINE(relay_adv_buf_pool, CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT,
- BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
-static struct bt_mesh_adv relay_adv_pool[CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT];
-
-static struct bt_mesh_queue relay_queue;
#define BLE_MESH_RELAY_QUEUE_SIZE CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT
static QueueSetHandle_t mesh_queue_set;
#define BLE_MESH_QUEUE_SET_SIZE (BLE_MESH_ADV_QUEUE_SIZE + BLE_MESH_RELAY_QUEUE_SIZE)
-#define BLE_MESH_RELAY_TIME_INTERVAL K_SECONDS(6)
-#define BLE_MESH_MAX_TIME_INTERVAL 0xFFFFFFFF
-
-static bool ignore_relay_packet(uint32_t timestamp);
#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
-#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
-/* length + advertising data + length + scan response data */
-NET_BUF_POOL_DEFINE(ble_adv_buf_pool, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT,
- ((BLE_MESH_ADV_DATA_SIZE + 3) << 1), BLE_MESH_ADV_USER_DATA_SIZE, NULL);
-
-static struct bt_mesh_adv ble_adv_pool[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
-
-enum {
- TIMER_INIT, /* Resend timer is initialized */
- NUM_FLAGS,
-};
-
-static struct ble_adv_tx {
- struct bt_mesh_ble_adv_param param;
- struct net_buf *buf;
- struct k_delayed_work resend;
- BLE_MESH_ATOMIC_DEFINE(flags, NUM_FLAGS);
-} ble_adv_tx[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
-
-#define SEND_BLE_ADV_INFINITE 0xFFFF
-
-#if CONFIG_BLE_MESH_DEINIT
-static void bt_mesh_ble_adv_deinit(void);
-#endif /* CONFIG_BLE_MESH_DEINIT */
-#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
-
-struct bt_mesh_adv_task {
- TaskHandle_t handle;
-#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
- (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
- CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
- StaticTask_t *task;
- StackType_t *stack;
-#endif
-};
-
-static struct bt_mesh_adv_task adv_task;
-
-static struct bt_mesh_adv *adv_alloc(int id)
-{
- return &adv_pool[id];
-}
-
static inline void adv_send_start(uint16_t duration, int err,
const struct bt_mesh_send_cb *cb,
void *cb_data)
@@ -144,17 +54,6 @@ static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb,
}
}
-uint16_t bt_mesh_pdu_duration(uint8_t xmit)
-{
- uint16_t duration = 0U;
- uint16_t adv_int = 0U;
-
- adv_int = MAX(ADV_ITVL_MIN, BLE_MESH_TRANSMIT_INT(xmit));
- duration = (BLE_MESH_TRANSMIT_COUNT(xmit) + 1) * (adv_int + 10);
-
- return duration;
-}
-
static inline int adv_send(struct net_buf *buf)
{
const struct bt_mesh_send_cb *cb = BLE_MESH_ADV(buf)->cb;
@@ -187,25 +86,41 @@ static inline int adv_send(struct net_buf *buf)
param.interval_min = ADV_SCAN_UNIT(adv_int);
param.interval_max = param.interval_min;
+#if CONFIG_BLE_MESH_USE_BLE_50
+ param.adv_duration = duration;
+ param.adv_count = BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1;
+#endif
+
#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
if (BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_PROXY_SOLIC) {
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
- struct bt_mesh_adv_data solic_ad[3] = {
- BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_FLAGS, (BLE_MESH_AD_GENERAL | BLE_MESH_AD_NO_BREDR)),
+ struct bt_mesh_adv_data solic_ad[2] = {
BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_UUID16_ALL, 0x59, 0x18),
BLE_MESH_ADV_DATA(BLE_MESH_DATA_SVC_DATA16, buf->data, buf->len),
};
- err = bt_le_adv_start(&param, solic_ad, 3, NULL, 0);
+#if CONFIG_BLE_MESH_USE_BLE_50
+ param.primary_phy = BLE_MESH_ADV_PHY_1M;
+ param.secondary_phy = BLE_MESH_ADV_PHY_1M;
+ err = bt_le_ext_adv_start(CONFIG_BLE_MESH_ADV_INST_ID, &param, solic_ad, ARRAY_SIZE(solic_ad), NULL, 0);
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
+ err = bt_le_adv_start(&param, solic_ad, ARRAY_SIZE(solic_ad), NULL, 0);
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
} else
#endif
{
bt_mesh_adv_buf_ref_debug(__func__, buf, 4U, BLE_MESH_BUF_REF_SMALL);
+#if CONFIG_BLE_MESH_USE_BLE_50
+ param.primary_phy = BLE_MESH_ADV_PHY_1M;
+ param.secondary_phy = BLE_MESH_ADV_PHY_1M;
+ err = bt_le_ext_adv_start(CONFIG_BLE_MESH_ADV_INST_ID, &param, &ad, 1, NULL, 0);
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
err = bt_le_adv_start(&param, &ad, 1, NULL, 0);
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
}
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
} else {
struct bt_mesh_ble_adv_data data = {0};
- struct ble_adv_tx *tx = cb_data;
+ struct bt_mesh_ble_adv_tx *tx = cb_data;
if (tx == NULL) {
BT_ERR("Invalid adv user data");
@@ -229,7 +144,11 @@ static inline int adv_send(struct net_buf *buf)
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
+#if CONFIG_BLE_MESH_USE_BLE_50
+ err = bt_mesh_ble_ext_adv_start(CONFIG_BLE_MESH_ADV_INST_ID, &tx->param, &data);
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
err = bt_mesh_ble_adv_start(&tx->param, &data);
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
@@ -242,9 +161,19 @@ static inline int adv_send(struct net_buf *buf)
BT_DBG("Advertising started. Sleeping %u ms", duration);
- k_sleep(K_MSEC(duration));
+#if CONFIG_BLE_MESH_USE_BLE_50
+ if (!ble_mesh_adv_task_wait(UINT32_MAX, K_FOREVER, NULL)) {
+ BT_WARN("Advertising didn't finish on time");
+ bt_le_ext_adv_stop(CONFIG_BLE_MESH_ADV_INST_ID);
+ }
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
+ ble_mesh_adv_task_wait(K_MSEC(duration));
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+#if !CONFIG_BLE_MESH_USE_BLE_50
err = bt_le_adv_stop();
+#endif
+
adv_send_end(err, cb, cb_data);
if (err) {
BT_ERR("Stop advertising failed: err %d", err);
@@ -255,15 +184,12 @@ static inline int adv_send(struct net_buf *buf)
return 0;
}
-static inline TickType_t K_WAIT(int32_t val)
-{
- return (val == K_FOREVER) ? portMAX_DELAY : (val / portTICK_PERIOD_MS);
-}
-
static void adv_thread(void *p)
{
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
QueueSetMemberHandle_t handle = NULL;
+ QueueHandle_t relay_adv_handle =
+ bt_mesh_adv_types_mgnt_get(BLE_MESH_ADV_RELAY_DATA)->adv_q->q.handle;
#endif
bt_mesh_msg_t msg = {0};
struct net_buf **buf = NULL;
@@ -277,28 +203,28 @@ static void adv_thread(void *p)
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_SERVER
- xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
+ xQueueReceive(adv_queue->q.handle, &msg, K_NO_WAIT);
while (!(*buf)) {
int32_t timeout = 0;
BT_DBG("Mesh Proxy Advertising start");
timeout = bt_mesh_proxy_server_adv_start();
BT_DBG("Mesh Proxy Advertising up to %d ms", timeout);
- xQueueReceive(adv_queue.handle, &msg, K_WAIT(timeout));
+ xQueueReceive(adv_queue->q.handle, &msg, K_WAIT(timeout));
BT_DBG("Mesh Proxy Advertising stop");
bt_mesh_proxy_server_adv_stop();
}
#else
- xQueueReceive(adv_queue.handle, &msg, portMAX_DELAY);
+ xQueueReceive(adv_queue->q.handle, &msg, portMAX_DELAY);
#endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
#else /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_SERVER
handle = xQueueSelectFromSet(mesh_queue_set, K_NO_WAIT);
if (handle) {
- if (uxQueueMessagesWaiting(adv_queue.handle)) {
- xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
- } else if (uxQueueMessagesWaiting(relay_queue.handle)) {
- xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
+ if (uxQueueMessagesWaiting(adv_queue->q.handle)) {
+ xQueueReceive(adv_queue->q.handle, &msg, K_NO_WAIT);
+ } else if (uxQueueMessagesWaiting(relay_adv_handle)) {
+ xQueueReceive(relay_adv_handle, &msg, K_NO_WAIT);
}
} else {
while (!(*buf)) {
@@ -310,10 +236,10 @@ static void adv_thread(void *p)
BT_DBG("Mesh Proxy Advertising stop");
bt_mesh_proxy_server_adv_stop();
if (handle) {
- if (uxQueueMessagesWaiting(adv_queue.handle)) {
- xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
- } else if (uxQueueMessagesWaiting(relay_queue.handle)) {
- xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
+ if (uxQueueMessagesWaiting(adv_queue->q.handle)) {
+ xQueueReceive(adv_queue->q.handle, &msg, K_NO_WAIT);
+ } else if (uxQueueMessagesWaiting(relay_adv_handle)) {
+ xQueueReceive(relay_adv_handle, &msg, K_NO_WAIT);
}
}
}
@@ -321,10 +247,10 @@ static void adv_thread(void *p)
#else
handle = xQueueSelectFromSet(mesh_queue_set, portMAX_DELAY);
if (handle) {
- if (uxQueueMessagesWaiting(adv_queue.handle)) {
- xQueueReceive(adv_queue.handle, &msg, K_NO_WAIT);
- } else if (uxQueueMessagesWaiting(relay_queue.handle)) {
- xQueueReceive(relay_queue.handle, &msg, K_NO_WAIT);
+ if (uxQueueMessagesWaiting(adv_queue->q.handle)) {
+ xQueueReceive(adv_queue->q.handle, &msg, K_NO_WAIT);
+ } else if (uxQueueMessagesWaiting(relay_adv_handle)) {
+ xQueueReceive(relay_adv_handle, &msg, K_NO_WAIT);
}
}
#endif /* (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_SERVER */
@@ -335,14 +261,13 @@ static void adv_thread(void *p)
}
/* busy == 0 means this was canceled */
- if (BLE_MESH_ADV(*buf)->busy) {
- BLE_MESH_ADV(*buf)->busy = 0U;
+ if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(*buf), 1, 0)) {
#if !CONFIG_BLE_MESH_RELAY_ADV_BUF
if (adv_send(*buf)) {
BT_WARN("Failed to send adv packet");
}
#else /* !CONFIG_BLE_MESH_RELAY_ADV_BUF */
- if (msg.relay && ignore_relay_packet(msg.timestamp)) {
+ if (msg.relay && bt_mesh_ignore_relay_packet(msg.timestamp)) {
/* If the interval between "current time - msg.timestamp" is bigger than
* BLE_MESH_RELAY_TIME_INTERVAL, this relay packet will not be sent.
*/
@@ -364,119 +289,6 @@ static void adv_thread(void *p)
}
}
-struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool,
- bt_mesh_adv_alloc_t get_id,
- enum bt_mesh_adv_type type,
- int32_t timeout)
-{
- struct bt_mesh_adv *adv = NULL;
- struct net_buf *buf = NULL;
-
- if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_SUSPENDED)) {
- BT_WARN("Refusing to allocate buffer while suspended");
- return NULL;
- }
-
- buf = net_buf_alloc(pool, timeout);
- if (!buf) {
- return NULL;
- }
-
- BT_DBG("pool %p, buf_count %d, uinit_count %d",
- buf->pool, pool->buf_count, pool->uninit_count);
-
- adv = get_id(net_buf_id(buf));
- BLE_MESH_ADV(buf) = adv;
-
- (void)memset(adv, 0, sizeof(*adv));
-
- adv->type = type;
-
- return buf;
-}
-
-void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool)
-{
- int i;
-
- if (pool == NULL) {
- BT_ERR("%s, Invalid parameter", __func__);
- return;
- }
-
- for (i = 0; i < pool->buf_count; i++) {
- struct net_buf *buf = &pool->__bufs[i];
- if (buf->ref > 1U) {
- buf->ref = 1U;
- }
- net_buf_unref(buf);
- }
-}
-
-struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
-{
- return bt_mesh_adv_create_from_pool(&adv_buf_pool, adv_alloc,
- type, timeout);
-}
-
-void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
- uint8_t ref_cmp, bt_mesh_buf_ref_flag_t flag)
-{
- if (buf == NULL || func == NULL || flag >= BLE_MESH_BUF_REF_MAX) {
- BT_ERR("%s, Invalid parameter", __func__);
- return;
- }
-
- switch (flag) {
- case BLE_MESH_BUF_REF_EQUAL:
- if (buf->ref != ref_cmp) {
- BT_ERR("Unexpected ref %d in %s, expect to equal to %d", buf->ref, func, ref_cmp);
- }
- break;
- case BLE_MESH_BUF_REF_SMALL:
- if (buf->ref >= ref_cmp) {
- BT_ERR("Unexpected ref %d in %s, expect to smaller than %d", buf->ref, func, ref_cmp);
- }
- break;
- default:
- break;
- }
-}
-
-static void bt_mesh_unref_buf(bt_mesh_msg_t *msg)
-{
- struct net_buf *buf = NULL;
-
- if (msg->arg) {
- buf = (struct net_buf *)msg->arg;
- BLE_MESH_ADV(buf)->busy = 0U;
- if (buf->ref > 1U) {
- buf->ref = 1U;
- }
- net_buf_unref(buf);
- }
-}
-
-static void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
-{
- if (adv_queue.handle == NULL) {
- BT_ERR("Invalid adv queue");
- return;
- }
-
- if (front) {
- if (xQueueSendToFront(adv_queue.handle, msg, timeout) != pdTRUE) {
- BT_ERR("Failed to send item to adv queue front");
- bt_mesh_unref_buf(msg);
- }
- } else {
- if (xQueueSend(adv_queue.handle, msg, timeout) != pdTRUE) {
- BT_ERR("Failed to send item to adv queue back");
- bt_mesh_unref_buf(msg);
- }
- }
-}
-
void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
const struct bt_mesh_send_cb *cb,
void *cb_data)
@@ -490,7 +302,7 @@ void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
BLE_MESH_ADV(buf)->cb = cb;
BLE_MESH_ADV(buf)->cb_data = cb_data;
- BLE_MESH_ADV(buf)->busy = 1U;
+ bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
BLE_MESH_ADV(buf)->xmit = xmit;
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
@@ -509,476 +321,55 @@ void bt_mesh_adv_update(void)
bt_mesh_task_post(&msg, K_NO_WAIT, false);
}
-#if CONFIG_BLE_MESH_RELAY_ADV_BUF
-static bool ignore_relay_packet(uint32_t timestamp)
-{
- uint32_t now = k_uptime_get_32();
- uint32_t interval = 0U;
-
- if (now >= timestamp) {
- interval = now - timestamp;
- } else {
- interval = BLE_MESH_MAX_TIME_INTERVAL - (timestamp - now) + 1;
- }
-
- return (interval >= BLE_MESH_RELAY_TIME_INTERVAL) ? true : false;
-}
-
-static struct bt_mesh_adv *relay_adv_alloc(int id)
-{
- return &relay_adv_pool[id];
-}
-
-struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
-{
- return bt_mesh_adv_create_from_pool(&relay_adv_buf_pool, relay_adv_alloc,
- type, timeout);
-}
-
-static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout)
-{
- QueueSetMemberHandle_t handle = NULL;
- bt_mesh_msg_t old_msg = {0};
-
- if (relay_queue.handle == NULL) {
- BT_ERR("Invalid relay queue");
- return;
- }
-
- if (xQueueSend(relay_queue.handle, msg, timeout) == pdTRUE) {
- return;
- }
-
- /* If failed to send packet to the relay queue(queue is full), we will
- * remove the oldest packet in the queue and put the new one into it.
- */
- handle = xQueueSelectFromSet(mesh_queue_set, K_NO_WAIT);
- if (handle && uxQueueMessagesWaiting(relay_queue.handle)) {
- BT_INFO("Full queue, remove the oldest relay packet");
- /* Remove the oldest relay packet from queue */
- if (xQueueReceive(relay_queue.handle, &old_msg, K_NO_WAIT) != pdTRUE) {
- BT_ERR("Failed to remove item from relay queue");
- bt_mesh_unref_buf(msg);
- return;
- }
- /* Unref buf used for the oldest relay packet */
- bt_mesh_unref_buf(&old_msg);
- /* Send the latest relay packet to queue */
- if (xQueueSend(relay_queue.handle, msg, K_NO_WAIT) != pdTRUE) {
- BT_ERR("Failed to send item to relay queue");
- bt_mesh_unref_buf(msg);
- return;
- }
- } else {
- BT_WARN("Empty queue, but failed to send the relay packet");
- bt_mesh_unref_buf(msg);
- }
-}
-
-void bt_mesh_relay_adv_send(struct net_buf *buf, uint8_t xmit,
- uint16_t src, uint16_t dst,
- const struct bt_mesh_send_cb *cb,
- void *cb_data)
-{
- bt_mesh_msg_t msg = {
- .relay = true,
- };
-
- BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
- bt_hex(buf->data, buf->len));
-
- BLE_MESH_ADV(buf)->cb = cb;
- BLE_MESH_ADV(buf)->cb_data = cb_data;
- BLE_MESH_ADV(buf)->busy = 1U;
- BLE_MESH_ADV(buf)->xmit = xmit;
-
- msg.arg = (void *)net_buf_ref(buf);
- msg.src = src;
- msg.dst = dst;
- msg.timestamp = k_uptime_get_32();
- /* Use K_NO_WAIT here, if relay_queue is full return immediately */
- ble_mesh_relay_task_post(&msg, K_NO_WAIT);
-}
-
-uint16_t bt_mesh_get_stored_relay_count(void)
-{
- return (uint16_t)uxQueueMessagesWaiting(relay_queue.handle);
-}
-#endif /* #if CONFIG_BLE_MESH_RELAY_ADV_BUF */
-
void bt_mesh_adv_init(void)
{
-#if !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
- adv_queue.handle = xQueueCreate(BLE_MESH_ADV_QUEUE_SIZE, sizeof(bt_mesh_msg_t));
- __ASSERT(adv_queue.handle, "Failed to create queue");
-#else /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
-#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
- adv_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
-#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
- adv_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
-#endif
- __ASSERT(adv_queue.buffer, "Failed to create queue buffer");
-#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
- adv_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_ADV_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
-#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
- adv_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_ADV_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
-#endif
- __ASSERT(adv_queue.storage, "Failed to create queue storage");
- adv_queue.handle = xQueueCreateStatic(BLE_MESH_ADV_QUEUE_SIZE, sizeof(bt_mesh_msg_t), (uint8_t*)adv_queue.storage, adv_queue.buffer);
- __ASSERT(adv_queue.handle, "Failed to create static queue");
-#endif /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
-#if !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
- relay_queue.handle = xQueueCreate(BLE_MESH_RELAY_QUEUE_SIZE, sizeof(bt_mesh_msg_t));
- __ASSERT(relay_queue.handle, "Failed to create relay queue");
-#else /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
-#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
- relay_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
-#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
- relay_queue.buffer = heap_caps_calloc_prefer(1, sizeof(StaticQueue_t), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+ bt_mesh_relay_adv_init();
#endif
- __ASSERT(relay_queue.buffer, "Failed to create relay queue buffer");
-#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL
- relay_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_RELAY_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
-#elif CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_IRAM_8BIT
- relay_queue.storage = heap_caps_calloc_prefer(1, (BLE_MESH_RELAY_QUEUE_SIZE * sizeof(bt_mesh_msg_t)), 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+ bt_mesh_ble_adv_init();
#endif
- __ASSERT(relay_queue.storage, "Failed to create relay queue storage");
- relay_queue.handle = xQueueCreateStatic(BLE_MESH_RELAY_QUEUE_SIZE, sizeof(bt_mesh_msg_t), (uint8_t*)relay_queue.storage, relay_queue.buffer);
- __ASSERT(relay_queue.handle, "Failed to create static relay queue");
-#endif /* !CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
+ bt_mesh_adv_common_init();
+ adv_queue = bt_mesh_adv_queue_get();
+
+ assert(adv_queue && adv_queue->q.handle && adv_queue->send);
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF && !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ QueueHandle_t relay_adv_handle =
+ bt_mesh_adv_types_mgnt_get(BLE_MESH_ADV_RELAY_DATA)->adv_q->q.handle;
mesh_queue_set = xQueueCreateSet(BLE_MESH_QUEUE_SET_SIZE);
__ASSERT(mesh_queue_set, "Failed to create queue set");
- xQueueAddToSet(adv_queue.handle, mesh_queue_set);
- xQueueAddToSet(relay_queue.handle, mesh_queue_set);
-#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
+ xQueueAddToSet(adv_queue->q.handle, mesh_queue_set);
+ xQueueAddToSet(relay_adv_handle, mesh_queue_set);
+#endif
-#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
- (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
- CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
- adv_task.task = heap_caps_calloc(1, sizeof(StaticTask_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
- __ASSERT(adv_task.task, "Failed to create adv thread task");
- adv_task.stack = heap_caps_calloc_prefer(1, BLE_MESH_ADV_TASK_STACK_SIZE * sizeof(StackType_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
- __ASSERT(adv_task.stack, "Failed to create adv thread stack");
- adv_task.handle = xTaskCreateStaticPinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
- BLE_MESH_ADV_TASK_PRIO, adv_task.stack, adv_task.task, BLE_MESH_ADV_TASK_CORE);
- __ASSERT(adv_task.handle, "Failed to create static adv thread");
-#else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
- int ret = xTaskCreatePinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
- BLE_MESH_ADV_TASK_PRIO, &adv_task.handle, BLE_MESH_ADV_TASK_CORE);
- __ASSERT(ret == pdTRUE, "Failed to create adv thread");
- (void)ret;
-#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
+ bt_mesh_adv_task_init(adv_thread);
}
#if CONFIG_BLE_MESH_DEINIT
void bt_mesh_adv_deinit(void)
{
- if (adv_queue.handle == NULL) {
- return;
- }
-
- vTaskDelete(adv_task.handle);
- adv_task.handle = NULL;
-#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
- (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
- CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
- heap_caps_free(adv_task.stack);
- adv_task.stack = NULL;
- heap_caps_free(adv_task.task);
- adv_task.task = NULL;
-#endif
+ /* Adv task must be deinit first */
+ bt_mesh_adv_task_deinit();
#if CONFIG_BLE_MESH_RELAY_ADV_BUF
- xQueueRemoveFromSet(adv_queue.handle, mesh_queue_set);
- xQueueRemoveFromSet(relay_queue.handle, mesh_queue_set);
-
- vQueueDelete(relay_queue.handle);
- relay_queue.handle = NULL;
-#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
- heap_caps_free(relay_queue.buffer);
- relay_queue.buffer = NULL;
- heap_caps_free(relay_queue.storage);
- relay_queue.storage = NULL;
-#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
-
- bt_mesh_unref_buf_from_pool(&relay_adv_buf_pool);
- memset(relay_adv_pool, 0, sizeof(relay_adv_pool));
+ QueueHandle_t relay_adv_handle =
+ bt_mesh_adv_types_mgnt_get(BLE_MESH_ADV_RELAY_DATA)->adv_q->q.handle;
+ xQueueRemoveFromSet(adv_queue->q.handle, mesh_queue_set);
+ xQueueRemoveFromSet(relay_adv_handle, mesh_queue_set);
vQueueDelete(mesh_queue_set);
mesh_queue_set = NULL;
-#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
- vQueueDelete(adv_queue.handle);
- adv_queue.handle = NULL;
-#if CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC
- heap_caps_free(adv_queue.buffer);
- adv_queue.buffer = NULL;
- heap_caps_free(adv_queue.storage);
- adv_queue.storage = NULL;
-#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC */
-
- bt_mesh_unref_buf_from_pool(&adv_buf_pool);
- memset(adv_pool, 0, sizeof(adv_pool));
+ bt_mesh_relay_adv_deinit();
+#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
bt_mesh_ble_adv_deinit();
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
-}
-#endif /* CONFIG_BLE_MESH_DEINIT */
-
-#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
-static struct bt_mesh_adv *ble_adv_alloc(int id)
-{
- return &ble_adv_pool[id];
-}
-
-static struct net_buf *bt_mesh_ble_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
-{
- return bt_mesh_adv_create_from_pool(&ble_adv_buf_pool, ble_adv_alloc,
- type, timeout);
-}
-
-static void bt_mesh_ble_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
- void *cb_data, bool front)
-{
- bt_mesh_msg_t msg = {
- .relay = false,
- };
-
- BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
- bt_hex(buf->data, buf->len));
-
- BLE_MESH_ADV(buf)->cb = cb;
- BLE_MESH_ADV(buf)->cb_data = cb_data;
- BLE_MESH_ADV(buf)->busy = 1U;
-
- bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
-
- msg.arg = (void *)net_buf_ref(buf);
- bt_mesh_task_post(&msg, portMAX_DELAY, front);
-}
-
-static void ble_adv_tx_reset(struct ble_adv_tx *tx, bool unref)
-{
- if (tx->buf == NULL) {
- return;
- }
-
- if (bt_mesh_atomic_test_bit(tx->flags, TIMER_INIT)) {
- k_delayed_work_free(&tx->resend);
- }
- bt_mesh_atomic_set(tx->flags, 0);
- memset(&tx->param, 0, sizeof(tx->param));
- BLE_MESH_ADV(tx->buf)->busy = 0U;
- if (unref) {
- net_buf_unref(tx->buf);
- }
- tx->buf = NULL;
-}
-
-static void ble_adv_send_start(uint16_t duration, int err, void *cb_data)
-{
- struct ble_adv_tx *tx = cb_data;
-
- BT_DBG("%s, duration %d, err %d", __func__, duration, err);
-
- /* If failed to send BLE adv packet, and param->count is not 0
- * which means the timer has been initialized, here we need to
- * free the timer.
- */
- if (err) {
- ble_adv_tx_reset(tx, true);
- }
-}
-
-static void ble_adv_send_end(int err, void *cb_data)
-{
- struct ble_adv_tx *tx = cb_data;
-
- BT_DBG("%s, err %d", __func__, err);
-
- if (err) {
- ble_adv_tx_reset(tx, true);
- return;
- }
-
- if (tx->param.count) {
- k_delayed_work_submit(&tx->resend, tx->param.period);
- } else {
- ble_adv_tx_reset(tx, true);
- }
-}
-
-static struct bt_mesh_send_cb ble_adv_send_cb = {
- .start = ble_adv_send_start,
- .end = ble_adv_send_end,
-};
-
-static void ble_adv_resend(struct k_work *work)
-{
- struct ble_adv_tx *tx = CONTAINER_OF(work,
- struct ble_adv_tx,
- resend.work);
- bool front = false;
-
- if (tx->buf == NULL) {
- /* The advertising has been cancelled */
- return;
- }
-
- front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false;
- bt_mesh_ble_adv_send(tx->buf, &ble_adv_send_cb, tx, front);
-
- if (tx->param.count == SEND_BLE_ADV_INFINITE) {
- /* Send the BLE advertising packet infinitely */
- return;
- }
-
- if (tx->param.count > 0U) {
- tx->param.count--;
- }
-}
-
-int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
- const struct bt_mesh_ble_adv_data *data, uint8_t *index)
-{
- struct ble_adv_tx *tx = NULL;
- struct net_buf *buf = NULL;
- bool front = false;
-
- if (param == NULL || index == NULL) {
- BT_ERR("%s, Invalid parameter", __func__);
- return -EINVAL;
- }
-
- if (param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
- (param->interval < 0x20 || param->interval > 0x4000)) {
- BT_ERR("Invalid adv interval 0x%04x", param->interval);
- return -EINVAL;
- }
-
- if (param->adv_type > BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
- BT_ERR("Invalid adv type 0x%02x", param->adv_type);
- return -EINVAL;
- }
-
- if (param->own_addr_type > BLE_MESH_ADDR_RANDOM_ID) {
- BT_ERR("Invalid own addr type 0x%02x", param->own_addr_type);
- return -EINVAL;
- }
-
- if ((param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID ||
- param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID ||
- param->adv_type == BLE_MESH_ADV_DIRECT_IND ||
- param->adv_type == BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) &&
- param->peer_addr_type > BLE_MESH_ADDR_RANDOM) {
- BT_ERR("Invalid peer addr type 0x%02x", param->peer_addr_type);
- return -EINVAL;
- }
-
- if (data && (data->adv_data_len > 31 || data->scan_rsp_data_len > 31)) {
- BT_ERR("Invalid adv data length (adv %d, scan rsp %d)",
- data->adv_data_len, data->scan_rsp_data_len);
- return -EINVAL;
- }
-
- if (param->priority > BLE_MESH_BLE_ADV_PRIO_HIGH) {
- BT_ERR("Invalid adv priority %d", param->priority);
- return -EINVAL;
- }
-
- if (param->duration < ADV_SCAN_INT(param->interval)) {
- BT_ERR("Too small duration %dms", param->duration);
- return -EINVAL;
- }
-
- buf = bt_mesh_ble_adv_create(BLE_MESH_ADV_BLE, K_NO_WAIT);
- if (!buf) {
- BT_ERR("No empty ble adv buffer");
- return -ENOBUFS;
- }
-
- /* Set advertising data and scan response data */
- memset(buf->data, 0, buf->size);
- if (data) {
- net_buf_add_u8(buf, data->adv_data_len);
- if (data->adv_data_len) {
- net_buf_add_mem(buf, data->adv_data, data->adv_data_len);
- }
- net_buf_add_u8(buf, data->scan_rsp_data_len);
- if (data->scan_rsp_data_len) {
- net_buf_add_mem(buf, data->scan_rsp_data, data->scan_rsp_data_len);
- }
- }
-
- *index = net_buf_id(buf);
- tx = &ble_adv_tx[*index];
- tx->buf = buf;
- memcpy(&tx->param, param, sizeof(tx->param));
-
- front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false;
- bt_mesh_ble_adv_send(buf, &ble_adv_send_cb, tx, front);
- if (param->count) {
- if (k_delayed_work_init(&tx->resend, ble_adv_resend)) {
- /* If failed to create a timer, the BLE adv packet will be
- * sent only once. Just give a warning here, and since the
- * BLE adv packet can be sent, return 0 here.
- */
- BT_WARN("Send BLE adv packet only once");
- tx->param.count = 0;
- net_buf_unref(buf);
- return 0;
- }
- bt_mesh_atomic_set_bit(tx->flags, TIMER_INIT);
- } else {
- /* Send the BLE advertising packet only once */
- net_buf_unref(buf);
- }
-
- return 0;
-}
-
-int bt_mesh_stop_ble_advertising(uint8_t index)
-{
- struct ble_adv_tx *tx = NULL;
- bool unref = true;
-
- if (index >= ARRAY_SIZE(ble_adv_tx)) {
- BT_ERR("Invalid adv index %d", index);
- return -EINVAL;
- }
-
- tx = &ble_adv_tx[index];
-
- if (tx->buf == NULL) {
- BT_WARN("Already stopped, index %d", index);
- return 0;
- }
-
- /* busy 1, ref 1; busy 1, ref 2;
- * busy 0, ref 0; busy 0, ref 1;
- */
- if (BLE_MESH_ADV(tx->buf)->busy == 1U &&
- tx->buf->ref == 1U) {
- unref = false;
- }
- ble_adv_tx_reset(tx, unref);
-
- return 0;
-}
-#if CONFIG_BLE_MESH_DEINIT
-static void bt_mesh_ble_adv_deinit(void)
-{
- for (int i = 0; i < ARRAY_SIZE(ble_adv_tx); i++) {
- struct ble_adv_tx *tx = &ble_adv_tx[i];
- ble_adv_tx_reset(tx, false);
- }
- bt_mesh_unref_buf_from_pool(&ble_adv_buf_pool);
- memset(ble_adv_pool, 0, sizeof(ble_adv_pool));
+ bt_mesh_adv_common_deinit();
}
#endif /* CONFIG_BLE_MESH_DEINIT */
-#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
diff --git a/lib/bt/esp_ble_mesh/core/adv.h b/lib/bt/esp_ble_mesh/core/adv.h
index ab37ec3c..5770364a 100644
--- a/lib/bt/esp_ble_mesh/core/adv.h
+++ b/lib/bt/esp_ble_mesh/core/adv.h
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -10,96 +10,30 @@
#ifndef _ADV_H_
#define _ADV_H_
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+#include "ext_adv.h"
+#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+#include "mesh/atomic.h"
#include "mesh/access.h"
#include "mesh/adapter.h"
+#include "mesh/utils.h"
+#include "adv_common.h"
#ifdef __cplusplus
extern "C" {
#endif
-/* Maximum advertising data payload for a single data type */
-#define BLE_MESH_ADV_DATA_SIZE 29
-
-/* The user data is a pointer (4 bytes) to struct bt_mesh_adv */
-#define BLE_MESH_ADV_USER_DATA_SIZE 4
-
-#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf))
-
-uint16_t bt_mesh_pdu_duration(uint8_t xmit);
-
-typedef struct bt_mesh_msg {
- bool relay; /* Flag indicates if the packet is a relayed one */
- void *arg; /* Pointer to the struct net_buf */
- uint16_t src; /* Source address for relay packets */
- uint16_t dst; /* Destination address for relay packets */
- uint32_t timestamp; /* Timestamp recorded when the relay packet is posted to queue */
-} bt_mesh_msg_t;
-
-enum bt_mesh_adv_type {
- BLE_MESH_ADV_PROV,
- BLE_MESH_ADV_DATA,
- BLE_MESH_ADV_BEACON,
- BLE_MESH_ADV_URI,
- BLE_MESH_ADV_BLE,
- BLE_MESH_ADV_PROXY_SOLIC,
-};
-
-struct bt_mesh_adv {
- const struct bt_mesh_send_cb *cb;
- void *cb_data;
-
- uint8_t type:3,
- busy:1;
- uint8_t xmit;
-};
-
-typedef struct bt_mesh_adv *(*bt_mesh_adv_alloc_t)(int id);
-
-struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, int32_t timeout);
-
-typedef enum {
- BLE_MESH_BUF_REF_EQUAL,
- BLE_MESH_BUF_REF_SMALL,
- BLE_MESH_BUF_REF_MAX,
-} bt_mesh_buf_ref_flag_t;
-
-void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
- uint8_t ref_cmp, bt_mesh_buf_ref_flag_t flag);
-
-struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *pool,
- bt_mesh_adv_alloc_t get_id,
- enum bt_mesh_adv_type type,
- int32_t timeout);
-
-void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool);
-
void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
const struct bt_mesh_send_cb *cb,
void *cb_data);
-struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, int32_t timeout);
-
-void bt_mesh_relay_adv_send(struct net_buf *buf, uint8_t xmit,
- uint16_t src, uint16_t dst,
- const struct bt_mesh_send_cb *cb,
- void *cb_data);
-
-uint16_t bt_mesh_get_stored_relay_count(void);
-
void bt_mesh_adv_update(void);
void bt_mesh_adv_init(void);
void bt_mesh_adv_deinit(void);
-#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
-int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
- const struct bt_mesh_ble_adv_data *data, uint8_t *index);
-
-int bt_mesh_stop_ble_advertising(uint8_t index);
-#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
-
#ifdef __cplusplus
}
#endif
-
+#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
#endif /* _ADV_H_ */
diff --git a/lib/bt/esp_ble_mesh/core/adv_common.c b/lib/bt/esp_ble_mesh/core/adv_common.c
new file mode 100644
index 00000000..4a7078d7
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/core/adv_common.c
@@ -0,0 +1,683 @@
+/* Bluetooth Mesh */
+
+/*
+ * SPDX-FileCopyrightText: 2017 Intel Corporation
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include "adv_common.h"
+#include "net.h"
+#include "ble_adv.h"
+
+NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BLE_MESH_ADV_BUF_COUNT,
+ BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
+
+static struct bt_mesh_adv adv_pool[CONFIG_BLE_MESH_ADV_BUF_COUNT];
+
+static struct bt_mesh_adv_queue adv_queue;
+
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF
+NET_BUF_POOL_DEFINE(relay_adv_buf_pool, CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT,
+ BLE_MESH_ADV_DATA_SIZE, BLE_MESH_ADV_USER_DATA_SIZE, NULL);
+
+static struct bt_mesh_adv relay_adv_pool[CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT];
+struct bt_mesh_adv_queue relay_adv_queue;
+
+#define BLE_MESH_RELAY_TIME_INTERVAL K_SECONDS(6)
+#define BLE_MESH_MAX_TIME_INTERVAL 0xFFFFFFFF
+
+#endif
+
+#if CONFIG_BLE_MESH_FRIEND
+/* We reserve one extra buffer for each friendship, since we need to be able
+ * to resend the last sent PDU, which sits separately outside of the queue.
+ */
+#define FRIEND_BUF_COUNT ((CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE + 1) * \
+ CONFIG_BLE_MESH_FRIEND_LPN_COUNT)
+
+NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT,
+ BLE_MESH_ADV_DATA_SIZE, NULL);
+
+bt_mesh_friend_adv_t frnd_adv_pool[FRIEND_BUF_COUNT];
+
+struct bt_mesh_adv *bt_mesh_frnd_adv_buf_get(int idx)
+{
+ frnd_adv_pool[idx].app_idx = BLE_MESH_KEY_UNUSED;
+ return &frnd_adv_pool[idx].adv;
+}
+#endif
+
+struct bt_mesh_adv_task {
+ TaskHandle_t handle;
+#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
+ (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
+ CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
+ StaticTask_t *task;
+ StackType_t *stack;
+#endif
+};
+
+static struct bt_mesh_adv_task adv_task;
+static struct bt_mesh_adv_type_manager adv_types[BLE_MESH_ADV_TYPES_NUM];
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+static struct bt_mesh_adv_inst adv_insts[] = {
+ [BLE_MESH_ADV_INS] = {
+ .id = CONFIG_BLE_MESH_ADV_INST_ID,
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ .busy = false,
+#endif
+ },
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ [BLE_MESH_ADV_PROXY_INS] = {
+ .id = CONFIG_BLE_MESH_PROXY_ADV_INST_ID,
+ .busy = false,
+ },
+#endif
+#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
+ [BLE_MESH_RELAY_ADV_INS] = {
+ .id = CONFIG_BLE_MESH_RELAY_ADV_INST_ID,
+ .busy = false,
+ },
+#endif
+#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
+ [BLE_MESH_BLE_ADV_INS] = {
+ .id = CONFIG_BLE_MESH_BLE_ADV_INST_ID,
+ .busy = false,
+ },
+#endif
+#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+};
+
+static struct bt_mesh_adv_inst *find_adv_inst_with_inst_id(uint8_t id)
+{
+ for (int i = 0; i < ARRAY_SIZE(adv_insts); i++) {
+ if (adv_insts[i].id == id) {
+ return &adv_insts[i];
+ }
+ }
+
+ return NULL;
+}
+
+struct bt_mesh_adv_inst *bt_mesh_get_adv_insts_set(void)
+{
+ return adv_insts;
+}
+
+bool bt_mesh_is_adv_inst_used(uint8_t adv_inst_id)
+{
+ return (find_adv_inst_with_inst_id(adv_inst_id) != NULL);
+}
+
+int bt_mesh_adv_inst_init(enum bt_mesh_adv_inst_type inst_type, uint8_t inst_id)
+{
+ if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
+ BT_ERR("Invalid instance type %d", inst_type);
+ return -EINVAL;
+ }
+
+ if (inst_id == BLE_MESH_ADV_INS_UNUSED) {
+ BT_ERR("Invalid instance id %d", inst_id);
+ return -EINVAL;
+ }
+
+ adv_insts[inst_type].id = inst_id;
+ return 0;
+}
+
+int bt_mesh_adv_inst_deinit(enum bt_mesh_adv_inst_type inst_type)
+{
+ if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
+ BT_ERR("Invalid instance type %d", inst_type);
+ return -EINVAL;
+ }
+
+ bt_le_ext_adv_stop(adv_insts[inst_type].id);
+
+ adv_insts[inst_type].id = BLE_MESH_ADV_INS_UNUSED;
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ adv_insts[inst_type].spt_mask = 0;
+#endif
+ return 0;
+}
+
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+
+struct bt_mesh_adv *adv_alloc(int id)
+{
+ return &adv_pool[id];
+}
+
+struct bt_mesh_adv_type_manager *bt_mesh_adv_types_mgnt_get(enum bt_mesh_adv_type adv_type)
+{
+ return &adv_types[adv_type];
+}
+
+void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
+ uint8_t ref_cmp, bt_mesh_buf_ref_flag_t flag)
+{
+ if (buf == NULL || func == NULL || flag >= BLE_MESH_BUF_REF_MAX) {
+ BT_ERR("%s, Invalid parameter", __func__);
+ return;
+ }
+
+ switch (flag) {
+ case BLE_MESH_BUF_REF_EQUAL:
+ if (buf->ref != ref_cmp) {
+ BT_ERR("Unexpected ref %d in %s, expect to equal to %d", buf->ref, func, ref_cmp);
+ }
+ break;
+ case BLE_MESH_BUF_REF_SMALL:
+ if (buf->ref >= ref_cmp) {
+ BT_ERR("Unexpected ref %d in %s, expect to smaller than %d", buf->ref, func, ref_cmp);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+void bt_mesh_adv_inst_supported_adv_type_add(enum bt_mesh_adv_inst_type inst_type,
+ enum bt_mesh_adv_type adv_type)
+{
+ if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
+ BT_ERR("Invalid instance type %d", inst_type);
+ return;
+ }
+
+ if (adv_type >= BLE_MESH_ADV_TYPES_NUM) {
+ BT_ERR("Invalid adv type %d", adv_type);
+ return;
+ }
+
+ adv_insts[inst_type].spt_mask |= BIT(adv_type);
+}
+
+void bt_mesh_adv_inst_supported_adv_type_rm(enum bt_mesh_adv_inst_type inst_type,
+ enum bt_mesh_adv_type adv_type)
+{
+ if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
+ BT_ERR("Invalid instance type %d", inst_type);
+ return;
+ }
+
+ if (adv_type >= BLE_MESH_ADV_TYPES_NUM) {
+ BT_ERR("Invalid adv type %d", adv_type);
+ return;
+ }
+
+ adv_insts[inst_type].spt_mask &= ~BIT(adv_type);
+}
+
+void bt_mesh_adv_inst_supported_adv_type_clear(enum bt_mesh_adv_inst_type inst_type,
+ enum bt_mesh_adv_type adv_type)
+{
+ if (inst_type >= BLE_MESH_ADV_INS_TYPES_NUM) {
+ BT_ERR("Invalid instance type %d", inst_type);
+ return;
+ }
+
+ if (adv_type >= BLE_MESH_ADV_TYPES_NUM) {
+ BT_ERR("Invalid adv type %d", adv_type);
+ return;
+ }
+
+ adv_insts[inst_type].spt_mask = 0;
+}
+#endif
+
+int bt_mesh_adv_queue_init(struct bt_mesh_adv_queue *adv_queue, uint16_t queue_size,
+ bt_mesh_adv_queue_send_cb_t cb)
+{
+ if (!adv_queue || !queue_size || !cb) {
+ BT_ERR("Invalid param %s", __func__);
+ return -EINVAL;
+ }
+
+ bt_mesh_queue_init(&adv_queue->q, queue_size, sizeof(bt_mesh_msg_t));
+
+ adv_queue->send = cb;
+
+ return 0;
+}
+
+int bt_mesh_adv_queue_deinit(struct bt_mesh_adv_queue *adv_queue)
+{
+ if (!adv_queue) {
+ BT_ERR("Invalid param %s", __func__);
+ return -EINVAL;
+ }
+
+ bt_mesh_queue_deinit(&adv_queue->q);
+
+ adv_queue->send = NULL;
+
+ return 0;
+}
+
+void bt_mesh_adv_type_init(enum bt_mesh_adv_type adv_type,
+ struct bt_mesh_adv_queue *adv_queue,
+ struct net_buf_pool *buf_pool,
+ bt_mesh_pool_allocator_t adv_alloc)
+{
+ if (adv_type >= BLE_MESH_ADV_TYPES_NUM) {
+ BT_ERR("%s Invalid adv type %d",__func__, adv_type);
+ return;
+ }
+
+ if (!adv_queue || !buf_pool || !adv_alloc) {
+ BT_ERR("Invalid parameters %s", __func__);
+ return;
+ }
+
+ adv_types[adv_type].adv_q = adv_queue;
+ adv_types[adv_type].pool = buf_pool;
+ adv_types[adv_type].pool_allocator = adv_alloc;
+}
+
+void bt_mesh_adv_type_deinit(enum bt_mesh_adv_type adv_type)
+{
+ if (adv_type >= BLE_MESH_ADV_TYPES_NUM) {
+ BT_ERR("%s Invalid adv type %d",__func__, adv_type);
+ return;
+ }
+
+ adv_types[adv_type].adv_q = NULL;
+ adv_types[adv_type].pool = NULL;
+ adv_types[adv_type].pool_allocator = NULL;
+}
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+int ble_mesh_adv_task_wakeup(uint32_t evt)
+{
+ xTaskNotify(adv_task.handle, evt, eSetBits);
+ return 0;
+}
+
+bool ble_mesh_adv_task_wait(uint32_t wait_bits, uint32_t timeout, uint32_t *notify)
+{
+ return (xTaskNotifyWait(wait_bits, UINT32_MAX, notify, K_WAIT(timeout)) == pdTRUE);
+}
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
+bool ble_mesh_adv_task_wait(uint32_t timeout)
+{
+ vTaskDelay(K_WAIT(timeout));
+ return true;
+}
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+
+uint16_t bt_mesh_pdu_duration(uint8_t xmit)
+{
+ uint16_t duration = 0U;
+ uint16_t adv_int = 0U;
+
+ adv_int = MAX(ADV_ITVL_MIN, BLE_MESH_TRANSMIT_INT(xmit));
+ duration = (BLE_MESH_TRANSMIT_COUNT(xmit) + 1) * (adv_int + 10);
+
+ return duration;
+}
+
+struct net_buf *bt_mesh_adv_create_from_pool(enum bt_mesh_adv_type type,
+ int32_t timeout)
+{
+ struct bt_mesh_adv *adv = NULL;
+ struct net_buf *buf = NULL;
+ struct net_buf_pool *pool = adv_types[type].pool;
+
+ if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_SUSPENDED)) {
+ BT_WARN("Refusing to allocate buffer while suspended");
+ return NULL;
+ }
+
+ if (!pool || !adv_types[type].pool_allocator) {
+ BT_ERR("Uninitialized adv type %d", type);
+ return NULL;
+ }
+
+ buf = net_buf_alloc(pool, timeout);
+ if (!buf) {
+ BT_WARN("Buf alloc failed");
+ return NULL;
+ }
+
+ 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));
+ BLE_MESH_ADV(buf) = adv;
+
+ (void)memset(adv, 0, sizeof(*adv));
+
+ adv->type = type;
+
+ return buf;
+}
+
+void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool)
+{
+ if (pool == NULL) {
+ BT_ERR("%s, Invalid parameter", __func__);
+ return;
+ }
+
+ for (int i = 0; i < pool->buf_count; i++) {
+ struct net_buf *buf = &pool->__bufs[i];
+ if (buf->ref > 1U) {
+ buf->ref = 1U;
+ }
+ net_buf_unref(buf);
+ }
+}
+
+void bt_mesh_unref_buf(bt_mesh_msg_t *msg)
+{
+ struct net_buf *buf = NULL;
+
+ if (msg->arg) {
+ buf = (struct net_buf *)msg->arg;
+ bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0);
+ if (buf->ref > 1U) {
+ buf->ref = 1U;
+ }
+ net_buf_unref(buf);
+ }
+}
+
+void bt_mesh_generic_adv_send(struct net_buf *buf, uint8_t xmit,
+ const struct bt_mesh_send_cb *cb,
+ void *cb_data, uint16_t src,
+ uint16_t dst, bool front)
+{
+ bt_mesh_msg_t msg = {
+ .relay = false, /* useless flag in multi-instance mode */
+ };
+
+ BT_DBG("type 0x%02x len %u: %s", BLE_MESH_ADV(buf)->type, buf->len,
+ bt_hex(buf->data, buf->len));
+
+ BLE_MESH_ADV(buf)->cb = cb;
+ BLE_MESH_ADV(buf)->cb_data = cb_data;
+ bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1);
+ BLE_MESH_ADV(buf)->xmit = xmit;
+
+ bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
+
+ msg.arg = (void *)net_buf_ref(buf);
+
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF
+ if (BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_RELAY_DATA) {
+ msg.relay = true;
+ msg.src = src;
+ msg.dst = dst;
+ msg.timestamp = k_uptime_get_32();
+ }
+#endif
+
+ assert(adv_types[BLE_MESH_ADV(buf)->type].adv_q && adv_types[BLE_MESH_ADV(buf)->type].adv_q->send);
+
+ adv_types[BLE_MESH_ADV(buf)->type].adv_q->send(&msg, portMAX_DELAY, front);
+
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ ble_mesh_adv_task_wakeup(ADV_TASK_PKT_SEND_EVT);
+#endif
+}
+
+struct bt_mesh_adv_queue *bt_mesh_adv_queue_get(void)
+{
+ return &adv_queue;
+}
+
+void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
+{
+ if (adv_queue.q.handle == NULL) {
+ BT_ERR("Invalid adv queue");
+ return;
+ }
+
+ if (front) {
+ if (xQueueSendToFront(adv_queue.q.handle, msg, timeout) != pdTRUE) {
+ BT_ERR("Failed to send item to adv queue front");
+ bt_mesh_unref_buf(msg);
+ }
+ } else {
+ if (xQueueSend(adv_queue.q.handle, msg, timeout) != pdTRUE) {
+ BT_ERR("Failed to send item to adv queue back");
+ bt_mesh_unref_buf(msg);
+ }
+ }
+}
+
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF
+bool bt_mesh_ignore_relay_packet(uint32_t timestamp)
+{
+ uint32_t now = k_uptime_get_32();
+ uint32_t interval = 0U;
+
+ if (now >= timestamp) {
+ interval = now - timestamp;
+ } else {
+ interval = BLE_MESH_MAX_TIME_INTERVAL - (timestamp - now) + 1;
+ }
+
+ return ((interval >= BLE_MESH_RELAY_TIME_INTERVAL) ? true : false);
+}
+
+static struct bt_mesh_adv *relay_adv_alloc(int id)
+{
+ return &relay_adv_pool[id];
+}
+
+struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
+{
+ return bt_mesh_adv_create_from_pool(type, timeout);
+}
+
+static void ble_mesh_relay_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
+{
+ bt_mesh_msg_t old_msg = {0};
+
+ ARG_UNUSED(front);
+
+ if (relay_adv_queue.q.handle == NULL) {
+ BT_ERR("Invalid relay queue");
+ return;
+ }
+
+ if (xQueueSend(relay_adv_queue.q.handle, msg, timeout) == pdTRUE) {
+ return;
+ }
+
+ /* If failed to send packet to the relay queue(queue is full), we will
+ * remove the oldest packet in the queue and put the new one into it.
+ */
+ if (uxQueueMessagesWaiting(relay_adv_queue.q.handle)) {
+ BT_INFO("Full queue, remove the oldest relay packet");
+ /* Remove the oldest relay packet from queue */
+ if (xQueueReceive(relay_adv_queue.q.handle, &old_msg, K_NO_WAIT) != pdTRUE) {
+ BT_ERR("Failed to remove item from relay queue");
+ bt_mesh_unref_buf(msg);
+ return;
+ }
+ /* Unref buf used for the oldest relay packet */
+ bt_mesh_unref_buf(&old_msg);
+ /* Send the latest relay packet to queue */
+ if (xQueueSend(relay_adv_queue.q.handle, msg, K_NO_WAIT) != pdTRUE) {
+ BT_ERR("Failed to send item to relay queue");
+ bt_mesh_unref_buf(msg);
+ return;
+ }
+ } else {
+ BT_WARN("Empty queue, but failed to send the relay packet");
+ bt_mesh_unref_buf(msg);
+ }
+}
+
+uint16_t bt_mesh_get_stored_relay_count(void)
+{
+ return (uint16_t)uxQueueMessagesWaiting(relay_adv_queue.q.handle);
+}
+
+void bt_mesh_relay_adv_init(void)
+{
+ bt_mesh_adv_queue_init(&relay_adv_queue, CONFIG_BLE_MESH_RELAY_ADV_BUF_COUNT,
+ 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_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);
+#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
+#endif /* CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE */
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+}
+#if CONFIG_BLE_MESH_DEINIT
+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_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);
+ 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
+#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);
+ memset(relay_adv_pool, 0, sizeof(relay_adv_pool));
+}
+#endif /* CONFIG_BLE_MESH_DEINIT */
+#endif /* CONFIG_BLE_MESH_RELAY_ADV_BUF */
+
+#if CONFIG_BLE_MESH_FRIEND
+struct net_buf_pool *bt_mesh_frnd_adv_pool_get(void)
+{
+ return &friend_buf_pool;
+}
+
+void bt_mesh_frnd_adv_init(void)
+{
+ bt_mesh_adv_type_init(BLE_MESH_ADV_FRIEND, &adv_queue, &friend_buf_pool, bt_mesh_frnd_adv_buf_get);
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_FRIEND);
+#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+}
+
+void bt_mesh_frnd_adv_deinit(void)
+{
+ bt_mesh_adv_type_deinit(BLE_MESH_ADV_FRIEND);
+
+#if CONFIG_BLE_MESH_FRIEND && CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_FRIEND);
+#endif /* CONFIG_BLE_MESH_FRIEND */
+
+ bt_mesh_unref_buf_from_pool(&friend_buf_pool);
+ memset(frnd_adv_pool, 0, sizeof(frnd_adv_pool));
+}
+#endif /* CONFIG_BLE_MESH_FRIEND */
+
+void bt_mesh_adv_task_init(void adv_thread(void *p))
+{
+ if (!adv_thread) {
+ BT_ERR("Invalid param %s", __func__);
+ return;
+ }
+
+#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
+ (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
+ CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
+ adv_task.task = heap_caps_calloc(1, sizeof(StaticTask_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+ __ASSERT(adv_task.task, "Failed to create adv thread task");
+ adv_task.stack = heap_caps_calloc_prefer(1, BLE_MESH_ADV_TASK_STACK_SIZE * sizeof(StackType_t), 2, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
+ __ASSERT(adv_task.stack, "Failed to create adv thread stack");
+ adv_task.handle = xTaskCreateStaticPinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
+ BLE_MESH_ADV_TASK_PRIO, adv_task.stack, adv_task.task, BLE_MESH_ADV_TASK_CORE);
+ __ASSERT(adv_task.handle, "Failed to create static adv thread");
+#else /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
+ int ret = xTaskCreatePinnedToCore(adv_thread, BLE_MESH_ADV_TASK_NAME, BLE_MESH_ADV_TASK_STACK_SIZE, NULL,
+ BLE_MESH_ADV_TASK_PRIO, &adv_task.handle, BLE_MESH_ADV_TASK_CORE);
+ __ASSERT(ret == pdTRUE, "Failed to create adv thread");
+ (void)ret;
+#endif /* CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY */
+}
+
+void bt_mesh_adv_common_init(void)
+{
+ bt_mesh_adv_queue_init(&adv_queue, BLE_MESH_ADV_QUEUE_SIZE, 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);
+ bt_mesh_adv_type_init(BLE_MESH_ADV_URI, &adv_queue, &adv_buf_pool, adv_alloc);
+#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
+ bt_mesh_adv_type_init(BLE_MESH_ADV_PROXY_SOLIC, &adv_queue, &adv_buf_pool, adv_alloc);
+#endif
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+ bt_mesh_adv_inst_init(BLE_MESH_ADV_INS, CONFIG_BLE_MESH_ADV_INST_ID);
+#endif
+
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ /**
+ * Due to the limitation of the sequence number in the network layer,
+ * it is not possible to use multiple advertising instances to process
+ * data from the same message queue when sending mesh packets.
+ *
+ * Therefore, shall to check whether there are
+ * duplicates in the queue buffer corresponding to each advertising instance.
+ */
+ bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_PROV);
+ 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);
+#endif
+}
+
+#if CONFIG_BLE_MESH_DEINIT
+void bt_mesh_adv_task_deinit(void)
+{
+ vTaskDelete(adv_task.handle);
+ adv_task.handle = NULL;
+
+#if (CONFIG_BLE_MESH_FREERTOS_STATIC_ALLOC_EXTERNAL && \
+ (CONFIG_SPIRAM_CACHE_WORKAROUND || !CONFIG_IDF_TARGET_ESP32) && \
+ CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY)
+ heap_caps_free(adv_task.stack);
+ adv_task.stack = NULL;
+ heap_caps_free(adv_task.task);
+ adv_task.task = NULL;
+#endif
+}
+
+void bt_mesh_adv_common_deinit(void)
+{
+ bt_mesh_adv_type_deinit(BLE_MESH_ADV_PROV);
+ bt_mesh_adv_type_deinit(BLE_MESH_ADV_DATA);
+ bt_mesh_adv_type_deinit(BLE_MESH_ADV_BEACON);
+ bt_mesh_adv_type_deinit(BLE_MESH_ADV_URI);
+
+ bt_mesh_adv_queue_deinit(&adv_queue);
+#if CONFIG_BLE_MESH_USE_BLE_50
+ bt_mesh_adv_inst_deinit(BLE_MESH_ADV_INS);
+#endif
+
+ bt_mesh_unref_buf_from_pool(&adv_buf_pool);
+ memset(adv_pool, 0, sizeof(adv_pool));
+}
+#endif /* CONFIG_BLE_MESH_DEINIT */
diff --git a/lib/bt/esp_ble_mesh/core/adv_common.h b/lib/bt/esp_ble_mesh/core/adv_common.h
new file mode 100644
index 00000000..0477e889
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/core/adv_common.h
@@ -0,0 +1,293 @@
+/* Bluetooth Mesh */
+
+/*
+ * SPDX-FileCopyrightText: 2017 Intel Corporation
+ * SPDX-FileContributor: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _ADV_COMMON_H_
+#define _ADV_COMMON_H_
+
+#include "mesh/common.h"
+#include "mesh/atomic.h"
+#include "mesh/access.h"
+#include "mesh/adapter.h"
+#include "mesh/queue.h"
+#include "mesh/timer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Pre-5.0 controllers enforce a minimum interval of 100ms
+ * whereas 5.0+ controllers can go down to 20ms.
+ */
+#if CONFIG_BLE_MESH_HCI_5_0
+#define ADV_ITVL_MIN 20
+#else
+#define ADV_ITVL_MIN 100
+#endif
+
+/* Convert from ms to 0.625ms units */
+#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5)
+/* Convert from 0.625ms units to interval(ms) */
+#define ADV_SCAN_INT(val) ((val) * 5 / 8)
+
+/* Maximum advertising data payload for a single data type */
+#define BLE_MESH_ADV_DATA_SIZE 29
+
+/* The user data is a pointer (4 bytes) to struct bt_mesh_adv */
+#define BLE_MESH_ADV_USER_DATA_SIZE 4
+
+#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf))
+#define BLE_MESH_ADV_BUSY(buf) (BLE_MESH_ADV(buf)->busy)
+
+#define BLE_MESH_MSG_NET_BUF(msg) ((struct net_buf *)(msg->arg))
+
+#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;
+
+ uint8_t type;
+
+ bt_mesh_atomic_t busy;
+
+ uint8_t xmit;
+};
+
+#if CONFIG_BLE_MESH_FRIEND
+
+#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), bt_mesh_friend_adv_t, adv)
+
+typedef struct {
+ struct bt_mesh_adv adv;
+ uint16_t app_idx;
+} bt_mesh_friend_adv_t;
+
+#endif
+
+enum {
+#if CONFIG_BLE_MESH_USE_BLE_50
+ ADV_TASK_MESH_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_ADV_INST_ID),
+
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ ADV_TASK_PROX_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_PROXY_ADV_INST_ID),
+#endif
+
+#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
+ ADV_TASK_RELAY_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_RELAY_ADV_INST_ID),
+#endif
+
+#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
+ ADV_TASK_BLE_ADV_INST_EVT = BIT(CONFIG_BLE_MESH_BLE_ADV_INST_ID),
+#endif
+#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ ADV_TASK_PROXY_ADV_UPD_EVT = BIT(30),
+#endif
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+ ADV_TASK_PKT_SEND_EVT = BIT(31),
+ ADV_TASK_EVT_MAX,
+};
+
+uint16_t bt_mesh_pdu_duration(uint8_t xmit);
+
+typedef struct bt_mesh_msg {
+ bool relay; /* Flag indicates if the packet is a relayed one */
+ void *arg; /* Pointer to the struct net_buf */
+ uint16_t src; /* Source address for relay packets */
+ uint16_t dst; /* Destination address for relay packets */
+ 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
+ bool busy;
+ struct net_buf *sending_buf;
+
+ /* indicates that which adv_type is supported by this instance */
+ uint32_t spt_mask;
+#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+};
+
+enum bt_mesh_adv_type {
+ BLE_MESH_ADV_PROV,
+ BLE_MESH_ADV_DATA,
+#if CONFIG_BLE_MESH_FRIEND
+ BLE_MESH_ADV_FRIEND,
+#endif
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF
+ BLE_MESH_ADV_RELAY_DATA,
+#endif
+ BLE_MESH_ADV_BEACON,
+ BLE_MESH_ADV_URI,
+#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
+ BLE_MESH_ADV_PROXY_SOLIC,
+#endif
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+ BLE_MESH_ADV_BLE,
+#endif
+ BLE_MESH_ADV_TYPES_NUM,
+};
+
+typedef enum {
+ BLE_MESH_BUF_REF_EQUAL,
+ BLE_MESH_BUF_REF_SMALL,
+ 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_FRIEND
+ [BLE_MESH_ADV_FRIEND] = BLE_MESH_DATA_MESH_MESSAGE,
+#endif
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF
+ [BLE_MESH_ADV_RELAY_DATA] = BLE_MESH_DATA_MESH_MESSAGE,
+#endif
+ [BLE_MESH_ADV_BEACON] = BLE_MESH_DATA_MESH_BEACON,
+ [BLE_MESH_ADV_URI] = BLE_MESH_DATA_URI,
+};
+
+static inline TickType_t K_WAIT(int32_t val)
+{
+ return (val == K_FOREVER) ? portMAX_DELAY : (val / portTICK_PERIOD_MS);
+}
+
+struct bt_mesh_adv_queue *bt_mesh_adv_queue_get(void);
+
+struct net_buf *bt_mesh_adv_create_from_pool(enum bt_mesh_adv_type type,
+ int32_t timeout);
+
+static inline struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
+{
+ return bt_mesh_adv_create_from_pool(type, timeout);
+}
+
+void bt_mesh_adv_buf_ref_debug(const char *func, struct net_buf *buf,
+ uint8_t ref_cmp, bt_mesh_buf_ref_flag_t flag);
+
+struct bt_mesh_adv_type_manager *bt_mesh_adv_types_mgnt_get(enum bt_mesh_adv_type adv_type);
+
+void bt_mesh_generic_adv_send(struct net_buf *buf, uint8_t xmit,
+ const struct bt_mesh_send_cb *cb,
+ void *cb_data, uint16_t src,
+ uint16_t dst, bool front);
+
+void bt_mesh_unref_buf_from_pool(struct net_buf_pool *pool);
+void bt_mesh_unref_buf(bt_mesh_msg_t *msg);
+
+int bt_mesh_adv_queue_init(struct bt_mesh_adv_queue *adv_queue,
+ uint16_t queue_size,
+ bt_mesh_adv_queue_send_cb_t cb);
+
+int bt_mesh_adv_queue_deinit(struct bt_mesh_adv_queue *adv_queue);
+
+void bt_mesh_adv_type_init(enum bt_mesh_adv_type adv_type,
+ struct bt_mesh_adv_queue *adv_queue,
+ struct net_buf_pool *buf_pool,
+ bt_mesh_pool_allocator_t adv_alloc);
+
+void bt_mesh_adv_type_deinit(enum bt_mesh_adv_type adv_type);
+
+void bt_mesh_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front);
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+struct bt_mesh_adv_inst * bt_mesh_get_adv_insts_set(void);
+int bt_mesh_adv_inst_init(enum bt_mesh_adv_inst_type inst_type, uint8_t inst_id);
+int bt_mesh_adv_inst_deinit(enum bt_mesh_adv_inst_type inst_type);
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+void bt_mesh_adv_inst_supported_adv_type_add(enum bt_mesh_adv_inst_type inst_type,
+ enum bt_mesh_adv_type adv_type);
+
+void bt_mesh_adv_inst_supported_adv_type_rm(enum bt_mesh_adv_inst_type inst_type,
+ enum bt_mesh_adv_type adv_type);
+
+void bt_mesh_adv_inst_supported_adv_type_clear(enum bt_mesh_adv_inst_type inst_type,
+ enum bt_mesh_adv_type adv_type);
+#endif
+
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF
+void bt_mesh_relay_adv_init(void);
+bool bt_mesh_ignore_relay_packet(uint32_t timestamp);
+struct net_buf *bt_mesh_relay_adv_create(enum bt_mesh_adv_type type, int32_t timeout);
+
+static inline void bt_mesh_relay_adv_send(struct net_buf *buf, uint8_t xmit,
+ uint16_t src, uint16_t dst,
+ const struct bt_mesh_send_cb *cb,
+ void *cb_data)
+{
+ bt_mesh_generic_adv_send(buf, xmit, cb, cb_data, src, dst, false);
+};
+
+uint16_t bt_mesh_get_stored_relay_count(void);
+
+#if CONFIG_BLE_MESH_DEINIT
+void bt_mesh_relay_adv_deinit(void);
+#endif
+#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 net_buf_pool *bt_mesh_frnd_adv_pool_get(void);
+void bt_mesh_frnd_adv_init(void);
+#if CONFIG_BLE_MESH_DEINIT
+void bt_mesh_frnd_adv_deinit(void);
+#endif /* CONFIG_BLE_MESH_DEINIT */
+#endif /* CONFIG_BLE_MESH_FRIEND */
+
+void bt_mesh_adv_task_init(void adv_thread(void *p));
+void bt_mesh_adv_common_init(void);
+
+#if CONFIG_BLE_MESH_DEINIT
+void bt_mesh_adv_task_deinit(void);
+void bt_mesh_adv_common_deinit(void);
+#endif
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+bool bt_mesh_is_adv_inst_used(uint8_t adv_inst_id);
+bool ble_mesh_adv_task_wait(uint32_t wait_bits, TickType_t timeout, uint32_t *notify);
+int ble_mesh_adv_task_wakeup(uint32_t evt);
+#else
+bool ble_mesh_adv_task_wait(uint32_t timeout);
+#endif
+
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
+ const struct bt_mesh_ble_adv_data *data, uint8_t *index);
+
+int bt_mesh_stop_ble_advertising(uint8_t index);
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ADV_COMMON_H_ */
diff --git a/lib/bt/esp_ble_mesh/core/beacon.c b/lib/bt/esp_ble_mesh/core/beacon.c
index 488a3c5f..97ec6ebd 100644
--- a/lib/bt/esp_ble_mesh/core/beacon.c
+++ b/lib/bt/esp_ble_mesh/core/beacon.c
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -25,7 +25,9 @@
#include "pvnr_mgmt.h"
#include "mesh/common.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#if defined(CONFIG_BLE_MESH_UNPROVISIONED_BEACON_INTERVAL)
#define UNPROV_BEACON_INTERVAL K_SECONDS(CONFIG_BLE_MESH_UNPROVISIONED_BEACON_INTERVAL)
@@ -33,7 +35,11 @@
#define UNPROV_BEACON_INTERVAL K_SECONDS(5)
#endif
+#if CONFIG_BLE_MESH_BQB_TEST
+#define SECURE_BEACON_INTERVAL K_SECONDS(3)
+#else
#define SECURE_BEACON_INTERVAL K_SECONDS(10)
+#endif
/* 3 transmissions, 20ms interval */
#define UNPROV_XMIT BLE_MESH_TRANSMIT(2, 20)
@@ -472,12 +478,13 @@ void bt_mesh_beacon_recv(struct net_buf_simple *buf, int8_t rssi)
bt_mesh_provisioner_unprov_beacon_recv(buf, rssi);
}
- if (IS_ENABLED(CONFIG_BLE_MESH_RPR_SRV) &&
- bt_mesh_is_provisioned()) {
+#if CONFIG_BLE_MESH_RPR_SRV
+ if (bt_mesh_is_provisioned()) {
const bt_mesh_addr_t *addr = bt_mesh_get_unprov_dev_addr();
bt_mesh_unprov_dev_fifo_enqueue(buf->data, addr->val, bt_mesh_get_adv_type());
bt_mesh_rpr_srv_unprov_beacon_recv(buf, bt_mesh_get_adv_type(), addr, rssi);
}
+#endif
break;
case BEACON_TYPE_SECURE:
secure_beacon_recv(buf);
diff --git a/lib/bt/esp_ble_mesh/core/ble_adv.c b/lib/bt/esp_ble_mesh/core/ble_adv.c
new file mode 100644
index 00000000..ec99efa0
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/core/ble_adv.c
@@ -0,0 +1,323 @@
+/* Bluetooth Mesh */
+
+/*
+ * SPDX-FileCopyrightText: 2017 Intel Corporation
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <string.h>
+#include <errno.h>
+
+#include "ble_adv.h"
+#include "mesh/common.h"
+#include "mesh/buf.h"
+
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+
+static struct bt_mesh_adv_queue ble_adv_queue;
+#define BLE_MESH_BLE_ADV_QUEUE_SIZE (CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT + 1)
+/* length + advertising data + length + scan response data */
+NET_BUF_POOL_DEFINE(ble_adv_buf_pool, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT,
+ ((BLE_MESH_ADV_DATA_SIZE + 3) << 1), BLE_MESH_ADV_USER_DATA_SIZE, NULL);
+
+static struct bt_mesh_adv ble_adv_pool[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
+
+static struct bt_mesh_ble_adv_tx ble_adv_tx[CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT];
+
+#define SEND_BLE_ADV_INFINITE 0xFFFF
+
+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)
+{
+ return &ble_adv_pool[id];
+}
+
+static void bt_mesh_ble_task_post(bt_mesh_msg_t *msg, uint32_t timeout, bool front)
+{
+ BT_DBG("%s", __func__);
+
+ if (ble_adv_queue.q.handle == NULL) {
+ BT_ERR("Invalid adv queue");
+ return;
+ }
+
+ if (front) {
+ if (xQueueSendToFront(ble_adv_queue.q.handle, msg, timeout) != pdTRUE) {
+ BT_ERR("Failed to send item to adv queue front");
+ bt_mesh_unref_buf(msg);
+ }
+ } else {
+ if (xQueueSend(ble_adv_queue.q.handle, msg, timeout) != pdTRUE) {
+ BT_ERR("Failed to send item to adv queue back");
+ bt_mesh_unref_buf(msg);
+ }
+ }
+}
+
+static struct net_buf *bt_mesh_ble_adv_create(enum bt_mesh_adv_type type, int32_t timeout)
+{
+ return bt_mesh_adv_create_from_pool(type, timeout);
+}
+
+inline void bt_mesh_ble_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb,
+ void *cb_data, bool front)
+{
+ bt_mesh_generic_adv_send(buf, 0, cb, cb_data, BLE_MESH_ADDR_UNASSIGNED, BLE_MESH_ADDR_UNASSIGNED, front);
+}
+
+static void ble_adv_tx_reset(struct bt_mesh_ble_adv_tx *tx, bool unref)
+{
+ if (tx->buf == NULL) {
+ return;
+ }
+
+ if (bt_mesh_atomic_test_bit(tx->flags, TIMER_INIT)) {
+ k_delayed_work_free(&tx->resend);
+ }
+ bt_mesh_atomic_set(tx->flags, 0);
+ memset(&tx->param, 0, sizeof(tx->param));
+ bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->buf), 0);
+ if (unref) {
+ net_buf_unref(tx->buf);
+ }
+ tx->buf = NULL;
+}
+
+static void ble_adv_send_start(uint16_t duration, int err, void *cb_data)
+{
+ struct bt_mesh_ble_adv_tx *tx = cb_data;
+
+ BT_DBG("%s, duration %d, err %d", __func__, duration, err);
+
+ /* If failed to send BLE adv packet, and param->count is not 0
+ * which means the timer has been initialized, here we need to
+ * free the timer.
+ */
+ if (err) {
+ ble_adv_tx_reset(tx, true);
+ }
+}
+
+static void ble_adv_send_end(int err, void *cb_data)
+{
+ struct bt_mesh_ble_adv_tx *tx = cb_data;
+
+ BT_DBG("%s, err %d", __func__, err);
+
+ if (err) {
+ ble_adv_tx_reset(tx, true);
+ return;
+ }
+
+ if (tx->param.count) {
+ if (tx->param.period) {
+ k_delayed_work_submit(&tx->resend, tx->param.period);
+ } else {
+ k_work_submit(&tx->resend.work);
+ }
+ } else {
+ ble_adv_tx_reset(tx, true);
+ }
+}
+
+static struct bt_mesh_send_cb ble_adv_send_cb = {
+ .start = ble_adv_send_start,
+ .end = ble_adv_send_end,
+};
+
+static void ble_adv_resend(struct k_work *work)
+{
+ struct bt_mesh_ble_adv_tx *tx = CONTAINER_OF(work, struct bt_mesh_ble_adv_tx, resend.work);
+ bool front = false;
+
+ if (tx->buf == NULL) {
+ /* The advertising has been cancelled */
+ return;
+ }
+
+ front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false;
+ bt_mesh_ble_adv_send(tx->buf, &ble_adv_send_cb, tx, front);
+
+ if (tx->param.count == SEND_BLE_ADV_INFINITE) {
+ /* Send the BLE advertising packet infinitely */
+ return;
+ }
+
+ if (tx->param.count > 0U) {
+ tx->param.count--;
+ }
+}
+
+int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
+ const struct bt_mesh_ble_adv_data *data, uint8_t *index)
+{
+ struct bt_mesh_ble_adv_tx *tx = NULL;
+ struct net_buf *buf = NULL;
+ bool front = false;
+
+ if (param == NULL || index == NULL) {
+ BT_ERR("%s, Invalid parameter", __func__);
+ return -EINVAL;
+ }
+
+ if (param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
+ (param->interval < 0x20 || param->interval > 0x4000)) {
+ BT_ERR("Invalid adv interval 0x%04x", param->interval);
+ return -EINVAL;
+ }
+
+ if (param->adv_type > BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
+ BT_ERR("Invalid adv type 0x%02x", param->adv_type);
+ return -EINVAL;
+ }
+
+ if (param->own_addr_type > BLE_MESH_ADDR_RANDOM_ID) {
+ BT_ERR("Invalid own addr type 0x%02x", param->own_addr_type);
+ return -EINVAL;
+ }
+
+ if ((param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID ||
+ param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID ||
+ param->adv_type == BLE_MESH_ADV_DIRECT_IND ||
+ param->adv_type == BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) &&
+ param->peer_addr_type > BLE_MESH_ADDR_RANDOM) {
+ BT_ERR("Invalid peer addr type 0x%02x", param->peer_addr_type);
+ return -EINVAL;
+ }
+
+ if (data && (data->adv_data_len > 31 || data->scan_rsp_data_len > 31)) {
+ BT_ERR("Invalid adv data length (adv %d, scan rsp %d)",
+ data->adv_data_len, data->scan_rsp_data_len);
+ return -EINVAL;
+ }
+
+ if (param->priority > BLE_MESH_BLE_ADV_PRIO_HIGH) {
+ BT_ERR("Invalid adv priority %d", param->priority);
+ return -EINVAL;
+ }
+
+ if (param->duration < ADV_SCAN_INT(param->interval)) {
+ BT_ERR("Too small duration %dms", param->duration);
+ return -EINVAL;
+ }
+
+ buf = bt_mesh_ble_adv_create(BLE_MESH_ADV_BLE, K_NO_WAIT);
+ if (!buf) {
+ BT_ERR("No empty ble adv buffer");
+ return -ENOBUFS;
+ }
+
+ /* Set advertising data and scan response data */
+ memset(buf->data, 0, buf->size);
+ if (data) {
+ net_buf_add_u8(buf, data->adv_data_len);
+ if (data->adv_data_len) {
+ net_buf_add_mem(buf, data->adv_data, data->adv_data_len);
+ }
+ net_buf_add_u8(buf, data->scan_rsp_data_len);
+ if (data->scan_rsp_data_len) {
+ net_buf_add_mem(buf, data->scan_rsp_data, data->scan_rsp_data_len);
+ }
+ }
+
+ *index = net_buf_id(buf);
+ tx = &ble_adv_tx[*index];
+ tx->buf = buf;
+ memcpy(&tx->param, param, sizeof(tx->param));
+
+ front = (tx->param.priority == BLE_MESH_BLE_ADV_PRIO_HIGH) ? true : false;
+ bt_mesh_ble_adv_send(buf, &ble_adv_send_cb, tx, front);
+ if (param->count) {
+ if (k_delayed_work_init(&tx->resend, ble_adv_resend)) {
+ /* If failed to create a timer, the BLE adv packet will be
+ * sent only once. Just give a warning here, and since the
+ * BLE adv packet can be sent, return 0 here.
+ */
+ BT_WARN("Send BLE adv packet only once");
+ tx->param.count = 0;
+ net_buf_unref(buf);
+ return 0;
+ }
+ bt_mesh_atomic_set_bit(tx->flags, TIMER_INIT);
+ } else {
+ /* Send the BLE advertising packet only once */
+ net_buf_unref(buf);
+ }
+
+ return 0;
+}
+
+int bt_mesh_stop_ble_advertising(uint8_t index)
+{
+ struct bt_mesh_ble_adv_tx *tx = NULL;
+ bool unref = true;
+
+ if (index >= ARRAY_SIZE(ble_adv_tx)) {
+ BT_ERR("Invalid adv index %d", index);
+ return -EINVAL;
+ }
+
+ tx = &ble_adv_tx[index];
+
+ if (tx->buf == NULL) {
+ BT_WARN("Already stopped, index %d", index);
+ return 0;
+ }
+
+ /* busy 1, ref 1; busy 1, ref 2;
+ * busy 0, ref 0; busy 0, ref 1;
+ */
+
+ if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)) &&
+ tx->buf->ref == 1U) {
+ unref = false;
+ }
+ ble_adv_tx_reset(tx, unref);
+
+ return 0;
+}
+
+void bt_mesh_ble_adv_init(void)
+{
+ bt_mesh_adv_queue_init(&ble_adv_queue, CONFIG_BLE_MESH_BLE_ADV_BUF_COUNT, bt_mesh_ble_task_post);
+ bt_mesh_adv_type_init(BLE_MESH_ADV_BLE, &ble_adv_queue, &ble_adv_buf_pool, ble_adv_alloc);
+#if CONFIG_BLE_MESH_USE_BLE_50
+#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
+ bt_mesh_adv_inst_init(BLE_MESH_BLE_ADV_INS, CONFIG_BLE_MESH_BLE_ADV_INST_ID);
+ bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_BLE_ADV_INS, BLE_MESH_ADV_BLE);
+#else
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ bt_mesh_adv_inst_supported_adv_type_add(BLE_MESH_ADV_INS, BLE_MESH_ADV_BLE);
+#endif
+#endif /* CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE */
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+}
+
+#if CONFIG_BLE_MESH_DEINIT
+void bt_mesh_ble_adv_deinit(void)
+{
+ for (int i = 0; i < ARRAY_SIZE(ble_adv_tx); i++) {
+ struct bt_mesh_ble_adv_tx *tx = &ble_adv_tx[i];
+ ble_adv_tx_reset(tx, false);
+ }
+ bt_mesh_unref_buf_from_pool(&ble_adv_buf_pool);
+ memset(ble_adv_pool, 0, sizeof(ble_adv_pool));
+
+ bt_mesh_adv_queue_deinit(&ble_adv_queue);
+ bt_mesh_adv_type_deinit(BLE_MESH_ADV_BLE);
+#if CONFIG_BLE_MESH_USE_BLE_50
+#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
+ bt_mesh_adv_inst_deinit(BLE_MESH_BLE_ADV_INS);
+ bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_BLE_ADV_INS, BLE_MESH_ADV_BLE);
+#else
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ bt_mesh_adv_inst_supported_adv_type_rm(BLE_MESH_ADV_INS, BLE_MESH_ADV_BLE);
+#endif
+#endif /* CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE */
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+}
+#endif /* CONFIG_BLE_MESH_DEINIT */
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
diff --git a/lib/bt/esp_ble_mesh/core/ble_adv.h b/lib/bt/esp_ble_mesh/core/ble_adv.h
new file mode 100644
index 00000000..733320d6
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/core/ble_adv.h
@@ -0,0 +1,54 @@
+/* Bluetooth Mesh */
+
+/*
+ * SPDX-FileCopyrightText: 2017 Intel Corporation
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_ADV_H_
+#define _BLE_ADV_H_
+
+#include "mesh/atomic.h"
+#include "mesh/access.h"
+#include "mesh/adapter.h"
+#include "mesh/utils.h"
+#include "adv_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+
+enum {
+ TIMER_INIT, /* Resend timer is initialized */
+ NUM_FLAGS,
+};
+
+struct bt_mesh_ble_adv_tx {
+ struct bt_mesh_ble_adv_param param;
+ struct net_buf *buf;
+ struct k_delayed_work resend;
+ BLE_MESH_ATOMIC_DEFINE(flags, NUM_FLAGS);
+};
+
+int bt_mesh_start_ble_advertising(const struct bt_mesh_ble_adv_param *param,
+ const struct bt_mesh_ble_adv_data *data, uint8_t *index);
+
+int bt_mesh_stop_ble_advertising(uint8_t index);
+
+void bt_mesh_ble_adv_init(void);
+
+#if CONFIG_BLE_MESH_DEINIT
+void bt_mesh_ble_adv_deinit(void);
+#endif
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_ADV_H_ */
diff --git a/lib/bt/esp_ble_mesh/core/bluedroid_host/adapter.c b/lib/bt/esp_ble_mesh/core/bluedroid_host/adapter.c
index e0fc33b4..db962097 100644
--- a/lib/bt/esp_ble_mesh/core/bluedroid_host/adapter.c
+++ b/lib/bt/esp_ble_mesh/core/bluedroid_host/adapter.c
@@ -29,10 +29,14 @@
#include "mesh/adapter.h"
#include "mesh/common.h"
#include "prov_pvnr.h"
+#include "scan.h"
#include "net.h"
#include "beacon.h"
+#include "btc_ble_mesh_ble.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
struct bt_mesh_dev bt_mesh_dev;
@@ -58,7 +62,10 @@ static uint8_t bt_mesh_private_key[32];
/* Scan related functions */
static bt_mesh_scan_cb_t *bt_mesh_scan_dev_found_cb;
+
+#if !CONFIG_BLE_MESH_USE_BLE_50
static void bt_mesh_scan_result_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data);
+#endif
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_SERVER || \
@@ -102,6 +109,16 @@ static struct bt_mesh_prov_conn_cb *bt_mesh_gattc_conn_cb;
static tBTA_GATTC_IF bt_mesh_gattc_if;
#endif
+#if CONFIG_BLE_MESH_USE_BLE_50 && \
+ CONFIG_BLE_MESH_SUPPORT_BLE_ADV && \
+ (!CONFIG_BLE_MESH_SUPPORT_MULTI_ADV)
+static inline void bt_mesh_set_ble_adv_running();
+
+static inline void bt_mesh_unset_ble_adv_running();
+
+static inline bool bt_mesh_is_ble_adv_running();
+#endif
+
int bt_mesh_host_init(void)
{
return 0;
@@ -136,11 +153,18 @@ void bt_mesh_hci_init(void)
const uint8_t *p = controller_get_interface()->get_ble_supported_states();
uint64_t states_fh = 0, states_sh = 0;
- STREAM_TO_UINT32(states_fh, p);
- STREAM_TO_UINT32(states_sh, p);
+
+ /* macro STREAM_TO_UINT32 expansion */
+ states_fh = (((uint32_t)(*(p))) + ((((uint32_t)(*((p) + 1)))) << 8) + ((((uint32_t)(*((p) + 2)))) << 16) + ((((uint32_t)(*((p) + 3)))) << 24));
+ (p) += 4;
+
+ states_sh = (((uint32_t)(*(p))) + ((((uint32_t)(*((p) + 1)))) << 8) + ((((uint32_t)(*((p) + 2)))) << 16) + ((((uint32_t)(*((p) + 3)))) << 24));
+ (p) += 4;
+
bt_mesh_dev.le.states = (states_sh << 32) | states_fh;
}
+#if !CONFIG_BLE_MESH_USE_BLE_50
static void bt_mesh_scan_results_change_2_bta(tBTM_INQ_RESULTS *p_inq, uint8_t *p_eir,
tBTA_DM_SEARCH_CBACK *p_scan_cback)
{
@@ -183,6 +207,193 @@ static void bt_mesh_scan_results_cb(tBTM_INQ_RESULTS *p_inq, uint8_t *p_eir)
{
bt_mesh_scan_results_change_2_bta(p_inq, p_eir, bt_mesh_scan_result_callback);
}
+#endif
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+extern void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
+ tBTA_DM_BLE_5_GAP_CB_PARAMS *params);
+
+void bt_mesh_ble_ext_adv_report(tBTM_BLE_EXT_ADV_REPORT *ext_adv_report)
+{
+#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
+ bt_mesh_ble_adv_report_t adv_rpt = {0};
+
+ if (bt_mesh_ble_scan_state_get()) {
+ memcpy(adv_rpt.addr, ext_adv_report->addr, BLE_MESH_ADDR_LEN);
+ memcpy(adv_rpt.dir_addr, ext_adv_report->dir_addr, BLE_MESH_ADDR_LEN);
+
+ adv_rpt.addr_type = ext_adv_report->addr_type;
+ adv_rpt.data = ext_adv_report->adv_data;
+ adv_rpt.length = ext_adv_report->adv_data_len;
+ adv_rpt.rssi = ext_adv_report->rssi;
+ adv_rpt.event_type = ext_adv_report->event_type;
+ adv_rpt.primary_phy = ext_adv_report->primary_phy;
+ adv_rpt.secondary_phy = ext_adv_report->secondry_phy;
+ adv_rpt.sid = ext_adv_report->sid;
+ adv_rpt.tx_power = ext_adv_report->tx_power;
+ adv_rpt.dir_addr_type = ext_adv_report->dir_addr_type;
+ adv_rpt.data_status = ext_adv_report->data_status;
+ adv_rpt.per_adv_interval = ext_adv_report->per_adv_interval;
+
+ bt_mesh_ble_scan_cb_evt_to_btc(&adv_rpt);
+ }
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
+}
+
+static bool bt_mesh_scan_result_process(tBTM_BLE_EXT_ADV_REPORT *ext_adv_report)
+{
+ struct bt_mesh_adv_report adv_rpt = {0};
+
+ assert(ext_adv_report);
+
+ adv_rpt.addr.type = ext_adv_report->addr_type;
+ memcpy(adv_rpt.addr.val, ext_adv_report->addr, BLE_MESH_ADDR_LEN);
+ 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;
+
+ 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;
+ }
+
+ BT_DBG("Recv adv report type %04x", ext_adv_report->event_type);
+
+ 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:
+ adv_rpt.adv_type = ext_adv_report->event_type;
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ 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);
+ bt_mesh_scan_dev_found_cb(&adv_rpt);
+ if (adv_rpt.adv_data.len != ext_adv_report->adv_data_len) {
+ /* The advertising data has been processed by Mesh Protocol */
+ return true;
+ }
+ }
+ return false;
+}
+
+void ble_mesh_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event,
+ tBTA_DM_BLE_5_GAP_CB_PARAMS *params)
+{
+ BT_DBG("recv event %d", event);
+
+ switch (event) {
+ case BTA_DM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT:
+ if (!bt_mesh_is_adv_inst_used(params->set_params.instance)) {
+ goto transfer_to_user;
+ }
+ if (params->set_params.status != BTM_SUCCESS) {
+ BT_ERR("BTA_DM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT Failed");
+ }
+ break;
+ case BTA_DM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT:
+ if (!bt_mesh_is_adv_inst_used(params->adv_data_set.instance)) {
+ goto transfer_to_user;
+ }
+ if (params->adv_data_set.status != BTM_SUCCESS) {
+ BT_ERR("BTA_DM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT Failed");
+ }
+ break;
+ case BTA_DM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT:
+ if (!bt_mesh_is_adv_inst_used(params->scan_rsp_data_set.instance)) {
+ goto transfer_to_user;
+ }
+ if (params->scan_rsp_data_set.status != BTM_SUCCESS) {
+ BT_ERR("BTA_DM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT Failed");
+ }
+ break;
+ case BTA_DM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT:
+ if (!bt_mesh_is_adv_inst_used(params->adv_start.instance[0])) {
+ goto transfer_to_user;
+ }
+ if (params->adv_start.status != BTM_SUCCESS) {
+ BT_ERR("BTA_DM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT Failed");
+ }
+ break;
+ case BTA_DM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT:
+ if (!bt_mesh_is_adv_inst_used(params->adv_start.instance[0])) {
+ goto transfer_to_user;
+ }
+ if (params->adv_start.status != BTM_SUCCESS) {
+ BT_ERR("BTA_DM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT Failed");
+ }
+ break;
+ case BTA_DM_BLE_5_GAP_ADV_TERMINATED_EVT:
+ if (!bt_mesh_is_adv_inst_used(params->adv_term.adv_handle)) {
+ goto transfer_to_user;
+ }
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(params->adv_term.adv_handle));
+#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+ if (params->adv_term.status == 0x43 || /* Limit reached */
+ params->adv_term.status == 0x3C) { /* Advertising timeout */
+ ble_mesh_adv_task_wakeup(ADV_TASK_MESH_ADV_INST_EVT);
+ }
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+ /**
+ * This judgment is to distinguish between the termination
+ * events of BLE connectable broadcasting and proxy connectable
+ * adv under the same instance ID, that is, when the status is 0.
+ *
+ * Since the host task and adv task are currently operated in
+ * series, there is no need to consider competition issues between
+ * tasks.
+ *
+ * @attention: once multiple adv instances are used, the adv task
+ * and host will be asynchronous, and it is necessary to consider
+ * the issue of resource competition.
+ */
+ if (bt_mesh_is_ble_adv_running() &&
+ params->adv_term.status == 0x00) {
+ /* The unset operation must be performed before waking up the
+ * adv task; performing the unset after waking up the adv task
+ * could lead to resource contention issues.
+ */
+ bt_mesh_unset_ble_adv_running();
+ ble_mesh_adv_task_wakeup(ADV_TASK_MESH_ADV_INST_EVT);
+ }
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
+#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+ break;
+ case BTA_DM_BLE_5_GAP_EXT_ADV_REPORT_EVT:
+ if (!bt_mesh_scan_result_process(&params->ext_adv_report)) {
+ bt_mesh_ble_ext_adv_report(&params->ext_adv_report);
+ }
+ break;
+ case BTA_DM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT:
+ if (params->scan_start.status != BTM_SUCCESS) {
+ BT_ERR("BTA_DM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT Failed");
+ }
+ break;
+ case BTA_DM_BLE_5_GAP_EXT_SCAN_STOP_COMPLETE_EVT:
+ if (params->scan_stop.status != BTM_SUCCESS) {
+ BT_ERR("BTM_BLE_5_GAP_EXT_SCAN_START_COMPLETE_EVT Failed");
+ }
+ break;
+ default:
+ goto transfer_to_user;
+ }
+
+ return;
+
+transfer_to_user:
+ btc_ble_5_gap_callback(event, params);
+}
+#endif
static bool valid_adv_param(const struct bt_mesh_adv_param *param)
{
@@ -203,7 +414,12 @@ static bool valid_adv_param(const struct bt_mesh_adv_param *param)
return true;
}
+#if CONFIG_BLE_MESH_USE_BLE_50
+static int set_adv_data(uint16_t hci_op, const uint8_t inst_id,
+ const struct bt_mesh_adv_data *ad, size_t ad_len)
+#else
static int set_adv_data(uint16_t hci_op, const struct bt_mesh_adv_data *ad, size_t ad_len)
+#endif
{
struct bt_mesh_hci_cp_set_adv_data param = {0};
int i;
@@ -225,16 +441,22 @@ static int set_adv_data(uint16_t hci_op, const struct bt_mesh_adv_data *ad, size
param.len += ad[i].data_len;
}
+#if CONFIG_BLE_MESH_USE_BLE_50
+ BTA_DmBleGapConfigExtAdvDataRaw(hci_op == BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA,
+ inst_id, param.len, param.data);
+#else
/* Set adv data and scan rsp data. */
if (hci_op == BLE_MESH_HCI_OP_SET_ADV_DATA) {
BLE_MESH_BTM_CHECK_STATUS(BTM_BleWriteAdvDataRaw(param.data, param.len));
} else if (hci_op == BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA) {
BLE_MESH_BTM_CHECK_STATUS(BTM_BleWriteScanRspRaw(param.data, param.len));
}
+#endif
return 0;
}
+#if !CONFIG_BLE_MESH_USE_BLE_50
static void start_adv_completed_cb(uint8_t status)
{
#if BLE_MESH_DEV
@@ -243,6 +465,7 @@ static void start_adv_completed_cb(uint8_t status)
}
#endif
}
+#endif
static bool valid_scan_param(const struct bt_mesh_scan_param *param)
{
@@ -274,15 +497,54 @@ static bool valid_scan_param(const struct bt_mesh_scan_param *param)
static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
uint8_t filter_dup, uint8_t scan_fil_policy)
{
+#if !CONFIG_BLE_MESH_USE_BLE_50
uint8_t addr_type_own = BLE_MESH_ADDR_PUBLIC; /* Currently only support Public Address */
tGATT_IF client_if = 0xFF; /* Default GATT interface id */
+#endif
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+ tBTA_DM_BLE_EXT_SCAN_PARAMS ext_scan_params = {0};
+
+ if (interval == 0 ||
+ interval < window) {
+ BT_ERR("invalid scan param itvl %d win %d", interval, window);
+ return EINVAL;
+ }
+
+ ext_scan_params.own_addr_type = BLE_MESH_ADDR_PUBLIC;
+ ext_scan_params.filter_policy = scan_fil_policy;
+ ext_scan_params.scan_duplicate = filter_dup;
+ if (window == 0) {
+ ext_scan_params.cfg_mask = BTM_BLE_GAP_EXT_SCAN_CODE_MASK;
+ } else if (interval > window) {
+ ext_scan_params.cfg_mask = BTM_BLE_GAP_EXT_SCAN_UNCODE_MASK | BTM_BLE_GAP_EXT_SCAN_CODE_MASK;
+ } else {
+ // interval == window
+ ext_scan_params.cfg_mask = BTM_BLE_GAP_EXT_SCAN_UNCODE_MASK;
+ }
+
+ ext_scan_params.uncoded_cfg.scan_type = scan_type;
+ ext_scan_params.uncoded_cfg.scan_interval = interval;
+ ext_scan_params.uncoded_cfg.scan_window = window;
+
+ ext_scan_params.coded_cfg.scan_type = scan_type;
+ ext_scan_params.coded_cfg.scan_interval = interval;
+ ext_scan_params.coded_cfg.scan_window = interval - window;
+
+ BTA_DmBleGapSetExtScanParams(&ext_scan_params);
+
+ BTM_BleGapRegisterCallback(ble_mesh_5_gap_callback);
+
+ BTA_DmBleGapExtScan(true, 0, 0);
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
BLE_MESH_BTM_CHECK_STATUS(
BTM_BleSetScanFilterParams(client_if, interval, window, scan_type, addr_type_own,
filter_dup, scan_fil_policy, NULL));
/* BLE Mesh scan permanently, so no duration of scan here */
BLE_MESH_BTM_CHECK_STATUS(BTM_BleScan(true, 0, bt_mesh_scan_results_cb, NULL, NULL));
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if BLE_MESH_DEV
if (scan_type == BLE_MESH_SCAN_ACTIVE) {
@@ -295,22 +557,32 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
return 0;
}
+#if !CONFIG_BLE_MESH_USE_BLE_50
static void bt_mesh_scan_result_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
{
- struct net_buf_simple buf = {0};
- bt_mesh_addr_t addr = {0};
+ struct bt_mesh_adv_report adv_rpt = {0};
BT_DBG("%s, event %d", __func__, event);
if (event == BTA_DM_INQ_RES_EVT) {
/* TODO: How to process scan response here? PS: p_data->inq_res.scan_rsp_len */
- addr.type = p_data->inq_res.ble_addr_type;
- memcpy(addr.val, p_data->inq_res.bd_addr, BLE_MESH_ADDR_LEN);
- net_buf_simple_init_with_data(&buf, p_data->inq_res.p_eir, p_data->inq_res.adv_data_len);
+ adv_rpt.addr.type = p_data->inq_res.ble_addr_type;
+ adv_rpt.rssi = p_data->inq_res.rssi;
+ adv_rpt.adv_type = p_data->inq_res.ble_evt_type;
+
+ memcpy(adv_rpt.addr.val, p_data->inq_res.bd_addr, BLE_MESH_ADDR_LEN);
+
+ net_buf_simple_init_with_data(&adv_rpt.adv_data, p_data->inq_res.p_eir, p_data->inq_res.adv_data_len);
if (bt_mesh_scan_dev_found_cb) {
- bt_mesh_scan_dev_found_cb(&addr, p_data->inq_res.rssi, p_data->inq_res.ble_evt_type, &buf, p_data->inq_res.scan_rsp_len);
+ bt_mesh_scan_dev_found_cb(&adv_rpt);
+
+ if (p_data->inq_res.scan_rsp_len) {
+ adv_rpt.adv_type = BLE_MESH_ADV_SCAN_RSP;
+ net_buf_simple_init_with_data(&adv_rpt.adv_data, p_data->inq_res.p_eir + p_data->inq_res.adv_data_len, p_data->inq_res.scan_rsp_len);
+ bt_mesh_scan_dev_found_cb(&adv_rpt);
+ }
}
} else if (event == BTA_DM_INQ_CMPL_EVT) {
BT_INFO("Scan completed, number of scan response %d", p_data->inq_cmpl.num_resps);
@@ -318,7 +590,133 @@ static void bt_mesh_scan_result_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARC
BT_WARN("Unexpected scan result event %d", event);
}
}
+#endif
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+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,
+ const struct bt_mesh_adv_data *sd, size_t sd_len)
+{
+ tBTA_DM_BLE_GAP_EXT_ADV_PARAMS ext_adv_params = {0};
+ tBTA_DM_BLE_EXT_ADV ext_adv = {0};
+ uint16_t interval = 0U;
+ int err = 0;
+
+ assert(param);
+
+#if BLE_MESH_DEV
+ if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
+ return -EALREADY;
+ }
+#endif
+
+ if (!valid_adv_param(param)) {
+ BT_ERR("Invalid adv parameters");
+ return -EINVAL;
+ }
+
+ memset(&ext_adv_params, 0, sizeof(tBTA_DM_BLE_GAP_EXT_ADV_PARAMS));
+
+ if (param->options & BLE_MESH_ADV_OPT_CONNECTABLE) {
+ ext_adv_params.type = BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_IND;
+ } else if (sd != NULL) {
+ 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;
+ }
+ }
+
+#if CONFIG_BLE_MESH_PRB_SRV
+ /* NOTE: When a Mesh Private beacon is advertised, the Mesh Private beacon shall
+ * use a resolvable private address or a non-resolvable private address in the
+ * AdvA field of the advertising PDU.
+ */
+ if (ad->type == BLE_MESH_DATA_MESH_BEACON && ad->data[0] == BEACON_TYPE_PRIVATE) {
+ ext_adv_params.own_addr_type = BLE_MESH_ADDR_RANDOM;
+ } else {
+ ext_adv_params.own_addr_type = BLE_MESH_ADDR_PUBLIC;
+ }
+#else
+ ext_adv_params.own_addr_type = BLE_MESH_ADDR_PUBLIC;
+#endif
+ ext_adv_params.sid = inst_id;
+ ext_adv_params.max_skip = 0;
+ ext_adv_params.tx_power = 0x7F;
+ 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;
+
+ interval = param->interval_min;
+
+#if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL
+ /* If non-connectable mesh packets are transmitted with an adv interval
+ * not smaller than 10ms, then we will use a random adv interval between
+ * [interval / 2, interval] for them.
+ */
+ if (ext_adv_params.type == BTA_DM_BLE_GAP_SET_EXT_ADV_PROP_LEGACY_NONCONN
+ && interval >= 16) {
+ interval >>= 1;
+ interval += (bt_mesh_get_rand() % (interval + 1));
+
+ BT_DBG("%u->%u", param->interval_min, interval);
+ }
+#endif
+
+ 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);
+
+ err = set_adv_data(BLE_MESH_HCI_OP_SET_ADV_DATA, inst_id, ad, ad_len);
+ if (err) {
+ BT_ERR("Failed to set adv data, err %d", err);
+ return err;
+ }
+
+ /*
+ * We need to set SCAN_RSP when enabling advertising type that allows
+ * for Scan Requests.
+ *
+ * If sd was not provided but we enable connectable undirected
+ * advertising sd needs to be cleared from values set by previous calls.
+ * Clearing sd is done by calling set_adv_data() with NULL data and zero len.
+ * So following condition check is unusual but correct.
+ */
+ if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) {
+ err = set_adv_data(BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA, inst_id, sd, sd_len);
+ if (err) {
+ BT_ERR("Failed to set scan rsp data err %d", err);
+ return err;
+ }
+ }
+
+ ext_adv.instance = inst_id;
+ ext_adv.duration = param->adv_duration / 10;
+ ext_adv.max_events = param->adv_count;
+
+ BTA_DmBleGapExtAdvEnable(true, 1, &ext_adv);
+
+#if BLE_MESH_DEV
+ bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
+
+ if (!(param->options & BLE_MESH_ADV_OPT_ONE_TIME)) {
+ bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
+ }
+#endif
+
+ return 0;
+}
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
/* APIs functions */
int bt_le_adv_start(const struct bt_mesh_adv_param *param,
const struct bt_mesh_adv_data *ad, size_t ad_len,
@@ -346,7 +744,7 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
err = set_adv_data(BLE_MESH_HCI_OP_SET_ADV_DATA, ad, ad_len);
if (err) {
- BT_ERR("Failed to set adv data");
+ BT_ERR("Failed to set adv data, err %d", err);
return err;
}
@@ -362,7 +760,7 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) {
err = set_adv_data(BLE_MESH_HCI_OP_SET_SCAN_RSP_DATA, sd, sd_len);
if (err) {
- BT_ERR("Failed to set scan rsp data");
+ BT_ERR("Failed to set scan rsp data, err %d", err);
return err;
}
}
@@ -425,8 +823,100 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
return 0;
}
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+#if CONFIG_BLE_MESH_USE_BLE_50
+#if !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+static bool _ble_adv_running_flag;
+
+static inline void bt_mesh_set_ble_adv_running()
+{
+ _ble_adv_running_flag = true;
+}
+
+static inline void bt_mesh_unset_ble_adv_running()
+{
+ _ble_adv_running_flag = false;
+}
+
+static inline bool bt_mesh_is_ble_adv_running()
+{
+ return _ble_adv_running_flag == true;
+}
+#endif /* !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+
+int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
+ const struct bt_mesh_ble_adv_param *param,
+ const struct bt_mesh_ble_adv_data *data)
+{
+ tBTA_DM_BLE_GAP_EXT_ADV_PARAMS ext_adv_params = {0};
+ tBTA_DM_BLE_EXT_ADV ext_adv = {0};
+ struct bt_mesh_hci_cp_set_adv_data set = {0};
+
+ if (data && param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
+ param->adv_type != BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
+ if (data->adv_data_len) {
+ set.len = data->adv_data_len;
+ memcpy(set.data, data->adv_data, data->adv_data_len);
+ BTA_DmBleGapConfigExtAdvDataRaw(false, inst_id, set.len, set.data);
+ }
+ if (data->scan_rsp_data_len && param->adv_type != BLE_MESH_ADV_NONCONN_IND) {
+ set.len = data->scan_rsp_data_len;
+ memcpy(set.data, data->scan_rsp_data, data->scan_rsp_data_len);
+ BTA_DmBleGapConfigExtAdvDataRaw(true, inst_id, set.len, set.data);
+ }
+ }
+
+ switch (param->adv_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:
+ ext_adv_params.type = param->adv_type;
+ break;
+ default:
+ BT_ERR("Unsupported adv type %d", param->adv_type);
+ return -EINVAL;
+ }
+
+ ext_adv_params.max_skip = 0;
+ ext_adv_params.tx_power = 0x7F;
+ ext_adv_params.sid = inst_id;
+ ext_adv_params.scan_req_notif = false;
+ ext_adv_params.own_addr_type = param->own_addr_type;
+ ext_adv_params.interval_min = param->interval;
+ ext_adv_params.interval_max = param->interval;
+ 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;
+
+ if (param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID ||
+ param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID ||
+ param->adv_type == BLE_MESH_ADV_DIRECT_IND ||
+ param->adv_type == BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
+ ext_adv_params.peer_addr_type = param->peer_addr_type;
+ memcpy(ext_adv_params.peer_addr, param->peer_addr, BLE_MESH_ADDR_LEN);
+ }
+
+ ext_adv.instance = inst_id;
+ ext_adv.duration = param->duration;
+ ext_adv.max_events = param->count;
+
+ /* Check if we can start adv using BTM_BleSetAdvParamsStartAdvCheck */
+ BTA_DmBleGapExtAdvSetParams(inst_id, &ext_adv_params);
+
+ BTA_DmBleGapExtAdvEnable(true, 1, &ext_adv);
+
+#if !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ bt_mesh_set_ble_adv_running();
+#endif
+
+ return 0;
+}
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
const struct bt_mesh_ble_adv_data *data)
{
@@ -468,8 +958,32 @@ int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
return 0;
}
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
+#if CONFIG_BLE_MESH_USE_BLE_50
+int bt_le_ext_adv_stop(uint8_t inst_id)
+{
+ tBTA_DM_BLE_EXT_ADV ext_adv = {0};
+
+#if BLE_MESH_DEV
+ bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
+ if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
+ return 0;
+ }
+#endif
+
+ ext_adv.instance = inst_id;
+
+ BTA_DmBleGapExtAdvEnable(false, 1, &ext_adv);
+
+#if BLE_MESH_DEV
+ bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
+#endif
+
+ return 0;
+}
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_adv_stop(void)
{
#if BLE_MESH_DEV
@@ -487,6 +1001,7 @@ int bt_le_adv_stop(void)
return 0;
}
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t cb)
{
@@ -528,7 +1043,11 @@ int bt_le_scan_stop(void)
return -EALREADY;
}
+#if CONFIG_BLE_MESH_USE_BLE_50
+ BTA_DmBleGapExtScan(false, 0 ,0);
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
BLE_MESH_BTM_CHECK_STATUS(BTM_BleScan(false, 0, NULL, NULL, NULL));
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
bt_mesh_scan_dev_found_cb = NULL;
@@ -655,6 +1174,19 @@ static void bt_mesh_bta_gatts_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
/* When connection is created, advertising will be stopped automatically. */
bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
#endif
+
+#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
+ /* Check if this connection is created by Proxy client */
+ for (size_t i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
+ if (!memcmp(bt_mesh_gattc_info[i].addr.val, p_data->conn.remote_bda, BLE_MESH_ADDR_LEN)) {
+ BT_WARN("Already create connection with %s by proxy client",
+ bt_hex(p_data->conn.remote_bda, BLE_MESH_ADDR_LEN));
+ return;
+ }
+ }
+#endif
if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->connected != NULL) {
uint8_t index = BLE_MESH_GATT_GET_CONN_ID(p_data->conn.conn_id);
if (index < BLE_MESH_MAX_CONN) {
@@ -1196,6 +1728,7 @@ uint16_t bt_mesh_gattc_get_service_uuid(struct bt_mesh_conn *conn)
int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid)
{
+ tBTA_BLE_CONN_PARAMS conn_1m_param = {0};
uint8_t zero[6] = {0};
int i;
@@ -1238,21 +1771,49 @@ int bt_mesh_gattc_conn_create(const bt_mesh_addr_t *addr, uint16_t service_uuid)
}
if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
+#if CONFIG_BLE_MESH_USE_BLE_50
+ BTA_DmBleGapExtScan(false, 0 ,0);
+#else
BLE_MESH_BTM_CHECK_STATUS(BTM_BleScan(false, 0, NULL, NULL, NULL));
+#endif
bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
}
BT_DBG("Create conn with %s", bt_hex(addr->val, BLE_MESH_ADDR_LEN));
+#if CONFIG_BLE_MESH_USE_BLE_50
/* Min_interval: 15ms
* Max_interval: 15ms
* Slave_latency: 0x0
* Supervision_timeout: 1s
*/
- BTA_DmSetBlePrefConnParams(bt_mesh_gattc_info[i].addr.val, 0x18, 0x18, 0x00, 0x64);
-
- BTA_GATTC_Open(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val,
- bt_mesh_gattc_info[i].addr.type, true, BTA_GATT_TRANSPORT_LE, FALSE);
+ conn_1m_param.scan_interval = 0x0020;
+ conn_1m_param.scan_window = 0x0020;
+ conn_1m_param.interval_min = 0x18;
+ conn_1m_param.interval_max = 0x18;
+ conn_1m_param.latency = 0;
+ conn_1m_param.supervision_timeout = 0x64;
+ conn_1m_param.min_ce_len = 0;
+ conn_1m_param.max_ce_len = 0;
+
+ BTA_GATTC_Enh_Open(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val,
+ bt_mesh_gattc_info[i].addr.type, true, BTA_GATT_TRANSPORT_LE, TRUE, BLE_ADDR_UNKNOWN_TYPE,
+ BTA_BLE_PHY_1M_MASK, &conn_1m_param, NULL, NULL);
+#else
+ /* Min_interval: 15ms
+ * Max_interval: 15ms
+ * Slave_latency: 0x0
+ * Supervision_timeout: 1s
+ */
+ conn_1m_param.interval_min = 0x18;
+ conn_1m_param.interval_max = 0x18;
+ conn_1m_param.latency = 0;
+ conn_1m_param.supervision_timeout = 0x64;
+
+ BTA_GATTC_Enh_Open(bt_mesh_gattc_if, bt_mesh_gattc_info[i].addr.val,
+ bt_mesh_gattc_info[i].addr.type, true, BTA_GATT_TRANSPORT_LE, FALSE, BLE_ADDR_UNKNOWN_TYPE,
+ BTA_BLE_PHY_1M_MASK, &conn_1m_param, NULL, NULL);
+#endif
return 0;
}
@@ -1592,8 +2153,10 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
if (bt_mesh_gattc_info[i].conn.handle == handle) {
if (bt_mesh_gattc_info[i].wr_desc_done == false) {
- BT_DBG("Receive notification before finishing to write ccc");
+ BT_WARN("Receive notification before finishing to write ccc");
+#if !CONFIG_BLE_MESH_BQB_TEST
return;
+#endif
}
conn = &bt_mesh_gattc_info[i].conn;
@@ -1653,11 +2216,15 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
* use BTM_BleScan() to re-enable scan.
*/
if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
+#if CONFIG_BLE_MESH_USE_BLE_50
+ BTA_DmBleGapExtScan(true, 0 ,0);
+#else
tBTM_STATUS status = BTM_BleScan(true, 0, bt_mesh_scan_results_cb, NULL, NULL);
if (status != BTM_SUCCESS && status != BTM_CMD_STARTED) {
BT_ERR("Invalid scan status %d", status);
break;
}
+#endif
bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING);
}
break;
diff --git a/lib/bt/esp_ble_mesh/core/cfg_srv.c b/lib/bt/esp_ble_mesh/core/cfg_srv.c
index 9d91cb21..fe605939 100644
--- a/lib/bt/esp_ble_mesh/core/cfg_srv.c
+++ b/lib/bt/esp_ble_mesh/core/cfg_srv.c
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -30,7 +30,9 @@
#include "mesh/common.h"
#include "heartbeat.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#define DEFAULT_TTL 7
@@ -38,6 +40,158 @@ static struct bt_mesh_cfg_srv *conf;
static struct label labels[CONFIG_BLE_MESH_LABEL_COUNT];
+#if !CONFIG_BLE_MESH_V11_SUPPORT
+const void *comp_0;
+
+static uint8_t bt_mesh_comp_page_check(uint8_t page, bool largest)
+{
+ /* If the page doesn't exist, TWO situations currently:
+ * 1. For Composition Data Get:
+ * With the Page field set to the largest page number of
+ * the Composition Data that the node supports and that is
+ * less than the Page field value of the received Config
+ * Composition Data Get message;
+ * 2. For Large Composition Data Get:
+ * The Page field shall be set to the largest page number
+ * of the Composition Data that the node supports.
+ */
+ ARG_UNUSED(largest);
+
+ if (page != 0) {
+ BT_WARN("Composition Data Page %d not exists", page);
+ }
+
+ return 0;
+}
+
+static inline uint16_t get_comp_elem_size(struct bt_mesh_elem *elem)
+{
+ return (4 + elem->model_count * 2 + elem->vnd_model_count * 4);
+}
+
+static uint16_t get_comp_data_size(const struct bt_mesh_comp *comp)
+{
+ uint16_t size = 10; /* CID + PID + VID + CRPL + Features */
+
+ for (int i = 0; i < comp->elem_count; i++) {
+ size += get_comp_elem_size(&(comp->elem[i]));
+ }
+
+ return size;
+}
+
+static void get_comp_data(struct net_buf_simple *buf,
+ const struct bt_mesh_comp *comp,
+ bool full_element)
+{
+ struct bt_mesh_model *model = NULL;
+ struct bt_mesh_elem *elem = NULL;
+ uint16_t feat = 0;
+
+ if (IS_ENABLED(CONFIG_BLE_MESH_RELAY)) {
+ feat |= BLE_MESH_FEAT_RELAY;
+ }
+
+ if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
+ feat |= BLE_MESH_FEAT_PROXY;
+ }
+
+ if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
+ feat |= BLE_MESH_FEAT_FRIEND;
+ }
+
+ if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
+ feat |= BLE_MESH_FEAT_LOW_POWER;
+ }
+
+ net_buf_simple_add_le16(buf, comp->cid);
+ net_buf_simple_add_le16(buf, comp->pid);
+ net_buf_simple_add_le16(buf, comp->vid);
+ net_buf_simple_add_le16(buf, CONFIG_BLE_MESH_CRPL);
+ net_buf_simple_add_le16(buf, feat);
+
+ for (size_t i = 0; i < comp->elem_count; i++) {
+ elem = &(comp->elem[i]);
+
+ /* If "full_element" is true, which means the complete list
+ * of models within the element needs to fit in the data,
+ * otherwise the element shall not be reported.
+ */
+ if (full_element &&
+ net_buf_simple_tailroom(buf) < get_comp_elem_size(elem)) {
+ return;
+ }
+
+ net_buf_simple_add_le16(buf, elem->loc);
+ net_buf_simple_add_u8(buf, elem->model_count);
+ net_buf_simple_add_u8(buf, elem->vnd_model_count);
+
+ for (size_t j = 0; j < elem->model_count; j++) {
+ model = &(elem->models[j]);
+ net_buf_simple_add_le16(buf, model->id);
+ }
+
+ for (size_t j = 0; j < elem->vnd_model_count; j++) {
+ model = &(elem->vnd_models[j]);
+ net_buf_simple_add_le16(buf, model->vnd.company);
+ net_buf_simple_add_le16(buf, model->vnd.id);
+ }
+ }
+}
+
+static int fetch_comp_data(struct net_buf_simple *buf,
+ const struct bt_mesh_comp *comp,
+ uint8_t page, uint16_t offset,
+ bool full_element)
+{
+ uint16_t size = get_comp_data_size(comp);
+
+ if (offset >= size) {
+ BT_WARN("Too large offset %d for comp data %d, size %d",
+ page, offset, size);
+ return 0;
+ }
+
+ if (net_buf_simple_tailroom(buf) < 10 ||
+ size - offset > net_buf_simple_tailroom(buf)) {
+ BT_ERR("Too small buffer for comp data %d, %d, expected %d",
+ page, buf->size, size - offset);
+ return -EINVAL;
+ }
+
+ if (offset) {
+ struct net_buf_simple *pdu = bt_mesh_alloc_buf(size);
+ if (pdu == NULL) {
+ BT_ERR("%s, Out of memory", __func__);
+ return -ENOMEM;
+ }
+
+ get_comp_data(pdu, comp, false);
+
+ /* Get part of Composition Data Page 0/128 */
+ net_buf_simple_add_mem(buf, pdu->data + offset, pdu->len - offset);
+
+ bt_mesh_free_buf(pdu);
+ } else {
+ get_comp_data(buf, comp, full_element);
+ }
+
+ return 0;
+}
+
+static int bt_mesh_get_comp_data(struct net_buf_simple *buf,
+ uint8_t page, uint16_t offset,
+ bool full_element)
+{
+ if (page == 0) {
+ return fetch_comp_data(buf, comp_0, page, offset, full_element);
+ }
+
+ BT_ERR("Invalid Composition Data Page %d", page);
+ return -EINVAL;
+}
+#endif /* !CONFIG_BLE_MESH_V11_SUPPORT */
+
static void comp_data_get(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
@@ -1133,7 +1287,7 @@ static struct label *va_find(const uint8_t *label_uuid,
return match;
}
-static uint8_t va_add(uint8_t *label_uuid, uint16_t *addr)
+uint8_t va_add(uint8_t *label_uuid, uint16_t *addr)
{
struct label *update = NULL, *free_slot = NULL;
@@ -1141,6 +1295,9 @@ static uint8_t va_add(uint8_t *label_uuid, uint16_t *addr)
if (update) {
update->ref++;
va_store(update);
+ if (addr) {
+ *addr = update->addr;
+ }
return STATUS_SUCCESS;
}
@@ -1160,7 +1317,7 @@ static uint8_t va_add(uint8_t *label_uuid, uint16_t *addr)
return STATUS_SUCCESS;
}
-static uint8_t va_del(uint8_t *label_uuid, uint16_t *addr)
+uint8_t va_del(uint8_t *label_uuid, uint16_t *addr)
{
struct label *update = NULL;
@@ -2758,7 +2915,7 @@ static void node_reset(struct bt_mesh_model *model,
bt_mesh_model_msg_init(&msg, OP_NODE_RESET_STATUS);
- /* Send the response first since we wont have any keys left to
+ /* Send the response first since we won't have any keys left to
* send it later.
*/
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
diff --git a/lib/bt/esp_ble_mesh/core/crypto.c b/lib/bt/esp_ble_mesh/core/crypto.c
index 9b762fb5..2577c65e 100644
--- a/lib/bt/esp_ble_mesh/core/crypto.c
+++ b/lib/bt/esp_ble_mesh/core/crypto.c
@@ -22,7 +22,9 @@
#include "mesh/common.h"
#include "mesh/adapter.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#define NET_MIC_LEN(pdu) (((pdu)[1] & 0x80) ? 8 : 4)
#define APP_MIC_LEN(aszmic) ((aszmic) ? 8 : 4)
diff --git a/lib/bt/esp_ble_mesh/core/ext_adv.c b/lib/bt/esp_ble_mesh/core/ext_adv.c
new file mode 100644
index 00000000..b8b4d231
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/core/ext_adv.c
@@ -0,0 +1,427 @@
+/* Bluetooth Mesh */
+
+/*
+ * SPDX-FileCopyrightText: 2017 Intel Corporation
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+
+#include "mesh/kernel.h"
+#include "mesh.h"
+#include "mesh/hci.h"
+#include "mesh/common.h"
+#include "mesh/ffs.h"
+#include "ext_adv.h"
+#include "beacon.h"
+#include "prov_common.h"
+#include "foundation.h"
+#include "proxy_server.h"
+#include "proxy_client.h"
+#include "prov_pvnr.h"
+#include "mesh/adapter.h"
+
+#include "adv_common.h"
+#include "ble_adv.h"
+
+static struct bt_mesh_adv_queue *adv_queue;
+
+static struct bt_mesh_adv_inst *adv_insts;
+
+static inline void adv_send_start(uint16_t duration, int err,
+ const struct bt_mesh_send_cb *cb,
+ void *cb_data)
+{
+ if (cb && cb->start) {
+ cb->start(duration, err, cb_data);
+ }
+}
+
+static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb,
+ void *cb_data)
+{
+ if (cb && cb->end) {
+ cb->end(err, cb_data);
+ }
+}
+
+static inline int adv_send(struct bt_mesh_adv_inst *inst, uint16_t *adv_duration)
+{
+ struct net_buf *buf = inst->sending_buf;
+ const struct bt_mesh_send_cb *cb = BLE_MESH_ADV(buf)->cb;
+ void *cb_data = BLE_MESH_ADV(buf)->cb_data;
+ struct bt_mesh_adv_param param = {0};
+ uint16_t duration = 0U, adv_int = 0U;
+ struct bt_mesh_adv_data ad = {0};
+ int err = 0;
+
+ BT_DBG("type %u len %u: %s", BLE_MESH_ADV(buf)->type,
+ buf->len, bt_hex(buf->data, buf->len));
+
+ switch (BLE_MESH_ADV(buf)->type) {
+ case BLE_MESH_ADV_PROV:
+ case BLE_MESH_ADV_DATA:
+#if CONFIG_BLE_MESH_FRIEND
+ case BLE_MESH_ADV_FRIEND:
+#endif
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF
+ case BLE_MESH_ADV_RELAY_DATA:
+#endif
+#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
+ case BLE_MESH_ADV_PROXY_SOLIC:
+#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);
+
+ BT_DBG("count %u interval %ums duration %ums",
+ BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1, adv_int,
+ duration);
+
+ ad.type = adv_type[BLE_MESH_ADV(buf)->type];
+ ad.data_len = buf->len;
+ ad.data = buf->data;
+
+ param.options = 0U;
+ param.interval_min = ADV_SCAN_UNIT(adv_int);
+ param.interval_max = param.interval_min;
+
+ param.adv_duration = duration;
+ param.adv_count = BLE_MESH_TRANSMIT_COUNT(BLE_MESH_ADV(buf)->xmit) + 1;
+
+ param.primary_phy = BLE_MESH_ADV_PHY_1M;
+ param.secondary_phy = BLE_MESH_ADV_PHY_1M;
+
+#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
+ if (BLE_MESH_ADV(buf)->type == BLE_MESH_ADV_PROXY_SOLIC) {
+ bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
+ struct bt_mesh_adv_data solic_ad[2] = {
+ BLE_MESH_ADV_DATA_BYTES(BLE_MESH_DATA_UUID16_ALL, 0x59, 0x18),
+ BLE_MESH_ADV_DATA(BLE_MESH_DATA_SVC_DATA16, buf->data, buf->len),
+ };
+ err = bt_le_ext_adv_start(CONFIG_BLE_MESH_ADV_INST_ID, &param, solic_ad, ARRAY_SIZE(solic_ad), NULL, 0);
+ } else
+#endif
+ {
+ bt_mesh_adv_buf_ref_debug(__func__, buf, 4U, BLE_MESH_BUF_REF_SMALL);
+ err = bt_le_ext_adv_start(inst->id, &param, &ad, 1, NULL, 0);
+ }
+ }
+ break;
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+ case BLE_MESH_ADV_BLE:
+ struct bt_mesh_ble_adv_data data = {0};
+ struct bt_mesh_ble_adv_tx *tx = cb_data;
+
+ if (tx == NULL) {
+ BT_ERR("Invalid adv user data");
+ net_buf_unref(buf);
+ return -EINVAL;
+ }
+
+ BT_DBG("interval %dms, duration %dms, period %dms, count %d",
+ ADV_SCAN_INT(tx->param.interval), tx->param.duration,
+ tx->param.period, tx->param.count);
+
+ data.adv_data_len = tx->buf->data[0];
+ if (data.adv_data_len) {
+ memcpy(data.adv_data, tx->buf->data + 1, data.adv_data_len);
+ }
+ data.scan_rsp_data_len = tx->buf->data[data.adv_data_len + 1];
+ if (data.scan_rsp_data_len) {
+ memcpy(data.scan_rsp_data, tx->buf->data + data.adv_data_len + 2, data.scan_rsp_data_len);
+ }
+ duration = tx->param.duration;
+
+ bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
+
+ err = bt_mesh_ble_ext_adv_start(inst->id, &tx->param, &data);
+ break;
+#endif
+ default:
+ BT_ERR("Error Type");
+ break;
+ }
+
+ adv_send_start(duration, err, cb, cb_data);
+ if (err) {
+ BT_ERR("Start advertising failed: err %d", err);
+ return err;
+ }
+
+ *adv_duration = duration;
+ BT_DBG("Advertising started. %u ms", duration);
+ return 0;
+}
+
+static inline int find_valid_msg_from_queue(bt_mesh_queue_t *msg_queue, bt_mesh_msg_t *msg)
+{
+ while(uxQueueMessagesWaiting(msg_queue->handle)) {
+ xQueueReceive(msg_queue->handle, msg, K_WAIT(K_FOREVER));
+
+ /* In the previous adv task design, only
+ * the *buf of messages pushed to the queue
+ * by adv_update would be empty, but in the
+ * new design, there is a new processing method
+ * for adv_update's messages,
+ * so *buf here cannot be empty. */
+ assert(msg->arg);
+
+ /* If the message is canceled for advertising,
+ * then continue to retrieve the next message
+ * from that queue. */
+ if (!bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(BLE_MESH_MSG_NET_BUF(msg)), 1, 0)) {
+ bt_mesh_adv_buf_ref_debug(__func__, BLE_MESH_MSG_NET_BUF(msg), 1U, BLE_MESH_BUF_REF_EQUAL);
+ /* Cancel the adv task's reference to this data packet.
+ * tips: The reference of buffer by adv_task occurs
+ * when the buffer is pushed into the queue.
+ */
+ net_buf_unref(BLE_MESH_MSG_NET_BUF(msg));
+ /* Avoid reading the last message in the queue, which could lead
+ * to pointing to an invalid buffer due to the absence of other
+ * messages in the queue. */
+ msg->arg = NULL;
+ continue;
+ }
+
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF
+ /* If the relay message should be ignored,
+ * then continue to retrieve the next message
+ * from that queue. */
+ if (msg->relay && bt_mesh_ignore_relay_packet(msg->timestamp)) {
+ /* If the interval between "current time - msg.timestamp" is bigger than
+ * BLE_MESH_RELAY_TIME_INTERVAL, this relay packet will not be sent.
+ */
+ BT_DBG("Ignore relay packet");
+ net_buf_unref(BLE_MESH_MSG_NET_BUF(msg));
+ msg->arg = NULL;
+ continue;
+ }
+#endif
+ break;
+ }
+
+ if (msg->arg == NULL) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline int active_idle_adv_instance(uint32_t *update_evts, uint16_t *min_duration)
+{
+ uint32_t evts = 0;
+ uint16_t duration = K_FOREVER;
+ uint16_t cur_min_duration = K_FOREVER;
+ enum bt_mesh_adv_type adv_type = 0;
+ struct bt_mesh_adv_inst *instance = NULL;
+ bt_mesh_queue_t *msg_queue = NULL;
+ bt_mesh_msg_t msg = {0};
+ uint32_t spt_mask = 0;
+
+#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ if (!adv_insts[BLE_MESH_ADV_PROXY_INS].busy) {
+ BT_DBG("Mesh Proxy Advertising start");
+ duration = bt_mesh_proxy_server_adv_start();
+ if (duration < cur_min_duration) {
+ cur_min_duration = duration;
+ }
+ adv_insts[BLE_MESH_ADV_PROXY_INS].busy = true;
+ evts |= ADV_TASK_ADV_INST_EVT(adv_insts[BLE_MESH_ADV_PROXY_INS].id);
+ }
+#endif
+
+ for (int i = BLE_MESH_ADV_INS; i < BLE_MESH_ADV_INS_TYPES_NUM; i++) {
+ instance = &adv_insts[i];
+ if (instance->busy
+#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ || unlikely(instance->id == CONFIG_BLE_MESH_PROXY_ADV_INST_ID)
+#endif
+ ) {
+ continue;
+ }
+
+ spt_mask = instance->spt_mask;
+ adv_type = 0;
+
+ while(spt_mask) {
+ adv_type = find_lsb_set(spt_mask) - 1;
+ spt_mask &= ~BIT(adv_type);
+ msg_queue = &(bt_mesh_adv_types_mgnt_get(adv_type)->adv_q->q);
+
+ /* When there is no new message in the queue, *buf (aka: msg.arg)
+ * will be empty. */
+ if (find_valid_msg_from_queue(msg_queue, &msg)) {
+ BT_DBG("no valid message for instance %d", instance->id);
+ continue;
+ }
+
+ instance->sending_buf = (struct net_buf *)msg.arg;
+ if (adv_send(instance, &duration)) {
+ BT_ERR("adv start failed");
+ net_buf_unref(instance->sending_buf);
+ instance->sending_buf = NULL;
+ /* When this adv instance fails to broadcast, it could be
+ * due to some persistent issues, such as incorrect adv
+ * parameter settings, or it could be due to some temporary
+ * issues, such as memory allocation failure. Therefore, it
+ * is advisable to skip subsequent queue reads for this instance
+ * and attempt to broadcast subsequent data again next time,
+ * rather than disabling the adv instance. */
+ break;
+ }
+
+ if (duration < cur_min_duration) {
+ cur_min_duration = duration;
+ }
+
+ instance->busy = true;
+ evts |= ADV_TASK_ADV_INST_EVT(adv_insts[i].id);
+
+ /* Must be nullified to avoid affecting the next adv
+ * instance's judgment on whether the message queue
+ * is empty. */
+ msg.arg = NULL;
+ break;
+ }
+ }
+
+ *min_duration = cur_min_duration;
+ *update_evts |= evts;
+
+ return 0;
+}
+
+static uint32_t received_adv_evts_handle(uint32_t recv_evts)
+{
+ uint32_t evt = 0;
+
+ if (!recv_evts) {
+ return 0;
+ }
+
+ for (int i = 0; recv_evts && i < BLE_MESH_ADV_INS_TYPES_NUM; i++) {
+ evt = ADV_TASK_ADV_INST_EVT(adv_insts[i].id);
+ if (recv_evts & evt) {
+ recv_evts &= ~evt;
+#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
+CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ if (unlikely(i == BLE_MESH_ADV_PROXY_INS)) {
+ BT_DBG("Mesh Proxy Advertising auto stop");
+ bt_mesh_proxy_server_adv_flag_set(false);
+ } else
+#endif
+ {
+ /* adv_send_end maybe*/
+ adv_send_end(0, BLE_MESH_ADV(adv_insts[i].sending_buf)->cb, BLE_MESH_ADV(adv_insts[i].sending_buf)->cb_data);
+ bt_mesh_adv_buf_ref_debug(__func__, adv_insts[i].sending_buf, 4U, BLE_MESH_BUF_REF_SMALL);
+ net_buf_unref(adv_insts[i].sending_buf);
+ adv_insts[i].sending_buf = NULL;
+ }
+ adv_insts[i].busy = false;
+ }
+ }
+
+ return recv_evts;
+}
+
+static void adv_thread(void *p)
+{
+ uint16_t adv_duration = K_FOREVER;
+ uint32_t recv_evts = 0;
+ uint32_t wait_evts = 0;
+
+ BT_DBG("%s, starts", __func__);
+
+ while (1) {
+ adv_duration = K_FOREVER;
+ wait_evts |= ADV_TASK_PKT_SEND_EVT;
+
+ active_idle_adv_instance(&wait_evts, &adv_duration);
+
+ ble_mesh_adv_task_wait(wait_evts, adv_duration, &recv_evts);
+
+ wait_evts &= ~recv_evts;
+
+#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ if (recv_evts & ADV_TASK_PROXY_ADV_UPD_EVT) {
+ adv_insts[BLE_MESH_ADV_PROXY_INS].busy = false;
+ recv_evts &= ~ADV_TASK_PROXY_ADV_UPD_EVT;
+ }
+#endif
+
+ /**
+ * `recv_evts == ADV_TASK_PKT_SEND_EVT` indicates that new packets
+ * have been placed into the queue, and the advertising instances started
+ * previous have not yet stopped.
+ */
+ if (recv_evts == ADV_TASK_PKT_SEND_EVT) {
+ continue;
+ }
+
+ recv_evts = received_adv_evts_handle(recv_evts);
+
+ if (recv_evts) {
+ BT_ERR("Remain evts %08x to handle", recv_evts);
+ }
+ }
+}
+
+void bt_mesh_adv_update(void)
+{
+#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ BT_DBG("Mesh Proxy Advertising stopped manually");
+ bt_mesh_proxy_server_adv_stop();
+ if (adv_insts[BLE_MESH_ADV_PROXY_INS].busy) {
+ ble_mesh_adv_task_wakeup(ADV_TASK_PROXY_ADV_UPD_EVT);
+ }
+#endif
+}
+
+void bt_mesh_adv_init(void)
+{
+ bt_mesh_adv_common_init();
+
+ adv_insts = bt_mesh_get_adv_insts_set();
+ adv_queue = bt_mesh_adv_queue_get();
+
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF
+ bt_mesh_relay_adv_init();
+#endif
+
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+ bt_mesh_ble_adv_init();
+#endif
+
+ bt_mesh_adv_task_init(adv_thread);
+}
+
+#if CONFIG_BLE_MESH_DEINIT
+void bt_mesh_adv_deinit(void)
+{
+ bt_mesh_adv_task_deinit();
+
+ bt_mesh_adv_common_deinit();
+
+ adv_insts = NULL;
+
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF
+ bt_mesh_relay_adv_deinit();
+#endif
+
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+ bt_mesh_ble_adv_deinit();
+#endif
+}
+#endif /* CONFIG_BLE_MESH_DEINIT */
diff --git a/lib/bt/esp_ble_mesh/core/ext_adv.h b/lib/bt/esp_ble_mesh/core/ext_adv.h
new file mode 100644
index 00000000..3004db27
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/core/ext_adv.h
@@ -0,0 +1,39 @@
+/* Bluetooth Mesh */
+
+/*
+ * SPDX-FileCopyrightText: 2017 Intel Corporation
+ * SPDX-FileContributor: 2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _EXT_ADV_H_
+#define _EXT_ADV_H_
+
+#include "mesh/atomic.h"
+#include "mesh/access.h"
+#include "mesh/adapter.h"
+#include "mesh/queue.h"
+#include "adv_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline void bt_mesh_adv_send(struct net_buf *buf, uint8_t xmit,
+ const struct bt_mesh_send_cb *cb,
+ void *cb_data)
+{
+ bt_mesh_generic_adv_send(buf, xmit, cb, cb_data, BLE_MESH_ADDR_UNASSIGNED, BLE_MESH_ADDR_UNASSIGNED, false);
+}
+
+void bt_mesh_adv_update(void);
+
+void bt_mesh_adv_init(void);
+void bt_mesh_adv_deinit(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _EXT_ADV_H_ */
diff --git a/lib/bt/esp_ble_mesh/core/friend.c b/lib/bt/esp_ble_mesh/core/friend.c
index fca3cf13..99e41cd0 100644
--- a/lib/bt/esp_ble_mesh/core/friend.c
+++ b/lib/bt/esp_ble_mesh/core/friend.c
@@ -21,18 +21,12 @@
#include "mesh/common.h"
#include "pvnr_mgmt.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#ifdef CONFIG_BLE_MESH_FRIEND
-/* We reserve one extra buffer for each friendship, since we need to be able
- * to resend the last sent PDU, which sits separately outside of the queue.
- */
-#define FRIEND_BUF_COUNT ((CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE + 1) * \
- CONFIG_BLE_MESH_FRIEND_LPN_COUNT)
-
-#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), struct friend_adv, adv)
-
/* PDUs from Friend to the LPN should only be transmitted once with the
* smallest possible interval (20ms).
*
@@ -55,14 +49,6 @@ struct friend_pdu_info {
uint32_t iv_index;
};
-NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT,
- BLE_MESH_ADV_DATA_SIZE, NULL);
-
-static struct friend_adv {
- struct bt_mesh_adv adv;
- uint16_t app_idx;
-} adv_pool[FRIEND_BUF_COUNT];
-
enum {
BLE_MESH_FRIENDSHIP_TERMINATE_ESTABLISH_FAIL,
BLE_MESH_FRIENDSHIP_TERMINATE_POLL_TIMEOUT,
@@ -81,12 +67,6 @@ static struct bt_mesh_subnet *friend_subnet_get(uint16_t net_idx)
return bt_mesh_subnet_get(net_idx);
}
-static struct bt_mesh_adv *adv_alloc(int id)
-{
- adv_pool[id].app_idx = BLE_MESH_KEY_UNUSED;
- return &adv_pool[id].adv;
-}
-
static bool is_lpn_unicast(struct bt_mesh_friend *frnd, uint16_t addr)
{
if (frnd->lpn == BLE_MESH_ADDR_UNASSIGNED) {
@@ -183,7 +163,7 @@ static void friend_clear(struct bt_mesh_friend *frnd, uint8_t reason)
/* Cancel the sending if necessary */
if (frnd->pending_buf) {
bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 2U, BLE_MESH_BUF_REF_EQUAL);
- BLE_MESH_ADV(frnd->last)->busy = 0U;
+ bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(frnd->last), 0);
} else {
bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 1U, BLE_MESH_BUF_REF_EQUAL);
}
@@ -366,8 +346,7 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd,
{
struct net_buf *buf = NULL;
- buf = bt_mesh_adv_create_from_pool(&friend_buf_pool, adv_alloc,
- BLE_MESH_ADV_DATA, K_NO_WAIT);
+ buf = bt_mesh_adv_create_from_pool(BLE_MESH_ADV_FRIEND, K_NO_WAIT);
if (!buf) {
return NULL;
}
@@ -1321,6 +1300,8 @@ int bt_mesh_friend_init(void)
}
}
+ bt_mesh_frnd_adv_init();
+
friend_init = true;
return 0;
@@ -1347,8 +1328,7 @@ int bt_mesh_friend_deinit(void)
k_delayed_work_free(&frnd->clear.timer);
}
- bt_mesh_unref_buf_from_pool(&friend_buf_pool);
- memset(adv_pool, 0, sizeof(adv_pool));
+ bt_mesh_frnd_adv_deinit();
friend_init = false;
diff --git a/lib/bt/esp_ble_mesh/core/include/mesh/access.h b/lib/bt/esp_ble_mesh/core/include/mesh/access.h
index 86731036..fac49976 100644
--- a/lib/bt/esp_ble_mesh/core/include/mesh/access.h
+++ b/lib/bt/esp_ble_mesh/core/include/mesh/access.h
@@ -4,7 +4,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -348,7 +348,7 @@ struct bt_mesh_model_op {
* @return Mesh transmit value that can be used e.g. for the default
* values of the configuration model data.
*/
-#define BLE_MESH_TRANSMIT(count, int_ms) ((count) | ((((int_ms) / 10) - 1) << 3))
+#define BLE_MESH_TRANSMIT(count, int_ms) ((uint8_t)(count) | ((((int_ms) / 10) - 1) << 3))
/** @def BLE_MESH_TRANSMIT_COUNT
*
diff --git a/lib/bt/esp_ble_mesh/core/include/mesh/adapter.h b/lib/bt/esp_ble_mesh/core/include/mesh/adapter.h
index 1cb239a3..f02c9f5b 100644
--- a/lib/bt/esp_ble_mesh/core/include/mesh/adapter.h
+++ b/lib/bt/esp_ble_mesh/core/include/mesh/adapter.h
@@ -1,7 +1,7 @@
/*
* SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2015-2017 Intel Corporation
- * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -21,18 +21,78 @@ extern "C" {
#endif
/* BLE Mesh Max Connection Count */
+/**
+ * The maximum number of connection count is limited by
+ * the resources allocated by both the host and the controller
+ * components, so the actual number of available connections
+ * is the minimum of the resources from both.
+ *
+ * On the C3/S3 platform, the controller uses the macro `CONFIG_BT_CTRL_BLE_MAX_ACT`,
+ * but adv and scan also occupy this resource, so the actual number of available
+ * connections is (CONFIG_BT_CTRL_BLE_MAX_ACT - adv instance count - scan).
+ * However, the macro allocation on the host is entirely for connections,
+ * so on the C3/S3 platform, the maximum number of connectable devices should
+ * be determined by the configuration at the host minus the number of
+ * advertising instances and scan from the controller's configuration.
+*/
#ifdef CONFIG_BT_BLUEDROID_ENABLED
+#if CONFIG_IDF_TARGET_ESP32
+#define BLE_MESH_MAX_CONN 1
+#elif (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3)
+/* @todo: must ensure CONFIG_BT_CTRL_BLE_MAX_ACT is greater than 2 */
+#if CONFIG_BT_ACL_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2)
+/* decrease the adv,scan */
+#define BLE_MESH_MAX_CONN (CONFIG_BT_CTRL_BLE_MAX_ACT - 2)
+#else
#define BLE_MESH_MAX_CONN CONFIG_BT_ACL_CONNECTIONS
+#endif /* CONFIG_BT_ACL_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) */
+#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5
+#if CONFIG_BT_ACL_CONNECTIONS > CONFIG_BT_LE_MAX_CONNECTIONS
+#define BLE_MESH_MAX_CONN CONFIG_BT_LE_MAX_CONNECTIONS
+#else
+#define BLE_MESH_MAX_CONN CONFIG_BT_ACL_CONNECTIONS
+#endif /* CONFIG_BT_ACL_CONNECTIONS > CONFIG_BT_LE_MAX_CONNECTIONS */
+#else
+/* default setting */
+#define BLE_MESH_MAX_CONN 1
#endif
+#endif /* CONFIG_BT_BLUEDROID_ENABLED */
#ifdef CONFIG_BT_NIMBLE_ENABLED
+#if CONFIG_IDF_TARGET_ESP32
+#define BLE_MESH_MAX_CONN 1
+#elif (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3)
+/* @todo: must ensure CONFIG_BT_CTRL_BLE_MAX_ACT is greater than 2 */
+#if CONFIG_BT_NIMBLE_MAX_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2)
+/* decrease the adv,scan */
+#define BLE_MESH_MAX_CONN (CONFIG_BT_CTRL_BLE_MAX_ACT - 2)
+#else
+#define BLE_MESH_MAX_CONN CONFIG_BT_NIMBLE_MAX_CONNECTIONS
+#endif /* CONFIG_BT_NIMBLE_MAX_CONNECTIONS > (CONFIG_BT_CTRL_BLE_MAX_ACT - 2) */
+#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5
#define BLE_MESH_MAX_CONN CONFIG_BT_NIMBLE_MAX_CONNECTIONS
+#else
+/* default setting */
+#define BLE_MESH_MAX_CONN 1
#endif
+#endif /* CONFIG_BT_NIMBLE_ENABLED */
#define BLE_MESH_GAP_ADV_MAX_LEN 31
#define BLE_MESH_GATT_DEF_MTU_SIZE 23
+#if CONFIG_BLE_MESH_USE_BLE_50
+#define BLE_MESH_ADV_PHY_UNASSIGNED 0
+#define BLE_MESH_ADV_PHY_1M 1
+#define BLE_MESH_ADV_PHY_2M 2
+#define BLE_MESH_ADV_PHY_CODED 3
+#define BLE_MESH_ADV_PHY_OPTION_NO_PREFER 0
+#define BLE_MESH_ADV_PHY_OPTION_PREFER_S2 1
+#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
+#endif
+
/* BD ADDR types */
#define BLE_MESH_ADDR_PUBLIC 0x00
#define BLE_MESH_ADDR_RANDOM 0x01
@@ -43,11 +103,22 @@ extern "C" {
#define BLE_MESH_ADDR_LEN 0x06
/* Advertising types */
+#if !CONFIG_BLE_MESH_USE_BLE_50
#define BLE_MESH_ADV_IND 0x00
#define BLE_MESH_ADV_DIRECT_IND 0x01
#define BLE_MESH_ADV_SCAN_IND 0x02
#define BLE_MESH_ADV_NONCONN_IND 0x03
#define BLE_MESH_ADV_DIRECT_IND_LOW_DUTY 0x04
+#define BLE_MESH_ADV_SCAN_RSP 0x04
+#else
+/* Bluetooth Core Spec 6.0, Vol 4, Part E, 7.7.65.13 */
+#define BLE_MESH_ADV_IND (0x13)
+#define BLE_MESH_ADV_DIRECT_IND (0x15)
+#define BLE_MESH_ADV_SCAN_IND (0x12)
+#define BLE_MESH_ADV_NONCONN_IND (0x10)
+#define BLE_MESH_ADV_DIRECT_IND_LOW_DUTY (0x1b)
+#define BLE_MESH_ADV_SCAN_RSP (0x1b)
+#endif
/* advertising channel map */
#define BLE_MESH_ADV_CHNL_37 BIT(0)
@@ -400,6 +471,39 @@ struct bt_mesh_adv_param {
/** Maximum Advertising Interval (N * 0.625) */
uint16_t interval_max;
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+ /** Maximum Advertising Duration (N * 0.625) */
+ uint16_t adv_duration;
+
+ /** Advertising Packages Number */
+ uint16_t adv_count;
+
+ /** Advertising Primary PHY */
+ uint8_t primary_phy;
+
+ /** Advertising Secondary PHY */
+ uint8_t secondary_phy;
+#endif
+};
+
+#define ADV_TASK_ADV_INST_EVT(inst_id) BIT(inst_id)
+
+enum bt_mesh_adv_inst_type {
+ BLE_MESH_ADV_INS,
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ BLE_MESH_ADV_PROXY_INS,
+#endif
+#if CONFIG_BLE_MESH_SEPARATE_RELAY_ADV_INSTANCE
+ BLE_MESH_RELAY_ADV_INS,
+#endif
+#if CONFIG_BLE_MESH_SEPARATE_BLE_ADV_INSTANCE
+ BLE_MESH_BLE_ADV_INS,
+#endif
+#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+ BLE_MESH_ADV_INS_TYPES_NUM,
};
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
@@ -441,7 +545,7 @@ struct bt_mesh_scan_param {
/** Scan interval (N * 0.625 ms) */
uint16_t interval;
- /** Scan window (N * 0.625 ms) */
+ /** Uncoded phy Scan window (N * 0.625 ms) */
uint16_t window;
/** BLE scan filter policy */
@@ -453,21 +557,38 @@ struct bt_mesh_conn {
bt_mesh_atomic_t ref;
};
+/* BLE Mesh advertising report */
+struct bt_mesh_adv_report {
+ /* Advertiser LE address and type. */
+ bt_mesh_addr_t addr;
+
+ /* Strength of advertiser signal. */
+ int8_t rssi;
+
+ /* Type of advertising response from advertiser. */
+ uint8_t adv_type;
+
+ /* Buffer containing advertiser data. */
+ struct net_buf_simple adv_data;
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+ /* Primary advertising PHY */
+ uint8_t primary_phy;
+
+ /* Secondary advertising PHY */
+ uint8_t secondary_phy;
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+};
+
/** @typedef bt_mesh_scan_cb_t
* @brief Callback type for reporting LE scan results.
*
* A function of this type is given to the bt_le_scan_start() function
* and will be called for any discovered LE device.
*
- * @param addr Advertiser LE address and type.
- * @param rssi Strength of advertiser signal.
- * @param adv_type Type of advertising response from advertiser.
- * @param data Buffer containing advertiser data.
- * @param scan_rsp_len Scan Response data length.
+ * @param adv_rpt: BLE Mesh advertising report.
*/
-typedef void bt_mesh_scan_cb_t(const bt_mesh_addr_t *addr, int8_t rssi,
- uint8_t adv_type, struct net_buf_simple *buf,
- uint8_t scan_rsp_len);
+typedef void bt_mesh_scan_cb_t(struct bt_mesh_adv_report *adv_rpt);
/* @typedef bt_mesh_dh_key_cb_t
* @brief Callback type for DH Key calculation.
@@ -553,7 +674,7 @@ struct bt_mesh_gatt_attr {
* @param len Length of data to read
* @param offset Offset to start reading from
*
- * @return Number fo bytes read, or in case of an error
+ * @return Number of bytes read, or in case of an error
* BLE_MESH_GATT_ERR() with a specific ATT error code.
*/
ssize_t (*read)(struct bt_mesh_conn *conn,
@@ -684,6 +805,21 @@ struct bt_mesh_gatt_attr {
int bt_mesh_host_init(void);
int bt_mesh_host_deinit(void);
+#if CONFIG_BLE_MESH_USE_BLE_50
+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,
+ const struct bt_mesh_adv_data *sd, size_t sd_len);
+
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
+ const struct bt_mesh_ble_adv_param *param,
+ const struct bt_mesh_ble_adv_data *adv_data);
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
+
+int bt_le_ext_adv_stop(uint8_t inst_id);
+
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_adv_start(const struct bt_mesh_adv_param *param,
const struct bt_mesh_adv_data *ad, size_t ad_len,
const struct bt_mesh_adv_data *sd, size_t sd_len);
@@ -691,9 +827,10 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param,
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
const struct bt_mesh_ble_adv_data *data);
-#endif
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
int bt_le_adv_stop(void);
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t cb);
diff --git a/lib/bt/esp_ble_mesh/core/lpn.c b/lib/bt/esp_ble_mesh/core/lpn.c
index f445be56..80f5b432 100644
--- a/lib/bt/esp_ble_mesh/core/lpn.c
+++ b/lib/bt/esp_ble_mesh/core/lpn.c
@@ -10,6 +10,7 @@
#include <errno.h>
#include "crypto.h"
+#include "tag.h"
#include "adv.h"
#include "scan.h"
#include "mesh.h"
@@ -23,7 +24,9 @@
#include "mesh/cfg_srv.h"
#include "heartbeat.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#ifdef CONFIG_BLE_MESH_LOW_POWER
diff --git a/lib/bt/esp_ble_mesh/core/main.c b/lib/bt/esp_ble_mesh/core/main.c
index ad94e2c8..957234e3 100644
--- a/lib/bt/esp_ble_mesh/core/main.c
+++ b/lib/bt/esp_ble_mesh/core/main.c
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -30,7 +30,9 @@
#include "prov_pvnr.h"
#include "pvnr_mgmt.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
static bool mesh_init = false;
@@ -161,9 +163,9 @@ void bt_mesh_node_reset(void)
bt_mesh_clear_seq();
bt_mesh_clear_dkca();
bt_mesh_clear_role();
- if (IS_ENABLED(CONFIG_BLE_MESH_DF_SRV)) {
- bt_mesh_clear_all_directed_forwarding_table_data();
- }
+#if CONFIG_BLE_MESH_DF_SRV
+ bt_mesh_clear_all_directed_forwarding_table_data();
+#endif
}
memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags));
@@ -405,12 +407,14 @@ int bt_mesh_init(const struct bt_mesh_prov *prov,
return -EALREADY;
}
+#if CONFIG_BLE_MESH_V11_SUPPORT
extern int bt_mesh_v11_ext_init(void);
err = bt_mesh_v11_ext_init();
if (err) {
BT_ERR("Bluetooth Mesh v1.1 init failed");
return err;
}
+#endif
bt_mesh_mutex_init();
@@ -437,7 +441,9 @@ int bt_mesh_init(const struct bt_mesh_prov *prov,
if ((IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) &&
IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) ||
- IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)) {
+ IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT) ||
+ (IS_ENABLED(CONFIG_BLE_MESH_RPR_SRV) &&
+ IS_ENABLED(CONFIG_BLE_MESH_PB_GATT))) {
bt_mesh_proxy_client_init();
}
@@ -587,7 +593,9 @@ int bt_mesh_deinit(struct bt_mesh_deinit_param *param)
if ((IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) &&
IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) ||
- IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)) {
+ IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT) ||
+ (IS_ENABLED(CONFIG_BLE_MESH_RPR_SRV) &&
+ IS_ENABLED(CONFIG_BLE_MESH_PB_GATT))) {
bt_mesh_proxy_client_deinit();
}
diff --git a/lib/bt/esp_ble_mesh/core/mesh.h b/lib/bt/esp_ble_mesh/core/mesh.h
index c9392240..12784479 100644
--- a/lib/bt/esp_ble_mesh/core/mesh.h
+++ b/lib/bt/esp_ble_mesh/core/mesh.h
@@ -11,6 +11,7 @@
#define _MESH_H_
#include "net.h"
+#include "tag.h"
#ifdef __cplusplus
extern "C" {
diff --git a/lib/bt/esp_ble_mesh/core/net.c b/lib/bt/esp_ble_mesh/core/net.c
index 2f988966..4f54c854 100644
--- a/lib/bt/esp_ble_mesh/core/net.c
+++ b/lib/bt/esp_ble_mesh/core/net.c
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2018-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -13,6 +13,7 @@
#include "crypto.h"
#include "adv.h"
+#include "net.h"
#include "scan.h"
#include "mesh.h"
#include "lpn.h"
@@ -31,7 +32,9 @@
#include "proxy_server.h"
#include "pvnr_mgmt.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
/* Minimum valid Mesh Network PDU length. The Network headers
* themselves take up 9 bytes. After that there is a minimum of 1 byte
@@ -834,6 +837,9 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf,
uint16_t dst = 0U;
int err = 0;
+ /* The variable is not used when proxy server or proxy client is disabled. */
+ ARG_UNUSED(dst);
+
BT_DBG("net_idx 0x%04x new_key %u len %u", sub->net_idx, new_key,
buf->len);
@@ -911,18 +917,22 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf,
return err;
}
- if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
- bt_mesh_proxy_server_relay(&buf->b, dst) &&
- BLE_MESH_ADDR_IS_UNICAST(dst)) {
+ /**
+ * TODO: Find a way to determine how the message was sent previously
+ * during a retransmission, to avoid ineffective advertising.
+ */
+#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ if (bt_mesh_proxy_server_relay(&buf->b, dst) &&
+ BLE_MESH_ADDR_IS_UNICAST(dst) &&
+ bt_mesh_proxy_server_find_client_by_addr(dst)) {
send_cb_finalize(cb, cb_data);
return 0;
}
+#endif
- if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT) &&
- bt_mesh_proxy_client_relay(&buf->b, dst)) {
- send_cb_finalize(cb, cb_data);
- return 0;
- }
+#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
+ bt_mesh_proxy_client_relay(&buf->b, dst);
+#endif
bt_mesh_adv_send(buf, BLE_MESH_ADV(buf)->xmit, cb, cb_data);
return 0;
@@ -1019,9 +1029,37 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf,
return bt_mesh_net_obfuscate(buf->data, BLE_MESH_NET_IVI_TX, priv);
}
+#if !CONFIG_BLE_MESH_V11_SUPPORT
+static void bt_mesh_net_adv_xmit_update(struct bt_mesh_net_tx *tx)
+{
+ /* When transmitting a Network PDU that is tagged as friendship,
+ * the Advertising Bearer Network Interface shall transmit the
+ * Network PDU over the advertising bearer only once.
+ *
+ * Note: Currently when transmitting a packet with the friendship
+ * credentials used, the message flow will not reach here. It
+ * will be enqueued into the friend queue in transport.c, and
+ * waited to be sent.
+ */
+ if (bt_mesh_tag_friendship(tx->ctx->send_tag)) {
+ tx->xmit = BLE_MESH_TRANSMIT(0, BLE_MESH_TRANSMIT_INT(bt_mesh_net_transmit_get()));
+ return;
+ }
+
+ if (bt_mesh_tag_relay(tx->ctx->send_tag)) {
+ tx->xmit = bt_mesh_relay_retransmit_get();
+ } else {
+ tx->xmit = bt_mesh_net_transmit_get();
+ }
+
+ return;
+}
+#endif /* !CONFIG_BLE_MESH_V11_SUPPORT */
+
int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
const struct bt_mesh_send_cb *cb, void *cb_data)
{
+ const struct bt_mesh_send_cb *send_cb = cb;
uint8_t bearer = BLE_MESH_ALL_BEARERS;
int err = 0;
@@ -1086,31 +1124,48 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
* shall drop all messages secured using the friendship security
* credentials."
*/
-
- if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
- (bearer & BLE_MESH_GATT_BEARER) &&
- (tx->ctx->send_ttl != 1U ||
- bt_mesh_tag_relay(tx->ctx->send_tag)) &&
+#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ if ((bearer & BLE_MESH_GATT_BEARER) &&
+ (tx->ctx->send_ttl != 1U || bt_mesh_tag_relay(tx->ctx->send_tag)) &&
tx->ctx->send_cred != BLE_MESH_FRIENDSHIP_CRED) {
if (bt_mesh_proxy_server_relay(&buf->b, tx->ctx->addr) &&
BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) {
- /* Notify completion if this only went
- * through the Mesh Proxy.
+ /* When the destination address is identified as a proxy client
+ * address, the message will be sent only to the proxy client.
+ * This action will enhance the efficiency of the proxy server
+ * in sending data packets.
+ *
+ * It should be noted that this approach does not significantly
+ * reduce the number of advertising packets in the air, as other
+ * proxy clients may receive the message and resend it through
+ * a advertising method.
*/
- if ((bearer & (~BLE_MESH_GATT_BEARER)) == 0) {
- send_cb_finalize(cb, cb_data);
+ if (bt_mesh_proxy_server_find_client_by_addr(tx->ctx->addr)) {
+ send_cb_finalize(send_cb, cb_data);
+ send_cb = NULL;
- err = 0;
goto done;
}
+ /* Finalize transmission if this only went through GATT bearer */
+ if ((bearer & (~BLE_MESH_GATT_BEARER)) == 0) {
+ send_cb_finalize(send_cb, cb_data);
+ send_cb = NULL;
+
+#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
+ /* This message will not be transmitted by proxy client */
+ if (!bt_mesh_proxy_client_get_conn_count()) {
+ goto done;
+ }
+#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
+ }
}
}
+#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */
- if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT) &&
- (bearer & BLE_MESH_GATT_BEARER) &&
- (tx->ctx->send_ttl != 1U ||
- bt_mesh_tag_relay(tx->ctx->send_tag)) &&
+#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
+ if ((bearer & BLE_MESH_GATT_BEARER) &&
+ (tx->ctx->send_ttl != 1U || bt_mesh_tag_relay(tx->ctx->send_tag)) &&
tx->ctx->send_cred != BLE_MESH_FRIENDSHIP_CRED) {
if (bt_mesh_proxy_client_relay(&buf->b, tx->ctx->addr)) {
/* If Proxy Client succeeds to send messages with GATT bearer,
@@ -1118,34 +1173,43 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
* connection has been created with Proxy Client, here we will
* use advertising bearer for the messages.
*/
- send_cb_finalize(cb, cb_data);
+ if ((bearer & (~BLE_MESH_GATT_BEARER)) == 0) {
+ send_cb_finalize(send_cb, cb_data);
+ send_cb = NULL;
- err = 0;
- goto done;
+ goto done;
+ }
}
}
+#endif /* CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
/* Deliver to local network interface if necessary */
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->ctx->addr) || bt_mesh_elem_find(tx->ctx->addr))) {
- if (cb && cb->start) {
- cb->start(0, 0, cb_data);
- }
+ /* If the target address isn't a unicast address, then the callback
+ * function will be called by mesh adv task instead of called here
+ * to avoid the callback function being called twice.
+ * See BLEMESH24-76 for more details.
+ */
+ if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) {
+ if (send_cb && send_cb->start) {
+ send_cb->start(0, 0, cb_data);
+ }
- net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf));
+ net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf));
- if (cb && cb->end) {
- cb->end(0, cb_data);
- }
+ if (send_cb && send_cb->end) {
+ send_cb->end(0, cb_data);
+ }
- bt_mesh_net_local();
+ bt_mesh_net_local();
- err = 0;
- /* If it is a group address, it still needs to be relayed */
- if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) {
goto done;
}
+
+ net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf));
+ bt_mesh_net_local();
}
if ((bearer & BLE_MESH_ADV_BEARER) &&
@@ -1167,7 +1231,6 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
BLE_MESH_TRANSMIT_COUNT(tx->xmit), BLE_MESH_TRANSMIT_INT(tx->xmit));
bt_mesh_adv_send(buf, tx->xmit, cb, cb_data);
- err = 0;
goto done;
}
@@ -1407,13 +1470,94 @@ static bool relay_to_adv(enum bt_mesh_net_if net_if)
case BLE_MESH_NET_IF_ADV:
return (bt_mesh_relay_get() == BLE_MESH_RELAY_ENABLED);
case BLE_MESH_NET_IF_PROXY:
- return (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED ||
- bt_mesh_private_gatt_proxy_state_get() == BLE_MESH_PRIVATE_GATT_PROXY_ENABLED);
+ return (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED
+#if CONFIG_BLE_MESH_PRB_SRV
+ || bt_mesh_private_gatt_proxy_state_get() == BLE_MESH_PRIVATE_GATT_PROXY_ENABLED
+#endif
+ );
default:
return false;
}
}
+#if !CONFIG_BLE_MESH_V11_SUPPORT
+static uint8_t net_retransmission_adv(struct bt_mesh_net_rx *rx,
+ uint8_t *cred, uint8_t *tag)
+{
+ if (rx->ctx.recv_cred == BLE_MESH_FLOODING_CRED) {
+ uint8_t bearer = BLE_MESH_NONE_BEARER;
+
+ /* Inbound bearer: ADV;
+ * Inbound Security Material: managed flooding;
+ */
+
+ /* Condition: Relay is enabled. */
+ if (IS_ENABLED(CONFIG_BLE_MESH_RELAY) &&
+ bt_mesh_relay_get() == BLE_MESH_RELAY_ENABLED) {
+ bearer |= BLE_MESH_ADV_BEARER;
+ *cred = BLE_MESH_FLOODING_CRED;
+ /* Additional action: Tag as relay */
+ *tag |= BLE_MESH_TAG_RELAY;
+ }
+
+ /* Condition: Proxy is enabled. */
+ if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
+ bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) {
+ bearer |= BLE_MESH_GATT_BEARER;
+ *cred = BLE_MESH_FLOODING_CRED;
+ }
+
+ return bearer;
+ }
+
+ if (rx->ctx.recv_cred == BLE_MESH_FRIENDSHIP_CRED &&
+ IS_ENABLED(CONFIG_BLE_MESH_FRIEND) &&
+ bt_mesh_friend_get() == BLE_MESH_FRIEND_ENABLED) {
+
+ /* Condition: Directed friend is disabled. */
+ *cred = BLE_MESH_FLOODING_CRED;
+ return BLE_MESH_ALL_BEARERS;
+ }
+
+ return BLE_MESH_NONE_BEARER;
+}
+
+static uint8_t net_retransmission_gatt(struct bt_mesh_net_rx *rx,
+ uint8_t *cred, uint8_t *tag)
+{
+ if (rx->ctx.recv_cred == BLE_MESH_FLOODING_CRED) {
+ /* Inbound bearer: GATT;
+ * Inbound Security Material: managed flooding;
+ * Condition: Proxy is enabled;
+ */
+ if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
+ bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) {
+ /* Condition: Directed proxy is disabled. */
+ *cred = BLE_MESH_FLOODING_CRED;
+ return BLE_MESH_ALL_BEARERS;
+ }
+
+ return BLE_MESH_NONE_BEARER;
+ }
+
+ return BLE_MESH_NONE_BEARER;
+}
+
+static uint8_t bt_mesh_net_retrans_match(struct bt_mesh_net_rx *rx,
+ uint8_t *cred, uint8_t *tag)
+{
+ if (rx->net_if == BLE_MESH_NET_IF_ADV) {
+ return net_retransmission_adv(rx, cred, tag);
+ }
+
+ if (rx->net_if == BLE_MESH_NET_IF_PROXY) {
+ return net_retransmission_gatt(rx, cred, tag);
+ }
+
+ return BLE_MESH_NONE_BEARER;
+}
+#endif /* !CONFIG_BLE_MESH_V11_SUPPORT */
+
static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
struct bt_mesh_net_rx *rx)
{
@@ -1538,7 +1682,7 @@ 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_DATA, K_NO_WAIT);
+ buf = bt_mesh_relay_adv_create(BLE_MESH_ADV_RELAY_DATA, K_NO_WAIT);
#endif
if (!buf) {
@@ -1606,20 +1750,25 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf,
* shall drop all messages secured using the friendship security
* credentials.
*/
- if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
- (bearer & BLE_MESH_GATT_BEARER) &&
+#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
+ if ((bearer & BLE_MESH_GATT_BEARER) &&
((bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED &&
cred != BLE_MESH_FRIENDSHIP_CRED) ||
+#if CONFIG_BLE_MESH_PRB_SRV
bt_mesh_private_gatt_proxy_state_get() == BLE_MESH_PRIVATE_GATT_PROXY_ENABLED ||
+#endif
rx->net_if == BLE_MESH_NET_IF_LOCAL ||
rx->ctx.recv_cred == BLE_MESH_FRIENDSHIP_CRED)) {
if (bt_mesh_proxy_server_relay(&buf->b, rx->ctx.recv_dst) &&
BLE_MESH_ADDR_IS_UNICAST(rx->ctx.recv_dst)) {
- if ((bearer & (~BLE_MESH_GATT_BEARER)) == 0) {
+
+ if (((bearer & (~BLE_MESH_GATT_BEARER)) == 0) ||
+ bt_mesh_proxy_server_find_client_by_addr(rx->ctx.recv_dst)) {
goto done;
}
}
}
+#endif /* CONFIG_BLE_MESH_GATT_PROXY_SERVER */
if (((bearer & BLE_MESH_ADV_BEARER) && relay_to_adv(rx->net_if)) ||
netkey_changed ||
@@ -1769,24 +1918,26 @@ static bool ignore_net_msg(uint16_t src, uint16_t dst)
return false;
}
-void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
- enum bt_mesh_net_if net_if)
+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 bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi };
struct net_buf_simple_state state = {0};
- BT_DBG("rssi %d net_if %u", rssi, net_if);
+ assert(rx);
+
+ BT_DBG("rssi %d net_if %u", rx->ctx.recv_rssi, net_if);
if (!ready_to_recv()) {
return;
}
- if (bt_mesh_net_decode(data, net_if, &rx, &buf)) {
+ if (bt_mesh_net_decode(data, net_if, rx, &buf)) {
return;
}
- if (ignore_net_msg(rx.ctx.addr, rx.ctx.recv_dst)) {
+ if (ignore_net_msg(rx->ctx.addr, rx->ctx.recv_dst)) {
return;
}
@@ -1796,24 +1947,26 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
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,
+ 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));
/* 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
* corresponding subnet.
*/
- rx.local_match = (bt_mesh_fixed_group_match(rx.ctx.recv_dst) ||
- bt_mesh_fixed_direct_match(rx.sub, rx.ctx.recv_dst) ||
- bt_mesh_elem_find(rx.ctx.recv_dst));
+ rx->local_match = (bt_mesh_fixed_group_match(rx->ctx.recv_dst) ||
+ bt_mesh_fixed_direct_match(rx->sub, rx->ctx.recv_dst) ||
+ bt_mesh_elem_find(rx->ctx.recv_dst));
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 &&
+#endif
net_if == BLE_MESH_NET_IF_PROXY) {
- bt_mesh_proxy_server_addr_add(data, rx.ctx.addr);
+ bt_mesh_proxy_server_addr_add(data, rx->ctx.addr);
if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_DISABLED &&
- !rx.local_match) {
+ !rx->local_match) {
BT_INFO("Proxy is disabled; ignoring message");
return;
}
@@ -1826,11 +1979,11 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
* tag the Network PDU with the immutable-credentials tag.
*/
#if CONFIG_BLE_MESH_DF_SRV
- if (rx.sub->directed_proxy == BLE_MESH_DIRECTED_PROXY_ENABLED &&
- rx.sub->use_directed == BLE_MESH_PROXY_USE_DIRECTED_ENABLED &&
- !bt_mesh_addr_in_uar(&rx.sub->proxy_client_uar, rx.ctx.addr) &&
- !bt_mesh_proxy_server_find_client_by_addr(rx.ctx.addr)) {
- rx.ctx.recv_tag |= BLE_MESH_TAG_IMMUTABLE_CRED;
+ if (rx->sub->directed_proxy == BLE_MESH_DIRECTED_PROXY_ENABLED &&
+ rx->sub->use_directed == BLE_MESH_PROXY_USE_DIRECTED_ENABLED &&
+ !bt_mesh_addr_in_uar(&rx->sub->proxy_client_uar, rx->ctx.addr) &&
+ !bt_mesh_proxy_server_find_client_by_addr(rx->ctx.addr)) {
+ rx->ctx.recv_tag |= BLE_MESH_TAG_IMMUTABLE_CRED;
}
#endif /* CONFIG_BLE_MESH_DF_SRV */
}
@@ -1842,24 +1995,24 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
* 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;
+ msg_cache[rx->msg_cache_idx].src = BLE_MESH_ADDR_UNASSIGNED;
/* Rewind the next index now that we're not using this entry */
- msg_cache_next = rx.msg_cache_idx;
+ msg_cache_next = rx->msg_cache_idx;
}
/* Relay if this was a group/virtual address, or if the destination
* was neither a local element nor an LPN we're Friends for.
*/
- if (!BLE_MESH_ADDR_IS_UNICAST(rx.ctx.recv_dst) ||
- (!rx.local_match && !rx.friend_match
+ if (!BLE_MESH_ADDR_IS_UNICAST(rx->ctx.recv_dst) ||
+ (!rx->local_match && !rx->friend_match
#if CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG
- && !rx.replay_msg
+ && !rx->replay_msg
#endif
)) {
net_buf_simple_restore(&buf, &state);
- bt_mesh_net_relay(&buf, &rx);
+ bt_mesh_net_relay(&buf, rx);
}
}
diff --git a/lib/bt/esp_ble_mesh/core/net.h b/lib/bt/esp_ble_mesh/core/net.h
index 7da8c4a0..94e07819 100644
--- a/lib/bt/esp_ble_mesh/core/net.h
+++ b/lib/bt/esp_ble_mesh/core/net.h
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -465,8 +465,16 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf,
int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if,
struct bt_mesh_net_rx *rx, struct net_buf_simple *buf);
-void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
- enum bt_mesh_net_if net_if);
+void bt_mesh_generic_net_recv(struct net_buf_simple *data,
+ struct bt_mesh_net_rx *rx,
+ enum bt_mesh_net_if net_if);
+
+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 };
+ bt_mesh_generic_net_recv(data, &rx, net_if);
+}
bool bt_mesh_primary_subnet_exist(void);
diff --git a/lib/bt/esp_ble_mesh/core/nimble_host/adapter.c b/lib/bt/esp_ble_mesh/core/nimble_host/adapter.c
index 0418b76c..b2477345 100644
--- a/lib/bt/esp_ble_mesh/core/nimble_host/adapter.c
+++ b/lib/bt/esp_ble_mesh/core/nimble_host/adapter.c
@@ -1,7 +1,7 @@
/*
* SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA
* SPDX-FileCopyrightText: 2015-2016 Intel Corporation
- * SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -27,6 +27,8 @@
#include "mesh/hci.h"
#include "mesh/common.h"
#include "prov_pvnr.h"
+#include "scan.h"
+#include "btc_ble_mesh_ble.h"
/** @def BT_UUID_MESH_PROV
* @brief Mesh Provisioning Service
@@ -69,7 +71,6 @@ static uint8_t bt_mesh_private_key[32];
/* Scan related functions */
static bt_mesh_scan_cb_t *bt_mesh_scan_dev_found_cb;
-
#if CONFIG_BLE_MESH_NODE
/* the gatt database list to save the attribute table */
static sys_slist_t bt_mesh_gatts_db;
@@ -79,10 +80,59 @@ static struct bt_mesh_conn bt_mesh_gatts_conn[BLE_MESH_MAX_CONN];
static struct bt_mesh_conn_cb *bt_mesh_gatts_conn_cb;
static uint8_t bt_mesh_gatts_addr[6];
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+static bool g_gatts_svcs_add = false;
+#endif
#endif /* CONFIG_BLE_MESH_NODE */
+#if CONFIG_BLE_MESH_USE_BLE_50 && \
+ CONFIG_BLE_MESH_SUPPORT_BLE_ADV && \
+ (!CONFIG_BLE_MESH_SUPPORT_MULTI_ADV)
+static inline void bt_mesh_set_ble_adv_running();
+
+static inline void bt_mesh_unset_ble_adv_running();
+
+static inline bool bt_mesh_is_ble_adv_running();
+#endif
+
static bool g_host_init = false;
+#if CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_USE_BLE_50
+
+#define BT_MESH_GATTS_CONN_UNUSED 0xFF
+
+static void bt_mesh_gatts_conn_init(void)
+{
+ int i;
+ for (i = 0; i < BLE_MESH_MAX_CONN; i++) {
+ bt_mesh_gatts_conn[i].handle = BT_MESH_GATTS_CONN_UNUSED;
+ }
+}
+
+static int bt_mesh_find_free_conn_idx(void)
+{
+ int i;
+ for (i = 0; i < BLE_MESH_MAX_CONN; i++) {
+ if (bt_mesh_gatts_conn[i].handle == BT_MESH_GATTS_CONN_UNUSED) {
+ return i;
+ }
+ }
+ return -ENOMEM;
+}
+
+static int bt_mesh_find_conn_idx(uint16_t conn_handle)
+{
+ int i;
+ for (i = 0; i < BLE_MESH_MAX_CONN; i++) {
+ if (bt_mesh_gatts_conn[i].handle == conn_handle) {
+ return i;
+ }
+ }
+ return -ENODEV;
+}
+#endif /* CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_USE_BLE_50 */
+
int bt_mesh_host_init(void)
{
int rc;
@@ -145,9 +195,16 @@ void bt_mesh_hci_init(void)
#endif
}
+#if CONFIG_BLE_MESH_USE_BLE_50
+static struct ble_gap_ext_disc_params uncoded_disc_params;
+static struct ble_gap_ext_disc_params coded_disc_params;
+#else
static struct ble_gap_disc_params scan_param;
+#endif
+
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
- CONFIG_BLE_MESH_GATT_PROXY_CLIENT
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
static struct gattc_prov_info {
/* Service to be found depends on the type of adv pkt received */
struct bt_mesh_conn conn;
@@ -350,13 +407,19 @@ static int svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
}
uuid = &service->uuid;
- uuid_length = (uint8_t) (uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16);
+ uuid_length = (uint8_t)(uuid->u.type == BLE_UUID_TYPE_16 ? 2 : 16);
if (uuid_length != 2) {
return 0;
}
for (i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
- if (bt_mesh_gattc_info[i].service_uuid == (uint16_t)BLE_UUID16(uuid)->value) {
+ /**
+ * In scenarios with multiple connections, to prevent
+ * subsequent connections from affecting the first one,
+ * a check for the connection handle is needed here.
+ */
+ if (bt_mesh_gattc_info[i].conn.handle == conn_handle &&
+ bt_mesh_gattc_info[i].service_uuid == (uint16_t)BLE_UUID16(uuid)->value) {
bt_mesh_gattc_info[i].start_handle = service->start_handle;
bt_mesh_gattc_info[i].end_handle = service->end_handle;
break;
@@ -396,13 +459,52 @@ static int svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
return rc;
}
-#endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
+#endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT ||
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) */
-static int disc_cb(struct ble_gap_event *event, void *arg)
+#if CONFIG_BLE_MESH_USE_BLE_50
+void bt_mesh_ble_ext_adv_report(struct ble_gap_ext_disc_desc *desc)
{
+#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
+ bt_mesh_ble_adv_report_t adv_rpt = {0};
+ if (bt_mesh_ble_scan_state_get()) {
+ memcpy(adv_rpt.addr, desc->addr.val, BLE_MESH_ADDR_LEN);
+ memcpy(adv_rpt.dir_addr, desc->direct_addr.val, BLE_MESH_ADDR_LEN);
+
+ /* Here, only a shallow copy needs to be implemented;
+ * deep copying behavior occurs in btc_ble_mesh_ble_copy_req_data. */
+ adv_rpt.data = desc->data;
+
+ adv_rpt.event_type = desc->props;
+ adv_rpt.addr_type = desc->addr.type;
+ adv_rpt.length = desc->length_data;
+ adv_rpt.rssi = desc->rssi;
+ adv_rpt.primary_phy = desc->prim_phy;
+ adv_rpt.secondary_phy = desc->sec_phy;
+ adv_rpt.sid = desc->sid;
+ adv_rpt.tx_power = desc->tx_power;
+ adv_rpt.dir_addr_type = desc->direct_addr.type;
+ adv_rpt.data_status = desc->data_status;
+ adv_rpt.per_adv_interval = desc->periodic_adv_itvl;
+
+ bt_mesh_ble_scan_cb_evt_to_btc(&adv_rpt);
+ }
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
+}
+#endif
+
+int disc_cb(struct ble_gap_event *event, void *arg)
+{
+#if CONFIG_BLE_MESH_USE_BLE_50
+ struct ble_gap_ext_disc_desc *desc;
+#else
struct ble_gap_disc_desc *desc;
+#endif
+
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
- CONFIG_BLE_MESH_GATT_PROXY_CLIENT
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
int rc, i;
uint8_t notif_data[100];
uint16_t notif_len;
@@ -412,21 +514,59 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
#endif
switch (event->type) {
+#if CONFIG_BLE_MESH_USE_BLE_50
+ case BLE_GAP_EVENT_EXT_DISC: {
+ struct bt_mesh_adv_report adv_rpt = {0};
+
+ desc = &event->ext_disc;
+
+ 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;
+
+ net_buf_simple_init_with_data(&adv_rpt.adv_data, (void *)desc->data, desc->length_data);
+
+ if (bt_mesh_scan_dev_found_cb) {
+ /* TODO: Support Scan Response data length for NimBLE host */
+ if (desc->props & BLE_HCI_ADV_LEGACY_MASK) {
+ 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);
+ }
+
+ break;
+ }
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
case BLE_GAP_EVENT_DISC: {
- struct net_buf_simple buf = {0};
+ struct bt_mesh_adv_report adv_rpt = {0};
desc = &event->disc;
- net_buf_simple_init_with_data(&buf, (void *)desc->data, desc->length_data);
+
+ adv_rpt.rssi = desc->rssi;
+ adv_rpt.adv_type = desc->event_type;
+
+ memcpy(&adv_rpt.addr, &desc->addr, sizeof(bt_mesh_addr_t));
+
+ net_buf_simple_init_with_data(&adv_rpt.adv_data, (void *)desc->data, desc->length_data);
if (bt_mesh_scan_dev_found_cb) {
/* TODO: Support Scan Response data length for NimBLE host */
- bt_mesh_scan_dev_found_cb((bt_mesh_addr_t *)&desc->addr, desc->rssi, desc->event_type, &buf, 0);
+ bt_mesh_scan_dev_found_cb(&adv_rpt);
}
break;
}
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
- CONFIG_BLE_MESH_GATT_PROXY_CLIENT
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
case BLE_GAP_EVENT_CONNECT:
+ /* @todo: process connect failed event */
if (event->connect.status == 0) {
/* Connection successfully established. */
MODLOG_DFLT(INFO, "Connection established ");
@@ -442,10 +582,21 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
break;
}
}
+ if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
+ goto transfer_to_user;
+ }
+ } else {
+ goto transfer_to_user;
}
}
if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_SCANNING)) {
+#if CONFIG_BLE_MESH_USE_BLE_50
+ rc = ble_gap_ext_disc(BLE_OWN_ADDR_PUBLIC, 0, 0, 0, 0, 0,
+ uncoded_disc_params.itvl ? &uncoded_disc_params : NULL,
+ coded_disc_params.itvl ? &coded_disc_params : NULL, disc_cb, NULL);
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &scan_param, disc_cb, NULL);
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
if (rc != 0) {
BT_ERR("Invalid scan status %d", rc);
break;
@@ -494,7 +645,13 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
bt_mesh_gattc_info[i].wr_desc_done = false;
break;
}
+
+ if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
+ goto transfer_to_user;
+ }
}
+ } else {
+ goto transfer_to_user;
}
break;
case BLE_GAP_EVENT_MTU:
@@ -521,6 +678,8 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
}
/* Search Mesh Provisioning Service or Mesh Proxy Service */
ble_gattc_disc_all_svcs(bt_mesh_gattc_info[i].conn.handle, svc_disced, NULL);
+ } else {
+ goto transfer_to_user;
}
break;
case BLE_GAP_EVENT_NOTIFY_RX:
@@ -531,8 +690,8 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
}
if (i == ARRAY_SIZE(bt_mesh_gattc_info)) {
- BT_ERR("Conn handle 0x%04x not found", event->notify_rx.conn_handle);
- return 0;
+ BT_DBG("Conn handle 0x%04x not blonges to Mesh", event->notify_rx.conn_handle);
+ goto transfer_to_user;
}
conn = &bt_mesh_gattc_info[i].conn;
@@ -557,7 +716,7 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
if (bt_mesh_gattc_info[i].service_uuid == BLE_MESH_UUID_MESH_PROV_VAL) {
if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->prov_notify != NULL) {
len = bt_mesh_gattc_conn_cb->prov_notify(&bt_mesh_gattc_info[i].conn,
- notif_data, notif_len);
+ notif_data, notif_len);
if (len < 0) {
BT_ERR("prov_notify failed");
bt_mesh_gattc_disconnect(conn);
@@ -568,7 +727,7 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
if (bt_mesh_gattc_conn_cb != NULL && bt_mesh_gattc_conn_cb->proxy_notify != NULL &&
bt_mesh_gattc_info[i].wr_desc_done) {
len = bt_mesh_gattc_conn_cb->proxy_notify(&bt_mesh_gattc_info[i].conn,
- notif_data, notif_len);
+ notif_data, notif_len);
if (len < 0) {
BT_ERR("proxy_notify failed");
bt_mesh_gattc_disconnect(conn);
@@ -579,14 +738,53 @@ static int disc_cb(struct ble_gap_event *event, void *arg)
break;
#endif
default:
+ goto transfer_to_user;
break;
}
return 0;
+
+transfer_to_user:
+#if CONFIG_BLE_MESH_USE_BLE_50
+ bt_mesh_ble_nimble_evt_to_btc(event, arg);
+#endif
+ return 0;
}
+#if CONFIG_BLE_MESH_USE_BLE_50
+/**
+ * @brief Get the gap callback function used by BLE Mesh
+ *
+ * @note The user must get the mesh gap event handler function
+ * through the bt_mesh_nimble_gap_cb_get function and pass
+ * it in as a callback function when using the api:
+ * ble_gap_ext_connect, ble_gap_ext_disc, ble_gap_connect,
+ * and ble_gap_disc.
+ *
+ * @return void*
+ */
+void *bt_mesh_nimble_gap_cb_get(void)
+{
+ return (void*)disc_cb;
+}
+#endif
+
static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window, uint8_t filter_dup)
{
+#if CONFIG_BLE_MESH_USE_BLE_50
+ uncoded_disc_params.itvl = (window ? interval : 0);
+ uncoded_disc_params.window = window;
+
+ coded_disc_params.itvl = ((interval > window) ? interval : 0);
+ coded_disc_params.window = ((interval > window) ? interval - window : 0);
+
+ coded_disc_params.passive = (scan_type == BLE_MESH_SCAN_PASSIVE);
+ uncoded_disc_params.passive = (scan_type == BLE_MESH_SCAN_PASSIVE);
+
+ ble_gap_ext_disc(BLE_OWN_ADDR_PUBLIC, 0, 0, filter_dup, 0, 0,
+ uncoded_disc_params.itvl ? &uncoded_disc_params : NULL,
+ coded_disc_params.itvl ? &coded_disc_params : NULL, disc_cb, NULL);
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
scan_param.filter_duplicates = filter_dup;
scan_param.itvl = interval;
scan_param.window = window;
@@ -597,6 +795,7 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window,
scan_param.passive = 0;
}
ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &scan_param, disc_cb, NULL);
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if BLE_MESH_DEV
if (scan_type == BLE_MESH_SCAN_ACTIVE) {
@@ -648,12 +847,38 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
/* When connection is created, advertising will be stopped automatically. */
bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
#endif
+
+#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
+ /* Check if this connection is created by Proxy client */
+ for (size_t i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
+ if (!memcmp(bt_mesh_gattc_info[i].addr.val, desc.peer_id_addr.val, BLE_MESH_ADDR_LEN)) {
+ BT_WARN("Already create connection with %s by proxy client",
+ bt_hex(desc.peer_id_addr.val, BLE_MESH_ADDR_LEN));
+ return 0;
+ }
+ }
+#endif
+
if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->connected != NULL) {
- uint8_t index = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
+ int index = 0;
+#if CONFIG_BLE_MESH_USE_BLE_50
+ index = bt_mesh_find_free_conn_idx();
+ if (index != -ENOMEM) {
+ bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
+ (bt_mesh_gatts_conn_cb->connected)(&bt_mesh_gatts_conn[index], 0);
+ } else {
+ BT_ERR("No space for new connection");
+ ble_gap_terminate(event->connect.conn_handle, BLE_ERR_CONN_LIMIT);
+ }
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
+ index = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
if (index < BLE_MESH_MAX_CONN) {
bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->connect.conn_handle);
(bt_mesh_gatts_conn_cb->connected)(&bt_mesh_gatts_conn[index], 0);
}
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
memcpy(bt_mesh_gatts_addr, desc.peer_id_addr.val, BLE_MESH_ADDR_LEN);
/* This is for EspBleMesh Android app. When it tries to connect with the
* device at the first time and it fails due to some reason. And after
@@ -673,11 +898,23 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
bt_mesh_atomic_test_and_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
#endif
if (bt_mesh_gatts_conn_cb != NULL && bt_mesh_gatts_conn_cb->disconnected != NULL) {
- uint8_t index = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
+ int index = 0;
+#if CONFIG_BLE_MESH_USE_BLE_50
+ index = bt_mesh_find_conn_idx(BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle));
+ if (index != -ENODEV) {
+ bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
+ (bt_mesh_gatts_conn_cb->disconnected)(&bt_mesh_gatts_conn[index], event->disconnect.reason);
+ } else {
+ BT_ERR("No device");
+ }
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
+ index = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
if (index < BLE_MESH_MAX_CONN) {
bt_mesh_gatts_conn[index].handle = BLE_MESH_GATT_GET_CONN_ID(event->disconnect.conn.conn_handle);
(bt_mesh_gatts_conn_cb->disconnected)(&bt_mesh_gatts_conn[index], event->disconnect.reason);
}
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+ bt_mesh_gatts_conn[index].handle = 0;
memset(bt_mesh_gatts_addr, 0x0, BLE_MESH_ADDR_LEN);
}
@@ -693,8 +930,43 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
return 0;
case BLE_GAP_EVENT_ADV_COMPLETE:
- MODLOG_DFLT(INFO, "advertise complete; reason=%d",
- event->adv_complete.reason);
+ BT_DBG("advertise complete; reason=%d",
+ event->adv_complete.reason);
+#if CONFIG_BLE_MESH_USE_BLE_50
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
+#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+ assert(CONFIG_BLE_MESH_ADV_INST_ID == event->adv_complete.instance);
+ /* Limit Reached (0x43) and Advertising Timeout (0x3C) will cause BLE_HS_ETIMEOUT to be set. */
+ if (event->adv_complete.reason == BLE_HS_ETIMEOUT) {
+ ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
+ }
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+ /**
+ * This judgment is to distinguish between the termination
+ * events of BLE connectable broadcasting and proxy connectable
+ * adv under the same instance ID, that is, when the status is 0.
+ *
+ * Since the host task and adv task are currently operated in
+ * series, there is no need to consider competition issues between
+ * tasks.
+ *
+ * @attention: once multiple adv instances are used, the adv task
+ * and host will be asynchronous, and it is necessary to consider
+ * the issue of resource competition.
+ */
+ if (bt_mesh_is_ble_adv_running() &&
+ event->adv_complete.reason == 0) {
+ /* The unset operation must be performed before waking up the
+ * adv task; performing the unset after waking up the adv task
+ * could lead to resource contention issues.
+ */
+ bt_mesh_unset_ble_adv_running();
+ ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
+ }
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
+#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
return 0;
case BLE_GAP_EVENT_ENC_CHANGE:
@@ -717,10 +989,20 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
event->subscribe.prev_indicate,
event->subscribe.cur_indicate);
struct bt_mesh_gatt_attr *attr = bt_mesh_gatts_find_attr_by_handle(event->subscribe.attr_handle + 1);
- uint8_t index = BLE_MESH_GATT_GET_CONN_ID(event->subscribe.conn_handle);
+ int index = 0;
uint16_t len = 0;
uint16_t ccc_val = 0;
+#if CONFIG_BLE_MESH_USE_BLE_50
+ index = bt_mesh_find_conn_idx(BLE_MESH_GATT_GET_CONN_ID(event->subscribe.conn_handle));
+ if (index == -ENODEV) {
+ BT_ERR("Couldn't find conn %d", event->subscribe.conn_handle);
+ return 0;
+ }
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
+ index = BLE_MESH_GATT_GET_CONN_ID(event->subscribe.conn_handle);
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+
if (event->subscribe.prev_notify != event->subscribe.cur_notify) {
ccc_val = event->subscribe.cur_notify;
} else if (event->subscribe.prev_indicate != event->subscribe.cur_indicate) {
@@ -773,10 +1055,233 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
#else
static int gap_event_cb(struct ble_gap_event *event, void *arg)
{
+#if CONFIG_BLE_MESH_USE_BLE_50
+ switch (event->type) {
+ case BLE_GAP_EVENT_ADV_COMPLETE:
+ BT_DBG("Provisioner advertise complete; reason=%d",
+ event->adv_complete.reason);
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(event->adv_complete.instance));
+#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+ assert(CONFIG_BLE_MESH_ADV_INST_ID == event->adv_complete.instance);
+ /* Limit Reached (0x43) and Advertising Timeout (0x3C) will cause BLE_HS_ETIMEOUT to be set. */
+ if (event->adv_complete.reason == BLE_HS_ETIMEOUT) {
+ ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(CONFIG_BLE_MESH_ADV_INST_ID));
+ }
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+ /**
+ * This judgment is to distinguish between the termination
+ * events of BLE connectable broadcasting and proxy connectable
+ * adv under the same instance ID, that is, when the status is 0.
+ *
+ * Since the host task and adv task are currently operated in
+ * series, there is no need to consider competition issues between
+ * tasks.
+ *
+ * @attention: once multiple adv instances are used, the adv task
+ * and host will be asynchronous, and it is necessary to consider
+ * the issue of resource competition.
+ */
+ if (bt_mesh_is_ble_adv_running() &&
+ event->adv_complete.reason == 0) {
+ /* The unset operation must be performed before waking up the
+ * adv task; performing the unset after waking up the adv task
+ * could lead to resource contention issues.
+ */
+ bt_mesh_unset_ble_adv_running();
+ ble_mesh_adv_task_wakeup(ADV_TASK_ADV_INST_EVT(CONFIG_BLE_MESH_ADV_INST_ID));
+ }
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
+#endif /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+ break;
+ }
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
return 0;
}
#endif /* CONFIG_BLE_MESH_NODE */
+#if CONFIG_BLE_MESH_USE_BLE_50
+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,
+ const struct bt_mesh_adv_data *sd, size_t sd_len)
+{
+ struct ble_gap_ext_adv_params adv_params = {0};
+ struct os_mbuf *data = NULL;
+ struct os_mbuf *scan_rsp = NULL;
+ uint8_t *buf = NULL;
+ uint16_t interval = 0;
+ uint8_t buf_len = 0;
+ int err = 0;
+
+ err = ble_gap_ext_adv_active(inst_id);
+ if (err) {
+ BT_ERR("adv inst(%d) is running %d", inst_id, err);
+ return -EINVAL;
+ }
+
+#if BLE_MESH_DEV
+ if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
+ return -EALREADY;
+ }
+#endif
+ buf = bt_mesh_calloc(ad_len * BLE_HS_ADV_MAX_SZ);
+ if (!buf) {
+ BT_ERR("ad buffer alloc failed");
+ return -ENOMEM;
+ }
+
+ err = set_ad(ad, ad_len, buf, &buf_len);
+ if (err) {
+ bt_mesh_free(buf);
+ BT_ERR("set_ad failed: err %d", err);
+ return err;
+ }
+
+ data = os_msys_get_pkthdr(buf_len, 0);
+ if (!data) {
+ bt_mesh_free(buf);
+ BT_ERR("os buf get failed");
+ return -ENOBUFS;
+ }
+
+ err = os_mbuf_append(data, buf, buf_len);
+ if (err) {
+ bt_mesh_free(buf);
+ BT_ERR("Append ad data to os buf failed %d", err);
+ return -EINVAL;
+ }
+
+ bt_mesh_free(buf);
+
+ if (sd && (param->options & BLE_MESH_ADV_OPT_CONNECTABLE)) {
+ buf_len = 0;
+
+ buf = bt_mesh_calloc(sd_len * BLE_HS_ADV_MAX_SZ);
+ if (!buf) {
+ BT_ERR("ad buffer alloc failed");
+ return -ENOMEM;
+ }
+
+ err = set_ad(sd, sd_len, buf, &buf_len);
+ if (err) {
+ bt_mesh_free(buf);
+ BT_ERR("set_ad failed: err %d", err);
+ return err;
+ }
+
+ scan_rsp = os_msys_get_pkthdr(buf_len, 0);
+ if (!data) {
+ bt_mesh_free(buf);
+ BT_ERR("os buf get failed");
+ return -ENOBUFS;
+ }
+
+ err = os_mbuf_append(scan_rsp, buf, buf_len);
+ if (err) {
+ bt_mesh_free(buf);
+ BT_ERR("Append ad data to os buf failed %d", err);
+ return -EINVAL;
+ }
+
+ bt_mesh_free(buf);
+ }
+
+ memset(&adv_params, 0, sizeof adv_params);
+
+ assert(param);
+
+ if (param->options & BLE_MESH_ADV_OPT_CONNECTABLE) {
+ adv_params.connectable = true;
+ adv_params.scannable = true;
+ adv_params.legacy_pdu = true;
+ } else if (sd != NULL) {
+ adv_params.connectable = false;
+ adv_params.scannable = true;
+ 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;
+ }
+ }
+
+ 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.own_addr_type = BLE_OWN_ADDR_PUBLIC;
+
+ interval = param->interval_min;
+
+#if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL
+ /* If non-connectable mesh packets are transmitted with an adv interval
+ * not smaller than 10ms, then we will use a random adv interval between
+ * [interval / 2, interval] for them.
+ */
+ if (adv_params.legacy_pdu && interval >= 16) {
+ interval >>= 1;
+ interval += (bt_mesh_get_rand() % (interval + 1));
+
+ BT_DBG("%u->%u", param->interval_min, interval);
+ }
+#endif
+
+ 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;
+ }
+
+ err = ble_gap_ext_adv_set_data(inst_id, data);
+ if (err != 0) {
+ BT_ERR("Advertising set failed: err %d", err);
+ return err;
+ }
+
+ if (scan_rsp) {
+ err = ble_gap_ext_adv_rsp_set_data(inst_id, scan_rsp);
+ if (err != 0) {
+ BT_ERR("scan rsp set failed: err %d", err);
+ return err;
+ } else {
+ BT_INFO("scan rsp set succeed\n");
+ }
+ }
+
+again:
+
+ if (param->adv_duration < 10 &&
+ param->adv_duration != 0) {
+ BT_WARN("adv duration shall not be less than 10ms");
+ }
+
+ err = ble_gap_ext_adv_start(inst_id, param->adv_duration ?
+ 2 + param->adv_duration / 10 : 0, param->adv_count);
+ if (err) {
+ if (err == BLE_HS_EALREADY) {
+ ble_gap_ext_adv_stop(inst_id);
+ goto again;
+ }
+
+ BT_ERR("Advertising start failed: err %d", err);
+ return err;
+ }
+
+#if BLE_MESH_DEV
+ bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
+
+ if (!(param->options & BLE_MESH_ADV_OPT_ONE_TIME)) {
+ bt_mesh_atomic_set_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
+ }
+#endif
+
+ return 0;
+}
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
/* APIs functions */
int bt_le_adv_start(const struct bt_mesh_adv_param *param,
const struct bt_mesh_adv_data *ad, size_t ad_len,
@@ -877,8 +1382,156 @@ again:
return 0;
}
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+#if CONFIG_BLE_MESH_USE_BLE_50
+#if !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+/**
+ * The current flag is only used to distinguish between BLE ADV
+ * and proxy ADV in the same adv instance to handle the adv
+ * completed events.
+ *
+ * This flag is not needed in the case of multiple adv instances.
+ */
+static bool _ble_adv_running_flag;
+
+static inline void bt_mesh_set_ble_adv_running()
+{
+ _ble_adv_running_flag = true;
+}
+
+static inline void bt_mesh_unset_ble_adv_running()
+{
+ _ble_adv_running_flag = false;
+}
+
+static inline bool bt_mesh_is_ble_adv_running()
+{
+ return _ble_adv_running_flag == true;
+}
+#endif /* BLE_MESH_SUPPORT_MULTI_ADV */
+
+int bt_mesh_ble_ext_adv_start(const uint8_t inst_id,
+ const struct bt_mesh_ble_adv_param *param,
+ const struct bt_mesh_ble_adv_data *adv_data)
+{
+ struct ble_gap_ext_adv_params adv_params = {0};
+ struct os_mbuf *data = NULL;
+ int err = 0;
+
+ assert(param);
+
+ switch (param->adv_type) {
+ case BLE_MESH_ADV_IND:
+ adv_params.connectable = true;
+ adv_params.scannable = true;
+ adv_params.legacy_pdu = true;
+ break;
+ case BLE_MESH_ADV_DIRECT_IND:
+ adv_params.connectable = true;
+ adv_params.scannable = false;
+ adv_params.directed = true;
+ adv_params.high_duty_directed = false;
+ adv_params.legacy_pdu = true;
+ break;
+ case BLE_MESH_ADV_SCAN_IND:
+ adv_params.connectable = false;
+ adv_params.scannable = true;
+ adv_params.directed = false;
+ adv_params.high_duty_directed = false;
+ adv_params.legacy_pdu = true;
+ break;
+ case BLE_MESH_ADV_NONCONN_IND:
+ adv_params.connectable = false;
+ adv_params.scannable = false;
+ adv_params.directed = false;
+ adv_params.high_duty_directed = false;
+ adv_params.legacy_pdu = true;
+ break;
+ case BLE_MESH_ADV_DIRECT_IND_LOW_DUTY:
+ adv_params.connectable = true;
+ adv_params.scannable = false;
+ adv_params.directed = true;
+ adv_params.high_duty_directed = true;
+ adv_params.legacy_pdu = true;
+ break;
+ }
+
+ 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.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;
+
+ if (param->own_addr_type == BLE_MESH_ADDR_PUBLIC_ID ||
+ param->own_addr_type == BLE_MESH_ADDR_RANDOM_ID ||
+ param->adv_type == BLE_MESH_ADV_DIRECT_IND ||
+ param->adv_type == BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
+ adv_params.peer.type = param->peer_addr_type;
+ memcpy(adv_params.peer.val, param->peer_addr, BLE_MESH_ADDR_LEN);
+ }
+
+
+ if (ble_gap_ext_adv_configure(inst_id, &adv_params, NULL,
+ gap_event_cb, NULL)) {
+ BT_ERR("ble adv configure failed\n");
+ return -EINVAL;
+ }
+
+ if (adv_data && param->adv_type != BLE_MESH_ADV_DIRECT_IND &&
+ param->adv_type != BLE_MESH_ADV_DIRECT_IND_LOW_DUTY) {
+ if (adv_data->adv_data_len) {
+ data = os_msys_get_pkthdr(adv_data->adv_data_len, 0);
+ if (!data) {
+ BT_ERR("Failed to alloc buffer for ble");
+ return -ENOMEM;
+ }
+
+ if (os_mbuf_append(data, adv_data->adv_data, adv_data->adv_data_len)) {
+ BT_ERR("Append data failed");
+ return -EINVAL;
+ }
+
+ err = ble_gap_ext_adv_set_data(inst_id, data);
+ if (err) {
+ BT_ERR("Failed to set advertising data, err %d", err);
+ return err;
+ }
+ }
+ if (adv_data->scan_rsp_data_len && param->adv_type != BLE_MESH_ADV_NONCONN_IND) {
+ data = os_msys_get_pkthdr(adv_data->scan_rsp_data_len, 0);
+ if (!data) {
+ BT_ERR("Failed to alloc buffer for ble");
+ return -ENOMEM;
+ }
+
+ if (os_mbuf_append(data, adv_data->scan_rsp_data, adv_data->scan_rsp_data_len)) {
+ BT_ERR("Append data failed");
+ return -EINVAL;
+ }
+ err = ble_gap_ext_adv_rsp_set_data(inst_id, data);
+ if (err) {
+ BT_ERR("Failed to set scan rsp data, err %d", err);
+ return err;
+ }
+ }
+ }
+
+ err = ble_gap_ext_adv_start(inst_id, 2 + param->duration / 10, param->count);
+ if (err) {
+ BT_ERR("Failed to start advertising, err %d", err);
+ return err;
+ }
+
+#if !CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ bt_mesh_set_ble_adv_running();
+#endif
+
+ return 0;
+}
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
const struct bt_mesh_ble_adv_data *data)
{
@@ -949,8 +1602,27 @@ int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param,
return 0;
}
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_ADV */
+#if CONFIG_BLE_MESH_USE_BLE_50
+int bt_le_ext_adv_stop(uint8_t inst_id)
+{
+#if BLE_MESH_DEV
+ bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_KEEP_ADVERTISING);
+ if (!bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) {
+ return 0;
+ }
+#endif
+ ble_gap_ext_adv_stop(inst_id);
+
+#if BLE_MESH_DEV
+ bt_mesh_atomic_clear_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING);
+#endif
+
+ return 0;
+}
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_adv_stop(void)
{
#if BLE_MESH_DEV
@@ -967,6 +1639,7 @@ int bt_le_adv_stop(void)
return 0;
}
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t cb)
{
@@ -987,6 +1660,7 @@ int bt_le_scan_start(const struct bt_mesh_scan_param *param, bt_mesh_scan_cb_t c
err = start_le_scan(param->type, param->interval, param->window, param->filter_dup);
if (err) {
+ BT_ERR("Failed to start advertising, err %d", err);
return err;
}
@@ -1309,7 +1983,6 @@ int bt_mesh_gatts_service_stop(struct bt_mesh_gatt_service *svc)
{
int rc;
uint16_t handle;
- const ble_uuid_t *uuid;
if (!svc) {
BT_ERR("%s, Invalid parameter", __func__);
@@ -1317,12 +1990,11 @@ int bt_mesh_gatts_service_stop(struct bt_mesh_gatt_service *svc)
}
if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROXY_VAL) {
- uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL);
+ rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), &handle);
} else {
- uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL);
+ rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle);
}
- rc = ble_gatts_find_svc(uuid, &handle);
assert(rc == 0);
ble_gatts_svc_set_visibility(handle, 0);
@@ -1336,15 +2008,13 @@ int bt_mesh_gatts_service_start(struct bt_mesh_gatt_service *svc)
{
int rc;
uint16_t handle;
- const ble_uuid_t *uuid;
if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROXY_VAL) {
- uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL);
+ rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), &handle);
} else {
- uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL);
+ rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle);
}
- rc = ble_gatts_find_svc(uuid, &handle);
assert(rc == 0);
ble_gatts_svc_set_visibility(handle, 1);
@@ -1361,7 +2031,8 @@ int bt_mesh_gatts_set_local_device_name(const char *name)
#endif /* CONFIG_BLE_MESH_NODE */
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
- CONFIG_BLE_MESH_GATT_PROXY_CLIENT
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
void bt_mesh_gattc_conn_cb_register(struct bt_mesh_prov_conn_cb *cb)
{
bt_mesh_gattc_conn_cb = cb;
@@ -1558,6 +2229,7 @@ int bt_mesh_gattc_write_no_rsp(struct bt_mesh_conn *conn,
om = ble_hs_mbuf_from_flat(data, len);
if (om == NULL) {
+ BT_ERR("om buffer alloc failed");
return -1;
}
@@ -1602,7 +2274,10 @@ void bt_mesh_gattc_disconnect(struct bt_mesh_conn *conn)
* Mesh Proxy Data In: 0x2ADD
* Mesh PROXY Data Out: 0x2ADE
*/
-#endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
+
+#endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) ||
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT ||
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)*/
struct bt_mesh_conn *bt_mesh_conn_ref(struct bt_mesh_conn *conn)
{
@@ -1626,9 +2301,19 @@ static int proxy_char_access_cb(uint16_t conn_handle, uint16_t attr_handle,
{
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR || ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) {
struct bt_mesh_gatt_attr *attr = bt_mesh_gatts_find_attr_by_handle(attr_handle);
- uint8_t index = BLE_MESH_GATT_GET_CONN_ID(conn_handle);
+ int index = 0;
uint16_t len = 0;
+#if CONFIG_BLE_MESH_USE_BLE_50
+ index = bt_mesh_find_conn_idx(BLE_MESH_GATT_GET_CONN_ID(conn_handle));
+ if (index == -ENODEV) {
+ BT_ERR("Unknown conn handle");
+ return 0;
+ }
+#else
+ index = BLE_MESH_GATT_GET_CONN_ID(conn_handle);
+#endif
+
BT_DBG("write, handle %d, len %d, data %s", attr_handle,
ctxt->om->om_len,
bt_hex(ctxt->om->om_data, ctxt->om->om_len));
@@ -1717,6 +2402,58 @@ void gatt_register_cb(struct ble_gatt_register_ctxt *ctxt,
}
}
+#if CONFIG_BLE_MESH_USE_BLE_50
+void bt_mesh_gatts_svcs_add(void)
+{
+ ble_hs_cfg.gatts_register_cb = gatt_register_cb;
+
+#if CONFIG_BLE_MESH_NODE
+ int rc = 0;
+
+ ble_svc_gap_init();
+ ble_svc_gatt_init();
+
+ rc = ble_gatts_count_cfg(svc_defs);
+ assert(rc == 0);
+
+ rc = ble_gatts_add_svcs(svc_defs);
+ assert(rc == 0);
+
+ g_gatts_svcs_add = true;
+#endif
+}
+
+void bt_mesh_gatt_init(void)
+{
+ ble_att_set_preferred_mtu(BLE_MESH_GATT_DEF_MTU_SIZE);
+
+#if CONFIG_BLE_MESH_NODE
+ static bool init = false;
+
+ if (init == false) {
+
+ __ASSERT(g_gatts_svcs_add, "func bt_mesh_gatts_svcs_add should be called before mesh init");
+
+ ble_gatts_svc_set_visibility(prov_svc_start_handle, 1);
+ ble_gatts_svc_set_visibility(proxy_svc_start_handle, 0);
+
+#if CONFIG_BLE_MESH_USE_BLE_50
+ bt_mesh_gatts_conn_init();
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+ init = true;
+ }
+#endif /* CONFIG_BLE_MESH_NODE */
+
+#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT
+ for (int i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
+ bt_mesh_gattc_info[i].conn.handle = 0xFFFF;
+ bt_mesh_gattc_info[i].mtu = BLE_ATT_MTU_DFLT;
+ bt_mesh_gattc_info[i].wr_desc_done = false;
+ }
+#endif
+}
+#else
void bt_mesh_gatt_init(void)
{
ble_att_set_preferred_mtu(BLE_ATT_MTU_DFLT);
@@ -1747,7 +2484,8 @@ void bt_mesh_gatt_init(void)
#endif /* CONFIG_BLE_MESH_NODE */
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
- CONFIG_BLE_MESH_GATT_PROXY_CLIENT
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
for (int i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
bt_mesh_gattc_info[i].conn.handle = 0xFFFF;
bt_mesh_gattc_info[i].mtu = BLE_ATT_MTU_DFLT;
@@ -1755,6 +2493,7 @@ void bt_mesh_gatt_init(void)
}
#endif
}
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
#if CONFIG_BLE_MESH_DEINIT
void bt_mesh_gatt_deinit(void)
@@ -1765,7 +2504,8 @@ void bt_mesh_gatt_deinit(void)
#endif
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
- CONFIG_BLE_MESH_GATT_PROXY_CLIENT
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
for (int i = 0; i < ARRAY_SIZE(bt_mesh_gattc_info); i++) {
bt_mesh_gattc_info[i].conn.handle = 0xFFFF;
memset(&bt_mesh_gattc_info[i].addr, 0, sizeof(bt_mesh_addr_t));
@@ -1985,12 +2725,12 @@ int bt_mesh_update_exceptional_list(uint8_t sub_code, uint32_t type, void *info)
if ((sub_code > BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN) ||
(sub_code < BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN &&
- type > BLE_MESH_EXCEP_LIST_TYPE_MESH_PROXY_ADV) ||
+ type > BLE_MESH_EXCEP_LIST_TYPE_MAX) ||
(sub_code == BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN &&
!(type & BLE_MESH_EXCEP_LIST_CLEAN_ALL_LIST))) {
BT_ERR("%s, Invalid parameter", __func__);
return -EINVAL;
- }
+ }
if (type == BLE_MESH_EXCEP_LIST_TYPE_MESH_LINK_ID) {
if (!info) {
diff --git a/lib/bt/esp_ble_mesh/core/prov_common.c b/lib/bt/esp_ble_mesh/core/prov_common.c
index 655c4712..6f9e1dfa 100644
--- a/lib/bt/esp_ble_mesh/core/prov_common.c
+++ b/lib/bt/esp_ble_mesh/core/prov_common.c
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2018-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -135,6 +135,9 @@ bool bt_mesh_prov_pdu_check(uint8_t type, uint16_t length, uint8_t *reason)
#define CLOSE_XMIT BLE_MESH_TRANSMIT(2, 20)
#define CLOSE_TIMEOUT K_MSEC(100)
+#define CLOSE_RETRANS_CNT 3
+#define CLOSE_RETRANS_WITH_REASON(cnt, rsn) (((cnt) << 4) | ((rsn) & 0x0f))
+#define CLOSE_RETRANS_GET(rsn) ((rsn) >> 4)
#define BUF_TIMEOUT K_MSEC(400)
@@ -143,7 +146,7 @@ bool bt_mesh_prov_pdu_check(uint8_t type, uint16_t length, uint8_t *reason)
static uint8_t bt_mesh_prov_buf_type_get(struct net_buf_simple *buf)
{
- return buf->data[PROV_BUF_HEADROOM];
+ return buf->__buf[PROV_BUF_HEADROOM];
}
uint8_t node_next_xact_id(struct bt_mesh_prov_link *link)
@@ -359,7 +362,7 @@ static void free_segments(struct bt_mesh_prov_link *link)
link->tx.buf[i] = NULL;
bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL);
/* Mark as canceled */
- BLE_MESH_ADV(buf)->busy = 0U;
+ bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0);
net_buf_unref(buf);
}
}
@@ -457,12 +460,19 @@ static void prov_retransmit(struct k_work *work)
if (link->pb_remote_close) {
link->pb_remote_close(link, link->reason);
}
+ return;
} else {
- if (link->reset_adv_link) {
- link->reset_adv_link(link, link->reason);
+ uint8_t retrans_cnt = CLOSE_RETRANS_GET(link->reason);
+ if (!retrans_cnt) {
+ if (link->reset_adv_link) {
+ link->reset_adv_link(link, link->reason);
+ }
+ return;
+ } else {
+ retrans_cnt--;
+ link->reason = CLOSE_RETRANS_WITH_REASON(retrans_cnt, link->reason);
}
}
- return;
}
bt_mesh_mutex_lock(&link->buf_lock);
@@ -474,7 +484,7 @@ static void prov_retransmit(struct k_work *work)
break;
}
- if (BLE_MESH_ADV(buf)->busy) {
+ if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(buf))) {
continue;
}
@@ -547,7 +557,14 @@ int bt_mesh_prov_bearer_ctl_send(struct bt_mesh_prov_link *link, uint8_t op,
if (op == LINK_CLOSE) {
bt_mesh_atomic_clear_bit(link->flags, LINK_ACTIVE);
bt_mesh_atomic_set_bit(link->flags, LINK_CLOSING);
- link->reason = *((uint8_t *)data);
+ /** We can also use buf->ref and a flag to decide that
+ * link close has been sent 3 times.
+ * Here we use another way: use retransmit timer and need
+ * to make sure the timer is not cancelled during sending
+ * link close pdu, Therefore, use the higher four bits
+ * of reason as a retransmit count.
+ */
+ link->reason = CLOSE_RETRANS_WITH_REASON(CLOSE_RETRANS_CNT, (*((uint8_t *)data)));
}
return 0;
diff --git a/lib/bt/esp_ble_mesh/core/prov_common.h b/lib/bt/esp_ble_mesh/core/prov_common.h
index 561712ef..d2a8771b 100644
--- a/lib/bt/esp_ble_mesh/core/prov_common.h
+++ b/lib/bt/esp_ble_mesh/core/prov_common.h
@@ -17,7 +17,9 @@
#include "mesh/timer.h"
#include "mesh/adapter.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#ifdef __cplusplus
extern "C" {
diff --git a/lib/bt/esp_ble_mesh/core/prov_node.c b/lib/bt/esp_ble_mesh/core/prov_node.c
index 4871a1cb..cf789470 100644
--- a/lib/bt/esp_ble_mesh/core/prov_node.c
+++ b/lib/bt/esp_ble_mesh/core/prov_node.c
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -22,7 +22,9 @@
#include "prov_common.h"
#include "prov_node.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#if CONFIG_BLE_MESH_NODE
@@ -80,12 +82,12 @@ static void reset_state(void)
}
#endif /* CONFIG_BLE_MESH_PB_GATT */
-#if CONFIG_BLE_MESH_PB_ADV
/* Clear everything except the retransmit and protocol timer
* delayed work objects.
*/
(void)memset(&prov_link, 0, offsetof(struct bt_mesh_prov_link, tx.retransmit));
+#if CONFIG_BLE_MESH_PB_ADV
prov_link.pending_ack = PROV_XACT_NVAL;
prov_link.rx.prev_id = PROV_XACT_NVAL;
@@ -152,7 +154,7 @@ static int prov_send_gatt(struct bt_mesh_prov_link *link, struct net_buf_simple
/* Changed by Espressif, add provisioning timeout timer operations.
* When sending a provisioning PDU successfully, restart the 60s timer.
*/
-#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT && CONFIG_BLE_MESH_RPR_SRV
+#if CONFIG_BLE_MESH_RPR_SRV
if (bt_mesh_atomic_test_bit(link->flags, PB_REMOTE)) {
err = bt_mesh_proxy_client_send(link->conn, BLE_MESH_PROXY_PROV, msg);
@@ -1073,10 +1075,19 @@ static void link_ack(struct prov_rx *rx, struct net_buf_simple *buf)
bt_mesh_prov_clear_tx(&prov_link, true);
bt_mesh_rpr_srv_recv_link_ack(prov_link.pb_remote_uuid, true);
} else {
- BT_INFO("Link ACK for PB-Remote already received");
+ BT_DBG("Link ACK for PB-Remote already received");
+ return;
}
}
#endif /* CONFIG_BLE_MESH_RPR_SRV */
+
+ if (!k_delayed_work_remaining_get(&prov_link.prot_timer)) {
+ /**
+ * When the link is opened, the provisioner and the unprovisioned device
+ * shall start the link timer with the timeout value set to 60 seconds.
+ */
+ k_delayed_work_submit(&prov_link.prot_timer, PROTOCOL_TIMEOUT);
+ }
}
static void link_close(struct prov_rx *rx, struct net_buf_simple *buf)
@@ -1432,6 +1443,11 @@ int bt_mesh_pb_gatt_open(struct bt_mesh_conn *conn)
{
BT_DBG("conn %p", conn);
+ /**
+ * It's necessary to determine if it is PB_REMOTE because when the
+ * node acts as an RPR server, LINK_ACTIVE has already been set upon
+ * receiving the link open from the RPR client.
+ */
if (!bt_mesh_atomic_test_bit(prov_link.flags, PB_REMOTE) &&
bt_mesh_atomic_test_and_set_bit(prov_link.flags, LINK_ACTIVE)) {
BT_ERR("Link is busy");
@@ -1449,6 +1465,14 @@ int bt_mesh_pb_gatt_open(struct bt_mesh_conn *conn)
prov_link.expect = PROV_INVITE;
}
+ /**
+ * Just like ADV Link, start provision timeout timer after
+ * establishing the link to prevent the RPR server from
+ * being unable to recover to a configurable network state
+ * during remote provisioning.
+ */
+ k_delayed_work_submit(&prov_link.prot_timer, PROTOCOL_TIMEOUT);
+
if (bt_mesh_prov_get()->link_open) {
bt_mesh_prov_get()->link_open(BLE_MESH_PROV_GATT);
}
@@ -1469,6 +1493,9 @@ int bt_mesh_pb_gatt_close(struct bt_mesh_conn *conn, uint8_t reason)
if (bt_mesh_atomic_test_bit(prov_link.flags, PB_REMOTE)) {
prov_link.pb_remote_cbd = true;
prov_link.pb_remote_reset = true;
+ /* @todo: the close reason is disconnect reason, not the
+ * link close reason, should change it to link close reason?
+ */
prov_link.pb_remote_close(&prov_link, reason);
}
#endif
@@ -1494,7 +1521,7 @@ static void protocol_timeout(struct k_work *work)
#if CONFIG_BLE_MESH_PB_GATT
if (prov_link.conn) {
-#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT && CONFIG_BLE_MESH_RPR_SRV
+#if CONFIG_BLE_MESH_RPR_SRV
if (bt_mesh_atomic_test_bit(prov_link.flags, PB_REMOTE)) {
prov_link.pb_remote_reset = true;
bt_mesh_gattc_disconnect(prov_link.conn);
diff --git a/lib/bt/esp_ble_mesh/core/prov_pvnr.c b/lib/bt/esp_ble_mesh/core/prov_pvnr.c
index e2e0fe58..091e3e86 100644
--- a/lib/bt/esp_ble_mesh/core/prov_pvnr.c
+++ b/lib/bt/esp_ble_mesh/core/prov_pvnr.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -22,7 +22,9 @@
#include "prov_pvnr.h"
#include "pvnr_mgmt.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#if CONFIG_BLE_MESH_PROVISIONER
@@ -45,6 +47,10 @@ _Static_assert(BLE_MESH_MAX_CONN >= CONFIG_BLE_MESH_PBG_SAME_TIME,
*/
static struct bt_mesh_prov_link prov_links[BLE_MESH_PROV_SAME_TIME];
+#if CONFIG_BLE_MESH_RPR_CLI
+extern struct bt_mesh_prov_link rpr_links[CONFIG_BLE_MESH_RPR_CLI_PROV_SAME_TIME];
+#endif
+
struct bt_mesh_prov_ctx {
/* Primary element address of Provisioner */
uint16_t primary_addr;
@@ -242,7 +248,7 @@ void bt_mesh_provisioner_restore_prov_info(uint16_t primary_addr, uint16_t alloc
}
#endif /* CONFIG_BLE_MESH_SETTINGS */
-static bool is_unprov_dev_being_provision(const uint8_t uuid[16])
+bool bt_mesh_is_unprov_dev_being_prov(const uint8_t uuid[16])
{
int i;
@@ -259,6 +265,15 @@ static bool is_unprov_dev_being_provision(const uint8_t uuid[16])
}
#endif /* CONFIG_BLE_MESH_FAST_PROV */
+#if CONFIG_BLE_MESH_RPR_CLI
+ for (i = 0; i < CONFIG_BLE_MESH_RPR_CLI_PROV_SAME_TIME;i++) {
+ if (!memcmp(rpr_links[i].pb_remote_uuid, uuid, 16)) {
+ BT_WARN("Device is being provisioning by Remote Provisioning");
+ return true;
+ }
+ }
+#endif
+
for (i = 0; i < BLE_MESH_PROV_SAME_TIME; i++) {
if (bt_mesh_atomic_test_bit(prov_links[i].flags, LINK_ACTIVE)
#if CONFIG_BLE_MESH_PB_GATT
@@ -309,7 +324,7 @@ static int provisioner_check_unprov_dev_info(const uint8_t uuid[16], bt_mesh_pro
* receive the connectable prov adv pkt from this device.
* Here we check both PB-GATT and PB-ADV link status.
*/
- if (is_unprov_dev_being_provision(uuid)) {
+ if (bt_mesh_is_unprov_dev_being_prov(uuid)) {
return -EALREADY;
}
@@ -364,7 +379,7 @@ static int provisioner_start_prov_pb_adv(const uint8_t uuid[16], const bt_mesh_a
return -EIO;
}
- if (is_unprov_dev_being_provision(uuid)) {
+ if (bt_mesh_is_unprov_dev_being_prov(uuid)) {
bt_mesh_pb_adv_unlock();
return 0;
}
@@ -426,7 +441,7 @@ static int provisioner_start_prov_pb_gatt(const uint8_t uuid[16], const bt_mesh_
return -EIO;
}
- if (is_unprov_dev_being_provision(uuid)) {
+ if (bt_mesh_is_unprov_dev_being_prov(uuid)) {
bt_mesh_pb_gatt_unlock();
return 0;
}
@@ -1413,7 +1428,7 @@ static int prov_auth(struct bt_mesh_prov_link *link,
return -EINVAL;
}
- /* Provisioner ouput number/string and wait for device's Provisioning Input Complete PDU */
+ /* Provisioner output number/string and wait for device's Provisioning Input Complete PDU */
link->expect = PROV_INPUT_COMPLETE;
/* NOTE: The Bluetooth SIG recommends that mesh implementations enforce a randomly
@@ -1957,6 +1972,7 @@ static void send_prov_data(struct bt_mesh_prov_link *link)
uint8_t session_key[16] = {0};
uint8_t nonce[13] = {0};
uint8_t pdu[25] = {0};
+ uint8_t *dev_uuid = NULL;
PROV_BUF(buf, 34);
int err = 0;
@@ -2012,7 +2028,13 @@ static void send_prov_data(struct bt_mesh_prov_link *link)
*/
/* Check if this device is a re-provisioned device */
- node = bt_mesh_provisioner_get_node_with_uuid(link->uuid);
+ if (bt_mesh_atomic_test_bit(link->flags, PB_REMOTE)) {
+ dev_uuid = link->pb_remote_uuid;
+ } else {
+ dev_uuid = link->uuid;
+ }
+
+ node = bt_mesh_provisioner_get_node_with_uuid(dev_uuid);
if (node) {
if (link->element_num <= node->element_num &&
link->pb_remote_nppi != NPPI_NODE_ADDR_REFRESH) {
@@ -2027,7 +2049,7 @@ static void send_prov_data(struct bt_mesh_prov_link *link)
*/
if (!bt_mesh_atomic_test_bit(link->flags, PB_REMOTE) ||
link->pb_remote_nppi == NPPI_UNKNOWN) {
- bt_mesh_provisioner_remove_node(link->uuid);
+ bt_mesh_provisioner_remove_node(dev_uuid);
}
}
@@ -2211,6 +2233,7 @@ static void prov_complete(struct bt_mesh_prov_link *link,
uint16_t net_idx = 0U;
uint16_t index = 0U;
bool nppi = false;
+ uint8_t *dev_uuid = NULL;
int err = 0;
int i;
@@ -2227,12 +2250,16 @@ static void prov_complete(struct bt_mesh_prov_link *link,
net_idx = prov_ctx.net_idx;
}
- if (bt_mesh_atomic_test_bit(link->flags, PB_REMOTE) &&
- link->pb_remote_nppi != NPPI_UNKNOWN) {
- nppi = true;
+ if (bt_mesh_atomic_test_bit(link->flags, PB_REMOTE)) {
+ if (link->pb_remote_nppi != NPPI_UNKNOWN) {
+ nppi = true;
+ }
+ dev_uuid = link->pb_remote_uuid;
+ } else {
+ dev_uuid = link->uuid;
}
- err = bt_mesh_provisioner_provision(&link->addr, link->uuid, link->oob_info,
+ err = bt_mesh_provisioner_provision(&link->addr, dev_uuid, link->oob_info,
link->unicast_addr, link->element_num,
net_idx, link->kri_flags, bt_mesh.iv_index,
device_key, &index, nppi);
@@ -2264,13 +2291,13 @@ static void prov_complete(struct bt_mesh_prov_link *link,
#endif /* CONFIG_BLE_MESH_RPR_CLI */
if (bt_mesh_prov_get()->prov_complete) {
- bt_mesh_prov_get()->prov_complete(index, link->uuid, link->unicast_addr,
+ bt_mesh_prov_get()->prov_complete(index, dev_uuid, link->unicast_addr,
link->element_num, net_idx);
}
/* Find if the device is in the device queue */
for (i = 0; i < ARRAY_SIZE(unprov_dev); i++) {
- if (!memcmp(unprov_dev[i].uuid, link->uuid, 16) &&
+ if (!memcmp(unprov_dev[i].uuid, dev_uuid, 16) &&
(unprov_dev[i].flags & RM_AFTER_PROV)) {
memset(&unprov_dev[i], 0, sizeof(struct unprov_dev_queue));
break;
diff --git a/lib/bt/esp_ble_mesh/core/prov_pvnr.h b/lib/bt/esp_ble_mesh/core/prov_pvnr.h
index 0553a72d..b3eb5048 100644
--- a/lib/bt/esp_ble_mesh/core/prov_pvnr.h
+++ b/lib/bt/esp_ble_mesh/core/prov_pvnr.h
@@ -379,6 +379,8 @@ uint16_t bt_mesh_provisioner_get_fast_prov_net_idx(void);
*/
uint8_t bt_mesh_set_fast_prov_unicast_addr_range(uint16_t min, uint16_t max);
+bool bt_mesh_is_unprov_dev_being_prov(const uint8_t uuid[16]);
+
int bt_mesh_rpr_cli_pdu_recv(struct bt_mesh_prov_link *link, uint8_t type,
struct net_buf_simple *buf);
diff --git a/lib/bt/esp_ble_mesh/core/proxy_client.c b/lib/bt/esp_ble_mesh/core/proxy_client.c
index 9382cf61..ac05f92f 100644
--- a/lib/bt/esp_ble_mesh/core/proxy_client.c
+++ b/lib/bt/esp_ble_mesh/core/proxy_client.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -21,14 +21,17 @@
#include "pvnr_mgmt.h"
#include "mesh/adapter.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
- CONFIG_BLE_MESH_GATT_PROXY_CLIENT
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
static struct bt_mesh_proxy_server {
struct bt_mesh_conn *conn;
-
+ bt_mesh_addr_t addr;
enum __attribute__((packed)) {
CLI_NONE,
CLI_PROV,
@@ -83,6 +86,22 @@ static void proxy_sar_timeout(struct k_work *work)
bt_mesh_gattc_disconnect(server->conn);
}
+#if (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
+int bt_mesh_rpr_srv_set_waiting_prov_link(struct bt_mesh_prov_link *link,
+ bt_mesh_addr_t *addr)
+{
+ for (size_t i = 0; i < ARRAY_SIZE(waiting_conn_link);i++) {
+ if (waiting_conn_link[i].link == NULL) {
+ waiting_conn_link[i].link = link;
+ memcpy(&waiting_conn_link[i].addr, addr, sizeof(bt_mesh_addr_t));
+ return 0;
+ }
+ }
+
+ return -ENOBUFS;
+}
+#endif /* CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT */
+
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
/**
* The following callbacks are used to notify proper information
@@ -113,22 +132,6 @@ void bt_mesh_proxy_client_set_filter_status_cb(proxy_client_recv_filter_status_c
proxy_client_filter_status_recv_cb = cb;
}
-#if (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
-int bt_mesh_rpr_srv_set_waiting_prov_link(struct bt_mesh_prov_link *link,
- bt_mesh_addr_t *addr)
-{
- for (size_t i = 0; i < ARRAY_SIZE(waiting_conn_link);i++) {
- if (waiting_conn_link[i].link == NULL) {
- waiting_conn_link[i].link = link;
- memcpy(&waiting_conn_link[i].addr, addr, sizeof(bt_mesh_addr_t));
- return 0;
- }
- }
-
- return -ENOBUFS;
-}
-#endif /* CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT */
-
static void filter_status(struct bt_mesh_proxy_server *server,
struct bt_mesh_net_rx *rx,
struct net_buf_simple *buf)
@@ -264,7 +267,9 @@ static void proxy_complete_pdu(struct bt_mesh_proxy_server *server)
} else
#endif
{
+#if CONFIG_BLE_MESH_PROVISIONER
bt_mesh_provisioner_pb_gatt_recv(server->conn, &server->buf);
+#endif
}
break;
#endif
@@ -460,6 +465,7 @@ static void proxy_connected(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn, int
server->conn = bt_mesh_conn_ref(conn);
server->conn_type = CLI_NONE;
+ memcpy(&server->addr, addr, sizeof(bt_mesh_addr_t));
net_buf_simple_reset(&server->buf);
#if CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT
@@ -492,6 +498,7 @@ static void proxy_disconnected(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn,
if (bt_mesh_prov_node_get_link()->conn == conn) {
for (size_t i = 0; i < ARRAY_SIZE(waiting_conn_link); i++) {
if (waiting_conn_link[i].link->conn == conn) {
+ waiting_conn_link[i].link = NULL;
memset(&waiting_conn_link[i].addr, 0, sizeof(bt_mesh_addr_t));
break;
}
@@ -501,7 +508,9 @@ static void proxy_disconnected(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn,
} else
#endif /* CONFIG_BLE_MESH_RPR_SRV */
{
+#if CONFIG_BLE_MESH_PROVISIONER
bt_mesh_provisioner_pb_gatt_close(conn, reason);
+#endif /* CONFIG_BLE_MESH_PROVISIONER */
}
}
#endif /* CONFIG_BLE_MESH_PB_GATT && (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV) */
@@ -548,7 +557,9 @@ static ssize_t prov_write_ccc(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn)
}
#endif
+#if CONFIG_BLE_MESH_PROVISIONER
return bt_mesh_provisioner_pb_gatt_open(conn, addr->val);
+#endif
}
return -ENOMEM;
@@ -619,6 +630,12 @@ static ssize_t proxy_write_ccc(bt_mesh_addr_t *addr, struct bt_mesh_conn *conn)
return 0;
}
+#if CONFIG_BLE_MESH_BQB_TEST
+ /* notify maybe received first */
+ if (server->conn_type == CLI_PROXY) {
+ return 0;
+ }
+#endif
return -EINVAL;
}
@@ -631,6 +648,16 @@ static ssize_t proxy_recv_ntf(struct bt_mesh_conn *conn, uint8_t *data, uint16_t
return -ENOTCONN;
}
+#if CONFIG_BLE_MESH_BQB_TEST
+ /* update conn type if notify received before write ccc */
+ if (server->conn_type == CLI_NONE) {
+ server->conn_type = CLI_PROXY;
+ if (proxy_client_connect_cb) {
+ proxy_client_connect_cb(&server->addr, server - servers, server->net_idx);
+ }
+ }
+#endif
+
if (server->conn_type == CLI_PROXY) {
return proxy_recv(conn, NULL, data, len, 0, 0);
}
@@ -692,10 +719,12 @@ int bt_mesh_proxy_client_gatt_disable(void)
static struct bt_mesh_prov_conn_cb conn_callbacks = {
.connected = proxy_connected,
.disconnected = proxy_disconnected,
-#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
+#if (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV) && \
+ CONFIG_BLE_MESH_PB_GATT
.prov_write_descr = prov_write_ccc,
.prov_notify = prov_recv_ntf,
-#endif /* CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT */
+#endif /* (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV) && \
+ CONFIG_BLE_MESH_PB_GATT */
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
.proxy_write_descr = proxy_write_ccc,
.proxy_notify = proxy_recv_ntf,
@@ -818,6 +847,23 @@ int bt_mesh_proxy_client_disconnect(uint8_t conn_handle)
return 0;
}
+uint16_t bt_mesh_proxy_client_get_conn_count(void)
+{
+ uint16_t count = 0;
+
+ for (size_t i = 0; i < ARRAY_SIZE(servers); i++) {
+ struct bt_mesh_proxy_server *server = &servers[i];
+
+ if (!server->conn || server->conn_type != CLI_PROXY) {
+ continue;
+ }
+
+ count++;
+ }
+
+ return count;
+}
+
bool bt_mesh_proxy_client_relay(struct net_buf_simple *buf, uint16_t dst)
{
bool send = false;
@@ -1123,4 +1169,5 @@ int bt_mesh_proxy_client_deinit(void)
#endif /* CONFIG_BLE_MESH_DEINIT */
#endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
- CONFIG_BLE_MESH_GATT_PROXY_CLIENT */
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) */
diff --git a/lib/bt/esp_ble_mesh/core/proxy_client.h b/lib/bt/esp_ble_mesh/core/proxy_client.h
index d2d85017..6bc0732d 100644
--- a/lib/bt/esp_ble_mesh/core/proxy_client.h
+++ b/lib/bt/esp_ble_mesh/core/proxy_client.h
@@ -11,7 +11,9 @@
#include "mesh/adapter.h"
#include "prov_common.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#ifdef __cplusplus
extern "C" {
@@ -102,6 +104,8 @@ int bt_mesh_proxy_client_disconnect(uint8_t conn_handle);
bool bt_mesh_proxy_client_beacon_send(struct bt_mesh_subnet *sub, bool private);
+uint16_t bt_mesh_proxy_client_get_conn_count(void);
+
bool bt_mesh_proxy_client_relay(struct net_buf_simple *buf, uint16_t dst);
int bt_mesh_proxy_client_cfg_send(uint8_t conn_handle, uint16_t net_idx,
diff --git a/lib/bt/esp_ble_mesh/core/proxy_server.c b/lib/bt/esp_ble_mesh/core/proxy_server.c
index 020793dc..e8069155 100644
--- a/lib/bt/esp_ble_mesh/core/proxy_server.c
+++ b/lib/bt/esp_ble_mesh/core/proxy_server.c
@@ -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
*/
@@ -22,17 +22,23 @@
#include "prov_common.h"
#include "prov_node.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#if (CONFIG_BLE_MESH_NODE && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_SERVER
-#if !CONFIG_BLE_MESH_BQB_TEST
+#if !CONFIG_BLE_MESH_BQB_TEST && !CONFIG_BLE_MESH_PROXY_CLI_SRV_COEXIST && !CONFIG_BLE_MESH_RPR_SRV
/* Not support enabling Proxy Client and Proxy Server simultaneously */
_Static_assert(!(IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)),
"Not support Proxy Server and Proxy Client simultaneously");
#endif
+#if CONFIG_BLE_MESH_USE_BLE_50
+static uint8_t proxy_adv_inst = BLE_MESH_ADV_INS_UNUSED;
+#endif
+
#define ADV_OPT (BLE_MESH_ADV_OPT_CONNECTABLE | BLE_MESH_ADV_OPT_ONE_TIME)
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER && \
@@ -50,12 +56,24 @@ 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,
+#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,
+#endif
};
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,
+#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,
+#endif
};
static bool proxy_adv_enabled;
@@ -152,6 +170,11 @@ static void proxy_sar_timeout(struct k_work *work)
bt_mesh_gatts_disconnect(client->conn, 0x13);
}
+void bt_mesh_proxy_server_adv_flag_set(bool enable)
+{
+ proxy_adv_enabled = enable;
+}
+
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
/**
* The following callbacks are used to notify proper information
@@ -826,10 +849,18 @@ static void proxy_connected(struct bt_mesh_conn *conn, uint8_t err)
BT_DBG("conn %p err 0x%02x", conn, err);
+ if (gatt_svc == MESH_GATT_PROV && conn_count == 1) {
+ BT_WARN("Only one prov connection could exists");
+ bt_mesh_gatts_disconnect(conn, 0x13);
+ return;
+ }
+
conn_count++;
/* Since we use ADV_OPT_ONE_TIME */
- proxy_adv_enabled = false;
+#if !CONFIG_BLE_MESH_USE_BLE_50
+ bt_mesh_proxy_server_adv_flag_set(false);
+#endif
#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX
/* Before re-enabling advertising, stop advertising
@@ -1019,7 +1050,6 @@ int bt_mesh_proxy_server_prov_enable(void)
}
}
-
return 0;
}
@@ -1333,7 +1363,7 @@ int bt_mesh_proxy_server_segment_send(struct bt_mesh_conn *conn, uint8_t type,
net_buf_simple_pull(msg, mtu);
while (msg->len) {
- if (msg->len + 1 < mtu) {
+ if (msg->len + 1 <= mtu) {
net_buf_simple_push_u8(msg, BLE_MESH_PROXY_PDU_HDR(BLE_MESH_PROXY_SAR_LAST, type));
proxy_send(conn, msg->data, msg->len);
break;
@@ -1463,14 +1493,19 @@ static int node_id_adv(struct bt_mesh_subnet *sub)
memcpy(proxy_svc_data + 3, tmp + 8, 8);
proxy_sd_len = gatt_proxy_adv_create(&proxy_sd);
- err = bt_le_adv_start(&fast_adv_param, node_id_ad,
- ARRAY_SIZE(node_id_ad), &proxy_sd, proxy_sd_len);
+#if CONFIG_BLE_MESH_USE_BLE_50
+ err = bt_le_ext_adv_start(proxy_adv_inst, &fast_adv_param, node_id_ad,
+ ARRAY_SIZE(node_id_ad), &proxy_sd, proxy_sd_len);
+#else
+ err = bt_le_adv_start(&fast_adv_param, node_id_ad,
+ ARRAY_SIZE(node_id_ad), &proxy_sd, proxy_sd_len);
+#endif
if (err) {
BT_WARN("Failed to advertise using Node ID (err %d)", err);
return err;
}
- proxy_adv_enabled = true;
+ bt_mesh_proxy_server_adv_flag_set(true);
return 0;
}
@@ -1489,14 +1524,19 @@ static int net_id_adv(struct bt_mesh_subnet *sub)
memcpy(proxy_svc_data + 3, sub->keys[sub->kr_flag].net_id, 8);
proxy_sd_len = gatt_proxy_adv_create(&proxy_sd);
- err = bt_le_adv_start(&slow_adv_param, net_id_ad,
- ARRAY_SIZE(net_id_ad), &proxy_sd, proxy_sd_len);
+#if CONFIG_BLE_MESH_USE_BLE_50
+ err = bt_le_ext_adv_start(proxy_adv_inst, &slow_adv_param, net_id_ad,
+ ARRAY_SIZE(net_id_ad), &proxy_sd, proxy_sd_len);
+#else
+ err = bt_le_adv_start(&slow_adv_param, net_id_ad,
+ ARRAY_SIZE(net_id_ad), &proxy_sd, proxy_sd_len);
+#endif
if (err) {
BT_WARN("Failed to advertise using Network ID (err %d)", err);
return err;
}
- proxy_adv_enabled = true;
+ bt_mesh_proxy_server_adv_flag_set(true);
return 0;
}
@@ -1559,7 +1599,7 @@ static int private_node_id_adv(struct bt_mesh_subnet *sub)
return err;
}
- proxy_adv_enabled = true;
+ bt_mesh_proxy_server_adv_flag_set(true);
return 0;
}
@@ -1603,7 +1643,7 @@ static int private_net_id_adv(struct bt_mesh_subnet *sub)
return err;
}
- proxy_adv_enabled = true;
+ bt_mesh_proxy_server_adv_flag_set(true);
return 0;
}
@@ -1715,6 +1755,7 @@ static int32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub)
&& sub->private_node_id == BLE_MESH_PRIVATE_NODE_IDENTITY_STOPPED
#endif
) {
+ /* advertising node identity forever */
if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) {
net_id_adv(sub);
}
@@ -1830,17 +1871,25 @@ static int32_t solic_adv_private_net_id(void)
int32_t bt_mesh_proxy_server_adv_start(void)
{
+ BT_DBG("proxy server start");
+
if (gatt_svc == MESH_GATT_NONE) {
return K_FOREVER;
}
+#if CONFIG_BLE_MESH_USE_BLE_50
+ if (proxy_adv_inst == BLE_MESH_ADV_INS_UNUSED) {
+ return K_FOREVER;
+ }
+#endif
+
#if CONFIG_BLE_MESH_PB_GATT
if (prov_fast_adv) {
prov_start_time = k_uptime_get_32();
}
if (!bt_mesh_is_provisioned()) {
- const struct bt_mesh_adv_param *param;
+ const struct bt_mesh_adv_param *param = NULL;
struct bt_mesh_adv_data prov_sd[2];
size_t prov_sd_len;
@@ -1852,9 +1901,15 @@ int32_t bt_mesh_proxy_server_adv_start(void)
prov_sd_len = gatt_prov_adv_create(prov_sd);
+#if CONFIG_BLE_MESH_USE_BLE_50
+ if (bt_le_ext_adv_start(proxy_adv_inst, param, prov_ad, ARRAY_SIZE(prov_ad),
+ prov_sd, prov_sd_len) == 0) {
+#else /* CONFIG_BLE_MESH_USE_BLE_50 */
if (bt_le_adv_start(param, prov_ad, ARRAY_SIZE(prov_ad),
prov_sd, prov_sd_len) == 0) {
- proxy_adv_enabled = true;
+#endif /* CONFIG_BLE_MESH_USE_BLE_50 */
+
+ bt_mesh_proxy_server_adv_flag_set(true);
/* Advertise 60 seconds using fast interval */
if (prov_fast_adv) {
@@ -1884,25 +1939,35 @@ int32_t bt_mesh_proxy_server_adv_start(void)
}
#endif /* GATT_PROXY */
+ /* used to indicate proxy advertising could be stopped */
return K_FOREVER;
}
-void bt_mesh_proxy_server_adv_stop(void)
+int bt_mesh_proxy_server_adv_stop(void)
{
int err = 0;
- BT_DBG("adv_enabled %u", proxy_adv_enabled);
-
if (!proxy_adv_enabled) {
- return;
+ return -EALREADY;
}
+#if CONFIG_BLE_MESH_USE_BLE_50
+ if (proxy_adv_inst == BLE_MESH_ADV_INS_UNUSED) {
+ BT_ERR("Proxy adv inst is not initialized!");
+ return -EINVAL;
+ }
+
+ err = bt_le_ext_adv_stop(proxy_adv_inst);
+#else
err = bt_le_adv_stop();
+#endif
if (err) {
BT_ERR("Failed to stop advertising (err %d)", err);
- } else {
- proxy_adv_enabled = false;
+ return -EINVAL;
}
+
+ bt_mesh_proxy_server_adv_flag_set(false);
+ return 0;
}
static struct bt_mesh_conn_cb conn_callbacks = {
@@ -1914,6 +1979,14 @@ int bt_mesh_proxy_server_init(void)
{
int i;
+#if CONFIG_BLE_MESH_USE_BLE_50
+#if CONFIG_BLE_MESH_SUPPORT_MULTI_ADV
+ proxy_adv_inst = CONFIG_BLE_MESH_PROXY_ADV_INST_ID;
+#else /* CONFIG_BLE_MESH_SUPPORT_MULTI_ADV */
+ proxy_adv_inst = CONFIG_BLE_MESH_ADV_INST_ID;
+#endif
+#endif
+
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
bt_mesh_gatts_service_register(&proxy_svc);
#endif
@@ -1952,7 +2025,11 @@ int bt_mesh_proxy_server_deinit(void)
{
int i;
- proxy_adv_enabled = false;
+#if CONFIG_BLE_MESH_USE_BLE_50
+ proxy_adv_inst = BLE_MESH_ADV_INS_UNUSED;
+#endif
+
+ bt_mesh_proxy_server_adv_flag_set(false);
gatt_svc = MESH_GATT_NONE;
#if CONFIG_BLE_MESH_GATT_PROXY_SERVER
diff --git a/lib/bt/esp_ble_mesh/core/proxy_server.h b/lib/bt/esp_ble_mesh/core/proxy_server.h
index b9872891..fc4041f8 100644
--- a/lib/bt/esp_ble_mesh/core/proxy_server.h
+++ b/lib/bt/esp_ble_mesh/core/proxy_server.h
@@ -12,6 +12,7 @@
#include "net.h"
#include "mesh/adapter.h"
+#include "adv.h"
#ifdef __cplusplus
extern "C" {
@@ -94,7 +95,7 @@ void bt_mesh_proxy_server_beacon_send(struct bt_mesh_subnet *sub);
struct net_buf_simple *bt_mesh_proxy_server_get_buf(void);
int32_t bt_mesh_proxy_server_adv_start(void);
-void bt_mesh_proxy_server_adv_stop(void);
+int bt_mesh_proxy_server_adv_stop(void);
void bt_mesh_proxy_server_update_net_id_rand(void);
void bt_mesh_proxy_server_update_net_id_rand_stop(void);
@@ -117,6 +118,7 @@ void bt_mesh_proxy_server_identity_stop(struct bt_mesh_subnet *sub);
bool bt_mesh_proxy_server_relay(struct net_buf_simple *buf, uint16_t dst);
void bt_mesh_proxy_server_addr_add(struct net_buf_simple *buf, uint16_t addr);
+void bt_mesh_proxy_server_adv_flag_set(bool enable);
int bt_mesh_proxy_server_init(void);
int bt_mesh_proxy_server_deinit(void);
diff --git a/lib/bt/esp_ble_mesh/core/pvnr_mgmt.c b/lib/bt/esp_ble_mesh/core/pvnr_mgmt.c
index 2531a2d2..96ad2feb 100644
--- a/lib/bt/esp_ble_mesh/core/pvnr_mgmt.c
+++ b/lib/bt/esp_ble_mesh/core/pvnr_mgmt.c
@@ -22,7 +22,9 @@
#include "prov_pvnr.h"
#include "pvnr_mgmt.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#if CONFIG_BLE_MESH_PROVISIONER
diff --git a/lib/bt/esp_ble_mesh/core/scan.c b/lib/bt/esp_ble_mesh/core/scan.c
index e1b43dd2..192f63f8 100644
--- a/lib/bt/esp_ble_mesh/core/scan.c
+++ b/lib/bt/esp_ble_mesh/core/scan.c
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -27,7 +27,9 @@
#include "prov_pvnr.h"
#include "mesh/adapter.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
/* Scan Window and Interval are equal for continuous scanning */
#define SCAN_INTERVAL 0x20
@@ -39,6 +41,22 @@
#define PROXY_SVC_DATA_LEN_PRIVATE_NET_ID 0x11
#define PROXY_SVC_DATA_LEN_PRIVATE_NODE_ID 0x11
+static struct bt_mesh_scan_param scan_param = {
+#if CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
+ .type = BLE_MESH_SCAN_ACTIVE,
+#else
+ .type = BLE_MESH_SCAN_PASSIVE,
+#endif
+#if CONFIG_BLE_MESH_USE_DUPLICATE_SCAN
+ .filter_dup = BLE_MESH_SCAN_FILTER_DUP_ENABLE,
+#else
+ .filter_dup = BLE_MESH_SCAN_FILTER_DUP_DISABLE,
+#endif
+ .interval = SCAN_INTERVAL,
+ .window = SCAN_WINDOW,
+ .scan_fil_policy = BLE_MESH_SP_ADV_ALL,
+};
+
#if (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV)
static const bt_mesh_addr_t *unprov_dev_addr;
static uint8_t current_adv_type;
@@ -84,13 +102,14 @@ int bt_mesh_unprov_dev_info_query(uint8_t uuid[16], uint8_t addr[6],
{
uint8_t idx = 0;
uint8_t cnt = 0;
+ uint8_t pair_num = unprov_dev_info_fifo.pair_num;
- if (uuid == NULL || addr == NULL) {
+ if (uuid == NULL && addr == NULL) {
BT_WARN("No available information to query");
return -1;
}
- while (cnt < unprov_dev_info_fifo.pair_num) {
+ while (cnt < pair_num) {
idx = (cnt + unprov_dev_info_fifo.start_idx) % BLE_MESH_STORE_UNPROV_INFO_MAX_NUM;
if (query_type & BLE_MESH_STORE_UNPROV_INFO_QUERY_TYPE_UUID) {
if (!memcmp(unprov_dev_info_fifo.info[idx].addr, addr, 6)) {
@@ -116,8 +135,7 @@ int bt_mesh_unprov_dev_info_query(uint8_t uuid[16], uint8_t addr[6],
cnt++;
}
- if (cnt == unprov_dev_info_fifo.pair_num) {
- BT_WARN("Didn't find info for %d", query_type);
+ if (cnt == pair_num) {
return -1;
}
@@ -134,6 +152,11 @@ int bt_mesh_unprov_dev_fifo_enqueue(uint8_t uuid[16], const uint8_t addr[6], uin
return -EINVAL;
}
+ if (!bt_mesh_unprov_dev_info_query(uuid, NULL, NULL, BLE_MESH_STORE_UNPROV_INFO_QUERY_TYPE_ADDR |
+ BLE_MESH_STORE_UNPROV_INFO_QUERY_TYPE_EXISTS)) {
+ return 0;
+ }
+
if (unprov_dev_info_fifo.pair_num == BLE_MESH_STORE_UNPROV_INFO_MAX_NUM) {
bt_mesh_unprov_dev_fifo_dequeue(NULL, NULL);
}
@@ -164,7 +187,8 @@ uint8_t bt_mesh_get_adv_type(void)
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
- CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX
+ CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
static bool adv_flags_valid(struct net_buf_simple *buf)
{
uint8_t flags = 0U;
@@ -251,8 +275,10 @@ static void handle_adv_service_data(struct net_buf_simple *buf,
}
switch (type) {
-#if CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT
+#if (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV) && \
+ CONFIG_BLE_MESH_PB_GATT
case BLE_MESH_UUID_MESH_PROV_VAL:
+#if CONFIG_BLE_MESH_PROVISIONER
if (bt_mesh_is_provisioner_en()) {
if (buf->len != PROV_SVC_DATA_LEN) {
BT_WARN("Invalid Mesh Prov Service Data length %d", buf->len);
@@ -262,15 +288,19 @@ static void handle_adv_service_data(struct net_buf_simple *buf,
BT_DBG("Start to handle Mesh Prov Service Data");
bt_mesh_provisioner_prov_adv_recv(buf, addr, rssi);
}
+#endif /* CONFIG_BLE_MESH_PROVISIONER */
- if (IS_ENABLED(CONFIG_BLE_MESH_RPR_SRV) &&
- bt_mesh_is_provisioned()) {
+#if CONFIG_BLE_MESH_RPR_SRV
+ if (bt_mesh_is_provisioned()) {
const bt_mesh_addr_t *addr = bt_mesh_get_unprov_dev_addr();
bt_mesh_unprov_dev_fifo_enqueue(buf->data, addr->val, bt_mesh_get_adv_type());
bt_mesh_rpr_srv_unprov_beacon_recv(buf, bt_mesh_get_adv_type(), addr, rssi);
}
+#endif /* CONFIG_BLE_MESH_RPR_SRV */
+#endif /* (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV) &&
+ CONFIG_BLE_MESH_PB_GATT */
break;
-#endif
+
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
case BLE_MESH_UUID_MESH_PROXY_VAL:
if (buf->len != PROXY_SVC_DATA_LEN_NET_ID &&
@@ -303,8 +333,9 @@ static void handle_adv_service_data(struct net_buf_simple *buf,
}
}
#endif /* (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
- CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
- CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX */
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT) */
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
static bool ble_scan_en;
@@ -333,13 +364,27 @@ int bt_mesh_stop_ble_scan(void)
return 0;
}
+bool bt_mesh_ble_scan_state_get(void)
+{
+ return ble_scan_en;
+}
+
static void inline callback_ble_adv_pkt(const bt_mesh_addr_t *addr,
uint8_t adv_type, uint8_t data[],
uint16_t length, int8_t rssi)
{
+#if !CONFIG_BLE_MESH_USE_BLE_50
+ bt_mesh_ble_adv_report_t adv_rpt = {0};
if (ble_scan_en) {
- bt_mesh_ble_scan_cb_evt_to_btc(addr, adv_type, data, length, rssi);
+ memcpy(adv_rpt.addr, addr->val, BD_ADDR_LEN);
+ adv_rpt.addr_type = addr->type;
+ adv_rpt.adv_type = adv_type;
+ adv_rpt.length = length;
+ adv_rpt.data = data;
+ adv_rpt.rssi = rssi;
+ bt_mesh_ble_scan_cb_evt_to_btc(&adv_rpt);
}
+#endif
}
#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
@@ -361,14 +406,15 @@ static bool rpr_ext_scan_handle_adv_pkt(const bt_mesh_addr_t *addr,
}
#endif /* CONFIG_BLE_MESH_RPR_SRV */
-static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
- int8_t rssi, uint8_t adv_type,
- struct net_buf_simple *buf,
- uint8_t scan_rsp_len)
+static void bt_mesh_scan_cb(struct bt_mesh_adv_report *adv_rpt)
{
+ struct net_buf_simple_state buf_state = {0};
+ struct net_buf_simple *buf = &adv_rpt->adv_data;
+
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
- CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
- CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX
+ CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
+ CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
uint16_t uuid = 0U;
#endif
#if (CONFIG_BLE_MESH_RPR_SRV || CONFIG_BLE_MESH_SUPPORT_BLE_SCAN)
@@ -376,19 +422,43 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
uint16_t adv_len = buf->len;
#endif
- if (adv_type != BLE_MESH_ADV_NONCONN_IND && adv_type != BLE_MESH_ADV_IND) {
+ net_buf_simple_save(buf, &buf_state);
+
+ if (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
+#endif
+ ) {
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
- callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
+ callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
+ net_buf_simple_restore(buf, &buf_state);
return;
}
BT_DBG("scan, len %u: %s", buf->len, bt_hex(buf->data, buf->len));
#if (CONFIG_BLE_MESH_PROVISIONER || CONFIG_BLE_MESH_RPR_SRV)
- unprov_dev_addr = addr;
- current_adv_type = adv_type;
+ unprov_dev_addr = &adv_rpt->addr;
+ current_adv_type = adv_rpt->adv_type;
+#endif
+
+#if CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
+ if (adv_rpt->adv_type == BLE_MESH_ADV_SCAN_RSP) {
+ /**
+ * scan response is only visible for remote provisioning extend scan.
+ */
+ if (rpr_ext_scan_handle_adv_pkt(&adv_rpt->addr, adv_data, adv_len)) {
+ return;
+ } else {
+#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
+ callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
+ net_buf_simple_restore(buf, &buf_state);
+ }
+ }
+#endif /* CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN */
while (buf->len > 1) {
struct net_buf_simple_state state;
@@ -398,16 +468,18 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
/* Check for early termination */
if (len == 0U) {
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
- callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
+ callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
+ net_buf_simple_restore(buf, &buf_state);
return;
}
if (len > buf->len) {
BT_DBG("AD malformed");
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
- callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
+ callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
+ net_buf_simple_restore(buf, &buf_state);
return;
}
@@ -418,14 +490,17 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
buf->len = len - 1;
if ((type == BLE_MESH_DATA_MESH_PROV || type == BLE_MESH_DATA_MESH_MESSAGE ||
- type == BLE_MESH_DATA_MESH_BEACON) && (adv_type != BLE_MESH_ADV_NONCONN_IND)) {
- BT_DBG("Ignore mesh packet (type 0x%02x) with adv_type 0x%02x", type, adv_type);
+ type == BLE_MESH_DATA_MESH_BEACON) && (adv_rpt->adv_type != BLE_MESH_ADV_NONCONN_IND)) {
+ BT_DBG("Ignore mesh packet (type 0x%02x) with adv_type 0x%02x", type, adv_rpt->adv_type);
return;
}
switch (type) {
case BLE_MESH_DATA_MESH_MESSAGE:
- bt_mesh_net_recv(buf, rssi, BLE_MESH_NET_IF_ADV);
+ struct bt_mesh_net_rx rx = {
+ .ctx.recv_rssi = adv_rpt->rssi,
+ };
+ bt_mesh_generic_net_recv(buf, &rx, BLE_MESH_NET_IF_ADV);
break;
#if CONFIG_BLE_MESH_PB_ADV
case BLE_MESH_DATA_MESH_PROV:
@@ -438,17 +513,19 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
break;
#endif /* CONFIG_BLE_MESH_PB_ADV */
case BLE_MESH_DATA_MESH_BEACON:
- bt_mesh_beacon_recv(buf, rssi);
+ bt_mesh_beacon_recv(buf, adv_rpt->rssi);
break;
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
CONFIG_BLE_MESH_GATT_PROXY_CLIENT || \
- CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX
+ CONFIG_BLE_MESH_PROXY_SOLIC_PDU_RX || \
+ (CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_PB_GATT)
case BLE_MESH_DATA_FLAGS:
if (!adv_flags_valid(buf)) {
BT_DBG("Adv Flags mismatch, ignore this adv pkt");
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
- callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
+ callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
+ net_buf_simple_restore(buf, &buf_state);
return;
}
break;
@@ -456,7 +533,7 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
if (!adv_service_uuid_valid(buf, &uuid)) {
BT_DBG("Adv Service UUID mismatch, ignore this adv pkt");
#if CONFIG_BLE_MESH_RPR_SRV
- if (rpr_ext_scan_handle_adv_pkt(addr, adv_data, adv_len)) {
+ if (rpr_ext_scan_handle_adv_pkt(&adv_rpt->addr, adv_data, adv_len)) {
/* If handled as extended scan report successfully, then not
* notify to the application layer as normal BLE adv packet.
*/
@@ -464,18 +541,19 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
}
#endif
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
- callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
+ callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
+ net_buf_simple_restore(buf, &buf_state);
return;
}
break;
case BLE_MESH_DATA_SVC_DATA16:
- handle_adv_service_data(buf, addr, uuid, rssi);
+ handle_adv_service_data(buf, &adv_rpt->addr, uuid, adv_rpt->rssi);
break;
#endif
default:
#if CONFIG_BLE_MESH_RPR_SRV
- if (rpr_ext_scan_handle_adv_pkt(addr, adv_data, adv_len)) {
+ if (rpr_ext_scan_handle_adv_pkt(&adv_rpt->addr, adv_data, adv_len)) {
/* If handled as extended scan report successfully, then not
* notify to the application layer as normal BLE adv packet.
*/
@@ -483,44 +561,21 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr,
}
#endif
#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
- callback_ble_adv_pkt(addr, adv_type, adv_data, adv_len, rssi);
+ callback_ble_adv_pkt(&adv_rpt->addr, adv_rpt->adv_type, adv_data, adv_len, adv_rpt->rssi);
#endif
+ net_buf_simple_restore(buf, &buf_state);
return;
}
net_buf_simple_restore(buf, &state);
net_buf_simple_pull(buf, len);
}
-#if CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
- if (scan_rsp_len != 0) {
- /**
- * scan response is only visible for remote provisioning extend scan.
- */
- rpr_ext_scan_handle_adv_pkt(addr, adv_data + adv_len, scan_rsp_len);
- }
-#endif /* CONFIG_BLE_MESH_RPR_SRV && CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN */
}
int bt_mesh_scan_enable(void)
{
int err = 0;
- struct bt_mesh_scan_param scan_param = {
-#if CONFIG_BLE_MESH_RPR_SRV_ACTIVE_SCAN
- .type = BLE_MESH_SCAN_ACTIVE,
-#else
- .type = BLE_MESH_SCAN_PASSIVE,
-#endif
-#if CONFIG_BLE_MESH_USE_DUPLICATE_SCAN
- .filter_dup = BLE_MESH_SCAN_FILTER_DUP_ENABLE,
-#else
- .filter_dup = BLE_MESH_SCAN_FILTER_DUP_DISABLE,
-#endif
- .interval = SCAN_INTERVAL,
- .window = SCAN_WINDOW,
- .scan_fil_policy = BLE_MESH_SP_ADV_ALL,
- };
-
err = bt_le_scan_start(&scan_param, bt_mesh_scan_cb);
if (err && err != -EALREADY) {
BT_ERR("starting scan failed (err %d)", err);
@@ -543,6 +598,49 @@ int bt_mesh_scan_disable(void)
return 0;
}
+int bt_mesh_scan_param_update(struct bt_mesh_scan_param *param)
+{
+ int err = 0;
+
+ if (param == NULL ||
+ param->interval == 0 ||
+ param->interval < param->window) {
+ return -EINVAL;
+ }
+
+ scan_param.interval = param->interval;
+ scan_param.window = param->window;
+
+ err = bt_le_scan_stop();
+ if (err) {
+ if (err == -EALREADY) {
+ BT_INFO("New scan parameters will take effect after scan starts");
+ return 0;
+ }
+ BT_ERR("Failed to stop scan (err %d)", err);
+ return err;
+ }
+
+ /**
+ * Since the user only needs to set the scan interval
+ * and scan window parameters, only the interval and
+ * window parameters in the `param` are correct.
+ *
+ * For the aforementioned reason, when updating the scan
+ * parameters, the other parameters also need to be set
+ * correctly, and these other parameters are saved in the
+ * `scan_param`. Therefore, `scan_param` must be used instead
+ * of `param` here.
+ */
+ err = bt_le_scan_start(&scan_param, bt_mesh_scan_cb);
+ if (err && err != -EALREADY) {
+ BT_ERR("Failed to start scan (err %d)", err);
+ return err;
+ }
+
+ return 0;
+}
+
#if CONFIG_BLE_MESH_TEST_USE_WHITE_LIST
int bt_mesh_scan_with_wl_enable(void)
{
diff --git a/lib/bt/esp_ble_mesh/core/scan.h b/lib/bt/esp_ble_mesh/core/scan.h
index b7d0555c..612751d3 100644
--- a/lib/bt/esp_ble_mesh/core/scan.h
+++ b/lib/bt/esp_ble_mesh/core/scan.h
@@ -2,7 +2,7 @@
/*
* SPDX-FileCopyrightText: 2017 Intel Corporation
- * SPDX-FileContributor: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileContributor: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -33,16 +33,22 @@ int bt_mesh_scan_enable(void);
int bt_mesh_scan_disable(void);
+int bt_mesh_scan_param_update(struct bt_mesh_scan_param *scan_param);
+
int bt_mesh_scan_with_wl_enable(void);
struct bt_mesh_ble_scan_param {
uint32_t duration;
};
+#if CONFIG_BLE_MESH_SUPPORT_BLE_SCAN
int bt_mesh_start_ble_scan(struct bt_mesh_ble_scan_param *param);
int bt_mesh_stop_ble_scan(void);
+bool bt_mesh_ble_scan_state_get(void);
+#endif /* CONFIG_BLE_MESH_SUPPORT_BLE_SCAN */
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/esp_ble_mesh/core/storage/settings.c b/lib/bt/esp_ble_mesh/core/storage/settings.c
index 34a40d2d..40cf117f 100644
--- a/lib/bt/esp_ble_mesh/core/storage/settings.c
+++ b/lib/bt/esp_ble_mesh/core/storage/settings.c
@@ -22,7 +22,9 @@
#include "pvnr_mgmt.h"
#include "prov_pvnr.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
/* BLE Mesh NVS Key and corresponding data struct.
* Note: The length of nvs key must be <= 15.
@@ -1481,6 +1483,8 @@ int settings_core_commit(void)
struct bt_mesh_hb_pub *hb_pub = NULL;
struct bt_mesh_cfg_srv *cfg = NULL;
+ bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_VALID);
+
hb_pub = bt_mesh_hb_pub_get();
if (hb_pub && hb_pub->dst != BLE_MESH_ADDR_UNASSIGNED &&
hb_pub->count && hb_pub->period) {
@@ -1499,7 +1503,6 @@ int settings_core_commit(void)
cfg->default_ttl = stored_cfg.cfg.default_ttl;
}
- bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_VALID);
bt_mesh_net_start();
}
#endif /* CONFIG_BLE_MESH_NODE */
diff --git a/lib/bt/esp_ble_mesh/core/tag.h b/lib/bt/esp_ble_mesh/core/tag.h
new file mode 100644
index 00000000..d1b98310
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/core/tag.h
@@ -0,0 +1,53 @@
+/*
+ * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef _BLE_MESH_v11_TAG_H_
+#define _BLE_MESH_v11_TAG_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "mesh.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !CONFIG_BLE_MESH_V11_SUPPORT
+
+/* TAG - additional metadata */
+#define BLE_MESH_TAG_SEND_SEGMENTED BIT(0)
+#define BLE_MESH_TAG_IMMUTABLE_CRED BIT(1)
+#define BLE_MESH_TAG_RELAY BIT(3)
+#define BLE_MESH_TAG_FRIENDSHIP BIT(4)
+
+static inline bool bt_mesh_tag_send_segmented(uint8_t tag)
+{
+ return (tag & BLE_MESH_TAG_SEND_SEGMENTED);
+}
+
+static inline bool bt_mesh_tag_immutable_cred(uint8_t tag)
+{
+ return (tag & BLE_MESH_TAG_IMMUTABLE_CRED);
+}
+
+static inline bool bt_mesh_tag_relay(uint8_t tag)
+{
+ return (tag & BLE_MESH_TAG_RELAY);
+}
+
+static inline bool bt_mesh_tag_friendship(uint8_t tag)
+{
+ return (tag & BLE_MESH_TAG_FRIENDSHIP);
+}
+
+#endif /* !CONFIG_BLE_MESH_V11_SUPPORT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BLE_MESH_v11_TAG_H_ */
diff --git a/lib/bt/esp_ble_mesh/core/transport.c b/lib/bt/esp_ble_mesh/core/transport.c
index 64ac566a..fd3fd60a 100644
--- a/lib/bt/esp_ble_mesh/core/transport.c
+++ b/lib/bt/esp_ble_mesh/core/transport.c
@@ -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
*/
@@ -11,6 +11,7 @@
#include <errno.h>
#include "crypto.h"
+#include "tag.h"
#include "adv.h"
#include "mesh.h"
#include "lpn.h"
@@ -26,7 +27,9 @@
#include "mesh/cfg_srv.h"
#include "heartbeat.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
/* The transport layer needs at least three buffers for itself to avoid
* deadlocks. Ensure that there are a sufficient number of advertising
@@ -310,7 +313,15 @@ 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);
- BLE_MESH_ADV(tx->seg[seg_idx])->busy = 0U;
+ /**
+ * When cancelling a segment that is still in the adv sending queue, `tx->seg_pending`
+ * must else be decremented by one. More detailed information
+ * can be found in BLEMESH24-26.
+ */
+ if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(tx->seg[seg_idx]), 1, 0)) {
+ tx->seg_pending--;
+ }
+
net_buf_unref(tx->seg[seg_idx]);
tx->seg[seg_idx] = NULL;
tx->nack_count--;
@@ -369,6 +380,20 @@ static inline void seg_tx_complete(struct seg_tx *tx, int err)
static void schedule_retransmit(struct seg_tx *tx)
{
+ /* It's possible that a segment broadcast hasn't finished,
+ * but the tx are already released. Only the seg_pending
+ * of this segment remains unprocessed. So, here, we
+ * determine if the tx are released by checking if the
+ * destination (dst) is unassigned, and then process
+ * the seg_pending of this segment.
+ * See BLEMESH25-92 for details */
+ if (tx->dst == BLE_MESH_ADDR_UNASSIGNED) {
+ if (tx->seg_pending) {
+ tx->seg_pending--;
+ }
+ return;
+ }
+
if (--tx->seg_pending) {
return;
}
@@ -443,7 +468,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx)
continue;
}
- if (BLE_MESH_ADV(seg)->busy) {
+ if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) {
BT_DBG("Skipping segment that's still advertising");
continue;
}
@@ -493,7 +518,15 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
net_tx->aszmic, sdu->len);
for (tx = NULL, i = 0; i < ARRAY_SIZE(seg_tx); i++) {
- if (!seg_tx[i].nack_count) {
+ if (!seg_tx[i].nack_count &&
+ /* In some critical conditions, the tx might be
+ * reset before a segment broadcast is finished.
+ * If this happens, the seg_pending of the segment
+ * hasn't been processed. To avoid assigning this
+ * uncleared tx to a new message, extra checks for
+ * seg_pending being 0 are added. See BLEMESH25-92
+ * for details.*/
+ !seg_tx[i].seg_pending) {
tx = &seg_tx[i];
break;
}
@@ -1031,18 +1064,18 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, uint8_t hdr,
return 0;
}
- if (IS_ENABLED(CONFIG_BLE_MESH_DF_SRV)) {
- switch (ctl_op) {
- case TRANS_CTL_OP_PATH_REQ:
- case TRANS_CTL_OP_PATH_REPLY:
- case TRANS_CTL_OP_PATH_CFM:
- case TRANS_CTL_OP_PATH_ECHO_REQ:
- case TRANS_CTL_OP_PATH_ECHO_REPLY:
- case TRANS_CTL_OP_DEP_NODE_UPDATE:
- case TRANS_CTL_OP_PATH_REQ_SOLIC:
- return bt_mesh_directed_forwarding_ctl_recv(ctl_op, rx, buf);
- }
+#if CONFIG_BLE_MESH_DF_SRV
+ switch (ctl_op) {
+ case TRANS_CTL_OP_PATH_REQ:
+ case TRANS_CTL_OP_PATH_REPLY:
+ case TRANS_CTL_OP_PATH_CFM:
+ case TRANS_CTL_OP_PATH_ECHO_REQ:
+ case TRANS_CTL_OP_PATH_ECHO_REPLY:
+ case TRANS_CTL_OP_DEP_NODE_UPDATE:
+ case TRANS_CTL_OP_PATH_REQ_SOLIC:
+ return bt_mesh_directed_forwarding_ctl_recv(ctl_op, rx, buf);
}
+#endif
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !bt_mesh_lpn_established()) {
switch (ctl_op) {
@@ -1528,7 +1561,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx,
* eventually be freed up and we'll be able to process
* this one.
*/
- BT_WARN("No free slots for new incoming segmented messages");
+ BT_WARN("No free slots for new incoming segmented messages, src: %04x", net_rx->ctx.addr);
return -ENOMEM;
}
@@ -1751,8 +1784,6 @@ void bt_mesh_trans_init(void)
{
int i;
- bt_mesh_sar_init();
-
for (i = 0; i < ARRAY_SIZE(seg_tx); i++) {
k_delayed_work_init(&seg_tx[i].rtx_timer, seg_retransmit);
}
diff --git a/lib/bt/esp_ble_mesh/core/transport.enh.c b/lib/bt/esp_ble_mesh/core/transport.enh.c
index 6ef6c0a5..a4a5130e 100644
--- a/lib/bt/esp_ble_mesh/core/transport.enh.c
+++ b/lib/bt/esp_ble_mesh/core/transport.enh.c
@@ -350,7 +350,7 @@ static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx)
*/
bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 4U, BLE_MESH_BUF_REF_SMALL);
- BLE_MESH_ADV(tx->seg[seg_idx])->busy = 0U;
+ bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->seg[seg_idx]), 0);
net_buf_unref(tx->seg[seg_idx]);
tx->seg[seg_idx] = NULL;
@@ -498,7 +498,7 @@ static bool send_next_segment(struct seg_tx *tx, int *result)
/* The segment may have already been transmitted, for example, the
* Segment Retransmission timer is expired earlier.
*/
- if (BLE_MESH_ADV(seg)->busy) {
+ if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) {
return false;
}
@@ -768,7 +768,7 @@ static bool resend_unacked_seg(struct seg_tx *tx, int *result)
* A is still going to be retransmitted, but at this moment we could
* find that the "busy" flag of Segment A is 1.
*/
- if (BLE_MESH_ADV(seg)->busy) {
+ if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) {
return false;
}
diff --git a/lib/bt/esp_ble_mesh/lib/ext.c b/lib/bt/esp_ble_mesh/lib/ext.c
index ca779960..d9803b83 100644
--- a/lib/bt/esp_ble_mesh/lib/ext.c
+++ b/lib/bt/esp_ble_mesh/lib/ext.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -8,6 +8,8 @@
#include <string.h>
#include <assert.h>
+#include "esp_log.h"
+
#if CONFIG_BT_BLUEDROID_ENABLED
#include "bta/bta_api.h"
#endif
@@ -79,6 +81,25 @@
#define RPL(a) ((struct bt_mesh_rpl *)(a))
#define VOID(a) ((void *)(a))
+/* Declare Lib Variables */
+uint8_t __meshlib_var_BLE_MESH_ADV_PROV = BLE_MESH_ADV_PROV;
+uint8_t __meshlib_var_BLE_MESH_ADV_DATA = BLE_MESH_ADV_DATA;
+#if CONFIG_BLE_MESH_FRIEND
+uint8_t __meshlib_var_BLE_MESH_ADV_FRIEND = BLE_MESH_ADV_FRIEND;
+#endif
+#if CONFIG_BLE_MESH_RELAY_ADV_BUF
+uint8_t __meshlib_var_BLE_MESH_ADV_RELAY_DATA = BLE_MESH_ADV_RELAY_DATA;
+#endif
+uint8_t __meshlib_var_BLE_MESH_ADV_BEACON = BLE_MESH_ADV_BEACON;
+uint8_t __meshlib_var_BLE_MESH_ADV_URI = BLE_MESH_ADV_URI;
+#if CONFIG_BLE_MESH_PROXY_SOLIC_PDU_TX
+uint8_t __meshlib_var_BLE_MESH_ADV_PROXY_SOLIC = BLE_MESH_ADV_PROXY_SOLIC;
+#endif
+#if CONFIG_BLE_MESH_SUPPORT_BLE_ADV
+uint8_t __meshlib_var_BLE_MESH_ADV_BLE = BLE_MESH_ADV_BLE;
+#endif
+uint8_t __meshlib_var_BLE_MESH_ADV_TYPES_NUM = BLE_MESH_ADV_TYPES_NUM;
+
/* Sys utilities */
void bt_mesh_ext_put_be16(uint16_t val, uint8_t dst[2])
{
@@ -190,6 +211,11 @@ void bt_mesh_ext_mem_swap(void *buf, size_t length)
sys_mem_swap(buf, length);
}
+uint32_t bt_mesh_ext_log_timestamp(void)
+{
+ return esp_log_timestamp();
+}
+
/* Net buf */
void bt_mesh_ext_buf_simple_init(struct net_buf_simple *buf, size_t reserve_head)
{
@@ -498,6 +524,11 @@ float bt_mesh_ext_log2(float num)
return bt_mesh_log2(num);
}
+const char *bt_mesh_ext_hex(const void *buf, size_t len)
+{
+ return bt_hex(buf, len);
+}
+
/* Crypto */
bool bt_mesh_ext_s1(const char *m, uint8_t salt[16])
{
@@ -1147,17 +1178,17 @@ uint8_t *bt_mesh_ext_net_get_dev_key_ca(void)
return bt_mesh.dev_key_ca;
}
-uint8_t bt_mesh_ext_net_get_rpl_count(void)
+uint16_t bt_mesh_ext_net_get_rpl_count(void)
{
return ARRAY_SIZE(bt_mesh.rpl);
}
-uint16_t bt_mesh_ext_net_get_rpl_src(uint8_t index)
+uint16_t bt_mesh_ext_net_get_rpl_src(uint16_t index)
{
return bt_mesh.rpl[index].src;
}
-void bt_mesh_ext_net_reset_rpl(uint8_t index)
+void bt_mesh_ext_net_reset_rpl(uint16_t index)
{
memset(&bt_mesh.rpl[index], 0, sizeof(bt_mesh.rpl[index]));
}
@@ -1494,6 +1525,11 @@ void bt_mesh_ext_prov_link_set_expect(void *link, uint8_t val)
LINK(link)->expect = val;
}
+uint8_t bt_mesh_ext_prov_link_get_expect(void *link)
+{
+ return LINK(link)->expect;
+}
+
uint8_t bt_mesh_ext_prov_link_get_pub_key_type(void *link)
{
return LINK(link)->public_key;
@@ -1621,6 +1657,16 @@ uint8_t *bt_mesh_ext_prov_link_get_pb_remote_uuid(void *link)
return LINK(link)->pb_remote_uuid;
}
+void *bt_mesh_ext_prov_link_get_prot_timer(void *link)
+{
+ return &(LINK(link)->prot_timer);
+}
+
+void *bt_mesh_ext_prov_link_get_with_work(void *work)
+{
+ return CONTAINER_OF(work, struct bt_mesh_prov_link, prot_timer.work);
+}
+
uint8_t bt_mesh_ext_prov_link_get_pb_remote_timeout(void *link)
{
return LINK(link)->pb_remote_timeout;
@@ -2037,9 +2083,19 @@ int bt_mesh_ext_rpr_cli_pdu_recv(void *link, uint8_t type, struct net_buf_simple
}
#if CONFIG_BLE_MESH_RPR_CLI
-static struct bt_mesh_prov_link rpr_links[CONFIG_BLE_MESH_RPR_CLI_PROV_SAME_TIME];
+struct bt_mesh_prov_link rpr_links[CONFIG_BLE_MESH_RPR_CLI_PROV_SAME_TIME];
#endif /* CONFIG_BLE_MESH_RPR_CLI */
+bool bt_mesh_ext_bt_mesh_is_unprov_dev_being_prov(void *uuid)
+{
+#if CONFIG_BLE_MESH_RPR_CLI
+ return bt_mesh_is_unprov_dev_being_prov(uuid);
+#else
+ assert(0);
+ return 0;
+#endif
+}
+
void *bt_mesh_ext_rpr_cli_get_rpr_link(uint8_t index)
{
#if CONFIG_BLE_MESH_RPR_CLI
@@ -2071,16 +2127,12 @@ int bt_mesh_ext_rpr_srv_nppi_pdu_recv(uint8_t type, const uint8_t *data)
int bt_mesh_ext_rpr_srv_set_waiting_prov_link(void* link, bt_mesh_addr_t *addr)
{
-#if (CONFIG_BLE_MESH_GATT_PROXY_CLIENT && \
- CONFIG_BLE_MESH_PB_GATT && \
- CONFIG_BLE_MESH_RPR_SRV)
+#if (CONFIG_BLE_MESH_PB_GATT && CONFIG_BLE_MESH_RPR_SRV)
return bt_mesh_rpr_srv_set_waiting_prov_link(link, addr);
#else
assert(0);
return 0;
-#endif /* (CONFIG_BLE_MESH_GATT_PROXY_CLIENT && \
- CONFIG_BLE_MESH_PB_GATT && \
- CONFIG_BLE_MESH_RPR_SRV) */
+#endif /* CONFIG_BLE_MESH_PB_GATT && CONFIG_BLE_MESH_RPR_SRV) */
}
/* Friend */
@@ -3764,7 +3816,7 @@ void *bt_mesh_ext_brc_srv_get_bridge_table_entry(void *srv, uint8_t index)
#endif /* CONFIG_BLE_MESH_BRC_SRV */
}
-void *bt_mesh_ext_brc_srv_get_bridge_rpl(uint8_t index)
+void *bt_mesh_ext_brc_srv_get_bridge_rpl(uint16_t index)
{
#if CONFIG_BLE_MESH_BRC_SRV
return &bridge_rpl[index];
@@ -3954,6 +4006,9 @@ void bt_mesh_ext_mbt_server_cb_evt_to_btc(uint8_t event, void *model, void *ctx)
}
typedef struct {
+ uint64_t config_ble_mesh_stack_trace_level : 3;
+
+ uint64_t config_ble_mesh_use_ble_50: 1;
uint64_t config_ble_mesh_use_duplicate_scan : 1;
uint64_t config_ble_mesh_pb_adv : 1;
uint64_t config_ble_mesh_pb_gatt : 1;
@@ -3997,6 +4052,7 @@ typedef struct {
uint64_t config_ble_mesh_srpl_cli : 1;
uint64_t config_ble_mesh_srpl_srv : 1;
+ uint32_t config_ble_mesh_prov_protocol_timeout;
uint16_t config_ble_mesh_record_frag_max_size;
uint16_t config_ble_mesh_crpl;
uint16_t config_ble_mesh_proxy_solic_rx_crpl;
@@ -4116,6 +4172,9 @@ typedef struct {
} bt_mesh_ext_config_t;
static const bt_mesh_ext_config_t bt_mesh_ext_cfg = {
+ .config_ble_mesh_stack_trace_level = BLE_MESH_LOG_LEVEL,
+
+ .config_ble_mesh_use_ble_50 = IS_ENABLED(CONFIG_BLE_MESH_USE_BLE_50),
.config_ble_mesh_use_duplicate_scan = IS_ENABLED(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN),
.config_ble_mesh_pb_adv = IS_ENABLED(CONFIG_BLE_MESH_PB_ADV),
.config_ble_mesh_pb_gatt = IS_ENABLED(CONFIG_BLE_MESH_PB_GATT),
@@ -4160,6 +4219,7 @@ static const bt_mesh_ext_config_t bt_mesh_ext_cfg = {
.config_ble_mesh_sar_srv = IS_ENABLED(CONFIG_BLE_MESH_SAR_SRV),
.config_ble_mesh_srpl_cli = IS_ENABLED(CONFIG_BLE_MESH_SRPL_CLI),
.config_ble_mesh_srpl_srv = IS_ENABLED(CONFIG_BLE_MESH_SRPL_SRV),
+ .config_ble_mesh_prov_protocol_timeout = PROTOCOL_TIMEOUT,
#if CONFIG_BLE_MESH_CERT_BASED_PROV
.config_ble_mesh_record_frag_max_size = CONFIG_BLE_MESH_RECORD_FRAG_MAX_SIZE,
@@ -4495,6 +4555,7 @@ typedef struct {
int (*_bt_mesh_ext_rpr_cli_pdu_send)(void *link, uint8_t type);
int (*_bt_mesh_ext_rpr_cli_recv_pub_key_outbound_report)(void *link);
int (*_bt_mesh_ext_rpr_cli_pdu_recv)(void *link, uint8_t type, struct net_buf_simple *buf);
+ bool (*_bt_mesh_ext_bt_mesh_is_unprov_dev_being_prov)(void *uuid);
void *(*_bt_mesh_ext_rpr_cli_get_rpr_link)(uint8_t index);
/* CONFIG_BLE_MESH_RPR_CLI */
@@ -4526,7 +4587,7 @@ typedef struct {
uint16_t (*_bt_mesh_ext_sub_get_sbr_net_idx)(void *sub);
void (*_bt_mesh_ext_sub_set_sbr_net_idx)(void *sub, uint16_t sbr_net_idx);
void *(*_bt_mesh_ext_brc_srv_get_bridge_table_entry)(void *srv, uint8_t index);
- void *(*_bt_mesh_ext_brc_srv_get_bridge_rpl)(uint8_t index);
+ void *(*_bt_mesh_ext_brc_srv_get_bridge_rpl)(uint16_t index);
/* CONFIG_BLE_MESH_BRC_SRV */
/* CONFIG_BLE_MESH_AGG_CLI */
@@ -4816,6 +4877,7 @@ static const bt_mesh_ext_funcs_t bt_mesh_ext_func = {
._bt_mesh_ext_rpr_cli_pdu_send = bt_mesh_ext_rpr_cli_pdu_send,
._bt_mesh_ext_rpr_cli_recv_pub_key_outbound_report = bt_mesh_ext_rpr_cli_recv_pub_key_outbound_report,
._bt_mesh_ext_rpr_cli_pdu_recv = bt_mesh_ext_rpr_cli_pdu_recv,
+ ._bt_mesh_ext_bt_mesh_is_unprov_dev_being_prov = bt_mesh_ext_bt_mesh_is_unprov_dev_being_prov,
._bt_mesh_ext_rpr_cli_get_rpr_link = bt_mesh_ext_rpr_cli_get_rpr_link,
/* CONFIG_BLE_MESH_RPR_CLI */
diff --git a/lib/bt/esp_ble_mesh/lib/include/mesh_v1.1/utils.h b/lib/bt/esp_ble_mesh/lib/include/mesh_v1.1/utils.h
index 71a02314..d8e80b19 100644
--- a/lib/bt/esp_ble_mesh/lib/include/mesh_v1.1/utils.h
+++ b/lib/bt/esp_ble_mesh/lib/include/mesh_v1.1/utils.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
diff --git a/lib/bt/esp_ble_mesh/lib/lib/esp32/libble_mesh.a b/lib/bt/esp_ble_mesh/lib/lib/esp32/libble_mesh.a
index 5f8b75a3..73d2771c 100644
--- a/lib/bt/esp_ble_mesh/lib/lib/esp32/libble_mesh.a
+++ b/lib/bt/esp_ble_mesh/lib/lib/esp32/libble_mesh.a
Binary files differ
diff --git a/lib/bt/esp_ble_mesh/lib/lib/esp32c3/libble_mesh.a b/lib/bt/esp_ble_mesh/lib/lib/esp32c3/libble_mesh.a
index ffc32db1..27e93069 100644
--- a/lib/bt/esp_ble_mesh/lib/lib/esp32c3/libble_mesh.a
+++ b/lib/bt/esp_ble_mesh/lib/lib/esp32c3/libble_mesh.a
Binary files differ
diff --git a/lib/bt/esp_ble_mesh/lib/lib/esp32c5/libble_mesh.a b/lib/bt/esp_ble_mesh/lib/lib/esp32c5/libble_mesh.a
new file mode 100644
index 00000000..27e93069
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/lib/lib/esp32c5/libble_mesh.a
Binary files differ
diff --git a/lib/bt/esp_ble_mesh/lib/lib/esp32c6/libble_mesh.a b/lib/bt/esp_ble_mesh/lib/lib/esp32c6/libble_mesh.a
index ffc32db1..27e93069 100644
--- a/lib/bt/esp_ble_mesh/lib/lib/esp32c6/libble_mesh.a
+++ b/lib/bt/esp_ble_mesh/lib/lib/esp32c6/libble_mesh.a
Binary files differ
diff --git a/lib/bt/esp_ble_mesh/lib/lib/esp32c61/libble_mesh.a b/lib/bt/esp_ble_mesh/lib/lib/esp32c61/libble_mesh.a
new file mode 100644
index 00000000..27e93069
--- /dev/null
+++ b/lib/bt/esp_ble_mesh/lib/lib/esp32c61/libble_mesh.a
Binary files differ
diff --git a/lib/bt/esp_ble_mesh/lib/lib/esp32h2/libble_mesh.a b/lib/bt/esp_ble_mesh/lib/lib/esp32h2/libble_mesh.a
index ffc32db1..27e93069 100644
--- a/lib/bt/esp_ble_mesh/lib/lib/esp32h2/libble_mesh.a
+++ b/lib/bt/esp_ble_mesh/lib/lib/esp32h2/libble_mesh.a
Binary files differ
diff --git a/lib/bt/esp_ble_mesh/lib/lib/esp32s3/libble_mesh.a b/lib/bt/esp_ble_mesh/lib/lib/esp32s3/libble_mesh.a
index 5f8b75a3..a72cd64c 100644
--- a/lib/bt/esp_ble_mesh/lib/lib/esp32s3/libble_mesh.a
+++ b/lib/bt/esp_ble_mesh/lib/lib/esp32s3/libble_mesh.a
Binary files differ
diff --git a/lib/bt/esp_ble_mesh/models/client/client_common.c b/lib/bt/esp_ble_mesh/models/client/client_common.c
index db878516..7e544870 100644
--- a/lib/bt/esp_ble_mesh/models/client/client_common.c
+++ b/lib/bt/esp_ble_mesh/models/client/client_common.c
@@ -14,7 +14,9 @@
#include "mesh/client_common.h"
#include "mesh/common.h"
+#if CONFIG_BLE_MESH_V11_SUPPORT
#include "mesh_v1.1/utils.h"
+#endif
#define HCI_TIME_FOR_START_ADV K_MSEC(5) /* Three adv related hci commands may take 4 ~ 5ms */
diff --git a/lib/bt/esp_ble_mesh/models/server/time_scene_server.c b/lib/bt/esp_ble_mesh/models/server/time_scene_server.c
index 3494653a..a63550bc 100644
--- a/lib/bt/esp_ble_mesh/models/server/time_scene_server.c
+++ b/lib/bt/esp_ble_mesh/models/server/time_scene_server.c
@@ -244,7 +244,8 @@ static void time_get(struct bt_mesh_model *model,
change.time_status.subsecond = srv->state->time.subsecond;
change.time_status.uncertainty = srv->state->time.uncertainty;
change.time_status.time_authority = srv->state->time.time_authority;
- change.time_status.tai_utc_delta_curr = srv->state->time.subsecond;
+ change.time_status.tai_utc_delta_curr = srv->state->time.tai_utc_delta_curr;
+ change.time_status.time_zone_offset_curr = srv->state->time.time_zone_offset_curr;
bt_mesh_time_scene_server_cb_evt_to_btc(BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE,
model, ctx, (const uint8_t *)&change, sizeof(change));
@@ -386,7 +387,8 @@ static void time_set(struct bt_mesh_model *model,
change.time_set.subsecond = srv->state->time.subsecond;
change.time_set.uncertainty = srv->state->time.uncertainty;
change.time_set.time_authority = srv->state->time.time_authority;
- change.time_set.tai_utc_delta_curr = srv->state->time.subsecond;
+ change.time_set.tai_utc_delta_curr = srv->state->time.tai_utc_delta_curr;
+ change.time_set.time_zone_offset_curr = srv->state->time.time_zone_offset_curr;
break;
case BLE_MESH_MODEL_OP_TIME_ZONE_SET:
change.time_zone_set.time_zone_offset_new = srv->state->time.time_zone_offset_new;
diff --git a/lib/bt/esp_ble_mesh/v1.1/api/core/esp_ble_mesh_rpr_model_api.c b/lib/bt/esp_ble_mesh/v1.1/api/core/esp_ble_mesh_rpr_model_api.c
index 5ab2cd17..de5550ce 100644
--- a/lib/bt/esp_ble_mesh/v1.1/api/core/esp_ble_mesh_rpr_model_api.c
+++ b/lib/bt/esp_ble_mesh/v1.1/api/core/esp_ble_mesh_rpr_model_api.c
@@ -1,10 +1,11 @@
/*
- * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
+#include <string.h>
#include "btc/btc_manage.h"
@@ -91,4 +92,34 @@ esp_err_t esp_ble_mesh_register_rpr_server_callback(esp_ble_mesh_rpr_server_cb_t
return (btc_profile_cb_set(BTC_PID_RPR_SERVER, callback) == 0 ? ESP_OK : ESP_FAIL);
}
+
+esp_err_t esp_ble_mesh_rpr_server_set_uuid_match(const uint8_t *match_val, uint8_t match_len, uint8_t offset)
+{
+ btc_ble_mesh_rpr_server_args_t arg = {0};
+ btc_msg_t msg = {0};
+
+ msg.sig = BTC_SIG_API_CALL;
+ msg.pid = BTC_PID_RPR_SERVER;
+ msg.act = BTC_BLE_MESH_ACT_RPR_SRV_SET_UUID_MATCH;
+
+ if (!match_len || match_len > 16 ||
+ !match_val || offset >= 16 ||
+ offset + match_len > 16) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ arg.set_uuid_match.match_val = bt_mesh_calloc(match_len);
+ if (!arg.set_uuid_match.match_val) {
+ BT_ERR("%s:Out of memory", __func__);
+ return ESP_ERR_NO_MEM;
+ }
+
+ memcpy(arg.set_uuid_match.match_val, match_val, match_len);
+ arg.set_uuid_match.match_len = match_len;
+ arg.set_uuid_match.offset = offset;
+
+ return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_rpr_server_args_t),
+ btc_ble_mesh_rpr_server_arg_deep_copy,
+ btc_ble_mesh_rpr_server_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
+}
#endif /* CONFIG_BLE_MESH_RPR_SRV */
diff --git a/lib/bt/esp_ble_mesh/v1.1/api/core/include/esp_ble_mesh_rpr_model_api.h b/lib/bt/esp_ble_mesh/v1.1/api/core/include/esp_ble_mesh_rpr_model_api.h
index 31d0923e..a19e5539 100644
--- a/lib/bt/esp_ble_mesh/v1.1/api/core/include/esp_ble_mesh_rpr_model_api.h
+++ b/lib/bt/esp_ble_mesh/v1.1/api/core/include/esp_ble_mesh_rpr_model_api.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -396,6 +396,13 @@ typedef union {
uint16_t net_idx; /*!< NetKey Index used by Remote Provisioning Client */
uint16_t rpr_cli_addr; /*!< Unicast address of Remote Provisioning Client */
} prov_comp;
+
+ /**
+ * @brief ESP_BLE_MESH_RPR_SERVER_SET_UUID_MATCH_COMP_EVT
+ */
+ struct {
+ int err_code; /*!< Indicate the result of setting Device UUID match value by the Remote Provisioning Server */
+ } set_uuid_match_comp;
} esp_ble_mesh_rpr_server_cb_param_t;
/** This enum value is the event of Remote Provisioning Server model */
@@ -407,6 +414,7 @@ typedef enum {
ESP_BLE_MESH_RPR_SERVER_LINK_OPEN_EVT,
ESP_BLE_MESH_RPR_SERVER_LINK_CLOSE_EVT,
ESP_BLE_MESH_RPR_SERVER_PROV_COMP_EVT,
+ ESP_BLE_MESH_RPR_SERVER_SET_UUID_MATCH_COMP_EVT,
ESP_BLE_MESH_RPR_SERVER_EVT_MAX,
} esp_ble_mesh_rpr_server_cb_event_t;
@@ -474,6 +482,18 @@ typedef void (* esp_ble_mesh_rpr_server_cb_t)(esp_ble_mesh_rpr_server_cb_event_t
*/
esp_err_t esp_ble_mesh_register_rpr_server_callback(esp_ble_mesh_rpr_server_cb_t callback);
+/**
+ * @brief This function is called by Remote Provisioning Server to set the part of
+ * the device UUID to be compared before starting to remote provision.
+ *
+ * @param[in] match_val: Value to be compared with the part of the device UUID.
+ * @param[in] match_len: Length of the compared match value.
+ * @param[in] offset: Offset of the device UUID to be compared (based on zero).
+ *
+ * @return ESP_OK on success or error code otherwise.
+*/
+esp_err_t esp_ble_mesh_rpr_server_set_uuid_match(const uint8_t *match_val, uint8_t match_len, uint8_t offset);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c b/lib/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c
index 5e4437f4..e5200d7c 100644
--- a/lib/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c
+++ b/lib/bt/esp_ble_mesh/v1.1/btc/btc_ble_mesh_rpr_model.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -451,6 +451,61 @@ void btc_ble_mesh_rpr_client_cb_handler(btc_msg_t *msg)
#if CONFIG_BLE_MESH_RPR_SRV
/* Remote Provisioning Server model related functions */
+extern int bt_mesh_rpr_srv_scan_set_dev_uuid_match(uint8_t offset, uint8_t length,const uint8_t *match);
+
+void btc_ble_mesh_rpr_server_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
+{
+ btc_ble_mesh_rpr_server_args_t *dst = p_dest;
+ btc_ble_mesh_rpr_server_args_t *src = p_src;
+
+ if (!msg || !dst || !src) {
+ BT_ERR("%s, Invalid parameter", __func__);
+ return;
+ }
+
+ switch(msg->act) {
+ case BTC_BLE_MESH_ACT_RPR_SRV_SET_UUID_MATCH:
+ dst->set_uuid_match.match_val = bt_mesh_calloc(src->set_uuid_match.match_len);
+ if (dst->set_uuid_match.match_val) {
+ memcpy(dst->set_uuid_match.match_val, src->set_uuid_match.match_val, src->set_uuid_match.match_len);
+ dst->set_uuid_match.match_len = src->set_uuid_match.match_len;
+ dst->set_uuid_match.offset = src->set_uuid_match.offset;
+ } else {
+ BT_ERR("%s, Out of memory, act %d", __func__, msg->act);
+ }
+ bt_mesh_free(src->set_uuid_match.match_val);
+ break;
+ default:
+ BT_DBG("%s, Unknown act %d", __func__, msg->act);
+ break;
+ }
+
+ return;
+}
+
+void btc_ble_mesh_rpr_server_arg_deep_free(btc_msg_t *msg)
+{
+ btc_ble_mesh_rpr_server_args_t *arg = NULL;
+
+ if (!msg) {
+ BT_ERR("%s, Invalid parameter", __func__);
+ return;
+ }
+
+ arg = (btc_ble_mesh_rpr_server_args_t *)msg->arg;
+
+ switch(msg->act) {
+ case BTC_BLE_MESH_ACT_RPR_SRV_SET_UUID_MATCH:
+ if (arg->set_uuid_match.match_val) {
+ bt_mesh_free(arg->set_uuid_match.match_val);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return;
+}
static inline void btc_ble_mesh_rpr_server_cb_to_app(esp_ble_mesh_rpr_server_cb_event_t event,
esp_ble_mesh_rpr_server_cb_param_t *param)
@@ -522,6 +577,33 @@ void bt_mesh_rpr_server_cb_evt_to_btc(uint8_t event, const void *val, size_t len
btc_ble_mesh_rpr_server_cb(&cb_params, act);
}
+void btc_ble_mesh_rpr_server_call_handler(btc_msg_t *msg)
+{
+ esp_ble_mesh_rpr_server_cb_param_t cb = {0};
+ btc_ble_mesh_rpr_server_args_t *arg = NULL;
+
+ if (!msg) {
+ BT_ERR("%s, Invalid parameter", __func__);
+ return;
+ }
+
+ arg = (btc_ble_mesh_rpr_server_args_t *)msg->arg;
+
+ switch (msg->act) {
+ case BTC_BLE_MESH_ACT_RPR_SRV_SET_UUID_MATCH:
+ cb.set_uuid_match_comp.err_code = bt_mesh_rpr_srv_scan_set_dev_uuid_match(arg->set_uuid_match.offset,
+ arg->set_uuid_match.match_len,
+ arg->set_uuid_match.match_val);
+
+ btc_ble_mesh_rpr_server_cb(&cb, ESP_BLE_MESH_RPR_SERVER_SET_UUID_MATCH_COMP_EVT);
+ break;
+ default:
+ break;
+ }
+
+ btc_ble_mesh_rpr_server_arg_deep_free(msg);
+}
+
void btc_ble_mesh_rpr_server_cb_handler(btc_msg_t *msg)
{
esp_ble_mesh_rpr_server_cb_param_t *arg = NULL;
diff --git a/lib/bt/esp_ble_mesh/v1.1/btc/include/btc_ble_mesh_rpr_model.h b/lib/bt/esp_ble_mesh/v1.1/btc/include/btc_ble_mesh_rpr_model.h
index e5217782..5b78299a 100644
--- a/lib/bt/esp_ble_mesh/v1.1/btc/include/btc_ble_mesh_rpr_model.h
+++ b/lib/bt/esp_ble_mesh/v1.1/btc/include/btc_ble_mesh_rpr_model.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -65,6 +65,11 @@ void bt_mesh_rpr_client_cb_evt_to_btc(uint32_t opcode, uint8_t event,
const void *val, size_t len);
typedef enum {
+ BTC_BLE_MESH_ACT_RPR_SRV_SET_UUID_MATCH,
+ BTC_BLE_MESH_ACT_RPR_SRV_MAX,
+} btc_ble_mesh_rpr_server_act_t;
+
+typedef enum {
BTC_BLE_MESH_EVT_RPR_SERVER_SCAN_START,
BTC_BLE_MESH_EVT_RPR_SERVER_SCAN_STOP,
BTC_BLE_MESH_EVT_RPR_SERVER_EXT_SCAN_START,
@@ -72,9 +77,22 @@ typedef enum {
BTC_BLE_MESH_EVT_RPR_SERVER_LINK_OPEN,
BTC_BLE_MESH_EVT_RPR_SERVER_LINK_CLOSE,
BTC_BLE_MESH_EVT_RPR_SERVER_PROV_COMP,
+ BTC_BLE_MESH_EVT_RPR_SERVER_SET_UUID_MATCH_COMP,
BTC_BLE_MESH_EVT_RPR_SERVER_MAX,
} btc_ble_mesh_rpr_server_evt_t;
+typedef union {
+ struct {
+ uint8_t *match_val;
+ uint8_t match_len;
+ uint8_t offset;
+ } set_uuid_match;
+} btc_ble_mesh_rpr_server_args_t;
+
+void btc_ble_mesh_rpr_server_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
+void btc_ble_mesh_rpr_server_arg_deep_free(btc_msg_t *msg);
+
+void btc_ble_mesh_rpr_server_call_handler(btc_msg_t *msg);
void btc_ble_mesh_rpr_server_cb_handler(btc_msg_t *msg);
void bt_mesh_rpr_server_cb_evt_to_btc(uint8_t event, const void *val, size_t len);