diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 30e4ae4ad8..abb0326384 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -1335,8 +1335,8 @@ if BLE_MESH if BLE_MESH_PB_ADV config BLE_MESH_PBA_SAME_TIME int "Maximum number of PB-ADV running at the same time by provisioner" - default 10 - range 1 30 + default 2 + range 1 10 help This option specifies how many devices can be provisioned at the same time using PB-ADV. @@ -1345,7 +1345,7 @@ if BLE_MESH if BLE_MESH_PB_GATT config BLE_MESH_PBG_SAME_TIME int "Maximum number of PB-GATT running at the same time by provisioner" - default 4 + default 1 range 1 5 help This option specifies how many devices can be provisioned at the same @@ -1447,7 +1447,7 @@ if BLE_MESH config BLE_MESH_STORE_TIMEOUT int "Delay (in seconds) before storing anything persistently" range 0 1000000 - default 2 + default 0 help This value defines in seconds how soon any pending changes are actually written into persistent storage (flash) after a change occurs. @@ -1486,21 +1486,21 @@ if BLE_MESH config BLE_MESH_SUBNET_COUNT int "Maximum number of mesh subnets per network" - default 1 + default 3 range 1 4096 help This option specifies how many subnets a Mesh network can have at the same time. config BLE_MESH_APP_KEY_COUNT int "Maximum number of application keys per network" - default 1 + default 3 range 1 4096 help This option specifies how many application keys the device can store per network. config BLE_MESH_MODEL_KEY_COUNT int "Maximum number of application keys per model" - default 1 + default 3 range 1 4096 help This option specifies the maximum number of application keys to which each model @@ -1508,7 +1508,7 @@ if BLE_MESH config BLE_MESH_MODEL_GROUP_COUNT int "Maximum number of group address subscriptions per model" - default 1 + default 3 range 1 4096 help This option specifies the maximum number of addresses to which each model can @@ -1516,7 +1516,7 @@ if BLE_MESH config BLE_MESH_LABEL_COUNT int "Maximum number of Label UUIDs used for Virtual Addresses" - default 1 + default 3 range 0 4096 help This option specifies how many Label UUIDs can be stored. diff --git a/components/bt/ble_mesh/mesh_core/mesh_kernel.c b/components/bt/ble_mesh/mesh_core/mesh_kernel.c index eaa4492259..d1d1ca6670 100644 --- a/components/bt/ble_mesh/mesh_core/mesh_kernel.c +++ b/components/bt/ble_mesh/mesh_core/mesh_kernel.c @@ -113,18 +113,18 @@ void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler) if (!hash_map_has_key(bm_alarm_hash_map, (void *)work)) { alarm = osi_alarm_new("bt_mesh", bt_mesh_alarm_cb, (void *)work, 0); if (alarm == NULL) { - LOG_ERROR("%s, Unable to create alarm", __func__); + BT_ERR("%s, Unable to create alarm", __func__); return; } if (!hash_map_set(bm_alarm_hash_map, work, (void *)alarm)) { - LOG_ERROR("%s Unable to add the timer to hash map.", __func__); + BT_ERR("%s Unable to add the timer to hash map.", __func__); } } osi_mutex_unlock(&bm_alarm_lock); alarm = hash_map_get(bm_alarm_hash_map, work); if (alarm == NULL) { - LOG_WARN("%s, Unable to find expected alarm in hash map", __func__); + BT_WARN("%s, Unable to find expected alarm in hash map", __func__); return; } @@ -140,7 +140,7 @@ int k_delayed_work_submit(struct k_delayed_work *work, osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work); if (alarm == NULL) { - LOG_WARN("%s, Unable to find expected alarm in hash map", __func__); + BT_WARN("%s, Unable to find expected alarm in hash map", __func__); return -EINVAL; } @@ -156,7 +156,7 @@ int k_delayed_work_cancel(struct k_delayed_work *work) osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work); if (alarm == NULL) { - LOG_WARN("%s, Unable to find expected alarm in hash map", __func__); + BT_WARN("%s, Unable to find expected alarm in hash map", __func__); return -EINVAL; } @@ -171,7 +171,7 @@ int k_delayed_work_free(struct k_delayed_work *work) osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, work); if (alarm == NULL) { - LOG_WARN("%s Unable to find expected alarm in hash map", __func__); + BT_WARN("%s Unable to find expected alarm in hash map", __func__); return -EINVAL; } @@ -185,7 +185,7 @@ s32_t k_delayed_work_remaining_get(struct k_delayed_work *work) osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work); if (alarm == NULL) { - LOG_WARN("%s Unable to find expected alarm in hash map", __func__); + BT_WARN("%s Unable to find expected alarm in hash map", __func__); return 0; } diff --git a/components/bt/ble_mesh/mesh_core/net.c b/components/bt/ble_mesh/mesh_core/net.c index cc0ba7ece1..d2b43a0918 100644 --- a/components/bt/ble_mesh/mesh_core/net.c +++ b/components/bt/ble_mesh/mesh_core/net.c @@ -1255,6 +1255,15 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, transmit = bt_mesh_relay_retransmit_get(); } else { transmit = bt_mesh_net_transmit_get(); + if (rx->net_if == BLE_MESH_NET_IF_PROXY && + transmit < BLE_MESH_TRANSMIT(5, 20)) { + /** + * Add this in case EspBleMesh APP just send a message once, and + * the Proxy Node will send this message using advertising bearer + * with duration not less than 180ms. + */ + transmit = BLE_MESH_TRANSMIT(5, 20); + } } buf = bt_mesh_adv_create(BLE_MESH_ADV_DATA, diff --git a/components/bt/ble_mesh/mesh_core/prov.c b/components/bt/ble_mesh/mesh_core/prov.c index 5640fe98cf..8d41e5e8a1 100644 --- a/components/bt/ble_mesh/mesh_core/prov.c +++ b/components/bt/ble_mesh/mesh_core/prov.c @@ -136,6 +136,7 @@ struct prov_link { #if defined(CONFIG_BLE_MESH_PB_ADV) u32_t id; /* Link ID */ + u8_t tx_pdu_type; /* The previously transmitted Provisioning PDU type */ struct { u8_t id; /* Transaction ID */ @@ -171,12 +172,14 @@ struct prov_rx { u8_t gpc; }; -#define RETRANSMIT_TIMEOUT K_MSEC(500) #define BUF_TIMEOUT K_MSEC(400) + #if defined(CONFIG_BLE_MESH_FAST_PROV) +#define RETRANSMIT_TIMEOUT K_MSEC(360) #define TRANSACTION_TIMEOUT K_SECONDS(3) #define PROVISION_TIMEOUT K_SECONDS(6) #else +#define RETRANSMIT_TIMEOUT K_MSEC(500) #define TRANSACTION_TIMEOUT K_SECONDS(30) #define PROVISION_TIMEOUT K_SECONDS(60) #endif /* CONFIG_BLE_MESH_FAST_PROV */ @@ -412,7 +415,7 @@ static int prov_send_adv(struct net_buf_simple *msg) struct net_buf *start, *buf; u8_t seg_len, seg_id; u8_t xact_id; - u8_t type; + s32_t timeout = PROVISION_TIMEOUT; BT_DBG("%s, len %u: %s", __func__, msg->len, bt_hex(msg->data, msg->len)); @@ -432,8 +435,8 @@ static int prov_send_adv(struct net_buf_simple *msg) net_buf_add_u8(start, bt_mesh_fcs_calc(msg->data, msg->len)); link.tx.buf[0] = start; - /* Change by Espressif, get message type */ - type = msg->data[0]; + /* Changed by Espressif, get message type */ + link.tx_pdu_type = msg->data[0]; seg_len = MIN(msg->len, START_PAYLOAD_MAX); BT_DBG("seg 0 len %u: %s", seg_len, bt_hex(msg->data, seg_len)); @@ -476,10 +479,13 @@ static int prov_send_adv(struct net_buf_simple *msg) if (bt_mesh_atomic_test_and_clear_bit(link.flags, TIMEOUT_START)) { k_delayed_work_cancel(&link.timeout); } - if (type != PROV_COMPLETE && type != PROV_FAILED) { - if (!bt_mesh_atomic_test_and_set_bit(link.flags, TIMEOUT_START)) { - k_delayed_work_submit(&link.timeout, PROVISION_TIMEOUT); - } +#if defined(CONFIG_BLE_MESH_FAST_PROV) + if (link.tx_pdu_type >= PROV_COMPLETE) { + timeout = K_SECONDS(60); + } +#endif + if (!bt_mesh_atomic_test_and_set_bit(link.flags, TIMEOUT_START)) { + k_delayed_work_submit(&link.timeout, timeout); } return 0; @@ -1243,6 +1249,7 @@ static void prov_timeout(struct k_work *work) #if defined(CONFIG_BLE_MESH_PB_ADV) static void prov_retransmit(struct k_work *work) { + s64_t timeout = TRANSACTION_TIMEOUT; int i; BT_DBG("%s", __func__); @@ -1252,8 +1259,14 @@ static void prov_retransmit(struct k_work *work) return; } - if (k_uptime_get() - link.tx.start > TRANSACTION_TIMEOUT) { - BT_WARN("Giving up transaction"); +#if defined(CONFIG_BLE_MESH_FAST_PROV) + /* When Provisioning Failed PDU is sent, 3s may be used here. */ + if (link.tx_pdu_type >= PROV_COMPLETE) { + timeout = K_SECONDS(30); + } +#endif + if (k_uptime_get() - link.tx.start > timeout) { + BT_WARN("Node timeout, giving up transaction"); reset_link(); return; } @@ -1290,7 +1303,14 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf) } if (bt_mesh_atomic_test_bit(link.flags, LINK_ACTIVE)) { - BT_WARN("Ignoring bearer open: link already active"); + /* Send another link ack if the provisioner missed the last */ + if (link.id == rx->link_id && link.expect == PROV_INVITE) { + BT_DBG("Resending link ack"); + bearer_ctl_send(LINK_ACK, NULL, 0); + } else { + BT_WARN("Ignoring bearer open: link already active"); + } + return; } @@ -1495,7 +1515,7 @@ static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf) if (link.rx.buf->len > link.rx.buf->size) { BT_ERR("%s, Too large provisioning PDU (%u bytes)", __func__, link.rx.buf->len); - close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED); + // close_link(PROV_ERR_NVAL_FMT, CLOSE_REASON_FAILED); return; } diff --git a/components/bt/ble_mesh/mesh_core/provisioner_prov.c b/components/bt/ble_mesh/mesh_core/provisioner_prov.c index 4569c02440..8300f9412e 100644 --- a/components/bt/ble_mesh/mesh_core/provisioner_prov.c +++ b/components/bt/ble_mesh/mesh_core/provisioner_prov.c @@ -15,9 +15,9 @@ #include #include -#include "stack/bt_types.h" #include "sdkconfig.h" #include "osi/allocator.h" +#include "osi/mutex.h" #include "mesh_main.h" #include "mesh_trace.h" @@ -168,10 +168,11 @@ struct prov_link { #if defined(CONFIG_BLE_MESH_PB_ADV) bool linking; /* Linking is being establishing */ - u16_t link_close; /* Link close been sent flag */ + u16_t send_link_close; /* Link close is being sent flag */ u32_t link_id; /* Link ID */ u8_t pending_ack; /* Decide which transaction id ack is pending */ u8_t expect_ack_for; /* Transaction ACK expected for provisioning pdu */ + u8_t tx_pdu_type; /* The current transmitted Provisioning PDU type */ struct { u8_t trans_id; /* Transaction ID */ @@ -197,6 +198,7 @@ struct prov_link { struct k_delayed_work retransmit; } tx; #endif + /** Provision timeout timer. Spec P259 says: The provisioning protocol * shall have a minimum timeout of 60 seconds that is reset each time * a provisioning protocol PDU is sent or received. @@ -204,6 +206,12 @@ struct prov_link { struct k_delayed_work timeout; }; +/* Number of devices can be provisioned at the same time equals to PB-ADV + PB-GATT */ +#define BLE_MESH_PROV_SAME_TIME \ + (CONFIG_BLE_MESH_PBA_SAME_TIME + CONFIG_BLE_MESH_PBG_SAME_TIME) + +static struct prov_link link[BLE_MESH_PROV_SAME_TIME]; + struct prov_rx { u32_t link_id; u8_t xact_id; @@ -255,6 +263,12 @@ struct prov_ctx_t { /* Indicate when received uuid_match adv_pkts, can provision it at once */ bool prov_after_match; + /* Mutex used to protect the PB-ADV procedure */ + osi_mutex_t pb_adv_lock; + + /* Mutex used to protect the PB-GATT procedure */ + osi_mutex_t pb_gatt_lock; + /** This structure is used to store the information of the device which * provisioner has successfully sent provisioning data to. In this * structure, we don't care if the device is currently in the mesh @@ -268,9 +282,11 @@ struct prov_ctx_t { } already_prov[BLE_MESH_ALREADY_PROV_NUM]; }; +static struct prov_ctx_t prov_ctx; + struct prov_node_info { bool provisioned; /* device provisioned flag */ - bt_mesh_addr_t addr; /* device address */ + bt_mesh_addr_t addr; /* device address */ u8_t uuid[16]; /* node uuid */ u16_t oob_info; /* oob info contained in adv pkt */ u8_t element_num; /* element contained in this node */ @@ -280,6 +296,8 @@ struct prov_node_info { u32_t iv_index; /* IV Index */ }; +static struct prov_node_info prov_nodes[CONFIG_BLE_MESH_MAX_PROV_NODES]; + struct unprov_dev_queue { bt_mesh_addr_t addr; u8_t uuid[16]; @@ -296,12 +314,14 @@ struct unprov_dev_queue { static unprov_adv_pkt_cb_t notify_unprov_adv_pkt_cb; -#define RETRANSMIT_TIMEOUT K_MSEC(500) #define BUF_TIMEOUT K_MSEC(400) + #if defined(CONFIG_BLE_MESH_FAST_PROV) +#define RETRANSMIT_TIMEOUT K_MSEC(360) #define TRANSACTION_TIMEOUT K_SECONDS(3) #define PROVISION_TIMEOUT K_SECONDS(6) #else +#define RETRANSMIT_TIMEOUT K_MSEC(500) #define TRANSACTION_TIMEOUT K_SECONDS(30) #define PROVISION_TIMEOUT K_SECONDS(60) #endif /* CONFIG_BLE_MESH_FAST_PROV */ @@ -314,19 +334,10 @@ static unprov_adv_pkt_cb_t notify_unprov_adv_pkt_cb; #define PROV_BUF(len) NET_BUF_SIMPLE(PROV_BUF_HEADROOM + len) -/* Number of devices can be provisioned at the same time using PB-GATT + PB-ADV */ -#define BLE_MESH_PROV_SAME_TIME (CONFIG_BLE_MESH_PBA_SAME_TIME + CONFIG_BLE_MESH_PBG_SAME_TIME) - -static struct prov_link link[BLE_MESH_PROV_SAME_TIME]; - static const struct bt_mesh_prov *prov; -static struct prov_ctx_t prov_ctx; - -static struct prov_node_info prov_nodes[CONFIG_BLE_MESH_MAX_PROV_NODES]; - #if defined(CONFIG_BLE_MESH_PB_ADV) -static void send_link_open(void); +static void send_link_open(int i); #endif static void prov_gen_dh_key(int i); @@ -351,15 +362,14 @@ static struct adv_buf_t { } /* Fast provisioning uses this structure for provisioning data */ -struct bt_mesh_fast_prov { +static struct bt_mesh_fast_prov_info { u16_t net_idx; const u8_t *net_key; u8_t flags; u32_t iv_index; u16_t unicast_addr_min; u16_t unicast_addr_max; -}; -static struct bt_mesh_fast_prov fast_prov; +} fast_prov_info; static bool fast_prov_flag; #define FAST_PROV_FLAG_GET() fast_prov_flag @@ -448,7 +458,7 @@ static int provisioner_dev_find(const bt_mesh_addr_t *addr, const u8_t uuid[16], comp = memcmp(addr->val, zero, BLE_MESH_ADDR_LEN); } - if ((!uuid && (!addr || (comp == 0) || (addr->type > BLE_ADDR_RANDOM))) || !index) { + if ((!uuid && (!addr || (comp == 0) || (addr->type > BLE_MESH_ADDR_RANDOM))) || !index) { return -EINVAL; } @@ -465,7 +475,7 @@ static int provisioner_dev_find(const bt_mesh_addr_t *addr, const u8_t uuid[16], } } - if (addr && comp && (addr->type <= BLE_ADDR_RANDOM)) { + if (addr && comp && (addr->type <= BLE_MESH_ADDR_RANDOM)) { for (j = 0; j < ARRAY_SIZE(unprov_dev); j++) { if (!memcmp(unprov_dev[j].addr.val, addr->val, BLE_MESH_ADDR_LEN) && unprov_dev[j].addr.type == addr->type) { @@ -495,24 +505,60 @@ static int provisioner_dev_find(const bt_mesh_addr_t *addr, const u8_t uuid[16], return 0; } -static int provisioner_dev_uuid_match(const u8_t uuid[16]) +static bool is_unprov_dev_being_provision(const u8_t uuid[16]) { - if (!uuid) { - BT_ERR("%s, Invalid parameter", __func__); - return -EINVAL; - } + int i; - if (prov_ctx.match_length && prov_ctx.match_value) { - if (memcmp(uuid + prov_ctx.match_offset, - prov_ctx.match_value, prov_ctx.match_length)) { - return -EAGAIN; +#if defined(CONFIG_BLE_MESH_FAST_PROV) + /** + * During Fast Provisioning test, we found that if a device has already being + * provisioned, there is still a chance that the Provisioner can receive the + * Unprovisioned Device Beacon from the device (because the device will stop + * Unprovisioned Device Beacon when Transaction ACK for Provisioning Complete + * is received). So in Fast Provisioning the Provisioner should ignore this. + */ + for (i = 0; i < ARRAY_SIZE(prov_nodes); i++) { + if (prov_nodes[i].provisioned) { + if (!memcmp(prov_nodes[i].uuid, uuid, 16)) { + BT_WARN("Device has already been provisioned"); + return -EALREADY; + } + } + } +#endif + + for (i = 0; i < BLE_MESH_PROV_SAME_TIME; i++) { +#if defined(CONFIG_BLE_MESH_PB_ADV) && defined(CONFIG_BLE_MESH_PB_GATT) + if (link[i].linking || link[i].connecting || + bt_mesh_atomic_test_bit(link[i].flags, LINK_ACTIVE)) { +#elif defined(CONFIG_BLE_MESH_PB_ADV) && !defined(CONFIG_BLE_MESH_PB_GATT) + if (link[i].linking || bt_mesh_atomic_test_bit(link[i].flags, LINK_ACTIVE)) { +#else + if (link[i].connecting || bt_mesh_atomic_test_bit(link[i].flags, LINK_ACTIVE)) { +#endif + if (!memcmp(link[i].uuid, uuid, 16)) { + BT_DBG("%s, Device is being provisioned", __func__); + return true; + } } } - return 0; + return false; } -static int provisioner_check_device_uuid(const u8_t uuid[16]) +static bool is_unprov_dev_uuid_match(const u8_t uuid[16]) +{ + if (prov_ctx.match_length && prov_ctx.match_value) { + if (memcmp(uuid + prov_ctx.match_offset, + prov_ctx.match_value, prov_ctx.match_length)) { + return false; + } + } + + return true; +} + +static int provisioner_check_unprov_dev_info(const u8_t uuid[16]) { int i; @@ -521,29 +567,20 @@ static int provisioner_check_device_uuid(const u8_t uuid[16]) return -EINVAL; } + /* Check if the device uuid matches configured value */ + if (is_unprov_dev_uuid_match(uuid) == false) { + BT_DBG("%s, Device uuid is not matched", __func__); + return -EIO; + } + /* Check if this device is currently being provisioned. * According to Zephyr's device code, if we connect with * one device and start to provision it, we may still can * receive the connectable prov adv pkt from this device. * Here we check both PB-GATT and PB-ADV link status. */ - for (i = 0; i < BLE_MESH_PROV_SAME_TIME; i++) { -#if defined(CONFIG_BLE_MESH_PB_GATT) - if (link[i].connecting || bt_mesh_atomic_test_bit(link[i].flags, LINK_ACTIVE)) { -#else - if (link[i].linking || bt_mesh_atomic_test_bit(link[i].flags, LINK_ACTIVE)) { -#endif - if (!memcmp(link[i].uuid, uuid, 16)) { - BT_DBG("%s, Device is being provisioned", __func__); - return -EALREADY; - } - } - } - - /* Check if the device uuid matches configured value */ - if (provisioner_dev_uuid_match(uuid)) { - BT_DBG("%s, Device uuid failed to match", __func__); - return -EIO; + if (is_unprov_dev_being_provision(uuid)) { + return -EALREADY; } /* Check if the device has already been provisioned */ @@ -570,74 +607,95 @@ static int provisioner_check_device_uuid(const u8_t uuid[16]) return 0; } -static int provisioner_start_prov_device(bt_mesh_prov_bearer_t bearer, const u8_t uuid[16], +#if defined(CONFIG_BLE_MESH_PB_ADV) +static int provisioner_start_prov_pb_adv(const u8_t uuid[16], const bt_mesh_addr_t *addr, u16_t oob_info) { u8_t zero[6] = {0}; int addr_cmp, i; - if ((bearer != BLE_MESH_PROV_ADV && bearer != BLE_MESH_PROV_GATT) || !uuid || !addr) { + if (!uuid || !addr) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; } - addr_cmp = memcmp(addr->val, zero, BLE_MESH_ADDR_LEN); + osi_mutex_lock(&prov_ctx.pb_adv_lock, OSI_MUTEX_MAX_TIMEOUT); - if (bearer == BLE_MESH_PROV_ADV) { -#if defined(CONFIG_BLE_MESH_PB_ADV) - for (i = 0; i < CONFIG_BLE_MESH_PBA_SAME_TIME; i++) { - if (!bt_mesh_atomic_test_bit(link[i].flags, LINK_ACTIVE) && !link[i].linking) { - memcpy(link[i].uuid, uuid, 16); - link[i].oob_info = oob_info; - if (addr_cmp && (addr->type <= BLE_ADDR_RANDOM)) { - link[i].addr.type = addr->type; - memcpy(link[i].addr.val, addr->val, BLE_MESH_ADDR_LEN); - } - prov_set_pb_index(i); - send_link_open(); - /* If Provisioner sets LINK_ACTIVE flag once Link Open is sent, here - * we may not need to use linking flag (like PB-GATT connecting) to - * prevent the stored device info (UUID, oob_info) being replaced by - * other received unprovisioned device beacons. - * But if Provisioner sets LINK_ACTIVE flag after Link ACK is received, - * we need to use linking flag to prevent device info being replaced. - * Currently we set LINK_ACTIVE flag after sending Link Open. - */ - link[i].linking = true; - if (prov->prov_link_open) { - prov->prov_link_open(BLE_MESH_PROV_ADV); - } - return 0; - } - } -#endif - } else { -#if defined(CONFIG_BLE_MESH_PB_GATT) - for (i = CONFIG_BLE_MESH_PBA_SAME_TIME; i < BLE_MESH_PROV_SAME_TIME; i++) { - if (!bt_mesh_atomic_test_bit(link[i].flags, LINK_ACTIVE) && !link[i].connecting) { - memcpy(link[i].uuid, uuid, 16); - link[i].oob_info = oob_info; - if (addr_cmp && (addr->type <= BLE_ADDR_RANDOM)) { - link[i].addr.type = addr->type; - memcpy(link[i].addr.val, addr->val, BLE_MESH_ADDR_LEN); - } - if (bt_mesh_gattc_conn_create(&link[i].addr, BLE_MESH_UUID_MESH_PROV_VAL)) { - memset(link[i].uuid, 0, 16); - link[i].oob_info = 0x0; - memset(&link[i].addr, 0, sizeof(bt_mesh_addr_t)); - return -EIO; - } - /* If creating connection successfully, set connecting flag to 1 */ - link[i].connecting = true; - return 0; - } - } -#endif + if (is_unprov_dev_being_provision(uuid)) { + osi_mutex_unlock(&prov_ctx.pb_adv_lock); + return -EALREADY; } - BT_ERR("%s, No link is available", __func__); + addr_cmp = memcmp(addr->val, zero, BLE_MESH_ADDR_LEN); + + for (i = 0; i < CONFIG_BLE_MESH_PBA_SAME_TIME; i++) { + if (!bt_mesh_atomic_test_bit(link[i].flags, LINK_ACTIVE) && !link[i].linking) { + memcpy(link[i].uuid, uuid, 16); + link[i].oob_info = oob_info; + if (addr_cmp && (addr->type <= BLE_MESH_ADDR_RANDOM)) { + link[i].addr.type = addr->type; + memcpy(link[i].addr.val, addr->val, BLE_MESH_ADDR_LEN); + } + send_link_open(i); + osi_mutex_unlock(&prov_ctx.pb_adv_lock); + return 0; + } + } + + BT_ERR("%s, No PB-ADV link is available", __func__); + osi_mutex_unlock(&prov_ctx.pb_adv_lock); return -ENOMEM; } +#endif /* CONFIG_BLE_MESH_PB_ADV */ + +#if defined(CONFIG_BLE_MESH_PB_GATT) +static int provisioner_start_prov_pb_gatt(const u8_t uuid[16], + const bt_mesh_addr_t *addr, u16_t oob_info) +{ + u8_t zero[6] = {0}; + int addr_cmp, i; + + if (!uuid || !addr) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + osi_mutex_lock(&prov_ctx.pb_gatt_lock, OSI_MUTEX_MAX_TIMEOUT); + + if (is_unprov_dev_being_provision(uuid)) { + osi_mutex_unlock(&prov_ctx.pb_gatt_lock); + return -EALREADY; + } + + addr_cmp = memcmp(addr->val, zero, BLE_MESH_ADDR_LEN); + + for (i = CONFIG_BLE_MESH_PBA_SAME_TIME; i < BLE_MESH_PROV_SAME_TIME; i++) { + if (!link[i].connecting && !bt_mesh_atomic_test_bit(link[i].flags, LINK_ACTIVE)) { + memcpy(link[i].uuid, uuid, 16); + link[i].oob_info = oob_info; + if (addr_cmp && (addr->type <= BLE_MESH_ADDR_RANDOM)) { + link[i].addr.type = addr->type; + memcpy(link[i].addr.val, addr->val, BLE_MESH_ADDR_LEN); + } + if (bt_mesh_gattc_conn_create(&link[i].addr, BLE_MESH_UUID_MESH_PROV_VAL)) { + memset(link[i].uuid, 0, 16); + link[i].oob_info = 0x0; + memset(&link[i].addr, 0, sizeof(bt_mesh_addr_t)); + osi_mutex_unlock(&prov_ctx.pb_gatt_lock); + return -EIO; + } + /* If creating connection successfully, set connecting flag to 1 */ + link[i].connecting = true; + osi_mutex_unlock(&prov_ctx.pb_gatt_lock); + return 0; + } + } + + BT_ERR("%s, No PB-GATT link is available", __func__); + osi_mutex_unlock(&prov_ctx.pb_gatt_lock); + return -ENOMEM; +} +#endif /* CONFIG_BLE_MESH_PB_GATT */ int bt_mesh_provisioner_add_unprov_dev(struct bt_mesh_unprov_dev_add *add_dev, u8_t flags) { @@ -655,7 +713,7 @@ int bt_mesh_provisioner_add_unprov_dev(struct bt_mesh_unprov_dev_add *add_dev, u uuid_cmp = memcmp(add_dev->uuid, zero, 16); if (add_dev->bearer == 0x0 || ((uuid_cmp == 0) && - ((addr_cmp == 0) || add_dev->addr_type > BLE_ADDR_RANDOM))) { + ((addr_cmp == 0) || add_dev->addr_type > BLE_MESH_ADDR_RANDOM))) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; } @@ -672,7 +730,7 @@ int bt_mesh_provisioner_add_unprov_dev(struct bt_mesh_unprov_dev_add *add_dev, u } if ((add_dev->bearer & BLE_MESH_PROV_GATT) && (flags & START_PROV_NOW) && - ((addr_cmp == 0) || add_dev->addr_type > BLE_ADDR_RANDOM)) { + ((addr_cmp == 0) || add_dev->addr_type > BLE_MESH_ADDR_RANDOM)) { BT_ERR("%s, Invalid device address for PB-GATT", __func__); return -EINVAL; } @@ -712,7 +770,7 @@ int bt_mesh_provisioner_add_unprov_dev(struct bt_mesh_unprov_dev_add *add_dev, u if (unprov_dev[i].bearer) { continue; } - if (addr_cmp && (add_dev->addr_type <= BLE_ADDR_RANDOM)) { + if (addr_cmp && (add_dev->addr_type <= BLE_MESH_ADDR_RANDOM)) { unprov_dev[i].addr.type = add_dev->addr_type; memcpy(unprov_dev[i].addr.val, add_dev->addr, BLE_MESH_ADDR_LEN); } @@ -728,7 +786,7 @@ int bt_mesh_provisioner_add_unprov_dev(struct bt_mesh_unprov_dev_add *add_dev, u for (i = 0; i < ARRAY_SIZE(unprov_dev); i++) { if (unprov_dev[i].flags & FLUSHABLE_DEV) { memset(&unprov_dev[i], 0, sizeof(struct unprov_dev_queue)); - if (addr_cmp && (add_dev->addr_type <= BLE_ADDR_RANDOM)) { + if (addr_cmp && (add_dev->addr_type <= BLE_MESH_ADDR_RANDOM)) { unprov_dev[i].addr.type = add_dev->addr_type; memcpy(unprov_dev[i].addr.val, add_dev->addr, BLE_MESH_ADDR_LEN); } @@ -756,7 +814,7 @@ start: return -EIO; } - if ((err = provisioner_check_device_uuid(add_dev->uuid))) { + if ((err = provisioner_check_unprov_dev_info(add_dev->uuid))) { return err; } @@ -766,7 +824,7 @@ start: BT_WARN("%s, Current PB-ADV links reach max limit", __func__); return -EIO; } - if ((err = provisioner_start_prov_device(BLE_MESH_PROV_ADV, + if ((err = provisioner_start_prov_pb_adv( add_dev->uuid, &add_addr, add_dev->oob_info))) { return err; } @@ -777,7 +835,7 @@ start: BT_WARN("%s, Current PB-GATT links reach max limit", __func__); return -EIO; } - if ((err = provisioner_start_prov_device(BLE_MESH_PROV_GATT, + if ((err = provisioner_start_prov_pb_gatt( add_dev->uuid, &add_addr, add_dev->oob_info))) { return err; } @@ -812,7 +870,7 @@ int bt_mesh_provisioner_delete_device(struct bt_mesh_device_delete *del_dev) addr_cmp = memcmp(del_dev->addr, zero, BLE_MESH_ADDR_LEN); uuid_cmp = memcmp(del_dev->uuid, zero, 16); - if ((uuid_cmp == 0) && ((addr_cmp == 0) || del_dev->addr_type > BLE_ADDR_RANDOM)) { + if ((uuid_cmp == 0) && ((addr_cmp == 0) || del_dev->addr_type > BLE_MESH_ADDR_RANDOM)) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; } @@ -830,7 +888,7 @@ int bt_mesh_provisioner_delete_device(struct bt_mesh_device_delete *del_dev) /* Second: find if the device is being provisioned */ for (i = 0; i < ARRAY_SIZE(link); i++) { - if (addr_cmp && (del_dev->addr_type <= BLE_ADDR_RANDOM)) { + if (addr_cmp && (del_dev->addr_type <= BLE_MESH_ADDR_RANDOM)) { if (!memcmp(link[i].addr.val, del_dev->addr, BLE_MESH_ADDR_LEN) && link[i].addr.type == del_dev->addr_type) { addr_match = true; @@ -849,7 +907,7 @@ int bt_mesh_provisioner_delete_device(struct bt_mesh_device_delete *del_dev) /* Third: find if the device is been provisioned */ for (i = 0; i < ARRAY_SIZE(prov_nodes); i++) { - if (addr_cmp && (del_dev->addr_type <= BLE_ADDR_RANDOM)) { + if (addr_cmp && (del_dev->addr_type <= BLE_MESH_ADDR_RANDOM)) { if (!memcmp(prov_nodes[i].addr.val, del_dev->addr, BLE_MESH_ADDR_LEN) && prov_nodes[i].addr.type == del_dev->addr_type) { addr_match = true; @@ -943,8 +1001,8 @@ void provisioner_set_fast_prov_flag(bool flag) u8_t provisioner_set_fast_prov_net_idx(const u8_t *net_key, u16_t net_idx) { - fast_prov.net_idx = net_idx; - fast_prov.net_key = net_key; + fast_prov_info.net_idx = net_idx; + fast_prov_info.net_key = net_key; if (!net_key) { BT_WARN("%s, Wait for NetKey for fast provisioning", __func__); @@ -956,7 +1014,7 @@ u8_t provisioner_set_fast_prov_net_idx(const u8_t *net_key, u16_t net_idx) u16_t provisioner_get_fast_prov_net_idx(void) { - return fast_prov.net_idx; + return fast_prov_info.net_idx; } u8_t bt_mesh_set_fast_prov_unicast_addr_range(u16_t min, u16_t max) @@ -971,15 +1029,15 @@ u8_t bt_mesh_set_fast_prov_unicast_addr_range(u16_t min, u16_t max) return 0x02; /* status: min is bigger than max */ } - if (min <= fast_prov.unicast_addr_max) { + if (min <= fast_prov_info.unicast_addr_max) { BT_ERR("%s, Address overlap", __func__); return 0x03; /* status: address overlaps with current value */ } - fast_prov.unicast_addr_min = min; - fast_prov.unicast_addr_max = max; + fast_prov_info.unicast_addr_min = min; + fast_prov_info.unicast_addr_max = max; - prov_ctx.current_addr = fast_prov.unicast_addr_min; + prov_ctx.current_addr = fast_prov_info.unicast_addr_min; return 0x0; /* status: success */ } @@ -987,8 +1045,8 @@ u8_t bt_mesh_set_fast_prov_unicast_addr_range(u16_t min, u16_t max) void bt_mesh_set_fast_prov_flags_iv_index(u8_t flags, u32_t iv_index) { /* BIT0: Key Refreash flag, BIT1: IV Update flag */ - fast_prov.flags = flags & BIT_MASK(2); - fast_prov.iv_index = iv_index; + fast_prov_info.flags = flags & BIT_MASK(2); + fast_prov_info.iv_index = iv_index; } #if defined(CONFIG_BLE_MESH_PB_ADV) @@ -1207,16 +1265,16 @@ static int bearer_ctl_send(int i, u8_t op, void *data, u8_t data_len) */ if (op == LINK_CLOSE) { u8_t reason = *(u8_t *)data; - link[i].link_close = (reason << 8 | BIT(0)); + link[i].send_link_close = ((reason & BIT_MASK(2)) << 1) | BIT(0); link[i].tx.trans_id = 0; } return 0; } -static void send_link_open(void) +static void send_link_open(int i) { - int i = prov_get_pb_index(), j; + int j; /** Generate link ID, and may need to check if this id is * currently being used, which may will not happen ever. @@ -1244,9 +1302,23 @@ static void send_link_open(void) bearer_ctl_send(i, LINK_OPEN, link[i].uuid, 16); - /* Set LINK_ACTIVE just to be in compatibility with current Zephyr code */ + /* If Provisioner sets LINK_ACTIVE flag once Link Open is sent, we have + * no need to use linking flag (like PB-GATT connecting) to prevent the + * stored device info (UUID, oob_info) being replaced by other received + * unprovisioned device beacons. + * But if Provisioner sets LINK_ACTIVE flag after Link ACK is received, + * we need to use linking flag to prevent device info being replaced. + * Currently we set LINK_ACTIVE flag after sending Link Open. + */ + link[i].linking = true; + + /* Set LINK_ACTIVE just to be in compatibility with current Zephyr code */ bt_mesh_atomic_set_bit(link[i].flags, LINK_ACTIVE); + if (prov->prov_link_open) { + prov->prov_link_open(BLE_MESH_PROV_ADV); + } + prov_ctx.pba_count++; } @@ -1265,11 +1337,10 @@ static inline u8_t next_transaction_id(void) { int i = prov_get_pb_index(); - if (link[i].tx.trans_id < 0x7F) { - return link[i].tx.trans_id++; + if (link[i].tx.trans_id > 0x7F) { + link[i].tx.trans_id = 0x0; } - - return 0x0; + return link[i].tx.trans_id++; } static int prov_send_adv(struct net_buf_simple *msg) @@ -1278,6 +1349,7 @@ static int prov_send_adv(struct net_buf_simple *msg) u8_t seg_len, seg_id; u8_t xact_id; int i = prov_get_pb_index(); + s32_t timeout = PROVISION_TIMEOUT; BT_DBG("%s, len %u: %s", __func__, msg->len, bt_hex(msg->data, msg->len)); @@ -1297,6 +1369,8 @@ static int prov_send_adv(struct net_buf_simple *msg) net_buf_add_u8(start, bt_mesh_fcs_calc(msg->data, msg->len)); link[i].tx.buf[0] = start; + /* Changed by Espressif, get message type */ + link[i].tx_pdu_type = msg->data[0]; seg_len = MIN(msg->len, START_PAYLOAD_MAX); BT_DBG("seg 0 len %u: %s", seg_len, bt_hex(msg->data, seg_len)); @@ -1333,8 +1407,13 @@ static int prov_send_adv(struct net_buf_simple *msg) send_reliable(i); +#if defined(CONFIG_BLE_MESH_FAST_PROV) + if (link[i].tx_pdu_type >= PROV_DATA) { + timeout = K_SECONDS(60); + } +#endif if (!bt_mesh_atomic_test_and_set_bit(link[i].flags, TIMEOUT_START)) { - k_delayed_work_submit(&link[i].timeout, PROVISION_TIMEOUT); + k_delayed_work_submit(&link[i].timeout, timeout); } return 0; @@ -1816,36 +1895,38 @@ int bt_mesh_prov_set_oob_input_data(u8_t *val, u8_t link_idx, bool num_flag) return 0; } -// int bt_mesh_prov_set_oob_output_data(u8_t *num, u8_t size, bool num_flag, u8_t link_idx) -// { -// /** This function should be called in the prov_output_num -// * callback, after the data has been output by provisioner. -// * Parameter size is used to indicate the length of data -// * indicated by Pointer num, for example, if provisioner -// * output data is 12345678(decimal), the data in auth value -// * will be 0xBC614E. -// * Parameter num_flag is used to indicate whether the value -// * output by provisioner is number or string. -// */ -// if (!link[link_idx].auth) { -// BT_ERR("%s, link auth is NULL", __func__); -// return -EINVAL; -// } +#if 0 +int bt_mesh_prov_set_oob_output_data(u8_t *num, u8_t size, bool num_flag, u8_t link_idx) +{ + /** This function should be called in the prov_output_num + * callback, after the data has been output by provisioner. + * Parameter size is used to indicate the length of data + * indicated by Pointer num, for example, if provisioner + * output data is 12345678(decimal), the data in auth value + * will be 0xBC614E. + * Parameter num_flag is used to indicate whether the value + * output by provisioner is number or string. + */ + if (!link[link_idx].auth) { + BT_ERR("%s, link auth is NULL", __func__); + return -EINVAL; + } -// if (num_flag) { -// /* Provisioner output number */ -// memset(link[link_idx].auth, 0, 16); -// memcpy(link[link_idx].auth + 16 - size, num, size); -// } else { -// /* Provisioner output string */ -// memset(link[link_idx].auth, 0, 16); -// memcpy(link[link_idx].auth, num, size); -// } + if (num_flag) { + /* Provisioner output number */ + memset(link[link_idx].auth, 0, 16); + memcpy(link[link_idx].auth + 16 - size, num, size); + } else { + /* Provisioner output string */ + memset(link[link_idx].auth, 0, 16); + memcpy(link[link_idx].auth, num, size); + } -// link[link_idx].expect = PROV_INPUT_COMPLETE; + link[link_idx].expect = PROV_INPUT_COMPLETE; -// return 0; -// } + return 0; +} +#endif int bt_mesh_prov_read_oob_pub_key(u8_t link_idx, u8_t pub_key_x[32], u8_t pub_key_y[32]) { @@ -2106,15 +2187,15 @@ static void send_prov_data(void) * subnet will the device be provisioned later. */ if (FAST_PROV_FLAG_GET()) { - netkey = fast_prov.net_key; + netkey = fast_prov_info.net_key; if (!netkey) { BT_ERR("%s, Failed to get NetKey for fast provisioning", __func__); goto fail; } memcpy(pdu, netkey, 16); - sys_put_be16(fast_prov.net_idx, &pdu[16]); - pdu[18] = fast_prov.flags; - sys_put_be32(fast_prov.iv_index, &pdu[19]); + sys_put_be16(fast_prov_info.net_idx, &pdu[16]); + pdu[18] = fast_prov_info.flags; + sys_put_be32(fast_prov_info.iv_index, &pdu[19]); } else { netkey = provisioner_net_key_get(prov_ctx.curr_net_idx); if (!netkey) { @@ -2161,7 +2242,7 @@ static void send_prov_data(void) } } - max_addr = FAST_PROV_FLAG_GET() ? fast_prov.unicast_addr_max : 0x7FFF; + max_addr = FAST_PROV_FLAG_GET() ? fast_prov_info.unicast_addr_max : 0x7FFF; if (!already_flag) { /* If this device to be provisioned is a new device */ @@ -2220,8 +2301,8 @@ static void send_prov_data(void) } if (FAST_PROV_FLAG_GET()) { - link[i].ki_flags = fast_prov.flags; - link[i].iv_index = fast_prov.iv_index; + link[i].ki_flags = fast_prov_info.flags; + link[i].iv_index = fast_prov_info.iv_index; } else { link[i].ki_flags = prov_ctx.curr_flags; link[i].iv_index = prov_ctx.curr_iv_index; @@ -2317,7 +2398,7 @@ static void prov_complete(const u8_t *data) prov_nodes[j].element_num = link[i].element_num; prov_nodes[j].unicast_addr = link[i].unicast_addr; if (FAST_PROV_FLAG_GET()) { - prov_nodes[j].net_idx = fast_prov.net_idx; + prov_nodes[j].net_idx = fast_prov_info.net_idx; } else { prov_nodes[j].net_idx = prov_ctx.curr_net_idx; } @@ -2422,6 +2503,7 @@ static void prov_timeout(struct k_work *work) #if defined(CONFIG_BLE_MESH_PB_ADV) static void prov_retransmit(struct k_work *work) { + s64_t timeout = TRANSACTION_TIMEOUT; int id = work->index; BT_DBG("%s", __func__); @@ -2431,18 +2513,25 @@ static void prov_retransmit(struct k_work *work) return; } - if (k_uptime_get() - link[id].tx.start > TRANSACTION_TIMEOUT) { - BT_WARN("%s, Timeout, giving up transaction", __func__); - close_link(id, CLOSE_REASON_TIMEOUT); +#if defined(CONFIG_BLE_MESH_FAST_PROV) + if (link[id].tx_pdu_type >= PROV_DATA) { + timeout = K_SECONDS(30); + } +#endif + if (k_uptime_get() - link[id].tx.start > timeout) { + BT_WARN("Provisioner timeout, giving up transaction"); + reset_link(id, CLOSE_REASON_TIMEOUT); return; } - if (link[id].link_close & BIT(0)) { - if (link[id].link_close >> 1 & 0x02) { - reset_link(id, link[id].link_close >> 8); + if (link[id].send_link_close & BIT(0)) { + u8_t reason = (link[id].send_link_close >> 1) & BIT_MASK(2); + u16_t count = (link[id].send_link_close >> 3); + if (count >= 2) { + reset_link(id, reason); return; } - link[id].link_close += BIT(1); + link[id].send_link_close += BIT(3); } for (int i = 0; i < ARRAY_SIZE(link[id].tx.buf); i++) { @@ -2490,10 +2579,6 @@ static void link_ack(struct prov_rx *rx, struct net_buf_simple *buf) return; } - /** After received link_ack, we don't call prov_clear_tx() to - * cancel retransmit timer, because retransmit timer will be - * cancelled after we send the provisioning invite pdu. - */ send_invite(); } @@ -2702,7 +2787,7 @@ static void gen_prov_start(struct prov_rx *rx, struct net_buf_simple *buf) if (link[i].rx.buf->len > link[i].rx.buf->size) { BT_ERR("%s, Too large provisioning PDU (%u bytes)", __func__, link[i].rx.buf->len); - close_link(i, CLOSE_REASON_FAILED); + // close_link(i, CLOSE_REASON_FAILED); return; } @@ -3024,45 +3109,43 @@ int provisioner_prov_init(const struct bt_mesh_prov *prov_info) prov_ctx.curr_flags = prov->flags; prov_ctx.curr_iv_index = prov->iv_index; + osi_mutex_new(&prov_ctx.pb_adv_lock); + osi_mutex_new(&prov_ctx.pb_gatt_lock); + return 0; } -static int provisioner_notify_unprov_adv_pkt(bt_mesh_prov_bearer_t bearer, const u8_t uuid[16], - const bt_mesh_addr_t *addr, u16_t oob_info) +static bool is_unprov_dev_info_callback_to_app(bt_mesh_prov_bearer_t bearer, + const u8_t uuid[16], const bt_mesh_addr_t *addr, u16_t oob_info) { - u8_t adv_type; int index; - if ((bearer != BLE_MESH_PROV_ADV && bearer != BLE_MESH_PROV_GATT) || !uuid || !addr) { - BT_ERR("%s, invalid parameter", __func__); - return -EINVAL; - } - - adv_type = (bearer == BLE_MESH_PROV_ADV) ? BLE_MESH_ADV_NONCONN_IND : BLE_MESH_ADV_IND; - if (prov_ctx.prov_after_match == false) { if (provisioner_dev_find(addr, uuid, &index)) { - BT_DBG("%s, Device is not found, notify to upper layer", __func__); + BT_DBG("%s, Device is not in queue, notify to upper layer", __func__); + u8_t adv_type = (bearer == BLE_MESH_PROV_ADV) ? + BLE_MESH_ADV_NONCONN_IND : BLE_MESH_ADV_IND; if (notify_unprov_adv_pkt_cb) { notify_unprov_adv_pkt_cb(addr->val, addr->type, adv_type, uuid, oob_info, bearer); } - return -EALREADY; + return true; } if (!(unprov_dev[index].bearer & bearer)) { - BT_DBG("%s, Not support PB-%s", __func__, (bearer == BLE_MESH_PROV_ADV) ? "ADV" : "GATT"); - return -EIO; + BT_WARN("Device in queue not support PB-%s", + (bearer == BLE_MESH_PROV_ADV) ? "ADV" : "GATT"); + return true; } } - return 0; + return false; } void provisioner_unprov_beacon_recv(struct net_buf_simple *buf) { #if defined(CONFIG_BLE_MESH_PB_ADV) const bt_mesh_addr_t *addr = NULL; - u8_t *uuid = NULL; + const u8_t *uuid = NULL; u16_t oob_info; if (buf->len != 0x12 && buf->len != 0x16) { @@ -3081,16 +3164,16 @@ void provisioner_unprov_beacon_recv(struct net_buf_simple *buf) /* Mesh beacon uses big-endian to send beacon data */ oob_info = net_buf_simple_pull_be16(buf); - if (provisioner_check_device_uuid(uuid)) { + if (provisioner_check_unprov_dev_info(uuid)) { return; } - if (provisioner_notify_unprov_adv_pkt( + if (is_unprov_dev_info_callback_to_app( BLE_MESH_PROV_ADV, uuid, addr, oob_info)) { return; } - provisioner_start_prov_device(BLE_MESH_PROV_ADV, uuid, addr, oob_info); + provisioner_start_prov_pb_adv(uuid, addr, oob_info); #endif /* CONFIG_BLE_MESH_PB_ADV */ } @@ -3175,7 +3258,7 @@ void provisioner_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_addr_t static void provisioner_prov_srv_data_recv(struct net_buf_simple *buf, const bt_mesh_addr_t *addr) { #if defined(CONFIG_BLE_MESH_PB_GATT) - u8_t *uuid = NULL; + const u8_t *uuid = NULL; u16_t oob_info; if (prov_ctx.pbg_count == CONFIG_BLE_MESH_PBG_SAME_TIME) { @@ -3188,11 +3271,11 @@ static void provisioner_prov_srv_data_recv(struct net_buf_simple *buf, const bt_ /* Mesh beacon uses big-endian to send beacon data */ oob_info = net_buf_simple_pull_be16(buf); - if (provisioner_check_device_uuid(uuid)) { + if (provisioner_check_unprov_dev_info(uuid)) { return; } - if (provisioner_notify_unprov_adv_pkt( + if (is_unprov_dev_info_callback_to_app( BLE_MESH_PROV_GATT, uuid, addr, oob_info)) { return; } @@ -3209,7 +3292,7 @@ static void provisioner_prov_srv_data_recv(struct net_buf_simple *buf, const bt_ * Use connecting flag to prevent if two devices's adv pkts are both received, * the previous one info will be replaced by the second one. */ - provisioner_start_prov_device(BLE_MESH_PROV_GATT, uuid, addr, oob_info); + provisioner_start_prov_pb_gatt(uuid, addr, oob_info); #endif /* CONFIG_BLE_MESH_PB_GATT */ } diff --git a/examples/bluetooth/ble_mesh/ble_mesh_client_model/sdkconfig.defaults b/examples/bluetooth/ble_mesh/ble_mesh_client_model/sdkconfig.defaults index c10b1b3265..919398f29d 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_client_model/sdkconfig.defaults +++ b/examples/bluetooth/ble_mesh/ble_mesh_client_model/sdkconfig.defaults @@ -1,11 +1,16 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= +CONFIG_BTDM_CONTROLLER_MODE_BTDM= +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=n CONFIG_BLE_SCAN_DUPLICATE=y CONFIG_SCAN_DUPLICATE_TYPE=2 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=200 CONFIG_BLE_MESH_SCAN_DUPLICATE_EN=y CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE=200 +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_GATTS_ENABLE=y CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL=y CONFIG_BLE_MESH=y diff --git a/examples/bluetooth/ble_mesh/ble_mesh_console/ble_mesh_node/sdkconfig.defaults b/examples/bluetooth/ble_mesh/ble_mesh_console/ble_mesh_node/sdkconfig.defaults index 87e0bf5bb4..ae1b8dfdf8 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_console/ble_mesh_node/sdkconfig.defaults +++ b/examples/bluetooth/ble_mesh/ble_mesh_console/ble_mesh_node/sdkconfig.defaults @@ -4,11 +4,16 @@ CONFIG_CONSOLE_UART_BAUDRATE=921600 CONFIG_ESPTOOLPY_BAUD_921600B=y CONFIG_MONITOR_BAUD_921600B=y CONFIG_BT_ENABLED=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= +CONFIG_BTDM_CONTROLLER_MODE_BTDM= +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=n CONFIG_BLE_SCAN_DUPLICATE=y CONFIG_SCAN_DUPLICATE_TYPE=2 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=200 CONFIG_BLE_MESH_SCAN_DUPLICATE_EN=y CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE=200 +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_GATTS_ENABLE=y CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL=y CONFIG_BLE_MESH=y diff --git a/examples/bluetooth/ble_mesh/ble_mesh_console/ble_mesh_provisioner/sdkconfig.defaults b/examples/bluetooth/ble_mesh/ble_mesh_console/ble_mesh_provisioner/sdkconfig.defaults index d9b602b567..74dfe97dbb 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_console/ble_mesh_provisioner/sdkconfig.defaults +++ b/examples/bluetooth/ble_mesh/ble_mesh_console/ble_mesh_provisioner/sdkconfig.defaults @@ -1,11 +1,16 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= +CONFIG_BTDM_CONTROLLER_MODE_BTDM= +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=n CONFIG_BLE_SCAN_DUPLICATE=y CONFIG_SCAN_DUPLICATE_TYPE=2 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=200 CONFIG_BLE_MESH_SCAN_DUPLICATE_EN=y CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE=200 +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_BLE_MESH=y CONFIG_BLE_MESH_USE_DUPLICATE_SCAN=y CONFIG_BLE_MESH_PROV=y diff --git a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/sdkconfig.defaults b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/sdkconfig.defaults index 84d6bbbcc4..a7cf17c978 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/sdkconfig.defaults +++ b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/sdkconfig.defaults @@ -1,11 +1,16 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= +CONFIG_BTDM_CONTROLLER_MODE_BTDM= +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=n CONFIG_BLE_SCAN_DUPLICATE=y CONFIG_SCAN_DUPLICATE_TYPE=2 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=200 CONFIG_BLE_MESH_SCAN_DUPLICATE_EN=y CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE=200 +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_BLE_MESH=y CONFIG_BLE_MESH_USE_DUPLICATE_SCAN=y CONFIG_BLE_MESH_PROV=y diff --git a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c index 39ca5cb9e3..ad1647eae4 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c @@ -113,10 +113,12 @@ static esp_ble_mesh_model_pub_t onoff_pub = { }; static esp_ble_mesh_model_op_t fast_prov_srv_op[] = { - { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET, 3, NULL }, - { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_ADD, 16, NULL }, - { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR, 2, NULL }, - { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET, 0, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET, 3, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_ADD, 16, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR, 2, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET, 0, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_ADD, 2, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_DELETE, 2, NULL }, ESP_BLE_MESH_MODEL_OP_END, }; @@ -179,7 +181,6 @@ static void gen_onoff_get_handler(esp_ble_mesh_model_t *model, } send_data = led->current; - ESP_LOGI(TAG, "%s, addr 0x%04x onoff 0x%02x", __func__, model->element->element_addr, led->current); /* Sends Generic OnOff Status as a reponse to Generic OnOff Get */ err = esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, @@ -210,12 +211,7 @@ static void gen_onoff_set_unack_handler(esp_ble_mesh_model_t *model, } led->current = data[0]; - ESP_LOGI(TAG, "addr 0x%02x onoff 0x%02x", model->element->element_addr, led->current); - - if (led_action_task_post(led, portMAX_DELAY) != ESP_OK) { - ESP_LOGE(TAG, "%s: Failed to post led action to queue", __func__); - return; - } + gpio_set_level(led->pin, led->current); /* When the node receives the first Generic OnOff Get/Set/Set Unack message, it will * start the timer used to disable fast provisioning functionality. @@ -268,6 +264,9 @@ static void provisioner_prov_complete(int node_idx, const uint8_t uuid[16], uint fast_prov_server.prov_node_cnt++; } + ESP_LOG_BUFFER_HEX("Device uuid", uuid + 2, 6); + ESP_LOGI(TAG, "Unicast address 0x%04x", unicast_addr); + /* Sets node info */ err = example_store_node_info(uuid, unicast_addr, element_num, net_idx, fast_prov_server.app_idx, LED_OFF); @@ -295,12 +294,13 @@ static void provisioner_prov_complete(int node_idx, const uint8_t uuid[16], uint ESP_LOGE(TAG, "%s: Failed to store node address 0x%04x", __func__, unicast_addr); return; } - if (fast_prov_server.node_addr_cnt <= fast_prov_server.max_node_num) { - if (bt_mesh_atomic_test_and_clear_bit(fast_prov_server.srv_flags, SEND_ALL_NODE_ADDR_START)) { - k_delayed_work_cancel(&fast_prov_server.send_all_node_addr_timer); + if (fast_prov_server.node_addr_cnt != FAST_PROV_NODE_COUNT_MIN && + fast_prov_server.node_addr_cnt <= fast_prov_server.max_node_num) { + if (bt_mesh_atomic_test_and_clear_bit(fast_prov_server.srv_flags, GATT_PROXY_ENABLE_START)) { + k_delayed_work_cancel(&fast_prov_server.gatt_proxy_enable_timer); } - if (!bt_mesh_atomic_test_and_set_bit(fast_prov_server.srv_flags, SEND_ALL_NODE_ADDR_START)) { - k_delayed_work_submit(&fast_prov_server.send_all_node_addr_timer, SEND_ALL_NODE_ADDR_TIMEOUT); + if (!bt_mesh_atomic_test_and_set_bit(fast_prov_server.srv_flags, GATT_PROXY_ENABLE_START)) { + k_delayed_work_submit(&fast_prov_server.gatt_proxy_enable_timer, GATT_PROXY_ENABLE_TIMEOUT); } } } else { @@ -503,7 +503,9 @@ static void example_ble_mesh_custom_model_cb(esp_ble_mesh_model_cb_event_t event case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET: case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_ADD: case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR: - case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET: { + case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET: + case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_ADD: + case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_DELETE: { ESP_LOGI(TAG, "%s: Fast prov server receives msg, opcode 0x%04x", __func__, opcode); struct net_buf_simple buf = { .len = param->model_operation.length, diff --git a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/board.c b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/board.c index 9a5a8eb95d..4c51d04af7 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/board.c +++ b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/board.c @@ -14,27 +14,18 @@ #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" - #include "driver/gpio.h" - #include "board.h" -#include "esp_fast_prov_server_model.h" +#include "esp_fast_prov_common.h" #define TAG "BOARD" -extern example_fast_prov_server_t fast_prov_server; - struct _led_state led_state[3] = { { LED_OFF, LED_OFF, LED_R, "red" }, { LED_OFF, LED_OFF, LED_G, "green" }, { LED_OFF, LED_OFF, LED_B, "blue" }, }; -static xQueueHandle led_action_queue; - void board_output_number(esp_ble_mesh_output_action_t action, uint32_t number) { ESP_LOGI(TAG, "Board output number %d", number); @@ -74,48 +65,8 @@ static void board_led_init(void) } } -static void led_action_thread(void *arg) -{ - struct _led_state led = {0}; - - while (1) { - if (xQueueReceive(led_action_queue, &led, (portTickType)portMAX_DELAY)) { - ESP_LOGI(TAG, "%s: pin 0x%04x onoff 0x%02x", __func__, led.pin, led.current); - /* If the node is controlled by phone, add a delay when turn on/off led */ - if (fast_prov_server.primary_role == true) { - vTaskDelay(50 / portTICK_PERIOD_MS); - } - gpio_set_level(led.pin, led.current); - } - } -} - -esp_err_t led_action_task_post(struct _led_state *msg, uint32_t timeout) -{ - if (xQueueSend(led_action_queue, msg, timeout) != pdTRUE) { - return ESP_FAIL; - } - return ESP_OK; -} - esp_err_t board_init(void) { - BaseType_t ret; - board_led_init(); - - led_action_queue = xQueueCreate(60, sizeof(struct _led_state)); - if (!led_action_queue) { - ESP_LOGE(TAG, "%s: Failed to create led action queue", __func__); - return ESP_FAIL; - } - - ret = xTaskCreate(led_action_thread, "led_action_thread", 4096, NULL, 5, NULL); - if (ret == pdFAIL) { - ESP_LOGE(TAG, "%s: Failed to create led_action_thread", __func__); - vQueueDelete(led_action_queue); - return ESP_FAIL; - } - return ESP_OK; } diff --git a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/board.h b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/board.h index c45b7b37a2..83d6057427 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/board.h +++ b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/board.h @@ -41,8 +41,6 @@ void board_prov_complete(void); void board_led_operation(uint8_t pin, uint8_t onoff); -esp_err_t led_action_task_post(struct _led_state *msg, uint32_t timeout); - esp_err_t board_init(void); #endif diff --git a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/sdkconfig.defaults b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/sdkconfig.defaults index 6f6dd42d95..dd6f002e7e 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/sdkconfig.defaults +++ b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/sdkconfig.defaults @@ -1,11 +1,16 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= +CONFIG_BTDM_CONTROLLER_MODE_BTDM= +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=n CONFIG_BLE_SCAN_DUPLICATE=y CONFIG_SCAN_DUPLICATE_TYPE=2 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=200 CONFIG_BLE_MESH_SCAN_DUPLICATE_EN=y CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE=200 +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_GATTS_ENABLE=y CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL=y CONFIG_BLE_MESH=y @@ -23,6 +28,10 @@ CONFIG_BLE_MESH_PROVISIONER_SUBNET_COUNT=3 CONFIG_BLE_MESH_PROVISIONER_APP_KEY_COUNT=9 CONFIG_BLE_MESH_PB_ADV=y CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y +CONFIG_BLE_MESH_SUBNET_COUNT=2 +CONFIG_BLE_MESH_APP_KEY_COUNT=3 +CONFIG_BLE_MESH_MODEL_KEY_COUNT=3 +CONFIG_BLE_MESH_MODEL_GROUP_COUNT=3 CONFIG_BLE_MESH_PB_GATT=y CONFIG_BLE_MESH_GATT_PROXY=y CONFIG_BLE_MESH_RELAY=y diff --git a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/tutorial/ble_mesh_fast_provision_server.md b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/tutorial/ble_mesh_fast_provision_server.md index 5b401c318b..d1e597cda6 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/tutorial/ble_mesh_fast_provision_server.md +++ b/examples/bluetooth/ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/tutorial/ble_mesh_fast_provision_server.md @@ -55,7 +55,7 @@ typedef struct { uint8_t state; /* Fast prov state -> 0: idle, 1: pend, 2: active */ struct k_delayed_work disable_fast_prov_timer; /* Used to disable fast provisioning */ - struct k_delayed_work send_all_node_addr_timer; /* Used to send all node addresses to top provisioner(e.g. phone) */ + struct k_delayed_work gatt_proxy_enable_timer; /* Used to Mesh GATT Proxy functionality */ } __attribute__((packed)) example_fast_prov_server_t; ``` @@ -70,7 +70,7 @@ In the struct, there are three variables that are related to roles and states, w | ---------------------|------------------------- | | `primary_role` | Provisioner identity | | `state` | Fast provisioner state (0: idle, 1: pend, 2: active) | -| `srv_flags` | Flags (`DISABLE_FAST_PROV_START`,`SEND_ALL_NODE_ADDR_START`,`RELAY_PROXY_DISABLED`,`SRV_MAX_FLAGS`) | +| `srv_flags` | Flags (`DISABLE_FAST_PROV_START`,`GATT_PROXY_ENABLE_START`,`RELAY_PROXY_DISABLED`,`SRV_MAX_FLAGS`) | Among which, there are four roles in this demo (`primary_role`): @@ -120,7 +120,7 @@ The node's cache data, which are described in the following table, is sent by th There are two timers in this demo, which are: -1. `send_all_node_addr_timer` is used to collect the addresses of all nodes. +1. `gatt_proxy_enable_timer` is used to enable Mesh GATT Proxy functionality. * The timer starts or resets and starts when a Temporary Provisioner provisions an unprovisioned device. * The Temporary Provisioner will send a message (Address information) to the Primary Provisioner. 2. `disable_fast_prov_timer` is used to disable the provisioning capabilities. @@ -131,7 +131,7 @@ The variables that are related to these two timers are described below: | Variable Name |Description | | ----------------------|------------------------- | | `disable_fast_prov_timer` |Used to disable fast provisioning| -| `send_all_node_addr_timer` |Used to send all node addresses to top provisioner| +| `gatt_proxy_enable_timer` |Used to enable Mesh GATT Proxy functionality| ### 2.2 Model Definition diff --git a/examples/bluetooth/ble_mesh/ble_mesh_node/sdkconfig.defaults b/examples/bluetooth/ble_mesh/ble_mesh_node/sdkconfig.defaults index f0031b8e07..34e84bc4ad 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_node/sdkconfig.defaults +++ b/examples/bluetooth/ble_mesh/ble_mesh_node/sdkconfig.defaults @@ -1,11 +1,16 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= +CONFIG_BTDM_CONTROLLER_MODE_BTDM= +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=n CONFIG_BLE_SCAN_DUPLICATE=y CONFIG_SCAN_DUPLICATE_TYPE=2 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=200 CONFIG_BLE_MESH_SCAN_DUPLICATE_EN=y CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE=200 +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_GATTS_ENABLE=y CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL=y CONFIG_BLE_MESH=y diff --git a/examples/bluetooth/ble_mesh/ble_mesh_provisioner/sdkconfig.defaults b/examples/bluetooth/ble_mesh/ble_mesh_provisioner/sdkconfig.defaults index 2b5c4a37de..5c7cb1846c 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_provisioner/sdkconfig.defaults +++ b/examples/bluetooth/ble_mesh/ble_mesh_provisioner/sdkconfig.defaults @@ -1,11 +1,16 @@ # Override some defaults so BT stack is enabled # by default in this example CONFIG_BT_ENABLED=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= +CONFIG_BTDM_CONTROLLER_MODE_BTDM= +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=n CONFIG_BLE_SCAN_DUPLICATE=y CONFIG_SCAN_DUPLICATE_TYPE=2 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=200 CONFIG_BLE_MESH_SCAN_DUPLICATE_EN=y CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE=200 +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_BLE_MESH=y CONFIG_BLE_MESH_USE_DUPLICATE_SCAN=y CONFIG_BLE_MESH_PROV=y diff --git a/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_common.h b/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_common.h index e222863363..6f4771239f 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_common.h +++ b/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_common.h @@ -41,6 +41,10 @@ #define ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET ESP_BLE_MESH_MODEL_OP_3(0x06, CID_ESP) #define ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_STATUS ESP_BLE_MESH_MODEL_OP_3(0x07, CID_ESP) +#define ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_ADD ESP_BLE_MESH_MODEL_OP_3(0x08, CID_ESP) + +#define ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_DELETE ESP_BLE_MESH_MODEL_OP_3(0x09, CID_ESP) + typedef struct { uint16_t net_idx; uint16_t app_idx; diff --git a/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_operation.c b/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_operation.c index d198a5f5be..f09fb643bf 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_operation.c +++ b/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_operation.c @@ -289,6 +289,40 @@ esp_err_t example_add_fast_prov_group_address(uint16_t model_id, uint16_t group_ return ESP_OK; } +esp_err_t example_delete_fast_prov_group_address(uint16_t model_id, uint16_t group_addr) +{ + const esp_ble_mesh_comp_t *comp = NULL; + esp_ble_mesh_elem_t *element = NULL; + esp_ble_mesh_model_t *model = NULL; + int i, j; + + if (!ESP_BLE_MESH_ADDR_IS_GROUP(group_addr)) { + return ESP_ERR_INVALID_ARG; + } + + comp = esp_ble_mesh_get_composition_data(); + if (comp == NULL) { + return ESP_FAIL; + } + + for (i = 0; i < comp->element_count; i++) { + element = &comp->elements[i]; + + model = esp_ble_mesh_find_sig_model(element, model_id); + if (model == NULL) { + continue; + } + for (j = 0; j < ARRAY_SIZE(model->groups); j++) { + if (model->groups[j] == group_addr) { + model->groups[j] = ESP_BLE_MESH_ADDR_UNASSIGNED; + break; + } + } + } + + return ESP_OK; +} + esp_err_t example_send_config_appkey_add(esp_ble_mesh_model_t *model, example_msg_common_info_t *info, esp_ble_mesh_cfg_app_key_add_t *add_key) diff --git a/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_operation.h b/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_operation.h index 6ef5fb8b47..3a3135062e 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_operation.h +++ b/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_operation.h @@ -34,6 +34,8 @@ esp_err_t example_handle_config_app_key_add_evt(uint16_t app_idx); esp_err_t example_add_fast_prov_group_address(uint16_t model_id, uint16_t group_addr); +esp_err_t example_delete_fast_prov_group_address(uint16_t model_id, uint16_t group_addr); + esp_err_t example_send_config_appkey_add(esp_ble_mesh_model_t *model, example_msg_common_info_t *info, esp_ble_mesh_cfg_app_key_add_t *add_key); diff --git a/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.c b/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.c index d64c967e5c..e5b68578f7 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.c +++ b/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.c @@ -28,7 +28,7 @@ #define TAG "FAST_PROV_SERVER" /* Array used to store all node addresses */ -static uint16_t all_node_addr[100]; +static uint16_t all_node_addr[120]; static uint16_t all_node_addr_cnt; esp_err_t example_store_remote_node_address(uint16_t node_addr) @@ -57,6 +57,20 @@ esp_err_t example_store_remote_node_address(uint16_t node_addr) return ESP_FAIL; } +esp_ble_mesh_cfg_srv_t *get_cfg_srv_user_data(void) +{ + esp_ble_mesh_model_t *model = NULL; + + model = example_find_model(esp_ble_mesh_get_primary_element_address(), + ESP_BLE_MESH_MODEL_ID_CONFIG_SRV, CID_NVAL); + if (!model) { + ESP_LOGE(TAG, "%s: Failed to get config server model", __func__); + return NULL; + } + + return (esp_ble_mesh_cfg_srv_t *)(model->user_data); +} + /* Timeout handler for disable_fast_prov_timer */ static void disable_fast_prov_cb(struct k_work *work) { @@ -74,41 +88,20 @@ static void disable_fast_prov_cb(struct k_work *work) } } -static esp_ble_mesh_cfg_srv_t *get_cfg_srv_user_data(void) +/* Timeout handler for gatt_proxy_enable_timer */ +static void enable_gatt_proxy_cb(struct k_work *work) { - esp_ble_mesh_model_t *model = NULL; + example_fast_prov_server_t *srv = NULL; - model = example_find_model(esp_ble_mesh_get_primary_element_address(), - ESP_BLE_MESH_MODEL_ID_CONFIG_SRV, CID_NVAL); - if (!model) { - ESP_LOGE(TAG, "%s: Failed to get config server model", __func__); - return NULL; - } - - return (esp_ble_mesh_cfg_srv_t *)(model->user_data); -} - -/* Timeout handler for send_all_node_addr_timer */ -static void example_send_all_node_addr(struct k_work *work) -{ - example_fast_prov_server_t *fast_prov_srv_data = NULL; - esp_ble_mesh_cfg_srv_t *cfg_srv_data = NULL; - - fast_prov_srv_data = CONTAINER_OF(work, example_fast_prov_server_t, send_all_node_addr_timer.work); - if (!fast_prov_srv_data) { + srv = CONTAINER_OF(work, example_fast_prov_server_t, gatt_proxy_enable_timer.work); + if (!srv) { ESP_LOGE(TAG, "%s: Failed to get fast prov server model user_data", __func__); return; } - cfg_srv_data = get_cfg_srv_user_data(); - if (!cfg_srv_data) { - ESP_LOGE(TAG, "%s: Failed to get config server model user_data", __func__); - return; - } - - if (bt_mesh_atomic_test_and_clear_bit(fast_prov_srv_data->srv_flags, RELAY_PROXY_DISABLED)) { + if (bt_mesh_atomic_test_and_clear_bit(srv->srv_flags, RELAY_PROXY_DISABLED)) { ESP_LOGI(TAG, "%s: Enable BLE Mesh Relay & GATT Proxy", __func__); - cfg_srv_data->relay = ESP_BLE_MESH_RELAY_ENABLED; + /* For Primary Provisioner, Relay will not be enabled */ esp_ble_mesh_proxy_gatt_enable(); esp_ble_mesh_proxy_identity_enable(); } @@ -125,22 +118,18 @@ static void example_free_set_info(example_fast_prov_server_t *srv) } esp_err_t example_fast_prov_server_recv_msg(esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx, - struct net_buf_simple *buf) + esp_ble_mesh_msg_ctx_t *ctx, struct net_buf_simple *buf) { example_fast_prov_server_t *srv = NULL; struct net_buf_simple *msg = NULL; - uint32_t opcode; + uint32_t opcode = 0; esp_err_t err; - if (!model || !ctx || !buf) { + if (!model || !model->user_data || !ctx || !buf) { return ESP_ERR_INVALID_ARG; } srv = (example_fast_prov_server_t *)model->user_data; - if (!srv) { - return ESP_FAIL; - } ESP_LOG_BUFFER_HEX("fast prov server recv", buf->data, buf->len); @@ -280,6 +269,10 @@ esp_err_t example_fast_prov_server_recv_msg(esp_ble_mesh_model_t *model, return ESP_FAIL; } + if (unicast_max < unicast_min + srv->max_node_num - 1) { + srv->max_node_num = unicast_max - unicast_min + 1; + } + srv->set_info->set_succeed = false; srv->set_info->node_addr_cnt = node_addr_cnt; srv->set_info->unicast_min = unicast_min; @@ -294,7 +287,7 @@ esp_err_t example_fast_prov_server_recv_msg(esp_ble_mesh_model_t *model, esp_ble_mesh_fast_prov_info_t info_set = { .unicast_min = unicast_min, - .unicast_max = unicast_max, + .unicast_max = unicast_min + srv->max_node_num - 1, .flags = flags, .iv_index = iv_index, .net_idx = net_idx, @@ -340,14 +333,13 @@ esp_err_t example_fast_prov_server_recv_msg(esp_ble_mesh_model_t *model, return ESP_FAIL; } - if (bt_mesh_atomic_test_and_clear_bit(srv->srv_flags, SEND_ALL_NODE_ADDR_START)) { - k_delayed_work_cancel(&srv->send_all_node_addr_timer); + if (bt_mesh_atomic_test_and_clear_bit(srv->srv_flags, GATT_PROXY_ENABLE_START)) { + k_delayed_work_cancel(&srv->gatt_proxy_enable_timer); } - uint16_t length = buf->len; - for (int i = 0; i < (length >> 1); i++) { + for (; buf->len; ) { uint16_t node_addr = net_buf_simple_pull_le16(buf); - ESP_LOGI(TAG, "node address %d: 0x%04x", i, node_addr); + ESP_LOGI(TAG, "Node address: 0x%04x", node_addr); err = example_store_remote_node_address(node_addr); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: Failed to store node address 0x%04x", __func__, node_addr); @@ -374,6 +366,46 @@ esp_err_t example_fast_prov_server_recv_msg(esp_ble_mesh_model_t *model, opcode = ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_STATUS; break; } + case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_ADD: { + uint16_t own_addr = esp_ble_mesh_get_primary_element_address(); + uint16_t group_addr = net_buf_simple_pull_le16(buf); + ESP_LOGI(TAG, "%s, group address 0x%04x", __func__, group_addr); + if (!ESP_BLE_MESH_ADDR_IS_GROUP(group_addr)) { + return ESP_FAIL; + } + for (; buf->len; ) { + uint16_t dst = net_buf_simple_pull_le16(buf); + ESP_LOGI(TAG, "%s, dst 0x%04x, own address 0x%04x", __func__, dst, own_addr); + if (dst == own_addr) { + err = example_add_fast_prov_group_address(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, group_addr); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: Failed to add group address 0x%04x", __func__, group_addr); + } + return err; + } + } + return ESP_OK; + } + case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_DELETE: { + uint16_t own_addr = esp_ble_mesh_get_primary_element_address(); + uint16_t group_addr = net_buf_simple_pull_le16(buf); + ESP_LOGI(TAG, "%s, group address 0x%04x", __func__, group_addr); + if (!ESP_BLE_MESH_ADDR_IS_GROUP(group_addr)) { + return ESP_FAIL; + } + for (; buf->len; ) { + uint16_t dst = net_buf_simple_pull_le16(buf); + ESP_LOGI(TAG, "%s, dst 0x%04x, own address 0x%04x", __func__, dst, own_addr); + if (dst == own_addr) { + err = example_delete_fast_prov_group_address(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, group_addr); + if (err != ESP_OK) { + ESP_LOGE(TAG, "%s: Failed to delete group address 0x%04x", __func__, group_addr); + } + return err; + } + } + return ESP_OK; + } default: ESP_LOGW(TAG, "%s: Not a Fast Prov Client message opcode", __func__); return ESP_FAIL; @@ -396,12 +428,12 @@ esp_err_t example_handle_fast_prov_info_set_comp_evt(esp_ble_mesh_model_t *model struct net_buf_simple *msg = NULL; esp_err_t err; - if (!model) { + if (!model || !model->user_data) { return ESP_ERR_INVALID_ARG; } srv = (example_fast_prov_server_t *)model->user_data; - if (!srv || !srv->set_info) { + if (!srv->set_info) { return ESP_FAIL; } @@ -416,9 +448,6 @@ esp_err_t example_handle_fast_prov_info_set_comp_evt(esp_ble_mesh_model_t *model } /* Update Fast Prov Server Model user_data */ - if (srv->set_info->unicast_max < srv->set_info->unicast_min + srv->max_node_num - 1) { - srv->max_node_num = srv->set_info->unicast_max - srv->set_info->unicast_min + 1; - } srv->unicast_min = srv->set_info->unicast_min + srv->max_node_num; srv->unicast_max = srv->set_info->unicast_max; srv->unicast_cur = srv->set_info->unicast_min + srv->max_node_num; @@ -476,29 +505,48 @@ send: esp_err_t example_handle_fast_prov_action_set_comp_evt(esp_ble_mesh_model_t *model, uint8_t status_action) { - example_fast_prov_server_t *srv = model->user_data; + example_fast_prov_server_t *srv = NULL; struct net_buf_simple *msg = NULL; uint32_t opcode; esp_err_t err; + if (!model || !model->user_data) { + return ESP_ERR_INVALID_ARG; + } + + srv = (example_fast_prov_server_t *)model->user_data; + msg = bt_mesh_alloc_buf(9); net_buf_simple_init(msg, 0); switch (srv->state) { - case STATE_IDLE: { /* fast prov info set (enter) */ + case STATE_IDLE: { /* fast prov info set (enter) */ const uint8_t zero[6] = {0}; net_buf_simple_add_le16(msg, 0x7f); net_buf_simple_add_mem(msg, zero, 6); net_buf_simple_add_u8(msg, status_action); opcode = ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_STATUS; + /** + * Disable relay should not have a impact on Mesh Proxy PDU, and + * we can also move "disabling relay" in the event of "disabling + * gatt proxy" here. + */ + if (srv->node_addr_cnt == FAST_PROV_NODE_COUNT_MIN) { + if (bt_mesh_atomic_test_and_clear_bit(srv->srv_flags, GATT_PROXY_ENABLE_START)) { + k_delayed_work_cancel(&srv->gatt_proxy_enable_timer); + } + if (!bt_mesh_atomic_test_and_set_bit(srv->srv_flags, GATT_PROXY_ENABLE_START)) { + k_delayed_work_submit(&srv->gatt_proxy_enable_timer, K_SECONDS(3)); + } + } break; } - case STATE_ACTIVE: /* fast prov info set (suspend/exit) */ - /* Currently we only support suspend/exit fast prov after - * Generic OnOff Set/Set Unack is received. So no fast prov - * status message will be sent. + case STATE_ACTIVE: /* fast prov info set (suspend/exit) */ + /* Currently we only support suspend/exit fast prov after Generic + * OnOff Set/Set Unack is received. So no fast prov status message + * will be sent. */ - case STATE_PEND: /* fast prov net_key add */ + case STATE_PEND: /* fast prov net_key add */ /* In this case, we should send fast prov net_key status */ default: bt_mesh_free_buf(msg); @@ -529,19 +577,18 @@ esp_err_t example_handle_fast_prov_action_set_comp_evt(esp_ble_mesh_model_t *mod } esp_err_t example_handle_fast_prov_status_send_comp_evt(int err_code, uint32_t opcode, - esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx) + esp_ble_mesh_model_t *model, esp_ble_mesh_msg_ctx_t *ctx) { - example_fast_prov_server_t *srv = model->user_data; - esp_ble_mesh_cfg_srv_t *cfg_srv_data = NULL; + example_fast_prov_server_t *srv = NULL; + + if (!model || !model->user_data) { + return ESP_ERR_INVALID_ARG; + } + + srv = (example_fast_prov_server_t *)model->user_data; ESP_LOGI(TAG, "%s: opcode 0x%06x", __func__, opcode); - cfg_srv_data = get_cfg_srv_user_data(); - if (!cfg_srv_data) { - return ESP_FAIL; - } - switch (opcode) { case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_STATUS: if (err_code == 0 && srv->set_info && srv->set_info->set_succeed == true) { @@ -558,11 +605,8 @@ esp_err_t example_handle_fast_prov_status_send_comp_evt(int err_code, uint32_t o case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_STATUS: break; case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_ACK: - /* Minus 1 which is provisioned by the top device */ - if (all_node_addr_cnt < srv->node_addr_cnt - 1) { - if (!bt_mesh_atomic_test_and_set_bit(srv->srv_flags, SEND_ALL_NODE_ADDR_START)) { - k_delayed_work_submit(&srv->send_all_node_addr_timer, SEND_ALL_NODE_ADDR_TIMEOUT); - } + if (!bt_mesh_atomic_test_and_set_bit(srv->srv_flags, GATT_PROXY_ENABLE_START)) { + k_delayed_work_submit(&srv->gatt_proxy_enable_timer, GATT_PROXY_ENABLE_TIMEOUT); } break; case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_STATUS: @@ -578,19 +622,15 @@ esp_err_t example_fast_prov_server_init(esp_ble_mesh_model_t *model) { example_fast_prov_server_t *srv = NULL; - if (!model) { + if (!model || !model->user_data) { return ESP_ERR_INVALID_ARG; } srv = (example_fast_prov_server_t *)model->user_data; - if (!srv) { - return ESP_FAIL; - } - srv->model = model; k_delayed_work_init(&srv->disable_fast_prov_timer, disable_fast_prov_cb); - k_delayed_work_init(&srv->send_all_node_addr_timer, example_send_all_node_addr); + k_delayed_work_init(&srv->gatt_proxy_enable_timer, enable_gatt_proxy_cb); return ESP_OK; } diff --git a/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.h b/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.h index 0cc060625c..b4dec616a6 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.h +++ b/examples/bluetooth/ble_mesh/ble_mesh_vendor_models/fast_prov_vendor_model/components/esp_fast_prov_server_model.h @@ -18,11 +18,13 @@ #include "esp_fast_prov_common.h" #define DISABLE_FAST_PROV_TIMEOUT K_SECONDS(10) -#define SEND_ALL_NODE_ADDR_TIMEOUT K_SECONDS(10) +#define GATT_PROXY_ENABLE_TIMEOUT K_SECONDS(10) + +#define FAST_PROV_NODE_COUNT_MIN 0x01 enum { DISABLE_FAST_PROV_START, /* Flag indicates the timer used to disable fast provisioning has been started */ - SEND_ALL_NODE_ADDR_START, /* Flag indicates the timer used to send all node address has been started */ + GATT_PROXY_ENABLE_START, /* Flag indicates the timer used to enable Mesh GATT Proxy has been started */ RELAY_PROXY_DISABLED, /* Flag indicates if relay & proxy_adv are enabled or disabled */ SRV_MAX_FLAGS, }; @@ -79,14 +81,13 @@ typedef struct { uint8_t state; /* Fast prov state -> 0: idle, 1: pend, 2: active */ struct k_delayed_work disable_fast_prov_timer; /* Used to disable fast provisioning */ - struct k_delayed_work send_all_node_addr_timer; /* Used to send all node addresses to top provisioner(e.g. phone) */ + struct k_delayed_work gatt_proxy_enable_timer; /* Used to enable Mesh GATT Proxy functionality */ } __attribute__((packed)) example_fast_prov_server_t; esp_err_t example_store_remote_node_address(uint16_t node_addr); esp_err_t example_fast_prov_server_recv_msg(esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx, - struct net_buf_simple *buf); + esp_ble_mesh_msg_ctx_t *ctx, struct net_buf_simple *buf); esp_err_t example_handle_fast_prov_info_set_comp_evt(esp_ble_mesh_model_t *model, uint8_t status_unicast, uint8_t status_net_idx, uint8_t status_match); @@ -94,8 +95,7 @@ esp_err_t example_handle_fast_prov_info_set_comp_evt(esp_ble_mesh_model_t *model esp_err_t example_handle_fast_prov_action_set_comp_evt(esp_ble_mesh_model_t *model, uint8_t status_action); esp_err_t example_handle_fast_prov_status_send_comp_evt(int err_code, uint32_t opcode, - esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx); + esp_ble_mesh_model_t *model, esp_ble_mesh_msg_ctx_t *ctx); esp_err_t example_fast_prov_server_init(esp_ble_mesh_model_t *model); diff --git a/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_main.c b/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_main.c index a67034e4ff..87b1e3117d 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/ble_mesh_demo_main.c @@ -125,10 +125,12 @@ static esp_ble_mesh_model_pub_t onoff_pub = { }; static esp_ble_mesh_model_op_t fast_prov_srv_op[] = { - { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET, 3, NULL }, - { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_ADD, 16, NULL }, - { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR, 2, NULL }, - { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET, 0, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET, 3, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_ADD, 16, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR, 2, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET, 0, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_ADD, 2, NULL }, + { ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_DELETE, 2, NULL }, ESP_BLE_MESH_MODEL_OP_END, }; @@ -191,7 +193,6 @@ static void gen_onoff_get_handler(esp_ble_mesh_model_t *model, } send_data = led->current; - ESP_LOGI(TAG, "%s, addr 0x%04x onoff 0x%02x", __func__, model->element->element_addr, led->current); /* Sends Generic OnOff Status as a reponse to Generic OnOff Get */ err = esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, @@ -222,12 +223,7 @@ static void gen_onoff_set_unack_handler(esp_ble_mesh_model_t *model, } led->current = data[0]; - ESP_LOGI(TAG, "addr 0x%02x onoff 0x%02x", model->element->element_addr, led->current); - - if (led_action_task_post(led, portMAX_DELAY) != ESP_OK) { - ESP_LOGE(TAG, "%s: Failed to post led action to queue", __func__); - return; - } + gpio_set_level(led->pin, led->current); /* When the node receives the first Generic OnOff Get/Set/Set Unack message, it will * start the timer used to disable fast provisioning functionality. @@ -280,6 +276,9 @@ static void provisioner_prov_complete(int node_idx, const uint8_t uuid[16], uint fast_prov_server.prov_node_cnt++; } + ESP_LOG_BUFFER_HEX("Device uuid", uuid + 2, 6); + ESP_LOGI(TAG, "Unicast address 0x%04x", unicast_addr); + /* Sets node info */ err = example_store_node_info(uuid, unicast_addr, element_num, net_idx, fast_prov_server.app_idx, LED_OFF); @@ -307,12 +306,13 @@ static void provisioner_prov_complete(int node_idx, const uint8_t uuid[16], uint ESP_LOGE(TAG, "%s: Failed to store node address 0x%04x", __func__, unicast_addr); return; } - if (fast_prov_server.node_addr_cnt <= fast_prov_server.max_node_num) { - if (bt_mesh_atomic_test_and_clear_bit(fast_prov_server.srv_flags, SEND_ALL_NODE_ADDR_START)) { - k_delayed_work_cancel(&fast_prov_server.send_all_node_addr_timer); + if (fast_prov_server.node_addr_cnt != FAST_PROV_NODE_COUNT_MIN && + fast_prov_server.node_addr_cnt <= fast_prov_server.max_node_num) { + if (bt_mesh_atomic_test_and_clear_bit(fast_prov_server.srv_flags, GATT_PROXY_ENABLE_START)) { + k_delayed_work_cancel(&fast_prov_server.gatt_proxy_enable_timer); } - if (!bt_mesh_atomic_test_and_set_bit(fast_prov_server.srv_flags, SEND_ALL_NODE_ADDR_START)) { - k_delayed_work_submit(&fast_prov_server.send_all_node_addr_timer, SEND_ALL_NODE_ADDR_TIMEOUT); + if (!bt_mesh_atomic_test_and_set_bit(fast_prov_server.srv_flags, GATT_PROXY_ENABLE_START)) { + k_delayed_work_submit(&fast_prov_server.gatt_proxy_enable_timer, GATT_PROXY_ENABLE_TIMEOUT); } } } else { @@ -515,7 +515,9 @@ static void example_ble_mesh_custom_model_cb(esp_ble_mesh_model_cb_event_t event case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET: case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_ADD: case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR: - case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET: { + case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET: + case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_ADD: + case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_GROUP_DELETE: { ESP_LOGI(TAG, "%s: Fast prov server receives msg, opcode 0x%04x", __func__, opcode); struct net_buf_simple buf = { .len = param->model_operation.length, diff --git a/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/board.c b/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/board.c index 9a5a8eb95d..4c51d04af7 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/board.c +++ b/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/board.c @@ -14,27 +14,18 @@ #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" - #include "driver/gpio.h" - #include "board.h" -#include "esp_fast_prov_server_model.h" +#include "esp_fast_prov_common.h" #define TAG "BOARD" -extern example_fast_prov_server_t fast_prov_server; - struct _led_state led_state[3] = { { LED_OFF, LED_OFF, LED_R, "red" }, { LED_OFF, LED_OFF, LED_G, "green" }, { LED_OFF, LED_OFF, LED_B, "blue" }, }; -static xQueueHandle led_action_queue; - void board_output_number(esp_ble_mesh_output_action_t action, uint32_t number) { ESP_LOGI(TAG, "Board output number %d", number); @@ -74,48 +65,8 @@ static void board_led_init(void) } } -static void led_action_thread(void *arg) -{ - struct _led_state led = {0}; - - while (1) { - if (xQueueReceive(led_action_queue, &led, (portTickType)portMAX_DELAY)) { - ESP_LOGI(TAG, "%s: pin 0x%04x onoff 0x%02x", __func__, led.pin, led.current); - /* If the node is controlled by phone, add a delay when turn on/off led */ - if (fast_prov_server.primary_role == true) { - vTaskDelay(50 / portTICK_PERIOD_MS); - } - gpio_set_level(led.pin, led.current); - } - } -} - -esp_err_t led_action_task_post(struct _led_state *msg, uint32_t timeout) -{ - if (xQueueSend(led_action_queue, msg, timeout) != pdTRUE) { - return ESP_FAIL; - } - return ESP_OK; -} - esp_err_t board_init(void) { - BaseType_t ret; - board_led_init(); - - led_action_queue = xQueueCreate(60, sizeof(struct _led_state)); - if (!led_action_queue) { - ESP_LOGE(TAG, "%s: Failed to create led action queue", __func__); - return ESP_FAIL; - } - - ret = xTaskCreate(led_action_thread, "led_action_thread", 4096, NULL, 5, NULL); - if (ret == pdFAIL) { - ESP_LOGE(TAG, "%s: Failed to create led_action_thread", __func__); - vQueueDelete(led_action_queue); - return ESP_FAIL; - } - return ESP_OK; } diff --git a/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/board.h b/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/board.h index c45b7b37a2..83d6057427 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/board.h +++ b/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/main/board.h @@ -41,8 +41,6 @@ void board_prov_complete(void); void board_led_operation(uint8_t pin, uint8_t onoff); -esp_err_t led_action_task_post(struct _led_state *msg, uint32_t timeout); - esp_err_t board_init(void); #endif diff --git a/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults b/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults index 89e4084602..72d91402c9 100644 --- a/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults +++ b/examples/bluetooth/ble_mesh/ble_mesh_wifi_coexist/sdkconfig.defaults @@ -5,11 +5,16 @@ CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 CONFIG_MEMMAP_SMP=y CONFIG_BT_ENABLED=y +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= +CONFIG_BTDM_CONTROLLER_MODE_BTDM= +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=n CONFIG_BLE_SCAN_DUPLICATE=y CONFIG_SCAN_DUPLICATE_TYPE=2 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=200 CONFIG_BLE_MESH_SCAN_DUPLICATE_EN=y CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE=200 +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED=y CONFIG_GATTS_ENABLE=y CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL=y CONFIG_BLE_MESH=y